def test_two_direct_transfers( settle_timeout, deposit, tester_chain, tester_channels, tester_token): """ The value of both transfers must be account for. """ pkey0, pkey1, nettingchannel, channel0, channel1 = tester_channels[0] address0 = privatekey_to_address(pkey0) address1 = privatekey_to_address(pkey1) initial0 = tester_token.balanceOf(address0, sender=pkey0) initial1 = tester_token.balanceOf(address1, sender=pkey0) first_amount0 = 90 block_number = tester_chain.block.number make_direct_transfer_from_channel( block_number, channel0, channel1, first_amount0, pkey0, ) second_amount0 = 90 block_number = tester_chain.block.number second_direct0 = make_direct_transfer_from_channel( block_number, channel0, channel1, second_amount0, pkey0, ) nettingchannel.close(sender=pkey0) second_direct0_hash = sha3(second_direct0.packed().data[:-65]) nettingchannel.updateTransfer( second_direct0.nonce, second_direct0.transferred_amount, second_direct0.locksroot, second_direct0_hash, second_direct0.signature, sender=pkey1, ) tester_chain.mine(number_of_blocks=settle_timeout + 1) nettingchannel.settle(sender=pkey0) balance0 = initial0 + deposit - first_amount0 - second_amount0 balance1 = initial1 + deposit + first_amount0 + second_amount0 assert tester_token.balanceOf(address0, sender=pkey0) == balance0 assert tester_token.balanceOf(address1, sender=pkey0) == balance1 assert tester_token.balanceOf(nettingchannel.address, sender=pkey0) == 0
def test_update_not_allowed_for_the_closing_address(tester_state, tester_channels): """ Closing address cannot call updateTransfer. """ pkey0, pkey1, nettingchannel, channel0, channel1 = tester_channels[0] block_number = tester_state.block.number transfer0 = make_direct_transfer_from_channel( block_number, channel0, channel1, amount=10, pkey=pkey0, ) block_number = tester_state.block.number transfer1 = make_direct_transfer_from_channel( block_number, channel1, channel0, amount=10, pkey=pkey1, ) nettingchannel.close(sender=pkey0) # do not accept a transfer from the party that closed transfer0_hash = sha3(transfer0.packed().data[:-65]) with pytest.raises(TransactionFailed): nettingchannel.updateTransfer( transfer0.nonce, transfer0.transferred_amount, transfer0.locksroot, transfer0_hash, transfer0.signature, sender=pkey0, ) # nor a transfer from the partner transfer1_hash = sha3(transfer1.packed().data[:-65]) with pytest.raises(TransactionFailed): nettingchannel.updateTransfer( transfer1.nonce, transfer1.transferred_amount, transfer1.locksroot, transfer1_hash, transfer1.signature, sender=pkey0, )
def test_update_called_multiple_times_same_transfer(tester_channels): """ updateTransfer can be called only once. """ pkey0, pkey1, nettingchannel, channel0, channel1 = tester_channels[0] payment_network_identifier = factories.make_address() transfer0 = make_direct_transfer_from_channel( payment_network_identifier, channel0, channel1, amount=10, pkey=pkey0, ) nettingchannel.close(sender=pkey0) transfer0_hash = sha3(transfer0.packed().data[:-65]) nettingchannel.updateTransfer( transfer0.nonce, transfer0.transferred_amount, transfer0.locksroot, transfer0_hash, transfer0.signature, sender=pkey1, ) with pytest.raises(TransactionFailed): nettingchannel.updateTransfer( transfer0.nonce, transfer0.transferred_amount, transfer0.locksroot, transfer0_hash, transfer0.signature, sender=pkey1, )
def test_settle_single_direct_transfer_for_counterparty( deposit, settle_timeout, tester_channels, tester_state, tester_token): """ Test settle of a channel with one direct transfer to the participant that did not call close. """ pkey0, pkey1, nettingchannel, channel0, channel1 = tester_channels[0] address0 = privatekey_to_address(pkey0) address1 = privatekey_to_address(pkey1) initial0 = tester_token.balanceOf(address0, sender=pkey0) initial1 = tester_token.balanceOf(address1, sender=pkey0) amount = 90 transfer0 = make_direct_transfer_from_channel(channel0, channel1, amount, pkey0) transfer0_data = str(transfer0.packed().data) nettingchannel.close('', sender=pkey0) nettingchannel.updateTransfer(transfer0_data, sender=pkey1) tester_state.mine(number_of_blocks=settle_timeout + 1) nettingchannel.settle(sender=pkey0) assert tester_token.balanceOf(address0, sender=pkey0) == initial0 + deposit - amount assert tester_token.balanceOf(address1, sender=pkey0) == initial1 + deposit + amount assert tester_token.balanceOf(nettingchannel.address, sender=pkey0) == 0
def test_update_called_multiple_times_same_transfer(tester_chain, tester_channels): """ updateTransfer can be called only once. """ pkey0, pkey1, nettingchannel, channel0, channel1 = tester_channels[0] block_number = tester_chain.block.number transfer0 = make_direct_transfer_from_channel( block_number, channel0, channel1, amount=10, pkey=pkey0, ) nettingchannel.close(sender=pkey0) transfer0_hash = sha3(transfer0.packed().data[:-65]) nettingchannel.updateTransfer( transfer0.nonce, transfer0.transferred_amount, transfer0.locksroot, transfer0_hash, transfer0.signature, sender=pkey1, ) with pytest.raises(TransactionFailed): nettingchannel.updateTransfer( transfer0.nonce, transfer0.transferred_amount, transfer0.locksroot, transfer0_hash, transfer0.signature, sender=pkey1, )
def test_close_tampered_identifier(tester_channels): """ Messages with a tampered identifier must be rejected. """ pkey0, pkey1, nettingchannel, channel0, channel1 = tester_channels[0] payment_network_identifier = factories.make_address() transfer0 = make_direct_transfer_from_channel( payment_network_identifier, channel0, channel1, amount=90, pkey=pkey0, ) transfer0_data = transfer0.encode() tampered_transfer = DirectTransfer.decode(transfer0_data) tampered_transfer.payment_identifier += 1 tampered_transfer_hash = sha3(tampered_transfer.encode()[:-65]) with pytest.raises(TransactionFailed): nettingchannel.close( tampered_transfer.nonce, tampered_transfer.transferred_amount, tampered_transfer.locksroot, tampered_transfer_hash, tampered_transfer.signature, sender=pkey1, )
def test_update_not_allowed_after_settlement_period(settle_timeout, tester_channels, tester_chain): """ updateTransfer cannot be called after the settlement period. """ pkey0, pkey1, nettingchannel, channel0, channel1 = tester_channels[0] block_number = tester_chain.block.number direct0 = make_direct_transfer_from_channel( block_number, channel0, channel1, amount=70, pkey=pkey0, ) nettingchannel.close(sender=pkey0) tester_chain.mine(number_of_blocks=settle_timeout + 1) direct0_hash = sha3(direct0.packed().data[:-65]) with pytest.raises(TransactionFailed): nettingchannel.updateTransfer( direct0.nonce, direct0.transferred_amount, direct0.locksroot, direct0_hash, direct0.signature, sender=pkey1, )
def test_transfer_update_event(tester_state, tester_channels, tester_events): """ The event TransferUpdated is emitted after a successful call to updateTransfer. """ pkey0, pkey1, nettingchannel, channel0, channel1 = tester_channels[0] address1 = privatekey_to_address(pkey1) block_number = tester_state.block.number direct0 = make_direct_transfer_from_channel( block_number, channel0, channel1, amount=90, pkey=pkey0, ) nettingchannel.close(sender=pkey0) previous_events = list(tester_events) direct0_hash = sha3(direct0.packed().data[:-65]) nettingchannel.updateTransfer( direct0.nonce, direct0.transferred_amount, direct0.locksroot, direct0_hash, direct0.signature, sender=pkey1, ) assert len(previous_events) + 1 == len(tester_events) assert tester_events[-1] == { '_event_type': 'TransferUpdated', 'node_address': address1.encode('hex'), }
def test_close_tampered_nonce(tester_channels): """ Messages with a tampered nonce must be rejected. """ pkey0, pkey1, nettingchannel, channel0, channel1 = tester_channels[0] transfer0 = make_direct_transfer_from_channel( channel0, channel1, amount=90, pkey=pkey0, ) transfer0_data = transfer0.encode() tampered_transfer = DirectTransfer.decode(transfer0_data) tampered_transfer.nonce += 1 tampered_transfer_hash = sha3(tampered_transfer.encode()[:-65]) with pytest.raises(TransactionFailed): nettingchannel.close( tampered_transfer.nonce, tampered_transfer.transferred_amount, tampered_transfer.locksroot, tampered_transfer_hash, tampered_transfer.signature, sender=pkey1, )
def test_update_called_multiple_times_same_transfer(tester_state, tester_channels): """ updateTransfer can be called only once. """ pkey0, pkey1, nettingchannel, channel0, channel1 = tester_channels[0] block_number = tester_state.block.number transfer0 = make_direct_transfer_from_channel( block_number, channel0, channel1, amount=10, pkey=pkey0, ) nettingchannel.close(sender=pkey0) transfer0_hash = sha3(transfer0.packed().data[:-65]) nettingchannel.updateTransfer( transfer0.nonce, transfer0.transferred_amount, transfer0.locksroot, transfer0_hash, transfer0.signature, sender=pkey1, ) with pytest.raises(TransactionFailed): nettingchannel.updateTransfer( transfer0.nonce, transfer0.transferred_amount, transfer0.locksroot, transfer0_hash, transfer0.signature, sender=pkey1, )
def test_update_not_allowed_after_settlement_period(settle_timeout, tester_channels, tester_state): """ updateTransfer cannot be called after the settlement period. """ pkey0, pkey1, nettingchannel, channel0, channel1 = tester_channels[0] block_number = tester_state.block.number direct0 = make_direct_transfer_from_channel( block_number, channel0, channel1, amount=70, pkey=pkey0, ) nettingchannel.close(sender=pkey0) tester_state.mine(number_of_blocks=settle_timeout + 1) direct0_hash = sha3(direct0.packed().data[:-65]) with pytest.raises(TransactionFailed): nettingchannel.updateTransfer( direct0.nonce, direct0.transferred_amount, direct0.locksroot, direct0_hash, direct0.signature, sender=pkey1, )
def test_close_tampered_nonce(tester_chain, tester_channels): """ Messages with a tampered nonce must be rejected. """ pkey0, pkey1, nettingchannel, channel0, channel1 = tester_channels[0] block_number = tester_chain.block.number transfer0 = make_direct_transfer_from_channel( block_number, channel0, channel1, amount=90, pkey=pkey0, ) transfer0_data = transfer0.encode() tampered_transfer = DirectTransfer.decode(transfer0_data) tampered_transfer.nonce += 1 tampered_transfer_hash = sha3(tampered_transfer.encode()[:-65]) with pytest.raises(TransactionFailed): nettingchannel.close( tampered_transfer.nonce, tampered_transfer.transferred_amount, tampered_transfer.locksroot, tampered_transfer_hash, tampered_transfer.signature, sender=pkey1, )
def test_transfer_update_event(tester_state, tester_channels, tester_events): """ The event TransferUpdated is emitted after a successful call to updateTransfer. """ pkey0, pkey1, nettingchannel, channel0, channel1 = tester_channels[0] address1 = privatekey_to_address(pkey1) block_number = tester_state.block.number direct0 = make_direct_transfer_from_channel( block_number, channel0, channel1, amount=90, pkey=pkey0, ) direct0_data = str(direct0.packed().data) nettingchannel.close('', sender=pkey0) previous_events = list(tester_events) nettingchannel.updateTransfer(direct0_data, sender=pkey1) assert len(previous_events) + 1 == len(tester_events) assert tester_events[-1] == { '_event_type': 'TransferUpdated', 'node_address': address1.encode('hex'), 'block_number': tester_state.block.number, }
def test_update_not_allowed_for_the_closing_address(tester_chain, tester_channels): """ Closing address cannot call updateTransfer. """ pkey0, pkey1, nettingchannel, channel0, channel1 = tester_channels[0] block_number = tester_chain.block.number transfer0 = make_direct_transfer_from_channel( block_number, channel0, channel1, amount=10, pkey=pkey0, ) block_number = tester_chain.block.number transfer1 = make_direct_transfer_from_channel( block_number, channel1, channel0, amount=10, pkey=pkey1, ) nettingchannel.close(sender=pkey0) # do not accept a transfer from the party that closed transfer0_hash = sha3(transfer0.packed().data[:-65]) with pytest.raises(TransactionFailed): nettingchannel.updateTransfer( transfer0.nonce, transfer0.transferred_amount, transfer0.locksroot, transfer0_hash, transfer0.signature, sender=pkey0, ) # nor a transfer from the partner transfer1_hash = sha3(transfer1.packed().data[:-65]) with pytest.raises(TransactionFailed): nettingchannel.updateTransfer( transfer1.nonce, transfer1.transferred_amount, transfer1.locksroot, transfer1_hash, transfer1.signature, sender=pkey0, )
def test_settle_two_direct_transfers(deposit, settle_timeout, tester_state, tester_channels, tester_token): """ Test settle of a channel with two direct transfers. """ pkey0, pkey1, nettingchannel, channel0, channel1 = tester_channels[0] address0 = privatekey_to_address(pkey0) address1 = privatekey_to_address(pkey1) initial_balance0 = tester_token.balanceOf(address0, sender=pkey0) initial_balance1 = tester_token.balanceOf(address1, sender=pkey0) amount0 = 10 block_number = tester_state.block.number transfer0 = make_direct_transfer_from_channel( block_number, channel0, channel1, amount0, pkey0, ) transfer0_data = str(transfer0.packed().data) amount1 = 30 block_number = tester_state.block.number transfer1 = make_direct_transfer_from_channel( block_number, channel1, channel0, amount1, pkey1, ) transfer1_data = str(transfer1.packed().data) nettingchannel.close(transfer1_data, sender=pkey0) nettingchannel.updateTransfer(transfer0_data, sender=pkey1) tester_state.mine(number_of_blocks=settle_timeout + 1) nettingchannel.settle(sender=pkey0) balance0 = tester_token.balanceOf(address0, sender=pkey0) balance1 = tester_token.balanceOf(address1, sender=pkey0) assert balance0 == initial_balance0 + deposit - amount0 + amount1 assert balance1 == initial_balance1 + deposit + amount0 - amount1 assert tester_token.balanceOf(nettingchannel.address, sender=pkey0) == 0
def test_update_called_multiple_times_new_transfer(tester_state, tester_channels): """ updateTransfer second call must fail even if there is a new transfer. """ pkey0, pkey1, nettingchannel, channel0, channel1 = tester_channels[0] block_number = tester_state.block.number transfer0 = make_direct_transfer_from_channel( block_number, channel0, channel1, amount=10, pkey=pkey0, ) block_number = tester_state.block.number transfer1 = make_direct_transfer_from_channel( block_number, channel0, channel1, amount=10, pkey=pkey0, ) nettingchannel.close(sender=pkey0) transfer0_hash = sha3(transfer0.packed().data[:-65]) nettingchannel.updateTransfer( transfer0.nonce, transfer0.transferred_amount, transfer0.locksroot, transfer0_hash, transfer0.signature, sender=pkey1, ) transfer1_hash = sha3(transfer1.packed().data[:-65]) with pytest.raises(TransactionFailed): nettingchannel.updateTransfer( transfer1.nonce, transfer1.transferred_amount, transfer1.locksroot, transfer1_hash, transfer1.signature, sender=pkey1, )
def test_close_first_argument_is_for_partner_transfer(tester_channels): """ Close must not accept a transfer from the closing address. """ pkey0, _, nettingchannel, channel0, channel1 = tester_channels[0] transfer0 = make_direct_transfer_from_channel(channel0, channel1, amount=90, pkey=pkey0) transfer0_data = str(transfer0.packed().data) with pytest.raises(TransactionFailed): nettingchannel.close(transfer0_data, sender=pkey0)
def test_two_direct_transfers(settle_timeout, deposit, tester_state, tester_channels, tester_token): """ The value of both transfers must be account for. """ pkey0, pkey1, nettingchannel, channel0, channel1 = tester_channels[0] address0 = privatekey_to_address(pkey0) address1 = privatekey_to_address(pkey1) initial0 = tester_token.balanceOf(address0, sender=pkey0) initial1 = tester_token.balanceOf(address1, sender=pkey0) first_amount0 = 90 block_number = tester_state.block.number make_direct_transfer_from_channel( block_number, channel0, channel1, first_amount0, pkey0, ) second_amount0 = 90 block_number = tester_state.block.number second_direct0 = make_direct_transfer_from_channel( block_number, channel0, channel1, second_amount0, pkey0, ) second_direct0_data = str(second_direct0.packed().data) nettingchannel.close('', sender=pkey0) nettingchannel.updateTransfer(second_direct0_data, sender=pkey1) tester_state.mine(number_of_blocks=settle_timeout + 1) nettingchannel.settle(sender=pkey0) balance0 = initial0 + deposit - first_amount0 - second_amount0 balance1 = initial1 + deposit + first_amount0 + second_amount0 assert tester_token.balanceOf(address0, sender=pkey0) == balance0 assert tester_token.balanceOf(address1, sender=pkey0) == balance1 assert tester_token.balanceOf(nettingchannel.address, sender=pkey0) == 0
def test_update_called_multiple_times_new_transfer(tester_chain, tester_channels): """ updateTransfer second call must fail even if there is a new transfer. """ pkey0, pkey1, nettingchannel, channel0, channel1 = tester_channels[0] block_number = tester_chain.block.number transfer0 = make_direct_transfer_from_channel( block_number, channel0, channel1, amount=10, pkey=pkey0, ) block_number = tester_chain.block.number transfer1 = make_direct_transfer_from_channel( block_number, channel0, channel1, amount=10, pkey=pkey0, ) nettingchannel.close(sender=pkey0) transfer0_hash = sha3(transfer0.packed().data[:-65]) nettingchannel.updateTransfer( transfer0.nonce, transfer0.transferred_amount, transfer0.locksroot, transfer0_hash, transfer0.signature, sender=pkey1, ) transfer1_hash = sha3(transfer1.packed().data[:-65]) with pytest.raises(TransactionFailed): nettingchannel.updateTransfer( transfer1.nonce, transfer1.transferred_amount, transfer1.locksroot, transfer1_hash, transfer1.signature, sender=pkey1, )
def test_update_called_multiple_times_older_transfer(tester_registry_address, tester_channels): """ updateTransfer second call must fail even if called with an older transfer. """ pkey0, pkey1, nettingchannel, channel0, channel1 = tester_channels[0] transfer0 = make_direct_transfer_from_channel( tester_registry_address, channel0, channel1, amount=10, pkey=pkey0, ) transfer1 = make_direct_transfer_from_channel( tester_registry_address, channel0, channel1, amount=10, pkey=pkey0, ) nettingchannel.close(sender=pkey0) transfer1_hash = sha3(transfer1.packed().data[:-65]) nettingchannel.updateTransfer( transfer1.nonce, transfer1.transferred_amount, transfer1.locksroot, transfer1_hash, transfer1.signature, sender=pkey1, ) transfer0_hash = sha3(transfer0.packed().data[:-65]) with pytest.raises(TransactionFailed): nettingchannel.updateTransfer( transfer0.nonce, transfer0.transferred_amount, transfer0.locksroot, transfer0_hash, transfer0.signature, sender=pkey1, )
def test_update_called_multiple_times_older_transfer(tester_channels): """ updateTransfer second call must fail even if called with an older transfer. """ pkey0, pkey1, nettingchannel, channel0, channel1 = tester_channels[0] transfer0 = make_direct_transfer_from_channel(channel0, channel1, amount=10, pkey=pkey0) transfer0_data = str(transfer0.packed().data) transfer1 = make_direct_transfer_from_channel(channel0, channel1, amount=10, pkey=pkey0) transfer1_data = str(transfer1.packed().data) nettingchannel.close('', sender=pkey0) nettingchannel.updateTransfer(transfer1_data, sender=pkey1) with pytest.raises(TransactionFailed): nettingchannel.updateTransfer(transfer0_data, sender=pkey1)
def test_update_fails_on_open_channel(tester_channels): """ Cannot call updateTransfer on a open channel. """ pkey0, _, nettingchannel, channel0, channel1 = tester_channels[0] transfer0 = make_direct_transfer_from_channel(channel0, channel1, amount=10, pkey=pkey0) transfer0_data = str(transfer0.packed().data) with pytest.raises(TransactionFailed): nettingchannel.updateTransfer(transfer0_data, sender=pkey0)
def test_settlement_with_unauthorized_token_transfer( deposit, settle_timeout, tester_state, tester_channels, tester_token): pkey0, pkey1, nettingchannel, channel0, channel1 = tester_channels[0] address0 = privatekey_to_address(pkey0) address1 = privatekey_to_address(pkey1) initial_balance0 = tester_token.balanceOf(address0, sender=pkey0) initial_balance1 = tester_token.balanceOf(address1, sender=pkey0) amount0 = 10 transfer0 = make_direct_transfer_from_channel(channel0, channel1, amount0, pkey0) transfer0_data = str(transfer0.packed().data) amount1 = 30 transfer1 = make_direct_transfer_from_channel(channel1, channel0, amount1, pkey1) transfer1_data = str(transfer1.packed().data) extra_amount = 10 assert tester_token.transfer(nettingchannel.address, extra_amount, sender=pkey0) nettingchannel.close(transfer1_data, sender=pkey0) nettingchannel.updateTransfer(transfer0_data, sender=pkey1) tester_state.mine(number_of_blocks=settle_timeout + 1) nettingchannel.settle(sender=pkey0) balance0 = tester_token.balanceOf(address0, sender=pkey0) balance1 = tester_token.balanceOf(address1, sender=pkey0) # Make sure that the extra amount is burned/locked in the netting channel assert balance0 == initial_balance0 + deposit - amount0 + amount1 - extra_amount assert balance1 == initial_balance1 + deposit + amount0 - amount1 assert tester_token.balanceOf(nettingchannel.address, sender=pkey1) == extra_amount
def test_netting(deposit, settle_timeout, tester_channels, tester_state, tester_token): """ Transferred amount can be larger than the deposit. """ pkey0, pkey1, nettingchannel, channel0, channel1 = tester_channels[0] address0 = privatekey_to_address(pkey0) address1 = privatekey_to_address(pkey1) initial_balance0 = tester_token.balanceOf(address0, sender=pkey0) initial_balance1 = tester_token.balanceOf(address1, sender=pkey1) transferred_amount0 = deposit * 3 + 30 increase_transferred_amount(channel0, channel1, transferred_amount0) transferred_amount1 = deposit * 3 + 70 increase_transferred_amount(channel1, channel0, transferred_amount1) amount0 = 10 transferred_amount0 += amount0 direct0 = make_direct_transfer_from_channel(channel0, channel1, amount0, pkey0) direct0_data = str(direct0.packed().data) amount1 = 30 transferred_amount1 += amount1 direct1 = make_direct_transfer_from_channel(channel1, channel0, amount1, pkey1) direct1_data = str(direct1.packed().data) nettingchannel.close(direct1_data, sender=pkey0) nettingchannel.updateTransfer(direct0_data, sender=pkey1) tester_state.mine(number_of_blocks=settle_timeout + 1) nettingchannel.settle(sender=pkey0) # the balances only change by transferred_amount because the lock was /not/ unlocked balance0 = initial_balance0 + deposit - transferred_amount0 + transferred_amount1 balance1 = initial_balance1 + deposit + transferred_amount0 - transferred_amount1 assert tester_token.balanceOf(nettingchannel.address, sender=pkey1) == 0 assert tester_token.balanceOf(address0, sender=pkey0) == balance0 assert tester_token.balanceOf(address1, sender=pkey1) == balance1
def test_close_tampered_nonce(tester_state, tester_channels): """ Messages with a tampered nonce must be rejected. """ pkey0, pkey1, nettingchannel, channel0, channel1 = tester_channels[0] transfer0 = make_direct_transfer_from_channel(channel0, channel1, amount=90, pkey=pkey0) transfer0_data = transfer0.encode() tampered_transfer = DirectTransfer.decode(transfer0_data) tampered_transfer.nonce += 1 tampered_transfer_data = tampered_transfer.encode() with pytest.raises(TransactionFailed): nettingchannel.close(tampered_transfer_data, sender=pkey1)
def test_update_called_multiple_times_same_transfer(tester_channels): """ updateTransfer can be called only once. """ pkey0, pkey1, nettingchannel, channel0, channel1 = tester_channels[0] transfer0 = make_direct_transfer_from_channel(channel0, channel1, amount=10, pkey=pkey0) transfer0_data = str(transfer0.packed().data) nettingchannel.close('', sender=pkey0) nettingchannel.updateTransfer(transfer0_data, sender=pkey1) with pytest.raises(TransactionFailed): nettingchannel.updateTransfer(transfer0_data, sender=pkey1)
def test_settle_single_direct_transfer_for_counterparty( deposit, settle_timeout, tester_channels, tester_chain, tester_token, ): """ Test settle of a channel with one direct transfer to the participant that did not call close. """ pkey0, pkey1, nettingchannel, channel0, channel1 = tester_channels[0] payment_network_identifier = factories.make_address() address0 = privatekey_to_address(pkey0) address1 = privatekey_to_address(pkey1) initial0 = tester_token.balanceOf(address0, sender=pkey0) initial1 = tester_token.balanceOf(address1, sender=pkey0) amount = 90 transfer0 = make_direct_transfer_from_channel( payment_network_identifier, channel0, channel1, amount, pkey0, ) transfer0_hash = sha3(transfer0.packed().data[:-65]) nettingchannel.close(sender=pkey0) nettingchannel.updateTransfer( transfer0.nonce, transfer0.transferred_amount, transfer0.locksroot, transfer0_hash, transfer0.signature, sender=pkey1, ) tester_chain.mine(number_of_blocks=settle_timeout + 1) nettingchannel.settle(sender=pkey0) assert tester_token.balanceOf(address0, sender=pkey0) == initial0 + deposit - amount assert tester_token.balanceOf(address1, sender=pkey0) == initial1 + deposit + amount assert tester_token.balanceOf(nettingchannel.address, sender=pkey0) == 0
def test_update_not_allowed_after_settlement_period(settle_timeout, tester_channels, tester_state): """ updateTransfer cannot be called after the settlement period. """ pkey0, pkey1, nettingchannel, channel0, channel1 = tester_channels[0] direct0 = make_direct_transfer_from_channel(channel0, channel1, amount=70, pkey=pkey0) direct0_data = str(direct0.packed().data) nettingchannel.close('', sender=pkey0) tester_state.mine(number_of_blocks=settle_timeout + 1) with pytest.raises(TransactionFailed): nettingchannel.updateTransfer(direct0_data, sender=pkey1)
def test_settle_single_direct_transfer_for_counterparty( deposit, settle_timeout, tester_channels, tester_chain, tester_token): """ Test settle of a channel with one direct transfer to the participant that did not call close. """ pkey0, pkey1, nettingchannel, channel0, channel1 = tester_channels[0] address0 = privatekey_to_address(pkey0) address1 = privatekey_to_address(pkey1) initial0 = tester_token.balanceOf(address0, sender=pkey0) initial1 = tester_token.balanceOf(address1, sender=pkey0) amount = 90 block_number = tester_chain.block.number transfer0 = make_direct_transfer_from_channel( block_number, channel0, channel1, amount, pkey0, ) transfer0_hash = sha3(transfer0.packed().data[:-65]) nettingchannel.close(sender=pkey0) nettingchannel.updateTransfer( transfer0.nonce, transfer0.transferred_amount, transfer0.locksroot, transfer0_hash, transfer0.signature, sender=pkey1, ) tester_chain.mine(number_of_blocks=settle_timeout + 1) nettingchannel.settle(sender=pkey0) assert tester_token.balanceOf(address0, sender=pkey0) == initial0 + deposit - amount assert tester_token.balanceOf(address1, sender=pkey0) == initial1 + deposit + amount assert tester_token.balanceOf(nettingchannel.address, sender=pkey0) == 0
def test_settle_single_direct_transfer_for_closing_party( deposit, settle_timeout, tester_channels, tester_state, tester_token): """ Test settle of a channel with one direct transfer to the participant that called close. """ pkey0, pkey1, nettingchannel, channel0, channel1 = tester_channels[0] address0 = privatekey_to_address(pkey0) address1 = privatekey_to_address(pkey1) initial0 = tester_token.balanceOf(address0, sender=pkey0) initial1 = tester_token.balanceOf(address1, sender=pkey0) amount = 90 block_number = tester_state.block.number transfer0 = make_direct_transfer_from_channel( block_number, channel0, channel1, amount, pkey0, ) transfer0_hash = sha3(transfer0.packed().data[:-65]) nettingchannel.close( transfer0.nonce, transfer0.transferred_amount, transfer0.locksroot, transfer0_hash, transfer0.signature, sender=pkey1, ) tester_state.mine(number_of_blocks=settle_timeout + 1) nettingchannel.settle(sender=pkey0) assert tester_token.balanceOf(address0, sender=pkey0) == initial0 + deposit - amount assert tester_token.balanceOf(address1, sender=pkey0) == initial1 + deposit + amount assert tester_token.balanceOf(nettingchannel.address, sender=pkey0) == 0
def test_close_tampered_identifier(tester_state, tester_channels): """ Messages with a tampered identifier must be rejected. """ pkey0, pkey1, nettingchannel, channel0, channel1 = tester_channels[0] block_number = tester_state.block.number transfer0 = make_direct_transfer_from_channel( block_number, channel0, channel1, amount=90, pkey=pkey0, ) transfer0_data = transfer0.encode() tampered_transfer = DirectTransfer.decode(transfer0_data) tampered_transfer.identifier += 1 tampered_transfer_data = tampered_transfer.encode() with pytest.raises(TransactionFailed): nettingchannel.close(tampered_transfer_data, sender=pkey1)
def test_update_fails_on_open_channel(tester_channels): """ Cannot call updateTransfer on a open channel. """ pkey0, _, nettingchannel, channel0, channel1 = tester_channels[0] transfer0 = make_direct_transfer_from_channel( channel0, channel1, amount=10, pkey=pkey0, ) transfer0_hash = sha3(transfer0.packed().data[:-65]) with pytest.raises(TransactionFailed): nettingchannel.updateTransfer( transfer0.nonce, transfer0.transferred_amount, transfer0.locksroot, transfer0_hash, transfer0.signature, sender=pkey0, )
def test_close_first_argument_is_for_partner_transfer(tester_channels): """ Close must not accept a transfer from the closing address. """ pkey0, _, nettingchannel, channel0, channel1 = tester_channels[0] transfer0 = make_direct_transfer_from_channel( channel0, channel1, amount=90, pkey=pkey0, ) transfer0_hash = sha3(transfer0.packed().data[:-65]) with pytest.raises(TransactionFailed): nettingchannel.close( transfer0.nonce, transfer0.transferred_amount, transfer0.locksroot, transfer0_hash, transfer0.signature, sender=pkey0, )
def test_update_fails_on_open_channel(tester_chain, tester_channels): """ Cannot call updateTransfer on a open channel. """ pkey0, _, nettingchannel, channel0, channel1 = tester_channels[0] block_number = tester_chain.block.number transfer0 = make_direct_transfer_from_channel( block_number, channel0, channel1, amount=10, pkey=pkey0, ) transfer0_hash = sha3(transfer0.packed().data[:-65]) with pytest.raises(TransactionFailed): nettingchannel.updateTransfer( transfer0.nonce, transfer0.transferred_amount, transfer0.locksroot, transfer0_hash, transfer0.signature, sender=pkey0, )
def test_close_first_argument_is_for_partner_transfer(tester_chain, tester_channels): """ Close must not accept a transfer from the closing address. """ pkey0, _, nettingchannel, channel0, channel1 = tester_channels[0] block_number = tester_chain.block.number transfer0 = make_direct_transfer_from_channel( block_number, channel0, channel1, amount=90, pkey=pkey0, ) transfer0_hash = sha3(transfer0.packed().data[:-65]) with pytest.raises(TransactionFailed): nettingchannel.close( transfer0.nonce, transfer0.transferred_amount, transfer0.locksroot, transfer0_hash, transfer0.signature, sender=pkey0, )
def test_transfer_update_event(tester_chain, tester_channels, tester_events): """ The event TransferUpdated is emitted after a successful call to updateTransfer. """ pkey0, pkey1, nettingchannel, channel0, channel1 = tester_channels[0] address1 = privatekey_to_address(pkey1) block_number = tester_chain.block.number direct0 = make_direct_transfer_from_channel( block_number, channel0, channel1, amount=90, pkey=pkey0, ) nettingchannel.close(sender=pkey0) previous_events = list(tester_events) direct0_hash = sha3(direct0.packed().data[:-65]) nettingchannel.updateTransfer( direct0.nonce, direct0.transferred_amount, direct0.locksroot, direct0_hash, direct0.signature, sender=pkey1, ) assert len(previous_events) + 1 == len(tester_events) last_event = event_decoder(tester_events[-1], nettingchannel.translator) assert last_event == { '_event_type': b'TransferUpdated', 'node_address': address_encoder(address1), }
def test_transfer_update_event(tester_channels, tester_events): """ The event TransferUpdated is emitted after a successful call to updateTransfer. """ pkey0, pkey1, nettingchannel, channel0, channel1 = tester_channels[0] address1 = privatekey_to_address(pkey1) payment_network_identifier = factories.make_address() direct0 = make_direct_transfer_from_channel( payment_network_identifier, channel0, channel1, amount=90, pkey=pkey0, ) nettingchannel.close(sender=pkey0) previous_events = list(tester_events) direct0_hash = sha3(direct0.packed().data[:-65]) nettingchannel.updateTransfer( direct0.nonce, direct0.transferred_amount, direct0.locksroot, direct0_hash, direct0.signature, sender=pkey1, ) assert len(previous_events) + 1 == len(tester_events) last_event = event_decoder(tester_events[-1], nettingchannel.translator) assert last_event == { '_event_type': b'TransferUpdated', 'node_address': address_encoder(address1), }
def test_mediated_after_direct_transfer( reveal_timeout, settle_timeout, deposit, tester_chain, tester_channels, tester_token, ): """ The transfer types must not change the behavior of the dispute. """ pkey0, pkey1, nettingchannel, channel0, channel1 = tester_channels[0] payment_network_identifier = factories.make_address() pseudo_random_generator = random.Random() address0 = privatekey_to_address(pkey0) address1 = privatekey_to_address(pkey1) initial_balance0 = tester_token.balanceOf(address0, sender=pkey0) initial_balance1 = tester_token.balanceOf(address1, sender=pkey0) first_amount0 = 90 make_direct_transfer_from_channel( payment_network_identifier, channel0, channel1, first_amount0, pkey0, ) lock_expiration = tester_chain.block.number + reveal_timeout + 5 new_block = Block(tester_chain.block.number) channel.state_transition( channel0, new_block, pseudo_random_generator, new_block.block_number, ) channel.state_transition( channel1, new_block, pseudo_random_generator, new_block.block_number, ) lock1 = Lock(amount=31, expiration=lock_expiration, secrethash=sha3(b'lock2')) second_mediated0 = make_mediated_transfer( payment_network_identifier, channel0, channel1, address0, address1, lock1, pkey0, ) nettingchannel.close(sender=pkey0) second_mediated0_hash = sha3(second_mediated0.packed().data[:-65]) nettingchannel.updateTransfer( second_mediated0.nonce, second_mediated0.transferred_amount, second_mediated0.locksroot, second_mediated0_hash, second_mediated0.signature, sender=pkey1, ) tester_chain.mine(number_of_blocks=settle_timeout + 1) nettingchannel.settle(sender=pkey0) # the balances only change by transferred_amount because the lock was /not/ unlocked balance0 = initial_balance0 + deposit - first_amount0 balance1 = initial_balance1 + deposit + first_amount0 assert tester_token.balanceOf(nettingchannel.address, sender=pkey1) == 0 assert tester_token.balanceOf(address0, sender=pkey0) == balance0 assert tester_token.balanceOf(address1, sender=pkey1) == balance1
def test_netting(deposit, settle_timeout, tester_channels, tester_chain, tester_token): """ Transferred amount can be larger than the deposit. """ pkey0, pkey1, nettingchannel, channel0, channel1 = tester_channels[0] address0 = privatekey_to_address(pkey0) address1 = privatekey_to_address(pkey1) initial_balance0 = tester_token.balanceOf(address0, sender=pkey0) initial_balance1 = tester_token.balanceOf(address1, sender=pkey1) # increase the transferred amount by three times the deposits for _ in range(3): increase_transferred_amount(channel0, channel1, deposit) increase_transferred_amount(channel1, channel0, deposit) transferred_amount0 = deposit * 3 transferred_amount1 = deposit * 3 amount0 = 10 transferred_amount0 += amount0 block_number = tester_chain.block.number direct0 = make_direct_transfer_from_channel( block_number, channel0, channel1, amount0, pkey0, ) amount1 = 30 transferred_amount1 += amount1 block_number = tester_chain.block.number direct1 = make_direct_transfer_from_channel( block_number, channel1, channel0, amount1, pkey1, ) direct1_hash = sha3(direct1.packed().data[:-65]) nettingchannel.close( direct1.nonce, direct1.transferred_amount, direct1.locksroot, direct1_hash, direct1.signature, sender=pkey0, ) direct0_hash = sha3(direct0.packed().data[:-65]) nettingchannel.updateTransfer( direct0.nonce, direct0.transferred_amount, direct0.locksroot, direct0_hash, direct0.signature, sender=pkey1, ) tester_chain.mine(number_of_blocks=settle_timeout + 1) nettingchannel.settle(sender=pkey0) # the balances only change by transferred_amount because the lock was /not/ unlocked balance0 = initial_balance0 + deposit - transferred_amount0 + transferred_amount1 balance1 = initial_balance1 + deposit + transferred_amount0 - transferred_amount1 assert tester_token.balanceOf(nettingchannel.address, sender=pkey1) == 0 assert tester_token.balanceOf(address0, sender=pkey0) == balance0 assert tester_token.balanceOf(address1, sender=pkey1) == balance1
def test_settle_two_direct_transfers( deposit, settle_timeout, tester_chain, tester_channels, tester_token): """ Test settle of a channel with two direct transfers. """ pkey0, pkey1, nettingchannel, channel0, channel1 = tester_channels[0] address0 = privatekey_to_address(pkey0) address1 = privatekey_to_address(pkey1) initial_balance0 = tester_token.balanceOf(address0, sender=pkey0) initial_balance1 = tester_token.balanceOf(address1, sender=pkey0) amount0 = 10 block_number = tester_chain.block.number transfer0 = make_direct_transfer_from_channel( block_number, channel0, channel1, amount0, pkey0, ) amount1 = 30 block_number = tester_chain.block.number transfer1 = make_direct_transfer_from_channel( block_number, channel1, channel0, amount1, pkey1, ) transfer1_hash = sha3(transfer1.packed().data[:-65]) nettingchannel.close( transfer1.nonce, transfer1.transferred_amount, transfer1.locksroot, transfer1_hash, transfer1.signature, sender=pkey0, ) transfer0_hash = sha3(transfer0.packed().data[:-65]) nettingchannel.updateTransfer( transfer0.nonce, transfer0.transferred_amount, transfer0.locksroot, transfer0_hash, transfer0.signature, sender=pkey1, ) tester_chain.mine(number_of_blocks=settle_timeout + 1) nettingchannel.settle(sender=pkey0) balance0 = tester_token.balanceOf(address0, sender=pkey0) balance1 = tester_token.balanceOf(address1, sender=pkey0) assert balance0 == initial_balance0 + deposit - amount0 + amount1 assert balance1 == initial_balance1 + deposit + amount0 - amount1 assert tester_token.balanceOf(nettingchannel.address, sender=pkey0) == 0
def test_settlement_with_unauthorized_token_transfer( deposit, settle_timeout, tester_chain, tester_channels, tester_token, ): pkey0, pkey1, nettingchannel, channel0, channel1 = tester_channels[0] payment_network_identifier = factories.make_address() address0 = privatekey_to_address(pkey0) address1 = privatekey_to_address(pkey1) initial_balance0 = tester_token.balanceOf(address0, sender=pkey0) initial_balance1 = tester_token.balanceOf(address1, sender=pkey0) amount0 = 10 transfer0 = make_direct_transfer_from_channel( payment_network_identifier, channel0, channel1, amount0, pkey0, ) amount1 = 30 transfer1 = make_direct_transfer_from_channel( payment_network_identifier, channel1, channel0, amount1, pkey1, ) extra_amount = 10 assert tester_token.transfer(nettingchannel.address, extra_amount, sender=pkey0) transfer1_hash = sha3(transfer1.packed().data[:-65]) nettingchannel.close( transfer1.nonce, transfer1.transferred_amount, transfer1.locksroot, transfer1_hash, transfer1.signature, sender=pkey0, ) transfer0_hash = sha3(transfer0.packed().data[:-65]) nettingchannel.updateTransfer( transfer0.nonce, transfer0.transferred_amount, transfer0.locksroot, transfer0_hash, transfer0.signature, sender=pkey1, ) tester_chain.mine(number_of_blocks=settle_timeout + 1) nettingchannel.settle(sender=pkey0) balance0 = tester_token.balanceOf(address0, sender=pkey0) balance1 = tester_token.balanceOf(address1, sender=pkey0) # Make sure that the extra amount is burned/locked in the netting channel assert balance0 == initial_balance0 + deposit - amount0 + amount1 - extra_amount assert balance1 == initial_balance1 + deposit + amount0 - amount1 assert tester_token.balanceOf(nettingchannel.address, sender=pkey1) == extra_amount
def test_mediated_after_direct_transfer( reveal_timeout, settle_timeout, deposit, tester_chain, tester_channels, tester_token): """ The transfer types must not change the behavior of the dispute. """ pkey0, pkey1, nettingchannel, channel0, channel1 = tester_channels[0] address0 = privatekey_to_address(pkey0) address1 = privatekey_to_address(pkey1) initial_balance0 = tester_token.balanceOf(address0, sender=pkey0) initial_balance1 = tester_token.balanceOf(address1, sender=pkey0) first_amount0 = 90 block_number = tester_chain.block.number make_direct_transfer_from_channel( block_number, channel0, channel1, first_amount0, pkey0, ) lock_expiration = tester_chain.block.number + reveal_timeout + 5 new_block = Block(tester_chain.block.number) channel0.state_transition(new_block) channel1.state_transition(new_block) lock1 = Lock(amount=31, expiration=lock_expiration, hashlock=sha3(b'lock2')) second_mediated0 = make_mediated_transfer( channel0, channel1, address0, address1, lock1, pkey0, tester_chain.block.number, ) nettingchannel.close(sender=pkey0) second_mediated0_hash = sha3(second_mediated0.packed().data[:-65]) nettingchannel.updateTransfer( second_mediated0.nonce, second_mediated0.transferred_amount, second_mediated0.locksroot, second_mediated0_hash, second_mediated0.signature, sender=pkey1, ) tester_chain.mine(number_of_blocks=settle_timeout + 1) nettingchannel.settle(sender=pkey0) # the balances only change by transferred_amount because the lock was /not/ unlocked balance0 = initial_balance0 + deposit - first_amount0 balance1 = initial_balance1 + deposit + first_amount0 assert tester_token.balanceOf(nettingchannel.address, sender=pkey1) == 0 assert tester_token.balanceOf(address0, sender=pkey0) == balance0 assert tester_token.balanceOf(address1, sender=pkey1) == balance1
def test_netting(deposit, settle_timeout, tester_channels, tester_chain, tester_token): """ Transferred amount can be larger than the deposit. """ pkey0, pkey1, nettingchannel, channel0, channel1 = tester_channels[0] payment_network_identifier = factories.make_address() address0 = privatekey_to_address(pkey0) address1 = privatekey_to_address(pkey1) initial_balance0 = tester_token.balanceOf(address0, sender=pkey0) initial_balance1 = tester_token.balanceOf(address1, sender=pkey1) # increase the transferred amount by three times the deposits for _ in range(3): increase_transferred_amount( payment_network_identifier, channel0, channel1, deposit, pkey0, ) increase_transferred_amount( payment_network_identifier, channel1, channel0, deposit, pkey1, ) transferred_amount0 = deposit * 3 transferred_amount1 = deposit * 3 amount0 = 10 transferred_amount0 += amount0 direct0 = make_direct_transfer_from_channel( payment_network_identifier, channel0, channel1, amount0, pkey0, ) amount1 = 30 transferred_amount1 += amount1 direct1 = make_direct_transfer_from_channel( payment_network_identifier, channel1, channel0, amount1, pkey1, ) direct1_hash = sha3(direct1.packed().data[:-65]) nettingchannel.close( direct1.nonce, direct1.transferred_amount, direct1.locksroot, direct1_hash, direct1.signature, sender=pkey0, ) direct0_hash = sha3(direct0.packed().data[:-65]) nettingchannel.updateTransfer( direct0.nonce, direct0.transferred_amount, direct0.locksroot, direct0_hash, direct0.signature, sender=pkey1, ) tester_chain.mine(number_of_blocks=settle_timeout + 1) nettingchannel.settle(sender=pkey0) # the balances only change by transferred_amount because the lock was /not/ unlocked balance0 = initial_balance0 + deposit - transferred_amount0 + transferred_amount1 balance1 = initial_balance1 + deposit + transferred_amount0 - transferred_amount1 assert tester_token.balanceOf(nettingchannel.address, sender=pkey1) == 0 assert tester_token.balanceOf(address0, sender=pkey0) == balance0 assert tester_token.balanceOf(address1, sender=pkey1) == balance1
def test_settlement_with_unauthorized_token_transfer( deposit, settle_timeout, tester_chain, tester_channels, tester_token): pkey0, pkey1, nettingchannel, channel0, channel1 = tester_channels[0] address0 = privatekey_to_address(pkey0) address1 = privatekey_to_address(pkey1) initial_balance0 = tester_token.balanceOf(address0, sender=pkey0) initial_balance1 = tester_token.balanceOf(address1, sender=pkey0) amount0 = 10 block_number = tester_chain.block.number transfer0 = make_direct_transfer_from_channel( block_number, channel0, channel1, amount0, pkey0, ) amount1 = 30 block_number = tester_chain.block.number transfer1 = make_direct_transfer_from_channel( block_number, channel1, channel0, amount1, pkey1, ) extra_amount = 10 assert tester_token.transfer(nettingchannel.address, extra_amount, sender=pkey0) transfer1_hash = sha3(transfer1.packed().data[:-65]) nettingchannel.close( transfer1.nonce, transfer1.transferred_amount, transfer1.locksroot, transfer1_hash, transfer1.signature, sender=pkey0, ) transfer0_hash = sha3(transfer0.packed().data[:-65]) nettingchannel.updateTransfer( transfer0.nonce, transfer0.transferred_amount, transfer0.locksroot, transfer0_hash, transfer0.signature, sender=pkey1, ) tester_chain.mine(number_of_blocks=settle_timeout + 1) nettingchannel.settle(sender=pkey0) balance0 = tester_token.balanceOf(address0, sender=pkey0) balance1 = tester_token.balanceOf(address1, sender=pkey0) # Make sure that the extra amount is burned/locked in the netting channel assert balance0 == initial_balance0 + deposit - amount0 + amount1 - extra_amount assert balance1 == initial_balance1 + deposit + amount0 - amount1 assert tester_token.balanceOf(nettingchannel.address, sender=pkey1) == extra_amount