Merge remote-tracking branch 'origin/unstable' into tree-states

This commit is contained in:
Michael Sproul
2023-12-01 12:02:21 +11:00
72 changed files with 2467 additions and 1336 deletions

View File

@@ -100,6 +100,7 @@ pub mod slot_data;
pub mod sqlite;
pub mod blob_sidecar;
pub mod light_client_header;
pub mod sidecar;
pub mod signed_blob;
@@ -157,8 +158,11 @@ pub use crate::fork_versioned_response::{ForkVersionDeserialize, ForkVersionedRe
pub use crate::graffiti::{Graffiti, GRAFFITI_BYTES_LEN};
pub use crate::historical_batch::HistoricalBatch;
pub use crate::indexed_attestation::IndexedAttestation;
pub use crate::light_client_bootstrap::LightClientBootstrap;
pub use crate::light_client_finality_update::LightClientFinalityUpdate;
pub use crate::light_client_header::LightClientHeader;
pub use crate::light_client_optimistic_update::LightClientOptimisticUpdate;
pub use crate::light_client_update::{Error as LightClientError, LightClientUpdate};
pub use crate::participation_flags::ParticipationFlags;
pub use crate::participation_list::ParticipationList;
pub use crate::payload::{

View File

@@ -1,11 +1,14 @@
use super::{BeaconBlockHeader, BeaconState, EthSpec, Hash256, SyncCommittee};
use crate::{light_client_update::*, test_utils::TestRandom};
use serde::{Deserialize, Serialize};
use super::{BeaconState, EthSpec, Hash256, SyncCommittee};
use crate::{
light_client_update::*, test_utils::TestRandom, ForkName, ForkVersionDeserialize,
LightClientHeader,
};
use serde::{Deserialize, Deserializer, Serialize};
use serde_json::Value;
use ssz_derive::{Decode, Encode};
use ssz_types::FixedVector;
use std::sync::Arc;
use test_random_derive::TestRandom;
use tree_hash::TreeHash;
/// A LightClientBootstrap is the initializer we send over to lightclient nodes
/// that are trying to generate their basic storage when booting up.
@@ -23,8 +26,8 @@ use tree_hash::TreeHash;
#[serde(bound = "T: EthSpec")]
#[arbitrary(bound = "T: EthSpec")]
pub struct LightClientBootstrap<T: EthSpec> {
/// Requested beacon block header.
pub header: BeaconBlockHeader,
/// The requested beacon block header.
pub header: LightClientHeader,
/// The `SyncCommittee` used in the requested period.
pub current_sync_committee: Arc<SyncCommittee<T>>,
/// Merkle proof for sync committee
@@ -34,17 +37,37 @@ pub struct LightClientBootstrap<T: EthSpec> {
impl<T: EthSpec> LightClientBootstrap<T> {
pub fn from_beacon_state(beacon_state: &mut BeaconState<T>) -> Result<Self, Error> {
let mut header = beacon_state.latest_block_header().clone();
header.state_root = beacon_state.tree_hash_root();
header.state_root = beacon_state.update_tree_hash_cache()?;
let current_sync_committee_branch =
beacon_state.compute_merkle_proof(CURRENT_SYNC_COMMITTEE_INDEX)?;
Ok(LightClientBootstrap {
header,
header: header.into(),
current_sync_committee: beacon_state.current_sync_committee()?.clone(),
current_sync_committee_branch: FixedVector::new(current_sync_committee_branch)?,
})
}
}
impl<T: EthSpec> ForkVersionDeserialize for LightClientBootstrap<T> {
fn deserialize_by_fork<'de, D: Deserializer<'de>>(
value: Value,
fork_name: ForkName,
) -> Result<Self, D::Error> {
match fork_name {
ForkName::Altair | ForkName::Merge => {
Ok(serde_json::from_value::<LightClientBootstrap<T>>(value)
.map_err(serde::de::Error::custom))?
}
ForkName::Base | ForkName::Capella | ForkName::Deneb => {
Err(serde::de::Error::custom(format!(
"LightClientBootstrap failed to deserialize: unsupported fork '{}'",
fork_name
)))
}
}
}
}
#[cfg(test)]
mod tests {
use super::*;

View File

@@ -1,9 +1,12 @@
use super::{
BeaconBlockHeader, EthSpec, FixedVector, Hash256, SignedBeaconBlock, SignedBlindedBeaconBlock,
Slot, SyncAggregate,
EthSpec, FixedVector, Hash256, SignedBeaconBlock, SignedBlindedBeaconBlock, Slot, SyncAggregate,
};
use crate::{light_client_update::*, test_utils::TestRandom, BeaconState, ChainSpec};
use serde::{Deserialize, Serialize};
use crate::{
light_client_update::*, test_utils::TestRandom, BeaconState, ChainSpec, ForkName,
ForkVersionDeserialize, LightClientHeader,
};
use serde::{Deserialize, Deserializer, Serialize};
use serde_json::Value;
use ssz_derive::{Decode, Encode};
use test_random_derive::TestRandom;
use tree_hash::TreeHash;
@@ -25,9 +28,9 @@ use tree_hash::TreeHash;
#[arbitrary(bound = "T: EthSpec")]
pub struct LightClientFinalityUpdate<T: EthSpec> {
/// The last `BeaconBlockHeader` from the last attested block by the sync committee.
pub attested_header: BeaconBlockHeader,
pub attested_header: LightClientHeader,
/// The last `BeaconBlockHeader` from the last attested finalized block (end of epoch).
pub finalized_header: BeaconBlockHeader,
pub finalized_header: LightClientHeader,
/// Merkle proof attesting finalized header.
#[test_random(default)]
pub finality_branch: FixedVector<Hash256, FinalizedRootProofLen>,
@@ -69,8 +72,8 @@ impl<T: EthSpec> LightClientFinalityUpdate<T> {
let finality_branch = attested_state.compute_merkle_proof(FINALIZED_ROOT_INDEX)?;
Ok(Self {
attested_header,
finalized_header,
attested_header: attested_header.into(),
finalized_header: finalized_header.into(),
finality_branch: FixedVector::new(finality_branch)?,
sync_aggregate: sync_aggregate.clone(),
signature_slot: block.slot(),
@@ -78,6 +81,26 @@ impl<T: EthSpec> LightClientFinalityUpdate<T> {
}
}
impl<T: EthSpec> ForkVersionDeserialize for LightClientFinalityUpdate<T> {
fn deserialize_by_fork<'de, D: Deserializer<'de>>(
value: Value,
fork_name: ForkName,
) -> Result<Self, D::Error> {
match fork_name {
ForkName::Altair | ForkName::Merge => Ok(serde_json::from_value::<
LightClientFinalityUpdate<T>,
>(value)
.map_err(serde::de::Error::custom))?,
ForkName::Base | ForkName::Capella | ForkName::Deneb => {
Err(serde::de::Error::custom(format!(
"LightClientFinalityUpdate failed to deserialize: unsupported fork '{}'",
fork_name
)))
}
}
}
}
#[cfg(test)]
mod tests {
use super::*;

View File

@@ -0,0 +1,26 @@
use crate::test_utils::TestRandom;
use crate::BeaconBlockHeader;
use serde::{Deserialize, Serialize};
use ssz_derive::{Decode, Encode};
use test_random_derive::TestRandom;
#[derive(
Debug,
Clone,
PartialEq,
Serialize,
Deserialize,
Encode,
Decode,
TestRandom,
arbitrary::Arbitrary,
)]
pub struct LightClientHeader {
pub beacon: BeaconBlockHeader,
}
impl From<BeaconBlockHeader> for LightClientHeader {
fn from(beacon: BeaconBlockHeader) -> Self {
LightClientHeader { beacon }
}
}

View File

@@ -1,8 +1,10 @@
use super::{BeaconBlockHeader, EthSpec, Slot, SyncAggregate};
use super::{EthSpec, ForkName, ForkVersionDeserialize, Slot, SyncAggregate};
use crate::light_client_header::LightClientHeader;
use crate::{
light_client_update::Error, test_utils::TestRandom, BeaconState, ChainSpec, SignedBeaconBlock,
};
use serde::{Deserialize, Serialize};
use serde::{Deserialize, Deserializer, Serialize};
use serde_json::Value;
use ssz_derive::{Decode, Encode};
use test_random_derive::TestRandom;
use tree_hash::TreeHash;
@@ -24,7 +26,7 @@ use tree_hash::TreeHash;
#[arbitrary(bound = "T: EthSpec")]
pub struct LightClientOptimisticUpdate<T: EthSpec> {
/// The last `BeaconBlockHeader` from the last attested block by the sync committee.
pub attested_header: BeaconBlockHeader,
pub attested_header: LightClientHeader,
/// current sync aggreggate
pub sync_aggregate: SyncAggregate<T>,
/// Slot of the sync aggregated singature
@@ -53,13 +55,33 @@ impl<T: EthSpec> LightClientOptimisticUpdate<T> {
let mut attested_header = attested_state.latest_block_header().clone();
attested_header.state_root = attested_state.tree_hash_root();
Ok(Self {
attested_header,
attested_header: attested_header.into(),
sync_aggregate: sync_aggregate.clone(),
signature_slot: block.slot(),
})
}
}
impl<T: EthSpec> ForkVersionDeserialize for LightClientOptimisticUpdate<T> {
fn deserialize_by_fork<'de, D: Deserializer<'de>>(
value: Value,
fork_name: ForkName,
) -> Result<Self, D::Error> {
match fork_name {
ForkName::Altair | ForkName::Merge => Ok(serde_json::from_value::<
LightClientOptimisticUpdate<T>,
>(value)
.map_err(serde::de::Error::custom))?,
ForkName::Base | ForkName::Capella | ForkName::Deneb => {
Err(serde::de::Error::custom(format!(
"LightClientOptimisticUpdate failed to deserialize: unsupported fork '{}'",
fork_name
)))
}
}
}
}
#[cfg(test)]
mod tests {
use super::*;

View File

@@ -1,7 +1,11 @@
use super::{BeaconBlockHeader, EthSpec, Hash256, Slot, SyncAggregate, SyncCommittee};
use crate::{beacon_state, test_utils::TestRandom, BeaconBlock, BeaconState, ChainSpec};
use crate::{
beacon_state, test_utils::TestRandom, BeaconBlock, BeaconState, ChainSpec, ForkName,
ForkVersionDeserialize, LightClientHeader,
};
use safe_arith::ArithError;
use serde::{Deserialize, Serialize};
use serde::{Deserialize, Deserializer, Serialize};
use serde_json::Value;
use ssz_derive::{Decode, Encode};
use ssz_types::{
typenum::{U5, U6},
@@ -77,13 +81,13 @@ impl From<milhouse::Error> for Error {
#[arbitrary(bound = "T: EthSpec")]
pub struct LightClientUpdate<T: EthSpec> {
/// The last `BeaconBlockHeader` from the last attested block by the sync committee.
pub attested_header: BeaconBlockHeader,
pub attested_header: LightClientHeader,
/// The `SyncCommittee` used in the next period.
pub next_sync_committee: Arc<SyncCommittee<T>>,
/// Merkle proof for next sync committee
pub next_sync_committee_branch: FixedVector<Hash256, NextSyncCommitteeProofLen>,
/// The last `BeaconBlockHeader` from the last attested finalized block (end of epoch).
pub finalized_header: BeaconBlockHeader,
pub finalized_header: LightClientHeader,
/// Merkle proof attesting finalized header.
pub finality_branch: FixedVector<Hash256, FinalizedRootProofLen>,
/// current sync aggreggate
@@ -138,10 +142,10 @@ impl<T: EthSpec> LightClientUpdate<T> {
attested_state.compute_merkle_proof(NEXT_SYNC_COMMITTEE_INDEX)?;
let finality_branch = attested_state.compute_merkle_proof(FINALIZED_ROOT_INDEX)?;
Ok(Self {
attested_header,
attested_header: attested_header.into(),
next_sync_committee: attested_state.next_sync_committee()?.clone(),
next_sync_committee_branch: FixedVector::new(next_sync_committee_branch)?,
finalized_header,
finalized_header: finalized_header.into(),
finality_branch: FixedVector::new(finality_branch)?,
sync_aggregate: sync_aggregate.clone(),
signature_slot: block.slot(),
@@ -149,6 +153,26 @@ impl<T: EthSpec> LightClientUpdate<T> {
}
}
impl<T: EthSpec> ForkVersionDeserialize for LightClientUpdate<T> {
fn deserialize_by_fork<'de, D: Deserializer<'de>>(
value: Value,
fork_name: ForkName,
) -> Result<Self, D::Error> {
match fork_name {
ForkName::Altair | ForkName::Merge => {
Ok(serde_json::from_value::<LightClientUpdate<T>>(value)
.map_err(serde::de::Error::custom))?
}
ForkName::Base | ForkName::Capella | ForkName::Deneb => {
Err(serde::de::Error::custom(format!(
"LightClientUpdate failed to deserialize: unsupported fork '{}'",
fork_name
)))
}
}
}
}
#[cfg(test)]
mod tests {
use super::*;

View File

@@ -25,11 +25,11 @@ pub struct SyncAggregatorSelectionData {
pub subcommittee_index: u64,
}
impl SignedRoot for SyncAggregatorSelectionData {}
#[cfg(test)]
mod tests {
use super::*;
ssz_and_tree_hash_tests!(SyncAggregatorSelectionData);
}
impl SignedRoot for SyncAggregatorSelectionData {}

View File

@@ -1,17 +1,14 @@
use crate::test_utils::TestRandom;
use crate::typenum::Unsigned;
use crate::{EthSpec, SyncSubnetId};
use bls::PublicKeyBytes;
use safe_arith::{ArithError, SafeArith};
use serde::{Deserialize, Serialize};
use ssz_derive::{Decode, Encode};
use ssz_types::FixedVector;
use std::collections::HashMap;
use test_random_derive::TestRandom;
use tree_hash_derive::TreeHash;
// Use flat `FixedVector` regardless of whether or not tree states are used.
use ssz_types::FixedVector;
#[derive(Debug, PartialEq)]
pub enum Error {
ArithError(ArithError),
@@ -49,14 +46,11 @@ pub struct SyncCommittee<T: EthSpec> {
impl<T: EthSpec> SyncCommittee<T> {
/// Create a temporary sync committee that should *never* be included in a legitimate consensus object.
pub fn temporary() -> Result<Self, ssz_types::Error> {
Ok(Self {
pubkeys: FixedVector::new(vec![
PublicKeyBytes::empty();
T::SyncCommitteeSize::to_usize()
])?,
pub fn temporary() -> Self {
Self {
pubkeys: FixedVector::from_elem(PublicKeyBytes::empty()),
aggregate_pubkey: PublicKeyBytes::empty(),
})
}
}
/// Return the pubkeys in this `SyncCommittee` for the given `subcommittee_index`.