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 test_monitor_reward_claimed_event_handler(context: Context, log): metrics_state = save_metrics_state(metrics.REGISTRY) context = setup_state_with_closed_channel(context) claim_event = ReceiveMonitoringRewardClaimedEvent( ms_address=context.ms_state.address, amount=TokenAmount(1), reward_identifier="REWARD", block_number=BlockNumber(23), ) monitor_reward_claim_event_handler(claim_event, context) assert (metrics_state.get_delta( "economics_reward_claims_successful_total", labels=metrics.Who.US.to_label_dict()) == 1.0) assert (metrics_state.get_delta( "economics_reward_claims_token_total", labels=metrics.Who.US.to_label_dict()) == 1.0) assert log.has("Successfully claimed reward") claim_event.ms_address = Address(bytes([3] * 20)) monitor_reward_claim_event_handler(claim_event, context) assert (metrics_state.get_delta( "economics_reward_claims_successful_total", labels=metrics.Who.THEY.to_label_dict()) == 1.0) assert (metrics_state.get_delta( "economics_reward_claims_token_total", labels=metrics.Who.THEY.to_label_dict()) == 1.0) assert log.has("Another MS claimed reward")
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_prometheus_event_handling_raise_exception(pathfinding_service_mock_empty): metrics_state = save_metrics_state(metrics.REGISTRY) pfs = pathfinding_service_mock_empty event = ReceiveTokenNetworkCreatedEvent( token_address=TokenAddress(bytes([1] * 20)), token_network_address=TokenNetworkAddress(bytes([2] * 20)), settle_timeout=DEFAULT_TOKEN_NETWORK_SETTLE_TIMEOUT, block_number=BlockNumber(1), ) pfs.handle_token_network_created = Mock(side_effect=KeyError()) with pytest.raises(KeyError): pfs.handle_event(event) # The exceptions raised in the wrapped part of the prometheus logging # will not be handled anywhere at the moment. # Force an exception and test correct logging of it anyways, # since at some point higher in the call stack we could catch exceptions. assert ( metrics_state.get_delta( "events_exceptions_total", labels={"event_type": "ReceiveTokenNetworkCreatedEvent"}, ) == 1.0 )
def test_metrics_iou( # pylint: disable=too-many-locals pathfinding_service_web3_mock: PathfindingService, one_to_n_contract, web3: Web3, deposit_to_udc, get_accounts, get_private_key, ): pfs = pathfinding_service_web3_mock metrics_state = save_metrics_state(metrics.REGISTRY) # Prepare test data account = [decode_hex(acc) for acc in get_accounts(1)][0] local_signer = LocalSigner(private_key=get_private_key(account)) iou = IOU( sender=account, receiver=pfs.address, amount=TokenAmount(100), expiration_block=BlockNumber(100), signature=Signature(bytes([1] * 64)), chain_id=ChainID(61), one_to_n_address=to_canonical_address(one_to_n_contract.address), claimed=False, ) iou.signature = Signature(local_signer.sign(iou.packed_data())) pfs.database.upsert_iou(iou) deposit_to_udc(iou.sender, 300) # Claim IOUs skipped, failures = claim_ious( ious=[iou], claim_cost_rdn=TokenAmount(100), one_to_n_contract=one_to_n_contract, web3=web3, database=pfs.database, ) assert (skipped, failures) == (0, 0) assert ( metrics_state.get_delta( "economics_iou_claims_total", labels=metrics.IouStatus.SUCCESSFUL.to_label_dict() ) == 1.0 ) assert ( metrics_state.get_delta( "economics_iou_claims_token_total", labels=metrics.IouStatus.SUCCESSFUL.to_label_dict(), ) == 100.0 )
def test_update_fee(order, pathfinding_service_mock, token_network_model): metrics_state = save_metrics_state(metrics.REGISTRY) pathfinding_service_mock.database.insert( "token_network", dict(address=token_network_model.address) ) if order == "normal": setup_channel(pathfinding_service_mock, token_network_model) exception_expected = False else: exception_expected = True fee_schedule = FeeScheduleState( flat=FeeAmount(1), proportional=ProportionalFeeAmount(int(0.1e9)), imbalance_penalty=[(TokenAmount(0), FeeAmount(0)), (TokenAmount(10), FeeAmount(10))], ) fee_update = PFSFeeUpdate( canonical_identifier=CanonicalIdentifier( chain_identifier=ChainID(61), token_network_address=token_network_model.address, channel_identifier=ChannelID(1), ), updating_participant=PARTICIPANT1, fee_schedule=fee_schedule, timestamp=datetime.utcnow(), signature=EMPTY_SIGNATURE, ) fee_update.sign(LocalSigner(PARTICIPANT1_PRIVKEY)) pathfinding_service_mock.handle_message(fee_update) # Test for metrics having seen the processing of the message assert ( metrics_state.get_delta( "messages_processing_duration_seconds_sum", labels={"message_type": "PFSFeeUpdate"}, ) > 0.0 ) assert metrics_state.get_delta( "messages_exceptions_total", labels={"message_type": "PFSFeeUpdate"} ) == float(exception_expected) if order == "fee_update_before_channel_open": setup_channel(pathfinding_service_mock, token_network_model) cv = token_network_model.G[PARTICIPANT1][PARTICIPANT2]["view"] for key in ("flat", "proportional", "imbalance_penalty"): assert getattr(cv.fee_schedule_sender, key) == getattr(fee_schedule, key)
def test_channel_closed_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 = ReceiveChannelClosedEvent( token_network_address=DEFAULT_TOKEN_NETWORK_ADDRESS, channel_identifier=ChannelID(4), closing_participant=DEFAULT_PARTICIPANT2, block_number=BlockNumber(52), ) assert context.database.channel_count() == 0 channel_closed_event_handler(event, context) assert context.database.channel_count() == 0 assert (metrics_state.get_delta( "events_log_errors_total", labels=metrics.ErrorCategory.STATE.to_label_dict()) == 1.0)
def test_prometheus_event_handling_no_exceptions(pathfinding_service_mock_empty): metrics_state = save_metrics_state(metrics.REGISTRY) pfs = pathfinding_service_mock_empty token_address = TokenAddress(bytes([1] * 20)) token_network_address = TokenNetworkAddress(bytes([2] * 20)) channel_id = ChannelID(1) p1 = Address(bytes([3] * 20)) p2 = Address(bytes([4] * 20)) events = [ ReceiveTokenNetworkCreatedEvent( token_address=token_address, token_network_address=token_network_address, settle_timeout=DEFAULT_TOKEN_NETWORK_SETTLE_TIMEOUT, block_number=BlockNumber(1), ), ReceiveChannelOpenedEvent( token_network_address=token_network_address, channel_identifier=channel_id, participant1=p1, participant2=p2, block_number=BlockNumber(2), ), ] for event in events: pfs.handle_event(event) # check that we have non-zero processing time for the events we created assert ( metrics_state.get_delta( "events_processing_duration_seconds_sum", labels={"event_type": event.__class__.__name__}, ) > 0.0 ) # there should be no exception raised assert ( metrics_state.get_delta( "events_exceptions_total", labels={"event_type": event.__class__.__name__} ) == 0.0 )
def test_unhandled_message(pathfinding_service_mock, log): metrics_state = save_metrics_state(metrics.REGISTRY) unknown_message = Processed(MessageID(123), signature=EMPTY_SIGNATURE) unknown_message.sign(LocalSigner(PARTICIPANT1_PRIVKEY)) pathfinding_service_mock.handle_message(unknown_message) # Although the message is unknown and will be ignored, # it is still logged under it's message type assert (metrics_state.get_delta( "messages_processing_duration_seconds_sum", labels={"message_type": "Processed"}, ) > 0.0) assert (metrics_state.get_delta("messages_exceptions_total", labels={"message_type": "Processed"}) == 0.0) assert log.has("Ignoring message", unknown_message=unknown_message)