Skip to content

Commit a1f907c

Browse files
adi2011sangbida
authored andcommitted
chanbackup: Store the latest recvd peer storage only
Node should not store SCB that is older than what we already have. Changelog-Fixed: Protocol: we now only store the most recent peer backup when recovering from peers.
1 parent 98ba9eb commit a1f907c

1 file changed

Lines changed: 53 additions & 11 deletions

File tree

plugins/chanbackup.c

Lines changed: 53 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,9 @@ struct chanbackup {
6767
/* Global secret object to keep the derived encryption key for the SCB */
6868
struct secret secret;
6969

70+
/* We store the timestamp of the latest peer storage that we have. */
71+
u32 latest_timestamp;
72+
7073
/* Cache of backups for each peer we know about */
7174
struct backup_map *backups;
7275

@@ -819,14 +822,49 @@ static struct command_result *datastore_failed(struct command *cmd,
819822
return command_hook_success(cmd);
820823
}
821824

825+
/* Compares the data between the stored scb and latest recvd scb,
826+
* stores the most recent one only. */
827+
static struct command_result *store_latest_scb(struct command *cmd,
828+
struct chanbackup *cb,
829+
const u8 *received_scb)
830+
{
831+
size_t recvd_scb_len = tal_bytelen(received_scb);
832+
u64 version;
833+
struct modern_scb_chan **scb_tlvs;
834+
u32 timestamp_new;
835+
bool is_converted;
836+
837+
if (!read_static_chan_backup(cmd, received_scb, &version, &timestamp_new, &scb_tlvs, &is_converted)) {
838+
plugin_log(cmd->plugin, LOG_BROKEN, "Ignoring invalid peer storage: %s",
839+
tal_hex(tmpctx, received_scb));
840+
return command_hook_success(cmd);
841+
}
842+
843+
if (timestamp_new < cb->latest_timestamp) {
844+
plugin_log(cmd->plugin, LOG_DBG, "Ignoring old Peer Storage");
845+
return command_hook_success(cmd);
846+
}
847+
848+
cb->latest_timestamp = timestamp_new;
849+
850+
return jsonrpc_set_datastore_binary(cmd,
851+
mkdatastorekey(tmpctx, "chanbackup", "latestscb"),
852+
received_scb, recvd_scb_len,
853+
"create-or-replace",
854+
datastore_success,
855+
datastore_failed,
856+
"Saving latestscb");
857+
858+
}
859+
822860
static struct command_result *handle_your_peer_storage(struct command *cmd,
823861
const char *buf,
824862
const jsmntok_t *params)
825863
{
826864
struct node_id node_id;
827865
u8 *payload, *payload_deserialise;
828866
const char *err;
829-
const struct chanbackup *cb = chanbackup(cmd->plugin);
867+
struct chanbackup *cb = chanbackup(cmd->plugin);
830868

831869
err = json_scan(cmd, buf, params,
832870
"{payload:%,peer_id:%}",
@@ -906,16 +944,7 @@ static struct command_result *handle_your_peer_storage(struct command *cmd,
906944
NULL, 0) != 0)
907945
return failed_peer_restore(cmd, &node_id,
908946
"Peer altered our data");
909-
910-
911-
return jsonrpc_set_datastore_binary(cmd,
912-
mkdatastorekey(tmpctx, "chanbackup", "latestscb"),
913-
decoded_bkp,
914-
tal_bytelen(decoded_bkp),
915-
"create-or-replace",
916-
datastore_success,
917-
datastore_failed,
918-
"Saving latestscb");
947+
return store_latest_scb(cmd, cb, decoded_bkp);
919948
} else {
920949
/* Any other message we ignore */
921950
return command_hook_success(cmd);
@@ -1092,6 +1121,7 @@ static const char *init(struct command *init_cmd,
10921121
const char *info = "scb secret";
10931122
u8 *info_hex = tal_dup_arr(tmpctx, u8, (u8*)info, strlen(info), 0);
10941123
u8 *features;
1124+
u8 *latestscb;
10951125

10961126
/* Figure out if they specified --experimental-peer-storage */
10971127
rpc_scan(init_cmd, "getinfo",
@@ -1115,6 +1145,18 @@ static const char *init(struct command *init_cmd,
11151145
tal_bytelen(info_hex)))),
11161146
"{secret:%}", JSON_SCAN(json_to_secret, &cb->secret));
11171147

1148+
/* Caching timestamp of latestscb that we have stored. This
1149+
* would be useful for upgrading `chanbackup/latestscb`. */
1150+
cb->latest_timestamp = 0;
1151+
if (rpc_scan_datastore_hex(tmpctx, init_cmd,
1152+
mkdatastorekey(tmpctx, "chanbackup", "latestscb"),
1153+
JSON_SCAN_TAL(tmpctx, json_tok_bin_from_hex, &latestscb)) == NULL) {
1154+
u64 version;
1155+
struct modern_scb_chan **scb_tlvs;
1156+
bool is_converted;
1157+
read_static_chan_backup(init_cmd, latestscb, &version, &cb->latest_timestamp, &scb_tlvs, &is_converted);
1158+
}
1159+
11181160
setup_backup_map(init_cmd, cb);
11191161
plugin_set_data(init_cmd->plugin, cb);
11201162
plugin_log(init_cmd->plugin, LOG_DBG, "Chanbackup Initialised!");

0 commit comments

Comments
 (0)