def test_new_channel_state(private_keys, tester_chain, tester_channelmanager):
    """ Tests the state of a newly created netting channel. """
    pkey0, pkey1 = private_keys

    events = list()
    settle_timeout = 10
    channel = new_nettingcontract(
        pkey0,
        pkey1,
        tester_chain,
        events.append,
        tester_channelmanager,
        settle_timeout,
    )

    # pylint: disable=no-member
    assert channel.settleTimeout(sender=pkey0) == settle_timeout
    assert channel.tokenAddress(sender=pkey0) == tester_channelmanager.tokenAddress(sender=pkey0)
    assert channel.opened(sender=pkey0) == tester_chain.block.number - 1
    assert channel.closed(sender=pkey0) == 0

    address_and_balances = channel.addressAndBalance(sender=pkey0)
    address0 = privatekey_to_address(pkey0)
    address1 = privatekey_to_address(pkey1)

    assert address_and_balances[0] == address_encoder(address0)
    assert address_and_balances[1] == 0
    assert address_and_balances[2] == address_encoder(address1)
    assert address_and_balances[3] == 0
def test_channelnew_event(
        settle_timeout,
        tester_channelmanager,
        private_keys,
        tester_events):
    """ When a new channel is created the channel new event must be emitted. """

    pkey0 = private_keys[0]
    address0 = privatekey_to_address(pkey0)
    address1 = privatekey_to_address(private_keys[1])

    # pylint: disable=no-member
    netting_channel_address1_hex = tester_channelmanager.newChannel(
        address1,
        settle_timeout,
        sender=pkey0,
    )

    last_event = event_decoder(tester_events[-1], tester_channelmanager.translator)
    assert last_event == {
        '_event_type': b'ChannelNew',
        'netting_channel': netting_channel_address1_hex,
        'participant1': address_encoder(address0),
        'participant2': address_encoder(address1),
        'settle_timeout': settle_timeout,
    }
def test_channelmanager(private_keys, settle_timeout, tester_channelmanager):
    pkey0 = private_keys[0]
    address0 = privatekey_to_address(private_keys[0])
    address1 = privatekey_to_address(private_keys[1])
    address2 = privatekey_to_address(private_keys[2])

    total_pairs = 0
    for addr in [address1, address2]:
        channel_address_hex = tester_channelmanager.newChannel(
            addr,
            settle_timeout,
            sender=pkey0,
        )

        assert tester_channelmanager.getChannelWith(addr, sender=pkey0) == channel_address_hex

        total_pairs += 2
        participant_pairs = tester_channelmanager.getChannelsParticipants(sender=pkey0)
        assert len(participant_pairs) == total_pairs

    # pylint: disable=no-member
    addr0_channels = tester_channelmanager.nettingContractsByAddress(address0, sender=pkey0)
    addr1_channels = tester_channelmanager.nettingContractsByAddress(address1, sender=pkey0)

    nonexisting_address = sha3(b'this_does_not_exist')[:20]
    nonaddr_channels = tester_channelmanager.nettingContractsByAddress(
        nonexisting_address,
        sender=pkey0,
    )

    assert len(addr0_channels) == 2
    assert len(addr1_channels) == 1
    assert not nonaddr_channels
示例#4
0
def geth_wait_and_check(privatekeys, rpc_ports):
    """ Wait until the geth cluster is ready. """
    address = address_encoder(privatekey_to_address(privatekeys[0]))
    jsonrpc_running = False
    tries = 5
    rpc_port = rpc_ports[0]
    jsonrpc_client = JSONRPCClient(host="0.0.0.0", port=rpc_port, privkey=privatekeys[0], print_communication=False)

    while not jsonrpc_running and tries > 0:
        try:
            jsonrpc_client.call("eth_getBalance", address, "latest")
            jsonrpc_running = True
        except ConnectionError:
            gevent.sleep(0.5)
            tries -= 1

    if jsonrpc_running is False:
        raise ValueError("geth didnt start the jsonrpc interface")

    for key in set(privatekeys):
        address = address_encoder(privatekey_to_address(key))
        jsonrpc_client = JSONRPCClient(host="0.0.0.0", port=rpc_port, privkey=key, print_communication=False)

        tries = 10
        balance = "0x0"
        while balance == "0x0" and tries > 0:
            balance = jsonrpc_client.call("eth_getBalance", address, "latest")
            gevent.sleep(1)
            tries -= 1

        if balance == "0x0":
            raise ValueError("account is with a balance of 0")
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_settle_with_locked_mediated_transfer_for_counterparty(
        deposit,
        settle_timeout,
        reveal_timeout,
        tester_chain,
        tester_channels,
        tester_token):

    """ Test settle with a locked mediated transfer for the counter party. """

    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)

    transferred_amount0 = 30
    increase_transferred_amount(channel0, channel1, transferred_amount0)

    expiration0 = tester_chain.block.number + reveal_timeout + 5
    new_block = Block(tester_chain.block.number)
    channel0.state_transition(new_block)
    channel1.state_transition(new_block)
    lock0 = Lock(amount=29, expiration=expiration0, hashlock=sha3(b'lock1'))
    mediated0 = make_mediated_transfer(
        channel0,
        channel1,
        address0,
        address1,
        lock0,
        pkey0,
        tester_chain.block.number,
    )

    nettingchannel.close(sender=pkey0)

    mediated0_hash = sha3(mediated0.packed().data[:-65])
    nettingchannel.updateTransfer(
        mediated0.nonce,
        mediated0.transferred_amount,
        mediated0.locksroot,
        mediated0_hash,
        mediated0.signature,
        sender=pkey1,
    )

    tester_chain.mine(number_of_blocks=settle_timeout + 1)
    nettingchannel.settle(sender=pkey1)

    # the balances only change by transferred_amount because the lock was /not/ unlocked
    balance0 = initial0 + deposit - transferred_amount0
    balance1 = initial1 + transferred_amount0

    assert tester_token.balanceOf(nettingchannel.address, sender=pkey0) == 0
    assert tester_token.balanceOf(address0, sender=pkey0) == balance0
    assert tester_token.balanceOf(address1, sender=pkey0) == balance1
    def __init__(self, private_key, tester_chain):
        self.tester_chain = tester_chain

        self.address = privatekey_to_address(private_key)
        self.private_key = private_key
        self.node_address = privatekey_to_address(private_key)

        self.address_to_token = dict()
        self.address_to_discovery = dict()
        self.address_to_nettingchannel = dict()
        self.address_to_registry = dict()
        self.client = ClientMock()
def test_reopen_channel(
        private_keys,
        settle_timeout,
        tester_channelmanager,
        tester_chain):
    """ A new channel can be opened after the old one is settled. When this
    happens the channel manager must update its internal data structures to
    point to the new channel address.
    """

    log = list()
    pkey = private_keys[0]

    channels = list()
    old_channel_addresses = list()
    for partner_pkey in private_keys[1:]:
        nettingcontract = new_nettingcontract(
            pkey, partner_pkey, tester_chain, log.append, tester_channelmanager, settle_timeout,
        )
        channels.append(nettingcontract)

        address = privatekey_to_address(partner_pkey)
        channel_address = tester_channelmanager.getChannelWith(
            address,
            sender=pkey,
        )
        old_channel_addresses.append(channel_address)

    for nettingchannel in channels:
        netting_channel_settled(
            tester_chain,
            nettingchannel,
            pkey,
            settle_timeout,
        )

    channels = list()
    for partner_pkey in private_keys[1:]:
        nettingcontract = new_nettingcontract(
            pkey, partner_pkey, tester_chain, log.append, tester_channelmanager, settle_timeout,
        )
        channels.append(nettingcontract)

    # there must be a single entry for each participant
    for partner_pkey in private_keys[1:]:
        address = privatekey_to_address(partner_pkey)
        channel_address = tester_channelmanager.getChannelWith(
            address,
            sender=pkey,
        )
        assert channel_address
        assert channel_address not in old_channel_addresses
def test_deposit(private_keys, tester_channelmanager, tester_chain, tester_token):
    """ A call to deposit must increase the available token amount in the
    netting channel.
    """
    pkey0 = private_keys[0]
    pkey1 = private_keys[1]
    address0 = address_encoder(privatekey_to_address(pkey0))
    address1 = address_encoder(privatekey_to_address(pkey1))

    settle_timeout = 10
    events = list()

    # not using the tester_nettingcontracts fixture because it has a set balance
    channel = new_nettingcontract(
        pkey0,
        pkey1,
        tester_chain,
        events.append,
        tester_channelmanager,
        settle_timeout,
    )

    deposit = 100

    # cannot deposit without approving
    assert channel.deposit(deposit, sender=pkey0) is False

    assert tester_token.approve(channel.address, deposit, sender=pkey0) is True

    # cannot deposit negative values
    with pytest.raises(abi.ValueOutOfBounds):
        channel.deposit(-1, sender=pkey0)

    zero_state = (address0, 0, address1, 0)
    assert tuple(channel.addressAndBalance(sender=pkey0)) == zero_state

    assert channel.deposit(deposit, sender=pkey0) is True

    deposit_state = (address0, deposit, address1, 0)
    assert tuple(channel.addressAndBalance(sender=pkey0)) == deposit_state
    assert tester_token.balanceOf(channel.address, sender=pkey0) == deposit

    # cannot over deposit (the allowance is depleted)
    assert channel.deposit(deposit, sender=pkey0) is False

    assert tester_token.approve(channel.address, deposit, sender=pkey0) is True
    assert channel.deposit(deposit, sender=pkey0) is True

    second_deposit_state = (address0, deposit * 2, address1, 0)
    assert tuple(channel.addressAndBalance(sender=pkey0)) == second_deposit_state
def test_withdraw_twice(reveal_timeout, tester_channels, tester_chain):
    """ A lock can be withdrawn only once, the second try must fail. """
    pkey0, pkey1, nettingchannel, channel0, channel1 = tester_channels[0]

    lock_expiration = tester_chain.block.number + reveal_timeout + 5
    secret = b'secretsecretsecretsecretsecretse'
    new_block = Block(tester_chain.block.number)
    channel0.state_transition(new_block)
    channel1.state_transition(new_block)
    lock = Lock(17, lock_expiration, sha3(secret))

    mediated0 = make_mediated_transfer(
        channel1,
        channel0,
        privatekey_to_address(pkey1),
        privatekey_to_address(pkey0),
        lock,
        pkey1,
        tester_chain.block.number,
        secret,
    )

    mediated0_hash = sha3(mediated0.packed().data[:-65])
    nettingchannel.close(
        mediated0.nonce,
        mediated0.transferred_amount,
        mediated0.locksroot,
        mediated0_hash,
        mediated0.signature,
        sender=pkey0,
    )

    unlock_proofs = list(channel0.partner_state.get_known_unlocks())
    proof = unlock_proofs[0]

    nettingchannel.withdraw(
        proof.lock_encoded,
        b''.join(proof.merkle_proof),
        proof.secret,
        sender=pkey0,
    )

    with pytest.raises(TransactionFailed):
        nettingchannel.withdraw(
            proof.lock_encoded,
            b''.join(proof.merkle_proof),
            proof.secret,
            sender=pkey0,
        )
def test_for_issue_892(
        private_keys,
        settle_timeout,
        tester_channelmanager,
        tester_chain,
        tester_events):
    """
    This is a regression test for issue #892 (https://github.com/raiden-network/raiden/issues/892)
    where the `getChannelsParticipants()` call was returning an empty list if one channel from
    the channel manager has been settled
    """

    pairs = itertools.combinations(private_keys, 2)

    participant_pairs = []
    first_pair = True
    for pkey0, pkey1 in pairs:
        address0 = privatekey_to_address(pkey0)
        address1 = privatekey_to_address(pkey1)

        channel_address_hex = tester_channelmanager.newChannel(
            address1,
            settle_timeout,
            sender=pkey0,
        )
        tester_chain.mine()

        assert tester_channelmanager.getChannelWith(address1, sender=pkey0) == channel_address_hex
        assert tester_channelmanager.getChannelWith(address0, sender=pkey1) == channel_address_hex

        if first_pair:
            first_pair = False
            nettingchannel = create_nettingchannel_proxy(
                tester_chain,
                channel_address_hex,
                tester_events.append,
            )
            nettingchannel.close(sender=pkey0)
            tester_chain.mine(number_of_blocks=settle_timeout + 2)
            nettingchannel.settle(sender=pkey1)

        else:
            # this is brittle, relying on an implicit ordering of addresses
            participant_pairs.extend((
                address_encoder(address0),
                address_encoder(address1),
            ))

        assert participant_pairs == tester_channelmanager.getChannelsParticipants(sender=pkey0)
def test_update_must_fail_with_a_channel_address(tester_channels, private_keys):
    """ updateTransfer must not accept a transfer signed with the wrong channel address. """
    pkey0, pkey1, nettingchannel, channel0, channel1 = tester_channels[0]
    opened_block = nettingchannel.opened(sender=pkey0)
    wrong_channel = make_address()

    # make a transfer where pkey1 is the target
    transfer_wrong_recipient = DirectTransfer(
        identifier=1,
        nonce=1 + (opened_block * (2 ** 32)),
        token=channel0.token_address,
        channel=wrong_channel,
        transferred_amount=10,
        recipient=channel1.our_address,
        locksroot=EMPTY_MERKLE_ROOT,
    )

    our_address = privatekey_to_address(pkey0)
    our_sign_key = PrivateKey(pkey0)

    transfer_wrong_recipient.sign(our_sign_key, our_address)

    nettingchannel.close(sender=pkey0)

    transfer_wrong_recipient_hash = sha3(transfer_wrong_recipient.packed().data[:-65])
    with pytest.raises(TransactionFailed):
        nettingchannel.updateTransfer(
            transfer_wrong_recipient.nonce,
            transfer_wrong_recipient.transferred_amount,
            transfer_wrong_recipient.locksroot,
            transfer_wrong_recipient_hash,
            transfer_wrong_recipient.signature,
            sender=pkey1,
        )
