Skip to content

feat(registry): take historical validator snapshots #99

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 8 commits into
base: main
Choose a base branch
from

Conversation

k4m4
Copy link
Collaborator

@k4m4 k4m4 commented Jul 25, 2025

This PR completes Stage 1: Administration of the roadmap for using the PodRegistry contract on Ethereum as the source of truth for pod validators (ultimately, with staking & slashing). It introduces a validator lifecycle model with active/inactive states, allowing validators to temporarily deactivate (e.g., for maintenance) and later reactivate. The contract owner can also ban/unban validators, where banning permanently removes a validator from the active set until explicitly unbanned.

The contract now also supports historical validator set tracking via snapshots. Each time the active validator set changes (addition, ban/unban, deactivate/reactivate), a snapshot of the validator bitmap and the block number is stored. This enables efficient historical proofs of validator membership using a witness index and block reference.

Breaking Changes

  1. Removed removeValidator(); replaced by banValidator() and unbanValidator().
  2. Removed validatorCount from storage; validator counts are now derived from activeValidatorBitmap.
  3. Added computeWeight() signature requiring blockNumber and snapshotIndex for historical validation.
  • computeWeight() computes the number of validators in the given subset that were active at a specific historical block using the provided snapshot index as a witness. Ensures the snapshot is valid for the given block and counts unique active validators without duplication.

Important Notes

  1. Active vs. Inactive: Validators can deactivate/reactivate themselves but cannot rejoin if banned.
  2. Snapshots: Stored in history[] and indexed by block; use findSnapshotIndex() view function for binary search off-chain.
  3. Bitmap Representation: Active validators tracked via activeValidatorBitmap; supports up to 255 validators.
  4. Fault Tolerance: Calculated on-demand by counting set bits (popcount) of activeValidatorBitmap instead of using a stored counter.
  5. Witness Validation: computeWeight() checks that the provided snapshot index is neither too old nor too new for the given block.

@k4m4 k4m4 marked this pull request as ready for review July 25, 2025 13:41
require(!bannedValidators[validator], "pod: validator is already banned");

uint256 mask = 1 << (index - 1);
if ((activeValidatorBitmap & mask) != 0) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

does this if check make sense? logically i prefer to always just unset, and gas wise i doubt it's an improvement

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

for example in deactivate you (in my opinion correctly) don't check first

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