예제 #1
0
def test_channel_opening(client: Client, web3: Web3, make_account,
                         private_keys: List[str], channel_manager_contract,
                         token_contract, mine_sync_event, wait_for_blocks,
                         use_tester, state_db_path):
    receiver1_privkey = make_account(RECEIVER_ETH_ALLOWANCE,
                                     RECEIVER_TOKEN_ALLOWANCE, private_keys[2])
    receiver2_privkey = make_account(RECEIVER_ETH_ALLOWANCE,
                                     RECEIVER_TOKEN_ALLOWANCE, private_keys[3])
    receiver_address = privkey_to_addr(receiver1_privkey)
    # make sure channel_manager1 is terminated properly, otherwise Blockchain will be running
    #  in the background, ruining other tests' results
    channel_manager1 = ChannelManager(web3,
                                      channel_manager_contract,
                                      token_contract,
                                      receiver1_privkey,
                                      n_confirmations=5,
                                      state_filename=state_db_path)
    start_channel_manager(channel_manager1, use_tester, mine_sync_event)

    channel_manager2 = ChannelManager(web3,
                                      channel_manager_contract,
                                      token_contract,
                                      receiver2_privkey,
                                      n_confirmations=5,
                                      state_filename=state_db_path)
    start_channel_manager(channel_manager2, use_tester, mine_sync_event)
    channel_manager1.wait_sync()
    channel_manager2.wait_sync()
    blockchain = channel_manager1.blockchain
    channel = client.open_channel(receiver_address, 10)
    # should be in unconfirmed channels
    wait_for_blocks(1)
    gevent.sleep(blockchain.poll_interval)
    assert (channel.sender, channel.block) not in channel_manager1.channels
    assert (channel.sender,
            channel.block) in channel_manager1.unconfirmed_channels
    channel_rec = channel_manager1.unconfirmed_channels[channel.sender,
                                                        channel.block]
    assert is_same_address(channel_rec.receiver, receiver_address)
    assert is_same_address(channel_rec.sender, channel.sender)
    assert channel_rec.mtime == channel_rec.ctime

    # should be confirmed after n blocks
    wait_for_blocks(blockchain.n_confirmations)
    gevent.sleep(blockchain.poll_interval)
    assert (channel.sender, channel.block) in channel_manager1.channels
    channel_rec = channel_manager1.channels[channel.sender, channel.block]
    assert is_same_address(channel_rec.receiver, receiver_address)
    assert is_same_address(channel_rec.sender, channel.sender)
    assert channel_rec.balance == 0
    assert channel_rec.last_signature is None
    assert channel_rec.is_closed is False
    assert channel_rec.settle_timeout == -1

    # should not appear in other channel manager
    assert (channel.sender, channel.block) not in channel_manager2.channels
    assert (channel.sender,
            channel.block) not in channel_manager2.unconfirmed_channels
    channel_manager1.stop()
    channel_manager2.stop()
예제 #2
0
def test_version(web3: Web3, channel_manager_contract: Contract,
                 token_contract: Contract, make_account,
                 private_keys: List[str]):
    """Test if proxy refuses to run if it deployed contract version
    is different from the one it expects"""
    receiver1_privkey = make_account(RECEIVER_ETH_ALLOWANCE,
                                     RECEIVER_TOKEN_ALLOWANCE, private_keys[2])

    # this one should not raise
    cm = ChannelManager(web3,
                        channel_manager_contract,
                        token_contract,
                        receiver1_privkey,
                        state_filename=":memory:")
    cm.stop()
    # now we patch it
    channel_manager_contract = FakeChannelManagerContract(receiver1_privkey)

    # check of version string should fail here
    with pytest.raises(InvalidContractVersion):
        ChannelManager(web3,
                       channel_manager_contract,
                       token_contract,
                       receiver1_privkey,
                       state_filename=":memory:")
