verification

package
v5.0.1-rc.3 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Mar 6, 2024 License: GPL-3.0 Imports: 25 Imported by: 0

Documentation

Index

Constants

View Source
const (
	DefaultSignatureCacheSize = 256
)

Variables

View Source
var (
	ErrBlobInvalid = errors.New("blob failed verification")
	// ErrBlobIndexInvalid means RequireBlobIndexInBounds failed.
	ErrBlobIndexInvalid = errors.Wrap(ErrBlobInvalid, "incorrect blob sidecar index")
	// ErrFromFutureSlot means RequireSlotNotTooEarly failed.
	ErrFromFutureSlot = errors.Wrap(ErrBlobInvalid, "slot is too far in the future")
	// ErrSlotNotAfterFinalized means RequireSlotAboveFinalized failed.
	ErrSlotNotAfterFinalized = errors.Wrap(ErrBlobInvalid, "slot <= finalized checkpoint")
	// ErrInvalidProposerSignature means RequireValidProposerSignature failed.
	ErrInvalidProposerSignature = errors.Wrap(ErrBlobInvalid, "proposer signature could not be verified")
	// ErrSidecarParentNotSeen means RequireSidecarParentSeen failed.
	ErrSidecarParentNotSeen = errors.Wrap(ErrBlobInvalid, "parent root has not been seen")
	// ErrSidecarParentInvalid means RequireSidecarParentValid failed.
	ErrSidecarParentInvalid = errors.Wrap(ErrBlobInvalid, "parent block is not valid")
	// ErrSlotNotAfterParent means RequireSidecarParentSlotLower failed.
	ErrSlotNotAfterParent = errors.Wrap(ErrBlobInvalid, "slot <= slot")
	// ErrSidecarNotFinalizedDescendent means RequireSidecarDescendsFromFinalized failed.
	ErrSidecarNotFinalizedDescendent = errors.Wrap(ErrBlobInvalid, "blob parent is not descended from the finalized block")
	// ErrSidecarInclusionProofInvalid means RequireSidecarInclusionProven failed.
	ErrSidecarInclusionProofInvalid = errors.Wrap(ErrBlobInvalid, "sidecar inclusion proof verification failed")
	// ErrSidecarKzgProofInvalid means RequireSidecarKzgProofVerified failed.
	ErrSidecarKzgProofInvalid = errors.Wrap(ErrBlobInvalid, "sidecar kzg commitment proof verification failed")
	// ErrSidecarUnexpectedProposer means RequireSidecarProposerExpected failed.
	ErrSidecarUnexpectedProposer = errors.Wrap(ErrBlobInvalid, "sidecar was not proposed by the expected proposer_index")
)
View Source
var BackfillSidecarRequirements = InitsyncSidecarRequirements

BackfillSidecarRequirements is the same as InitsyncSidecarRequirements

View Source
var ErrMissingVerification = errors.New("verification was not performed for requirement")

ErrMissingVerification indicates that the given verification function was never performed on the value.

GossipSidecarRequirements defines the set of requirements that BlobSidecars received on gossip must satisfy in order to upgrade an ROBlob to a VerifiedROBlob.

InitsyncSidecarRequirements is the list of verification requirements to be used by the init-sync service for batch-mode syncing. Because we only perform batch verification as part of the IsDataAvailable method for blobs after the block has been verified, and the blobs to be verified are keyed in the cache by the block root, it is safe to skip the following verifications. RequireSidecarProposerExpected RequireNotFromFutureSlot, RequireSlotAboveFinalized, RequireSidecarParentSeen, RequireSidecarParentValid, RequireSidecarParentSlotLower, RequireSidecarDescendsFromFinalized,

Functions

func BlobSidecarNoop

func BlobSidecarNoop(b blocks.ROBlob) (blocks.VerifiedROBlob, error)

BlobSidecarNoop is a FAKE verification function that simply launders a ROBlob->VerifiedROBlob. TODO: find all code that uses this method and replace it with full verification.

func BlobSidecarSliceNoop

func BlobSidecarSliceNoop(b []blocks.ROBlob) ([]blocks.VerifiedROBlob, error)

BlobSidecarSliceNoop is a FAKE verification function that simply launders a ROBlob->VerifiedROBlob. TODO: find all code that uses this method and replace it with full verification.

func FakeVerifyForTest

func FakeVerifyForTest(t *testing.T, b blocks.ROBlob) blocks.VerifiedROBlob

FakeVerifyForTest can be used by tests that need a VerifiedROBlob but don't want to do all the expensive set up to perform full validation.

func FakeVerifySliceForTest

