Skip to content

Commit d187721

Browse files
Correctly fail back non-intro-node blinded HTLCs on initial forward
We were already doing this correctly in several places, this fixes up the remaining.
1 parent 9cab1fc commit d187721

File tree

1 file changed

+57
-13
lines changed

1 file changed

+57
-13
lines changed

lightning/src/ln/channelmanager.rs

Lines changed: 57 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2941,11 +2941,14 @@ where
29412941
macro_rules! return_malformed_err {
29422942
($msg: expr, $err_code: expr) => {
29432943
{
2944+
let sha256_of_onion = if msg.blinding_point.is_some() { [0; 32] } else {
2945+
Sha256::hash(&msg.onion_routing_packet.hop_data).into_inner()
2946+
};
29442947
log_info!(self.logger, "Failed to accept/forward incoming HTLC: {}", $msg);
29452948
return Err(HTLCFailureMsg::Malformed(msgs::UpdateFailMalformedHTLC {
29462949
channel_id: msg.channel_id,
29472950
htlc_id: msg.htlc_id,
2948-
sha256_of_onion: Sha256::hash(&msg.onion_routing_packet.hop_data).into_inner(),
2951+
sha256_of_onion,
29492952
failure_code: $err_code,
29502953
}));
29512954
}
@@ -3005,21 +3008,31 @@ where
30053008
{
30063009
Ok(res) => res,
30073010
Err(onion_utils::OnionDecodeErr::Malformed { err_msg, err_code }) => {
3008-
return_malformed_err!(err_msg, err_code);
3011+
if msg.blinding_point.is_some() {
3012+
return_blinded_htlc_err!(err_msg);
3013+
} else {
3014+
return_malformed_err!(err_msg, err_code);
3015+
}
30093016
},
30103017
Err(onion_utils::OnionDecodeErr::Relay { err_msg, err_code }) => {
3011-
return_err!(err_msg, err_code, &[0; 0]);
3018+
if msg.blinding_point.is_some() {
3019+
return_blinded_htlc_err!(err_msg);
3020+
} else {
3021+
return_err!(err_msg, err_code, &[0; 0]);
3022+
}
30123023
},
30133024
};
3014-
let (outgoing_scid, outgoing_amt_msat, outgoing_cltv_value, next_packet_pk_opt) = match next_hop {
3025+
let (outgoing_scid, outgoing_amt_msat, outgoing_cltv_value, next_packet_pk_opt, blinded)
3026+
= match next_hop
3027+
{
30153028
onion_utils::Hop::Forward {
30163029
next_hop_data: msgs::InboundOnionPayload::Forward {
30173030
short_channel_id, amt_to_forward, outgoing_cltv_value
30183031
}, ..
30193032
} => {
30203033
let next_packet_pk = onion_utils::next_hop_pubkey(&self.secp_ctx,
30213034
msg.onion_routing_packet.public_key.unwrap(), &shared_secret);
3022-
(short_channel_id, amt_to_forward, outgoing_cltv_value, Some(next_packet_pk))
3035+
(short_channel_id, amt_to_forward, outgoing_cltv_value, Some(next_packet_pk), false)
30233036
},
30243037
onion_utils::Hop::Forward {
30253038
next_hop_data: msgs::InboundOnionPayload::BlindedForward {
@@ -3052,15 +3065,17 @@ where
30523065
}
30533066
let next_packet_pk = onion_utils::next_hop_pubkey(&self.secp_ctx,
30543067
msg.onion_routing_packet.public_key.unwrap(), &shared_secret);
3055-
(short_channel_id, amt_to_forward, outgoing_cltv_value, Some(next_packet_pk))
3068+
(short_channel_id, amt_to_forward, outgoing_cltv_value, Some(next_packet_pk), true)
30563069
},
30573070
// We'll do receive checks in [`Self::construct_pending_htlc_info`] so we have access to the
30583071
// inbound channel's state.
30593072
onion_utils::Hop::Receive { .. } => return Ok((next_hop, shared_secret, None)),
30603073
onion_utils::Hop::Forward { next_hop_data: msgs::InboundOnionPayload::Receive { .. }, .. } => {
30613074
return_err!("Final Node OnionHopData provided for us as an intermediary node", 0x4000 | 22, &[0; 0]);
30623075
},
3063-
_ => todo!()
3076+
onion_utils::Hop::Forward { next_hop_data: msgs::InboundOnionPayload::BlindedReceive { .. }, .. } => {
3077+
return_blinded_htlc_err!("Blinded final node onion provided for us as an intermediary node");
3078+
},
30643079
};
30653080

30663081
// Perform outbound checks here instead of in [`Self::construct_pending_htlc_info`] because we
@@ -3172,6 +3187,7 @@ where
31723187
break None;
31733188
}
31743189
{
3190+
if blinded { return_blinded_htlc_err!(err); }
31753191
let mut res = VecWriter(Vec::with_capacity(chan_update.serialized_length() + 2 + 8 + 2));
31763192
if let Some(chan_update) = chan_update {
31773193
if code == 0x1000 | 11 || code == 0x1000 | 12 {
@@ -3204,13 +3220,23 @@ where
32043220
allow_underpay: bool, next_packet_pubkey_opt: Option<Result<PublicKey, secp256k1::Error>>
32053221
) -> PendingHTLCStatus {
32063222
macro_rules! return_err {
3207-
($msg: expr, $err_code: expr, $data: expr) => {
3223+
($msg: expr, $err_code: expr, $data: expr, $intro_node: expr) => {
32083224
{
32093225
log_info!(self.logger, "Failed to accept/forward incoming HTLC: {}", $msg);
3226+
let (err_code, err_data) = if msg.blinding_point.is_some() {
3227+
return PendingHTLCStatus::Fail(HTLCFailureMsg::Malformed(msgs::UpdateFailMalformedHTLC {
3228+
channel_id: msg.channel_id,
3229+
htlc_id: msg.htlc_id,
3230+
sha256_of_onion: [0; 32],
3231+
failure_code: INVALID_ONION_BLINDING,
3232+
}))
3233+
} else if $intro_node {
3234+
(INVALID_ONION_BLINDING, vec![0; 32])
3235+
} else { ($err_code, $data) };
32103236
return PendingHTLCStatus::Fail(HTLCFailureMsg::Relay(msgs::UpdateFailHTLC {
32113237
channel_id: msg.channel_id,
32123238
htlc_id: msg.htlc_id,
3213-
reason: HTLCFailReason::reason($err_code, $data.to_vec())
3239+
reason: HTLCFailReason::reason(err_code, err_data.to_vec())
32143240
.get_encrypted_failure_packet(&shared_secret, &None),
32153241
}));
32163242
}
@@ -3229,14 +3255,19 @@ where
32293255
// delay) once they've send us a commitment_signed!
32303256
PendingHTLCStatus::Forward(info)
32313257
},
3232-
Err(InboundOnionErr { err_code, err_data, msg }) => return_err!(msg, err_code, &err_data)
3258+
Err(InboundOnionErr { err_code, err_data, msg }) =>
3259+
return_err!(msg, err_code, err_data, false)
32333260
}
32343261
},
32353262
onion_utils::Hop::Forward { next_hop_data, next_hop_hmac, new_packet_bytes } => {
3263+
let is_intro_node = if let msgs::InboundOnionPayload::BlindedForward {
3264+
intro_node_blinding_point: Some(_), ..
3265+
} = next_hop_data { true } else { false };
32363266
match self.construct_fwd_pending_htlc_info(msg, next_hop_data, next_hop_hmac,
32373267
new_packet_bytes, shared_secret, next_packet_pubkey_opt) {
32383268
Ok(info) => PendingHTLCStatus::Forward(info),
3239-
Err(InboundOnionErr { err_code, err_data, msg }) => return_err!(msg, err_code, &err_data)
3269+
Err(InboundOnionErr { err_code, err_data, msg }) =>
3270+
return_err!(msg, err_code, err_data, is_intro_node)
32403271
}
32413272
}
32423273
}
@@ -6107,8 +6138,21 @@ where
61076138
// but if we've sent a shutdown and they haven't acknowledged it yet, we just
61086139
// want to reject the new HTLC and fail it backwards instead of forwarding.
61096140
match pending_forward_info {
6110-
PendingHTLCStatus::Forward(PendingHTLCInfo { ref incoming_shared_secret, .. }) => {
6111-
let reason = if (error_code & 0x1000) != 0 {
6141+
PendingHTLCStatus::Forward(PendingHTLCInfo {
6142+
ref incoming_shared_secret, ref routing, ..
6143+
}) => {
6144+
if msg.blinding_point.is_some() {
6145+
let fail_malformed = msgs::UpdateFailMalformedHTLC {
6146+
channel_id: msg.channel_id,
6147+
htlc_id: msg.htlc_id,
6148+
sha256_of_onion: [0; 32],
6149+
failure_code: INVALID_ONION_BLINDING,
6150+
};
6151+
return PendingHTLCStatus::Fail(HTLCFailureMsg::Malformed(fail_malformed))
6152+
}
6153+
let reason = if routing.blinded().is_some() {
6154+
HTLCFailReason::reason(INVALID_ONION_BLINDING, vec![0; 32])
6155+
} else if (error_code & 0x1000) != 0 {
61126156
let (real_code, error_data) = self.get_htlc_inbound_temp_fail_err_and_data(error_code, chan);
61136157
HTLCFailReason::reason(real_code, error_data)
61146158
} else {

0 commit comments

Comments
 (0)