diff --git a/beacon_node/store/src/errors.rs b/beacon_node/store/src/errors.rs index 30ee66074..3e1c6d012 100644 --- a/beacon_node/store/src/errors.rs +++ b/beacon_node/store/src/errors.rs @@ -3,7 +3,7 @@ use crate::config::StoreConfigError; use crate::hot_cold_store::HotColdDBError; use ssz::DecodeError; use state_processing::BlockReplayError; -use types::{BeaconStateError, Hash256, Slot}; +use types::{BeaconStateError, Hash256, InconsistentFork, Slot}; pub type Result = std::result::Result; @@ -45,6 +45,7 @@ pub enum Error { ResyncRequiredForExecutionPayloadSeparation, SlotClockUnavailableForMigration, V9MigrationFailure(Hash256), + InconsistentFork(InconsistentFork), } pub trait HandleUnavailable { @@ -103,6 +104,12 @@ impl From for Error { } } +impl From for Error { + fn from(e: InconsistentFork) -> Error { + Error::InconsistentFork(e) + } +} + #[derive(Debug)] pub struct DBError { pub message: String, diff --git a/beacon_node/store/src/hot_cold_store.rs b/beacon_node/store/src/hot_cold_store.rs index e8c782b8c..0f0d1460f 100644 --- a/beacon_node/store/src/hot_cold_store.rs +++ b/beacon_node/store/src/hot_cold_store.rs @@ -358,7 +358,8 @@ impl, Cold: ItemStore> HotColdDB } else if !self.config.prune_payloads { // If payload pruning is disabled there's a chance we may have the payload of // this finalized block. Attempt to load it but don't error in case it's missing. - if let Some(payload) = self.get_execution_payload(block_root)? { + let fork_name = blinded_block.fork_name(&self.spec)?; + if let Some(payload) = self.get_execution_payload(block_root, fork_name)? { DatabaseBlock::Full( blinded_block .try_into_full_block(Some(payload)) @@ -407,8 +408,9 @@ impl, Cold: ItemStore> HotColdDB blinded_block: SignedBeaconBlock>, ) -> Result, Error> { if blinded_block.message().execution_payload().is_ok() { + let fork_name = blinded_block.fork_name(&self.spec)?; let execution_payload = self - .get_execution_payload(block_root)? + .get_execution_payload(block_root, fork_name)? .ok_or(HotColdDBError::MissingExecutionPayload(*block_root))?; blinded_block.try_into_full_block(Some(execution_payload)) } else { @@ -451,9 +453,26 @@ impl, Cold: ItemStore> HotColdDB } /// Load the execution payload for a block from disk. + /// This method deserializes with the proper fork. pub fn get_execution_payload( &self, block_root: &Hash256, + fork_name: ForkName, + ) -> Result>, Error> { + let column = ExecutionPayload::::db_column().into(); + let key = block_root.as_bytes(); + + match self.hot_db.get_bytes(column, key)? { + Some(bytes) => Ok(Some(ExecutionPayload::from_ssz_bytes(&bytes, fork_name)?)), + None => Ok(None), + } + } + + /// Load the execution payload for a block from disk. + /// DANGEROUS: this method just guesses the fork. + pub fn get_execution_payload_dangerous_fork_agnostic( + &self, + block_root: &Hash256, ) -> Result>, Error> { self.get_item(block_root) }