Skip to content

Commit 69065b2

Browse files
committed
add AGENTS.md
1 parent f956503 commit 69065b2

1 file changed

Lines changed: 153 additions & 0 deletions

File tree

AGENTS.md

Lines changed: 153 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,153 @@
1+
# AGENTS.md - Waterfalls Developer Guide
2+
3+
Waterfalls is a Rust project providing blockchain data to Liquid and Bitcoin light-client wallets.
4+
5+
## Development Environment
6+
7+
Use Nix (defined in `flake.nix`): `nix develop` or `direnv allow`.
8+
Provides: Rust toolchain (via rust-overlay), RocksDB, OpenSSL, bitcoind, elementsd, libclang.
9+
10+
When the nix env is not already active (e.g. sandbox), prefer `direnv exec . <command>`
11+
(e.g. `direnv exec . cargo check`) over `nix develop --command <command>` — it uses the
12+
cached nix-direnv environment and avoids flake re-evaluation overhead.
13+
14+
## Build & Check Commands
15+
16+
```bash
17+
cargo build # Debug build
18+
cargo build --release # Release build
19+
cargo check # Fast type-check
20+
cargo check --no-default-features # Check without default features
21+
cargo check --no-default-features --features test_env
22+
cargo check --benches
23+
cargo check --tests
24+
```
25+
26+
## Test Commands
27+
28+
```bash
29+
cargo test # Run all tests (uses default features: test_env, db)
30+
cargo test test_name # Run a single test by name
31+
cargo test test_name -- --exact # Run exactly one test (no substring match)
32+
cargo test -- --nocapture # Show stdout/stderr
33+
cargo test -- --ignored # Run ignored tests (require internet)
34+
cargo test --test integration # Run only integration tests
35+
cargo bench --features bench_test # Run benchmarks (criterion)
36+
```
37+
38+
### Feature Flags
39+
40+
- `test_env` (default) — enables `bitcoind` dep for tests requiring local nodes
41+
- `db` (default) — enables RocksDB storage backend
42+
- `synced_node` — tests requiring a locally running synced node
43+
- `bench_test` — long-running benchmark tests
44+
- `examine_logs` — log inspection tests
45+
46+
### Required Environment Variables for Tests
47+
48+
```bash
49+
export BITCOIND_EXEC=/path/to/bitcoind # Provided by nix develop
50+
export ELEMENTSD_EXEC=/path/to/elementsd # Provided by nix develop
51+
export RUST_LOG=debug # Optional: enable debug logging
52+
```
53+
54+
## Formatting & Linting
55+
56+
```bash
57+
cargo fmt # Format code (default rustfmt settings)
58+
cargo clippy # Lint
59+
cargo clippy -- -D warnings # Lint, fail on warnings (CI enforced)
60+
```
61+
62+
No `rustfmt.toml` or `clippy.toml` — default settings are used.
63+
64+
## Code Style Guidelines
65+
66+
### Imports
67+
68+
Grouped in this order (separated by blank lines when practical):
69+
1. `std::` — standard library
70+
2. External crates — `anyhow`, `elements`, `hyper`, `serde`, `tokio`, etc.
71+
3. `crate::` / `super::` — internal modules
72+
73+
Use absolute paths: `use waterfalls::be::Address` (in tests/benches), `use crate::be::Address` (within the crate).
74+
75+
### Error Handling
76+
77+
- **Application-level**: `anyhow::Result` for fallible operations in fetch, threads, startup.
78+
- **Server routes**: custom `Error` enum in `src/server/mod.rs` mapped to HTTP status codes.
79+
- `CannotDecrypt` → 422, `BodyTooLarge` → 413, `BodyReadTimeout` → 408, input errors → 400, others → 500.
80+
- **Fetch layer**: custom `Error` enum in `src/fetch.rs` (`TxNotFound`, `BlockNotFound`, etc.).
81+
- **Unrecoverable**: `error_panic!` macro (defined in `src/lib.rs`) — logs via `log::error!` then panics.
82+
- Log errors with `log::error!` before returning them.
83+
84+
### Logging
85+
86+
- Use the `log` crate: `log::info!`, `log::warn!`, `log::error!`, `log::debug!`
87+
- Initialized via `env_logger` in `main.rs` (default filter: `info`)
88+
- For systemd integration: set `RUST_LOG_STYLE=SYSTEMD`
89+
90+
### Async Code
91+
92+
- Runtime: `tokio` with `rt-multi-thread`
93+
- Use `tokio::select!` for concurrent operations (e.g., signal handling)
94+
- Use `#[tokio::test]` for async tests
95+
96+
### Serialization
97+
98+
- JSON: `serde` / `serde_json` with `Serialize`/`Deserialize` derives
99+
- CBOR: `minicbor` with `Encode`/`Decode` derives and custom `with` helpers in `src/cbor.rs`
100+
- Field annotations: `#[cbor(n(X))]` for CBOR field indices, `#[serde(skip_serializing_if = ...)]`
101+
102+
### Testing Patterns
103+
104+
- `#[tokio::test]` for async tests
105+
- `#[cfg(feature = "test_env")]` gates tests needing bitcoind/elementsd
106+
- `#[cfg(all(feature = "test_env", feature = "db"))]` for DB-backed integration tests
107+
- `#[ignore = "requires internet"]` for tests hitting remote endpoints
108+
- `env_logger::try_init()` at test start (ignore the error if already initialized)
109+
- Test infrastructure in `src/test_env.rs`: `TestEnv`, `WaterfallClient`, `launch()`, `launch_with_node()`
110+
- Integration tests in `tests/integration.rs` use `launch_memory()` / `test_env::launch()` to spin up node + server
111+
112+
## Project Structure
113+
114+
```
115+
src/
116+
├── lib.rs # Library root: types, error_panic! macro, prometheus metrics
117+
├── main.rs # Binary entry: clap parsing, logging, signal handling
118+
├── fetch.rs # Blockchain data fetching (esplora / local node REST)
119+
├── cbor.rs # CBOR encoding helpers for block hashes
120+
├── test_env.rs # Test utilities (TestEnv, WaterfallClient)
121+
├── be/ # Backend types (Address, Block, BlockHeader, Descriptor, Tx, Txid)
122+
├── server/ # HTTP server: Arguments (clap), Network, Error enum, routing,
123+
│ # state, mempool, signing, encryption, derivation_cache, preload
124+
├── store/ # Store trait + AnyStore, memory.rs, db.rs (RocksDB, behind `db` feature)
125+
└── threads/ # Background tasks: block indexing, mempool sync
126+
build.rs # Injects GIT_COMMIT_HASH at build time
127+
tests/integration.rs # Integration tests
128+
benches/benches.rs # Criterion benchmarks
129+
```
130+
131+
## CI (`.github/workflows/rust.yml`)
132+
133+
Runs on push/PR to `master`:
134+
- **tests**: downloads bitcoind 28.0 & elementsd 23.2.4, runs `cargo test` and `cargo test -- --ignored`
135+
- **checks**: `cargo check` with various feature combinations
136+
- **nix**: `nix build .` with cachix
137+
138+
## Cursor Rules
139+
140+
From `.cursor/rules/my-custom-rule.mdc` (always applied):
141+
142+
1. The developer uses a Nix environment from `flake.nix` — use it when proposing commands
143+
2. Add new structs at the end of files, or just before `#[cfg(test)] mod tests` if present
144+
3. Never add new dependencies unless explicitly asked
145+
146+
## Common Tasks
147+
148+
```bash
149+
cargo run -- --network liquid --use-esplora # Run server against esplora
150+
cargo test --features "test_env db" # Run tests with DB backend
151+
nix build .#dockerImage && docker load < result # Build Docker image
152+
cargo bench --features bench_test # Run benchmarks
153+
```

0 commit comments

Comments
 (0)