Merge unstable 20230925 into deneb-free-blobs.

This commit is contained in:
Jimmy Chen
2023-09-26 10:32:18 +10:00
164 changed files with 3844 additions and 3057 deletions

View File

@@ -1,55 +1,58 @@
[package]
name = "execution_layer"
version = "0.1.0"
edition = "2021"
edition = { workspace = true }
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
types = { path = "../../consensus/types"}
tokio = { version = "1.10.0", features = ["full"] }
types = { workspace = true }
tokio = { workspace = true }
async-trait = "0.1.51"
slog = "2.5.2"
futures = "0.3.7"
sensitive_url = { path = "../../common/sensitive_url" }
reqwest = { version = "0.11.0", features = ["json","stream"] }
ethereum_serde_utils = "0.5.0"
serde_json = "1.0.58"
serde = { version = "1.0.116", features = ["derive"] }
warp = { version = "0.3.2", features = ["tls"] }
slog = { workspace = true }
futures = { workspace = true }
sensitive_url = { workspace = true }
reqwest = { workspace = true }
ethereum_serde_utils = { workspace = true }
serde_json = { workspace = true }
serde = { workspace = true }
warp = { workspace = true }
jsonwebtoken = "8"
environment = { path = "../../lighthouse/environment" }
bytes = "1.1.0"
task_executor = { path = "../../common/task_executor" }
hex = "0.4.2"
ethereum_ssz = "0.5.0"
ssz_types = "0.5.4"
eth2 = { path = "../../common/eth2" }
kzg = { path = "../../crypto/kzg" }
state_processing = { path = "../../consensus/state_processing" }
superstruct = "0.6.0"
lru = "0.7.1"
exit-future = "0.2.0"
tree_hash = "0.5.2"
tree_hash_derive = "0.5.0"
parking_lot = "0.12.0"
slot_clock = { path = "../../common/slot_clock" }
tempfile = "3.1.0"
rand = "0.8.5"
zeroize = { version = "1.4.2", features = ["zeroize_derive"] }
lighthouse_metrics = { path = "../../common/lighthouse_metrics" }
lazy_static = "1.4.0"
ethers-core = "1.0.2"
environment = { workspace = true }
bytes = { workspace = true }
task_executor = { workspace = true }
hex = { workspace = true }
ethereum_ssz = { workspace = true }
ssz_types = { workspace = true }
eth2 = { workspace = true }
kzg = { workspace = true }
state_processing = { workspace = true }
superstruct = { workspace = true }
lru = { workspace = true }
exit-future = { workspace = true }
tree_hash = { workspace = true }
tree_hash_derive = { workspace = true }
parking_lot = { workspace = true }
slot_clock = { workspace = true }
tempfile = { workspace = true }
rand = { workspace = true }
zeroize = { workspace = true }
lighthouse_metrics = { workspace = true }
lazy_static = { workspace = true }
ethers-core = { workspace = true }
builder_client = { path = "../builder_client" }
fork_choice = { path = "../../consensus/fork_choice" }
fork_choice = { workspace = true }
#PR: https://github.com/ralexstokes/mev-rs/pull/124
mev-rs = { git = "https://github.com/jimmygchen/mev-rs", rev = "dedc77a" }
axum = "0.6"
hyper = "0.14"
ethereum-consensus = { git = "https://github.com/ralexstokes/ethereum-consensus", rev = "12508c1f9b0c8f4bf4c5e9b6d441e840c1b37fd9" }
ssz_rs = "0.9.0"
tokio-stream = { version = "0.1.9", features = [ "sync" ] }
strum = "0.24.0"
tokio-stream = { workspace = true }
strum = { workspace = true }
keccak-hash = "0.10.0"
hash256-std-hasher = "0.15.2"
triehash = "0.8.4"
hash-db = "0.15.2"
pretty_reqwest_error = { path = "../../common/pretty_reqwest_error" }
pretty_reqwest_error = { workspace = true }
arc-swap = "1.6.0"

View File

@@ -5,6 +5,7 @@
//! deposit-contract functionality that the `beacon_node/eth1` crate already provides.
use crate::payload_cache::PayloadCache;
use arc_swap::ArcSwapOption;
use auth::{strip_prefix, Auth, JwtKey};
use builder_client::BuilderHttpClient;
pub use engine_api::EngineCapabilities;
@@ -301,7 +302,7 @@ type PayloadContentsRefTuple<'a, T> = (ExecutionPayloadRef<'a, T>, Option<&'a Bl
struct Inner<E: EthSpec> {
engine: Arc<Engine>,
builder: Option<BuilderHttpClient>,
builder: ArcSwapOption<BuilderHttpClient>,
execution_engine_forkchoice_lock: Mutex<()>,
suggested_fee_recipient: Option<Address>,
proposer_preparation_data: Mutex<HashMap<u64, ProposerPreparationDataEntry>>,
@@ -453,25 +454,9 @@ impl<T: EthSpec> ExecutionLayer<T> {
Engine::new(api, executor.clone(), &log)
};
let builder = builder_url
.map(|url| {
let builder_client = BuilderHttpClient::new(url.clone(), builder_user_agent)
.map_err(Error::Builder)?;
info!(
log,
"Using external block builder";
"builder_url" => ?url,
"builder_profit_threshold" => builder_profit_threshold,
"local_user_agent" => builder_client.get_user_agent(),
);
Ok::<_, Error>(builder_client)
})
.transpose()?;
let inner = Inner {
engine: Arc::new(engine),
builder,
builder: ArcSwapOption::empty(),
execution_engine_forkchoice_lock: <_>::default(),
suggested_fee_recipient,
proposer_preparation_data: Mutex::new(HashMap::new()),
@@ -486,19 +471,45 @@ impl<T: EthSpec> ExecutionLayer<T> {
last_new_payload_errored: RwLock::new(false),
};
Ok(Self {
let el = Self {
inner: Arc::new(inner),
})
}
}
};
if let Some(builder_url) = builder_url {
el.set_builder_url(builder_url, builder_user_agent)?;
}
Ok(el)
}
impl<T: EthSpec> ExecutionLayer<T> {
fn engine(&self) -> &Arc<Engine> {
&self.inner.engine
}
pub fn builder(&self) -> &Option<BuilderHttpClient> {
&self.inner.builder
pub fn builder(&self) -> Option<Arc<BuilderHttpClient>> {
self.inner.builder.load_full()
}
/// Set the builder URL after initialization.
///
/// This is useful for breaking circular dependencies between mock ELs and mock builders in
/// tests.
pub fn set_builder_url(
&self,
builder_url: SensitiveUrl,
builder_user_agent: Option<String>,
) -> Result<(), Error> {
let builder_client = BuilderHttpClient::new(builder_url.clone(), builder_user_agent)
.map_err(Error::Builder)?;
info!(
self.log(),
"Using external block builder";
"builder_url" => ?builder_url,
"builder_profit_threshold" => self.inner.builder_profit_threshold.as_u128(),
"local_user_agent" => builder_client.get_user_agent(),
);
self.inner.builder.swap(Some(Arc::new(builder_client)));
Ok(())
}
/// Cache a full payload, keyed on the `tree_hash_root` of the payload
@@ -655,9 +666,9 @@ impl<T: EthSpec> ExecutionLayer<T> {
///
/// This function is a wrapper over `Self::is_synced` that makes an additional
/// check for the execution layer sync status. Checks if the latest block has
/// a `block_number != 0`.
/// a `block_number != 0` *if* the `current_slot` is also `> 0`.
/// Returns the `Self::is_synced` response if unable to get latest block.
pub async fn is_synced_for_notifier(&self) -> bool {
pub async fn is_synced_for_notifier(&self, current_slot: Slot) -> bool {
let synced = self.is_synced().await;
if synced {
if let Ok(Some(block)) = self
@@ -666,7 +677,7 @@ impl<T: EthSpec> ExecutionLayer<T> {
.get_block_by_number(BlockByNumberQuery::Tag(LATEST_TAG))
.await
{
if block.block_number == 0 {
if block.block_number == 0 && current_slot > 0 {
return false;
}
}
@@ -1743,6 +1754,17 @@ impl<T: EthSpec> ExecutionLayer<T> {
}
}
pub async fn get_block_by_number(
&self,
query: BlockByNumberQuery<'_>,
) -> Result<Option<ExecutionBlock>, Error> {
self.engine()
.request(|engine| async move { engine.api.get_block_by_number(query).await })
.await
.map_err(Box::new)
.map_err(Error::EngineError)
}
pub async fn get_payload_by_hash_legacy(
&self,
hash: ExecutionBlockHash,

View File

@@ -42,6 +42,11 @@ use types::{
ExecutionPayloadHeader, ForkName, ForkVersionedResponse, Hash256, Slot, Uint256,
};
pub type MockBuilderServer = axum::Server<
hyper::server::conn::AddrIncoming,
axum::routing::IntoMakeService<axum::routing::Router>,
>;
#[derive(Clone)]
pub enum Operation {
FeeRecipient(Address),
@@ -166,19 +171,25 @@ impl BidStuff for BuilderBid {
}
}
pub struct TestingBuilder<E: EthSpec> {
server: BlindedBlockProviderServer<MockBuilder<E>>,
pub builder: MockBuilder<E>,
#[derive(Clone)]
pub struct MockBuilder<E: EthSpec> {
el: ExecutionLayer<E>,
beacon_client: BeaconNodeHttpClient,
spec: ChainSpec,
context: Arc<Context>,
val_registration_cache: Arc<RwLock<HashMap<BlsPublicKey, SignedValidatorRegistration>>>,
builder_sk: SecretKey,
operations: Arc<RwLock<Vec<Operation>>>,
invalidate_signatures: Arc<RwLock<bool>>,
}
impl<E: EthSpec> TestingBuilder<E> {
pub fn new(
impl<E: EthSpec> MockBuilder<E> {
pub fn new_for_testing(
mock_el_url: SensitiveUrl,
builder_url: SensitiveUrl,
beacon_url: SensitiveUrl,
spec: ChainSpec,
executor: TaskExecutor,
) -> Self {
) -> (Self, MockBuilderServer) {
let file = NamedTempFile::new().unwrap();
let path = file.path().into();
std::fs::write(&path, hex::encode(DEFAULT_JWT_SECRET)).unwrap();
@@ -207,39 +218,13 @@ impl<E: EthSpec> TestingBuilder<E> {
spec,
context,
);
let port = builder_url.full.port().unwrap();
let host: Ipv4Addr = builder_url
.full
.host_str()
.unwrap()
.to_string()
.parse()
.unwrap();
let server = BlindedBlockProviderServer::new(host, port, builder.clone());
Self { server, builder }
let host: Ipv4Addr = Ipv4Addr::LOCALHOST;
let port = 0;
let provider = BlindedBlockProviderServer::new(host, port, builder.clone());
let server = provider.serve();
(builder, server)
}
pub async fn run(&self) {
let server = self.server.serve();
if let Err(err) = server.await {
println!("error while listening for incoming: {err}")
}
}
}
#[derive(Clone)]
pub struct MockBuilder<E: EthSpec> {
el: ExecutionLayer<E>,
beacon_client: BeaconNodeHttpClient,
spec: ChainSpec,
context: Arc<Context>,
val_registration_cache: Arc<RwLock<HashMap<BlsPublicKey, SignedValidatorRegistration>>>,
builder_sk: SecretKey,
operations: Arc<RwLock<Vec<Operation>>>,
invalidate_signatures: Arc<RwLock<bool>>,
}
impl<E: EthSpec> MockBuilder<E> {
pub fn new(
el: ExecutionLayer<E>,
beacon_client: BeaconNodeHttpClient,

View File

@@ -34,7 +34,6 @@ impl<T: EthSpec> MockExecutionLayer<T> {
Some(JwtKey::from_slice(&DEFAULT_JWT_SECRET).unwrap()),
spec,
None,
None,
)
}
@@ -47,7 +46,6 @@ impl<T: EthSpec> MockExecutionLayer<T> {
builder_threshold: Option<u128>,
jwt_key: Option<JwtKey>,
spec: ChainSpec,
builder_url: Option<SensitiveUrl>,
kzg: Option<Kzg<T::Kzg>>,
) -> Self {
let handle = executor.handle().unwrap();
@@ -72,7 +70,6 @@ impl<T: EthSpec> MockExecutionLayer<T> {
let config = Config {
execution_endpoints: vec![url],
builder_url,
secret_files: vec![path],
suggested_fee_recipient: Some(Address::repeat_byte(42)),
builder_profit_threshold: builder_threshold.unwrap_or(DEFAULT_BUILDER_THRESHOLD_WEI),

View File

@@ -31,7 +31,7 @@ pub use execution_block_generator::{
pub use hook::Hook;
pub use mock_builder::{
convert_err, custom_err, from_ssz_rs, to_ssz_rs, Context as MockBuilderContext, MockBuilder,
Operation, TestingBuilder,
MockBuilderServer, Operation,
};
pub use mock_execution_layer::MockExecutionLayer;