Merge branch 'unstable' of https://github.com/sigp/lighthouse into merge-unstable-deneb-jul-14

This commit is contained in:
realbigsean
2023-07-17 09:33:37 -04:00
51 changed files with 642 additions and 294 deletions

View File

@@ -75,7 +75,7 @@ impl<T: EthSpec> PackingEfficiencyHandler<T> {
available_attestations: HashSet::new(),
included_attestations: HashMap::new(),
committee_store: CommitteeStore::new(),
_phantom: PhantomData::default(),
_phantom: PhantomData,
};
handler.compute_epoch(start_epoch, &starting_state, spec)?;

View File

@@ -70,15 +70,32 @@ impl StateId {
.map_err(BeaconChainError::DBError)
.map_err(warp_utils::reject::beacon_chain_error)?
{
let execution_optimistic = chain
.canonical_head
.fork_choice_read_lock()
.is_optimistic_or_invalid_block_no_fallback(&hot_summary.latest_block_root)
.map_err(BeaconChainError::ForkChoiceError)
.map_err(warp_utils::reject::beacon_chain_error)?;
let finalized = chain
.is_finalized_state(root, hot_summary.slot)
let finalization_status = chain
.state_finalization_and_canonicity(root, hot_summary.slot)
.map_err(warp_utils::reject::beacon_chain_error)?;
let finalized = finalization_status.is_finalized();
let fork_choice = chain.canonical_head.fork_choice_read_lock();
let execution_optimistic = if finalization_status.slot_is_finalized
&& !finalization_status.canonical
{
// This block is permanently orphaned and has likely been pruned from fork
// choice. If it isn't found in fork choice, mark it optimistic to be on the
// safe side.
fork_choice
.is_optimistic_or_invalid_block_no_fallback(
&hot_summary.latest_block_root,
)
.unwrap_or(true)
} else {
// This block is either old and finalized, or recent and unfinalized, so
// it's safe to fallback to the optimistic status of the finalized block.
chain
.canonical_head
.fork_choice_read_lock()
.is_optimistic_or_invalid_block(&hot_summary.latest_block_root)
.map_err(BeaconChainError::ForkChoiceError)
.map_err(warp_utils::reject::beacon_chain_error)?
};
return Ok((*root, execution_optimistic, finalized));
} else if let Some(_cold_state_slot) = chain
.store

View File

@@ -2,8 +2,9 @@
use beacon_chain::{
chain_config::{DisallowedReOrgOffsets, ReOrgThreshold},
test_utils::{AttestationStrategy, BlockStrategy, SyncCommitteeStrategy},
ChainConfig,
};
use eth2::types::DepositContractData;
use eth2::types::{DepositContractData, StateId};
use execution_layer::{ForkchoiceState, PayloadAttributes};
use http_api::test_utils::InteractiveTester;
use parking_lot::Mutex;
@@ -17,7 +18,7 @@ use std::time::Duration;
use tree_hash::TreeHash;
use types::{
Address, Epoch, EthSpec, ExecPayload, ExecutionBlockHash, ForkName, FullPayload,
MainnetEthSpec, ProposerPreparationData, Slot,
MainnetEthSpec, MinimalEthSpec, ProposerPreparationData, Slot,
};
type E = MainnetEthSpec;
@@ -48,6 +49,76 @@ async fn deposit_contract_custom_network() {
assert_eq!(result, expected);
}
// Test that state lookups by root function correctly for states that are finalized but still
// present in the hot database, and have had their block pruned from fork choice.
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
async fn state_by_root_pruned_from_fork_choice() {
type E = MinimalEthSpec;
let validator_count = 24;
let spec = ForkName::latest().make_genesis_spec(E::default_spec());
let tester = InteractiveTester::<E>::new_with_initializer_and_mutator(
Some(spec.clone()),
validator_count,
Some(Box::new(move |builder| {
builder
.deterministic_keypairs(validator_count)
.fresh_ephemeral_store()
.chain_config(ChainConfig {
epochs_per_migration: 1024,
..ChainConfig::default()
})
})),
None,
)
.await;
let client = &tester.client;
let harness = &tester.harness;
// Create some chain depth and finalize beyond fork choice's pruning depth.
let num_epochs = 8_u64;
let num_initial = num_epochs * E::slots_per_epoch();
harness.advance_slot();
harness
.extend_chain_with_sync(
num_initial as usize,
BlockStrategy::OnCanonicalHead,
AttestationStrategy::AllValidators,
SyncCommitteeStrategy::NoValidators,
)
.await;
// Should now be finalized.
let finalized_epoch = harness.finalized_checkpoint().epoch;
assert_eq!(finalized_epoch, num_epochs - 2);
// The split slot should still be at 0.
assert_eq!(harness.chain.store.get_split_slot(), 0);
// States that are between the split and the finalized slot should be able to be looked up by
// state root.
for slot in 0..finalized_epoch.start_slot(E::slots_per_epoch()).as_u64() {
let state_root = harness
.chain
.state_root_at_slot(Slot::new(slot))
.unwrap()
.unwrap();
let response = client
.get_debug_beacon_states::<E>(StateId::Root(state_root))
.await
.unwrap()
.unwrap();
assert!(response.finalized.unwrap());
assert!(!response.execution_optimistic.unwrap());
let mut state = response.data;
assert_eq!(state.update_tree_hash_cache().unwrap(), state_root);
}
}
/// Data structure for tracking fork choice updates received by the mock execution layer.
#[derive(Debug, Default)]
struct ForkChoiceUpdates {