mirror of
https://github.com/sigp/lighthouse.git
synced 2026-03-10 12:11:59 +00:00
Connect up DB replay_blocks/load_blocks
This commit is contained in:
@@ -159,7 +159,8 @@ pub fn reset_fork_choice_to_finalization<E: EthSpec, Hot: ItemStore<E>, Cold: It
|
||||
// Replay blocks from finalized checkpoint back to head.
|
||||
// We do not replay attestations presently, relying on the absence of other blocks
|
||||
// to guarantee `head_block_root` as the head.
|
||||
let blocks = store
|
||||
// TODO(gloas): this code doesn't work anyway, could just delete all of it
|
||||
let (blocks, _envelopes) = store
|
||||
.load_blocks_to_replay(finalized_slot + 1, head_state.slot(), head_block_root)
|
||||
.map_err(|e| format!("Error loading blocks to replay for fork choice: {:?}", e))?;
|
||||
|
||||
|
||||
@@ -688,7 +688,7 @@ async fn block_replayer_hooks() {
|
||||
.add_attested_blocks_at_slots(state.clone(), state_root, &block_slots, &all_validators)
|
||||
.await;
|
||||
|
||||
let blocks = store
|
||||
let (blocks, envelopes) = store
|
||||
.load_blocks_to_replay(Slot::new(0), max_slot, end_block_root.into())
|
||||
.unwrap();
|
||||
|
||||
@@ -697,7 +697,6 @@ async fn block_replayer_hooks() {
|
||||
let mut pre_block_slots = vec![];
|
||||
let mut post_block_slots = vec![];
|
||||
|
||||
// TODO(gloas): handle payloads?
|
||||
let mut replay_state = BlockReplayer::<MinimalEthSpec>::new(state, &chain.spec)
|
||||
.pre_slot_hook(Box::new(|_, state| {
|
||||
pre_slots.push(state.slot());
|
||||
@@ -725,7 +724,7 @@ async fn block_replayer_hooks() {
|
||||
post_block_slots.push(block.slot());
|
||||
Ok(())
|
||||
}))
|
||||
.apply_blocks(blocks, vec![], None)
|
||||
.apply_blocks(blocks, envelopes, None)
|
||||
.unwrap()
|
||||
.into_state();
|
||||
|
||||
|
||||
@@ -32,7 +32,7 @@ pub fn get_block_rewards<T: BeaconChainTypes>(
|
||||
.map_err(unhandled_error)?
|
||||
.ok_or_else(|| custom_bad_request(format!("block at end slot {} unknown", end_slot)))?;
|
||||
|
||||
let blocks = chain
|
||||
let (blocks, envelopes) = chain
|
||||
.store
|
||||
.load_blocks_to_replay(start_slot, end_slot, end_block_root)
|
||||
.map_err(|e| unhandled_error(BeaconChainError::from(e)))?;
|
||||
@@ -56,7 +56,6 @@ pub fn get_block_rewards<T: BeaconChainTypes>(
|
||||
let mut reward_cache = Default::default();
|
||||
let mut block_rewards = Vec::with_capacity(blocks.len());
|
||||
|
||||
// TODO(gloas): handle payloads
|
||||
let block_replayer = BlockReplayer::new(state, &chain.spec)
|
||||
.pre_block_hook(Box::new(|state, block| {
|
||||
state.build_all_committee_caches(&chain.spec)?;
|
||||
@@ -79,7 +78,7 @@ pub fn get_block_rewards<T: BeaconChainTypes>(
|
||||
)
|
||||
.no_signature_verification()
|
||||
.minimal_block_root_verification()
|
||||
.apply_blocks(blocks, vec![], None)
|
||||
.apply_blocks(blocks, envelopes, None)
|
||||
.map_err(unhandled_error)?;
|
||||
|
||||
if block_replayer.state_root_miss() {
|
||||
|
||||
@@ -186,6 +186,7 @@ pub enum HotColdDBError {
|
||||
MissingHotHDiff(Hash256),
|
||||
MissingHDiff(Slot),
|
||||
MissingExecutionPayload(Hash256),
|
||||
MissingExecutionPayloadEnvelope(Hash256),
|
||||
MissingFullBlockExecutionPayloadPruned(Hash256, Slot),
|
||||
MissingAnchorInfo,
|
||||
MissingFrozenBlockSlot(Hash256),
|
||||
@@ -2020,7 +2021,8 @@ impl<E: EthSpec, Hot: ItemStore<E>, Cold: ItemStore<E>> HotColdDB<E, Hot, Cold>
|
||||
return Ok(base_state);
|
||||
}
|
||||
|
||||
let blocks = self.load_blocks_to_replay(base_state.slot(), slot, latest_block_root)?;
|
||||
let (blocks, envelopes) =
|
||||
self.load_blocks_to_replay(base_state.slot(), slot, latest_block_root)?;
|
||||
let _t = metrics::start_timer(&metrics::STORE_BEACON_REPLAY_HOT_BLOCKS_TIME);
|
||||
|
||||
// If replaying blocks, and `update_cache` is true, also cache the epoch boundary
|
||||
@@ -2053,6 +2055,7 @@ impl<E: EthSpec, Hot: ItemStore<E>, Cold: ItemStore<E>> HotColdDB<E, Hot, Cold>
|
||||
self.replay_blocks(
|
||||
base_state,
|
||||
blocks,
|
||||
envelopes,
|
||||
slot,
|
||||
no_state_root_iter(),
|
||||
Some(Box::new(state_cache_hook)),
|
||||
@@ -2357,6 +2360,8 @@ impl<E: EthSpec, Hot: ItemStore<E>, Cold: ItemStore<E>> HotColdDB<E, Hot, Cold>
|
||||
}
|
||||
|
||||
let blocks = self.load_cold_blocks(base_state.slot() + 1, slot)?;
|
||||
// TODO(gloas): load payload envelopes
|
||||
let envelopes = vec![];
|
||||
|
||||
// Include state root for base state as it is required by block processing to not
|
||||
// have to hash the state.
|
||||
@@ -2365,7 +2370,14 @@ impl<E: EthSpec, Hot: ItemStore<E>, Cold: ItemStore<E>> HotColdDB<E, Hot, Cold>
|
||||
self.forwards_state_roots_iterator_until(base_state.slot(), slot, || {
|
||||
Err(Error::StateShouldNotBeRequired(slot))
|
||||
})?;
|
||||
let state = self.replay_blocks(base_state, blocks, slot, Some(state_root_iter), None)?;
|
||||
let state = self.replay_blocks(
|
||||
base_state,
|
||||
blocks,
|
||||
envelopes,
|
||||
slot,
|
||||
Some(state_root_iter),
|
||||
None,
|
||||
)?;
|
||||
debug!(
|
||||
target_slot = %slot,
|
||||
replay_time_ms = metrics::stop_timer_with_duration(replay_timer).as_millis(),
|
||||
@@ -2480,18 +2492,31 @@ impl<E: EthSpec, Hot: ItemStore<E>, Cold: ItemStore<E>> HotColdDB<E, Hot, Cold>
|
||||
})?
|
||||
}
|
||||
|
||||
/// Load the blocks between `start_slot` and `end_slot` by backtracking from `end_block_hash`.
|
||||
/// Load the blocks & envelopes between `start_slot` and `end_slot` by backtracking from
|
||||
/// `end_block_root`.
|
||||
///
|
||||
/// Blocks are returned in slot-ascending order, suitable for replaying on a state with slot
|
||||
/// equal to `start_slot`, to reach a state with slot equal to `end_slot`.
|
||||
///
|
||||
/// Payloads are also returned in slot-ascending order, but only payloads forming part of
|
||||
/// the chain are loaded (payloads for EMPTY slots are omitted). Prior to Gloas, an empty
|
||||
/// vec of payloads will be returned.
|
||||
// TODO(gloas): handle last payload
|
||||
#[allow(clippy::type_complexity)]
|
||||
pub fn load_blocks_to_replay(
|
||||
&self,
|
||||
start_slot: Slot,
|
||||
end_slot: Slot,
|
||||
end_block_hash: Hash256,
|
||||
) -> Result<Vec<SignedBeaconBlock<E, BlindedPayload<E>>>, Error> {
|
||||
end_block_root: Hash256,
|
||||
) -> Result<
|
||||
(
|
||||
Vec<SignedBlindedBeaconBlock<E>>,
|
||||
Vec<SignedExecutionPayloadEnvelope<E>>,
|
||||
),
|
||||
Error,
|
||||
> {
|
||||
let _t = metrics::start_timer(&metrics::STORE_BEACON_LOAD_HOT_BLOCKS_TIME);
|
||||
let mut blocks = ParentRootBlockIterator::new(self, end_block_hash)
|
||||
let mut blocks = ParentRootBlockIterator::new(self, end_block_root)
|
||||
.map(|result| result.map(|(_, block)| block))
|
||||
// Include the block at the end slot (if any), it needs to be
|
||||
// replayed in order to construct the canonical state at `end_slot`.
|
||||
@@ -2518,7 +2543,35 @@ impl<E: EthSpec, Hot: ItemStore<E>, Cold: ItemStore<E>> HotColdDB<E, Hot, Cold>
|
||||
})
|
||||
.collect::<Result<Vec<_>, _>>()?;
|
||||
blocks.reverse();
|
||||
Ok(blocks)
|
||||
|
||||
// If Gloas is not enabled for any slots in the range, just return `blocks`.
|
||||
if !self.spec.fork_name_at_slot::<E>(start_slot).gloas_enabled()
|
||||
&& !self.spec.fork_name_at_slot::<E>(end_slot).gloas_enabled()
|
||||
{
|
||||
return Ok((blocks, vec![]));
|
||||
}
|
||||
|
||||
// Load envelopes.
|
||||
let mut envelopes = vec![];
|
||||
|
||||
for (block, next_block) in blocks.iter().tuple_windows() {
|
||||
if block.fork_name_unchecked().gloas_enabled() {
|
||||
// Check next block to see if this block's payload is canonical on this chain.
|
||||
let block_hash = block.payload_bid_block_hash()?;
|
||||
if !next_block.is_parent_block_full(block_hash) {
|
||||
// No payload at this slot (empty), nothing to load.
|
||||
continue;
|
||||
}
|
||||
// Using `parent_root` avoids computation.
|
||||
let block_root = next_block.parent_root();
|
||||
let envelope = self
|
||||
.get_payload_envelope(&block_root)?
|
||||
.ok_or(HotColdDBError::MissingExecutionPayloadEnvelope(block_root))?;
|
||||
envelopes.push(envelope);
|
||||
}
|
||||
}
|
||||
|
||||
Ok((blocks, envelopes))
|
||||
}
|
||||
|
||||
/// Replay `blocks` on top of `state` until `target_slot` is reached.
|
||||
@@ -2528,7 +2581,8 @@ impl<E: EthSpec, Hot: ItemStore<E>, Cold: ItemStore<E>> HotColdDB<E, Hot, Cold>
|
||||
pub fn replay_blocks(
|
||||
&self,
|
||||
state: BeaconState<E>,
|
||||
blocks: Vec<SignedBeaconBlock<E, BlindedPayload<E>>>,
|
||||
blocks: Vec<SignedBlindedBeaconBlock<E>>,
|
||||
envelopes: Vec<SignedExecutionPayloadEnvelope<E>>,
|
||||
target_slot: Slot,
|
||||
state_root_iter: Option<impl Iterator<Item = Result<(Hash256, Slot), Error>>>,
|
||||
pre_slot_hook: Option<PreSlotHook<E, Error>>,
|
||||
@@ -2548,9 +2602,8 @@ impl<E: EthSpec, Hot: ItemStore<E>, Cold: ItemStore<E>> HotColdDB<E, Hot, Cold>
|
||||
block_replayer = block_replayer.pre_slot_hook(pre_slot_hook);
|
||||
}
|
||||
|
||||
// TODO(gloas): plumb through payloads here
|
||||
block_replayer
|
||||
.apply_blocks(blocks, vec![], Some(target_slot))
|
||||
.apply_blocks(blocks, envelopes, Some(target_slot))
|
||||
.map(|block_replayer| {
|
||||
if have_state_root_iterator && block_replayer.state_root_miss() {
|
||||
warn!(
|
||||
|
||||
Reference in New Issue
Block a user