Skip to content

Commit 1fb2dd1

Browse files
committed
Potuz's first round feedback
1 parent 8e3e182 commit 1fb2dd1

File tree

17 files changed

+200
-199
lines changed

17 files changed

+200
-199
lines changed

Diff for: beacon-chain/blockchain/chain_info.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ type ForkchoiceFetcher interface {
4141
Ancestor(context.Context, []byte, primitives.Slot) ([]byte, error)
4242
CachedHeadRoot() [32]byte
4343
GetProposerHead() [32]byte
44-
SafeHeadPayloadBlockHash() [32]byte
44+
SafeBlockHash() [32]byte
4545
SetForkChoiceGenesisTime(uint64)
4646
UpdateHead(context.Context, primitives.Slot)
4747
HighestReceivedBlockSlot() primitives.Slot

Diff for: beacon-chain/blockchain/chain_info_forkchoice.go

+2-3
Original file line numberDiff line numberDiff line change
@@ -90,11 +90,10 @@ func (s *Service) UnrealizedJustifiedPayloadBlockHash() [32]byte {
9090
return s.cfg.ForkChoiceStore.UnrealizedJustifiedPayloadBlockHash()
9191
}
9292

93-
// SafeHeadPayloadBlockHash returns safe head payload block hash from forkchoice.
94-
func (s *Service) SafeHeadPayloadBlockHash() [32]byte {
93+
func (s *Service) SafeBlockHash() [32]byte {
9594
s.cfg.ForkChoiceStore.RLock()
9695
defer s.cfg.ForkChoiceStore.RUnlock()
97-
return s.cfg.ForkChoiceStore.SafeHeadPayloadBlockHash()
96+
return s.cfg.ForkChoiceStore.SafeBlockHash()
9897
}
9998

10099
// FinalizedBlockHash returns finalized payload block hash from forkchoice.

Diff for: beacon-chain/blockchain/execution_engine.go

+1-6
Original file line numberDiff line numberDiff line change
@@ -63,12 +63,7 @@ func (s *Service) notifyForkchoiceUpdate(ctx context.Context, arg *fcuConfig) (*
6363
return nil, nil
6464
}
6565
finalizedHash := s.cfg.ForkChoiceStore.FinalizedPayloadBlockHash()
66-
safeBlockHash := [32]byte{}
67-
if features.Get().SafeHeadFCU {
68-
safeBlockHash = s.cfg.ForkChoiceStore.SafeHeadPayloadBlockHash()
69-
} else {
70-
safeBlockHash = s.cfg.ForkChoiceStore.UnrealizedJustifiedPayloadBlockHash()
71-
}
66+
safeBlockHash := s.cfg.ForkChoiceStore.SafeBlockHash()
7267
fcs := &enginev1.ForkchoiceState{
7368
HeadBlockHash: headPayload.BlockHash(),
7469
SafeBlockHash: safeBlockHash[:],

Diff for: beacon-chain/blockchain/testing/mock.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -627,8 +627,8 @@ func (s *ChainService) CachedHeadRoot() [32]byte {
627627
return [32]byte{}
628628
}
629629

630-
// SafeHeadPayloadBlockHash mocks the same method in the chain service
631-
func (s *ChainService) SafeHeadPayloadBlockHash() [32]byte {
630+
// SafeBlockHash mocks the same method in the chain service
631+
func (s *ChainService) SafeBlockHash() [32]byte {
632632
return [32]byte{}
633633
}
634634

Diff for: beacon-chain/forkchoice/doubly-linked-tree/BUILD.bazel

+1
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ go_library(
2727
"//beacon-chain/forkchoice:go_default_library",
2828
"//beacon-chain/forkchoice/types:go_default_library",
2929
"//beacon-chain/state:go_default_library",
30+
"//config/features:go_default_library",
3031
"//config/fieldparams:go_default_library",
3132
"//config/params:go_default_library",
3233
"//consensus-types/blocks:go_default_library",

Diff for: beacon-chain/forkchoice/doubly-linked-tree/forkchoice.go

+29-12
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import (
88
"github.com/OffchainLabs/prysm/v6/beacon-chain/forkchoice"
99
forkchoicetypes "github.com/OffchainLabs/prysm/v6/beacon-chain/forkchoice/types"
1010
"github.com/OffchainLabs/prysm/v6/beacon-chain/state"
11+
"github.com/OffchainLabs/prysm/v6/config/features"
1112
fieldparams "github.com/OffchainLabs/prysm/v6/config/fieldparams"
1213
"github.com/OffchainLabs/prysm/v6/config/params"
1314
consensus_blocks "github.com/OffchainLabs/prysm/v6/consensus-types/blocks"
@@ -65,7 +66,7 @@ func (f *ForkChoice) Head(
6566
return [32]byte{}, errors.Wrap(err, "could not apply proposer boost score")
6667
}
6768

68-
if err := f.store.treeRootNode.applyWeightChanges(ctx, f.store.proposerBoostRoot, f.store.previousProposerBoostScore); err != nil {
69+
if err := f.store.treeRootNode.applyWeightChanges(ctx); err != nil {
6970
return [32]byte{}, errors.Wrap(err, "could not apply weight changes")
7071
}
7172

@@ -76,18 +77,31 @@ func (f *ForkChoice) Head(
7677
if err != nil {
7778
log.WithError(err).Error("could not compute seconds since slot start")
7879
}
79-
if err := f.store.treeRootNode.updateBestDescendant(ctx, jc.Epoch, fc.Epoch, currentSlot, secondsSinceSlotStart, f.store.committeeWeight); err != nil {
80+
if err := f.store.treeRootNode.updateBestDescendant(ctx, &updateDescendantArgs{
81+
justifiedEpoch: jc.Epoch,
82+
finalizedEpoch: fc.Epoch,
83+
currentSlot: currentSlot,
84+
secondsSinceSlotStart: secondsSinceSlotStart,
85+
committeeWeight: f.store.committeeWeight,
86+
pbRoot: f.store.proposerBoostRoot,
87+
pbValue: f.store.previousProposerBoostScore,
88+
}); err != nil {
8089
return [32]byte{}, errors.Wrap(err, "could not update best descendant")
8190
}
82-
if err := f.UpdateSafeHead(ctx); err != nil {
91+
h, err := f.store.head(ctx)
92+
if err != nil {
93+
return [32]byte{}, errors.Wrap(err, "could not get head")
94+
}
95+
96+
if err := f.updateSafeHead(ctx); err != nil {
8397
log.WithError(err).Error("could not update safe head")
8498
}
8599

86-
return f.store.head(ctx)
100+
return h, nil
87101
}
88102

89-
// UpdateSafeHead updates the safe head in the fork choice store.
90-
func (f *ForkChoice) UpdateSafeHead(
103+
// updateSafeHead updates the safe head in the fork choice store.
104+
func (f *ForkChoice) updateSafeHead(
91105
ctx context.Context,
92106
) error {
93107
oldSafeHeadRoot := f.store.safeHeadRoot
@@ -139,9 +153,8 @@ func (f *ForkChoice) logSafeHead(ctx context.Context, newSafeHeadRoot [32]byte,
139153
return
140154
}
141155

156+
// The safe head has reorged. This is bad!
142157
if oldSafeHeadRoot != [32]byte{} && commonRoot != oldSafeHeadRoot {
143-
// The safe head has reorged.
144-
// Calculate reorg metrics.
145158
oldSafeHeadNode, ok := f.store.nodeByRoot[oldSafeHeadRoot]
146159
if !ok || oldSafeHeadNode == nil {
147160
log.WithError(ErrNilNode).Error("could not find old safe head node")
@@ -156,8 +169,8 @@ func (f *ForkChoice) logSafeHead(ctx context.Context, newSafeHeadRoot [32]byte,
156169
"commonAncestorRoot": fmt.Sprintf("%#x", commonRoot),
157170
"distance": dis,
158171
"depth": dep,
159-
}).Debug("Safe head reorg occurred")
160-
// Update reorg metrics.
172+
}).Error("Safe head reorg occurred")
173+
161174
safeHeadReorgDistance.Observe(float64(dis))
162175
safeHeadReorgDepth.Observe(float64(dep))
163176
safeHeadReorgCount.Inc()
@@ -624,8 +637,12 @@ func (f *ForkChoice) UnrealizedJustifiedPayloadBlockHash() [32]byte {
624637
return node.payloadHash
625638
}
626639

627-
// SafeHeadPayloadBlockHash returns the hash of the payload at the safe head
628-
func (f *ForkChoice) SafeHeadPayloadBlockHash() [32]byte {
640+
// SafeBlockHash returns the hash of the payload at the safe head
641+
func (f *ForkChoice) SafeBlockHash() [32]byte {
642+
if !features.Get().EnableFastConfirmation {
643+
return f.UnrealizedJustifiedPayloadBlockHash()
644+
}
645+
629646
safeHeadRoot := f.store.safeHeadRoot
630647
node, ok := f.store.nodeByRoot[safeHeadRoot]
631648
if !ok || node == nil {

Diff for: beacon-chain/forkchoice/doubly-linked-tree/forkchoice_test.go

+13-6
Original file line numberDiff line numberDiff line change
@@ -227,11 +227,17 @@ func TestForkChoice_IsCanonicalReorg(t *testing.T) {
227227
require.NoError(t, f.InsertNode(ctx, st, roblock))
228228

229229
f.store.nodeByRoot[[32]byte{'3'}].balance = 10
230-
require.NoError(t, f.store.treeRootNode.applyWeightChanges(ctx, params.BeaconConfig().ZeroHash, 0))
230+
require.NoError(t, f.store.treeRootNode.applyWeightChanges(ctx))
231231
require.Equal(t, uint64(10), f.store.nodeByRoot[[32]byte{'1'}].weight)
232232
require.Equal(t, uint64(0), f.store.nodeByRoot[[32]byte{'2'}].weight)
233233

234-
require.NoError(t, f.store.treeRootNode.updateBestDescendant(ctx, 1, 1, 6, 0, f.store.committeeWeight))
234+
require.NoError(t, f.store.treeRootNode.updateBestDescendant(ctx, &updateDescendantArgs{
235+
justifiedEpoch: 1,
236+
finalizedEpoch: 1,
237+
currentSlot: 6,
238+
secondsSinceSlotStart: 0,
239+
committeeWeight: f.store.committeeWeight,
240+
}))
235241
require.DeepEqual(t, [32]byte{'3'}, f.store.treeRootNode.bestDescendant.root)
236242

237243
r1 := [32]byte{'1'}
@@ -943,13 +949,14 @@ func TestForkChoiceSafeHead(t *testing.T) {
943949
require.Equal(t, primitives.Slot(32), slotsPerEpoch)
944950

945951
driftGenesisTime(f, primitives.Slot(11), 0)
946-
st, blkRoot, err := prepareForkchoiceState(ctx, 1, indexToHash(1), params.BeaconConfig().ZeroHash, params.BeaconConfig().ZeroHash, 0, 0)
952+
st, b, err := prepareForkchoiceState(ctx, 1, indexToHash(1), params.BeaconConfig().ZeroHash, params.BeaconConfig().ZeroHash, 0, 0)
947953
require.NoError(t, err)
948-
require.NoError(t, f.InsertNode(ctx, st, blkRoot))
954+
require.NoError(t, f.InsertNode(ctx, st, b))
949955
for i := 2; i < 10; i++ {
950-
st, blkRoot, err = prepareForkchoiceState(ctx, primitives.Slot(i), indexToHash(uint64(i)), indexToHash(uint64(i-1)), params.BeaconConfig().ZeroHash, 0, 0)
956+
st, b, err = prepareForkchoiceState(ctx, primitives.Slot(i), indexToHash(uint64(i)), indexToHash(uint64(i-1)), params.BeaconConfig().ZeroHash, 0, 0)
951957
require.NoError(t, err)
952-
require.NoError(t, f.InsertNode(ctx, st, blkRoot))
958+
t.Logf("Inserting node %d", b.Block().Slot())
959+
require.NoError(t, f.InsertNode(ctx, st, b))
953960
}
954961

955962
tests := []struct {

Diff for: beacon-chain/forkchoice/doubly-linked-tree/node.go

+35-26
Original file line numberDiff line numberDiff line change
@@ -16,35 +16,36 @@ import (
1616
// process attestations for the current slot
1717
const ProcessAttestationsThreshold = 10
1818

19+
type updateDescendantArgs struct {
20+
justifiedEpoch primitives.Epoch
21+
finalizedEpoch primitives.Epoch
22+
currentSlot primitives.Slot
23+
secondsSinceSlotStart uint64
24+
committeeWeight uint64
25+
pbRoot [32]byte
26+
pbValue uint64
27+
}
28+
1929
// applyWeightChanges recursively traverses a tree of nodes to update each node's total weight and
2030
// weight without proposer boost by summing the balance of the node and its children.
2131
// If the node matches a specific root (`pbRoot`), it subtracts a given boost value (`pbValue`) from the weight without boost,
2232
// ensuring the balance is sufficient. It also handles context cancellation and errors during recursion.
23-
func (n *Node) applyWeightChanges(ctx context.Context, pbRoot [32]byte, pbValue uint64) error {
33+
func (n *Node) applyWeightChanges(ctx context.Context) error {
2434
// Recursively calling the children to sum their weights.
2535
childrenWeight := uint64(0)
26-
childrenWeightWithoutBoost := uint64(0)
2736
for _, child := range n.children {
2837
if ctx.Err() != nil {
2938
return ctx.Err()
3039
}
31-
if err := child.applyWeightChanges(ctx, pbRoot, pbValue); err != nil {
40+
if err := child.applyWeightChanges(ctx); err != nil {
3241
return err
3342
}
3443
childrenWeight += child.weight
35-
childrenWeightWithoutBoost += child.weightWithoutBoost
3644
}
3745
if n.root == params.BeaconConfig().ZeroHash {
3846
return nil
3947
}
4048
n.weight = n.balance + childrenWeight
41-
n.weightWithoutBoost = n.balance + childrenWeightWithoutBoost
42-
if n.root == pbRoot {
43-
if n.balance < pbValue {
44-
return fmt.Errorf("node balance %d is less than proposer boost value %d", n.balance, pbValue)
45-
}
46-
n.weightWithoutBoost -= pbValue
47-
}
4849
return nil
4950
}
5051

@@ -86,9 +87,7 @@ func (n *Node) maxWeight(endSlot primitives.Slot, committeeWeight uint64) uint64
8687

8788
// updateBestDescendant updates the best descendant of this node and its
8889
// children.
89-
func (n *Node) updateBestDescendant(ctx context.Context,
90-
justifiedEpoch primitives.Epoch, finalizedEpoch primitives.Epoch,
91-
currentSlot primitives.Slot, secondsSinceSlotStart uint64, committeeWeight uint64) error {
90+
func (n *Node) updateBestDescendant(ctx context.Context, args *updateDescendantArgs) error {
9291
if ctx.Err() != nil {
9392
return ctx.Err()
9493
}
@@ -105,13 +104,11 @@ func (n *Node) updateBestDescendant(ctx context.Context,
105104
if child == nil {
106105
return errors.Wrap(ErrNilNode, "could not update best descendant")
107106
}
108-
if err := child.updateBestDescendant(ctx,
109-
justifiedEpoch, finalizedEpoch,
110-
currentSlot, secondsSinceSlotStart, committeeWeight); err != nil {
107+
if err := child.updateBestDescendant(ctx, args); err != nil {
111108
return err
112109
}
113-
currentEpoch := slots.ToEpoch(currentSlot)
114-
childLeadsToViableHead := child.leadsToViableHead(justifiedEpoch, currentEpoch)
110+
currentEpoch := slots.ToEpoch(args.currentSlot)
111+
childLeadsToViableHead := child.leadsToViableHead(args.justifiedEpoch, currentEpoch)
115112
if childLeadsToViableHead && !hasViableDescendant {
116113
// The child leads to a viable head, but the current
117114
// parent's best child doesn't.
@@ -140,14 +137,14 @@ func (n *Node) updateBestDescendant(ctx context.Context,
140137
// The best descendant is more than 1 hop away.
141138
n.bestDescendant = bestChild.bestDescendant
142139
}
143-
// Compute safe head only during the first interval of the slot
144-
if secondsSinceSlotStart < params.BeaconConfig().SecondsPerSlot/params.BeaconConfig().IntervalsPerSlot {
140+
141+
if args.secondsSinceSlotStart < params.BeaconConfig().SecondsPerSlot/params.BeaconConfig().IntervalsPerSlot {
145142
prevSlot := primitives.Slot(0)
146-
if currentSlot > 1 {
147-
prevSlot = currentSlot - 1
143+
if args.currentSlot > 1 {
144+
prevSlot = args.currentSlot - 1
148145
}
149146

150-
if bestChild.confirmed(prevSlot, committeeWeight) {
147+
if bestChild.confirmed(prevSlot, args.committeeWeight, args.pbRoot, args.pbValue) {
151148
n.bestConfirmedDescendant = bestChild.bestConfirmedDescendant
152149
if n.bestConfirmedDescendant == nil {
153150
n.bestConfirmedDescendant = bestChild
@@ -267,7 +264,7 @@ func (n *Node) nodeTreeDump(ctx context.Context, nodes []*forkchoice2.Node) ([]*
267264
}
268265

269266
// confirmed returns true if the node satisfies the confirmation rule.
270-
func (n *Node) confirmed(slot primitives.Slot, committeeWeight uint64) bool {
267+
func (n *Node) confirmed(slot primitives.Slot, committeeWeight uint64, pbRoot [32]byte, pbValue uint64) bool {
271268
if n.slot > slot {
272269
return false
273270
}
@@ -276,5 +273,17 @@ func (n *Node) confirmed(slot primitives.Slot, committeeWeight uint64) bool {
276273
maxWeight := n.maxWeight(slot, committeeWeight)
277274
threshold := (maxWeight + pbWeight) / 2
278275

279-
return n.weightWithoutBoost > threshold
276+
nodeWeight := n.weight
277+
if n.root == pbRoot {
278+
nodeWeight -= pbValue
279+
}
280+
if n.bestDescendant != nil && n.bestDescendant.root == pbRoot {
281+
if nodeWeight < pbValue {
282+
return false
283+
}
284+
nodeWeight -= pbValue
285+
}
286+
287+
fmt.Println(nodeWeight, threshold)
288+
return nodeWeight > threshold
280289
}

0 commit comments

Comments
 (0)