func FakeVerifySliceForTest(t *testing.T, b []blocks.ROBlob) []blocks.VerifiedROBlob

FakeVerifySliceForTest can be used by tests that need a []VerifiedROBlob but don't want to do all the expensive set up to perform full validation.

Types

type BlobVerifier

type BlobVerifier interface {
	VerifiedROBlob() (blocks.VerifiedROBlob, error)
	BlobIndexInBounds() (err error)
	NotFromFutureSlot() (err error)
	SlotAboveFinalized() (err error)
	ValidProposerSignature(ctx context.Context) (err error)
	SidecarParentSeen(parentSeen func([32]byte) bool) (err error)
	SidecarParentValid(badParent func([32]byte) bool) (err error)
	SidecarParentSlotLower() (err error)
	SidecarDescendsFromFinalized() (err error)
	SidecarInclusionProven() (err error)
	SidecarKzgProofVerified() (err error)
	SidecarProposerExpected(ctx context.Context) (err error)
	SatisfyRequirement(Requirement)
}

BlobVerifier defines the methods implemented by the ROBlobVerifier. It is mainly intended to make mocks and tests more straightforward, and to deal with the awkwardness of mocking a concrete type that returns a concrete type in tests outside of this package.

type Forkchoicer

type Forkchoicer interface {
	FinalizedCheckpoint() *forkchoicetypes.Checkpoint
	HasNode([32]byte) bool
	IsCanonical(root [32]byte) bool
	Slot([32]byte) (primitives.Slot, error)
	TargetRootForEpoch([32]byte, primitives.Epoch) ([32]byte, error)
}

Forkchoicer represents the forkchoice methods that the verifiers need. Note that forkchoice is used here in a lock-free fashion, assuming that a version of forkchoice is given that internally handles the details of locking the underlying store.

type Initializer

type Initializer struct {
	// contains filtered or unexported fields
}

Initializer is used to create different Verifiers. Verifiers require access to stateful data structures, like caches, and it is Initializer's job to provide access to those.

func (*Initializer) NewBlobVerifier

func (ini *Initializer) NewBlobVerifier(b blocks.ROBlob, reqs []Requirement) *ROBlobVerifier

NewBlobVerifier creates a BlobVerifier for a single blob, with the given set of requirements.

type InitializerWaiter

type InitializerWaiter struct {
	sync.RWMutex
	// contains filtered or unexported fields
}

InitializerWaiter provides an Initializer once all dependent resources are ready via the WaitForInitializer method.

func NewInitializerWaiter

func NewInitializerWaiter(cw startup.ClockWaiter, fc Forkchoicer, sr StateByRooter) *InitializerWaiter

NewInitializerWaiter creates an InitializerWaiter which can be used to obtain an Initializer once async dependencies are ready.

func (*InitializerWaiter) WaitForInitializer

func (w *InitializerWaiter) WaitForInitializer(ctx context.Context) (*Initializer, error)

WaitForInitializer ensures that asynchronous initialization of the shared resources the initializer depends on has completed before the underlying Initializer is accessible by client code.

type MockBlobVerifier

type MockBlobVerifier struct {
	ErrBlobIndexInBounds            error
	ErrSlotTooEarly                 error
	ErrSlotAboveFinalized           error
	ErrValidProposerSignature       error
	ErrSidecarParentSeen            error
	ErrSidecarParentValid           error
	ErrSidecarParentSlotLower       error
	ErrSidecarDescendsFromFinalized error
	ErrSidecarInclusionProven       error
	ErrSidecarKzgProofVerified      error
	ErrSidecarProposerExpected      error
	// contains filtered or unexported fields
}

func (*MockBlobVerifier) BlobIndexInBounds

func (m *MockBlobVerifier) BlobIndexInBounds() (err error)

func (*MockBlobVerifier) NotFromFutureSlot

func (m *MockBlobVerifier) NotFromFutureSlot() (err error)

func (*MockBlobVerifier) SatisfyRequirement

func (*MockBlobVerifier) SatisfyRequirement(_ Requirement)

func (*MockBlobVerifier) SidecarDescendsFromFinalized

func (m *MockBlobVerifier) SidecarDescendsFromFinalized() (err error)

func (*MockBlobVerifier) SidecarInclusionProven

func (m *MockBlobVerifier) SidecarInclusionProven() (err error)

func (*MockBlobVerifier) SidecarKzgProofVerified

func (m *MockBlobVerifier) SidecarKzgProofVerified() (err error)

func (*MockBlobVerifier) SidecarParentSeen

func (m *MockBlobVerifier) SidecarParentSeen(_ func([32]byte) bool) (err error)

func (*MockBlobVerifier) SidecarParentSlotLower

