Reason codes配置Share 事件安全边界
VELDRA · 运营者参考

文档

跨越 Veldra 边界的每一个 reason code、每一个配置项、每一个事件字段。一页尽收。源自 reservegrid-common 中的 Rust 权威类型。

95
Reason codes
91 Phase 1 · 4 Phase 2
69
配置项
policy.toml + gateway.toml
13
类别
verifier · gateway · share · …
2
Share 事件
share_accepted · forward_result
§ 1 · Reason codes

网关可发出的 95 个 reason code。

每一次拒绝、每一次降级、每一次内部故障都带有一个稳定的 snake_case 标识符。它们是验证器、网关、传输、share 路径与 Invariant Shield 各自 ReasonCode 的并集。在 minor 版本之间保持稳定;新的 code 只在增量式发布中新增。

95 个 CODES
protocol_version_mismatch
Template protocol version does not match expected
Template Policy
invalid_prev_hash
Template prev_hash is not 32 bytes or does not parse
Template Policy
prev_hash_len_mismatch
Wire prev_hash length differs from header expectation
Template Policy
coinbase_value_zero_rejected
Coinbase output value is zero and policy rejects it
Template Policy
empty_template_rejected
Template contains zero non-coinbase transactions
Template Policy
tx_count_exceeded
Template tx count exceeds policy maximum
Template Policy
total_fees_below_minimum
Sum of fees below configured minimum
Template Policy
avg_fee_below_minimum
Average fee per vByte below configured minimum
Template Policy
policy_load_error
policy.toml could not be parsed or violates schema
Template Policy
mempool_backend_unavailable
Phase 2 RPC backend unreachable; verifier degrades to Phase 1
Template Policy
weight_ratio_exceeded
Template weight ratio exceeds policy maximum
Template Policy
template_stale
Template age exceeds max_template_age_ms
Template Policy
sigops_budget_warning
Sigops within block budget but ratio above warn threshold
Template Policy
coinbase_sigops_abnormal
Coinbase script sigops count is abnormally high
Template Policy
v2_invariant_coinbase_value_mismatch
Re-derived coinbase value disagrees with declared total
Phase 1 (S+D)
v2_invariant_template_weight_mismatch
Re-derived template weight differs from declared
Phase 1 (S+D)
v2_invariant_merkle_root_mismatch
Re-derived merkle root does not match block header
Phase 1 (S+D)
v2_invariant_witness_commitment_missing
Block has segwit txs but no witness commitment output
Phase 1 (S+D)
v2_invariant_witness_commitment_mismatch
Witness commitment output does not match witness root
Phase 1 (S+D)
v2_invariant_sigops_mismatch
Re-derived total sigops disagrees with declared
Phase 1 (S+D)
v2_invariant_coinbase_sigops_mismatch
Re-derived coinbase sigops disagrees with declared
Phase 1 (S+D)
v2_invariant_tx_count_mismatch
Re-counted txs disagrees with declared count
Phase 1 (S+D)
v2_invariant_coinbase_script_length
Coinbase script length outside protocol bounds (2..=100 bytes)
Phase 1 (S+D)
v2_invariant_coinbase_output_count
Coinbase output count is zero
Phase 1 (S+D)
v2_invariant_coinbase_bip34_missing
Coinbase script lacks BIP-34 height push
Phase 1 (S+D)
v2_invariant_coinbase_height_mismatch
BIP-34 height in coinbase ≠ declared template height
Phase 1 (S+D)
v2_invariant_weight_exceeds_max
Template weight exceeds 4 000 000 (consensus max)
Phase 1 (S+D)
v2_invariant_sigops_exceed_max
Template sigops exceed 80 000 (consensus max)
Phase 1 (S+D)
v2_invariant_nontcb_null_prevout
Non-coinbase transaction has a null prevout
Phase 1 (S+D)
v2_invariant_header_version_low
Block header version below BIP-34 minimum (2)
Phase 1 (S+D)
v2_invariant_duplicate_tx
Duplicate txid present in template
Phase 1 (S+D)
v2_invariant_decode_failed
Could not decode raw transaction bytes
Phase 1 (S+D)
v2_invariant_mempool_tx_unknown
Phase 2: template tx not present in operator mempool snapshot
Phase 2 (M)
v2_invariant_mempool_tolerance_exceeded
Phase 2: unknown-tx ratio exceeds [policy.mempool] tolerance_pct
Phase 2 (M)
v2_invariant_mempool_unavailable
Phase 2: bitcoind RPC unavailable; degraded to Phase 1
Phase 2 (M)
v2_invariant_mempool_view_stale
Phase 2: mempool snapshot age exceeds max_stale_secs
Phase 2 (M)
auth_failed
API key or HMAC signature did not validate
运营
unsupported_algorithm
Auth or signing algorithm unknown to this build
运营
rate_limited
Caller exceeded RPS quota for this endpoint
运营
payload_too_large
Body exceeds max_payload_bytes
运营
invalid_content_type
Content-Type does not match expected media
运营
payload_unknown_field
JSON payload contains an unknown field (strict deserializer)
运营
payload_field_out_of_range
Numeric field outside accepted bounds
运营
payload_malformed
Body could not be parsed as JSON
运营
payload_nesting_exceeded
JSON nesting exceeds the parser ceiling
运营
request_expired
Signed request timestamp outside replay window
运营
request_replayed
Request HMAC matches a previously-seen one
运营
handler_timeout
Handler exceeded handler_timeout_ms before responding
运营
config_invalid
Config file failed validation at startup
运营
internal_line_too_large
Internal NDJSON message exceeded MAX_INTERNAL_LINE_BYTES (1 MiB)
运营
internal_framing_error
Internal NDJSON message could not be parsed
运营
internal_version_mismatch
Internal msg_type version not supported
运营
internal_unknown_msg_flood
Unknown msg_type exceeded MAX_UNKNOWN_MSG_TYPE_PER_MINUTE
运营
noise_handshake_failed
Noise NX handshake did not complete
SV2 + 连接
noise_handshake_timeout
Handshake exceeded handshake_timeout_ms
SV2 + 连接
unsupported_protocol_version
Miner offered unsupported SV2 protocol version
SV2 + 连接
frame_decode_error
SV2 binary frame could not be decoded
SV2 + 连接
frame_too_large
Frame exceeded maximum allowed size
SV2 + 连接
connection_rate_limited
Inbound connections exceeded per-IP rate limit
SV2 + 连接
peer_quota_exceeded
Peer exceeded rate_limit_messages_per_sec or _bytes_per_sec
SV2 + 连接
miner_unauthorized
Miner credentials did not validate against whitelist
矿工授权
identity_prefix_unmatched
Worker identity prefix not in pool's expected list
矿工授权
identity_too_long
Worker identity longer than max_worker_id_bytes
矿工授权
channel_open_rejected
OpenMiningChannel denied (mapped to SV2 error)
生命周期
channel_limit_exceeded
Connection exceeded max_channels_per_connection
生命周期
invalid_channel_id
Channel ID not recognized for this connection
生命周期
extended_channel_unsupported
Extended channel requested; this build only supports standard channels
生命周期
prevhash_switch_timeout
Prevhash verdict not received within prevhash_verdict_timeout_ms
Template + Prevhash
prevhash_verdict_rejected
Prevhash verdict was 'reject'; gateway fail-closed
Template + Prevhash
template_cache_miss
Job references a template the gateway no longer has
Template + Prevhash
stale_job_submission
Submission references a job from a prior prevhash epoch
Template + Prevhash
upstream_unavailable
Template source (template-manager) not reachable
Template + Prevhash
missing_gateway_signature
Share posted without HMAC header
HMAC
malformed_gateway_signature
HMAC header could not be decoded
HMAC
malformed_event_id
Event ID is not a valid v7 ULID/UUID
HMAC
invalid_gateway_signature
HMAC signature did not validate against gateway key
HMAC
share_replay_detected
Share event_id matches a recently-seen one (dedup window)
Share 校验
share_difficulty_below_target
Submitted difficulty below configured minimum
Share 校验
share_invalid_job_id
Submission references unknown job ID
Share 校验
share_invalid_nonce
Header bytes hash does not satisfy share difficulty
Share 校验
version_bit_violation
version_bits outside BIP-320 general purpose mask
Share 校验
ntime_out_of_range
Submitted ntime outside template-allowed window
Share 校验
share_forward_failed
Could not POST share to upstream within retry budget
Share 校验
share_upstream_rejected
Upstream (pool/template-manager) returned a non-2xx status
Share 校验
share_dropped_queue_full
Outbound share queue at capacity; backpressure policy = drop
Share 校验
share_evicted_from_queue
Share evicted by newer entry under FIFO eviction
Share 校验
share_rate_limited
Per-account share rate exceeded pool_account_rate_limit
Share 校验
process_crash_recovery
Synthetic forward result for shares orphaned by a crash
崩溃恢复
wal_write_failure
WAL append failed; gateway shutting down to preserve durability
崩溃恢复
peer_transport_error
Peer TCP connection dropped or transport I/O error
SV2 + 连接
channel_open_timeout
Peer did not OpenMiningChannel within channel_open_timeout_ms
生命周期
setup_connection_rejected
SV2 SetupConnection exchange failed
SV2 + 连接
shutdown_drain
Gateway is draining connections during graceful shutdown
健康探针
startup_pending
Gateway has not completed startup initialization
健康探针
internal_error
Catch-all for unexpected internal failures
系统
§ 2 · 配置

