mirror of
https://github.com/sigp/lighthouse.git
synced 2026-06-29 10:54:24 +00:00
Merge branch 'electra-engine-api' of https://github.com/sigp/lighthouse into beacon-api-electra
This commit is contained in:
@@ -3,7 +3,8 @@ use crate::http::{
|
|||||||
ENGINE_FORKCHOICE_UPDATED_V1, ENGINE_FORKCHOICE_UPDATED_V2, ENGINE_FORKCHOICE_UPDATED_V3,
|
ENGINE_FORKCHOICE_UPDATED_V1, ENGINE_FORKCHOICE_UPDATED_V2, ENGINE_FORKCHOICE_UPDATED_V3,
|
||||||
ENGINE_GET_CLIENT_VERSION_V1, ENGINE_GET_PAYLOAD_BODIES_BY_HASH_V1,
|
ENGINE_GET_CLIENT_VERSION_V1, ENGINE_GET_PAYLOAD_BODIES_BY_HASH_V1,
|
||||||
ENGINE_GET_PAYLOAD_BODIES_BY_RANGE_V1, ENGINE_GET_PAYLOAD_V1, ENGINE_GET_PAYLOAD_V2,
|
ENGINE_GET_PAYLOAD_BODIES_BY_RANGE_V1, ENGINE_GET_PAYLOAD_V1, ENGINE_GET_PAYLOAD_V2,
|
||||||
ENGINE_GET_PAYLOAD_V3, ENGINE_NEW_PAYLOAD_V1, ENGINE_NEW_PAYLOAD_V2, ENGINE_NEW_PAYLOAD_V3,
|
ENGINE_GET_PAYLOAD_V3, ENGINE_GET_PAYLOAD_V4, ENGINE_NEW_PAYLOAD_V1, ENGINE_NEW_PAYLOAD_V2,
|
||||||
|
ENGINE_NEW_PAYLOAD_V3, ENGINE_NEW_PAYLOAD_V4,
|
||||||
};
|
};
|
||||||
use eth2::types::{
|
use eth2::types::{
|
||||||
BlobsBundle, SsePayloadAttributes, SsePayloadAttributesV1, SsePayloadAttributesV2,
|
BlobsBundle, SsePayloadAttributes, SsePayloadAttributesV1, SsePayloadAttributesV2,
|
||||||
@@ -19,6 +20,7 @@ use reqwest::StatusCode;
|
|||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use strum::IntoStaticStr;
|
use strum::IntoStaticStr;
|
||||||
use superstruct::superstruct;
|
use superstruct::superstruct;
|
||||||
|
use types::execution_payload::{DepositReceipts, WithdrawalRequests};
|
||||||
pub use types::{
|
pub use types::{
|
||||||
Address, BeaconBlockRef, EthSpec, ExecutionBlockHash, ExecutionPayload, ExecutionPayloadHeader,
|
Address, BeaconBlockRef, EthSpec, ExecutionBlockHash, ExecutionPayload, ExecutionPayloadHeader,
|
||||||
ExecutionPayloadRef, FixedVector, ForkName, Hash256, Transactions, Uint256, VariableList,
|
ExecutionPayloadRef, FixedVector, ForkName, Hash256, Transactions, Uint256, VariableList,
|
||||||
@@ -40,6 +42,8 @@ pub use new_payload_request::{
|
|||||||
NewPayloadRequestDeneb, NewPayloadRequestElectra,
|
NewPayloadRequestDeneb, NewPayloadRequestElectra,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
use self::json_structures::{JsonDepositRequest, JsonWithdrawalRequest};
|
||||||
|
|
||||||
pub const LATEST_TAG: &str = "latest";
|
pub const LATEST_TAG: &str = "latest";
|
||||||
|
|
||||||
pub type PayloadId = [u8; 8];
|
pub type PayloadId = [u8; 8];
|
||||||
@@ -63,6 +67,8 @@ pub enum Error {
|
|||||||
TransitionConfigurationMismatch,
|
TransitionConfigurationMismatch,
|
||||||
SszError(ssz_types::Error),
|
SszError(ssz_types::Error),
|
||||||
DeserializeWithdrawals(ssz_types::Error),
|
DeserializeWithdrawals(ssz_types::Error),
|
||||||
|
DeserializeDepositReceipts(ssz_types::Error),
|
||||||
|
DeserializeWithdrawalRequests(ssz_types::Error),
|
||||||
BuilderApi(builder_client::Error),
|
BuilderApi(builder_client::Error),
|
||||||
IncorrectStateVariant,
|
IncorrectStateVariant,
|
||||||
RequiredMethodUnsupported(&'static str),
|
RequiredMethodUnsupported(&'static str),
|
||||||
@@ -197,6 +203,10 @@ pub struct ExecutionBlockWithTransactions<E: EthSpec> {
|
|||||||
#[superstruct(only(Deneb, Electra))]
|
#[superstruct(only(Deneb, Electra))]
|
||||||
#[serde(with = "serde_utils::u64_hex_be")]
|
#[serde(with = "serde_utils::u64_hex_be")]
|
||||||
pub excess_blob_gas: u64,
|
pub excess_blob_gas: u64,
|
||||||
|
#[superstruct(only(Electra))]
|
||||||
|
pub deposit_receipts: Vec<JsonDepositRequest>,
|
||||||
|
#[superstruct(only(Electra))]
|
||||||
|
pub withdrawal_requests: Vec<JsonWithdrawalRequest>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<E: EthSpec> TryFrom<ExecutionPayload<E>> for ExecutionBlockWithTransactions<E> {
|
impl<E: EthSpec> TryFrom<ExecutionPayload<E>> for ExecutionBlockWithTransactions<E> {
|
||||||
@@ -304,6 +314,16 @@ impl<E: EthSpec> TryFrom<ExecutionPayload<E>> for ExecutionBlockWithTransactions
|
|||||||
.collect(),
|
.collect(),
|
||||||
blob_gas_used: block.blob_gas_used,
|
blob_gas_used: block.blob_gas_used,
|
||||||
excess_blob_gas: block.excess_blob_gas,
|
excess_blob_gas: block.excess_blob_gas,
|
||||||
|
deposit_receipts: block
|
||||||
|
.deposit_receipts
|
||||||
|
.into_iter()
|
||||||
|
.map(|deposit| deposit.into())
|
||||||
|
.collect(),
|
||||||
|
withdrawal_requests: block
|
||||||
|
.withdrawal_requests
|
||||||
|
.into_iter()
|
||||||
|
.map(|withdrawal| withdrawal.into())
|
||||||
|
.collect(),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -526,6 +546,8 @@ impl<E: EthSpec> GetPayloadResponse<E> {
|
|||||||
pub struct ExecutionPayloadBodyV1<E: EthSpec> {
|
pub struct ExecutionPayloadBodyV1<E: EthSpec> {
|
||||||
pub transactions: Transactions<E>,
|
pub transactions: Transactions<E>,
|
||||||
pub withdrawals: Option<Withdrawals<E>>,
|
pub withdrawals: Option<Withdrawals<E>>,
|
||||||
|
pub deposit_receipts: Option<DepositReceipts<E>>,
|
||||||
|
pub withdrawal_requests: Option<WithdrawalRequests<E>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<E: EthSpec> ExecutionPayloadBodyV1<E> {
|
impl<E: EthSpec> ExecutionPayloadBodyV1<E> {
|
||||||
@@ -613,7 +635,17 @@ impl<E: EthSpec> ExecutionPayloadBodyV1<E> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
ExecutionPayloadHeader::Electra(header) => {
|
ExecutionPayloadHeader::Electra(header) => {
|
||||||
if let Some(withdrawals) = self.withdrawals {
|
let (Some(withdrawals), Some(deposit_receipts), Some(withdrawal_requests)) = (
|
||||||
|
self.withdrawals,
|
||||||
|
self.deposit_receipts,
|
||||||
|
self.withdrawal_requests,
|
||||||
|
) else {
|
||||||
|
return Err(format!(
|
||||||
|
"block {} is post-electra but payload body doesn't have withdrawals/deposit_receipts/withdrawal_requests \
|
||||||
|
Check that ELs are returning receipts and withdrawal_requests in getPayloadBody requests",
|
||||||
|
header.block_hash
|
||||||
|
))
|
||||||
|
};
|
||||||
Ok(ExecutionPayload::Electra(ExecutionPayloadElectra {
|
Ok(ExecutionPayload::Electra(ExecutionPayloadElectra {
|
||||||
parent_hash: header.parent_hash,
|
parent_hash: header.parent_hash,
|
||||||
fee_recipient: header.fee_recipient,
|
fee_recipient: header.fee_recipient,
|
||||||
@@ -632,16 +664,9 @@ impl<E: EthSpec> ExecutionPayloadBodyV1<E> {
|
|||||||
withdrawals,
|
withdrawals,
|
||||||
blob_gas_used: header.blob_gas_used,
|
blob_gas_used: header.blob_gas_used,
|
||||||
excess_blob_gas: header.excess_blob_gas,
|
excess_blob_gas: header.excess_blob_gas,
|
||||||
// TODO(electra)
|
deposit_receipts,
|
||||||
deposit_receipts: <_>::default(),
|
withdrawal_requests,
|
||||||
withdrawal_requests: <_>::default(),
|
|
||||||
}))
|
}))
|
||||||
} else {
|
|
||||||
Err(format!(
|
|
||||||
"block {} is post-capella but payload body doesn't have withdrawals",
|
|
||||||
header.block_hash
|
|
||||||
))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -652,6 +677,7 @@ pub struct EngineCapabilities {
|
|||||||
pub new_payload_v1: bool,
|
pub new_payload_v1: bool,
|
||||||
pub new_payload_v2: bool,
|
pub new_payload_v2: bool,
|
||||||
pub new_payload_v3: bool,
|
pub new_payload_v3: bool,
|
||||||
|
pub new_payload_v4: bool,
|
||||||
pub forkchoice_updated_v1: bool,
|
pub forkchoice_updated_v1: bool,
|
||||||
pub forkchoice_updated_v2: bool,
|
pub forkchoice_updated_v2: bool,
|
||||||
pub forkchoice_updated_v3: bool,
|
pub forkchoice_updated_v3: bool,
|
||||||
@@ -660,6 +686,7 @@ pub struct EngineCapabilities {
|
|||||||
pub get_payload_v1: bool,
|
pub get_payload_v1: bool,
|
||||||
pub get_payload_v2: bool,
|
pub get_payload_v2: bool,
|
||||||
pub get_payload_v3: bool,
|
pub get_payload_v3: bool,
|
||||||
|
pub get_payload_v4: bool,
|
||||||
pub get_client_version_v1: bool,
|
pub get_client_version_v1: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -675,6 +702,9 @@ impl EngineCapabilities {
|
|||||||
if self.new_payload_v3 {
|
if self.new_payload_v3 {
|
||||||
response.push(ENGINE_NEW_PAYLOAD_V3);
|
response.push(ENGINE_NEW_PAYLOAD_V3);
|
||||||
}
|
}
|
||||||
|
if self.new_payload_v4 {
|
||||||
|
response.push(ENGINE_NEW_PAYLOAD_V4);
|
||||||
|
}
|
||||||
if self.forkchoice_updated_v1 {
|
if self.forkchoice_updated_v1 {
|
||||||
response.push(ENGINE_FORKCHOICE_UPDATED_V1);
|
response.push(ENGINE_FORKCHOICE_UPDATED_V1);
|
||||||
}
|
}
|
||||||
@@ -699,6 +729,9 @@ impl EngineCapabilities {
|
|||||||
if self.get_payload_v3 {
|
if self.get_payload_v3 {
|
||||||
response.push(ENGINE_GET_PAYLOAD_V3);
|
response.push(ENGINE_GET_PAYLOAD_V3);
|
||||||
}
|
}
|
||||||
|
if self.get_payload_v4 {
|
||||||
|
response.push(ENGINE_GET_PAYLOAD_V4);
|
||||||
|
}
|
||||||
if self.get_client_version_v1 {
|
if self.get_client_version_v1 {
|
||||||
response.push(ENGINE_GET_CLIENT_VERSION_V1);
|
response.push(ENGINE_GET_CLIENT_VERSION_V1);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -34,11 +34,13 @@ pub const ETH_SYNCING_TIMEOUT: Duration = Duration::from_secs(1);
|
|||||||
pub const ENGINE_NEW_PAYLOAD_V1: &str = "engine_newPayloadV1";
|
pub const ENGINE_NEW_PAYLOAD_V1: &str = "engine_newPayloadV1";
|
||||||
pub const ENGINE_NEW_PAYLOAD_V2: &str = "engine_newPayloadV2";
|
pub const ENGINE_NEW_PAYLOAD_V2: &str = "engine_newPayloadV2";
|
||||||
pub const ENGINE_NEW_PAYLOAD_V3: &str = "engine_newPayloadV3";
|
pub const ENGINE_NEW_PAYLOAD_V3: &str = "engine_newPayloadV3";
|
||||||
|
pub const ENGINE_NEW_PAYLOAD_V4: &str = "engine_newPayloadV4";
|
||||||
pub const ENGINE_NEW_PAYLOAD_TIMEOUT: Duration = Duration::from_secs(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_V1: &str = "engine_getPayloadV1";
|
||||||
pub const ENGINE_GET_PAYLOAD_V2: &str = "engine_getPayloadV2";
|
pub const ENGINE_GET_PAYLOAD_V2: &str = "engine_getPayloadV2";
|
||||||
pub const ENGINE_GET_PAYLOAD_V3: &str = "engine_getPayloadV3";
|
pub const ENGINE_GET_PAYLOAD_V3: &str = "engine_getPayloadV3";
|
||||||
|
pub const ENGINE_GET_PAYLOAD_V4: &str = "engine_getPayloadV4";
|
||||||
pub const ENGINE_GET_PAYLOAD_TIMEOUT: Duration = Duration::from_secs(2);
|
pub const ENGINE_GET_PAYLOAD_TIMEOUT: Duration = Duration::from_secs(2);
|
||||||
|
|
||||||
pub const ENGINE_FORKCHOICE_UPDATED_V1: &str = "engine_forkchoiceUpdatedV1";
|
pub const ENGINE_FORKCHOICE_UPDATED_V1: &str = "engine_forkchoiceUpdatedV1";
|
||||||
@@ -66,9 +68,11 @@ pub static LIGHTHOUSE_CAPABILITIES: &[&str] = &[
|
|||||||
ENGINE_NEW_PAYLOAD_V1,
|
ENGINE_NEW_PAYLOAD_V1,
|
||||||
ENGINE_NEW_PAYLOAD_V2,
|
ENGINE_NEW_PAYLOAD_V2,
|
||||||
ENGINE_NEW_PAYLOAD_V3,
|
ENGINE_NEW_PAYLOAD_V3,
|
||||||
|
ENGINE_NEW_PAYLOAD_V4,
|
||||||
ENGINE_GET_PAYLOAD_V1,
|
ENGINE_GET_PAYLOAD_V1,
|
||||||
ENGINE_GET_PAYLOAD_V2,
|
ENGINE_GET_PAYLOAD_V2,
|
||||||
ENGINE_GET_PAYLOAD_V3,
|
ENGINE_GET_PAYLOAD_V3,
|
||||||
|
ENGINE_GET_PAYLOAD_V4,
|
||||||
ENGINE_FORKCHOICE_UPDATED_V1,
|
ENGINE_FORKCHOICE_UPDATED_V1,
|
||||||
ENGINE_FORKCHOICE_UPDATED_V2,
|
ENGINE_FORKCHOICE_UPDATED_V2,
|
||||||
ENGINE_FORKCHOICE_UPDATED_V3,
|
ENGINE_FORKCHOICE_UPDATED_V3,
|
||||||
@@ -833,7 +837,7 @@ impl HttpJsonRpc {
|
|||||||
Ok(response.into())
|
Ok(response.into())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn new_payload_v3_electra<E: EthSpec>(
|
pub async fn new_payload_v4_electra<E: EthSpec>(
|
||||||
&self,
|
&self,
|
||||||
new_payload_request_electra: NewPayloadRequestElectra<'_, E>,
|
new_payload_request_electra: NewPayloadRequestElectra<'_, E>,
|
||||||
) -> Result<PayloadStatusV1, Error> {
|
) -> Result<PayloadStatusV1, Error> {
|
||||||
@@ -845,7 +849,7 @@ impl HttpJsonRpc {
|
|||||||
|
|
||||||
let response: JsonPayloadStatusV1 = self
|
let response: JsonPayloadStatusV1 = self
|
||||||
.rpc_request(
|
.rpc_request(
|
||||||
ENGINE_NEW_PAYLOAD_V3,
|
ENGINE_NEW_PAYLOAD_V4,
|
||||||
params,
|
params,
|
||||||
ENGINE_NEW_PAYLOAD_TIMEOUT * self.execution_timeout_multiplier,
|
ENGINE_NEW_PAYLOAD_TIMEOUT * self.execution_timeout_multiplier,
|
||||||
)
|
)
|
||||||
@@ -929,19 +933,43 @@ impl HttpJsonRpc {
|
|||||||
.await?;
|
.await?;
|
||||||
Ok(JsonGetPayloadResponse::V3(response).into())
|
Ok(JsonGetPayloadResponse::V3(response).into())
|
||||||
}
|
}
|
||||||
|
ForkName::Base
|
||||||
|
| ForkName::Altair
|
||||||
|
| ForkName::Bellatrix
|
||||||
|
| ForkName::Capella
|
||||||
|
| ForkName::Electra => Err(Error::UnsupportedForkVariant(format!(
|
||||||
|
"called get_payload_v3 with {}",
|
||||||
|
fork_name
|
||||||
|
))),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn get_payload_v4<E: EthSpec>(
|
||||||
|
&self,
|
||||||
|
fork_name: ForkName,
|
||||||
|
payload_id: PayloadId,
|
||||||
|
) -> Result<GetPayloadResponse<E>, Error> {
|
||||||
|
let params = json!([JsonPayloadIdRequest::from(payload_id)]);
|
||||||
|
|
||||||
|
match fork_name {
|
||||||
ForkName::Electra => {
|
ForkName::Electra => {
|
||||||
let response: JsonGetPayloadResponseV4<E> = self
|
let response: JsonGetPayloadResponseV4<E> = self
|
||||||
.rpc_request(
|
.rpc_request(
|
||||||
ENGINE_GET_PAYLOAD_V3,
|
ENGINE_GET_PAYLOAD_V4,
|
||||||
params,
|
params,
|
||||||
ENGINE_GET_PAYLOAD_TIMEOUT * self.execution_timeout_multiplier,
|
ENGINE_GET_PAYLOAD_TIMEOUT * self.execution_timeout_multiplier,
|
||||||
)
|
)
|
||||||
.await?;
|
.await?;
|
||||||
Ok(JsonGetPayloadResponse::V4(response).into())
|
Ok(JsonGetPayloadResponse::V4(response).into())
|
||||||
}
|
}
|
||||||
ForkName::Base | ForkName::Altair | ForkName::Bellatrix | ForkName::Capella => Err(
|
ForkName::Base
|
||||||
Error::UnsupportedForkVariant(format!("called get_payload_v3 with {}", fork_name)),
|
| ForkName::Altair
|
||||||
),
|
| ForkName::Bellatrix
|
||||||
|
| ForkName::Capella
|
||||||
|
| ForkName::Deneb => Err(Error::UnsupportedForkVariant(format!(
|
||||||
|
"called get_payload_v4 with {}",
|
||||||
|
fork_name
|
||||||
|
))),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1067,6 +1095,7 @@ impl HttpJsonRpc {
|
|||||||
new_payload_v1: capabilities.contains(ENGINE_NEW_PAYLOAD_V1),
|
new_payload_v1: capabilities.contains(ENGINE_NEW_PAYLOAD_V1),
|
||||||
new_payload_v2: capabilities.contains(ENGINE_NEW_PAYLOAD_V2),
|
new_payload_v2: capabilities.contains(ENGINE_NEW_PAYLOAD_V2),
|
||||||
new_payload_v3: capabilities.contains(ENGINE_NEW_PAYLOAD_V3),
|
new_payload_v3: capabilities.contains(ENGINE_NEW_PAYLOAD_V3),
|
||||||
|
new_payload_v4: capabilities.contains(ENGINE_NEW_PAYLOAD_V4),
|
||||||
forkchoice_updated_v1: capabilities.contains(ENGINE_FORKCHOICE_UPDATED_V1),
|
forkchoice_updated_v1: capabilities.contains(ENGINE_FORKCHOICE_UPDATED_V1),
|
||||||
forkchoice_updated_v2: capabilities.contains(ENGINE_FORKCHOICE_UPDATED_V2),
|
forkchoice_updated_v2: capabilities.contains(ENGINE_FORKCHOICE_UPDATED_V2),
|
||||||
forkchoice_updated_v3: capabilities.contains(ENGINE_FORKCHOICE_UPDATED_V3),
|
forkchoice_updated_v3: capabilities.contains(ENGINE_FORKCHOICE_UPDATED_V3),
|
||||||
@@ -1077,6 +1106,7 @@ impl HttpJsonRpc {
|
|||||||
get_payload_v1: capabilities.contains(ENGINE_GET_PAYLOAD_V1),
|
get_payload_v1: capabilities.contains(ENGINE_GET_PAYLOAD_V1),
|
||||||
get_payload_v2: capabilities.contains(ENGINE_GET_PAYLOAD_V2),
|
get_payload_v2: capabilities.contains(ENGINE_GET_PAYLOAD_V2),
|
||||||
get_payload_v3: capabilities.contains(ENGINE_GET_PAYLOAD_V3),
|
get_payload_v3: capabilities.contains(ENGINE_GET_PAYLOAD_V3),
|
||||||
|
get_payload_v4: capabilities.contains(ENGINE_GET_PAYLOAD_V4),
|
||||||
get_client_version_v1: capabilities.contains(ENGINE_GET_CLIENT_VERSION_V1),
|
get_client_version_v1: capabilities.contains(ENGINE_GET_CLIENT_VERSION_V1),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -1199,11 +1229,11 @@ impl HttpJsonRpc {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
NewPayloadRequest::Electra(new_payload_request_electra) => {
|
NewPayloadRequest::Electra(new_payload_request_electra) => {
|
||||||
if engine_capabilities.new_payload_v3 {
|
if engine_capabilities.new_payload_v4 {
|
||||||
self.new_payload_v3_electra(new_payload_request_electra)
|
self.new_payload_v4_electra(new_payload_request_electra)
|
||||||
.await
|
.await
|
||||||
} else {
|
} else {
|
||||||
Err(Error::RequiredMethodUnsupported("engine_newPayloadV3"))
|
Err(Error::RequiredMethodUnsupported("engine_newPayloadV4"))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1221,17 +1251,24 @@ impl HttpJsonRpc {
|
|||||||
ForkName::Bellatrix | ForkName::Capella => {
|
ForkName::Bellatrix | ForkName::Capella => {
|
||||||
if engine_capabilities.get_payload_v2 {
|
if engine_capabilities.get_payload_v2 {
|
||||||
self.get_payload_v2(fork_name, payload_id).await
|
self.get_payload_v2(fork_name, payload_id).await
|
||||||
} else if engine_capabilities.new_payload_v1 {
|
} else if engine_capabilities.get_payload_v1 {
|
||||||
self.get_payload_v1(payload_id).await
|
self.get_payload_v1(payload_id).await
|
||||||
} else {
|
} else {
|
||||||
Err(Error::RequiredMethodUnsupported("engine_getPayload"))
|
Err(Error::RequiredMethodUnsupported("engine_getPayload"))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ForkName::Deneb | ForkName::Electra => {
|
ForkName::Deneb => {
|
||||||
if engine_capabilities.get_payload_v3 {
|
if engine_capabilities.get_payload_v3 {
|
||||||
self.get_payload_v3(fork_name, payload_id).await
|
self.get_payload_v3(fork_name, payload_id).await
|
||||||
} else {
|
} else {
|
||||||
Err(Error::RequiredMethodUnsupported("engine_getPayloadV3"))
|
Err(Error::RequiredMethodUnsupported("engine_getPayloadv3"))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ForkName::Electra => {
|
||||||
|
if engine_capabilities.get_payload_v4 {
|
||||||
|
self.get_payload_v4(fork_name, payload_id).await
|
||||||
|
} else {
|
||||||
|
Err(Error::RequiredMethodUnsupported("engine_getPayloadv4"))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ForkName::Base | ForkName::Altair => Err(Error::UnsupportedForkVariant(format!(
|
ForkName::Base | ForkName::Altair => Err(Error::UnsupportedForkVariant(format!(
|
||||||
|
|||||||
@@ -4,7 +4,10 @@ use strum::EnumString;
|
|||||||
use superstruct::superstruct;
|
use superstruct::superstruct;
|
||||||
use types::beacon_block_body::KzgCommitments;
|
use types::beacon_block_body::KzgCommitments;
|
||||||
use types::blob_sidecar::BlobsList;
|
use types::blob_sidecar::BlobsList;
|
||||||
use types::{FixedVector, Unsigned};
|
use types::{
|
||||||
|
DepositReceipt, ExecutionLayerWithdrawalRequest, FixedVector, PublicKeyBytes, Signature,
|
||||||
|
Unsigned,
|
||||||
|
};
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Serialize, Deserialize)]
|
#[derive(Debug, PartialEq, Serialize, Deserialize)]
|
||||||
#[serde(rename_all = "camelCase")]
|
#[serde(rename_all = "camelCase")]
|
||||||
@@ -101,6 +104,12 @@ pub struct JsonExecutionPayload<E: EthSpec> {
|
|||||||
#[superstruct(only(V3, V4))]
|
#[superstruct(only(V3, V4))]
|
||||||
#[serde(with = "serde_utils::u64_hex_be")]
|
#[serde(with = "serde_utils::u64_hex_be")]
|
||||||
pub excess_blob_gas: u64,
|
pub excess_blob_gas: u64,
|
||||||
|
#[superstruct(only(V4))]
|
||||||
|
// TODO(electra): Field name should be changed post devnet-0. See https://github.com/ethereum/execution-apis/pull/544
|
||||||
|
pub deposit_requests: VariableList<JsonDepositRequest, E::MaxDepositReceiptsPerPayload>,
|
||||||
|
#[superstruct(only(V4))]
|
||||||
|
pub withdrawal_requests:
|
||||||
|
VariableList<JsonWithdrawalRequest, E::MaxWithdrawalRequestsPerPayload>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<E: EthSpec> From<ExecutionPayloadBellatrix<E>> for JsonExecutionPayloadV1<E> {
|
impl<E: EthSpec> From<ExecutionPayloadBellatrix<E>> for JsonExecutionPayloadV1<E> {
|
||||||
@@ -203,6 +212,18 @@ impl<E: EthSpec> From<ExecutionPayloadElectra<E>> for JsonExecutionPayloadV4<E>
|
|||||||
.into(),
|
.into(),
|
||||||
blob_gas_used: payload.blob_gas_used,
|
blob_gas_used: payload.blob_gas_used,
|
||||||
excess_blob_gas: payload.excess_blob_gas,
|
excess_blob_gas: payload.excess_blob_gas,
|
||||||
|
deposit_requests: payload
|
||||||
|
.deposit_receipts
|
||||||
|
.into_iter()
|
||||||
|
.map(Into::into)
|
||||||
|
.collect::<Vec<_>>()
|
||||||
|
.into(),
|
||||||
|
withdrawal_requests: payload
|
||||||
|
.withdrawal_requests
|
||||||
|
.into_iter()
|
||||||
|
.map(Into::into)
|
||||||
|
.collect::<Vec<_>>()
|
||||||
|
.into(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -319,9 +340,18 @@ impl<E: EthSpec> From<JsonExecutionPayloadV4<E>> for ExecutionPayloadElectra<E>
|
|||||||
.into(),
|
.into(),
|
||||||
blob_gas_used: payload.blob_gas_used,
|
blob_gas_used: payload.blob_gas_used,
|
||||||
excess_blob_gas: payload.excess_blob_gas,
|
excess_blob_gas: payload.excess_blob_gas,
|
||||||
// TODO(electra)
|
deposit_receipts: payload
|
||||||
deposit_receipts: Default::default(),
|
.deposit_requests
|
||||||
withdrawal_requests: Default::default(),
|
.into_iter()
|
||||||
|
.map(Into::into)
|
||||||
|
.collect::<Vec<_>>()
|
||||||
|
.into(),
|
||||||
|
withdrawal_requests: payload
|
||||||
|
.withdrawal_requests
|
||||||
|
.into_iter()
|
||||||
|
.map(Into::into)
|
||||||
|
.collect::<Vec<_>>()
|
||||||
|
.into(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -694,6 +724,9 @@ pub struct JsonExecutionPayloadBodyV1<E: EthSpec> {
|
|||||||
#[serde(with = "ssz_types::serde_utils::list_of_hex_var_list")]
|
#[serde(with = "ssz_types::serde_utils::list_of_hex_var_list")]
|
||||||
pub transactions: Transactions<E>,
|
pub transactions: Transactions<E>,
|
||||||
pub withdrawals: Option<VariableList<JsonWithdrawal, E::MaxWithdrawalsPerPayload>>,
|
pub withdrawals: Option<VariableList<JsonWithdrawal, E::MaxWithdrawalsPerPayload>>,
|
||||||
|
pub deposit_receipts: Option<VariableList<JsonDepositRequest, E::MaxDepositReceiptsPerPayload>>,
|
||||||
|
pub withdrawal_requests:
|
||||||
|
Option<VariableList<JsonWithdrawalRequest, E::MaxWithdrawalRequestsPerPayload>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<E: EthSpec> From<JsonExecutionPayloadBodyV1<E>> for ExecutionPayloadBodyV1<E> {
|
impl<E: EthSpec> From<JsonExecutionPayloadBodyV1<E>> for ExecutionPayloadBodyV1<E> {
|
||||||
@@ -708,6 +741,22 @@ impl<E: EthSpec> From<JsonExecutionPayloadBodyV1<E>> for ExecutionPayloadBodyV1<
|
|||||||
.collect::<Vec<_>>(),
|
.collect::<Vec<_>>(),
|
||||||
)
|
)
|
||||||
}),
|
}),
|
||||||
|
deposit_receipts: value.deposit_receipts.map(|json_receipts| {
|
||||||
|
DepositReceipts::<E>::from(
|
||||||
|
json_receipts
|
||||||
|
.into_iter()
|
||||||
|
.map(Into::into)
|
||||||
|
.collect::<Vec<_>>(),
|
||||||
|
)
|
||||||
|
}),
|
||||||
|
withdrawal_requests: value.withdrawal_requests.map(|json_withdrawal_requests| {
|
||||||
|
WithdrawalRequests::<E>::from(
|
||||||
|
json_withdrawal_requests
|
||||||
|
.into_iter()
|
||||||
|
.map(Into::into)
|
||||||
|
.collect::<Vec<_>>(),
|
||||||
|
)
|
||||||
|
}),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -783,3 +832,68 @@ impl TryFrom<JsonClientVersionV1> for ClientVersionV1 {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
pub struct JsonDepositRequest {
|
||||||
|
pub pubkey: PublicKeyBytes,
|
||||||
|
pub withdrawal_credentials: Hash256,
|
||||||
|
#[serde(with = "serde_utils::quoted_u64")]
|
||||||
|
pub amount: u64,
|
||||||
|
pub signature: Signature,
|
||||||
|
#[serde(with = "serde_utils::quoted_u64")]
|
||||||
|
pub index: u64,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<DepositReceipt> for JsonDepositRequest {
|
||||||
|
fn from(deposit: DepositReceipt) -> Self {
|
||||||
|
Self {
|
||||||
|
pubkey: deposit.pubkey,
|
||||||
|
withdrawal_credentials: deposit.withdrawal_credentials,
|
||||||
|
amount: deposit.amount,
|
||||||
|
signature: deposit.signature,
|
||||||
|
index: deposit.index,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<JsonDepositRequest> for DepositReceipt {
|
||||||
|
fn from(json_deposit: JsonDepositRequest) -> Self {
|
||||||
|
Self {
|
||||||
|
pubkey: json_deposit.pubkey,
|
||||||
|
withdrawal_credentials: json_deposit.withdrawal_credentials,
|
||||||
|
amount: json_deposit.amount,
|
||||||
|
signature: json_deposit.signature,
|
||||||
|
index: json_deposit.index,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
pub struct JsonWithdrawalRequest {
|
||||||
|
pub source_address: Address,
|
||||||
|
pub validator_public_key: PublicKeyBytes,
|
||||||
|
#[serde(with = "serde_utils::quoted_u64")]
|
||||||
|
pub amount: u64,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<ExecutionLayerWithdrawalRequest> for JsonWithdrawalRequest {
|
||||||
|
fn from(withdrawal_request: ExecutionLayerWithdrawalRequest) -> Self {
|
||||||
|
Self {
|
||||||
|
source_address: withdrawal_request.source_address,
|
||||||
|
validator_public_key: withdrawal_request.validator_pubkey,
|
||||||
|
amount: withdrawal_request.amount,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<JsonWithdrawalRequest> for ExecutionLayerWithdrawalRequest {
|
||||||
|
fn from(json_withdrawal_request: JsonWithdrawalRequest) -> Self {
|
||||||
|
Self {
|
||||||
|
source_address: json_withdrawal_request.source_address,
|
||||||
|
validator_pubkey: json_withdrawal_request.validator_public_key,
|
||||||
|
amount: json_withdrawal_request.amount,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -1985,6 +1985,22 @@ impl<E: EthSpec> ExecutionLayer<E> {
|
|||||||
.collect(),
|
.collect(),
|
||||||
)
|
)
|
||||||
.map_err(ApiError::DeserializeWithdrawals)?;
|
.map_err(ApiError::DeserializeWithdrawals)?;
|
||||||
|
let deposit_receipts = VariableList::new(
|
||||||
|
electra_block
|
||||||
|
.deposit_receipts
|
||||||
|
.into_iter()
|
||||||
|
.map(Into::into)
|
||||||
|
.collect(),
|
||||||
|
)
|
||||||
|
.map_err(ApiError::DeserializeDepositReceipts)?;
|
||||||
|
let withdrawal_requests = VariableList::new(
|
||||||
|
electra_block
|
||||||
|
.withdrawal_requests
|
||||||
|
.into_iter()
|
||||||
|
.map(Into::into)
|
||||||
|
.collect(),
|
||||||
|
)
|
||||||
|
.map_err(ApiError::DeserializeWithdrawalRequests)?;
|
||||||
ExecutionPayload::Electra(ExecutionPayloadElectra {
|
ExecutionPayload::Electra(ExecutionPayloadElectra {
|
||||||
parent_hash: electra_block.parent_hash,
|
parent_hash: electra_block.parent_hash,
|
||||||
fee_recipient: electra_block.fee_recipient,
|
fee_recipient: electra_block.fee_recipient,
|
||||||
@@ -2003,11 +2019,8 @@ impl<E: EthSpec> ExecutionLayer<E> {
|
|||||||
withdrawals,
|
withdrawals,
|
||||||
blob_gas_used: electra_block.blob_gas_used,
|
blob_gas_used: electra_block.blob_gas_used,
|
||||||
excess_blob_gas: electra_block.excess_blob_gas,
|
excess_blob_gas: electra_block.excess_blob_gas,
|
||||||
// TODO(electra)
|
deposit_receipts,
|
||||||
// deposit_receipts: electra_block.deposit_receipts,
|
withdrawal_requests,
|
||||||
// withdrawal_requests: electra_block.withdrawal_requests,
|
|
||||||
deposit_receipts: <_>::default(),
|
|
||||||
withdrawal_requests: <_>::default(),
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -111,20 +111,14 @@ pub async fn handle_rpc<E: EthSpec>(
|
|||||||
.map(|jep| JsonExecutionPayload::V1(jep))
|
.map(|jep| JsonExecutionPayload::V1(jep))
|
||||||
})
|
})
|
||||||
.map_err(|s| (s, BAD_PARAMS_ERROR_CODE))?,
|
.map_err(|s| (s, BAD_PARAMS_ERROR_CODE))?,
|
||||||
ENGINE_NEW_PAYLOAD_V3 => get_param::<JsonExecutionPayloadV4<E>>(params, 0)
|
// From v3 onwards, we use the newPayload version only for the corresponding
|
||||||
.map(|jep| JsonExecutionPayload::V4(jep))
|
// ExecutionPayload version. So we return an error instead of falling back to
|
||||||
.or_else(|_| {
|
// older versions of newPayload
|
||||||
get_param::<JsonExecutionPayloadV3<E>>(params, 0)
|
ENGINE_NEW_PAYLOAD_V3 => get_param::<JsonExecutionPayloadV3<E>>(params, 0)
|
||||||
.map(|jep| JsonExecutionPayload::V3(jep))
|
.map(|jep| JsonExecutionPayload::V3(jep))
|
||||||
.or_else(|_| {
|
.map_err(|s| (s, BAD_PARAMS_ERROR_CODE))?,
|
||||||
get_param::<JsonExecutionPayloadV2<E>>(params, 0)
|
ENGINE_NEW_PAYLOAD_V4 => get_param::<JsonExecutionPayloadV4<E>>(params, 0)
|
||||||
.map(|jep| JsonExecutionPayload::V2(jep))
|
.map(|jep| JsonExecutionPayload::V4(jep))
|
||||||
.or_else(|_| {
|
|
||||||
get_param::<JsonExecutionPayloadV1<E>>(params, 0)
|
|
||||||
.map(|jep| JsonExecutionPayload::V1(jep))
|
|
||||||
})
|
|
||||||
})
|
|
||||||
})
|
|
||||||
.map_err(|s| (s, BAD_PARAMS_ERROR_CODE))?,
|
.map_err(|s| (s, BAD_PARAMS_ERROR_CODE))?,
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
};
|
};
|
||||||
@@ -190,7 +184,10 @@ pub async fn handle_rpc<E: EthSpec>(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
ForkName::Electra => {
|
ForkName::Electra => {
|
||||||
if method == ENGINE_NEW_PAYLOAD_V1 || method == ENGINE_NEW_PAYLOAD_V2 {
|
if method == ENGINE_NEW_PAYLOAD_V1
|
||||||
|
|| method == ENGINE_NEW_PAYLOAD_V2
|
||||||
|
|| method == ENGINE_NEW_PAYLOAD_V3
|
||||||
|
{
|
||||||
return Err((
|
return Err((
|
||||||
format!("{} called after Electra fork!", method),
|
format!("{} called after Electra fork!", method),
|
||||||
GENERIC_ERROR_CODE,
|
GENERIC_ERROR_CODE,
|
||||||
@@ -259,7 +256,10 @@ pub async fn handle_rpc<E: EthSpec>(
|
|||||||
|
|
||||||
Ok(serde_json::to_value(JsonPayloadStatusV1::from(response)).unwrap())
|
Ok(serde_json::to_value(JsonPayloadStatusV1::from(response)).unwrap())
|
||||||
}
|
}
|
||||||
ENGINE_GET_PAYLOAD_V1 | ENGINE_GET_PAYLOAD_V2 | ENGINE_GET_PAYLOAD_V3 => {
|
ENGINE_GET_PAYLOAD_V1
|
||||||
|
| ENGINE_GET_PAYLOAD_V2
|
||||||
|
| ENGINE_GET_PAYLOAD_V3
|
||||||
|
| ENGINE_GET_PAYLOAD_V4 => {
|
||||||
let request: JsonPayloadIdRequest =
|
let request: JsonPayloadIdRequest =
|
||||||
get_param(params, 0).map_err(|s| (s, BAD_PARAMS_ERROR_CODE))?;
|
get_param(params, 0).map_err(|s| (s, BAD_PARAMS_ERROR_CODE))?;
|
||||||
let id = request.into();
|
let id = request.into();
|
||||||
@@ -309,7 +309,9 @@ pub async fn handle_rpc<E: EthSpec>(
|
|||||||
.read()
|
.read()
|
||||||
.get_fork_at_timestamp(response.timestamp())
|
.get_fork_at_timestamp(response.timestamp())
|
||||||
== ForkName::Electra
|
== ForkName::Electra
|
||||||
&& method == ENGINE_GET_PAYLOAD_V1
|
&& (method == ENGINE_GET_PAYLOAD_V1
|
||||||
|
|| method == ENGINE_GET_PAYLOAD_V2
|
||||||
|
|| method == ENGINE_GET_PAYLOAD_V3)
|
||||||
{
|
{
|
||||||
return Err((
|
return Err((
|
||||||
format!("{} called after Electra fork!", method),
|
format!("{} called after Electra fork!", method),
|
||||||
@@ -338,6 +340,9 @@ pub async fn handle_rpc<E: EthSpec>(
|
|||||||
}
|
}
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
}),
|
}),
|
||||||
|
// From v3 onwards, we use the getPayload version only for the corresponding
|
||||||
|
// ExecutionPayload version. So we return an error if the ExecutionPayload version
|
||||||
|
// we get does not correspond to the getPayload version.
|
||||||
ENGINE_GET_PAYLOAD_V3 => Ok(match JsonExecutionPayload::from(response) {
|
ENGINE_GET_PAYLOAD_V3 => Ok(match JsonExecutionPayload::from(response) {
|
||||||
JsonExecutionPayload::V3(execution_payload) => {
|
JsonExecutionPayload::V3(execution_payload) => {
|
||||||
serde_json::to_value(JsonGetPayloadResponseV3 {
|
serde_json::to_value(JsonGetPayloadResponseV3 {
|
||||||
@@ -353,6 +358,9 @@ pub async fn handle_rpc<E: EthSpec>(
|
|||||||
})
|
})
|
||||||
.unwrap()
|
.unwrap()
|
||||||
}
|
}
|
||||||
|
_ => unreachable!(),
|
||||||
|
}),
|
||||||
|
ENGINE_GET_PAYLOAD_V4 => Ok(match JsonExecutionPayload::from(response) {
|
||||||
JsonExecutionPayload::V4(execution_payload) => {
|
JsonExecutionPayload::V4(execution_payload) => {
|
||||||
serde_json::to_value(JsonGetPayloadResponseV4 {
|
serde_json::to_value(JsonGetPayloadResponseV4 {
|
||||||
execution_payload,
|
execution_payload,
|
||||||
@@ -578,6 +586,14 @@ pub async fn handle_rpc<E: EthSpec>(
|
|||||||
.withdrawals()
|
.withdrawals()
|
||||||
.ok()
|
.ok()
|
||||||
.map(|withdrawals| VariableList::from(withdrawals.clone())),
|
.map(|withdrawals| VariableList::from(withdrawals.clone())),
|
||||||
|
deposit_receipts: block.deposit_receipts().ok().map(
|
||||||
|
|deposit_receipts| VariableList::from(deposit_receipts.clone()),
|
||||||
|
),
|
||||||
|
withdrawal_requests: block.withdrawal_requests().ok().map(
|
||||||
|
|withdrawal_requests| {
|
||||||
|
VariableList::from(withdrawal_requests.clone())
|
||||||
|
},
|
||||||
|
),
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
None => response.push(None),
|
None => response.push(None),
|
||||||
|
|||||||
@@ -43,6 +43,7 @@ pub const DEFAULT_ENGINE_CAPABILITIES: EngineCapabilities = EngineCapabilities {
|
|||||||
new_payload_v1: true,
|
new_payload_v1: true,
|
||||||
new_payload_v2: true,
|
new_payload_v2: true,
|
||||||
new_payload_v3: true,
|
new_payload_v3: true,
|
||||||
|
new_payload_v4: true,
|
||||||
forkchoice_updated_v1: true,
|
forkchoice_updated_v1: true,
|
||||||
forkchoice_updated_v2: true,
|
forkchoice_updated_v2: true,
|
||||||
forkchoice_updated_v3: true,
|
forkchoice_updated_v3: true,
|
||||||
@@ -51,6 +52,7 @@ pub const DEFAULT_ENGINE_CAPABILITIES: EngineCapabilities = EngineCapabilities {
|
|||||||
get_payload_v1: true,
|
get_payload_v1: true,
|
||||||
get_payload_v2: true,
|
get_payload_v2: true,
|
||||||
get_payload_v3: true,
|
get_payload_v3: true,
|
||||||
|
get_payload_v4: true,
|
||||||
get_client_version_v1: true,
|
get_client_version_v1: true,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -13,6 +13,10 @@ pub type Transactions<E> = VariableList<
|
|||||||
>;
|
>;
|
||||||
|
|
||||||
pub type Withdrawals<E> = VariableList<Withdrawal, <E as EthSpec>::MaxWithdrawalsPerPayload>;
|
pub type Withdrawals<E> = VariableList<Withdrawal, <E as EthSpec>::MaxWithdrawalsPerPayload>;
|
||||||
|
pub type DepositReceipts<E> =
|
||||||
|
VariableList<DepositReceipt, <E as EthSpec>::MaxDepositReceiptsPerPayload>;
|
||||||
|
pub type WithdrawalRequests<E> =
|
||||||
|
VariableList<ExecutionLayerWithdrawalRequest, <E as EthSpec>::MaxWithdrawalRequestsPerPayload>;
|
||||||
|
|
||||||
#[superstruct(
|
#[superstruct(
|
||||||
variants(Bellatrix, Capella, Deneb, Electra),
|
variants(Bellatrix, Capella, Deneb, Electra),
|
||||||
|
|||||||
@@ -117,7 +117,6 @@ impl<E: EthSpec> ExecutionPayloadHeader<E> {
|
|||||||
#[allow(clippy::arithmetic_side_effects)]
|
#[allow(clippy::arithmetic_side_effects)]
|
||||||
pub fn ssz_max_var_len_for_fork(fork_name: ForkName) -> usize {
|
pub fn ssz_max_var_len_for_fork(fork_name: ForkName) -> usize {
|
||||||
// Matching here in case variable fields are added in future forks.
|
// Matching here in case variable fields are added in future forks.
|
||||||
// TODO(electra): review electra changes
|
|
||||||
match fork_name {
|
match fork_name {
|
||||||
ForkName::Base
|
ForkName::Base
|
||||||
| ForkName::Altair
|
| ForkName::Altair
|
||||||
|
|||||||
Reference in New Issue
Block a user