diff --git a/Cargo.lock b/Cargo.lock index c1c68a8de..12a4fdd74 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4187,12 +4187,14 @@ version = "2.2.5" dependencies = [ "arbitrary", "bincode", + "cfg_eval", "itertools 0.12.1", "num-derive", "num-traits", "rand 0.8.5", "serde", "serde_derive", + "serde_with", "solana-clock", "solana-epoch-schedule", "solana-frozen-abi", diff --git a/vote-interface/Cargo.toml b/vote-interface/Cargo.toml index e6e76f324..1acb616f0 100644 --- a/vote-interface/Cargo.toml +++ b/vote-interface/Cargo.toml @@ -35,8 +35,10 @@ frozen-abi = [ "solana-short-vec/frozen-abi", ] serde = [ + "dep:cfg_eval", "dep:serde", "dep:serde_derive", + "dep:serde_with", "dep:solana-serde-varint", "dep:solana-short-vec", "solana-hash/serde", @@ -46,10 +48,12 @@ serde = [ [dependencies] arbitrary = { workspace = true, features = ["derive"], optional = true } bincode = { workspace = true, optional = true } +cfg_eval = { workspace = true, optional = true } num-derive = { workspace = true } num-traits = { workspace = true } serde = { workspace = true, optional = true } serde_derive = { workspace = true, optional = true } +serde_with = { workspace = true, features = ["macros"], optional = true } solana-clock = { workspace = true } solana-frozen-abi = { workspace = true, features = [ "frozen-abi", diff --git a/vote-interface/src/state/mod.rs b/vote-interface/src/state/mod.rs index 85c028923..63d724040 100644 --- a/vote-interface/src/state/mod.rs +++ b/vote-interface/src/state/mod.rs @@ -23,9 +23,14 @@ pub mod vote_state_versions; pub use vote_state_versions::*; pub mod vote_state_v3; pub use vote_state_v3::VoteStateV3; +pub mod vote_state_v4; +pub use vote_state_v4::VoteStateV4; mod vote_instruction_data; pub use vote_instruction_data::*; +/// Size of a BLS public key in a compressed point representation +pub const BLS_PUBLIC_KEY_COMPRESSED_SIZE: usize = 48; + // Maximum number of votes to keep around, tightly coupled with epoch_schedule::MINIMUM_SLOTS_PER_EPOCH pub const MAX_LOCKOUT_HISTORY: usize = 31; pub const INITIAL_LOCKOUT: usize = 2; diff --git a/vote-interface/src/state/vote_state_v4.rs b/vote-interface/src/state/vote_state_v4.rs new file mode 100644 index 000000000..956f158ac --- /dev/null +++ b/vote-interface/src/state/vote_state_v4.rs @@ -0,0 +1,67 @@ +#[cfg(feature = "dev-context-only-utils")] +use arbitrary::Arbitrary; +#[cfg(feature = "serde")] +use serde_derive::{Deserialize, Serialize}; +#[cfg(feature = "serde")] +use serde_with::serde_as; +#[cfg(feature = "frozen-abi")] +use solana_frozen_abi_macro::{frozen_abi, AbiExample}; +use { + super::{BlockTimestamp, LandedVote, BLS_PUBLIC_KEY_COMPRESSED_SIZE}, + crate::authorized_voters::AuthorizedVoters, + solana_clock::{Epoch, Slot}, + solana_pubkey::Pubkey, + std::{collections::VecDeque, fmt::Debug}, +}; + +#[cfg_attr( + feature = "frozen-abi", + frozen_abi(digest = "3ZzRX9A9Ft55EPsKo9yuTKTReigf6RW3EKp71p451Sqo"), + derive(AbiExample) +)] +#[cfg_attr(feature = "serde", cfg_eval::cfg_eval, serde_as)] +#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))] +#[derive(Debug, Default, PartialEq, Eq, Clone)] +#[cfg_attr(feature = "dev-context-only-utils", derive(Arbitrary))] +pub struct VoteStateV4 { + /// The node that votes in this account. + pub node_pubkey: Pubkey, + /// The signer for withdrawals. + pub authorized_withdrawer: Pubkey, + + /// The collector account for inflation rewards. + pub inflation_rewards_collector: Pubkey, + /// The collector account for block revenue. + pub block_revenue_collector: Pubkey, + + /// Basis points (0-10,000) that represent how much of the inflation + /// rewards should be given to this vote account. + pub inflation_rewards_commission_bps: u16, + /// Basis points (0-10,000) that represent how much of the block revenue + /// should be given to this vote account. + pub block_revenue_commission_bps: u16, + + /// Reward amount pending distribution to stake delegators. + pub pending_delegator_rewards: u64, + + /// Compressed BLS pubkey for Alpenglow. + #[cfg_attr( + feature = "serde", + serde_as(as = "Option<[_; BLS_PUBLIC_KEY_COMPRESSED_SIZE]>") + )] + pub bls_pubkey_compressed: Option<[u8; BLS_PUBLIC_KEY_COMPRESSED_SIZE]>, + + pub votes: VecDeque, + pub root_slot: Option, + + /// The signer for vote transactions. + /// Contains entries for the current epoch and the previous epoch. + pub authorized_voters: AuthorizedVoters, + + /// History of credits earned by the end of each epoch. + /// Each tuple is (Epoch, credits, prev_credits). + pub epoch_credits: Vec<(Epoch, u64, u64)>, + + /// Most recent timestamp submitted with a vote. + pub last_timestamp: BlockTimestamp, +}