def test_channel_bp_updated_event_handler_channel_not_in_database(context: Context): metrics_state = save_metrics_state(metrics.REGISTRY) # only setup the token network without channels create_default_token_network(context) event_bp = ReceiveNonClosingBalanceProofUpdatedEvent( token_network_address=DEFAULT_TOKEN_NETWORK_ADDRESS, channel_identifier=DEFAULT_CHANNEL_IDENTIFIER, closing_participant=DEFAULT_PARTICIPANT2, nonce=Nonce(2), block_number=BlockNumber(23), ) channel = context.database.get_channel( event_bp.token_network_address, event_bp.channel_identifier ) assert channel is None assert context.database.channel_count() == 0 non_closing_balance_proof_updated_event_handler(event_bp, context) assert ( metrics_state.get_delta( "events_log_errors_total", labels=metrics.ErrorCategory.STATE.to_label_dict() ) == 1.0 )
def test_channel_bp_updated_event_handler_lower_nonce_than_expected( context: Context): metrics_state = save_metrics_state(metrics.REGISTRY) context = setup_state_with_closed_channel(context) event_bp = ReceiveNonClosingBalanceProofUpdatedEvent( token_network_address=DEFAULT_TOKEN_NETWORK_ADDRESS, channel_identifier=DEFAULT_CHANNEL_IDENTIFIER, closing_participant=DEFAULT_PARTICIPANT2, nonce=Nonce(1), block_number=BlockNumber(23), ) channel = context.database.get_channel(event_bp.token_network_address, event_bp.channel_identifier) assert context.database.channel_count() == 1 assert channel assert channel.update_status is None non_closing_balance_proof_updated_event_handler(event_bp, context) # send twice the same message to trigger the non-increasing nonce non_closing_balance_proof_updated_event_handler(event_bp, context) assert (metrics_state.get_delta( "events_log_errors_total", labels=metrics.ErrorCategory.PROTOCOL.to_label_dict()) == 1.0)
def parse_token_network_event(event: dict) -> Optional[Event]: event_name = event["event"] common_infos = dict( token_network_address=decode_hex(event["address"]), channel_identifier=event["args"]["channel_identifier"], block_number=event["blockNumber"], ) if event_name == ChannelEvent.OPENED: return ReceiveChannelOpenedEvent( participant1=to_canonical_address(event["args"]["participant1"]), participant2=to_canonical_address(event["args"]["participant2"]), settle_timeout=event["args"]["settle_timeout"], **common_infos, ) if event_name == ChannelEvent.CLOSED: return ReceiveChannelClosedEvent( closing_participant=to_canonical_address(event["args"]["closing_participant"]), **common_infos, ) if event_name == ChannelEvent.BALANCE_PROOF_UPDATED: return ReceiveNonClosingBalanceProofUpdatedEvent( closing_participant=to_canonical_address(event["args"]["closing_participant"]), nonce=event["args"]["nonce"], **common_infos, ) if event_name == ChannelEvent.SETTLED: return ReceiveChannelSettledEvent(**common_infos) return None
def test_channel_bp_updated_event_handler_sets_update_status_if_not_set(context: Context): context = setup_state_with_closed_channel(context) event_bp = ReceiveNonClosingBalanceProofUpdatedEvent( token_network_address=DEFAULT_TOKEN_NETWORK_ADDRESS, channel_identifier=DEFAULT_CHANNEL_IDENTIFIER, closing_participant=DEFAULT_PARTICIPANT2, nonce=Nonce(2), block_number=BlockNumber(23), ) channel = context.database.get_channel( event_bp.token_network_address, event_bp.channel_identifier ) assert channel assert channel.update_status is None non_closing_balance_proof_updated_event_handler(event_bp, context) assert context.database.channel_count() == 1 channel = context.database.get_channel( event_bp.token_network_address, event_bp.channel_identifier ) assert channel assert channel.update_status is not None assert channel.update_status.nonce == 2 assert channel.update_status.update_sender_address == DEFAULT_PARTICIPANT1 event_bp2 = ReceiveNonClosingBalanceProofUpdatedEvent( token_network_address=DEFAULT_TOKEN_NETWORK_ADDRESS, channel_identifier=DEFAULT_CHANNEL_IDENTIFIER, closing_participant=DEFAULT_PARTICIPANT2, nonce=Nonce(5), block_number=BlockNumber(53), ) non_closing_balance_proof_updated_event_handler(event_bp2, context) assert context.database.channel_count() == 1 channel = context.database.get_channel( event_bp.token_network_address, event_bp.channel_identifier ) assert channel assert channel.update_status is not None assert channel.update_status.nonce == 5 assert channel.update_status.update_sender_address == DEFAULT_PARTICIPANT1
def parse_token_network_event(event: dict) -> Optional[Event]: event_name = event["event"] # `DeprecationSwitch` isn't used currently, but needs to be checked so we can have # `channel_identifier` in `common_infos` # FIXME: use value from ChannelEvent as soon as PR is merged # https://github.com/raiden-network/raiden-contracts/pull/1389 if event_name == "DeprecationSwitch": return None common_infos = dict( token_network_address=decode_hex(event["address"]), channel_identifier=event["args"]["channel_identifier"], block_number=event["blockNumber"], ) if event_name == ChannelEvent.OPENED: return ReceiveChannelOpenedEvent( participant1=to_canonical_address(event["args"]["participant1"]), participant2=to_canonical_address(event["args"]["participant2"]), settle_timeout=event["args"]["settle_timeout"], **common_infos, ) if event_name == ChannelEvent.CLOSED: return ReceiveChannelClosedEvent( closing_participant=to_canonical_address( event["args"]["closing_participant"]), **common_infos, ) if event_name == ChannelEvent.BALANCE_PROOF_UPDATED: return ReceiveNonClosingBalanceProofUpdatedEvent( closing_participant=to_canonical_address( event["args"]["closing_participant"]), nonce=event["args"]["nonce"], **common_infos, ) if event_name == ChannelEvent.SETTLED: return ReceiveChannelSettledEvent(**common_infos) return None
def parse_token_network_event(event: dict) -> Optional[Event]: event_name = event["event"] # `DeprecationSwitch` isn't used currently, but needs to be checked so we can have # `channel_identifier` in `common_infos` if event_name == ChannelEvent.DEPRECATED: return None common_infos = dict( token_network_address=decode_hex(event["address"]), channel_identifier=event["args"]["channel_identifier"], block_number=event["blockNumber"], ) if event_name == ChannelEvent.OPENED: return ReceiveChannelOpenedEvent( participant1=to_canonical_address(event["args"]["participant1"]), participant2=to_canonical_address(event["args"]["participant2"]), **common_infos, ) if event_name == ChannelEvent.CLOSED: return ReceiveChannelClosedEvent( closing_participant=to_canonical_address( event["args"]["closing_participant"]), **common_infos, ) if event_name == ChannelEvent.BALANCE_PROOF_UPDATED: return ReceiveNonClosingBalanceProofUpdatedEvent( closing_participant=to_canonical_address( event["args"]["closing_participant"]), nonce=event["args"]["nonce"], **common_infos, ) if event_name == ChannelEvent.SETTLED: return ReceiveChannelSettledEvent(**common_infos) return None
def get_blockchain_events( web3: Web3, contract_manager: ContractManager, chain_state: BlockchainState, to_block: BlockNumber, query_ms: bool = True, ) -> Tuple[BlockchainState, List[Event]]: # increment by one, as latest_known_block has been queried last time already from_block = BlockNumber(chain_state.latest_known_block + 1) # Check if the current block was already processed if from_block > to_block: return chain_state, [] new_chain_state = deepcopy(chain_state) log.info('Querying new block(s)', from_block=from_block, end_block=to_block) # first check for new token networks and add to state registry_events = query_blockchain_events( web3=web3, contract_manager=contract_manager, contract_address=new_chain_state.token_network_registry_address, contract_name=CONTRACT_TOKEN_NETWORK_REGISTRY, topics=create_registry_event_topics(contract_manager), from_block=from_block, to_block=to_block, ) events: List[Event] = [] for event in registry_events: token_network_address = event['args']['token_network_address'] token_address = event['args']['token_address'] block_number = event['blockNumber'] events.append( ReceiveTokenNetworkCreatedEvent( token_address=token_address, token_network_address=token_network_address, block_number=block_number, )) new_chain_state.token_network_addresses.append( event['args']['token_network_address']) # then check all token networks for token_network_address in new_chain_state.token_network_addresses: network_events = query_blockchain_events( web3=web3, contract_manager=contract_manager, contract_address=Address(token_network_address), contract_name=CONTRACT_TOKEN_NETWORK, topics=[None], from_block=from_block, to_block=to_block, ) for event in network_events: event_name = event['event'] common_infos = dict( token_network_address=event['address'], channel_identifier=event['args']['channel_identifier'], block_number=event['blockNumber'], ) if event_name == ChannelEvent.OPENED: events.append( ReceiveChannelOpenedEvent( participant1=event['args']['participant1'], participant2=event['args']['participant2'], settle_timeout=event['args']['settle_timeout'], **common_infos, )) elif event_name == ChannelEvent.DEPOSIT: events.append( ReceiveChannelNewDepositEvent( participant_address=event['args']['participant'], total_deposit=event['args']['total_deposit'], **common_infos, )) elif event_name == ChannelEvent.CLOSED: events.append( ReceiveChannelClosedEvent(closing_participant=event['args'] ['closing_participant'], **common_infos)) elif event_name == ChannelEvent.BALANCE_PROOF_UPDATED: events.append( ReceiveNonClosingBalanceProofUpdatedEvent( closing_participant=event['args'] ['closing_participant'], nonce=event['args']['nonce'], **common_infos, )) elif event_name == ChannelEvent.SETTLED: events.append(ReceiveChannelSettledEvent(**common_infos)) # get events from monitoring service contract if query_ms: monitoring_events = get_monitoring_blockchain_events( web3=web3, contract_manager=contract_manager, chain_state=new_chain_state, from_block=from_block, to_block=to_block, ) events.extend(monitoring_events) # commit new block number events.append(UpdatedHeadBlockEvent(head_block_number=to_block)) return new_chain_state, events