# Fuel Core User Guide

## 1. Quick Start

Fuel Core is the official Rust implementation of the Fuel protocol — a high-performance, UTXO-based blockchain execution layer designed for modular blockchain architectures. It runs the FuelVM, a purpose-built virtual machine optimized for parallel transaction execution with a fraud-provable design.

**Key features:**

- UTXO-based transaction model enabling parallel execution
- FuelVM execution environment with native multi-asset support
- GraphQL API for querying blockchain state and submitting transactions
- Peer-to-peer networking via libp2p for block and transaction propagation
- Proof-of-Authority (PoA) consensus with configurable block production triggers
- Ethereum L1 relayer for cross-chain message bridging
- RocksDB-backed persistent storage with historical state access
- WASM-based upgradable executor for forkless protocol upgrades

**Prerequisites:** Rust 1.93.0+, clang/llvm (for RocksDB), and a chain configuration snapshot.

**Fastest way to start a local node:**

```bash
cargo run -p fuel-core-bin -- run --db-type in-memory
```

```text
GraphQL API listening on 127.0.0.1:4000
```

> [!TIP]
> For quick experimentation, use `--db-type in-memory` to skip RocksDB setup entirely. State is lost on restart but startup is instant.

**What to try next:** Query the node health at `http://127.0.0.1:4000/v1/playground` using the built-in GraphiQL interface, or submit a transaction via the `fuel-core-client` crate.

## 2. Installation

### System Requirements

| Requirement | Minimum | Recommended |
|---|---|---|
| Rust toolchain | 1.93.0 | Latest stable |
| OS | Linux, macOS, Windows | Linux (Ubuntu 22.04+) |
| RAM | 4 GB | 16 GB+ (production) |
| Disk | 10 GB | 100 GB+ SSD (production with RocksDB) |
| CPU | 2 cores | 4+ cores |

### Building from Source

```bash
git clone https://github.com/FuelLabs/fuel-core.git
cd fuel-core
cargo build -p fuel-core-bin --release
```

```text
Compiling fuel-core-bin v0.48.0
    Finished release [optimized] target(s)
```

> [!IMPORTANT]
> The default build includes RocksDB support, which requires `clang` and `llvm` development libraries. On Ubuntu: `apt install clang llvm libclang-dev`. On macOS: `xcode-select --install`.

### Production Build

For production deployments, enable jemalloc for improved memory performance:

```bash
cargo build -p fuel-core-bin --release --features rocksdb-production
```

### Feature Flags

| Feature | Description | Default |
|---|---|---|
| `rocksdb` | RocksDB persistent storage | Yes |
| `rocksdb-production` | RocksDB with jemalloc allocator | No |
| `p2p` | Peer-to-peer networking via libp2p | No |
| `relayer` | Ethereum L1 relayer for bridge messages | No |
| `wasm-executor` | WASM upgradable executor | No |
| `rpc` | Block aggregator RPC/gRPC API | No |
| `shared-sequencer` | Shared sequencer integration (Cosmos SDK) | No |

### Post-Install Verification

```bash
./target/release/fuel-core --version
```

```text
fuel-core 0.48.0
```

```bash
./target/release/fuel-core run --db-type in-memory &
curl -s http://127.0.0.1:4000/v1/health
```

```text
true
```

> [!WARNING]
> If building on ARM (aarch64), use the provided cross-compilation Dockerfiles in `ci/Dockerfile.aarch64-unknown-linux-gnu-clang` for reproducible builds.

### Key Generation

Generate cryptographic keys for block production or P2P peering:

```bash
./target/release/fuel-core-keygen new --key-type block-production
```

```json
{
  "secret": "0x...",
  "address": "0x...",
  "type": "block-production"
}
```

```bash
./target/release/fuel-core-keygen new --key-type peering
```

```json
{
  "secret": "0x...",
  "peer_id": "16Uiu2HAm...",
  "type": "p2p"
}
```

> [!CAUTION]
> Store generated secret keys securely. The block production key controls consensus authority. Never commit secrets to version control.

### Derive Address from Existing Secret

```bash
./target/release/fuel-core-keygen parse --key-type block-production --secret 0xYOUR_SECRET_KEY
```

