def run_test_automatic_secret_registration(raiden_chain, token_addresses): app0, app1 = raiden_chain token_address = token_addresses[0] token_network_identifier = views.get_token_network_identifier_by_token_address( views.state_from_app(app0), app0.raiden.default_registry.address, token_address, ) amount = 100 identifier = 1 hold_event_handler = HoldOffChainSecretRequest() message_handler = WaitForMessage() app1.raiden.raiden_event_handler = hold_event_handler app1.raiden.message_handler = message_handler target = app1.raiden.address secret = sha3(target) secrethash = sha3(secret) 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_identifier=token_network_identifier, amount=amount, fee=0, 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=random.randint(0, UINT64_MAX), secret=secret, ) app0.raiden.sign(reveal_secret) message_handler.on_message(app1.raiden, reveal_secret) chain_state = views.state_from_app(app1) secrethash = sha3(secret) target_task = chain_state.payment_mapping.secrethashes_to_task[secrethash] lock_expiration = target_task.target_state.transfer.lock.expiration app1.raiden.chain.wait_until_block(target_block_number=lock_expiration) assert app1.raiden.default_secret_registry.is_secret_registered( secrethash=secrethash, block_identifier='latest', )
def test_automatic_secret_registration(raiden_chain, token_addresses): 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) hold_event_handler = app1.raiden.raiden_event_handler amount = 100 identifier = 1 message_handler = WaitForMessage() app1.raiden.message_handler = message_handler target = app1.raiden.address secret = Secret(sha3(target)) secrethash = sha256_secrethash(secret) 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_message(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.wait_until_block( target_block_number=lock_expiration) assert app1.raiden.default_secret_registry.is_secret_registered( secrethash=secrethash, block_identifier="latest")
def run_test_event_transfer_received_success( token_addresses, raiden_chain, ): sender_apps = raiden_chain[:-1] target_app = raiden_chain[-1] token_address = token_addresses[0] registry_address = target_app.raiden.default_registry.address target_address = target_app.raiden.address message_handler = WaitForMessage() target_app.raiden.message_handler = message_handler wait_for = list() for amount, app in enumerate(sender_apps, 1): secret = random_secret() wait = message_handler.wait_for_message( Unlock, {'secret': secret}, ) wait_for.append((wait, app.raiden.address, amount)) RaidenAPI(app.raiden).transfer_async( registry_address=registry_address, token_address=token_address, amount=amount, identifier=amount, target=target_address, secret=to_hex(secret), secret_hash=to_hex(sha3(secret)), ) for wait, sender, amount in wait_for: wait.wait() assert search_for_item( target_app.raiden.wal.storage.get_events(), EventPaymentReceivedSuccess, { 'amount': amount, 'identifier': amount, 'initiator': sender, 'payment_network_identifier': registry_address, # 'token_network_identifier': , }, )
def test_mediated_transfer_with_node_consuming_more_than_allocated_fee( raiden_network, number_of_nodes, deposit, token_addresses, network_wait): """ Tests a mediator node consuming more fees than allocated. Which means that the initiator will not reveal the secret to the target. """ app0, app1, app2 = raiden_network token_address = token_addresses[0] chain_state = views.state_from_app(app0) token_network_registry_address = app0.raiden.default_registry.address token_network_address = views.get_token_network_address_by_token_address( chain_state, token_network_registry_address, token_address) assert token_network_address amount = PaymentAmount(100) fee = FeeAmount(5) fee_margin = calculate_fee_margin(amount, fee) app1_app2_channel_state = views.get_channelstate_by_token_network_and_partner( chain_state=views.state_from_raiden(app1.raiden), token_network_address=token_network_address, partner_address=app2.raiden.address, ) assert app1_app2_channel_state # Let app1 consume all of the allocated mediation fee app1_app2_channel_state.fee_schedule = FeeScheduleState( flat=FeeAmount(fee * 2)) secret = factories.make_secret(0) secrethash = sha256_secrethash(secret) wait_message_handler = WaitForMessage() app0.raiden.message_handler = wait_message_handler secret_request_received = wait_message_handler.wait_for_message( SecretRequest, {"secrethash": secrethash}) def get_best_routes_with_fees(*args, **kwargs): routes = get_best_routes_internal(*args, **kwargs) for r in routes: r.estimated_fee = fee return routes with patch("raiden.routing.get_best_routes_internal", get_best_routes_with_fees): app0.raiden.start_mediated_transfer_with_secret( token_network_address=token_network_address, amount=amount, target=app2.raiden.address, identifier=1, secret=secret, ) app0_app1_channel_state = views.get_channelstate_by_token_network_and_partner( chain_state=views.state_from_raiden(app0.raiden), token_network_address=token_network_address, partner_address=app1.raiden.address, ) assert app0_app1_channel_state msg = "App0 should have the transfer in secrethashes_to_lockedlocks" assert secrethash in app0_app1_channel_state.our_state.secrethashes_to_lockedlocks, msg msg = "App0 should have locked the amount + fee" lock_amount = app0_app1_channel_state.our_state.secrethashes_to_lockedlocks[ secrethash].amount assert lock_amount == amount + fee + fee_margin, msg secret_request_received.wait() app0_chain_state = views.state_from_app(app0) initiator_task = cast( InitiatorTask, app0_chain_state.payment_mapping.secrethashes_to_task[secrethash]) msg = "App0 should have never revealed the secret" transfer_state = initiator_task.manager_state.initiator_transfers[ secrethash].transfer_state assert transfer_state != "transfer_secret_revealed", msg
def test_mediated_transfer_messages_out_of_order( # pylint: disable=unused-argument raiden_network, deposit, token_addresses, network_wait): """Raiden must properly handle repeated locked transfer messages.""" app0, app1, app2 = raiden_network app1_wait_for_message = WaitForMessage() app2_wait_for_message = WaitForMessage() app1.raiden.message_handler = app1_wait_for_message app2.raiden.message_handler = app2_wait_for_message secret = factories.make_secret(0) secrethash = sha256_secrethash(secret) # Save the messages, these will be processed again app1_mediatedtransfer = app1_wait_for_message.wait_for_message( LockedTransfer, {"lock": { "secrethash": secrethash }}) app2_mediatedtransfer = app2_wait_for_message.wait_for_message( LockedTransfer, {"lock": { "secrethash": secrethash }}) # Wait until the node receives a reveal secret to redispatch the locked # transfer message app1_revealsecret = app1_wait_for_message.wait_for_message( RevealSecret, {"secret": secret}) app2_revealsecret = app2_wait_for_message.wait_for_message( RevealSecret, {"secret": secret}) token_address = token_addresses[0] chain_state = views.state_from_app(app0) token_network_registry_address = app0.raiden.default_registry.address token_network_address = views.get_token_network_address_by_token_address( chain_state, token_network_registry_address, token_address) amount = 10 identifier = 1 transfer_received = app0.raiden.start_mediated_transfer_with_secret( token_network_address=token_network_address, amount=amount, target=app2.raiden.address, identifier=identifier, secret=secret, ) # - Wait until reveal secret is received to replay the message # - The secret is revealed backwards, app2 should be first # - The locked transfer is sent before the secret reveal, so the mediated # transfers async results must be set and `get_nowait` can be used app2_revealsecret.get(timeout=network_wait) mediated_transfer_msg = app2_mediatedtransfer.get_nowait() app2.raiden.message_handler.handle_message_lockedtransfer( app2.raiden, mediated_transfer_msg) app1_revealsecret.get(timeout=network_wait) app1.raiden.message_handler.handle_message_lockedtransfer( app1.raiden, app1_mediatedtransfer.get_nowait()) transfer_received.payment_done.wait() with block_timeout_for_transfer_by_secrethash(app1.raiden, secrethash): wait_assert( assert_succeeding_transfer_invariants, token_network_address, app0, deposit - amount, [], app1, deposit + amount, [], ) with block_timeout_for_transfer_by_secrethash(app2.raiden, secrethash): wait_assert( assert_succeeding_transfer_invariants, token_network_address, app1, deposit - amount, [], app2, deposit + amount, [], )
def test_recovery_happy_case( raiden_network, number_of_nodes, deposit, token_addresses, network_wait, skip_if_not_udp, ): app0, app1, app2 = raiden_network token_address = token_addresses[0] app2_wait_for = WaitForMessage() app2.raiden.message_handler = app2_wait_for chain_state = views.state_from_app(app0) payment_network_id = app0.raiden.default_registry.address token_network_identifier = views.get_token_network_identifier_by_token_address( chain_state, payment_network_id, token_address, ) # make a few transfers from app0 to app2 amount = 1 spent_amount = deposit - 2 for _ in range(spent_amount): mediated_transfer( app0, app2, token_network_identifier, amount, timeout=network_wait * number_of_nodes, ) app0.raiden.stop() host_port = ( app0.raiden.config['transport']['udp']['host'], app0.raiden.config['transport']['udp']['port'], ) socket = server._udp_socket(host_port) new_transport = UDPTransport( app0.raiden.address, app0.discovery, socket, app0.raiden.transport.throttle_policy, app0.raiden.config['transport']['udp'], ) raiden_event_handler = RaidenEventHandler() message_handler = MessageHandler() app0_restart = App( config=app0.config, chain=app0.raiden.chain, query_start_block=0, default_registry=app0.raiden.default_registry, default_secret_registry=app0.raiden.default_secret_registry, transport=new_transport, raiden_event_handler=raiden_event_handler, message_handler=message_handler, discovery=app0.raiden.discovery, ) app0.stop() del app0 # from here on the app0_restart should be used app0_restart.start() assert_synced_channel_state( token_network_identifier, app0_restart, deposit - spent_amount, [], app1, deposit + spent_amount, [], ) assert_synced_channel_state( token_network_identifier, app1, deposit - spent_amount, [], app2, deposit + spent_amount, [], ) # wait for the nodes' healthcheck to update the network statuses waiting.wait_for_healthy( app0_restart.raiden, app1.raiden.address, network_wait, ) waiting.wait_for_healthy( app1.raiden, app0_restart.raiden.address, network_wait, ) identifier = create_default_identifier() wait_for_payment = app2_wait_for.wait_for_message(Secret, {'payment_identifier': identifier}) mediated_transfer( app2, app0_restart, token_network_identifier, amount, timeout=network_wait * number_of_nodes * 2, ) mediated_transfer( initiator_app=app0_restart, target_app=app2, token_network_identifier=token_network_identifier, amount=amount, identifier=identifier, timeout=network_wait * number_of_nodes * 2, ) assert_synced_channel_state( token_network_identifier, app0_restart, deposit - spent_amount, [], app1, deposit + spent_amount, [], ) wait_for_payment.wait() assert_synced_channel_state( token_network_identifier, app1, deposit - spent_amount, [], app2, deposit + spent_amount, [], )
def test_echo_node_response(token_addresses, raiden_chain, retry_timeout): app0, app1, echo_app = raiden_chain token_address = token_addresses[0] registry_address = echo_app.raiden.default_registry.address echo_api = RaidenAPI(echo_app.raiden) echo_node = EchoNode(echo_api, token_address) message_handler = WaitForMessage() echo_app.raiden.message_handler = message_handler echo_node.ready.wait(timeout=30) assert echo_node.ready.is_set() transfer_timeout = 10 wait_for = list() for num, app in enumerate([app0, app1]): amount = PaymentAmount(1 + num) identifier = PaymentID(10 ** (num + 1)) secret, secrethash = make_secret_with_hash() payment_status = RaidenAPI(app.raiden).transfer_async( registry_address=registry_address, token_address=token_address, amount=amount, target=echo_app.raiden.address, identifier=identifier, secret=secret, secrethash=secrethash, ) wait = message_handler.wait_for_message(Unlock, {"secret": secret}) wait_for.append((wait, app.raiden.address, amount, identifier)) msg = ( f"Transfer {identifier} from " f"{to_checksum_address(app.raiden.address)} to " f"{to_checksum_address(echo_app.raiden.address)} timed out after " f"{transfer_timeout}" ) timeout = gevent.Timeout(transfer_timeout, exception=RuntimeError(msg)) with watch_for_unlock_failures(*raiden_chain), timeout: payment_status.payment_done.wait() echo_identifier = PaymentID(identifier + amount) msg = ( f"Response transfer {echo_identifier} from echo node " f"{to_checksum_address(echo_app.raiden.address)} to " f"{to_checksum_address(app.raiden.address)} timed out after " f"{transfer_timeout}" ) with gevent.Timeout(transfer_timeout, exception=RuntimeError(msg)): result = wait_for_received_transfer_result( raiden=app.raiden, payment_identifier=echo_identifier, amount=amount, retry_timeout=retry_timeout, secrethash=secrethash, ) assert result == TransferWaitResult.UNLOCKED for wait, sender, amount, ident in wait_for: wait.wait() assert search_for_item( echo_app.raiden.wal.storage.get_events(), EventPaymentReceivedSuccess, { "amount": amount, "identifier": ident, "initiator": sender, "token_network_registry_address": registry_address, }, ) echo_node.stop()
def test_lock_expiry(raiden_network, token_addresses, deposit): """Test lock expiry and removal.""" alice_app, bob_app = raiden_network token_address = token_addresses[0] token_network_identifier = views.get_token_network_identifier_by_token_address( views.state_from_app(alice_app), alice_app.raiden.default_registry.address, token_address, ) hold_event_handler = HoldOffChainSecretRequest() wait_message_handler = WaitForMessage() bob_app.raiden.message_handler = wait_message_handler bob_app.raiden.raiden_event_handler = hold_event_handler token_network = views.get_token_network_by_identifier( views.state_from_app(alice_app), token_network_identifier, ) channel_state = get_channelstate(alice_app, bob_app, token_network_identifier) channel_identifier = channel_state.identifier assert channel_identifier in token_network.partneraddresses_to_channelidentifiers[ bob_app.raiden.address ] alice_to_bob_amount = 10 identifier = 1 target = bob_app.raiden.address transfer_1_secret = factories.make_secret(0) transfer_1_secrethash = sha3(transfer_1_secret) transfer_2_secret = factories.make_secret(1) transfer_2_secrethash = sha3(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_identifier, alice_to_bob_amount, target, identifier, transfer_1_secret, ) transfer1_received.wait() alice_bob_channel_state = get_channelstate(alice_app, bob_app, token_network_identifier) lock = channel.get_lock(alice_bob_channel_state.our_state, transfer_1_secrethash) # This is the current state of the protocol: # # A -> B LockedTransfer # B -> A SecretRequest # - protocol didn't continue assert_synced_channel_state( token_network_identifier, alice_app, deposit, [lock], bob_app, deposit, [], ) # Verify lock is registered in both channel states alice_channel_state = get_channelstate(alice_app, bob_app, token_network_identifier) assert transfer_1_secrethash in alice_channel_state.our_state.secrethashes_to_lockedlocks bob_channel_state = get_channelstate(bob_app, alice_app, token_network_identifier) 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_identifier) 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_identifier) 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 = 10 identifier = 2 hold_event_handler.hold_secretrequest_for(secrethash=transfer_2_secrethash) alice_app.raiden.start_mediated_transfer_with_secret( token_network_identifier, alice_to_bob_amount, target, identifier, 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_identifier) assert transfer_2_secrethash in bob_channel_state.partner_state.secrethashes_to_lockedlocks
def test_lock_expiry(raiden_network, token_addresses, deposit): """Test lock expiry and removal.""" alice_app, bob_app = raiden_network token_address = token_addresses[0] token_network_identifier = views.get_token_network_identifier_by_token_address( views.state_from_app(alice_app), alice_app.raiden.default_registry.address, token_address, ) hold_event_handler = HoldOffChainSecretRequest() wait_message_handler = WaitForMessage() bob_app.raiden.message_handler = wait_message_handler bob_app.raiden.raiden_event_handler = hold_event_handler token_network = views.get_token_network_by_identifier( views.state_from_app(alice_app), token_network_identifier, ) channel_state = get_channelstate(alice_app, bob_app, token_network_identifier) channel_identifier = channel_state.identifier assert channel_identifier in token_network.partneraddresses_to_channelidentifiers[ bob_app.raiden.address] alice_to_bob_amount = 10 identifier = 1 target = bob_app.raiden.address transfer_1_secret = factories.make_secret(0) transfer_1_secrethash = sha3(transfer_1_secret) transfer_2_secret = factories.make_secret(1) transfer_2_secrethash = sha3(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_identifier, alice_to_bob_amount, target, identifier, transfer_1_secret, ) transfer1_received.wait() alice_bob_channel_state = get_channelstate(alice_app, bob_app, token_network_identifier) lock = channel.get_lock(alice_bob_channel_state.our_state, transfer_1_secrethash) # This is the current state of the protocol: # # A -> B LockedTransfer # B -> A SecretRequest # - protocol didn't continue assert_synced_channel_state( token_network_identifier, alice_app, deposit, [lock], bob_app, deposit, [], ) # Verify lock is registered in both channel states alice_channel_state = get_channelstate(alice_app, bob_app, token_network_identifier) assert transfer_1_secrethash in alice_channel_state.our_state.secrethashes_to_lockedlocks bob_channel_state = get_channelstate(bob_app, alice_app, token_network_identifier) 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_identifier) 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_identifier) 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 = 10 identifier = 2 hold_event_handler.hold_secretrequest_for(secrethash=transfer_2_secrethash) alice_app.raiden.start_mediated_transfer_with_secret( token_network_identifier, alice_to_bob_amount, target, identifier, 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_identifier) assert transfer_2_secrethash in bob_channel_state.partner_state.secrethashes_to_lockedlocks
def run_test_mediated_transfer_with_node_consuming_more_than_allocated_fee( raiden_network, number_of_nodes, deposit, token_addresses, network_wait): app0, app1, app2 = raiden_network token_address = token_addresses[0] chain_state = views.state_from_app(app0) payment_network_id = app0.raiden.default_registry.address token_network_identifier = views.get_token_network_identifier_by_token_address( chain_state, payment_network_id, token_address) fee = 5 amount = 10 app1_app2_channel_state = views.get_channelstate_by_token_network_and_partner( chain_state=views.state_from_raiden(app1.raiden), token_network_id=token_network_identifier, partner_address=app2.raiden.address, ) # Let app1 consume all of the allocated mediation fee action_set_fee = ActionChannelSetFee( canonical_identifier=app1_app2_channel_state.canonical_identifier, mediation_fee=fee * 2) app1.raiden.handle_state_change(state_change=action_set_fee) secret = factories.make_secret(0) secrethash = sha3(secret) wait_message_handler = WaitForMessage() app0.raiden.message_handler = wait_message_handler secret_request_received = wait_message_handler.wait_for_message( SecretRequest, {"secrethash": secrethash}) app0.raiden.start_mediated_transfer_with_secret( token_network_identifier=token_network_identifier, amount=amount, fee=fee, target=app2.raiden.address, identifier=1, payment_hash_invoice=EMPTY_PAYMENT_HASH_INVOICE, secret=secret, ) app0_app1_channel_state = views.get_channelstate_by_token_network_and_partner( chain_state=views.state_from_raiden(app0.raiden), token_network_id=token_network_identifier, partner_address=app1.raiden.address, ) msg = "App0 should have the transfer in secrethashes_to_lockedlocks" assert secrethash in app0_app1_channel_state.our_state.secrethashes_to_lockedlocks, msg msg = "App0 should have locked the amount + fee" lock_amount = app0_app1_channel_state.our_state.secrethashes_to_lockedlocks[ secrethash].amount assert lock_amount == amount + fee, msg secret_request_received.wait() app0_chain_state = views.state_from_app(app0) initiator_task = app0_chain_state.payment_mapping.secrethashes_to_task[ secrethash] msg = "App0 should have never revealed the secret" assert initiator_task.manager_state.initiator_transfers[ secrethash].revealsecret is None
def run_test_mediated_transfer_messages_out_of_order(raiden_network, deposit, token_addresses, network_wait): """Raiden must properly handle repeated locked transfer messages.""" app0, app1, app2 = raiden_network app1_wait_for_message = WaitForMessage() app2_wait_for_message = WaitForMessage() app1.raiden.message_handler = app1_wait_for_message app2.raiden.message_handler = app2_wait_for_message secret = factories.make_secret(0) secrethash = sha3(secret) # Save the messages, these will be processed again app1_mediatedtransfer = app1_wait_for_message.wait_for_message( LockedTransfer, {"lock": { "secrethash": secrethash }}) app2_mediatedtransfer = app2_wait_for_message.wait_for_message( LockedTransfer, {"lock": { "secrethash": secrethash }}) # Wait until the node receives a reveal secret to redispatch the locked # transfer message app1_revealsecret = app1_wait_for_message.wait_for_message( RevealSecret, {"secret": secret}) app2_revealsecret = app2_wait_for_message.wait_for_message( RevealSecret, {"secret": secret}) token_address = token_addresses[0] chain_state = views.state_from_app(app0) payment_network_id = app0.raiden.default_registry.address token_network_identifier = views.get_token_network_identifier_by_token_address( chain_state, payment_network_id, token_address) amount = 10 identifier = 1 transfer_received = app0.raiden.start_mediated_transfer_with_secret( token_network_identifier=token_network_identifier, amount=amount, fee=0, target=app2.raiden.address, identifier=identifier, payment_hash_invoice=EMPTY_PAYMENT_HASH_INVOICE, secret=secret, ) # - Wait until reveal secret is received to replay the message # - The secret is revealed backwards, app2 should be first # - The locked transfer is sent before the secret reveal, so the mediated # transfers async results must be set and `get_nowait` can be used app2_revealsecret.get(timeout=network_wait) mediated_transfer_msg = app2_mediatedtransfer.get_nowait() app2.raiden.message_handler.handle_message_lockedtransfer( app2.raiden, mediated_transfer_msg) app1_revealsecret.get(timeout=network_wait) app1.raiden.message_handler.handle_message_lockedtransfer( app1.raiden, app1_mediatedtransfer.get_nowait()) transfer_received.payment_done.wait() with gevent.Timeout(network_wait): wait_assert( assert_synced_channel_state, token_network_identifier, app0, deposit - amount, [], app1, deposit + amount, [], ) with gevent.Timeout(network_wait): wait_assert( assert_synced_channel_state, token_network_identifier, app1, deposit - amount, [], app2, deposit + amount, [], )
def test_recovery_happy_case( raiden_network, number_of_nodes, deposit, token_addresses, network_wait, skip_if_not_udp, ): app0, app1, app2 = raiden_network token_address = token_addresses[0] app2_wait_for = WaitForMessage() app2.raiden.message_handler = app2_wait_for chain_state = views.state_from_app(app0) payment_network_id = app0.raiden.default_registry.address token_network_identifier = views.get_token_network_identifier_by_token_address( chain_state, payment_network_id, token_address, ) # make a few transfers from app0 to app2 amount = 1 spent_amount = deposit - 2 for _ in range(spent_amount): mediated_transfer( app0, app2, token_network_identifier, amount, timeout=network_wait * number_of_nodes, ) app0.raiden.stop() host_port = ( app0.raiden.config['transport']['udp']['host'], app0.raiden.config['transport']['udp']['port'], ) socket = server._udp_socket(host_port) new_transport = UDPTransport( app0.raiden.address, app0.discovery, socket, app0.raiden.transport.throttle_policy, app0.raiden.config['transport']['udp'], ) raiden_event_handler = RaidenEventHandler() message_handler = MessageHandler() app0_restart = App( config=app0.config, chain=app0.raiden.chain, query_start_block=0, default_registry=app0.raiden.default_registry, default_secret_registry=app0.raiden.default_secret_registry, transport=new_transport, raiden_event_handler=raiden_event_handler, message_handler=message_handler, discovery=app0.raiden.discovery, ) app0.stop() del app0 # from here on the app0_restart should be used app0_restart.start() assert_synced_channel_state( token_network_identifier, app0_restart, deposit - spent_amount, [], app1, deposit + spent_amount, [], ) assert_synced_channel_state( token_network_identifier, app1, deposit - spent_amount, [], app2, deposit + spent_amount, [], ) # wait for the nodes' healthcheck to update the network statuses waiting.wait_for_healthy( app0_restart.raiden, app1.raiden.address, network_wait, ) waiting.wait_for_healthy( app1.raiden, app0_restart.raiden.address, network_wait, ) identifier = create_default_identifier() wait_for_payment = app2_wait_for.wait_for_message( Unlock, {'payment_identifier': identifier}) mediated_transfer( app2, app0_restart, token_network_identifier, amount, timeout=network_wait * number_of_nodes * 2, ) mediated_transfer( initiator_app=app0_restart, target_app=app2, token_network_identifier=token_network_identifier, amount=amount, identifier=identifier, timeout=network_wait * number_of_nodes * 2, ) assert_synced_channel_state( token_network_identifier, app0_restart, deposit - spent_amount, [], app1, deposit + spent_amount, [], ) wait_for_payment.wait() assert_synced_channel_state( token_network_identifier, app1, deposit - spent_amount, [], app2, deposit + spent_amount, [], )