def test_token_network_proxy(token_network_proxy, private_keys, token_proxy, chain_id, web3, contract_manager): assert token_network_proxy.settlement_timeout_min( ) == TEST_SETTLE_TIMEOUT_MIN assert token_network_proxy.settlement_timeout_max( ) == TEST_SETTLE_TIMEOUT_MAX token_network_address = to_canonical_address( token_network_proxy.proxy.contract.address) c1_signer = LocalSigner(private_keys[1]) c1_client = JSONRPCClient(web3, private_keys[1]) c1_chain = BlockChainService(jsonrpc_client=c1_client, contract_manager=contract_manager) c2_client = JSONRPCClient(web3, private_keys[2]) c1_token_network_proxy = TokenNetwork( jsonrpc_client=c1_client, token_network_address=token_network_address, contract_manager=contract_manager, ) c2_token_network_proxy = TokenNetwork( jsonrpc_client=c2_client, token_network_address=token_network_address, contract_manager=contract_manager, ) initial_token_balance = 100 token_proxy.transfer(c1_client.address, initial_token_balance) token_proxy.transfer(c2_client.address, initial_token_balance) initial_balance_c1 = token_proxy.balance_of(c1_client.address) assert initial_balance_c1 == initial_token_balance initial_balance_c2 = token_proxy.balance_of(c2_client.address) assert initial_balance_c2 == initial_token_balance # instantiating a new channel - test basic assumptions assert (c1_token_network_proxy._channel_exists_and_not_settled( participant1=c1_client.address, participant2=c2_client.address, block_identifier="latest", ) is False) channel_identifier = c1_token_network_proxy._call_and_check_result( "latest", "getChannelIdentifier", to_checksum_address(c1_client.address), to_checksum_address(c2_client.address), ) assert channel_identifier == 0 msg = "Zero is not a valid channel_identifier identifier, ValueError must be " "raised." with pytest.raises(ValueError, message=msg): assert c1_token_network_proxy.channel_is_opened( participant1=c1_client.address, participant2=c2_client.address, block_identifier="latest", channel_identifier=0, ) msg = "Zero is not a valid channel_identifier identifier. ValueError must be " "raised." with pytest.raises(ValueError, message=msg): assert c1_token_network_proxy.channel_is_closed( participant1=c1_client.address, participant2=c2_client.address, block_identifier="latest", channel_identifier=0, ) msg = ("Opening a channel with a settle_timeout lower then token " "network's minimum will fail. This must be validated and the " "transaction must not be sent.") with pytest.raises(InvalidSettleTimeout, message=msg): c1_token_network_proxy.new_netting_channel( partner=c2_client.address, settle_timeout=TEST_SETTLE_TIMEOUT_MIN - 1, given_block_identifier="latest", ) msg = ("Opening a channel with a settle_timeout larger then token " "network's maximum will fail. This must be validated and the " "transaction must not be sent.") with pytest.raises(InvalidSettleTimeout, message=msg): c1_token_network_proxy.new_netting_channel( partner=c2_client.address, settle_timeout=TEST_SETTLE_TIMEOUT_MAX + 1, given_block_identifier="latest", ) msg = ( "Opening a channel with itself is not allow. This must be validated and " "the transaction must not be sent.") with pytest.raises(SamePeerAddress, message=msg): c1_token_network_proxy.new_netting_channel( partner=c1_client.address, settle_timeout=TEST_SETTLE_TIMEOUT_MIN, given_block_identifier="latest", ) msg = "Trying a deposit to an inexisting channel must fail." with pytest.raises(RaidenUnrecoverableError, message=msg, match="does not exist"): c1_token_network_proxy.set_total_deposit( given_block_identifier="latest", channel_identifier=1, total_deposit=1, partner=c2_client.address, ) msg = "Trying to close an inexisting channel must fail." match = "The channel was not open at the provided block" with pytest.raises(RaidenUnrecoverableError, message=msg, match=match): c1_token_network_proxy.close( channel_identifier=1, partner=c2_client.address, balance_hash=EMPTY_HASH, nonce=0, additional_hash=EMPTY_HASH, signature=EMPTY_SIGNATURE, given_block_identifier="latest", ) channel_identifier = c1_token_network_proxy.new_netting_channel( partner=c2_client.address, settle_timeout=TEST_SETTLE_TIMEOUT_MIN, given_block_identifier="latest", ) msg = "new_netting_channel did not return a valid channel id" assert isinstance(channel_identifier, T_ChannelID), msg msg = "multiple channels with the same peer are not allowed" with pytest.raises(DuplicatedChannelError, message=msg): c1_token_network_proxy.new_netting_channel( partner=c2_client.address, settle_timeout=TEST_SETTLE_TIMEOUT_MIN, given_block_identifier="latest", ) assert (c1_token_network_proxy._channel_exists_and_not_settled( participant1=c1_client.address, participant2=c2_client.address, channel_identifier=channel_identifier, block_identifier="latest", ) is True) assert (c1_token_network_proxy.channel_is_opened( participant1=c1_client.address, participant2=c2_client.address, block_identifier="latest", channel_identifier=channel_identifier, ) is True) msg = "set_total_deposit must fail if the amount exceed the account's balance" with pytest.raises(DepositMismatch, message=msg): c1_token_network_proxy.set_total_deposit( given_block_identifier="latest", channel_identifier=channel_identifier, total_deposit=initial_token_balance + 1, partner=c2_client.address, ) msg = "set_total_deposit must fail with a negative amount" with pytest.raises(DepositMismatch): c1_token_network_proxy.set_total_deposit( given_block_identifier="latest", channel_identifier=channel_identifier, total_deposit=-1, partner=c2_client.address, ) msg = "set_total_deposit must fail with a zero amount" with pytest.raises(DepositMismatch): c1_token_network_proxy.set_total_deposit( given_block_identifier="latest", channel_identifier=channel_identifier, total_deposit=0, partner=c2_client.address, ) c1_token_network_proxy.set_total_deposit( given_block_identifier="latest", channel_identifier=channel_identifier, total_deposit=10, partner=c2_client.address, ) transferred_amount = 3 balance_proof = BalanceProof( channel_identifier=channel_identifier, token_network_address=to_checksum_address(token_network_address), nonce=1, chain_id=chain_id, transferred_amount=transferred_amount, ) signature = c1_signer.sign(data=balance_proof.serialize_bin()) balance_proof.signature = encode_hex(signature) signature_number = int.from_bytes(signature, "big") bit_to_change = random.randint(0, SIGNATURE_SIZE_IN_BITS - 1) signature_number_bit_flipped = signature_number ^ (2**bit_to_change) invalid_signatures = [ EMPTY_SIGNATURE, b"\x11" * 65, signature_number_bit_flipped.to_bytes(len(signature), "big"), ] msg = "close must fail if the signature is invalid" for invalid_signature in invalid_signatures: with pytest.raises(RaidenUnrecoverableError, message=msg): c2_token_network_proxy.close( channel_identifier=channel_identifier, partner=c1_client.address, balance_hash=decode_hex(balance_proof.balance_hash), nonce=balance_proof.nonce, additional_hash=decode_hex(balance_proof.additional_hash), signature=invalid_signature, given_block_identifier="latest", ) blocknumber_prior_to_close = c2_client.block_number() c2_token_network_proxy.close( channel_identifier=channel_identifier, partner=c1_client.address, balance_hash=decode_hex(balance_proof.balance_hash), nonce=balance_proof.nonce, additional_hash=decode_hex(balance_proof.additional_hash), signature=decode_hex(balance_proof.signature), given_block_identifier="latest", ) assert (c1_token_network_proxy.channel_is_closed( participant1=c1_client.address, participant2=c2_client.address, block_identifier="latest", channel_identifier=channel_identifier, ) is True) assert (c1_token_network_proxy._channel_exists_and_not_settled( participant1=c1_client.address, participant2=c2_client.address, channel_identifier=channel_identifier, block_identifier="latest", ) is True) msg = ( "given_block_identifier is the block at which the transaction is being " "sent. If the channel is already closed at that block the client code " "has a programming error. An exception is raised for that.") with pytest.raises(RaidenUnrecoverableError, message=msg): c2_token_network_proxy.close( channel_identifier=channel_identifier, partner=c1_client.address, balance_hash=decode_hex(balance_proof.balance_hash), nonce=balance_proof.nonce, additional_hash=decode_hex(balance_proof.additional_hash), signature=decode_hex(balance_proof.signature), given_block_identifier="latest", ) msg = ("The channel cannot be closed two times. If it was not closed at " "given_block_identifier but it is closed at the time the proxy is " "called an exception must be raised.") with pytest.raises(RaidenRecoverableError, message=msg): c2_token_network_proxy.close( channel_identifier=channel_identifier, partner=c1_client.address, balance_hash=decode_hex(balance_proof.balance_hash), nonce=balance_proof.nonce, additional_hash=decode_hex(balance_proof.additional_hash), signature=decode_hex(balance_proof.signature), given_block_identifier=blocknumber_prior_to_close, ) msg = "depositing to a closed channel must fail" match = "setTotalDeposit call will fail. Channel is already closed" with pytest.raises(RaidenRecoverableError, message=msg, match=match): c2_token_network_proxy.set_total_deposit( given_block_identifier=blocknumber_prior_to_close, channel_identifier=channel_identifier, total_deposit=20, partner=c1_client.address, ) c1_chain.wait_until_block(target_block_number=c1_chain.block_number() + TEST_SETTLE_TIMEOUT_MIN) invalid_transferred_amount = 1 msg = "settle with invalid transferred_amount data must fail" with pytest.raises(RaidenUnrecoverableError, message=msg): c2_token_network_proxy.settle( channel_identifier=channel_identifier, transferred_amount=invalid_transferred_amount, locked_amount=0, locksroot=EMPTY_HASH, partner=c1_client.address, partner_transferred_amount=transferred_amount, partner_locked_amount=0, partner_locksroot=EMPTY_HASH, given_block_identifier="latest", ) c2_token_network_proxy.settle( channel_identifier=channel_identifier, transferred_amount=0, locked_amount=0, locksroot=EMPTY_HASH, partner=c1_client.address, partner_transferred_amount=transferred_amount, partner_locked_amount=0, partner_locksroot=EMPTY_HASH, given_block_identifier="latest", ) assert (c1_token_network_proxy._channel_exists_and_not_settled( participant1=c1_client.address, participant2=c2_client.address, channel_identifier=channel_identifier, block_identifier="latest", ) is False) assert token_proxy.balance_of(c1_client.address) == (initial_balance_c1 - transferred_amount) assert token_proxy.balance_of(c2_client.address) == (initial_balance_c2 + transferred_amount) msg = "depositing to a settled channel must fail" match = "setTotalDeposit call will fail." with pytest.raises(RaidenUnrecoverableError, message=msg, match=match): c1_token_network_proxy.set_total_deposit( given_block_identifier="latest", channel_identifier=channel_identifier, total_deposit=10, partner=c2_client.address, )
def run_test_node_can_settle_if_close_didnt_use_any_balance_proof( raiden_network, number_of_nodes, token_addresses, network_wait, ): app0, app1 = raiden_network token_address = token_addresses[0] chain_state = views.state_from_app(app0) payment_network_id = app0.raiden.default_registry.address registry_address = app0.raiden.default_registry.address token_network_identifier = views.get_token_network_identifier_by_token_address( chain_state=chain_state, payment_network_id=payment_network_id, token_address=token_address, ) channel_identifier = get_channelstate(app0, app1, token_network_identifier).identifier # make a transfer from app0 to app1 so that app1 is supposed to have a non # empty balance hash transfer( initiator_app=app0, target_app=app1, token_address=token_address, amount=1, identifier=1, timeout=network_wait * number_of_nodes, ) # stop app1 - the test uses token_network_contract now app1.stop() token_network_contract = TokenNetwork( jsonrpc_client=app1.raiden.chain.client, token_network_address=token_network_identifier, contract_manager=app1.raiden.contract_manager, ) # app1 closes the channel with an empty hash instead of the expected hash # of the transferred amount from app0 token_network_contract.close( channel_identifier=channel_identifier, partner=app0.raiden.address, balance_hash=EMPTY_HASH, nonce=0, additional_hash=EMPTY_HASH, signature=EMPTY_SIGNATURE, given_block_identifier='latest', ) waiting.wait_for_settle( raiden=app0.raiden, payment_network_id=registry_address, token_address=token_address, channel_ids=[channel_identifier], retry_timeout=app0.raiden.alarm.sleep_time, ) state_changes = app0.raiden.wal.storage.get_statechanges_by_identifier( from_identifier=0, to_identifier='latest', ) assert search_for_item( state_changes, ContractReceiveChannelSettled, { 'token_network_identifier': token_network_identifier, 'channel_identifier': channel_identifier, }, )
def test_token_network_actions_at_pruned_blocks(token_network_proxy, private_keys, token_proxy, web3, chain_id, contract_manager): token_network_address = to_canonical_address( token_network_proxy.proxy.contract.address) c1_client = JSONRPCClient(web3, private_keys[1]) c1_token_network_proxy = TokenNetwork( jsonrpc_client=c1_client, token_network_address=token_network_address, contract_manager=contract_manager, ) c1_chain = BlockChainService(jsonrpc_client=c1_client, contract_manager=contract_manager) c2_client = JSONRPCClient(web3, private_keys[2]) c3_client = JSONRPCClient(web3, private_keys[0]) c2_token_network_proxy = TokenNetwork( jsonrpc_client=c2_client, token_network_address=token_network_address, contract_manager=contract_manager, ) initial_token_balance = 100 token_proxy.transfer(c1_client.address, initial_token_balance) token_proxy.transfer(c2_client.address, initial_token_balance) initial_balance_c1 = token_proxy.balance_of(c1_client.address) assert initial_balance_c1 == initial_token_balance initial_balance_c2 = token_proxy.balance_of(c2_client.address) assert initial_balance_c2 == initial_token_balance # create a channel settle_timeout = STATE_PRUNING_AFTER_BLOCKS + 10 channel_identifier = c1_token_network_proxy.new_netting_channel( partner=c2_client.address, settle_timeout=settle_timeout, given_block_identifier="latest") # Now wait until this block becomes pruned pruned_number = c1_chain.block_number() c1_chain.wait_until_block(target_block_number=pruned_number + STATE_PRUNING_AFTER_BLOCKS) # create a channel with given block being pruned, should always throw with pytest.raises(NoStateForBlockIdentifier): channel_identifier = c1_token_network_proxy.new_netting_channel( partner=c3_client.address, settle_timeout=10, given_block_identifier=pruned_number) # deposit with given block being pruned c1_token_network_proxy.set_total_deposit( given_block_identifier=pruned_number, channel_identifier=channel_identifier, total_deposit=2, partner=c2_client.address, ) # balance proof signed by c1 transferred_amount_c1 = 1 balance_proof_c1 = BalanceProof( channel_identifier=channel_identifier, token_network_address=to_checksum_address(token_network_address), nonce=1, chain_id=chain_id, transferred_amount=transferred_amount_c1, ) balance_proof_c1.signature = encode_hex( LocalSigner( private_keys[1]).sign(data=balance_proof_c1.serialize_bin())) non_closing_data = balance_proof_c1.serialize_bin( msg_type=MessageTypeId.BALANCE_PROOF_UPDATE) + decode_hex( balance_proof_c1.signature) non_closing_signature = LocalSigner( c2_client.privkey).sign(data=non_closing_data) # close channel with given block being pruned c1_token_network_proxy.close( channel_identifier=channel_identifier, partner=c2_client.address, balance_hash=EMPTY_HASH, nonce=0, additional_hash=EMPTY_HASH, signature=EMPTY_SIGNATURE, given_block_identifier=pruned_number, ) close_pruned_number = c1_chain.block_number() assert (c1_token_network_proxy.channel_is_closed( participant1=c1_client.address, participant2=c2_client.address, block_identifier="latest", channel_identifier=channel_identifier, ) is True) assert (c1_token_network_proxy._channel_exists_and_not_settled( participant1=c1_client.address, participant2=c2_client.address, channel_identifier=channel_identifier, block_identifier="latest", ) is True) c1_chain.wait_until_block(target_block_number=close_pruned_number + STATE_PRUNING_AFTER_BLOCKS) # update transfer with given block being pruned c2_token_network_proxy.update_transfer( channel_identifier=channel_identifier, partner=c1_client.address, balance_hash=decode_hex(balance_proof_c1.balance_hash), nonce=balance_proof_c1.nonce, additional_hash=decode_hex(balance_proof_c1.additional_hash), closing_signature=decode_hex(balance_proof_c1.signature), non_closing_signature=non_closing_signature, given_block_identifier=close_pruned_number, ) # update transfer c1_chain.wait_until_block(target_block_number=c1_chain.block_number() + settle_timeout) # settle with given block being pruned c1_token_network_proxy.settle( channel_identifier=channel_identifier, transferred_amount=transferred_amount_c1, locked_amount=0, locksroot=EMPTY_HASH, partner=c2_client.address, partner_transferred_amount=0, partner_locked_amount=0, partner_locksroot=EMPTY_HASH, given_block_identifier=close_pruned_number, ) assert token_proxy.balance_of( c2_client.address) == (initial_balance_c2 + transferred_amount_c1 - 0) assert token_proxy.balance_of( c1_client.address) == (initial_balance_c1 + 0 - transferred_amount_c1)
def test_token_network_proxy_update_transfer(token_network_proxy, private_keys, token_proxy, chain_id, web3, contract_manager): """Tests channel lifecycle, with `update_transfer` before settling""" token_network_address = to_canonical_address( token_network_proxy.proxy.contract.address) c1_client = JSONRPCClient(web3, private_keys[1]) c1_chain = BlockChainService(jsonrpc_client=c1_client, contract_manager=contract_manager) c2_client = JSONRPCClient(web3, private_keys[2]) c1_token_network_proxy = TokenNetwork( jsonrpc_client=c1_client, token_network_address=token_network_address, contract_manager=contract_manager, ) c2_token_network_proxy = TokenNetwork( jsonrpc_client=c2_client, token_network_address=token_network_address, contract_manager=contract_manager, ) # create a channel channel_identifier = c1_token_network_proxy.new_netting_channel( partner=c2_client.address, settle_timeout=10, given_block_identifier="latest") # deposit to the channel initial_balance = 100 token_proxy.transfer(c1_client.address, initial_balance) token_proxy.transfer(c2_client.address, initial_balance) initial_balance_c1 = token_proxy.balance_of(c1_client.address) assert initial_balance_c1 == initial_balance initial_balance_c2 = token_proxy.balance_of(c2_client.address) assert initial_balance_c2 == initial_balance c1_token_network_proxy.set_total_deposit( given_block_identifier="latest", channel_identifier=channel_identifier, total_deposit=10, partner=c2_client.address, ) c2_token_network_proxy.set_total_deposit( given_block_identifier="latest", channel_identifier=channel_identifier, total_deposit=10, partner=c1_client.address, ) # balance proof signed by c1 transferred_amount_c1 = 1 transferred_amount_c2 = 3 balance_proof_c1 = BalanceProof( channel_identifier=channel_identifier, token_network_address=to_checksum_address(token_network_address), nonce=1, chain_id=chain_id, transferred_amount=transferred_amount_c1, ) balance_proof_c1.signature = encode_hex( LocalSigner( private_keys[1]).sign(data=balance_proof_c1.serialize_bin())) # balance proof signed by c2 balance_proof_c2 = BalanceProof( channel_identifier=channel_identifier, token_network_address=to_checksum_address(token_network_address), nonce=2, chain_id=chain_id, transferred_amount=transferred_amount_c2, ) balance_proof_c2.signature = encode_hex( LocalSigner( private_keys[2]).sign(data=balance_proof_c2.serialize_bin())) non_closing_data = balance_proof_c1.serialize_bin( msg_type=MessageTypeId.BALANCE_PROOF_UPDATE) + decode_hex( balance_proof_c1.signature) non_closing_signature = LocalSigner( c2_client.privkey).sign(data=non_closing_data) with pytest.raises(RaidenUnrecoverableError) as exc: c2_token_network_proxy.update_transfer( channel_identifier=channel_identifier, partner=c1_client.address, balance_hash=decode_hex(balance_proof_c1.balance_hash), nonce=balance_proof_c1.nonce, additional_hash=decode_hex(balance_proof_c1.additional_hash), closing_signature=decode_hex(balance_proof_c1.signature), non_closing_signature=non_closing_signature, given_block_identifier="latest", ) assert "not in a closed state" in str(exc) # close by c1 c1_token_network_proxy.close( channel_identifier=channel_identifier, partner=c2_client.address, balance_hash=decode_hex(balance_proof_c2.balance_hash), nonce=balance_proof_c2.nonce, additional_hash=decode_hex(balance_proof_c2.additional_hash), signature=decode_hex(balance_proof_c2.signature), given_block_identifier="latest", ) # update transfer with completely invalid closing signature with pytest.raises(RaidenUnrecoverableError) as excinfo: c2_token_network_proxy.update_transfer( channel_identifier=channel_identifier, partner=c1_client.address, balance_hash=decode_hex(balance_proof_c1.balance_hash), nonce=balance_proof_c1.nonce, additional_hash=decode_hex(balance_proof_c1.additional_hash), closing_signature=b"", non_closing_signature=b"", given_block_identifier="latest", ) assert str(excinfo.value) == "Couldn't verify the balance proof signature" # using invalid non-closing signature # Usual mistake when calling update Transfer - balance proof signature is missing in the data non_closing_data = balance_proof_c1.serialize_bin( msg_type=MessageTypeId.BALANCE_PROOF_UPDATE) non_closing_signature = LocalSigner( c2_client.privkey).sign(data=non_closing_data) with pytest.raises(RaidenUnrecoverableError): c2_token_network_proxy.update_transfer( channel_identifier=channel_identifier, partner=c1_client.address, balance_hash=decode_hex(balance_proof_c1.balance_hash), nonce=balance_proof_c1.nonce, additional_hash=decode_hex(balance_proof_c1.additional_hash), closing_signature=decode_hex(balance_proof_c1.signature), non_closing_signature=non_closing_signature, given_block_identifier="latest", ) non_closing_data = balance_proof_c1.serialize_bin( msg_type=MessageTypeId.BALANCE_PROOF_UPDATE) + decode_hex( balance_proof_c1.signature) non_closing_signature = LocalSigner( c2_client.privkey).sign(data=non_closing_data) c2_token_network_proxy.update_transfer( channel_identifier=channel_identifier, partner=c1_client.address, balance_hash=decode_hex(balance_proof_c1.balance_hash), nonce=balance_proof_c1.nonce, additional_hash=decode_hex(balance_proof_c1.additional_hash), closing_signature=decode_hex(balance_proof_c1.signature), non_closing_signature=non_closing_signature, given_block_identifier="latest", ) with pytest.raises(RaidenUnrecoverableError) as exc: c1_token_network_proxy.settle( channel_identifier=channel_identifier, transferred_amount=transferred_amount_c1, locked_amount=0, locksroot=EMPTY_HASH, partner=c2_client.address, partner_transferred_amount=transferred_amount_c2, partner_locked_amount=0, partner_locksroot=EMPTY_HASH, given_block_identifier="latest", ) assert "cannot be settled before settlement window is over" in str(exc) c1_chain.wait_until_block(target_block_number=c1_chain.block_number() + 10) # settling with an invalid amount with pytest.raises(RaidenUnrecoverableError): c1_token_network_proxy.settle( channel_identifier=channel_identifier, transferred_amount=2, locked_amount=0, locksroot=EMPTY_HASH, partner=c2_client.address, partner_transferred_amount=2, partner_locked_amount=0, partner_locksroot=EMPTY_HASH, given_block_identifier="latest", ) # proper settle c1_token_network_proxy.settle( channel_identifier=channel_identifier, transferred_amount=transferred_amount_c1, locked_amount=0, locksroot=EMPTY_HASH, partner=c2_client.address, partner_transferred_amount=transferred_amount_c2, partner_locked_amount=0, partner_locksroot=EMPTY_HASH, given_block_identifier="latest", ) assert token_proxy.balance_of( c2_client.address) == (initial_balance_c2 + transferred_amount_c1 - transferred_amount_c2) assert token_proxy.balance_of( c1_client.address) == (initial_balance_c1 + transferred_amount_c2 - transferred_amount_c1) # Already settled with pytest.raises(RaidenUnrecoverableError) as exc: c2_token_network_proxy.set_total_deposit( given_block_identifier="latest", channel_identifier=channel_identifier, total_deposit=20, partner=c1_client.address, ) assert "getChannelIdentifier returned 0" in str(exc)
def test_token_network_proxy_basics( token_network_proxy, private_keys, token_proxy, chain_id, web3, contract_manager, ): # check settlement timeouts assert token_network_proxy.settlement_timeout_min( ) == TEST_SETTLE_TIMEOUT_MIN assert token_network_proxy.settlement_timeout_max( ) == TEST_SETTLE_TIMEOUT_MAX token_network_address = to_canonical_address( token_network_proxy.proxy.contract.address) c1_client = JSONRPCClient(web3, private_keys[1]) c1_chain = BlockChainService( jsonrpc_client=c1_client, contract_manager=contract_manager, ) c2_client = JSONRPCClient(web3, private_keys[2]) c1_token_network_proxy = TokenNetwork( jsonrpc_client=c1_client, token_network_address=token_network_address, contract_manager=contract_manager, ) c2_token_network_proxy = TokenNetwork( jsonrpc_client=c2_client, token_network_address=token_network_address, contract_manager=contract_manager, ) initial_token_balance = 100 token_proxy.transfer(c1_client.address, initial_token_balance) token_proxy.transfer(c2_client.address, initial_token_balance) initial_balance_c1 = token_proxy.balance_of(c1_client.address) assert initial_balance_c1 == initial_token_balance initial_balance_c2 = token_proxy.balance_of(c2_client.address) assert initial_balance_c2 == initial_token_balance # instantiating a new channel - test basic assumptions assert c1_token_network_proxy._channel_exists_and_not_settled( participant1=c1_client.address, participant2=c2_client.address, block_identifier='latest', ) is False channel_identifier = c1_token_network_proxy._call_and_check_result( 'latest', 'getChannelIdentifier', to_checksum_address(c1_client.address), to_checksum_address(c2_client.address), ) assert c1_token_network_proxy.channel_is_opened( participant1=c1_client.address, participant2=c2_client.address, block_identifier='latest', channel_identifier=channel_identifier, ) is False assert c1_token_network_proxy.channel_is_closed( participant1=c1_client.address, participant2=c2_client.address, block_identifier='latest', channel_identifier=channel_identifier, ) is False # test timeout limits with pytest.raises(InvalidSettleTimeout): c1_token_network_proxy.new_netting_channel( partner=c2_client.address, settle_timeout=TEST_SETTLE_TIMEOUT_MIN - 1, given_block_identifier='latest', ) with pytest.raises(InvalidSettleTimeout): c1_token_network_proxy.new_netting_channel( partner=c2_client.address, settle_timeout=TEST_SETTLE_TIMEOUT_MAX + 1, given_block_identifier='latest', ) # channel to self with pytest.raises(SamePeerAddress): c1_token_network_proxy.new_netting_channel( partner=c1_client.address, settle_timeout=TEST_SETTLE_TIMEOUT_MIN, given_block_identifier='latest', ) # Channel is not open yet with pytest.raises(RaidenUnrecoverableError) as exc: c1_token_network_proxy.set_total_deposit( given_block_identifier='latest', channel_identifier=1, total_deposit=1, partner=c2_client.address, ) assert 'does not exist' in str(exc) # Channel is not open yet with pytest.raises(RaidenUnrecoverableError) as exc: c1_token_network_proxy.close( channel_identifier=1, partner=c2_client.address, balance_hash=EMPTY_HASH, nonce=0, additional_hash=EMPTY_HASH, signature=EMPTY_HASH, given_block_identifier='latest', ) assert 'does not exist' in str(exc) # actually create a channel channel_identifier = c1_token_network_proxy.new_netting_channel( partner=c2_client.address, settle_timeout=TEST_SETTLE_TIMEOUT_MIN, given_block_identifier='latest', ) assert channel_identifier is not None # multiple channels with the same peer are not allowed with pytest.raises(DuplicatedChannelError): c1_token_network_proxy.new_netting_channel( partner=c2_client.address, settle_timeout=TEST_SETTLE_TIMEOUT_MIN, given_block_identifier='latest', ) assert c1_token_network_proxy._channel_exists_and_not_settled( participant1=c1_client.address, participant2=c2_client.address, channel_identifier=channel_identifier, block_identifier='latest', ) is True assert c1_token_network_proxy.channel_is_opened( participant1=c1_client.address, participant2=c2_client.address, block_identifier='latest', channel_identifier=channel_identifier, ) is True # channel is open. # deposit with no balance with pytest.raises(DepositMismatch): c1_token_network_proxy.set_total_deposit( given_block_identifier='latest', channel_identifier=channel_identifier, total_deposit=101, partner=c2_client.address, ) # no negative deposit with pytest.raises(DepositMismatch): c1_token_network_proxy.set_total_deposit( given_block_identifier='latest', channel_identifier=channel_identifier, total_deposit=-1, partner=c2_client.address, ) # actual deposit c1_token_network_proxy.set_total_deposit( given_block_identifier='latest', channel_identifier=channel_identifier, total_deposit=10, partner=c2_client.address, ) # balance proof by c2 transferred_amount = 3 balance_proof = BalanceProof( channel_identifier=channel_identifier, token_network_address=to_checksum_address(token_network_address), nonce=1, chain_id=chain_id, transferred_amount=transferred_amount, ) balance_proof.signature = encode_hex( LocalSigner(private_keys[1]).sign( data=balance_proof.serialize_bin(), ), ) # close with invalid signature with pytest.raises(RaidenUnrecoverableError): c2_token_network_proxy.close( channel_identifier=channel_identifier, partner=c1_client.address, balance_hash=decode_hex(balance_proof.balance_hash), nonce=balance_proof.nonce, additional_hash=decode_hex(balance_proof.additional_hash), signature=b'\x11' * 65, given_block_identifier='latest', ) # correct close c2_token_network_proxy.close( channel_identifier=channel_identifier, partner=c1_client.address, balance_hash=decode_hex(balance_proof.balance_hash), nonce=balance_proof.nonce, additional_hash=decode_hex(balance_proof.additional_hash), signature=decode_hex(balance_proof.signature), given_block_identifier='latest', ) assert c1_token_network_proxy.channel_is_closed( participant1=c1_client.address, participant2=c2_client.address, block_identifier='latest', channel_identifier=channel_identifier, ) is True assert c1_token_network_proxy._channel_exists_and_not_settled( participant1=c1_client.address, participant2=c2_client.address, channel_identifier=channel_identifier, block_identifier='latest', ) is True # closing already closed channel with pytest.raises(RaidenRecoverableError): c2_token_network_proxy.close( channel_identifier=channel_identifier, partner=c1_client.address, balance_hash=decode_hex(balance_proof.balance_hash), nonce=balance_proof.nonce, additional_hash=decode_hex(balance_proof.additional_hash), signature=decode_hex(balance_proof.signature), given_block_identifier='latest', ) with pytest.raises(RaidenRecoverableError) as exc: c2_token_network_proxy.set_total_deposit( given_block_identifier='latest', channel_identifier=channel_identifier, total_deposit=20, partner=c1_client.address, ) assert 'not in an open state' in str(exc) with pytest.raises(RaidenRecoverableError) as exc: c2_token_network_proxy.close( channel_identifier=channel_identifier, partner=c1_client.address, balance_hash=decode_hex(balance_proof.balance_hash), nonce=balance_proof.nonce, additional_hash=decode_hex(balance_proof.additional_hash), signature=decode_hex(balance_proof.signature), given_block_identifier='latest', ) assert 'not in an open state' in str(exc) # update transfer c1_chain.wait_until_block(target_block_number=c1_chain.block_number() + TEST_SETTLE_TIMEOUT_MIN, ) # try to settle using incorrect data with pytest.raises(RaidenUnrecoverableError): c2_token_network_proxy.settle( channel_identifier=channel_identifier, transferred_amount=1, locked_amount=0, locksroot=EMPTY_HASH, partner=c1_client.address, partner_transferred_amount=transferred_amount, partner_locked_amount=0, partner_locksroot=EMPTY_HASH, given_block_identifier='latest', ) c2_token_network_proxy.settle( channel_identifier=channel_identifier, transferred_amount=0, locked_amount=0, locksroot=EMPTY_HASH, partner=c1_client.address, partner_transferred_amount=transferred_amount, partner_locked_amount=0, partner_locksroot=EMPTY_HASH, given_block_identifier='latest', ) assert c1_token_network_proxy._channel_exists_and_not_settled( participant1=c1_client.address, participant2=c2_client.address, channel_identifier=channel_identifier, block_identifier='latest', ) is False assert token_proxy.balance_of(c1_client.address) == (initial_balance_c1 - transferred_amount) assert token_proxy.balance_of(c2_client.address) == (initial_balance_c2 + transferred_amount) with pytest.raises(RaidenUnrecoverableError) as exc: c1_token_network_proxy.set_total_deposit( given_block_identifier='latest', channel_identifier=channel_identifier, total_deposit=10, partner=c2_client.address, ) # No channel exists assert 'getChannelIdentifier returned 0' in str(exc)
def test_payment_channel_outdated_channel_close( token_network_proxy, private_keys, chain_id, web3, contract_manager, ): token_network_address = to_canonical_address( token_network_proxy.proxy.contract.address) partner = privatekey_to_address(private_keys[0]) client = JSONRPCClient(web3, private_keys[1]) chain = BlockChainService( jsonrpc_client=client, contract_manager=contract_manager, ) token_network_proxy = TokenNetwork( jsonrpc_client=client, token_network_address=token_network_address, contract_manager=contract_manager, ) start_block = web3.eth.blockNumber # create a channel channel_identifier = token_network_proxy.new_netting_channel( partner=partner, settle_timeout=TEST_SETTLE_TIMEOUT_MIN, given_block_identifier='latest', ) assert channel_identifier is not None # create channel proxies channel_proxy_1 = PaymentChannel( token_network=token_network_proxy, channel_identifier=channel_identifier, contract_manager=contract_manager, ) channel_filter = channel_proxy_1.all_events_filter( from_block=start_block, to_block='latest', ) assert channel_proxy_1.channel_identifier == channel_identifier assert channel_proxy_1.opened('latest') is True # balance proof by c1 balance_proof = BalanceProof( channel_identifier=channel_identifier, token_network_address=to_checksum_address(token_network_address), nonce=0, chain_id=chain_id, transferred_amount=0, ) balance_proof.signature = encode_hex( LocalSigner(private_keys[0]).sign( data=balance_proof.serialize_bin(), ), ) # correct close token_network_proxy.close( channel_identifier=channel_identifier, partner=partner, balance_hash=bytes(32), nonce=balance_proof.nonce, additional_hash=bytes(32), signature=decode_hex(balance_proof.signature), given_block_identifier='latest', ) assert channel_proxy_1.closed('latest') is True events = channel_filter.get_all_entries() assert len(events) == 2 # ChannelOpened, ChannelClosed # check the settlement timeouts again assert channel_proxy_1.settle_timeout() == TEST_SETTLE_TIMEOUT_MIN # update transfer -- we need to wait on +1 since we use the latest block on parity for # estimate gas and at the time the latest block is the settle timeout block. # More info: https://github.com/raiden-network/raiden/pull/3699#discussion_r270477227 chain.wait_until_block(target_block_number=client.block_number() + TEST_SETTLE_TIMEOUT_MIN + 1) token_network_proxy.settle( channel_identifier=channel_identifier, transferred_amount=0, locked_amount=0, locksroot=EMPTY_HASH, partner=partner, partner_transferred_amount=0, partner_locked_amount=0, partner_locksroot=EMPTY_HASH, given_block_identifier='latest', ) assert channel_proxy_1.settled('latest') is True events = channel_filter.get_all_entries() assert len(events) == 3 # ChannelOpened, ChannelClosed, ChannelSettled # Create a new channel with a different identifier # create a channel new_channel_identifier = token_network_proxy.new_netting_channel( partner=partner, settle_timeout=TEST_SETTLE_TIMEOUT_MIN, given_block_identifier='latest', ) assert new_channel_identifier is not None # create channel proxies channel_proxy_2 = PaymentChannel( token_network=token_network_proxy, channel_identifier=new_channel_identifier, contract_manager=contract_manager, ) assert channel_proxy_2.channel_identifier == new_channel_identifier assert channel_proxy_2.opened('latest') is True with pytest.raises(ChannelOutdatedError): token_network_proxy.close( channel_identifier=channel_identifier, partner=partner, balance_hash=bytes(32), nonce=balance_proof.nonce, additional_hash=bytes(32), signature=decode_hex(balance_proof.signature), given_block_identifier='latest', )
def test_payment_channel_proxy_basics( token_network_proxy, private_keys, token_proxy, chain_id, web3, contract_manager, ): token_network_address = to_canonical_address( token_network_proxy.proxy.contract.address) c1_client = JSONRPCClient(web3, private_keys[1]) c1_chain = BlockChainService( jsonrpc_client=c1_client, contract_manager=contract_manager, ) c2_client = JSONRPCClient(web3, private_keys[2]) c1_token_network_proxy = TokenNetwork( jsonrpc_client=c1_client, token_network_address=token_network_address, contract_manager=contract_manager, ) c2_token_network_proxy = TokenNetwork( jsonrpc_client=c2_client, token_network_address=token_network_address, contract_manager=contract_manager, ) start_block = web3.eth.blockNumber # create a channel channel_identifier = c1_token_network_proxy.new_netting_channel( partner=c2_client.address, settle_timeout=TEST_SETTLE_TIMEOUT_MIN, given_block_identifier='latest', ) assert channel_identifier is not None # create channel proxies channel_proxy_1 = PaymentChannel( token_network=c1_token_network_proxy, channel_identifier=channel_identifier, contract_manager=contract_manager, ) channel_proxy_2 = PaymentChannel( token_network=c2_token_network_proxy, channel_identifier=channel_identifier, contract_manager=contract_manager, ) channel_filter = channel_proxy_1.all_events_filter( from_block=start_block, to_block='latest', ) assert channel_proxy_1.channel_identifier == channel_identifier assert channel_proxy_2.channel_identifier == channel_identifier assert channel_proxy_1.opened('latest') is True assert channel_proxy_2.opened('latest') is True # check the settlement timeouts assert channel_proxy_1.settle_timeout() == channel_proxy_2.settle_timeout() assert channel_proxy_1.settle_timeout() == TEST_SETTLE_TIMEOUT_MIN events = channel_filter.get_all_entries() assert len(events) == 1 # ChannelOpened # test deposits initial_token_balance = 100 token_proxy.transfer(c1_client.address, initial_token_balance) initial_balance_c1 = token_proxy.balance_of(c1_client.address) assert initial_balance_c1 == initial_token_balance initial_balance_c2 = token_proxy.balance_of(c2_client.address) assert initial_balance_c2 == 0 # actual deposit channel_proxy_1.set_total_deposit(total_deposit=10, block_identifier='latest') events = channel_filter.get_all_entries() assert len(events) == 2 # ChannelOpened, ChannelNewDeposit # balance proof by c2 transferred_amount = 3 balance_proof = BalanceProof( channel_identifier=channel_identifier, token_network_address=to_checksum_address(token_network_address), nonce=1, chain_id=chain_id, transferred_amount=transferred_amount, ) balance_proof.signature = encode_hex( LocalSigner(private_keys[1]).sign( data=balance_proof.serialize_bin(), ), ) # correct close c2_token_network_proxy.close( channel_identifier=channel_identifier, partner=c1_client.address, balance_hash=decode_hex(balance_proof.balance_hash), nonce=balance_proof.nonce, additional_hash=decode_hex(balance_proof.additional_hash), signature=decode_hex(balance_proof.signature), given_block_identifier='latest', ) assert channel_proxy_1.closed('latest') is True assert channel_proxy_2.closed('latest') is True events = channel_filter.get_all_entries() assert len(events) == 3 # ChannelOpened, ChannelNewDeposit, ChannelClosed # check the settlement timeouts again assert channel_proxy_1.settle_timeout() == channel_proxy_2.settle_timeout() assert channel_proxy_1.settle_timeout() == TEST_SETTLE_TIMEOUT_MIN # update transfer -- we need to wait on +1 since we use the latest block on parity for # estimate gas and at the time the latest block is the settle timeout block. # More info: https://github.com/raiden-network/raiden/pull/3699#discussion_r270477227 c1_chain.wait_until_block(target_block_number=c1_client.block_number() + TEST_SETTLE_TIMEOUT_MIN + 1, ) c2_token_network_proxy.settle( channel_identifier=channel_identifier, transferred_amount=0, locked_amount=0, locksroot=EMPTY_HASH, partner=c1_client.address, partner_transferred_amount=transferred_amount, partner_locked_amount=0, partner_locksroot=EMPTY_HASH, given_block_identifier='latest', ) assert channel_proxy_1.settled('latest') is True assert channel_proxy_2.settled('latest') is True events = channel_filter.get_all_entries() assert len( events ) == 4 # ChannelOpened, ChannelNewDeposit, ChannelClosed, ChannelSettled