From 5f237cd64f548f444e96494fc5889f892ffec4e1 Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Mon, 31 May 2021 12:42:30 +0930 Subject: [PATCH] channeld: tweak function to allow testing for pending *uncommitted* changes. For quiescence, we can't have sent any updates at all. But for upgrades on reconnection, we may have already added uncommitted HTLCs for retransmission, but they don't count towards "are we quiesced" since they're not sent yet. Signed-off-by: Rusty Russell --- channeld/channeld.c | 6 +++--- channeld/full_channel.c | 20 ++++++++++++++++---- channeld/full_channel.h | 4 +++- common/fee_states.c | 6 +++++- common/fee_states.h | 5 +++-- 5 files changed, 30 insertions(+), 11 deletions(-) diff --git a/channeld/channeld.c b/channeld/channeld.c index d33e9da1e2fe..95802ad13715 100644 --- a/channeld/channeld.c +++ b/channeld/channeld.c @@ -290,7 +290,7 @@ static void maybe_send_stfu(struct peer *peer) if (!peer->stfu) return; - if (!peer->stfu_sent[LOCAL] && !pending_updates(peer->channel, LOCAL)) { + if (!peer->stfu_sent[LOCAL] && !pending_updates(peer->channel, LOCAL, false)) { u8 *msg = towire_stfu(NULL, &peer->channel_id, peer->stfu_initiator == LOCAL); sync_crypto_write(peer->pps, take(msg)); @@ -323,7 +323,7 @@ static void handle_stfu(struct peer *peer, const u8 *stfu) } /* Sanity check */ - if (pending_updates(peer->channel, REMOTE)) + if (pending_updates(peer->channel, REMOTE, false)) peer_failed_warn(peer->pps, &peer->channel_id, "STFU but you still have updates pending?"); @@ -1141,7 +1141,7 @@ static void send_commit(struct peer *peer) /* FIXME: We occasionally desynchronize with LND here, so * don't stress things by having more than one feerate change * in-flight! */ - if (feerate_changes_done(peer->channel->fee_states)) { + if (feerate_changes_done(peer->channel->fee_states, false)) { u8 *msg; if (!channel_update_feerate(peer->channel, feerate_target)) diff --git a/channeld/full_channel.c b/channeld/full_channel.c index 55ae6214c0b3..eb6f0375d1ec 100644 --- a/channeld/full_channel.c +++ b/channeld/full_channel.c @@ -1252,26 +1252,38 @@ static bool adjust_balance(struct balance view_owed[NUM_SIDES][NUM_SIDES], return true; } -bool pending_updates(const struct channel *channel, enum side side) +bool pending_updates(const struct channel *channel, + enum side side, + bool uncommitted_ok) { struct htlc_map_iter it; const struct htlc *htlc; /* Initiator might have fee changes in play. */ if (side == channel->opener) { - if (!feerate_changes_done(channel->fee_states)) + if (!feerate_changes_done(channel->fee_states, uncommitted_ok)) return true; } for (htlc = htlc_map_first(channel->htlcs, &it); htlc; htlc = htlc_map_next(channel->htlcs, &it)) { - /* If it's still being added, it's owner added it. */ - if (htlc_state_flags(htlc->state) & HTLC_ADDING) { + int flags = htlc_state_flags(htlc->state); + + /* If it's still being added, its owner added it. */ + if (flags & HTLC_ADDING) { + /* It might be OK if it's added, but not committed */ + if (uncommitted_ok + && (flags & HTLC_FLAG(!side, HTLC_F_PENDING))) + continue; if (htlc_owner(htlc) == side) return true; /* If it's being removed, non-owner removed it */ } else if (htlc_state_flags(htlc->state) & HTLC_REMOVING) { + /* It might be OK if it's removed, but not committed */ + if (uncommitted_ok + && (flags & HTLC_FLAG(!side, HTLC_F_PENDING))) + continue; if (htlc_owner(htlc) != side) return true; } diff --git a/channeld/full_channel.h b/channeld/full_channel.h index 8f04547eb70b..e23deb3b11fa 100644 --- a/channeld/full_channel.h +++ b/channeld/full_channel.h @@ -258,8 +258,10 @@ void dump_htlcs(const struct channel *channel, const char *prefix); * pending_updates: does this side have updates pending in channel? * @channel: the channel * @side: the side who is offering or failing/fulfilling HTLC, or feechange + * @uncommitted_ok: don't count uncommitted changes. */ -bool pending_updates(const struct channel *channel, enum side side); +bool pending_updates(const struct channel *channel, enum side side, + bool uncommitted_ok); const char *channel_add_err_name(enum channel_add_err e); const char *channel_remove_err_name(enum channel_remove_err e); diff --git a/common/fee_states.c b/common/fee_states.c index c12470911e1d..451d3849f150 100644 --- a/common/fee_states.c +++ b/common/fee_states.c @@ -74,10 +74,14 @@ u32 get_feerate(const struct fee_states *fee_states, } /* Are feerates all agreed by both sides? */ -bool feerate_changes_done(const struct fee_states *fee_states) +bool feerate_changes_done(const struct fee_states *fee_states, + bool ignore_uncommitted) { size_t num_feerates = 0; for (size_t i = 0; i < ARRAY_SIZE(fee_states->feerate); i++) { + if (ignore_uncommitted + && (i == RCVD_ADD_HTLC || i == SENT_ADD_HTLC)) + continue; num_feerates += (fee_states->feerate[i] != NULL); } return num_feerates == 1; diff --git a/common/fee_states.h b/common/fee_states.h index 40cc18ddccd3..cf846002b90e 100644 --- a/common/fee_states.h +++ b/common/fee_states.h @@ -86,7 +86,8 @@ struct fee_states *fromwire_fee_states(const tal_t *ctx, */ bool fee_states_valid(const struct fee_states *fee_states, enum side opener); -/* Are therre no more fee changes in-flight? */ -bool feerate_changes_done(const struct fee_states *fee_states); +/* Are there no more fee changes in-flight? */ +bool feerate_changes_done(const struct fee_states *fee_states, + bool ignore_uncommitted); #endif /* LIGHTNING_COMMON_FEE_STATES_H */