fix: update the Leios setup to the latest prototype - #3706
Merged
Merged
Conversation
`test_no_voting_before_committee_epoch` checks that no EB is voted on before the Leios voting committee becomes active in `VOTING_START_EPOCH`. The premise no longer holds on the `leios_fast` testnet variant, where every pool votes from the first slot, so the test failed with a vote, a peer vote and a certificate reported by all three pools in epoch 0. The committee is drawn from a stake distribution snapshot. A pool registered by a transaction on a freshly started cluster instance gets into one only in `VOTING_START_EPOCH`, but cardonnay's `POOLS_IN_GENESIS` writes the pool parameters, BLS key included, straight into the genesis to avoid `VRFKeyHashAlreadyRegistered` on testnets that start in Dijkstra. Such a pool is in the initial ledger state and therefore on the committee from slot 0. The genesis always lists the pools created by `genesis create-staked --gen-pools`, so their presence doesn't tell the two setups apart, while the BLS key in their entries does. Add `_is_committee_seated_in_genesis`, which reads it from `extraConfig` or, before cardano-cli 11.2, from `staking`, and skip on it as the first thing the test does, before the wait that can otherwise burn a whole epoch.
`test_stake_snapshot` fails on a Leios enabled node with: KeyError: "Neither 'activeStake' nor 'stake' found in stake snapshot" The `pstakeMark`, `pstakeSet` and `pstakeGo` entries of `esSnapshots` are no longer the stake distribution itself. The distribution moved under a `snapShot` key, next to the new `epochNo` and `leiosCommitteeSize` fields, so `get_stake_rec` and `get_snapshot_delegations` no longer find the record they look for. Add `unwrap_snapshot`, which returns the `snapShot` value when there is one and the entry itself otherwise, and read the entries through it. The older layouts, `activeStake` of cardano-node 10.7+ and the `stake` and `delegations` of the versions before it, are kept working, with or without the wrapper. The `cardano-cli query stake-snapshot` output is not affected; it only gained a `leiosCommittee` key. Cover all three layouts with unit tests.
Every entry of `scripts/deselected_leios_tests.txt` was there for one cause, the missing PlutusV2 cost model in the Dijkstra genesis, which the node no longer has - `query protocol-parameters` reports a PlutusV2 entry in `costModels`. The latest regression run in `run_workdir` ran without the list and has a result for all 107 of its tests: 48 passed, 59 were collected but not reached before the end of the session, none failed. The 48 cover 13 of the 18 affected modules and every sub-pattern of the list - raw and build minting and spending, the `mix_v1_v2` and `mix_v2_v1` two-script cases, secp256k1 ecdsa and schnorr, inline datum and reference script visibility, and reference inputs. Drop the list and its wiring in `runner/env_leios`, the launcher and the docs. The `skip_deselect` workflow input goes with it: it existed only to clear a `DESELECT_FROM_FILE` coming from an env file, and no env file sets one anymore. The generic deselect machinery in `runner/run_tests.sh` and the tcache path stay.
Contributor
There was a problem hiding this comment.
Copilot review overview
🟡 Changes recommended
The pre-committee path lacks verified coverage, and 54 formerly deselected tests remain unverified.
Get a fresh assessment by requesting another Copilot review.
Review effort: Lite
Findings: 1
What changed in this PR
Updates the Leios setup for cardonnay 0.4.7, genesis-seated pools, and the latest snapshot format.
Changes:
- Enables
POOLS_IN_GENESISand updates dependencies. - Adds wrapped snapshot support and committee detection.
- Removes obsolete deselection configuration.
| File | Summary / review note |
|---|---|
uv.lock |
Locks cardonnay 0.4.7. |
scripts/test_leios.sh |
Removes obsolete deselection guidance. Moderate (1 vote): 54 formerly deselected tests remain unverified. |
scripts/deselected_leios_tests.txt |
Removes obsolete Leios deselection entries. |
runner/run_tests.sh |
Updates deselection comments while retaining generic machinery. |
runner/env_leios |
Enables POOLS_IN_GENESIS. Nit (1 vote): documentation should describe this requirement and the removed skip_deselect input. |
pyproject.toml |
Raises the minimum cardonnay version. |
framework_tests/test_clusterlib_utils.py |
Adds snapshot helper and layout coverage. |
doc/leios_tests.md |
Documents Leios setup and CI inputs. Nit (2 votes): the setup variable and removed workflow input remain stale. |
cardano_node_tests/utils/clusterlib_utils.py |
Supports wrapped Leios stake snapshots. |
cardano_node_tests/tests/test_leios_blocks.py |
Detects genesis-seated committees. Moderate (1 vote): the pre-committee path lacks verified coverage for modern and legacy layouts. |
.github/workflows/regression-leios.yaml |
Removes the obsolete workflow input. |
.github/workflows/regression_reusable.yaml |
Removes deselection override handling. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
The forge loop forecasts the ledger view from the tip of the chain the node has selected, and the forecast reaches only `3k/f` slots past that tip. On `leios_fast` that is 240 slots at k=4 and f=0.05. A node kept busy by a standalone Tx load generator can fall further behind than that, and then it just skips the slot it was about to forge and recovers as soon as it catches up. The trace lands in whatever test happens to be in teardown, so it is reported as a failure of an unrelated test. Ignore it, but only when `ENABLE_TX_CENTRIFUGE` or `ENABLE_TX_FIREHOSE` is set - without the load, a node falling that far behind is worth reporting.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.

