Skip to content

chore(deps): drop the placeholder-genesis dig-constants copy, pin to the chia tip - #199

Merged
MichaelTaylor3d merged 1 commit into
mainfrom
chore/2072-dig-constants-collapse
Aug 7, 2026
Merged

chore(deps): drop the placeholder-genesis dig-constants copy, pin to the chia tip#199
MichaelTaylor3d merged 1 commit into
mainfrom
chore/2072-dig-constants-collapse

Conversation

@MichaelTaylor3d

@MichaelTaylor3d MichaelTaylor3d commented Aug 7, 2026

Copy link
Copy Markdown
Contributor

What this does

Removes the dig-constants copy that was actually wrong, and puts dig-node's own crates on the tip of the chia line they build against.

  • dig-wallet: dig-clvm moves from a git rev (resolving to 0.1.1) to crates.io 0.2 — also closing a §3.6 git-dep.
  • dig-node-core + dig-node-service: dig-constants 0.40.9.

No source changes were needed; both bumps compile as-is.

The finding — one constant value moved, and dig-node was on the wrong side of it

dig-constants 0.1.0 shipped an all-zeros PLACEHOLDER DIG_MAINNET_GENESIS_CHALLENGE, with all six AGG_SIG additional-data domains correctly derived from that placeholder. Self-consistent, so no derivation test could catch it. 0.4.0 finalized the real challenge (0af98186…) and recomputed all six domains.

That 0.1.0 copy reached the binary through dig-clvm 0.1.1, and dig-wallet's run_and_validate used its re-exported DIG_MAINNET as the spend-validation ValidationContext — describing a different chain identity than every other subsystem in the same process.

Nothing was mis-signed. That call site sets DONT_VALIDATE_SIGNATURE, and WalletSigner's agg_sig_data is injected by the caller rather than read from DIG_MAINNET; the CLVM cost limits that were consulted (max_block_cost_clvm, cost_per_byte) are identical across every version. So it was latent, not live — one refactor away from mattering. This PR closes it.

Every other version is value-neutral. 0.4.0 → 0.10.0 is purely additive (DIG_ASSET_ID, treasury hash/address, DEK labels, dig.local, rpc.dig.net, the profile-sealing label); 0.9.0 → 0.10.0 changes only upstream chia plot-consensus field names, no DIG value.

Why 0.9 and not the 0.10.0 tip

dig-constants 0.10.0 moved to chia-protocol 0.36.1 / chia-wallet-sdk 0.34. This workspace builds against 0.26 / 0.30, including the chia-protocol fork dig-gossip vendors through [patch.crates-io]. Depending on 0.10 links a second chia_protocol, and DIG_MAINNET.genesis_challenge() returns a Bytes32 no function here accepts — measured, 11 errors of the form expected BytesImpl<32>, found chia_protocol::bytes::BytesImpl<32>.

Being current on dig-constants is downstream of migrating dig-node to chia 0.36. It is a platform migration wearing a dependency bump's clothes.

The gate in #178 does NOT pass, and cannot pass in this repo

scripts/check-dig-constants-current.sh from #178, run against this branch's lock:

published tip : 0.10.0
in this lock  : 0.4.0 0.5.1 0.8.0 0.9.0
GATE_EXIT=1

The remaining three copies are held down by published ranges in other repos, which a consumer cannot edit:

copy held by its published requirement
0.4.0 dig-gossip (git rev) >=0.2, <0.5
0.5.1 dig-nat 0.18.0, digstore-chain (git rev) >=0.4, <0.6 / ^0.5
0.8.0 dig-download 0.17.0 ^0.8

Collapsing to one 0.9.0 needs a release-first cascade: dig-gossip and digstore-chain via a git-rev move once their mains bump, dig-nat → 0.18.1 and dig-download → 0.17.3 as patch releases against dig-constants 0.9 (patch keeps ^0.18/^0.17 consumers resolving forward, avoiding a second cascade through dig-dht/dig-peer/dig-peer-selector). Reaching 0.10.0 additionally requires the chia 0.36 migration across all of them.

The regression guard (gate finding, added)

crates/dig-node-core/tests/dependency_tree.rsno_dig_constants_copy_predates_the_real_genesis_challenge.

The suite could not see this defect before the fix or after it. grep 0af98186 --include=*.rs finds nothing — no source pins the genesis literal — and every runtime check (peer.rs:3857, :3927) compares dig_constants::DIG_MAINNET.genesis_challenge() against itself. That is circular: it passes identically under the real value and under the placeholder. spend.rs:1090 is not a guard either; a tampered bundle fails under 0.1.0 constants exactly as under 0.9.

