Releases: michaeljfazio/dugite
Dugite v2.0.2
dugite v2.0.2
Stability and byte-exactness release: closes every open bug in the backlog (#733, #734, #735, #736, #738, #740) and lands the first dugite build validated byte-exact against mainnet across 25 consecutive epoch boundaries (ep342→367, including the Vasil hard fork) under genesis consensus mode with ChainSync Jumping enabled.
Highlights
- Mainnet ledger byte-exactness across non-linear transitions. From-genesis replay → restart (snapshot seam) → live genesis-mode sync now produces treasury/reserves identical to mainnet (cross-validated against Koios at every epoch boundary ep342→367, through three restart-seams and multiple binary rolls). The remaining seam bug — the pv≤6 RUPD
startStepcredential capture (rupd_addrs_rew) not being persisted in ledger snapshots — is fixed; snapshot format is now v22 (older snapshots are quarantined on load and rebuilt by the ~35-minute from-genesis replay). (#736) - Fork-switch correctness. Fork-replay paths (including the genesis LoE-reprocess path that applies most blocks during catch-up) decoded blocks with the witness-skipping minimal decoder while running the full-validation oracle — every post-switch transaction spuriously failed witness checks. The decoder now follows the validation mode. (#738)
- Limit-on-Patience Haskell parity. The LoP bucket no longer leaks while dugite's own wire-level backpressure has the header pipeline paused (mirrors Haskell
Client.hspauseBucket: "the peer is not responsible for this waiting time"). This was killing every hot big-ledger peer ~200s into bulk sync, pinning the HAA at its threshold and flapping the GSM. Peer-selection target switching is now keyed on the CaughtUp↔not-CaughtUp boundary only (Haskell LSJ semantics), with sync targets applied from boot. (#740) - ChainSync Jumping is now enabled by default on mainnet (
EnableCSJ=true). The far-ahead-fetch wedge is closed by two Haskell-parity invariants: a promoted dynamo/objector re-intersects at the frontier before streaming (any accepted jump moves the server cursor), and BlockFetch only dispatches ranges that contiguously extend a stored block (gross-request invariant,selectThePeer/requestHeadInCandidate). Validated by a multi-hour CSJ-on soak through deep mainnet catch-up with dozens of dynamo rotations, all self-healing. (#735) - Phase-2 collection errors are block-fatal at apply (Babbage+), mirroring Haskell
UtxosFailure (CollectErrors …)— includingTimeTranslationPastHorizon— with every correction from the adversarial design review: a conservative horizon that can never false-fire at hard-fork windows (validated live across the Alonzo→Babbage window ep364–366: zero false fatalities with the horizon armed on the first Babbage blocks), the Alonzo warn-only gate, a CEK-panic split (reject at admission, warn at apply), a UTxO-gap carve-out, deterministic per-block horizon snapshots anchored at the pre-block tip, and exact-rationalstability_windowmath. Escape hatch:DUGITE_PHASE2_APPLY_FATAL=0. (#733; admission half shipped in v2.0.1 — #734 verified closed by tx-zoo 03l/03m in both consensus modes) - Genesis key delegation certificates decode correctly. All three Shelley-family era decoders read the two 28-byte key hashes as 32-byte hashes and failed at first contact with a real certificate (mainnet slot 66137371, the pre-Vasil genesis-delegate rotations). First sync past mainnet ep350 now works.
- Vasil-epoch reward prefilter byte-exactness. The
fvAddrsRewstartStep freeze now gates on prevPParams' protocol version (the version the next reward update is computed under), not curPParams — the freeze was skipped during the Vasil epoch itself, leaving the 365→366 reward update 857.6 ADA short of treasury. Caught live at the first Babbage boundary after 23 byte-exact boundaries; re-validated by a fresh from-genesis replay. - Phase-1 oracle uses sequential in-block state. Same-block withdraw→deregister chains no longer false-positive
StakeKeyHasNonZeroBalance(Haskell LEDGERS applies transactions sequentially).
Validation
- devnet-validate (standard preset, 4 rounds): baseline, epoch-boundary, restart, and genesis-mode rounds all PASS — 324 tx-zoo passes / 0 fails, byte-exact pot parity vs cardano-node 11.0.1 at the first RUPD boundary, 19-script bidirectional accept/reject parity with zero off-diagonal cells, 22-query CLI parity with zero divergences, all adversarial N2N protocol tests green. Full report:
reports/devnet-validate/v2.0.2.json/.md. - Mainnet (genesis mode, CSJ on): treasury byte-exact vs Koios at every boundary ep342→ep367, including the replay seam, three restart-seams, live-tip fork switches, and the Alonzo→Babbage hard-fork window. Sync-to-tip continues as a long-running validation.
Operational notes
- Ledger snapshot format bumped to v22 — nodes restart with a from-genesis ledger replay (~35 min on Apple Silicon; ImmutableDB chunks are reused, no re-download).
EnableCSJnow defaults totrueinconfig/mainnet/config.json(LowLevelGenesisOptions). Set it tofalseto revert to single-session header sync.- New env vars:
DUGITE_PHASE2_APPLY_FATAL=0(revert phase-2 apply fatality to warn-and-trust),DUGITE_DECODE_FAIL_DUMP=<dir>(capture undecodable block CBOR for offline analysis).
devnet-validate report
| Result | ✅ PASS |
| Git | dbd5b1c7186c2d89e37c68e13cc8e1faba2d54a9 |
| Preset | standard |
| cardano-node | 11.0.1 |
| cardano-cli | 11.0.0.0 |
| Generated | 2026-06-11T14:26:33Z |
Round summary
| Round | Result | Canonical blocks | Tx-zoo | CLI parity | Tip-age p99 | Chain density |
|---|---|---|---|---|---|---|
| baseline | ✅ PASS | 61 | 81/84 | ✅ 0✓ | 7.00s | 0.530 |
| epoch-boundary | ✅ PASS | 443 | 81/84 | ✅ 0✓ | 6.00s | 0.491 |
| restart | ✅ PASS | 20 | 81/84 | ✅ 0✓ | 7.00s | 0.114 |
| genesis-mode | ✅ PASS | 146 | 81/84 | ✅ 0✓ | 5.00s | 0.485 |
Total canonical blocks: 670
Total tx-zoo pass/fail: 324 / 0
Predicate breakdown
Round: baseline
| Predicate | Result | Detail |
|---|---|---|
| p1 — forge-cross-check | PASS | (51 canonical blocks, >=3 observers each; 10 orphan(s) excluded) |
| p2 — per-bp-attribution | PASS | (validator-only: pool1=61, pool2=0 as designed) |
| p4 — tip-parity | PASS | (24/24 ticks in-parity = 100% across all 3 observers) |
| p5 — tip-age | PASS | (threshold 300s; dugite-bp=max7s/last1s/n12 dugite-relay=max7s/last1s/n12) |
| p3 — tx-inclusion | SKIP | (no txs submitted during this soak — Round 3 / restart-only sample) |
Round: epoch-boundary
| Predicate | Result | Detail |
|---|---|---|
| p1 — forge-cross-check | PASS | (433 canonical blocks, >=3 observers each; 10 orphan(s) excluded) |
| p2 — per-bp-attribution | PASS | (validator-only: pool1=443, pool2=0 as designed) |
| p3 — tx-inclusion | PASS | (30 txs submitted; 26 accepted/4 rejected — all 3 nodes agree) |
| p4 — tip-parity | PASS | (175/175 ticks in-parity = 100% across all 3 observers) |
| p5 — tip-age | PASS | (threshold 300s; dugite-bp=max8s/last3s/n167 dugite-relay=max8s/last3s/n167) |
Round: restart
| Predicate | Result | Detail |
|---|---|---|
| p1 — forge-cross-check | PASS | (70 canonical blocks, >=3 observers each; 20 orphan(s) excluded) |
| p2 — per-bp-attribution | PASS | (validator-only: pool1=30, pool2=0 as designed) |
| p3 — tx-inclusion | PASS | (15 txs submitted; 11 accepted/4 rejected — all 3 nodes agree) |
| p4 — tip-parity | PASS | (35/35 ticks in-parity = 100% across all 3 observers) |
| p5 — tip-age | PASS | (threshold 300s; dugite-bp=max7s/last1s/n24 dugite-relay=max7s/last1s/n24) |
Round: genesis-mode
| Predicate | Result | Detail |
|---|---|---|
| p1 — forge-cross-check | PASS | (136 canonical blocks, >=3 observers each; 10 orphan(s) excluded) |
| p2 — per-bp-attribution | PASS | (validator-only: pool1=146, pool2=0 as designed) |
| p3 — tx-inclusion | PASS | (15 txs submitted; 12 accepted/3 rejected — all 3 nodes agree) |
| p4 — tip-parity | PASS | (59/59 ticks in-parity = 100% across all 3 observers) |
| p5 — tip-age | PASS | (threshold 300s; dugite-bp=max5s/last2s/n48 dugite-relay=max5s/last2s/n48) |
Generated by .claude/skills/devnet-validate/scripts/generate-release-report.sh
Schema: .claude/skills/devnet-validate/schemas/report.v1.json
Dugite v2.0.1
What's changed in v2.0.1
A bug-fix release hardening Plutus phase-2 admission, Byron-era block storage/serving, and bulk-sync throughput. No wire-format or ledger-semantic changes; v2.0.1 is a drop-in replacement for v2.0.0.
Consensus / ledger correctness
- Phase-2 admission partition (#733/#734). Transaction phase-2 outcomes are now split into genuine script-evaluation failures (which legitimise
is_valid=false) and collection/context errors (CollectErrors: decode failures, missing script/datum, validity-interval time translation past the safe-zone horizon), mirroring the Haskell UTXOS rule exactly. Collection errors now reject the transaction regardless of theis_validtag — closing a hole where anis_valid=falsetx whose scripts actually pass, or whose context errors out (e.g. a past-horizon TTL), could be admitted, forged, and produce a block that cardano-node rejects. Resolved UTxOs created pre-Conway are re-decoded with prune semantics so legitimate Conway spends of zero-asset outputs are not spuriously rejected. - Conway committee / vote byte-exactness (#731). GOVCERT future-member handling, committee-state pruning, and vote de-duplication corrected for byte-exact alignment with cardano-ledger.
- Zero-quantity multi-asset entries (#730). Pruned pre-Conway, rejected in Conway, matching cardano-ledger's decoder-version-gated
decodeMultiAsset.
Byron-era storage & serving
- Byron Epoch Boundary Blocks (EBBs) are no longer dropped at volatile→immutable flush batch boundaries; ChainSync/BlockFetch now serve same-slot EBB/main-block pairs via point-cursor iteration.
- From-genesis replay wipes a stale on-disk LSM UTxO store, fixing a Byron→Shelley
reserves=0/ MIR panic.
Performance & operability
- Bulk-sync throughput +59%. The N2C LocalStateQuery snapshot rebuild (~1.4 s at mainnet scale) now runs at a 30 s cadence during catch-up instead of every block, eliminating a metronomic apply-loop stall that consumed ~57% of wall time during sync (20.2 → 32.0 blk/s on a dense mainnet segment).
- dugite-monitor "Stuck" debounce. The tip/header pills now require 90 s of sustained no-advance before reporting Stuck/Stalled, instead of flapping red on any single quiet 1 s poll window during legitimately bursty heavy-era sync.
Testing
- New tx-zoo
03mpast-horizon-rejection test (bothis_validpolarities);03j/03lTTLs kept inside the time-translation horizon;03lharness crash fixed.
Deferred: the block-apply half of #733 (making CollectErrors fatal at block application) is tracked on the issue with the corrections an adversarial review surfaced (TransitionKnown horizon, Alonzo-era gate, panic handling, partial-replay carve-out).
Full Changelog: v2.0.0...v2.0.1
QA — devnet-validate (standard preset)
devnet-validate report
| Result | ✅ PASS |
| Git | 501ba2577a6465ddcd57035098bf24e7c29ba56f |
| Preset | standard |
| cardano-node | 11.0.1 |
| cardano-cli | 11.0.0.0 |
| Generated | 2026-06-10T11:55:09Z |
Round summary
| Round | Result | Canonical blocks | Tx-zoo | CLI parity | Tip-age p99 | Chain density |
|---|---|---|---|---|---|---|
| restart | ✅ PASS | 159 | 0/84 | ✅ 0✓ | 8.00s | 0.528 |
Total canonical blocks: 159
Total tx-zoo pass/fail: 0 / 0
Predicate breakdown
Round: restart
| Predicate | Result | Detail |
|---|---|---|
| p1 — forge-cross-check | PASS | (149 canonical blocks, >=3 observers each; 10 orphan(s) excluded) |
| p2 — per-bp-attribution | PASS | (validator-only: pool1=159, pool2=0 as designed) |
| p3 — tx-inclusion | PASS | (12 txs submitted; 0 accepted/0 rejected — all 3 nodes agree) |
| p4 — tip-parity | PASS | (59/59 ticks in-parity = 100% across all 3 observers) |
| p5 — tip-age | PASS | (threshold 300s; dugite-bp=max8s/last2s/n48 dugite-relay=max8s/last2s/n48) |
Generated by .claude/skills/devnet-validate/scripts/generate-release-report.sh
Schema: .claude/skills/devnet-validate/schemas/report.v1.json
Container Image
docker pull ghcr.io/michaeljfazio/dugite:2.0.1Available for linux/amd64 and linux/arm64.
Helm Chart
helm install dugite-relay \
oci://ghcr.io/michaeljfazio/charts/dugite-node \
--version 2.0.1 \
--set network.name=previewSee Kubernetes Deployment for the full chart reference.
Binary Downloads
| Platform | Architecture | Download |
|---|---|---|
| Linux | x86_64 | dugite-x86_64-linux.tar.gz |
| Linux | aarch64 | dugite-aarch64-linux.tar.gz |
| macOS | x86_64 | dugite-x86_64-macos.tar.gz |
| macOS | Apple Silicon | dugite-aarch64-macos.tar.gz |
Verify checksums: sha256sum -c SHA256SUMS.txt
Full Changelog: v2.0.0...v2.0.1
Dugite v2.0.0
Container Image
docker pull ghcr.io/michaeljfazio/dugite:2.0.0Available for linux/amd64 and linux/arm64.
Helm Chart
helm install dugite-relay \
oci://ghcr.io/michaeljfazio/charts/dugite-node \
--version 2.0.0 \
--set network.name=previewSee Kubernetes Deployment for the full chart reference.
Binary Downloads
| Platform | Architecture | Download |
|---|---|---|
| Linux | x86_64 | dugite-x86_64-linux.tar.gz |
| Linux | aarch64 | dugite-aarch64-linux.tar.gz |
| macOS | x86_64 | dugite-x86_64-macos.tar.gz |
| macOS | Apple Silicon | dugite-aarch64-macos.tar.gz |
Verify checksums: sha256sum -c SHA256SUMS.txt
Full Changelog: 2.0...v2.0.0
Conformance corpus conformance-corpus-v20260607-033545
Conformance corpus conformance-corpus-v20260607-033545
Generated at 2026-06-07T04:26:52Z by the regenerate-conformance-corpus workflow.
Upstream pins
[ouroboros-consensus]
sha = "b7135f845480f347f618217a00f6ecad4124766d"
[cardano-ledger]
sha = "ebed62de1ebcd4b13512418d49d17802a193e2c1"
[cardano-node]
sha = "9c20173514507050308bb5f2d67ac30cb0963ac9"
[plutus]
tag = "1.65.0.0"
[ledger-rules]
sha = "ebed62de1ebcd4b13512418d49d17802a193e2c1"
[cardano-base]
sha = "096124a9dfce0264270251115aaee64f574b50c3"
[mithril]
sha = "51874212d135567d7d1c85b811a23cc76e33372b"
Assets
ouroboros-consensus.tar.gzcardano-ledger.tar.gzcardano-node.tar.gzplutus.tar.gzledger-rules.tar.gzcardano-base.tar.gzmithril.tar.gzcorpus-manifest.json
Conformance corpus conformance-corpus-v20260531-041129
Conformance corpus conformance-corpus-v20260531-041129
Generated at 2026-05-31T05:01:17Z by the regenerate-conformance-corpus workflow.
Upstream pins
[ouroboros-consensus]
sha = "b7135f845480f347f618217a00f6ecad4124766d"
[cardano-ledger]
sha = "ebed62de1ebcd4b13512418d49d17802a193e2c1"
[cardano-node]
sha = "9c20173514507050308bb5f2d67ac30cb0963ac9"
[plutus]
tag = "1.65.0.0"
[ledger-rules]
sha = "ebed62de1ebcd4b13512418d49d17802a193e2c1"
[cardano-base]
sha = "096124a9dfce0264270251115aaee64f574b50c3"
[mithril]
sha = "51874212d135567d7d1c85b811a23cc76e33372b"
Assets
ouroboros-consensus.tar.gzcardano-ledger.tar.gzcardano-node.tar.gzplutus.tar.gzledger-rules.tar.gzcardano-base.tar.gzmithril.tar.gzcorpus-manifest.json
Conformance corpus conformance-corpus-v20260527-125834
Conformance corpus conformance-corpus-v20260527-125834
Generated at 2026-05-27T13:51:34Z by the regenerate-conformance-corpus workflow.
Upstream pins
[ouroboros-consensus]
sha = "b7135f845480f347f618217a00f6ecad4124766d"
[cardano-ledger]
sha = "ebed62de1ebcd4b13512418d49d17802a193e2c1"
[cardano-node]
sha = "9c20173514507050308bb5f2d67ac30cb0963ac9"
[plutus]
tag = "1.65.0.0"
[ledger-rules]
sha = "ebed62de1ebcd4b13512418d49d17802a193e2c1"
[cardano-base]
sha = "096124a9dfce0264270251115aaee64f574b50c3"
[mithril]
sha = "51874212d135567d7d1c85b811a23cc76e33372b"
Assets
ouroboros-consensus.tar.gzcardano-ledger.tar.gzcardano-node.tar.gzplutus.tar.gzledger-rules.tar.gzcardano-base.tar.gzmithril.tar.gzcorpus-manifest.json
Conformance corpus conformance-corpus-v20260524-075059
Conformance corpus conformance-corpus-v20260524-075059
Generated at 2026-05-24T08:36:05Z by the regenerate-conformance-corpus workflow.
Upstream pins
[ouroboros-consensus]
sha = "b7135f845480f347f618217a00f6ecad4124766d"
[cardano-ledger]
sha = "ebed62de1ebcd4b13512418d49d17802a193e2c1"
[cardano-node]
sha = "9c20173514507050308bb5f2d67ac30cb0963ac9"
[plutus]
tag = "1.65.0.0"
[ledger-rules]
sha = "ebed62de1ebcd4b13512418d49d17802a193e2c1"
[cardano-base]
sha = "096124a9dfce0264270251115aaee64f574b50c3"
[mithril]
sha = "51874212d135567d7d1c85b811a23cc76e33372b"
Assets
ouroboros-consensus.tar.gzcardano-ledger.tar.gzcardano-node.tar.gzplutus.tar.gzledger-rules.tar.gzcardano-base.tar.gzmithril.tar.gzcorpus-manifest.json
Conformance corpus conformance-corpus-v20260524-070654
Conformance corpus conformance-corpus-v20260524-070654
Generated at 2026-05-24T07:07:03Z by the regenerate-conformance-corpus workflow.
Upstream pins
[ouroboros-consensus]
sha = "b7135f845480f347f618217a00f6ecad4124766d"
[cardano-ledger]
sha = "ebed62de1ebcd4b13512418d49d17802a193e2c1"
[cardano-node]
sha = "9c20173514507050308bb5f2d67ac30cb0963ac9"
[plutus]
tag = "1.65.0.0"
[ledger-rules]
sha = "ebed62de1ebcd4b13512418d49d17802a193e2c1"
[cardano-base]
sha = "096124a9dfce0264270251115aaee64f574b50c3"
[mithril]
sha = "51874212d135567d7d1c85b811a23cc76e33372b"
Assets
ouroboros-consensus.tar.gzcardano-ledger.tar.gzcardano-node.tar.gzplutus.tar.gzledger-rules.tar.gzcardano-base.tar.gzmithril.tar.gzcorpus-manifest.json
Conformance corpus conformance-corpus-v20260523-165156
Conformance corpus conformance-corpus-v20260523-165156
Generated at 2026-05-23T17:27:01Z by the regenerate-conformance-corpus workflow.
Upstream pins
[ouroboros-consensus]
sha = "b7135f845480f347f618217a00f6ecad4124766d"
[cardano-ledger]
sha = "ebed62de1ebcd4b13512418d49d17802a193e2c1"
[cardano-node]
sha = "9c20173514507050308bb5f2d67ac30cb0963ac9"
[plutus]
tag = "1.65.0.0"
[ledger-rules]
sha = "ebed62de1ebcd4b13512418d49d17802a193e2c1"
[cardano-base]
sha = "096124a9dfce0264270251115aaee64f574b50c3"
[mithril]
sha = "51874212d135567d7d1c85b811a23cc76e33372b"
Assets
ouroboros-consensus.tar.gzcardano-ledger.tar.gzcardano-node.tar.gzplutus.tar.gzledger-rules.tar.gzcardano-base.tar.gzmithril.tar.gzcorpus-manifest.json
Conformance corpus conformance-corpus-v20260523-072525
Conformance corpus conformance-corpus-v20260523-072525
Generated at 2026-05-23T07:25:36Z by the regenerate-conformance-corpus workflow.
Upstream pins
[ouroboros-consensus]
sha = "b7135f845480f347f618217a00f6ecad4124766d"
[cardano-ledger]
sha = "ebed62de1ebcd4b13512418d49d17802a193e2c1"
[cardano-node]
sha = "9c20173514507050308bb5f2d67ac30cb0963ac9"
[plutus]
tag = "1.65.0.0"
[ledger-rules]
sha = "ebed62de1ebcd4b13512418d49d17802a193e2c1"
[cardano-base]
sha = "096124a9dfce0264270251115aaee64f574b50c3"
[mithril]
sha = "51874212d135567d7d1c85b811a23cc76e33372b"
Assets
ouroboros-consensus.tar.gzcardano-ledger.tar.gzcardano-node.tar.gzplutus.tar.gzledger-rules.tar.gzcardano-base.tar.gzmithril.tar.gzcorpus-manifest.json