forest-filecoin 0.32.1

Rust Filecoin implementation.
Documentation
# AGENTS.md

This file provides guidance to AI coding assistants (such as Claude Code, Cursor, Copilot, etc.) when working with code in this repository.

## Project Overview

Forest is a Rust implementation of a Filecoin node that can transfer FIL, host a high-performance RPC API, validate the Filecoin blockchain, and generate blockchain snapshots. It aims to be faster and easier-to-use than the canonical Filecoin node (Lotus).

## Development Commands

### Building and Installing

```bash
# Install Forest binaries with release profile (recommended)
mise run install

# Install with different profiles
mise run install quick          # Faster build, less optimization
mise run install release-lto-fat # Maximum optimization (slower build)
mise run install dev            # Debug build

# Install slim version (minimal features)
mise run install --slim

# Build without installing
cargo build --release
cargo build --profile quick  # Faster compile time

# Run binaries directly (for development)
cargo daemon --chain calibnet  # Alias for: cargo run --bin forest --
cargo cli info show            # Alias for: cargo run --bin forest-cli --
cargo forest-tool --help       # Alias for: cargo run --bin forest-tool --release --
```

### Testing

```bash
# Run all tests (requires cargo-nextest: cargo install cargo-nextest --locked)
mise test           # Uses 'quick' profile by default
mise test release   # Run with release profile
mise test dev       # Run with dev profile

# Run only Rust tests (no doctests)
mise test:rust
mise test:rust release

# Run only doctests
mise test:docs
mise test:docs release

# Run specific test
cargo nextest run --cargo-profile quick <test_name>

# Run tests in a specific file/module
cargo nextest run --cargo-profile quick state_manager::

# Run single test with full output
cargo nextest run --cargo-profile quick --no-capture <test_name>

# Run doctests for private items
cargo test --doc --profile quick --features doctest-private
```

### Linting and Formatting

```bash
# Install all linting tools
mise install-lint-tools

# Run all linters
mise lint

# Run specific linters
mise lint:rust-fmt    # Rust formatting check
mise lint:clippy      # Rust linter
mise lint:toml        # TOML formatting/linting
mise lint:spellcheck  # Spell checking
mise lint:deny        # Check licenses and security
mise lint:unused-deps # Check for unused dependencies
mise lint:dockerfile  # Lint Dockerfiles
mise lint:shellcheck  # Lint shell scripts
mise lint:golang      # Lint Go code (F3 sidecar)

# Format code
mise fmt              # Format Rust, TOML, markdown, YAML

# Check specific issues
cargo fmt --all -- --check
cargo clippy --all-targets --no-deps -- --deny=warnings
taplo fmt --check && taplo lint
```

### Code Coverage

```bash
# Generate coverage report (requires cargo-llvm-cov: cargo install cargo-llvm-cov)
mise codecov
```

### Cleaning

```bash
# Clean all build artifacts and dependencies
mise clean
```

## High-Level Architecture

### Core Modules

- **`daemon/`** - Node startup, initialization, and service orchestration
- **`chain/`** - Blockchain storage (`ChainStore`) and index management
- **`chain_sync/`** - Chain synchronization, consensus (`ChainFollower`, `ChainMuxer`)
- **`state_manager/`** - State tree management and FVM execution coordinator
- **`rpc/`** - JSON-RPC API server with authentication and filtering middleware
- **`libp2p/`** - P2P networking (peer discovery, chain exchange, gossipsub)
- **`message_pool/`** - Transaction pool for pending messages
- **`db/`** - Database abstraction layer (ParityDb, MemoryDB, CAR format)
- **`interpreter/`** - Filecoin Virtual Machine (FVM) integration (multi-version)
- **`blocks/`** - Block and tipset structures
- **`shim/`** - Filecoin protocol primitives (actors, crypto, addresses, state tree)
- **`eth/`** - Ethereum compatibility layer (EVM transactions, address mapping)
- **`wallet/`** - Key management and transaction signing
- **`networks/`** - Network configurations (mainnet, calibnet, devnet)

### Key Architectural Patterns

**Blockstore Pattern**: Generic database trait (`fvm_ipld_blockstore::Blockstore`) allows swapping storage implementations. Most core structures are generic over `DB: Blockstore`:

```rust
pub struct StateManager<DB> where DB: Blockstore { ... }
pub struct ChainStore<DB> where DB: Blockstore { ... }
```

**Publisher/Subscriber**: `HeadChange` events (new tipsets, reorg reverts) are broadcast via `Publisher` to multiple subscribers (RPC, message pool, chain indexer).

**State Management**: `StateManager` is the central coordinator for state transitions, actor queries, and FVM execution. It caches state roots and receipts in `TipsetStateCache`.

