Skip to content

Commit 07ef83b

Browse files
committed
chanbackup: make getemergencyrecoverdata rpc more verbose
Adding more information to geremergencyrecoverdata, to let users know if they are using legacy file format and the list of all the backed up channel ids. Key Changes: - Added: 1. can_create_penalty: To let user know if they need to update the file. 2. backed_up_channel_ids: List of all the backed up channels
1 parent bf6703a commit 07ef83b

File tree

4 files changed

+101
-75
lines changed

4 files changed

+101
-75
lines changed

contrib/msggen/msggen/schema.json

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14058,7 +14058,9 @@
1405814058
},
1405914059
"response": {
1406014060
"required": [
14061-
"filedata"
14061+
"filedata",
14062+
"can_create_penalty",
14063+
"backed_up_channel_ids"
1406214064
],
1406314065
"additionalProperties": false,
1406414066
"properties": {
@@ -14067,6 +14069,21 @@
1406714069
"description": [
1406814070
"The raw, hex-encoded, emergency.recover file"
1406914071
]
14072+
},
14073+
"can_create_penalty": {
14074+
"type": "boolean",
14075+
"description": [
14076+
"If false, you are using legacy file version, which can not create penalty transactions, kindly delete emergency.recover and restart the node!"
14077+
]
14078+
},
14079+
"backed_up_channel_ids": {
14080+
"type": "array",
14081+
"items": {
14082+
"type": "hex",
14083+
"description": [
14084+
"Channel IDs of channels backed up inside emergency.recover"
14085+
]
14086+
}
1407014087
}
1407114088
}
1407214089
},

doc/schemas/getemergencyrecoverdata.json

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,9 @@
1313
},
1414
"response": {
1515
"required": [
16-
"filedata"
16+
"filedata",
17+
"can_create_penalty",
18+
"backed_up_channel_ids"
1719
],
1820
"additionalProperties": false,
1921
"properties": {
@@ -22,6 +24,21 @@
2224
"description": [
2325
"The raw, hex-encoded, emergency.recover file"
2426
]
27+
},
28+
"can_create_penalty": {
29+
"type": "boolean",
30+
"description": [
31+
"If false, you are using legacy file version, which can not create penalty transactions, kindly delete emergency.recover and restart the node!"
32+
]
33+
},
34+
"backed_up_channel_ids": {
35+
"type": "array",
36+
"items": {
37+
"type": "hex",
38+
"description": [
39+
"Channel IDs of channels backed up inside emergency.recover"
40+
]
41+
}
2542
}
2643
}
2744
},

plugins/chanbackup.c

Lines changed: 61 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -316,6 +316,35 @@ static struct modern_scb_chan *convert_from_legacy(const tal_t *ctx, struct lega
316316
return modern_scb_tlv;
317317
}
318318

