mirror of
https://github.com/OffchainLabs/prysm.git
synced 2026-01-07 22:54:17 -05:00
Optimize BuildBlobSidecars Merkle proof computation by pre-computing subtrees (#15473)
* Optimize BuildBlobSidecars Merkle proof computation by pre-computing subtrees Co-Authored-By: Claude <noreply@anthropic.com> * Add change log * Fix change log --------- Co-authored-by: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -25,6 +25,12 @@ var (
|
||||
errInvalidInclusionProof = errors.New("invalid KZG commitment inclusion proof")
|
||||
)
|
||||
|
||||
// MerkleProofComponents contains pre-computed components for efficient proof generation
|
||||
type MerkleProofComponents struct {
|
||||
kzgSubtree *trie.SparseMerkleTrie
|
||||
topLevelProof [][]byte
|
||||
}
|
||||
|
||||
// VerifyKZGInclusionProof verifies the Merkle proof in a Blob sidecar against
|
||||
// the beacon block body root.
|
||||
func VerifyKZGInclusionProof(blob ROBlob) error {
|
||||
@@ -80,6 +86,67 @@ func MerkleProofKZGCommitment(body interfaces.ReadOnlyBeaconBlockBody, index int
|
||||
return proof, nil
|
||||
}
|
||||
|
||||
// PrecomputeMerkleProofComponents pre-computes the expensive parts of Merkle proof generation
|
||||
// that are shared across all blob indices for a given block body.
|
||||
func PrecomputeMerkleProofComponents(body interfaces.ReadOnlyBeaconBlockBody) (*MerkleProofComponents, error) {
|
||||
bodyVersion := body.Version()
|
||||
if bodyVersion < version.Deneb {
|
||||
return nil, errUnsupportedBeaconBlockBody
|
||||
}
|
||||
|
||||
// Pre-compute KZG subtree
|
||||
commitments, err := body.BlobKzgCommitments()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// No work needed if there are no commitments
|
||||
if len(commitments) == 0 {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
leaves := LeavesFromCommitments(commitments)
|
||||
kzgSubtree, err := trie.GenerateTrieFromItems(leaves, field_params.LogMaxBlobCommitments)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Pre-compute top-level components
|
||||
membersRoots, err := topLevelRoots(body)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
topLevelTrie, err := trie.GenerateTrieFromItems(membersRoots, logBodyLength)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
topLevelProof, err := topLevelTrie.MerkleProof(kzgPosition)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// Remove the last element that is not needed in topProof
|
||||
topLevelProof = topLevelProof[:len(topLevelProof)-1]
|
||||
|
||||
return &MerkleProofComponents{
|
||||
kzgSubtree: kzgSubtree,
|
||||
topLevelProof: topLevelProof,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// MerkleProofKZGCommitmentFromComponents constructs a Merkle proof for a specific index
|
||||
// using pre-computed components, avoiding redundant calculations.
|
||||
func MerkleProofKZGCommitmentFromComponents(components *MerkleProofComponents, index int) ([][]byte, error) {
|
||||
// Generate index-specific proof from pre-computed KZG subtree
|
||||
subtreeProof, err := components.kzgSubtree.MerkleProof(index)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Combine with pre-computed top-level proof
|
||||
proof := append(subtreeProof, components.topLevelProof...)
|
||||
return proof, nil
|
||||
}
|
||||
|
||||
// MerkleProofKZGCommitments constructs a Merkle proof of inclusion of the KZG
|
||||
// commitments into the Beacon Block with the given `body`
|
||||
func MerkleProofKZGCommitments(body interfaces.ReadOnlyBeaconBlockBody) ([][]byte, error) {
|
||||
|
||||
Reference in New Issue
Block a user