**Multi-version FVM**: Supports FVM2, FVM3, and FVM4 for different network versions. Stack size management with `stacker::grow()` is required for WASM execution.

### Daemon Startup Flow

1. `startup_init()` - Increase file descriptor limits, initialize proof cache
2. `AppContext::init()` - Initialize database, state manager, keystore, JWT
3. `create_p2p_service()` - Start libp2p networking stack
4. `create_mpool()` - Initialize message pool
5. `create_chain_follower()` - Start chain synchronization
6. `maybe_start_rpc_service()` - Start JSON-RPC server
7. `maybe_start_metrics_service()` - Start Prometheus metrics endpoint
8. `maybe_start_health_check_service()` - Start health check service
9. `maybe_start_f3_service()` - Start F3 sidecar (Fast Finality, optional)

### Chain Synchronization

**ChainFollower** orchestrates synchronization:

- Receives tipsets from network peers
- Validates blocks via `TipsetSyncer` and `TipsetValidator`
- Resolves forks via `ChainMuxer` (heaviest chain wins)
- Updates chain head through `StateManager`
- Maintains `BadBlockCache` for invalid blocks
- Reports `SyncStatus` to RPC clients

### RPC Server Architecture

Multi-layer middleware stack:

```
Request → AuthLayer → FilterLayer → SegregationLayer →
SetExtensionLayer → LogLayer → MetricsLayer → RpcHandler
```

Major RPC namespaces: `auth::`, `chain::`, `state::`, `mpool::`, `eth::`, `net::`, `sync::`, `wallet::`

### FVM Integration

**Version Selection**: Network version determines FVM version (FVM2 for v1-v15, FVM3 for v16-v20, FVM4 for v21+)

**VM Execution Flow**:

```
StateManager::call_with_gas()
  → VM::new(ExecutionContext)
  → vm.apply_message() / apply_implicit_message()
  → VM::flush() → new_state_root
```

**Key Concepts**:

- **State Tree** - IPLD-based Merkle tree of actor states
- **Actors** - Smart contracts (System, Init, Power, Market, Miner, etc.)
- **Messages** - Transactions that execute actor methods
- **Receipts** - Execution results (gas used, exit code, return value)
- **Randomness** - Provided by Drand beacon (via `ChainRand`)
- **State Migrations** - Automatic upgrades at network version boundaries

### P2P Networking

Libp2p protocols:

- **Chain Exchange** - Fetch blocks and messages during sync
- **Hello** - Exchange peer info and genesis CID
- **Gossipsub** - Broadcast new blocks and messages
- **Bitswap** - IPLD block exchange (legacy)
- **Kademlia DHT** - Peer discovery
- **mDNS** - Local network discovery

**Peer Manager** tracks peer quality, manages connections, and scores peers based on message validity.

### Database Organization

Storage layers:

```
Application (StateManager, ChainStore)
  ↓
IPLD Blockstore (LogicalDB)
  ↓
Write Buffer / Read Cache (optional)
  ↓
ParityDb (embedded KV store)
```

Special stores:

- **Settings Store** - Configuration persistence (chain head, message pool config)
- **Eth Mappings Store** - ETH ↔ Filecoin address mappings
- **Indices Store** - Message and event indices
- **CAR DB** - Snapshot import/export (v1, v2 with F3 data)

### Ethereum Compatibility

Supports legacy transactions, EIP-155, and EIP-1559. Provides standard Ethereum RPC methods (`eth_call`, `eth_sendTransaction`, `eth_getTransactionReceipt`, `eth_subscribe`, etc.)

**Address Mapping**: EVM addresses map to Filecoin f4 (delegated) addresses. Precompiles provide Filecoin-specific operations.

## Project-Specific Patterns

### Error Handling

Use `anyhow::Result<T>` for most operations. Add context with `.context()`:

```rust
some_operation().context("Failed to execute VM")?
```

### Async/Await

- Tokio runtime for async execution
- Use `tokio::task::spawn_blocking` for CPU-intensive work (VM execution, cryptography)
- Channel-based communication between tasks (flume, tokio channels)

### Module Organization

Each module has:

- `mod.rs` - Public API exports
- Private submodules for implementation details
- Clear trait boundaries for extensibility

### Code Style

- **No indexing** - Use `.get()` instead of `[index]` (enforced by clippy)
- **No unwrap in production** - Use `?` or `expect()` with descriptive messages
- **No dbg! or todo!** - Enforced in non-test code
- Use `strum` for enum string conversions
- Use `derive_more` for common trait implementations

### Testing Utilities

- `test_utils/` provides fixtures and helpers
- Use `#[cfg(test)]` or `#[cfg(feature = "doctest-private")]` for test-only code
- Serial tests (database tests) use `#[serial_test::serial]`

