|
| 1 | +# Agent Guidelines for Fiber Network Node (FNN) |
| 2 | + |
| 3 | +This document provides essential guidelines for AI coding agents working on the Fiber Network Node codebase. The Fiber Network is a reference implementation of a peer-to-peer payment/swap network built on CKB blockchain, similar to Lightning Network. |
| 4 | + |
| 5 | +## Build System & Commands |
| 6 | + |
| 7 | +### Primary Language & Toolchain |
| 8 | +- **Language**: Rust 1.85.0 (specified in `rust-toolchain.toml`) |
| 9 | +- **Build System**: Cargo workspace with 5 member crates |
| 10 | +- **Test Runner**: cargo-nextest (preferred over `cargo test`) |
| 11 | + |
| 12 | +### Essential Commands |
| 13 | + |
| 14 | +#### Building |
| 15 | +```bash |
| 16 | +cargo build # Debug build |
| 17 | +cargo build --release # Release build |
| 18 | +cargo check --locked # Quick check with Cargo.lock |
| 19 | +make check # Full check (debug, release, no-default-features) |
| 20 | +``` |
| 21 | + |
| 22 | +#### Testing |
| 23 | +```bash |
| 24 | +# Run all tests with nextest (PREFERRED) |
| 25 | +cargo nextest run --no-fail-fast |
| 26 | + |
| 27 | +# Run specific package tests |
| 28 | +cargo nextest run -p fnn -p fiber-bin |
| 29 | + |
| 30 | +# Run single test by name |
| 31 | +cargo nextest run test_name |
| 32 | + |
| 33 | +# Run tests matching pattern |
| 34 | +cargo nextest run 'test_pattern' |
| 35 | + |
| 36 | +# Standard cargo test (if nextest unavailable) |
| 37 | +RUST_LOG=off cargo test -p fnn -p fiber-bin |
| 38 | + |
| 39 | +# Run benchmarks |
| 40 | +cargo criterion --features bench |
| 41 | +make benchmark-test |
| 42 | +``` |
| 43 | + |
| 44 | +**Note**: The `.config/nextest.toml` configures thread requirements for heavy/channel/payment tests. Tests require `RUST_TEST_THREADS: 2` in CI. |
| 45 | + |
| 46 | +#### Linting & Formatting |
| 47 | +```bash |
| 48 | +# Format code (REQUIRED before commits) |
| 49 | +cargo fmt --all |
| 50 | + |
| 51 | +# Check formatting without modifying |
| 52 | +cargo fmt --all -- --check |
| 53 | +make fmt |
| 54 | + |
| 55 | +# Run clippy (REQUIRED, must pass with no warnings) |
| 56 | +cargo clippy --all-targets --all-features -p fnn -p fiber-bin -- -D warnings |
| 57 | +make clippy |
| 58 | + |
| 59 | +# Auto-fix clippy warnings and format |
| 60 | +make bless |
| 61 | + |
| 62 | +# Check for typos |
| 63 | +typos |
| 64 | +typos -w # Auto-fix typos |
| 65 | +``` |
| 66 | + |
| 67 | +#### WASM-specific |
| 68 | +```bash |
| 69 | +# Check WASM crates |
| 70 | +cargo clippy -p fiber-wasm -p fiber-wasm-db-worker -p fiber-wasm-db-common --target wasm32-unknown-unknown -- -D warnings |
| 71 | +``` |
| 72 | + |
| 73 | +#### Other Checks |
| 74 | +```bash |
| 75 | +# Check for unused dependencies |
| 76 | +cargo shear |
| 77 | + |
| 78 | +# Generate RPC documentation |
| 79 | +make gen-rpc-doc |
| 80 | + |
| 81 | +# Verify data migration schemas |
| 82 | +make check-migrate |
| 83 | + |
| 84 | +# Update migration schemas |
| 85 | +make update-migrate-check |
| 86 | +``` |
| 87 | + |
| 88 | +## Code Style Guidelines |
| 89 | + |
| 90 | +### Module & Import Organization |
| 91 | +1. **Import ordering** (top to bottom): |
| 92 | + - Standard library (`use std::...`) |
| 93 | + - External crates (alphabetical) |
| 94 | + - Internal crate modules (`use crate::...`) |
| 95 | + - Local modules (`use super::...`) |
| 96 | +2. Group imports by category with blank lines between groups |
| 97 | +3. Use explicit imports, avoid glob imports except for preludes |
| 98 | + |
| 99 | +### Naming Conventions |
| 100 | +- **Files**: Snake_case (e.g., `channel_actor.rs`, `payment_handler.rs`) |
| 101 | +- **Types**: PascalCase (e.g., `ChannelActor`, `PaymentRequest`) |
| 102 | +- **Functions/Variables**: Snake_case (e.g., `process_message`, `peer_id`) |
| 103 | +- **Constants**: SCREAMING_SNAKE_CASE (e.g., `MAX_TLC_VALUE`, `DEFAULT_TIMEOUT`) |
| 104 | +- **Modules**: Snake_case (e.g., `fiber::channel`, `ckb::actor`) |
| 105 | + |
| 106 | +### Type Annotations |
| 107 | +- Use explicit types for public APIs and struct fields |
| 108 | +- Type inference is acceptable for local variables when clear |
| 109 | +- Always annotate function return types |
| 110 | +- Use `#[serde_as]` and `serde_with` for complex serialization (e.g., `U128Hex`, `U64Hex`) |
| 111 | + |
| 112 | +### Error Handling |
| 113 | +- Use `thiserror::Error` for custom error types (see `src/errors.rs`) |
| 114 | +- Prefer `Result<T, Error>` over `Result<T, SomeError>` |
| 115 | +- Use `?` operator for error propagation |
| 116 | +- Provide descriptive error messages with context |
| 117 | +- Don't panic in production code; use `expect()` only when truly unreachable |
| 118 | + |
| 119 | +**Example**: |
| 120 | +```rust |
| 121 | +#[derive(Error, Debug)] |
| 122 | +pub enum Error { |
| 123 | + #[error("Peer not found error: {0:?}")] |
| 124 | + PeerNotFound(PeerId), |
| 125 | + #[error("Channel not found error: {0:?}")] |
| 126 | + ChannelNotFound(Hash256), |
| 127 | + #[error("Invalid parameter: {0}")] |
| 128 | + InvalidParameter(String), |
| 129 | +} |
| 130 | + |
| 131 | +pub type Result<T> = std::result::Result<T, Error>; |
| 132 | +``` |
| 133 | + |
| 134 | +### Async & Actor Patterns |
| 135 | +- This codebase uses the **Ractor** actor framework extensively |
| 136 | +- Use `async_trait::async_trait` for async traits |
| 137 | +- For WASM compatibility, use `#[cfg_attr(target_arch="wasm32", async_trait::async_trait(?Send))]` |
| 138 | +- Actor messages use enums (e.g., `ChannelActorMessage`, `NetworkActorMessage`) |
| 139 | +- Use `ractor::call` for RPC-style actor communication |
| 140 | + |
| 141 | +**Example**: |
| 142 | +```rust |
| 143 | +#[cfg_attr(target_arch="wasm32", async_trait::async_trait(?Send))] |
| 144 | +#[cfg_attr(not(target_arch = "wasm32"), async_trait::async_trait)] |
| 145 | +impl Actor for MyActor { |
| 146 | + type Msg = MyActorMessage; |
| 147 | + type State = MyState; |
| 148 | + type Arguments = MyArgs; |
| 149 | + // Implementation... |
| 150 | +} |
| 151 | +``` |
| 152 | + |
| 153 | +### Logging & Tracing |
| 154 | +- Use `tracing` crate for structured logging |
| 155 | +- Levels: `trace`, `debug`, `info`, `warn`, `error` |
| 156 | +- Include context in log messages (peer_id, channel_id, etc.) |
| 157 | +- Log at appropriate levels: |
| 158 | + - `error!`: Critical failures requiring attention |
| 159 | + - `warn!`: Unexpected but recoverable situations |
| 160 | + - `info!`: Important state changes |
| 161 | + - `debug!`: Detailed operational info |
| 162 | + - `trace!`: Very verbose, protocol-level details |
| 163 | + |
| 164 | +### Documentation |
| 165 | +- Public APIs MUST have doc comments (`///`) |
| 166 | +- RPC methods require detailed documentation (checked by `make gen-rpc-doc`) |
| 167 | +- Use `/// # Example` sections for complex APIs |
| 168 | +- Document invariants and assumptions |
| 169 | +- Explain "why" in comments, not just "what" |
| 170 | + |
| 171 | +### Testing Conventions |
| 172 | +- Unit tests in same file: `#[cfg(test)] mod tests { ... }` |
| 173 | +- Integration tests in `tests/` directory |
| 174 | +- Use descriptive test names: `test_channel_open_accept_flow` |
| 175 | +- Mock actors and external dependencies |
| 176 | +- Test both success and error paths |
| 177 | + |
| 178 | +### Platform-Specific Code |
| 179 | +- Use `#[cfg(not(target_arch = "wasm32"))]` for native-only code |
| 180 | +- Use `#[cfg(target_arch = "wasm32")]` for WASM-only code |
| 181 | +- Keep platform-specific code minimal and isolated |
| 182 | +- Test both native and WASM builds in CI |
| 183 | + |
| 184 | +### Serialization |
| 185 | +- Use `serde` with `#[derive(Serialize, Deserialize)]` |
| 186 | +- Use `serde_with` for custom serialization (hex, base64, etc.) |
| 187 | +- Use `molecule` for CKB-specific binary formats |
| 188 | +- Maintain backward compatibility for persisted data |
| 189 | + |
| 190 | +### Security & Best Practices |
| 191 | +- No unsafe code without thorough review |
| 192 | +- Validate all external inputs (RPC, peer messages) |
| 193 | +- Use constant-time operations for cryptographic comparisons |
| 194 | +- Clear sensitive data (private keys) when done |
| 195 | +- Follow principle of least privilege |
| 196 | + |
| 197 | +## Allowed Clippy Lints |
| 198 | + |
| 199 | +The following clippy lints are explicitly allowed (see `Cargo.toml`): |
| 200 | +- `expect-fun-call`: Acceptable to use `expect()` with computed messages |
| 201 | +- `fallible-impl-from`: Allow `From` impls that can panic |
| 202 | +- `large-enum-variant`: Acceptable for actor message enums |
| 203 | +- `mutable-key-type`: Needed for certain data structures |
| 204 | +- `needless-return`: Explicit returns are sometimes clearer |
| 205 | +- `upper-case-acronyms`: Allow acronyms like `TLC`, `RPC`, `UDT` |
| 206 | + |
| 207 | +## Project Structure |
| 208 | + |
| 209 | +``` |
| 210 | +fiber/ |
| 211 | +├── crates/ |
| 212 | +│ ├── fiber-lib/ # Core library (fnn crate) |
| 213 | +│ │ └── src/ |
| 214 | +│ │ ├── fiber/ # Protocol implementation |
| 215 | +│ │ ├── ckb/ # CKB blockchain integration |
| 216 | +│ │ ├── rpc/ # JSON-RPC API |
| 217 | +│ │ ├── store/ # Data persistence |
| 218 | +│ │ └── watchtower/ # Watchtower service |
| 219 | +│ ├── fiber-bin/ # Binary executable |
| 220 | +│ ├── fiber-wasm/ # WebAssembly bindings |
| 221 | +│ └── fiber-wasm-db-*/ # WASM database workers |
| 222 | +├── tests/ # Integration tests |
| 223 | +├── migrate/ # Database migration tool |
| 224 | +└── Makefile # Convenience targets |
| 225 | +``` |
| 226 | + |
| 227 | +## Common Pitfalls |
| 228 | + |
| 229 | +1. **Don't forget to run tests with nextest**, not standard `cargo test` |
| 230 | +2. **Always run `make clippy` before committing** - CI enforces `-D warnings` |
| 231 | +3. **Check WASM compatibility** for code in `fiber-lib` - it must compile for both native and WASM |
| 232 | +4. **Update migration schemas** if you change data structures (`make check-migrate`) |
| 233 | +5. **Regenerate RPC docs** if you modify RPC methods (`make gen-rpc-doc`) |
| 234 | +6. **Use `cargo fmt` before committing** - formatting is strictly enforced |
| 235 | + |
| 236 | +## Continuous Integration |
| 237 | + |
| 238 | +CI runs the following checks (all must pass): |
| 239 | +- `make check` (multiple build configurations) |
| 240 | +- `make check-migrate` (migration schema validation) |
| 241 | +- `make check-dirty-rpc-doc` (RPC documentation up-to-date) |
| 242 | +- `cargo nextest run --no-fail-fast` (all tests) |
| 243 | +- `cargo fmt --all -- --check` (formatting) |
| 244 | +- `make clippy` (linting with warnings as errors) |
| 245 | +- `typos` (spell checking) |
| 246 | +- `cargo shear` (unused dependencies) |
| 247 | + |
| 248 | +## Additional Resources |
| 249 | + |
| 250 | +- RPC API documentation: `crates/fiber-lib/src/rpc/README.md` (auto-generated) |
| 251 | +- Protocol specifications: `docs/specs/` |
| 252 | +- Development notes: `docs/notes/` |
0 commit comments