mirror of
https://github.com/sigp/lighthouse.git
synced 2026-03-16 11:22:56 +00:00
Engine API v1.0.0.alpha.6 + interop tests (#3024)
## Issue Addressed NA ## Proposed Changes This PR extends #3018 to address my review comments there and add automated integration tests with Geth (and other implementations, in the future). I've also de-duplicated the "unused port" logic by creating an `common/unused_port` crate. ## Additional Info I'm not sure if we want to merge this PR, or update #3018 and merge that. I don't mind, I'm primarily opening this PR to make sure CI works. Co-authored-by: Mark Mackey <mark@sigmaprime.io>
This commit is contained in:
@@ -1,6 +1,5 @@
|
||||
use crate::engine_api::{
|
||||
ExecutePayloadResponse, ExecutePayloadResponseStatus, ExecutionBlock, PayloadAttributes,
|
||||
PayloadId,
|
||||
ExecutionBlock, PayloadAttributes, PayloadId, PayloadStatusV1, PayloadStatusV1Status,
|
||||
};
|
||||
use crate::engines::ForkChoiceState;
|
||||
use serde::{Deserialize, Serialize};
|
||||
@@ -235,20 +234,20 @@ impl<T: EthSpec> ExecutionBlockGenerator<T> {
|
||||
self.payload_ids.remove(id)
|
||||
}
|
||||
|
||||
pub fn notify_new_payload(&mut self, payload: ExecutionPayload<T>) -> ExecutePayloadResponse {
|
||||
pub fn new_payload(&mut self, payload: ExecutionPayload<T>) -> PayloadStatusV1 {
|
||||
let parent = if let Some(parent) = self.blocks.get(&payload.parent_hash) {
|
||||
parent
|
||||
} else {
|
||||
return ExecutePayloadResponse {
|
||||
status: ExecutePayloadResponseStatus::Syncing,
|
||||
return PayloadStatusV1 {
|
||||
status: PayloadStatusV1Status::Syncing,
|
||||
latest_valid_hash: None,
|
||||
validation_error: None,
|
||||
};
|
||||
};
|
||||
|
||||
if payload.block_number != parent.block_number() + 1 {
|
||||
return ExecutePayloadResponse {
|
||||
status: ExecutePayloadResponseStatus::Invalid,
|
||||
return PayloadStatusV1 {
|
||||
status: PayloadStatusV1Status::Invalid,
|
||||
latest_valid_hash: Some(parent.block_hash()),
|
||||
validation_error: Some("invalid block number".to_string()),
|
||||
};
|
||||
@@ -257,8 +256,8 @@ impl<T: EthSpec> ExecutionBlockGenerator<T> {
|
||||
let valid_hash = payload.block_hash;
|
||||
self.pending_payloads.insert(payload.block_hash, payload);
|
||||
|
||||
ExecutePayloadResponse {
|
||||
status: ExecutePayloadResponseStatus::Valid,
|
||||
PayloadStatusV1 {
|
||||
status: PayloadStatusV1Status::Valid,
|
||||
latest_valid_hash: Some(valid_hash),
|
||||
validation_error: None,
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
use super::Context;
|
||||
use crate::engine_api::{http::*, ExecutePayloadResponse, ExecutePayloadResponseStatus};
|
||||
use crate::engine_api::{http::*, PayloadStatusV1, PayloadStatusV1Status};
|
||||
use crate::json_structures::*;
|
||||
use serde::de::DeserializeOwned;
|
||||
use serde_json::Value as JsonValue;
|
||||
@@ -54,30 +54,30 @@ pub async fn handle_rpc<T: EthSpec>(
|
||||
)
|
||||
.unwrap())
|
||||
}
|
||||
ENGINE_EXECUTE_PAYLOAD_V1 => {
|
||||
ENGINE_NEW_PAYLOAD_V1 => {
|
||||
let request: JsonExecutionPayloadV1<T> = get_param(params, 0)?;
|
||||
|
||||
let response = if let Some(status) = *ctx.static_notify_new_payload_response.lock() {
|
||||
let response = if let Some(status) = *ctx.static_new_payload_response.lock() {
|
||||
match status {
|
||||
ExecutePayloadResponseStatus::Valid => ExecutePayloadResponse {
|
||||
PayloadStatusV1Status::Valid => PayloadStatusV1 {
|
||||
status,
|
||||
latest_valid_hash: Some(request.block_hash),
|
||||
validation_error: None,
|
||||
},
|
||||
ExecutePayloadResponseStatus::Syncing => ExecutePayloadResponse {
|
||||
PayloadStatusV1Status::Syncing => PayloadStatusV1 {
|
||||
status,
|
||||
latest_valid_hash: None,
|
||||
validation_error: None,
|
||||
},
|
||||
_ => unimplemented!("invalid static executePayloadResponse"),
|
||||
_ => unimplemented!("invalid static newPayloadResponse"),
|
||||
}
|
||||
} else {
|
||||
ctx.execution_block_generator
|
||||
.write()
|
||||
.notify_new_payload(request.into())
|
||||
.new_payload(request.into())
|
||||
};
|
||||
|
||||
Ok(serde_json::to_value(JsonExecutePayloadV1Response::from(response)).unwrap())
|
||||
Ok(serde_json::to_value(JsonPayloadStatusV1::from(response)).unwrap())
|
||||
}
|
||||
ENGINE_GET_PAYLOAD_V1 => {
|
||||
let request: JsonPayloadIdRequest = get_param(params, 0)?;
|
||||
@@ -94,6 +94,8 @@ pub async fn handle_rpc<T: EthSpec>(
|
||||
ENGINE_FORKCHOICE_UPDATED_V1 => {
|
||||
let forkchoice_state: JsonForkChoiceStateV1 = get_param(params, 0)?;
|
||||
let payload_attributes: Option<JsonPayloadAttributesV1> = get_param(params, 1)?;
|
||||
|
||||
let head_block_hash = forkchoice_state.head_block_hash;
|
||||
let id = ctx
|
||||
.execution_block_generator
|
||||
.write()
|
||||
@@ -103,7 +105,11 @@ pub async fn handle_rpc<T: EthSpec>(
|
||||
)?;
|
||||
|
||||
Ok(serde_json::to_value(JsonForkchoiceUpdatedV1Response {
|
||||
status: JsonForkchoiceUpdatedV1ResponseStatus::Success,
|
||||
payload_status: JsonPayloadStatusV1 {
|
||||
status: JsonPayloadStatusV1Status::Valid,
|
||||
latest_valid_hash: Some(head_block_hash),
|
||||
validation_error: None,
|
||||
},
|
||||
payload_id: id.map(Into::into),
|
||||
})
|
||||
.unwrap())
|
||||
|
||||
@@ -147,8 +147,8 @@ impl<T: EthSpec> MockExecutionLayer<T> {
|
||||
|
||||
let (payload_response, latest_valid_hash) =
|
||||
self.el.notify_new_payload(&payload).await.unwrap();
|
||||
assert_eq!(payload_response, ExecutePayloadResponseStatus::Valid);
|
||||
assert_eq!(latest_valid_hash, Some(payload.block_hash));
|
||||
assert_eq!(payload_response, PayloadStatusV1Status::Valid);
|
||||
assert_eq!(latest_valid_hash, Some(vec![payload.block_hash]));
|
||||
|
||||
self.el
|
||||
.notify_forkchoice_updated(block_hash, Hash256::zero(), None)
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
//! Provides a mock execution engine HTTP JSON-RPC API for use in testing.
|
||||
|
||||
use crate::engine_api::http::JSONRPC_VERSION;
|
||||
use crate::engine_api::ExecutePayloadResponseStatus;
|
||||
use crate::engine_api::PayloadStatusV1Status;
|
||||
use bytes::Bytes;
|
||||
use environment::null_logger;
|
||||
use execution_block_generator::{Block, PoWBlock};
|
||||
@@ -62,7 +62,7 @@ impl<T: EthSpec> MockServer<T> {
|
||||
last_echo_request: last_echo_request.clone(),
|
||||
execution_block_generator: RwLock::new(execution_block_generator),
|
||||
preloaded_responses,
|
||||
static_notify_new_payload_response: <_>::default(),
|
||||
static_new_payload_response: <_>::default(),
|
||||
_phantom: PhantomData,
|
||||
});
|
||||
|
||||
@@ -117,8 +117,7 @@ impl<T: EthSpec> MockServer<T> {
|
||||
}
|
||||
|
||||
pub fn all_payloads_valid(&self) {
|
||||
*self.ctx.static_notify_new_payload_response.lock() =
|
||||
Some(ExecutePayloadResponseStatus::Valid)
|
||||
*self.ctx.static_new_payload_response.lock() = Some(PayloadStatusV1Status::Valid)
|
||||
}
|
||||
|
||||
pub fn insert_pow_block(
|
||||
@@ -188,7 +187,7 @@ pub struct Context<T: EthSpec> {
|
||||
pub last_echo_request: Arc<RwLock<Option<Bytes>>>,
|
||||
pub execution_block_generator: RwLock<ExecutionBlockGenerator<T>>,
|
||||
pub preloaded_responses: Arc<Mutex<Vec<serde_json::Value>>>,
|
||||
pub static_notify_new_payload_response: Arc<Mutex<Option<ExecutePayloadResponseStatus>>>,
|
||||
pub static_new_payload_response: Arc<Mutex<Option<PayloadStatusV1Status>>>,
|
||||
pub _phantom: PhantomData<T>,
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user