From 1447eeb40b2f3987c290e60c8e24d8c70c525fe2 Mon Sep 17 00:00:00 2001 From: Michael Sproul Date: Tue, 24 Sep 2024 10:16:18 +1000 Subject: [PATCH] Improve single-node testnet support and Arc NetworkConfig/ChainSpec (#6396) * Arc ChainSpec and NetworkConfig * Fix release tests * Fix lint * Merge remote-tracking branch 'origin/unstable' into single-node-testnet --- .../beacon_chain/src/beacon_block_streamer.rs | 4 +- beacon_node/beacon_chain/src/beacon_chain.rs | 2 +- beacon_node/beacon_chain/src/builder.rs | 14 +++-- .../src/data_availability_checker.rs | 3 +- .../overflow_lru_cache.rs | 5 +- beacon_node/beacon_chain/src/eth1_chain.rs | 14 +++-- .../beacon_chain/src/graffiti_calculator.rs | 9 +-- .../src/observed_data_sidecars.rs | 9 +-- beacon_node/beacon_chain/src/test_utils.rs | 10 ++-- .../src/validator_pubkey_cache.rs | 3 +- .../tests/attestation_verification.rs | 6 +- beacon_node/beacon_chain/tests/bellatrix.rs | 4 +- .../beacon_chain/tests/block_verification.rs | 6 +- beacon_node/beacon_chain/tests/capella.rs | 2 +- beacon_node/beacon_chain/tests/events.rs | 4 +- .../beacon_chain/tests/op_verification.rs | 2 +- .../tests/payload_invalidation.rs | 2 +- beacon_node/beacon_chain/tests/rewards.rs | 2 +- beacon_node/beacon_chain/tests/store_tests.rs | 14 ++--- .../tests/sync_committee_verification.rs | 2 +- beacon_node/client/src/builder.rs | 13 ++--- beacon_node/eth1/src/inner.rs | 7 ++- beacon_node/eth1/src/service.rs | 10 +++- beacon_node/eth1/tests/test.rs | 39 ++++++++----- .../src/test_utils/mock_builder.rs | 6 +- .../genesis/src/eth1_genesis_service.rs | 10 ++-- beacon_node/genesis/tests/tests.rs | 12 ++-- beacon_node/http_api/src/lib.rs | 12 +++- beacon_node/http_api/src/test_utils.rs | 6 +- beacon_node/http_api/tests/tests.rs | 2 +- .../lighthouse_network/src/discovery/mod.rs | 4 +- .../src/peer_manager/mod.rs | 23 +++----- .../lighthouse_network/src/service/mod.rs | 7 ++- .../lighthouse_network/src/service/utils.rs | 4 +- .../lighthouse_network/src/types/globals.rs | 48 +++++++++++----- .../src/types/sync_state.rs | 8 +++ .../lighthouse_network/tests/common.rs | 24 ++++---- .../lighthouse_network/tests/rpc_tests.rs | 40 ++++++-------- .../src/network_beacon_processor/tests.rs | 5 +- beacon_node/network/src/persisted_dht.rs | 3 +- beacon_node/network/src/service.rs | 12 ++-- beacon_node/network/src/service/tests.rs | 8 ++- .../network/src/subnet_service/tests/mod.rs | 2 +- .../network/src/sync/block_lookups/tests.rs | 6 +- .../network/src/sync/range_sync/range.rs | 7 ++- beacon_node/operation_pool/src/lib.rs | 4 +- beacon_node/src/lib.rs | 4 +- beacon_node/store/src/hot_cold_store.rs | 8 +-- beacon_node/store/src/iter.rs | 7 ++- common/eth2_config/src/lib.rs | 14 ++--- consensus/fork_choice/tests/tests.rs | 2 +- .../src/per_block_processing/tests.rs | 3 +- .../src/per_epoch_processing/tests.rs | 5 +- database_manager/src/lib.rs | 4 +- lcli/src/transition_blocks.rs | 14 +++-- lighthouse/environment/src/lib.rs | 2 +- testing/ef_tests/src/cases/fork_choice.rs | 3 +- testing/simulator/src/basic_sim.rs | 5 +- testing/simulator/src/fallback_sim.rs | 5 +- testing/web3signer_tests/src/lib.rs | 55 ++++++++++--------- validator_client/src/beacon_node_fallback.rs | 4 +- validator_client/src/duties_service.rs | 2 +- validator_client/src/http_api/mod.rs | 4 +- validator_client/src/http_api/test_utils.rs | 6 +- validator_client/src/http_api/tests.rs | 4 +- validator_client/src/validator_store.rs | 4 +- 66 files changed, 342 insertions(+), 252 deletions(-) diff --git a/beacon_node/beacon_chain/src/beacon_block_streamer.rs b/beacon_node/beacon_chain/src/beacon_block_streamer.rs index ace5f0be74a..198d7d61f09 100644 --- a/beacon_node/beacon_chain/src/beacon_block_streamer.rs +++ b/beacon_node/beacon_chain/src/beacon_block_streamer.rs @@ -711,6 +711,7 @@ mod tests { use crate::beacon_block_streamer::{BeaconBlockStreamer, CheckCaches}; use crate::test_utils::{test_spec, BeaconChainHarness, EphemeralHarnessType}; use execution_layer::test_utils::Block; + use std::sync::Arc; use std::sync::LazyLock; use tokio::sync::mpsc; use types::{ @@ -725,7 +726,7 @@ mod tests { fn get_harness( validator_count: usize, - spec: ChainSpec, + spec: Arc, ) -> BeaconChainHarness> { let harness = BeaconChainHarness::builder(MinimalEthSpec) .spec(spec) @@ -756,6 +757,7 @@ mod tests { spec.capella_fork_epoch = Some(Epoch::new(capella_fork_epoch as u64)); spec.deneb_fork_epoch = Some(Epoch::new(deneb_fork_epoch as u64)); spec.electra_fork_epoch = Some(Epoch::new(electra_fork_epoch as u64)); + let spec = Arc::new(spec); let harness = get_harness(VALIDATOR_COUNT, spec.clone()); // go to bellatrix fork diff --git a/beacon_node/beacon_chain/src/beacon_chain.rs b/beacon_node/beacon_chain/src/beacon_chain.rs index 7094060b718..515b65b1af7 100644 --- a/beacon_node/beacon_chain/src/beacon_chain.rs +++ b/beacon_node/beacon_chain/src/beacon_chain.rs @@ -371,7 +371,7 @@ type ReqRespPreImportCache = HashMap>>; /// Represents the "Beacon Chain" component of Ethereum 2.0. Allows import of blocks and block /// operations and chooses a canonical head. pub struct BeaconChain { - pub spec: ChainSpec, + pub spec: Arc, /// Configuration for `BeaconChain` runtime behaviour. pub config: ChainConfig, /// Persistent storage for blocks, states, etc. Typically an on-disk store, such as LevelDB. diff --git a/beacon_node/beacon_chain/src/builder.rs b/beacon_node/beacon_chain/src/builder.rs index c38101e274c..001dbf00808 100644 --- a/beacon_node/beacon_chain/src/builder.rs +++ b/beacon_node/beacon_chain/src/builder.rs @@ -93,7 +93,7 @@ pub struct BeaconChainBuilder { light_client_server_tx: Option>>, head_tracker: Option, validator_pubkey_cache: Option>, - spec: ChainSpec, + spec: Arc, chain_config: ChainConfig, log: Option, beacon_graffiti: GraffitiOrigin, @@ -137,7 +137,7 @@ where light_client_server_tx: None, head_tracker: None, validator_pubkey_cache: None, - spec: E::default_spec(), + spec: Arc::new(E::default_spec()), chain_config: ChainConfig::default(), log: None, beacon_graffiti: GraffitiOrigin::default(), @@ -154,7 +154,7 @@ where /// /// This method should generally be called immediately after `Self::new` to ensure components /// are started with a consistent spec. - pub fn custom_spec(mut self, spec: ChainSpec) -> Self { + pub fn custom_spec(mut self, spec: Arc) -> Self { self.spec = spec; self } @@ -1183,8 +1183,12 @@ mod test { MinimalEthSpec, MemoryStore, MemoryStore, - > = HotColdDB::open_ephemeral(StoreConfig::default(), ChainSpec::minimal(), log.clone()) - .unwrap(); + > = HotColdDB::open_ephemeral( + StoreConfig::default(), + ChainSpec::minimal().into(), + log.clone(), + ) + .unwrap(); let spec = MinimalEthSpec::default_spec(); let genesis_state = interop_genesis_state( diff --git a/beacon_node/beacon_chain/src/data_availability_checker.rs b/beacon_node/beacon_chain/src/data_availability_checker.rs index c13593d7afc..4d5afdc8904 100644 --- a/beacon_node/beacon_chain/src/data_availability_checker.rs +++ b/beacon_node/beacon_chain/src/data_availability_checker.rs @@ -100,9 +100,8 @@ impl DataAvailabilityChecker { kzg: Arc, store: BeaconStore, import_all_data_columns: bool, - spec: ChainSpec, + spec: Arc, ) -> Result { - let spec = Arc::new(spec); let custody_subnet_count = if import_all_data_columns { spec.data_column_sidecar_subnet_count as usize } else { diff --git a/beacon_node/beacon_chain/src/data_availability_checker/overflow_lru_cache.rs b/beacon_node/beacon_chain/src/data_availability_checker/overflow_lru_cache.rs index 05f8da4eed9..46ab08a8215 100644 --- a/beacon_node/beacon_chain/src/data_availability_checker/overflow_lru_cache.rs +++ b/beacon_node/beacon_chain/src/data_availability_checker/overflow_lru_cache.rs @@ -704,7 +704,7 @@ mod test { fn get_store_with_spec( db_path: &TempDir, - spec: ChainSpec, + spec: Arc, log: Logger, ) -> Arc, LevelDB>> { let hot_path = db_path.path().join("hot_db"); @@ -741,6 +741,7 @@ mod test { spec.bellatrix_fork_epoch = Some(bellatrix_fork_epoch); spec.capella_fork_epoch = Some(capella_fork_epoch); spec.deneb_fork_epoch = Some(deneb_fork_epoch); + let spec = Arc::new(spec); let chain_store = get_store_with_spec::(db_path, spec.clone(), log.clone()); let validators_keypairs = @@ -884,7 +885,7 @@ mod test { let log = test_logger(); let chain_db_path = tempdir().expect("should get temp dir"); let harness = get_deneb_chain(log.clone(), &chain_db_path).await; - let spec = Arc::new(harness.spec.clone()); + let spec = harness.spec.clone(); let test_store = harness.chain.store.clone(); let capacity_non_zero = new_non_zero_usize(capacity); let cache = Arc::new( diff --git a/beacon_node/beacon_chain/src/eth1_chain.rs b/beacon_node/beacon_chain/src/eth1_chain.rs index 2252d5b9c92..276262085eb 100644 --- a/beacon_node/beacon_chain/src/eth1_chain.rs +++ b/beacon_node/beacon_chain/src/eth1_chain.rs @@ -10,6 +10,7 @@ use state_processing::per_block_processing::get_new_eth1_data; use std::cmp::Ordering; use std::collections::HashMap; use std::marker::PhantomData; +use std::sync::Arc; use std::time::{SystemTime, UNIX_EPOCH}; use store::{DBColumn, Error as StoreError, StoreItem}; use task_executor::TaskExecutor; @@ -284,7 +285,7 @@ where ssz_container: &SszEth1, config: Eth1Config, log: &Logger, - spec: ChainSpec, + spec: Arc, ) -> Result { let backend = Eth1ChainBackend::from_bytes(&ssz_container.backend_bytes, config, log.clone(), spec)?; @@ -355,7 +356,7 @@ pub trait Eth1ChainBackend: Sized + Send + Sync { bytes: &[u8], config: Eth1Config, log: Logger, - spec: ChainSpec, + spec: Arc, ) -> Result; } @@ -413,7 +414,7 @@ impl Eth1ChainBackend for DummyEth1ChainBackend { _bytes: &[u8], _config: Eth1Config, _log: Logger, - _spec: ChainSpec, + _spec: Arc, ) -> Result { Ok(Self(PhantomData)) } @@ -441,7 +442,7 @@ impl CachingEth1Backend { /// Instantiates `self` with empty caches. /// /// Does not connect to the eth1 node or start any tasks to keep the cache updated. - pub fn new(config: Eth1Config, log: Logger, spec: ChainSpec) -> Result { + pub fn new(config: Eth1Config, log: Logger, spec: Arc) -> Result { Ok(Self { core: HttpService::new(config, log.clone(), spec) .map_err(|e| format!("Failed to create eth1 http service: {:?}", e))?, @@ -596,7 +597,7 @@ impl Eth1ChainBackend for CachingEth1Backend { bytes: &[u8], config: Eth1Config, log: Logger, - spec: ChainSpec, + spec: Arc, ) -> Result { let inner = HttpService::from_bytes(bytes, config, log.clone(), spec)?; Ok(Self { @@ -752,7 +753,8 @@ mod test { let log = test_logger(); Eth1Chain::new( - CachingEth1Backend::new(eth1_config, log, MainnetEthSpec::default_spec()).unwrap(), + CachingEth1Backend::new(eth1_config, log, Arc::new(MainnetEthSpec::default_spec())) + .unwrap(), ) } diff --git a/beacon_node/beacon_chain/src/graffiti_calculator.rs b/beacon_node/beacon_chain/src/graffiti_calculator.rs index 42a1aa1a0b4..4373164d62f 100644 --- a/beacon_node/beacon_chain/src/graffiti_calculator.rs +++ b/beacon_node/beacon_chain/src/graffiti_calculator.rs @@ -242,6 +242,7 @@ mod tests { use execution_layer::test_utils::{DEFAULT_CLIENT_VERSION, DEFAULT_ENGINE_CAPABILITIES}; use execution_layer::EngineCapabilities; use slog::info; + use std::sync::Arc; use std::sync::LazyLock; use std::time::Duration; use types::{ChainSpec, Graffiti, Keypair, MinimalEthSpec, GRAFFITI_BYTES_LEN}; @@ -253,7 +254,7 @@ mod tests { fn get_harness( validator_count: usize, - spec: ChainSpec, + spec: Arc, chain_config: Option, ) -> BeaconChainHarness> { let harness = BeaconChainHarness::builder(MinimalEthSpec) @@ -272,7 +273,7 @@ mod tests { #[tokio::test] async fn check_graffiti_without_el_version_support() { - let spec = test_spec::(); + let spec = Arc::new(test_spec::()); let harness = get_harness(VALIDATOR_COUNT, spec, None); // modify execution engine so it doesn't support engine_getClientVersionV1 method let mock_execution_layer = harness.mock_execution_layer.as_ref().unwrap(); @@ -313,7 +314,7 @@ mod tests { #[tokio::test] async fn check_graffiti_with_el_version_support() { - let spec = test_spec::(); + let spec = Arc::new(test_spec::()); let harness = get_harness(VALIDATOR_COUNT, spec, None); let found_graffiti_bytes = harness.chain.graffiti_calculator.get_graffiti(None).await.0; @@ -355,7 +356,7 @@ mod tests { #[tokio::test] async fn check_graffiti_with_validator_specified_value() { - let spec = test_spec::(); + let spec = Arc::new(test_spec::()); let harness = get_harness(VALIDATOR_COUNT, spec, None); let graffiti_str = "nice graffiti bro"; diff --git a/beacon_node/beacon_chain/src/observed_data_sidecars.rs b/beacon_node/beacon_chain/src/observed_data_sidecars.rs index 601241dd8ad..9b59a8f85b1 100644 --- a/beacon_node/beacon_chain/src/observed_data_sidecars.rs +++ b/beacon_node/beacon_chain/src/observed_data_sidecars.rs @@ -6,6 +6,7 @@ use crate::observed_block_producers::ProposalKey; use std::collections::{HashMap, HashSet}; use std::marker::PhantomData; +use std::sync::Arc; use types::{BlobSidecar, ChainSpec, DataColumnSidecar, EthSpec, Slot}; #[derive(Debug, PartialEq)] @@ -74,13 +75,13 @@ pub struct ObservedDataSidecars { finalized_slot: Slot, /// Stores all received data indices for a given `(ValidatorIndex, Slot)` tuple. items: HashMap>, - spec: ChainSpec, + spec: Arc, _phantom: PhantomData, } impl ObservedDataSidecars { /// Instantiates `Self` with `finalized_slot == 0`. - pub fn new(spec: ChainSpec) -> Self { + pub fn new(spec: Arc) -> Self { Self { finalized_slot: Slot::new(0), items: HashMap::new(), @@ -167,7 +168,7 @@ mod tests { #[test] fn pruning() { - let spec = test_spec::(); + let spec = Arc::new(test_spec::()); let mut cache = ObservedDataSidecars::>::new(spec); assert_eq!(cache.finalized_slot, 0, "finalized slot is zero"); @@ -306,7 +307,7 @@ mod tests { #[test] fn simple_observations() { - let spec = test_spec::(); + let spec = Arc::new(test_spec::()); let mut cache = ObservedDataSidecars::>::new(spec); // Slot 0, index 0 diff --git a/beacon_node/beacon_chain/src/test_utils.rs b/beacon_node/beacon_chain/src/test_utils.rs index 8261500fba1..582d20637b3 100644 --- a/beacon_node/beacon_chain/src/test_utils.rs +++ b/beacon_node/beacon_chain/src/test_utils.rs @@ -206,7 +206,7 @@ pub fn test_spec() -> ChainSpec { pub struct Builder { eth_spec_instance: T::EthSpec, - spec: Option, + spec: Option>, validator_keypairs: Option>, withdrawal_keypairs: Vec>, chain_config: Option, @@ -395,12 +395,12 @@ where self.spec_or_default(None) } - pub fn spec(self, spec: ChainSpec) -> Self { + pub fn spec(self, spec: Arc) -> 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::)); + pub fn spec_or_default(mut self, spec: Option>) -> Self { + self.spec = Some(spec.unwrap_or_else(|| Arc::new(test_spec::()))); self } @@ -648,7 +648,7 @@ pub struct BeaconChainHarness { pub withdrawal_keypairs: Vec>, pub chain: Arc>, - pub spec: ChainSpec, + pub spec: Arc, pub shutdown_receiver: Arc>>, pub runtime: TestRuntime, diff --git a/beacon_node/beacon_chain/src/validator_pubkey_cache.rs b/beacon_node/beacon_chain/src/validator_pubkey_cache.rs index 917c20bfa5a..877c297a3b7 100644 --- a/beacon_node/beacon_chain/src/validator_pubkey_cache.rs +++ b/beacon_node/beacon_chain/src/validator_pubkey_cache.rs @@ -232,7 +232,8 @@ mod test { fn get_store() -> BeaconStore { Arc::new( - HotColdDB::open_ephemeral(<_>::default(), E::default_spec(), test_logger()).unwrap(), + HotColdDB::open_ephemeral(<_>::default(), Arc::new(E::default_spec()), test_logger()) + .unwrap(), ) } diff --git a/beacon_node/beacon_chain/tests/attestation_verification.rs b/beacon_node/beacon_chain/tests/attestation_verification.rs index 335884d57a9..f3b25ed5ce4 100644 --- a/beacon_node/beacon_chain/tests/attestation_verification.rs +++ b/beacon_node/beacon_chain/tests/attestation_verification.rs @@ -18,7 +18,7 @@ use ssz_types::BitVector; use state_processing::{ per_block_processing::errors::AttestationValidationError, per_slot_processing, }; -use std::sync::LazyLock; +use std::sync::{Arc, LazyLock}; use tree_hash::TreeHash; use types::{ signed_aggregate_and_proof::SignedAggregateAndProofRefMut, @@ -47,6 +47,7 @@ fn get_harness(validator_count: usize) -> BeaconChainHarness BeaconChainHarness (BeaconChainHarness>, ChainSpec) { +) -> (BeaconChainHarness>, Arc) { let mut spec = E::default_spec(); spec.altair_fork_epoch = Some(Epoch::new(0)); spec.bellatrix_fork_epoch = Some(Epoch::new(0)); spec.capella_fork_epoch = Some(Epoch::new(CAPELLA_FORK_EPOCH as u64)); + let spec = Arc::new(spec); let validator_keypairs = KEYPAIRS[0..validator_count].to_vec(); let genesis_state = interop_genesis_state( diff --git a/beacon_node/beacon_chain/tests/bellatrix.rs b/beacon_node/beacon_chain/tests/bellatrix.rs index 027082c11c9..5bd3452623a 100644 --- a/beacon_node/beacon_chain/tests/bellatrix.rs +++ b/beacon_node/beacon_chain/tests/bellatrix.rs @@ -49,7 +49,7 @@ async fn merge_with_terminal_block_hash_override() { spec.terminal_block_hash = genesis_pow_block_hash; let harness = BeaconChainHarness::builder(E::default()) - .spec(spec) + .spec(spec.into()) .logger(logging::test_logger()) .deterministic_keypairs(VALIDATOR_COUNT) .fresh_ephemeral_store() @@ -106,7 +106,7 @@ async fn base_altair_bellatrix_with_terminal_block_after_fork() { let mut execution_payloads = vec![]; let harness = BeaconChainHarness::builder(E::default()) - .spec(spec) + .spec(spec.into()) .logger(logging::test_logger()) .deterministic_keypairs(VALIDATOR_COUNT) .fresh_ephemeral_store() diff --git a/beacon_node/beacon_chain/tests/block_verification.rs b/beacon_node/beacon_chain/tests/block_verification.rs index faa4d74a182..535d63427a1 100644 --- a/beacon_node/beacon_chain/tests/block_verification.rs +++ b/beacon_node/beacon_chain/tests/block_verification.rs @@ -1354,7 +1354,7 @@ async fn add_base_block_to_altair_chain() { spec.altair_fork_epoch = Some(Epoch::new(1)); let harness = BeaconChainHarness::builder(MainnetEthSpec) - .spec(spec) + .spec(spec.into()) .keypairs(KEYPAIRS[..].to_vec()) .fresh_ephemeral_store() .mock_execution_layer() @@ -1489,7 +1489,7 @@ async fn add_altair_block_to_base_chain() { spec.altair_fork_epoch = None; let harness = BeaconChainHarness::builder(MainnetEthSpec) - .spec(spec) + .spec(spec.into()) .keypairs(KEYPAIRS[..].to_vec()) .fresh_ephemeral_store() .mock_execution_layer() @@ -1622,7 +1622,7 @@ async fn import_duplicate_block_unrealized_justification() { let spec = MainnetEthSpec::default_spec(); let harness = BeaconChainHarness::builder(MainnetEthSpec) - .spec(spec) + .spec(spec.into()) .keypairs(KEYPAIRS[..].to_vec()) .fresh_ephemeral_store() .mock_execution_layer() diff --git a/beacon_node/beacon_chain/tests/capella.rs b/beacon_node/beacon_chain/tests/capella.rs index c8fd2637f0c..ac97a95721d 100644 --- a/beacon_node/beacon_chain/tests/capella.rs +++ b/beacon_node/beacon_chain/tests/capella.rs @@ -39,7 +39,7 @@ async fn base_altair_bellatrix_capella() { spec.capella_fork_epoch = Some(capella_fork_epoch); let harness = BeaconChainHarness::builder(E::default()) - .spec(spec) + .spec(spec.into()) .logger(logging::test_logger()) .deterministic_keypairs(VALIDATOR_COUNT) .fresh_ephemeral_store() diff --git a/beacon_node/beacon_chain/tests/events.rs b/beacon_node/beacon_chain/tests/events.rs index b8d4a7722a4..ab784d3be45 100644 --- a/beacon_node/beacon_chain/tests/events.rs +++ b/beacon_node/beacon_chain/tests/events.rs @@ -12,7 +12,7 @@ type E = MinimalEthSpec; /// Verifies that a blob event is emitted when a gossip verified blob is received via gossip or the publish block API. #[tokio::test] async fn blob_sidecar_event_on_process_gossip_blob() { - let spec = ForkName::Deneb.make_genesis_spec(E::default_spec()); + let spec = Arc::new(ForkName::Deneb.make_genesis_spec(E::default_spec())); let harness = BeaconChainHarness::builder(E::default()) .spec(spec) .deterministic_keypairs(8) @@ -46,7 +46,7 @@ async fn blob_sidecar_event_on_process_gossip_blob() { /// Verifies that a blob event is emitted when blobs are received via RPC. #[tokio::test] async fn blob_sidecar_event_on_process_rpc_blobs() { - let spec = ForkName::Deneb.make_genesis_spec(E::default_spec()); + let spec = Arc::new(ForkName::Deneb.make_genesis_spec(E::default_spec())); let harness = BeaconChainHarness::builder(E::default()) .spec(spec) .deterministic_keypairs(8) diff --git a/beacon_node/beacon_chain/tests/op_verification.rs b/beacon_node/beacon_chain/tests/op_verification.rs index 2f8fb6d2bcc..df0d561e1cd 100644 --- a/beacon_node/beacon_chain/tests/op_verification.rs +++ b/beacon_node/beacon_chain/tests/op_verification.rs @@ -29,7 +29,7 @@ type TestHarness = BeaconChainHarness>; type HotColdDB = store::HotColdDB, LevelDB>; fn get_store(db_path: &TempDir) -> Arc { - let spec = test_spec::(); + let spec = Arc::new(test_spec::()); let hot_path = db_path.path().join("hot_db"); let cold_path = db_path.path().join("cold_db"); let blobs_path = db_path.path().join("blobs_db"); diff --git a/beacon_node/beacon_chain/tests/payload_invalidation.rs b/beacon_node/beacon_chain/tests/payload_invalidation.rs index b455c3bace4..dd195048e87 100644 --- a/beacon_node/beacon_chain/tests/payload_invalidation.rs +++ b/beacon_node/beacon_chain/tests/payload_invalidation.rs @@ -57,7 +57,7 @@ impl InvalidPayloadRig { spec.bellatrix_fork_epoch = Some(Epoch::new(0)); let harness = BeaconChainHarness::builder(MainnetEthSpec) - .spec(spec) + .spec(spec.into()) .chain_config(ChainConfig { reconstruct_historic_states: true, ..ChainConfig::default() diff --git a/beacon_node/beacon_chain/tests/rewards.rs b/beacon_node/beacon_chain/tests/rewards.rs index 323f4f38eb2..be7045c54a9 100644 --- a/beacon_node/beacon_chain/tests/rewards.rs +++ b/beacon_node/beacon_chain/tests/rewards.rs @@ -32,7 +32,7 @@ fn get_harness(spec: ChainSpec) -> BeaconChainHarness> { }; let harness = BeaconChainHarness::builder(E::default()) - .spec(spec) + .spec(Arc::new(spec)) .keypairs(KEYPAIRS.to_vec()) .fresh_ephemeral_store() .chain_config(chain_config) diff --git a/beacon_node/beacon_chain/tests/store_tests.rs b/beacon_node/beacon_chain/tests/store_tests.rs index 541abaa4247..5d83d65efd2 100644 --- a/beacon_node/beacon_chain/tests/store_tests.rs +++ b/beacon_node/beacon_chain/tests/store_tests.rs @@ -69,7 +69,7 @@ fn get_store_generic( &blobs_path, |_, _, _| Ok(()), config, - spec, + spec.into(), log, ) .expect("disk store should initialize") @@ -182,7 +182,7 @@ async fn light_client_bootstrap_test() { let beacon_chain = BeaconChainBuilder::>::new(MinimalEthSpec, kzg) .store(store.clone()) - .custom_spec(test_spec::()) + .custom_spec(test_spec::().into()) .task_executor(harness.chain.task_executor.clone()) .logger(log.clone()) .weak_subjectivity_state( @@ -325,7 +325,7 @@ async fn light_client_updates_test() { let beacon_chain = BeaconChainBuilder::>::new(MinimalEthSpec, kzg) .store(store.clone()) - .custom_spec(test_spec::()) + .custom_spec(test_spec::().into()) .task_executor(harness.chain.task_executor.clone()) .logger(log.clone()) .weak_subjectivity_state( @@ -2695,7 +2695,7 @@ async fn weak_subjectivity_sync_test(slots: Vec, checkpoint_slot: Slot) { let beacon_chain = BeaconChainBuilder::>::new(MinimalEthSpec, kzg) .store(store.clone()) - .custom_spec(test_spec::()) + .custom_spec(test_spec::().into()) .task_executor(harness.chain.task_executor.clone()) .logger(log.clone()) .weak_subjectivity_state( @@ -3162,7 +3162,7 @@ async fn revert_minority_fork_on_resume() { let db_path1 = tempdir().unwrap(); let store1 = get_store_generic(&db_path1, StoreConfig::default(), spec1.clone()); let harness1 = BeaconChainHarness::builder(MinimalEthSpec) - .spec(spec1) + .spec(spec1.clone().into()) .keypairs(KEYPAIRS[0..validator_count].to_vec()) .fresh_disk_store(store1) .mock_execution_layer() @@ -3172,7 +3172,7 @@ async fn revert_minority_fork_on_resume() { let db_path2 = tempdir().unwrap(); let store2 = get_store_generic(&db_path2, StoreConfig::default(), spec2.clone()); let harness2 = BeaconChainHarness::builder(MinimalEthSpec) - .spec(spec2.clone()) + .spec(spec2.clone().into()) .keypairs(KEYPAIRS[0..validator_count].to_vec()) .fresh_disk_store(store2) .mock_execution_layer() @@ -3268,7 +3268,7 @@ async fn revert_minority_fork_on_resume() { let resume_store = get_store_generic(&db_path1, StoreConfig::default(), spec2.clone()); let resumed_harness = TestHarness::builder(MinimalEthSpec) - .spec(spec2) + .spec(spec2.clone().into()) .keypairs(KEYPAIRS[0..validator_count].to_vec()) .resumed_disk_store(resume_store) .override_store_mutator(Box::new(move |mut builder| { diff --git a/beacon_node/beacon_chain/tests/sync_committee_verification.rs b/beacon_node/beacon_chain/tests/sync_committee_verification.rs index f8da2e8da1c..d1b3139d42c 100644 --- a/beacon_node/beacon_chain/tests/sync_committee_verification.rs +++ b/beacon_node/beacon_chain/tests/sync_committee_verification.rs @@ -30,7 +30,7 @@ fn get_harness(validator_count: usize) -> BeaconChainHarness { #[allow(clippy::type_complexity)] store: Option>>, runtime_context: Option>, - chain_spec: Option, + chain_spec: Option>, beacon_chain_builder: Option>, beacon_chain: Option>>, eth1_service: Option, @@ -137,7 +137,7 @@ where } /// Specifies the `ChainSpec`. - pub fn chain_spec(mut self, spec: ChainSpec) -> Self { + pub fn chain_spec(mut self, spec: Arc) -> Self { self.chain_spec = Some(spec); self } @@ -604,10 +604,9 @@ where }; let genesis_state = genesis_service - .wait_for_genesis_state( - Duration::from_millis(ETH1_GENESIS_UPDATE_INTERVAL_MILLIS), - context.eth2_config().spec.clone(), - ) + .wait_for_genesis_state(Duration::from_millis( + ETH1_GENESIS_UPDATE_INTERVAL_MILLIS, + )) .await?; let _ = exit_tx.send(()); @@ -641,7 +640,7 @@ where } /// Starts the networking stack. - pub async fn network(mut self, config: &NetworkConfig) -> Result { + pub async fn network(mut self, config: Arc) -> Result { let beacon_chain = self .beacon_chain .clone() diff --git a/beacon_node/eth1/src/inner.rs b/beacon_node/eth1/src/inner.rs index 7387642bf4c..1f45346256b 100644 --- a/beacon_node/eth1/src/inner.rs +++ b/beacon_node/eth1/src/inner.rs @@ -9,6 +9,7 @@ use parking_lot::RwLock; use ssz::four_byte_option_impl; use ssz::{Decode, Encode}; use ssz_derive::{Decode, Encode}; +use std::sync::Arc; use superstruct::superstruct; use types::{ChainSpec, DepositTreeSnapshot, Eth1Data}; @@ -51,7 +52,7 @@ pub struct Inner { pub to_finalize: RwLock>, pub config: RwLock, pub remote_head_block: RwLock>, - pub spec: ChainSpec, + pub spec: Arc, } impl Inner { @@ -71,7 +72,7 @@ impl Inner { } /// Recover `Inner` given byte representation of eth1 deposit and block caches. - pub fn from_bytes(bytes: &[u8], config: Config, spec: ChainSpec) -> Result { + pub fn from_bytes(bytes: &[u8], config: Config, spec: Arc) -> Result { SszEth1Cache::from_ssz_bytes(bytes) .map_err(|e| format!("Ssz decoding error: {:?}", e))? .to_inner(config, spec) @@ -109,7 +110,7 @@ impl SszEth1Cache { } } - pub fn to_inner(&self, config: Config, spec: ChainSpec) -> Result { + pub fn to_inner(&self, config: Config, spec: Arc) -> Result { Ok(Inner { block_cache: RwLock::new(self.block_cache.clone()), deposit_cache: RwLock::new(DepositUpdater { diff --git a/beacon_node/eth1/src/service.rs b/beacon_node/eth1/src/service.rs index e5d60fac49c..a70a927307d 100644 --- a/beacon_node/eth1/src/service.rs +++ b/beacon_node/eth1/src/service.rs @@ -397,7 +397,7 @@ pub struct Service { impl Service { /// Creates a new service. Does not attempt to connect to the eth1 node. - pub fn new(config: Config, log: Logger, spec: ChainSpec) -> Result { + pub fn new(config: Config, log: Logger, spec: Arc) -> Result { Ok(Self { inner: Arc::new(Inner { block_cache: <_>::default(), @@ -414,6 +414,10 @@ impl Service { }) } + pub fn chain_spec(&self) -> &Arc { + &self.inner.spec + } + pub fn client(&self) -> &HttpJsonRpc { &self.inner.endpoint } @@ -422,7 +426,7 @@ impl Service { pub fn from_deposit_snapshot( config: Config, log: Logger, - spec: ChainSpec, + spec: Arc, deposit_snapshot: &DepositTreeSnapshot, ) -> Result { let deposit_cache = @@ -464,7 +468,7 @@ impl Service { bytes: &[u8], config: Config, log: Logger, - spec: ChainSpec, + spec: Arc, ) -> Result { let inner = Inner::from_bytes(bytes, config, spec)?; Ok(Self { diff --git a/beacon_node/eth1/tests/test.rs b/beacon_node/eth1/tests/test.rs index 3ad9b34381a..e442ce48630 100644 --- a/beacon_node/eth1/tests/test.rs +++ b/beacon_node/eth1/tests/test.rs @@ -8,6 +8,7 @@ use logging::test_logger; use merkle_proof::verify_merkle_proof; use sensitive_url::SensitiveUrl; use std::ops::Range; +use std::sync::Arc; use std::time::Duration; use tree_hash::TreeHash; use types::{ @@ -122,8 +123,12 @@ mod eth1_cache { }; let cache_follow_distance = config.cache_follow_distance(); - let service = - Service::new(config, log.clone(), MainnetEthSpec::default_spec()).unwrap(); + let service = Service::new( + config, + log.clone(), + Arc::new(MainnetEthSpec::default_spec()), + ) + .unwrap(); // Create some blocks and then consume them, performing the test `rounds` times. for round in 0..2 { @@ -204,7 +209,7 @@ mod eth1_cache { ..Config::default() }, log, - MainnetEthSpec::default_spec(), + Arc::new(MainnetEthSpec::default_spec()), ) .unwrap(); @@ -259,7 +264,7 @@ mod eth1_cache { ..Config::default() }, log, - MainnetEthSpec::default_spec(), + Arc::new(MainnetEthSpec::default_spec()), ) .unwrap(); @@ -310,7 +315,7 @@ mod eth1_cache { ..Config::default() }, log, - MainnetEthSpec::default_spec(), + Arc::new(MainnetEthSpec::default_spec()), ) .unwrap(); @@ -365,7 +370,7 @@ mod deposit_tree { ..Config::default() }, log, - MainnetEthSpec::default_spec(), + Arc::new(MainnetEthSpec::default_spec()), ) .unwrap(); @@ -447,7 +452,7 @@ mod deposit_tree { ..Config::default() }, log, - MainnetEthSpec::default_spec(), + Arc::new(MainnetEthSpec::default_spec()), ) .unwrap(); @@ -694,7 +699,7 @@ mod fast { let anvil_client = eth1.json_rpc_client(); let now = get_block_number(&anvil_client).await; - let spec = MainnetEthSpec::default_spec(); + let spec = Arc::new(MainnetEthSpec::default_spec()); let service = Service::new( Config { endpoint: Eth1Endpoint::NoAuth( @@ -788,8 +793,12 @@ mod persist { block_cache_truncation: None, ..Config::default() }; - let service = - Service::new(config.clone(), log.clone(), MainnetEthSpec::default_spec()).unwrap(); + let service = Service::new( + config.clone(), + log.clone(), + Arc::new(MainnetEthSpec::default_spec()), + ) + .unwrap(); let n = 10; let deposits: Vec<_> = (0..n).map(|_| random_deposit_data()).collect(); for deposit in &deposits { @@ -828,9 +837,13 @@ mod persist { // Drop service and recover from bytes drop(service); - let recovered_service = - Service::from_bytes(ð1_bytes, config, log, MainnetEthSpec::default_spec()) - .unwrap(); + let recovered_service = Service::from_bytes( + ð1_bytes, + config, + log, + Arc::new(MainnetEthSpec::default_spec()), + ) + .unwrap(); assert_eq!( recovered_service.block_cache_len(), block_count, diff --git a/beacon_node/execution_layer/src/test_utils/mock_builder.rs b/beacon_node/execution_layer/src/test_utils/mock_builder.rs index 46830256b09..1291c8cf97b 100644 --- a/beacon_node/execution_layer/src/test_utils/mock_builder.rs +++ b/beacon_node/execution_layer/src/test_utils/mock_builder.rs @@ -209,7 +209,7 @@ impl BidStuff for BuilderBid { pub struct MockBuilder { el: ExecutionLayer, beacon_client: BeaconNodeHttpClient, - spec: ChainSpec, + spec: Arc, val_registration_cache: Arc>>, builder_sk: SecretKey, operations: Arc>>, @@ -220,7 +220,7 @@ impl MockBuilder { pub fn new_for_testing( mock_el_url: SensitiveUrl, beacon_url: SensitiveUrl, - spec: ChainSpec, + spec: Arc, executor: TaskExecutor, ) -> (Self, (SocketAddr, impl Future)) { let file = NamedTempFile::new().unwrap(); @@ -252,7 +252,7 @@ impl MockBuilder { pub fn new( el: ExecutionLayer, beacon_client: BeaconNodeHttpClient, - spec: ChainSpec, + spec: Arc, ) -> Self { let sk = SecretKey::random(); Self { diff --git a/beacon_node/genesis/src/eth1_genesis_service.rs b/beacon_node/genesis/src/eth1_genesis_service.rs index 3347f6c6c2a..3981833a5cb 100644 --- a/beacon_node/genesis/src/eth1_genesis_service.rs +++ b/beacon_node/genesis/src/eth1_genesis_service.rs @@ -43,7 +43,7 @@ impl Eth1GenesisService { /// Creates a new service. Does not attempt to connect to the Eth1 node. /// /// Modifies the given `config` to make it more suitable to the task of listening to genesis. - pub fn new(config: Eth1Config, log: Logger, spec: ChainSpec) -> Result { + pub fn new(config: Eth1Config, log: Logger, spec: Arc) -> Result { let config = Eth1Config { // Truncating the block cache makes searching for genesis more // complicated. @@ -100,9 +100,9 @@ impl Eth1GenesisService { pub async fn wait_for_genesis_state( &self, update_interval: Duration, - spec: ChainSpec, ) -> Result, String> { let eth1_service = &self.eth1_service; + let spec = eth1_service.chain_spec(); let log = ð1_service.log; let mut sync_blocks = false; @@ -180,13 +180,13 @@ impl Eth1GenesisService { // Scan the new eth1 blocks, searching for genesis. if let Some(genesis_state) = - self.scan_new_blocks::(&mut highest_processed_block, &spec)? + self.scan_new_blocks::(&mut highest_processed_block, spec)? { info!( log, "Genesis ceremony complete"; "genesis_validators" => genesis_state - .get_active_validator_indices(E::genesis_epoch(), &spec) + .get_active_validator_indices(E::genesis_epoch(), spec) .map_err(|e| format!("Genesis validators error: {:?}", e))? .len(), "genesis_time" => genesis_state.genesis_time(), @@ -203,7 +203,7 @@ impl Eth1GenesisService { let latest_timestamp = self.stats.latest_timestamp.load(Ordering::Relaxed); // Perform some logging. - if timestamp_can_trigger_genesis(latest_timestamp, &spec)? { + if timestamp_can_trigger_genesis(latest_timestamp, spec)? { // Indicate that we are awaiting adequate active validators. if (active_validator_count as u64) < spec.min_genesis_active_validator_count { info!( diff --git a/beacon_node/genesis/tests/tests.rs b/beacon_node/genesis/tests/tests.rs index b5c6d85afeb..6cc7517aa44 100644 --- a/beacon_node/genesis/tests/tests.rs +++ b/beacon_node/genesis/tests/tests.rs @@ -5,6 +5,7 @@ use eth1_test_rig::{AnvilEth1Instance, DelayThenDeposit, Middleware}; use genesis::{Eth1Config, Eth1GenesisService}; use sensitive_url::SensitiveUrl; use state_processing::is_valid_genesis_state; +use std::sync::Arc; use std::time::Duration; use types::{ test_utils::generate_deterministic_keypair, FixedBytesExtended, Hash256, MinimalEthSpec, @@ -24,7 +25,10 @@ pub fn new_env() -> Environment { fn basic() { let env = new_env(); let log = env.core_context().log().clone(); - let mut spec = env.eth2_config().spec.clone(); + let mut spec = (*env.eth2_config().spec).clone(); + spec.min_genesis_time = 0; + spec.min_genesis_active_validator_count = 8; + let spec = Arc::new(spec); env.runtime().block_on(async { let eth1 = AnvilEth1Instance::new(DEFAULT_CHAIN_ID.into()) @@ -60,9 +64,6 @@ fn basic() { // you're experiencing failures, try increasing the update_interval. let update_interval = Duration::from_millis(500); - spec.min_genesis_time = 0; - spec.min_genesis_active_validator_count = 8; - let deposits = (0..spec.min_genesis_active_validator_count + 2) .map(|i| { deposit_contract.deposit_helper::( @@ -79,8 +80,7 @@ fn basic() { let deposit_future = deposit_contract.deposit_multiple(deposits); - let wait_future = - service.wait_for_genesis_state::(update_interval, spec.clone()); + let wait_future = service.wait_for_genesis_state::(update_interval); let state = futures::try_join!(deposit_future, wait_future) .map(|(_, state)| state) diff --git a/beacon_node/http_api/src/lib.rs b/beacon_node/http_api/src/lib.rs index 998114f565e..15d463b661f 100644 --- a/beacon_node/http_api/src/lib.rs +++ b/beacon_node/http_api/src/lib.rs @@ -153,6 +153,7 @@ pub struct Config { #[serde(with = "eth2::types::serde_status_code")] pub duplicate_block_status_code: StatusCode, pub enable_light_client_server: bool, + pub target_peers: usize, } impl Default for Config { @@ -169,6 +170,7 @@ impl Default for Config { enable_beacon_processor: true, duplicate_block_status_code: StatusCode::ACCEPTED, enable_light_client_server: false, + target_peers: 100, } } } @@ -2934,8 +2936,16 @@ pub fn serve( let is_optimistic = head_execution_status.is_optimistic_or_invalid(); + // When determining sync status, make an exception for single-node + // testnets with 0 peers. + let sync_state = network_globals.sync_state.read(); + let is_synced = sync_state.is_synced() + || (sync_state.is_stalled() + && network_globals.config.target_peers == 0); + drop(sync_state); + let syncing_data = api_types::SyncingData { - is_syncing: !network_globals.sync_state.read().is_synced(), + is_syncing: !is_synced, is_optimistic, el_offline, head_slot, diff --git a/beacon_node/http_api/src/test_utils.rs b/beacon_node/http_api/src/test_utils.rs index dcd494a880f..4742fa109ff 100644 --- a/beacon_node/http_api/src/test_utils.rs +++ b/beacon_node/http_api/src/test_utils.rs @@ -16,7 +16,7 @@ use lighthouse_network::{ }, rpc::methods::{MetaData, MetaDataV2}, types::{EnrAttestationBitfield, EnrSyncCommitteeBitfield, SyncState}, - ConnectedPoint, Enr, NetworkGlobals, PeerId, PeerManager, + ConnectedPoint, Enr, NetworkConfig, NetworkGlobals, PeerId, PeerManager, }; use logging::test_logger; use network::{NetworkReceivers, NetworkSenders}; @@ -71,7 +71,7 @@ impl InteractiveTester { mutator: Option>, ) -> Self { let mut harness_builder = BeaconChainHarness::builder(E::default()) - .spec_or_default(spec) + .spec_or_default(spec.map(Arc::new)) .logger(test_logger()) .mock_execution_layer(); @@ -145,12 +145,14 @@ pub async fn create_api_server( }); let enr_key = CombinedKey::generate_secp256k1(); let enr = Enr::builder().build(&enr_key).unwrap(); + let network_config = Arc::new(NetworkConfig::default()); let network_globals = Arc::new(NetworkGlobals::new( enr.clone(), meta_data, vec![], false, &log, + network_config, chain.spec.clone(), )); diff --git a/beacon_node/http_api/tests/tests.rs b/beacon_node/http_api/tests/tests.rs index 19a01a91c50..940f3ae9c0c 100644 --- a/beacon_node/http_api/tests/tests.rs +++ b/beacon_node/http_api/tests/tests.rs @@ -122,7 +122,7 @@ impl ApiTester { } pub async fn new_from_config(config: ApiTesterConfig) -> Self { - let spec = config.spec; + let spec = Arc::new(config.spec); let mut harness = BeaconChainHarness::builder(MainnetEthSpec) .spec(spec.clone()) diff --git a/beacon_node/lighthouse_network/src/discovery/mod.rs b/beacon_node/lighthouse_network/src/discovery/mod.rs index e1cea3153ac..d57c67bacb8 100644 --- a/beacon_node/lighthouse_network/src/discovery/mod.rs +++ b/beacon_node/lighthouse_network/src/discovery/mod.rs @@ -1215,10 +1215,11 @@ mod tests { } async fn build_discovery() -> Discovery { - let spec = ChainSpec::default(); + let spec = Arc::new(ChainSpec::default()); let keypair = secp256k1::Keypair::generate(); let mut config = NetworkConfig::default(); config.set_listening_addr(crate::ListenAddress::unused_v4_ports()); + let config = Arc::new(config); let enr_key: CombinedKey = CombinedKey::from_secp256k1(&keypair); let enr: Enr = build_enr::(&enr_key, &config, &EnrForkId::default(), &spec).unwrap(); let log = build_log(slog::Level::Debug, false); @@ -1232,6 +1233,7 @@ mod tests { vec![], false, &log, + config.clone(), spec.clone(), ); let keypair = keypair.into(); diff --git a/beacon_node/lighthouse_network/src/peer_manager/mod.rs b/beacon_node/lighthouse_network/src/peer_manager/mod.rs index 320bbc4d638..b8dce6667e4 100644 --- a/beacon_node/lighthouse_network/src/peer_manager/mod.rs +++ b/beacon_node/lighthouse_network/src/peer_manager/mod.rs @@ -4,9 +4,7 @@ use crate::discovery::enr_ext::EnrExt; use crate::discovery::peer_id_to_node_id; use crate::rpc::{GoodbyeReason, MetaData, Protocol, RPCError, RPCResponseErrorCode}; use crate::service::TARGET_SUBNET_PEERS; -use crate::{error, metrics, Gossipsub}; -use crate::{NetworkGlobals, PeerId}; -use crate::{Subnet, SubnetDiscovery}; +use crate::{error, metrics, Gossipsub, NetworkGlobals, PeerId, Subnet, SubnetDiscovery}; use delay_map::HashSetDelay; use discv5::Enr; use libp2p::identify::Info as IdentifyInfo; @@ -1452,6 +1450,7 @@ enum ConnectingType { #[cfg(test)] mod tests { use super::*; + use crate::NetworkConfig; use slog::{o, Drain}; use types::MainnetEthSpec as E; @@ -1468,15 +1467,7 @@ mod tests { } async fn build_peer_manager(target_peer_count: usize) -> PeerManager { - let config = config::Config { - target_peer_count, - discovery_enabled: false, - ..Default::default() - }; - let log = build_log(slog::Level::Debug, false); - let spec = E::default_spec(); - let globals = NetworkGlobals::new_test_globals(vec![], &log, spec); - PeerManager::new(config, Arc::new(globals), &log).unwrap() + build_peer_manager_with_trusted_peers(vec![], target_peer_count).await } async fn build_peer_manager_with_trusted_peers( @@ -1488,9 +1479,13 @@ mod tests { discovery_enabled: false, ..Default::default() }; + let network_config = Arc::new(NetworkConfig { + target_peers: target_peer_count, + ..Default::default() + }); let log = build_log(slog::Level::Debug, false); - let spec = E::default_spec(); - let globals = NetworkGlobals::new_test_globals(trusted_peers, &log, spec); + let spec = Arc::new(E::default_spec()); + let globals = NetworkGlobals::new_test_globals(trusted_peers, &log, network_config, spec); PeerManager::new(config, Arc::new(globals), &log).unwrap() } diff --git a/beacon_node/lighthouse_network/src/service/mod.rs b/beacon_node/lighthouse_network/src/service/mod.rs index a97157ff0a4..43217ba5ab6 100644 --- a/beacon_node/lighthouse_network/src/service/mod.rs +++ b/beacon_node/lighthouse_network/src/service/mod.rs @@ -166,7 +166,7 @@ impl Network { &config, &ctx.enr_fork_id, &log, - ctx.chain_spec, + &ctx.chain_spec, )?; // Construct the metadata let custody_subnet_count = if ctx.chain_spec.is_peer_das_scheduled() { @@ -186,6 +186,7 @@ impl Network { trusted_peers, config.disable_peer_scoring, &log, + config.clone(), ctx.chain_spec.clone(), ); Arc::new(globals) @@ -209,7 +210,7 @@ impl Network { E::slots_per_epoch(), ); - let score_settings = PeerScoreSettings::new(ctx.chain_spec, gs_config.mesh_n()); + let score_settings = PeerScoreSettings::new(&ctx.chain_spec, gs_config.mesh_n()); let gossip_cache = { let slot_duration = std::time::Duration::from_secs(ctx.chain_spec.seconds_per_slot); @@ -346,7 +347,7 @@ impl Network { &config, network_globals.clone(), &log, - ctx.chain_spec, + &ctx.chain_spec, ) .await?; // start searching for peers diff --git a/beacon_node/lighthouse_network/src/service/utils.rs b/beacon_node/lighthouse_network/src/service/utils.rs index 8b6a84ae0cb..81ee86b8b9b 100644 --- a/beacon_node/lighthouse_network/src/service/utils.rs +++ b/beacon_node/lighthouse_network/src/service/utils.rs @@ -30,10 +30,10 @@ pub const MAX_CONNECTIONS_PER_PEER: u32 = 1; pub const METADATA_FILENAME: &str = "metadata"; pub struct Context<'a> { - pub config: &'a NetworkConfig, + pub config: Arc, pub enr_fork_id: EnrForkId, pub fork_context: Arc, - pub chain_spec: &'a ChainSpec, + pub chain_spec: Arc, pub libp2p_registry: Option<&'a mut Registry>, } diff --git a/beacon_node/lighthouse_network/src/types/globals.rs b/beacon_node/lighthouse_network/src/types/globals.rs index ac78e2cb01e..f271c9ff722 100644 --- a/beacon_node/lighthouse_network/src/types/globals.rs +++ b/beacon_node/lighthouse_network/src/types/globals.rs @@ -2,12 +2,11 @@ use crate::peer_manager::peerdb::PeerDB; use crate::rpc::{MetaData, MetaDataV3}; use crate::types::{BackFillState, SyncState}; -use crate::Client; -use crate::EnrExt; -use crate::{Enr, GossipTopic, Multiaddr, PeerId}; +use crate::{Client, Enr, EnrExt, GossipTopic, Multiaddr, NetworkConfig, PeerId}; use itertools::Itertools; use parking_lot::RwLock; use std::collections::HashSet; +use std::sync::Arc; use types::{ChainSpec, ColumnIndex, DataColumnSubnetId, EthSpec}; pub struct NetworkGlobals { @@ -30,7 +29,10 @@ pub struct NetworkGlobals { /// The computed custody subnets and columns is stored to avoid re-computing. pub custody_subnets: Vec, pub custody_columns: Vec, - pub spec: ChainSpec, + /// Network-related configuration. Immutable after initialization. + pub config: Arc, + /// Ethereum chain configuration. Immutable after initialization. + pub spec: Arc, } impl NetworkGlobals { @@ -40,7 +42,8 @@ impl NetworkGlobals { trusted_peers: Vec, disable_peer_scoring: bool, log: &slog::Logger, - spec: ChainSpec, + config: Arc, + spec: Arc, ) -> Self { let (custody_subnets, custody_columns) = if spec.is_peer_das_scheduled() { let custody_subnet_count = local_metadata @@ -75,6 +78,7 @@ impl NetworkGlobals { backfill_state: RwLock::new(BackFillState::NotRequired), custody_subnets, custody_columns, + config, spec, } } @@ -160,7 +164,8 @@ impl NetworkGlobals { pub fn new_test_globals( trusted_peers: Vec, log: &slog::Logger, - spec: ChainSpec, + config: Arc, + spec: Arc, ) -> NetworkGlobals { let metadata = MetaData::V3(MetaDataV3 { seq_number: 0, @@ -168,20 +173,21 @@ impl NetworkGlobals { syncnets: Default::default(), custody_subnet_count: spec.custody_requirement, }); - Self::new_test_globals_with_metadata(trusted_peers, metadata, log, spec) + Self::new_test_globals_with_metadata(trusted_peers, metadata, log, config, spec) } pub(crate) fn new_test_globals_with_metadata( trusted_peers: Vec, metadata: MetaData, log: &slog::Logger, - spec: ChainSpec, + config: Arc, + spec: Arc, ) -> NetworkGlobals { use crate::CombinedKeyExt; let keypair = libp2p::identity::secp256k1::Keypair::generate(); let enr_key: discv5::enr::CombinedKey = discv5::enr::CombinedKey::from_secp256k1(&keypair); let enr = discv5::enr::Enr::builder().build(&enr_key).unwrap(); - NetworkGlobals::new(enr, metadata, trusted_peers, false, log, spec) + NetworkGlobals::new(enr, metadata, trusted_peers, false, log, config, spec) } } @@ -198,9 +204,15 @@ mod test { let custody_subnet_count = spec.data_column_sidecar_subnet_count / 2; let metadata = get_metadata(custody_subnet_count); - - let globals = - NetworkGlobals::::new_test_globals_with_metadata(vec![], metadata, &log, spec); + let config = Arc::new(NetworkConfig::default()); + + let globals = NetworkGlobals::::new_test_globals_with_metadata( + vec![], + metadata, + &log, + config, + Arc::new(spec), + ); assert_eq!(globals.custody_subnets.len(), custody_subnet_count as usize); } @@ -213,9 +225,15 @@ mod test { let custody_subnet_count = spec.data_column_sidecar_subnet_count / 2; let custody_columns_count = spec.number_of_columns / 2; let metadata = get_metadata(custody_subnet_count); - - let globals = - NetworkGlobals::::new_test_globals_with_metadata(vec![], metadata, &log, spec); + let config = Arc::new(NetworkConfig::default()); + + let globals = NetworkGlobals::::new_test_globals_with_metadata( + vec![], + metadata, + &log, + config, + Arc::new(spec), + ); assert_eq!(globals.custody_columns.len(), custody_columns_count); } diff --git a/beacon_node/lighthouse_network/src/types/sync_state.rs b/beacon_node/lighthouse_network/src/types/sync_state.rs index b82e63bd9c0..4322763fc58 100644 --- a/beacon_node/lighthouse_network/src/types/sync_state.rs +++ b/beacon_node/lighthouse_network/src/types/sync_state.rs @@ -91,6 +91,14 @@ impl SyncState { pub fn is_synced(&self) -> bool { matches!(self, SyncState::Synced | SyncState::BackFillSyncing { .. }) } + + /// Returns true if the node is *stalled*, i.e. has no synced peers. + /// + /// Usually this state is treated as unsynced, except in some places where we make an exception + /// for single-node testnets where having 0 peers is desired. + pub fn is_stalled(&self) -> bool { + matches!(self, SyncState::Stalled) + } } impl std::fmt::Display for SyncState { diff --git a/beacon_node/lighthouse_network/tests/common.rs b/beacon_node/lighthouse_network/tests/common.rs index 660d786169f..84e19c81d04 100644 --- a/beacon_node/lighthouse_network/tests/common.rs +++ b/beacon_node/lighthouse_network/tests/common.rs @@ -76,7 +76,7 @@ pub fn build_log(level: slog::Level, enabled: bool) -> slog::Logger { } } -pub fn build_config(mut boot_nodes: Vec) -> NetworkConfig { +pub fn build_config(mut boot_nodes: Vec) -> Arc { let mut config = NetworkConfig::default(); // Find unused ports by using the 0 port. @@ -92,7 +92,7 @@ pub fn build_config(mut boot_nodes: Vec) -> NetworkConfig { config.enr_address = (Some(std::net::Ipv4Addr::LOCALHOST), None); config.boot_nodes_enr.append(&mut boot_nodes); config.network_dir = path.into_path(); - config + Arc::new(config) } pub async fn build_libp2p_instance( @@ -100,7 +100,7 @@ pub async fn build_libp2p_instance( boot_nodes: Vec, log: slog::Logger, fork_name: ForkName, - spec: &ChainSpec, + chain_spec: Arc, ) -> Libp2pInstance { let config = build_config(boot_nodes); // launch libp2p service @@ -109,10 +109,10 @@ pub async fn build_libp2p_instance( let (shutdown_tx, _) = futures::channel::mpsc::channel(1); let executor = task_executor::TaskExecutor::new(rt, exit, log.clone(), shutdown_tx); let libp2p_context = lighthouse_network::Context { - config: &config, + config, enr_fork_id: EnrForkId::default(), fork_context: Arc::new(fork_context(fork_name)), - chain_spec: spec, + chain_spec, libp2p_registry: None, }; Libp2pInstance( @@ -142,14 +142,16 @@ pub async fn build_node_pair( rt: Weak, log: &slog::Logger, fork_name: ForkName, - spec: &ChainSpec, + spec: Arc, protocol: Protocol, ) -> (Libp2pInstance, Libp2pInstance) { let sender_log = log.new(o!("who" => "sender")); let receiver_log = log.new(o!("who" => "receiver")); - let mut sender = build_libp2p_instance(rt.clone(), vec![], sender_log, fork_name, spec).await; - let mut receiver = build_libp2p_instance(rt, vec![], receiver_log, fork_name, spec).await; + let mut sender = + build_libp2p_instance(rt.clone(), vec![], sender_log, fork_name, spec.clone()).await; + let mut receiver = + build_libp2p_instance(rt, vec![], receiver_log, fork_name, spec.clone()).await; // let the two nodes set up listeners let sender_fut = async { @@ -218,11 +220,13 @@ pub async fn build_linear( log: slog::Logger, n: usize, fork_name: ForkName, - spec: &ChainSpec, + spec: Arc, ) -> Vec { let mut nodes = Vec::with_capacity(n); for _ in 0..n { - nodes.push(build_libp2p_instance(rt.clone(), vec![], log.clone(), fork_name, spec).await); + nodes.push( + build_libp2p_instance(rt.clone(), vec![], log.clone(), fork_name, spec.clone()).await, + ); } let multiaddrs: Vec = nodes diff --git a/beacon_node/lighthouse_network/tests/rpc_tests.rs b/beacon_node/lighthouse_network/tests/rpc_tests.rs index 25d249960d2..8a0416c1f8a 100644 --- a/beacon_node/lighthouse_network/tests/rpc_tests.rs +++ b/beacon_node/lighthouse_network/tests/rpc_tests.rs @@ -61,7 +61,7 @@ fn test_tcp_status_rpc() { let log = common::build_log(log_level, enable_logging); - let spec = E::default_spec(); + let spec = Arc::new(E::default_spec()); rt.block_on(async { // get sender/receiver @@ -69,7 +69,7 @@ fn test_tcp_status_rpc() { Arc::downgrade(&rt), &log, ForkName::Base, - &spec, + spec, Protocol::Tcp, ) .await; @@ -163,7 +163,7 @@ fn test_tcp_blocks_by_range_chunked_rpc() { let rt = Arc::new(Runtime::new().unwrap()); - let spec = E::default_spec(); + let spec = Arc::new(E::default_spec()); rt.block_on(async { // get sender/receiver @@ -171,7 +171,7 @@ fn test_tcp_blocks_by_range_chunked_rpc() { Arc::downgrade(&rt), &log, ForkName::Bellatrix, - &spec, + spec.clone(), Protocol::Tcp, ) .await; @@ -179,8 +179,6 @@ fn test_tcp_blocks_by_range_chunked_rpc() { // BlocksByRange Request let rpc_request = Request::BlocksByRange(BlocksByRangeRequest::new(0, messages_to_send)); - let spec = E::default_spec(); - // BlocksByRange Response let full_block = BeaconBlock::Base(BeaconBlockBase::::full(&spec)); let signed_full_block = SignedBeaconBlock::from_block(full_block, Signature::empty()); @@ -300,12 +298,12 @@ fn test_blobs_by_range_chunked_rpc() { rt.block_on(async { // get sender/receiver - let spec = E::default_spec(); + let spec = Arc::new(E::default_spec()); let (mut sender, mut receiver) = common::build_node_pair( Arc::downgrade(&rt), &log, ForkName::Deneb, - &spec, + spec.clone(), Protocol::Tcp, ) .await; @@ -410,7 +408,7 @@ fn test_tcp_blocks_by_range_over_limit() { let rt = Arc::new(Runtime::new().unwrap()); - let spec = E::default_spec(); + let spec = Arc::new(E::default_spec()); rt.block_on(async { // get sender/receiver @@ -418,7 +416,7 @@ fn test_tcp_blocks_by_range_over_limit() { Arc::downgrade(&rt), &log, ForkName::Bellatrix, - &spec, + spec.clone(), Protocol::Tcp, ) .await; @@ -502,7 +500,7 @@ fn test_tcp_blocks_by_range_chunked_rpc_terminates_correctly() { let rt = Arc::new(Runtime::new().unwrap()); - let spec = E::default_spec(); + let spec = Arc::new(E::default_spec()); rt.block_on(async { // get sender/receiver @@ -510,7 +508,7 @@ fn test_tcp_blocks_by_range_chunked_rpc_terminates_correctly() { Arc::downgrade(&rt), &log, ForkName::Base, - &spec, + spec.clone(), Protocol::Tcp, ) .await; @@ -519,7 +517,6 @@ fn test_tcp_blocks_by_range_chunked_rpc_terminates_correctly() { let rpc_request = Request::BlocksByRange(BlocksByRangeRequest::new(0, messages_to_send)); // BlocksByRange Response - let spec = E::default_spec(); let empty_block = BeaconBlock::empty(&spec); let empty_signed = SignedBeaconBlock::from_block(empty_block, Signature::empty()); let rpc_response = Response::BlocksByRange(Some(Arc::new(empty_signed))); @@ -631,7 +628,7 @@ fn test_tcp_blocks_by_range_single_empty_rpc() { let log = common::build_log(log_level, enable_logging); let rt = Arc::new(Runtime::new().unwrap()); - let spec = E::default_spec(); + let spec = Arc::new(E::default_spec()); rt.block_on(async { // get sender/receiver @@ -639,7 +636,7 @@ fn test_tcp_blocks_by_range_single_empty_rpc() { Arc::downgrade(&rt), &log, ForkName::Base, - &spec, + spec.clone(), Protocol::Tcp, ) .await; @@ -648,7 +645,6 @@ fn test_tcp_blocks_by_range_single_empty_rpc() { let rpc_request = Request::BlocksByRange(BlocksByRangeRequest::new(0, 10)); // BlocksByRange Response - let spec = E::default_spec(); let empty_block = BeaconBlock::empty(&spec); let empty_signed = SignedBeaconBlock::from_block(empty_block, Signature::empty()); let rpc_response = Response::BlocksByRange(Some(Arc::new(empty_signed))); @@ -739,7 +735,7 @@ fn test_tcp_blocks_by_root_chunked_rpc() { let messages_to_send = 6; let log = common::build_log(log_level, enable_logging); - let spec = E::default_spec(); + let spec = Arc::new(E::default_spec()); let rt = Arc::new(Runtime::new().unwrap()); // get sender/receiver @@ -748,7 +744,7 @@ fn test_tcp_blocks_by_root_chunked_rpc() { Arc::downgrade(&rt), &log, ForkName::Bellatrix, - &spec, + spec.clone(), Protocol::Tcp, ) .await; @@ -877,7 +873,7 @@ fn test_tcp_blocks_by_root_chunked_rpc_terminates_correctly() { let extra_messages_to_send: u64 = 10; let log = common::build_log(log_level, enable_logging); - let spec = E::default_spec(); + let spec = Arc::new(E::default_spec()); let rt = Arc::new(Runtime::new().unwrap()); // get sender/receiver @@ -886,7 +882,7 @@ fn test_tcp_blocks_by_root_chunked_rpc_terminates_correctly() { Arc::downgrade(&rt), &log, ForkName::Base, - &spec, + spec.clone(), Protocol::Tcp, ) .await; @@ -1016,12 +1012,12 @@ fn goodbye_test(log_level: Level, enable_logging: bool, protocol: Protocol) { let rt = Arc::new(Runtime::new().unwrap()); - let spec = E::default_spec(); + let spec = Arc::new(E::default_spec()); // get sender/receiver rt.block_on(async { let (mut sender, mut receiver) = - common::build_node_pair(Arc::downgrade(&rt), &log, ForkName::Base, &spec, protocol) + common::build_node_pair(Arc::downgrade(&rt), &log, ForkName::Base, spec, protocol) .await; // build the sender future diff --git a/beacon_node/network/src/network_beacon_processor/tests.rs b/beacon_node/network/src/network_beacon_processor/tests.rs index 391175ccd41..6e8f151a05c 100644 --- a/beacon_node/network/src/network_beacon_processor/tests.rs +++ b/beacon_node/network/src/network_beacon_processor/tests.rs @@ -21,7 +21,7 @@ use lighthouse_network::{ discv5::enr::{self, CombinedKey}, rpc::methods::{MetaData, MetaDataV2}, types::{EnrAttestationBitfield, EnrSyncCommitteeBitfield}, - Client, MessageId, NetworkGlobals, PeerId, Response, + Client, MessageId, NetworkConfig, NetworkGlobals, PeerId, Response, }; use slot_clock::SlotClock; use std::iter::Iterator; @@ -91,6 +91,7 @@ impl TestRig { // This allows for testing voluntary exits without building out a massive chain. let mut spec = test_spec::(); spec.shard_committee_period = 2; + let spec = Arc::new(spec); let harness = BeaconChainHarness::builder(MainnetEthSpec) .spec(spec.clone()) @@ -204,12 +205,14 @@ impl TestRig { }); let enr_key = CombinedKey::generate_secp256k1(); let enr = enr::Enr::builder().build(&enr_key).unwrap(); + let network_config = Arc::new(NetworkConfig::default()); let network_globals = Arc::new(NetworkGlobals::new( enr, meta_data, vec![], false, &log, + network_config, spec, )); diff --git a/beacon_node/network/src/persisted_dht.rs b/beacon_node/network/src/persisted_dht.rs index 522ff0536eb..1e1420883e8 100644 --- a/beacon_node/network/src/persisted_dht.rs +++ b/beacon_node/network/src/persisted_dht.rs @@ -81,7 +81,8 @@ mod tests { MinimalEthSpec, MemoryStore, MemoryStore, - > = HotColdDB::open_ephemeral(StoreConfig::default(), ChainSpec::minimal(), log).unwrap(); + > = HotColdDB::open_ephemeral(StoreConfig::default(), ChainSpec::minimal().into(), log) + .unwrap(); let enrs = vec![Enr::from_str("enr:-IS4QHCYrYZbAKWCBRlAy5zzaDZXJBGkcnh4MHcBFZntXNFrdvJjX04jRzjzCBOonrkTfj499SZuOh8R33Ls8RRcy5wBgmlkgnY0gmlwhH8AAAGJc2VjcDI1NmsxoQPKY0yuDUmstAHYpMa2_oxVtw0RW_QAdpzBQA8yWM0xOIN1ZHCCdl8").unwrap()]; store .put_item(&DHT_DB_KEY, &PersistedDht { enrs: enrs.clone() }) diff --git a/beacon_node/network/src/service.rs b/beacon_node/network/src/service.rs index 5782fb00b6c..150402a7ab2 100644 --- a/beacon_node/network/src/service.rs +++ b/beacon_node/network/src/service.rs @@ -205,7 +205,7 @@ pub struct NetworkService { impl NetworkService { async fn build( beacon_chain: Arc>, - config: &NetworkConfig, + config: Arc, executor: task_executor::TaskExecutor, libp2p_registry: Option<&'_ mut Registry>, beacon_processor_send: BeaconProcessorSend, @@ -271,10 +271,10 @@ impl NetworkService { // construct the libp2p service context let service_context = Context { - config, + config: config.clone(), enr_fork_id, fork_context: fork_context.clone(), - chain_spec: &beacon_chain.spec, + chain_spec: beacon_chain.spec.clone(), libp2p_registry, }; @@ -318,12 +318,12 @@ impl NetworkService { let attestation_service = AttestationService::new( beacon_chain.clone(), network_globals.local_enr().node_id(), - config, + &config, &network_log, ); // sync committee subnet service let sync_committee_service = - SyncCommitteeService::new(beacon_chain.clone(), config, &network_log); + SyncCommitteeService::new(beacon_chain.clone(), &config, &network_log); // create a timer for updating network metrics let metrics_update = tokio::time::interval(Duration::from_secs(METRIC_UPDATE_INTERVAL)); @@ -368,7 +368,7 @@ impl NetworkService { #[allow(clippy::type_complexity)] pub async fn start( beacon_chain: Arc>, - config: &NetworkConfig, + config: Arc, executor: task_executor::TaskExecutor, libp2p_registry: Option<&'_ mut Registry>, beacon_processor_send: BeaconProcessorSend, diff --git a/beacon_node/network/src/service/tests.rs b/beacon_node/network/src/service/tests.rs index fec5f3f83f7..b55992c624e 100644 --- a/beacon_node/network/src/service/tests.rs +++ b/beacon_node/network/src/service/tests.rs @@ -73,6 +73,7 @@ mod tests { config.discv5_config.table_filter = |_| true; // Do not ignore local IPs config.upnp_enabled = false; config.boot_nodes_enr = enrs.clone(); + let config = Arc::new(config); runtime.block_on(async move { // Create a new network service which implicitly gets dropped at the // end of the block. @@ -86,7 +87,7 @@ mod tests { let _network_service = NetworkService::start( beacon_chain.clone(), - &config, + config, executor, None, beacon_processor_tx, @@ -125,7 +126,7 @@ mod tests { // Build beacon chain. let beacon_chain = BeaconChainHarness::builder(MinimalEthSpec) - .spec(spec.clone()) + .spec(spec.clone().into()) .deterministic_keypairs(8) .fresh_ephemeral_store() .mock_execution_layer() @@ -149,12 +150,13 @@ mod tests { config.set_ipv4_listening_address(std::net::Ipv4Addr::UNSPECIFIED, 21214, 21214, 21215); config.discv5_config.table_filter = |_| true; // Do not ignore local IPs config.upnp_enabled = false; + let config = Arc::new(config); let beacon_processor_channels = BeaconProcessorChannels::new(&BeaconProcessorConfig::default()); NetworkService::build( beacon_chain.clone(), - &config, + config, executor.clone(), None, beacon_processor_channels.beacon_processor_tx, diff --git a/beacon_node/network/src/subnet_service/tests/mod.rs b/beacon_node/network/src/subnet_service/tests/mod.rs index 3ee7c7f7680..a784b05ea7a 100644 --- a/beacon_node/network/src/subnet_service/tests/mod.rs +++ b/beacon_node/network/src/subnet_service/tests/mod.rs @@ -38,7 +38,7 @@ pub struct TestBeaconChain { impl TestBeaconChain { pub fn new_with_system_clock() -> Self { - let spec = MainnetEthSpec::default_spec(); + let spec = Arc::new(MainnetEthSpec::default_spec()); let keypairs = generate_deterministic_keypairs(1); diff --git a/beacon_node/network/src/sync/block_lookups/tests.rs b/beacon_node/network/src/sync/block_lookups/tests.rs index 5aa1d5c2902..6e6c9a5cdfe 100644 --- a/beacon_node/network/src/sync/block_lookups/tests.rs +++ b/beacon_node/network/src/sync/block_lookups/tests.rs @@ -28,7 +28,7 @@ use lighthouse_network::service::api_types::{ SyncRequestId, }; use lighthouse_network::types::SyncState; -use lighthouse_network::{NetworkGlobals, Request}; +use lighthouse_network::{NetworkConfig, NetworkGlobals, Request}; use slog::info; use slot_clock::{ManualSlotClock, SlotClock, TestingSlotClock}; use store::MemoryStore; @@ -116,7 +116,7 @@ impl TestRig { // Initialise a new beacon chain let harness = BeaconChainHarness::>::builder(E) - .spec(spec) + .spec(Arc::new(spec)) .logger(log.clone()) .deterministic_keypairs(1) .fresh_ephemeral_store() @@ -132,9 +132,11 @@ impl TestRig { let (network_tx, network_rx) = mpsc::unbounded_channel(); // TODO(das): make the generation of the ENR use the deterministic rng to have consistent // column assignments + let network_config = Arc::new(NetworkConfig::default()); let globals = Arc::new(NetworkGlobals::new_test_globals( Vec::new(), &log, + network_config, chain.spec.clone(), )); let (beacon_processor, beacon_processor_rx) = NetworkBeaconProcessor::null_for_testing( diff --git a/beacon_node/network/src/sync/range_sync/range.rs b/beacon_node/network/src/sync/range_sync/range.rs index 28dea8e4b5e..f28b57eb187 100644 --- a/beacon_node/network/src/sync/range_sync/range.rs +++ b/beacon_node/network/src/sync/range_sync/range.rs @@ -51,8 +51,7 @@ use beacon_chain::block_verification_types::RpcBlock; use beacon_chain::{BeaconChain, BeaconChainTypes}; use lighthouse_network::rpc::GoodbyeReason; use lighthouse_network::service::api_types::Id; -use lighthouse_network::PeerId; -use lighthouse_network::SyncInfo; +use lighthouse_network::{PeerId, SyncInfo}; use lru_cache::LRUTimeCache; use slog::{crit, debug, trace, warn}; use std::collections::HashMap; @@ -399,7 +398,7 @@ mod tests { use beacon_processor::WorkEvent as BeaconWorkEvent; use lighthouse_network::service::api_types::SyncRequestId; use lighthouse_network::{ - rpc::StatusMessage, service::api_types::AppRequestId, NetworkGlobals, + rpc::StatusMessage, service::api_types::AppRequestId, NetworkConfig, NetworkGlobals, }; use slog::{o, Drain}; use slot_clock::TestingSlotClock; @@ -692,9 +691,11 @@ mod tests { log.new(o!("component" => "range")), ); let (network_tx, network_rx) = mpsc::unbounded_channel(); + let network_config = Arc::new(NetworkConfig::default()); let globals = Arc::new(NetworkGlobals::new_test_globals( Vec::new(), &log, + network_config, chain.spec.clone(), )); let (network_beacon_processor, beacon_processor_rx) = diff --git a/beacon_node/operation_pool/src/lib.rs b/beacon_node/operation_pool/src/lib.rs index c60480ef377..e6a61edc098 100644 --- a/beacon_node/operation_pool/src/lib.rs +++ b/beacon_node/operation_pool/src/lib.rs @@ -801,7 +801,7 @@ mod release_tests { use state_processing::epoch_cache::initialize_epoch_cache; use state_processing::{common::get_attesting_indices_from_state, VerifyOperation}; use std::collections::BTreeSet; - use std::sync::LazyLock; + use std::sync::{Arc, LazyLock}; use types::consts::altair::SYNC_COMMITTEE_SUBNET_COUNT; use types::*; @@ -816,7 +816,7 @@ mod release_tests { spec: Option, ) -> BeaconChainHarness> { let harness = BeaconChainHarness::builder(E::default()) - .spec_or_default(spec) + .spec_or_default(spec.map(Arc::new)) .keypairs(KEYPAIRS[0..validator_count].to_vec()) .fresh_ephemeral_store() .mock_execution_layer() diff --git a/beacon_node/src/lib.rs b/beacon_node/src/lib.rs index 945bd787dd4..5bc0f9dc6a6 100644 --- a/beacon_node/src/lib.rs +++ b/beacon_node/src/lib.rs @@ -119,7 +119,7 @@ impl ProductionBeaconNode { let slasher = Arc::new( Slasher::open( slasher_config, - Arc::new(spec), + spec, log.new(slog::o!("service" => "slasher")), ) .map_err(|e| format!("Slasher open error: {:?}", e))?, @@ -174,7 +174,7 @@ impl ProductionBeaconNode { builder .build_beacon_chain()? - .network(&client_config.network) + .network(Arc::new(client_config.network)) .await? .notifier()? .http_metrics_config(client_config.http_metrics.clone()) diff --git a/beacon_node/store/src/hot_cold_store.rs b/beacon_node/store/src/hot_cold_store.rs index bd87cdcfee6..ba288039d6b 100644 --- a/beacon_node/store/src/hot_cold_store.rs +++ b/beacon_node/store/src/hot_cold_store.rs @@ -82,7 +82,7 @@ pub struct HotColdDB, Cold: ItemStore> { /// LRU cache of replayed states. historic_state_cache: Mutex>>, /// Chain spec. - pub(crate) spec: ChainSpec, + pub(crate) spec: Arc, /// Logger. pub log: Logger, /// Mere vessel for E. @@ -194,7 +194,7 @@ pub enum HotColdDBError { impl HotColdDB, MemoryStore> { pub fn open_ephemeral( config: StoreConfig, - spec: ChainSpec, + spec: Arc, log: Logger, ) -> Result, MemoryStore>, Error> { Self::verify_config(&config)?; @@ -231,7 +231,7 @@ impl HotColdDB, LevelDB> { blobs_db_path: &Path, migrate_schema: impl FnOnce(Arc, SchemaVersion, SchemaVersion) -> Result<(), Error>, config: StoreConfig, - spec: ChainSpec, + spec: Arc, log: Logger, ) -> Result, Error> { Self::verify_slots_per_restore_point(config.slots_per_restore_point)?; @@ -1868,7 +1868,7 @@ impl, Cold: ItemStore> HotColdDB } /// Get a reference to the `ChainSpec` used by the database. - pub fn get_chain_spec(&self) -> &ChainSpec { + pub fn get_chain_spec(&self) -> &Arc { &self.spec } diff --git a/beacon_node/store/src/iter.rs b/beacon_node/store/src/iter.rs index a7e0c09ed1f..71dc96d99e9 100644 --- a/beacon_node/store/src/iter.rs +++ b/beacon_node/store/src/iter.rs @@ -385,6 +385,7 @@ mod test { use beacon_chain::test_utils::BeaconChainHarness; use beacon_chain::types::{ChainSpec, MainnetEthSpec}; use sloggers::{null::NullLoggerBuilder, Build}; + use std::sync::Arc; use types::FixedBytesExtended; fn get_state() -> BeaconState { @@ -401,7 +402,8 @@ mod test { fn block_root_iter() { let log = NullLoggerBuilder.build().unwrap(); let store = - HotColdDB::open_ephemeral(Config::default(), ChainSpec::minimal(), log).unwrap(); + HotColdDB::open_ephemeral(Config::default(), Arc::new(ChainSpec::minimal()), log) + .unwrap(); let slots_per_historical_root = MainnetEthSpec::slots_per_historical_root(); let mut state_a: BeaconState = get_state(); @@ -449,7 +451,8 @@ mod test { fn state_root_iter() { let log = NullLoggerBuilder.build().unwrap(); let store = - HotColdDB::open_ephemeral(Config::default(), ChainSpec::minimal(), log).unwrap(); + HotColdDB::open_ephemeral(Config::default(), Arc::new(ChainSpec::minimal()), log) + .unwrap(); let slots_per_historical_root = MainnetEthSpec::slots_per_historical_root(); let mut state_a: BeaconState = get_state(); diff --git a/common/eth2_config/src/lib.rs b/common/eth2_config/src/lib.rs index 9104db8f67d..cd5d7a8bd4d 100644 --- a/common/eth2_config/src/lib.rs +++ b/common/eth2_config/src/lib.rs @@ -7,6 +7,7 @@ use std::env; use std::path::PathBuf; +use std::sync::Arc; use types::{ChainSpec, EthSpecId}; pub use paste::paste; @@ -44,15 +45,12 @@ const CHIADO_GENESIS_STATE_SOURCE: GenesisStateSource = GenesisStateSource::Url #[derive(Debug, Clone)] pub struct Eth2Config { pub eth_spec_id: EthSpecId, - pub spec: ChainSpec, + pub spec: Arc, } impl Default for Eth2Config { fn default() -> Self { - Self { - eth_spec_id: EthSpecId::Minimal, - spec: ChainSpec::minimal(), - } + Self::minimal() } } @@ -60,21 +58,21 @@ impl Eth2Config { pub fn mainnet() -> Self { Self { eth_spec_id: EthSpecId::Mainnet, - spec: ChainSpec::mainnet(), + spec: Arc::new(ChainSpec::mainnet()), } } pub fn minimal() -> Self { Self { eth_spec_id: EthSpecId::Minimal, - spec: ChainSpec::minimal(), + spec: Arc::new(ChainSpec::minimal()), } } pub fn gnosis() -> Self { Self { eth_spec_id: EthSpecId::Gnosis, - spec: ChainSpec::gnosis(), + spec: Arc::new(ChainSpec::gnosis()), } } } diff --git a/consensus/fork_choice/tests/tests.rs b/consensus/fork_choice/tests/tests.rs index b1ef833be0f..ce19d68203e 100644 --- a/consensus/fork_choice/tests/tests.rs +++ b/consensus/fork_choice/tests/tests.rs @@ -55,7 +55,7 @@ impl ForkChoiceTest { // Run fork choice tests against the latest fork. let spec = ForkName::latest().make_genesis_spec(ChainSpec::default()); let harness = BeaconChainHarness::builder(MainnetEthSpec) - .spec(spec) + .spec(spec.into()) .chain_config(chain_config) .deterministic_keypairs(VALIDATOR_COUNT) .fresh_ephemeral_store() diff --git a/consensus/state_processing/src/per_block_processing/tests.rs b/consensus/state_processing/src/per_block_processing/tests.rs index f8b354d92df..c59449634ac 100644 --- a/consensus/state_processing/src/per_block_processing/tests.rs +++ b/consensus/state_processing/src/per_block_processing/tests.rs @@ -12,7 +12,7 @@ use crate::{ }; use beacon_chain::test_utils::{BeaconChainHarness, EphemeralHarnessType}; use ssz_types::Bitfield; -use std::sync::LazyLock; +use std::sync::{Arc, LazyLock}; use test_utils::generate_deterministic_keypairs; use types::*; @@ -1017,6 +1017,7 @@ async fn fork_spanning_exit() { spec.altair_fork_epoch = Some(Epoch::new(2)); spec.bellatrix_fork_epoch = Some(Epoch::new(4)); spec.shard_committee_period = 0; + let spec = Arc::new(spec); let harness = BeaconChainHarness::builder(MainnetEthSpec) .spec(spec.clone()) diff --git a/consensus/state_processing/src/per_epoch_processing/tests.rs b/consensus/state_processing/src/per_epoch_processing/tests.rs index 8c240548b04..b93ede248ca 100644 --- a/consensus/state_processing/src/per_epoch_processing/tests.rs +++ b/consensus/state_processing/src/per_epoch_processing/tests.rs @@ -45,6 +45,7 @@ mod release_tests { per_slot_processing::per_slot_processing, EpochProcessingError, SlotProcessingError, }; use beacon_chain::test_utils::{AttestationStrategy, BlockStrategy}; + use std::sync::Arc; use types::{Epoch, ForkName, InconsistentFork, MainnetEthSpec}; #[tokio::test] @@ -56,7 +57,7 @@ mod release_tests { let altair_state = { let harness = BeaconChainHarness::builder(MainnetEthSpec) - .spec(spec.clone()) + .spec(Arc::new(spec.clone())) .deterministic_keypairs(8) .fresh_ephemeral_store() .build(); @@ -116,7 +117,7 @@ mod release_tests { let base_state = { let harness = BeaconChainHarness::builder(MainnetEthSpec) - .spec(spec.clone()) + .spec(Arc::new(spec.clone())) .deterministic_keypairs(8) .fresh_ephemeral_store() .build(); diff --git a/database_manager/src/lib.rs b/database_manager/src/lib.rs index c5344f1f92e..3d556318486 100644 --- a/database_manager/src/lib.rs +++ b/database_manager/src/lib.rs @@ -301,7 +301,7 @@ pub fn migrate_db( runtime_context: &RuntimeContext, log: Logger, ) -> Result<(), Error> { - let spec = &runtime_context.eth2_config.spec; + let spec = runtime_context.eth2_config.spec.clone(); let hot_path = client_config.get_db_path(); let cold_path = client_config.get_freezer_db_path(); let blobs_path = client_config.get_blobs_db_path(); @@ -334,7 +334,7 @@ pub fn migrate_db( from, to, log, - spec, + &spec, ) } diff --git a/lcli/src/transition_blocks.rs b/lcli/src/transition_blocks.rs index ec3bb5b9edb..94d95a0d1c4 100644 --- a/lcli/src/transition_blocks.rs +++ b/lcli/src/transition_blocks.rs @@ -103,7 +103,7 @@ pub fn run( network_config: Eth2NetworkConfig, matches: &ArgMatches, ) -> Result<(), String> { - let spec = &network_config.chain_spec::()?; + let spec = Arc::new(network_config.chain_spec::()?); let executor = env.core_context().executor; /* @@ -137,13 +137,15 @@ pub fn run( (Some(pre_state_path), Some(block_path), None) => { info!("Block path: {:?}", block_path); info!("Pre-state path: {:?}", pre_state_path); - let pre_state = load_from_ssz_with(&pre_state_path, spec, BeaconState::from_ssz_bytes)?; - let block = load_from_ssz_with(&block_path, spec, SignedBeaconBlock::from_ssz_bytes)?; + let pre_state = + load_from_ssz_with(&pre_state_path, &spec, BeaconState::from_ssz_bytes)?; + let block = load_from_ssz_with(&block_path, &spec, SignedBeaconBlock::from_ssz_bytes)?; (pre_state, None, block) } (None, None, Some(beacon_url)) => { let block_id: BlockId = parse_required(matches, "block-id")?; let client = BeaconNodeHttpClient::new(beacon_url, Timeouts::set_all(HTTP_TIMEOUT)); + let inner_spec = spec.clone(); executor .handle() .ok_or("shutdown in progress")? @@ -155,7 +157,7 @@ pub fn run( .ok_or_else(|| format!("Unable to locate block at {:?}", block_id))? .data; - if block.slot() == spec.genesis_slot { + if block.slot() == inner_spec.genesis_slot { return Err("Cannot run on the genesis block".to_string()); } @@ -215,7 +217,7 @@ pub fn run( if config.exclude_cache_builds { pre_state - .build_all_caches(spec) + .build_all_caches(&spec) .map_err(|e| format!("Unable to build caches: {:?}", e))?; let state_root = pre_state .update_tree_hash_cache() @@ -251,7 +253,7 @@ pub fn run( &config, &validator_pubkey_cache, &mut saved_ctxt, - spec, + &spec, )?; let duration = Instant::now().duration_since(start); diff --git a/lighthouse/environment/src/lib.rs b/lighthouse/environment/src/lib.rs index aa2caa23507..9ad40a6acd4 100644 --- a/lighthouse/environment/src/lib.rs +++ b/lighthouse/environment/src/lib.rs @@ -333,7 +333,7 @@ impl EnvironmentBuilder { eth2_network_config: Eth2NetworkConfig, ) -> Result { // Create a new chain spec from the default configuration. - self.eth2_config.spec = eth2_network_config.chain_spec::()?; + self.eth2_config.spec = Arc::new(eth2_network_config.chain_spec::()?); self.eth2_network_config = Some(eth2_network_config); Ok(self) diff --git a/testing/ef_tests/src/cases/fork_choice.rs b/testing/ef_tests/src/cases/fork_choice.rs index 2a2cc067e58..33ae132e8a2 100644 --- a/testing/ef_tests/src/cases/fork_choice.rs +++ b/testing/ef_tests/src/cases/fork_choice.rs @@ -350,11 +350,12 @@ impl Case for ForkChoiceTest { /// A testing rig used to execute a test case. struct Tester { harness: BeaconChainHarness>, - spec: ChainSpec, + spec: Arc, } impl Tester { pub fn new(case: &ForkChoiceTest, spec: ChainSpec) -> Result { + let spec = Arc::new(spec); let genesis_time = case.anchor_state.genesis_time(); if case.anchor_state.slot() != spec.genesis_slot { diff --git a/testing/simulator/src/basic_sim.rs b/testing/simulator/src/basic_sim.rs index 16badaffc2d..e1cef95cd32 100644 --- a/testing/simulator/src/basic_sim.rs +++ b/testing/simulator/src/basic_sim.rs @@ -11,6 +11,7 @@ use node_test_rig::{ }; use rayon::prelude::*; use std::cmp::max; +use std::sync::Arc; use std::time::Duration; use tokio::time::sleep; use types::{Epoch, EthSpec, MinimalEthSpec}; @@ -98,7 +99,7 @@ pub fn run_basic_sim(matches: &ArgMatches) -> Result<(), String> { .multi_threaded_tokio_runtime()? .build()?; - let spec = &mut env.eth2_config.spec; + let mut spec = (*env.eth2_config.spec).clone(); let total_validator_count = validators_per_node * node_count; let genesis_delay = GENESIS_DELAY; @@ -117,6 +118,8 @@ pub fn run_basic_sim(matches: &ArgMatches) -> Result<(), String> { spec.capella_fork_epoch = Some(Epoch::new(CAPELLA_FORK_EPOCH)); spec.deneb_fork_epoch = Some(Epoch::new(DENEB_FORK_EPOCH)); //spec.electra_fork_epoch = Some(Epoch::new(ELECTRA_FORK_EPOCH)); + let spec = Arc::new(spec); + env.eth2_config.spec = spec.clone(); let slot_duration = Duration::from_secs(spec.seconds_per_slot); let slots_per_epoch = MinimalEthSpec::slots_per_epoch(); diff --git a/testing/simulator/src/fallback_sim.rs b/testing/simulator/src/fallback_sim.rs index 73984aadad7..b27a6246bf8 100644 --- a/testing/simulator/src/fallback_sim.rs +++ b/testing/simulator/src/fallback_sim.rs @@ -10,6 +10,7 @@ use node_test_rig::{ }; use rayon::prelude::*; use std::cmp::max; +use std::sync::Arc; use std::time::Duration; use tokio::time::sleep; use types::{Epoch, EthSpec, MinimalEthSpec}; @@ -105,7 +106,7 @@ pub fn run_fallback_sim(matches: &ArgMatches) -> Result<(), String> { .multi_threaded_tokio_runtime()? .build()?; - let spec = &mut env.eth2_config.spec; + let mut spec = (*env.eth2_config.spec).clone(); let total_validator_count = validators_per_vc * vc_count; let node_count = vc_count * bns_per_vc; @@ -122,6 +123,8 @@ pub fn run_fallback_sim(matches: &ArgMatches) -> Result<(), String> { spec.capella_fork_epoch = Some(Epoch::new(CAPELLA_FORK_EPOCH)); spec.deneb_fork_epoch = Some(Epoch::new(DENEB_FORK_EPOCH)); //spec.electra_fork_epoch = Some(Epoch::new(ELECTRA_FORK_EPOCH)); + let spec = Arc::new(spec); + env.eth2_config.spec = spec.clone(); let slot_duration = Duration::from_secs(spec.seconds_per_slot); let slots_per_epoch = MinimalEthSpec::slots_per_epoch(); diff --git a/testing/web3signer_tests/src/lib.rs b/testing/web3signer_tests/src/lib.rs index f6ee01a4ba1..3a039d3c803 100644 --- a/testing/web3signer_tests/src/lib.rs +++ b/testing/web3signer_tests/src/lib.rs @@ -317,7 +317,7 @@ mod tests { validator_definitions: Vec, slashing_protection_config: SlashingProtectionConfig, using_web3signer: bool, - spec: ChainSpec, + spec: Arc, ) -> Self { let log = test_logger(); let validator_dir = TempDir::new().unwrap(); @@ -408,7 +408,7 @@ mod tests { pub async fn new( network: &str, slashing_protection_config: SlashingProtectionConfig, - spec: ChainSpec, + spec: Arc, listen_port: u16, ) -> Self { let signer_rig = @@ -575,7 +575,7 @@ mod tests { /// Test all the "base" (phase 0) types. async fn test_base_types(network: &str, listen_port: u16) { let network_config = Eth2NetworkConfig::constant(network).unwrap().unwrap(); - let spec = &network_config.chain_spec::().unwrap(); + let spec = Arc::new(network_config.chain_spec::().unwrap()); TestingRig::new( network, @@ -591,13 +591,16 @@ mod tests { .unwrap() }) .await - .assert_signatures_match("beacon_block_base", |pubkey, validator_store| async move { - let block = BeaconBlock::Base(BeaconBlockBase::empty(spec)); - let block_slot = block.slot(); - validator_store - .sign_block(pubkey, block, block_slot) - .await - .unwrap() + .assert_signatures_match("beacon_block_base", |pubkey, validator_store| { + let spec = spec.clone(); + async move { + let block = BeaconBlock::Base(BeaconBlockBase::empty(&spec)); + let block_slot = block.slot(); + validator_store + .sign_block(pubkey, block, block_slot) + .await + .unwrap() + } }) .await .assert_signatures_match("attestation", |pubkey, validator_store| async move { @@ -645,7 +648,7 @@ mod tests { /// Test all the Altair types. async fn test_altair_types(network: &str, listen_port: u16) { let network_config = Eth2NetworkConfig::constant(network).unwrap().unwrap(); - let spec = &network_config.chain_spec::().unwrap(); + let spec = Arc::new(network_config.chain_spec::().unwrap()); let altair_fork_slot = spec .altair_fork_epoch .unwrap() @@ -658,17 +661,17 @@ mod tests { listen_port, ) .await - .assert_signatures_match( - "beacon_block_altair", - |pubkey, validator_store| async move { - let mut altair_block = BeaconBlockAltair::empty(spec); + .assert_signatures_match("beacon_block_altair", |pubkey, validator_store| { + let spec = spec.clone(); + async move { + let mut altair_block = BeaconBlockAltair::empty(&spec); altair_block.slot = altair_fork_slot; validator_store .sign_block(pubkey, BeaconBlock::Altair(altair_block), altair_fork_slot) .await .unwrap() - }, - ) + } + }) .await .assert_signatures_match( "sync_selection_proof", @@ -728,7 +731,7 @@ mod tests { /// Test all the Bellatrix types. async fn test_bellatrix_types(network: &str, listen_port: u16) { let network_config = Eth2NetworkConfig::constant(network).unwrap().unwrap(); - let spec = &network_config.chain_spec::().unwrap(); + let spec = Arc::new(network_config.chain_spec::().unwrap()); let bellatrix_fork_slot = spec .bellatrix_fork_epoch .unwrap() @@ -741,10 +744,10 @@ mod tests { listen_port, ) .await - .assert_signatures_match( - "beacon_block_bellatrix", - |pubkey, validator_store| async move { - let mut bellatrix_block = BeaconBlockBellatrix::empty(spec); + .assert_signatures_match("beacon_block_bellatrix", |pubkey, validator_store| { + let spec = spec.clone(); + async move { + let mut bellatrix_block = BeaconBlockBellatrix::empty(&spec); bellatrix_block.slot = bellatrix_fork_slot; validator_store .sign_block( @@ -754,8 +757,8 @@ mod tests { ) .await .unwrap() - }, - ) + } + }) .await; } @@ -767,7 +770,7 @@ mod tests { let network = "mainnet"; let network_config = Eth2NetworkConfig::constant(network).unwrap().unwrap(); - let spec = &network_config.chain_spec::().unwrap(); + let spec = Arc::new(network_config.chain_spec::().unwrap()); let bellatrix_fork_slot = spec .bellatrix_fork_epoch .unwrap() @@ -805,7 +808,7 @@ mod tests { }; let first_block = || { - let mut bellatrix_block = BeaconBlockBellatrix::empty(spec); + let mut bellatrix_block = BeaconBlockBellatrix::empty(&spec); bellatrix_block.slot = bellatrix_fork_slot; BeaconBlock::Bellatrix(bellatrix_block) }; diff --git a/validator_client/src/beacon_node_fallback.rs b/validator_client/src/beacon_node_fallback.rs index 58d7f9d8eef..6bba55d6767 100644 --- a/validator_client/src/beacon_node_fallback.rs +++ b/validator_client/src/beacon_node_fallback.rs @@ -347,7 +347,7 @@ pub struct BeaconNodeFallback { candidates: Vec>, slot_clock: Option, broadcast_topics: Vec, - spec: ChainSpec, + spec: Arc, log: Logger, } @@ -355,7 +355,7 @@ impl BeaconNodeFallback { pub fn new( candidates: Vec>, broadcast_topics: Vec, - spec: ChainSpec, + spec: Arc, log: Logger, ) -> Self { Self { diff --git a/validator_client/src/duties_service.rs b/validator_client/src/duties_service.rs index faa157a8592..1c205b38e5d 100644 --- a/validator_client/src/duties_service.rs +++ b/validator_client/src/duties_service.rs @@ -229,7 +229,7 @@ pub struct DutiesService { /// The runtime for spawning tasks. pub context: RuntimeContext, /// The current chain spec. - pub spec: ChainSpec, + pub spec: Arc, //// Whether we permit large validator counts in the metrics. pub enable_high_validator_count_metrics: bool, /// If this validator is running in distributed mode. diff --git a/validator_client/src/http_api/mod.rs b/validator_client/src/http_api/mod.rs index 3d7cab8e5e0..bfd5c1fa80d 100644 --- a/validator_client/src/http_api/mod.rs +++ b/validator_client/src/http_api/mod.rs @@ -77,7 +77,7 @@ pub struct Context { pub secrets_dir: Option, pub graffiti_file: Option, pub graffiti_flag: Option, - pub spec: ChainSpec, + pub spec: Arc, pub config: Config, pub log: Logger, pub sse_logging_components: Option, @@ -217,7 +217,7 @@ pub fn serve( let inner_slot_clock = ctx.slot_clock.clone(); let slot_clock_filter = warp::any().map(move || inner_slot_clock.clone()); - let inner_spec = Arc::new(ctx.spec.clone()); + let inner_spec = ctx.spec.clone(); let spec_filter = warp::any().map(move || inner_spec.clone()); let api_token_path_inner = api_token_path.clone(); diff --git a/validator_client/src/http_api/test_utils.rs b/validator_client/src/http_api/test_utils.rs index 8bb56e87a32..6c0e8b1617c 100644 --- a/validator_client/src/http_api/test_utils.rs +++ b/validator_client/src/http_api/test_utils.rs @@ -96,7 +96,7 @@ impl ApiTester { ..Default::default() }; - let spec = E::default_spec(); + let spec = Arc::new(E::default_spec()); let slashing_db_path = config.validator_dir.join(SLASHING_PROTECTION_FILENAME); let slashing_protection = SlashingDatabase::open_or_create(&slashing_db_path).unwrap(); @@ -110,7 +110,7 @@ impl ApiTester { initialized_validators, slashing_protection, Hash256::repeat_byte(42), - spec, + spec.clone(), Some(Arc::new(DoppelgangerService::new(log.clone()))), slot_clock.clone(), &config, @@ -132,7 +132,7 @@ impl ApiTester { validator_store: Some(validator_store.clone()), graffiti_file: None, graffiti_flag: Some(Graffiti::default()), - spec: E::default_spec(), + spec, config: http_config, log, sse_logging_components: None, diff --git a/validator_client/src/http_api/tests.rs b/validator_client/src/http_api/tests.rs index ce1937d4379..98fbc854ae9 100644 --- a/validator_client/src/http_api/tests.rs +++ b/validator_client/src/http_api/tests.rs @@ -80,7 +80,7 @@ impl ApiTester { config.validator_dir = validator_dir.path().into(); config.secrets_dir = secrets_dir.path().into(); - let spec = E::default_spec(); + let spec = Arc::new(E::default_spec()); let slashing_db_path = config.validator_dir.join(SLASHING_PROTECTION_FILENAME); let slashing_protection = SlashingDatabase::open_or_create(&slashing_db_path).unwrap(); @@ -120,7 +120,7 @@ impl ApiTester { validator_store: Some(validator_store.clone()), graffiti_file: None, graffiti_flag: Some(Graffiti::default()), - spec: E::default_spec(), + spec: E::default_spec().into(), config: HttpConfig { enabled: true, listen_addr: IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)), diff --git a/validator_client/src/validator_store.rs b/validator_client/src/validator_store.rs index 8a9e125936e..6753c50cff5 100644 --- a/validator_client/src/validator_store.rs +++ b/validator_client/src/validator_store.rs @@ -85,7 +85,7 @@ impl ValidatorStore { validators: InitializedValidators, slashing_protection: SlashingDatabase, genesis_validators_root: Hash256, - spec: ChainSpec, + spec: Arc, doppelganger_service: Option>, slot_clock: T, config: &Config, @@ -97,7 +97,7 @@ impl ValidatorStore { slashing_protection, slashing_protection_last_prune: Arc::new(Mutex::new(Epoch::new(0))), genesis_validators_root, - spec: Arc::new(spec), + spec, log, doppelganger_service, slot_clock,