Merge branch 'electra-engine-api' of https://github.com/sigp/lighthouse into beacon-api-electra

This commit is contained in:
realbigsean
2024-07-08 18:25:56 -07:00
113 changed files with 1728 additions and 2663 deletions

View File

@@ -33,7 +33,6 @@ test_random_derive = { path = "../../common/test_random_derive" }
tree_hash = { workspace = true, features = ["arbitrary"] }
tree_hash_derive = { workspace = true }
rand_xorshift = "0.3.0"
cached_tree_hash = { workspace = true }
serde_yaml = { workspace = true }
tempfile = { workspace = true }
derivative = { workspace = true }

View File

@@ -35,7 +35,7 @@ MAX_CONSOLIDATIONS: 1
# Execution
# ---------------------------------------------------------------
# 2**13 (= 8192) receipts
MAX_DEPOSIT_RECEIPTS_PER_PAYLOAD: 8192
MAX_DEPOSIT_REQUESTS_PER_PAYLOAD: 8192
# 2**4 (= 16) withdrawal requests
MAX_WITHDRAWAL_REQUESTS_PER_PAYLOAD: 16

View File

@@ -35,7 +35,7 @@ MAX_CONSOLIDATIONS: 1
# Execution
# ---------------------------------------------------------------
# 2**13 (= 8192) receipts
MAX_DEPOSIT_RECEIPTS_PER_PAYLOAD: 8192
MAX_DEPOSIT_REQUESTS_PER_PAYLOAD: 8192
# 2**4 (= 16) withdrawal requests
MAX_WITHDRAWAL_REQUESTS_PER_PAYLOAD: 16

View File

@@ -35,7 +35,7 @@ MAX_CONSOLIDATIONS: 1
# Execution
# ---------------------------------------------------------------
# [customized]
MAX_DEPOSIT_RECEIPTS_PER_PAYLOAD: 4
MAX_DEPOSIT_REQUESTS_PER_PAYLOAD: 4
# [customized] 2**1 (= 2) withdrawal requests
MAX_WITHDRAWAL_REQUESTS_PER_PAYLOAD: 2

View File

@@ -3,6 +3,7 @@ use crate::indexed_attestation::{
};
use crate::{test_utils::TestRandom, EthSpec};
use derivative::Derivative;
use rand::{Rng, RngCore};
use serde::{Deserialize, Serialize};
use ssz_derive::{Decode, Encode};
use superstruct::superstruct;
@@ -160,6 +161,16 @@ impl<E: EthSpec> AttesterSlashing<E> {
}
}
impl<E: EthSpec> TestRandom for AttesterSlashing<E> {
fn random_for_test(rng: &mut impl RngCore) -> Self {
if rng.gen_bool(0.5) {
AttesterSlashing::Base(AttesterSlashingBase::random_for_test(rng))
} else {
AttesterSlashing::Electra(AttesterSlashingElectra::random_for_test(rng))
}
}
}
impl<E: EthSpec> crate::ForkVersionDeserialize for Vec<AttesterSlashing<E>> {
fn deserialize_by_fork<'de, D: serde::Deserializer<'de>>(
value: serde_json::Value,

View File

@@ -121,7 +121,6 @@ pub enum Error {
state: Slot,
},
TreeHashError(tree_hash::Error),
CachedTreeHashError(cached_tree_hash::Error),
InvalidValidatorPubkey(ssz::DecodeError),
ValidatorRegistryShrunk,
TreeHashCacheInconsistent,
@@ -481,7 +480,7 @@ where
#[superstruct(only(Electra), partial_getter(copy))]
#[metastruct(exclude_from(tree_lists))]
#[serde(with = "serde_utils::quoted_u64")]
pub deposit_receipts_start_index: u64,
pub deposit_requests_start_index: u64,
#[superstruct(only(Electra), partial_getter(copy))]
#[metastruct(exclude_from(tree_lists))]
#[serde(with = "serde_utils::quoted_u64")]
@@ -2560,12 +2559,6 @@ impl From<bls::Error> for Error {
}
}
impl From<cached_tree_hash::Error> for Error {
fn from(e: cached_tree_hash::Error) -> Error {
Error::CachedTreeHashError(e)
}
}
impl From<tree_hash::Error> for Error {
fn from(e: tree_hash::Error) -> Error {
Error::TreeHashError(e)

View File

@@ -180,7 +180,7 @@ pub struct ChainSpec {
pub electra_fork_version: [u8; 4],
/// The Electra fork epoch is optional, with `None` representing "Electra never happens".
pub electra_fork_epoch: Option<Epoch>,
pub unset_deposit_receipts_start_index: u64,
pub unset_deposit_requests_start_index: u64,
pub full_exit_request_amount: u64,
pub min_activation_balance: u64,
pub max_effective_balance_electra: u64,
@@ -393,7 +393,7 @@ impl ChainSpec {
state: &BeaconState<E>,
) -> u64 {
let fork_name = state.fork_name_unchecked();
if fork_name >= ForkName::Electra {
if fork_name.electra_enabled() {
self.whistleblower_reward_quotient_electra
} else {
self.whistleblower_reward_quotient
@@ -401,7 +401,7 @@ impl ChainSpec {
}
pub fn max_effective_balance_for_fork(&self, fork_name: ForkName) -> u64 {
if fork_name >= ForkName::Electra {
if fork_name.electra_enabled() {
self.max_effective_balance_electra
} else {
self.max_effective_balance
@@ -747,7 +747,7 @@ impl ChainSpec {
*/
electra_fork_version: [0x05, 00, 00, 00],
electra_fork_epoch: None,
unset_deposit_receipts_start_index: u64::MAX,
unset_deposit_requests_start_index: u64::MAX,
full_exit_request_amount: 0,
min_activation_balance: option_wrapper(|| {
u64::checked_pow(2, 5)?.checked_mul(u64::checked_pow(10, 9)?)
@@ -1049,7 +1049,7 @@ impl ChainSpec {
*/
electra_fork_version: [0x05, 0x00, 0x00, 0x64],
electra_fork_epoch: None,
unset_deposit_receipts_start_index: u64::MAX,
unset_deposit_requests_start_index: u64::MAX,
full_exit_request_amount: 0,
min_activation_balance: option_wrapper(|| {
u64::checked_pow(2, 5)?.checked_mul(u64::checked_pow(10, 9)?)

View File

@@ -124,7 +124,7 @@ pub fn get_extra_fields(spec: &ChainSpec) -> HashMap<String, Value> {
"versioned_hash_version_kzg".to_uppercase() => deneb::VERSIONED_HASH_VERSION_KZG.to_string().into(),
// Electra
"compounding_withdrawal_prefix".to_uppercase() => u8_hex(spec.compounding_withdrawal_prefix_byte),
"unset_deposit_receipts_start_index".to_uppercase() => spec.unset_deposit_receipts_start_index.to_string().into(),
"unset_deposit_requests_start_index".to_uppercase() => spec.unset_deposit_requests_start_index.to_string().into(),
"full_exit_request_amount".to_uppercase() => spec.full_exit_request_amount.to_string().into(),
"domain_consolidation".to_uppercase()=> u32_hex(spec.domain_consolidation),
}

View File

@@ -19,7 +19,7 @@ use tree_hash_derive::TreeHash;
TreeHash,
TestRandom,
)]
pub struct DepositReceipt {
pub struct DepositRequest {
pub pubkey: PublicKeyBytes,
pub withdrawal_credentials: Hash256,
#[serde(with = "serde_utils::quoted_u64")]
@@ -33,5 +33,5 @@ pub struct DepositReceipt {
mod tests {
use super::*;
ssz_and_tree_hash_tests!(DepositReceipt);
ssz_and_tree_hash_tests!(DepositRequest);
}

View File

@@ -144,7 +144,7 @@ pub trait EthSpec:
type PendingPartialWithdrawalsLimit: Unsigned + Clone + Sync + Send + Debug + PartialEq;
type PendingConsolidationsLimit: Unsigned + Clone + Sync + Send + Debug + PartialEq;
type MaxConsolidations: Unsigned + Clone + Sync + Send + Debug + PartialEq;
type MaxDepositReceiptsPerPayload: Unsigned + Clone + Sync + Send + Debug + PartialEq;
type MaxDepositRequestsPerPayload: Unsigned + Clone + Sync + Send + Debug + PartialEq;
type MaxAttesterSlashingsElectra: Unsigned + Clone + Sync + Send + Debug + PartialEq;
type MaxAttestationsElectra: Unsigned + Clone + Sync + Send + Debug + PartialEq;
type MaxWithdrawalRequestsPerPayload: Unsigned + Clone + Sync + Send + Debug + PartialEq;
@@ -330,9 +330,9 @@ pub trait EthSpec:
Self::MaxConsolidations::to_usize()
}
/// Returns the `MAX_DEPOSIT_RECEIPTS_PER_PAYLOAD` constant for this specification.
fn max_deposit_receipts_per_payload() -> usize {
Self::MaxDepositReceiptsPerPayload::to_usize()
/// Returns the `MAX_DEPOSIT_REQUESTS_PER_PAYLOAD` constant for this specification.
fn max_deposit_requests_per_payload() -> usize {
Self::MaxDepositRequestsPerPayload::to_usize()
}
/// Returns the `MAX_ATTESTER_SLASHINGS_ELECTRA` constant for this specification.
@@ -405,7 +405,7 @@ impl EthSpec for MainnetEthSpec {
type PendingPartialWithdrawalsLimit = U134217728;
type PendingConsolidationsLimit = U262144;
type MaxConsolidations = U1;
type MaxDepositReceiptsPerPayload = U8192;
type MaxDepositRequestsPerPayload = U8192;
type MaxAttesterSlashingsElectra = U1;
type MaxAttestationsElectra = U8;
type MaxWithdrawalRequestsPerPayload = U16;
@@ -442,7 +442,7 @@ impl EthSpec for MinimalEthSpec {
type KzgCommitmentInclusionProofDepth = U9;
type PendingPartialWithdrawalsLimit = U64;
type PendingConsolidationsLimit = U64;
type MaxDepositReceiptsPerPayload = U4;
type MaxDepositRequestsPerPayload = U4;
type MaxWithdrawalRequestsPerPayload = U2;
params_from_eth_spec!(MainnetEthSpec {
@@ -528,7 +528,7 @@ impl EthSpec for GnosisEthSpec {
type PendingPartialWithdrawalsLimit = U134217728;
type PendingConsolidationsLimit = U262144;
type MaxConsolidations = U1;
type MaxDepositReceiptsPerPayload = U8192;
type MaxDepositRequestsPerPayload = U8192;
type MaxAttesterSlashingsElectra = U1;
type MaxAttestationsElectra = U8;
type MaxWithdrawalRequestsPerPayload = U16;

View File

@@ -13,8 +13,8 @@ pub type Transactions<E> = VariableList<
>;
pub type Withdrawals<E> = VariableList<Withdrawal, <E as EthSpec>::MaxWithdrawalsPerPayload>;
pub type DepositReceipts<E> =
VariableList<DepositReceipt, <E as EthSpec>::MaxDepositReceiptsPerPayload>;
pub type DepositRequests<E> =
VariableList<DepositRequest, <E as EthSpec>::MaxDepositRequestsPerPayload>;
pub type WithdrawalRequests<E> =
VariableList<ExecutionLayerWithdrawalRequest, <E as EthSpec>::MaxWithdrawalRequestsPerPayload>;
@@ -94,7 +94,7 @@ pub struct ExecutionPayload<E: EthSpec> {
#[serde(with = "serde_utils::quoted_u64")]
pub excess_blob_gas: u64,
#[superstruct(only(Electra))]
pub deposit_receipts: VariableList<DepositReceipt, E::MaxDepositReceiptsPerPayload>,
pub deposit_requests: VariableList<DepositRequest, E::MaxDepositRequestsPerPayload>,
#[superstruct(only(Electra))]
pub withdrawal_requests:
VariableList<ExecutionLayerWithdrawalRequest, E::MaxWithdrawalRequestsPerPayload>,

View File

@@ -295,7 +295,7 @@ impl<'a, E: EthSpec> From<&'a ExecutionPayloadElectra<E>> for ExecutionPayloadHe
withdrawals_root: payload.withdrawals.tree_hash_root(),
blob_gas_used: payload.blob_gas_used,
excess_blob_gas: payload.excess_blob_gas,
deposit_receipts_root: payload.deposit_receipts.tree_hash_root(),
deposit_receipts_root: payload.deposit_requests.tree_hash_root(),
withdrawal_requests_root: payload.withdrawal_requests.tree_hash_root(),
}
}

View File

@@ -1,14 +1,10 @@
use crate::test_utils::TestRandom;
use crate::Unsigned;
use crate::{BeaconState, EthSpec, Hash256};
use cached_tree_hash::Error;
use cached_tree_hash::{int_log, CacheArena, CachedTreeHash, TreeHashCache};
use compare_fields_derive::CompareFields;
use serde::{Deserialize, Serialize};
use ssz_derive::{Decode, Encode};
use ssz_types::VariableList;
use test_random_derive::TestRandom;
use tree_hash::{mix_in_length, TreeHash, BYTES_PER_CHUNK};
use tree_hash::TreeHash;
use tree_hash_derive::TreeHash;
/// `HistoricalSummary` matches the components of the phase0 `HistoricalBatch`
@@ -44,46 +40,3 @@ impl HistoricalSummary {
}
}
}
/// Wrapper type allowing the implementation of `CachedTreeHash`.
#[derive(Debug)]
pub struct HistoricalSummaryCache<'a, N: Unsigned> {
pub inner: &'a VariableList<HistoricalSummary, N>,
}
impl<'a, N: Unsigned> HistoricalSummaryCache<'a, N> {
pub fn new(inner: &'a VariableList<HistoricalSummary, N>) -> Self {
Self { inner }
}
#[allow(clippy::len_without_is_empty)]
pub fn len(&self) -> usize {
self.inner.len()
}
}
impl<'a, N: Unsigned> CachedTreeHash<TreeHashCache> for HistoricalSummaryCache<'a, N> {
fn new_tree_hash_cache(&self, arena: &mut CacheArena) -> TreeHashCache {
TreeHashCache::new(arena, int_log(N::to_usize()), self.len())
}
fn recalculate_tree_hash_root(
&self,
arena: &mut CacheArena,
cache: &mut TreeHashCache,
) -> Result<Hash256, Error> {
Ok(mix_in_length(
&cache.recalculate_merkle_root(arena, leaf_iter(self.inner))?,
self.len(),
))
}
}
pub fn leaf_iter(
values: &[HistoricalSummary],
) -> impl ExactSizeIterator<Item = [u8; BYTES_PER_CHUNK]> + '_ {
values
.iter()
.map(|value| value.tree_hash_root())
.map(Hash256::to_fixed_bytes)
}

View File

@@ -53,10 +53,10 @@ use tree_hash_derive::TreeHash;
pub struct IndexedAttestation<E: EthSpec> {
/// Lists validator registry indices, not committee indices.
#[superstruct(only(Base), partial_getter(rename = "attesting_indices_base"))]
#[serde(with = "quoted_variable_list_u64")]
#[serde(with = "ssz_types::serde_utils::quoted_u64_var_list")]
pub attesting_indices: VariableList<u64, E::MaxValidatorsPerCommittee>,
#[superstruct(only(Electra), partial_getter(rename = "attesting_indices_electra"))]
#[serde(with = "quoted_variable_list_u64")]
#[serde(with = "ssz_types::serde_utils::quoted_u64_var_list")]
pub attesting_indices: VariableList<u64, E::MaxValidatorsPerSlot>,
pub data: AttestationData,
pub signature: AggregateSignature,
@@ -203,43 +203,6 @@ impl<E: EthSpec> Hash for IndexedAttestation<E> {
}
}
/// Serialize a variable list of `u64` such that each int is quoted. Deserialize a variable
/// list supporting both quoted and un-quoted ints.
///
/// E.g.,`["0", "1", "2"]`
mod quoted_variable_list_u64 {
use super::*;
use crate::Unsigned;
use serde::ser::SerializeSeq;
use serde::{Deserializer, Serializer};
use serde_utils::quoted_u64_vec::{QuotedIntVecVisitor, QuotedIntWrapper};
pub fn serialize<S, T>(value: &VariableList<u64, T>, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
T: Unsigned,
{
let mut seq = serializer.serialize_seq(Some(value.len()))?;
for &int in value.iter() {
seq.serialize_element(&QuotedIntWrapper { int })?;
}
seq.end()
}
pub fn deserialize<'de, D, T>(deserializer: D) -> Result<VariableList<u64, T>, D::Error>
where
D: Deserializer<'de>,
T: Unsigned,
{
deserializer
.deserialize_any(QuotedIntVecVisitor)
.and_then(|vec| {
VariableList::new(vec)
.map_err(|e| serde::de::Error::custom(format!("invalid length: {:?}", e)))
})
}
}
#[cfg(test)]
mod tests {
use super::*;

View File

@@ -84,7 +84,6 @@ pub mod config_and_preset;
pub mod execution_block_header;
pub mod fork_context;
pub mod participation_flags;
pub mod participation_list;
pub mod payload;
pub mod preset;
pub mod slot_epoch;
@@ -150,7 +149,7 @@ pub use crate::contribution_and_proof::ContributionAndProof;
pub use crate::deposit::{Deposit, DEPOSIT_TREE_DEPTH};
pub use crate::deposit_data::DepositData;
pub use crate::deposit_message::DepositMessage;
pub use crate::deposit_receipt::DepositReceipt;
pub use crate::deposit_receipt::DepositRequest;
pub use crate::deposit_tree_snapshot::{DepositTreeSnapshot, FinalizedExecutionBlock};
pub use crate::enr_fork_id::EnrForkId;
pub use crate::epoch_cache::{EpochCache, EpochCacheError, EpochCacheKey};
@@ -200,7 +199,6 @@ pub use crate::light_client_update::{
LightClientUpdateCapella, LightClientUpdateDeneb, LightClientUpdateElectra,
};
pub use crate::participation_flags::ParticipationFlags;
pub use crate::participation_list::ParticipationList;
pub use crate::payload::{
AbstractExecPayload, BlindedPayload, BlindedPayloadBellatrix, BlindedPayloadCapella,
BlindedPayloadDeneb, BlindedPayloadElectra, BlindedPayloadRef, BlockType, ExecPayload,

View File

@@ -1,55 +0,0 @@
#![allow(clippy::arithmetic_side_effects)]
use crate::{Hash256, ParticipationFlags, Unsigned, VariableList};
use cached_tree_hash::{int_log, CacheArena, CachedTreeHash, Error, TreeHashCache};
use tree_hash::{mix_in_length, BYTES_PER_CHUNK};
/// Wrapper type allowing the implementation of `CachedTreeHash`.
#[derive(Debug)]
pub struct ParticipationList<'a, N: Unsigned> {
pub inner: &'a VariableList<ParticipationFlags, N>,
}
impl<'a, N: Unsigned> ParticipationList<'a, N> {
pub fn new(inner: &'a VariableList<ParticipationFlags, N>) -> Self {
Self { inner }
}
}
impl<'a, N: Unsigned> CachedTreeHash<TreeHashCache> for ParticipationList<'a, N> {
fn new_tree_hash_cache(&self, arena: &mut CacheArena) -> TreeHashCache {
TreeHashCache::new(
arena,
int_log(N::to_usize() / BYTES_PER_CHUNK),
leaf_count(self.inner.len()),
)
}
fn recalculate_tree_hash_root(
&self,
arena: &mut CacheArena,
cache: &mut TreeHashCache,
) -> Result<Hash256, Error> {
Ok(mix_in_length(
&cache.recalculate_merkle_root(arena, leaf_iter(self.inner))?,
self.inner.len(),
))
}
}
pub fn leaf_count(len: usize) -> usize {
(len + BYTES_PER_CHUNK - 1) / BYTES_PER_CHUNK
}
pub fn leaf_iter(
values: &[ParticipationFlags],
) -> impl ExactSizeIterator<Item = [u8; BYTES_PER_CHUNK]> + '_ {
values.chunks(BYTES_PER_CHUNK).map(|xs| {
// Zero-pad chunks on the right.
let mut chunk = [0u8; BYTES_PER_CHUNK];
for (byte, x) in chunk.iter_mut().zip(xs) {
*byte = x.into_u8();
}
chunk
})
}

View File

@@ -45,9 +45,9 @@ pub trait ExecPayload<E: EthSpec>: Debug + Clone + PartialEq + Hash + TreeHash +
Option<VariableList<ExecutionLayerWithdrawalRequest, E::MaxWithdrawalRequestsPerPayload>>,
Error,
>;
fn deposit_receipts(
fn deposit_requests(
&self,
) -> Result<Option<VariableList<DepositReceipt, E::MaxDepositReceiptsPerPayload>>, Error>;
) -> Result<Option<VariableList<DepositRequest, E::MaxDepositRequestsPerPayload>>, Error>;
/// Is this a default payload with 0x0 roots for transactions and withdrawals?
fn is_default_with_zero_roots(&self) -> bool;
@@ -303,15 +303,15 @@ impl<E: EthSpec> ExecPayload<E> for FullPayload<E> {
}
}
fn deposit_receipts(
fn deposit_requests(
&self,
) -> Result<Option<VariableList<DepositReceipt, E::MaxDepositReceiptsPerPayload>>, Error> {
) -> Result<Option<VariableList<DepositRequest, E::MaxDepositRequestsPerPayload>>, Error> {
match self {
FullPayload::Bellatrix(_) | FullPayload::Capella(_) | FullPayload::Deneb(_) => {
Err(Error::IncorrectStateVariant)
}
FullPayload::Electra(inner) => {
Ok(Some(inner.execution_payload.deposit_receipts.clone()))
Ok(Some(inner.execution_payload.deposit_requests.clone()))
}
}
}
@@ -464,15 +464,15 @@ impl<'b, E: EthSpec> ExecPayload<E> for FullPayloadRef<'b, E> {
}
}
fn deposit_receipts(
fn deposit_requests(
&self,
) -> Result<Option<VariableList<DepositReceipt, E::MaxDepositReceiptsPerPayload>>, Error> {
) -> Result<Option<VariableList<DepositRequest, E::MaxDepositRequestsPerPayload>>, Error> {
match self {
FullPayloadRef::Bellatrix(_)
| FullPayloadRef::Capella(_)
| FullPayloadRef::Deneb(_) => Err(Error::IncorrectStateVariant),
FullPayloadRef::Electra(inner) => {
Ok(Some(inner.execution_payload.deposit_receipts.clone()))
Ok(Some(inner.execution_payload.deposit_requests.clone()))
}
}
}
@@ -666,9 +666,9 @@ impl<E: EthSpec> ExecPayload<E> for BlindedPayload<E> {
Ok(None)
}
fn deposit_receipts(
fn deposit_requests(
&self,
) -> Result<Option<VariableList<DepositReceipt, E::MaxDepositReceiptsPerPayload>>, Error> {
) -> Result<Option<VariableList<DepositRequest, E::MaxDepositRequestsPerPayload>>, Error> {
Ok(None)
}
@@ -782,9 +782,9 @@ impl<'b, E: EthSpec> ExecPayload<E> for BlindedPayloadRef<'b, E> {
Ok(None)
}
fn deposit_receipts(
fn deposit_requests(
&self,
) -> Result<Option<VariableList<DepositReceipt, E::MaxDepositReceiptsPerPayload>>, Error> {
) -> Result<Option<VariableList<DepositRequest, E::MaxDepositRequestsPerPayload>>, Error> {
Ok(None)
}
@@ -890,9 +890,9 @@ macro_rules! impl_exec_payload_common {
i(self)
}
fn deposit_receipts(
fn deposit_requests(
&self,
) -> Result<Option<VariableList<DepositReceipt, E::MaxDepositReceiptsPerPayload>>, Error> {
) -> Result<Option<VariableList<DepositRequest, E::MaxDepositRequestsPerPayload>>, Error> {
let j = $j;
j(self)
}
@@ -1052,11 +1052,11 @@ macro_rules! impl_exec_payload_for_fork {
let c: for<'a> fn(
&'a $wrapper_type_full<E>,
) -> Result<
Option<VariableList<DepositReceipt, E::MaxDepositReceiptsPerPayload>>,
Option<VariableList<DepositRequest, E::MaxDepositRequestsPerPayload>>,
Error,
> = |payload: &$wrapper_type_full<E>| {
let wrapper_ref_type = FullPayloadRef::$fork_variant(&payload);
wrapper_ref_type.deposit_receipts()
wrapper_ref_type.deposit_requests()
};
c
}

View File

@@ -248,7 +248,7 @@ pub struct ElectraPreset {
#[serde(with = "serde_utils::quoted_u64")]
pub max_consolidations: u64,
#[serde(with = "serde_utils::quoted_u64")]
pub max_deposit_receipts_per_payload: u64,
pub max_deposit_requests_per_payload: u64,
#[serde(with = "serde_utils::quoted_u64")]
pub max_attester_slashings_electra: u64,
#[serde(with = "serde_utils::quoted_u64")]
@@ -270,7 +270,7 @@ impl ElectraPreset {
pending_partial_withdrawals_limit: E::pending_partial_withdrawals_limit() as u64,
pending_consolidations_limit: E::pending_consolidations_limit() as u64,
max_consolidations: E::max_consolidations() as u64,
max_deposit_receipts_per_payload: E::max_deposit_receipts_per_payload() as u64,
max_deposit_requests_per_payload: E::max_deposit_requests_per_payload() as u64,
max_attester_slashings_electra: E::max_attester_slashings_electra() as u64,
max_attestations_electra: E::max_attestations_electra() as u64,
max_withdrawal_requests_per_payload: E::max_withdrawal_requests_per_payload() as u64,

View File

@@ -2,6 +2,7 @@ use crate::*;
use rand::RngCore;
use rand::SeedableRng;
use rand_xorshift::XorShiftRng;
use smallvec::{smallvec, SmallVec};
use std::marker::PhantomData;
use std::sync::Arc;
@@ -118,6 +119,21 @@ where
}
}
impl<U, const N: usize> TestRandom for SmallVec<[U; N]>
where
U: TestRandom,
{
fn random_for_test(rng: &mut impl RngCore) -> Self {
let mut output = smallvec![];
for _ in 0..(usize::random_for_test(rng) % 4) {
output.push(<U>::random_for_test(rng));
}
output
}
}
macro_rules! impl_test_random_for_u8_array {
($len: expr) => {
impl TestRandom for [u8; $len] {