daemon: don't allow fulfill/fail on uncommitted HTLCs.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
This commit is contained in:
Rusty Russell 2016-05-26 15:25:24 +09:30
parent f43cc72d6a
commit 0ceee86098

View File

@ -2267,6 +2267,18 @@ const struct json_command newhtlc_command = {
"Returns an empty result on success" "Returns an empty result on success"
}; };
/* Looks for their HTLC, but must be committed. */
static size_t find_their_committed_htlc(struct peer *peer,
const struct sha256 *rhash)
{
/* Must be in last committed cstate. */
if (funding_find_htlc(&peer->them.commit->cstate->a, rhash)
== tal_count(peer->them.commit->cstate->a.htlcs))
return tal_count(peer->them.staging_cstate->a.htlcs);
return funding_find_htlc(&peer->them.staging_cstate->a, rhash);
}
struct fulfillhtlc { struct fulfillhtlc {
struct command *jsoncmd; struct command *jsoncmd;
struct sha256 r; struct sha256 r;
@ -2284,7 +2296,7 @@ static void do_fullfill(struct peer *peer,
sha256(&rhash, &fulfillhtlc->r, sizeof(fulfillhtlc->r)); sha256(&rhash, &fulfillhtlc->r, sizeof(fulfillhtlc->r));
i = funding_find_htlc(&peer->them.staging_cstate->a, &rhash); i = find_their_committed_htlc(peer, &rhash);
if (i == tal_count(peer->them.staging_cstate->a.htlcs)) { if (i == tal_count(peer->them.staging_cstate->a.htlcs)) {
command_fail(fulfillhtlc->jsoncmd, "preimage htlc not found"); command_fail(fulfillhtlc->jsoncmd, "preimage htlc not found");
return; return;
@ -2358,8 +2370,7 @@ static void do_failhtlc(struct peer *peer,
/* Look in peer->them.staging_cstate->a, as that's where we'll /* Look in peer->them.staging_cstate->a, as that's where we'll
* immediately remove it from: avoids double-handling. */ * immediately remove it from: avoids double-handling. */
/* FIXME: Make sure it's also committed in previous commit tx! */ i = find_their_committed_htlc(peer, &failhtlc->rhash);
i = funding_find_htlc(&peer->them.staging_cstate->a, &failhtlc->rhash);
if (i == tal_count(peer->them.staging_cstate->a.htlcs)) { if (i == tal_count(peer->them.staging_cstate->a.htlcs)) {
command_fail(failhtlc->jsoncmd, "htlc not found"); command_fail(failhtlc->jsoncmd, "htlc not found");
return; return;