Skip to content
Open
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions vote-interface/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ frozen-abi = [
serde = [
"dep:cfg_eval",
"dep:serde",
"dep:serde_bytes",
"dep:serde_derive",
"dep:serde_with",
"dep:solana-serde-varint",
Expand All @@ -54,6 +55,7 @@ cfg_eval = { workspace = true, optional = true }
num-derive = { workspace = true }
num-traits = { workspace = true }
serde = { workspace = true, optional = true }
serde_bytes = { workspace = true, optional = true }
serde_derive = { workspace = true, optional = true }
serde_with = { workspace = true, features = ["macros"], optional = true }
solana-clock = { workspace = true }
Expand Down
58 changes: 57 additions & 1 deletion vote-interface/src/instruction.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use {
super::state::TowerSync,
crate::state::{
Vote, VoteAuthorize, VoteAuthorizeCheckedWithSeedArgs, VoteAuthorizeWithSeedArgs, VoteInit,
VoteStateUpdate, VoteStateV4,
VoteInitV2, VoteStateUpdate, VoteStateV4,
},
solana_clock::{Slot, UnixTimestamp},
solana_hash::Hash,
Expand Down Expand Up @@ -34,6 +34,15 @@ pub enum VoteInstruction {
/// 3. `[SIGNER]` New validator identity (node_pubkey)
InitializeAccount(VoteInit),

// Initialize a vote account using VoteInitV2
///
/// # Account references
/// 0. `[WRITE]` Uninitialized vote account
/// 1. `[]` Rent sysvar
/// 2. `[]` Clock sysvar
/// 3. `[SIGNER]` New validator identity (node_pubkey)
InitializeAccountV2(VoteInitV2),

/// Authorize a key to send votes or issue a withdrawal
///
/// # Account references
Expand Down Expand Up @@ -265,6 +274,22 @@ fn initialize_account(vote_pubkey: &Pubkey, vote_init: &VoteInit) -> Instruction
)
}

#[cfg(feature = "bincode")]
fn initialize_account_v2(vote_pubkey: &Pubkey, vote_init: &VoteInitV2) -> Instruction {
let account_metas = vec![
AccountMeta::new(*vote_pubkey, false),
AccountMeta::new_readonly(sysvar::rent::id(), false),
AccountMeta::new_readonly(sysvar::clock::id(), false),
AccountMeta::new_readonly(vote_init.node_pubkey, true),
];

Instruction::new_with_bincode(
id(),
&VoteInstruction::InitializeAccountV2(*vote_init),
account_metas,
)
}

pub struct CreateVoteAccountConfig<'a> {
pub space: u64,
pub with_seed: Option<(&'a Pubkey, &'a str)>,
Expand Down Expand Up @@ -311,6 +336,37 @@ pub fn create_account_with_config(
vec![create_ix, init_ix]
}

#[cfg(feature = "bincode")]
pub fn create_account_v2(
from_pubkey: &Pubkey,
vote_pubkey: &Pubkey,
vote_init: &VoteInitV2,
lamports: u64,
config: CreateVoteAccountConfig,
) -> Vec<Instruction> {
let create_ix = if let Some((base, seed)) = config.with_seed {
solana_system_interface::instruction::create_account_with_seed(
from_pubkey,
vote_pubkey,
base,
seed,
lamports,
config.space,
&id(),
)
} else {
solana_system_interface::instruction::create_account(
from_pubkey,
vote_pubkey,
lamports,
config.space,
&id(),
)
};
let init_ix = initialize_account_v2(vote_pubkey, vote_init);
vec![create_ix, init_ix]
}

#[cfg(feature = "bincode")]
pub fn authorize(
vote_pubkey: &Pubkey,
Expand Down
3 changes: 3 additions & 0 deletions vote-interface/src/state/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,9 @@ pub(crate) mod vote_state_deserialize;
/// Size of a BLS public key in a compressed point representation
pub const BLS_PUBLIC_KEY_COMPRESSED_SIZE: usize = 48;

/// Size of a BLS signature in a compressed point representation
pub const BLS_SIGNATURE_COMPRESSED_SIZE: usize = 96;

// 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;
Expand Down
53 changes: 50 additions & 3 deletions vote-interface/src/state/vote_instruction_data.rs
Original file line number Diff line number Diff line change
@@ -1,14 +1,19 @@
#[cfg(feature = "serde")]
use serde_derive::{Deserialize, Serialize};
#[cfg(feature = "frozen-abi")]
use solana_frozen_abi_macro::{frozen_abi, AbiExample};
use {
crate::state::{Lockout, MAX_LOCKOUT_HISTORY},
crate::state::{
Lockout, BLS_PUBLIC_KEY_COMPRESSED_SIZE, BLS_SIGNATURE_COMPRESSED_SIZE, MAX_LOCKOUT_HISTORY,
},
solana_clock::{Slot, UnixTimestamp},
solana_hash::Hash,
solana_pubkey::Pubkey,
std::{collections::VecDeque, fmt::Debug},
};
#[cfg(feature = "serde")]
use {
serde_derive::{Deserialize, Serialize},
serde_with::serde_as,
};

#[cfg_attr(
feature = "frozen-abi",
Expand Down Expand Up @@ -201,11 +206,53 @@ pub struct VoteInit {
pub commission: u8,
}

#[cfg_attr(feature = "serde", serde_as)]
#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
#[derive(Debug, PartialEq, Eq, Clone, Copy)]
pub struct VoteInitV2 {
pub node_pubkey: Pubkey,
pub authorized_voter: Pubkey,
#[cfg_attr(feature = "serde", serde(with = "serde_bytes"))]
pub authorized_voter_bls_pubkey: [u8; BLS_PUBLIC_KEY_COMPRESSED_SIZE],
#[cfg_attr(feature = "serde", serde(with = "serde_bytes"))]
pub authorized_voter_bls_proof_of_possession: [u8; BLS_SIGNATURE_COMPRESSED_SIZE],
pub authorized_withdrawer: Pubkey,
pub inflation_rewards_commission_bps: u16,
pub inflation_rewards_collector: Pubkey,
pub block_revenue_commission_bps: u16,
pub block_revenue_collector: Pubkey,
}

impl Default for VoteInitV2 {
fn default() -> Self {
Self {
node_pubkey: Pubkey::default(),
authorized_voter: Pubkey::default(),
authorized_voter_bls_pubkey: [0u8; BLS_PUBLIC_KEY_COMPRESSED_SIZE],
authorized_voter_bls_proof_of_possession: [0u8; BLS_SIGNATURE_COMPRESSED_SIZE],
authorized_withdrawer: Pubkey::default(),
inflation_rewards_commission_bps: 0,
inflation_rewards_collector: Pubkey::default(),
block_revenue_commission_bps: 0,
block_revenue_collector: Pubkey::default(),
}
}
}

#[cfg_attr(feature = "serde", serde_as)]
#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
#[derive(Debug, PartialEq, Eq, Clone, Copy)]
pub enum VoteAuthorize {
Voter,
Withdrawer,
VoterWithBLS(
// BLS public key
#[cfg_attr(feature = "serde", serde(with = "serde_bytes"))]
[u8; BLS_PUBLIC_KEY_COMPRESSED_SIZE],
// BLS Proof of Possession
#[cfg_attr(feature = "serde", serde(with = "serde_bytes"))]
[u8; BLS_SIGNATURE_COMPRESSED_SIZE],
),
}

#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
Expand Down
16 changes: 15 additions & 1 deletion vote-interface/src/state/vote_state_v4.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ use solana_frozen_abi_macro::{frozen_abi, AbiExample};
#[cfg(any(target_os = "solana", feature = "bincode"))]
use solana_instruction::error::InstructionError;
use {
super::{BlockTimestamp, LandedVote, VoteInit, BLS_PUBLIC_KEY_COMPRESSED_SIZE},
super::{BlockTimestamp, LandedVote, VoteInit, VoteInitV2, BLS_PUBLIC_KEY_COMPRESSED_SIZE},
crate::authorized_voters::AuthorizedVoters,
solana_clock::{Clock, Epoch, Slot},
solana_pubkey::Pubkey,
Expand Down Expand Up @@ -92,6 +92,20 @@ impl VoteStateV4 {
}
}

pub fn new_with_vote_init_v2(vote_init: &VoteInitV2, clock: &Clock) -> Self {
Self {
node_pubkey: vote_init.node_pubkey,
authorized_voters: AuthorizedVoters::new(clock.epoch, vote_init.authorized_voter),
bls_pubkey_compressed: Some(vote_init.authorized_voter_bls_pubkey),
authorized_withdrawer: vote_init.authorized_withdrawer,
inflation_rewards_commission_bps: vote_init.inflation_rewards_commission_bps,
inflation_rewards_collector: vote_init.inflation_rewards_collector,
block_revenue_commission_bps: vote_init.block_revenue_commission_bps,
block_revenue_collector: vote_init.block_revenue_collector,
..Self::default()
}
}

#[cfg(any(target_os = "solana", feature = "bincode"))]
pub fn deserialize(input: &[u8], vote_pubkey: &Pubkey) -> Result<Self, InstructionError> {
let mut vote_state = Self::default();
Expand Down