Exemple #1
0
def get_contract_events(
    chain: BlockChainService,
    abi: Dict,
    contract_address: Address,
    topics: List[str],
    from_block: BlockSpecification,
    to_block: BlockSpecification,
) -> List[Dict]:
    """ Query the blockchain for all events of the smart contract at
    `contract_address` that match the filters `topics`, `from_block`, and
    `to_block`.
    """
    verify_block_number(from_block, 'from_block')
    verify_block_number(to_block, 'to_block')
    events = chain.client.get_filter_events(
        contract_address,
        topics=topics,
        from_block=from_block,
        to_block=to_block,
    )

    result = []
    for event in events:
        decoded_event = dict(decode_event(abi, event))
        if event.get('blockNumber'):
            decoded_event['block_number'] = event['blockNumber']
        result.append(decoded_event)
    return result
Exemple #2
0
    def __init__(
            self,
            token_network: TokenNetwork,
            channel_identifier: typing.ChannelID,
    ):
        filter_args = get_filter_args_for_specific_event_from_channel(
            token_network_address=token_network.address,
            channel_identifier=channel_identifier,
            event_name=EVENT_CHANNEL_OPENED,
        )

        events = token_network.proxy.contract.web3.eth.getLogs(filter_args)
        if not len(events) > 0:
            raise ValueError('Channel is non-existing.')

        event = decode_event(CONTRACT_MANAGER.get_contract_abi(CONTRACT_TOKEN_NETWORK), events[-1])
        participant1 = decode_hex(event['args']['participant1'])
        participant2 = decode_hex(event['args']['participant2'])

        if token_network.node_address not in (participant1, participant2):
            raise ValueError('One participant must be the node address')

        if token_network.node_address == participant2:
            participant1, participant2 = participant2, participant1

        self.channel_identifier = channel_identifier
        self.channel_operations_lock = RLock()
        self.participant1 = participant1
        self.participant2 = participant2
        self.token_network = token_network
Exemple #3
0
def get_contract_events(
        chain: BlockChainService,
        abi: Dict,
        contract_address: Address,
        topics: List[str],
        from_block: BlockSpecification,
        to_block: BlockSpecification,
) -> List[Dict]:
    """ Query the blockchain for all events of the smart contract at
    `contract_address` that match the filters `topics`, `from_block`, and
    `to_block`.
    """
    verify_block_number(from_block, 'from_block')
    verify_block_number(to_block, 'to_block')
    events = chain.client.get_filter_events(
        contract_address,
        topics=topics,
        from_block=from_block,
        to_block=to_block,
    )

    result = []
    for event in events:
        decoded_event = dict(decode_event(abi, event))
        if event.get('blockNumber'):
            decoded_event['block_number'] = event['blockNumber']
        result.append(decoded_event)
    return result
Exemple #4
0
    def poll_blockchain_events(self, block_number: int = None):
        # When we test with geth if the contracts have already been deployed
        # before the filter creation we need to use `get_all_entries` to make
        # sure we get all the events. With tester this is not required.

        for event_listener in self.event_listeners:
            if isinstance(event_listener.filter, StatelessFilter):
                events = event_listener.filter.get_new_entries(block_number)
            elif event_listener.first_run is True:
                events = event_listener.filter.get_all_entries()
                index = self.event_listeners.index(event_listener)
                self.event_listeners[index] = event_listener._replace(first_run=False)
            else:
                events = event_listener.filter.get_new_entries()

            for log_event in events:
                decoded_event = dict(decode_event(
                    event_listener.abi,
                    log_event,
                ))

                if decoded_event is not None:
                    decoded_event['block_number'] = log_event.get('blockNumber', 0)
                    event = Event(
                        to_canonical_address(log_event['address']),
                        decoded_event,
                    )
                    yield decode_event_to_internal(event)
