Fix attestation withdrawals root mismatch (#4249)

## Issue Addressed

Addresses #4234 

## Proposed Changes

- Skip withdrawals processing in an inconsistent state replay. 
- Repurpose `StateRootStrategy`: rename to `StateProcessingStrategy` and always skip withdrawals if using `StateProcessingStrategy::Inconsistent`
- Add a test to reproduce the scenario


Co-authored-by: Jimmy Chen <jimmy@sigmaprime.io>
This commit is contained in:
Jimmy Chen
2023-05-09 10:48:15 +00:00
parent c7c51062ab
commit 8d9c748025
16 changed files with 230 additions and 41 deletions

View File

@@ -29,7 +29,7 @@ pub struct BlockReplayer<
> {
state: BeaconState<Spec>,
spec: &'a ChainSpec,
state_root_strategy: StateRootStrategy,
state_processing_strategy: StateProcessingStrategy,
block_sig_strategy: BlockSignatureStrategy,
verify_block_root: Option<VerifyBlockRoot>,
pre_block_hook: Option<PreBlockHook<'a, Spec, Error>>,
@@ -60,13 +60,13 @@ impl From<BlockProcessingError> for BlockReplayError {
}
}
/// Defines how state roots should be computed during block replay.
#[derive(PartialEq)]
pub enum StateRootStrategy {
/// Defines how state roots should be computed and whether to perform all state transitions during block replay.
#[derive(PartialEq, Clone, Copy)]
pub enum StateProcessingStrategy {
/// Perform all transitions faithfully to the specification.
Accurate,
/// Don't compute state roots, eventually computing an invalid beacon state that can only be
/// used for obtaining shuffling.
/// Don't compute state roots and process withdrawals, eventually computing an invalid beacon
/// state that can only be used for obtaining shuffling.
Inconsistent,
}
@@ -87,7 +87,7 @@ where
Self {
state,
spec,
state_root_strategy: StateRootStrategy::Accurate,
state_processing_strategy: StateProcessingStrategy::Accurate,
block_sig_strategy: BlockSignatureStrategy::VerifyBulk,
verify_block_root: Some(VerifyBlockRoot::True),
pre_block_hook: None,
@@ -100,12 +100,15 @@ where
}
}
/// Set the replayer's state root strategy different from the default.
pub fn state_root_strategy(mut self, state_root_strategy: StateRootStrategy) -> Self {
if state_root_strategy == StateRootStrategy::Inconsistent {
/// Set the replayer's state processing strategy different from the default.
pub fn state_processing_strategy(
mut self,
state_processing_strategy: StateProcessingStrategy,
) -> Self {
if state_processing_strategy == StateProcessingStrategy::Inconsistent {
self.verify_block_root = None;
}
self.state_root_strategy = state_root_strategy;
self.state_processing_strategy = state_processing_strategy;
self
}
@@ -182,7 +185,7 @@ where
i: usize,
) -> Result<Option<Hash256>, Error> {
// If we don't care about state roots then return immediately.
if self.state_root_strategy == StateRootStrategy::Inconsistent {
if self.state_processing_strategy == StateProcessingStrategy::Inconsistent {
return Ok(Some(Hash256::zero()));
}
@@ -249,7 +252,7 @@ where
// If no explicit policy is set, verify only the first 1 or 2 block roots if using
// accurate state roots. Inaccurate state roots require block root verification to
// be off.
if i <= 1 && self.state_root_strategy == StateRootStrategy::Accurate {
if i <= 1 && self.state_processing_strategy == StateProcessingStrategy::Accurate {
VerifyBlockRoot::True
} else {
VerifyBlockRoot::False
@@ -263,6 +266,7 @@ where
&mut self.state,
block,
self.block_sig_strategy,
self.state_processing_strategy,
verify_block_root,
&mut ctxt,
self.spec,