Skip to content

Commit 949273c

Browse files
committed
chore: add CLAUDE.md guidance file
1 parent 111c24b commit 949273c

File tree

2 files changed

+400
-0
lines changed

2 files changed

+400
-0
lines changed

AGENTS.md

Lines changed: 399 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,399 @@
1+
# CLAUDE.md
2+
3+
This file provides guidance to AI coding assistants (such as Claude Code, Cursor, Copilot, etc.) when working with code in this repository.
4+
5+
## Project Overview
6+
7+
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).
8+
9+
## Development Commands
10+
11+
### Building and Installing
12+
13+
```bash
14+
# Install Forest binaries with release profile (recommended)
15+
mise install
16+
17+
# Install with different profiles
18+
mise install quick # Faster build, less optimization
19+
mise install release-lto-fat # Maximum optimization (slower build)
20+
mise install dev # Debug build
21+
22+
# Install slim version (minimal features)
23+
mise install --slim
24+
25+
# Build without installing
26+
cargo build --release
27+
cargo build --profile quick # Faster compile time
28+
29+
# Run binaries directly (for development)
30+
cargo daemon --chain calibnet # Alias for: cargo run --bin forest --
31+
cargo cli info show # Alias for: cargo run --bin forest-cli --
32+
cargo forest-tool --help # Alias for: cargo run --bin forest-tool --release --
33+
```
34+
35+
### Testing
36+
37+
```bash
38+
# Run all tests (requires cargo-nextest: cargo install cargo-nextest --locked)
39+
mise test # Uses 'quick' profile by default
40+
mise test release # Run with release profile
41+
mise test dev # Run with dev profile
42+
43+
# Run only Rust tests (no doctests)
44+
mise test:rust
45+
mise test:rust release
46+
47+
# Run only doctests
48+
mise test:docs
49+
mise test:docs release
50+
51+
# Run specific test
52+
cargo nextest run --cargo-profile quick <test_name>
53+
54+
# Run tests in a specific file/module
55+
cargo nextest run --cargo-profile quick state_manager::
56+
57+
# Run single test with full output
58+
cargo nextest run --cargo-profile quick --no-capture <test_name>
59+
60+
# Run doctests for private items
61+
cargo test --doc --profile quick --features doctest-private
62+
```
63+
64+
### Linting and Formatting
65+
66+
```bash
67+
# Install all linting tools
68+
mise install-lint-tools
69+
70+
# Run all linters
71+
mise lint
72+
73+
# Run specific linters
74+
mise lint:rust-fmt # Rust formatting check
75+
mise lint:clippy # Rust linter
76+
mise lint:toml # TOML formatting/linting
77+
mise lint:spellcheck # Spell checking
78+
mise lint:deny # Check licenses and security
79+
mise lint:unused-deps # Check for unused dependencies
80+
mise lint:dockerfile # Lint Dockerfiles
81+
mise lint:shellcheck # Lint shell scripts
82+
mise lint:golang # Lint Go code (F3 sidecar)
83+
84+
# Format code
85+
mise fmt # Format Rust, TOML, markdown, YAML
86+
87+
# Check specific issues
88+
cargo fmt --all -- --check
89+
cargo clippy --all-targets --no-deps -- --deny=warnings
90+
taplo fmt --check && taplo lint
91+
```
92+
93+
### Code Coverage
94+
95+
```bash
96+
# Generate coverage report (requires cargo-llvm-cov: cargo install cargo-llvm-cov)
97+
mise codecov
98+
```
99+
100+
### Cleaning
101+
102+
```bash
103+
# Clean all build artifacts and dependencies
104+
mise clean
105+
```
106+
107+
## High-Level Architecture
108+
109+
### Core Modules
110+
111+
- **`daemon/`** - Node startup, initialization, and service orchestration
112+
- **`chain/`** - Blockchain storage (`ChainStore`) and index management
113+
- **`chain_sync/`** - Chain synchronization, consensus (`ChainFollower`, `ChainMuxer`)
114+
- **`state_manager/`** - State tree management and FVM execution coordinator
115+
- **`rpc/`** - JSON-RPC API server with authentication and filtering middleware
116+
- **`libp2p/`** - P2P networking (peer discovery, chain exchange, gossipsub)
117+
- **`message_pool/`** - Transaction pool for pending messages
118+
- **`db/`** - Database abstraction layer (ParityDb, MemoryDB, CAR format)
119+
- **`interpreter/`** - Filecoin Virtual Machine (FVM) integration (multi-version)
120+
- **`blocks/`** - Block and tipset structures
121+
- **`shim/`** - Filecoin protocol primitives (actors, crypto, addresses, state tree)
122+
- **`eth/`** - Ethereum compatibility layer (EVM transactions, address mapping)
123+
- **`wallet/`** - Key management and transaction signing
124+
- **`networks/`** - Network configurations (mainnet, calibnet, devnet)
125+
126+
### Key Architectural Patterns
127+
128+
**Blockstore Pattern**: Generic database trait (`fvm_ipld_blockstore::Blockstore`) allows swapping storage implementations. Most core structures are generic over `DB: Blockstore`:
129+
130+
```rust
131+
pub struct StateManager<DB> where DB: Blockstore { ... }
132+
pub struct ChainStore<DB> where DB: Blockstore { ... }
133+
```
134+
135+
**Publisher/Subscriber**: `HeadChange` events (new tipsets, reorg reverts) are broadcast via `Publisher` to multiple subscribers (RPC, message pool, chain indexer).
136+
137+
**State Management**: `StateManager` is the central coordinator for state transitions, actor queries, and FVM execution. It caches state roots and receipts in `TipsetStateCache`.
138+
139+
**Multi-version FVM**: Supports FVM2, FVM3, and FVM4 for different network versions. Stack size management with `stacker::grow()` is required for WASM execution.
140+
141+
### Daemon Startup Flow
142+
143+
1. `startup_init()` - Increase file descriptor limits, initialize proof cache
144+
2. `AppContext::init()` - Initialize database, state manager, keystore, JWT
145+
3. `create_p2p_service()` - Start libp2p networking stack
146+
4. `create_mpool()` - Initialize message pool
147+
5. `create_chain_follower()` - Start chain synchronization
148+
6. `maybe_start_rpc_service()` - Start JSON-RPC server
149+
7. `maybe_start_metrics_service()` - Start Prometheus metrics endpoint
150+
8. `maybe_start_health_check_service()` - Start health check service
151+
9. `maybe_start_f3_service()` - Start F3 sidecar (Fast Finality, optional)
152+
153+
### Chain Synchronization
154+
155+
**ChainFollower** orchestrates synchronization:
156+
157+
- Receives tipsets from network peers
158+
- Validates blocks via `TipsetSyncer` and `TipsetValidator`
159+
- Resolves forks via `ChainMuxer` (heaviest chain wins)
160+
- Updates chain head through `StateManager`
161+
- Maintains `BadBlockCache` for invalid blocks
162+
- Reports `SyncStatus` to RPC clients
163+
164+
### RPC Server Architecture
165+
166+
Multi-layer middleware stack:
167+
168+
```
169+
Request → AuthLayer → FilterLayer → SegregationLayer →
170+
SetExtensionLayer → LogLayer → MetricsLayer → RpcHandler
171+
```
172+
173+
Major RPC namespaces: `auth::`, `chain::`, `state::`, `mpool::`, `eth::`, `net::`, `sync::`, `wallet::`
174+
175+
### FVM Integration
176+
177+
**Version Selection**: Network version determines FVM version (FVM2 for v1-v15, FVM3 for v16-v20, FVM4 for v21+)
178+
179+
**VM Execution Flow**:
180+
181+
```
182+
StateManager::call_with_gas()
183+
→ VM::new(ExecutionContext)
184+
→ vm.apply_message() / apply_implicit_message()
185+
→ VM::flush() → new_state_root
186+
```
187+
188+
**Key Concepts**:
189+
190+
- **State Tree** - IPLD-based Merkle tree of actor states
191+
- **Actors** - Smart contracts (System, Init, Power, Market, Miner, etc.)
192+
- **Messages** - Transactions that execute actor methods
193+
- **Receipts** - Execution results (gas used, exit code, return value)
194+
- **Randomness** - Provided by Drand beacon (via `ChainRand`)
195+
- **State Migrations** - Automatic upgrades at network version boundaries
196+
197+
### P2P Networking
198+
199+
Libp2p protocols:
200+
201+
- **Chain Exchange** - Fetch blocks and messages during sync
202+
- **Hello** - Exchange peer info and genesis CID
203+
- **Gossipsub** - Broadcast new blocks and messages
204+
- **Bitswap** - IPLD block exchange (legacy)
205+
- **Kademlia DHT** - Peer discovery
206+
- **mDNS** - Local network discovery
207+
208+
**Peer Manager** tracks peer quality, manages connections, and scores peers based on message validity.
209+
210+
### Database Organization
211+
212+
Storage layers:
213+
214+
```
215+
Application (StateManager, ChainStore)
216+
217+
IPLD Blockstore (LogicalDB)
218+
219+
Write Buffer / Read Cache (optional)
220+
221+
ParityDb (embedded KV store)
222+
```
223+
224+
Special stores:
225+
226+
- **Settings Store** - Configuration persistence (chain head, message pool config)
227+
- **Eth Mappings Store** - ETH ↔ Filecoin address mappings
228+
- **Indices Store** - Message and event indices
229+
- **CAR DB** - Snapshot import/export (v1, v2 with F3 data)
230+
231+
### Ethereum Compatibility
232+
233+
Supports legacy transactions, EIP-155, and EIP-1559. Provides standard Ethereum RPC methods (`eth_call`, `eth_sendTransaction`, `eth_getTransactionReceipt`, `eth_subscribe`, etc.)
234+
235+
**Address Mapping**: EVM addresses map to Filecoin f4 (delegated) addresses. Precompiles provide Filecoin-specific operations.
236+
237+
## Project-Specific Patterns
238+
239+
### Error Handling
240+
241+
Use `anyhow::Result<T>` for most operations. Add context with `.context()`:
242+
243+
```rust
244+
some_operation().context("Failed to execute VM")?
245+
```
246+
247+
### Async/Await
248+
249+
- Tokio runtime for async execution
250+
- Use `tokio::task::spawn_blocking` for CPU-intensive work (VM execution, cryptography)
251+
- Channel-based communication between tasks (flume, tokio channels)
252+
253+
### Module Organization
254+
255+
Each module has:
256+
257+
- `mod.rs` - Public API exports
258+
- Private submodules for implementation details
259+
- Clear trait boundaries for extensibility
260+
261+
### Code Style
262+
263+
- **No indexing** - Use `.get()` instead of `[index]` (enforced by clippy)
264+
- **No unwrap in production** - Use `?` or `expect()` with descriptive messages
265+
- **No dbg! or todo!** - Enforced in non-test code
266+
- Use `strum` for enum string conversions
267+
- Use `derive_more` for common trait implementations
268+
269+
### Testing Utilities
270+
271+
- `test_utils/` provides fixtures and helpers
272+
- Use `#[cfg(test)]` or `#[cfg(feature = "doctest-private")]` for test-only code
273+
- Serial tests (database tests) use `#[serial_test::serial]`
274+
275+
### Network-Specific Configuration
276+
277+
Networks defined in `networks/`:
278+
279+
- **mainnet** - Production Filecoin network
280+
- **calibnet** - Public testnet (recommended for development)
281+
- **devnet** - Lightweight local network
282+
- **butterflynet** - Alternative testnet
283+
284+
Each network has its own genesis, bootstrap peers, actor bundles, and upgrade epochs.
285+
286+
## Common Development Workflows
287+
288+
### Running a Local Node
289+
290+
```bash
291+
# Mainnet (requires snapshot download)
292+
forest --encrypt-keystore false
293+
294+
# Calibnet (testnet, auto-download snapshot)
295+
forest --chain calibnet --auto-download-snapshot --encrypt-keystore false
296+
297+
# Using Docker
298+
docker run --init -it --rm ghcr.io/chainsafe/forest:latest --chain calibnet --auto-download-snapshot
299+
```
300+
301+
### Using the CLI
302+
303+
```bash
304+
# Set admin token for privileged operations
305+
export FULLNODE_API_INFO="<token>:/ip4/127.0.0.1/tcp/2345/http"
306+
307+
# Or use --token flag
308+
forest-cli --token <ADMIN_TOKEN> info show
309+
310+
# Common commands
311+
forest-cli info show # Node status
312+
forest-cli chain head # Current chain head
313+
forest-cli sync status # Sync progress
314+
forest-cli net peers # Connected peers
315+
forest-cli wallet list # List wallets
316+
forest-cli mpool pending # Pending messages
317+
```
318+
319+
### Working with Snapshots
320+
321+
```bash
322+
# Fetch snapshot
323+
forest-tool snapshot fetch --chain calibnet
324+
325+
# Export snapshot
326+
forest-tool snapshot export --output snapshot.car
327+
328+
# Import snapshot
329+
forest --import-snapshot snapshot.car --encrypt-keystore false
330+
```
331+
332+
### Debugging
333+
334+
```bash
335+
# Enable debug logging
336+
RUST_LOG=debug forest --chain calibnet
337+
338+
# Filter specific modules
339+
RUST_LOG="debug,forest_libp2p::service=info" forest
340+
341+
# Use tokio-console (requires tokio-console feature)
342+
tokio-console # In separate terminal
343+
forest # With RUSTFLAGS="--cfg tokio_unstable"
344+
345+
# Profile with debugging symbols
346+
FOREST_F3_SIDECAR_FFI_BUILD_OPT_OUT=1 cargo build --profile debugging
347+
lldb target/debugging/forest
348+
```
349+
350+
## Important Environment Variables
351+
352+
- `FOREST_KEYSTORE_PHRASE` - Passphrase for encrypted keystore (headless mode)
353+
- `FOREST_CONFIG_PATH` - Path to config file (overrides default locations)
354+
- `RUST_LOG` - Logging configuration (e.g., `debug`, `forest=trace`)
355+
- `FULLNODE_API_INFO` - RPC endpoint and authentication token
356+
- `FOREST_F3_SIDECAR_FFI_BUILD_OPT_OUT` - Disable F3 sidecar build (for debugging profile)
357+
358+
## Cargo Features
359+
360+
- **`default`** - `jemalloc`, `tokio-console`, `tracing-loki`, `tracing-chrome`
361+
- **`slim`** - Minimal feature set (uses rustalloc)
362+
- **`jemalloc`** - Use jemalloc allocator (production default)
363+
- **`rustalloc`** - Use Rust standard allocator
364+
- **`system-alloc`** - Use system allocator (for memory profiling)
365+
- **`tokio-console`** - Enable tokio-console integration
366+
- **`tracing-loki`** - Send telemetry to Loki
367+
- **`tracing-chrome`** - Chrome tracing support
368+
- **`no-f3-sidecar`** - Disable F3 sidecar build
369+
- **`doctest-private`** - Enable doctests for private items
370+
- **`benchmark-private`** - Enable benchmark suite
371+
- **`interop-tests-private`** - Enable interop tests
372+
373+
## Build Profiles
374+
375+
- **`dev`** - Fast compile, line-table-only debug info, opt-level=1 for deps
376+
- **`quick`** - Inherits from release, opt-level=1, no LTO (good for testing)
377+
- **`release`** - Optimized, stripped, thin LTO, panic=abort
378+
- **`release-lto-fat`** - Maximum optimization with fat LTO
379+
- **`debugging`** - Full debug info (requires `FOREST_F3_SIDECAR_FFI_BUILD_OPT_OUT=1`)
380+
- **`profiling`** - For profiling tools
381+
382+
## Key Dependencies
383+
384+
- **Rust**: Version specified in `rust-toolchain.toml`
385+
- **Go**: Version specified in `go.work` (required for F3 sidecar)
386+
- **OS packages**: `build-essential` (Ubuntu), `clang`, `clang-devel` (Fedora)
387+
- **mise-en-place**: Task runner and tool installer (`mise.jdx.dev`)
388+
389+
## Contributing Guidelines
390+
391+
From CONTRIBUTING.md:
392+
393+
- Use conventional commits (e.g., `feat: add Filecoin.RuleTheWorld RPC method`)
394+
- Run linters before submitting: `mise lint`
395+
- Format code: `mise fmt`
396+
- Ensure tests pass: `mise test`
397+
- Fill PR template exhaustively
398+
- First-time contributors sign CLA when opening PR
399+
- Document public functions and structs (see [Documentation practices](https://github.com/ChainSafe/forest/wiki/Documentation-practices))

0 commit comments

Comments
 (0)