Skip to content

Commit fd2d240

Browse files
committed
test(devnet): v2.0.6 QA report — extended suite PASS (3/3 rounds, 0 invalid forges) on the tag candidate
1 parent 5ba80bb commit fd2d240

2 files changed

Lines changed: 259 additions & 0 deletions

File tree

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
# dugite v2.0.6
2+
3+
Ledger byte-exactness and genesis-mode bootstrap release. Four fixes, each
4+
root-caused against a confirmed mainnet/preprod artifact and the Haskell
5+
reference, validated live, and pinned with regression tests.
6+
7+
## Fixes
8+
9+
- **node: genesis-mode reaches the tip when bootstrapped from a Mithril
10+
snapshot** (closes #757). A `--consensus-mode genesis` node booted from a
11+
Mithril snapshot froze at exactly `snapshot_tip + k`: with zero big-ledger
12+
peers at startup (no `peerSnapshotFile`; ledger discovery deferred ~5 min)
13+
the GSM stayed in PreSyncing, where LoE caps selection at k. Oracle-confirmed
14+
Haskell semantics (`isHaaSatisfied` under `UseBootstrapPeers` is satisfied by
15+
trusted bootstrap peers, and a recent/Mithril-certified selection is past the
16+
from-genesis-vulnerable regime where GDD alone guards the bounded gap): the
17+
GSM now suppresses the Syncing→PreSyncing HAA-loss regression while the tip is
18+
recent, only regressing if HAA is lost AND the tip is stale. Cold-start from
19+
genesis still requires full HAA; Praos is byte-identical. **Proven live on
20+
preprod**: a node frozen at `snapshot_tip + k` unstuck and reached the live
21+
tip in Syncing.
22+
23+
- **ledger: redeemers required only for Plutus-script purposes, not native**
24+
(closes #758). A confirmed Babbage tx spending a native-multisig-locked input
25+
was falsely rejected with `MissingSpendRedeemer` — native scripts have no
26+
redeemers. Haskell's `hasExactSetOfRedeemers` filters `redeemersNeeded` to
27+
Plutus scripts only. Now **all** purposes (Spend/Reward/Cert/Vote) gate the
28+
redeemer requirement — and the extra-redeemer check — on the credential's
29+
locking script resolving to Plutus, matching the reference. Pinned with a
30+
real on-chain tx plus native/Plutus positive+negative controls per purpose.
31+
32+
- **ledger: duplicate-input rejection only at PV≥9** (closes #759). A confirmed
33+
Babbage tx whose spend-inputs array carried the same `TxIn` twice was falsely
34+
rejected. Haskell's `decodeSet` at PV<9 routes through `Set.fromList` and
35+
silently drops the duplicate (no `DuplicateInput` predicate exists pre-Conway);
36+
only PV≥9 uses `decodeSetEnforceNoDuplicates`. The check is now gated on
37+
`protocol_version_major >= 9`. Conway+ rejection unchanged; pinned with the
38+
real on-chain tx.
39+
40+
- **ledger: pin Conway RUPD inputs survive snapshot round-trip** (closes #755).
41+
A forensic investigation traced a ~996K ADA reserves over-allocation in one
42+
validation DB to a v2.0.2-line binary at boundary 388→389 — a **state
43+
artifact**, not a live-code defect (current code verified clean across 60+
44+
live epoch boundaries; the #736 fixes closed the pv≤6 restart-during-RUPD
45+
window). Adds a regression test pinning that the Conway RUPD inputs
46+
(go/bprev/ss_fee/prevPParams) survive snapshot save/restore byte-exact, so the
47+
artifact's mechanism can never silently regress.
48+
49+
## Validation
50+
51+
`just check`, conformance (6027/6027), an adversarial multi-agent code review
52+
(which caught and forced corrections to the first #757 and #758 attempts), live
53+
preprod genesis-bootstrap validation, and `devnet-validate-extended` (3 rounds)
54+
all green on the tag commit.
Lines changed: 205 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,205 @@
1+
{
2+
"schema_version": 1,
3+
"timestamp": "2026-06-12T19:16:00Z",
4+
"git_rev": "5ba80bb590",
5+
"release_tag": "v2.0.6",
6+
"preset": "extended",
7+
"cardano_node_version": "11.0.1",
8+
"cardano_cli_version": "11.0.0.0",
9+
"rounds": [
10+
{
11+
"name": "baseline",
12+
"pass": true,
13+
"evidence_dir": "evidence-kept/round1-20260612T182006Z",
14+
"duration_seconds": 180,
15+
"git_rev": "5ba80bb590c9cfdcb1f0efd674ec799bfc49f790",
16+
"cardano_node_version": "11.0.1",
17+
"cardano_cli_version": "11.0.0.0",
18+
"blocks": {
19+
"total_forges": 87,
20+
"canonical": 87,
21+
"orphans": 0,
22+
"orphan_rate": 0.0
23+
},
24+
"tip_age": {
25+
"avg_seconds": 1.53,
26+
"p99_seconds": 8.0
27+
},
28+
"chain_density": 0.506,
29+
"tx_zoo": {
30+
"pass": 0,
31+
"fail": 0,
32+
"skip": 0,
33+
"total": 0
34+
},
35+
"predicates": {
36+
"p1_forge_cross_check": true,
37+
"p2_per_bp_attribution": true,
38+
"p3_tx_inclusion": true,
39+
"p4_tip_parity": true,
40+
"p5_tip_age": true
41+
},
42+
"log_errors": {
43+
"dugite-bp": {
44+
"errors": 1,
45+
"warns": 4
46+
},
47+
"dugite-relay": {
48+
"errors": 21,
49+
"warns": 40
50+
},
51+
"cardano-bp": {
52+
"errors": 1,
53+
"warns": 1
54+
}
55+
},
56+
"anomalies": [],
57+
"epoch_transitions_observed": 1,
58+
"n2n_adversarial": {
59+
"pass": 0,
60+
"fail": 0,
61+
"panic": 0,
62+
"silent_skip": 0
63+
},
64+
"cli_parity": {
65+
"equal": 0,
66+
"divergent": 0,
67+
"skip": 0,
68+
"error": 0
69+
}
70+
},
71+
{
72+
"name": "epoch-boundary",
73+
"pass": true,
74+
"evidence_dir": "evidence-kept/round2-20260612T183349Z",
75+
"duration_seconds": 180,
76+
"git_rev": "5ba80bb590c9cfdcb1f0efd674ec799bfc49f790",
77+
"cardano_node_version": "11.0.1",
78+
"cardano_cli_version": "11.0.0.0",
79+
"blocks": {
80+
"total_forges": 89,
81+
"canonical": 89,
82+
"orphans": 0,
83+
"orphan_rate": 0.0
84+
},
85+
"tip_age": {
86+
"avg_seconds": 1.58,
87+
"p99_seconds": 7.0
88+
},
89+
"chain_density": 0.494,
90+
"tx_zoo": {
91+
"pass": 0,
92+
"fail": 0,
93+
"skip": 0,
94+
"total": 0
95+
},
96+
"predicates": {
97+
"p1_forge_cross_check": true,
98+
"p2_per_bp_attribution": true,
99+
"p3_tx_inclusion": true,
100+
"p4_tip_parity": true,
101+
"p5_tip_age": true
102+
},
103+
"log_errors": {
104+
"dugite-bp": {
105+
"errors": 1,
106+
"warns": 4
107+
},
108+
"dugite-relay": {
109+
"errors": 21,
110+
"warns": 39
111+
},
112+
"cardano-bp": {
113+
"errors": 1,
114+
"warns": 1
115+
}
116+
},
117+
"anomalies": [],
118+
"epoch_transitions_observed": 1,
119+
"n2n_adversarial": {
120+
"pass": 0,
121+
"fail": 0,
122+
"panic": 0,
123+
"silent_skip": 0
124+
},
125+
"cli_parity": {
126+
"equal": 0,
127+
"divergent": 0,
128+
"skip": 0,
129+
"error": 0
130+
}
131+
},
132+
{
133+
"name": "restart",
134+
"pass": true,
135+
"evidence_dir": "evidence-kept/round3-20260612T190423Z",
136+
"duration_seconds": 180,
137+
"git_rev": "5ba80bb590c9cfdcb1f0efd674ec799bfc49f790",
138+
"cardano_node_version": "11.0.1",
139+
"cardano_cli_version": "11.0.0.0",
140+
"blocks": {
141+
"total_forges": 86,
142+
"canonical": 86,
143+
"orphans": 0,
144+
"orphan_rate": 0.0
145+
},
146+
"tip_age": {
147+
"avg_seconds": 1.24,
148+
"p99_seconds": 7.0
149+
},
150+
"chain_density": 0.478,
151+
"tx_zoo": {
152+
"pass": 0,
153+
"fail": 0,
154+
"skip": 0,
155+
"total": 0
156+
},
157+
"predicates": {
158+
"p1_forge_cross_check": true,
159+
"p2_per_bp_attribution": true,
160+
"p3_tx_inclusion": true,
161+
"p4_tip_parity": true,
162+
"p5_tip_age": true
163+
},
164+
"log_errors": {
165+
"dugite-bp": {
166+
"errors": 1,
167+
"warns": 5
168+
},
169+
"dugite-relay": {
170+
"errors": 20,
171+
"warns": 37
172+
},
173+
"cardano-bp": {
174+
"errors": 1,
175+
"warns": 2
176+
}
177+
},
178+
"anomalies": [],
179+
"epoch_transitions_observed": 1,
180+
"n2n_adversarial": {
181+
"pass": 0,
182+
"fail": 0,
183+
"panic": 0,
184+
"silent_skip": 0
185+
},
186+
"cli_parity": {
187+
"equal": 0,
188+
"divergent": 0,
189+
"skip": 0,
190+
"error": 0
191+
}
192+
}
193+
],
194+
"summary": {
195+
"pass": true,
196+
"rounds_pass": 3,
197+
"rounds_fail": 0,
198+
"total_canonical_blocks": 262,
199+
"total_tx_zoo_pass": 0,
200+
"total_tx_zoo_fail": 0,
201+
"invalid_forges_detected": 0,
202+
"critical_anomalies": 0
203+
},
204+
"trend": null
205+
}

0 commit comments

Comments
 (0)