Exemple #5
0
    def poll_blockchain_events(self, block_number: int = None):
        # When we test with geth if the contracts have already been deployed
        # before the filter creation we need to use `get_all_entries` to make
        # sure we get all the events. With tester this is not required.

        for event_listener in self.event_listeners:
            if isinstance(event_listener.filter, StatelessFilter):
                events = event_listener.filter.get_new_entries(block_number)
            elif event_listener.first_run is True:
                events = event_listener.filter.get_all_entries()
                index = self.event_listeners.index(event_listener)
                self.event_listeners[index] = event_listener._replace(
                    first_run=False)
            else:
                events = event_listener.filter.get_new_entries()

            for log_event in events:
                decoded_event = dict(
                    decode_event(
                        event_listener.abi,
                        log_event,
                    ))

                if decoded_event is not None:
                    decoded_event['block_number'] = log_event.get(
                        'blockNumber', 0)
                    event = Event(
                        to_canonical_address(log_event['address']),
                        decoded_event,
                    )
                    yield decode_event_to_internal(event)
Exemple #6
0
    def __init__(
        self,
        token_network: TokenNetwork,
        channel_identifier: typing.ChannelID,
    ):
        filter_args = get_filter_args_for_specific_event_from_channel(
            token_network_address=token_network.address,
            channel_identifier=channel_identifier,
            event_name=EVENT_CHANNEL_OPENED,
        )

        events = token_network.proxy.contract.web3.eth.getLogs(filter_args)
        if not len(events) > 0:
            raise ValueError('Channel is non-existing.')

        event = decode_event(
            CONTRACT_MANAGER.get_contract_abi(CONTRACT_TOKEN_NETWORK),
            events[-1])
        participant1 = decode_hex(event['args']['participant1'])
        participant2 = decode_hex(event['args']['participant2'])

        if token_network.node_address not in (participant1, participant2):
            raise ValueError('One participant must be the node address')

        if token_network.node_address == participant2:
            participant1, participant2 = participant2, participant1

        self.channel_identifier = channel_identifier
        self.channel_operations_lock = RLock()
        self.participant1 = participant1
        self.participant2 = participant2
        self.token_network = token_network
Exemple #7
0
def decode_event_to_internal(abi, log_event):
    """ Enforce the binary for internal usage. """
    # Note: All addresses inside the event_data must be decoded.

    decoded_event = decode_event(abi, log_event)

    if not decoded_event:
        raise UnknownEventType()

    # copy the attribute dict because that data structure is immutable
    data = dict(decoded_event)
    args = dict(data['args'])

    data['args'] = args
    # translate from web3's to raiden's name convention
    data['block_number'] = log_event.pop('blockNumber')
    data['transaction_hash'] = log_event.pop('transactionHash')
    data['block_hash'] = bytes(log_event.pop('blockHash'))

    assert data['block_number'], 'The event must have the block_number'
    assert data[
        'transaction_hash'], 'The event must have the transaction hash field'

    event = data['event']
    if event == EVENT_TOKEN_NETWORK_CREATED:
        args['token_network_address'] = to_canonical_address(
            args['token_network_address'])
        args['token_address'] = to_canonical_address(args['token_address'])

    elif event == ChannelEvent.OPENED:
        args['participant1'] = to_canonical_address(args['participant1'])
        args['participant2'] = to_canonical_address(args['participant2'])

    elif event == ChannelEvent.DEPOSIT:
        args['participant'] = to_canonical_address(args['participant'])

    elif event == ChannelEvent.BALANCE_PROOF_UPDATED:
        args['closing_participant'] = to_canonical_address(
            args['closing_participant'])

    elif event == ChannelEvent.CLOSED:
        args['closing_participant'] = to_canonical_address(
            args['closing_participant'])

    elif event == ChannelEvent.UNLOCKED:
        args['participant'] = to_canonical_address(args['participant'])
        args['partner'] = to_canonical_address(args['partner'])

    return Event(
        originating_contract=to_canonical_address(log_event['address']),
        event_data=data,
    )