def test_channel_opening(client, web3, make_account,
                         make_channel_manager_proxy, token_contract,
                         mine_sync_event, wait_for_blocks, use_tester):
    receiver1_privkey = make_account(RECEIVER_ETH_ALLOWANCE,
                                     RECEIVER_TOKEN_ALLOWANCE)
    receiver2_privkey = make_account(RECEIVER_ETH_ALLOWANCE,
                                     RECEIVER_TOKEN_ALLOWANCE)
    receiver_address = privkey_to_addr(receiver1_privkey)
    channel_manager1 = ChannelManager(
        web3,
        make_channel_manager_proxy(receiver1_privkey),
        token_contract,
        receiver1_privkey,
        n_confirmations=5)
    start_channel_manager(channel_manager1, use_tester, mine_sync_event)

    channel_manager2 = ChannelManager(
        web3,
        make_channel_manager_proxy(receiver2_privkey),
        token_contract,
        receiver2_privkey,
        n_confirmations=5)
    start_channel_manager(channel_manager2, use_tester, mine_sync_event)
    channel_manager1.wait_sync()
    channel_manager2.wait_sync()
    blockchain = channel_manager1.blockchain
    channel = client.open_channel(receiver_address, 10)
    # should be in unconfirmed channels
    wait_for_blocks(1)
    gevent.sleep(blockchain.poll_interval)
    assert (channel.sender, channel.block) not in channel_manager1.channels
    assert (channel.sender,
            channel.block) in channel_manager1.unconfirmed_channels
    channel_rec = channel_manager1.unconfirmed_channels[channel.sender,
                                                        channel.block]
    assert is_same_address(channel_rec.receiver, receiver_address)
    assert is_same_address(channel_rec.sender, channel.sender)
    assert channel_rec.mtime == channel_rec.ctime

    # should be confirmed after n blocks
    wait_for_blocks(blockchain.n_confirmations)
    gevent.sleep(blockchain.poll_interval)
    assert (channel.sender, channel.block) in channel_manager1.channels
    channel_rec = channel_manager1.channels[channel.sender, channel.block]
    assert is_same_address(channel_rec.receiver, receiver_address)
    assert is_same_address(channel_rec.sender, channel.sender)
    assert channel_rec.balance == 0
    assert channel_rec.last_signature is None
    assert channel_rec.is_closed is False
    assert channel_rec.settle_timeout == -1

    # should not appear in other channel manager
    assert (channel.sender, channel.block) not in channel_manager2.channels
    assert (channel.sender,
            channel.block) not in channel_manager2.unconfirmed_channels
예제 #4
0
def make_channel_manager(private_key: str, state_filename: str, web3):
    contracts_abi_path = os.path.join(os.path.dirname(__file__),
                                      'data/contracts.json')
    abi = json.load(open(contracts_abi_path))['ERC223Token']['abi']
    channel_manager_proxy = make_contract_proxy(web3, private_key,
                                                config.CHANNEL_MANAGER_ADDRESS)
    token_address = channel_manager_proxy.contract.call().token_address()
    token_contract = web3.eth.contract(abi=abi, address=token_address)
    try:
        return ChannelManager(web3,
                              channel_manager_proxy,
                              token_contract,
                              private_key,
                              state_filename=state_filename)
    except StateReceiverAddrMismatch as e:
        log.error(
            'Receiver address does not match address stored in a saved state. '
            'Use a different file, or backup and remove %s. (%s)' %
            (state_filename, e))
        sys.exit(1)

    except StateContractAddrMismatch as e:
        log.error('channel contract address mismatch. '
                  'Saved state file is %s. Backup it, remove, then'
                  'start proxy again (%s)' % (state_filename, e))
        sys.exit(1)
예제 #5
0
def make_channel_manager(
        private_key: str,
        channel_manager_address: str,
        state_filename: str,
        web3: Web3
) -> ChannelManager:
    channel_manager_contract = make_channel_manager_contract(web3, channel_manager_address)
    token_address = channel_manager_contract.call().token()
    token_abi = config.CONTRACT_METADATA[config.TOKEN_ABI_NAME]['abi']
    token_contract = web3.eth.contract(abi=token_abi, address=token_address)
    try:
        return ChannelManager(
            web3,
            channel_manager_contract,
            token_contract,
            private_key,
            state_filename=state_filename
        )
    except StateReceiverAddrMismatch as e:
        log.error(
            'Receiver address does not match address stored in a saved state. '
            'Use a different file, or backup and remove %s. (%s)' %
            (state_filename, e)
        )
        sys.exit(1)

    except StateContractAddrMismatch as e:
        log.error(
            'Channel contract address mismatch. '
            'Saved state file is %s. Backup it, remove, then start proxy again (%s)' %
            (state_filename, e)
        )
        sys.exit(1)
