pub struct BlockchainConfig {Show 27 fields
pub rpc_url: Option<String>,
pub eth_keystore: Option<PathBuf>,
pub payment_pool_address: Option<String>,
pub capacity_bond_address: Option<String>,
pub origin_assignment_address: Option<String>,
pub origin_directory_positive_ttl_sec: Option<u64>,
pub origin_directory_negative_ttl_sec: Option<u64>,
pub origin_directory_cache_capacity: Option<usize>,
pub publisher_registry_address: Option<String>,
pub slash_judge_address: Option<String>,
pub slash_appeal_address: Option<String>,
pub content_blacklist_address: Option<String>,
pub content_blacklist_poll_interval_sec: Option<u64>,
pub chain_staleness_grace_sec: Option<u64>,
pub chain_id: Option<u64>,
pub rpc_watchdog_interval_sec: Option<u64>,
pub event_poll_interval_ms: Option<u64>,
pub get_logs_max_block_span: Option<u64>,
pub fee_shares_poll_interval_sec: Option<u64>,
pub redeem_threshold_micro_usdc: Option<u64>,
pub redeem_max_vouchers_per_tx: Option<u64>,
pub redeem_interval_secs: Option<u64>,
pub buyer_working_deposit_micro_usdc: Option<u64>,
pub buyer_max_approve: Option<bool>,
pub pool_min_remaining_deposit_micro_usdc: Option<u64>,
pub pool_floor_signer_live_windows: Option<u64>,
pub usdc_address: Option<String>,
}Expand description
Blockchain section of the config file.
Fields§
§rpc_url: Option<String>JSON-RPC endpoint URL.
eth_keystore: Option<PathBuf>Ethereum keystore file path.
payment_pool_address: Option<String>PaymentPool contract address — the shared payment pool this node
registers against for buyer and seller flows alike.
capacity_bond_address: Option<String>CapacityBond contract address.
origin_assignment_address: Option<String>OriginAssignment contract address. Optional: when set, the node runs the
chain-backed origin directory for node-to-node routing, resolving a
request’s namespace via getOrigins(namespaceId) (ADR 022) for the
FIND_VALUE fallback. Unset => the origin directory is empty, so that
fallback resolves nothing.
origin_directory_positive_ttl_sec: Option<u64>Positive-hit TTL for the lazy origin directory cache, in seconds. Only
consulted when origin_assignment_address is set. Absent =>
DEFAULT_ORIGIN_DIRECTORY_POSITIVE_TTL_SEC.
origin_directory_negative_ttl_sec: Option<u64>Negative-hit TTL for the lazy origin directory cache, in seconds. Only
consulted when origin_assignment_address is set. Absent =>
DEFAULT_ORIGIN_DIRECTORY_NEGATIVE_TTL_SEC.
origin_directory_cache_capacity: Option<usize>Max distinct namespaces held in the lazy origin directory cache (LRU
eviction). Only consulted when origin_assignment_address is set.
Absent => DEFAULT_ORIGIN_DIRECTORY_CACHE_CAPACITY.
publisher_registry_address: Option<String>PublisherRegistry contract address. Independent of the origin directory:
it is the publish CLI’s namespace create target and is not consumed by
the node runtime.
slash_judge_address: Option<String>SlashJudge contract address — the EIP-712 verifyingContract for
ProbeResponse / StreamResponse slash_sig signatures (ADR 014
§1–2). Required: a wrong/zero address silently produces signatures no
verifier accepts, so resolution fails fast when it is missing rather
than defaulting.
slash_appeal_address: Option<String>SlashAppeal contract address — the target for decdn appeal slash
(ADR 028). Consumed only by that CLI (via chain_ctx::resolve_appeal,
which validates it); the daemon accepts the key here — [blockchain]
denies unknown fields and a node’s node.toml is shared with the CLI —
but does not resolve or use it.
content_blacklist_address: Option<String>ContentBlacklist contract address. Required at node config resolution;
startup completes the initial global + operator-scope replay before any
ALPN accepts connections (ADR 011/019/031).
content_blacklist_poll_interval_sec: Option<u64>Seconds between the blacklist watcher’s periodic replay + re-scope pass
(ADR 011 §Polling cadence). This backstop is what catches scope changes
with no ContentBlacklist event — an operator region/ripening
transition. Absent =>
super::DEFAULT_CONTENT_BLACKLIST_POLL_INTERVAL_SEC (600s). Only
consulted when content_blacklist_address is set.
chain_staleness_grace_sec: Option<u64>Seconds the node may go without a successful chain read before it stops
serving (ADR 011 § Serving while chain-stale). While the blacklist
watcher cannot reach the RPC, every chain-derived serve guard — the
deny-set, pool solvency, per-signer caps — answers from stale state, so a
takedown that lands during the outage would go unenforced and serving it
past the compliance window is slashable. Past this window the serve and
probe paths refuse rather than sign evidence the node can no longer
vouch for. Always evaluated (there is no on/off flag); set it large to
opt out. Absent => super::DEFAULT_CHAIN_STALENESS_GRACE_SEC (1800s /
30 min). Must not be 0 (that would refuse every serve). Only consulted
when content_blacklist_address is set.
chain_id: Option<u64>EIP-712 chainId bound into every slash_sig domain separator.
Absent => super::DEFAULT_CHAIN_ID (Arbitrum Sepolia, the initial
network target — matches the chain id bound on the runtime signer).
rpc_watchdog_interval_sec: Option<u64>Seconds between RPC connectivity watchdog probes. 0 disables the
watchdog entirely; absent => default (30s). Non-zero values below
MIN_RPC_WATCHDOG_INTERVAL_SEC are rejected at config resolution.
event_poll_interval_ms: Option<u64>Milliseconds between chain-event poll ticks (#1011, #1106). Drives two
unrelated consumers: the eth_getLogs tick cadence of every chain
watcher, and alloy’s pending-transaction receipt heartbeat (see
ResolvedBlockchain::event_poll_interval_ms). The heartbeat is why this
overrides alloy’s own default, which is 250 ms for a localhost RPC (it
auto-detects 127.0.0.1/localhost) and 7000 ms otherwise — the 250 ms
local default hammers a dev anvil. Absent => default
(DEFAULT_EVENT_POLL_INTERVAL_MS, 7000 ms, matching alloy’s non-local
cadence so live-RPC load is unchanged). Values below
MIN_EVENT_POLL_INTERVAL_MS are rejected at config resolution.
get_logs_max_block_span: Option<u64>Maximum block span of one chain-watcher eth_getLogs request. Set it to
the RPC provider’s actual eth_getLogs range limit: the lowest span
the poller reaches while rejections keep coming (the shrink warn! and
the decdn_chain_get_logs_span gauge show it). A provider’s documented
or quoted limit can be wrong. The poller also shrinks its window on its own when the provider
rejects a range, and grows it back toward this ceiling, so this is a
ceiling, not a hard requirement. Absent =>
super::DEFAULT_GET_LOGS_MAX_BLOCK_SPAN (10 000). Must not be 0;
rejected at config resolution.
Seconds between authoritative FeeRouter.getShares() re-reads by the
fee-shares watcher (ADR 041 / ADR 016 § Tunable Economics). This is the
safety-net cadence in addition to the SharesUpdated event
subscription (which follows Self::event_poll_interval_ms); it
reconciles any log the event tail missed. Absent =>
super::DEFAULT_FEE_SHARES_POLL_INTERVAL_SEC (3600s / 1h). Must not
be 0 (that would poll every tick); rejected at config resolution.
redeem_threshold_micro_usdc: Option<u64>Per-chunk redemption floor (base units, µUSDC, ADR 003 § Operator
early withdrawal). The node submits an on-chain redemption
transaction for a chunk of lanes only once the aggregate un-redeemed
value across that chunk’s lanes reaches this floor; every lane in a
submitted chunk settles, so a small (dust) lane rides alongside the
larger lanes that cleared the floor. Larger values amortize gas
across more delivery; smaller values bound unsettled exposure.
Absent => default (1 USDC = 1_000_000 µUSDC).
redeem_max_vouchers_per_tx: Option<u64>Maximum vouchers packed into one redeemMany transaction. The redeemer
splits a sweep across this many vouchers per transaction so a high-fan-out
node stays under the block gas limit; a chunk that still fails to send
oversized is halved and retried. Absent => default (300). Must not be
0; rejected at config resolution.
redeem_interval_secs: Option<u64>Seconds between the redeemer’s self-tick sweeps (#327, #751): the
low-frequency backstop that sweeps every lane and redeems the chunks
that clear the redemption floor, independent of the advisory per-voucher
hints, so a dropped hint can never strand an accrued balance. Smaller values withdraw earnings sooner
at the cost of more pool-state reads; larger values lean harder on the
hints. Absent => default (300s / 5 min). Must not be 0; rejected at
config resolution.
buyer_working_deposit_micro_usdc: Option<u64>Deposit (base units, µUSDC) the buyer path escrows when it opens a
payment pool, and the target every top-up refills the pool balance
toward once it is reused or runs short mid-transfer. The shared pool is
fully withdrawable, so the buyer opens at this amount directly rather
than escrowing a smaller first-contact lock. Both refill legs target
it: the low-water refill, which both binaries run on pool reuse, and
the funding recovery step, which every fetch path (decdn fetch,
decdn bundle pull, and the daemon’s node-to-node cache-miss pull)
runs once no node serves at the current deposit (#1530). Larger values amortize gas across more delivery at
the cost of more capital locked. Absent => default (10 USDC =
10_000_000). Must be nonzero (the pool’s openPool reverts on a zero
deposit).
buyer_max_approve: Option<bool>Whether to issue an unlimited (max) USDC approval for the
PaymentPool contract so the buyer path can join a pool (#744).
The absent-default is profile-dependent: the node daemon defaults to
true (a long-lived operator amortizes one unlimited approval across many
node-to-node miss pulls), while the decdn client fetch commands (fetch,
bundle pull) default to false, i.e. an exact deposit-sized approval
scoped to what each pool escrows. Set true on the client to opt a
power user back into the unlimited allowance.
pool_min_remaining_deposit_micro_usdc: Option<u64>The node’s refundable floor M (base units, µUSDC): the minimum
remaining on-chain pool balance the node insists on keeping in reserve
(ADR 003 § Sizing, M = k·ρ·B·Δ — a function of the redeem cadence k,
the node’s advertised rate ρ, the credit window B, and the round-trip
slack Δ). The node stops serving a pool once its remaining on-chain
balance minus M can no longer cover the next credit window, so a buyer
that drains its pool balance cannot leave the node’s already-delivered,
not-yet-redeemed bytes stranded. Absent => default (1 USDC =
1_000_000 µUSDC), a conservative static value at the redeem-threshold
scale; sizing this precisely per ADR 003 is governance/ops policy, not a
build-time constant.
pool_floor_signer_live_windows: Option<u64>Per-signer LIVE concurrency cap k, counted in ramp-start credit windows
(ADR 003 § Pool solvency, per-signer floor isolation): the most live
un-vouchered floor reservation any ONE capability signer may hold against a
pool, k · one credit window, underneath the pool-wide remaining − M
ceiling. The credit window is one chunk normally, and at
credit_ramp_divisor == 0 it is credit_max raised to one chunk.
This bounds concurrency, not paid throughput: a signer that pays its vouchers releases that stream’s reservation, so its cap recycles and a stream already under way is never slowed. It carries no permanent memory and never penalizes a signer for quitting.
The window is the unit actually being rationed: honest need is concurrent un-vouchered streams × one window regardless of the pool’s size, so an absolute
window count fits it directly. Node-local risk policy — it needs no pool-owner
cooperation. Lower-clamped to one window (so a lone signer’s first stream is
always admissible). Absent => default (8). See
DEFAULT_POOL_FLOOR_SIGNER_LIVE_WINDOWS.
usdc_address: Option<String>USDC settlement-token contract address — the ERC-20 clients spend on
deposits into a payment pool. Declared here so a client config that names
it passes decdn config validate under this section’s
deny_unknown_fields; the running client resolves the token at runtime
from PaymentPool.usdc().
Trait Implementations§
Source§impl Debug for BlockchainConfig
impl Debug for BlockchainConfig
Source§impl Default for BlockchainConfig
impl Default for BlockchainConfig
Source§impl<'de> Deserialize<'de> for BlockchainConfig
impl<'de> Deserialize<'de> for BlockchainConfig
Source§fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>where
__D: Deserializer<'de>,
fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>where
__D: Deserializer<'de>,
Auto Trait Implementations§
impl Freeze for BlockchainConfig
impl RefUnwindSafe for BlockchainConfig
impl Send for BlockchainConfig
impl Sync for BlockchainConfig
impl Unpin for BlockchainConfig
impl UnsafeUnpin for BlockchainConfig
impl UnwindSafe for BlockchainConfig
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
impl<T> DeserializeOwned for Twhere
T: for<'de> Deserialize<'de>,
Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
Source§fn in_current_span(self) -> Instrumented<Self> ⓘ
fn in_current_span(self) -> Instrumented<Self> ⓘ
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more