예제 #1
0
def test_cooperative(
        channel_manager: ChannelManager,
        confirmed_open_channel: Channel,
        receiver_address: str,
        web3: Web3,
        token_contract: Contract,
        wait_for_blocks,
        sender_address: str
):
    blockchain = channel_manager.blockchain
    channel_id = (confirmed_open_channel.sender, confirmed_open_channel.block)

    sig1 = encode_hex(confirmed_open_channel.create_transfer(5))
    channel_manager.register_payment(sender_address, confirmed_open_channel.block, 5, sig1)

    receiver_sig = channel_manager.sign_close(sender_address, confirmed_open_channel.block, 5)
    channel_rec = channel_manager.channels[channel_id]
    assert channel_rec.is_closed is True
    block_before = web3.eth.blockNumber
    confirmed_open_channel.close_cooperatively(receiver_sig)
    wait_for_blocks(blockchain.n_confirmations)
    gevent.sleep(blockchain.poll_interval)
    logs = get_logs(token_contract, 'Transfer', from_block=block_before - 1)
    assert len([l for l in logs
                if is_same_address(l['args']['_to'], receiver_address) and
                l['args']['_value'] == 5]) == 1
    assert len([l for l in logs
                if is_same_address(l['args']['_to'], sender_address) and
                l['args']['_value'] == 5]) == 1
    wait_for_blocks(blockchain.n_confirmations)
    gevent.sleep(blockchain.poll_interval)
    assert channel_id not in channel_manager.channels
예제 #2
0
def test_balances(
        channel_manager: ChannelManager,
        confirmed_open_channel: Channel,
        wait_for_blocks,
        sender_address: str,
        use_tester: bool
):
    blockchain = channel_manager.blockchain
    initial_liquid_balance = channel_manager.get_liquid_balance()
    initial_locked_balance = channel_manager.get_locked_balance()
    if use_tester:
        assert initial_liquid_balance == 0
        assert initial_locked_balance == 0

    sig = encode_hex(confirmed_open_channel.create_transfer(5))
    channel_manager.register_payment(sender_address, confirmed_open_channel.block, 5, sig)

    assert channel_manager.get_liquid_balance() == initial_liquid_balance
    assert channel_manager.get_locked_balance() == 5

    receiver_sig = channel_manager.sign_close(sender_address, confirmed_open_channel.block, 5)
    confirmed_open_channel.close_cooperatively(receiver_sig)
    wait_for_blocks(blockchain.n_confirmations)
    gevent.sleep(blockchain.poll_interval)

    assert channel_manager.get_liquid_balance() == initial_liquid_balance + 5
    assert channel_manager.get_locked_balance() == initial_locked_balance
예제 #3
0
def test_topup(
        channel_manager: ChannelManager,
        confirmed_open_channel: Channel,
        wait_for_blocks
):
    blockchain = channel_manager.blockchain
    channel_manager.wait_sync()

    channel_id = (confirmed_open_channel.sender, confirmed_open_channel.block)
    confirmed_open_channel.topup(5)

    wait_for_blocks(1)
    gevent.sleep(blockchain.poll_interval)

    channel_rec = channel_manager.channels[channel_id]
    topup_txs = channel_rec.unconfirmed_topups
    assert len(topup_txs) == 1 and list(topup_txs.values())[0] == 5

    wait_for_blocks(channel_manager.blockchain.n_confirmations)
    gevent.sleep(blockchain.poll_interval)

    channel_rec = channel_manager.channels[channel_id]
    topup_txs = channel_rec.unconfirmed_topups
    assert len(topup_txs) == 0
    assert channel_rec.deposit == 15
