|
| 1 | +# Freenet Core Crate Architecture |
| 2 | + |
| 3 | +```mermaid |
| 4 | +graph LR |
| 5 | + %% Client Application |
| 6 | + Client[Client Application] |
| 7 | + Client -->|"Requests"| WebSocket |
| 8 | +
|
| 9 | + subgraph Core[Freenet Core] |
| 10 | + %% Client Interface Layer |
| 11 | + WebSocket[WebSocket API] |
| 12 | + Server[Server] --> WebSocket |
| 13 | + WebSocket -->|"Messages"| ClientEvents |
| 14 | + Server -->|"ClientConnection"| ClientEvents |
| 15 | + |
| 16 | + %% Central Node Event Loop |
| 17 | + subgraph NodeLoop[Node Event Loop] |
| 18 | + Node[Node] |
| 19 | + Node -->|"Messages"| EventChannelIn[(Incoming Channel)] |
| 20 | + EventChannelOut[(Outgoing Channel)] --> Node |
| 21 | + end |
| 22 | +
|
| 23 | + %% Event Loop Connections |
| 24 | + ClientEvents -->|"OpenRequest"| EventChannelIn |
| 25 | + OpManager -->|"Op Results"| EventChannelIn |
| 26 | + ContractHandler -->|"Contract Events"| EventChannelIn |
| 27 | + NetworkBridge -->|"Net Messages"| EventChannelIn |
| 28 | +
|
| 29 | + EventChannelOut -->|"Client Responses"| ClientEvents |
| 30 | + EventChannelOut -->|"Operations"| OpManager |
| 31 | + EventChannelOut -->|"Contract Queries"| ContractHandler |
| 32 | + EventChannelOut -->|"Network Messages"| NetworkBridge |
| 33 | +
|
| 34 | + %% Operations Management |
| 35 | + subgraph OpLoop[OpManager Event Loop] |
| 36 | + OpManager -->|"States"| OpChannelIn[(Op In Channel)] |
| 37 | + OpChannelOut[(Op Out Channel)] -->|"Updates"| OpManager |
| 38 | + end |
| 39 | +
|
| 40 | + OpMachines[Operation State Machines] |
| 41 | + OpManager -->|"Process"| OpMachines |
| 42 | + OpMachines -->|"Transitions"| OpChannelIn |
| 43 | + OpChannelOut -->|"Messages"| NetworkBridge |
| 44 | +
|
| 45 | + %% Contract System |
| 46 | + subgraph ContractHandling[Contract Processing] |
| 47 | + Executor[Executor] |
| 48 | + WasmRuntime[Runtime] |
| 49 | + StateStore[StateStore] |
| 50 | + end |
| 51 | +
|
| 52 | + ContractHandler -->|"Execute"| Executor |
| 53 | + Executor -->|"WASM"| WasmRuntime |
| 54 | + Executor -->|"State"| StateStore |
| 55 | + |
| 56 | + subgraph ExecutorLoop[Executor Callback Loop] |
| 57 | + ExecutorEvents[Executor Event Handler] |
| 58 | + ExecutorCallback[Callback Channel] |
| 59 | + ExecutorEvents -->|"Tx ID"| ExecutorCallback |
| 60 | + ExecutorCallback -->|"Results"| ExecutorEvents |
| 61 | + end |
| 62 | + |
| 63 | + Executor --> ExecutorEvents |
| 64 | + ExecutorCallback --> OpManager |
| 65 | +
|
| 66 | + %% Network Stack |
| 67 | + subgraph NetStack[Network Stack] |
| 68 | + Ring[Ring] |
| 69 | + Transport[Transport] |
| 70 | + NetMessage[(NetMessage)] |
| 71 | + end |
| 72 | +
|
| 73 | + subgraph NetworkLoop[Network Event Listener] |
| 74 | + HandshakeHandler[Handshake Handler] |
| 75 | + ConnManager[Connection Manager] |
| 76 | + HandshakeHandler --> ConnManager |
| 77 | + ConnManager --> HandshakeHandler |
| 78 | + end |
| 79 | + |
| 80 | + NetworkBridge --> NetworkLoop |
| 81 | + NetworkLoop --> Ring |
| 82 | + NetworkLoop --> Transport |
| 83 | + end |
| 84 | +
|
| 85 | + Peers[Peer Nodes] |
| 86 | + Transport <-->|"Packets"| Peers |
| 87 | +
|
| 88 | + %% Style Definitions |
| 89 | + %% Client Interface Layer |
| 90 | + classDef clientInterface fill:#c6dcef,stroke:#2874a6,stroke-width:1px,color:#000; |
| 91 | + class Client,WebSocket,Server,ClientEvents clientInterface; |
| 92 | + |
| 93 | + %% Node Core |
| 94 | + classDef nodeCore fill:#d5f5e3,stroke:#1e8449,stroke-width:1px,color:#000; |
| 95 | + class Node,EventChannelIn,EventChannelOut nodeCore; |
| 96 | + |
| 97 | + %% Operations |
| 98 | + classDef operations fill:#fdebd0,stroke:#d35400,stroke-width:1px,color:#000; |
| 99 | + class OpManager,OpMachines,OpChannelIn,OpChannelOut operations; |
| 100 | + |
| 101 | + %% Contracts |
| 102 | + classDef contracts fill:#e8daef,stroke:#8e44ad,stroke-width:1px,color:#000; |
| 103 | + class ContractHandler,Executor,WasmRuntime,StateStore,ExecutorEvents,ExecutorCallback contracts; |
| 104 | + |
| 105 | + %% Network - Changed to a more distinct teal color |
| 106 | + classDef network fill:#d1f2eb,stroke:#16a085,stroke-width:1px,color:#000; |
| 107 | + class NetworkBridge,HandshakeHandler,ConnManager,Ring,Transport,NetMessage,Peers network; |
| 108 | + |
| 109 | + %% Event Loops |
| 110 | + classDef eventLoop fill:#f9e79f,stroke:#f39c12,stroke-width:2px; |
| 111 | + class NodeLoop,OpLoop,ExecutorLoop,NetworkLoop eventLoop; |
| 112 | + |
| 113 | + %% Boundary |
| 114 | + classDef boundary fill:#ebf5fb,stroke:#3498db,stroke-width:2px; |
| 115 | + class Core boundary; |
| 116 | + |
| 117 | + %% Link Styling - Colored by SOURCE component - Fixed version |
| 118 | + %% Client Interface links (blue) |
| 119 | + linkStyle 0,1,2,3,6 stroke:#2874a6,stroke-width:2px; |
| 120 | + |
| 121 | + %% Node Core links (green) |
| 122 | + linkStyle 4,5,10,11,12,13 stroke:#1e8449,stroke-width:2px; |
| 123 | + |
| 124 | + %% Operation links (orange) |
| 125 | + linkStyle 7,14,15,16,17,18 stroke:#d35400,stroke-width:2px; |
| 126 | + |
| 127 | + %% Contract links (purple) |
| 128 | + linkStyle 8,19,20,21,22,23,24 stroke:#8e44ad,stroke-width:2px; |
| 129 | + |
| 130 | + %% Network links - Changed to teal |
| 131 | + linkStyle 9,25,26,27,28 stroke:#16a085,stroke-width:2px; |
| 132 | +``` |
| 133 | + |
| 134 | +**Key Components & Communication:** |
| 135 | + |
| 136 | +- **[Server](src/server/mod.rs):** Handles HTTP and WebSocket endpoints for client connections. The `ClientConnection` enum in [http_gateway.rs](src/server/http_gateway.rs) defines the interface between the server and client events system. The server manages the WebSocket API and passes client requests to the ClientEvents subsystem. |
| 137 | + |
| 138 | +- **[Node](src/node.rs):** Central coordinator with the main event loop implemented in `run_event_loop()`. This function contains the core `tokio::select!` loop that dispatches events to appropriate handlers like `handle_network_message()`, `handle_node_event()`, and `handle_client_request()`. |
| 139 | + |
| 140 | +- **[ClientEvents](src/client_events/mod.rs):** Bridges client connections to the Node system through the `ClientEventsProxy` trait in [mod.rs](src/client_events/mod.rs). The WebSocket implementation in [websocket.rs](src/client_events/websocket.rs) provides key methods like `websocket_interface()` and `process_client_request()` that handle client connections. |
| 141 | + |
| 142 | +- **[OpManager](src/operations/op_manager.rs):** Tracks operation state using internal hash maps for each operation type. The `push()` and `pop()` methods manage operation lifecycle, while `garbage_cleanup_task()` runs as a background task to remove stale transactions. Other important methods include `notify_op_change()` and `notify_node_event()` for event notification. |
| 143 | + |
| 144 | +- **[ContractHandler](src/contract/handler.rs):** Manages contract interactions through `ContractHandlerChannel<T>` with different halves for different communication directions. The `send_to_handler()` and `recv_from_sender()` methods implement the bidirectional communication protocol for contract operations. |
| 145 | + |
| 146 | +- **[ContractExecutor](src/contract/executor.rs):** Executes WASM contract code with network capabilities defined by the `ContractExecutor` trait. The `Executor<R>` implementation connects contracts to the network using `ComposeNetworkMessage<Op>` implementations like `GetContract`, `PutContract`, and `UpdateContract`. |
| 147 | + |
| 148 | +- **[WasmRuntime](src/wasm_runtime/mod.rs):** Provides the sandboxed execution environment through the `ContractRuntimeInterface` and `DelegateRuntimeInterface` traits defined in [mod.rs](src/wasm_runtime/mod.rs). These traits include methods for contract instantiation and function invocation. |
| 149 | + |
| 150 | +- **[StateStore](src/contract/storages.rs):** Handles persistent contract state through the `StateStore<S>` implementation, which provides methods like `get_state()` and `put_state()`. The backing store is abstracted through the `Storage` trait. |
| 151 | + |
| 152 | +- **[NetworkBridge](src/node/network_bridge/mod.rs):** Abstracts network communication via the `NetworkBridge` trait in [network_bridge.rs](src/node/network_bridge.rs). The primary implementation is `P2pConnManager` in [p2p_protoc.rs](src/node/network_bridge/p2p_protoc.rs), which provides the `run_event_listener()` method containing the network event loop. |
| 153 | + |
| 154 | +- **[Ring](src/ring/mod.rs):** Manages network topology through the `Ring` struct and `ConnectionManager` in [mod.rs](src/ring/mod.rs). Key methods include `add_connection()` for peer registration and `route()` for determining message paths. |
| 155 | + |
| 156 | +- **[Transport](src/transport/mod.rs):** Implements low-level communication through the `Socket` trait in [mod.rs](src/transport/mod.rs). The `UdpSocket` implementation provides the actual network I/O operations with support for encryption and rate limiting. |
| 157 | + |
| 158 | +- **[NetMessage](src/message.rs):** Defines the message format used for P2P communication through the `NetMessage` enum hierarchy. Each message includes a `Transaction` ID for tracking and contains operation-specific data in variants like `ConnectMsg`, `PutMsg`, and `GetMsg`. |
| 159 | + |
| 160 | +- **[Operation State Machines](src/operations/mod.rs):** Each operation type is implemented in a dedicated module (e.g., [get.rs](src/operations/get.rs), [put.rs](src/operations/put.rs)) with functions like `start_op()` to create initial state and `request_get()` to initiate network operations. |
| 161 | + |
| 162 | +**Event Loops and Channels:** |
| 163 | + |
| 164 | +1. **Node Event Loop:** The primary coordination loop in [node.rs:run_event_loop()](src/node.rs). Channels are created with `event_loop_notification_channel()` in [network_bridge.rs](src/node/network_bridge.rs), which sets up the `EventLoopNotificationsReceiver` and `EventLoopNotificationsSender` for inter-component communication. |
| 165 | + |
| 166 | +2. **OpManager Event Loop:** Implemented as `garbage_cleanup_task()` in [op_manager.rs](src/operations/op_manager.rs). This task continuously monitors for expired transactions and removes them from the system, sending `NodeEvent::TransactionTimedOut` notifications when needed. |
| 167 | + |
| 168 | +3. **Network Event Listener:** The network main loop in [p2p_protoc.rs:run_event_listener()](src/node/network_bridge/p2p_protoc.rs). It uses `wait_for_event()` to multiplex between multiple event sources and routes incoming/outgoing messages appropriately. |
| 169 | + |
| 170 | +4. **Executor Callback Loop:** Created through `executor_channel()` in [executor.rs](src/contract/executor.rs). This allows contract code to initiate network operations and receive results asynchronously while maintaining execution context. |
| 171 | + |
| 172 | +**Request Lifecycle: Client to Network and Back** |
| 173 | + |
| 174 | +A typical client request follows this path through the system: |
| 175 | + |
| 176 | +1. **Client Initiation** |
| 177 | + - Client connects to the WebSocket endpoint at `/v1/contract/command` |
| 178 | + - `websocket_commands()` in `client_events/websocket.rs` handles the connection |
| 179 | + - Client sends a `ClientRequest` (e.g., `ContractRequest::Get{key}`) |
| 180 | + |
| 181 | +2. **Request Processing** |
| 182 | + - `process_client_request()` deserializes the request and assigns a `ClientId` |
| 183 | + - `WebSocketProxy.recv()` wraps it in an `OpenRequest` and sends to the Node |
| 184 | + - Node receives the request in `handle_client_request()` and determines the type |
| 185 | + |
| 186 | +3. **Operation Creation** |
| 187 | + - For GET requests: Node calls `get::start_op()` to create a new `GetOp` |
| 188 | + - `OpManager.push()` stores the operation state in its collections |
| 189 | + - Node initiates the operation with `get::request_get()` |
| 190 | + - A unique `Transaction` ID is assigned to track this operation |
| 191 | + |
| 192 | +4. **Network Traversal** |
| 193 | + - `OpManager` determines the target peer based on the contract key's location |
| 194 | + - It constructs a `NetMessage::V1(NetMessageV1::Get(GetMsg::...))` |
| 195 | + - `NetworkBridge.send()` delivers this to the target peer |
| 196 | + - `P2pConnManager` sends the actual network packet via `UdpSocket.send_to()` |
| 197 | + |
| 198 | +5. **Remote Processing** |
| 199 | + - The receiving peer's `NetworkBridge` gets the message via `UdpSocket.recv_from()` |
| 200 | + - `P2pConnManager.process_message()` forwards to Node's event loop |
| 201 | + - Remote Node processes the Get request in its contract subsystem |
| 202 | + - If the contract exists, a response message is created and sent back |
| 203 | + |
| 204 | +6. **Response Handling** |
| 205 | + - Local `NetworkBridge` receives the response message |
| 206 | + - Node event loop processes it in `handle_network_message()` |
| 207 | + - Message is matched to pending `Transaction` via its ID |
| 208 | + - `OpManager.pop()` retrieves and updates the operation state |
| 209 | + - Contract state from response is stored in `StateStore` if needed |
| 210 | + |
| 211 | +7. **Client Response** |
| 212 | + - Node creates a `HostResponse::ContractResponse(ContractResponse::GetResponse{...})` |
| 213 | + - Response is sent to `WebSocketProxy.send(client_id, result)` |
| 214 | + - `process_host_response()` serializes it in client's preferred format (Flatbuffers/Native) |
| 215 | + - WebSocket connection sends serialized response to client application |
| 216 | + |
| 217 | +This cycle demonstrates how a distributed operation flows through all major components while maintaining transaction context throughout the process. Each step includes error handling and timeout mechanisms to ensure reliability. |
| 218 | + |
| 219 | +_Refer to the diagram above for a visual representation of these interactions._ |
0 commit comments