Add New MsgType and SubType for SCB

Adding new fields to the SCB would break the current serialization format.
To address this, we have introduced a new message type with a predefined TLV length,
allowing us to split and process each channel separately.

Key Changes:
 - Added a new SubType and MsgType to accommodate the new fields.
 - Included it in varsize_types in generate-wire.py to ignore the double
   pointer in the struct definition within the wiregen file.
This commit is contained in:
Aditya Sharma 2025-02-12 04:57:48 +05:30
parent c9466f1d73
commit 167e0b2e95
4 changed files with 77 additions and 14 deletions

View file

@ -27,10 +27,27 @@ subtypedata,scb_chan,addr,wireaddr,
subtypedata,scb_chan,funding,bitcoin_outpoint,
subtypedata,scb_chan,funding_sats,amount_sat,
subtypedata,scb_chan,type,channel_type,
subtypedata,scb_chan,tlvs,scb_tlvs,
msgtype,static_chan_backup,6135,
msgdata,static_chan_backup,version,u64,
msgdata,static_chan_backup,timestamp,u32,
msgdata,static_chan_backup,num,u16,
msgdata,static_chan_backup,channels,scb_chan,num
subtype,scb_chan_with_tlvs
subtypedata,scb_chan_with_tlvs,id,u64,
subtypedata,scb_chan_with_tlvs,cid,channel_id,
subtypedata,scb_chan_with_tlvs,node_id,node_id,
subtypedata,scb_chan_with_tlvs,unused,u8,
subtypedata,scb_chan_with_tlvs,addr,wireaddr,
subtypedata,scb_chan_with_tlvs,funding,bitcoin_outpoint,
subtypedata,scb_chan_with_tlvs,funding_sats,amount_sat,
subtypedata,scb_chan_with_tlvs,type,channel_type,
subtypedata,scb_chan_with_tlvs,len_tlv,u32,
subtypedata,scb_chan_with_tlvs,tlvs,scb_tlvs,len_tlv
msgtype,static_chan_backup_with_tlvs,6137,
msgdata,static_chan_backup_with_tlvs,version,u64,
msgdata,static_chan_backup_with_tlvs,timestamp,u32,
msgdata,static_chan_backup_with_tlvs,num,u16,
msgdata,static_chan_backup_with_tlvs,channels,scb_chan_with_tlvs,num

Can't render this file because it has a wrong number of fields in line 11.

View file