So the assertion goes where the defect is decided — the lock — and is stated as a FLOOR: no dig-constants copy below 0.4.0. Not != "0.1.0", because 0.2.x and 0.3.x carry the same placeholder and an equality check is bypassed by the next one. This is deliberately the same property, in the same words, as the 0.4.0 floor #178 now enforces at release time — one rule, two levels.

It also asserts the resolved set is non-empty, so a rename or a botched merge that removes dig-constants from the lock cannot satisfy it vacuously.

Proven RED: reverting this PR's two dependency edits returns 0.1.0 to the lock and this is the only test in the workspace that fails:

dig-constants ["0.1.0"] predates 0.4.0, the release that replaced the PLACEHOLDER DIG
L2 genesis challenge with the real one. ... the resolved set was ["0.1.0", "0.4.0", "0.5.1", "0.8.0"]
test result: FAILED. 3 passed; 1 failed

What the remaining duplicates actually are

Their full DIG_MAINNET const bodies are identical across 0.4.0/0.5.1/0.8.0/0.9.0, CLVM cost limits included. The surviving copies are a type-unification nuisance, not an identity split — the cascade below is a cleanliness task, not a correctness emergency.

Blast radius

cargo tree -i dig-constants@{0.1.0,0.4.0,0.5.1,0.8.0} on origin/main named all seven holders; the two owned by this repo are the two edited. dig_constants is referenced at 10 sites in this workspace (DIG_MAINNET.genesis_challenge(), DIG_RELAY_URL, DIG_NODE_PORT) — all three values unchanged 0.4 → 0.9. dig_clvm is used at exactly one site, dig-wallet/src/sage/spend.rs.

How verified

cargo build --workspace --all-targets, cargo fmt --all --check, cargo clippy --workspace --all-targets -- -D warnings all clean. cargo test --workspace: 794 passed, 4 failed in dig-node-core --libpre-existing, reproduced identically on an unmodified origin/main tree in the same worktree (pinned root is not the current on-chain root, -32005 vs -32008; they reach a live chain resolver).

Version: minor. Workspace 0.101.00.102.0; dig-wallet is already 0.13.0 from #189.

Refs DIG-Network/dig_ecosystem#2072

@MichaelTaylor3d
MichaelTaylor3d force-pushed the chore/2072-dig-constants-collapse branch 2 times, most recently from 21e56a4 to e18f239 Compare August 7, 2026 17:06
@MichaelTaylor3d MichaelTaylor3d changed the title chore(deps): collapse the placeholder-genesis dig-constants copy and pin the node to its chia-line tip chore(deps): drop the placeholder-genesis dig-constants copy, pin to the chia tip Aug 7, 2026
@MichaelTaylor3d
MichaelTaylor3d force-pushed the chore/2072-dig-constants-collapse branch 2 times, most recently from b7fcb89 to f5e55cf Compare August 7, 2026 17:15

@MichaelTaylor3d MichaelTaylor3d left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

VERDICT: CHANGES-REQUIRED (recorded as a comment review - GitHub rejects a request-changes review from the PR author identity, 422).

Correctness gate — CHANGES-REQUIRED (one gating finding)

Head reviewed: f5e55cf590d8257ecac2fd50b63e3586e20b5de4. Read-only, from an isolated worktree.

The chain-identity question, answered: YES, the node is now on ONE correct chain identity.

