mirror of
https://github.com/sigp/lighthouse.git
synced 2026-04-29 02:33:48 +00:00
Fulu update to spec v1.6.0-alpha.4 (#7890)
Fulu update to spec [v1.6.0-alpha.4](https://github.com/ethereum/consensus-specs/releases/tag/v1.6.0-alpha.4). - Make `number_of_columns` a preset - Optimise `get_custody_groups` to avoid computing if cgc = 128 - Add support for additional typenum values in type_dispatch macro
This commit is contained in:
@@ -8,3 +8,7 @@ FIELD_ELEMENTS_PER_CELL: 64
|
||||
FIELD_ELEMENTS_PER_EXT_BLOB: 8192
|
||||
# uint64(floorlog2(get_generalized_index(BeaconBlockBody, 'blob_kzg_commitments'))
|
||||
KZG_COMMITMENTS_INCLUSION_PROOF_DEPTH: 4
|
||||
# FIELD_ELEMENTS_PER_EXT_BLOB // FIELD_ELEMENTS_PER_CELL (= 128)
|
||||
CELLS_PER_EXT_BLOB: 128
|
||||
# CELLS_PER_EXT_BLOB (= 128)
|
||||
NUMBER_OF_COLUMNS: 128
|
||||
@@ -8,3 +8,7 @@ FIELD_ELEMENTS_PER_CELL: 64
|
||||
FIELD_ELEMENTS_PER_EXT_BLOB: 8192
|
||||
# uint64(floorlog2(get_generalized_index(BeaconBlockBody, 'blob_kzg_commitments'))
|
||||
KZG_COMMITMENTS_INCLUSION_PROOF_DEPTH: 4
|
||||
# FIELD_ELEMENTS_PER_EXT_BLOB // FIELD_ELEMENTS_PER_CELL (= 128)
|
||||
CELLS_PER_EXT_BLOB: 128
|
||||
# CELLS_PER_EXT_BLOB (= 128)
|
||||
NUMBER_OF_COLUMNS: 128
|
||||
@@ -8,3 +8,7 @@ FIELD_ELEMENTS_PER_CELL: 64
|
||||
FIELD_ELEMENTS_PER_EXT_BLOB: 8192
|
||||
# uint64(floorlog2(get_generalized_index(BeaconBlockBody, 'blob_kzg_commitments'))
|
||||
KZG_COMMITMENTS_INCLUSION_PROOF_DEPTH: 4
|
||||
# FIELD_ELEMENTS_PER_EXT_BLOB // FIELD_ELEMENTS_PER_CELL (= 128)
|
||||
CELLS_PER_EXT_BLOB: 128
|
||||
# CELLS_PER_EXT_BLOB (= 128)
|
||||
NUMBER_OF_COLUMNS: 128
|
||||
@@ -1094,22 +1094,12 @@ mod tests {
|
||||
slot: fulu_slot,
|
||||
..<_>::random_for_test(rng)
|
||||
});
|
||||
// It's invalid to have a Fulu block with a epoch lower than the fork epoch.
|
||||
let _bad_block = {
|
||||
let mut bad = good_block.clone();
|
||||
*bad.slot_mut() = electra_slot;
|
||||
bad
|
||||
};
|
||||
|
||||
assert_eq!(
|
||||
BeaconBlock::from_ssz_bytes(&good_block.as_ssz_bytes(), &spec)
|
||||
.expect("good fulu block can be decoded"),
|
||||
good_block
|
||||
);
|
||||
// TODO(fulu): Uncomment once Fulu has features since without features
|
||||
// and with an Electra slot it decodes successfully to Electra.
|
||||
//BeaconBlock::from_ssz_bytes(&bad_block.as_ssz_bytes(), &spec)
|
||||
// .expect_err("bad fulu block cannot be decoded");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -201,7 +201,6 @@ pub struct ChainSpec {
|
||||
pub fulu_fork_version: [u8; 4],
|
||||
/// The Fulu fork epoch is optional, with `None` representing "Fulu never happens".
|
||||
pub fulu_fork_epoch: Option<Epoch>,
|
||||
pub number_of_columns: u64,
|
||||
pub number_of_custody_groups: u64,
|
||||
pub data_column_sidecar_subnet_count: u64,
|
||||
pub samples_per_slot: u64,
|
||||
@@ -773,20 +772,19 @@ impl ChainSpec {
|
||||
}
|
||||
|
||||
/// Returns the number of data columns per custody group.
|
||||
pub fn data_columns_per_group(&self) -> u64 {
|
||||
self.number_of_columns
|
||||
pub fn data_columns_per_group<E: EthSpec>(&self) -> u64 {
|
||||
(E::number_of_columns() as u64)
|
||||
.safe_div(self.number_of_custody_groups)
|
||||
.expect("Custody group count must be greater than 0")
|
||||
}
|
||||
|
||||
/// Returns the number of column sidecars to sample per slot.
|
||||
pub fn sampling_size_columns(&self, custody_group_count: u64) -> Result<usize, String> {
|
||||
pub fn sampling_size_columns<E: EthSpec>(
|
||||
&self,
|
||||
custody_group_count: u64,
|
||||
) -> Result<usize, String> {
|
||||
let sampling_size_groups = self.sampling_size_custody_groups(custody_group_count)?;
|
||||
|
||||
let columns_per_custody_group = self
|
||||
.number_of_columns
|
||||
.safe_div(self.number_of_custody_groups)
|
||||
.map_err(|_| "number_of_custody_groups must be greater than 0")?;
|
||||
let columns_per_custody_group = self.data_columns_per_group::<E>();
|
||||
|
||||
let sampling_size_columns = columns_per_custody_group
|
||||
.safe_mul(sampling_size_groups)
|
||||
@@ -1048,7 +1046,6 @@ impl ChainSpec {
|
||||
custody_requirement: 4,
|
||||
number_of_custody_groups: 128,
|
||||
data_column_sidecar_subnet_count: 128,
|
||||
number_of_columns: 128,
|
||||
samples_per_slot: 8,
|
||||
validator_custody_requirement: 8,
|
||||
balance_per_additional_custody_group: 32000000000,
|
||||
@@ -1088,7 +1085,6 @@ impl ChainSpec {
|
||||
max_blocks_by_root_request: default_max_blocks_by_root_request(),
|
||||
max_blocks_by_root_request_deneb: default_max_blocks_by_root_request_deneb(),
|
||||
max_blobs_by_root_request: default_max_blobs_by_root_request(),
|
||||
max_data_columns_by_root_request: default_data_columns_by_root_request(),
|
||||
|
||||
/*
|
||||
* Networking Electra specific
|
||||
@@ -1103,6 +1099,7 @@ impl ChainSpec {
|
||||
blob_schedule: BlobSchedule::default(),
|
||||
min_epochs_for_data_column_sidecars_requests:
|
||||
default_min_epochs_for_data_column_sidecars_requests(),
|
||||
max_data_columns_by_root_request: default_data_columns_by_root_request(),
|
||||
|
||||
/*
|
||||
* Application specific
|
||||
@@ -1386,7 +1383,6 @@ impl ChainSpec {
|
||||
custody_requirement: 4,
|
||||
number_of_custody_groups: 128,
|
||||
data_column_sidecar_subnet_count: 128,
|
||||
number_of_columns: 128,
|
||||
samples_per_slot: 8,
|
||||
validator_custody_requirement: 8,
|
||||
balance_per_additional_custody_group: 32000000000,
|
||||
@@ -1426,7 +1422,6 @@ impl ChainSpec {
|
||||
max_blocks_by_root_request: default_max_blocks_by_root_request(),
|
||||
max_blocks_by_root_request_deneb: default_max_blocks_by_root_request_deneb(),
|
||||
max_blobs_by_root_request: default_max_blobs_by_root_request(),
|
||||
max_data_columns_by_root_request: default_data_columns_by_root_request(),
|
||||
|
||||
/*
|
||||
* Networking Electra specific
|
||||
@@ -1441,6 +1436,7 @@ impl ChainSpec {
|
||||
blob_schedule: BlobSchedule::default(),
|
||||
min_epochs_for_data_column_sidecars_requests:
|
||||
default_min_epochs_for_data_column_sidecars_requests(),
|
||||
max_data_columns_by_root_request: default_data_columns_by_root_request(),
|
||||
|
||||
/*
|
||||
* Application specific
|
||||
@@ -1759,9 +1755,6 @@ pub struct Config {
|
||||
#[serde(with = "serde_utils::quoted_u64")]
|
||||
max_request_blob_sidecars_electra: u64,
|
||||
|
||||
#[serde(default = "default_number_of_columns")]
|
||||
#[serde(with = "serde_utils::quoted_u64")]
|
||||
number_of_columns: u64,
|
||||
#[serde(default = "default_number_of_custody_groups")]
|
||||
#[serde(with = "serde_utils::quoted_u64")]
|
||||
number_of_custody_groups: u64,
|
||||
@@ -1938,10 +1931,6 @@ const fn default_data_column_sidecar_subnet_count() -> u64 {
|
||||
128
|
||||
}
|
||||
|
||||
const fn default_number_of_columns() -> u64 {
|
||||
128
|
||||
}
|
||||
|
||||
const fn default_number_of_custody_groups() -> u64 {
|
||||
128
|
||||
}
|
||||
@@ -1987,19 +1976,15 @@ fn max_blobs_by_root_request_common(max_request_blob_sidecars: u64) -> usize {
|
||||
.len()
|
||||
}
|
||||
|
||||
fn max_data_columns_by_root_request_common(
|
||||
max_request_blocks: u64,
|
||||
number_of_columns: u64,
|
||||
) -> usize {
|
||||
fn max_data_columns_by_root_request_common<E: EthSpec>(max_request_blocks: u64) -> usize {
|
||||
let max_request_blocks = max_request_blocks as usize;
|
||||
let number_of_columns = number_of_columns as usize;
|
||||
|
||||
let empty_data_columns_by_root_id = DataColumnsByRootIdentifier {
|
||||
block_root: Hash256::zero(),
|
||||
columns: RuntimeVariableList::from_vec(vec![0; number_of_columns], number_of_columns),
|
||||
columns: VariableList::from(vec![0]),
|
||||
};
|
||||
|
||||
RuntimeVariableList::<DataColumnsByRootIdentifier>::from_vec(
|
||||
RuntimeVariableList::<DataColumnsByRootIdentifier<E>>::from_vec(
|
||||
vec![empty_data_columns_by_root_id; max_request_blocks],
|
||||
max_request_blocks,
|
||||
)
|
||||
@@ -2020,10 +2005,7 @@ fn default_max_blobs_by_root_request() -> usize {
|
||||
}
|
||||
|
||||
fn default_data_columns_by_root_request() -> usize {
|
||||
max_data_columns_by_root_request_common(
|
||||
default_max_request_blocks_deneb(),
|
||||
default_number_of_columns(),
|
||||
)
|
||||
max_data_columns_by_root_request_common::<MainnetEthSpec>(default_max_request_blocks_deneb())
|
||||
}
|
||||
|
||||
impl Default for Config {
|
||||
@@ -2165,7 +2147,6 @@ impl Config {
|
||||
blob_sidecar_subnet_count_electra: spec.blob_sidecar_subnet_count_electra,
|
||||
max_request_blob_sidecars_electra: spec.max_request_blob_sidecars_electra,
|
||||
|
||||
number_of_columns: spec.number_of_columns,
|
||||
number_of_custody_groups: spec.number_of_custody_groups,
|
||||
data_column_sidecar_subnet_count: spec.data_column_sidecar_subnet_count,
|
||||
samples_per_slot: spec.samples_per_slot,
|
||||
@@ -2248,7 +2229,6 @@ impl Config {
|
||||
max_blobs_per_block_electra,
|
||||
blob_sidecar_subnet_count_electra,
|
||||
max_request_blob_sidecars_electra,
|
||||
number_of_columns,
|
||||
number_of_custody_groups,
|
||||
data_column_sidecar_subnet_count,
|
||||
samples_per_slot,
|
||||
@@ -2330,12 +2310,10 @@ impl Config {
|
||||
max_request_blocks_deneb,
|
||||
),
|
||||
max_blobs_by_root_request: max_blobs_by_root_request_common(max_request_blob_sidecars),
|
||||
max_data_columns_by_root_request: max_data_columns_by_root_request_common(
|
||||
max_data_columns_by_root_request: max_data_columns_by_root_request_common::<E>(
|
||||
max_request_blocks_deneb,
|
||||
number_of_columns,
|
||||
),
|
||||
|
||||
number_of_columns,
|
||||
number_of_custody_groups,
|
||||
data_column_sidecar_subnet_count,
|
||||
samples_per_slot,
|
||||
@@ -2815,7 +2793,6 @@ mod yaml_tests {
|
||||
DEPOSIT_CONTRACT_ADDRESS: 0x00000000219ab540356cBB839Cbe05303d7705Fa
|
||||
CUSTODY_REQUIREMENT: 1
|
||||
DATA_COLUMN_SIDECAR_SUBNET_COUNT: 128
|
||||
NUMBER_OF_COLUMNS: 128
|
||||
SAMPLES_PER_SLOT: 8
|
||||
"#;
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
use crate::{ChainSpec, ColumnIndex, DataColumnSubnetId};
|
||||
use crate::{ChainSpec, ColumnIndex, DataColumnSubnetId, EthSpec};
|
||||
use alloy_primitives::U256;
|
||||
use itertools::Itertools;
|
||||
use safe_arith::{ArithError, SafeArith};
|
||||
@@ -24,8 +24,12 @@ pub fn get_custody_groups(
|
||||
custody_group_count: u64,
|
||||
spec: &ChainSpec,
|
||||
) -> Result<HashSet<CustodyIndex>, DataColumnCustodyGroupError> {
|
||||
get_custody_groups_ordered(raw_node_id, custody_group_count, spec)
|
||||
.map(|custody_groups| custody_groups.into_iter().collect())
|
||||
if custody_group_count == spec.number_of_custody_groups {
|
||||
Ok(HashSet::from_iter(0..spec.number_of_custody_groups))
|
||||
} else {
|
||||
get_custody_groups_ordered(raw_node_id, custody_group_count, spec)
|
||||
.map(|custody_groups| custody_groups.into_iter().collect())
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns a deterministically ordered list of custody groups assigned to a node,
|
||||
@@ -75,7 +79,7 @@ pub fn get_custody_groups_ordered(
|
||||
/// Returns the columns that are associated with a given custody group.
|
||||
///
|
||||
/// spec: https://github.com/ethereum/consensus-specs/blob/8e0d0d48e81d6c7c5a8253ab61340f5ea5bac66a/specs/fulu/das-core.md#compute_columns_for_custody_group
|
||||
pub fn compute_columns_for_custody_group(
|
||||
pub fn compute_columns_for_custody_group<E: EthSpec>(
|
||||
custody_group: CustodyIndex,
|
||||
spec: &ChainSpec,
|
||||
) -> Result<impl Iterator<Item = ColumnIndex>, DataColumnCustodyGroupError> {
|
||||
@@ -87,7 +91,7 @@ pub fn compute_columns_for_custody_group(
|
||||
}
|
||||
|
||||
let mut columns = Vec::new();
|
||||
for i in 0..spec.data_columns_per_group() {
|
||||
for i in 0..spec.data_columns_per_group::<E>() {
|
||||
let column = number_of_custody_groups
|
||||
.safe_mul(i)
|
||||
.and_then(|v| v.safe_add(custody_group))
|
||||
@@ -98,7 +102,7 @@ pub fn compute_columns_for_custody_group(
|
||||
Ok(columns.into_iter())
|
||||
}
|
||||
|
||||
pub fn compute_subnets_for_node(
|
||||
pub fn compute_subnets_for_node<E: EthSpec>(
|
||||
raw_node_id: [u8; 32],
|
||||
custody_group_count: u64,
|
||||
spec: &ChainSpec,
|
||||
@@ -107,7 +111,7 @@ pub fn compute_subnets_for_node(
|
||||
let mut subnets = HashSet::new();
|
||||
|
||||
for custody_group in custody_groups {
|
||||
let custody_group_subnets = compute_subnets_from_custody_group(custody_group, spec)?;
|
||||
let custody_group_subnets = compute_subnets_from_custody_group::<E>(custody_group, spec)?;
|
||||
subnets.extend(custody_group_subnets);
|
||||
}
|
||||
|
||||
@@ -115,11 +119,11 @@ pub fn compute_subnets_for_node(
|
||||
}
|
||||
|
||||
/// Returns the subnets that are associated with a given custody group.
|
||||
pub fn compute_subnets_from_custody_group(
|
||||
pub fn compute_subnets_from_custody_group<E: EthSpec>(
|
||||
custody_group: CustodyIndex,
|
||||
spec: &ChainSpec,
|
||||
) -> Result<impl Iterator<Item = DataColumnSubnetId> + '_, DataColumnCustodyGroupError> {
|
||||
let result = compute_columns_for_custody_group(custody_group, spec)?
|
||||
let result = compute_columns_for_custody_group::<E>(custody_group, spec)?
|
||||
.map(|column_index| DataColumnSubnetId::from_column_index(column_index, spec))
|
||||
.unique();
|
||||
Ok(result)
|
||||
@@ -128,19 +132,23 @@ pub fn compute_subnets_from_custody_group(
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use super::*;
|
||||
use crate::MainnetEthSpec;
|
||||
|
||||
type E = MainnetEthSpec;
|
||||
|
||||
#[test]
|
||||
fn test_compute_columns_for_custody_group() {
|
||||
let mut spec = ChainSpec::mainnet();
|
||||
spec.number_of_custody_groups = 64;
|
||||
spec.number_of_columns = 128;
|
||||
let columns_per_custody_group = spec.number_of_columns / spec.number_of_custody_groups;
|
||||
|
||||
let columns_per_custody_group =
|
||||
E::number_of_columns() / (spec.number_of_custody_groups as usize);
|
||||
|
||||
for custody_group in 0..spec.number_of_custody_groups {
|
||||
let columns = compute_columns_for_custody_group(custody_group, &spec)
|
||||
let columns = compute_columns_for_custody_group::<E>(custody_group, &spec)
|
||||
.unwrap()
|
||||
.collect::<Vec<_>>();
|
||||
assert_eq!(columns.len(), columns_per_custody_group as usize);
|
||||
assert_eq!(columns.len(), columns_per_custody_group);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -148,14 +156,13 @@ mod test {
|
||||
fn test_compute_subnets_from_custody_group() {
|
||||
let mut spec = ChainSpec::mainnet();
|
||||
spec.number_of_custody_groups = 64;
|
||||
spec.number_of_columns = 256;
|
||||
spec.data_column_sidecar_subnet_count = 128;
|
||||
|
||||
let subnets_per_custody_group =
|
||||
spec.data_column_sidecar_subnet_count / spec.number_of_custody_groups;
|
||||
|
||||
for custody_group in 0..spec.number_of_custody_groups {
|
||||
let subnets = compute_subnets_from_custody_group(custody_group, &spec)
|
||||
let subnets = compute_subnets_from_custody_group::<E>(custody_group, &spec)
|
||||
.unwrap()
|
||||
.collect::<Vec<_>>();
|
||||
assert_eq!(subnets.len(), subnets_per_custody_group as usize);
|
||||
|
||||
@@ -2,19 +2,17 @@ use crate::beacon_block_body::{BLOB_KZG_COMMITMENTS_INDEX, KzgCommitments};
|
||||
use crate::context_deserialize;
|
||||
use crate::test_utils::TestRandom;
|
||||
use crate::{
|
||||
BeaconBlockHeader, BeaconStateError, Epoch, EthSpec, ForkName, Hash256, RuntimeVariableList,
|
||||
BeaconBlockHeader, BeaconStateError, Epoch, EthSpec, ForkName, Hash256,
|
||||
SignedBeaconBlockHeader, Slot,
|
||||
};
|
||||
use bls::Signature;
|
||||
use context_deserialize::ContextDeserialize;
|
||||
use derivative::Derivative;
|
||||
use kzg::Error as KzgError;
|
||||
use kzg::{KzgCommitment, KzgProof};
|
||||
use merkle_proof::verify_merkle_proof;
|
||||
use safe_arith::ArithError;
|
||||
use serde::de::Error;
|
||||
use serde::{Deserialize, Deserializer, Serialize};
|
||||
use ssz::{DecodeError, Encode};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use ssz::Encode;
|
||||
use ssz_derive::{Decode, Encode};
|
||||
use ssz_types::Error as SszError;
|
||||
use ssz_types::{FixedVector, VariableList};
|
||||
@@ -28,69 +26,11 @@ pub type Cell<E> = FixedVector<u8, <E as EthSpec>::BytesPerCell>;
|
||||
pub type DataColumn<E> = VariableList<Cell<E>, <E as EthSpec>::MaxBlobCommitmentsPerBlock>;
|
||||
|
||||
/// Identifies a set of data columns associated with a specific beacon block.
|
||||
#[derive(Encode, Clone, Debug, PartialEq, TreeHash)]
|
||||
pub struct DataColumnsByRootIdentifier {
|
||||
#[derive(Encode, Decode, Clone, Debug, PartialEq, TreeHash, Deserialize)]
|
||||
#[context_deserialize(ForkName)]
|
||||
pub struct DataColumnsByRootIdentifier<E: EthSpec> {
|
||||
pub block_root: Hash256,
|
||||
pub columns: RuntimeVariableList<ColumnIndex>,
|
||||
}
|
||||
|
||||
impl<'de> ContextDeserialize<'de, (ForkName, usize)> for DataColumnsByRootIdentifier {
|
||||
fn context_deserialize<D>(deserializer: D, context: (ForkName, usize)) -> Result<Self, D::Error>
|
||||
where
|
||||
D: Deserializer<'de>,
|
||||
{
|
||||
#[derive(Deserialize)]
|
||||
struct Helper {
|
||||
block_root: Hash256,
|
||||
columns: serde_json::Value,
|
||||
}
|
||||
|
||||
let helper = Helper::deserialize(deserializer)?;
|
||||
Ok(Self {
|
||||
block_root: helper.block_root,
|
||||
columns: RuntimeVariableList::context_deserialize(helper.columns, context)
|
||||
.map_err(Error::custom)?,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl DataColumnsByRootIdentifier {
|
||||
pub fn from_ssz_bytes(bytes: &[u8], num_columns: usize) -> Result<Self, DecodeError> {
|
||||
let mut builder = ssz::SszDecoderBuilder::new(bytes);
|
||||
builder.register_type::<Hash256>()?;
|
||||
builder.register_anonymous_variable_length_item()?;
|
||||
|
||||
let mut decoder = builder.build()?;
|
||||
let block_root = decoder.decode_next()?;
|
||||
let columns = decoder
|
||||
.decode_next_with(|bytes| RuntimeVariableList::from_ssz_bytes(bytes, num_columns))?;
|
||||
Ok(DataColumnsByRootIdentifier {
|
||||
block_root,
|
||||
columns,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl RuntimeVariableList<DataColumnsByRootIdentifier> {
|
||||
pub fn from_ssz_bytes_with_nested(
|
||||
bytes: &[u8],
|
||||
max_len: usize,
|
||||
num_columns: usize,
|
||||
) -> Result<Self, DecodeError> {
|
||||
if bytes.is_empty() {
|
||||
return Ok(RuntimeVariableList::empty(max_len));
|
||||
}
|
||||
|
||||
let vec = ssz::decode_list_of_variable_length_items::<Vec<u8>, Vec<Vec<u8>>>(
|
||||
bytes,
|
||||
Some(max_len),
|
||||
)?
|
||||
.into_iter()
|
||||
.map(|bytes| DataColumnsByRootIdentifier::from_ssz_bytes(&bytes, num_columns))
|
||||
.collect::<Result<Vec<_>, _>>()?;
|
||||
|
||||
Ok(RuntimeVariableList::from_vec(vec, max_len))
|
||||
}
|
||||
pub columns: VariableList<ColumnIndex, E::NumberOfColumns>,
|
||||
}
|
||||
|
||||
pub type DataColumnSidecarList<E> = Vec<Arc<DataColumnSidecar<E>>>;
|
||||
@@ -228,45 +168,3 @@ impl From<SszError> for DataColumnSidecarError {
|
||||
Self::SszError(e)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use super::*;
|
||||
use bls::FixedBytesExtended;
|
||||
|
||||
#[test]
|
||||
fn round_trip_dcbroot_list() {
|
||||
let max_outer = 5;
|
||||
let max_inner = 10;
|
||||
|
||||
let data = vec![
|
||||
DataColumnsByRootIdentifier {
|
||||
block_root: Hash256::from_low_u64_be(10),
|
||||
columns: RuntimeVariableList::<ColumnIndex>::from_vec(vec![1u64, 2, 3], max_inner),
|
||||
},
|
||||
DataColumnsByRootIdentifier {
|
||||
block_root: Hash256::from_low_u64_be(20),
|
||||
columns: RuntimeVariableList::<ColumnIndex>::from_vec(vec![4u64, 5], max_inner),
|
||||
},
|
||||
];
|
||||
|
||||
let list = RuntimeVariableList::from_vec(data.clone(), max_outer);
|
||||
|
||||
let ssz_bytes = list.as_ssz_bytes();
|
||||
|
||||
let decoded =
|
||||
RuntimeVariableList::<DataColumnsByRootIdentifier>::from_ssz_bytes_with_nested(
|
||||
&ssz_bytes, max_outer, max_inner,
|
||||
)
|
||||
.expect("should decode list of DataColumnsByRootIdentifier");
|
||||
|
||||
assert_eq!(decoded.len(), data.len());
|
||||
for (original, decoded) in data.iter().zip(decoded.iter()) {
|
||||
assert_eq!(decoded.block_root, original.block_root);
|
||||
assert_eq!(
|
||||
decoded.columns.iter().copied().collect::<Vec<_>>(),
|
||||
original.columns.iter().copied().collect::<Vec<_>>()
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -111,11 +111,13 @@ pub trait EthSpec: 'static + Default + Sync + Send + Clone + Debug + PartialEq +
|
||||
type BytesPerFieldElement: Unsigned + Clone + Sync + Send + Debug + PartialEq;
|
||||
type KzgCommitmentInclusionProofDepth: Unsigned + Clone + Sync + Send + Debug + PartialEq;
|
||||
/*
|
||||
* New in PeerDAS
|
||||
* New in Fulu
|
||||
*/
|
||||
type FieldElementsPerCell: Unsigned + Clone + Sync + Send + Debug + PartialEq;
|
||||
type FieldElementsPerExtBlob: Unsigned + Clone + Sync + Send + Debug + PartialEq;
|
||||
type KzgCommitmentsInclusionProofDepth: Unsigned + Clone + Sync + Send + Debug + PartialEq;
|
||||
type CellsPerExtBlob: Unsigned + Clone + Sync + Send + Debug + PartialEq;
|
||||
type NumberOfColumns: Unsigned + Clone + Sync + Send + Debug + PartialEq;
|
||||
type ProposerLookaheadSlots: Unsigned + Clone + Sync + Send + Debug + PartialEq;
|
||||
/*
|
||||
* Derived values (set these CAREFULLY)
|
||||
@@ -378,6 +380,14 @@ pub trait EthSpec: 'static + Default + Sync + Send + Clone + Debug + PartialEq +
|
||||
Self::KzgCommitmentsInclusionProofDepth::to_usize()
|
||||
}
|
||||
|
||||
fn cells_per_ext_blob() -> usize {
|
||||
Self::CellsPerExtBlob::to_usize()
|
||||
}
|
||||
|
||||
fn number_of_columns() -> usize {
|
||||
Self::NumberOfColumns::to_usize()
|
||||
}
|
||||
|
||||
fn proposer_lookahead_slots() -> usize {
|
||||
Self::ProposerLookaheadSlots::to_usize()
|
||||
}
|
||||
@@ -433,6 +443,8 @@ impl EthSpec for MainnetEthSpec {
|
||||
type MaxCellsPerBlock = U33554432;
|
||||
type KzgCommitmentInclusionProofDepth = U17;
|
||||
type KzgCommitmentsInclusionProofDepth = U4; // inclusion of the whole list of commitments
|
||||
type CellsPerExtBlob = U128;
|
||||
type NumberOfColumns = U128;
|
||||
type ProposerLookaheadSlots = U64; // Derived from (MIN_SEED_LOOKAHEAD + 1) * SLOTS_PER_EPOCH
|
||||
type SyncSubcommitteeSize = U128; // 512 committee size / 4 sync committee subnet count
|
||||
type MaxPendingAttestations = U4096; // 128 max attestations * 32 slots per epoch
|
||||
@@ -487,6 +499,8 @@ impl EthSpec for MinimalEthSpec {
|
||||
type MaxCellsPerBlock = U33554432;
|
||||
type BytesPerCell = U2048;
|
||||
type KzgCommitmentsInclusionProofDepth = U4;
|
||||
type CellsPerExtBlob = U128;
|
||||
type NumberOfColumns = U128;
|
||||
type ProposerLookaheadSlots = U16; // Derived from (MIN_SEED_LOOKAHEAD + 1) * SLOTS_PER_EPOCH
|
||||
|
||||
params_from_eth_spec!(MainnetEthSpec {
|
||||
@@ -584,6 +598,8 @@ impl EthSpec for GnosisEthSpec {
|
||||
type MaxCellsPerBlock = U33554432;
|
||||
type BytesPerCell = U2048;
|
||||
type KzgCommitmentsInclusionProofDepth = U4;
|
||||
type CellsPerExtBlob = U128;
|
||||
type NumberOfColumns = U128;
|
||||
type ProposerLookaheadSlots = U32; // Derived from (MIN_SEED_LOOKAHEAD + 1) * SLOTS_PER_EPOCH
|
||||
|
||||
fn default_spec() -> ChainSpec {
|
||||
|
||||
@@ -297,6 +297,10 @@ pub struct FuluPreset {
|
||||
pub field_elements_per_ext_blob: u64,
|
||||
#[serde(with = "serde_utils::quoted_u64")]
|
||||
pub kzg_commitments_inclusion_proof_depth: u64,
|
||||
#[serde(with = "serde_utils::quoted_u64")]
|
||||
pub cells_per_ext_blob: u64,
|
||||
#[serde(with = "serde_utils::quoted_u64")]
|
||||
pub number_of_columns: u64,
|
||||
}
|
||||
|
||||
impl FuluPreset {
|
||||
@@ -306,6 +310,8 @@ impl FuluPreset {
|
||||
field_elements_per_ext_blob: E::field_elements_per_ext_blob() as u64,
|
||||
kzg_commitments_inclusion_proof_depth: E::kzg_commitments_inclusion_proof_depth()
|
||||
as u64,
|
||||
cells_per_ext_blob: E::cells_per_ext_blob() as u64,
|
||||
number_of_columns: E::number_of_columns() as u64,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user