mirror of
https://gitlab.com/pulsechaincom/prysm-pulse.git
synced 2025-01-19 00:04:12 +00:00
0e043d55b4
* Use VerifiedROBlobs in initial-sync * Update beacon-chain/das/cache.go Co-authored-by: Justin Traglia <95511699+jtraglia@users.noreply.github.com> * Apply suggestions from code review comment fixes Co-authored-by: Justin Traglia <95511699+jtraglia@users.noreply.github.com> * fix lint error from gh web ui * deepsource fixes * more deepsource * fix init wiring * mark blobless blocks verified in batch mode * move sig check after parent checks * validate block commitment length at start of da check * remove vestigial locking * rm more copy-locksta * rm old comment * fail the entire batch if any sidecar fails * lint * skip redundant checks, fix len check * assume sig and proposer checks passed for block * inherits most checks from processed block * Assume block processing handles most checks * lint * cleanup unused call and gaz * more detailed logging for e2e * fix bad refactor breaking non-finalized init-sync * self-review cleanup * gaz * Update beacon-chain/verification/blob.go Co-authored-by: Justin Traglia <95511699+jtraglia@users.noreply.github.com> * terence and justin feedback --------- Co-authored-by: Kasey Kirkham <kasey@users.noreply.github.com> Co-authored-by: Justin Traglia <95511699+jtraglia@users.noreply.github.com>
100 lines
3.9 KiB
Go
100 lines
3.9 KiB
Go
package initialsync
|
|
|
|
import (
|
|
"context"
|
|
|
|
"github.com/pkg/errors"
|
|
"github.com/prysmaticlabs/prysm/v4/beacon-chain/blockchain/kzg"
|
|
"github.com/prysmaticlabs/prysm/v4/beacon-chain/das"
|
|
"github.com/prysmaticlabs/prysm/v4/beacon-chain/verification"
|
|
"github.com/prysmaticlabs/prysm/v4/consensus-types/blocks"
|
|
"github.com/prysmaticlabs/prysm/v4/encoding/bytesutil"
|
|
)
|
|
|
|
var (
|
|
// ErrBatchSignatureMismatch is returned by VerifiedROBlobs when any of the blobs in the batch have a signature
|
|
// which does not match the signature for the block with a corresponding root.
|
|
ErrBatchSignatureMismatch = errors.New("Sidecar block header signature does not match signed block")
|
|
// ErrBlockRootMismatch is returned by VerifiedROBlobs in the scenario where the root of the given signed block
|
|
// does not match the block header in one of the corresponding sidecars.
|
|
ErrBatchBlockRootMismatch = errors.New("Sidecar block header root does not match signed block")
|
|
)
|
|
|
|
func newBlobVerifierFromInitializer(ini *verification.Initializer) verification.NewBlobVerifier {
|
|
return func(b blocks.ROBlob, reqs []verification.Requirement) verification.BlobVerifier {
|
|
return ini.NewBlobVerifier(b, reqs)
|
|
}
|
|
}
|
|
|
|
func newBlobBatchVerifier(newVerifier verification.NewBlobVerifier) *BlobBatchVerifier {
|
|
return &BlobBatchVerifier{
|
|
verifyKzg: kzg.Verify,
|
|
newVerifier: newVerifier,
|
|
}
|
|
}
|
|
|
|
type kzgVerifier func(b ...blocks.ROBlob) error
|
|
|
|
// BlobBatchVerifier solves problems that come from verifying batches of blobs from RPC.
|
|
// First: we only update forkchoice after the entire batch has completed, so the n+1 elements in the batch
|
|
// won't be in forkchoice yet.
|
|
// Second: it is more efficient to batch some verifications, like kzg commitment verification. Batch adds a
|
|
// method to BlobVerifier to verify the kzg commitments of all blob sidecars for a block together, then using the cached
|
|
// result of the batch verification when verifying the individual blobs.
|
|
type BlobBatchVerifier struct {
|
|
verifyKzg kzgVerifier
|
|
newVerifier verification.NewBlobVerifier
|
|
}
|
|
|
|
var _ das.BlobBatchVerifier = &BlobBatchVerifier{}
|
|
|
|
func (batch *BlobBatchVerifier) VerifiedROBlobs(ctx context.Context, blk blocks.ROBlock, scs []blocks.ROBlob) ([]blocks.VerifiedROBlob, error) {
|
|
if len(scs) == 0 {
|
|
return nil, nil
|
|
}
|
|
// We assume the proposer was validated wrt the block in batch block processing before performing the DA check.
|
|
|
|
// So at this stage we just need to make sure the value being signed and signature bytes match the block.
|
|
for i := range scs {
|
|
if blk.Signature() != bytesutil.ToBytes96(scs[i].SignedBlockHeader.Signature) {
|
|
return nil, ErrBatchSignatureMismatch
|
|
}
|
|
// Extra defensive check to make sure the roots match. This should be unnecessary in practice since the root from
|
|
// the block should be used as the lookup key into the cache of sidecars.
|
|
if blk.Root() != scs[i].BlockRoot() {
|
|
return nil, ErrBatchBlockRootMismatch
|
|
}
|
|
}
|
|
// Verify commitments for all blobs at once. verifyOneBlob assumes it is only called once this check succeeds.
|
|
if err := batch.verifyKzg(scs...); err != nil {
|
|
return nil, err
|
|
}
|
|
vs := make([]blocks.VerifiedROBlob, len(scs))
|
|
for i := range scs {
|
|
vb, err := batch.verifyOneBlob(ctx, scs[i])
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
vs[i] = vb
|
|
}
|
|
return vs, nil
|
|
}
|
|
|
|
func (batch *BlobBatchVerifier) verifyOneBlob(ctx context.Context, sc blocks.ROBlob) (blocks.VerifiedROBlob, error) {
|
|
vb := blocks.VerifiedROBlob{}
|
|
bv := batch.newVerifier(sc, verification.InitsyncSidecarRequirements)
|
|
// We can satisfy the following 2 requirements immediately because VerifiedROBlobs always verifies commitments
|
|
// and block signature for all blobs in the batch before calling verifyOneBlob.
|
|
bv.SatisfyRequirement(verification.RequireSidecarKzgProofVerified)
|
|
bv.SatisfyRequirement(verification.RequireValidProposerSignature)
|
|
|
|
if err := bv.BlobIndexInBounds(); err != nil {
|
|
return vb, err
|
|
}
|
|
if err := bv.SidecarInclusionProven(); err != nil {
|
|
return vb, err
|
|
}
|
|
|
|
return bv.VerifiedROBlob()
|
|
}
|