mirror of
https://gitlab.com/pulsechaincom/prysm-pulse.git
synced 2025-01-11 04:00:05 +00:00
379bed9268
* add heuristics for pulltips * gazelle * add unit test * fix unit test Co-authored-by: terencechain <terence@prysmaticlabs.com> Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
129 lines
4.2 KiB
Go
129 lines
4.2 KiB
Go
package protoarray
|
|
|
|
import (
|
|
"context"
|
|
|
|
"github.com/prysmaticlabs/prysm/beacon-chain/core/epoch/precompute"
|
|
forkchoicetypes "github.com/prysmaticlabs/prysm/beacon-chain/forkchoice/types"
|
|
"github.com/prysmaticlabs/prysm/beacon-chain/state"
|
|
"github.com/prysmaticlabs/prysm/config/params"
|
|
types "github.com/prysmaticlabs/prysm/consensus-types/primitives"
|
|
"github.com/prysmaticlabs/prysm/encoding/bytesutil"
|
|
ethpb "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1"
|
|
"github.com/prysmaticlabs/prysm/time/slots"
|
|
)
|
|
|
|
func (s *Store) setUnrealizedJustifiedEpoch(root [32]byte, epoch types.Epoch) error {
|
|
s.nodesLock.Lock()
|
|
defer s.nodesLock.Unlock()
|
|
index, ok := s.nodesIndices[root]
|
|
if !ok {
|
|
return ErrUnknownNodeRoot
|
|
}
|
|
if index >= uint64(len(s.nodes)) {
|
|
return errInvalidNodeIndex
|
|
}
|
|
node := s.nodes[index]
|
|
if node == nil {
|
|
return errInvalidNodeIndex
|
|
}
|
|
if epoch < node.unrealizedJustifiedEpoch {
|
|
return errInvalidUnrealizedJustifiedEpoch
|
|
}
|
|
node.unrealizedJustifiedEpoch = epoch
|
|
return nil
|
|
}
|
|
|
|
func (s *Store) setUnrealizedFinalizedEpoch(root [32]byte, epoch types.Epoch) error {
|
|
s.nodesLock.Lock()
|
|
defer s.nodesLock.Unlock()
|
|
index, ok := s.nodesIndices[root]
|
|
if !ok {
|
|
return ErrUnknownNodeRoot
|
|
}
|
|
if index >= uint64(len(s.nodes)) {
|
|
return errInvalidNodeIndex
|
|
}
|
|
node := s.nodes[index]
|
|
if node == nil {
|
|
return errInvalidNodeIndex
|
|
}
|
|
if epoch < node.unrealizedFinalizedEpoch {
|
|
return errInvalidUnrealizedFinalizedEpoch
|
|
}
|
|
node.unrealizedFinalizedEpoch = epoch
|
|
return nil
|
|
}
|
|
|
|
// UpdateUnrealizedCheckpoints "realizes" the unrealized justified and finalized
|
|
// epochs stored within nodes. It should be called at the beginning of each
|
|
// epoch
|
|
func (f *ForkChoice) UpdateUnrealizedCheckpoints() {
|
|
f.store.nodesLock.Lock()
|
|
defer f.store.nodesLock.Unlock()
|
|
for _, node := range f.store.nodes {
|
|
node.justifiedEpoch = node.unrealizedJustifiedEpoch
|
|
node.finalizedEpoch = node.unrealizedFinalizedEpoch
|
|
if node.justifiedEpoch > f.store.justifiedCheckpoint.Epoch {
|
|
if node.justifiedEpoch > f.store.bestJustifiedCheckpoint.Epoch {
|
|
f.store.bestJustifiedCheckpoint = f.store.unrealizedJustifiedCheckpoint
|
|
}
|
|
f.store.justifiedCheckpoint = f.store.unrealizedJustifiedCheckpoint
|
|
}
|
|
if node.finalizedEpoch > f.store.finalizedCheckpoint.Epoch {
|
|
f.store.justifiedCheckpoint = f.store.unrealizedJustifiedCheckpoint
|
|
f.store.finalizedCheckpoint = f.store.unrealizedFinalizedCheckpoint
|
|
}
|
|
}
|
|
}
|
|
|
|
func (s *Store) pullTips(ctx context.Context, state state.BeaconState, node *Node, jc, fc *ethpb.Checkpoint) (*ethpb.Checkpoint, *ethpb.Checkpoint) {
|
|
var uj, uf *ethpb.Checkpoint
|
|
|
|
currentSlot := slots.CurrentSlot(s.genesisTime)
|
|
currentEpoch := slots.ToEpoch(currentSlot)
|
|
stateSlot := state.Slot()
|
|
stateEpoch := slots.ToEpoch(stateSlot)
|
|
if node.parent == NonExistentNode {
|
|
return jc, fc
|
|
}
|
|
parent := s.nodes[node.parent]
|
|
currJustified := parent.unrealizedJustifiedEpoch == currentEpoch
|
|
prevJustified := parent.unrealizedJustifiedEpoch+1 == currentEpoch
|
|
tooEarlyForCurr := slots.SinceEpochStarts(stateSlot)*3 < params.BeaconConfig().SlotsPerEpoch*2
|
|
if currJustified || (stateEpoch == currentEpoch && prevJustified && tooEarlyForCurr) {
|
|
node.unrealizedJustifiedEpoch = parent.unrealizedJustifiedEpoch
|
|
node.unrealizedFinalizedEpoch = parent.unrealizedFinalizedEpoch
|
|
return jc, fc
|
|
}
|
|
|
|
uj, uf, err := precompute.UnrealizedCheckpoints(ctx, state)
|
|
if err != nil {
|
|
log.WithError(err).Debug("could not compute unrealized checkpoints")
|
|
uj, uf = jc, fc
|
|
}
|
|
node.unrealizedJustifiedEpoch, node.unrealizedFinalizedEpoch = uj.Epoch, uf.Epoch
|
|
s.checkpointsLock.Lock()
|
|
if uj.Epoch > s.unrealizedJustifiedCheckpoint.Epoch {
|
|
s.unrealizedJustifiedCheckpoint = &forkchoicetypes.Checkpoint{
|
|
Epoch: uj.Epoch, Root: bytesutil.ToBytes32(uj.Root),
|
|
}
|
|
}
|
|
if uf.Epoch > s.unrealizedFinalizedCheckpoint.Epoch {
|
|
s.unrealizedJustifiedCheckpoint = &forkchoicetypes.Checkpoint{
|
|
Epoch: uj.Epoch, Root: bytesutil.ToBytes32(uj.Root),
|
|
}
|
|
s.unrealizedFinalizedCheckpoint = &forkchoicetypes.Checkpoint{
|
|
Epoch: uf.Epoch, Root: bytesutil.ToBytes32(uf.Root),
|
|
}
|
|
}
|
|
|
|
if stateEpoch < currentEpoch {
|
|
jc, fc = uj, uf
|
|
node.justifiedEpoch = uj.Epoch
|
|
node.finalizedEpoch = uf.Epoch
|
|
}
|
|
s.checkpointsLock.Unlock()
|
|
return jc, fc
|
|
}
|