mirror of
https://gitlab.com/pulsechaincom/prysm-pulse.git
synced 2024-12-23 03:51:29 +00:00
5a66807989
* First take at updating everything to v5 * Patch gRPC gateway to use prysm v5 Fix patch * Update go ssz --------- Co-authored-by: Preston Van Loon <pvanloon@offchainlabs.com>
142 lines
4.8 KiB
Go
142 lines
4.8 KiB
Go
package backfill
|
|
|
|
import (
|
|
"bytes"
|
|
"context"
|
|
|
|
"github.com/pkg/errors"
|
|
"github.com/prysmaticlabs/prysm/v5/beacon-chain/das"
|
|
"github.com/prysmaticlabs/prysm/v5/beacon-chain/db/filesystem"
|
|
"github.com/prysmaticlabs/prysm/v5/beacon-chain/verification"
|
|
fieldparams "github.com/prysmaticlabs/prysm/v5/config/fieldparams"
|
|
"github.com/prysmaticlabs/prysm/v5/consensus-types/blocks"
|
|
"github.com/prysmaticlabs/prysm/v5/consensus-types/primitives"
|
|
"github.com/prysmaticlabs/prysm/v5/encoding/bytesutil"
|
|
)
|
|
|
|
var (
|
|
errUnexpectedResponseSize = errors.New("received more blobs than expected for the requested range")
|
|
errUnexpectedCommitment = errors.New("BlobSidecar commitment does not match block")
|
|
errUnexpectedResponseContent = errors.New("BlobSidecar response does not include expected values in expected order")
|
|
errBatchVerifierMismatch = errors.New("the list of blocks passed to the availability check does not match what was verified")
|
|
)
|
|
|
|
type blobSummary struct {
|
|
blockRoot [32]byte
|
|
index uint64
|
|
commitment [48]byte
|
|
signature [fieldparams.BLSSignatureLength]byte
|
|
}
|
|
|
|
type blobSyncConfig struct {
|
|
retentionStart primitives.Slot
|
|
nbv verification.NewBlobVerifier
|
|
store *filesystem.BlobStorage
|
|
}
|
|
|
|
func newBlobSync(current primitives.Slot, vbs verifiedROBlocks, cfg *blobSyncConfig) (*blobSync, error) {
|
|
expected, err := vbs.blobIdents(cfg.retentionStart)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
bbv := newBlobBatchVerifier(cfg.nbv)
|
|
as := das.NewLazilyPersistentStore(cfg.store, bbv)
|
|
return &blobSync{current: current, expected: expected, bbv: bbv, store: as}, nil
|
|
}
|
|
|
|
type blobVerifierMap map[[32]byte][fieldparams.MaxBlobsPerBlock]verification.BlobVerifier
|
|
|
|
type blobSync struct {
|
|
store das.AvailabilityStore
|
|
expected []blobSummary
|
|
next int
|
|
bbv *blobBatchVerifier
|
|
current primitives.Slot
|
|
}
|
|
|
|
func (bs *blobSync) blobsNeeded() int {
|
|
return len(bs.expected) - bs.next
|
|
}
|
|
|
|
func (bs *blobSync) validateNext(rb blocks.ROBlob) error {
|
|
if bs.next >= len(bs.expected) {
|
|
return errUnexpectedResponseSize
|
|
}
|
|
next := bs.expected[bs.next]
|
|
bs.next += 1
|
|
// Get the super cheap verifications out of the way before we init a verifier.
|
|
if next.blockRoot != rb.BlockRoot() {
|
|
return errors.Wrapf(errUnexpectedResponseContent, "next expected root=%#x, saw=%#x", next.blockRoot, rb.BlockRoot())
|
|
}
|
|
if next.index != rb.Index {
|
|
return errors.Wrapf(errUnexpectedResponseContent, "next expected root=%#x, saw=%#x for root=%#x", next.index, rb.Index, next.blockRoot)
|
|
}
|
|
if next.commitment != bytesutil.ToBytes48(rb.KzgCommitment) {
|
|
return errors.Wrapf(errUnexpectedResponseContent, "next expected commitment=%#x, saw=%#x for root=%#x", next.commitment, rb.KzgCommitment, rb.BlockRoot())
|
|
}
|
|
|
|
if bytesutil.ToBytes96(rb.SignedBlockHeader.Signature) != next.signature {
|
|
return verification.ErrInvalidProposerSignature
|
|
}
|
|
v := bs.bbv.newVerifier(rb)
|
|
if err := v.BlobIndexInBounds(); err != nil {
|
|
return err
|
|
}
|
|
v.SatisfyRequirement(verification.RequireValidProposerSignature)
|
|
if err := v.SidecarInclusionProven(); err != nil {
|
|
return err
|
|
}
|
|
if err := v.SidecarKzgProofVerified(); err != nil {
|
|
return err
|
|
}
|
|
if err := bs.store.Persist(bs.current, rb); err != nil {
|
|
return err
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func newBlobBatchVerifier(nbv verification.NewBlobVerifier) *blobBatchVerifier {
|
|
return &blobBatchVerifier{newBlobVerifier: nbv, verifiers: make(blobVerifierMap)}
|
|
}
|
|
|
|
type blobBatchVerifier struct {
|
|
newBlobVerifier verification.NewBlobVerifier
|
|
verifiers blobVerifierMap
|
|
}
|
|
|
|
func (bbv *blobBatchVerifier) newVerifier(rb blocks.ROBlob) verification.BlobVerifier {
|
|
m := bbv.verifiers[rb.BlockRoot()]
|
|
m[rb.Index] = bbv.newBlobVerifier(rb, verification.BackfillSidecarRequirements)
|
|
bbv.verifiers[rb.BlockRoot()] = m
|
|
return m[rb.Index]
|
|
}
|
|
|
|
func (bbv blobBatchVerifier) VerifiedROBlobs(_ context.Context, blk blocks.ROBlock, _ []blocks.ROBlob) ([]blocks.VerifiedROBlob, error) {
|
|
m, ok := bbv.verifiers[blk.Root()]
|
|
if !ok {
|
|
return nil, errors.Wrapf(verification.ErrMissingVerification, "no record of verifiers for root %#x", blk.Root())
|
|
}
|
|
c, err := blk.Block().Body().BlobKzgCommitments()
|
|
if err != nil {
|
|
return nil, errors.Wrapf(errUnexpectedCommitment, "error reading commitments from block root %#x", blk.Root())
|
|
}
|
|
vbs := make([]blocks.VerifiedROBlob, len(c))
|
|
for i := range c {
|
|
if m[i] == nil {
|
|
return nil, errors.Wrapf(errBatchVerifierMismatch, "do not have verifier for block root %#x idx %d", blk.Root(), i)
|
|
}
|
|
vb, err := m[i].VerifiedROBlob()
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
if !bytes.Equal(vb.KzgCommitment, c[i]) {
|
|
return nil, errors.Wrapf(errBatchVerifierMismatch, "commitments do not match, verified=%#x da check=%#x for root %#x", vb.KzgCommitment, c[i], vb.BlockRoot())
|
|
}
|
|
vbs[i] = vb
|
|
}
|
|
return vbs, nil
|
|
}
|
|
|
|
var _ das.BlobBatchVerifier = &blobBatchVerifier{}
|