### Network-Specific Configuration

Networks defined in `networks/`:

- **mainnet** - Production Filecoin network
- **calibnet** - Public testnet (recommended for development)
- **devnet** - Lightweight local network
- **butterflynet** - Alternative testnet

Each network has its own genesis, bootstrap peers, actor bundles, and upgrade epochs.

## Common Development Workflows

### Running a Local Node

```bash
# Mainnet (requires snapshot download)
forest

# Calibnet (testnet, auto-download snapshot)
forest --chain calibnet --auto-download-snapshot

# Using Docker
docker run --init -it --rm ghcr.io/chainsafe/forest:latest --chain calibnet --auto-download-snapshot
```

### Using the CLI

```bash
# Set admin token for privileged operations
export FULLNODE_API_INFO="<token>:/ip4/127.0.0.1/tcp/2345/http"

# Or use --token flag
forest-cli --token <ADMIN_TOKEN> info show

# Common commands
forest-cli info show           # Node status
forest-cli chain head          # Current chain head
forest-cli sync status         # Sync progress
forest-cli net peers           # Connected peers
forest-cli wallet list         # List wallets
forest-cli mpool pending       # Pending messages
```

### Working with Snapshots

```bash
# Fetch snapshot
forest-tool snapshot fetch --chain calibnet

# Export snapshot
forest-tool snapshot export --output snapshot.car

# Import snapshot
forest --import-snapshot snapshot.car
```

### Debugging

```bash
# Enable debug logging
RUST_LOG=debug forest --chain calibnet

# Filter specific modules
RUST_LOG="debug,forest_libp2p::service=info" forest

# Use tokio-console (requires tokio-console feature)
tokio-console  # In separate terminal
forest         # With RUSTFLAGS="--cfg tokio_unstable"

# Profile with debugging symbols
FOREST_F3_SIDECAR_FFI_BUILD_OPT_OUT=1 cargo build --profile debugging
lldb target/debugging/forest
```

## Important Environment Variables

- `FOREST_KEYSTORE_PHRASE` - Passphrase for encrypted keystore (headless mode)
- `FOREST_CONFIG_PATH` - Path to config file (overrides default locations)
- `RUST_LOG` - Logging configuration (e.g., `debug`, `forest=trace`)
- `FULLNODE_API_INFO` - RPC endpoint and authentication token
- `FOREST_F3_SIDECAR_FFI_BUILD_OPT_OUT` - Disable F3 sidecar build (for debugging profile)

## Cargo Features

- **`default`** - `jemalloc`, `tokio-console`, `tracing-loki`, `tracing-chrome`
- **`test`** - Default feature set for unit tests
- **`slim`** - Minimal feature set (uses rustalloc)
- **`jemalloc`** - Use jemalloc allocator (production default)
- **`rustalloc`** - Use Rust standard allocator
- **`system-alloc`** - Use system allocator (for memory profiling)
- **`tokio-console`** - Enable tokio-console integration
- **`tracing-loki`** - Send telemetry to Loki
- **`tracing-chrome`** - Chrome tracing support
- **`no-f3-sidecar`** - Disable F3 sidecar build
- **`cargo-test`** - Group of tests that is recommended to run with `cargo test` instead of `nextest`
- **`doctest-private`** - Enable doctests for private items
- **`benchmark-private`** - Enable benchmark suite
- **`interop-tests-private`** - Enable interop tests

## Build Profiles

- **`dev`** - Fast compile, line-table-only debug info, opt-level=1 for deps
- **`quick`** - Inherits from release, opt-level=1, no LTO (good for testing)
- **`release`** - Optimized, stripped, thin LTO, panic=abort
- **`release-lto-fat`** - Maximum optimization with fat LTO
- **`debugging`** - Full debug info (requires `FOREST_F3_SIDECAR_FFI_BUILD_OPT_OUT=1`)
- **`profiling`** - For profiling tools

## Key Dependencies

- **Rust**: Version specified in `rust-toolchain.toml`
- **Go**: Version specified in `go.work` (required for F3 sidecar)
- **OS packages**: `build-essential` (Ubuntu), `clang`, `clang-devel` (Fedora)
- **mise-en-place**: Task runner and tool installer (`mise.jdx.dev`)

## Contributing Guidelines

From CONTRIBUTING.md:

- Use conventional commits (e.g., `feat: add Filecoin.RuleTheWorld RPC method`)
- Run linters before submitting: `mise lint`
- Format code: `mise fmt`
- Ensure tests pass: `mise test`
- Fill PR template exhaustively
- First-time contributors sign CLA when opening PR
- Document public functions and structs (see [Documentation practices]https://github.com/ChainSafe/forest/wiki/Documentation-practices)