@@ -288,6 +288,11 @@ pub(super) enum HTLCForwardInfo {
288
288
htlc_id: u64,
289
289
err_packet: msgs::OnionErrorPacket,
290
290
},
291
+ FailMalformedHTLC {
292
+ htlc_id: u64,
293
+ failure_code: u16,
294
+ sha256_of_onion: [u8; 32],
295
+ },
291
296
}
292
297
293
298
// Used for failing blinded HTLCs backwards correctly.
@@ -4286,7 +4291,7 @@ where
4286
4291
fail_forward!(format!("Unknown short channel id {} for forward HTLC", short_chan_id), 0x4000 | 10, Vec::new(), None);
4287
4292
}
4288
4293
},
4289
- HTLCForwardInfo::FailHTLC { .. } => {
4294
+ HTLCForwardInfo::FailHTLC { .. } | HTLCForwardInfo::FailMalformedHTLC { .. } => {
4290
4295
// Channel went away before we could fail it. This implies
4291
4296
// the channel is now on chain and our counterparty is
4292
4297
// trying to broadcast the HTLC-Timeout, but that's their
@@ -4382,6 +4387,9 @@ where
4382
4387
continue;
4383
4388
}
4384
4389
},
4390
+ HTLCForwardInfo::FailMalformedHTLC { .. } => {
4391
+ todo!()
4392
+ },
4385
4393
}
4386
4394
}
4387
4395
} else {
@@ -4636,7 +4644,7 @@ where
4636
4644
},
4637
4645
};
4638
4646
},
4639
- HTLCForwardInfo::FailHTLC { .. } => {
4647
+ HTLCForwardInfo::FailHTLC { .. } | HTLCForwardInfo::FailMalformedHTLC { .. } => {
4640
4648
panic!("Got pending fail of our own HTLC");
4641
4649
}
4642
4650
}
@@ -9639,13 +9647,68 @@ impl_writeable_tlv_based!(PendingAddHTLCInfo, {
9639
9647
(6, prev_funding_outpoint, required),
9640
9648
});
9641
9649
9642
- impl_writeable_tlv_based_enum!(HTLCForwardInfo,
9643
- (1, FailHTLC) => {
9644
- (0, htlc_id, required),
9645
- (2, err_packet, required),
9646
- };
9647
- (0, AddHTLC)
9648
- );
9650
+ impl Writeable for HTLCForwardInfo {
9651
+ fn write<W: Writer>(&self, w: &mut W) -> Result<(), io::Error> {
9652
+ const FAIL_HTLC_VARIANT_ID: u8 = 1;
9653
+ match self {
9654
+ Self::AddHTLC(info) => {
9655
+ 0u8.write(w)?;
9656
+ info.write(w)?;
9657
+ },
9658
+ Self::FailHTLC { htlc_id, err_packet } => {
9659
+ FAIL_HTLC_VARIANT_ID.write(w)?;
9660
+ write_tlv_fields!(w, {
9661
+ (0, htlc_id, required),
9662
+ (2, err_packet, required),
9663
+ });
9664
+ },
9665
+ Self::FailMalformedHTLC { htlc_id, failure_code, sha256_of_onion } => {
9666
+ // Since this variant was added in 0.0.119, write this as `::FailHTLC` with an empty error
9667
+ // packet so older versions have something to fail back with, but serialize the real data as
9668
+ // optional TLVs for the benefit of newer versions.
9669
+ FAIL_HTLC_VARIANT_ID.write(w)?;
9670
+ let dummy_err_packet = msgs::OnionErrorPacket { data: Vec::new() };
9671
+ write_tlv_fields!(w, {
9672
+ (0, htlc_id, required),
9673
+ (1, failure_code, required),
9674
+ (2, dummy_err_packet, required),
9675
+ (3, sha256_of_onion, required),
9676
+ });
9677
+ },
9678
+ }
9679
+ Ok(())
9680
+ }
9681
+ }
9682
+
9683
+ impl Readable for HTLCForwardInfo {
9684
+ fn read<R: Read>(r: &mut R) -> Result<Self, DecodeError> {
9685
+ let id: u8 = Readable::read(r)?;
9686
+ Ok(match id {
9687
+ 0 => Self::AddHTLC(Readable::read(r)?),
9688
+ 1 => {
9689
+ _init_and_read_len_prefixed_tlv_fields!(r, {
9690
+ (0, htlc_id, required),
9691
+ (1, malformed_htlc_failure_code, option),
9692
+ (2, err_packet, required),
9693
+ (3, sha256_of_onion, option),
9694
+ });
9695
+ if let Some(failure_code) = malformed_htlc_failure_code {
9696
+ Self::FailMalformedHTLC {
9697
+ htlc_id: _init_tlv_based_struct_field!(htlc_id, required),
9698
+ failure_code,
9699
+ sha256_of_onion: sha256_of_onion.ok_or(DecodeError::InvalidValue)?,
9700
+ }
9701
+ } else {
9702
+ Self::FailHTLC {
9703
+ htlc_id: _init_tlv_based_struct_field!(htlc_id, required),
9704
+ err_packet: _init_tlv_based_struct_field!(err_packet, required),
9705
+ }
9706
+ }
9707
+ },
9708
+ _ => return Err(DecodeError::InvalidValue),
9709
+ })
9710
+ }
9711
+ }
9649
9712
9650
9713
impl_writeable_tlv_based!(PendingInboundPayment, {
9651
9714
(0, payment_secret, required),
0 commit comments