mirror of
https://github.com/sigp/lighthouse.git
synced 2026-03-22 06:14:38 +00:00
Updated for queueless withdrawals spec
This commit is contained in:
@@ -62,6 +62,10 @@ pub struct BeaconBlockBody<T: EthSpec, Payload: AbstractExecPayload<T> = FullPay
|
||||
#[superstruct(only(Eip4844), partial_getter(rename = "execution_payload_eip4844"))]
|
||||
#[serde(flatten)]
|
||||
pub execution_payload: Payload::Eip4844,
|
||||
#[cfg(feature = "withdrawals")]
|
||||
#[superstruct(only(Capella, Eip4844))]
|
||||
pub bls_to_execution_changes:
|
||||
VariableList<SignedBlsToExecutionChange, T::MaxBlsToExecutionChanges>,
|
||||
#[superstruct(only(Eip4844))]
|
||||
pub blob_kzg_commitments: VariableList<KzgCommitment, T::MaxBlobsPerBlock>,
|
||||
#[superstruct(only(Base, Altair))]
|
||||
|
||||
@@ -297,13 +297,10 @@ where
|
||||
// Withdrawals
|
||||
#[cfg(feature = "withdrawals")]
|
||||
#[superstruct(only(Capella, Eip4844))]
|
||||
pub withdrawal_queue: VariableList<Withdrawal, T::WithdrawalQueueLimit>,
|
||||
#[cfg(feature = "withdrawals")]
|
||||
#[superstruct(only(Capella, Eip4844))]
|
||||
pub next_withdrawal_index: u64,
|
||||
#[cfg(feature = "withdrawals")]
|
||||
#[superstruct(only(Capella, Eip4844))]
|
||||
pub next_partial_withdrawal_validator_index: u64,
|
||||
pub latest_withdrawal_validator_index: u64,
|
||||
|
||||
// Caching (not in the spec)
|
||||
#[serde(skip_serializing, skip_deserializing)]
|
||||
|
||||
@@ -98,8 +98,6 @@ pub trait EthSpec: 'static + Default + Sync + Send + Clone + Debug + PartialEq +
|
||||
/*
|
||||
* New in Capella
|
||||
*/
|
||||
type MaxPartialWithdrawalsPerEpoch: Unsigned + Clone + Sync + Send + Debug + PartialEq;
|
||||
type WithdrawalQueueLimit: Unsigned + Clone + Sync + Send + Debug + PartialEq;
|
||||
type MaxBlsToExecutionChanges: Unsigned + Clone + Sync + Send + Debug + PartialEq;
|
||||
type MaxWithdrawalsPerPayload: Unsigned + Clone + Sync + Send + Debug + PartialEq;
|
||||
/*
|
||||
@@ -235,16 +233,6 @@ pub trait EthSpec: 'static + Default + Sync + Send + Clone + Debug + PartialEq +
|
||||
Self::BytesPerLogsBloom::to_usize()
|
||||
}
|
||||
|
||||
/// Returns the `MAX_PARTIAL_WITHDRAWALS_PER_EPOCH` constant for this specification.
|
||||
fn max_partial_withdrawals_per_epoch() -> usize {
|
||||
Self::MaxPartialWithdrawalsPerEpoch::to_usize()
|
||||
}
|
||||
|
||||
/// Returns the `WITHDRAWAL_QUEUE_LIMIT` constant for this specification.
|
||||
fn withdrawal_queue_limit() -> usize {
|
||||
Self::WithdrawalQueueLimit::to_usize()
|
||||
}
|
||||
|
||||
/// Returns the `MAX_BLS_TO_EXECUTION_CHANGES` constant for this specification.
|
||||
fn max_bls_to_execution_changes() -> usize {
|
||||
Self::MaxBlsToExecutionChanges::to_usize()
|
||||
@@ -309,8 +297,6 @@ impl EthSpec for MainnetEthSpec {
|
||||
type SyncSubcommitteeSize = U128; // 512 committee size / 4 sync committee subnet count
|
||||
type MaxPendingAttestations = U4096; // 128 max attestations * 32 slots per epoch
|
||||
type SlotsPerEth1VotingPeriod = U2048; // 64 epochs * 32 slots per epoch
|
||||
type MaxPartialWithdrawalsPerEpoch = U256;
|
||||
type WithdrawalQueueLimit = U1099511627776;
|
||||
type MaxBlsToExecutionChanges = U16;
|
||||
type MaxWithdrawalsPerPayload = U16;
|
||||
|
||||
@@ -358,8 +344,6 @@ impl EthSpec for MinimalEthSpec {
|
||||
GasLimitDenominator,
|
||||
MinGasLimit,
|
||||
MaxExtraDataBytes,
|
||||
MaxPartialWithdrawalsPerEpoch,
|
||||
WithdrawalQueueLimit,
|
||||
MaxBlsToExecutionChanges,
|
||||
MaxWithdrawalsPerPayload,
|
||||
MaxBlobsPerBlock,
|
||||
@@ -408,8 +392,6 @@ impl EthSpec for GnosisEthSpec {
|
||||
type SyncSubcommitteeSize = U128; // 512 committee size / 4 sync committee subnet count
|
||||
type MaxPendingAttestations = U2048; // 128 max attestations * 16 slots per epoch
|
||||
type SlotsPerEth1VotingPeriod = U1024; // 64 epochs * 16 slots per epoch
|
||||
type MaxPartialWithdrawalsPerEpoch = U256;
|
||||
type WithdrawalQueueLimit = U1099511627776;
|
||||
type MaxBlsToExecutionChanges = U16;
|
||||
type MaxWithdrawalsPerPayload = U16;
|
||||
type MaxBlobsPerBlock = U16; // 2**4 = 16
|
||||
|
||||
@@ -3,7 +3,6 @@ use derivative::Derivative;
|
||||
use serde_derive::{Deserialize, Serialize};
|
||||
use ssz::Encode;
|
||||
use ssz_derive::{Decode, Encode};
|
||||
use std::slice::Iter;
|
||||
use test_random_derive::TestRandom;
|
||||
use tree_hash_derive::TreeHash;
|
||||
|
||||
@@ -13,6 +12,8 @@ pub type Transactions<T> = VariableList<
|
||||
<T as EthSpec>::MaxTransactionsPerPayload,
|
||||
>;
|
||||
|
||||
pub type Withdrawals<T> = VariableList<Withdrawal, <T as EthSpec>::MaxWithdrawalsPerPayload>;
|
||||
|
||||
#[superstruct(
|
||||
variants(Merge, Capella, Eip4844),
|
||||
variant_attributes(
|
||||
@@ -82,7 +83,7 @@ pub struct ExecutionPayload<T: EthSpec> {
|
||||
pub transactions: Transactions<T>,
|
||||
#[cfg(feature = "withdrawals")]
|
||||
#[superstruct(only(Capella, Eip4844))]
|
||||
pub withdrawals: VariableList<Withdrawal, T::MaxWithdrawalsPerPayload>,
|
||||
pub withdrawals: Withdrawals<T>,
|
||||
}
|
||||
|
||||
impl<T: EthSpec> ExecutionPayload<T> {
|
||||
|
||||
@@ -27,6 +27,7 @@ pub mod beacon_block_body;
|
||||
pub mod beacon_block_header;
|
||||
pub mod beacon_committee;
|
||||
pub mod beacon_state;
|
||||
pub mod bls_to_execution_change;
|
||||
pub mod builder_bid;
|
||||
pub mod chain_spec;
|
||||
pub mod checkpoint;
|
||||
@@ -61,6 +62,7 @@ pub mod shuffling_id;
|
||||
pub mod signed_aggregate_and_proof;
|
||||
pub mod signed_beacon_block;
|
||||
pub mod signed_beacon_block_header;
|
||||
pub mod signed_bls_to_execution_change;
|
||||
pub mod signed_contribution_and_proof;
|
||||
pub mod signed_voluntary_exit;
|
||||
pub mod signing_data;
|
||||
@@ -117,6 +119,7 @@ pub use crate::beacon_block_header::BeaconBlockHeader;
|
||||
pub use crate::beacon_committee::{BeaconCommittee, OwnedBeaconCommittee};
|
||||
pub use crate::beacon_state::{BeaconTreeHashCache, Error as BeaconStateError, *};
|
||||
pub use crate::blobs_sidecar::BlobsSidecar;
|
||||
pub use crate::bls_to_execution_change::BlsToExecutionChange;
|
||||
pub use crate::chain_spec::{ChainSpec, Config, Domain};
|
||||
pub use crate::checkpoint::Checkpoint;
|
||||
pub use crate::config_and_preset::{
|
||||
@@ -133,7 +136,7 @@ pub use crate::eth_spec::EthSpecId;
|
||||
pub use crate::execution_block_hash::ExecutionBlockHash;
|
||||
pub use crate::execution_payload::{
|
||||
ExecutionPayload, ExecutionPayloadCapella, ExecutionPayloadEip4844, ExecutionPayloadMerge,
|
||||
ExecutionPayloadRef, Transaction, Transactions,
|
||||
ExecutionPayloadRef, Transaction, Transactions, Withdrawals,
|
||||
};
|
||||
pub use crate::execution_payload_header::{
|
||||
ExecutionPayloadHeader, ExecutionPayloadHeaderCapella, ExecutionPayloadHeaderEip4844,
|
||||
@@ -170,6 +173,7 @@ pub use crate::signed_beacon_block::{
|
||||
SignedBlindedBeaconBlock,
|
||||
};
|
||||
pub use crate::signed_beacon_block_header::SignedBeaconBlockHeader;
|
||||
pub use crate::signed_bls_to_execution_change::SignedBlsToExecutionChange;
|
||||
pub use crate::signed_contribution_and_proof::SignedContributionAndProof;
|
||||
pub use crate::signed_voluntary_exit::SignedVoluntaryExit;
|
||||
pub use crate::signing_data::{SignedRoot, SigningData};
|
||||
|
||||
@@ -36,6 +36,9 @@ pub trait ExecPayload<T: EthSpec>: Debug + Clone + PartialEq + Hash + TreeHash +
|
||||
fn fee_recipient(&self) -> Address;
|
||||
fn gas_limit(&self) -> u64;
|
||||
fn transactions(&self) -> Option<&Transactions<T>>;
|
||||
/// fork-specific fields
|
||||
#[cfg(feature = "withdrawals")]
|
||||
fn withdrawals(&self) -> Option<Result<&Withdrawals<T>, Error>>;
|
||||
|
||||
/// Is this a default payload? (pre-merge)
|
||||
fn is_default(&self) -> bool;
|
||||
@@ -225,6 +228,15 @@ impl<T: EthSpec> ExecPayload<T> for FullPayload<T> {
|
||||
})
|
||||
}
|
||||
|
||||
#[cfg(feature = "withdrawals")]
|
||||
fn withdrawals(&self) -> Option<Result<&Withdrawals<T>, Error>> {
|
||||
match self {
|
||||
FullPayload::Merge(_) => Some(Err(Error::IncorrectStateVariant)),
|
||||
FullPayload::Capella(ref inner) => Some(Ok(&inner.execution_payload.withdrawals)),
|
||||
FullPayload::Eip4844(ref inner) => Some(Ok(&inner.execution_payload.withdrawals)),
|
||||
}
|
||||
}
|
||||
|
||||
fn is_default<'a>(&'a self) -> bool {
|
||||
map_full_payload_ref!(&'a _, self.to_ref(), move |payload, cons| {
|
||||
cons(payload);
|
||||
@@ -309,6 +321,15 @@ impl<'b, T: EthSpec> ExecPayload<T> for FullPayloadRef<'b, T> {
|
||||
})
|
||||
}
|
||||
|
||||
#[cfg(feature = "withdrawals")]
|
||||
fn withdrawals(&self) -> Option<Result<&Withdrawals<T>, Error>> {
|
||||
match self {
|
||||
FullPayloadRef::Merge(_inner) => Some(Err(Error::IncorrectStateVariant)),
|
||||
FullPayloadRef::Capella(inner) => Some(Ok(&inner.execution_payload.withdrawals)),
|
||||
FullPayloadRef::Eip4844(inner) => Some(Ok(&inner.execution_payload.withdrawals)),
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: can this function be optimized?
|
||||
fn is_default<'a>(&'a self) -> bool {
|
||||
map_full_payload_ref!(&'a _, self, move |payload, cons| {
|
||||
@@ -463,6 +484,11 @@ impl<T: EthSpec> ExecPayload<T> for BlindedPayload<T> {
|
||||
None
|
||||
}
|
||||
|
||||
#[cfg(feature = "withdrawals")]
|
||||
fn withdrawals(&self) -> Option<Result<&Withdrawals<T>, Error>> {
|
||||
None
|
||||
}
|
||||
|
||||
fn is_default<'a>(&'a self) -> bool {
|
||||
map_blinded_payload_ref!(&'a _, self.to_ref(), move |payload, cons| {
|
||||
cons(payload);
|
||||
@@ -536,6 +562,11 @@ impl<'b, T: EthSpec> ExecPayload<T> for BlindedPayloadRef<'b, T> {
|
||||
None
|
||||
}
|
||||
|
||||
#[cfg(feature = "withdrawals")]
|
||||
fn withdrawals<'a>(&'a self) -> Option<Result<&Withdrawals<T>, Error>> {
|
||||
None
|
||||
}
|
||||
|
||||
// TODO: can this function be optimized?
|
||||
fn is_default<'a>(&'a self) -> bool {
|
||||
map_blinded_payload_ref!(&'a _, self, move |payload, cons| {
|
||||
@@ -546,7 +577,7 @@ impl<'b, T: EthSpec> ExecPayload<T> for BlindedPayloadRef<'b, T> {
|
||||
}
|
||||
|
||||
macro_rules! impl_exec_payload_common {
|
||||
($wrapper_type:ident, $wrapped_type_full:ident, $wrapped_header_type:ident, $wrapped_field:ident, $fork_variant:ident, $block_type_variant:ident, $f:block) => {
|
||||
($wrapper_type:ident, $wrapped_type_full:ident, $wrapped_header_type:ident, $wrapped_field:ident, $fork_variant:ident, $block_type_variant:ident, $f:block, $g:block) => {
|
||||
impl<T: EthSpec> ExecPayload<T> for $wrapper_type<T> {
|
||||
fn block_type() -> BlockType {
|
||||
BlockType::$block_type_variant
|
||||
@@ -594,6 +625,12 @@ macro_rules! impl_exec_payload_common {
|
||||
let f = $f;
|
||||
f(self)
|
||||
}
|
||||
|
||||
#[cfg(feature = "withdrawals")]
|
||||
fn withdrawals(&self) -> Option<Result<&Withdrawals<T>, Error>> {
|
||||
let g = $g;
|
||||
g(self)
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: EthSpec> From<$wrapped_type_full<T>> for $wrapper_type<T> {
|
||||
@@ -605,7 +642,7 @@ macro_rules! impl_exec_payload_common {
|
||||
}
|
||||
|
||||
macro_rules! impl_exec_payload_for_fork {
|
||||
($wrapper_type_header:ident, $wrapper_type_full:ident, $wrapped_type_header:ident, $wrapped_type_full:ident, $fork_variant:ident) => {
|
||||
($wrapper_type_header:ident, $wrapper_type_full:ident, $wrapped_type_header:ident, $wrapped_type_full:ident, $fork_variant:ident, $withdrawal_fn:block) => {
|
||||
//*************** Blinded payload implementations ******************//
|
||||
|
||||
impl_exec_payload_common!(
|
||||
@@ -615,6 +652,7 @@ macro_rules! impl_exec_payload_for_fork {
|
||||
execution_payload_header,
|
||||
$fork_variant,
|
||||
Blinded,
|
||||
{ |_| { None } },
|
||||
{ |_| { None } }
|
||||
);
|
||||
|
||||
@@ -680,7 +718,8 @@ macro_rules! impl_exec_payload_for_fork {
|
||||
let c: for<'a> fn(&'a $wrapper_type_full<T>) -> Option<&'a Transactions<T>> =
|
||||
|payload: &$wrapper_type_full<T>| Some(&payload.execution_payload.transactions);
|
||||
c
|
||||
}
|
||||
},
|
||||
$withdrawal_fn
|
||||
);
|
||||
|
||||
impl<T: EthSpec> Default for $wrapper_type_full<T> {
|
||||
@@ -723,21 +762,36 @@ impl_exec_payload_for_fork!(
|
||||
FullPayloadMerge,
|
||||
ExecutionPayloadHeaderMerge,
|
||||
ExecutionPayloadMerge,
|
||||
Merge
|
||||
Merge,
|
||||
{
|
||||
let c: for<'a> fn(&'a FullPayloadMerge<T>) -> Option<Result<&'a Withdrawals<T>, Error>> =
|
||||
|_| Some(Err(Error::IncorrectStateVariant));
|
||||
c
|
||||
}
|
||||
);
|
||||
impl_exec_payload_for_fork!(
|
||||
BlindedPayloadCapella,
|
||||
FullPayloadCapella,
|
||||
ExecutionPayloadHeaderCapella,
|
||||
ExecutionPayloadCapella,
|
||||
Capella
|
||||
Capella,
|
||||
{
|
||||
let c: for<'a> fn(&'a FullPayloadCapella<T>) -> Option<Result<&Withdrawals<T>, Error>> =
|
||||
|payload: &FullPayloadCapella<T>| Some(Ok(&payload.execution_payload.withdrawals));
|
||||
c
|
||||
}
|
||||
);
|
||||
impl_exec_payload_for_fork!(
|
||||
BlindedPayloadEip4844,
|
||||
FullPayloadEip4844,
|
||||
ExecutionPayloadHeaderEip4844,
|
||||
ExecutionPayloadEip4844,
|
||||
Eip4844
|
||||
Eip4844,
|
||||
{
|
||||
let c: for<'a> fn(&'a FullPayloadEip4844<T>) -> Option<Result<&Withdrawals<T>, Error>> =
|
||||
|payload: &FullPayloadEip4844<T>| Some(Ok(&payload.execution_payload.withdrawals));
|
||||
c
|
||||
}
|
||||
);
|
||||
|
||||
impl<T: EthSpec> AbstractExecPayload<T> for BlindedPayload<T> {
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
use crate::{
|
||||
test_utils::TestRandom, BeaconState, ChainSpec, Epoch, EthSpec, Hash256, PublicKeyBytes,
|
||||
test_utils::TestRandom, Address, BeaconState, BlsToExecutionChange, ChainSpec, Epoch, EthSpec,
|
||||
Hash256, PublicKeyBytes,
|
||||
};
|
||||
use serde_derive::{Deserialize, Serialize};
|
||||
use ssz_derive::{Decode, Encode};
|
||||
@@ -75,6 +76,16 @@ impl Validator {
|
||||
.unwrap_or(false)
|
||||
}
|
||||
|
||||
/// Changes withdrawal credentials to the provided eth1 execution address
|
||||
///
|
||||
/// WARNING: this function does NO VALIDATION - it just does it!
|
||||
pub fn change_withdrawal_credentials(&mut self, execution_address: &Address, spec: &ChainSpec) {
|
||||
let mut bytes = [0u8; 32];
|
||||
bytes[0] = spec.eth1_address_withdrawal_prefix_byte;
|
||||
bytes[12..].copy_from_slice(execution_address.as_bytes());
|
||||
self.withdrawal_credentials = Hash256::from(bytes);
|
||||
}
|
||||
|
||||
/// Returns `true` if the validator is fully withdrawable at some epoch
|
||||
pub fn is_fully_withdrawable_at(&self, balance: u64, epoch: Epoch, spec: &ChainSpec) -> bool {
|
||||
self.has_eth1_withdrawal_credential(spec) && self.withdrawable_epoch <= epoch && balance > 0
|
||||
|
||||
Reference in New Issue
Block a user