From f4f8a363dddd297b59ed1ee16a8259cee27931c3 Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Wed, 20 May 2020 06:11:24 +0930 Subject: [PATCH] pytest: fix feature mask for EXPERIMENTAL_FEATURES, add wumbo support. There are various places where our tests failed with --enable-expimental-features. And our plugin test overlapped an existing feature. We make our expected_feature functions more generic, and use them everywhere. Signed-off-by: Rusty Russell --- tests/plugins/feature-test.py | 6 ++--- tests/test_misc.py | 2 ++ tests/test_plugin.py | 21 ++++++++-------- tests/utils.py | 46 ++++++++++++++++++++++++++--------- 4 files changed, 50 insertions(+), 25 deletions(-) diff --git a/tests/plugins/feature-test.py b/tests/plugins/feature-test.py index 8c8c68f9e..02be45004 100755 --- a/tests/plugins/feature-test.py +++ b/tests/plugins/feature-test.py @@ -6,9 +6,9 @@ from pyln.client import Plugin # later check that they are being passed correctly. plugin = Plugin( dynamic=False, - init_features=1 << 101, - node_features=1 << 103, - invoice_features=1 << 105, + init_features=1 << 201, + node_features=1 << 203, + invoice_features=1 << 205, ) diff --git a/tests/test_misc.py b/tests/test_misc.py index 159e50fb1..24c1b3aab 100644 --- a/tests/test_misc.py +++ b/tests/test_misc.py @@ -1880,6 +1880,8 @@ def test_list_features_only(node_factory): 'option_payment_secret/odd', 'option_basic_mpp/odd', ] + if EXPERIMENTAL_FEATURES: + expected += ['option_unknown_102/odd'] assert features == expected diff --git a/tests/test_plugin.py b/tests/test_plugin.py index 702ef24c8..5e348eaff 100644 --- a/tests/test_plugin.py +++ b/tests/test_plugin.py @@ -6,7 +6,8 @@ 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_peer_features, expected_node_features, account_balance, + DEPRECATED_APIS, expected_peer_features, expected_node_features, + expected_channel_features, account_balance, check_coin_moves, first_channel_id, check_coin_moves_idx ) @@ -1001,9 +1002,9 @@ def test_plugin_feature_announce(node_factory): registers an individual featurebit for each of the locations we can stash feature bits in: - - 1 << 101 for `init` messages - - 1 << 103 for `node_announcement` - - 1 << 105 for bolt11 invoices + - 1 << 201 for `init` messages + - 1 << 203 for `node_announcement` + - 1 << 205 for bolt11 invoices """ plugin = os.path.join(os.path.dirname(__file__), 'plugins/feature-test.py') @@ -1013,18 +1014,18 @@ 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_peer_features())) + # feature-test.py. + assert l1.daemon.is_in_log(r'\[OUT\] 001000022200....{}' + .format(expected_peer_features(extra=[201]))) # Check the invoice featurebit we set in feature-test.py inv = l1.rpc.invoice(123, 'lbl', 'desc')['bolt11'] details = Invoice.decode(inv) - assert(details.featurebits.int & (1 << 105) != 0) + assert(details.featurebits.int & (1 << 205) != 0) # Check the featurebit set in the `node_announcement` node = l1.rpc.listnodes(l1.info['id'])['nodes'][0] - assert(int(node['features'], 16) & (1 << 103) != 0) + assert node['features'] == expected_node_features(extra=[203]) def test_hook_chaining(node_factory): @@ -1247,7 +1248,7 @@ def test_feature_set(node_factory): fs = l1.rpc.call('getfeatureset') assert fs['init'] == expected_peer_features() assert fs['node'] == expected_node_features() - assert fs['channel'] == '' + assert fs['channel'] == expected_channel_features() assert 'invoice' in fs diff --git a/tests/utils.py b/tests/utils.py index 3962c2681..0e678a126 100644 --- a/tests/utils.py +++ b/tests/utils.py @@ -1,32 +1,54 @@ from pyln.testing.utils import TEST_NETWORK, SLOW_MACHINE, TIMEOUT, VALGRIND, DEVELOPER, DEPRECATED_APIS # noqa: F401 from pyln.testing.utils import env, only_one, wait_for, write_config, TailableProc, sync_blockheight, wait_channel_quiescent, get_tx_p2wsh_outnum # noqa: F401 - +import bitstring EXPERIMENTAL_FEATURES = env("EXPERIMENTAL_FEATURES", "0") == "1" COMPAT = env("COMPAT", "1") == "1" -def expected_peer_features(): +def hex_bits(features): + # We always to full bytes + flen = (max(features + [0]) + 7) // 8 * 8 + res = bitstring.BitArray(length=flen) + # Big endian sucketh. + for f in features: + res[flen - 1 - f] = 1 + return res.hex + + +def expected_peer_features(wumbo_channels=False, extra=[]): """Return the expected peer features hexstring for this configuration""" - # features 1, 3, 7, 9, 11, 13, 15 and 17 (0x02aaa2). - return "02aaa2" + features = [1, 5, 7, 9, 11, 13, 15, 17] + if EXPERIMENTAL_FEATURES: + # OPT_ONION_MESSAGES + features += [103] + if wumbo_channels: + features += [19] + return hex_bits(features + extra) # 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(): +def expected_node_features(wumbo_channels=False, extra=[]): """Return the expected node features hexstring for this configuration""" - # features 1, 3, 7, 9, 11, 13, 15, 17 and 55 (0x8000000002aaa2). - return "8000000002aaa2" + features = [1, 5, 7, 9, 11, 13, 15, 17, 55] + if EXPERIMENTAL_FEATURES: + # OPT_ONION_MESSAGES + features += [103] + if wumbo_channels: + features += [19] + return hex_bits(features + extra) -def expected_channel_features(): +def expected_channel_features(wumbo_channels=False, extra=[]): """Return the expected channel features hexstring for this configuration""" - # experimental OPT_ONION_MESSAGES + features = [] if EXPERIMENTAL_FEATURES: - return '80000000000000000000000000' - else: - return '' + # OPT_ONION_MESSAGES + features += [103] + if wumbo_channels: + features += [19] + return hex_bits(features + extra) def check_coin_moves(n, account_id, expected_moves):