policy.toml + gateway.toml 共 69 个键。

启动时校验。非法值会以 config_invalid 触发 fail-closed。Phase 2 的 mempool 配置块需显式启用;默认部署只运行 Phase 1。

policy.toml · [policy] · 12
配置项类型默认值说明
protocol_versionu162Highest accepted TemplatePropose protocol_version.
required_prevhash_lenusize64Required prev_hash length in hex characters.
min_total_feesu640Minimum sum of fees in a template (sats).
max_tx_countu3210000Maximum non-coinbase transactions per template.
low_mempool_txu6450Below this mempool tx count the low fee tier applies.
high_mempool_txu64500At or above this mempool tx count the high fee tier applies.
min_avg_fee_lou640Minimum average fee per tx, low tier (sats).
min_avg_fee_midu640Minimum average fee per tx, mid tier (sats).
min_avg_fee_hiu640Minimum average fee per tx, high tier (sats).
reject_empty_templatesbooltrueReject templates with zero non-coinbase transactions.
reject_coinbase_zeroboolfalseReject templates whose coinbase value is zero.
unknown_mempool_as_highbooltrueTreat an unknown mempool size as the high fee tier.
policy.toml · [policy.safety] · 6
配置项类型默认值说明
max_weight_ratiof640.999Maximum template weight as a fraction of the 4M weight cap.
enforce_weight_ratioboolfalseReject, not just warn, when the weight ratio is exceeded.
max_template_age_msu64?unsetReject templates older than this; unset disables the check.
enforce_template_ageboolfalseReject, not just warn, when a template exceeds max_template_age_ms.
warn_sigops_ratiof640.95Warn above this fraction of the consensus sigops cap.
warn_coinbase_sigops_maxu32400Warn when coinbase sigops exceed this count.
policy.toml · [policy.mempool] · 8
配置项类型默认值说明
enforceboolfalseGate templates on the Class M mempool check (inline mode only).
tolerance_pctf644.0Max percent of template txs allowed to be unknown to the mempool view.
poll_interval_secsu6410Interval between bitcoind getrawmempool polls.
max_stale_secsu6460Mempool view age before it degrades and Class M abstains.
per_tx_detailboolfalseExpand rejection detail to list every unknown txid.
rpc_urlstringbitcoind JSON-RPC URL.
rpc_userstringbitcoind RPC username.
rpc_passstringbitcoind RPC password (prefer VELDRA_BITCOIND_RPC_PASS env).
gateway.toml · (root) · 1
配置项类型默认值说明
modeenuminlineDeployment mode: inline | observe | shadow.
gateway.toml · [gateway] · 34
配置项类型默认值说明
listen_addrstring0.0.0.0:3333SV2 (Noise NX) miner-facing listener address.
health_addrstring127.0.0.1:8080HTTP health, metrics and events address.
noise_keypair_pathstringPath to the gateway Noise static keypair.
noise_cert_pathstringPath to the signed Noise certificate.
authority_pubkeystringx-only authority public key miners verify.
max_connectionsu321024Global concurrent SV2 connection cap.
max_connections_per_ipu3216Per-source-IP connection cap (0 = unlimited).
max_channels_per_connu32256Per-connection mining channel cap.
noise_cert_validity_secsu323600Noise certificate validity window.
noise_handshake_timeout_msu645000Noise NX handshake timeout.
template_urlstringTemplate-manager base URL.
template_poll_interval_msu643000Template-manager poll interval.
max_template_age_msu6430000Reject templates older than this at the gateway.
prevhash_verdict_timeout_msu642000Max wait for a verifier verdict on a new block; warns below 1000.
prevhash_stale_hold_msu645000Hold stale work this long before disconnecting miners.
upstream_stale_max_msu6430000Max upstream staleness before the fail policy acts.
upstream_failure_policyenumfail_closedfail_closed | fail_open on upstream loss.
job_retention_msu64300000How long jobs are retained for share validation.
ntime_elapsed_slack_secondsu322Tolerance for miner ntime drift (seconds).
max_shares_per_second_per_channelu320Per-channel share rate cap (0 = off).
channel_target_hexstring?unsetFixed channel difficulty target (regtest); unset = real difficulty.
extended_channels_enabledbooltrueAccept OpenExtendedMiningChannel (0x13).
vardiff_enabledboolfalseEnable variable-difficulty retargeting.
vardiff_target_shares_per_minf6420.0Target share submission rate for vardiff.
vardiff_retarget_interval_secsu6490Vardiff retarget interval.
vardiff_min_difficultyu641Vardiff difficulty floor.
vardiff_max_difficultyu64u64::MAXVardiff difficulty ceiling.
vardiff_max_adjustment_factorf644.0Max per-retarget vardiff change factor.
noise_keypair_reload_sighupbooltrueReload the Noise keypair on SIGHUP.
wal_pathstringShare write-ahead log path (empty = disabled).
wal_compaction_thresholdusize1000Completed-record count that triggers WAL compaction.
gateway_instance_idstring$HOSTNAMEStable instance ID for split-brain prevention and share tracing.
auto_degradebooltrueAuto inline-to-observe degradation on verifier heartbeat loss.
auto_degrade_after_msu6410000Heartbeat-loss window before auto-degrade.
gateway.toml · [verifier] · 4
配置项类型默认值说明
addrstringPool-verifier NDJSON TCP address.
health_probe_staleness_msu6410000Mark the verifier unhealthy after this silence.
reconnect_delay_msu642000Delay between verifier reconnect attempts.
heartbeat_interval_msu645000Verifier heartbeat interval.
gateway.toml · [share_upstream] · 4
配置项类型默认值说明
urlstringUpstream share-receiver endpoint.
retriesu322Retry budget per share forward (5xx / timeout only).
forward_queue_sizeusize50000Bounded outbound share-forward queue.
forward_max_in_flightusize256Max concurrent in-flight share forwards.
§ 3 · Share 事件

两个事件跨越网关边界。

网关在 share 本地通过校验的瞬间发出 share_accepted,并在(且仅在)上游矿池确认时发出 share_forward_result。两者均经 HMAC 签名;两者都携带一个稳定的 v7 ULID event_id,供下游做重放安全的去重。

share_accepted

v1 · 发出时机 locally after share passes nonce + difficulty + version-bits + ntime checks
字段
类型
描述
event_id
string · v7 ULID
Stable identifier for dedup. Time-ordered.
account_id
string
Pool-side miner account.
worker_id
string
Sub-identity (e.g. rig name) ≤ max_worker_id_bytes.
channel_id
u32
SV2 channel ID this share arrived on.
job_id
u32
Template ID this share targets.
nonce
u32
Header nonce as submitted.
ntime
u32
Header ntime as submitted.
version_bits
u32
BIP-320 version-rolling bits.
share_difficulty
f64
Difficulty the share met.
template_difficulty
f64
Difficulty the underlying template targets.
block_solution
bool
True if this share also solves the block.
accepted_at
u64 · ms epoch
Gateway-side timestamp at validation.
template_height
u32
Block height of the template.
prev_hash
string · 64 hex
Header prev_hash; ties share to a chain epoch.

share_forward_result

v1 · 发出时机 after upstream accept/reject — or synthetically after crash recovery (process_crash_recovery)
字段
类型
描述
event_id
string · v7 ULID
Same ULID as the original share_accepted.
forwarded_at
u64 · ms epoch
When the forward attempt completed.
status
enum
accepted | rejected | dropped | recovered
upstream_status_code
u16 · null
HTTP status from pool/template-manager.
upstream_reason
string · null
Pool-supplied reason (e.g. duplicate, low_diff).
reason_code
string · null
Veldra reason code if status ∈ {dropped, recovered}.
attempt_count
u8
Number of upstream attempts (1..=forward_max_retries+1).
queue_age_ms
u64
Time the share spent in the outbound queue.
latency_ms
u64
Round-trip to upstream on the successful attempt.
传输
Both events are POSTed as NDJSON over HTTPS to the configured [share].forward_url, with an HMAC-SHA256 signature in X-Veldra-Signature derived from the signing key at [hmac].share_signing_key_path. Missing or malformed signatures are rejected upstream with missing_gateway_signature / invalid_gateway_signature.
§ 4 · 安全边界

每一层信任什么。每一层拒绝什么。

Veldra 的安全性是逐层构建的。任何一层都不信任它下面的一层;每一层都会对自己转发的内容重新推导或重新校验。本页记录的是这份契约;这些边界上的失败模式收录在 Failure Atlas

L0 · TRANSPORT

SV2 framing + Noise NX

Inbound peer is anonymous TCP until the Noise handshake completes. Until then, frames are size-capped, rate-limited per-IP, and subject to handshake timeout.

拒绝:

  • Frames over max_frame_bytes
  • Handshakes past handshake_timeout_ms
  • Connections over connection_rate_per_ip_per_min
  • Unsupported SV2 protocol versions
L1 · GATEWAY

Authenticated channel + job routing

Past handshake, the miner authenticates via whitelist. Channels open subject to per-connection caps; each job is bound to a template ID and prevhash epoch.

拒绝:

  • Unauthorized miners or stale identity prefixes
  • Channel-open requests for unsupported channel types
  • Submissions referencing unknown job_id
  • Submissions from prior prevhash epoch (past grace)
L2 · INVARIANT SHIELD

Re-derivation + cross-check

Every template — whether locally generated or upstream — is re-decoded and re-derived. Phase 1 checks structural invariants. Phase 2 (opt-in) cross-checks against bitcoind mempool.

拒绝:

  • Mismatch on merkle root, witness commitment, sigops, weight
  • BIP-34 height mismatch or missing
  • Duplicate txids, null prevouts, undecodable txs
  • Phase 2: unknown-tx ratio over tolerance_pct
L3 · SHARE PATH

HMAC-signed, dedup'd, durable

Every share is locally validated, then signed with the gateway's HMAC key and queued to upstream. The WAL persists the queue across crashes; the dedup window catches replays.

拒绝:

  • Shares below min_difficulty
  • Shares whose event_id matches one in the dedup window
  • Shares forwarded without an HMAC signature
  • Shares from accounts past pool_account_rate_limit
默认姿态
上文每一次拒绝默认都是 fail-closed:工作不会被转发,share 不会被计入,上游系统永远看不到坏输入。fail_closed = false 仅在 Invariant Shield 上可用,且意在用于 canary 部署——不用于生产环境。