@@ -359,15 +359,32 @@ struct InboundOnionErr {
359
359
pub enum FailureCode {
360
360
/// We had a temporary error processing the payment. Useful if no other error codes fit
361
361
/// and you want to indicate that the payer may want to retry.
362
- TemporaryNodeFailure = 0x2000 | 2 ,
362
+ TemporaryNodeFailure,
363
363
/// We have a required feature which was not in this onion. For example, you may require
364
364
/// some additional metadata that was not provided with this payment.
365
- RequiredNodeFeatureMissing = 0x4000 | 0x2000 | 3 ,
365
+ RequiredNodeFeatureMissing,
366
366
/// You may wish to use this when a `payment_preimage` is unknown, or the CLTV expiry of
367
367
/// the HTLC is too close to the current block height for safe handling.
368
368
/// Using this failure code in [`ChannelManager::fail_htlc_backwards_with_reason`] is
369
369
/// equivalent to calling [`ChannelManager::fail_htlc_backwards`].
370
- IncorrectOrUnknownPaymentDetails = 0x4000 | 15 ,
370
+ IncorrectOrUnknownPaymentDetails,
371
+ /// We failed to process the payload after the onion was decrypted. You may wish to
372
+ /// use this when receiving custom HTLC TLVs with even type numbers that you don't recognize.
373
+ ///
374
+ /// If available, the tuple data may include the type number and byte offset in the
375
+ /// decrypted byte stream where the failure occurred.
376
+ InvalidOnionPayload(Option<(u64, u16)>),
377
+ }
378
+
379
+ impl Into<u16> for FailureCode {
380
+ fn into(self) -> u16 {
381
+ match self {
382
+ FailureCode::TemporaryNodeFailure => 0x2000 | 2,
383
+ FailureCode::RequiredNodeFeatureMissing => 0x4000 | 0x2000 | 3,
384
+ FailureCode::IncorrectOrUnknownPaymentDetails => 0x4000 | 15,
385
+ FailureCode::InvalidOnionPayload(_) => 0x4000 | 22,
386
+ }
387
+ }
371
388
}
372
389
373
390
/// Error type returned across the peer_state mutex boundary. When an Err is generated for a
@@ -4583,12 +4600,19 @@ where
4583
4600
/// Gets error data to form an [`HTLCFailReason`] given a [`FailureCode`] and [`ClaimableHTLC`].
4584
4601
fn get_htlc_fail_reason_from_failure_code(&self, failure_code: FailureCode, htlc: &ClaimableHTLC) -> HTLCFailReason {
4585
4602
match failure_code {
4586
- FailureCode :: TemporaryNodeFailure => HTLCFailReason :: from_failure_code ( failure_code as u16 ) ,
4587
- FailureCode :: RequiredNodeFeatureMissing => HTLCFailReason :: from_failure_code ( failure_code as u16 ) ,
4603
+ FailureCode::TemporaryNodeFailure => HTLCFailReason::from_failure_code(failure_code.into() ),
4604
+ FailureCode::RequiredNodeFeatureMissing => HTLCFailReason::from_failure_code(failure_code.into() ),
4588
4605
FailureCode::IncorrectOrUnknownPaymentDetails => {
4589
4606
let mut htlc_msat_height_data = htlc.value.to_be_bytes().to_vec();
4590
4607
htlc_msat_height_data.extend_from_slice(&self.best_block.read().unwrap().height().to_be_bytes());
4591
- HTLCFailReason :: reason ( failure_code as u16 , htlc_msat_height_data)
4608
+ HTLCFailReason::reason(failure_code.into(), htlc_msat_height_data)
4609
+ },
4610
+ FailureCode::InvalidOnionPayload(data) => {
4611
+ let fail_data = match data {
4612
+ Some((typ, offset)) => [BigSize(typ).encode(), offset.encode()].concat(),
4613
+ None => Vec::new(),
4614
+ };
4615
+ HTLCFailReason::reason(failure_code.into(), fail_data)
4592
4616
}
4593
4617
}
4594
4618
}
0 commit comments