Correct Channel outbound HTLC serialization 2021-04-fix-htlc-ser
authorMatt Corallo <git@bluematt.me>
Wed, 21 Apr 2021 20:47:24 +0000 (20:47 +0000)
committerMatt Corallo <git@bluematt.me>
Mon, 31 May 2021 18:20:22 +0000 (18:20 +0000)
Channel serialization should happen "as if
remove_uncommitted_htlcs_and_mark_paused had just been called".

This is true for the most part, but outbound RemoteRemoved HTLCs
were being serialized as normal, even though
`remote_uncommitted_htlcs_and_mark_paused` resets them to
`Committed`.

This led to a bug identified by the `chanmon_consistency_target`
fuzzer wherein, if we receive a update_*_htlc message bug not the
corresponding commitment_signed prior to a serialization roundtrip,
we'd force-close the channel due to the peer "attempting to
fail/claim an HTLC which was already failed/claimed".

lightning/src/ln/channel.rs

index dbc63c957ff7e2a20d2416a5713e972e87ac755d..689f5e6b52ac78066006bcbd6f2f06c1a70ff85a 100644 (file)
@@ -4451,9 +4451,10 @@ impl<Signer: Sign> Writeable for Channel<Signer> {
                                &OutboundHTLCState::Committed => {
                                        1u8.write(writer)?;
                                },
-                               &OutboundHTLCState::RemoteRemoved(ref fail_reason) => {
-                                       2u8.write(writer)?;
-                                       fail_reason.write(writer)?;
+                               &OutboundHTLCState::RemoteRemoved(_) => {
+                                       // Treat this as a Committed because we haven't received the CS - they'll
+                                       // resend the claim/fail on reconnect as we all (hopefully) the missing CS.
+                                       1u8.write(writer)?;
                                },
                                &OutboundHTLCState::AwaitingRemoteRevokeToRemove(ref fail_reason) => {
                                        3u8.write(writer)?;