|
1 | 1 | # High-Level Architecture |
2 | 2 |
|
3 | | -This file explains the repository-level architecture and how major crate groups interact. It intentionally stays high level. Detailed/lower-level architecture belongs in crate-specific docs under `.agents/context/crates/` as those files are added. For crate-by-crate ownership, use `.agents/context/crate-map.md`. |
4 | | - |
5 | | -## System shape |
6 | | - |
7 | | -The validator is a service graph around one core loop: make the right accounts available locally, execute valid ER transactions, persist the result, and settle scheduled state changes back to Solana. This graph is performance-sensitive: architectural changes must preserve low-latency, high-throughput behavior on critical paths unless there is no viable alternative, and any unavoidable tradeoff must be called out explicitly. See `.agents/rules/validator-goals.md` and `.agents/specs/validator-specification.md` for binding security details. |
| 3 | +The workspace separates process roles from reusable runtime construction. For |
| 4 | +crate-by-crate ownership, use `.agents/context/crate-map.md`. |
8 | 5 |
|
9 | 6 | ```text |
10 | | -Client / Operator |
11 | | - | |
12 | | - v |
13 | | -RPC / TUI / Admin ingress |
14 | | - | |
15 | | - v |
16 | | -Validator orchestration |
17 | | - | |
18 | | - +--> account synchronization <----> Solana RPC/WS + delegation metadata |
19 | | - | |
20 | | - +--> transaction execution -----> local AccountsDb + Ledger -----> events |
21 | | - | |
22 | | - +--> commit/undelegation -------> base-layer transactions |
23 | | - | |
24 | | - +--> task scheduling -----------> submitted transactions |
| 7 | + +--> Chainlink / Aperture / settlement / scheduler |
| 8 | +mbv-leader --> Engine<Leader> |
25 | 9 | | |
26 | | - +--> replication/metrics -------> replicas + observability |
27 | | -``` |
28 | | - |
29 | | -## Main layers |
30 | | - |
31 | | -### 1. Process and service orchestration |
32 | | - |
33 | | -Owned primarily by `magicblock-validator`, `magicblock-api`, and `magicblock-config`. |
34 | | - |
35 | | -Responsibilities: |
36 | | - |
37 | | -- parse/load configuration, |
38 | | -- construct the validator service graph, |
39 | | -- open persistent stores, |
40 | | -- initialize account sync, RPC, scheduler, committor, task scheduler, replication, metrics, and admin support, |
41 | | -- recover persisted work, |
42 | | -- coordinate startup mode versus primary/replica mode, |
43 | | -- stop services and flush state in the correct order. |
44 | | - |
45 | | -Architecture rule: process entrypoints should stay thin; cross-service wiring belongs in the orchestration layer, not in leaf crates. |
46 | | - |
47 | | -### 2. Client/API ingress |
48 | | - |
49 | | -Owned primarily by `magicblock-aperture` plus admin/TUI support crates. |
50 | | - |
51 | | -Responsibilities: |
52 | | - |
53 | | -- expose Solana-compatible JSON-RPC and websocket/pubsub behavior, |
54 | | -- accept transactions and simulations, |
55 | | -- serve account/ledger/status reads, |
56 | | -- trigger just-in-time account availability work for local misses, |
57 | | -- forward validator events to clients/subscribers. |
58 | | - |
59 | | -Architecture rule: the RPC layer should route work to account sync and execution services; it should not duplicate execution, delegation, or commit protocol logic. Keep per-request work lean and avoid blocking critical request paths. |
60 | | - |
61 | | -### 3. Account synchronization |
62 | | - |
63 | | -Owned primarily by `magicblock-chainlink`, `magicblock-account-cloner`, and `magicblock-accounts`. |
64 | | - |
65 | | -Responsibilities: |
66 | | - |
67 | | -- determine whether required accounts are delegated, undelegated/read-only, fee-payers, programs, or missing/stale, |
68 | | -- fetch base-layer account data and delegation metadata, |
69 | | -- subscribe to remote changes where needed, |
70 | | -- materialize local account/program state, |
71 | | -- provide account availability to RPC and transaction execution, |
72 | | -- hand scheduled commit work toward settlement. |
73 | | - |
74 | | -Architecture rule: this layer prepares local state for execution. It should not decide post-execution account access rules; those belong to the execution/SVM path. Avoid fetch amplification, duplicate clone work, subscription churn, and unnecessary serialization in account availability paths. |
75 | | - |
76 | | -### 4. Transaction execution |
77 | | - |
78 | | -Owned primarily by `magicblock-processor`, `magicblock-core`, the local storage crates, and the forked SVM dependency. |
79 | | - |
80 | | -Responsibilities: |
81 | | - |
82 | | -- receive processable transactions, |
83 | | -- acquire account locks, |
84 | | -- schedule work onto executors, |
85 | | -- run SVM execution, |
86 | | -- enforce MagicBlock access validation, |
87 | | -- commit local account changes, |
88 | | -- write ledger/status records, |
89 | | -- emit account, transaction, slot, and replication events. |
| 10 | + +-------> magicblock-runtime image <-------+ |
| 11 | + | |
| 12 | +mbv-verifier --> Engine<Follower> + replicator --+ |
90 | 13 |
|
91 | | -Architecture rule: execution must preserve the writable-account invariant and avoid mixing scheduler/account-lock concerns with RPC or commit-delivery concerns. It must also preserve scheduler/executor parallelism and avoid avoidable latency, contention, allocation, or I/O regressions in the hot path. |
92 | | - |
93 | | -### 5. Local persistence |
94 | | - |
95 | | -Owned primarily by `magicblock-accounts-db` and `magicblock-ledger`. |
96 | | - |
97 | | -Responsibilities: |
98 | | - |
99 | | -- store local account state, |
100 | | -- index accounts for execution/RPC, |
101 | | -- support snapshots/maintenance, |
102 | | -- store transaction, status, block, address-signature, and blockhash history, |
103 | | -- support recovery and user-visible RPC history. |
104 | | - |
105 | | -Architecture rule: maintenance operations that can race execution must be coordinated with scheduler pausing. |
106 | | - |
107 | | -### 6. Base-layer settlement |
108 | | - |
109 | | -Owned primarily by `magicblock-program`, `magicblock-magic-program-api`, `magicblock-committor-service`, `magicblock-committor-program`, `magicblock-table-mania`, and `magicblock-rpc-client`. |
110 | | - |
111 | | -Responsibilities: |
112 | | - |
113 | | -- let programs schedule commits, commit-and-undelegate operations, intent bundles, and Magic Actions, |
114 | | -- persist and recover pending settlement work, |
115 | | -- build valid base-layer transactions, |
116 | | -- handle address lookup tables and large changesets, |
117 | | -- send/confirm base-layer transactions, |
118 | | -- keep local lifecycle state consistent with scheduled undelegation. |
119 | | - |
120 | | -Architecture rule: Magic Program instructions schedule intent; validator services realize that intent on the base layer. |
121 | | - |
122 | | -### 7. Background services |
123 | | - |
124 | | -Owned by task scheduler, replicator, metrics, admin, and shared service crates. |
125 | | - |
126 | | -Responsibilities: |
127 | | - |
128 | | -- execute scheduled program tasks, |
129 | | -- replicate primary output to replicas, |
130 | | -- expose metrics/admin/operator hooks, |
131 | | -- provide reusable service infrastructure. |
132 | | - |
133 | | -Architecture rule: background services should integrate through shared channels/service APIs rather than reaching through unrelated crate internals. |
134 | | - |
135 | | -## Important interaction patterns |
136 | | - |
137 | | -### Transaction submission path |
138 | | - |
139 | | -```text |
140 | | -RPC/router ingress |
141 | | - -> account synchronization ensures required accounts exist locally |
142 | | - -> processor scheduler locks accounts |
143 | | - -> executor runs SVM |
144 | | - -> AccountsDb and Ledger persist results |
145 | | - -> events notify RPC subscriptions, metrics, replication, and other consumers |
| 14 | +mbv ------> Magic Domain Program over base-layer RPC |
| 15 | +mbv-tui --> leader RPC and websocket endpoints |
146 | 16 | ``` |
147 | 17 |
|
148 | | -### First use of delegated state |
149 | | - |
150 | | -```text |
151 | | -base-layer delegation exists |
152 | | - -> ER read/transaction needs account |
153 | | - -> account sync fetches account + delegation metadata |
154 | | - -> cloner installs local representation |
155 | | - -> processor can execute valid transactions against it |
156 | | -``` |
| 18 | +## Process roles |
157 | 19 |
|
158 | | -### Commit / undelegation path |
| 20 | +`mbv-leader` owns all leader-only service orchestration and orderly shutdown. |
| 21 | +Unexpected engine service termination is process-fatal. Magic Domain Program |
| 22 | +registration and unregistration are deliberately absent from its lifecycle. |
159 | 23 |
|
160 | | -```text |
161 | | -program invokes Magic Program in ER |
162 | | - -> MagicContext records scheduled intent |
163 | | - -> validator-side processing picks up intent |
164 | | - -> committor builds/sends base-layer transaction(s) |
165 | | - -> commit keeps delegation active OR undelegation returns ownership after settlement |
166 | | -``` |
| 24 | +`mbv-verifier` owns only the follower engine and replication client. It must |
| 25 | +not start leader RPC, cloning, settlement, scheduling, or admin services. It |
| 26 | +does own a process-lifetime metrics endpoint, which remains available while |
| 27 | +`ShutdownReason::RestartRequired` closes and reopens the engine after a |
| 28 | +snapshot has been staged; other unexpected exits are fatal. |
167 | 29 |
|
168 | | -### Startup path |
| 30 | +`mbv` and `mbv-tui` are out-of-process operator clients. The former owns |
| 31 | +manual Magic Domain Program transactions, while the latter observes compatible |
| 32 | +RPC/websocket endpoints. |
169 | 33 |
|
170 | | -```text |
171 | | -load config |
172 | | - -> open ledger/accounts storage |
173 | | - -> initialize services |
174 | | - -> recover persisted work |
175 | | - -> replay/repair local state where configured |
176 | | - -> enter primary or replica execution mode |
177 | | -``` |
| 34 | +## Shared execution image |
178 | 35 |
|
179 | | -### Shutdown path |
| 36 | +`magicblock-runtime` is the authoritative builder for the Keeper image used by both |
| 37 | +engine roles. Native builtins, configured BPF programs, and genesis accounts |
| 38 | +must remain shared here to prevent execution drift. Role-specific storage, |
| 39 | +replication, and service lifecycle stay in the owning binaries. |
180 | 40 |
|
181 | | -```text |
182 | | -cancel services |
183 | | - -> protect/finish in-flight work where required |
184 | | - -> join threads/runtimes |
185 | | - -> flush persistent stores |
186 | | -``` |
| 41 | +## Performance boundaries |
187 | 42 |
|
188 | | -## Boundaries .agents should preserve |
| 43 | +Execution, current AccountsDb/ledger persistence, and TCP replication live in |
| 44 | +the sibling `../engine` workspace. Leader-side account materialization is owned |
| 45 | +by `magicblock-chainlink`; settlement is owned by the committor crates; RPC is |
| 46 | +owned by `magicblock-aperture`. Keep operator tooling and process setup off |
| 47 | +transaction-critical paths. |
189 | 48 |
|
190 | | -- **RPC ingress is not the protocol source of truth.** It should call into account sync, execution, and storage layers. |
191 | | -- **Account synchronization is not transaction execution.** It prepares accounts; execution validates and commits changes. |
192 | | -- **Magic Program scheduling is not base-layer settlement.** It records intent; committor services deliver it. |
193 | | -- **Local persistence is shared infrastructure.** Coordinate maintenance with execution. |
194 | | -- **Replication observes/replays validator output.** Do not make primary and replica modes accidentally diverge. |
195 | | -- **Crate-specific details belong in crate docs.** Keep this file focused on cross-crate architecture. |
196 | | -- **Performance is part of the architecture contract.** Do not move heavy work into RPC, account sync, scheduler/executor, persistence, or settlement hot paths without an explicit justification and mitigation plan. |
197 | | -- **Security boundaries must remain explicit between layers.** RPC ingress handles untrusted input and must not become a path that bypasses execution/SVM validation or account-sync correctness. |
| 49 | +The deprecated `magicblock-ledger` remains only for leader historical RPC |
| 50 | +fallback during migration. |
0 commit comments