@ -716,6 +716,7 @@ static struct command_result *after_latestscb(struct command *cmd,
{
u64 version;
u32 timestamp;
struct scb_chan_with_tlvs **scb_tlvs;
struct scb_chan **scb;
struct json_stream *response;
struct out_req *req;
@ -728,29 +729,54 @@ static struct command_result *after_latestscb(struct command *cmd,
return command_finished(cmd, response);
}
bool is_tlvs = false;
if (!fromwire_static_chan_backup(cmd,
res,
&version,
&timestamp,
&scb)) {
plugin_err(cmd->plugin, "Corrupted SCB on disk!");
if(!fromwire_static_chan_backup_with_tlvs(cmd,
res,
&version,
&timestamp,
&scb_tlvs)) {
plugin_err(cmd->plugin, "Corrupted SCB!");
}
is_tlvs = true;
}
if (version != VERSION) {
plugin_err(cmd->plugin,
"Incompatible version, Contact the admin!");
"Incompatible SCB file version on disk, contact the admin!");
}
req = jsonrpc_request_start(cmd, "recoverchannel",
req = jsonrpc_request_start(cmd, "recoverchannel",
after_recover_rpc,
&forward_error, NULL);
json_array_start(req->js, "scb");
for (size_t i=0; i<tal_count(scb); i++) {
u8 *scb_hex = tal_arr(cmd, u8, 0);
towire_scb_chan(&scb_hex,scb[i]);
json_add_hex(req->js, NULL, scb_hex, tal_bytelen(scb_hex));
if (is_tlvs) {
for (size_t i=0; i<tal_count(scb_tlvs); i++) {
u8 *scb_hex = tal_arr(cmd, u8, 0);
towire_scb_chan_with_tlvs(&scb_hex,scb_tlvs[i]);
json_add_hex(req->js, NULL, scb_hex, tal_bytelen(scb_hex));
}
} else {
for (size_t i=0; i<tal_count(scb); i++) {
u8 *scb_hex = tal_arr(cmd, u8, 0);
struct scb_chan_with_tlvs *tmp_scb_tlv = tal(cmd, struct scb_chan_with_tlvs);
tmp_scb_tlv->id = scb[i]->id;
tmp_scb_tlv->addr = scb[i]->addr;
tmp_scb_tlv->cid = scb[i]->cid;
tmp_scb_tlv->funding = scb[i]->funding;
tmp_scb_tlv->funding_sats = scb[i]->funding_sats;
tmp_scb_tlv->type = scb[i]->type;
tmp_scb_tlv->tlvs = tlv_scb_tlvs_new(cmd);
towire_scb_chan_with_tlvs(&scb_hex, tmp_scb_tlv);
json_add_hex(req->js, NULL, scb_hex, tal_bytelen(scb_hex));
}
}
json_array_end(req->js);
return send_outreq(req);

View file

@ -250,6 +250,7 @@ class Type(FieldSet):
'wally_psbt',
'wally_tx',
'scb_chan',
'scb_chan_with_tlvs',
'inflight',
]

View file

@ -20,6 +20,7 @@ static void test_error(struct lightningd *ld, bool fatal, const char *fmt, va_li
wallet_err = tal_vfmt(NULL, fmt, ap);
}
#include "common/scb_wiregen.c"
#include "wallet/wallet.c"
#include "lightningd/hsm_control.c"
#include "lightningd/htlc_end.c"
@ -277,6 +278,13 @@ u64 forward_index_update_status(struct lightningd *ld UNNEEDED,
struct amount_msat in_amount UNNEEDED,
const struct short_channel_id *out_channel UNNEEDED)
{ fprintf(stderr, "forward_index_update_status called!\n"); abort(); }
/* Generated stub for fromwire_channel_id */
bool fromwire_channel_id(const u8 **cursor UNNEEDED, size_t *max UNNEEDED,
struct channel_id *channel_id UNNEEDED)
{ fprintf(stderr, "fromwire_channel_id called!\n"); abort(); }
/* Generated stub for fromwire_channel_type */
struct channel_type *fromwire_channel_type(const tal_t *ctx UNNEEDED, const u8 **cursor UNNEEDED, size_t *plen UNNEEDED)
{ fprintf(stderr, "fromwire_channel_type called!\n"); abort(); }
/* Generated stub for fromwire_channeld_dev_memleak_reply */
bool fromwire_channeld_dev_memleak_reply(const void *p UNNEEDED, bool *leak UNNEEDED)
{ fprintf(stderr, "fromwire_channeld_dev_memleak_reply called!\n"); abort(); }
@ -349,6 +357,12 @@ bool fromwire_onchaind_dev_memleak_reply(const void *p UNNEEDED, bool *leak UNNE
/* Generated stub for fromwire_openingd_dev_memleak_reply */
bool fromwire_openingd_dev_memleak_reply(const void *p UNNEEDED, bool *leak UNNEEDED)
{ fprintf(stderr, "fromwire_openingd_dev_memleak_reply called!\n"); abort(); }
/* Generated stub for fromwire_tlv */
bool fromwire_tlv(const u8 **cursor UNNEEDED, size_t *max UNNEEDED,
const struct tlv_record_type *types UNNEEDED, size_t num_types UNNEEDED,
void *record UNNEEDED, struct tlv_field **fields UNNEEDED,
const u64 *extra_types UNNEEDED, size_t *err_off UNNEEDED, u64 *err_type UNNEEDED)
{ fprintf(stderr, "fromwire_tlv called!\n"); abort(); }
/* Generated stub for get_block_height */
u32 get_block_height(const struct chain_topology *topo UNNEEDED)
{ fprintf(stderr, "get_block_height called!\n"); abort(); }
@ -1017,9 +1031,6 @@ void tell_connectd_peer_importance(struct peer *peer UNNEEDED,
/* Generated stub for tlv_hsmd_dev_preinit_tlvs_new */
struct tlv_hsmd_dev_preinit_tlvs *tlv_hsmd_dev_preinit_tlvs_new(const tal_t *ctx UNNEEDED)
{ fprintf(stderr, "tlv_hsmd_dev_preinit_tlvs_new called!\n"); abort(); }
/* Generated stub for tlv_scb_tlvs_new */
struct tlv_scb_tlvs *tlv_scb_tlvs_new(const tal_t *ctx UNNEEDED)
{ fprintf(stderr, "tlv_scb_tlvs_new called!\n"); abort(); }
/* Generated stub for to_canonical_invstr */
const char *to_canonical_invstr(const tal_t *ctx UNNEEDED, const char *invstring UNNEEDED)
{ fprintf(stderr, "to_canonical_invstr called!\n"); abort(); }
@ -1033,9 +1044,15 @@ void topology_add_sync_waiter_(const tal_t *ctx UNNEEDED,
/* Generated stub for towire_announcement_signatures */
u8 *towire_announcement_signatures(const tal_t *ctx UNNEEDED, const struct channel_id *channel_id UNNEEDED, struct short_channel_id short_channel_id UNNEEDED, const secp256k1_ecdsa_signature *node_signature UNNEEDED, const secp256k1_ecdsa_signature *bitcoin_signature UNNEEDED)
{ fprintf(stderr, "towire_announcement_signatures called!\n"); abort(); }
/* Generated stub for towire_channel_id */
void towire_channel_id(u8 **pptr UNNEEDED, const struct channel_id *channel_id UNNEEDED)
{ fprintf(stderr, "towire_channel_id called!\n"); abort(); }
/* Generated stub for towire_channel_reestablish */
u8 *towire_channel_reestablish(const tal_t *ctx UNNEEDED, const struct channel_id *channel_id UNNEEDED, u64 next_commitment_number UNNEEDED, u64 next_revocation_number UNNEEDED, const struct secret *your_last_per_commitment_secret UNNEEDED, const struct pubkey *my_current_per_commitment_point UNNEEDED, const struct tlv_channel_reestablish_tlvs *channel_reestablish UNNEEDED)
{ fprintf(stderr, "towire_channel_reestablish called!\n"); abort(); }
/* Generated stub for towire_channel_type */
void towire_channel_type(u8 **p UNNEEDED, const struct channel_type *channel_type UNNEEDED)
{ fprintf(stderr, "towire_channel_type called!\n"); abort(); }
/* Generated stub for towire_channeld_dev_memleak */
u8 *towire_channeld_dev_memleak(const tal_t *ctx UNNEEDED)
{ fprintf(stderr, "towire_channeld_dev_memleak called!\n"); abort(); }
@ -1155,15 +1172,17 @@ u8 *towire_openingd_dev_memleak(const tal_t *ctx UNNEEDED)
/* Generated stub for towire_permanent_channel_failure */
u8 *towire_permanent_channel_failure(const tal_t *ctx UNNEEDED)
{ fprintf(stderr, "towire_permanent_channel_failure called!\n"); abort(); }
/* Generated stub for towire_scb_chan */
void towire_scb_chan(u8 **p UNNEEDED, const struct scb_chan *scb_chan UNNEEDED)
{ fprintf(stderr, "towire_scb_chan called!\n"); abort(); }
/* Generated stub for towire_temporary_channel_failure */
u8 *towire_temporary_channel_failure(const tal_t *ctx UNNEEDED, const u8 *channel_update UNNEEDED)
{ fprintf(stderr, "towire_temporary_channel_failure called!\n"); abort(); }
/* Generated stub for towire_temporary_node_failure */
u8 *towire_temporary_node_failure(const tal_t *ctx UNNEEDED)
{ fprintf(stderr, "towire_temporary_node_failure called!\n"); abort(); }
/* Generated stub for towire_tlv */
void towire_tlv(u8 **pptr UNNEEDED,
const struct tlv_record_type *types UNNEEDED, size_t num_types UNNEEDED,
const void *record UNNEEDED)
{ fprintf(stderr, "towire_tlv called!\n"); abort(); }
/* Generated stub for towire_unknown_next_peer */
u8 *towire_unknown_next_peer(const tal_t *ctx UNNEEDED)
{ fprintf(stderr, "towire_unknown_next_peer called!\n"); abort(); }