Allow requests for old target roots (#13281)

This commit is contained in:
Potuz
2023-12-06 14:11:34 -03:00
committed by GitHub
parent e1a3852f08
commit 604c82626f
2 changed files with 37 additions and 2 deletions

View File

@@ -643,16 +643,35 @@ func (f *ForkChoice) Slot(root [32]byte) (primitives.Slot, error) {
// When inserting a block at slot 63 with block root 0xA and target root 0xB (pointing to the block at slot 32),
// and at slot 64, where the block is skipped, the attestation will reference the target root as 0xA (for slot 63), not 0xB (for slot 32).
// This implies that if the input slot exceeds the block slot, the target root will be the same as the block root.
// We also allow for the epoch to be below the current target for this root, in
// which case we return the root of the checkpoint of the chain containing the
// passed root, at the given epoch
func (f *ForkChoice) TargetRootForEpoch(root [32]byte, epoch primitives.Epoch) ([32]byte, error) {
n, ok := f.store.nodeByRoot[root]
if !ok || n == nil {
return [32]byte{}, ErrNilNode
}
if epoch > slots.ToEpoch(n.slot) {
nodeEpoch := slots.ToEpoch(n.slot)
if epoch > nodeEpoch {
return n.root, nil
}
if n.target == nil {
return [32]byte{}, nil
}
return n.target.root, nil
targetRoot := n.target.root
if epoch == nodeEpoch {
return targetRoot, nil
}
targetNode, ok := f.store.nodeByRoot[targetRoot]
if !ok || targetNode == nil {
return [32]byte{}, ErrNilNode
}
// If slot 0 was not missed we consider a previous block to go back at least one epoch
if nodeEpoch == slots.ToEpoch(targetNode.slot) {
targetNode = targetNode.parent
if targetNode == nil {
return [32]byte{}, ErrNilNode
}
}
return f.TargetRootForEpoch(targetNode.root, epoch)
}

View File

@@ -499,6 +499,22 @@ func TestStore_TargetRootForEpoch(t *testing.T) {
require.NoError(t, err)
require.Equal(t, target, root5)
// Target root where the target epoch is two epochs ago
target, err = f.TargetRootForEpoch(root5, 2)
require.NoError(t, err)
require.Equal(t, root1, target) // the parent of root4 in epoch 3 is root 1 in epoch 1
// Target root where the target is two epochs ago, slot 0 was missed
state, root6, err := prepareForkchoiceState(ctx, 4*params.BeaconConfig().SlotsPerEpoch+1, [32]byte{'g'}, root5, params.BeaconConfig().ZeroHash, 1, 1)
require.NoError(t, err)
require.NoError(t, f.InsertNode(ctx, state, root6))
target, err = f.TargetRootForEpoch(root6, 4)
require.NoError(t, err)
require.Equal(t, target, root5)
target, err = f.TargetRootForEpoch(root6, 2)
require.NoError(t, err)
require.Equal(t, target, root1)
// Prune finalization
s.finalizedCheckpoint.Root = root4
require.NoError(t, s.prune(ctx))