diff --git a/core/src/validator.rs b/core/src/validator.rs index 5ffc1e1276..66bba74614 100644 --- a/core/src/validator.rs +++ b/core/src/validator.rs @@ -672,9 +672,13 @@ fn new_banks_from_ledger( TransactionHistoryServices::default() }; + // TODO: Add evm-state to config. + let evm_state_path = ledger_path.join("evm-state"); + let (mut bank_forks, mut leader_schedule_cache, snapshot_hash) = bank_forks_utils::load( &genesis_config, &blockstore, + evm_state_path, config.account_paths.clone(), config.snapshot_config.as_ref(), process_options, diff --git a/core/tests/bank_forks.rs b/core/tests/bank_forks.rs index a528376669..9639304c9e 100644 --- a/core/tests/bank_forks.rs +++ b/core/tests/bank_forks.rs @@ -65,6 +65,7 @@ mod tests { DEFINE_SNAPSHOT_VERSION_PARAMETERIZED_TEST_FUNCTIONS!(V1_2_0, MainnetBeta, V1_2_0_MainnetBeta); struct SnapshotTestConfig { + evm_state_dir: TempDir, accounts_dir: TempDir, snapshot_dir: TempDir, _snapshot_output_path: TempDir, @@ -79,6 +80,7 @@ mod tests { cluster_type: ClusterType, snapshot_interval_slots: u64, ) -> SnapshotTestConfig { + let evm_state_dir = TempDir::new().unwrap(); let accounts_dir = TempDir::new().unwrap(); let snapshot_dir = TempDir::new().unwrap(); let snapshot_output_path = TempDir::new().unwrap(); @@ -102,6 +104,7 @@ mod tests { }; bank_forks.set_snapshot_config(Some(snapshot_config.clone())); SnapshotTestConfig { + evm_state_dir, accounts_dir, snapshot_dir, _snapshot_output_path: snapshot_output_path, @@ -116,6 +119,7 @@ mod tests { old_bank_forks: &BankForks, old_last_slot: Slot, old_genesis_config: &GenesisConfig, + evm_state_path: &Path, account_paths: &[PathBuf], ) { let (snapshot_path, snapshot_package_output_path) = old_bank_forks @@ -127,6 +131,7 @@ mod tests { let old_last_bank = old_bank_forks.get(old_last_slot).unwrap(); let deserialized_bank = snapshot_utils::bank_from_archive( + evm_state_path, &account_paths, &[], &old_bank_forks @@ -213,9 +218,16 @@ mod tests { snapshot_utils::archive_snapshot_package(&snapshot_package).unwrap(); // Restore bank from snapshot + let evm_state_path = snapshot_test_config.evm_state_dir.path(); let account_paths = &[snapshot_test_config.accounts_dir.path().to_path_buf()]; let genesis_config = &snapshot_test_config.genesis_config_info.genesis_config; - restore_from_snapshot(bank_forks, last_slot, genesis_config, account_paths); + restore_from_snapshot( + evm_state_path, + bank_forks, + last_slot, + genesis_config, + account_paths, + ); } fn run_test_bank_forks_snapshot_n( diff --git a/evm-utils/evm-state/src/layered_backend.rs b/evm-utils/evm-state/src/layered_backend.rs index 88cbf4c77a..7b3911b87c 100644 --- a/evm-utils/evm-state/src/layered_backend.rs +++ b/evm-utils/evm-state/src/layered_backend.rs @@ -143,7 +143,7 @@ pub struct EvmState { impl Default for EvmState { fn default() -> Self { let path = std::env::temp_dir().join("evm-state"); - Self::load_from(path, Slot::default()).expect("Unable to instantiate default EVM state") + Self::new(path).expect("Unable to instantiate default EVM state") } } @@ -260,6 +260,11 @@ impl EvmState { } impl EvmState { + pub fn new>(path: P) -> Result { + //TODO: add flags, to asserts for empty storage. + Self::load_from(path, 0) + } + pub fn load_from>(path: P, slot: Slot) -> Result { info!( "open evm state storage {} for slot {}", diff --git a/evm-utils/evm-state/src/storage.rs b/evm-utils/evm-state/src/storage.rs index 7bdc4d8b6f..5b3d9a0d1f 100644 --- a/evm-utils/evm-state/src/storage.rs +++ b/evm-utils/evm-state/src/storage.rs @@ -117,6 +117,9 @@ where self.db.put(key, value)?; } Some(data) => { + warn!("Found confict previous: previous = {:?}, version = {:?}, previous_in_db = {:?}", previous, + version, + CODER.deserialize::>(&data).typed_ctx() ); // TODO: assert or do some check // assert_eq!( // previous, diff --git a/ledger-tool/src/main.rs b/ledger-tool/src/main.rs index 3ad267ec04..332493cb6c 100644 --- a/ledger-tool/src/main.rs +++ b/ledger-tool/src/main.rs @@ -691,9 +691,12 @@ fn load_bank_forks( vec![non_primary_accounts_path] }; + let evm_state_path = ledger_path.join("evm-state"); + bank_forks_utils::load( &genesis_config, &blockstore, + evm_state_path, account_paths, snapshot_config.as_ref(), process_options, diff --git a/ledger/src/bank_forks_utils.rs b/ledger/src/bank_forks_utils.rs index 4002b7898d..9b211793c7 100644 --- a/ledger/src/bank_forks_utils.rs +++ b/ledger/src/bank_forks_utils.rs @@ -32,6 +32,7 @@ fn to_loadresult( pub fn load( genesis_config: &GenesisConfig, blockstore: &Blockstore, + evm_state_path: PathBuf, account_paths: Vec, snapshot_config: Option<&SnapshotConfig>, process_options: ProcessOptions, @@ -59,6 +60,7 @@ pub fn load( } let deserialized_bank = snapshot_utils::bank_from_archive( + &evm_state_path, &account_paths, &process_options.frozen_accounts, &snapshot_config.snapshot_path, @@ -104,6 +106,7 @@ pub fn load( blockstore_processor::process_blockstore( &genesis_config, &blockstore, + &evm_state_path, account_paths, process_options, ), diff --git a/ledger/src/blockstore_processor.rs b/ledger/src/blockstore_processor.rs index e72721d280..9b0afff3ba 100644 --- a/ledger/src/blockstore_processor.rs +++ b/ledger/src/blockstore_processor.rs @@ -36,7 +36,7 @@ use solana_vote_program::vote_state::VoteState; use std::{ cell::RefCell, collections::{BTreeMap, HashMap}, - path::PathBuf, + path::{Path, PathBuf}, result, sync::Arc, time::{Duration, Instant}, @@ -320,6 +320,7 @@ fn initiate_callback(mut bank: &mut Arc, genesis_config: &GenesisConfig) { pub fn process_blockstore( genesis_config: &GenesisConfig, blockstore: &Blockstore, + evm_state_path: &Path, account_paths: Vec, opts: ProcessOptions, ) -> BlockstoreProcessorResult { @@ -335,6 +336,7 @@ pub fn process_blockstore( // Setup bank for slot 0 let mut bank0 = Arc::new(Bank::new_with_paths( &genesis_config, + Some(evm_state_path), account_paths, &opts.frozen_accounts, )); diff --git a/runtime/src/bank.rs b/runtime/src/bank.rs index 0673787ce5..97eead34b7 100644 --- a/runtime/src/bank.rs +++ b/runtime/src/bank.rs @@ -66,7 +66,7 @@ use std::{ convert::TryFrom, mem, ops::RangeInclusive, - path::PathBuf, + path::{Path, PathBuf}, ptr, rc::Rc, sync::atomic::{AtomicBool, AtomicU64, Ordering}, @@ -96,9 +96,6 @@ pub mod inline_spl_token_v2_0 { } } -// TODO: get real path from extern configuration -pub const EVM_STATE_STORAGE: &str = "/tmp/solana/evm-state"; - pub const SECONDS_PER_YEAR: f64 = 365.25 * 24.0 * 60.0 * 60.0; pub const MAX_LEADER_SCHEDULE_STAKES: Epoch = 5; @@ -473,11 +470,12 @@ impl Default for BlockhashQueue { impl Bank { pub fn new(genesis_config: &GenesisConfig) -> Self { - Self::new_with_paths(&genesis_config, Vec::new(), &[]) + Self::new_with_paths(&genesis_config, None, Vec::new(), &[]) } pub fn new_with_paths( genesis_config: &GenesisConfig, + evm_state_path: Option<&Path>, // TODO: Remove option, currently need for Bank::new, that is used for tests paths: Vec, frozen_account_pubkeys: &[Pubkey], ) -> Self { @@ -486,6 +484,9 @@ impl Bank { bank.ancestors.insert(bank.slot(), 0); bank.rc.accounts = Arc::new(Accounts::new(paths, &genesis_config.cluster_type)); + if let Some(evm_state_path) = evm_state_path { + bank.evm_state = RwLock::new(evm_state::EvmState::new(evm_state_path).unwrap()); + } bank.process_genesis_config(genesis_config); bank.finish_init(genesis_config); @@ -640,6 +641,7 @@ impl Bank { /// Create a bank from explicit arguments and deserialized fields from snapshot #[allow(clippy::float_cmp)] pub(crate) fn new_from_fields( + evm_state: evm_state::EvmState, bank_rc: BankRc, genesis_config: &GenesisConfig, fields: BankFieldsToDeserialize, @@ -648,9 +650,6 @@ impl Bank { T::default() } - let evm_state = evm_state::EvmState::load_from(EVM_STATE_STORAGE, fields.slot) - .expect("Unable to open EVM state storage"); - let mut bank = Self { rc: bank_rc, src: new(), diff --git a/runtime/src/serde_snapshot.rs b/runtime/src/serde_snapshot.rs index 39054414ea..848889c910 100644 --- a/runtime/src/serde_snapshot.rs +++ b/runtime/src/serde_snapshot.rs @@ -121,6 +121,7 @@ pub(crate) fn bank_from_stream( serde_style: SerdeStyle, stream: &mut BufReader, append_vecs_path: P, + evm_state_path: &Path, account_paths: &[PathBuf], genesis_config: &GenesisConfig, frozen_account_pubkeys: &[Pubkey], @@ -138,6 +139,7 @@ where accounts_db_fields, genesis_config, frozen_account_pubkeys, + evm_state_path, account_paths, append_vecs_path, )?; @@ -222,6 +224,7 @@ fn reconstruct_bank_from_fields( accounts_db_fields: AccountsDbFields, genesis_config: &GenesisConfig, frozen_account_pubkeys: &[Pubkey], + evm_state_path: &Path, account_paths: &[PathBuf], append_vecs_path: P, ) -> Result @@ -238,7 +241,9 @@ where accounts_db.freeze_accounts(&bank_fields.ancestors, frozen_account_pubkeys); let bank_rc = BankRc::new(Accounts::new_empty(accounts_db), bank_fields.slot); - let bank = Bank::new_from_fields(bank_rc, genesis_config, bank_fields); + let evm_state = evm_state::EvmState::load_from(evm_state_path, bank_fields.slot) + .expect("Unable to open EVM state storage"); + let bank = Bank::new_from_fields(evm_state, bank_rc, genesis_config, bank_fields); Ok(bank) } diff --git a/runtime/src/serde_snapshot/tests.rs b/runtime/src/serde_snapshot/tests.rs index ee21da53ac..dc1bf77781 100644 --- a/runtime/src/serde_snapshot/tests.rs +++ b/runtime/src/serde_snapshot/tests.rs @@ -197,6 +197,7 @@ fn test_bank_serialize_style(serde_style: SerdeStyle) { let rdr = Cursor::new(&buf[..]); let mut reader = std::io::BufReader::new(&buf[rdr.position() as usize..]); + let evm_state_dir = TempDir::new().unwrap(); // Create a new set of directories for this bank's accounts let (_accounts_dir, dbank_paths) = get_temp_accounts_paths(4).unwrap(); let ref_sc = StatusCacheRc::default(); @@ -208,6 +209,7 @@ fn test_bank_serialize_style(serde_style: SerdeStyle) { serde_style, &mut reader, copied_accounts.path(), + &evm_state_dir.path(), &dbank_paths, &genesis_config, &[], diff --git a/runtime/src/snapshot_utils.rs b/runtime/src/snapshot_utils.rs index 53d073d606..88231b8977 100644 --- a/runtime/src/snapshot_utils.rs +++ b/runtime/src/snapshot_utils.rs @@ -1,5 +1,5 @@ use crate::{ - bank::{Bank, BankSlotDelta, EVM_STATE_STORAGE}, + bank::{Bank, BankSlotDelta}, bank_forks::CompressionType, hardened_unpack::{unpack_snapshot, UnpackError}, serde_snapshot::{ @@ -599,6 +599,7 @@ pub fn remove_snapshot>(slot: Slot, snapshot_path: P) -> Result<( } pub fn bank_from_archive>( + evm_state_path: &Path, account_paths: &[PathBuf], frozen_account_pubkeys: &[Pubkey], snapshot_path: &PathBuf, @@ -620,6 +621,7 @@ pub fn bank_from_archive>( let bank = rebuild_bank_from_snapshots( snapshot_version.trim(), + evm_state_path, account_paths, frozen_account_pubkeys, &unpacked_snapshots_dir, @@ -777,6 +779,7 @@ pub fn untar_snapshot_in, Q: AsRef>( fn rebuild_bank_from_snapshots

( snapshot_version: &str, + evm_state_path: &Path, account_paths: &[PathBuf], frozen_account_pubkeys: &[Pubkey], unpacked_snapshots_dir: &PathBuf, @@ -808,7 +811,7 @@ where root_paths.evm_state_backup_path ); let mut measure = Measure::start("evm state database restore"); - evm_state::Storage::restore_from(root_paths.evm_state_backup_path, EVM_STATE_STORAGE) + evm_state::Storage::restore_from(root_paths.evm_state_backup_path, evm_state_path) .expect("Unable to restore EVM state underlying database from storage backup"); measure.stop(); info!("{}", measure); @@ -820,6 +823,7 @@ where SerdeStyle::NEWER, &mut stream, &append_vecs_path, + evm_state_path, account_paths, genesis_config, frozen_account_pubkeys,