Exemple #1
0
def test_contract_events_throttler_inclusive_block_ranges():
    event_name = 'TestEvent'

    #
    # 1 block at a time
    #
    mock_method = Mock(return_value=[])
    agent = Mock(events={event_name: mock_method})
    events_throttler = ContractEventsThrottler(agent=agent,
                                               event_name=event_name,
                                               from_block=0,
                                               to_block=10,
                                               max_blocks_per_call=1)

    for _ in events_throttler:
        pass

    # check calls to filter
    # ranges used = (0, 1), (2, 3), (4, 5), (6, 7), (8, 9), (10, 10)
    assert mock_method.call_count == 6
    mock_method.assert_any_call(from_block=0, to_block=1)
    mock_method.assert_any_call(from_block=2, to_block=3)
    mock_method.assert_any_call(from_block=4, to_block=5)
    mock_method.assert_any_call(from_block=6, to_block=7)
    mock_method.assert_any_call(from_block=8, to_block=9)
    mock_method.assert_any_call(from_block=10, to_block=10)

    #
    # 5 blocks at a time
    #
    mock_method = Mock(return_value=[])
    agent = Mock(events={event_name: mock_method})
    argument_filters = {'address': '0xdeadbeef'}
    events_throttler = ContractEventsThrottler(agent=agent,
                                               event_name=event_name,
                                               from_block=0,
                                               to_block=21,
                                               max_blocks_per_call=5,
                                               **argument_filters)

    for _ in events_throttler:
        pass

    # check calls to filter
    # ranges used = (0, 5), (6, 11), (12, 17) (18, 21)
    assert mock_method.call_count == 4
    mock_method.assert_any_call(**argument_filters, from_block=0, to_block=5)
    mock_method.assert_any_call(**argument_filters, from_block=6, to_block=11)
    mock_method.assert_any_call(**argument_filters, from_block=12, to_block=17)
    mock_method.assert_any_call(**argument_filters, from_block=18, to_block=21)
Exemple #2
0
    def initialize(self, metrics_prefix: str,
                   registry: CollectorRegistry) -> None:
        super().initialize(metrics_prefix=metrics_prefix, registry=registry)

        missing_commitments = self.contract_agent.get_missing_commitments(
            checksum_address=self.staker_address)
        if missing_commitments == 0:
            # has either already committed to this period or the next period

            # use local event filter for initial data
            last_committed_period = self.contract_agent.get_last_committed_period(
                staker_address=self.staker_address)
            arg_filters = {
                'staker': self.staker_address,
                'period': last_committed_period
            }
            latest_block = self.contract_agent.blockchain.client.block_number
            previous_period = self.contract_agent.get_current_period(
            ) - 1  # just in case
            # we estimate the block number for the previous period to start search from since either
            # - commitment made during previous period for current period, OR
            # - commitment made during current period for next period
            block_number_for_previous_period = estimate_block_number_for_period(
                period=previous_period,
                seconds_per_period=self.contract_agent.staking_parameters()[0],
                latest_block=latest_block)

            events_throttler = ContractEventsThrottler(
                agent=self.contract_agent,
                event_name=self.event_name,
                from_block=block_number_for_previous_period,
                to_block=latest_block,
                **arg_filters)
            for event_record in events_throttler:
                self._event_occurred(event_record.raw_event)
Exemple #3
0
def test_contract_events_throttler_to_block_check():
    event_name = 'TestEvent'
    latest_block = 50
    blockchain = MagicMock()
    blockchain.client.block_number = latest_block
    agent = Mock(events={event_name: Mock(return_value=[])},
                 blockchain=blockchain)

    # from_block < to_block
    throttler = ContractEventsThrottler(agent=agent,
                                        event_name=event_name,
                                        from_block=1,
                                        to_block=10)
    assert throttler.from_block == 1
    assert throttler.to_block == 10

    # to_block < from_block
    with pytest.raises(ValueError):
        ContractEventsThrottler(agent=agent,
                                event_name=event_name,
                                from_block=10,
                                to_block=8)

    # to_block can be equal to from_block
    throttler = ContractEventsThrottler(agent=agent,
                                        event_name=event_name,
                                        from_block=10,
                                        to_block=10)
    assert throttler.from_block == 10
    assert throttler.to_block == 10

    # from_block and to_block value of zero allowed
    throttler = ContractEventsThrottler(agent=agent,
                                        event_name=event_name,
                                        from_block=0,
                                        to_block=0)
    assert throttler.from_block == 0
    assert throttler.to_block == 0

    #
    # when to_block is not specified it defaults to latest block number
    #

    # latest block is lower than from_block
    with pytest.raises(ValueError):
        ContractEventsThrottler(agent=agent,
                                event_name=event_name,
                                from_block=latest_block + 1)

    # latest block is equal to from_block
    throttler = ContractEventsThrottler(agent=agent,
                                        event_name=event_name,
                                        from_block=latest_block)
    assert throttler.from_block == latest_block
    assert throttler.to_block == latest_block
Exemple #4
0
    def _collect_internal(self) -> None:
        from_block = self.filter_current_from_block
        to_block = self.contract_agent.blockchain.client.block_number
        if from_block >= to_block:
            # we've already checked the latest block and waiting for a new block
            # nothing to see here
            return

        events_throttler = ContractEventsThrottler(agent=self.contract_agent,
                                                   event_name=self.event_name,
                                                   from_block=from_block,
                                                   to_block=to_block,
                                                   **self.filter_arguments)
        for event_record in events_throttler:
            self._event_occurred(event_record.raw_event)

        # update last block checked for the next round - from/to block range is inclusive
        self.filter_current_from_block = to_block + 1
Exemple #5
0
    def _collect_internal(self) -> None:
        contract_agent = ContractAgency.get_agent(
            self.contract_agent_class, registry=self.contract_registry)
        from_block = self.filter_current_from_block
        to_block = contract_agent.blockchain.client.block_number
        if from_block >= to_block:
            # we've already checked the latest block and waiting for a new block
            # nothing to see here
            return

        # update last block checked for the next round - from/to block range is inclusive
        # increment before potentially long running execution to improve concurrency handling
        self.filter_current_from_block = to_block + 1

        events_throttler = ContractEventsThrottler(agent=contract_agent,
                                                   event_name=self.event_name,
                                                   from_block=from_block,
                                                   to_block=to_block,
                                                   **self.filter_arguments)
        for event_record in events_throttler:
            self._event_occurred(event_record.raw_event)