Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Start prototyping superstruct features #5610

Open
wants to merge 11 commits into
base: unstable
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 8 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,7 @@ smallvec = "1.11.2"
snap = "1"
ssz_types = "0.6"
strum = { version = "0.24", features = ["derive"] }
superstruct = "0.7"
superstruct = { git = "https://github.com/sigp/superstruct", branch = "features" }
syn = "1"
sysinfo = "0.26"
tempfile = "3"
Expand Down
66 changes: 37 additions & 29 deletions beacon_node/beacon_chain/src/beacon_chain.rs
Original file line number Diff line number Diff line change
Expand Up @@ -733,6 +733,20 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
.map(|slot| slot.epoch(T::EthSpec::slots_per_epoch()))
}

/// Returns the latest fork for the current slot.
pub fn current_fork(&self) -> Result<ForkName, Error> {
Ok(self.spec.fork_name_at_slot::<T::EthSpec>(self.slot()?))
}

/// Checks if a feature is enabled on the current fork.
pub fn is_feature_enabled(&self, feature: FeatureName) -> bool {
if let Ok(current_fork) = self.current_fork() {
current_fork.is_feature_enabled(feature)
} else {
false
}
}

/// Iterates across all `(block_root, slot)` pairs from `start_slot`
/// to the head of the chain (inclusive).
///
Expand Down Expand Up @@ -2523,7 +2537,7 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
bls_to_execution_change: SignedBlsToExecutionChange,
) -> Result<ObservationOutcome<SignedBlsToExecutionChange, T::EthSpec>, Error> {
// Ignore BLS to execution changes on gossip prior to Capella.
if !self.current_slot_is_post_capella()? {
if !self.is_feature_enabled(FeatureName::Capella) {
return Err(Error::BlsToExecutionPriorToCapella);
}
self.verify_bls_to_execution_change_for_http_api(bls_to_execution_change)
Expand All @@ -2536,16 +2550,6 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
})
}

/// Check if the current slot is greater than or equal to the Capella fork epoch.
pub fn current_slot_is_post_capella(&self) -> Result<bool, Error> {
let current_fork = self.spec.fork_name_at_slot::<T::EthSpec>(self.slot()?);
if let ForkName::Base | ForkName::Altair | ForkName::Bellatrix = current_fork {
Ok(false)
} else {
Ok(true)
}
}

