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
64 changes: 43 additions & 21 deletions runtime/src/bank/serde_snapshot.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,7 @@ mod tests {
use {
crate::{
bank::{test_utils as bank_test_utils, Bank},
epoch_stakes::{
BLSPubkeyToRankMap, EpochAuthorizedVoters, NodeIdToVoteAccounts,
VersionedEpochStakes,
},
epoch_stakes::VersionedEpochStakes,
genesis_utils::activate_all_features,
runtime_config::RuntimeConfig,
serde_snapshot::{self, ExtraFieldsToSerialize, SnapshotStreams},
Expand All @@ -16,7 +13,6 @@ mod tests {
create_tmp_accounts_dir_for_tests, get_storages_to_serialize,
StorageAndNextAccountsFileId,
},
stakes::{SerdeStakesToStakeFormat, Stakes},
},
solana_accounts_db::{
account_storage::AccountStorageMap,
Expand All @@ -30,8 +26,11 @@ mod tests {
solana_genesis_config::create_genesis_config,
solana_nohash_hasher::BuildNoHashHasher,
solana_pubkey::Pubkey,
solana_stake_interface::state::Stake,
solana_signer::Signer,
solana_vote::vote_account::VoteAccount,
solana_votor_messages::state::VoteState as AlpenglowVoteState,
std::{
collections::HashMap,
io::{BufReader, BufWriter, Cursor},
mem,
ops::RangeFull,
Expand Down Expand Up @@ -186,33 +185,38 @@ mod tests {
bank.flush_accounts_cache_slot_for_tests()
}

#[test_case(StorageAccess::Mmap)]
#[test_case(StorageAccess::File)]
fn test_extra_fields_eof(storage_access: StorageAccess) {
#[test_case(StorageAccess::Mmap, false)]
#[test_case(StorageAccess::File, false)]
#[test_case(StorageAccess::Mmap, true)]
#[test_case(StorageAccess::File, true)]
fn test_extra_fields_eof(storage_access: StorageAccess, is_alpenglow: bool) {
solana_logger::setup();
let (genesis_config, _) = create_genesis_config(500);
let (genesis_config, keypair) = create_genesis_config(500);

let bank0 = Arc::new(Bank::new_for_tests(&genesis_config));
bank0.squash();
let mut bank = Bank::new_from_parent(bank0.clone(), &Pubkey::default(), 1);
bank.freeze();
add_root_and_flush_write_cache(&bank0);

let epoch_with_real_stake = 42;

// Set extra fields
bank.fee_rate_governor.lamports_per_signature = 7000;
// Note that epoch_stakes already has two epoch stakes entries for epochs 0 and 1
// which will also be serialized to the versioned epoch stakes extra field. Those
// entries are of type Stakes<StakeAccount> so add a new entry for Stakes<Stake>.
bank.epoch_stakes.insert(
42,
VersionedEpochStakes::Current {
stakes: SerdeStakesToStakeFormat::Stake(Stakes::<Stake>::default()),
total_stake: 42,
node_id_to_vote_accounts: Arc::<NodeIdToVoteAccounts>::default(),
epoch_authorized_voters: Arc::<EpochAuthorizedVoters>::default(),
bls_pubkey_to_rank_map: Arc::new(BLSPubkeyToRankMap::default()),
},
);
// 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())
} else {
VoteAccount::new_random()
};
let vote_accounts_hash_map = HashMap::from([(keypair.pubkey(), (100, vote_account))]);
let stakes =
VersionedEpochStakes::new_for_tests(vote_accounts_hash_map, epoch_with_real_stake);
bank.epoch_stakes.insert(epoch_with_real_stake, stakes);
assert_eq!(bank.epoch_stakes.len(), 3);

// Serialize
Expand Down Expand Up @@ -258,6 +262,24 @@ mod tests {
)
.unwrap();

// Specifically check that bls_pubkey_rank_map is equal, you do need to call this
// before checking epoch_stakes because this needs to be populated.
for (epoch, epoch_stakes) in dbank.epoch_stakes.iter() {
let bls_pubkey_to_rank_map = epoch_stakes.bls_pubkey_to_rank_map();
if is_alpenglow && *epoch == epoch_with_real_stake {
assert!(!bls_pubkey_to_rank_map.is_empty());
} else {
assert!(bls_pubkey_to_rank_map.is_empty());
}
assert_eq!(
bls_pubkey_to_rank_map,
bank.epoch_stakes
.get(epoch)
.expect("Expecting epoch stakes for {epoch}")
.bls_pubkey_to_rank_map()
);
}

assert_eq!(bank.epoch_stakes, dbank.epoch_stakes);
assert_eq!(
bank.fee_rate_governor.lamports_per_signature,
Expand Down Expand Up @@ -356,7 +378,7 @@ mod tests {
#[cfg_attr(
feature = "frozen-abi",
derive(AbiExample),
frozen_abi(digest = "DDFYjSvRswgrMu7pcPzjvThUviKV8ELyAmxkQuhT9hGc")
frozen_abi(digest = "4zSePLuo5DnagjcFySpN2xSmQ1JqYmbQm59vfjS7qKpc")
)]
#[derive(Serialize)]
pub struct BankAbiTestWrapper {
Expand Down
19 changes: 13 additions & 6 deletions runtime/src/epoch_stakes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,17 @@ use {
solana_clock::Epoch,
solana_pubkey::Pubkey,
solana_vote::vote_account::VoteAccountsHashMap,
std::{collections::HashMap, sync::Arc},
std::{
collections::HashMap,
sync::{Arc, OnceLock},
},
};

pub type NodeIdToVoteAccounts = HashMap<Pubkey, NodeVoteAccounts>;
pub type EpochAuthorizedVoters = HashMap<Pubkey, Pubkey>;
pub type SortedPubkeys = Vec<(Pubkey, BLSPubkey)>;

#[derive(Clone, Debug, Serialize, Deserialize, Default)]
#[derive(Clone, Debug, Default)]
#[cfg_attr(feature = "frozen-abi", derive(AbiExample))]
Comment thread
bw-solana marked this conversation as resolved.
#[cfg_attr(feature = "dev-context-only-utils", derive(PartialEq))]
pub struct BLSPubkeyToRankMap {
Expand Down Expand Up @@ -84,7 +87,8 @@ pub enum VersionedEpochStakes {
total_stake: u64,
node_id_to_vote_accounts: Arc<NodeIdToVoteAccounts>,
epoch_authorized_voters: Arc<EpochAuthorizedVoters>,
bls_pubkey_to_rank_map: Arc<BLSPubkeyToRankMap>,
#[serde(skip)]
bls_pubkey_to_rank_map: OnceLock<Arc<BLSPubkeyToRankMap>>,
},
}

Expand All @@ -93,13 +97,12 @@ impl VersionedEpochStakes {
let epoch_vote_accounts = stakes.vote_accounts();
let (total_stake, node_id_to_vote_accounts, epoch_authorized_voters) =
Self::parse_epoch_vote_accounts(epoch_vote_accounts.as_ref(), leader_schedule_epoch);
let bls_pubkey_to_rank_map = BLSPubkeyToRankMap::new(epoch_vote_accounts.as_ref());
Self::Current {
stakes,
total_stake,
node_id_to_vote_accounts: Arc::new(node_id_to_vote_accounts),
epoch_authorized_voters: Arc::new(epoch_authorized_voters),
bls_pubkey_to_rank_map: Arc::new(bls_pubkey_to_rank_map),
bls_pubkey_to_rank_map: OnceLock::new(),
}
}

Expand Down Expand Up @@ -171,7 +174,11 @@ impl VersionedEpochStakes {
Self::Current {
bls_pubkey_to_rank_map,
..
} => bls_pubkey_to_rank_map,
} => bls_pubkey_to_rank_map.get_or_init(|| {
Arc::new(BLSPubkeyToRankMap::new(
self.stakes().vote_accounts().as_ref(),
))
}),
}
}

Expand Down