示例#13
0
    def __init__(
            self,
            jsonrpc_client,
            secret_registry_address,
    ):
        if not is_binary_address(secret_registry_address):
            raise InvalidAddress('Expected binary address format for secret registry')

        check_address_has_code(jsonrpc_client, secret_registry_address, CONTRACT_SECRET_REGISTRY)

        proxy = jsonrpc_client.new_contract_proxy(
            CONTRACT_MANAGER.get_contract_abi(CONTRACT_SECRET_REGISTRY),
            to_normalized_address(secret_registry_address),
        )

        if not compare_versions(
            proxy.contract.functions.contract_version().call(),
            EXPECTED_CONTRACTS_VERSION,
        ):
            raise ContractVersionMismatch('Incompatible ABI for SecretRegistry')

        self.address = secret_registry_address
        self.proxy = proxy
        self.client = jsonrpc_client
        self.node_address = privatekey_to_address(self.client.privkey)
        self.open_secret_transactions = dict()
    def detail(self):
        """ FIXME: 'our_address' is only needed for the pure python mock implementation """
        self._check_exists()

        data = self.proxy.addressAndBalance()
        settle_timeout = self.proxy.settleTimeout()
        our_address = privatekey_to_address(self.private_key)

        if address_decoder(data[0]) == our_address:
            return {
                'our_address': address_decoder(data[0]),
                'our_balance': data[1],
                'partner_address': address_decoder(data[2]),
                'partner_balance': data[3],
                'settle_timeout': settle_timeout,
            }

        if address_decoder(data[2]) == our_address:
            return {
                'our_address': address_decoder(data[2]),
                'our_balance': data[3],
                'partner_address': address_decoder(data[0]),
                'partner_balance': data[1],
                'settle_timeout': settle_timeout,
            }

        raise ValueError('We [{}] are not a participant of the given channel ({}, {})'.format(
            pex(our_address),
            data[0],
            data[2],
        ))
示例#15
0
    def __init__(
            self,
            jsonrpc_client,
            secret_registry_address,
            contract_manager: ContractManager,
    ):
        if not is_binary_address(secret_registry_address):
            raise InvalidAddress('Expected binary address format for secret registry')

        self.contract_manager = contract_manager
        check_address_has_code(jsonrpc_client, secret_registry_address, CONTRACT_SECRET_REGISTRY)

        proxy = jsonrpc_client.new_contract_proxy(
            self.contract_manager.get_contract_abi(CONTRACT_SECRET_REGISTRY),
            to_normalized_address(secret_registry_address),
        )

        compare_contract_versions(
            proxy=proxy,
            expected_version=contract_manager.contracts_version,
            contract_name=CONTRACT_SECRET_REGISTRY,
            address=secret_registry_address,
        )

        self.address = secret_registry_address
        self.proxy = proxy
        self.client = jsonrpc_client
        self.node_address = privatekey_to_address(self.client.privkey)
        self.open_secret_transactions = dict()
示例#16
0
    def __init__(
            self,
            jsonrpc_client,
            discovery_address,
            contract_manager: ContractManager,
    ):
        contract = jsonrpc_client.new_contract(
            contract_manager.get_contract_abi(CONTRACT_ENDPOINT_REGISTRY),
            to_normalized_address(discovery_address),
        )
        proxy = ContractProxy(jsonrpc_client, contract)

        if not is_binary_address(discovery_address):
            raise ValueError('discovery_address must be a valid address')

        check_address_has_code(jsonrpc_client, discovery_address, 'Discovery')

        compare_contract_versions(
            proxy=proxy,
            expected_version=contract_manager.contracts_version,
            contract_name=CONTRACT_ENDPOINT_REGISTRY,
            address=discovery_address,
        )

        self.address = discovery_address
        self.node_address = privatekey_to_address(jsonrpc_client.privkey)
        self.client = jsonrpc_client
        self.not_found_address = NULL_ADDRESS
        self.proxy = proxy
def make_direct_transfer_from_channel(block_number, from_channel, partner_channel, amount, pkey):
    """ Helper to create and register a direct transfer from `from_channel` to
    `partner_channel`.
    """
    identifier = from_channel.get_next_nonce()

    direct_transfer_msg = from_channel.create_directtransfer(
        amount,
        identifier=identifier,
    )

    address = privatekey_to_address(pkey)
    sign_key = PrivateKey(pkey)
    direct_transfer_msg.sign(sign_key, address)

    # if this fails it's not the right key for the current `from_channel`
    assert direct_transfer_msg.sender == from_channel.our_state.address

    from_channel.register_transfer(
        block_number,
        direct_transfer_msg,
    )
    partner_channel.register_transfer(
        block_number,
        direct_transfer_msg,
    )

    return direct_transfer_msg
def test_close_accepts_only_transfer_from_participants(tester_channels, private_keys):
    """ Close must not accept a transfer signed by a non participant. """
    pkey0, _, nettingchannel, channel0, _ = tester_channels[0]
    nonparticipant_key = private_keys[2]
    opened_block = nettingchannel.opened(sender=pkey0)

    # make a transfer where pkey0 is the target
    transfer_nonparticipant = DirectTransfer(
        identifier=1,
        nonce=1 + (opened_block * (2 ** 32)),
        token=channel0.token_address,
        channel=channel0.channel_address,
        transferred_amount=10,
        recipient=channel0.our_address,
        locksroot=EMPTY_MERKLE_ROOT,
    )

    nonparticipant_address = privatekey_to_address(nonparticipant_key)
    nonparticipant_sign_key = PrivateKey(nonparticipant_key)

    transfer_nonparticipant.sign(nonparticipant_sign_key, nonparticipant_address)

    transfer_nonparticipant_hash = sha3(transfer_nonparticipant.packed().data[:-65])
    with pytest.raises(TransactionFailed):
        nettingchannel.close(
            transfer_nonparticipant.nonce,
            transfer_nonparticipant.transferred_amount,
            transfer_nonparticipant.locksroot,
            transfer_nonparticipant_hash,
            transfer_nonparticipant.signature,
            sender=pkey0,
        )
def test_close_wrong_channel(tester_channels):
    """ Close must not accept a transfer aimed at a different channel. """
    pkey0, pkey1, nettingchannel, channel0, _ = tester_channels[0]
    opened_block = nettingchannel.opened(sender=pkey0)
    wrong_address = make_address()

    # make a transfer where the recipient is totally wrong
    transfer_wrong_channel = DirectTransfer(
        identifier=1,
        nonce=1 + (opened_block * (2 ** 32)),
        token=channel0.token_address,
        channel=wrong_address,
        transferred_amount=10,
        recipient=channel0.our_address,
        locksroot=EMPTY_MERKLE_ROOT,
    )

    transfer_wrong_channel.sign(PrivateKey(pkey1), privatekey_to_address(pkey1))

    transfer_wrong_channel_hash = sha3(transfer_wrong_channel.packed().data[:-65])
    with pytest.raises(TransactionFailed):
        nettingchannel.close(
            transfer_wrong_channel.nonce,
            transfer_wrong_channel.transferred_amount,
            transfer_wrong_channel.locksroot,
            transfer_wrong_channel_hash,
            transfer_wrong_channel.signature,
            sender=pkey0,
        )
示例#20
0
def test_endpointregistry(private_keys, blockchain_services, contract_manager):
    chain = blockchain_services.blockchain_services[0]
    my_address = privatekey_to_address(private_keys[0])

    endpointregistry_address = deploy_contract_web3(
        contract_name=CONTRACT_ENDPOINT_REGISTRY,
        deploy_client=chain.client,
        contract_manager=contract_manager,
    )
    discovery_proxy = chain.discovery(endpointregistry_address)

    contract_discovery = ContractDiscovery(my_address, discovery_proxy)

    unregistered_address = make_address()

    # get should raise for unregistered addresses
    with pytest.raises(UnknownAddress):
        contract_discovery.get(my_address)

    with pytest.raises(UnknownAddress):
        contract_discovery.get(unregistered_address)

    contract_discovery.register(my_address, '127.0.0.1', 44444)
    assert contract_discovery.get(my_address) == ('127.0.0.1', 44444)

    contract_discovery.register(my_address, '127.0.0.1', 88888)
    assert contract_discovery.get(my_address) == ('127.0.0.1', 88888)

    with pytest.raises(UnknownAddress):
        contract_discovery.get(unregistered_address)
示例#21
0
def new_nettingcontract(
        our_key,
        partner_key,
        tester_chain,
        log_listener,
        channelmanager,
        settle_timeout):

    invalid_timeout = (
        settle_timeout < NETTINGCHANNEL_SETTLE_TIMEOUT_MIN or
        settle_timeout > NETTINGCHANNEL_SETTLE_TIMEOUT_MAX
    )
    if invalid_timeout:
        raise ValueError('settle_timeout must be in range [{}, {}]'.format(
            NETTINGCHANNEL_SETTLE_TIMEOUT_MIN, NETTINGCHANNEL_SETTLE_TIMEOUT_MAX
        ))

    netting_channel_address0_hex = channelmanager.newChannel(
        privatekey_to_address(partner_key),
        settle_timeout,
        sender=our_key,
    )
    tester_chain.mine(number_of_blocks=1)

    nettingchannel = create_nettingchannel_proxy(
        tester_chain,
        netting_channel_address0_hex,
        log_listener,
    )

    return nettingchannel
def test_endpointregistry(private_keys, blockchain_services):
    chain = blockchain_services.blockchain_services[0]
    my_address = privatekey_to_address(private_keys[0])

    endpointregistry_address = chain.deploy_contract(
        'EndpointRegistry',
        get_contract_path('EndpointRegistry.sol'),
    )
    discovery_proxy = chain.discovery(endpointregistry_address)

    contract_discovery = ContractDiscovery(my_address, discovery_proxy)

    unregistered_address = make_address()

    # get should raise for unregistered addresses
    with pytest.raises(UnknownAddress):
        contract_discovery.get(my_address)

    with pytest.raises(UnknownAddress):
        contract_discovery.get(unregistered_address)

    assert contract_discovery.nodeid_by_host_port(('127.0.0.1', 44444)) is None

    contract_discovery.register(my_address, '127.0.0.1', 44444)

    assert contract_discovery.nodeid_by_host_port(('127.0.0.1', 44444)) == my_address
    assert contract_discovery.get(my_address) == ('127.0.0.1', 44444)

    contract_discovery.register(my_address, '127.0.0.1', 88888)

    assert contract_discovery.nodeid_by_host_port(('127.0.0.1', 88888)) == my_address
    assert contract_discovery.get(my_address) == ('127.0.0.1', 88888)

    with pytest.raises(UnknownAddress):
        contract_discovery.get(unregistered_address)
示例#23
0
    def new_netting_channel(self, peer1, peer2, settle_timeout):
        """ Creates a new netting contract between peer1 and peer2.

        Raises:
            ValueError: If peer1 or peer2 is not a valid address.
        """
        if not isaddress(peer1):
            raise ValueError('The pee1 must be a valid address')

        if not isaddress(peer2):
            raise ValueError('The peer2 must be a valid address')

        if privatekey_to_address(self.private_key) == peer1:
            other = peer2
        else:
            other = peer1

        netting_channel_address_hex = self.proxy.newChannel(other, settle_timeout)
        self.tester_state.mine(number_of_blocks=1)

        channel = NettingChannelTesterMock(
            self.tester_state,
            self.private_key,
            netting_channel_address_hex,
        )

        return decode_hex(channel.address)
def geth_bare_genesis(genesis_path, private_keys, random_marker):
    """Writes a bare genesis to `genesis_path`.

    Args:
        genesis_path (str): the path in which the genesis block is written.
        private_keys list(str): iterable list of privatekeys whose corresponding accounts will
                    have a premined balance available.
    """

    account_addresses = [
        privatekey_to_address(key)
        for key in sorted(set(private_keys))
    ]

    alloc = {
        address_encoder(address): {
            'balance': DEFAULT_BALANCE_BIN,
        }
        for address in account_addresses
    }
    genesis = GENESIS_STUB.copy()
    genesis['alloc'].update(alloc)

    genesis['config']['clique'] = {'period': 1, 'epoch': 30000}

    genesis['extraData'] = clique_extradata(
        random_marker,
        address_encoder(account_addresses[0])[2:],
    )

    with open(genesis_path, 'w') as handler:
        json.dump(genesis, handler)
示例#25
0
    def __init__(
            self,
            jsonrpc_client,
            manager_address,
    ):
        if not is_binary_address(manager_address):
            raise InvalidAddress('Expected binary address format for token nework')

        check_address_has_code(jsonrpc_client, manager_address, CONTRACT_TOKEN_NETWORK)

        proxy = jsonrpc_client.new_contract_proxy(
            CONTRACT_MANAGER.get_contract_abi(CONTRACT_TOKEN_NETWORK),
            to_normalized_address(manager_address),
        )

        is_good_version = compare_versions(
            proxy.contract.functions.contract_version().call(),
            EXPECTED_CONTRACTS_VERSION,
        )
        if not is_good_version:
            raise ContractVersionMismatch('Incompatible ABI for TokenNetwork')

        self.address = manager_address
        self.proxy = proxy
        self.client = jsonrpc_client
        self.node_address = privatekey_to_address(self.client.privkey)
        self.open_channel_transactions = dict()

        # Forbids concurrent operations on the same channel
        self.channel_operations_lock = defaultdict(RLock)

        # Serializes concurent deposits on this token network. This must be an
        # exclusive lock, since we need to coordinate the approve and
        # setTotalDeposit calls.
        self.deposit_lock = Semaphore()
示例#26
0
def hostport_to_privkeyaddr(host, port):
    """ Return `(private key, address)` deterministically generated. """
    myip_port = '{}:{}'.format(host, port)
    privkey = sha3(myip_port.encode())
    addr = privatekey_to_address(privkey)

    return privkey, addr
