def test_send_refund_transfer_contains_balance_proof(): recipient = make_address() transfer = make_transfer() message_identifier = 1 channel_identifier = make_channel_identifier() event = SendRefundTransfer( recipient=recipient, channel_identifier=channel_identifier, message_identifier=message_identifier, transfer=transfer, ) assert hasattr(event, 'balance_proof') assert SendRefundTransfer.from_dict(event.to_dict()) == event
def test_send_refund_transfer_contains_balance_proof(): recipient = factories.make_address() transfer = factories.create(factories.LockedTransferUnsignedStateProperties()) message_identifier = 1 channel_identifier = factories.make_channel_identifier() event = SendRefundTransfer( recipient=recipient, channel_identifier=channel_identifier, message_identifier=message_identifier, transfer=transfer, ) assert hasattr(event, "balance_proof") assert SendRefundTransfer.from_dict(event.to_dict()) == event
def test_send_refund_transfer_contains_balance_proof(): recipient = factories.make_address() transfer = factories.create(factories.LockedTransferUnsignedStateProperties()) message_identifier = 1 event = SendRefundTransfer( recipient=recipient, message_identifier=message_identifier, transfer=transfer, canonical_identifier=factories.make_canonical_identifier(), ) assert hasattr(event, "balance_proof") assert JSONSerializer.deserialize(JSONSerializer.serialize(event)) == event
def events_for_refund_transfer(refund_route, refund_transfer, timeout_blocks, block_number): """ Refund the transfer. Args: refund_route (RouteState): The original route that sent the mediated transfer to this node. refund_transfer (LockedTransferState): The original mediated transfer from the refund_route. timeout_blocks (int): The number of blocks available from the /latest transfer/ received by this node, this transfer might be the original mediated transfer (if no route was available) or a refund transfer from a down stream node. block_number (int): The current block number. Returns: An empty list if there are not enough blocks to safely create a refund, or a list with a refund event. """ # A refund transfer works like a special SendMediatedTransfer, so it must # follow the same rules and decrement reveal_timeout from the # payee_transfer. new_lock_timeout = timeout_blocks - refund_route.reveal_timeout if new_lock_timeout > 0: new_lock_expiration = new_lock_timeout + block_number refund_transfer = SendRefundTransfer( refund_transfer.identifier, refund_transfer.token, refund_transfer.amount, refund_transfer.hashlock, refund_transfer.initiator, refund_transfer.target, new_lock_expiration, refund_route.node_address, ) return [refund_transfer] # Can not create a refund lock with a safe expiration, so don't do anything # and wait for the received lock to expire. return list()
def test_get_event_with_balance_proof(): """ All events which contain a balance proof must be found by when querying the database. """ serializer = JSONSerializer storage = SQLiteStorage(':memory:', serializer) counter = itertools.count() lock_expired = SendLockExpired( recipient=factories.make_address(), message_identifier=next(counter), balance_proof=make_balance_proof_from_counter(counter), secrethash=sha3(factories.make_secret(next(counter))), ) locked_transfer = SendLockedTransfer( recipient=factories.make_address(), channel_identifier=factories.make_channel_identifier(), message_identifier=next(counter), transfer=make_transfer_from_counter(counter), ) balance_proof = SendBalanceProof( recipient=factories.make_address(), channel_identifier=factories.make_channel_identifier(), message_identifier=next(counter), payment_identifier=next(counter), token_address=factories.make_address(), secret=factories.make_secret(next(counter)), balance_proof=make_balance_proof_from_counter(counter), ) refund_transfer = SendRefundTransfer( recipient=factories.make_address(), channel_identifier=factories.make_channel_identifier(), message_identifier=next(counter), transfer=make_transfer_from_counter(counter), ) events_balanceproofs = [ (lock_expired, lock_expired.balance_proof), (locked_transfer, locked_transfer.balance_proof), (balance_proof, balance_proof.balance_proof), (refund_transfer, refund_transfer.transfer.balance_proof), ] timestamp = datetime.utcnow().isoformat(timespec='milliseconds') state_change = '' for event, _ in events_balanceproofs: state_change_identifier = storage.write_state_change( state_change, timestamp, ) storage.write_events( state_change_identifier=state_change_identifier, events=[event], log_time=timestamp, ) for event, balance_proof in events_balanceproofs: event_record = get_event_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, balance_hash=balance_proof.balance_hash, ) assert event_record.data == event
def test_get_event_with_balance_proof(): """ All events which contain a balance proof must be found by when querying the database. """ serializer = JSONSerializer() storage = SerializedSQLiteStorage(":memory:", serializer) counter = itertools.count(1) partner_address = factories.make_address() balance_proof = make_balance_proof_from_counter(counter) lock_expired = SendLockExpired( recipient=partner_address, message_identifier=MessageID(next(counter)), balance_proof=balance_proof, secrethash=factories.make_secret_hash(next(counter)), canonical_identifier=balance_proof.canonical_identifier, ) locked_transfer = SendLockedTransfer( recipient=partner_address, message_identifier=MessageID(next(counter)), transfer=make_transfer_from_counter(counter), canonical_identifier=factories.make_canonical_identifier(), ) send_balance_proof = SendBalanceProof( recipient=partner_address, message_identifier=MessageID(next(counter)), payment_identifier=factories.make_payment_id(), token_address=factories.make_token_address(), secret=factories.make_secret(next(counter)), balance_proof=make_balance_proof_from_counter(counter), canonical_identifier=factories.make_canonical_identifier(), ) refund_transfer = SendRefundTransfer( recipient=partner_address, message_identifier=MessageID(next(counter)), transfer=make_transfer_from_counter(counter), canonical_identifier=factories.make_canonical_identifier(), ) events_balanceproofs = [ (lock_expired, lock_expired.balance_proof), (locked_transfer, locked_transfer.balance_proof), (send_balance_proof, send_balance_proof.balance_proof), (refund_transfer, refund_transfer.transfer.balance_proof), ] state_change = Block(BlockNumber(1), BlockGasLimit(1), factories.make_block_hash()) for event, _ in events_balanceproofs: state_change_identifiers = storage.write_state_changes([state_change]) storage.write_events(events=[(state_change_identifiers[0], event)]) for event, balance_proof in events_balanceproofs: event_record = get_event_with_balance_proof_by_balance_hash( storage=storage, canonical_identifier=balance_proof.canonical_identifier, balance_hash=balance_proof.balance_hash, recipient=partner_address, ) assert event_record assert event_record.data == event event_record = get_event_with_balance_proof_by_locksroot( storage=storage, canonical_identifier=balance_proof.canonical_identifier, recipient=event.recipient, locksroot=balance_proof.locksroot, ) assert event_record assert event_record.data == event # Checking that balance proof attribute can be accessed for all events. # Issue https://github.com/raiden-network/raiden/issues/3179 assert event_record.data.balance_proof == event.balance_proof storage.close()
def test_pfs_global_messages( matrix_transports, monkeypatch, ): """ Test that `update_pfs` from `RaidenEventHandler` sends balance proof updates to the global PATH_FINDING_BROADCASTING_ROOM room on Send($BalanceProof)* events, i.e. events, that send a new balance proof to the channel partner. """ transport = matrix_transports[0] transport._client.api.retry_timeout = 0 transport._send_raw = MagicMock() raiden_service = MockRaidenService(None) 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() # create mock events that should trigger a send lock = make_lock() hash_time_lock = HashTimeLockState(lock.amount, lock.expiration, lock.secrethash) def make_unsigned_balance_proof(nonce): return BalanceProofUnsignedState.from_dict( make_balance_proof(nonce=nonce, signer=LocalSigner(HOP1_KEY), amount=1).to_dict(), ) transfer1 = LockedTransferUnsignedState( balance_proof=make_unsigned_balance_proof(nonce=1), payment_identifier=1, token=b'1', lock=hash_time_lock, target=HOP1, initiator=HOP1, ) transfer2 = LockedTransferUnsignedState( balance_proof=make_unsigned_balance_proof(nonce=2), payment_identifier=1, token=b'1', lock=hash_time_lock, target=HOP1, initiator=HOP1, ) send_balance_proof_events = [ SendLockedTransfer(HOP1, 1, 1, transfer1), SendRefundTransfer(HOP1, 1, 1, transfer2), SendBalanceProof(HOP1, 1, 1, 1, b'1', b'x' * 32, make_unsigned_balance_proof(nonce=3)), SendLockExpired(HOP1, 1, make_unsigned_balance_proof(nonce=4), b'x' * 32), ] for num, event in enumerate(send_balance_proof_events): assert event.balance_proof.nonce == num + 1 # make sure we cover all configured event types assert all(event in [type(event) for event in send_balance_proof_events] for event in SEND_BALANCE_PROOF_EVENTS) event_handler = raiden_event_handler.RaidenEventHandler() # let our mock objects pass validation channelstate_mock = Mock() channelstate_mock.reveal_timeout = 1 monkeypatch.setattr( raiden_event_handler, 'get_channelstate_by_token_network_and_partner', lambda *args, **kwargs: channelstate_mock, ) monkeypatch.setattr(raiden_event_handler, 'state_from_raiden', lambda *args, **kwargs: 1) monkeypatch.setattr(event_handler, 'handle_send_lockedtransfer', lambda *args, **kwargs: 1) monkeypatch.setattr(event_handler, 'handle_send_refundtransfer', lambda *args, **kwargs: 1) # handle the events for event in send_balance_proof_events: event_handler.on_raiden_event( raiden_service, event, ) gevent.idle() # ensure all events triggered a send for their respective balance_proof # matrix transport may concatenate multiple messages send in one interval assert pfs_room.send_text.call_count >= 1 concatenated_call_args = ' '.join( str(arg) for arg in pfs_room.send_text.call_args_list) assert all(f'"nonce": {i + 1}' in concatenated_call_args for i in range(len(SEND_BALANCE_PROOF_EVENTS))) transport.stop() transport.get()
def test_get_event_with_balance_proof(): """ All events which contain a balance proof must be found by when querying the database. """ serializer = JSONSerializer storage = SerializedSQLiteStorage(":memory:", serializer) counter = itertools.count() lock_expired = SendLockExpired( recipient=factories.make_address(), message_identifier=next(counter), balance_proof=make_balance_proof_from_counter(counter), secrethash=sha3(factories.make_secret(next(counter))), ) locked_transfer = SendLockedTransfer( recipient=factories.make_address(), channel_identifier=factories.make_channel_identifier(), message_identifier=next(counter), transfer=make_transfer_from_counter(counter), ) balance_proof = SendBalanceProof( recipient=factories.make_address(), channel_identifier=factories.make_channel_identifier(), message_identifier=next(counter), payment_identifier=next(counter), token_address=factories.make_address(), secret=factories.make_secret(next(counter)), balance_proof=make_balance_proof_from_counter(counter), ) refund_transfer = SendRefundTransfer( recipient=factories.make_address(), channel_identifier=factories.make_channel_identifier(), message_identifier=next(counter), transfer=make_transfer_from_counter(counter), ) events_balanceproofs = [ (lock_expired, lock_expired.balance_proof), (locked_transfer, locked_transfer.balance_proof), (balance_proof, balance_proof.balance_proof), (refund_transfer, refund_transfer.transfer.balance_proof), ] timestamp = datetime.utcnow().isoformat(timespec="milliseconds") state_change = "" for event, _ in events_balanceproofs: state_change_identifier = storage.write_state_change( state_change, timestamp) storage.write_events(state_change_identifier=state_change_identifier, events=[event], log_time=timestamp) for event, balance_proof in events_balanceproofs: event_record = get_event_with_balance_proof_by_balance_hash( storage=storage, canonical_identifier=balance_proof.canonical_identifier, balance_hash=balance_proof.balance_hash, ) assert event_record.data == event # Checking that balance proof attribute can be accessed for all events. # Issue https://github.com/raiden-network/raiden/issues/3179 assert event_record.data.balance_proof == event.balance_proof