SIMD-0033

Timely Vote Credits

Author: Bryan Ischo <[email protected]> · Category: Core Protocol GitHub →

Feature Gate Status

Mainnet Active E703
Testnet Active E692
Devnet Active E735

tvcF6b1TRz353zKuhBjinZkKzjmihXmBAHJdjNYw1sQ

TL;DR

Award a variable number of vote credits per voted on slot, with more credits being given for votes that have "less latency" than votes that have "more latency".

Summary

Award a variable number of vote credits per voted on slot, with more credits being given for votes that have "less latency" than votes that have "more latency".

Motivation

Vote credits are the accounting method used to determine what percentage of inflation rewards a validator earns on behalf of its stakers. Currently, when a slot that a validator has previously voted on is "rooted", it earns 1 vote credit. A "rooted" slot is one which has received full commitment by the validator (i.e. has been finalized). One problem with this simple accounting method is that it awards one credit per rooted slot regardless of when it was voted on. This means that a validator can delay its voting for many slots in order to survey forks and make votes that are more likely to be rooted. This strategy saves fees on extraneous votes, and minimizes no voting periods due to lockout. This is not just a theoretical concern; a number of validators appear to be using this technique to inflate their vote credits, some having been doing so for over a year. The number of validators using this approach is increasing over time. It is estimated that about 7.5 million stake, or roughly 2% of all stake on the network, is using an intentional vote lagging strategy.

Impact

1. Any code which deserialized vote account state will require a recompile with the newest Solana SDK in order to be able to deserialize the new vote account state. 2. There will be a strong anti-incentive for vote lagging. Validators who currently delay their votes in order to reduce their chances of being locked out from voting, will no longer do so. 3. The Solana CLI will have been updated to show vote latencies for each vote; any context in which the Solana CLI output is observed by users or other tooling will need to adapt to the additonal data being displayed. 4. The maximum number of earnable credits will increase from 432,000 to 3,456,000. This will add an extra digit in any context where this value is displayed, which could make the tabular form of some tooling too large to fit the predefined columns. 5. The format of data stored in vote accounts will change; see the Backwards Compatibility section for details.

Backwards Compatibility

Because a new field is added to the Lockout struct, the format of the VoteState struct, which is Rust bincode serialized and stored in the Vote account for each validator, is changed. This requires adding a new enum value to VoteStateVersions, which then makes any code outside of the validator code base which does not know about this new VoteStateVersion unable to deserialize vote account contents. This will require some announcement and for applications which deserialize Vote accounts to be given time to recompile with the new Solana SDK that includes the new VoteStateVersion. In addition, when VoteState updates, any validators running a version of the code from before the addition of the new VoteStateVersion will be unable to deserialize vote accounts loaded from snapshots produced by validators running newer versions of the code. This could create difficulties for validator operators who download snapshots and find that their validator cannot process vote transactions due to the vote accounts being unloadable. For this reason, the change must be broken into several parts, with enough time between changes to allow the validator set to all move well beyond incompatible code versions: 1. A change will be made which adds the new VoteStateVersion to the code base but does not enable its use. The enablement of the use of the new VoteStateVersion will be behind a feature switch; until this feature is enabled, validators will internally represent Vote accounts using the new VoteStateVersion, but will always serialize and store vote account contents using the prior version. This does not lose information as the latency value will not be used for anything before a later change, and thus is implicitly always valued as '0', and on reading the vote account and converting it to the newest VoteStateVersion, the default value of '0' for latency will reconstitute the value of 0 that was in that field at the time that the VoteState was serialized. Once this software version has been integrated into the cluster and proven for a period of time, would the feature be enabled. At this point, validators will begin writing vote account state using the newest VoteStateVersion, and their snapshots will no longer be usable by the old software versions, which by this point will be so old that rollback to them is a practical impossibility anyway. In addition, the vote state of an account cannot be updated to the new larger form unless the vote account has sufficient lamports to cover the new higher rent exempt minimum. The new size of vote accounts will be 3762 bytes, a 31 byte increase on the old size of 3731 bytes. The rent exempt minimum for vote accounts will thus increase from 0.02685864 SOL to 0.0270744 SOL. This is an additional 0.00021576 SOL per vote account. Given roughly 2,000 vote accounts currently on mainline, the maximum SOL needed to increase all vote accounts to the requi

Security Considerations

The are no security considerations; however there are changes to incentive structure for voting which may result in differing vote behavior becoming more optimal with regards to earning credits. To maximize vote credits, a validator must vote on all slots that end up being rooted by the cluster, and no slots that are not rooted. This means always "picking the right fork" whenever there are forks. It is the drive to always vote on the correct fork that causes validators to choose a vote lagging strategy in the first place; they can earn more credits if they reduce their chances of voting on "the wrong fork" by waiting until sufficient votes from other validators have landed on a given slot before voting on it. Therefore the optimal vote strategy currently is to wait until a slot is rooted (i.e. has received 31 confirmations) before voting on it. In this way, perfect vote credits would be earned. However, this optimal voting strategy, if employed cluster-wide, would halt the cluster as no validators would vote, all of them waiting for others to vote first. It's possible to get very close to this optimal strategy by waiting for some number of confirmations less than 31, with the number of incidents of picking the wrong fork increasing as the waiting time is decreased. The current "vote laggers" have done this, with varying degrees of skill. After the timely vote credits change, the dynamics will change; it will no longer be profitable to intentionally lag, or if it is profitable in some situations to do so, the frequency and duration of this situations will be vastly reduced. The new optimal voting strategy will be a complex calculation based partially on predictions of how frequently forks will occur and how long they will last. This is because a validator who votes more quickly will earn more vote credits per vote, but will also be more likely to have voted on a dead fork and end up being locked out for some number of slots. It will become impossible to pick a voting strategy that always produces the most possible vote credits. Different voting strategies will all exist simultaneously, in a sort of a "rock paper scissors" situation where the best possible strategy shifts over time depending on how other validators are voting. This will result in the strengthening of the cluster via the elimination of a "voting monoculture".