Context
With deterministic (SIGHASH_DEFAULT) second-level HTLCs on asset channels (lightningnetwork/lnd#11094 and follow-ups), the pre-signed second-level HTLC transaction carries a minimal baked-in fee plus a CPFP anchor at output index 1. The anchor is the only fee-bumping path: the peer's signature commits to the full transaction, so no RBF and no added inputs.
How aggressively lnd's sweeper bumps via that anchor is bounded by a budget (max sats it may burn as fees on the child). lnd can only derive that budget from BTC-denominated values it knows about, and on an asset channel those are tiny by design (the HTLC output is around 1200 sats while the HTLC may carry arbitrarily valuable assets). A budget derived from the BTC value alone means the sweeper gives up on fee-bumping long before it stops being economical, and in a high-fee environment the second-level transaction may never confirm before the deadline. This was raised in review on the lnd PR.
The same blindness applies to other sweeps of asset-bearing outputs (first-level HTLC sweeps, breach/justice sweeps): lnd budgets by BTC value, tapd is the only party that knows the real value at stake.
What exists today
lnd already has the right hook: sweep.AuxSweeper.ExtraBudgetForInputs(inputs []input.Input) lets the aux side add budget for a set of inputs, and the sweeper applies it in its input-set and aggregation logic. tapd currently returns a fixed or zero value and only looks at whether an input carries a resolution blob. Two gaps:
- tapd does not recognize which inputs protect asset value (the second-level CPFP anchor input carries no resolution blob at all), so it cannot target the inputs that matter.
- tapd has no pricing step: turning "this input protects X units of asset Y" into a sat-denominated budget needs a rate, e.g. via the RFQ price oracle, plus a configurable ratio/cap similar to lnd's
--sweeper.budget.* knobs.
Proposal
- Extend tapd's
ExtraBudgetForInputs to identify inputs that protect asset value (by outpoint mapping to known channel/HTLC state, including second-level anchor outputs of deterministic HTLC transactions) and return a budget derived from the protected asset value priced in sats, with a configurable ratio and cap.
- Consider a read-only RPC endpoint to inspect the budget tapd would assign for a given outpoint (or to query an HTLC's real value in asset units and its current sat valuation), so operators can audit and tune sweeping behavior.
- Depending on review discussion on the lnd side, the second-level anchor budget could alternatively be supplied at resolution time via the aux resolver rather than the sweeper hook; tracking both options here.
Refs
Context
With deterministic (SIGHASH_DEFAULT) second-level HTLCs on asset channels (lightningnetwork/lnd#11094 and follow-ups), the pre-signed second-level HTLC transaction carries a minimal baked-in fee plus a CPFP anchor at output index 1. The anchor is the only fee-bumping path: the peer's signature commits to the full transaction, so no RBF and no added inputs.
How aggressively lnd's sweeper bumps via that anchor is bounded by a budget (max sats it may burn as fees on the child). lnd can only derive that budget from BTC-denominated values it knows about, and on an asset channel those are tiny by design (the HTLC output is around 1200 sats while the HTLC may carry arbitrarily valuable assets). A budget derived from the BTC value alone means the sweeper gives up on fee-bumping long before it stops being economical, and in a high-fee environment the second-level transaction may never confirm before the deadline. This was raised in review on the lnd PR.
The same blindness applies to other sweeps of asset-bearing outputs (first-level HTLC sweeps, breach/justice sweeps): lnd budgets by BTC value, tapd is the only party that knows the real value at stake.
What exists today
lnd already has the right hook:
sweep.AuxSweeper.ExtraBudgetForInputs(inputs []input.Input)lets the aux side add budget for a set of inputs, and the sweeper applies it in its input-set and aggregation logic. tapd currently returns a fixed or zero value and only looks at whether an input carries a resolution blob. Two gaps:--sweeper.budget.*knobs.Proposal
ExtraBudgetForInputsto identify inputs that protect asset value (by outpoint mapping to known channel/HTLC state, including second-level anchor outputs of deterministic HTLC transactions) and return a budget derived from the protected asset value priced in sats, with a configurable ratio and cap.Refs
sweep/interface.goExtraBudgetForInputsin lnd