start adding types
This commit is contained in:
parent
aa022f4685
commit
8e4e499b51
@ -1,6 +1,6 @@
|
|||||||
use crate::beacon_block_body::{
|
use crate::beacon_block_body::{
|
||||||
BeaconBlockBodyAltair, BeaconBlockBodyBase, BeaconBlockBodyMerge, BeaconBlockBodyRef,
|
BeaconBlockBodyAltair, BeaconBlockBodyBase, BeaconBlockBodyMerge, BeaconBlockBodyRef,
|
||||||
BeaconBlockBodyRefMut,
|
BeaconBlockBodyRefMut, BeaconBlockBobyEip4844
|
||||||
};
|
};
|
||||||
use crate::test_utils::TestRandom;
|
use crate::test_utils::TestRandom;
|
||||||
use crate::*;
|
use crate::*;
|
||||||
@ -17,7 +17,7 @@ use tree_hash_derive::TreeHash;
|
|||||||
|
|
||||||
/// A block of the `BeaconChain`.
|
/// A block of the `BeaconChain`.
|
||||||
#[superstruct(
|
#[superstruct(
|
||||||
variants(Base, Altair, Merge),
|
variants(Base, Altair, Merge, Eip4844),
|
||||||
variant_attributes(
|
variant_attributes(
|
||||||
derive(
|
derive(
|
||||||
Debug,
|
Debug,
|
||||||
@ -64,6 +64,8 @@ pub struct BeaconBlock<T: EthSpec, Payload: ExecPayload<T> = FullPayload<T>> {
|
|||||||
pub body: BeaconBlockBodyAltair<T, Payload>,
|
pub body: BeaconBlockBodyAltair<T, Payload>,
|
||||||
#[superstruct(only(Merge), partial_getter(rename = "body_merge"))]
|
#[superstruct(only(Merge), partial_getter(rename = "body_merge"))]
|
||||||
pub body: BeaconBlockBodyMerge<T, Payload>,
|
pub body: BeaconBlockBodyMerge<T, Payload>,
|
||||||
|
#[superstruct(only(Eip4844), partial_getter(rename = "body_eip4844"))]
|
||||||
|
pub body: BeaconBlockBodyEip4844<T, Payload>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: EthSpec, Payload: ExecPayload<T>> SignedRoot for BeaconBlock<T, Payload> {}
|
impl<T: EthSpec, Payload: ExecPayload<T>> SignedRoot for BeaconBlock<T, Payload> {}
|
||||||
@ -540,6 +542,7 @@ macro_rules! impl_from {
|
|||||||
impl_from!(BeaconBlockBase, <E, FullPayload<E>>, <E, BlindedPayload<E>>, |body: BeaconBlockBodyBase<_, _>| body.into());
|
impl_from!(BeaconBlockBase, <E, FullPayload<E>>, <E, BlindedPayload<E>>, |body: BeaconBlockBodyBase<_, _>| body.into());
|
||||||
impl_from!(BeaconBlockAltair, <E, FullPayload<E>>, <E, BlindedPayload<E>>, |body: BeaconBlockBodyAltair<_, _>| body.into());
|
impl_from!(BeaconBlockAltair, <E, FullPayload<E>>, <E, BlindedPayload<E>>, |body: BeaconBlockBodyAltair<_, _>| body.into());
|
||||||
impl_from!(BeaconBlockMerge, <E, FullPayload<E>>, <E, BlindedPayload<E>>, |body: BeaconBlockBodyMerge<_, _>| body.into());
|
impl_from!(BeaconBlockMerge, <E, FullPayload<E>>, <E, BlindedPayload<E>>, |body: BeaconBlockBodyMerge<_, _>| body.into());
|
||||||
|
impl_from!(BeaconBlockEip4844, <E, FullPayload<E>>, <E, BlindedPayload<E>>, |body: BeaconBlockBodyEip4844<_, _>| body.into());
|
||||||
|
|
||||||
// We can clone blocks with payloads to blocks without payloads, without cloning the payload.
|
// We can clone blocks with payloads to blocks without payloads, without cloning the payload.
|
||||||
macro_rules! impl_clone_as_blinded {
|
macro_rules! impl_clone_as_blinded {
|
||||||
|
@ -13,7 +13,7 @@ use tree_hash_derive::TreeHash;
|
|||||||
///
|
///
|
||||||
/// This *superstruct* abstracts over the hard-fork.
|
/// This *superstruct* abstracts over the hard-fork.
|
||||||
#[superstruct(
|
#[superstruct(
|
||||||
variants(Base, Altair, Merge),
|
variants(Base, Altair, Merge, Eip4844),
|
||||||
variant_attributes(
|
variant_attributes(
|
||||||
derive(
|
derive(
|
||||||
Debug,
|
Debug,
|
||||||
@ -47,14 +47,16 @@ pub struct BeaconBlockBody<T: EthSpec, Payload: ExecPayload<T> = FullPayload<T>>
|
|||||||
pub attestations: VariableList<Attestation<T>, T::MaxAttestations>,
|
pub attestations: VariableList<Attestation<T>, T::MaxAttestations>,
|
||||||
pub deposits: VariableList<Deposit, T::MaxDeposits>,
|
pub deposits: VariableList<Deposit, T::MaxDeposits>,
|
||||||
pub voluntary_exits: VariableList<SignedVoluntaryExit, T::MaxVoluntaryExits>,
|
pub voluntary_exits: VariableList<SignedVoluntaryExit, T::MaxVoluntaryExits>,
|
||||||
#[superstruct(only(Altair, Merge))]
|
#[superstruct(only(Altair, Merge, Eip4844))]
|
||||||
pub sync_aggregate: SyncAggregate<T>,
|
pub sync_aggregate: SyncAggregate<T>,
|
||||||
// We flatten the execution payload so that serde can use the name of the inner type,
|
// We flatten the execution payload so that serde can use the name of the inner type,
|
||||||
// either `execution_payload` for full payloads, or `execution_payload_header` for blinded
|
// either `execution_payload` for full payloads, or `execution_payload_header` for blinded
|
||||||
// payloads.
|
// payloads.
|
||||||
#[superstruct(only(Merge))]
|
#[superstruct(only(Merge, Eip4844))]
|
||||||
#[serde(flatten)]
|
#[serde(flatten)]
|
||||||
pub execution_payload: Payload,
|
pub execution_payload: Payload,
|
||||||
|
#[superstruct(only(Eip4844))]
|
||||||
|
pub blob_kzg_commitments: VariableList<TODO, T::MaxBlobsPerBlock>,
|
||||||
#[superstruct(only(Base, Altair))]
|
#[superstruct(only(Base, Altair))]
|
||||||
#[ssz(skip_serializing, skip_deserializing)]
|
#[ssz(skip_serializing, skip_deserializing)]
|
||||||
#[tree_hash(skip_hashing)]
|
#[tree_hash(skip_hashing)]
|
||||||
|
@ -95,6 +95,10 @@ pub trait EthSpec: 'static + Default + Sync + Send + Clone + Debug + PartialEq +
|
|||||||
type GasLimitDenominator: Unsigned + Clone + Sync + Send + Debug + PartialEq;
|
type GasLimitDenominator: Unsigned + Clone + Sync + Send + Debug + PartialEq;
|
||||||
type MinGasLimit: Unsigned + Clone + Sync + Send + Debug + PartialEq;
|
type MinGasLimit: Unsigned + Clone + Sync + Send + Debug + PartialEq;
|
||||||
type MaxExtraDataBytes: Unsigned + Clone + Sync + Send + Debug + PartialEq;
|
type MaxExtraDataBytes: Unsigned + Clone + Sync + Send + Debug + PartialEq;
|
||||||
|
/*
|
||||||
|
* New in Eip4844
|
||||||
|
*/
|
||||||
|
type MaxBlobsPerBlock: Unsigned + Clone + Sync + Send + Debug + PartialEq;
|
||||||
/*
|
/*
|
||||||
* Derived values (set these CAREFULLY)
|
* Derived values (set these CAREFULLY)
|
||||||
*/
|
*/
|
||||||
@ -222,6 +226,11 @@ pub trait EthSpec: 'static + Default + Sync + Send + Clone + Debug + PartialEq +
|
|||||||
fn bytes_per_logs_bloom() -> usize {
|
fn bytes_per_logs_bloom() -> usize {
|
||||||
Self::BytesPerLogsBloom::to_usize()
|
Self::BytesPerLogsBloom::to_usize()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns the `MAX_BLOBS_PER_BLOCK` constant for this specification.
|
||||||
|
fn max_blobs_per_block() -> usize {
|
||||||
|
Self::MaxBlobsPerBlock::to_usize()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Macro to inherit some type values from another EthSpec.
|
/// Macro to inherit some type values from another EthSpec.
|
||||||
@ -265,6 +274,7 @@ impl EthSpec for MainnetEthSpec {
|
|||||||
type SyncSubcommitteeSize = U128; // 512 committee size / 4 sync committee subnet count
|
type SyncSubcommitteeSize = U128; // 512 committee size / 4 sync committee subnet count
|
||||||
type MaxPendingAttestations = U4096; // 128 max attestations * 32 slots per epoch
|
type MaxPendingAttestations = U4096; // 128 max attestations * 32 slots per epoch
|
||||||
type SlotsPerEth1VotingPeriod = U2048; // 64 epochs * 32 slots per epoch
|
type SlotsPerEth1VotingPeriod = U2048; // 64 epochs * 32 slots per epoch
|
||||||
|
type MaxBlobsPerBlock = U16;
|
||||||
|
|
||||||
fn default_spec() -> ChainSpec {
|
fn default_spec() -> ChainSpec {
|
||||||
ChainSpec::mainnet()
|
ChainSpec::mainnet()
|
||||||
@ -309,7 +319,8 @@ impl EthSpec for MinimalEthSpec {
|
|||||||
BytesPerLogsBloom,
|
BytesPerLogsBloom,
|
||||||
GasLimitDenominator,
|
GasLimitDenominator,
|
||||||
MinGasLimit,
|
MinGasLimit,
|
||||||
MaxExtraDataBytes
|
MaxExtraDataBytes,
|
||||||
|
MaxBlobsPerBlock
|
||||||
});
|
});
|
||||||
|
|
||||||
fn default_spec() -> ChainSpec {
|
fn default_spec() -> ChainSpec {
|
||||||
@ -354,6 +365,7 @@ impl EthSpec for GnosisEthSpec {
|
|||||||
type SyncSubcommitteeSize = U128; // 512 committee size / 4 sync committee subnet count
|
type SyncSubcommitteeSize = U128; // 512 committee size / 4 sync committee subnet count
|
||||||
type MaxPendingAttestations = U2048; // 128 max attestations * 16 slots per epoch
|
type MaxPendingAttestations = U2048; // 128 max attestations * 16 slots per epoch
|
||||||
type SlotsPerEth1VotingPeriod = U1024; // 64 epochs * 16 slots per epoch
|
type SlotsPerEth1VotingPeriod = U1024; // 64 epochs * 16 slots per epoch
|
||||||
|
type MaxBlobsPerBlock = U16;
|
||||||
|
|
||||||
fn default_spec() -> ChainSpec {
|
fn default_spec() -> ChainSpec {
|
||||||
ChainSpec::gnosis()
|
ChainSpec::gnosis()
|
||||||
|
112
consensus/types/src/kzg_commitment.rs
Normal file
112
consensus/types/src/kzg_commitment.rs
Normal file
@ -0,0 +1,112 @@
|
|||||||
|
use std::fmt;
|
||||||
|
use serde::{Deserialize, Deserializer, Serializer};
|
||||||
|
use ssz::{Decode, DecodeError, Encode};
|
||||||
|
use tree_hash::TreeHash;
|
||||||
|
|
||||||
|
const KZG_COMMITMENT_BYTES_LEN: usize = 48;
|
||||||
|
|
||||||
|
#[derive(Default, Debug, PartialEq, Hash, Clone, Copy, Serialize, Deserialize)]
|
||||||
|
#[serde(transparent)]
|
||||||
|
pub struct KzgCommitment(#[serde(with = "serde_kzg_commitment")] pub [u8; KZG_COMMITMENT_BYTES_LEN]);
|
||||||
|
|
||||||
|
impl fmt::Display for KzgCommitment {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
|
write!(f, "{}", eth2_serde_utils::hex::encode(&self.0))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<[u8; KZG_COMMITMENT_BYTES_LEN]> for KzgCommitment {
|
||||||
|
fn from(bytes: [u8; KZG_COMMITMENT_BYTES_LEN]) -> Self {
|
||||||
|
Self(bytes)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Into<[u8; KZG_COMMITMENT_BYTES_LEN]> for KzgCommitment {
|
||||||
|
fn into(self) -> [u8; KZG_COMMITMENT_BYTES_LEN] {
|
||||||
|
self.0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub mod serde_kzg_commitment {
|
||||||
|
use serde::de::Error;
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
pub fn serialize<S>(bytes: &[u8; KZG_COMMITMENT_BYTES_LEN], serializer: S) -> Result<S::Ok, S::Error>
|
||||||
|
where
|
||||||
|
S: Serializer,
|
||||||
|
{
|
||||||
|
serializer.serialize_str(ð2_serde_utils::hex::encode(bytes))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn deserialize<'de, D>(deserializer: D) -> Result<[u8; KZG_COMMITMENT_BYTES_LEN], D::Error>
|
||||||
|
where
|
||||||
|
D: Deserializer<'de>,
|
||||||
|
{
|
||||||
|
let s: String = Deserialize::deserialize(deserializer)?;
|
||||||
|
|
||||||
|
let bytes = eth2_serde_utils::hex::decode(&s).map_err(D::Error::custom)?;
|
||||||
|
|
||||||
|
if bytes.len() != KZG_COMMITMENT_BYTES_LEN {
|
||||||
|
return Err(D::Error::custom(format!(
|
||||||
|
"incorrect byte length {}, expected {}",
|
||||||
|
bytes.len(),
|
||||||
|
KZG_COMMITMENT_BYTES_LEN
|
||||||
|
)));
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut array = [0; KZG_COMMITMENT_BYTES_LEN];
|
||||||
|
array[..].copy_from_slice(&bytes);
|
||||||
|
|
||||||
|
Ok(array)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Encode for KzgCommitment {
|
||||||
|
fn is_ssz_fixed_len() -> bool {
|
||||||
|
<[u8; KZG_COMMITMENT_BYTES_LEN] as Encode>::is_ssz_fixed_len()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn ssz_fixed_len() -> usize {
|
||||||
|
<[u8; KZG_COMMITMENT_BYTES_LEN] as Encode>::ssz_fixed_len()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn ssz_bytes_len(&self) -> usize {
|
||||||
|
self.0.ssz_bytes_len()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn ssz_append(&self, buf: &mut Vec<u8>) {
|
||||||
|
self.0.ssz_append(buf)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Decode for KzgCommitment {
|
||||||
|
fn is_ssz_fixed_len() -> bool {
|
||||||
|
<[u8; KZG_COMMITMENT_BYTES_LEN] as Decode>::is_ssz_fixed_len()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn ssz_fixed_len() -> usize {
|
||||||
|
<[u8; KZG_COMMITMENT_BYTES_LEN] as Decode>::ssz_fixed_len()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn from_ssz_bytes(bytes: &[u8]) -> Result<Self, DecodeError> {
|
||||||
|
<[u8; KZG_COMMITMENT_BYTES_LEN]>::from_ssz_bytes(bytes).map(Self)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl TreeHash for KzgCommitment {
|
||||||
|
fn tree_hash_type() -> tree_hash::TreeHashType {
|
||||||
|
<[u8; KZG_COMMITMENT_BYTES_LEN]>::tree_hash_type()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn tree_hash_packed_encoding(&self) -> Vec<u8> {
|
||||||
|
self.0.tree_hash_packed_encoding()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn tree_hash_packing_factor() -> usize {
|
||||||
|
<[u8; KZG_COMMITMENT_BYTES_LEN]>::tree_hash_packing_factor()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn tree_hash_root(&self) -> tree_hash::Hash256 {
|
||||||
|
self.0.tree_hash_root()
|
||||||
|
}
|
||||||
|
}
|
112
consensus/types/src/kzg_proof.rs
Normal file
112
consensus/types/src/kzg_proof.rs
Normal file
@ -0,0 +1,112 @@
|
|||||||
|
use std::fmt;
|
||||||
|
use serde::{Deserialize, Deserializer, Serializer};
|
||||||
|
use ssz::{Decode, DecodeError, Encode};
|
||||||
|
use tree_hash::TreeHash;
|
||||||
|
|
||||||
|
const KZG_PROOF_BYTES_LEN: usize = 48;
|
||||||
|
|
||||||
|
#[derive(Default, Debug, PartialEq, Hash, Clone, Copy, Serialize, Deserialize)]
|
||||||
|
#[serde(transparent)]
|
||||||
|
pub struct KzgProof(#[serde(with = "serde_kzg_proof")] pub [u8; KZG_PROOF_BYTES_LEN]);
|
||||||
|
|
||||||
|
impl fmt::Display for KzgProof {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
|
write!(f, "{}", eth2_serde_utils::hex::encode(&self.0))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<[u8; KZG_PROOF_BYTES_LEN]> for KzgProof {
|
||||||
|
fn from(bytes: [u8; KZG_PROOF_BYTES_LEN]) -> Self {
|
||||||
|
Self(bytes)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Into<[u8; KZG_PROOF_BYTES_LEN]> for KzgProof {
|
||||||
|
fn into(self) -> [u8; KZG_PROOF_BYTES_LEN] {
|
||||||
|
self.0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub mod serde_kzg_proof {
|
||||||
|
use serde::de::Error;
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
pub fn serialize<S>(bytes: &[u8; KZG_PROOF_BYTES_LEN], serializer: S) -> Result<S::Ok, S::Error>
|
||||||
|
where
|
||||||
|
S: Serializer,
|
||||||
|
{
|
||||||
|
serializer.serialize_str(ð2_serde_utils::hex::encode(bytes))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn deserialize<'de, D>(deserializer: D) -> Result<[u8; KZG_PROOF_BYTES_LEN], D::Error>
|
||||||
|
where
|
||||||
|
D: Deserializer<'de>,
|
||||||
|
{
|
||||||
|
let s: String = Deserialize::deserialize(deserializer)?;
|
||||||
|
|
||||||
|
let bytes = eth2_serde_utils::hex::decode(&s).map_err(D::Error::custom)?;
|
||||||
|
|
||||||
|
if bytes.len() != KZG_PROOF_BYTES_LEN {
|
||||||
|
return Err(D::Error::custom(format!(
|
||||||
|
"incorrect byte length {}, expected {}",
|
||||||
|
bytes.len(),
|
||||||
|
KZG_PROOF_BYTES_LEN
|
||||||
|
)));
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut array = [0; KZG_PROOF_BYTES_LEN];
|
||||||
|
array[..].copy_from_slice(&bytes);
|
||||||
|
|
||||||
|
Ok(array)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Encode for KzgProof {
|
||||||
|
fn is_ssz_fixed_len() -> bool {
|
||||||
|
<[u8; KZG_PROOF_BYTES_LEN] as Encode>::is_ssz_fixed_len()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn ssz_fixed_len() -> usize {
|
||||||
|
<[u8; KZG_PROOF_BYTES_LEN] as Encode>::ssz_fixed_len()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn ssz_bytes_len(&self) -> usize {
|
||||||
|
self.0.ssz_bytes_len()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn ssz_append(&self, buf: &mut Vec<u8>) {
|
||||||
|
self.0.ssz_append(buf)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Decode for KzgProof {
|
||||||
|
fn is_ssz_fixed_len() -> bool {
|
||||||
|
<[u8; KZG_PROOF_BYTES_LEN] as Decode>::is_ssz_fixed_len()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn ssz_fixed_len() -> usize {
|
||||||
|
<[u8; KZG_PROOF_BYTES_LEN] as Decode>::ssz_fixed_len()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn from_ssz_bytes(bytes: &[u8]) -> Result<Self, DecodeError> {
|
||||||
|
<[u8; KZG_PROOF_BYTES_LEN]>::from_ssz_bytes(bytes).map(Self)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl TreeHash for KzgProof {
|
||||||
|
fn tree_hash_type() -> tree_hash::TreeHashType {
|
||||||
|
<[u8; KZG_PROOF_BYTES_LEN]>::tree_hash_type()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn tree_hash_packed_encoding(&self) -> Vec<u8> {
|
||||||
|
self.0.tree_hash_packed_encoding()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn tree_hash_packing_factor() -> usize {
|
||||||
|
<[u8; KZG_PROOF_BYTES_LEN]>::tree_hash_packing_factor()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn tree_hash_root(&self) -> tree_hash::Hash256 {
|
||||||
|
self.0.tree_hash_root()
|
||||||
|
}
|
||||||
|
}
|
@ -14,6 +14,8 @@
|
|||||||
|
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate lazy_static;
|
extern crate lazy_static;
|
||||||
|
extern crate core;
|
||||||
|
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
pub mod test_utils;
|
pub mod test_utils;
|
||||||
|
|
||||||
@ -90,6 +92,9 @@ pub mod slot_data;
|
|||||||
#[cfg(feature = "sqlite")]
|
#[cfg(feature = "sqlite")]
|
||||||
pub mod sqlite;
|
pub mod sqlite;
|
||||||
|
|
||||||
|
pub mod kzg_commitment;
|
||||||
|
pub mod kzg_proof;
|
||||||
|
|
||||||
use ethereum_types::{H160, H256};
|
use ethereum_types::{H160, H256};
|
||||||
|
|
||||||
pub use crate::aggregate_and_proof::AggregateAndProof;
|
pub use crate::aggregate_and_proof::AggregateAndProof;
|
||||||
|
Loading…
Reference in New Issue
Block a user