mirror of
https://github.com/sigp/lighthouse.git
synced 2026-05-08 17:26:04 +00:00
Add LRU cache for execution blocks
This commit is contained in:
1
Cargo.lock
generated
1
Cargo.lock
generated
@@ -2075,6 +2075,7 @@ dependencies = [
|
|||||||
"eth2_ssz_types",
|
"eth2_ssz_types",
|
||||||
"futures",
|
"futures",
|
||||||
"hex",
|
"hex",
|
||||||
|
"lru",
|
||||||
"reqwest",
|
"reqwest",
|
||||||
"sensitive_url",
|
"sensitive_url",
|
||||||
"serde",
|
"serde",
|
||||||
|
|||||||
@@ -23,3 +23,4 @@ bytes = "1.1.0"
|
|||||||
task_executor = { path = "../../common/task_executor" }
|
task_executor = { path = "../../common/task_executor" }
|
||||||
hex = "0.4.2"
|
hex = "0.4.2"
|
||||||
eth2_ssz_types = { path = "../../consensus/ssz_types"}
|
eth2_ssz_types = { path = "../../consensus/ssz_types"}
|
||||||
|
lru = "0.6.0"
|
||||||
|
|||||||
@@ -102,7 +102,6 @@ pub enum BlockByNumberQuery<'a> {
|
|||||||
#[serde(rename_all = "camelCase")]
|
#[serde(rename_all = "camelCase")]
|
||||||
pub struct ExecutionBlock {
|
pub struct ExecutionBlock {
|
||||||
pub block_hash: Hash256,
|
pub block_hash: Hash256,
|
||||||
pub block_number: u64,
|
|
||||||
pub parent_hash: Hash256,
|
pub parent_hash: Hash256,
|
||||||
pub total_difficulty: Uint256,
|
pub total_difficulty: Uint256,
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,10 +1,12 @@
|
|||||||
use engine_api::{Error as ApiError, *};
|
use engine_api::{Error as ApiError, *};
|
||||||
use engines::{Engine, EngineError, Engines};
|
use engines::{Engine, EngineError, Engines};
|
||||||
|
use lru::LruCache;
|
||||||
use sensitive_url::SensitiveUrl;
|
use sensitive_url::SensitiveUrl;
|
||||||
use slog::{crit, Logger};
|
use slog::{crit, Logger};
|
||||||
use std::future::Future;
|
use std::future::Future;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use task_executor::TaskExecutor;
|
use task_executor::TaskExecutor;
|
||||||
|
use tokio::sync::{Mutex, MutexGuard};
|
||||||
|
|
||||||
pub use engine_api::{http::HttpJsonRpc, ConsensusStatus, ExecutePayloadResponse};
|
pub use engine_api::{http::HttpJsonRpc, ConsensusStatus, ExecutePayloadResponse};
|
||||||
pub use execute_payload_handle::ExecutePayloadHandle;
|
pub use execute_payload_handle::ExecutePayloadHandle;
|
||||||
@@ -14,6 +16,8 @@ mod engines;
|
|||||||
mod execute_payload_handle;
|
mod execute_payload_handle;
|
||||||
pub mod test_utils;
|
pub mod test_utils;
|
||||||
|
|
||||||
|
const EXECUTION_BLOCKS_LRU_CACHE_SIZE: usize = 128;
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum Error {
|
pub enum Error {
|
||||||
ApiError(ApiError),
|
ApiError(ApiError),
|
||||||
@@ -33,6 +37,7 @@ struct Inner {
|
|||||||
engines: Engines<HttpJsonRpc>,
|
engines: Engines<HttpJsonRpc>,
|
||||||
terminal_total_difficulty: Uint256,
|
terminal_total_difficulty: Uint256,
|
||||||
fee_recipient: Option<Address>,
|
fee_recipient: Option<Address>,
|
||||||
|
execution_blocks: Mutex<LruCache<Hash256, ExecutionBlock>>,
|
||||||
executor: TaskExecutor,
|
executor: TaskExecutor,
|
||||||
log: Logger,
|
log: Logger,
|
||||||
}
|
}
|
||||||
@@ -66,6 +71,7 @@ impl ExecutionLayer {
|
|||||||
},
|
},
|
||||||
terminal_total_difficulty,
|
terminal_total_difficulty,
|
||||||
fee_recipient,
|
fee_recipient,
|
||||||
|
execution_blocks: Mutex::new(LruCache::new(EXECUTION_BLOCKS_LRU_CACHE_SIZE)),
|
||||||
executor,
|
executor,
|
||||||
log,
|
log,
|
||||||
};
|
};
|
||||||
@@ -95,6 +101,10 @@ impl ExecutionLayer {
|
|||||||
.ok_or(Error::FeeRecipientUnspecified)
|
.ok_or(Error::FeeRecipientUnspecified)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async fn execution_blocks(&self) -> MutexGuard<'_, LruCache<Hash256, ExecutionBlock>> {
|
||||||
|
self.inner.execution_blocks.lock().await
|
||||||
|
}
|
||||||
|
|
||||||
fn log(&self) -> &Logger {
|
fn log(&self) -> &Logger {
|
||||||
&self.inner.log
|
&self.inner.log
|
||||||
}
|
}
|
||||||
@@ -266,13 +276,27 @@ impl ExecutionLayer {
|
|||||||
.api
|
.api
|
||||||
.get_block_by_number(BlockByNumberQuery::Tag(LATEST_TAG))
|
.get_block_by_number(BlockByNumberQuery::Tag(LATEST_TAG))
|
||||||
.await?;
|
.await?;
|
||||||
|
self.execution_blocks().await.put(block.parent_hash, block);
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
if block.total_difficulty >= self.terminal_total_difficulty() {
|
if block.total_difficulty >= self.terminal_total_difficulty() {
|
||||||
ttd_exceeding_block = Some(block.block_hash);
|
ttd_exceeding_block = Some(block.block_hash);
|
||||||
|
|
||||||
// TODO(paul): add a LRU cache for these lookups.
|
let cached = self
|
||||||
block = engine.api.get_block_by_hash(block.parent_hash).await?;
|
.execution_blocks()
|
||||||
|
.await
|
||||||
|
.get(&block.parent_hash)
|
||||||
|
.copied();
|
||||||
|
if let Some(cached_block) = cached {
|
||||||
|
// The block was in the cache, no need to request it from the execution
|
||||||
|
// engine.
|
||||||
|
block = cached_block;
|
||||||
|
} else {
|
||||||
|
// The block was *not* in the cache, request it from the execution
|
||||||
|
// engine and cache it for future reference.
|
||||||
|
block = engine.api.get_block_by_hash(block.parent_hash).await?;
|
||||||
|
self.execution_blocks().await.put(block.parent_hash, block);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
return Ok::<_, ApiError>(ttd_exceeding_block);
|
return Ok::<_, ApiError>(ttd_exceeding_block);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user