예제 #6
0
def channel_manager(web3, receiver_privkey, make_channel_manager_proxy,
                    token_contract, use_tester, mine_sync_event):
    contract_proxy = make_channel_manager_proxy(receiver_privkey)
    manager = ChannelManager(web3,
                             contract_proxy,
                             token_contract,
                             receiver_privkey,
                             n_confirmations=5)
    start_channel_manager(manager, use_tester, mine_sync_event)
    return manager
예제 #7
0
def channel_manager(web3, receiver_privkey, make_channel_manager_proxy,
                    token_contract, use_tester, mine_sync_event, state_db_path,
                    revert_chain):
    contract_proxy = make_channel_manager_proxy(receiver_privkey)
    manager = ChannelManager(web3,
                             contract_proxy,
                             token_contract,
                             receiver_privkey,
                             n_confirmations=5,
                             state_filename=state_db_path)
    start_channel_manager(manager, use_tester, mine_sync_event)
    yield manager
    manager.stop()
예제 #8
0
def channel_manager(web3, receiver_privkey, make_channel_manager_proxy,
                    token_contract, use_tester, mine_sync_event):
    if use_tester:
        snapshot_id = web3.testing.snapshot()
    contract_proxy = make_channel_manager_proxy(receiver_privkey)
    manager = ChannelManager(web3,
                             contract_proxy,
                             token_contract,
                             receiver_privkey,
                             n_confirmations=5)
    start_channel_manager(manager, use_tester, mine_sync_event)
    yield manager
    if use_tester:
        web3.testing.revert(snapshot_id)
예제 #9
0
def make_channel_manager(
        private_key: str,
        channel_manager_address: str,
        state_filename: str,
        web3: Web3
) -> ChannelManager:
    """
    Args:
        private_key (str): receiver's private key
        channel_manager_address (str): channel manager contract to use
        state_filename (str): path to the channel manager state database
        web3 (Web3): web3 provider
    Returns:
        ChannelManager: intialized and synced channel manager

    """
    channel_manager_address = to_checksum_address(channel_manager_address)
    channel_manager_contract = make_channel_manager_contract(web3, channel_manager_address)
    token_address = channel_manager_contract.call().token()
    token_abi = constants.CONTRACT_METADATA[constants.TOKEN_ABI_NAME]['abi']
    token_contract = web3.eth.contract(abi=token_abi, address=token_address)
    try:
        return ChannelManager(
            web3,
            channel_manager_contract,
            token_contract,
            private_key,
            state_filename=state_filename
        )
    except StateReceiverAddrMismatch as e:
        log.error(
            'Receiver address does not match address stored in a saved state. '
            'Use a different file, or backup and remove %s. (%s)' %
            (state_filename, e)
        )
        sys.exit(1)

    except StateContractAddrMismatch as e:
        log.error(
            'Channel contract address mismatch. '
            'Saved state file is %s. Backup it, remove, then start proxy again (%s)' %
            (state_filename, e)
        )
        sys.exit(1)