Exemple #8
0
    def __init__(
        self,
        token_network: TokenNetwork,
        channel_identifier: ChannelID,
        contract_manager: ContractManager,
    ):
        if channel_identifier <= 0 or channel_identifier > UINT256_MAX:
            raise ValueError(
                f"channel_identifier {channel_identifier} is not a uint256")

        # FIXME: Issue #3958
        from_block = GENESIS_BLOCK_NUMBER

        # For this check it is perfectly fine to use a `latest` block number.
        # If the channel happened to be closed, even if the chanel is already
        # closed/settled.
        to_block = "latest"

        filter_args = get_filter_args_for_specific_event_from_channel(
            token_network_address=token_network.address,
            channel_identifier=channel_identifier,
            event_name=ChannelEvent.OPENED,
            contract_manager=contract_manager,
            from_block=from_block,
            to_block=to_block,
        )

        events = token_network.proxy.contract.web3.eth.getLogs(filter_args)
        if not len(events) > 0:
            raise ValueError("Channel is non-existing.")

        event = decode_event(
            contract_manager.get_contract_abi(CONTRACT_TOKEN_NETWORK),
            events[-1])
        participant1 = Address(decode_hex(event["args"]["participant1"]))
        participant2 = Address(decode_hex(event["args"]["participant2"]))

        if token_network.node_address not in (participant1, participant2):
            raise ValueError("One participant must be the node address")

        if token_network.node_address == participant2:
            participant1, participant2 = participant2, participant1

        self.channel_identifier = channel_identifier
        self.participant1 = participant1
        self.participant2 = participant2
        self.token_network = token_network
        self.client = token_network.client
        self.contract_manager = contract_manager
Exemple #9
0
    def settle_timeout(self) -> int:
        """ Returns the channels settle_timeout. """

        # There is no way to get the settle timeout after the channel has been closed as
        # we're saving gas. Therefore get the ChannelOpened event and get the timeout there.
        filter_args = get_filter_args_for_specific_event_from_channel(
            token_network_address=self.token_network.address,
            channel_identifier=self.channel_identifier,
            event_name=EVENT_CHANNEL_OPENED,
        )

        events = self.token_network.proxy.contract.web3.eth.getLogs(filter_args)
        assert len(events) > 0, 'No matching ChannelOpen event found.'

        # we want the latest event here, there might have been multiple channels
        event = decode_event(CONTRACT_MANAGER.get_contract_abi(CONTRACT_TOKEN_NETWORK), events[-1])
        return event['args']['settle_timeout']
Exemple #10
0
    def settle_timeout(self) -> int:
        """ Returns the channels settle_timeout. """

        # There is no way to get the settle timeout after the channel has been closed as
        # we're saving gas. Therefore get the ChannelOpened event and get the timeout there.
        filter_args = get_filter_args_for_specific_event_from_channel(
            token_network_address=self.token_network.address,
            channel_identifier=self.channel_identifier,
            event_name=ChannelEvent.OPENED,
        )

        events = self.token_network.proxy.contract.web3.eth.getLogs(filter_args)
        assert len(events) > 0, 'No matching ChannelOpen event found.'

        # we want the latest event here, there might have been multiple channels
        event = decode_event(CONTRACT_MANAGER.get_contract_abi(CONTRACT_TOKEN_NETWORK), events[-1])
        return event['args']['settle_timeout']
Exemple #11
0
    def poll_blockchain_events(self, block_number: int):
        """ Poll for new blockchain events up to `block_number`. """

        for event_listener in self.event_listeners:
            assert isinstance(event_listener.filter, StatelessFilter)

            for log_event in event_listener.filter.get_new_entries(block_number):
                decoded_event = dict(decode_event(
                    event_listener.abi,
                    log_event,
                ))

                if decoded_event:
                    decoded_event['block_number'] = log_event.get('blockNumber', 0)
                    event = Event(
                        to_canonical_address(log_event['address']),
                        decoded_event,
                    )
                    yield decode_event_to_internal(event)