def test_channel_settled_event(
        channel_manager: ChannelManager,
        confirmed_open_channel: Channel,
        wait_for_blocks,
        web3: Web3,
        use_tester: bool
):
    if not use_tester:
        pytest.skip('This test takes several hours on real blockchains.')

    blockchain = channel_manager.blockchain
    channel_manager.wait_sync()
    channel_id = (confirmed_open_channel.sender, confirmed_open_channel.block)
    confirmed_open_channel.close()
    wait_for_blocks(blockchain.n_confirmations)
    gevent.sleep(blockchain.poll_interval)
    channel_rec = channel_manager.channels[channel_id]
    wait_for_blocks(channel_rec.settle_timeout - web3.eth.blockNumber)
    gevent.sleep(blockchain.poll_interval)
    assert web3.eth.blockNumber >= channel_rec.settle_timeout
    assert channel_id in channel_manager.channels
    confirmed_open_channel.settle()
    wait_for_blocks(blockchain.n_confirmations)
    gevent.sleep(blockchain.poll_interval)
    assert channel_id not in channel_manager.channels
예제 #5
0
def close_channel_cooperatively(
        channel: Channel, privkey_receiver: str, contract_address: str, balance: int=None
):
    if balance is not None:
        channel.balance = balance
    closing_sig = sign_close(privkey_receiver, channel.balance_sig)
    assert channel.close_cooperatively(closing_sig)
def test_multiple_topups(
        channel_manager: ChannelManager,
        confirmed_open_channel: Channel,
        wait_for_blocks
):
    blockchain = channel_manager.blockchain
    channel_id = (confirmed_open_channel.sender, confirmed_open_channel.block)
    channel_rec = channel_manager.channels[channel_id]

    # first unconfirmed topup
    assert channel_rec.deposit == 10
    confirmed_open_channel.topup(5)
    wait_for_blocks(1)
    gevent.sleep(blockchain.poll_interval)

    channel_rec = channel_manager.channels[channel_id]
    assert len(channel_rec.unconfirmed_topups) == 1
    assert list(channel_rec.unconfirmed_topups.values()) == [5]
    assert channel_rec.deposit == 10

    # second unconfirmed_topups
    confirmed_open_channel.topup(10)
    wait_for_blocks(1)
    gevent.sleep(blockchain.poll_interval)
    channel_rec = channel_manager.channels[channel_id]
    assert len(channel_rec.unconfirmed_topups) >= 1  # equality if first is confirmed
    assert 10 in channel_rec.unconfirmed_topups.values()
    assert channel_rec.deposit in [10, 15]  # depends if first topup is confirmed or not

    # wait for confirmations
    wait_for_blocks(blockchain.n_confirmations)
    gevent.sleep(blockchain.poll_interval)
    channel_rec = channel_manager.channels[channel_id]
    assert len(channel_rec.unconfirmed_topups) == 0
    assert channel_rec.deposit == 25
def test_topup(
        channel_manager: ChannelManager,
        confirmed_open_channel: Channel,
        wait_for_blocks
):
    blockchain = channel_manager.blockchain
    channel_manager.wait_sync()

    channel_id = (confirmed_open_channel.sender, confirmed_open_channel.block)
    confirmed_open_channel.topup(5)

    wait_for_blocks(1)
    gevent.sleep(blockchain.poll_interval)

    channel_rec = channel_manager.channels[channel_id]
    topup_txs = channel_rec.unconfirmed_topups
    assert len(topup_txs) == 1 and list(topup_txs.values())[0] == 5

    wait_for_blocks(channel_manager.blockchain.n_confirmations)
    gevent.sleep(blockchain.poll_interval)

    channel_rec = channel_manager.channels[channel_id]
    topup_txs = channel_rec.unconfirmed_topups
    assert len(topup_txs) == 0
    assert channel_rec.deposit == 15
def test_cooperative(
        channel_manager: ChannelManager,
        confirmed_open_channel: Channel,
        receiver_address: str,
        web3: Web3,
        token_contract: Contract,
        wait_for_blocks,
        sender_address: str
):
    blockchain = channel_manager.blockchain
    channel_id = (confirmed_open_channel.sender, confirmed_open_channel.block)

    sig1 = encode_hex(confirmed_open_channel.create_transfer(5))
    channel_manager.register_payment(sender_address, confirmed_open_channel.block, 5, sig1)

    receiver_sig = channel_manager.sign_close(sender_address, confirmed_open_channel.block, 5)
    channel_rec = channel_manager.channels[channel_id]
    assert channel_rec.is_closed is True
    block_before = web3.eth.blockNumber
    confirmed_open_channel.close_cooperatively(receiver_sig)
    wait_for_blocks(blockchain.n_confirmations)
    gevent.sleep(blockchain.poll_interval)
    logs = get_logs(token_contract, 'Transfer', from_block=block_before - 1)
    assert len([l for l in logs
                if is_same_address(l['args']['_to'], receiver_address) and
                l['args']['_value'] == 5]) == 1
    assert len([l for l in logs
                if is_same_address(l['args']['_to'], sender_address) and
                l['args']['_value'] == 5]) == 1
    wait_for_blocks(blockchain.n_confirmations)
    gevent.sleep(blockchain.poll_interval)
    assert channel_id not in channel_manager.channels