예제 #10
0
def make_channel_manager(
        receiver: str,
        private_key: str,
        channel_manager_address: str,
        state_filename: str,
        web3: Web3
) -> ChannelManager:
    """
    Args:
        private_key (str): receiver's private key
        channel_manager_address (str): channel manager contract to use
        state_filename (str): path to the channel manager state database
        web3 (Web3): web3 provider
    Returns:
        ChannelManager: intialized and synced channel manager

    """
    channel_manager_address = Web3.toChecksumAddress(channel_manager_address)
    channel_manager_contract = make_channel_manager_contract(web3, channel_manager_address)
    receiver_address = Web3.toChecksumAddress(receiver)
    try:
        return ChannelManager(
            web3,
            channel_manager_contract,
            receiver,
            private_key,
            state_filename=state_filename
        )
    except StateReceiverAddrMismatch as e:
        log.error(
            'Receiver address does not match address stored in a saved state. '
            'Use a different file, or backup and remove %s. (%s)' %
            (state_filename, e)
        )
        sys.exit(1)

    except StateContractAddrMismatch as e:
        log.error(
            'Channel contract address mismatch. '
            'Saved state file is %s. Backup it, remove, then start proxy again (%s)' %
            (state_filename, e)
        )
        sys.exit(1)
예제 #11
0
def test_different_receivers(web3, make_account, make_channel_manager_proxy,
                             token_contract, mine_sync_event, client,
                             sender_address, wait_for_blocks, use_tester,
                             state_db_path):
    receiver1_privkey = make_account(RECEIVER_ETH_ALLOWANCE,
                                     RECEIVER_TOKEN_ALLOWANCE)
    receiver2_privkey = make_account(RECEIVER_ETH_ALLOWANCE,
                                     RECEIVER_TOKEN_ALLOWANCE)
    receiver1_address = privkey_to_addr(receiver1_privkey)
    channel_manager1 = ChannelManager(
        web3,
        make_channel_manager_proxy(receiver1_privkey),
        token_contract,
        receiver1_privkey,
        n_confirmations=5,
        state_filename=state_db_path)
    start_channel_manager(channel_manager1, use_tester, mine_sync_event)

    channel_manager2 = ChannelManager(
        web3,
        make_channel_manager_proxy(receiver2_privkey),
        token_contract,
        receiver2_privkey,
        n_confirmations=5,
        state_filename=state_db_path)
    start_channel_manager(channel_manager2, use_tester, mine_sync_event)
    channel_manager1.wait_sync()
    channel_manager2.wait_sync()
    blockchain = channel_manager1.blockchain

    assert channel_manager2.blockchain.n_confirmations == blockchain.n_confirmations
    assert channel_manager2.blockchain.poll_interval == blockchain.poll_interval

    # unconfirmed open
    channel = client.open_channel(receiver1_address, 10)
    wait_for_blocks(1)
    gevent.sleep(blockchain.poll_interval)
    assert (sender_address,
            channel.block) in channel_manager1.unconfirmed_channels
    assert (sender_address,
            channel.block) not in channel_manager2.unconfirmed_channels

    # confirmed open
    wait_for_blocks(blockchain.n_confirmations)
    gevent.sleep(blockchain.poll_interval)
    assert (sender_address, channel.block) in channel_manager1.channels
    assert (sender_address, channel.block) not in channel_manager2.channels

    # unconfirmed topup
    channel.topup(5)
    wait_for_blocks(1)
    gevent.sleep(blockchain.poll_interval)
    channel_rec = channel_manager1.channels[sender_address, channel.block]
    assert len(channel_rec.unconfirmed_topups) == 1
    assert channel_rec.deposit == 10

    # confirmed topup
    wait_for_blocks(blockchain.n_confirmations)
    gevent.sleep(blockchain.poll_interval)
    channel_rec = channel_manager1.channels[sender_address, channel.block]
    assert len(channel_rec.unconfirmed_topups) == 0
    assert channel_rec.deposit == 15

    # closing
    channel.close()
    wait_for_blocks(blockchain.n_confirmations)
    gevent.sleep(blockchain.poll_interval)
    channel_rec = channel_manager1.channels[sender_address, channel.block]
    assert channel_rec.is_closed is True

    # settlement
    block_before = web3.eth.blockNumber
    wait_for_blocks(channel_rec.settle_timeout - block_before)
    channel.settle()
    wait_for_blocks(blockchain.n_confirmations)
    gevent.sleep(blockchain.poll_interval)
    assert (sender_address, channel.block) not in channel_manager1.channels
    channel_manager1.stop()
    channel_manager2.stop()