def handle_channel_batch_unlock(raiden: 'RaidenService', event: Event): token_network_identifier = event.originating_contract data = event.event_data args = data['args'] block_number = data['block_number'] block_hash = data['block_hash'] transaction_hash = data['transaction_hash'] chain_state = views.state_from_raiden(raiden) unlock_state_change = ContractReceiveChannelBatchUnlock( transaction_hash=transaction_hash, canonical_identifier=CanonicalIdentifier( chain_identifier=chain_state.chain_id, token_network_address=token_network_identifier, # FIXME: we will resolve the channel identifier only further down in # raiden.transfer.token_network::handle_batch_unlock # can/should we do it here already? channel_identifier=CHANNEL_ID_UNSPECIFIED, ), participant=args['participant'], partner=args['partner'], locksroot=args['locksroot'], unlocked_amount=args['unlocked_amount'], returned_tokens=args['returned_tokens'], block_number=block_number, block_hash=block_hash, ) raiden.handle_and_track_state_change(unlock_state_change)
def test_write_read_log() -> None: wal = new_wal(state_transition_noop) block_number = BlockNumber(1337) block_hash = make_block_hash() block = Block(block_number=block_number, gas_limit=BlockGasLimit(1), block_hash=block_hash) unlocked_amount = TokenAmount(10) returned_amount = TokenAmount(5) participant = make_address() partner = make_address() locksroot = make_locksroot() contract_receive_unlock = ContractReceiveChannelBatchUnlock( transaction_hash=make_transaction_hash(), canonical_identifier=make_canonical_identifier( token_network_address=make_address()), receiver=participant, sender=partner, locksroot=locksroot, unlocked_amount=unlocked_amount, returned_tokens=returned_amount, block_number=block_number, block_hash=block_hash, ) state_changes1 = wal.storage.get_statechanges_by_range( RANGE_ALL_STATE_CHANGES) count1 = len(state_changes1) dispatch(wal, [block]) state_changes2 = wal.storage.get_statechanges_by_range( RANGE_ALL_STATE_CHANGES) count2 = len(state_changes2) assert count1 + 1 == count2 dispatch(wal, [contract_receive_unlock]) state_changes3 = wal.storage.get_statechanges_by_range( RANGE_ALL_STATE_CHANGES) count3 = len(state_changes3) assert count2 + 1 == count3 result1, result2 = state_changes3[-2:] assert isinstance(result1, Block) assert result1.block_number == block_number assert isinstance(result2, ContractReceiveChannelBatchUnlock) assert result2.receiver == participant assert result2.sender == partner assert result2.locksroot == locksroot assert result2.unlocked_amount == unlocked_amount assert result2.returned_tokens == returned_amount # Make sure state snapshot can only go for corresponding state change ids with pytest.raises(sqlite3.IntegrityError): wal.storage.write_state_snapshot(State(), StateChangeID(make_ulid()), 1)
def test_write_read_log(): wal = new_wal() block_number = 1337 block = Block(block_number) unlocked_amount = 10 returned_amount = 5 channel_identifier = factories.make_address() contract_receive_unlock = ContractReceiveChannelBatchUnlock( factories.make_address(), channel_identifier, factories.ADDR, unlocked_amount, returned_amount, ) state_changes1 = wal.storage.get_statechanges_by_identifier( from_identifier=0, to_identifier='latest', ) count1 = len(state_changes1) wal.log_and_dispatch(block, block_number) state_changes2 = wal.storage.get_statechanges_by_identifier( from_identifier=0, to_identifier='latest', ) count2 = len(state_changes2) assert count1 + 1 == count2 wal.log_and_dispatch(contract_receive_unlock, block_number) state_changes3 = wal.storage.get_statechanges_by_identifier( from_identifier=0, to_identifier='latest', ) count3 = len(state_changes3) assert count2 + 1 == count3 result1, result2 = state_changes3[-2:] assert isinstance(result1, Block) assert result1.block_number == block_number assert isinstance(result2, ContractReceiveChannelBatchUnlock) assert result2.channel_identifier == channel_identifier # Make sure state snapshot can only go for corresponding state change ids with pytest.raises(sqlite3.IntegrityError): wal.storage.write_state_snapshot(34, 'AAAA') # Make sure we can only have a single state snapshot assert wal.storage.get_state_snapshot() is None wal.storage.write_state_snapshot(1, 'AAAA') assert wal.storage.get_state_snapshot() == (1, 'AAAA') wal.storage.write_state_snapshot(2, 'BBBB') assert wal.storage.get_state_snapshot() == (2, 'BBBB')
def test_is_transaction_effect_satisfied( chain_state, token_network_state, token_network_id, netting_channel_state, ): transaction = ContractSendChannelBatchUnlock( token_address=token_network_state.token_address, token_network_identifier=token_network_id, channel_identifier=netting_channel_state.identifier, participant=HOP2, ) state_change = ContractReceiveChannelBatchUnlock( transaction_hash=UNIT_SECRETHASH, token_network_identifier=token_network_id, participant=HOP1, partner=HOP2, locksroot=EMPTY_MERKLE_ROOT, unlocked_amount=0, returned_tokens=0, block_number=1, ) # unlock for a channel in which this node is not a participant must return False assert not is_transaction_effect_satisfied(chain_state, transaction, state_change) # now call normally with us being the partner and not the participant state_change.partner = netting_channel_state.our_state.address state_change.participant = netting_channel_state.partner_state.address assert not is_transaction_effect_satisfied(chain_state, transaction, state_change) # finally call with us being the participant and not the partner which should check out state_change.participant = netting_channel_state.our_state.address state_change.partner = netting_channel_state.partner_state.address assert is_transaction_effect_satisfied(chain_state, transaction, state_change)
def make_unlock(unlock_end, partner_end): batch_unlock = ContractReceiveChannelBatchUnlock( transaction_hash=make_transaction_hash(), canonical_identifier=channel_state.canonical_identifier, receiver=partner_end.address, sender=unlock_end.address, locksroot=unlock_end.balance_proof.locksroot, unlocked_amount=10, returned_tokens=0, block_number=block_number, block_hash=block_hash, ) return batch_unlock
def handle_channel_batch_unlock(raiden, event, current_block_number): token_network_identifier = event.originating_contract data = event.event_data unlock_state_change = ContractReceiveChannelBatchUnlock( token_network_identifier, data['participant'], data['partner'], data['locksroot'], data['unlocked_amount'], data['returned_tokens'], ) raiden.handle_state_change(unlock_state_change, current_block_number)
def contractreceivechannelbatchunlock_from_event( canonical_identifier: CanonicalIdentifier, event: DecodedEvent) -> ContractReceiveChannelBatchUnlock: data = event.event_data args = data["args"] return ContractReceiveChannelBatchUnlock( canonical_identifier=canonical_identifier, receiver=args["receiver"], sender=args["sender"], locksroot=args["locksroot"], unlocked_amount=args["unlocked_amount"], returned_tokens=args["returned_tokens"], transaction_hash=event.transaction_hash, block_number=event.block_number, block_hash=event.block_hash, )
def handle_channel_batch_unlock(raiden, event, current_block_number): token_network_identifier = event.originating_contract data = event.event_data transaction_hash = data['transactionHash'] assert transaction_hash, 'A mined transaction must have the hash field' unlock_state_change = ContractReceiveChannelBatchUnlock( transaction_hash, token_network_identifier, data['participant'], data['partner'], data['locksroot'], data['unlocked_amount'], data['returned_tokens'], ) raiden.handle_state_change(unlock_state_change, current_block_number)
def handle_channel_batch_unlock(raiden: RaidenService, event: Event): token_network_identifier = event.originating_contract data = event.event_data args = data['args'] transaction_hash = data['transaction_hash'] unlock_state_change = ContractReceiveChannelBatchUnlock( transaction_hash=transaction_hash, token_network_identifier=token_network_identifier, participant=args['participant'], partner=args['partner'], locksroot=args['locksroot'], unlocked_amount=args['unlocked_amount'], returned_tokens=args['returned_tokens'], block_number=data['block_number'], ) raiden.handle_state_change(unlock_state_change)
def handle_channel_batch_unlock(raiden, event, current_block_number): token_network_identifier = event.originating_contract data = event.event_data from_address = raiden.chain.client.get_transaction_from( event.event_data['transactionHash']) assert from_address, 'A mined transaction must have the from field' unlock_state_change = ContractReceiveChannelBatchUnlock( from_address, token_network_identifier, data['participant'], data['partner'], data['locksroot'], data['unlocked_amount'], data['returned_tokens'], ) raiden.handle_state_change(unlock_state_change, current_block_number)
def test_is_transaction_effect_satisfied(chain_state, token_network_id, netting_channel_state): canonical_identifier = netting_channel_state.canonical_identifier assert token_network_id == canonical_identifier.token_network_address transaction = ContractSendChannelBatchUnlock( canonical_identifier=canonical_identifier, participant=netting_channel_state.partner_state.address, triggered_by_block_hash=make_block_hash(), ) state_change = ContractReceiveChannelBatchUnlock( transaction_hash=UNIT_SECRETHASH, canonical_identifier=canonical_identifier, participant=HOP1, partner=HOP2, locksroot=EMPTY_MERKLE_ROOT, unlocked_amount=0, returned_tokens=0, block_number=1, block_hash=make_block_hash(), ) # unlock for a channel in which this node is not a participant must return False assert not is_transaction_effect_satisfied(chain_state, transaction, state_change) # now call normally with us being the partner and not the participant state_change.partner = netting_channel_state.partner_state.address state_change.participant = netting_channel_state.our_state.address assert not is_transaction_effect_satisfied(chain_state, transaction, state_change) # finally call with us being the participant and not the partner which should check out state_change.participant = netting_channel_state.partner_state.address state_change.partner = netting_channel_state.our_state.address # ContractSendChannelBatchUnlock would only be satisfied if both sides are unlocked # and if the channel was cleared assert not is_transaction_effect_satisfied(chain_state, transaction, state_change) channel_settled = ContractReceiveChannelSettled( transaction_hash=bytes(32), canonical_identifier=canonical_identifier, our_onchain_locksroot=EMPTY_MERKLE_ROOT, partner_onchain_locksroot=EMPTY_MERKLE_ROOT, block_number=1, block_hash=make_block_hash(), ) iteration = state_transition(chain_state=chain_state, state_change=channel_settled) assert is_transaction_effect_satisfied(iteration.new_state, transaction, state_change)
def test_mediator_clear_pairs_after_batch_unlock( chain_state, token_network_state, our_address, ): """ Regression test for https://github.com/raiden-network/raiden/issues/2932 The mediator must also clear the transfer pairs once a ReceiveBatchUnlock where he is a participant is received. """ open_block_number = 10 pseudo_random_generator = random.Random() pkey, address = factories.make_privkey_address() amount = 30 our_balance = amount + 50 channel_state = factories.make_channel( our_balance=our_balance, our_address=our_address, partner_balance=our_balance, partner_address=address, token_network_identifier=token_network_state.address, ) payment_network_identifier = factories.make_payment_network_identifier() channel_new_state_change = ContractReceiveChannelNew( factories.make_transaction_hash(), token_network_state.address, channel_state, open_block_number, ) channel_new_iteration = token_network.state_transition( payment_network_identifier, token_network_state, channel_new_state_change, pseudo_random_generator, open_block_number, ) lock_amount = 30 lock_expiration = 20 lock_secret = sha3(b'test_end_state') lock_secrethash = sha3(lock_secret) lock = HashTimeLockState( lock_amount, lock_expiration, lock_secrethash, ) mediated_transfer = make_receive_transfer_mediated( channel_state=channel_state, privkey=pkey, nonce=1, transferred_amount=0, lock=lock, ) from_route = factories.route_from_channel(channel_state) init_mediator = ActionInitMediator( routes=[from_route], from_route=from_route, from_transfer=mediated_transfer, ) node.state_transition(chain_state, init_mediator) closed_block_number = open_block_number + 10 channel_close_state_change = ContractReceiveChannelClosed( factories.make_transaction_hash(), channel_state.partner_state.address, token_network_state.address, channel_state.identifier, closed_block_number, ) channel_closed_iteration = token_network.state_transition( payment_network_identifier, channel_new_iteration.new_state, channel_close_state_change, pseudo_random_generator, closed_block_number, ) settle_block_number = closed_block_number + channel_state.settle_timeout + 1 channel_settled_state_change = ContractReceiveChannelSettled( factories.make_transaction_hash(), token_network_state.address, channel_state.identifier, settle_block_number, ) channel_settled_iteration = token_network.state_transition( payment_network_identifier, channel_closed_iteration.new_state, channel_settled_state_change, pseudo_random_generator, closed_block_number, ) token_network_state_after_settle = channel_settled_iteration.new_state ids_to_channels = token_network_state_after_settle.channelidentifiers_to_channels assert len(ids_to_channels) == 1 assert channel_state.identifier in ids_to_channels block_number = closed_block_number + 1 channel_batch_unlock_state_change = ContractReceiveChannelBatchUnlock( transaction_hash=factories.make_transaction_hash(), token_network_identifier=token_network_state.address, participant=our_address, partner=address, locksroot=lock_secrethash, unlocked_amount=lock_amount, returned_tokens=0, block_number=block_number, ) channel_unlock_iteration = node.state_transition( chain_state=chain_state, state_change=channel_batch_unlock_state_change, ) chain_state = channel_unlock_iteration.new_state token_network_state = views.get_token_network_by_identifier( chain_state=chain_state, token_network_id=token_network_state.address, ) ids_to_channels = token_network_state.channelidentifiers_to_channels assert len(ids_to_channels) == 0 # Make sure that all is fine in the next block block = Block( block_number=block_number + 1, gas_limit=1, block_hash=factories.make_transaction_hash(), ) iteration = node.state_transition( chain_state=chain_state, state_change=block, ) assert iteration.new_state # Make sure that mediator task was cleared during the next block processing # since the channel was removed mediator_task = chain_state.payment_mapping.secrethashes_to_task.get( lock_secrethash) assert not mediator_task
def test_channel_data_removed_after_unlock( chain_state, token_network_state, our_address, ): open_block_number = 10 pseudo_random_generator = random.Random() pkey, address = factories.make_privkey_address() amount = 30 our_balance = amount + 50 channel_state = factories.make_channel( our_balance=our_balance, our_address=our_address, partner_balance=our_balance, partner_address=address, ) payment_network_identifier = factories.make_payment_network_identifier() channel_new_state_change = ContractReceiveChannelNew( factories.make_transaction_hash(), token_network_state.address, channel_state, ) channel_new_iteration = token_network.state_transition( payment_network_identifier, token_network_state, channel_new_state_change, pseudo_random_generator, open_block_number, ) lock_amount = 30 lock_expiration = 20 lock_secret = sha3(b'test_end_state') lock_secrethash = sha3(lock_secret) lock = HashTimeLockState( lock_amount, lock_expiration, lock_secrethash, ) mediated_transfer = make_receive_transfer_mediated( channel_state=channel_state, privkey=pkey, nonce=1, transferred_amount=0, lock=lock, token_network_address=token_network_state.address, ) from_route = factories.route_from_channel(channel_state) init_target = ActionInitTarget( from_route, mediated_transfer, ) node.state_transition(chain_state, init_target) closed_block_number = open_block_number + 10 channel_close_state_change = ContractReceiveChannelClosed( factories.make_transaction_hash(), channel_state.partner_state.address, token_network_state.address, channel_state.identifier, closed_block_number, ) channel_closed_iteration = token_network.state_transition( payment_network_identifier, channel_new_iteration.new_state, channel_close_state_change, pseudo_random_generator, closed_block_number, ) settle_block_number = closed_block_number + channel_state.settle_timeout + 1 channel_settled_state_change = ContractReceiveChannelSettled( factories.make_transaction_hash(), token_network_state.address, channel_state.identifier, settle_block_number, ) channel_settled_iteration = token_network.state_transition( payment_network_identifier, channel_closed_iteration.new_state, channel_settled_state_change, pseudo_random_generator, closed_block_number, ) token_network_state_after_settle = channel_settled_iteration.new_state ids_to_channels = token_network_state_after_settle.channelidentifiers_to_channels assert len(ids_to_channels) == 1 assert channel_state.identifier in ids_to_channels unlock_blocknumber = settle_block_number + 5 channel_batch_unlock_state_change = ContractReceiveChannelBatchUnlock( transaction_hash=factories.make_transaction_hash(), token_network_identifier=token_network_state.address, participant=our_address, partner=address, locksroot=lock_secrethash, unlocked_amount=lock_amount, returned_tokens=0, ) channel_unlock_iteration = token_network.state_transition( payment_network_identifier, channel_settled_iteration.new_state, channel_batch_unlock_state_change, pseudo_random_generator, unlock_blocknumber, ) token_network_state_after_unlock = channel_unlock_iteration.new_state ids_to_channels = token_network_state_after_unlock.channelidentifiers_to_channels assert len(ids_to_channels) == 0
def test_write_read_log(): wal = new_wal(state_transition_noop) block_number = 1337 block_hash = factories.make_transaction_hash() block = Block(block_number=block_number, gas_limit=1, block_hash=block_hash) unlocked_amount = 10 returned_amount = 5 participant = factories.make_address() partner = factories.make_address() locksroot = sha3(b"test_write_read_log") contract_receive_unlock = ContractReceiveChannelBatchUnlock( transaction_hash=factories.make_transaction_hash(), canonical_identifier=factories.make_canonical_identifier( token_network_address=factories.make_address()), participant=participant, partner=partner, locksroot=locksroot, unlocked_amount=unlocked_amount, returned_tokens=returned_amount, block_number=block_number, block_hash=block_hash, ) state_changes1 = wal.storage.get_statechanges_by_identifier( from_identifier=0, to_identifier="latest") count1 = len(state_changes1) wal.log_and_dispatch(block) state_changes2 = wal.storage.get_statechanges_by_identifier( from_identifier=0, to_identifier="latest") count2 = len(state_changes2) assert count1 + 1 == count2 wal.log_and_dispatch(contract_receive_unlock) state_changes3 = wal.storage.get_statechanges_by_identifier( from_identifier=0, to_identifier="latest") count3 = len(state_changes3) assert count2 + 1 == count3 result1, result2 = state_changes3[-2:] assert isinstance(result1, Block) assert result1.block_number == block_number assert isinstance(result2, ContractReceiveChannelBatchUnlock) assert result2.participant == participant assert result2.partner == partner assert result2.locksroot == locksroot assert result2.unlocked_amount == unlocked_amount assert result2.returned_tokens == returned_amount # Make sure state snapshot can only go for corresponding state change ids with pytest.raises(sqlite3.IntegrityError): wal.storage.write_state_snapshot(34, "AAAA") # Make sure we can only have a single state snapshot assert wal.storage.get_latest_state_snapshot() is None wal.storage.write_state_snapshot(1, "AAAA") assert wal.storage.get_latest_state_snapshot() == (1, "AAAA") wal.storage.write_state_snapshot(2, "BBBB") assert wal.storage.get_latest_state_snapshot() == (2, "BBBB")
def test_mediator_clear_pairs_after_batch_unlock(chain_state, token_network_state, our_address, channel_properties): """ Regression test for https://github.com/raiden-network/raiden/issues/2932 The mediator must also clear the transfer pairs once a ReceiveBatchUnlock where he is a participant is received. """ open_block_number = 10 open_block_hash = factories.make_block_hash() pseudo_random_generator = random.Random() properties, pkey = channel_properties address = properties.partner_state.address channel_state = factories.create(properties) channel_new_state_change = ContractReceiveChannelNew( transaction_hash=factories.make_transaction_hash(), channel_state=channel_state, block_number=open_block_number, block_hash=open_block_hash, ) channel_new_iteration = token_network.state_transition( token_network_state=token_network_state, state_change=channel_new_state_change, block_number=open_block_number, block_hash=open_block_hash, pseudo_random_generator=pseudo_random_generator, ) lock_amount = 30 lock_expiration = 20 lock_secret = keccak(b"test_end_state") lock_secrethash = sha256(lock_secret).digest() lock = HashTimeLockState(lock_amount, lock_expiration, lock_secrethash) mediated_transfer = make_receive_transfer_mediated( channel_state=channel_state, privkey=pkey, nonce=1, transferred_amount=0, lock=lock) route_state = RouteState( route=[ channel_state.our_state.address, channel_state.partner_state.address ], forward_channel_id=channel_state.canonical_identifier. channel_identifier, ) from_hop = factories.make_hop_from_channel(channel_state) init_mediator = ActionInitMediator( route_states=[route_state], from_hop=from_hop, from_transfer=mediated_transfer, balance_proof=mediated_transfer.balance_proof, sender=mediated_transfer.balance_proof.sender, # pylint: disable=no-member ) node.state_transition(chain_state, init_mediator) closed_block_number = open_block_number + 10 closed_block_hash = factories.make_block_hash() channel_close_state_change = ContractReceiveChannelClosed( transaction_hash=factories.make_transaction_hash(), transaction_from=channel_state.partner_state.address, canonical_identifier=channel_state.canonical_identifier, block_number=closed_block_number, block_hash=closed_block_hash, ) channel_closed_iteration = token_network.state_transition( token_network_state=channel_new_iteration.new_state, state_change=channel_close_state_change, block_number=closed_block_number, block_hash=closed_block_hash, pseudo_random_generator=pseudo_random_generator, ) settle_block_number = closed_block_number + channel_state.settle_timeout + 1 channel_settled_state_change = ContractReceiveChannelSettled( transaction_hash=factories.make_transaction_hash(), canonical_identifier=channel_state.canonical_identifier, block_number=settle_block_number, block_hash=factories.make_block_hash(), our_onchain_locksroot=factories.make_32bytes(), partner_onchain_locksroot=LOCKSROOT_OF_NO_LOCKS, ) channel_settled_iteration = token_network.state_transition( token_network_state=channel_closed_iteration.new_state, state_change=channel_settled_state_change, block_number=closed_block_number, block_hash=closed_block_hash, pseudo_random_generator=pseudo_random_generator, ) token_network_state_after_settle = channel_settled_iteration.new_state ids_to_channels = token_network_state_after_settle.channelidentifiers_to_channels assert len(ids_to_channels) == 1 assert channel_state.identifier in ids_to_channels block_number = closed_block_number + 1 channel_batch_unlock_state_change = ContractReceiveChannelBatchUnlock( transaction_hash=factories.make_transaction_hash(), canonical_identifier=channel_state.canonical_identifier, receiver=address, sender=our_address, locksroot=compute_locksroot(PendingLocksState([bytes(lock.encoded)])), unlocked_amount=lock_amount, returned_tokens=0, block_number=block_number, block_hash=factories.make_block_hash(), ) channel_unlock_iteration = node.state_transition( chain_state=chain_state, state_change=channel_batch_unlock_state_change) chain_state = channel_unlock_iteration.new_state token_network_state = views.get_token_network_by_address( chain_state=chain_state, token_network_address=token_network_state.address) ids_to_channels = token_network_state.channelidentifiers_to_channels assert len(ids_to_channels) == 0 # Make sure that all is fine in the next block block = Block(block_number=block_number + 1, gas_limit=1, block_hash=factories.make_transaction_hash()) iteration = node.state_transition(chain_state=chain_state, state_change=block) assert iteration.new_state # Make sure that mediator task was cleared during the next block processing # since the channel was removed mediator_task = chain_state.payment_mapping.secrethashes_to_task.get( lock_secrethash) assert not mediator_task
def test_channel_data_removed_after_unlock(chain_state, token_network_state, our_address, channel_properties): open_block_number = 10 open_block_hash = factories.make_block_hash() pseudo_random_generator = random.Random() properties, pkey = channel_properties address = properties.partner_state.address channel_state = factories.create(properties) channel_new_state_change = ContractReceiveChannelNew( transaction_hash=factories.make_transaction_hash(), channel_state=channel_state, block_number=open_block_number, block_hash=open_block_hash, ) channel_new_iteration = token_network.state_transition( token_network_state=token_network_state, state_change=channel_new_state_change, block_number=open_block_number, block_hash=open_block_hash, pseudo_random_generator=pseudo_random_generator, ) lock_amount = 30 lock_expiration = 20 lock_secret = keccak(b"test_end_state") lock_secrethash = sha256(lock_secret).digest() lock = HashTimeLockState(lock_amount, lock_expiration, lock_secrethash) mediated_transfer = make_receive_transfer_mediated( channel_state=channel_state, privkey=pkey, nonce=1, transferred_amount=0, lock=lock) from_hop = factories.make_hop_from_channel(channel_state) init_target = ActionInitTarget( sender=mediated_transfer.balance_proof.sender, # pylint: disable=no-member balance_proof=mediated_transfer.balance_proof, from_hop=from_hop, transfer=mediated_transfer, ) node.state_transition(chain_state, init_target) closed_block_number = open_block_number + 10 closed_block_hash = factories.make_block_hash() channel_close_state_change = ContractReceiveChannelClosed( transaction_hash=factories.make_transaction_hash(), transaction_from=channel_state.partner_state.address, canonical_identifier=channel_state.canonical_identifier, block_number=closed_block_number, block_hash=closed_block_hash, ) channel_closed_iteration = token_network.state_transition( token_network_state=channel_new_iteration.new_state, state_change=channel_close_state_change, block_number=closed_block_number, block_hash=closed_block_hash, pseudo_random_generator=pseudo_random_generator, ) channel_state_after_closed = channel_closed_iteration.new_state.channelidentifiers_to_channels[ channel_state.identifier] settle_block_number = closed_block_number + channel_state.settle_timeout + 1 channel_settled_state_change = ContractReceiveChannelSettled( transaction_hash=factories.make_transaction_hash(), canonical_identifier=channel_state.canonical_identifier, block_number=settle_block_number, block_hash=factories.make_block_hash(), our_onchain_locksroot=compute_locksroot( channel_state_after_closed.our_state.pending_locks), partner_onchain_locksroot=compute_locksroot( channel_state_after_closed.partner_state.pending_locks), ) channel_settled_iteration = token_network.state_transition( token_network_state=channel_closed_iteration.new_state, state_change=channel_settled_state_change, block_number=closed_block_number, block_hash=closed_block_hash, pseudo_random_generator=pseudo_random_generator, ) token_network_state_after_settle = channel_settled_iteration.new_state ids_to_channels = token_network_state_after_settle.channelidentifiers_to_channels assert len(ids_to_channels) == 1 assert channel_state.identifier in ids_to_channels unlock_blocknumber = settle_block_number + 5 channel_batch_unlock_state_change = ContractReceiveChannelBatchUnlock( transaction_hash=factories.make_transaction_hash(), canonical_identifier=channel_state.canonical_identifier, receiver=our_address, sender=address, locksroot=compute_locksroot(PendingLocksState([bytes(lock.encoded)])), unlocked_amount=lock_amount, returned_tokens=0, block_number=closed_block_number + 1, block_hash=factories.make_block_hash(), ) channel_unlock_iteration = token_network.state_transition( token_network_state=channel_settled_iteration.new_state, state_change=channel_batch_unlock_state_change, block_number=unlock_blocknumber, block_hash=factories.make_block_hash(), pseudo_random_generator=pseudo_random_generator, ) token_network_state_after_unlock = channel_unlock_iteration.new_state ids_to_channels = token_network_state_after_unlock.channelidentifiers_to_channels assert len(ids_to_channels) == 0
def handle_channel_batch_unlock(raiden: "RaidenService", event: Event): assert raiden.wal, "The Raiden Service must be initialize to handle events" token_network_identifier = event.originating_contract data = event.event_data args = data["args"] block_number = data["block_number"] block_hash = data["block_hash"] transaction_hash = data["transaction_hash"] participant1 = args["participant"] participant2 = args["partner"] locksroot = args["locksroot"] chain_state = views.state_from_raiden(raiden) token_network_state = views.get_token_network_by_identifier( chain_state, token_network_identifier) assert token_network_state is not None if participant1 == raiden.address: partner = participant2 elif participant2 == raiden.address: partner = participant1 else: log.debug( "Discarding unlock event, we're not part of it", participant1=pex(participant1), participant2=pex(participant2), ) return channel_identifiers = token_network_state.partneraddresses_to_channelidentifiers[ partner] canonical_identifier = None for channel_identifier in channel_identifiers: if partner == args["partner"]: state_change_record = get_state_change_with_balance_proof_by_locksroot( storage=raiden.wal.storage, canonical_identifier=CanonicalIdentifier( chain_identifier=raiden.chain.network_id, token_network_address=token_network_identifier, channel_identifier=channel_identifier, ), locksroot=locksroot, sender=partner, ) if state_change_record.state_change_identifier: canonical_identifier = state_change_record.data.balance_proof.canonical_identifier break elif partner == args["participant"]: event_record = get_event_with_balance_proof_by_locksroot( storage=raiden.wal.storage, canonical_identifier=CanonicalIdentifier( chain_identifier=raiden.chain.network_id, token_network_address=token_network_identifier, channel_identifier=channel_identifier, ), locksroot=locksroot, recipient=partner, ) if event_record.event_identifier: canonical_identifier = event_record.data.balance_proof.canonical_identifier break msg = ( f"Can not resolve channel_id for unlock with locksroot {pex(locksroot)} and " f"partner {pex(partner)}.") assert canonical_identifier is not None, msg unlock_state_change = ContractReceiveChannelBatchUnlock( transaction_hash=transaction_hash, canonical_identifier=canonical_identifier, participant=args["participant"], partner=args["partner"], locksroot=args["locksroot"], unlocked_amount=args["unlocked_amount"], returned_tokens=args["returned_tokens"], block_number=block_number, block_hash=block_hash, ) raiden.handle_and_track_state_change(unlock_state_change)
def test_channel_data_removed_after_unlock(chain_state, token_network_state, our_address, channel_properties): open_block_number = 10 open_block_hash = factories.make_block_hash() properties, pkey = channel_properties address = properties.partner_state.address channel_state = factories.create(properties) channel_new_state_change = ContractReceiveChannelNew( transaction_hash=factories.make_transaction_hash(), channel_state=channel_state, block_number=open_block_number, block_hash=open_block_hash, ) channel_new_iteration = token_network.state_transition( token_network_state=token_network_state, state_change=channel_new_state_change, block_number=open_block_number, block_hash=open_block_hash, ) lock_amount = 30 lock_expiration = 20 lock_secret = sha3(b"test_end_state") lock_secrethash = sha3(lock_secret) lock = HashTimeLockState(lock_amount, lock_expiration, lock_secrethash) mediated_transfer = make_receive_transfer_mediated( channel_state=channel_state, privkey=pkey, nonce=1, transferred_amount=0, lock=lock) from_route = factories.make_route_from_channel(channel_state) init_target = ActionInitTarget(from_route, mediated_transfer) node.state_transition(chain_state, init_target) closed_block_number = open_block_number + 10 closed_block_hash = factories.make_block_hash() channel_close_state_change = ContractReceiveChannelClosed( transaction_hash=factories.make_transaction_hash(), transaction_from=channel_state.partner_state.address, canonical_identifier=channel_state.canonical_identifier, block_number=closed_block_number, block_hash=closed_block_hash, ) channel_closed_iteration = token_network.state_transition( token_network_state=channel_new_iteration.new_state, state_change=channel_close_state_change, block_number=closed_block_number, block_hash=closed_block_hash, ) settle_block_number = closed_block_number + channel_state.settle_timeout + 1 channel_settled_state_change = ContractReceiveChannelSettled( transaction_hash=factories.make_transaction_hash(), canonical_identifier=channel_state.canonical_identifier, block_number=settle_block_number, block_hash=factories.make_block_hash(), our_onchain_locksroot=factories.make_32bytes(), partner_onchain_locksroot=EMPTY_MERKLE_ROOT, ) channel_settled_iteration = token_network.state_transition( token_network_state=channel_closed_iteration.new_state, state_change=channel_settled_state_change, block_number=closed_block_number, block_hash=closed_block_hash, ) token_network_state_after_settle = channel_settled_iteration.new_state ids_to_channels = token_network_state_after_settle.channelidentifiers_to_channels assert len(ids_to_channels) == 1 assert channel_state.identifier in ids_to_channels unlock_blocknumber = settle_block_number + 5 channel_batch_unlock_state_change = ContractReceiveChannelBatchUnlock( transaction_hash=factories.make_transaction_hash(), canonical_identifier=channel_state.canonical_identifier, participant=our_address, partner=address, locksroot=lock_secrethash, unlocked_amount=lock_amount, returned_tokens=0, block_number=closed_block_number + 1, block_hash=factories.make_block_hash(), ) channel_unlock_iteration = token_network.state_transition( token_network_state=channel_settled_iteration.new_state, state_change=channel_batch_unlock_state_change, block_number=unlock_blocknumber, block_hash=factories.make_block_hash(), ) token_network_state_after_unlock = channel_unlock_iteration.new_state ids_to_channels = token_network_state_after_unlock.channelidentifiers_to_channels assert len(ids_to_channels) == 0
def test_mediator_clear_pairs_after_batch_unlock(chain_state, token_network_state, our_address, channel_properties): """ Regression test for https://github.com/raiden-network/raiden/issues/2932 The mediator must also clear the transfer pairs once a ReceiveBatchUnlock where he is a participant is received. """ open_block_number = 10 open_block_hash = factories.make_block_hash() properties, pkey = channel_properties address = properties.partner_state.address channel_state = factories.create(properties) channel_new_state_change = ContractReceiveChannelNew( transaction_hash=factories.make_transaction_hash(), channel_state=channel_state, block_number=open_block_number, block_hash=open_block_hash, ) channel_new_iteration = token_network.state_transition( token_network_state=token_network_state, state_change=channel_new_state_change, block_number=open_block_number, block_hash=open_block_hash, ) lock_amount = 30 lock_expiration = 20 lock_secret = sha3(b"test_end_state") lock_secrethash = sha3(lock_secret) lock = HashTimeLockState(lock_amount, lock_expiration, lock_secrethash) mediated_transfer = make_receive_transfer_mediated( channel_state=channel_state, privkey=pkey, nonce=1, transferred_amount=0, lock=lock) from_route = factories.make_route_from_channel(channel_state) init_mediator = ActionInitMediator(routes=[from_route], from_route=from_route, from_transfer=mediated_transfer) node.state_transition(chain_state, init_mediator, None) closed_block_number = open_block_number + 10 closed_block_hash = factories.make_block_hash() channel_close_state_change = ContractReceiveChannelClosed( transaction_hash=factories.make_transaction_hash(), transaction_from=channel_state.partner_state.address, canonical_identifier=channel_state.canonical_identifier, block_number=closed_block_number, block_hash=closed_block_hash, ) channel_closed_iteration = token_network.state_transition( token_network_state=channel_new_iteration.new_state, state_change=channel_close_state_change, block_number=closed_block_number, block_hash=closed_block_hash, ) settle_block_number = closed_block_number + channel_state.settle_timeout + 1 channel_settled_state_change = ContractReceiveChannelSettled( transaction_hash=factories.make_transaction_hash(), canonical_identifier=channel_state.canonical_identifier, block_number=settle_block_number, block_hash=factories.make_block_hash(), our_onchain_locksroot=factories.make_32bytes(), partner_onchain_locksroot=EMPTY_MERKLE_ROOT, ) channel_settled_iteration = token_network.state_transition( token_network_state=channel_closed_iteration.new_state, state_change=channel_settled_state_change, block_number=closed_block_number, block_hash=closed_block_hash, ) token_network_state_after_settle = channel_settled_iteration.new_state ids_to_channels = token_network_state_after_settle.channelidentifiers_to_channels assert len(ids_to_channels) == 1 assert channel_state.identifier in ids_to_channels block_number = closed_block_number + 1 channel_batch_unlock_state_change = ContractReceiveChannelBatchUnlock( transaction_hash=factories.make_transaction_hash(), canonical_identifier=channel_state.canonical_identifier, participant=address, partner=our_address, locksroot=lock_secrethash, unlocked_amount=lock_amount, returned_tokens=0, block_number=block_number, block_hash=factories.make_block_hash(), ) channel_unlock_iteration = node.state_transition( chain_state=chain_state, state_change=channel_batch_unlock_state_change, storage=None) chain_state = channel_unlock_iteration.new_state token_network_state = views.get_token_network_by_identifier( chain_state=chain_state, token_network_id=token_network_state.address) ids_to_channels = token_network_state.channelidentifiers_to_channels assert len(ids_to_channels) == 0 # Make sure that all is fine in the next block block = Block(block_number=block_number + 1, gas_limit=1, block_hash=factories.make_transaction_hash()) iteration = node.state_transition(chain_state=chain_state, state_change=block, storage=None) assert iteration.new_state # Make sure that mediator task was cleared during the next block processing # since the channel was removed mediator_task = chain_state.payment_mapping.secrethashes_to_task.get( lock_secrethash) assert not mediator_task