示例#27
0
def test_token(
    deploy_client,
    token_proxy,
    private_keys,
    blockchain_rpc_ports,
    web3,
):
    privkey = private_keys[1]
    address = privatekey_to_address(privkey)
    address = to_canonical_address(address)
    other_client = JSONRPCClient(
        '0.0.0.0',
        blockchain_rpc_ports[0],
        privkey,
        web3=web3,
    )
    other_token_proxy = Token(
        other_client,
        to_canonical_address(token_proxy.proxy.contract.address),
    )

    # send some funds from deployer to generated address
    transfer_funds = 100
    token_proxy.transfer(address, transfer_funds)
    assert transfer_funds == token_proxy.balance_of(address)
    allow_funds = 100
    token_proxy.approve(address, allow_funds)
    assert allow_funds == token_proxy.proxy.contract.functions.allowance(
        to_checksum_address(deploy_client.sender),
        to_checksum_address(address),
    ).call()
    other_token_proxy.transfer(deploy_client.sender, transfer_funds)
    assert token_proxy.balance_of(address) == 0
def geth_wait_and_check(deploy_client, privatekeys, random_marker):
    """ Wait until the geth cluster is ready. """
    jsonrpc_running = False

    tries = 5
    while not jsonrpc_running and tries > 0:
        try:
            block = deploy_client.call('eth_getBlockByNumber', '0x0', True)
        except ConnectionError:
            gevent.sleep(0.5)
            tries -= 1
        else:
            jsonrpc_running = True
            running_marker = block['extraData'][2:len(random_marker) + 2]
            if running_marker != random_marker:
                raise RuntimeError(
                    'the test marker does not match, maybe two tests are running in '
                    'parallel with the same port?'
                )

    if jsonrpc_running is False:
        raise ValueError('geth didnt start the jsonrpc interface')

    for key in sorted(set(privatekeys)):
        address = address_encoder(privatekey_to_address(key))

        tries = 10
        balance = '0x0'
        while balance == '0x0' and tries > 0:
            balance = deploy_client.call('eth_getBalance', address, 'latest')
            gevent.sleep(1)
            tries -= 1

        if balance == '0x0':
            raise ValueError('account is with a balance of 0')
示例#29
0
def token_addresses(
        token_amount,
        number_of_tokens,
        private_keys,
        deploy_service,
        token_network_registry_address,
        register_tokens,
        contract_manager,
) -> typing.List[typing.Address]:
    """ Fixture that yields `number_of_tokens` ERC20 token addresses, where the
    `token_amount` (per token) is distributed among the addresses behind `deploy_client` and
    potentially pre-registered with the raiden Registry.
    The following arguments can control the behavior:

    Args:
        token_amount (int): the overall number of units minted per token
        number_of_tokens (int): the number of token instances
        register_tokens (bool): controls if tokens will be registered with raiden Registry
    """

    participants = [privatekey_to_address(key) for key in private_keys]
    token_addresses = deploy_tokens_and_fund_accounts(
        token_amount=token_amount,
        number_of_tokens=number_of_tokens,
        deploy_service=deploy_service,
        participants=participants,
        contract_manager=contract_manager,
    )

    if register_tokens:
        for token in token_addresses:
            deploy_service.token_network_registry(token_network_registry_address).add_token(token)

    return token_addresses
def create_node_configuration(miner=True,
                              port=30301,
                              rpcport=8101,
                              host='127.0.0.1',
                              node_key_seed=0):
    """
    Create configuration (ports, keys, etc...) for one node.

    :param miner: if True, setup to be a mining node
    :param port: the p2p port to assign
    :param rpcport: the port to assign
    :param host: the host for the node to run on
    :return: node configuration dict
    """
    node = dict()
    if miner:
        node['minerthreads'] = 1  # conservative
        node['unlock'] = 0
    node['nodekey'] = sha3('node:{}'.format(node_key_seed).encode())
    node['nodekeyhex'] = encode_hex(node['nodekey'])
    node['pub'] = encode_hex(privtopub_enode(node['nodekey']))
    node['address'] = privatekey_to_address(node['nodekey'])
    node['host'] = host
    node['port'] = port
    node['rpcport'] = rpcport
    node['enode'] = 'enode://{pub}@{host}:{port}'.format(**node)
    return node
示例#31
0
def cached_genesis(request, blockchain_type):
    """
    Deploy all contracts that are required by the fixtures into a tester and
    then serialize the accounts into a genesis block.

    Returns:
        dict: A dictionary representing the genesis block.
    """

    if not request.config.option.blockchain_cache:
        return

    if blockchain_type != 'geth':
        return

    # this will create the tester _and_ deploy the Registry
    deploy_key = request.getfixturevalue('deploy_key')
    private_keys = request.getfixturevalue('private_keys')
    registry, deploy_service, blockchain_services = _tester_services(
        deploy_key,
        private_keys,
        request.getfixturevalue('tester_blockgas_limit'),
    )

    registry_address = registry.address

    # create_network only registers the tokens,
    # the contracts must be deployed previously
    register = True
    participants = [
        privatekey_to_address(privatekey) for privatekey in private_keys
    ]
    token_contract_addresses = _token_addresses(
        request.getfixturevalue('token_amount'),
        request.getfixturevalue('number_of_tokens'), deploy_service, registry,
        participants, register)

    endpoint_discovery_address = deploy_service.deploy_contract(
        'EndpointRegistry',
        get_contract_path('EndpointRegistry.sol'),
    )

    endpoint_discovery_services = [
        ContractDiscovery(
            chain.node_address,
            chain.discovery(endpoint_discovery_address),
        ) for chain in blockchain_services
    ]

    raiden_apps = create_apps(
        blockchain_services,
        endpoint_discovery_services,
        registry_address,
        request.getfixturevalue('raiden_udp_ports'),
        DummyTransport,  # Do not use a UDP server to avoid port reuse in MacOSX
        request.getfixturevalue('reveal_timeout'),
        request.getfixturevalue('settle_timeout'),
        request.getfixturevalue('database_paths'),
        request.getfixturevalue('retry_interval'),
        request.getfixturevalue('retries_before_backoff'),
        request.getfixturevalue('throttle_capacity'),
        request.getfixturevalue('throttle_fill_rate'),
        request.getfixturevalue('nat_invitation_timeout'),
        request.getfixturevalue('nat_keepalive_retries'),
        request.getfixturevalue('nat_keepalive_timeout'),
    )

    if 'raiden_network' in request.fixturenames:
        create_network_channels(
            raiden_apps,
            token_contract_addresses,
            request.getfixturevalue('channels_per_node'),
            request.getfixturevalue('deposit'),
            request.getfixturevalue('settle_timeout'),
        )

    elif 'raiden_chain' in request.fixturenames:
        create_sequential_channels(
            raiden_apps,
            token_contract_addresses[0],
            request.getfixturevalue('channels_per_node'),
            request.getfixturevalue('deposit'),
            request.getfixturevalue('settle_timeout'),
        )

    # else: a test that is not creating channels

    for app in raiden_apps:
        app.stop(leave_channels=False)

    # save the state from the last block into a genesis dict
    tester = blockchain_services[0].tester_state
    tester.mine()

    genesis_alloc = dict()
    for account_address in tester.block.state.to_dict():
        account_alloc = tester.block.account_to_dict(account_address)

        # Both keys and values of the account storage associative array
        # must now be encoded with 64 hex digits
        if account_alloc['storage']:
            account_alloc['storage'] = fix_tester_storage(
                account_alloc['storage'])

        # code must be hex encoded with 0x prefix
        account_alloc['code'] = account_alloc.get('code', '')

        # account_to_dict returns accounts with nonce=0 and the nonce must
        # be encoded with 16 hex digits
        account_alloc['nonce'] = '0x%016x' % tester.block.get_nonce(
            account_address)

        genesis_alloc[account_address] = account_alloc

    all_keys = set(private_keys)
    all_keys.add(deploy_key)
    all_keys = sorted(all_keys)
    account_addresses = [privatekey_to_address(key) for key in all_keys]

    for address in account_addresses:
        genesis_alloc[address]['balance'] = DEFAULT_BALANCE_BIN

    alloc = {
        address_encoder(address_maybe_bin): data
        for address_maybe_bin, data in genesis_alloc.iteritems()
    }

    genesis = GENESIS_STUB.copy()
    genesis['config']['clique'] = {'period': 1, 'epoch': 30000}

    random_marker = request.getfixturevalue('random_marker')
    genesis['extraData'] = clique_extradata(
        random_marker,
        address_encoder(account_addresses[0])[2:],
    )
    genesis['alloc'] = alloc
    genesis['config']['defaultDiscoveryAddress'] = address_encoder(
        endpoint_discovery_address)
    genesis['config']['defaultRegistryAddress'] = address_encoder(
        registry_address)
    genesis['config']['tokenAddresses'] = [
        address_encoder(token_address)
        for token_address in token_contract_addresses
    ]

    return genesis
示例#32
0
def test_two_messages_mediated_transfer(deposit, settle_timeout, tester_state,
                                        tester_channels, tester_token,
                                        tester_events):

    privatekey0, privatekey1, nettingchannel, channel0, channel1 = tester_channels[
        0]
    address0 = privatekey_to_address(privatekey0)
    address1 = privatekey_to_address(privatekey1)
    unknow_key = tester.k3

    initial_balance0 = tester_token.balanceOf(address0, sender=privatekey0)
    initial_balance1 = tester_token.balanceOf(address1, sender=privatekey1)

    lock_amount0 = 29
    lock_expiration0 = tester_state.block.number + DEFAULT_REVEAL_TIMEOUT + 3
    hashlock0 = sha3(tester.k0)

    mediated_transfer0 = channel0.create_mediatedtransfer(
        transfer_initiator=address0,
        transfer_target=address1,
        fee=0,
        amount=lock_amount0,
        expiration=lock_expiration0,
        hashlock=hashlock0,
    )
    mediated_transfer0.sign(privatekey0)

    lock_amount1 = 29
    lock_expiration1 = tester_state.block.number + DEFAULT_REVEAL_TIMEOUT + 5
    hashlock1 = sha3(tester.k1)

    mediated_transfer1 = channel1.create_mediatedtransfer(
        transfer_initiator=address1,
        transfer_target=address0,
        fee=0,
        amount=lock_amount1,
        expiration=lock_expiration1,
        hashlock=hashlock1,
    )
    mediated_transfer1.sign(privatekey1)

    with pytest.raises(TransactionFailed):
        nettingchannel.close(
            str(mediated_transfer0.packed().data),
            str(mediated_transfer1.packed().data),
            sender=unknow_key,
        )

    previous_events = list(tester_events)
    nettingchannel.close(
        str(mediated_transfer0.packed().data),
        str(mediated_transfer1.packed().data),
        sender=privatekey0,
    )
    assert len(previous_events) + 1 == len(tester_events)

    block_number = tester_state.block.number

    close_event = tester_events[-1]
    assert close_event == {
        '_event_type': 'ChannelClosed',
        'closingAddress': encode_hex(address0),
        'blockNumber': block_number,
    }
    assert nettingchannel.closed(sender=privatekey0) == block_number
    assert nettingchannel.closingAddress(
        sender=privatekey0) == encode_hex(address0)

    tester_state.mine(number_of_blocks=settle_timeout + 1)

    previous_events = list(tester_events)
    nettingchannel.settle(sender=privatekey0)
    block_number = tester_state.block.number

    assert len(previous_events) + 3 == len(tester_events)

    transfer0_event = tester_events[-3]
    assert transfer0_event == {
        '_event_type': 'Transfer',
        '_from': nettingchannel.address,
        '_to': encode_hex(address0),
        '_value': deposit,
    }

    transfer1_event = tester_events[-2]
    assert transfer1_event == {
        '_event_type': 'Transfer',
        '_from': nettingchannel.address,
        '_to': encode_hex(address1),
        '_value': deposit,
    }

    settle_event = tester_events[-1]
    assert settle_event == {
        '_event_type': 'ChannelSettled',
        'blockNumber': block_number,
    }

    assert tester_token.balanceOf(
        address0, sender=privatekey0) == initial_balance0 + deposit  # noqa
    assert tester_token.balanceOf(
        address1, sender=privatekey1) == initial_balance1 + deposit  # noqa
    assert tester_token.balanceOf(nettingchannel.address,
                                  sender=privatekey1) == 0
