From: Matt Corallo Date: Thu, 23 Aug 2018 21:02:29 +0000 (-0400) Subject: Fix duplicate payment_hashes one immediately failed, one fail crash X-Git-Tag: v0.0.12~340^2~1 X-Git-Url: http://git.bitcoin.ninja/index.cgi?a=commitdiff_plain;h=dfc04ad0b4a70649c07625aa80c8bb8587718cc2;p=rust-lightning Fix duplicate payment_hashes one immediately failed, one fail crash Found by fuzzer --- diff --git a/src/ln/channel.rs b/src/ln/channel.rs index 7d858555f..47c05de2a 100644 --- a/src/ln/channel.rs +++ b/src/ln/channel.rs @@ -1131,17 +1131,24 @@ impl Channel { if htlc_id != 0 { panic!("Duplicate HTLC payment_hash, you probably re-used payment preimages, NEVER DO THIS!"); } - htlc_id = htlc.htlc_id; - htlc_amount_msat += htlc.amount_msat; if htlc.state == HTLCState::Committed { htlc.state = HTLCState::LocalRemoved; } else if htlc.state == HTLCState::RemoteAnnounced { - panic!("Somehow forwarded HTLC prior to remote revocation!"); + if let Some(PendingHTLCStatus::Forward(_)) = htlc.pending_forward_state { + panic!("Somehow forwarded HTLC prior to remote revocation!"); + } else { + // We have to pretend this isn't here - we're probably a duplicate with the + // same payment_hash as some other HTLC, and the other is getting failed, + // we'll fail this one as soon as remote commits to it. + continue; + } } else if htlc.state == HTLCState::LocalRemoved || htlc.state == HTLCState::LocalRemovedAwaitingCommitment { return Err(HandleError{err: "Unable to find a pending HTLC which matched the given payment preimage", action: None}); } else { panic!("Have an inbound HTLC when not awaiting remote revoke that had a garbage state"); } + htlc_id = htlc.htlc_id; + htlc_amount_msat += htlc.amount_msat; } } if htlc_amount_msat == 0 {