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

Update emergency.recover after every 'commitment_revocation' so that user can sweep funds by penalty transaction. #7772

Open
wants to merge 10 commits into
base: master
Choose a base branch
from
Open
38 changes: 34 additions & 4 deletions common/scb_wire.csv
Original file line number Diff line number Diff line change
@@ -1,9 +1,21 @@
#include <common/node_id.h>
#include <bitcoin/tx.h>
#include <ccan/crypto/shachain/shachain.h>
#include <common/amount.h>
#include <common/channel_id.h>
#include <common/wireaddr.h>
#include <common/channel_type.h>
#include <common/amount.h>
#include <bitcoin/tx.h>
#include <common/derive_basepoints.h>
#include <common/htlc_wire.h>
adi2011 marked this conversation as resolved.
Show resolved Hide resolved
#include <common/node_id.h>
#include <common/wireaddr.h>

tlvtype,scb_tlvs,shachain,1,
tlvdata,scb_tlvs,shachain,their_shachain,shachain,
tlvtype,scb_tlvs,basepoints,3,
tlvdata,scb_tlvs,basepoints,their_basepoint,basepoints,
tlvtype,scb_tlvs,opener,5,
tlvdata,scb_tlvs,opener,opener,enum side,
tlvtype,scb_tlvs,remote_to_self_delay,7,
tlvdata,scb_tlvs,remote_to_self_delay,remote_to_self_delay,u16,

