merge with unstable

This commit is contained in:
realbigsean
2022-11-01 13:18:00 -04:00
143 changed files with 4773 additions and 1876 deletions

View File

@@ -38,11 +38,11 @@ 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 = { git = "https://github.com/gakonst/ethers-rs", rev = "02ad93a1cfb7b62eb051c77c61dc4c0218428e4a" }
ethers-core = "0.17.0"
builder_client = { path = "../builder_client" }
fork_choice = { path = "../../consensus/fork_choice" }
mev-build-rs = {git = "https://github.com/ralexstokes/mev-rs", rev = "a088806575805c00d63fa59c002abc5eb1dc7709"}
ethereum-consensus = {git = "https://github.com/ralexstokes/ethereum-consensus", rev = "e1188b1" }
ssz-rs = {git = "https://github.com/ralexstokes/ssz-rs", rev = "cb08f1" }
mev-build-rs = { git = "https://github.com/ralexstokes/mev-rs", rev = "6c99b0fbdc0427b1625469d2e575303ce08de5b8" }
ethereum-consensus = { git = "https://github.com/ralexstokes/ethereum-consensus", rev = "a8110af76d97bf2bf27fb987a671808fcbdf1834" }
ssz-rs = { git = "https://github.com/ralexstokes/ssz-rs", rev = "cb08f1" }
tokio-stream = { version = "0.1.9", features = [ "sync" ] }
strum = "0.24.0"

View File

@@ -211,6 +211,7 @@ pub mod deposit_methods {
#[derive(Clone, Copy)]
pub enum BlockQuery {
Number(u64),
Hash(Hash256),
Latest,
}
@@ -325,9 +326,12 @@ pub mod deposit_methods {
query: BlockQuery,
timeout: Duration,
) -> Result<Block, String> {
let query_param = match query {
BlockQuery::Number(block_number) => format!("0x{:x}", block_number),
BlockQuery::Latest => "latest".to_string(),
let (method, query_param) = match query {
BlockQuery::Number(block_number) => {
("eth_getBlockByNumber", format!("0x{:x}", block_number))
}
BlockQuery::Hash(block_hash) => ("eth_getBlockByHash", format!("{:?}", block_hash)),
BlockQuery::Latest => ("eth_getBlockByNumber", "latest".to_string()),
};
let params = json!([
query_param,
@@ -335,9 +339,9 @@ pub mod deposit_methods {
]);
let response: Value = self
.rpc_request("eth_getBlockByNumber", params, timeout)
.rpc_request(method, params, timeout)
.await
.map_err(|e| format!("eth_getBlockByNumber call failed {:?}", e))?;
.map_err(|e| format!("{} call failed {:?}", method, e))?;
let hash: Vec<u8> = hex_to_bytes(
response
@@ -521,22 +525,32 @@ pub mod deposit_methods {
pub struct HttpJsonRpc {
pub client: Client,
pub url: SensitiveUrl,
pub execution_timeout_multiplier: u32,
auth: Option<Auth>,
}
impl HttpJsonRpc {
pub fn new(url: SensitiveUrl) -> Result<Self, Error> {
pub fn new(
url: SensitiveUrl,
execution_timeout_multiplier: Option<u32>,
) -> Result<Self, Error> {
Ok(Self {
client: Client::builder().build()?,
url,
execution_timeout_multiplier: execution_timeout_multiplier.unwrap_or(1),
auth: None,
})
}
pub fn new_with_auth(url: SensitiveUrl, auth: Auth) -> Result<Self, Error> {
pub fn new_with_auth(
url: SensitiveUrl,
auth: Auth,
execution_timeout_multiplier: Option<u32>,
) -> Result<Self, Error> {
Ok(Self {
client: Client::builder().build()?,
url,
execution_timeout_multiplier: execution_timeout_multiplier.unwrap_or(1),
auth: Some(auth),
})
}
@@ -593,7 +607,11 @@ impl std::fmt::Display for HttpJsonRpc {
impl HttpJsonRpc {
pub async fn upcheck(&self) -> Result<(), Error> {
let result: serde_json::Value = self
.rpc_request(ETH_SYNCING, json!([]), ETH_SYNCING_TIMEOUT)
.rpc_request(
ETH_SYNCING,
json!([]),
ETH_SYNCING_TIMEOUT * self.execution_timeout_multiplier,
)
.await?;
/*
@@ -617,7 +635,7 @@ impl HttpJsonRpc {
self.rpc_request(
ETH_GET_BLOCK_BY_NUMBER,
params,
ETH_GET_BLOCK_BY_NUMBER_TIMEOUT,
ETH_GET_BLOCK_BY_NUMBER_TIMEOUT * self.execution_timeout_multiplier,
)
.await
}
@@ -628,8 +646,12 @@ impl HttpJsonRpc {
) -> Result<Option<ExecutionBlock>, Error> {
let params = json!([block_hash, RETURN_FULL_TRANSACTION_OBJECTS]);
self.rpc_request(ETH_GET_BLOCK_BY_HASH, params, ETH_GET_BLOCK_BY_HASH_TIMEOUT)
.await
self.rpc_request(
ETH_GET_BLOCK_BY_HASH,
params,
ETH_GET_BLOCK_BY_HASH_TIMEOUT * self.execution_timeout_multiplier,
)
.await
}
pub async fn get_block_by_hash_with_txns<T: EthSpec>(
@@ -637,8 +659,12 @@ impl HttpJsonRpc {
block_hash: ExecutionBlockHash,
) -> Result<Option<ExecutionBlockWithTransactions<T>>, Error> {
let params = json!([block_hash, true]);
self.rpc_request(ETH_GET_BLOCK_BY_HASH, params, ETH_GET_BLOCK_BY_HASH_TIMEOUT)
.await
self.rpc_request(
ETH_GET_BLOCK_BY_HASH,
params,
ETH_GET_BLOCK_BY_HASH_TIMEOUT * self.execution_timeout_multiplier,
)
.await
}
pub async fn new_payload_v1<T: EthSpec>(
@@ -648,7 +674,11 @@ impl HttpJsonRpc {
let params = json!([JsonExecutionPayload::from(execution_payload)]);
let response: JsonPayloadStatusV1 = self
.rpc_request(ENGINE_NEW_PAYLOAD_V1, params, ENGINE_NEW_PAYLOAD_TIMEOUT)
.rpc_request(
ENGINE_NEW_PAYLOAD_V1,
params,
ENGINE_NEW_PAYLOAD_TIMEOUT * self.execution_timeout_multiplier,
)
.await?;
Ok(response.into())
@@ -661,7 +691,11 @@ impl HttpJsonRpc {
let params = json!([JsonPayloadIdRequest::from(payload_id)]);
let response: JsonExecutionPayload<T> = self
.rpc_request(ENGINE_GET_PAYLOAD_V1, params, ENGINE_GET_PAYLOAD_TIMEOUT)
.rpc_request(
ENGINE_GET_PAYLOAD_V1,
params,
ENGINE_GET_PAYLOAD_TIMEOUT * self.execution_timeout_multiplier,
)
.await?;
Ok(response.into())
@@ -698,7 +732,7 @@ impl HttpJsonRpc {
.rpc_request(
ENGINE_FORKCHOICE_UPDATED_V1,
params,
ENGINE_FORKCHOICE_UPDATED_TIMEOUT,
ENGINE_FORKCHOICE_UPDATED_TIMEOUT * self.execution_timeout_multiplier,
)
.await?;
@@ -715,7 +749,8 @@ impl HttpJsonRpc {
.rpc_request(
ENGINE_EXCHANGE_TRANSITION_CONFIGURATION_V1,
params,
ENGINE_EXCHANGE_TRANSITION_CONFIGURATION_V1_TIMEOUT,
ENGINE_EXCHANGE_TRANSITION_CONFIGURATION_V1_TIMEOUT
* self.execution_timeout_multiplier,
)
.await?;
@@ -755,13 +790,13 @@ mod test {
let echo_auth =
Auth::new(JwtKey::from_slice(&DEFAULT_JWT_SECRET).unwrap(), None, None);
(
Arc::new(HttpJsonRpc::new_with_auth(rpc_url, rpc_auth).unwrap()),
Arc::new(HttpJsonRpc::new_with_auth(echo_url, echo_auth).unwrap()),
Arc::new(HttpJsonRpc::new_with_auth(rpc_url, rpc_auth, None).unwrap()),
Arc::new(HttpJsonRpc::new_with_auth(echo_url, echo_auth, None).unwrap()),
)
} else {
(
Arc::new(HttpJsonRpc::new(rpc_url).unwrap()),
Arc::new(HttpJsonRpc::new(echo_url).unwrap()),
Arc::new(HttpJsonRpc::new(rpc_url, None).unwrap()),
Arc::new(HttpJsonRpc::new(echo_url, None).unwrap()),
)
};

View File

@@ -1,5 +1,6 @@
use super::*;
use serde::{Deserialize, Serialize};
use strum::EnumString;
use superstruct::superstruct;
use types::{
Blob, EthSpec, ExecutionBlockHash, ExecutionPayloadEip4844, ExecutionPayloadHeaderEip4844,
@@ -514,8 +515,9 @@ impl From<JsonForkChoiceStateV1> for ForkChoiceState {
}
}
#[derive(Debug, PartialEq, Serialize, Deserialize)]
#[derive(Debug, Clone, Copy, PartialEq, Serialize, Deserialize, EnumString)]
#[serde(rename_all = "SCREAMING_SNAKE_CASE")]
#[strum(serialize_all = "SCREAMING_SNAKE_CASE")]
pub enum JsonPayloadStatusV1Status {
Valid,
Invalid,

View File

@@ -226,6 +226,7 @@ pub struct Config {
pub default_datadir: PathBuf,
/// The minimum value of an external payload for it to be considered in a proposal.
pub builder_profit_threshold: u128,
pub execution_timeout_multiplier: Option<u32>,
}
/// Provides access to one execution engine and provides a neat interface for consumption by the
@@ -247,6 +248,7 @@ impl<T: EthSpec> ExecutionLayer<T> {
jwt_version,
default_datadir,
builder_profit_threshold,
execution_timeout_multiplier,
} = config;
if urls.len() > 1 {
@@ -291,7 +293,8 @@ impl<T: EthSpec> ExecutionLayer<T> {
let engine: Engine = {
let auth = Auth::new(jwt_key, jwt_id, jwt_version);
debug!(log, "Loaded execution endpoint"; "endpoint" => %execution_url, "jwt_path" => ?secret_file.as_path());
let api = HttpJsonRpc::new_with_auth(execution_url, auth).map_err(Error::ApiError)?;
let api = HttpJsonRpc::new_with_auth(execution_url, auth, execution_timeout_multiplier)
.map_err(Error::ApiError)?;
Engine::new(api, executor.clone(), &log)
};

View File

@@ -77,6 +77,11 @@ pub async fn handle_rpc<T: EthSpec>(
ENGINE_NEW_PAYLOAD_V1 => {
let request: JsonExecutionPayload<T> = get_param(params, 0)?;
// Canned responses set by block hash take priority.
if let Some(status) = ctx.get_new_payload_status(&request.block_hash) {
return Ok(serde_json::to_value(JsonPayloadStatusV1::from(status)).unwrap());
}
let (static_response, should_import) =
if let Some(mut response) = ctx.static_new_payload_response.lock().clone() {
if response.status.status == PayloadStatusV1Status::Valid {
@@ -120,6 +125,15 @@ pub async fn handle_rpc<T: EthSpec>(
let head_block_hash = forkchoice_state.head_block_hash;
// Canned responses set by block hash take priority.
if let Some(status) = ctx.get_fcu_payload_status(&head_block_hash) {
let response = JsonForkchoiceUpdatedV1Response {
payload_status: JsonPayloadStatusV1::from(status),
payload_id: None,
};
return Ok(serde_json::to_value(response).unwrap());
}
let mut response = ctx
.execution_block_generator
.write()

View File

@@ -12,6 +12,7 @@ use parking_lot::{Mutex, RwLock, RwLockWriteGuard};
use serde::{Deserialize, Serialize};
use serde_json::json;
use slog::{info, Logger};
use std::collections::HashMap;
use std::convert::Infallible;
use std::future::Future;
use std::marker::PhantomData;
@@ -98,6 +99,8 @@ impl<T: EthSpec> MockServer<T> {
static_new_payload_response: <_>::default(),
static_forkchoice_updated_response: <_>::default(),
static_get_block_by_hash_response: <_>::default(),
new_payload_statuses: <_>::default(),
fcu_payload_statuses: <_>::default(),
_phantom: PhantomData,
});
@@ -370,6 +373,25 @@ impl<T: EthSpec> MockServer<T> {
pub fn drop_all_blocks(&self) {
self.ctx.execution_block_generator.write().drop_all_blocks()
}
pub fn set_payload_statuses(&self, block_hash: ExecutionBlockHash, status: PayloadStatusV1) {
self.set_new_payload_status(block_hash, status.clone());
self.set_fcu_payload_status(block_hash, status);
}
pub fn set_new_payload_status(&self, block_hash: ExecutionBlockHash, status: PayloadStatusV1) {
self.ctx
.new_payload_statuses
.lock()
.insert(block_hash, status);
}
pub fn set_fcu_payload_status(&self, block_hash: ExecutionBlockHash, status: PayloadStatusV1) {
self.ctx
.fcu_payload_statuses
.lock()
.insert(block_hash, status);
}
}
#[derive(Debug)]
@@ -419,9 +441,33 @@ pub struct Context<T: EthSpec> {
pub static_new_payload_response: Arc<Mutex<Option<StaticNewPayloadResponse>>>,
pub static_forkchoice_updated_response: Arc<Mutex<Option<PayloadStatusV1>>>,
pub static_get_block_by_hash_response: Arc<Mutex<Option<Option<ExecutionBlock>>>>,
// Canned responses by block hash.
//
// This is a more flexible and less stateful alternative to `static_new_payload_response`
// and `preloaded_responses`.
pub new_payload_statuses: Arc<Mutex<HashMap<ExecutionBlockHash, PayloadStatusV1>>>,
pub fcu_payload_statuses: Arc<Mutex<HashMap<ExecutionBlockHash, PayloadStatusV1>>>,
pub _phantom: PhantomData<T>,
}
impl<T: EthSpec> Context<T> {
pub fn get_new_payload_status(
&self,
block_hash: &ExecutionBlockHash,
) -> Option<PayloadStatusV1> {
self.new_payload_statuses.lock().get(block_hash).cloned()
}
pub fn get_fcu_payload_status(
&self,
block_hash: &ExecutionBlockHash,
) -> Option<PayloadStatusV1> {
self.fcu_payload_statuses.lock().get(block_hash).cloned()
}
}
/// Configuration for the HTTP server.
#[derive(PartialEq, Debug, Clone, Serialize, Deserialize)]
pub struct Config {