This document describes the high-level architecture of fuel-core, explaining how the major components are organized and interact with each other. It covers the service-oriented design, layered system structure, and the orchestration model that coordinates all subsystems.
For information about specific subsystems, see:
The fuel-core node is organized into five major layers: External Clients, API Layer, Core Services, Storage Layer, and External Systems. The central orchestrator FuelService at crates/fuel-core/src/service.rs114 manages all sub-services through a SharedState structure at crates/fuel-core/src/service.rs78
Sources: crates/fuel-core/src/service.rs114-130 crates/fuel-core/src/service.rs78-112 crates/fuel-core/src/service/sub_services.rs106-455 bin/fuel-core/src/cli/run.rs128-341
| Component | File Location | Responsibility |
|---|---|---|
FuelService | crates/fuel-core/src/service.rs114 | Main orchestrator that manages service lifecycle and coordinates sub-services |
Config | crates/fuel-core/src/service/config.rs64 | Configuration structure containing all service parameters |
SharedState | crates/fuel-core/src/service.rs78 | Shared state accessed by multiple services for coordination |
CombinedDatabase | crates/combined_database.rs | Aggregates multiple logical databases (on-chain, off-chain, relayer, gas price) |
SubServices | crates/fuel-core/src/service/sub_services.rs | Collection of all running sub-services |
Sources: crates/fuel-core/src/service.rs1-341 crates/fuel-core/src/service/config.rs1-240
The system follows a service-oriented architecture where each major subsystem implements the RunnableService trait. This provides a uniform interface for lifecycle management across all components.
Sources: crates/services/src/service.rs1-300 crates/services/src/state.rs1-80
Each service is wrapped in a ServiceRunner which manages its execution and state transitions. The runner provides methods like start(), stop(), and state watching capabilities.
Sources: crates/fuel-core/src/graphql_api/api_service.rs99 crates/fuel-core/src/service/sub_services.rs106-124
The block lifecycle illustrates how transactions flow through the system, from submission to finalization:
Sources: crates/services/executor/src/executor.rs1-300 crates/services/producer/src/block_producer/producer.rs crates/services/importer/src/importer.rs1-200 crates/fuel-core/src/graphql_api/worker_service.rs
| Layer | Components | Primary Responsibility |
|---|---|---|
| External Clients | Fuel SDK, CLI operators, monitoring tools | Application integration, node operation, observability |
| API | GraphQL service at :4000/v1/graphql, health endpoints | HTTP/WebSocket query processing, transaction submission |
| Core Services | FuelService, BlockProducer, BlockImporter, Executor, TxPool, TxStatusManager | Block production, validation, transaction management, pre-confirmations |
| Networking | P2PService (libp2p 0.54), Sync, Gossipsub | Peer discovery, block/tx propagation, network synchronization |
| Data Availability | Relayer, CompressionService | Ethereum L1 bridging, DA cost optimization through compression |
| Economics | GasPriceService (v1 algorithm) | Dynamic gas price calculation based on DA costs |
| Storage | CombinedDatabase, five domain-specific Database<T> instances | Multi-domain persistence with historical state support |
Sources: crates/fuel-core/src/service/sub_services.rs106-455 crates/fuel-core/src/service.rs78-112
The initialization process follows a specific order to satisfy dependencies between services:
Sources: crates/fuel-core/src/service.rs138-195 crates/fuel-core/src/service/sub_services.rs129-600
CombinedDatabase is opened and version-checked at crates/fuel-core/src/service.rs152-159ExecutorAdapter wraps upgradable executor at crates/fuel-core/src/service/sub_services.rs212-218VerifierAdapter and BlockImporterAdapter created at crates/fuel-core/src/service/sub_services.rs222-234PoAService or other consensus modules at crates/fuel-core/src/service/sub_services.rs390-403Sources: crates/fuel-core/src/service/sub_services.rs129-600
Services communicate through SharedState and various adapter patterns:
Sources: crates/fuel-core/src/service.rs78-112 crates/fuel-core/src/service/adapters.rs1-700
The port-adapter pattern decouples service implementations from their consumers:
| Adapter | Source Location | Purpose |
|---|---|---|
BlockImporterAdapter | service/adapters/block_importer.rs | Wraps block importer and broadcasts ImportResult events |
ExecutorAdapter | service/adapters.rs76 | Provides execution capabilities with memory pooling |
TxPoolAdapter | service/adapters.rs400 | Wraps transaction pool shared state |
P2PAdapter | service/adapters.rs500 | Interfaces with P2P network for block/transaction propagation |
PoAAdapter | service/adapters.rs600 | Wraps PoA consensus module |
Sources: crates/fuel-core/src/service/adapters.rs1-700
Configuration flows from CLI arguments through structured configuration types:
Sources: bin/fuel-core/src/cli/run.rs128-800 crates/fuel-core/src/service/config.rs64-240
The main Config struct at crates/fuel-core/src/service/config.rs64-117 aggregates all subsystem configurations:
Sources: crates/fuel-core/src/service/config.rs64-117
The storage layer uses a CombinedDatabase at crates/fuel-core/src/combined_database.rs that aggregates five domain-specific databases, each with transactional and historical capabilities:
Sources: crates/fuel-core/src/combined_database.rs crates/database/src/database_description/ crates/storage/src/transactional.rs crates/fuel-core/src/state/historical_rocksdb.rs
The separation into five domain-specific databases enables independent evolution and optimized access patterns:
| Database | Description | Key Tables | Transactional | Used By |
|---|---|---|---|---|
OnChain | Consensus-critical state, deterministic execution | FuelBlocks, Transactions, Coins, Messages, ContractsRawCode, ContractsState, ConsensusParametersVersions, StateTransitionBytecodeVersions | Yes | Executor, Validator, Producer, Block Importer |
OffChain | Query optimization indexes, derived data | TransactionStatuses, OwnedCoins, OwnedMessageIds, CoinBalances, MessageBalances, CoinsToSpendIndex | Yes | GraphQL API, GraphQL Worker |
Relayer | DA layer event synchronization | EventsHistory, DaMessages, DaTransactions | Yes | Relayer service |
GasPriceDatabase | Gas price algorithm state | GasPriceMetadata, GasPriceRollingWindow | Yes | Gas Price Service v1 |
CompressionDatabase | DA compression temporal registry | TemporalRegistry, Registrations (merkleized) | Yes | DA Compression Service |
The HistoricalRocksDB at crates/fuel-core/src/state/historical_rocksdb.rs wraps the physical storage and maintains ModificationsHistoryV2 for state rewind capabilities with a configurable retention window (default 7 days / 604800 blocks at bin/fuel-core/src/cli/run.rs179).
Sources: crates/database/src/database_description/ crates/fuel-core/src/combined_database.rs crates/fuel-core/src/state/historical_rocksdb.rs bin/fuel-core/src/cli/run.rs169-180
The execution model at crates/services/upgradable-executor/src/executor.rs supports protocol upgrades by routing blocks to either native Rust execution or WASM execution based on the StateTransitionBytecodeVersion in the block header:
Sources: crates/services/upgradable-executor/src/executor.rs142-339 crates/services/executor/src/executor.rs1-300 crates/types/src/blockchain/header.rs70-79
The executor at crates/services/upgradable-executor/src/executor.rs203-267 maintains a version mapping:
This enables execution of blocks from any network upgrade by loading the corresponding WASM module from the StateTransitionBytecodeVersions table at crates/storage/src/tables.rs
Three MemoryPool instances at crates/services/upgradable-executor/src/executor.rs147-155 reuse VM memory allocations:
produce_block_pool: Single instance for block production (mutex-protected)validate_block_pool: Single instance for block validationdry_run_pool: Unlimited instances for concurrent dry runsThe FUEL_ALWAYS_USE_WASM environment variable at crates/services/upgradable-executor/src/executor.rs201 forces WASM execution even for native version blocks, useful for testing forward compatibility.
Sources: crates/services/upgradable-executor/src/executor.rs147-339 crates/types/src/blockchain/header.rs33-47 crates/storage/src/tables.rs
Services depend on abstract ports (traits) rather than concrete implementations:
Sources: crates/fuel-core/src/service/adapters/block_importer.rs crates/services/importer/src/ports.rs
Services expose immutable shared state for coordination:
Sources: crates/fuel-core/src/service.rs78-112
All services implement RunnableTask for uniform lifecycle management:
Sources: crates/services/src/service.rs400-450
The fuel-core architecture is built on three foundational principles:
FuelService coordinates all subsystems through SharedState and adapter patternsThis design enables modular development, testability through dependency injection, and flexibility to swap implementations without affecting dependent services.
Sources: crates/fuel-core/src/service.rs1-341 crates/fuel-core/src/service/sub_services.rs1-600 crates/fuel-core/src/service/config.rs1-240 bin/fuel-core/src/cli/run.rs1-800
Refresh this wiki