# scb_chan stores min. info required to sweep the peer's force close.
subtype,scb_chan
Expand All @@ -21,3 +33,21 @@ 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
12 changes: 10 additions & 2 deletions lightningd/channel.c
Original file line number Diff line number Diff line change
Expand Up @@ -482,10 +482,11 @@ struct channel *new_channel(struct peer *peer, u64 dbid,
channel->owner = NULL;
memset(&channel->billboard, 0, sizeof(channel->billboard));
channel->billboard.transient = tal_strdup(channel, transient_billboard);
channel->channel_info = *channel_info;

/* If it's a unix domain socket connection, we don't save it */
if (peer->addr.itype == ADDR_INTERNAL_WIREADDR) {
channel->scb = tal(channel, struct scb_chan);
channel->scb = tal(channel, struct scb_chan_with_tlvs);
channel->scb->id = dbid;
channel->scb->unused = 0;
/* More useful to have last_known_addr, if avail */
Expand All @@ -497,6 +498,14 @@ struct channel *new_channel(struct peer *peer, u64 dbid,
channel->scb->cid = *cid;
channel->scb->funding_sats = funding_sats;
channel->scb->type = channel_type_dup(channel->scb, type);

struct tlv_scb_tlvs *scb_tlvs = tlv_scb_tlvs_new(channel);
scb_tlvs->shachain = &channel->their_shachain.chain;
scb_tlvs->basepoints = &channel->channel_info.theirbase;
scb_tlvs->opener = &channel->opener;
scb_tlvs->remote_to_self_delay = &channel->channel_info.their_config.to_self_delay;

channel->scb->tlvs = scb_tlvs;
} else
channel->scb = NULL;

Expand Down Expand Up @@ -542,7 +551,6 @@ struct channel *new_channel(struct peer *peer, u64 dbid,
if (last_sig)
channel->last_sig = *last_sig;
channel->last_htlc_sigs = tal_steal(channel, last_htlc_sigs);
channel->channel_info = *channel_info;
channel->fee_states = dup_fee_states(channel, fee_states);
channel->shutdown_scriptpubkey[REMOTE]
= tal_steal(channel, remote_shutdown_scriptpubkey);
Expand Down
2 changes: 1 addition & 1 deletion lightningd/channel.h
Original file line number Diff line number Diff line change
Expand Up @@ -334,7 +334,7 @@ struct channel {

/* `Channel-shell` of this channel
* (Minimum information required to backup this channel). */
struct scb_chan *scb;
struct scb_chan_with_tlvs *scb;

/* Do we allow the peer to set any fee it wants? */
bool ignore_fee_limits;
Expand Down
10 changes: 9 additions & 1 deletion lightningd/dual_open_control.c
Original file line number Diff line number Diff line change
Expand Up @@ -1462,14 +1462,22 @@ wallet_commit_channel(struct lightningd *ld,
channel->min_possible_feerate = commitment_feerate;
channel->max_possible_feerate = commitment_feerate;
if (channel->peer->addr.itype == ADDR_INTERNAL_WIREADDR) {
channel->scb = tal(channel, struct scb_chan);
channel->scb = tal(channel, struct scb_chan_with_tlvs);
channel->scb->id = channel->dbid;
channel->scb->unused = 0;
channel->scb->addr = channel->peer->addr.u.wireaddr.wireaddr;
channel->scb->node_id = channel->peer->id;
channel->scb->funding = *funding;
channel->scb->cid = channel->cid;
channel->scb->funding_sats = total_funding;

struct tlv_scb_tlvs *scb_tlvs = tlv_scb_tlvs_new(channel);
scb_tlvs->shachain = &channel->their_shachain.chain;
scb_tlvs->basepoints = &channel_info->theirbase;
scb_tlvs->opener = &channel->opener;
scb_tlvs->remote_to_self_delay = &channel_info->their_config.to_self_delay;

channel->scb->tlvs = scb_tlvs;
} else
channel->scb = NULL;

Expand Down
71 changes: 61 additions & 10 deletions lightningd/opening_control.c
adi2011 marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
Expand Up @@ -1452,7 +1452,11 @@ static struct channel *stub_chan(struct command *cmd,
struct bitcoin_outpoint funding,
struct wireaddr addr,
struct amount_sat funding_sats,
struct channel_type *type)
struct channel_type *type,
struct shachain shachain,
struct basepoints their_basepoint,
enum side opener,
u16 remote_to_self_delay)
{
struct basepoints basepoints;
struct bitcoin_signature *sig;
Expand All @@ -1468,6 +1472,10 @@ static struct channel *stub_chan(struct command *cmd,
u32 blockht;
u32 feerate;
struct channel_stats zero_channel_stats;
struct wallet_shachain *their_shachain = tal(cmd, struct wallet_shachain);
their_shachain->chain = shachain;
their_shachain->id = 0;

u8 *dummy_sig = tal_hexdata(cmd,
"30450221009b2e0eef267b94c3899fb0dc73750"
"12e2cee4c10348a068fe78d1b82b4b1403602207"
Expand Down Expand Up @@ -1528,8 +1536,11 @@ static struct channel *stub_chan(struct command *cmd,
/* FIXME: Makeake these a pointer, so they could be NULL */
memset(our_config, 0, sizeof(struct channel_config));
memset(their_config, 0, sizeof(struct channel_config));
memset(channel_info, 0, sizeof(struct channel_info));

our_config->to_self_delay = remote_to_self_delay;
channel_info->their_config = *their_config;
channel_info->theirbase = basepoints;
channel_info->theirbase = their_basepoint;
channel_info->remote_fundingkey = pk;
channel_info->remote_per_commit = pk;
channel_info->old_remote_per_commit = pk;
Expand All @@ -1545,9 +1556,9 @@ static struct channel *stub_chan(struct command *cmd,

/* Channel Shell with Dummy data(mostly) */
channel = new_channel(peer, id,
NULL, /* No shachain yet */
their_shachain,
CHANNELD_NORMAL,
LOCAL,
opener,
NULL,
"restored from static channel backup",
0, false, false,
Expand All @@ -1574,15 +1585,15 @@ static struct channel *stub_chan(struct command *cmd,
sig,
NULL, /* No HTLC sigs */
channel_info,
new_fee_states(cmd, LOCAL, &feerate),
new_fee_states(cmd, opener, &feerate),
NULL, /* No shutdown_scriptpubkey[REMOTE] */
NULL,
1, false,
NULL, /* No commit sent */
/* If we're fundee, could be a little before this
* in theory, but it's only used for timing out. */
get_network_blockheight(ld->topology),
FEERATE_FLOOR,
feerate,
funding_sats.satoshis / MINIMUM_TX_WEIGHT * 1000 /* Raw: convert to feerate */,
&basepoints,
&localFundingPubkey,
Expand All @@ -1596,7 +1607,7 @@ static struct channel *stub_chan(struct command *cmd,
0, /* no close_attempt_height */
REASON_REMOTE,
NULL,
take(new_height_states(ld->wallet, LOCAL,
take(new_height_states(ld->wallet, opener,
&blockht)),
0, NULL, 0, 0, /* No leases on v1s */
ld->config.htlc_minimum_msat,
Expand All @@ -1621,7 +1632,7 @@ static struct command_result *json_recoverchannel(struct command *cmd,
const jsmntok_t *scb, *t;
size_t i;
struct json_stream *response;
struct scb_chan *scb_chan = tal(cmd, struct scb_chan);
struct scb_chan_with_tlvs *scb_chan = tal(cmd, struct scb_chan_with_tlvs);

if (!param(cmd, buffer, params,
p_req("scb", param_array, &scb),
Expand All @@ -1636,14 +1647,50 @@ static struct command_result *json_recoverchannel(struct command *cmd,
char *token = json_strdup(tmpctx, buffer, t);
const u8 *scb_arr = tal_hexdata(cmd, token, strlen(token));
size_t scblen = tal_count(scb_arr);
struct shachain chain;
struct basepoints basepoints;
struct pubkey _localfundingpubkey;
enum side opener = LOCAL;
u16 remote_to_self_delay = 0;

scb_chan = fromwire_scb_chan(cmd ,&scb_arr, &scblen);
scb_chan = fromwire_scb_chan_with_tlvs(cmd, &scb_arr, &scblen);

if (scb_chan == NULL) {
log_broken(cmd->ld->log, "SCB is invalid!");
continue;
}

if (scb_chan->tlvs != NULL) {
if (scb_chan->tlvs->shachain == NULL) {
shachain_init(&chain);
} else {
chain = *scb_chan->tlvs->shachain;
}

if (scb_chan->tlvs->basepoints == NULL) {
get_channel_basepoints(cmd->ld,
&scb_chan->node_id,
scb_chan->id,
&basepoints,
&_localfundingpubkey);
} else {
basepoints = *scb_chan->tlvs->basepoints;
}

if (scb_chan->tlvs->opener != NULL)
opener = *scb_chan->tlvs->opener;

if (scb_chan->tlvs->remote_to_self_delay != NULL)
remote_to_self_delay = *scb_chan->tlvs->remote_to_self_delay;
} else {
shachain_init(&chain);
get_channel_basepoints(cmd->ld,
&scb_chan->node_id,
scb_chan->id,
&basepoints,
&_localfundingpubkey);
}

struct lightningd *ld = cmd->ld;
struct channel *channel= stub_chan(cmd,
scb_chan->id,
Expand All @@ -1652,7 +1699,11 @@ static struct command_result *json_recoverchannel(struct command *cmd,
scb_chan->funding,
scb_chan->addr,
scb_chan->funding_sats,
scb_chan->type);
scb_chan->type,
chain,
basepoints,
opener,
remote_to_self_delay);

/* Returns NULL only when channel already exists, so we skip over it. */
if (channel == NULL)
Expand Down
4 changes: 3 additions & 1 deletion lightningd/peer_control.c
Original file line number Diff line number Diff line change
Expand Up @@ -2367,8 +2367,10 @@ static void json_add_scb(struct command *cmd,
struct channel *c)
{
u8 *scb = tal_arr(cmd, u8, 0);
/* Update shachain in SCB. */
c->scb->tlvs->shachain = &c->their_shachain.chain;
towire_scb_chan_with_tlvs(&scb, c->scb);

towire_scb_chan(&scb, c->scb);
json_add_hex_talarr(response, fieldname,
scb);
}
Expand Down
6 changes: 3 additions & 3 deletions lightningd/test/run-invoice-select-inchan.c
Original file line number Diff line number Diff line change
Expand Up @@ -1021,9 +1021,9 @@ u8 *towire_onchaind_dev_memleak(const tal_t *ctx UNNEEDED)
/* Generated stub for towire_openingd_dev_memleak */
u8 *towire_openingd_dev_memleak(const tal_t *ctx UNNEEDED)
{ fprintf(stderr, "towire_openingd_dev_memleak 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_scb_chan_with_tlvs */
void towire_scb_chan_with_tlvs(u8 **p UNNEEDED, const struct scb_chan_with_tlvs *scb_chan_with_tlvs UNNEEDED)
{ fprintf(stderr, "towire_scb_chan_with_tlvs called!\n"); abort(); }
/* Generated stub for towire_warningfmt */
u8 *towire_warningfmt(const tal_t *ctx UNNEEDED,
const struct channel_id *channel UNNEEDED,
Expand Down
2 changes: 1 addition & 1 deletion plugins/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -223,7 +223,7 @@ plugins/pay: $(PLUGIN_PAY_OBJS) $(PLUGIN_LIB_OBJS) $(PLUGIN_PAY_LIB_OBJS) $(PLUG

plugins/autoclean: $(PLUGIN_AUTOCLEAN_OBJS) $(PLUGIN_LIB_OBJS) $(PLUGIN_COMMON_OBJS) $(JSMN_OBJS)

plugins/chanbackup: $(PLUGIN_chanbackup_OBJS) $(PLUGIN_LIB_OBJS) $(PLUGIN_COMMON_OBJS) $(JSMN_OBJS) common/scb_wiregen.o wire/channel_type_wiregen.o
plugins/chanbackup: $(PLUGIN_chanbackup_OBJS) $(PLUGIN_LIB_OBJS) $(PLUGIN_COMMON_OBJS) $(JSMN_OBJS) common/scb_wiregen.o wire/channel_type_wiregen.o common/htlc_wire.o common/onionreply.o common/derive_basepoints.o

plugins/commando: $(PLUGIN_COMMANDO_OBJS) $(PLUGIN_LIB_OBJS) $(PLUGIN_COMMON_OBJS) $(JSMN_OBJS)

Expand Down
Loading
Loading