def test_invalid_instantiation_locked_transfer_state(): valid_unsigned = factories.create( factories.LockedTransferUnsignedStateProperties()) valid_signed = factories.create( factories.LockedTransferSignedStateProperties()) # neither class can be instantiated with an empty locksroot for valid in (valid_unsigned, valid_signed): empty_balance_proof = replace(valid.balance_proof, locksroot=LOCKSROOT_OF_NO_LOCKS) with pytest.raises(ValueError): replace(valid, balance_proof=empty_balance_proof) # an unsigned locked transfer state cannot be instantiated with a signed balance proof with pytest.raises(ValueError): replace(valid_unsigned, balance_proof=valid_signed.balance_proof) # and vice versa with pytest.raises(ValueError): replace(valid_signed, balance_proof=valid_unsigned.balance_proof) # lock is typechecked wrong_type_lock = object() for valid in (valid_unsigned, valid_signed): with pytest.raises(ValueError): replace(valid, lock=wrong_type_lock)
def test_mediator_task_view(): """Same as above for mediator tasks.""" secret1 = factories.make_secret(1) locked_amount1 = 11 payee_transfer = factories.create( factories.LockedTransferUnsignedStateProperties(secret=secret1)) payer_transfer = factories.create( factories.LockedTransferSignedStateProperties( secret=secret1, payment_identifier=1, locked_amount=locked_amount1)) secrethash1 = payee_transfer.lock.secrethash initiator = payee_transfer.initiator initiator_channel = factories.create( factories.NettingChannelStateProperties( partner_state=factories.NettingChannelEndStateProperties( address=initiator, balance=100))) routes = [factories.make_route_from_channel(initiator_channel)] transfer_state1 = MediatorTransferState(secrethash=secrethash1, routes=routes) transfer_state1.transfers_pair.append( MediationPairState( payer_transfer=payer_transfer, payee_transfer=payee_transfer, payee_address=payee_transfer.target, )) task1 = MediatorTask( token_network_identifier=factories.UNIT_TOKEN_NETWORK_ADDRESS, mediator_state=transfer_state1, ) secret2 = factories.make_secret(2) locked_amount2 = 13 transfer2 = factories.create( factories.LockedTransferSignedStateProperties( secret=secret2, payment_identifier=2, locked_amount=locked_amount2)) secrethash2 = transfer2.lock.secrethash transfer_state2 = MediatorTransferState(secrethash=secrethash2, routes=routes) transfer_state2.waiting_transfer = WaitingTransferState(transfer=transfer2) task2 = MediatorTask( token_network_identifier=factories.UNIT_TOKEN_NETWORK_ADDRESS, mediator_state=transfer_state2, ) payment_mapping = {secrethash1: task1, secrethash2: task2} view = transfer_tasks_view(payment_mapping) assert len(view) == 2 if view[0].get("payment_identifier") == "1": pending_transfer, waiting_transfer = view else: waiting_transfer, pending_transfer = view assert pending_transfer.get("role") == waiting_transfer.get( "role") == "mediator" assert pending_transfer.get("payment_identifier") == "1" assert waiting_transfer.get("payment_identifier") == "2" assert pending_transfer.get("locked_amount") == str(locked_amount1) assert waiting_transfer.get("locked_amount") == str(locked_amount2)
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_target_task_view(): """Same as above for target tasks.""" secret = factories.make_secret() transfer = factories.create( factories.LockedTransferSignedStateProperties( transfer=factories.LockedTransferProperties(secret=secret), )) secrethash = transfer.lock.secrethash mediator = factories.make_address() mediator_channel = factories.create( factories.NettingChannelStateProperties( partner_state=factories.NettingChannelEndStateProperties( address=mediator, balance=100), )) transfer_state = TargetTransferState(route=None, transfer=transfer, secret=secret) task = TargetTask( token_network_identifier=factories.UNIT_TOKEN_NETWORK_ADDRESS, channel_identifier=mediator_channel.identifier, target_state=transfer_state, ) payment_mapping = {secrethash: task} view = transfer_tasks_view(payment_mapping) assert len(view) == 1 pending_transfer = view[0] assert pending_transfer.get('role') == 'target' assert pending_transfer.get('locked_amount') == str( transfer.balance_proof.locked_amount) assert pending_transfer.get('payment_identifier') == str( transfer.payment_identifier)
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=100))) transfer_state = TargetTransferState(route=None, transfer=transfer, secret=secret) task = TargetTask( canonical_identifier=mediator_channel.canonical_identifier, target_state=transfer_state) payment_mapping = {secrethash: task} view = transfer_tasks_view(payment_mapping) assert len(view) == 1 pending_transfer = view[0] assert pending_transfer.get("role") == "target" assert pending_transfer.get("locked_amount") == str( transfer.balance_proof.locked_amount) assert pending_transfer.get("payment_identifier") == str( transfer.payment_identifier)
def test_mediator_task_view(): """Same as above for mediator tasks.""" secret1 = factories.make_secret(1) locked_amount1 = TokenAmount(11) payee_transfer = factories.create( factories.LockedTransferUnsignedStateProperties(secret=secret1)) payer_transfer = factories.create( factories.LockedTransferSignedStateProperties( secret=secret1, payment_identifier=PaymentID(1), locked_amount=locked_amount1)) secrethash1 = payee_transfer.lock.secrethash route_state = RouteState(route=[payee_transfer.target]) transfer_state1 = MediatorTransferState(secrethash=secrethash1, routes=[route_state]) # pylint: disable=E1101 transfer_state1.transfers_pair.append( MediationPairState( payer_transfer=payer_transfer, payee_transfer=payee_transfer, payee_address=payee_transfer.target, )) task1 = MediatorTask( token_network_address=factories.UNIT_TOKEN_NETWORK_ADDRESS, mediator_state=transfer_state1) secret2 = factories.make_secret(2) locked_amount2 = TokenAmount(13) transfer2 = factories.create( factories.LockedTransferSignedStateProperties( secret=secret2, payment_identifier=PaymentID(2), locked_amount=locked_amount2)) secrethash2 = transfer2.lock.secrethash transfer_state2 = MediatorTransferState(secrethash=secrethash2, routes=[route_state]) transfer_state2.waiting_transfer = WaitingTransferState(transfer=transfer2) task2 = MediatorTask( token_network_address=factories.UNIT_TOKEN_NETWORK_ADDRESS, mediator_state=transfer_state2) payment_mapping = { secrethash1: cast(TransferTask, task1), secrethash2: cast(TransferTask, task2), } view = transfer_tasks_view(payment_mapping) assert len(view) == 2 if view[0].get("payment_identifier") == "1": pending_transfer, waiting_transfer = view else: waiting_transfer, pending_transfer = view assert pending_transfer.get("role") == waiting_transfer.get( "role") == "mediator" assert pending_transfer.get("payment_identifier") == "1" assert waiting_transfer.get("payment_identifier") == "2" assert pending_transfer.get("locked_amount") == str(locked_amount1) assert waiting_transfer.get("locked_amount") == str(locked_amount2)
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 test_pfs_global_messages( local_matrix_servers, private_rooms, retry_interval, retries_before_backoff, monkeypatch, global_rooms, ): """ Test that RaidenService sends UpdatePFS messages to global PATH_FINDING_BROADCASTING_ROOM room on newly received balance proofs. """ transport = MatrixTransport({ "global_rooms": global_rooms, # FIXME: #3735 "retries_before_backoff": retries_before_backoff, "retry_interval": retry_interval, "server": local_matrix_servers[0], "server_name": local_matrix_servers[0].netloc, "available_servers": [local_matrix_servers[0]], "private_rooms": private_rooms, }) transport._client.api.retry_timeout = 0 transport._send_raw = MagicMock() raiden_service = MockRaidenService(None) raiden_service.config = dict(services=dict(monitoring_enabled=True)) transport.start(raiden_service, raiden_service.message_handler, None) pfs_room_name = make_room_alias(transport.network_id, PATH_FINDING_BROADCASTING_ROOM) pfs_room = transport._global_rooms.get(pfs_room_name) assert isinstance(pfs_room, Room) pfs_room.send_text = MagicMock(spec=pfs_room.send_text) raiden_service.transport = transport transport.log = MagicMock() balance_proof = factories.create(HOP1_BALANCE_PROOF) channel_state = factories.create(factories.NettingChannelStateProperties()) channel_state.our_state.balance_proof = balance_proof channel_state.partner_state.balance_proof = balance_proof monkeypatch.setattr( raiden.transfer.views, "get_channelstate_by_canonical_identifier", lambda *a, **kw: channel_state, ) update_path_finding_service_from_balance_proof( raiden=raiden_service, chain_state=None, new_balance_proof=balance_proof) gevent.idle() with gevent.Timeout(2): while pfs_room.send_text.call_count < 1: gevent.idle() assert pfs_room.send_text.call_count == 1 transport.stop() transport.get()
def test_is_valid_balanceproof_signature(): balance_proof = factories.create(factories.BalanceProofSignedStateProperties()) valid = is_valid_balanceproof_signature(balance_proof, factories.make_address()) assert not valid, "Address does not match." balance_proof = factories.create( factories.BalanceProofSignedStateProperties(signature=b"\0" * 65) ) valid = is_valid_balanceproof_signature(balance_proof, factories.make_address()) assert not valid, f"Invalid signature check: {valid.as_error_message}"
def test_fee_round_trip(flat_fee, prop_fee, imbalance_fee, amount): """ Tests mediation fee deduction. """ balance = TokenAmount(100_000) prop_fee_per_channel = ppm_fee_per_channel(ProportionalFeeAmount(prop_fee)) imbalance_fee = calculate_imbalance_fees( channel_capacity=balance, proportional_imbalance_fee=ProportionalFeeAmount(imbalance_fee)) payer_channel = factories.create( NettingChannelStateProperties( our_state=NettingChannelEndStateProperties(balance=TokenAmount(0)), partner_state=NettingChannelEndStateProperties(balance=balance), fee_schedule=FeeScheduleState( flat=FeeAmount(flat_fee), proportional=prop_fee_per_channel, imbalance_penalty=imbalance_fee, ), )) payer_channel_backwards = factories.create( NettingChannelStateProperties( partner_state=NettingChannelEndStateProperties( balance=TokenAmount(0)), our_state=NettingChannelEndStateProperties(balance=balance), fee_schedule=FeeScheduleState( flat=FeeAmount(flat_fee), proportional=prop_fee_per_channel, imbalance_penalty=imbalance_fee, ), )) payee_channel = factories.create( NettingChannelStateProperties( our_state=NettingChannelEndStateProperties(balance=balance), partner_state=NettingChannelEndStateProperties( balance=TokenAmount(0)), fee_schedule=FeeScheduleState( flat=FeeAmount(flat_fee), proportional=prop_fee_per_channel, imbalance_penalty=imbalance_fee, ), )) fee_calculation = get_initial_payment_for_final_target_amount( final_amount=PaymentAmount(amount), channels=[payer_channel_backwards, payee_channel]) assert fee_calculation amount_after_fees = get_lock_amount_after_fees( lock=make_hash_time_lock_state(amount=fee_calculation.total_amount), payer_channel=payer_channel, payee_channel=payee_channel, ) assert amount_after_fees assert abs(amount - amount_after_fees) < 100
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 test_get_capacity(): our_state = factories.create( factories.NettingChannelEndStateProperties(balance=TokenAmount(100))) channel_state = factories.create( factories.NettingChannelStateProperties( our_state=our_state, partner_state=factories.NettingChannelEndStateProperties( balance=TokenAmount(50)), )) assert channel.get_capacity(channel_state) == 150 channel_state.our_state = replace(our_state, onchain_total_withdraw=50) assert channel.get_capacity(channel_state) == 100
def test_get_status(): failed_status = TransactionExecutionStatus( finished_block_number=10, result=TransactionExecutionStatus.FAILURE) close_failed = factories.create( factories.NettingChannelStateProperties( close_transaction=failed_status)) assert get_status(close_failed) == ChannelState.STATE_UNUSABLE settle_failed = factories.create( factories.NettingChannelStateProperties( settle_transaction=failed_status)) assert get_status(settle_failed) == ChannelState.STATE_UNUSABLE
def test_is_balance_proof_usable_onchain_answer_is_false(): channel_state = factories.make_channel_set( number_of_channels=1).channels[0] balance_proof_wrong_channel = factories.create( factories.BalanceProofSignedStateProperties()) is_valid_balance_proof = is_balance_proof_usable_onchain( received_balance_proof=balance_proof_wrong_channel, channel_state=channel_state, sender_state=channel_state.partner_state, ) assert is_valid_balance_proof.fail error_message = is_valid_balance_proof.as_error_message assert error_message.startswith( "channel_identifier does not match. "), error_message wrong_token_network_canonical_identifier = replace( channel_state.canonical_identifier, token_network_address=factories.make_address()) balance_proof_wrong_token_network = factories.create( factories.BalanceProofSignedStateProperties( canonical_identifier=wrong_token_network_canonical_identifier)) is_valid_balance_proof = is_balance_proof_usable_onchain( received_balance_proof=balance_proof_wrong_token_network, channel_state=channel_state, sender_state=channel_state.partner_state, ) assert is_valid_balance_proof.fail error_message = is_valid_balance_proof.as_error_message assert error_message.startswith( "token_network_address does not match. "), error_message balance_proof_overflow = factories.create( factories.BalanceProofSignedStateProperties( transferred_amount=factories.UINT256_MAX, locked_amount=1, canonical_identifier=channel_state.canonical_identifier, )) is_valid_balance_proof = is_balance_proof_usable_onchain( received_balance_proof=balance_proof_overflow, channel_state=channel_state, sender_state=channel_state.partner_state, ) assert is_valid_balance_proof.fail msg = is_valid_balance_proof.as_error_message assert msg.startswith( "Balance proof total transferred amount would overflow "), msg assert str(factories.UINT256_MAX) in msg, msg assert str(factories.UINT256_MAX + 1) in msg, msg
def test_balance_proof_invalid_attributes(): invalid_nonces = [-10, 0, UINT64_MAX + 1] invalid_transferred_amounts = [-1, UINT256_MAX + 1] invalid_locksroots = [urandom(31), urandom(33)] invalid_signatures = [urandom(64), urandom(66)] properties_unsigned = factories.BalanceProofProperties() properties_signed = factories.BalanceProofSignedStateProperties( signature=urandom(64)) for properties in (properties_unsigned, properties_signed): for nonce in invalid_nonces: with pytest.raises(ValueError): factories.create(factories.replace(properties, nonce=nonce)) for amount in invalid_transferred_amounts: with pytest.raises(ValueError): factories.create( factories.replace(properties, transferred_amount=amount)) for locksroot in invalid_locksroots: with pytest.raises(ValueError): factories.create( factories.replace(properties, locksroot=locksroot)) for signature in invalid_signatures: with pytest.raises(ValueError): factories.create( factories.replace(properties_signed, signature=signature))
def test_locked_transfer_additional_hash_contains_route_metadata_hash(): one_locked_transfer = factories.create( factories.LockedTransferProperties()) route_metadata = factories.create( factories.RouteMetadataProperties( route=[factories.HOP2, factories.HOP1])) another_locked_transfer = factories.create( factories.LockedTransferProperties(metadata=factories.create( factories.MetadataProperties(routes=[route_metadata])))) assert ( one_locked_transfer.message_hash != another_locked_transfer.message_hash ), "LockedTransfers with different routes should have different message hashes"
def test_update_pfs(): properties = factories.BalanceProofSignedStateProperties(pkey=PRIVKEY) balance_proof = factories.create(properties) channel_state = factories.create(factories.NettingChannelStateProperties()) channel_state.our_state.balance_proof = balance_proof channel_state.partner_state.balance_proof = balance_proof message = PFSCapacityUpdate.from_channel_state(channel_state=channel_state) assert message.signature == EMPTY_SIGNATURE privkey2, address2 = factories.make_privkey_address() signer2 = LocalSigner(privkey2) message.sign(signer2) assert recover(message._data_to_sign(), message.signature) == address2 assert message == DictSerializer.deserialize(DictSerializer.serialize(message))
def test_update_pfs(): properties = factories.BalanceProofSignedStateProperties(pkey=PRIVKEY) balance_proof = factories.create(properties) channel_state = factories.create(factories.NettingChannelStateProperties()) channel_state.our_state.balance_proof = balance_proof channel_state.partner_state.balance_proof = balance_proof message = UpdatePFS.from_channel_state(channel_state=channel_state) assert message.signature == b"" privkey2, address2 = factories.make_privkey_address() signer2 = LocalSigner(privkey2) message.sign(signer2) assert recover(message._data_to_sign(), message.signature) == address2 assert message == UpdatePFS.from_dict(message.to_dict())
def netting_channel_state(chain_state, token_network_state, token_network_registry_state, partner): if partner is None: partner = factories.make_address() canonical_identifier = factories.make_canonical_identifier( token_network_address=token_network_state.address) channel_state = factories.create( factories.NettingChannelStateProperties( our_state=factories.NettingChannelEndStateProperties( balance=TokenAmount(10), address=chain_state.our_address), partner_state=factories.NettingChannelEndStateProperties( balance=TokenAmount(10), address=partner), token_address=token_network_state.token_address, token_network_registry_address=token_network_registry_state. address, canonical_identifier=canonical_identifier, )) channel_id = canonical_identifier.channel_identifier token_network_state.partneraddresses_to_channelidentifiers[partner].append( channel_id) token_network_state.channelidentifiers_to_channels[ channel_id] = channel_state return channel_state
def make_signed_transfer_from_counter(counter): lock = Lock( amount=next(counter), expiration=next(counter), secrethash=factories.make_secret_hash(next(counter)), ) signed_transfer = factories.create( factories.LockedTransferSignedStateProperties( amount=next(counter), initiator=factories.make_initiator_address(), target=factories.make_target_address(), expiration=next(counter), secret=factories.make_secret(next(counter)), payment_identifier=next(counter), token=factories.make_token_address(), nonce=next(counter), transferred_amount=next(counter), locked_amount=next(counter), locksroot=sha3(lock.as_bytes), canonical_identifier=factories.make_canonical_identifier( token_network_address=factories.make_address(), channel_identifier=next(counter)), recipient=factories.make_address(), sender=factories.HOP1, pkey=factories.HOP1_KEY, )) return signed_transfer
def make_from_route_from_counter(counter): from_channel = factories.create( factories.NettingChannelStateProperties( canonical_identifier=factories.make_canonical_identifier(), token_address=factories.make_token_address(), partner_state=factories.NettingChannelEndStateProperties( balance=next(counter), address=factories.HOP1), )) from_hop = factories.make_hop_from_channel(from_channel) expiration = BlockExpiration(factories.UNIT_REVEAL_TIMEOUT + 1) from_transfer = factories.make_signed_transfer_for( from_channel, factories.LockedTransferSignedStateProperties( transferred_amount=TokenAmount(0), canonical_identifier=factories.make_canonical_identifier( token_network_address=from_channel.token_network_address), amount=TokenAmount(1), expiration=expiration, secret=sha3(factories.make_secret(next(counter))), initiator=factories.make_initiator_address(), target=factories.make_target_address(), payment_identifier=next(counter), sender=factories.HOP1, pkey=factories.HOP1_KEY, ), ) return from_hop, from_transfer
def _new_mediator_transfer( self, initiator_address, target_address, payment_id, amount, secret, our_address ) -> LockedTransferSignedState: initiator_pkey = self.address_to_privkey[initiator_address] balance_proof_data = self._update_balance_proof_data( initiator_address, amount, self.block_number + 10, secret, our_address ) self.secrethash_to_secret[sha256_secrethash(secret)] = secret return factories.create( factories.LockedTransferSignedStateProperties( **balance_proof_data.properties.__dict__, amount=amount, expiration=self.block_number + 10, payment_identifier=payment_id, secret=secret, initiator=initiator_address, target=target_address, token=self.token_id, sender=initiator_address, recipient=our_address, pkey=initiator_pkey, message_identifier=1, ) )
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_handle_block_closed_channel(): channel_state = factories.create( factories.NettingChannelStateProperties( close_transaction=TransactionExecutionStatus( finished_block_number=50, result=TransactionExecutionStatus.SUCCESS), settle_timeout=50, )) pseudo_random_generator = random.Random() block = Block(block_number=90, gas_limit=100000, block_hash=factories.make_block_hash()) before_settle = handle_block( channel_state=channel_state, state_change=block, block_number=block.block_number, pseudo_random_generator=pseudo_random_generator, ) assert get_status(before_settle.new_state) == ChannelState.STATE_CLOSED assert not before_settle.events block = Block(block_number=102, gas_limit=100000, block_hash=factories.make_block_hash()) after_settle = handle_block( channel_state=before_settle.new_state, state_change=block, block_number=block.block_number, pseudo_random_generator=pseudo_random_generator, ) assert get_status(after_settle.new_state) == ChannelState.STATE_SETTLING assert after_settle.events
def test_get_secret(): secret1 = factories.make_secret() secret2 = factories.make_secret() secrethash3 = factories.make_keccak_hash() secrethash4 = factories.make_keccak_hash() lock_state = HashTimeLockState(amount=10, expiration=10, secrethash=factories.UNIT_SECRETHASH) end_state = factories.create(factories.NettingChannelEndStateProperties()) end_state = factories.replace( end_state, secrethashes_to_lockedlocks={secrethash3: lock_state}, secrethashes_to_unlockedlocks={ sha3(secret1): UnlockPartialProofState(lock=lock_state, secret=secret1) }, secrethashes_to_onchain_unlockedlocks={ sha3(secret2): UnlockPartialProofState(lock=lock_state, secret=secret2) }, ) assert get_secret( end_state, sha3(secret1)) == secret1 # known secret from offchain unlock assert get_secret( end_state, sha3(secret2)) == secret2 # known secret from offchain unlock assert get_secret(end_state, secrethash3) is None # known lock but not unlocked yet assert get_secret(end_state, secrethash4) is None # unknown secrethash
def test_mediated_transfer_calls_pfs(raiden_network, token_addresses): app0, = raiden_network token_address = token_addresses[0] chain_state = views.state_from_app(app0) token_network_registry_address = app0.raiden.default_registry.address token_network_address = views.get_token_network_address_by_token_address( chain_state, token_network_registry_address, token_address) with patch("raiden.routing.query_paths", return_value=([], None)) as patched: app0.raiden.start_mediated_transfer_with_secret( token_network_address=token_network_address, amount=10, target=factories.HOP1, identifier=1, secret=b"1" * 32, ) assert not patched.called # Setup PFS config app0.raiden.config["pfs_config"] = PFSConfig( info=PFSInfo( url="mock-address", chain_id=app0.raiden.rpc_client.chain_id, token_network_registry_address=token_network_registry_address, payment_address=factories.make_address(), message="", operator="", version="", price=TokenAmount(0), ), maximum_fee=TokenAmount(100), iou_timeout=BlockNumber(100), max_paths=5, ) app0.raiden.start_mediated_transfer_with_secret( token_network_address=token_network_address, amount=11, target=factories.HOP2, identifier=2, secret=b"2" * 32, ) assert patched.call_count == 1 # Mediator should not re-query PFS locked_transfer = factories.create( factories.LockedTransferProperties( amount=TokenAmount(5), initiator=factories.HOP1, target=TargetAddress(factories.HOP2), sender=factories.HOP1, pkey=factories.HOP1_KEY, token=token_address, canonical_identifier=factories.make_canonical_identifier( token_network_address=token_network_address), )) app0.raiden.mediate_mediated_transfer(locked_transfer) assert patched.call_count == 1
def test_get_batch_unlock_gain(): channel_state = factories.create(factories.NettingChannelStateProperties()) channel_state.our_state = replace( channel_state.our_state, secrethashes_to_lockedlocks={ factories.make_keccak_hash(): make_hash_time_lock_state(1), factories.make_keccak_hash(): make_hash_time_lock_state(2), }, secrethashes_to_unlockedlocks={ factories.make_keccak_hash(): make_unlock_partial_proof_state(4) }, secrethashes_to_onchain_unlockedlocks={ factories.make_keccak_hash(): make_unlock_partial_proof_state(8) }, ) channel_state.partner_state = replace( channel_state.partner_state, secrethashes_to_lockedlocks={ factories.make_keccak_hash(): make_hash_time_lock_state(16) }, secrethashes_to_unlockedlocks={ factories.make_keccak_hash(): make_unlock_partial_proof_state(32) }, secrethashes_to_onchain_unlockedlocks={ factories.make_keccak_hash(): make_unlock_partial_proof_state(64), factories.make_keccak_hash(): make_unlock_partial_proof_state(128), }, ) unlock_gain = get_batch_unlock_gain(channel_state) assert unlock_gain.from_partner_locks == 192 assert unlock_gain.from_our_locks == 7
def test_fee_update(): channel_state = factories.create(factories.NettingChannelStateProperties()) message = PFSFeeUpdate.from_channel_state(channel_state) message.sign(signer) assert message == DictSerializer.deserialize( DictSerializer.serialize(message))
def test_channel_closed_must_clear_ordered_messages(chain_state, token_network_state, netting_channel_state): recipient = netting_channel_state.partner_state.address message_identifier = random.randint(0, 2**16) amount = 10 queue_identifier = QueueIdentifier( recipient=recipient, canonical_identifier=netting_channel_state.canonical_identifier) # Regression test: # The code delivered_message handler worked only with a queue of one # element message = factories.create( factories.LockedTransferProperties( message_identifier=message_identifier, token=token_network_state.token_address, canonical_identifier=netting_channel_state.canonical_identifier, transferred_amount=amount, recipient=recipient, )) chain_state.queueids_to_queues[queue_identifier] = [message] closed = state_change.ContractReceiveChannelClosed( transaction_hash=EMPTY_HASH, transaction_from=recipient, canonical_identifier=netting_channel_state.canonical_identifier, block_number=1, block_hash=factories.make_block_hash(), ) iteration = node.handle_state_change(chain_state, closed) assert queue_identifier not in iteration.new_state.queueids_to_queues
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 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( balance_proof=BalanceProofProperties( nonce=2, transferred_amount=from_transfer.balance_proof.transferred_amount, locked_amount=0, token_network_identifier=from_transfer.balance_proof.token_network_identifier, channel_identifier=channels[0].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 must_contain_entry(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 must_contain_entry(iteration.events, SendProcessed, {})
def test_state_transition(): """ Happy case testing. """ lock_amount = 7 block_number = 1 initiator = factories.HOP6 pseudo_random_generator = random.Random() channels = make_channel_set([channel_properties2]) from_transfer = make_target_transfer(channels[0], amount=lock_amount, initiator=initiator) 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 first_new_block = Block( block_number=block_number + 1, gas_limit=1, block_hash=factories.make_transaction_hash(), ) first_block_iteration = target.state_transition( target_state=init_transition.new_state, state_change=first_new_block, channel_state=channels[0], pseudo_random_generator=pseudo_random_generator, block_number=first_new_block.block_number, ) secret_reveal = ReceiveSecretReveal(factories.UNIT_SECRET, initiator) reveal_iteration = target.state_transition( target_state=first_block_iteration.new_state, state_change=secret_reveal, channel_state=channels[0], pseudo_random_generator=pseudo_random_generator, block_number=first_new_block.block_number, ) assert reveal_iteration.events second_new_block = Block( block_number=block_number + 2, gas_limit=1, block_hash=factories.make_transaction_hash(), ) iteration = target.state_transition( target_state=init_transition.new_state, state_change=second_new_block, channel_state=channels[0], pseudo_random_generator=pseudo_random_generator, block_number=second_new_block.block_number, ) assert not iteration.events balance_proof = create(BalanceProofSignedStateProperties( balance_proof=BalanceProofProperties( nonce=from_transfer.balance_proof.nonce + 1, transferred_amount=lock_amount, locked_amount=0, token_network_identifier=channels[0].token_network_identifier, channel_identifier=channels.get_route(0).channel_identifier, locksroot=EMPTY_MERKLE_ROOT, ), message_hash=b'\x00' * 32, # invalid )) balance_proof_state_change = ReceiveUnlock( message_identifier=random.randint(0, UINT64_MAX), secret=UNIT_SECRET, balance_proof=balance_proof, ) proof_iteration = target.state_transition( target_state=init_transition.new_state, state_change=balance_proof_state_change, channel_state=channels[0], pseudo_random_generator=pseudo_random_generator, block_number=block_number + 2, ) assert proof_iteration.new_state is None