mirror of
https://gitlab.com/pulsechaincom/prysm-pulse.git
synced 2025-01-09 19:21:19 +00:00
0a87210514
* write locks * fix forkchoice tests * blockchain locks * lock on IsOptimistic * use forkchoice instead of chaininfo within savehead * Use forkchoice HasNode to check if a block is consistent with finality * interface fix * Use forkchoice HasNode to check if a block is consistent with finality * interface fix * fix tests * remove VerifyFinalizedBlkDescendant * don't write lock wrappers * fix validateBeaconBlock * Terence's review and more missing locks * add lock for InForkChoice * lock head on fillMissingBlockPayload * fix lock on IsOptimisticForRoot * fix lock in fillMissingBlockPayloadId * extra comments * lock proposerBoost on spectests * nishant's review --------- Co-authored-by: Nishant Das <nishdas93@gmail.com>
93 lines
3.3 KiB
Go
93 lines
3.3 KiB
Go
package validator
|
|
|
|
import (
|
|
"context"
|
|
|
|
"github.com/pkg/errors"
|
|
"github.com/prysmaticlabs/prysm/v3/beacon-chain/db/kv"
|
|
"github.com/prysmaticlabs/prysm/v3/config/params"
|
|
"github.com/prysmaticlabs/prysm/v3/consensus-types/primitives"
|
|
"github.com/sirupsen/logrus"
|
|
)
|
|
|
|
// Returns true if builder (ie outsourcing block construction) can be used. Both conditions have to meet:
|
|
// - Validator has registered to use builder (ie called registerBuilder API end point)
|
|
// - Circuit breaker has not been activated (ie the liveness of the chain is healthy)
|
|
func (vs *Server) canUseBuilder(ctx context.Context, slot primitives.Slot, idx primitives.ValidatorIndex) (bool, error) {
|
|
activated, err := vs.circuitBreakBuilder(slot)
|
|
if err != nil {
|
|
return false, err
|
|
}
|
|
if activated {
|
|
return false, nil
|
|
}
|
|
return vs.validatorRegistered(ctx, idx)
|
|
}
|
|
|
|
// validatorRegistered returns true if validator with index `id` was previously registered in the database.
|
|
func (vs *Server) validatorRegistered(ctx context.Context, id primitives.ValidatorIndex) (bool, error) {
|
|
if vs.BeaconDB == nil {
|
|
return false, errors.New("nil beacon db")
|
|
}
|
|
_, err := vs.BeaconDB.RegistrationByValidatorID(ctx, id)
|
|
switch {
|
|
case errors.Is(err, kv.ErrNotFoundFeeRecipient):
|
|
return false, nil
|
|
case err != nil:
|
|
return false, err
|
|
}
|
|
return true, nil
|
|
}
|
|
|
|
// circuitBreakBuilder returns true if the builder is not allowed to be used due to circuit breaker conditions.
|
|
func (vs *Server) circuitBreakBuilder(s primitives.Slot) (bool, error) {
|
|
if vs.ForkFetcher == nil || vs.ForkFetcher.ForkChoicer() == nil {
|
|
return true, errors.New("no fork choicer configured")
|
|
}
|
|
|
|
vs.ForkFetcher.ForkChoicer().RLock()
|
|
defer vs.ForkFetcher.ForkChoicer().RUnlock()
|
|
|
|
// Circuit breaker is active if the missing consecutive slots greater than `MaxBuilderConsecutiveMissedSlots`.
|
|
highestReceivedSlot := vs.ForkFetcher.ForkChoicer().HighestReceivedBlockSlot()
|
|
maxConsecutiveSkipSlotsAllowed := params.BeaconConfig().MaxBuilderConsecutiveMissedSlots
|
|
diff, err := s.SafeSubSlot(highestReceivedSlot)
|
|
if err != nil {
|
|
return true, err
|
|
}
|
|
|
|
if diff > maxConsecutiveSkipSlotsAllowed {
|
|
log.WithFields(logrus.Fields{
|
|
"currentSlot": s,
|
|
"highestReceivedSlot": highestReceivedSlot,
|
|
"maxConsecutiveSkipSlotsAllowed": maxConsecutiveSkipSlotsAllowed,
|
|
}).Warn("Circuit breaker activated due to missing consecutive slot. Ignore if mev-boost is not used")
|
|
return true, nil
|
|
}
|
|
|
|
// Not much reason to check missed slots epoch rolling window if input slot is less than epoch.
|
|
if s < params.BeaconConfig().SlotsPerEpoch {
|
|
return false, nil
|
|
}
|
|
|
|
// Circuit breaker is active if the missing slots per epoch (rolling window) greater than `MaxBuilderEpochMissedSlots`.
|
|
receivedCount, err := vs.ForkFetcher.ForkChoicer().ReceivedBlocksLastEpoch()
|
|
if err != nil {
|
|
return true, err
|
|
}
|
|
maxEpochSkipSlotsAllowed := params.BeaconConfig().MaxBuilderEpochMissedSlots
|
|
diff, err = params.BeaconConfig().SlotsPerEpoch.SafeSub(receivedCount)
|
|
if err != nil {
|
|
return true, err
|
|
}
|
|
if diff > maxEpochSkipSlotsAllowed {
|
|
log.WithFields(logrus.Fields{
|
|
"totalMissed": diff,
|
|
"maxEpochSkipSlotsAllowed": maxEpochSkipSlotsAllowed,
|
|
}).Warn("Circuit breaker activated due to missing enough slots last epoch. Ignore if mev-boost is not used")
|
|
return true, nil
|
|
}
|
|
|
|
return false, nil
|
|
}
|