示例#33
0
def test_new_netting_contract(raiden_network, token_amount, settle_timeout):
    # pylint: disable=line-too-long,too-many-statements,too-many-locals

    app0, app1, app2 = raiden_network
    peer0_address = app0.raiden.address
    peer1_address = app1.raiden.address
    peer2_address = app2.raiden.address

    blockchain_service0 = app0.raiden.chain

    token_address = blockchain_service0.deploy_and_register_token(
        contract_name='HumanStandardToken',
        contract_file='HumanStandardToken.sol',
        constructor_parameters=(token_amount, 'raiden', 2, 'Rd'),
    )

    token0 = blockchain_service0.token(token_address)
    for transfer_to in raiden_network[1:]:
        token0.transfer(
            privatekey_to_address(transfer_to.raiden.privkey),
            token_amount // len(raiden_network),
        )

    manager0 = blockchain_service0.manager_by_token(token_address)

    # sanity
    assert manager0.channels_addresses() == []
    assert manager0.channels_by_participant(peer0_address) == []
    assert manager0.channels_by_participant(peer1_address) == []
    assert manager0.channels_by_participant(peer2_address) == []

    # create one channel
    netting_address_01 = manager0.new_netting_channel(
        peer0_address,
        peer1_address,
        settle_timeout,
    )

    # check contract state
    netting_channel_01 = blockchain_service0.netting_channel(
        netting_address_01)
    assert netting_channel_01.isopen() is False
    assert netting_channel_01.partner(peer0_address) == peer1_address
    assert netting_channel_01.partner(peer1_address) == peer0_address

    # check channels
    channel_list = manager0.channels_addresses()
    assert sorted(channel_list[0]) == sorted([peer0_address, peer1_address])

    assert manager0.channels_by_participant(peer0_address) == [
        netting_address_01
    ]
    assert manager0.channels_by_participant(peer1_address) == [
        netting_address_01
    ]
    assert manager0.channels_by_participant(peer2_address) == []

    # create other chanel
    netting_address_02 = manager0.new_netting_channel(
        peer0_address,
        peer2_address,
        settle_timeout,
    )

    netting_channel_02 = blockchain_service0.netting_channel(
        netting_address_02)

    assert netting_channel_02.isopen() is False
    assert netting_channel_02.partner(peer0_address) == peer2_address
    assert netting_channel_02.partner(peer2_address) == peer0_address

    channel_list = manager0.channels_addresses()
    expected_channels = [
        sorted([peer0_address, peer1_address]),
        sorted([peer0_address, peer2_address]),
    ]

    for channel in channel_list:
        assert sorted(channel) in expected_channels

    result0 = sorted(manager0.channels_by_participant(peer0_address))
    result1 = sorted([netting_address_01, netting_address_02])
    assert result0 == result1
    assert manager0.channels_by_participant(peer1_address) == [
        netting_address_01
    ]
    assert manager0.channels_by_participant(peer2_address) == [
        netting_address_02
    ]

    # deposit without approve should fail
    netting_channel_01.deposit(peer0_address, 100)
    assert netting_channel_01.isopen() is False
    assert netting_channel_02.isopen() is False
    assert netting_channel_01.detail(peer0_address)['our_balance'] == 0
    assert netting_channel_01.detail(peer1_address)['our_balance'] == 0

    # single-funded channel
    app0.raiden.chain.token(token_address).approve(netting_address_01, 100)
    netting_channel_01.deposit(peer0_address, 100)
    assert netting_channel_01.isopen() is True
    assert netting_channel_02.isopen() is False

    assert netting_channel_01.detail(peer0_address)['our_balance'] == 100
    assert netting_channel_01.detail(peer1_address)['our_balance'] == 0

    # double-funded channel
    app0.raiden.chain.token(token_address).approve(netting_address_02, 70)
    netting_channel_02.deposit(peer0_address, 70)
    assert netting_channel_01.isopen() is True
    assert netting_channel_02.isopen() is True

    assert netting_channel_02.detail(peer0_address)['our_balance'] == 70
    assert netting_channel_02.detail(peer2_address)['our_balance'] == 0

    app2.raiden.chain.token(token_address).approve(netting_address_02, 130)
    app2.raiden.chain.netting_channel(netting_address_02).deposit(
        peer2_address, 130)
    assert netting_channel_01.isopen() is True
    assert netting_channel_02.isopen() is True

    assert netting_channel_02.detail(peer0_address)['our_balance'] == 70
    assert netting_channel_02.detail(peer2_address)['our_balance'] == 130
示例#34
0
def test_withdraw_at_settlement_block(deposit, settle_timeout,
                                      tester_nettingcontracts, tester_chain,
                                      tester_token):
    """ It must be possible to unlock a lock up to and including the settlment
    block.
    """

    pkey0, pkey1, nettingchannel = tester_nettingcontracts[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)

    lock_amount = 31
    lock_expiration = tester_chain.block.number + settle_timeout
    secret = b'settlementsettlementsettlementse'
    hashlock = sha3(secret)

    lock0 = Lock(
        amount=lock_amount,
        expiration=lock_expiration,
        hashlock=hashlock,
    )
    lock0_bytes = bytes(lock0.as_bytes)
    lock0_hash = sha3(lock0_bytes)

    opened_block = nettingchannel.opened(sender=pkey0)
    nonce = 1 + (opened_block * (2**32))

    mediated0 = MediatedTransfer(
        identifier=1,
        nonce=nonce,
        token=tester_token.address,
        channel=normalize_address(nettingchannel.address),
        transferred_amount=0,
        recipient=address1,
        locksroot=lock0_hash,
        lock=lock0,
        target=address1,
        initiator=address0,
        fee=0,
    )

    sign_key0 = PrivateKey(pkey0)
    mediated0.sign(sign_key0, address0)

    mediated0_hash = sha3(mediated0.packed().data[:-65])
    nettingchannel.close(
        mediated0.nonce,
        mediated0.transferred_amount,
        mediated0.locksroot,
        mediated0_hash,
        mediated0.signature,
        sender=pkey1,
    )

    block_until_settlement_end = lock_expiration - tester_chain.block.number
    tester_chain.mine(number_of_blocks=block_until_settlement_end)

    assert lock_expiration == tester_chain.block.number
    nettingchannel.withdraw(
        lock0_bytes,
        b'',  # the lock itself it the root, the proof is empty
        secret,
        sender=pkey1,
    )

    tester_chain.mine(number_of_blocks=1)
    nettingchannel.settle(sender=pkey0)

    balance0 = initial_balance0 + deposit - lock0.amount
    balance1 = initial_balance1 + deposit + lock0.amount
    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
示例#35
0
def channel_from_nettingcontract(our_key, netting_contract, reveal_timeout):
    """ Create a `channel.Channel` for the `netting_contract`.

    Use this to make sure that both implementations (the smart contract and the
    python code) work in tandem."""
    our_address = privatekey_to_address(our_key)

    token_address_hex = netting_contract.tokenAddress(sender=our_key)
    settle_timeout = netting_contract.settleTimeout(sender=our_key)

    address_balance = netting_contract.addressAndBalance(sender=our_key)
    address1_hex, balance1, address2_hex, balance2 = address_balance

    opened_block_number = netting_contract.opened(sender=our_key)
    closed_block_number = netting_contract.closed(sender=our_key)
    settled_block_number = None

    identifier = address_decoder(netting_contract.address)
    token_address = normalize_address(token_address_hex)
    address1 = normalize_address(address1_hex)
    address2 = normalize_address(address2_hex)

    if our_address == address1:
        our_balance = balance1
        partner_address = address2
        partner_balance = balance2
    else:
        our_balance = balance2
        partner_address = address1
        partner_balance = balance1

    our_state = NettingChannelEndState(
        our_address,
        our_balance,
    )
    partner_state = NettingChannelEndState(
        partner_address,
        partner_balance,
    )

    open_transaction = TransactionExecutionStatus(
        None,
        opened_block_number,
        TransactionExecutionStatus.SUCCESS,
    )

    close_transaction = None
    if closed_block_number:
        close_transaction = TransactionExecutionStatus(
            None,
            closed_block_number,
            TransactionExecutionStatus.SUCCESS,
        )

    settle_transaction = None
    if settled_block_number:
        settle_transaction = TransactionExecutionStatus(
            None,
            settled_block_number,
            TransactionExecutionStatus.SUCCESS,
        )

    channel = NettingChannelState(
        identifier,
        token_address,
        reveal_timeout,
        settle_timeout,
        our_state,
        partner_state,
        open_transaction,
        close_transaction,
        settle_transaction,
    )

    return channel
示例#36
0
def test_withdraw_both_participants(
        deposit,
        settle_timeout,
        reveal_timeout,
        tester_channels,
        tester_chain,
        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)

    secret = b'secretsecretsecretsecretsecretse'
    hashlock = sha3(secret)

    lock_amount = 31
    lock01_expiration = tester_chain.block.number + settle_timeout - 1 * reveal_timeout
    lock10_expiration = tester_chain.block.number + settle_timeout - 2 * reveal_timeout

    new_block = Block(tester_chain.block.number)
    channel0.state_transition(new_block)
    channel1.state_transition(new_block)

    # using the same hashlock and amount is intentional
    lock01 = Lock(lock_amount, lock01_expiration, hashlock)
    lock10 = Lock(lock_amount, lock10_expiration, hashlock)

    mediated01 = make_mediated_transfer(
        channel0,
        channel1,
        address0,
        address1,
        lock01,
        pkey0,
        tester_chain.block.number,
        secret,
    )

    mediated10 = make_mediated_transfer(
        channel1,
        channel0,
        address1,
        address0,
        lock10,
        pkey1,
        tester_chain.block.number,
        secret,
    )

    mediated01_hash = sha3(mediated01.packed().data[:-65])
    nettingchannel.close(
        mediated01.nonce,
        mediated01.transferred_amount,
        mediated01.locksroot,
        mediated01_hash,
        mediated01.signature,
        sender=pkey1,
    )
    tester_chain.mine(number_of_blocks=1)

    mediated10_hash = sha3(mediated10.packed().data[:-65])
    nettingchannel.updateTransfer(
        mediated10.nonce,
        mediated10.transferred_amount,
        mediated10.locksroot,
        mediated10_hash,
        mediated10.signature,
        sender=pkey0,
    )
    tester_chain.mine(number_of_blocks=1)

    proof01 = channel1.partner_state.compute_proof_for_lock(
        secret,
        mediated01.lock,
    )
    nettingchannel.withdraw(
        proof01.lock_encoded,
        b''.join(proof01.merkle_proof),
        proof01.secret,
        sender=pkey1,
    )

    proof10 = channel0.partner_state.compute_proof_for_lock(
        secret,
        mediated10.lock,
    )
    nettingchannel.withdraw(
        proof10.lock_encoded,
        b''.join(proof10.merkle_proof),
        proof10.secret,
        sender=pkey0,
    )

    tester_chain.mine(number_of_blocks=settle_timeout + 1)
    nettingchannel.settle(sender=pkey0)

    balance0 = initial_balance0 + deposit - lock01.amount + lock10.amount
    balance1 = initial_balance1 + deposit + lock01.amount - lock10.amount
    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
示例#37
0
    def register_endpoint(self, node_address, endpoint):
        if node_address != privatekey_to_address(self.private_key):
            raise ValueError('node_address doesnt match this node address')

        self.proxy.registerEndpoint(endpoint)
        self.tester_state.mine(number_of_blocks=1)
示例#38
0
def test_unlock(reveal_timeout, tester_token, tester_channels, tester_events,
                tester_state):
    privatekey0_raw, privatekey1_raw, nettingchannel, channel0, channel1 = tester_channels[
        0]
    privatekey0 = PrivateKey(privatekey0_raw, ctx=GLOBAL_CTX, raw=True)
    address0 = privatekey_to_address(privatekey0_raw)

    target = tester.a0
    initiator = tester.a1

    lock_amount0 = 5
    lock_timeout0 = reveal_timeout + 5
    lock_expiration0 = tester_state.block.number + lock_timeout0
    secret0 = 'expiredlockexpiredlockexpiredloc'
    lock_hashlock0 = sha3(secret0)
    mediated_transfer0 = channel0.create_mediatedtransfer(
        transfer_initiator=initiator,
        transfer_target=target,
        fee=0,
        amount=lock_amount0,
        identifier=1,  # TODO: fill in identifier
        expiration=lock_expiration0,
        hashlock=lock_hashlock0,
    )
    mediated_transfer0.sign(privatekey0, address0)

    channel0.register_transfer(mediated_transfer0)
    channel1.register_transfer(mediated_transfer0)

    # expire the first lock
    tester_state.mine(number_of_blocks=lock_timeout0 + 1)

    lock_amount1 = 5
    lock_timeout1 = reveal_timeout + 3
    lock_expiration1 = tester_state.block.number + lock_timeout1
    secret1 = 'secretsecretsecretsecretsecretse'
    lock_hashlock1 = sha3(secret1)
    mediated_transfer1 = channel0.create_mediatedtransfer(
        transfer_initiator=initiator,
        transfer_target=target,
        fee=0,
        amount=lock_amount1,
        identifier=1,  # TODO: fill in identifier
        expiration=lock_expiration1,
        hashlock=lock_hashlock1,
    )
    mediated_transfer1.sign(privatekey0, address0)
    mediated_transfer1_data = str(mediated_transfer1.packed().data)

    channel0.register_transfer(mediated_transfer1)
    channel1.register_transfer(mediated_transfer1)

    channel1.register_secret(secret1)

    nettingchannel.close(
        mediated_transfer1_data,
        "",
        sender=privatekey1_raw,
    )

    unlockproof0 = channel1.our_state.balance_proof.compute_proof_for_lock(
        secret0,
        mediated_transfer0.lock,
    )

    # expiration has passed, should fail
    with pytest.raises(TransactionFailed):
        nettingchannel.unlock(
            str(unlockproof0.lock_encoded),
            ''.join(unlockproof0.merkle_proof),
            unlockproof0.secret,
            sender=privatekey1_raw,
        )

    unlock_proofs = list(channel1.our_state.balance_proof.get_known_unlocks())

    assert len(unlock_proofs) == 1

    channel1.external_state.unlock(channel1.our_state.address, unlock_proofs)

    # already unlock, shoud fail
    with pytest.raises(TransactionFailed):
        proof = unlock_proofs[0]

        nettingchannel.unlock(
            proof.lock_encoded,
            ''.join(proof.merkle_proof),
            proof.secret,
            sender=privatekey0_raw,
        )
示例#39
0
def test_update_mediated_transfer(settle_timeout, reveal_timeout, tester_state,
                                  tester_channels, tester_events):
    privatekey0_raw, privatekey1_raw, nettingchannel, channel0, channel1 = tester_channels[
        0]
    privatekey0 = PrivateKey(privatekey0_raw, ctx=GLOBAL_CTX, raw=True)
    privatekey1 = PrivateKey(privatekey1_raw, ctx=GLOBAL_CTX, raw=True)
    address0 = privatekey_to_address(privatekey0_raw)
    address1 = privatekey_to_address(privatekey1_raw)

    transfer_amount = 3
    direct_transfer0 = channel0.create_directtransfer(
        transfer_amount,
        1  # TODO: fill in identifier
    )
    direct_transfer0.sign(privatekey0, address0)
    direct_transfer0_data = str(direct_transfer0.packed().data)

    channel0.register_transfer(direct_transfer0)
    channel1.register_transfer(direct_transfer0)

    target = tester.a0
    initiator = tester.a1
    lock_amount = 5
    lock_expiration = tester_state.block.number + reveal_timeout + 3
    lock_hashlock = sha3('secret')
    mediated_transfer0 = channel0.create_mediatedtransfer(
        transfer_initiator=initiator,
        transfer_target=target,
        fee=0,
        amount=lock_amount,
        identifier=1,  # TODO: fill in identifier
        expiration=lock_expiration,
        hashlock=lock_hashlock,
    )
    mediated_transfer0.sign(privatekey0, address0)
    mediated_transfer0_data = str(mediated_transfer0.packed().data)

    channel0.register_transfer(mediated_transfer0)
    channel1.register_transfer(mediated_transfer0)

    transfer_amount = 13
    direct_transfer1 = channel1.create_directtransfer(
        transfer_amount,
        1  # TODO: fill in identifier
    )
    direct_transfer1.sign(privatekey1, address1)
    direct_transfer1_data = str(direct_transfer1.packed().data)

    channel0.register_transfer(direct_transfer1)
    channel1.register_transfer(direct_transfer1)

    nettingchannel.close(
        direct_transfer0_data,
        direct_transfer1_data,
        sender=privatekey1_raw,
    )

    nettingchannel.updateTransfer(
        mediated_transfer0_data,
        sender=privatekey0_raw,
    )

    tester_state.mine(number_of_blocks=settle_timeout + 1)
