def _channel_and_transfer(num_pending_locks): our_model, _ = create_model(700) partner_model, privkey = create_model(700, num_pending_locks) reverse_channel_state = create_channel_from_models(partner_model, our_model, privkey) lock_secret = sha3(b"some secret seed") lock = HashTimeLockState(30, 10, sha256(lock_secret).digest()) mediated_transfer = make_receive_transfer_mediated( reverse_channel_state, privkey, nonce=partner_model.next_nonce, transferred_amount=0, lock=lock, pending_locks=PendingLocksState(partner_model.pending_locks + [bytes(lock.encoded)]), locked_amount=lock.amount, ) channel_state = deepcopy(reverse_channel_state) channel_state.our_state = reverse_channel_state.partner_state channel_state.partner_state = reverse_channel_state.our_state return channel_state, mediated_transfer
def _channel_and_transfer(merkletree_width): our_model, _ = create_model(700) partner_model, privkey = create_model(700, merkletree_width) reverse_channel_state = create_channel_from_models(partner_model, our_model) lock_secret = sha3(b"some secret") lock = HashTimeLockState(30, 10, sha3(lock_secret)) mediated_transfer = make_receive_transfer_mediated( reverse_channel_state, privkey, nonce=1, transferred_amount=0, lock=lock, merkletree_leaves=partner_model.merkletree_leaves + [lock.lockhash], locked_amount=lock.amount, ) channel_state = deepcopy(reverse_channel_state) channel_state.our_state = reverse_channel_state.partner_state channel_state.partner_state = reverse_channel_state.our_state return channel_state, mediated_transfer
def test_channel_cleared_after_our_unlock(): pseudo_random_generator = random.Random() our_model, _ = create_model(balance=700, num_pending_locks=1) partner_model, partner_key1 = create_model(balance=700, num_pending_locks=0) channel_state = create_channel_from_models(our_model, partner_model, partner_key1) block_number = 1 block_hash = make_block_hash() 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 settle_channel = ContractReceiveChannelSettled( transaction_hash=make_transaction_hash(), canonical_identifier=channel_state.canonical_identifier, our_onchain_locksroot=compute_locksroot( channel_state.our_state.pending_locks), partner_onchain_locksroot=compute_locksroot( channel_state.partner_state.pending_locks), block_number=1, block_hash=make_block_hash(), ) assert settle_channel.our_onchain_locksroot != LOCKSROOT_OF_NO_LOCKS assert settle_channel.partner_onchain_locksroot == LOCKSROOT_OF_NO_LOCKS iteration = channel.state_transition( channel_state=channel_state, state_change=settle_channel, block_number=block_number, block_hash=block_hash, pseudo_random_generator=pseudo_random_generator, ) batch_unlock = make_unlock(channel_state.our_state, channel_state.partner_state) iteration = channel.state_transition( channel_state=iteration.new_state, state_change=batch_unlock, block_number=block_number, block_hash=block_hash, pseudo_random_generator=pseudo_random_generator, ) msg = "partner did not have any locks in the pending locks, channel should have been cleaned" assert iteration.new_state is None, msg
def test_channel_cleared_after_our_unlock(): our_model, _ = create_model(balance=700, merkletree_width=1) partner_model, partner_key1 = create_model(balance=700, merkletree_width=0) channel_state = create_channel_from_models(our_model, partner_model, partner_key1) block_number = 1 block_hash = make_block_hash() def make_unlock(unlock_end, partner_end): batch_unlock = ContractReceiveChannelBatchUnlock( transaction_hash=make_transaction_hash(), canonical_identifier=channel_state.canonical_identifier, participant=partner_end.address, partner=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 settle_channel = ContractReceiveChannelSettled( transaction_hash=make_transaction_hash(), canonical_identifier=channel_state.canonical_identifier, our_onchain_locksroot=merkleroot(channel_state.our_state.merkletree), partner_onchain_locksroot=merkleroot( channel_state.partner_state.merkletree), block_number=1, block_hash=make_block_hash(), ) assert settle_channel.our_onchain_locksroot is not EMPTY_MERKLE_ROOT assert settle_channel.partner_onchain_locksroot is EMPTY_MERKLE_ROOT iteration = channel.state_transition(channel_state, settle_channel, block_number, block_hash) batch_unlock = make_unlock(channel_state.our_state, channel_state.partner_state) iteration = channel.state_transition(iteration.new_state, batch_unlock, block_number, block_hash) msg = "partner did not have any locks in the merkletree, channel should have been cleaned" assert iteration.new_state is None, msg
def _channel_and_transfer(merkletree_width): our_model, _ = create_model(700) partner_model, privkey = create_model(700, merkletree_width) reverse_channel_state = create_channel_from_models(partner_model, our_model) lock_secret = sha3(b'some secret') lock = HashTimeLockState(30, 10, sha3(lock_secret)) mediated_transfer = make_receive_transfer_mediated( reverse_channel_state, privkey, nonce=1, transferred_amount=0, lock=lock, merkletree_leaves=partner_model.merkletree_leaves + [lock.lockhash], locked_amount=lock.amount, ) channel_state = deepcopy(reverse_channel_state) channel_state.our_state = reverse_channel_state.partner_state channel_state.partner_state = reverse_channel_state.our_state return channel_state, mediated_transfer
def test_subdispatch_by_canonical_id(chain_state): our_model, _ = create_model(balance=10, num_pending_locks=1) partner_model, _ = create_model(balance=0, num_pending_locks=0) channel_state = create_channel_from_models( our_model, partner_model, factories.make_privatekey_bin() ) canonical_identifier = channel_state.canonical_identifier token_network = TokenNetworkState( address=canonical_identifier.token_network_address, token_address=factories.make_address(), network_graph=TokenNetworkGraphState( token_network_address=channel_state.token_network_address ), ) token_network.partneraddresses_to_channelidentifiers[ partner_model.participant_address ] = canonical_identifier.channel_identifier token_network.channelidentifiers_to_channels[ canonical_identifier.channel_identifier ] = channel_state token_network_registry = TokenNetworkRegistryState( address=factories.make_address(), token_network_list=[token_network] ) chain_state.identifiers_to_tokennetworkregistries[ token_network_registry.address ] = token_network_registry chain_state.tokennetworkaddresses_to_tokennetworkregistryaddresses[ canonical_identifier.token_network_address ] = token_network_registry.address # dispatching a Block will be ignored previous_state = deepcopy(chain_state) state_change = Block( block_number=chain_state.block_number, gas_limit=GAS_LIMIT, block_hash=chain_state.block_hash, ) transition_result = subdispatch_by_canonical_id( chain_state=chain_state, canonical_identifier=canonical_identifier, state_change=state_change, ) assert transition_result.new_state == previous_state assert transition_result.events == [] state_change = ActionChannelClose(canonical_identifier=canonical_identifier) # dispatching for an unknown canonical_identifier will not emit events transition_result = subdispatch_by_canonical_id( chain_state=chain_state, canonical_identifier=CanonicalIdentifier( chain_identifier=chain_state.chain_id, token_network_address=factories.make_address(), channel_identifier=factories.make_channel_identifier(), ), state_change=state_change, ) assert not transition_result.events, transition_result assert get_status(channel_state) == ChannelState.STATE_OPENED transition_result = subdispatch_by_canonical_id( chain_state=chain_state, canonical_identifier=canonical_identifier, state_change=state_change, ) assert get_status(channel_state) == ChannelState.STATE_CLOSING assert transition_result.new_state == chain_state, transition_result
def test_channel_cleared_after_two_unlocks(): our_model, _ = create_model(balance=700, num_pending_locks=1) partner_model, partner_key1 = create_model(balance=700, num_pending_locks=1) channel_state = create_channel_from_models(our_model, partner_model, partner_key1) block_number = 1 block_hash = make_block_hash() pseudo_random_generator = random.Random() 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 settle_channel = ContractReceiveChannelSettled( transaction_hash=make_transaction_hash(), canonical_identifier=channel_state.canonical_identifier, our_onchain_locksroot=compute_locksroot( channel_state.our_state.pending_locks), partner_onchain_locksroot=compute_locksroot( channel_state.partner_state.pending_locks), block_number=1, block_hash=make_block_hash(), ) iteration = channel.state_transition( channel_state=channel_state, state_change=settle_channel, block_number=block_number, block_hash=block_hash, pseudo_random_generator=pseudo_random_generator, ) msg = "both participants have pending locks, locksroot must not represent the empty list" assert iteration.new_state.our_state.onchain_locksroot != LOCKSROOT_OF_NO_LOCKS, msg assert iteration.new_state.partner_state.onchain_locksroot != LOCKSROOT_OF_NO_LOCKS, msg batch_unlock = make_unlock(channel_state.our_state, channel_state.partner_state) iteration = channel.state_transition( channel_state=iteration.new_state, state_change=batch_unlock, block_number=block_number, block_hash=block_hash, pseudo_random_generator=pseudo_random_generator, ) msg = "all of our locks has been unlocked, onchain state must be updated" assert iteration.new_state.our_state.onchain_locksroot is LOCKSROOT_OF_NO_LOCKS, msg msg = "partner has pending locks, the locksroot must not represent the empty list" assert iteration.new_state.partner_state.onchain_locksroot is not LOCKSROOT_OF_NO_LOCKS, msg msg = "partner locksroot is not unlocked, channel should not have been cleaned" assert iteration.new_state is not None, msg # processing the same unlock twice must not count iteration = channel.state_transition( channel_state=iteration.new_state, state_change=batch_unlock, block_number=block_number, block_hash=block_hash, pseudo_random_generator=pseudo_random_generator, ) msg = "partner has pending locks, the locksroot must not represent the empty list" assert iteration.new_state.partner_state.onchain_locksroot is not LOCKSROOT_OF_NO_LOCKS, msg msg = "partner locksroot is not unlocked, channel should not have been cleaned" assert iteration.new_state is not None, msg iteration = channel.state_transition( channel_state=iteration.new_state, state_change=make_unlock(channel_state.partner_state, channel_state.our_state), block_number=block_number, block_hash=block_hash, pseudo_random_generator=pseudo_random_generator, ) msg = "all unlocks have been done, channel must be cleared" assert iteration.new_state is None, msg
def test_channel_cleared_after_two_unlocks(): our_model, _ = create_model(balance=700, merkletree_width=1) partner_model, partner_key1 = create_model(balance=700, merkletree_width=1) channel_state = create_channel_from_models(our_model, partner_model, partner_key1) block_number = 1 block_hash = make_block_hash() def make_unlock(unlock_end, partner_end): batch_unlock = ContractReceiveChannelBatchUnlock( transaction_hash=make_transaction_hash(), canonical_identifier=channel_state.canonical_identifier, participant=partner_end.address, partner=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 settle_channel = ContractReceiveChannelSettled( transaction_hash=make_transaction_hash(), canonical_identifier=channel_state.canonical_identifier, our_onchain_locksroot=merkleroot(channel_state.our_state.merkletree), partner_onchain_locksroot=merkleroot(channel_state.partner_state.merkletree), block_number=1, block_hash=make_block_hash(), ) iteration = channel.state_transition(channel_state, settle_channel, block_number, block_hash) msg = "both participants have pending locks, merkleroot must not be empty" assert iteration.new_state.our_state.onchain_locksroot is not EMPTY_MERKLE_ROOT, msg assert iteration.new_state.partner_state.onchain_locksroot is not EMPTY_MERKLE_ROOT, msg batch_unlock = make_unlock(channel_state.our_state, channel_state.partner_state) iteration = channel.state_transition( iteration.new_state, batch_unlock, block_number, block_hash ) msg = "all of our locks has been unlocked, onchain state must be updated" assert iteration.new_state.our_state.onchain_locksroot is EMPTY_MERKLE_ROOT, msg msg = "partner has pending locks, the merkleroot must not be cleared" assert iteration.new_state.partner_state.onchain_locksroot is not EMPTY_MERKLE_ROOT, msg msg = "partner locksroot is not unlocked, channel should not have been cleaned" assert iteration.new_state is not None, msg # processing the same unlock twice must not count iteration = channel.state_transition( iteration.new_state, batch_unlock, block_number, block_hash ) msg = "partner has pending locks, the merkleroot must not be cleared" assert iteration.new_state.partner_state.onchain_locksroot is not EMPTY_MERKLE_ROOT, msg msg = "partner locksroot is not unlocked, channel should not have been cleaned" assert iteration.new_state is not None, msg iteration = channel.state_transition( iteration.new_state, make_unlock(channel_state.partner_state, channel_state.our_state), block_number, block_hash, ) msg = "all unlocks have been done, channel must be cleared" assert iteration.new_state is None, msg