def test_target_task_view(): """Same as above for target tasks.""" secret = factories.make_secret() transfer = factories.create( factories.LockedTransferSignedStateProperties(secret=secret)) secrethash = transfer.lock.secrethash mediator = factories.make_address() mediator_channel = factories.create( factories.NettingChannelStateProperties( partner_state=factories.NettingChannelEndStateProperties( address=mediator, balance=TokenAmount(100)))) transfer_state = TargetTransferState( from_hop=HopState( channel_identifier=mediator_channel.canonical_identifier. channel_identifier, node_address=mediator, ), transfer=transfer, secret=secret, ) task = TargetTask( canonical_identifier=mediator_channel.canonical_identifier, target_state=transfer_state) payment_mapping = {secrethash: cast(TransferTask, task)} view = transfer_tasks_view(payment_mapping) assert len(view) == 1 pending_transfer = view[0] assert pending_transfer.get("role") == "target" # pylint: disable=no-member assert pending_transfer.get("locked_amount") == str( transfer.balance_proof.locked_amount) assert pending_transfer.get("payment_identifier") == str( transfer.payment_identifier)
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()], forward_channel_id=factories.make_channel_identifier() ) 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_subdispatch_to_paymenttask_target(chain_state, netting_channel_state): target_state = TargetTransferState( from_hop=HopState( node_address=netting_channel_state.partner_state.address, channel_identifier=netting_channel_state.canonical_identifier. channel_identifier, ), transfer=factories.create( factories.LockedTransferSignedStateProperties()), secret=UNIT_SECRET, ) subtask = TargetTask( canonical_identifier=netting_channel_state.canonical_identifier, target_state=target_state) chain_state.payment_mapping.secrethashes_to_task[UNIT_SECRETHASH] = subtask lock = factories.HashTimeLockState(amount=0, expiration=2, secrethash=UNIT_SECRETHASH) netting_channel_state.partner_state.secrethashes_to_lockedlocks[ UNIT_SECRETHASH] = lock netting_channel_state.partner_state.pending_locks = PendingLocksState( [bytes(lock.encoded)]) state_change = Block( block_number=chain_state.block_number, gas_limit=GAS_LIMIT, block_hash=chain_state.block_hash, ) transition_result = subdispatch_to_paymenttask(chain_state=chain_state, state_change=state_change, secrethash=UNIT_SECRETHASH) assert transition_result.events == [] assert transition_result.new_state == chain_state chain_state.block_number = 20 balance_proof: BalanceProofSignedState = factories.create( factories.BalanceProofSignedStateProperties( canonical_identifier=netting_channel_state.canonical_identifier, sender=netting_channel_state.partner_state.address, transferred_amount=0, pkey=factories.UNIT_TRANSFER_PKEY, locksroot=LOCKSROOT_OF_NO_LOCKS, )) state_change = ReceiveLockExpired( balance_proof=balance_proof, sender=netting_channel_state.partner_state.address, secrethash=UNIT_SECRETHASH, message_identifier=factories.make_message_identifier(), ) transition_result = subdispatch_to_paymenttask(chain_state=chain_state, state_change=state_change, secrethash=UNIT_SECRETHASH) msg = "ReceiveLockExpired should have cleared the task" assert UNIT_SECRETHASH not in chain_state.payment_mapping.secrethashes_to_task, msg assert len( transition_result.events), "ReceiveLockExpired should generate events" assert transition_result.new_state == chain_state
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_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 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 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)