Skip to content

Commit

Permalink
closingd: add support for handling wrong_funding.
Browse files Browse the repository at this point in the history
Signed-off-by: Rusty Russell <[email protected]>
  • Loading branch information
rustyrussell committed Mar 16, 2021
1 parent 820fbcd commit 1cfb7b8
Show file tree
Hide file tree
Showing 7 changed files with 134 additions and 65 deletions.
13 changes: 13 additions & 0 deletions bitcoin/tx.c
Original file line number Diff line number Diff line change
Expand Up @@ -399,6 +399,19 @@ void bitcoin_tx_input_get_txid(const struct bitcoin_tx *tx, int innum,
wally_tx_input_get_txid(&tx->wtx->inputs[innum], out);
}

void bitcoin_tx_input_set_txid(struct bitcoin_tx *tx, int innum,
const struct bitcoin_txid *txid,
u32 index)
{
struct wally_tx_input *in;
assert(innum < tx->wtx->num_inputs);

in = &tx->wtx->inputs[innum];
BUILD_ASSERT(sizeof(struct bitcoin_txid) == sizeof(in->txhash));
memcpy(in->txhash, txid, sizeof(struct bitcoin_txid));
in->index = index;
}

void wally_tx_input_get_txid(const struct wally_tx_input *in,
struct bitcoin_txid *txid)
{
Expand Down
7 changes: 7 additions & 0 deletions bitcoin/tx.h
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,13 @@ void bitcoin_tx_input_get_txid(const struct bitcoin_tx *tx, int innum,
void wally_tx_input_get_txid(const struct wally_tx_input *in,
struct bitcoin_txid *txid);

/**
* Overwrite the txhash and index in the wally_tx_input
*/
void bitcoin_tx_input_set_txid(struct bitcoin_tx *tx, int innum,
const struct bitcoin_txid *txid,
u32 index);

/**
* Check a transaction for consistency.
*
Expand Down
105 changes: 70 additions & 35 deletions closingd/closingd.c
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,8 @@ static struct bitcoin_tx *close_tx(const tal_t *ctx,
const struct amount_sat out[NUM_SIDES],
enum side opener,
struct amount_sat fee,
struct amount_sat dust_limit)
struct amount_sat dust_limit,
const struct bitcoin_outpoint *wrong_funding)
{
struct bitcoin_tx *tx;
struct amount_sat out_minus_fee[NUM_SIDES];
Expand Down Expand Up @@ -88,6 +89,12 @@ static struct bitcoin_tx *close_tx(const tal_t *ctx,
type_to_string(tmpctx, struct amount_sat, &dust_limit),
type_to_string(tmpctx, struct amount_sat, &out[LOCAL]),
type_to_string(tmpctx, struct amount_sat, &out[REMOTE]));

if (wrong_funding)
bitcoin_tx_input_set_txid(tx, 0,
&wrong_funding->txid,
wrong_funding->n);

return tx;
}

Expand Down Expand Up @@ -148,13 +155,15 @@ static void do_reconnect(struct per_peer_state *pps,
u64 revocations_received,
const u8 *channel_reestablish,
const u8 *final_scriptpubkey,
const struct secret *last_remote_per_commit_secret)
const struct secret *last_remote_per_commit_secret,
const struct bitcoin_outpoint *wrong_funding)
{
u8 *msg;
struct channel_id their_channel_id;
u64 next_local_commitment_number, next_remote_revocation_number;
struct pubkey my_current_per_commitment_point, next_commitment_point;
struct secret their_secret;
struct tlv_shutdown_tlvs *tlvs;

my_current_per_commitment_point = get_per_commitment_point(next_index[LOCAL]-1);

Expand Down Expand Up @@ -218,8 +227,16 @@ static void do_reconnect(struct per_peer_state *pps,
* - if it has sent a previous `shutdown`:
* - MUST retransmit `shutdown`.
*/
/* FIXME: retransmit wrong_funding */
msg = towire_shutdown(NULL, channel_id, final_scriptpubkey, NULL);
if (wrong_funding) {
tlvs = tlv_shutdown_tlvs_new(tmpctx);
tlvs->wrong_funding
= tal(tlvs, struct tlv_shutdown_tlvs_wrong_funding);
tlvs->wrong_funding->txid = wrong_funding->txid;
tlvs->wrong_funding->outnum = wrong_funding->n;
} else
tlvs = NULL;

msg = towire_shutdown(NULL, channel_id, final_scriptpubkey, tlvs);
sync_crypto_write(pps, take(msg));

/* BOLT #2:
Expand Down Expand Up @@ -250,7 +267,8 @@ static void send_offer(struct per_peer_state *pps,
const struct amount_sat out[NUM_SIDES],
enum side opener,
struct amount_sat our_dust_limit,
struct amount_sat fee_to_offer)
struct amount_sat fee_to_offer,
const struct bitcoin_outpoint *wrong_funding)
{
struct bitcoin_tx *tx;
struct bitcoin_signature our_sig;
Expand All @@ -269,7 +287,8 @@ static void send_offer(struct per_peer_state *pps,
funding,
funding_wscript,
out,
opener, fee_to_offer, our_dust_limit);
opener, fee_to_offer, our_dust_limit,
wrong_funding);

/* BOLT #3:
*
Expand Down Expand Up @@ -329,6 +348,7 @@ receive_offer(struct per_peer_state *pps,
enum side opener,
struct amount_sat our_dust_limit,
struct amount_sat min_fee_to_accept,
const struct bitcoin_outpoint *wrong_funding,
struct bitcoin_txid *closing_txid)
{
u8 *msg;
Expand Down Expand Up @@ -379,7 +399,8 @@ receive_offer(struct per_peer_state *pps,
funding_txout,
funding,
funding_wscript,
out, opener, received_fee, our_dust_limit);
out, opener, received_fee, our_dust_limit,
wrong_funding);

if (!check_tx_sig(tx, 0, NULL, funding_wscript,
&funding_pubkey[REMOTE], &their_sig)) {
Expand Down Expand Up @@ -410,7 +431,8 @@ receive_offer(struct per_peer_state *pps,
funding,
funding_wscript,
trimming_out,
opener, received_fee, our_dust_limit);
opener, received_fee, our_dust_limit,
wrong_funding);
if (!trimmed
|| !check_tx_sig(trimmed, 0, NULL, funding_wscript,
&funding_pubkey[REMOTE], &their_sig)) {
Expand Down Expand Up @@ -619,37 +641,39 @@ int main(int argc, char *argv[])
enum side whose_turn;
u8 *channel_reestablish;
struct secret last_remote_per_commit_secret;
struct bitcoin_outpoint *wrong_funding;

subdaemon_setup(argc, argv);

status_setup_sync(REQ_FD);

msg = wire_sync_read(tmpctx, REQ_FD);
if (!fromwire_closingd_init(ctx, msg,
&chainparams,
&pps,
&channel_id,
&funding_txid, &funding_txout,
&funding,
&funding_pubkey[LOCAL],
&funding_pubkey[REMOTE],
&opener,
&out[LOCAL],
&out[REMOTE],
&our_dust_limit,
&min_fee_to_accept, &commitment_fee,
&offer[LOCAL],
&scriptpubkey[LOCAL],
&scriptpubkey[REMOTE],
&fee_negotiation_step,
&fee_negotiation_step_unit,
&reconnected,
&next_index[LOCAL],
&next_index[REMOTE],
&revocations_received,
&channel_reestablish,
&last_remote_per_commit_secret,
&dev_fast_gossip))
&chainparams,
&pps,
&channel_id,
&funding_txid, &funding_txout,
&funding,
&funding_pubkey[LOCAL],
&funding_pubkey[REMOTE],
&opener,
&out[LOCAL],
&out[REMOTE],
&our_dust_limit,
&min_fee_to_accept, &commitment_fee,
&offer[LOCAL],
&scriptpubkey[LOCAL],
&scriptpubkey[REMOTE],
&fee_negotiation_step,
&fee_negotiation_step_unit,
&reconnected,
&next_index[LOCAL],
&next_index[REMOTE],
&revocations_received,
&channel_reestablish,
&last_remote_per_commit_secret,
&dev_fast_gossip,
&wrong_funding))
master_badmsg(WIRE_CLOSINGD_INIT, msg);

/* stdin == requests, 3 == peer, 4 = gossip, 5 = gossip_store, 6 = hsmd */
Expand All @@ -670,6 +694,11 @@ int main(int argc, char *argv[])
status_debug("fee = %s",
type_to_string(tmpctx, struct amount_sat, &offer[LOCAL]));
status_debug("fee negotiation step = %s", fee_negotiation_step_str);
if (wrong_funding)
status_unusual("Setting wrong_funding_txid to %s:%u",
type_to_string(tmpctx, struct bitcoin_txid,
&wrong_funding->txid),
wrong_funding->n);

funding_wscript = bitcoin_redeem_2of2(ctx,
&funding_pubkey[LOCAL],
Expand All @@ -679,7 +708,8 @@ int main(int argc, char *argv[])
do_reconnect(pps, &channel_id,
next_index, revocations_received,
channel_reestablish, scriptpubkey[LOCAL],
&last_remote_per_commit_secret);
&last_remote_per_commit_secret,
wrong_funding);

peer_billboard(
true,
Expand All @@ -705,7 +735,8 @@ int main(int argc, char *argv[])
scriptpubkey, &funding_txid, funding_txout,
funding, out, opener,
our_dust_limit,
offer[LOCAL]);
offer[LOCAL],
wrong_funding);
} else {
if (i == 0)
peer_billboard(false, "Waiting for their initial"
Expand All @@ -726,6 +757,7 @@ int main(int argc, char *argv[])
out, opener,
our_dust_limit,
min_fee_to_accept,
wrong_funding,
&closing_txid);
}
}
Expand Down Expand Up @@ -754,7 +786,8 @@ int main(int argc, char *argv[])
scriptpubkey, &funding_txid, funding_txout,
funding, out, opener,
our_dust_limit,
offer[LOCAL]);
offer[LOCAL],
wrong_funding);
} else {
peer_billboard(false, "Waiting for another"
" closing fee offer:"
Expand All @@ -770,6 +803,7 @@ int main(int argc, char *argv[])
out, opener,
our_dust_limit,
min_fee_to_accept,
wrong_funding,
&closing_txid);
}

