lnwallet: make DustLimitForSize total over the sizes it can be handed
What changed, and why it matters
This change removes a deliberate program crash (panic) in LND's fee/dust-limit helper and replaces it with a safe fallback. Previously, if the helper received a script length it didn't explicitly recognize, it would panic and potentially crash the node. Now it treats any unrecognized length as a generic witness output and returns a dust value instead. The patch is defensive: it makes the code well-defined for future Bitcoin witness versions and arbitrary script sizes, but the commit message does not frame it as fixing a known exploitable vulnerability.
Review callers of DustLimitForSize to confirm they no longer rely on panic behavior, and ensure the conservative unknown-witness dust threshold is acceptable for all possible script sizes in production paths. Consider whether any caller should explicitly reject unsupported sizes rather than silently accepting the fallback.
Security signals we found
Removal of a panic/default branch in favor of a conservative fallback
Defensive handling of arbitrary and future witness-version script sizes
Potential denial-of-service vector eliminated: unhandled script lengths no longer crash the helper
Conservative dust pricing chosen for unknown cases, reducing economic risk
Evidence from the diff
DustLimitForSize in lnwallet/parameters.go switched on script size and panicked in the default case. The commit changes the default case to generate an unknown-witness pkscript and return its dust threshold. This covers witness program lengths from 2-40 bytes (versions 1-16) that don’t match the fixed P2WPKH/P2WSH/P2SH/P2PKH sizes. A test is added for sizes 7 and 42. The change prevents node crashes on unexpected script sizes and future witness versions, using the most conservative dust pricing as a fallback.
Changed components
lnwallet/parameters.golnwallet/parameters_test.goDustLimitForSize helperInspect captured patch +23 / −6
### lnwallet/parameters.go
@@ -41,8 +41,10 @@ func DefaultRoutingFeeLimitForAmount(a lnwire.MilliSatoshi) lnwire.MilliSatoshi
// 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. It must be
-// called with a proper size parameter or else a panic occurs.
+// 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
@@ -66,11 +68,11 @@ func DustLimitForSize(scriptSize int) btcutil.Amount {
case input.P2PKHSize:
pkscript, _ = input.GenerateP2PKH([]byte{})
- case input.UnknownWitnessSize:
- pkscript, _ = input.GenerateUnknownWitness()
-
+ // 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:
- panic("invalid script size")
+ pkscript, _ = input.GenerateUnknownWitness()
}
// Call GetDustThreshold with a TxOut containing the generated
### lnwallet/parameters_test.go
@@ -81,6 +81,21 @@ func TestDustLimitForSize(t *testing.T) {
size: input.UnknownWitnessSize,
expectedLimit: btcutil.Amount(354),
},
+ {
+ // An arbitrary short length that matches no known
+ // template is priced as a generic witness output
+ // rather than treated as an error.
+ name: "arbitrary small size",
+ size: 7,
+ expectedLimit: btcutil.Amount(354),
+ },
+ {
+ // The largest witness program length is also handled
+ // as a generic witness output.
+ name: "arbitrary large witness size",
+ size: 42,
+ expectedLimit: btcutil.Amount(354),
+ },
}
for _, test := range tests {Why this scored 51/100
Community notes
Notes can correct, qualify, or add evidence to the AI analysis. Every note shown here has been validated by a human moderator.
The AI analysis stands alone for now. Submit a note if you can add evidence or important context.