Skip to content

Commit 0073e49

Browse files
committed
Refactor HTLCFailureMsg generation out from decode_update_add_htlc_onion
In the future, we plan to complete remove `decode_update_add_htlc_onion` and replace it with a batched variant. This refactor, while improving readability in its current form, does not feature any functional changes and allows us to reuse most of the logic in the batched variant.
1 parent 3f940d3 commit 0073e49

File tree

1 file changed

+59
-54
lines changed

1 file changed

+59
-54
lines changed

lightning/src/ln/channelmanager.rs

Lines changed: 59 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -3094,6 +3094,61 @@ where
30943094
}
30953095
}
30963096

3097+
fn htlc_failure_from_update_add_err(
3098+
&self, msg: &msgs::UpdateAddHTLC, counterparty_node_id: &PublicKey, err_msg: &'static str,
3099+
mut err_code: u16, chan_update: Option<msgs::ChannelUpdate>, is_intro_node_blinded_forward: bool,
3100+
shared_secret: &[u8; 32]
3101+
) -> HTLCFailureMsg {
3102+
let mut res = VecWriter(Vec::with_capacity(chan_update.serialized_length() + 2 + 8 + 2));
3103+
if let Some(chan_update) = chan_update {
3104+
if err_code == 0x1000 | 11 || err_code == 0x1000 | 12 {
3105+
msg.amount_msat.write(&mut res).expect("Writes cannot fail");
3106+
}
3107+
else if err_code == 0x1000 | 13 {
3108+
msg.cltv_expiry.write(&mut res).expect("Writes cannot fail");
3109+
}
3110+
else if err_code == 0x1000 | 20 {
3111+
// TODO: underspecified, follow https://github.com/lightning/bolts/issues/791
3112+
0u16.write(&mut res).expect("Writes cannot fail");
3113+
}
3114+
(chan_update.serialized_length() as u16 + 2).write(&mut res).expect("Writes cannot fail");
3115+
msgs::ChannelUpdate::TYPE.write(&mut res).expect("Writes cannot fail");
3116+
chan_update.write(&mut res).expect("Writes cannot fail");
3117+
} else if err_code & 0x1000 == 0x1000 {
3118+
// If we're trying to return an error that requires a `channel_update` but
3119+
// we're forwarding to a phantom or intercept "channel" (i.e. cannot
3120+
// generate an update), just use the generic "temporary_node_failure"
3121+
// instead.
3122+
err_code = 0x2000 | 2;
3123+
}
3124+
3125+
log_info!(
3126+
WithContext::from(&self.logger, Some(*counterparty_node_id), Some(msg.channel_id)),
3127+
"Failed to accept/forward incoming HTLC: {}", err_msg
3128+
);
3129+
// If `msg.blinding_point` is set, we must always fail with malformed.
3130+
if msg.blinding_point.is_some() {
3131+
return HTLCFailureMsg::Malformed(msgs::UpdateFailMalformedHTLC {
3132+
channel_id: msg.channel_id,
3133+
htlc_id: msg.htlc_id,
3134+
sha256_of_onion: [0; 32],
3135+
failure_code: INVALID_ONION_BLINDING,
3136+
});
3137+
}
3138+
3139+
let (err_code, err_data) = if is_intro_node_blinded_forward {
3140+
(INVALID_ONION_BLINDING, &[0; 32][..])
3141+
} else {
3142+
(err_code, &res.0[..])
3143+
};
3144+
HTLCFailureMsg::Relay(msgs::UpdateFailHTLC {
3145+
channel_id: msg.channel_id,
3146+
htlc_id: msg.htlc_id,
3147+
reason: HTLCFailReason::reason(err_code, err_data.to_vec())
3148+
.get_encrypted_failure_packet(shared_secret, &None),
3149+
})
3150+
}
3151+
30973152
fn decode_update_add_htlc_onion(
30983153
&self, msg: &msgs::UpdateAddHTLC, counterparty_node_id: &PublicKey,
30993154
) -> Result<
@@ -3103,36 +3158,6 @@ where
31033158
msg, &self.node_signer, &self.logger, &self.secp_ctx
31043159
)?;
31053160

