This commit is contained in:
realbigsean
2022-10-03 10:06:04 -04:00
64 changed files with 1349 additions and 321 deletions

View File

@@ -7,9 +7,10 @@ use serde::{Deserialize, Serialize};
use strum::IntoStaticStr;
pub use types::{
Address, EthSpec, ExecutionBlockHash, ExecutionPayload, ExecutionPayloadHeader, FixedVector,
Hash256, Uint256, VariableList,
Hash256, Uint256, VariableList, kzg_proof::KzgProof, kzg_commitment::KzgCommitment, blob::Blob,
};
use types::{KZGCommitment};
use types::{KzgCommitment};
pub mod auth;
pub mod http;
@@ -170,6 +171,6 @@ pub struct ProposeBlindedBlockResponse {
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
pub struct BlobDetailsV1 {
kzg: KZGCommitment,
kzg: KzgCommitment,
blob: Vec<Hash256>,
}

View File

@@ -3,13 +3,14 @@
use super::*;
use crate::auth::Auth;
use crate::json_structures::*;
use eth2::lighthouse::Eth1Block;
use reqwest::header::CONTENT_TYPE;
use sensitive_url::SensitiveUrl;
use serde::de::DeserializeOwned;
use serde_json::json;
use std::time::Duration;
use types::EthSpec;
use types::{EthSpec, FullPayload, execution_payload::BlobsBundle};
pub use deposit_log::{DepositLog, Log};
pub use reqwest::Client;
@@ -34,8 +35,8 @@ pub const ENGINE_NEW_PAYLOAD_TIMEOUT: Duration = Duration::from_secs(8);
pub const ENGINE_GET_PAYLOAD_V1: &str = "engine_getPayloadV1";
pub const ENGINE_GET_PAYLOAD_TIMEOUT: Duration = Duration::from_secs(2);
pub const ENGINE_GET_BLOB_V1: &str = "engine_getBlobV1";
pub const ENGINE_GET_BLOB_TIMEOUT: Duration = Duration::from_secs(2);
pub const ENGINE_GET_BLOBS_BUNDLE_V1: &str = "engine_getBlobsBundleV1";
pub const ENGINE_GET_BLOBS_BUNDLE_TIMEOUT: Duration = Duration::from_secs(2);
pub const ENGINE_FORKCHOICE_UPDATED_V1: &str = "engine_forkchoiceUpdatedV1";
pub const ENGINE_FORKCHOICE_UPDATED_TIMEOUT: Duration = Duration::from_secs(8);
@@ -667,15 +668,14 @@ impl HttpJsonRpc {
Ok(response.into())
}
pub async fn get_blob_v1<T: EthSpec>(
pub async fn get_blobs_bundle_v1<T: EthSpec>(
&self,
payload_id: PayloadId,
versioned_hash: ExecutionBlockHash,
) -> Result<BlobDetailsV1, Error> {
let params = json!([JsonPayloadIdRequest::from(payload_id), versioned_hash]);
) -> Result<BlobsBundle<T>, Error> {
let params = json!([JsonPayloadIdRequest::from(payload_id)]);
let response: BlobDetailsV1 = self
.rpc_request(ENGINE_GET_BLOB_V1, params, ENGINE_GET_BLOB_TIMEOUT)
let response: JsonBlobBundlesV1<T> = self
.rpc_request(ENGINE_GET_BLOBS_BUNDLE_V1, params, ENGINE_GET_BLOBS_BUNDLE_TIMEOUT)
.await?;
Ok(response.into())

View File

@@ -1,6 +1,6 @@
use super::*;
use serde::{Deserialize, Serialize};
use types::{EthSpec, ExecutionBlockHash, FixedVector, Transaction, Unsigned, VariableList};
use types::{EthSpec, ExecutionBlockHash, FixedVector, Transaction, Unsigned, VariableList, execution_payload::BlobsBundle};
#[derive(Debug, PartialEq, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
@@ -269,6 +269,54 @@ impl From<JsonPayloadAttributesV1> for PayloadAttributes {
}
}
#[derive(Debug, PartialEq, Serialize, Deserialize)]
#[serde(bound = "T: EthSpec", rename_all = "camelCase")]
pub struct JsonBlobBundlesV1<T: EthSpec> {
pub block_hash: Hash256,
pub kzgs: Vec<KzgCommitment>,
pub blobs: Vec<Blob<T>>,
pub aggregated_proof: KzgProof,
}
impl <T: EthSpec> From<BlobsBundle<T>> for JsonBlobBundlesV1<T> {
fn from(p: BlobsBundle<T>) -> Self {
// Use this verbose deconstruction pattern to ensure no field is left unused.
let BlobsBundle {
block_hash,
aggregated_proof,
blobs,
kzgs,
} = p;
Self {
block_hash,
aggregated_proof,
blobs,
kzgs,
}
}
}
impl <T: EthSpec> From<JsonBlobBundlesV1<T>> for BlobsBundle<T> {
fn from(j: JsonBlobBundlesV1<T>) -> Self {
// Use this verbose deconstruction pattern to ensure no field is left unused.
let JsonBlobBundlesV1 {
block_hash,
aggregated_proof,
blobs,
kzgs,
} = j;
Self {
block_hash,
aggregated_proof,
blobs,
kzgs,
}
}
}
#[derive(Debug, PartialEq, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct JsonForkChoiceStateV1 {

View File

@@ -781,6 +781,55 @@ impl<T: EthSpec> ExecutionLayer<T> {
.await
}
pub async fn get_blob_bundles(
&self,
parent_hash: ExecutionBlockHash,
timestamp: u64,
prev_randao: Hash256,
suggested_fee_recipient: Address,
) -> Result<BlobsBundle<T>, Error> {
debug!(
self.log(),
"Issuing engine_getPayload";
"suggested_fee_recipient" => ?suggested_fee_recipient,
"prev_randao" => ?prev_randao,
"timestamp" => timestamp,
"parent_hash" => ?parent_hash,
);
self.engine()
.request(|engine| async move {
let payload_id = if let Some(id) = engine
.get_payload_id(parent_hash, timestamp, prev_randao, suggested_fee_recipient)
.await
{
// The payload id has been cached for this engine.
metrics::inc_counter_vec(
&metrics::EXECUTION_LAYER_PRE_PREPARED_PAYLOAD_ID,
&[metrics::HIT],
);
id
} else {
error!(
self.log(),
"Exec engine unable to produce blobs, did you call get_payload before?",
);
return Err(ApiError::PayloadIdUnavailable);
};
engine
.api
.get_blobs_bundle_v1::<T>(payload_id)
.await
.map(|bundle| {
// TODO verify the blob bundle here?
bundle.into()
})
})
.await
.map_err(Box::new)
.map_err(Error::EngineError)
}
async fn get_full_payload_with<Payload: ExecPayload<T>>(
&self,
parent_hash: ExecutionBlockHash,