def test_pfs_handler_handle_paymentsentsuccess_without_feedback_token(): ( raiden, pfs_handler, token_network_registry_address, token_network_address, route, _, ) = setup_pfs_handler_test(set_feedback_token=False) payment_id = make_payment_id() amount = PaymentAmount(123) target = TargetAddress(route[-1]) raiden.targets_to_identifiers_to_statuses[target][payment_id] = Mock() route_failed_event = EventPaymentSentSuccess( token_network_registry_address=token_network_registry_address, token_network_address=token_network_address, identifier=payment_id, amount=amount, target=TargetAddress(target), secret=make_secret(), route=route, ) with patch("raiden.raiden_event_handler.post_pfs_feedback" ) as pfs_feedback_handler: pfs_handler.on_raiden_events( raiden=raiden, chain_state=cast( ChainState, raiden.wal.state_manager.current_state), # type: ignore events=[route_failed_event], ) assert not pfs_feedback_handler.called
def test_automatic_secret_registration( raiden_chain: List[App], token_addresses: List[TokenAddress] ) -> None: app0, app1 = raiden_chain token_address = token_addresses[0] token_network_address = views.get_token_network_address_by_token_address( views.state_from_app(app0), app0.raiden.default_registry.address, token_address ) assert token_network_address hold_event_handler = app1.raiden.raiden_event_handler message_handler = app1.raiden.message_handler msg = "hold event handler necessary to control messages" assert isinstance(hold_event_handler, HoldRaidenEventHandler), msg assert isinstance(message_handler, WaitForMessage), msg amount = PaymentAmount(100) identifier = factories.make_payment_id() target = TargetAddress(app1.raiden.address) (secret, secrethash) = factories.make_secret_with_hash() hold_event_handler.hold_secretrequest_for(secrethash=secrethash) locked_transfer_received = message_handler.wait_for_message(LockedTransfer, {}) app0.raiden.start_mediated_transfer_with_secret( token_network_address=token_network_address, amount=amount, target=target, identifier=identifier, secret=secret, ) # Wait for app1 to receive the locked transfer. locked_transfer_received.wait() # Stop app0 to avoid sending the unlock, this must be done after the locked # transfer is sent. app0.raiden.transport.stop() reveal_secret = RevealSecret( message_identifier=MessageID(random.randint(0, UINT64_MAX)), secret=secret, signature=EMPTY_SIGNATURE, ) app0.raiden.sign(reveal_secret) message_handler.on_messages(app1.raiden, [reveal_secret]) chain_state = views.state_from_app(app1) secrethash = sha256_secrethash(secret) target_task = chain_state.payment_mapping.secrethashes_to_task[secrethash] lock_expiration = target_task.target_state.transfer.lock.expiration # type: ignore app1.raiden.proxy_manager.client.wait_until_block(target_block_number=lock_expiration) assert app1.raiden.default_secret_registry.is_secret_registered( secrethash=secrethash, block_identifier=BLOCK_ID_LATEST )
def test_pfs_handler_handle_paymentsentsuccess_with_feedback_token(): ( raiden, pfs_handler, token_network_registry_address, token_network_address, route, feedback_uuid, ) = setup_pfs_handler_test(set_feedback_token=True) payment_id = make_payment_id() amount = PaymentAmount(123) target = TargetAddress(route[-1]) raiden.targets_to_identifiers_to_statuses[target][payment_id] = Mock() route_failed_event = EventPaymentSentSuccess( token_network_registry_address=token_network_registry_address, token_network_address=token_network_address, identifier=payment_id, amount=amount, target=TargetAddress(target), secret=make_secret(), route=route, ) with patch("raiden.raiden_event_handler.post_pfs_feedback" ) as pfs_feedback_handler: pfs_handler.on_raiden_event( raiden=raiden, chain_state=cast( ChainState, raiden.wal.state_manager.current_state), # type: ignore event=route_failed_event, ) assert pfs_feedback_handler.called assert pfs_feedback_handler.call_args == call( pfs_config=raiden.config.pfs_config, route=route, routing_mode=RoutingMode.PRIVATE, successful=True, token=feedback_uuid, token_network_address=token_network_address, )
def test_get_event_with_balance_proof(): """ All events which contain a balance proof must be found by when querying the database. """ serializer = JSONSerializer() storage = SerializedSQLiteStorage(":memory:", serializer) counter = itertools.count(1) partner_address = factories.make_address() balance_proof = make_balance_proof_from_counter(counter) lock_expired = SendLockExpired( recipient=partner_address, message_identifier=MessageID(next(counter)), balance_proof=balance_proof, secrethash=factories.make_secret_hash(next(counter)), canonical_identifier=balance_proof.canonical_identifier, ) locked_transfer = SendLockedTransfer( recipient=partner_address, message_identifier=MessageID(next(counter)), transfer=make_transfer_from_counter(counter), canonical_identifier=factories.make_canonical_identifier(), ) send_balance_proof = SendBalanceProof( recipient=partner_address, message_identifier=MessageID(next(counter)), payment_identifier=factories.make_payment_id(), token_address=factories.make_token_address(), secret=factories.make_secret(next(counter)), balance_proof=make_balance_proof_from_counter(counter), canonical_identifier=factories.make_canonical_identifier(), ) refund_transfer = SendRefundTransfer( recipient=partner_address, message_identifier=MessageID(next(counter)), transfer=make_transfer_from_counter(counter), canonical_identifier=factories.make_canonical_identifier(), ) events_balanceproofs = [ (lock_expired, lock_expired.balance_proof), (locked_transfer, locked_transfer.balance_proof), (send_balance_proof, send_balance_proof.balance_proof), (refund_transfer, refund_transfer.transfer.balance_proof), ] state_change = Block(BlockNumber(1), BlockGasLimit(1), factories.make_block_hash()) for event, _ in events_balanceproofs: state_change_identifiers = storage.write_state_changes([state_change]) storage.write_events(events=[(state_change_identifiers[0], event)]) for event, balance_proof in events_balanceproofs: event_record = get_event_with_balance_proof_by_balance_hash( storage=storage, canonical_identifier=balance_proof.canonical_identifier, balance_hash=balance_proof.balance_hash, recipient=partner_address, ) assert event_record assert event_record.data == event event_record = get_event_with_balance_proof_by_locksroot( storage=storage, canonical_identifier=balance_proof.canonical_identifier, recipient=event.recipient, locksroot=balance_proof.locksroot, ) assert event_record assert event_record.data == event # Checking that balance proof attribute can be accessed for all events. # Issue https://github.com/raiden-network/raiden/issues/3179 assert event_record.data.balance_proof == event.balance_proof storage.close()
def test_encoding_and_decoding(): message_factories = ( factories.LockedTransferProperties(), factories.RefundTransferProperties(), factories.LockExpiredProperties(), factories.UnlockProperties(), ) messages = [factories.create(factory) for factory in message_factories] # TODO Handle these with factories once #5091 is implemented messages.append( Delivered( delivered_message_identifier=factories.make_message_identifier(), signature=factories.make_signature(), )) messages.append( Processed( message_identifier=factories.make_message_identifier(), signature=factories.make_signature(), )) messages.append( RevealSecret( message_identifier=factories.make_message_identifier(), secret=factories.make_secret(), signature=factories.make_signature(), )) messages.append( SecretRequest( message_identifier=factories.make_message_identifier(), payment_identifier=factories.make_payment_id(), secrethash=factories.make_secret_hash(), amount=factories.make_token_amount(), expiration=factories.make_block_number(), signature=factories.make_signature(), )) messages.append( WithdrawRequest( message_identifier=factories.make_message_identifier(), chain_id=factories.make_chain_id(), token_network_address=factories.make_token_network_address(), channel_identifier=factories.make_channel_identifier(), participant=factories.make_address(), total_withdraw=factories.make_token_amount(), nonce=factories.make_nonce(), expiration=factories.make_block_number(), signature=factories.make_signature(), )) messages.append( WithdrawConfirmation( message_identifier=factories.make_message_identifier(), chain_id=factories.make_chain_id(), token_network_address=factories.make_token_network_address(), channel_identifier=factories.make_channel_identifier(), participant=factories.make_address(), total_withdraw=factories.make_token_amount(), nonce=factories.make_nonce(), expiration=factories.make_block_number(), signature=factories.make_signature(), )) messages.append( WithdrawExpired( message_identifier=factories.make_message_identifier(), chain_id=factories.make_chain_id(), token_network_address=factories.make_token_network_address(), channel_identifier=factories.make_channel_identifier(), participant=factories.make_address(), total_withdraw=factories.make_token_amount(), nonce=factories.make_nonce(), expiration=factories.make_block_number(), signature=factories.make_signature(), )) messages.append( PFSCapacityUpdate( canonical_identifier=factories.make_canonical_identifier(), updating_participant=factories.make_address(), other_participant=factories.make_address(), updating_nonce=factories.make_nonce(), other_nonce=factories.make_nonce(), updating_capacity=factories.make_token_amount(), other_capacity=factories.make_token_amount(), reveal_timeout=factories.make_uint64(), signature=factories.make_signature(), )) messages.append( PFSFeeUpdate( canonical_identifier=factories.make_canonical_identifier(), updating_participant=factories.make_address(), fee_schedule=factories.create( factories.FeeScheduleStateProperties()), timestamp=datetime.now(), signature=factories.make_signature(), )) messages.append( RequestMonitoring( reward_amount=factories.make_token_amount(), balance_proof=SignedBlindedBalanceProof. from_balance_proof_signed_state( factories.create( factories.BalanceProofSignedStateProperties())), monitoring_service_contract_address=factories.make_address(), non_closing_participant=factories.make_address(), non_closing_signature=factories.make_signature(), signature=factories.make_signature(), )) for message in messages: serialized = MessageSerializer.serialize(message) deserialized = MessageSerializer.deserialize(serialized) assert deserialized == message
Processed( message_identifier=factories.make_message_identifier(), signature=factories.make_signature(), ) ) messages.append( RevealSecret( message_identifier=factories.make_message_identifier(), secret=factories.make_secret(), signature=factories.make_signature(), ) ) messages.append( SecretRequest( message_identifier=factories.make_message_identifier(), payment_identifier=factories.make_payment_id(), secrethash=factories.make_secret_hash(), amount=factories.make_payment_amount(), expiration=factories.make_block_expiration_number(), signature=factories.make_signature(), ) ) messages.append( WithdrawRequest( message_identifier=factories.make_message_identifier(), chain_id=factories.make_chain_id(), token_network_address=factories.make_token_network_address(), channel_identifier=factories.make_channel_identifier(), participant=factories.make_address(), total_withdraw=factories.make_withdraw_amount(), nonce=factories.make_nonce(),
def test_settled_lock( token_addresses: List[TokenAddress], raiden_network: List[App], deposit: TokenAmount ) -> None: """ Any transfer following a secret reveal must update the locksroot, so that an attacker cannot reuse a secret to double claim a lock. """ app0, app1 = raiden_network registry_address = app0.raiden.default_registry.address token_address = token_addresses[0] amount = PaymentAmount(30) token_network_address = views.get_token_network_address_by_token_address( views.state_from_app(app0), app0.raiden.default_registry.address, token_address ) assert token_network_address hold_event_handler = app1.raiden.raiden_event_handler msg = "hold event handler necessary to control messages" assert isinstance(hold_event_handler, HoldRaidenEventHandler), msg address0 = app0.raiden.address address1 = app1.raiden.address deposit0 = deposit deposit1 = deposit token_proxy = app0.raiden.proxy_manager.token(token_address, BLOCK_ID_LATEST) initial_balance0 = token_proxy.balance_of(address0) initial_balance1 = token_proxy.balance_of(address1) identifier = factories.make_payment_id() target = TargetAddress(app1.raiden.address) secret = factories.make_secret() secrethash = sha256_secrethash(secret) secret_available = hold_event_handler.hold_secretrequest_for(secrethash=secrethash) app0.raiden.start_mediated_transfer_with_secret( token_network_address=token_network_address, amount=amount, target=target, identifier=identifier, secret=secret, ) secret_available.wait() # wait for the messages to be exchanged # Save the pending locks from the pending transfer, used to test the unlock channelstate_0_1 = get_channelstate(app0, app1, token_network_address) batch_unlock = channel.get_batch_unlock(channelstate_0_1.our_state) assert batch_unlock hold_event_handler.release_secretrequest_for(app1.raiden, secrethash) transfer( initiator_app=app0, target_app=app1, token_address=token_address, amount=amount, identifier=PaymentID(2), ) # The channel state has to be recovered before the settlement, otherwise # the object is cleared from the node's state. channelstate_1_0 = get_channelstate(app1, app0, token_network_address) RaidenAPI(app1.raiden).channel_close(registry_address, token_address, app0.raiden.address) waiting.wait_for_settle( app1.raiden, app1.raiden.default_registry.address, token_address, [channelstate_0_1.identifier], app1.raiden.alarm.sleep_time, ) current_block = app0.raiden.rpc_client.block_number() netting_channel = app1.raiden.proxy_manager.payment_channel( channel_state=channelstate_1_0, block_identifier=BLOCK_ID_LATEST ) # The transfer locksroot must not contain the unlocked lock, the # unlock must fail. with pytest.raises(RaidenUnrecoverableError): netting_channel.unlock( sender=channelstate_0_1.our_state.address, receiver=channelstate_0_1.partner_state.address, pending_locks=batch_unlock, given_block_identifier=current_block, ) expected_balance0 = initial_balance0 + deposit0 - amount * 2 expected_balance1 = initial_balance1 + deposit1 + amount * 2 assert token_proxy.balance_of(address0) == expected_balance0 assert token_proxy.balance_of(address1) == expected_balance1
def test_lock_expiry( raiden_network: List[App], token_addresses: List[TokenAddress], deposit: TokenAmount ) -> None: """Test lock expiry and removal.""" alice_app, bob_app = raiden_network token_address = token_addresses[0] token_network_address = views.get_token_network_address_by_token_address( views.state_from_app(alice_app), alice_app.raiden.default_registry.address, token_address ) assert token_network_address hold_event_handler = bob_app.raiden.raiden_event_handler wait_message_handler = bob_app.raiden.message_handler msg = "hold event handler necessary to control messages" assert isinstance(hold_event_handler, HoldRaidenEventHandler), msg assert isinstance(wait_message_handler, WaitForMessage), msg token_network = views.get_token_network_by_address( views.state_from_app(alice_app), token_network_address ) assert token_network channel_state = get_channelstate(alice_app, bob_app, token_network_address) channel_identifier = channel_state.identifier assert ( channel_identifier in token_network.partneraddresses_to_channelidentifiers[bob_app.raiden.address] ) alice_to_bob_amount = PaymentAmount(10) identifier = factories.make_payment_id() target = TargetAddress(bob_app.raiden.address) transfer_1_secret = factories.make_secret(0) transfer_1_secrethash = sha256_secrethash(transfer_1_secret) transfer_2_secret = factories.make_secret(1) transfer_2_secrethash = sha256_secrethash(transfer_2_secret) hold_event_handler.hold_secretrequest_for(secrethash=transfer_1_secrethash) transfer1_received = wait_message_handler.wait_for_message( LockedTransfer, {"lock": {"secrethash": transfer_1_secrethash}} ) transfer2_received = wait_message_handler.wait_for_message( LockedTransfer, {"lock": {"secrethash": transfer_2_secrethash}} ) remove_expired_lock_received = wait_message_handler.wait_for_message( LockExpired, {"secrethash": transfer_1_secrethash} ) alice_app.raiden.start_mediated_transfer_with_secret( token_network_address=token_network_address, amount=alice_to_bob_amount, target=target, identifier=identifier, secret=transfer_1_secret, ) transfer1_received.wait() alice_bob_channel_state = get_channelstate(alice_app, bob_app, token_network_address) lock = channel.get_lock(alice_bob_channel_state.our_state, transfer_1_secrethash) assert lock # This is the current state of the protocol: # # A -> B LockedTransfer # B -> A SecretRequest # - protocol didn't continue assert_synced_channel_state( token_network_address, alice_app, Balance(deposit), [lock], bob_app, Balance(deposit), [] ) # Verify lock is registered in both channel states alice_channel_state = get_channelstate(alice_app, bob_app, token_network_address) assert transfer_1_secrethash in alice_channel_state.our_state.secrethashes_to_lockedlocks bob_channel_state = get_channelstate(bob_app, alice_app, token_network_address) assert transfer_1_secrethash in bob_channel_state.partner_state.secrethashes_to_lockedlocks alice_chain_state = views.state_from_raiden(alice_app.raiden) assert transfer_1_secrethash in alice_chain_state.payment_mapping.secrethashes_to_task remove_expired_lock_received.wait() alice_channel_state = get_channelstate(alice_app, bob_app, token_network_address) assert transfer_1_secrethash not in alice_channel_state.our_state.secrethashes_to_lockedlocks # Verify Bob received the message and processed the LockExpired message bob_channel_state = get_channelstate(bob_app, alice_app, token_network_address) assert transfer_1_secrethash not in bob_channel_state.partner_state.secrethashes_to_lockedlocks alice_chain_state = views.state_from_raiden(alice_app.raiden) assert transfer_1_secrethash not in alice_chain_state.payment_mapping.secrethashes_to_task # Make another transfer alice_to_bob_amount = PaymentAmount(10) identifier = factories.make_payment_id() hold_event_handler.hold_secretrequest_for(secrethash=transfer_2_secrethash) alice_app.raiden.start_mediated_transfer_with_secret( token_network_address=token_network_address, amount=alice_to_bob_amount, target=target, identifier=identifier, secret=transfer_2_secret, ) transfer2_received.wait() # Make sure the other transfer still exists alice_chain_state = views.state_from_raiden(alice_app.raiden) assert transfer_2_secrethash in alice_chain_state.payment_mapping.secrethashes_to_task bob_channel_state = get_channelstate(bob_app, alice_app, token_network_address) assert transfer_2_secrethash in bob_channel_state.partner_state.secrethashes_to_lockedlocks