mirror of
https://github.com/sigp/lighthouse.git
synced 2026-05-31 13:17:09 +00:00
Test only execute for glosa
This commit is contained in:
@@ -612,8 +612,6 @@ impl<E: EthSpec> AvailablePayload<E> {
|
|||||||
/// Returns `AvailabilityCheckError` if:
|
/// Returns `AvailabilityCheckError` if:
|
||||||
/// - `column_data` contains data not required by the block
|
/// - `column_data` contains data not required by the block
|
||||||
/// - Required `column_data` is missing
|
/// - Required `column_data` is missing
|
||||||
/// - Blob count doesn't match expected
|
|
||||||
/// - Custody columns are incomplete
|
|
||||||
pub fn new<T>(
|
pub fn new<T>(
|
||||||
payload: Arc<SignedExecutionPayloadEnvelope<T::EthSpec>>,
|
payload: Arc<SignedExecutionPayloadEnvelope<T::EthSpec>>,
|
||||||
block: Arc<SignedBeaconBlock<E>>,
|
block: Arc<SignedBeaconBlock<E>>,
|
||||||
|
|||||||
@@ -776,6 +776,7 @@ mod test {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
|
#[ignore] // TODO(gloas): Implement availability_pending_payload
|
||||||
async fn overflow_cache_test_insert_components() {
|
async fn overflow_cache_test_insert_components() {
|
||||||
type E = MinimalEthSpec;
|
type E = MinimalEthSpec;
|
||||||
type T = DiskHarnessType<E>;
|
type T = DiskHarnessType<E>;
|
||||||
@@ -899,6 +900,7 @@ mod test {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
|
#[ignore] // TODO(gloas): Implement availability_pending_payload
|
||||||
// ensure the state cache keeps memory usage low and that it can properly recover states
|
// ensure the state cache keeps memory usage low and that it can properly recover states
|
||||||
// THIS TEST CAN BE DELETED ONCE TREE STATES IS MERGED AND WE RIP OUT THE STATE CACHE
|
// THIS TEST CAN BE DELETED ONCE TREE STATES IS MERGED AND WE RIP OUT THE STATE CACHE
|
||||||
async fn overflow_cache_test_state_cache() {
|
async fn overflow_cache_test_state_cache() {
|
||||||
@@ -1024,14 +1026,14 @@ mod pending_components_tests {
|
|||||||
use super::*;
|
use super::*;
|
||||||
use crate::PayloadVerificationOutcome;
|
use crate::PayloadVerificationOutcome;
|
||||||
use crate::data_column_verification::KzgVerifiedDataColumn;
|
use crate::data_column_verification::KzgVerifiedDataColumn;
|
||||||
use crate::test_utils::{NumBlobs, generate_data_column_sidecars_from_payload, test_spec};
|
use crate::test_utils::{NumBlobs, generate_rand_payload_and_columns, test_spec};
|
||||||
use fork_choice::PayloadVerificationStatus;
|
use fork_choice::PayloadVerificationStatus;
|
||||||
use kzg::KzgCommitment;
|
use kzg::KzgCommitment;
|
||||||
|
use rand::SeedableRng;
|
||||||
use rand::rngs::StdRng;
|
use rand::rngs::StdRng;
|
||||||
use rand::{Rng, SeedableRng};
|
|
||||||
use ssz_types::VariableList;
|
use ssz_types::VariableList;
|
||||||
use types::test_utils::TestRandom;
|
use types::test_utils::TestRandom;
|
||||||
use types::{ForkName, MainnetEthSpec, SignedExecutionPayloadEnvelope};
|
use types::{ForkName, MainnetEthSpec, SignedExecutionPayloadEnvelope, Slot};
|
||||||
|
|
||||||
type E = MainnetEthSpec;
|
type E = MainnetEthSpec;
|
||||||
|
|
||||||
@@ -1041,28 +1043,27 @@ mod pending_components_tests {
|
|||||||
DataColumnSidecarList<E>,
|
DataColumnSidecarList<E>,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
/// Returns true if gloas is enabled for testing. Tests should skip if this returns false.
|
||||||
|
fn is_gloas_enabled() -> bool {
|
||||||
|
let spec = test_spec::<E>();
|
||||||
|
spec.fork_name_at_slot::<E>(Slot::new(0)).gloas_enabled()
|
||||||
|
}
|
||||||
|
|
||||||
fn pre_setup() -> Setup {
|
fn pre_setup() -> Setup {
|
||||||
let mut rng = StdRng::seed_from_u64(0xDEADBEEF0BAD5EEDu64);
|
let mut rng = StdRng::seed_from_u64(0xDEADBEEF0BAD5EEDu64);
|
||||||
let spec = test_spec::<E>();
|
let spec = test_spec::<E>();
|
||||||
// Ensure spec supports gloas so build_data_column_sidecars_gloas succeeds
|
|
||||||
let spec = ForkName::Gloas.make_genesis_spec(spec);
|
|
||||||
|
|
||||||
let mut payload = SignedExecutionPayloadEnvelope::<E>::random_for_test(&mut rng);
|
assert!(
|
||||||
// Generate blob transactions to populate blob_kzg_commitments
|
spec.fork_name_at_slot::<E>(Slot::new(0)).gloas_enabled(),
|
||||||
let num_blobs = match NumBlobs::Random {
|
"pre_setup() only works after gloas"
|
||||||
NumBlobs::Random => rng.random_range(1..=6usize),
|
);
|
||||||
NumBlobs::Number(n) => n,
|
|
||||||
NumBlobs::None => 0,
|
|
||||||
};
|
|
||||||
let (bundle, transactions) =
|
|
||||||
execution_layer::test_utils::generate_blobs::<E>(num_blobs, ForkName::Gloas).unwrap();
|
|
||||||
payload.message.payload.transactions = <_>::default();
|
|
||||||
for tx in Vec::from(transactions) {
|
|
||||||
payload.message.payload.transactions.push(tx).unwrap();
|
|
||||||
}
|
|
||||||
payload.message.blob_kzg_commitments = bundle.commitments.clone();
|
|
||||||
|
|
||||||
let columns = generate_data_column_sidecars_from_payload(&payload, &spec);
|
let (payload, columns) = generate_rand_payload_and_columns::<E>(
|
||||||
|
ForkName::Gloas,
|
||||||
|
NumBlobs::Random,
|
||||||
|
&mut rng,
|
||||||
|
&spec,
|
||||||
|
);
|
||||||
|
|
||||||
// Create invalid columns by mutating kzg_commitments
|
// Create invalid columns by mutating kzg_commitments
|
||||||
let invalid_columns: DataColumnSidecarList<E> = columns
|
let invalid_columns: DataColumnSidecarList<E> = columns
|
||||||
@@ -1163,6 +1164,9 @@ mod pending_components_tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn payload_invalid_columns_valid_columns() {
|
fn payload_invalid_columns_valid_columns() {
|
||||||
|
if !is_gloas_enabled() {
|
||||||
|
return;
|
||||||
|
}
|
||||||
let (payload, columns, invalid_columns) = pre_setup();
|
let (payload, columns, invalid_columns) = pre_setup();
|
||||||
let (diet_payload, columns, invalid_columns) =
|
let (diet_payload, columns, invalid_columns) =
|
||||||
setup_pending_components(payload, columns, invalid_columns);
|
setup_pending_components(payload, columns, invalid_columns);
|
||||||
@@ -1183,6 +1187,9 @@ mod pending_components_tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn invalid_columns_payload_valid_columns() {
|
fn invalid_columns_payload_valid_columns() {
|
||||||
|
if !is_gloas_enabled() {
|
||||||
|
return;
|
||||||
|
}
|
||||||
let (payload, columns, invalid_columns) = pre_setup();
|
let (payload, columns, invalid_columns) = pre_setup();
|
||||||
let (diet_payload, columns, invalid_columns) =
|
let (diet_payload, columns, invalid_columns) =
|
||||||
setup_pending_components(payload, columns, invalid_columns);
|
setup_pending_components(payload, columns, invalid_columns);
|
||||||
@@ -1202,6 +1209,9 @@ mod pending_components_tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn invalid_columns_valid_columns_payload() {
|
fn invalid_columns_valid_columns_payload() {
|
||||||
|
if !is_gloas_enabled() {
|
||||||
|
return;
|
||||||
|
}
|
||||||
let (payload, columns, invalid_columns) = pre_setup();
|
let (payload, columns, invalid_columns) = pre_setup();
|
||||||
let (diet_payload, columns, invalid_columns) =
|
let (diet_payload, columns, invalid_columns) =
|
||||||
setup_pending_components(payload, columns, invalid_columns);
|
setup_pending_components(payload, columns, invalid_columns);
|
||||||
@@ -1222,6 +1232,9 @@ mod pending_components_tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn payload_valid_columns_invalid_columns() {
|
fn payload_valid_columns_invalid_columns() {
|
||||||
|
if !is_gloas_enabled() {
|
||||||
|
return;
|
||||||
|
}
|
||||||
let (payload, columns, invalid_columns) = pre_setup();
|
let (payload, columns, invalid_columns) = pre_setup();
|
||||||
let (diet_payload, columns, invalid_columns) =
|
let (diet_payload, columns, invalid_columns) =
|
||||||
setup_pending_components(payload, columns, invalid_columns);
|
setup_pending_components(payload, columns, invalid_columns);
|
||||||
@@ -1242,6 +1255,9 @@ mod pending_components_tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn valid_columns_payload_invalid_columns() {
|
fn valid_columns_payload_invalid_columns() {
|
||||||
|
if !is_gloas_enabled() {
|
||||||
|
return;
|
||||||
|
}
|
||||||
let (payload, columns, invalid_columns) = pre_setup();
|
let (payload, columns, invalid_columns) = pre_setup();
|
||||||
let (diet_payload, columns, invalid_columns) =
|
let (diet_payload, columns, invalid_columns) =
|
||||||
setup_pending_components(payload, columns, invalid_columns);
|
setup_pending_components(payload, columns, invalid_columns);
|
||||||
@@ -1262,6 +1278,9 @@ mod pending_components_tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn valid_columns_invalid_columns_payload() {
|
fn valid_columns_invalid_columns_payload() {
|
||||||
|
if !is_gloas_enabled() {
|
||||||
|
return;
|
||||||
|
}
|
||||||
let (payload, columns, invalid_columns) = pre_setup();
|
let (payload, columns, invalid_columns) = pre_setup();
|
||||||
let (diet_payload, columns, invalid_columns) =
|
let (diet_payload, columns, invalid_columns) =
|
||||||
setup_pending_components(payload, columns, invalid_columns);
|
setup_pending_components(payload, columns, invalid_columns);
|
||||||
@@ -1282,6 +1301,9 @@ mod pending_components_tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn should_not_insert_pre_execution_payload_if_executed_payload_exists() {
|
fn should_not_insert_pre_execution_payload_if_executed_payload_exists() {
|
||||||
|
if !is_gloas_enabled() {
|
||||||
|
return;
|
||||||
|
}
|
||||||
let (payload, _columns, _invalid_columns) = pre_setup();
|
let (payload, _columns, _invalid_columns) = pre_setup();
|
||||||
let (diet_payload, _columns, _invalid_columns) =
|
let (diet_payload, _columns, _invalid_columns) =
|
||||||
setup_pending_components(payload.clone(), _columns, _invalid_columns);
|
setup_pending_components(payload.clone(), _columns, _invalid_columns);
|
||||||
|
|||||||
@@ -3436,7 +3436,7 @@ macro_rules! add_blob_transactions_gloas {
|
|||||||
}};
|
}};
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn generate_rand_payloads_and_columns<E: EthSpec>(
|
pub fn generate_rand_payload_and_columns<E: EthSpec>(
|
||||||
fork_name: ForkName,
|
fork_name: ForkName,
|
||||||
num_blobs: NumBlobs,
|
num_blobs: NumBlobs,
|
||||||
rng: &mut impl Rng,
|
rng: &mut impl Rng,
|
||||||
@@ -3616,8 +3616,10 @@ pub fn generate_data_column_sidecars_from_payload<E: EthSpec>(
|
|||||||
return vec![];
|
return vec![];
|
||||||
}
|
}
|
||||||
|
|
||||||
// load the precomputed column sidecar to avoid computing them for every block in the tests.
|
// Load the precomputed column sidecar to avoid computing them for every block in the tests.
|
||||||
let template_data_columns = RuntimeVariableList::<DataColumnSidecarGloas<E>>::from_ssz_bytes(
|
// TODO(gloas): The fixture is currently in Fulu format. We should generate a Gloas-specific
|
||||||
|
// fixture once the format is finalized, or compute columns dynamically for Gloas tests.
|
||||||
|
let template_data_columns = RuntimeVariableList::<DataColumnSidecarFulu<E>>::from_ssz_bytes(
|
||||||
TEST_DATA_COLUMN_SIDECARS_SSZ,
|
TEST_DATA_COLUMN_SIDECARS_SSZ,
|
||||||
E::number_of_columns(),
|
E::number_of_columns(),
|
||||||
)
|
)
|
||||||
@@ -3626,7 +3628,7 @@ pub fn generate_data_column_sidecars_from_payload<E: EthSpec>(
|
|||||||
let (cells, proofs) = template_data_columns
|
let (cells, proofs) = template_data_columns
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|sidecar| {
|
.map(|sidecar| {
|
||||||
let DataColumnSidecarGloas {
|
let DataColumnSidecarFulu {
|
||||||
column, kzg_proofs, ..
|
column, kzg_proofs, ..
|
||||||
} = sidecar;
|
} = sidecar;
|
||||||
// There's only one cell per column for a single blob
|
// There's only one cell per column for a single blob
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ use std::sync::Arc;
|
|||||||
use bls::Signature;
|
use bls::Signature;
|
||||||
use context_deserialize::context_deserialize;
|
use context_deserialize::context_deserialize;
|
||||||
use educe::Educe;
|
use educe::Educe;
|
||||||
use kzg::{BYTES_PER_BLOB, CellsAndKzgProofs, Kzg, KzgCommitment, KzgProof};
|
use kzg::{KzgCommitment, KzgProof};
|
||||||
use merkle_proof::verify_merkle_proof;
|
use merkle_proof::verify_merkle_proof;
|
||||||
use safe_arith::ArithError;
|
use safe_arith::ArithError;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
@@ -17,11 +17,8 @@ use tree_hash::TreeHash;
|
|||||||
use tree_hash_derive::TreeHash;
|
use tree_hash_derive::TreeHash;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
block::{
|
block::{BLOB_KZG_COMMITMENTS_INDEX, BeaconBlockHeader, SignedBeaconBlockHeader},
|
||||||
BLOB_KZG_COMMITMENTS_INDEX, BeaconBlockHeader, SignedBeaconBlock, SignedBeaconBlockHeader,
|
core::{Epoch, EthSpec, Hash256, Slot},
|
||||||
},
|
|
||||||
core::{ChainSpec, Epoch, EthSpec, Hash256, Slot},
|
|
||||||
data::BlobsList,
|
|
||||||
fork::ForkName,
|
fork::ForkName,
|
||||||
kzg_ext::{KzgCommitments, KzgError},
|
kzg_ext::{KzgCommitments, KzgError},
|
||||||
state::BeaconStateError,
|
state::BeaconStateError,
|
||||||
@@ -137,124 +134,6 @@ impl<E: EthSpec> DataColumnSidecar<E> {
|
|||||||
)),
|
)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Build data column sidecars from blobs and a signed beacon block.
|
|
||||||
///
|
|
||||||
/// This method computes cells and cell proofs from the blobs using KZG,
|
|
||||||
/// then constructs the appropriate data column sidecar variant (Fulu or Gloas)
|
|
||||||
/// based on the block's fork.
|
|
||||||
pub fn build_sidecars(
|
|
||||||
blobs: BlobsList<E>,
|
|
||||||
block: &SignedBeaconBlock<E>,
|
|
||||||
kzg: &Kzg,
|
|
||||||
spec: &ChainSpec,
|
|
||||||
) -> Result<DataColumnSidecarList<E>, DataColumnSidecarError> {
|
|
||||||
if blobs.is_empty() {
|
|
||||||
return Ok(vec![]);
|
|
||||||
}
|
|
||||||
|
|
||||||
let kzg_commitments = block
|
|
||||||
.message()
|
|
||||||
.body()
|
|
||||||
.blob_kzg_commitments()
|
|
||||||
.map_err(|_| DataColumnSidecarError::PreDeneb)?
|
|
||||||
.clone();
|
|
||||||
|
|
||||||
// Compute cells and proofs for each blob
|
|
||||||
let blob_cells_and_proofs: Vec<CellsAndKzgProofs> = blobs
|
|
||||||
.iter()
|
|
||||||
.map(|blob| {
|
|
||||||
let blob_bytes: &[u8; BYTES_PER_BLOB] = blob.as_ref().try_into().map_err(|_| {
|
|
||||||
DataColumnSidecarError::KzgError(KzgError::InconsistentArrayLength(format!(
|
|
||||||
"blob should have size {}, got {}",
|
|
||||||
BYTES_PER_BLOB,
|
|
||||||
blob.len()
|
|
||||||
)))
|
|
||||||
})?;
|
|
||||||
kzg.compute_cells_and_proofs(blob_bytes)
|
|
||||||
.map_err(DataColumnSidecarError::KzgError)
|
|
||||||
})
|
|
||||||
.collect::<Result<Vec<_>, _>>()?;
|
|
||||||
|
|
||||||
let number_of_columns = E::number_of_columns();
|
|
||||||
let max_blobs_per_block =
|
|
||||||
spec.max_blobs_per_block(block.slot().epoch(E::slots_per_epoch())) as usize;
|
|
||||||
|
|
||||||
// Initialize columns and proofs vectors
|
|
||||||
let mut columns: Vec<Vec<Cell<E>>> =
|
|
||||||
vec![Vec::with_capacity(max_blobs_per_block); number_of_columns];
|
|
||||||
let mut column_kzg_proofs: Vec<Vec<KzgProof>> =
|
|
||||||
vec![Vec::with_capacity(max_blobs_per_block); number_of_columns];
|
|
||||||
|
|
||||||
// Arrange cells and proofs into columns
|
|
||||||
for (blob_cells, blob_cell_proofs) in &blob_cells_and_proofs {
|
|
||||||
for col_idx in 0..number_of_columns {
|
|
||||||
let cell = blob_cells
|
|
||||||
.get(col_idx)
|
|
||||||
.ok_or(DataColumnSidecarError::DataColumnIndexOutOfBounds)?;
|
|
||||||
let cell_vec: Vec<u8> = cell.to_vec();
|
|
||||||
let cell = Cell::<E>::try_from(cell_vec)?;
|
|
||||||
|
|
||||||
let proof = blob_cell_proofs
|
|
||||||
.get(col_idx)
|
|
||||||
.ok_or(DataColumnSidecarError::DataColumnIndexOutOfBounds)?;
|
|
||||||
|
|
||||||
columns
|
|
||||||
.get_mut(col_idx)
|
|
||||||
.ok_or(DataColumnSidecarError::DataColumnIndexOutOfBounds)?
|
|
||||||
.push(cell);
|
|
||||||
column_kzg_proofs
|
|
||||||
.get_mut(col_idx)
|
|
||||||
.ok_or(DataColumnSidecarError::DataColumnIndexOutOfBounds)?
|
|
||||||
.push(*proof);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Build sidecars based on fork
|
|
||||||
let fork_name = block.fork_name_unchecked();
|
|
||||||
if fork_name.gloas_enabled() {
|
|
||||||
// Gloas variant
|
|
||||||
let beacon_block_root = block.canonical_root();
|
|
||||||
let slot = block.slot();
|
|
||||||
|
|
||||||
columns
|
|
||||||
.into_iter()
|
|
||||||
.zip(column_kzg_proofs)
|
|
||||||
.enumerate()
|
|
||||||
.map(|(index, (col, proofs))| {
|
|
||||||
Ok(Arc::new(DataColumnSidecar::Gloas(DataColumnSidecarGloas {
|
|
||||||
index: index as u64,
|
|
||||||
column: DataColumn::<E>::try_from(col)?,
|
|
||||||
kzg_commitments: kzg_commitments.clone(),
|
|
||||||
kzg_proofs: VariableList::try_from(proofs)?,
|
|
||||||
slot,
|
|
||||||
beacon_block_root,
|
|
||||||
})))
|
|
||||||
})
|
|
||||||
.collect()
|
|
||||||
} else {
|
|
||||||
// Fulu variant
|
|
||||||
let signed_block_header = block.signed_block_header();
|
|
||||||
let kzg_commitments_inclusion_proof =
|
|
||||||
block.message().body().kzg_commitments_merkle_proof()?;
|
|
||||||
|
|
||||||
columns
|
|
||||||
.into_iter()
|
|
||||||
.zip(column_kzg_proofs)
|
|
||||||
.enumerate()
|
|
||||||
.map(|(index, (col, proofs))| {
|
|
||||||
Ok(Arc::new(DataColumnSidecar::Fulu(DataColumnSidecarFulu {
|
|
||||||
index: index as u64,
|
|
||||||
column: DataColumn::<E>::try_from(col)?,
|
|
||||||
kzg_commitments: kzg_commitments.clone(),
|
|
||||||
kzg_proofs: VariableList::try_from(proofs)?,
|
|
||||||
signed_block_header: signed_block_header.clone(),
|
|
||||||
kzg_commitments_inclusion_proof: kzg_commitments_inclusion_proof.clone(),
|
|
||||||
})))
|
|
||||||
})
|
|
||||||
.collect()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<E: EthSpec> DataColumnSidecarFulu<E> {
|
impl<E: EthSpec> DataColumnSidecarFulu<E> {
|
||||||
|
|||||||
Reference in New Issue
Block a user