def test_balances(
        channel_manager: ChannelManager,
        confirmed_open_channel: Channel,
        wait_for_blocks,
        sender_address: str,
        use_tester: bool
):
    blockchain = channel_manager.blockchain
    initial_liquid_balance = channel_manager.get_liquid_balance()
    initial_locked_balance = channel_manager.get_locked_balance()
    if use_tester:
        assert initial_liquid_balance == 0
        assert initial_locked_balance == 0

    sig = encode_hex(confirmed_open_channel.create_transfer(5))
    channel_manager.register_payment(sender_address, confirmed_open_channel.block, 5, sig)

    assert channel_manager.get_liquid_balance() == initial_liquid_balance
    assert channel_manager.get_locked_balance() == 5

    receiver_sig = channel_manager.sign_close(sender_address, confirmed_open_channel.block, 5)
    confirmed_open_channel.close_cooperatively(receiver_sig)
    wait_for_blocks(blockchain.n_confirmations)
    gevent.sleep(blockchain.poll_interval)

    assert channel_manager.get_liquid_balance() == initial_liquid_balance + 5
    assert channel_manager.get_locked_balance() == initial_locked_balance
예제 #10
0
def close_channel_cooperatively(channel: Channel,
                                privkey_receiver: str,
                                balance: int = None):
    if balance is not None:
        channel.update_balance(balance)
    closing_sig = sign_close(privkey_receiver, channel.balance_sig)
    assert channel.close_cooperatively(closing_sig)
예제 #11
0
def test_multiple_topups(
        channel_manager: ChannelManager,
        confirmed_open_channel: Channel,
        wait_for_blocks
):
    blockchain = channel_manager.blockchain
    channel_id = (confirmed_open_channel.sender, confirmed_open_channel.block)
    channel_rec = channel_manager.channels[channel_id]

    # first unconfirmed topup
    assert channel_rec.deposit == 10
    confirmed_open_channel.topup(5)
    wait_for_blocks(1)
    gevent.sleep(blockchain.poll_interval)

    channel_rec = channel_manager.channels[channel_id]
    assert len(channel_rec.unconfirmed_topups) == 1
    assert list(channel_rec.unconfirmed_topups.values()) == [5]
    assert channel_rec.deposit == 10

    # second unconfirmed_topups
    confirmed_open_channel.topup(10)
    wait_for_blocks(1)
    gevent.sleep(blockchain.poll_interval)
    channel_rec = channel_manager.channels[channel_id]
    assert len(channel_rec.unconfirmed_topups) >= 1  # equality if first is confirmed
    assert 10 in channel_rec.unconfirmed_topups.values()
    assert channel_rec.deposit in [10, 15]  # depends if first topup is confirmed or not

    # wait for confirmations
    wait_for_blocks(blockchain.n_confirmations)
    gevent.sleep(blockchain.poll_interval)
    channel_rec = channel_manager.channels[channel_id]
    assert len(channel_rec.unconfirmed_topups) == 0
    assert channel_rec.deposit == 25
