channeld: allow stfu based on peer features, not EXPERIMENTAL_FEATURES.

Changelog-EXPERIMENTAL: Config: `--experimental-quiesce` enables queiescence, for testing.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
This commit is contained in:
Rusty Russell 2023-05-22 10:21:44 +09:30
parent e51460be28
commit 6c23349c72
17 changed files with 45 additions and 55 deletions

View file

@ -139,7 +139,6 @@ struct peer {
/* If master told us to send wrong_funding */
struct bitcoin_outpoint *shutdown_wrong_funding;
#if EXPERIMENTAL_FEATURES
/* Do we want quiescence? */
bool stfu;
/* Which side is considered the initiator? */
@ -148,7 +147,6 @@ struct peer {
bool stfu_sent[NUM_SIDES];
/* Updates master asked, which we've deferred while quiescing */
struct msg_queue *update_queue;
#endif
#if DEVELOPER
/* If set, don't fire commit counter when this hits 0 */
@ -227,7 +225,6 @@ const u8 *hsm_req(const tal_t *ctx, const u8 *req TAKES)
return msg;
}
#if EXPERIMENTAL_FEATURES
static void maybe_send_stfu(struct peer *peer)
{
if (!peer->stfu)
@ -252,6 +249,12 @@ static void handle_stfu(struct peer *peer, const u8 *stfu)
struct channel_id channel_id;
u8 remote_initiated;
if (!feature_negotiated(peer->our_features,
peer->their_features,
OPT_QUIESCE))
peer_failed_warn(peer->pps, &peer->channel_id,
"stfu not supported");
if (!fromwire_stfu(stfu, &channel_id, &remote_initiated))
peer_failed_warn(peer->pps, &peer->channel_id,
"Bad stfu %s", tal_hex(peer, stfu));
@ -312,6 +315,7 @@ static bool handle_master_request_later(struct peer *peer, const u8 *msg)
return false;
}
#if EXPERIMENTAL_FEATURES
/* Compare, with false if either is NULL */
static bool match_type(const u8 *t1, const u8 *t2)
{
@ -341,16 +345,7 @@ static void set_channel_type(struct channel *channel, const u8 *type)
wire_sync_write(MASTER_FD,
take(towire_channeld_upgraded(NULL, channel->type)));
}
#else /* !EXPERIMENTAL_FEATURES */
static bool handle_master_request_later(struct peer *peer, const u8 *msg)
{
return false;
}
static void maybe_send_stfu(struct peer *peer)
{
}
#endif
#endif /* EXPERIMENTAL_FEATURES */
/* Tell gossipd to create channel_update (then it goes into
* gossip_store, then streams out to peers, or sends it directly if
@ -1144,11 +1139,10 @@ static bool want_fee_update(const struct peer *peer, u32 *target)
if (peer->channel->opener != LOCAL)
return false;
#if EXPERIMENTAL_FEATURES
/* No fee update while quiescing! */
if (peer->stfu)
return false;
#endif
current = channel_feerate(peer->channel, REMOTE);
/* max is *approximate*: only take it into account if we're
@ -1184,11 +1178,10 @@ static bool want_blockheight_update(const struct peer *peer, u32 *height)
if (peer->channel->lease_expiry == 0)
return false;
#if EXPERIMENTAL_FEATURES
/* No fee update while quiescing! */
if (peer->stfu)
return false;
#endif
/* What's the current blockheight */
last = get_blockheight(peer->channel->blockheight_states,
peer->channel->opener, LOCAL);
@ -2245,12 +2238,9 @@ static void peer_in(struct peer *peer, const u8 *msg)
case WIRE_SHUTDOWN:
handle_peer_shutdown(peer, msg);
return;
#if EXPERIMENTAL_FEATURES
case WIRE_STFU:
handle_stfu(peer, msg);
return;
#endif
case WIRE_INIT:
case WIRE_OPEN_CHANNEL:
case WIRE_ACCEPT_CHANNEL:
@ -3636,7 +3626,6 @@ static void handle_dev_memleak(struct peer *peer, const u8 *msg)
found_leak)));
}
#if EXPERIMENTAL_FEATURES
static void handle_dev_quiesce(struct peer *peer, const u8 *msg)
{
if (!fromwire_channeld_dev_quiesce(msg))
@ -3650,7 +3639,6 @@ static void handle_dev_quiesce(struct peer *peer, const u8 *msg)
peer->stfu_initiator = LOCAL;
maybe_send_stfu(peer);
}
#endif /* EXPERIMENTAL_FEATURES */
#endif /* DEVELOPER */
static void req_in(struct peer *peer, const u8 *msg)
@ -3708,10 +3696,8 @@ static void req_in(struct peer *peer, const u8 *msg)
handle_dev_memleak(peer, msg);
return;
case WIRE_CHANNELD_DEV_QUIESCE:
#if EXPERIMENTAL_FEATURES
handle_dev_quiesce(peer, msg);
return;
#endif /* EXPERIMENTAL_FEATURES */
#else
case WIRE_CHANNELD_DEV_REENABLE_COMMIT:
case WIRE_CHANNELD_DEV_MEMLEAK:
@ -3980,11 +3966,9 @@ int main(int argc, char *argv[])
peer->shutdown_wrong_funding = NULL;
peer->last_update_timestamp = 0;
peer->last_empty_commitment = 0;
#if EXPERIMENTAL_FEATURES
peer->stfu = false;
peer->stfu_sent[LOCAL] = peer->stfu_sent[REMOTE] = false;
peer->update_queue = msg_queue_new(peer, false);
#endif
/* We send these to HSM to get real signatures; don't have valgrind
* complain. */