3106-
macro_rules! return_err {
3107-
($msg: expr, $err_code: expr, $data: expr) => {
3108-
{
3109-
log_info!(
3110-
WithContext::from(&self.logger, Some(*counterparty_node_id), Some(msg.channel_id)),
3111-
"Failed to accept/forward incoming HTLC: {}", $msg
3112-
);
3113-
// If `msg.blinding_point` is set, we must always fail with malformed.
3114-
if msg.blinding_point.is_some() {
3115-
return Err(HTLCFailureMsg::Malformed(msgs::UpdateFailMalformedHTLC {
3116-
channel_id: msg.channel_id,
3117-
htlc_id: msg.htlc_id,
3118-
sha256_of_onion: [0; 32],
3119-
failure_code: INVALID_ONION_BLINDING,
3120-
}));
3121-
}
3122-
3123-
let (err_code, err_data) = if next_hop.is_intro_node_blinded_forward() {
3124-
(INVALID_ONION_BLINDING, &[0; 32][..])
3125-
} else { ($err_code, $data) };
3126-
return Err(HTLCFailureMsg::Relay(msgs::UpdateFailHTLC {
3127-
channel_id: msg.channel_id,
3128-
htlc_id: msg.htlc_id,
3129-
reason: HTLCFailReason::reason(err_code, err_data.to_vec())
3130-
.get_encrypted_failure_packet(&shared_secret, &None),
3131-
}));
3132-
}
3133-
}
3134-
}
3135-
31363161
let NextPacketDetails {
31373162
next_packet_pubkey, outgoing_amt_msat, outgoing_scid, outgoing_cltv_value
31383163
} = match next_packet_details_opt {
@@ -3143,7 +3168,7 @@ where
31433168

31443169
// Perform outbound checks here instead of in [`Self::construct_pending_htlc_info`] because we
31453170
// can't hold the outbound peer state lock at the same time as the inbound peer state lock.
3146-
if let Some((err, mut code, chan_update)) = loop {
3171+
if let Some((err, code, chan_update)) = loop {
31473172
let id_option = self.short_to_chan_info.read().unwrap().get(&outgoing_scid).cloned();
31483173
let forwarding_chan_info_opt = match id_option {
31493174
None => { // unknown_next_peer
@@ -3236,29 +3261,9 @@ where
32363261
break None;
32373262
}
32383263
{
3239-
let mut res = VecWriter(Vec::with_capacity(chan_update.serialized_length() + 2 + 8 + 2));
3240-
if let Some(chan_update) = chan_update {
3241-
if code == 0x1000 | 11 || code == 0x1000 | 12 {
3242-
msg.amount_msat.write(&mut res).expect("Writes cannot fail");
3243-
}
3244-
else if code == 0x1000 | 13 {
3245-
msg.cltv_expiry.write(&mut res).expect("Writes cannot fail");
3246-
}
3247-
else if code == 0x1000 | 20 {
3248-
// TODO: underspecified, follow https://github.com/lightning/bolts/issues/791
3249-
0u16.write(&mut res).expect("Writes cannot fail");
3250-
}
3251-
(chan_update.serialized_length() as u16 + 2).write(&mut res).expect("Writes cannot fail");
3252-
msgs::ChannelUpdate::TYPE.write(&mut res).expect("Writes cannot fail");
3253-
chan_update.write(&mut res).expect("Writes cannot fail");
3254-
} else if code & 0x1000 == 0x1000 {
3255-
// If we're trying to return an error that requires a `channel_update` but
3256-
// we're forwarding to a phantom or intercept "channel" (i.e. cannot
3257-
// generate an update), just use the generic "temporary_node_failure"
3258-
// instead.
3259-
code = 0x2000 | 2;
3260-
}
3261-
return_err!(err, code, &res.0[..]);
3264+
return Err(self.htlc_failure_from_update_add_err(
3265+
msg, counterparty_node_id, err, code, chan_update, next_hop.is_intro_node_blinded_forward(), &shared_secret
3266+
));
32623267
}
32633268
Ok((next_hop, shared_secret, Some(next_packet_pubkey)))
32643269
}

0 commit comments

Comments
 (0)