-
Notifications
You must be signed in to change notification settings - Fork 18
Expand file tree
/
Copy pathdefaults.conf
More file actions
718 lines (591 loc) · 32.2 KB
/
Copy pathdefaults.conf
File metadata and controls
718 lines (591 loc) · 32.2 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
# Start a stand-alone node.
# In this mode node
# 1. does not connect to any network
# 2. `casper.genesis-ceremony.ceremony-master-mode` = true
# 3. `required-signatures` = 0
# for node to be able to create and approve genesis block if its not available
standalone = false
# Auto-propose mode: when enabled, the node attempts to propose a block
# immediately after every successful deploy submission, regardless of
# heartbeat cadence or synchrony gates. Intended for single-node dev
# scenarios; in multi-validator deployments use the heartbeat proposer
# (casper.heartbeat.enabled) instead so cross-validator coordination
# applies.
autopropose = false
protocol-server {
# ID of the RChain network.
# Node shall only accept messages with this `network-id`.
# This is not Casper construct so it is not in `casper` section.
# This is used to filter out messages originated from different networks to lower down the load.
network-id = "testnet"
# Host name or IP address of this node. Will be used by peers to reach this node, so by default have to be public
# address.
# If this attribute is not set then node will try to guess its public IP address.
# Note: actual protocol server is binded to "0.0.0.0"
# host = localhost
# Allow `host` to be a non publicly accessible address (RFC1918 ranges,
# localhost, etc.). Required for private-network / docker-bridge / LAN
# installations where the protocol-server binds to an address that other
# nodes will see only via NAT or compose-internal DNS. Public mainnet
# deployments should keep this `false` so nodes refuse to advertise
# unreachable peer addresses.
allow-private-addresses = false
# When the configured RChain Protocol port and/or Kademlia port are
# already bound, fall back to OS-assigned random ports rather than
# exiting. Useful for multi-node dev shards on the same host.
use-random-ports = false
# Re-resolve the node's public IP at runtime instead of caching it from
# startup. Enable on networks where the public address can change while
# the node is running (e.g. NAT relocation, dial-up).
dynamic-ip = false
# Disable UPnP port-mapping requests to the local NAT gateway. UPnP is
# used to open the Protocol/Kademlia ports automatically when the node
# is behind a residential NAT; disable on networks where UPnP is absent
# or restricted by policy.
no-upnp = false
# Port for the gRPC protocol server (block / deploy / packet exchange
# between peer nodes). Pair with peers-discovery.port for Kademlia.
port = 40400
# Maximum size of a single inbound gRPC unary message at the protocol
# server. Smaller than the streamed-block size below so per-message
# framing stays bounded; raise only if a non-block protocol message is
# rejected as oversized.
grpc-max-recv-message-size = 256K
# Maximum size of messages that can be received via streams
# This is effectively max size of a block
grpc-max-recv-stream-message-size = 256M
# Number of incoming RChain Protocol message consumers
# This should be high enough, as BlockMessage consumption can hang waiting for block processing lock and
# occupy one consumer.
# The very minimum should be {number of nodes} * {synchrony constraint}, which is enough to consume
# blocks proposed by peers simultaneously. Taking into account blocks are not the only protocol message,
# and blocks can be received as well via `requesting missing blocks` routine, it is recommended to
# make this number high. Upper bounded by the numer of messages (blocks are the biggest of them)
# node is able to keep in memory. Block size upper bound size is `max-stream-message-size`.
max-message-consumers = 400
# When `true`, this node refuses to serve state-snapshot exports to
# peers requesting Last-Finalized-State sync. Disable on edge / private
# nodes that should not bootstrap others; keep enabled on public peers
# so new joiners can sync without replaying from genesis.
disable-state-exporter = false
}
protocol-client {
# Should be the same as server network ID.
network-id = ${protocol-server.network-id}
# Address of RNode to bootstrap from when connecting to a network.
# This should be provided by bootstrap node operator. You can bootstrap from any network peer.
# <node-id> is derived from TLS public key used to secure internode communications (see tls.key-path).
# To manually generate one the following command can be used
# ```openssl ec -text -in <path-to-tls-key>/node.key.pem | grep pub -A 5 | tail -n +2 | tr -d '\n[:space:]:' | \
# sed 's/^04//' | keccak-256sum -x -l | tr -d ' -' | tail -c 41```
# Example placeholder (replace with your shard's bootstrap address):
# rnode://<node-id>@<host>?protocol=<protocol-port>&discovery=<discovery-port>
bootstrap = "rnode://0000000000000000000000000000000000000000@127.0.0.1?protocol=40400&discovery=40404"
# Disable the node to start from Last Finalized State, instead it will start from genesis.
# If this is `true`, when a node without any data connecting to existing network, the node would start from
# genesis block and validate blocks from scratch. Otherwise, the node would start from last finalized block which
# can save a lot of time of validating all the history blocks.
disable-lfs = false
# Fan-out cap: when broadcasting a block / packet, the node randomly
# samples this many connected peers as the recipient set. Higher values
# improve gossip reach (faster propagation) at the cost of more
# outbound bandwidth and CPU per emit. Below ~10 increases stale-tip
# risk on large shards.
batch-max-connections = 20
# Default per-call timeout for outbound RChain Protocol RPCs (block
# request, has-block, etc.). Low values surface slow peers fast but
# increase retry churn on lossy networks.
network-timeout = 5 seconds
# Max message size for inbound gRPC messages on the client side
# (responses from peer servers). Mirrors the server-side limit unless
# overridden.
grpc-max-recv-message-size = ${protocol-server.grpc-max-recv-message-size}
# Chunk size used when streaming a large message (e.g. a block)
# outbound. Smaller chunks reduce per-message stall under packet loss
# but add framing overhead. Keep aligned with server-side stream
# capacity.
grpc-stream-chunk-size = 256K
}
peers-discovery {
# host name or IP address of this node
# If this attribute is not set then the node will try to guess its IP address
# host = localhost
# Port for the Kademlia DHT server (peer discovery / routing-table
# maintenance). Distinct from protocol-server.port which carries
# block/deploy traffic.
port = 40404
# How often the node performs a Kademlia FIND_NODE lookup to refresh
# its routing table and discover new peers. Lower values reduce
# stale-peer ratio on rapidly-changing networks; higher values reduce
# discovery traffic on stable shards.
lookup-interval = 20 seconds
# How often the node prunes connections that have failed liveness
# checks. Pairs with `heartbeat-batch-size` below.
cleanup-interval = 10 seconds
# Number of connections to check for being active at a time
# If there are thousands of nodes, we might want to not check all of them each time.
# One of strategies might be to check all connections with moderately low `check-stale-interval`
# We implement this by default, so `batch-size` is high
heartbeat-batch-size = 100
# Polling interval used at node startup while waiting for the first
# peer connection to be established before genesis-validator or
# ceremony-master logic can proceed. Lower values shorten cold-start
# time at the cost of busier polling loops.
init-wait-loop-interval = 1 seconds
}
api-server {
# Bind address for all API servers (gRPC + HTTP). `0.0.0.0` listens on
# every interface; bind to a specific address (e.g. `127.0.0.1`) to
# restrict access to local-only or a single NIC.
host = "0.0.0.0"
# Public gRPC API port — exposes deploy submission, block / DAG queries,
# finalization checks. Safe to expose externally with appropriate
# network ACL.
port-grpc-external = 40401
# Internal / privileged gRPC API port — exposes propose, validator
# operations, and other admin endpoints. Should NOT be exposed
# externally; bind via `host = 127.0.0.1` or firewall to validator
# operators only.
port-grpc-internal = 40402
# Maximum size of an inbound gRPC message at the API server (effectively
# the largest deploy this node will accept). Larger values support
# heavier Rholang contracts; smaller values constrain deploy abuse.
grpc-max-recv-message-size = 16M
# Public HTTP API port (REST endpoints, status JSON, /api/* routes).
# Read-only; safe to expose alongside port-grpc-external.
port-http = 40403
# Admin HTTP API port (block-store inspection, internal diagnostics).
# Privileged; do not expose externally.
port-admin-http = 40405
# Cap on how many blocks any single API call may load into memory.
# Prevents OOM from `getBlocks(depth=100000)` style requests. Raise
# only when serving operator-controlled tooling that needs deep walks.
max-blocks-limit = 100
# Enable the block-replay reporting API surface (`/api/explore-deploy`,
# event-log queries, cost reports). Disable on validators that should
# not serve read-heavy reporting traffic.
enable-reporting = true
# gRPC keep-alive PING interval. The server sends a PING after this
# idle period to detect half-open connections. 2h matches the typical
# NAT idle-timeout window; lower values increase liveness signal but
# add traffic.
keep-alive-time = 2 hours
# Timeout for the keep-alive PING response. If the peer doesn't ACK
# within this window after a PING, the server closes the connection.
keep-alive-timeout = 20 seconds
# Floor on client-configurable keep-alive intervals. Clients pinging
# more aggressively than this rate get their connection closed
# (defends the server against keep-alive flood).
permit-keep-alive-time = 5 minutes
# Max idle duration after which an otherwise-unused connection is
# gracefully terminated. Frees server-side resources held by stale
# clients without aggressive keep-alive churn.
max-connection-idle = 1 hours
# Hard cap on connection lifetime. The server will gracefully drain
# any RPC older than this and close the connection. Forces periodic
# reconnect cycles which are useful for upstream load-balancer
# rebalancing.
max-connection-age = 1 hours
# Grace window after max-connection-age fires, allowing in-flight RPCs
# to finish before forced cancellation. Set higher than the slowest
# expected RPC to avoid spurious cancellations during planned drains.
max-connection-age-grace = 1 hours
}
storage {
# Path to data directory. Depends on CLI `profile` option.
data-dir = ${default-data-dir}
}
tls {
# "Path to X.509 certificate for TLS. If file does not exist, certificate will be
# generated from PEM key located at `tls.key-path`.
certificate-path = ${storage.data-dir}/node.certificate.pem
# Path to private key for TLS. Elliptic curve secp256r1 key in PEM format is supported.
# If file does not exist, new key will be generated.
key-path = ${storage.data-dir}/node.key.pem
# Use a non-blocking secure-random source for TLS key generation.
# Default `false` uses the standard blocking source which gathers more
# entropy. Set `true` only on entropy-starved environments (containers,
# short-lived test rigs) where blocking startup is unacceptable; this
# reduces the cryptographic strength of the generated key.
secure-random-non-blocking = false
# Reserved for operator-managed TLS material outside the standard
# data-dir paths. Currently unused; retained for forward compatibility
# with planned out-of-tree certificate rotation.
custom-certificate-location = false
custom-key-location = false
}
casper {
# Block is considered as finalized if its fault tolerance is bigger then this value. For more info
# https://github.com/rchain/rchain/blob/dev/casper/src/main/scala/coop/rchain/casper/SafetyOracle.scala
fault-tolerance-threshold = 0.67
# Base16 encoding of the public key to use for signing a proposed blocks.
# Can be inferred from the private key for some signature algorithms.
# validator-public-key =
# Base16 encoding of the private key to use for signing a proposed blocks.
# It is not recommended to use in production since private key could be revealed through the process table.
# validator-private-key =
# Path to the base16 encoded private key to use for signing a proposed blocks.
# validator-private-key-path =
# Shard name written into PoS contract during genesis.
shard-name = root,
# ID of the parent shard. For root shard it's `/`. ID of the shard is `{parent-shard-id}/{shard-name}`.
# So for root named `root` shard ID is `/root`, for its child shard `rootchild` shard ID is `/root/rootchild`.
parent-shard-id = /
# Interval of the casper loop to maintain requested blocks and missing dependent blocks
# in the node runtime, there is a loop which would fetch dependency of the missing dag and maintain
# requested blocks. See
# https://github.com/rchain/rchain/blob/43a1dfd90ec16a4a5c3b24e7d7aab8bc160ccb2b/node/src/main/scala/coop/rchain/node/NodeRuntime.scala#L746-L759
casper-loop-interval = 750 ms
# Timeout for the requested blocks
# all requests sent to request blocks is put into a data structure for maintain.
requested-blocks-timeout = 240 seconds
# Finalization is called every `finalization-rate` blocks
finalization-rate = 1
# Enable background garbage collection for mergeable channels
# When enabled: Uses safe reachability-based GC (required for multi-parent mode)
# When disabled (default): Uses immediate deletion on finalization (legacy behavior)
enable-mergeable-channel-gc = true
# Interval for garbage collecting mergeable channels (only when GC enabled)
# Background process that safely deletes mergeable data when provably unreachable
mergeable-channels-gc-interval = 5 minutes
# Depth buffer for mergeable channels garbage collection (only when GC enabled)
# Additional safety margin beyond max-parent-depth before deleting data
mergeable-channels-gc-depth-buffer = 10
# Cap on parents per proposed block. The proposer normally selects one
# parent per bonded validator (via latest-message-per-validator), so
# this cap binds at shards larger than this value. CRITICAL: must be
# >= 3 when heartbeat is enabled — single-parent mode causes
# heartbeat empty blocks to fail InvalidParents validation when peers
# have newer blocks. Recommended: 3× shard size.
max-number-of-parents = 100
# Bound on how far back (in block-height terms) secondary parents are
# allowed to live relative to the main parent. Default i32::MAX
# disables the bound. Lower values reduce merge work for proposers on
# wide DAGs at the cost of dropping older parent justifications.
# See https://github.com/rchain/rchain/pull/2816 for the original
# rationale.
max-parent-depth = 2147483647
# Age threshold past which the node treats its known fork-choice tip as
# stale and requests fresh tips from peers. Higher values reduce
# tip-request gossip on idle networks; lower values tighten recovery
# from network partitions or peer outages.
fork-choice-stale-threshold = 10 minutes
# Polling interval for the staleness check above. Should be slightly
# larger than `fork-choice-stale-threshold` so the staleness flag
# reflects a stable state rather than triggering during the threshold
# boundary itself.
fork-choice-check-if-stale-interval = 11 minutes
# Cross-validator coordination gate. Each block must be justified by
# peer blocks; before proposing, the node checks whether the stake
# behind those justifications meets
# `synchrony-constraint-threshold * total-stake-of-other-validators`.
# 0 disables the check (every validator may propose any time —
# maximises liveness, increases sibling rate). > 0 forces validators
# to wait for peer progress before proposing — reduces siblings and
# tightens DAG width but can stall when peers are slow. 0.67 is the
# production safety value for honest-majority assumptions.
synchrony-constraint-threshold = 0
# Duration before synchrony recovery bypass becomes eligible.
# Longer values reduce false stall detection but delay recovery.
synchrony-recovery-stall-window = 60 seconds
# Cooldown between synchrony recovery bypass attempts.
synchrony-recovery-cooldown = 20 seconds
# Maximum times to bypass synchrony constraint per stall event.
# 0 = never bypass (validator can get permanently stuck).
synchrony-recovery-max-bypasses = 2
# Use finalized block as fallback baseline for synchrony calculation.
# Essential for preventing stalls when LFB is old.
synchrony-finalized-baseline-enabled = true
# Maximum distance from LFB for finalized baseline to be used.
# Larger values allow recovery on busier networks.
synchrony-finalized-baseline-max-distance = 2048
# Hard cap on user deploys per block. Adaptive deploy cap adjusts within this ceiling.
max-user-deploys-per-block = 32
# Hard cap on (latest_block_number - last_finalized_block_number) for
# this validator. If the gap exceeds this, propose is refused until
# finalization catches up. Protects against runaway DAG growth when
# finalization is stuck. Lower → tighter back-pressure, more refusals
# under transient finalizer slowness; higher → more tolerance for
# finality lag at the cost of larger memory / replay budgets.
height-constraint-threshold = 1000
# Round-robin peer-message dispatcher tunables. Still parsed and the
# struct is loaded into the runtime, but the dispatcher loop is not
# currently wired into the message-consumer path, so these knobs are
# inert at runtime. Retained for forward-compatibility with planned
# re-enablement; do not rely on changes here taking effect.
round-robin-dispatcher {
# Per-peer inbound queue depth before further messages from that peer
# are skipped (round-robin'd to other peers) until the queue drains.
max-peer-queue-size = 100
# Number of times the dispatcher may skip a peer for being above its
# queue cap before the peer is treated as "given up on" for the
# current scheduling round. 0 disables skip-counting.
give-up-after-skipped = 0
# Number of consecutive retry failures after which a peer connection
# is dropped entirely. 0 disables retry-based eviction.
drop-peer-after-retries = 0
}
# Genesis block variables
genesis-block-data {
# Directory holding genesis-ceremony inputs (bonds.txt, wallets.txt)
# and any auto-generated validator key files written when
# autogen-shard-size is used. Must be readable by the node process at
# startup; on first ceremony run it is also written into.
genesis-data-dir = ${storage.data-dir}/genesis
# Plain text file consisting of lines of the form `<pk> <stake>`,
# which defines the bond amounts for each validator at genesis.
# <pk> is the public key (in base-16 encoding) identifying the validator and <stake>
# is the amount they have bonded (an integer).
bonds-file = ${casper.genesis-block-data.genesis-data-dir}/bonds.txt
# Plain text file consisting of lines of the form `<algorithm> <pk> <balance>`,
# which defines the wallets that exist at genesis.
# <algorithm> is the algorithm used to verify signatures when using the wallet (one of ed25519 or secp256k1),
# <pk> is the public key (in base-16 encoding) identifying the wallet and <balance>
# is the balance in the wallet.
wallets-file = ${casper.genesis-block-data.genesis-data-dir}/wallets.txt
# Minimum bond accepted by the PoS contract in the genesis block.
bond-minimum = 1
# Maximum bond accepted by the PoS contract in the genesis block.
bond-maximum = 9223372036854775807
# Length of the validation epoch measured in blocks.
# This is put into PoS contract in the genesis block.
epoch-length = 10000
# Length of the quarantine time measured in blocks.
# This is put into PoS contract in the genesis block.
quarantine-length = 50000
# Max number of active validator in a shard. Validator rotation will be enabled if there are
# extra bond requests then slots available.
number-of-active-validators = 100
# TODO remove this
# Timestamp for the deploys
# deploy-timestamp = 0
# genesis-block-number is used for hard fork on existing network.
genesis-block-number = 0
# Public keys accepted by the PoS contract in the genesis block.
pos-multi-sig-public-keys = [
04db91a53a2b72fcdcb201031772da86edad1e4979eb6742928d27731b1771e0bc40c9e9c9fa6554bdec041a87cee423d6f2e09e9dfb408b78e85a4aa611aad20c,
042a736b30fffcc7d5a58bb9416f7e46180818c82b15542d0a7819d1a437aa7f4b6940c50db73a67bfc5f5ec5b5fa555d24ef8339b03edaa09c096de4ded6eae14,
047f0f0f5bbe1d6d1a8dac4d88a3957851940f39a57cd89d55fe25b536ab67e6d76fd3f365c83e5bfe11fe7117e549b1ae3dd39bfc867d1c725a4177692c4e7754
]
# How many confirmations are necessary to use multi-sig vault.
# The value should be less or equal the number of PoS multi-sig public keys.
pos-multi-sig-quorum = 2
# Native token metadata written into genesis state and exposed via /api/status.
# Immutable after genesis. Must be set before genesis.
#
# native-token-name : full display name (e.g. "F1R3CAP")
# native-token-symbol : ticker symbol (e.g. "F1R3")
# native-token-decimals: number of decimal places (1 token = 10^decimals dust)
native-token-name = "F1R3CAP"
native-token-symbol = "F1R3"
native-token-decimals = 8
}
# Genesis ceremony variables
genesis-ceremony {
# Number of signatures from bonded validators required for Ceremony Master to approve the genesis block.
# For standalone node in testing environment always use `0` so node can approve genesis block and start the
# one-node network.
required-signatures = 0
# Each `approve-interval` Ceremony Master (CM) checks if it have gathered enough signatures to approve
# the genesis block. If positive, CM broadcasts Approved Block, if negative - broadcast Unapproved Block
# one more time and keeps waiting for approvals.
approve-interval = 5 minutes
# Time window in which BlockApproval messages will be accumulated before checking conditions.
# TODO remove this as it is effectively just puts lower bound for genesis ceremony duration
approve-duration = 10 seconds
# If node has to create genesis block but no bonds file is provided, bonds file with a list of
# random public keys is generated + private keys corresponding to that keys are stored
# in `<genesis-path>/<public_key>.sk`
# This param specifies number of validator identites to generate.
autogen-shard-size = 5
# Allow node being a genesis validator
# If this is `true` and no genesis block available on startup, node enter genesis validator mode.
genesis-validator-mode = false
# Allow node being ceremony master
# If this is `true` and no genesis block available on startup node will start genesis ceremony.
ceremony-master-mode = ${standalone}
}
# The minimum Phlogiston price. Value can be configured to provide sufficient transaction fees to cover
# the cost of the network and equipment
min-phlo-price = 1
# Heartbeat configuration for maintaining liveness during periods of no user activity
heartbeat {
# Enable heartbeat block proposing
enabled = false
# Check interval - how often to check if heartbeat is needed
check-interval = 5 seconds
# Maximum age of last finalized block before triggering heartbeat
# If no block has been finalized in this duration, propose an empty block
max-lfb-age = 5 seconds
# Minimum time between heartbeat self-proposals.
# Controls proposal rate to prevent flooding the network.
self-propose-cooldown = 15 seconds
# Minimum age of LFB/frontier before stale-recovery, leader-recovery,
# and pending-deploy backstop are allowed to fire. Debounces empty-block
# churn when the cluster is healthy. Lower → more responsive recovery
# but more empty heartbeat blocks; higher → slower recovery, fewer
# blocks per minute.
stale-recovery-min-interval = 12 seconds
# When pending deploys land, opens a grace window during which lag caps
# relax (advanced.deploy-recovery-max-lag instead of advanced.pending-
# deploy-max-lag) and self-propose-cooldown is bypassable. Burst-tolerance
# budget. Higher → more sustained burst capacity; lower → quicker return
# to idle steady state.
deploy-finalization-grace = 25 seconds
# EXPERIMENTAL tuning knobs for the proposer's lag caps. They bound
# DAG width relative to replay cost in lieu of adaptive backpressure.
# Treat as unstable API.
advanced {
# When this validator is already ahead of LFB, how many blocks of
# lag tolerate before "frontier-follow" proposing is throttled.
# 0 = never frontier-chase while ahead unless deploy recovery is
# active (which raises this dynamically).
frontier-chase-max-lag = 0
# If the validator has pending deploys but is already > N blocks
# ahead of LFB, suppress pending-deploy proposing. Prevents lag
# amplification: more deploys → more blocks → wider DAG → slower
# finalization → still "ahead" → keeps proposing forever.
# Lower → harder load-relief valve.
pending-deploy-max-lag = 20
# During an active deploy-finalization grace window, the lag cap
# widens to this value. The "absolute safe lag during recovery"
# ceiling. Should be >= pending-deploy-max-lag to take effect:
# the proposer uses max(pending-deploy-max-lag, deploy-recovery-
# max-lag), so values below collapse to the pending floor and the
# knob has no effect (a startup warning fires in that case).
deploy-recovery-max-lag = 64
}
}
# Finalizer configuration — controls how the node finds and confirms finalized blocks.
# Larger validator sets and wider DAGs may require larger budgets.
finalizer {
# Maximum time budget per finalization cycle.
work-budget = 8 seconds
# Timeout for evaluating a single finalization candidate (clique computation).
step-timeout = 1 second
# Work budget when the node is far behind (>1024 blocks from tip).
catchup-work-budget = 8 seconds
# Step timeout in catchup mode.
catchup-step-timeout = 1 second
}
# Disable late block filtering in DagMerger.
# When true (default), all blocks are included in merged state regardless of when
# they were observed. This prevents deploy loss during network partitions.
disable-late-block-filtering = true
}
# Metrics reporter configuration. All four reporters can be enabled
# independently; the metrics-rs runtime fans out to whichever are on.
metrics {
# Expose Prometheus scrape endpoint at /metrics on the admin HTTP
# port. Required for Grafana / alerting workflows; cheap when idle.
prometheus = false
# Enable the InfluxDB HTTP push reporter (epoch-seconds timestamps).
# Use UDP variant below for sub-second sampling — at 500ms intervals
# the HTTP reporter overwrites same-second points.
influxdb = false
# Enable the custom InfluxDB UDP reporter with epoch-millisecond
# timestamps. Required when sampling faster than once per second.
influxdb-udp = false
# Enable Zipkin span export for distributed tracing of inter-node
# request flows. Requires a Zipkin collector at the configured
# endpoint; off by default.
zipkin = false
# Enable Sigar-based host-level metrics (CPU, memory, disk, network).
# Requires the native Sigar library on the host; off by default
# because it adds a native dependency and most operators prefer
# node_exporter or similar for OS-level metrics.
sigar = false
# How often the metric reporters poll and emit (drives the InfluxDB
# HTTP/UDP and Sigar system-metrics reporters). Value in seconds.
tick-interval = 10
# Endpoint settings for the InfluxDB reporters (HTTP and UDP). Both
# reporters share the hostname/port pair; protocol/database/auth only
# apply to the HTTP reporter.
influxdb-endpoint {
# Hostname or IP of the InfluxDB collector. Shared by HTTP and UDP
# reporters.
hostname = "127.0.0.1"
# Collector port. Conventional choices: 8086 for HTTP write API,
# 8089 for UDP listener. Default below targets the UDP listener
# (matches `metrics.influxdb-udp = true` shape); change to 8086 when
# using the HTTP reporter against a standard InfluxDB install.
port = 8089
# Target database/bucket for the HTTP reporter. Empty by default —
# must be set whenever `metrics.influxdb = true`. Ignored by the UDP
# reporter (which derives the destination from the listener config).
database = ""
# Wire protocol for the HTTP reporter ("http" or "https"). Has no
# effect on the UDP reporter. Use "https" against TLS-fronted
# InfluxDB collectors.
protocol = "http"
# Optional HTTP basic-auth credentials. Only consumed by the HTTP
# reporter; leave commented out (None) when InfluxDB is unauthenticated
# or when using the UDP reporter.
# user = "<username>"
# password = "<password>"
}
}
# Loosens validation invariants and enables in-process developer
# shortcuts. Permissions/identity checks normally enforced at the API
# boundary are relaxed. Never enable on a production validator.
dev-mode = false
# OpenAI configuration
# Ported from Scala PR #123 - Issue #127
openai {
# Enable or disable OpenAI service functionality.
# Priority order: 1. Environment variable OPENAI_ENABLED, 2. Configuration (this file), 3. Default (false)
#
# Configuration options:
# - enabled = true: OpenAI features are active and require a valid API key (node will crash at startup if missing)
# - enabled = false: OpenAI features are disabled and no API key is required (safe mode)
#
# Environment variable OPENAI_ENABLED accepts: true/false, 1/0, yes/no, on/off (case insensitive)
# Example: export OPENAI_ENABLED=true
#
# Default: false (disabled for safety)
#
# NOTE: When OpenAI is disabled (enabled = false), all AI-related system processes are excluded from the runtime.
# If you attempt to deploy a contract that uses AI processes (rho:ai:gpt4, rho:ai:dalle3, rho:ai:textToAudio),
# the deployment will fail with an error. This is expected behavior when AI is disabled.
enabled = false
# API key used by OpenAIService. Only required when OpenAI service is enabled.
# Resolution order: 1. Environment variable OPENAI_API_KEY, 2. This configuration
# Example: api-key = "sk-********************************"
api-key = ""
# Validate API key at startup by calling a lightweight endpoint (list models).
# Set to false to skip validation.
validate-api-key = true
# Timeout for API key validation call in seconds.
validation-timeout-sec = 15
}
# Ollama configuration
ollama {
# Enable or disable Ollama service functionality.
# Priority order: 1. Environment variable OLLAMA_ENABLED, 2. Configuration (this file), 3. Default (false)
#
# Configuration options:
# - enabled = true: Ollama features are active and require a running Ollama server (node will crash at startup if unavailable)
# - enabled = false: Ollama features are disabled and no local server is required (safe mode)
# - Comment out or omit: Falls back to environment variable OLLAMA_ENABLED
#
# Environment variable OLLAMA_ENABLED accepts: true/false, 1/0, yes/no, on/off (case insensitive)
# Example: export OLLAMA_ENABLED=true
#
# Default: false (disabled for safety)
#
# NOTE: When Ollama is disabled (enabled = false), all Ollama-related system processes are excluded from the runtime.
# If you attempt to deploy a contract that uses Ollama processes (rho:ollama:chat, rho:ollama:generate, rho:ollama:models),
# the deployment will fail with an error. This is expected behavior when Ollama is disabled.
enabled = false
# Base URL for Ollama API. Default points to local Ollama installation.
base-url = "http://localhost:11434"
# Default model to use when no model is specified in requests.
default-model = "llama4:latest"
# Connection is validated automatically at startup when enabled.
# Timeout for connection validation and API requests.
timeout-sec = 30
}
dev {
# If set, on each propose node will add dummy deploy signed by this key.
# deployer-private-key =
}