feat: add --fee-strategy flag for adaptive fee calculation#209
Merged
qu0b merged 5 commits intoethpandaops:masterfrom Mar 19, 2026
Merged
feat: add --fee-strategy flag for adaptive fee calculation#209qu0b merged 5 commits intoethpandaops:masterfrom
qu0b merged 5 commits intoethpandaops:masterfrom
Conversation
Replace the static baseFee*2 multiplier with adaptive fee calculation
in GetSuggestedFees (works for all scenarios, no rate manipulation):
1. Dynamic headroom (sliding window over last 10 blocks):
50% avg fill (target) → baseFee/8 headroom (1 block of max change)
100% avg fill → baseFee/16 (clamped minimum)
0% avg fill → baseFee/4 headroom (2 blocks of max change)
2. Lagged baseFee center: uses the AVERAGE baseFee from the window
instead of the current baseFee. When baseFee is rising, the average
lags behind, shifting more tx below currentBaseFee → rejected by EL →
nonce gaps → wallet stalls → reduced throughput → baseFee recovers.
3. Normal distribution spread: feeCaps sampled from N(center, sigma²)
where sigma = headroom/1.28. ~10% canary tx sit near the floor.
4. baseFeeWei parameter (scenario default: 20 gwei) now acts as a
MAXIMUM CAP instead of an exact override. The dynamic mechanism
always runs — the cap only triggers if the computed feeCap exceeds
baseFeeWei (e.g., on chains with very high baseFee). No scenario
default changes needed.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Restore original fee calculation as default (use provided fees or fetch from network via eth_gasPrice). Move the dynamic headroom + normal distribution fee calculation behind --fee-strategy adaptive flag. This collapses the fee changes from PR ethpandaops#207 and the dynamic headroom commit into a single opt-in strategy, keeping the client distribution fix from ethpandaops#207 untouched. Also fix EIP-1559 violation in adaptive mode where feeCap could be lower than tipCap due to normal distribution sampling. Configuration examples: # CLI (single scenario) spamoor eoatx --fee-strategy adaptive -h http://localhost:8545 # CLI (yaml multi-scenario) spamoor run config.yaml --fee-strategy adaptive # Daemon spamoor-daemon --fee-strategy adaptive -h http://localhost:8545 # Kurtosis (spamoor_params) spamoor_params: extra_args: - --fee-strategy=adaptive Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Move FeeStrategy from TxPoolOptions (global) to WalletPoolConfig
(per-spammer) so each spammer in daemon mode can use a different fee
calculation strategy.
- Add FeeStrategy field to WalletPoolConfig (yaml: fee_strategy)
- Add WalletPool.GetSuggestedFees() convenience method that reads
the strategy from its own config
- Change TxPool.GetSuggestedFees() to accept variadic feeStrategy
parameter (backward compatible - existing callers unchanged)
- Update all 42 scenario call sites to use walletPool.GetSuggestedFees()
- Keep --fee-strategy CLI flag on single-scenario mode (cmd/spamoor)
- Remove --fee-strategy from daemon and run commands (comes from
per-spammer YAML config instead)
Configuration examples:
# CLI (single scenario)
spamoor eoatx --fee-strategy adaptive -h http://localhost:8545
# YAML (per-spammer in run or daemon mode)
- scenario: eoatx
config:
fee_strategy: adaptive
throughput: 50
# Kurtosis (spamoor_params)
spamoor_params:
spammers:
- scenario: eoatx
config: {fee_strategy: adaptive, throughput: 50}
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Return a clear error instead of panicking if client is nil when the adaptive strategy needs to fetch fees from the network. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Add commented-out fee_strategy hint to the default YAML config shown when creating a new spammer in the web UI. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
pk910
approved these changes
Mar 19, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
eth_gasPrice)fee_strategy: adaptiveWalletPoolConfig, not global — each spammer in daemon mode can use a different strategyfeeCap < tipCapcould occur in the adaptive strategy due to normal distribution samplingwalletPool.GetSuggestedFees()(reads strategy from config)The adaptive strategy uses a sliding window of recent block gas usage to compute dynamic headroom above the average baseFee, with a normal distribution spread across transactions. This creates a self-correcting feedback loop: when blocks are full and baseFee is rising, more transactions land below the current baseFee and get rejected, reducing throughput until baseFee recovers.
Configuration
CLI (single scenario)
YAML (per-spammer in
spamoor runor daemon mode)YAML (mixed strategies — different per spammer)
Daemon mode (via UI/API)
Set
fee_strategy: adaptivein the spammer config — each spammer gets its ownWalletPoolwith independent fee strategy.Kurtosis (spamoor_params)
Docker
Test plan
go build ./...,go vet ./...,go fmt ./...)--fee-strategy adaptiveCLI flag — 10 tx/block confirmed, zero errorsfee_strategy: adaptiveinspamoor run— 10 tx/block confirmed, zero errors🤖 Generated with Claude Code