Gloas: fix test failures (KZG verifier wiring, harness columns, WSS sync)

Brings the FORK_NAME=gloas beacon_chain test suite from 31 failures to green:

- v1 KZG batch verifier couldn't verify Gloas columns. Added
  verify_columns_against_block helper that picks commitments per fork
  (Fulu: inline on column; Gloas: signed_execution_payload_bid).
- BeaconChainHarness::process_envelope didn't persist columns. Now mirrors
  what production does in import_available_execution_payload_envelope.
- get_or_reconstruct_blobs returned an error for Gloas. Now short-circuits to
  Ok(None); WSS test copies columns from source to dest directly.
- update_data_column_signed_header (block_verification tests) only handled
  Fulu shape. Added a Gloas branch that re-keys to canonical_root.
- BlockError::EnvelopeBlockRootUnknown changed to tuple variant.
- Removed duplicate process_payload_envelope_availability.
This commit is contained in:
dapplion
2026-05-01 03:46:10 +02:00
parent aa531bac22
commit dac8a6ec8d
11 changed files with 205 additions and 56 deletions

View File

@@ -33,6 +33,7 @@ use crate::data_column_verification::{
GossipVerifiedDataColumn, KzgVerifiedCustodyDataColumn, KzgVerifiedDataColumn,
verify_kzg_for_data_column_list,
};
use crate::kzg_utils::validate_full_data_columns_with_commitments;
use crate::metrics::{
KZG_DATA_COLUMN_RECONSTRUCTION_ATTEMPTS, KZG_DATA_COLUMN_RECONSTRUCTION_FAILURES,
};
@@ -490,8 +491,7 @@ impl<T: BeaconChainTypes> DataAvailabilityChecker<T> {
AvailableBlockData::Blobs(blobs) => verify_kzg_for_blob_list(blobs.iter(), &self.kzg)
.map_err(AvailabilityCheckError::InvalidBlobs),
AvailableBlockData::DataColumns(columns) => {
verify_kzg_for_data_column_list(columns.iter(), &self.kzg)
.map_err(AvailabilityCheckError::InvalidColumn)
verify_columns_against_block(&self.kzg, available_block.block(), columns)
}
}
}
@@ -504,13 +504,17 @@ impl<T: BeaconChainTypes> DataAvailabilityChecker<T> {
available_blocks: &[AvailableBlock<T::EthSpec>],
) -> Result<(), AvailabilityCheckError> {
let mut all_blobs = Vec::new();
let mut all_data_columns = Vec::new();
for available_block in available_blocks {
match available_block.data().to_owned() {
match available_block.data() {
AvailableBlockData::NoData => {}
AvailableBlockData::Blobs(blobs) => all_blobs.extend(blobs),
AvailableBlockData::DataColumns(columns) => all_data_columns.extend(columns),
AvailableBlockData::Blobs(blobs) => all_blobs.extend(blobs.iter().cloned()),
AvailableBlockData::DataColumns(columns) => {
// Each block has its own commitments. For Gloas they live in the bid; for
// Fulu they live inline on the column. Verify per block and let the helper
// pick the right path.
verify_columns_against_block(&self.kzg, available_block.block(), columns)?;
}
}
}
@@ -519,11 +523,6 @@ impl<T: BeaconChainTypes> DataAvailabilityChecker<T> {
.map_err(AvailabilityCheckError::InvalidBlobs)?;
}
if !all_data_columns.is_empty() {
verify_kzg_for_data_column_list(all_data_columns.iter(), &self.kzg)
.map_err(AvailabilityCheckError::InvalidColumn)?;
}
Ok(())
}
@@ -679,6 +678,35 @@ impl<T: BeaconChainTypes> DataAvailabilityChecker<T> {
}
}
/// Verify a batch of data columns belonging to a single block, picking the right commitment
/// source for the block's fork (Fulu: inline on column; Gloas: from the embedded payload bid).
fn verify_columns_against_block<E: EthSpec>(
kzg: &Kzg,
block: &SignedBeaconBlock<E>,
columns: &[Arc<DataColumnSidecar<E>>],
) -> Result<(), AvailabilityCheckError> {
if columns.is_empty() {
return Ok(());
}
if block.fork_name_unchecked().gloas_enabled() {
let commitments = block
.message()
.body()
.signed_execution_payload_bid()
.map(|bid| bid.message.blob_kzg_commitments.clone())
.map_err(|_| {
AvailabilityCheckError::Unexpected(
"Gloas block missing signed_execution_payload_bid".to_string(),
)
})?;
validate_full_data_columns_with_commitments(kzg, columns.iter(), commitments.as_ref())
.map_err(AvailabilityCheckError::InvalidColumn)
} else {
verify_kzg_for_data_column_list(columns.iter(), kzg)
.map_err(AvailabilityCheckError::InvalidColumn)
}
}
/// Helper struct to group data availability checker metrics.
pub struct DataAvailabilityCheckerMetrics {
pub block_cache_size: usize,