Barretenberg
The ZK-SNARK library at the core of Aztec
Loading...
Searching...
No Matches
wsdb_ipc_server.cpp
Go to the documentation of this file.
6#include "barretenberg/wsdb/generated/wsdb_ipc_server.hpp"
9#include "ipc_runtime/ipc_server.hpp"
10#include "ipc_runtime/serve_helper.hpp"
11#include "ipc_runtime/signal_handlers.hpp"
12
13#include <cstdint>
14#include <iostream>
15#include <memory>
16#include <sstream>
17#include <string>
18#include <unordered_map>
19#include <vector>
20
21namespace bb::wsdb {
22
23using namespace bb::world_state;
24using namespace bb::crypto::merkle_tree;
25
26// ---------------------------------------------------------------------------
27// Simple JSON-like parsing for config maps
28// Parses "{0:1024,1:2048,...}" into unordered_map<uint32_t, uint64_t>
29// ---------------------------------------------------------------------------
30
31static std::unordered_map<world_state::MerkleTreeId, uint64_t> parse_tree_uint64_map(const std::string& json)
32{
34 if (json.empty()) {
35 return result;
36 }
37 std::string cleaned;
38 for (char c : json) {
39 if (c != '{' && c != '}' && c != ' ') {
40 cleaned += c;
41 }
42 }
43 std::istringstream ss(cleaned);
44 std::string pair;
45 while (std::getline(ss, pair, ',')) {
46 auto colon_pos = pair.find(':');
47 if (colon_pos != std::string::npos) {
48 auto key = static_cast<world_state::MerkleTreeId>(std::stoi(pair.substr(0, colon_pos)));
49 auto value = static_cast<uint64_t>(std::stoull(pair.substr(colon_pos + 1)));
50 result[key] = value;
51 }
52 }
53 return result;
54}
55
56static std::unordered_map<world_state::MerkleTreeId, uint32_t> parse_tree_uint32_map(const std::string& json)
57{
59 if (json.empty()) {
60 return result;
61 }
62 auto u64_map = parse_tree_uint64_map(json);
63 for (const auto& [k, v] : u64_map) {
64 result[k] = static_cast<uint32_t>(v);
65 }
66 return result;
67}
68
69static std::unordered_map<world_state::MerkleTreeId, index_t> parse_tree_index_map(const std::string& json)
70{
72 if (json.empty()) {
73 return result;
74 }
75 auto u64_map = parse_tree_uint64_map(json);
76 for (const auto& [k, v] : u64_map) {
77 result[k] = static_cast<index_t>(v);
78 }
79 return result;
80}
81
82// ---------------------------------------------------------------------------
83// Parse prefilled public data from JSON: [["slot_hex","value_hex"],...]
84// Each hex string is a 64-char (32-byte) hex-encoded field element.
85// ---------------------------------------------------------------------------
86
87static fr hex_to_fr(const std::string& hex)
88{
89 std::string cleaned = hex;
90 if (cleaned.size() >= 2 && cleaned[0] == '0' && (cleaned[1] == 'x' || cleaned[1] == 'X')) {
91 cleaned = cleaned.substr(2);
92 }
93 return fr(cleaned);
94}
95
96static std::vector<PublicDataLeafValue> parse_prefilled_public_data(const std::string& json)
97{
99 if (json.empty() || json == "[]") {
100 return result;
101 }
102
103 // Simple state-machine parser for [["hex","hex"],["hex","hex"],...]
104 std::vector<std::string> hex_values;
105 std::string current;
106 bool in_string = false;
107
108 for (char c : json) {
109 if (c == '"') {
110 in_string = !in_string;
111 } else if (in_string) {
112 current += c;
113 } else if ((c == ',' || c == ']') && !current.empty()) {
114 hex_values.push_back(std::move(current));
115 current.clear();
116 }
117 }
118
119 // hex_values should have pairs: slot, value, slot, value, ...
120 if (hex_values.size() % 2 != 0) {
121 std::cerr << "Warning: odd number of hex values in prefilled public data, ignoring last" << '\n';
122 }
123 for (size_t i = 0; i + 1 < hex_values.size(); i += 2) {
124 result.emplace_back(hex_to_fr(hex_values[i]), hex_to_fr(hex_values[i + 1]));
125 }
126 return result;
127}
128
129// ---------------------------------------------------------------------------
130// IPC server execution
131// ---------------------------------------------------------------------------
132
133int execute_wsdb_server(const std::string& input_path,
134 const std::string& data_dir,
135 const std::string& tree_heights_json,
136 const std::string& tree_prefill_json,
137 const std::string& map_sizes_json,
138 uint32_t threads,
139 uint32_t initial_header_generator_point,
140 const std::string& prefilled_public_data_json,
141 uint64_t genesis_timestamp,
142 size_t request_ring_size,
143 size_t response_ring_size)
144{
145 const uint64_t DEFAULT_MAP_SIZE = 1024UL * 1024;
146
147 // Parse config
148 auto tree_height = parse_tree_uint32_map(tree_heights_json);
149 auto tree_prefill = parse_tree_index_map(tree_prefill_json);
150
157 };
158 if (!map_sizes_json.empty()) {
159 auto parsed = parse_tree_uint64_map(map_sizes_json);
160 for (const auto& [k, v] : parsed) {
161 map_size[k] = v;
162 }
163 }
164
165 // Parse prefilled public data: JSON array of ["slot_hex","value_hex"] pairs
166 std::vector<PublicDataLeafValue> prefilled_public_data;
167 if (!prefilled_public_data_json.empty()) {
168 prefilled_public_data = parse_prefilled_public_data(prefilled_public_data_json);
169 std::cerr << "Parsed " << prefilled_public_data.size() << " prefilled public data entries" << '\n';
170 }
171
172 // Create WorldState
173 std::cerr << "Creating WorldState at " << data_dir << " with " << threads << " threads" << '\n';
174 auto ws = std::make_unique<WorldState>(threads,
175 data_dir,
176 map_size,
177 tree_height,
178 tree_prefill,
179 prefilled_public_data,
180 initial_header_generator_point,
181 genesis_timestamp);
182
183 WsdbRequest request{ .world_state = *ws };
184
185 // Pick UDS vs MPSC-SHM by path suffix; install the runtime's default
186 // lifecycle signal handlers (SIGTERM/SIGINT → request_shutdown, SIGBUS/SIGSEGV
187 // → close+exit, plus parent-death monitoring via prctl/kqueue).
188 ipc::ServerOptions opts;
189 opts.max_shm_clients = 2; // TS backend (client 0) + AVM binary (client 1)
190 opts.shm_request_ring_size = request_ring_size;
191 opts.shm_response_ring_size = response_ring_size;
192 auto server = ipc::make_server(input_path, opts);
193 if (!server) {
194 std::cerr << "Error: --input path must end with .sock or .shm: " << input_path << '\n';
195 return 1;
196 }
197 std::cerr << "aztec-wsdb listening on " << input_path << '\n';
198 ipc::install_default_signal_handlers(*server);
199
200 if (!server->listen()) {
201 std::cerr << "Error: Could not start IPC server" << '\n';
202 return 1;
203 }
204
205 std::cerr << "aztec-wsdb IPC server ready" << '\n';
206
207 auto handler = make_wsdb_handler(request);
208 server->run([&handler](int /*client_id*/, std::span<const uint8_t> raw) {
209 return handler(std::vector<uint8_t>(raw.begin(), raw.end()));
210 });
211
212 server->close();
213 return 0;
214}
215
216} // namespace bb::wsdb
const uint64_t DEFAULT_MAP_SIZE
@ L1_TO_L2_MESSAGE_TREE
Definition types.hpp:23
int execute_wsdb_server(const std::string &input_path, const std::string &data_dir, const std::string &tree_heights_json, const std::string &tree_prefill_json, const std::string &map_sizes_json, uint32_t threads, uint32_t initial_header_generator_point, const std::string &prefilled_public_data_json, uint64_t genesis_timestamp, size_t request_ring_size, size_t response_ring_size)
Start the aztec-wsdb IPC server.
field< Bn254FrParams > fr
Definition fr.hpp:155
constexpr decltype(auto) get(::tuplet::tuple< T... > &&t) noexcept
Definition tuple.hpp:13
pair(A, B) -> pair< unwrap_ref_decay_t< A >, unwrap_ref_decay_t< B > >
world_state::WorldState & world_state
Non-template handler declarations for the wsdb service.
Service-level context passed to every wsdb handler.