mirror of
https://github.com/sigp/lighthouse.git
synced 2026-03-03 00:31:50 +00:00
@@ -32,10 +32,10 @@ MAX_ATTESTATIONS_ELECTRA: 8
|
||||
|
||||
# Execution
|
||||
# ---------------------------------------------------------------
|
||||
# [customized] 2**2 (= 4) deposit requests
|
||||
MAX_DEPOSIT_REQUESTS_PER_PAYLOAD: 4
|
||||
# [customized] 2**1 (= 2) withdrawal requests
|
||||
MAX_WITHDRAWAL_REQUESTS_PER_PAYLOAD: 2
|
||||
# 2**13 (= 8,192) deposit requests
|
||||
MAX_DEPOSIT_REQUESTS_PER_PAYLOAD: 8192
|
||||
# 2**4 (= 16) withdrawal requests
|
||||
MAX_WITHDRAWAL_REQUESTS_PER_PAYLOAD: 16
|
||||
# 2**1 (= 2) consolidation requests
|
||||
MAX_CONSOLIDATION_REQUESTS_PER_PAYLOAD: 2
|
||||
|
||||
|
||||
@@ -6,12 +6,14 @@ use crate::{
|
||||
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::{Deserialize, Serialize};
|
||||
use serde::de::Error;
|
||||
use serde::{Deserialize, Deserializer, Serialize};
|
||||
use ssz::{DecodeError, Encode};
|
||||
use ssz_derive::{Decode, Encode};
|
||||
use ssz_types::Error as SszError;
|
||||
@@ -26,12 +28,49 @@ 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)]
|
||||
#[derive(Encode, Clone, Debug, PartialEq, TreeHash)]
|
||||
pub struct DataColumnsByRootIdentifier {
|
||||
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],
|
||||
@@ -47,21 +86,7 @@ impl RuntimeVariableList<DataColumnsByRootIdentifier> {
|
||||
Some(max_len),
|
||||
)?
|
||||
.into_iter()
|
||||
.map(|bytes| {
|
||||
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,
|
||||
})
|
||||
})
|
||||
.map(|bytes| DataColumnsByRootIdentifier::from_ssz_bytes(&bytes, num_columns))
|
||||
.collect::<Result<Vec<_>, _>>()?;
|
||||
|
||||
Ok(RuntimeVariableList::from_vec(vec, max_len))
|
||||
|
||||
@@ -476,8 +476,6 @@ impl EthSpec for MinimalEthSpec {
|
||||
type KzgCommitmentInclusionProofDepth = U10;
|
||||
type PendingPartialWithdrawalsLimit = U64;
|
||||
type PendingConsolidationsLimit = U64;
|
||||
type MaxDepositRequestsPerPayload = U4;
|
||||
type MaxWithdrawalRequestsPerPayload = U2;
|
||||
type FieldElementsPerCell = U64;
|
||||
type FieldElementsPerExtBlob = U8192;
|
||||
type MaxCellsPerBlock = U33554432;
|
||||
@@ -509,7 +507,9 @@ impl EthSpec for MinimalEthSpec {
|
||||
MaxPendingDepositsPerEpoch,
|
||||
MaxConsolidationRequestsPerPayload,
|
||||
MaxAttesterSlashingsElectra,
|
||||
MaxAttestationsElectra
|
||||
MaxAttestationsElectra,
|
||||
MaxDepositRequestsPerPayload,
|
||||
MaxWithdrawalRequestsPerPayload
|
||||
});
|
||||
|
||||
fn default_spec() -> ChainSpec {
|
||||
|
||||
@@ -6,6 +6,7 @@ use ssz::Decode;
|
||||
use ssz_types::Error;
|
||||
use std::ops::{Deref, Index, IndexMut};
|
||||
use std::slice::SliceIndex;
|
||||
use tree_hash::{Hash256, MerkleHasher, PackedEncoding, TreeHash, TreeHashType};
|
||||
|
||||
/// Emulates a SSZ `List`.
|
||||
///
|
||||
@@ -241,6 +242,62 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: TreeHash> TreeHash for RuntimeVariableList<T> {
|
||||
fn tree_hash_type() -> tree_hash::TreeHashType {
|
||||
tree_hash::TreeHashType::List
|
||||
}
|
||||
|
||||
fn tree_hash_packed_encoding(&self) -> PackedEncoding {
|
||||
unreachable!("List should never be packed.")
|
||||
}
|
||||
|
||||
fn tree_hash_packing_factor() -> usize {
|
||||
unreachable!("List should never be packed.")
|
||||
}
|
||||
|
||||
fn tree_hash_root(&self) -> Hash256 {
|
||||
let root = runtime_vec_tree_hash_root::<T>(&self.vec, self.max_len);
|
||||
|
||||
tree_hash::mix_in_length(&root, self.len())
|
||||
}
|
||||
}
|
||||
|
||||
// We can delete this once the upstream `vec_tree_hash_root` is modified to use a runtime max len.
|
||||
pub fn runtime_vec_tree_hash_root<T>(vec: &[T], max_len: usize) -> Hash256
|
||||
where
|
||||
T: TreeHash,
|
||||
{
|
||||
match T::tree_hash_type() {
|
||||
TreeHashType::Basic => {
|
||||
let mut hasher =
|
||||
MerkleHasher::with_leaves(max_len.div_ceil(T::tree_hash_packing_factor()));
|
||||
|
||||
for item in vec {
|
||||
hasher
|
||||
.write(&item.tree_hash_packed_encoding())
|
||||
.expect("ssz_types variable vec should not contain more elements than max");
|
||||
}
|
||||
|
||||
hasher
|
||||
.finish()
|
||||
.expect("ssz_types variable vec should not have a remaining buffer")
|
||||
}
|
||||
TreeHashType::Container | TreeHashType::List | TreeHashType::Vector => {
|
||||
let mut hasher = MerkleHasher::with_leaves(max_len);
|
||||
|
||||
for item in vec {
|
||||
hasher
|
||||
.write(item.tree_hash_root().as_slice())
|
||||
.expect("ssz_types vec should not contain more elements than max");
|
||||
}
|
||||
|
||||
hasher
|
||||
.finish()
|
||||
.expect("ssz_types vec should not have a remaining buffer")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use super::*;
|
||||
|
||||
Reference in New Issue
Block a user