Fix stale beacon_state_root in test helpers (#9289)

Test helpers `add_attested_block_at_slot` and `add_attested_blocks_at_slot` accepted `state_root` argument which was computed before applying the block.


  


Co-Authored-By: hopinheimer <knmanas6@gmail.com>
This commit is contained in:
hopinheimer
2026-05-12 02:24:18 -04:00
committed by GitHub
parent f968c7e5bb
commit 757873200b
13 changed files with 118 additions and 226 deletions

View File

@@ -325,7 +325,7 @@ mod test {
.deterministic_keypairs(8)
.fresh_ephemeral_store()
.build();
let (mut state, _) = harness.get_current_state_and_root();
let mut state = harness.get_current_state();
state
.build_committee_cache(RelativeEpoch::Current, &harness.chain.spec)
.unwrap();

View File

@@ -1570,6 +1570,15 @@ where
mut state: Cow<BeaconState<E>>,
state_root: Hash256,
) -> Result<Attestation<E>, BeaconChainError> {
assert_eq!(
state.get_latest_block_root(state_root),
beacon_block_root,
"State must match beacon block root, state slot {:?} attestation slot {:?} state root {:?}",
state.latest_block_header().slot,
slot,
state_root,
);
let epoch = slot.epoch(E::slots_per_epoch());
if state.slot() > slot {
@@ -1594,6 +1603,13 @@ where
*state.get_block_root(target_slot)?
};
let payload_present = state.fork_name_unchecked().gloas_enabled()
&& state.latest_block_header().slot != slot
&& self
.chain
.canonical_head
.block_has_canonical_payload(&beacon_block_root, &self.spec)?;
Ok(Attestation::empty_for_signing(
index,
committee_len,
@@ -1604,7 +1620,7 @@ where
epoch,
root: target_root,
},
false,
payload_present,
&self.spec,
)?)
}
@@ -3111,13 +3127,11 @@ where
&self,
slot: Slot,
state: BeaconState<E>,
state_root: Hash256,
validators: &[usize],
) -> Result<(SignedBeaconBlockHash, BeaconState<E>), BlockError> {
self.add_attested_block_at_slot_with_sync(
slot,
state,
state_root,
validators,
SyncCommitteeStrategy::NoValidators,
)
@@ -3128,18 +3142,18 @@ where
&self,
slot: Slot,
state: BeaconState<E>,
state_root: Hash256,
validators: &[usize],
sync_committee_strategy: SyncCommitteeStrategy,
) -> Result<(SignedBeaconBlockHash, BeaconState<E>), BlockError> {
let (block_hash, block, state) = self.add_block_at_slot(slot, state).await?;
self.attest_block(&state, state_root, block_hash, &block.0, validators);
let (block_hash, block, mut new_state) = self.add_block_at_slot(slot, state).await?;
let new_state_root = new_state.canonical_root().unwrap();
self.attest_block(&new_state, new_state_root, block_hash, &block.0, validators);
if sync_committee_strategy == SyncCommitteeStrategy::AllValidators
&& state.current_sync_committee().is_ok()
&& new_state.current_sync_committee().is_ok()
{
self.sync_committee_sign_block(
&state,
&new_state,
block_hash.into(),
slot,
if (slot + 1).epoch(E::slots_per_epoch())
@@ -3153,19 +3167,17 @@ where
);
}
Ok((block_hash, state))
Ok((block_hash, new_state))
}
pub async fn add_attested_blocks_at_slots(
&self,
state: BeaconState<E>,
state_root: Hash256,
slots: &[Slot],
validators: &[usize],
) -> AddBlocksResult<E> {
self.add_attested_blocks_at_slots_with_sync(
state,
state_root,
slots,
validators,
SyncCommitteeStrategy::NoValidators,
@@ -3176,7 +3188,6 @@ where
pub async fn add_attested_blocks_at_slots_with_sync(
&self,
state: BeaconState<E>,
state_root: Hash256,
slots: &[Slot],
validators: &[usize],
sync_committee_strategy: SyncCommitteeStrategy,
@@ -3184,7 +3195,6 @@ where
assert!(!slots.is_empty());
self.add_attested_blocks_at_slots_given_lbh(
state,
state_root,
slots,
validators,
None,
@@ -3241,7 +3251,6 @@ where
pub async fn add_attested_blocks_at_slots_with_lc_data(
&self,
mut state: BeaconState<E>,
state_root: Hash256,
slots: &[Slot],
validators: &[usize],
mut latest_block_hash: Option<SignedBeaconBlockHash>,
@@ -3255,7 +3264,6 @@ where
.add_attested_block_at_slot_with_sync(
*slot,
state,
state_root,
validators,
sync_committee_strategy,
)
@@ -3281,7 +3289,6 @@ where
async fn add_attested_blocks_at_slots_given_lbh(
&self,
mut state: BeaconState<E>,
state_root: Hash256,
slots: &[Slot],
validators: &[usize],
mut latest_block_hash: Option<SignedBeaconBlockHash>,
@@ -3295,7 +3302,6 @@ where
let (block_hash, new_state) = Box::pin(self.add_attested_block_at_slot_with_sync(
*slot,
state,
state_root,
validators,
sync_committee_strategy,
))
@@ -3359,14 +3365,8 @@ where
for epoch in min_epoch.as_u64()..=max_epoch.as_u64() {
let mut new_chains = vec![];
for (
mut head_state,
slots,
validators,
mut block_hashes,
mut state_hashes,
head_block,
) in chains
for (head_state, slots, validators, mut block_hashes, mut state_hashes, head_block) in
chains
{
let epoch_slots = slots
.iter()
@@ -3374,11 +3374,9 @@ where
.copied()
.collect::<Vec<_>>();
let head_state_root = head_state.update_tree_hash_cache().unwrap();
let (new_block_hashes, new_state_hashes, new_head_block, new_head_state) = self
.add_attested_blocks_at_slots_given_lbh(
head_state,
head_state_root,
&epoch_slots,
&validators,
Some(head_block),
@@ -3540,7 +3538,7 @@ where
sync_committee_strategy: SyncCommitteeStrategy,
light_client_strategy: LightClientStrategy,
) -> Hash256 {
let (mut state, slots) = match block_strategy {
let (state, slots) = match block_strategy {
BlockStrategy::OnCanonicalHead => {
let current_slot: u64 = self.get_current_slot().into();
let slots: Vec<Slot> = (current_slot..(current_slot + (num_blocks as u64)))
@@ -3569,12 +3567,10 @@ where
AttestationStrategy::SomeValidators(vals) => vals,
};
let state_root = state.update_tree_hash_cache().unwrap();
let (_, _, last_produced_block_hash, _) = match light_client_strategy {
LightClientStrategy::Enabled => {
self.add_attested_blocks_at_slots_with_lc_data(
state,
state_root,
&slots,
&validators,
None,
@@ -3585,7 +3581,6 @@ where
LightClientStrategy::Disabled => {
self.add_attested_blocks_at_slots_with_sync(
state,
state_root,
&slots,
&validators,
sync_committee_strategy,