Skip to content

Commit d1bd3ce

Browse files
Track whether a payment is blinded in HTLCPreviousHopData
This will allow us to fail blinded HTLCs backwards properly.
1 parent 2e3b378 commit d1bd3ce

File tree

1 file changed

+35
-7
lines changed

1 file changed

+35
-7
lines changed

lightning/src/ln/channelmanager.rs

Lines changed: 35 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,18 @@ pub(super) enum PendingHTLCRouting {
131131
},
132132
}
133133

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+
134146
#[derive(Clone)] // See Channel::revoke_and_ack for why, tl;dr: Rust bug
135147
pub(super) struct PendingHTLCInfo {
136148
pub(super) routing: PendingHTLCRouting,
@@ -198,6 +210,9 @@ pub(crate) struct HTLCPreviousHopData {
198210
htlc_id: u64,
199211
incoming_packet_shared_secret: [u8; 32],
200212
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>,
201216

202217
// This field is consumed by `claim_funds_from_hop()` when updating a force-closed backwards
203218
// channel with a preimage provided by the forward channel.
@@ -3919,14 +3934,17 @@ where
39193934
err: format!("Payment with intercept id {} not found", log_bytes!(intercept_id.0))
39203935
})?;
39213936

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+
{
39233940
let htlc_source = HTLCSource::PreviousHopData(HTLCPreviousHopData {
39243941
short_channel_id: payment.prev_short_channel_id,
39253942
user_channel_id: Some(payment.prev_user_channel_id),
39263943
outpoint: payment.prev_funding_outpoint,
39273944
htlc_id: payment.prev_htlc_id,
39283945
incoming_packet_shared_secret: payment.forward_info.incoming_shared_secret,
39293946
phantom_shared_secret: None,
3947+
blinded: blinded.map(|b| b.we_are_intro_node),
39303948
});
39313949

39323950
let failure_reason = HTLCFailReason::from_failure_code(0x4000 | 10);
@@ -3975,6 +3993,7 @@ where
39753993
htlc_id: prev_htlc_id,
39763994
incoming_packet_shared_secret: incoming_shared_secret,
39773995
phantom_shared_secret: $phantom_ss,
3996+
blinded: routing.blinded(),
39783997
});
39793998

39803999
let reason = if $next_hop_unknown {
@@ -4004,7 +4023,7 @@ where
40044023
}
40054024
}
40064025
}
4007-
if let PendingHTLCRouting::Forward { onion_packet, .. } = routing {
4026+
if let PendingHTLCRouting::Forward { ref onion_packet, .. } = routing {
40084027
let phantom_pubkey_res = self.node_signer.get_node_id(Recipient::PhantomNode);
40094028
if phantom_pubkey_res.is_ok() && fake_scid::is_valid_phantom(&self.fake_scid_rand_bytes, short_chan_id, &self.genesis_hash) {
40104029
let phantom_shared_secret = self.node_signer.ecdh(Recipient::PhantomNode, &onion_packet.public_key.unwrap(), None).unwrap().secret_bytes();
@@ -4095,6 +4114,7 @@ where
40954114
incoming_packet_shared_secret: incoming_shared_secret,
40964115
// Phantom payments are only PendingHTLCRouting::Receive.
40974116
phantom_shared_secret: None,
4117+
blinded: blinded.map(|b| b.we_are_intro_node),
40984118
});
40994119
let next_blinding_point = if let Some(b) = blinded {
41004120
let encrypted_tlvs_ss = self.node_signer.ecdh(
@@ -4162,28 +4182,31 @@ where
41624182
skimmed_fee_msat, ..
41634183
}
41644184
}) => {
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 {
41664189
PendingHTLCRouting::Receive {
41674190
payment_data, payment_metadata, incoming_cltv_expiry, phantom_shared_secret,
4168-
custom_tlvs, ..
4191+
custom_tlvs, blinded
41694192
} => {
41704193
let _legacy_hop_data = Some(payment_data.clone());
41714194
let onion_fields = RecipientOnionFields { payment_secret: Some(payment_data.payment_secret),
41724195
payment_metadata, custom_tlvs };
41734196
(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)
41754198
},
41764199
PendingHTLCRouting::ReceiveKeysend {
41774200
payment_data, payment_preimage, payment_metadata, incoming_cltv_expiry,
4178-
custom_tlvs, ..
4201+
custom_tlvs, blinded
41794202
} => {
41804203
let onion_fields = RecipientOnionFields {
41814204
payment_secret: payment_data.as_ref().map(|data| data.payment_secret),
41824205
payment_metadata,
41834206
custom_tlvs,
41844207
};
41854208
(incoming_cltv_expiry, OnionPayload::Spontaneous(payment_preimage),
4186-
payment_data, None, onion_fields)
4209+
payment_data, None, onion_fields, blinded)
41874210
},
41884211
_ => {
41894212
panic!("short_channel_id == 0 should imply any pending_forward entries are of type Receive");
@@ -4197,6 +4220,7 @@ where
41974220
htlc_id: prev_htlc_id,
41984221
incoming_packet_shared_secret: incoming_shared_secret,
41994222
phantom_shared_secret,
4223+
blinded: blinded.map(|()| false),
42004224
},
42014225
// We differentiate the received value from the sender intended value
42024226
// if possible so that we don't prematurely mark MPP payments complete
@@ -4227,6 +4251,7 @@ where
42274251
htlc_id: $htlc.prev_hop.htlc_id,
42284252
incoming_packet_shared_secret: $htlc.prev_hop.incoming_packet_shared_secret,
42294253
phantom_shared_secret,
4254+
blinded: blinded.map(|()| false),
42304255
}), payment_hash,
42314256
HTLCFailReason::reason(0x4000 | 15, htlc_msat_height_data),
42324257
HTLCDestination::FailedPayment { payment_hash: $payment_hash },
@@ -6205,6 +6230,7 @@ where
62056230
htlc_id: prev_htlc_id,
62066231
incoming_packet_shared_secret: forward_info.incoming_shared_secret,
62076232
phantom_shared_secret: None,
6233+
blinded: forward_info.routing.blinded(),
62086234
});
62096235

62106236
failed_intercept_forwards.push((htlc_source, forward_info.payment_hash,
@@ -7332,6 +7358,7 @@ where
73327358
incoming_packet_shared_secret: htlc.forward_info.incoming_shared_secret,
73337359
phantom_shared_secret: None,
73347360
outpoint: htlc.prev_funding_outpoint,
7361+
blinded: htlc.forward_info.routing.blinded(),
73357362
});
73367363

73377364
let requested_forward_scid /* intercept scid */ = match htlc.forward_info.routing {
@@ -8153,6 +8180,7 @@ impl_writeable_tlv_based!(HTLCPreviousHopData, {
81538180
(4, htlc_id, required),
81548181
(6, incoming_packet_shared_secret, required),
81558182
(7, user_channel_id, option),
8183+
(8, blinded, option),
81568184
});
81578185

81588186
impl Writeable for ClaimableHTLC {

0 commit comments

Comments
 (0)