Verified independently of anything the crate asserts about itself.

  1. The genesis value at this head. dig-constants 0.9.0 ships DIG_MAINNET_GENESIS_CHALLENGE = 0af981862a4df51f51ec59c312315d959931d917c375730b89b9e2b0854d1abf. Checked against the chain, not against the crate: POST api.coinset.org/get_block_record_by_height {"height":9021277} returns header_hash 0x0af981862a4df51f51ec59c312315d959931d917c375730b89b9e2b0854d1abf. A real, verifiable Chia mainnet header hash — not a placeholder, and deliberately NOT the Chia L1 genesis (ccd5bb71…, which the crate carries separately as CHIA_L1_MAINNET_AGG_SIG_ME). The DIG-L2 / Chia-L1 split is intentional and correctly documented.

  2. All six AGG_SIG domains re-derived from scratch. sha256(genesis || opcode) for opcodes 43,44,45,46,47,48 reproduces all six published values byte-for-byte; agg_sig_me == genesis. Correct per condition_tools.py.

  3. One identity across the whole binary. The lock still holds four copies (0.4.0 / 0.5.1 / 0.8.0 / 0.9.0), but the full DIG_MAINNET const body is identical across all four — field for field, including max_block_cost_clvm and cost_per_byte. So the four copies are a type-unification nuisance, not an identity split. The 0.1.0 all-zeros copy is GONE from the lock and nothing regressed to an older copy. That is exactly the improvement #2072 asked for.

  4. 0.4.0 → 0.9 is genuinely additive. Programmatic diff of every pub const: 12 added (DIG_ASSET_ID, DIG_TREASURY_*, CHIA_L1_*_AGG_SIG_ME, DEK_SALT, PROFILE_*, SYMMETRIC_KEY_LEN, IDENTITY_IKM_VERSION, DIG_LOCAL_HOST, RPC_DIG_NET_URL), zero removed, zero changed. CLVM cost limits, generator limits, hard-fork heights untouched; the public method set on NetworkConstants is identical. The 0.9→0.10 claim also checks out — plot-consensus field renames plus upstream's removal of max_generator_size; no DIG value moves.

  5. dig-clvm git rev → crates.io 0.2. diff -r between the git tree at 35677103 and the published dig-clvm-0.2.2: src/ is byte-identical, public symbols identical. The only delta is the manifest — dig-constants = "0.1.0""0.9". That makes "zero source changes" a consequence, not a coincidence: the API did not move because the code did not move.

  6. The 0.10 deferral holds. 0.10 moves to chia-protocol 0.36.1 while [patch.crates-io] vendors the 0.26 fork; a second chia_protocol in the graph is a real type-unification break, not an excuse.

The PR body, the manifest comments, and the DEVELOPMENT_LOG entry are unusually good — the reasoning is checkable, and every checkable claim I checked held.

What blocks merge

One thing: this is a bugfix that ships without the regression guard that would have caught the bug (§2.2). Detail inline on crates/dig-node-core/Cargo.toml.

Notes that do NOT block (resolved by me)

  • Version collision from #189: none. This head is already rebased on 0ea5d252; main is 0.101.0, this PR is 0.102.0. Clean.
  • dig-wallet was NOT bumped by this PR. The 0.12.2 → 0.13.0 move came with #189 and is already on main, so a behaviour-relevant dependency change lands on dig-wallet at an unchanged version. Acceptable: the crate is workspace-internal (the dig-wallet on crates.io is an unrelated package), and this repo's stated convention (crates/dig-node-core/Cargo.toml:2-18) bumps a library version on PUBLIC-SURFACE movement, which did not occur. No consumer pin breaks.
  • dig-constants check (both questions). (1) Nothing in this diff defines a shared value locally — it removes one. (2) One pre-existing candidate, not introduced here: crates/dig-node-core/src/peer.rs:80 defines DEFAULT_NETWORK_ID = "DIG_MAINNET" locally and dig-constants 0.9 does not publish it. That string is the gossip discovery namespace, byte-identical across dig-node / dig-gossip / the relay, so it belongs in dig-constants by the same rule that put DIG_RELAY_URL and DIG_NODE_PORT there. Moving it needs a dig-constants release plus the cascade this PR already documents as deferred — a ticket for the #2072 family, not a blocker on this diff.
  • Gates. 15/15 green on this exact head, including Test + coverage (7m04s) and Clippy. mergeStateStatus: CLEAN, zero pre-existing review threads. I did not re-run the suite locally; CI on f5e55cf is stronger evidence, and the four dig-node-core live-chain failures (#2317) reproduce on unmodified main.

Comment thread crates/dig-node-core/Cargo.toml
Comment thread crates/dig-wallet/Cargo.toml
…the chia tip

dig-node's lock held FOUR dig-constants versions in one binary (0.1.0, 0.4.0, 0.5.1,
0.8.0). Only two of the seven holders are dig-node's own crates; the rest are pinned by
upstream crates' PUBLISHED ranges, which a consumer cannot edit.

The copy that mattered was 0.1.0, reached through dig-clvm 0.1.1 (a git rev in
dig-wallet). dig-constants 0.1.0 shipped an all-zeros PLACEHOLDER DIG L2 genesis
challenge with all six AGG_SIG domains derived from it — self-consistent, so no
derivation test could see it — and 0.4.0 finalized the real values. dig-wallet's
spend-validation ValidationContext therefore described a different chain identity than
the rest of the node. Nothing was mis-signed: that call site sets
DONT_VALIDATE_SIGNATURE and the signing domain is injected by the caller. Moving
dig-clvm to crates.io 0.2 (also closing a §3.6 git-dep) removes the copy. dig-clvm's
own requirement was `>=0.1.0, <0.2.0`, so it could never have resolved forward off the
placeholder on its own — which is why this sat as long as it did.

