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 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_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 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()
def channel_manager(web3, receiver_privkey, make_channel_manager_proxy, token_contract, use_tester, mine_sync_event, state_db_path): 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, state_filename=state_db_path) start_channel_manager(manager, use_tester, mine_sync_event) yield manager manager.stop() if use_tester: web3.testing.revert(snapshot_id) manager.stop()
def channel_manager( web3, receiver_privkey, channel_manager_contract, token_contract, use_tester, mine_sync_event, state_db_path, patched_contract, revert_chain ): manager = ChannelManager( web3, channel_manager_contract, 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()
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_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()
def stop_patched(self: ChannelManager): mine_sync_event.set() ChannelManager.stop(self)
def stop_patched(self: ChannelManager): mine_sync_event.set() ChannelManager.stop(self) self.stop = types.MethodType(ChannelManager.stop, self)
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()