Skip to content

Optimize GetBlobsV2 Verification #7553

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 4 commits into
base: unstable
Choose a base branch
from

Conversation

eserilev
Copy link
Member

@eserilev eserilev commented Jun 3, 2025

Issue Addressed

#7545

Proposed Changes

Add a verification mode that skips block proposer and block signature checks.

@eserilev eserilev requested a review from jxs as a code owner June 3, 2025 19:21
@eserilev eserilev added optimization Something to make Lighthouse run more efficiently. das Data Availability Sampling ready-for-review The code is ready for review labels Jun 3, 2025
verify_proposer_and_signature(&data_column, &parent_block, chain)?;

match check_block_header {
CheckBlockHeader::Yes => verify_proposer_and_signature(&data_column, &parent_block, chain)?,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it's worth considering skipping some more checks:

  • verify_parent_block_and_finalized_descendant: this acquires a fork choice read lock - so it could delay verification when the node is overwhelmed
  • verify_column_inclusion_proof isn't necessary for sidecars constructed internally, because we're verifying proofs we just constructed (on the critical path as well!) - although this isn't part of the header, so skipping it when CheckBlockHeader::No may be confusing.
  • chain.observed_slashable.write(): it's likely a quick operation but i think we'd want to avoid acquiring locks unnecessarily - in this case it's observing the data from the header

I realise I may have not explained the rationale in the issues clearly - the main thing is we can avoid verifying some properties of the DataColumnSidecar if the sidecar is constructed internally by the node, e.g. block proposal, fetch blobs etc - and in these case we can skip:

  1. the block header that we've already verified, and have just been cloned over to the sidecar
  2. the kzg inclusion proof that we've just constructed

But for any DataColumnSidecars received over gossip, we'd want to fully verify them.

For reference, the function to construct DataColumnSidecar is below, and and the only untrusted input is Blobs and Proofs:

pub fn blobs_to_data_column_sidecars<E: EthSpec>(
blobs: &[&Blob<E>],
cell_proofs: Vec<KzgProof>,
block: &SignedBeaconBlock<E>,
kzg: &Kzg,
spec: &ChainSpec,
) -> Result<DataColumnSidecarList<E>, DataColumnSidecarError> {

let gossip_verified_column = GossipVerifiedDataColumn::new(
data_column_sidecar,
subnet.into(),
CheckBlockHeader::Yes,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The DataColumnSidecar is constructed in the same function internally by the node, so we just do light verification here i believe.

Copy link
Member

@jimmygchen jimmygchen left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice, this looks good, thanks @eserilev !

I've added some questions regarding if we could skip more checks, let me know what you think!

@michaelsproul we briefly talked about this before, so would be great to get your input too 🙏

@jimmygchen jimmygchen added waiting-on-author The reviewer has suggested changes and awaits thier implementation. and removed ready-for-review The code is ready for review labels Jun 4, 2025
}
ConstructedInternally::Yes => (),
};

let kzg = &chain.kzg;
let kzg_verified_data_column = verify_kzg_for_data_column(data_column.clone(), kzg)
Copy link
Member

@jimmygchen jimmygchen Jun 6, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I might be overthinking, but I'm also tempted to include observe_slashable (without changing the ordering), because it acquires a write lock, and usually data columns arrives in burst (128 simultaneously), and the write lock can only be acquired by one thread at a time, so this write could potentially slow things down even though it's a very fast operation.

    chain
        .observed_slashable
        .write()

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It might be worth writing some bench tests for gossip verification (in a later PR) - given that 1/ gossip verification time is critical to both the network and the performance of the node; 2/ the volume of verification is significantly higher now with data columns.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Created issue for benchmark #7576

@eserilev eserilev added ready-for-review The code is ready for review and removed waiting-on-author The reviewer has suggested changes and awaits thier implementation. labels Jun 9, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
das Data Availability Sampling optimization Something to make Lighthouse run more efficiently. ready-for-review The code is ready for review
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants