mirror of
https://github.com/sigp/lighthouse.git
synced 2026-03-09 11:41:51 +00:00
Deduplicate block root computation (#3590)
## Issue Addressed NA ## Proposed Changes This PR removes duplicated block root computation. Computing the `SignedBeaconBlock::canonical_root` has become more expensive since the merge as we need to compute the merke root of each transaction inside an `ExecutionPayload`. Computing the root for [a mainnet block](https://beaconcha.in/slot/4704236) is taking ~10ms on my i7-8700K CPU @ 3.70GHz (no sha extensions). Given that our median seen-to-imported time for blocks is presently 300-400ms, removing a few duplicated block roots (~30ms) could represent an easy 10% improvement. When we consider that the seen-to-imported times include operations *after* the block has been placed in the early attester cache, we could expect the 30ms to be more significant WRT our seen-to-attestable times. ## Additional Info NA
This commit is contained in:
@@ -1046,7 +1046,7 @@ pub fn serve<T: BeaconChainTypes>(
|
||||
chain: Arc<BeaconChain<T>>,
|
||||
network_tx: UnboundedSender<NetworkMessage<T::EthSpec>>,
|
||||
log: Logger| async move {
|
||||
publish_blocks::publish_block(block, chain, &network_tx, log)
|
||||
publish_blocks::publish_block(None, block, chain, &network_tx, log)
|
||||
.await
|
||||
.map(|()| warp::reply())
|
||||
},
|
||||
|
||||
@@ -9,13 +9,14 @@ use std::sync::Arc;
|
||||
use tokio::sync::mpsc::UnboundedSender;
|
||||
use tree_hash::TreeHash;
|
||||
use types::{
|
||||
BlindedPayload, ExecPayload, ExecutionBlockHash, ExecutionPayload, FullPayload,
|
||||
BlindedPayload, ExecPayload, ExecutionBlockHash, ExecutionPayload, FullPayload, Hash256,
|
||||
SignedBeaconBlock,
|
||||
};
|
||||
use warp::Rejection;
|
||||
|
||||
/// Handles a request from the HTTP API for full blocks.
|
||||
pub async fn publish_block<T: BeaconChainTypes>(
|
||||
block_root: Option<Hash256>,
|
||||
block: Arc<SignedBeaconBlock<T::EthSpec>>,
|
||||
chain: Arc<BeaconChain<T>>,
|
||||
network_tx: &UnboundedSender<NetworkMessage<T::EthSpec>>,
|
||||
@@ -31,8 +32,10 @@ pub async fn publish_block<T: BeaconChainTypes>(
|
||||
let delay = get_block_delay_ms(seen_timestamp, block.message(), &chain.slot_clock);
|
||||
metrics::observe_duration(&metrics::HTTP_API_BLOCK_BROADCAST_DELAY_TIMES, delay);
|
||||
|
||||
let block_root = block_root.unwrap_or_else(|| block.canonical_root());
|
||||
|
||||
match chain
|
||||
.process_block(block.clone(), CountUnrealized::True)
|
||||
.process_block(block_root, block.clone(), CountUnrealized::True)
|
||||
.await
|
||||
{
|
||||
Ok(root) => {
|
||||
@@ -127,8 +130,16 @@ pub async fn publish_blinded_block<T: BeaconChainTypes>(
|
||||
network_tx: &UnboundedSender<NetworkMessage<T::EthSpec>>,
|
||||
log: Logger,
|
||||
) -> Result<(), Rejection> {
|
||||
let full_block = reconstruct_block(chain.clone(), block, log.clone()).await?;
|
||||
publish_block::<T>(Arc::new(full_block), chain, network_tx, log).await
|
||||
let block_root = block.canonical_root();
|
||||
let full_block = reconstruct_block(chain.clone(), block_root, block, log.clone()).await?;
|
||||
publish_block::<T>(
|
||||
Some(block_root),
|
||||
Arc::new(full_block),
|
||||
chain,
|
||||
network_tx,
|
||||
log,
|
||||
)
|
||||
.await
|
||||
}
|
||||
|
||||
/// Deconstruct the given blinded block, and construct a full block. This attempts to use the
|
||||
@@ -136,6 +147,7 @@ pub async fn publish_blinded_block<T: BeaconChainTypes>(
|
||||
/// the full payload.
|
||||
async fn reconstruct_block<T: BeaconChainTypes>(
|
||||
chain: Arc<BeaconChain<T>>,
|
||||
block_root: Hash256,
|
||||
block: SignedBeaconBlock<T::EthSpec, BlindedPayload<T::EthSpec>>,
|
||||
log: Logger,
|
||||
) -> Result<SignedBeaconBlock<T::EthSpec, FullPayload<T::EthSpec>>, Rejection> {
|
||||
@@ -155,12 +167,15 @@ async fn reconstruct_block<T: BeaconChainTypes>(
|
||||
cached_payload
|
||||
// Otherwise, this means we are attempting a blind block proposal.
|
||||
} else {
|
||||
let full_payload = el.propose_blinded_beacon_block(&block).await.map_err(|e| {
|
||||
warp_utils::reject::custom_server_error(format!(
|
||||
"Blind block proposal failed: {:?}",
|
||||
e
|
||||
))
|
||||
})?;
|
||||
let full_payload = el
|
||||
.propose_blinded_beacon_block(block_root, &block)
|
||||
.await
|
||||
.map_err(|e| {
|
||||
warp_utils::reject::custom_server_error(format!(
|
||||
"Blind block proposal failed: {:?}",
|
||||
e
|
||||
))
|
||||
})?;
|
||||
info!(log, "Successfully published a block to the builder network"; "block_hash" => ?full_payload.block_hash);
|
||||
full_payload
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user