Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Peer storage feature #5361

Merged
merged 21 commits into from
Feb 8, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
5e1e7c7
lightningd: fix leak report from peer_connected.
rustyrussell Feb 2, 2023
33d5b43
lightningd: don't access peer after free if it disconnects during pee…
rustyrussell Feb 3, 2023
61045b2
lightningd: allow sendcustommsg even if plugins are still processing …
rustyrussell Feb 2, 2023
7908e51
wire: Add patch file for peer storage bkp
adi2011 Feb 2, 2023
156bdc4
feature(PEER_STORAGE and YOUR_PEER_STORAGE) added in feature.c and in…
adi2011 Feb 2, 2023
3126cca
peer_wire_is_internal helper.
adi2011 Feb 2, 2023
234c0a3
connectd: make exception for peer storage msgs.
adi2011 Feb 2, 2023
228f547
plugins/chanbackup: PLUGIN_RESTARTABLE to PLUGIN_STATIC...
adi2011 Feb 2, 2023
cb5309c
Plugins/chanbackup: Add featurebit Peerstrg and YourPeerStrg.
adi2011 Feb 2, 2023
3a391d6
plugins/chanbackup: Define FILENAME globally (Good Manners)
adi2011 Feb 2, 2023
65496fd
plugins/chanbackup: use grab_file.
adi2011 Feb 2, 2023
53b427c
Plugins/chanbackup: Add SCB on CHANNELD_AWAITING_LOCKING stage
adi2011 Feb 2, 2023
6f8a800
Plugins/chanbackup: Add hook for receiving custommsg
adi2011 Feb 2, 2023
837e9e1
Plugins/chanbackup: Add hook for exchanging msgs on connect with a peer
adi2011 Feb 2, 2023
8140b4a
Plugins/chanbackup: Add RPC for recovering from the latestscb receive…
adi2011 Feb 2, 2023
3be74fd
tests/test_misc.py: Add test_restorefrompeer.
adi2011 Feb 2, 2023
b372392
plugins/chanbackup: switch to normal indentation.
rustyrussell Feb 2, 2023
21351e2
features: make name of peer storage features match spec.
rustyrussell Feb 4, 2023
349828d
plugins/chanbackup: neaten a little.
rustyrussell Feb 4, 2023
6c8ba17
plugins/chanbackup: make get_file_data take ctx.
rustyrussell Feb 4, 2023
081a1d8
options: create enable/disable option for peer storage.
rustyrussell Feb 5, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions channeld/channeld.c
Original file line number Diff line number Diff line change
Expand Up @@ -2300,6 +2300,8 @@ static void peer_in(struct peer *peer, const u8 *msg)
case WIRE_WARNING:
case WIRE_ERROR:
case WIRE_ONION_MESSAGE:
case WIRE_PEER_STORAGE:
case WIRE_YOUR_PEER_STORAGE:
abort();
}

Expand Down
10 changes: 8 additions & 2 deletions common/features.c
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,12 @@ static const struct feature_style feature_styles[] = {
[NODE_ANNOUNCE_FEATURE] = FEATURE_REPRESENT,
[BOLT11_FEATURE] = FEATURE_DONT_REPRESENT,
[CHANNEL_FEATURE] = FEATURE_DONT_REPRESENT } },
{ OPT_WANT_PEER_BACKUP_STORAGE,
.copy_style = { [INIT_FEATURE] = FEATURE_REPRESENT,
[NODE_ANNOUNCE_FEATURE] = FEATURE_REPRESENT } },
{ OPT_PROVIDE_PEER_BACKUP_STORAGE,
.copy_style = { [INIT_FEATURE] = FEATURE_REPRESENT,
[NODE_ANNOUNCE_FEATURE] = FEATURE_REPRESENT } },
};

