mirror of
https://github.com/sigp/lighthouse.git
synced 2026-03-16 19:32:55 +00:00
Merge remote-tracking branch 'origin/deneb-free-blobs' into tree-states
This commit is contained in:
@@ -1,27 +1,36 @@
|
||||
use crate::engines::ForkchoiceState;
|
||||
use crate::http::{
|
||||
ENGINE_FORKCHOICE_UPDATED_V1, ENGINE_FORKCHOICE_UPDATED_V2,
|
||||
ENGINE_FORKCHOICE_UPDATED_V1, ENGINE_FORKCHOICE_UPDATED_V2, ENGINE_FORKCHOICE_UPDATED_V3,
|
||||
ENGINE_GET_PAYLOAD_BODIES_BY_HASH_V1, ENGINE_GET_PAYLOAD_BODIES_BY_RANGE_V1,
|
||||
ENGINE_GET_PAYLOAD_V1, ENGINE_GET_PAYLOAD_V2, ENGINE_NEW_PAYLOAD_V1, ENGINE_NEW_PAYLOAD_V2,
|
||||
ENGINE_GET_PAYLOAD_V1, ENGINE_GET_PAYLOAD_V2, ENGINE_GET_PAYLOAD_V3, ENGINE_NEW_PAYLOAD_V1,
|
||||
ENGINE_NEW_PAYLOAD_V2, ENGINE_NEW_PAYLOAD_V3,
|
||||
};
|
||||
use eth2::types::{SsePayloadAttributes, SsePayloadAttributesV1, SsePayloadAttributesV2};
|
||||
pub use ethers_core::types::Transaction;
|
||||
use ethers_core::utils::rlp::{self, Decodable, Rlp};
|
||||
use eth2::types::{
|
||||
BlobsBundle, SsePayloadAttributes, SsePayloadAttributesV1, SsePayloadAttributesV2,
|
||||
SsePayloadAttributesV3,
|
||||
};
|
||||
use ethers_core::types::Transaction;
|
||||
use ethers_core::utils::rlp;
|
||||
use ethers_core::utils::rlp::{Decodable, Rlp};
|
||||
use http::deposit_methods::RpcError;
|
||||
pub use json_structures::{JsonWithdrawal, TransitionConfigurationV1};
|
||||
use pretty_reqwest_error::PrettyReqwestError;
|
||||
use reqwest::StatusCode;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use ssz_types::FixedVector;
|
||||
use state_processing::per_block_processing::deneb::kzg_commitment_to_versioned_hash;
|
||||
use std::convert::TryFrom;
|
||||
use strum::IntoStaticStr;
|
||||
use superstruct::superstruct;
|
||||
pub use types::{
|
||||
Address, EthSpec, ExecutionBlockHash, ExecutionPayload, ExecutionPayloadHeader,
|
||||
Address, BeaconBlockRef, EthSpec, ExecutionBlockHash, ExecutionPayload, ExecutionPayloadHeader,
|
||||
ExecutionPayloadRef, ForkName, Hash256, Transactions, Uint256, VariableList, Withdrawal,
|
||||
Withdrawals,
|
||||
};
|
||||
use types::{ExecutionPayloadCapella, ExecutionPayloadMerge};
|
||||
use types::{
|
||||
BeaconStateError, ExecutionPayloadCapella, ExecutionPayloadDeneb, ExecutionPayloadMerge,
|
||||
KzgProofs, VersionedHash,
|
||||
};
|
||||
|
||||
pub mod auth;
|
||||
pub mod http;
|
||||
@@ -49,14 +58,12 @@ pub enum Error {
|
||||
PayloadIdUnavailable,
|
||||
TransitionConfigurationMismatch,
|
||||
PayloadConversionLogicFlaw,
|
||||
DeserializeTransaction(ssz_types::Error),
|
||||
DeserializeTransactions(ssz_types::Error),
|
||||
SszError(ssz_types::Error),
|
||||
DeserializeWithdrawals(ssz_types::Error),
|
||||
BuilderApi(builder_client::Error),
|
||||
IncorrectStateVariant,
|
||||
RequiredMethodUnsupported(&'static str),
|
||||
UnsupportedForkVariant(String),
|
||||
BadConversion(String),
|
||||
RlpDecoderError(rlp::DecoderError),
|
||||
}
|
||||
|
||||
@@ -97,6 +104,12 @@ impl From<rlp::DecoderError> for Error {
|
||||
}
|
||||
}
|
||||
|
||||
impl From<ssz_types::Error> for Error {
|
||||
fn from(e: ssz_types::Error) -> Self {
|
||||
Error::SszError(e)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug, PartialEq, IntoStaticStr)]
|
||||
#[strum(serialize_all = "snake_case")]
|
||||
pub enum PayloadStatusV1Status {
|
||||
@@ -138,7 +151,7 @@ pub struct ExecutionBlock {
|
||||
|
||||
/// Representation of an execution block with enough detail to reconstruct a payload.
|
||||
#[superstruct(
|
||||
variants(Merge, Capella),
|
||||
variants(Merge, Capella, Deneb),
|
||||
variant_attributes(
|
||||
derive(Clone, Debug, PartialEq, Serialize, Deserialize,),
|
||||
serde(bound = "T: EthSpec", rename_all = "camelCase"),
|
||||
@@ -172,8 +185,14 @@ pub struct ExecutionBlockWithTransactions<T: EthSpec> {
|
||||
#[serde(rename = "hash")]
|
||||
pub block_hash: ExecutionBlockHash,
|
||||
pub transactions: Vec<Transaction>,
|
||||
#[superstruct(only(Capella))]
|
||||
#[superstruct(only(Capella, Deneb))]
|
||||
pub withdrawals: Vec<JsonWithdrawal>,
|
||||
#[superstruct(only(Deneb))]
|
||||
#[serde(with = "serde_utils::u64_hex_be")]
|
||||
pub blob_gas_used: u64,
|
||||
#[superstruct(only(Deneb))]
|
||||
#[serde(with = "serde_utils::u64_hex_be")]
|
||||
pub excess_blob_gas: u64,
|
||||
}
|
||||
|
||||
impl<T: EthSpec> TryFrom<ExecutionPayload<T>> for ExecutionBlockWithTransactions<T> {
|
||||
@@ -227,13 +246,39 @@ impl<T: EthSpec> TryFrom<ExecutionPayload<T>> for ExecutionBlockWithTransactions
|
||||
.collect(),
|
||||
})
|
||||
}
|
||||
ExecutionPayload::Deneb(block) => Self::Deneb(ExecutionBlockWithTransactionsDeneb {
|
||||
parent_hash: block.parent_hash,
|
||||
fee_recipient: block.fee_recipient,
|
||||
state_root: block.state_root,
|
||||
receipts_root: block.receipts_root,
|
||||
logs_bloom: block.logs_bloom,
|
||||
prev_randao: block.prev_randao,
|
||||
block_number: block.block_number,
|
||||
gas_limit: block.gas_limit,
|
||||
gas_used: block.gas_used,
|
||||
timestamp: block.timestamp,
|
||||
extra_data: block.extra_data,
|
||||
base_fee_per_gas: block.base_fee_per_gas,
|
||||
block_hash: block.block_hash,
|
||||
transactions: block
|
||||
.transactions
|
||||
.iter()
|
||||
.map(|tx| Transaction::decode(&Rlp::new(tx)))
|
||||
.collect::<Result<Vec<_>, _>>()?,
|
||||
withdrawals: Vec::from(block.withdrawals)
|
||||
.into_iter()
|
||||
.map(|withdrawal| withdrawal.into())
|
||||
.collect(),
|
||||
blob_gas_used: block.blob_gas_used,
|
||||
excess_blob_gas: block.excess_blob_gas,
|
||||
}),
|
||||
};
|
||||
Ok(json_payload)
|
||||
}
|
||||
}
|
||||
|
||||
#[superstruct(
|
||||
variants(V1, V2),
|
||||
variants(V1, V2, V3),
|
||||
variant_attributes(derive(Clone, Debug, Eq, Hash, PartialEq),),
|
||||
cast_error(ty = "Error", expr = "Error::IncorrectStateVariant"),
|
||||
partial_getter_error(ty = "Error", expr = "Error::IncorrectStateVariant")
|
||||
@@ -246,8 +291,10 @@ pub struct PayloadAttributes {
|
||||
pub prev_randao: Hash256,
|
||||
#[superstruct(getter(copy))]
|
||||
pub suggested_fee_recipient: Address,
|
||||
#[superstruct(only(V2))]
|
||||
#[superstruct(only(V2, V3))]
|
||||
pub withdrawals: Vec<Withdrawal>,
|
||||
#[superstruct(only(V3), partial_getter(copy))]
|
||||
pub parent_beacon_block_root: Hash256,
|
||||
}
|
||||
|
||||
impl PayloadAttributes {
|
||||
@@ -256,14 +303,24 @@ impl PayloadAttributes {
|
||||
prev_randao: Hash256,
|
||||
suggested_fee_recipient: Address,
|
||||
withdrawals: Option<Vec<Withdrawal>>,
|
||||
parent_beacon_block_root: Option<Hash256>,
|
||||
) -> Self {
|
||||
match withdrawals {
|
||||
Some(withdrawals) => PayloadAttributes::V2(PayloadAttributesV2 {
|
||||
timestamp,
|
||||
prev_randao,
|
||||
suggested_fee_recipient,
|
||||
withdrawals,
|
||||
}),
|
||||
Some(withdrawals) => match parent_beacon_block_root {
|
||||
Some(parent_beacon_block_root) => PayloadAttributes::V3(PayloadAttributesV3 {
|
||||
timestamp,
|
||||
prev_randao,
|
||||
suggested_fee_recipient,
|
||||
withdrawals,
|
||||
parent_beacon_block_root,
|
||||
}),
|
||||
None => PayloadAttributes::V2(PayloadAttributesV2 {
|
||||
timestamp,
|
||||
prev_randao,
|
||||
suggested_fee_recipient,
|
||||
withdrawals,
|
||||
}),
|
||||
},
|
||||
None => PayloadAttributes::V1(PayloadAttributesV1 {
|
||||
timestamp,
|
||||
prev_randao,
|
||||
@@ -296,6 +353,19 @@ impl From<PayloadAttributes> for SsePayloadAttributes {
|
||||
suggested_fee_recipient,
|
||||
withdrawals,
|
||||
}),
|
||||
PayloadAttributes::V3(PayloadAttributesV3 {
|
||||
timestamp,
|
||||
prev_randao,
|
||||
suggested_fee_recipient,
|
||||
withdrawals,
|
||||
parent_beacon_block_root,
|
||||
}) => Self::V3(SsePayloadAttributesV3 {
|
||||
timestamp,
|
||||
prev_randao,
|
||||
suggested_fee_recipient,
|
||||
withdrawals,
|
||||
parent_beacon_block_root,
|
||||
}),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -321,7 +391,7 @@ pub struct ProposeBlindedBlockResponse {
|
||||
}
|
||||
|
||||
#[superstruct(
|
||||
variants(Merge, Capella),
|
||||
variants(Merge, Capella, Deneb),
|
||||
variant_attributes(derive(Clone, Debug, PartialEq),),
|
||||
map_into(ExecutionPayload),
|
||||
map_ref_into(ExecutionPayloadRef),
|
||||
@@ -334,7 +404,27 @@ pub struct GetPayloadResponse<T: EthSpec> {
|
||||
pub execution_payload: ExecutionPayloadMerge<T>,
|
||||
#[superstruct(only(Capella), partial_getter(rename = "execution_payload_capella"))]
|
||||
pub execution_payload: ExecutionPayloadCapella<T>,
|
||||
#[superstruct(only(Deneb), partial_getter(rename = "execution_payload_deneb"))]
|
||||
pub execution_payload: ExecutionPayloadDeneb<T>,
|
||||
pub block_value: Uint256,
|
||||
#[superstruct(only(Deneb))]
|
||||
pub blobs_bundle: BlobsBundle<T>,
|
||||
#[superstruct(only(Deneb), partial_getter(copy))]
|
||||
pub should_override_builder: bool,
|
||||
}
|
||||
|
||||
impl<E: EthSpec> GetPayloadResponse<E> {
|
||||
pub fn fee_recipient(&self) -> Address {
|
||||
ExecutionPayloadRef::from(self.to_ref()).fee_recipient()
|
||||
}
|
||||
|
||||
pub fn block_hash(&self) -> ExecutionBlockHash {
|
||||
ExecutionPayloadRef::from(self.to_ref()).block_hash()
|
||||
}
|
||||
|
||||
pub fn block_number(&self) -> u64 {
|
||||
ExecutionPayloadRef::from(self.to_ref()).block_number()
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, T: EthSpec> From<GetPayloadResponseRef<'a, T>> for ExecutionPayloadRef<'a, T> {
|
||||
@@ -353,16 +443,25 @@ impl<T: EthSpec> From<GetPayloadResponse<T>> for ExecutionPayload<T> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: EthSpec> From<GetPayloadResponse<T>> for (ExecutionPayload<T>, Uint256) {
|
||||
impl<T: EthSpec> From<GetPayloadResponse<T>>
|
||||
for (ExecutionPayload<T>, Uint256, Option<BlobsBundle<T>>)
|
||||
{
|
||||
fn from(response: GetPayloadResponse<T>) -> Self {
|
||||
match response {
|
||||
GetPayloadResponse::Merge(inner) => (
|
||||
ExecutionPayload::Merge(inner.execution_payload),
|
||||
inner.block_value,
|
||||
None,
|
||||
),
|
||||
GetPayloadResponse::Capella(inner) => (
|
||||
ExecutionPayload::Capella(inner.execution_payload),
|
||||
inner.block_value,
|
||||
None,
|
||||
),
|
||||
GetPayloadResponse::Deneb(inner) => (
|
||||
ExecutionPayload::Deneb(inner.execution_payload),
|
||||
inner.block_value,
|
||||
Some(inner.blobs_bundle),
|
||||
),
|
||||
}
|
||||
}
|
||||
@@ -436,6 +535,138 @@ impl<E: EthSpec> ExecutionPayloadBodyV1<E> {
|
||||
))
|
||||
}
|
||||
}
|
||||
ExecutionPayloadHeader::Deneb(header) => {
|
||||
if let Some(withdrawals) = self.withdrawals {
|
||||
Ok(ExecutionPayload::Deneb(ExecutionPayloadDeneb {
|
||||
parent_hash: header.parent_hash,
|
||||
fee_recipient: header.fee_recipient,
|
||||
state_root: header.state_root,
|
||||
receipts_root: header.receipts_root,
|
||||
logs_bloom: header.logs_bloom,
|
||||
prev_randao: header.prev_randao,
|
||||
block_number: header.block_number,
|
||||
gas_limit: header.gas_limit,
|
||||
gas_used: header.gas_used,
|
||||
timestamp: header.timestamp,
|
||||
extra_data: header.extra_data,
|
||||
base_fee_per_gas: header.base_fee_per_gas,
|
||||
block_hash: header.block_hash,
|
||||
transactions: self.transactions,
|
||||
withdrawals,
|
||||
blob_gas_used: header.blob_gas_used,
|
||||
excess_blob_gas: header.excess_blob_gas,
|
||||
}))
|
||||
} else {
|
||||
Err(format!(
|
||||
"block {} is post capella but payload body doesn't have withdrawals",
|
||||
header.block_hash
|
||||
))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[superstruct(
|
||||
variants(Merge, Capella, Deneb),
|
||||
variant_attributes(derive(Clone, Debug, PartialEq),),
|
||||
map_into(ExecutionPayload),
|
||||
map_ref_into(ExecutionPayloadRef),
|
||||
cast_error(
|
||||
ty = "BeaconStateError",
|
||||
expr = "BeaconStateError::IncorrectStateVariant"
|
||||
),
|
||||
partial_getter_error(
|
||||
ty = "BeaconStateError",
|
||||
expr = "BeaconStateError::IncorrectStateVariant"
|
||||
)
|
||||
)]
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
pub struct NewPayloadRequest<E: EthSpec> {
|
||||
#[superstruct(only(Merge), partial_getter(rename = "execution_payload_merge"))]
|
||||
pub execution_payload: ExecutionPayloadMerge<E>,
|
||||
#[superstruct(only(Capella), partial_getter(rename = "execution_payload_capella"))]
|
||||
pub execution_payload: ExecutionPayloadCapella<E>,
|
||||
#[superstruct(only(Deneb), partial_getter(rename = "execution_payload_deneb"))]
|
||||
pub execution_payload: ExecutionPayloadDeneb<E>,
|
||||
#[superstruct(only(Deneb))]
|
||||
pub versioned_hashes: Vec<VersionedHash>,
|
||||
#[superstruct(only(Deneb))]
|
||||
pub parent_beacon_block_root: Hash256,
|
||||
}
|
||||
|
||||
impl<E: EthSpec> NewPayloadRequest<E> {
|
||||
pub fn parent_hash(&self) -> ExecutionBlockHash {
|
||||
match self {
|
||||
Self::Merge(payload) => payload.execution_payload.parent_hash,
|
||||
Self::Capella(payload) => payload.execution_payload.parent_hash,
|
||||
Self::Deneb(payload) => payload.execution_payload.parent_hash,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn block_hash(&self) -> ExecutionBlockHash {
|
||||
match self {
|
||||
Self::Merge(payload) => payload.execution_payload.block_hash,
|
||||
Self::Capella(payload) => payload.execution_payload.block_hash,
|
||||
Self::Deneb(payload) => payload.execution_payload.block_hash,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn block_number(&self) -> u64 {
|
||||
match self {
|
||||
Self::Merge(payload) => payload.execution_payload.block_number,
|
||||
Self::Capella(payload) => payload.execution_payload.block_number,
|
||||
Self::Deneb(payload) => payload.execution_payload.block_number,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn into_execution_payload(self) -> ExecutionPayload<E> {
|
||||
map_new_payload_request_into_execution_payload!(self, |request, cons| {
|
||||
cons(request.execution_payload)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, E: EthSpec> TryFrom<BeaconBlockRef<'a, E>> for NewPayloadRequest<E> {
|
||||
type Error = BeaconStateError;
|
||||
|
||||
fn try_from(block: BeaconBlockRef<'a, E>) -> Result<Self, Self::Error> {
|
||||
match block {
|
||||
BeaconBlockRef::Base(_) | BeaconBlockRef::Altair(_) => {
|
||||
Err(Self::Error::IncorrectStateVariant)
|
||||
}
|
||||
BeaconBlockRef::Merge(block_ref) => Ok(Self::Merge(NewPayloadRequestMerge {
|
||||
execution_payload: block_ref.body.execution_payload.execution_payload.clone(),
|
||||
})),
|
||||
BeaconBlockRef::Capella(block_ref) => Ok(Self::Capella(NewPayloadRequestCapella {
|
||||
execution_payload: block_ref.body.execution_payload.execution_payload.clone(),
|
||||
})),
|
||||
BeaconBlockRef::Deneb(block_ref) => Ok(Self::Deneb(NewPayloadRequestDeneb {
|
||||
execution_payload: block_ref.body.execution_payload.execution_payload.clone(),
|
||||
versioned_hashes: block_ref
|
||||
.body
|
||||
.blob_kzg_commitments
|
||||
.iter()
|
||||
.map(kzg_commitment_to_versioned_hash)
|
||||
.collect(),
|
||||
parent_beacon_block_root: block_ref.parent_root,
|
||||
})),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<E: EthSpec> TryFrom<ExecutionPayload<E>> for NewPayloadRequest<E> {
|
||||
type Error = BeaconStateError;
|
||||
|
||||
fn try_from(payload: ExecutionPayload<E>) -> Result<Self, Self::Error> {
|
||||
match payload {
|
||||
ExecutionPayload::Merge(payload) => Ok(Self::Merge(NewPayloadRequestMerge {
|
||||
execution_payload: payload,
|
||||
})),
|
||||
ExecutionPayload::Capella(payload) => Ok(Self::Capella(NewPayloadRequestCapella {
|
||||
execution_payload: payload,
|
||||
})),
|
||||
ExecutionPayload::Deneb(_) => Err(Self::Error::IncorrectStateVariant),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -444,12 +675,15 @@ impl<E: EthSpec> ExecutionPayloadBodyV1<E> {
|
||||
pub struct EngineCapabilities {
|
||||
pub new_payload_v1: bool,
|
||||
pub new_payload_v2: bool,
|
||||
pub new_payload_v3: bool,
|
||||
pub forkchoice_updated_v1: bool,
|
||||
pub forkchoice_updated_v2: bool,
|
||||
pub forkchoice_updated_v3: bool,
|
||||
pub get_payload_bodies_by_hash_v1: bool,
|
||||
pub get_payload_bodies_by_range_v1: bool,
|
||||
pub get_payload_v1: bool,
|
||||
pub get_payload_v2: bool,
|
||||
pub get_payload_v3: bool,
|
||||
}
|
||||
|
||||
impl EngineCapabilities {
|
||||
@@ -461,12 +695,18 @@ impl EngineCapabilities {
|
||||
if self.new_payload_v2 {
|
||||
response.push(ENGINE_NEW_PAYLOAD_V2);
|
||||
}
|
||||
if self.new_payload_v3 {
|
||||
response.push(ENGINE_NEW_PAYLOAD_V3);
|
||||
}
|
||||
if self.forkchoice_updated_v1 {
|
||||
response.push(ENGINE_FORKCHOICE_UPDATED_V1);
|
||||
}
|
||||
if self.forkchoice_updated_v2 {
|
||||
response.push(ENGINE_FORKCHOICE_UPDATED_V2);
|
||||
}
|
||||
if self.forkchoice_updated_v3 {
|
||||
response.push(ENGINE_FORKCHOICE_UPDATED_V3);
|
||||
}
|
||||
if self.get_payload_bodies_by_hash_v1 {
|
||||
response.push(ENGINE_GET_PAYLOAD_BODIES_BY_HASH_V1);
|
||||
}
|
||||
@@ -479,6 +719,9 @@ impl EngineCapabilities {
|
||||
if self.get_payload_v2 {
|
||||
response.push(ENGINE_GET_PAYLOAD_V2);
|
||||
}
|
||||
if self.get_payload_v3 {
|
||||
response.push(ENGINE_GET_PAYLOAD_V3);
|
||||
}
|
||||
|
||||
response
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user