/// Import a BLS to execution change to the op pool.
///
/// Return `true` if the change was added to the pool.
Expand Down Expand Up @@ -5552,27 +5556,31 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
payload_attributes
} else {
let prepare_slot_fork = self.spec.fork_name_at_slot::<T::EthSpec>(prepare_slot);
let withdrawals = match prepare_slot_fork {
ForkName::Base | ForkName::Altair | ForkName::Bellatrix => None,
ForkName::Capella | ForkName::Deneb | ForkName::Electra => {
let chain = self.clone();
self.spawn_blocking_handle(
move || {
chain.get_expected_withdrawals(&forkchoice_update_params, prepare_slot)
},
"prepare_beacon_proposer_withdrawals",
)
.await?
.map(Some)?
}
let withdrawals = if prepare_slot_fork.is_feature_enabled(FeatureName::Capella) {
let chain = self.clone();
self.spawn_blocking_handle(
move || chain.get_expected_withdrawals(&forkchoice_update_params, prepare_slot),
"prepare_beacon_proposer_withdrawals",
)
.await?
.map(Some)?
} else {
None
};

let parent_beacon_block_root = match prepare_slot_fork {
ForkName::Base | ForkName::Altair | ForkName::Bellatrix | ForkName::Capella => None,
ForkName::Deneb | ForkName::Electra => {
let parent_beacon_block_root =
if prepare_slot_fork.is_feature_enabled(FeatureName::Deneb) {
Some(pre_payload_attributes.parent_beacon_block_root)
}
};
} else {
None
};

//let parent_beacon_block_root = match prepare_slot_fork {
// ForkName::Base | ForkName::Altair | ForkName::Bellatrix | ForkName::Capella => None,
// ForkName::Deneb | ForkName::Electra => {
// Some(pre_payload_attributes.parent_beacon_block_root)
// }
//};

let payload_attributes = PayloadAttributes::new(
self.slot_clock
Expand Down
2 changes: 2 additions & 0 deletions beacon_node/execution_layer/build.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
// Dummy build.rs file to enable OUT_DIR usage by superstruct
fn main() {}
4 changes: 2 additions & 2 deletions beacon_node/execution_layer/src/block_hash.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,8 @@ pub fn calculate_execution_block_hash<E: EthSpec>(
KECCAK_EMPTY_LIST_RLP.as_fixed_bytes().into(),
rlp_transactions_root,
rlp_withdrawals_root,
rlp_blob_gas_used,
rlp_excess_blob_gas,
rlp_blob_gas_used.copied(),
rlp_excess_blob_gas.copied(),
parent_beacon_block_root,
);

Expand Down
32 changes: 24 additions & 8 deletions beacon_node/execution_layer/src/engine_api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ pub use types::{
};
use types::{
ExecutionPayloadBellatrix, ExecutionPayloadCapella, ExecutionPayloadDeneb,
ExecutionPayloadElectra, KzgProofs,
ExecutionPayloadElectra, FeatureName, KzgProofs,
};
use types::{Graffiti, GRAFFITI_BYTES_LEN};

Expand Down Expand Up @@ -155,7 +155,15 @@ pub struct ExecutionBlock {

/// Representation of an execution block with enough detail to reconstruct a payload.
#[superstruct(
variants(Bellatrix, Capella, Deneb, Electra),
feature(Bellatrix),
variants_and_features_from = "FORK_ORDER",
feature_dependencies = "FEATURE_DEPENDENCIES",
variant_type(name = "ForkName", getter = "fork_name"),
feature_type(
name = "FeatureName",
list = "list_all_features",
check = "is_feature_enabled"
),
variant_attributes(
derive(Clone, Debug, PartialEq, Serialize, Deserialize,),
serde(bound = "E: EthSpec", rename_all = "camelCase"),
Expand Down Expand Up @@ -189,12 +197,12 @@ pub struct ExecutionBlockWithTransactions<E: EthSpec> {
#[serde(rename = "hash")]
pub block_hash: ExecutionBlockHash,
pub transactions: Vec<Transaction>,
#[superstruct(only(Capella, Deneb, Electra))]
#[superstruct(feature(Capella))]
pub withdrawals: Vec<JsonWithdrawal>,
#[superstruct(only(Deneb, Electra))]
#[superstruct(feature(Deneb))]
#[serde(with = "serde_utils::u64_hex_be")]
pub blob_gas_used: u64,
#[superstruct(only(Deneb, Electra))]
#[superstruct(feature(Deneb))]
#[serde(with = "serde_utils::u64_hex_be")]
pub excess_blob_gas: u64,
}
Expand Down Expand Up @@ -425,7 +433,15 @@ pub struct ProposeBlindedBlockResponse {
}

#[superstruct(
variants(Bellatrix, Capella, Deneb, Electra),
feature(Bellatrix),
variants_and_features_from = "FORK_ORDER",
feature_dependencies = "FEATURE_DEPENDENCIES",
variant_type(name = "ForkName", getter = "fork_name"),
feature_type(
name = "FeatureName",
list = "list_all_features",
check = "is_feature_enabled"
),
variant_attributes(derive(Clone, Debug, PartialEq),),
map_into(ExecutionPayload),
map_ref_into(ExecutionPayloadRef),
Expand All @@ -446,9 +462,9 @@ pub struct GetPayloadResponse<E: EthSpec> {
#[superstruct(only(Electra), partial_getter(rename = "execution_payload_electra"))]
pub execution_payload: ExecutionPayloadElectra<E>,
pub block_value: Uint256,
#[superstruct(only(Deneb, Electra))]
#[superstruct(feature(Deneb))]
pub blobs_bundle: BlobsBundle<E>,
#[superstruct(only(Deneb, Electra), partial_getter(copy))]
#[superstruct(feature(Deneb), partial_getter(copy))]
pub should_override_builder: bool,
}

Expand Down
32 changes: 15 additions & 17 deletions beacon_node/execution_layer/src/engine_api/http.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1217,27 +1217,25 @@ impl HttpJsonRpc {
payload_id: PayloadId,
) -> Result<GetPayloadResponse<E>, Error> {
let engine_capabilities = self.get_engine_capabilities(None).await?;
match fork_name {
ForkName::Bellatrix | ForkName::Capella => {
if engine_capabilities.get_payload_v2 {
self.get_payload_v2(fork_name, payload_id).await
} else if engine_capabilities.new_payload_v1 {
self.get_payload_v1(payload_id).await
} else {
Err(Error::RequiredMethodUnsupported("engine_getPayload"))
}
if fork_name.is_feature_enabled(FeatureName::Deneb) {
if engine_capabilities.get_payload_v3 {
self.get_payload_v3(fork_name, payload_id).await
} else {
Err(Error::RequiredMethodUnsupported("engine_getPayloadV3"))
}
ForkName::Deneb | ForkName::Electra => {
if engine_capabilities.get_payload_v3 {
self.get_payload_v3(fork_name, payload_id).await
} else {
Err(Error::RequiredMethodUnsupported("engine_getPayloadV3"))
}
} else if fork_name.is_feature_enabled(FeatureName::Bellatrix) {
if engine_capabilities.get_payload_v2 {
self.get_payload_v2(fork_name, payload_id).await
} else if engine_capabilities.new_payload_v1 {
self.get_payload_v1(payload_id).await
} else {
Err(Error::RequiredMethodUnsupported("engine_getPayload"))
}
ForkName::Base | ForkName::Altair => Err(Error::UnsupportedForkVariant(format!(
} else {
Err(Error::UnsupportedForkVariant(format!(
"called get_payload with {}",
fork_name
))),
)))
}
}

Expand Down
16 changes: 12 additions & 4 deletions beacon_node/execution_layer/src/engine_api/new_payload_request.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,23 @@ use state_processing::per_block_processing::deneb::kzg_commitment_to_versioned_h
use superstruct::superstruct;
use types::{
BeaconBlockRef, BeaconStateError, EthSpec, ExecutionBlockHash, ExecutionPayload,
ExecutionPayloadRef, Hash256, VersionedHash,
ExecutionPayloadRef, FeatureName, ForkName, Hash256, VersionedHash,
};
use types::{
ExecutionPayloadBellatrix, ExecutionPayloadCapella, ExecutionPayloadDeneb,
ExecutionPayloadElectra,
};

#[superstruct(
variants(Bellatrix, Capella, Deneb, Electra),
feature(Bellatrix),
variants_and_features_from = "FORK_ORDER",
feature_dependencies = "FEATURE_DEPENDENCIES",
variant_type(name = "ForkName", getter = "fork_name"),
feature_type(
name = "FeatureName",
list = "list_all_features",
check = "is_feature_enabled"
),
variant_attributes(derive(Clone, Debug, PartialEq),),
map_into(ExecutionPayload),
map_ref_into(ExecutionPayloadRef),
Expand All @@ -39,9 +47,9 @@ pub struct NewPayloadRequest<'block, E: EthSpec> {
pub execution_payload: &'block ExecutionPayloadDeneb<E>,
#[superstruct(only(Electra), partial_getter(rename = "execution_payload_electra"))]
pub execution_payload: &'block ExecutionPayloadElectra<E>,
#[superstruct(only(Deneb, Electra))]
#[superstruct(feature(Deneb))]
pub versioned_hashes: Vec<VersionedHash>,
#[superstruct(only(Deneb, Electra))]
#[superstruct(feature(Deneb))]
pub parent_beacon_block_root: Hash256,
}

Expand Down
15 changes: 8 additions & 7 deletions beacon_node/execution_layer/src/test_utils/mock_builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,9 @@ use types::builder_bid::{
};
use types::{
Address, BeaconState, ChainSpec, EthSpec, ExecPayload, ExecutionPayload,
ExecutionPayloadHeaderRefMut, ForkName, ForkVersionedResponse, Hash256, PublicKeyBytes,
Signature, SignedBlindedBeaconBlock, SignedRoot, SignedValidatorRegistrationData, Slot,
Uint256,
ExecutionPayloadHeaderRefMut, FeatureName, ForkName, ForkVersionedResponse, Hash256,
PublicKeyBytes, Signature, SignedBlindedBeaconBlock, SignedRoot,
SignedValidatorRegistrationData, Slot, Uint256,
};
use types::{ExecutionBlockHash, SecretKey};
use warp::{Filter, Rejection};
Expand Down Expand Up @@ -479,16 +479,17 @@ pub fn serve<E: EthSpec>(
let prev_randao = head_state
.get_randao_mix(head_state.current_epoch())
.map_err(|_| reject("couldn't get prev randao"))?;
let expected_withdrawals = match fork {
ForkName::Base | ForkName::Altair | ForkName::Bellatrix => None,
ForkName::Capella | ForkName::Deneb | ForkName::Electra => Some(
let expected_withdrawals = if fork.is_feature_enabled(FeatureName::Capella) {
Some(
builder
.beacon_client
.get_expected_withdrawals(&StateId::Head)
.await
.unwrap()
.data,
),
)
} else {
None
};

let payload_attributes = match fork {
Expand Down
12 changes: 6 additions & 6 deletions beacon_node/http_api/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -79,11 +79,11 @@ use tokio_stream::{
};
use types::{
fork_versioned_response::EmptyMetadata, Attestation, AttestationData, AttestationShufflingId,
AttesterSlashing, BeaconStateError, CommitteeCache, ConfigAndPreset, Epoch, EthSpec, ForkName,
ForkVersionedResponse, Hash256, ProposerPreparationData, ProposerSlashing, RelativeEpoch,
SignedAggregateAndProof, SignedBlindedBeaconBlock, SignedBlsToExecutionChange,
SignedContributionAndProof, SignedValidatorRegistrationData, SignedVoluntaryExit, Slot,
SyncCommitteeMessage, SyncContributionData,
AttesterSlashing, BeaconStateError, CommitteeCache, ConfigAndPreset, Epoch, EthSpec,
FeatureName, ForkName, ForkVersionedResponse, Hash256, ProposerPreparationData,
ProposerSlashing, RelativeEpoch, SignedAggregateAndProof, SignedBlindedBeaconBlock,
SignedBlsToExecutionChange, SignedContributionAndProof, SignedValidatorRegistrationData,
SignedVoluntaryExit, Slot, SyncCommitteeMessage, SyncContributionData,
};
use validator::pubkey_to_validator_index;
use version::{
Expand Down Expand Up @@ -2046,7 +2046,7 @@ pub fn serve<T: BeaconChainTypes>(
.to_execution_address;

// New to P2P *and* op pool, gossip immediately if post-Capella.
let received_pre_capella = if chain.current_slot_is_post_capella().unwrap_or(false) {
let received_pre_capella = if chain.is_feature_enabled(FeatureName::Capella) {
ReceivedPreCapella::No
} else {
ReceivedPreCapella::Yes
Expand Down
2 changes: 2 additions & 0 deletions beacon_node/store/build.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
// Dummy build.rs file to enable OUT_DIR usage by superstruct
fn main() {}
Loading
Loading