Exemple #12
0
    def __init__(
        self,
        token_network: TokenNetwork,
        channel_identifier: ChannelID,
        contract_manager: ContractManager,
    ):

        self.contract_manager = contract_manager
        if channel_identifier < 0 or channel_identifier > UINT256_MAX:
            raise ValueError('channel_identifier {} is not a uint256'.format(
                channel_identifier))

        filter_args = get_filter_args_for_specific_event_from_channel(
            token_network_address=token_network.address,
            channel_identifier=channel_identifier,
            event_name=ChannelEvent.OPENED,
            contract_manager=self.contract_manager,
        )

        events = token_network.proxy.contract.web3.eth.getLogs(filter_args)
        if not len(events) > 0:
            raise ValueError('Channel is non-existing.')

        event = decode_event(
            self.contract_manager.get_contract_abi(CONTRACT_TOKEN_NETWORK),
            events[-1],
        )
        participant1 = Address(decode_hex(event['args']['participant1']))
        participant2 = Address(decode_hex(event['args']['participant2']))

        if token_network.node_address not in (participant1, participant2):
            raise ValueError('One participant must be the node address')

        if token_network.node_address == participant2:
            participant1, participant2 = participant2, participant1

        self.channel_identifier = channel_identifier
        self.participant1 = participant1
        self.participant2 = participant2
        self.token_network = token_network
        self.client = self.token_network.client
Exemple #13
0
    def close_block_number(self) -> typing.Optional[int]:
        """ Returns the channel's closed block number. """

        # The closed block number is not in the smart contract storage to save
        # gas. Therefore get the ChannelClosed event is needed here.
        filter_args = get_filter_args_for_specific_event_from_channel(
            token_network_address=self.token_network.address,
            channel_identifier=self.channel_identifier,
            event_name=ChannelEvent.CLOSED,
        )

        events = self.token_network.proxy.contract.web3.eth.getLogs(
            filter_args)
        if not events:
            return None

        assert len(events) == 1
        event = decode_event(
            CONTRACT_MANAGER.get_contract_abi(CONTRACT_TOKEN_NETWORK),
            events[0])
        return event['blockNumber']
Exemple #14
0
    def close_block_number(self) -> Optional[int]:
        """ Returns the channel's closed block number. """

        # The closed block number is not in the smart contract storage to save
        # gas. Therefore get the ChannelClosed event is needed here.
        filter_args = get_filter_args_for_specific_event_from_channel(
            token_network_address=self.token_network.address,
            channel_identifier=self.channel_identifier,
            event_name=ChannelEvent.CLOSED,
            contract_manager=self.contract_manager,
        )

        events = self.token_network.proxy.contract.web3.eth.getLogs(filter_args)
        if not events:
            return None

        assert len(events) == 1
        event = decode_event(
            self.contract_manager.get_contract_abi(CONTRACT_TOKEN_NETWORK),
            events[0],
        )
        return event['blockNumber']
Exemple #15
0
    def __init__(
            self,
            token_network: TokenNetwork,
            channel_identifier: ChannelID,
            contract_manager: ContractManager,
    ):

        self.contract_manager = contract_manager
        if channel_identifier < 0 or channel_identifier > UINT256_MAX:
            raise ValueError('channel_identifier {} is not a uint256'.format(channel_identifier))

        filter_args = get_filter_args_for_specific_event_from_channel(
            token_network_address=token_network.address,
            channel_identifier=channel_identifier,
            event_name=ChannelEvent.OPENED,
            contract_manager=self.contract_manager,
        )

        events = token_network.proxy.contract.web3.eth.getLogs(filter_args)
        if not len(events) > 0:
            raise ValueError('Channel is non-existing.')

        event = decode_event(
            self.contract_manager.get_contract_abi(CONTRACT_TOKEN_NETWORK),
            events[-1],
        )
        participant1 = decode_hex(event['args']['participant1'])
        participant2 = decode_hex(event['args']['participant2'])

        if token_network.node_address not in (participant1, participant2):
            raise ValueError('One participant must be the node address')

        if token_network.node_address == participant2:
            participant1, participant2 = participant2, participant1

        self.channel_identifier = channel_identifier
        self.participant1 = participant1
        self.participant2 = participant2
        self.token_network = token_network
Exemple #16
0
    def poll_blockchain_events(self):
        # When we test with geth if the contracts have already been deployed
        # before the filter creation we need to use `get_all_entries` to make
        # sure we get all the events. With tester this is not required.
        if self.first_run:
            query_fn = 'get_all_entries'
            self.first_run = False
        else:
            query_fn = 'get_new_entries'

        for event_listener in self.event_listeners:
            for log_event in getattr(event_listener.filter, query_fn)():
                decoded_event = dict(decode_event(
                    event_listener.abi,
                    log_event,
                ))

                if decoded_event is not None:
                    decoded_event['block_number'] = log_event.get('blockNumber', 0)
                    event = Event(
                        to_canonical_address(log_event['address']),
                        decoded_event,
                    )
                    yield decode_event_to_internal(event)
 def decode_event(self, log: Dict):
     return decode_event(self.contract.abi, log)
Exemple #18
0
def test_blockchain(
        web3,
        blockchain_rpc_ports,
        private_keys,
):
    # pylint: disable=too-many-locals

    addresses = [
        privatekey_to_address(priv)
        for priv in private_keys
    ]

    privatekey = private_keys[0]
    address = privatekey_to_address(privatekey)
    total_token = 100

    host = '127.0.0.1'
    jsonrpc_client = JSONRPCClient(
        host,
        blockchain_rpc_ports[0],
        privatekey,
        web3=web3,
    )

    humantoken_path = get_contract_path('HumanStandardToken.sol')
    humantoken_contracts = compile_files_cwd([humantoken_path])
    token_proxy = jsonrpc_client.deploy_solidity_contract(
        'HumanStandardToken',
        humantoken_contracts,
        list(),
        (total_token, 'raiden', 2, 'Rd'),
        contract_path=humantoken_path,
    )
    token_proxy = Token(jsonrpc_client, to_canonical_address(token_proxy.contract.address))

    registry_path = get_contract_path('Registry.sol')
    registry_contracts = compile_files_cwd([registry_path])
    registry_proxy = jsonrpc_client.deploy_solidity_contract(
        'Registry',
        registry_contracts,
        list(),
        tuple(),
        contract_path=registry_path,
    )
    registry_proxy = Registry(
        jsonrpc_client,
        to_canonical_address(registry_proxy.contract.address),
    )

    log_list = jsonrpc_client.web3.eth.getLogs(
        {
            'fromBlock': 0,
            'toBlock': 'latest',
            'topics': [],
        },
    )
    assert not log_list

    assert token_proxy.balance_of(address) == total_token
    manager_address = registry_proxy.add_token(
        to_canonical_address(token_proxy.proxy.contract.address),
    )
    assert is_address(manager_address)
    assert len(registry_proxy.token_addresses()) == 1

    log_list = jsonrpc_client.web3.eth.getLogs(
        {
            'fromBlock': 0,
            'toBlock': 'latest',
            'topics': [],
        },
    )
    assert len(log_list) == 1

    channel_manager_address_encoded = registry_proxy.manager_address_by_token(
        token_proxy.proxy.contract.address,
    )
    channel_manager_address = to_canonical_address(channel_manager_address_encoded)

    log = log_list[0]
    event = decode_event(CONTRACT_MANAGER.get_contract_abi(CONTRACT_REGISTRY), log)
    event_args = event['args']

    assert channel_manager_address == to_canonical_address(event_args['channel_manager_address'])
    assert is_same_address(token_proxy.proxy.contract.address, event_args['token_address'])

    channel_manager_proxy = jsonrpc_client.new_contract_proxy(
        CONTRACT_MANAGER.get_contract_abi(CONTRACT_CHANNEL_MANAGER),
        channel_manager_address,
    )
    channel_manager_proxy = ChannelManager(
        jsonrpc_client,
        to_canonical_address(channel_manager_proxy.contract.address),
    )

    channel_address = channel_manager_proxy.new_netting_channel(
        addresses[1],
        10,
    )
    assert is_address(channel_address)

    log_list = jsonrpc_client.web3.eth.getLogs(
        {
            'fromBlock': 0,
            'toBlock': 'latest',
            'topics': [],
        },
    )
    assert len(log_list) == 2
Exemple #19
0
 def decode_event(self, log: Dict):
     return decode_event(self.contract.abi, log)