def test_serialize_contract_send_subclass(chain_state): """Serializing must preserve class Regression test for https://github.com/raiden-network/raiden/issues/6075 """ canonical_identifier = CanonicalIdentifier( chain_identifier=ChainID(1), token_network_address=TokenNetworkAddress(factories.make_address()), channel_identifier=factories.make_channel_identifier(), ) chain_state.pending_transactions = [ ContractSendChannelClose( canonical_identifier=canonical_identifier, triggered_by_block_hash=factories.make_block_hash(), balance_proof=None, ) ] serialized_chain_state = JSONSerializer.serialize(chain_state) deserialized_chain_state = JSONSerializer.deserialize( serialized_chain_state) assert ( chain_state.pending_transactions[0].__class__.__name__ == deserialized_chain_state.pending_transactions[0].__class__.__name__) assert chain_state == deserialized_chain_state
def events_for_close(channel_state, block_number): events = list() if get_status(channel_state) in CHANNEL_STATES_PRIOR_TO_CLOSED: channel_state.close_transaction = TransactionExecutionStatus( block_number, None, None) close_event = ContractSendChannelClose( channel_state.identifier, channel_state.token_address, channel_state.partner_state.balance_proof, ) events.append(close_event) return events
def test_secret_revealed_on_chain(raiden_chain, deposit, settle_timeout, token_addresses, retry_interval_initial): """ A node must reveal the secret on-chain if it's known and the channel is closed. """ app0, app1, app2 = 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 amount = 10 identifier = 1 target = app2.raiden.address secret, secrethash = factories.make_secret_with_hash() # Reveal the secret, but do not unlock it off-chain app1_hold_event_handler = app1.raiden.raiden_event_handler app1_hold_event_handler.hold_unlock_for(secrethash=secrethash) app0.raiden.start_mediated_transfer_with_secret( token_network_address=token_network_address, amount=amount, target=target, identifier=identifier, secret=secret, ) with watch_for_unlock_failures(*raiden_chain), block_offset_timeout( app0.raiden): wait_for_state_change(app2.raiden, ReceiveSecretReveal, {"secrethash": secrethash}, retry_interval_initial) channel_state2_1 = get_channelstate(app2, app1, token_network_address) pending_lock = channel_state2_1.partner_state.secrethashes_to_unlockedlocks.get( secrethash) msg = "The lock must be registered in unlocked locks since the secret is known" assert pending_lock is not None, msg # The channels are out-of-sync. app1 has sent the unlock, however we are # intercepting it and app2 has not received the updated balance proof # Close the channel. This must register the secret on chain balance_proof = channel_state2_1.partner_state.balance_proof assert isinstance(balance_proof, BalanceProofSignedState) channel_close_event = ContractSendChannelClose( canonical_identifier=channel_state2_1.canonical_identifier, balance_proof=balance_proof, triggered_by_block_hash=app0.raiden.rpc_client. blockhash_from_blocknumber(BLOCK_ID_LATEST), ) current_state = app2.raiden.wal.state_manager.current_state app2.raiden.raiden_event_handler.on_raiden_events( raiden=app2.raiden, chain_state=current_state, events=[channel_close_event]) settle_expiration = (app0.raiden.rpc_client.block_number() + settle_timeout + DEFAULT_NUMBER_OF_BLOCK_CONFIRMATIONS) app0.raiden.proxy_manager.client.wait_until_block( target_block_number=settle_expiration) # TODO: # - assert on the transferred amounts on-chain (for settle and unlock) # The channel app0-app1 should continue with the protocol off-chain, once # the secret is released on-chain by app2 assert_synced_channel_state(token_network_address, app0, deposit - amount, [], app1, deposit + amount, []) with watch_for_unlock_failures(*raiden_chain), gevent.Timeout(10): wait_for_state_change( app2.raiden, ContractReceiveSecretReveal, {"secrethash": secrethash}, retry_interval_initial, )
def test_secret_revealed_on_chain( raiden_chain, deposit, settle_timeout, token_addresses, retry_interval, ): """ A node must reveal the secret on-chain if it's known and the channel is closed. """ app0, app1, app2 = 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 = 10 identifier = 1 target = app2.raiden.address secret = sha3(target) secrethash = sha3(secret) # Reveal the secret, but do not unlock it off-chain app1_hold_event_handler = HoldOffChainSecretRequest() app1.raiden.raiden_event_handler = app1_hold_event_handler app1_hold_event_handler.hold_unlock_for(secrethash=secrethash) app0.raiden.start_mediated_transfer_with_secret( token_network_identifier, amount, target, identifier, secret, ) with gevent.Timeout(10): wait_for_state_change( app2.raiden, ReceiveSecretReveal, {'secrethash': secrethash}, retry_interval, ) channel_state2_1 = get_channelstate(app2, app1, token_network_identifier) pending_lock = channel_state2_1.partner_state.secrethashes_to_unlockedlocks.get( secrethash) msg = "The lock must be registered in unlocked locks since the secret is known" assert pending_lock is not None, msg # The channels are out-of-sync. app1 has sent the unlock, however we are # intercepting it and app2 has not received the updated balance proof # Close the channel. This must register the secret on chain channel_close_event = ContractSendChannelClose( channel_identifier=channel_state2_1.identifier, token_address=channel_state2_1.token_address, token_network_identifier=token_network_identifier, balance_proof=channel_state2_1.partner_state.balance_proof, triggered_by_block_hash=app0.raiden.chain.block_hash(), ) app2.raiden.raiden_event_handler.on_raiden_event(app2.raiden, channel_close_event) settle_expiration = (app0.raiden.chain.block_number() + settle_timeout + DEFAULT_NUMBER_OF_BLOCK_CONFIRMATIONS) app0.raiden.chain.wait_until_block(target_block_number=settle_expiration) # TODO: # - assert on the transferred amounts on-chain (for settle and unlock) # The channel app0-app1 should continue with the protocol off-chain, once # the secret is released on-chain by app2 assert_synced_channel_state( token_network_identifier, app0, deposit - amount, [], app1, deposit + amount, [], ) with gevent.Timeout(10): wait_for_state_change( app2.raiden, ContractReceiveSecretReveal, {'secrethash': secrethash}, retry_interval, )