예제 #12
0
def test_settlement(
        channel_manager: ChannelManager,
        confirmed_open_channel: Channel,
        receiver_address: str,
        wait_for_blocks,
        web3: Web3,
        token_contract: Contract,
        sender_address: str
):
    blockchain = channel_manager.blockchain
    channel_id = (confirmed_open_channel.sender, confirmed_open_channel.block)

    sig = encode_hex(confirmed_open_channel.create_transfer(2))
    channel_manager.register_payment(sender_address, confirmed_open_channel.block, 2, sig)

    confirmed_open_channel.close()
    wait_for_blocks(blockchain.n_confirmations)
    gevent.sleep(blockchain.poll_interval)
    block_before = web3.eth.blockNumber
    channel_rec = channel_manager.channels[channel_id]
    wait_for_blocks(channel_rec.settle_timeout - block_before)
    confirmed_open_channel.settle()

    logs = get_logs(token_contract, 'Transfer', from_block=block_before - 1)
    assert len([l for l in logs
                if is_same_address(l['args']['_to'], receiver_address) and
                l['args']['_value'] == 2]) == 1
    assert len([l for l in logs
                if is_same_address(l['args']['_to'], sender_address) and
                l['args']['_value'] == 8]) == 1

    wait_for_blocks(blockchain.n_confirmations)
    gevent.sleep(blockchain.poll_interval)
    assert channel_id not in channel_manager.channels
예제 #13
0
def close_channel_cooperatively(channel: Channel,
                                privkey_receiver: str,
                                contract_address: str,
                                balance: int = None):
    if balance is not None:
        channel.update_balance(balance)
    closing_sig = sign_close(privkey_receiver, channel.sender, channel.block,
                             channel.balance, contract_address)
    assert channel.close_cooperatively(closing_sig)
예제 #14
0
 def close_channel(self, channel: Channel):
     log.info(
         'Requesting closing signature from server for balance {} on channel {}/{}/{}.'
         .format(channel.balance, channel.sender, channel.sender, channel.block)
     )
     url = self.make_url('api/1/channels/{}/{}'.format(channel.sender, channel.block))
     response = requests.delete(url, data={'balance': channel.balance})
     if response.status_code == requests.codes.OK:
         closing_sig = json.loads(response.content.decode())['close_signature']
         channel.close_cooperatively(decode_hex(closing_sig))
     else:
         body = response.content.decode() if response.content else None
         log.error('No closing signature received: {}'.format(body))
예제 #15
0
def close_channel_cooperatively(
        channel: Channel, privkey_receiver: str, contract_address: str, balance: int=None
):
    if balance is not None:
        channel.update_balance(balance)
    closing_sig = sign_close(
        privkey_receiver,
        channel.sender,
        channel.block,
        channel.balance,
        contract_address
    )
    assert channel.close_cooperatively(closing_sig)
예제 #16
0
 def close_channel(self, endpoint_url: str, channel: Channel):
     log.debug(
         'Requesting closing signature from server for balance {} on channel {}/{}/{}.'
         .format(channel.balance, channel.sender, channel.sender,
                 channel.block))
     url = '{}/api/1/channels/{}/{}'.format(endpoint_url, channel.sender,
                                            channel.block)
     response = requests.delete(url, data={'balance': channel.balance})
     if response.status_code == requests.codes.OK:
         closing_sig = response.json()['close_signature']
         channel.close_cooperatively(decode_hex(closing_sig))
     else:
         self.on_cooperative_close_denied(endpoint_url, channel, response)
예제 #17
0
def test_cooperative_wrong_balance_proof(
        channel_manager: ChannelManager,
        confirmed_open_channel: Channel,
        sender_address: str
):
    channel_id = (confirmed_open_channel.sender, confirmed_open_channel.block)
    channel_rec = channel_manager.channels[channel_id]

    sig1 = encode_hex(confirmed_open_channel.create_transfer(5))
    channel_manager.register_payment(sender_address, confirmed_open_channel.block, 5, sig1)

    sig2 = encode_hex(confirmed_open_channel.create_transfer(1))
    with pytest.raises(InvalidBalanceProof):
        channel_manager.sign_close(sender_address, confirmed_open_channel.block, sig2)
    assert channel_rec.is_closed is False
