dig-block
dig-block is the DIG Network L2 block format, production, and validation library. It
owns the canonical on-wire shape of every L2 block, the builder pipeline that assembles blocks
from spend bundles, and the three-tier validation pipeline (structural → execution → state)
that rejects any block that does not match consensus rules.
Scope
This crate is single-block scoped: every public function operates on one block (or one checkpoint) in isolation. External state (coin set, chain tip, wall clock, validator set) is injected through two traits:
CoinLookup— coin-set queries for Tier 3 state validation.BlockSigner— proposer signing hook for block production.
dig-block never reads from disk, never makes network calls, and never maintains state across
blocks. Downstream crates (dig-coinstore, dig-epoch, dig-gossip) supply the trait
implementations, storage, chain management, and networking.
Install
[]
= "0.1"
Rust edition 2021; minimum supported Rust version 1.75.
Public API at a glance
| Concern | Key items |
|---|---|
| Block types | L2BlockHeader, L2Block, AttestedBlock, Checkpoint, CheckpointSubmission, Receipt, ReceiptList, SignerBitmap, BlockStatus, CheckpointStatus |
| Block production | BlockBuilder, CheckpointBuilder |
| Validation | L2Block::validate_structure, L2Block::validate_execution, L2Block::validate_state, L2Block::validate_full |
| Validation output | ExecutionResult, PendingAssertion, AssertionKind |
| Integration traits | CoinLookup, BlockSigner |
| Hashing | hash_leaf, hash_node, compute_spends_root, compute_additions_root, compute_removals_root, compute_filter_hash, compute_receipts_root, compute_state_root_from_delta |
| Errors | BlockError, CheckpointError, BuilderError, SignerBitmapError, ReceiptError |
| Constants | EMPTY_ROOT, ZERO_HASH, MAX_BLOCK_SIZE, MAX_COST_PER_BLOCK, MAX_SLASH_PROPOSALS_PER_BLOCK, MAX_SLASH_PROPOSAL_PAYLOAD_BYTES, DFSP_ACTIVATION_HEIGHT, MAX_FUTURE_TIMESTAMP_SECONDS, HASH_LEAF_PREFIX, HASH_TREE_PREFIX, VERSION_V1, VERSION_V2, MAX_VALIDATORS |
| Primitives | Bytes32, Cost, Signature, PublicKey (re-exported from chia-protocol / chia-bls) |
A convenience glob import is provided:
use *;
Quickstart — build a block
use *;
use SignerError;
// 1. Implement BlockSigner for your key backend.
;
// 2. Build an anchored builder.
let parent = default;
let l1_hash = default;
let mut builder = new;
// 3. (Optional) add spend bundles / slash proposals / set L1 proofs etc.
// builder.add_spend_bundle(bundle, cost, fee)?;
// 4. Finalize and sign.
let state_root = default;
let receipts_root = default;
let block = builder.build
.expect;
The output is structurally valid by construction: block.validate_structure() always passes
on anything BlockBuilder::build produces (BLD-007).
Quickstart — validate a block
use *;
use CoinState;
use ValidationConfig;
;
Validation pipeline
┌─────────────────────────────────────────────────────────────────────┐
│ L2Block │
│ │ │
│ ▼ │
│ Tier 1: L2Block::validate_structure() │
│ • no external state │
│ • SVL-001..006: version, DFSP roots, cost/size, timestamp, │
│ count agreement, Merkle roots, duplicates │
│ │ │
│ ▼ │
│ Tier 2: L2Block::validate_execution(config, genesis_challenge) │
│ • dig_clvm::validate_spend_bundle per SpendBundle │
│ • EXE-002..007: puzzle hash, CLVM, conditions, BLS, conservation, │
│ cost │
│ • Produces ExecutionResult → PendingAssertion vec │
│ │ │
│ ▼ │
│ Tier 3: L2Block::validate_state(exec, coins, pubkey) │
│ • CoinLookup for persistent coin state │
│ • STV-002..007: coin existence, puzzle-hash cross-check, │
│ addition uniqueness, height/time locks, proposer signature, │
│ state root recompute │
│ │ │
│ ▼ │
│ Ok(computed_state_root) / Err(BlockError) │
└─────────────────────────────────────────────────────────────────────┘
Each tier can also be invoked independently, e.g. for light clients that only need structural
verification, or for validators that want to cache ExecutionResult for replay.
Dependencies
dig-block reuses the Chia Rust ecosystem and does not reimplement CLVM, BLS, or Merkle primitives:
| Concern | Crate |
|---|---|
Core protocol types (Bytes32, Coin, SpendBundle, CoinSpend, CoinState) |
chia-protocol |
BLS12-381 signatures (Signature, PublicKey, verify) |
chia-bls |
| CLVM execution + condition parsing | dig-clvm (wraps chia-consensus) |
| Merkle set roots (additions, removals) | chia-consensus |
| Binary Merkle trees (spends, receipts, slash proposals) | chia-sdk-types |
| SHA-256 | chia-sha2 |
| CLVM tree hashing | clvm-utils |
| Bincode serialization | bincode + serde |
| BIP-158 compact block filter | bitcoin::bip158 |
CLVM execution is always routed through dig_clvm::validate_spend_bundle; dig-block never
calls chia-consensus::run_spendbundle directly. This architectural boundary is enforced by a
grep-based lint in tests/test_exe_003_clvm_delegation.rs.
Testing
74 normative requirements; one dedicated integration test file per requirement. The full suite:
Runs ~600 tests against the public API (no unit tests reach into private modules). Property-based
coverage via proptest in tests/test_ser_005_roundtrip_integrity.rs.
Specification
All behavior is derived from the authoritative crate specification:
docs/resources/SPEC.md.
Each requirement has a three-document trace:
docs/requirements/domains/{domain}/NORMATIVE.md— authoritative MUST/SHOULD statementsdocs/requirements/domains/{domain}/specs/{PREFIX-NNN}.md— detailed spec + test plandocs/requirements/domains/{domain}/VERIFICATION.md/TRACKING.yaml— status + test refs
License
MIT. See LICENSE.
Versioning
Semantic versioning. Wire-format changes to the block header bump the minor version pre-1.0 and
the major version post-1.0. Adding new protocol versions (VERSION_V3, etc.) follows the same
rule.