From d6d26dd056dcd1e0ed9c453b01ae8744fae51781 Mon Sep 17 00:00:00 2001 From: lisa neigut Date: Mon, 27 Apr 2020 19:33:03 -0500 Subject: [PATCH] features: split expected feature bits into node/peer sets The new `keysend` plugin modifies the node features that we send to peers. This commit breaks out the 'expected_features' we use for tests to encompass this differentiation. --- tests/test_connection.py | 19 ++++++++++--------- tests/test_gossip.py | 4 ++-- tests/test_plugin.py | 8 ++++---- tests/utils.py | 12 ++++++++++-- 4 files changed, 26 insertions(+), 17 deletions(-) diff --git a/tests/test_connection.py b/tests/test_connection.py index cc7dfe529..0c06a85b6 100644 --- a/tests/test_connection.py +++ b/tests/test_connection.py @@ -6,7 +6,7 @@ from flaky import flaky # noqa: F401 from pyln.client import RpcError, Millisatoshi from utils import ( DEVELOPER, only_one, wait_for, sync_blockheight, VALGRIND, TIMEOUT, - SLOW_MACHINE, expected_features + SLOW_MACHINE, expected_peer_features, expected_node_features ) from bitcoin.core import CMutableTransaction, CMutableTxOut @@ -1558,7 +1558,8 @@ def test_forget_channel(node_factory): def test_peerinfo(node_factory, bitcoind): l1, l2 = node_factory.line_graph(2, fundchannel=False, opts={'may_reconnect': True}) - lfeatures = expected_features() + lfeatures = expected_peer_features() + nfeatures = expected_node_features() # Gossiping but no node announcement yet assert l1.rpc.getpeer(l2.info['id'])['connected'] assert len(l1.rpc.getpeer(l2.info['id'])['channels']) == 0 @@ -1576,11 +1577,11 @@ def test_peerinfo(node_factory, bitcoind): nodes2 = l2.rpc.listnodes(l2.info['id'])['nodes'] peer1 = l1.rpc.getpeer(l2.info['id']) peer2 = l2.rpc.getpeer(l1.info['id']) - assert only_one(nodes1)['features'] == peer1['features'] - assert only_one(nodes2)['features'] == peer2['features'] - - assert l1.rpc.getpeer(l2.info['id'])['features'] == lfeatures - assert l2.rpc.getpeer(l1.info['id'])['features'] == lfeatures + # peer features != to node features now because of keysend, which adds a node feature + assert only_one(nodes1)['features'] == nfeatures + assert only_one(nodes2)['features'] == nfeatures + assert peer1['features'] == lfeatures + assert peer2['features'] == lfeatures # If it reconnects after db load, it should know features. l1.restart() @@ -1813,7 +1814,7 @@ def test_dataloss_protection(node_factory, bitcoind): l2 = node_factory.get_node(may_reconnect=True, options={'log-level': 'io'}, feerates=(7500, 7500, 7500, 7500), allow_broken_log=True) - lf = expected_features() + lf = expected_peer_features() l1.rpc.connect(l2.info['id'], 'localhost', l2.port) # l1 should send out WIRE_INIT (0010) @@ -2236,7 +2237,7 @@ def test_pay_disconnect_stress(node_factory, executor): def test_wumbo_channels(node_factory, bitcoind): - f = bytes.fromhex(expected_features()) + f = bytes.fromhex(expected_peer_features()) # OPT_LARGE_CHANNELS = 18 (19 for us). 0x080000 f = (f[:-3] + bytes([f[-3] | 0x08]) + f[-2:]).hex() diff --git a/tests/test_gossip.py b/tests/test_gossip.py index 7c2bb3b72..9a3076b28 100644 --- a/tests/test_gossip.py +++ b/tests/test_gossip.py @@ -4,7 +4,7 @@ from fixtures import * # noqa: F401,F403 from fixtures import TEST_NETWORK from pyln.client import RpcError from utils import ( - wait_for, TIMEOUT, only_one, sync_blockheight, expected_features + wait_for, TIMEOUT, only_one, sync_blockheight, expected_node_features ) import json @@ -1029,7 +1029,7 @@ def test_node_reannounce(node_factory, bitcoind): wait_for(lambda: 'alias' in only_one(l2.rpc.listnodes(l1.info['id'])['nodes'])) assert only_one(l2.rpc.listnodes(l1.info['id'])['nodes'])['alias'].startswith('JUNIORBEAM') - lfeatures = expected_features() + lfeatures = expected_node_features() # Make sure it gets features correct. assert only_one(l2.rpc.listnodes(l1.info['id'])['nodes'])['features'] == lfeatures diff --git a/tests/test_plugin.py b/tests/test_plugin.py index 797a4fed2..cbf324cac 100644 --- a/tests/test_plugin.py +++ b/tests/test_plugin.py @@ -6,7 +6,7 @@ from pyln.client import RpcError, Millisatoshi from pyln.proto import Invoice from utils import ( DEVELOPER, only_one, sync_blockheight, TIMEOUT, wait_for, TEST_NETWORK, - DEPRECATED_APIS, expected_features + DEPRECATED_APIS, expected_peer_features, expected_node_features ) import json @@ -946,7 +946,7 @@ def test_plugin_feature_announce(node_factory): # Check the featurebits we've set in the `init` message from # feature-test.py. (1 << 101) results in 13 bytes featutebits (000d) and # has a leading 0x20. - assert l1.daemon.is_in_log(r'\[OUT\] 001000.*000d20{:0>24}'.format(expected_features())) + assert l1.daemon.is_in_log(r'\[OUT\] 001000.*000d20{:0>24}'.format(expected_peer_features())) # Check the invoice featurebit we set in feature-test.py inv = l1.rpc.invoice(123, 'lbl', 'desc')['bolt11'] @@ -1176,8 +1176,8 @@ def test_feature_set(node_factory): l1 = node_factory.get_node(options={"plugin": plugin}) fs = l1.rpc.call('getfeatureset') - assert fs['init'] == expected_features() - assert fs['node'] == expected_features() + assert fs['init'] == expected_peer_features() + assert fs['node'] == expected_node_features() assert fs['channel'] == '' assert 'invoice' in fs diff --git a/tests/utils.py b/tests/utils.py index a6a2aca38..814f05ded 100644 --- a/tests/utils.py +++ b/tests/utils.py @@ -6,7 +6,15 @@ EXPERIMENTAL_FEATURES = env("EXPERIMENTAL_FEATURES", "0") == "1" COMPAT = env("COMPAT", "1") == "1" -def expected_features(): - """Return the expected features hexstring for this configuration""" +def expected_peer_features(): + """Return the expected peer features hexstring for this configuration""" # features 1, 3, 7, 9, 11, 13, 15 and 17 (0x02aaa2). return "02aaa2" + + +# With the addition of the keysend plugin, we now send a different set of +# features for the 'node' and the 'peer' feature sets +def expected_node_features(): + """Return the expected node features hexstring for this configuration""" + # features 1, 3, 7, 9, 11, 13, 15, 17 and 55 (0x8000000002aaa2). + return "8000000002aaa2"