예제 #18
0
def test_cooperative_wrong_balance_proof(
        channel_manager: ChannelManager,
        confirmed_open_channel: Channel,
        sender_address: str
):
    channel_id = (confirmed_open_channel.sender, confirmed_open_channel.block)
    channel_rec = channel_manager.channels[channel_id]

    sig1 = encode_hex(confirmed_open_channel.create_transfer(5))
    channel_manager.register_payment(sender_address, confirmed_open_channel.block, 5, sig1)

    sig2 = encode_hex(confirmed_open_channel.create_transfer(1))
    with pytest.raises(InvalidBalanceProof):
        channel_manager.sign_close(sender_address, confirmed_open_channel.block, sig2)
    assert channel_rec.is_closed is False
예제 #19
0
def test_close_confirmed_event(channel_manager: ChannelManager,
                               confirmed_open_channel: Channel,
                               wait_for_blocks):
    blockchain = channel_manager.blockchain
    channel_manager.wait_sync()

    confirmed_open_channel.close()
    wait_for_blocks(blockchain.n_confirmations)
    gevent.sleep(blockchain.poll_interval)

    channel_id = (confirmed_open_channel.sender, confirmed_open_channel.block)
    channel_rec = channel_manager.channels[channel_id]
    assert channel_rec.is_closed is True

    settle_block = channel_manager.channel_manager_contract.call(
    ).getChannelInfo(channel_rec.sender, channel_rec.receiver,
                     channel_rec.open_block_number)[2]
    assert channel_rec.settle_timeout == settle_block
예제 #20
0
def test_channel_settled_event(channel_manager: ChannelManager,
                               confirmed_open_channel: Channel,
                               wait_for_blocks, web3: Web3, use_tester: bool):
    if not use_tester:
        pytest.skip('This test takes several hours on real blockchains.')

    blockchain = channel_manager.blockchain
    channel_manager.wait_sync()
    channel_id = (confirmed_open_channel.sender, confirmed_open_channel.block)
    confirmed_open_channel.close()
    wait_for_blocks(blockchain.n_confirmations)
    gevent.sleep(blockchain.poll_interval)
    channel_rec = channel_manager.channels[channel_id]
    wait_for_blocks(channel_rec.settle_timeout - web3.eth.blockNumber)
    gevent.sleep(blockchain.poll_interval)
    assert web3.eth.blockNumber >= channel_rec.settle_timeout
    assert channel_id in channel_manager.channels
    confirmed_open_channel.settle()
    wait_for_blocks(blockchain.n_confirmations)
    gevent.sleep(blockchain.poll_interval)
    assert channel_id not in channel_manager.channels
예제 #21
0
def test_channel_settled_event(
        channel_manager: ChannelManager,
        confirmed_open_channel: Channel,
        wait_for_blocks,
        web3: Web3
):
    blockchain = channel_manager.blockchain
    channel_manager.wait_sync()
    channel_id = (confirmed_open_channel.sender, confirmed_open_channel.block)
    confirmed_open_channel.close()
    wait_for_blocks(blockchain.n_confirmations)
    gevent.sleep(blockchain.poll_interval)
    channel_rec = channel_manager.channels[channel_id]
    wait_for_blocks(channel_rec.settle_timeout - web3.eth.blockNumber)
    gevent.sleep(blockchain.poll_interval)
    assert web3.eth.blockNumber >= channel_rec.settle_timeout
    assert channel_id in channel_manager.channels
    confirmed_open_channel.settle()
    wait_for_blocks(blockchain.n_confirmations)
    gevent.sleep(blockchain.poll_interval)
    assert channel_id not in channel_manager.channels
예제 #22
0
def test_close_confirmed_event(
        channel_manager: ChannelManager,
        confirmed_open_channel: Channel,
        wait_for_blocks
):
    blockchain = channel_manager.blockchain
    channel_manager.wait_sync()

    confirmed_open_channel.close()
    wait_for_blocks(blockchain.n_confirmations)
    gevent.sleep(blockchain.poll_interval)

    channel_id = (confirmed_open_channel.sender, confirmed_open_channel.block)
    channel_rec = channel_manager.channels[channel_id]
    assert channel_rec.is_closed is True

    settle_block = channel_manager.channel_manager_contract.call().getChannelInfo(
        channel_rec.sender,
        channel_rec.receiver,
        channel_rec.open_block_number
    )[2]
    assert channel_rec.settle_timeout == settle_block