示例#40
0
def test_update_direct_transfer(settle_timeout, tester_state, tester_channels,
                                tester_events):
    privatekey0_raw, privatekey1_raw, nettingchannel, channel0, channel1 = tester_channels[
        0]
    privatekey0 = PrivateKey(privatekey0_raw, ctx=GLOBAL_CTX, raw=True)
    privatekey1 = PrivateKey(privatekey1_raw, ctx=GLOBAL_CTX, raw=True)
    address0 = privatekey_to_address(privatekey0_raw)
    address1 = privatekey_to_address(privatekey1_raw)

    transfer_amount = 3
    first_direct_transfer0 = channel0.create_directtransfer(
        transfer_amount,
        1  # TODO: fill in identifier
    )
    first_direct_transfer0.sign(privatekey0, address0)
    first_direct_transfer0_data = str(first_direct_transfer0.packed().data)

    channel0.register_transfer(first_direct_transfer0)
    channel1.register_transfer(first_direct_transfer0)

    transfer_amount = 5
    second_direct_transfer0 = channel0.create_directtransfer(
        transfer_amount,
        1  # TODO: fill in identifier
    )
    second_direct_transfer0.sign(privatekey0, address0)
    second_direct_transfer0_data = str(second_direct_transfer0.packed().data)

    channel0.register_transfer(second_direct_transfer0)
    channel1.register_transfer(second_direct_transfer0)

    transfer_amount = 7
    third_direct_transfer0 = channel0.create_directtransfer(
        transfer_amount,
        1  # TODO: fill in identifier
    )
    third_direct_transfer0.sign(privatekey0, address0)
    third_direct_transfer0_data = str(third_direct_transfer0.packed().data)

    channel0.register_transfer(third_direct_transfer0)
    channel1.register_transfer(third_direct_transfer0)

    transfer_amount = 11
    fourth_direct_transfer0 = channel0.create_directtransfer(
        transfer_amount,
        1  # TODO: fill in identifier
    )
    fourth_direct_transfer0.sign(privatekey0, address0)
    fourth_direct_transfer0_data = str(fourth_direct_transfer0.packed().data)

    channel0.register_transfer(fourth_direct_transfer0)
    channel1.register_transfer(fourth_direct_transfer0)

    transfer_amount = 13
    direct_transfer1 = channel1.create_directtransfer(
        transfer_amount,
        1  # TODO: fill in identifier
    )
    direct_transfer1.sign(privatekey1, address1)
    direct_transfer1_data = str(direct_transfer1.packed().data)

    channel0.register_transfer(direct_transfer1)
    channel1.register_transfer(direct_transfer1)

    # not yet closed
    with pytest.raises(TransactionFailed):
        nettingchannel.updateTransfer(
            second_direct_transfer0_data,
            sender=privatekey0_raw,
        )

    nettingchannel.close(
        second_direct_transfer0_data,
        direct_transfer1_data,
        sender=privatekey1_raw,
    )

    # who closes the channel cannot call updateTransfer
    with pytest.raises(TransactionFailed):
        nettingchannel.updateTransfer(
            third_direct_transfer0_data,
            sender=privatekey1_raw,
        )

    # nonce too low
    with pytest.raises(TransactionFailed):
        nettingchannel.updateTransfer(
            first_direct_transfer0_data,
            sender=privatekey0_raw,
        )

    nettingchannel.updateTransfer(
        third_direct_transfer0_data,
        sender=privatekey0_raw,
    )

    transfer1_event = tester_events[-1]
    assert transfer1_event == {
        '_event_type': 'TransferUpdated',
        'node_address': address0.encode('hex'),
        'block_number': tester_state.block.number,
    }

    tester_state.mine(number_of_blocks=settle_timeout + 1)

    # settle time passed
    with pytest.raises(TransactionFailed):
        nettingchannel.updateTransfer(
            fourth_direct_transfer0_data,
            sender=privatekey0_raw,
        )
示例#41
0
def test_close_settle(deposit, settle_timeout, tester_state, tester_channels,
                      tester_events, tester_token):

    privatekey0_raw, privatekey1_raw, nettingchannel, channel0, channel1 = tester_channels[
        0]
    privatekey0 = PrivateKey(privatekey0_raw, ctx=GLOBAL_CTX, raw=True)
    privatekey1 = PrivateKey(privatekey1_raw, ctx=GLOBAL_CTX, raw=True)
    address0 = privatekey_to_address(privatekey0_raw)
    address1 = privatekey_to_address(privatekey1_raw)
    unknown_key = tester.k3

    initial_balance0 = tester_token.balanceOf(address0, sender=privatekey0_raw)
    initial_balance1 = tester_token.balanceOf(address1, sender=privatekey1_raw)

    transfer_amount0 = 10
    direct_transfer0 = channel0.create_directtransfer(
        transfer_amount0,
        1  # TODO: fill in identifier
    )
    direct_transfer0.sign(privatekey0, address0)

    transfer_amount1 = 30
    direct_transfer1 = channel1.create_directtransfer(
        transfer_amount1,
        1  # TODO: fill in identifier
    )
    direct_transfer1.sign(privatekey1, address1)

    # random people can't close the channel
    with pytest.raises(TransactionFailed):
        nettingchannel.close(
            str(direct_transfer0.packed().data),
            str(direct_transfer1.packed().data),
            sender=unknown_key,
        )
    # the closing party should be the one that provides the first transfer
    with pytest.raises(TransactionFailed):
        nettingchannel.close(
            str(direct_transfer0.packed().data),
            str(direct_transfer1.packed().data),
            sender=privatekey0_raw,
        )

    previous_events = list(tester_events)
    nettingchannel.close(
        str(direct_transfer0.packed().data),
        str(direct_transfer1.packed().data),
        sender=privatekey1_raw,
    )
    assert len(previous_events) + 1 == len(tester_events)

    block_number = tester_state.block.number

    close_event = tester_events[-1]
    assert close_event == {
        '_event_type': 'ChannelClosed',
        'closing_address': encode_hex(address1),
        'block_number': block_number,
    }

    assert nettingchannel.closed(sender=privatekey0_raw) == block_number
    assert nettingchannel.closingAddress(
        sender=privatekey0_raw) == encode_hex(address1)

    tester_state.mine(number_of_blocks=settle_timeout + 1)

    previous_events = list(tester_events)
    nettingchannel.settle(sender=privatekey0_raw)
    assert len(previous_events) + 3 == len(tester_events)

    block_number = tester_state.block.number

    transfer0_event = tester_events[-3]
    assert transfer0_event == {
        '_event_type': 'Transfer',
        '_from': nettingchannel.address,
        '_to': encode_hex(address0),
        '_value': deposit - transfer_amount0 + transfer_amount1,
    }

    transfer1_event = tester_events[-2]
    assert transfer1_event == {
        '_event_type': 'Transfer',
        '_from': nettingchannel.address,
        '_to': encode_hex(address1),
        '_value': deposit + transfer_amount0 - transfer_amount1,
    }

    settle_event = tester_events[-1]
    assert settle_event == {
        '_event_type': 'ChannelSettled',
        'block_number': block_number,
    }

    assert tester_token.balanceOf(
        address0, sender=privatekey0_raw
    ) == initial_balance0 + deposit - transfer_amount0 + transfer_amount1  # noqa
    assert tester_token.balanceOf(
        address1, sender=privatekey1_raw
    ) == initial_balance1 + deposit + transfer_amount0 - transfer_amount1  # noqa
    assert tester_token.balanceOf(nettingchannel.address,
                                  sender=privatekey1_raw) == 0
示例#42
0
def test_closewithouttransfer_settle(deposit, settle_timeout, tester_state,
                                     tester_events, tester_nettingcontracts,
                                     tester_token):

    privatekey0, privatekey1, nettingchannel = tester_nettingcontracts[0]
    address0 = privatekey_to_address(privatekey0)
    address1 = privatekey_to_address(privatekey1)
    unknown_key = tester.k3

    initial_balance0 = tester_token.balanceOf(address0, sender=privatekey0)
    initial_balance1 = tester_token.balanceOf(address1, sender=privatekey1)

    with pytest.raises(TransactionFailed):
        nettingchannel.close(sender=unknown_key)

    previous_events = list(tester_events)
    nettingchannel.close("", "", sender=privatekey0)
    assert len(previous_events) + 1 == len(tester_events)

    block_number = tester_state.block.number

    close_event = tester_events[-1]
    assert close_event == {
        '_event_type': 'ChannelClosed',
        'closing_address': encode_hex(address0),
        'block_number': block_number,
    }

    assert nettingchannel.closed(sender=privatekey0) == block_number
    assert nettingchannel.closingAddress(
        sender=privatekey0) == encode_hex(address0)

    tester_state.mine(number_of_blocks=settle_timeout + 1)

    previous_events = list(tester_events)
    # Anyone can call settle(), not just channel participants
    nettingchannel.settle(sender=unknown_key)
    block_number = tester_state.block.number

    assert len(previous_events) + 3 == len(tester_events)

    transfer0_event = tester_events[-3]
    assert transfer0_event == {
        '_event_type': 'Transfer',
        '_from': nettingchannel.address,
        '_to': encode_hex(address1),
        '_value': deposit,
    }

    transfer1_event = tester_events[-2]
    assert transfer1_event == {
        '_event_type': 'Transfer',
        '_from': nettingchannel.address,
        '_to': encode_hex(address0),
        '_value': deposit,
    }

    settle_event = tester_events[-1]
    assert settle_event == {
        '_event_type': 'ChannelSettled',
        'block_number': block_number,
    }

    assert tester_token.balanceOf(
        address0, sender=privatekey0) == initial_balance0 + deposit
    assert tester_token.balanceOf(
        address1, sender=privatekey1) == initial_balance1 + deposit
    assert tester_token.balanceOf(nettingchannel.address,
                                  sender=privatekey1) == 0
示例#43
0
def geth_create_blockchain(deploy_key,
                           private_keys,
                           blockchain_private_keys,
                           rpc_ports,
                           p2p_ports,
                           base_datadir,
                           verbosity,
                           genesis_path=None,
                           logdirectory=None):
    # pylint: disable=too-many-locals,too-many-statements,too-many-arguments

    nodes_configuration = []
    key_p2p_rpc = zip(blockchain_private_keys, p2p_ports, rpc_ports)

    for pos, (key, p2p_port, rpc_port) in enumerate(key_p2p_rpc):
        config = dict()

        address = privatekey_to_address(key)
        # make the first node miner
        if pos == 0:
            config['unlock'] = 0

        config['nodekey'] = key
        config['nodekeyhex'] = encode_hex(key)
        config['pub'] = encode_hex(privtopub(key))
        config['address'] = address
        config['port'] = p2p_port
        config['rpcport'] = rpc_port
        config['enode'] = 'enode://{pub}@127.0.0.1:{port}'.format(
            pub=config['pub'],
            port=config['port'],
        )
        nodes_configuration.append(config)

    for config in nodes_configuration:
        config['bootnodes'] = ','.join(node['enode']
                                       for node in nodes_configuration)

    all_keys = set(private_keys)
    all_keys.add(deploy_key)
    all_keys = sorted(all_keys)

    cmds = []
    for i, config in enumerate(nodes_configuration):
        # HACK: Use only the first 8 characters to avoid golang's issue
        # https://github.com/golang/go/issues/6895 (IPC bind fails with path
        # longer than 108 characters).
        nodekey_part = config['nodekeyhex'][:8]
        nodedir = os.path.join(base_datadir, nodekey_part)
        node_genesis_path = os.path.join(nodedir, 'custom_genesis.json')

        assert len(nodedir + '/geth.ipc') < 108, 'geth data path is too large'

        os.makedirs(nodedir)

        if genesis_path is None:
            geth_bare_genesis(node_genesis_path, all_keys)
        else:
            shutil.copy(genesis_path, node_genesis_path)

        geth_init_datadir(nodedir, node_genesis_path)

        if 'unlock' in config:
            geth_create_account(nodedir, all_keys[i])

        commandline = geth_to_cmd(config, nodedir, verbosity)
        cmds.append(commandline)

    # save current term settings before running geth
    if isinstance(sys.stdin,
                  file):  # check that the test is running on non-capture mode
        term_settings = termios.tcgetattr(sys.stdin)

    stdout = None
    stderr = None
    processes_list = []
    for pos, cmd in enumerate(cmds):
        if logdirectory:
            log_path = os.path.join(logdirectory, str(pos))
            logfile = open(log_path, 'w')

            stdout = logfile
            stderr = logfile

        if '--unlock' in cmd:
            cmd.append('--mine')
            process = subprocess.Popen(
                cmd,
                universal_newlines=True,
                stdin=subprocess.PIPE,
                stdout=stdout,
                stderr=stderr,
            )

            # --password wont work, write password to unlock
            process.stdin.write(DEFAULT_PASSPHRASE + os.linesep)  # Passphrase:
            process.stdin.write(DEFAULT_PASSPHRASE +
                                os.linesep)  # Repeat passphrase:
        else:
            process = subprocess.Popen(
                cmd,
                universal_newlines=True,
                stdout=stdout,
                stderr=stderr,
            )

        processes_list.append(process)
        assert process.returncode is None

    geth_wait_and_check(private_keys, rpc_ports)

    # reenter echo mode (disabled by geth pasphrase prompt)
    if isinstance(sys.stdin, file):
        termios.tcsetattr(sys.stdin, termios.TCSADRAIN, term_settings)

    return processes_list
示例#44
0
UNIT_CHANNEL_ADDRESS = b'channelchannelchanne'

UNIT_TRANSFER_IDENTIFIER = 37
UNIT_TRANSFER_INITIATOR = b'initiatorinitiatorin'
UNIT_TRANSFER_TARGET = b'targettargettargetta'
UNIT_TRANSFER_DESCRIPTION = TransferDescriptionWithSecretState(
    UNIT_TRANSFER_IDENTIFIER,
    UNIT_TRANSFER_AMOUNT,
    UNIT_TOKEN_NETWORK_ADDRESS,
    UNIT_TRANSFER_INITIATOR,
    UNIT_TRANSFER_TARGET,
    UNIT_SECRET,
)
UNIT_TRANSFER_PKEY_BIN = sha3(b'transfer pkey')
UNIT_TRANSFER_PKEY = PrivateKey(UNIT_TRANSFER_PKEY_BIN)
UNIT_TRANSFER_SENDER = privatekey_to_address(sha3(b'transfer pkey'))

HOP1_KEY = PrivateKey(b'11111111111111111111111111111111')
HOP2_KEY = PrivateKey(b'22222222222222222222222222222222')
HOP3_KEY = PrivateKey(b'33333333333333333333333333333333')
HOP4_KEY = PrivateKey(b'44444444444444444444444444444444')
HOP5_KEY = PrivateKey(b'55555555555555555555555555555555')
HOP6_KEY = PrivateKey(b'66666666666666666666666666666666')
HOP1 = privatekey_to_address(b'11111111111111111111111111111111')
HOP2 = privatekey_to_address(b'22222222222222222222222222222222')
HOP3 = privatekey_to_address(b'33333333333333333333333333333333')
HOP4 = privatekey_to_address(b'44444444444444444444444444444444')
HOP5 = privatekey_to_address(b'55555555555555555555555555555555')
HOP6 = privatekey_to_address(b'66666666666666666666666666666666')

ADDR = b'addraddraddraddraddr'
示例#45
0
def web3(
    blockchain_p2p_ports,
    blockchain_private_keys,
    blockchain_rpc_ports,
    blockchain_type,
    deploy_key,
    private_keys,
    random_marker,
    request,
    tmpdir,
    chain_id,
):
    """ Starts a private chain with accounts funded. """
    # include the deploy key in the list of funded accounts
    keys_to_fund = set(private_keys)
    keys_to_fund.add(deploy_key)
    keys_to_fund = sorted(keys_to_fund)

    if blockchain_type == 'geth':
        host = '0.0.0.0'
        rpc_port = blockchain_rpc_ports[0]
        endpoint = f'http://{host}:{rpc_port}'
        web3 = Web3(HTTPProvider(endpoint))

        assert len(blockchain_private_keys) == len(blockchain_rpc_ports)
        assert len(blockchain_private_keys) == len(blockchain_p2p_ports)

        geth_nodes = [
            GethNodeDescription(
                key,
                rpc,
                p2p,
                miner=(pos == 0),
            ) for pos, (key, rpc, p2p) in enumerate(
                zip(
                    blockchain_private_keys,
                    blockchain_rpc_ports,
                    blockchain_p2p_ports,
                ))
        ]

        accounts_to_fund = [privatekey_to_address(key) for key in keys_to_fund]

        geth_processes = geth_run_private_blockchain(
            web3,
            accounts_to_fund,
            geth_nodes,
            str(tmpdir),
            chain_id,
            request.config.option.verbose,
            random_marker,
        )

        yield web3

        for process in geth_processes:
            process.terminate()

        cleanup_tasks()

    else:
        raise ValueError(f'unknown blockchain_type {blockchain_type}')
示例#46
0
    CONTRACT_SECRET_REGISTRY,
    CONTRACT_TOKEN_NETWORK_REGISTRY,
    NETWORKNAME_TO_ID,
    TEST_SETTLE_TIMEOUT_MAX,
    TEST_SETTLE_TIMEOUT_MIN,
)
from raiden_contracts.contract_manager import ContractManager, contracts_precompiled_path

# the smoketest will assert that a different endpoint got successfully registered
TEST_ENDPOINT = '9.9.9.9:9999'
TEST_PARTNER_ADDRESS = '2' * 40
TEST_DEPOSIT_AMOUNT = 5

TEST_PRIVKEY = (b'\xad\xd4\xd3\x10\xba\x04$hy\x1d\xd7\xbf\x7fn\xae\x85\xac'
                b'\xc4\xdd\x14?\xfa\x81\x0e\xf1\x80\x9aj\x11\xf2\xbcD')
TEST_ACCOUNT_ADDRESS = privatekey_to_address(TEST_PRIVKEY)

RST_DATADIR = tempfile.mkdtemp()
os.environ['RST_DATADIR'] = RST_DATADIR


def ensure_executable(cmd):
    """look for the given command and make sure it can be executed"""
    if not shutil.which(cmd):
        print(
            'Error: unable to locate %s binary.\n'
            'Make sure it is installed and added to the PATH variable.' %
            cmd, )
        sys.exit(1)

示例#47
0
    def __init__(
        self,
        chain: BlockChainService,
        query_start_block: typing.BlockNumber,
        default_registry: TokenNetworkRegistry,
        default_secret_registry: SecretRegistry,
        private_key_bin,
        transport,
        config,
        discovery=None,
    ):
        super().__init__()
        if not isinstance(private_key_bin,
                          bytes) or len(private_key_bin) != 32:
            raise ValueError('invalid private_key')

        self.tokennetworkids_to_connectionmanagers = dict()
        self.identifier_to_results: typing.Dict[typing.PaymentID,
                                                AsyncResult, ] = dict()

        self.chain: BlockChainService = chain
        self.default_registry = default_registry
        self.query_start_block = query_start_block
        self.default_secret_registry = default_secret_registry
        self.config = config
        self.privkey = private_key_bin
        self.address = privatekey_to_address(private_key_bin)
        self.discovery = discovery

        self.private_key = PrivateKey(private_key_bin)
        self.pubkey = self.private_key.public_key.format(compressed=False)
        self.transport = transport

        self.blockchain_events = BlockchainEvents()
        self.alarm = AlarmTask(chain)

        self.stop_event = Event()
        self.stop_event.set()  # inits as stopped

        self.wal = None
        self.snapshot_group = 0

        # This flag will be used to prevent the service from processing
        # state changes events until we know that pending transactions
        # have been dispatched.
        self.dispatch_events_lock = Semaphore(1)

        self.database_path = config['database_path']
        if self.database_path != ':memory:':
            database_dir = os.path.dirname(config['database_path'])
            os.makedirs(database_dir, exist_ok=True)

            self.database_dir = database_dir
            # Prevent concurrent access to the same db
            self.lock_file = os.path.join(self.database_dir, '.lock')
            self.db_lock = filelock.FileLock(self.lock_file)
        else:
            self.database_path = ':memory:'
            self.database_dir = None
            self.lock_file = None
            self.serialization_file = None
            self.db_lock = None

        self.event_poll_lock = gevent.lock.Semaphore()
示例#48
0
def test_channelnewbalance_event(private_keys, settle_timeout, tester_state,
                                 tester_events, tester_token, tester_registry):
    """ Check the correct events are generated for deposit calls. """

    privatekey0 = private_keys[0]
    privatekey1 = private_keys[1]
    address0 = privatekey_to_address(privatekey0)
    address1 = privatekey_to_address(privatekey1)

    channel_manager = new_channelmanager(
        privatekey0,
        tester_state,
        tester_events.append,
        tester_registry,
        tester_token,
    )

    nettingchannel = new_nettingcontract(
        privatekey0,
        privatekey1,
        tester_state,
        tester_events.append,
        channel_manager,
        settle_timeout,
    )

    initial_balance0 = tester_token.balanceOf(address0, sender=privatekey0)
    deposit_amount = initial_balance0 // 10

    assert tester_token.approve(
        nettingchannel.address, deposit_amount, sender=privatekey0) is True
    assert tester_token.approve(
        nettingchannel.address, deposit_amount, sender=privatekey1) is True

    previous_events = list(tester_events)
    assert nettingchannel.deposit(deposit_amount, sender=privatekey0) is True
    assert len(previous_events) + 2 == len(tester_events)

    block_number = tester_state.block.number

    transfer_event = tester_events[-2]
    assert transfer_event == {
        '_event_type': 'Transfer',
        '_from': encode_hex(address0),
        '_to': nettingchannel.address,
        '_value': deposit_amount,
    }

    newbalance_event = tester_events[-1]
    assert newbalance_event == {
        '_event_type': 'ChannelNewBalance',
        'assetAddress': encode_hex(tester_token.address),
        'participant': encode_hex(address0),
        'balance': deposit_amount,
        'blockNumber': block_number,
    }

    previous_events = list(tester_events)
    assert nettingchannel.deposit(deposit_amount, sender=privatekey1) is True
    assert len(previous_events) + 2 == len(tester_events)

    block_number = tester_state.block.number

    transfer_event = tester_events[-2]
    assert transfer_event == {
        '_event_type': 'Transfer',
        '_from': encode_hex(address1),
        '_to': nettingchannel.address,
        '_value': deposit_amount,
    }

    newbalance_event = tester_events[-1]
    assert newbalance_event == {
        '_event_type': 'ChannelNewBalance',
        'assetAddress': encode_hex(tester_token.address),
        'participant': encode_hex(address1),
        'balance': deposit_amount,
        'blockNumber': block_number,
    }
示例#49
0
def test_withdraw(
        deposit,
        settle_timeout,
        reveal_timeout,
        tester_channels,
        tester_chain,
        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)

    lock_amount = 31
    lock_expiration = tester_chain.block.number + reveal_timeout + 5
    secret = b'secretsecretsecretsecretsecretse'
    hashlock = sha3(secret)
    new_block = Block(tester_chain.block.number)
    channel0.state_transition(new_block)
    channel1.state_transition(new_block)
    lock0 = Lock(lock_amount, lock_expiration, hashlock)

    mediated0 = make_mediated_transfer(
        channel0,
        channel1,
        address0,
        address1,
        lock0,
        pkey0,
        tester_chain.block.number,
        secret,
    )

    # withdraw the pending transfer sent to us by our partner
    proof = channel1.partner_state.compute_proof_for_lock(
        secret,
        mediated0.lock,
    )

    mediated0_hash = sha3(mediated0.packed().data[:-65])
    nettingchannel.close(
        mediated0.nonce,
        mediated0.transferred_amount,
        mediated0.locksroot,
        mediated0_hash,
        mediated0.signature,
        sender=pkey1,
    )

    tester_chain.mine(number_of_blocks=1)

    nettingchannel.withdraw(
        proof.lock_encoded,
        b''.join(proof.merkle_proof),
        proof.secret,
        sender=pkey1,
    )

    tester_chain.mine(number_of_blocks=settle_timeout + 1)
    nettingchannel.settle(sender=pkey0)

    balance0 = initial_balance0 + deposit - lock0.amount
    balance1 = initial_balance1 + deposit + lock0.amount
    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
示例#50
0
def test_withdraw_tampered_lock_amount(tree, tester_channels, tester_chain,
                                       tester_token, settle_timeout):
    """ withdraw must fail if the lock amonut is tampered. """
    pkey0, pkey1, nettingchannel, channel0, _ = tester_channels[0]

    current_block = tester_chain.block.number
    expiration = current_block + settle_timeout - 1
    locks = [
        make_lock(
            hashlock=hashlock,
            expiration=expiration,
        ) for hashlock in tree
    ]

    leaves = [sha3(lock.as_bytes) for lock in locks]
    layers = compute_layers(leaves)
    merkle_tree = MerkleTreeState(layers)

    opened_block = nettingchannel.opened(sender=pkey0)
    nonce = 1 + (opened_block * (2**32))
    direct_transfer = make_direct_transfer(
        nonce=nonce,
        channel=channel0.identifier,
        locksroot=merkleroot(merkle_tree),
        token=tester_token.address,
        recipient=privatekey_to_address(pkey1))

    address = privatekey_to_address(pkey0)
    sign_key = PrivateKey(pkey0)
    direct_transfer.sign(sign_key, address)

    direct_transfer_hash = sha3(direct_transfer.packed().data[:-65])
    nettingchannel.close(
        direct_transfer.nonce,
        direct_transfer.transferred_amount,
        direct_transfer.locksroot,
        direct_transfer_hash,
        direct_transfer.signature,
        sender=pkey1,
    )

    for lock in locks:
        secret = HASHLOCKS_SECRESTS[lock.hashlock]

        lock_encoded = lock.as_bytes
        merkle_proof = compute_merkleproof_for(merkle_tree, sha3(lock_encoded))

        tampered_lock = make_lock(
            amount=lock.amount * 100,
            hashlock=lock.hashlock,
            expiration=lock.expiration,
        )
        tampered_lock_encoded = sha3(tampered_lock.as_bytes)

        with pytest.raises(TransactionFailed):
            nettingchannel.withdraw(
                tampered_lock_encoded,
                b''.join(merkle_proof),
                secret,
                sender=pkey1,
            )
示例#51
0
def test_withdraw_tampered_merkle_proof(tree, tester_channels, tester_chain, settle_timeout):
    """ withdraw must fail if the proof is tampered. """
    pkey0, pkey1, nettingchannel, channel0, _ = tester_channels[0]

    current_block = tester_chain.block.number
    expiration = current_block + settle_timeout - 1
    locks = [
        make_lock(
            hashlock=hashlock,
            expiration=expiration,
        )
        for hashlock in tree
    ]

    leaves = [sha3(lock.as_bytes) for lock in locks]
    layers = compute_layers(leaves)
    merkle_tree = MerkleTreeState(layers)

    opened_block = nettingchannel.opened(sender=pkey0)
    nonce = 1 + (opened_block * (2 ** 32))
    direct_transfer = make_direct_transfer(
        nonce=nonce,
        channel=channel0.channel_address,
        locksroot=merkleroot(merkle_tree),
        recipient=privatekey_to_address(pkey1)
    )

    address = privatekey_to_address(pkey0)
    sign_key = PrivateKey(pkey0)
    direct_transfer.sign(sign_key, address)

    direct_transfer_hash = sha3(direct_transfer.packed().data[:-65])
    nettingchannel.close(
        direct_transfer.nonce,
        direct_transfer.transferred_amount,
        direct_transfer.locksroot,
        direct_transfer_hash,
        direct_transfer.signature,
        sender=pkey1,
    )

    for lock in locks:
        secret = HASHLOCKS_SECRESTS[lock.hashlock]

        lock_encoded = lock.as_bytes
        merkle_proof = compute_merkleproof_for(merkle_tree, sha3(lock_encoded))

        # withdraw must fail regardless of which part of the proof is tampered
        for pos, hash_ in enumerate(merkle_proof):
            # changing arbitrary bytes from the proof
            tampered_hash = bytearray(hash_)
            tampered_hash[6], tampered_hash[7] = tampered_hash[7], tampered_hash[6]

            tampered_proof = list(merkle_proof)
            tampered_proof[pos] = tampered_hash

            joiner = b''
            with pytest.raises(TransactionFailed):
                nettingchannel.withdraw(
                    lock_encoded,
                    joiner.join(tampered_proof),
                    secret,
                    sender=pkey1,
                )
示例#52
0
def test_withdraw_lock_with_a_large_expiration(deposit, tester_channels,
                                               tester_chain, tester_token,
                                               settle_timeout):
    """ Withdraw must accept a lock that expires after the settlement period. """
    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)

    # use a really large expiration
    lock_expiration = tester_chain.block.number + settle_timeout * 5

    # work around for the python expiration validation
    bad_block_number = lock_expiration - 10
    channel.state_transition(channel0, Block(bad_block_number),
                             bad_block_number)

    lock_amount = 29
    secret = sha3(b'test_withdraw_lock_with_a_large_expiration')
    lock_hashlock = sha3(secret)
    lock = Lock(
        amount=lock_amount,
        expiration=lock_expiration,
        hashlock=lock_hashlock,
    )
    mediated0 = make_mediated_transfer(
        channel0,
        channel1,
        address0,
        address1,
        lock,
        pkey0,
        secret,
    )

    nettingchannel.close(sender=pkey0)

    mediated0_hash = sha3(mediated0.packed().data[:-65])
    nettingchannel.updateTransfer(
        mediated0.nonce,
        mediated0.transferred_amount,
        mediated0.locksroot,
        mediated0_hash,
        mediated0.signature,
        sender=pkey1,
    )

    unlock_proofs = channel.get_known_unlocks(channel1.partner_state)
    proof = unlock_proofs[0]

    nettingchannel.withdraw(
        proof.lock_encoded,
        b''.join(proof.merkle_proof),
        proof.secret,
        sender=pkey1,
    )

    tester_chain.mine(number_of_blocks=settle_timeout + 1)
    nettingchannel.settle(sender=pkey0)

    balance0 = initial_balance0 + deposit - lock_amount
    balance1 = initial_balance1 + deposit + lock_amount
    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
示例#53
0
    def __init__(
            self,
            chain: BlockChainService,
            default_registry,
            private_key_bin,
            transport,
            config,
            discovery=None,
    ):
        if not isinstance(private_key_bin, bytes) or len(private_key_bin) != 32:
            raise ValueError('invalid private_key')

        invalid_timeout = (
            config['settle_timeout'] < NETTINGCHANNEL_SETTLE_TIMEOUT_MIN or
            config['settle_timeout'] > NETTINGCHANNEL_SETTLE_TIMEOUT_MAX
        )
        if invalid_timeout:
            raise ValueError('settle_timeout must be in range [{}, {}]'.format(
                NETTINGCHANNEL_SETTLE_TIMEOUT_MIN, NETTINGCHANNEL_SETTLE_TIMEOUT_MAX,
            ))

        self.tokens_to_connectionmanagers = dict()
        self.identifier_to_results = defaultdict(list)

        self.chain: BlockChainService = chain
        self.default_registry = default_registry
        self.config = config
        self.privkey = private_key_bin
        self.address = privatekey_to_address(private_key_bin)

        if config['transport_type'] == 'udp':
            endpoint_registration_event = gevent.spawn(
                discovery.register,
                self.address,
                config['external_ip'],
                config['external_port'],
            )
            endpoint_registration_event.link_exception(endpoint_registry_exception_handler)

        self.private_key = PrivateKey(private_key_bin)
        self.pubkey = self.private_key.public_key.format(compressed=False)
        self.transport = transport

        self.blockchain_events = BlockchainEvents()
        self.alarm = AlarmTask(chain)
        self.shutdown_timeout = config['shutdown_timeout']
        self.stop_event = Event()
        self.start_event = Event()
        self.chain.client.inject_stop_event(self.stop_event)

        self.wal = None

        self.database_path = config['database_path']
        if self.database_path != ':memory:':
            database_dir = os.path.dirname(config['database_path'])
            os.makedirs(database_dir, exist_ok=True)

            self.database_dir = database_dir
            # Prevent concurrent acces to the same db
            self.lock_file = os.path.join(self.database_dir, '.lock')
            self.db_lock = filelock.FileLock(self.lock_file)
        else:
            self.database_path = ':memory:'
            self.database_dir = None
            self.lock_file = None
            self.serialization_file = None
            self.db_lock = None

        if config['transport_type'] == 'udp':
            # If the endpoint registration fails the node will quit, this must
            # finish before starting the transport
            endpoint_registration_event.join()

        self.event_poll_lock = gevent.lock.Semaphore()

        self.start()
示例#54
0
def create_apps(
    blockchain_services,
    endpoint_discovery_services,
    registry_address,
    raiden_udp_ports,
    reveal_timeout,
    settle_timeout,
    database_paths,
    retry_interval,
    retries_before_backoff,
    throttle_capacity,
    throttle_fill_rate,
    nat_invitation_timeout,
    nat_keepalive_retries,
    nat_keepalive_timeout,
    use_matrix=False,
    local_matrix_url=None,
):
    """ Create the apps."""
    # pylint: disable=too-many-locals
    services = zip(blockchain_services, endpoint_discovery_services)

    apps = []
    for idx, (blockchain, discovery) in enumerate(services):
        port = raiden_udp_ports[idx]
        private_key = blockchain.private_key
        nodeid = privatekey_to_address(private_key)

        host = '127.0.0.1'

        discovery.register(nodeid, host, port)

        config = {
            'host': host,
            'port': port,
            'external_ip': host,
            'external_port': port,
            'privatekey_hex': hexlify(private_key),
            'reveal_timeout': reveal_timeout,
            'settle_timeout': settle_timeout,
            'database_path': database_paths[idx],
            'protocol': {
                'retry_interval': retry_interval,
                'retries_before_backoff': retries_before_backoff,
                'throttle_capacity': throttle_capacity,
                'throttle_fill_rate': throttle_fill_rate,
                'nat_invitation_timeout': nat_invitation_timeout,
                'nat_keepalive_retries': nat_keepalive_retries,
                'nat_keepalive_timeout': nat_keepalive_timeout,
            },
            'rpc': True,
            'console': False,
        }
        config_copy = App.DEFAULT_CONFIG.copy()
        config_copy.update(config)

        if use_matrix:
            if local_matrix_url is not None:
                matrix_config = {
                    'server': local_matrix_url,
                }
            else:
                matrix_config = {
                    'client_class': MockMatrixClient,
                    'server': 'http://matrix.mock',
                }
            config.update({
                'transport_type': 'matrix',
                'matrix': matrix_config
            })

        registry = blockchain.registry(registry_address)

        if use_matrix:
            transport = MatrixTransport(config['matrix'])
        else:
            throttle_policy = TokenBucket(
                config['protocol']['throttle_capacity'],
                config['protocol']['throttle_fill_rate'])

            transport = UDPTransport(
                discovery,
                server._udp_socket((host, port)),  # pylint: disable=protected-access
                throttle_policy,
                config['protocol'],
            )

        app = App(
            config_copy,
            blockchain,
            registry,
            transport,
            discovery,
        )
        apps.append(app)

    return apps
示例#55
0
def test_channeldeposit(private_keys, settle_timeout, tester_state,
                        tester_token, tester_events, tester_registry):
    """ Guarantee the correct tracking of each participant deposits, checks the
    initial state (pre-deposit) and state changes for each deposits.
    """

    # not using the tester_nettingcontracts fixture to control the
    # transfer/deposits

    privatekey0 = private_keys[0]
    privatekey1 = private_keys[1]
    address0 = privatekey_to_address(privatekey0)
    address1 = privatekey_to_address(privatekey1)
    unknow_key = tester.k3

    channel_manager = new_channelmanager(
        privatekey0,
        tester_state,
        tester_events.append,
        tester_registry,
        tester_token,
    )

    channel = new_nettingcontract(
        privatekey0,
        privatekey1,
        tester_state,
        tester_events.append,
        channel_manager,
        settle_timeout,
    )

    # check initial state, needs to be zeroed out
    assert channel.settleTimeout(sender=privatekey0) == settle_timeout
    assert channel.assetAddress(sender=privatekey0) == encode_hex(
        tester_token.address)
    assert channel.opened(sender=privatekey0) == 0
    assert channel.closed(sender=privatekey0) == 0
    assert channel.settled(sender=privatekey0) == 0

    assert channel.addressAndBalance(
        sender=privatekey0)[0] == encode_hex(address0)
    assert channel.addressAndBalance(sender=privatekey0)[1] == 0
    assert channel.addressAndBalance(
        sender=privatekey0)[2] == encode_hex(address1)
    assert channel.addressAndBalance(sender=privatekey0)[3] == 0

    initial_balance0 = tester_token.balanceOf(address0, sender=privatekey0)
    deposit_amount = initial_balance0 // 10

    # try to make invalid deposits
    with pytest.raises(TransactionFailed):
        channel.deposit(1, sender=unknow_key)  # not participant

    assert tester_token.approve(
        channel.address, deposit_amount * 2, sender=privatekey0) is True

    assert channel.deposit(deposit_amount * 2 + 1, sender=privatekey0) is False

    with pytest.raises(abi.ValueOutOfBounds):
        channel.deposit(-1, sender=privatekey0)

    # create a first deposit with half of the allowance
    assert channel.deposit(deposit_amount, sender=privatekey0) is True

    assert tester_token.balanceOf(channel.address,
                                  sender=privatekey0) == deposit_amount
    assert tester_token.balanceOf(
        address0,
        sender=privatekey0) == initial_balance0 - deposit_amount  # noqa
    assert channel.opened(sender=privatekey0) == tester_state.block.number

    assert channel.addressAndBalance(
        sender=privatekey0)[0] == encode_hex(address0)
    assert channel.addressAndBalance(sender=privatekey0)[1] == deposit_amount
    assert channel.addressAndBalance(
        sender=privatekey0)[2] == encode_hex(address1)
    assert channel.addressAndBalance(sender=privatekey0)[3] == 0

    # check a second depoist with the rest of the allowance
    assert channel.deposit(deposit_amount, sender=privatekey0) is True

    assert tester_token.balanceOf(channel.address,
                                  sender=privatekey0) == deposit_amount * 2
    assert tester_token.balanceOf(
        address0,
        sender=privatekey0) == initial_balance0 - deposit_amount * 2  # noqa
    assert channel.opened(sender=privatekey0) == tester_state.block.number

    assert channel.addressAndBalance(
        sender=privatekey0)[0] == encode_hex(address0)
    assert channel.addressAndBalance(
        sender=privatekey0)[1] == deposit_amount * 2
    assert channel.addressAndBalance(
        sender=privatekey0)[2] == encode_hex(address1)
    assert channel.addressAndBalance(sender=privatekey0)[3] == 0

    # allowance zeroed, we cant make a new deposit
    assert channel.deposit(deposit_amount, sender=privatekey0) is False

    # needs to be able to add aditional asset
    assert tester_token.approve(
        channel.address, deposit_amount, sender=privatekey0) is True
    assert channel.deposit(deposit_amount, sender=privatekey0) is True

    assert tester_token.balanceOf(channel.address,
                                  sender=privatekey0) == deposit_amount * 3
    assert tester_token.balanceOf(
        address0,
        sender=privatekey0) == initial_balance0 - deposit_amount * 3  # noqa
    assert channel.opened(sender=privatekey0) == tester_state.block.number

    assert channel.addressAndBalance(
        sender=privatekey0)[0] == encode_hex(address0)
    assert channel.addressAndBalance(
        sender=privatekey0)[1] == deposit_amount * 3
    assert channel.addressAndBalance(
        sender=privatekey0)[2] == encode_hex(address1)
    assert channel.addressAndBalance(sender=privatekey0)[3] == 0