```json
{
  "address": "0x...",
  "type": "block-production"
}
```

## 3. Configuration

Fuel Core uses a chain configuration snapshot for genesis state and consensus parameters. The node is configured primarily through CLI flags.

### Chain Configuration

The chain configuration defines the genesis state and consensus rules. It consists of:

| File | Purpose |
|---|---|
| `chain_config.json` | Chain name, consensus parameters, state transition bytecode, consensus type (PoA/PoAV2) |
| `state_config.json` | Genesis coins, contracts, messages, blobs |
| `metadata.json` | Chain height, DA height metadata |

### Consensus Modes

| Mode | CLI Value | Behavior |
|---|---|---|
| Instant | `instant` | Produce a block as soon as transactions arrive (development) |
| Interval | `interval { block_time }` | Produce blocks at fixed time intervals (production) |
| Never | N/A | Passive listener — does not produce blocks (follower node) |

### Essential CLI Flags

| Flag | Type | Description |
|---|---|---|
| `--db-type` | `rocks-db` \| `in-memory` | Storage backend |
| `--db-path` | Path | RocksDB database directory |
| `--ip` | Address | GraphQL API bind address (default: `127.0.0.1`) |
| `--port` | u16 | GraphQL API port (default: `4000`) |
| `--snapshot` | Path | Path to chain configuration snapshot directory |
| `--utxo-validation` | bool | Enable UTXO existence validation |
| `--debug` | bool | Enable debug endpoints (VM debugger) |

> [!NOTE]
> For full configuration reference including P2P, relayer, gas price, GraphQL tuning, and advanced settings, see the Admin Guide.

### Minimal Local Development Configuration

```bash
fuel-core run \
  --db-type in-memory \
  --debug \
  --snapshot ./path/to/chain-config
```

### Connecting to an Existing Network

To sync with an existing Fuel network, you need the network's chain configuration snapshot and at least one bootstrap peer:

```bash
fuel-core run \
  --db-type rocks-db \
  --db-path /data/fuel-core \
  --snapshot ./chain-config \
  --keypair $P2P_SECRET \
  --reserved-nodes /dns4/bootstrap.fuel.network/tcp/30333/p2p/$PEER_ID
```

> [!TIP]
> Use `--reserved-nodes` to specify bootstrap peers. The node discovers additional peers through the Kademlia DHT once connected.

## 4. Core Usage

### Interacting via GraphQL

Fuel Core exposes a GraphQL API as its primary interface. Access the GraphiQL playground at `http://<host>:<port>/v1/playground`.

#### Check Node Health

```graphql
query {
  health
}
```

```json
{
  "data": {
    "health": true
  }
}
```

#### Query Node Information

```graphql
query {
  nodeInfo {
    utxoValidation
    vmBacktrace
    maxTx
    maxDepth
    nodeVersion
    peers {
      id
      blockHeight
    }
  }
}
```

#### Query Chain Information

```graphql
query {
  chain {
    name
    latestBlock {
      header {
        height
        time
      }
    }
    consensusParameters {
      version
    }
  }
}
```

#### Submit a Transaction

```graphql
mutation {
  submit(tx: "0x...hex-encoded-transaction...") {
    id
  }
}
```

> [!WARNING]
> When `--utxo-validation` is enabled, the node validates that all input UTXOs exist and are unspent before accepting a transaction. Transactions referencing consumed UTXOs are rejected.

#### Query Transaction Status

```graphql
query {
  transaction(id: "0x...tx_id...") {
    status {
      ... on SuccessStatus {
        blockHeight
      }
      ... on FailureStatus {
        reason
      }
      ... on SubmittedStatus {
        time
      }
    }
  }
}
```

#### Subscribe to Transaction Status Changes

```graphql
subscription {
  statusChange(id: "0x...tx_id...") {
    ... on SubmittedStatus { time }
    ... on SuccessStatus { blockHeight }
    ... on FailureStatus { reason }
  }
}
```

> [!NOTE]
> Subscriptions use Server-Sent Events (SSE). The `fuel-core-client` crate handles reconnection automatically when using the `subscriptions` feature.