예제 #23
0
def test_settlement(
        channel_manager: ChannelManager,
        confirmed_open_channel: Channel,
        receiver_address: str,
        wait_for_blocks,
        web3: Web3,
        token_contract: Contract,
        sender_address: str,
        use_tester: bool
):
    if not use_tester:
        pytest.skip('This test takes several hours on real blockchains.')

    blockchain = channel_manager.blockchain
    channel_id = (confirmed_open_channel.sender, confirmed_open_channel.block)

    sig = encode_hex(confirmed_open_channel.create_transfer(2))
    channel_manager.register_payment(sender_address, confirmed_open_channel.block, 2, sig)

    confirmed_open_channel.close()
    wait_for_blocks(blockchain.n_confirmations)
    gevent.sleep(blockchain.poll_interval)
    block_before = web3.eth.blockNumber
    channel_rec = channel_manager.channels[channel_id]
    wait_for_blocks(channel_rec.settle_timeout - block_before)
    confirmed_open_channel.settle()

    logs = get_logs(token_contract, 'Transfer', from_block=block_before - 1)
    assert len([l for l in logs
                if is_same_address(l['args']['_to'], receiver_address) and
                l['args']['_value'] == 2]) == 1
    assert len([l for l in logs
                if is_same_address(l['args']['_to'], sender_address) and
                l['args']['_value'] == 8]) == 1

    wait_for_blocks(blockchain.n_confirmations)
    gevent.sleep(blockchain.poll_interval)
    assert channel_id not in channel_manager.channels
예제 #24
0
def test_challenge(
        channel_manager: ChannelManager,
        confirmed_open_channel: Channel,
        receiver_address: str,
        sender_address: str,
        wait_for_blocks,
        web3: Web3,
        client: Client
):
    blockchain = channel_manager.blockchain
    channel_id = (confirmed_open_channel.sender, confirmed_open_channel.block)
    sig = encode_hex(confirmed_open_channel.create_transfer(5))
    channel_manager.register_payment(sender_address, confirmed_open_channel.block, 5, sig)
    # hack channel to decrease balance
    confirmed_open_channel.update_balance(0)
    sig = confirmed_open_channel.create_transfer(3)
    block_before = web3.eth.blockNumber
    confirmed_open_channel.close()
    # should challenge and immediately settle
    for waited_blocks in count():
        logs = get_logs(client.context.token, 'Transfer', from_block=block_before - 1)
        if logs:
            break
        wait_for_blocks(1)
        assert waited_blocks < 10

    assert len([l for l in logs
                if is_same_address(l['args']['_to'], receiver_address) and
                l['args']['_value'] == 5]) == 1
    assert len([l for l in logs
                if is_same_address(l['args']['_to'], sender_address) and
                l['args']['_value'] == 5]) == 1
    wait_for_blocks(blockchain.n_confirmations)
    gevent.sleep(blockchain.poll_interval)
    assert channel_id not in channel_manager.channels

    # update channel state so that it will not be closed twice
    client.sync_channels()
    new_state = None
    for channel in client.channels:
        if all(channel.sender == confirmed_open_channel.sender,
               channel.receiver == confirmed_open_channel.receiver,
               channel.block == confirmed_open_channel.block):
            new_state = channel.state
    if new_state is None:
        confirmed_open_channel.state = confirmed_open_channel.State.closed
    else:
        confirmed_open_channel.state = new_state
