mirror of
https://gitlab.com/pulsechaincom/prysm-pulse.git
synced 2025-01-03 08:37:37 +00:00
track target in forkchoice (#13249)
This commit is contained in:
parent
59aa978223
commit
cf8e554981
@ -637,3 +637,15 @@ func (f *ForkChoice) Slot(root [32]byte) (primitives.Slot, error) {
|
||||
}
|
||||
return n.slot, nil
|
||||
}
|
||||
|
||||
// TargetRoot returns the root of the checkpoint block for the given head root
|
||||
func (f *ForkChoice) TargetRoot(root [32]byte) ([32]byte, error) {
|
||||
n, ok := f.store.nodeByRoot[root]
|
||||
if !ok || n == nil {
|
||||
return [32]byte{}, ErrNilNode
|
||||
}
|
||||
if n.target == nil {
|
||||
return [32]byte{}, nil
|
||||
}
|
||||
return n.target.root, nil
|
||||
}
|
||||
|
@ -75,7 +75,6 @@ func (s *Store) insert(ctx context.Context,
|
||||
}
|
||||
|
||||
parent := s.nodeByRoot[parentRoot]
|
||||
|
||||
n := &Node{
|
||||
slot: slot,
|
||||
root: root,
|
||||
@ -89,6 +88,17 @@ func (s *Store) insert(ctx context.Context,
|
||||
timestamp: uint64(time.Now().Unix()),
|
||||
}
|
||||
|
||||
// Set the node's target checkpoint
|
||||
if slot%params.BeaconConfig().SlotsPerEpoch == 0 {
|
||||
n.target = n
|
||||
} else if parent != nil {
|
||||
if slots.ToEpoch(slot) == slots.ToEpoch(parent.slot) {
|
||||
n.target = parent.target
|
||||
} else {
|
||||
n.target = parent
|
||||
}
|
||||
}
|
||||
|
||||
s.nodeByPayload[payloadHash] = n
|
||||
s.nodeByRoot[root] = n
|
||||
if parent == nil {
|
||||
@ -145,6 +155,9 @@ func (s *Store) pruneFinalizedNodeByRootMap(ctx context.Context, node, finalized
|
||||
return ctx.Err()
|
||||
}
|
||||
if node == finalizedNode {
|
||||
if node.target != node {
|
||||
node.target = nil
|
||||
}
|
||||
return nil
|
||||
}
|
||||
for _, child := range node.children {
|
||||
|
@ -435,3 +435,69 @@ func TestForkChoice_ReceivedBlocksLastEpoch(t *testing.T) {
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, uint64(0), count)
|
||||
}
|
||||
|
||||
func TestStore_Target(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
f := setup(1, 1)
|
||||
|
||||
state, blkRoot, err := prepareForkchoiceState(ctx, params.BeaconConfig().SlotsPerEpoch, [32]byte{'a'}, params.BeaconConfig().ZeroHash, params.BeaconConfig().ZeroHash, 1, 1)
|
||||
require.NoError(t, err)
|
||||
require.NoError(t, f.InsertNode(ctx, state, blkRoot))
|
||||
target, err := f.TargetRoot(blkRoot)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, target, blkRoot)
|
||||
|
||||
state, root1, err := prepareForkchoiceState(ctx, params.BeaconConfig().SlotsPerEpoch+1, [32]byte{'b'}, blkRoot, params.BeaconConfig().ZeroHash, 1, 1)
|
||||
require.NoError(t, err)
|
||||
require.NoError(t, f.InsertNode(ctx, state, root1))
|
||||
target, err = f.TargetRoot(root1)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, target, blkRoot)
|
||||
|
||||
// Insert a block for the next epoch (missed slot 0)
|
||||
|
||||
state, root2, err := prepareForkchoiceState(ctx, 2*params.BeaconConfig().SlotsPerEpoch+1, [32]byte{'c'}, root1, params.BeaconConfig().ZeroHash, 1, 1)
|
||||
require.NoError(t, err)
|
||||
require.NoError(t, f.InsertNode(ctx, state, root2))
|
||||
target, err = f.TargetRoot(root2)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, target, root1)
|
||||
|
||||
state, root3, err := prepareForkchoiceState(ctx, 2*params.BeaconConfig().SlotsPerEpoch+2, [32]byte{'d'}, root2, params.BeaconConfig().ZeroHash, 1, 1)
|
||||
require.NoError(t, err)
|
||||
require.NoError(t, f.InsertNode(ctx, state, root3))
|
||||
target, err = f.TargetRoot(root2)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, target, root1)
|
||||
|
||||
// Prune finalization
|
||||
s := f.store
|
||||
s.finalizedCheckpoint.Root = root1
|
||||
require.NoError(t, s.prune(ctx))
|
||||
target, err = f.TargetRoot(root1)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, [32]byte{}, target)
|
||||
|
||||
// Insert a block for next epoch (slot 0 present)
|
||||
|
||||
state, root4, err := prepareForkchoiceState(ctx, 3*params.BeaconConfig().SlotsPerEpoch, [32]byte{'e'}, root1, params.BeaconConfig().ZeroHash, 1, 1)
|
||||
require.NoError(t, err)
|
||||
require.NoError(t, f.InsertNode(ctx, state, root4))
|
||||
target, err = f.TargetRoot(root4)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, target, root4)
|
||||
|
||||
state, root5, err := prepareForkchoiceState(ctx, 3*params.BeaconConfig().SlotsPerEpoch+1, [32]byte{'f'}, root4, params.BeaconConfig().ZeroHash, 1, 1)
|
||||
require.NoError(t, err)
|
||||
require.NoError(t, f.InsertNode(ctx, state, root5))
|
||||
target, err = f.TargetRoot(root5)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, target, root4)
|
||||
|
||||
// Prune finalization
|
||||
s.finalizedCheckpoint.Root = root4
|
||||
require.NoError(t, s.prune(ctx))
|
||||
target, err = f.TargetRoot(root4)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, root4, target)
|
||||
}
|
||||
|
@ -50,6 +50,7 @@ type Node struct {
|
||||
root [fieldparams.RootLength]byte // root of the block converted to the node.
|
||||
payloadHash [fieldparams.RootLength]byte // payloadHash of the block converted to the node.
|
||||
parent *Node // parent index of this node.
|
||||
target *Node // target checkpoint for
|
||||
children []*Node // the list of direct children of this Node
|
||||
justifiedEpoch primitives.Epoch // justifiedEpoch of this node.
|
||||
unrealizedJustifiedEpoch primitives.Epoch // the epoch that would be justified if the block would be advanced to the next epoch.
|
||||
|
@ -69,6 +69,7 @@ type Getter interface {
|
||||
ShouldOverrideFCU() bool
|
||||
Slot([32]byte) (primitives.Slot, error)
|
||||
LastRoot(primitives.Epoch) [32]byte
|
||||
TargetRoot([32]byte) ([32]byte, error)
|
||||
}
|
||||
|
||||
// Setter allows to set forkchoice information
|
||||
|
Loading…
Reference in New Issue
Block a user