mirror of
https://gitlab.com/pulsechaincom/prysm-pulse.git
synced 2024-12-22 19:40:37 +00:00
Use advanced epoch cache when preparing proposals (#13377)
This commit is contained in:
parent
d0bf03e863
commit
e80db9554d
@ -5,15 +5,27 @@ import (
|
||||
"github.com/prysmaticlabs/prysm/v4/beacon-chain/core/helpers"
|
||||
"github.com/prysmaticlabs/prysm/v4/beacon-chain/state"
|
||||
"github.com/prysmaticlabs/prysm/v4/consensus-types/primitives"
|
||||
"github.com/prysmaticlabs/prysm/v4/time/slots"
|
||||
)
|
||||
|
||||
// trackedProposer returns whether the beacon node was informed, via the
|
||||
// validators/prepare_proposer endpoint, of the proposer at the given slot.
|
||||
// It only returns true if the tracked proposer is present and active.
|
||||
func (s *Service) trackedProposer(st state.ReadOnlyBeaconState, slot primitives.Slot) (cache.TrackedValidator, bool) {
|
||||
id, err := helpers.BeaconProposerIndexAtSlot(s.ctx, st, slot)
|
||||
if err != nil {
|
||||
return cache.TrackedValidator{}, false
|
||||
// if the head state and slot are in different epochs, try first the
|
||||
// precomputed cache one epoch in advance
|
||||
var id primitives.ValidatorIndex
|
||||
var err error
|
||||
stateEpoch := slots.ToEpoch(st.Slot())
|
||||
e := slots.ToEpoch(slot)
|
||||
if stateEpoch != e {
|
||||
id, err = helpers.UnsafeBeaconProposerIndexAtSlot(st, slot)
|
||||
}
|
||||
if err != nil || stateEpoch == e {
|
||||
id, err = helpers.BeaconProposerIndexAtSlot(s.ctx, st, slot)
|
||||
if err != nil {
|
||||
return cache.TrackedValidator{}, false
|
||||
}
|
||||
}
|
||||
val, ok := s.cfg.TrackedValidatorsCache.Validator(id)
|
||||
if !ok {
|
||||
|
@ -281,6 +281,39 @@ func cachedProposerIndexAtSlot(slot primitives.Slot, root [32]byte) (primitives.
|
||||
return proposerIndices[slot%params.BeaconConfig().SlotsPerEpoch], nil
|
||||
}
|
||||
|
||||
// cachedUnsafeProposerIndexAtSlot returns the proposer index at the given slot
|
||||
// from the unsafe cache computed in the previous epoch
|
||||
func cachedUnsafeProposerIndexAtSlot(slot primitives.Slot, root [32]byte) (primitives.ValidatorIndex, error) {
|
||||
proposerIndices, has := proposerIndicesCache.UnsafeProposerIndices(slots.ToEpoch(slot), root)
|
||||
if !has {
|
||||
cache.ProposerIndicesCacheMiss.Inc()
|
||||
return 0, errProposerIndexMiss
|
||||
}
|
||||
if len(proposerIndices) != int(params.BeaconConfig().SlotsPerEpoch) {
|
||||
cache.ProposerIndicesCacheMiss.Inc()
|
||||
return 0, errProposerIndexMiss
|
||||
}
|
||||
return proposerIndices[slot%params.BeaconConfig().SlotsPerEpoch], nil
|
||||
}
|
||||
|
||||
// UnsafeBeaconProposerIndexAtSlot returns the proposer index at the given slot
|
||||
// if it has been cached one epoch in advance
|
||||
func UnsafeBeaconProposerIndexAtSlot(state state.ReadOnlyBeaconState, slot primitives.Slot) (primitives.ValidatorIndex, error) {
|
||||
e := slots.ToEpoch(slot)
|
||||
if e < 2 {
|
||||
return 0, errProposerIndexMiss
|
||||
}
|
||||
s, err := slots.EpochEnd(e - 2)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
r, err := StateRootAtSlot(state, s)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return cachedUnsafeProposerIndexAtSlot(slot, [32]byte(r))
|
||||
}
|
||||
|
||||
// BeaconProposerIndexAtSlot returns proposer index at the given slot from the
|
||||
// point of view of the given state as head state
|
||||
func BeaconProposerIndexAtSlot(ctx context.Context, state state.ReadOnlyBeaconState, slot primitives.Slot) (primitives.ValidatorIndex, error) {
|
||||
|
@ -16,6 +16,7 @@ import (
|
||||
ethpb "github.com/prysmaticlabs/prysm/v4/proto/prysm/v1alpha1"
|
||||
"github.com/prysmaticlabs/prysm/v4/testing/assert"
|
||||
"github.com/prysmaticlabs/prysm/v4/testing/require"
|
||||
"github.com/prysmaticlabs/prysm/v4/time/slots"
|
||||
)
|
||||
|
||||
func TestIsActiveValidator_OK(t *testing.T) {
|
||||
@ -802,3 +803,26 @@ func TestLastActivatedValidatorIndex_OK(t *testing.T) {
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, index, primitives.ValidatorIndex(3))
|
||||
}
|
||||
|
||||
func TestUnsafeProposerIndexAtSlot(t *testing.T) {
|
||||
bRoot := [32]byte{'A'}
|
||||
e := 4
|
||||
slot := primitives.Slot(e) * params.BeaconConfig().SlotsPerEpoch
|
||||
indices, ok := proposerIndicesCache.UnsafeProposerIndices(primitives.Epoch(e), bRoot)
|
||||
require.Equal(t, false, ok)
|
||||
|
||||
beaconState, err := state_native.InitializeFromProtoPhase0(ðpb.BeaconState{})
|
||||
require.NoError(t, err)
|
||||
roots := make([][]byte, fieldparams.StateRootsLength)
|
||||
roots[(e-1)*int(params.BeaconConfig().SlotsPerEpoch)-1] = bRoot[:]
|
||||
id := primitives.ValidatorIndex(17)
|
||||
indices[0] = id
|
||||
require.NoError(t, beaconState.SetStateRoots(roots))
|
||||
require.NoError(t, beaconState.SetSlot(slot))
|
||||
epoch := slots.ToEpoch(slot)
|
||||
require.Equal(t, primitives.Epoch(e), epoch)
|
||||
proposerIndicesCache.SetUnsafe(epoch, bRoot, indices)
|
||||
pid, err := UnsafeBeaconProposerIndexAtSlot(beaconState, slot)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, id, pid)
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user