The suite could not see any of that, before the fix or after it: no source pins the
genesis literal, and every runtime check compares
`dig_constants::DIG_MAINNET.genesis_challenge()` against itself, which passes
identically under the real value and under the placeholder. So the guard goes where the
defect is actually decided, in `dependency_tree.rs` against the lock: no dig-constants
copy below 0.4.0. Stated as a FLOOR, not `!= "0.1.0"` — 0.2.x and 0.3.x carry the same
placeholder, and this is the same property the release gate enforces at 0.4.0 (#178).
Proven RED by reverting both dependency edits: 0.1.0 returns to the lock and this is the
only test in the workspace that fails.

The node's own two crates move 0.4 -> 0.9. Values are identical from 0.4.0 through
0.10.0, so this is value-neutral. 0.9 — not the 0.10.0 tip — is correct: 0.10.0 moved
to chia-protocol 0.36.1 / chia-wallet-sdk 0.34 while this workspace builds against
0.26 / 0.30 with dig-gossip's vendored chia-protocol fork, so depending on it links a
second chia_protocol and DIG_MAINNET.genesis_challenge() stops type-unifying (measured:
11 errors). Reaching 0.10 is the chia 0.36 migration, not a dependency bump.

The three copies that survive (0.4.0/0.5.1/0.8.0/0.9.0) are held down by upstream
crates' PUBLISHED ranges. Their full DIG_MAINNET const bodies are IDENTICAL, cost limits
included, so what remains is a type-unification nuisance rather than an identity split;
collapsing it is a cleanliness cascade, not a correctness fix.

Version: minor, for the dig-wallet spend-validation constants changing value
(placeholder -> real genesis) — observable behaviour. Workspace 0.101.0 -> 0.102.0;
dig-wallet is already 0.13.0 from #189.

Refs DIG-Network/dig_ecosystem#2072

Co-Authored-By: Claude <noreply@anthropic.com>
@MichaelTaylor3d
MichaelTaylor3d force-pushed the chore/2072-dig-constants-collapse branch from f5e55cf to ea82230 Compare August 7, 2026 17:46
@MichaelTaylor3d

Copy link
Copy Markdown
Contributor Author

Merging. The guard is the right shape and I checked it rather than taking the RED on trust: semver_triple(v) < REAL_GENESIS_FLOOR is a real version comparison stated over the class, and the non-empty assertion means a lock that resolves no dig-constants at all cannot satisfy it vacuously — which is the exact way this kind of assertion usually rots. Your point that != "0.1.0" would have been wrong because 0.2.x and 0.3.x carry the same placeholder is the reason the class formulation matters.

Three of your realizations are worth more than this PR and I want them recorded rather than lost in a lane transcript:

A constant compared only against itself is unguarded no matter how many assertions mention it. Both peer.rs genesis checks and spend.rs:1090 look like coverage of the chain identity and not one of them can tell the real value from all-zeros. Your suggestion of an audit sweep for X == X-shaped assertions across the crates re-exporting dig-constants is a good one — I am filing it.

Verifying a constant from inside the dependency graph is structurally impossible. You could only compare crate versions against each other; the coinset get_block_record_by_height call is what established which one was right. Constants anchoring an external identity need their provenance test to reach the external source. That is now the load-bearing requirement on #2316.

dig-clvm 0.1.1's >=0.1.0, <0.2.0 is the actual root cause of the longevity — a dependency whose range cannot span the release that fixes its own data is a permanent pin wearing a range's syntax. Your proposed lint (any DIG crate whose dig-constants requirement has an upper bound below the current floor) would have surfaced this years earlier than a human read of a lockfile.

And the self-correction is the one I value most: you scoped a five-step cross-repo publish order as closing an identity split, then re-labelled it as type-unification cleanup once the reviewer diffed the const bodies across the versions you were not changing. Noticing that your own remediation was scoped against an unverified premise, and downgrading it, is worth more than getting it right first time.

@MichaelTaylor3d
MichaelTaylor3d marked this pull request as ready for review August 7, 2026 17:56
@MichaelTaylor3d
MichaelTaylor3d merged commit e625f8c into main Aug 7, 2026
15 of 16 checks passed
@MichaelTaylor3d
MichaelTaylor3d deleted the chore/2072-dig-constants-collapse branch August 7, 2026 17:56
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant