lightningd: add dev-any-channel-type to allow obsolete channel types.

We're about to make static_remotekey compulsory, but we still want to
do tests for pre-existing channels.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
This commit is contained in:
Rusty Russell 2024-01-29 10:06:15 +10:30
parent 3c2a57598f
commit e531ff83b3
10 changed files with 68 additions and 14 deletions

View file

@ -3107,6 +3107,7 @@ static struct command_result *json_openchannel_init(struct command *cmd,
} }
if (ctype && if (ctype &&
!cmd->ld->dev_any_channel_type &&
!channel_type_accept(tmpctx, !channel_type_accept(tmpctx,
ctype->features, ctype->features,
cmd->ld->our_features)) { cmd->ld->our_features)) {
@ -4042,7 +4043,8 @@ bool peer_start_dualopend(struct peer *peer,
&channel->local_basepoints, &channel->local_basepoints,
&channel->local_funding_pubkey, &channel->local_funding_pubkey,
channel->minimum_depth, channel->minimum_depth,
peer->ld->config.require_confirmed_inputs); peer->ld->config.require_confirmed_inputs,
peer->ld->dev_any_channel_type);
subd_send_msg(channel->owner, take(msg)); subd_send_msg(channel->owner, take(msg));
return true; return true;
} }

View file

@ -144,6 +144,7 @@ static struct lightningd *new_lightningd(const tal_t *ctx)
ld->dev_ignore_modern_onion = false; ld->dev_ignore_modern_onion = false;
ld->dev_disable_commit = -1; ld->dev_disable_commit = -1;
ld->dev_no_ping_timer = false; ld->dev_no_ping_timer = false;
ld->dev_any_channel_type = false;
/*~ This is a CCAN list: an embedded double-linked list. It's not /*~ This is a CCAN list: an embedded double-linked list. It's not
* really typesafe, but relies on convention to access the contents. * really typesafe, but relies on convention to access the contents.

View file

@ -337,6 +337,9 @@ struct lightningd {
/* Tell channeld not to worry about pings. */ /* Tell channeld not to worry about pings. */
bool dev_no_ping_timer; bool dev_no_ping_timer;
/* Tell openingd/dualopend to accept all, allow sending any. */
bool dev_any_channel_type;
/* tor support */ /* tor support */
struct wireaddr *proxyaddr; struct wireaddr *proxyaddr;
bool always_use_proxy; bool always_use_proxy;

View file

