Skip to content

Commit 0a01ca2

Browse files
committed
Honor the per-peer fee policy at the skim site
The forwarding skim now reads the peer's granted policy from the SCID store instead of hard-coding Flat(Standard). A peer with no grant resolves to Standard, so the skim is byte-for-byte the historical 2% for everyone the issuer set has not waived. This is the read side that makes the persisted grant actually take effect; before it, a verified ZeroFee was stored and then ignored. The lookup is hoisted out of the per-HTLC loop because the policy is keyed by peer, not by HTLC, so it is one store read per batch rather than one per forward. A zero skim is now two distinct cases, so the log is split. ZeroFee is the expected path and logs at info. Any other tier skimming nothing means the fee would have consumed the whole HTLC, which keeps the error-level log: a forward of the full amount that we expected to take a cut on. Previously ZeroFee was unreachable, so the single error log was correct; now that a grant can legitimately waive the fee, the error would be noise.
1 parent d886fba commit 0a01ca2

1 file changed

Lines changed: 24 additions & 8 deletions

File tree

lightning-liquidity/src/lsps4/service.rs

Lines changed: 24 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -466,6 +466,14 @@ where
466466
skimmed_fee_msat: u64,
467467
}
468468

469+
// The peer's granted policy, looked up once. Peers with no grant resolve to Standard, so
470+
// the skim matches the historical 2% for everyone the issuer set hasn't waived.
471+
let policy = self
472+
.scid_store
473+
.get_policy(&their_node_id)
474+
.unwrap_or(FeePolicy::Flat(FeeTier::Standard));
475+
let is_zero_fee = matches!(policy, FeePolicy::Flat(FeeTier::ZeroFee));
476+
469477
let mut computed_htlcs: Vec<ComputedHtlc> = htlcs
470478
.drain(..)
471479
.map(|htlc| {
@@ -476,18 +484,26 @@ where
476484

477485
let htlc_id = htlc.id();
478486
let skimmed_fee_msat = resolve_skim(
479-
&FeePolicy::Flat(FeeTier::Standard),
487+
&policy,
480488
expected_outbound_msat,
481489
self.config.forwarding_fee_proportional_millionths,
482490
);
483491
if skimmed_fee_msat == 0 {
484-
// The policy here is always Flat(Standard), so a zero skim can only mean the
485-
// fee would have consumed the entire HTLC; it is never a ZeroFee waiver yet.
486-
log_error!(
487-
self.logger,
488-
"Standard skim would have consumed the entire HTLC {:?}; forwarding the full amount.",
489-
htlc_id
490-
);
492+
if is_zero_fee {
493+
log_info!(
494+
self.logger,
495+
"Zero-fee policy for HTLC {:?}; forwarding the full amount.",
496+
htlc_id
497+
);
498+
} else {
499+
// A non-zero-fee tier skimmed nothing only because the fee would have
500+
// consumed the entire HTLC; forward it intact rather than break it.
501+
log_error!(
502+
self.logger,
503+
"Skim would have consumed the entire HTLC {:?}; forwarding the full amount.",
504+
htlc_id
505+
);
506+
}
491507
}
492508

493509
let amount_to_forward_msat = expected_outbound_msat.saturating_sub(skimmed_fee_msat);

0 commit comments

Comments
 (0)