lightningd: respond with channel_reestablish if contacted about long-closed channels.
This may be useful for their recovery, though they should see the spend onchain. Signed-off-by: Rusty Russell <rusty@rustcorp.com.au> Changelog-Added: Protocol: We now reply to `channel_reestablish` even on long-closed channels.
This commit is contained in:
@@ -44,6 +44,7 @@
|
||||
#include <lightningd/channel.h>
|
||||
#include <lightningd/channel_control.h>
|
||||
#include <lightningd/channel_gossip.h>
|
||||
#include <lightningd/closed_channel.h>
|
||||
#include <lightningd/closing_control.h>
|
||||
#include <lightningd/connect_control.h>
|
||||
#include <lightningd/dual_open_control.h>
|
||||
@@ -1797,7 +1798,10 @@ void peer_connected(struct lightningd *ld, const u8 *msg)
|
||||
plugin_hook_call_peer_connected(ld, cmd_id, hook_payload);
|
||||
}
|
||||
|
||||
static void send_reestablish(struct lightningd *ld, struct channel *channel)
|
||||
static void send_reestablish(struct peer *peer,
|
||||
const struct channel_id *cid,
|
||||
const struct shachain *their_shachain,
|
||||
u64 local_next_index)
|
||||
{
|
||||
u8 *msg;
|
||||
struct secret last_remote_per_commit_secret;
|
||||
@@ -1810,30 +1814,42 @@ static void send_reestablish(struct lightningd *ld, struct channel *channel)
|
||||
* - MUST set `your_last_per_commitment_secret` to the last
|
||||
* `per_commitment_secret` it received
|
||||
*/
|
||||
num_revocations = revocations_received(&channel->their_shachain.chain);
|
||||
num_revocations = revocations_received(their_shachain);
|
||||
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,
|
||||
else if (!shachain_get_secret(their_shachain,
|
||||
num_revocations-1,
|
||||
&last_remote_per_commit_secret)) {
|
||||
channel_fail_permanent(channel,
|
||||
REASON_LOCAL,
|
||||
"Could not get revocation secret %"PRIu64,
|
||||
num_revocations-1);
|
||||
log_peer_broken(peer->ld->log, &peer->id,
|
||||
"%s: cannot get shachain secret %"PRIu64" to send reestablish",
|
||||
fmt_channel_id(tmpctx, cid), num_revocations-1);
|
||||
return;
|
||||
}
|
||||
|
||||
msg = towire_channel_reestablish(tmpctx, &channel->cid,
|
||||
channel->next_index[LOCAL],
|
||||
/* BOLT #2:
|
||||
* The sending node:
|
||||
* - MUST set `next_commitment_number` to the commitment number of the
|
||||
* next `commitment_signed` it expects to receive.
|
||||
* - MUST set `next_revocation_number` to the commitment number of the
|
||||
* next `revoke_and_ack` message it expects to receive.
|
||||
* - MUST set `my_current_per_commitment_point` to a valid point.
|
||||
* - if `next_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
|
||||
*/
|
||||
msg = towire_channel_reestablish(tmpctx, cid,
|
||||
local_next_index,
|
||||
num_revocations,
|
||||
&last_remote_per_commit_secret,
|
||||
&channel->channel_info.remote_per_commit,
|
||||
/* Any valid point works, since static_remotekey */
|
||||
&peer->ld->our_pubkey,
|
||||
/* No upgrade for you, since we're closed! */
|
||||
NULL);
|
||||
subd_send_msg(ld->connectd,
|
||||
take(towire_connectd_peer_send_msg(NULL, &channel->peer->id,
|
||||
channel->peer->connectd_counter,
|
||||
subd_send_msg(peer->ld->connectd,
|
||||
take(towire_connectd_peer_send_msg(NULL, &peer->id,
|
||||
peer->connectd_counter,
|
||||
msg)));
|
||||
}
|
||||
|
||||
@@ -1847,6 +1863,7 @@ void peer_spoke(struct lightningd *ld, const u8 *msg)
|
||||
u16 msgtype;
|
||||
u64 connectd_counter;
|
||||
struct channel *channel;
|
||||
struct closed_channel *closed_channel;
|
||||
struct channel_id channel_id;
|
||||
struct peer *peer;
|
||||
bool dual_fund;
|
||||
@@ -1885,7 +1902,9 @@ void peer_spoke(struct lightningd *ld, const u8 *msg)
|
||||
"Trouble in paradise?");
|
||||
goto send_error;
|
||||
}
|
||||
send_reestablish(ld, channel);
|
||||
send_reestablish(peer, &channel->cid,
|
||||
&channel->their_shachain.chain,
|
||||
channel->next_index[LOCAL]);
|
||||
}
|
||||
|
||||
/* If we have a canned error for this channel, send it now */
|
||||
@@ -1978,6 +1997,20 @@ void peer_spoke(struct lightningd *ld, const u8 *msg)
|
||||
/* FIXME: Send informative error? */
|
||||
close(other_fd);
|
||||
return;
|
||||
|
||||
case WIRE_CHANNEL_REESTABLISH:
|
||||
/* Maybe a previously closed channel? */
|
||||
closed_channel = closed_channel_map_get(peer->ld->closed_channels, &channel_id);
|
||||
if (closed_channel && closed_channel->their_shachain) {
|
||||
send_reestablish(peer, &closed_channel->cid,
|
||||
closed_channel->their_shachain,
|
||||
closed_channel->next_index[LOCAL]);
|
||||
log_peer_info(ld->log, &peer->id, "Responded to reestablish for long-closed channel %s",
|
||||
fmt_channel_id(tmpctx, &channel_id));
|
||||
error = towire_errorfmt(tmpctx, &channel_id,
|
||||
"Channel is closed and forgotten");
|
||||
goto send_error;
|
||||
}
|
||||
}
|
||||
|
||||
/* Weird message? Log and reply with error. */
|
||||
|
||||
@@ -362,6 +362,9 @@ u32 get_feerate(const struct fee_states *fee_states UNNEEDED,
|
||||
enum side opener UNNEEDED,
|
||||
enum side side UNNEEDED)
|
||||
{ fprintf(stderr, "get_feerate called!\n"); abort(); }
|
||||
/* Generated stub for hash_cid */
|
||||
size_t hash_cid(const struct channel_id *cid UNNEEDED)
|
||||
{ fprintf(stderr, "hash_cid called!\n"); abort(); }
|
||||
/* Generated stub for hash_htlc_key */
|
||||
size_t hash_htlc_key(const struct htlc_key *htlc_key UNNEEDED)
|
||||
{ fprintf(stderr, "hash_htlc_key called!\n"); abort(); }
|
||||
|
||||
Reference in New Issue
Block a user