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 make_external_state():
    channel_for_hashlock = list()
    netting_channel = NettingChannelMock()

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

    return external_state
Beispiel #3
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 #4
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 #5
0
def make_external_state():
    block_alarm = list()
    channel_for_hashlock = list()
    netting_channel = NettingChannelMock()
    netting_channel.address = make_address()

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

    return external_state
Beispiel #6
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 #8
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
Beispiel #9
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 #10
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 #11
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 #12
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