Skip to content
This repository was archived by the owner on Jan 22, 2025. It is now read-only.
Closed
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
2 changes: 1 addition & 1 deletion cli/src/vote.rs
Original file line number Diff line number Diff line change
Expand Up @@ -433,7 +433,7 @@ pub fn process_show_vote_account(
build_balance_message(vote_account.lamports, use_lamports_unit, true)
);
println!("Validator Identity: {}", vote_state.node_pubkey);
println!("Authorized Voter: {}", vote_state.authorized_voter);
println!("Authorized Voter: {:?}", vote_state.authorized_voters());
println!(
"Authorized Withdrawer: {}",
vote_state.authorized_withdrawer
Expand Down
8 changes: 5 additions & 3 deletions core/src/commitment.rs
Original file line number Diff line number Diff line change
Expand Up @@ -233,7 +233,7 @@ mod tests {
use crate::genesis_utils::{create_genesis_config, GenesisConfigInfo};
use solana_sdk::pubkey::Pubkey;
use solana_stake_program::stake_state;
use solana_vote_program::vote_state;
use solana_vote_program::vote_state::{self, VoteStateVersions};

#[test]
fn test_block_commitment() {
Expand Down Expand Up @@ -446,13 +446,15 @@ mod tests {
let mut vote_state1 = VoteState::from(&vote_account1).unwrap();
vote_state1.process_slot_vote_unchecked(3);
vote_state1.process_slot_vote_unchecked(5);
vote_state1.to(&mut vote_account1).unwrap();
let versioned = VoteStateVersions::Current(Box::new(vote_state1));
VoteState::to(&versioned, &mut vote_account1).unwrap();
bank.store_account(&pk1, &vote_account1);

let mut vote_state2 = VoteState::from(&vote_account2).unwrap();
vote_state2.process_slot_vote_unchecked(9);
vote_state2.process_slot_vote_unchecked(10);
vote_state2.to(&mut vote_account2).unwrap();
let versioned = VoteStateVersions::Current(Box::new(vote_state2));
VoteState::to(&versioned, &mut vote_account2).unwrap();
bank.store_account(&pk2, &vote_account2);

let commitment = AggregateCommitmentService::aggregate_commitment(&ancestors, &bank);
Expand Down
13 changes: 9 additions & 4 deletions core/src/consensus.rs
Original file line number Diff line number Diff line change
Expand Up @@ -484,7 +484,10 @@ pub mod test {
signature::{Keypair, Signer},
transaction::Transaction,
};
use solana_vote_program::{vote_instruction, vote_state::Vote};
use solana_vote_program::{
vote_instruction,
vote_state::{Vote, VoteStateVersions},
};
use std::collections::{HashMap, VecDeque};
use std::sync::RwLock;
use std::{thread::sleep, time::Duration};
Expand Down Expand Up @@ -707,9 +710,11 @@ pub mod test {
for slot in *votes {
vote_state.process_slot_vote_unchecked(*slot);
}
vote_state
.serialize(&mut account.data)
.expect("serialize state");
VoteState::serialize(
&VoteStateVersions::Current(Box::new(vote_state)),
&mut account.data,
)
.expect("serialize state");
stakes.push((Pubkey::new_rand(), (*lamports, account)));
}
stakes
Expand Down
8 changes: 5 additions & 3 deletions core/src/replay_stage.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1087,7 +1087,7 @@ pub(crate) mod tests {
transaction::TransactionError,
};
use solana_stake_program::stake_state;
use solana_vote_program::vote_state::{self, Vote, VoteState};
use solana_vote_program::vote_state::{self, Vote, VoteState, VoteStateVersions};
use std::{
fs::remove_dir_all,
iter,
Expand Down Expand Up @@ -1122,7 +1122,8 @@ pub(crate) mod tests {
let mut vote_account = bank.get_account(&pubkey).unwrap();
let mut vote_state = VoteState::from(&vote_account).unwrap();
vote_state.process_slot_vote_unchecked(slot);
vote_state.to(&mut vote_account).unwrap();
let versioned = VoteStateVersions::Current(Box::new(vote_state));
VoteState::to(&versioned, &mut vote_account).unwrap();
bank.store_account(&pubkey, &vote_account);
}

Expand Down Expand Up @@ -1706,7 +1707,8 @@ pub(crate) mod tests {
let mut leader_vote_account = bank.get_account(&pubkey).unwrap();
let mut vote_state = VoteState::from(&leader_vote_account).unwrap();
vote_state.process_slot_vote_unchecked(bank.slot());
vote_state.to(&mut leader_vote_account).unwrap();
let versioned = VoteStateVersions::Current(Box::new(vote_state));
VoteState::to(&versioned, &mut leader_vote_account).unwrap();
bank.store_account(&pubkey, &leader_vote_account);
}

Expand Down
153 changes: 152 additions & 1 deletion ledger-tool/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,18 @@ use solana_ledger::{
shred_version::compute_shred_version,
snapshot_utils,
};
use solana_runtime::bank::Bank;
use solana_sdk::{
clock::Slot, genesis_config::GenesisConfig, native_token::lamports_to_sol,
program_utils::limited_deserialize, pubkey::Pubkey,
};
use solana_vote_program::vote_state::VoteState;
use solana_vote_program::{
self,
vote_state::{VoteState, VoteStateVersions},
};

use std::{
boxed::Box,
collections::{BTreeMap, HashMap, HashSet},
ffi::OsStr,
fs::{self, File},
Expand Down Expand Up @@ -524,6 +530,21 @@ fn hardforks_of(matches: &ArgMatches<'_>, name: &str) -> Option<Vec<Slot>> {
}
}

fn load_bank_from_snapshot(arg_matches: &ArgMatches, ledger_path: &PathBuf) -> Bank {
let snapshot_config = SnapshotConfig {
snapshot_interval_slots: 0, // Value doesn't matter
snapshot_package_output_path: ledger_path.clone(),
snapshot_path: ledger_path.clone().join("snapshot"),
};
let account_paths = if let Some(account_paths) = arg_matches.value_of("account_paths") {
account_paths.split(',').map(PathBuf::from).collect()
} else {
vec![ledger_path.join("accounts")]
};

bank_forks_utils::load_bank_from_archive(account_paths, &snapshot_config)
}

fn load_bank_forks(
arg_matches: &ArgMatches,
ledger_path: &PathBuf,
Expand Down Expand Up @@ -692,6 +713,27 @@ fn main() {
.takes_value(true)
.help("Output directory for the snapshot"),
)
).subcommand(
SubCommand::with_name("verify-snapshot")
.about("Convert accounts in snapshot")
.arg(&no_snapshot_arg)
.arg(&account_paths_arg)
.arg(&halt_at_slot_arg)
.arg(&hard_forks_arg)
).subcommand(
SubCommand::with_name("convert-accounts")
.about("Convert accounts in snapshot")
.arg(&no_snapshot_arg)
.arg(&account_paths_arg)
.arg(&halt_at_slot_arg)
.arg(&hard_forks_arg)
.arg(
Arg::with_name("output_directory")
.index(1)
.value_name("DIR")
.takes_value(true)
.help("Output directory for the snapshot"),
)
).subcommand(
SubCommand::with_name("print-accounts")
.about("Print account contents after processing in the ledger")
Expand Down Expand Up @@ -942,6 +984,115 @@ fn main() {
}
}
}
("verify-snapshot", Some(arg_matches)) => {
load_bank_from_snapshot(arg_matches, &ledger_path);
}
("convert-accounts", Some(arg_matches)) => {
let output_directory = value_t_or_exit!(arg_matches, "output_directory", String);
let genesis_config = open_genesis_config(&ledger_path);
let mut root_bank = load_bank_from_snapshot(arg_matches, &ledger_path);
// Convert root_bank.EpochStakes
for (_, stakes) in root_bank.epoch_stakes.iter_mut() {
for (pubkey, (_, vote_account)) in stakes.vote_accounts.iter_mut() {
VoteStateVersions::convert_from_raw(vote_account, &pubkey);
}
}

for (pubkey, (_, vote_account)) in
root_bank.stakes.write().unwrap().vote_accounts.iter_mut()
{
VoteStateVersions::convert_from_raw(vote_account, &pubkey);
}

let index: Vec<_> = {
let index = root_bank
.rc
.accounts
.accounts_db
.accounts_index
.read()
.unwrap();

// Write out the new accounts
let total: usize = index
.account_maps
.values()
.map(|slot_list| slot_list.read().unwrap().len())
.sum();

println!("Converting {} accounts", total);
index
.account_maps
.iter()
.map(|(pubkey, slot_list)| (*pubkey, slot_list.read().unwrap().clone()))
.collect()
};

for (pubkey, slot_list) in index.iter() {
for (slot, _) in slot_list.iter() {
let ancestors = vec![(*slot, 1)].into_iter().collect();
let res = root_bank.rc.accounts.load_slow(&ancestors, pubkey);

if let Some((mut account, _)) = res {
if account.owner == solana_vote_program::id() {
VoteStateVersions::convert_from_raw(&mut account, pubkey);
root_bank.rc.accounts.store_slow(*slot, pubkey, &account);
(*slot, pubkey, &account);
}
}
}
}

// Update the bank hash
println!("Updating bank hash");
root_bank
.rc
.accounts
.accounts_db
.recompute_bank_hash(root_bank.slot())
.expect("Failed to recompute bank hash");

root_bank.recompute_hash();

let temp_dir = tempfile::TempDir::new().unwrap_or_else(|err| {
eprintln!("Unable to create temporary directory: {}", err);
exit(1);
});

let storages: Vec<_> = root_bank.get_snapshot_storages();
snapshot_utils::add_snapshot(&temp_dir, &root_bank, &storages)
.and_then(|slot_snapshot_paths| {
snapshot_utils::package_snapshot(
&root_bank,
&slot_snapshot_paths,
snapshot_utils::get_snapshot_archive_path(output_directory),
&temp_dir,
&root_bank.src.roots(),
storages,
)
})
.and_then(|package| {
snapshot_utils::archive_snapshot_package(&package).map(|ok| {
println!(
"Successfully created snapshot for slot {}: {:?}",
root_bank.slot(),
package.tar_output_file
);
println!(
"Shred version: {}",
compute_shred_version(
&genesis_config.hash(),
Some(&root_bank.hard_forks().read().unwrap())
)
);
ok
})
})
.unwrap_or_else(|err| {
eprintln!("Unable to create snapshot archive: {}", err);
exit(1);
});
}
("print-accounts", Some(arg_matches)) => {
let dev_halt_at_slot = value_t!(arg_matches, "halt_at_slot", Slot).ok();
let process_options = ProcessOptions {
Expand Down
4 changes: 4 additions & 0 deletions ledger/src/bank_forks.rs
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,10 @@ impl BankForks {
self.banks.get(&bank_slot)
}

pub fn remove(&mut self, bank_slot: Slot) -> Arc<Bank> {
self.banks.remove(&bank_slot).unwrap()
}

pub fn new_from_banks(initial_forks: &[Arc<Bank>], rooted_path: Vec<Slot>) -> Self {
let mut banks = HashMap::new();
let working_bank = initial_forks[0].clone();
Expand Down
10 changes: 10 additions & 0 deletions ledger/src/bank_forks_utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ use crate::{
snapshot_utils,
};
use log::*;
use solana_runtime::bank::Bank;
use solana_sdk::{clock::Slot, genesis_config::GenesisConfig, hash::Hash};
use std::{fs, path::PathBuf, result, sync::Arc};

Expand Down Expand Up @@ -36,6 +37,15 @@ fn to_loadresult(
})
}

pub fn load_bank_from_archive(
account_paths: Vec<PathBuf>,
snapshot_config: &SnapshotConfig,
) -> Bank {
let tar =
snapshot_utils::get_snapshot_archive_path(&snapshot_config.snapshot_package_output_path);
snapshot_utils::bank_from_archive(&account_paths, &snapshot_config.snapshot_path, &tar).unwrap()
}

pub fn load(
genesis_config: &GenesisConfig,
blockstore: &Blockstore,
Expand Down
10 changes: 1 addition & 9 deletions ledger/src/snapshot_utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -556,15 +556,7 @@ where
&root_paths.snapshot_file_path,
MAX_SNAPSHOT_DATA_FILE_SIZE,
|stream| {
let mut bank: Bank = match snapshot_version {
env!("CARGO_PKG_VERSION") => deserialize_from_snapshot(stream.by_ref())?,
_ => {
return Err(get_io_error(&format!(
"unsupported snapshot version: {}",
snapshot_version
)));
}
};
let mut bank: Bank = deserialize_from_snapshot(stream.by_ref())?;
info!("Rebuilding accounts...");
bank.set_bank_rc(
bank::BankRc::new(account_paths.to_vec(), 0, bank.slot()),
Expand Down
9 changes: 5 additions & 4 deletions programs/stake/src/stake_state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ use solana_sdk::{
rent::Rent,
stake_history::{StakeHistory, StakeHistoryEntry},
};
use solana_vote_program::vote_state::VoteState;
use solana_vote_program::vote_state::{VoteState, VoteStateVersions};
use std::collections::HashSet;

#[derive(Debug, Serialize, Deserialize, PartialEq, Clone, Copy)]
Expand Down Expand Up @@ -595,7 +595,7 @@ impl<'a> StakeAccount for KeyedAccount<'a> {
let stake = Stake::new(
self.lamports()?.saturating_sub(meta.rent_exempt_reserve), // can't stake the rent ;)
vote_account.unsigned_key(),
&vote_account.state()?,
&State::<VoteStateVersions>::state(vote_account)?.convert_to_current(),
clock.epoch,
config,
);
Expand All @@ -605,7 +605,7 @@ impl<'a> StakeAccount for KeyedAccount<'a> {
meta.authorized.check(signers, StakeAuthorize::Staker)?;
stake.redelegate(
vote_account.unsigned_key(),
&vote_account.state()?,
&State::<VoteStateVersions>::state(vote_account)?.convert_to_current(),
clock,
stake_history,
config,
Expand Down Expand Up @@ -778,7 +778,8 @@ pub fn redeem_rewards(
stake_history: Option<&StakeHistory>,
) -> Result<(u64, u64), InstructionError> {
if let StakeState::Stake(meta, mut stake) = stake_account.state()? {
let vote_state = vote_account.state()?;
let vote_state: VoteState =
StateMut::<VoteStateVersions>::state(vote_account)?.convert_to_current();

if let Some((voters_reward, stakers_reward)) =
stake.redeem_rewards(point_value, &vote_state, stake_history)
Expand Down
Loading