Skip to content

Commit 2a6fb17

Browse files
committed
feat: add config field registry and migration framework
Registry auto-discovers all 217 config fields via reflection and provides introspection by key, env var, section, hot-reload status, and per-mode defaults. Enrichments add curated descriptions, units, and runtime-reload metadata for downstream consumers (CRD validation, CLI help, documentation generation). Migration framework supports sequential version upgrades with chain validation, diagnostics capture, and post-migration validation.
1 parent 3b336eb commit 2a6fb17

6 files changed

Lines changed: 1614 additions & 5 deletions

File tree

enrichments.go

Lines changed: 387 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,387 @@
1+
package seiconfig
2+
3+
// DefaultEnrichments returns the curated field metadata for every field
4+
// where description, unit, hot-reload, or deprecation information is known.
5+
// Call registry.EnrichAll(DefaultEnrichments()) after BuildRegistry().
6+
func DefaultEnrichments() map[string][]FieldOption {
7+
return map[string][]FieldOption{
8+
// ---------------------------------------------------------------
9+
// Top-level
10+
// ---------------------------------------------------------------
11+
"version": {
12+
WithDescription("Config schema version. Set by tooling, not operators."),
13+
},
14+
"mode": {
15+
WithDescription("Node operating mode: validator, full, seed, archive, rpc, indexer."),
16+
},
17+
18+
// ---------------------------------------------------------------
19+
// Chain
20+
// ---------------------------------------------------------------
21+
"chain.chain_id": {
22+
WithDescription("The network chain ID. Sourced from genesis.json at init time."),
23+
},
24+
"chain.moniker": {
25+
WithDescription("A human-readable name for this node, used in P2P and logging."),
26+
},
27+
"chain.min_gas_prices": {
28+
WithDescription("Minimum gas prices a validator will accept for processing a transaction."),
29+
},
30+
"chain.halt_height": {
31+
WithDescription("Block height at which the node will gracefully halt. 0 disables."),
32+
WithUnit("blocks"),
33+
},
34+
"chain.halt_time": {
35+
WithDescription("Minimum block time (Unix seconds) at which the node will halt. 0 disables."),
36+
WithUnit("seconds"),
37+
},
38+
"chain.min_retain_blocks": {
39+
WithDescription("Minimum block height offset from current for Tendermint block pruning. 0 keeps all."),
40+
WithUnit("blocks"),
41+
},
42+
"chain.inter_block_cache": {
43+
WithDescription("Enable inter-block caching for improved read performance."),
44+
},
45+
"chain.concurrency_workers": {
46+
WithDescription("Number of workers for concurrent transaction execution. -1 for unlimited."),
47+
},
48+
"chain.occ_enabled": {
49+
WithDescription("Enable optimistic concurrency control for transaction processing."),
50+
},
51+
52+
// ---------------------------------------------------------------
53+
// Network — RPC
54+
// ---------------------------------------------------------------
55+
"network.rpc.listen_address": {
56+
WithDescription("TCP or UNIX socket address for the Tendermint RPC server."),
57+
WithHotReload(),
58+
},
59+
"network.rpc.cors_allowed_origins": {
60+
WithDescription("Origins allowed for cross-domain requests. '*' allows all."),
61+
WithHotReload(),
62+
},
63+
"network.rpc.unsafe": {
64+
WithDescription("Enable unsafe RPC commands like /dial-persistent-peers."),
65+
},
66+
"network.rpc.max_open_connections": {
67+
WithDescription("Maximum simultaneous connections (including WebSocket). 0 for unlimited."),
68+
WithUnit("connections"),
69+
WithHotReload(),
70+
},
71+
"network.rpc.timeout_broadcast_tx_commit": {
72+
WithDescription("How long to wait for a tx to be committed during /broadcast_tx_commit."),
73+
},
74+
"network.rpc.max_body_bytes": {
75+
WithDescription("Maximum size of request body."),
76+
WithUnit("bytes"),
77+
},
78+
"network.rpc.lag_threshold": {
79+
WithDescription("Block lag threshold for the /lag_status health endpoint."),
80+
WithUnit("blocks"),
81+
WithHotReload(),
82+
},
83+
84+
// ---------------------------------------------------------------
85+
// Network — P2P
86+
// ---------------------------------------------------------------
87+
"network.p2p.listen_address": {
88+
WithDescription("Address to listen for incoming P2P connections."),
89+
},
90+
"network.p2p.external_address": {
91+
WithDescription("Address to advertise to peers for them to dial."),
92+
},
93+
"network.p2p.persistent_peers": {
94+
WithDescription("Comma-separated list of node IDs to maintain persistent connections to."),
95+
WithHotReload(),
96+
},
97+
"network.p2p.max_connections": {
98+
WithDescription("Maximum connected peers (inbound + outbound)."),
99+
WithUnit("connections"),
100+
},
101+
"network.p2p.pex": {
102+
WithDescription("Enable the peer exchange reactor for peer discovery."),
103+
},
104+
"network.p2p.allow_duplicate_ip": {
105+
WithDescription("Allow multiple peers from the same IP address."),
106+
},
107+
"network.p2p.send_rate": {
108+
WithDescription("Rate at which packets can be sent per connection."),
109+
WithUnit("bytes/sec"),
110+
},
111+
"network.p2p.recv_rate": {
112+
WithDescription("Rate at which packets can be received per connection."),
113+
WithUnit("bytes/sec"),
114+
},
115+
116+
// ---------------------------------------------------------------
117+
// Consensus
118+
// ---------------------------------------------------------------
119+
"consensus.create_empty_blocks": {
120+
WithDescription("Whether to create blocks even when there are no transactions."),
121+
},
122+
"consensus.gossip_transaction_key_only": {
123+
WithDescription("Gossip only transaction hashes instead of full transactions."),
124+
},
125+
"consensus.peer_gossip_sleep_duration": {
126+
WithDescription("Sleep duration between rounds of peer gossip."),
127+
},
128+
"consensus.double_sign_check_height": {
129+
WithDescription("Number of past blocks to check for double-signing. 0 disables."),
130+
WithUnit("blocks"),
131+
},
132+
"consensus.unsafe_commit_timeout_override": {
133+
WithDescription("Unsafe override for the Commit timeout consensus parameter."),
134+
},
135+
136+
// ---------------------------------------------------------------
137+
// Mempool
138+
// ---------------------------------------------------------------
139+
"mempool.size": {
140+
WithDescription("Maximum number of transactions in the mempool."),
141+
WithUnit("transactions"),
142+
WithHotReload(),
143+
},
144+
"mempool.max_txs_bytes": {
145+
WithDescription("Total size limit for all transactions in the mempool."),
146+
WithUnit("bytes"),
147+
},
148+
"mempool.max_tx_bytes": {
149+
WithDescription("Maximum size of a single transaction."),
150+
WithUnit("bytes"),
151+
},
152+
"mempool.ttl_duration": {
153+
WithDescription("Maximum time a transaction can remain in the mempool."),
154+
},
155+
"mempool.ttl_num_blocks": {
156+
WithDescription("Maximum number of blocks a transaction can remain in the mempool."),
157+
WithUnit("blocks"),
158+
},
159+
160+
// ---------------------------------------------------------------
161+
// State Sync
162+
// ---------------------------------------------------------------
163+
"state_sync.enable": {
164+
WithDescription("Enable state sync to bootstrap from snapshots instead of replaying blocks."),
165+
},
166+
"state_sync.trust_height": {
167+
WithDescription("Height of a trusted block for light client verification."),
168+
WithUnit("blocks"),
169+
},
170+
"state_sync.trust_hash": {
171+
WithDescription("Hash of the trusted block (hex-encoded)."),
172+
},
173+
"state_sync.trust_period": {
174+
WithDescription("Trust period for light client verification. Should be < unbonding period."),
175+
},
176+
"state_sync.use_local_snapshot": {
177+
WithDescription("Use a local snapshot for state sync instead of discovering from peers."),
178+
},
179+
180+
// ---------------------------------------------------------------
181+
// Storage
182+
// ---------------------------------------------------------------
183+
"storage.db_backend": {
184+
WithDescription("Database backend: goleveldb, cleveldb, boltdb, rocksdb."),
185+
},
186+
"storage.db_path": {
187+
WithDescription("Path to the database directory relative to the home directory."),
188+
},
189+
"storage.pruning": {
190+
WithDescription("Pruning strategy: default, nothing, everything, custom."),
191+
},
192+
"storage.pruning_keep_recent": {
193+
WithDescription("Number of recent states to keep when pruning strategy is 'custom'."),
194+
},
195+
"storage.pruning_interval": {
196+
WithDescription("Block interval between pruning operations when strategy is 'custom'."),
197+
WithUnit("blocks"),
198+
},
199+
"storage.snapshot_interval": {
200+
WithDescription("Block interval for state sync snapshot creation. 0 disables."),
201+
WithUnit("blocks"),
202+
},
203+
"storage.snapshot_keep_recent": {
204+
WithDescription("Number of recent snapshots to keep. 0 keeps all."),
205+
},
206+
"storage.compaction_interval": {
207+
WithDescription("Interval between forced LevelDB compaction. 0 disables."),
208+
WithUnit("seconds"),
209+
},
210+
211+
// Storage — State Commit
212+
"storage.state_commit.enable": {
213+
WithDescription("Enable SeiDB state-commit layer (replaces IAVL with MemIAVL)."),
214+
},
215+
"storage.state_commit.write_mode": {
216+
WithDescription("EVM write routing: cosmos_only, dual_write, split_write, evm_only."),
217+
},
218+
"storage.state_commit.read_mode": {
219+
WithDescription("EVM read routing: cosmos_only, evm_first, split_read."),
220+
},
221+
222+
// Storage — State Store
223+
"storage.state_store.enable": {
224+
WithDescription("Enable SeiDB state-store for historical queries."),
225+
},
226+
"storage.state_store.backend": {
227+
WithDescription("State store backend: pebbledb, rocksdb."),
228+
},
229+
"storage.state_store.keep_recent": {
230+
WithDescription("Number of recent versions to keep. 0 keeps all."),
231+
WithUnit("versions"),
232+
},
233+
"storage.state_store.prune_interval_seconds": {
234+
WithDescription("Interval between state store pruning operations."),
235+
WithUnit("seconds"),
236+
},
237+
238+
// ---------------------------------------------------------------
239+
// Tx Index
240+
// ---------------------------------------------------------------
241+
"tx_index.indexer": {
242+
WithDescription("Transaction indexer backends. Options: null, kv, psql."),
243+
},
244+
245+
// ---------------------------------------------------------------
246+
// EVM
247+
// ---------------------------------------------------------------
248+
"evm.http_enabled": {
249+
WithDescription("Enable the EVM JSON-RPC HTTP server."),
250+
},
251+
"evm.http_port": {
252+
WithDescription("Port for the EVM JSON-RPC HTTP server."),
253+
},
254+
"evm.ws_enabled": {
255+
WithDescription("Enable the EVM JSON-RPC WebSocket server."),
256+
},
257+
"evm.ws_port": {
258+
WithDescription("Port for the EVM JSON-RPC WebSocket server."),
259+
},
260+
"evm.simulation_gas_limit": {
261+
WithDescription("Maximum gas limit for eth_call and eth_estimateGas simulations."),
262+
WithUnit("gas"),
263+
},
264+
"evm.cors_origins": {
265+
WithDescription("CORS allowed origins for EVM RPC, comma-separated. '*' allows all."),
266+
WithHotReload(),
267+
},
268+
"evm.max_tx_pool_txs": {
269+
WithDescription("Maximum transactions to pull from the mempool for EVM."),
270+
WithUnit("transactions"),
271+
},
272+
"evm.deny_list": {
273+
WithDescription("RPC methods that should immediately fail (e.g. debug_traceBlockByNumber)."),
274+
WithHotReload(),
275+
},
276+
"evm.max_log_no_block": {
277+
WithDescription("Maximum logs returned when block range is open-ended."),
278+
},
279+
"evm.max_blocks_for_log": {
280+
WithDescription("Maximum block range for eth_getLogs queries."),
281+
WithUnit("blocks"),
282+
},
283+
"evm.max_concurrent_trace_calls": {
284+
WithDescription("Maximum concurrent debug_trace calls. 0 for unlimited."),
285+
},
286+
"evm.max_trace_lookback_blocks": {
287+
WithDescription("Maximum blocks to look back for tracing. -1 for unlimited (archive)."),
288+
WithUnit("blocks"),
289+
},
290+
"evm.trace_timeout": {
291+
WithDescription("Timeout for each trace call."),
292+
},
293+
"evm.worker_pool_size": {
294+
WithDescription("Number of workers in the EVM RPC worker pool. 0 for default."),
295+
},
296+
297+
// ---------------------------------------------------------------
298+
// API
299+
// ---------------------------------------------------------------
300+
"api.rest.enable": {
301+
WithDescription("Enable the Cosmos REST API server."),
302+
},
303+
"api.rest.address": {
304+
WithDescription("Address for the REST API server."),
305+
},
306+
"api.rest.swagger": {
307+
WithDescription("Enable Swagger documentation endpoint."),
308+
},
309+
"api.grpc.enable": {
310+
WithDescription("Enable the gRPC server."),
311+
},
312+
"api.grpc.address": {
313+
WithDescription("Address for the gRPC server."),
314+
},
315+
"api.grpc_web.enable": {
316+
WithDescription("Enable the gRPC-Web proxy server."),
317+
},
318+
"api.grpc_web.address": {
319+
WithDescription("Address for the gRPC-Web server."),
320+
},
321+
322+
// ---------------------------------------------------------------
323+
// Metrics
324+
// ---------------------------------------------------------------
325+
"metrics.enabled": {
326+
WithDescription("Enable Prometheus metrics collection and serving."),
327+
},
328+
"metrics.prometheus_listen_addr": {
329+
WithDescription("Address for the Prometheus metrics endpoint."),
330+
},
331+
"metrics.namespace": {
332+
WithDescription("Metrics namespace prefix for all emitted metrics."),
333+
},
334+
"metrics.prometheus_retention_time": {
335+
WithDescription("How long to retain Prometheus metrics in memory."),
336+
WithUnit("seconds"),
337+
},
338+
339+
// ---------------------------------------------------------------
340+
// Logging
341+
// ---------------------------------------------------------------
342+
"logging.level": {
343+
WithDescription("Log level: debug, info, warn, error."),
344+
WithHotReload(),
345+
},
346+
"logging.format": {
347+
WithDescription("Log format: plain, text, json."),
348+
},
349+
350+
// ---------------------------------------------------------------
351+
// WASM
352+
// ---------------------------------------------------------------
353+
"wasm.query_gas_limit": {
354+
WithDescription("Maximum gas for CosmWasm smart query execution."),
355+
WithUnit("gas"),
356+
},
357+
"wasm.lru_size": {
358+
WithDescription("Size of the CosmWasm compiled module LRU cache."),
359+
},
360+
361+
// ---------------------------------------------------------------
362+
// Giga Executor
363+
// ---------------------------------------------------------------
364+
"giga_executor.enabled": {
365+
WithDescription("Enable the Giga parallel execution engine."),
366+
},
367+
"giga_executor.occ_enabled": {
368+
WithDescription("Enable OCC within the Giga executor."),
369+
},
370+
371+
// ---------------------------------------------------------------
372+
// Self-Remediation
373+
// ---------------------------------------------------------------
374+
"self_remediation.p2p_no_peers_restart_window_seconds": {
375+
WithDescription("Restart if no P2P peers available for this duration. 0 disables."),
376+
WithUnit("seconds"),
377+
},
378+
"self_remediation.blocks_behind_threshold": {
379+
WithDescription("Restart if node falls this many blocks behind. 0 disables."),
380+
WithUnit("blocks"),
381+
},
382+
"self_remediation.restart_cooldown_seconds": {
383+
WithDescription("Minimum time between self-remediation restarts."),
384+
WithUnit("seconds"),
385+
},
386+
}
387+
}

0 commit comments

Comments
 (0)