Fix flaky ProposeNewConstitution test#6601
Conversation
2064644 to
0e48d61
Compare
d9fddec to
0020a36
Compare
0020a36 to
29c0245
Compare
There was a problem hiding this comment.
Pull request overview
This PR aims to make the ProposeNewConstitution governance integration test deterministic by avoiding a transient “proposal-with-votes-but-not-yet-ratified” window caused by low (0%) voting thresholds and pulsing snapshot lag.
Changes:
- Overrides Conway genesis in the test to raise
dvtUpdateToConstitution(to 51%) and extendgovActionLifetime, and updates theconfiguration.yamlgenesis hash accordingly. - Splits DRep voting into two rounds and replaces “wait then assert” logic with
retryUntilJustMpolling guards that wait for exact expected vote counts in ledger state and CLI output. - Updates several golden query outputs (notably PlutusV3 cost model parameter values) and adds
.serena/to.gitignore.
Reviewed changes
Copilot reviewed 5 out of 6 changed files in this pull request and generated 5 comments.
Show a summary per file
| File | Description |
|---|---|
| cardano-testnet/test/cardano-testnet-test/Cardano/Testnet/Test/Gov/ProposeNewConstitution.hs | Reworks the test setup (genesis override + rehash), voting flow (two rounds), and assertion strategy (exact-count polling) to eliminate flakiness. |
| cardano-testnet/test/cardano-testnet-test/files/golden/queries/protocolParametersOut.txt | Updates expected protocol parameter output (PlutusV3 cost model values). |
| cardano-testnet/test/cardano-testnet-test/files/golden/queries/protocolParametersFileOut.json | Updates expected protocol parameter JSON output (PlutusV3 cost model values). |
| cardano-testnet/test/cardano-testnet-test/files/golden/queries/govStateOut.json | Updates expected governance state JSON output (PlutusV3 cost model values). |
| cardano-testnet/changelog.d/20260629_103800_mgalazyn_fix_flaky_propose_new_constitution.md | Documents the test flake fix and new strategy. |
| .gitignore | Ignores .serena/ directory. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
00ab82e to
a9e4c17
Compare
palas
left a comment
There was a problem hiding this comment.
Looks good, just a couple of really minor nits
| proposalsStakePoolVotes === mempty | ||
| -- Round 1: submit 3 yes votes. Ratio = 3 yes / (3 yes + 6 non-voting) = 33.3%, below 51% threshold. | ||
| -- The proposal cannot be ratified, so it persists across epoch boundaries. | ||
| do let drepVotes = [(defaultDRepKeyPair idx, vote) | (vote, idx) <- round1Votes] |
There was a problem hiding this comment.
I think this do is redundant, is it for reducing the scope of the inner variables? Same with the do for the second round
There was a problem hiding this comment.
Yes, it just reduces the scope and makes the test more readable.
a9e4c17 to
7f04054
Compare
7f04054 to
4f64bc1
Compare
Summary
dvtUpdateToConstitutionto 51% (from the default 0%) via Conway genesis override, so a minority of yes-votes cannot trigger instant ratification.waitForGovActionVotes+ immediate assertions withretryUntilJustMpolling that exits only when the exact expected vote count appears in both ledger state and CLI output.govActionLifetimeto 4 epochs and ratification timeout to epoch 20 so the proposal survives the pulsing snapshot refresh cycle.query proposalsassertion before voting so the proposal structure is verified while it has zero votes (deterministic).Root cause
The default
dvtUpdateToConstitution = 0%means any single DRep yes-vote immediately satisfies the ratification threshold.Combined with the pulsing snapshot lag (the snapshot only picks up new votes at epoch boundaries), the window where the proposal exists with votes but is not yet ratified is extremely narrow.
The old test submitted all 9 votes at once and then asserted on the transient "proposal with votes" state, which was a race condition.
Approach
Structure the test so that the states we are interested in are longer-lived (addressing review feedback):
Test plan
DISABLE_RETRIES=1(4/4 runs, ~75-96s each)