def get_channel_participants_from_open_event( token_network: "TokenNetwork", channel_identifier: ChannelID, contract_manager: ContractManager, from_block: BlockNumber, ) -> Optional[Tuple[Address, Address]]: # For this check it is perfectly fine to use a `latest` block number. # Because the filter is looking just for the OPENED event. 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) # There must be only one channel open event per channel identifier if len(events) != 1: return None event = decode_event( contract_manager.get_contract_abi(CONTRACT_TOKEN_NETWORK), events[0]) participant1 = Address(decode_hex(event["args"]["participant1"])) participant2 = Address(decode_hex(event["args"]["participant2"])) return participant1, participant2
def test_get_filter_args(contract_manager): channel_identifier = factories.UNIT_CHANNEL_ID token_network_address = factories.UNIT_TOKEN_NETWORK_ADDRESS event_filter_params = get_filter_args_for_all_events_from_channel( token_network_address=token_network_address, channel_identifier=channel_identifier, contract_manager=contract_manager, ) assert event_filter_params["topics"][0] is None assert to_int( hexstr=event_filter_params["topics"][1]) == channel_identifier assert event_filter_params["address"] == to_checksum_address( token_network_address) assert event_filter_params["fromBlock"] == 0 assert event_filter_params["toBlock"] == BLOCK_ID_LATEST with pytest.raises(ValueError): # filter argument generation checks if event type is known get_filter_args_for_specific_event_from_channel( token_network_address=token_network_address, channel_identifier=channel_identifier, event_name="NonexistingEvent", contract_manager=contract_manager, ) event_filter_params = get_filter_args_for_specific_event_from_channel( token_network_address=token_network_address, channel_identifier=channel_identifier, event_name="ChannelOpened", contract_manager=contract_manager, from_block=BlockNumber(100), to_block=BlockNumber(200), ) assert event_filter_params["topics"][0] is not None assert to_int( hexstr=event_filter_params["topics"][1]) == channel_identifier assert event_filter_params["address"] == to_checksum_address( token_network_address) assert event_filter_params["fromBlock"] == 100 assert event_filter_params["toBlock"] == 200
def settle_timeout(self) -> BlockTimeout: """ 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, contract_manager=self.contract_manager, ) events = self.client.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( self.contract_manager.get_contract_abi(CONTRACT_TOKEN_NETWORK), events[-1]) return event["args"]["settle_timeout"]
def close_block_number(self) -> Optional[BlockNumber]: """ 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"]