# Freenet Core Crate

## Trigger-Action Rules

### BEFORE writing any new code in this crate

```
Does this code need current time?
  → DO NOT use: std::time::Instant::now(), tokio::time::sleep()
  → USE: TimeSource trait from src/simulation/

Does this code need randomness?
  → DO NOT use: rand::random(), rand::thread_rng()
  → USE: GlobalRng from src/config.rs

Is this network code for tests?
  → DO NOT use: tokio::net::UdpSocket
  → USE: SimulationSocket from src/transport/in_memory_socket.rs
```

### WHEN adding a test

```
Is it testing network behavior?
  → Use #[freenet_test] macro for SimNetwork

Is it a unit test?
  → Use mocks: MockNetworkBridge, MockRing

Need deterministic results?
  → Use GlobalRng seeding (see src/config.rs)
```

### WHEN modifying transport/

```
Read first: docs/architecture/transport/README.md
Key decision points:
  - Connection state: peer_connection.rs
  - Rate limiting: rate_limiter.rs
  - Congestion control: congestion/ (LEDBAT++, BBR, FixedRate)
```

### WHEN modifying operations/

```
Each op has wire-format types + helpers in `<op>.rs` and one or more
task-per-transaction drivers under `<op>/op_ctx_task.rs`. The legacy
`Operation` trait / `process_message` / `load_or_init` / `handle_op_request`
mediator path is gone; `connect.rs` still carries the relay/joiner
state-machine helpers (`handle_request`, `new_joiner`, `new_relay`) as
test-only fixtures.

Driver entry points:

  connect/op_ctx_task.rs    → start_client_connect, start_relay_connect
  get/op_ctx_task.rs        → start_client_get, start_relay_get,
                              start_sub_op_get, start_targeted_sub_op_get
  put/op_ctx_task.rs        → start_client_put, start_relay_put,
                              start_relay_put_streaming
  update/op_ctx_task.rs     → start_client_update,
                              start_relay_request_update,
                              start_relay_broadcast_to,
                              start_relay_request_update_streaming,
                              start_relay_broadcast_to_streaming
  subscribe/op_ctx_task.rs  → start_client_subscribe,
                              start_directed_subscribe,
                              run_executor_subscribe,
                              run_renewal_subscribe,
                              start_relay_subscribe

All five relay drivers share the per-node dedup gate pattern
(`active_relay_{get,update,put,subscribe,connect}_txs`) and the
`Relay*InflightGuard` RAII. CONNECT relay's admission RAII guard is
scoped to the initial-actions block (NOT held across the recv loop)
to avoid admission slot starvation under load. UPDATE is
fire-and-forget end-to-end; the others share `op_ctx.rs::drive_retry_loop`.

`Unsubscribe` routes to `subscribe::handle_unsubscribe_inbound` (free
function). `ForwardingAck` is a no-op telemetry hook.

See `.claude/rules/operations.md` for dispatch and invariants.
```

## Module Map

| Module | Entry Point | What It Does |
|--------|-------------|--------------|
| `node/` | `node.rs` | Event loop (start here for data flow) |
| `operations/` | `operations.rs` | Transaction state machines |
| `contract/` | `handler.rs` | WASM execution |
| `transport/` | `connection_handler.rs` | Networking layer |
| `ring/` | `ring.rs` | DHT routing |
| `server/` | `server.rs` | Client API |
| `simulation/` | `time.rs`, `rng.rs` | DST abstractions |

## Commands

```bash
cargo test -p freenet                           # All tests
cargo bench --bench transport_perf -- level0    # Quick benchmark
```
