2020-05-22 10:54:24 -07:00
use {
crate ::{
accounts ::Accounts ,
2021-06-09 21:21:32 -07:00
accounts_db ::{
2021-09-07 21:30:38 -07:00
AccountShrinkThreshold , AccountStorageEntry , AccountsDb , AccountsDbConfig , AppendVecId ,
BankHashInfo ,
2021-06-09 21:21:32 -07:00
} ,
2021-09-07 21:30:38 -07:00
accounts_index ::AccountSecondaryIndexes ,
2021-09-30 14:26:17 -07:00
accounts_update_notifier_interface ::AccountsUpdateNotifier ,
2021-05-19 09:50:34 -07:00
ancestors ::Ancestors ,
2021-05-17 16:58:36 -07:00
append_vec ::{ AppendVec , StoredMetaWriteVersion } ,
2021-09-02 21:29:11 -07:00
bank ::{ Bank , BankFieldsToDeserialize , BankRc } ,
2020-07-13 07:00:59 -07:00
blockhash_queue ::BlockhashQueue ,
2021-09-02 21:29:11 -07:00
builtins ::Builtins ,
2020-07-13 07:00:59 -07:00
epoch_stakes ::EpochStakes ,
2021-03-10 09:49:10 -08:00
hardened_unpack ::UnpackedAppendVecMap ,
2020-07-13 07:00:59 -07:00
rent_collector ::RentCollector ,
2021-01-28 08:15:33 -08:00
serde_snapshot ::future ::SerializableStorage ,
2020-07-13 07:00:59 -07:00
stakes ::Stakes ,
2020-05-22 10:54:24 -07:00
} ,
2020-07-13 07:00:59 -07:00
bincode ,
2020-08-03 16:27:17 -07:00
bincode ::{ config ::Options , Error } ,
2021-03-10 09:49:10 -08:00
log ::* ,
2021-06-16 06:48:24 -07:00
rayon ::prelude ::* ,
2020-08-03 16:27:17 -07:00
serde ::{ de ::DeserializeOwned , Deserialize , Serialize } ,
2021-09-23 15:34:32 -07:00
solana_measure ::measure ::Measure ,
2021-08-26 17:30:36 -07:00
solana_program_runtime ::InstructionProcessor ,
2020-07-13 07:00:59 -07:00
solana_sdk ::{
clock ::{ Epoch , Slot , UnixTimestamp } ,
epoch_schedule ::EpochSchedule ,
fee_calculator ::{ FeeCalculator , FeeRateGovernor } ,
genesis_config ::GenesisConfig ,
hard_forks ::HardForks ,
hash ::Hash ,
inflation ::Inflation ,
pubkey ::Pubkey ,
} ,
2020-05-22 10:54:24 -07:00
std ::{
2020-09-23 18:46:42 -07:00
collections ::{ HashMap , HashSet } ,
2021-03-10 09:49:10 -08:00
io ::{ self , BufReader , BufWriter , Read , Write } ,
2021-06-21 08:47:58 -07:00
path ::{ Path , PathBuf } ,
2020-05-22 10:54:24 -07:00
result ::Result ,
2021-09-23 15:34:32 -07:00
sync ::{
atomic ::{ AtomicUsize , Ordering } ,
Arc , RwLock ,
} ,
2020-05-22 10:54:24 -07:00
} ,
} ;
2020-07-13 07:00:59 -07:00
#[ cfg(RUSTC_WITH_SPECIALIZATION) ]
2020-10-19 21:07:46 -07:00
use solana_frozen_abi ::abi_example ::IgnoreAsHelper ;
2020-07-13 07:00:59 -07:00
mod common ;
2020-05-22 10:54:24 -07:00
mod future ;
mod tests ;
mod utils ;
use future ::Context as TypeContextFuture ;
#[ allow(unused_imports) ]
use utils ::{ serialize_iter_as_map , serialize_iter_as_seq , serialize_iter_as_tuple } ;
// a number of test cases in accounts_db use this
#[ cfg(test) ]
pub ( crate ) use self ::tests ::reconstruct_accounts_db_via_serialization ;
2020-07-13 07:00:59 -07:00
pub ( crate ) use crate ::accounts_db ::{ SnapshotStorage , SnapshotStorages } ;
2020-05-22 10:54:24 -07:00
#[ derive(Copy, Clone, Eq, PartialEq) ]
2020-07-13 07:00:59 -07:00
pub ( crate ) enum SerdeStyle {
2021-02-18 23:42:09 -08:00
Newer ,
2020-05-22 10:54:24 -07:00
}
2020-07-13 07:00:59 -07:00
const MAX_STREAM_SIZE : u64 = 32 * 1024 * 1024 * 1024 ;
2020-05-22 10:54:24 -07:00
2020-07-13 07:00:59 -07:00
#[ derive(Clone, Debug, Default, Deserialize, Serialize, AbiExample) ]
2021-05-17 16:58:36 -07:00
struct AccountsDbFields < T > (
HashMap < Slot , Vec < T > > ,
StoredMetaWriteVersion ,
Slot ,
BankHashInfo ,
) ;
2020-05-22 10:54:24 -07:00
2021-07-22 12:40:37 -07:00
/// Helper type to wrap BufReader streams when deserializing and reconstructing from either just a
/// full snapshot, or both a full and incremental snapshot
pub struct SnapshotStreams < ' a , R > {
pub full_snapshot_stream : & ' a mut BufReader < R > ,
pub incremental_snapshot_stream : Option < & ' a mut BufReader < R > > ,
}
/// Helper type to wrap AccountsDbFields when reconstructing AccountsDb from either just a full
/// snapshot, or both a full and incremental snapshot
#[ derive(Debug) ]
struct SnapshotAccountsDbFields < T > {
full_snapshot_accounts_db_fields : AccountsDbFields < T > ,
incremental_snapshot_accounts_db_fields : Option < AccountsDbFields < T > > ,
}
impl < T > SnapshotAccountsDbFields < T > {
/// Collapse the SnapshotAccountsDbFields into a single AccountsDbFields. If there is no
/// incremental snapshot, this returns the AccountsDbFields from the full snapshot. Otherwise
/// this uses the version, slot, and bank hash info from the incremental snapshot, then the
/// combination of the storages from both the full and incremental snapshots.
fn collapse_into ( self ) -> Result < AccountsDbFields < T > , Error > {
match self . incremental_snapshot_accounts_db_fields {
None = > Ok ( self . full_snapshot_accounts_db_fields ) ,
Some ( AccountsDbFields (
mut incremental_snapshot_storages ,
incremental_snapshot_version ,
incremental_snapshot_slot ,
incremental_snapshot_bank_hash_info ,
) ) = > {
let full_snapshot_storages = self . full_snapshot_accounts_db_fields . 0 ;
let full_snapshot_slot = self . full_snapshot_accounts_db_fields . 2 ;
// filter out incremental snapshot storages with slot <= full snapshot slot
incremental_snapshot_storages . retain ( | slot , _ | * slot > full_snapshot_slot ) ;
// There must not be any overlap in the slots of storages between the full snapshot and the incremental snapshot
incremental_snapshot_storages
. iter ( )
. all ( | storage_entry | ! full_snapshot_storages . contains_key ( storage_entry . 0 ) ) . then ( | | ( ) ) . ok_or_else ( | | {
io ::Error ::new ( io ::ErrorKind ::InvalidData , " Snapshots are incompatible: There are storages for the same slot in both the full snapshot and the incremental snapshot! " )
} ) ? ;
let mut combined_storages = full_snapshot_storages ;
combined_storages . extend ( incremental_snapshot_storages . into_iter ( ) ) ;
Ok ( AccountsDbFields (
combined_storages ,
incremental_snapshot_version ,
incremental_snapshot_slot ,
incremental_snapshot_bank_hash_info ,
) )
}
}
}
}
2020-07-13 07:00:59 -07:00
trait TypeContext < ' a > {
2020-05-22 10:54:24 -07:00
type SerializableAccountStorageEntry : Serialize
+ DeserializeOwned
+ From < & ' a AccountStorageEntry >
2021-06-16 06:48:24 -07:00
+ SerializableStorage
+ Sync ;
2020-05-22 10:54:24 -07:00
2020-07-13 07:00:59 -07:00
fn serialize_bank_and_storage < S : serde ::ser ::Serializer > (
2020-05-22 10:54:24 -07:00
serializer : S ,
2020-07-13 07:00:59 -07:00
serializable_bank : & SerializableBankAndStorage < ' a , Self > ,
2020-05-22 10:54:24 -07:00
) -> std ::result ::Result < S ::Ok , S ::Error >
where
Self : std ::marker ::Sized ;
fn serialize_accounts_db_fields < S : serde ::ser ::Serializer > (
serializer : S ,
2021-02-18 23:42:09 -08:00
serializable_db : & SerializableAccountsDb < ' a , Self > ,
2020-05-22 10:54:24 -07:00
) -> std ::result ::Result < S ::Ok , S ::Error >
where
Self : std ::marker ::Sized ;
2020-07-13 07:00:59 -07:00
fn deserialize_bank_fields < R > (
stream : & mut BufReader < R > ,
) -> Result <
(
BankFieldsToDeserialize ,
AccountsDbFields < Self ::SerializableAccountStorageEntry > ,
) ,
Error ,
>
where
R : Read ;
2020-05-22 10:54:24 -07:00
fn deserialize_accounts_db_fields < R > (
stream : & mut BufReader < R > ,
2020-07-13 07:00:59 -07:00
) -> Result < AccountsDbFields < Self ::SerializableAccountStorageEntry > , Error >
2020-05-22 10:54:24 -07:00
where
R : Read ;
2020-07-13 07:00:59 -07:00
}
2020-05-22 10:54:24 -07:00
2020-07-13 07:00:59 -07:00
fn deserialize_from < R , T > ( reader : R ) -> bincode ::Result < T >
where
R : Read ,
T : DeserializeOwned ,
{
bincode ::options ( )
. with_limit ( MAX_STREAM_SIZE )
. with_fixint_encoding ( )
. allow_trailing_bytes ( )
. deserialize_from ::< R , T > ( reader )
2020-05-22 10:54:24 -07:00
}
2021-01-11 17:00:23 -08:00
#[ allow(clippy::too_many_arguments) ]
2021-07-22 12:40:37 -07:00
pub ( crate ) fn bank_from_streams < R > (
2020-05-22 10:54:24 -07:00
serde_style : SerdeStyle ,
2021-07-22 12:40:37 -07:00
snapshot_streams : & mut SnapshotStreams < R > ,
2020-07-13 07:00:59 -07:00
account_paths : & [ PathBuf ] ,
2021-03-10 09:49:10 -08:00
unpacked_append_vec_map : UnpackedAppendVecMap ,
2020-07-13 07:00:59 -07:00
genesis_config : & GenesisConfig ,
frozen_account_pubkeys : & [ Pubkey ] ,
2020-09-23 18:46:42 -07:00
debug_keys : Option < Arc < HashSet < Pubkey > > > ,
2020-09-24 12:23:09 -07:00
additional_builtins : Option < & Builtins > ,
2021-07-22 12:40:37 -07:00
account_secondary_indexes : AccountSecondaryIndexes ,
2021-01-11 17:00:23 -08:00
caching_enabled : bool ,
2021-05-26 08:36:12 -07:00
limit_load_slot_count_from_snapshot : Option < usize > ,
2021-06-09 21:21:32 -07:00
shrink_ratio : AccountShrinkThreshold ,
2021-07-13 09:06:18 -07:00
verify_index : bool ,
2021-09-07 21:30:38 -07:00
accounts_db_config : Option < AccountsDbConfig > ,
2021-09-30 14:26:17 -07:00
accounts_update_notifier : Option < AccountsUpdateNotifier > ,
2020-07-13 07:00:59 -07:00
) -> std ::result ::Result < Bank , Error >
2020-05-22 10:54:24 -07:00
where
R : Read ,
{
macro_rules ! INTO {
2020-07-13 07:00:59 -07:00
( $x :ident ) = > { {
2021-07-22 12:40:37 -07:00
let ( full_snapshot_bank_fields , full_snapshot_accounts_db_fields ) =
$x ::deserialize_bank_fields ( snapshot_streams . full_snapshot_stream ) ? ;
let ( incremental_snapshot_bank_fields , incremental_snapshot_accounts_db_fields ) =
if let Some ( ref mut incremental_snapshot_stream ) =
snapshot_streams . incremental_snapshot_stream
{
let ( bank_fields , accounts_db_fields ) =
$x ::deserialize_bank_fields ( incremental_snapshot_stream ) ? ;
( Some ( bank_fields ) , Some ( accounts_db_fields ) )
} else {
( None , None )
} ;
let snapshot_accounts_db_fields = SnapshotAccountsDbFields {
full_snapshot_accounts_db_fields ,
incremental_snapshot_accounts_db_fields ,
} ;
2020-07-13 07:00:59 -07:00
let bank = reconstruct_bank_from_fields (
2021-07-22 12:40:37 -07:00
incremental_snapshot_bank_fields . unwrap_or ( full_snapshot_bank_fields ) ,
snapshot_accounts_db_fields ,
2020-07-13 07:00:59 -07:00
genesis_config ,
frozen_account_pubkeys ,
account_paths ,
2021-03-10 09:49:10 -08:00
unpacked_append_vec_map ,
2020-09-23 18:46:42 -07:00
debug_keys ,
2020-09-24 12:23:09 -07:00
additional_builtins ,
2021-07-22 12:40:37 -07:00
account_secondary_indexes ,
2021-01-11 17:00:23 -08:00
caching_enabled ,
2021-05-26 08:36:12 -07:00
limit_load_slot_count_from_snapshot ,
2021-06-09 21:21:32 -07:00
shrink_ratio ,
2021-07-13 09:06:18 -07:00
verify_index ,
2021-09-07 21:30:38 -07:00
accounts_db_config ,
2021-09-30 14:26:17 -07:00
accounts_update_notifier ,
2020-07-13 07:00:59 -07:00
) ? ;
Ok ( bank )
} } ;
2020-05-22 10:54:24 -07:00
}
match serde_style {
2021-02-18 23:42:09 -08:00
SerdeStyle ::Newer = > INTO ! ( TypeContextFuture ) ,
2020-05-22 10:54:24 -07:00
}
2020-06-17 01:56:29 -07:00
. map_err ( | err | {
warn! ( " bankrc_from_stream error: {:?} " , err ) ;
err
} )
2020-05-22 10:54:24 -07:00
}
2020-07-13 07:00:59 -07:00
pub ( crate ) fn bank_to_stream < W > (
2020-05-22 10:54:24 -07:00
serde_style : SerdeStyle ,
stream : & mut BufWriter < W > ,
2020-07-13 07:00:59 -07:00
bank : & Bank ,
2020-05-22 10:54:24 -07:00
snapshot_storages : & [ SnapshotStorage ] ,
2020-06-17 01:56:29 -07:00
) -> Result < ( ) , Error >
2020-05-22 10:54:24 -07:00
where
W : Write ,
{
macro_rules ! INTO {
( $x :ident ) = > {
2020-07-13 07:00:59 -07:00
bincode ::serialize_into (
2020-05-22 10:54:24 -07:00
stream ,
2020-07-13 07:00:59 -07:00
& SerializableBankAndStorage ::< $x > {
bank ,
2020-05-22 10:54:24 -07:00
snapshot_storages ,
phantom : std ::marker ::PhantomData ::default ( ) ,
} ,
)
} ;
}
match serde_style {
2021-02-18 23:42:09 -08:00
SerdeStyle ::Newer = > INTO ! ( TypeContextFuture ) ,
2020-05-22 10:54:24 -07:00
}
2020-06-17 01:56:29 -07:00
. map_err ( | err | {
warn! ( " bankrc_to_stream error: {:?} " , err ) ;
err
} )
2020-05-22 10:54:24 -07:00
}
2020-07-13 07:00:59 -07:00
struct SerializableBankAndStorage < ' a , C > {
bank : & ' a Bank ,
2020-05-22 10:54:24 -07:00
snapshot_storages : & ' a [ SnapshotStorage ] ,
phantom : std ::marker ::PhantomData < C > ,
}
2020-07-13 07:00:59 -07:00
impl < ' a , C : TypeContext < ' a > > Serialize for SerializableBankAndStorage < ' a , C > {
2020-05-22 10:54:24 -07:00
fn serialize < S > ( & self , serializer : S ) -> std ::result ::Result < S ::Ok , S ::Error >
where
S : serde ::ser ::Serializer ,
{
2020-07-13 07:00:59 -07:00
C ::serialize_bank_and_storage ( serializer , self )
2020-05-22 10:54:24 -07:00
}
}
2021-02-18 23:42:09 -08:00
struct SerializableAccountsDb < ' a , C > {
accounts_db : & ' a AccountsDb ,
2020-05-22 10:54:24 -07:00
slot : Slot ,
account_storage_entries : & ' a [ SnapshotStorage ] ,
phantom : std ::marker ::PhantomData < C > ,
}
2021-02-18 23:42:09 -08:00
impl < ' a , C : TypeContext < ' a > > Serialize for SerializableAccountsDb < ' a , C > {
2020-05-22 10:54:24 -07:00
fn serialize < S > ( & self , serializer : S ) -> std ::result ::Result < S ::Ok , S ::Error >
where
S : serde ::ser ::Serializer ,
{
C ::serialize_accounts_db_fields ( serializer , self )
}
}
2020-07-13 07:00:59 -07:00
#[ cfg(RUSTC_WITH_SPECIALIZATION) ]
2021-02-18 23:42:09 -08:00
impl < ' a , C > IgnoreAsHelper for SerializableAccountsDb < ' a , C > { }
2020-07-13 07:00:59 -07:00
2021-01-11 17:00:23 -08:00
#[ allow(clippy::too_many_arguments) ]
2021-03-10 09:49:10 -08:00
fn reconstruct_bank_from_fields < E > (
2020-07-13 07:00:59 -07:00
bank_fields : BankFieldsToDeserialize ,
2021-07-22 12:40:37 -07:00
snapshot_accounts_db_fields : SnapshotAccountsDbFields < E > ,
2020-07-13 07:00:59 -07:00
genesis_config : & GenesisConfig ,
frozen_account_pubkeys : & [ Pubkey ] ,
account_paths : & [ PathBuf ] ,
2021-03-10 09:49:10 -08:00
unpacked_append_vec_map : UnpackedAppendVecMap ,
2020-09-23 18:46:42 -07:00
debug_keys : Option < Arc < HashSet < Pubkey > > > ,
2020-09-24 12:23:09 -07:00
additional_builtins : Option < & Builtins > ,
2021-07-22 12:40:37 -07:00
account_secondary_indexes : AccountSecondaryIndexes ,
2021-01-11 17:00:23 -08:00
caching_enabled : bool ,
2021-05-26 08:36:12 -07:00
limit_load_slot_count_from_snapshot : Option < usize > ,
2021-06-09 21:21:32 -07:00
shrink_ratio : AccountShrinkThreshold ,
2021-07-13 09:06:18 -07:00
verify_index : bool ,
2021-09-07 21:30:38 -07:00
accounts_db_config : Option < AccountsDbConfig > ,
2021-09-30 14:26:17 -07:00
accounts_update_notifier : Option < AccountsUpdateNotifier > ,
2020-07-13 07:00:59 -07:00
) -> Result < Bank , Error >
where
2021-06-16 06:48:24 -07:00
E : SerializableStorage + std ::marker ::Sync ,
2020-07-13 07:00:59 -07:00
{
2020-09-02 00:37:36 -07:00
let mut accounts_db = reconstruct_accountsdb_from_fields (
2021-07-22 12:40:37 -07:00
snapshot_accounts_db_fields ,
2020-09-02 00:37:36 -07:00
account_paths ,
2021-03-10 09:49:10 -08:00
unpacked_append_vec_map ,
2021-10-11 10:46:27 -07:00
genesis_config ,
2021-07-22 12:40:37 -07:00
account_secondary_indexes ,
2021-01-11 17:00:23 -08:00
caching_enabled ,
2021-05-26 08:36:12 -07:00
limit_load_slot_count_from_snapshot ,
2021-06-09 21:21:32 -07:00
shrink_ratio ,
2021-07-13 09:06:18 -07:00
verify_index ,
2021-09-07 21:30:38 -07:00
accounts_db_config ,
2021-09-30 14:26:17 -07:00
accounts_update_notifier ,
2020-09-02 00:37:36 -07:00
) ? ;
2021-05-20 08:11:56 -07:00
accounts_db . freeze_accounts (
& Ancestors ::from ( & bank_fields . ancestors ) ,
frozen_account_pubkeys ,
) ;
2020-07-13 07:00:59 -07:00
let bank_rc = BankRc ::new ( Accounts ::new_empty ( accounts_db ) , bank_fields . slot ) ;
2021-06-15 13:39:22 -07:00
// if limit_load_slot_count_from_snapshot is set, then we need to side-step some correctness checks beneath this call
let debug_do_not_add_builtins = limit_load_slot_count_from_snapshot . is_some ( ) ;
2020-09-24 12:23:09 -07:00
let bank = Bank ::new_from_fields (
bank_rc ,
genesis_config ,
bank_fields ,
debug_keys ,
additional_builtins ,
2021-06-15 13:39:22 -07:00
debug_do_not_add_builtins ,
2020-09-24 12:23:09 -07:00
) ;
2020-07-13 07:00:59 -07:00
Ok ( bank )
}
2021-06-21 08:47:58 -07:00
fn reconstruct_single_storage < E > (
slot : & Slot ,
append_vec_path : & Path ,
storage_entry : & E ,
2021-09-23 15:34:32 -07:00
remapped_append_vec_id : Option < AppendVecId > ,
2021-06-21 08:47:58 -07:00
new_slot_storage : & mut HashMap < AppendVecId , Arc < AccountStorageEntry > > ,
) -> Result < ( ) , Error >
where
E : SerializableStorage ,
{
2021-09-23 15:34:32 -07:00
let append_vec_id = remapped_append_vec_id . unwrap_or_else ( | | storage_entry . id ( ) ) ;
2021-06-21 08:47:58 -07:00
let ( accounts , num_accounts ) =
AppendVec ::new_from_file ( append_vec_path , storage_entry . current_len ( ) ) ? ;
let u_storage_entry =
2021-09-23 15:34:32 -07:00
AccountStorageEntry ::new_existing ( * slot , append_vec_id , accounts , num_accounts ) ;
2021-06-21 08:47:58 -07:00
2021-09-23 15:34:32 -07:00
new_slot_storage . insert ( append_vec_id , Arc ::new ( u_storage_entry ) ) ;
2021-06-21 08:47:58 -07:00
Ok ( ( ) )
}
2021-08-10 03:45:46 -07:00
#[ allow(clippy::too_many_arguments) ]
2021-03-10 09:49:10 -08:00
fn reconstruct_accountsdb_from_fields < E > (
2021-07-22 12:40:37 -07:00
snapshot_accounts_db_fields : SnapshotAccountsDbFields < E > ,
2020-05-22 10:54:24 -07:00
account_paths : & [ PathBuf ] ,
2021-03-10 09:49:10 -08:00
unpacked_append_vec_map : UnpackedAppendVecMap ,
2021-10-11 10:46:27 -07:00
genesis_config : & GenesisConfig ,
2021-07-22 12:40:37 -07:00
account_secondary_indexes : AccountSecondaryIndexes ,
2021-01-11 17:00:23 -08:00
caching_enabled : bool ,
2021-05-26 08:36:12 -07:00
limit_load_slot_count_from_snapshot : Option < usize > ,
2021-06-09 21:21:32 -07:00
shrink_ratio : AccountShrinkThreshold ,
2021-07-13 09:06:18 -07:00
verify_index : bool ,
2021-09-07 21:30:38 -07:00
accounts_db_config : Option < AccountsDbConfig > ,
2021-09-30 14:26:17 -07:00
accounts_update_notifier : Option < AccountsUpdateNotifier > ,
2021-02-18 23:42:09 -08:00
) -> Result < AccountsDb , Error >
2020-05-22 10:54:24 -07:00
where
2021-06-16 06:48:24 -07:00
E : SerializableStorage + std ::marker ::Sync ,
2020-05-22 10:54:24 -07:00
{
2021-02-18 23:42:09 -08:00
let mut accounts_db = AccountsDb ::new_with_config (
2021-01-11 17:00:23 -08:00
account_paths . to_vec ( ) ,
2021-10-11 10:46:27 -07:00
& genesis_config . cluster_type ,
2021-07-22 12:40:37 -07:00
account_secondary_indexes ,
2021-01-11 17:00:23 -08:00
caching_enabled ,
2021-06-09 21:21:32 -07:00
shrink_ratio ,
2021-09-07 21:30:38 -07:00
accounts_db_config ,
2021-09-30 14:26:17 -07:00
accounts_update_notifier ,
2021-01-11 17:00:23 -08:00
) ;
2021-07-22 12:40:37 -07:00
let AccountsDbFields (
snapshot_storages ,
snapshot_version ,
snapshot_slot ,
snapshot_bank_hash_info ,
) = snapshot_accounts_db_fields . collapse_into ( ) ? ;
let snapshot_storages = snapshot_storages . into_iter ( ) . collect ::< Vec < _ > > ( ) ;
2020-05-22 10:54:24 -07:00
2021-01-02 17:57:56 -08:00
// Ensure all account paths exist
for path in & accounts_db . paths {
std ::fs ::create_dir_all ( path )
. unwrap_or_else ( | err | panic! ( " Failed to create directory {} : {} " , path . display ( ) , err ) ) ;
}
2020-05-22 10:54:24 -07:00
// Remap the deserialized AppendVec paths to point to correct local paths
2021-09-23 15:34:32 -07:00
let num_collisions = AtomicUsize ::new ( 0 ) ;
let next_append_vec_id = AtomicUsize ::new ( 0 ) ;
let mut measure_remap = Measure ::start ( " remap " ) ;
2021-07-22 12:40:37 -07:00
let mut storage = ( 0 .. snapshot_storages . len ( ) )
2021-06-16 06:48:24 -07:00
. into_par_iter ( )
. map ( | i | {
2021-07-22 12:40:37 -07:00
let ( slot , slot_storage ) = & snapshot_storages [ i ] ;
2020-05-22 10:54:24 -07:00
let mut new_slot_storage = HashMap ::new ( ) ;
2021-06-16 06:48:24 -07:00
for storage_entry in slot_storage {
let file_name = AppendVec ::file_name ( * slot , storage_entry . id ( ) ) ;
2020-05-22 10:54:24 -07:00
2021-03-10 09:49:10 -08:00
let append_vec_path = unpacked_append_vec_map . get ( & file_name ) . ok_or_else ( | | {
io ::Error ::new (
io ::ErrorKind ::NotFound ,
format! ( " {} not found in unpacked append vecs " , file_name ) ,
)
} ) ? ;
2021-01-28 08:15:33 -08:00
2021-09-23 15:34:32 -07:00
// Remap the AppendVec ID to handle any duplicate IDs that may previously existed
// due to full snapshots and incremental snapshots generated from different nodes
let ( remapped_append_vec_id , remapped_append_vec_path ) = loop {
let remapped_append_vec_id = next_append_vec_id . fetch_add ( 1 , Ordering ::Relaxed ) ;
let remapped_file_name = AppendVec ::file_name ( * slot , remapped_append_vec_id ) ;
let remapped_append_vec_path =
append_vec_path . parent ( ) . unwrap ( ) . join ( & remapped_file_name ) ;
// Break out of the loop in the following situations:
// 1. The new ID is the same as the original ID. This means we do not need to
// rename the file, since the ID is the "correct" one already.
// 2. There is not a file already at the new path. This means it is safe to
// rename the file to this new path.
// **DEVELOPER NOTE:** Keep this check last so that it can short-circuit if
// possible.
if storage_entry . id ( ) = = remapped_append_vec_id
| | std ::fs ::metadata ( & remapped_append_vec_path ) . is_err ( )
{
break ( remapped_append_vec_id , remapped_append_vec_path ) ;
}
// If we made it this far, a file exists at the new path. Record the collision
// and try again.
num_collisions . fetch_add ( 1 , Ordering ::Relaxed ) ;
} ;
// Only rename the file if the new ID is actually different from the original.
if storage_entry . id ( ) ! = remapped_append_vec_id {
std ::fs ::rename ( append_vec_path , & remapped_append_vec_path ) ? ;
}
2021-06-21 08:47:58 -07:00
reconstruct_single_storage (
2021-06-21 10:12:56 -07:00
slot ,
2021-09-23 15:34:32 -07:00
& remapped_append_vec_path ,
2021-06-21 08:47:58 -07:00
storage_entry ,
2021-09-23 15:34:32 -07:00
Some ( remapped_append_vec_id ) ,
2021-06-21 08:47:58 -07:00
& mut new_slot_storage ,
) ? ;
2020-05-22 10:54:24 -07:00
}
2021-06-16 06:48:24 -07:00
Ok ( ( * slot , new_slot_storage ) )
2020-05-22 10:54:24 -07:00
} )
2020-06-17 01:56:29 -07:00
. collect ::< Result < HashMap < Slot , _ > , Error > > ( ) ? ;
2021-09-23 15:34:32 -07:00
measure_remap . stop ( ) ;
2020-05-22 10:54:24 -07:00
// discard any slots with no storage entries
// this can happen if a non-root slot was serialized
// but non-root stores should not be included in the snapshot
storage . retain ( | _slot , stores | ! stores . is_empty ( ) ) ;
2021-09-23 15:34:32 -07:00
assert! (
! storage . is_empty ( ) ,
" At least one storage entry must exist from deserializing stream "
) ;
let next_append_vec_id = next_append_vec_id . load ( Ordering ::Relaxed ) ;
let max_append_vec_id = next_append_vec_id - 1 ;
assert! (
max_append_vec_id < = AppendVecId ::MAX / 2 ,
" Storage id {} larger than allowed max " ,
max_append_vec_id
) ;
2020-05-22 10:54:24 -07:00
2021-09-23 15:34:32 -07:00
// Process deserialized data, set necessary fields in self
2020-05-22 10:54:24 -07:00
accounts_db
. bank_hashes
. write ( )
. unwrap ( )
2021-07-22 12:40:37 -07:00
. insert ( snapshot_slot , snapshot_bank_hash_info ) ;
2021-09-23 15:34:32 -07:00
accounts_db . storage . 0. extend (
storage
. into_iter ( )
. map ( | ( slot , slot_storage_entry ) | ( slot , Arc ::new ( RwLock ::new ( slot_storage_entry ) ) ) ) ,
) ;
accounts_db
. next_id
. store ( next_append_vec_id , Ordering ::Relaxed ) ;
2020-05-22 10:54:24 -07:00
accounts_db
. write_version
2021-07-22 12:40:37 -07:00
. fetch_add ( snapshot_version , Ordering ::Relaxed ) ;
2021-07-13 09:06:18 -07:00
accounts_db . generate_index ( limit_load_slot_count_from_snapshot , verify_index ) ;
2021-10-11 10:46:27 -07:00
accounts_db . maybe_add_filler_accounts ( genesis_config . ticks_per_slot ( ) ) ;
2021-09-23 15:34:32 -07:00
2021-09-30 14:26:17 -07:00
let mut measure_notify = Measure ::start ( " accounts_notify " ) ;
accounts_db . notify_account_restore_from_snapshot ( ) ;
measure_notify . stop ( ) ;
2021-09-23 15:34:32 -07:00
datapoint_info! (
" reconstruct_accountsdb_from_fields() " ,
( " remap-time-us " , measure_remap . as_us ( ) , i64 ) ,
(
" remap-collisions " ,
num_collisions . load ( Ordering ::Relaxed ) ,
i64
) ,
2021-09-30 14:26:17 -07:00
( " accountsdb-notify-at-start-us " , measure_notify . as_us ( ) , i64 ) ,
2021-09-23 15:34:32 -07:00
) ;
2020-05-22 10:54:24 -07:00
Ok ( accounts_db )
}