diff --git a/channeld/channeld.c b/channeld/channeld.c index 305de7e9eb34..d37cd96b7454 100644 --- a/channeld/channeld.c +++ b/channeld/channeld.c @@ -918,6 +918,15 @@ static void maybe_send_shutdown(struct peer *peer) billboard_update(peer); } +static void send_shutdown_complete(struct peer *peer) +{ + /* Now we can tell master shutdown is complete. */ + wire_sync_write(MASTER_FD, + take(towire_channeld_shutdown_complete(NULL, peer->pps))); + per_peer_state_fdpass_send(MASTER_FD, peer->pps); + close(MASTER_FD); +} + /* This queues other traffic from the fd until we get reply. */ static u8 *master_wait_sync_reply(const tal_t *ctx, struct peer *peer, @@ -2511,7 +2520,8 @@ static bool capture_premature_msg(const u8 ***shit_lnd_says, const u8 *msg) } static void peer_reconnect(struct peer *peer, - const struct secret *last_remote_per_commit_secret) + const struct secret *last_remote_per_commit_secret, + u8 *reestablish_only) { struct channel_id channel_id; /* Note: BOLT #2 uses these names! */ @@ -2636,6 +2646,13 @@ static void peer_reconnect(struct peer *peer, bool soft_error = peer->funding_locked[REMOTE] || peer->funding_locked[LOCAL]; + /* If they sent reestablish, we analyze it for courtesy, but also + * in case *they* are ahead of us! */ + if (reestablish_only) { + msg = reestablish_only; + goto got_reestablish; + } + /* Read until they say something interesting (don't forward * gossip *to* them yet: we might try sending channel_update * before we've reestablished channel). */ @@ -2647,6 +2664,7 @@ static void peer_reconnect(struct peer *peer, msg) || capture_premature_msg(&premature_msgs, msg)); +got_reestablish: #if EXPERIMENTAL_FEATURES recv_tlvs = tlv_channel_reestablish_tlvs_new(tmpctx); #endif @@ -2668,6 +2686,15 @@ static void peer_reconnect(struct peer *peer, tal_hex(msg, msg)); } + if (!channel_id_eq(&channel_id, &peer->channel_id)) { + peer_failed_err(peer->pps, + &channel_id, + "bad reestablish msg for unknown channel %s: %s", + type_to_string(tmpctx, struct channel_id, + &channel_id), + tal_hex(msg, msg)); + } + status_debug("Got reestablish commit=%"PRIu64" revoke=%"PRIu64, next_commitment_number, next_revocation_number); @@ -2910,6 +2937,19 @@ static void peer_reconnect(struct peer *peer, #endif /* EXPERIMENTAL_FEATURES */ + /* Now stop, we've been polite long enough. */ + if (reestablish_only) { + /* If we were successfully closing, we still go to closingd. */ + if (shutdown_complete(peer)) { + send_shutdown_complete(peer); + daemon_shutdown(); + exit(0); + } + peer_failed_err(peer->pps, + &peer->channel_id, + "Channel is already closed"); + } + /* Corner case: we didn't send shutdown before because update_add_htlc * pending, but now they're cleared by restart, and we're actually * complete. In that case, their `shutdown` will trigger us. */ @@ -3400,6 +3440,7 @@ static void init_channel(struct peer *peer) secp256k1_ecdsa_signature *remote_ann_bitcoin_sig; bool option_static_remotekey, option_anchor_outputs; struct penalty_base *pbases; + u8 *reestablish_only; #if !DEVELOPER bool dev_fail_process_onionpacket; /* Ignored */ #endif @@ -3461,7 +3502,8 @@ static void init_channel(struct peer *peer) &option_anchor_outputs, &dev_fast_gossip, &dev_fail_process_onionpacket, - &pbases)) { + &pbases, + &reestablish_only)) { master_badmsg(WIRE_CHANNELD_INIT, msg); } @@ -3553,7 +3595,10 @@ static void init_channel(struct peer *peer) /* OK, now we can process peer messages. */ if (reconnected) - peer_reconnect(peer, &last_remote_per_commit_secret); + peer_reconnect(peer, &last_remote_per_commit_secret, + reestablish_only); + else + assert(!reestablish_only); /* If we have a messages to send, send them immediately */ if (fwd_msg) @@ -3565,15 +3610,6 @@ static void init_channel(struct peer *peer) billboard_update(peer); } -static void send_shutdown_complete(struct peer *peer) -{ - /* Now we can tell master shutdown is complete. */ - wire_sync_write(MASTER_FD, - take(towire_channeld_shutdown_complete(NULL, peer->pps))); - per_peer_state_fdpass_send(MASTER_FD, peer->pps); - close(MASTER_FD); -} - static void try_read_gossip_store(struct peer *peer) { u8 *msg = gossip_store_next(tmpctx, peer->pps); diff --git a/channeld/channeld_wire.csv b/channeld/channeld_wire.csv index 8af0756a34a1..7fd521e2140c 100644 --- a/channeld/channeld_wire.csv +++ b/channeld/channeld_wire.csv @@ -73,6 +73,8 @@ msgdata,channeld_init,dev_fast_gossip,bool, msgdata,channeld_init,dev_fail_process_onionpacket,bool, msgdata,channeld_init,num_penalty_bases,u32, msgdata,channeld_init,pbases,penalty_base,num_penalty_bases +msgdata,channeld_init,reestablish_only_len,u16, +msgdata,channeld_init,reestablish_only,u8,reestablish_only_len # master->channeld funding hit new depth(funding locked if >= lock depth) msgtype,channeld_funding_depth,1002 diff --git a/channeld/channeld_wiregen.c b/channeld/channeld_wiregen.c index 0a4d375bc327..44ef1f31b943 100644 --- a/channeld/channeld_wiregen.c +++ b/channeld/channeld_wiregen.c @@ -98,7 +98,7 @@ bool channeld_wire_is_defined(u16 type) /* WIRE: CHANNELD_INIT */ /* Begin! (passes gossipd-client fd) */ -u8 *towire_channeld_init(const tal_t *ctx, const struct chainparams *chainparams, const struct feature_set *our_features, const struct channel_id *channel_id, const struct bitcoin_txid *funding_txid, u16 funding_txout, struct amount_sat funding_satoshi, u32 minimum_depth, const struct channel_config *our_config, const struct channel_config *their_config, const struct fee_states *fee_states, u32 feerate_min, u32 feerate_max, u32 feerate_penalty, const struct bitcoin_signature *first_commit_sig, const struct per_peer_state *per_peer_state, const struct pubkey *remote_fundingkey, const struct basepoints *remote_basepoints, const struct pubkey *remote_per_commit, const struct pubkey *old_remote_per_commit, enum side opener, u32 fee_base, u32 fee_proportional, struct amount_msat local_msatoshi, const struct basepoints *our_basepoints, const struct pubkey *our_funding_pubkey, const struct node_id *local_node_id, const struct node_id *remote_node_id, u32 commit_msec, u16 cltv_delta, bool last_was_revoke, const struct changed_htlc *last_sent_commit, u64 next_index_local, u64 next_index_remote, u64 revocations_received, u64 next_htlc_id, const struct existing_htlc **htlcs, bool local_funding_locked, bool remote_funding_locked, const struct short_channel_id *funding_short_id, bool reestablish, bool send_shutdown, bool remote_shutdown_received, const u8 *final_scriptpubkey, u8 flags, const u8 *init_peer_pkt, bool reached_announce_depth, const struct secret *last_remote_secret, const u8 *their_features, const u8 *upfront_shutdown_script, const secp256k1_ecdsa_signature *remote_ann_node_sig, const secp256k1_ecdsa_signature *remote_ann_bitcoin_sig, bool option_static_remotekey, bool option_anchor_outputs, bool dev_fast_gossip, bool dev_fail_process_onionpacket, const struct penalty_base *pbases) +u8 *towire_channeld_init(const tal_t *ctx, const struct chainparams *chainparams, const struct feature_set *our_features, const struct channel_id *channel_id, const struct bitcoin_txid *funding_txid, u16 funding_txout, struct amount_sat funding_satoshi, u32 minimum_depth, const struct channel_config *our_config, const struct channel_config *their_config, const struct fee_states *fee_states, u32 feerate_min, u32 feerate_max, u32 feerate_penalty, const struct bitcoin_signature *first_commit_sig, const struct per_peer_state *per_peer_state, const struct pubkey *remote_fundingkey, const struct basepoints *remote_basepoints, const struct pubkey *remote_per_commit, const struct pubkey *old_remote_per_commit, enum side opener, u32 fee_base, u32 fee_proportional, struct amount_msat local_msatoshi, const struct basepoints *our_basepoints, const struct pubkey *our_funding_pubkey, const struct node_id *local_node_id, const struct node_id *remote_node_id, u32 commit_msec, u16 cltv_delta, bool last_was_revoke, const struct changed_htlc *last_sent_commit, u64 next_index_local, u64 next_index_remote, u64 revocations_received, u64 next_htlc_id, const struct existing_htlc **htlcs, bool local_funding_locked, bool remote_funding_locked, const struct short_channel_id *funding_short_id, bool reestablish, bool send_shutdown, bool remote_shutdown_received, const u8 *final_scriptpubkey, u8 flags, const u8 *init_peer_pkt, bool reached_announce_depth, const struct secret *last_remote_secret, const u8 *their_features, const u8 *upfront_shutdown_script, const secp256k1_ecdsa_signature *remote_ann_node_sig, const secp256k1_ecdsa_signature *remote_ann_bitcoin_sig, bool option_static_remotekey, bool option_anchor_outputs, bool dev_fast_gossip, bool dev_fail_process_onionpacket, const struct penalty_base *pbases, const u8 *reestablish_only) { u16 num_last_sent_commit = tal_count(last_sent_commit); u16 num_existing_htlcs = tal_count(htlcs); @@ -107,6 +107,7 @@ u8 *towire_channeld_init(const tal_t *ctx, const struct chainparams *chainparams u16 flen = tal_count(their_features); u16 upfront_shutdown_script_len = tal_count(upfront_shutdown_script); u32 num_penalty_bases = tal_count(pbases); + u16 reestablish_only_len = tal_count(reestablish_only); u8 *p = tal_arr(ctx, u8, 0); towire_u16(&p, WIRE_CHANNELD_INIT); @@ -186,10 +187,12 @@ u8 *towire_channeld_init(const tal_t *ctx, const struct chainparams *chainparams towire_u32(&p, num_penalty_bases); for (size_t i = 0; i < num_penalty_bases; i++) towire_penalty_base(&p, pbases + i); + towire_u16(&p, reestablish_only_len); + towire_u8_array(&p, reestablish_only, reestablish_only_len); return memcheck(p, tal_count(p)); } -bool fromwire_channeld_init(const tal_t *ctx, const void *p, const struct chainparams **chainparams, struct feature_set **our_features, struct channel_id *channel_id, struct bitcoin_txid *funding_txid, u16 *funding_txout, struct amount_sat *funding_satoshi, u32 *minimum_depth, struct channel_config *our_config, struct channel_config *their_config, struct fee_states **fee_states, u32 *feerate_min, u32 *feerate_max, u32 *feerate_penalty, struct bitcoin_signature *first_commit_sig, struct per_peer_state **per_peer_state, struct pubkey *remote_fundingkey, struct basepoints *remote_basepoints, struct pubkey *remote_per_commit, struct pubkey *old_remote_per_commit, enum side *opener, u32 *fee_base, u32 *fee_proportional, struct amount_msat *local_msatoshi, struct basepoints *our_basepoints, struct pubkey *our_funding_pubkey, struct node_id *local_node_id, struct node_id *remote_node_id, u32 *commit_msec, u16 *cltv_delta, bool *last_was_revoke, struct changed_htlc **last_sent_commit, u64 *next_index_local, u64 *next_index_remote, u64 *revocations_received, u64 *next_htlc_id, struct existing_htlc ***htlcs, bool *local_funding_locked, bool *remote_funding_locked, struct short_channel_id *funding_short_id, bool *reestablish, bool *send_shutdown, bool *remote_shutdown_received, u8 **final_scriptpubkey, u8 *flags, u8 **init_peer_pkt, bool *reached_announce_depth, struct secret *last_remote_secret, u8 **their_features, u8 **upfront_shutdown_script, secp256k1_ecdsa_signature **remote_ann_node_sig, secp256k1_ecdsa_signature **remote_ann_bitcoin_sig, bool *option_static_remotekey, bool *option_anchor_outputs, bool *dev_fast_gossip, bool *dev_fail_process_onionpacket, struct penalty_base **pbases) +bool fromwire_channeld_init(const tal_t *ctx, const void *p, const struct chainparams **chainparams, struct feature_set **our_features, struct channel_id *channel_id, struct bitcoin_txid *funding_txid, u16 *funding_txout, struct amount_sat *funding_satoshi, u32 *minimum_depth, struct channel_config *our_config, struct channel_config *their_config, struct fee_states **fee_states, u32 *feerate_min, u32 *feerate_max, u32 *feerate_penalty, struct bitcoin_signature *first_commit_sig, struct per_peer_state **per_peer_state, struct pubkey *remote_fundingkey, struct basepoints *remote_basepoints, struct pubkey *remote_per_commit, struct pubkey *old_remote_per_commit, enum side *opener, u32 *fee_base, u32 *fee_proportional, struct amount_msat *local_msatoshi, struct basepoints *our_basepoints, struct pubkey *our_funding_pubkey, struct node_id *local_node_id, struct node_id *remote_node_id, u32 *commit_msec, u16 *cltv_delta, bool *last_was_revoke, struct changed_htlc **last_sent_commit, u64 *next_index_local, u64 *next_index_remote, u64 *revocations_received, u64 *next_htlc_id, struct existing_htlc ***htlcs, bool *local_funding_locked, bool *remote_funding_locked, struct short_channel_id *funding_short_id, bool *reestablish, bool *send_shutdown, bool *remote_shutdown_received, u8 **final_scriptpubkey, u8 *flags, u8 **init_peer_pkt, bool *reached_announce_depth, struct secret *last_remote_secret, u8 **their_features, u8 **upfront_shutdown_script, secp256k1_ecdsa_signature **remote_ann_node_sig, secp256k1_ecdsa_signature **remote_ann_bitcoin_sig, bool *option_static_remotekey, bool *option_anchor_outputs, bool *dev_fast_gossip, bool *dev_fail_process_onionpacket, struct penalty_base **pbases, u8 **reestablish_only) { u16 num_last_sent_commit; u16 num_existing_htlcs; @@ -198,6 +201,7 @@ bool fromwire_channeld_init(const tal_t *ctx, const void *p, const struct chainp u16 flen; u16 upfront_shutdown_script_len; u32 num_penalty_bases; + u16 reestablish_only_len; const u8 *cursor = p; size_t plen = tal_count(p); @@ -294,6 +298,10 @@ bool fromwire_channeld_init(const tal_t *ctx, const void *p, const struct chainp *pbases = num_penalty_bases ? tal_arr(ctx, struct penalty_base, num_penalty_bases) : NULL; for (size_t i = 0; i < num_penalty_bases; i++) fromwire_penalty_base(&cursor, &plen, *pbases + i); + reestablish_only_len = fromwire_u16(&cursor, &plen); + // 2nd case reestablish_only + *reestablish_only = reestablish_only_len ? tal_arr(ctx, u8, reestablish_only_len) : NULL; + fromwire_u8_array(&cursor, &plen, *reestablish_only, reestablish_only_len); return cursor != NULL; } @@ -1137,4 +1145,4 @@ bool fromwire_channeld_upgraded(const void *p, bool *option_static_remotekey) *option_static_remotekey = fromwire_bool(&cursor, &plen); return cursor != NULL; } -// SHA256STAMP:2d7b763e89512ad8c5921b90c13f37ac83ab0016384c38e8c8e831683d668651 +// SHA256STAMP:d67a5e23adc6362c93c60fcf3e4a46ccb1804dff1f10ec9a8d361ba9c548bb12 diff --git a/channeld/channeld_wiregen.h b/channeld/channeld_wiregen.h index 3dde409668f6..c41ea9353582 100644 --- a/channeld/channeld_wiregen.h +++ b/channeld/channeld_wiregen.h @@ -91,8 +91,8 @@ bool channeld_wire_is_defined(u16 type); /* WIRE: CHANNELD_INIT */ /* Begin! (passes gossipd-client fd) */ -u8 *towire_channeld_init(const tal_t *ctx, const struct chainparams *chainparams, const struct feature_set *our_features, const struct channel_id *channel_id, const struct bitcoin_txid *funding_txid, u16 funding_txout, struct amount_sat funding_satoshi, u32 minimum_depth, const struct channel_config *our_config, const struct channel_config *their_config, const struct fee_states *fee_states, u32 feerate_min, u32 feerate_max, u32 feerate_penalty, const struct bitcoin_signature *first_commit_sig, const struct per_peer_state *per_peer_state, const struct pubkey *remote_fundingkey, const struct basepoints *remote_basepoints, const struct pubkey *remote_per_commit, const struct pubkey *old_remote_per_commit, enum side opener, u32 fee_base, u32 fee_proportional, struct amount_msat local_msatoshi, const struct basepoints *our_basepoints, const struct pubkey *our_funding_pubkey, const struct node_id *local_node_id, const struct node_id *remote_node_id, u32 commit_msec, u16 cltv_delta, bool last_was_revoke, const struct changed_htlc *last_sent_commit, u64 next_index_local, u64 next_index_remote, u64 revocations_received, u64 next_htlc_id, const struct existing_htlc **htlcs, bool local_funding_locked, bool remote_funding_locked, const struct short_channel_id *funding_short_id, bool reestablish, bool send_shutdown, bool remote_shutdown_received, const u8 *final_scriptpubkey, u8 flags, const u8 *init_peer_pkt, bool reached_announce_depth, const struct secret *last_remote_secret, const u8 *their_features, const u8 *upfront_shutdown_script, const secp256k1_ecdsa_signature *remote_ann_node_sig, const secp256k1_ecdsa_signature *remote_ann_bitcoin_sig, bool option_static_remotekey, bool option_anchor_outputs, bool dev_fast_gossip, bool dev_fail_process_onionpacket, const struct penalty_base *pbases); -bool fromwire_channeld_init(const tal_t *ctx, const void *p, const struct chainparams **chainparams, struct feature_set **our_features, struct channel_id *channel_id, struct bitcoin_txid *funding_txid, u16 *funding_txout, struct amount_sat *funding_satoshi, u32 *minimum_depth, struct channel_config *our_config, struct channel_config *their_config, struct fee_states **fee_states, u32 *feerate_min, u32 *feerate_max, u32 *feerate_penalty, struct bitcoin_signature *first_commit_sig, struct per_peer_state **per_peer_state, struct pubkey *remote_fundingkey, struct basepoints *remote_basepoints, struct pubkey *remote_per_commit, struct pubkey *old_remote_per_commit, enum side *opener, u32 *fee_base, u32 *fee_proportional, struct amount_msat *local_msatoshi, struct basepoints *our_basepoints, struct pubkey *our_funding_pubkey, struct node_id *local_node_id, struct node_id *remote_node_id, u32 *commit_msec, u16 *cltv_delta, bool *last_was_revoke, struct changed_htlc **last_sent_commit, u64 *next_index_local, u64 *next_index_remote, u64 *revocations_received, u64 *next_htlc_id, struct existing_htlc ***htlcs, bool *local_funding_locked, bool *remote_funding_locked, struct short_channel_id *funding_short_id, bool *reestablish, bool *send_shutdown, bool *remote_shutdown_received, u8 **final_scriptpubkey, u8 *flags, u8 **init_peer_pkt, bool *reached_announce_depth, struct secret *last_remote_secret, u8 **their_features, u8 **upfront_shutdown_script, secp256k1_ecdsa_signature **remote_ann_node_sig, secp256k1_ecdsa_signature **remote_ann_bitcoin_sig, bool *option_static_remotekey, bool *option_anchor_outputs, bool *dev_fast_gossip, bool *dev_fail_process_onionpacket, struct penalty_base **pbases); +u8 *towire_channeld_init(const tal_t *ctx, const struct chainparams *chainparams, const struct feature_set *our_features, const struct channel_id *channel_id, const struct bitcoin_txid *funding_txid, u16 funding_txout, struct amount_sat funding_satoshi, u32 minimum_depth, const struct channel_config *our_config, const struct channel_config *their_config, const struct fee_states *fee_states, u32 feerate_min, u32 feerate_max, u32 feerate_penalty, const struct bitcoin_signature *first_commit_sig, const struct per_peer_state *per_peer_state, const struct pubkey *remote_fundingkey, const struct basepoints *remote_basepoints, const struct pubkey *remote_per_commit, const struct pubkey *old_remote_per_commit, enum side opener, u32 fee_base, u32 fee_proportional, struct amount_msat local_msatoshi, const struct basepoints *our_basepoints, const struct pubkey *our_funding_pubkey, const struct node_id *local_node_id, const struct node_id *remote_node_id, u32 commit_msec, u16 cltv_delta, bool last_was_revoke, const struct changed_htlc *last_sent_commit, u64 next_index_local, u64 next_index_remote, u64 revocations_received, u64 next_htlc_id, const struct existing_htlc **htlcs, bool local_funding_locked, bool remote_funding_locked, const struct short_channel_id *funding_short_id, bool reestablish, bool send_shutdown, bool remote_shutdown_received, const u8 *final_scriptpubkey, u8 flags, const u8 *init_peer_pkt, bool reached_announce_depth, const struct secret *last_remote_secret, const u8 *their_features, const u8 *upfront_shutdown_script, const secp256k1_ecdsa_signature *remote_ann_node_sig, const secp256k1_ecdsa_signature *remote_ann_bitcoin_sig, bool option_static_remotekey, bool option_anchor_outputs, bool dev_fast_gossip, bool dev_fail_process_onionpacket, const struct penalty_base *pbases, const u8 *reestablish_only); +bool fromwire_channeld_init(const tal_t *ctx, const void *p, const struct chainparams **chainparams, struct feature_set **our_features, struct channel_id *channel_id, struct bitcoin_txid *funding_txid, u16 *funding_txout, struct amount_sat *funding_satoshi, u32 *minimum_depth, struct channel_config *our_config, struct channel_config *their_config, struct fee_states **fee_states, u32 *feerate_min, u32 *feerate_max, u32 *feerate_penalty, struct bitcoin_signature *first_commit_sig, struct per_peer_state **per_peer_state, struct pubkey *remote_fundingkey, struct basepoints *remote_basepoints, struct pubkey *remote_per_commit, struct pubkey *old_remote_per_commit, enum side *opener, u32 *fee_base, u32 *fee_proportional, struct amount_msat *local_msatoshi, struct basepoints *our_basepoints, struct pubkey *our_funding_pubkey, struct node_id *local_node_id, struct node_id *remote_node_id, u32 *commit_msec, u16 *cltv_delta, bool *last_was_revoke, struct changed_htlc **last_sent_commit, u64 *next_index_local, u64 *next_index_remote, u64 *revocations_received, u64 *next_htlc_id, struct existing_htlc ***htlcs, bool *local_funding_locked, bool *remote_funding_locked, struct short_channel_id *funding_short_id, bool *reestablish, bool *send_shutdown, bool *remote_shutdown_received, u8 **final_scriptpubkey, u8 *flags, u8 **init_peer_pkt, bool *reached_announce_depth, struct secret *last_remote_secret, u8 **their_features, u8 **upfront_shutdown_script, secp256k1_ecdsa_signature **remote_ann_node_sig, secp256k1_ecdsa_signature **remote_ann_bitcoin_sig, bool *option_static_remotekey, bool *option_anchor_outputs, bool *dev_fast_gossip, bool *dev_fail_process_onionpacket, struct penalty_base **pbases, u8 **reestablish_only); /* WIRE: CHANNELD_FUNDING_DEPTH */ /* master->channeld funding hit new depth(funding locked if >= lock depth) */ @@ -232,4 +232,4 @@ bool fromwire_channeld_upgraded(const void *p, bool *option_static_remotekey); #endif /* LIGHTNING_CHANNELD_CHANNELD_WIREGEN_H */ -// SHA256STAMP:2d7b763e89512ad8c5921b90c13f37ac83ab0016384c38e8c8e831683d668651 +// SHA256STAMP:d67a5e23adc6362c93c60fcf3e4a46ccb1804dff1f10ec9a8d361ba9c548bb12 diff --git a/closingd/closingd.c b/closingd/closingd.c index 1184b12a712a..6c95ab92679d 100644 --- a/closingd/closingd.c +++ b/closingd/closingd.c @@ -130,158 +130,6 @@ static u8 *closing_read_peer_msg(const tal_t *ctx, } } -static struct pubkey get_per_commitment_point(u64 commitment_number) -{ - u8 *msg; - struct pubkey 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_hsmd_get_per_commitment_point(NULL, - commitment_number); - 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_hsmd_get_per_commitment_point_reply(tmpctx, msg, - &commitment_point, - &s)) - status_failed(STATUS_FAIL_HSM_IO, - "Bad per_commitment_point reply %s", - tal_hex(tmpctx, msg)); - - return commitment_point; -} - -static void do_reconnect(struct per_peer_state *pps, - const struct channel_id *channel_id, - const u64 next_index[NUM_SIDES], - u64 revocations_received, - const u8 *channel_reestablish, - const u8 *final_scriptpubkey, - 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; -#if EXPERIMENTAL_FEATURES - struct tlv_channel_reestablish_tlvs *reestablish_tlvs = tlv_channel_reestablish_tlvs_new(tmpctx); -#endif - - my_current_per_commitment_point = get_per_commitment_point(next_index[LOCAL]-1); - - /* BOLT #2: - * - * - upon reconnection: - * - if a channel is in an error state: - * - SHOULD retransmit the error packet and ignore any other packets for - * that channel. - * - otherwise: - * - MUST transmit `channel_reestablish` for each channel. - * - MUST wait to receive the other node's `channel_reestablish` - * message before sending any other messages for that channel. - * - * 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. - */ - - msg = towire_channel_reestablish(NULL, channel_id, - next_index[LOCAL], - revocations_received, - last_remote_per_commit_secret, - &my_current_per_commitment_point -#if EXPERIMENTAL_FEATURES - , reestablish_tlvs -#endif - ); - sync_crypto_write(pps, take(msg)); - - /* They might have already sent reestablish, which triggered us */ - if (!channel_reestablish) { - do { - tal_free(channel_reestablish); - channel_reestablish = closing_read_peer_msg(tmpctx, pps, - channel_id); - /* They *should* send reestablish first, but lnd - * sends other messages, which we can ignore since - * we're closing anyway... */ - } while (fromwire_peektype(channel_reestablish) - != WIRE_CHANNEL_REESTABLISH); - } - -#if EXPERIMENTAL_FEATURES - reestablish_tlvs = tlv_channel_reestablish_tlvs_new(tmpctx); -#endif - - if (!fromwire_channel_reestablish(channel_reestablish, &their_channel_id, - &next_local_commitment_number, - &next_remote_revocation_number, - &their_secret, - &next_commitment_point -#if EXPERIMENTAL_FEATURES - , reestablish_tlvs -#endif - )) { - peer_failed_warn(pps, channel_id, - "bad reestablish msg: %s %s", - peer_wire_name(fromwire_peektype(channel_reestablish)), - tal_hex(tmpctx, channel_reestablish)); - } - status_debug("Got reestablish commit=%"PRIu64" revoke=%"PRIu64, - next_local_commitment_number, - next_remote_revocation_number); - - /* BOLT #2: - * - * A node: - *... - * - upon reconnection: - * - if it has sent a previous `shutdown`: - * - MUST retransmit `shutdown`. - */ - 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: - * - * A node: - *... - * - if `next_commitment_number` is 1 in both the `channel_reestablish` it sent and received: - * - MUST retransmit `funding_locked`. - */ - if (next_index[REMOTE] == 1 && next_index[LOCAL] == 1) { - status_debug("Retransmitting funding_locked for channel %s", - type_to_string(tmpctx, struct channel_id, channel_id)); - next_commitment_point = get_per_commitment_point(next_index[LOCAL]); - msg = towire_funding_locked(NULL, channel_id, &next_commitment_point); - sync_crypto_write(pps, take(msg)); - } -} - static void send_offer(struct per_peer_state *pps, const struct chainparams *chainparams, const struct channel_id *channel_id, @@ -663,11 +511,7 @@ int main(int argc, char *argv[]) u8 fee_negotiation_step_unit; char fee_negotiation_step_str[32]; /* fee_negotiation_step + "sat" */ struct channel_id channel_id; - bool reconnected; - u64 next_index[NUM_SIDES], revocations_received; enum side whose_turn; - u8 *channel_reestablish; - struct secret last_remote_per_commit_secret; struct bitcoin_outpoint *wrong_funding; subdaemon_setup(argc, argv); @@ -693,12 +537,6 @@ int main(int argc, char *argv[]) &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); @@ -731,13 +569,6 @@ int main(int argc, char *argv[]) &funding_pubkey[LOCAL], &funding_pubkey[REMOTE]); - if (reconnected) - do_reconnect(pps, &channel_id, - next_index, revocations_received, - channel_reestablish, scriptpubkey[LOCAL], - &last_remote_per_commit_secret, - wrong_funding); - peer_billboard( true, "Negotiating closing fee between %s and %s satoshi (ideal %s) " diff --git a/closingd/closingd_wire.csv b/closingd/closingd_wire.csv index c6f7ea07f5f3..4558c9a982d2 100644 --- a/closingd/closingd_wire.csv +++ b/closingd/closingd_wire.csv @@ -26,13 +26,6 @@ msgdata,closingd_init,remote_scriptpubkey_len,u16, msgdata,closingd_init,remote_scriptpubkey,u8,remote_scriptpubkey_len msgdata,closingd_init,fee_negotiation_step,u64, msgdata,closingd_init,fee_negotiation_step_unit,u8, -msgdata,closingd_init,reconnected,bool, -msgdata,closingd_init,next_index_local,u64, -msgdata,closingd_init,next_index_remote,u64, -msgdata,closingd_init,revocations_received,u64, -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, diff --git a/closingd/closingd_wiregen.c b/closingd/closingd_wiregen.c index d1a94dfb55f4..ca64732c0360 100644 --- a/closingd/closingd_wiregen.c +++ b/closingd/closingd_wiregen.c @@ -48,11 +48,10 @@ bool closingd_wire_is_defined(u16 type) /* WIRE: CLOSINGD_INIT */ /* Begin! (passes peer fd */ -u8 *towire_closingd_init(const tal_t *ctx, const struct chainparams *chainparams, const struct per_peer_state *pps, const struct channel_id *channel_id, const struct bitcoin_txid *funding_txid, u16 funding_txout, struct amount_sat funding_satoshi, const struct pubkey *local_fundingkey, const struct pubkey *remote_fundingkey, enum side opener, struct amount_sat local_sat, struct amount_sat remote_sat, struct amount_sat our_dust_limit, struct amount_sat min_fee_satoshi, struct amount_sat fee_limit_satoshi, struct amount_sat initial_fee_satoshi, const u8 *local_scriptpubkey, const u8 *remote_scriptpubkey, u64 fee_negotiation_step, u8 fee_negotiation_step_unit, bool reconnected, u64 next_index_local, u64 next_index_remote, u64 revocations_received, const u8 *channel_reestablish, const struct secret *last_remote_secret, bool dev_fast_gossip, const struct bitcoin_outpoint *shutdown_wrong_funding) +u8 *towire_closingd_init(const tal_t *ctx, const struct chainparams *chainparams, const struct per_peer_state *pps, const struct channel_id *channel_id, const struct bitcoin_txid *funding_txid, u16 funding_txout, struct amount_sat funding_satoshi, const struct pubkey *local_fundingkey, const struct pubkey *remote_fundingkey, enum side opener, struct amount_sat local_sat, struct amount_sat remote_sat, struct amount_sat our_dust_limit, struct amount_sat min_fee_satoshi, struct amount_sat fee_limit_satoshi, struct amount_sat initial_fee_satoshi, const u8 *local_scriptpubkey, const u8 *remote_scriptpubkey, u64 fee_negotiation_step, u8 fee_negotiation_step_unit, bool dev_fast_gossip, const struct bitcoin_outpoint *shutdown_wrong_funding) { u16 local_scriptpubkey_len = tal_count(local_scriptpubkey); u16 remote_scriptpubkey_len = tal_count(remote_scriptpubkey); - u16 channel_reestablish_len = tal_count(channel_reestablish); u8 *p = tal_arr(ctx, u8, 0); towire_u16(&p, WIRE_CLOSINGD_INIT); @@ -77,13 +76,6 @@ u8 *towire_closingd_init(const tal_t *ctx, const struct chainparams *chainparams towire_u8_array(&p, remote_scriptpubkey, remote_scriptpubkey_len); towire_u64(&p, fee_negotiation_step); towire_u8(&p, fee_negotiation_step_unit); - towire_bool(&p, reconnected); - towire_u64(&p, next_index_local); - towire_u64(&p, next_index_remote); - towire_u64(&p, revocations_received); - towire_u16(&p, channel_reestablish_len); - towire_u8_array(&p, channel_reestablish, channel_reestablish_len); - towire_secret(&p, last_remote_secret); towire_bool(&p, dev_fast_gossip); if (!shutdown_wrong_funding) towire_bool(&p, false); @@ -94,11 +86,10 @@ u8 *towire_closingd_init(const tal_t *ctx, const struct chainparams *chainparams return memcheck(p, tal_count(p)); } -bool fromwire_closingd_init(const tal_t *ctx, const void *p, const struct chainparams **chainparams, struct per_peer_state **pps, struct channel_id *channel_id, struct bitcoin_txid *funding_txid, u16 *funding_txout, struct amount_sat *funding_satoshi, struct pubkey *local_fundingkey, struct pubkey *remote_fundingkey, enum side *opener, struct amount_sat *local_sat, struct amount_sat *remote_sat, struct amount_sat *our_dust_limit, struct amount_sat *min_fee_satoshi, struct amount_sat *fee_limit_satoshi, struct amount_sat *initial_fee_satoshi, u8 **local_scriptpubkey, u8 **remote_scriptpubkey, u64 *fee_negotiation_step, u8 *fee_negotiation_step_unit, bool *reconnected, u64 *next_index_local, u64 *next_index_remote, u64 *revocations_received, u8 **channel_reestablish, struct secret *last_remote_secret, bool *dev_fast_gossip, struct bitcoin_outpoint **shutdown_wrong_funding) +bool fromwire_closingd_init(const tal_t *ctx, const void *p, const struct chainparams **chainparams, struct per_peer_state **pps, struct channel_id *channel_id, struct bitcoin_txid *funding_txid, u16 *funding_txout, struct amount_sat *funding_satoshi, struct pubkey *local_fundingkey, struct pubkey *remote_fundingkey, enum side *opener, struct amount_sat *local_sat, struct amount_sat *remote_sat, struct amount_sat *our_dust_limit, struct amount_sat *min_fee_satoshi, struct amount_sat *fee_limit_satoshi, struct amount_sat *initial_fee_satoshi, u8 **local_scriptpubkey, u8 **remote_scriptpubkey, u64 *fee_negotiation_step, u8 *fee_negotiation_step_unit, bool *dev_fast_gossip, struct bitcoin_outpoint **shutdown_wrong_funding) { u16 local_scriptpubkey_len; u16 remote_scriptpubkey_len; - u16 channel_reestablish_len; const u8 *cursor = p; size_t plen = tal_count(p); @@ -130,15 +121,6 @@ bool fromwire_closingd_init(const tal_t *ctx, const void *p, const struct chainp fromwire_u8_array(&cursor, &plen, *remote_scriptpubkey, remote_scriptpubkey_len); *fee_negotiation_step = fromwire_u64(&cursor, &plen); *fee_negotiation_step_unit = fromwire_u8(&cursor, &plen); - *reconnected = fromwire_bool(&cursor, &plen); - *next_index_local = fromwire_u64(&cursor, &plen); - *next_index_remote = fromwire_u64(&cursor, &plen); - *revocations_received = fromwire_u64(&cursor, &plen); - channel_reestablish_len = fromwire_u16(&cursor, &plen); - // 2nd case channel_reestablish - *channel_reestablish = channel_reestablish_len ? tal_arr(ctx, u8, channel_reestablish_len) : NULL; - fromwire_u8_array(&cursor, &plen, *channel_reestablish, channel_reestablish_len); - fromwire_secret(&cursor, &plen, last_remote_secret); *dev_fast_gossip = fromwire_bool(&cursor, &plen); if (!fromwire_bool(&cursor, &plen)) *shutdown_wrong_funding = NULL; @@ -213,4 +195,4 @@ bool fromwire_closingd_complete(const void *p) return false; return cursor != NULL; } -// SHA256STAMP:8a13df246be151bcef3dae15a9853016119248d330e76ab79d7013a11d5ecd23 +// SHA256STAMP:b08cf96b79e7a72bb574d0549148dd521d77834454a528fb13ee5b83d4942573 diff --git a/closingd/closingd_wiregen.h b/closingd/closingd_wiregen.h index 9f46a12b97fe..9d1eeb4046a6 100644 --- a/closingd/closingd_wiregen.h +++ b/closingd/closingd_wiregen.h @@ -37,8 +37,8 @@ bool closingd_wire_is_defined(u16 type); /* WIRE: CLOSINGD_INIT */ /* Begin! (passes peer fd */ -u8 *towire_closingd_init(const tal_t *ctx, const struct chainparams *chainparams, const struct per_peer_state *pps, const struct channel_id *channel_id, const struct bitcoin_txid *funding_txid, u16 funding_txout, struct amount_sat funding_satoshi, const struct pubkey *local_fundingkey, const struct pubkey *remote_fundingkey, enum side opener, struct amount_sat local_sat, struct amount_sat remote_sat, struct amount_sat our_dust_limit, struct amount_sat min_fee_satoshi, struct amount_sat fee_limit_satoshi, struct amount_sat initial_fee_satoshi, const u8 *local_scriptpubkey, const u8 *remote_scriptpubkey, u64 fee_negotiation_step, u8 fee_negotiation_step_unit, bool reconnected, u64 next_index_local, u64 next_index_remote, u64 revocations_received, const u8 *channel_reestablish, const struct secret *last_remote_secret, bool dev_fast_gossip, const struct bitcoin_outpoint *shutdown_wrong_funding); -bool fromwire_closingd_init(const tal_t *ctx, const void *p, const struct chainparams **chainparams, struct per_peer_state **pps, struct channel_id *channel_id, struct bitcoin_txid *funding_txid, u16 *funding_txout, struct amount_sat *funding_satoshi, struct pubkey *local_fundingkey, struct pubkey *remote_fundingkey, enum side *opener, struct amount_sat *local_sat, struct amount_sat *remote_sat, struct amount_sat *our_dust_limit, struct amount_sat *min_fee_satoshi, struct amount_sat *fee_limit_satoshi, struct amount_sat *initial_fee_satoshi, u8 **local_scriptpubkey, u8 **remote_scriptpubkey, u64 *fee_negotiation_step, u8 *fee_negotiation_step_unit, bool *reconnected, u64 *next_index_local, u64 *next_index_remote, u64 *revocations_received, u8 **channel_reestablish, struct secret *last_remote_secret, bool *dev_fast_gossip, struct bitcoin_outpoint **shutdown_wrong_funding); +u8 *towire_closingd_init(const tal_t *ctx, const struct chainparams *chainparams, const struct per_peer_state *pps, const struct channel_id *channel_id, const struct bitcoin_txid *funding_txid, u16 funding_txout, struct amount_sat funding_satoshi, const struct pubkey *local_fundingkey, const struct pubkey *remote_fundingkey, enum side opener, struct amount_sat local_sat, struct amount_sat remote_sat, struct amount_sat our_dust_limit, struct amount_sat min_fee_satoshi, struct amount_sat fee_limit_satoshi, struct amount_sat initial_fee_satoshi, const u8 *local_scriptpubkey, const u8 *remote_scriptpubkey, u64 fee_negotiation_step, u8 fee_negotiation_step_unit, bool dev_fast_gossip, const struct bitcoin_outpoint *shutdown_wrong_funding); +bool fromwire_closingd_init(const tal_t *ctx, const void *p, const struct chainparams **chainparams, struct per_peer_state **pps, struct channel_id *channel_id, struct bitcoin_txid *funding_txid, u16 *funding_txout, struct amount_sat *funding_satoshi, struct pubkey *local_fundingkey, struct pubkey *remote_fundingkey, enum side *opener, struct amount_sat *local_sat, struct amount_sat *remote_sat, struct amount_sat *our_dust_limit, struct amount_sat *min_fee_satoshi, struct amount_sat *fee_limit_satoshi, struct amount_sat *initial_fee_satoshi, u8 **local_scriptpubkey, u8 **remote_scriptpubkey, u64 *fee_negotiation_step, u8 *fee_negotiation_step_unit, bool *dev_fast_gossip, struct bitcoin_outpoint **shutdown_wrong_funding); /* WIRE: CLOSINGD_RECEIVED_SIGNATURE */ /* We received an offer */ @@ -56,4 +56,4 @@ bool fromwire_closingd_complete(const void *p); #endif /* LIGHTNING_CLOSINGD_CLOSINGD_WIREGEN_H */ -// SHA256STAMP:8a13df246be151bcef3dae15a9853016119248d330e76ab79d7013a11d5ecd23 +// SHA256STAMP:b08cf96b79e7a72bb574d0549148dd521d77834454a528fb13ee5b83d4942573 diff --git a/common/crypto_sync.c b/common/crypto_sync.c index e8f5f83212b2..c529de687169 100644 --- a/common/crypto_sync.c +++ b/common/crypto_sync.c @@ -17,7 +17,7 @@ void sync_crypto_write(struct per_peer_state *pps, const void *msg TAKES) { #if DEVELOPER - bool post_sabotage = false; + bool post_sabotage = false, post_close; int type = fromwire_peektype(msg); #endif u8 *enc; @@ -28,18 +28,23 @@ void sync_crypto_write(struct per_peer_state *pps, const void *msg TAKES) #if DEVELOPER switch (dev_disconnect(type)) { case DEV_DISCONNECT_BEFORE: - dev_sabotage_fd(pps->peer_fd); + dev_sabotage_fd(pps->peer_fd, true); peer_failed_connection_lost(); case DEV_DISCONNECT_DROPPKT: enc = tal_free(enc); /* FALL THRU */ case DEV_DISCONNECT_AFTER: post_sabotage = true; + post_close = true; break; case DEV_DISCONNECT_BLACKHOLE: dev_blackhole_fd(pps->peer_fd); break; case DEV_DISCONNECT_NORMAL: break; + case DEV_DISCONNECT_DISABLE_AFTER: + post_sabotage = true; + post_close = false; + break; } #endif if (!write_all(pps->peer_fd, enc, tal_count(enc))) @@ -48,7 +53,7 @@ void sync_crypto_write(struct per_peer_state *pps, const void *msg TAKES) #if DEVELOPER if (post_sabotage) - dev_sabotage_fd(pps->peer_fd); + dev_sabotage_fd(pps->peer_fd, post_close); #endif } diff --git a/common/dev_disconnect.c b/common/dev_disconnect.c index d55c7f029b3e..ab8302a29964 100644 --- a/common/dev_disconnect.c +++ b/common/dev_disconnect.c @@ -90,16 +90,13 @@ enum dev_disconnect dev_disconnect(int pkt_type) return dev_disconnect_line[0]; } -void dev_sabotage_fd(int fd) +void dev_sabotage_fd(int fd, bool close_fd) { int fds[2]; if (socketpair(AF_UNIX, SOCK_STREAM, 0, fds) != 0) err(1, "dev_sabotage_fd: creating socketpair"); - /* Close one. */ - close(fds[0]); - #if defined(TCP_NODELAY) /* On Linux, at least, this flushes. */ int opt = TCP_NODELAY; @@ -108,6 +105,16 @@ void dev_sabotage_fd(int fd) #else #error No TCP_NODELAY? #endif + + /* Move fd out the way if we don't want to close it. */ + if (!close_fd) { + if (dup(fd) == -1) { + ; /* -Wunused-result */ + } + } else + /* Close other end of socket. */ + close(fds[0]); + /* Move other over to the fd we want to sabotage. */ dup2(fds[1], fd); close(fds[1]); diff --git a/common/dev_disconnect.h b/common/dev_disconnect.h index 8760f35ee305..3c0f4b8973d4 100644 --- a/common/dev_disconnect.h +++ b/common/dev_disconnect.h @@ -15,13 +15,15 @@ enum dev_disconnect { DEV_DISCONNECT_DROPPKT = '@', /* Swallow all writes from now on, and do no more reads. */ DEV_DISCONNECT_BLACKHOLE = '0', + /* Don't use connection after sending packet, but don't close. */ + DEV_DISCONNECT_DISABLE_AFTER = 'x', }; /* Force a close fd before or after a certain packet type */ enum dev_disconnect dev_disconnect(int pkt_type); /* Make next write on fd fail as if they'd disconnected. */ -void dev_sabotage_fd(int fd); +void dev_sabotage_fd(int fd, bool close_fd); /* No more data to arrive, what's written is swallowed. */ void dev_blackhole_fd(int fd); diff --git a/common/read_peer_msg.c b/common/read_peer_msg.c index 2215c10643f9..6859be7cd073 100644 --- a/common/read_peer_msg.c +++ b/common/read_peer_msg.c @@ -162,7 +162,6 @@ bool handle_peer_gossip_or_error(struct per_peer_state *pps, { char *err; bool warning; - struct channel_id actual; #if DEVELOPER /* Any odd-typed unknown message is handled by the caller, so if we @@ -200,18 +199,6 @@ bool handle_peer_gossip_or_error(struct per_peer_state *pps, goto handled; } - /* They're talking about a different channel? */ - if (is_wrong_channel(msg, channel_id, &actual)) { - status_debug("Rejecting %s for unknown channel_id %s", - peer_wire_name(fromwire_peektype(msg)), - type_to_string(tmpctx, struct channel_id, &actual)); - sync_crypto_write(pps, - take(towire_errorfmt(NULL, &actual, - "Multiple channels" - " unsupported"))); - goto handled; - } - return false; handled: diff --git a/common/read_peer_msg.h b/common/read_peer_msg.h index 824c2ba3d518..698a11976a93 100644 --- a/common/read_peer_msg.h +++ b/common/read_peer_msg.h @@ -62,8 +62,8 @@ bool is_wrong_channel(const u8 *msg, const struct channel_id *expected, * @msg: the peer message (only taken if returns true). * * This returns true if it handled the packet: a gossip packet (forwarded - * to gossipd), an error packet (causes peer_failed_received_errmsg or - * ignored), or a message about the wrong channel (sends sync error reply). + * to gossipd), or an error packet (causes peer_failed_received_errmsg or + * ignored). */ bool handle_peer_gossip_or_error(struct per_peer_state *pps, const struct channel_id *channel_id, diff --git a/connectd/peer_exchange_initmsg.c b/connectd/peer_exchange_initmsg.c index f5e2dc24de19..f4aecacaf10a 100644 --- a/connectd/peer_exchange_initmsg.c +++ b/connectd/peer_exchange_initmsg.c @@ -132,7 +132,14 @@ static struct io_plan *read_init(struct io_conn *conn, struct peer *peer) static struct io_plan *peer_write_postclose(struct io_conn *conn, struct peer *peer) { - dev_sabotage_fd(io_conn_fd(conn)); + dev_sabotage_fd(io_conn_fd(conn), true); + return read_init(conn, peer); +} + +static struct io_plan *peer_write_post_sabotage(struct io_conn *conn, + struct peer *peer) +{ + dev_sabotage_fd(io_conn_fd(conn), false); return read_init(conn, peer); } #endif @@ -197,7 +204,7 @@ struct io_plan *peer_exchange_initmsg(struct io_conn *conn, #if DEVELOPER switch (dev_disconnect(WIRE_INIT)) { case DEV_DISCONNECT_BEFORE: - dev_sabotage_fd(io_conn_fd(conn)); + dev_sabotage_fd(io_conn_fd(conn), true); break; case DEV_DISCONNECT_DROPPKT: peer->msg = tal_free(peer->msg); /* FALL THRU */ @@ -209,6 +216,9 @@ struct io_plan *peer_exchange_initmsg(struct io_conn *conn, break; case DEV_DISCONNECT_NORMAL: break; + case DEV_DISCONNECT_DISABLE_AFTER: + next = peer_write_post_sabotage; + break; } #endif /* DEVELOPER */ diff --git a/devtools/gossipwith.c b/devtools/gossipwith.c index 92983bf9261c..9f0a715f3c3a 100644 --- a/devtools/gossipwith.c +++ b/devtools/gossipwith.c @@ -67,7 +67,7 @@ void status_fmt(enum log_level level, } #if DEVELOPER -void dev_sabotage_fd(int fd) +void dev_sabotage_fd(int fd, bool close_fd) { abort(); } diff --git a/lightningd/channel.h b/lightningd/channel.h index 0ea0ca451a12..d3f4f8dc2b99 100644 --- a/lightningd/channel.h +++ b/lightningd/channel.h @@ -363,6 +363,10 @@ struct channel *any_channel_by_scid(struct lightningd *ld, struct channel *channel_by_cid(struct lightningd *ld, const struct channel_id *cid); +/* Find this channel within peer */ +struct channel *find_channel_by_id(const struct peer *peer, + const struct channel_id *cid); + void channel_set_last_tx(struct channel *channel, struct bitcoin_tx *tx, const struct bitcoin_signature *sig, @@ -403,6 +407,15 @@ static inline bool channel_active(const struct channel *channel) && !channel_on_chain(channel); } +static inline bool channel_closed(const struct channel *channel) +{ + return channel->state == CLOSINGD_COMPLETE + || channel->state == AWAITING_UNILATERAL + || channel->state == FUNDING_SPEND_SEEN + || channel->state == ONCHAIN + || channel->state == CLOSED; +} + void get_channel_basepoints(struct lightningd *ld, const struct node_id *peer_id, const u64 dbid, diff --git a/lightningd/channel_control.c b/lightningd/channel_control.c index a322fe57ef3e..e1585e0d73a6 100644 --- a/lightningd/channel_control.c +++ b/lightningd/channel_control.c @@ -315,12 +315,16 @@ static void peer_start_closingd_after_shutdown(struct channel *channel, per_peer_state_set_fds_arr(pps, fds); /* This sets channel->owner, closes down channeld. */ - peer_start_closingd(channel, pps, false, NULL); - channel_set_state(channel, - CHANNELD_SHUTTING_DOWN, - CLOSINGD_SIGEXCHANGE, - REASON_UNKNOWN, - "Start closingd"); + peer_start_closingd(channel, pps); + + /* We might have reconnected, so already be here. */ + if (!channel_closed(channel) + && channel->state != CLOSINGD_SIGEXCHANGE) + channel_set_state(channel, + CHANNELD_SHUTTING_DOWN, + CLOSINGD_SIGEXCHANGE, + REASON_UNKNOWN, + "Start closingd"); } static void forget(struct channel *channel) @@ -478,7 +482,8 @@ static unsigned channel_msg(struct subd *sd, const u8 *msg, const int *fds) void peer_start_channeld(struct channel *channel, struct per_peer_state *pps, const u8 *fwd_msg, - bool reconnected) + bool reconnected, + const u8 *reestablish_only) { u8 *initmsg; int hsmfd; @@ -619,7 +624,11 @@ void peer_start_channeld(struct channel *channel, channel->remote_funding_locked, &scid, reconnected, - channel->state == CHANNELD_SHUTTING_DOWN, + /* Anything that indicates we are or have + * shut down */ + channel->state == CHANNELD_SHUTTING_DOWN + || channel->state == CLOSINGD_SIGEXCHANGE + || channel_closed(channel), channel->shutdown_scriptpubkey[REMOTE] != NULL, channel->shutdown_scriptpubkey[LOCAL], channel->channel_flags, @@ -636,7 +645,8 @@ void peer_start_channeld(struct channel *channel, channel->option_anchor_outputs, IFDEV(ld->dev_fast_gossip, false), IFDEV(dev_fail_process_onionpacket, false), - pbases); + pbases, + reestablish_only); /* We don't expect a response: we are triggered by funding_depth_cb. */ subd_send_msg(channel->owner, take(initmsg)); @@ -784,8 +794,8 @@ void channel_notify_new_block(struct lightningd *ld, tal_free(to_forget); } -static struct channel *find_channel_by_id(const struct peer *peer, - const struct channel_id *cid) +struct channel *find_channel_by_id(const struct peer *peer, + const struct channel_id *cid) { struct channel *c; diff --git a/lightningd/channel_control.h b/lightningd/channel_control.h index 5290a64a99af..bf32b5897ba4 100644 --- a/lightningd/channel_control.h +++ b/lightningd/channel_control.h @@ -13,7 +13,8 @@ struct peer; void peer_start_channeld(struct channel *channel, struct per_peer_state *pps, const u8 *fwd_msg, - bool reconnected); + bool reconnected, + const u8 *reestablish_only); /* Returns true if subd told, otherwise false. */ bool channel_tell_depth(struct lightningd *ld, diff --git a/lightningd/closing_control.c b/lightningd/closing_control.c index a4769cdf81df..d2070875715f 100644 --- a/lightningd/closing_control.c +++ b/lightningd/closing_control.c @@ -145,7 +145,7 @@ static void peer_closing_complete(struct channel *channel, const u8 *msg) channel_set_billboard(channel, false, NULL); /* Retransmission only, ignore closing. */ - if (channel->state == CLOSINGD_COMPLETE) + if (channel_closed(channel)) return; /* Channel gets dropped to chain cooperatively. */ @@ -193,17 +193,13 @@ static unsigned closing_msg(struct subd *sd, const u8 *msg, const int *fds UNUSE } void peer_start_closingd(struct channel *channel, - struct per_peer_state *pps, - bool reconnected, - const u8 *channel_reestablish) + struct per_peer_state *pps) { u8 *initmsg; u32 feerate; struct amount_sat minfee, startfee, feelimit; - u64 num_revocations; struct amount_msat their_msat; int hsmfd; - struct secret last_remote_per_commit_secret; struct lightningd *ld = channel->peer->ld; u32 final_commit_feerate; @@ -270,9 +266,6 @@ void peer_start_closingd(struct channel *channel, if (amount_sat_greater(minfee, feelimit)) minfee = feelimit; - num_revocations - = revocations_received(&channel->their_shachain.chain); - /* BOLT #3: * * Each node offering a signature: @@ -292,25 +285,6 @@ void peer_start_closingd(struct channel *channel, return; } - /* BOLT #2: - * - 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 - */ - 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, - REASON_LOCAL, - "Could not get revocation secret %"PRIu64, - num_revocations-1); - return; - } initmsg = towire_closingd_init(tmpctx, chainparams, pps, @@ -329,12 +303,6 @@ void peer_start_closingd(struct channel *channel, 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); diff --git a/lightningd/closing_control.h b/lightningd/closing_control.h index cbaa76ab9941..0ee6afb29a56 100644 --- a/lightningd/closing_control.h +++ b/lightningd/closing_control.h @@ -3,13 +3,10 @@ #include "config.h" #include -struct channel_id; -struct crypto_state; +struct channel; struct per_peer_state; void peer_start_closingd(struct channel *channel, - struct per_peer_state *pps, - bool reconnected, - const u8 *channel_reestablish); + struct per_peer_state *pps); #endif /* LIGHTNING_LIGHTNINGD_CLOSING_CONTROL_H */ diff --git a/lightningd/dual_open_control.c b/lightningd/dual_open_control.c index ac9e1f6effea..167074eea0fa 100644 --- a/lightningd/dual_open_control.c +++ b/lightningd/dual_open_control.c @@ -1293,7 +1293,7 @@ static void handle_channel_closed(struct subd *dualopend, per_peer_state_set_fds_arr(pps, fds); - peer_start_closingd(channel, pps, false, NULL); + peer_start_closingd(channel, pps); channel_set_state(channel, CHANNELD_SHUTTING_DOWN, CLOSINGD_SIGEXCHANGE, @@ -1549,7 +1549,7 @@ static void handle_channel_locked(struct subd *dualopend, wallet_channel_clear_inflights(dualopend->ld->wallet, channel); /* FIXME: LND sigs/update_fee msgs? */ - peer_start_channeld(channel, pps, NULL, false); + peer_start_channeld(channel, pps, NULL, false, NULL); return; } diff --git a/lightningd/opening_common.c b/lightningd/opening_common.c index 4f50d4b37250..1882cdd0663a 100644 --- a/lightningd/opening_common.c +++ b/lightningd/opening_common.c @@ -1,8 +1,10 @@ #include #include #include +#include #include #include +#include #include #include #include @@ -151,6 +153,46 @@ void channel_config(struct lightningd *ld, ours->channel_reserve = AMOUNT_SAT(UINT64_MAX); } +void handle_reestablish(struct lightningd *ld, + const struct node_id *peer_id, + const struct channel_id *channel_id, + const u8 *reestablish, + struct per_peer_state *pps) +{ + struct peer *peer; + struct channel *c; + + /* We very carefully re-xmit the last reestablish, so they can get + * their secrets back. We don't otherwise touch them. */ + peer = peer_by_id(ld, peer_id); + if (peer) + c = find_channel_by_id(peer, channel_id); + else + c = NULL; + + if (c && channel_closed(c)) { + log_debug(c->log, "Reestablish on %s channel: using channeld to reply", + channel_state_name(c)); + peer_start_channeld(c, pps, NULL, true, reestablish); + } else { + const u8 *err = towire_errorfmt(tmpctx, channel_id, + "Unknown channel for reestablish"); + log_debug(ld->log, "Reestablish on UNKNOWN channel %s", + type_to_string(tmpctx, struct channel_id, channel_id)); + subd_send_msg(ld->connectd, + take(towire_connectd_peer_final_msg(NULL, peer_id, + pps, err))); + subd_send_fd(ld->connectd, pps->peer_fd); + subd_send_fd(ld->connectd, pps->gossip_fd); + subd_send_fd(ld->connectd, pps->gossip_store_fd); + /* Don't close those fds! */ + pps->peer_fd + = pps->gossip_fd + = pps->gossip_store_fd + = -1; + } +} + #if DEVELOPER /* Indented to avoid include ordering check */ #include diff --git a/lightningd/opening_common.h b/lightningd/opening_common.h index 212a9109c13a..b499407e6437 100644 --- a/lightningd/opening_common.h +++ b/lightningd/opening_common.h @@ -118,6 +118,12 @@ void channel_config(struct lightningd *ld, u32 *max_to_self_delay, struct amount_msat *min_effective_htlc_capacity); +void handle_reestablish(struct lightningd *ld, + const struct node_id *peer_id, + const struct channel_id *channel_id, + const u8 *reestablish, + struct per_peer_state *pps); + #if DEVELOPER struct command; /* Calls report_leak_info() async. */ diff --git a/lightningd/opening_control.c b/lightningd/opening_control.c index 394b64525cf4..cfba876c289e 100644 --- a/lightningd/opening_control.c +++ b/lightningd/opening_control.c @@ -420,7 +420,7 @@ static void opening_funder_finished(struct subd *openingd, const u8 *resp, wallet_penalty_base_add(ld->wallet, channel->dbid, pbase); funding_success(channel); - peer_start_channeld(channel, pps, NULL, false); + peer_start_channeld(channel, pps, NULL, false, NULL); cleanup: subd_release_channel(openingd, fc->uc); @@ -535,7 +535,7 @@ static void opening_fundee_finished(struct subd *openingd, wallet_penalty_base_add(ld->wallet, channel->dbid, pbase); /* On to normal operation! */ - peer_start_channeld(channel, pps, fwd_msg, false); + peer_start_channeld(channel, pps, fwd_msg, false, NULL); subd_release_channel(openingd, uc); uc->open_daemon = NULL; @@ -801,6 +801,31 @@ static void opening_got_offer(struct subd *openingd, plugin_hook_call_openchannel(openingd->ld, payload); } +static void opening_got_reestablish(struct subd *openingd, const u8 *msg, + const int fds[3], + struct uncommitted_channel *uc) +{ + struct lightningd *ld = openingd->ld; + struct node_id peer_id = uc->peer->id; + struct channel_id channel_id; + u8 *reestablish; + struct per_peer_state *pps; + + if (!fromwire_openingd_got_reestablish(tmpctx, msg, &channel_id, + &reestablish, &pps)) { + log_broken(openingd->log, "Malformed opening_got_reestablish %s", + tal_hex(tmpctx, msg)); + tal_free(openingd); + return; + } + per_peer_state_set_fds_arr(pps, fds); + + /* This could free peer */ + tal_free(uc); + + handle_reestablish(ld, &peer_id, &channel_id, reestablish, pps); +} + static unsigned int openingd_msg(struct subd *openingd, const u8 *msg, const int *fds) { @@ -848,6 +873,12 @@ static unsigned int openingd_msg(struct subd *openingd, opening_got_offer(openingd, msg, uc); return 0; + case WIRE_OPENINGD_GOT_REESTABLISH: + if (tal_count(fds) != 3) + return 3; + opening_got_reestablish(openingd, msg, fds, uc); + return 0; + /* We send these! */ case WIRE_OPENINGD_INIT: case WIRE_OPENINGD_FUNDER_START: diff --git a/lightningd/peer_control.c b/lightningd/peer_control.c index 47957c1ab7aa..71211588fdbb 100644 --- a/lightningd/peer_control.c +++ b/lightningd/peer_control.c @@ -1121,17 +1121,12 @@ static void peer_connected_hook_final(struct peer_connected_hook_payload *payloa case CHANNELD_AWAITING_LOCKIN: case CHANNELD_NORMAL: case CHANNELD_SHUTTING_DOWN: - assert(!channel->owner); - channel->peer->addr = addr; - channel->peer->connected_incoming = payload->incoming; - peer_start_channeld(channel, payload->pps, NULL, true); - return; - case CLOSINGD_SIGEXCHANGE: assert(!channel->owner); channel->peer->addr = addr; channel->peer->connected_incoming = payload->incoming; - peer_start_closingd(channel, payload->pps, true, NULL); + peer_start_channeld(channel, payload->pps, NULL, true, + NULL); return; } abort(); @@ -1590,6 +1585,7 @@ static const struct json_command listpeers_command = { json_listpeers, "Show current peers, if {level} is set, include logs for {id}" }; +/* Comment added to satisfice AUTODATA */ AUTODATA(json_command, &listpeers_command); static struct command_result * @@ -2965,7 +2961,6 @@ static const struct json_command sendcustommsg_command = { .verbose = "dev-sendcustommsg node_id hexcustommsg", }; -/* Comment added to satisfice AUTODATA */ AUTODATA(json_command, &sendcustommsg_command); #endif /* DEVELOPER */ diff --git a/lightningd/test/run-invoice-select-inchan.c b/lightningd/test/run-invoice-select-inchan.c index 8a4fd854e092..5601ab8a24de 100644 --- a/lightningd/test/run-invoice-select-inchan.c +++ b/lightningd/test/run-invoice-select-inchan.c @@ -575,14 +575,9 @@ void peer_restart_dualopend(struct peer *peer UNNEEDED, void peer_start_channeld(struct channel *channel UNNEEDED, struct per_peer_state *pps UNNEEDED, const u8 *fwd_msg UNNEEDED, - bool reconnected UNNEEDED) -{ fprintf(stderr, "peer_start_channeld called!\n"); abort(); } -/* Generated stub for peer_start_closingd */ -void peer_start_closingd(struct channel *channel UNNEEDED, - struct per_peer_state *pps UNNEEDED, bool reconnected UNNEEDED, - const u8 *channel_reestablish UNNEEDED) -{ fprintf(stderr, "peer_start_closingd called!\n"); abort(); } + const u8 *reestablish_only UNNEEDED) +{ fprintf(stderr, "peer_start_channeld called!\n"); abort(); } /* Generated stub for peer_start_dualopend */ void peer_start_dualopend(struct peer *peer UNNEEDED, struct per_peer_state *pps UNNEEDED) { fprintf(stderr, "peer_start_dualopend called!\n"); abort(); } diff --git a/openingd/openingd.c b/openingd/openingd.c index 7a0d1bdeed2d..051b153eaa85 100644 --- a/openingd/openingd.c +++ b/openingd/openingd.c @@ -1149,6 +1149,7 @@ static u8 *handle_peer_in(struct state *state) u8 *msg = sync_crypto_read(tmpctx, state->pps); enum peer_wire t = fromwire_peektype(msg); struct channel_id channel_id; + bool extracted; if (t == WIRE_OPEN_CHANNEL) return fundee_channel(state, msg); @@ -1170,9 +1171,17 @@ static u8 *handle_peer_in(struct state *state) &state->channel_id, false, msg)) return NULL; + extracted = extract_channel_id(msg, &channel_id); + + /* Reestablish on some now-closed channel? Be nice. */ + if (extracted && fromwire_peektype(msg) == WIRE_CHANNEL_REESTABLISH) { + return towire_openingd_got_reestablish(NULL, + &channel_id, msg, + state->pps); + } sync_crypto_write(state->pps, take(towire_warningfmt(NULL, - extract_channel_id(msg, &channel_id) ? &channel_id : NULL, + extracted ? &channel_id : NULL, "Unexpected message %s: %s", peer_wire_name(t), tal_hex(tmpctx, msg)))); @@ -1287,6 +1296,7 @@ static u8 *handle_master_in(struct state *state) case WIRE_OPENINGD_FUNDER_FAILED: case WIRE_OPENINGD_GOT_OFFER: case WIRE_OPENINGD_GOT_OFFER_REPLY: + case WIRE_OPENINGD_GOT_REESTABLISH: break; } diff --git a/openingd/openingd_wire.csv b/openingd/openingd_wire.csv index 0c4e6ff80b4c..84f51bccfbc6 100644 --- a/openingd/openingd_wire.csv +++ b/openingd/openingd_wire.csv @@ -29,6 +29,13 @@ msgdata,openingd_init,option_anchor_outputs,bool, msgdata,openingd_init,dev_temporary_channel_id,?byte,32 msgdata,openingd_init,dev_fast_gossip,bool, +# Openingd->master: they tried to reestablish a channel. +msgtype,openingd_got_reestablish,6001 +msgdata,openingd_got_reestablish,channel_id,channel_id, +msgdata,openingd_got_reestablish,len,u16, +msgdata,openingd_got_reestablish,msg,u8,len +msgdata,openingd_got_reestablish,pps,per_peer_state, + # Openingd->master: they offered channel, should we continue? msgtype,openingd_got_offer,6005 msgdata,openingd_got_offer,funding_satoshis,amount_sat, diff --git a/openingd/openingd_wiregen.c b/openingd/openingd_wiregen.c index 7f615aa0996d..76bc14a30ab7 100644 --- a/openingd/openingd_wiregen.c +++ b/openingd/openingd_wiregen.c @@ -21,6 +21,7 @@ const char *openingd_wire_name(int e) switch ((enum openingd_wire)e) { case WIRE_OPENINGD_INIT: return "WIRE_OPENINGD_INIT"; + case WIRE_OPENINGD_GOT_REESTABLISH: return "WIRE_OPENINGD_GOT_REESTABLISH"; case WIRE_OPENINGD_GOT_OFFER: return "WIRE_OPENINGD_GOT_OFFER"; case WIRE_OPENINGD_GOT_OFFER_REPLY: return "WIRE_OPENINGD_GOT_OFFER_REPLY"; case WIRE_OPENINGD_FUNDER_REPLY: return "WIRE_OPENINGD_FUNDER_REPLY"; @@ -42,6 +43,7 @@ bool openingd_wire_is_defined(u16 type) { switch ((enum openingd_wire)type) { case WIRE_OPENINGD_INIT:; + case WIRE_OPENINGD_GOT_REESTABLISH:; case WIRE_OPENINGD_GOT_OFFER:; case WIRE_OPENINGD_GOT_OFFER_REPLY:; case WIRE_OPENINGD_FUNDER_REPLY:; @@ -138,6 +140,39 @@ bool fromwire_openingd_init(const tal_t *ctx, const void *p, const struct chainp return cursor != NULL; } +/* WIRE: OPENINGD_GOT_REESTABLISH */ +/* Openingd->master: they tried to reestablish a channel. */ +u8 *towire_openingd_got_reestablish(const tal_t *ctx, const struct channel_id *channel_id, const u8 *msg, const struct per_peer_state *pps) +{ + u16 len = tal_count(msg); + u8 *p = tal_arr(ctx, u8, 0); + + towire_u16(&p, WIRE_OPENINGD_GOT_REESTABLISH); + towire_channel_id(&p, channel_id); + towire_u16(&p, len); + towire_u8_array(&p, msg, len); + towire_per_peer_state(&p, pps); + + return memcheck(p, tal_count(p)); +} +bool fromwire_openingd_got_reestablish(const tal_t *ctx, const void *p, struct channel_id *channel_id, u8 **msg, struct per_peer_state **pps) +{ + u16 len; + + const u8 *cursor = p; + size_t plen = tal_count(p); + + if (fromwire_u16(&cursor, &plen) != WIRE_OPENINGD_GOT_REESTABLISH) + return false; + fromwire_channel_id(&cursor, &plen, channel_id); + len = fromwire_u16(&cursor, &plen); + // 2nd case msg + *msg = len ? tal_arr(ctx, u8, len) : NULL; + fromwire_u8_array(&cursor, &plen, *msg, len); + *pps = fromwire_per_peer_state(ctx, &cursor, &plen); + return cursor != NULL; +} + /* WIRE: OPENINGD_GOT_OFFER */ /* Openingd->master: they offered channel */ u8 *towire_openingd_got_offer(const tal_t *ctx, struct amount_sat funding_satoshis, struct amount_msat push_msat, struct amount_sat dust_limit_satoshis, struct amount_msat max_htlc_value_in_flight_msat, struct amount_sat channel_reserve_satoshis, struct amount_msat htlc_minimum_msat, u32 feerate_per_kw, u16 to_self_delay, u16 max_accepted_htlcs, u8 channel_flags, const u8 *shutdown_scriptpubkey) @@ -569,4 +604,4 @@ bool fromwire_openingd_dev_memleak_reply(const void *p, bool *leak) *leak = fromwire_bool(&cursor, &plen); return cursor != NULL; } -// SHA256STAMP:d2fcabdf157b098608e47dcdc37db0f46fe8d466d74159969544d7c4bb77f061 +// SHA256STAMP:005577de0219577522210df32b3ed325f028b24fc25d3b77a1dc770077381b6b diff --git a/openingd/openingd_wiregen.h b/openingd/openingd_wiregen.h index 047c82110783..1eaa101bbe47 100644 --- a/openingd/openingd_wiregen.h +++ b/openingd/openingd_wiregen.h @@ -18,6 +18,8 @@ enum openingd_wire { WIRE_OPENINGD_INIT = 6000, + /* Openingd->master: they tried to reestablish a channel. */ + WIRE_OPENINGD_GOT_REESTABLISH = 6001, /* Openingd->master: they offered channel */ WIRE_OPENINGD_GOT_OFFER = 6005, /* master->openingd: optional rejection message */ @@ -61,6 +63,11 @@ bool openingd_wire_is_defined(u16 type); u8 *towire_openingd_init(const tal_t *ctx, const struct chainparams *chainparams, const struct feature_set *our_features, const struct channel_config *our_config, u32 max_to_self_delay, struct amount_msat min_effective_htlc_capacity_msat, const struct per_peer_state *pps, const struct basepoints *our_basepoints, const struct pubkey *our_funding_pubkey, u32 minimum_depth, u32 min_feerate, u32 max_feerate, const u8 *lfeatures, bool option_static_remotekey, bool option_anchor_outputs, const struct channel_id *dev_temporary_channel_id, bool dev_fast_gossip); bool fromwire_openingd_init(const tal_t *ctx, const void *p, const struct chainparams **chainparams, struct feature_set **our_features, struct channel_config *our_config, u32 *max_to_self_delay, struct amount_msat *min_effective_htlc_capacity_msat, struct per_peer_state **pps, struct basepoints *our_basepoints, struct pubkey *our_funding_pubkey, u32 *minimum_depth, u32 *min_feerate, u32 *max_feerate, u8 **lfeatures, bool *option_static_remotekey, bool *option_anchor_outputs, struct channel_id **dev_temporary_channel_id, bool *dev_fast_gossip); +/* WIRE: OPENINGD_GOT_REESTABLISH */ +/* Openingd->master: they tried to reestablish a channel. */ +u8 *towire_openingd_got_reestablish(const tal_t *ctx, const struct channel_id *channel_id, const u8 *msg, const struct per_peer_state *pps); +bool fromwire_openingd_got_reestablish(const tal_t *ctx, const void *p, struct channel_id *channel_id, u8 **msg, struct per_peer_state **pps); + /* WIRE: OPENINGD_GOT_OFFER */ /* Openingd->master: they offered channel */ u8 *towire_openingd_got_offer(const tal_t *ctx, struct amount_sat funding_satoshis, struct amount_msat push_msat, struct amount_sat dust_limit_satoshis, struct amount_msat max_htlc_value_in_flight_msat, struct amount_sat channel_reserve_satoshis, struct amount_msat htlc_minimum_msat, u32 feerate_per_kw, u16 to_self_delay, u16 max_accepted_htlcs, u8 channel_flags, const u8 *shutdown_scriptpubkey); @@ -121,4 +128,4 @@ bool fromwire_openingd_dev_memleak_reply(const void *p, bool *leak); #endif /* LIGHTNING_OPENINGD_OPENINGD_WIREGEN_H */ -// SHA256STAMP:d2fcabdf157b098608e47dcdc37db0f46fe8d466d74159969544d7c4bb77f061 +// SHA256STAMP:005577de0219577522210df32b3ed325f028b24fc25d3b77a1dc770077381b6b diff --git a/tests/test_closing.py b/tests/test_closing.py index 55d05d447dac..127511a3ed87 100644 --- a/tests/test_closing.py +++ b/tests/test_closing.py @@ -2742,6 +2742,110 @@ def test_shutdown_alternate_txid(node_factory, bitcoind): wait_for(lambda: l1.rpc.listpeers()['peers'] == []) +@pytest.mark.developer("needs dev_disconnect") +def test_htlc_rexmit_while_closing(node_factory, executor): + """Retranmitting an HTLC revocation while shutting down should work""" + # l1 disconnects after sending second COMMITMENT_SIGNED. + # Then it stops receiving after sending WIRE_SHUTDOWN (which is before it + # reads the revoke_and_ack). + disconnects = ['+WIRE_COMMITMENT_SIGNED*2', + 'xWIRE_SHUTDOWN'] + + l1, l2 = node_factory.line_graph(2, opts=[{'may_reconnect': True, + 'dev-no-reconnect': None, + 'disconnect': disconnects}, + {'may_reconnect': True, + 'dev-no-reconnect': None}]) + + # Start payment, will disconnect + l1.pay(l2, 200000) + wait_for(lambda: only_one(l1.rpc.listpeers()['peers'])['connected'] is False) + + # Tell it to close (will block) + fut = executor.submit(l1.rpc.close, l2.info['id']) + + # Original problem was with multiple disconnects, but to simplify we make + # l2 send shutdown too. + fut2 = executor.submit(l2.rpc.close, l1.info['id']) + + # Reconnect, shutdown will continue disconnect again + l1.rpc.connect(l2.info['id'], 'localhost', l2.port) + + # Now l2 should be in CLOSINGD_SIGEXCHANGE, l1 still waiting on + # WIRE_REVOKE_AND_ACK. + wait_for(lambda: only_one(only_one(l2.rpc.listpeers()['peers'])['channels'])['state'] == 'CLOSINGD_SIGEXCHANGE') + assert only_one(only_one(l1.rpc.listpeers()['peers'])['channels'])['state'] == 'CHANNELD_SHUTTING_DOWN' + + # They don't realize they're not talking, so disconnect and reconnect. + l1.rpc.disconnect(l2.info['id'], force=True) + + # Now it hangs, since l1 is expecting rexmit of revoke-and-ack. + l1.rpc.connect(l2.info['id'], 'localhost', l2.port) + + fut.result(TIMEOUT) + fut2.result(TIMEOUT) + + +@pytest.mark.openchannel('v1') +@pytest.mark.developer("needs dev_disconnect") +def test_you_forgot_closed_channel(node_factory, executor): + """Ideally you'd keep talking to us about closed channels: simple""" + disconnects = ['@WIRE_CLOSING_SIGNED'] + + l1, l2 = node_factory.line_graph(2, opts=[{'may_reconnect': True, + 'dev-no-reconnect': None}, + {'may_reconnect': True, + 'dev-no-reconnect': None, + 'disconnect': disconnects}]) + + l1.pay(l2, 200000) + + fut = executor.submit(l1.rpc.close, l2.info['id']) + + # l2 considers the closing done, l1 does not + wait_for(lambda: only_one(only_one(l2.rpc.listpeers()['peers'])['channels'])['state'] == 'CLOSINGD_COMPLETE') + assert only_one(only_one(l1.rpc.listpeers()['peers'])['channels'])['state'] == 'CLOSINGD_SIGEXCHANGE' + + # l1 reconnects, it should succeed. + l1.rpc.connect(l2.info['id'], 'localhost', l2.port) + fut.result(TIMEOUT) + + +@pytest.mark.developer("needs dev_disconnect") +def test_you_forgot_closed_channel_onchain(node_factory, bitcoind, executor): + """Ideally you'd keep talking to us about closed channels: even if close is mined""" + disconnects = ['@WIRE_CLOSING_SIGNED'] + + l1, l2 = node_factory.line_graph(2, opts=[{'may_reconnect': True, + 'dev-no-reconnect': None}, + {'may_reconnect': True, + 'dev-no-reconnect': None, + 'disconnect': disconnects}]) + + l1.pay(l2, 200000) + + fut = executor.submit(l1.rpc.close, l2.info['id']) + + # l2 considers the closing done, l1 does not + wait_for(lambda: only_one(only_one(l2.rpc.listpeers()['peers'])['channels'])['state'] == 'CLOSINGD_COMPLETE') + assert only_one(only_one(l1.rpc.listpeers()['peers'])['channels'])['state'] == 'CLOSINGD_SIGEXCHANGE' + + # l1 does not see any new blocks. + def no_new_blocks(req): + return {"result": {"blockhash": None, "block": None}} + + l1.daemon.rpcproxy.mock_rpc('getrawblockbyheight', no_new_blocks) + + # Close transaction mined + bitcoind.generate_block(1, wait_for_mempool=1) + + wait_for(lambda: only_one(only_one(l2.rpc.listpeers()['peers'])['channels'])['state'] == 'ONCHAIN') + + # l1 reconnects, it should succeed. + l1.rpc.connect(l2.info['id'], 'localhost', l2.port) + fut.result(TIMEOUT) + + @unittest.skipIf(TEST_NETWORK == 'liquid-regtest', "Uses regtest addresses") @pytest.mark.developer("too slow without fast polling for blocks") def test_segwit_anyshutdown(node_factory, bitcoind, executor): diff --git a/tests/test_connection.py b/tests/test_connection.py index ecadb4b208a5..b331c9e65313 100644 --- a/tests/test_connection.py +++ b/tests/test_connection.py @@ -588,7 +588,7 @@ def test_reconnect_no_update(node_factory, executor, bitcoind): # Close will trigger the @WIRE_SHUTDOWN and we then wait for the # automatic reconnection to trigger the retransmission. l1.rpc.close(l2.info['id'], 0) - l2.daemon.wait_for_log(r"closingd.* Retransmitting funding_locked for channel") + l2.daemon.wait_for_log(r"channeld.* Retransmitting funding_locked for channel") l1.daemon.wait_for_log(r"CLOSINGD_COMPLETE") @@ -1242,7 +1242,7 @@ def test_funding_external_wallet_corners(node_factory, bitcoind): # on reconnect, channel should get destroyed l1.rpc.connect(l2.info['id'], 'localhost', l2.port) - l1.daemon.wait_for_log('Rejecting WIRE_CHANNEL_REESTABLISH for unknown channel_id') + l1.daemon.wait_for_log('Reestablish on UNKNOWN channel') wait_for(lambda: len(l1.rpc.listpeers()['peers']) == 0) wait_for(lambda: len(l2.rpc.listpeers()['peers']) == 0) diff --git a/wallet/db_postgres_sqlgen.c b/wallet/db_postgres_sqlgen.c index e85d5929d387..5ca4e2066e01 100644 --- a/wallet/db_postgres_sqlgen.c +++ b/wallet/db_postgres_sqlgen.c @@ -1924,4 +1924,4 @@ struct db_query db_postgres_queries[] = { #endif /* LIGHTNINGD_WALLET_GEN_DB_POSTGRES */ -// SHA256STAMP:dbbcb7d784e7b3d6c7b27c2ff976dcc39335fdc26fbf095b65116488007799f7 +// SHA256STAMP:0cb27df4073d1a617d3d1712579e28c190208818458ea8b35c3c88276b428dc0 diff --git a/wallet/db_sqlite3_sqlgen.c b/wallet/db_sqlite3_sqlgen.c index 5b6eb8fa06d6..70365e62920a 100644 --- a/wallet/db_sqlite3_sqlgen.c +++ b/wallet/db_sqlite3_sqlgen.c @@ -1924,4 +1924,4 @@ struct db_query db_sqlite3_queries[] = { #endif /* LIGHTNINGD_WALLET_GEN_DB_SQLITE3 */ -// SHA256STAMP:dbbcb7d784e7b3d6c7b27c2ff976dcc39335fdc26fbf095b65116488007799f7 +// SHA256STAMP:0cb27df4073d1a617d3d1712579e28c190208818458ea8b35c3c88276b428dc0 diff --git a/wallet/statements_gettextgen.po b/wallet/statements_gettextgen.po index 030daf2061c8..635a8f473bee 100644 --- a/wallet/statements_gettextgen.po +++ b/wallet/statements_gettextgen.po @@ -1262,11 +1262,11 @@ msgstr "" msgid "not a valid SQL statement" msgstr "" -#: wallet/test/run-wallet.c:1455 +#: wallet/test/run-wallet.c:1450 msgid "SELECT COUNT(1) FROM channel_funding_inflights WHERE channel_id = ?;" msgstr "" -#: wallet/test/run-wallet.c:1653 +#: wallet/test/run-wallet.c:1648 msgid "INSERT INTO channels (id) VALUES (1);" msgstr "" -# SHA256STAMP:e3c8d5cac8615668f0c9f37ebf6edff3b18833bafdf9643c2203b2a4ab654b7c +# SHA256STAMP:af00e095200a0cdcd525759a786e1897d11a0effffd7d4b9d618bfa780acd229 diff --git a/wallet/test/run-wallet.c b/wallet/test/run-wallet.c index c95aca7cb359..191df6698f21 100644 --- a/wallet/test/run-wallet.c +++ b/wallet/test/run-wallet.c @@ -647,14 +647,9 @@ void peer_restart_dualopend(struct peer *peer UNNEEDED, void peer_start_channeld(struct channel *channel UNNEEDED, struct per_peer_state *pps UNNEEDED, const u8 *fwd_msg UNNEEDED, - bool reconnected UNNEEDED) -{ fprintf(stderr, "peer_start_channeld called!\n"); abort(); } -/* Generated stub for peer_start_closingd */ -void peer_start_closingd(struct channel *channel UNNEEDED, - struct per_peer_state *pps UNNEEDED, bool reconnected UNNEEDED, - const u8 *channel_reestablish UNNEEDED) -{ fprintf(stderr, "peer_start_closingd called!\n"); abort(); } + const u8 *reestablish_only UNNEEDED) +{ fprintf(stderr, "peer_start_channeld called!\n"); abort(); } /* Generated stub for peer_start_dualopend */ void peer_start_dualopend(struct peer *peer UNNEEDED, struct per_peer_state *pps UNNEEDED) { fprintf(stderr, "peer_start_dualopend called!\n"); abort(); }