mirror of
https://github.com/ElementsProject/lightning.git
synced 2025-03-01 17:47:30 +01:00
lightningd: message for channeld to tell us that channel risks penalty.
For option_data_loss_protect, the peer can prove to us that it's ahead; it gives us the (hopefully honest!) per_commitment_point it will use, and we make sure we don't broadcast the commitment transaction we have. Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
This commit is contained in:
parent
18297a173c
commit
43156643b4
6 changed files with 60 additions and 6 deletions
|
@ -2309,6 +2309,7 @@ static void req_in(struct peer *peer, const u8 *msg)
|
||||||
case WIRE_CHANNEL_GOT_SHUTDOWN:
|
case WIRE_CHANNEL_GOT_SHUTDOWN:
|
||||||
case WIRE_CHANNEL_SHUTDOWN_COMPLETE:
|
case WIRE_CHANNEL_SHUTDOWN_COMPLETE:
|
||||||
case WIRE_CHANNEL_DEV_REENABLE_COMMIT_REPLY:
|
case WIRE_CHANNEL_DEV_REENABLE_COMMIT_REPLY:
|
||||||
|
case WIRE_CHANNEL_FAIL_FALLEN_BEHIND:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
master_badmsg(-1, msg);
|
master_badmsg(-1, msg);
|
||||||
|
|
|
@ -165,3 +165,8 @@ channel_feerates,1027
|
||||||
channel_feerates,,feerate,u32
|
channel_feerates,,feerate,u32
|
||||||
channel_feerates,,min_feerate,u32
|
channel_feerates,,min_feerate,u32
|
||||||
channel_feerates,,max_feerate,u32
|
channel_feerates,,max_feerate,u32
|
||||||
|
|
||||||
|
# Peer presented proof it was from the future.
|
||||||
|
channel_fail_fallen_behind,1028
|
||||||
|
channel_fail_fallen_behind,,remote_per_commitment_point,struct pubkey
|
||||||
|
|
||||||
|
|
|
|
@ -231,6 +231,7 @@ struct channel *new_channel(struct peer *peer, u64 dbid,
|
||||||
channel->connected = connected;
|
channel->connected = connected;
|
||||||
channel->local_basepoints = *local_basepoints;
|
channel->local_basepoints = *local_basepoints;
|
||||||
channel->local_funding_pubkey = *local_funding_pubkey;
|
channel->local_funding_pubkey = *local_funding_pubkey;
|
||||||
|
channel->future_per_commitment_point = NULL;
|
||||||
|
|
||||||
list_add_tail(&peer->channels, &channel->list);
|
list_add_tail(&peer->channels, &channel->list);
|
||||||
tal_add_destructor(channel, destroy_channel);
|
tal_add_destructor(channel, destroy_channel);
|
||||||
|
|
|
@ -105,6 +105,10 @@ struct channel {
|
||||||
|
|
||||||
/* Does gossipd need to know if the owner dies? (ie. not onchaind) */
|
/* Does gossipd need to know if the owner dies? (ie. not onchaind) */
|
||||||
bool connected;
|
bool connected;
|
||||||
|
|
||||||
|
/* Do we have an "impossible" future per_commitment_point from
|
||||||
|
* peer via option_data_loss_protect? */
|
||||||
|
struct pubkey *future_per_commitment_point;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct channel *new_channel(struct peer *peer, u64 dbid,
|
struct channel *new_channel(struct peer *peer, u64 dbid,
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
#include <common/memleak.h>
|
#include <common/memleak.h>
|
||||||
#include <common/timeout.h>
|
#include <common/timeout.h>
|
||||||
#include <common/utils.h>
|
#include <common/utils.h>
|
||||||
|
#include <common/wire_error.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <gossipd/gossip_constants.h>
|
#include <gossipd/gossip_constants.h>
|
||||||
#include <hsmd/gen_hsm_client_wire.h>
|
#include <hsmd/gen_hsm_client_wire.h>
|
||||||
|
@ -101,6 +102,32 @@ static void peer_got_shutdown(struct channel *channel, const u8 *msg)
|
||||||
wallet_channel_save(ld->wallet, channel);
|
wallet_channel_save(ld->wallet, channel);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void channel_fail_fallen_behind(struct channel *channel, const u8 *msg)
|
||||||
|
{
|
||||||
|
struct pubkey per_commitment_point;
|
||||||
|
struct channel_id cid;
|
||||||
|
|
||||||
|
if (!fromwire_channel_fail_fallen_behind(msg, &per_commitment_point)) {
|
||||||
|
channel_internal_error(channel,
|
||||||
|
"bad channel_fail_fallen_behind %s",
|
||||||
|
tal_hex(tmpctx, msg));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* FIXME: Save in db! */
|
||||||
|
channel->future_per_commitment_point
|
||||||
|
= tal_dup(channel, struct pubkey, &per_commitment_point);
|
||||||
|
|
||||||
|
/* We don't fail yet, since we want daemon to send them an error
|
||||||
|
* to trigger rebroadcasting. But make sure we set error now in
|
||||||
|
* case something else goes wrong! */
|
||||||
|
derive_channel_id(&cid,
|
||||||
|
&channel->funding_txid,
|
||||||
|
channel->funding_outnum);
|
||||||
|
channel->error = towire_errorfmt(channel, &cid,
|
||||||
|
"Catastrophic failure: please close channel");
|
||||||
|
}
|
||||||
|
|
||||||
static void peer_start_closingd_after_shutdown(struct channel *channel,
|
static void peer_start_closingd_after_shutdown(struct channel *channel,
|
||||||
const u8 *msg,
|
const u8 *msg,
|
||||||
const int *fds)
|
const int *fds)
|
||||||
|
@ -147,6 +174,9 @@ static unsigned channel_msg(struct subd *sd, const u8 *msg, const int *fds)
|
||||||
return 2;
|
return 2;
|
||||||
peer_start_closingd_after_shutdown(sd->channel, msg, fds);
|
peer_start_closingd_after_shutdown(sd->channel, msg, fds);
|
||||||
break;
|
break;
|
||||||
|
case WIRE_CHANNEL_FAIL_FALLEN_BEHIND:
|
||||||
|
channel_fail_fallen_behind(sd->channel, msg);
|
||||||
|
break;
|
||||||
|
|
||||||
/* And we never get these from channeld. */
|
/* And we never get these from channeld. */
|
||||||
case WIRE_CHANNEL_INIT:
|
case WIRE_CHANNEL_INIT:
|
||||||
|
|
|
@ -370,15 +370,28 @@ register_close_command(struct lightningd *ld,
|
||||||
void drop_to_chain(struct lightningd *ld, struct channel *channel,
|
void drop_to_chain(struct lightningd *ld, struct channel *channel,
|
||||||
bool cooperative)
|
bool cooperative)
|
||||||
{
|
{
|
||||||
sign_last_tx(channel);
|
/* BOLT #2:
|
||||||
|
*
|
||||||
|
* - if `next_remote_revocation_number` is greater than expected
|
||||||
|
* above, AND `your_last_per_commitment_secret` is correct for that
|
||||||
|
* `next_remote_revocation_number` minus 1:
|
||||||
|
* - MUST NOT broadcast its commitment transaction.
|
||||||
|
*/
|
||||||
|
if (channel->future_per_commitment_point && !cooperative) {
|
||||||
|
log_broken(channel->log,
|
||||||
|
"Cannot broadcast our commitment tx:"
|
||||||
|
" they have a future one");
|
||||||
|
} else {
|
||||||
|
sign_last_tx(channel);
|
||||||
|
|
||||||
/* Keep broadcasting until we say stop (can fail due to dup,
|
/* Keep broadcasting until we say stop (can fail due to dup,
|
||||||
* if they beat us to the broadcast). */
|
* if they beat us to the broadcast). */
|
||||||
broadcast_tx(ld->topology, channel, channel->last_tx, NULL);
|
broadcast_tx(ld->topology, channel, channel->last_tx, NULL);
|
||||||
|
|
||||||
|
remove_sig(channel->last_tx);
|
||||||
|
}
|
||||||
|
|
||||||
resolve_close_command(ld, channel, cooperative);
|
resolve_close_command(ld, channel, cooperative);
|
||||||
|
|
||||||
remove_sig(channel->last_tx);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void channel_errmsg(struct channel *channel,
|
void channel_errmsg(struct channel *channel,
|
||||||
|
|
Loading…
Add table
Reference in a new issue