Documentation ¶
Index ¶
- Constants
- Variables
- func BlobSidecarNoop(b blocks.ROBlob) (blocks.VerifiedROBlob, error)
- func BlobSidecarSliceNoop(b []blocks.ROBlob) ([]blocks.VerifiedROBlob, error)
- func FakeVerifyForTest(t *testing.T, b blocks.ROBlob) blocks.VerifiedROBlob
- func FakeVerifySliceForTest(t *testing.T, b []blocks.ROBlob) []blocks.VerifiedROBlob
- type BlobBatchVerifier
- type BlobVerifier
- type Forkchoicer
- type Initializer
- type InitializerOption
- type InitializerWaiter
- type MockBlobVerifier
- func (m *MockBlobVerifier) BlobIndexInBounds() (err error)
- func (m *MockBlobVerifier) NotFromFutureSlot() (err error)
- func (*MockBlobVerifier) SatisfyRequirement(_ Requirement)
- func (m *MockBlobVerifier) SidecarDescendsFromFinalized() (err error)
- func (m *MockBlobVerifier) SidecarInclusionProven() (err error)
- func (m *MockBlobVerifier) SidecarKzgProofVerified() (err error)
- func (m *MockBlobVerifier) SidecarParentSeen(_ func([32]byte) bool) (err error)
- func (m *MockBlobVerifier) SidecarParentSlotLower() (err error)
- func (m *MockBlobVerifier) SidecarParentValid(_ func([32]byte) bool) (err error)
- func (m *MockBlobVerifier) SidecarProposerExpected(_ context.Context) (err error)
- func (m *MockBlobVerifier) SlotAboveFinalized() (err error)
- func (m *MockBlobVerifier) ValidProposerSignature(_ context.Context) (err error)
- func (m *MockBlobVerifier) VerifiedROBlob() (blocks.VerifiedROBlob, error)
- type NewBlobVerifier
- type ProposerCache
- type ROBlobVerifier
- func (bv *ROBlobVerifier) BlobIndexInBounds() (err error)
- func (bv *ROBlobVerifier) NotFromFutureSlot() (err error)
- func (bv *ROBlobVerifier) SatisfyRequirement(req Requirement)
- func (bv *ROBlobVerifier) SidecarDescendsFromFinalized() (err error)
- func (bv *ROBlobVerifier) SidecarInclusionProven() (err error)
- func (bv *ROBlobVerifier) SidecarKzgProofVerified() (err error)
- func (bv *ROBlobVerifier) SidecarParentSeen(parentSeen func([32]byte) bool) (err error)
- func (bv *ROBlobVerifier) SidecarParentSlotLower() (err error)
- func (bv *ROBlobVerifier) SidecarParentValid(badParent func([32]byte) bool) (err error)
- func (bv *ROBlobVerifier) SidecarProposerExpected(ctx context.Context) (err error)
- func (bv *ROBlobVerifier) SlotAboveFinalized() (err error)
- func (bv *ROBlobVerifier) ValidProposerSignature(ctx context.Context) (err error)
- func (bv *ROBlobVerifier) VerifiedROBlob() (blocks.VerifiedROBlob, error)
- type Requirement
- type SignatureCache
- type SignatureData
- type StateByRooter
- type ValidatorAtIndexer
- type VerificationMultiError
Constants ¶
const (
DefaultSignatureCacheSize = 256
)
Variables ¶
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") // ErrBatchBlockRootMismatch 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") )
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") )
var BackfillSidecarRequirements = requirementList(InitsyncSidecarRequirements).excluding()
BackfillSidecarRequirements is the same as InitsyncSidecarRequirements.
var ErrMissingVerification = errors.New("verification was not performed for requirement")
ErrMissingVerification indicates that the given verification function was never performed on the value.
var GossipSidecarRequirements = requirementList(allSidecarRequirements).excluding()
GossipSidecarRequirements defines the set of requirements that BlobSidecars received on gossip must satisfy in order to upgrade an ROBlob to a VerifiedROBlob.
var InitsyncSidecarRequirements = requirementList(GossipSidecarRequirements).excluding( RequireNotFromFutureSlot, RequireSlotAboveFinalized, RequireSidecarParentSeen, RequireSidecarParentValid, RequireSidecarParentSlotLower, RequireSidecarDescendsFromFinalized, RequireSidecarProposerExpected, )
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, the list of required verifications is much shorter than gossip.
var PendingQueueSidecarRequirements = requirementList(InitsyncSidecarRequirements).excluding()
PendingQueueSidecarRequirements is the same as InitsyncSidecarRequirements, used by the pending blocks queue.
var SpectestSidecarRequirements = requirementList(GossipSidecarRequirements).excluding( RequireSidecarParentSeen, RequireSidecarParentValid)
SpectestSidecarRequirements is used by the forkchoice spectests when verifying blobs used in the on_block tests. The only requirements we exclude for these tests are the parent validity and seen tests, as these are specific to gossip processing and require the bad block cache that we only use there.
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 ¶
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 ¶
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 BlobBatchVerifier ¶ added in v5.0.2
type BlobBatchVerifier struct {
// contains filtered or unexported fields
}
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.
func NewBlobBatchVerifier ¶ added in v5.0.2
func NewBlobBatchVerifier(newVerifier NewBlobVerifier, reqs []Requirement) *BlobBatchVerifier
NewBlobBatchVerifier initializes a blob batch verifier. It requires the caller to correctly specify verification Requirements and to also pass in a NewBlobVerifier, which is a callback function that returns a new BlobVerifier for handling a single blob in the batch.
func (*BlobBatchVerifier) VerifiedROBlobs ¶ added in v5.0.2
func (batch *BlobBatchVerifier) VerifiedROBlobs(ctx context.Context, blk blocks.ROBlock, scs []blocks.ROBlob) ([]blocks.VerifiedROBlob, error)
VerifiedROBlobs satisfies the das.BlobBatchVerifier interface, used by das.AvailabilityStore.
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 InitializerOption ¶ added in v5.0.2
type InitializerOption func(waiter *InitializerWaiter)
func WithForkLookup ¶ added in v5.0.2
func WithForkLookup(fl forkLookup) InitializerOption
WithForkLookup allows tests to modify how Fork consensus type lookup works. Needed for spectests with weird Forks.
type InitializerWaiter ¶
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, opts ...InitializerOption) *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 requirement 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 )
func (Requirement) String ¶ added in v5.0.2
func (r Requirement) String() string
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.