Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 30 additions & 4 deletions beacon_node/beacon_chain/src/beacon_chain.rs
Original file line number Diff line number Diff line change
Expand Up @@ -911,7 +911,7 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
if let Some(block) = self.early_attester_cache.get_block(*block_root) {
return Ok(Some(block));
}
Ok(self.get_block(block_root).await?.map(Arc::new))
Ok(self.get_block(*block_root).await?.map(Arc::new))
}

/// Returns the block at the given root, if any.
Expand All @@ -921,11 +921,18 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
/// May return a database error.
pub async fn get_block(
&self,
block_root: &Hash256,
block_root: Hash256,
) -> Result<Option<SignedBeaconBlock<T::EthSpec>>, Error> {
// Load block from database, returning immediately if we have the full block w payload
// stored.
let blinded_block = match self.store.try_get_full_block(block_root)? {
let db = self.store.clone();
let database_block = self
.spawn_blocking_handle(
move || db.try_get_full_block(&block_root),
"beacon_chain_get_block_from_db",
)
.await??;
let blinded_block = match database_block {
Some(DatabaseBlock::Full(block)) => return Ok(Some(block)),
Some(DatabaseBlock::Blinded(block)) => block,
None => return Ok(None),
Expand All @@ -935,7 +942,7 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
let block_message = blinded_block.message();
let execution_payload_header = &block_message
.execution_payload()
.map_err(|_| Error::BlockVariantLacksExecutionPayload(*block_root))?
.map_err(|_| Error::BlockVariantLacksExecutionPayload(block_root))?
.execution_payload_header;

let exec_block_hash = execution_payload_header.block_hash;
Expand Down Expand Up @@ -970,6 +977,25 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
});
}

// If payload pruning is disabled, store this payload so we don't need to re-load it
// in future.
if !self.store.get_config().prune_payloads {
debug!(
self.log,
"Caching execution payload";
"block_root" => %block_root,
"slot" => blinded_block.slot(),
);

let db = self.store.clone();
let db_payload = execution_payload.clone();
self.spawn_blocking_handle(
move || db.put_execution_payload(&block_root, &db_payload),
"beacon_chain_store_downloaded_payload",
)
.await??;
}

// Add the payload to the block to form a full block.
blinded_block
.try_into_full_block(Some(execution_payload))
Expand Down
4 changes: 2 additions & 2 deletions beacon_node/beacon_chain/src/otb_verification_service.rs
Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,7 @@ pub async fn validate_optimistic_transition_blocks<T: BeaconChainTypes>(

// ensure finalized canonical otb are valid, otherwise kill client
for otb in finalized_canonical_otbs {
match chain.get_block(otb.root()).await {
match chain.get_block(*otb.root()).await {
Ok(Some(block)) => {
match validate_merge_block(chain, block.message(), AllowOptimisticImport::No).await
{
Expand Down Expand Up @@ -236,7 +236,7 @@ pub async fn validate_optimistic_transition_blocks<T: BeaconChainTypes>(

// attempt to validate any non-finalized canonical otb blocks
for otb in unfinalized_canonical_otbs {
match chain.get_block(otb.root()).await {
match chain.get_block(*otb.root()).await {
Ok(Some(block)) => {
match validate_merge_block(chain, block.message(), AllowOptimisticImport::No).await
{
Expand Down
4 changes: 2 additions & 2 deletions beacon_node/http_api/src/block_id.rs
Original file line number Diff line number Diff line change
Expand Up @@ -173,7 +173,7 @@ impl BlockId {
CoreBlockId::Slot(slot) => {
let (root, execution_optimistic) = self.root(chain)?;
chain
.get_block(&root)
.get_block(root)
.await
.map_err(warp_utils::reject::beacon_chain_error)
.and_then(|block_opt| match block_opt {
Expand All @@ -195,7 +195,7 @@ impl BlockId {
_ => {
let (root, execution_optimistic) = self.root(chain)?;
chain
.get_block(&root)
.get_block(root)
.await
.map_err(warp_utils::reject::beacon_chain_error)
.and_then(|block_opt| {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -351,7 +351,7 @@ impl<T: BeaconChainTypes> Worker<T> {
let mut send_response = true;

for root in block_roots {
match self.chain.get_block(&root).await {
match self.chain.get_block(root).await {
Ok(Some(block)) => {
// Due to skip slots, blocks could be out of the range, we ensure they
// are in the range before sending
Expand Down
12 changes: 12 additions & 0 deletions beacon_node/store/src/hot_cold_store.rs
Original file line number Diff line number Diff line change
Expand Up @@ -454,6 +454,18 @@ impl<E: EthSpec, Hot: ItemStore<E>, Cold: ItemStore<E>> HotColdDB<E, Hot, Cold>
self.get_item(block_root)
}

/// Store the execution payload for a block to disk.
///
/// This will commit immediately, usually you'll want to use a transaction.
pub fn put_execution_payload(
&self,
block_root: &Hash256,
execution_payload: &ExecutionPayload<E>,
) -> Result<(), Error> {
let ops = vec![execution_payload.as_kv_store_op(*block_root)];
self.hot_db.do_atomically(ops)
}

/// Check if the execution payload for a block exists on disk.
pub fn execution_payload_exists(&self, block_root: &Hash256) -> Result<bool, Error> {
self.get_item::<ExecutionPayload<E>>(block_root)
Expand Down