diff --git a/lightningd/lightningd.c b/lightningd/lightningd.c index 3919c678e..d8120f4e2 100644 --- a/lightningd/lightningd.c +++ b/lightningd/lightningd.c @@ -896,7 +896,7 @@ static struct feature_set *default_features(const tal_t *ctx) OPTIONAL_FEATURE(OPT_BASIC_MPP), OPTIONAL_FEATURE(OPT_LARGE_CHANNELS), OPTIONAL_FEATURE(OPT_GOSSIP_QUERIES_EX), - OPTIONAL_FEATURE(OPT_STATIC_REMOTEKEY), + COMPULSORY_FEATURE(OPT_STATIC_REMOTEKEY), OPTIONAL_FEATURE(OPT_SHUTDOWN_ANYSEGWIT), OPTIONAL_FEATURE(OPT_PAYMENT_METADATA), OPTIONAL_FEATURE(OPT_SCID_ALIAS), diff --git a/tests/test_connection.py b/tests/test_connection.py index 70c60185d..8410539ee 100644 --- a/tests/test_connection.py +++ b/tests/test_connection.py @@ -3578,15 +3578,19 @@ def test_channel_features(node_factory, bitcoind, anchors): def test_nonstatic_channel(node_factory, bitcoind): """Smoke test for a channel without option_static_remotekey""" - l1, l2 = node_factory.line_graph(2, - opts=[{}, - # needs at least 1, 7 and 15 to connect - # (and 9 is a dependent) - {'dev-force-features': '1,7,9,15////////'}]) + l1, l2 = node_factory.get_nodes(2, + # This forces us to allow send/recv of non-static-remotekey! + opts={'dev-any-channel-type': None}) + l1.fundwallet(2000000) + l1.rpc.connect(l2.info['id'], 'localhost', port=l2.port) + l1.rpc.fundchannel(l2.info['id'], 'all', channel_type=[]) + bitcoind.generate_block(1, wait_for_mempool=1) + chan = only_one(l1.rpc.listpeerchannels()['channels']) assert 'option_static_remotekey' not in chan['features'] assert 'option_anchor' not in chan['features'] assert 'option_anchors_zero_fee_htlc_tx' not in chan['features'] + wait_for(lambda: only_one(l1.rpc.listpeerchannels()['channels'])['state'] == 'CHANNELD_NORMAL') l1.pay(l2, 1000) l1.rpc.close(l2.info['id']) @@ -3693,12 +3697,20 @@ def test_openchannel_init_alternate(node_factory, executor): def test_upgrade_statickey(node_factory, executor): """l1 doesn't have option_static_remotekey, l2 offers it.""" - l1, l2 = node_factory.line_graph(2, opts=[{'may_reconnect': True, - 'dev-force-features': ["-13"], - 'experimental-upgrade-protocol': None}, - {'may_reconnect': True, - 'experimental-upgrade-protocol': None}]) + l1, l2 = node_factory.get_nodes(2, opts=[{'may_reconnect': True, + 'experimental-upgrade-protocol': None, + # This forces us to allow sending non-static-remotekey! + 'dev-any-channel-type': None}, + {'may_reconnect': True, + # This forces us to accept non-static-remotekey! + 'dev-any-channel-type': None, + 'experimental-upgrade-protocol': None}]) + l1.fundwallet(2000000) + l1.rpc.connect(l2.info['id'], 'localhost', port=l2.port) + l1.rpc.fundchannel(l2.info['id'], 'all', channel_type=[]) + + # Now reconnect. l1.rpc.disconnect(l2.info['id'], force=True) l1.rpc.connect(l2.info['id'], 'localhost', l2.port) @@ -3723,15 +3735,22 @@ def test_upgrade_statickey(node_factory, executor): def test_upgrade_statickey_onchaind(node_factory, executor, bitcoind): """We test penalty before/after, and unilateral before/after""" - l1, l2 = node_factory.line_graph(2, opts=[{'may_reconnect': True, - 'dev-no-reconnect': None, - 'dev-force-features': ["-13"], - 'experimental-upgrade-protocol': None, - # We try to cheat! - 'allow_broken_log': True}, - {'may_reconnect': True, - 'dev-no-reconnect': None, - 'experimental-upgrade-protocol': None}]) + l1, l2 = node_factory.get_nodes(2, opts=[{'may_reconnect': True, + 'experimental-upgrade-protocol': None, + # This forces us to allow sending non-static-remotekey! + 'dev-any-channel-type': None, + # We try to cheat! + 'allow_broken_log': True}, + {'may_reconnect': True, + # This forces us to allow non-static-remotekey! + 'dev-any-channel-type': None, + 'experimental-upgrade-protocol': None}]) + + l1.fundwallet(FUNDAMOUNT + 1000) + l1.rpc.connect(l2.info['id'], 'localhost', port=l2.port) + l1.rpc.fundchannel(l2.info['id'], 'all', channel_type=[]) + bitcoind.generate_block(1, wait_for_mempool=1) + wait_for(lambda: only_one(l1.rpc.listpeerchannels()['channels'])['state'] == 'CHANNELD_NORMAL') # TEST 1: Cheat from pre-upgrade. tx = l1.rpc.dev_sign_last_tx(l2.info['id'])['tx'] @@ -3769,12 +3788,17 @@ def test_upgrade_statickey_onchaind(node_factory, executor, bitcoind): wait_for(lambda: l2.rpc.listpeerchannels()['channels'] == []) # TEST 2: Cheat from post-upgrade. - node_factory.join_nodes([l1, l2]) + l1.fundwallet(FUNDAMOUNT + 1000) + l1.rpc.connect(l2.info['id'], 'localhost', port=l2.port) + l1.rpc.fundchannel(l2.info['id'], 'all', channel_type=[]) + l1.rpc.disconnect(l2.info['id'], force=True) l1.rpc.connect(l2.info['id'], 'localhost', l2.port) l1.daemon.wait_for_log('option_static_remotekey enabled at 1/1') l2.daemon.wait_for_log('option_static_remotekey enabled at 1/1') + bitcoind.generate_block(1, wait_for_mempool=1) + wait_for(lambda: only_one(l1.rpc.listpeerchannels()['channels'])['state'] == 'CHANNELD_NORMAL') l1.pay(l2, 1000000) @@ -3796,7 +3820,11 @@ def test_upgrade_statickey_onchaind(node_factory, executor, bitcoind): wait_for(lambda: len(l2.rpc.listpeerchannels()['channels']) == 0) # TEST 3: Unilateral close from pre-upgrade - node_factory.join_nodes([l1, l2]) + l1.rpc.connect(l2.info['id'], 'localhost', port=l2.port) + l1.fundwallet(FUNDAMOUNT + 1000) + l1.rpc.fundchannel(l2.info['id'], 'all', channel_type=[]) + bitcoind.generate_block(1, wait_for_mempool=1) + wait_for(lambda: only_one(l1.rpc.listpeerchannels()['channels'])['state'] == 'CHANNELD_NORMAL') # Give them both something for onchain close. l1.pay(l2, 1000000) @@ -3827,12 +3855,16 @@ def test_upgrade_statickey_onchaind(node_factory, executor, bitcoind): wait_for(lambda: len(l2.rpc.listpeerchannels()['channels']) == 0) # TEST 4: Unilateral close from post-upgrade - node_factory.join_nodes([l1, l2]) + l1.rpc.connect(l2.info['id'], 'localhost', port=l2.port) + l1.rpc.fundchannel(l2.info['id'], 'all', channel_type=[]) l1.rpc.disconnect(l2.info['id'], force=True) l1.rpc.connect(l2.info['id'], 'localhost', l2.port) l1.daemon.wait_for_log('option_static_remotekey enabled at 1/1') + bitcoind.generate_block(1, wait_for_mempool=1) + wait_for(lambda: only_one(l1.rpc.listpeerchannels()['channels'])['state'] == 'CHANNELD_NORMAL') + # Move to static_remotekey. l1.pay(l2, 1000000) @@ -3862,20 +3894,28 @@ def test_upgrade_statickey_fail(node_factory, executor, bitcoind): l2_disconnects = ['-WIRE_REVOKE_AND_ACK', '-WIRE_COMMITMENT_SIGNED'] - l1, l2 = node_factory.line_graph(2, opts=[{'may_reconnect': True, - 'dev-no-reconnect': None, - 'disconnect': l1_disconnects, - 'experimental-upgrade-protocol': None, - 'dev-force-features': ["-13"], - # Don't have feerate changes! - 'feerates': (7500, 7500, 7500, 7500)}, - {'may_reconnect': True, - 'dev-no-reconnect': None, - 'experimental-upgrade-protocol': None, - 'disconnect': l2_disconnects, - 'plugin': os.path.join(os.getcwd(), 'tests/plugins/hold_htlcs.py'), - 'hold-time': 10000, - 'hold-result': 'fail'}]) + l1, l2 = node_factory.get_nodes(2, opts=[{'may_reconnect': True, + 'dev-no-reconnect': None, + 'disconnect': l1_disconnects, + # This allows us to send non-static-remotekey! + 'dev-any-channel-type': None, + 'experimental-upgrade-protocol': None, + # Don't have feerate changes! + 'feerates': (7500, 7500, 7500, 7500)}, + {'may_reconnect': True, + 'dev-no-reconnect': None, + 'experimental-upgrade-protocol': None, + # This forces us to accept non-static-remotekey! + 'dev-any-channel-type': None, + 'disconnect': l2_disconnects, + 'plugin': os.path.join(os.getcwd(), 'tests/plugins/hold_htlcs.py'), + 'hold-time': 10000, + 'hold-result': 'fail'}]) + l1.fundwallet(FUNDAMOUNT + 1000) + l1.rpc.connect(l2.info['id'], 'localhost', port=l2.port) + l1.rpc.fundchannel(l2.info['id'], 'all', channel_type=[]) + bitcoind.generate_block(1, wait_for_mempool=1) + wait_for(lambda: only_one(l1.rpc.listpeerchannels()['channels'])['state'] == 'CHANNELD_NORMAL') # This HTLC will fail l1.rpc.sendpay([{'amount_msat': 1000, 'id': l2.info['id'], 'delay': 5, 'channel': first_scid(l1, l2)}], '00' * 32, payment_secret='00' * 32) diff --git a/tests/test_misc.py b/tests/test_misc.py index 911d8df9f..851dd7eec 100644 --- a/tests/test_misc.py +++ b/tests/test_misc.py @@ -2248,7 +2248,7 @@ def test_list_features_only(node_factory): 'option_gossip_queries/even', 'option_var_onion_optin/even', 'option_gossip_queries_ex/odd', - 'option_static_remotekey/odd', + 'option_static_remotekey/even', 'option_payment_secret/even', 'option_basic_mpp/odd', 'option_support_large_channel/odd', diff --git a/tests/test_opening.py b/tests/test_opening.py index 7bc4a01fd..a86766957 100644 --- a/tests/test_opening.py +++ b/tests/test_opening.py @@ -2608,8 +2608,7 @@ def test_opening_explicit_channel_type(node_factory, bitcoind): ZEROCONF = 50 for zeroconf in ([], [ZEROCONF]): - for ctype in ([], - [STATIC_REMOTEKEY], + for ctype in ([STATIC_REMOTEKEY], [ANCHORS_ZERO_FEE_HTLC_TX, STATIC_REMOTEKEY]): l1.rpc.fundchannel_start(l2.info['id'], FUNDAMOUNT, channel_type=ctype + zeroconf) @@ -2617,15 +2616,14 @@ def test_opening_explicit_channel_type(node_factory, bitcoind): # FIXME: Check type is actually correct! # Zeroconf is refused to l4. - for ctype in ([], - [STATIC_REMOTEKEY], + for ctype in ([STATIC_REMOTEKEY], [ANCHORS_ZERO_FEE_HTLC_TX, STATIC_REMOTEKEY]): with pytest.raises(RpcError, match=r'not on our allowlist'): l1.rpc.fundchannel_start(l4.info['id'], FUNDAMOUNT, channel_type=ctype + [ZEROCONF]) psbt = l1.rpc.fundpsbt(FUNDAMOUNT - 1000, '253perkw', 250, reserve=0)['psbt'] - for ctype in ([], [12], [22, 12]): + for ctype in ([12], [22, 12]): cid = l1.rpc.openchannel_init(l3.info['id'], FUNDAMOUNT - 1000, psbt, channel_type=ctype)['channel_id'] l1.rpc.openchannel_abort(cid) @@ -2636,6 +2634,13 @@ def test_opening_explicit_channel_type(node_factory, bitcoind): with pytest.raises(RpcError, match=r'channel_type not supported'): l1.rpc.openchannel_init(l3.info['id'], FUNDAMOUNT - 1000, psbt, channel_type=[STATIC_REMOTEKEY, ANCHORS_OLD]) + # We need static_remotekey now, too + with pytest.raises(RpcError, match=r'channel_type not supported'): + l1.rpc.fundchannel_start(l2.info['id'], FUNDAMOUNT, channel_type=[]) + + with pytest.raises(RpcError, match=r'channel_type not supported'): + l1.rpc.openchannel_init(l3.info['id'], FUNDAMOUNT - 1000, psbt, channel_type=[]) + # l1 will try, with dev-any-channel-type, l2 will reject. l1.stop() l1.daemon.opts['dev-any-channel-type'] = None @@ -2644,7 +2649,7 @@ def test_opening_explicit_channel_type(node_factory, bitcoind): with pytest.raises(RpcError, match=r'They sent ERROR .*: You gave bad parameters: Did not support channel_type 12,20'): l1.rpc.fundchannel_start(l2.info['id'], FUNDAMOUNT, channel_type=[STATIC_REMOTEKEY, ANCHORS_OLD]) - + # Now make l2 accept it! l2.stop() l2.daemon.opts['dev-any-channel-type'] = None diff --git a/tests/test_plugin.py b/tests/test_plugin.py index 43a5cd872..1c1da3c86 100644 --- a/tests/test_plugin.py +++ b/tests/test_plugin.py @@ -1661,7 +1661,7 @@ def test_plugin_feature_announce(node_factory): # Check the featurebits we've set in the `init` message from # feature-test.py. - assert l1.daemon.is_in_log(r'\[OUT\] 001000022100....{}' + assert l1.daemon.is_in_log(r'\[OUT\] 001000021100....{}' .format(expected_peer_features(extra=[201]))) # Check the invoice featurebit we set in feature-test.py diff --git a/tests/utils.py b/tests/utils.py index ab84dfff8..2f9e903ff 100644 --- a/tests/utils.py +++ b/tests/utils.py @@ -36,7 +36,7 @@ def hex_bits(features): def expected_peer_features(extra=[]): """Return the expected peer features hexstring for this configuration""" - features = [0, 5, 6, 8, 11, 13, 14, 17, 19, 25, 27, 45, 47, 51] + features = [0, 5, 6, 8, 11, 12, 14, 17, 19, 25, 27, 45, 47, 51] if EXPERIMENTAL_DUAL_FUND: # option_dual_fund features += [29] @@ -50,7 +50,7 @@ def expected_peer_features(extra=[]): # features for the 'node' and the 'peer' feature sets def expected_node_features(extra=[]): """Return the expected node features hexstring for this configuration""" - features = [0, 5, 6, 8, 11, 13, 14, 17, 19, 25, 27, 45, 47, 51, 55] + features = [0, 5, 6, 8, 11, 12, 14, 17, 19, 25, 27, 45, 47, 51, 55] if EXPERIMENTAL_DUAL_FUND: # option_dual_fund features += [29]