mirror of
https://github.com/sigp/lighthouse.git
synced 2026-05-08 01:05:47 +00:00
Fix replayer
This commit is contained in:
@@ -9,6 +9,7 @@ use crate::{
|
|||||||
per_slot_processing,
|
per_slot_processing,
|
||||||
};
|
};
|
||||||
use itertools::Itertools;
|
use itertools::Itertools;
|
||||||
|
use std::collections::HashMap;
|
||||||
use std::iter::Peekable;
|
use std::iter::Peekable;
|
||||||
use std::marker::PhantomData;
|
use std::marker::PhantomData;
|
||||||
use types::{
|
use types::{
|
||||||
@@ -288,17 +289,11 @@ where
|
|||||||
payload_envelopes: Vec<SignedExecutionPayloadEnvelope<E>>,
|
payload_envelopes: Vec<SignedExecutionPayloadEnvelope<E>>,
|
||||||
target_slot: Option<Slot>,
|
target_slot: Option<Slot>,
|
||||||
) -> Result<Self, Error> {
|
) -> Result<Self, Error> {
|
||||||
let mut envelopes_iter = payload_envelopes.into_iter();
|
let mut envelopes_by_slot: HashMap<Slot, SignedExecutionPayloadEnvelope<E>> =
|
||||||
|
payload_envelopes
|
||||||
let mut next_envelope_at_slot = |slot| {
|
.into_iter()
|
||||||
if let Some(envelope) = envelopes_iter.next()
|
.map(|e| (e.message.slot, e))
|
||||||
&& envelope.message.slot == slot
|
.collect();
|
||||||
{
|
|
||||||
Ok(envelope)
|
|
||||||
} else {
|
|
||||||
Err(BlockReplayError::MissingPayloadEnvelope { slot })
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
for (i, block) in blocks.iter().enumerate() {
|
for (i, block) in blocks.iter().enumerate() {
|
||||||
// Allow one additional block at the start which is only used for its state root.
|
// Allow one additional block at the start which is only used for its state root.
|
||||||
@@ -313,24 +308,41 @@ where
|
|||||||
// indicates that the parent is full (and it hasn't already been applied).
|
// indicates that the parent is full (and it hasn't already been applied).
|
||||||
state_root = if block.fork_name_unchecked().gloas_enabled()
|
state_root = if block.fork_name_unchecked().gloas_enabled()
|
||||||
&& self.state.slot() == self.state.latest_block_header().slot
|
&& self.state.slot() == self.state.latest_block_header().slot
|
||||||
&& self.state.payload_status() == StatePayloadStatus::Pending
|
|
||||||
{
|
{
|
||||||
let latest_bid_block_hash = self
|
if self.state.payload_status() == StatePayloadStatus::Pending {
|
||||||
.state
|
let latest_bid_block_hash = self
|
||||||
.latest_execution_payload_bid()
|
.state
|
||||||
.map_err(BlockReplayError::from)?
|
.latest_execution_payload_bid()
|
||||||
.block_hash;
|
.map_err(BlockReplayError::from)?
|
||||||
|
.block_hash;
|
||||||
|
|
||||||
// Similar to `is_parent_block_full`, but reading the block hash from the
|
// Similar to `is_parent_block_full`, but reading the block hash from the
|
||||||
// not-yet-applied `block`. The slot 0 case covers genesis (no block replay reqd).
|
// not-yet-applied `block`. The slot 0 case covers genesis (no block replay
|
||||||
if self.state.slot() != 0 && block.is_parent_block_full(latest_bid_block_hash) {
|
// reqd).
|
||||||
let envelope = next_envelope_at_slot(self.state.slot())?;
|
if self.state.slot() != 0
|
||||||
// State root for the next slot processing is now the envelope's state root.
|
&& block.is_parent_block_full(latest_bid_block_hash)
|
||||||
self.apply_payload_envelope(&envelope, state_root)?
|
{
|
||||||
|
let envelope = envelopes_by_slot.remove(&self.state.slot()).ok_or(
|
||||||
|
BlockReplayError::MissingPayloadEnvelope {
|
||||||
|
slot: self.state.slot(),
|
||||||
|
},
|
||||||
|
)?;
|
||||||
|
// State root for the next slot processing is now the envelope's
|
||||||
|
// state root.
|
||||||
|
self.apply_payload_envelope(&envelope, state_root)?
|
||||||
|
} else {
|
||||||
|
// Empty payload at this slot, the state root is unchanged from
|
||||||
|
// when the beacon block was applied.
|
||||||
|
state_root
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
// Empty payload at this slot, the state root is unchanged from when the
|
// Full: the envelope was already applied. Use its state_root so
|
||||||
// beacon block was applied.
|
// per_slot_processing stores the correct post-envelope root
|
||||||
state_root
|
// (not the pre-envelope block state root).
|
||||||
|
envelopes_by_slot
|
||||||
|
.get(&self.state.slot())
|
||||||
|
.map(|e| e.message.state_root)
|
||||||
|
.unwrap_or(state_root)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Pre-Gloas or at skipped slots post-Gloas, the state root of the parent state
|
// Pre-Gloas or at skipped slots post-Gloas, the state root of the parent state
|
||||||
@@ -384,7 +396,11 @@ where
|
|||||||
let mut opt_state_root = if let StatePayloadStatus::Full = self.desired_state_payload_status
|
let mut opt_state_root = if let StatePayloadStatus::Full = self.desired_state_payload_status
|
||||||
&& let Some(last_block) = blocks.last()
|
&& let Some(last_block) = blocks.last()
|
||||||
{
|
{
|
||||||
let envelope = next_envelope_at_slot(self.state.slot())?;
|
let envelope = envelopes_by_slot.remove(&self.state.slot()).ok_or(
|
||||||
|
BlockReplayError::MissingPayloadEnvelope {
|
||||||
|
slot: self.state.slot(),
|
||||||
|
},
|
||||||
|
)?;
|
||||||
Some(self.apply_payload_envelope(&envelope, last_block.state_root())?)
|
Some(self.apply_payload_envelope(&envelope, last_block.state_root())?)
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
|
|||||||
Reference in New Issue
Block a user