func (m *MockBlobVerifier) SidecarParentSlotLower() (err error)

func (*MockBlobVerifier) SidecarParentValid

func (m *MockBlobVerifier) SidecarParentValid(_ func([32]byte) bool) (err error)

func (*MockBlobVerifier) SidecarProposerExpected

func (m *MockBlobVerifier) SidecarProposerExpected(_ context.Context) (err error)

func (*MockBlobVerifier) SlotAboveFinalized

func (m *MockBlobVerifier) SlotAboveFinalized() (err error)

func (*MockBlobVerifier) ValidProposerSignature

func (m *MockBlobVerifier) ValidProposerSignature(_ context.Context) (err error)

func (*MockBlobVerifier) VerifiedROBlob

func (m *MockBlobVerifier) VerifiedROBlob() (blocks.VerifiedROBlob, error)

type NewBlobVerifier

type NewBlobVerifier func(b blocks.ROBlob, reqs []Requirement) BlobVerifier

NewBlobVerifier is a function signature that can be used by code that needs to be able to mock Initializer.NewBlobVerifier without complex setup.

type ProposerCache

type ProposerCache interface {
	ComputeProposer(ctx context.Context, root [32]byte, slot primitives.Slot, pst state.BeaconState) (primitives.ValidatorIndex, error)
	Proposer(c *forkchoicetypes.Checkpoint, slot primitives.Slot) (primitives.ValidatorIndex, bool)
}

ProposerCache represents a type that can compute the proposer for a given slot + parent root, and cache the result so that it can be reused when the same verification needs to be performed across multiple values.

type ROBlobVerifier

type ROBlobVerifier struct {
	// contains filtered or unexported fields
}

func (*ROBlobVerifier) BlobIndexInBounds

func (bv *ROBlobVerifier) BlobIndexInBounds() (err error)

BlobIndexInBounds represents the follow spec verification: [REJECT] The sidecar's index is consistent with MAX_BLOBS_PER_BLOCK -- i.e. blob_sidecar.index < MAX_BLOBS_PER_BLOCK.

func (*ROBlobVerifier) NotFromFutureSlot

func (bv *ROBlobVerifier) NotFromFutureSlot() (err error)

NotFromFutureSlot represents the spec verification: [IGNORE] The sidecar is not from a future slot (with a MAXIMUM_GOSSIP_CLOCK_DISPARITY allowance) -- i.e. validate that block_header.slot <= current_slot

func (*ROBlobVerifier) SatisfyRequirement

func (bv *ROBlobVerifier) SatisfyRequirement(req Requirement)

SatisfyRequirement allows the caller to assert that a requirement has been satisfied. This gives us a way to tick the box for a requirement where the usual method would be impractical. For example, when batch syncing, forkchoice is only updated at the end of the batch. So the checks that use forkchoice, like descends from finalized or parent seen, would necessarily fail. Allowing the caller to assert the requirement has been satisfied ensures we have an easy way to audit which piece of code is satisfying a requireent outside of this package.

func (*ROBlobVerifier) SidecarDescendsFromFinalized

func (bv *ROBlobVerifier) SidecarDescendsFromFinalized() (err error)

SidecarDescendsFromFinalized represents the spec verification: [REJECT] The current finalized_checkpoint is an ancestor of the sidecar's block -- i.e. get_checkpoint_block(store, block_header.parent_root, store.finalized_checkpoint.epoch) == store.finalized_checkpoint.root.

func (*ROBlobVerifier) SidecarInclusionProven

func (bv *ROBlobVerifier) SidecarInclusionProven() (err error)

SidecarInclusionProven represents the spec verification: [REJECT] The sidecar's inclusion proof is valid as verified by verify_blob_sidecar_inclusion_proof(blob_sidecar).

func (*ROBlobVerifier) SidecarKzgProofVerified

func (bv *ROBlobVerifier) SidecarKzgProofVerified() (err error)

SidecarKzgProofVerified represents the spec verification: [REJECT] The sidecar's blob is valid as verified by verify_blob_kzg_proof(blob_sidecar.blob, blob_sidecar.kzg_commitment, blob_sidecar.kzg_proof).

func (*ROBlobVerifier) SidecarParentSeen

func (bv *ROBlobVerifier) SidecarParentSeen(parentSeen func([32]byte) bool) (err error)

SidecarParentSeen represents the spec verification: [IGNORE] The sidecar's block's parent (defined by block_header.parent_root) has been seen (via both gossip and non-gossip sources) (a client MAY queue sidecars for processing once the parent block is retrieved).

func (*ROBlobVerifier) SidecarParentSlotLower

func (bv *ROBlobVerifier) SidecarParentSlotLower() (err error)

