Skip to content

fix(config): fail loudly on invalid or fractional numeric config#24536

Merged
PhilWindle merged 4 commits into
merge-train/spartan-v5from
spl/a-1398-number-config-options-silently-truncate-decimals
Jul 6, 2026
Merged

fix(config): fail loudly on invalid or fractional numeric config#24536
PhilWindle merged 4 commits into
merge-train/spartan-v5from
spl/a-1398-number-config-options-silently-truncate-decimals

Conversation

@spalladino

@spalladino spalladino commented Jul 6, 2026

Copy link
Copy Markdown
Contributor

Human-written summary

Invalid numeric values in config were silently ignored and replaced with the default. Also, config entries defined with numberConfigHelper accepted non-integer values but silently truncated them.

Context

The numeric config helpers mishandled bad input in two ways:

  • numberConfigHelper / optionalNumberConfigHelper parsed with parseInt, which silently truncated decimals — an integer config set to 0.8 became 0 with no warning. In the worst case (A-1312) that turned a fractional retention window into 0, i.e. "delete immediately".
  • numberConfigHelper, floatConfigHelper and percentageConfigHelper swallowed any unparseable value and returned the config default (the JSDoc even documented "...or is invalid"), so a typo'd env var ran silently with an unexpected value.

Approach

The config default is for an unset env var only — empty/unset is already resolved to the default before parseEnv runs, so the only thing parseEnv returning a default achieved was hiding bad input. The helpers now parse strictly and throw on any set-but-invalid value:

  • numberConfigHelper / optionalNumberConfigHelper: parse with parseFloat and require a safe integer (no more silent truncation).
  • floatConfigHelper / percentageConfigHelper: require a finite number; percentage additionally enforces 0–1.

bigint, enum and the secret helpers already threw on invalid input. booleanConfigHelper is intentionally unchanged: parseBooleanEnv is a total function (unrecognized tokens map to false), it never substitutes the configured default.

Auditing all ~150 numberConfigHelper call sites then surfaced options that legitimately take fractional values and would now wrongly reject them; these were moved to floatConfigHelper:

  • p2p gossipsub tx scoring — topic weight, invalid-message-delivery weight, and decay (default 0.5), which feed libp2p's float TopicScoreParams.
  • sequencer perBlockDAAllocationMultiplier (default 1.5); its sibling perBlockAllocationMultiplier already used floatConfigHelper.
  • L1 tx fee percentages — gasLimitBufferPercentage, priorityFeeBumpPercentage, priorityFeeRetryBumpPercentage.
  • bot minFeePadding, consumed as the fractional overpay factor 1 + padding; its zod schema no longer pins it to an integer.

Impact

A node whose numeric config env var (or CLI flag) is set to a non-numeric, fractional (for integer options), or out-of-range value now fails at startup with a clear error instead of silently running with a truncated or default value. Operators relying on the old lenient behavior must correct the value.

Fixes A-1398

numberConfigHelper and optionalNumberConfigHelper used parseInt, which
silently truncated decimals (parseInt('0.8') === 0). A user setting an
integer config to a fractional value ended up with an unexpected value
and no warning. Both helpers now parse with parseFloat and throw when the
result is not a safe integer, so misconfiguration fails loudly. Values
that legitimately need decimals already have floatConfigHelper and
percentageConfigHelper.

Fixes A-1398
An audit of numberConfigHelper call sites surfaced options whose default
is already fractional but were parsed as integers:

- p2p gossipsub tx scoring params (topic weight, invalid-message-delivery
  weight and decay) feed libp2p's float TopicScoreParams; the decay
  defaults to 0.5.
- The sequencer per-block DA allocation multiplier defaults to 1.5 and its
  sibling perBlockAllocationMultiplier already uses floatConfigHelper.

With number config helpers now rejecting non-integers, an operator setting
any of these to a decimal would fail at startup, so migrate them to
floatConfigHelper.
Continue the numberConfigHelper audit: these options accept a percentage
or multiplier where a fractional value is meaningful, so parse them as
floats rather than rejecting decimals.

- L1 tx fee percentages: gasLimitBufferPercentage, priorityFeeBumpPercentage
  and priorityFeeRetryBumpPercentage (e.g. a 12.5% buffer).
- bot minFeePadding, consumed as the fractional overpay factor 1 + padding
  (the wallet-sdk defaults the same concept to 0.5); its zod schema no
  longer pins it to an integer.
…g default

numberConfigHelper, floatConfigHelper and percentageConfigHelper swallowed
unparseable input and returned the config default, so a typo'd or malformed
value ran silently with an unexpected value. The default is meant for an
unset env var only (empty/unset is already resolved to the default before
parseEnv runs), so parseEnv now throws on any set-but-invalid value. Updated
the misleading '...or is invalid' JSDoc accordingly.
@spalladino spalladino changed the title fix(foundation): reject non-integer values in number config helpers fix(config): fail loudly on invalid or fractional numeric config Jul 6, 2026
@PhilWindle
PhilWindle merged commit 2ec670f into merge-train/spartan-v5 Jul 6, 2026
21 checks passed
@PhilWindle
PhilWindle deleted the spl/a-1398-number-config-options-silently-truncate-decimals branch July 6, 2026 16:32
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants