merge with capella

This commit is contained in:
realbigsean 2022-12-23 10:21:18 -05:00
commit f45d117e73
No known key found for this signature in database
GPG Key ID: B372B64D866BF8CC
45 changed files with 164 additions and 231 deletions

View File

@ -66,7 +66,7 @@ jobs:
DOCKER_CLI_EXPERIMENTAL: enabled DOCKER_CLI_EXPERIMENTAL: enabled
VERSION: ${{ needs.extract-version.outputs.VERSION }} VERSION: ${{ needs.extract-version.outputs.VERSION }}
VERSION_SUFFIX: ${{ needs.extract-version.outputs.VERSION_SUFFIX }} VERSION_SUFFIX: ${{ needs.extract-version.outputs.VERSION_SUFFIX }}
CROSS_FEATURES: withdrawals,withdrawals-processing CROSS_FEATURES: withdrawals-processing
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v3
- name: Update Rust - name: Update Rust

View File

@ -21,7 +21,7 @@ CROSS_FEATURES ?= gnosis,slasher-lmdb,slasher-mdbx
CROSS_PROFILE ?= release CROSS_PROFILE ?= release
# List of features to use when running EF tests. # List of features to use when running EF tests.
EF_TEST_FEATURES ?= withdrawals,withdrawals-processing EF_TEST_FEATURES ?= beacon_chain/withdrawals-processing
# Cargo profile for regular builds. # Cargo profile for regular builds.
PROFILE ?= release PROFILE ?= release

View File

@ -13,7 +13,6 @@ node_test_rig = { path = "../testing/node_test_rig" }
[features] [features]
write_ssz_files = ["beacon_chain/write_ssz_files"] # Writes debugging .ssz files to /tmp during block processing. write_ssz_files = ["beacon_chain/write_ssz_files"] # Writes debugging .ssz files to /tmp during block processing.
withdrawals = ["beacon_chain/withdrawals", "types/withdrawals", "store/withdrawals", "execution_layer/withdrawals"]
withdrawals-processing = [ withdrawals-processing = [
"beacon_chain/withdrawals-processing", "beacon_chain/withdrawals-processing",
"store/withdrawals-processing", "store/withdrawals-processing",

View File

@ -10,7 +10,6 @@ default = ["participation_metrics"]
write_ssz_files = [] # Writes debugging .ssz files to /tmp during block processing. write_ssz_files = [] # Writes debugging .ssz files to /tmp during block processing.
participation_metrics = [] # Exposes validator participation metrics to Prometheus. participation_metrics = [] # Exposes validator participation metrics to Prometheus.
fork_from_env = [] # Initialise the harness chain spec from the FORK_NAME env variable fork_from_env = [] # Initialise the harness chain spec from the FORK_NAME env variable
withdrawals = ["state_processing/withdrawals", "types/withdrawals", "store/withdrawals", "execution_layer/withdrawals"]
withdrawals-processing = [ withdrawals-processing = [
"state_processing/withdrawals-processing", "state_processing/withdrawals-processing",
"store/withdrawals-processing", "store/withdrawals-processing",

View File

@ -80,14 +80,12 @@ use slasher::Slasher;
use slog::{crit, debug, error, info, trace, warn, Logger}; use slog::{crit, debug, error, info, trace, warn, Logger};
use slot_clock::SlotClock; use slot_clock::SlotClock;
use ssz::Encode; use ssz::Encode;
#[cfg(feature = "withdrawals")]
use state_processing::per_block_processing::get_expected_withdrawals;
use state_processing::{ use state_processing::{
common::get_attesting_indices_from_state, common::get_attesting_indices_from_state,
per_block_processing, per_block_processing,
per_block_processing::{ per_block_processing::{
errors::AttestationValidationError, verify_attestation_for_block_inclusion, errors::AttestationValidationError, get_expected_withdrawals,
VerifySignatures, verify_attestation_for_block_inclusion, VerifySignatures,
}, },
per_slot_processing, per_slot_processing,
state_advance::{complete_state_advance, partial_state_advance}, state_advance::{complete_state_advance, partial_state_advance},
@ -290,7 +288,6 @@ struct PartialBeaconBlock<E: EthSpec, Payload: AbstractExecPayload<E>> {
voluntary_exits: Vec<SignedVoluntaryExit>, voluntary_exits: Vec<SignedVoluntaryExit>,
sync_aggregate: Option<SyncAggregate<E>>, sync_aggregate: Option<SyncAggregate<E>>,
prepare_payload_handle: Option<PreparePayloadHandle<E, Payload>>, prepare_payload_handle: Option<PreparePayloadHandle<E, Payload>>,
#[cfg(feature = "withdrawals")]
bls_to_execution_changes: Vec<SignedBlsToExecutionChange>, bls_to_execution_changes: Vec<SignedBlsToExecutionChange>,
} }
@ -4208,7 +4205,6 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
let eth1_data = eth1_chain.eth1_data_for_block_production(&state, &self.spec)?; let eth1_data = eth1_chain.eth1_data_for_block_production(&state, &self.spec)?;
let deposits = eth1_chain.deposits_for_block_inclusion(&state, &eth1_data, &self.spec)?; let deposits = eth1_chain.deposits_for_block_inclusion(&state, &eth1_data, &self.spec)?;
#[cfg(feature = "withdrawals")]
let bls_to_execution_changes = self let bls_to_execution_changes = self
.op_pool .op_pool
.get_bls_to_execution_changes(&state, &self.spec); .get_bls_to_execution_changes(&state, &self.spec);
@ -4371,7 +4367,6 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
voluntary_exits, voluntary_exits,
sync_aggregate, sync_aggregate,
prepare_payload_handle, prepare_payload_handle,
#[cfg(feature = "withdrawals")]
bls_to_execution_changes, bls_to_execution_changes,
}) })
} }
@ -4400,7 +4395,6 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
// this function. We can assume that the handle has already been consumed in order to // this function. We can assume that the handle has already been consumed in order to
// produce said `execution_payload`. // produce said `execution_payload`.
prepare_payload_handle: _, prepare_payload_handle: _,
#[cfg(feature = "withdrawals")]
bls_to_execution_changes, bls_to_execution_changes,
} = partial_beacon_block; } = partial_beacon_block;
@ -4501,7 +4495,6 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
execution_payload: payload execution_payload: payload
.try_into() .try_into()
.map_err(|_| BlockProductionError::InvalidPayloadFork)?, .map_err(|_| BlockProductionError::InvalidPayloadFork)?,
#[cfg(feature = "withdrawals")]
bls_to_execution_changes: bls_to_execution_changes.into(), bls_to_execution_changes: bls_to_execution_changes.into(),
}, },
}), }),
@ -4533,7 +4526,6 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
execution_payload: payload execution_payload: payload
.try_into() .try_into()
.map_err(|_| BlockProductionError::InvalidPayloadFork)?, .map_err(|_| BlockProductionError::InvalidPayloadFork)?,
#[cfg(feature = "withdrawals")]
bls_to_execution_changes: bls_to_execution_changes.into(), bls_to_execution_changes: bls_to_execution_changes.into(),
blob_kzg_commitments: kzg_commitments blob_kzg_commitments: kzg_commitments
.ok_or(BlockProductionError::InvalidPayloadFork)?, .ok_or(BlockProductionError::InvalidPayloadFork)?,
@ -4833,7 +4825,6 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
return Ok(()); return Ok(());
} }
#[cfg(feature = "withdrawals")]
let withdrawals = match self.spec.fork_name_at_slot::<T::EthSpec>(prepare_slot) { let withdrawals = match self.spec.fork_name_at_slot::<T::EthSpec>(prepare_slot) {
ForkName::Base | ForkName::Altair | ForkName::Merge => None, ForkName::Base | ForkName::Altair | ForkName::Merge => None,
ForkName::Capella | ForkName::Eip4844 => { ForkName::Capella | ForkName::Eip4844 => {
@ -4868,10 +4859,7 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
execution_layer execution_layer
.get_suggested_fee_recipient(proposer as u64) .get_suggested_fee_recipient(proposer as u64)
.await, .await,
#[cfg(feature = "withdrawals")]
withdrawals, withdrawals,
#[cfg(not(feature = "withdrawals"))]
None,
); );
debug!( debug!(

View File

@ -17,11 +17,9 @@ use fork_choice::{InvalidationOperation, PayloadVerificationStatus};
use proto_array::{Block as ProtoBlock, ExecutionStatus}; use proto_array::{Block as ProtoBlock, ExecutionStatus};
use slog::debug; use slog::debug;
use slot_clock::SlotClock; use slot_clock::SlotClock;
#[cfg(feature = "withdrawals")]
use state_processing::per_block_processing::get_expected_withdrawals;
use state_processing::per_block_processing::{ use state_processing::per_block_processing::{
compute_timestamp_at_slot, is_execution_enabled, is_merge_transition_complete, compute_timestamp_at_slot, get_expected_withdrawals, is_execution_enabled,
partially_verify_execution_payload, is_merge_transition_complete, partially_verify_execution_payload,
}; };
use std::sync::Arc; use std::sync::Arc;
use tokio::task::JoinHandle; use tokio::task::JoinHandle;
@ -382,7 +380,6 @@ pub fn get_execution_payload<
let random = *state.get_randao_mix(current_epoch)?; let random = *state.get_randao_mix(current_epoch)?;
let latest_execution_payload_header_block_hash = let latest_execution_payload_header_block_hash =
state.latest_execution_payload_header()?.block_hash(); state.latest_execution_payload_header()?.block_hash();
#[cfg(feature = "withdrawals")]
let withdrawals = match state { let withdrawals = match state {
&BeaconState::Capella(_) | &BeaconState::Eip4844(_) => { &BeaconState::Capella(_) | &BeaconState::Eip4844(_) => {
Some(get_expected_withdrawals(state, spec)?.into()) Some(get_expected_withdrawals(state, spec)?.into())
@ -407,7 +404,6 @@ pub fn get_execution_payload<
proposer_index, proposer_index,
latest_execution_payload_header_block_hash, latest_execution_payload_header_block_hash,
builder_params, builder_params,
#[cfg(feature = "withdrawals")]
withdrawals, withdrawals,
) )
.await .await
@ -442,7 +438,7 @@ pub async fn prepare_execution_payload<T, Payload>(
proposer_index: u64, proposer_index: u64,
latest_execution_payload_header_block_hash: ExecutionBlockHash, latest_execution_payload_header_block_hash: ExecutionBlockHash,
builder_params: BuilderParams, builder_params: BuilderParams,
#[cfg(feature = "withdrawals")] withdrawals: Option<Vec<Withdrawal>>, withdrawals: Option<Vec<Withdrawal>>,
) -> Result<BlockProposalContents<T::EthSpec, Payload>, BlockProductionError> ) -> Result<BlockProposalContents<T::EthSpec, Payload>, BlockProductionError>
where where
T: BeaconChainTypes, T: BeaconChainTypes,
@ -504,15 +500,8 @@ where
let suggested_fee_recipient = execution_layer let suggested_fee_recipient = execution_layer
.get_suggested_fee_recipient(proposer_index) .get_suggested_fee_recipient(proposer_index)
.await; .await;
let payload_attributes = PayloadAttributes::new( let payload_attributes =
timestamp, PayloadAttributes::new(timestamp, random, suggested_fee_recipient, withdrawals);
random,
suggested_fee_recipient,
#[cfg(feature = "withdrawals")]
withdrawals,
#[cfg(not(feature = "withdrawals"))]
None,
);
// Note: the suggested_fee_recipient is stored in the `execution_layer`, it will add this parameter. // Note: the suggested_fee_recipient is stored in the `execution_layer`, it will add this parameter.
// //

View File

@ -5,7 +5,6 @@ edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[features] [features]
withdrawals = ["state_processing/withdrawals", "types/withdrawals", "eth2/withdrawals"]
withdrawals-processing = ["state_processing/withdrawals-processing", "eth2/withdrawals-processing"] withdrawals-processing = ["state_processing/withdrawals-processing", "eth2/withdrawals-processing"]
[dependencies] [dependencies]

View File

@ -165,7 +165,6 @@ pub struct ExecutionBlockWithTransactions<T: EthSpec> {
#[serde(rename = "hash")] #[serde(rename = "hash")]
pub block_hash: ExecutionBlockHash, pub block_hash: ExecutionBlockHash,
pub transactions: Vec<Transaction>, pub transactions: Vec<Transaction>,
#[cfg(feature = "withdrawals")]
#[superstruct(only(Capella, Eip4844))] #[superstruct(only(Capella, Eip4844))]
pub withdrawals: Vec<JsonWithdrawal>, pub withdrawals: Vec<JsonWithdrawal>,
} }
@ -215,7 +214,6 @@ impl<T: EthSpec> TryFrom<ExecutionPayload<T>> for ExecutionBlockWithTransactions
.iter() .iter()
.map(|tx| Transaction::decode(&Rlp::new(tx))) .map(|tx| Transaction::decode(&Rlp::new(tx)))
.collect::<Result<Vec<_>, _>>()?, .collect::<Result<Vec<_>, _>>()?,
#[cfg(feature = "withdrawals")]
withdrawals: Vec::from(block.withdrawals) withdrawals: Vec::from(block.withdrawals)
.into_iter() .into_iter()
.map(|withdrawal| withdrawal.into()) .map(|withdrawal| withdrawal.into())
@ -243,7 +241,6 @@ impl<T: EthSpec> TryFrom<ExecutionPayload<T>> for ExecutionBlockWithTransactions
.iter() .iter()
.map(|tx| Transaction::decode(&Rlp::new(tx))) .map(|tx| Transaction::decode(&Rlp::new(tx)))
.collect::<Result<Vec<_>, _>>()?, .collect::<Result<Vec<_>, _>>()?,
#[cfg(feature = "withdrawals")]
withdrawals: Vec::from(block.withdrawals) withdrawals: Vec::from(block.withdrawals)
.into_iter() .into_iter()
.map(|withdrawal| withdrawal.into()) .map(|withdrawal| withdrawal.into())

View File

@ -779,7 +779,7 @@ impl HttpJsonRpc {
) -> Result<ExecutionPayload<T>, Error> { ) -> Result<ExecutionPayload<T>, Error> {
let params = json!([JsonPayloadIdRequest::from(payload_id)]); let params = json!([JsonPayloadIdRequest::from(payload_id)]);
let payload_v2: JsonExecutionPayloadV2<T> = self let response: JsonGetPayloadResponse<T> = self
.rpc_request( .rpc_request(
ENGINE_GET_PAYLOAD_V2, ENGINE_GET_PAYLOAD_V2,
params, params,
@ -787,7 +787,7 @@ impl HttpJsonRpc {
) )
.await?; .await?;
JsonExecutionPayload::V2(payload_v2).try_into_execution_payload(fork_name) JsonExecutionPayload::V2(response.execution_payload).try_into_execution_payload(fork_name)
} }
pub async fn get_payload_v3<T: EthSpec>( pub async fn get_payload_v3<T: EthSpec>(
@ -889,11 +889,11 @@ impl HttpJsonRpc {
pub async fn supported_apis_v1(&self) -> Result<SupportedApis, Error> { pub async fn supported_apis_v1(&self) -> Result<SupportedApis, Error> {
Ok(SupportedApis { Ok(SupportedApis {
new_payload_v1: true, new_payload_v1: true,
new_payload_v2: cfg!(all(feature = "withdrawals", not(test))), new_payload_v2: cfg!(not(test)),
forkchoice_updated_v1: true, forkchoice_updated_v1: true,
forkchoice_updated_v2: cfg!(all(feature = "withdrawals", not(test))), forkchoice_updated_v2: cfg!(not(test)),
get_payload_v1: true, get_payload_v1: true,
get_payload_v2: cfg!(all(feature = "withdrawals", not(test))), get_payload_v2: cfg!(not(test)),
exchange_transition_configuration_v1: true, exchange_transition_configuration_v1: true,
}) })
} }

View File

@ -164,7 +164,6 @@ impl<T: EthSpec> JsonExecutionPayload<T> {
base_fee_per_gas: v2.base_fee_per_gas, base_fee_per_gas: v2.base_fee_per_gas,
block_hash: v2.block_hash, block_hash: v2.block_hash,
transactions: v2.transactions, transactions: v2.transactions,
#[cfg(feature = "withdrawals")]
withdrawals: v2 withdrawals: v2
.withdrawals .withdrawals
.map(|v| { .map(|v| {
@ -192,7 +191,6 @@ impl<T: EthSpec> JsonExecutionPayload<T> {
excess_data_gas: v2.excess_data_gas.ok_or_else(|| Error::BadConversion("Null `excess_data_gas` field converting JsonExecutionPayloadV2 -> ExecutionPayloadEip4844".to_string()))?, excess_data_gas: v2.excess_data_gas.ok_or_else(|| Error::BadConversion("Null `excess_data_gas` field converting JsonExecutionPayloadV2 -> ExecutionPayloadEip4844".to_string()))?,
block_hash: v2.block_hash, block_hash: v2.block_hash,
transactions: v2.transactions, transactions: v2.transactions,
#[cfg(feature = "withdrawals")]
withdrawals: v2 withdrawals: v2
.withdrawals .withdrawals
.map(|v| { .map(|v| {
@ -280,7 +278,6 @@ impl<T: EthSpec> TryFrom<ExecutionPayload<T>> for JsonExecutionPayloadV2<T> {
excess_data_gas: None, excess_data_gas: None,
block_hash: capella.block_hash, block_hash: capella.block_hash,
transactions: capella.transactions, transactions: capella.transactions,
#[cfg(feature = "withdrawals")]
withdrawals: Some( withdrawals: Some(
Vec::from(capella.withdrawals) Vec::from(capella.withdrawals)
.into_iter() .into_iter()
@ -288,8 +285,6 @@ impl<T: EthSpec> TryFrom<ExecutionPayload<T>> for JsonExecutionPayloadV2<T> {
.collect::<Vec<_>>() .collect::<Vec<_>>()
.into(), .into(),
), ),
#[cfg(not(feature = "withdrawals"))]
withdrawals: None,
}), }),
ExecutionPayload::Eip4844(eip4844) => Ok(JsonExecutionPayloadV2 { ExecutionPayload::Eip4844(eip4844) => Ok(JsonExecutionPayloadV2 {
parent_hash: eip4844.parent_hash, parent_hash: eip4844.parent_hash,
@ -307,7 +302,6 @@ impl<T: EthSpec> TryFrom<ExecutionPayload<T>> for JsonExecutionPayloadV2<T> {
excess_data_gas: Some(eip4844.excess_data_gas), excess_data_gas: Some(eip4844.excess_data_gas),
block_hash: eip4844.block_hash, block_hash: eip4844.block_hash,
transactions: eip4844.transactions, transactions: eip4844.transactions,
#[cfg(feature = "withdrawals")]
withdrawals: Some( withdrawals: Some(
Vec::from(eip4844.withdrawals) Vec::from(eip4844.withdrawals)
.into_iter() .into_iter()
@ -315,13 +309,20 @@ impl<T: EthSpec> TryFrom<ExecutionPayload<T>> for JsonExecutionPayloadV2<T> {
.collect::<Vec<_>>() .collect::<Vec<_>>()
.into(), .into(),
), ),
#[cfg(not(feature = "withdrawals"))]
withdrawals: None,
}), }),
} }
} }
} }
#[derive(Debug, PartialEq, Serialize, Deserialize)]
#[serde(bound = "T: EthSpec", rename_all = "camelCase")]
pub struct JsonGetPayloadResponse<T: EthSpec> {
pub execution_payload: JsonExecutionPayloadV2<T>,
// uncomment this when geth fixes its serialization
//#[serde(with = "eth2_serde_utils::u256_hex_be")]
//pub block_value: Uint256,
}
#[derive(Debug, PartialEq, Clone, Serialize, Deserialize)] #[derive(Debug, PartialEq, Clone, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
pub struct JsonWithdrawal { pub struct JsonWithdrawal {

View File

@ -1642,7 +1642,6 @@ impl<T: EthSpec> ExecutionLayer<T> {
}) })
} }
ExecutionBlockWithTransactions::Capella(capella_block) => { ExecutionBlockWithTransactions::Capella(capella_block) => {
#[cfg(feature = "withdrawals")]
let withdrawals = VariableList::new( let withdrawals = VariableList::new(
capella_block capella_block
.withdrawals .withdrawals
@ -1651,7 +1650,6 @@ impl<T: EthSpec> ExecutionLayer<T> {
.collect(), .collect(),
) )
.map_err(ApiError::DeserializeWithdrawals)?; .map_err(ApiError::DeserializeWithdrawals)?;
ExecutionPayload::Capella(ExecutionPayloadCapella { ExecutionPayload::Capella(ExecutionPayloadCapella {
parent_hash: capella_block.parent_hash, parent_hash: capella_block.parent_hash,
fee_recipient: capella_block.fee_recipient, fee_recipient: capella_block.fee_recipient,
@ -1667,12 +1665,10 @@ impl<T: EthSpec> ExecutionLayer<T> {
base_fee_per_gas: capella_block.base_fee_per_gas, base_fee_per_gas: capella_block.base_fee_per_gas,
block_hash: capella_block.block_hash, block_hash: capella_block.block_hash,
transactions, transactions,
#[cfg(feature = "withdrawals")]
withdrawals, withdrawals,
}) })
} }
ExecutionBlockWithTransactions::Eip4844(eip4844_block) => { ExecutionBlockWithTransactions::Eip4844(eip4844_block) => {
#[cfg(feature = "withdrawals")]
let withdrawals = VariableList::new( let withdrawals = VariableList::new(
eip4844_block eip4844_block
.withdrawals .withdrawals
@ -1681,7 +1677,6 @@ impl<T: EthSpec> ExecutionLayer<T> {
.collect(), .collect(),
) )
.map_err(ApiError::DeserializeWithdrawals)?; .map_err(ApiError::DeserializeWithdrawals)?;
ExecutionPayload::Eip4844(ExecutionPayloadEip4844 { ExecutionPayload::Eip4844(ExecutionPayloadEip4844 {
parent_hash: eip4844_block.parent_hash, parent_hash: eip4844_block.parent_hash,
fee_recipient: eip4844_block.fee_recipient, fee_recipient: eip4844_block.fee_recipient,
@ -1698,7 +1693,6 @@ impl<T: EthSpec> ExecutionLayer<T> {
excess_data_gas: eip4844_block.excess_data_gas, excess_data_gas: eip4844_block.excess_data_gas,
block_hash: eip4844_block.block_hash, block_hash: eip4844_block.block_hash,
transactions, transactions,
#[cfg(feature = "withdrawals")]
withdrawals, withdrawals,
}) })
} }

View File

@ -103,10 +103,7 @@ impl<T: EthSpec> MockExecutionLayer<T> {
prev_randao, prev_randao,
Address::repeat_byte(42), Address::repeat_byte(42),
// FIXME: think about how to handle different forks / withdrawals here.. // FIXME: think about how to handle different forks / withdrawals here..
#[cfg(feature = "withdrawals")]
Some(vec![]), Some(vec![]),
#[cfg(not(feature = "withdrawals"))]
None,
); );
// Insert a proposer to ensure the fork choice updated command works. // Insert a proposer to ensure the fork choice updated command works.

View File

@ -521,6 +521,15 @@ impl<T: BeaconChainTypes> Worker<T> {
"block_root" => ?root, "block_root" => ?root,
"error" => ?e "error" => ?e
); );
// send the stream terminator
self.send_error_response(
peer_id,
RPCResponseErrorCode::ServerError,
"Failed fetching blocks".into(),
request_id,
);
send_response = false;
break; break;
} }
} }

View File

@ -28,5 +28,4 @@ directory = { path = "../../common/directory" }
strum = { version = "0.24.0", features = ["derive"] } strum = { version = "0.24.0", features = ["derive"] }
[features] [features]
withdrawals = ["state_processing/withdrawals", "types/withdrawals"]
withdrawals-processing = ["state_processing/withdrawals-processing"] withdrawals-processing = ["state_processing/withdrawals-processing"]

View File

@ -105,10 +105,8 @@ where
pub latest_execution_payload_header: ExecutionPayloadHeaderEip4844<T>, pub latest_execution_payload_header: ExecutionPayloadHeaderEip4844<T>,
// Withdrawals // Withdrawals
#[cfg(feature = "withdrawals")]
#[superstruct(only(Capella, Eip4844))] #[superstruct(only(Capella, Eip4844))]
pub next_withdrawal_index: u64, pub next_withdrawal_index: u64,
#[cfg(feature = "withdrawals")]
#[superstruct(only(Capella, Eip4844))] #[superstruct(only(Capella, Eip4844))]
pub next_withdrawal_validator_index: u64, pub next_withdrawal_validator_index: u64,
} }
@ -199,7 +197,6 @@ impl<T: EthSpec> PartialBeaconState<T> {
latest_execution_payload_header latest_execution_payload_header
] ]
), ),
#[cfg(feature = "withdrawals")]
BeaconState::Capella(s) => impl_from_state_forgetful!( BeaconState::Capella(s) => impl_from_state_forgetful!(
s, s,
outer, outer,
@ -216,22 +213,6 @@ impl<T: EthSpec> PartialBeaconState<T> {
next_withdrawal_validator_index next_withdrawal_validator_index
] ]
), ),
#[cfg(not(feature = "withdrawals"))]
BeaconState::Capella(s) => impl_from_state_forgetful!(
s,
outer,
Capella,
PartialBeaconStateCapella,
[
previous_epoch_participation,
current_epoch_participation,
current_sync_committee,
next_sync_committee,
inactivity_scores,
latest_execution_payload_header
]
),
#[cfg(feature = "withdrawals")]
BeaconState::Eip4844(s) => impl_from_state_forgetful!( BeaconState::Eip4844(s) => impl_from_state_forgetful!(
s, s,
outer, outer,
@ -248,21 +229,6 @@ impl<T: EthSpec> PartialBeaconState<T> {
next_withdrawal_validator_index next_withdrawal_validator_index
] ]
), ),
#[cfg(not(feature = "withdrawals"))]
BeaconState::Eip4844(s) => impl_from_state_forgetful!(
s,
outer,
Eip4844,
PartialBeaconStateEip4844,
[
previous_epoch_participation,
current_epoch_participation,
current_sync_committee,
next_sync_committee,
inactivity_scores,
latest_execution_payload_header
]
),
} }
} }
@ -450,7 +416,6 @@ impl<E: EthSpec> TryInto<BeaconState<E>> for PartialBeaconState<E> {
latest_execution_payload_header latest_execution_payload_header
] ]
), ),
#[cfg(feature = "withdrawals")]
PartialBeaconState::Capella(inner) => impl_try_into_beacon_state!( PartialBeaconState::Capella(inner) => impl_try_into_beacon_state!(
inner, inner,
Capella, Capella,
@ -466,21 +431,6 @@ impl<E: EthSpec> TryInto<BeaconState<E>> for PartialBeaconState<E> {
next_withdrawal_validator_index next_withdrawal_validator_index
] ]
), ),
#[cfg(not(feature = "withdrawals"))]
PartialBeaconState::Capella(inner) => impl_try_into_beacon_state!(
inner,
Capella,
BeaconStateCapella,
[
previous_epoch_participation,
current_epoch_participation,
current_sync_committee,
next_sync_committee,
inactivity_scores,
latest_execution_payload_header
]
),
#[cfg(feature = "withdrawals")]
PartialBeaconState::Eip4844(inner) => impl_try_into_beacon_state!( PartialBeaconState::Eip4844(inner) => impl_try_into_beacon_state!(
inner, inner,
Eip4844, Eip4844,
@ -496,20 +446,6 @@ impl<E: EthSpec> TryInto<BeaconState<E>> for PartialBeaconState<E> {
next_withdrawal_validator_index next_withdrawal_validator_index
] ]
), ),
#[cfg(not(feature = "withdrawals"))]
PartialBeaconState::Eip4844(inner) => impl_try_into_beacon_state!(
inner,
Eip4844,
BeaconStateEip4844,
[
previous_epoch_participation,
current_epoch_participation,
current_sync_committee,
next_sync_committee,
inactivity_scores,
latest_execution_payload_header
]
),
}; };
Ok(state) Ok(state)
} }

View File

@ -35,5 +35,4 @@ procinfo = { version = "0.4.2", optional = true }
[features] [features]
default = ["lighthouse"] default = ["lighthouse"]
lighthouse = ["proto_array", "psutil", "procinfo", "store", "slashing_protection"] lighthouse = ["proto_array", "psutil", "procinfo", "store", "slashing_protection"]
withdrawals = ["store/withdrawals", "types/withdrawals"]
withdrawals-processing = ["store/withdrawals-processing"] withdrawals-processing = ["store/withdrawals-processing"]

View File

@ -1,5 +1,5 @@
# Gnosis Chain Team # Gnosis Chain Team
- enr:-IS4QGmLwm7gFd0L0CEisllrb1op3v-wAGSc7_pwSMGgN3bOS9Fz7m1dWbwuuPHKqeETz9MbhjVuoWk0ohkyRv98kVoBgmlkgnY0gmlwhGjtlgaJc2VjcDI1NmsxoQLMdh0It9fJbuiLydZ9fpF6MRzgNle0vODaDiMqhbC7WIN1ZHCCIyg - enr:-Ly4QMU1y81COwm1VZgxGF4_eZ21ub9-GHF6dXZ29aEJ0oZpcV2Rysw-viaEKfpcpu9ZarILJLxFZjcKOjE0Sybs3MQBh2F0dG5ldHOIAAAAAAAAAACEZXRoMpCCS-QxAgAAZP__________gmlkgnY0gmlwhANLnx-Jc2VjcDI1NmsxoQKoaYT8I-wf2I_f_ii6EgoSSXj5T3bhiDyW-7ZLsY3T64hzeW5jbmV0cwCDdGNwgiMog3VkcIIjKA
- enr:-IS4QFUVG3dvLPCUEI7ycRvFm0Ieg_ITa5tALmJ9LI7dJ6ieT3J4fF9xLRjOoB4ApV-Rjp7HeLKzyTWG1xRdbFBNZPQBgmlkgnY0gmlwhErP5weJc2VjcDI1NmsxoQOBbaJBvx0-w_pyZUhQl9A510Ho2T0grE0K8JevzES99IN1ZHCCIyg - enr:-Ly4QBf76jLiCA_pDXoZjhyRbuwzFOscFY-MIKkPnmHPQbvaKhIDZutfe38G9ibzgQP0RKrTo3vcWOy4hf_8wOZ-U5MBh2F0dG5ldHOIAAAAAAAAAACEZXRoMpCCS-QxAgAAZP__________gmlkgnY0gmlwhBLGgjaJc2VjcDI1NmsxoQLGeo0Q4lDvxIjHjnkAqEuETTaFIjsNrEcSpdDhcHXWFYhzeW5jbmV0cwCDdGNwgiMog3VkcIIjKA
- enr:-Ku4QOQk8V-Hu2gxFzRXmLYIO4AvWDZhoMFwTf3n3DYm_mbsWv0ZitoqiN6JZUUj6Li6e1Jk1w2zFSVHKPMUP1g5tsgBh2F0dG5ldHOIAAAAAAAAAACEZXRoMpD5Jd3FAAAAZP__________gmlkgnY0gmlwhC1PTpmJc2VjcDI1NmsxoQL1Ynt5PoA0UOcHa1Rfn98rmnRlLzNuWTePPP4m4qHVroN1ZHCCKvg - enr:-Ly4QLjZUWdqUO_RwyDqCAccIK5-MbLRD6A2c7oBuVbBgBnWDkEf0UKJVAaJqi2pO101WVQQLYSnYgz1Q3pRhYdrlFoBh2F0dG5ldHOIAAAAAAAAAACEZXRoMpCCS-QxAgAAZP__________gmlkgnY0gmlwhANA8sSJc2VjcDI1NmsxoQK4TC_EK1jSs0VVPUpOjIo1rhJmff2SLBPFOWSXMwdLVYhzeW5jbmV0cwCDdGNwgiMog3VkcIIjKA
- enr:-Ku4QFaTwgoms-EiiRIfHUH3FXprWUFgjHg4UuWvilqoUQtDbmTszVIxUEOwQUmA2qkiP-T9wXjc_rVUuh9cU7WgwbgBh2F0dG5ldHOIAAAAAAAAAACEZXRoMpD5Jd3FAAAAZP__________gmlkgnY0gmlwhC0hBmCJc2VjcDI1NmsxoQOpsg1XCrXmCwZKcSTcycLwldoKUMHPUpMEVGeg_EEhuYN1ZHCCKvg - enr:-Ly4QKwX2rTFtKWKQHSGQFhquxsxL1jewO8JB1MG-jgHqAZVFWxnb3yMoQqnYSV1bk25-_jiLuhIulxar3RBWXEDm6EBh2F0dG5ldHOIAAAAAAAAAACEZXRoMpCCS-QxAgAAZP__________gmlkgnY0gmlwhAN-qZeJc2VjcDI1NmsxoQI7EPGMpecl0QofLp4Wy_lYNCCChUFEH6kY7k-oBGkPFIhzeW5jbmV0cwCDdGNwgiMog3VkcIIjKA

View File

@ -43,5 +43,4 @@ arbitrary-fuzz = [
"eth2_ssz_types/arbitrary", "eth2_ssz_types/arbitrary",
"tree_hash/arbitrary", "tree_hash/arbitrary",
] ]
withdrawals = ["types/withdrawals"]
withdrawals-processing = [] withdrawals-processing = []

View File

@ -19,6 +19,7 @@ pub use process_operations::process_operations;
pub use verify_attestation::{ pub use verify_attestation::{
verify_attestation_for_block_inclusion, verify_attestation_for_state, verify_attestation_for_block_inclusion, verify_attestation_for_state,
}; };
#[cfg(feature = "withdrawals-processing")]
pub use verify_bls_to_execution_change::verify_bls_to_execution_change; pub use verify_bls_to_execution_change::verify_bls_to_execution_change;
pub use verify_deposit::{ pub use verify_deposit::{
get_existing_validator_index, verify_deposit_merkle_proof, verify_deposit_signature, get_existing_validator_index, verify_deposit_merkle_proof, verify_deposit_signature,
@ -35,6 +36,7 @@ pub mod signature_sets;
pub mod tests; pub mod tests;
mod verify_attestation; mod verify_attestation;
mod verify_attester_slashing; mod verify_attester_slashing;
#[cfg(feature = "withdrawals-processing")]
mod verify_bls_to_execution_change; mod verify_bls_to_execution_change;
mod verify_deposit; mod verify_deposit;
mod verify_exit; mod verify_exit;
@ -162,7 +164,7 @@ pub fn per_block_processing<T: EthSpec, Payload: AbstractExecPayload<T>>(
// previous block. // previous block.
if is_execution_enabled(state, block.body()) { if is_execution_enabled(state, block.body()) {
let payload = block.body().execution_payload()?; let payload = block.body().execution_payload()?;
#[cfg(all(feature = "withdrawals", feature = "withdrawals-processing"))] #[cfg(feature = "withdrawals-processing")]
process_withdrawals::<T, Payload>(state, payload, spec)?; process_withdrawals::<T, Payload>(state, payload, spec)?;
process_execution_payload::<T, Payload>(state, payload, spec)?; process_execution_payload::<T, Payload>(state, payload, spec)?;
} }
@ -466,8 +468,9 @@ pub fn compute_timestamp_at_slot<T: EthSpec>(
.and_then(|since_genesis| state.genesis_time().safe_add(since_genesis)) .and_then(|since_genesis| state.genesis_time().safe_add(since_genesis))
} }
/// FIXME: add link to this function once the spec is stable /// Compute the next batch of withdrawals which should be included in a block.
#[cfg(feature = "withdrawals")] ///
/// https://github.com/ethereum/consensus-specs/blob/dev/specs/capella/beacon-chain.md#new-get_expected_withdrawals
pub fn get_expected_withdrawals<T: EthSpec>( pub fn get_expected_withdrawals<T: EthSpec>(
state: &BeaconState<T>, state: &BeaconState<T>,
spec: &ChainSpec, spec: &ChainSpec,
@ -481,7 +484,11 @@ pub fn get_expected_withdrawals<T: EthSpec>(
return Ok(withdrawals.into()); return Ok(withdrawals.into());
} }
for _ in 0..state.validators().len() { let bound = std::cmp::min(
state.validators().len() as u64,
spec.max_validators_per_withdrawals_sweep,
);
for _ in 0..bound {
let validator = state.get_validator(validator_index as usize)?; let validator = state.get_validator(validator_index as usize)?;
let balance = *state.balances().get(validator_index as usize).ok_or( let balance = *state.balances().get(validator_index as usize).ok_or(
BeaconStateError::BalancesOutOfBounds(validator_index as usize), BeaconStateError::BalancesOutOfBounds(validator_index as usize),
@ -518,8 +525,8 @@ pub fn get_expected_withdrawals<T: EthSpec>(
Ok(withdrawals.into()) Ok(withdrawals.into())
} }
/// FIXME: add link to this function once the spec is stable /// Apply withdrawals to the state.
#[cfg(feature = "withdrawals")] #[cfg(feature = "withdrawals-processing")]
pub fn process_withdrawals<'payload, T: EthSpec, Payload: AbstractExecPayload<T>>( pub fn process_withdrawals<'payload, T: EthSpec, Payload: AbstractExecPayload<T>>(
state: &mut BeaconState<T>, state: &mut BeaconState<T>,
payload: Payload::Ref<'payload>, payload: Payload::Ref<'payload>,
@ -547,11 +554,26 @@ pub fn process_withdrawals<'payload, T: EthSpec, Payload: AbstractExecPayload<T>
)?; )?;
} }
// Update the next withdrawal index if this block contained withdrawals
if let Some(latest_withdrawal) = expected_withdrawals.last() { if let Some(latest_withdrawal) = expected_withdrawals.last() {
*state.next_withdrawal_index_mut()? = latest_withdrawal.index.safe_add(1)?; *state.next_withdrawal_index_mut()? = latest_withdrawal.index.safe_add(1)?;
let next_validator_index = latest_withdrawal
.validator_index // Update the next validator index to start the next withdrawal sweep
.safe_add(1)? if expected_withdrawals.len() == T::max_withdrawals_per_payload() {
// Next sweep starts after the latest withdrawal's validator index
let next_validator_index = latest_withdrawal
.validator_index
.safe_add(1)?
.safe_rem(state.validators().len() as u64)?;
*state.next_withdrawal_validator_index_mut()? = next_validator_index;
}
}
// Advance sweep by the max length of the sweep if there was not a full set of withdrawals
if expected_withdrawals.len() != T::max_withdrawals_per_payload() {
let next_validator_index = state
.next_withdrawal_validator_index()?
.safe_add(spec.max_validators_per_withdrawals_sweep)?
.safe_rem(state.validators().len() as u64)?; .safe_rem(state.validators().len() as u64)?;
*state.next_withdrawal_validator_index_mut()? = next_validator_index; *state.next_withdrawal_validator_index_mut()? = next_validator_index;
} }

View File

@ -170,7 +170,6 @@ where
// Deposits are not included because they can legally have invalid signatures. // Deposits are not included because they can legally have invalid signatures.
self.include_exits(block)?; self.include_exits(block)?;
self.include_sync_aggregate(block)?; self.include_sync_aggregate(block)?;
#[cfg(feature = "withdrawals")]
self.include_bls_to_execution_changes(block)?; self.include_bls_to_execution_changes(block)?;
Ok(()) Ok(())
@ -345,7 +344,6 @@ where
} }
/// Include the signature of the block's BLS to execution changes for verification. /// Include the signature of the block's BLS to execution changes for verification.
#[cfg(feature = "withdrawals")]
pub fn include_bls_to_execution_changes<Payload: AbstractExecPayload<T>>( pub fn include_bls_to_execution_changes<Payload: AbstractExecPayload<T>>(
&mut self, &mut self,
block: &'a SignedBeaconBlock<T, Payload>, block: &'a SignedBeaconBlock<T, Payload>,

View File

@ -34,7 +34,7 @@ pub fn process_operations<'a, T: EthSpec, Payload: AbstractExecPayload<T>>(
process_deposits(state, block_body.deposits(), spec)?; process_deposits(state, block_body.deposits(), spec)?;
process_exits(state, block_body.voluntary_exits(), verify_signatures, spec)?; process_exits(state, block_body.voluntary_exits(), verify_signatures, spec)?;
#[cfg(all(feature = "withdrawals", feature = "withdrawals-processing"))] #[cfg(feature = "withdrawals-processing")]
if let Ok(bls_to_execution_changes) = block_body.bls_to_execution_changes() { if let Ok(bls_to_execution_changes) = block_body.bls_to_execution_changes() {
process_bls_to_execution_changes(state, bls_to_execution_changes, verify_signatures, spec)?; process_bls_to_execution_changes(state, bls_to_execution_changes, verify_signatures, spec)?;
} }
@ -295,6 +295,7 @@ pub fn process_exits<T: EthSpec>(
/// ///
/// Returns `Ok(())` if the validation and state updates completed successfully. Otherwise returns /// Returns `Ok(())` if the validation and state updates completed successfully. Otherwise returns
/// an `Err` describing the invalid object or cause of failure. /// an `Err` describing the invalid object or cause of failure.
#[cfg(feature = "withdrawals-processing")]
pub fn process_bls_to_execution_changes<T: EthSpec>( pub fn process_bls_to_execution_changes<T: EthSpec>(
state: &mut BeaconState<T>, state: &mut BeaconState<T>,
bls_to_execution_changes: &[SignedBlsToExecutionChange], bls_to_execution_changes: &[SignedBlsToExecutionChange],

View File

@ -56,9 +56,7 @@ pub fn upgrade_to_capella<E: EthSpec>(
// Execution // Execution
latest_execution_payload_header: pre.latest_execution_payload_header.upgrade_to_capella(), latest_execution_payload_header: pre.latest_execution_payload_header.upgrade_to_capella(),
// Withdrawals // Withdrawals
#[cfg(feature = "withdrawals")]
next_withdrawal_index: 0, next_withdrawal_index: 0,
#[cfg(feature = "withdrawals")]
next_withdrawal_validator_index: 0, next_withdrawal_validator_index: 0,
// Caches // Caches
total_active_balance: pre.total_active_balance, total_active_balance: pre.total_active_balance,

View File

@ -9,13 +9,7 @@ pub fn upgrade_to_eip4844<E: EthSpec>(
let epoch = pre_state.current_epoch(); let epoch = pre_state.current_epoch();
let pre = pre_state.as_capella_mut()?; let pre = pre_state.as_capella_mut()?;
// FIXME(sean) This is a hack to let us participate in testnets where capella doesn't exist. let previous_fork_version = pre.fork.current_version;
// if we are disabling withdrawals, assume we should fork off of bellatrix.
let previous_fork_version = if cfg!(feature = "withdrawals") {
pre.fork.current_version
} else {
spec.bellatrix_fork_version
};
// Where possible, use something like `mem::take` to move fields from behind the &mut // Where possible, use something like `mem::take` to move fields from behind the &mut
// reference. For other fields that don't have a good default value, use `clone`. // reference. For other fields that don't have a good default value, use `clone`.
@ -64,9 +58,7 @@ pub fn upgrade_to_eip4844<E: EthSpec>(
// Execution // Execution
latest_execution_payload_header: pre.latest_execution_payload_header.upgrade_to_eip4844(), latest_execution_payload_header: pre.latest_execution_payload_header.upgrade_to_eip4844(),
// Withdrawals // Withdrawals
#[cfg(feature = "withdrawals")]
next_withdrawal_index: pre.next_withdrawal_index, next_withdrawal_index: pre.next_withdrawal_index,
#[cfg(feature = "withdrawals")]
next_withdrawal_validator_index: pre.next_withdrawal_validator_index, next_withdrawal_validator_index: pre.next_withdrawal_validator_index,
// Caches // Caches
total_active_balance: pre.total_active_balance, total_active_balance: pre.total_active_balance,

View File

@ -74,4 +74,3 @@ arbitrary-fuzz = [
"swap_or_not_shuffle/arbitrary", "swap_or_not_shuffle/arbitrary",
"tree_hash/arbitrary", "tree_hash/arbitrary",
] ]
withdrawals = []

View File

@ -0,0 +1,17 @@
# Mainnet preset - Capella
# Misc
# Max operations per block
# ---------------------------------------------------------------
# 2**4 (= 16)
MAX_BLS_TO_EXECUTION_CHANGES: 16
# Execution
# ---------------------------------------------------------------
# 2**4 (= 16) withdrawals
MAX_WITHDRAWALS_PER_PAYLOAD: 16
# Withdrawals processing
# ---------------------------------------------------------------
# 2**14 (= 16384) validators
MAX_VALIDATORS_PER_WITHDRAWALS_SWEEP: 16384

View File

@ -9,4 +9,9 @@ MAX_BLS_TO_EXECUTION_CHANGES: 16
# Execution # Execution
# --------------------------------------------------------------- # ---------------------------------------------------------------
# 2**4 (= 16) withdrawals # 2**4 (= 16) withdrawals
MAX_WITHDRAWALS_PER_PAYLOAD: 16 MAX_WITHDRAWALS_PER_PAYLOAD: 16
# Withdrawals processing
# ---------------------------------------------------------------
# 2**14 (= 16384) validators
MAX_VALIDATORS_PER_WITHDRAWALS_SWEEP: 16384

View File

@ -9,4 +9,9 @@ MAX_BLS_TO_EXECUTION_CHANGES: 16
# Execution # Execution
# --------------------------------------------------------------- # ---------------------------------------------------------------
# [customized] 2**2 (= 4) # [customized] 2**2 (= 4)
MAX_WITHDRAWALS_PER_PAYLOAD: 4 MAX_WITHDRAWALS_PER_PAYLOAD: 4
# Withdrawals processing
# ---------------------------------------------------------------
# [customized] 2**4 (= 16) validators
MAX_VALIDATORS_PER_WITHDRAWALS_SWEEP: 16

View File

@ -502,7 +502,6 @@ impl<T: EthSpec, Payload: AbstractExecPayload<T>> EmptyBlock for BeaconBlockCape
voluntary_exits: VariableList::empty(), voluntary_exits: VariableList::empty(),
sync_aggregate: SyncAggregate::empty(), sync_aggregate: SyncAggregate::empty(),
execution_payload: Payload::Capella::default(), execution_payload: Payload::Capella::default(),
#[cfg(feature = "withdrawals")]
bls_to_execution_changes: VariableList::empty(), bls_to_execution_changes: VariableList::empty(),
}, },
} }
@ -532,7 +531,6 @@ impl<T: EthSpec, Payload: AbstractExecPayload<T>> EmptyBlock for BeaconBlockEip4
voluntary_exits: VariableList::empty(), voluntary_exits: VariableList::empty(),
sync_aggregate: SyncAggregate::empty(), sync_aggregate: SyncAggregate::empty(),
execution_payload: Payload::Eip4844::default(), execution_payload: Payload::Eip4844::default(),
#[cfg(feature = "withdrawals")]
bls_to_execution_changes: VariableList::empty(), bls_to_execution_changes: VariableList::empty(),
blob_kzg_commitments: VariableList::empty(), blob_kzg_commitments: VariableList::empty(),
}, },

View File

@ -61,7 +61,6 @@ pub struct BeaconBlockBody<T: EthSpec, Payload: AbstractExecPayload<T> = FullPay
#[superstruct(only(Eip4844), partial_getter(rename = "execution_payload_eip4844"))] #[superstruct(only(Eip4844), partial_getter(rename = "execution_payload_eip4844"))]
#[serde(flatten)] #[serde(flatten)]
pub execution_payload: Payload::Eip4844, pub execution_payload: Payload::Eip4844,
#[cfg(feature = "withdrawals")]
#[superstruct(only(Capella, Eip4844))] #[superstruct(only(Capella, Eip4844))]
pub bls_to_execution_changes: pub bls_to_execution_changes:
VariableList<SignedBlsToExecutionChange, T::MaxBlsToExecutionChanges>, VariableList<SignedBlsToExecutionChange, T::MaxBlsToExecutionChanges>,
@ -300,7 +299,6 @@ impl<E: EthSpec> From<BeaconBlockBodyCapella<E, FullPayload<E>>>
voluntary_exits, voluntary_exits,
sync_aggregate, sync_aggregate,
execution_payload: FullPayloadCapella { execution_payload }, execution_payload: FullPayloadCapella { execution_payload },
#[cfg(feature = "withdrawals")]
bls_to_execution_changes, bls_to_execution_changes,
} = body; } = body;
@ -318,7 +316,6 @@ impl<E: EthSpec> From<BeaconBlockBodyCapella<E, FullPayload<E>>>
execution_payload: BlindedPayloadCapella { execution_payload: BlindedPayloadCapella {
execution_payload_header: From::from(execution_payload.clone()), execution_payload_header: From::from(execution_payload.clone()),
}, },
#[cfg(feature = "withdrawals")]
bls_to_execution_changes, bls_to_execution_changes,
}, },
Some(execution_payload), Some(execution_payload),
@ -344,7 +341,6 @@ impl<E: EthSpec> From<BeaconBlockBodyEip4844<E, FullPayload<E>>>
voluntary_exits, voluntary_exits,
sync_aggregate, sync_aggregate,
execution_payload: FullPayloadEip4844 { execution_payload }, execution_payload: FullPayloadEip4844 { execution_payload },
#[cfg(feature = "withdrawals")]
bls_to_execution_changes, bls_to_execution_changes,
blob_kzg_commitments, blob_kzg_commitments,
} = body; } = body;
@ -363,7 +359,6 @@ impl<E: EthSpec> From<BeaconBlockBodyEip4844<E, FullPayload<E>>>
execution_payload: BlindedPayloadEip4844 { execution_payload: BlindedPayloadEip4844 {
execution_payload_header: From::from(execution_payload.clone()), execution_payload_header: From::from(execution_payload.clone()),
}, },
#[cfg(feature = "withdrawals")]
bls_to_execution_changes, bls_to_execution_changes,
blob_kzg_commitments, blob_kzg_commitments,
}, },
@ -432,7 +427,6 @@ impl<E: EthSpec> BeaconBlockBodyCapella<E, FullPayload<E>> {
voluntary_exits, voluntary_exits,
sync_aggregate, sync_aggregate,
execution_payload: FullPayloadCapella { execution_payload }, execution_payload: FullPayloadCapella { execution_payload },
#[cfg(feature = "withdrawals")]
bls_to_execution_changes, bls_to_execution_changes,
} = self; } = self;
@ -449,7 +443,6 @@ impl<E: EthSpec> BeaconBlockBodyCapella<E, FullPayload<E>> {
execution_payload: BlindedPayloadCapella { execution_payload: BlindedPayloadCapella {
execution_payload_header: From::from(execution_payload.clone()), execution_payload_header: From::from(execution_payload.clone()),
}, },
#[cfg(feature = "withdrawals")]
bls_to_execution_changes: bls_to_execution_changes.clone(), bls_to_execution_changes: bls_to_execution_changes.clone(),
} }
} }
@ -468,7 +461,6 @@ impl<E: EthSpec> BeaconBlockBodyEip4844<E, FullPayload<E>> {
voluntary_exits, voluntary_exits,
sync_aggregate, sync_aggregate,
execution_payload: FullPayloadEip4844 { execution_payload }, execution_payload: FullPayloadEip4844 { execution_payload },
#[cfg(feature = "withdrawals")]
bls_to_execution_changes, bls_to_execution_changes,
blob_kzg_commitments, blob_kzg_commitments,
} = self; } = self;
@ -486,7 +478,6 @@ impl<E: EthSpec> BeaconBlockBodyEip4844<E, FullPayload<E>> {
execution_payload: BlindedPayloadEip4844 { execution_payload: BlindedPayloadEip4844 {
execution_payload_header: From::from(execution_payload.clone()), execution_payload_header: From::from(execution_payload.clone()),
}, },
#[cfg(feature = "withdrawals")]
bls_to_execution_changes: bls_to_execution_changes.clone(), bls_to_execution_changes: bls_to_execution_changes.clone(),
blob_kzg_commitments: blob_kzg_commitments.clone(), blob_kzg_commitments: blob_kzg_commitments.clone(),
} }

View File

@ -297,10 +297,8 @@ where
pub latest_execution_payload_header: ExecutionPayloadHeaderEip4844<T>, pub latest_execution_payload_header: ExecutionPayloadHeaderEip4844<T>,
// Withdrawals // Withdrawals
#[cfg(feature = "withdrawals")]
#[superstruct(only(Capella, Eip4844), partial_getter(copy))] #[superstruct(only(Capella, Eip4844), partial_getter(copy))]
pub next_withdrawal_index: u64, pub next_withdrawal_index: u64,
#[cfg(feature = "withdrawals")]
#[superstruct(only(Capella, Eip4844), partial_getter(copy))] #[superstruct(only(Capella, Eip4844), partial_getter(copy))]
pub next_withdrawal_validator_index: u64, pub next_withdrawal_validator_index: u64,

View File

@ -336,11 +336,9 @@ impl<T: EthSpec> BeaconTreeHashCacheInner<T> {
} }
// Withdrawal indices (Capella and later). // Withdrawal indices (Capella and later).
#[cfg(feature = "withdrawals")]
if let Ok(next_withdrawal_index) = state.next_withdrawal_index() { if let Ok(next_withdrawal_index) = state.next_withdrawal_index() {
hasher.write(next_withdrawal_index.tree_hash_root().as_bytes())?; hasher.write(next_withdrawal_index.tree_hash_root().as_bytes())?;
} }
#[cfg(feature = "withdrawals")]
if let Ok(next_withdrawal_validator_index) = state.next_withdrawal_validator_index() { if let Ok(next_withdrawal_validator_index) = state.next_withdrawal_validator_index() {
hasher.write(next_withdrawal_validator_index.tree_hash_root().as_bytes())?; hasher.write(next_withdrawal_validator_index.tree_hash_root().as_bytes())?;
} }

View File

@ -158,8 +158,9 @@ pub struct ChainSpec {
* Capella hard fork params * Capella hard fork params
*/ */
pub capella_fork_version: [u8; 4], pub capella_fork_version: [u8; 4],
/// The Capella fork epoch is optional, with `None` representing "Merge never happens". /// The Capella fork epoch is optional, with `None` representing "Capella never happens".
pub capella_fork_epoch: Option<Epoch>, pub capella_fork_epoch: Option<Epoch>,
pub max_validators_per_withdrawals_sweep: u64,
/* /*
* Eip4844 hard fork params * Eip4844 hard fork params
@ -634,6 +635,7 @@ impl ChainSpec {
*/ */
capella_fork_version: [0x03, 00, 00, 00], capella_fork_version: [0x03, 00, 00, 00],
capella_fork_epoch: None, capella_fork_epoch: None,
max_validators_per_withdrawals_sweep: 16384,
/* /*
* Eip4844 hard fork params * Eip4844 hard fork params
@ -707,6 +709,7 @@ impl ChainSpec {
// Capella // Capella
capella_fork_version: [0x03, 0x00, 0x00, 0x01], capella_fork_version: [0x03, 0x00, 0x00, 0x01],
capella_fork_epoch: None, capella_fork_epoch: None,
max_validators_per_withdrawals_sweep: 16,
// Eip4844 // Eip4844
eip4844_fork_version: [0x04, 0x00, 0x00, 0x01], eip4844_fork_version: [0x04, 0x00, 0x00, 0x01],
eip4844_fork_epoch: None, eip4844_fork_epoch: None,
@ -869,6 +872,7 @@ impl ChainSpec {
*/ */
capella_fork_version: [0x03, 0x00, 0x00, 0x64], capella_fork_version: [0x03, 0x00, 0x00, 0x64],
capella_fork_epoch: None, capella_fork_epoch: None,
max_validators_per_withdrawals_sweep: 16384,
/* /*
* Eip4844 hard fork params * Eip4844 hard fork params

View File

@ -1,5 +1,6 @@
use crate::{ use crate::{
consts::altair, AltairPreset, BasePreset, BellatrixPreset, ChainSpec, Config, EthSpec, ForkName, consts::altair, AltairPreset, BasePreset, BellatrixPreset, CapellaPreset, ChainSpec, Config,
EthSpec, ForkName,
}; };
use maplit::hashmap; use maplit::hashmap;
use serde_derive::{Deserialize, Serialize}; use serde_derive::{Deserialize, Serialize};
@ -11,7 +12,7 @@ use superstruct::superstruct;
/// ///
/// Mostly useful for the API. /// Mostly useful for the API.
#[superstruct( #[superstruct(
variants(Altair, Bellatrix), variants(Bellatrix, Capella),
variant_attributes(derive(Serialize, Deserialize, Debug, PartialEq, Clone)) variant_attributes(derive(Serialize, Deserialize, Debug, PartialEq, Clone))
)] )]
#[derive(Serialize, Deserialize, Debug, PartialEq, Clone)] #[derive(Serialize, Deserialize, Debug, PartialEq, Clone)]
@ -24,9 +25,11 @@ pub struct ConfigAndPreset {
pub base_preset: BasePreset, pub base_preset: BasePreset,
#[serde(flatten)] #[serde(flatten)]
pub altair_preset: AltairPreset, pub altair_preset: AltairPreset,
#[superstruct(only(Bellatrix))]
#[serde(flatten)] #[serde(flatten)]
pub bellatrix_preset: BellatrixPreset, pub bellatrix_preset: BellatrixPreset,
#[superstruct(only(Capella))]
#[serde(flatten)]
pub capella_preset: CapellaPreset,
/// The `extra_fields` map allows us to gracefully decode fields intended for future hard forks. /// The `extra_fields` map allows us to gracefully decode fields intended for future hard forks.
#[serde(flatten)] #[serde(flatten)]
pub extra_fields: HashMap<String, Value>, pub extra_fields: HashMap<String, Value>,
@ -37,14 +40,24 @@ impl ConfigAndPreset {
let config = Config::from_chain_spec::<T>(spec); let config = Config::from_chain_spec::<T>(spec);
let base_preset = BasePreset::from_chain_spec::<T>(spec); let base_preset = BasePreset::from_chain_spec::<T>(spec);
let altair_preset = AltairPreset::from_chain_spec::<T>(spec); let altair_preset = AltairPreset::from_chain_spec::<T>(spec);
let bellatrix_preset = BellatrixPreset::from_chain_spec::<T>(spec);
let extra_fields = get_extra_fields(spec); let extra_fields = get_extra_fields(spec);
if spec.bellatrix_fork_epoch.is_some() if spec.capella_fork_epoch.is_some()
|| fork_name.is_none() || fork_name.is_none()
|| fork_name == Some(ForkName::Merge) || fork_name == Some(ForkName::Capella)
{ {
let bellatrix_preset = BellatrixPreset::from_chain_spec::<T>(spec); let capella_preset = CapellaPreset::from_chain_spec::<T>(spec);
ConfigAndPreset::Capella(ConfigAndPresetCapella {
config,
base_preset,
altair_preset,
bellatrix_preset,
capella_preset,
extra_fields,
})
} else {
ConfigAndPreset::Bellatrix(ConfigAndPresetBellatrix { ConfigAndPreset::Bellatrix(ConfigAndPresetBellatrix {
config, config,
base_preset, base_preset,
@ -52,13 +65,6 @@ impl ConfigAndPreset {
bellatrix_preset, bellatrix_preset,
extra_fields, extra_fields,
}) })
} else {
ConfigAndPreset::Altair(ConfigAndPresetAltair {
config,
base_preset,
altair_preset,
extra_fields,
})
} }
} }
} }
@ -131,8 +137,8 @@ mod test {
.write(false) .write(false)
.open(tmp_file.as_ref()) .open(tmp_file.as_ref())
.expect("error while opening the file"); .expect("error while opening the file");
let from: ConfigAndPresetBellatrix = let from: ConfigAndPresetCapella =
serde_yaml::from_reader(reader).expect("error while deserializing"); serde_yaml::from_reader(reader).expect("error while deserializing");
assert_eq!(ConfigAndPreset::Bellatrix(from), yamlconfig); assert_eq!(ConfigAndPreset::Capella(from), yamlconfig);
} }
} }

View File

@ -80,7 +80,6 @@ pub struct ExecutionPayload<T: EthSpec> {
pub block_hash: ExecutionBlockHash, pub block_hash: ExecutionBlockHash,
#[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<T>, pub transactions: Transactions<T>,
#[cfg(feature = "withdrawals")]
#[superstruct(only(Capella, Eip4844))] #[superstruct(only(Capella, Eip4844))]
pub withdrawals: Withdrawals<T>, pub withdrawals: Withdrawals<T>,
} }

View File

@ -75,7 +75,6 @@ pub struct ExecutionPayloadHeader<T: EthSpec> {
pub block_hash: ExecutionBlockHash, pub block_hash: ExecutionBlockHash,
#[superstruct(getter(copy))] #[superstruct(getter(copy))]
pub transactions_root: Hash256, pub transactions_root: Hash256,
#[cfg(feature = "withdrawals")]
#[superstruct(only(Capella, Eip4844))] #[superstruct(only(Capella, Eip4844))]
#[superstruct(getter(copy))] #[superstruct(getter(copy))]
pub withdrawals_root: Hash256, pub withdrawals_root: Hash256,
@ -128,7 +127,6 @@ impl<T: EthSpec> ExecutionPayloadHeaderMerge<T> {
base_fee_per_gas: self.base_fee_per_gas, base_fee_per_gas: self.base_fee_per_gas,
block_hash: self.block_hash, block_hash: self.block_hash,
transactions_root: self.transactions_root, transactions_root: self.transactions_root,
#[cfg(feature = "withdrawals")]
withdrawals_root: Hash256::zero(), withdrawals_root: Hash256::zero(),
} }
} }
@ -153,7 +151,6 @@ impl<T: EthSpec> ExecutionPayloadHeaderCapella<T> {
excess_data_gas: Uint256::zero(), excess_data_gas: Uint256::zero(),
block_hash: self.block_hash, block_hash: self.block_hash,
transactions_root: self.transactions_root, transactions_root: self.transactions_root,
#[cfg(feature = "withdrawals")]
withdrawals_root: self.withdrawals_root, withdrawals_root: self.withdrawals_root,
} }
} }
@ -196,7 +193,6 @@ impl<T: EthSpec> From<ExecutionPayloadCapella<T>> for ExecutionPayloadHeaderCape
base_fee_per_gas: payload.base_fee_per_gas, base_fee_per_gas: payload.base_fee_per_gas,
block_hash: payload.block_hash, block_hash: payload.block_hash,
transactions_root: payload.transactions.tree_hash_root(), transactions_root: payload.transactions.tree_hash_root(),
#[cfg(feature = "withdrawals")]
withdrawals_root: payload.withdrawals.tree_hash_root(), withdrawals_root: payload.withdrawals.tree_hash_root(),
} }
} }
@ -219,7 +215,6 @@ impl<T: EthSpec> From<ExecutionPayloadEip4844<T>> for ExecutionPayloadHeaderEip4
excess_data_gas: payload.excess_data_gas, excess_data_gas: payload.excess_data_gas,
block_hash: payload.block_hash, block_hash: payload.block_hash,
transactions_root: payload.transactions.tree_hash_root(), transactions_root: payload.transactions.tree_hash_root(),
#[cfg(feature = "withdrawals")]
withdrawals_root: payload.withdrawals.tree_hash_root(), withdrawals_root: payload.withdrawals.tree_hash_root(),
} }
} }

View File

@ -123,7 +123,7 @@ pub use crate::bls_to_execution_change::BlsToExecutionChange;
pub use crate::chain_spec::{ChainSpec, Config, Domain}; pub use crate::chain_spec::{ChainSpec, Config, Domain};
pub use crate::checkpoint::Checkpoint; pub use crate::checkpoint::Checkpoint;
pub use crate::config_and_preset::{ pub use crate::config_and_preset::{
ConfigAndPreset, ConfigAndPresetAltair, ConfigAndPresetBellatrix, ConfigAndPreset, ConfigAndPresetBellatrix, ConfigAndPresetCapella,
}; };
pub use crate::contribution_and_proof::ContributionAndProof; pub use crate::contribution_and_proof::ContributionAndProof;
pub use crate::deposit::{Deposit, DEPOSIT_TREE_DEPTH}; pub use crate::deposit::{Deposit, DEPOSIT_TREE_DEPTH};
@ -160,7 +160,7 @@ pub use crate::payload::{
FullPayloadCapella, FullPayloadEip4844, FullPayloadMerge, FullPayloadRef, OwnedExecPayload, FullPayloadCapella, FullPayloadEip4844, FullPayloadMerge, FullPayloadRef, OwnedExecPayload,
}; };
pub use crate::pending_attestation::PendingAttestation; pub use crate::pending_attestation::PendingAttestation;
pub use crate::preset::{AltairPreset, BasePreset, BellatrixPreset}; pub use crate::preset::{AltairPreset, BasePreset, BellatrixPreset, CapellaPreset};
pub use crate::proposer_preparation_data::ProposerPreparationData; pub use crate::proposer_preparation_data::ProposerPreparationData;
pub use crate::proposer_slashing::ProposerSlashing; pub use crate::proposer_slashing::ProposerSlashing;
pub use crate::relative_epoch::{Error as RelativeEpochError, RelativeEpoch}; pub use crate::relative_epoch::{Error as RelativeEpochError, RelativeEpoch};

View File

@ -37,7 +37,6 @@ pub trait ExecPayload<T: EthSpec>: Debug + Clone + PartialEq + Hash + TreeHash +
fn gas_limit(&self) -> u64; fn gas_limit(&self) -> u64;
fn transactions(&self) -> Option<&Transactions<T>>; fn transactions(&self) -> Option<&Transactions<T>>;
/// fork-specific fields /// fork-specific fields
#[cfg(feature = "withdrawals")]
fn withdrawals_root(&self) -> Result<Hash256, Error>; fn withdrawals_root(&self) -> Result<Hash256, Error>;
/// Is this a default payload with 0x0 roots for transactions and withdrawals? /// Is this a default payload with 0x0 roots for transactions and withdrawals?
@ -241,7 +240,6 @@ impl<T: EthSpec> ExecPayload<T> for FullPayload<T> {
}) })
} }
#[cfg(feature = "withdrawals")]
fn withdrawals_root(&self) -> Result<Hash256, Error> { fn withdrawals_root(&self) -> Result<Hash256, Error> {
match self { match self {
FullPayload::Merge(_) => Err(Error::IncorrectStateVariant), FullPayload::Merge(_) => Err(Error::IncorrectStateVariant),
@ -343,7 +341,6 @@ impl<'b, T: EthSpec> ExecPayload<T> for FullPayloadRef<'b, T> {
}) })
} }
#[cfg(feature = "withdrawals")]
fn withdrawals_root(&self) -> Result<Hash256, Error> { fn withdrawals_root(&self) -> Result<Hash256, Error> {
match self { match self {
FullPayloadRef::Merge(_) => Err(Error::IncorrectStateVariant), FullPayloadRef::Merge(_) => Err(Error::IncorrectStateVariant),
@ -523,7 +520,6 @@ impl<T: EthSpec> ExecPayload<T> for BlindedPayload<T> {
None None
} }
#[cfg(feature = "withdrawals")]
fn withdrawals_root(&self) -> Result<Hash256, Error> { fn withdrawals_root(&self) -> Result<Hash256, Error> {
match self { match self {
BlindedPayload::Merge(_) => Err(Error::IncorrectStateVariant), BlindedPayload::Merge(_) => Err(Error::IncorrectStateVariant),
@ -614,7 +610,6 @@ impl<'b, T: EthSpec> ExecPayload<T> for BlindedPayloadRef<'b, T> {
None None
} }
#[cfg(feature = "withdrawals")]
fn withdrawals_root(&self) -> Result<Hash256, Error> { fn withdrawals_root(&self) -> Result<Hash256, Error> {
match self { match self {
BlindedPayloadRef::Merge(_) => Err(Error::IncorrectStateVariant), BlindedPayloadRef::Merge(_) => Err(Error::IncorrectStateVariant),
@ -712,7 +707,6 @@ macro_rules! impl_exec_payload_common {
f(self) f(self)
} }
#[cfg(feature = "withdrawals")]
fn withdrawals_root(&self) -> Result<Hash256, Error> { fn withdrawals_root(&self) -> Result<Hash256, Error> {
let g = $g; let g = $g;
g(self) g(self)

View File

@ -184,6 +184,27 @@ impl BellatrixPreset {
} }
} }
#[derive(Debug, PartialEq, Clone, Serialize, Deserialize)]
#[serde(rename_all = "UPPERCASE")]
pub struct CapellaPreset {
#[serde(with = "eth2_serde_utils::quoted_u64")]
pub max_bls_to_execution_changes: u64,
#[serde(with = "eth2_serde_utils::quoted_u64")]
pub max_withdrawals_per_payload: u64,
#[serde(with = "eth2_serde_utils::quoted_u64")]
pub max_validators_per_withdrawals_sweep: u64,
}
impl CapellaPreset {
pub fn from_chain_spec<T: EthSpec>(spec: &ChainSpec) -> Self {
Self {
max_bls_to_execution_changes: T::max_bls_to_execution_changes() as u64,
max_withdrawals_per_payload: T::max_withdrawals_per_payload() as u64,
max_validators_per_withdrawals_sweep: spec.max_validators_per_withdrawals_sweep,
}
}
}
#[cfg(test)] #[cfg(test)]
mod test { mod test {
use super::*; use super::*;
@ -219,6 +240,9 @@ mod test {
let bellatrix: BellatrixPreset = preset_from_file(&preset_name, "bellatrix.yaml"); let bellatrix: BellatrixPreset = preset_from_file(&preset_name, "bellatrix.yaml");
assert_eq!(bellatrix, BellatrixPreset::from_chain_spec::<E>(&spec)); assert_eq!(bellatrix, BellatrixPreset::from_chain_spec::<E>(&spec));
let capella: CapellaPreset = preset_from_file(&preset_name, "capella.yaml");
assert_eq!(capella, CapellaPreset::from_chain_spec::<E>(&spec));
} }
#[test] #[test]

View File

@ -341,7 +341,6 @@ impl<E: EthSpec> SignedBeaconBlockCapella<E, BlindedPayload<E>> {
voluntary_exits, voluntary_exits,
sync_aggregate, sync_aggregate,
execution_payload: BlindedPayloadCapella { .. }, execution_payload: BlindedPayloadCapella { .. },
#[cfg(feature = "withdrawals")]
bls_to_execution_changes, bls_to_execution_changes,
}, },
}, },
@ -364,7 +363,6 @@ impl<E: EthSpec> SignedBeaconBlockCapella<E, BlindedPayload<E>> {
voluntary_exits, voluntary_exits,
sync_aggregate, sync_aggregate,
execution_payload: FullPayloadCapella { execution_payload }, execution_payload: FullPayloadCapella { execution_payload },
#[cfg(feature = "withdrawals")]
bls_to_execution_changes, bls_to_execution_changes,
}, },
}, },
@ -397,7 +395,6 @@ impl<E: EthSpec> SignedBeaconBlockEip4844<E, BlindedPayload<E>> {
voluntary_exits, voluntary_exits,
sync_aggregate, sync_aggregate,
execution_payload: BlindedPayloadEip4844 { .. }, execution_payload: BlindedPayloadEip4844 { .. },
#[cfg(feature = "withdrawals")]
bls_to_execution_changes, bls_to_execution_changes,
blob_kzg_commitments, blob_kzg_commitments,
}, },
@ -421,7 +418,6 @@ impl<E: EthSpec> SignedBeaconBlockEip4844<E, BlindedPayload<E>> {
voluntary_exits, voluntary_exits,
sync_aggregate, sync_aggregate,
execution_payload: FullPayloadEip4844 { execution_payload }, execution_payload: FullPayloadEip4844 { execution_payload },
#[cfg(feature = "withdrawals")]
bls_to_execution_changes, bls_to_execution_changes,
blob_kzg_commitments, blob_kzg_commitments,
}, },

View File

@ -24,8 +24,6 @@ gnosis = []
slasher-mdbx = ["slasher/mdbx"] slasher-mdbx = ["slasher/mdbx"]
# Support slasher LMDB backend. # Support slasher LMDB backend.
slasher-lmdb = ["slasher/lmdb"] slasher-lmdb = ["slasher/lmdb"]
# Support for inclusion of withdrawals fields in all capella consensus types in all APIs.
withdrawals = ["types/withdrawals", "beacon_node/withdrawals"]
# Support for withdrawals consensus processing logic. # Support for withdrawals consensus processing logic.
withdrawals-processing = ["beacon_node/withdrawals-processing"] withdrawals-processing = ["beacon_node/withdrawals-processing"]

View File

@ -1,4 +1,4 @@
TESTS_TAG := v1.3.0-alpha.1-hotfix TESTS_TAG := v1.3.0-alpha.2
TESTS = general minimal mainnet TESTS = general minimal mainnet
TARBALLS = $(patsubst %,%-$(TESTS_TAG).tar.gz,$(TESTS)) TARBALLS = $(patsubst %,%-$(TESTS_TAG).tar.gz,$(TESTS))

View File

@ -4,9 +4,10 @@ use crate::case_result::compare_beacon_state_results_without_caches;
use crate::decode::{ssz_decode_file, ssz_decode_file_with, ssz_decode_state, yaml_decode_file}; use crate::decode::{ssz_decode_file, ssz_decode_file_with, ssz_decode_state, yaml_decode_file};
use crate::testing_spec; use crate::testing_spec;
use serde_derive::Deserialize; use serde_derive::Deserialize;
use state_processing::per_block_processing::process_operations::process_bls_to_execution_changes; #[cfg(feature = "withdrawals-processing")]
#[cfg(feature = "withdrawals")] use state_processing::per_block_processing::process_operations::{
use state_processing::per_block_processing::process_withdrawals; process_bls_to_execution_changes, process_bls_to_execution_changes,
};
use state_processing::{ use state_processing::{
per_block_processing::{ per_block_processing::{
errors::BlockProcessingError, errors::BlockProcessingError,
@ -21,7 +22,7 @@ use state_processing::{
}; };
use std::fmt::Debug; use std::fmt::Debug;
use std::path::Path; use std::path::Path;
#[cfg(feature = "withdrawals")] #[cfg(feature = "withdrawals-processing")]
use types::SignedBlsToExecutionChange; use types::SignedBlsToExecutionChange;
use types::{ use types::{
Attestation, AttesterSlashing, BeaconBlock, BeaconState, BlindedPayload, ChainSpec, Deposit, Attestation, AttesterSlashing, BeaconBlock, BeaconState, BlindedPayload, ChainSpec, Deposit,
@ -41,7 +42,7 @@ struct ExecutionMetadata {
} }
/// Newtype for testing withdrawals. /// Newtype for testing withdrawals.
#[cfg(feature = "withdrawals")] #[cfg(feature = "withdrawals-processing")]
#[derive(Debug, Clone, Deserialize)] #[derive(Debug, Clone, Deserialize)]
pub struct WithdrawalsPayload<T: EthSpec> { pub struct WithdrawalsPayload<T: EthSpec> {
payload: FullPayload<T>, payload: FullPayload<T>,
@ -340,6 +341,7 @@ impl<E: EthSpec> Operation<E> for BlindedPayload<E> {
} }
} }
#[cfg(feature = "withdrawals-processing")]
impl<E: EthSpec> Operation<E> for WithdrawalsPayload<E> { impl<E: EthSpec> Operation<E> for WithdrawalsPayload<E> {
fn handler_name() -> String { fn handler_name() -> String {
"withdrawals".into() "withdrawals".into()
@ -385,18 +387,7 @@ impl<E: EthSpec> Operation<E> for WithdrawalsPayload<E> {
} }
} }
#[cfg(not(feature = "withdrawals"))] #[cfg(feature = "withdrawals-processing")]
fn apply_to(
&self,
state: &mut BeaconState<E>,
spec: &ChainSpec,
_: &Operations<E, Self>,
) -> Result<(), BlockProcessingError> {
Ok(())
}
}
#[cfg(feature = "withdrawals")]
impl<E: EthSpec> Operation<E> for SignedBlsToExecutionChange { impl<E: EthSpec> Operation<E> for SignedBlsToExecutionChange {
fn handler_name() -> String { fn handler_name() -> String {
"bls_to_execution_change".into() "bls_to_execution_change".into()

View File

@ -1,5 +1,5 @@
pub use case_result::CaseResult; pub use case_result::CaseResult;
#[cfg(all(feature = "withdrawals", feature = "withdrawals-processing"))] #[cfg(feature = "withdrawals-processing")]
pub use cases::WithdrawalsPayload; pub use cases::WithdrawalsPayload;
pub use cases::{ pub use cases::{
Case, EffectiveBalanceUpdates, Eth1DataReset, HistoricalRootsUpdate, InactivityUpdates, Case, EffectiveBalanceUpdates, Eth1DataReset, HistoricalRootsUpdate, InactivityUpdates,

View File

@ -82,14 +82,14 @@ fn operations_execution_payload_blinded() {
OperationsHandler::<MainnetEthSpec, BlindedPayload<_>>::default().run(); OperationsHandler::<MainnetEthSpec, BlindedPayload<_>>::default().run();
} }
#[cfg(all(feature = "withdrawals", feature = "withdrawals-processing"))] #[cfg(feature = "withdrawals-processing")]
#[test] #[test]
fn operations_withdrawals() { fn operations_withdrawals() {
OperationsHandler::<MinimalEthSpec, WithdrawalsPayload<_>>::default().run(); OperationsHandler::<MinimalEthSpec, WithdrawalsPayload<_>>::default().run();
OperationsHandler::<MainnetEthSpec, WithdrawalsPayload<_>>::default().run(); OperationsHandler::<MainnetEthSpec, WithdrawalsPayload<_>>::default().run();
} }
#[cfg(all(feature = "withdrawals", feature = "withdrawals-processing"))] #[cfg(feature = "withdrawals-processing")]
#[test] #[test]
fn operations_bls_to_execution_change() { fn operations_bls_to_execution_change() {
OperationsHandler::<MinimalEthSpec, SignedBlsToExecutionChange>::default().run(); OperationsHandler::<MinimalEthSpec, SignedBlsToExecutionChange>::default().run();

View File

@ -23,5 +23,4 @@ hex = "0.4.2"
fork_choice = { path = "../../consensus/fork_choice" } fork_choice = { path = "../../consensus/fork_choice" }
[features] [features]
default = [] default = []
withdrawals = []