def test_reorg( web3: Web3, channel_manager: ChannelManager, client: Client, receiver_address: str, wait_for_blocks, use_tester: bool ): if not use_tester: pytest.skip('Chain reorg tests only work in tester chain') wait_for_blocks(10) # create unconfirmed channel channel_manager.wait_sync() snapshot_id = web3.testing.snapshot() channel = client.open_channel(receiver_address, 10) wait_for_blocks(0) assert (channel.sender, channel.block) in channel_manager.unconfirmed_channels # remove unconfirmed channel opening with reorg web3.testing.revert(snapshot_id) snapshot_id = web3.testing.snapshot() wait_for_blocks(0) assert (channel.sender, channel.block) not in channel_manager.unconfirmed_channels web3.testing.mine(channel_manager.n_confirmations) assert (channel.sender, channel.block) not in channel_manager.channels # leave confirmed channel opening web3.testing.revert(snapshot_id) channel = client.open_channel(receiver_address, 10) wait_for_blocks(channel_manager.n_confirmations) assert (channel.sender, channel.block) in channel_manager.channels confirmed_snapshot_id = web3.testing.snapshot() wait_for_blocks(3) web3.testing.revert(confirmed_snapshot_id) assert (channel.sender, channel.block) in channel_manager.channels # remove unconfirmed topup channel = client.open_channel(receiver_address, 10) wait_for_blocks(channel_manager.n_confirmations) assert (channel.sender, channel.block) in channel_manager.channels topup_snapshot_id = web3.testing.snapshot() channel.topup(5) wait_for_blocks(0) channel_rec = channel_manager.channels[channel.sender, channel.block] assert len(channel_rec.unconfirmed_topups) == 1 web3.testing.revert(topup_snapshot_id) wait_for_blocks(0) assert (channel.sender, channel.block) in channel_manager.channels channel_rec = channel_manager.channels[channel.sender, channel.block] assert len(channel_rec.unconfirmed_topups) == 0
def test_withdraw_above_minimum( client: Client, channel_manager: ChannelManager, web3: Web3, wait_for_blocks ): sender = client.context.address receiver = channel_manager.receiver channel = client.open_channel(receiver, 10) wait_for_blocks(channel_manager.n_confirmations + 1) channel_manager.register_payment(sender, channel.block, 4, encode_hex(channel.create_transfer(4))) channel_manager.stop() # don't update state from this point on channel_manager.join() state = channel_manager.state tx_count_before = web3.eth.getTransactionCount(receiver) withdraw_from_channels( channel_manager.private_key, state, channel_manager.channel_manager_contract, 3, wait=lambda: wait_for_blocks(1) ) tx_count_after = web3.eth.getTransactionCount(receiver) assert tx_count_after == tx_count_before + 1 channel_id = (channel.sender, channel.receiver, channel.block) channel_info = channel_manager.channel_manager_contract.call().getChannelInfo(*channel_id) _, deposit, settle_block_number, closing_balance, transferred_tokens = channel_info assert transferred_tokens == 4 wait_for_blocks(1)
def test_open_channel_insufficient_tokens(client: Client, web3: Web3, receiver_address: str): balance_of = client.context.token.call().balanceOf(client.context.address) tx_count_pre = web3.eth.getTransactionCount(client.context.address) channel = client.open_channel(receiver_address, balance_of + 1) tx_count_post = web3.eth.getTransactionCount(client.context.address) assert channel is None assert tx_count_post == tx_count_pre
def test_close_valid_close(client: Client, channel_manager: ChannelManager, web3: Web3, wait_for_blocks): sender = client.context.address receiver = channel_manager.receiver channel = client.open_channel(receiver, 10) wait_for_blocks(channel_manager.n_confirmations + 1) channel_manager.register_payment(sender, channel.block, 2, encode_hex(channel.create_transfer(2))) channel.close() channel_manager.stop() # don't update state from this point on channel_manager.join() state = channel_manager.state tx_count_before = web3.eth.getTransactionCount(receiver) close_open_channels(channel_manager.private_key, state, channel_manager.channel_manager_contract, wait=lambda: wait_for_blocks(1)) tx_count_after = web3.eth.getTransactionCount(receiver) assert tx_count_after == tx_count_before + 1 with pytest.raises((BadFunctionCallOutput, TransactionFailed)): channel_id = (channel.sender, channel.receiver, channel.block) channel_manager.channel_manager_contract.call().getChannelInfo( *channel_id) wait_for_blocks(1)
def test_close_settled(client: Client, channel_manager: ChannelManager, web3: Web3, wait_for_blocks): sender = client.context.address receiver = channel_manager.receiver channel = client.open_channel(receiver, 10) wait_for_blocks(channel_manager.n_confirmations + 1) channel_manager.register_payment(sender, channel.block, 2, encode_hex(channel.create_transfer(2))) receiver_sig = channel_manager.sign_close(sender, channel.block, 2) channel.close_cooperatively(receiver_sig) wait_for_blocks(channel_manager.n_confirmations + 1) channel_manager.stop() # don't update state from this point on channel_manager.join() state = channel_manager.state tx_count_before = web3.eth.getTransactionCount(receiver) close_open_channels(channel_manager.private_key, state, channel_manager.channel_manager_contract, wait=lambda: wait_for_blocks(1)) tx_count_after = web3.eth.getTransactionCount(receiver) assert tx_count_after == tx_count_before wait_for_blocks(1)
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()
def confirmed_open_channel(channel_manager: ChannelManager, client: Client, receiver_address: str, wait_for_blocks): channel = client.open_channel(receiver_address, 10) wait_for_blocks(channel_manager.n_confirmations + 1) gevent.sleep(channel_manager.blockchain.poll_interval) assert (channel.sender, channel.block) in channel_manager.channels return channel
def test_topup_channel_insufficient_tokens(client: Client, web3: Web3, receiver_address: str): balance_of = client.token_proxy.contract.call().balanceOf(client.account) channel = client.open_channel(receiver_address, 1) tx_count_pre = web3.eth.getTransactionCount(client.account) assert channel.topup(balance_of) is None tx_count_post = web3.eth.getTransactionCount(client.account) assert tx_count_post == tx_count_pre
def confirmed_open_channel( channel_manager: ChannelManager, client: Client, receiver_address: str, wait_for_blocks ): channel = client.open_channel(receiver_address, 10) wait_for_blocks(channel_manager.n_confirmations + 1) gevent.sleep(channel_manager.blockchain.poll_interval) assert (channel.sender, channel.block) in channel_manager.channels return channel
def test_client(client: Client, receiver_address): """test if contract calls go through""" c = client.open_channel(receiver_address, 10) assert c is not None sig = c.create_transfer(5) assert sig is not None ev = c.topup(10) assert ev is not None assert c.deposit == 20 ev = c.close() assert ev is not None
def test_unconfirmed_topup(channel_manager: ChannelManager, client: Client, receiver_address: str, wait_for_blocks): blockchain = channel_manager.blockchain channel_manager.wait_sync() channel = client.open_channel(receiver_address, 10) wait_for_blocks(1) gevent.sleep(blockchain.poll_interval) assert (channel.sender, channel.block) in channel_manager.unconfirmed_channels channel.topup(5) wait_for_blocks(channel_manager.blockchain.n_confirmations) gevent.sleep(blockchain.poll_interval) assert (channel.sender, channel.block) in channel_manager.channels channel_rec = channel_manager.channels[channel.sender, channel.block] assert channel_rec.deposit == 15
def open_channel( channel_manager: ChannelManager, client: Client, receiver_address: str, ): channel = client.open_channel(receiver_address, 10) wait_for_blocks(channel_manager.n_confirmations + 1) gevent.sleep(channel_manager.blockchain.poll_interval) time.sleep(30) #time.sleep(120) print("channels: ", channel_manager.channels) print("sender: ", channel.sender) print("block: ", channel.block) #assert (channel.sender, channel.block) in channel_manager.channels return channel
def test_unconfirmed_topup( channel_manager: ChannelManager, client: Client, receiver_address: str, wait_for_blocks ): blockchain = channel_manager.blockchain channel_manager.wait_sync() channel = client.open_channel(receiver_address, 10) wait_for_blocks(1) gevent.sleep(blockchain.poll_interval) assert (channel.sender, channel.block) in channel_manager.unconfirmed_channels channel.topup(5) wait_for_blocks(channel_manager.blockchain.n_confirmations) gevent.sleep(blockchain.poll_interval) assert (channel.sender, channel.block) in channel_manager.channels channel_rec = channel_manager.channels[channel.sender, channel.block] assert channel_rec.deposit == 15
def test_client(client: Client, receiver_privkey, receiver_address): """test if contract calls go through""" import logging logging.basicConfig(level=logging.INFO) c = client.open_channel(receiver_address, 10) assert c is not None sig = c.create_transfer(5) assert sig is not None ev = c.topup(10) assert ev is not None assert c.deposit == 20 ev = c.close() assert ev is not None close_channel_cooperatively(c, receiver_privkey)
def test_close_unconfirmed_event( channel_manager: ChannelManager, client: Client, receiver_address: str, wait_for_blocks ): channel_manager.wait_sync() blockchain = channel_manager.blockchain # if unconfirmed channel is closed it should simply be forgotten channel = client.open_channel(receiver_address, 10) wait_for_blocks(1) gevent.sleep(blockchain.poll_interval) assert (channel.sender, channel.block) in channel_manager.unconfirmed_channels assert (channel.sender, channel.block) not in channel_manager.channels channel.close() wait_for_blocks(channel_manager.blockchain.n_confirmations) # opening confirmed gevent.sleep(blockchain.poll_interval) assert (channel.sender, channel.block) not in channel_manager.unconfirmed_channels assert (channel.sender, channel.block) in channel_manager.channels wait_for_blocks(1) # closing confirmed gevent.sleep(blockchain.poll_interval) assert (channel.sender, channel.block) not in channel_manager.unconfirmed_channels assert (channel.sender, channel.block) in channel_manager.channels
def test_different_receivers( web3: Web3, make_account, private_keys: List[str], channel_manager_contract: Contract, token_contract: Contract, mine_sync_event, client: Client, sender_address: str, wait_for_blocks, use_tester: bool, state_db_path: str ): if not use_tester: pytest.skip('This test takes several hours on real blockchains.') 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] ) receiver1_address = privkey_to_addr(receiver1_privkey) 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 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()
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()
def test_different_receivers( web3: Web3, make_account, channel_manager_contract: Contract, token_contract: Contract, mine_sync_event, client: Client, sender_address: str, wait_for_blocks, use_tester: bool, state_db_path: str ): 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, 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 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()