-
Notifications
You must be signed in to change notification settings - Fork 378
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
bugfix: python's api close was non-functional
This fixes the python api close, add a regression test for that problem and add general tests for it.
- Loading branch information
1 parent
6522f98
commit 3832815
Showing
6 changed files
with
210 additions
and
30 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,159 @@ | ||
# -*- coding: utf-8 -*- | ||
import pytest | ||
|
||
from raiden.api.python import RaidenAPI | ||
from raiden.exceptions import InvalidState | ||
from raiden.network.protocol import ( | ||
NODE_NETWORK_REACHABLE, | ||
NODE_NETWORK_UNKNOWN, | ||
) | ||
from raiden.transfer.state import ( | ||
CHANNEL_STATE_CLOSED, | ||
CHANNEL_STATE_OPENED, | ||
CHANNEL_STATE_SETTLED, | ||
) | ||
from raiden.utils import get_contract_path | ||
from raiden.tests.utils.blockchain import wait_until_block | ||
|
||
|
||
@pytest.mark.parametrize('privatekey_seed', ['test_token_addresses:{}']) | ||
@pytest.mark.parametrize('number_of_nodes', [2]) | ||
@pytest.mark.parametrize('number_of_tokens', [2]) | ||
def test_token_addresses(raiden_network, token_addresses): | ||
node1, node2 = raiden_network | ||
token_address = token_addresses[0] | ||
|
||
api1 = RaidenAPI(node1.raiden) | ||
api2 = RaidenAPI(node2.raiden) | ||
|
||
assert api1.address == node1.raiden.address | ||
|
||
assert set(api1.tokens) == set(token_addresses) | ||
assert set(api1.get_tokens_list()) == set(token_addresses) | ||
|
||
channels = api1.get_channel_list(token_address, api2.address) | ||
assert api1.get_channel_list(token_address) == channels | ||
assert len(api1.get_channel_list()) == 2 | ||
|
||
assert api1.get_node_network_state(api2.address) == NODE_NETWORK_REACHABLE | ||
|
||
|
||
@pytest.mark.parametrize('privatekey_seed', ['test_token_registration:{}']) | ||
@pytest.mark.parametrize('number_of_nodes', [1]) | ||
@pytest.mark.parametrize('number_of_tokens', [0]) | ||
def test_token_registration(blockchain_type, raiden_network, tester_state): | ||
if blockchain_type == 'tester': | ||
pytest.skip( | ||
'current version of the pyethereum dependency does not support the REVERT opcode' | ||
) | ||
|
||
node1 = raiden_network[0] | ||
token_amount = 1000 | ||
|
||
token_address = node1.raiden.chain.deploy_contract( | ||
contract_name='HumanStandardToken', | ||
contract_path=get_contract_path('HumanStandardToken.sol'), | ||
constructor_parameters=(token_amount, 'raiden', 2, 'Rd'), | ||
) | ||
|
||
api1 = RaidenAPI(node1.raiden) | ||
assert not api1.get_tokens_list() | ||
|
||
assert api1.manager_address_if_token_registered(token_address) is None | ||
|
||
node1.raiden.poll_blockchain_events() | ||
assert not api1.get_tokens_list() | ||
|
||
api1.register_token(token_address) | ||
|
||
assert api1.manager_address_if_token_registered(token_address) is not None | ||
assert api1.get_tokens_list() == [token_address] | ||
|
||
|
||
@pytest.mark.parametrize('privatekey_seed', ['test_channel_lifetime:{}']) | ||
@pytest.mark.parametrize('number_of_nodes', [2]) | ||
@pytest.mark.parametrize('channels_per_node', [0]) | ||
def test_channel_lifecycle(blockchain_type, raiden_network, token_addresses, deposit): | ||
if blockchain_type == 'tester': | ||
pytest.skip( | ||
'there is not support ATM for retrieving events from tester' | ||
) | ||
|
||
node1, node2 = raiden_network | ||
token_address = token_addresses[0] | ||
|
||
api1 = RaidenAPI(node1.raiden) | ||
api2 = RaidenAPI(node2.raiden) | ||
|
||
# nodes don't have a channel, so they are not healthchecking | ||
assert api1.get_node_network_state(api2.address) == NODE_NETWORK_UNKNOWN | ||
assert api2.get_node_network_state(api1.address) == NODE_NETWORK_UNKNOWN | ||
assert api1.get_channel_list(token_address, api2.address) == [] | ||
|
||
# this is a synchronous api | ||
api1.open(token_address, api2.address) | ||
channels = api1.get_channel_list(token_address, api2.address) | ||
assert len(channels) == 1 | ||
channel12 = channels[0] | ||
|
||
event_list1 = api1.get_channel_events( | ||
channel12.channel_address, | ||
channel12.external_state.opened_block, | ||
) | ||
assert event_list1 == [] | ||
|
||
# the channel has no deposit yet | ||
assert channel12.state == CHANNEL_STATE_OPENED | ||
|
||
api1.deposit(token_address, api2.address, deposit) | ||
|
||
assert channel12.state == CHANNEL_STATE_OPENED | ||
assert channel12.balance == deposit | ||
assert channel12.contract_balance == deposit | ||
assert api1.get_channel_list(token_address, api2.address) == [channel12] | ||
|
||
# there is a channel open, they must be checking each other | ||
assert api1.get_node_network_state(api2.address) == NODE_NETWORK_REACHABLE | ||
assert api2.get_node_network_state(api1.address) == NODE_NETWORK_REACHABLE | ||
|
||
event_list2 = api1.get_channel_events( | ||
channel12.channel_address, | ||
channel12.external_state.opened_block, | ||
) | ||
assert any( | ||
( | ||
event['_event_type'] == 'ChannelNewBalance' and | ||
event['participant'] == api1.address.encode('hex') | ||
) | ||
for event in event_list2 | ||
) | ||
|
||
with pytest.raises(InvalidState): | ||
api1.settle(token_address, api2.address) | ||
|
||
api1.close(token_address, api2.address) | ||
node1.raiden.poll_blockchain_events() | ||
|
||
event_list3 = api1.get_channel_events( | ||
channel12.channel_address, | ||
channel12.external_state.opened_block, | ||
) | ||
assert len(event_list3) > len(event_list2) | ||
assert any( | ||
( | ||
event['_event_type'] == 'ChannelClosed' and | ||
event['closing_address'] == api1.address.encode('hex') | ||
) | ||
for event in event_list3 | ||
) | ||
assert channel12.state == CHANNEL_STATE_CLOSED | ||
|
||
settlement_block = ( | ||
channel12.external_state.closed_block + | ||
channel12.settle_timeout + | ||
5 # arbitrary number of additional blocks, used to wait for the settle() call | ||
) | ||
wait_until_block(node1.raiden.chain, settlement_block) | ||
|
||
node1.raiden.poll_blockchain_events() | ||
assert channel12.state == CHANNEL_STATE_SETTLED |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
# -*- coding: utf-8 -*- | ||
import pytest | ||
|
||
from raiden.api.python import RaidenAPI | ||
|
||
|
||
@pytest.mark.parametrize('privatekey_seed', ['test_close_regression:{}']) | ||
@pytest.mark.parametrize('number_of_nodes', [2]) | ||
@pytest.mark.parametrize('channels_per_node', [1]) | ||
def test_close_regression(raiden_network, token_addresses): | ||
""" The python api was using the wrong balance proof to close the channel, | ||
thus the close was failling if a transfer was made. | ||
""" | ||
node1, node2 = raiden_network | ||
token_address = token_addresses[0] | ||
|
||
api1 = RaidenAPI(node1.raiden) | ||
api2 = RaidenAPI(node2.raiden) | ||
|
||
amount = 10 | ||
assert api1.transfer(token_address, amount, api2.address) | ||
|
||
api1.close(token_address, api2.address) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters