Bump SSZ version for larger bitfield SmallVec (#6915)

NA


  Bumps the `ethereum_ssz` version, along with other crates that share the dep.

Primarily, this give us bitfields which can store 128 bytes on the stack before allocating, rather than 32 bytes (https://github.com/sigp/ethereum_ssz/pull/38). The validator count has increase massively since we set it at 32 bytes, so aggregation bitfields (et al) now require a heap allocation. This new value of 128 should get us to ~2m active validators.
This commit is contained in:
Paul Hauner
2025-03-10 19:18:33 +11:00
committed by GitHub
parent b4e79edf2a
commit 8d1abce26e
13 changed files with 192 additions and 62 deletions

66
Cargo.lock generated
View File

@@ -2244,6 +2244,18 @@ dependencies = [
"zeroize",
]
[[package]]
name = "educe"
version = "0.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1d7bc049e1bd8cdeb31b68bbd586a9464ecf9f3944af3958a7a9d0f8b9799417"
dependencies = [
"enum-ordinalize",
"proc-macro2",
"quote",
"syn 2.0.98",
]
[[package]]
name = "ef_tests"
version = "0.2.0"
@@ -2361,6 +2373,26 @@ dependencies = [
"syn 2.0.98",
]
[[package]]
name = "enum-ordinalize"
version = "4.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fea0dcfa4e54eeb516fe454635a95753ddd39acda650ce703031c6973e315dd5"
dependencies = [
"enum-ordinalize-derive",
]
[[package]]
name = "enum-ordinalize-derive"
version = "4.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0d28318a75d4aead5c4db25382e8ef717932d0346600cacae6357eb5941bc5ff"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.98",
]
[[package]]
name = "env_logger"
version = "0.8.4"
@@ -2721,20 +2753,25 @@ dependencies = [
[[package]]
name = "ethereum_ssz"
version = "0.7.1"
version = "0.8.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1e999563461faea0ab9bc0024e5e66adcee35881f3d5062f52f31a4070fe1522"
checksum = "86da3096d1304f5f28476ce383005385459afeaf0eea08592b65ddbc9b258d16"
dependencies = [
"alloy-primitives",
"arbitrary",
"ethereum_serde_utils",
"itertools 0.13.0",
"serde",
"serde_derive",
"smallvec",
"typenum",
]
[[package]]
name = "ethereum_ssz_derive"
version = "0.7.1"
version = "0.8.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f3deae99c8e74829a00ba7a92d49055732b3c1f093f2ccfa3cbc621679b6fa91"
checksum = "d832a5c38eba0e7ad92592f7a22d693954637fbb332b4f669590d66a5c3183e5"
dependencies = [
"darling 0.20.10",
"proc-macro2",
@@ -5597,13 +5634,13 @@ dependencies = [
[[package]]
name = "milhouse"
version = "0.3.0"
version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f68e33f98199224d1073f7c1468ea6abfea30736306fb79c7181a881e97ea32f"
checksum = "eb1ada1f56cc1c79f40517fdcbf57e19f60424a3a1ce372c3fe9b22e4fdd83eb"
dependencies = [
"alloy-primitives",
"arbitrary",
"derivative",
"educe",
"ethereum_hashing",
"ethereum_ssz",
"ethereum_ssz_derive",
@@ -8300,12 +8337,11 @@ dependencies = [
[[package]]
name = "ssz_types"
version = "0.8.0"
version = "0.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "35e0719d2b86ac738a55ae71a8429f52aa2741da988f1fd0975b4cc610fd1e08"
checksum = "22bc24c8a61256950632fb6b68ea09f6b5c988070924c6292eb5933635202e00"
dependencies = [
"arbitrary",
"derivative",
"ethereum_serde_utils",
"ethereum_ssz",
"itertools 0.13.0",
@@ -9116,20 +9152,22 @@ dependencies = [
[[package]]
name = "tree_hash"
version = "0.8.0"
version = "0.9.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "373495c23db675a5192de8b610395e1bec324d596f9e6111192ce903dc11403a"
checksum = "6c58eb0f518840670270d90d97ffee702d8662d9c5494870c9e1e9e0fa00f668"
dependencies = [
"alloy-primitives",
"ethereum_hashing",
"ethereum_ssz",
"smallvec",
"typenum",
]
[[package]]
name = "tree_hash_derive"
version = "0.8.0"
version = "0.9.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b0857056ca4eb5de8c417309be42bcff6017b47e86fbaddde609b4633f66061e"
checksum = "699e7fb6b3fdfe0c809916f251cf5132d64966858601695c3736630a87e7166a"
dependencies = [
"darling 0.20.10",
"proc-macro2",

View File

@@ -137,8 +137,8 @@ discv5 = { version = "0.9", features = ["libp2p"] }
env_logger = "0.9"
ethereum_hashing = "0.7.0"
ethereum_serde_utils = "0.7"
ethereum_ssz = "0.7"
ethereum_ssz_derive = "0.7"
ethereum_ssz = "0.8.2"
ethereum_ssz_derive = "0.8.2"
ethers-core = "1"
ethers-providers = { version = "1", default-features = false }
exit-future = "0.2"
@@ -154,7 +154,7 @@ libsecp256k1 = "0.7"
log = "0.4"
lru = "0.12"
maplit = "1"
milhouse = "0.3"
milhouse = "0.5"
mockito = "1.5.0"
num_cpus = "1"
parking_lot = "0.12"
@@ -192,7 +192,7 @@ slog-term = "2"
sloggers = { version = "2", features = ["json"] }
smallvec = { version = "1.11.2", features = ["arbitrary"] }
snap = "1"
ssz_types = "0.8"
ssz_types = "0.10"
strum = { version = "0.24", features = ["derive"] }
superstruct = "0.8"
syn = "1"
@@ -211,8 +211,8 @@ tracing-appender = "0.2"
tracing-core = "0.1"
tracing-log = "0.2"
tracing-subscriber = { version = "0.3", features = ["env-filter"] }
tree_hash = "0.8"
tree_hash_derive = "0.8"
tree_hash = "0.9"
tree_hash_derive = "0.9"
url = "2"
uuid = { version = "0.8", features = ["serde", "v4"] }
warp = { version = "0.3.7", default-features = false, features = ["tls"] }

View File

@@ -2713,16 +2713,16 @@ where
let mut block_hash_from_slot: HashMap<Slot, SignedBeaconBlockHash> = HashMap::new();
let mut state_hash_from_slot: HashMap<Slot, BeaconStateHash> = HashMap::new();
for slot in slots {
let (block_hash, new_state) = self
.add_attested_block_at_slot_with_sync(
*slot,
state,
state_root,
validators,
sync_committee_strategy,
)
.await
.unwrap();
// Using a `Box::pin` to reduce the stack size. Clippy was raising a lints.
let (block_hash, new_state) = Box::pin(self.add_attested_block_at_slot_with_sync(
*slot,
state,
state_root,
validators,
sync_committee_strategy,
))
.await
.unwrap();
state = new_state;

View File

@@ -328,8 +328,7 @@ async fn test_rewards_base_multi_inclusion() {
.extend_slots(E::slots_per_epoch() as usize * 2 - 4)
.await;
// pin to reduce stack size for clippy
Box::pin(check_all_base_rewards(&harness, initial_balances)).await;
check_all_base_rewards(&harness, initial_balances).await;
}
#[tokio::test]
@@ -692,7 +691,8 @@ async fn check_all_base_rewards(
harness: &BeaconChainHarness<EphemeralHarnessType<E>>,
balances: Vec<u64>,
) {
check_all_base_rewards_for_subset(harness, balances, vec![]).await;
// The box reduces the size on the stack for a clippy lint.
Box::pin(check_all_base_rewards_for_subset(harness, balances, vec![])).await;
}
async fn check_all_base_rewards_for_subset(

View File

@@ -765,8 +765,8 @@ fn handle_rpc_response<E: EthSpec>(
SupportedProtocol::PingV1 => Ok(Some(RpcSuccessResponse::Pong(Ping {
data: u64::from_ssz_bytes(decoded_buffer)?,
}))),
SupportedProtocol::MetaDataV1 => Ok(Some(RpcSuccessResponse::MetaData(MetaData::V1(
MetaDataV1::from_ssz_bytes(decoded_buffer)?,
SupportedProtocol::MetaDataV1 => Ok(Some(RpcSuccessResponse::MetaData(Arc::new(
MetaData::V1(MetaDataV1::from_ssz_bytes(decoded_buffer)?),
)))),
SupportedProtocol::LightClientBootstrapV1 => match fork_name {
Some(fork_name) => Ok(Some(RpcSuccessResponse::LightClientBootstrap(Arc::new(
@@ -826,11 +826,11 @@ fn handle_rpc_response<E: EthSpec>(
)),
},
// MetaData V2/V3 responses have no context bytes, so behave similarly to V1 responses
SupportedProtocol::MetaDataV3 => Ok(Some(RpcSuccessResponse::MetaData(MetaData::V3(
MetaDataV3::from_ssz_bytes(decoded_buffer)?,
SupportedProtocol::MetaDataV3 => Ok(Some(RpcSuccessResponse::MetaData(Arc::new(
MetaData::V3(MetaDataV3::from_ssz_bytes(decoded_buffer)?),
)))),
SupportedProtocol::MetaDataV2 => Ok(Some(RpcSuccessResponse::MetaData(MetaData::V2(
MetaDataV2::from_ssz_bytes(decoded_buffer)?,
SupportedProtocol::MetaDataV2 => Ok(Some(RpcSuccessResponse::MetaData(Arc::new(
MetaData::V2(MetaDataV2::from_ssz_bytes(decoded_buffer)?),
)))),
SupportedProtocol::BlocksByRangeV2 => match fork_name {
Some(ForkName::Altair) => Ok(Some(RpcSuccessResponse::BlocksByRange(Arc::new(
@@ -1008,6 +1008,7 @@ mod tests {
) -> SignedBeaconBlock<Spec> {
let mut block: BeaconBlockBellatrix<_, FullPayload<Spec>> =
BeaconBlockBellatrix::empty(&Spec::default_spec());
let tx = VariableList::from(vec![0; 1024]);
let txs = VariableList::from(std::iter::repeat(tx).take(5000).collect::<Vec<_>>());
@@ -1027,6 +1028,7 @@ mod tests {
) -> SignedBeaconBlock<Spec> {
let mut block: BeaconBlockBellatrix<_, FullPayload<Spec>> =
BeaconBlockBellatrix::empty(&Spec::default_spec());
let tx = VariableList::from(vec![0; 1024]);
let txs = VariableList::from(std::iter::repeat(tx).take(100000).collect::<Vec<_>>());
@@ -1105,28 +1107,31 @@ mod tests {
Ping { data: 1 }
}
fn metadata() -> MetaData<Spec> {
fn metadata() -> Arc<MetaData<Spec>> {
MetaData::V1(MetaDataV1 {
seq_number: 1,
attnets: EnrAttestationBitfield::<Spec>::default(),
})
.into()
}
fn metadata_v2() -> MetaData<Spec> {
fn metadata_v2() -> Arc<MetaData<Spec>> {
MetaData::V2(MetaDataV2 {
seq_number: 1,
attnets: EnrAttestationBitfield::<Spec>::default(),
syncnets: EnrSyncCommitteeBitfield::<Spec>::default(),
})
.into()
}
fn metadata_v3() -> MetaData<Spec> {
fn metadata_v3() -> Arc<MetaData<Spec>> {
MetaData::V3(MetaDataV3 {
seq_number: 1,
attnets: EnrAttestationBitfield::<Spec>::default(),
syncnets: EnrSyncCommitteeBitfield::<Spec>::default(),
custody_group_count: 1,
})
.into()
}
/// Encodes the given protocol response as bytes.

View File

@@ -578,7 +578,7 @@ pub enum RpcSuccessResponse<E: EthSpec> {
Pong(Ping),
/// A response to a META_DATA request.
MetaData(MetaData<E>),
MetaData(Arc<MetaData<E>>),
}
/// Indicates which response is being terminated by a stream termination response.

View File

@@ -1190,7 +1190,7 @@ impl<E: EthSpec> Network<E> {
) {
let metadata = self.network_globals.local_metadata.read().clone();
// The encoder is responsible for sending the negotiated version of the metadata
let event = RpcResponse::Success(RpcSuccessResponse::MetaData(metadata));
let event = RpcResponse::Success(RpcSuccessResponse::MetaData(Arc::new(metadata)));
self.eth2_rpc_mut()
.send_response(peer_id, id, request_id, event);
}
@@ -1605,7 +1605,7 @@ impl<E: EthSpec> Network<E> {
}
RpcSuccessResponse::MetaData(meta_data) => {
self.peer_manager_mut()
.meta_data_response(&peer_id, meta_data);
.meta_data_response(&peer_id, meta_data.as_ref().clone());
None
}
/* Network propagated protocols */

View File

@@ -7,9 +7,11 @@
//!
//! A) `JEMALLOC_SYS_WITH_MALLOC_CONF` at compile-time.
//! B) `_RJEM_MALLOC_CONF` at runtime.
use metrics::{set_gauge, try_create_int_gauge, IntGauge};
use metrics::{
set_gauge, set_gauge_vec, try_create_int_gauge, try_create_int_gauge_vec, IntGauge, IntGaugeVec,
};
use std::sync::LazyLock;
use tikv_jemalloc_ctl::{arenas, epoch, stats, Access, AsName, Error};
use tikv_jemalloc_ctl::{arenas, epoch, raw, stats, Access, AsName, Error};
#[global_allocator]
static ALLOC: tikv_jemallocator::Jemalloc = tikv_jemallocator::Jemalloc;
@@ -33,6 +35,38 @@ pub static BYTES_RESIDENT: LazyLock<metrics::Result<IntGauge>> = LazyLock::new(|
pub static BYTES_RETAINED: LazyLock<metrics::Result<IntGauge>> = LazyLock::new(|| {
try_create_int_gauge("jemalloc_bytes_retained", "Equivalent to stats.retained")
});
pub static JEMALLOC_ARENAS_SMALL_NMALLOC: LazyLock<metrics::Result<IntGaugeVec>> =
LazyLock::new(|| {
try_create_int_gauge_vec(
"jemalloc_arenas_small_nmalloc",
"Equivalent to stats.arenas.<i>.small.nmalloc",
&["arena"],
)
});
pub static JEMALLOC_ARENAS_SMALL_NDALLOC: LazyLock<metrics::Result<IntGaugeVec>> =
LazyLock::new(|| {
try_create_int_gauge_vec(
"jemalloc_arenas_small_ndalloc",
"Equivalent to stats.arenas.<i>.small.ndalloc",
&["arena"],
)
});
pub static JEMALLOC_ARENAS_LARGE_NMALLOC: LazyLock<metrics::Result<IntGaugeVec>> =
LazyLock::new(|| {
try_create_int_gauge_vec(
"jemalloc_arenas_large_nmalloc",
"Equivalent to stats.arenas.<i>.large.nmalloc",
&["arena"],
)
});
pub static JEMALLOC_ARENAS_LARGE_NDALLOC: LazyLock<metrics::Result<IntGaugeVec>> =
LazyLock::new(|| {
try_create_int_gauge_vec(
"jemalloc_arenas_large_ndalloc",
"Equivalent to stats.arenas.<i>.large.ndalloc",
&["arena"],
)
});
pub fn scrape_jemalloc_metrics() {
scrape_jemalloc_metrics_fallible().unwrap()
@@ -42,7 +76,8 @@ pub fn scrape_jemalloc_metrics_fallible() -> Result<(), Error> {
// Advance the epoch so that the underlying statistics are updated.
epoch::advance()?;
set_gauge(&NUM_ARENAS, arenas::narenas::read()? as i64);
let num_arenas = arenas::narenas::read()?;
set_gauge(&NUM_ARENAS, num_arenas as i64);
set_gauge(&BYTES_ALLOCATED, stats::allocated::read()? as i64);
set_gauge(&BYTES_ACTIVE, stats::active::read()? as i64);
set_gauge(&BYTES_MAPPED, stats::mapped::read()? as i64);
@@ -50,9 +85,40 @@ pub fn scrape_jemalloc_metrics_fallible() -> Result<(), Error> {
set_gauge(&BYTES_RESIDENT, stats::resident::read()? as i64);
set_gauge(&BYTES_RETAINED, stats::retained::read()? as i64);
for arena in 0..num_arenas {
unsafe {
set_stats_gauge(
&JEMALLOC_ARENAS_SMALL_NMALLOC,
arena,
&format!("stats.arenas.{arena}.small.nmalloc\0"),
);
set_stats_gauge(
&JEMALLOC_ARENAS_SMALL_NDALLOC,
arena,
&format!("stats.arenas.{arena}.small.ndalloc\0"),
);
set_stats_gauge(
&JEMALLOC_ARENAS_LARGE_NMALLOC,
arena,
&format!("stats.arenas.{arena}.large.nmalloc\0"),
);
set_stats_gauge(
&JEMALLOC_ARENAS_LARGE_NDALLOC,
arena,
&format!("stats.arenas.{arena}.large.ndalloc\0"),
);
}
}
Ok(())
}
unsafe fn set_stats_gauge(metric: &metrics::Result<IntGaugeVec>, arena: u32, stat: &str) {
if let Ok(val) = raw::read::<usize>(stat.as_bytes()) {
set_gauge_vec(metric, &[&format!("arena_{arena}")], val as i64);
}
}
pub fn page_size() -> Result<usize, Error> {
// Full list of keys: https://jemalloc.net/jemalloc.3.html
"arenas.page\0".name().read()

View File

@@ -60,6 +60,7 @@ pub enum BlockProcessingError {
SignatureSetError(SignatureSetError),
SszTypesError(ssz_types::Error),
SszDecodeError(DecodeError),
BitfieldError(ssz::BitfieldError),
MerkleTreeError(MerkleTreeError),
ArithError(ArithError),
InconsistentBlockFork(InconsistentFork),
@@ -153,6 +154,7 @@ impl From<BlockOperationError<HeaderInvalid>> for BlockProcessingError {
BlockOperationError::BeaconStateError(e) => BlockProcessingError::BeaconStateError(e),
BlockOperationError::SignatureSetError(e) => BlockProcessingError::SignatureSetError(e),
BlockOperationError::SszTypesError(e) => BlockProcessingError::SszTypesError(e),
BlockOperationError::BitfieldError(e) => BlockProcessingError::BitfieldError(e),
BlockOperationError::ConsensusContext(e) => BlockProcessingError::ConsensusContext(e),
BlockOperationError::ArithError(e) => BlockProcessingError::ArithError(e),
}
@@ -181,6 +183,7 @@ macro_rules! impl_into_block_processing_error_with_index {
BlockOperationError::BeaconStateError(e) => BlockProcessingError::BeaconStateError(e),
BlockOperationError::SignatureSetError(e) => BlockProcessingError::SignatureSetError(e),
BlockOperationError::SszTypesError(e) => BlockProcessingError::SszTypesError(e),
BlockOperationError::BitfieldError(e) => BlockProcessingError::BitfieldError(e),
BlockOperationError::ConsensusContext(e) => BlockProcessingError::ConsensusContext(e),
BlockOperationError::ArithError(e) => BlockProcessingError::ArithError(e),
}
@@ -215,6 +218,7 @@ pub enum BlockOperationError<T> {
BeaconStateError(BeaconStateError),
SignatureSetError(SignatureSetError),
SszTypesError(ssz_types::Error),
BitfieldError(ssz::BitfieldError),
ConsensusContext(ContextError),
ArithError(ArithError),
}
@@ -242,6 +246,12 @@ impl<T> From<ssz_types::Error> for BlockOperationError<T> {
}
}
impl<T> From<ssz::BitfieldError> for BlockOperationError<T> {
fn from(error: ssz::BitfieldError) -> Self {
BlockOperationError::BitfieldError(error)
}
}
impl<T> From<ArithError> for BlockOperationError<T> {
fn from(e: ArithError) -> Self {
BlockOperationError::ArithError(e)
@@ -367,6 +377,7 @@ impl From<BlockOperationError<IndexedAttestationInvalid>>
BlockOperationError::BeaconStateError(e) => BlockOperationError::BeaconStateError(e),
BlockOperationError::SignatureSetError(e) => BlockOperationError::SignatureSetError(e),
BlockOperationError::SszTypesError(e) => BlockOperationError::SszTypesError(e),
BlockOperationError::BitfieldError(e) => BlockOperationError::BitfieldError(e),
BlockOperationError::ConsensusContext(e) => BlockOperationError::ConsensusContext(e),
BlockOperationError::ArithError(e) => BlockOperationError::ArithError(e),
}

View File

@@ -19,9 +19,10 @@ pub enum EpochProcessingError {
BeaconStateError(BeaconStateError),
InclusionError(InclusionError),
SszTypesError(ssz_types::Error),
BitfieldError(ssz::BitfieldError),
ArithError(safe_arith::ArithError),
InconsistentStateFork(InconsistentFork),
InvalidJustificationBit(ssz_types::Error),
InvalidJustificationBit(ssz::BitfieldError),
InvalidFlagIndex(usize),
MilhouseError(milhouse::Error),
EpochCache(EpochCacheError),
@@ -49,6 +50,12 @@ impl From<ssz_types::Error> for EpochProcessingError {
}
}
impl From<ssz::BitfieldError> for EpochProcessingError {
fn from(e: ssz::BitfieldError) -> EpochProcessingError {
EpochProcessingError::BitfieldError(e)
}
}
impl From<safe_arith::ArithError> for EpochProcessingError {
fn from(e: safe_arith::ArithError) -> EpochProcessingError {
EpochProcessingError::ArithError(e)

View File

@@ -18,6 +18,7 @@ use super::{
#[derive(Debug, PartialEq)]
pub enum Error {
SszTypesError(ssz_types::Error),
BitfieldError(ssz::BitfieldError),
AlreadySigned(usize),
IncorrectStateVariant,
InvalidCommitteeLength,
@@ -223,7 +224,7 @@ impl<E: EthSpec> Attestation<E> {
}
}
pub fn get_aggregation_bit(&self, index: usize) -> Result<bool, ssz_types::Error> {
pub fn get_aggregation_bit(&self, index: usize) -> Result<bool, ssz::BitfieldError> {
match self {
Attestation::Base(att) => att.aggregation_bits.get(index),
Attestation::Electra(att) => att.aggregation_bits.get(index),
@@ -353,13 +354,13 @@ impl<E: EthSpec> AttestationElectra<E> {
if self
.aggregation_bits
.get(committee_position)
.map_err(Error::SszTypesError)?
.map_err(Error::BitfieldError)?
{
Err(Error::AlreadySigned(committee_position))
} else {
self.aggregation_bits
.set(committee_position, true)
.map_err(Error::SszTypesError)?;
.map_err(Error::BitfieldError)?;
self.signature.add_assign(signature);
@@ -427,13 +428,13 @@ impl<E: EthSpec> AttestationBase<E> {
if self
.aggregation_bits
.get(committee_position)
.map_err(Error::SszTypesError)?
.map_err(Error::BitfieldError)?
{
Err(Error::AlreadySigned(committee_position))
} else {
self.aggregation_bits
.set(committee_position, true)
.map_err(Error::SszTypesError)?;
.map_err(Error::BitfieldError)?;
self.signature.add_assign(signature);
@@ -443,7 +444,7 @@ impl<E: EthSpec> AttestationBase<E> {
pub fn extend_aggregation_bits(
&self,
) -> Result<BitList<E::MaxValidatorsPerSlot>, ssz_types::Error> {
) -> Result<BitList<E::MaxValidatorsPerSlot>, ssz::BitfieldError> {
self.aggregation_bits.resize::<E::MaxValidatorsPerSlot>()
}
}
@@ -600,12 +601,12 @@ mod tests {
let attestation_data = size_of::<AttestationData>();
let signature = size_of::<AggregateSignature>();
assert_eq!(aggregation_bits, 56);
assert_eq!(aggregation_bits, 152);
assert_eq!(attestation_data, 128);
assert_eq!(signature, 288 + 16);
let attestation_expected = aggregation_bits + attestation_data + signature;
assert_eq!(attestation_expected, 488);
assert_eq!(attestation_expected, 584);
assert_eq!(
size_of::<AttestationBase<MainnetEthSpec>>(),
attestation_expected
@@ -623,13 +624,13 @@ mod tests {
size_of::<BitList<<MainnetEthSpec as EthSpec>::MaxCommitteesPerSlot>>();
let signature = size_of::<AggregateSignature>();
assert_eq!(aggregation_bits, 56);
assert_eq!(committee_bits, 56);
assert_eq!(aggregation_bits, 152);
assert_eq!(committee_bits, 152);
assert_eq!(attestation_data, 128);
assert_eq!(signature, 288 + 16);
let attestation_expected = aggregation_bits + committee_bits + attestation_data + signature;
assert_eq!(attestation_expected, 544);
assert_eq!(attestation_expected, 736);
assert_eq!(
size_of::<AttestationElectra<MainnetEthSpec>>(),
attestation_expected

View File

@@ -11,6 +11,7 @@ use tree_hash_derive::TreeHash;
#[derive(Debug, PartialEq)]
pub enum Error {
SszTypesError(ssz_types::Error),
BitfieldError(ssz::BitfieldError),
ArithError(ArithError),
}
@@ -68,7 +69,7 @@ impl<E: EthSpec> SyncAggregate<E> {
sync_aggregate
.sync_committee_bits
.set(participant_index, true)
.map_err(Error::SszTypesError)?;
.map_err(Error::BitfieldError)?;
}
}
sync_aggregate

View File

@@ -9,6 +9,7 @@ use tree_hash_derive::TreeHash;
#[derive(Debug, PartialEq)]
pub enum Error {
SszTypesError(ssz_types::Error),
BitfieldError(ssz::BitfieldError),
AlreadySigned(usize),
}
@@ -51,7 +52,7 @@ impl<E: EthSpec> SyncCommitteeContribution<E> {
) -> Result<Self, Error> {
let mut bits = BitVector::new();
bits.set(validator_sync_committee_index, true)
.map_err(Error::SszTypesError)?;
.map_err(Error::BitfieldError)?;
Ok(Self {
slot: message.slot,
beacon_block_root: message.beacon_block_root,