Skip to content

Commit f574737

Browse files
Fix storage unit test crash when exiting (#1778)
This bug has no impact on production. Co-authored-by: Zhe Yang <[email protected]>
1 parent e5544c3 commit f574737

File tree

10 files changed

+76
-82
lines changed

10 files changed

+76
-82
lines changed

.gitignore

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,4 +14,3 @@ build/
1414
**/*.log
1515
**/testnet.toml
1616
*~
17-
conflux_unit_test_data_dir

core/examples/snapshot_merge_test.rs

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -295,7 +295,7 @@ fn new_state_manager(
295295
}
296296

297297
fn initialize_genesis(
298-
manager: &StateManager,
298+
manager: &Arc<StateManager>,
299299
) -> Result<(H256, MerkleHash), Error> {
300300
let mut state = manager.get_state_for_genesis_write();
301301

@@ -321,8 +321,9 @@ fn initialize_genesis(
321321
}
322322

323323
fn prepare_state(
324-
manager: &StateManager, parent: H256, height: &mut u64, accounts: usize,
325-
accounts_per_epoch: usize, account_map: &mut HashMap<Address, Account>,
324+
manager: &Arc<StateManager>, parent: H256, height: &mut u64,
325+
accounts: usize, accounts_per_epoch: usize,
326+
account_map: &mut HashMap<Address, Account>,
326327
old_state_root: &StateRootWithAuxInfo, state_root: &StateRootWithAuxInfo,
327328
) -> Result<(H256, MerkleHash), StorageError>
328329
{
@@ -347,7 +348,7 @@ fn prepare_state(
347348
}
348349

349350
fn add_accounts(
350-
manager: &StateManager, parent: H256, height: &mut u64,
351+
manager: &Arc<StateManager>, parent: H256, height: &mut u64,
351352
accounts_per_epoch: usize, new_account_map: &HashMap<Address, Account>,
352353
old_state_root: &StateRootWithAuxInfo, state_root: &StateRootWithAuxInfo,
353354
) -> Result<(H256, MerkleHash), StorageError>
@@ -407,7 +408,7 @@ fn add_accounts(
407408
}
408409

409410
fn add_accounts_and_commit<'a, Iter>(
410-
manager: &StateManager, accounts: usize, account_map: &mut Iter,
411+
manager: &Arc<StateManager>, accounts: usize, account_map: &mut Iter,
411412
state_index: StateIndex,
412413
) -> H256
413414
where

core/src/executive/context.rs

Lines changed: 18 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -424,10 +424,7 @@ mod tests {
424424
machine::{new_machine_with_builtin, Machine},
425425
parameters::consensus::TRANSACTION_DEFAULT_EPOCH_BOUND,
426426
state::{State, Substate},
427-
storage::{
428-
new_storage_manager_for_testing, tests::FakeStateManager,
429-
StorageManager,
430-
},
427+
storage::{new_storage_manager_for_testing, tests::FakeStateManager},
431428
test_helpers::get_state_for_genesis_write,
432429
vm::{
433430
CallType, Context as ContextTrait, ContractCreateResult,
@@ -464,9 +461,12 @@ mod tests {
464461
}
465462
}
466463

464+
// storage_manager is apparently unused but it must be held to keep the
465+
// database directory.
466+
#[allow(unused)]
467467
struct TestSetup {
468-
storage_manager: Option<Box<FakeStateManager>>,
469-
state: Option<State>,
468+
storage_manager: FakeStateManager,
469+
state: State,
470470
machine: Machine,
471471
internal_contract_map: InternalContractMap,
472472
spec: Spec,
@@ -475,36 +475,25 @@ mod tests {
475475
}
476476

477477
impl TestSetup {
478-
fn init_state(&mut self, storage_manager: &'static StorageManager) {
479-
self.state = Some(get_state_for_genesis_write(storage_manager));
480-
}
481-
482478
fn new() -> Self {
483-
let storage_manager = Box::new(new_storage_manager_for_testing());
479+
let storage_manager = new_storage_manager_for_testing();
480+
let state = get_state_for_genesis_write(&*storage_manager);
484481
let machine = new_machine_with_builtin(Default::default());
485482
let env = get_test_env();
486483
let spec = machine.spec(env.number);
487484
let internal_contract_map = InternalContractMap::new();
488485

489486
let mut setup = Self {
490-
storage_manager: None,
491-
state: None,
487+
storage_manager,
488+
state,
492489
machine,
493490
internal_contract_map,
494491
spec,
495492
substate: Substate::new(),
496493
env,
497494
};
498-
setup.storage_manager = Some(storage_manager);
499-
setup.init_state(unsafe {
500-
&*(&**setup.storage_manager.as_ref().unwrap().as_ref()
501-
as *const StorageManager)
502-
});
503-
504495
setup
505496
.state
506-
.as_mut()
507-
.unwrap()
508497
.init_code(&Address::zero(), vec![], Address::zero())
509498
.ok();
510499

@@ -515,7 +504,7 @@ mod tests {
515504
#[test]
516505
fn can_be_created() {
517506
let mut setup = TestSetup::new();
518-
let state = &mut setup.state.unwrap();
507+
let state = &mut setup.state;
519508
let origin = get_test_origin();
520509

521510
let ctx = Context::new(
@@ -538,7 +527,7 @@ mod tests {
538527
#[test]
539528
fn can_return_block_hash_no_env() {
540529
let mut setup = TestSetup::new();
541-
let state = &mut setup.state.unwrap();
530+
let state = &mut setup.state;
542531
let origin = get_test_origin();
543532

544533
let mut ctx = Context::new(
@@ -580,7 +569,7 @@ mod tests {
580569
// last_hashes.push(test_hash.clone());
581570
// env.last_hashes = Arc::new(last_hashes);
582571
// }
583-
// let state = &mut setup.state.unwrap();
572+
// let state = &mut setup.state;
584573
// let origin = get_test_origin();
585574
//
586575
// let mut ctx = Context::new(
@@ -610,7 +599,7 @@ mod tests {
610599
#[should_panic]
611600
fn can_call_fail_empty() {
612601
let mut setup = TestSetup::new();
613-
let state = &mut setup.state.unwrap();
602+
let state = &mut setup.state;
614603
let origin = get_test_origin();
615604

616605
let mut ctx = Context::new(
@@ -658,7 +647,7 @@ mod tests {
658647
.unwrap()];
659648

660649
let mut setup = TestSetup::new();
661-
let state = &mut setup.state.unwrap();
650+
let state = &mut setup.state;
662651
let origin = get_test_origin();
663652

664653
{
@@ -687,7 +676,7 @@ mod tests {
687676
refund_account.set_user_account_type_bits();
688677

689678
let mut setup = TestSetup::new();
690-
let state = &mut setup.state.unwrap();
679+
let state = &mut setup.state;
691680
let mut origin = get_test_origin();
692681

693682
let mut contract_address = Address::zero();
@@ -731,7 +720,7 @@ mod tests {
731720
use std::str::FromStr;
732721

733722
let mut setup = TestSetup::new();
734-
let state = &mut setup.state.unwrap();
723+
let state = &mut setup.state;
735724
let origin = get_test_origin();
736725

737726
let address = {
@@ -777,7 +766,7 @@ mod tests {
777766
use std::str::FromStr;
778767

779768
let mut setup = TestSetup::new();
780-
let state = &mut setup.state.unwrap();
769+
let state = &mut setup.state;
781770
let origin = get_test_origin();
782771

783772
let address = {

core/src/genesis.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -98,8 +98,9 @@ pub fn initialize_internal_contract_accounts(state: &mut State) {
9898
/// ` test_net_version` is used to update the genesis author so that after
9999
/// resetting, the chain of the older version will be discarded
100100
pub fn genesis_block(
101-
storage_manager: &StorageManager, genesis_accounts: HashMap<Address, U256>,
102-
test_net_version: Address, initial_difficulty: U256,
101+
storage_manager: &Arc<StorageManager>,
102+
genesis_accounts: HashMap<Address, U256>, test_net_version: Address,
103+
initial_difficulty: U256,
103104
) -> Block
104105
{
105106
let mut state = State::new(

core/src/state/state_tests.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,11 @@ use crate::{
1919
use cfx_types::{address_util::AddressUtil, Address, BigEndianHash, U256};
2020
use keccak_hash::{keccak, KECCAK_EMPTY};
2121
use primitives::{EpochId, StorageKey, StorageLayout};
22+
use std::sync::Arc;
2223

23-
fn get_state(storage_manager: &StorageManager, epoch_id: &EpochId) -> State {
24+
fn get_state(
25+
storage_manager: &Arc<StorageManager>, epoch_id: &EpochId,
26+
) -> State {
2427
State::new(
2528
StateDb::new(
2629
storage_manager

core/src/storage/impls/state_manager.rs

Lines changed: 10 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -540,23 +540,20 @@ impl StateManager {
540540

541541
impl StateManagerTrait for StateManager {
542542
fn get_state_no_commit(
543-
&self, state_index: StateIndex, try_open: bool,
543+
self: &Arc<Self>, state_index: StateIndex, try_open: bool,
544544
) -> Result<Option<State>> {
545545
let maybe_state_trees = self.get_state_trees(&state_index, try_open)?;
546546
match maybe_state_trees {
547547
None => Ok(None),
548-
Some(state_trees) => Ok(Some(State::new(
549-
// Safe because StateManager is always an Arc.
550-
unsafe { shared_from_this(self) },
551-
state_trees,
552-
))),
548+
Some(state_trees) => {
549+
Ok(Some(State::new(self.clone(), state_trees)))
550+
}
553551
}
554552
}
555553

556-
fn get_state_for_genesis_write(&self) -> State {
554+
fn get_state_for_genesis_write(self: &Arc<Self>) -> State {
557555
State::new(
558-
// Safe because StateManager is always an Arc.
559-
unsafe { shared_from_this(self) },
556+
self.clone(),
560557
StateTrees {
561558
snapshot_db: self
562559
.storage_manager
@@ -600,19 +597,17 @@ impl StateManagerTrait for StateManager {
600597
// Due to the complexity of the latter approach, we stay with the
601598
// simple approach.
602599
fn get_state_for_next_epoch(
603-
&self, parent_epoch_id: StateIndex,
600+
self: &Arc<Self>, parent_epoch_id: StateIndex,
604601
) -> Result<Option<State>> {
605602
let maybe_state_trees = self.get_state_trees_for_next_epoch(
606603
&parent_epoch_id,
607604
/* try_open = */ false,
608605
)?;
609606
match maybe_state_trees {
610607
None => Ok(None),
611-
Some(state_trees) => Ok(Some(State::new(
612-
// Safe because StateManager is always an Arc.
613-
unsafe { shared_from_this(self) },
614-
state_trees,
615-
))),
608+
Some(state_trees) => {
609+
Ok(Some(State::new(self.clone(), state_trees)))
610+
}
616611
}
617612
}
618613
}
@@ -630,7 +625,6 @@ use crate::storage::{
630625
state::*,
631626
state_manager::*,
632627
storage_db::*,
633-
utils::arc_ext::shared_from_this,
634628
StorageConfiguration,
635629
};
636630
use malloc_size_of_derive::MallocSizeOf as MallocSizeOfDerive;

core/src/storage/state_manager.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -31,12 +31,12 @@ pub trait StateManagerTrait {
3131
/// With try_open == true, the call fails immediately when the max number of
3232
/// snapshot open is reached.
3333
fn get_state_no_commit(
34-
&self, epoch_id: StateIndex, try_open: bool,
34+
self: &Arc<Self>, epoch_id: StateIndex, try_open: bool,
3535
) -> Result<Option<State>>;
3636
fn get_state_for_next_epoch(
37-
&self, parent_epoch_id: StateIndex,
37+
self: &Arc<Self>, parent_epoch_id: StateIndex,
3838
) -> Result<Option<State>>;
39-
fn get_state_for_genesis_write(&self) -> State;
39+
fn get_state_for_genesis_write(self: &Arc<Self>) -> State;
4040
}
4141

4242
impl StateIndex {

core/src/storage/tests/mod.rs

Lines changed: 26 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ impl KeyValueDB for FakeDbForStateTest {
5656
#[cfg(test)]
5757
pub struct FakeStateManager {
5858
data_dir: String,
59-
state_manager: Option<StateManager>,
59+
state_manager: Option<Arc<StateManager>>,
6060
}
6161

6262
#[cfg(test)]
@@ -82,27 +82,30 @@ impl FakeStateManager {
8282
let unit_test_data_path = Path::new(&unit_test_data_dir);
8383
Ok(FakeStateManager {
8484
data_dir: unit_test_data_dir.clone(),
85-
state_manager: Some(StateManager::new(StorageConfiguration {
86-
additional_maintained_snapshot_count: 0,
87-
consensus_param: ConsensusParam {
88-
snapshot_epoch_count,
85+
state_manager: Some(Arc::new(StateManager::new(
86+
StorageConfiguration {
87+
additional_maintained_snapshot_count: 0,
88+
consensus_param: ConsensusParam {
89+
snapshot_epoch_count,
90+
},
91+
debug_snapshot_checker_threads: 0,
92+
delta_mpts_cache_recent_lfu_factor: 4.0,
93+
delta_mpts_cache_size: 20_000_000,
94+
delta_mpts_cache_start_size: 1_000_000,
95+
delta_mpts_node_map_vec_size: 20_000_000,
96+
delta_mpts_slab_idle_size: 200_000,
97+
max_open_snapshots:
98+
defaults::DEFAULT_MAX_OPEN_SNAPSHOTS,
99+
path_delta_mpts_dir: unit_test_data_path
100+
.join(&*storage_dir::DELTA_MPTS_DIR),
101+
path_snapshot_dir: unit_test_data_path
102+
.join(&*storage_dir::SNAPSHOT_DIR),
103+
path_snapshot_info_db: unit_test_data_path
104+
.join(&*storage_dir::SNAPSHOT_INFO_DB_PATH),
105+
path_storage_dir: unit_test_data_path
106+
.join(&*storage_dir::STORAGE_DIR),
89107
},
90-
debug_snapshot_checker_threads: 0,
91-
delta_mpts_cache_recent_lfu_factor: 4.0,
92-
delta_mpts_cache_size: 20_000_000,
93-
delta_mpts_cache_start_size: 1_000_000,
94-
delta_mpts_node_map_vec_size: 20_000_000,
95-
delta_mpts_slab_idle_size: 200_000,
96-
max_open_snapshots: defaults::DEFAULT_MAX_OPEN_SNAPSHOTS,
97-
path_delta_mpts_dir: unit_test_data_path
98-
.join(&*storage_dir::DELTA_MPTS_DIR),
99-
path_snapshot_dir: unit_test_data_path
100-
.join(&*storage_dir::SNAPSHOT_DIR),
101-
path_snapshot_info_db: unit_test_data_path
102-
.join(&*storage_dir::SNAPSHOT_INFO_DB_PATH),
103-
path_storage_dir: unit_test_data_path
104-
.join(&*storage_dir::STORAGE_DIR),
105-
})?),
108+
)?)),
106109
})
107110
}
108111
}
@@ -122,7 +125,7 @@ impl Drop for FakeStateManager {
122125

123126
#[cfg(test)]
124127
impl Deref for FakeStateManager {
125-
type Target = StateManager;
128+
type Target = Arc<StateManager>;
126129

127130
fn deref(&self) -> &Self::Target { self.state_manager.as_ref().unwrap() }
128131
}
@@ -298,4 +301,5 @@ use std::{
298301
fs, mem,
299302
ops::{Deref, DerefMut},
300303
path::Path,
304+
sync::Arc,
301305
};

core/src/storage/tests/state.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -591,7 +591,7 @@ fn test_set_order() {
591591
#[test]
592592
fn test_set_order_concurrent() {
593593
let mut rng = get_rng_for_test();
594-
let state_manager = Arc::new(new_state_manager_for_unit_test());
594+
let state_manager = new_state_manager_for_unit_test();
595595
let keys = Arc::new(
596596
generate_keys(TEST_NUMBER_OF_KEYS / 10)
597597
.iter()

core/src/test_helpers.rs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,16 +6,19 @@ use crate::{
66
storage::{StateIndex, StorageManager, StorageManagerTrait},
77
};
88
use primitives::EpochId;
9+
use std::sync::Arc;
910

10-
pub fn get_state_for_genesis_write(storage_manager: &StorageManager) -> State {
11+
pub fn get_state_for_genesis_write(
12+
storage_manager: &Arc<StorageManager>,
13+
) -> State {
1114
get_state_for_genesis_write_with_factory(
1215
storage_manager,
1316
Factory::default(),
1417
)
1518
}
1619

1720
pub fn get_state_for_genesis_write_with_factory(
18-
storage_manager: &StorageManager, factory: Factory,
21+
storage_manager: &Arc<StorageManager>, factory: Factory,
1922
) -> State {
2023
let mut state = State::new(
2124
StateDb::new(storage_manager.get_state_for_genesis_write()),

0 commit comments

Comments
 (0)