mirror of
https://github.com/aljazceru/lightning.git
synced 2025-12-19 15:14:23 +01:00
closingd: send option_dataloss_protect fields when reestablishing.
Travis caught an error where this happened: when closingd reconnects it was sending the reestablish message without the option_dataloss_protect fields. That causes the peer to fail the channel! Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
This commit is contained in:
committed by
neil saitug
parent
4811024518
commit
13b5047a31
@@ -25,6 +25,8 @@ changes.
|
|||||||
|
|
||||||
### Fixed
|
### Fixed
|
||||||
|
|
||||||
|
- protocol: reconnection during closing negotiation now supports
|
||||||
|
`option_data_loss_protect` properly.
|
||||||
- `--bind-addr=<path>` fixed for nodes using local sockets (eg. testing).
|
- `--bind-addr=<path>` fixed for nodes using local sockets (eg. testing).
|
||||||
- Unannounced local channels were forgotten for routing on restart until reconnection occurred.
|
- Unannounced local channels were forgotten for routing on restart until reconnection occurred.
|
||||||
|
|
||||||
|
|||||||
@@ -27,6 +27,7 @@ closing_init,,channel_reestablish_len,u16
|
|||||||
closing_init,,channel_reestablish,channel_reestablish_len*u8
|
closing_init,,channel_reestablish,channel_reestablish_len*u8
|
||||||
closing_init,,final_scriptpubkey_len,u16
|
closing_init,,final_scriptpubkey_len,u16
|
||||||
closing_init,,final_scriptpubkey,final_scriptpubkey_len*u8
|
closing_init,,final_scriptpubkey,final_scriptpubkey_len*u8
|
||||||
|
closing_init,,last_remote_secret,struct secret
|
||||||
|
|
||||||
# We received an offer, save signature.
|
# We received an offer, save signature.
|
||||||
closing_received_signature,2002
|
closing_received_signature,2002
|
||||||
|
|||||||
|
@@ -112,11 +112,36 @@ static void do_reconnect(struct crypto_state *cs,
|
|||||||
const u64 next_index[NUM_SIDES],
|
const u64 next_index[NUM_SIDES],
|
||||||
u64 revocations_received,
|
u64 revocations_received,
|
||||||
const u8 *channel_reestablish,
|
const u8 *channel_reestablish,
|
||||||
const u8 *final_scriptpubkey)
|
const u8 *final_scriptpubkey,
|
||||||
|
const struct secret *last_remote_per_commit_secret)
|
||||||
{
|
{
|
||||||
u8 *msg;
|
u8 *msg;
|
||||||
struct channel_id their_channel_id;
|
struct channel_id their_channel_id;
|
||||||
u64 next_local_commitment_number, next_remote_revocation_number;
|
u64 next_local_commitment_number, next_remote_revocation_number;
|
||||||
|
struct pubkey my_current_per_commitment_point;
|
||||||
|
struct secret *s;
|
||||||
|
|
||||||
|
/* Our current per-commitment point is the commitment point in the last
|
||||||
|
* received signed commitment; HSM gives us that and the previous
|
||||||
|
* secret (which we don't need). */
|
||||||
|
msg = towire_hsm_get_per_commitment_point(NULL,
|
||||||
|
next_index[LOCAL]-1);
|
||||||
|
if (!wire_sync_write(HSM_FD, take(msg)))
|
||||||
|
status_failed(STATUS_FAIL_HSM_IO,
|
||||||
|
"Writing get_per_commitment_point to HSM: %s",
|
||||||
|
strerror(errno));
|
||||||
|
|
||||||
|
msg = wire_sync_read(tmpctx, HSM_FD);
|
||||||
|
if (!msg)
|
||||||
|
status_failed(STATUS_FAIL_HSM_IO,
|
||||||
|
"Reading resp get_per_commitment_point reply: %s",
|
||||||
|
strerror(errno));
|
||||||
|
if (!fromwire_hsm_get_per_commitment_point_reply(tmpctx, msg,
|
||||||
|
&my_current_per_commitment_point,
|
||||||
|
&s))
|
||||||
|
status_failed(STATUS_FAIL_HSM_IO,
|
||||||
|
"Bad per_commitment_point reply %s",
|
||||||
|
tal_hex(tmpctx, msg));
|
||||||
|
|
||||||
/* BOLT #2:
|
/* BOLT #2:
|
||||||
*
|
*
|
||||||
@@ -135,9 +160,14 @@ static void do_reconnect(struct crypto_state *cs,
|
|||||||
* - MUST set `next_remote_revocation_number` to the commitment number
|
* - MUST set `next_remote_revocation_number` to the commitment number
|
||||||
* of the next `revoke_and_ack` message it expects to receive.
|
* of the next `revoke_and_ack` message it expects to receive.
|
||||||
*/
|
*/
|
||||||
msg = towire_channel_reestablish(NULL, channel_id,
|
|
||||||
|
/* We're always allowed to send extra fields, so we send dataloss_protect
|
||||||
|
* even if we didn't negotiate it */
|
||||||
|
msg = towire_channel_reestablish_option_data_loss_protect(NULL, channel_id,
|
||||||
next_index[LOCAL],
|
next_index[LOCAL],
|
||||||
revocations_received);
|
revocations_received,
|
||||||
|
last_remote_per_commit_secret,
|
||||||
|
&my_current_per_commitment_point);
|
||||||
sync_crypto_write(cs, PEER_FD, take(msg));
|
sync_crypto_write(cs, PEER_FD, take(msg));
|
||||||
|
|
||||||
/* They might have already send reestablish, which triggered us */
|
/* They might have already send reestablish, which triggered us */
|
||||||
@@ -509,6 +539,7 @@ int main(int argc, char *argv[])
|
|||||||
u64 next_index[NUM_SIDES], revocations_received;
|
u64 next_index[NUM_SIDES], revocations_received;
|
||||||
enum side whose_turn;
|
enum side whose_turn;
|
||||||
u8 *channel_reestablish;
|
u8 *channel_reestablish;
|
||||||
|
struct secret last_remote_per_commit_secret;
|
||||||
|
|
||||||
subdaemon_setup(argc, argv);
|
subdaemon_setup(argc, argv);
|
||||||
|
|
||||||
@@ -534,7 +565,8 @@ int main(int argc, char *argv[])
|
|||||||
&next_index[REMOTE],
|
&next_index[REMOTE],
|
||||||
&revocations_received,
|
&revocations_received,
|
||||||
&channel_reestablish,
|
&channel_reestablish,
|
||||||
&final_scriptpubkey))
|
&final_scriptpubkey,
|
||||||
|
&last_remote_per_commit_secret))
|
||||||
master_badmsg(WIRE_CLOSING_INIT, msg);
|
master_badmsg(WIRE_CLOSING_INIT, msg);
|
||||||
|
|
||||||
status_trace("out = %s/%s",
|
status_trace("out = %s/%s",
|
||||||
@@ -553,7 +585,8 @@ int main(int argc, char *argv[])
|
|||||||
if (reconnected)
|
if (reconnected)
|
||||||
do_reconnect(&cs, &channel_id,
|
do_reconnect(&cs, &channel_id,
|
||||||
next_index, revocations_received,
|
next_index, revocations_received,
|
||||||
channel_reestablish, final_scriptpubkey);
|
channel_reestablish, final_scriptpubkey,
|
||||||
|
&last_remote_per_commit_secret);
|
||||||
|
|
||||||
/* We don't need this any more */
|
/* We don't need this any more */
|
||||||
tal_free(final_scriptpubkey);
|
tal_free(final_scriptpubkey);
|
||||||
|
|||||||
@@ -159,6 +159,7 @@ void peer_start_closingd(struct channel *channel,
|
|||||||
u64 num_revocations;
|
u64 num_revocations;
|
||||||
struct amount_msat their_msat;
|
struct amount_msat their_msat;
|
||||||
int hsmfd;
|
int hsmfd;
|
||||||
|
struct secret last_remote_per_commit_secret;
|
||||||
struct lightningd *ld = channel->peer->ld;
|
struct lightningd *ld = channel->peer->ld;
|
||||||
|
|
||||||
if (!channel->remote_shutdown_scriptpubkey) {
|
if (!channel->remote_shutdown_scriptpubkey) {
|
||||||
@@ -168,7 +169,8 @@ void peer_start_closingd(struct channel *channel,
|
|||||||
}
|
}
|
||||||
|
|
||||||
hsmfd = hsm_get_client_fd(ld, &channel->peer->id, channel->dbid,
|
hsmfd = hsm_get_client_fd(ld, &channel->peer->id, channel->dbid,
|
||||||
HSM_CAP_SIGN_CLOSING_TX);
|
HSM_CAP_SIGN_CLOSING_TX
|
||||||
|
| HSM_CAP_COMMITMENT_POINT);
|
||||||
|
|
||||||
channel_set_owner(channel,
|
channel_set_owner(channel,
|
||||||
new_channel_subd(ld,
|
new_channel_subd(ld,
|
||||||
@@ -235,6 +237,27 @@ void peer_start_closingd(struct channel *channel,
|
|||||||
channel_fail_permanent(channel, "our_msat overflow on closing");
|
channel_fail_permanent(channel, "our_msat overflow on closing");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* BOLT #2:
|
||||||
|
*
|
||||||
|
* - if it supports `option_data_loss_protect`:
|
||||||
|
* - if `next_remote_revocation_number` equals 0:
|
||||||
|
* - MUST set `your_last_per_commitment_secret` to all zeroes
|
||||||
|
* - otherwise:
|
||||||
|
* - MUST set `your_last_per_commitment_secret` to the last
|
||||||
|
* `per_commitment_secret` it received
|
||||||
|
*/
|
||||||
|
if (num_revocations == 0)
|
||||||
|
memset(&last_remote_per_commit_secret, 0,
|
||||||
|
sizeof(last_remote_per_commit_secret));
|
||||||
|
else if (!shachain_get_secret(&channel->their_shachain.chain,
|
||||||
|
num_revocations-1,
|
||||||
|
&last_remote_per_commit_secret)) {
|
||||||
|
channel_fail_permanent(channel,
|
||||||
|
"Could not get revocation secret %"PRIu64,
|
||||||
|
num_revocations-1);
|
||||||
|
return;
|
||||||
|
}
|
||||||
initmsg = towire_closing_init(tmpctx,
|
initmsg = towire_closing_init(tmpctx,
|
||||||
cs,
|
cs,
|
||||||
&channel->funding_txid,
|
&channel->funding_txid,
|
||||||
@@ -256,7 +279,8 @@ void peer_start_closingd(struct channel *channel,
|
|||||||
num_revocations,
|
num_revocations,
|
||||||
channel_reestablish,
|
channel_reestablish,
|
||||||
p2wpkh_for_keyidx(tmpctx, ld,
|
p2wpkh_for_keyidx(tmpctx, ld,
|
||||||
channel->final_key_idx));
|
channel->final_key_idx),
|
||||||
|
&last_remote_per_commit_secret);
|
||||||
|
|
||||||
/* We don't expect a response: it will give us feedback on
|
/* We don't expect a response: it will give us feedback on
|
||||||
* signatures sent and received, then closing_complete. */
|
* signatures sent and received, then closing_complete. */
|
||||||
|
|||||||
Reference in New Issue
Block a user