#### Query Account Balance

```graphql
query {
  balance(owner: "0x...address...", assetId: "0x...asset_id...") {
    amount
  }
}
```

#### List Coins (UTXOs)

```graphql
query {
  coins(filter: { owner: "0x...address..." }, first: 10) {
    nodes {
      utxoId
      amount
      assetId
    }
  }
}
```

### Using the Rust Client

The `fuel-core-client` crate provides a typed Rust client for the GraphQL API:

```rust
use fuel_core_client::client::FuelClient;

let client = FuelClient::new("http://127.0.0.1:4000").unwrap();
let health = client.health().await.unwrap();
assert!(health);
```

The client supports pagination via cursor-based `ConnectionArgs` with `first`/`after` (forward) or `last`/`before` (backward) parameters.

### VM Debugger (Debug Mode)

When running with `--debug`, interactive VM debugging is available via GraphQL mutations:

1. **Start a debug session:**
   ```graphql
   mutation { startSession }
   ```

2. **Load and execute a transaction:**
   ```graphql
   mutation { startTx(id: $sessionId, txJson: "...") { breakpoint jsonReceipts } }
   ```

3. **Set breakpoints on a contract:**
   ```graphql
   mutation { setBreakpoint(id: $sessionId, breakpoint: { contract: "0x...", pc: 10 }) }
   ```

4. **Step through execution:**
   ```graphql
   mutation { setSingleStepping(id: $sessionId, enable: true) }
   mutation { continueTx(id: $sessionId) { breakpoint jsonReceipts } }
   ```

5. **Inspect VM state:**
   ```graphql
   query { register(id: $sessionId, register: 16) }
   query { memory(id: $sessionId, start: 0, size: 256) }
   ```

6. **End session:**
   ```graphql
   mutation { endSession(id: $sessionId) }
   ```

> [!CAUTION]
> Debug mode exposes full VM state inspection. Never enable `--debug` on production nodes — it allows arbitrary transaction execution replay and memory inspection.

## 5. Common Tasks

### Run a Local Development Node

**Goal:** Start a local node for smart contract development.

**Steps:**
1. Build fuel-core with default features
2. Start the node:
   ```bash
   fuel-core run \
     --db-type in-memory \
     --debug \
     --utxo-validation
   ```

**Verify:** Query `http://127.0.0.1:4000/v1/health` returns `true`.

### Run a Persistent Node

**Goal:** Run a node with data that survives restarts.

**Steps:**
1. Create a data directory: `mkdir -p /var/lib/fuel-core/db`
2. Start the node:
   ```bash
   fuel-core run \
     --db-type rocks-db \
     --db-path /var/lib/fuel-core/db \
     --snapshot /etc/fuel-core/chain-config
   ```

**Verify:** Check that `/var/lib/fuel-core/db` contains RocksDB files after the first block.

**If it fails:** Ensure the `--db-path` directory exists and is writable. Check that the chain configuration snapshot at `--snapshot` contains valid `chain_config.json` and `state_config.json`.

### Query Gas Price

**Goal:** Get the current gas price for transaction fee estimation.

```graphql
query {
  latestGasPrice {
    gasPrice
    blockHeight
  }
}
```

To estimate gas price at a future block:

```graphql
query {
  estimateGasPrice(blockHorizon: 10) {
    gasPrice
  }
}
```

### Dry-Run a Transaction

**Goal:** Simulate a transaction without committing it to the chain.

```graphql
mutation {
  dryRun(tx: "0x...hex-encoded-tx...", utxoValidation: true) {
    ... on SuccessStatus {
      totalGas
      totalFee
    }
    receipts {
      receiptType
      data
    }
  }
}
```

> [!TIP]
> Use dry-run to estimate gas costs before submitting. The `utxoValidation` parameter can be set independently of the node's global `--utxo-validation` flag.

### Query Block Details

```graphql
query {
  block(height: "100") {
    header {
      height
      time
      daHeight
      transactionsCount
    }
    transactions {
      id
    }
  }
}
```

### Query Cross-Chain Messages

```graphql
query {
  messages(owner: "0x...address...", first: 10) {
    nodes {
      sender
      recipient
      amount
      data
      daHeight
    }
  }
}
```

