mirror of
https://github.com/sigp/lighthouse.git
synced 2026-04-16 12:28:24 +00:00
Merge remote-tracking branch 'origin/unstable' into progressive-list-tests
This commit is contained in:
@@ -73,6 +73,9 @@ paste = { workspace = true }
|
||||
state_processing = { workspace = true }
|
||||
tokio = { workspace = true }
|
||||
|
||||
[lints.clippy]
|
||||
module_inception = "allow"
|
||||
|
||||
[[bench]]
|
||||
name = "benches"
|
||||
harness = false
|
||||
|
||||
@@ -1,17 +1,20 @@
|
||||
use super::{AttestationBase, AttestationElectra, AttestationRef};
|
||||
use super::{
|
||||
ChainSpec, Domain, EthSpec, Fork, ForkName, Hash256, PublicKey, SecretKey, SelectionProof,
|
||||
Signature, SignedRoot,
|
||||
};
|
||||
use crate::Attestation;
|
||||
use crate::context_deserialize;
|
||||
use crate::test_utils::TestRandom;
|
||||
use bls::{PublicKey, SecretKey, Signature};
|
||||
use context_deserialize::context_deserialize;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use ssz_derive::{Decode, Encode};
|
||||
use superstruct::superstruct;
|
||||
use test_random_derive::TestRandom;
|
||||
use tree_hash_derive::TreeHash;
|
||||
|
||||
use crate::{
|
||||
attestation::{
|
||||
Attestation, AttestationBase, AttestationElectra, AttestationRef, SelectionProof,
|
||||
},
|
||||
core::{ChainSpec, Domain, EthSpec, Hash256, SignedRoot},
|
||||
fork::{Fork, ForkName},
|
||||
test_utils::TestRandom,
|
||||
};
|
||||
|
||||
#[superstruct(
|
||||
variants(Base, Electra),
|
||||
variant_attributes(
|
||||
@@ -1,23 +1,28 @@
|
||||
use super::{
|
||||
AggregateSignature, AttestationData, BitList, ChainSpec, Domain, EthSpec, Fork, SecretKey,
|
||||
Signature, SignedRoot,
|
||||
use std::{
|
||||
collections::HashSet,
|
||||
hash::{Hash, Hasher},
|
||||
};
|
||||
use crate::slot_data::SlotData;
|
||||
use crate::{
|
||||
Checkpoint, ContextDeserialize, ForkName, IndexedAttestationBase, IndexedAttestationElectra,
|
||||
};
|
||||
use crate::{Hash256, Slot, test_utils::TestRandom};
|
||||
use crate::{IndexedAttestation, context_deserialize};
|
||||
|
||||
use bls::{AggregateSignature, SecretKey, Signature};
|
||||
use context_deserialize::{ContextDeserialize, context_deserialize};
|
||||
use educe::Educe;
|
||||
use serde::{Deserialize, Deserializer, Serialize};
|
||||
use ssz_derive::{Decode, Encode};
|
||||
use ssz_types::BitVector;
|
||||
use std::collections::HashSet;
|
||||
use std::hash::{Hash, Hasher};
|
||||
use ssz_types::{BitList, BitVector};
|
||||
use superstruct::superstruct;
|
||||
use test_random_derive::TestRandom;
|
||||
use tree_hash_derive::TreeHash;
|
||||
|
||||
use crate::{
|
||||
attestation::{
|
||||
AttestationData, Checkpoint, IndexedAttestation, IndexedAttestationBase,
|
||||
IndexedAttestationElectra,
|
||||
},
|
||||
core::{ChainSpec, Domain, EthSpec, Hash256, SignedRoot, Slot, SlotData},
|
||||
fork::{Fork, ForkName},
|
||||
test_utils::TestRandom,
|
||||
};
|
||||
|
||||
#[derive(Debug, PartialEq, Clone)]
|
||||
pub enum Error {
|
||||
SszTypesError(ssz_types::Error),
|
||||
@@ -1,11 +1,16 @@
|
||||
use crate::slot_data::SlotData;
|
||||
use crate::test_utils::TestRandom;
|
||||
use crate::{Checkpoint, ForkName, Hash256, SignedRoot, Slot};
|
||||
use context_deserialize::context_deserialize;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use ssz_derive::{Decode, Encode};
|
||||
use test_random_derive::TestRandom;
|
||||
use tree_hash_derive::TreeHash;
|
||||
|
||||
use crate::{
|
||||
attestation::Checkpoint,
|
||||
core::{Hash256, SignedRoot, Slot, SlotData},
|
||||
fork::ForkName,
|
||||
test_utils::TestRandom,
|
||||
};
|
||||
|
||||
/// The data upon which an attestation is based.
|
||||
///
|
||||
/// Spec v0.12.1
|
||||
@@ -1,6 +1,7 @@
|
||||
use crate::*;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use crate::{attestation::CommitteeIndex, core::Slot};
|
||||
|
||||
#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
|
||||
#[derive(Debug, PartialEq, Clone, Copy, Default, Serialize, Deserialize)]
|
||||
pub struct AttestationDuty {
|
||||
@@ -1,4 +1,4 @@
|
||||
use crate::*;
|
||||
use crate::{attestation::CommitteeIndex, core::Slot};
|
||||
|
||||
#[derive(Default, Clone, Debug, PartialEq)]
|
||||
pub struct BeaconCommittee<'a> {
|
||||
@@ -1,11 +1,15 @@
|
||||
use crate::test_utils::TestRandom;
|
||||
use crate::{Epoch, ForkName, Hash256};
|
||||
use context_deserialize::context_deserialize;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use ssz_derive::{Decode, Encode};
|
||||
use test_random_derive::TestRandom;
|
||||
use tree_hash_derive::TreeHash;
|
||||
|
||||
use crate::{
|
||||
core::{Epoch, Hash256},
|
||||
fork::ForkName,
|
||||
test_utils::TestRandom,
|
||||
};
|
||||
|
||||
/// Casper FFG checkpoint, used in attestations.
|
||||
///
|
||||
/// Spec v0.12.1
|
||||
@@ -1,17 +1,21 @@
|
||||
use crate::context_deserialize;
|
||||
use crate::{
|
||||
AggregateSignature, AttestationData, EthSpec, ForkName, VariableList, test_utils::TestRandom,
|
||||
use std::{
|
||||
hash::{Hash, Hasher},
|
||||
slice::Iter,
|
||||
};
|
||||
use core::slice::Iter;
|
||||
|
||||
use bls::AggregateSignature;
|
||||
use context_deserialize::context_deserialize;
|
||||
use educe::Educe;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use ssz::Encode;
|
||||
use ssz_derive::{Decode, Encode};
|
||||
use std::hash::{Hash, Hasher};
|
||||
use ssz_types::VariableList;
|
||||
use superstruct::superstruct;
|
||||
use test_random_derive::TestRandom;
|
||||
use tree_hash_derive::TreeHash;
|
||||
|
||||
use crate::{attestation::AttestationData, core::EthSpec, fork::ForkName, test_utils::TestRandom};
|
||||
|
||||
/// Details an attestation that can be slashable.
|
||||
///
|
||||
/// To be included in an `AttesterSlashing`.
|
||||
@@ -208,9 +212,10 @@ impl<E: EthSpec> Hash for IndexedAttestation<E> {
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use crate::MainnetEthSpec;
|
||||
use crate::slot_epoch::Epoch;
|
||||
use crate::test_utils::{SeedableRng, XorShiftRng};
|
||||
use crate::{
|
||||
core::{Epoch, MainnetEthSpec},
|
||||
test_utils::{SeedableRng, XorShiftRng},
|
||||
};
|
||||
|
||||
#[test]
|
||||
pub fn test_is_double_vote_true() {
|
||||
39
consensus/types/src/attestation/mod.rs
Normal file
39
consensus/types/src/attestation/mod.rs
Normal file
@@ -0,0 +1,39 @@
|
||||
mod aggregate_and_proof;
|
||||
mod attestation;
|
||||
mod attestation_data;
|
||||
mod attestation_duty;
|
||||
mod beacon_committee;
|
||||
mod checkpoint;
|
||||
mod indexed_attestation;
|
||||
mod participation_flags;
|
||||
mod pending_attestation;
|
||||
mod selection_proof;
|
||||
mod shuffling_id;
|
||||
mod signed_aggregate_and_proof;
|
||||
mod subnet_id;
|
||||
|
||||
pub use aggregate_and_proof::{
|
||||
AggregateAndProof, AggregateAndProofBase, AggregateAndProofElectra, AggregateAndProofRef,
|
||||
};
|
||||
pub use attestation::{
|
||||
Attestation, AttestationBase, AttestationElectra, AttestationOnDisk, AttestationRef,
|
||||
AttestationRefMut, AttestationRefOnDisk, Error as AttestationError, SingleAttestation,
|
||||
};
|
||||
pub use attestation_data::AttestationData;
|
||||
pub use attestation_duty::AttestationDuty;
|
||||
pub use beacon_committee::{BeaconCommittee, OwnedBeaconCommittee};
|
||||
pub use checkpoint::Checkpoint;
|
||||
pub use indexed_attestation::{
|
||||
IndexedAttestation, IndexedAttestationBase, IndexedAttestationElectra, IndexedAttestationRef,
|
||||
};
|
||||
pub use participation_flags::ParticipationFlags;
|
||||
pub use pending_attestation::PendingAttestation;
|
||||
pub use selection_proof::SelectionProof;
|
||||
pub use shuffling_id::AttestationShufflingId;
|
||||
pub use signed_aggregate_and_proof::{
|
||||
SignedAggregateAndProof, SignedAggregateAndProofBase, SignedAggregateAndProofElectra,
|
||||
SignedAggregateAndProofRefMut,
|
||||
};
|
||||
pub use subnet_id::SubnetId;
|
||||
|
||||
pub type CommitteeIndex = u64;
|
||||
@@ -1,10 +1,14 @@
|
||||
use crate::{Hash256, consts::altair::NUM_FLAG_INDICES, test_utils::TestRandom};
|
||||
use safe_arith::{ArithError, SafeArith};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use ssz::{Decode, DecodeError, Encode};
|
||||
use test_random_derive::TestRandom;
|
||||
use tree_hash::{PackedEncoding, TreeHash, TreeHashType};
|
||||
|
||||
use crate::{
|
||||
core::{Hash256, consts::altair::NUM_FLAG_INDICES},
|
||||
test_utils::TestRandom,
|
||||
};
|
||||
|
||||
#[derive(Debug, Default, Clone, Copy, PartialEq, Deserialize, Serialize, TestRandom)]
|
||||
#[serde(transparent)]
|
||||
#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
|
||||
@@ -1,11 +1,12 @@
|
||||
use crate::context_deserialize;
|
||||
use crate::test_utils::TestRandom;
|
||||
use crate::{AttestationData, BitList, EthSpec, ForkName};
|
||||
use context_deserialize::context_deserialize;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use ssz_derive::{Decode, Encode};
|
||||
use ssz_types::BitList;
|
||||
use test_random_derive::TestRandom;
|
||||
use tree_hash_derive::TreeHash;
|
||||
|
||||
use crate::{attestation::AttestationData, core::EthSpec, fork::ForkName, test_utils::TestRandom};
|
||||
|
||||
/// An attestation that has been included in the state but not yet fully processed.
|
||||
///
|
||||
/// Spec v0.12.1
|
||||
@@ -1,11 +1,15 @@
|
||||
use crate::{
|
||||
ChainSpec, Domain, EthSpec, Fork, Hash256, PublicKey, SecretKey, Signature, SignedRoot, Slot,
|
||||
};
|
||||
use std::cmp;
|
||||
|
||||
use bls::{PublicKey, SecretKey, Signature};
|
||||
use ethereum_hashing::hash;
|
||||
use safe_arith::{ArithError, SafeArith};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use ssz::Encode;
|
||||
use std::cmp;
|
||||
|
||||
use crate::{
|
||||
core::{ChainSpec, Domain, EthSpec, Hash256, SignedRoot, Slot},
|
||||
fork::Fork,
|
||||
};
|
||||
|
||||
#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
|
||||
#[derive(PartialEq, Debug, Clone, Serialize, Deserialize)]
|
||||
@@ -1,7 +1,12 @@
|
||||
use crate::*;
|
||||
use std::hash::Hash;
|
||||
|
||||
use serde::{Deserialize, Serialize};
|
||||
use ssz_derive::{Decode, Encode};
|
||||
use std::hash::Hash;
|
||||
|
||||
use crate::{
|
||||
core::{Epoch, EthSpec, Hash256, RelativeEpoch},
|
||||
state::{BeaconState, BeaconStateError},
|
||||
};
|
||||
|
||||
/// Can be used to key (ID) the shuffling in some chain, in some epoch.
|
||||
///
|
||||
@@ -1,18 +1,21 @@
|
||||
use super::{
|
||||
AggregateAndProof, AggregateAndProofBase, AggregateAndProofElectra, AggregateAndProofRef,
|
||||
};
|
||||
use super::{
|
||||
Attestation, AttestationRef, ChainSpec, Domain, EthSpec, Fork, ForkName, Hash256, SecretKey,
|
||||
SelectionProof, Signature, SignedRoot,
|
||||
};
|
||||
use crate::context_deserialize;
|
||||
use crate::test_utils::TestRandom;
|
||||
use bls::{SecretKey, Signature};
|
||||
use context_deserialize::context_deserialize;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use ssz_derive::{Decode, Encode};
|
||||
use superstruct::superstruct;
|
||||
use test_random_derive::TestRandom;
|
||||
use tree_hash_derive::TreeHash;
|
||||
|
||||
use crate::{
|
||||
attestation::{
|
||||
AggregateAndProof, AggregateAndProofBase, AggregateAndProofElectra, AggregateAndProofRef,
|
||||
Attestation, AttestationRef, SelectionProof,
|
||||
},
|
||||
core::{ChainSpec, Domain, EthSpec, Hash256, SignedRoot},
|
||||
fork::{Fork, ForkName},
|
||||
test_utils::TestRandom,
|
||||
};
|
||||
|
||||
/// A Validators signed aggregate proof to publish on the `beacon_aggregate_and_proof`
|
||||
/// gossipsub topic.
|
||||
///
|
||||
@@ -1,11 +1,17 @@
|
||||
//! Identifies each shard by an integer identifier.
|
||||
use crate::SingleAttestation;
|
||||
use crate::{AttestationRef, ChainSpec, CommitteeIndex, EthSpec, Slot};
|
||||
use std::{
|
||||
ops::{Deref, DerefMut},
|
||||
sync::LazyLock,
|
||||
};
|
||||
|
||||
use alloy_primitives::{U256, bytes::Buf};
|
||||
use safe_arith::{ArithError, SafeArith};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::ops::{Deref, DerefMut};
|
||||
use std::sync::LazyLock;
|
||||
|
||||
use crate::{
|
||||
attestation::{AttestationRef, CommitteeIndex, SingleAttestation},
|
||||
core::{ChainSpec, EthSpec, Slot},
|
||||
};
|
||||
|
||||
const MAX_SUBNET_ID: usize = 64;
|
||||
|
||||
@@ -1,261 +0,0 @@
|
||||
use crate::{ContextDeserialize, ForkName};
|
||||
use serde::de::DeserializeOwned;
|
||||
use serde::{Deserialize, Deserializer, Serialize};
|
||||
use serde_json::value::Value;
|
||||
|
||||
pub trait ForkVersionDecode: Sized {
|
||||
/// SSZ decode with explicit fork variant.
|
||||
fn from_ssz_bytes_by_fork(bytes: &[u8], fork_name: ForkName) -> Result<Self, ssz::DecodeError>;
|
||||
}
|
||||
|
||||
/// The metadata of type M should be set to `EmptyMetadata` if you don't care about adding fields other than
|
||||
/// version. If you *do* care about adding other fields you can mix in any type that implements
|
||||
/// `Deserialize`.
|
||||
#[derive(Debug, PartialEq, Clone, Serialize)]
|
||||
pub struct ForkVersionedResponse<T, M = EmptyMetadata> {
|
||||
pub version: ForkName,
|
||||
#[serde(flatten)]
|
||||
pub metadata: M,
|
||||
pub data: T,
|
||||
}
|
||||
|
||||
// Used for responses to V1 endpoints that don't have a version field.
|
||||
/// The metadata of type M should be set to `EmptyMetadata` if you don't care about adding fields other than
|
||||
/// version. If you *do* care about adding other fields you can mix in any type that implements
|
||||
/// `Deserialize`.
|
||||
#[derive(Debug, PartialEq, Clone, Serialize)]
|
||||
pub struct UnversionedResponse<T, M = EmptyMetadata> {
|
||||
#[serde(flatten)]
|
||||
pub metadata: M,
|
||||
pub data: T,
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq, Clone, Serialize)]
|
||||
#[serde(untagged)]
|
||||
pub enum BeaconResponse<T, M = EmptyMetadata> {
|
||||
ForkVersioned(ForkVersionedResponse<T, M>),
|
||||
Unversioned(UnversionedResponse<T, M>),
|
||||
}
|
||||
|
||||
impl<T, M> BeaconResponse<T, M> {
|
||||
pub fn version(&self) -> Option<ForkName> {
|
||||
match self {
|
||||
BeaconResponse::ForkVersioned(response) => Some(response.version),
|
||||
BeaconResponse::Unversioned(_) => None,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn data(&self) -> &T {
|
||||
match self {
|
||||
BeaconResponse::ForkVersioned(response) => &response.data,
|
||||
BeaconResponse::Unversioned(response) => &response.data,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn metadata(&self) -> &M {
|
||||
match self {
|
||||
BeaconResponse::ForkVersioned(response) => &response.metadata,
|
||||
BeaconResponse::Unversioned(response) => &response.metadata,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Metadata type similar to unit (i.e. `()`) but deserializes from a map (`serde_json::Value`).
|
||||
///
|
||||
/// Unfortunately the braces are semantically significant, i.e. `struct EmptyMetadata;` does not
|
||||
/// work.
|
||||
#[derive(Debug, PartialEq, Clone, Default, Deserialize, Serialize)]
|
||||
pub struct EmptyMetadata {}
|
||||
|
||||
/// Fork versioned response with extra information about finalization & optimistic execution.
|
||||
pub type ExecutionOptimisticFinalizedBeaconResponse<T> =
|
||||
BeaconResponse<T, ExecutionOptimisticFinalizedMetadata>;
|
||||
|
||||
#[derive(Debug, PartialEq, Clone, Serialize, Deserialize)]
|
||||
pub struct ExecutionOptimisticFinalizedMetadata {
|
||||
pub execution_optimistic: Option<bool>,
|
||||
pub finalized: Option<bool>,
|
||||
}
|
||||
|
||||
impl<'de, T, M> Deserialize<'de> for ForkVersionedResponse<T, M>
|
||||
where
|
||||
T: ContextDeserialize<'de, ForkName>,
|
||||
M: DeserializeOwned,
|
||||
{
|
||||
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
|
||||
where
|
||||
D: Deserializer<'de>,
|
||||
{
|
||||
#[derive(Deserialize)]
|
||||
struct Helper {
|
||||
version: ForkName,
|
||||
#[serde(flatten)]
|
||||
metadata: Value,
|
||||
data: Value,
|
||||
}
|
||||
|
||||
let helper = Helper::deserialize(deserializer)?;
|
||||
|
||||
// Deserialize metadata
|
||||
let metadata = serde_json::from_value(helper.metadata).map_err(serde::de::Error::custom)?;
|
||||
|
||||
// Deserialize `data` using ContextDeserialize
|
||||
let data = T::context_deserialize(helper.data, helper.version)
|
||||
.map_err(serde::de::Error::custom)?;
|
||||
|
||||
Ok(ForkVersionedResponse {
|
||||
version: helper.version,
|
||||
metadata,
|
||||
data,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl<'de, T, M> Deserialize<'de> for UnversionedResponse<T, M>
|
||||
where
|
||||
T: DeserializeOwned,
|
||||
M: DeserializeOwned,
|
||||
{
|
||||
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
|
||||
where
|
||||
D: Deserializer<'de>,
|
||||
{
|
||||
#[derive(Deserialize)]
|
||||
struct Helper<T, M> {
|
||||
#[serde(flatten)]
|
||||
metadata: M,
|
||||
data: T,
|
||||
}
|
||||
|
||||
let helper = Helper::deserialize(deserializer)?;
|
||||
|
||||
Ok(UnversionedResponse {
|
||||
metadata: helper.metadata,
|
||||
data: helper.data,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl<T, M> BeaconResponse<T, M> {
|
||||
pub fn map_data<U>(self, f: impl FnOnce(T) -> U) -> BeaconResponse<U, M> {
|
||||
match self {
|
||||
BeaconResponse::ForkVersioned(response) => {
|
||||
BeaconResponse::ForkVersioned(response.map_data(f))
|
||||
}
|
||||
BeaconResponse::Unversioned(response) => {
|
||||
BeaconResponse::Unversioned(response.map_data(f))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn into_data(self) -> T {
|
||||
match self {
|
||||
BeaconResponse::ForkVersioned(response) => response.data,
|
||||
BeaconResponse::Unversioned(response) => response.data,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T, M> UnversionedResponse<T, M> {
|
||||
pub fn map_data<U>(self, f: impl FnOnce(T) -> U) -> UnversionedResponse<U, M> {
|
||||
let UnversionedResponse { metadata, data } = self;
|
||||
UnversionedResponse {
|
||||
metadata,
|
||||
data: f(data),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T, M> ForkVersionedResponse<T, M> {
|
||||
/// Apply a function to the inner `data`, potentially changing its type.
|
||||
pub fn map_data<U>(self, f: impl FnOnce(T) -> U) -> ForkVersionedResponse<U, M> {
|
||||
let ForkVersionedResponse {
|
||||
version,
|
||||
metadata,
|
||||
data,
|
||||
} = self;
|
||||
ForkVersionedResponse {
|
||||
version,
|
||||
metadata,
|
||||
data: f(data),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T, M> From<ForkVersionedResponse<T, M>> for BeaconResponse<T, M> {
|
||||
fn from(response: ForkVersionedResponse<T, M>) -> Self {
|
||||
BeaconResponse::ForkVersioned(response)
|
||||
}
|
||||
}
|
||||
|
||||
impl<T, M> From<UnversionedResponse<T, M>> for BeaconResponse<T, M> {
|
||||
fn from(response: UnversionedResponse<T, M>) -> Self {
|
||||
BeaconResponse::Unversioned(response)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod fork_version_response_tests {
|
||||
use crate::beacon_response::ExecutionOptimisticFinalizedMetadata;
|
||||
use crate::{
|
||||
ExecutionPayload, ExecutionPayloadBellatrix, ForkName, ForkVersionedResponse,
|
||||
MainnetEthSpec, UnversionedResponse,
|
||||
};
|
||||
use serde_json::json;
|
||||
|
||||
#[test]
|
||||
fn fork_versioned_response_deserialize_correct_fork() {
|
||||
type E = MainnetEthSpec;
|
||||
|
||||
let response_json =
|
||||
serde_json::to_string(&json!(ForkVersionedResponse::<ExecutionPayload<E>> {
|
||||
version: ForkName::Bellatrix,
|
||||
metadata: Default::default(),
|
||||
data: ExecutionPayload::Bellatrix(ExecutionPayloadBellatrix::default()),
|
||||
}))
|
||||
.unwrap();
|
||||
|
||||
let result: Result<ForkVersionedResponse<ExecutionPayload<E>>, _> =
|
||||
serde_json::from_str(&response_json);
|
||||
|
||||
assert!(result.is_ok());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn fork_versioned_response_deserialize_incorrect_fork() {
|
||||
type E = MainnetEthSpec;
|
||||
|
||||
let response_json =
|
||||
serde_json::to_string(&json!(ForkVersionedResponse::<ExecutionPayload<E>> {
|
||||
version: ForkName::Capella,
|
||||
metadata: Default::default(),
|
||||
data: ExecutionPayload::Bellatrix(ExecutionPayloadBellatrix::default()),
|
||||
}))
|
||||
.unwrap();
|
||||
|
||||
let result: Result<ForkVersionedResponse<ExecutionPayload<E>>, _> =
|
||||
serde_json::from_str(&response_json);
|
||||
|
||||
assert!(result.is_err());
|
||||
}
|
||||
|
||||
// The following test should only pass by having the attribute #[serde(flatten)] on the metadata
|
||||
#[test]
|
||||
fn unversioned_response_serialize_dezerialize_round_trip_test() {
|
||||
// Create an UnversionedResponse with some data
|
||||
let data = UnversionedResponse {
|
||||
metadata: ExecutionOptimisticFinalizedMetadata {
|
||||
execution_optimistic: Some(false),
|
||||
finalized: Some(false),
|
||||
},
|
||||
data: "some_test_data".to_string(),
|
||||
};
|
||||
|
||||
let serialized = serde_json::to_string(&data);
|
||||
|
||||
let deserialized =
|
||||
serde_json::from_str(&serialized.unwrap()).expect("Failed to deserialize");
|
||||
|
||||
assert_eq!(data, deserialized);
|
||||
}
|
||||
}
|
||||
@@ -1,18 +1,39 @@
|
||||
use crate::attestation::AttestationBase;
|
||||
use crate::test_utils::TestRandom;
|
||||
use crate::*;
|
||||
use std::{fmt, marker::PhantomData};
|
||||
|
||||
use bls::{AggregateSignature, PublicKeyBytes, SecretKey, Signature, SignatureBytes};
|
||||
use context_deserialize::ContextDeserialize;
|
||||
use educe::Educe;
|
||||
use fixed_bytes::FixedBytesExtended;
|
||||
use serde::{Deserialize, Deserializer, Serialize};
|
||||
use ssz::{Decode, DecodeError};
|
||||
use ssz_derive::{Decode, Encode};
|
||||
use std::fmt;
|
||||
use std::marker::PhantomData;
|
||||
use ssz_types::{BitList, BitVector, FixedVector, VariableList, typenum::Unsigned};
|
||||
use superstruct::superstruct;
|
||||
use test_random_derive::TestRandom;
|
||||
use tree_hash::TreeHash;
|
||||
use tree_hash_derive::TreeHash;
|
||||
|
||||
use self::indexed_attestation::IndexedAttestationBase;
|
||||
use crate::{
|
||||
attestation::{AttestationBase, AttestationData, IndexedAttestationBase},
|
||||
block::{
|
||||
BeaconBlockBodyAltair, BeaconBlockBodyBase, BeaconBlockBodyBellatrix,
|
||||
BeaconBlockBodyCapella, BeaconBlockBodyDeneb, BeaconBlockBodyElectra, BeaconBlockBodyFulu,
|
||||
BeaconBlockBodyGloas, BeaconBlockBodyRef, BeaconBlockBodyRefMut, BeaconBlockHeader,
|
||||
SignedBeaconBlock, SignedBeaconBlockHeader,
|
||||
},
|
||||
core::{ChainSpec, Domain, Epoch, EthSpec, Graffiti, Hash256, SignedRoot, Slot},
|
||||
deposit::{Deposit, DepositData},
|
||||
execution::{
|
||||
AbstractExecPayload, BlindedPayload, Eth1Data, ExecutionPayload, ExecutionRequests,
|
||||
FullPayload,
|
||||
},
|
||||
exit::{SignedVoluntaryExit, VoluntaryExit},
|
||||
fork::{Fork, ForkName, InconsistentFork, map_fork_name},
|
||||
slashing::{AttesterSlashingBase, ProposerSlashing},
|
||||
state::BeaconStateError,
|
||||
sync_committee::SyncAggregate,
|
||||
test_utils::TestRandom,
|
||||
};
|
||||
|
||||
/// A block of the `BeaconChain`.
|
||||
#[superstruct(
|
||||
@@ -283,7 +304,7 @@ impl<'a, E: EthSpec, Payload: AbstractExecPayload<E>> BeaconBlockRef<'a, E, Payl
|
||||
|
||||
/// Extracts a reference to an execution payload from a block, returning an error if the block
|
||||
/// is pre-merge.
|
||||
pub fn execution_payload(&self) -> Result<Payload::Ref<'a>, Error> {
|
||||
pub fn execution_payload(&self) -> Result<Payload::Ref<'a>, BeaconStateError> {
|
||||
self.body().execution_payload()
|
||||
}
|
||||
}
|
||||
@@ -865,7 +886,10 @@ impl fmt::Display for BlockImportSource {
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use crate::test_utils::{SeedableRng, XorShiftRng, test_ssz_tree_hash_pair_with};
|
||||
use crate::{
|
||||
core::MainnetEthSpec,
|
||||
test_utils::{SeedableRng, XorShiftRng, test_ssz_tree_hash_pair_with},
|
||||
};
|
||||
use ssz::Encode;
|
||||
|
||||
type BeaconBlock = super::BeaconBlock<MainnetEthSpec>;
|
||||
@@ -1,18 +1,42 @@
|
||||
use crate::test_utils::TestRandom;
|
||||
use crate::*;
|
||||
use std::marker::PhantomData;
|
||||
|
||||
use bls::Signature;
|
||||
use context_deserialize::{ContextDeserialize, context_deserialize};
|
||||
use educe::Educe;
|
||||
use merkle_proof::{MerkleTree, MerkleTreeError};
|
||||
use metastruct::metastruct;
|
||||
use serde::{Deserialize, Deserializer, Serialize};
|
||||
use ssz_derive::{Decode, Encode};
|
||||
use std::marker::PhantomData;
|
||||
use ssz_types::{FixedVector, VariableList};
|
||||
use superstruct::superstruct;
|
||||
use test_random_derive::TestRandom;
|
||||
use tree_hash::{BYTES_PER_CHUNK, TreeHash};
|
||||
use tree_hash_derive::TreeHash;
|
||||
|
||||
pub type KzgCommitments<E> =
|
||||
VariableList<KzgCommitment, <E as EthSpec>::MaxBlobCommitmentsPerBlock>;
|
||||
use crate::{
|
||||
attestation::{AttestationBase, AttestationElectra, AttestationRef, AttestationRefMut},
|
||||
core::{EthSpec, Graffiti, Hash256},
|
||||
deposit::Deposit,
|
||||
execution::{
|
||||
AbstractExecPayload, BlindedPayload, BlindedPayloadBellatrix, BlindedPayloadCapella,
|
||||
BlindedPayloadDeneb, BlindedPayloadElectra, BlindedPayloadFulu, BlindedPayloadGloas,
|
||||
Eth1Data, ExecutionPayload, ExecutionPayloadBellatrix, ExecutionPayloadCapella,
|
||||
ExecutionPayloadDeneb, ExecutionPayloadElectra, ExecutionPayloadFulu,
|
||||
ExecutionPayloadGloas, ExecutionRequests, FullPayload, FullPayloadBellatrix,
|
||||
FullPayloadCapella, FullPayloadDeneb, FullPayloadElectra, FullPayloadFulu,
|
||||
FullPayloadGloas, SignedBlsToExecutionChange,
|
||||
},
|
||||
exit::SignedVoluntaryExit,
|
||||
fork::{ForkName, map_fork_name},
|
||||
kzg_ext::KzgCommitments,
|
||||
light_client::consts::{EXECUTION_PAYLOAD_INDEX, EXECUTION_PAYLOAD_PROOF_LEN},
|
||||
slashing::{
|
||||
AttesterSlashingBase, AttesterSlashingElectra, AttesterSlashingRef, ProposerSlashing,
|
||||
},
|
||||
state::BeaconStateError,
|
||||
sync_committee::SyncAggregate,
|
||||
test_utils::TestRandom,
|
||||
};
|
||||
|
||||
/// The number of leaves (including padding) on the `BeaconBlockBody` Merkle tree.
|
||||
///
|
||||
@@ -63,8 +87,14 @@ pub const BLOB_KZG_COMMITMENTS_INDEX: usize = 11;
|
||||
Fulu(metastruct(mappings(beacon_block_body_fulu_fields(groups(fields))))),
|
||||
Gloas(metastruct(mappings(beacon_block_body_gloas_fields(groups(fields))))),
|
||||
),
|
||||
cast_error(ty = "Error", expr = "Error::IncorrectStateVariant"),
|
||||
partial_getter_error(ty = "Error", expr = "Error::IncorrectStateVariant")
|
||||
cast_error(
|
||||
ty = "BeaconStateError",
|
||||
expr = "BeaconStateError::IncorrectStateVariant"
|
||||
),
|
||||
partial_getter_error(
|
||||
ty = "BeaconStateError",
|
||||
expr = "BeaconStateError::IncorrectStateVariant"
|
||||
)
|
||||
)]
|
||||
#[cfg_attr(
|
||||
feature = "arbitrary",
|
||||
@@ -147,7 +177,7 @@ pub struct BeaconBlockBody<E: EthSpec, Payload: AbstractExecPayload<E> = FullPay
|
||||
}
|
||||
|
||||
impl<E: EthSpec, Payload: AbstractExecPayload<E>> BeaconBlockBody<E, Payload> {
|
||||
pub fn execution_payload(&self) -> Result<Payload::Ref<'_>, Error> {
|
||||
pub fn execution_payload(&self) -> Result<Payload::Ref<'_>, BeaconStateError> {
|
||||
self.to_ref().execution_payload()
|
||||
}
|
||||
|
||||
@@ -158,9 +188,9 @@ impl<E: EthSpec, Payload: AbstractExecPayload<E>> BeaconBlockBody<E, Payload> {
|
||||
}
|
||||
|
||||
impl<'a, E: EthSpec, Payload: AbstractExecPayload<E>> BeaconBlockBodyRef<'a, E, Payload> {
|
||||
pub fn execution_payload(&self) -> Result<Payload::Ref<'a>, Error> {
|
||||
pub fn execution_payload(&self) -> Result<Payload::Ref<'a>, BeaconStateError> {
|
||||
match self {
|
||||
Self::Base(_) | Self::Altair(_) => Err(Error::IncorrectStateVariant),
|
||||
Self::Base(_) | Self::Altair(_) => Err(BeaconStateError::IncorrectStateVariant),
|
||||
Self::Bellatrix(body) => Ok(Payload::Ref::from(&body.execution_payload)),
|
||||
Self::Capella(body) => Ok(Payload::Ref::from(&body.execution_payload)),
|
||||
Self::Deneb(body) => Ok(Payload::Ref::from(&body.execution_payload)),
|
||||
@@ -216,7 +246,7 @@ impl<'a, E: EthSpec, Payload: AbstractExecPayload<E>> BeaconBlockBodyRef<'a, E,
|
||||
pub fn kzg_commitment_merkle_proof(
|
||||
&self,
|
||||
index: usize,
|
||||
) -> Result<FixedVector<Hash256, E::KzgCommitmentInclusionProofDepth>, Error> {
|
||||
) -> Result<FixedVector<Hash256, E::KzgCommitmentInclusionProofDepth>, BeaconStateError> {
|
||||
let kzg_commitments_proof = self.kzg_commitments_merkle_proof()?;
|
||||
let proof = self.complete_kzg_commitment_merkle_proof(index, &kzg_commitments_proof)?;
|
||||
Ok(proof)
|
||||
@@ -228,10 +258,10 @@ impl<'a, E: EthSpec, Payload: AbstractExecPayload<E>> BeaconBlockBodyRef<'a, E,
|
||||
&self,
|
||||
index: usize,
|
||||
kzg_commitments_proof: &[Hash256],
|
||||
) -> Result<FixedVector<Hash256, E::KzgCommitmentInclusionProofDepth>, Error> {
|
||||
) -> Result<FixedVector<Hash256, E::KzgCommitmentInclusionProofDepth>, BeaconStateError> {
|
||||
match self {
|
||||
Self::Base(_) | Self::Altair(_) | Self::Bellatrix(_) | Self::Capella(_) => {
|
||||
Err(Error::IncorrectStateVariant)
|
||||
Err(BeaconStateError::IncorrectStateVariant)
|
||||
}
|
||||
Self::Deneb(_) | Self::Electra(_) | Self::Fulu(_) | Self::Gloas(_) => {
|
||||
// We compute the branches by generating 2 merkle trees:
|
||||
@@ -253,7 +283,7 @@ impl<'a, E: EthSpec, Payload: AbstractExecPayload<E>> BeaconBlockBodyRef<'a, E,
|
||||
let tree = MerkleTree::create(&blob_leaves, depth as usize);
|
||||
let (_, mut proof) = tree
|
||||
.generate_proof(index, depth as usize)
|
||||
.map_err(Error::MerkleTreeError)?;
|
||||
.map_err(BeaconStateError::MerkleTreeError)?;
|
||||
|
||||
// Add the branch corresponding to the length mix-in.
|
||||
let length = blob_leaves.len();
|
||||
@@ -261,7 +291,9 @@ impl<'a, E: EthSpec, Payload: AbstractExecPayload<E>> BeaconBlockBodyRef<'a, E,
|
||||
let mut length_bytes = [0; BYTES_PER_CHUNK];
|
||||
length_bytes
|
||||
.get_mut(0..usize_len)
|
||||
.ok_or(Error::MerkleTreeError(MerkleTreeError::PleaseNotifyTheDevs))?
|
||||
.ok_or(BeaconStateError::MerkleTreeError(
|
||||
MerkleTreeError::PleaseNotifyTheDevs,
|
||||
))?
|
||||
.copy_from_slice(&length.to_le_bytes());
|
||||
let length_root = Hash256::from_slice(length_bytes.as_slice());
|
||||
proof.push(length_root);
|
||||
@@ -279,32 +311,41 @@ impl<'a, E: EthSpec, Payload: AbstractExecPayload<E>> BeaconBlockBodyRef<'a, E,
|
||||
/// Produces the proof of inclusion for `self.blob_kzg_commitments`.
|
||||
pub fn kzg_commitments_merkle_proof(
|
||||
&self,
|
||||
) -> Result<FixedVector<Hash256, E::KzgCommitmentsInclusionProofDepth>, Error> {
|
||||
) -> Result<FixedVector<Hash256, E::KzgCommitmentsInclusionProofDepth>, BeaconStateError> {
|
||||
let body_leaves = self.body_merkle_leaves();
|
||||
let beacon_block_body_depth = body_leaves.len().next_power_of_two().ilog2() as usize;
|
||||
let tree = MerkleTree::create(&body_leaves, beacon_block_body_depth);
|
||||
let (_, proof) = tree
|
||||
.generate_proof(BLOB_KZG_COMMITMENTS_INDEX, beacon_block_body_depth)
|
||||
.map_err(Error::MerkleTreeError)?;
|
||||
.map_err(BeaconStateError::MerkleTreeError)?;
|
||||
Ok(FixedVector::new(proof)?)
|
||||
}
|
||||
|
||||
pub fn block_body_merkle_proof(&self, generalized_index: usize) -> Result<Vec<Hash256>, Error> {
|
||||
pub fn block_body_merkle_proof(
|
||||
&self,
|
||||
generalized_index: usize,
|
||||
) -> Result<Vec<Hash256>, BeaconStateError> {
|
||||
let field_index = match generalized_index {
|
||||
light_client_update::EXECUTION_PAYLOAD_INDEX => {
|
||||
EXECUTION_PAYLOAD_INDEX => {
|
||||
// Execution payload is a top-level field, subtract off the generalized indices
|
||||
// for the internal nodes. Result should be 9, the field offset of the execution
|
||||
// payload in the `BeaconBlockBody`:
|
||||
// https://github.com/ethereum/consensus-specs/blob/dev/specs/deneb/beacon-chain.md#beaconblockbody
|
||||
generalized_index
|
||||
.checked_sub(NUM_BEACON_BLOCK_BODY_HASH_TREE_ROOT_LEAVES)
|
||||
.ok_or(Error::GeneralizedIndexNotSupported(generalized_index))?
|
||||
.ok_or(BeaconStateError::GeneralizedIndexNotSupported(
|
||||
generalized_index,
|
||||
))?
|
||||
}
|
||||
_ => {
|
||||
return Err(BeaconStateError::GeneralizedIndexNotSupported(
|
||||
generalized_index,
|
||||
));
|
||||
}
|
||||
_ => return Err(Error::GeneralizedIndexNotSupported(generalized_index)),
|
||||
};
|
||||
|
||||
let leaves = self.body_merkle_leaves();
|
||||
let depth = light_client_update::EXECUTION_PAYLOAD_PROOF_LEN;
|
||||
let depth = EXECUTION_PAYLOAD_PROOF_LEN;
|
||||
let tree = merkle_proof::MerkleTree::create(&leaves, depth);
|
||||
let (_, proof) = tree.generate_proof(field_index, depth)?;
|
||||
|
||||
@@ -1100,22 +1141,16 @@ impl<'de, E: EthSpec, Payload: AbstractExecPayload<E>> ContextDeserialize<'de, F
|
||||
}
|
||||
}
|
||||
|
||||
/// Util method helpful for logging.
|
||||
pub fn format_kzg_commitments(commitments: &[KzgCommitment]) -> String {
|
||||
let commitment_strings: Vec<String> = commitments.iter().map(|x| x.to_string()).collect();
|
||||
let commitments_joined = commitment_strings.join(", ");
|
||||
let surrounded_commitments = format!("[{}]", commitments_joined);
|
||||
surrounded_commitments
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
mod base {
|
||||
use super::super::*;
|
||||
use crate::core::MainnetEthSpec;
|
||||
ssz_and_tree_hash_tests!(BeaconBlockBodyBase<MainnetEthSpec>);
|
||||
}
|
||||
mod altair {
|
||||
use super::super::*;
|
||||
use crate::core::MainnetEthSpec;
|
||||
ssz_and_tree_hash_tests!(BeaconBlockBodyAltair<MainnetEthSpec>);
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,4 @@
|
||||
use crate::test_utils::TestRandom;
|
||||
use crate::*;
|
||||
|
||||
use bls::SecretKey;
|
||||
use context_deserialize::context_deserialize;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use ssz_derive::{Decode, Encode};
|
||||
@@ -8,6 +6,13 @@ use test_random_derive::TestRandom;
|
||||
use tree_hash::TreeHash;
|
||||
use tree_hash_derive::TreeHash;
|
||||
|
||||
use crate::{
|
||||
block::SignedBeaconBlockHeader,
|
||||
core::{ChainSpec, Domain, EthSpec, Hash256, SignedRoot, Slot},
|
||||
fork::{Fork, ForkName},
|
||||
test_utils::TestRandom,
|
||||
};
|
||||
|
||||
/// A header of a `BeaconBlock`.
|
||||
///
|
||||
/// Spec v0.12.1
|
||||
26
consensus/types/src/block/mod.rs
Normal file
26
consensus/types/src/block/mod.rs
Normal file
@@ -0,0 +1,26 @@
|
||||
mod beacon_block;
|
||||
mod beacon_block_body;
|
||||
mod beacon_block_header;
|
||||
mod signed_beacon_block;
|
||||
mod signed_beacon_block_header;
|
||||
|
||||
pub use beacon_block::{
|
||||
BeaconBlock, BeaconBlockAltair, BeaconBlockBase, BeaconBlockBellatrix, BeaconBlockCapella,
|
||||
BeaconBlockDeneb, BeaconBlockElectra, BeaconBlockFulu, BeaconBlockGloas, BeaconBlockRef,
|
||||
BeaconBlockRefMut, BlindedBeaconBlock, BlockImportSource, EmptyBlock,
|
||||
};
|
||||
pub use beacon_block_body::{
|
||||
BLOB_KZG_COMMITMENTS_INDEX, BeaconBlockBody, BeaconBlockBodyAltair, BeaconBlockBodyBase,
|
||||
BeaconBlockBodyBellatrix, BeaconBlockBodyCapella, BeaconBlockBodyDeneb, BeaconBlockBodyElectra,
|
||||
BeaconBlockBodyFulu, BeaconBlockBodyGloas, BeaconBlockBodyRef, BeaconBlockBodyRefMut,
|
||||
NUM_BEACON_BLOCK_BODY_HASH_TREE_ROOT_LEAVES,
|
||||
};
|
||||
pub use beacon_block_header::BeaconBlockHeader;
|
||||
|
||||
pub use signed_beacon_block::{
|
||||
SignedBeaconBlock, SignedBeaconBlockAltair, SignedBeaconBlockBase, SignedBeaconBlockBellatrix,
|
||||
SignedBeaconBlockCapella, SignedBeaconBlockDeneb, SignedBeaconBlockElectra,
|
||||
SignedBeaconBlockFulu, SignedBeaconBlockGloas, SignedBeaconBlockHash, SignedBlindedBeaconBlock,
|
||||
ssz_tagged_signed_beacon_block, ssz_tagged_signed_beacon_block_arc,
|
||||
};
|
||||
pub use signed_beacon_block_header::SignedBeaconBlockHeader;
|
||||
@@ -1,17 +1,42 @@
|
||||
use crate::beacon_block_body::{BLOB_KZG_COMMITMENTS_INDEX, format_kzg_commitments};
|
||||
use crate::test_utils::TestRandom;
|
||||
use crate::*;
|
||||
use std::fmt;
|
||||
|
||||
use bls::{PublicKey, Signature};
|
||||
use context_deserialize::ContextDeserialize;
|
||||
use educe::Educe;
|
||||
use merkle_proof::MerkleTree;
|
||||
use serde::{Deserialize, Deserializer, Serialize};
|
||||
use ssz_derive::{Decode, Encode};
|
||||
use std::fmt;
|
||||
use ssz_types::FixedVector;
|
||||
use superstruct::superstruct;
|
||||
use test_random_derive::TestRandom;
|
||||
use tracing::instrument;
|
||||
use tree_hash::TreeHash;
|
||||
use tree_hash_derive::TreeHash;
|
||||
|
||||
use crate::{
|
||||
block::{
|
||||
BLOB_KZG_COMMITMENTS_INDEX, BeaconBlock, BeaconBlockAltair, BeaconBlockBase,
|
||||
BeaconBlockBellatrix, BeaconBlockBodyBellatrix, BeaconBlockBodyCapella,
|
||||
BeaconBlockBodyDeneb, BeaconBlockBodyElectra, BeaconBlockBodyFulu, BeaconBlockBodyGloas,
|
||||
BeaconBlockCapella, BeaconBlockDeneb, BeaconBlockElectra, BeaconBlockFulu,
|
||||
BeaconBlockGloas, BeaconBlockHeader, BeaconBlockRef, BeaconBlockRefMut,
|
||||
SignedBeaconBlockHeader,
|
||||
},
|
||||
core::{ChainSpec, Domain, Epoch, EthSpec, Hash256, SignedRoot, SigningData, Slot},
|
||||
execution::{
|
||||
AbstractExecPayload, BlindedPayload, BlindedPayloadBellatrix, BlindedPayloadCapella,
|
||||
BlindedPayloadDeneb, BlindedPayloadElectra, BlindedPayloadFulu, BlindedPayloadGloas,
|
||||
ExecutionPayload, ExecutionPayloadBellatrix, ExecutionPayloadCapella,
|
||||
ExecutionPayloadDeneb, ExecutionPayloadElectra, ExecutionPayloadFulu,
|
||||
ExecutionPayloadGloas, FullPayload, FullPayloadBellatrix, FullPayloadCapella,
|
||||
FullPayloadDeneb, FullPayloadElectra, FullPayloadFulu, FullPayloadGloas,
|
||||
},
|
||||
fork::{Fork, ForkName, ForkVersionDecode, InconsistentFork, map_fork_name},
|
||||
kzg_ext::format_kzg_commitments,
|
||||
state::BeaconStateError,
|
||||
test_utils::TestRandom,
|
||||
};
|
||||
|
||||
#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
|
||||
#[derive(PartialEq, Eq, Hash, Clone, Copy)]
|
||||
pub struct SignedBeaconBlockHash(Hash256);
|
||||
@@ -272,7 +297,7 @@ impl<E: EthSpec, Payload: AbstractExecPayload<E>> SignedBeaconBlock<E, Payload>
|
||||
SignedBeaconBlockHeader,
|
||||
FixedVector<Hash256, E::KzgCommitmentsInclusionProofDepth>,
|
||||
),
|
||||
Error,
|
||||
BeaconStateError,
|
||||
> {
|
||||
// Create the block body merkle tree
|
||||
let body_leaves = self.message().body().body_merkle_leaves();
|
||||
@@ -282,7 +307,7 @@ impl<E: EthSpec, Payload: AbstractExecPayload<E>> SignedBeaconBlock<E, Payload>
|
||||
// Compute the KZG commitments inclusion proof
|
||||
let (_, proof) = body_merkle_tree
|
||||
.generate_proof(BLOB_KZG_COMMITMENTS_INDEX, beacon_block_body_depth)
|
||||
.map_err(Error::MerkleTreeError)?;
|
||||
.map_err(BeaconStateError::MerkleTreeError)?;
|
||||
let kzg_commitments_inclusion_proof = FixedVector::new(proof)?;
|
||||
|
||||
let block_header = BeaconBlockHeader {
|
||||
@@ -919,6 +944,7 @@ pub mod ssz_tagged_signed_beacon_block_arc {
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use super::*;
|
||||
use crate::{block::EmptyBlock, core::MainnetEthSpec};
|
||||
|
||||
#[test]
|
||||
fn add_remove_payload_roundtrip() {
|
||||
@@ -1,13 +1,17 @@
|
||||
use crate::context_deserialize;
|
||||
use crate::{
|
||||
BeaconBlockHeader, ChainSpec, Domain, EthSpec, Fork, ForkName, Hash256, PublicKey, Signature,
|
||||
SignedRoot, test_utils::TestRandom,
|
||||
};
|
||||
use bls::{PublicKey, Signature};
|
||||
use context_deserialize::context_deserialize;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use ssz_derive::{Decode, Encode};
|
||||
use test_random_derive::TestRandom;
|
||||
use tree_hash_derive::TreeHash;
|
||||
|
||||
use crate::{
|
||||
block::BeaconBlockHeader,
|
||||
core::{ChainSpec, Domain, EthSpec, Hash256, SignedRoot},
|
||||
fork::{Fork, ForkName},
|
||||
test_utils::TestRandom,
|
||||
};
|
||||
|
||||
/// A signed header of a `BeaconBlock`.
|
||||
///
|
||||
/// Spec v0.12.1
|
||||
@@ -1,13 +1,6 @@
|
||||
use crate::beacon_block_body::KzgCommitments;
|
||||
use crate::{
|
||||
ChainSpec, ContextDeserialize, EthSpec, ExecutionPayloadHeaderBellatrix,
|
||||
ExecutionPayloadHeaderCapella, ExecutionPayloadHeaderDeneb, ExecutionPayloadHeaderElectra,
|
||||
ExecutionPayloadHeaderFulu, ExecutionPayloadHeaderGloas, ExecutionPayloadHeaderRef,
|
||||
ExecutionPayloadHeaderRefMut, ExecutionRequests, ForkName, ForkVersionDecode, SignedRoot,
|
||||
Uint256, test_utils::TestRandom,
|
||||
};
|
||||
use bls::PublicKeyBytes;
|
||||
use bls::Signature;
|
||||
use context_deserialize::ContextDeserialize;
|
||||
use serde::{Deserialize, Deserializer, Serialize};
|
||||
use ssz::Decode;
|
||||
use ssz_derive::{Decode, Encode};
|
||||
@@ -15,6 +8,19 @@ use superstruct::superstruct;
|
||||
use test_random_derive::TestRandom;
|
||||
use tree_hash_derive::TreeHash;
|
||||
|
||||
use crate::{
|
||||
core::{ChainSpec, EthSpec, SignedRoot, Uint256},
|
||||
execution::{
|
||||
ExecutionPayloadHeaderBellatrix, ExecutionPayloadHeaderCapella,
|
||||
ExecutionPayloadHeaderDeneb, ExecutionPayloadHeaderElectra, ExecutionPayloadHeaderFulu,
|
||||
ExecutionPayloadHeaderGloas, ExecutionPayloadHeaderRef, ExecutionPayloadHeaderRefMut,
|
||||
ExecutionRequests,
|
||||
},
|
||||
fork::{ForkName, ForkVersionDecode},
|
||||
kzg_ext::KzgCommitments,
|
||||
test_utils::TestRandom,
|
||||
};
|
||||
|
||||
#[superstruct(
|
||||
variants(Bellatrix, Capella, Deneb, Electra, Fulu, Gloas),
|
||||
variant_attributes(
|
||||
6
consensus/types/src/builder/mod.rs
Normal file
6
consensus/types/src/builder/mod.rs
Normal file
@@ -0,0 +1,6 @@
|
||||
mod builder_bid;
|
||||
|
||||
pub use builder_bid::{
|
||||
BuilderBid, BuilderBidBellatrix, BuilderBidCapella, BuilderBidDeneb, BuilderBidElectra,
|
||||
BuilderBidFulu, BuilderBidGloas, SignedBuilderBid,
|
||||
};
|
||||
@@ -1,11 +1,17 @@
|
||||
use crate::context_deserialize;
|
||||
use crate::{Address, ForkName, PublicKeyBytes, SignedRoot, test_utils::TestRandom};
|
||||
use bls::PublicKeyBytes;
|
||||
use context_deserialize::context_deserialize;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use ssz::Encode;
|
||||
use ssz_derive::{Decode, Encode};
|
||||
use test_random_derive::TestRandom;
|
||||
use tree_hash_derive::TreeHash;
|
||||
|
||||
use crate::{
|
||||
core::{Address, SignedRoot},
|
||||
fork::ForkName,
|
||||
test_utils::TestRandom,
|
||||
};
|
||||
|
||||
#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
|
||||
#[derive(
|
||||
Debug, PartialEq, Eq, Hash, Clone, Serialize, Deserialize, Encode, Decode, TreeHash, TestRandom,
|
||||
5
consensus/types/src/consolidation/mod.rs
Normal file
5
consensus/types/src/consolidation/mod.rs
Normal file
@@ -0,0 +1,5 @@
|
||||
mod consolidation_request;
|
||||
mod pending_consolidation;
|
||||
|
||||
pub use consolidation_request::ConsolidationRequest;
|
||||
pub use pending_consolidation::PendingConsolidation;
|
||||
@@ -1,11 +1,11 @@
|
||||
use crate::ForkName;
|
||||
use crate::context_deserialize;
|
||||
use crate::test_utils::TestRandom;
|
||||
use context_deserialize::context_deserialize;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use ssz_derive::{Decode, Encode};
|
||||
use test_random_derive::TestRandom;
|
||||
use tree_hash_derive::TreeHash;
|
||||
|
||||
use crate::{fork::ForkName, test_utils::TestRandom};
|
||||
|
||||
#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
|
||||
#[derive(
|
||||
Debug, PartialEq, Eq, Hash, Clone, Serialize, Deserialize, Encode, Decode, TreeHash, TestRandom,
|
||||
@@ -1,19 +1,27 @@
|
||||
use crate::application_domain::{APPLICATION_DOMAIN_BUILDER, ApplicationDomain};
|
||||
use crate::blob_sidecar::BlobIdentifier;
|
||||
use crate::data_column_sidecar::DataColumnsByRootIdentifier;
|
||||
use crate::*;
|
||||
use std::{fs::File, path::Path, time::Duration};
|
||||
|
||||
use educe::Educe;
|
||||
use ethereum_hashing::hash;
|
||||
use fixed_bytes::FixedBytesExtended;
|
||||
use int_to_bytes::int_to_bytes4;
|
||||
use safe_arith::{ArithError, SafeArith};
|
||||
use serde::{Deserialize, Deserializer, Serialize, Serializer};
|
||||
use serde_utils::quoted_u64::MaybeQuoted;
|
||||
use ssz::Encode;
|
||||
use std::fs::File;
|
||||
use std::path::Path;
|
||||
use std::time::Duration;
|
||||
use ssz_types::{RuntimeVariableList, VariableList};
|
||||
use tree_hash::TreeHash;
|
||||
|
||||
use crate::{
|
||||
core::{
|
||||
APPLICATION_DOMAIN_BUILDER, Address, ApplicationDomain, EnrForkId, Epoch, EthSpec,
|
||||
EthSpecId, Hash256, MainnetEthSpec, Slot, Uint256,
|
||||
},
|
||||
data::{BlobIdentifier, DataColumnSubnetId, DataColumnsByRootIdentifier},
|
||||
execution::ExecutionBlockHash,
|
||||
fork::{Fork, ForkData, ForkName},
|
||||
state::BeaconState,
|
||||
};
|
||||
|
||||
/// Each of the BLS signature domains.
|
||||
#[derive(Debug, PartialEq, Clone, Copy)]
|
||||
pub enum Domain {
|
||||
@@ -2581,6 +2589,7 @@ mod tests {
|
||||
#[cfg(test)]
|
||||
mod yaml_tests {
|
||||
use super::*;
|
||||
use crate::core::MinimalEthSpec;
|
||||
use paste::paste;
|
||||
use std::sync::Arc;
|
||||
use tempfile::NamedTempFile;
|
||||
@@ -1,13 +1,14 @@
|
||||
use crate::{
|
||||
AltairPreset, BasePreset, BellatrixPreset, CapellaPreset, ChainSpec, Config, DenebPreset,
|
||||
ElectraPreset, EthSpec, FuluPreset, GloasPreset, consts::altair, consts::deneb,
|
||||
};
|
||||
use maplit::hashmap;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use serde_json::Value;
|
||||
use std::collections::HashMap;
|
||||
use superstruct::superstruct;
|
||||
|
||||
use crate::core::{
|
||||
AltairPreset, BasePreset, BellatrixPreset, CapellaPreset, ChainSpec, Config, DenebPreset,
|
||||
ElectraPreset, EthSpec, FuluPreset, GloasPreset, consts,
|
||||
};
|
||||
|
||||
/// Fusion of a runtime-config with the compile-time preset values.
|
||||
///
|
||||
/// Mostly useful for the API.
|
||||
@@ -131,11 +132,11 @@ pub fn get_extra_fields(spec: &ChainSpec) -> HashMap<String, Value> {
|
||||
"domain_sync_committee_selection_proof".to_uppercase() =>
|
||||
u32_hex(spec.domain_sync_committee_selection_proof),
|
||||
"sync_committee_subnet_count".to_uppercase() =>
|
||||
altair::SYNC_COMMITTEE_SUBNET_COUNT.to_string().into(),
|
||||
consts::altair::SYNC_COMMITTEE_SUBNET_COUNT.to_string().into(),
|
||||
"target_aggregators_per_sync_subcommittee".to_uppercase() =>
|
||||
altair::TARGET_AGGREGATORS_PER_SYNC_SUBCOMMITTEE.to_string().into(),
|
||||
consts::altair::TARGET_AGGREGATORS_PER_SYNC_SUBCOMMITTEE.to_string().into(),
|
||||
// Deneb
|
||||
"versioned_hash_version_kzg".to_uppercase() => deneb::VERSIONED_HASH_VERSION_KZG.to_string().into(),
|
||||
"versioned_hash_version_kzg".to_uppercase() => consts::deneb::VERSIONED_HASH_VERSION_KZG.to_string().into(),
|
||||
// Electra
|
||||
"compounding_withdrawal_prefix".to_uppercase() => u8_hex(spec.compounding_withdrawal_prefix_byte),
|
||||
"unset_deposit_requests_start_index".to_uppercase() => spec.unset_deposit_requests_start_index.to_string().into(),
|
||||
@@ -23,5 +23,5 @@ pub mod bellatrix {
|
||||
pub const INTERVALS_PER_SLOT: u64 = 3;
|
||||
}
|
||||
pub mod deneb {
|
||||
pub use crate::VERSIONED_HASH_VERSION_KZG;
|
||||
pub use kzg::VERSIONED_HASH_VERSION_KZG;
|
||||
}
|
||||
@@ -1,11 +1,10 @@
|
||||
use crate::Epoch;
|
||||
use crate::test_utils::TestRandom;
|
||||
|
||||
use serde::{Deserialize, Serialize};
|
||||
use ssz_derive::{Decode, Encode};
|
||||
use test_random_derive::TestRandom;
|
||||
use tree_hash_derive::TreeHash;
|
||||
|
||||
use crate::{core::Epoch, test_utils::TestRandom};
|
||||
|
||||
/// Specifies a fork which allows nodes to identify each other on the network. This fork is used in
|
||||
/// a nodes local ENR.
|
||||
///
|
||||
@@ -1,16 +1,22 @@
|
||||
use crate::*;
|
||||
use std::{
|
||||
fmt::{self, Debug},
|
||||
str::FromStr,
|
||||
};
|
||||
|
||||
use safe_arith::SafeArith;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use ssz_types::typenum::{
|
||||
U0, U1, U2, U4, U8, U16, U17, U32, U64, U128, U256, U512, U625, U1024, U2048, U4096, U8192,
|
||||
U65536, U131072, U262144, U1048576, U16777216, U33554432, U134217728, U1073741824,
|
||||
U1099511627776, UInt, bit::B0,
|
||||
U1099511627776, UInt, Unsigned, bit::B0,
|
||||
};
|
||||
use std::fmt::{self, Debug};
|
||||
use std::str::FromStr;
|
||||
|
||||
pub type U5000 = UInt<UInt<UInt<U625, B0>, B0>, B0>; // 625 * 8 = 5000
|
||||
use crate::{
|
||||
core::{ChainSpec, Epoch},
|
||||
state::BeaconStateError,
|
||||
};
|
||||
|
||||
type U5000 = UInt<UInt<UInt<U625, B0>, B0>, B0>; // 625 * 8 = 5000
|
||||
|
||||
const MAINNET: &str = "mainnet";
|
||||
const MINIMAL: &str = "minimal";
|
||||
@@ -182,7 +188,7 @@ pub trait EthSpec: 'static + Default + Sync + Send + Clone + Debug + PartialEq +
|
||||
fn get_committee_count_per_slot(
|
||||
active_validator_count: usize,
|
||||
spec: &ChainSpec,
|
||||
) -> Result<usize, Error> {
|
||||
) -> Result<usize, BeaconStateError> {
|
||||
Self::get_committee_count_per_slot_with(
|
||||
active_validator_count,
|
||||
spec.max_committees_per_slot,
|
||||
@@ -194,7 +200,7 @@ pub trait EthSpec: 'static + Default + Sync + Send + Clone + Debug + PartialEq +
|
||||
active_validator_count: usize,
|
||||
max_committees_per_slot: usize,
|
||||
target_committee_size: usize,
|
||||
) -> Result<usize, Error> {
|
||||
) -> Result<usize, BeaconStateError> {
|
||||
let slots_per_epoch = Self::SlotsPerEpoch::to_usize();
|
||||
|
||||
Ok(std::cmp::max(
|
||||
@@ -1,14 +1,13 @@
|
||||
use crate::{
|
||||
Hash256,
|
||||
test_utils::{RngCore, TestRandom},
|
||||
};
|
||||
use std::{fmt, str::FromStr};
|
||||
|
||||
use rand::RngCore;
|
||||
use regex::bytes::Regex;
|
||||
use serde::{Deserialize, Deserializer, Serialize, Serializer, de::Error};
|
||||
use ssz::{Decode, DecodeError, Encode};
|
||||
use std::fmt;
|
||||
use std::str::FromStr;
|
||||
use tree_hash::{PackedEncoding, TreeHash};
|
||||
|
||||
use crate::{core::Hash256, test_utils::TestRandom};
|
||||
|
||||
pub const GRAFFITI_BYTES_LEN: usize = 32;
|
||||
|
||||
/// The 32-byte `graffiti` field on a beacon block.
|
||||
44
consensus/types/src/core/mod.rs
Normal file
44
consensus/types/src/core/mod.rs
Normal file
@@ -0,0 +1,44 @@
|
||||
pub mod consts;
|
||||
|
||||
mod application_domain;
|
||||
mod chain_spec;
|
||||
mod config_and_preset;
|
||||
mod enr_fork_id;
|
||||
mod eth_spec;
|
||||
mod graffiti;
|
||||
mod non_zero_usize;
|
||||
mod preset;
|
||||
mod relative_epoch;
|
||||
mod signing_data;
|
||||
mod slot_data;
|
||||
#[macro_use]
|
||||
mod slot_epoch_macros;
|
||||
mod slot_epoch;
|
||||
#[cfg(feature = "sqlite")]
|
||||
mod sqlite;
|
||||
|
||||
pub use application_domain::{APPLICATION_DOMAIN_BUILDER, ApplicationDomain};
|
||||
pub use chain_spec::{BlobParameters, BlobSchedule, ChainSpec, Config, Domain};
|
||||
pub use config_and_preset::{
|
||||
ConfigAndPreset, ConfigAndPresetDeneb, ConfigAndPresetElectra, ConfigAndPresetFulu,
|
||||
ConfigAndPresetGloas, get_extra_fields,
|
||||
};
|
||||
pub use enr_fork_id::EnrForkId;
|
||||
pub use eth_spec::{EthSpec, EthSpecId, GNOSIS, GnosisEthSpec, MainnetEthSpec, MinimalEthSpec};
|
||||
pub use graffiti::{GRAFFITI_BYTES_LEN, Graffiti, GraffitiString};
|
||||
pub use non_zero_usize::new_non_zero_usize;
|
||||
pub use preset::{
|
||||
AltairPreset, BasePreset, BellatrixPreset, CapellaPreset, DenebPreset, ElectraPreset,
|
||||
FuluPreset, GloasPreset,
|
||||
};
|
||||
pub use relative_epoch::{Error as RelativeEpochError, RelativeEpoch};
|
||||
pub use signing_data::{SignedRoot, SigningData};
|
||||
pub use slot_data::SlotData;
|
||||
pub use slot_epoch::{Epoch, Slot};
|
||||
|
||||
pub type Hash256 = alloy_primitives::B256;
|
||||
pub type Uint256 = alloy_primitives::U256;
|
||||
pub type Hash64 = alloy_primitives::B64;
|
||||
pub type Address = alloy_primitives::Address;
|
||||
pub type VersionedHash = Hash256;
|
||||
pub type MerkleProof = Vec<Hash256>;
|
||||
@@ -1,5 +1,7 @@
|
||||
use crate::{ChainSpec, Epoch, EthSpec, Unsigned};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use ssz_types::typenum::Unsigned;
|
||||
|
||||
use crate::core::{ChainSpec, Epoch, EthSpec};
|
||||
|
||||
/// Value-level representation of an Ethereum consensus "preset".
|
||||
///
|
||||
@@ -1,6 +1,7 @@
|
||||
use crate::*;
|
||||
use safe_arith::{ArithError, SafeArith};
|
||||
|
||||
use crate::core::{Epoch, Slot};
|
||||
|
||||
#[derive(Debug, PartialEq, Clone, Copy)]
|
||||
pub enum Error {
|
||||
EpochTooLow { base: Epoch, other: Epoch },
|
||||
@@ -1,13 +1,12 @@
|
||||
use crate::context_deserialize;
|
||||
use crate::test_utils::TestRandom;
|
||||
use crate::{ForkName, Hash256};
|
||||
|
||||
use context_deserialize::context_deserialize;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use ssz_derive::{Decode, Encode};
|
||||
use test_random_derive::TestRandom;
|
||||
use tree_hash::TreeHash;
|
||||
use tree_hash_derive::TreeHash;
|
||||
|
||||
use crate::{core::Hash256, fork::ForkName, test_utils::TestRandom};
|
||||
|
||||
#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
|
||||
#[derive(Debug, PartialEq, Clone, Serialize, Deserialize, Encode, Decode, TreeHash, TestRandom)]
|
||||
#[context_deserialize(ForkName)]
|
||||
@@ -1,4 +1,4 @@
|
||||
use crate::Slot;
|
||||
use crate::core::Slot;
|
||||
|
||||
/// A trait providing a `Slot` getter for messages that are related to a single slot. Useful in
|
||||
/// making parts of attestation and sync committee processing generic.
|
||||
@@ -10,15 +10,17 @@
|
||||
//! implement `Into<u64>`, however this would allow operations between `Slots` and `Epochs` which
|
||||
//! may lead to programming errors which are not detected by the compiler.
|
||||
|
||||
use crate::test_utils::TestRandom;
|
||||
use crate::{ChainSpec, SignedRoot};
|
||||
use std::{fmt, hash::Hash};
|
||||
|
||||
use rand::RngCore;
|
||||
use safe_arith::{ArithError, SafeArith};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use ssz::{Decode, DecodeError, Encode};
|
||||
use std::fmt;
|
||||
use std::hash::Hash;
|
||||
|
||||
use crate::{
|
||||
core::{ChainSpec, SignedRoot},
|
||||
test_utils::TestRandom,
|
||||
};
|
||||
|
||||
#[cfg(feature = "legacy-arith")]
|
||||
use std::ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Rem, Sub, SubAssign};
|
||||
@@ -1,10 +1,11 @@
|
||||
//! Implementations of SQLite compatibility traits.
|
||||
use crate::{Epoch, Slot};
|
||||
use rusqlite::{
|
||||
Error,
|
||||
types::{FromSql, FromSqlError, ToSql, ToSqlOutput, ValueRef},
|
||||
};
|
||||
|
||||
use crate::core::{Epoch, Slot};
|
||||
|
||||
macro_rules! impl_to_from_sql {
|
||||
($type:ty) => {
|
||||
impl ToSql for $type {
|
||||
@@ -1,12 +1,7 @@
|
||||
use crate::context_deserialize;
|
||||
use crate::test_utils::TestRandom;
|
||||
use crate::{
|
||||
AbstractExecPayload, BeaconBlockHeader, BeaconStateError, Blob, ChainSpec, Epoch, EthSpec,
|
||||
FixedVector, ForkName, Hash256, KzgProofs, RuntimeFixedVector, RuntimeVariableList,
|
||||
SignedBeaconBlock, SignedBeaconBlockHeader, Slot, VariableList,
|
||||
beacon_block_body::BLOB_KZG_COMMITMENTS_INDEX,
|
||||
};
|
||||
use std::{fmt::Debug, hash::Hash, sync::Arc};
|
||||
|
||||
use bls::Signature;
|
||||
use context_deserialize::context_deserialize;
|
||||
use educe::Educe;
|
||||
use kzg::{BYTES_PER_BLOB, BYTES_PER_FIELD_ELEMENT, Blob as KzgBlob, Kzg, KzgCommitment, KzgProof};
|
||||
use merkle_proof::{MerkleTreeError, merkle_root_from_branch, verify_merkle_proof};
|
||||
@@ -15,13 +10,24 @@ use safe_arith::ArithError;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use ssz::Encode;
|
||||
use ssz_derive::{Decode, Encode};
|
||||
use std::fmt::Debug;
|
||||
use std::hash::Hash;
|
||||
use std::sync::Arc;
|
||||
use ssz_types::{FixedVector, RuntimeFixedVector, RuntimeVariableList, VariableList};
|
||||
use test_random_derive::TestRandom;
|
||||
use tree_hash::TreeHash;
|
||||
use tree_hash_derive::TreeHash;
|
||||
|
||||
use crate::{
|
||||
block::{
|
||||
BLOB_KZG_COMMITMENTS_INDEX, BeaconBlockHeader, SignedBeaconBlock, SignedBeaconBlockHeader,
|
||||
},
|
||||
core::{ChainSpec, Epoch, EthSpec, Hash256, Slot},
|
||||
data::Blob,
|
||||
execution::AbstractExecPayload,
|
||||
fork::ForkName,
|
||||
kzg_ext::KzgProofs,
|
||||
state::BeaconStateError,
|
||||
test_utils::TestRandom,
|
||||
};
|
||||
|
||||
/// Container of the data that identifies an individual blob.
|
||||
#[derive(
|
||||
Serialize, Deserialize, Encode, Decode, TreeHash, Copy, Clone, Debug, PartialEq, Eq, Hash,
|
||||
@@ -1,8 +1,14 @@
|
||||
use crate::{ChainSpec, ColumnIndex, DataColumnSubnetId, EthSpec};
|
||||
use std::collections::HashSet;
|
||||
|
||||
use alloy_primitives::U256;
|
||||
use itertools::Itertools;
|
||||
use safe_arith::{ArithError, SafeArith};
|
||||
use std::collections::HashSet;
|
||||
|
||||
use crate::{
|
||||
EthSpec,
|
||||
core::ChainSpec,
|
||||
data::{ColumnIndex, DataColumnSubnetId},
|
||||
};
|
||||
|
||||
pub type CustodyIndex = u64;
|
||||
|
||||
@@ -1,13 +1,8 @@
|
||||
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,
|
||||
SignedBeaconBlockHeader, Slot,
|
||||
};
|
||||
use std::sync::Arc;
|
||||
|
||||
use bls::Signature;
|
||||
use context_deserialize::context_deserialize;
|
||||
use educe::Educe;
|
||||
use kzg::Error as KzgError;
|
||||
use kzg::{KzgCommitment, KzgProof};
|
||||
use merkle_proof::verify_merkle_proof;
|
||||
use safe_arith::ArithError;
|
||||
@@ -16,11 +11,19 @@ use ssz::Encode;
|
||||
use ssz_derive::{Decode, Encode};
|
||||
use ssz_types::Error as SszError;
|
||||
use ssz_types::{FixedVector, VariableList};
|
||||
use std::sync::Arc;
|
||||
use test_random_derive::TestRandom;
|
||||
use tree_hash::TreeHash;
|
||||
use tree_hash_derive::TreeHash;
|
||||
|
||||
use crate::{
|
||||
block::{BLOB_KZG_COMMITMENTS_INDEX, BeaconBlockHeader, SignedBeaconBlockHeader},
|
||||
core::{Epoch, EthSpec, Hash256, Slot},
|
||||
fork::ForkName,
|
||||
kzg_ext::{KzgCommitments, KzgError},
|
||||
state::BeaconStateError,
|
||||
test_utils::TestRandom,
|
||||
};
|
||||
|
||||
pub type ColumnIndex = u64;
|
||||
pub type Cell<E> = FixedVector<u8, <E as EthSpec>::BytesPerCell>;
|
||||
pub type DataColumn<E> = VariableList<Cell<E>, <E as EthSpec>::MaxBlobCommitmentsPerBlock>;
|
||||
@@ -1,10 +1,13 @@
|
||||
//! Identifies each data column subnet by an integer identifier.
|
||||
use crate::ChainSpec;
|
||||
use crate::data_column_sidecar::ColumnIndex;
|
||||
use safe_arith::{ArithError, SafeArith};
|
||||
use std::{
|
||||
fmt::{self, Display},
|
||||
ops::{Deref, DerefMut},
|
||||
};
|
||||
|
||||
use safe_arith::SafeArith;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::fmt::{self, Display};
|
||||
use std::ops::{Deref, DerefMut};
|
||||
|
||||
use crate::{core::ChainSpec, data::ColumnIndex};
|
||||
|
||||
#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
|
||||
#[derive(Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
|
||||
@@ -69,15 +72,3 @@ impl From<&DataColumnSubnetId> for u64 {
|
||||
val.0
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum Error {
|
||||
ArithError(ArithError),
|
||||
InvalidCustodySubnetCount(u64),
|
||||
}
|
||||
|
||||
impl From<ArithError> for Error {
|
||||
fn from(e: ArithError) -> Self {
|
||||
Error::ArithError(e)
|
||||
}
|
||||
}
|
||||
23
consensus/types/src/data/mod.rs
Normal file
23
consensus/types/src/data/mod.rs
Normal file
@@ -0,0 +1,23 @@
|
||||
mod blob_sidecar;
|
||||
mod data_column_custody_group;
|
||||
mod data_column_sidecar;
|
||||
mod data_column_subnet_id;
|
||||
|
||||
pub use blob_sidecar::{
|
||||
BlobIdentifier, BlobSidecar, BlobSidecarError, BlobSidecarList, BlobsList, FixedBlobSidecarList,
|
||||
};
|
||||
pub use data_column_custody_group::{
|
||||
CustodyIndex, DataColumnCustodyGroupError, compute_columns_for_custody_group,
|
||||
compute_ordered_custody_column_indices, compute_subnets_for_node,
|
||||
compute_subnets_from_custody_group, get_custody_groups,
|
||||
};
|
||||
pub use data_column_sidecar::{
|
||||
Cell, ColumnIndex, DataColumn, DataColumnSidecar, DataColumnSidecarError,
|
||||
DataColumnSidecarList, DataColumnsByRootIdentifier,
|
||||
};
|
||||
pub use data_column_subnet_id::DataColumnSubnetId;
|
||||
|
||||
use crate::core::EthSpec;
|
||||
use ssz_types::FixedVector;
|
||||
|
||||
pub type Blob<E> = FixedVector<u8, <E as EthSpec>::BytesPerBlob>;
|
||||
@@ -1,12 +1,12 @@
|
||||
use crate::context_deserialize;
|
||||
use crate::test_utils::TestRandom;
|
||||
use crate::*;
|
||||
use context_deserialize::context_deserialize;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use ssz_derive::{Decode, Encode};
|
||||
use ssz_types::typenum::U33;
|
||||
use ssz_types::{FixedVector, typenum::U33};
|
||||
use test_random_derive::TestRandom;
|
||||
use tree_hash_derive::TreeHash;
|
||||
|
||||
use crate::{core::Hash256, deposit::DepositData, fork::ForkName, test_utils::TestRandom};
|
||||
|
||||
pub const DEPOSIT_TREE_DEPTH: usize = 32;
|
||||
|
||||
/// A deposit to potentially become a beacon chain validator.
|
||||
@@ -1,10 +1,17 @@
|
||||
use crate::test_utils::TestRandom;
|
||||
use crate::*;
|
||||
use bls::{PublicKeyBytes, SecretKey, SignatureBytes};
|
||||
use context_deserialize::context_deserialize;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use ssz_derive::{Decode, Encode};
|
||||
use test_random_derive::TestRandom;
|
||||
use tree_hash_derive::TreeHash;
|
||||
|
||||
use crate::{
|
||||
core::{ChainSpec, Hash256, SignedRoot},
|
||||
deposit::DepositMessage,
|
||||
fork::ForkName,
|
||||
test_utils::TestRandom,
|
||||
};
|
||||
|
||||
/// The data supplied by the user to the deposit contract.
|
||||
///
|
||||
/// Spec v0.12.1
|
||||
@@ -1,11 +1,16 @@
|
||||
use crate::test_utils::TestRandom;
|
||||
use crate::*;
|
||||
|
||||
use bls::PublicKeyBytes;
|
||||
use context_deserialize::context_deserialize;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use ssz_derive::{Decode, Encode};
|
||||
use test_random_derive::TestRandom;
|
||||
use tree_hash_derive::TreeHash;
|
||||
|
||||
use crate::{
|
||||
core::{Hash256, SignedRoot},
|
||||
fork::ForkName,
|
||||
test_utils::TestRandom,
|
||||
};
|
||||
|
||||
/// The data supplied by the user to the deposit contract.
|
||||
///
|
||||
/// Spec v0.12.1
|
||||
@@ -1,13 +1,13 @@
|
||||
use crate::context_deserialize;
|
||||
use crate::test_utils::TestRandom;
|
||||
use crate::{ForkName, Hash256, PublicKeyBytes};
|
||||
use bls::SignatureBytes;
|
||||
use bls::{PublicKeyBytes, SignatureBytes};
|
||||
use context_deserialize::context_deserialize;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use ssz::Encode;
|
||||
use ssz_derive::{Decode, Encode};
|
||||
use test_random_derive::TestRandom;
|
||||
use tree_hash_derive::TreeHash;
|
||||
|
||||
use crate::{core::Hash256, fork::ForkName, test_utils::TestRandom};
|
||||
|
||||
#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
|
||||
#[derive(
|
||||
Debug, PartialEq, Hash, Clone, Serialize, Deserialize, Encode, Decode, TreeHash, TestRandom,
|
||||
@@ -1,10 +1,11 @@
|
||||
use crate::*;
|
||||
use ethereum_hashing::{ZERO_HASHES, hash32_concat};
|
||||
use fixed_bytes::FixedBytesExtended;
|
||||
use int_to_bytes::int_to_bytes32;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use ssz_derive::{Decode, Encode};
|
||||
use test_random_derive::TestRandom;
|
||||
use test_utils::TestRandom;
|
||||
|
||||
use crate::{core::Hash256, deposit::DEPOSIT_TREE_DEPTH, test_utils::TestRandom};
|
||||
|
||||
#[derive(Encode, Decode, Deserialize, Serialize, Clone, Debug, PartialEq, TestRandom)]
|
||||
pub struct FinalizedExecutionBlock {
|
||||
13
consensus/types/src/deposit/mod.rs
Normal file
13
consensus/types/src/deposit/mod.rs
Normal file
@@ -0,0 +1,13 @@
|
||||
mod deposit;
|
||||
mod deposit_data;
|
||||
mod deposit_message;
|
||||
mod deposit_request;
|
||||
mod deposit_tree_snapshot;
|
||||
mod pending_deposit;
|
||||
|
||||
pub use deposit::{DEPOSIT_TREE_DEPTH, Deposit};
|
||||
pub use deposit_data::DepositData;
|
||||
pub use deposit_message::DepositMessage;
|
||||
pub use deposit_request::DepositRequest;
|
||||
pub use deposit_tree_snapshot::{DepositTreeSnapshot, FinalizedExecutionBlock};
|
||||
pub use pending_deposit::PendingDeposit;
|
||||
@@ -1,10 +1,16 @@
|
||||
use crate::test_utils::TestRandom;
|
||||
use crate::*;
|
||||
use bls::{PublicKeyBytes, SignatureBytes};
|
||||
use context_deserialize::context_deserialize;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use ssz_derive::{Decode, Encode};
|
||||
use test_random_derive::TestRandom;
|
||||
use tree_hash_derive::TreeHash;
|
||||
|
||||
use crate::{
|
||||
core::{Hash256, Slot},
|
||||
fork::ForkName,
|
||||
test_utils::TestRandom,
|
||||
};
|
||||
|
||||
#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
|
||||
#[derive(
|
||||
Debug, PartialEq, Hash, Clone, Serialize, Deserialize, Encode, Decode, TreeHash, TestRandom,
|
||||
@@ -1,10 +1,17 @@
|
||||
use crate::test_utils::TestRandom;
|
||||
use crate::*;
|
||||
use bls::{PublicKeyBytes, SecretKey};
|
||||
use context_deserialize::context_deserialize;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use ssz_derive::{Decode, Encode};
|
||||
use test_random_derive::TestRandom;
|
||||
use tree_hash_derive::TreeHash;
|
||||
|
||||
use crate::{
|
||||
core::{Address, ChainSpec, Domain, Hash256, SignedRoot},
|
||||
execution::SignedBlsToExecutionChange,
|
||||
fork::ForkName,
|
||||
test_utils::TestRandom,
|
||||
};
|
||||
|
||||
#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
|
||||
#[derive(
|
||||
Debug, PartialEq, Eq, Hash, Clone, Serialize, Deserialize, Encode, Decode, TreeHash, TestRandom,
|
||||
@@ -1,12 +1,11 @@
|
||||
use super::Hash256;
|
||||
use crate::ForkName;
|
||||
use crate::context_deserialize;
|
||||
use crate::test_utils::TestRandom;
|
||||
use context_deserialize::context_deserialize;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use ssz_derive::{Decode, Encode};
|
||||
use test_random_derive::TestRandom;
|
||||
use tree_hash_derive::TreeHash;
|
||||
|
||||
use crate::{core::Hash256, fork::ForkName, test_utils::TestRandom};
|
||||
|
||||
/// Contains data obtained from the Eth1 chain.
|
||||
///
|
||||
/// Spec v0.12.1
|
||||
@@ -1,10 +1,11 @@
|
||||
use crate::FixedBytesExtended;
|
||||
use crate::Hash256;
|
||||
use crate::test_utils::TestRandom;
|
||||
use std::fmt;
|
||||
|
||||
use fixed_bytes::FixedBytesExtended;
|
||||
use rand::RngCore;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use ssz::{Decode, DecodeError, Encode};
|
||||
use std::fmt;
|
||||
|
||||
use crate::{core::Hash256, test_utils::TestRandom};
|
||||
|
||||
#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
|
||||
#[derive(Default, Clone, Copy, Serialize, Deserialize, Eq, PartialEq, Hash)]
|
||||
@@ -17,10 +17,15 @@
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
use crate::{Address, EthSpec, ExecutionPayloadRef, Hash64, Hash256, Uint256};
|
||||
use alloy_rlp::RlpEncodable;
|
||||
use fixed_bytes::Uint256;
|
||||
use metastruct::metastruct;
|
||||
|
||||
use crate::{
|
||||
core::{Address, EthSpec, Hash64, Hash256},
|
||||
execution::ExecutionPayloadRef,
|
||||
};
|
||||
|
||||
/// Execution block header as used for RLP encoding and Keccak hashing.
|
||||
///
|
||||
/// Credit to Reth for the type definition.
|
||||
@@ -1,19 +1,29 @@
|
||||
use crate::{test_utils::TestRandom, *};
|
||||
use context_deserialize::{ContextDeserialize, context_deserialize};
|
||||
use educe::Educe;
|
||||
use fixed_bytes::Uint256;
|
||||
use serde::{Deserialize, Deserializer, Serialize};
|
||||
use ssz::{Decode, Encode};
|
||||
use ssz_derive::{Decode, Encode};
|
||||
use ssz_types::{FixedVector, VariableList};
|
||||
use superstruct::superstruct;
|
||||
use test_random_derive::TestRandom;
|
||||
use tree_hash_derive::TreeHash;
|
||||
|
||||
use crate::{
|
||||
core::{Address, EthSpec, Hash256},
|
||||
execution::ExecutionBlockHash,
|
||||
fork::{ForkName, ForkVersionDecode},
|
||||
state::BeaconStateError,
|
||||
test_utils::TestRandom,
|
||||
withdrawal::Withdrawals,
|
||||
};
|
||||
|
||||
pub type Transaction<N> = VariableList<u8, N>;
|
||||
pub type Transactions<E> = VariableList<
|
||||
Transaction<<E as EthSpec>::MaxBytesPerTransaction>,
|
||||
<E as EthSpec>::MaxTransactionsPerPayload,
|
||||
>;
|
||||
|
||||
pub type Withdrawals<E> = VariableList<Withdrawal, <E as EthSpec>::MaxWithdrawalsPerPayload>;
|
||||
|
||||
#[superstruct(
|
||||
variants(Bellatrix, Capella, Deneb, Electra, Fulu, Gloas),
|
||||
variant_attributes(
|
||||
@@ -38,8 +48,14 @@ pub type Withdrawals<E> = VariableList<Withdrawal, <E as EthSpec>::MaxWithdrawal
|
||||
arbitrary(bound = "E: EthSpec"),
|
||||
),
|
||||
),
|
||||
cast_error(ty = "Error", expr = "BeaconStateError::IncorrectStateVariant"),
|
||||
partial_getter_error(ty = "Error", expr = "BeaconStateError::IncorrectStateVariant"),
|
||||
cast_error(
|
||||
ty = "BeaconStateError",
|
||||
expr = "BeaconStateError::IncorrectStateVariant"
|
||||
),
|
||||
partial_getter_error(
|
||||
ty = "BeaconStateError",
|
||||
expr = "BeaconStateError::IncorrectStateVariant"
|
||||
),
|
||||
map_into(FullPayload, BlindedPayload),
|
||||
map_ref_into(ExecutionPayloadHeader)
|
||||
)]
|
||||
@@ -1,12 +1,27 @@
|
||||
use crate::{test_utils::TestRandom, *};
|
||||
use context_deserialize::{ContextDeserialize, context_deserialize};
|
||||
use educe::Educe;
|
||||
use fixed_bytes::FixedBytesExtended;
|
||||
use serde::{Deserialize, Deserializer, Serialize};
|
||||
use ssz::{Decode, Encode};
|
||||
use ssz_derive::{Decode, Encode};
|
||||
use ssz_types::{FixedVector, VariableList};
|
||||
use superstruct::superstruct;
|
||||
use test_random_derive::TestRandom;
|
||||
use tree_hash::TreeHash;
|
||||
use tree_hash_derive::TreeHash;
|
||||
|
||||
use crate::{
|
||||
core::{Address, EthSpec, Hash256, Uint256},
|
||||
execution::{
|
||||
ExecutionBlockHash, ExecutionPayloadBellatrix, ExecutionPayloadCapella,
|
||||
ExecutionPayloadDeneb, ExecutionPayloadElectra, ExecutionPayloadFulu,
|
||||
ExecutionPayloadGloas, ExecutionPayloadRef, Transactions,
|
||||
},
|
||||
fork::ForkName,
|
||||
state::BeaconStateError,
|
||||
test_utils::TestRandom,
|
||||
};
|
||||
|
||||
#[superstruct(
|
||||
variants(Bellatrix, Capella, Deneb, Electra, Fulu, Gloas),
|
||||
variant_attributes(
|
||||
@@ -35,8 +50,14 @@ use tree_hash_derive::TreeHash;
|
||||
derive(PartialEq, TreeHash, Debug),
|
||||
tree_hash(enum_behaviour = "transparent")
|
||||
),
|
||||
cast_error(ty = "Error", expr = "BeaconStateError::IncorrectStateVariant"),
|
||||
partial_getter_error(ty = "Error", expr = "BeaconStateError::IncorrectStateVariant"),
|
||||
cast_error(
|
||||
ty = "BeaconStateError",
|
||||
expr = "BeaconStateError::IncorrectStateVariant"
|
||||
),
|
||||
partial_getter_error(
|
||||
ty = "BeaconStateError",
|
||||
expr = "BeaconStateError::IncorrectStateVariant"
|
||||
),
|
||||
map_ref_into(ExecutionPayloadHeader)
|
||||
)]
|
||||
#[cfg_attr(
|
||||
@@ -1,7 +1,5 @@
|
||||
use crate::context_deserialize;
|
||||
use crate::test_utils::TestRandom;
|
||||
use crate::{ConsolidationRequest, DepositRequest, EthSpec, ForkName, Hash256, WithdrawalRequest};
|
||||
use alloy_primitives::Bytes;
|
||||
use context_deserialize::context_deserialize;
|
||||
use educe::Educe;
|
||||
use ethereum_hashing::{DynamicContext, Sha256Context};
|
||||
use serde::{Deserialize, Serialize};
|
||||
@@ -11,6 +9,15 @@ use ssz_types::VariableList;
|
||||
use test_random_derive::TestRandom;
|
||||
use tree_hash_derive::TreeHash;
|
||||
|
||||
use crate::{
|
||||
consolidation::ConsolidationRequest,
|
||||
core::{EthSpec, Hash256},
|
||||
deposit::DepositRequest,
|
||||
fork::ForkName,
|
||||
test_utils::TestRandom,
|
||||
withdrawal::WithdrawalRequest,
|
||||
};
|
||||
|
||||
pub type DepositRequests<E> =
|
||||
VariableList<DepositRequest, <E as EthSpec>::MaxDepositRequestsPerPayload>;
|
||||
pub type WithdrawalRequests<E> =
|
||||
36
consensus/types/src/execution/mod.rs
Normal file
36
consensus/types/src/execution/mod.rs
Normal file
@@ -0,0 +1,36 @@
|
||||
mod eth1_data;
|
||||
mod execution_block_hash;
|
||||
mod execution_block_header;
|
||||
#[macro_use]
|
||||
mod execution_payload;
|
||||
mod bls_to_execution_change;
|
||||
mod execution_payload_header;
|
||||
mod execution_requests;
|
||||
mod payload;
|
||||
mod signed_bls_to_execution_change;
|
||||
|
||||
pub use bls_to_execution_change::BlsToExecutionChange;
|
||||
pub use eth1_data::Eth1Data;
|
||||
pub use execution_block_hash::ExecutionBlockHash;
|
||||
pub use execution_block_header::{EncodableExecutionBlockHeader, ExecutionBlockHeader};
|
||||
pub use execution_payload::{
|
||||
ExecutionPayload, ExecutionPayloadBellatrix, ExecutionPayloadCapella, ExecutionPayloadDeneb,
|
||||
ExecutionPayloadElectra, ExecutionPayloadFulu, ExecutionPayloadGloas, ExecutionPayloadRef,
|
||||
Transaction, Transactions,
|
||||
};
|
||||
pub use execution_payload_header::{
|
||||
ExecutionPayloadHeader, ExecutionPayloadHeaderBellatrix, ExecutionPayloadHeaderCapella,
|
||||
ExecutionPayloadHeaderDeneb, ExecutionPayloadHeaderElectra, ExecutionPayloadHeaderFulu,
|
||||
ExecutionPayloadHeaderGloas, ExecutionPayloadHeaderRef, ExecutionPayloadHeaderRefMut,
|
||||
};
|
||||
pub use execution_requests::{
|
||||
ConsolidationRequests, DepositRequests, ExecutionRequests, RequestType, WithdrawalRequests,
|
||||
};
|
||||
pub use payload::{
|
||||
AbstractExecPayload, BlindedPayload, BlindedPayloadBellatrix, BlindedPayloadCapella,
|
||||
BlindedPayloadDeneb, BlindedPayloadElectra, BlindedPayloadFulu, BlindedPayloadGloas,
|
||||
BlindedPayloadRef, BlockProductionVersion, BlockType, ExecPayload, FullPayload,
|
||||
FullPayloadBellatrix, FullPayloadCapella, FullPayloadDeneb, FullPayloadElectra,
|
||||
FullPayloadFulu, FullPayloadGloas, FullPayloadRef, OwnedExecPayload,
|
||||
};
|
||||
pub use signed_bls_to_execution_change::SignedBlsToExecutionChange;
|
||||
@@ -1,16 +1,29 @@
|
||||
use crate::{test_utils::TestRandom, *};
|
||||
use educe::Educe;
|
||||
use serde::de::DeserializeOwned;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use ssz::{Decode, Encode};
|
||||
use ssz_derive::{Decode, Encode};
|
||||
use std::borrow::Cow;
|
||||
use std::fmt::Debug;
|
||||
use std::hash::Hash;
|
||||
use ssz_types::VariableList;
|
||||
use std::{borrow::Cow, fmt::Debug, hash::Hash};
|
||||
use superstruct::superstruct;
|
||||
use test_random_derive::TestRandom;
|
||||
use tree_hash::TreeHash;
|
||||
use tree_hash_derive::TreeHash;
|
||||
|
||||
use crate::{
|
||||
core::{Address, EthSpec, Hash256},
|
||||
execution::{
|
||||
ExecutionBlockHash, ExecutionPayload, ExecutionPayloadBellatrix, ExecutionPayloadCapella,
|
||||
ExecutionPayloadDeneb, ExecutionPayloadElectra, ExecutionPayloadFulu,
|
||||
ExecutionPayloadGloas, ExecutionPayloadHeader, ExecutionPayloadHeaderBellatrix,
|
||||
ExecutionPayloadHeaderCapella, ExecutionPayloadHeaderDeneb, ExecutionPayloadHeaderElectra,
|
||||
ExecutionPayloadHeaderFulu, ExecutionPayloadHeaderGloas, ExecutionPayloadRef, Transactions,
|
||||
},
|
||||
fork::ForkName,
|
||||
state::BeaconStateError,
|
||||
test_utils::TestRandom,
|
||||
};
|
||||
|
||||
#[derive(Debug, PartialEq)]
|
||||
pub enum BlockType {
|
||||
Blinded,
|
||||
@@ -38,8 +51,8 @@ pub trait ExecPayload<E: EthSpec>: Debug + Clone + PartialEq + Hash + TreeHash +
|
||||
fn gas_limit(&self) -> u64;
|
||||
fn transactions(&self) -> Option<&Transactions<E>>;
|
||||
/// fork-specific fields
|
||||
fn withdrawals_root(&self) -> Result<Hash256, Error>;
|
||||
fn blob_gas_used(&self) -> Result<u64, Error>;
|
||||
fn withdrawals_root(&self) -> Result<Hash256, BeaconStateError>;
|
||||
fn blob_gas_used(&self) -> Result<u64, BeaconStateError>;
|
||||
|
||||
/// Is this a default payload with 0x0 roots for transactions and withdrawals?
|
||||
fn is_default_with_zero_roots(&self) -> bool;
|
||||
@@ -179,8 +192,14 @@ pub trait AbstractExecPayload<E: EthSpec>:
|
||||
),
|
||||
map_into(ExecutionPayload),
|
||||
map_ref_into(ExecutionPayloadRef),
|
||||
cast_error(ty = "Error", expr = "BeaconStateError::IncorrectStateVariant"),
|
||||
partial_getter_error(ty = "Error", expr = "BeaconStateError::IncorrectStateVariant")
|
||||
cast_error(
|
||||
ty = "BeaconStateError",
|
||||
expr = "BeaconStateError::IncorrectStateVariant"
|
||||
),
|
||||
partial_getter_error(
|
||||
ty = "BeaconStateError",
|
||||
expr = "BeaconStateError::IncorrectStateVariant"
|
||||
)
|
||||
)]
|
||||
#[cfg_attr(
|
||||
feature = "arbitrary",
|
||||
@@ -311,9 +330,9 @@ impl<E: EthSpec> ExecPayload<E> for FullPayload<E> {
|
||||
})
|
||||
}
|
||||
|
||||
fn withdrawals_root(&self) -> Result<Hash256, Error> {
|
||||
fn withdrawals_root(&self) -> Result<Hash256, BeaconStateError> {
|
||||
match self {
|
||||
FullPayload::Bellatrix(_) => Err(Error::IncorrectStateVariant),
|
||||
FullPayload::Bellatrix(_) => Err(BeaconStateError::IncorrectStateVariant),
|
||||
FullPayload::Capella(inner) => Ok(inner.execution_payload.withdrawals.tree_hash_root()),
|
||||
FullPayload::Deneb(inner) => Ok(inner.execution_payload.withdrawals.tree_hash_root()),
|
||||
FullPayload::Electra(inner) => Ok(inner.execution_payload.withdrawals.tree_hash_root()),
|
||||
@@ -322,10 +341,10 @@ impl<E: EthSpec> ExecPayload<E> for FullPayload<E> {
|
||||
}
|
||||
}
|
||||
|
||||
fn blob_gas_used(&self) -> Result<u64, Error> {
|
||||
fn blob_gas_used(&self) -> Result<u64, BeaconStateError> {
|
||||
match self {
|
||||
FullPayload::Bellatrix(_) | FullPayload::Capella(_) => {
|
||||
Err(Error::IncorrectStateVariant)
|
||||
Err(BeaconStateError::IncorrectStateVariant)
|
||||
}
|
||||
FullPayload::Deneb(inner) => Ok(inner.execution_payload.blob_gas_used),
|
||||
FullPayload::Electra(inner) => Ok(inner.execution_payload.blob_gas_used),
|
||||
@@ -354,9 +373,9 @@ impl<E: EthSpec> FullPayload<E> {
|
||||
})
|
||||
}
|
||||
|
||||
pub fn default_at_fork(fork_name: ForkName) -> Result<Self, Error> {
|
||||
pub fn default_at_fork(fork_name: ForkName) -> Result<Self, BeaconStateError> {
|
||||
match fork_name {
|
||||
ForkName::Base | ForkName::Altair => Err(Error::IncorrectStateVariant),
|
||||
ForkName::Base | ForkName::Altair => Err(BeaconStateError::IncorrectStateVariant),
|
||||
ForkName::Bellatrix => Ok(FullPayloadBellatrix::default().into()),
|
||||
ForkName::Capella => Ok(FullPayloadCapella::default().into()),
|
||||
ForkName::Deneb => Ok(FullPayloadDeneb::default().into()),
|
||||
@@ -450,9 +469,9 @@ impl<E: EthSpec> ExecPayload<E> for FullPayloadRef<'_, E> {
|
||||
})
|
||||
}
|
||||
|
||||
fn withdrawals_root(&self) -> Result<Hash256, Error> {
|
||||
fn withdrawals_root(&self) -> Result<Hash256, BeaconStateError> {
|
||||
match self {
|
||||
FullPayloadRef::Bellatrix(_) => Err(Error::IncorrectStateVariant),
|
||||
FullPayloadRef::Bellatrix(_) => Err(BeaconStateError::IncorrectStateVariant),
|
||||
FullPayloadRef::Capella(inner) => {
|
||||
Ok(inner.execution_payload.withdrawals.tree_hash_root())
|
||||
}
|
||||
@@ -469,10 +488,10 @@ impl<E: EthSpec> ExecPayload<E> for FullPayloadRef<'_, E> {
|
||||
}
|
||||
}
|
||||
|
||||
fn blob_gas_used(&self) -> Result<u64, Error> {
|
||||
fn blob_gas_used(&self) -> Result<u64, BeaconStateError> {
|
||||
match self {
|
||||
FullPayloadRef::Bellatrix(_) | FullPayloadRef::Capella(_) => {
|
||||
Err(Error::IncorrectStateVariant)
|
||||
Err(BeaconStateError::IncorrectStateVariant)
|
||||
}
|
||||
FullPayloadRef::Deneb(inner) => Ok(inner.execution_payload.blob_gas_used),
|
||||
FullPayloadRef::Electra(inner) => Ok(inner.execution_payload.blob_gas_used),
|
||||
@@ -548,8 +567,14 @@ impl<E: EthSpec> TryFrom<ExecutionPayloadHeader<E>> for FullPayload<E> {
|
||||
tree_hash(enum_behaviour = "transparent"),
|
||||
),
|
||||
map_into(ExecutionPayloadHeader),
|
||||
cast_error(ty = "Error", expr = "BeaconStateError::IncorrectStateVariant"),
|
||||
partial_getter_error(ty = "Error", expr = "BeaconStateError::IncorrectStateVariant")
|
||||
cast_error(
|
||||
ty = "BeaconStateError",
|
||||
expr = "BeaconStateError::IncorrectStateVariant"
|
||||
),
|
||||
partial_getter_error(
|
||||
ty = "BeaconStateError",
|
||||
expr = "BeaconStateError::IncorrectStateVariant"
|
||||
)
|
||||
)]
|
||||
#[cfg_attr(
|
||||
feature = "arbitrary",
|
||||
@@ -658,9 +683,9 @@ impl<E: EthSpec> ExecPayload<E> for BlindedPayload<E> {
|
||||
None
|
||||
}
|
||||
|
||||
fn withdrawals_root(&self) -> Result<Hash256, Error> {
|
||||
fn withdrawals_root(&self) -> Result<Hash256, BeaconStateError> {
|
||||
match self {
|
||||
BlindedPayload::Bellatrix(_) => Err(Error::IncorrectStateVariant),
|
||||
BlindedPayload::Bellatrix(_) => Err(BeaconStateError::IncorrectStateVariant),
|
||||
BlindedPayload::Capella(inner) => Ok(inner.execution_payload_header.withdrawals_root),
|
||||
BlindedPayload::Deneb(inner) => Ok(inner.execution_payload_header.withdrawals_root),
|
||||
BlindedPayload::Electra(inner) => Ok(inner.execution_payload_header.withdrawals_root),
|
||||
@@ -669,10 +694,10 @@ impl<E: EthSpec> ExecPayload<E> for BlindedPayload<E> {
|
||||
}
|
||||
}
|
||||
|
||||
fn blob_gas_used(&self) -> Result<u64, Error> {
|
||||
fn blob_gas_used(&self) -> Result<u64, BeaconStateError> {
|
||||
match self {
|
||||
BlindedPayload::Bellatrix(_) | BlindedPayload::Capella(_) => {
|
||||
Err(Error::IncorrectStateVariant)
|
||||
Err(BeaconStateError::IncorrectStateVariant)
|
||||
}
|
||||
BlindedPayload::Deneb(inner) => Ok(inner.execution_payload_header.blob_gas_used),
|
||||
BlindedPayload::Electra(inner) => Ok(inner.execution_payload_header.blob_gas_used),
|
||||
@@ -766,9 +791,9 @@ impl<'b, E: EthSpec> ExecPayload<E> for BlindedPayloadRef<'b, E> {
|
||||
None
|
||||
}
|
||||
|
||||
fn withdrawals_root(&self) -> Result<Hash256, Error> {
|
||||
fn withdrawals_root(&self) -> Result<Hash256, BeaconStateError> {
|
||||
match self {
|
||||
BlindedPayloadRef::Bellatrix(_) => Err(Error::IncorrectStateVariant),
|
||||
BlindedPayloadRef::Bellatrix(_) => Err(BeaconStateError::IncorrectStateVariant),
|
||||
BlindedPayloadRef::Capella(inner) => {
|
||||
Ok(inner.execution_payload_header.withdrawals_root)
|
||||
}
|
||||
@@ -781,10 +806,10 @@ impl<'b, E: EthSpec> ExecPayload<E> for BlindedPayloadRef<'b, E> {
|
||||
}
|
||||
}
|
||||
|
||||
fn blob_gas_used(&self) -> Result<u64, Error> {
|
||||
fn blob_gas_used(&self) -> Result<u64, BeaconStateError> {
|
||||
match self {
|
||||
BlindedPayloadRef::Bellatrix(_) | BlindedPayloadRef::Capella(_) => {
|
||||
Err(Error::IncorrectStateVariant)
|
||||
Err(BeaconStateError::IncorrectStateVariant)
|
||||
}
|
||||
BlindedPayloadRef::Deneb(inner) => Ok(inner.execution_payload_header.blob_gas_used),
|
||||
BlindedPayloadRef::Electra(inner) => Ok(inner.execution_payload_header.blob_gas_used),
|
||||
@@ -877,12 +902,12 @@ macro_rules! impl_exec_payload_common {
|
||||
f(self)
|
||||
}
|
||||
|
||||
fn withdrawals_root(&self) -> Result<Hash256, Error> {
|
||||
fn withdrawals_root(&self) -> Result<Hash256, BeaconStateError> {
|
||||
let g = $g;
|
||||
g(self)
|
||||
}
|
||||
|
||||
fn blob_gas_used(&self) -> Result<u64, Error> {
|
||||
fn blob_gas_used(&self) -> Result<u64, BeaconStateError> {
|
||||
let h = $h;
|
||||
h(self)
|
||||
}
|
||||
@@ -917,15 +942,16 @@ macro_rules! impl_exec_payload_for_fork {
|
||||
},
|
||||
{ |_| { None } },
|
||||
{
|
||||
let c: for<'a> fn(&'a $wrapper_type_header<E>) -> Result<Hash256, Error> =
|
||||
|payload: &$wrapper_type_header<E>| {
|
||||
let wrapper_ref_type = BlindedPayloadRef::$fork_variant(&payload);
|
||||
wrapper_ref_type.withdrawals_root()
|
||||
};
|
||||
let c: for<'a> fn(
|
||||
&'a $wrapper_type_header<E>,
|
||||
) -> Result<Hash256, BeaconStateError> = |payload: &$wrapper_type_header<E>| {
|
||||
let wrapper_ref_type = BlindedPayloadRef::$fork_variant(&payload);
|
||||
wrapper_ref_type.withdrawals_root()
|
||||
};
|
||||
c
|
||||
},
|
||||
{
|
||||
let c: for<'a> fn(&'a $wrapper_type_header<E>) -> Result<u64, Error> =
|
||||
let c: for<'a> fn(&'a $wrapper_type_header<E>) -> Result<u64, BeaconStateError> =
|
||||
|payload: &$wrapper_type_header<E>| {
|
||||
let wrapper_ref_type = BlindedPayloadRef::$fork_variant(&payload);
|
||||
wrapper_ref_type.blob_gas_used()
|
||||
@@ -935,12 +961,12 @@ macro_rules! impl_exec_payload_for_fork {
|
||||
);
|
||||
|
||||
impl<E: EthSpec> TryInto<$wrapper_type_header<E>> for BlindedPayload<E> {
|
||||
type Error = Error;
|
||||
type Error = BeaconStateError;
|
||||
|
||||
fn try_into(self) -> Result<$wrapper_type_header<E>, Self::Error> {
|
||||
match self {
|
||||
BlindedPayload::$fork_variant(payload) => Ok(payload),
|
||||
_ => Err(Error::IncorrectStateVariant),
|
||||
_ => Err(BeaconStateError::IncorrectStateVariant),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -963,13 +989,13 @@ macro_rules! impl_exec_payload_for_fork {
|
||||
}
|
||||
|
||||
impl<E: EthSpec> TryFrom<ExecutionPayloadHeader<E>> for $wrapper_type_header<E> {
|
||||
type Error = Error;
|
||||
type Error = BeaconStateError;
|
||||
fn try_from(header: ExecutionPayloadHeader<E>) -> Result<Self, Self::Error> {
|
||||
match header {
|
||||
ExecutionPayloadHeader::$fork_variant(execution_payload_header) => {
|
||||
Ok(execution_payload_header.into())
|
||||
}
|
||||
_ => Err(Error::PayloadConversionLogicFlaw),
|
||||
_ => Err(BeaconStateError::PayloadConversionLogicFlaw),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1004,7 +1030,7 @@ macro_rules! impl_exec_payload_for_fork {
|
||||
c
|
||||
},
|
||||
{
|
||||
let c: for<'a> fn(&'a $wrapper_type_full<E>) -> Result<Hash256, Error> =
|
||||
let c: for<'a> fn(&'a $wrapper_type_full<E>) -> Result<Hash256, BeaconStateError> =
|
||||
|payload: &$wrapper_type_full<E>| {
|
||||
let wrapper_ref_type = FullPayloadRef::$fork_variant(&payload);
|
||||
wrapper_ref_type.withdrawals_root()
|
||||
@@ -1012,7 +1038,7 @@ macro_rules! impl_exec_payload_for_fork {
|
||||
c
|
||||
},
|
||||
{
|
||||
let c: for<'a> fn(&'a $wrapper_type_full<E>) -> Result<u64, Error> =
|
||||
let c: for<'a> fn(&'a $wrapper_type_full<E>) -> Result<u64, BeaconStateError> =
|
||||
|payload: &$wrapper_type_full<E>| {
|
||||
let wrapper_ref_type = FullPayloadRef::$fork_variant(&payload);
|
||||
wrapper_ref_type.blob_gas_used()
|
||||
@@ -1039,26 +1065,26 @@ macro_rules! impl_exec_payload_for_fork {
|
||||
}
|
||||
|
||||
impl<E: EthSpec> TryFrom<ExecutionPayloadHeader<E>> for $wrapper_type_full<E> {
|
||||
type Error = Error;
|
||||
type Error = BeaconStateError;
|
||||
fn try_from(_: ExecutionPayloadHeader<E>) -> Result<Self, Self::Error> {
|
||||
Err(Error::PayloadConversionLogicFlaw)
|
||||
Err(BeaconStateError::PayloadConversionLogicFlaw)
|
||||
}
|
||||
}
|
||||
|
||||
impl<E: EthSpec> TryFrom<$wrapped_type_header<E>> for $wrapper_type_full<E> {
|
||||
type Error = Error;
|
||||
type Error = BeaconStateError;
|
||||
fn try_from(_: $wrapped_type_header<E>) -> Result<Self, Self::Error> {
|
||||
Err(Error::PayloadConversionLogicFlaw)
|
||||
Err(BeaconStateError::PayloadConversionLogicFlaw)
|
||||
}
|
||||
}
|
||||
|
||||
impl<E: EthSpec> TryInto<$wrapper_type_full<E>> for FullPayload<E> {
|
||||
type Error = Error;
|
||||
type Error = BeaconStateError;
|
||||
|
||||
fn try_into(self) -> Result<$wrapper_type_full<E>, Self::Error> {
|
||||
match self {
|
||||
FullPayload::$fork_variant(payload) => Ok(payload),
|
||||
_ => Err(Error::PayloadConversionLogicFlaw),
|
||||
_ => Err(BeaconStateError::PayloadConversionLogicFlaw),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,10 +1,12 @@
|
||||
use crate::test_utils::TestRandom;
|
||||
use crate::*;
|
||||
use bls::Signature;
|
||||
use context_deserialize::context_deserialize;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use ssz_derive::{Decode, Encode};
|
||||
use test_random_derive::TestRandom;
|
||||
use tree_hash_derive::TreeHash;
|
||||
|
||||
use crate::{execution::BlsToExecutionChange, fork::ForkName, test_utils::TestRandom};
|
||||
|
||||
#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
|
||||
#[derive(
|
||||
Debug, PartialEq, Eq, Hash, Clone, Serialize, Deserialize, Encode, Decode, TreeHash, TestRandom,
|
||||
5
consensus/types/src/exit/mod.rs
Normal file
5
consensus/types/src/exit/mod.rs
Normal file
@@ -0,0 +1,5 @@
|
||||
mod signed_voluntary_exit;
|
||||
mod voluntary_exit;
|
||||
|
||||
pub use signed_voluntary_exit::SignedVoluntaryExit;
|
||||
pub use voluntary_exit::VoluntaryExit;
|
||||
@@ -1,12 +1,12 @@
|
||||
use crate::context_deserialize;
|
||||
use crate::{ForkName, VoluntaryExit, test_utils::TestRandom};
|
||||
use bls::Signature;
|
||||
|
||||
use context_deserialize::context_deserialize;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use ssz_derive::{Decode, Encode};
|
||||
use test_random_derive::TestRandom;
|
||||
use tree_hash_derive::TreeHash;
|
||||
|
||||
use crate::{exit::VoluntaryExit, fork::ForkName, test_utils::TestRandom};
|
||||
|
||||
/// An exit voluntarily submitted a validator who wishes to withdraw.
|
||||
///
|
||||
/// Spec v0.12.1
|
||||
@@ -1,14 +1,17 @@
|
||||
use crate::context_deserialize;
|
||||
use crate::{
|
||||
ChainSpec, Domain, Epoch, ForkName, Hash256, SecretKey, SignedRoot, SignedVoluntaryExit,
|
||||
test_utils::TestRandom,
|
||||
};
|
||||
|
||||
use bls::SecretKey;
|
||||
use context_deserialize::context_deserialize;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use ssz_derive::{Decode, Encode};
|
||||
use test_random_derive::TestRandom;
|
||||
use tree_hash_derive::TreeHash;
|
||||
|
||||
use crate::{
|
||||
core::{ChainSpec, Domain, Epoch, Hash256, SignedRoot},
|
||||
exit::SignedVoluntaryExit,
|
||||
fork::ForkName,
|
||||
test_utils::TestRandom,
|
||||
};
|
||||
|
||||
/// An exit voluntarily submitted a validator who wishes to withdraw.
|
||||
///
|
||||
/// Spec v0.12.1
|
||||
@@ -1,12 +1,11 @@
|
||||
use crate::test_utils::TestRandom;
|
||||
use crate::{Epoch, ForkName};
|
||||
use context_deserialize::context_deserialize;
|
||||
|
||||
use serde::{Deserialize, Serialize};
|
||||
use ssz_derive::{Decode, Encode};
|
||||
use test_random_derive::TestRandom;
|
||||
use tree_hash_derive::TreeHash;
|
||||
|
||||
use crate::{core::Epoch, fork::ForkName, test_utils::TestRandom};
|
||||
|
||||
/// Specifies a fork of the `BeaconChain`, to prevent replay attacks.
|
||||
///
|
||||
/// Spec v0.12.1
|
||||
@@ -1,7 +1,11 @@
|
||||
use std::collections::BTreeMap;
|
||||
|
||||
use parking_lot::RwLock;
|
||||
|
||||
use crate::{ChainSpec, Epoch, EthSpec, ForkName, Hash256, Slot};
|
||||
use std::collections::BTreeMap;
|
||||
use crate::{
|
||||
core::{ChainSpec, Epoch, EthSpec, Hash256, Slot},
|
||||
fork::ForkName,
|
||||
};
|
||||
|
||||
/// Represents a hard fork in the consensus protocol.
|
||||
///
|
||||
@@ -152,8 +156,7 @@ impl ForkContext {
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use crate::MainnetEthSpec;
|
||||
use crate::chain_spec::{BlobParameters, BlobSchedule};
|
||||
use crate::core::{BlobParameters, BlobSchedule, MainnetEthSpec};
|
||||
|
||||
type E = MainnetEthSpec;
|
||||
|
||||
@@ -1,12 +1,15 @@
|
||||
use crate::test_utils::TestRandom;
|
||||
use crate::{ForkName, Hash256, SignedRoot};
|
||||
use context_deserialize::context_deserialize;
|
||||
|
||||
use serde::{Deserialize, Serialize};
|
||||
use ssz_derive::{Decode, Encode};
|
||||
use test_random_derive::TestRandom;
|
||||
use tree_hash_derive::TreeHash;
|
||||
|
||||
use crate::{
|
||||
core::{Hash256, SignedRoot},
|
||||
fork::ForkName,
|
||||
test_utils::TestRandom,
|
||||
};
|
||||
|
||||
/// Specifies a fork of the `BeaconChain`, to prevent replay attacks.
|
||||
///
|
||||
/// Spec v0.12.1
|
||||
60
consensus/types/src/fork/fork_macros.rs
Normal file
60
consensus/types/src/fork/fork_macros.rs
Normal file
@@ -0,0 +1,60 @@
|
||||
/// Map a fork name into a fork-versioned superstruct type like `BeaconBlock`.
|
||||
///
|
||||
/// The `$body` expression is where the magic happens. The macro allows us to achieve polymorphism
|
||||
/// in the return type, which is not usually possible in Rust without trait objects.
|
||||
///
|
||||
/// E.g. you could call `map_fork_name!(fork, BeaconBlock, serde_json::from_str(s))` to decode
|
||||
/// different `BeaconBlock` variants depending on the value of `fork`. Note how the type of the body
|
||||
/// will change between `BeaconBlockBase` and `BeaconBlockAltair` depending on which branch is
|
||||
/// taken, the important thing is that they are re-unified by injecting them back into the
|
||||
/// `BeaconBlock` parent enum.
|
||||
///
|
||||
/// If you would also like to extract additional data alongside the superstruct type, use
|
||||
/// the more flexible `map_fork_name_with` macro.
|
||||
#[macro_export]
|
||||
macro_rules! map_fork_name {
|
||||
($fork_name:expr, $t:tt, $body:expr) => {
|
||||
$crate::map_fork_name_with!($fork_name, $t, { ($body, ()) }).0
|
||||
};
|
||||
}
|
||||
|
||||
/// Map a fork name into a tuple of `(t, extra)` where `t` is a superstruct type.
|
||||
#[macro_export]
|
||||
macro_rules! map_fork_name_with {
|
||||
($fork_name:expr, $t:tt, $body:block) => {
|
||||
match $fork_name {
|
||||
$crate::fork::ForkName::Base => {
|
||||
let (value, extra_data) = $body;
|
||||
($t::Base(value), extra_data)
|
||||
}
|
||||
$crate::fork::ForkName::Altair => {
|
||||
let (value, extra_data) = $body;
|
||||
($t::Altair(value), extra_data)
|
||||
}
|
||||
$crate::fork::ForkName::Bellatrix => {
|
||||
let (value, extra_data) = $body;
|
||||
($t::Bellatrix(value), extra_data)
|
||||
}
|
||||
$crate::fork::ForkName::Capella => {
|
||||
let (value, extra_data) = $body;
|
||||
($t::Capella(value), extra_data)
|
||||
}
|
||||
$crate::fork::ForkName::Deneb => {
|
||||
let (value, extra_data) = $body;
|
||||
($t::Deneb(value), extra_data)
|
||||
}
|
||||
$crate::fork::ForkName::Electra => {
|
||||
let (value, extra_data) = $body;
|
||||
($t::Electra(value), extra_data)
|
||||
}
|
||||
$crate::fork::ForkName::Fulu => {
|
||||
let (value, extra_data) = $body;
|
||||
($t::Fulu(value), extra_data)
|
||||
}
|
||||
$crate::fork::ForkName::Gloas => {
|
||||
let (value, extra_data) = $body;
|
||||
($t::Gloas(value), extra_data)
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -1,8 +1,12 @@
|
||||
use crate::{ChainSpec, Epoch};
|
||||
use std::{
|
||||
fmt::{self, Display, Formatter},
|
||||
str::FromStr,
|
||||
};
|
||||
|
||||
use serde::{Deserialize, Serialize};
|
||||
use ssz_derive::{Decode, Encode};
|
||||
use std::fmt::{self, Display, Formatter};
|
||||
use std::str::FromStr;
|
||||
|
||||
use crate::core::{ChainSpec, Epoch};
|
||||
|
||||
#[derive(
|
||||
Debug, Clone, Copy, Decode, Encode, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize,
|
||||
@@ -243,67 +247,6 @@ impl ForkName {
|
||||
}
|
||||
}
|
||||
|
||||
/// Map a fork name into a fork-versioned superstruct type like `BeaconBlock`.
|
||||
///
|
||||
/// The `$body` expression is where the magic happens. The macro allows us to achieve polymorphism
|
||||
/// in the return type, which is not usually possible in Rust without trait objects.
|
||||
///
|
||||
/// E.g. you could call `map_fork_name!(fork, BeaconBlock, serde_json::from_str(s))` to decode
|
||||
/// different `BeaconBlock` variants depending on the value of `fork`. Note how the type of the body
|
||||
/// will change between `BeaconBlockBase` and `BeaconBlockAltair` depending on which branch is
|
||||
/// taken, the important thing is that they are re-unified by injecting them back into the
|
||||
/// `BeaconBlock` parent enum.
|
||||
///
|
||||
/// If you would also like to extract additional data alongside the superstruct type, use
|
||||
/// the more flexible `map_fork_name_with` macro.
|
||||
#[macro_export]
|
||||
macro_rules! map_fork_name {
|
||||
($fork_name:expr, $t:tt, $body:expr) => {
|
||||
map_fork_name_with!($fork_name, $t, { ($body, ()) }).0
|
||||
};
|
||||
}
|
||||
|
||||
/// Map a fork name into a tuple of `(t, extra)` where `t` is a superstruct type.
|
||||
#[macro_export]
|
||||
macro_rules! map_fork_name_with {
|
||||
($fork_name:expr, $t:tt, $body:block) => {
|
||||
match $fork_name {
|
||||
ForkName::Base => {
|
||||
let (value, extra_data) = $body;
|
||||
($t::Base(value), extra_data)
|
||||
}
|
||||
ForkName::Altair => {
|
||||
let (value, extra_data) = $body;
|
||||
($t::Altair(value), extra_data)
|
||||
}
|
||||
ForkName::Bellatrix => {
|
||||
let (value, extra_data) = $body;
|
||||
($t::Bellatrix(value), extra_data)
|
||||
}
|
||||
ForkName::Capella => {
|
||||
let (value, extra_data) = $body;
|
||||
($t::Capella(value), extra_data)
|
||||
}
|
||||
ForkName::Deneb => {
|
||||
let (value, extra_data) = $body;
|
||||
($t::Deneb(value), extra_data)
|
||||
}
|
||||
ForkName::Electra => {
|
||||
let (value, extra_data) = $body;
|
||||
($t::Electra(value), extra_data)
|
||||
}
|
||||
ForkName::Fulu => {
|
||||
let (value, extra_data) = $body;
|
||||
($t::Fulu(value), extra_data)
|
||||
}
|
||||
ForkName::Gloas => {
|
||||
let (value, extra_data) = $body;
|
||||
($t::Gloas(value), extra_data)
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
impl FromStr for ForkName {
|
||||
type Err = String;
|
||||
|
||||
6
consensus/types/src/fork/fork_version_decode.rs
Normal file
6
consensus/types/src/fork/fork_version_decode.rs
Normal file
@@ -0,0 +1,6 @@
|
||||
use crate::fork::ForkName;
|
||||
|
||||
pub trait ForkVersionDecode: Sized {
|
||||
/// SSZ decode with explicit fork variant.
|
||||
fn from_ssz_bytes_by_fork(bytes: &[u8], fork_name: ForkName) -> Result<Self, ssz::DecodeError>;
|
||||
}
|
||||
15
consensus/types/src/fork/mod.rs
Normal file
15
consensus/types/src/fork/mod.rs
Normal file
@@ -0,0 +1,15 @@
|
||||
mod fork;
|
||||
mod fork_context;
|
||||
mod fork_data;
|
||||
mod fork_macros;
|
||||
mod fork_name;
|
||||
mod fork_version_decode;
|
||||
|
||||
pub use crate::{map_fork_name, map_fork_name_with};
|
||||
pub use fork::Fork;
|
||||
pub use fork_context::{ForkContext, HardFork};
|
||||
pub use fork_data::ForkData;
|
||||
pub use fork_name::{ForkName, InconsistentFork};
|
||||
pub use fork_version_decode::ForkVersionDecode;
|
||||
|
||||
pub type ForkVersion = [u8; 4];
|
||||
3
consensus/types/src/kzg_ext/consts.rs
Normal file
3
consensus/types/src/kzg_ext/consts.rs
Normal file
@@ -0,0 +1,3 @@
|
||||
pub use kzg::{
|
||||
BYTES_PER_BLOB, BYTES_PER_COMMITMENT, BYTES_PER_FIELD_ELEMENT, VERSIONED_HASH_VERSION_KZG,
|
||||
};
|
||||
27
consensus/types/src/kzg_ext/mod.rs
Normal file
27
consensus/types/src/kzg_ext/mod.rs
Normal file
@@ -0,0 +1,27 @@
|
||||
pub mod consts;
|
||||
|
||||
pub use kzg::{Blob as KzgBlob, Error as KzgError, Kzg, KzgCommitment, KzgProof};
|
||||
|
||||
use ssz_types::VariableList;
|
||||
|
||||
use crate::core::EthSpec;
|
||||
|
||||
// Note on List limit:
|
||||
// - Deneb to Electra: `MaxBlobCommitmentsPerBlock`
|
||||
// - Fulu: `MaxCellsPerBlock`
|
||||
// We choose to use a single type (with the larger value from Fulu as `N`) instead of having to
|
||||
// introduce a new type for Fulu. This is to avoid messy conversions and having to add extra types
|
||||
// with no gains - as `N` does not impact serialisation at all, and only affects merkleization,
|
||||
// which we don't current do on `KzgProofs` anyway.
|
||||
pub type KzgProofs<E> = VariableList<KzgProof, <E as EthSpec>::MaxCellsPerBlock>;
|
||||
|
||||
pub type KzgCommitments<E> =
|
||||
VariableList<KzgCommitment, <E as EthSpec>::MaxBlobCommitmentsPerBlock>;
|
||||
|
||||
/// Util method helpful for logging.
|
||||
pub fn format_kzg_commitments(commitments: &[KzgCommitment]) -> String {
|
||||
let commitment_strings: Vec<String> = commitments.iter().map(|x| x.to_string()).collect();
|
||||
let commitments_joined = commitment_strings.join(", ");
|
||||
let surrounded_commitments = format!("[{}]", commitments_joined);
|
||||
surrounded_commitments
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
//! Ethereum 2.0 types
|
||||
//! Ethereum Consensus types
|
||||
// Clippy lint set up
|
||||
#![cfg_attr(
|
||||
not(test),
|
||||
@@ -12,287 +12,167 @@
|
||||
#[macro_use]
|
||||
pub mod test_utils;
|
||||
|
||||
pub mod aggregate_and_proof;
|
||||
pub mod application_domain;
|
||||
pub mod attestation;
|
||||
pub mod attestation_data;
|
||||
pub mod attestation_duty;
|
||||
pub mod attester_slashing;
|
||||
pub mod beacon_block;
|
||||
pub mod beacon_block_body;
|
||||
pub mod beacon_block_header;
|
||||
pub mod beacon_committee;
|
||||
pub mod beacon_response;
|
||||
pub mod beacon_state;
|
||||
pub mod bls_to_execution_change;
|
||||
pub mod builder_bid;
|
||||
pub mod chain_spec;
|
||||
pub mod checkpoint;
|
||||
pub mod consolidation_request;
|
||||
pub mod consts;
|
||||
pub mod contribution_and_proof;
|
||||
pub mod block;
|
||||
pub mod builder;
|
||||
pub mod consolidation;
|
||||
pub mod core;
|
||||
pub mod data;
|
||||
pub mod deposit;
|
||||
pub mod deposit_data;
|
||||
pub mod deposit_message;
|
||||
pub mod deposit_request;
|
||||
pub mod deposit_tree_snapshot;
|
||||
pub mod enr_fork_id;
|
||||
pub mod eth1_data;
|
||||
pub mod eth_spec;
|
||||
pub mod execution_block_hash;
|
||||
pub mod execution_payload;
|
||||
pub mod execution_payload_header;
|
||||
pub mod execution;
|
||||
pub mod exit;
|
||||
pub mod fork;
|
||||
pub mod fork_data;
|
||||
pub mod fork_name;
|
||||
pub mod graffiti;
|
||||
pub mod historical_batch;
|
||||
pub mod historical_summary;
|
||||
pub mod indexed_attestation;
|
||||
pub mod light_client_bootstrap;
|
||||
pub mod light_client_finality_update;
|
||||
pub mod light_client_optimistic_update;
|
||||
pub mod light_client_update;
|
||||
pub mod pending_attestation;
|
||||
pub mod pending_consolidation;
|
||||
pub mod pending_deposit;
|
||||
pub mod pending_partial_withdrawal;
|
||||
pub mod proposer_preparation_data;
|
||||
pub mod proposer_slashing;
|
||||
pub mod relative_epoch;
|
||||
pub mod selection_proof;
|
||||
pub mod shuffling_id;
|
||||
pub mod signed_aggregate_and_proof;
|
||||
pub mod signed_beacon_block;
|
||||
pub mod signed_beacon_block_header;
|
||||
pub mod signed_bls_to_execution_change;
|
||||
pub mod signed_contribution_and_proof;
|
||||
pub mod signed_voluntary_exit;
|
||||
pub mod signing_data;
|
||||
pub mod sync_committee_subscription;
|
||||
pub mod sync_duty;
|
||||
pub mod validator;
|
||||
pub mod validator_subscription;
|
||||
pub mod voluntary_exit;
|
||||
pub mod withdrawal_credentials;
|
||||
pub mod withdrawal_request;
|
||||
#[macro_use]
|
||||
pub mod slot_epoch_macros;
|
||||
pub mod activation_queue;
|
||||
pub mod config_and_preset;
|
||||
pub mod execution_block_header;
|
||||
pub mod execution_requests;
|
||||
pub mod fork_context;
|
||||
pub mod participation_flags;
|
||||
pub mod payload;
|
||||
pub mod preset;
|
||||
pub mod slot_epoch;
|
||||
pub mod subnet_id;
|
||||
pub mod sync_aggregate;
|
||||
pub mod sync_aggregator_selection_data;
|
||||
pub mod kzg_ext;
|
||||
pub mod light_client;
|
||||
pub mod slashing;
|
||||
pub mod state;
|
||||
pub mod sync_committee;
|
||||
pub mod sync_committee_contribution;
|
||||
pub mod sync_committee_message;
|
||||
pub mod sync_selection_proof;
|
||||
pub mod sync_subnet_id;
|
||||
pub mod validator_registration_data;
|
||||
pub mod validator;
|
||||
pub mod withdrawal;
|
||||
|
||||
pub mod epoch_cache;
|
||||
pub mod slot_data;
|
||||
#[cfg(feature = "sqlite")]
|
||||
pub mod sqlite;
|
||||
// Temporary root level exports to maintain backwards compatibility for Lighthouse.
|
||||
pub use attestation::*;
|
||||
pub use block::*;
|
||||
pub use builder::*;
|
||||
pub use consolidation::*;
|
||||
pub use core::{consts, *};
|
||||
pub use data::*;
|
||||
pub use deposit::*;
|
||||
pub use execution::*;
|
||||
pub use exit::*;
|
||||
pub use fork::*;
|
||||
pub use kzg_ext::*;
|
||||
pub use light_client::*;
|
||||
pub use slashing::*;
|
||||
pub use state::*;
|
||||
pub use sync_committee::*;
|
||||
pub use validator::*;
|
||||
pub use withdrawal::*;
|
||||
|
||||
pub mod blob_sidecar;
|
||||
pub mod data_column_custody_group;
|
||||
pub mod data_column_sidecar;
|
||||
pub mod data_column_subnet_id;
|
||||
pub mod light_client_header;
|
||||
pub mod non_zero_usize;
|
||||
pub mod runtime_fixed_vector;
|
||||
pub mod runtime_var_list;
|
||||
// Temporary facade modules to maintain backwards compatibility for Lighthouse.
|
||||
pub mod eth_spec {
|
||||
pub use crate::core::EthSpec;
|
||||
}
|
||||
|
||||
pub use crate::activation_queue::ActivationQueue;
|
||||
pub use crate::aggregate_and_proof::{
|
||||
AggregateAndProof, AggregateAndProofBase, AggregateAndProofElectra, AggregateAndProofRef,
|
||||
};
|
||||
pub use crate::attestation::{
|
||||
Attestation, AttestationBase, AttestationElectra, AttestationRef, AttestationRefMut,
|
||||
Error as AttestationError, SingleAttestation,
|
||||
};
|
||||
pub use crate::attestation_data::AttestationData;
|
||||
pub use crate::attestation_duty::AttestationDuty;
|
||||
pub use crate::attester_slashing::{
|
||||
AttesterSlashing, AttesterSlashingBase, AttesterSlashingElectra, AttesterSlashingOnDisk,
|
||||
AttesterSlashingRef, AttesterSlashingRefOnDisk,
|
||||
};
|
||||
pub use crate::beacon_block::{
|
||||
BeaconBlock, BeaconBlockAltair, BeaconBlockBase, BeaconBlockBellatrix, BeaconBlockCapella,
|
||||
BeaconBlockDeneb, BeaconBlockElectra, BeaconBlockFulu, BeaconBlockGloas, BeaconBlockRef,
|
||||
BeaconBlockRefMut, BlindedBeaconBlock, BlockImportSource, EmptyBlock,
|
||||
};
|
||||
pub use crate::beacon_block_body::{
|
||||
BeaconBlockBody, BeaconBlockBodyAltair, BeaconBlockBodyBase, BeaconBlockBodyBellatrix,
|
||||
BeaconBlockBodyCapella, BeaconBlockBodyDeneb, BeaconBlockBodyElectra, BeaconBlockBodyFulu,
|
||||
BeaconBlockBodyGloas, BeaconBlockBodyRef, BeaconBlockBodyRefMut,
|
||||
};
|
||||
pub use crate::beacon_block_header::BeaconBlockHeader;
|
||||
pub use crate::beacon_committee::{BeaconCommittee, OwnedBeaconCommittee};
|
||||
pub use crate::beacon_response::{
|
||||
BeaconResponse, ForkVersionDecode, ForkVersionedResponse, UnversionedResponse,
|
||||
};
|
||||
pub use crate::beacon_state::{Error as BeaconStateError, *};
|
||||
pub use crate::blob_sidecar::{BlobIdentifier, BlobSidecar, BlobSidecarList, BlobsList};
|
||||
pub use crate::bls_to_execution_change::BlsToExecutionChange;
|
||||
pub use crate::chain_spec::{ChainSpec, Config, Domain};
|
||||
pub use crate::checkpoint::Checkpoint;
|
||||
pub use crate::config_and_preset::{
|
||||
ConfigAndPreset, ConfigAndPresetDeneb, ConfigAndPresetElectra, ConfigAndPresetFulu,
|
||||
ConfigAndPresetGloas,
|
||||
};
|
||||
pub use crate::consolidation_request::ConsolidationRequest;
|
||||
pub use crate::contribution_and_proof::ContributionAndProof;
|
||||
pub use crate::data_column_sidecar::{
|
||||
ColumnIndex, DataColumnSidecar, DataColumnSidecarList, DataColumnsByRootIdentifier,
|
||||
};
|
||||
pub use crate::data_column_subnet_id::DataColumnSubnetId;
|
||||
pub use crate::deposit::{DEPOSIT_TREE_DEPTH, Deposit};
|
||||
pub use crate::deposit_data::DepositData;
|
||||
pub use crate::deposit_message::DepositMessage;
|
||||
pub use crate::deposit_request::DepositRequest;
|
||||
pub use crate::deposit_tree_snapshot::{DepositTreeSnapshot, FinalizedExecutionBlock};
|
||||
pub use crate::enr_fork_id::EnrForkId;
|
||||
pub use crate::epoch_cache::{EpochCache, EpochCacheError, EpochCacheKey};
|
||||
pub use crate::eth_spec::EthSpecId;
|
||||
pub use crate::eth1_data::Eth1Data;
|
||||
pub use crate::execution_block_hash::ExecutionBlockHash;
|
||||
pub use crate::execution_block_header::{EncodableExecutionBlockHeader, ExecutionBlockHeader};
|
||||
pub use crate::execution_payload::{
|
||||
ExecutionPayload, ExecutionPayloadBellatrix, ExecutionPayloadCapella, ExecutionPayloadDeneb,
|
||||
ExecutionPayloadElectra, ExecutionPayloadFulu, ExecutionPayloadGloas, ExecutionPayloadRef,
|
||||
Transaction, Transactions, Withdrawals,
|
||||
};
|
||||
pub use crate::execution_payload_header::{
|
||||
ExecutionPayloadHeader, ExecutionPayloadHeaderBellatrix, ExecutionPayloadHeaderCapella,
|
||||
ExecutionPayloadHeaderDeneb, ExecutionPayloadHeaderElectra, ExecutionPayloadHeaderFulu,
|
||||
ExecutionPayloadHeaderGloas, ExecutionPayloadHeaderRef, ExecutionPayloadHeaderRefMut,
|
||||
};
|
||||
pub use crate::execution_requests::{ExecutionRequests, RequestType};
|
||||
pub use crate::fork::Fork;
|
||||
pub use crate::fork_context::ForkContext;
|
||||
pub use crate::fork_data::ForkData;
|
||||
pub use crate::fork_name::{ForkName, InconsistentFork};
|
||||
pub use crate::graffiti::{GRAFFITI_BYTES_LEN, Graffiti};
|
||||
pub use crate::historical_batch::HistoricalBatch;
|
||||
pub use crate::indexed_attestation::{
|
||||
IndexedAttestation, IndexedAttestationBase, IndexedAttestationElectra, IndexedAttestationRef,
|
||||
};
|
||||
pub use crate::light_client_bootstrap::{
|
||||
LightClientBootstrap, LightClientBootstrapAltair, LightClientBootstrapCapella,
|
||||
LightClientBootstrapDeneb, LightClientBootstrapElectra, LightClientBootstrapFulu,
|
||||
LightClientBootstrapGloas,
|
||||
};
|
||||
pub use crate::light_client_finality_update::{
|
||||
LightClientFinalityUpdate, LightClientFinalityUpdateAltair, LightClientFinalityUpdateCapella,
|
||||
LightClientFinalityUpdateDeneb, LightClientFinalityUpdateElectra,
|
||||
LightClientFinalityUpdateFulu, LightClientFinalityUpdateGloas,
|
||||
};
|
||||
pub use crate::light_client_header::{
|
||||
LightClientHeader, LightClientHeaderAltair, LightClientHeaderCapella, LightClientHeaderDeneb,
|
||||
LightClientHeaderElectra, LightClientHeaderFulu, LightClientHeaderGloas,
|
||||
};
|
||||
pub use crate::light_client_optimistic_update::{
|
||||
LightClientOptimisticUpdate, LightClientOptimisticUpdateAltair,
|
||||
LightClientOptimisticUpdateCapella, LightClientOptimisticUpdateDeneb,
|
||||
LightClientOptimisticUpdateElectra, LightClientOptimisticUpdateFulu,
|
||||
LightClientOptimisticUpdateGloas,
|
||||
};
|
||||
pub use crate::light_client_update::{
|
||||
Error as LightClientUpdateError, LightClientUpdate, LightClientUpdateAltair,
|
||||
LightClientUpdateCapella, LightClientUpdateDeneb, LightClientUpdateElectra,
|
||||
LightClientUpdateFulu, LightClientUpdateGloas, MerkleProof,
|
||||
};
|
||||
pub use crate::participation_flags::ParticipationFlags;
|
||||
pub use crate::payload::{
|
||||
AbstractExecPayload, BlindedPayload, BlindedPayloadBellatrix, BlindedPayloadCapella,
|
||||
BlindedPayloadDeneb, BlindedPayloadElectra, BlindedPayloadFulu, BlindedPayloadGloas,
|
||||
BlindedPayloadRef, BlockType, ExecPayload, FullPayload, FullPayloadBellatrix,
|
||||
FullPayloadCapella, FullPayloadDeneb, FullPayloadElectra, FullPayloadFulu, FullPayloadGloas,
|
||||
FullPayloadRef, OwnedExecPayload,
|
||||
};
|
||||
pub use crate::pending_attestation::PendingAttestation;
|
||||
pub use crate::pending_consolidation::PendingConsolidation;
|
||||
pub use crate::pending_deposit::PendingDeposit;
|
||||
pub use crate::pending_partial_withdrawal::PendingPartialWithdrawal;
|
||||
pub use crate::preset::{
|
||||
AltairPreset, BasePreset, BellatrixPreset, CapellaPreset, DenebPreset, ElectraPreset,
|
||||
FuluPreset, GloasPreset,
|
||||
};
|
||||
pub use crate::proposer_preparation_data::ProposerPreparationData;
|
||||
pub use crate::proposer_slashing::ProposerSlashing;
|
||||
pub use crate::relative_epoch::{Error as RelativeEpochError, RelativeEpoch};
|
||||
pub use crate::runtime_fixed_vector::RuntimeFixedVector;
|
||||
pub use crate::runtime_var_list::RuntimeVariableList;
|
||||
pub use crate::selection_proof::SelectionProof;
|
||||
pub use crate::shuffling_id::AttestationShufflingId;
|
||||
pub use crate::signed_aggregate_and_proof::{
|
||||
SignedAggregateAndProof, SignedAggregateAndProofBase, SignedAggregateAndProofElectra,
|
||||
};
|
||||
pub use crate::signed_beacon_block::{
|
||||
SignedBeaconBlock, SignedBeaconBlockAltair, SignedBeaconBlockBase, SignedBeaconBlockBellatrix,
|
||||
SignedBeaconBlockCapella, SignedBeaconBlockDeneb, SignedBeaconBlockElectra,
|
||||
SignedBeaconBlockFulu, SignedBeaconBlockGloas, SignedBeaconBlockHash, SignedBlindedBeaconBlock,
|
||||
ssz_tagged_signed_beacon_block, ssz_tagged_signed_beacon_block_arc,
|
||||
};
|
||||
pub use crate::signed_beacon_block_header::SignedBeaconBlockHeader;
|
||||
pub use crate::signed_bls_to_execution_change::SignedBlsToExecutionChange;
|
||||
pub use crate::signed_contribution_and_proof::SignedContributionAndProof;
|
||||
pub use crate::signed_voluntary_exit::SignedVoluntaryExit;
|
||||
pub use crate::signing_data::{SignedRoot, SigningData};
|
||||
pub use crate::slot_epoch::{Epoch, Slot};
|
||||
pub use crate::subnet_id::SubnetId;
|
||||
pub use crate::sync_aggregate::SyncAggregate;
|
||||
pub use crate::sync_aggregator_selection_data::SyncAggregatorSelectionData;
|
||||
pub use crate::sync_committee::SyncCommittee;
|
||||
pub use crate::sync_committee_contribution::{SyncCommitteeContribution, SyncContributionData};
|
||||
pub use crate::sync_committee_message::SyncCommitteeMessage;
|
||||
pub use crate::sync_committee_subscription::SyncCommitteeSubscription;
|
||||
pub use crate::sync_duty::SyncDuty;
|
||||
pub use crate::sync_selection_proof::SyncSelectionProof;
|
||||
pub use crate::sync_subnet_id::SyncSubnetId;
|
||||
pub use crate::validator::Validator;
|
||||
pub use crate::validator_registration_data::*;
|
||||
pub use crate::validator_subscription::ValidatorSubscription;
|
||||
pub use crate::voluntary_exit::VoluntaryExit;
|
||||
pub use crate::withdrawal::Withdrawal;
|
||||
pub use crate::withdrawal_credentials::WithdrawalCredentials;
|
||||
pub use crate::withdrawal_request::WithdrawalRequest;
|
||||
pub use fixed_bytes::FixedBytesExtended;
|
||||
pub mod chain_spec {
|
||||
pub use crate::core::ChainSpec;
|
||||
}
|
||||
|
||||
pub type CommitteeIndex = u64;
|
||||
pub type Hash256 = fixed_bytes::Hash256;
|
||||
pub type Uint256 = fixed_bytes::Uint256;
|
||||
pub type Address = fixed_bytes::Address;
|
||||
pub type ForkVersion = [u8; 4];
|
||||
pub type BLSFieldElement = Uint256;
|
||||
pub type Blob<E> = FixedVector<u8, <E as EthSpec>::BytesPerBlob>;
|
||||
// Note on List limit:
|
||||
// - Deneb to Electra: `MaxBlobCommitmentsPerBlock`
|
||||
// - Fulu: `MaxCellsPerBlock`
|
||||
// We choose to use a single type (with the larger value from Fulu as `N`) instead of having to
|
||||
// introduce a new type for Fulu. This is to avoid messy conversions and having to add extra types
|
||||
// with no gains - as `N` does not impact serialisation at all, and only affects merkleization,
|
||||
// which we don't current do on `KzgProofs` anyway.
|
||||
pub type KzgProofs<E> = VariableList<KzgProof, <E as EthSpec>::MaxCellsPerBlock>;
|
||||
pub type VersionedHash = Hash256;
|
||||
pub type Hash64 = alloy_primitives::B64;
|
||||
pub mod beacon_block {
|
||||
pub use crate::block::{BlindedBeaconBlock, BlockImportSource};
|
||||
}
|
||||
|
||||
pub mod beacon_block_body {
|
||||
pub use crate::kzg_ext::{KzgCommitments, format_kzg_commitments};
|
||||
}
|
||||
|
||||
pub mod beacon_state {
|
||||
pub use crate::state::{
|
||||
BeaconState, BeaconStateBase, CommitteeCache, compute_committee_index_in_epoch,
|
||||
compute_committee_range_in_epoch, epoch_committee_count,
|
||||
};
|
||||
}
|
||||
|
||||
pub mod graffiti {
|
||||
pub use crate::core::GraffitiString;
|
||||
}
|
||||
|
||||
pub mod indexed_attestation {
|
||||
pub use crate::attestation::{IndexedAttestationBase, IndexedAttestationElectra};
|
||||
}
|
||||
|
||||
pub mod historical_summary {
|
||||
pub use crate::state::HistoricalSummary;
|
||||
}
|
||||
|
||||
pub mod participation_flags {
|
||||
pub use crate::attestation::ParticipationFlags;
|
||||
}
|
||||
|
||||
pub mod epoch_cache {
|
||||
pub use crate::state::{EpochCache, EpochCacheError, EpochCacheKey};
|
||||
}
|
||||
|
||||
pub mod non_zero_usize {
|
||||
pub use crate::core::new_non_zero_usize;
|
||||
}
|
||||
|
||||
pub mod data_column_sidecar {
|
||||
pub use crate::data::{
|
||||
Cell, ColumnIndex, DataColumn, DataColumnSidecar, DataColumnSidecarError,
|
||||
DataColumnSidecarList,
|
||||
};
|
||||
}
|
||||
|
||||
pub mod builder_bid {
|
||||
pub use crate::builder::*;
|
||||
}
|
||||
|
||||
pub mod blob_sidecar {
|
||||
pub use crate::data::{
|
||||
BlobIdentifier, BlobSidecar, BlobSidecarError, BlobsList, FixedBlobSidecarList,
|
||||
};
|
||||
}
|
||||
|
||||
pub mod payload {
|
||||
pub use crate::execution::BlockProductionVersion;
|
||||
}
|
||||
|
||||
pub mod execution_requests {
|
||||
pub use crate::execution::{
|
||||
ConsolidationRequests, DepositRequests, ExecutionRequests, RequestType, WithdrawalRequests,
|
||||
};
|
||||
}
|
||||
|
||||
pub mod data_column_custody_group {
|
||||
pub use crate::data::{
|
||||
CustodyIndex, compute_columns_for_custody_group, compute_ordered_custody_column_indices,
|
||||
compute_subnets_for_node, compute_subnets_from_custody_group, get_custody_groups,
|
||||
};
|
||||
}
|
||||
|
||||
pub mod sync_aggregate {
|
||||
pub use crate::sync_committee::SyncAggregateError as Error;
|
||||
}
|
||||
|
||||
pub mod light_client_update {
|
||||
pub use crate::light_client::consts::{
|
||||
CURRENT_SYNC_COMMITTEE_INDEX, CURRENT_SYNC_COMMITTEE_INDEX_ELECTRA, FINALIZED_ROOT_INDEX,
|
||||
FINALIZED_ROOT_INDEX_ELECTRA, MAX_REQUEST_LIGHT_CLIENT_UPDATES, NEXT_SYNC_COMMITTEE_INDEX,
|
||||
NEXT_SYNC_COMMITTEE_INDEX_ELECTRA,
|
||||
};
|
||||
}
|
||||
|
||||
pub mod sync_committee_contribution {
|
||||
pub use crate::sync_committee::{
|
||||
SyncCommitteeContributionError as Error, SyncContributionData,
|
||||
};
|
||||
}
|
||||
|
||||
pub mod slot_data {
|
||||
pub use crate::core::SlotData;
|
||||
}
|
||||
|
||||
pub mod signed_aggregate_and_proof {
|
||||
pub use crate::attestation::SignedAggregateAndProofRefMut;
|
||||
}
|
||||
|
||||
pub mod application_domain {
|
||||
pub use crate::core::ApplicationDomain;
|
||||
}
|
||||
|
||||
// Temporary re-exports to maintain backwards compatibility for Lighthouse.
|
||||
pub use crate::kzg_ext::consts::VERSIONED_HASH_VERSION_KZG;
|
||||
pub use crate::light_client::LightClientError as LightClientUpdateError;
|
||||
pub use crate::state::BeaconStateError as Error;
|
||||
|
||||
pub use bls::{
|
||||
AggregatePublicKey, AggregateSignature, Keypair, PublicKey, PublicKeyBytes, SecretKey,
|
||||
Signature, SignatureBytes,
|
||||
AggregatePublicKey, AggregateSignature, Error as BlsError, Keypair, PUBLIC_KEY_BYTES_LEN,
|
||||
PublicKey, PublicKeyBytes, SIGNATURE_BYTES_LEN, SecretKey, Signature, SignatureBytes,
|
||||
get_withdrawal_credentials,
|
||||
};
|
||||
pub use context_deserialize::{ContextDeserialize, context_deserialize};
|
||||
pub use kzg::{KzgCommitment, KzgProof, VERSIONED_HASH_VERSION_KZG};
|
||||
pub use fixed_bytes::FixedBytesExtended;
|
||||
pub use milhouse::{self, List, ProgressiveList, Vector};
|
||||
pub use ssz_types::{BitList, BitVector, FixedVector, VariableList, typenum, typenum::Unsigned};
|
||||
pub use superstruct::superstruct;
|
||||
|
||||
21
consensus/types/src/light_client/consts.rs
Normal file
21
consensus/types/src/light_client/consts.rs
Normal file
@@ -0,0 +1,21 @@
|
||||
pub const FINALIZED_ROOT_PROOF_LEN: usize = 6;
|
||||
pub const CURRENT_SYNC_COMMITTEE_PROOF_LEN: usize = 5;
|
||||
pub const NEXT_SYNC_COMMITTEE_PROOF_LEN: usize = 5;
|
||||
pub const EXECUTION_PAYLOAD_PROOF_LEN: usize = 4;
|
||||
|
||||
pub const FINALIZED_ROOT_PROOF_LEN_ELECTRA: usize = 7;
|
||||
pub const NEXT_SYNC_COMMITTEE_PROOF_LEN_ELECTRA: usize = 6;
|
||||
pub const CURRENT_SYNC_COMMITTEE_PROOF_LEN_ELECTRA: usize = 6;
|
||||
|
||||
pub const FINALIZED_ROOT_INDEX: usize = 105;
|
||||
pub const CURRENT_SYNC_COMMITTEE_INDEX: usize = 54;
|
||||
pub const NEXT_SYNC_COMMITTEE_INDEX: usize = 55;
|
||||
pub const EXECUTION_PAYLOAD_INDEX: usize = 25;
|
||||
|
||||
pub const FINALIZED_ROOT_INDEX_ELECTRA: usize = 169;
|
||||
pub const CURRENT_SYNC_COMMITTEE_INDEX_ELECTRA: usize = 86;
|
||||
pub const NEXT_SYNC_COMMITTEE_INDEX_ELECTRA: usize = 87;
|
||||
|
||||
// Max light client updates by range request limits
|
||||
// spec: https://github.com/ethereum/consensus-specs/blob/dev/specs/altair/light-client/p2p-interface.md#configuration
|
||||
pub const MAX_REQUEST_LIGHT_CLIENT_UPDATES: u64 = 128;
|
||||
41
consensus/types/src/light_client/error.rs
Normal file
41
consensus/types/src/light_client/error.rs
Normal file
@@ -0,0 +1,41 @@
|
||||
use safe_arith::ArithError;
|
||||
|
||||
use crate::state::BeaconStateError;
|
||||
|
||||
#[derive(Debug, PartialEq, Clone)]
|
||||
pub enum LightClientError {
|
||||
SszTypesError(ssz_types::Error),
|
||||
MilhouseError(milhouse::Error),
|
||||
BeaconStateError(BeaconStateError),
|
||||
ArithError(ArithError),
|
||||
AltairForkNotActive,
|
||||
NotEnoughSyncCommitteeParticipants,
|
||||
MismatchingPeriods,
|
||||
InvalidFinalizedBlock,
|
||||
BeaconBlockBodyError,
|
||||
InconsistentFork,
|
||||
}
|
||||
|
||||
impl From<ssz_types::Error> for LightClientError {
|
||||
fn from(e: ssz_types::Error) -> LightClientError {
|
||||
LightClientError::SszTypesError(e)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<BeaconStateError> for LightClientError {
|
||||
fn from(e: BeaconStateError) -> LightClientError {
|
||||
LightClientError::BeaconStateError(e)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<ArithError> for LightClientError {
|
||||
fn from(e: ArithError) -> LightClientError {
|
||||
LightClientError::ArithError(e)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<milhouse::Error> for LightClientError {
|
||||
fn from(e: milhouse::Error) -> LightClientError {
|
||||
LightClientError::MilhouseError(e)
|
||||
}
|
||||
}
|
||||
@@ -1,19 +1,30 @@
|
||||
use crate::context_deserialize;
|
||||
use crate::{
|
||||
BeaconState, ChainSpec, ContextDeserialize, EthSpec, FixedVector, ForkName, Hash256,
|
||||
LightClientHeader, LightClientHeaderAltair, LightClientHeaderCapella, LightClientHeaderDeneb,
|
||||
LightClientHeaderElectra, LightClientHeaderFulu, LightClientHeaderGloas,
|
||||
SignedBlindedBeaconBlock, Slot, SyncCommittee, light_client_update::*, test_utils::TestRandom,
|
||||
};
|
||||
use std::sync::Arc;
|
||||
|
||||
use context_deserialize::{ContextDeserialize, context_deserialize};
|
||||
use educe::Educe;
|
||||
use serde::{Deserialize, Deserializer, Serialize};
|
||||
use ssz::{Decode, Encode};
|
||||
use ssz_derive::{Decode, Encode};
|
||||
use std::sync::Arc;
|
||||
use ssz_types::FixedVector;
|
||||
use superstruct::superstruct;
|
||||
use test_random_derive::TestRandom;
|
||||
use tree_hash_derive::TreeHash;
|
||||
|
||||
use crate::{
|
||||
block::SignedBlindedBeaconBlock,
|
||||
core::{ChainSpec, EthSpec, Hash256, Slot},
|
||||
fork::ForkName,
|
||||
light_client::{
|
||||
CurrentSyncCommitteeProofLen, CurrentSyncCommitteeProofLenElectra, LightClientError,
|
||||
LightClientHeader, LightClientHeaderAltair, LightClientHeaderCapella,
|
||||
LightClientHeaderDeneb, LightClientHeaderElectra, LightClientHeaderFulu,
|
||||
LightClientHeaderGloas,
|
||||
},
|
||||
state::BeaconState,
|
||||
sync_committee::SyncCommittee,
|
||||
test_utils::TestRandom,
|
||||
};
|
||||
|
||||
/// A LightClientBootstrap is the initializer we send over to light_client nodes
|
||||
/// that are trying to generate their basic storage when booting up.
|
||||
#[superstruct(
|
||||
@@ -142,53 +153,53 @@ impl<E: EthSpec> LightClientBootstrap<E> {
|
||||
current_sync_committee: Arc<SyncCommittee<E>>,
|
||||
current_sync_committee_branch: Vec<Hash256>,
|
||||
chain_spec: &ChainSpec,
|
||||
) -> Result<Self, Error> {
|
||||
) -> Result<Self, LightClientError> {
|
||||
let light_client_bootstrap = match block
|
||||
.fork_name(chain_spec)
|
||||
.map_err(|_| Error::InconsistentFork)?
|
||||
.map_err(|_| LightClientError::InconsistentFork)?
|
||||
{
|
||||
ForkName::Base => return Err(Error::AltairForkNotActive),
|
||||
ForkName::Base => return Err(LightClientError::AltairForkNotActive),
|
||||
ForkName::Altair | ForkName::Bellatrix => Self::Altair(LightClientBootstrapAltair {
|
||||
header: LightClientHeaderAltair::block_to_light_client_header(block)?,
|
||||
current_sync_committee,
|
||||
current_sync_committee_branch: current_sync_committee_branch
|
||||
.try_into()
|
||||
.map_err(Error::SszTypesError)?,
|
||||
.map_err(LightClientError::SszTypesError)?,
|
||||
}),
|
||||
ForkName::Capella => Self::Capella(LightClientBootstrapCapella {
|
||||
header: LightClientHeaderCapella::block_to_light_client_header(block)?,
|
||||
current_sync_committee,
|
||||
current_sync_committee_branch: current_sync_committee_branch
|
||||
.try_into()
|
||||
.map_err(Error::SszTypesError)?,
|
||||
.map_err(LightClientError::SszTypesError)?,
|
||||
}),
|
||||
ForkName::Deneb => Self::Deneb(LightClientBootstrapDeneb {
|
||||
header: LightClientHeaderDeneb::block_to_light_client_header(block)?,
|
||||
current_sync_committee,
|
||||
current_sync_committee_branch: current_sync_committee_branch
|
||||
.try_into()
|
||||
.map_err(Error::SszTypesError)?,
|
||||
.map_err(LightClientError::SszTypesError)?,
|
||||
}),
|
||||
ForkName::Electra => Self::Electra(LightClientBootstrapElectra {
|
||||
header: LightClientHeaderElectra::block_to_light_client_header(block)?,
|
||||
current_sync_committee,
|
||||
current_sync_committee_branch: current_sync_committee_branch
|
||||
.try_into()
|
||||
.map_err(Error::SszTypesError)?,
|
||||
.map_err(LightClientError::SszTypesError)?,
|
||||
}),
|
||||
ForkName::Fulu => Self::Fulu(LightClientBootstrapFulu {
|
||||
header: LightClientHeaderFulu::block_to_light_client_header(block)?,
|
||||
current_sync_committee,
|
||||
current_sync_committee_branch: current_sync_committee_branch
|
||||
.try_into()
|
||||
.map_err(Error::SszTypesError)?,
|
||||
.map_err(LightClientError::SszTypesError)?,
|
||||
}),
|
||||
ForkName::Gloas => Self::Gloas(LightClientBootstrapGloas {
|
||||
header: LightClientHeaderGloas::block_to_light_client_header(block)?,
|
||||
current_sync_committee,
|
||||
current_sync_committee_branch: current_sync_committee_branch
|
||||
.try_into()
|
||||
.map_err(Error::SszTypesError)?,
|
||||
.map_err(LightClientError::SszTypesError)?,
|
||||
}),
|
||||
};
|
||||
|
||||
@@ -199,56 +210,56 @@ impl<E: EthSpec> LightClientBootstrap<E> {
|
||||
beacon_state: &mut BeaconState<E>,
|
||||
block: &SignedBlindedBeaconBlock<E>,
|
||||
chain_spec: &ChainSpec,
|
||||
) -> Result<Self, Error> {
|
||||
) -> Result<Self, LightClientError> {
|
||||
let current_sync_committee_branch = beacon_state.compute_current_sync_committee_proof()?;
|
||||
let current_sync_committee = beacon_state.current_sync_committee()?.clone();
|
||||
|
||||
let light_client_bootstrap = match block
|
||||
.fork_name(chain_spec)
|
||||
.map_err(|_| Error::InconsistentFork)?
|
||||
.map_err(|_| LightClientError::InconsistentFork)?
|
||||
{
|
||||
ForkName::Base => return Err(Error::AltairForkNotActive),
|
||||
ForkName::Base => return Err(LightClientError::AltairForkNotActive),
|
||||
ForkName::Altair | ForkName::Bellatrix => Self::Altair(LightClientBootstrapAltair {
|
||||
header: LightClientHeaderAltair::block_to_light_client_header(block)?,
|
||||
current_sync_committee,
|
||||
current_sync_committee_branch: current_sync_committee_branch
|
||||
.try_into()
|
||||
.map_err(Error::SszTypesError)?,
|
||||
.map_err(LightClientError::SszTypesError)?,
|
||||
}),
|
||||
ForkName::Capella => Self::Capella(LightClientBootstrapCapella {
|
||||
header: LightClientHeaderCapella::block_to_light_client_header(block)?,
|
||||
current_sync_committee,
|
||||
current_sync_committee_branch: current_sync_committee_branch
|
||||
.try_into()
|
||||
.map_err(Error::SszTypesError)?,
|
||||
.map_err(LightClientError::SszTypesError)?,
|
||||
}),
|
||||
ForkName::Deneb => Self::Deneb(LightClientBootstrapDeneb {
|
||||
header: LightClientHeaderDeneb::block_to_light_client_header(block)?,
|
||||
current_sync_committee,
|
||||
current_sync_committee_branch: current_sync_committee_branch
|
||||
.try_into()
|
||||
.map_err(Error::SszTypesError)?,
|
||||
.map_err(LightClientError::SszTypesError)?,
|
||||
}),
|
||||
ForkName::Electra => Self::Electra(LightClientBootstrapElectra {
|
||||
header: LightClientHeaderElectra::block_to_light_client_header(block)?,
|
||||
current_sync_committee,
|
||||
current_sync_committee_branch: current_sync_committee_branch
|
||||
.try_into()
|
||||
.map_err(Error::SszTypesError)?,
|
||||
.map_err(LightClientError::SszTypesError)?,
|
||||
}),
|
||||
ForkName::Fulu => Self::Fulu(LightClientBootstrapFulu {
|
||||
header: LightClientHeaderFulu::block_to_light_client_header(block)?,
|
||||
current_sync_committee,
|
||||
current_sync_committee_branch: current_sync_committee_branch
|
||||
.try_into()
|
||||
.map_err(Error::SszTypesError)?,
|
||||
.map_err(LightClientError::SszTypesError)?,
|
||||
}),
|
||||
ForkName::Gloas => Self::Gloas(LightClientBootstrapGloas {
|
||||
header: LightClientHeaderGloas::block_to_light_client_header(block)?,
|
||||
current_sync_committee,
|
||||
current_sync_committee_branch: current_sync_committee_branch
|
||||
.try_into()
|
||||
.map_err(Error::SszTypesError)?,
|
||||
.map_err(LightClientError::SszTypesError)?,
|
||||
}),
|
||||
};
|
||||
|
||||
@@ -1,21 +1,27 @@
|
||||
use super::{EthSpec, FixedVector, Hash256, LightClientHeader, Slot, SyncAggregate};
|
||||
use crate::ChainSpec;
|
||||
use crate::context_deserialize;
|
||||
use crate::{
|
||||
ContextDeserialize, ForkName, LightClientHeaderAltair, LightClientHeaderCapella,
|
||||
LightClientHeaderDeneb, LightClientHeaderElectra, LightClientHeaderFulu,
|
||||
LightClientHeaderGloas, SignedBlindedBeaconBlock, light_client_update::*,
|
||||
test_utils::TestRandom,
|
||||
};
|
||||
use context_deserialize::{ContextDeserialize, context_deserialize};
|
||||
use educe::Educe;
|
||||
use serde::{Deserialize, Deserializer, Serialize};
|
||||
use ssz::{Decode, Encode};
|
||||
use ssz_derive::Decode;
|
||||
use ssz_derive::Encode;
|
||||
use ssz_types::FixedVector;
|
||||
use superstruct::superstruct;
|
||||
use test_random_derive::TestRandom;
|
||||
use tree_hash_derive::TreeHash;
|
||||
|
||||
use crate::{
|
||||
block::SignedBlindedBeaconBlock,
|
||||
core::{ChainSpec, EthSpec, Hash256, Slot},
|
||||
fork::ForkName,
|
||||
light_client::{
|
||||
FinalizedRootProofLen, FinalizedRootProofLenElectra, LightClientError, LightClientHeader,
|
||||
LightClientHeaderAltair, LightClientHeaderCapella, LightClientHeaderDeneb,
|
||||
LightClientHeaderElectra, LightClientHeaderFulu, LightClientHeaderGloas,
|
||||
},
|
||||
sync_committee::SyncAggregate,
|
||||
test_utils::TestRandom,
|
||||
};
|
||||
|
||||
#[superstruct(
|
||||
variants(Altair, Capella, Deneb, Electra, Fulu, Gloas),
|
||||
variant_attributes(
|
||||
@@ -103,10 +109,10 @@ impl<E: EthSpec> LightClientFinalityUpdate<E> {
|
||||
sync_aggregate: SyncAggregate<E>,
|
||||
signature_slot: Slot,
|
||||
chain_spec: &ChainSpec,
|
||||
) -> Result<Self, Error> {
|
||||
) -> Result<Self, LightClientError> {
|
||||
let finality_update = match attested_block
|
||||
.fork_name(chain_spec)
|
||||
.map_err(|_| Error::InconsistentFork)?
|
||||
.map_err(|_| LightClientError::InconsistentFork)?
|
||||
{
|
||||
ForkName::Altair | ForkName::Bellatrix => {
|
||||
Self::Altair(LightClientFinalityUpdateAltair {
|
||||
@@ -116,7 +122,9 @@ impl<E: EthSpec> LightClientFinalityUpdate<E> {
|
||||
finalized_header: LightClientHeaderAltair::block_to_light_client_header(
|
||||
finalized_block,
|
||||
)?,
|
||||
finality_branch: finality_branch.try_into().map_err(Error::SszTypesError)?,
|
||||
finality_branch: finality_branch
|
||||
.try_into()
|
||||
.map_err(LightClientError::SszTypesError)?,
|
||||
sync_aggregate,
|
||||
signature_slot,
|
||||
})
|
||||
@@ -128,7 +136,9 @@ impl<E: EthSpec> LightClientFinalityUpdate<E> {
|
||||
finalized_header: LightClientHeaderCapella::block_to_light_client_header(
|
||||
finalized_block,
|
||||
)?,
|
||||
finality_branch: finality_branch.try_into().map_err(Error::SszTypesError)?,
|
||||
finality_branch: finality_branch
|
||||
.try_into()
|
||||
.map_err(LightClientError::SszTypesError)?,
|
||||
sync_aggregate,
|
||||
signature_slot,
|
||||
}),
|
||||
@@ -139,7 +149,9 @@ impl<E: EthSpec> LightClientFinalityUpdate<E> {
|
||||
finalized_header: LightClientHeaderDeneb::block_to_light_client_header(
|
||||
finalized_block,
|
||||
)?,
|
||||
finality_branch: finality_branch.try_into().map_err(Error::SszTypesError)?,
|
||||
finality_branch: finality_branch
|
||||
.try_into()
|
||||
.map_err(LightClientError::SszTypesError)?,
|
||||
sync_aggregate,
|
||||
signature_slot,
|
||||
}),
|
||||
@@ -150,7 +162,9 @@ impl<E: EthSpec> LightClientFinalityUpdate<E> {
|
||||
finalized_header: LightClientHeaderElectra::block_to_light_client_header(
|
||||
finalized_block,
|
||||
)?,
|
||||
finality_branch: finality_branch.try_into().map_err(Error::SszTypesError)?,
|
||||
finality_branch: finality_branch
|
||||
.try_into()
|
||||
.map_err(LightClientError::SszTypesError)?,
|
||||
sync_aggregate,
|
||||
signature_slot,
|
||||
}),
|
||||
@@ -161,7 +175,9 @@ impl<E: EthSpec> LightClientFinalityUpdate<E> {
|
||||
finalized_header: LightClientHeaderFulu::block_to_light_client_header(
|
||||
finalized_block,
|
||||
)?,
|
||||
finality_branch: finality_branch.try_into().map_err(Error::SszTypesError)?,
|
||||
finality_branch: finality_branch
|
||||
.try_into()
|
||||
.map_err(LightClientError::SszTypesError)?,
|
||||
sync_aggregate,
|
||||
signature_slot,
|
||||
}),
|
||||
@@ -172,12 +188,14 @@ impl<E: EthSpec> LightClientFinalityUpdate<E> {
|
||||
finalized_header: LightClientHeaderGloas::block_to_light_client_header(
|
||||
finalized_block,
|
||||
)?,
|
||||
finality_branch: finality_branch.try_into().map_err(Error::SszTypesError)?,
|
||||
finality_branch: finality_branch
|
||||
.try_into()
|
||||
.map_err(LightClientError::SszTypesError)?,
|
||||
sync_aggregate,
|
||||
signature_slot,
|
||||
}),
|
||||
|
||||
ForkName::Base => return Err(Error::AltairForkNotActive),
|
||||
ForkName::Base => return Err(LightClientError::AltairForkNotActive),
|
||||
};
|
||||
|
||||
Ok(finality_update)
|
||||
@@ -1,22 +1,27 @@
|
||||
use crate::ChainSpec;
|
||||
use crate::context_deserialize;
|
||||
use crate::{BeaconBlockBody, light_client_update::*};
|
||||
use crate::{BeaconBlockHeader, ExecutionPayloadHeader};
|
||||
use crate::{ContextDeserialize, ForkName};
|
||||
use crate::{
|
||||
EthSpec, ExecutionPayloadHeaderCapella, ExecutionPayloadHeaderDeneb,
|
||||
ExecutionPayloadHeaderElectra, ExecutionPayloadHeaderFulu, ExecutionPayloadHeaderGloas,
|
||||
FixedVector, Hash256, SignedBlindedBeaconBlock, test_utils::TestRandom,
|
||||
};
|
||||
use std::marker::PhantomData;
|
||||
|
||||
use context_deserialize::{ContextDeserialize, context_deserialize};
|
||||
use educe::Educe;
|
||||
use serde::{Deserialize, Deserializer, Serialize};
|
||||
use ssz::Decode;
|
||||
use ssz_derive::{Decode, Encode};
|
||||
use std::marker::PhantomData;
|
||||
use ssz_types::FixedVector;
|
||||
use superstruct::superstruct;
|
||||
use test_random_derive::TestRandom;
|
||||
use tree_hash_derive::TreeHash;
|
||||
|
||||
use crate::{
|
||||
block::{BeaconBlockBody, BeaconBlockHeader, SignedBlindedBeaconBlock},
|
||||
core::{ChainSpec, EthSpec, Hash256},
|
||||
execution::{
|
||||
ExecutionPayloadHeader, ExecutionPayloadHeaderCapella, ExecutionPayloadHeaderDeneb,
|
||||
ExecutionPayloadHeaderElectra, ExecutionPayloadHeaderFulu, ExecutionPayloadHeaderGloas,
|
||||
},
|
||||
fork::ForkName,
|
||||
light_client::{ExecutionPayloadProofLen, LightClientError, consts::EXECUTION_PAYLOAD_INDEX},
|
||||
test_utils::TestRandom,
|
||||
};
|
||||
|
||||
#[superstruct(
|
||||
variants(Altair, Capella, Deneb, Electra, Fulu, Gloas),
|
||||
variant_attributes(
|
||||
@@ -85,12 +90,12 @@ impl<E: EthSpec> LightClientHeader<E> {
|
||||
pub fn block_to_light_client_header(
|
||||
block: &SignedBlindedBeaconBlock<E>,
|
||||
chain_spec: &ChainSpec,
|
||||
) -> Result<Self, Error> {
|
||||
) -> Result<Self, LightClientError> {
|
||||
let header = match block
|
||||
.fork_name(chain_spec)
|
||||
.map_err(|_| Error::InconsistentFork)?
|
||||
.map_err(|_| LightClientError::InconsistentFork)?
|
||||
{
|
||||
ForkName::Base => return Err(Error::AltairForkNotActive),
|
||||
ForkName::Base => return Err(LightClientError::AltairForkNotActive),
|
||||
ForkName::Altair | ForkName::Bellatrix => LightClientHeader::Altair(
|
||||
LightClientHeaderAltair::block_to_light_client_header(block)?,
|
||||
),
|
||||
@@ -163,7 +168,7 @@ impl<E: EthSpec> LightClientHeader<E> {
|
||||
impl<E: EthSpec> LightClientHeaderAltair<E> {
|
||||
pub fn block_to_light_client_header(
|
||||
block: &SignedBlindedBeaconBlock<E>,
|
||||
) -> Result<Self, Error> {
|
||||
) -> Result<Self, LightClientError> {
|
||||
Ok(LightClientHeaderAltair {
|
||||
beacon: block.message().block_header(),
|
||||
_phantom_data: PhantomData,
|
||||
@@ -183,7 +188,7 @@ impl<E: EthSpec> Default for LightClientHeaderAltair<E> {
|
||||
impl<E: EthSpec> LightClientHeaderCapella<E> {
|
||||
pub fn block_to_light_client_header(
|
||||
block: &SignedBlindedBeaconBlock<E>,
|
||||
) -> Result<Self, Error> {
|
||||
) -> Result<Self, LightClientError> {
|
||||
let payload = block
|
||||
.message()
|
||||
.execution_payload()?
|
||||
@@ -194,7 +199,7 @@ impl<E: EthSpec> LightClientHeaderCapella<E> {
|
||||
block
|
||||
.message()
|
||||
.body_capella()
|
||||
.map_err(|_| Error::BeaconBlockBodyError)?
|
||||
.map_err(|_| LightClientError::BeaconBlockBodyError)?
|
||||
.to_owned(),
|
||||
);
|
||||
|
||||
@@ -225,7 +230,7 @@ impl<E: EthSpec> Default for LightClientHeaderCapella<E> {
|
||||
impl<E: EthSpec> LightClientHeaderDeneb<E> {
|
||||
pub fn block_to_light_client_header(
|
||||
block: &SignedBlindedBeaconBlock<E>,
|
||||
) -> Result<Self, Error> {
|
||||
) -> Result<Self, LightClientError> {
|
||||
let header = block
|
||||
.message()
|
||||
.execution_payload()?
|
||||
@@ -236,7 +241,7 @@ impl<E: EthSpec> LightClientHeaderDeneb<E> {
|
||||
block
|
||||
.message()
|
||||
.body_deneb()
|
||||
.map_err(|_| Error::BeaconBlockBodyError)?
|
||||
.map_err(|_| LightClientError::BeaconBlockBodyError)?
|
||||
.to_owned(),
|
||||
);
|
||||
|
||||
@@ -267,7 +272,7 @@ impl<E: EthSpec> Default for LightClientHeaderDeneb<E> {
|
||||
impl<E: EthSpec> LightClientHeaderElectra<E> {
|
||||
pub fn block_to_light_client_header(
|
||||
block: &SignedBlindedBeaconBlock<E>,
|
||||
) -> Result<Self, Error> {
|
||||
) -> Result<Self, LightClientError> {
|
||||
let payload = block
|
||||
.message()
|
||||
.execution_payload()?
|
||||
@@ -278,7 +283,7 @@ impl<E: EthSpec> LightClientHeaderElectra<E> {
|
||||
block
|
||||
.message()
|
||||
.body_electra()
|
||||
.map_err(|_| Error::BeaconBlockBodyError)?
|
||||
.map_err(|_| LightClientError::BeaconBlockBodyError)?
|
||||
.to_owned(),
|
||||
);
|
||||
|
||||
@@ -309,7 +314,7 @@ impl<E: EthSpec> Default for LightClientHeaderElectra<E> {
|
||||
impl<E: EthSpec> LightClientHeaderFulu<E> {
|
||||
pub fn block_to_light_client_header(
|
||||
block: &SignedBlindedBeaconBlock<E>,
|
||||
) -> Result<Self, Error> {
|
||||
) -> Result<Self, LightClientError> {
|
||||
let payload = block
|
||||
.message()
|
||||
.execution_payload()?
|
||||
@@ -320,7 +325,7 @@ impl<E: EthSpec> LightClientHeaderFulu<E> {
|
||||
block
|
||||
.message()
|
||||
.body_fulu()
|
||||
.map_err(|_| Error::BeaconBlockBodyError)?
|
||||
.map_err(|_| LightClientError::BeaconBlockBodyError)?
|
||||
.to_owned(),
|
||||
);
|
||||
|
||||
@@ -351,7 +356,7 @@ impl<E: EthSpec> Default for LightClientHeaderFulu<E> {
|
||||
impl<E: EthSpec> LightClientHeaderGloas<E> {
|
||||
pub fn block_to_light_client_header(
|
||||
block: &SignedBlindedBeaconBlock<E>,
|
||||
) -> Result<Self, Error> {
|
||||
) -> Result<Self, LightClientError> {
|
||||
let payload = block
|
||||
.message()
|
||||
.execution_payload()?
|
||||
@@ -362,7 +367,7 @@ impl<E: EthSpec> LightClientHeaderGloas<E> {
|
||||
block
|
||||
.message()
|
||||
.body_gloas()
|
||||
.map_err(|_| Error::BeaconBlockBodyError)?
|
||||
.map_err(|_| LightClientError::BeaconBlockBodyError)?
|
||||
.to_owned(),
|
||||
);
|
||||
|
||||
@@ -1,21 +1,26 @@
|
||||
use super::{ContextDeserialize, EthSpec, ForkName, LightClientHeader, Slot, SyncAggregate};
|
||||
use crate::context_deserialize;
|
||||
use crate::test_utils::TestRandom;
|
||||
use crate::{
|
||||
ChainSpec, LightClientHeaderAltair, LightClientHeaderCapella, LightClientHeaderDeneb,
|
||||
LightClientHeaderElectra, LightClientHeaderFulu, LightClientHeaderGloas,
|
||||
SignedBlindedBeaconBlock, light_client_update::*,
|
||||
};
|
||||
use context_deserialize::{ContextDeserialize, context_deserialize};
|
||||
use educe::Educe;
|
||||
use serde::{Deserialize, Deserializer, Serialize};
|
||||
use ssz::{Decode, Encode};
|
||||
use ssz_derive::Decode;
|
||||
use ssz_derive::Encode;
|
||||
use ssz_derive::{Decode, Encode};
|
||||
use superstruct::superstruct;
|
||||
use test_random_derive::TestRandom;
|
||||
use tree_hash::Hash256;
|
||||
use tree_hash_derive::TreeHash;
|
||||
|
||||
use crate::{
|
||||
block::SignedBlindedBeaconBlock,
|
||||
core::{ChainSpec, EthSpec, Slot},
|
||||
fork::ForkName,
|
||||
light_client::{
|
||||
LightClientError, LightClientHeader, LightClientHeaderAltair, LightClientHeaderCapella,
|
||||
LightClientHeaderDeneb, LightClientHeaderElectra, LightClientHeaderFulu,
|
||||
LightClientHeaderGloas,
|
||||
},
|
||||
sync_committee::SyncAggregate,
|
||||
test_utils::TestRandom,
|
||||
};
|
||||
|
||||
/// A LightClientOptimisticUpdate is the update we send on each slot,
|
||||
/// it is based off the current unfinalized epoch is verified only against BLS signature.
|
||||
#[superstruct(
|
||||
@@ -79,10 +84,10 @@ impl<E: EthSpec> LightClientOptimisticUpdate<E> {
|
||||
sync_aggregate: SyncAggregate<E>,
|
||||
signature_slot: Slot,
|
||||
chain_spec: &ChainSpec,
|
||||
) -> Result<Self, Error> {
|
||||
) -> Result<Self, LightClientError> {
|
||||
let optimistic_update = match attested_block
|
||||
.fork_name(chain_spec)
|
||||
.map_err(|_| Error::InconsistentFork)?
|
||||
.map_err(|_| LightClientError::InconsistentFork)?
|
||||
{
|
||||
ForkName::Altair | ForkName::Bellatrix => {
|
||||
Self::Altair(LightClientOptimisticUpdateAltair {
|
||||
@@ -128,7 +133,7 @@ impl<E: EthSpec> LightClientOptimisticUpdate<E> {
|
||||
sync_aggregate,
|
||||
signature_slot,
|
||||
}),
|
||||
ForkName::Base => return Err(Error::AltairForkNotActive),
|
||||
ForkName::Base => return Err(LightClientError::AltairForkNotActive),
|
||||
};
|
||||
|
||||
Ok(optimistic_update)
|
||||
@@ -1,12 +1,6 @@
|
||||
use super::{EthSpec, FixedVector, Hash256, Slot, SyncAggregate, SyncCommittee};
|
||||
use crate::LightClientHeader;
|
||||
use crate::context_deserialize;
|
||||
use crate::light_client_header::LightClientHeaderElectra;
|
||||
use crate::{
|
||||
ChainSpec, ContextDeserialize, Epoch, ForkName, LightClientHeaderAltair,
|
||||
LightClientHeaderCapella, LightClientHeaderDeneb, LightClientHeaderFulu,
|
||||
LightClientHeaderGloas, SignedBlindedBeaconBlock, beacon_state, test_utils::TestRandom,
|
||||
};
|
||||
use std::sync::Arc;
|
||||
|
||||
use context_deserialize::{ContextDeserialize, context_deserialize};
|
||||
use educe::Educe;
|
||||
use safe_arith::ArithError;
|
||||
use safe_arith::SafeArith;
|
||||
@@ -14,20 +8,24 @@ use serde::{Deserialize, Deserializer, Serialize};
|
||||
use ssz::{Decode, Encode};
|
||||
use ssz_derive::Decode;
|
||||
use ssz_derive::Encode;
|
||||
use ssz_types::FixedVector;
|
||||
use ssz_types::typenum::{U4, U5, U6, U7};
|
||||
use std::sync::Arc;
|
||||
use superstruct::superstruct;
|
||||
use test_random_derive::TestRandom;
|
||||
use tree_hash_derive::TreeHash;
|
||||
|
||||
pub const FINALIZED_ROOT_INDEX: usize = 105;
|
||||
pub const CURRENT_SYNC_COMMITTEE_INDEX: usize = 54;
|
||||
pub const NEXT_SYNC_COMMITTEE_INDEX: usize = 55;
|
||||
pub const EXECUTION_PAYLOAD_INDEX: usize = 25;
|
||||
|
||||
pub const FINALIZED_ROOT_INDEX_ELECTRA: usize = 169;
|
||||
pub const CURRENT_SYNC_COMMITTEE_INDEX_ELECTRA: usize = 86;
|
||||
pub const NEXT_SYNC_COMMITTEE_INDEX_ELECTRA: usize = 87;
|
||||
use crate::{
|
||||
block::SignedBlindedBeaconBlock,
|
||||
core::{ChainSpec, Epoch, EthSpec, Hash256, Slot},
|
||||
fork::ForkName,
|
||||
light_client::{
|
||||
LightClientError, LightClientHeader, LightClientHeaderAltair, LightClientHeaderCapella,
|
||||
LightClientHeaderDeneb, LightClientHeaderElectra, LightClientHeaderFulu,
|
||||
LightClientHeaderGloas,
|
||||
},
|
||||
sync_committee::{SyncAggregate, SyncCommittee},
|
||||
test_utils::TestRandom,
|
||||
};
|
||||
|
||||
pub type FinalizedRootProofLen = U6;
|
||||
pub type CurrentSyncCommitteeProofLen = U5;
|
||||
@@ -38,64 +36,12 @@ pub type FinalizedRootProofLenElectra = U7;
|
||||
pub type CurrentSyncCommitteeProofLenElectra = U6;
|
||||
pub type NextSyncCommitteeProofLenElectra = U6;
|
||||
|
||||
pub const FINALIZED_ROOT_PROOF_LEN: usize = 6;
|
||||
pub const CURRENT_SYNC_COMMITTEE_PROOF_LEN: usize = 5;
|
||||
pub const NEXT_SYNC_COMMITTEE_PROOF_LEN: usize = 5;
|
||||
pub const EXECUTION_PAYLOAD_PROOF_LEN: usize = 4;
|
||||
|
||||
pub const FINALIZED_ROOT_PROOF_LEN_ELECTRA: usize = 7;
|
||||
pub const NEXT_SYNC_COMMITTEE_PROOF_LEN_ELECTRA: usize = 6;
|
||||
pub const CURRENT_SYNC_COMMITTEE_PROOF_LEN_ELECTRA: usize = 6;
|
||||
|
||||
pub type MerkleProof = Vec<Hash256>;
|
||||
// Max light client updates by range request limits
|
||||
// spec: https://github.com/ethereum/consensus-specs/blob/dev/specs/altair/light-client/p2p-interface.md#configuration
|
||||
pub const MAX_REQUEST_LIGHT_CLIENT_UPDATES: u64 = 128;
|
||||
|
||||
type FinalityBranch = FixedVector<Hash256, FinalizedRootProofLen>;
|
||||
type FinalityBranchElectra = FixedVector<Hash256, FinalizedRootProofLenElectra>;
|
||||
type NextSyncCommitteeBranch = FixedVector<Hash256, NextSyncCommitteeProofLen>;
|
||||
|
||||
type NextSyncCommitteeBranchElectra = FixedVector<Hash256, NextSyncCommitteeProofLenElectra>;
|
||||
|
||||
#[derive(Debug, PartialEq, Clone)]
|
||||
pub enum Error {
|
||||
SszTypesError(ssz_types::Error),
|
||||
MilhouseError(milhouse::Error),
|
||||
BeaconStateError(beacon_state::Error),
|
||||
ArithError(ArithError),
|
||||
AltairForkNotActive,
|
||||
NotEnoughSyncCommitteeParticipants,
|
||||
MismatchingPeriods,
|
||||
InvalidFinalizedBlock,
|
||||
BeaconBlockBodyError,
|
||||
InconsistentFork,
|
||||
}
|
||||
|
||||
impl From<ssz_types::Error> for Error {
|
||||
fn from(e: ssz_types::Error) -> Error {
|
||||
Error::SszTypesError(e)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<beacon_state::Error> for Error {
|
||||
fn from(e: beacon_state::Error) -> Error {
|
||||
Error::BeaconStateError(e)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<ArithError> for Error {
|
||||
fn from(e: ArithError) -> Error {
|
||||
Error::ArithError(e)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<milhouse::Error> for Error {
|
||||
fn from(e: milhouse::Error) -> Error {
|
||||
Error::MilhouseError(e)
|
||||
}
|
||||
}
|
||||
|
||||
/// A LightClientUpdate is the update we request solely to either complete the bootstrapping process,
|
||||
/// or to sync up to the last committee period, we need to have one ready for each ALTAIR period
|
||||
/// we go over, note: there is no need to keep all of the updates from [ALTAIR_PERIOD, CURRENT_PERIOD].
|
||||
@@ -238,12 +184,12 @@ impl<E: EthSpec> LightClientUpdate<E> {
|
||||
attested_block: &SignedBlindedBeaconBlock<E>,
|
||||
finalized_block: Option<&SignedBlindedBeaconBlock<E>>,
|
||||
chain_spec: &ChainSpec,
|
||||
) -> Result<Self, Error> {
|
||||
) -> Result<Self, LightClientError> {
|
||||
let light_client_update = match attested_block
|
||||
.fork_name(chain_spec)
|
||||
.map_err(|_| Error::InconsistentFork)?
|
||||
.map_err(|_| LightClientError::InconsistentFork)?
|
||||
{
|
||||
ForkName::Base => return Err(Error::AltairForkNotActive),
|
||||
ForkName::Base => return Err(LightClientError::AltairForkNotActive),
|
||||
fork_name @ ForkName::Altair | fork_name @ ForkName::Bellatrix => {
|
||||
let attested_header =
|
||||
LightClientHeaderAltair::block_to_light_client_header(attested_block)?;
|
||||
@@ -263,9 +209,11 @@ impl<E: EthSpec> LightClientUpdate<E> {
|
||||
next_sync_committee,
|
||||
next_sync_committee_branch: next_sync_committee_branch
|
||||
.try_into()
|
||||
.map_err(Error::SszTypesError)?,
|
||||
.map_err(LightClientError::SszTypesError)?,
|
||||
finalized_header,
|
||||
finality_branch: finality_branch.try_into().map_err(Error::SszTypesError)?,
|
||||
finality_branch: finality_branch
|
||||
.try_into()
|
||||
.map_err(LightClientError::SszTypesError)?,
|
||||
sync_aggregate: sync_aggregate.clone(),
|
||||
signature_slot: block_slot,
|
||||
})
|
||||
@@ -289,9 +237,11 @@ impl<E: EthSpec> LightClientUpdate<E> {
|
||||
next_sync_committee,
|
||||
next_sync_committee_branch: next_sync_committee_branch
|
||||
.try_into()
|
||||
.map_err(Error::SszTypesError)?,
|
||||
.map_err(LightClientError::SszTypesError)?,
|
||||
finalized_header,
|
||||
finality_branch: finality_branch.try_into().map_err(Error::SszTypesError)?,
|
||||
finality_branch: finality_branch
|
||||
.try_into()
|
||||
.map_err(LightClientError::SszTypesError)?,
|
||||
sync_aggregate: sync_aggregate.clone(),
|
||||
signature_slot: block_slot,
|
||||
})
|
||||
@@ -315,9 +265,11 @@ impl<E: EthSpec> LightClientUpdate<E> {
|
||||
next_sync_committee,
|
||||
next_sync_committee_branch: next_sync_committee_branch
|
||||
.try_into()
|
||||
.map_err(Error::SszTypesError)?,
|
||||
.map_err(LightClientError::SszTypesError)?,
|
||||
finalized_header,
|
||||
finality_branch: finality_branch.try_into().map_err(Error::SszTypesError)?,
|
||||
finality_branch: finality_branch
|
||||
.try_into()
|
||||
.map_err(LightClientError::SszTypesError)?,
|
||||
sync_aggregate: sync_aggregate.clone(),
|
||||
signature_slot: block_slot,
|
||||
})
|
||||
@@ -341,9 +293,11 @@ impl<E: EthSpec> LightClientUpdate<E> {
|
||||
next_sync_committee,
|
||||
next_sync_committee_branch: next_sync_committee_branch
|
||||
.try_into()
|
||||
.map_err(Error::SszTypesError)?,
|
||||
.map_err(LightClientError::SszTypesError)?,
|
||||
finalized_header,
|
||||
finality_branch: finality_branch.try_into().map_err(Error::SszTypesError)?,
|
||||
finality_branch: finality_branch
|
||||
.try_into()
|
||||
.map_err(LightClientError::SszTypesError)?,
|
||||
sync_aggregate: sync_aggregate.clone(),
|
||||
signature_slot: block_slot,
|
||||
})
|
||||
@@ -367,9 +321,11 @@ impl<E: EthSpec> LightClientUpdate<E> {
|
||||
next_sync_committee,
|
||||
next_sync_committee_branch: next_sync_committee_branch
|
||||
.try_into()
|
||||
.map_err(Error::SszTypesError)?,
|
||||
.map_err(LightClientError::SszTypesError)?,
|
||||
finalized_header,
|
||||
finality_branch: finality_branch.try_into().map_err(Error::SszTypesError)?,
|
||||
finality_branch: finality_branch
|
||||
.try_into()
|
||||
.map_err(LightClientError::SszTypesError)?,
|
||||
sync_aggregate: sync_aggregate.clone(),
|
||||
signature_slot: block_slot,
|
||||
})
|
||||
@@ -393,9 +349,11 @@ impl<E: EthSpec> LightClientUpdate<E> {
|
||||
next_sync_committee,
|
||||
next_sync_committee_branch: next_sync_committee_branch
|
||||
.try_into()
|
||||
.map_err(Error::SszTypesError)?,
|
||||
.map_err(LightClientError::SszTypesError)?,
|
||||
finalized_header,
|
||||
finality_branch: finality_branch.try_into().map_err(Error::SszTypesError)?,
|
||||
finality_branch: finality_branch
|
||||
.try_into()
|
||||
.map_err(LightClientError::SszTypesError)?,
|
||||
sync_aggregate: sync_aggregate.clone(),
|
||||
signature_slot: block_slot,
|
||||
})
|
||||
@@ -452,23 +410,32 @@ impl<E: EthSpec> LightClientUpdate<E> {
|
||||
fn attested_header_sync_committee_period(
|
||||
&self,
|
||||
chain_spec: &ChainSpec,
|
||||
) -> Result<Epoch, Error> {
|
||||
) -> Result<Epoch, LightClientError> {
|
||||
compute_sync_committee_period_at_slot::<E>(self.attested_header_slot(), chain_spec)
|
||||
.map_err(Error::ArithError)
|
||||
.map_err(LightClientError::ArithError)
|
||||
}
|
||||
|
||||
fn signature_slot_sync_committee_period(&self, chain_spec: &ChainSpec) -> Result<Epoch, Error> {
|
||||
fn signature_slot_sync_committee_period(
|
||||
&self,
|
||||
chain_spec: &ChainSpec,
|
||||
) -> Result<Epoch, LightClientError> {
|
||||
compute_sync_committee_period_at_slot::<E>(*self.signature_slot(), chain_spec)
|
||||
.map_err(Error::ArithError)
|
||||
.map_err(LightClientError::ArithError)
|
||||
}
|
||||
|
||||
pub fn is_sync_committee_update(&self, chain_spec: &ChainSpec) -> Result<bool, Error> {
|
||||
pub fn is_sync_committee_update(
|
||||
&self,
|
||||
chain_spec: &ChainSpec,
|
||||
) -> Result<bool, LightClientError> {
|
||||
Ok(!self.is_next_sync_committee_branch_empty()
|
||||
&& (self.attested_header_sync_committee_period(chain_spec)?
|
||||
== self.signature_slot_sync_committee_period(chain_spec)?))
|
||||
}
|
||||
|
||||
pub fn has_sync_committee_finality(&self, chain_spec: &ChainSpec) -> Result<bool, Error> {
|
||||
pub fn has_sync_committee_finality(
|
||||
&self,
|
||||
chain_spec: &ChainSpec,
|
||||
) -> Result<bool, LightClientError> {
|
||||
Ok(
|
||||
compute_sync_committee_period_at_slot::<E>(self.finalized_header_slot(), chain_spec)?
|
||||
== self.attested_header_sync_committee_period(chain_spec)?,
|
||||
@@ -482,7 +449,7 @@ impl<E: EthSpec> LightClientUpdate<E> {
|
||||
&self,
|
||||
new: &Self,
|
||||
chain_spec: &ChainSpec,
|
||||
) -> Result<bool, Error> {
|
||||
) -> Result<bool, LightClientError> {
|
||||
// Compare super majority (> 2/3) sync committee participation
|
||||
let max_active_participants = new.sync_aggregate().sync_committee_bits.len();
|
||||
|
||||
@@ -606,6 +573,7 @@ fn compute_sync_committee_period_at_slot<E: EthSpec>(
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use crate::light_client::consts::*;
|
||||
use ssz_types::typenum::Unsigned;
|
||||
|
||||
// `ssz_tests!` can only be defined once per namespace
|
||||
37
consensus/types/src/light_client/mod.rs
Normal file
37
consensus/types/src/light_client/mod.rs
Normal file
@@ -0,0 +1,37 @@
|
||||
mod error;
|
||||
mod light_client_bootstrap;
|
||||
mod light_client_finality_update;
|
||||
mod light_client_header;
|
||||
mod light_client_optimistic_update;
|
||||
mod light_client_update;
|
||||
|
||||
pub mod consts;
|
||||
|
||||
pub use error::LightClientError;
|
||||
pub use light_client_bootstrap::{
|
||||
LightClientBootstrap, LightClientBootstrapAltair, LightClientBootstrapCapella,
|
||||
LightClientBootstrapDeneb, LightClientBootstrapElectra, LightClientBootstrapFulu,
|
||||
LightClientBootstrapGloas,
|
||||
};
|
||||
pub use light_client_finality_update::{
|
||||
LightClientFinalityUpdate, LightClientFinalityUpdateAltair, LightClientFinalityUpdateCapella,
|
||||
LightClientFinalityUpdateDeneb, LightClientFinalityUpdateElectra,
|
||||
LightClientFinalityUpdateFulu, LightClientFinalityUpdateGloas,
|
||||
};
|
||||
pub use light_client_header::{
|
||||
LightClientHeader, LightClientHeaderAltair, LightClientHeaderCapella, LightClientHeaderDeneb,
|
||||
LightClientHeaderElectra, LightClientHeaderFulu, LightClientHeaderGloas,
|
||||
};
|
||||
pub use light_client_optimistic_update::{
|
||||
LightClientOptimisticUpdate, LightClientOptimisticUpdateAltair,
|
||||
LightClientOptimisticUpdateCapella, LightClientOptimisticUpdateDeneb,
|
||||
LightClientOptimisticUpdateElectra, LightClientOptimisticUpdateFulu,
|
||||
LightClientOptimisticUpdateGloas,
|
||||
};
|
||||
pub use light_client_update::{
|
||||
CurrentSyncCommitteeProofLen, CurrentSyncCommitteeProofLenElectra, ExecutionPayloadProofLen,
|
||||
FinalizedRootProofLen, FinalizedRootProofLenElectra, LightClientUpdate,
|
||||
LightClientUpdateAltair, LightClientUpdateCapella, LightClientUpdateDeneb,
|
||||
LightClientUpdateElectra, LightClientUpdateFulu, LightClientUpdateGloas,
|
||||
NextSyncCommitteeProofLen, NextSyncCommitteeProofLenElectra,
|
||||
};
|
||||
@@ -1,90 +0,0 @@
|
||||
//! Emulates a fixed size array but with the length set at runtime.
|
||||
//!
|
||||
//! The length of the list cannot be changed once it is set.
|
||||
|
||||
use std::fmt;
|
||||
use std::fmt::Debug;
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct RuntimeFixedVector<T> {
|
||||
vec: Vec<T>,
|
||||
len: usize,
|
||||
}
|
||||
|
||||
impl<T: Debug> Debug for RuntimeFixedVector<T> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
write!(f, "{:?} (len={})", self.vec, self.len)
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Clone + Default> RuntimeFixedVector<T> {
|
||||
pub fn new(vec: Vec<T>) -> Self {
|
||||
let len = vec.len();
|
||||
Self { vec, len }
|
||||
}
|
||||
|
||||
pub fn to_vec(&self) -> Vec<T> {
|
||||
self.vec.clone()
|
||||
}
|
||||
|
||||
pub fn as_slice(&self) -> &[T] {
|
||||
self.vec.as_slice()
|
||||
}
|
||||
|
||||
#[allow(clippy::len_without_is_empty)]
|
||||
pub fn len(&self) -> usize {
|
||||
self.len
|
||||
}
|
||||
|
||||
pub fn into_vec(self) -> Vec<T> {
|
||||
self.vec
|
||||
}
|
||||
|
||||
pub fn default(max_len: usize) -> Self {
|
||||
Self {
|
||||
vec: vec![T::default(); max_len],
|
||||
len: max_len,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn take(&mut self) -> Self {
|
||||
let new = std::mem::take(&mut self.vec);
|
||||
*self = Self::new(vec![T::default(); self.len]);
|
||||
Self {
|
||||
vec: new,
|
||||
len: self.len,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> std::ops::Deref for RuntimeFixedVector<T> {
|
||||
type Target = [T];
|
||||
|
||||
fn deref(&self) -> &[T] {
|
||||
&self.vec[..]
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> std::ops::DerefMut for RuntimeFixedVector<T> {
|
||||
fn deref_mut(&mut self) -> &mut [T] {
|
||||
&mut self.vec[..]
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> IntoIterator for RuntimeFixedVector<T> {
|
||||
type Item = T;
|
||||
type IntoIter = std::vec::IntoIter<T>;
|
||||
|
||||
fn into_iter(self) -> Self::IntoIter {
|
||||
self.vec.into_iter()
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, T> IntoIterator for &'a RuntimeFixedVector<T> {
|
||||
type Item = &'a T;
|
||||
type IntoIter = std::slice::Iter<'a, T>;
|
||||
|
||||
fn into_iter(self) -> Self::IntoIter {
|
||||
self.vec.iter()
|
||||
}
|
||||
}
|
||||
@@ -1,387 +0,0 @@
|
||||
use crate::ContextDeserialize;
|
||||
use educe::Educe;
|
||||
use serde::de::Error as DeError;
|
||||
use serde::{Deserialize, Deserializer, Serialize};
|
||||
use ssz::Decode;
|
||||
use ssz_types::Error;
|
||||
use std::fmt;
|
||||
use std::fmt::Debug;
|
||||
use std::ops::{Deref, Index, IndexMut};
|
||||
use std::slice::SliceIndex;
|
||||
use tree_hash::{Hash256, MerkleHasher, PackedEncoding, TreeHash, TreeHashType};
|
||||
|
||||
/// Emulates a SSZ `List`.
|
||||
///
|
||||
/// An ordered, heap-allocated, variable-length, homogeneous collection of `T`, with no more than
|
||||
/// `max_len` values.
|
||||
///
|
||||
/// To ensure there are no inconsistent states, we do not allow any mutating operation if `max_len` is not set.
|
||||
///
|
||||
/// ## Example
|
||||
///
|
||||
/// ```
|
||||
/// use types::{RuntimeVariableList};
|
||||
///
|
||||
/// let base: Vec<u64> = vec![1, 2, 3, 4];
|
||||
///
|
||||
/// // Create a `RuntimeVariableList` from a `Vec` that has the expected length.
|
||||
/// let exact: RuntimeVariableList<_> = RuntimeVariableList::new(base.clone(), 4).unwrap();
|
||||
/// assert_eq!(&exact[..], &[1, 2, 3, 4]);
|
||||
///
|
||||
/// // Create a `RuntimeVariableList` from a `Vec` that is too long you'll get an error.
|
||||
/// let err = RuntimeVariableList::new(base.clone(), 3).unwrap_err();
|
||||
/// assert_eq!(err, ssz_types::Error::OutOfBounds { i: 4, len: 3 });
|
||||
///
|
||||
/// // Create a `RuntimeVariableList` from a `Vec` that is shorter than the maximum.
|
||||
/// let mut long: RuntimeVariableList<_> = RuntimeVariableList::new(base, 5).unwrap();
|
||||
/// assert_eq!(&long[..], &[1, 2, 3, 4]);
|
||||
///
|
||||
/// // Push a value to if it does not exceed the maximum
|
||||
/// long.push(5).unwrap();
|
||||
/// assert_eq!(&long[..], &[1, 2, 3, 4, 5]);
|
||||
///
|
||||
/// // Push a value to if it _does_ exceed the maximum.
|
||||
/// assert!(long.push(6).is_err());
|
||||
///
|
||||
/// ```
|
||||
#[derive(Clone, Serialize, Deserialize, Educe)]
|
||||
#[educe(PartialEq, Eq, Hash(bound(T: std::hash::Hash)))]
|
||||
#[serde(transparent)]
|
||||
pub struct RuntimeVariableList<T> {
|
||||
vec: Vec<T>,
|
||||
#[serde(skip)]
|
||||
max_len: usize,
|
||||
}
|
||||
|
||||
impl<T: Debug> Debug for RuntimeVariableList<T> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
write!(f, "{:?} (max_len={})", self.vec, self.max_len)
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> RuntimeVariableList<T> {
|
||||
/// Returns `Ok` if the given `vec` equals the fixed length of `Self`. Otherwise returns
|
||||
/// `Err(OutOfBounds { .. })`.
|
||||
pub fn new(vec: Vec<T>, max_len: usize) -> Result<Self, Error> {
|
||||
if vec.len() <= max_len {
|
||||
Ok(Self { vec, max_len })
|
||||
} else {
|
||||
Err(Error::OutOfBounds {
|
||||
i: vec.len(),
|
||||
len: max_len,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
/// Create an empty list with the given `max_len`.
|
||||
pub fn empty(max_len: usize) -> Self {
|
||||
Self {
|
||||
vec: vec![],
|
||||
max_len,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn as_slice(&self) -> &[T] {
|
||||
self.vec.as_slice()
|
||||
}
|
||||
|
||||
pub fn as_mut_slice(&mut self) -> &mut [T] {
|
||||
self.vec.as_mut_slice()
|
||||
}
|
||||
|
||||
/// Returns the number of values presently in `self`.
|
||||
pub fn len(&self) -> usize {
|
||||
self.vec.len()
|
||||
}
|
||||
|
||||
/// True if `self` does not contain any values.
|
||||
pub fn is_empty(&self) -> bool {
|
||||
self.len() == 0
|
||||
}
|
||||
|
||||
/// Returns the type-level maximum length.
|
||||
///
|
||||
/// Returns `None` if self is uninitialized with a max_len.
|
||||
pub fn max_len(&self) -> usize {
|
||||
self.max_len
|
||||
}
|
||||
|
||||
/// Appends `value` to the back of `self`.
|
||||
///
|
||||
/// Returns `Err(())` when appending `value` would exceed the maximum length.
|
||||
pub fn push(&mut self, value: T) -> Result<(), Error> {
|
||||
if self.vec.len() < self.max_len {
|
||||
self.vec.push(value);
|
||||
Ok(())
|
||||
} else {
|
||||
Err(Error::OutOfBounds {
|
||||
i: self.vec.len().saturating_add(1),
|
||||
len: self.max_len,
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Decode> RuntimeVariableList<T> {
|
||||
pub fn from_ssz_bytes(bytes: &[u8], max_len: usize) -> Result<Self, ssz::DecodeError> {
|
||||
let vec = if bytes.is_empty() {
|
||||
vec![]
|
||||
} else if <T as Decode>::is_ssz_fixed_len() {
|
||||
let num_items = bytes
|
||||
.len()
|
||||
.checked_div(<T as Decode>::ssz_fixed_len())
|
||||
.ok_or(ssz::DecodeError::ZeroLengthItem)?;
|
||||
|
||||
if num_items > max_len {
|
||||
return Err(ssz::DecodeError::BytesInvalid(format!(
|
||||
"RuntimeVariableList of {} items exceeds maximum of {}",
|
||||
num_items, max_len
|
||||
)));
|
||||
}
|
||||
|
||||
bytes.chunks(<T as Decode>::ssz_fixed_len()).try_fold(
|
||||
Vec::with_capacity(num_items),
|
||||
|mut vec, chunk| {
|
||||
vec.push(<T as Decode>::from_ssz_bytes(chunk)?);
|
||||
Ok(vec)
|
||||
},
|
||||
)?
|
||||
} else {
|
||||
ssz::decode_list_of_variable_length_items(bytes, Some(max_len))?
|
||||
};
|
||||
Ok(Self { vec, max_len })
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> From<RuntimeVariableList<T>> for Vec<T> {
|
||||
fn from(list: RuntimeVariableList<T>) -> Vec<T> {
|
||||
list.vec
|
||||
}
|
||||
}
|
||||
|
||||
impl<T, I: SliceIndex<[T]>> Index<I> for RuntimeVariableList<T> {
|
||||
type Output = I::Output;
|
||||
|
||||
#[inline]
|
||||
fn index(&self, index: I) -> &Self::Output {
|
||||
Index::index(&self.vec, index)
|
||||
}
|
||||
}
|
||||
|
||||
impl<T, I: SliceIndex<[T]>> IndexMut<I> for RuntimeVariableList<T> {
|
||||
#[inline]
|
||||
fn index_mut(&mut self, index: I) -> &mut Self::Output {
|
||||
IndexMut::index_mut(&mut self.vec, index)
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> Deref for RuntimeVariableList<T> {
|
||||
type Target = [T];
|
||||
|
||||
fn deref(&self) -> &[T] {
|
||||
&self.vec[..]
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, T> IntoIterator for &'a RuntimeVariableList<T> {
|
||||
type Item = &'a T;
|
||||
type IntoIter = std::slice::Iter<'a, T>;
|
||||
|
||||
fn into_iter(self) -> Self::IntoIter {
|
||||
self.iter()
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> IntoIterator for RuntimeVariableList<T> {
|
||||
type Item = T;
|
||||
type IntoIter = std::vec::IntoIter<T>;
|
||||
|
||||
fn into_iter(self) -> Self::IntoIter {
|
||||
self.vec.into_iter()
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> ssz::Encode for RuntimeVariableList<T>
|
||||
where
|
||||
T: ssz::Encode,
|
||||
{
|
||||
fn is_ssz_fixed_len() -> bool {
|
||||
<Vec<T>>::is_ssz_fixed_len()
|
||||
}
|
||||
|
||||
fn ssz_append(&self, buf: &mut Vec<u8>) {
|
||||
self.vec.ssz_append(buf)
|
||||
}
|
||||
|
||||
fn ssz_fixed_len() -> usize {
|
||||
<Vec<T>>::ssz_fixed_len()
|
||||
}
|
||||
|
||||
fn ssz_bytes_len(&self) -> usize {
|
||||
self.vec.ssz_bytes_len()
|
||||
}
|
||||
}
|
||||
|
||||
impl<'de, C, T> ContextDeserialize<'de, (C, usize)> for RuntimeVariableList<T>
|
||||
where
|
||||
T: ContextDeserialize<'de, C>,
|
||||
C: Clone,
|
||||
{
|
||||
fn context_deserialize<D>(deserializer: D, context: (C, usize)) -> Result<Self, D::Error>
|
||||
where
|
||||
D: Deserializer<'de>,
|
||||
{
|
||||
// first parse out a Vec<C> using the Vec<C> impl you already have
|
||||
let vec: Vec<T> = Vec::context_deserialize(deserializer, context.0)?;
|
||||
let vec_len = vec.len();
|
||||
RuntimeVariableList::new(vec, context.1).map_err(|e| {
|
||||
DeError::custom(format!(
|
||||
"RuntimeVariableList length {} exceeds max_len {}: {e:?}",
|
||||
vec_len, context.1,
|
||||
))
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
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::*;
|
||||
use ssz::*;
|
||||
use std::fmt::Debug;
|
||||
|
||||
#[test]
|
||||
fn new() {
|
||||
let vec = vec![42; 5];
|
||||
let fixed: Result<RuntimeVariableList<u64>, _> = RuntimeVariableList::new(vec, 4);
|
||||
assert!(fixed.is_err());
|
||||
|
||||
let vec = vec![42; 3];
|
||||
let fixed: Result<RuntimeVariableList<u64>, _> = RuntimeVariableList::new(vec, 4);
|
||||
assert!(fixed.is_ok());
|
||||
|
||||
let vec = vec![42; 4];
|
||||
let fixed: Result<RuntimeVariableList<u64>, _> = RuntimeVariableList::new(vec, 4);
|
||||
assert!(fixed.is_ok());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn indexing() {
|
||||
let vec = vec![1, 2];
|
||||
|
||||
let mut fixed: RuntimeVariableList<u64> =
|
||||
RuntimeVariableList::new(vec.clone(), 8192).unwrap();
|
||||
|
||||
assert_eq!(fixed[0], 1);
|
||||
assert_eq!(&fixed[0..1], &vec[0..1]);
|
||||
assert_eq!(fixed[..].len(), 2);
|
||||
|
||||
fixed[1] = 3;
|
||||
assert_eq!(fixed[1], 3);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn length() {
|
||||
// Too long.
|
||||
let vec = vec![42; 5];
|
||||
let err = RuntimeVariableList::<u64>::new(vec.clone(), 4).unwrap_err();
|
||||
assert_eq!(err, Error::OutOfBounds { i: 5, len: 4 });
|
||||
|
||||
let vec = vec![42; 3];
|
||||
let fixed: RuntimeVariableList<u64> = RuntimeVariableList::new(vec.clone(), 4).unwrap();
|
||||
assert_eq!(&fixed[0..3], &vec[..]);
|
||||
assert_eq!(&fixed[..], &vec![42, 42, 42][..]);
|
||||
|
||||
let vec = vec![];
|
||||
let fixed: RuntimeVariableList<u64> = RuntimeVariableList::new(vec, 4).unwrap();
|
||||
assert_eq!(&fixed[..], &[] as &[u64]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn deref() {
|
||||
let vec = vec![0, 2, 4, 6];
|
||||
let fixed: RuntimeVariableList<u64> = RuntimeVariableList::new(vec, 4).unwrap();
|
||||
|
||||
assert_eq!(fixed.first(), Some(&0));
|
||||
assert_eq!(fixed.get(3), Some(&6));
|
||||
assert_eq!(fixed.get(4), None);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn encode() {
|
||||
let vec: RuntimeVariableList<u16> = RuntimeVariableList::new(vec![0; 2], 2).unwrap();
|
||||
assert_eq!(vec.as_ssz_bytes(), vec![0, 0, 0, 0]);
|
||||
assert_eq!(<RuntimeVariableList<u16> as Encode>::ssz_fixed_len(), 4);
|
||||
}
|
||||
|
||||
fn round_trip<T: Encode + Decode + PartialEq + Debug>(item: RuntimeVariableList<T>) {
|
||||
let max_len = item.max_len();
|
||||
let encoded = &item.as_ssz_bytes();
|
||||
assert_eq!(item.ssz_bytes_len(), encoded.len());
|
||||
assert_eq!(
|
||||
RuntimeVariableList::from_ssz_bytes(encoded, max_len),
|
||||
Ok(item)
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn u16_len_8() {
|
||||
round_trip::<u16>(RuntimeVariableList::new(vec![42; 8], 8).unwrap());
|
||||
round_trip::<u16>(RuntimeVariableList::new(vec![0; 8], 8).unwrap());
|
||||
}
|
||||
}
|
||||
@@ -1,9 +1,4 @@
|
||||
use crate::context_deserialize;
|
||||
use crate::indexed_attestation::{
|
||||
IndexedAttestationBase, IndexedAttestationElectra, IndexedAttestationRef,
|
||||
};
|
||||
use crate::{ContextDeserialize, ForkName};
|
||||
use crate::{EthSpec, test_utils::TestRandom};
|
||||
use context_deserialize::{ContextDeserialize, context_deserialize};
|
||||
use educe::Educe;
|
||||
use rand::{Rng, RngCore};
|
||||
use serde::{Deserialize, Deserializer, Serialize};
|
||||
@@ -12,6 +7,13 @@ use superstruct::superstruct;
|
||||
use test_random_derive::TestRandom;
|
||||
use tree_hash_derive::TreeHash;
|
||||
|
||||
use crate::{
|
||||
attestation::{IndexedAttestationBase, IndexedAttestationElectra, IndexedAttestationRef},
|
||||
core::EthSpec,
|
||||
fork::ForkName,
|
||||
test_utils::TestRandom,
|
||||
};
|
||||
|
||||
#[superstruct(
|
||||
variants(Base, Electra),
|
||||
variant_attributes(
|
||||
8
consensus/types/src/slashing/mod.rs
Normal file
8
consensus/types/src/slashing/mod.rs
Normal file
@@ -0,0 +1,8 @@
|
||||
mod attester_slashing;
|
||||
mod proposer_slashing;
|
||||
|
||||
pub use attester_slashing::{
|
||||
AttesterSlashing, AttesterSlashingBase, AttesterSlashingElectra, AttesterSlashingOnDisk,
|
||||
AttesterSlashingRef, AttesterSlashingRefOnDisk,
|
||||
};
|
||||
pub use proposer_slashing::ProposerSlashing;
|
||||
@@ -1,12 +1,11 @@
|
||||
use crate::context_deserialize;
|
||||
use crate::test_utils::TestRandom;
|
||||
use crate::{ForkName, SignedBeaconBlockHeader};
|
||||
|
||||
use context_deserialize::context_deserialize;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use ssz_derive::{Decode, Encode};
|
||||
use test_random_derive::TestRandom;
|
||||
use tree_hash_derive::TreeHash;
|
||||
|
||||
use crate::{block::SignedBeaconBlockHeader, fork::ForkName, test_utils::TestRandom};
|
||||
|
||||
/// Two conflicting proposals from the same proposer (validator).
|
||||
///
|
||||
/// Spec v0.12.1
|
||||
@@ -1,6 +1,10 @@
|
||||
use crate::{ChainSpec, Epoch, Validator};
|
||||
use std::collections::BTreeSet;
|
||||
|
||||
use crate::{
|
||||
core::{ChainSpec, Epoch},
|
||||
validator::Validator,
|
||||
};
|
||||
|
||||
/// Activation queue computed during epoch processing for use in the *next* epoch.
|
||||
#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
|
||||
#[derive(Debug, PartialEq, Eq, Default, Clone)]
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,17 +1,20 @@
|
||||
#![allow(clippy::arithmetic_side_effects)]
|
||||
|
||||
use crate::*;
|
||||
use core::num::NonZeroUsize;
|
||||
use std::{num::NonZeroUsize, ops::Range, sync::Arc};
|
||||
|
||||
use educe::Educe;
|
||||
use safe_arith::SafeArith;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use ssz::{Decode, DecodeError, Encode, four_byte_option_impl};
|
||||
use ssz_derive::{Decode, Encode};
|
||||
use std::ops::Range;
|
||||
use std::sync::Arc;
|
||||
use swap_or_not_shuffle::shuffle_list;
|
||||
|
||||
mod tests;
|
||||
use crate::{
|
||||
attestation::{AttestationDuty, BeaconCommittee, CommitteeIndex},
|
||||
core::{ChainSpec, Domain, Epoch, EthSpec, Slot},
|
||||
state::{BeaconState, BeaconStateError},
|
||||
validator::Validator,
|
||||
};
|
||||
|
||||
// Define "legacy" implementations of `Option<Epoch>`, `Option<NonZeroUsize>` which use four bytes
|
||||
// for encoding the union selector.
|
||||
@@ -66,7 +69,7 @@ impl CommitteeCache {
|
||||
state: &BeaconState<E>,
|
||||
epoch: Epoch,
|
||||
spec: &ChainSpec,
|
||||
) -> Result<Arc<CommitteeCache>, Error> {
|
||||
) -> Result<Arc<CommitteeCache>, BeaconStateError> {
|
||||
// Check that the cache is being built for an in-range epoch.
|
||||
//
|
||||
// We allow caches to be constructed for historic epochs, per:
|
||||
@@ -77,23 +80,23 @@ impl CommitteeCache {
|
||||
.saturating_sub(1u64);
|
||||
|
||||
if reqd_randao_epoch < state.min_randao_epoch() || epoch > state.current_epoch() + 1 {
|
||||
return Err(Error::EpochOutOfBounds);
|
||||
return Err(BeaconStateError::EpochOutOfBounds);
|
||||
}
|
||||
|
||||
// May cause divide-by-zero errors.
|
||||
if E::slots_per_epoch() == 0 {
|
||||
return Err(Error::ZeroSlotsPerEpoch);
|
||||
return Err(BeaconStateError::ZeroSlotsPerEpoch);
|
||||
}
|
||||
|
||||
// The use of `NonZeroUsize` reduces the maximum number of possible validators by one.
|
||||
if state.validators().len() == usize::MAX {
|
||||
return Err(Error::TooManyValidators);
|
||||
return Err(BeaconStateError::TooManyValidators);
|
||||
}
|
||||
|
||||
let active_validator_indices = get_active_validator_indices(state.validators(), epoch);
|
||||
|
||||
if active_validator_indices.is_empty() {
|
||||
return Err(Error::InsufficientValidators);
|
||||
return Err(BeaconStateError::InsufficientValidators);
|
||||
}
|
||||
|
||||
let committees_per_slot =
|
||||
@@ -107,13 +110,14 @@ impl CommitteeCache {
|
||||
&seed[..],
|
||||
false,
|
||||
)
|
||||
.ok_or(Error::UnableToShuffle)?;
|
||||
.ok_or(BeaconStateError::UnableToShuffle)?;
|
||||
|
||||
let mut shuffling_positions = vec![<_>::default(); state.validators().len()];
|
||||
for (i, &v) in shuffling.iter().enumerate() {
|
||||
*shuffling_positions
|
||||
.get_mut(v)
|
||||
.ok_or(Error::ShuffleIndexOutOfBounds(v))? = NonZeroUsize::new(i + 1).into();
|
||||
.ok_or(BeaconStateError::ShuffleIndexOutOfBounds(v))? =
|
||||
NonZeroUsize::new(i + 1).into();
|
||||
}
|
||||
|
||||
Ok(Arc::new(CommitteeCache {
|
||||
@@ -188,24 +192,24 @@ impl CommitteeCache {
|
||||
pub fn get_beacon_committees_at_slot(
|
||||
&self,
|
||||
slot: Slot,
|
||||
) -> Result<Vec<BeaconCommittee<'_>>, Error> {
|
||||
) -> Result<Vec<BeaconCommittee<'_>>, BeaconStateError> {
|
||||
if self.initialized_epoch.is_none() {
|
||||
return Err(Error::CommitteeCacheUninitialized(None));
|
||||
return Err(BeaconStateError::CommitteeCacheUninitialized(None));
|
||||
}
|
||||
|
||||
(0..self.committees_per_slot())
|
||||
.map(|index| {
|
||||
self.get_beacon_committee(slot, index)
|
||||
.ok_or(Error::NoCommittee { slot, index })
|
||||
.ok_or(BeaconStateError::NoCommittee { slot, index })
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
|
||||
/// Returns all committees for `self.initialized_epoch`.
|
||||
pub fn get_all_beacon_committees(&self) -> Result<Vec<BeaconCommittee<'_>>, Error> {
|
||||
pub fn get_all_beacon_committees(&self) -> Result<Vec<BeaconCommittee<'_>>, BeaconStateError> {
|
||||
let initialized_epoch = self
|
||||
.initialized_epoch
|
||||
.ok_or(Error::CommitteeCacheUninitialized(None))?;
|
||||
.ok_or(BeaconStateError::CommitteeCacheUninitialized(None))?;
|
||||
|
||||
initialized_epoch.slot_iter(self.slots_per_epoch).try_fold(
|
||||
Vec::with_capacity(self.epoch_committee_count()),
|
||||
@@ -1,7 +1,12 @@
|
||||
use crate::{ActivationQueue, BeaconStateError, ChainSpec, Epoch, Hash256, Slot};
|
||||
use safe_arith::{ArithError, SafeArith};
|
||||
use std::sync::Arc;
|
||||
|
||||
use safe_arith::{ArithError, SafeArith};
|
||||
|
||||
use crate::{
|
||||
core::{ChainSpec, Epoch, Hash256, Slot},
|
||||
state::{ActivationQueue, BeaconStateError},
|
||||
};
|
||||
|
||||
/// Cache of values which are uniquely determined at the start of an epoch.
|
||||
///
|
||||
/// The values are fixed with respect to the last block of the _prior_ epoch, which we refer
|
||||
@@ -1,7 +1,13 @@
|
||||
use super::{BeaconStateError, ChainSpec, Epoch, Validator};
|
||||
use safe_arith::SafeArith;
|
||||
use std::cmp::Ordering;
|
||||
|
||||
use safe_arith::SafeArith;
|
||||
|
||||
use crate::{
|
||||
core::{ChainSpec, Epoch},
|
||||
state::BeaconStateError,
|
||||
validator::Validator,
|
||||
};
|
||||
|
||||
/// Map from exit epoch to the number of validators with that exit epoch.
|
||||
#[derive(Debug, Default, Clone, PartialEq)]
|
||||
pub struct ExitCache {
|
||||
@@ -1,11 +1,16 @@
|
||||
use crate::test_utils::TestRandom;
|
||||
use crate::*;
|
||||
|
||||
use context_deserialize::context_deserialize;
|
||||
use milhouse::Vector;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use ssz_derive::{Decode, Encode};
|
||||
use test_random_derive::TestRandom;
|
||||
use tree_hash_derive::TreeHash;
|
||||
|
||||
use crate::{
|
||||
core::{EthSpec, Hash256},
|
||||
fork::ForkName,
|
||||
test_utils::TestRandom,
|
||||
};
|
||||
|
||||
/// Historical block and state roots.
|
||||
///
|
||||
/// Spec v0.12.1
|
||||
@@ -26,6 +31,7 @@ pub struct HistoricalBatch<E: EthSpec> {
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use crate::core::MainnetEthSpec;
|
||||
|
||||
pub type FoundationHistoricalBatch = HistoricalBatch<MainnetEthSpec>;
|
||||
|
||||
@@ -1,13 +1,18 @@
|
||||
use crate::context_deserialize;
|
||||
use crate::test_utils::TestRandom;
|
||||
use crate::{BeaconState, EthSpec, ForkName, Hash256};
|
||||
use compare_fields::CompareFields;
|
||||
use context_deserialize::context_deserialize;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use ssz_derive::{Decode, Encode};
|
||||
use test_random_derive::TestRandom;
|
||||
use tree_hash::TreeHash;
|
||||
use tree_hash_derive::TreeHash;
|
||||
|
||||
use crate::{
|
||||
core::{EthSpec, Hash256},
|
||||
fork::ForkName,
|
||||
state::BeaconState,
|
||||
test_utils::TestRandom,
|
||||
};
|
||||
|
||||
/// `HistoricalSummary` matches the components of the phase0 `HistoricalBatch`
|
||||
/// making the two hash_tree_root-compatible. This struct is introduced into the beacon state
|
||||
/// in the Capella hard fork.
|
||||
@@ -1,4 +1,7 @@
|
||||
use crate::*;
|
||||
use crate::{
|
||||
core::{EthSpec, Hash256, Slot},
|
||||
state::{BeaconState, BeaconStateError},
|
||||
};
|
||||
|
||||
/// Returns an iterator across the past block roots of `state` in descending slot-order.
|
||||
///
|
||||
@@ -28,7 +31,7 @@ impl<'a, E: EthSpec> BlockRootsIter<'a, E> {
|
||||
}
|
||||
|
||||
impl<E: EthSpec> Iterator for BlockRootsIter<'_, E> {
|
||||
type Item = Result<(Slot, Hash256), Error>;
|
||||
type Item = Result<(Slot, Hash256), BeaconStateError>;
|
||||
|
||||
fn next(&mut self) -> Option<Self::Item> {
|
||||
if self.prev > self.genesis_slot
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user