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 8 commits into
base: master
Choose a base branch
from
13 changes: 13 additions & 0 deletions common/scb_wire.csv
Original file line number Diff line number Diff line change
@@ -1,10 +1,22 @@
#include <ccan/crypto/shachain/shachain.h>
#include <common/node_id.h>
#include <common/channel_id.h>
#include <common/htlc_wire.h>
#include <common/wireaddr.h>
#include <common/channel_type.h>
#include <common/derive_basepoints.h>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: list these alphabetically?

#include <common/amount.h>
#include <bitcoin/tx.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
subtypedata,scb_chan,id,u64,
Expand All @@ -15,6 +27,7 @@ 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,
Expand Down
10 changes: 9 additions & 1 deletion lightningd/channel.c
Original file line number Diff line number Diff line change
Expand Up @@ -482,6 +482,7 @@ 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) {
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
8 changes: 8 additions & 0 deletions lightningd/dual_open_control.c
Original file line number Diff line number Diff line change
Expand Up @@ -1470,6 +1470,14 @@ wallet_commit_channel(struct lightningd *ld,
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
54 changes: 45 additions & 9 deletions lightningd/opening_control.c
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

for commit 53b16a0, it looks like a keyword got omitted from the commit message

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 @@ -1465,9 +1469,13 @@ static struct channel *stub_chan(struct command *cmd,
struct pubkey localFundingPubkey;
struct pubkey pk;
struct short_channel_id *scid;
u32 blockht;
u32 blockht = 0;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why set this here? it doesn't look like it got used again in this commit

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 Down Expand Up @@ -1636,6 +1647,8 @@ 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;

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

Expand All @@ -1644,6 +1657,25 @@ static struct command_result *json_recoverchannel(struct command *cmd,
continue;
}

if (scb_chan->tlvs->shachain == NULL) {
shachain_init(&chain);
} else {
log_debug(cmd->ld->log, "shachain is not null yayyy");
chain = *scb_chan->tlvs->shachain;
}

if (scb_chan->tlvs->basepoints == NULL) {
struct pubkey _localfundingpubkey;
get_channel_basepoints(cmd->ld,
&scb_chan->node_id,
scb_chan->id,
&basepoints,
&_localfundingpubkey);
} else {
log_debug(cmd->ld->log, "basepoints is not null yayyy");
basepoints = *scb_chan->tlvs->basepoints;
}

struct lightningd *ld = cmd->ld;
struct channel *channel= stub_chan(cmd,
scb_chan->id,
Expand All @@ -1652,7 +1684,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,
scb_chan->tlvs->opener == NULL ? LOCAL : *scb_chan->tlvs->opener,
scb_chan->tlvs->remote_to_self_delay == NULL ? 0 : *scb_chan->tlvs->remote_to_self_delay);

/* Returns NULL only when channel already exists, so we skip over it. */
if (channel == NULL)
Expand Down
2 changes: 2 additions & 0 deletions lightningd/peer_control.c
Original file line number Diff line number Diff line change
Expand Up @@ -2368,6 +2368,8 @@ static void json_add_scb(struct command *cmd,
{
u8 *scb = tal_arr(cmd, u8, 0);

// Update shachain in SCB.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: comments are of form /* Update shachain in SCB. */

c->scb->tlvs->shachain = &c->their_shachain.chain;
towire_scb_chan(&scb, c->scb);
json_add_hex_talarr(response, fieldname,
scb);
Expand Down
2 changes: 1 addition & 1 deletion plugins/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -219,7 +219,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
48 changes: 40 additions & 8 deletions plugins/chanbackup.c
Original file line number Diff line number Diff line change
Expand Up @@ -401,6 +401,17 @@ struct info {
size_t idx;
};

/* We refresh scb from both channel_state_changed notification and
on_commitment_revocation hook. Both have to be terminated
differently. */
static struct command_result *notification_or_hook_done(struct command *cmd)
{
if (cmd->type == COMMAND_TYPE_NOTIFICATION)
return notification_handled(cmd);
assert(cmd->type == COMMAND_TYPE_HOOK);
return command_hook_success(cmd);
}

static struct command_result *after_send_scb_single(struct command *cmd,
const char *method,
const char *buf,
Expand All @@ -411,7 +422,7 @@ static struct command_result *after_send_scb_single(struct command *cmd,
if (--info->idx != 0)
return command_still_pending(cmd);

return notification_handled(cmd);
return notification_or_hook_done(cmd);
}

static struct command_result *after_send_scb_single_fail(struct command *cmd,
Expand All @@ -424,7 +435,7 @@ static struct command_result *after_send_scb_single_fail(struct command *cmd,
if (--info->idx != 0)
return command_still_pending(cmd);

return notification_handled(cmd);
return notification_or_hook_done(cmd);
}

static struct command_result *after_listpeers(struct command *cmd,
Expand All @@ -441,7 +452,7 @@ static struct command_result *after_listpeers(struct command *cmd,
u8 *serialise_scb;

if (!peer_backup)
return notification_handled(cmd);
return notification_or_hook_done(cmd);

serialise_scb = towire_peer_storage(cmd,
get_file_data(tmpctx, cmd->plugin));
Expand Down Expand Up @@ -485,7 +496,7 @@ static struct command_result *after_listpeers(struct command *cmd,
}

if (info->idx == 0)
return notification_handled(cmd);
return notification_or_hook_done(cmd);
return command_still_pending(cmd);
}

Expand All @@ -507,7 +518,7 @@ static struct command_result *after_staticbackup(struct command *cmd,
req = jsonrpc_request_start(cmd,
"listpeers",
after_listpeers,
&forward_error,
plugin_broken_cb,
info);
return send_outreq(req);
}
Expand All @@ -528,13 +539,13 @@ static struct command_result *json_state_changed(struct command *cmd,
req = jsonrpc_request_start(cmd,
"staticbackup",
after_staticbackup,
&forward_error,
log_broken_and_complete,
NULL);

return send_outreq(req);
}

return notification_handled(cmd);
return notification_or_hook_done(cmd);
}


Expand Down Expand Up @@ -776,6 +787,23 @@ static struct command_result *json_getemergencyrecoverdata(struct command *cmd,
return command_finished(cmd, response);
}

static struct command_result *on_commitment_revocation(struct command *cmd,
const char *buf,
const jsmntok_t *params)
{
struct out_req *req;

plugin_log(cmd->plugin, LOG_DBG, "Updated `emergency.recover` state after receiving new commitment secret.");

req = jsonrpc_request_start(cmd,
"staticbackup",
after_staticbackup,
log_broken_and_complete,
NULL);

return send_outreq(req);
}

static const char *init(struct command *init_cmd,
const char *buf UNUSED,
const jsmntok_t *config UNUSED)
Expand Down Expand Up @@ -817,7 +845,7 @@ static const struct plugin_notification notifs[] = {
{
"channel_state_changed",
json_state_changed,
}
},
};

static const struct plugin_hook hooks[] = {
Expand All @@ -829,6 +857,10 @@ static const struct plugin_hook hooks[] = {
"peer_connected",
peer_connected,
},
{
"commitment_revocation",
on_commitment_revocation,
}
};

static const struct plugin_command commands[] = {
Expand Down
Loading
Loading