SidecarParentSlotLower represents the spec verification: [REJECT] The sidecar is from a higher slot than the sidecar's block's parent (defined by block_header.parent_root).

func (*ROBlobVerifier) SidecarParentValid

func (bv *ROBlobVerifier) SidecarParentValid(badParent func([32]byte) bool) (err error)

SidecarParentValid represents the spec verification: [REJECT] The sidecar's block's parent (defined by block_header.parent_root) passes validation.

func (*ROBlobVerifier) SidecarProposerExpected

func (bv *ROBlobVerifier) SidecarProposerExpected(ctx context.Context) (err error)

SidecarProposerExpected represents the spec verification: [REJECT] The sidecar is proposed by the expected proposer_index for the block's slot in the context of the current shuffling (defined by block_header.parent_root/block_header.slot). If the proposer_index cannot immediately be verified against the expected shuffling, the sidecar MAY be queued for later processing while proposers for the block's branch are calculated -- in such a case do not REJECT, instead IGNORE this message.

func (*ROBlobVerifier) SlotAboveFinalized

func (bv *ROBlobVerifier) SlotAboveFinalized() (err error)

SlotAboveFinalized represents the spec verification: [IGNORE] The sidecar is from a slot greater than the latest finalized slot -- i.e. validate that block_header.slot > compute_start_slot_at_epoch(state.finalized_checkpoint.epoch)

func (*ROBlobVerifier) ValidProposerSignature

func (bv *ROBlobVerifier) ValidProposerSignature(ctx context.Context) (err error)

ValidProposerSignature represents the spec verification: [REJECT] The proposer signature of blob_sidecar.signed_block_header, is valid with respect to the block_header.proposer_index pubkey.

func (*ROBlobVerifier) VerifiedROBlob

func (bv *ROBlobVerifier) VerifiedROBlob() (blocks.VerifiedROBlob, error)

VerifiedROBlob "upgrades" the wrapped ROBlob to a VerifiedROBlob. If any of the verifications ran against the blob failed, or some required verifications were not run, an error will be returned.

type Requirement

type Requirement int

Requirement represents a validation check that needs to pass in order for a Verified form a consensus type to be issued.

const (
	RequireBlobIndexInBounds Requirement = iota
	RequireNotFromFutureSlot
	RequireSlotAboveFinalized
	RequireValidProposerSignature
	RequireSidecarParentSeen
	RequireSidecarParentValid
	RequireSidecarParentSlotLower
	RequireSidecarDescendsFromFinalized
	RequireSidecarInclusionProven
	RequireSidecarKzgProofVerified
	RequireSidecarProposerExpected
)

type SignatureCache

type SignatureCache interface {
	// VerifySignature perform signature verification and caches the result.
	VerifySignature(sig SignatureData, v ValidatorAtIndexer) (err error)
	// SignatureVerified accesses the result of a previous signature verification.
	SignatureVerified(sig SignatureData) (bool, error)
}

SignatureCache represents a type that can perform signature verification and cache the result so that it can be used when the same signature is seen in multiple places, like a SignedBeaconBlockHeader found in multiple BlobSidecars.

type SignatureData

type SignatureData struct {
	Root      [32]byte
	Parent    [32]byte
	Signature [96]byte
	Proposer  primitives.ValidatorIndex
	Slot      primitives.Slot
}

SignatureData represents the set of parameters that together uniquely identify a signature observed on a beacon block. This is used as the key for the signature cache.

type StateByRooter

type StateByRooter interface {
	StateByRoot(ctx context.Context, blockRoot [32]byte) (state.BeaconState, error)
}

StateByRooter describes a stategen-ish type that can produce arbitrary states by their root

type ValidatorAtIndexer

type ValidatorAtIndexer interface {
	ValidatorAtIndex(idx primitives.ValidatorIndex) (*ethpb.Validator, error)
}

ValidatorAtIndexer defines the method needed to retrieve a validator by its index. This interface is satisfied by state.BeaconState, but can also be satisfied by a cache.

type VerificationMultiError

type VerificationMultiError struct {
	// contains filtered or unexported fields
}

VerificationMultiError is a custom error that can be used to access individual verification failures.

func (VerificationMultiError) Error

func (ve VerificationMultiError) Error() string

Error satisfies the standard error interface.

func (VerificationMultiError) Failures

func (ve VerificationMultiError) Failures() map[Requirement]error

Failures provides access to map of Requirements->error messages so that calling code can introspect on what went wrong.

func (VerificationMultiError) Unwrap

func (ve VerificationMultiError) Unwrap() error

Unwrap is used by errors.Is to unwrap errors.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL