Skip to content

Commit 492fa70

Browse files
authored
Merge pull request #3956 from joostjager/demacro-process-forward-htlcs
Demacro process forward htlcs
2 parents f246159 + 8ccab2b commit 492fa70

File tree

1 file changed

+223
-116
lines changed

1 file changed

+223
-116
lines changed

lightning/src/ln/channelmanager.rs

Lines changed: 223 additions & 116 deletions
Original file line numberDiff line numberDiff line change
@@ -6393,137 +6393,226 @@ where
63936393
should_persist
63946394
}
63956395

6396-
fn process_forward_htlcs(
6397-
&self, short_chan_id: u64, pending_forwards: &mut Vec<HTLCForwardInfo>,
6398-
failed_forwards: &mut Vec<FailedHTLCForward>,
6396+
/// Fail the list of provided HTLC forwards because the channel they were to be forwarded over does no longer exist.
6397+
fn forwarding_channel_not_found(
6398+
&self, forward_infos: impl Iterator<Item = HTLCForwardInfo>, short_chan_id: u64,
6399+
forwarding_counterparty: Option<PublicKey>, failed_forwards: &mut Vec<FailedHTLCForward>,
63996400
phantom_receives: &mut Vec<PerSourcePendingForward>,
64006401
) {
6401-
let mut forwarding_counterparty = None;
6402-
macro_rules! forwarding_channel_not_found {
6403-
($forward_infos: expr) => {
6404-
for forward_info in $forward_infos {
6405-
match forward_info {
6406-
HTLCForwardInfo::AddHTLC(PendingAddHTLCInfo {
6407-
prev_short_channel_id, prev_htlc_id, prev_channel_id, prev_funding_outpoint,
6408-
prev_user_channel_id, prev_counterparty_node_id, forward_info: PendingHTLCInfo {
6409-
routing, incoming_shared_secret, payment_hash, outgoing_amt_msat,
6410-
outgoing_cltv_value, ..
6411-
}
6412-
}) => {
6413-
let cltv_expiry = routing.incoming_cltv_expiry();
6414-
macro_rules! failure_handler {
6415-
($msg: expr, $reason: expr, $err_data: expr, $phantom_ss: expr, $next_hop_unknown: expr) => {
6416-
let logger = WithContext::from(&self.logger, forwarding_counterparty, Some(prev_channel_id), Some(payment_hash));
6417-
log_info!(logger, "Failed to accept/forward incoming HTLC: {}", $msg);
6418-
6419-
let htlc_source = HTLCSource::PreviousHopData(HTLCPreviousHopData {
6420-
short_channel_id: prev_short_channel_id,
6421-
user_channel_id: Some(prev_user_channel_id),
6422-
channel_id: prev_channel_id,
6423-
outpoint: prev_funding_outpoint,
6424-
counterparty_node_id: prev_counterparty_node_id,
6425-
htlc_id: prev_htlc_id,
6426-
incoming_packet_shared_secret: incoming_shared_secret,
6427-
phantom_shared_secret: $phantom_ss,
6428-
blinded_failure: routing.blinded_failure(),
6429-
cltv_expiry,
6430-
});
6402+
for forward_info in forward_infos {
6403+
match forward_info {
6404+
HTLCForwardInfo::AddHTLC(PendingAddHTLCInfo {
6405+
prev_short_channel_id,
6406+
prev_htlc_id,
6407+
prev_channel_id,
6408+
prev_funding_outpoint,
6409+
prev_user_channel_id,
6410+
prev_counterparty_node_id,
6411+
forward_info:
6412+
PendingHTLCInfo {
6413+
routing,
6414+
incoming_shared_secret,
6415+
payment_hash,
6416+
outgoing_amt_msat,
6417+
outgoing_cltv_value,
6418+
..
6419+
},
6420+
}) => {
6421+
let cltv_expiry = routing.incoming_cltv_expiry();
6422+
let logger = WithContext::from(
6423+
&self.logger,
6424+
forwarding_counterparty,
6425+
Some(prev_channel_id),
6426+
Some(payment_hash),
6427+
);
6428+
let mut failure_handler =
6429+
|msg, reason, err_data, phantom_ss, next_hop_unknown| {
6430+
log_info!(logger, "Failed to accept/forward incoming HTLC: {}", msg);
6431+
6432+
let htlc_source = HTLCSource::PreviousHopData(HTLCPreviousHopData {
6433+
short_channel_id: prev_short_channel_id,
6434+
user_channel_id: Some(prev_user_channel_id),
6435+
channel_id: prev_channel_id,
6436+
outpoint: prev_funding_outpoint,
6437+
counterparty_node_id: prev_counterparty_node_id,
6438+
htlc_id: prev_htlc_id,
6439+
incoming_packet_shared_secret: incoming_shared_secret,
6440+
phantom_shared_secret: phantom_ss,
6441+
blinded_failure: routing.blinded_failure(),
6442+
cltv_expiry,
6443+
});
64316444

6432-
let reason = if $next_hop_unknown {
6433-
HTLCHandlingFailureType::InvalidForward { requested_forward_scid: short_chan_id }
6434-
} else {
6435-
HTLCHandlingFailureType::Receive{ payment_hash }
6436-
};
6445+
let failure_type = if next_hop_unknown {
6446+
HTLCHandlingFailureType::InvalidForward {
6447+
requested_forward_scid: short_chan_id,
6448+
}
6449+
} else {
6450+
HTLCHandlingFailureType::Receive { payment_hash }
6451+
};
64376452

6438-
failed_forwards.push((htlc_source, payment_hash,
6439-
HTLCFailReason::reason($reason, $err_data),
6440-
reason
6441-
));
6453+
failed_forwards.push((
6454+
htlc_source,
6455+
payment_hash,
6456+
HTLCFailReason::reason(reason, err_data),
6457+
failure_type,
6458+
));
6459+
};
6460+
6461+
if let PendingHTLCRouting::Forward { ref onion_packet, .. } = routing {
6462+
let phantom_pubkey_res =
6463+
self.node_signer.get_node_id(Recipient::PhantomNode);
6464+
if phantom_pubkey_res.is_ok()
6465+
&& fake_scid::is_valid_phantom(
6466+
&self.fake_scid_rand_bytes,
6467+
short_chan_id,
6468+
&self.chain_hash,
6469+
) {
6470+
let decode_res = onion_utils::decode_next_payment_hop(
6471+
Recipient::PhantomNode,
6472+
&onion_packet.public_key.unwrap(),
6473+
&onion_packet.hop_data,
6474+
onion_packet.hmac,
6475+
payment_hash,
6476+
None,
6477+
&*self.node_signer,
6478+
);
6479+
let next_hop = match decode_res {
6480+
Ok(res) => res,
6481+
Err(onion_utils::OnionDecodeErr::Malformed { err_msg, reason }) => {
6482+
let sha256_of_onion =
6483+
Sha256::hash(&onion_packet.hop_data).to_byte_array();
6484+
// In this scenario, the phantom would have sent us an
6485+
// `update_fail_malformed_htlc`, meaning here we encrypt the error as
6486+
// if it came from us (the second-to-last hop) but contains the sha256
6487+
// of the onion.
6488+
failure_handler(
6489+
err_msg,
6490+
reason,
6491+
sha256_of_onion.to_vec(),
6492+
None,
6493+
false,
6494+
);
64426495
continue;
6443-
}
6444-
}
6445-
macro_rules! fail_forward {
6446-
($msg: expr, $reason: expr, $err_data: expr, $phantom_ss: expr) => {
6447-
{
6448-
failure_handler!($msg, $reason, $err_data, $phantom_ss, true);
6449-
}
6450-
}
6451-
}
6452-
macro_rules! failed_payment {
6453-
($msg: expr, $reason: expr, $err_data: expr, $phantom_ss: expr) => {
6454-
{
6455-
failure_handler!($msg, $reason, $err_data, $phantom_ss, false);
6456-
}
6457-
}
6458-
}
6459-
if let PendingHTLCRouting::Forward { ref onion_packet, .. } = routing {
6460-
let phantom_pubkey_res = self.node_signer.get_node_id(Recipient::PhantomNode);
6461-
if phantom_pubkey_res.is_ok() && fake_scid::is_valid_phantom(&self.fake_scid_rand_bytes, short_chan_id, &self.chain_hash) {
6462-
let decode_res = onion_utils::decode_next_payment_hop(
6463-
Recipient::PhantomNode, &onion_packet.public_key.unwrap(), &onion_packet.hop_data,
6464-
onion_packet.hmac, payment_hash, None, &*self.node_signer
6496+
},
6497+
Err(onion_utils::OnionDecodeErr::Relay {
6498+
err_msg,
6499+
reason,
6500+
shared_secret,
6501+
..
6502+
}) => {
6503+
let phantom_shared_secret = shared_secret.secret_bytes();
6504+
failure_handler(
6505+
err_msg,
6506+
reason,
6507+
Vec::new(),
6508+
Some(phantom_shared_secret),
6509+
false,
64656510
);
6466-
let next_hop = match decode_res {
6467-
Ok(res) => res,
6468-
Err(onion_utils::OnionDecodeErr::Malformed { err_msg, reason }) => {
6469-
let sha256_of_onion = Sha256::hash(&onion_packet.hop_data).to_byte_array();
6470-
// In this scenario, the phantom would have sent us an
6471-
// `update_fail_malformed_htlc`, meaning here we encrypt the error as
6472-
// if it came from us (the second-to-last hop) but contains the sha256
6473-
// of the onion.
6474-
failed_payment!(err_msg, reason, sha256_of_onion.to_vec(), None);
6475-
},
6476-
Err(onion_utils::OnionDecodeErr::Relay { err_msg, reason, shared_secret, .. }) => {
6477-
let phantom_shared_secret = shared_secret.secret_bytes();
6478-
failed_payment!(err_msg, reason, Vec::new(), Some(phantom_shared_secret));
6479-
},
6480-
};
6481-
let phantom_shared_secret = next_hop.shared_secret().secret_bytes();
6482-
let current_height: u32 = self.best_block.read().unwrap().height;
6483-
let create_res = create_recv_pending_htlc_info(next_hop,
6484-
incoming_shared_secret, payment_hash, outgoing_amt_msat,
6485-
outgoing_cltv_value, Some(phantom_shared_secret), false, None,
6486-
current_height);
6487-
match create_res
6488-
{
6489-
Ok(info) => phantom_receives.push((
6490-
prev_short_channel_id, prev_counterparty_node_id, prev_funding_outpoint,
6491-
prev_channel_id, prev_user_channel_id, vec![(info, prev_htlc_id)]
6492-
)),
6493-
Err(InboundHTLCErr { reason, err_data, msg }) => failed_payment!(msg, reason, err_data, Some(phantom_shared_secret))
6494-
}
6495-
} else {
6496-
fail_forward!(format!("Unknown short channel id {} for forward HTLC", short_chan_id),
6497-
LocalHTLCFailureReason::UnknownNextPeer, Vec::new(), None);
6498-
}
6499-
} else {
6500-
fail_forward!(format!("Unknown short channel id {} for forward HTLC", short_chan_id),
6501-
LocalHTLCFailureReason::UnknownNextPeer, Vec::new(), None);
6511+
continue;
6512+
},
6513+
};
6514+
let phantom_shared_secret = next_hop.shared_secret().secret_bytes();
6515+
let current_height: u32 = self.best_block.read().unwrap().height;
6516+
let create_res = create_recv_pending_htlc_info(
6517+
next_hop,
6518+
incoming_shared_secret,
6519+
payment_hash,
6520+
outgoing_amt_msat,
6521+
outgoing_cltv_value,
6522+
Some(phantom_shared_secret),
6523+
false,
6524+
None,
6525+
current_height,
6526+
);
6527+
match create_res {
6528+
Ok(info) => phantom_receives.push((
6529+
prev_short_channel_id,
6530+
prev_counterparty_node_id,
6531+
prev_funding_outpoint,
6532+
prev_channel_id,
6533+
prev_user_channel_id,
6534+
vec![(info, prev_htlc_id)],
6535+
)),
6536+
Err(InboundHTLCErr { reason, err_data, msg }) => {
6537+
failure_handler(
6538+
msg,
6539+
reason,
6540+
err_data,
6541+
Some(phantom_shared_secret),
6542+
false,
6543+
);
6544+
continue;
6545+
},
65026546
}
6503-
},
6504-
HTLCForwardInfo::FailHTLC { .. } | HTLCForwardInfo::FailMalformedHTLC { .. } => {
6505-
// Channel went away before we could fail it. This implies
6506-
// the channel is now on chain and our counterparty is
6507-
// trying to broadcast the HTLC-Timeout, but that's their
6508-
// problem, not ours.
6547+
} else {
6548+
let msg = format!(
6549+
"Unknown short channel id {} for forward HTLC",
6550+
short_chan_id
6551+
);
6552+
failure_handler(
6553+
&msg,
6554+
LocalHTLCFailureReason::UnknownNextPeer,
6555+
Vec::new(),
6556+
None,
6557+
true,
6558+
);
6559+
continue;
65096560
}
6561+
} else {
6562+
let msg =
6563+
format!("Unknown short channel id {} for forward HTLC", short_chan_id);
6564+
failure_handler(
6565+
&msg,
6566+
LocalHTLCFailureReason::UnknownNextPeer,
6567+
Vec::new(),
6568+
None,
6569+
true,
6570+
);
6571+
continue;
65106572
}
6511-
}
6573+
},
6574+
HTLCForwardInfo::FailHTLC { .. } | HTLCForwardInfo::FailMalformedHTLC { .. } => {
6575+
// Channel went away before we could fail it. This implies
6576+
// the channel is now on chain and our counterparty is
6577+
// trying to broadcast the HTLC-Timeout, but that's their
6578+
// problem, not ours.
6579+
},
65126580
}
65136581
}
6582+
}
6583+
6584+
fn process_forward_htlcs(
6585+
&self, short_chan_id: u64, pending_forwards: &mut Vec<HTLCForwardInfo>,
6586+
failed_forwards: &mut Vec<FailedHTLCForward>,
6587+
phantom_receives: &mut Vec<PerSourcePendingForward>,
6588+
) {
6589+
let mut forwarding_counterparty = None;
6590+
65146591
let chan_info_opt = self.short_to_chan_info.read().unwrap().get(&short_chan_id).cloned();
65156592
let (counterparty_node_id, forward_chan_id) = match chan_info_opt {
65166593
Some((cp_id, chan_id)) => (cp_id, chan_id),
65176594
None => {
6518-
forwarding_channel_not_found!(pending_forwards.drain(..));
6595+
self.forwarding_channel_not_found(
6596+
pending_forwards.drain(..),
6597+
short_chan_id,
6598+
forwarding_counterparty,
6599+
failed_forwards,
6600+
phantom_receives,
6601+
);
65196602
return;
65206603
},
65216604
};
65226605
forwarding_counterparty = Some(counterparty_node_id);
65236606
let per_peer_state = self.per_peer_state.read().unwrap();
65246607
let peer_state_mutex_opt = per_peer_state.get(&counterparty_node_id);
65256608
if peer_state_mutex_opt.is_none() {
6526-
forwarding_channel_not_found!(pending_forwards.drain(..));
6609+
self.forwarding_channel_not_found(
6610+
pending_forwards.drain(..),
6611+
short_chan_id,
6612+
forwarding_counterparty,
6613+
failed_forwards,
6614+
phantom_receives,
6615+
);
65276616
return;
65286617
}
65296618
let mut peer_state_lock = peer_state_mutex_opt.unwrap().lock().unwrap();
@@ -6618,7 +6707,13 @@ where
66186707
} else {
66196708
let fwd_iter =
66206709
core::iter::once(forward_info).chain(draining_pending_forwards);
6621-
forwarding_channel_not_found!(fwd_iter);
6710+
self.forwarding_channel_not_found(
6711+
fwd_iter,
6712+
short_chan_id,
6713+
forwarding_counterparty,
6714+
failed_forwards,
6715+
phantom_receives,
6716+
);
66226717
break;
66236718
}
66246719
},
@@ -6673,8 +6768,12 @@ where
66736768
failure_type,
66746769
));
66756770
} else {
6676-
forwarding_channel_not_found!(
6677-
core::iter::once(forward_info).chain(draining_pending_forwards)
6771+
self.forwarding_channel_not_found(
6772+
core::iter::once(forward_info).chain(draining_pending_forwards),
6773+
short_chan_id,
6774+
forwarding_counterparty,
6775+
failed_forwards,
6776+
phantom_receives,
66786777
);
66796778
break;
66806779
}
@@ -6694,8 +6793,12 @@ where
66946793
log_trace!(logger, "Failing HTLC back to channel with short id {} (backward HTLC ID {}) after delay", short_chan_id, htlc_id);
66956794
Some((chan.queue_fail_htlc(htlc_id, err_packet.clone(), &&logger), htlc_id))
66966795
} else {
6697-
forwarding_channel_not_found!(
6698-
core::iter::once(forward_info).chain(draining_pending_forwards)
6796+
self.forwarding_channel_not_found(
6797+
core::iter::once(forward_info).chain(draining_pending_forwards),
6798+
short_chan_id,
6799+
forwarding_counterparty,
6800+
failed_forwards,
6801+
phantom_receives,
66996802
);
67006803
break;
67016804
}
@@ -6716,8 +6819,12 @@ where
67166819
);
67176820
Some((res, htlc_id))
67186821
} else {
6719-
forwarding_channel_not_found!(
6720-
core::iter::once(forward_info).chain(draining_pending_forwards)
6822+
self.forwarding_channel_not_found(
6823+
core::iter::once(forward_info).chain(draining_pending_forwards),
6824+
short_chan_id,
6825+
forwarding_counterparty,
6826+
failed_forwards,
6827+
phantom_receives,
67216828
);
67226829
break;
67236830
}

0 commit comments

Comments
 (0)