예제 #25
0
def test_challenge(
        channel_manager: ChannelManager,
        confirmed_open_channel: Channel,
        receiver_address: str,
        sender_address: str,
        wait_for_blocks,
        web3: Web3,
        client: Client
):
    blockchain = channel_manager.blockchain
    channel_id = (confirmed_open_channel.sender, confirmed_open_channel.block)
    sig = encode_hex(confirmed_open_channel.create_transfer(5))
    channel_manager.register_payment(sender_address, confirmed_open_channel.block, 5, sig)
    # hack channel to decrease balance
    confirmed_open_channel.update_balance(0)
    sig = confirmed_open_channel.create_transfer(3)
    block_before = web3.eth.blockNumber
    confirmed_open_channel.close()
    # should challenge and immediately settle
    for waited_blocks in count():
        logs = get_logs(client.context.token, 'Transfer', from_block=block_before - 1)
        if logs:
            break
        wait_for_blocks(1)
        assert waited_blocks < 10

    assert len([l for l in logs
                if is_same_address(l['args']['_to'], receiver_address) and
                l['args']['_value'] == 5]) == 1
    assert len([l for l in logs
                if is_same_address(l['args']['_to'], sender_address) and
                l['args']['_value'] == 5]) == 1
    wait_for_blocks(blockchain.n_confirmations)
    gevent.sleep(blockchain.poll_interval)
    assert channel_id not in channel_manager.channels

    # update channel state so that it will not be closed twice
    client.sync_channels()
    new_state = None
    for channel in client.channels:
        if all(channel.sender == confirmed_open_channel.sender,
               channel.receiver == confirmed_open_channel.receiver,
               channel.block == confirmed_open_channel.block):
            new_state = channel.state
    if new_state is None:
        confirmed_open_channel.state = confirmed_open_channel.State.closed
    else:
        confirmed_open_channel.state = new_state
예제 #26
0
    def sync_channels(self):
        """
        Merges locally available channel information, including their current balance signatures,
        with channel information available on the blockchain to make up for local data loss.
        Naturally, balance signatures cannot be recovered from the blockchain.
        """
        filters = {'_sender_address': self.context.address}
        create = get_logs(self.context.channel_manager,
                          'ChannelCreated',
                          argument_filters=filters,
                          from_block=start_sync_block,
                          to_block='latest')
        topup = get_logs(self.context.channel_manager,
                         'ChannelToppedUp',
                         argument_filters=filters,
                         from_block=start_sync_block,
                         to_block='latest')
        close = get_logs(self.context.channel_manager,
                         'ChannelCloseRequested',
                         argument_filters=filters,
                         from_block=start_sync_block,
                         to_block='latest')
        settle = get_logs(self.context.channel_manager,
                          'ChannelSettled',
                          argument_filters=filters,
                          from_block=start_sync_block,
                          to_block='latest')

        channel_key_to_channel = {}

        def get_channel(event) -> Channel:
            sender = to_checksum_address(event['args']['_sender_address'])
            receiver = to_checksum_address(event['args']['_receiver_address'])
            block = event['args'].get('_open_block_number',
                                      event['blockNumber'])
            assert is_same_address(sender, self.context.address)
            return channel_key_to_channel.get((sender, receiver, block), None)

        for c in self.channels:
            channel_key_to_channel[(c.sender, c.receiver, c.block)] = c

        for e in create:
            c = get_channel(e)
            if c:
                c.deposit = e['args']['_deposit']
            else:
                c = Channel(
                    self.context,
                    to_checksum_address(e['args']['_sender_address']),
                    to_checksum_address(e['args']['_receiver_address']),
                    e['blockNumber'],
                    e['args']['_deposit'],
                    on_settle=lambda channel: self.channels.remove(channel))
                assert is_same_address(c.sender, self.context.address)
                channel_key_to_channel[(c.sender, c.receiver, c.block)] = c

        for e in topup:
            c = get_channel(e)
            c.deposit += e['args']['_added_deposit']

        for e in close:
            # Requested closed, not actual closed.
            c = get_channel(e)

            c.update_balance(e['args']['_balance'])
            c.state = Channel.State.settling

        for e in settle:
            c = get_channel(e)
            c.state = Channel.State.closed

        # Forget closed channels.
        self.channels = [
            c for c in channel_key_to_channel.values()
            if c.state != Channel.State.closed
        ]

        log.debug('Synced a total of {} channels.'.format(len(self.channels)))
예제 #27
0
 def on_cooperative_close_denied(self, endpoint_url: str, channel: Channel,
                                 response: Response):
     log.warning(
         'No closing signature received. Closing noncooperatively on a balance of 0.'
     )
     channel.close(0)