diff --git a/lightningd/channel.c b/lightningd/channel.c index 5687269bd..cc60df3de 100644 --- a/lightningd/channel.c +++ b/lightningd/channel.c @@ -250,11 +250,14 @@ struct channel *new_unsaved_channel(struct peer *peer, /* BOLT-7b04b1461739c5036add61782d58ac490842d98b #9 * | 222/223 | `option_dual_fund` * | Use v2 of channel open, enables dual funding - * | IN9 - * | `option_anchor_outputs` */ + * | IN9 */ channel->static_remotekey_start[LOCAL] = channel->static_remotekey_start[REMOTE] = 0; - channel->type = channel_type_anchor_outputs(channel); + + channel->type = default_channel_type(channel, + peer->ld->our_features, + peer->their_features); + channel->future_per_commitment_point = NULL; channel->lease_commit_sig = NULL; diff --git a/lightningd/dual_open_control.c b/lightningd/dual_open_control.c index a39f7fb82..9eef6d326 100644 --- a/lightningd/dual_open_control.c +++ b/lightningd/dual_open_control.c @@ -2605,8 +2605,6 @@ static struct command_result *init_set_feerate(struct command *cmd, } if (!*feerate_per_kw) { *feerate_per_kw = tal(cmd, u32); - /* FIXME: Anchors are on by default, we should use the lowest - * possible feerate */ **feerate_per_kw = **feerate_per_kw_funding; } diff --git a/lightningd/options.c b/lightningd/options.c index f4267ecd8..a6f4bdc20 100644 --- a/lightningd/options.c +++ b/lightningd/options.c @@ -1045,10 +1045,10 @@ static char *opt_set_websocket_port(const char *arg, struct lightningd *ld) static char *opt_set_dual_fund(struct lightningd *ld) { - /* Dual funding implies anchor outputs */ + /* Dual funding implies static remotkey */ feature_set_or(ld->our_features, take(feature_set_for_feature(NULL, - OPTIONAL_FEATURE(OPT_ANCHOR_OUTPUTS)))); + OPTIONAL_FEATURE(OPT_STATIC_REMOTEKEY)))); feature_set_or(ld->our_features, take(feature_set_for_feature(NULL, OPTIONAL_FEATURE(OPT_DUAL_FUND)))); diff --git a/tests/test_bookkeeper.py b/tests/test_bookkeeper.py index 1e0f24b73..d85fc3748 100644 --- a/tests/test_bookkeeper.py +++ b/tests/test_bookkeeper.py @@ -4,7 +4,8 @@ from pyln.client import Millisatoshi from db import Sqlite3Db from fixtures import TEST_NETWORK from utils import ( - sync_blockheight, wait_for, only_one, first_channel_id, TIMEOUT + sync_blockheight, wait_for, only_one, first_channel_id, TIMEOUT, + anchor_expected ) from pathlib import Path @@ -332,6 +333,7 @@ def test_bookkeeping_rbf_withdraw(node_factory, bitcoind): @pytest.mark.openchannel('v2') @unittest.skipIf(os.getenv('TEST_DB_PROVIDER', 'sqlite3') != 'sqlite3', "turns off bookkeeper at start") @unittest.skipIf(TEST_NETWORK != 'regtest', "network fees hardcoded") +@pytest.mark.developer("dev-force-features") def test_bookkeeping_missed_chans_leases(node_factory, bitcoind): """ Test that a lease is correctly recorded if bookkeeper was off @@ -342,6 +344,10 @@ def test_bookkeeping_missed_chans_leases(node_factory, bitcoind): 'lease-fee-base-sat': '100sat', 'lease-fee-basis': 100, 'plugin': str(coin_mvt_plugin), 'disable-plugin': 'bookkeeper'} + + if not anchor_expected(): + opts['dev-force-features'] = '+21' + l1, l2 = node_factory.get_nodes(2, opts=opts) open_amt = 500000 diff --git a/tests/test_closing.py b/tests/test_closing.py index 5cab7aa76..5224b3893 100644 --- a/tests/test_closing.py +++ b/tests/test_closing.py @@ -739,7 +739,7 @@ def test_penalty_outhtlc(node_factory, bitcoind, executor, chainparams): @unittest.skipIf(TEST_NETWORK != 'regtest', 'elementsd doesnt yet support PSBT features we need') @pytest.mark.openchannel('v2') @pytest.mark.slow_test -@pytest.mark.developer("requres 'dev-queryrates'") +@pytest.mark.developer("requres 'dev-queryrates', 'dev-force-features'") def test_channel_lease_falls_behind(node_factory, bitcoind): ''' If our peer falls too far behind/doesn't send us an update for @@ -749,6 +749,11 @@ def test_channel_lease_falls_behind(node_factory, bitcoind): 'lease-fee-base-sat': '100sat', 'lease-fee-basis': 100}, {'funder-policy': 'match', 'funder-policy-mod': 100, 'lease-fee-base-sat': '100sat', 'lease-fee-basis': 100}] + + if not anchor_expected(): + for opt in opts: + opt['dev-force-features'] = '+21' + l1, l2, = node_factory.get_nodes(2, opts=opts) amount = 500000 feerate = 2000 @@ -779,7 +784,7 @@ def test_channel_lease_falls_behind(node_factory, bitcoind): @unittest.skipIf(TEST_NETWORK != 'regtest', 'elementsd doesnt yet support PSBT features we need') @pytest.mark.openchannel('v2') -@pytest.mark.developer("requres 'dev-queryrates'") +@pytest.mark.developer("requres 'dev-queryrates', 'dev-force-features'") @pytest.mark.slow_test def test_channel_lease_post_expiry(node_factory, bitcoind, chainparams): @@ -789,6 +794,9 @@ def test_channel_lease_post_expiry(node_factory, bitcoind, chainparams): 'may_reconnect': True, 'plugin': coin_mvt_plugin, 'dev-no-reconnect': None} + if not anchor_expected(): + opts['dev-force-features'] = '+21' + l1, l2, = node_factory.get_nodes(2, opts=opts) feerate = 2000 @@ -893,7 +901,7 @@ def test_channel_lease_post_expiry(node_factory, bitcoind, chainparams): @unittest.skipIf(TEST_NETWORK != 'regtest', 'elementsd doesnt yet support PSBT features we need') @pytest.mark.openchannel('v2') @pytest.mark.slow_test -@pytest.mark.developer("requres 'dev-queryrates'") +@pytest.mark.developer("requres 'dev-queryrates', 'dev-force-features'") def test_channel_lease_unilat_closes(node_factory, bitcoind): ''' Check that channel leases work @@ -905,6 +913,9 @@ def test_channel_lease_unilat_closes(node_factory, bitcoind): 'lease-fee-base-sat': '100sat', 'lease-fee-basis': 100, 'funder-lease-requests-only': False} + if not anchor_expected(): + opts['dev-force-features'] = '+21' + l1, l2, l3 = node_factory.get_nodes(3, opts=opts) # Allow l2 some warnings l2.allow_warning = True @@ -1005,7 +1016,7 @@ def test_channel_lease_unilat_closes(node_factory, bitcoind): @unittest.skipIf(TEST_NETWORK != 'regtest', 'elementsd doesnt yet support PSBT features we need') @pytest.mark.openchannel('v2') @unittest.skipIf(os.getenv('TEST_DB_PROVIDER', 'sqlite3') != 'sqlite3', "Makes use of the sqlite3 db") -@pytest.mark.developer("requres 'dev-queryrates'") +@pytest.mark.developer("requres 'dev-queryrates', 'dev-force-features'") def test_channel_lease_lessor_cheat(node_factory, bitcoind, chainparams): ''' Check that lessee can recover funds if lessor cheats @@ -1019,6 +1030,11 @@ def test_channel_lease_lessor_cheat(node_factory, bitcoind, chainparams): 'lease-fee-base-sat': '100sat', 'lease-fee-basis': 100, 'may_reconnect': True, 'allow_broken_log': True, 'plugin': balance_snaps}] + + if not anchor_expected(): + for opt in opts: + opt['dev-force-features'] = '+21' + l1, l2, = node_factory.get_nodes(2, opts=opts) amount = 500000 feerate = 2000 @@ -1081,7 +1097,7 @@ def test_channel_lease_lessor_cheat(node_factory, bitcoind, chainparams): @unittest.skipIf(TEST_NETWORK != 'regtest', 'elementsd doesnt yet support PSBT features we need') @pytest.mark.openchannel('v2') @unittest.skipIf(os.getenv('TEST_DB_PROVIDER', 'sqlite3') != 'sqlite3', "Makes use of the sqlite3 db") -@pytest.mark.developer("requres 'dev-queryrates', dev-no-reconnect") +@pytest.mark.developer("requres 'dev-queryrates', dev-no-reconnect, dev-force-features") def test_channel_lease_lessee_cheat(node_factory, bitcoind, chainparams): ''' Check that lessor can recover funds if lessee cheats @@ -1093,6 +1109,11 @@ def test_channel_lease_lessee_cheat(node_factory, bitcoind, chainparams): {'funder-policy': 'match', 'funder-policy-mod': 100, 'lease-fee-base-sat': '100sat', 'lease-fee-basis': 100, 'may_reconnect': True, 'dev-no-reconnect': None}] + + if not anchor_expected(): + for opt in opts: + opt['dev-force-features'] = '+21' + l1, l2, = node_factory.get_nodes(2, opts=opts) amount = 500000 feerate = 2000 diff --git a/tests/test_connection.py b/tests/test_connection.py index 614a8b91b..44b8e43fa 100644 --- a/tests/test_connection.py +++ b/tests/test_connection.py @@ -2668,12 +2668,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}) - if l1.config('experimental-dual-fund'): - lfeatures = expected_peer_features(extra=[21, 29]) - nfeatures = expected_node_features(extra=[21, 29]) - else: - lfeatures = expected_peer_features() - nfeatures = expected_node_features() + lfeatures = expected_peer_features() + nfeatures = expected_node_features() # Gossiping but no node announcement yet assert l1.rpc.getpeer(l2.info['id'])['connected'] @@ -3469,10 +3465,6 @@ def test_wumbo_channels(node_factory, bitcoind): conn = l1.rpc.connect(l2.info['id'], 'localhost', port=l2.port) expected_features = expected_peer_features(wumbo_channels=True) - if l1.config('experimental-dual-fund'): - expected_features = expected_peer_features(wumbo_channels=True, - extra=[21, 29]) - assert conn['features'] == expected_features assert only_one(l1.rpc.listpeers(l2.info['id'])['peers'])['features'] == expected_features @@ -3557,7 +3549,7 @@ def test_channel_features(node_factory, bitcoind): # We should see features in unconfirmed channels. chan = only_one(l1.rpc.listpeerchannels()['channels']) assert 'option_static_remotekey' in chan['features'] - if EXPERIMENTAL_FEATURES or l1.config('experimental-dual-fund'): + if EXPERIMENTAL_FEATURES: assert 'option_anchor_outputs' in chan['features'] # l2 should agree. @@ -3570,7 +3562,7 @@ def test_channel_features(node_factory, bitcoind): chan = only_one(l1.rpc.listpeerchannels()['channels']) assert 'option_static_remotekey' in chan['features'] - if EXPERIMENTAL_FEATURES or l1.config('experimental-dual-fund'): + if EXPERIMENTAL_FEATURES: assert 'option_anchor_outputs' in chan['features'] # l2 should agree. diff --git a/tests/test_gossip.py b/tests/test_gossip.py index c7acc4481..c5ee3dcd3 100644 --- a/tests/test_gossip.py +++ b/tests/test_gossip.py @@ -1307,12 +1307,8 @@ def test_node_reannounce(node_factory, bitcoind, chainparams): 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_node_features() - if l1.config('experimental-dual-fund'): - lfeatures = expected_node_features(extra=[21, 29]) - # Make sure it gets features correct. - assert only_one(l2.rpc.listnodes(l1.info['id'])['nodes'])['features'] == lfeatures + assert only_one(l2.rpc.listnodes(l1.info['id'])['nodes'])['features'] == expected_node_features() l1.stop() l1.daemon.opts['alias'] = 'SENIORBEAM' diff --git a/tests/test_opening.py b/tests/test_opening.py index d1a1b23eb..52d479f23 100644 --- a/tests/test_opening.py +++ b/tests/test_opening.py @@ -2,7 +2,7 @@ from fixtures import * # noqa: F401,F403 from fixtures import TEST_NETWORK from pyln.client import RpcError, Millisatoshi from utils import ( - only_one, wait_for, sync_blockheight, first_channel_id, calc_lease_fee, check_coin_moves + only_one, wait_for, sync_blockheight, first_channel_id, calc_lease_fee, check_coin_moves, anchor_expected ) from pathlib import Path @@ -19,9 +19,15 @@ def find_next_feerate(node, peer): @unittest.skipIf(TEST_NETWORK != 'regtest', 'elementsd doesnt yet support PSBT features we need') @pytest.mark.openchannel('v2') -@pytest.mark.developer("requres 'dev-queryrates'") +@pytest.mark.developer("requres 'dev-queryrates' + 'dev-force-features'") def test_queryrates(node_factory, bitcoind): - l1, l2 = node_factory.get_nodes(2, opts={'dev-no-reconnect': None}) + + opts = {'dev-no-reconnect': None} + + if not anchor_expected(): + opts['dev-force-features'] = '+21' + + l1, l2 = node_factory.get_nodes(2, opts=opts) amount = 10 ** 6 @@ -340,11 +346,16 @@ def test_v2_rbf_single(node_factory, bitcoind, chainparams): @unittest.skipIf(TEST_NETWORK != 'regtest', 'elementsd doesnt yet support PSBT features we need') @pytest.mark.openchannel('v2') +@pytest.mark.developer("requres 'dev-force-features'") def test_v2_rbf_liquidity_ad(node_factory, bitcoind, chainparams): opts = {'funder-policy': 'match', 'funder-policy-mod': 100, 'lease-fee-base-sat': '100sat', 'lease-fee-basis': 100, 'may_reconnect': True} + + if not anchor_expected(): + opts['dev-force-features'] = '+21' + l1, l2 = node_factory.get_nodes(2, opts=opts) # what happens when we RBF? @@ -1216,21 +1227,23 @@ def test_funder_contribution_limits(node_factory, bitcoind): @pytest.mark.openchannel('v2') -@pytest.mark.developer("requres 'dev-disconnect'") +@pytest.mark.developer("requres 'dev-disconnect', 'dev-force-features'") def test_inflight_dbload(node_factory, bitcoind): """Bad db field access breaks Postgresql on startup with opening leases""" disconnects = ["@WIRE_COMMITMENT_SIGNED"] - l1, l2 = node_factory.get_nodes(2, opts=[{'experimental-dual-fund': None, - 'dev-no-reconnect': None, - 'may_reconnect': True, - 'disconnect': disconnects}, - {'experimental-dual-fund': None, - 'dev-no-reconnect': None, - 'may_reconnect': True, - 'funder-policy': 'match', - 'funder-policy-mod': 100, - 'lease-fee-base-sat': '100sat', - 'lease-fee-basis': 100}]) + + opts = [{'experimental-dual-fund': None, 'dev-no-reconnect': None, + 'may_reconnect': True, 'disconnect': disconnects}, + {'experimental-dual-fund': None, 'dev-no-reconnect': None, + 'may_reconnect': True, 'funder-policy': 'match', + 'funder-policy-mod': 100, 'lease-fee-base-sat': '100sat', + 'lease-fee-basis': 100}] + + if not anchor_expected(): + for opt in opts: + opt['dev-force-features'] = '+21' + + l1, l2 = node_factory.get_nodes(2, opts=opts) feerate = 2000 amount = 500000 @@ -1528,6 +1541,7 @@ def test_buy_liquidity_ad_no_v2(node_factory, bitcoind): @pytest.mark.openchannel('v2') +@pytest.mark.developer("dev-force-features required") def test_v2_replay_bookkeeping(node_factory, bitcoind): """ Test that your bookkeeping for a liquidity ad is good even if we replay the opening and locking tx! @@ -1539,6 +1553,11 @@ def test_v2_replay_bookkeeping(node_factory, bitcoind): {'funder-policy': 'match', 'funder-policy-mod': 100, 'lease-fee-base-sat': '100sat', 'lease-fee-basis': 100, 'may_reconnect': True}] + + if not anchor_expected(): + for opt in opts: + opt['dev-force-features'] = '+21' + l1, l2, = node_factory.get_nodes(2, opts=opts) amount = 500000 feerate = 2000 @@ -1591,6 +1610,7 @@ def test_v2_replay_bookkeeping(node_factory, bitcoind): @pytest.mark.openchannel('v2') +@pytest.mark.developer("dev-force-features required") def test_buy_liquidity_ad_check_bookkeeping(node_factory, bitcoind): """ Test that your bookkeeping for a liquidity ad is good.""" @@ -1601,6 +1621,11 @@ def test_buy_liquidity_ad_check_bookkeeping(node_factory, bitcoind): {'funder-policy': 'match', 'funder-policy-mod': 100, 'lease-fee-base-sat': '100sat', 'lease-fee-basis': 100, 'may_reconnect': True}] + + if not anchor_expected(): + for opt in opts: + opt['dev-force-features'] = '+21' + l1, l2, = node_factory.get_nodes(2, opts=opts) amount = 500000 feerate = 2000 diff --git a/tests/test_plugin.py b/tests/test_plugin.py index 6c1585ce3..4fdfcb547 100644 --- a/tests/test_plugin.py +++ b/tests/test_plugin.py @@ -1606,15 +1606,10 @@ def test_plugin_feature_announce(node_factory): wait_for_announce=True ) - extra = [] - if l1.config('experimental-dual-fund'): - extra.append(21) # option-anchor-outputs - extra.append(29) # option-dual-fund - # Check the featurebits we've set in the `init` message from # feature-test.py. assert l1.daemon.is_in_log(r'\[OUT\] 001000022100....{}' - .format(expected_peer_features(extra=[201] + extra))) + .format(expected_peer_features(extra=[201]))) # Check the invoice featurebit we set in feature-test.py inv = l1.rpc.invoice(123, 'lbl', 'desc')['bolt11'] @@ -1623,7 +1618,7 @@ def test_plugin_feature_announce(node_factory): # Check the featurebit set in the `node_announcement` node = l1.rpc.listnodes(l1.info['id'])['nodes'][0] - assert node['features'] == expected_node_features(extra=[203] + extra) + assert node['features'] == expected_node_features(extra=[203]) def test_hook_chaining(node_factory): diff --git a/tests/utils.py b/tests/utils.py index cf443041b..6c8783d9b 100644 --- a/tests/utils.py +++ b/tests/utils.py @@ -48,8 +48,6 @@ def expected_peer_features(wumbo_channels=False, extra=[]): if wumbo_channels: features += [19] if EXPERIMENTAL_DUAL_FUND: - # option_anchor_outputs - features += [21] # option_dual_fund features += [29] return hex_bits(features + extra) @@ -70,8 +68,6 @@ def expected_node_features(wumbo_channels=False, extra=[]): if wumbo_channels: features += [19] if EXPERIMENTAL_DUAL_FUND: - # option_anchor_outputs - features += [21] # option_dual_fund features += [29] return hex_bits(features + extra)