Example #1
0
def test_token_network_proxy_basics(
    token_network_proxy,
    private_keys,
    blockchain_rpc_ports,
    token_proxy,
    chain_id,
):
    token_network_address = to_canonical_address(
        token_network_proxy.proxy.contract.address)

    c1_client = JSONRPCClient(
        '0.0.0.0',
        blockchain_rpc_ports[0],
        private_keys[1],
    )
    c2_client = JSONRPCClient(
        '0.0.0.0',
        blockchain_rpc_ports[0],
        private_keys[2],
    )
    c1_token_network_proxy = TokenNetwork(
        c1_client,
        token_network_address,
    )
    c2_token_network_proxy = TokenNetwork(
        c2_client,
        token_network_address,
    )

    # instantiating a new channel - test basic assumptions
    assert c1_token_network_proxy.channel_exists(c2_client.sender) is False
    assert c1_token_network_proxy.channel_is_opened(c2_client.sender) is False
    assert c1_token_network_proxy.channel_is_closed(c2_client.sender) is False
    # test timeout limits
    with pytest.raises(InvalidSettleTimeout):
        c1_token_network_proxy.new_netting_channel(
            c2_client.sender,
            NETTINGCHANNEL_SETTLE_TIMEOUT_MIN - 1,
        )
    with pytest.raises(InvalidSettleTimeout):
        c1_token_network_proxy.new_netting_channel(
            c2_client.sender,
            NETTINGCHANNEL_SETTLE_TIMEOUT_MAX + 1,
        )
    # channel to self
    with pytest.raises(SamePeerAddress):
        c1_token_network_proxy.new_netting_channel(
            c1_client.sender,
            NETTINGCHANNEL_SETTLE_TIMEOUT_MIN,
        )
    # actually create a channel
    channel_identifier = c1_token_network_proxy.new_netting_channel(
        c2_client.sender,
        NETTINGCHANNEL_SETTLE_TIMEOUT_MIN,
    )
    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(
            c2_client.sender,
            NETTINGCHANNEL_SETTLE_TIMEOUT_MIN,
        )
    assert c1_token_network_proxy.channel_exists(c2_client.sender) is True
    assert c1_token_network_proxy.channel_is_opened(c2_client.sender) is True

    # channel is open.
    # deposit with no balance
    with pytest.raises(ValueError):
        c1_token_network_proxy.deposit(
            10,
            c2_client.sender,
        )
    # test deposits
    initial_token_balance = 100
    token_proxy.transfer(c1_client.sender, initial_token_balance)
    initial_balance_c1 = token_proxy.balance_of(c1_client.sender)
    assert initial_balance_c1 == initial_token_balance
    initial_balance_c2 = token_proxy.balance_of(c2_client.sender)
    assert initial_balance_c2 == 0
    # no negative deposit
    with pytest.raises(ValueError):
        c1_token_network_proxy.deposit(
            -1,
            c2_client.sender,
        )
    # actual deposit
    c1_token_network_proxy.deposit(
        10,
        c2_client.sender,
    )
    # balance proof by c2
    transferred_amount = 3
    balance_proof = BalanceProof(
        channel_identifier=encode_hex(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(
        sign_data(encode_hex(private_keys[1]),
                  balance_proof.serialize_bin()), )
    # close with invalid signature
    with pytest.raises(TransactionThrew):
        c2_token_network_proxy.close(
            c1_client.sender,
            balance_proof.nonce,
            balance_proof.balance_hash,
            balance_proof.additional_hash,
            b'\x11' * 65,
        )
    # correct close
    c2_token_network_proxy.close(
        c1_client.sender,
        balance_proof.nonce,
        balance_proof.balance_hash,
        balance_proof.additional_hash,
        decode_hex(balance_proof.signature),
    )
    assert c1_token_network_proxy.channel_is_closed(c2_client.sender) is True
    assert c1_token_network_proxy.channel_exists(c2_client.sender) is True
    # closing already closed channel
    with pytest.raises(ChannelIncorrectStateError):
        c2_token_network_proxy.close(
            c1_client.sender,
            balance_proof.nonce,
            balance_proof.balance_hash,
            balance_proof.additional_hash,
            decode_hex(balance_proof.signature),
        )
    # update transfer
    wait_blocks(c1_client.web3, NETTINGCHANNEL_SETTLE_TIMEOUT_MIN)

    c2_token_network_proxy.settle(
        0,
        0,
        EMPTY_HASH,
        c1_client.sender,
        transferred_amount,
        0,
        EMPTY_HASH,
    )
    assert c1_token_network_proxy.channel_exists(c2_client.sender) is False
    assert token_proxy.balance_of(c1_client.sender) == (initial_balance_c1 -
                                                        transferred_amount)
    assert token_proxy.balance_of(c2_client.sender) == (initial_balance_c2 +
                                                        transferred_amount)
Example #2
0
def test_token_network_proxy_update_transfer(
    token_network_proxy,
    private_keys,
    blockchain_rpc_ports,
    token_proxy,
    chain_id,
):
    """Tests channel lifecycle, with `update_transfer` before settling"""
    token_network_address = to_canonical_address(
        token_network_proxy.proxy.contract.address)

    c1_client = JSONRPCClient(
        '0.0.0.0',
        blockchain_rpc_ports[0],
        private_keys[1],
    )
    c2_client = JSONRPCClient(
        '0.0.0.0',
        blockchain_rpc_ports[0],
        private_keys[2],
    )
    c1_token_network_proxy = TokenNetwork(
        c1_client,
        token_network_address,
    )
    c2_token_network_proxy = TokenNetwork(
        c2_client,
        token_network_address,
    )
    # create a channel
    channel_identifier = c1_token_network_proxy.new_netting_channel(
        c2_client.sender,
        NETTINGCHANNEL_SETTLE_TIMEOUT_MIN,
    )
    # deposit to the channel
    initial_balance = 100
    token_proxy.transfer(c1_client.sender, initial_balance)
    token_proxy.transfer(c2_client.sender, initial_balance)
    initial_balance_c1 = token_proxy.balance_of(c1_client.sender)
    assert initial_balance_c1 == initial_balance
    initial_balance_c2 = token_proxy.balance_of(c2_client.sender)
    assert initial_balance_c2 == initial_balance
    c1_token_network_proxy.deposit(
        10,
        c2_client.sender,
    )
    c2_token_network_proxy.deposit(
        10,
        c1_client.sender,
    )
    # balance proof signed by c1
    transferred_amount_c1 = 1
    transferred_amount_c2 = 3
    balance_proof_c1 = BalanceProof(
        channel_identifier=encode_hex(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(
        sign_data(encode_hex(private_keys[1]),
                  balance_proof_c1.serialize_bin()), )
    # balance proof signed by c2
    balance_proof_c2 = BalanceProof(
        channel_identifier=encode_hex(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(
        sign_data(encode_hex(private_keys[2]),
                  balance_proof_c2.serialize_bin()), )
    # close by c1
    c1_token_network_proxy.close(
        c2_client.sender,
        balance_proof_c2.nonce,
        balance_proof_c2.balance_hash,
        balance_proof_c2.additional_hash,
        decode_hex(balance_proof_c2.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()
    non_closing_signature = sign_data(
        encode_hex(c2_client.privkey),
        non_closing_data,
    )
    with pytest.raises(TransactionThrew):
        c2_token_network_proxy.update_transfer(
            c1_client.sender,
            balance_proof_c1.nonce,
            decode_hex(balance_proof_c1.balance_hash),
            decode_hex(balance_proof_c1.additional_hash),
            decode_hex(balance_proof_c1.signature),
            non_closing_signature,
        )

    non_closing_data = balance_proof_c1.serialize_bin() + decode_hex(
        balance_proof_c1.signature)
    non_closing_signature = sign_data(
        encode_hex(c2_client.privkey),
        non_closing_data,
    )
    c2_token_network_proxy.update_transfer(
        c1_client.sender,
        balance_proof_c1.nonce,
        decode_hex(balance_proof_c1.balance_hash),
        decode_hex(balance_proof_c1.additional_hash),
        decode_hex(balance_proof_c1.signature),
        non_closing_signature,
    )
    wait_blocks(c1_client.web3, NETTINGCHANNEL_SETTLE_TIMEOUT_MIN)

    # settling with an invalid amount
    with pytest.raises(TransactionThrew):
        c1_token_network_proxy.settle(
            2,
            0,
            EMPTY_HASH,
            c2_client.sender,
            2,
            0,
            EMPTY_HASH,
        )
    # proper settle
    c1_token_network_proxy.settle(
        transferred_amount_c1,
        0,
        EMPTY_HASH,
        c2_client.sender,
        transferred_amount_c2,
        0,
        EMPTY_HASH,
    )
    assert (token_proxy.balance_of(
        c2_client.sender) == (initial_balance_c2 + transferred_amount_c1 -
                              transferred_amount_c2))
    assert (token_proxy.balance_of(
        c1_client.sender) == (initial_balance_c1 + transferred_amount_c2 -
                              transferred_amount_c1))