How the Fuel Core Gas Price Algorithm Works: Components and Implementation
Fuel Core determines transaction fees through a pluggable gas price algorithm system built around a trait-based interface, thread-safe shared wrappers, and swappable implementations (V0, V1, and static) that calculate both current and worst-case gas prices for block validation.
Fuel Core uses a modular architecture to compute transaction fees dynamically. The gas price algorithm is implemented as a trait with multiple concrete versions, wrapped in a thread-safe container that allows live updates without restarting the node. This design separates the economic model from the node internals, enabling protocol upgrades to modify pricing logic on the fly.
Core Components of the Gas Price Algorithm Architecture
The GasPriceAlgorithm Trait
In crates/services/gas_price_service/src/common/gas_price_algorithm.rs, the GasPriceAlgorithm trait defines the contract that all algorithms must implement:
fn next_gas_price(&self) -> u64;
fn worst_case_gas_price(&self, block_height: BlockHeight) -> u64;
The next_gas_price method returns the fee for the immediate next block, while worst_case_gas_price provides an upper bound for a specific block height. The transaction pool uses this upper bound to reject transactions that would exceed the maximum accepted price before they enter the mempool.
The SharedGasPriceAlgo Wrapper
The same file defines SharedGasPriceAlgo<A>, a generic wrapper that holds the concrete algorithm inside an Arc<RwLock<A>>. This structure allows the Fuel Core node to:
- Query prices concurrently from multiple threads without blocking
- Replace the algorithm live via the
update(new_algo)method during network upgrades or configuration changes
Concrete Algorithm Implementations
Fuel Core ships with three distinct implementations:
V0 Algorithm – Located in crates/services/gas_price_service/src/v0/algorithm.rs, this is the original Fuel v0 implementation that delegates to fuel_gas_price_algorithm::v0::AlgorithmV0.
V1 Algorithm – Found in crates/services/gas_price_service/src/v1/algorithm.rs, this is the current default for Fuel v1+, using fuel_gas_price_algorithm::v1::AlgorithmV1 to calculate prices based on percentage changes and moving averages.
Static Algorithm – Defined in crates/services/gas_price_service/src/static_updater.rs, this constant-price fallback returns fixed values for both methods, useful for private networks and testing environments.
How Gas Prices Are Calculated and Queried
The algorithm operates through a delegation pattern. Both V0 and V1 implementations forward their calculations to the external fuel_gas_price_algorithm crate, which encapsulates the actual economic models. The static implementation simply returns a configured constant.
When the transaction pool needs to validate incoming transactions, it calls worst_case_gas_price for the current block height. If a transaction's offered fee exceeds this worst-case value, the node rejects it immediately.
Integration with Node Services and Persistence
Service Adapters and APIs
The crates/fuel-core/src/service/adapters/gas_price_adapters.rs file bridges the algorithm to the node's RPC and GraphQL interfaces. When clients query for the current gas price, the adapter reads from the shared algorithm instance and returns the result.
Database Schema
The last known gas price persists in the database schema defined in crates/fuel-core/src/schema/gas_price.rs, storing the price: u64 alongside a timestamp. This ensures that if the node restarts, it can restore the previous pricing state rather than starting from zero.
Live Algorithm Updates Without Restart
The SharedGasPriceAlgo wrapper enables hot-swapping of algorithms. During a hard fork or configuration change, operators can call:
shared_algo.update(new_algorithm);
This replaces the internal Arc pointer atomically, ensuring that subsequent queries use the new logic while existing references complete safely. This mechanism is tested in crates/services/gas_price_service/src/v0/tests.rs and the corresponding V1 test file.
Practical Example: Querying the Gas Price Algorithm
Here's how to interact with the shared algorithm in application code:
use fuel_core_types::fuel_types::BlockHeight;
use fuel_gas_price_algorithm::v1::AlgorithmV1;
use fuel_core::services::gas_price_service::{
common::gas_price_algorithm::{SharedGasPriceAlgo, GasPriceAlgorithm},
};
// Initialize a V1 algorithm with default parameters
let algo = AlgorithmV1::default();
let shared_algo = SharedGasPriceAlgo::new_with_algorithm(algo);
// Query the next block's gas price
let next_price = shared_algo.next_gas_price();
println!("Next block gas price: {}", next_price);
// Calculate worst-case price for a future block
let future_height = BlockHeight::new(1_500_000);
let worst_case = shared_algo.worst_case_gas_price(future_height);
println!("Worst-case price at height {}: {}", future_height, worst_case);
// Perform a live update during network upgrade
let upgraded_algo = AlgorithmV1::new(/* new params */);
shared_algo.update(upgraded_algo);
Summary
- Fuel Core implements gas pricing through a trait-based architecture centered on
GasPriceAlgorithmincrates/services/gas_price_service/src/common/gas_price_algorithm.rs. - The
SharedGasPriceAlgo<A>wrapper provides thread-safe access and enables live algorithm updates viaArc<RwLock<A>>. - Three concrete implementations exist: V0 (original), V1 (current with moving averages), and Static (constant price for testing).
- The algorithm calculates both
next_gas_pricefor immediate blocks andworst_case_gas_pricefor transaction pool validation. - Prices persist in the database schema at
crates/fuel-core/src/schema/gas_price.rsand expose via adapters incrates/fuel-core/src/service/adapters/gas_price_adapters.rs.
Frequently Asked Questions
What is the difference between V0 and V1 gas price algorithms in Fuel Core?
The V0 algorithm, found in crates/services/gas_price_service/src/v0/algorithm.rs, represents the original Fuel protocol implementation and delegates to fuel_gas_price_algorithm::v0::AlgorithmV0. The V1 algorithm, located in crates/services/gas_price_service/src/v1/algorithm.rs, is the updated version used from Fuel v1 onward, utilizing fuel_gas_price_algorithm::v1::AlgorithmV1 with refined economic models including percentage-based adjustments and moving averages for more stable fee markets.
How does Fuel Core handle gas price queries during a live algorithm update?
The SharedGasPriceAlgo wrapper uses an Arc<RwLock<A>> internally, allowing atomic updates through the update() method. When operators swap algorithms during a hard fork, the wrapper replaces the internal pointer atomically. New queries immediately use the updated logic while existing reads complete safely, ensuring zero-downtime configuration changes without node restarts.
What is the worst_case_gas_price method used for?
The worst_case_gas_price(&self, block_height: BlockHeight) -> u64 method provides an upper bound estimate for transaction fees at a specific future block height. The transaction pool uses this value to reject transactions that would exceed the maximum accepted price for the current block height, preventing users from accidentally overpaying or submitting transactions that violate protocol fee constraints.
Where is the current gas price stored when the node restarts?
Fuel Core persists the last known gas price in the database schema defined in crates/fuel-core/src/schema/gas_price.rs, which stores a price: u64 value alongside a timestamp. During node initialization, this stored price restores the algorithm's state, ensuring pricing continuity across restarts rather than resetting to default values.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →