channel: use flag to indicate we're awaiting revoke_and_ack.

We currently scan through HTLCs: this isn't enough if we've only got a
feechange in the commitment, so use a flag (but keep both for now for
debugging).

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
This commit is contained in:
Rusty Russell 2017-11-20 16:39:29 +10:30 committed by Christian Decker
parent c328a76438
commit 0a131c6389
4 changed files with 35 additions and 7 deletions

View File

@ -1046,6 +1046,12 @@ static struct io_plan *handle_peer_revoke_and_ack(struct io_conn *conn,
"Bad revoke_and_ack %s", tal_hex(msg, msg));
}
if (!channel_awaiting_revoke_and_ack(peer->channel))
peer_failed(io_conn_fd(peer->peer_conn),
&peer->pcs.cs,
&peer->channel_id,
"Unexpected revoke_and_ack");
/* BOLT #2:
*
* A receiving node MUST check that `per_commitment_secret` generates

View File

@ -696,6 +696,8 @@ bool channel_sending_commit(struct channel *channel,
assert(change & HTLC_REMOTE_F_COMMITTED);
channel->changes_pending[REMOTE] = false;
assert(!channel->awaiting_revoke_and_ack);
channel->awaiting_revoke_and_ack = true;
return true;
}
@ -716,6 +718,9 @@ bool channel_rcvd_revoke_and_ack(struct channel *channel,
if (change & HTLC_LOCAL_F_PENDING)
channel->changes_pending[LOCAL] = true;
assert(channel->awaiting_revoke_and_ack);
channel->awaiting_revoke_and_ack = false;
return change & HTLC_LOCAL_F_PENDING;
}
@ -762,25 +767,36 @@ bool channel_sending_revoke_and_ack(struct channel *channel)
return change & HTLC_REMOTE_F_PENDING;
}
/* FIXME: Trivial to optimize: set flag on channel_sending_commit,
* clear in channel_rcvd_revoke_and_ack. */
bool channel_awaiting_revoke_and_ack(const struct channel *channel)
static bool htlc_awaiting_revoke_and_ack(const struct htlc *h)
{
const enum htlc_state states[] = { SENT_ADD_COMMIT,
SENT_REMOVE_ACK_COMMIT,
SENT_ADD_ACK_COMMIT,
SENT_REMOVE_COMMIT };
for (size_t i = 0; i < ARRAY_SIZE(states); i++) {
if (h->state == states[i]) {
return true;
}
}
return false;
}
bool channel_awaiting_revoke_and_ack(const struct channel *channel)
{
struct htlc_map_iter it;
struct htlc *h;
size_t i;
/* FIXME: remove debugging iteration. */
for (h = htlc_map_first(channel->htlcs, &it);
h;
h = htlc_map_next(channel->htlcs, &it)) {
for (i = 0; i < ARRAY_SIZE(states); i++)
if (h->state == states[i])
return true;
if (htlc_awaiting_revoke_and_ack(h)) {
assert(channel->awaiting_revoke_and_ack);
return true;
}
}
assert(!channel->awaiting_revoke_and_ack);
return false;
}
@ -888,6 +904,8 @@ bool channel_force_htlcs(struct channel *channel,
return false;
}
if (htlc_awaiting_revoke_and_ack(htlc))
channel->awaiting_revoke_and_ack = true;
}
for (i = 0; i < tal_count(fulfilled); i++) {

View File

@ -40,6 +40,7 @@ struct channel *new_initial_channel(const tal_t *ctx,
channel->htlcs = NULL;
channel->changes_pending[LOCAL] = channel->changes_pending[REMOTE]
= false;
channel->awaiting_revoke_and_ack = false;
channel->view[LOCAL].feerate_per_kw
= channel->view[REMOTE].feerate_per_kw

View File

@ -55,6 +55,9 @@ struct channel {
/* Do we have changes pending for ourselves/other? */
bool changes_pending[NUM_SIDES];
/* Are we waiting for their revoke_and_ack? */
bool awaiting_revoke_and_ack;
/* What it looks like to each side. */
struct channel_view view[NUM_SIDES];
};