319+
/* Reads WIRE_STATIC_CHAN_BACKUP and converts from legacy_scb_chan to modern_scb_chan, if required. */
320+
static void read_static_chan_backup(struct command *cmd, const u8 *blob, u64 *version, u32 *timestamp, struct modern_scb_chan ***scb_tlvs, bool *is_converted) {
321+
bool is_tlvs = false;
322+
struct legacy_scb_chan **scb;
323+
324+
if(!fromwire_static_chan_backup(cmd,
325+
blob,
326+
version,
327+
timestamp,
328+
&scb)) {
329+
is_tlvs = true;
330+
if (!fromwire_static_chan_backup_with_tlvs(cmd,
331+
blob,
332+
version,
333+
timestamp,
334+
scb_tlvs)) {
335+
plugin_err(cmd->plugin, "Corrupted SCB!");
336+
}
337+
}
338+
*is_converted = !is_tlvs;
339+
if (!is_tlvs) {
340+
*scb_tlvs = tal_count(scb) ? tal_arr(cmd, struct modern_scb_chan *, tal_count(scb)): NULL;
341+
for (size_t i=0; i < tal_count(scb); i++){
342+
(*scb_tlvs)[i] = convert_from_legacy(cmd, scb[i]);
343+
}
344+
}
345+
return;
346+
}
347+
319348
/* Recovers the channels by making RPC to `recoverchannel` */
320349
static struct command_result *json_emergencyrecover(struct command *cmd,
321350
const char *buf,
@@ -324,28 +353,14 @@ static struct command_result *json_emergencyrecover(struct command *cmd,
324353
struct out_req *req;
325354
u64 version;
326355
u32 timestamp;
327-
struct legacy_scb_chan **scb;
356+
bool is_converted;
328357
struct modern_scb_chan **scb_tlvs;
329358

330359
if (!param(cmd, buf, params, NULL))
331360
return command_param_failed();
332361

333362
u8 *res = decrypt_scb(cmd->plugin);
334-
bool is_tlvs = false;
335-
if (!fromwire_static_chan_backup(cmd,
336-
res,
337-
&version,
338-
&timestamp,
339-
&scb)) {
340-
if(!fromwire_static_chan_backup_with_tlvs(cmd,
341-
res,
342-
&version,
343-
&timestamp,
344-
&scb_tlvs)) {
345-
plugin_err(cmd->plugin, "Corrupted SCB!");
346-
}
347-
is_tlvs = true;
348-
}
363+
read_static_chan_backup(cmd, res, &version, &timestamp, &scb_tlvs, &is_converted);
349364

350365
if ((version & 0x5555555555555555ULL) != (VERSION & 0x5555555555555555ULL)) {
351366
plugin_err(cmd->plugin,
@@ -356,26 +371,18 @@ static struct command_result *json_emergencyrecover(struct command *cmd,
356371
after_recover_rpc,
357372
forward_error, NULL);
358373

359-
json_array_start(req->js, "scb");
360-
if (is_tlvs) {
361-
for (size_t i=0; i<tal_count(scb_tlvs); i++) {
362-
u8 *scb_hex = tal_arr(cmd, u8, 0);
363-
towire_modern_scb_chan(&scb_hex,scb_tlvs[i]);
364-
json_add_hex_talarr(req->js, NULL, scb_hex);
365-
}
366-
} else {
374+
if (is_converted) {
367375
plugin_notify_message(cmd, LOG_DBG, "Processing legacy emergency.recover file format. "
368-
"Please migrate to the latest file format for improved "
369-
"compatibility and fund recovery.");
370-
371-
for (size_t i=0; i<tal_count(scb); i++) {
372-
u8 *scb_hex = tal_arr(cmd, u8, 0);
373-
struct modern_scb_chan *tmp_scb = convert_from_legacy(cmd, scb[i]);
374-
towire_modern_scb_chan(&scb_hex, tmp_scb);
375-
json_add_hex_talarr(req->js, NULL, scb_hex);
376-
}
376+
"Please migrate to the latest file format for improved "
377+
"compatibility and fund recovery.");
377378
}
378379

380+
json_array_start(req->js, "scb");
381+
for (size_t i=0; i<tal_count(scb_tlvs); i++) {
382+
u8 *scb_hex = tal_arr(cmd, u8, 0);
383+
towire_modern_scb_chan(&scb_hex, scb_tlvs[i]);
384+
json_add_hex_talarr(req->js, NULL, scb_hex);
385+
}
379386
json_array_end(req->js);
380387

381388
return send_outreq(req);
@@ -946,8 +953,8 @@ static struct command_result *after_latestscb(struct command *cmd,
946953
{
947954
u64 version;
948955
u32 timestamp;
956+
bool is_converted;
949957
struct modern_scb_chan **scb_tlvs;
950-
struct legacy_scb_chan **scb;
951958
struct json_stream *response;
952959
struct out_req *req;
953960

@@ -959,21 +966,7 @@ static struct command_result *after_latestscb(struct command *cmd,
959966
return command_finished(cmd, response);
960967
}
961968

962-
bool is_tlvs = false;
963-
if (!fromwire_static_chan_backup(cmd,
964-
res,
965-
&version,
966-
&timestamp,
967-
&scb)) {
968-
if(!fromwire_static_chan_backup_with_tlvs(cmd,
969-
res,
970-
&version,
971-
&timestamp,
972-
&scb_tlvs)) {
973-
plugin_err(cmd->plugin, "Corrupted SCB!");
974-
}
975-
is_tlvs = true;
976-
}
969+
read_static_chan_backup(cmd, res, &version, &timestamp, &scb_tlvs, &is_converted);
977970

978971
if ((version & 0x5555555555555555ULL) != (VERSION & 0x5555555555555555ULL)) {
979972
plugin_err(cmd->plugin,
@@ -985,28 +978,11 @@ static struct command_result *after_latestscb(struct command *cmd,
985978
&forward_error, NULL);
986979

987980
json_array_start(req->js, "scb");
988-
if (is_tlvs) {
989-
for (size_t i=0; i<tal_count(scb_tlvs); i++) {
990-
u8 *scb_hex = tal_arr(cmd, u8, 0);
991-
towire_modern_scb_chan(&scb_hex,scb_tlvs[i]);
992-
json_add_hex_talarr(req->js, NULL, scb_hex);
993-
}
994-
} else {
995-
for (size_t i=0; i<tal_count(scb); i++) {
996-
u8 *scb_hex = tal_arr(cmd, u8, 0);
997-
struct modern_scb_chan *tmp_scb_tlv = tal(cmd, struct modern_scb_chan);
998-
tmp_scb_tlv->id = scb[i]->id;
999-
tmp_scb_tlv->addr = scb[i]->addr;
1000-
tmp_scb_tlv->cid = scb[i]->cid;
1001-
tmp_scb_tlv->funding = scb[i]->funding;
1002-
tmp_scb_tlv->funding_sats = scb[i]->funding_sats;
1003-
tmp_scb_tlv->type = scb[i]->type;
1004-
tmp_scb_tlv->tlvs = tlv_scb_tlvs_new(cmd);
1005-
towire_modern_scb_chan(&scb_hex, tmp_scb_tlv);
1006-
json_add_hex_talarr(req->js, NULL, scb_hex);
1007-
}
981+
for (size_t i=0; i<tal_count(scb_tlvs); i++) {
982+
u8 *scb_hex = tal_arr(cmd, u8, 0);
983+
towire_modern_scb_chan(&scb_hex, scb_tlvs[i]);
984+
json_add_hex_talarr(req->js, NULL, scb_hex);
1008985
}
1009-
1010986
json_array_end(req->js);
1011987

1012988
return send_outreq(req);
@@ -1040,7 +1016,21 @@ static struct command_result *json_getemergencyrecoverdata(struct command *cmd,
10401016
response = jsonrpc_stream_success(cmd);
10411017
json_add_hex_talarr(response, "filedata", filedata);
10421018

1043-
1019+
// Add details about the SCB.
1020+
const u8 *decrypted_filedata = decrypt_scb(cmd->plugin);
1021+
u64 version;
1022+
u32 timestamp;
1023+
struct modern_scb_chan **scb_tlvs;
1024+
bool is_converted;
1025+
read_static_chan_backup(cmd, decrypted_filedata, &version, &timestamp, &scb_tlvs, &is_converted);
1026+
1027+
// If false, update the emergency.recover file immediately!
1028+
json_add_bool(response, "can_create_penalty", !is_converted);
1029+
json_array_start(response, "backed_up_channel_ids");
1030+
for (int i = 0; i < tal_count(scb_tlvs); i++) {
1031+
json_add_channel_id(response, NULL, &scb_tlvs[i]->cid);
1032+
}
1033+
json_array_end(response);
10441034
return command_finished(cmd, response);
10451035
}
10461036

tests/test_misc.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2973,8 +2973,10 @@ def test_getemergencyrecoverdata(node_factory):
29732973
Test getemergencyrecoverdata
29742974
"""
29752975
l1 = node_factory.get_node()
2976-
filedata = l1.rpc.getemergencyrecoverdata()['filedata']
2977-
2976+
rpc = l1.rpc.getemergencyrecoverdata()
2977+
filedata = rpc['filedata']
2978+
assert rpc['can_create_penalty'] == True
2979+
assert len(rpc['backed_up_channel_ids']) == 0
29782980
with open(os.path.join(l1.daemon.lightning_dir, TEST_NETWORK, "emergency.recover"), "rb") as f:
29792981
lines = f.read().hex()
29802982
assert lines == filedata

0 commit comments

Comments
 (0)