Skip to content

fix(staking): preserve validator UX on the train - #412

Draft
kirilaa wants to merge 5 commits into
v0.40-devfrom
fix/staking-paged-reads
Draft

fix(staking): preserve validator UX on the train#412
kirilaa wants to merge 5 commits into
v0.40-devfrom
fix/staking-paged-reads

Conversation

@kirilaa

@kirilaa kirilaa commented Aug 25, 2026

Copy link
Copy Markdown

Depends-On: genlayerlabs/genlayer-consensus#1307
Depends-On: genlayerlabs/genlayer-node#1800
Depends-On: genlayerlabs/genlayer-js#212

Decision

The CLI targets the train contracts without deployment-version fallbacks. Ordinary commands use the SDK's stored, consumer-oriented lifecycle; projection and manual finalization live under advanced/recovery commands.

  • active means selectable/duty-eligible;
  • joined means present in the validator registry, including not-yet-selectable validators;
  • receipt waiting accepts --wait-until decided|finalized, not raw protocol statuses.

Changes

  • Keeps staking active-validators strict and adds staking joined-validators.
  • Preserves validator priming guidance and proof-bound operator rotation UX.
  • Uses the required SDK lifecycle directly; there is no old-layout fallback or synthesized ReadyToFinalize.
  • Adds an advanced lifecycle command backed by the typed SDK API; raw protocol fields remain behind advanced/--raw output.
  • Keeps manual finalize commands in the advanced/recovery group.
  • Fixes SDK-integration bugs in staking action typing, current epoch metrics, owner-address guards, vesting wallet discovery, and keychain module loading.
  • Pins immutable genlayer-js commit d9c564ebb3294f4472fcc69638b0ab0b7624cf50.

Validation

  • npx tsc --noEmit
  • npm test -- --run: 813 passed across 75 files, including loopback wallet tests
  • npm run build
  • CLI API docs regenerated
  • git diff --check

Live composed behavior is qualified by genlayerlabs/genlayer-e2e#748; the 1,543-validator scenario remains gated.

The staking contract withdrew the unpaged validator reads the CLI was
built on. `activeValidators()` is gone outright, and the balanced-tree
walk lost both of its footholds: `validatorsRoot()` no longer exists and
`validatorView()` no longer carries the left/right/parent links. None of
this degrades gracefully -- the calls revert rather than truncating, so
`genlayer staking active-validators` exits non-zero against a deployment
carrying the change.

Read the append-only joined registry instead, one page at a time:
`validatorsJoinedCount()` bounds the walk and `getValidatorsJoined(start,
pageSize)` returns each page. The count is read first so a set that grows
underneath the walk cannot spin the loop, and a short page means it shrank
instead -- stop there and let the next read see the settled set. Page size
is 64, matching the convention the contract's own paged reads are written
around; committee capacity is 1,543 seats, which is why the unpaged read
had to go in the first place.

`staking validators` loses its one-call answer for "in the current draw",
so the active marker is now derived from what is still readable: joined,
and neither banned nor quarantined.
@coderabbitai

coderabbitai Bot commented Aug 25, 2026

Copy link
Copy Markdown

Important

Draft PR not reviewed

Draft PRs are not automatically reviewed by default.

  • Trigger a manual review

To automatically review draft PRs, update your CodeRabbit configuration:

reviews:
  auto_review:
    drafts: true

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@kirilaa

kirilaa commented Aug 25, 2026

Copy link
Copy Markdown
Author

The four SDK-side items under What this does NOT fix are now covered by
genlayerlabs/genlayer-js#212 — leaving a note rather than editing the body,
since that PR is yours.

Item listed here #212
getTransactionData successors detected against the chain's own ABI, so a testnet keeps the old call
activeValidatorsCount() inside getEpochInfo() reads validatorsJoinedCount() instead
validatorView drift breaking getValidatorInfo() ABI resynced to the train's nine fields
getKnownValidatorSet()client.getActiveValidators() paged walk over getValidatorsJoined

One correction worth carrying across: the paged reads are not train-only.
Pre-train StakingReadFacet already exposes validatorsJoinedCount and
getValidatorsJoined (and activeValidatorsCount), so moving to them is safe
on both surfaces — activeValidators, the one the train removed, lived on
StakingConfig. That narrows the shared compat risk to validatorView 12→9,
which is the one read with no chain ABI to detect against.

@MuncleUscles MuncleUscles changed the title fix(staking): read the joined validator set a page at a time fix(staking): preserve validator UX on the train Aug 27, 2026
Present the SDK's stored-state lifecycle in ordinary receipt output and reserve raw stored/projected/action data for an explicit advanced lifecycle command with optional timestamp evaluation. Keep manual finalization under advanced recovery and preserve full raw receipts behind --raw.\n\nValidation: full 75-file Vitest suite (814 tests); build; generated docs; diff check.
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.

2 participants