def test_target_lock_is_expired_if_secret_is_not_registered_onchain(): lock_amount = 7 block_number = 1 initiator = factories.HOP6 pseudo_random_generator = random.Random() our_balance = 100 our_address = factories.make_address() partner_balance = 130 from_channel = factories.make_channel( our_address=our_address, our_balance=our_balance, partner_address=UNIT_TRANSFER_SENDER, partner_balance=partner_balance, ) from_route = factories.route_from_channel(from_channel) expiration = block_number + from_channel.settle_timeout - from_channel.reveal_timeout from_transfer = factories.make_signed_transfer_for( from_channel, lock_amount, initiator, our_address, expiration, UNIT_SECRET, ) init = ActionInitTarget( from_route, from_transfer, ) init_transition = target.state_transition( None, init, from_channel, pseudo_random_generator, block_number, ) assert init_transition.new_state is not None secret_reveal_iteration = target.state_transition( target_state=init_transition.new_state, state_change=ReceiveSecretReveal(UNIT_SECRET, from_channel.partner_state.address), channel_state=from_channel, pseudo_random_generator=pseudo_random_generator, block_number=block_number, ) expired_block_number = from_transfer.lock.expiration + DEFAULT_NUMBER_OF_BLOCK_CONFIRMATIONS iteration = target.state_transition( target_state=secret_reveal_iteration.new_state, state_change=Block(expired_block_number, None, None), channel_state=from_channel, pseudo_random_generator=pseudo_random_generator, block_number=expired_block_number, ) assert must_contain_entry(iteration.events, EventUnlockClaimFailed, {})
def test_handle_inittarget(): """ Init transfer must send a secret request if the expiration is valid. """ block_number = 1 pseudo_random_generator = random.Random() channels = make_channel_set([channel_properties]) transfer_properties = LockedTransferSignedStateProperties( amount=channels[0].partner_state.contract_balance, expiration=channels[0].reveal_timeout + block_number + 1, canonical_identifier=channels[0].canonical_identifier, transferred_amount=0, locked_amount=channels[0].partner_state.contract_balance, ) from_transfer = create(transfer_properties) state_change = ActionInitTarget(channels.get_route(0), from_transfer) iteration = target.handle_inittarget(state_change, channels[0], pseudo_random_generator, block_number) assert search_for_item( iteration.events, SendSecretRequest, { "payment_identifier": from_transfer.payment_identifier, "amount": from_transfer.lock.amount, "secrethash": from_transfer.lock.secrethash, "recipient": UNIT_TRANSFER_INITIATOR, }, ) assert search_for_item(iteration.events, SendProcessed, {})
def test_target_accept_keccak_empty_hash(): lock_amount = 7 block_number = 1 pseudo_random_generator = random.Random() channels = make_channel_set([channel_properties2]) expiration = block_number + channels[0].settle_timeout - channels[ 0].reveal_timeout from_transfer = factories.make_signed_transfer_for( channels[0], factories.LockedTransferSignedStateProperties( amount=lock_amount, target=channels.our_address(0), expiration=expiration, secret=EMPTY_SECRET, ), allow_invalid=True, ) init = ActionInitTarget( from_hop=channels.get_hop(0), transfer=from_transfer, balance_proof=from_transfer.balance_proof, sender=from_transfer.balance_proof.sender, # pylint: disable=no-member ) init_transition = target.state_transition( target_state=None, state_change=init, channel_state=channels[0], pseudo_random_generator=pseudo_random_generator, block_number=block_number, ) assert init_transition.new_state
def test_handle_inittarget_bad_expiration(): """ Init transfer must do nothing if the expiration is bad. """ block_number = 1 amount = 3 initiator = factories.HOP1 target_address = UNIT_TRANSFER_TARGET payment_network_identifier = factories.make_address() from_channel = factories.make_channel( our_address=target_address, partner_address=UNIT_TRANSFER_SENDER, partner_balance=amount, ) from_route = factories.route_from_channel(from_channel) expiration = from_channel.reveal_timeout + block_number + 1 from_transfer = factories.make_signed_transfer_for( from_channel, amount, initiator, target_address, expiration, UNIT_SECRET, ) channel.handle_receive_lockedtransfer( from_channel, from_transfer, ) state_change = ActionInitTarget(payment_network_identifier, from_route, from_transfer) iteration = target.handle_inittarget(state_change, from_channel, block_number) assert must_contain_entry(iteration.events, EventWithdrawFailed, {})
def test_target_reject_keccak_empty_hash(): lock_amount = 7 block_number = 1 pseudo_random_generator = random.Random() channels = make_channel_set([channel_properties2]) expiration = block_number + channels[0].settle_timeout - channels[ 0].reveal_timeout from_transfer = factories.make_signed_transfer_for( channels[0], factories.LockedTransferSignedStateProperties( transfer=factories.LockedTransferProperties( amount=lock_amount, target=channels.our_address(0), expiration=expiration, secret=EMPTY_HASH, ), ), allow_invalid=True, ) init = ActionInitTarget(route=channels.get_route(0), transfer=from_transfer) init_transition = target.state_transition( target_state=None, state_change=init, channel_state=channels[0], pseudo_random_generator=pseudo_random_generator, block_number=block_number, ) assert init_transition.new_state is None
def test_handle_inittarget_bad_expiration(): """ Init transfer must do nothing if the expiration is bad. """ block_number = 1 amount = 3 expire = factories.UNIT_REVEAL_TIMEOUT + block_number from_transfer = factories.make_transfer( amount, factories.ADDR, expire, ) from_route = factories.make_route( factories.HOP1, amount, ) state_change = ActionInitTarget( factories.ADDR, from_route, from_transfer, factories.UNIT_HASHLOCK, block_number, ) iteration = target.handle_inittarget(state_change) assert len(iteration.events) == 0
def test_handle_inittarget(): """ Init transfer must send a secret request if the expiration is valid. """ block_number = 1 amount = 3 expire = factories.UNIT_REVEAL_TIMEOUT + block_number + 1 initiator = factories.HOP1 from_route, from_transfer = factories.make_from( amount, factories.ADDR, expire, initiator, ) state_change = ActionInitTarget( factories.ADDR, from_route, from_transfer, block_number, ) iteration = target.handle_inittarget(state_change) events = iteration.events assert isinstance(events[0], SendSecretRequest) assert events[0].identifier == from_transfer.identifier assert events[0].amount == from_transfer.amount assert events[0].hashlock == from_transfer.hashlock assert events[0].receiver == initiator
def test_target_receive_lock_expired(): lock_amount = 7 block_number = 1 pseudo_random_generator = random.Random() channels = make_channel_set([channel_properties2]) expiration = block_number + channels[0].settle_timeout - channels[ 0].reveal_timeout from_transfer = make_target_transfer(channels[0], amount=lock_amount, block_number=block_number) init = ActionInitTarget(channels.get_route(0), from_transfer) init_transition = target.state_transition( target_state=None, state_change=init, channel_state=channels[0], pseudo_random_generator=pseudo_random_generator, block_number=block_number, ) assert init_transition.new_state is not None assert init_transition.new_state.route == channels.get_route(0) assert init_transition.new_state.transfer == from_transfer balance_proof = create( BalanceProofSignedStateProperties( nonce=2, transferred_amount=from_transfer.balance_proof.transferred_amount, locked_amount=0, canonical_identifier=channels[0].canonical_identifier, message_hash=from_transfer.lock.secrethash, )) lock_expired_state_change = ReceiveLockExpired( balance_proof=balance_proof, secrethash=from_transfer.lock.secrethash, message_identifier=1) block_before_confirmed_expiration = expiration + DEFAULT_NUMBER_OF_BLOCK_CONFIRMATIONS - 1 iteration = target.state_transition( target_state=init_transition.new_state, state_change=lock_expired_state_change, channel_state=channels[0], pseudo_random_generator=pseudo_random_generator, block_number=block_before_confirmed_expiration, ) assert not search_for_item(iteration.events, SendProcessed, {}) block_lock_expired = block_before_confirmed_expiration + 1 iteration = target.state_transition( target_state=init_transition.new_state, state_change=lock_expired_state_change, channel_state=channels[0], pseudo_random_generator=pseudo_random_generator, block_number=block_lock_expired, ) assert search_for_item(iteration.events, SendProcessed, {})
def test_state_transition(): """ Happy case testing. """ amount = 7 block_number = 1 initiator = factories.HOP6 expire = block_number + factories.UNIT_REVEAL_TIMEOUT from_route, from_transfer = factories.make_from( amount, factories.ADDR, expire, initiator, ) init = ActionInitTarget( factories.ADDR, from_route, from_transfer, block_number, ) init_transition = target.state_transition(None, init) assert init_transition.new_state is not None assert init_transition.new_state.from_route == from_route assert init_transition.new_state.from_transfer == from_transfer first_new_block = Block(block_number + 1) first_block_iteration = target.state_transition(init_transition.new_state, first_new_block) assert first_block_iteration.new_state.block_number == block_number + 1 secret_reveal = ReceiveSecretReveal(factories.UNIT_SECRET, initiator) reveal_iteration = target.state_transition(first_block_iteration.new_state, secret_reveal) assert reveal_iteration.new_state.from_transfer.secret == factories.UNIT_SECRET second_new_block = Block(block_number + 2) second_block_iteration = target.state_transition(init_transition.new_state, second_new_block) assert second_block_iteration.new_state.block_number == block_number + 2 nonce = 11 transferred_amount = 13 locksroot = '' message_hash = '' balance_proof = ReceiveBalanceProof( from_transfer.identifier, from_route.node_address, nonce, transferred_amount, locksroot, from_route.channel_address, message_hash, ) proof_iteration = target.state_transition(init_transition.new_state, balance_proof) assert proof_iteration.new_state is None
def handle_message_lockedtransfer( raiden: "RaidenService", message: LockedTransfer # pylint: disable=unused-argument ) -> List[StateChange]: secrethash = message.lock.secrethash # We must check if the secret was registered against the latest block, # even if the block is forked away and the transaction that registers # the secret is removed from the blockchain. The rationale here is that # someone else does know the secret, regardless of the chain state, so # the node must not use it to start a payment. # # For this particular case, it's preferable to use `latest` instead of # having a specific block_hash, because it's preferable to know if the secret # was ever known, rather than having a consistent view of the blockchain. registered = raiden.default_secret_registry.is_secret_registered( secrethash=secrethash, block_identifier=BLOCK_ID_LATEST ) if registered: log.warning( f"Ignoring received locked transfer with secrethash {to_hex(secrethash)} " f"since it is already registered in the secret registry" ) return [] assert message.sender, "Invalid message dispatched, it should be signed" from_transfer = lockedtransfersigned_from_message(message) from_hop = HopState( node_address=message.sender, # pylint: disable=E1101 channel_identifier=from_transfer.balance_proof.channel_identifier, ) if message.target == TargetAddress(raiden.address): raiden.immediate_health_check_for(Address(message.initiator)) return [ ActionInitTarget( from_hop=from_hop, transfer=from_transfer, balance_proof=from_transfer.balance_proof, sender=from_transfer.balance_proof.sender, ) ] else: route_states = routing.resolve_routes( routes=message.metadata.routes, token_network_address=from_transfer.balance_proof.token_network_address, chain_state=views.state_from_raiden(raiden), ) return [ ActionInitMediator( from_hop=from_hop, route_states=route_states, from_transfer=from_transfer, balance_proof=from_transfer.balance_proof, sender=from_transfer.balance_proof.sender, ) ]
def test_target_transfer_invalid_if_lock_registered_onchain(): lock_amount = 7 block_number = 1 initiator = factories.HOP6 pseudo_random_generator = random.Random() our_balance = 100 our_address = factories.make_address() partner_balance = 130 from_channel = factories.make_channel( our_address=our_address, our_balance=our_balance, partner_address=UNIT_TRANSFER_SENDER, partner_balance=partner_balance, ) from_route = factories.route_from_channel(from_channel) expiration = block_number + from_channel.settle_timeout - from_channel.reveal_timeout from_transfer = factories.make_signed_transfer_for( from_channel, lock_amount, initiator, our_address, expiration, UNIT_SECRET, identifier=1, nonce=1, ) init = ActionInitTarget( from_route, from_transfer, ) secrethash = from_transfer.lock.secrethash # mock register secret on-chain from_channel.our_state.secrethashes_to_lockedlocks[ secrethash] = from_transfer.lock channel.register_onchain_secret( channel_state=from_channel, secret=UNIT_SECRET, secrethash=secrethash, secret_reveal_block_number=0, delete_lock=True, ) init_transition = target.state_transition( None, init, from_channel, pseudo_random_generator, block_number, ) assert init_transition.new_state is None
def target_init(transfer: LockedTransfer): from_transfer = lockedtransfersigned_from_message(transfer) from_route = RouteState( transfer.sender, from_transfer.balance_proof.channel_address, ) init_target_statechange = ActionInitTarget( from_route, from_transfer, ) return init_target_statechange
def test_invalid_instantiation_action_init_mediator_and_target( additional_args): hop_state = HopState( node_address=factories.make_address(), channel_identifier=factories.make_channel_identifier(), ) route_state = RouteState(route=[factories.make_address()]) not_a_route_state = object() valid_transfer = factories.create( factories.LockedTransferSignedStateProperties()) wrong_type_transfer = factories.create( factories.TransferDescriptionProperties()) with pytest.raises(ValueError): ActionInitMediator( from_transfer=wrong_type_transfer, from_hop=hop_state, route_states=[route_state], **additional_args, ) with pytest.raises(ValueError): ActionInitMediator( from_transfer=valid_transfer, from_hop=not_a_route_state, route_states=[route_state], **additional_args, ) with pytest.raises(ValueError): ActionInitTarget(transfer=wrong_type_transfer, from_hop=hop_state, **additional_args) with pytest.raises(ValueError): ActionInitTarget(transfer=valid_transfer, from_hop=not_a_route_state, **additional_args)
def test_get_state_change_with_transfer_by_secrethash(): serializer = JSONSerializer() storage = SerializedSQLiteStorage(":memory:", serializer) mediator_secret, mediator_secrethash = factories.make_secret_with_hash() channels = factories.mediator_make_channel_pair() mediator_transfer = factories.create( factories.LockedTransferSignedStateProperties( secret=mediator_secret, target=channels.partner_address(1), initiator=channels.partner_address(0), ) ) mediator_state_change = factories.mediator_make_init_action(channels, mediator_transfer) target_secret, target_secrethash = factories.make_secret_with_hash() from_channel = factories.create( factories.NettingChannelStateProperties( partner_state=factories.NettingChannelEndStateProperties( balance=100, address=factories.make_address() ) ) ) target_transfer = factories.create( factories.LockedTransferSignedStateProperties( secret=target_secret, target=channels.our_address(0), initiator=channels.partner_address(1), ) ) target_state_change = ActionInitTarget( from_hop=HopState( node_address=from_channel.partner_state.address, channel_identifier=from_channel.canonical_identifier.channel_identifier, ), transfer=target_transfer, balance_proof=target_transfer.balance_proof, sender=target_transfer.balance_proof.sender, # pylint: disable=no-member ) assert storage.count_state_changes() == 0 storage.write_state_changes([mediator_state_change, target_state_change]) assert storage.count_state_changes() == 2 restored = get_state_change_with_transfer_by_secrethash(storage, mediator_secrethash) assert isinstance(restored.data, ActionInitMediator) assert restored.data.from_transfer == mediator_transfer restored = get_state_change_with_transfer_by_secrethash(storage, target_secrethash) assert isinstance(restored.data, ActionInitTarget) assert restored.data.transfer == target_transfer
def target_init(raiden, transfer): from_transfer = lockedtransfersigned_from_message(transfer) from_route = RouteState( transfer.sender, from_transfer.balance_proof.channel_address, ) registry_address = raiden.default_registry.address init_target_statechange = ActionInitTarget( registry_address, from_route, from_transfer, ) return init_target_statechange
def locked_transfer_to_action_init_target( locked_transfer: LockedTransfer) -> ActionInitTarget: from_transfer = lockedtransfersigned_from_message(locked_transfer) channel_id = from_transfer.balance_proof.channel_identifier # pylint: disable=no-member from_hop = HopState(node_address=Address(locked_transfer.initiator), channel_identifier=channel_id) init_target_statechange = ActionInitTarget( from_hop=from_hop, transfer=from_transfer, balance_proof=from_transfer.balance_proof, sender=from_transfer.balance_proof.sender, # pylint: disable=no-member ) return init_target_statechange
def test_handle_inittarget_bad_expiration(): """ Init transfer must do nothing if the expiration is bad. """ block_number = 1 pseudo_random_generator = random.Random() channels = make_channel_set([channel_properties]) expiration = channels[0].reveal_timeout + block_number + 1 from_transfer = make_target_transfer(channels[0], expiration=expiration) channel.handle_receive_lockedtransfer(channels[0], from_transfer) state_change = ActionInitTarget(channels.get_route(0), from_transfer) iteration = target.handle_inittarget(state_change, channels[0], pseudo_random_generator, block_number) assert search_for_item(iteration.events, EventUnlockClaimFailed, {})
def test_handle_inittarget(): """ Init transfer must send a secret request if the expiration is valid. """ amount = 3 block_number = 1 initiator = factories.HOP1 target_address = UNIT_TRANSFER_TARGET payment_network_identifier = factories.make_address() pseudo_random_generator = random.Random() from_channel = factories.make_channel( our_address=target_address, partner_address=UNIT_TRANSFER_SENDER, partner_balance=amount, ) from_route = factories.route_from_channel(from_channel) expiration = from_channel.reveal_timeout + block_number + 1 from_transfer = factories.make_signed_transfer( amount, initiator, target_address, expiration, UNIT_SECRET, channel_identifier=from_channel.identifier, ) state_change = ActionInitTarget( payment_network_identifier, from_route, from_transfer, ) iteration = target.handle_inittarget( state_change, from_channel, pseudo_random_generator, block_number, ) events = iteration.events assert events assert isinstance(events[0], SendSecretRequest) assert events[0].payment_identifier == from_transfer.payment_identifier assert events[0].amount == from_transfer.lock.amount assert events[0].secrethash == from_transfer.lock.secrethash assert events[0].recipient == initiator
def test_handle_inittarget(): """ Init transfer must send a secret request if the expiration is valid. """ amount = 3 block_number = 1 initiator = factories.HOP1 target_address = UNIT_TRANSFER_TARGET pseudo_random_generator = random.Random() from_channel = factories.make_channel( our_address=target_address, partner_address=UNIT_TRANSFER_SENDER, partner_balance=amount, ) from_route = factories.route_from_channel(from_channel) expiration = from_channel.reveal_timeout + block_number + 1 from_transfer = factories.make_signed_transfer( amount, initiator, target_address, expiration, UNIT_SECRET, channel_identifier=from_channel.identifier, token_network_address=from_channel.token_network_identifier, ) state_change = ActionInitTarget( from_route, from_transfer, ) iteration = target.handle_inittarget( state_change, from_channel, pseudo_random_generator, block_number, ) assert must_contain_entry( iteration.events, SendSecretRequest, { 'payment_identifier': from_transfer.payment_identifier, 'amount': from_transfer.lock.amount, 'secrethash': from_transfer.lock.secrethash, 'recipient': initiator, }) assert must_contain_entry(iteration.events, SendProcessed, {})
def make_target_state( our_address=factories.ADDR, amount=3, block_number=1, initiator=UNIT_TRANSFER_INITIATOR, expiration=None, pseudo_random_generator=None, ): pseudo_random_generator = pseudo_random_generator or random.Random() channels = make_channel_set( [ NettingChannelStateProperties( our_state=NettingChannelEndStateProperties(address=our_address), partner_state=NettingChannelEndStateProperties( address=UNIT_TRANSFER_SENDER, balance=amount ), ) ] ) expiration = expiration or channels[0].reveal_timeout + block_number + 1 from_transfer = make_target_transfer(channels[0], amount, expiration, initiator) state_change = ActionInitTarget( from_hop=channels.get_hop(0), transfer=from_transfer, balance_proof=from_transfer.balance_proof, sender=from_transfer.balance_proof.sender, # pylint: disable=no-member ) iteration = target.handle_inittarget( state_change=state_change, channel_state=channels[0], pseudo_random_generator=pseudo_random_generator, block_number=block_number, ) return TargetStateSetup( channel=channels[0], new_state=iteration.new_state, our_address=our_address, initiator=initiator, expiration=expiration, amount=amount, block_number=block_number, pseudo_random_generator=pseudo_random_generator, )
def test_target_lock_is_expired_if_secret_is_not_registered_onchain(): lock_amount = 7 block_number = 1 pseudo_random_generator = random.Random() channels = make_channel_set([channel_properties2]) from_transfer = make_target_transfer(channels[0], amount=lock_amount, block_number=1) init = ActionInitTarget( from_hop=channels.get_hop(0), transfer=from_transfer, balance_proof=from_transfer.balance_proof, sender=from_transfer.balance_proof.sender, # pylint: disable=no-member ) init_transition = target.state_transition( target_state=None, state_change=init, channel_state=channels[0], pseudo_random_generator=pseudo_random_generator, block_number=block_number, ) assert init_transition.new_state is not None secret_reveal_iteration = target.state_transition( target_state=init_transition.new_state, state_change=ReceiveSecretReveal(UNIT_SECRET, channels[0].partner_state.address), channel_state=channels[0], pseudo_random_generator=pseudo_random_generator, block_number=block_number, ) expired_block_number = channel.get_receiver_expiration_threshold( from_transfer.lock.expiration) iteration = target.state_transition( target_state=secret_reveal_iteration.new_state, state_change=Block(expired_block_number, None, None), channel_state=channels[0], pseudo_random_generator=pseudo_random_generator, block_number=expired_block_number, ) assert search_for_item(iteration.events, EventUnlockClaimFailed, {})
def make_init_state_change(our_address, amount, block_number, initiator, expire=None): if expire is None: expire = block_number + factories.UNIT_REVEAL_TIMEOUT from_route, from_transfer = factories.make_from( amount, our_address, expire, initiator, ) init = ActionInitTarget( our_address, from_route, from_transfer, block_number, ) return init
def test_target_reject_keccak_empty_hash(): lock_amount = 7 block_number = 1 initiator = factories.HOP6 pseudo_random_generator = random.Random() our_balance = 100 our_address = factories.make_address() partner_balance = 130 from_channel = factories.make_channel( our_address=our_address, our_balance=our_balance, partner_address=UNIT_TRANSFER_SENDER, partner_balance=partner_balance, ) from_route = factories.route_from_channel(from_channel) expiration = block_number + from_channel.settle_timeout - from_channel.reveal_timeout from_transfer = factories.make_signed_transfer_for( channel_state=from_channel, amount=lock_amount, initiator=initiator, target=our_address, expiration=expiration, secret=EMPTY_HASH, allow_invalid=True, ) init = ActionInitTarget( route=from_route, transfer=from_transfer, ) init_transition = target.state_transition( None, init, from_channel, pseudo_random_generator, block_number, ) assert init_transition.new_state is None
def target_mediated_transfer(self, message): graph = self.token_to_channelgraph[message.token] from_channel = graph.partneraddress_to_channel[message.sender] from_route = channel_to_routestate(from_channel, message.sender) from_transfer = lockedtransfer_from_message(message) our_address = self.address block_number = self.get_block_number() init_target = ActionInitTarget( our_address, from_route, from_transfer, block_number, ) state_manager = StateManager(target_task.state_transition, None) self.state_machine_event_handler.log_and_dispatch(state_manager, init_target) identifier = message.identifier self.identifier_to_statemanagers[identifier].append(state_manager)
def test_target_lock_is_expired_if_secret_is_not_registered_onchain(): lock_amount = 7 block_number = 1 pseudo_random_generator = random.Random() channels = make_channel_set([channel_properties2]) from_transfer = make_target_transfer(channels[0], amount=lock_amount, block_number=1) init = ActionInitTarget(channels.get_route(0), from_transfer) init_transition = target.state_transition( target_state=None, state_change=init, channel_state=channels[0], pseudo_random_generator=pseudo_random_generator, block_number=block_number, ) assert init_transition.new_state is not None secret_reveal_iteration = target.state_transition( target_state=init_transition.new_state, state_change=ReceiveSecretReveal(UNIT_SECRET, channels[0].partner_state.address), channel_state=channels[0], pseudo_random_generator=pseudo_random_generator, block_number=block_number, ) expired_block_number = from_transfer.lock.expiration + DEFAULT_NUMBER_OF_BLOCK_CONFIRMATIONS iteration = target.state_transition( target_state=secret_reveal_iteration.new_state, state_change=Block(expired_block_number, None, None), channel_state=channels[0], pseudo_random_generator=pseudo_random_generator, block_number=expired_block_number, ) assert must_contain_entry(iteration.events, EventUnlockClaimFailed, {})
def action_init_initiator_to_action_init_target( action: ActionInitInitiator, channel: NettingChannelState, block_number: BlockNumber, route_state: RouteState, address: Address, private_key: PrivateKey, ) -> ActionInitTarget: transfer = signed_transfer_from_description( private_key=private_key, description=action.transfer, channel=channel, message_id=factories.make_message_identifier(), block_number=block_number, route_state=route_state, route_states=action.routes, ) from_hop = HopState(node_address=address, channel_identifier=channel.identifier) return ActionInitTarget(from_hop=from_hop, transfer=transfer, sender=address, balance_proof=transfer.balance_proof)
def test_handle_inittarget(): """ Init transfer must send a secret request if the expiration is valid. """ block_number = 1 pseudo_random_generator = random.Random() channels = make_channel_set([channel_properties]) transfer_properties = LockedTransferSignedStateProperties( transfer=LockedTransferProperties( amount=channels[0].partner_state.contract_balance, expiration=channels[0].reveal_timeout + block_number + 1, balance_proof=BalanceProofProperties( channel_identifier=channels[0].identifier, token_network_identifier=channels[0].token_network_identifier, transferred_amount=0, locked_amount=channels[0].partner_state.contract_balance, ), ), ) from_transfer = create(transfer_properties) state_change = ActionInitTarget(channels.get_route(0), from_transfer) iteration = target.handle_inittarget( state_change, channels[0], pseudo_random_generator, block_number, ) assert must_contain_entry( iteration.events, SendSecretRequest, { 'payment_identifier': from_transfer.payment_identifier, 'amount': from_transfer.lock.amount, 'secrethash': from_transfer.lock.secrethash, 'recipient': UNIT_TRANSFER_INITIATOR, }) assert must_contain_entry(iteration.events, SendProcessed, {})
def make_target_state( our_address, amount, block_number, initiator, expiration=None, pseudo_random_generator=None, ): pseudo_random_generator = pseudo_random_generator or random.Random() from_channel = factories.make_channel( our_address=our_address, partner_address=UNIT_TRANSFER_SENDER, partner_balance=amount, ) from_route = factories.route_from_channel(from_channel) if expiration is None: expiration = from_channel.reveal_timeout + block_number + 1 from_transfer = factories.make_signed_transfer_for( from_channel, amount, initiator, our_address, expiration, UNIT_SECRET, ) state_change = ActionInitTarget(from_route, from_transfer) iteration = target.handle_inittarget( state_change, from_channel, pseudo_random_generator, block_number, ) return from_channel, iteration.new_state
def test_get_state_change_with_balance_proof(): """ All state changes which contain a balance proof must be found by when querying the database. """ serializer = JSONSerializer storage = SQLiteStorage(':memory:', serializer) counter = itertools.count() lock_expired = ReceiveLockExpired( balance_proof=make_signed_balance_proof_from_counter(counter), secrethash=sha3(factories.make_secret(next(counter))), message_identifier=next(counter), ) unlock = ReceiveUnlock( message_identifier=next(counter), secret=sha3(factories.make_secret(next(counter))), balance_proof=make_signed_balance_proof_from_counter(counter), ) transfer_refund = ReceiveTransferRefund( transfer=make_signed_transfer_from_counter(counter), routes=list(), ) transfer_refund_cancel_route = ReceiveTransferRefundCancelRoute( routes=list(), transfer=make_signed_transfer_from_counter(counter), secret=sha3(factories.make_secret(next(counter))), ) mediator_from_route, mediator_signed_transfer = make_from_route_from_counter( counter) action_init_mediator = ActionInitMediator( routes=list(), from_route=mediator_from_route, from_transfer=mediator_signed_transfer, ) target_from_route, target_signed_transfer = make_from_route_from_counter( counter) action_init_target = ActionInitTarget( route=target_from_route, transfer=target_signed_transfer, ) statechanges_balanceproofs = [ (lock_expired, lock_expired.balance_proof), (unlock, unlock.balance_proof), (transfer_refund, transfer_refund.transfer.balance_proof), (transfer_refund_cancel_route, transfer_refund_cancel_route.transfer.balance_proof), (action_init_mediator, action_init_mediator.from_transfer.balance_proof), (action_init_target, action_init_target.transfer.balance_proof), ] timestamp = datetime.utcnow().isoformat(timespec='milliseconds') for state_change, _ in statechanges_balanceproofs: storage.write_state_change(state_change, timestamp) for state_change, balance_proof in statechanges_balanceproofs: state_change_record = get_state_change_with_balance_proof( storage=storage, chain_id=balance_proof.chain_id, token_network_identifier=balance_proof.token_network_identifier, channel_identifier=balance_proof.channel_identifier, sender=balance_proof.sender, balance_hash=balance_proof.balance_hash, ) assert state_change_record.data == state_change
def test_multiple_channel_states( 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 # Create new channel while the previous one is pending unlock new_channel_state = factories.make_channel( our_balance=our_balance, partner_balance=our_balance, partner_address=address, ) channel_new_state_change = ContractReceiveChannelNew( factories.make_transaction_hash(), token_network_state.address, new_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, ) token_network_state_after_new_open = channel_new_iteration.new_state ids_to_channels = token_network_state_after_new_open.channelidentifiers_to_channels assert len(ids_to_channels) == 2 assert channel_state.identifier in ids_to_channels