Skip to content

Commit d6c055d

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 cc516ad commit d6c055d

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
@@ -3091,6 +3091,61 @@ where
30913091
}
30923092
}
30933093

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

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

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

0 commit comments

Comments
 (0)