mirror of
https://github.com/sigp/lighthouse.git
synced 2026-05-31 05:07:12 +00:00
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:
@@ -323,18 +323,34 @@ fn update_data_column_signed_header<E: EthSpec>(
|
||||
) {
|
||||
for old_custody_column_sidecar in data_columns.as_mut_slice() {
|
||||
let old_column_sidecar = old_custody_column_sidecar.as_data_column();
|
||||
let new_column_sidecar = Arc::new(DataColumnSidecar::Fulu(DataColumnSidecarFulu {
|
||||
index: *old_column_sidecar.index(),
|
||||
column: old_column_sidecar.column().clone(),
|
||||
kzg_commitments: old_column_sidecar.kzg_commitments().unwrap().clone(),
|
||||
kzg_proofs: old_column_sidecar.kzg_proofs().clone(),
|
||||
signed_block_header: signed_block.signed_block_header(),
|
||||
kzg_commitments_inclusion_proof: signed_block
|
||||
.message()
|
||||
.body()
|
||||
.kzg_commitments_merkle_proof()
|
||||
.unwrap(),
|
||||
}));
|
||||
let new_column_sidecar = match old_column_sidecar.as_ref() {
|
||||
DataColumnSidecar::Fulu(_) => {
|
||||
Arc::new(DataColumnSidecar::Fulu(DataColumnSidecarFulu {
|
||||
index: *old_column_sidecar.index(),
|
||||
column: old_column_sidecar.column().clone(),
|
||||
kzg_commitments: old_column_sidecar.kzg_commitments().unwrap().clone(),
|
||||
kzg_proofs: old_column_sidecar.kzg_proofs().clone(),
|
||||
signed_block_header: signed_block.signed_block_header(),
|
||||
kzg_commitments_inclusion_proof: signed_block
|
||||
.message()
|
||||
.body()
|
||||
.kzg_commitments_merkle_proof()
|
||||
.unwrap(),
|
||||
}))
|
||||
}
|
||||
// Gloas columns reference the block by `beacon_block_root` instead of holding the
|
||||
// block header inline, so updating the parent root just means re-keying the column to
|
||||
// the new canonical root.
|
||||
DataColumnSidecar::Gloas(g) => {
|
||||
Arc::new(DataColumnSidecar::Gloas(types::DataColumnSidecarGloas {
|
||||
index: g.index,
|
||||
column: g.column.clone(),
|
||||
kzg_proofs: g.kzg_proofs.clone(),
|
||||
slot: g.slot,
|
||||
beacon_block_root: signed_block.canonical_root(),
|
||||
}))
|
||||
}
|
||||
};
|
||||
*old_custody_column_sidecar = CustodyDataColumn::from_asserted_custody(new_column_sidecar);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3133,6 +3133,29 @@ async fn weak_subjectivity_sync_test(
|
||||
|
||||
let beacon_chain = Arc::new(beacon_chain);
|
||||
let wss_block_root = wss_block.canonical_root();
|
||||
|
||||
// For Gloas, blobs aren't a standalone shape — the WSS data is the column sidecar set, which
|
||||
// `get_or_reconstruct_blobs` returns `None` for. Copy the WSS block's columns straight from
|
||||
// the source store so that the destination has them after checkpoint sync, matching what
|
||||
// network-driven WSS would produce in production.
|
||||
if wss_block.fork_name_unchecked().gloas_enabled()
|
||||
&& let Ok(Some(source_columns)) = harness
|
||||
.chain
|
||||
.store
|
||||
.get_data_columns(&wss_block_root, ForkName::Gloas)
|
||||
&& !source_columns.is_empty()
|
||||
&& let Some(store_op) = beacon_chain.get_blobs_or_columns_store_op(
|
||||
wss_block_root,
|
||||
wss_block.slot(),
|
||||
beacon_chain::block_verification_types::AvailableBlockData::DataColumns(source_columns),
|
||||
)
|
||||
{
|
||||
beacon_chain
|
||||
.store
|
||||
.do_atomically_with_block_and_blobs_cache(vec![store_op])
|
||||
.unwrap();
|
||||
}
|
||||
|
||||
let store_wss_block = harness
|
||||
.chain
|
||||
.get_block(&wss_block_root)
|
||||
@@ -3200,12 +3223,43 @@ async fn weak_subjectivity_sync_test(
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
// Store the envelope and apply it to fork choice.
|
||||
// Store the envelope, its columns, and apply to fork choice.
|
||||
if let Some(envelope) = &snapshot.execution_envelope {
|
||||
// Persist data columns for Gloas blocks. This mirrors what production does in
|
||||
// `import_available_execution_payload_envelope` and what the harness now does in
|
||||
// `process_envelope` — the WSS forward-sync loop bypasses both, so do it directly.
|
||||
let mut ops = vec![];
|
||||
let columns_block = beacon_chain
|
||||
.store
|
||||
.get_blinded_block(&block_root)
|
||||
.unwrap()
|
||||
.and_then(|b| beacon_chain.store.make_full_block(&block_root, b).ok());
|
||||
if let Some(full_block) = columns_block {
|
||||
let columns = beacon_chain::test_utils::generate_data_column_sidecars_from_block(
|
||||
&full_block,
|
||||
&beacon_chain.spec,
|
||||
);
|
||||
if !columns.is_empty()
|
||||
&& let Some(store_op) = beacon_chain.get_blobs_or_columns_store_op(
|
||||
block_root,
|
||||
full_block.slot(),
|
||||
beacon_chain::block_verification_types::AvailableBlockData::DataColumns(
|
||||
columns,
|
||||
),
|
||||
)
|
||||
{
|
||||
ops.push(store_op);
|
||||
}
|
||||
}
|
||||
ops.push(store::StoreOp::PutPayloadEnvelope(
|
||||
block_root,
|
||||
std::sync::Arc::new(envelope.as_ref().clone()),
|
||||
));
|
||||
beacon_chain
|
||||
.store
|
||||
.put_payload_envelope(&block_root, envelope)
|
||||
.do_atomically_with_block_and_blobs_cache(ops)
|
||||
.unwrap();
|
||||
|
||||
// Update fork choice so head selection accounts for Full payload status.
|
||||
beacon_chain
|
||||
.canonical_head
|
||||
|
||||
Reference in New Issue
Block a user