lnd/lnwallet/parameters.go
Olaoluwa Osuntokun f80f92dc04 lnwallet: make DustLimitForSize total over the sizes it can be handed
In this commit, we have DustLimitForSize fall back to the generic witness dust
threshold for any script size that doesn't match one of the well-known
templates.

The size switch covered P2WPKH, P2WSH, P2SH, P2PKH, and the explicit
unknown-witness size, and treated every other length as unreachable. That's a
narrower assumption than the callers can actually make good on: a witness
program for versions 1 through 16 carries a program of anywhere from 2 to 40
bytes, so its serialized length won't always land on one of those exact values.

The dust calculation only needs a representative output of roughly the right
shape, and the unknown-witness pricing is the conservative choice among the
ones we have, so we make it the default. That leaves the helper well defined
across the whole range of sizes callers can pass it, including scripts carrying
witness versions we don't know about yet.
2026-08-05 12:22:56 -07:00

89 lines
3 KiB
Go

package lnwallet
import (
"github.com/btcsuite/btcd/btcutil/v2"
"github.com/btcsuite/btcd/mempool"
"github.com/btcsuite/btcd/wire/v2"
"github.com/lightningnetwork/lnd/input"
"github.com/lightningnetwork/lnd/lnwire"
)
var (
// RoutingFee100PercentUpTo is the cut-off amount we allow 100% fees to
// be charged up to.
RoutingFee100PercentUpTo = lnwire.NewMSatFromSatoshis(1_000)
)
const (
// DefaultRoutingFeePercentage is the default off-chain routing fee we
// allow to be charged for a payment over the RoutingFee100PercentUpTo
// size.
DefaultRoutingFeePercentage lnwire.MilliSatoshi = 5
)
// DefaultRoutingFeeLimitForAmount returns the default off-chain routing fee
// limit lnd uses if the user does not specify a limit manually. The fee is
// amount dependent because of the base routing fee that is set on many
// channels. For example the default base fee is 1 satoshi. So sending a payment
// of one satoshi will cost 1 satoshi in fees over most channels, which comes to
// a fee of 100%. That's why for very small amounts we allow 100% fee.
func DefaultRoutingFeeLimitForAmount(a lnwire.MilliSatoshi) lnwire.MilliSatoshi {
// Allow 100% fees up to a certain amount to accommodate for base fees.
if a <= RoutingFee100PercentUpTo {
return a
}
// Everything larger than the cut-off amount will get a default fee
// percentage.
return a * DefaultRoutingFeePercentage / 100
}
// DustLimitForSize retrieves the dust limit for a given pkscript size. Given
// the size, it automatically determines whether the script is a witness script
// or not. It calls btcd's GetDustThreshold method under the hood. Any size that
// doesn't map to one of the well-known templates is treated as a generic
// witness output, so the helper stays well-defined for arbitrary (including
// future witness-version) script lengths.
func DustLimitForSize(scriptSize int) btcutil.Amount {
var (
dustlimit btcutil.Amount
pkscript []byte
)
// With the size of the script, determine which type of pkscript to
// create. This will be used in the call to GetDustThreshold. We pass
// in an empty byte slice since the contents of the script itself don't
// matter.
switch scriptSize {
case input.P2WPKHSize:
pkscript, _ = input.WitnessPubKeyHash([]byte{})
case input.P2WSHSize:
pkscript, _ = input.WitnessScriptHash([]byte{})
case input.P2SHSize:
pkscript, _ = input.GenerateP2SH([]byte{})
case input.P2PKHSize:
pkscript, _ = input.GenerateP2PKH([]byte{})
// Any other length (the explicit UnknownWitnessSize, or an otherwise
// unrecognized size) is priced as a generic witness output rather than
// treated as a hard error.
default:
pkscript, _ = input.GenerateUnknownWitness()
}
// Call GetDustThreshold with a TxOut containing the generated
// pkscript.
txout := &wire.TxOut{PkScript: pkscript}
dustlimit = btcutil.Amount(mempool.GetDustThreshold(txout))
return dustlimit
}
// DustLimitUnknownWitness returns the dust limit for an UnknownWitnessSize.
func DustLimitUnknownWitness() btcutil.Amount {
return DustLimitForSize(input.UnknownWitnessSize)
}