def test_regression_multiple_revealsecret(raiden_network, token_addresses, transport_config): """ Multiple RevealSecret messages arriving at the same time must be handled properly. Secret handling followed these steps: The Secret message arrives The secret is registered The channel is updated and the correspoding lock is removed * A balance proof for the new channel state is created and sent to the payer The channel is unregistered for the given secrethash The step marked with an asterisk above introduced a context-switch. This allowed a second Reveal Secret message to be handled before the channel was unregistered. And because the channel was already updated an exception was raised for an unknown secret. """ app0, app1 = raiden_network token = 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, ) channelstate_0_1 = get_channelstate(app0, app1, token_network_identifier) payment_identifier = 1 secret = sha3(b'test_regression_multiple_revealsecret') secrethash = sha3(secret) expiration = app0.raiden.get_block_number() + 100 lock_amount = 10 lock = Lock( lock_amount, expiration, secrethash, ) nonce = 1 transferred_amount = 0 mediated_transfer = LockedTransfer( chain_id=UNIT_CHAIN_ID, message_identifier=random.randint(0, UINT64_MAX), payment_identifier=payment_identifier, nonce=nonce, token_network_address=app0.raiden.default_registry.address, token=token, channel_identifier=channelstate_0_1.identifier, transferred_amount=transferred_amount, locked_amount=lock_amount, recipient=app1.raiden.address, locksroot=lock.secrethash, lock=lock, target=app1.raiden.address, initiator=app0.raiden.address, ) app0.raiden.sign(mediated_transfer) if transport_config.protocol is TransportProtocol.UDP: message_data = mediated_transfer.encode() host_port = None app1.raiden.transport.receive(message_data, host_port) elif transport_config.protocol is TransportProtocol.MATRIX: app1.raiden.transport._receive_message(mediated_transfer) else: raise TypeError('Unknown TransportProtocol') reveal_secret = RevealSecret( random.randint(0, UINT64_MAX), secret, ) app0.raiden.sign(reveal_secret) token_network_identifier = channelstate_0_1.token_network_identifier secret = Secret( chain_id=UNIT_CHAIN_ID, message_identifier=random.randint(0, UINT64_MAX), payment_identifier=payment_identifier, nonce=mediated_transfer.nonce + 1, token_network_address=token_network_identifier, channel_identifier=channelstate_0_1.identifier, transferred_amount=lock_amount, locked_amount=0, locksroot=EMPTY_MERKLE_ROOT, secret=secret, ) app0.raiden.sign(secret) if transport_config.protocol is TransportProtocol.UDP: messages = [ secret.encode(), reveal_secret.encode(), ] host_port = None receive_method = app1.raiden.transport.receive wait = [ gevent.spawn_later( .1, receive_method, data, host_port, ) for data in messages ] elif transport_config.protocol is TransportProtocol.MATRIX: messages = [ secret, reveal_secret, ] receive_method = app1.raiden.transport._receive_message wait = [ gevent.spawn_later( .1, receive_method, data, ) for data in messages ] else: raise TypeError('Unknown TransportProtocol') gevent.joinall(wait)
def test_regression_multiple_revealsecret(raiden_network, token_addresses): """ Multiple RevealSecret messages arriving at the same time must be handled properly. Secret handling followed these steps: The Secret message arrives The secret is registered The channel is updated and the correspoding lock is removed * A balance proof for the new channel state is created and sent to the payer The channel is unregistered for the given hashlock The step marked with an asterisk above introduced a context-switch, this allowed a second Reveal Secret message to be handled before the channel was unregistered, because the channel was already updated an exception was raised for an unknown secret. """ app0, app1 = raiden_network token = token_addresses[0] identifier = 1 secret = sha3(b'test_regression_multiple_revealsecret') hashlock = sha3(secret) expiration = app0.raiden.get_block_number() + 100 amount = 10 mediated_transfer = channel(app0, app1, token).create_mediatedtransfer( transfer_initiator=app0.raiden.address, transfer_target=app1.raiden.address, fee=0, amount=amount, identifier=identifier, expiration=expiration, hashlock=hashlock, ) app0.raiden.sign(mediated_transfer) message_data = mediated_transfer.encode() app1.raiden.protocol.receive(message_data) reveal_secret = RevealSecret(secret) app0.raiden.sign(reveal_secret) reveal_secret_data = reveal_secret.encode() secret = Secret( identifier=identifier, nonce=mediated_transfer.nonce + 1, channel=channel(app0, app1, token).channel_address, transferred_amount=amount, locksroot=EMPTY_MERKLE_ROOT, secret=secret, ) app0.raiden.sign(secret) secret_data = secret.encode() messages = [ secret_data, reveal_secret_data, ] wait = [ gevent.spawn_later( .1, app1.raiden.protocol.receive, data, ) for data in messages ] gevent.joinall(wait)
def test_regression_multiple_revealsecret(raiden_network, token_addresses, transport_protocol): """ Multiple RevealSecret messages arriving at the same time must be handled properly. Secret handling followed these steps: The Secret message arrives The secret is registered The channel is updated and the correspoding lock is removed * A balance proof for the new channel state is created and sent to the payer The channel is unregistered for the given secrethash The step marked with an asterisk above introduced a context-switch. This allowed a second Reveal Secret message to be handled before the channel was unregistered. And because the channel was already updated an exception was raised for an unknown secret. """ app0, app1 = raiden_network token = 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, ) channelstate_0_1 = get_channelstate(app0, app1, token_network_identifier) payment_identifier = 1 secret = sha3(b'test_regression_multiple_revealsecret') secrethash = sha3(secret) expiration = app0.raiden.get_block_number() + 100 lock_amount = 10 lock = Lock( lock_amount, expiration, secrethash, ) nonce = 1 transferred_amount = 0 mediated_transfer = LockedTransfer( chain_id=UNIT_CHAIN_ID, message_identifier=random.randint(0, UINT64_MAX), payment_identifier=payment_identifier, nonce=nonce, token_network_address=app0.raiden.default_registry.address, token=token, channel_identifier=channelstate_0_1.identifier, transferred_amount=transferred_amount, locked_amount=lock_amount, recipient=app1.raiden.address, locksroot=lock.secrethash, lock=lock, target=app1.raiden.address, initiator=app0.raiden.address, ) app0.raiden.sign(mediated_transfer) if transport_protocol is TransportProtocol.UDP: message_data = mediated_transfer.encode() host_port = None app1.raiden.transport.receive(message_data, host_port) elif transport_protocol is TransportProtocol.MATRIX: app1.raiden.transport._receive_message(mediated_transfer) else: raise TypeError('Unknown TransportProtocol') reveal_secret = RevealSecret( random.randint(0, UINT64_MAX), secret, ) app0.raiden.sign(reveal_secret) token_network_identifier = channelstate_0_1.token_network_identifier secret = Secret( chain_id=UNIT_CHAIN_ID, message_identifier=random.randint(0, UINT64_MAX), payment_identifier=payment_identifier, nonce=mediated_transfer.nonce + 1, token_network_address=token_network_identifier, channel_identifier=channelstate_0_1.identifier, transferred_amount=lock_amount, locked_amount=0, locksroot=EMPTY_MERKLE_ROOT, secret=secret, ) app0.raiden.sign(secret) if transport_protocol is TransportProtocol.UDP: messages = [ secret.encode(), reveal_secret.encode(), ] host_port = None receive_method = app1.raiden.transport.receive wait = [ gevent.spawn_later( .1, receive_method, data, host_port, ) for data in messages ] elif transport_protocol is TransportProtocol.MATRIX: messages = [ secret, reveal_secret, ] receive_method = app1.raiden.transport._receive_message wait = [ gevent.spawn_later( .1, receive_method, data, ) for data in messages ] else: raise TypeError('Unknown TransportProtocol') gevent.joinall(wait)
def test_regression_multiple_revealsecret(raiden_network, token_addresses): """ Multiple RevealSecret messages arriving at the same time must be handled properly. Secret handling followed these steps: The Secret message arrives The secret is registered The channel is updated and the correspoding lock is removed * A balance proof for the new channel state is created and sent to the payer The channel is unregistered for the given secrethash The step marked with an asterisk above introduced a context-switch. This allowed a second Reveal Secret message to be handled before the channel was unregistered. And because the channel was already updated an exception was raised for an unknown secret. """ app0, app1 = raiden_network token = token_addresses[0] channelstate_0_1 = get_channelstate(app0, app1, token) payment_identifier = 1 secret = sha3(b'test_regression_multiple_revealsecret') secrethash = sha3(secret) expiration = app0.raiden.get_block_number() + 100 amount = 10 lock = Lock( amount, expiration, secrethash, ) nonce = 1 transferred_amount = 0 mediated_transfer = LockedTransfer( random.randint(0, UINT64_MAX), payment_identifier, nonce, token, channelstate_0_1.identifier, transferred_amount, app1.raiden.address, lock.secrethash, lock, app1.raiden.address, app0.raiden.address, ) app0.raiden.sign(mediated_transfer) message_data = mediated_transfer.encode() app1.raiden.protocol.receive(message_data) reveal_secret = RevealSecret( random.randint(0, UINT64_MAX), secret, ) app0.raiden.sign(reveal_secret) reveal_secret_data = reveal_secret.encode() secret = Secret( message_identifier=random.randint(0, UINT64_MAX), payment_identifier=payment_identifier, nonce=mediated_transfer.nonce + 1, channel=channelstate_0_1.identifier, transferred_amount=amount, locksroot=EMPTY_MERKLE_ROOT, secret=secret, ) app0.raiden.sign(secret) secret_data = secret.encode() messages = [ secret_data, reveal_secret_data, ] wait = [ gevent.spawn_later( .1, app1.raiden.protocol.receive, data, ) for data in messages ] gevent.joinall(wait)