1

I would like to know the age of each validator in the mainnet. What is the best way to get this info on-chain?

2 Answers 2

2

This will be a bit tricky given that the vote account only stores a limited amount of history. The best you can do practically is epoch-level resolution. It is further complicated by the fact that the vote account may have been deleted and recreated in the past, potentially multiple times. Any history prior to the most recent creation would be lost in this case. (See appendix for additional thoughts)


I'm going to reference the vote program's code, which is in Rust, since it is the arbiter of truth. It looks like the corresponding RPC replies will follow its lead without modification, so the constants in the Rust code should apply there too. You will likely need to do your own snake-case to camel-case conversions.

We're going to be interested in the VoteState structure. Unfortunately the reply of getVoteAccounts omits the fields we're interest in here. Instead you can to use getProgramAccounts targeting the vote program with parsed accounts reply like this (or your favorite SDK's equivalent)

curl https://api.devnet.solana.com -X POST -H "Content-Type: application/json" -d '
  {
    "jsonrpc":"2.0",
    "id":1,
    "method":"getProgramAccounts",
    "params":[
      "Vote111111111111111111111111111111111111111",
      {"encoding":"jsonParsed"}
    ]
  }
'

prior_voters

The first place to look is the prior_voters field. This is a circular buffer with fixed size of 32 (as of July 2022) items. It stores historical authorized voters as the tuple (signing_pubkey, first_authorized_epoch, last_authorized_epoch).

  • If it is empty, the authorized voter has never been changed. Proceed to authorized_voters
  • If it is full, prior authorized voters may have been dropped from the history. Proceed to the appendix
  • Otherwise, the value of the lowest first_authorized_epoch should be when validator started voting

authorized_voters

The active and pending authorized voters are available in the authorized_voters field. It stores a mapping of first_authorized_epoch to signing_pubkeys. If prior_voters is empty, the lowest key in this map should be when the validator started voting.

Appendix

If prior_voters has overflowed, or there is suspicion that a vote account has been deleted and recreated, the only way forward is to walk the transaction history for each vote account looking for the earliest transaction to issue a VoteInstruction::Initialize instruction. You probably DO NOT want to do this. The vote account's address is referenced in every vote transaction, meaning that the initialization transaction(s) are buried in millions of votes.

There are two potential shortcuts, but they have their own caveats.

  1. Try to walk the the vote account's authorized_withdrawer's transaction history to find the earliest withdraw transaction, then switch to walking the vote account's history as described above
    • Won't work if the vote account has never been withdrawn from, as there is no history to walk
    • Won't help if the authorized_withdrawer was ever also an authorized_voter, as again the history is flooded with vote transactions
    • The authorized_withdrawer may have been changed. So you'll need to switch back to the vote account's history to find the transaction issuing a VoteAccount::Authorize instruction and proceed with the previous authorized_withdrawer transaction history
  2. Similar to [1], but with the authorized_staker. Same caveats, but instead you're looking for administrative instructions (VoteInstruction::{Authorize, UpdateValidatorIdentity, UpdateCommission, etc}).
1
  • I am not sure about the mapping of authorized_voters, it looks like more the latest_authorized_epoch than the first_authorized_epoch. If for example I take voter with identity XkCriyrNwS3G4rzAXtG5B1nnvb5Ka1JtCku93VqeKAr (Coinbase Cloud) which is not a new one. I got "authorizedVoters":[{"authorizedVoter":"XkCriyrNwS3G4rzAXtG5B1nnvb5Ka1JtCku93VqeKAr","epoch":329}]. So it's pointing to the current epoch (at the time of my writing). Do you think It's an issue of the jsonParsed mapping? Jul 21, 2022 at 22:05
1

Trent's answer is correct (as usual). That also looks like a lot of work. ;-)

If you want a "quick & dirty" estimate of when each validator came online, and are OK with off-chain data, you can use the API on validators.app. We maintain a list of validators including the date & time that we first saw them on the cluster. This will be accurate within a few minutes in most cases. See https://www.validators.app/api-documentation?locale=en&network=mainnet#validators-list and look for the created_at attribute.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.