def test_channel_must_accept_expired_locks(): """ A node may go offline for an undetermined period of time, and when it comes back online it must accept the messages that are waiting, otherwise the partner node won't make progress with its queue. If a N node goes offline for a number B of blocks, and the partner does not close the channel, when N comes back online some of the messages from its partner may become expired. Neverthless these messages are ordered and must be accepted for the partner to make progress with its queue. Note: Accepting a message with an expired lock does *not* imply the token transfer happened, and the receiver node must *not* forward the transfer, only accept the message allowing the partner to progress with its message queue. """ balance1 = 70 balance2 = 110 reveal_timeout = 5 settle_timeout = 15 privkey1, address1 = make_privkey_address() privkey2, address2 = make_privkey_address() token_address = make_address() our_state = ChannelEndState( address1, balance1, None, EMPTY_MERKLE_TREE, ) partner_state = ChannelEndState( address2, balance2, None, EMPTY_MERKLE_TREE, ) external_state = make_external_state() test_channel = Channel( our_state, partner_state, external_state, token_address, reveal_timeout, settle_timeout, ) block_number = 10 transfer = make_mediated_transfer( nonce=test_channel.get_next_nonce(), token=test_channel.token_address, channel=test_channel.channel_address, expiration=block_number + settle_timeout, recipient=address1, ) transfer.sign(privkey2, address2) test_channel.register_transfer( block_number + settle_timeout + 1, transfer, )
def test_decode_mediated_transfer( amount, identifier, nonce, transferred_amount, locksroot, fee, tester_state, tester_nettingchannel_library_address): privatekey0 = tester.DEFAULT_KEY address0 = privatekey_to_address(privatekey0) decoder = deploy_decoder_tester(tester_state, tester_nettingchannel_library_address) mediated_transfer = make_mediated_transfer( amount=amount, identifier=identifier, nonce=nonce, fee=fee, transferred_amount=transferred_amount, locksroot=locksroot, ) mediated_transfer.sign(PrivateKey(privatekey0), address0) assert_decoder_results(mediated_transfer, decoder)
def test_decode_tampered_mediated_transfer(tester_state, tester_nettingchannel_library_address): privatekey0 = tester.DEFAULT_KEY address0 = privatekey_to_address(privatekey0) decoder = deploy_decoder_tester(tester_state, tester_nettingchannel_library_address) mediated_transfer = make_mediated_transfer() mediated_transfer.sign(PrivateKey(privatekey0), address0) message_encoded = mediated_transfer.encode() transfer_raw, _ = decoder.getTransferRawAddress(message_encoded) names_slices = compute_slices(messages.MediatedTransfer.fields_spec) for name, slice_ in names_slices.iteritems(): if name == 'signature': continue tampered_transfer = bytearray(transfer_raw) tampered_transfer.pop(slice_.start) tampered_transfer = str(tampered_transfer) with pytest.raises(TransactionFailed): decoder.decodeTransfer(tampered_transfer) tampered_transfer = bytearray(transfer_raw) tampered_transfer.pop(slice_.stop - 1) tampered_transfer = str(tampered_transfer) with pytest.raises(TransactionFailed): decoder.decodeTransfer(tampered_transfer)
def test_mediated_transfer_min_max(amount, payment_identifier, fee, nonce, transferred_amount): mediated_transfer = make_mediated_transfer( amount=amount, payment_identifier=payment_identifier, nonce=nonce, fee=fee, transferred_amount=transferred_amount, ) mediated_transfer.sign(signer) assert LockedTransfer.from_dict(mediated_transfer.to_dict()) == mediated_transfer
def test_mediated_transfer_min_max(amount, identifier, fee, nonce, transferred_amount): mediated_transfer = make_mediated_transfer( amount=amount, identifier=identifier, nonce=nonce, fee=fee, transferred_amount=transferred_amount, ) mediated_transfer.sign(PRIVKEY, ADDRESS) assert decode(mediated_transfer.encode()) == mediated_transfer
def test_mediated_transfer_min_max(amount, payment_identifier, fee, nonce, transferred_amount): mediated_transfer = make_mediated_transfer( amount=amount, payment_identifier=payment_identifier, nonce=nonce, fee=fee, transferred_amount=transferred_amount, ) mediated_transfer.sign(PRIVKEY) assert LockedTransfer.from_dict(mediated_transfer.to_dict()) == mediated_transfer
def test_mediated_transfer_min_max(amount, payment_identifier, fee, nonce, transferred_amount): mediated_transfer = make_mediated_transfer( amount=amount, payment_identifier=payment_identifier, nonce=nonce, fee=fee, transferred_amount=transferred_amount, ) mediated_transfer.sign(PRIVKEY) assert mediated_transfer.sender == ADDRESS assert decode(mediated_transfer.encode()) == mediated_transfer
def test_mediated_transfer_min_max(amount, payment_identifier, fee, nonce, transferred_amount): mediated_transfer = make_mediated_transfer( amount=amount, payment_identifier=payment_identifier, nonce=nonce, fee=fee, transferred_amount=transferred_amount, ) mediated_transfer.sign(PRIVKEY, UNIT_CHAIN_ID) assert mediated_transfer.sender == ADDRESS assert decode(mediated_transfer.encode()) == mediated_transfer
def test_mediated_transfer_min_max(amount, identifier, fee, nonce, transferred_amount): mediated_transfer = make_mediated_transfer( amount=amount, identifier=identifier, nonce=nonce, fee=fee, transferred_amount=transferred_amount, ) mediated_transfer.sign(PRIVKEY, ADDRESS) assert LockedTransfer.from_dict( mediated_transfer.to_dict()) == mediated_transfer
def test_channel_closed_must_clear_ordered_messages( chain_id, chain_state, payment_network_state, token_network_state, netting_channel_state, ): recipient = netting_channel_state.partner_state.address channel_identifier = netting_channel_state.identifier message_identifier = random.randint(0, 2 ** 16) amount = 10 queue_identifier = QueueIdentifier( recipient, channel_identifier, ) # Regression test: # The code delivered_message handler worked only with a queue of one # element message = make_mediated_transfer( message_identifier=message_identifier, token=token_network_state.token_address, channel_identifier=channel_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, token_network_identifier=token_network_state.address, channel_identifier=channel_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_channel_closed_must_clear_ordered_messages( chain_id, chain_state, payment_network_state, token_network_state, netting_channel_state, ): recipient = netting_channel_state.partner_state.address channel_identifier = netting_channel_state.identifier message_identifier = random.randint(0, 2 ** 16) amount = 10 queue_identifier = QueueIdentifier( recipient, channel_identifier, ) # Regression test: # The code delivered_message handler worked only with a queue of one # element message = make_mediated_transfer( message_identifier=message_identifier, token=token_network_state.token_address, channel_identifier=channel_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, token_network_identifier=token_network_state.address, channel_identifier=channel_identifier, block_number=1, ) iteration = node.handle_state_change( chain_state, closed, ) assert queue_identifier not in iteration.new_state.queueids_to_queues
def test_mediated_transfer_out_of_bounds_values(): for args in MEDIATED_TRANSFER_INVALID_VALUES: with pytest.raises(ValueError): make_mediated_transfer(**args)
def test_mediated_transfer_out_of_bounds_values(args): with pytest.raises(ValueError): make_mediated_transfer(**args)