示例#56
0
    def __init__(self, chain, default_registry, private_key_bin, transport,
                 discovery, config):
        if not isinstance(private_key_bin,
                          bytes) or len(private_key_bin) != 32:
            raise ValueError('invalid private_key')

        invalid_timeout = (
            config['settle_timeout'] < NETTINGCHANNEL_SETTLE_TIMEOUT_MIN
            or config['settle_timeout'] > NETTINGCHANNEL_SETTLE_TIMEOUT_MAX)
        if invalid_timeout:
            raise ValueError('settle_timeout must be in range [{}, {}]'.format(
                NETTINGCHANNEL_SETTLE_TIMEOUT_MIN,
                NETTINGCHANNEL_SETTLE_TIMEOUT_MAX))

        self.token_to_channelgraph = dict()
        self.tokens_to_connectionmanagers = dict()
        self.manager_to_token = dict()
        self.swapkey_to_tokenswap = dict()
        self.swapkey_to_greenlettask = dict()

        self.identifier_to_statemanagers = defaultdict(list)
        self.identifier_to_results = defaultdict(list)

        # This is a map from a hashlock to a list of channels, the same
        # hashlock can be used in more than one token (for tokenswaps), a
        # channel should be removed from this list only when the lock is
        # released/withdrawn but not when the secret is registered.
        self.token_to_hashlock_to_channels = defaultdict(
            lambda: defaultdict(list))

        self.chain = chain
        self.default_registry = default_registry
        self.config = config
        self.privkey = private_key_bin
        self.address = privatekey_to_address(private_key_bin)

        endpoint_registration_event = gevent.spawn(
            discovery.register,
            self.address,
            config['external_ip'],
            config['external_port'],
        )
        endpoint_registration_event.link_exception(
            endpoint_registry_exception_handler)

        self.private_key = PrivateKey(private_key_bin)
        self.pubkey = self.private_key.public_key.format(compressed=False)
        self.protocol = RaidenProtocol(
            transport,
            discovery,
            self,
            config['protocol']['retry_interval'],
            config['protocol']['retries_before_backoff'],
            config['protocol']['nat_keepalive_retries'],
            config['protocol']['nat_keepalive_timeout'],
            config['protocol']['nat_invitation_timeout'],
        )

        # TODO: remove this cyclic dependency
        transport.protocol = self.protocol

        self.message_handler = RaidenMessageHandler(self)
        self.state_machine_event_handler = StateMachineEventHandler(self)
        self.pyethapp_blockchain_events = PyethappBlockchainEvents()
        self.greenlet_task_dispatcher = GreenletTasksDispatcher()
        self.on_message = self.message_handler.on_message
        self.alarm = AlarmTask(chain)
        self._blocknumber = None

        self.transaction_log = StateChangeLog(
            storage_instance=StateChangeLogSQLiteBackend(
                database_path=config['database_path']))

        if config['database_path'] != ':memory:':
            self.database_dir = os.path.dirname(config['database_path'])
            self.lock_file = os.path.join(self.database_dir, '.lock')
            self.snapshot_dir = os.path.join(self.database_dir, 'snapshots')
            self.serialization_file = os.path.join(self.snapshot_dir,
                                                   'data.pickle')

            if not os.path.exists(self.snapshot_dir):
                os.makedirs(self.snapshot_dir)

            # Prevent concurrent acces to the same db
            self.db_lock = filelock.FileLock(self.lock_file)
        else:
            self.database_dir = None
            self.lock_file = None
            self.snapshot_dir = None
            self.serialization_file = None
            self.db_lock = None

        # If the endpoint registration fails the node will quit, this must
        # finish before starting the protocol
        endpoint_registration_event.join()

        self.start()
示例#57
0
def test_closewithouttransfer_settle(deposit, settle_timeout, tester_state,
                                     tester_events, tester_nettingcontracts,
                                     tester_token):

    privatekey0, privatekey1, nettingchannel = tester_nettingcontracts[0]
    address0 = privatekey_to_address(privatekey0)
    address1 = privatekey_to_address(privatekey1)
    unknow_key = tester.k3

    initial_balance0 = tester_token.balanceOf(address0, sender=privatekey0)
    initial_balance1 = tester_token.balanceOf(address1, sender=privatekey1)

    with pytest.raises(TransactionFailed):
        nettingchannel.closeWithoutTransfers(sender=unknow_key)

    # this method needs to be implemented, the name could be changed
    previous_events = list(tester_events)
    nettingchannel.closeWithoutTransfers(sender=privatekey0)
    assert len(previous_events) + 1 == len(tester_events)

    block_number = tester_state.block.number

    close_event = tester_events[-1]
    assert close_event == {
        '_event_type': 'ChannelClosed',
        'closingAddress': encode_hex(address0),
        'blockNumber': block_number,
    }

    assert nettingchannel.closed() == block_number
    assert nettingchannel.closingAddress() == encode_hex(address0)

    tester_state.mine(number_of_blocks=settle_timeout + 1)

    previous_events = list(tester_events)
    nettingchannel.settle(sender=privatekey0)
    block_number = tester_state.block.number

    assert len(previous_events) + 3 == len(tester_events)

    transfer0_event = tester_events[-3]
    assert transfer0_event == {
        '_from': nettingchannel.address,
        '_to': encode_hex(address0),
        '_value': deposit,
    }

    transfer1_event = tester_events[-2]
    assert transfer1_event == {
        '_from': nettingchannel.address,
        '_to': encode_hex(address1),
        '_value': deposit,
    }

    settle_event = tester_events[-1]
    assert settle_event == {
        '_event_type': 'ChannelSettled',
        'blockNumber': block_number,
    }

    assert tester_token.balanceOf(
        address0, sender=privatekey0) == initial_balance0 + deposit
    assert tester_token.balanceOf(
        address1, sender=privatekey1) == initial_balance1 + deposit
    assert tester_token.balanceOf(nettingchannel.address,
                                  sender=privatekey1) == 0
示例#58
0
def test_close_settle(deposit, settle_timeout, tester_state, tester_channels,
                      tester_events, tester_token):

    privatekey0, privatekey1, nettingchannel, channel0, channel1 = tester_channels[
        0]
    address0 = privatekey_to_address(privatekey0)
    address1 = privatekey_to_address(privatekey1)
    unknow_key = tester.k3

    initial_balance0 = tester_token.balanceOf(address0, sender=privatekey0)
    initial_balance1 = tester_token.balanceOf(address1, sender=privatekey1)

    transfer_amount0 = 10
    direct_transfer0 = channel0.create_directtransfer(transfer_amount0)
    direct_transfer0.sign(privatekey0)

    transfer_amount1 = 30
    direct_transfer1 = channel1.create_directtransfer(transfer_amount1)
    direct_transfer1.sign(privatekey1)

    with pytest.raises(TransactionFailed):
        nettingchannel.close(
            str(direct_transfer0.packed().data),
            str(direct_transfer1.packed().data),
            sender=unknow_key,
        )

    previous_events = list(tester_events)
    nettingchannel.close(
        str(direct_transfer0.packed().data),
        str(direct_transfer1.packed().data),
        sender=privatekey0,
    )
    assert len(previous_events) + 1 == len(tester_events)

    block_number = tester_state.block.number

    close_event = tester_events[-1]
    assert close_event == {
        '_event_type': 'ChannelClosed',
        'closingAddress': encode_hex(address0),
        'blockNumber': block_number,
    }

    assert nettingchannel.closed(sender=privatekey0) == block_number
    assert nettingchannel.closingAddress(
        sender=privatekey0) == encode_hex(address0)

    tester_state.mine(number_of_blocks=settle_timeout + 1)

    previous_events = list(tester_events)
    nettingchannel.settle(sender=privatekey0)
    assert len(previous_events) + 3 == len(tester_events)

    block_number = tester_state.block.number

    transfer0_event = tester_events[-3]
    assert transfer0_event == {
        '_event_type': 'Transfer',
        '_from': nettingchannel.address,
        '_to': encode_hex(address0),
        '_value': deposit - transfer_amount0 + transfer_amount1,
    }

    transfer1_event = tester_events[-2]
    assert transfer1_event == {
        '_event_type': 'Transfer',
        '_from': nettingchannel.address,
        '_to': encode_hex(address1),
        '_value': deposit + transfer_amount0 - transfer_amount1,
    }

    settle_event = tester_events[-1]
    assert settle_event == {
        '_event_type': 'ChannelSettled',
        'blockNumber': block_number,
    }

    assert tester_token.balanceOf(
        address0, sender=privatekey0
    ) == initial_balance0 + deposit - transfer_amount0 + transfer_amount1  # noqa
    assert tester_token.balanceOf(
        address1, sender=privatekey1
    ) == initial_balance1 + deposit + transfer_amount0 - transfer_amount1  # noqa
    assert tester_token.balanceOf(nettingchannel.address,
                                  sender=privatekey1) == 0
示例#59
0
    def __init__(self, chain, default_registry, private_key_bin, transport,
                 discovery, config):
        if not isinstance(private_key_bin,
                          bytes) or len(private_key_bin) != 32:
            raise ValueError('invalid private_key')

        invalid_timeout = (
            config['settle_timeout'] < NETTINGCHANNEL_SETTLE_TIMEOUT_MIN
            or config['settle_timeout'] > NETTINGCHANNEL_SETTLE_TIMEOUT_MAX)
        if invalid_timeout:
            raise ValueError('settle_timeout must be in range [{}, {}]'.format(
                NETTINGCHANNEL_SETTLE_TIMEOUT_MIN,
                NETTINGCHANNEL_SETTLE_TIMEOUT_MAX))

        self.tokens_to_connectionmanagers = dict()
        self.identifier_to_results = defaultdict(list)

        # This is a map from a secrethash to a list of channels, the same
        # secrethash can be used in more than one token (for tokenswaps), a
        # channel should be removed from this list only when the lock is
        # released/withdrawn but not when the secret is registered.
        self.token_to_secrethash_to_channels = defaultdict(
            lambda: defaultdict(list))

        self.chain = chain
        self.default_registry = default_registry
        self.config = config
        self.privkey = private_key_bin
        self.address = privatekey_to_address(private_key_bin)

        endpoint_registration_event = gevent.spawn(
            discovery.register,
            self.address,
            config['external_ip'],
            config['external_port'],
        )
        endpoint_registration_event.link_exception(
            endpoint_registry_exception_handler)

        self.private_key = PrivateKey(private_key_bin)
        self.pubkey = self.private_key.public_key.format(compressed=False)
        self.protocol = RaidenProtocol(
            transport,
            discovery,
            self,
            config['protocol']['retry_interval'],
            config['protocol']['retries_before_backoff'],
            config['protocol']['nat_keepalive_retries'],
            config['protocol']['nat_keepalive_timeout'],
            config['protocol']['nat_invitation_timeout'],
        )

        # TODO: remove this cyclic dependency
        transport.protocol = self.protocol

        self.blockchain_events = BlockchainEvents()
        self.alarm = AlarmTask(chain)
        self.shutdown_timeout = config['shutdown_timeout']
        self._block_number = None
        self.stop_event = Event()
        self.start_event = Event()
        self.chain.client.inject_stop_event(self.stop_event)

        self.wal = None

        self.database_path = config['database_path']
        if self.database_path != ':memory:':
            database_dir = os.path.dirname(config['database_path'])
            os.makedirs(database_dir, exist_ok=True)

            self.database_dir = database_dir
            # Prevent concurrent acces to the same db
            self.lock_file = os.path.join(self.database_dir, '.lock')
            self.db_lock = filelock.FileLock(self.lock_file)
        else:
            self.database_path = ':memory:'
            self.database_dir = None
            self.lock_file = None
            self.serialization_file = None
            self.db_lock = None

        # If the endpoint registration fails the node will quit, this must
        # finish before starting the protocol
        endpoint_registration_event.join()

        # Lock used to serialize calls to `poll_blockchain_events`, this is
        # important to give a consistent view of the node state.
        self.event_poll_lock = gevent.lock.Semaphore()

        self.start()
示例#60
0
def test_blockchain(
        blockchain_type,
        blockchain_backend,  # required to start the geth backend
        blockchain_rpc_ports,
        private_keys,
        poll_timeout):
    # pylint: disable=too-many-locals

    # this test is for interaction with a blockchain using json-rpc, so it
    # doesnt make sense to execute it against mock or tester
    if blockchain_type not in ('geth', ):
        return

    addresses = [privatekey_to_address(priv) for priv in private_keys]

    privatekey = private_keys[0]
    address = privatekey_to_address(privatekey)
    total_token = 100

    jsonrpc_client = JSONRPCClient(
        port=blockchain_rpc_ports[0],
        privkey=privatekey,
        print_communication=False,
    )
    patch_send_transaction(jsonrpc_client)
    patch_send_message(jsonrpc_client)

    humantoken_path = get_contract_path('HumanStandardToken.sol')
    humantoken_contracts = compile_file(humantoken_path, libraries=dict())
    token_proxy = jsonrpc_client.deploy_solidity_contract(
        address,
        'HumanStandardToken',
        humantoken_contracts,
        dict(),
        (total_token, 'raiden', 2, 'Rd'),
        contract_path=humantoken_path,
        gasprice=default_gasprice,
        timeout=poll_timeout,
    )

    registry_path = get_contract_path('Registry.sol')
    registry_contracts = compile_file(registry_path)
    registry_proxy = jsonrpc_client.deploy_solidity_contract(
        address,
        'Registry',
        registry_contracts,
        dict(),
        tuple(),
        contract_path=registry_path,
        gasprice=default_gasprice,
        timeout=poll_timeout,
    )

    log_list = jsonrpc_client.call(
        'eth_getLogs',
        {
            'fromBlock': '0x0',
            'toBlock': 'latest',
            'topics': [],
        },
    )
    assert len(log_list) == 0

    # pylint: disable=no-member

    assert token_proxy.balanceOf(address) == total_token
    transaction_hash = registry_proxy.addToken.transact(
        token_proxy.address,
        gasprice=denoms.wei,
    )
    jsonrpc_client.poll(transaction_hash.decode('hex'), timeout=poll_timeout)

    assert len(registry_proxy.tokenAddresses.call()) == 1

    log_list = jsonrpc_client.call(
        'eth_getLogs',
        {
            'fromBlock': '0x0',
            'toBlock': 'latest',
            'topics': [],
        },
    )
    assert len(log_list) == 1

    channel_manager_address_encoded = registry_proxy.channelManagerByToken.call(
        token_proxy.address, )
    channel_manager_address = channel_manager_address_encoded.decode('hex')

    log = log_list[0]
    log_topics = [
        decode_topic(topic) for topic in log['topics']  # pylint: disable=invalid-sequence-index
    ]
    log_data = log['data']
    event = registry_proxy.translator.decode_event(
        log_topics,
        log_data[2:].decode('hex'),
    )

    assert channel_manager_address == event['channel_manager_address'].decode(
        'hex')
    assert token_proxy.address == event['token_address'].decode('hex')

    channel_manager_proxy = jsonrpc_client.new_contract_proxy(
        CHANNEL_MANAGER_ABI,
        channel_manager_address,
    )

    transaction_hash = channel_manager_proxy.newChannel.transact(
        addresses[1],
        10,
        gasprice=denoms.wei,
    )
    jsonrpc_client.poll(transaction_hash.decode('hex'), timeout=poll_timeout)

    log_list = jsonrpc_client.call(
        'eth_getLogs',
        {
            'fromBlock': '0x0',
            'toBlock': 'latest',
            'topics': [],
        },
    )
    assert len(log_list) == 2