Gas Fee Estimation
Purpose
Gas Fee Estimation addresses the challenge of accurately calculating transaction gas fees on Ethereum and EVM-compatible blockchains. Given the dynamic nature of blockchain transaction costs—driven by network demand and protocol changes—this component provides reliable fee estimates at various percentiles by analyzing recent block and transaction fee data. This enables clients to select appropriate gas fees for timely and cost-effective transaction inclusion, improving user experience and reducing failed transactions due to underpayment.
Functionality
The estimation logic centers on collecting and processing gas price data from recent blocks:
Block Data Collection: The system fetches a configurable number of the latest blocks (default 20) including their transactions.
Transaction Fee Extraction: For each transaction in these blocks, it extracts
gasPriceand maxPriorityFeePerGas values, filtering out transactions that pay no gas or are non-standard.Percentile Computation: For user-requested percentiles (e.g., 10th, 50th, 90th), it calculates average gas fees across these blocks at those statistical thresholds, providing tiered fee options.
Base Fee Handling: It tracks the current base fee per gas from the latest block or via a specialized RPC method (depending on blockchain), incorporating this into the max fee calculation with optional buffering for specific chains.
State Synchronization: The component continuously synchronizes its internal state by updating missing or new blocks and pruning outdated data, ensuring fee estimates reflect the most recent network conditions.
Resilience: Incorporates retry logic with exponential backoff for RPC failures, and supports coinstack-specific behaviors such as querying "pending" blocks or adjusting fee buffers.
Core Methods & Data Flow
start(): Initializes the oracle by loading recent blocks and kicking off the background block processing loop.estimateFees(percentiles, blockCount): Returns gas fee estimates at requested percentiles based on current cached block fee data.onBlock(newBlock): WebSocket handler that queues new blocks for processing.processBlocks(): Sequentially processes queued blocks, updating fee data.update(blockNumber, blockTag): Fetches and parses fee data for a specific block, updating internal maps.sync(): Validates and synchronizes internal block fee data with the latest blockchain state.averageAtPercentile(blockFees, percentile): Calculates average gas fees at a given percentile across blocks, filtering out outliers.
This data-driven, percentile-based approach allows nuanced fee recommendations that adapt dynamically to network conditions.
Relationship to Parent Topic and Other Subtopics
Within the broader **EVM Gas Oracle** module, Gas Fee Estimation provides the foundational calculation logic that feeds into other components such as:
Gas Oracle Integration: Utilizes the percentile fee estimates generated here to serve API requests, enabling clients to retrieve recommended gas fees for transactions.
WebSocket Event Subscription (if applicable): May consume real-time block updates to trigger onBlock calls, ensuring fee estimates remain current.
Gas Fee Estimation is distinct in focusing on statistical analysis of historical block data rather than solely integrating or exposing fees. It ensures that the gas fee values used throughout the system are statistically sound, responsive to network changes, and customized per blockchain’s capabilities and quirks.
Diagram
flowchart TD
Start[Start Oracle] --> FetchBlocks[Fetch Latest N Blocks]
FetchBlocks --> ExtractFees[Extract Tx Gas Prices & Priority Fees]
ExtractFees --> UpdateCache[Update Fee Cache per Block]
UpdateCache --> SyncState[Sync & Prune Cache]
SyncState --> Estimate[Estimate Fees at Requested Percentiles]
Estimate --> ReturnFees[Return Fee Estimates]
ReturnFees --> AwaitNewBlocks[Wait for New Blocks]
AwaitNewBlocks -->|New Block via WebSocket| EnqueueBlock[Enqueue New Block]
EnqueueBlock --> ProcessBlock[Process Next Block]
ProcessBlock --> UpdateCache
ProcessBlock --> SyncState
SyncState --> Estimate
This flowchart highlights the continuous cycle of fetching, caching, syncing, and estimating gas fees using recent blockchain data, incorporating new blocks via WebSocket events.
Code Snippet Illustration
The key method that calculates average fees at a percentile across recent blocks:
private averageAtPercentile(blockFees: Array<BlockFees>, percentile: number) {
const valueAtPercentile = (fees: Array<number>) => {
if (!fees.length) return 0
const rank = Math.ceil((percentile / 100) * fees.length)
return fees[rank - 1]
}
// Filter out outliers using thresholds
const gasPriceThreshold = getFeeThreshold(blockFees.flatMap(f => f.gasPrices).filter(p => p > 1))
const maxPriorityFeeThreshold = getFeeThreshold(blockFees.flatMap(f => f.maxPriorityFees).filter(p => p > 1))
const sum = blockFees.reduce((sum, fees) => {
sum.gasPrice += valueAtPercentile(fees.gasPrices.filter(p => p <= gasPriceThreshold))
sum.maxPriorityFee += valueAtPercentile(fees.maxPriorityFees.filter(p => p <= maxPriorityFeeThreshold))
return sum
}, { gasPrice: 0, maxPriorityFee: 0 })
return {
gasPrice: Math.ceil(sum.gasPrice / blockFees.length),
maxPriorityFee: Math.ceil(sum.maxPriorityFee / blockFees.length),
}
}
This snippet demonstrates how the oracle smooths out gas price data by removing outliers and averaging percentile values across multiple blocks to provide robust fee estimates.
Gas Fee Estimation thus serves as the statistical engine powering accurate, adaptive gas fee recommendations essential for efficient transaction processing on EVM-based blockchains.