Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
10 changes: 6 additions & 4 deletions genesis/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,9 @@ use {
solana_rent::Rent,
solana_rpc_client::rpc_client::RpcClient,
solana_rpc_client_api::request::MAX_MULTIPLE_ACCOUNTS,
solana_runtime::genesis_utils::include_alpenglow_bpf_program,
solana_runtime::genesis_utils::{
bls_pubkey_to_compressed_bytes, include_alpenglow_bpf_program,
},
solana_sdk_ids::system_program,
solana_signer::Signer,
solana_stake_interface::state::StakeStateV2,
Expand Down Expand Up @@ -268,13 +270,13 @@ fn add_validator_accounts(
let bls_pubkey = bls_pubkeys_iter
.next()
.expect("Missing BLS pubkey for {identity_pubkey}");
AlpenglowVoteState::create_account_with_authorized(
vote_state::create_v4_account_with_authorized(
identity_pubkey,
identity_pubkey,
identity_pubkey,
commission,
Some(bls_pubkey_to_compressed_bytes(bls_pubkey)),
commission.into(),
AlpenglowVoteState::get_rent_exempt_reserve(rent).max(1),
*bls_pubkey,
)
} else {
vote_state::create_account_with_authorized(
Expand Down
45 changes: 28 additions & 17 deletions programs/stake/src/stake_state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,7 @@ use {
solana_rent::Rent,
solana_sdk_ids::stake::id,
solana_stake_interface::stake_flags::StakeFlags,
solana_vote_interface::state::VoteStateV3,
solana_votor_messages::state::VoteState as AlpenglowVoteState,
solana_vote_interface::state::{VoteStateV3, VoteStateV4},
};

// utility function, used by Stakes, tests
Expand Down Expand Up @@ -41,12 +40,7 @@ pub fn meta_from(account: &AccountSharedData) -> Option<Meta> {
from(account).and_then(|state: StakeStateV2| state.meta())
}

pub(crate) fn new_stake_with_credits(
stake: u64,
voter_pubkey: &Pubkey,
credits: u64,
activation_epoch: Epoch,
) -> Stake {
fn new_stake(stake: u64, voter_pubkey: &Pubkey, credits: u64, activation_epoch: Epoch) -> Stake {
Stake {
delegation: Delegation::new(voter_pubkey, stake, activation_epoch),
credits_observed: credits,
Expand Down Expand Up @@ -94,6 +88,25 @@ pub fn create_account(
rent,
lamports,
Epoch::MAX,
false,
)
}

pub fn create_alpenglow_account(
authorized: &Pubkey,
voter_pubkey: &Pubkey,
vote_account: &AccountSharedData,
rent: &Rent,
lamports: u64,
) -> AccountSharedData {
do_create_account(
authorized,
voter_pubkey,
vote_account,
rent,
lamports,
Epoch::MAX,
true,
)
}

Expand All @@ -104,18 +117,16 @@ fn do_create_account(
rent: &Rent,
lamports: u64,
activation_epoch: Epoch,
is_alpenglow: bool,
) -> AccountSharedData {
let mut stake_account = AccountSharedData::new(lamports, StakeStateV2::size_of(), &id());

let credits = if solana_votor_messages::check_id(vote_account.owner()) {
AlpenglowVoteState::deserialize(vote_account.data())
.expect("alpenglow_vote_state")
.epoch_credits()
.credits()
let credits = if is_alpenglow {
let vote_state_v4 = VoteStateV4::deserialize(vote_account.data(), voter_pubkey).unwrap();
vote_state_v4.epoch_credits.last().map_or(0, |(_, c, _)| *c)
} else {
VoteStateV3::deserialize(vote_account.data())
.expect("vote_state")
.credits()
let vote_state = VoteStateV3::deserialize(vote_account.data()).expect("vote_state");
vote_state.credits()
};

let rent_exempt_reserve = rent.minimum_balance(stake_account.data().len());
Expand All @@ -127,7 +138,7 @@ fn do_create_account(
rent_exempt_reserve,
..Meta::default()
},
new_stake_with_credits(
new_stake(
lamports - rent_exempt_reserve, // underflow is an error, is basically: assert!(lamports > rent_exempt_reserve);
voter_pubkey,
credits,
Expand Down
87 changes: 84 additions & 3 deletions programs/vote/src/vote_state/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ use {
solana_rent::Rent,
solana_slot_hashes::SlotHash,
solana_transaction_context::{BorrowedInstructionAccount, IndexOfAccount, InstructionContext},
solana_vote_interface::{error::VoteError, program::id},
solana_vote_interface::{authorized_voters::AuthorizedVoters, error::VoteError, program::id},
std::{
cmp::Ordering,
collections::{HashSet, VecDeque},
Expand Down Expand Up @@ -1044,6 +1044,51 @@ pub fn create_account_with_authorized(
vote_account
}

// TODO(wen): when we have VoteStateV4::new(), switch all users there.
pub fn new_v4_vote_state(
node_pubkey: &Pubkey,
authorized_voter: &Pubkey,
authorized_withdrawer: &Pubkey,
bls_pubkey_compressed: Option<[u8; BLS_PUBLIC_KEY_COMPRESSED_SIZE]>,
inflation_rewards_commission_bps: u16,
) -> VoteStateV4 {
VoteStateV4 {
node_pubkey: *node_pubkey,
authorized_voters: AuthorizedVoters::new(0, *authorized_voter),
authorized_withdrawer: *authorized_withdrawer,
bls_pubkey_compressed,
inflation_rewards_commission_bps,
..VoteStateV4::default()
}
}

pub fn create_v4_account_with_authorized(
node_pubkey: &Pubkey,
authorized_voter: &Pubkey,
authorized_withdrawer: &Pubkey,
bls_pubkey_compressed: Option<[u8; BLS_PUBLIC_KEY_COMPRESSED_SIZE]>,
inflation_rewards_commission_bps: u16,
lamports: u64,
) -> AccountSharedData {
let mut vote_account = AccountSharedData::new(lamports, VoteStateV4::size_of(), &id());

let vote_state = new_v4_vote_state(
node_pubkey,
authorized_voter,
authorized_withdrawer,
bls_pubkey_compressed,
inflation_rewards_commission_bps,
);

VoteStateV4::serialize(
&VoteStateVersions::V4(Box::new(vote_state)),
vote_account.data_as_mut_slice(),
)
.unwrap();

vote_account
}

// create_account() should be removed, use create_account_with_authorized() instead
pub fn create_account(
vote_pubkey: &Pubkey,
Expand Down Expand Up @@ -1084,7 +1129,7 @@ mod tests {

fn create_test_account() -> (Pubkey, RefCell<AccountSharedData>) {
let rent = Rent::default();
let balance = VoteStateV3::get_rent_exempt_reserve(&rent);
let balance = rent.minimum_balance(VoteStateV3::size_of());
let vote_pubkey = solana_pubkey::new_rand();
(
vote_pubkey,
Expand Down Expand Up @@ -1223,7 +1268,7 @@ mod tests {
// Test that when the feature is enabled, if the vote account does have sufficient lamports, the
// new vote state is written out
assert_eq!(
borrowed_account.set_lamports(rent.minimum_balance(VoteStateV3::size_of()),),
borrowed_account.set_lamports(rent.minimum_balance(VoteStateV3::size_of())),
Ok(())
);
assert_eq!(
Expand Down Expand Up @@ -3535,4 +3580,40 @@ mod tests {
expected_allowed
);
}

#[test]
fn test_create_v4_account_with_authorized() {
let node_pubkey = Pubkey::new_unique();
let authorized_voter = Pubkey::new_unique();
let authorized_withdrawer = Pubkey::new_unique();
let bls_pubkey_compressed = [42; 48];
let inflation_rewards_commission_bps = 10000;
let lamports = 100;
let vote_account = create_v4_account_with_authorized(
&node_pubkey,
&authorized_voter,
&authorized_withdrawer,
Some(bls_pubkey_compressed),
inflation_rewards_commission_bps,
lamports,
);
assert_eq!(vote_account.lamports(), lamports);
assert_eq!(vote_account.owner(), &id());
assert_eq!(vote_account.data().len(), VoteStateV4::size_of());
let vote_state_v4 = VoteStateV4::deserialize(vote_account.data(), &node_pubkey).unwrap();
assert_eq!(vote_state_v4.node_pubkey, node_pubkey);
assert_eq!(
vote_state_v4.authorized_voters,
AuthorizedVoters::new(0, authorized_voter)
);
assert_eq!(vote_state_v4.authorized_withdrawer, authorized_withdrawer);
assert_eq!(
vote_state_v4.bls_pubkey_compressed,
Some(bls_pubkey_compressed)
);
assert_eq!(
vote_state_v4.inflation_rewards_commission_bps,
inflation_rewards_commission_bps
);
}
}
3 changes: 1 addition & 2 deletions runtime/src/bank/serde_snapshot.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@ mod tests {
solana_pubkey::Pubkey,
solana_signer::Signer,
solana_vote::vote_account::VoteAccount,
solana_votor_messages::state::VoteState as AlpenglowVoteState,
std::{
collections::HashMap,
io::{BufReader, BufWriter, Cursor},
Expand Down Expand Up @@ -208,7 +207,7 @@ mod tests {
// Give some real stake distribution and generate real VersionedEpochStakes, to
// make sure bls_pubkey_to_rank_map is populated correctly after deserialize.
let vote_account = if is_alpenglow {
VoteAccount::new_from_alpenglow_vote_state(&AlpenglowVoteState::default())
VoteAccount::new_random_alpenglow()
} else {
VoteAccount::new_random()
};
Expand Down
19 changes: 13 additions & 6 deletions runtime/src/bank/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ use {
vote_instruction,
vote_state::{
self, create_account_with_authorized, BlockTimestamp, VoteAuthorize, VoteInit,
VoteStateV3, VoteStateVersions, MAX_LOCKOUT_HISTORY,
VoteStateV3, VoteStateV4, VoteStateVersions, MAX_LOCKOUT_HISTORY,
},
},
spl_generic_token::token,
Expand Down Expand Up @@ -731,13 +731,20 @@ where
// generate some rewards
if is_alpenglow {
let mut vote_state =
*solana_votor_messages::state::VoteState::deserialize(vote_account.data()).unwrap();
VoteStateV4::deserialize(vote_account.data(), &Pubkey::default()).unwrap();
vote_state.epoch_credits.push((0, 0, 0));
for _ in 0..MAX_LOCKOUT_HISTORY + 42 {
let mut epoch_credits = *vote_state.epoch_credits();
epoch_credits.set_credits(epoch_credits.credits() + 16);
vote_state.set_epoch_credits(epoch_credits);
vote_state.serialize_into(vote_account.data_as_mut_slice());
let (_, current_credits, _) = vote_state.epoch_credits.last_mut().unwrap();
*current_credits += 16;
let versioned = VoteStateVersions::V4(Box::new(vote_state.clone()));
vote_state::to(&versioned, &mut vote_account).unwrap();
bank0.store_account_and_update_capitalization(&vote_id, &vote_account);
match versioned {
VoteStateVersions::V4(v) => {
vote_state = *v;
}
_ => panic!("Has to be of type Current"),
};
}
} else {
let mut vote_state = Some(vote_state::from(&vote_account).unwrap());
Expand Down
Loading