Skip to content

Commit 9d8dedb

Browse files
committed
SIMD-0185: Vote Account v4
1 parent 0005fd6 commit 9d8dedb

File tree

1 file changed

+243
-0
lines changed

1 file changed

+243
-0
lines changed

proposals/0185-vote-account-v4.md

+243
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,243 @@
1+
---
2+
simd: '0185'
3+
title: Vote Account v4
4+
authors: Justin Starry (Anza)
5+
category: Standard
6+
type: Core
7+
status: Review
8+
created: 2024-10-17
9+
feature: (fill in with feature tracking issues once accepted)
10+
---
11+
12+
## Summary
13+
14+
A new update for the vote program is proposed to improve authorized voter
15+
bookkeeping as well as allow validators to set commission rates and collector
16+
accounts for different revenue sources.
17+
18+
## Motivation
19+
20+
This SIMD details two different modifications to the vote program and vote
21+
account state and combines these changes into one proposal so that only
22+
one vote account version update is needed.
23+
24+
### Revenue Collection Customization
25+
26+
- There is only one commission rate stored in vote account state but validators
27+
with to be able to use different commission rates for different income streams
28+
like block rewards and tips.
29+
30+
- It's not possible to customize which accounts income is collected into.
31+
Currently all block rewards and tips are always collected into the validator
32+
identity account which cannot be a cold wallet since the identity needs to sign
33+
a lot of messages for various network protocols used in Solana like turbine,
34+
gossip, and QUIC.
35+
36+
### Authorized voter bookkeeping
37+
38+
- Over 40% of vote state size is reserved for tracking a history of 32 prior
39+
authorized voters for the vote account in the `prior_voters` field. Having such
40+
a long history of prior voters is arguably not very useful, tracking the most
41+
recent previous epoch's voter is probably sufficient and can be stored in the
42+
`authorized_voters` field instead.
43+
44+
- The `authorized_voters` field doesn't store the voter for the previous epoch
45+
so it's impossible to have a transition epoch where both the previous and newly
46+
assigned voter can both sign votes.
47+
48+
## Alternatives Considered
49+
50+
### Reuse vote commission
51+
52+
Vote accounts already allow validators to set a commission rate for inflation
53+
rewards and so it's not unreasonable to expect that this commission rate could
54+
also be used to distribute block rewards. However, some validators have
55+
expressed a desire to be able to tune revenue streams indpendently.
56+
57+
## New Terminology
58+
59+
- Block Fees Collector: The account used to collect commissioned block fees for
60+
validators. Previously collected by default into the validator identity account.
61+
62+
- Block Tips Collector: The account used to collect commissioned block tips for
63+
validators. Previously configured by a Jito CLI parameter.
64+
65+
- Inflation Rewards Collector: The account used to collect commissioned
66+
inflation rewards for validators. Previously collected by default into the vote
67+
account.
68+
69+
- Block Fees Commission: The commission rate that determines how much of block
70+
base fee and priority fee revenue is collected by the validator before
71+
distributing remaining funds to stake delegators. Previously 100% of block fees
72+
were distributed to the validator identity account.
73+
74+
- Block Tips Commission: The commission rate that determines how much of block
75+
tip revenue is collected by the validator before distributing remaining funds to
76+
stake delegators. Previously configured by a Jito CLI parameter.
77+
78+
- Inflation Rewards Commission: The commission rate that determines how much of
79+
stake inflation rewards are collected by the validator before distributing the
80+
remaining rewards to stake delegators. Previously referred to as simply the
81+
"commission" since there was no need to differentiate from other types of
82+
commission.
83+
84+
## Detailed Design
85+
86+
Currently, all block fees, including both transaction base fees and priority
87+
fees, are collected into a validator's node id account. This proposal details
88+
changes to the Vote Program and Vote Account that will allow validators to
89+
specify how different sources of income are collected. This proposal also
90+
updates the bookkeeping for authorized voters in the vote account state.
91+
92+
### Vote Account
93+
94+
A new version of vote state will be introduced with the enum discriminant value
95+
of `3u32` which will be little endian encoded in the first 4 bytes of account
96+
data.
97+
98+
```rust
99+
pub enum VoteStateVersions {
100+
V1(..),
101+
V2(..),
102+
V3(..),
103+
V4(..), // <- new variant
104+
}
105+
```
106+
107+
This new version of vote state will include new fields for setting the
108+
commission and collector account for each of the three sources of validator
109+
income: inflation rewards, block fees, and block tips. It will also remove
110+
the `prior_voters` field.
111+
112+
```rust
113+
pub struct VoteStateV4 {
114+
pub node_pubkey: Pubkey,
115+
pub authorized_withdrawer: Pubkey,
116+
117+
/// NEW: the collector accounts for validator income
118+
pub inflation_rewards_collector: Pubkey,
119+
pub block_fees_collector: Pubkey,
120+
pub block_tips_collector: Pubkey,
121+
122+
/// NEW: percentages (0-100) that represent how much of each income source
123+
/// should be given to this VoteAccount
124+
pub inflation_rewards_commission: u8,
125+
pub block_fees_commission: u8,
126+
pub block_tips_commission: u8,
127+
128+
/// NEW: bump seed for deriving this vote accounts stake rewards pool address
129+
pub stake_rewards_pool_bump_seed: u8,
130+
131+
/// REMOVED
132+
/// prior_voters: CircBuf<(Pubkey, Epoch, Epoch)>,
133+
134+
pub votes: VecDeque<LandedVote>,
135+
pub root_slot: Option<Slot>,
136+
pub authorized_voters: AuthorizedVoters,
137+
pub epoch_credits: Vec<(Epoch, u64, u64)>,
138+
pub last_timestamp: BlockTimestamp,
139+
}
140+
```
141+
142+
Whenever a vote account is modified by the vote program in a transaction AND
143+
hasn't been updated to v4 yet, the account state MUST be saved in the new format
144+
with the following default values for the new fields described above:
145+
146+
```rust
147+
VoteStateV4 {
148+
// ..
149+
150+
inflation_rewards_collector: vote_state_v3.node_pubkey,
151+
block_fees_collector: vote_state_v3.node_pubkey,
152+
block_tips_collector: vote_state_v3.node_pubkey,
153+
inflation_rewards_commission: vote_state_v3.commission,
154+
block_fees_commission: 100u8,
155+
block_tips_commission: 100u8,
156+
stake_rewards_pool_bump_seed: find_stake_rewards_pool_bump_seed(vote_pubkey),
157+
158+
// ..
159+
}
160+
161+
fn find_stake_rewards_pool_bump_seed(vote_pubkey: &Pubkey) -> u8 {
162+
Pubkey::find_program_address(
163+
[
164+
b"stake_rewards_pool",
165+
vote_pubkey.as_ref(),
166+
],
167+
&stake_program::id(),
168+
).1
169+
}
170+
```
171+
172+
### Vote Program
173+
174+
```rust
175+
pub enum VoteInstruction {
176+
// ..
177+
UpdateCommission {..} // 5u32
178+
// ..
179+
UpdateCommissionWithKind { // 16u32
180+
commission: u8,
181+
kind: CollectorKind,
182+
},
183+
UpdateCollectorAccount { // 17u32
184+
pubkey: Pubkey,
185+
kind: CollectorKind,
186+
},
187+
}
188+
189+
#[repr(u8)]
190+
pub enum CollectorKind {
191+
InflationRewards = 0,
192+
BlockFees,
193+
BlockTips,
194+
}
195+
```
196+
197+
#### `UpdateCommission`
198+
199+
The existing `UpdateCommission` instruction (with enum discriminant `5u32`) will
200+
continue to exist but will continue to only update the inflation rewards
201+
commission.
202+
203+
#### `UpdateCommissionWithKind`
204+
205+
A new instruction for setting different kinds of commissions will be added to
206+
the vote program with the enum discriminant of `16u32` little endian encoded in
207+
the first 4 bytes.
208+
209+
#### `UpdateCollectorAccount`
210+
211+
A new instruction for setting collector accounts will be added to the vote
212+
program with the enum discriminant value of `17u32` little endian encoded in the
213+
first 4 bytes.
214+
215+
#### `Authorize`, `AuthorizeChecked`, `AuthorizeWithSeed`, `AuthorizeCheckedWithSeed`
216+
217+
Existing authorize instructions will be processed differently when setting new
218+
authorized voters. Rather than purging authorized voter entries from the
219+
`authorized_voters` field that correspond to epochs less than the current epoch,
220+
only purge entries less than the previous epoch (current epoch - 1). This will
221+
mean that the `authorized_voters` field can now hold up to 4 entries for the
222+
epochs in the range `[current_epoch - 1, current_epoch + 2]`. Keeping the
223+
authorized voter around from the previous epoch will allow the protocol to
224+
accept votes from both the current and previous authorized voters to make voter
225+
transitions smoother.
226+
227+
## Impact
228+
229+
This is a prerequisite for implementing block reward distribution in SIMD-0123.
230+
231+
## Security Considerations
232+
233+
What security implications/considerations come with implementing this feature?
234+
Are there any implementation-specific guidance or pitfalls?
235+
236+
## Drawbacks *(Optional)*
237+
238+
Why should we not do this?
239+
240+
## Backwards Compatibility *(Optional)*
241+
242+
Does the feature introduce any breaking changes? All incompatibilities and
243+
consequences should be listed.

0 commit comments

Comments
 (0)