Start replacing boilerplate

This commit is contained in:
Mac L
2024-05-01 18:12:38 +10:00
parent 4e3839ec98
commit b68d08c847
9 changed files with 155 additions and 84 deletions

View File

@@ -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).
///
@@ -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)
@@ -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.
@@ -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

View File

@@ -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
))),
)))
}
}

View File

@@ -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};
@@ -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 {

View File

@@ -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::{
@@ -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

View File

@@ -337,9 +337,10 @@ impl ChainSpec {
}
pub fn inactivity_penalty_quotient_for_fork(&self, fork_name: ForkName) -> u64 {
if fork_name >= ForkName::Bellatrix {
// TODO(superstruct_features) Is this a better pattern?
if fork_name.is_feature_enabled(FeatureName::Bellatrix) {
self.inactivity_penalty_quotient_bellatrix
} else if fork_name >= ForkName::Altair {
} else if fork_name.is_feature_enabled(FeatureName::Altair) {
self.inactivity_penalty_quotient_altair
} else {
self.inactivity_penalty_quotient

View File

@@ -3,7 +3,7 @@
//
// For now, older Forks have a single "super-feature" which contains all features associated with
// that Fork. It may be worth splitting these up at a later time.
#[derive(PartialEq)]
#[derive(PartialEq, Clone, Copy, Debug)]
pub enum FeatureName {
// Altair.
Altair,

View File

@@ -1,5 +1,5 @@
use crate::fork_order::FORK_ORDER;
use crate::{ChainSpec, Epoch};
use crate::{ChainSpec, Epoch, FeatureName};
use serde::{Deserialize, Serialize};
use ssz_derive::{Decode, Encode};
use std::cmp::{Ord, Ordering};
@@ -49,6 +49,20 @@ impl ForkName {
FORK_ORDER[FORK_ORDER.len() - 1].0
}
pub fn list_all_enabled_features(self) -> Vec<FeatureName> {
let mut res = vec![];
for (fork, features) in FORK_ORDER {
if *fork <= self {
res.extend(features.iter());
}
}
res
}
pub fn is_feature_enabled(self, feature: FeatureName) -> bool {
self.list_all_enabled_features().contains(&feature)
}
/// Set the activation slots in the given `ChainSpec` so that the fork named by `self`
/// is the only fork in effect from genesis.
pub fn make_genesis_spec(&self, mut spec: ChainSpec) -> ChainSpec {
@@ -296,4 +310,51 @@ mod test {
assert!(prev_fork < fork);
}
}
#[test]
fn check_fork_name_enabled_features() {
let base = ForkName::Base;
let altair = ForkName::Altair;
let bellatrix = ForkName::Bellatrix;
let capella = ForkName::Capella;
let deneb = ForkName::Deneb;
let electra = ForkName::Electra;
assert_eq!(base.list_all_enabled_features(), vec![]);
assert_eq!(
altair.list_all_enabled_features(),
vec![FeatureName::Altair]
);
assert_eq!(
bellatrix.list_all_enabled_features(),
vec![FeatureName::Altair, FeatureName::Bellatrix]
);
assert_eq!(
capella.list_all_enabled_features(),
vec![
FeatureName::Altair,
FeatureName::Bellatrix,
FeatureName::Capella
]
);
assert_eq!(
deneb.list_all_enabled_features(),
vec![
FeatureName::Altair,
FeatureName::Bellatrix,
FeatureName::Capella,
FeatureName::Deneb
]
);
assert_eq!(
electra.list_all_enabled_features(),
vec![
FeatureName::Altair,
FeatureName::Bellatrix,
FeatureName::Capella,
FeatureName::Deneb,
FeatureName::Electra
]
);
}
}

View File

@@ -1,6 +1,6 @@
use crate::{
test_utils::TestRandom, ChainSpec, Domain, Epoch, ForkName, Hash256, SecretKey, SignedRoot,
SignedVoluntaryExit,
test_utils::TestRandom, ChainSpec, Domain, Epoch, FeatureName, ForkName, Hash256, SecretKey,
SignedRoot, SignedVoluntaryExit,
};
use serde::{Deserialize, Serialize};
@@ -41,12 +41,11 @@ impl VoluntaryExit {
spec: &ChainSpec,
) -> SignedVoluntaryExit {
let fork_name = spec.fork_name_at_epoch(self.epoch);
let fork_version = match fork_name {
ForkName::Base | ForkName::Altair | ForkName::Bellatrix | ForkName::Capella => {
spec.fork_version_for_name(fork_name)
}
// EIP-7044
ForkName::Deneb | ForkName::Electra => spec.fork_version_for_name(ForkName::Capella),
// EIP-7044
let fork_version = if fork_name.is_feature_enabled(FeatureName::Deneb) {
spec.fork_version_for_name(ForkName::Capella)
} else {
spec.fork_version_for_name(fork_name)
};
let domain =
spec.compute_domain(Domain::VoluntaryExit, fork_version, genesis_validators_root);

View File

@@ -19,7 +19,7 @@ use task_executor::TaskExecutor;
use types::{
attestation::Error as AttestationError, graffiti::GraffitiString, AbstractExecPayload, Address,
AggregateAndProof, Attestation, BeaconBlock, BlindedPayload, ChainSpec, ContributionAndProof,
Domain, Epoch, EthSpec, Fork, ForkName, Graffiti, Hash256, PublicKeyBytes, SelectionProof,
Domain, Epoch, EthSpec, FeatureName, Fork, Graffiti, Hash256, PublicKeyBytes, SelectionProof,
Signature, SignedAggregateAndProof, SignedBeaconBlock, SignedContributionAndProof, SignedRoot,
SignedValidatorRegistrationData, SignedVoluntaryExit, Slot, SyncAggregatorSelectionData,
SyncCommitteeContribution, SyncCommitteeMessage, SyncSelectionProof, SyncSubnetId,
@@ -359,17 +359,13 @@ impl<T: SlotClock + 'static, E: EthSpec> ValidatorStore<T, E> {
fn signing_context(&self, domain: Domain, signing_epoch: Epoch) -> SigningContext {
if domain == Domain::VoluntaryExit {
match self.spec.fork_name_at_epoch(signing_epoch) {
ForkName::Base | ForkName::Altair | ForkName::Bellatrix | ForkName::Capella => {
SigningContext {
domain,
epoch: signing_epoch,
fork: self.fork(signing_epoch),
genesis_validators_root: self.genesis_validators_root,
}
}
// EIP-7044
ForkName::Deneb | ForkName::Electra => SigningContext {
// EIP-7044
if self
.spec
.fork_name_at_epoch(signing_epoch)
.is_feature_enabled(FeatureName::Deneb)
{
SigningContext {
domain,
epoch: signing_epoch,
fork: Fork {
@@ -378,7 +374,14 @@ impl<T: SlotClock + 'static, E: EthSpec> ValidatorStore<T, E> {
epoch: signing_epoch,
},
genesis_validators_root: self.genesis_validators_root,
},
}
} else {
SigningContext {
domain,
epoch: signing_epoch,
fork: self.fork(signing_epoch),
genesis_validators_root: self.genesis_validators_root,
}
}
} else {
SigningContext {