Expand All @@ -782,6 +816,7 @@ int main(int argc, char *argv[])

#if DEVELOPER
/* We don't listen for master commands, so always check memleak here */
tal_free(wrong_funding);
closing_dev_memleak(ctx, scriptpubkey, funding_wscript);
#endif

Expand Down
1 change: 1 addition & 0 deletions closingd/closingd_wire.csv
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ msgdata,closingd_init,channel_reestablish_len,u16,
msgdata,closingd_init,channel_reestablish,u8,channel_reestablish_len
msgdata,closingd_init,last_remote_secret,secret,
msgdata,closingd_init,dev_fast_gossip,bool,
msgdata,closingd_init,shutdown_wrong_funding,?bitcoin_outpoint,

# We received an offer, save signature.
msgtype,closingd_received_signature,2002
Expand Down
18 changes: 15 additions & 3 deletions closingd/closingd_wiregen.c

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 3 additions & 3 deletions closingd/closingd_wiregen.h

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

49 changes: 25 additions & 24 deletions lightningd/closing_control.c
Original file line number Diff line number Diff line change
Expand Up @@ -286,30 +286,31 @@ void peer_start_closingd(struct channel *channel,
return;
}
initmsg = towire_closingd_init(tmpctx,
chainparams,
pps,
&channel->cid,
&channel->funding_txid,
channel->funding_outnum,
channel->funding,
&channel->local_funding_pubkey,
&channel->channel_info.remote_fundingkey,
channel->opener,
amount_msat_to_sat_round_down(channel->our_msat),
amount_msat_to_sat_round_down(their_msat),
channel->our_config.dust_limit,
minfee, feelimit, startfee,
channel->shutdown_scriptpubkey[LOCAL],
channel->shutdown_scriptpubkey[REMOTE],
channel->closing_fee_negotiation_step,
channel->closing_fee_negotiation_step_unit,
reconnected,
channel->next_index[LOCAL],
channel->next_index[REMOTE],
num_revocations,
channel_reestablish,
&last_remote_per_commit_secret,
IFDEV(ld->dev_fast_gossip, false));
chainparams,
pps,
&channel->cid,
&channel->funding_txid,
channel->funding_outnum,
channel->funding,
&channel->local_funding_pubkey,
&channel->channel_info.remote_fundingkey,
channel->opener,
amount_msat_to_sat_round_down(channel->our_msat),
amount_msat_to_sat_round_down(their_msat),
channel->our_config.dust_limit,
minfee, feelimit, startfee,
channel->shutdown_scriptpubkey[LOCAL],
channel->shutdown_scriptpubkey[REMOTE],
channel->closing_fee_negotiation_step,
channel->closing_fee_negotiation_step_unit,
reconnected,
channel->next_index[LOCAL],
channel->next_index[REMOTE],
num_revocations,
channel_reestablish,
&last_remote_per_commit_secret,
IFDEV(ld->dev_fast_gossip, false),
channel->shutdown_wrong_funding);

/* We don't expect a response: it will give us feedback on
* signatures sent and received, then closing_complete. */
Expand Down

0 comments on commit 1cfb7b8

Please sign in to comment.