View file

@ -196,9 +196,7 @@ static u8 *read_next_msg(const tal_t *ctx,
case WIRE_PING:
case WIRE_PONG:
case WIRE_SHUTDOWN:
#if EXPERIMENTAL_FEATURES
case WIRE_STFU:
#endif
*error = tal_fmt(ctx,
"Received invalid message from peer: %d", t);
return NULL;
@ -715,10 +713,10 @@ char *process_interactivetx_updates(const tal_t *ctx,
case WIRE_REPLY_SHORT_CHANNEL_IDS_END:
case WIRE_PING:
case WIRE_PONG:
case WIRE_STFU:
#if EXPERIMENTAL_FEATURES
case WIRE_SPLICE:
case WIRE_SPLICE_ACK:
case WIRE_STFU:
#endif
return tal_fmt(ctx, "Unexpected wire message %s",
tal_hex(ctx, msg));

View file

@ -91,9 +91,7 @@ static bool is_msg_gossip_broadcast(const u8 *cursor)
case WIRE_YOUR_PEER_STORAGE:
case WIRE_OPEN_CHANNEL2:
case WIRE_ACCEPT_CHANNEL2:
#if EXPERIMENTAL_FEATURES
case WIRE_STFU:
#endif
break;
}
return false;

View file

@ -94,9 +94,7 @@ static bool public_msg_type(enum peer_wire type)
case WIRE_ONION_MESSAGE:
case WIRE_PEER_STORAGE:
case WIRE_YOUR_PEER_STORAGE:
#if EXPERIMENTAL_FEATURES
case WIRE_STFU:
#endif
return false;
case WIRE_CHANNEL_ANNOUNCEMENT:
case WIRE_NODE_ANNOUNCEMENT:

View file

@ -389,9 +389,7 @@ static bool is_urgent(enum peer_wire type)
case WIRE_ONION_MESSAGE:
case WIRE_PEER_STORAGE:
case WIRE_YOUR_PEER_STORAGE:
#if EXPERIMENTAL_FEATURES
case WIRE_STFU:
#endif
return false;
/* These are time-sensitive, and so send without delay. */

View file

@ -63,6 +63,7 @@ On success, an object is returned, containing:
- **experimental-shutdown-wrong-funding** (boolean, optional): `experimental-shutdown-wrong-funding` field from config or cmdline, or default
- **experimental-websocket-port** (u16, optional): `experimental-websocket-port` field from config or cmdline, or default
- **experimental-peer-storage** (boolean, optional): `experimental-peer-storage` field from config or cmdline, or default *(added v23.02)*
- **experimental-quiesce** (boolean, optional): `experimental-quiesce` field from config or cmdline, or default *(added v23.08)*
- **database-upgrade** (boolean, optional): `database-upgrade` field from config or cmdline
- **rgb** (hex, optional): `rgb` field from config or cmdline, or default (always 6 characters)
- **alias** (string, optional): `alias` field from config or cmdline, or default
@ -224,4 +225,4 @@ RESOURCES
Main web site: <https://github.com/ElementsProject/lightning>
[comment]: # ( SHA256STAMP:b24158a61bb79aaf3f0f6d1c20a4b10d474613b371e80aede4aeb59ab471a989)
[comment]: # ( SHA256STAMP:62e8c380f4fa7b063c145ad43428c4ce48cb142cab61da72a26c2961375fabab)

View file

@ -720,6 +720,11 @@ frames once the connection is upgraded.
data for our peers, and give them our (encrypted!) backup data to
store as well, based on a protocol similar to [bolt][bolt] #881.
* **experimental-quiesce**
Specifying this option advertizes `option_quiesce`. Not very useful
by itself, except for testing.
BUGS
----

View file

@ -142,6 +142,11 @@
"added": "v23.02",
"description": "`experimental-peer-storage` field from config or cmdline, or default"
},
"experimental-quiesce": {
"type": "boolean",
"added": "v23.08",
"description": "`experimental-quiesce` field from config or cmdline, or default"
},
"database-upgrade": {
"type": "boolean",
"description": "`database-upgrade` field from config or cmdline"

View file

@ -628,9 +628,7 @@ static void handle_recv_gossip(struct daemon *daemon, const u8 *outermsg)
case WIRE_ONION_MESSAGE:
case WIRE_PEER_STORAGE:
case WIRE_YOUR_PEER_STORAGE:
#if EXPERIMENTAL_FEATURES
case WIRE_STFU:
#endif
break;
}

View file

@ -1164,7 +1164,6 @@ static const struct json_command dev_feerate_command = {
};
AUTODATA(json_command, &dev_feerate_command);
#if EXPERIMENTAL_FEATURES
static void quiesce_reply(struct subd *channeld UNUSED,
const u8 *reply,
const int *fds UNUSED,
@ -1196,6 +1195,7 @@ static struct command_result *json_dev_quiesce(struct command *cmd,
if (!peer)
return command_fail(cmd, LIGHTNINGD, "Peer not connected");
/* FIXME: If this becomes a real API, check for OPT_QUIESCE! */
channel = peer_any_active_channel(peer, &more_than_one);
if (!channel || !channel->owner || channel->state != CHANNELD_NORMAL)
return command_fail(cmd, LIGHTNINGD, "Peer bad state");
@ -1216,5 +1216,4 @@ static const struct json_command dev_quiesce_command = {
"Initiate quiscence protocol with peer"
};
AUTODATA(json_command, &dev_quiesce_command);
#endif /* EXPERIMENTAL_FEATURES */
#endif /* DEVELOPER */

View file

@ -861,7 +861,6 @@ static struct feature_set *default_features(const tal_t *ctx)
OPTIONAL_FEATURE(OPT_ROUTE_BLINDING),
#if EXPERIMENTAL_FEATURES
OPTIONAL_FEATURE(OPT_ANCHOR_OUTPUTS),
OPTIONAL_FEATURE(OPT_QUIESCE),
OPTIONAL_FEATURE(OPT_ONION_MESSAGES),
#endif
};

View file

@ -1101,6 +1101,14 @@ static char *opt_set_peer_storage(struct lightningd *ld)
return NULL;
}
static char *opt_set_quiesce(struct lightningd *ld)
{
feature_set_or(ld->our_features,
take(feature_set_for_feature(NULL,
OPTIONAL_FEATURE(OPT_QUIESCE))));
return NULL;
}
static char *opt_set_offers(struct lightningd *ld)
{
ld->config.exp_offers = true;
@ -1182,6 +1190,10 @@ static void register_opts(struct lightningd *ld)
opt_register_early_noarg("--experimental-peer-storage",
opt_set_peer_storage, ld,
"EXPERIMENTAL: enable peer backup storage and restore");
opt_register_early_noarg("--experimental-quiesce",
opt_set_quiesce, ld,
"experimental: Advertise ability to quiesce"
" channels.");
opt_register_early_arg("--announce-addr-dns",
opt_set_bool_arg, opt_show_bool,
&ld->announce_dns,
@ -1675,6 +1687,11 @@ static void add_config(struct lightningd *ld,
feature_offered(ld->our_features
->bits[INIT_FEATURE],
OPT_PROVIDE_PEER_BACKUP_STORAGE));
} else if (opt->cb == (void *)opt_set_quiesce) {
json_add_bool(response, name0,
feature_offered(ld->our_features
->bits[INIT_FEATURE],
OPT_QUIESCE));
} else if (opt->cb == (void *)plugin_opt_flag_set) {
/* Noop, they will get added below along with the
* OPT_HASARG options. */

View file

@ -1450,9 +1450,7 @@ static u8 *opening_negotiate_msg(const tal_t *ctx, struct state *state)
case WIRE_PONG:
case WIRE_PEER_STORAGE:
case WIRE_YOUR_PEER_STORAGE:
#if EXPERIMENTAL_FEATURES
case WIRE_STFU:
#endif
break;
}
@ -1826,9 +1824,7 @@ static bool run_tx_interactive(struct state *state,
case WIRE_PONG:
case WIRE_PEER_STORAGE:
case WIRE_YOUR_PEER_STORAGE:
#if EXPERIMENTAL_FEATURES
case WIRE_STFU:
#endif
open_abort(state, "Unexpected wire message %s",
tal_hex(tmpctx, msg));
return false;
@ -4196,9 +4192,7 @@ static u8 *handle_peer_in(struct state *state)
case WIRE_PONG:
case WIRE_PEER_STORAGE:
case WIRE_YOUR_PEER_STORAGE:
#if EXPERIMENTAL_FEATURES
case WIRE_STFU:
#endif
break;
}

View file

@ -3943,10 +3943,9 @@ def test_upgrade_statickey_fail(node_factory, executor, bitcoind):
assert 'option_static_remotekey' in only_one(l2.rpc.listpeerchannels()['channels'])['features']
@unittest.skipIf(not EXPERIMENTAL_FEATURES, "quiescence is experimental")
@pytest.mark.developer("quiescence triggering is dev only")
def test_quiescence(node_factory, executor):
l1, l2 = node_factory.line_graph(2)
l1, l2 = node_factory.line_graph(2, opts={'experimental-quiesce': None})
# Works fine.
l1.pay(l2, 1000)

View file

@ -49,9 +49,7 @@ static bool unknown_type(enum peer_wire t)
case WIRE_YOUR_PEER_STORAGE:
case WIRE_OPEN_CHANNEL2:
case WIRE_ACCEPT_CHANNEL2:
#if EXPERIMENTAL_FEATURES
case WIRE_STFU:
#endif
return false;
}
return true;
@ -105,9 +103,7 @@ bool is_msg_for_gossipd(const u8 *cursor)
case WIRE_ONION_MESSAGE:
case WIRE_PEER_STORAGE:
case WIRE_YOUR_PEER_STORAGE:
#if EXPERIMENTAL_FEATURES
case WIRE_STFU:
#endif
break;
}
return false;
@ -363,14 +359,12 @@ bool extract_channel_id(const u8 *in_pkt, struct channel_id *channel_id)
* 2. data:
* * [`channel_id`:`channel_id`]
*/
#if EXPERIMENTAL_FEATURES
case WIRE_STFU:
/* BOLT-quiescent #2:
* 1. type: 2 (`stfu`)
* 2. data:
* * [`channel_id`:`channel_id`]
*/
#endif
return fromwire_channel_id(&cursor, &max, channel_id);
}
return false;

View file

@ -203,6 +203,9 @@ subtypedata,lease_rates,lease_fee_basis,u16,
subtypedata,lease_rates,channel_fee_max_proportional_thousandths,u16,
subtypedata,lease_rates,lease_fee_base_sat,u32,
subtypedata,lease_rates,channel_fee_max_base_msat,tu32,
msgtype,stfu,2
msgdata,stfu,channel_id,channel_id,
msgdata,stfu,initiator,u8,
msgtype,shutdown,38
msgdata,shutdown,channel_id,channel_id,
msgdata,shutdown,len,u16,

1 msgtype,init,16
203 subtypedata,lease_rates,channel_fee_max_proportional_thousandths,u16,
204 subtypedata,lease_rates,lease_fee_base_sat,u32,
205 subtypedata,lease_rates,channel_fee_max_base_msat,tu32,
206 msgtype,stfu,2
207 msgdata,stfu,channel_id,channel_id,
208 msgdata,stfu,initiator,u8,
209 msgtype,shutdown,38
210 msgdata,shutdown,channel_id,channel_id,
211 msgdata,shutdown,len,u16,