-
-
Notifications
You must be signed in to change notification settings - Fork 9
Expand file tree
/
Copy pathconfig.example.yaml
More file actions
228 lines (208 loc) · 10.7 KB
/
Copy pathconfig.example.yaml
File metadata and controls
228 lines (208 loc) · 10.7 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
# Arcade configuration
# Copy to config.yaml and adjust for your environment.
# All values can be overridden with ARCADE_ prefixed env vars
# (e.g. ARCADE_LOG_LEVEL, ARCADE_KAFKA_BROKERS).
# Service mode: all, api-server, bump-builder, propagation
mode: all
log_level: info
# Bitcoin network everything in arcade attaches to. One of:
# mainnet — production Bitcoin SV
# testnet — public testnet
# teratestnet — teranode scaling testnet
# regtest — local/private network; requires operator-supplied
# p2p.bootstrap_peers when datahub_discovery is on, and
# auto-disables chaintracks_server (no regtest genesis header).
# Both the libp2p datahub discovery client and the embedded chaintracks
# instance derive their pubsub topic and bootstrap peers from this value.
network: mainnet
# callback_url: "https://example.com/callback"
# Bearer token the Merkle Service must present in the Authorization header on
# every POST /api/v1/merkle-service/callback. REQUIRED when merkle_service.url
# is set: arcade refuses to start otherwise, since an unset token would let any
# unauthenticated caller submit forged status updates for any txid. Generate a
# high-entropy random value (e.g. `openssl rand -hex 32`) and configure the
# matching token on the Merkle Service. See issue #76 / finding F-018.
# callback_token: "your-callback-token"
api:
host: 0.0.0.0
port: 8080
# Arcade does not create Kafka topics; the broker must already have them
# (auto-create on first publish is typically disabled in production, and
# arcade.propagation has a hard exactly-1-partition correctness constraint
# that arcade enforces at startup). See docs/production-kafka.md for the
# full topic list, partition guidance, and ready-to-paste rpk /
# kafka-topics.sh commands.
kafka:
brokers:
- localhost:9092
consumer_group: arcade
max_retries: 5
buffer_size: 10000
# Minimum partitions required on hot-path topics (transaction, propagation).
# Set to the replica count of the largest horizontally-scaled consumer when
# running in Kubernetes so arcade fails fast on misconfigured topics. Leave
# at 0 for standalone / single-replica deployments.
# min_partitions: 0
# Persistence backend. `backend` dispatches construction in storefactory.New;
# only the matching sub-block is read, so unused sections (pebble, postgres)
# can be left out entirely.
store:
backend: aerospike
aerospike:
# One or more seed hosts. Port is optional and defaults to 3000.
hosts:
- localhost:3000
# Aerospike namespace arcade writes into. Must exist on the cluster with
# enough storage for arcade_transactions, arcade_bumps, arcade_stumps,
# arcade_submissions, arcade_leases, and arcade_datahub_endpoints sets.
namespace: arcade
# Max records per BatchGet/BatchWrite call. Larger batches reduce RTT
# overhead but raise per-op latency and memory pressure.
batch_size: 500
# Per-node connection pool size (ConnectionQueueSize). Tune to roughly
# the peak concurrent goroutines hitting the store.
pool_size: 256
# Total deadline for scan/query operations (e.g. GetStatusesSince).
query_timeout_ms: 8000
# Total deadline for single-record reads/writes and batch operations.
op_timeout_ms: 3000
# Per-attempt socket timeout. Should be <= op_timeout_ms; the client
# may retry on socket timeout up to the op deadline.
socket_timeout_ms: 5000
# datahub_urls:
# - "https://datahub1.example.com"
# - "https://datahub2.example.com"
teranode:
auth_token: ""
merkle_service:
# Merkle Service base URL. Leaving this empty disables the Merkle integration
# (standalone profiles). When set, the top-level `callback_token` becomes
# REQUIRED — arcade fails to start otherwise so that the inbound callback
# endpoint never runs unauthenticated. See issue #76 / finding F-018.
url: ""
auth_token: ""
p2p:
seeds: []
# Peer discovery via go-teranode-p2p-client. When enabled, arcade subscribes
# to the canonical node_status topic (e.g. teranode/bitcoin/1.0.0/mainnet-node_status)
# and appends each peer's advertised datahub URL to the propagation endpoint
# list. Statically configured `datahub_urls` remain first in the list;
# discovered URLs are additive and deduplicated (including trailing-slash
# variants). Network and its bootstrap peers are derived from the top-level
# `network` value above; bootstrap_peers below only needs to be set to
# override or extend the built-in defaults (e.g. a private network).
# datahub_discovery: false
# listen_port: 9905
# dht_mode: off # "server", "client", or "off" (library default is "off")
# storage_path: "" # defaults to <top-level storage_path>/p2p; stores p2p_key.hex for stable peer ID
# bootstrap_peers: [] # override the built-in defaults; also feeds chaintracks
# (unless chaintracks.p2p.msgbus.bootstrappeers is set explicitly)
# enable_mdns: false
# allow_private_urls: false # accept loopback/RFC1918/link-local URLs from peers
health:
port: 8081
# Intake-time transaction validator. The default rejects txs whose
# fee rate is below the BSV miner policy minimum of 100 sat/kB.
# validator:
# min_fee_per_kb: 100
# # accept_zero_fee, when true, pins the floor to 0 sat/kB so any tx
# # (including fee=0) is accepted at intake. Intended for
# # teratestnet/regtest where the upstream Teranode is also configured
# # to accept zero-fee txs. Leave false on mainnet and testnet.
# # accept_zero_fee: false
# SSRF guard for client-supplied callback URLs. The api-server rejects
# X-CallbackUrl values whose host is loopback / link-local / RFC1918 /
# cloud-metadata, and the webhook delivery client refuses to dial those
# IPs at connection time (catches DNS rebinding). Set
# allow_private_ips: true if your deployment intentionally posts
# callbacks to internal services (testing, k8s service DNS, intranet
# webhooks). See finding F-017 / issue #75.
#
# max_body_bytes caps the size of an inbound POST
# /api/v1/merkle-service/callback request body (JSON, with embedded STUMP
# payload). Default 16 MiB is generous over a realistic STUMP delivery
# while bounding worst-case memory if a peer is malicious or malfunctioning.
# Oversize requests are rejected with 413 Payload Too Large. See finding
# F-019 / issue #77.
# callback:
# allow_private_ips: false
# max_body_bytes: 16777216 # 16 MiB
# events tunes the in-process status-update fan-out. subscriber_buffer is
# the channel capacity each Subscribe call mints (one per consumer — SSE
# manager and webhook delivery). When a consumer can't drain fast enough
# the publisher logs "subscriber channel full, dropping update" and drops.
# Default 4096 absorbs typical bursts; raise up to ~65536 if you see drops.
# Going beyond ~65536 just delays the drop rather than addressing the
# slow-consumer root cause. Memory cost is roughly
# subscribers × subscriber_buffer × ~500 bytes per slot.
# events:
# subscriber_buffer: 4096
# propagation:
# # Per-endpoint circuit-breaker for the datahub URL list. Endpoints that
# # accumulate `failure_threshold` consecutive failures are marked unhealthy
# # and excluded from broadcasts; a background probe hits GET /health on
# # unhealthy endpoints every `probe_interval_ms` to detect recovery. The
# # `min_healthy_endpoints` value is advisory — a WARN is logged when the
# # healthy count drops below it, but broadcasts are never blocked by it.
# endpoint_health:
# failure_threshold: 3
# probe_interval_ms: 30000
# probe_timeout_ms: 2000
# min_healthy_endpoints: 0
# # How often each pod's teranode.Client polls the shared store for new
# # datahub URLs registered by the p2p-client pod. Lower = faster cross-pod
# # convergence; higher = less store load. The first refresh runs
# # synchronously on Start (capped at 2s) so a freshly started pod sees
# # the current registry before serving traffic.
# refresh_interval_ms: 30000
bump_builder:
# Grace window after BLOCK_PROCESSED before reading STUMPs, to allow for
# late merkle-service retries of any STUMPs that initially got a 5xx.
grace_window_ms: 30000
# Maximum response body size, in bytes, accepted from a DataHub
# /block/<hash> endpoint. The endpoint serves block metadata (header +
# subtree-hash list + coinbase tx + coinbase BUMP), so the default
# 1 GiB leaves two-plus orders of magnitude of headroom over realistic
# Teranode payloads while bounding memory against a hostile or
# malfunctioning endpoint. Set <= 0 to use the built-in default.
# Mitigates F-007.
# datahub_max_block_bytes: 1073741824
# Shared on-disk root for arcade state. Chaintracks headers default to
# <storage_path>/chaintracks/.
# storage_path: "~/.arcade"
# Embedded block-header tracker (go-chaintracks). Serves routes under
# /chaintracks/v1/* and /chaintracks/v2/* on the api-server. Default is on
# so the refactor is a drop-in replacement for the original arcade binary.
# Set enabled: false in environments without outbound P2P.
chaintracks_server:
enabled: true
# go-chaintracks library config. See that library's docs for the full set.
# Defaults are inherited from the library's SetDefaults — uncomment to override.
#
# In single-binary (mode=all) and the dedicated chaintracks pod, leave mode at
# the default "embedded" so this process owns the header store and the P2P
# subscription. In a microservice deployment every OTHER consumer pod
# (bump-builder) should run mode="remote" with url pointed at the chaintracks
# pod's HTTP endpoint — otherwise each pod spins up its own embedded
# ChainManager and hits the upstream node N times. arcade additionally skips
# the chaintracks library entirely in modes that don't read from it
# (api-server, sse, propagation, p2p-client, watchdog), so those pods need no
# chaintracks config at all.
# chaintracks:
# mode: embedded # or "remote" with url set
# url: "" # required when mode=remote, e.g. http://chaintracks:8083
# storage_path: "" # embedded mode only; defaults to <storage_path>/chaintracks
# bootstrap_url: "" # embedded mode only
# bootstrap_mode: api # embedded mode only
# # Bootstrap peers default to the network-derived list, falling back to
# # p2p.bootstrap_peers when that's set — configure peers once at the p2p
# # block and both the p2p-client and chaintracks pick them up. Only set
# # the explicit override below when chaintracks needs a different peer
# # set than the p2p-client (rare). The upstream msgbus.Config struct has
# # no mapstructure tags, so the YAML key is the camelCase-flattened name
# # ("bootstrappeers", not "bootstrap_peers") — viper matches case-
# # insensitively but does not translate snake_case.
# p2p:
# msgbus:
# bootstrappeers:
# - /dns4/peer.example.cluster.local/tcp/9905/p2p/12D3Koo...