@@ -359,15 +359,32 @@ struct ReceiveError {
359359pub enum FailureCode {
360360	/// We had a temporary error processing the payment. Useful if no other error codes fit
361361	/// and you want to indicate that the payer may want to retry.
362- 	TemporaryNodeFailure             = 0x2000 | 2 ,
362+ 	TemporaryNodeFailure,
363363	/// We have a required feature which was not in this onion. For example, you may require
364364	/// some additional metadata that was not provided with this payment.
365- 	RequiredNodeFeatureMissing       = 0x4000 | 0x2000 | 3 ,
365+ 	RequiredNodeFeatureMissing,
366366	/// You may wish to use this when a `payment_preimage` is unknown, or the CLTV expiry of
367367	/// the HTLC is too close to the current block height for safe handling.
368368	/// Using this failure code in [`ChannelManager::fail_htlc_backwards_with_reason`] is
369369	/// 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+ 	}
371388}
372389
373390/// Error type returned across the peer_state mutex boundary. When an Err is generated for a
@@ -4570,12 +4587,19 @@ where
45704587	/// Gets error data to form an [`HTLCFailReason`] given a [`FailureCode`] and [`ClaimableHTLC`].
45714588	fn get_htlc_fail_reason_from_failure_code(&self, failure_code: FailureCode, htlc: &ClaimableHTLC) -> HTLCFailReason {
45724589		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() ),
45754592			FailureCode::IncorrectOrUnknownPaymentDetails => {
45764593				let mut htlc_msat_height_data = htlc.value.to_be_bytes().to_vec();
45774594				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)
45794603			}
45804604		}
45814605	}
0 commit comments