Skip to content

Commit 0254890

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

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.
@@ -3918,14 +3933,17 @@ where
39183933
err: format!("Payment with intercept id {} not found", log_bytes!(intercept_id.0))
39193934
})?;
39203935

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

39313949
let failure_reason = HTLCFailReason::from_failure_code(0x4000 | 10);
@@ -3974,6 +3992,7 @@ where
39743992
htlc_id: prev_htlc_id,
39753993
incoming_packet_shared_secret: incoming_shared_secret,
39763994
phantom_shared_secret: $phantom_ss,
3995+
blinded: routing.blinded(),
39773996
});
39783997

39793998
let reason = if $next_hop_unknown {
@@ -4003,7 +4022,7 @@ where
40034022
}
40044023
}
40054024
}
4006-
if let PendingHTLCRouting::Forward { onion_packet, .. } = routing {
4025+
if let PendingHTLCRouting::Forward { ref onion_packet, .. } = routing {
40074026
let phantom_pubkey_res = self.node_signer.get_node_id(Recipient::PhantomNode);
40084027
if phantom_pubkey_res.is_ok() && fake_scid::is_valid_phantom(&self.fake_scid_rand_bytes, short_chan_id, &self.genesis_hash) {
40094028
let phantom_shared_secret = self.node_signer.ecdh(Recipient::PhantomNode, &onion_packet.public_key.unwrap(), None).unwrap().secret_bytes();
@@ -4094,6 +4113,7 @@ where
40944113
incoming_packet_shared_secret: incoming_shared_secret,
40954114
// Phantom payments are only PendingHTLCRouting::Receive.
40964115
phantom_shared_secret: None,
4116+
blinded: blinded.map(|b| b.we_are_intro_node),
40974117
});
40984118
let next_blinding_point = if let Some(b) = blinded {
40994119
let encrypted_tlvs_ss = self.node_signer.ecdh(
@@ -4161,28 +4181,31 @@ where
41614181
skimmed_fee_msat, ..
41624182
}
41634183
}) => {
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 {
41654188
PendingHTLCRouting::Receive {
41664189
payment_data, payment_metadata, incoming_cltv_expiry, phantom_shared_secret,
4167-
custom_tlvs, ..
4190+
custom_tlvs, blinded
41684191
} => {
41694192
let _legacy_hop_data = Some(payment_data.clone());
41704193
let onion_fields = RecipientOnionFields { payment_secret: Some(payment_data.payment_secret),
41714194
payment_metadata, custom_tlvs };
41724195
(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)
41744197
},
41754198
PendingHTLCRouting::ReceiveKeysend {
41764199
payment_data, payment_preimage, payment_metadata, incoming_cltv_expiry,
4177-
custom_tlvs, ..
4200+
custom_tlvs, blinded
41784201
} => {
41794202
let onion_fields = RecipientOnionFields {
41804203
payment_secret: payment_data.as_ref().map(|data| data.payment_secret),
41814204
payment_metadata,
41824205
custom_tlvs,
41834206
};
41844207
(incoming_cltv_expiry, OnionPayload::Spontaneous(payment_preimage),
4185-
payment_data, None, onion_fields)
4208+
payment_data, None, onion_fields, blinded)
41864209
},
41874210
_ => {
41884211
panic!("short_channel_id == 0 should imply any pending_forward entries are of type Receive");
@@ -4196,6 +4219,7 @@ where
41964219
htlc_id: prev_htlc_id,
41974220
incoming_packet_shared_secret: incoming_shared_secret,
41984221
phantom_shared_secret,
4222+
blinded: blinded.map(|()| false),
41994223
},
42004224
// We differentiate the received value from the sender intended value
42014225
// if possible so that we don't prematurely mark MPP payments complete
@@ -4226,6 +4250,7 @@ where
42264250
htlc_id: $htlc.prev_hop.htlc_id,
42274251
incoming_packet_shared_secret: $htlc.prev_hop.incoming_packet_shared_secret,
42284252
phantom_shared_secret,
4253+
blinded: blinded.map(|()| false),
42294254
}), payment_hash,
42304255
HTLCFailReason::reason(0x4000 | 15, htlc_msat_height_data),
42314256
HTLCDestination::FailedPayment { payment_hash: $payment_hash },
@@ -6204,6 +6229,7 @@ where
62046229
htlc_id: prev_htlc_id,
62056230
incoming_packet_shared_secret: forward_info.incoming_shared_secret,
62066231
phantom_shared_secret: None,
6232+
blinded: forward_info.routing.blinded(),
62076233
});
62086234

62096235
failed_intercept_forwards.push((htlc_source, forward_info.payment_hash,
@@ -7331,6 +7357,7 @@ where
73317357
incoming_packet_shared_secret: htlc.forward_info.incoming_shared_secret,
73327358
phantom_shared_secret: None,
73337359
outpoint: htlc.prev_funding_outpoint,
7360+
blinded: htlc.forward_info.routing.blinded(),
73347361
});
73357362

73367363
let requested_forward_scid /* intercept scid */ = match htlc.forward_info.routing {
@@ -8152,6 +8179,7 @@ impl_writeable_tlv_based!(HTLCPreviousHopData, {
81528179
(4, htlc_id, required),
81538180
(6, incoming_packet_shared_secret, required),
81548181
(7, user_channel_id, option),
8182+
(8, blinded, option),
81558183
});
81568184

81578185
impl Writeable for ClaimableHTLC {

0 commit comments

Comments
 (0)