@@ -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.
@@ -3918,14 +3933,17 @@ where
3918
3933
err: format!("Payment with intercept id {} not found", log_bytes!(intercept_id.0))
3919
3934
})?;
3920
3935
3921
- if let PendingHTLCRouting::Forward { short_channel_id, .. } = payment.forward_info.routing {
3936
+ if let PendingHTLCRouting::Forward { short_channel_id, blinded, .. } =
3937
+ payment.forward_info.routing
3938
+ {
3922
3939
let htlc_source = HTLCSource::PreviousHopData(HTLCPreviousHopData {
3923
3940
short_channel_id: payment.prev_short_channel_id,
3924
3941
user_channel_id: Some(payment.prev_user_channel_id),
3925
3942
outpoint: payment.prev_funding_outpoint,
3926
3943
htlc_id: payment.prev_htlc_id,
3927
3944
incoming_packet_shared_secret: payment.forward_info.incoming_shared_secret,
3928
3945
phantom_shared_secret: None,
3946
+ blinded: blinded.map(|b| b.we_are_intro_node),
3929
3947
});
3930
3948
3931
3949
let failure_reason = HTLCFailReason::from_failure_code(0x4000 | 10);
@@ -3974,6 +3992,7 @@ where
3974
3992
htlc_id: prev_htlc_id,
3975
3993
incoming_packet_shared_secret: incoming_shared_secret,
3976
3994
phantom_shared_secret: $phantom_ss,
3995
+ blinded: routing.blinded(),
3977
3996
});
3978
3997
3979
3998
let reason = if $next_hop_unknown {
@@ -4003,7 +4022,7 @@ where
4003
4022
}
4004
4023
}
4005
4024
}
4006
- if let PendingHTLCRouting::Forward { onion_packet, .. } = routing {
4025
+ if let PendingHTLCRouting::Forward { ref onion_packet, .. } = routing {
4007
4026
let phantom_pubkey_res = self.node_signer.get_node_id(Recipient::PhantomNode);
4008
4027
if phantom_pubkey_res.is_ok() && fake_scid::is_valid_phantom(&self.fake_scid_rand_bytes, short_chan_id, &self.genesis_hash) {
4009
4028
let phantom_shared_secret = self.node_signer.ecdh(Recipient::PhantomNode, &onion_packet.public_key.unwrap(), None).unwrap().secret_bytes();
@@ -4094,6 +4113,7 @@ where
4094
4113
incoming_packet_shared_secret: incoming_shared_secret,
4095
4114
// Phantom payments are only PendingHTLCRouting::Receive.
4096
4115
phantom_shared_secret: None,
4116
+ blinded: blinded.map(|b| b.we_are_intro_node),
4097
4117
});
4098
4118
let next_blinding_point = if let Some(b) = blinded {
4099
4119
let encrypted_tlvs_ss = self.node_signer.ecdh(
@@ -4161,28 +4181,31 @@ where
4161
4181
skimmed_fee_msat, ..
4162
4182
}
4163
4183
}) => {
4164
- let (cltv_expiry, onion_payload, payment_data, phantom_shared_secret, mut onion_fields) = match routing {
4184
+ let (
4185
+ cltv_expiry, onion_payload, payment_data, phantom_shared_secret, mut onion_fields,
4186
+ blinded
4187
+ ) = match routing {
4165
4188
PendingHTLCRouting::Receive {
4166
4189
payment_data, payment_metadata, incoming_cltv_expiry, phantom_shared_secret,
4167
- custom_tlvs, ..
4190
+ custom_tlvs, blinded
4168
4191
} => {
4169
4192
let _legacy_hop_data = Some(payment_data.clone());
4170
4193
let onion_fields = RecipientOnionFields { payment_secret: Some(payment_data.payment_secret),
4171
4194
payment_metadata, custom_tlvs };
4172
4195
(incoming_cltv_expiry, OnionPayload::Invoice { _legacy_hop_data },
4173
- Some(payment_data), phantom_shared_secret, onion_fields)
4196
+ Some(payment_data), phantom_shared_secret, onion_fields, blinded )
4174
4197
},
4175
4198
PendingHTLCRouting::ReceiveKeysend {
4176
4199
payment_data, payment_preimage, payment_metadata, incoming_cltv_expiry,
4177
- custom_tlvs, ..
4200
+ custom_tlvs, blinded
4178
4201
} => {
4179
4202
let onion_fields = RecipientOnionFields {
4180
4203
payment_secret: payment_data.as_ref().map(|data| data.payment_secret),
4181
4204
payment_metadata,
4182
4205
custom_tlvs,
4183
4206
};
4184
4207
(incoming_cltv_expiry, OnionPayload::Spontaneous(payment_preimage),
4185
- payment_data, None, onion_fields)
4208
+ payment_data, None, onion_fields, blinded )
4186
4209
},
4187
4210
_ => {
4188
4211
panic!("short_channel_id == 0 should imply any pending_forward entries are of type Receive");
@@ -4196,6 +4219,7 @@ where
4196
4219
htlc_id: prev_htlc_id,
4197
4220
incoming_packet_shared_secret: incoming_shared_secret,
4198
4221
phantom_shared_secret,
4222
+ blinded: blinded.map(|()| false),
4199
4223
},
4200
4224
// We differentiate the received value from the sender intended value
4201
4225
// if possible so that we don't prematurely mark MPP payments complete
@@ -4226,6 +4250,7 @@ where
4226
4250
htlc_id: $htlc.prev_hop.htlc_id,
4227
4251
incoming_packet_shared_secret: $htlc.prev_hop.incoming_packet_shared_secret,
4228
4252
phantom_shared_secret,
4253
+ blinded: blinded.map(|()| false),
4229
4254
}), payment_hash,
4230
4255
HTLCFailReason::reason(0x4000 | 15, htlc_msat_height_data),
4231
4256
HTLCDestination::FailedPayment { payment_hash: $payment_hash },
@@ -6204,6 +6229,7 @@ where
6204
6229
htlc_id: prev_htlc_id,
6205
6230
incoming_packet_shared_secret: forward_info.incoming_shared_secret,
6206
6231
phantom_shared_secret: None,
6232
+ blinded: forward_info.routing.blinded(),
6207
6233
});
6208
6234
6209
6235
failed_intercept_forwards.push((htlc_source, forward_info.payment_hash,
@@ -7331,6 +7357,7 @@ where
7331
7357
incoming_packet_shared_secret: htlc.forward_info.incoming_shared_secret,
7332
7358
phantom_shared_secret: None,
7333
7359
outpoint: htlc.prev_funding_outpoint,
7360
+ blinded: htlc.forward_info.routing.blinded(),
7334
7361
});
7335
7362
7336
7363
let requested_forward_scid /* intercept scid */ = match htlc.forward_info.routing {
@@ -8152,6 +8179,7 @@ impl_writeable_tlv_based!(HTLCPreviousHopData, {
8152
8179
(4, htlc_id, required),
8153
8180
(6, incoming_packet_shared_secret, required),
8154
8181
(7, user_channel_id, option),
8182
+ (8, blinded, option),
8155
8183
});
8156
8184
8157
8185
impl Writeable for ClaimableHTLC {
0 commit comments