diff --git a/beacon_node/beacon_chain/src/snapshot_cache.rs b/beacon_node/beacon_chain/src/snapshot_cache.rs index b386c22c29..e273c35218 100644 --- a/beacon_node/beacon_chain/src/snapshot_cache.rs +++ b/beacon_node/beacon_chain/src/snapshot_cache.rs @@ -280,19 +280,17 @@ impl SnapshotCache { mod test { use super::*; use crate::test_utils::{BeaconChainHarness, EphemeralHarnessType}; - use store::StoreConfig; use types::{ test_utils::generate_deterministic_keypair, BeaconBlock, Epoch, MainnetEthSpec, SignedBeaconBlock, Slot, }; fn get_harness() -> BeaconChainHarness> { - let harness = BeaconChainHarness::new_with_store_config( - MainnetEthSpec, - None, - types::test_utils::generate_deterministic_keypairs(1), - StoreConfig::default(), - ); + let harness = BeaconChainHarness::builder(MainnetEthSpec) + .default_spec() + .deterministic_keypairs(1) + .fresh_ephemeral_store() + .build(); harness.advance_slot(); diff --git a/beacon_node/beacon_chain/src/test_utils.rs b/beacon_node/beacon_chain/src/test_utils.rs index 11d4af90f4..1be7d746cf 100644 --- a/beacon_node/beacon_chain/src/test_utils.rs +++ b/beacon_node/beacon_chain/src/test_utils.rs @@ -21,6 +21,7 @@ use rand::rngs::StdRng; use rand::Rng; use rand::SeedableRng; use rayon::prelude::*; +use slog::Logger; use slot_clock::TestingSlotClock; use state_processing::state_advance::complete_state_advance; use std::borrow::Cow; @@ -61,6 +62,12 @@ pub type BaseHarnessType = pub type DiskHarnessType = BaseHarnessType, LevelDB>; pub type EphemeralHarnessType = BaseHarnessType, MemoryStore>; +type BoxedMutator = Box< + dyn FnOnce( + BeaconChainBuilder>, + ) -> BeaconChainBuilder>, +>; + pub type AddBlocksResult = ( HashMap, HashMap, @@ -134,6 +141,216 @@ pub fn test_spec() -> ChainSpec { spec } +pub struct Builder { + eth_spec_instance: T::EthSpec, + spec: Option, + validator_keypairs: Option>, + chain_config: Option, + store_config: Option, + #[allow(clippy::type_complexity)] + store: Option>>, + initial_mutator: Option>, + store_mutator: Option>, + log: Logger, +} + +impl Builder> { + pub fn fresh_ephemeral_store(mut self) -> Self { + let spec = self.spec.as_ref().expect("cannot build without spec"); + let validator_keypairs = self + .validator_keypairs + .clone() + .expect("cannot build without validator keypairs"); + + let store = Arc::new( + HotColdDB::open_ephemeral( + self.store_config.clone().unwrap_or_default(), + spec.clone(), + self.log.clone(), + ) + .unwrap(), + ); + let mutator = move |builder: BeaconChainBuilder<_>| { + let genesis_state = interop_genesis_state::( + &validator_keypairs, + HARNESS_GENESIS_TIME, + builder.get_spec(), + ) + .expect("should generate interop state"); + builder + .genesis_state(genesis_state) + .expect("should build state using recent genesis") + }; + self.store = Some(store); + self.store_mutator(Box::new(mutator)) + } +} + +impl Builder> { + /// Disk store, start from genesis. + pub fn fresh_disk_store(mut self, store: Arc, LevelDB>>) -> Self { + let validator_keypairs = self + .validator_keypairs + .clone() + .expect("cannot build without validator keypairs"); + + let mutator = move |builder: BeaconChainBuilder<_>| { + let genesis_state = interop_genesis_state::( + &validator_keypairs, + HARNESS_GENESIS_TIME, + builder.get_spec(), + ) + .expect("should generate interop state"); + builder + .genesis_state(genesis_state) + .expect("should build state using recent genesis") + }; + self.store = Some(store); + self.store_mutator(Box::new(mutator)) + } + + /// Disk store, resume. + pub fn resumed_disk_store(mut self, store: Arc, LevelDB>>) -> Self { + let mutator = move |builder: BeaconChainBuilder<_>| { + builder + .resume_from_db() + .expect("should resume from database") + }; + self.store = Some(store); + self.store_mutator(Box::new(mutator)) + } +} + +impl Builder> +where + E: EthSpec, + Hot: ItemStore, + Cold: ItemStore, +{ + pub fn new(eth_spec_instance: E) -> Self { + Self { + eth_spec_instance, + spec: None, + validator_keypairs: None, + chain_config: None, + store_config: None, + store: None, + initial_mutator: None, + store_mutator: None, + log: test_logger(), + } + } + + pub fn deterministic_keypairs(self, num_keypairs: usize) -> Self { + self.keypairs(types::test_utils::generate_deterministic_keypairs( + num_keypairs, + )) + } + + pub fn keypairs(mut self, validator_keypairs: Vec) -> Self { + self.validator_keypairs = Some(validator_keypairs); + self + } + + pub fn default_spec(self) -> Self { + self.spec_or_default(None) + } + + pub fn spec(self, spec: ChainSpec) -> Self { + self.spec_or_default(Some(spec)) + } + + pub fn spec_or_default(mut self, spec: Option) -> Self { + self.spec = Some(spec.unwrap_or_else(test_spec::)); + self + } + + /// This mutator will be run before the `store_mutator`. + pub fn initial_mutator(mut self, mutator: BoxedMutator) -> Self { + assert!( + self.initial_mutator.is_none(), + "initial mutator already set" + ); + self.initial_mutator = Some(mutator); + self + } + + /// This mutator will be run after the `initial_mutator`. + pub fn store_mutator(mut self, mutator: BoxedMutator) -> Self { + assert!(self.store_mutator.is_none(), "store mutator already set"); + self.store_mutator = Some(mutator); + self + } + + /// Purposefully replace the `store_mutator`. + pub fn override_store_mutator(mut self, mutator: BoxedMutator) -> Self { + assert!(self.store_mutator.is_some(), "store mutator not set"); + self.store_mutator = Some(mutator); + self + } + + pub fn chain_config(mut self, chain_config: ChainConfig) -> Self { + self.chain_config = Some(chain_config); + self + } + + pub fn build(self) -> BeaconChainHarness> { + let (shutdown_tx, shutdown_receiver) = futures::channel::mpsc::channel(1); + + let log = test_logger(); + let spec = self.spec.expect("cannot build without spec"); + let validator_keypairs = self + .validator_keypairs + .expect("cannot build without validator keypairs"); + + let mut builder = BeaconChainBuilder::new(self.eth_spec_instance) + .logger(log.clone()) + .custom_spec(spec) + .store(self.store.expect("cannot build without store")) + .store_migrator_config(MigratorConfig::default().blocking()) + .dummy_eth1_backend() + .expect("should build dummy backend") + .shutdown_sender(shutdown_tx) + .chain_config(self.chain_config.unwrap_or_default()) + .event_handler(Some(ServerSentEventHandler::new_with_capacity( + log.clone(), + 5, + ))) + .monitor_validators(true, vec![], log); + + builder = if let Some(mutator) = self.initial_mutator { + mutator(builder) + } else { + builder + }; + + builder = if let Some(mutator) = self.store_mutator { + mutator(builder) + } else { + builder + }; + + // Initialize the slot clock only if it hasn't already been initialized. + builder = if builder.get_slot_clock().is_none() { + builder + .testing_slot_clock(HARNESS_SLOT_TIME) + .expect("should configure testing slot clock") + } else { + builder + }; + + let chain = builder.build().expect("should build"); + + BeaconChainHarness { + spec: chain.spec.clone(), + chain: Arc::new(chain), + validator_keypairs, + shutdown_receiver, + rng: make_rng(), + } + } +} + /// A testing harness which can instantiate a `BeaconChain` and populate it with blocks and /// attestations. /// @@ -158,205 +375,14 @@ pub type HarnessSyncContributions = Vec<( Option>, )>; -impl BeaconChainHarness> { - pub fn new( - eth_spec_instance: E, - spec: Option, - validator_keypairs: Vec, - ) -> Self { - Self::new_with_store_config( - eth_spec_instance, - spec, - validator_keypairs, - StoreConfig::default(), - ) - } - - pub fn new_with_store_config( - eth_spec_instance: E, - spec: Option, - validator_keypairs: Vec, - config: StoreConfig, - ) -> Self { - Self::new_with_chain_config( - eth_spec_instance, - spec, - validator_keypairs, - config, - ChainConfig::default(), - ) - } - - pub fn new_with_chain_config( - eth_spec_instance: E, - spec: Option, - validator_keypairs: Vec, - store_config: StoreConfig, - chain_config: ChainConfig, - ) -> Self { - Self::ephemeral_with_mutator( - eth_spec_instance, - spec, - validator_keypairs, - store_config, - chain_config, - |x| x, - ) - } - - pub fn ephemeral_with_mutator( - eth_spec_instance: E, - spec: Option, - validator_keypairs: Vec, - store_config: StoreConfig, - chain_config: ChainConfig, - mutator: impl FnOnce( - BeaconChainBuilder>, - ) -> BeaconChainBuilder>, - ) -> Self { - let spec = spec.unwrap_or_else(test_spec::); - let log = test_logger(); - let store = Arc::new(HotColdDB::open_ephemeral(store_config, spec.clone(), log).unwrap()); - Self::new_with_mutator( - eth_spec_instance, - spec, - store, - validator_keypairs.clone(), - chain_config, - |mut builder| { - builder = mutator(builder); - let genesis_state = interop_genesis_state::( - &validator_keypairs, - HARNESS_GENESIS_TIME, - builder.get_spec(), - ) - .expect("should generate interop state"); - builder - .genesis_state(genesis_state) - .expect("should build state using recent genesis") - }, - ) - } -} - -impl BeaconChainHarness> { - /// Disk store, start from genesis. - pub fn new_with_disk_store( - eth_spec_instance: E, - spec: Option, - store: Arc, LevelDB>>, - validator_keypairs: Vec, - ) -> Self { - let spec = spec.unwrap_or_else(test_spec::); - - let chain_config = ChainConfig::default(); - - Self::new_with_mutator( - eth_spec_instance, - spec, - store, - validator_keypairs.clone(), - chain_config, - |builder| { - let genesis_state = interop_genesis_state::( - &validator_keypairs, - HARNESS_GENESIS_TIME, - builder.get_spec(), - ) - .expect("should generate interop state"); - builder - .genesis_state(genesis_state) - .expect("should build state using recent genesis") - }, - ) - } - - /// Disk store, resume. - pub fn resume_from_disk_store( - eth_spec_instance: E, - spec: Option, - store: Arc, LevelDB>>, - validator_keypairs: Vec, - ) -> Self { - let spec = spec.unwrap_or_else(test_spec::); - - let chain_config = ChainConfig::default(); - - Self::new_with_mutator( - eth_spec_instance, - spec, - store, - validator_keypairs, - chain_config, - |builder| { - builder - .resume_from_db() - .expect("should resume from database") - }, - ) - } -} - impl BeaconChainHarness> where E: EthSpec, Hot: ItemStore, Cold: ItemStore, { - /// Generic initializer. - /// - /// This initializer should be able to handle almost any configuration via arguments and the - /// provided `mutator` function. Please do not copy and paste this function. - pub fn new_with_mutator( - eth_spec_instance: E, - spec: ChainSpec, - store: Arc>, - validator_keypairs: Vec, - chain_config: ChainConfig, - mutator: impl FnOnce( - BeaconChainBuilder>, - ) -> BeaconChainBuilder>, - ) -> Self { - let (shutdown_tx, shutdown_receiver) = futures::channel::mpsc::channel(1); - - let log = test_logger(); - - let mut builder = BeaconChainBuilder::new(eth_spec_instance) - .logger(log.clone()) - .custom_spec(spec) - .store(store) - .store_migrator_config(MigratorConfig::default().blocking()) - .dummy_eth1_backend() - .expect("should build dummy backend") - .shutdown_sender(shutdown_tx) - .chain_config(chain_config) - .event_handler(Some(ServerSentEventHandler::new_with_capacity( - log.clone(), - 5, - ))) - .monitor_validators(true, vec![], log); - - // Caller must initialize genesis state. - builder = mutator(builder); - - // Initialize the slot clock only if it hasn't already been initialized. - builder = if builder.get_slot_clock().is_none() { - builder - .testing_slot_clock(HARNESS_SLOT_TIME) - .expect("should configure testing slot clock") - } else { - builder - }; - - let chain = builder.build().expect("should build"); - - Self { - spec: chain.spec.clone(), - chain: Arc::new(chain), - validator_keypairs, - shutdown_receiver, - rng: make_rng(), - } + pub fn builder(eth_spec_instance: E) -> Builder> { + Builder::new(eth_spec_instance) } pub fn logger(&self) -> &slog::Logger { diff --git a/beacon_node/beacon_chain/src/validator_pubkey_cache.rs b/beacon_node/beacon_chain/src/validator_pubkey_cache.rs index c1d7ab5d28..2dbe8ce7bf 100644 --- a/beacon_node/beacon_chain/src/validator_pubkey_cache.rs +++ b/beacon_node/beacon_chain/src/validator_pubkey_cache.rs @@ -326,7 +326,7 @@ mod test { use crate::test_utils::{BeaconChainHarness, EphemeralHarnessType}; use logging::test_logger; use std::sync::Arc; - use store::{HotColdDB, StoreConfig}; + use store::HotColdDB; use tempfile::tempdir; use types::{ test_utils::generate_deterministic_keypair, BeaconState, EthSpec, Keypair, MainnetEthSpec, @@ -336,12 +336,11 @@ mod test { type T = EphemeralHarnessType; fn get_state(validator_count: usize) -> (BeaconState, Vec) { - let harness = BeaconChainHarness::new_with_store_config( - MainnetEthSpec, - None, - types::test_utils::generate_deterministic_keypairs(validator_count), - StoreConfig::default(), - ); + let harness = BeaconChainHarness::builder(MainnetEthSpec) + .default_spec() + .deterministic_keypairs(validator_count) + .fresh_ephemeral_store() + .build(); harness.advance_slot(); diff --git a/beacon_node/beacon_chain/tests/attestation_production.rs b/beacon_node/beacon_chain/tests/attestation_production.rs index 38877c99de..d2f564146d 100644 --- a/beacon_node/beacon_chain/tests/attestation_production.rs +++ b/beacon_node/beacon_chain/tests/attestation_production.rs @@ -5,7 +5,6 @@ extern crate lazy_static; use beacon_chain::test_utils::{AttestationStrategy, BeaconChainHarness, BlockStrategy}; use beacon_chain::{StateSkipConfig, WhenSlotSkipped}; -use store::config::StoreConfig; use tree_hash::TreeHash; use types::{AggregateSignature, EthSpec, Keypair, MainnetEthSpec, RelativeEpoch, Slot}; @@ -25,12 +24,11 @@ fn produces_attestations() { let num_blocks_produced = MainnetEthSpec::slots_per_epoch() * 4; let additional_slots_tested = MainnetEthSpec::slots_per_epoch() * 3; - let harness = BeaconChainHarness::new_with_store_config( - MainnetEthSpec, - None, - KEYPAIRS[..].to_vec(), - StoreConfig::default(), - ); + let harness = BeaconChainHarness::builder(MainnetEthSpec) + .default_spec() + .keypairs(KEYPAIRS[..].to_vec()) + .fresh_ephemeral_store() + .build(); let chain = &harness.chain; diff --git a/beacon_node/beacon_chain/tests/attestation_verification.rs b/beacon_node/beacon_chain/tests/attestation_verification.rs index 26aca88f8c..45d316e3d3 100644 --- a/beacon_node/beacon_chain/tests/attestation_verification.rs +++ b/beacon_node/beacon_chain/tests/attestation_verification.rs @@ -14,7 +14,6 @@ use int_to_bytes::int_to_bytes32; use state_processing::{ per_block_processing::errors::AttestationValidationError, per_slot_processing, }; -use store::config::StoreConfig; use tree_hash::TreeHash; use types::{ test_utils::generate_deterministic_keypair, AggregateSignature, Attestation, BeaconStateError, @@ -41,12 +40,11 @@ fn get_harness(validator_count: usize) -> BeaconChainHarness Vec> { } fn get_harness(validator_count: usize) -> BeaconChainHarness> { - let harness = BeaconChainHarness::new_with_store_config( - MainnetEthSpec, - None, - KEYPAIRS[0..validator_count].to_vec(), - StoreConfig::default(), - ); + let harness = BeaconChainHarness::builder(MainnetEthSpec) + .default_spec() + .keypairs(KEYPAIRS[0..validator_count].to_vec()) + .fresh_ephemeral_store() + .build(); harness.advance_slot(); @@ -841,14 +839,13 @@ fn verify_block_for_gossip_slashing_detection() { .unwrap(), ); - let harness = BeaconChainHarness::ephemeral_with_mutator( - MainnetEthSpec, - None, - KEYPAIRS.to_vec(), - StoreConfig::default(), - ChainConfig::default(), - |builder| builder.slasher(slasher.clone()), - ); + let inner_slasher = slasher.clone(); + let harness = BeaconChainHarness::builder(MainnetEthSpec) + .default_spec() + .keypairs(KEYPAIRS.to_vec()) + .fresh_ephemeral_store() + .initial_mutator(Box::new(move |builder| builder.slasher(inner_slasher))) + .build(); harness.advance_slot(); let state = harness.get_current_state(); @@ -923,13 +920,11 @@ fn add_base_block_to_altair_chain() { // The Altair fork happens at epoch 1. spec.altair_fork_epoch = Some(Epoch::new(1)); - let harness = BeaconChainHarness::new_with_chain_config( - MainnetEthSpec, - Some(spec), - KEYPAIRS[..].to_vec(), - StoreConfig::default(), - ChainConfig::default(), - ); + let harness = BeaconChainHarness::builder(MainnetEthSpec) + .spec(spec) + .keypairs(KEYPAIRS[..].to_vec()) + .fresh_ephemeral_store() + .build(); // Move out of the genesis slot. harness.advance_slot(); @@ -1042,13 +1037,11 @@ fn add_altair_block_to_base_chain() { // Altair never happens. spec.altair_fork_epoch = None; - let harness = BeaconChainHarness::new_with_chain_config( - MainnetEthSpec, - Some(spec), - KEYPAIRS[..].to_vec(), - StoreConfig::default(), - ChainConfig::default(), - ); + let harness = BeaconChainHarness::builder(MainnetEthSpec) + .spec(spec) + .keypairs(KEYPAIRS[..].to_vec()) + .fresh_ephemeral_store() + .build(); // Move out of the genesis slot. harness.advance_slot(); diff --git a/beacon_node/beacon_chain/tests/op_verification.rs b/beacon_node/beacon_chain/tests/op_verification.rs index 34ee8483b4..56e76cffe5 100644 --- a/beacon_node/beacon_chain/tests/op_verification.rs +++ b/beacon_node/beacon_chain/tests/op_verification.rs @@ -38,12 +38,11 @@ fn get_store(db_path: &TempDir) -> Arc { } fn get_harness(store: Arc, validator_count: usize) -> TestHarness { - let harness = BeaconChainHarness::new_with_disk_store( - MinimalEthSpec, - None, - store, - KEYPAIRS[0..validator_count].to_vec(), - ); + let harness = BeaconChainHarness::builder(MinimalEthSpec) + .default_spec() + .keypairs(KEYPAIRS[0..validator_count].to_vec()) + .fresh_disk_store(store) + .build(); harness.advance_slot(); harness } diff --git a/beacon_node/beacon_chain/tests/store_tests.rs b/beacon_node/beacon_chain/tests/store_tests.rs index afc14dce7b..8a2412b2fa 100644 --- a/beacon_node/beacon_chain/tests/store_tests.rs +++ b/beacon_node/beacon_chain/tests/store_tests.rs @@ -61,12 +61,11 @@ fn get_harness( store: Arc, LevelDB>>, validator_count: usize, ) -> TestHarness { - let harness = BeaconChainHarness::new_with_disk_store( - MinimalEthSpec, - None, - store, - KEYPAIRS[0..validator_count].to_vec(), - ); + let harness = BeaconChainHarness::builder(MinimalEthSpec) + .default_spec() + .keypairs(KEYPAIRS[0..validator_count].to_vec()) + .fresh_disk_store(store) + .build(); harness.advance_slot(); harness } @@ -365,12 +364,11 @@ fn delete_blocks_and_states() { let store = get_store(&db_path); let validators_keypairs = types::test_utils::generate_deterministic_keypairs(LOW_VALIDATOR_COUNT); - let harness = BeaconChainHarness::new_with_disk_store( - MinimalEthSpec, - None, - store.clone(), - validators_keypairs, - ); + let harness = BeaconChainHarness::builder(MinimalEthSpec) + .default_spec() + .keypairs(validators_keypairs) + .fresh_disk_store(store.clone()) + .build(); let unforked_blocks: u64 = 4 * E::slots_per_epoch(); @@ -492,8 +490,11 @@ fn multi_epoch_fork_valid_blocks_test( let store = get_store(&db_path); let validators_keypairs = types::test_utils::generate_deterministic_keypairs(LOW_VALIDATOR_COUNT); - let harness = - BeaconChainHarness::new_with_disk_store(MinimalEthSpec, None, store, validators_keypairs); + let harness = BeaconChainHarness::builder(MinimalEthSpec) + .default_spec() + .keypairs(validators_keypairs) + .fresh_disk_store(store) + .build(); let num_fork1_blocks: u64 = num_fork1_blocks_.try_into().unwrap(); let num_fork2_blocks: u64 = num_fork2_blocks_.try_into().unwrap(); @@ -783,7 +784,11 @@ fn prunes_abandoned_fork_between_two_finalized_checkpoints() { let validators_keypairs = types::test_utils::generate_deterministic_keypairs(VALIDATOR_COUNT); let honest_validators: Vec = (0..HONEST_VALIDATOR_COUNT).collect(); let adversarial_validators: Vec = (HONEST_VALIDATOR_COUNT..VALIDATOR_COUNT).collect(); - let rig = BeaconChainHarness::new(MinimalEthSpec, None, validators_keypairs); + let rig = BeaconChainHarness::builder(MinimalEthSpec) + .default_spec() + .keypairs(validators_keypairs) + .fresh_ephemeral_store() + .build(); let slots_per_epoch = rig.slots_per_epoch(); let (mut state, state_root) = rig.get_current_state_and_root(); @@ -888,7 +893,11 @@ fn pruning_does_not_touch_abandoned_block_shared_with_canonical_chain() { let validators_keypairs = types::test_utils::generate_deterministic_keypairs(VALIDATOR_COUNT); let honest_validators: Vec = (0..HONEST_VALIDATOR_COUNT).collect(); let adversarial_validators: Vec = (HONEST_VALIDATOR_COUNT..VALIDATOR_COUNT).collect(); - let rig = BeaconChainHarness::new(MinimalEthSpec, None, validators_keypairs); + let rig = BeaconChainHarness::builder(MinimalEthSpec) + .default_spec() + .keypairs(validators_keypairs) + .fresh_ephemeral_store() + .build(); let slots_per_epoch = rig.slots_per_epoch(); let (state, state_root) = rig.get_current_state_and_root(); @@ -1013,7 +1022,11 @@ fn pruning_does_not_touch_blocks_prior_to_finalization() { let validators_keypairs = types::test_utils::generate_deterministic_keypairs(VALIDATOR_COUNT); let honest_validators: Vec = (0..HONEST_VALIDATOR_COUNT).collect(); let adversarial_validators: Vec = (HONEST_VALIDATOR_COUNT..VALIDATOR_COUNT).collect(); - let rig = BeaconChainHarness::new(MinimalEthSpec, None, validators_keypairs); + let rig = BeaconChainHarness::builder(MinimalEthSpec) + .default_spec() + .keypairs(validators_keypairs) + .fresh_ephemeral_store() + .build(); let slots_per_epoch = rig.slots_per_epoch(); let (mut state, state_root) = rig.get_current_state_and_root(); @@ -1103,7 +1116,11 @@ fn prunes_fork_growing_past_youngest_finalized_checkpoint() { let validators_keypairs = types::test_utils::generate_deterministic_keypairs(VALIDATOR_COUNT); let honest_validators: Vec = (0..HONEST_VALIDATOR_COUNT).collect(); let adversarial_validators: Vec = (HONEST_VALIDATOR_COUNT..VALIDATOR_COUNT).collect(); - let rig = BeaconChainHarness::new(MinimalEthSpec, None, validators_keypairs); + let rig = BeaconChainHarness::builder(MinimalEthSpec) + .default_spec() + .keypairs(validators_keypairs) + .fresh_ephemeral_store() + .build(); let (state, state_root) = rig.get_current_state_and_root(); // Fill up 0th epoch with canonical chain blocks @@ -1241,7 +1258,11 @@ fn prunes_skipped_slots_states() { let validators_keypairs = types::test_utils::generate_deterministic_keypairs(VALIDATOR_COUNT); let honest_validators: Vec = (0..HONEST_VALIDATOR_COUNT).collect(); let adversarial_validators: Vec = (HONEST_VALIDATOR_COUNT..VALIDATOR_COUNT).collect(); - let rig = BeaconChainHarness::new(MinimalEthSpec, None, validators_keypairs); + let rig = BeaconChainHarness::builder(MinimalEthSpec) + .default_spec() + .keypairs(validators_keypairs) + .fresh_ephemeral_store() + .build(); let (state, state_root) = rig.get_current_state_and_root(); let canonical_slots_zeroth_epoch: Vec = @@ -1360,7 +1381,11 @@ fn finalizes_non_epoch_start_slot() { let validators_keypairs = types::test_utils::generate_deterministic_keypairs(VALIDATOR_COUNT); let honest_validators: Vec = (0..HONEST_VALIDATOR_COUNT).collect(); let adversarial_validators: Vec = (HONEST_VALIDATOR_COUNT..VALIDATOR_COUNT).collect(); - let rig = BeaconChainHarness::new(MinimalEthSpec, None, validators_keypairs); + let rig = BeaconChainHarness::builder(MinimalEthSpec) + .default_spec() + .keypairs(validators_keypairs) + .fresh_ephemeral_store() + .build(); let (state, state_root) = rig.get_current_state_and_root(); let canonical_slots_zeroth_epoch: Vec = @@ -1923,12 +1948,11 @@ fn finalizes_after_resuming_from_db() { let db_path = tempdir().unwrap(); let store = get_store(&db_path); - let harness = BeaconChainHarness::new_with_disk_store( - MinimalEthSpec, - None, - store.clone(), - KEYPAIRS[0..validator_count].to_vec(), - ); + let harness = BeaconChainHarness::builder(MinimalEthSpec) + .default_spec() + .keypairs(KEYPAIRS[0..validator_count].to_vec()) + .fresh_disk_store(store.clone()) + .build(); harness.advance_slot(); @@ -1967,12 +1991,11 @@ fn finalizes_after_resuming_from_db() { let original_chain = harness.chain; - let resumed_harness = BeaconChainHarness::resume_from_disk_store( - MinimalEthSpec, - None, - store, - KEYPAIRS[0..validator_count].to_vec(), - ); + let resumed_harness = BeaconChainHarness::builder(MinimalEthSpec) + .default_spec() + .keypairs(KEYPAIRS[0..validator_count].to_vec()) + .resumed_disk_store(store) + .build(); assert_chains_pretty_much_the_same(&original_chain, &resumed_harness.chain); @@ -2037,22 +2060,20 @@ fn revert_minority_fork_on_resume() { // Chain with no fork epoch configured. let db_path1 = tempdir().unwrap(); let store1 = get_store_with_spec(&db_path1, spec1.clone()); - let harness1 = BeaconChainHarness::new_with_disk_store( - MinimalEthSpec, - Some(spec1), - store1, - KEYPAIRS[0..validator_count].to_vec(), - ); + let harness1 = BeaconChainHarness::builder(MinimalEthSpec) + .spec(spec1) + .keypairs(KEYPAIRS[0..validator_count].to_vec()) + .fresh_disk_store(store1) + .build(); // Chain with fork epoch configured. let db_path2 = tempdir().unwrap(); let store2 = get_store_with_spec(&db_path2, spec2.clone()); - let harness2 = BeaconChainHarness::new_with_disk_store( - MinimalEthSpec, - Some(spec2.clone()), - store2, - KEYPAIRS[0..validator_count].to_vec(), - ); + let harness2 = BeaconChainHarness::builder(MinimalEthSpec) + .spec(spec2.clone()) + .keypairs(KEYPAIRS[0..validator_count].to_vec()) + .fresh_disk_store(store2) + .build(); // Apply the same blocks to both chains initially. let mut state = harness1.get_current_state(); @@ -2130,13 +2151,12 @@ fn revert_minority_fork_on_resume() { // the beacon chain builder loads the head block. drop(harness1); let resume_store = get_store_with_spec(&db_path1, spec2.clone()); - let resumed_harness = BeaconChainHarness::new_with_mutator( - MinimalEthSpec, - spec2, - resume_store, - KEYPAIRS[0..validator_count].to_vec(), - ChainConfig::default(), - |mut builder| { + + let resumed_harness = BeaconChainHarness::builder(MinimalEthSpec) + .spec(spec2) + .keypairs(KEYPAIRS[0..validator_count].to_vec()) + .resumed_disk_store(resume_store) + .override_store_mutator(Box::new(move |mut builder| { builder = builder .resume_from_db() .unwrap() @@ -2147,8 +2167,8 @@ fn revert_minority_fork_on_resume() { .unwrap() .set_slot(end_slot.as_u64()); builder - }, - ); + })) + .build(); // Head should now be just before the fork. resumed_harness.chain.fork_choice().unwrap(); diff --git a/beacon_node/beacon_chain/tests/sync_committee_verification.rs b/beacon_node/beacon_chain/tests/sync_committee_verification.rs index beeea37e62..7326a02f46 100644 --- a/beacon_node/beacon_chain/tests/sync_committee_verification.rs +++ b/beacon_node/beacon_chain/tests/sync_committee_verification.rs @@ -28,11 +28,11 @@ lazy_static! { fn get_harness(validator_count: usize) -> BeaconChainHarness> { let mut spec = E::default_spec(); spec.altair_fork_epoch = Some(Epoch::new(0)); - let harness = BeaconChainHarness::new( - MainnetEthSpec, - Some(spec), - KEYPAIRS[0..validator_count].to_vec(), - ); + let harness = BeaconChainHarness::builder(MainnetEthSpec) + .spec(spec) + .keypairs(KEYPAIRS[0..validator_count].to_vec()) + .fresh_ephemeral_store() + .build(); harness.advance_slot(); diff --git a/beacon_node/beacon_chain/tests/tests.rs b/beacon_node/beacon_chain/tests/tests.rs index f4399ed374..5b85da5bf8 100644 --- a/beacon_node/beacon_chain/tests/tests.rs +++ b/beacon_node/beacon_chain/tests/tests.rs @@ -15,7 +15,6 @@ use operation_pool::PersistedOperationPool; use state_processing::{ per_slot_processing, per_slot_processing::Error as SlotProcessingError, EpochProcessingError, }; -use store::config::StoreConfig; use types::{BeaconStateError, EthSpec, Hash256, Keypair, MinimalEthSpec, RelativeEpoch, Slot}; // Should ideally be divisible by 3. @@ -27,12 +26,11 @@ lazy_static! { } fn get_harness(validator_count: usize) -> BeaconChainHarness> { - let harness = BeaconChainHarness::new_with_store_config( - MinimalEthSpec, - None, - KEYPAIRS[0..validator_count].to_vec(), - StoreConfig::default(), - ); + let harness = BeaconChainHarness::builder(MinimalEthSpec) + .default_spec() + .keypairs(KEYPAIRS[0..validator_count].to_vec()) + .fresh_ephemeral_store() + .build(); harness.advance_slot(); diff --git a/beacon_node/http_api/tests/common.rs b/beacon_node/http_api/tests/common.rs index 04224b8471..a2298276c0 100644 --- a/beacon_node/http_api/tests/common.rs +++ b/beacon_node/http_api/tests/common.rs @@ -18,7 +18,7 @@ use std::net::{Ipv4Addr, SocketAddr}; use std::sync::Arc; use std::time::Duration; use tokio::sync::{mpsc, oneshot}; -use types::{test_utils::generate_deterministic_keypairs, ChainSpec, EthSpec}; +use types::{ChainSpec, EthSpec}; pub const TCP_PORT: u16 = 42; pub const UDP_PORT: u16 = 42; @@ -47,11 +47,11 @@ pub struct ApiServer> { impl InteractiveTester { pub async fn new(spec: Option, validator_count: usize) -> Self { - let harness = BeaconChainHarness::new( - E::default(), - spec, - generate_deterministic_keypairs(validator_count), - ); + let harness = BeaconChainHarness::builder(E::default()) + .spec_or_default(spec) + .deterministic_keypairs(validator_count) + .fresh_ephemeral_store() + .build(); let ApiServer { server, diff --git a/beacon_node/http_api/tests/tests.rs b/beacon_node/http_api/tests/tests.rs index 86762aeb42..df7af8cc4a 100644 --- a/beacon_node/http_api/tests/tests.rs +++ b/beacon_node/http_api/tests/tests.rs @@ -21,8 +21,8 @@ use tokio::sync::{mpsc, oneshot}; use tokio::time::Duration; use tree_hash::TreeHash; use types::{ - test_utils::generate_deterministic_keypairs, AggregateSignature, BeaconState, BitList, Domain, - EthSpec, Hash256, Keypair, MainnetEthSpec, RelativeEpoch, SelectionProof, SignedRoot, Slot, + AggregateSignature, BeaconState, BitList, Domain, EthSpec, Hash256, Keypair, MainnetEthSpec, + RelativeEpoch, SelectionProof, SignedRoot, Slot, }; type E = MainnetEthSpec; @@ -71,11 +71,11 @@ impl ApiTester { } pub async fn new_from_spec(spec: ChainSpec) -> Self { - let harness = BeaconChainHarness::new( - MainnetEthSpec, - Some(spec.clone()), - generate_deterministic_keypairs(VALIDATOR_COUNT), - ); + let harness = BeaconChainHarness::builder(MainnetEthSpec) + .spec(spec.clone()) + .deterministic_keypairs(VALIDATOR_COUNT) + .fresh_ephemeral_store() + .build(); harness.advance_slot(); @@ -214,11 +214,11 @@ impl ApiTester { } pub async fn new_from_genesis() -> Self { - let harness = BeaconChainHarness::new( - MainnetEthSpec, - None, - generate_deterministic_keypairs(VALIDATOR_COUNT), - ); + let harness = BeaconChainHarness::builder(MainnetEthSpec) + .default_spec() + .deterministic_keypairs(VALIDATOR_COUNT) + .fresh_ephemeral_store() + .build(); harness.advance_slot(); diff --git a/beacon_node/network/src/beacon_processor/tests.rs b/beacon_node/network/src/beacon_processor/tests.rs index 5b67d35555..de55901441 100644 --- a/beacon_node/network/src/beacon_processor/tests.rs +++ b/beacon_node/network/src/beacon_processor/tests.rs @@ -23,8 +23,8 @@ use std::time::Duration; use tokio::runtime::Runtime; use tokio::sync::mpsc; use types::{ - test_utils::generate_deterministic_keypairs, Attestation, AttesterSlashing, EthSpec, - MainnetEthSpec, ProposerSlashing, SignedBeaconBlock, SignedVoluntaryExit, SubnetId, + Attestation, AttesterSlashing, EthSpec, MainnetEthSpec, ProposerSlashing, SignedBeaconBlock, + SignedVoluntaryExit, SubnetId, }; type E = MainnetEthSpec; @@ -75,11 +75,11 @@ impl TestRig { let mut spec = E::default_spec(); spec.shard_committee_period = 2; - let harness = BeaconChainHarness::new( - MainnetEthSpec, - Some(spec), - generate_deterministic_keypairs(VALIDATOR_COUNT), - ); + let harness = BeaconChainHarness::builder(MainnetEthSpec) + .spec(spec) + .deterministic_keypairs(VALIDATOR_COUNT) + .fresh_ephemeral_store() + .build(); harness.advance_slot(); diff --git a/beacon_node/network/src/service/tests.rs b/beacon_node/network/src/service/tests.rs index db61d2a88c..f9e861a91d 100644 --- a/beacon_node/network/src/service/tests.rs +++ b/beacon_node/network/src/service/tests.rs @@ -9,9 +9,8 @@ mod tests { use sloggers::{null::NullLoggerBuilder, Build}; use std::str::FromStr; use std::sync::Arc; - use store::config::StoreConfig; use tokio::runtime::Runtime; - use types::{test_utils::generate_deterministic_keypairs, MinimalEthSpec}; + use types::MinimalEthSpec; fn get_logger(actual_log: bool) -> Logger { if actual_log { @@ -35,13 +34,12 @@ mod tests { fn test_dht_persistence() { let log = get_logger(false); - let beacon_chain = BeaconChainHarness::new_with_store_config( - MinimalEthSpec, - None, - generate_deterministic_keypairs(8), - StoreConfig::default(), - ) - .chain; + let beacon_chain = BeaconChainHarness::builder(MinimalEthSpec) + .default_spec() + .deterministic_keypairs(8) + .fresh_ephemeral_store() + .build() + .chain; let store = beacon_chain.store.clone(); diff --git a/beacon_node/operation_pool/src/lib.rs b/beacon_node/operation_pool/src/lib.rs index 6609c5ac7e..dad375b32f 100644 --- a/beacon_node/operation_pool/src/lib.rs +++ b/beacon_node/operation_pool/src/lib.rs @@ -632,8 +632,11 @@ mod release_tests { validator_count: usize, spec: Option, ) -> BeaconChainHarness> { - let harness = - BeaconChainHarness::new(E::default(), spec, KEYPAIRS[0..validator_count].to_vec()); + let harness = BeaconChainHarness::builder(E::default()) + .spec_or_default(spec) + .keypairs(KEYPAIRS[0..validator_count].to_vec()) + .fresh_ephemeral_store() + .build(); harness.advance_slot(); diff --git a/beacon_node/store/src/iter.rs b/beacon_node/store/src/iter.rs index 6735b4ff7d..8b11a6cc9c 100644 --- a/beacon_node/store/src/iter.rs +++ b/beacon_node/store/src/iter.rs @@ -371,18 +371,16 @@ mod test { use super::*; use crate::HotColdDB; use crate::StoreConfig as Config; - use beacon_chain::store::StoreConfig; use beacon_chain::test_utils::BeaconChainHarness; - use beacon_chain::types::{ChainSpec, Keypair, MainnetEthSpec}; + use beacon_chain::types::{ChainSpec, MainnetEthSpec}; use sloggers::{null::NullLoggerBuilder, Build}; fn get_state() -> BeaconState { - let harness = BeaconChainHarness::new_with_store_config( - T::default(), - None, - vec![Keypair::random()], - StoreConfig::default(), - ); + let harness = BeaconChainHarness::builder(T::default()) + .default_spec() + .deterministic_keypairs(1) + .fresh_ephemeral_store() + .build(); harness.advance_slot(); harness.get_current_state() } diff --git a/consensus/fork_choice/tests/tests.rs b/consensus/fork_choice/tests/tests.rs index f299de1b6f..08b098707f 100644 --- a/consensus/fork_choice/tests/tests.rs +++ b/consensus/fork_choice/tests/tests.rs @@ -14,11 +14,10 @@ use fork_choice::{ ForkChoiceStore, InvalidAttestation, InvalidBlock, QueuedAttestation, SAFE_SLOTS_TO_UPDATE_JUSTIFIED, }; -use store::{MemoryStore, StoreConfig}; +use store::MemoryStore; use types::{ - test_utils::{generate_deterministic_keypair, generate_deterministic_keypairs}, - BeaconBlock, BeaconBlockRef, BeaconState, Checkpoint, Epoch, EthSpec, Hash256, - IndexedAttestation, MainnetEthSpec, Slot, SubnetId, + test_utils::generate_deterministic_keypair, BeaconBlock, BeaconBlockRef, BeaconState, + Checkpoint, Epoch, EthSpec, Hash256, IndexedAttestation, MainnetEthSpec, Slot, SubnetId, }; pub type E = MainnetEthSpec; @@ -48,25 +47,23 @@ impl fmt::Debug for ForkChoiceTest { impl ForkChoiceTest { /// Creates a new tester. pub fn new() -> Self { - let harness = BeaconChainHarness::new_with_store_config( - MainnetEthSpec, - None, - generate_deterministic_keypairs(VALIDATOR_COUNT), - StoreConfig::default(), - ); + let harness = BeaconChainHarness::builder(MainnetEthSpec) + .default_spec() + .deterministic_keypairs(VALIDATOR_COUNT) + .fresh_ephemeral_store() + .build(); Self { harness } } /// Creates a new tester with a custom chain config. pub fn new_with_chain_config(chain_config: ChainConfig) -> Self { - let harness = BeaconChainHarness::new_with_chain_config( - MainnetEthSpec, - None, - generate_deterministic_keypairs(VALIDATOR_COUNT), - StoreConfig::default(), - chain_config, - ); + let harness = BeaconChainHarness::builder(MainnetEthSpec) + .default_spec() + .chain_config(chain_config) + .deterministic_keypairs(VALIDATOR_COUNT) + .fresh_ephemeral_store() + .build(); Self { harness } } diff --git a/consensus/state_processing/src/per_block_processing/tests.rs b/consensus/state_processing/src/per_block_processing/tests.rs index fe1537a50d..78c034caac 100644 --- a/consensus/state_processing/src/per_block_processing/tests.rs +++ b/consensus/state_processing/src/per_block_processing/tests.rs @@ -7,7 +7,6 @@ use crate::per_block_processing::errors::{ ProposerSlashingInvalid, }; use crate::{per_block_processing::process_operations, BlockSignatureStrategy, VerifySignatures}; -use beacon_chain::store::StoreConfig; use beacon_chain::test_utils::{BeaconChainHarness, EphemeralHarnessType}; use lazy_static::lazy_static; use ssz_types::Bitfield; @@ -32,12 +31,11 @@ fn get_harness( // Set the state and block to be in the last slot of the `epoch_offset`th epoch. let last_slot_of_epoch = (MainnetEthSpec::genesis_epoch() + epoch_offset).end_slot(E::slots_per_epoch()); - let harness = BeaconChainHarness::new_with_store_config( - E::default(), - None, - KEYPAIRS[0..num_validators].to_vec(), - StoreConfig::default(), - ); + let harness = BeaconChainHarness::builder(E::default()) + .default_spec() + .keypairs(KEYPAIRS[0..num_validators].to_vec()) + .fresh_ephemeral_store() + .build(); let state = harness.get_current_state(); if last_slot_of_epoch > Slot::new(0) { harness.add_attested_blocks_at_slots( diff --git a/consensus/state_processing/src/per_epoch_processing/tests.rs b/consensus/state_processing/src/per_epoch_processing/tests.rs index ac1ce6b019..4379547bfe 100644 --- a/consensus/state_processing/src/per_epoch_processing/tests.rs +++ b/consensus/state_processing/src/per_epoch_processing/tests.rs @@ -1,6 +1,5 @@ #![cfg(test)] use crate::per_epoch_processing::process_epoch; -use beacon_chain::store::StoreConfig; use beacon_chain::test_utils::BeaconChainHarness; use beacon_chain::types::{EthSpec, MinimalEthSpec}; use bls::Hash256; @@ -11,12 +10,11 @@ use types::Slot; fn runs_without_error() { Builder::from_env(Env::default().default_filter_or("error")).init(); - let harness = BeaconChainHarness::new_with_store_config( - MinimalEthSpec, - None, - types::test_utils::generate_deterministic_keypairs(8), - StoreConfig::default(), - ); + let harness = BeaconChainHarness::builder(MinimalEthSpec) + .default_spec() + .deterministic_keypairs(8) + .fresh_ephemeral_store() + .build(); harness.advance_slot(); let spec = MinimalEthSpec::default_spec(); @@ -55,11 +53,11 @@ mod release_tests { spec.altair_fork_epoch = Some(Epoch::new(1)); let altair_state = { - let harness = BeaconChainHarness::new( - MainnetEthSpec, - Some(spec.clone()), - types::test_utils::generate_deterministic_keypairs(8), - ); + let harness = BeaconChainHarness::builder(MainnetEthSpec) + .spec(spec.clone()) + .deterministic_keypairs(8) + .fresh_ephemeral_store() + .build(); harness.advance_slot(); @@ -113,11 +111,11 @@ mod release_tests { spec.altair_fork_epoch = None; let base_state = { - let harness = BeaconChainHarness::new( - MainnetEthSpec, - Some(spec.clone()), - types::test_utils::generate_deterministic_keypairs(8), - ); + let harness = BeaconChainHarness::builder(MainnetEthSpec) + .spec(spec.clone()) + .deterministic_keypairs(8) + .fresh_ephemeral_store() + .build(); harness.advance_slot(); diff --git a/consensus/tree_hash/examples/flamegraph_beacon_state.rs b/consensus/tree_hash/examples/flamegraph_beacon_state.rs index 309c2a2cc1..cb9fc9390a 100644 --- a/consensus/tree_hash/examples/flamegraph_beacon_state.rs +++ b/consensus/tree_hash/examples/flamegraph_beacon_state.rs @@ -1,4 +1,3 @@ -use beacon_chain::store::StoreConfig; use beacon_chain::test_utils::{BeaconChainHarness, EphemeralHarnessType}; use types::{BeaconState, EthSpec, MainnetEthSpec}; @@ -6,12 +5,11 @@ const TREE_HASH_LOOPS: usize = 1_000; const VALIDATOR_COUNT: usize = 1_000; fn get_harness() -> BeaconChainHarness> { - let harness = BeaconChainHarness::new_with_store_config( - T::default(), - None, - types::test_utils::generate_deterministic_keypairs(VALIDATOR_COUNT), - StoreConfig::default(), - ); + let harness = BeaconChainHarness::builder(T::default()) + .default_spec() + .deterministic_keypairs(VALIDATOR_COUNT) + .fresh_ephemeral_store() + .build(); harness.advance_slot(); diff --git a/consensus/types/src/beacon_state/committee_cache/tests.rs b/consensus/types/src/beacon_state/committee_cache/tests.rs index f6799e0fd0..48998e26d0 100644 --- a/consensus/types/src/beacon_state/committee_cache/tests.rs +++ b/consensus/types/src/beacon_state/committee_cache/tests.rs @@ -1,6 +1,5 @@ #![cfg(test)] use crate::test_utils::*; -use beacon_chain::store::StoreConfig; use beacon_chain::test_utils::{BeaconChainHarness, EphemeralHarnessType}; use beacon_chain::types::*; use swap_or_not_shuffle::shuffle_list; @@ -13,12 +12,11 @@ lazy_static! { } fn get_harness(validator_count: usize) -> BeaconChainHarness> { - let harness = BeaconChainHarness::new_with_store_config( - E::default(), - None, - KEYPAIRS[0..validator_count].to_vec(), - StoreConfig::default(), - ); + let harness = BeaconChainHarness::builder(E::default()) + .default_spec() + .keypairs(KEYPAIRS[0..validator_count].to_vec()) + .fresh_ephemeral_store() + .build(); harness.advance_slot(); harness } diff --git a/consensus/types/src/beacon_state/tests.rs b/consensus/types/src/beacon_state/tests.rs index f8f2447aaf..d8b6c796c0 100644 --- a/consensus/types/src/beacon_state/tests.rs +++ b/consensus/types/src/beacon_state/tests.rs @@ -1,7 +1,6 @@ #![cfg(test)] use crate::test_utils::*; use crate::test_utils::{SeedableRng, XorShiftRng}; -use beacon_chain::store::config::StoreConfig; use beacon_chain::test_utils::{ interop_genesis_state, test_spec, BeaconChainHarness, EphemeralHarnessType, }; @@ -29,12 +28,11 @@ fn get_harness( validator_count: usize, slot: Slot, ) -> BeaconChainHarness> { - let harness = BeaconChainHarness::new_with_store_config( - E::default(), - None, - KEYPAIRS[0..validator_count].to_vec(), - StoreConfig::default(), - ); + let harness = BeaconChainHarness::builder(E::default()) + .default_spec() + .keypairs(KEYPAIRS[0..validator_count].to_vec()) + .fresh_ephemeral_store() + .build(); let skip_to_slot = slot - SLOT_OFFSET; if skip_to_slot > Slot::new(0) { diff --git a/testing/state_transition_vectors/src/main.rs b/testing/state_transition_vectors/src/main.rs index 2512b03e5b..d66842e5a1 100644 --- a/testing/state_transition_vectors/src/main.rs +++ b/testing/state_transition_vectors/src/main.rs @@ -2,10 +2,7 @@ mod macros; mod exit; -use beacon_chain::{ - store::StoreConfig, - test_utils::{BeaconChainHarness, EphemeralHarnessType}, -}; +use beacon_chain::test_utils::{BeaconChainHarness, EphemeralHarnessType}; use lazy_static::lazy_static; use ssz::Encode; use std::env; @@ -56,12 +53,11 @@ fn get_harness( slot: Slot, validator_count: usize, ) -> BeaconChainHarness> { - let harness = BeaconChainHarness::new_with_store_config( - E::default(), - None, - KEYPAIRS[0..validator_count].to_vec(), - StoreConfig::default(), - ); + let harness = BeaconChainHarness::builder(E::default()) + .default_spec() + .keypairs(KEYPAIRS[0..validator_count].to_vec()) + .fresh_ephemeral_store() + .build(); let skip_to_slot = slot - SLOT_OFFSET; if skip_to_slot > Slot::new(0) { let state = harness.get_current_state();