struct dependency {
Expand Down Expand Up @@ -456,8 +462,8 @@ const char *feature_name(const tal_t *ctx, size_t f)
"option_quiesce", /* https://github.com/lightning/bolts/pull/869 */
NULL,
"option_onion_messages", /* https://github.com/lightning/bolts/pull/759 */
"option_want_peer_backup", /* 40/41 */ /* https://github.com/lightning/bolts/pull/881 */
"option_provide_peer_backup", /* https://github.com/lightning/bolts/pull/881 */
"option_want_peer_backup_storage", /* 40/41 */ /* https://github.com/lightning/bolts/pull/881/files */
"option_provide_peer_backup_storage", /* https://github.com/lightning/bolts/pull/881/files */
"option_channel_type",
"option_scid_alias", /* https://github.com/lightning/bolts/pull/910 */
"option_payment_metadata",
Expand Down
9 changes: 8 additions & 1 deletion common/features.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ enum feature_place {
BOLT12_INVOICE_FEATURE,
};
#define NUM_FEATURE_PLACE (BOLT12_INVOICE_FEATURE+1)

extern const char *feature_place_names[NUM_FEATURE_PLACE];

/* The complete set of features for all contexts */
Expand Down Expand Up @@ -165,4 +164,12 @@ struct feature_set *feature_set_dup(const tal_t *ctx,

#define OPT_SHUTDOWN_WRONG_FUNDING 104

/* BOLT-peer-storage #9:
*
* | 40/41 | `want_peer_backup_storage` | Want to use other nodes to store encrypted backup data | IN ...
* | 42/43 | `provide_peer_backup_storage` | Can store other nodes' encrypted backup data | IN ...
*/
#define OPT_WANT_PEER_BACKUP_STORAGE 40
#define OPT_PROVIDE_PEER_BACKUP_STORAGE 42

#endif /* LIGHTNING_COMMON_FEATURES_H */
2 changes: 2 additions & 0 deletions connectd/gossip_rcvd_filter.c
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,8 @@ static bool is_msg_gossip_broadcast(const u8 *cursor)
case WIRE_TX_INIT_RBF:
case WIRE_TX_ACK_RBF:
case WIRE_TX_ABORT:
case WIRE_PEER_STORAGE:
case WIRE_YOUR_PEER_STORAGE:
case WIRE_OPEN_CHANNEL2:
case WIRE_ACCEPT_CHANNEL2:
#if EXPERIMENTAL_FEATURES
Expand Down
2 changes: 2 additions & 0 deletions connectd/gossip_store.c
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,8 @@ static bool public_msg_type(enum peer_wire type)
case WIRE_REPLY_CHANNEL_RANGE:
case WIRE_GOSSIP_TIMESTAMP_FILTER:
case WIRE_ONION_MESSAGE:
case WIRE_PEER_STORAGE:
case WIRE_YOUR_PEER_STORAGE:
#if EXPERIMENTAL_FEATURES
case WIRE_STFU:
#endif
Expand Down
4 changes: 3 additions & 1 deletion connectd/multiplex.c
Original file line number Diff line number Diff line change
Expand Up @@ -385,6 +385,8 @@ static bool is_urgent(enum peer_wire type)
case WIRE_REPLY_CHANNEL_RANGE:
case WIRE_GOSSIP_TIMESTAMP_FILTER:
case WIRE_ONION_MESSAGE:
case WIRE_PEER_STORAGE:
case WIRE_YOUR_PEER_STORAGE:
#if EXPERIMENTAL_FEATURES
case WIRE_STFU:
#endif
Expand Down Expand Up @@ -721,7 +723,7 @@ static bool handle_custommsg(struct daemon *daemon,
const u8 *msg)
{
enum peer_wire type = fromwire_peektype(msg);
if (type % 2 == 1 && !peer_wire_is_defined(type)) {
if (type % 2 == 1 && !peer_wire_is_internal(type)) {
/* The message is not part of the messages we know how to
* handle. Assuming this is a custommsg, we just forward it to the
* master. */
Expand Down
3 changes: 2 additions & 1 deletion doc/lightning-listconfigs.7.md
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ On success, an object is returned, containing:
- **experimental-offers** (boolean, optional): `experimental-offers` field from config or cmdline, or default
- **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)*
- **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
Expand Down Expand Up @@ -223,4 +224,4 @@ RESOURCES

Main web site: <https://github.com/ElementsProject/lightning>

[comment]: # ( SHA256STAMP:581225b26efd84bfa99dc98e7a91e6fae11ef0b11939031d3da07f751f6d8f87)
[comment]: # ( SHA256STAMP:1088401b9aeae1e079dab550d3b035ef82195f0466ad471bc7373386182f37dc)
6 changes: 6 additions & 0 deletions doc/lightningd-config.5.md
Original file line number Diff line number Diff line change
Expand Up @@ -714,6 +714,12 @@ connections on that port, on any IPv4 and IPv6 addresses you listen
to ([bolt][bolt] #891). The normal protocol is expected to be sent over WebSocket binary
frames once the connection is upgraded.

* **experimental-peer-storage**

Specifying this option means we will store up to 64k of encrypted
data for our peers, and give them our (encrypted!) backup data to
store as well, based on a protocol similar to [bolt][bolt] #881.

BUGS
----

Expand Down
5 changes: 5 additions & 0 deletions doc/schemas/listconfigs.schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,11 @@
"type": "u16",
"description": "`experimental-websocket-port` field from config or cmdline, or default"
},
"experimental-peer-storage": {
"type": "boolean",
"added": "v23.02",
"description": "`experimental-peer-storage` field from config or cmdline, or default"
},
"database-upgrade": {
"type": "boolean",
"description": "`database-upgrade` field from config or cmdline"
Expand Down
2 changes: 2 additions & 0 deletions gossipd/gossipd.c
Original file line number Diff line number Diff line change
Expand Up @@ -569,6 +569,8 @@ static void handle_recv_gossip(struct daemon *daemon, const u8 *outermsg)
case WIRE_OPEN_CHANNEL2:
case WIRE_ACCEPT_CHANNEL2:
case WIRE_ONION_MESSAGE:
case WIRE_PEER_STORAGE:
case WIRE_YOUR_PEER_STORAGE:
#if EXPERIMENTAL_FEATURES
case WIRE_STFU:
#endif
Expand Down
12 changes: 7 additions & 5 deletions lightningd/connect_control.c
Original file line number Diff line number Diff line change
Expand Up @@ -752,7 +752,9 @@ static struct command_result *json_sendcustommsg(struct command *cmd,
return command_param_failed();

type = fromwire_peektype(msg);
if (peer_wire_is_defined(type)) {

/* Allow peer_storage and your_peer_storage msgtypes */
if (peer_wire_is_internal(type)) {
return command_fail(
cmd, JSONRPC2_INVALID_REQUEST,
"Cannot send messages of type %d (%s). It is not possible "
Expand All @@ -779,11 +781,11 @@ static struct command_result *json_sendcustommsg(struct command *cmd,
type_to_string(cmd, struct node_id, dest));
}

if (peer->connected != PEER_CONNECTED)
/* We allow messages from plugins responding to peer_connected hook,
* so can be PEER_CONNECTING. */
if (peer->connected == PEER_DISCONNECTED)
return command_fail(cmd, JSONRPC2_INVALID_REQUEST,
"Peer is %s",
peer->connected == PEER_DISCONNECTED
? "not connected" : "still connecting");
"Peer is not connected");

subd_send_msg(cmd->ld->connectd,
take(towire_connectd_custommsg_out(cmd, dest, msg)));
Expand Down
17 changes: 17 additions & 0 deletions lightningd/options.c
Original file line number Diff line number Diff line change
Expand Up @@ -1078,6 +1078,15 @@ static char *opt_set_shutdown_wrong_funding(struct lightningd *ld)
return NULL;
}

static char *opt_set_peer_storage(struct lightningd *ld)
{
feature_set_or(ld->our_features,
take(feature_set_for_feature(NULL, OPT_PROVIDE_PEER_BACKUP_STORAGE)));
feature_set_or(ld->our_features,
take(feature_set_for_feature(NULL, OPT_WANT_PEER_BACKUP_STORAGE)));
return NULL;
}

static char *opt_set_offers(struct lightningd *ld)
{
ld->config.exp_offers = true;
Expand Down Expand Up @@ -1156,6 +1165,9 @@ static void register_opts(struct lightningd *ld)
opt_register_early_noarg("--experimental-shutdown-wrong-funding",
opt_set_shutdown_wrong_funding, ld,
"EXPERIMENTAL: allow shutdown with alternate txids");
opt_register_early_noarg("--experimental-peer-storage",
opt_set_peer_storage, ld,
"EXPERIMENTAL: enable peer backup storage and restore");
opt_register_early_arg("--announce-addr-dns",
opt_set_bool_arg, opt_show_bool,
&ld->announce_dns,
Expand Down Expand Up @@ -1641,6 +1653,11 @@ static void add_config(struct lightningd *ld,
feature_offered(ld->our_features
->bits[INIT_FEATURE],
OPT_SHUTDOWN_WRONG_FUNDING));
} else if (opt->cb == (void *)opt_set_peer_storage) {
json_add_bool(response, name0,
feature_offered(ld->our_features
->bits[INIT_FEATURE],
OPT_PROVIDE_PEER_BACKUP_STORAGE));
} else if (opt->cb == (void *)plugin_opt_flag_set) {
/* Noop, they will get added below along with the
* OPT_HASARG options. */
Expand Down
28 changes: 18 additions & 10 deletions lightningd/peer_control.c
Original file line number Diff line number Diff line change
Expand Up @@ -1071,17 +1071,17 @@ struct peer_connected_hook_payload {
struct wireaddr_internal addr;
struct wireaddr *remote_addr;
bool incoming;
struct peer *peer;
/* We don't keep a pointer to peer: it might be freed! */
struct node_id peer_id;
u8 *error;
};

static void
peer_connected_serialize(struct peer_connected_hook_payload *payload,
struct json_stream *stream, struct plugin *plugin)
{
const struct peer *p = payload->peer;
json_object_start(stream, "peer");
json_add_node_id(stream, "id", &p->id);
json_add_node_id(stream, "id", &payload->peer_id);
json_add_string(stream, "direction", payload->incoming ? "in" : "out");
json_add_string(
stream, "addr",
Expand All @@ -1090,7 +1090,10 @@ peer_connected_serialize(struct peer_connected_hook_payload *payload,
json_add_string(
stream, "remote_addr",
type_to_string(stream, struct wireaddr, payload->remote_addr));
json_add_hex_talarr(stream, "features", p->their_features);
/* Since this is start of hook, peer is always in table! */
json_add_hex_talarr(stream, "features",
peer_by_id(payload->ld, &payload->peer_id)
->their_features);
json_object_end(stream); /* .peer */
}

Expand Down Expand Up @@ -1186,17 +1189,24 @@ static void peer_connected_hook_final(struct peer_connected_hook_payload *payloa
struct lightningd *ld = payload->ld;
struct channel *channel;
struct wireaddr_internal addr = payload->addr;
struct peer *peer = payload->peer;
struct peer *peer;
u8 *error;

/* Whatever happens, we free payload (it's currently a child
* of the peer, which may be freed if we fail to start
* subd). */
tal_steal(tmpctx, payload);

/* Peer might have gone away while we were waiting for plugin! */
peer = peer_by_id(ld, &payload->peer_id);
if (!peer)
return;

/* If we disconnected in the meantime, forget about it.
* (disconnect will have failed any connect commands). */
if (peer->connected == PEER_DISCONNECTED)
* (disconnect will have failed any connect commands).
* And if it has reconnected, and we're the second time the
* hook has been called, it'll be PEER_CONNECTED. */
if (peer->connected != PEER_CONNECTING)
return;

/* Check for specific errors of a hook */
Expand Down Expand Up @@ -1425,9 +1435,7 @@ void peer_connected(struct lightningd *ld, const u8 *msg)
tal_free(peer->remote_addr);
peer->remote_addr = NULL;
peer_update_features(peer, their_features);

tal_steal(peer, hook_payload);
hook_payload->peer = peer;
hook_payload->peer_id = id;

/* If there's a connect command, use its id as basis for hook id */
cmd_id = connect_any_cmd_id(tmpctx, ld, peer);
Expand Down
6 changes: 6 additions & 0 deletions openingd/dualopend.c
Original file line number Diff line number Diff line change
Expand Up @@ -1443,6 +1443,8 @@ static u8 *opening_negotiate_msg(const tal_t *ctx, struct state *state)
case WIRE_WARNING:
case WIRE_PING:
case WIRE_PONG:
case WIRE_PEER_STORAGE:
case WIRE_YOUR_PEER_STORAGE:
#if EXPERIMENTAL_FEATURES
case WIRE_STFU:
#endif
Expand Down Expand Up @@ -1817,6 +1819,8 @@ static bool run_tx_interactive(struct state *state,
case WIRE_REPLY_SHORT_CHANNEL_IDS_END:
case WIRE_PING:
case WIRE_PONG:
case WIRE_PEER_STORAGE:
case WIRE_YOUR_PEER_STORAGE:
#if EXPERIMENTAL_FEATURES
case WIRE_STFU:
#endif
Expand Down Expand Up @@ -4166,6 +4170,8 @@ static u8 *handle_peer_in(struct state *state)
case WIRE_WARNING:
case WIRE_PING:
case WIRE_PONG:
case WIRE_PEER_STORAGE:
case WIRE_YOUR_PEER_STORAGE:
#if EXPERIMENTAL_FEATURES
case WIRE_STFU:
#endif
Expand Down
Loading