### Query Contract State

```graphql
query {
  contract(id: "0x...contract_id...") {
    bytecode
    salt
  }
}
```

### Query DA Compressed Blocks

When the compression service is active, retrieve DA-compressed block data:

```graphql
query {
  daCompressedBlock(height: "100") {
    bytes
  }
}
```

### Run Benchmarks

**Goal:** Generate gas cost data for the FuelVM.

**Steps:**
1. Run benchmarks:
   ```bash
   cargo bench -p fuel-core-benches
   ```
2. Collect gas cost output:
   ```bash
   cargo criterion -p fuel-core-benches --message-format json --bench vm > bench.json
   cargo run -p fuel-core-benches --bin collect --release -- --input bench.json
   ```

```text
Generated gas-costs.yaml
```

> [!NOTE]
> Benchmarks require the `rocksdb` and `rocksdb-production` features enabled (default). See `benches/README.md` for profiling with flamegraphs.

## 6. Troubleshooting

### Diagnostic Decision Tree

```text
Node won't start?
├── Missing chain config? → Provide --snapshot path
├── RocksDB error? → Check --db-path permissions and disk space
├── Port in use? → Change --port or stop conflicting process
└── Version mismatch? → Ensure chain config matches fuel-core version

Transactions rejected?
├── UTXO not found? → UTXO was already spent or doesn't exist
├── Gas too low? → Query latestGasPrice and increase max_fee
├── Blacklisted? → Input address/UTXO/contract is blacklisted in txpool
├── Pool full? → Pool limits reached; retry with higher tip
└── Mint disallowed? → Only coinbase transactions can use Mint type

Node not syncing?
├── No peers? → Check --reserved-nodes and P2P port accessibility
├── Wrong chain? → Ensure chain config checksum matches network
└── Relayer behind? → Wait for Ethereum finality (~13 min)
```

### Error: `Failed to create FuelClient. No URL is provided.`

**Cause:** The `FuelClient` was constructed without specifying a URL.

**Solution:**
```rust
let client = FuelClient::new("http://127.0.0.1:4000").unwrap();
```

**Prevention:** Always pass the GraphQL endpoint URL when constructing `FuelClient`.

### Error: `unable to produce blocks without a consensus key`

**Cause:** The node is configured for block production (instant or interval trigger) but no signing key was provided.

**Solution:**
1. Generate a key: `fuel-core-keygen new --key-type block-production`
2. Pass it via the `--consensus-key` CLI flag

**Prevention:** Always configure a consensus key when using block production triggers.

### Error: `Block production timed out`

**Cause:** Block production exceeded the configured timeout, typically due to slow transaction execution or database I/O.

**Solution:**
1. Check disk I/O performance
2. Reduce the number of transactions per block
3. Verify the gas limit is not set excessively high

### Error: `Maximum number of subscriptions reached`

**Cause:** The transaction status manager has reached its subscription limit.

**Solution:**
1. Close unused subscriptions
2. Increase the subscription limit in node configuration

**Prevention:** Clean up subscription handles in client code after receiving terminal status updates (Success or Failure).

### Error: `Database doesn't have a height to rollback`

**Cause:** Attempted to roll back the database to a height that doesn't exist in the history.

**Solution:**
1. Check the current database height via GraphQL
2. Only roll back to heights within the available history window

### Error: `InvalidDatabaseVersion { expected, found }`

**Cause:** The database was created with an incompatible version of fuel-core.

**Solution:**
1. Back up the existing database
2. Re-sync from genesis with the correct fuel-core version

**Prevention:** Always use matching fuel-core versions with existing databases. Protocol upgrades use the WASM executor for forkless transitions.

> [!WARNING]
> Database version mismatches cannot be resolved by simply upgrading the binary. A re-sync from the chain configuration snapshot is required.

### Error: `The block timestamp should monotonically increase`

**Cause:** Attempted to produce a block with a timestamp earlier than or equal to the previous block.

**Solution:** Ensure system clock is synchronized and not drifting backward. Use NTP on production nodes.

**Prevention:** Run `ntpd` or `chronyd` to keep system time accurate.

