Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Configuration Flag Reference

This chapter is the complete reference for every config key satd recognizes: what it does, its default, whether it reloads live on SIGHUP, and whether it is Bitcoin Core-compatible or a satd extension.

For how configuration is sourced and how live reload works, see Configuration, Tuning & Reload. This chapter is the flat per-key index. The auth keys (authfile, *authbearer/*auth, *allowremote, cookie/rpcuser/rpcauth) are explained in context in Authentication & Authorization. The sync, consensus, and storage-tuning keys (assumevalid, consensus, shadow*, dbcache, prefetchworkers, maxahead, storageprofile, the rocksdb* / compaction* family, reindex) are covered in Initial Block Download & Fast Sync.

How satd reads configuration

The goal is that an existing Bitcoin Core bitcoin.conf drops in and works. satd reads Core's configuration surface directly: the same bitcoin.conf / satd.conf key=value and [network] section syntax, and the same flag names (-datadir, -rpcport, …). Supported names and semantics track Bitcoin Core v30.

  • Resolution order. -conf=<path> if given, else <datadir>/bitcoin.conf, else <datadir>/satd.conf. Flags override file values.
  • Comments. As in Core, # starts a comment anywhere on a line: txindex=1 # keep it sets txindex to 1. What is left of the line is trimmed of spaces, tabs and line endings. An rpcpassword line that contains a # is refused at load (using # in rpcpassword can be ambiguous and should be avoided), as Core refuses it.
  • Key disposition. Each config-file key gets one of four treatments:
    1. Honored. satd implements it. This is the common case.
    2. Skipped with a warning. A recognized Core v30 option satd does not implement but that is safe to skip. The node still starts, and a WARN line names the ignored key and the satd equivalent, if any. This is what lets a real bitcoin.conf boot unedited.
    3. Rejected at load. A small set where skipping would mislead you about the node's security, exposure, or privacy posture (see Unsupported Core keys). satd fails closed with guidance.
    4. Rejected as a typo. A key that is neither a satd option nor a known Core v30 option. Rejection stops a mistyped security option such as rpcusser= from silently disabling auth.
  • No key is silently ignored. Skipped keys always warn; nothing a config asks for is dropped without a log line.
  • -profile=<preset> seeds a hardware/role profile (archival, pruned-home, mining, regtest-dev, signet-watchtower). Explicit flags override the profile's values.

Note. Compatibility is pinned to Bitcoin Core v30, a frozen and verifiable surface. Keys Core adds in v31 or later are not recognized, and are rejected as typos, unless satd implements them (limitclustercount, limitclustersize and txospenderindex are; privatebroadcast is not). Keys Core removed at or before v30 (for example upnp, maxorphantx) are likewise not honored. A bitcoin.conf migrated from a newer Core that contains a v31+ key stops satd at startup with an "unknown key" error. This is intentional.

Note. This reference is for operating the node. To write software that consumes node state (blocks, mempool, address activity, reorgs), use the Streaming Consumption API (gRPC, WebSocket, or ZMQ). It is reorg-safe, supports durable cursor replay, and is decoupled from consensus. The Core *notify shell hooks and RPC polling exist for compatibility and quick scripts only. They have no delivery guarantee, no replay, and no reorg awareness.

Legend

  • Reload. hot: applied live on SIGHUP (systemctl reload satd). restart: wired into long-lived state at startup; reported as "restart required" on reload, never silently ignored. TLS certificate contents reload via SIGUSR1 even where the key is restart; see Live TLS Certificate Reload.
  • Compat. core: same key name and substantially the same semantics as Bitcoin Core. satd: a satd-specific extension (no Core equivalent, or satd-only semantics). The classification is best-effort; a key modeled on Core behavior but without a Core flag of the same name is satd.

Note. Every key in the per-category tables below is honored: satd implements it. Recognized Core v30 keys satd does not honor are not in these tables. They are listed, with their warn-and-skip or fail-closed disposition, under Unsupported Core keys: skipped vs rejected. A key in neither place is rejected as a typo.


Network selection

KeyDefaultReloadCompatDescription
regtestoffrestartcoreUse the regtest network.
testnetoffrestartcoreUse the testnet network.
testnet4offrestartcoreUse the testnet4 network.
signetoffrestartcoreUse the signet network.
chainmainrestartcoreUnified network selector: main|test|signet|regtest|testnet4. Alternative to the per-net flags.

The bare selectors (signet=1, testnet4=1, …) and chain= are honored both on the command line and in bitcoin.conf, as in Bitcoin Core. Command-line selectors take precedence over the config file. Selecting more than one network (two bare selectors, or a chain= that disagrees with a bare selector) is a startup error.

Filesystem

KeyDefaultReloadCompatDescription
datadirplatform defaultrestartcoreData directory.
blocksdir<datadir>/blocksrestartcoreAlternative location for blocks/ and flat-file undo data.
blocksxorunsetrestartcoreBlocks-dir *.dat XOR obfuscation (Core v28+ blocks/xor.dat). Unset: honor an existing key (an obfuscated Core v28+ blocks/ dir reads with no config) and initialize fresh dirs plaintext. 1: also generate a random key on a brand-new blocks dir (Core's default). 0: demand plaintext; refuses a dir with a nonzero stored key.
confbitcoin.conf in datadirrestartcoreConfig file path.
includeconfnonerestartcoreAdditional config file to splice in; honored only inside a config file.
pidnonerestartcoreWrite PID to file.
profilenonerestartsatdNamed preset: archival|pruned-home|mining|regtest-dev|signet-watchtower; CLI flags override it.

Daemon control

KeyDefaultReloadCompatDescription
daemonoffrestartcoreRun in background; accepted for compatibility (no-op; use systemd).
serveronrestartcoreAccept RPC commands; accepted for compatibility (always on).
logformattextrestartsatdLog output format: text or json. Only verbosity hot-reloads, not the format.
logtimestampsonrestartcorePrepend a timestamp to each log line. Disable (-nologtimestamps) when journald / the container runtime already stamps lines.
logthreadnamesoffrestartcorePrepend the originating thread name to each log line.
logsourcelocationsoffrestartcorePrepend source file:line to each log line.
debugnonehotcoreEnable debug logging for a category (repeatable; bare/all/1 = everything). satd adds stratum, the Stratum server's per-miner lines (see Verifying a miner).
debugexcludenonehotcoreDisable debug logging for a category debug would otherwise enable.
loglevelinfohotcoreGlobal verbosity (trace/debug/info/warn/error) or a per-category override (net:debug). Maps onto satd's tracing filter: a bare level sets the default for targets without an override, and does not lower a more specific -debug/RUST_LOG directive (-debug=net -loglevel=error still logs net at debug). A category:level pair overrides that subsystem. The JSON-RPC and WebSocket libraries' TRACE output (jsonrpsee*, tungstenite* targets), which prints request headers and call parameters, is never logged, whatever the level; their DEBUG output is.
allowignoredconfoffrestartcoreSuppress startup warnings about includeconf files satd had to ignore.
maxshutdownsecs30hotsatdGraceful-shutdown budget (seconds), shared by the shutdownnotify hook (at most half of it), the wait for running RPC calls to finish (at most a quarter of what is left), the wait for the block connector to stop (at most half of what is left after that) and the final flush. An RPC call or a connector still running at the end of its share costs the clean-shutdown marker but not the flush; a flush that overruns the budget force-exits without the marker.

RPC server

KeyDefaultReloadCompatDescription
rpcport8332 (network-dependent)restartcoreRPC server port. Defaults: main 8332, test 18332, testnet4 48332, signet 38332, regtest 18443.
rpcbind127.0.0.1:<rpcport> and [::1]:<rpcport>restartcoreBind plain-HTTP JSON-RPC to address (repeatable). Non-loopback requires rpcallowip. With no rpcbind, a default that cannot be bound (no IPv6) is skipped.
rpcallowiploopback onlyrestartcorePer-connection source-IP allowlist for JSON-RPC (repeatable). IPv6 may be bracketed ([::1]). Applies to the plain-HTTP binds always, and to rpctlsbind only once at least one entry is set (an empty list leaves a TLS bind reachable from wherever it is bound). Loopback is always allowed.
cjdnsreachablefalserestartcoresatd has no CJDNS transport; as in Core, an rpcallowip in fc00::/8 is refused while it is set.
rpcusernonehotcoreRPC username.
rpcpasswordnonehotcoreRPC password.
rpcthreads16restartcoreMax concurrent in-flight RPC method calls.
rpcworkqueue64restartcoreMax queued RPC requests beyond rpcthreads before HTTP 429 (Core returns 503; documented divergence).
rpcservertimeout30restartcoreSeconds a client may take to deliver a complete request (head and body), or sit idle between keep-alive requests, before the connection is closed. 0 disables. An open connection holds one of the listener's 100 connection slots until it closes, so with 0 an idle client keeps its slot indefinitely; see Scaling the API surfaces.
apithreadsmax(2, cores/4)restartsatdWorker threads for the isolated API runtime (Esplora/Electrum/events gRPC/metrics).
rpcreadonlybindnonerestartsatdBind an opt-in read-only JSON-RPC listener (reads + mempool submit) on the API runtime.
rpcreadonlyport8330restartsatdDefault port for rpcreadonlybind entries without an explicit port.
rpcreadonlyallowiploopback onlyrestartsatdSource-IP allowlist for the read-only listener.
rpcreadonlythreads= rpcthreadsrestartsatdMax in-flight calls on the read-only listener.
rpcreadonlyworkqueue= rpcworkqueuerestartsatdRead-only listener work-queue depth before HTTP 429.
rpcreadonlytlsbindnonerestartsatdTLS bind for the read-only listener (requires cert+key).
rpcreadonlytlscertnonerestartsatdPEM certificate (chain) for the read-only TLS listener.
rpcreadonlytlskeynonerestartsatdPEM private key for the read-only TLS listener.
rpcreadonlymtlsfalserestartsatdRequire a client cert (mTLS) on the read-only TLS surface.
rpcreadonlymtlsclientcanonerestartsatdCA bundle client certs must chain to on the read-only TLS surface.
rpcreadonlymtlsclientallowany CA-signedrestartsatdAllowlist of client-cert subjects on the read-only TLS surface.
rpcauthnonehotcoreHMAC-SHA256 RPC credential user:salt$hash (Core rpcauth format; repeatable). An empty or malformed entry stops startup; -norpcauth discards the entries before it, and the config file's unless an entry follows it.
rpcwhitelistnonerestartcoreLimit an RPC user to a list of JSON-RPC methods: <user>:<m1>,<m2>,... (repeatable; commas or spaces separate methods). A user listed more than once, including on the command line and in the file, keeps the intersection. A refused call is HTTP 403 with an empty body. Not combinable with rpcdisableauth. See Authentication & Authorization.
rpcwhitelistdefaulton if any rpcwhitelist is set, else offrestartcoreWhen on, an RPC user with no rpcwhitelist entry may call nothing.
authfilenonerestartsatdPath to unified-auth bearer-token file (TOML); enables the opt-in bearer-auth layer. Token contents reload live.
rpcauthbearerfalserestartsatdHonor Authorization: Bearer tokens on the JSON-RPC listeners (requires authfile).
rpccookiefile$DATADIR/.cookierestartcoreOverride the auto-generated cookie file path. -norpccookiefile writes no cookie.
rpccookiepermsowner (0600)restartcoreCookie file permissions: owner(0600)|group(0640)|all(0644).
deprecatedrpcnonerestartcoreBring back a deprecated RPC form (repeatable). satd knows warnings: getblockchaininfo, getnetworkinfo and getmininginfo then report warnings as one string, the latest warning or "", instead of the array Core v28 and later return. Other names are warned about and ignored.
rpcdefaultunitsbtchotsatdDefault units for RPC amount fields: btc (Core-compatible) or sats.
rpcdisableauthfalserestartsatdDisable HTTP Basic auth on the JSON-RPC TLS surface; only valid with rpcmtls=1.
rpcextendederrorsoffhotsatdEmit structured error payloads (category/suggestion/debug) on RPC errors.

RPC TLS

(satd-specific; Core's RPC is HTTP-only behind a TLS-terminating sidecar.)

KeyDefaultReloadCompatDescription
rpctlsbindnonerestartsatdBind the JSON-RPC TLS listener (requires cert+key).
rpctlscertnonerestartsatdPEM TLS certificate for the JSON-RPC server.
rpctlskeynonerestartsatdPEM TLS private key for the JSON-RPC server.
rpctlshandshaketimeout10restartsatdPer-handshake timeout (seconds) for the JSON-RPC TLS surface.
rpcmtlsfalserestartsatdRequire mutual TLS on the JSON-RPC TLS listener.
rpcmtlsclientcanonerestartsatdPEM CA bundle to verify client certs when rpcmtls=1.
rpcmtlsclientallowany CA-signedrestartsatdAllowlist of accepted client-cert CN/DNS-SAN values.

P2P

KeyDefaultReloadCompatDescription
listenon (see note)restartcoreAccept P2P connections. The default is soft, as in Core: a node given any connect (including connect=0 / -noconnect), or maxconnections ≤ 0, does not accept inbound either, since a node pinned to specific peers has not asked to be reachable. bind or whitebind raises it back, and an explicit listen — flag or config file — beats both. Because the value is derived, changing a hot key that feeds it (connect, maxconnections) over SIGHUP logs a listen restart-required notice; the running listener is not started or stopped until a restart. A listen that is off in turn soft-sets listenonion off, as in Core, so a pinned node does not publish a hidden service; an explicit listenonion beats that. A proxy also lowers listen, as in Core ("to protect privacy, do not listen by default if a default proxy server is specified"); set listen=1 to accept inbound with a proxy.
networkactiveonhotcoreStart with P2P networking enabled. =0 boots with networking paused (no inbound accepts, no outbound dials); change it at runtime with the setnetworkactive RPC.
blocksonlyfalsehotcoreSuppress P2P transaction relay; locally-submitted txs still relayed.
v2transporttruehotcoreOffer/accept BIP 324 v2 encrypted transport (Core default since v26).
v2onlyfalsehotsatdRefuse peers that do not speak BIP 324 v2 (privacy hardening).
externalipnonehotcoreExternal address to advertise to peers (repeatable): an IP, IP:port, or a v3 .onion address with or without a port. An onion entry is how a hidden service run from torrc tells the node its address, as in Core; satd advertises one onion address, so with listenonion the service satd creates is advertised while it is up, and an onion externalip while it is not. An onion entry takes effect at startup; a reload applies only the IP entries. Hostnames are refused. An address that is not routable (private, loopback, link-local, shared or documentation space) is accepted but never advertised, as Core's AddLocal refuses it.
whitelistnonehotcoreGrant net permissions to peers by source subnet (repeatable). [<perms>@]<subnet>. Inbound only unless the permission list carries out, as in Core; an out entry applies only to manual outbound connections (connect, addnode, and seednode, which satd keeps as a manual connection), never to automatic ones such as the peers the node finds through gossip, peers.dat or a DNS seed. @<subnet> with an empty list matches the range and grants nothing. A peer arriving over the Tor hidden service is never matched against this — it reaches the node on a loopback socket Tor forwards to, so matching would grant an anonymous remote peer whatever you granted your own machine. The addr permission exempts a peer from Core's address rate limit: otherwise the node takes one address from a peer's addr/addrv2 messages to start and one more every 10 seconds (a thousand more after it sends the peer getaddr), and getpeerinfo reports the rest as addr_rate_limited.
whitelistrelayonhotcoreGrant relay to whitelisted peers with default permissions (relay their txes even under -blocksonly). Entries with an explicit perms@ prefix are unaffected.
whitelistforcerelayoffhotcoreGrant forcerelay to whitelisted peers with default permissions. Entries with an explicit perms@ prefix are unaffected.
whitebindnonerestartcoreBind an extra permissioned P2P listener (repeatable).
asmapnonerestartcoreasmap file for ASN-based addrman bucketing (eclipse resistance).
portnetwork defaultrestartcoreP2P listen port.
bind0.0.0.0restartcoreBind P2P to this address; repeatable. Accepts addr, addr:port, and addr[:port]=onion. An entry with a port uses it; a bare address takes port, and a bare =onion entry takes port + 1 (as in Core). IPv6 literals may be plain (::1) or bracketed. Any explicit bind replaces the default listener. Cannot be combined with listen=0.
connectnonehotcoreConnect only to specific peer(s) (repeatable). An entry with no port takes the network's default P2P port. Any connect stops the node dialling addresses it learns from gossip and soft-sets listen=0 (see listen); connect=0 — and the command-line negation -noconnect — is Core's spelling for "open no outbound connections at all"; a literal connect=0 mixed with a peer address is refused, since Core keeps the peer and satd will not dial the 0. Connect-only exclusivity is a startup decision (restart to change).
addnodenonehotcoreAdd a node to connect to (does not disable DNS seeding, and does not affect listen). An entry with no port takes the network's default P2P port. As in Core, added nodes are counted apart from the automatic outbound peers and maxconnections: at most 8 are connected at a time, and one that is not connected is dialled again at most a minute later, however many automatic peers the node has. A ban does not stop the dial; it does stop automatic dials to that address.
uacommentnonerestartcoreAppend a comment to the advertised user agent (repeatable; command-line and config-file values accumulate, command line first). Renders as /satd:<version>(c1; c2)/. A comment may contain only alphanumerics and .,;-_?@ — the user agent's own delimiters /, :, ( and ) are refused — and the whole user agent may not exceed 256 bytes. Either violation is a startup error, as in Core.
seednodenonehotcoreOne-shot seed peer connected at startup to bootstrap discovery.
maxconnections125hotcoreMaximum total connections. Manual connections (connect, addnode, seednode, addnode onetry) do not count against the automatic outbound peers, as in Core. 0 (or any value ≤ 0) soft-sets listen=0, as in Core — see listen. That half is a startup decision: changing maxconnections over SIGHUP applies the new cap but does not start or stop the listener.
maxinboundperip3hotsatdMax simultaneous inbound peers from one source IP (Core-style flood guard; no Core flag).
cmpctblockprefillfalserestartsatdAnnounce a new block as a cmpctblock with the transactions this node lacked when it arrived prefilled, so a peer that lacks them too rebuilds the block without a getblocktxn round trip. Bitcoin Core's proposed design (#35558, not yet merged in Core); off until measurement says otherwise.
cmpctblockprefillbytes8192restartsatdTransaction bytes a cmpctblockprefill announcement may carry beyond the coinbase. Transactions nobody relayed to this node go first, then replaced or policy-refused ones; one that does not fit is skipped. 0 prefills nothing.
blockreconstructionextratxn100restartcoreRecently seen transactions that are not in the mempool — replaced, or refused by policy — kept so a compact block that includes one still reconstructs without a round trip. 0 keeps none.
maxuploadtarget0 (unlimited)hotcoreSoft cap (bytes/24h) on historical block upload.
dnstruerestartcoreAllow DNS lookups for -addnode/-seednode/-connect. With dns=0 those options accept only literal IP addresses and .onion targets; a hostname is refused.
dnsseedtruerestartcoreQuery DNS seeds for peer addresses (requires dns). With nothing reachable in the address book the seeds are queried at startup; otherwise the node tries the book first and queries them if it has fewer than two full-relay outbound peers after 11 seconds (5 minutes with 1,000 or more addresses), as Core does. Off by default when onlynet leaves out both IPv4 and IPv6; dnsseed=1 with such an onlynet is refused at startup, as in Core.
forcednsseedfalserestartcoreQuery DNS seeds at startup even with a populated address book.
fixedseedstruerestartcoreAllow the compiled-in fixed-seed fallback: added a minute after startup if the address book still has nothing reachable, or at startup when DNS seeding is off and no seednode or addnode is set, as in Core.
bantime86400hotcoreBan duration in seconds.
timeout5000 mshotcoreP2P connection timeout in milliseconds (accepts 5s/5000ms). Through a SOCKS5 proxy it bounds the connect to the proxy; the SOCKS5 exchange that follows gets 20 seconds or this value, whichever is larger, as Core gives each SOCKS5 reply 20 seconds.
onlynetallrestartcoreMake automatic outbound connections only to these networks (repeatable): ipv4, ipv6, onion, cjdns, i2p. Gossiped addresses on other networks are not kept. Inbound and manual connections (connect, addnode, seednode) are not affected. Refused at startup as in Core: an unknown name; onion with neither proxy nor onion (Core also takes listenonion; satd cannot reach Tor through it), or with onion=0; cjdns without cjdnsreachable; i2p (satd has no I2P transport).
signetseednodebuilt-in seedsrestartcoreAdditional signet seed node (repeatable; signet only).
signetchallengedefault signetrestartcoreCustom signet challenge script, hex (BIP 325; signet only). Without it satd runs the default signet and verifies every block against its challenge.

Note. satd answers a peer's BIP35 mempool message (a request to announce our entire mempool) only for peers granted the mempool net permission: -whitelist=mempool@<subnet>, all@<subnet>, or a bare -whitelist=<subnet> entry, whose implicit permission set includes mempool, as in Core. The permission is not implied by noban@. The response honors the requesting peer's fee filter, and dumps to one peer are rate-limited to at most one per 30 s. satd does not advertise NODE_BLOOM (BIP37 bloom filters are unsupported). mempool requests from peers without the permission are ignored, which is softer than Bitcoin Core with bloom disabled: Core disconnects such peers unless they have noban.

Proxy / Tor

KeyDefaultReloadCompatDescription
proxynonerestartcoreSOCKS5 proxy for all outbound connections; proxy=0 is none. Lowers listen by default (see listen). Nothing is looked up on the local resolver while this is set: that lookup would leak the peer names the proxy is there to hide. The DNS seeds, and a hostname in -seednode, are handed to the proxy by name instead, as short-lived addr-fetch connections that ask for addresses and close, as Core does. A hostname in -addnode/-connect is refused; use a literal IP or a .onion address.
proxyrandomizeonrestartcoreUse fresh random SOCKS5 credentials per connection so Tor isolates each peer on its own circuit (IsolateSOCKSAuth). Relies on Tor's default SocksPort isolation; a no-op on a non-Tor SOCKS proxy (or one with IsolateSOCKSAuth disabled), where credentials are not negotiated. Set =0 to opt out.
onion= -proxyrestartcoreSOCKS5 proxy for .onion connections. onion=0 (-noonion) never reaches .onion, even through proxy.
torcontrol127.0.0.1:9051restartcoreTor control port for the hidden service. Auth is negotiated via PROTOCOLINFO: SAFECOOKIE (stock-Tor default) when no password is set, else password, else null.
torpasswordnonerestartcoreTor control port password (for a HashedControlPassword setup). Leave unset to use SAFECOOKIE cookie auth.
listenonionoff (on if torcontrol set)restartcoreCreate a Tor v3 hidden service via the control port. Soft-set off when listen is off, as in Core; state it explicitly to keep the service on a non-listening node. Gets its own P2P listener on 127.0.0.1:<port+1> unless a bind=<addr>:<port>=onion entry names one, matching Core's onion_binds; peers arriving there are exempt from whitelist matching. The service's private key is kept in onion_v3_private_key in the network's data directory (mode 0600), as Core keeps it, and reused, so the onion address stays the same across restarts; delete the file to get a new address. Anyone who can read the file can run the node's onion address. When Tor stops or restarts, the address is withdrawn and satd reconnects to torcontrol, waiting 1 s, then half as long again each time up to 10 minutes, and adds the service again, as Core does; it also retries a failed authentication or ADD_ONION that way.

Consensus

KeyDefaultReloadCompatDescription
assumevalidper-network hash (none on a custom signet)restartcoreSkip script verification for HASH's buried ancestors on the best-header chain (0=verify all, all=skip old blocks).
assumevalidage86400restartsatdWith assumevalid=all, still verify scripts for blocks newer than SECS.
checkpointsonrestartcoreEnforce the built-in block checkpoints (mainnet and the default signet; a custom signet has none). A block at a checkpoint height must match it, and a new header forking below the highest checkpoint the block index holds is refused (bad-fork-prior-to-checkpoint). -checkpoints=0 disables both.
stopatheightnonerestartcoreStop once the active-chain tip reaches HEIGHT, during initial block download too, where the node stops at HEIGHT itself. 0 is off, as in Core.
testactivationheightnonerestartcoreRegtest only (warned and ignored elsewhere): name@height buried-deployment override (bip34|dersig|cltv|csv|segwit), repeatable. Note Core's own asymmetry, which satd matches: this option takes dersig/cltv, while getdeploymentinfo reports the same deployments as bip66/bip65; command-line and config-file occurrences merge, last wins per name.
vbparamsnonerestartcoreRegtest only (warned and ignored elsewhere): deployment:start:end[:min_activation_height] BIP 9 window override. Only testdummy is accepted — satd activates taproot at a fixed height and counts no signalling, so an override for it would be reported and not honoured, and is refused by name.
consensusrust-shadowrestartsatdConsensus engine: cpp|rust|rust-shadow|cpp-shadow.

Indexing

KeyDefaultReloadCompatDescription
txindexoffrestartcoreMaintain a full transaction index.
addressindexonrestartsatdMaintain an address-history index (backs native Electrum/Esplora).
addrindexmaxhistory200000restartsatdLargest scripthash history (transactions) the Electrum and Esplora address queries serve; a busier script is refused. 0 = no cap, which restores whole-history reads. See the Electrum chapter's History cap.
addrindexsubscriptions50000hotsatdMax concurrent per-scripthash status subscriptions, server-wide: shared by Electrum connections and Esplora SSE streams. See the Electrum chapter for sizing it against electrummaxconns × electrummaxsubsperconn.
blockfilterindexoffrestartcoreBIP 158 compact-block-filter index (basic/0/1, or no value for basic).
peerblockfiltersoffhotcoreAdvertise NODE_COMPACT_FILTERS and serve BIP 157 filters; implies blockfilterindex=basic.
silentpaymentindexoffrestartsatdBIP 352 silent-payment tweak index (sp_tweaks); backs the streaming tweaks firehose and scan-key-watch rescan. Backfill an existing datadir with backfillindex silentpayment.
coinstatsindexoffrestartcoreAccepted so a Core bitcoin.conf drops in unchanged. satd implements no UTXO-set hash index: the key sets nothing, and getindexinfo reports the index as never synced rather than claiming a readiness it cannot deliver.
txospenderindexoffrestartcoregettxspendingprevout also finds spenders in blocks, as in Core. satd answers from the address index's spend rows, which back Esplora's outspend endpoints, so the key needs addressindex and adds no index of its own. Refused with prune, as in Core.

Mempool / relay policy

KeyDefaultReloadCompatDescription
mempoolfullrbfonhotsatdEnable full replace-by-fee. Core removed this flag in v28 (full-RBF is now unconditional there); satd retains the flag.
maxmempool300 MBhotcoreMaximum mempool size in MB, measured by the serialized size of the transactions held. Bitcoin Core measures its memory use instead, so at the same setting satd holds more transactions than Core and uses more memory than the figure. At least 5, or 0, as in Core: a smaller value refuses to start.
minrelaytxfee1000 sat/kvBhotcoreMinimum relay fee rate. A bare integer is sat/kvB; a decimal is BTC/kvB, Bitcoin Core's spelling (0.00001 = 1000 sat/kvB).
dustrelayfee3000 sat/kvBhotcoreDust relay fee rate. A bare integer is sat/kvB; a decimal is BTC/kvB, Bitcoin Core's spelling (0.00003 = 3000 sat/kvB).
datacarrieronhotcoreAccept OP_RETURN outputs.
datacarriersize83 byteshotcoreMaximum OP_RETURN size in bytes (0 = reject all).
limitclustercount64hotcoreDo not accept a transaction whose cluster, the unconfirmed transactions connected to it through spends in either direction and itself included, would hold more than this many; it is rejected as too-large-cluster. 64 is both the default and the maximum, so the option can only lower it; a larger value is a startup error.
limitclustersize101 kvBhotcoreDo not accept a transaction whose cluster would come to more than this many kilobytes of sigop-adjusted virtual size; it is rejected as too-large-cluster. maxmempool must leave room for 40 such clusters.
limitancestorcount25hotcoreMaximum unconfirmed ancestor count. Deprecated in Bitcoin Core v31 and superseded by limitclustercount; accepted for config compatibility but no longer gates admission.
limitdescendantcount25hotcoreMaximum unconfirmed descendant count. Deprecated alongside limitancestorcount, and likewise no longer gates admission.
mempoolexpiry336 hhotcoreMempool entry expiry in hours.
maxtipage86400 srestartcoreA tip older than this keeps the node in initial block download.
minimumchainworkper networkrestartcoreThe chain work, in hex (up to 64 digits, optional 0x), a best header must have before -assumevalid skips scripts and before the node asks peers for header announcements.
persistmempoolonhotcorePersist the mempool to mempool.dat across restarts.
rebroadcastinterval0 (auto)hotsatdSeconds between rebroadcasts of unconfirmed local transactions (those submitted here via sendrawtransaction, the MCP tool, Esplora POST /tx, or Electrum transaction.broadcast). 0 = auto: a randomized 10–15 min interval per pass, matching Bitcoin Core. A locally-submitted tx is queued again for every peer that has not yet been announced it, until enough peers take it (see broadcastconfirmpeers) or it leaves the mempool, so it still propagates if no peer was connected at submit time; the pending set is persisted in mempool.dat so it also survives restarts. A SIGHUP interval change applies after the in-flight sleep completes.
txannouncedelay1hotsatd1: announce transactions to each peer on Bitcoin Core's random timers, every 2 s on average to an outbound peer and every 5 s to inbound peers (one shared timer per network and listener), so a peer cannot tell from the timing when a transaction arrived. 0: announce to every peer as soon as a transaction is queued, as Core announces to a noban peer; transactions spread faster but peers learn when each one arrived here, which helps locate where it was first broadcast. Either way each peer is announced each transaction once, parents first, at most 70 per message (more for a long queue). To skip the wait for chosen peers only, give them noban (whitelist/whitebind) instead.
broadcastconfirmpeers1hotsatdDistinct peer IPs that must take a locally-broadcast tx before it counts as propagated and rebroadcast stops. A peer takes a tx by fetching it via getdata (the primary signal) or announcing it back via inv. Counted per IP, not per connection, so a reconnecting host is one witness. Raising it demands wider observed propagation before retries stop.
permitbaremultisigonhotcoreAllow bare multisig outputs.
bytespersigop20restartcoreVbytes charged per unit of sigop cost when the mempool and block template price a transaction: its size is the larger of its vsize and its sigop cost times this.
acceptnonstdtxnoffhotcoreRelay and accept non-standard transactions (bypass the standardness relay checks: oversize, dust, OP_RETURN/datacarrier, non-standard scripts). Consensus rules are never relaxed. Intended for test/dev networks.

Esplora

(satd-specific; native Esplora REST server. See Esplora REST API.)

KeyDefaultReloadCompatDescription
esploraonrestartsatdRun the native Esplora REST server (requires addressindex=1).
esplorabind127.0.0.1:3000restartsatdBind the Esplora REST listener.
esploratlsbindnonerestartsatdBind the Esplora TLS listener (requires cert+key).
esploratlscertnonerestartsatdPEM TLS certificate for the Esplora server.
esploratlskeynonerestartsatdPEM TLS private key for the Esplora server.
esploramtlsfalserestartsatdRequire mutual TLS on the Esplora TLS listener.
esploramtlsclientcanonerestartsatdPEM CA bundle to verify client certs when esploramtls=1.
esploramtlsclientallowany CA-signedrestartsatdAllowlist of accepted client-cert CN/DNS-SAN values.
esploraprefix/restartsatdURL prefix to mount the API under (/api for blockstream-style).
esploracorsnonerestartsatdAllowed CORS origin (repeatable).
esplorarequesttimeout30restartsatdPer-request handler timeout (seconds).
esploramaxconns256restartsatdHard cap on concurrent in-flight Esplora requests.
esplorasseconns= esploramaxconnsrestartsatdHard cap on simultaneously-open SSE streams (0 disables SSE).
esploramaxsockets1024restartsatdHard cap on open sockets across both Esplora listeners, counted at accept with idle keep-alive connections included; over the cap a socket is dropped. esploramaxconns bounds requests in flight and never sees a socket that sends nothing. 0 disables. A keep-alive connection idle for longer than esplorarequesttimeout is closed.
esploraauthnonerestartsatdEsplora auth mode: none|cookie|userpass.
esploraauthbearerfalserestartsatdHonor bearer tokens (esplora:read) on the Esplora server (requires authfile).
esploracookiefileshared .cookierestartsatdCookie file when esploraauth=cookie.
esplorauserpassnonerestartsatdStatic user:pass when esploraauth=userpass.

Electrum

(satd-specific; native Electrum protocol server.)

KeyDefaultReloadCompatDescription
electrumoffrestartsatdRun the native Electrum protocol server (requires addressindex=1 and txindex=1).
electrumbind127.0.0.1:50001restartsatdBind the Electrum plain-TCP listener.
electrumtlsbindnone (std port 50002)restartsatdBind the Electrum TLS listener (requires cert+key).
electrumtlscertnonerestartsatdPEM TLS certificate for the Electrum server.
electrumtlskeynonerestartsatdPEM TLS private key for the Electrum server.
electrummtlsfalserestartsatdRequire mutual TLS on the Electrum TLS listener.
electrummtlsclientcanonerestartsatdPEM CA bundle to verify client certs when electrummtls=1.
electrummtlsclientallowany CA-signedrestartsatdAllowlist of accepted client-cert CN/DNS-SAN values.
electrummaxconns64restartsatdHard cap on simultaneously-open Electrum connections.
electrummaxsubsperconn10000restartsatdPer-connection scripthash subscription cap.
electrumrequesttimeout30restartsatdPer-request handler timeout (seconds). Past it the client gets a request timed out error and the connection is closed; the connection keeps its slot until the handler's work ends.
electrummaxbatchrequests100restartsatdMax requests per JSON-RPC batch line. Wallets (Sparrow) batch their whole gap-limit window of subscribes at scan time.
electrummaxbroadcastpackagetxs25restartsatdMax txs per blockchain.transaction.broadcast_package.
electrumfeehistogramttl10restartsatdTTL (seconds) for the mempool.get_fee_histogram cache.
electrumbannerpowered by satd <ver>restartsatdOverride for server.banner.
electrumservernamesatd-electrs-compatible/<ver>restartsatdName reported by server.version and server.features.server_version. The default carries an electrs compatibility token because Electrum clients feature-detect by matching on this string (Cake Wallet probes silent-payment tweaks only when it contains electrs). Affects the Electrum surface only — the P2P user agent stays /satd:<ver>/.
stratumoffrestartsatdRun the Stratum V1 solo-mining server. Refused on signet. See Stratum Mining Server.
stratumbind127.0.0.1:3333restartsatdBind the plaintext Stratum listener. A non-loopback address needs stratumtlsbind or stratumallowplaintextremote=1.
stratumtlsbindnone (conventional port 4333)restartsatdBind the Stratum TLS listener (requires cert+key).
stratumtlscertnonerestartsatdPEM TLS certificate (or full chain) for the Stratum server.
stratumtlskeynonerestartsatdPEM TLS private key for the Stratum server.
stratummtlsfalserestartsatdRequire mutual TLS on the Stratum TLS listener.
stratummtlsclientcanonerestartsatdPEM CA bundle to verify client certs when stratummtls=1.
stratummtlsclientallowany CA-signedrestartsatdAllowlist of accepted client-cert CN/DNS-SAN values.
stratumaddressnonerestartsatdPayout address for a miner whose username is not a valid address for this network.
stratumdifficulty10000 mainnet, 1000 testnet, 1 regtestrestartsatdInitial Stratum share difficulty.
stratummaxconns64restartsatdHard cap on simultaneous Stratum connections across both listeners.
stratumallowplaintextremotefalserestartsatdAccept a non-loopback stratumbind with no TLS listener.
stratumv2bindnonerestartsatdBind the Stratum V2 listener (Noise-encrypted; requires stratum=1).
stratumv2key<datadir>/stratum_v2.keyrestartsatdStratum V2 authority key file, created if absent. Back it up with the datadir: miners pin the key.
stratumv2maxchannels16restartsatdChannels one Stratum V2 connection may open.
stratumv2jdfalserestartsatdServe Stratum V2 Job Declaration on the V2 listener (requires stratumv2bind).

Storage / pruning / reindex

KeyDefaultReloadCompatDescription
prune0 (no pruning)restartcorePrune block data to target size in MB.
pruneopreturn0 (off)restartsatdStrip OP_RETURN payloads from stored blocks more than N blocks deep (minimum 288; 1/all = 288). Blocks are still fully validated; the node stops serving historical blocks (NODE_NETWORK_LIMITED). One-way: see OP_RETURN data pruning.
pruneopreturnpeerslimitedrestartsatdWhat a stripping node serves to peers. limited: only the last 288 blocks, as a pruned Core node. intact: any block it still holds intact, at any depth; notfound for stripped ones. Both advertise only NODE_NETWORK_LIMITED.
pruneopreturnsize4096restartsatdStrip only OP_RETURN outputs whose scriptPubKey is at least this size. Bytes, or with a suffix: k/M (1000s), KiB/MiB (1024s).
restoreopreturns0 (off)restartsatdDownload the blocks OP_RETURN pruning stripped again, from peers that keep every block, until none is left; the node then serves the full chain (NODE_NETWORK) without a restart. Refused with any pruneopreturn* option. Does nothing on a node with no stripped block. See Restoring stripped blocks.
reindexoffrestartcoreRebuild block index and chain state from block files on disk. Set in the config file, it rebuilds on every start, as in Core: remove it once the rebuild is done.
reindexchainstateoffrestartcoreRebuild the UTXO set from existing block files (Core -reindex-chainstate). Same rule in the config file as reindex.
upgradechainstateoffrestartsatdRebuild the UTXO set from the block files, unprompted, when the datadir's chainstate schema is older than this satd's or a previous rebuild did not finish; otherwise nothing. Safe to leave on. Pruned nodes are refused (they must resync), and a newer schema is never downgraded. The app-store packages set it.
checkblockindexoff (on for regtest)restartcoreAudit block-index / active-chain consistency at startup (Core -checkblockindex).
dbcache450 MB (or auto)restartcoreTotal write-cache size in MB, or auto for adaptive sizing.
storageprofilessdrestartsatdStorage class for chainstate tuning: ssd or hdd.
prefetchworkersCPU coresrestartsatdNumber of IBD prefetch worker threads.
maxahead50000restartsatdMax blocks ahead during IBD: number, N%, or all.
maxopenfiles2048restartsatdRocksDB max_open_files cap; -1 = unlimited.
rocksdbbackgroundjobsfrom storageprofilerestartsatdOverride RocksDB max_background_jobs (advanced).
rocksdbsubcompactionsfrom storageprofilerestartsatdOverride RocksDB max_subcompactions (advanced).
rocksdbwalmbfrom storageprofilerestartsatdOverride RocksDB max_total_wal_size in MB (advanced).
compactiondiagintervalsecs60 (0 disables)restartsatdPer-CF pending-compaction diagnostic log interval.
compactionintervalsecs1800 (0 disables)restartsatdPeriodic forced-compaction interval in seconds.
compactionl0at16restartsatdForce chainstate compaction when L0 SST count ≥ N.
ibdl0pauseat64 (0 disables)restartsatdPause the IBD connector when chainstate L0 SST count ≥ N.
stallwatchdogsecs300 (0 disables)restartsatdStall-watchdog forensic-dump threshold (seconds without tip advance).
stallabortsecs300restartsatdAdditional grace after the forensics dump before abort().
shadowqueuesize4194304restartsatdShadow-verification queue capacity.
shadowqueuemb128 (0 disables)restartsatdMemory the shadow-verification queue may hold, in MiB; work past it is dropped.
shadowworkers4restartsatdShadow-verification worker threads.

Mining

KeyDefaultReloadCompatDescription
blockmaxweight4000000restartcoreMaximum block weight for templates, coinbase reserve included (Core's -blockmaxweight). Applies to getblocktemplate, generatetoaddress / generatetodescriptor and Stratum jobs (not to generateblock, whose caller lists the transactions, as in Core); a transaction package that would bring the template to the cap is left out, as in Core. Above 4,000,000 is refused at startup; below the 8,000 WU coinbase reserve is raised to it, which leaves room for no transactions. getblocktemplate's weightlimit still reports the consensus limit, as Core's does.
blockmintxfee1 sat/kvBrestartcoreMinimum fee rate for a transaction (judged with its package) to enter the block template. A bare integer is sat/kvB; a decimal is BTC/kvB, Bitcoin Core's spelling (0.00001 = 1000 sat/kvB).
parunsetrestartcoreScript-verification threads (Core name). When shadowworkers is unset, a positive value sets the shadow-verification worker count. It does not size the connect path.

Node attestation (NAP)

KeyDefaultReloadCompatDescription
napoffrestartsatdPublish Node Attestation Protocol attestations: enables createnapattestation, submitnapattestation, listnapattestations and removenapattestation, keeps the attestations submitted in <datadir>/nap/attestations.dat and its journal attestations.journal, serves the valid ones to peers that ask, and advertises the experimental NODE_NAP service bit (bit 30). See Node Attestation (NAP).
napaggregatoroffrestartsatdCollect Node Attestation Protocol attestations from publishers over P2P: pulls from connected peers that advertise NODE_NAP and opens short nap-pull connections to the ones the address book knows, verifies what they serve, keeps the set in <datadir>/nap/aggregate/aggregate.dat, and enables listnapaggregate, getnapreport and exportnapsnapshot. Independent of nap. See Node Attestation (NAP).
napaggregatormax1000000restartsatdWith napaggregator, the most attestations the collected set holds; 0 is no limit. When full, coin-and-key pairs new to the set are refused and counted (listnapaggregate's full); pairs already held still take newer attestations. A set already larger, after the limit is lowered, keeps what fits.
napmaxattestations0 (no limit)restartsatdWith nap, the most attestations the store holds. A submission that would add one more is refused (-26, store-full); replacing a stored one is allowed. A store already larger, after the limit is lowered, is kept whole.
napstorerecoveroffrestartsatdWith nap, an attestation store that does not read back at startup is renamed, attestations.dat and attestations.journal each with a .bad-<unix time> suffix, with a warning, and the node starts with an empty one. Off: startup fails, naming the file.

Events

(satd-specific event bus. The eventszmq* keys configure satd's own ZMQ socket, which carries the event envelope; for Bitcoin Core's ZMQ topics, use the zmqpub* keys in Bitcoin Core ZMQ below.)

KeyDefaultReloadCompatDescription
eventsnodeidauto (persisted to <datadir>/node_id)restartsatdStable per-node identifier (32-char hex) stamped on events envelopes.
eventsregionnonerestartsatdOptional region tag (≤8 ASCII bytes) on events envelopes.
eventsgrpcbindoffrestartsatdhost:port to bind the events gRPC streaming server.
eventsgrpcallowremotefalserestartsatdPermit eventsgrpcbind on a non-loopback address (requires eventsgrpcauth or eventsgrpcmtls; with eventsgrpcauth, also requires eventsgrpctlscert/eventsgrpctlskey so the bearer token is never sent in cleartext).
eventsgrpcauthfalserestartsatdRequire bearer tokens (stream:subscribe) on events gRPC (requires authfile).
eventsgrpcmaxconns64 (0 disables)restartsatdHard cap on simultaneously-open events gRPC connections.
eventsgrpcmaxsubscriptions256 (0 disables)restartsatdHard cap on concurrent events gRPC Subscribe and Watch streams.
eventsgrpctlscertoffrestartsatdPEM TLS certificate. Set with eventsgrpctlskey to terminate TLS in-process on the eventsgrpcbind listener (no separate TLS bind).
eventsgrpctlskeyoffrestartsatdPEM TLS private key (required with eventsgrpctlscert).
eventsgrpcmtlsfalserestartsatdRequire mutual TLS (client certificates). Requires eventsgrpctlscert/key and eventsgrpcmtlsclientca.
eventsgrpcmtlsclientcaoffrestartsatdPEM CA bundle verifying client certs when eventsgrpcmtls=1.
eventsgrpcmtlsclientallowempty (any CA-signed cert)restartsatdAllowlist of accepted client-cert CN / DNS-SAN values (repeatable, comma-separated). Requires eventsgrpcmtls=1.
eventsgrpctlshandshaketimeout30restartsatdPer-handshake timeout (seconds) for the events gRPC TLS surface.
streamwsoffrestartsatdhost:port for the streaming JSON-over-WebSocket + SSE transport (/ws + /sse).
streamwsallowremotefalserestartsatdPermit streamws on a non-loopback address (requires streamwsauth).
streamwsauthfalserestartsatdRequire bearer tokens (stream:subscribe) on streamws (requires authfile).
streamwsmaxconns256restartsatdHard cap on simultaneously-open streamws connections.
streamwsmaxsockets1024restartsatdHard cap on open sockets on the streamws listener, counted at accept before any request is parsed and held until the socket closes, so an open WebSocket keeps its slot; over the cap a socket is dropped. streamwsmaxconns is taken inside the handlers and never sees a socket that sends nothing. 0 disables. A keep-alive connection idle for 30 s between requests is closed (an open /ws or /sse stream is not idle).
streamwsmaxsubscriptions256restartsatdHard cap on watch-set entries per streamws connection.
streamwsmaxmessagebytes262144restartsatdCap on a single inbound WebSocket message/frame in bytes.
streammaxresyncblocks10000 (0 disables)restartsatdMax blocks the watch matcher re-scans in one catch-up after lagging.
streamprefixminbits8restartsatdMinimum bit-length for a privacy-preserving script-prefix watch.
streamprefixmaxbits32restartsatdMaximum bit-length for a script-prefix watch (range [min, 32]).
eventszmqbindoffrestartsatdZMQ endpoint for the events PUB sink.
eventszmqhashtxon when boundrestartsatdEnable the Core wire-format hashtx topic.
eventszmqhashblockon when boundrestartsatdEnable the Core wire-format hashblock topic.
eventszmqmpevicton when boundrestartsatdEnable mpevict topic (mempool eviction w/ reason; JSON).
eventszmqmpreplaceon when boundrestartsatdEnable mpreplace topic (RBF replacement; JSON).
eventszmqmpconfirmon when boundrestartsatdEnable mpconfirm topic (mempool tx confirmed; JSON).
eventszmqnodeeventon when boundrestartsatdEnable nodeevent topic (full envelope JSON).

Bitcoin Core ZMQ

Bitcoin Core's ZMQ notifications, with Core's messages byte for byte. Each address key may be given more than once; every value is a notifier, and notifiers on the same address share a socket. unix:<path> binds a Unix socket (reported as ipc://<path>); ipc://<path> is also accepted. An address that cannot be bound turns ZMQ off and the node keeps running, as in Core; an address with one : and an invalid port stops startup. See Bitcoin Core ZMQ compatibility for what each topic publishes and the ordering guarantee.

KeyDefaultReloadCompatDescription
zmqpubhashblockoffrestartcorePublish each new tip's hash on hashblock at <address> (not during initial block download).
zmqpubhashtxoffrestartcorePublish the txid of each mempool admission and of each transaction in a connected or disconnected block on hashtx.
zmqpubrawblockoffrestartcorePublish each new tip's serialized block on rawblock (not during initial block download).
zmqpubrawtxoffrestartcorePublish each mempool admission and each transaction in a connected or disconnected block, serialized with its witness, on rawtx.
zmqpubsequenceoffrestartcorePublish sequence records: C/D for a connected/disconnected block, A/R with the mempool sequence number for a mempool admission/removal.
zmqpubhashblockhwm1000restartcoreOutbound high-water mark of the hashblock notifiers, in messages per subscriber; 0 is unlimited. A value that is not a number reads as 0 and a negative one keeps 1000, as in Core.
zmqpubhashtxhwm1000restartcoreAs zmqpubhashblockhwm, for hashtx.
zmqpubrawblockhwm1000restartcoreAs zmqpubhashblockhwm, for rawblock.
zmqpubrawtxhwm1000restartcoreAs zmqpubhashblockhwm, for rawtx.
zmqpubsequencehwm1000restartcoreAs zmqpubhashblockhwm, for sequence.

A socket shared by several topics takes the first one's high-water mark, in the order the table lists them. On top of it, a subscriber with more than 256 MiB of unsent messages loses further ones until it catches up.

Webhooks / notifications

KeyDefaultReloadCompatDescription
blocknotifynonerestartcoreShell command run on each new best block; %s is replaced by the block hash. Commands run serially on a dedicated subscriber task; a slow hook never stalls block connection, because notifications coalesce instead. The command body is not logged (it may embed credentials).
alertnotifynonerestartcoreShell command run on each new node warning; %s is replaced by the warning text. Deduped by warning id (a repeated condition fires once, not per repeat). One-shot events such as deep_reorg have no standing condition to dedupe, so they are rate-limited instead: one exec per minute per event id, reporting the worst occurrence in the window rather than the first. Runs serially like blocknotify. Live from the start of chain loading, so warnings raised during startup (a -reindex that halts or ends short) fire it too. See Observability → Node-health alerts.
startupnotifynonerestartcoreShell command run once after the node finishes starting up (no %s). Detached, so a slow hook does not delay startup. Prefer a systemd ExecStartPost=.
shutdownnotifynonerestartcoreShell command run once at the start of a graceful shutdown, before the final flush (no %s). Bounded by maxshutdownsecs so a hung hook can't wedge teardown. Prefer a systemd ExecStopPost=.
reorgwebhooknonehotsatdHTTP(S) endpoint receiving a POST on reorg detection.
reorgwebhooksecretnonehotsatdHMAC-SHA256 secret signing webhook bodies via X-Satd-Signature.

Health alerts

Thresholds for the node-health detectors. Each raises a status event on the Streaming Consumption API and an entry in getwarnings (which also fires alertnotify) when its condition is entered, and retracts both when it recovers. Every one is hot-reloadable — retuning an alert should not need a restart, since you are usually retuning it because it is firing.

Set a threshold to 0 to disable that detector. See Observability → Node-health alerts for the taxonomy and the details each event carries.

KeyDefaultReloadCompatDescription
alertfilenonepath restart, contents hotsatdTOML file describing outbound alert webhooks. Must be mode 0600 — it holds signing secrets. The path is read once at startup; the file's contents are re-read on every SIGHUP, so a hook can be added, edited, or removed live. A parse error keeps the last-good hook set. See Observability → Alert webhooks.
alerttipstallseconds3600 (0 on regtest)hotsatdRaise tip_stall after this many seconds with no connected block. Defaults to disabled on regtest only, where blocks exist just when a test mines them and an idle chain is normal; every other network — test networks included — keeps the hour, since going an hour without a block is not an ordinary property of thin hashrate the way a shallow reorg is. Not suppressed during initial block download — is_initial_block_download() compares the tip header's timestamp against the wall clock rather than tracking sync progress, so a node that was caught up and then wedged re-enters it precisely when you need paging. A node that is genuinely syncing moves its tip continuously and so never crosses the threshold: the detector watches the tip itself, not just block-connected notifications, because the block-download path connects without emitting any. Cleared the moment a block connects — or, if the tip moved without a notification, or you raise this value past the current tip age, on the next detector poll.
alertdiskfreemb10240hotsatdRaise disk_low below this many MiB free on the blocks directory (or the data directory when blocksdir is not split out). Clears at 1.5× the floor, or as soon as you lower the floor below the current reading.
alertmempoolfullpct90hotsatdRaise mempool_congested at this percentage of maxmempool. Clears below 75 % of the raise line, or as soon as you raise the threshold above the current occupancy. Values above 100 are clamped.
alertpeerfloor3 (0 on regtest; capped by the -connect= count)hotsatdRaise peer_floor below this many connected peers (inbound + outbound). The count must hold for 60 s in either direction, so ordinary peer churn does not page you, and it does not raise until 90 s after startup or the first peer, whichever is sooner. Defaults to disabled on regtest only, where a node with no peers is normal; signet keeps the floor — set alertpeerfloor=0 explicitly on a deliberately isolated signet node. When connect= is set the default drops to that many peers (never above 3), since connect= suppresses DNS and fixed seeds and the node can never exceed the addresses you named — an explicit value here still overrides it.
alertreorgdepth3 (10 on test networks, 0 on regtest)hotsatdEmit the one-shot deep_reorg event for a reorg that rolls back at least this many blocks. Depth 3 is an incident on mainnet and ordinary on a chain with thin, volatile hashrate, so signet/testnet/testnet4 default to 10 — above the 6-confirmation convention, so a reorg that invalidated something a wallet called final still reports. Regtest defaults off: its test suites reorg deliberately.

Note. The *notify shell hooks (blocknotify, alertnotify, startupnotify, shutdownnotify) exist for drop-in Bitcoin Core compatibility and quick scripts. They are best-effort shell execs with no delivery guarantee, no replay, and no reorg awareness. To build on satd, use the Streaming Consumption API (gRPC, WebSocket, or ZMQ): it is reorg-safe, offers durable cursor replay, and is decoupled from consensus. For lifecycle actions, prefer your service manager (systemd ExecStartPost= / ExecStopPost=). satd honors these four hooks. Only walletnotify is unsupported: satd is keyless, so watch scripts via the streaming or Esplora API. A node started with any of these hooks logs this guidance at startup.

MCP

(satd-specific; Model Context Protocol server.)

KeyDefaultReloadCompatDescription
mcpoffrestartsatdEnable the MCP server.
mcpportnonerestartsatdEnable the MCP HTTP transport on this port.
mcpbind127.0.0.1restartsatdMCP HTTP bind address (non-loopback requires auth + TLS).
mcpcertnonerestartsatdPEM TLS certificate for the MCP server (enables HTTPS; requires mcpkey). Required for any non-loopback bind.
mcpkeynonerestartsatdPEM TLS private key for the MCP server (requires mcpcert).
mcpmtlsfalserestartsatdRequire mutual TLS on the MCP listener (requires mcpcert/mcpkey + mcpmtlsclientca).
mcpmtlsclientcanonerestartsatdPEM CA bundle that client certs must chain to when mcpmtls.
mcpmtlsclientallowanyrestartsatdAllowlist of accepted client-cert CN / DNS-SAN values.
mcpauthfalserestartsatdRequire bearer tokens (mcp:*) on the MCP HTTP server (requires authfile).
mcpallowremotefalserestartsatdPermit a non-loopback MCP HTTP bind (requires mcpauth + TLS).
mcpallowedhostloopback onlyrestartsatdExtra Host values the MCP listener accepts, as host or host:port (repeatable, comma-separated). Loopback names are always accepted. Required to reach MCP by hostname.

Metrics / health

KeyDefaultReloadCompatDescription
metricsportnonerestartsatdEnable Prometheus /metrics + /healthz + /readyz on this port (unauthenticated).
metricsbind127.0.0.1restartsatdMetrics/health HTTP bind address.
metricstlsbindnonerestartsatdAlso serve the metrics/health endpoints over TLS on this addr:port (requires metricsport, cert and key).
metricstlscertnonerestartsatdPEM certificate for the metrics TLS listener.
metricstlskeynonerestartsatdPEM private key for the metrics TLS listener.
metricsmtlsfalserestartsatdRequire a client certificate on the metrics TLS listener (requires metricsmtlsclientca).
metricsmtlsclientcanonerestartsatdPEM CA bundle client certs must chain to when metricsmtls=1.
metricsmtlsclientallowanyrestartsatdAllowlist of accepted client-cert CN / DNS-SAN values on the metrics TLS listener.
statuspage0restartsatdServe the status page at /status, /status.json and /status.js on the metrics listener. Requires metricsport.
statusadvertisenonerestartsatdRepeatable, one per surface. <surface>=<url>, where surface is electrum, esplora, rpc or mcp: a connection string the status page shows, e.g. electrum=ssl://node.local:50002.

Unsupported Core keys: skipped vs rejected

A Core v30 option satd doesn't honor is handled one of two ways so that an existing bitcoin.conf still drops in.

Skipped with a warning (the node still starts)

Recognized Core v30 options satd doesn't implement, but that are safe to skip, are ignored with a startup WARN line; the node boots without them. The warning names the satd equivalent where one exists. This covers the long tail:

Key(s)Warning guidance
restsatd ships native Esplora REST instead of Core's /rest/; enable with -esplora (on by default).
peerbloomfiltersBIP37 unsupported (privacy/DoS); use BIP157/158 (-blockfilterindex/-peerblockfilters).
natpmpsatd doesn't implement PCP/NAT-PMP port mapping; configure port forwarding externally. (upnp was removed in Core v29 and is rejected as unknown, as in Core v30.)
debuglogfile, shrinkdebugfile, printtoconsole, logratelimitsatd logs to stdout/journald; no debug.log.
logtimemicrossatd's logger always emits sub-second timestamps; there is no seconds-only mode, so the option has no effect. Use -logtimestamps=0 to drop timestamps entirely.
maxorphantxRemoved in Core v30 too.
wallet, walletdir, walletnotify, …satd is keyless (no wallet); use external wallets + PSBT, and watch scripts via the streaming/Esplora API.
coinstatsindex, loadblock, checkblocks/checklevel, maxsigcachesize, blockversion, printpriority, txreconciliation, discover, persistmempoolv1, acceptstalefeeestimates, settings, daemonwait, rpcdoccheck, …Recognized Core v30 options satd does not implement; skipped (generic warning).

Rejected at load (fail-closed)

A small set stays fatal, because silently skipping them would mislead you about the node's security, exposure, or privacy posture. Each rejects with an actionable message:

Key(s)Reason
i2psam, i2pacceptincomingI2P is out of scope; skipping would route traffic over clearnet instead of the privacy network you configured. Tor is satd's anonymity network (-proxy/-onion/-torcontrol).

Typos

A key that is neither a satd option nor a known Core v30 option is rejected at load as a likely typo. This is what stops a mistyped rpcusser= from silently disabling authentication. The same rule catches Core v31+ keys: the compatibility surface is frozen at v30, so a key Core only added later is treated as unknown until the pin is bumped.

Note. "Supported" means the commonly used Core v30 operator surface, with semantics pinned to Core v30 (not later releases). The long tail is skipped with a warning rather than honored. To consume node events from your own software, use the Streaming Consumption API instead of the *notify hooks or RPC polling.