@@ -359,15 +359,32 @@ struct ReceiveError {
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
@@ -4570,12 +4587,19 @@ where
4570
4587
/// Gets error data to form an [`HTLCFailReason`] given a [`FailureCode`] and [`ClaimableHTLC`].
4571
4588
fn get_htlc_fail_reason_from_failure_code(&self, failure_code: FailureCode, htlc: &ClaimableHTLC) -> HTLCFailReason {
4572
4589
match failure_code {
4573
- FailureCode::TemporaryNodeFailure => HTLCFailReason::from_failure_code(failure_code as u16 ),
4574
- FailureCode::RequiredNodeFeatureMissing => HTLCFailReason::from_failure_code(failure_code as u16 ),
4590
+ FailureCode::TemporaryNodeFailure => HTLCFailReason::from_failure_code(failure_code.into() ),
4591
+ FailureCode::RequiredNodeFeatureMissing => HTLCFailReason::from_failure_code(failure_code.into() ),
4575
4592
FailureCode::IncorrectOrUnknownPaymentDetails => {
4576
4593
let mut htlc_msat_height_data = htlc.value.to_be_bytes().to_vec();
4577
4594
htlc_msat_height_data.extend_from_slice(&self.best_block.read().unwrap().height().to_be_bytes());
4578
- HTLCFailReason::reason(failure_code as u16, htlc_msat_height_data)
4595
+ HTLCFailReason::reason(failure_code.into(), htlc_msat_height_data)
4596
+ },
4597
+ FailureCode::InvalidOnionPayload(data) => {
4598
+ let fail_data = match data {
4599
+ Some((typ, offset)) => [BigSize(typ).encode(), offset.encode()].concat(),
4600
+ None => Vec::new(),
4601
+ };
4602
+ HTLCFailReason::reason(failure_code.into(), fail_data)
4579
4603
}
4580
4604
}
4581
4605
}
0 commit comments