Bumps
cardonnayto 0.4.7 and turns onPOOLS_IN_GENESISfor the Leiostestrun, then fixes the test fallout of that setup and of the latest
leios-prototypenode.POOLS_IN_GENESISPool re-registration fails on a testnet that starts in Dijkstra, because the
Dijkstra POOL rule expects every registered pool's VRF key hash in
psVRFKeyHashesand genesis staking injection records none.POOLS_IN_GENESIS(cardonnay 0.4.7) sidesteps it by writing the full pool parameters into the
genesis instead of submitting a registration transaction.
That puts the pools - BLS keys included - in the initial ledger state, which
changes when the Leios voting committee is seated.
test_no_voting_before_committee_epochThe test checks that no EB is voted on before the committee becomes active in
VOTING_START_EPOCH. With the pools in the genesis there is no such window:all three pools voted in epoch 0 and no pool ever reported
NotOnCommittee, sothe test failed on a premise that no longer holds.
The genesis always lists the pools created by
genesis create-staked --gen-pools, so their presence says nothing; the BLS key in their entries iswhat separates a genesis-seated pool from one registered by a transaction. The
new
_is_committee_seated_in_genesisreads it fromextraConfig.stakePools,or from
staking.poolsbefore cardano-cli 11.2, and the test skips on it asits first act - before the wait that can otherwise burn a whole epoch.
Checked against the genesis of five local clusters:
Truefor the threeleios_fastones,Falsefor bothlocal_fastones.Stake snapshots
test_stake_snapshotfailed with:The
pstakeMark,pstakeSetandpstakeGoentries ofesSnapshotsare nolonger the stake distribution itself - it moved under a
snapShotkey, next tothe new
epochNoandleiosCommitteeSizefields.unwrap_snapshotreturns thesnapShotvalue when there is one and the entryitself otherwise, and
get_stake_recandget_snapshot_delegationsread theentries through it. The older layouts keep working, with or without the
wrapper:
activeStakeof cardano-node 10.7+, andstake/delegationsbefore it.
cardano-cli query stake-snapshotis unaffected; it only gained aleiosCommitteekey.NoLedgerViewunder Tx loadTeardowns failed on
Forge.Loop.NoLedgerViewin a node log. The forge loopforecasts the ledger view from the tip of the chain the node has selected, and
ledgerViewForecastAtreaches onlystabilityWindow=3k/fslots past thattip - 240 slots on
leios_fast, at k=4, f=0.05 and a 1 s slot. A node kept busyby
tx-firehoseortx-centrifugecan fall further behind than that. It thenskips the slot it was about to forge and recovers as soon as it catches up, so
nothing is wrong with the node; the trace only lands in whatever test happens
to be in teardown and is reported as that test's failure.
_get_ignored_error_regexesnow ignores it, gated onENABLE_TX_CENTRIFUGEorENABLE_TX_FIREHOSE, next to the existingGITHUB_ACTIONSand testnet gates.Without a Tx load generator a node falling that far behind is still reported.
This silences the noise, it does not change the odds. The 240-slot window holds
only about 10.7 expected blocks at the measured chain density of 0.045, so the
tail is fat; the underlying fix would be a larger
kin the testnet variant.Raising
kis cheap for this repo - every test reads it from the genesis, andclusterlib_utils.get_stability_windowalready derives3k/f- but it belongsin cardonnay, not here.
Deselect list
Every entry of
scripts/deselected_leios_tests.txtwas there for one cause,the missing PlutusV2 cost model in the Dijkstra genesis, which the node no
longer has -
query protocol-parametersnow reports a PlutusV2 entry incostModels.The list and its wiring are gone, together with the
skip_deselectworkflowinput, which only existed to clear a
DESELECT_FROM_FILEcoming from an envfile and no env file sets one anymore. The generic deselect machinery in
runner/run_tests.shand the tcache path stay.Testing
snapshot layouts, both helpers and both
KeyErrorpaths, and a new case ontest_get_ignored_error_regexesfor the Tx load gate.test_stake_snapshotpasses against a local Dijkstra + Leios cluster whoseledger state does carry the
snapShotwrapper.48 passed, 59 were collected but not reached before the end of the session,
none failed. The 48 cover 13 of the 18 affected modules and every
sub-pattern - raw and build minting and spending, the
mix_v1_v2andmix_v2_v1two-script cases, secp256k1 ecdsa and schnorr, inline datum andreference script visibility, and reference inputs. Five more were rerun
locally and pass.
test_no_voting_before_committee_epochis verified only on the skip path; thesetup where the committee is not seated in the genesis needs a run on a testnet
variant without
POOLS_IN_GENESIS.