Beispiel #1
0
    def make_channel(
        self,
        token_address=make_address(),
        partner_address=make_address(),
        reveal_timeout=20,
        settle_timeout=800,
        balance=0,
    ):
        our_address = make_address()
        our_balance = balance
        partner_balance = balance
        our_state = ChannelEndState(our_address, our_balance, 1)
        partner_state = ChannelEndState(partner_address, partner_balance, 1)

        block_alarm = list()
        channel_for_hashlock = list()
        netting_channel = NettingChannelMock(make_address())
        external_state = ChannelExternalState(
            block_alarm.append,
            lambda *args: channel_for_hashlock.append(args),
            lambda: 1,
            netting_channel,
        )
        self.tokens.add(token_address)
        return Channel(
            our_state,
            partner_state,
            external_state,
            token_address,
            reveal_timeout,
            settle_timeout,
        )
Beispiel #2
0
def channel_list_mock(num_channels):
    channel_list = []
    for _ in range(0, num_channels):
        netting_channel = NettingChannelMock()
        asset_address = make_address()
        privkey1, address1 = make_privkey_address()
        address2 = make_address()

        balance1 = random.randint(0, 2**128)
        balance2 = random.randint(0, 2**128)

        reveal_timeout = random.randint(0, 2**64)
        settle_timeout = reveal_timeout + random.randint(0, 2**64)

        our_state = ChannelEndState(address1, balance1, netting_channel.opened)
        partner_state = ChannelEndState(address2, balance2,
                                        netting_channel.opened)
        external_state = make_external_state()

        test_channel = Channel(
            our_state,
            partner_state,
            external_state,
            asset_address,
            reveal_timeout,
            settle_timeout,
        )

        channel_list.append(test_channel)

    return channel_list
Beispiel #3
0
    def setup_channel(self, asset_manager, asset_address,
                      nettingcontract_address, min_locktime):
        """ Initialize the Channel for the given netting contract. """

        channel_details = self.chain.netting_contract_detail(
            asset_address,
            nettingcontract_address,
            self.address,
        )

        our_state = ChannelEndState(
            self.address,
            channel_details['our_balance'],
        )

        partner_state = ChannelEndState(
            channel_details['partner_address'],
            channel_details['partner_balance'],
        )

        channel = Channel(
            self.chain,
            asset_address,
            nettingcontract_address,
            our_state,
            partner_state,
            min_locktime=min_locktime,
        )

        asset_manager.add_channel(channel_details['partner_address'], channel)
Beispiel #4
0
def test_channel_must_accept_expired_locks():
    """ A node may go offline for an undetermined period of time, and when it
    comes back online it must accept the messages that are waiting, otherwise
    the partner node won't make progress with its queue.

    If a N node goes offline for a number B of blocks, and the partner does not
    close the channel, when N comes back online some of the messages from its
    partner may become expired. Neverthless these messages are ordered and must
    be accepted for the partner to make progress with its queue.

    Note: Accepting a message with an expired lock does *not* imply the token
    transfer happened, and the receiver node must *not* forward the transfer,
    only accept the message allowing the partner to progress with its message
    queue.
    """
    balance1 = 70
    balance2 = 110
    reveal_timeout = 5
    settle_timeout = 15
    privkey1, address1 = make_privkey_address()
    privkey2, address2 = make_privkey_address()
    token_address = make_address()

    our_state = ChannelEndState(
        address1,
        balance1,
        None,
        EMPTY_MERKLE_TREE,
    )
    partner_state = ChannelEndState(
        address2,
        balance2,
        None,
        EMPTY_MERKLE_TREE,
    )
    external_state = make_external_state()

    test_channel = Channel(
        our_state,
        partner_state,
        external_state,
        token_address,
        reveal_timeout,
        settle_timeout,
    )

    block_number = 10
    transfer = make_mediated_transfer(
        nonce=test_channel.get_next_nonce(),
        token=test_channel.token_address,
        channel=test_channel.channel_address,
        expiration=block_number + settle_timeout,
        recipient=address1,
    )
    transfer.sign(privkey2, address2)

    test_channel.register_transfer(
        block_number + settle_timeout + 1,
        transfer,
    )
Beispiel #5
0
def test_channel_to_api_dict():
    channel_address = b'\x00' * 20
    token_address = b'\x01' * 20
    our_address = b'\x02' * 20
    partner_address = b'\x03' * 20

    reveal_timeout = 10
    settle_timeout = 50
    opened_block = 900
    our_balance = 13
    partner_balance = 21

    our_state = ChannelEndState(
        our_address,
        our_balance,
        None,
        EMPTY_MERKLE_TREE,
    )
    partner_state = ChannelEndState(
        partner_address,
        partner_balance,
        None,
        EMPTY_MERKLE_TREE,
    )

    # mock external state to provide the channel address
    class NettingChannel(object):
        address = channel_address

    class ExternalState(object):
        def __init__(self, opened_block):
            self.netting_channel = NettingChannel()
            self.settled_block = 0
            self.closed_block = 0
            self.opened_block = opened_block

    channel = Channel(
        our_state,
        partner_state,
        ExternalState(opened_block),
        token_address,
        reveal_timeout,
        settle_timeout,
    )

    result = channel_to_api_dict(channel)
    expected_result = {
        'channel_address': channel_address,
        'token_address': token_address,
        'partner_address': partner_address,
        'settle_timeout': settle_timeout,
        'reveal_timeout': reveal_timeout,
        'balance': our_balance,
        'state': CHANNEL_STATE_OPENED
    }
    assert result == expected_result
Beispiel #6
0
def test_channel_close_called_only_once():
    class MockCheckCallsToClose():
        def __init__(self):
            self.address = 'mockcheckcallstoclosemockcheckcallstoclo'
            self.close_calls = 0

        def opened(self):
            return 1

        def closed(self):
            return 0

        def settled(self):
            return 0

        def close(self, nonce, transferred_amount, locksroot, extra_hash,
                  signature):
            self.close_calls += 1

    netting_channel = NettingChannelMock()
    token_address = make_address()
    privkey1, address1 = make_privkey_address()
    address2 = make_address()

    balance1 = 70
    balance2 = 110

    reveal_timeout = 5
    settle_timeout = 15

    our_state = ChannelEndState(address1, balance1, netting_channel.opened())
    partner_state = ChannelEndState(address2, balance2,
                                    netting_channel.opened())

    channel_for_hashlock = list()
    netting_channel = MockCheckCallsToClose()

    external_state = ChannelExternalState(
        lambda *args: channel_for_hashlock.append(args),
        netting_channel,
    )

    test_channel = Channel(
        our_state,
        partner_state,
        external_state,
        token_address,
        reveal_timeout,
        settle_timeout,
    )

    test_channel.external_state.close('')
    test_channel.external_state.close('')

    assert netting_channel.close_calls == 1
Beispiel #7
0
    def restore_channel(self, serialized_channel):
        token_address = serialized_channel.token_address

        netting_channel = self.chain.netting_channel(
            serialized_channel.channel_address,
        )

        # restoring balances from the BC since the serialized value could be
        # falling behind.
        channel_details = netting_channel.detail(self.address)

        # our_address is checked by detail
        assert channel_details['partner_address'] == serialized_channel.partner_address

        opened_block = netting_channel.opened()
        our_state = ChannelEndState(
            channel_details['our_address'],
            channel_details['our_balance'],
            opened_block,
        )
        partner_state = ChannelEndState(
            channel_details['partner_address'],
            channel_details['partner_balance'],
            opened_block,
        )

        def register_channel_for_hashlock(channel, hashlock):
            self.register_channel_for_hashlock(
                token_address,
                channel,
                hashlock,
            )

        external_state = ChannelExternalState(
            register_channel_for_hashlock,
            netting_channel,
        )
        details = ChannelDetails(
            serialized_channel.channel_address,
            our_state,
            partner_state,
            external_state,
            serialized_channel.reveal_timeout,
            channel_details['settle_timeout'],
        )

        graph = self.token_to_channelgraph[token_address]
        graph.add_channel(details)
        channel = graph.address_to_channel.get(
            serialized_channel.channel_address,
        )

        channel.our_state.balance_proof = serialized_channel.our_balance_proof
        channel.partner_state.balance_proof = serialized_channel.partner_balance_proof
