diff --git a/Cargo.toml b/Cargo.toml index d27c1dc132..f5bb36ac53 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -92,3 +92,6 @@ eth2_ssz = { path = "consensus/ssz" } eth2_ssz_types = { path = "consensus/ssz_types" } tree_hash = { path = "consensus/tree_hash" } eth2_serde_utils = { path = "consensus/serde_utils" } + +[profile.release] +debug = 1 diff --git a/beacon_node/beacon_chain/src/builder.rs b/beacon_node/beacon_chain/src/builder.rs index e9860124c0..f7d7722cdf 100644 --- a/beacon_node/beacon_chain/src/builder.rs +++ b/beacon_node/beacon_chain/src/builder.rs @@ -417,6 +417,12 @@ where let (_, updated_builder) = self.set_genesis_state(genesis_state)?; self = updated_builder; + // Build the committee caches before storing. The database assumes that states have + // committee caches built before storing. + weak_subj_state + .build_all_committee_caches(&self.spec) + .map_err(|e| format!("Error building caches on checkpoint state: {:?}", e))?; + // Write the state and block non-atomically, it doesn't matter if they're forgotten // about on a crash restart. store diff --git a/beacon_node/beacon_chain/src/validator_pubkey_cache.rs b/beacon_node/beacon_chain/src/validator_pubkey_cache.rs index e9649b6114..27bbd435f6 100644 --- a/beacon_node/beacon_chain/src/validator_pubkey_cache.rs +++ b/beacon_node/beacon_chain/src/validator_pubkey_cache.rs @@ -111,12 +111,11 @@ impl ValidatorPubkeyCache { state: &BeaconState, ) -> Result<(), BeaconChainError> { if state.validators().len() > self.pubkeys.len() { - // FIXME(sproul): iter_from would be more efficient than `skip` here self.import( state .validators() - .iter() - .skip(self.pubkeys.len()) + .iter_from(self.pubkeys.len()) + .unwrap() // FIXME(sproul) .map(|v| v.pubkey), ) } else { diff --git a/consensus/types/src/beacon_state.rs b/consensus/types/src/beacon_state.rs index 7d0ef2302e..ab02257e82 100644 --- a/consensus/types/src/beacon_state.rs +++ b/consensus/types/src/beacon_state.rs @@ -827,11 +827,13 @@ impl BeaconState { &mut self, sync_committee: &SyncCommittee, ) -> Result, Error> { + self.update_pubkey_cache()?; sync_committee .pubkeys .iter() .map(|pubkey| { - self.get_validator_index(pubkey)? + self.pubkey_cache() + .get(pubkey) .ok_or(Error::PubkeyCacheInconsistent) }) .collect() @@ -1650,13 +1652,11 @@ impl BeaconState { /// never re-add a pubkey. pub fn update_pubkey_cache(&mut self) -> Result<(), Error> { let mut pubkey_cache = mem::take(self.pubkey_cache_mut()); - for (i, validator) in self - .validators() - .iter() - .enumerate() - .skip(pubkey_cache.len()) - { - let success = pubkey_cache.insert(validator.pubkey, i); + let start_index = pubkey_cache.len(); + + for (i, validator) in self.validators().iter_from(start_index)?.enumerate() { + let index = start_index.safe_add(i)?; + let success = pubkey_cache.insert(validator.pubkey, index); if !success { return Err(Error::PubkeyCacheInconsistent); } diff --git a/lcli/Cargo.toml b/lcli/Cargo.toml index 339dfee5b1..2c734a0639 100644 --- a/lcli/Cargo.toml +++ b/lcli/Cargo.toml @@ -8,6 +8,7 @@ edition = "2018" [features] portable = ["bls/supranational-portable"] fake_crypto = ['bls/fake_crypto'] +tree-states = ["store/milhouse"] [dependencies] bls = { path = "../crypto/bls" } @@ -37,3 +38,4 @@ web3 = { version = "0.17.0", default-features = false, features = ["http-tls", " eth1_test_rig = { path = "../testing/eth1_test_rig" } sensitive_url = { path = "../common/sensitive_url" } eth2 = { path = "../common/eth2" } +store = { path = "../beacon_node/store" } diff --git a/lcli/src/replace_state_pubkeys.rs b/lcli/src/replace_state_pubkeys.rs index e9e3388c06..bba391aca8 100644 --- a/lcli/src/replace_state_pubkeys.rs +++ b/lcli/src/replace_state_pubkeys.rs @@ -42,7 +42,8 @@ pub fn run(testnet_dir: PathBuf, matches: &ArgMatches) -> Result<(), let mut deposit_tree = DepositDataTree::create(&[], 0, DEPOSIT_TREE_DEPTH); let mut deposit_root = Hash256::zero(); - for (index, validator) in state.validators_mut().iter_mut().enumerate() { + let mut validators = state.validators_mut(); + for index in 0..validators.len() { let (secret, _) = recover_validator_secret_from_mnemonic(seed.as_bytes(), index as u32, KeyType::Voting) .map_err(|e| format!("Unable to generate validator key: {:?}", e))?; @@ -52,11 +53,11 @@ pub fn run(testnet_dir: PathBuf, matches: &ArgMatches) -> Result<(), eprintln!("{}: {}", index, keypair.pk); - validator.pubkey = keypair.pk.into(); + validators.get_mut(index).unwrap().pubkey = keypair.pk.into(); // Update the deposit tree. let mut deposit_data = DepositData { - pubkey: validator.pubkey, + pubkey: validators.get(index).unwrap().pubkey, // Set this to a junk value since it's very time consuming to generate the withdrawal // keys and it's not useful for the time being. withdrawal_credentials: Hash256::zero(), @@ -69,6 +70,7 @@ pub fn run(testnet_dir: PathBuf, matches: &ArgMatches) -> Result<(), .map_err(|e| format!("failed to create deposit tree: {:?}", e))?; deposit_root = deposit_tree.root(); } + drop(validators); // Update the genesis validators root since we changed the validators. *state.genesis_validators_root_mut() = state.validators().tree_hash_root(); diff --git a/lcli/src/transition_blocks.rs b/lcli/src/transition_blocks.rs index f78c6b005e..3f539e49f7 100644 --- a/lcli/src/transition_blocks.rs +++ b/lcli/src/transition_blocks.rs @@ -43,7 +43,7 @@ pub fn run_transition_blocks( let block: SignedBeaconBlock = load_from_ssz_with(&block_path, spec, SignedBeaconBlock::from_ssz_bytes)?; - let post_state = do_transition(pre_state, block, spec)?; + let post_state = do_transition(pre_state.clone(), block, spec)?; let mut output_file = File::create(output_path).map_err(|e| format!("Unable to create output file: {:?}", e))?; @@ -52,6 +52,9 @@ pub fn run_transition_blocks( .write_all(&post_state.as_ssz_bytes()) .map_err(|e| format!("Unable to write to output file: {:?}", e))?; + drop(pre_state); + drop(post_state); + Ok(()) }