### P2P Connection Issues

**Cause:** Node cannot connect to peers.

**Solution:**
1. Ensure the P2P port is accessible (not firewalled)
2. Verify `--keypair` is set with a valid P2P secret key
3. Check that `--reserved-nodes` contains valid multiaddr strings
4. Verify the chain config checksum matches the network

**Prevention:** Use DNS-based multiaddrs for bootstrap nodes to handle IP changes.

> [!TIP]
> Enable `RUST_LOG=fuel_core_p2p=debug` to see detailed P2P connection diagnostics.

### Error: `Failed to acquire the production lock, block production is already in progress`

**Cause:** A new block production request was made while another is still executing.

**Solution:** Wait for the current block production to complete. This is normal under high load.

**Prevention:** This is a concurrency guard — the system handles it automatically.

## 7. FAQ

**Q: What database backends does fuel-core support?**

Fuel Core supports two backends: **RocksDB** (persistent, production-ready) and **in-memory** (ephemeral, for development/testing). Use `--db-type rocks-db` or `--db-type in-memory` to select.

**Q: What is the difference between PoA and PoAV2 consensus?**

PoA (V1) uses a single signing key for block production. PoAV2 extends this with height-based consensus parameter overrides, enabling protocol parameter changes at specific block heights without code changes.

**Q: How does the WASM executor enable forkless upgrades?**

The upgradable executor can load state transition logic from WASM bytecode stored on-chain. When an `Upgrade` transaction is included, nodes automatically switch to executing the new WASM bytecode — no binary update or hard fork required. The WASM executor is designed for one block execution per instance.

**Q: What is the Ethereum relayer?**

The relayer monitors the Fuel bridge contract on Ethereum (`FuelMessagePortal`), downloading finalized log events. It tracks `MessageSent` and `Transaction` events. Messages and relayed transactions become available to the Fuel chain after Ethereum finality (~13 minutes / ~100 blocks). The relayer uses a configurable `log_page_size` (default 10,000) for batch fetching.

**Q: How is gas pricing determined?**

Fuel Core supports both static and dynamic gas pricing. The static algorithm returns a fixed price. The dynamic algorithm (v1) uses a cumulative percentage-based model that adjusts based on L2 block utilization and DA layer recording costs. Query current prices via the `latestGasPrice` GraphQL endpoint.

**Q: Can I run a node without P2P?**

Yes. P2P is an optional feature flag. Without it, the node operates standalone — useful for local development, testing, and single-validator setups.

**Q: What transaction types are supported?**

Fuel Core supports six transaction types: `Script` (execute code), `Create` (deploy contracts), `Mint` (coinbase/block reward), `Upgrade` (protocol upgrades), `Upload` (upload bytecode chunks), and `Blob` (store arbitrary data).

**Q: How do I monitor node health in production?**

Query the `/v1/health` HTTP endpoint or use the GraphQL `health` query. Fuel-core exposes Prometheus-compatible metrics via the `fuel-core-metrics` subsystem covering GraphQL query costs, P2P peer counts, txpool sizes, block import times, gas price updates, and PoA block production timing.

**Q: What is the block aggregator API?**

The block aggregator API (enabled with `--features rpc`) provides a gRPC/protobuf interface for efficient block data retrieval, with support for S3-backed remote caching and compressed block storage for DA layer submission.

**Q: What is the shared sequencer?**

The shared sequencer service (enabled with `--features shared-sequencer`) integrates with a Cosmos SDK-based shared sequencer chain via Tendermint RPC, enabling cross-rollup ordering of transactions.

**Q: How does the transaction pool work?**

The txpool (v2) manages pending transactions with configurable limits on count, total gas, and byte size. It supports dependency chain tracking via `petgraph`, collision detection, TTL-based expiration, and a blacklist system for addresses, UTXOs, message nonces, and contract IDs. Transactions are selected using a ratio-based tip/gas algorithm.

---

_Generated May 2026 from FuelLabs/fuel-core at c453f81. AI-generated documentation. The library is checked by sampling (three repositories so far); this guide was not individually reviewed. Verify against the project before relying on it. Unofficial; not affiliated with or reviewed by the project._
