mirror of
https://github.com/ElementsProject/lightning.git
synced 2025-02-22 14:42:40 +01:00
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:
parent
e51460be28
commit
6c23349c72
17 changed files with 45 additions and 55 deletions
|
@ -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. */
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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. */
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
----
|
||||
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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
|
||||
};
|
||||
|
|
|
@ -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. */
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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,
|
||||
|
|
|
Loading…
Add table
Reference in a new issue