Beispiel #8
0
def channel_from_nettingcontract(
        our_key,
        netting_contract,
        external_state,
        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

    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 = ChannelEndState(
        our_address,
        our_balance,
        None,
        EMPTY_MERKLE_TREE,
    )
    partner_state = ChannelEndState(
        partner_address,
        partner_balance,
        None,
        EMPTY_MERKLE_TREE,
    )

    channel = Channel(
        our_state,
        partner_state,
        external_state,
        token_address,
        reveal_timeout,
        settle_timeout,
    )

    return channel
Beispiel #9
0
def test_invalid_timeouts():
    netting_channel = NettingChannelMock()
    token_address = make_address()
    reveal_timeout = 5
    settle_timeout = 15

    address1 = make_address()
    address2 = make_address()
    balance1 = 10
    balance2 = 10
    block_number = 10

    our_state = ChannelEndState(address1, balance1, netting_channel.opened())
    partner_state = ChannelEndState(address2, balance2,
                                    netting_channel.opened())
    external_state = make_external_state()

    # do not allow a reveal timeout larger than the settle timeout
    with pytest.raises(ValueError):
        large_reveal_timeout = 50
        small_settle_timeout = 49

        Channel(
            our_state,
            partner_state,
            external_state,
            token_address,
            large_reveal_timeout,
            small_settle_timeout,
            block_number,
        )

    for invalid_value in (-1, 0, 1.1, 1.0, 'a', [], {}):
        with pytest.raises(ValueError):
            Channel(
                our_state,
                partner_state,
                external_state,
                token_address,
                invalid_value,
                settle_timeout,
                block_number,
            )

        with pytest.raises(ValueError):
            Channel(
                our_state,
                partner_state,
                external_state,
                token_address,
                reveal_timeout,
                invalid_value,
                block_number,
            )
Beispiel #10
0
def channel_from_nettingcontract(our_key, netting_contract, external_state,
                                 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)

    asset_address_hex = netting_contract.assetAddress(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

    asset_address = decode_hex(asset_address_hex)
    address1 = decode_hex(address1_hex)
    address2 = decode_hex(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 = ChannelEndState(
        our_address,
        our_balance,
        external_state.opened_block,
    )
    partner_state = ChannelEndState(
        partner_address,
        partner_balance,
        external_state.opened_block,
    )

    channel = Channel(
        our_state,
        partner_state,
        external_state,
        asset_address,
        reveal_timeout,
        settle_timeout,
    )

    return channel
Beispiel #11
0
def test_invalid_timeouts():
    token_address = make_address()
    reveal_timeout = 5
    settle_timeout = 15

    address1 = make_address()
    address2 = make_address()
    balance1 = 10
    balance2 = 10

    our_state = ChannelEndState(address1, balance1, None, EMPTY_MERKLE_TREE)
    partner_state = ChannelEndState(address2, balance2, None,
                                    EMPTY_MERKLE_TREE)
    external_state = make_external_state()

    # do not allow a reveal timeout larger than the settle timeout
    with pytest.raises(ValueError):
        large_reveal_timeout = 50
        small_settle_timeout = 49

        Channel(
            our_state,
            partner_state,
            external_state,
            token_address,
            large_reveal_timeout,
            small_settle_timeout,
        )

    for invalid_value in (-1, 0, 1.1, 1.0, 'a', [], {}):
        with pytest.raises(ValueError):
            Channel(
                our_state,
                partner_state,
                external_state,
                token_address,
                invalid_value,
                settle_timeout,
            )

        with pytest.raises(ValueError):
            Channel(
                our_state,
                partner_state,
                external_state,
                token_address,
                reveal_timeout,
                invalid_value,
            )
Beispiel #12
0
def test_channel_increase_nonce_and_transferred_amount():
    """ The nonce must increase with each new transfer. """
    token_address = make_address()
    privkey1, address1 = make_privkey_address()
    address2 = make_address()

    balance1 = 70
    balance2 = 110

    reveal_timeout = 5
    settle_timeout = 15

    our_state = ChannelEndState(address1, balance1, None, EMPTY_MERKLE_TREE)
    partner_state = ChannelEndState(address2, balance2, None,
                                    EMPTY_MERKLE_TREE)
    external_state = make_external_state()

    test_channel = Channel(
        our_state,
        partner_state,
        external_state,
        token_address,
        reveal_timeout,
        settle_timeout,
    )

    previous_nonce = test_channel.get_next_nonce()
    previous_transferred = test_channel.transferred_amount

    amount = 7
    block_number = 1
    for _ in range(10):
        direct_transfer = test_channel.create_directtransfer(amount,
                                                             identifier=1)
        direct_transfer.sign(privkey1, address1)
        test_channel.register_transfer(block_number, direct_transfer)

        new_nonce = test_channel.get_next_nonce()
        new_transferred = test_channel.transferred_amount

        assert new_nonce == previous_nonce + 1
        assert new_transferred == previous_transferred + amount

        previous_nonce = new_nonce
        previous_transferred = new_transferred
Beispiel #13
0
    def get_channel_details(self, token_address, netting_channel):
        channel_details = netting_channel.detail()
        our_state = ChannelEndState(
            channel_details['our_address'],
            channel_details['our_balance'],
            None,
            EMPTY_MERKLE_TREE,
        )
        partner_state = ChannelEndState(
            channel_details['partner_address'],
            channel_details['partner_balance'],
            None,
            EMPTY_MERKLE_TREE,
        )

        def register_channel_for_hashlock(channel, hashlock):
            self.register_channel_for_hashlock(
                token_address,
                channel,
                hashlock,
            )

        channel_address = netting_channel.address
        reveal_timeout = self.config['reveal_timeout']
        settle_timeout = channel_details['settle_timeout']

        external_state = ChannelExternalState(
            register_channel_for_hashlock,
            netting_channel,
        )

        channel_detail = ChannelDetails(
            channel_address,
            our_state,
            partner_state,
            external_state,
            reveal_timeout,
            settle_timeout,
        )

        return channel_detail
    def make_channel(
            self,
            token_address=make_address(),
            partner_address=make_address(),
            reveal_timeout=20,
            settle_timeout=800,
            balance=0,
            block_number=1):

        our_address = make_address()
        our_balance = balance
        partner_balance = balance
        our_state = ChannelEndState(
            our_address,
            our_balance,
            None,
            EMPTY_MERKLE_TREE,
        )
        partner_state = ChannelEndState(
            partner_address,
            partner_balance,
            None,
            EMPTY_MERKLE_TREE,
        )

        channel_for_hashlock = list()
        netting_channel = NettingChannelMock(make_address())
        external_state = ChannelExternalState(
            lambda *args: channel_for_hashlock.append(args),
            netting_channel,
        )
        self.tokens.add(token_address)
        return Channel(
            our_state,
            partner_state,
            external_state,
            token_address,
            reveal_timeout,
            settle_timeout,
        )
Beispiel #15
0
def test_end_state():
    netting_channel = NettingChannelMock()
    token_address = make_address()
    privkey1, address1 = make_privkey_address()
    address2 = make_address()

    balance1 = 70
    balance2 = 110

    lock_secret = sha3('test_end_state')
    lock_amount = 30
    lock_expiration = 10
    lock_hashlock = sha3(lock_secret)

    state1 = ChannelEndState(address1, balance1, netting_channel.opened)
    state2 = ChannelEndState(address2, balance2, netting_channel.opened)

    assert state1.contract_balance == balance1
    assert state2.contract_balance == balance2
    assert state1.balance(state2) == balance1
    assert state2.balance(state1) == balance2

    assert state1.distributable(state2) == balance1
    assert state2.distributable(state1) == balance2

    assert state1.locked() == 0
    assert state2.locked() == 0

    assert state1.balance_proof.is_pending(lock_hashlock) is False
    assert state2.balance_proof.is_pending(lock_hashlock) is False

    assert state1.balance_proof.merkleroot_for_unclaimed() == ''
    assert state2.balance_proof.merkleroot_for_unclaimed() == ''

    lock = Lock(
        lock_amount,
        lock_expiration,
        lock_hashlock,
    )
    lock_hash = sha3(lock.as_bytes)

    transferred_amount = 0
    locksroot = state2.compute_merkleroot_with(lock)

    locked_transfer = LockedTransfer(
        1,  # TODO: fill in identifier
        nonce=state1.nonce,
        token=token_address,
        transferred_amount=transferred_amount,
        recipient=state2.address,
        locksroot=locksroot,
        lock=lock,
    )

    transfer_target = make_address()
    transfer_initiator = make_address()
    fee = 0
    mediated_transfer = locked_transfer.to_mediatedtransfer(
        transfer_target,
        transfer_initiator,
        fee,
    )
    mediated_transfer.sign(privkey1, address1)

    state2.register_locked_transfer(mediated_transfer)

    assert state1.contract_balance == balance1
    assert state2.contract_balance == balance2
    assert state1.balance(state2) == balance1
    assert state2.balance(state1) == balance2

    assert state1.distributable(state2) == balance1 - lock_amount
    assert state2.distributable(state1) == balance2

    assert state1.locked() == 0
    assert state2.locked() == lock_amount

    assert state1.balance_proof.is_pending(lock_hashlock) is False
    assert state2.balance_proof.is_pending(lock_hashlock) is True

    assert state1.balance_proof.merkleroot_for_unclaimed() == ''
    assert state2.balance_proof.merkleroot_for_unclaimed() == lock_hash

    with pytest.raises(ValueError):
        state1.update_contract_balance(balance1 - 10)

    state1.update_contract_balance(balance1 + 10)

    assert state1.contract_balance == balance1 + 10
    assert state2.contract_balance == balance2
    assert state1.balance(state2) == balance1 + 10
    assert state2.balance(state1) == balance2

    assert state1.distributable(state2) == balance1 - lock_amount + 10
    assert state2.distributable(state1) == balance2

    assert state1.locked() == 0
    assert state2.locked() == lock_amount

    assert state1.balance_proof.is_pending(lock_hashlock) is False
    assert state2.balance_proof.is_pending(lock_hashlock) is True

    assert state1.balance_proof.merkleroot_for_unclaimed() == ''
    assert state2.balance_proof.merkleroot_for_unclaimed() == lock_hash

    # registering the secret should not change the locked amount
    state2.register_secret(lock_secret)

    assert state1.contract_balance == balance1 + 10
    assert state2.contract_balance == balance2
    assert state1.balance(state2) == balance1 + 10
    assert state2.balance(state1) == balance2

    assert state1.distributable(state2) == balance1 - lock_amount + 10
    assert state2.distributable(state1) == balance2

    assert state1.locked() == 0
    assert state2.locked() == lock_amount

    assert state1.balance_proof.is_pending(lock_hashlock) is False
    assert state2.balance_proof.is_pending(lock_hashlock) is False

    assert state1.balance_proof.merkleroot_for_unclaimed() == ''
    assert state2.balance_proof.merkleroot_for_unclaimed() == lock_hash

    state2.release_lock(state1, lock_secret)

    assert state1.contract_balance == balance1 + 10
    assert state2.contract_balance == balance2
    assert state1.balance(state2) == balance1 + 10 - lock_amount
    assert state2.balance(state1) == balance2 + lock_amount

    assert state1.distributable(state2) == balance1 + 10 - lock_amount
    assert state2.distributable(state1) == balance2 + lock_amount

    assert state1.locked() == 0
    assert state2.locked() == 0

    assert state1.balance_proof.is_pending(lock_hashlock) is False
    assert state2.balance_proof.is_pending(lock_hashlock) is False

    assert state1.balance_proof.merkleroot_for_unclaimed() == ''
    assert state2.balance_proof.merkleroot_for_unclaimed() == ''
Beispiel #16
0
def test_python_channel():
    netting_channel = NettingChannelMock()
    token_address = make_address()
    privkey1, address1 = make_privkey_address()
    address2 = make_address()

    balance1 = 70
    balance2 = 110

    reveal_timeout = 5
    settle_timeout = 15

    our_state = ChannelEndState(address1, balance1, netting_channel.opened)
    partner_state = ChannelEndState(address2, balance2, netting_channel.opened)
    external_state = make_external_state()

    test_channel = Channel(
        our_state,
        partner_state,
        external_state,
        token_address,
        reveal_timeout,
        settle_timeout,
    )

    assert test_channel.contract_balance == our_state.contract_balance
    assert test_channel.balance == our_state.balance(partner_state)
    assert test_channel.transferred_amount == our_state.transferred_amount
    assert test_channel.distributable == our_state.distributable(partner_state)
    assert test_channel.outstanding == our_state.locked()
    assert test_channel.outstanding == 0
    assert test_channel.locked == partner_state.locked()
    assert test_channel.our_state.locked() == 0
    assert test_channel.partner_state.locked() == 0

    with pytest.raises(ValueError):
        test_channel.create_directtransfer(
            -10,
            1  # TODO: fill in identifier
        )

    with pytest.raises(ValueError):
        test_channel.create_directtransfer(
            balance1 + 10,
            1  # TODO: fill in identifier
        )

    amount1 = 10
    directtransfer = test_channel.create_directtransfer(
        amount1,
        1  # TODO: fill in identifier
    )
    directtransfer.sign(privkey1, address1)
    test_channel.register_transfer(directtransfer)

    assert test_channel.contract_balance == balance1
    assert test_channel.balance == balance1 - amount1
    assert test_channel.transferred_amount == amount1
    assert test_channel.distributable == balance1 - amount1
    assert test_channel.outstanding == 0
    assert test_channel.locked == 0
    assert test_channel.our_state.locked() == 0
    assert test_channel.partner_state.locked() == 0

    secret = sha3('test_channel')
    hashlock = sha3(secret)
    amount2 = 10
    fee = 0
    expiration = settle_timeout - 5
    mediatedtransfer = test_channel.create_mediatedtransfer(
        address1,
        address2,
        fee,
        amount2,
        1,  # TODO: fill in identifier
        expiration,
        hashlock,
    )
    mediatedtransfer.sign(privkey1, address1)

    test_channel.register_transfer(mediatedtransfer)

    assert test_channel.contract_balance == balance1
    assert test_channel.balance == balance1 - amount1
    assert test_channel.transferred_amount == amount1
    assert test_channel.distributable == balance1 - amount1 - amount2
    assert test_channel.outstanding == 0
    assert test_channel.locked == amount2
    assert test_channel.our_state.locked() == 0
    assert test_channel.partner_state.locked() == amount2

    test_channel.release_lock(secret)

    assert test_channel.contract_balance == balance1
    assert test_channel.balance == balance1 - amount1 - amount2
    assert test_channel.transferred_amount == amount1 + amount2
    assert test_channel.distributable == balance1 - amount1 - amount2
    assert test_channel.outstanding == 0
    assert test_channel.locked == 0
    assert test_channel.our_state.locked() == 0
    assert test_channel.partner_state.locked() == 0
Beispiel #17
0
    def register_channel(self, netting_channel, reveal_timeout):
        """ Register a new channel.

        Args:
            netting_channel (network.rpc.client.NettingChannel): The netting channel proxy.
            reveal_timeout (int): Minimum number of blocks required by this
                node to see a secret.

        Raises:
            ValueError: If raiden.address is not one of the participants in the
                netting channel.
        """
        translator = ContractTranslator(NETTING_CHANNEL_ABI)

        # race condition:
        # - if the filter is installed after a deposit is made it could be
        # missed, to avoid that we first install the filter, then request the
        # state from the node and then poll the filter.
        # - with the above strategy the same deposit could be handled twice,
        # once from the status received from the netting contract and once from
        # the event, to avoid problems the we use the balance instead of the
        # deposit is used.
        newbalance = netting_channel.channelnewbalance_filter()
        newbalance_listener = LogListenerTask(
            newbalance,
            self.raiden.on_event,
            translator,
        )

        secretrevealed = netting_channel.channelsecretrevealed_filter()
        secretrevealed_listener = LogListenerTask(
            secretrevealed,
            self.raiden.on_event,
            translator,
        )

        close = netting_channel.channelclosed_filter()
        close_listener = LogListenerTask(
            close,
            self.raiden.on_event,
            translator,
        )

        settled = netting_channel.channelsettled_filter()
        settled_listener = LogListenerTask(
            settled,
            self.raiden.on_event,
            translator,
        )

        channel_details = netting_channel.detail(self.raiden.address)
        our_state = ChannelEndState(
            channel_details['our_address'],
            channel_details['our_balance'],
        )
        partner_state = ChannelEndState(
            channel_details['partner_address'],
            channel_details['partner_balance'],
        )

        external_state = ChannelExternalState(
            self.register_channel_for_hashlock,
            self.raiden.chain.block_number,
            netting_channel,
        )

        channel = Channel(
            our_state,
            partner_state,
            external_state,

            self.asset_address,
            reveal_timeout,
            channel_details['settle_timeout'],
        )

        self.partneraddress_channel[partner_state.address] = channel
        self.address_channel[netting_channel.address] = channel

        self.channelgraph.add_path(
            channel_details['our_address'],
            channel_details['partner_address'],
        )

        newbalance_listener.start()
        secretrevealed_listener.start()
        close_listener.start()
        settled_listener.start()

        self.raiden.event_listeners.append(newbalance_listener)
        self.raiden.event_listeners.append(secretrevealed_listener)
        self.raiden.event_listeners.append(close_listener)
        self.raiden.event_listeners.append(settled_listener)
Beispiel #18
0
    def register_channel(self, netting_channel, reveal_timeout):
        """ Register a new channel.

        Args:
            netting_channel (network.rpc.client.NettingChannel): The netting channel proxy.
            reveal_timeout (int): Minimum number of blocks required by this
                node to see a secret.

        Raises:
            ValueError: If raiden.address is not one of the participants in the
                netting channel.
        """
        translator = ContractTranslator(NETTING_CHANNEL_ABI)

        # Race condition:
        # - If the filter is installed after the call to `details` a deposit
        # could be missed in the meantime, to avoid this we first install the
        # filter listener and then call `deposit`.
        # - Because of the above strategy a `deposit` event could be handled
        # twice, for this reason we must not use `deposit` in the events but
        # the resulting `balance`.

        task_name = 'ChannelNewBalance {}'.format(pex(netting_channel.address))
        newbalance = netting_channel.channelnewbalance_filter()
        newbalance_listener = LogListenerTask(
            task_name,
            newbalance,
            self.raiden.on_event,
            translator,
        )

        task_name = 'ChannelSecretRevelead {}'.format(
            pex(netting_channel.address))
        secretrevealed = netting_channel.channelsecretrevealed_filter()
        secretrevealed_listener = LogListenerTask(
            task_name,
            secretrevealed,
            self.raiden.on_event,
            translator,
        )

        task_name = 'ChannelClosed {}'.format(pex(netting_channel.address))
        close = netting_channel.channelclosed_filter()
        close_listener = LogListenerTask(
            task_name,
            close,
            self.raiden.on_event,
            translator,
        )

        task_name = 'ChannelSettled {}'.format(pex(netting_channel.address))
        settled = netting_channel.channelsettled_filter()
        settled_listener = LogListenerTask(
            task_name,
            settled,
            self.raiden.on_event,
            translator,
        )

        channel_details = netting_channel.detail(self.raiden.address)
        our_state = ChannelEndState(
            channel_details['our_address'],
            channel_details['our_balance'],
        )
        partner_state = ChannelEndState(
            channel_details['partner_address'],
            channel_details['partner_balance'],
        )

        external_state = ChannelExternalState(
            self.raiden.alarm.register_callback,
            self.register_channel_for_hashlock,
            self.raiden.chain.block_number,
            netting_channel,
        )

        channel = Channel(
            our_state,
            partner_state,
            external_state,
            self.asset_address,
            reveal_timeout,
            channel_details['settle_timeout'],
        )

        self.partneraddress_channel[partner_state.address] = channel
        self.address_channel[netting_channel.address] = channel

        newbalance_listener.start()
        secretrevealed_listener.start()
        close_listener.start()
        settled_listener.start()

        self.raiden.event_listeners.append(newbalance_listener)
        self.raiden.event_listeners.append(secretrevealed_listener)
        self.raiden.event_listeners.append(close_listener)
        self.raiden.event_listeners.append(settled_listener)
Beispiel #19
0
def test_end_state():
    token_address = make_address()
    privkey1, address1 = make_privkey_address()
    address2 = make_address()
    channel_address = make_address()

    balance1 = 70
    balance2 = 110

    lock_secret = sha3('test_end_state')
    lock_amount = 30
    lock_expiration = 10
    lock_hashlock = sha3(lock_secret)

    state1 = ChannelEndState(address1, balance1, None, EMPTY_MERKLE_TREE)
    state2 = ChannelEndState(address2, balance2, None, EMPTY_MERKLE_TREE)

    assert state1.contract_balance == balance1
    assert state2.contract_balance == balance2
    assert state1.balance(state2) == balance1
    assert state2.balance(state1) == balance2


    assert state1.is_locked(lock_hashlock) is False
    assert state2.is_locked(lock_hashlock) is False

    assert merkleroot(state1.merkletree) == EMPTY_MERKLE_ROOT
    assert merkleroot(state2.merkletree) == EMPTY_MERKLE_ROOT

    assert state1.nonce is None
    assert state2.nonce is None

    lock = Lock(
        lock_amount,
        lock_expiration,
        lock_hashlock,
    )
    lock_hash = sha3(lock.as_bytes)

    transferred_amount = 0
    locksroot = state2.compute_merkleroot_with(lock)

    locked_transfer = LockedTransfer(
        1,
        nonce=1,
        token=token_address,
        channel=channel_address,
        transferred_amount=transferred_amount,
        recipient=state2.address,
        locksroot=locksroot,
        lock=lock,
    )

    transfer_target = make_address()
    transfer_initiator = make_address()
    fee = 0
    mediated_transfer = locked_transfer.to_mediatedtransfer(
        transfer_target,
        transfer_initiator,
        fee,
    )
    mediated_transfer.sign(privkey1, address1)

    state1.register_locked_transfer(mediated_transfer)

    assert state1.contract_balance == balance1
    assert state2.contract_balance == balance2
    assert state1.balance(state2) == balance1
    assert state2.balance(state1) == balance2

    assert state1.distributable(state2) == balance1 - lock_amount
    assert state2.distributable(state1) == balance2

    assert state1.amount_locked == lock_amount
    assert state2.amount_locked == 0

    assert state1.is_locked(lock_hashlock) is True
    assert state2.is_locked(lock_hashlock) is False

    assert merkleroot(state1.merkletree) == lock_hash
    assert merkleroot(state2.merkletree) == EMPTY_MERKLE_ROOT

    assert state1.nonce is 1
    assert state2.nonce is None

    with pytest.raises(ValueError):
        state1.update_contract_balance(balance1 - 10)

    state1.update_contract_balance(balance1 + 10)

    assert state1.contract_balance == balance1 + 10
    assert state2.contract_balance == balance2
    assert state1.balance(state2) == balance1 + 10
    assert state2.balance(state1) == balance2

    assert state1.distributable(state2) == balance1 - lock_amount + 10
    assert state2.distributable(state1) == balance2

    assert state1.amount_locked == lock_amount
    assert state2.amount_locked == 0

    assert state1.is_locked(lock_hashlock) is True
    assert state2.is_locked(lock_hashlock) is False

    assert merkleroot(state1.merkletree) == lock_hash
    assert merkleroot(state2.merkletree) == EMPTY_MERKLE_ROOT

    assert state1.nonce is 1
    assert state2.nonce is None

    # registering the secret should not change the locked amount
    state1.register_secret(lock_secret)

    assert state1.contract_balance == balance1 + 10
    assert state2.contract_balance == balance2
    assert state1.balance(state2) == balance1 + 10
    assert state2.balance(state1) == balance2


    assert state1.is_locked(lock_hashlock) is False
    assert state2.is_locked(lock_hashlock) is False

    assert merkleroot(state1.merkletree) == lock_hash
    assert merkleroot(state2.merkletree) == EMPTY_MERKLE_ROOT

    assert state1.nonce is 1
    assert state2.nonce is None

    secret_message = Secret(
        identifier=1,
        nonce=2,
        channel=channel_address,
        transferred_amount=transferred_amount + lock_amount,
        locksroot=EMPTY_MERKLE_ROOT,
        secret=lock_secret,
    )
    secret_message.sign(privkey1, address1)
    state1.register_secretmessage(secret_message)

    assert state1.contract_balance == balance1 + 10
    assert state2.contract_balance == balance2
    assert state1.balance(state2) == balance1 + 10 - lock_amount
    assert state2.balance(state1) == balance2 + lock_amount

    assert state1.distributable(state2) == balance1 + 10 - lock_amount
    assert state2.distributable(state1) == balance2 + lock_amount

    assert state1.amount_locked == 0
    assert state2.amount_locked == 0

    assert state1.is_locked(lock_hashlock) is False
    assert state2.is_locked(lock_hashlock) is False

    assert merkleroot(state1.merkletree) == EMPTY_MERKLE_ROOT
    assert merkleroot(state2.merkletree) == EMPTY_MERKLE_ROOT

    assert state1.nonce is 2
    assert state2.nonce is None
Beispiel #20
0
def test_python_channel():
    token_address = make_address()
    privkey1, address1 = make_privkey_address()
    address2 = make_address()

    balance1 = 70
    balance2 = 110

    reveal_timeout = 5
    settle_timeout = 15
    block_number = 10

    our_state = ChannelEndState(address1, balance1, None, EMPTY_MERKLE_TREE)
    partner_state = ChannelEndState(address2, balance2, None, EMPTY_MERKLE_TREE)
    external_state = make_external_state()

    test_channel = Channel(
        our_state,
        partner_state,
        external_state,
        token_address,
        reveal_timeout,
        settle_timeout,
    )

    assert test_channel.contract_balance == our_state.contract_balance
    assert test_channel.transferred_amount == our_state.transferred_amount
    assert test_channel.distributable == our_state.contract_balance
    assert test_channel.outstanding == our_state.amount_locked
    assert test_channel.outstanding == 0
    assert test_channel.locked == partner_state.amount_locked
    assert test_channel.our_state.amount_locked == 0
    assert test_channel.partner_state.amount_locked == 0
    assert test_channel.get_next_nonce() == 1

    with pytest.raises(ValueError):
        test_channel.create_directtransfer(
            -10,
            identifier=1,
        )

    with pytest.raises(ValueError):
        test_channel.create_directtransfer(
            balance1 + 10,
            identifier=1,
        )

    amount1 = 10
    directtransfer = test_channel.create_directtransfer(
        amount1,
        identifier=1,
    )
    directtransfer.sign(privkey1, address1)
    test_channel.register_transfer(
        block_number,
        directtransfer,
    )

    assert test_channel.contract_balance == balance1
    assert test_channel.balance == balance1 - amount1
    assert test_channel.transferred_amount == amount1
    assert test_channel.distributable == balance1 - amount1
    assert test_channel.outstanding == 0
    assert test_channel.locked == 0
    assert test_channel.our_state.amount_locked == 0
    assert test_channel.partner_state.amount_locked == 0
    assert test_channel.get_next_nonce() == 2

    secret = sha3('test_channel')
    hashlock = sha3(secret)
    amount2 = 10
    fee = 0
    expiration = block_number + settle_timeout - 5
    identifier = 1
    mediatedtransfer = test_channel.create_mediatedtransfer(
        address1,
        address2,
        fee,
        amount2,
        identifier,
        expiration,
        hashlock,
    )
    mediatedtransfer.sign(privkey1, address1)

    test_channel.register_transfer(
        block_number,
        mediatedtransfer,
    )

    assert test_channel.contract_balance == balance1
    assert test_channel.balance == balance1 - amount1
    assert test_channel.transferred_amount == amount1
    assert test_channel.distributable == balance1 - amount1 - amount2
    assert test_channel.outstanding == 0
    assert test_channel.locked == amount2
    assert test_channel.our_state.amount_locked == amount2
    assert test_channel.partner_state.amount_locked == 0
    assert test_channel.get_next_nonce() == 3

    secret_message = test_channel.create_secret(identifier, secret)
    secret_message.sign(privkey1, address1)
    test_channel.register_transfer(block_number, secret_message)

    assert test_channel.contract_balance == balance1
    assert test_channel.balance == balance1 - amount1 - amount2
    assert test_channel.transferred_amount == amount1 + amount2
    assert test_channel.distributable == balance1 - amount1 - amount2
    assert test_channel.outstanding == 0
    assert test_channel.locked == 0
    assert test_channel.our_state.amount_locked == 0
    assert test_channel.partner_state.amount_locked == 0
    assert test_channel.get_next_nonce() == 4
Beispiel #21
0
def test_receiver_cannot_spend_locked_amount():
    token_address = make_address()
    privkey1, address1 = make_privkey_address()
    privkey2, address2 = make_privkey_address()

    balance1 = 33
    balance2 = 11

    reveal_timeout = 7
    settle_timeout = 21
    block_number = 7

    our_state = ChannelEndState(address1, balance1, None, EMPTY_MERKLE_TREE)
    partner_state = ChannelEndState(address2, balance2, None, EMPTY_MERKLE_TREE)
    external_state = make_external_state()

    test_channel = Channel(
        our_state,
        partner_state,
        external_state,
        token_address,
        reveal_timeout,
        settle_timeout,
    )

    amount1 = balance2
    expiration = block_number + settle_timeout
    receive_mediated_transfer0 = test_channel.create_mediatedtransfer(
        address1,
        address2,
        fee=0,
        amount=amount1,
        identifier=1,
        expiration=expiration,
        hashlock=sha3('test_locked_amount_cannot_be_spent'),
    )
    receive_mediated_transfer0.sign(privkey2, address2)

    test_channel.register_transfer(
        block_number,
        receive_mediated_transfer0,
    )

    # trying to send one unit of the locked token
    amount2 = balance1 + 1
    lock2 = Lock(
        amount=amount2,
        expiration=expiration,
        hashlock=sha3('test_locked_amount_cannot_be_spent2'),
    )
    layers = compute_layers([sha3(lock2.as_bytes)])
    tree2 = MerkleTreeState(layers)
    locksroot2 = merkleroot(tree2)

    send_mediated_transfer0 = MediatedTransfer(
        identifier=1,
        nonce=1,
        token=token_address,
        channel=test_channel.channel_address,
        transferred_amount=0,
        recipient=address2,
        locksroot=locksroot2,
        lock=lock2,
        target=address2,
        initiator=address1,
        fee=0,
    )
    send_mediated_transfer0.sign(privkey1, address1)

    # address1 balance is all locked
    with pytest.raises(InsufficientBalance):
        test_channel.register_transfer(
            block_number,
            send_mediated_transfer0,
        )
Beispiel #22
0
def test_sender_cannot_overspend():
    token_address = make_address()
    privkey1, address1 = make_privkey_address()
    address2 = make_address()

    balance1 = 70
    balance2 = 110

    reveal_timeout = 5
    settle_timeout = 15
    block_number = 10

    our_state = ChannelEndState(address1, balance1, None, EMPTY_MERKLE_TREE)
    partner_state = ChannelEndState(address2, balance2, None, EMPTY_MERKLE_TREE)
    external_state = make_external_state()

    test_channel = Channel(
        our_state,
        partner_state,
        external_state,
        token_address,
        reveal_timeout,
        settle_timeout,
    )

    amount = balance1
    expiration = block_number + settle_timeout
    sent_mediated_transfer0 = test_channel.create_mediatedtransfer(
        address1,
        address2,
        fee=0,
        amount=amount,
        identifier=1,
        expiration=expiration,
        hashlock=sha3('test_locked_amount_cannot_be_spent'),
    )
    sent_mediated_transfer0.sign(privkey1, address1)

    test_channel.register_transfer(
        block_number,
        sent_mediated_transfer0,
    )

    lock2 = Lock(
        amount=amount,
        expiration=expiration,
        hashlock=sha3('test_locked_amount_cannot_be_spent2'),
    )
    leaves = [
        sha3(sent_mediated_transfer0.lock.as_bytes),
        sha3(lock2.as_bytes),
    ]
    tree2 = MerkleTreeState(compute_layers(leaves))
    locksroot2 = merkleroot(tree2)

    sent_mediated_transfer1 = MediatedTransfer(
        identifier=2,
        nonce=sent_mediated_transfer0.nonce + 1,
        token=token_address,
        channel=test_channel.channel_address,
        transferred_amount=0,
        recipient=address2,
        locksroot=locksroot2,
        lock=lock2,
        target=address2,
        initiator=address1,
        fee=0,
    )
    sent_mediated_transfer1.sign(privkey1, address1)

    # address1 balance is all locked
    with pytest.raises(InsufficientBalance):
        test_channel.register_transfer(
            block_number,
            sent_mediated_transfer1,
        )
Beispiel #23
0
def test_python_channel():
    asset_address = make_address()
    privkey1, address1 = make_privkey_address()
    address2 = make_address()

    balance1 = 70
    balance2 = 110

    reveal_timeout = 5
    settle_timeout = 15

    our_state = ChannelEndState(address1, balance1)
    partner_state = ChannelEndState(address2, balance2)
    external_state = make_external_state()

    test_channel = Channel(
        our_state, partner_state, external_state,
        asset_address, reveal_timeout, settle_timeout,
    )

    assert test_channel.contract_balance == our_state.contract_balance
    assert test_channel.balance == our_state.balance(partner_state)
    assert test_channel.transferred_amount == our_state.transferred_amount
    assert test_channel.distributable == our_state.distributable(partner_state)
    assert test_channel.outstanding == our_state.locked()
    assert test_channel.outstanding == 0
    assert test_channel.locked == partner_state.locked()
    assert test_channel.our_state.locked() == 0
    assert test_channel.partner_state.locked() == 0

    with pytest.raises(ValueError):
        test_channel.create_directtransfer(
            -10,
            1  # TODO: fill in identifier
        )

    with pytest.raises(ValueError):
        test_channel.create_directtransfer(
            balance1 + 10,
            1  # TODO: fill in identifier
        )

    amount1 = 10
    directtransfer = test_channel.create_directtransfer(
        amount1,
        1  # TODO: fill in identifier
    )
    directtransfer.sign(privkey1, address1)
    test_channel.register_transfer(directtransfer)

    assert test_channel.contract_balance == balance1
    assert test_channel.balance == balance1 - amount1
    assert test_channel.transferred_amount == amount1
    assert test_channel.distributable == balance1 - amount1
    assert test_channel.outstanding == 0
    assert test_channel.locked == 0
    assert test_channel.our_state.locked() == 0
    assert test_channel.partner_state.locked() == 0

    secret = sha3('test_channel')
    hashlock = sha3(secret)
    amount2 = 10
    fee = 0
    expiration = settle_timeout - 5
    mediatedtransfer = test_channel.create_mediatedtransfer(
        address1,
        address2,
        fee,
        amount2,
        1,  # TODO: fill in identifier
        expiration,
        hashlock,
    )
    mediatedtransfer.sign(privkey1, address1)

    test_channel.register_transfer(mediatedtransfer)

    assert test_channel.contract_balance == balance1
    assert test_channel.balance == balance1 - amount1
    assert test_channel.transferred_amount == amount1
    assert test_channel.distributable == balance1 - amount1 - amount2
    assert test_channel.outstanding == 0
    assert test_channel.locked == amount2
    assert test_channel.our_state.locked() == 0
    assert test_channel.partner_state.locked() == amount2

    test_channel.release_lock(secret)

    assert test_channel.contract_balance == balance1
    assert test_channel.balance == balance1 - amount1 - amount2
    assert test_channel.transferred_amount == amount1 + amount2
    assert test_channel.distributable == balance1 - amount1 - amount2
    assert test_channel.outstanding == 0
    assert test_channel.locked == 0
    assert test_channel.our_state.locked() == 0
    assert test_channel.partner_state.locked() == 0
Beispiel #24
0
def test_end_state():
    asset_address = make_address()
    privkey1, address1 = make_privkey_address()
    address2 = make_address()

    balance1 = 70
    balance2 = 110

    lock_secret = sha3('test_end_state')
    lock_amount = 30
    lock_expiration = 10
    lock_hashlock = sha3(lock_secret)

    state1 = ChannelEndState(address1, balance1)
    state2 = ChannelEndState(address2, balance2)

    assert state1.contract_balance == balance1
    assert state2.contract_balance == balance2
    assert state1.balance(state2) == balance1
    assert state2.balance(state1) == balance2

    assert state1.distributable(state2) == balance1
    assert state2.distributable(state1) == balance2

    assert state1.locked() == 0
    assert state2.locked() == 0

    assert state1.balance_proof.is_pending(lock_hashlock) is False
    assert state2.balance_proof.is_pending(lock_hashlock) is False

    assert state1.balance_proof.merkleroot_for_unclaimed() == ''
    assert state2.balance_proof.merkleroot_for_unclaimed() == ''

    lock = Lock(
        lock_amount,
        lock_expiration,
        lock_hashlock,
    )
    lock_hash = sha3(lock.as_bytes)

    transferred_amount = 0
    locksroot = state2.compute_merkleroot_with(lock)

    locked_transfer = LockedTransfer(
        1,  # TODO: fill in identifier
        nonce=state1.nonce,
        asset=asset_address,
        transferred_amount=transferred_amount,
        recipient=state2.address,
        locksroot=locksroot,
        lock=lock,
    )

    transfer_target = make_address()
    transfer_initiator = make_address()
    fee = 0
    mediated_transfer = locked_transfer.to_mediatedtransfer(
        transfer_target,
        transfer_initiator,
        fee,
    )
    mediated_transfer.sign(privkey1, address1)

    state2.register_locked_transfer(mediated_transfer)

    assert state1.contract_balance == balance1
    assert state2.contract_balance == balance2
    assert state1.balance(state2) == balance1
    assert state2.balance(state1) == balance2

    assert state1.distributable(state2) == balance1 - lock_amount
    assert state2.distributable(state1) == balance2

    assert state1.locked() == 0
    assert state2.locked() == lock_amount

    assert state1.balance_proof.is_pending(lock_hashlock) is False
    assert state2.balance_proof.is_pending(lock_hashlock) is True

    assert state1.balance_proof.merkleroot_for_unclaimed() == ''
    assert state2.balance_proof.merkleroot_for_unclaimed() == lock_hash

    with pytest.raises(ValueError):
        state1.update_contract_balance(balance1 - 10)

    state1.update_contract_balance(balance1 + 10)

    assert state1.contract_balance == balance1 + 10
    assert state2.contract_balance == balance2
    assert state1.balance(state2) == balance1 + 10
    assert state2.balance(state1) == balance2

    assert state1.distributable(state2) == balance1 - lock_amount + 10
    assert state2.distributable(state1) == balance2

    assert state1.locked() == 0
    assert state2.locked() == lock_amount

    assert state1.balance_proof.is_pending(lock_hashlock) is False
    assert state2.balance_proof.is_pending(lock_hashlock) is True

    assert state1.balance_proof.merkleroot_for_unclaimed() == ''
    assert state2.balance_proof.merkleroot_for_unclaimed() == lock_hash

    # registering the secret should not change the locked amount
    state2.register_secret(lock_secret)

    assert state1.contract_balance == balance1 + 10
    assert state2.contract_balance == balance2
    assert state1.balance(state2) == balance1 + 10
    assert state2.balance(state1) == balance2

    assert state1.distributable(state2) == balance1 - lock_amount + 10
    assert state2.distributable(state1) == balance2

    assert state1.locked() == 0
    assert state2.locked() == lock_amount

    assert state1.balance_proof.is_pending(lock_hashlock) is False
    assert state2.balance_proof.is_pending(lock_hashlock) is False

    assert state1.balance_proof.merkleroot_for_unclaimed() == ''
    assert state2.balance_proof.merkleroot_for_unclaimed() == lock_hash

    state2.release_lock(state1, lock_secret)

    assert state1.contract_balance == balance1 + 10
    assert state2.contract_balance == balance2
    assert state1.balance(state2) == balance1 + 10 - lock_amount
    assert state2.balance(state1) == balance2 + lock_amount

    assert state1.distributable(state2) == balance1 + 10 - lock_amount
    assert state2.distributable(state1) == balance2 + lock_amount

    assert state1.locked() == 0
    assert state2.locked() == 0

    assert state1.balance_proof.is_pending(lock_hashlock) is False
    assert state2.balance_proof.is_pending(lock_hashlock) is False

    assert state1.balance_proof.merkleroot_for_unclaimed() == ''
    assert state2.balance_proof.merkleroot_for_unclaimed() == ''
Beispiel #25
0
    def register_channel(self, netting_channel, reveal_timeout):
        """ Register a new channel.

        Args:
            netting_channel (network.rpc.client.NettingChannel): The netting channel proxy.
            reveal_timeout (int): Minimum number of blocks required by this
                node to see a secret.

        Raises:
            ValueError:
                - If raiden.address is not one of the participants in the
                netting channel.
                - If the contract's settle_timeout is smaller than the
                reveal_timeout.
        """
        # pylint: disable=too-many-locals

        translator = ContractTranslator(NETTING_CHANNEL_ABI)

        # Race condition:
        # - If the filter is installed after the call to `details` a deposit
        # can be missed, to avoid this the listener is installed first.
        # - Because of the above a `ChannelNewBalance` event can be polled
        # after the `details` calls succeds so the effects  must be
        # idempotent.

        netting_channel_events = netting_channel.all_events_filter()

        channel_details = netting_channel.detail(self.raiden.address)
        our_state = ChannelEndState(
            channel_details['our_address'],
            channel_details['our_balance'],
            netting_channel.opened,
        )
        partner_state = ChannelEndState(
            channel_details['partner_address'],
            channel_details['partner_balance'],
            netting_channel.opened,
        )

        external_state = ChannelExternalState(
            self.raiden.alarm.register_callback,
            self.register_channel_for_hashlock,
            self.raiden.get_block_number,
            netting_channel,
        )

        channel = Channel(
            our_state,
            partner_state,
            external_state,
            self.token_address,
            reveal_timeout,
            channel_details['settle_timeout'],
        )

        self.partneraddress_channel[partner_state.address] = channel
        self.address_channel[netting_channel.address] = channel

        self.raiden.start_event_listener(
            'NettingChannel Event {}'.format(pex(netting_channel.address)),
            netting_channel_events,
            translator,
        )
Beispiel #26
0
def test_channel():
    class NettingChannelMock(object):
        def opened(self):
            return 1

        def closed(self):
            return 0

        def settled(self):
            return 0

    asset_address = make_address()
    privkey1, address1 = make_privkey_address()
    address2 = make_address()

    balance1 = 70
    balance2 = 110

    reveal_timeout = 5
    settle_timeout = 15

    our_state = ChannelEndState(address1, balance1)
    partner_state = ChannelEndState(address2, balance2)

    block_alarm = list()
    channel_for_hashlock = list()
    netting_channel = NettingChannelMock()

    external_state = ChannelExternalState(
        block_alarm.append,
        lambda *args: channel_for_hashlock.append(args),
        lambda: 1,
        netting_channel,
    )

    channel = Channel(
        our_state,
        partner_state,
        external_state,
        asset_address,
        reveal_timeout,
        settle_timeout,
    )

    assert channel.contract_balance == our_state.contract_balance
    assert channel.balance == our_state.balance(partner_state)
    assert channel.transfered_amount == our_state.transfered_amount
    assert channel.distributable == our_state.distributable(partner_state)
    assert channel.outstanding == our_state.locked()
    assert channel.outstanding == 0
    assert channel.locked == partner_state.locked()
    assert channel.our_state.locked() == 0
    assert channel.partner_state.locked() == 0

    with pytest.raises(ValueError):
        channel.create_directtransfer(-10)

    with pytest.raises(ValueError):
        channel.create_directtransfer(balance1 + 10)

    amount1 = 10
    directtransfer = channel.create_directtransfer(amount1)
    directtransfer.sign(privkey1, address1)
    channel.register_transfer(directtransfer)

    assert channel.contract_balance == balance1
    assert channel.balance == balance1 - amount1
    assert channel.transfered_amount == amount1
    assert channel.distributable == balance1 - amount1
    assert channel.outstanding == 0
    assert channel.locked == 0
    assert channel.our_state.locked() == 0
    assert channel.partner_state.locked() == 0

    secret = sha3('test_channel')
    hashlock = sha3(secret)
    amount2 = 10
    fee = 0
    expiration = settle_timeout - 5
    mediatedtransfer = channel.create_mediatedtransfer(
        address1,
        address2,
        fee,
        amount2,
        expiration,
        hashlock,
    )
    mediatedtransfer.sign(privkey1, address1)

    channel.register_transfer(mediatedtransfer)

    assert channel.contract_balance == balance1
    assert channel.balance == balance1 - amount1
    assert channel.transfered_amount == amount1
    assert channel.distributable == balance1 - amount1 - amount2
    assert channel.outstanding == 0
    assert channel.locked == amount2
    assert channel.our_state.locked() == 0
    assert channel.partner_state.locked() == amount2

    channel.claim_lock(secret)

    assert channel.contract_balance == balance1
    assert channel.balance == balance1 - amount1 - amount2
    assert channel.transfered_amount == amount1 + amount2
    assert channel.distributable == balance1 - amount1 - amount2
    assert channel.outstanding == 0
    assert channel.locked == 0
    assert channel.our_state.locked() == 0
    assert channel.partner_state.locked() == 0
Beispiel #27
0
    def restore_channel(self, serialized_channel):
        token_address = serialized_channel.token_address

        netting_channel = self.chain.netting_channel(
            serialized_channel.channel_address, )

        # restoring balances from the blockchain since the serialized
        # value could be falling behind.
        channel_details = netting_channel.detail()

        # our_address is checked by detail
        assert channel_details[
            'partner_address'] == serialized_channel.partner_address

        if serialized_channel.our_leaves:
            our_layers = compute_layers(serialized_channel.our_leaves)
            our_tree = MerkleTreeState(our_layers)
        else:
            our_tree = EMPTY_MERKLE_TREE

        our_state = ChannelEndState(
            channel_details['our_address'],
            channel_details['our_balance'],
            serialized_channel.our_balance_proof,
            our_tree,
        )

        if serialized_channel.partner_leaves:
            partner_layers = compute_layers(serialized_channel.partner_leaves)
            partner_tree = MerkleTreeState(partner_layers)
        else:
            partner_tree = EMPTY_MERKLE_TREE

        partner_state = ChannelEndState(
            channel_details['partner_address'],
            channel_details['partner_balance'],
            serialized_channel.partner_balance_proof,
            partner_tree,
        )

        def register_channel_for_hashlock(channel, hashlock):
            self.register_channel_for_hashlock(
                token_address,
                channel,
                hashlock,
            )

        external_state = ChannelExternalState(
            register_channel_for_hashlock,
            netting_channel,
        )
        details = ChannelDetails(
            serialized_channel.channel_address,
            our_state,
            partner_state,
            external_state,
            serialized_channel.reveal_timeout,
            channel_details['settle_timeout'],
        )

        graph = self.token_to_channelgraph[token_address]
        graph.add_channel(details)
        channel = graph.address_to_channel.get(
            serialized_channel.channel_address, )

        channel.our_state.balance_proof = serialized_channel.our_balance_proof
        channel.partner_state.balance_proof = serialized_channel.partner_balance_proof
def test_end_state():
    token_address = make_address()
    privkey1, address1 = make_privkey_address()
    address2 = make_address()
    channel_address = make_address()

    balance1 = 70
    balance2 = 110

    lock_secret = sha3(b'test_end_state')
    lock_amount = 30
    lock_expiration = 10
    lock_hashlock = sha3(lock_secret)

    state1 = ChannelEndState(address1, balance1, None, EMPTY_MERKLE_TREE)
    state2 = ChannelEndState(address2, balance2, None, EMPTY_MERKLE_TREE)

    assert state1.contract_balance == balance1
    assert state2.contract_balance == balance2
    assert state1.balance(state2) == balance1
    assert state2.balance(state1) == balance2

    assert state1.is_locked(lock_hashlock) is False
    assert state2.is_locked(lock_hashlock) is False

    assert merkleroot(state1.merkletree) == EMPTY_MERKLE_ROOT
    assert merkleroot(state2.merkletree) == EMPTY_MERKLE_ROOT

    assert state1.nonce is None
    assert state2.nonce is None

    lock = Lock(
        lock_amount,
        lock_expiration,
        lock_hashlock,
    )
    lock_hash = sha3(lock.as_bytes)

    transferred_amount = 0
    locksroot = state2.compute_merkleroot_with(lock)

    locked_transfer = LockedTransfer(
        1,
        nonce=1,
        token=token_address,
        channel=channel_address,
        transferred_amount=transferred_amount,
        recipient=state2.address,
        locksroot=locksroot,
        lock=lock,
    )

    transfer_target = make_address()
    transfer_initiator = make_address()
    fee = 0
    mediated_transfer = locked_transfer.to_mediatedtransfer(
        transfer_target,
        transfer_initiator,
        fee,
    )
    mediated_transfer.sign(privkey1, address1)

    state1.register_locked_transfer(mediated_transfer)

    assert state1.contract_balance == balance1
    assert state2.contract_balance == balance2
    assert state1.balance(state2) == balance1
    assert state2.balance(state1) == balance2

    assert state1.distributable(state2) == balance1 - lock_amount
    assert state2.distributable(state1) == balance2

    assert state1.amount_locked == lock_amount
    assert state2.amount_locked == 0

    assert state1.is_locked(lock_hashlock) is True
    assert state2.is_locked(lock_hashlock) is False

    assert merkleroot(state1.merkletree) == lock_hash
    assert merkleroot(state2.merkletree) == EMPTY_MERKLE_ROOT

    assert state1.nonce is 1
    assert state2.nonce is None

    with pytest.raises(ValueError):
        state1.update_contract_balance(balance1 - 10)

    state1.update_contract_balance(balance1 + 10)

    assert state1.contract_balance == balance1 + 10
    assert state2.contract_balance == balance2
    assert state1.balance(state2) == balance1 + 10
    assert state2.balance(state1) == balance2

    assert state1.distributable(state2) == balance1 - lock_amount + 10
    assert state2.distributable(state1) == balance2

    assert state1.amount_locked == lock_amount
    assert state2.amount_locked == 0

    assert state1.is_locked(lock_hashlock) is True
    assert state2.is_locked(lock_hashlock) is False

    assert merkleroot(state1.merkletree) == lock_hash
    assert merkleroot(state2.merkletree) == EMPTY_MERKLE_ROOT

    assert state1.nonce is 1
    assert state2.nonce is None

    # registering the secret should not change the locked amount
    state1.register_secret(lock_secret)

    assert state1.contract_balance == balance1 + 10
    assert state2.contract_balance == balance2
    assert state1.balance(state2) == balance1 + 10
    assert state2.balance(state1) == balance2

    assert state1.is_locked(lock_hashlock) is False
    assert state2.is_locked(lock_hashlock) is False

    assert merkleroot(state1.merkletree) == lock_hash
    assert merkleroot(state2.merkletree) == EMPTY_MERKLE_ROOT

    assert state1.nonce is 1
    assert state2.nonce is None

    secret_message = Secret(
        identifier=1,
        nonce=2,
        channel=channel_address,
        transferred_amount=transferred_amount + lock_amount,
        locksroot=EMPTY_MERKLE_ROOT,
        secret=lock_secret,
    )
    secret_message.sign(privkey1, address1)
    state1.register_secretmessage(secret_message)

    assert state1.contract_balance == balance1 + 10
    assert state2.contract_balance == balance2
    assert state1.balance(state2) == balance1 + 10 - lock_amount
    assert state2.balance(state1) == balance2 + lock_amount

    assert state1.distributable(state2) == balance1 + 10 - lock_amount
    assert state2.distributable(state1) == balance2 + lock_amount

    assert state1.amount_locked == 0
    assert state2.amount_locked == 0

    assert state1.is_locked(lock_hashlock) is False
    assert state2.is_locked(lock_hashlock) is False

    assert merkleroot(state1.merkletree) == EMPTY_MERKLE_ROOT
    assert merkleroot(state2.merkletree) == EMPTY_MERKLE_ROOT

    assert state1.nonce is 2
    assert state2.nonce is None