Skip to content

Commit c9fb114

Browse files
authored
Merge pull request #3744 from carlaKC/3541-followups
Use LocalHTLCFailureReason in Onion Processing
2 parents 29a6383 + 935ffde commit c9fb114

File tree

7 files changed

+151
-185
lines changed

7 files changed

+151
-185
lines changed

lightning/src/ln/channel.rs

+9-13
Original file line numberDiff line numberDiff line change
@@ -7879,17 +7879,15 @@ impl<SP: Deref> FundedChannel<SP> where
78797879

78807880
fn internal_htlc_satisfies_config(
78817881
&self, htlc: &msgs::UpdateAddHTLC, amt_to_forward: u64, outgoing_cltv_value: u32, config: &ChannelConfig,
7882-
) -> Result<(), (&'static str, LocalHTLCFailureReason)> {
7882+
) -> Result<(), LocalHTLCFailureReason> {
78837883
let fee = amt_to_forward.checked_mul(config.forwarding_fee_proportional_millionths as u64)
78847884
.and_then(|prop_fee| (prop_fee / 1000000).checked_add(config.forwarding_fee_base_msat as u64));
78857885
if fee.is_none() || htlc.amount_msat < fee.unwrap() ||
78867886
(htlc.amount_msat - fee.unwrap()) < amt_to_forward {
7887-
return Err(("Prior hop has deviated from specified fees parameters or origin node has obsolete ones",
7888-
LocalHTLCFailureReason::FeeInsufficient));
7887+
return Err(LocalHTLCFailureReason::FeeInsufficient);
78897888
}
78907889
if (htlc.cltv_expiry as u64) < outgoing_cltv_value as u64 + config.cltv_expiry_delta as u64 {
7891-
return Err(("Forwarding node has tampered with the intended HTLC values or origin node has an obsolete cltv_expiry_delta",
7892-
LocalHTLCFailureReason::IncorrectCLTVExpiry));
7890+
return Err(LocalHTLCFailureReason::IncorrectCLTVExpiry);
78937891
}
78947892
Ok(())
78957893
}
@@ -7899,7 +7897,7 @@ impl<SP: Deref> FundedChannel<SP> where
78997897
/// unsuccessful, falls back to the previous one if one exists.
79007898
pub fn htlc_satisfies_config(
79017899
&self, htlc: &msgs::UpdateAddHTLC, amt_to_forward: u64, outgoing_cltv_value: u32,
7902-
) -> Result<(), (&'static str, LocalHTLCFailureReason)> {
7900+
) -> Result<(), LocalHTLCFailureReason> {
79037901
self.internal_htlc_satisfies_config(&htlc, amt_to_forward, outgoing_cltv_value, &self.context.config())
79047902
.or_else(|err| {
79057903
if let Some(prev_config) = self.context.prev_config() {
@@ -7914,13 +7912,13 @@ impl<SP: Deref> FundedChannel<SP> where
79147912
/// this function determines whether to fail the HTLC, or forward / claim it.
79157913
pub fn can_accept_incoming_htlc<F: Deref, L: Deref>(
79167914
&self, msg: &msgs::UpdateAddHTLC, fee_estimator: &LowerBoundedFeeEstimator<F>, logger: L
7917-
) -> Result<(), (&'static str, LocalHTLCFailureReason)>
7915+
) -> Result<(), LocalHTLCFailureReason>
79187916
where
79197917
F::Target: FeeEstimator,
79207918
L::Target: Logger
79217919
{
79227920
if self.context.channel_state.is_local_shutdown_sent() {
7923-
return Err(("Shutdown was already sent", LocalHTLCFailureReason::ChannelClosed))
7921+
return Err(LocalHTLCFailureReason::ChannelClosed)
79247922
}
79257923

79267924
let dust_exposure_limiting_feerate = self.context.get_dust_exposure_limiting_feerate(&fee_estimator);
@@ -7931,8 +7929,7 @@ impl<SP: Deref> FundedChannel<SP> where
79317929
// Note that the total dust exposure includes both the dust HTLCs and the excess mining fees of the counterparty commitment transaction
79327930
log_info!(logger, "Cannot accept value that would put our total dust exposure at {} over the limit {} on counterparty commitment tx",
79337931
on_counterparty_tx_dust_htlc_exposure_msat, max_dust_htlc_exposure_msat);
7934-
return Err(("Exceeded our total dust exposure limit on counterparty commitment tx",
7935-
LocalHTLCFailureReason::DustLimitCounterparty))
7932+
return Err(LocalHTLCFailureReason::DustLimitCounterparty)
79367933
}
79377934
let htlc_success_dust_limit = if self.funding.get_channel_type().supports_anchors_zero_fee_htlc_tx() {
79387935
0
@@ -7946,8 +7943,7 @@ impl<SP: Deref> FundedChannel<SP> where
79467943
if on_holder_tx_dust_htlc_exposure_msat > max_dust_htlc_exposure_msat {
79477944
log_info!(logger, "Cannot accept value that would put our exposure to dust HTLCs at {} over the limit {} on holder commitment tx",
79487945
on_holder_tx_dust_htlc_exposure_msat, max_dust_htlc_exposure_msat);
7949-
return Err(("Exceeded our dust exposure limit on holder commitment tx",
7950-
LocalHTLCFailureReason::DustLimitHolder))
7946+
return Err(LocalHTLCFailureReason::DustLimitHolder)
79517947
}
79527948
}
79537949

@@ -7985,7 +7981,7 @@ impl<SP: Deref> FundedChannel<SP> where
79857981
}
79867982
if pending_remote_value_msat.saturating_sub(self.funding.holder_selected_channel_reserve_satoshis * 1000).saturating_sub(anchor_outputs_value_msat) < remote_fee_cost_incl_stuck_buffer_msat {
79877983
log_info!(logger, "Attempting to fail HTLC due to fee spike buffer violation in channel {}. Rebalancing is required.", &self.context.channel_id());
7988-
return Err(("Fee spike buffer violation", LocalHTLCFailureReason::FeeSpikeBuffer));
7984+
return Err(LocalHTLCFailureReason::FeeSpikeBuffer);
79897985
}
79907986
}
79917987

lightning/src/ln/channelmanager.rs

+16-24
Original file line numberDiff line numberDiff line change
@@ -4352,25 +4352,22 @@ where
43524352

43534353
fn can_forward_htlc_to_outgoing_channel(
43544354
&self, chan: &mut FundedChannel<SP>, msg: &msgs::UpdateAddHTLC, next_packet: &NextPacketDetails
4355-
) -> Result<(), (&'static str, LocalHTLCFailureReason)> {
4355+
) -> Result<(), LocalHTLCFailureReason> {
43564356
if !chan.context.should_announce() && !self.default_configuration.accept_forwards_to_priv_channels {
43574357
// Note that the behavior here should be identical to the above block - we
43584358
// should NOT reveal the existence or non-existence of a private channel if
43594359
// we don't allow forwards outbound over them.
4360-
return Err(("Refusing to forward to a private channel based on our config.",
4361-
LocalHTLCFailureReason::PrivateChannelForward));
4360+
return Err(LocalHTLCFailureReason::PrivateChannelForward);
43624361
}
43634362
if let HopConnector::ShortChannelId(outgoing_scid) = next_packet.outgoing_connector {
43644363
if chan.funding.get_channel_type().supports_scid_privacy() && outgoing_scid != chan.context.outbound_scid_alias() {
43654364
// `option_scid_alias` (referred to in LDK as `scid_privacy`) means
43664365
// "refuse to forward unless the SCID alias was used", so we pretend
43674366
// we don't have the channel here.
4368-
return Err(("Refusing to forward over real channel SCID as our counterparty requested.",
4369-
LocalHTLCFailureReason::RealSCIDForward));
4367+
return Err(LocalHTLCFailureReason::RealSCIDForward);
43704368
}
43714369
} else {
4372-
return Err(("Cannot forward by Node ID without SCID.",
4373-
LocalHTLCFailureReason::InvalidTrampolineForward));
4370+
return Err(LocalHTLCFailureReason::InvalidTrampolineForward);
43744371
}
43754372

43764373
// Note that we could technically not return an error yet here and just hope
@@ -4380,16 +4377,13 @@ where
43804377
// on a small/per-node/per-channel scale.
43814378
if !chan.context.is_live() {
43824379
if !chan.context.is_enabled() {
4383-
return Err(("Forwarding channel has been disconnected for some time.",
4384-
LocalHTLCFailureReason::ChannelDisabled));
4380+
return Err(LocalHTLCFailureReason::ChannelDisabled);
43854381
} else {
4386-
return Err(("Forwarding channel is not in a ready state.",
4387-
LocalHTLCFailureReason::ChannelNotReady));
4382+
return Err(LocalHTLCFailureReason::ChannelNotReady);
43884383
}
43894384
}
43904385
if next_packet.outgoing_amt_msat < chan.context.get_counterparty_htlc_minimum_msat() {
4391-
return Err(("HTLC amount was below the htlc_minimum_msat",
4392-
LocalHTLCFailureReason::AmountBelowMinimum));
4386+
return Err(LocalHTLCFailureReason::AmountBelowMinimum);
43934387
}
43944388
chan.htlc_satisfies_config(msg, next_packet.outgoing_amt_msat, next_packet.outgoing_cltv_value)?;
43954389

@@ -4420,12 +4414,11 @@ where
44204414

44214415
fn can_forward_htlc(
44224416
&self, msg: &msgs::UpdateAddHTLC, next_packet_details: &NextPacketDetails
4423-
) -> Result<(), (&'static str, LocalHTLCFailureReason)> {
4417+
) -> Result<(), LocalHTLCFailureReason> {
44244418
let outgoing_scid = match next_packet_details.outgoing_connector {
44254419
HopConnector::ShortChannelId(scid) => scid,
44264420
HopConnector::Trampoline(_) => {
4427-
return Err(("Cannot forward by Node ID without SCID.",
4428-
LocalHTLCFailureReason::InvalidTrampolineForward));
4421+
return Err(LocalHTLCFailureReason::InvalidTrampolineForward);
44294422
}
44304423
};
44314424
match self.do_funded_channel_callback(outgoing_scid, |chan: &mut FundedChannel<SP>| {
@@ -4440,8 +4433,7 @@ where
44404433
fake_scid::is_valid_intercept(&self.fake_scid_rand_bytes, outgoing_scid, &self.chain_hash)) ||
44414434
fake_scid::is_valid_phantom(&self.fake_scid_rand_bytes, outgoing_scid, &self.chain_hash)
44424435
{} else {
4443-
return Err(("Don't have available channel for forwarding as requested.",
4444-
LocalHTLCFailureReason::UnknownNextPeer));
4436+
return Err(LocalHTLCFailureReason::UnknownNextPeer);
44454437
}
44464438
}
44474439
}
@@ -4453,7 +4445,7 @@ where
44534445
}
44544446

44554447
fn htlc_failure_from_update_add_err(
4456-
&self, msg: &msgs::UpdateAddHTLC, counterparty_node_id: &PublicKey, err_msg: &'static str,
4448+
&self, msg: &msgs::UpdateAddHTLC, counterparty_node_id: &PublicKey,
44574449
reason: LocalHTLCFailureReason, is_intro_node_blinded_forward: bool,
44584450
shared_secret: &[u8; 32]
44594451
) -> HTLCFailureMsg {
@@ -4477,7 +4469,7 @@ where
44774469

44784470
log_info!(
44794471
WithContext::from(&self.logger, Some(*counterparty_node_id), Some(msg.channel_id), Some(msg.payment_hash)),
4480-
"Failed to accept/forward incoming HTLC: {}", err_msg
4472+
"Failed to accept/forward incoming HTLC: {:?}", reason,
44814473
);
44824474
// If `msg.blinding_point` is set, we must always fail with malformed.
44834475
if msg.blinding_point.is_some() {
@@ -5820,9 +5812,9 @@ where
58205812
)
58215813
}) {
58225814
Some(Ok(_)) => {},
5823-
Some(Err((err, reason))) => {
5815+
Some(Err(reason)) => {
58245816
let htlc_fail = self.htlc_failure_from_update_add_err(
5825-
&update_add_htlc, &incoming_counterparty_node_id, err, reason,
5817+
&update_add_htlc, &incoming_counterparty_node_id, reason,
58265818
is_intro_node_blinded_forward, &shared_secret,
58275819
);
58285820
let failure_type = get_htlc_failure_type(outgoing_scid_opt, update_add_htlc.payment_hash);
@@ -5835,11 +5827,11 @@ where
58355827

58365828
// Now process the HTLC on the outgoing channel if it's a forward.
58375829
if let Some(next_packet_details) = next_packet_details_opt.as_ref() {
5838-
if let Err((err, reason)) = self.can_forward_htlc(
5830+
if let Err(reason) = self.can_forward_htlc(
58395831
&update_add_htlc, next_packet_details
58405832
) {
58415833
let htlc_fail = self.htlc_failure_from_update_add_err(
5842-
&update_add_htlc, &incoming_counterparty_node_id, err, reason,
5834+
&update_add_htlc, &incoming_counterparty_node_id, reason,
58435835
is_intro_node_blinded_forward, &shared_secret,
58445836
);
58455837
let failure_type = get_htlc_failure_type(outgoing_scid_opt, update_add_htlc.payment_hash);

lightning/src/ln/onion_payment.rs

+7-8
Original file line numberDiff line numberDiff line change
@@ -453,11 +453,11 @@ where
453453
}),
454454
};
455455

456-
if let Err((err_msg, reason)) = check_incoming_htlc_cltv(
456+
if let Err(reason) = check_incoming_htlc_cltv(
457457
cur_height, outgoing_cltv_value, msg.cltv_expiry,
458458
) {
459459
return Err(InboundHTLCErr {
460-
msg: err_msg,
460+
msg: "incoming cltv check failed",
461461
reason,
462462
err_data: Vec::new(),
463463
});
@@ -601,19 +601,18 @@ where
601601

602602
pub(super) fn check_incoming_htlc_cltv(
603603
cur_height: u32, outgoing_cltv_value: u32, cltv_expiry: u32
604-
) -> Result<(), (&'static str, LocalHTLCFailureReason)> {
604+
) -> Result<(), LocalHTLCFailureReason> {
605605
if (cltv_expiry as u64) < (outgoing_cltv_value) as u64 + MIN_CLTV_EXPIRY_DELTA as u64 {
606-
return Err(("Forwarding node has tampered with the intended HTLC values or origin node has an obsolete cltv_expiry_delta",
607-
LocalHTLCFailureReason::IncorrectCLTVExpiry));
606+
return Err(LocalHTLCFailureReason::IncorrectCLTVExpiry);
608607
}
609608
// Theoretically, channel counterparty shouldn't send us a HTLC expiring now,
610609
// but we want to be robust wrt to counterparty packet sanitization (see
611610
// HTLC_FAIL_BACK_BUFFER rationale).
612611
if cltv_expiry <= cur_height + HTLC_FAIL_BACK_BUFFER as u32 {
613-
return Err(("CLTV expiry is too close", LocalHTLCFailureReason::CLTVExpiryTooSoon));
612+
return Err(LocalHTLCFailureReason::CLTVExpiryTooSoon);
614613
}
615614
if cltv_expiry > cur_height + CLTV_FAR_FAR_AWAY as u32 {
616-
return Err(("CLTV expiry is too far in the future", LocalHTLCFailureReason::CLTVExpiryTooFar));
615+
return Err(LocalHTLCFailureReason::CLTVExpiryTooFar);
617616
}
618617
// If the HTLC expires ~now, don't bother trying to forward it to our
619618
// counterparty. They should fail it anyway, but we don't want to bother with
@@ -624,7 +623,7 @@ pub(super) fn check_incoming_htlc_cltv(
624623
// but there is no need to do that, and since we're a bit conservative with our
625624
// risk threshold it just results in failing to forward payments.
626625
if (outgoing_cltv_value) as u64 <= (cur_height + LATENCY_GRACE_PERIOD_BLOCKS) as u64 {
627-
return Err(("Outgoing CLTV value is too soon", LocalHTLCFailureReason::OutgoingCLTVTooSoon));
626+
return Err(LocalHTLCFailureReason::OutgoingCLTVTooSoon);
628627
}
629628

630629
Ok(())

0 commit comments

Comments
 (0)