@@ -131,6 +131,18 @@ pub(super) enum PendingHTLCRouting {
131
131
},
132
132
}
133
133
134
+ impl PendingHTLCRouting {
135
+ // `Some` if this is a blinded HTLC, with the inner value set to true if we are the intro node.
136
+ fn blinded(&self) -> Option<bool> {
137
+ match self {
138
+ Self::Forward { blinded, .. } => blinded.map(|b| b.we_are_intro_node),
139
+ Self::Receive { blinded: Some(()), .. } => Some(false),
140
+ Self::ReceiveKeysend { blinded: Some(()), .. } => Some(false),
141
+ _ => None,
142
+ }
143
+ }
144
+ }
145
+
134
146
#[derive(Clone)] // See Channel::revoke_and_ack for why, tl;dr: Rust bug
135
147
pub(super) struct PendingHTLCInfo {
136
148
pub(super) routing: PendingHTLCRouting,
@@ -198,6 +210,9 @@ pub(crate) struct HTLCPreviousHopData {
198
210
htlc_id: u64,
199
211
incoming_packet_shared_secret: [u8; 32],
200
212
phantom_shared_secret: Option<[u8; 32]>,
213
+ // `Some` if this is a blinded HTLC, and `Some(true)` if we are the intro node. Used for failing
214
+ // backwards correctly.
215
+ blinded: Option<bool>,
201
216
202
217
// This field is consumed by `claim_funds_from_hop()` when updating a force-closed backwards
203
218
// channel with a preimage provided by the forward channel.
@@ -3919,14 +3934,17 @@ where
3919
3934
err: format!("Payment with intercept id {} not found", log_bytes!(intercept_id.0))
3920
3935
})?;
3921
3936
3922
- if let PendingHTLCRouting::Forward { short_channel_id, .. } = payment.forward_info.routing {
3937
+ if let PendingHTLCRouting::Forward { short_channel_id, blinded, .. } =
3938
+ payment.forward_info.routing
3939
+ {
3923
3940
let htlc_source = HTLCSource::PreviousHopData(HTLCPreviousHopData {
3924
3941
short_channel_id: payment.prev_short_channel_id,
3925
3942
user_channel_id: Some(payment.prev_user_channel_id),
3926
3943
outpoint: payment.prev_funding_outpoint,
3927
3944
htlc_id: payment.prev_htlc_id,
3928
3945
incoming_packet_shared_secret: payment.forward_info.incoming_shared_secret,
3929
3946
phantom_shared_secret: None,
3947
+ blinded: blinded.map(|b| b.we_are_intro_node),
3930
3948
});
3931
3949
3932
3950
let failure_reason = HTLCFailReason::from_failure_code(0x4000 | 10);
@@ -3975,6 +3993,7 @@ where
3975
3993
htlc_id: prev_htlc_id,
3976
3994
incoming_packet_shared_secret: incoming_shared_secret,
3977
3995
phantom_shared_secret: $phantom_ss,
3996
+ blinded: routing.blinded(),
3978
3997
});
3979
3998
3980
3999
let reason = if $next_hop_unknown {
@@ -4004,7 +4023,7 @@ where
4004
4023
}
4005
4024
}
4006
4025
}
4007
- if let PendingHTLCRouting::Forward { onion_packet, .. } = routing {
4026
+ if let PendingHTLCRouting::Forward { ref onion_packet, .. } = routing {
4008
4027
let phantom_pubkey_res = self.node_signer.get_node_id(Recipient::PhantomNode);
4009
4028
if phantom_pubkey_res.is_ok() && fake_scid::is_valid_phantom(&self.fake_scid_rand_bytes, short_chan_id, &self.genesis_hash) {
4010
4029
let phantom_shared_secret = self.node_signer.ecdh(Recipient::PhantomNode, &onion_packet.public_key.unwrap(), None).unwrap().secret_bytes();
@@ -4095,6 +4114,7 @@ where
4095
4114
incoming_packet_shared_secret: incoming_shared_secret,
4096
4115
// Phantom payments are only PendingHTLCRouting::Receive.
4097
4116
phantom_shared_secret: None,
4117
+ blinded: blinded.map(|b| b.we_are_intro_node),
4098
4118
});
4099
4119
let next_blinding_point = if let Some(b) = blinded {
4100
4120
let encrypted_tlvs_ss = self.node_signer.ecdh(
@@ -4162,28 +4182,31 @@ where
4162
4182
skimmed_fee_msat, ..
4163
4183
}
4164
4184
}) => {
4165
- let (cltv_expiry, onion_payload, payment_data, phantom_shared_secret, mut onion_fields) = match routing {
4185
+ let (
4186
+ cltv_expiry, onion_payload, payment_data, phantom_shared_secret, mut onion_fields,
4187
+ blinded
4188
+ ) = match routing {
4166
4189
PendingHTLCRouting::Receive {
4167
4190
payment_data, payment_metadata, incoming_cltv_expiry, phantom_shared_secret,
4168
- custom_tlvs, ..
4191
+ custom_tlvs, blinded
4169
4192
} => {
4170
4193
let _legacy_hop_data = Some(payment_data.clone());
4171
4194
let onion_fields = RecipientOnionFields { payment_secret: Some(payment_data.payment_secret),
4172
4195
payment_metadata, custom_tlvs };
4173
4196
(incoming_cltv_expiry, OnionPayload::Invoice { _legacy_hop_data },
4174
- Some(payment_data), phantom_shared_secret, onion_fields)
4197
+ Some(payment_data), phantom_shared_secret, onion_fields, blinded )
4175
4198
},
4176
4199
PendingHTLCRouting::ReceiveKeysend {
4177
4200
payment_data, payment_preimage, payment_metadata, incoming_cltv_expiry,
4178
- custom_tlvs, ..
4201
+ custom_tlvs, blinded
4179
4202
} => {
4180
4203
let onion_fields = RecipientOnionFields {
4181
4204
payment_secret: payment_data.as_ref().map(|data| data.payment_secret),
4182
4205
payment_metadata,
4183
4206
custom_tlvs,
4184
4207
};
4185
4208
(incoming_cltv_expiry, OnionPayload::Spontaneous(payment_preimage),
4186
- payment_data, None, onion_fields)
4209
+ payment_data, None, onion_fields, blinded )
4187
4210
},
4188
4211
_ => {
4189
4212
panic!("short_channel_id == 0 should imply any pending_forward entries are of type Receive");
@@ -4197,6 +4220,7 @@ where
4197
4220
htlc_id: prev_htlc_id,
4198
4221
incoming_packet_shared_secret: incoming_shared_secret,
4199
4222
phantom_shared_secret,
4223
+ blinded: blinded.map(|()| false),
4200
4224
},
4201
4225
// We differentiate the received value from the sender intended value
4202
4226
// if possible so that we don't prematurely mark MPP payments complete
@@ -4227,6 +4251,7 @@ where
4227
4251
htlc_id: $htlc.prev_hop.htlc_id,
4228
4252
incoming_packet_shared_secret: $htlc.prev_hop.incoming_packet_shared_secret,
4229
4253
phantom_shared_secret,
4254
+ blinded: blinded.map(|()| false),
4230
4255
}), payment_hash,
4231
4256
HTLCFailReason::reason(0x4000 | 15, htlc_msat_height_data),
4232
4257
HTLCDestination::FailedPayment { payment_hash: $payment_hash },
@@ -6205,6 +6230,7 @@ where
6205
6230
htlc_id: prev_htlc_id,
6206
6231
incoming_packet_shared_secret: forward_info.incoming_shared_secret,
6207
6232
phantom_shared_secret: None,
6233
+ blinded: forward_info.routing.blinded(),
6208
6234
});
6209
6235
6210
6236
failed_intercept_forwards.push((htlc_source, forward_info.payment_hash,
@@ -7332,6 +7358,7 @@ where
7332
7358
incoming_packet_shared_secret: htlc.forward_info.incoming_shared_secret,
7333
7359
phantom_shared_secret: None,
7334
7360
outpoint: htlc.prev_funding_outpoint,
7361
+ blinded: htlc.forward_info.routing.blinded(),
7335
7362
});
7336
7363
7337
7364
let requested_forward_scid /* intercept scid */ = match htlc.forward_info.routing {
@@ -8153,6 +8180,7 @@ impl_writeable_tlv_based!(HTLCPreviousHopData, {
8153
8180
(4, htlc_id, required),
8154
8181
(6, incoming_packet_shared_secret, required),
8155
8182
(7, user_channel_id, option),
8183
+ (8, blinded, option),
8156
8184
});
8157
8185
8158
8186
impl Writeable for ClaimableHTLC {
0 commit comments