mirror of
https://github.com/sigp/lighthouse.git
synced 2026-05-07 16:55:46 +00:00
Merge remote-tracking branch 'origin/unstable' into tree-states
This commit is contained in:
@@ -92,8 +92,7 @@ impl ForkChoiceTest {
|
||||
T: Fn(&BeaconForkChoiceStore<E, MemoryStore<E>, MemoryStore<E>>) -> U,
|
||||
{
|
||||
func(
|
||||
&self
|
||||
.harness
|
||||
self.harness
|
||||
.chain
|
||||
.canonical_head
|
||||
.fork_choice_read_lock()
|
||||
@@ -386,8 +385,7 @@ impl ForkChoiceTest {
|
||||
&self.harness.chain.spec,
|
||||
self.harness.logger(),
|
||||
)
|
||||
.err()
|
||||
.expect("on_block did not return an error");
|
||||
.expect_err("on_block did not return an error");
|
||||
comparison_func(err);
|
||||
self
|
||||
}
|
||||
@@ -841,7 +839,7 @@ async fn valid_attestation() {
|
||||
.apply_attestation_to_chain(
|
||||
MutationDelay::NoDelay,
|
||||
|_, _| {},
|
||||
|result| assert_eq!(result.unwrap(), ()),
|
||||
|result| assert!(result.is_ok()),
|
||||
)
|
||||
.await;
|
||||
}
|
||||
@@ -1074,7 +1072,7 @@ async fn invalid_attestation_delayed_slot() {
|
||||
.apply_attestation_to_chain(
|
||||
MutationDelay::NoDelay,
|
||||
|_, _| {},
|
||||
|result| assert_eq!(result.unwrap(), ()),
|
||||
|result| assert!(result.is_ok()),
|
||||
)
|
||||
.await
|
||||
.inspect_queued_attestations(|queue| assert_eq!(queue.len(), 1))
|
||||
@@ -1183,7 +1181,7 @@ async fn weak_subjectivity_check_fails_early_epoch() {
|
||||
|
||||
let mut checkpoint = setup_harness.harness.finalized_checkpoint();
|
||||
|
||||
checkpoint.epoch = checkpoint.epoch - 1;
|
||||
checkpoint.epoch -= 1;
|
||||
|
||||
let chain_config = ChainConfig {
|
||||
weak_subjectivity_checkpoint: Some(checkpoint),
|
||||
@@ -1210,7 +1208,7 @@ async fn weak_subjectivity_check_fails_late_epoch() {
|
||||
|
||||
let mut checkpoint = setup_harness.harness.finalized_checkpoint();
|
||||
|
||||
checkpoint.epoch = checkpoint.epoch + 1;
|
||||
checkpoint.epoch += 1;
|
||||
|
||||
let chain_config = ChainConfig {
|
||||
weak_subjectivity_checkpoint: Some(checkpoint),
|
||||
|
||||
@@ -1035,13 +1035,11 @@ impl ProtoArray {
|
||||
.epoch
|
||||
.start_slot(E::slots_per_epoch());
|
||||
|
||||
let mut node = if let Some(node) = self
|
||||
let Some(mut node) = self
|
||||
.indices
|
||||
.get(&root)
|
||||
.and_then(|index| self.nodes.get(*index))
|
||||
{
|
||||
node
|
||||
} else {
|
||||
else {
|
||||
// An unknown root is not a finalized descendant. This line can only
|
||||
// be reached if the user supplies a root that is not known to fork
|
||||
// choice.
|
||||
|
||||
@@ -41,3 +41,4 @@ arbitrary-fuzz = [
|
||||
"ssz_types/arbitrary",
|
||||
"tree_hash/arbitrary",
|
||||
]
|
||||
portable = ["bls/supranational-portable"]
|
||||
@@ -30,12 +30,11 @@ impl<E: EthSpec> AllCaches for BeaconState<E> {
|
||||
|
||||
fn all_caches_built(&self) -> bool {
|
||||
let current_epoch = self.current_epoch();
|
||||
let epoch_cache_decision_block_root =
|
||||
if let Ok(root) = self.proposer_shuffling_decision_root(Hash256::zero()) {
|
||||
root
|
||||
} else {
|
||||
return false;
|
||||
};
|
||||
let Ok(epoch_cache_decision_block_root) =
|
||||
self.proposer_shuffling_decision_root(Hash256::zero())
|
||||
else {
|
||||
return false;
|
||||
};
|
||||
self.get_total_active_balance_at_epoch(current_epoch)
|
||||
.is_ok()
|
||||
&& self.committee_cache_is_initialized(RelativeEpoch::Previous)
|
||||
|
||||
@@ -70,3 +70,4 @@ sqlite = []
|
||||
# The `arbitrary-fuzz` feature is a no-op provided for backwards compatibility.
|
||||
# For simplicity `Arbitrary` is now derived regardless of the feature's presence.
|
||||
arbitrary-fuzz = []
|
||||
portable = ["bls/supranational-portable"]
|
||||
@@ -3,7 +3,7 @@
|
||||
# Misc
|
||||
# ---------------------------------------------------------------
|
||||
# [customized]
|
||||
FIELD_ELEMENTS_PER_BLOB: 4
|
||||
FIELD_ELEMENTS_PER_BLOB: 4096
|
||||
# [customized]
|
||||
MAX_BLOB_COMMITMENTS_PER_BLOCK: 16
|
||||
# `uint64(6)`
|
||||
|
||||
@@ -508,6 +508,14 @@ impl<E: EthSpec> From<BeaconBlockBody<E, FullPayload<E>>>
|
||||
}
|
||||
}
|
||||
|
||||
/// 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 {
|
||||
|
||||
@@ -750,6 +750,25 @@ impl<T: EthSpec> BeaconState<T> {
|
||||
cache.get_all_beacon_committees()
|
||||
}
|
||||
|
||||
/// Returns the block root which decided the proposer shuffling for the epoch passed in parameter. This root
|
||||
/// can be used to key this proposer shuffling.
|
||||
///
|
||||
/// ## Notes
|
||||
///
|
||||
/// The `block_root` must be equal to the latest block applied to `self`.
|
||||
pub fn proposer_shuffling_decision_root_at_epoch(
|
||||
&self,
|
||||
epoch: Epoch,
|
||||
block_root: Hash256,
|
||||
) -> Result<Hash256, Error> {
|
||||
let decision_slot = self.proposer_shuffling_decision_slot(epoch);
|
||||
if self.slot() <= decision_slot {
|
||||
Ok(block_root)
|
||||
} else {
|
||||
self.get_block_root(decision_slot).map(|root| *root)
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns the block root which decided the proposer shuffling for the current epoch. This root
|
||||
/// can be used to key this proposer shuffling.
|
||||
///
|
||||
@@ -758,7 +777,7 @@ impl<T: EthSpec> BeaconState<T> {
|
||||
/// The `block_root` covers the one-off scenario where the genesis block decides its own
|
||||
/// shuffling. It should be set to the latest block applied to `self` or the genesis block root.
|
||||
pub fn proposer_shuffling_decision_root(&self, block_root: Hash256) -> Result<Hash256, Error> {
|
||||
let decision_slot = self.proposer_shuffling_decision_slot();
|
||||
let decision_slot = self.proposer_shuffling_decision_slot(self.current_epoch());
|
||||
if self.slot() == decision_slot {
|
||||
Ok(block_root)
|
||||
} else {
|
||||
@@ -767,11 +786,9 @@ impl<T: EthSpec> BeaconState<T> {
|
||||
}
|
||||
|
||||
/// Returns the slot at which the proposer shuffling was decided. The block root at this slot
|
||||
/// can be used to key the proposer shuffling for the current epoch.
|
||||
fn proposer_shuffling_decision_slot(&self) -> Slot {
|
||||
self.current_epoch()
|
||||
.start_slot(T::slots_per_epoch())
|
||||
.saturating_sub(1_u64)
|
||||
/// can be used to key the proposer shuffling for the given epoch.
|
||||
fn proposer_shuffling_decision_slot(&self, epoch: Epoch) -> Slot {
|
||||
epoch.start_slot(T::slots_per_epoch()).saturating_sub(1_u64)
|
||||
}
|
||||
|
||||
/// Returns the block root which decided the attester shuffling for the given `relative_epoch`.
|
||||
|
||||
@@ -1,7 +1,10 @@
|
||||
use crate::test_utils::TestRandom;
|
||||
use crate::{Blob, EthSpec, Hash256, SignedRoot, Slot};
|
||||
use derivative::Derivative;
|
||||
use kzg::{Kzg, KzgCommitment, KzgPreset, KzgProof, BYTES_PER_FIELD_ELEMENT};
|
||||
use kzg::{
|
||||
Blob as KzgBlob, Kzg, KzgCommitment, KzgProof, BYTES_PER_BLOB, BYTES_PER_FIELD_ELEMENT,
|
||||
FIELD_ELEMENTS_PER_BLOB,
|
||||
};
|
||||
use rand::Rng;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use ssz::Encode;
|
||||
@@ -142,12 +145,12 @@ impl<T: EthSpec> BlobSidecar<T> {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn random_valid<R: Rng>(rng: &mut R, kzg: &Kzg<T::Kzg>) -> Result<Self, String> {
|
||||
let mut blob_bytes = vec![0u8; T::Kzg::BYTES_PER_BLOB];
|
||||
pub fn random_valid<R: Rng>(rng: &mut R, kzg: &Kzg) -> Result<Self, String> {
|
||||
let mut blob_bytes = vec![0u8; BYTES_PER_BLOB];
|
||||
rng.fill_bytes(&mut blob_bytes);
|
||||
// Ensure that the blob is canonical by ensuring that
|
||||
// each field element contained in the blob is < BLS_MODULUS
|
||||
for i in 0..T::Kzg::FIELD_ELEMENTS_PER_BLOB {
|
||||
for i in 0..FIELD_ELEMENTS_PER_BLOB {
|
||||
let Some(byte) = blob_bytes.get_mut(
|
||||
i.checked_mul(BYTES_PER_FIELD_ELEMENT)
|
||||
.ok_or("overflow".to_string())?,
|
||||
@@ -159,7 +162,7 @@ impl<T: EthSpec> BlobSidecar<T> {
|
||||
|
||||
let blob = Blob::<T>::new(blob_bytes)
|
||||
.map_err(|e| format!("error constructing random blob: {:?}", e))?;
|
||||
let kzg_blob = T::blob_from_bytes(&blob).unwrap();
|
||||
let kzg_blob = KzgBlob::from_bytes(&blob).unwrap();
|
||||
|
||||
let commitment = kzg
|
||||
.blob_to_kzg_commitment(&kzg_blob)
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
use crate::*;
|
||||
|
||||
use kzg::{BlobTrait, KzgPreset, MainnetKzgPreset, MinimalKzgPreset};
|
||||
use safe_arith::SafeArith;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use ssz_types::typenum::{
|
||||
@@ -52,8 +51,6 @@ impl fmt::Display for EthSpecId {
|
||||
pub trait EthSpec:
|
||||
'static + Default + Sync + Send + Clone + Debug + PartialEq + Eq + for<'a> arbitrary::Arbitrary<'a>
|
||||
{
|
||||
type Kzg: KzgPreset;
|
||||
|
||||
/*
|
||||
* Constants
|
||||
*/
|
||||
@@ -270,10 +267,6 @@ pub trait EthSpec:
|
||||
Self::FieldElementsPerBlob::to_usize()
|
||||
}
|
||||
|
||||
fn blob_from_bytes(bytes: &[u8]) -> Result<<Self::Kzg as KzgPreset>::Blob, kzg::Error> {
|
||||
<Self::Kzg as KzgPreset>::Blob::from_bytes(bytes)
|
||||
}
|
||||
|
||||
/// Returns the `BYTES_PER_BLOB` constant for this specification.
|
||||
fn bytes_per_blob() -> usize {
|
||||
Self::BytesPerBlob::to_usize()
|
||||
@@ -293,8 +286,6 @@ macro_rules! params_from_eth_spec {
|
||||
pub struct MainnetEthSpec;
|
||||
|
||||
impl EthSpec for MainnetEthSpec {
|
||||
type Kzg = MainnetKzgPreset;
|
||||
|
||||
type JustificationBitsLength = U4;
|
||||
type SubnetBitfieldLength = U64;
|
||||
type MaxValidatorsPerCommittee = U2048;
|
||||
@@ -344,8 +335,6 @@ impl EthSpec for MainnetEthSpec {
|
||||
pub struct MinimalEthSpec;
|
||||
|
||||
impl EthSpec for MinimalEthSpec {
|
||||
type Kzg = MinimalKzgPreset;
|
||||
|
||||
type SlotsPerEpoch = U8;
|
||||
type EpochsPerEth1VotingPeriod = U4;
|
||||
type SlotsPerHistoricalRoot = U64;
|
||||
@@ -356,8 +345,8 @@ impl EthSpec for MinimalEthSpec {
|
||||
type MaxPendingAttestations = U1024; // 128 max attestations * 8 slots per epoch
|
||||
type SlotsPerEth1VotingPeriod = U32; // 4 epochs * 8 slots per epoch
|
||||
type MaxWithdrawalsPerPayload = U4;
|
||||
type FieldElementsPerBlob = U4;
|
||||
type BytesPerBlob = U128;
|
||||
type FieldElementsPerBlob = U4096;
|
||||
type BytesPerBlob = U131072;
|
||||
type MaxBlobCommitmentsPerBlock = U16;
|
||||
|
||||
params_from_eth_spec!(MainnetEthSpec {
|
||||
@@ -398,8 +387,6 @@ impl EthSpec for MinimalEthSpec {
|
||||
pub struct GnosisEthSpec;
|
||||
|
||||
impl EthSpec for GnosisEthSpec {
|
||||
type Kzg = MainnetKzgPreset;
|
||||
|
||||
type JustificationBitsLength = U4;
|
||||
type SubnetBitfieldLength = U64;
|
||||
type MaxValidatorsPerCommittee = U2048;
|
||||
|
||||
@@ -979,3 +979,10 @@ impl<T: EthSpec> From<BlindedPayload<T>> for ExecutionPayloadHeader<T> {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// The block production flow version to be used.
|
||||
pub enum BlockProductionVersion {
|
||||
V3,
|
||||
BlindedV2,
|
||||
FullV2,
|
||||
}
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
use crate::beacon_block_body::format_kzg_commitments;
|
||||
use crate::*;
|
||||
use bls::Signature;
|
||||
use derivative::Derivative;
|
||||
@@ -256,6 +257,15 @@ impl<E: EthSpec, Payload: AbstractExecPayload<E>> SignedBeaconBlock<E, Payload>
|
||||
.map(|c| c.len())
|
||||
.unwrap_or(0)
|
||||
}
|
||||
|
||||
/// Used for displaying commitments in logs.
|
||||
pub fn commitments_formatted(&self) -> String {
|
||||
let Ok(commitments) = self.message().body().blob_kzg_commitments() else {
|
||||
return "[]".to_string();
|
||||
};
|
||||
|
||||
format_kzg_commitments(commitments.as_ref())
|
||||
}
|
||||
}
|
||||
|
||||
// We can convert pre-Bellatrix blocks without payloads into blocks with payloads.
|
||||
|
||||
Reference in New Issue
Block a user