@ -981,7 +981,8 @@ bool peer_start_openingd(struct peer *peer, struct peer_fd *peer_fd)
uc->minimum_depth, uc->minimum_depth,
minrate, maxrate, minrate, maxrate,
peer->ld->dev_force_tmp_channel_id, peer->ld->dev_force_tmp_channel_id,
peer->ld->config.allowdustreserve); peer->ld->config.allowdustreserve,
peer->ld->dev_any_channel_type);
subd_send_msg(uc->open_daemon, take(msg)); subd_send_msg(uc->open_daemon, take(msg));
return true; return true;
} }
@ -1171,6 +1172,7 @@ static struct command_result *json_fundchannel_start(struct command *cmd,
return command_param_failed(); return command_param_failed();
if (ctype && if (ctype &&
!cmd->ld->dev_any_channel_type &&
!channel_type_accept(tmpctx, !channel_type_accept(tmpctx,
ctype->features, ctype->features,
cmd->ld->our_features)) { cmd->ld->our_features)) {

View file

@ -903,6 +903,10 @@ static void dev_register_opts(struct lightningd *ld)
opt_set_bool_arg, opt_show_bool, opt_set_bool_arg, opt_show_bool,
&ld->config.allowdustreserve, &ld->config.allowdustreserve,
"If true, we allow the `fundchannel` RPC command and the `openchannel` plugin hook to set a reserve that is below the dust limit."); "If true, we allow the `fundchannel` RPC command and the `openchannel` plugin hook to set a reserve that is below the dust limit.");
clnopt_noarg("--dev-any-channel-type", OPT_DEV,
opt_set_bool,
&ld->dev_any_channel_type,
"Allow sending any channel type, and accept any");
} }
static const struct config testnet_config = { static const struct config testnet_config = {

View file

@ -226,6 +226,8 @@ struct state {
/* Does this negotation require confirmed inputs? */ /* Does this negotation require confirmed inputs? */
bool require_confirmed_inputs[NUM_SIDES]; bool require_confirmed_inputs[NUM_SIDES];
bool dev_accept_any_channel_type;
}; };
/* psbt_changeset_get_next - Get next message to send /* psbt_changeset_get_next - Get next message to send
@ -2424,11 +2426,18 @@ static void accepter_start(struct state *state, const u8 *oc2_msg)
open_tlv->channel_type, open_tlv->channel_type,
state->our_features); state->our_features);
if (!state->channel_type) { if (!state->channel_type) {
negotiation_failed(state, if (state->dev_accept_any_channel_type) {
"Did not support channel_type %s", status_unusual("dev-any-channel-type: accepting %s",
fmt_featurebits(tmpctx, fmt_featurebits(tmpctx,
open_tlv->channel_type)); open_tlv->channel_type));
return; state->channel_type = channel_type_from(state, open_tlv->channel_type);
} else {
negotiation_failed(state,
"Did not support channel_type %s",
fmt_featurebits(tmpctx,
open_tlv->channel_type));
return;
}
} }
} else } else
state->channel_type state->channel_type
@ -4372,7 +4381,8 @@ int main(int argc, char *argv[])
&state->our_points, &state->our_points,
&state->our_funding_pubkey, &state->our_funding_pubkey,
&state->minimum_depth, &state->minimum_depth,
&state->require_confirmed_inputs[LOCAL])) { &state->require_confirmed_inputs[LOCAL],
&state->dev_accept_any_channel_type)) {
/*~ Initially we're not associated with a channel, but /*~ Initially we're not associated with a channel, but
* handle_peer_gossip_or_error compares this. */ * handle_peer_gossip_or_error compares this. */
memset(&state->channel_id, 0, sizeof(state->channel_id)); memset(&state->channel_id, 0, sizeof(state->channel_id));

View file

@ -29,6 +29,7 @@ msgdata,dualopend_init,our_funding_pubkey,pubkey,
# Constraints in case the other end tries to open a channel. # Constraints in case the other end tries to open a channel.
msgdata,dualopend_init,minimum_depth,u32, msgdata,dualopend_init,minimum_depth,u32,
msgdata,dualopend_init,require_confirmed_inputs,bool, msgdata,dualopend_init,require_confirmed_inputs,bool,
msgdata,dualopend_init,dev_accept_any_channel_type,bool,
# master-dualopend: peer has reconnected # master-dualopend: peer has reconnected
msgtype,dualopend_reinit,7001 msgtype,dualopend_reinit,7001

Can't render this file because it has a wrong number of fields in line 16.

View file

@ -103,6 +103,8 @@ struct state {
struct amount_sat *reserve; struct amount_sat *reserve;
bool allowdustreserve; bool allowdustreserve;
bool dev_accept_any_channel_type;
}; };
/*~ If we can't agree on parameters, we fail to open the channel. /*~ If we can't agree on parameters, we fail to open the channel.
@ -965,11 +967,18 @@ static u8 *fundee_channel(struct state *state, const u8 *open_channel_msg)
state->channel_type = channel_type_accept( state->channel_type = channel_type_accept(
state, open_tlvs->channel_type, state->our_features); state, open_tlvs->channel_type, state->our_features);
if (!state->channel_type) { if (!state->channel_type) {
negotiation_failed(state, if (state->dev_accept_any_channel_type) {
"Did not support channel_type %s", status_unusual("dev-any-channel-type: accepting %s",
fmt_featurebits(tmpctx, fmt_featurebits(tmpctx,
open_tlvs->channel_type)); open_tlvs->channel_type));
return NULL; state->channel_type = channel_type_from(state, open_tlvs->channel_type);
} else {
negotiation_failed(state,
"Did not support channel_type %s",
fmt_featurebits(tmpctx,
open_tlvs->channel_type));
return NULL;
}
} }
} else { } else {
open_channel_had_channel_type = false; open_channel_had_channel_type = false;
@ -1548,7 +1557,8 @@ int main(int argc, char *argv[])
&state->minimum_depth, &state->minimum_depth,
&state->min_feerate, &state->max_feerate, &state->min_feerate, &state->max_feerate,
&state->dev_force_tmp_channel_id, &state->dev_force_tmp_channel_id,
&state->allowdustreserve)) &state->allowdustreserve,
&state->dev_accept_any_channel_type))
master_badmsg(WIRE_OPENINGD_INIT, msg); master_badmsg(WIRE_OPENINGD_INIT, msg);
/* 3 == peer, 4 = hsmd */ /* 3 == peer, 4 = hsmd */

View file

@ -28,6 +28,7 @@ msgdata,openingd_init,dev_temporary_channel_id,?byte,32
# reserves? This is explicitly required by the spec for safety # reserves? This is explicitly required by the spec for safety
# reasons, but some implementations and users keep asking for it. # reasons, but some implementations and users keep asking for it.
msgdata,openingd_init,allowdustreserve,bool, msgdata,openingd_init,allowdustreserve,bool,
msgdata,openingd_init,dev_accept_any_channel_type,bool,
# Openingd->master: they offered channel, should we continue? # Openingd->master: they offered channel, should we continue?
msgtype,openingd_got_offer,6005 msgtype,openingd_got_offer,6005

1 #include <bitcoin/chainparams.h>
28 # reasons, but some implementations and users keep asking for it.
29 msgdata,openingd_init,allowdustreserve,bool,
30 # Openingd->master: they offered channel, should we continue? msgdata,openingd_init,dev_accept_any_channel_type,bool,
31 # Openingd->master: they offered channel, should we continue?
32 msgtype,openingd_got_offer,6005
33 msgdata,openingd_got_offer,funding_satoshis,amount_sat,
34 msgdata,openingd_got_offer,push_msat,amount_msat,

View file

@ -2636,6 +2636,25 @@ def test_opening_explicit_channel_type(node_factory, bitcoind):
with pytest.raises(RpcError, match=r'channel_type not supported'): 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]) l1.rpc.openchannel_init(l3.info['id'], FUNDAMOUNT - 1000, psbt, channel_type=[STATIC_REMOTEKEY, ANCHORS_OLD])
# l1 will try, with dev-any-channel-type, l2 will reject.
l1.stop()
l1.daemon.opts['dev-any-channel-type'] = None
l1.start()
l1.connect(l2)
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
l2.start()
l1.connect(l2)
l1.rpc.fundchannel_start(l2.info['id'], FUNDAMOUNT, channel_type=[STATIC_REMOTEKEY, ANCHORS_OLD])
# FIXME: Check type is actually correct!
l1.rpc.fundchannel_cancel(l2.info['id'])
l1.rpc.unreserveinputs(psbt) l1.rpc.unreserveinputs(psbt)
# Works with fundchannel / multifundchannel # Works with fundchannel / multifundchannel
@ -2646,5 +2665,6 @@ def test_opening_explicit_channel_type(node_factory, bitcoind):
bitcoind.generate_block(1, wait_for_mempool=1) bitcoind.generate_block(1, wait_for_mempool=1)
wait_for(lambda: len(l1.rpc.listfunds()['outputs']) == 1) wait_for(lambda: len(l1.rpc.listfunds()['outputs']) == 1)
l1.connect(l3)
# FIXME: Check type is actually correct! # FIXME: Check type is actually correct!
l1.rpc.fundchannel(l3.info['id'], FUNDAMOUNT // 3, channel_type=[STATIC_REMOTEKEY]) l1.rpc.fundchannel(l3.info['id'], FUNDAMOUNT // 3, channel_type=[STATIC_REMOTEKEY])