@@ -114,6 +114,9 @@ pub(super) enum PendingHTLCRouting {
114
114
phantom_shared_secret: Option<[u8; 32]>,
115
115
/// See [`RecipientOnionFields::custom_tlvs`] for more info.
116
116
custom_tlvs: Vec<(u64, Vec<u8>)>,
117
+ /// `Some` if this corresponds to a blinded HTLC. Used for failing backwards properly. We use an
118
+ /// option to maintain compatibility with LDK versions prior to 0.0.117.
119
+ blinded: Option<()>,
117
120
},
118
121
ReceiveKeysend {
119
122
/// This was added in 0.0.116 and will break deserialization on downgrades.
@@ -123,6 +126,8 @@ pub(super) enum PendingHTLCRouting {
123
126
incoming_cltv_expiry: u32, // Used to track when we should expire pending HTLCs that go unclaimed
124
127
/// See [`RecipientOnionFields::custom_tlvs`] for more info.
125
128
custom_tlvs: Vec<(u64, Vec<u8>)>,
129
+ /// See [`Self::Receive::blinded`] docs.
130
+ blinded: Option<()>,
126
131
},
127
132
}
128
133
@@ -181,7 +186,7 @@ pub(super) enum HTLCForwardInfo {
181
186
#[derive(Clone, Copy, Hash, PartialEq, Eq)]
182
187
pub(super) struct BlindedForward {
183
188
inbound_blinding_point: PublicKey,
184
- // Another field will be added later for error handling.
189
+ we_are_intro_node: bool,
185
190
}
186
191
187
192
/// Tracks the inbound corresponding to an outbound HTLC
@@ -2772,6 +2777,7 @@ where
2772
2777
blinded: intro_node_blinding_pt.or(msg.blinding_point)
2773
2778
.map(|bp| BlindedForward {
2774
2779
inbound_blinding_point: bp,
2780
+ we_are_intro_node: intro_node_blinding_pt.is_some(),
2775
2781
}),
2776
2782
},
2777
2783
payment_hash: msg.payment_hash,
@@ -2788,16 +2794,21 @@ where
2788
2794
amt_msat: u64, cltv_expiry: u32, phantom_shared_secret: Option<[u8; 32]>, allow_underpay: bool,
2789
2795
counterparty_skimmed_fee_msat: Option<u64>,
2790
2796
) -> Result<PendingHTLCInfo, InboundOnionErr> {
2791
- let (payment_data, keysend_preimage, custom_tlvs, onion_amt_msat, outgoing_cltv_value, payment_metadata) = match hop_data {
2797
+ let (
2798
+ payment_data, keysend_preimage, custom_tlvs, onion_amt_msat, outgoing_cltv_value,
2799
+ payment_metadata, blinded
2800
+ ) = match hop_data {
2792
2801
msgs::InboundOnionPayload::Receive {
2793
2802
payment_data, keysend_preimage, custom_tlvs, amt_msat, outgoing_cltv_value, payment_metadata, ..
2794
2803
} =>
2795
- (payment_data, keysend_preimage, custom_tlvs, amt_msat, outgoing_cltv_value, payment_metadata),
2804
+ (payment_data, keysend_preimage, custom_tlvs, amt_msat, outgoing_cltv_value,
2805
+ payment_metadata, None),
2796
2806
msgs::InboundOnionPayload::BlindedReceive {
2797
- amt_msat, total_msat, outgoing_cltv_value, payment_secret, ..
2807
+ amt_msat, total_msat, outgoing_cltv_value, payment_secret, intro_node_blinding_point, ..
2798
2808
} => {
2799
2809
let payment_data = msgs::FinalOnionHopData { payment_secret, total_msat };
2800
- (Some(payment_data), None, Vec::new(), amt_msat, outgoing_cltv_value, None)
2810
+ let blinded = if intro_node_blinding_point.is_none() { Some(()) } else { None };
2811
+ (Some(payment_data), None, Vec::new(), amt_msat, outgoing_cltv_value, None, blinded)
2801
2812
}
2802
2813
msgs::InboundOnionPayload::Forward { .. } => {
2803
2814
return Err(InboundOnionErr {
@@ -2877,6 +2888,7 @@ where
2877
2888
payment_metadata,
2878
2889
incoming_cltv_expiry: outgoing_cltv_value,
2879
2890
custom_tlvs,
2891
+ blinded,
2880
2892
}
2881
2893
} else if let Some(data) = payment_data {
2882
2894
PendingHTLCRouting::Receive {
@@ -2885,6 +2897,7 @@ where
2885
2897
incoming_cltv_expiry: outgoing_cltv_value,
2886
2898
phantom_shared_secret,
2887
2899
custom_tlvs,
2900
+ blinded,
2888
2901
}
2889
2902
} else {
2890
2903
return Err(InboundOnionErr {
@@ -4150,14 +4163,20 @@ where
4150
4163
}
4151
4164
}) => {
4152
4165
let (cltv_expiry, onion_payload, payment_data, phantom_shared_secret, mut onion_fields) = match routing {
4153
- PendingHTLCRouting::Receive { payment_data, payment_metadata, incoming_cltv_expiry, phantom_shared_secret, custom_tlvs } => {
4166
+ PendingHTLCRouting::Receive {
4167
+ payment_data, payment_metadata, incoming_cltv_expiry, phantom_shared_secret,
4168
+ custom_tlvs, ..
4169
+ } => {
4154
4170
let _legacy_hop_data = Some(payment_data.clone());
4155
4171
let onion_fields = RecipientOnionFields { payment_secret: Some(payment_data.payment_secret),
4156
4172
payment_metadata, custom_tlvs };
4157
4173
(incoming_cltv_expiry, OnionPayload::Invoice { _legacy_hop_data },
4158
4174
Some(payment_data), phantom_shared_secret, onion_fields)
4159
4175
},
4160
- PendingHTLCRouting::ReceiveKeysend { payment_data, payment_preimage, payment_metadata, incoming_cltv_expiry, custom_tlvs } => {
4176
+ PendingHTLCRouting::ReceiveKeysend {
4177
+ payment_data, payment_preimage, payment_metadata, incoming_cltv_expiry,
4178
+ custom_tlvs, ..
4179
+ } => {
4161
4180
let onion_fields = RecipientOnionFields {
4162
4181
payment_secret: payment_data.as_ref().map(|data| data.payment_secret),
4163
4182
payment_metadata,
@@ -8026,6 +8045,7 @@ impl_writeable_tlv_based_enum!(PendingHTLCRouting,
8026
8045
(1, phantom_shared_secret, option),
8027
8046
(2, incoming_cltv_expiry, required),
8028
8047
(3, payment_metadata, option),
8048
+ (4, blinded, option),
8029
8049
(5, custom_tlvs, optional_vec),
8030
8050
},
8031
8051
(2, ReceiveKeysend) => {
@@ -8034,11 +8054,13 @@ impl_writeable_tlv_based_enum!(PendingHTLCRouting,
8034
8054
(3, payment_metadata, option),
8035
8055
(4, payment_data, option), // Added in 0.0.116
8036
8056
(5, custom_tlvs, optional_vec),
8057
+ (6, blinded, option),
8037
8058
},
8038
8059
;);
8039
8060
8040
8061
impl_writeable_tlv_based!(BlindedForward, {
8041
8062
(0, inbound_blinding_point, required),
8063
+ (2, we_are_intro_node, required),
8042
8064
});
8043
8065
8044
8066
impl_writeable_tlv_based!(PendingHTLCInfo, {
0 commit comments