Skip to content

Commit 457288b

Browse files
committed
update forkchoice for spec changes
1 parent a2e82c2 commit 457288b

File tree

6 files changed

+80
-22
lines changed

6 files changed

+80
-22
lines changed

cl/clparams/constants.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ const (
1111
BuilderPaymentThresholdDenominator = uint64(10)
1212
PtcSize = uint64(512)
1313
PayloadTimelyThreshold = PtcSize / 2 // 256
14+
DataAvailabilityTimelyThreshold = PtcSize / 2 // 256
1415

1516
AttestationTimelinessIndex = 0
1617
PtcTimelinessIndex = 1

cl/phase1/forkchoice/forkchoice.go

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -148,7 +148,8 @@ type ForkChoiceStore struct {
148148
probabilisticHeadGetter bool
149149

150150
// [New in Gloas:EIP7732]
151-
ptcVote sync.Map // map[common.Hash][clparams.PtcSize]bool
151+
payloadTimelinessVote sync.Map // map[common.Hash][clparams.PtcSize]bool
152+
payloadDataAvailabilityVote sync.Map // map[common.Hash][clparams.PtcSize]bool
152153
// [New in Gloas:EIP7732] Indexed weight store for optimized weight calculation
153154
indexedWeightStore *indexedWeightStore
154155
}
@@ -297,7 +298,16 @@ func NewForkChoiceStore(
297298
f.highestSeen.Store(anchorState.Slot())
298299
f.time.Store(anchorState.GenesisTime() + anchorState.BeaconConfig().SecondsPerSlot*anchorState.Slot())
299300

300-
f.ptcVote.Store(common.Hash(anchorRoot), [clparams.PtcSize]bool{})
301+
// [New in Gloas:EIP7732] Initialize payload timeliness and data availability votes
302+
// Anchor block votes are initialized to all true (prior payloads/blobs were available)
303+
var anchorTimelinessVotes [clparams.PtcSize]bool
304+
var anchorDataAvailabilityVotes [clparams.PtcSize]bool
305+
for i := range anchorTimelinessVotes {
306+
anchorTimelinessVotes[i] = true
307+
anchorDataAvailabilityVotes[i] = true
308+
}
309+
f.payloadTimelinessVote.Store(common.Hash(anchorRoot), anchorTimelinessVotes)
310+
f.payloadDataAvailabilityVote.Store(common.Hash(anchorRoot), anchorDataAvailabilityVotes)
301311

302312
// [New in Gloas:EIP7732] Initialize indexed weight store
303313
f.indexedWeightStore = NewIndexedWeightStore(f)

cl/phase1/forkchoice/on_block.go

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -264,8 +264,9 @@ func (f *ForkChoiceStore) OnBlock(ctx context.Context, block *cltypes.SignedBeac
264264

265265
// [New in Gloas:EIP7732] GLOAS-specific on_block logic (post state transition)
266266
if isGloas {
267-
// Initialize PTC vote for this block
268-
f.ptcVote.Store(common.Hash(blockRoot), [clparams.PtcSize]bool{})
267+
// Initialize payload timeliness and data availability votes for this block
268+
f.payloadTimelinessVote.Store(common.Hash(blockRoot), [clparams.PtcSize]bool{})
269+
f.payloadDataAvailabilityVote.Store(common.Hash(blockRoot), [clparams.PtcSize]bool{})
269270

270271
// Notify PTC messages from payload attestations in the block
271272
if block.Block.Body.PayloadAttestations != nil {

cl/phase1/forkchoice/on_payload_attestation_message.go

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -88,15 +88,25 @@ func (f *ForkChoiceStore) onPayloadAttestationMessage(
8888
}
8989
}
9090

91-
// Get or initialize the PTC vote array for this block root
92-
var ptcVotes [clparams.PtcSize]bool
93-
if existing, ok := f.ptcVote.Load(blockRoot); ok {
94-
ptcVotes = existing.([clparams.PtcSize]bool)
91+
// Get or initialize the payload timeliness vote array for this block root
92+
var timelinessVotes [clparams.PtcSize]bool
93+
if existing, ok := f.payloadTimelinessVote.Load(blockRoot); ok {
94+
timelinessVotes = existing.([clparams.PtcSize]bool)
9595
}
9696

97-
// Update the ptc vote for the block
98-
ptcVotes[ptcIndex] = data.PayloadPresent
99-
f.ptcVote.Store(blockRoot, ptcVotes)
97+
// Update the payload timeliness vote for the block
98+
timelinessVotes[ptcIndex] = data.PayloadPresent
99+
f.payloadTimelinessVote.Store(blockRoot, timelinessVotes)
100+
101+
// Get or initialize the data availability vote array for this block root
102+
var dataAvailabilityVotes [clparams.PtcSize]bool
103+
if existing, ok := f.payloadDataAvailabilityVote.Load(blockRoot); ok {
104+
dataAvailabilityVotes = existing.([clparams.PtcSize]bool)
105+
}
106+
107+
// Update the data availability vote for the block
108+
dataAvailabilityVotes[ptcIndex] = data.BlobDataAvailable
109+
f.payloadDataAvailabilityVote.Store(blockRoot, dataAvailabilityVotes)
100110

101111
return nil
102112
}

cl/phase1/forkchoice/payload_vote.go

Lines changed: 36 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -54,8 +54,8 @@ func (f *ForkChoiceStore) notifyPtcMessages(
5454
// was voted as present by the PTC, and was locally determined to be available.
5555
// [New in Gloas:EIP7732]
5656
func (f *ForkChoiceStore) isPayloadTimely(root common.Hash) bool {
57-
// The beacon block root must be known in ptc_vote
58-
ptcVoteRaw, ok := f.ptcVote.Load(root)
57+
// The beacon block root must be known in payload_timeliness_vote
58+
voteRaw, ok := f.payloadTimelinessVote.Load(root)
5959
if !ok {
6060
return false
6161
}
@@ -67,17 +67,45 @@ func (f *ForkChoiceStore) isPayloadTimely(root common.Hash) bool {
6767
}
6868

6969
// Count PTC votes for payload present
70-
ptcVotes := ptcVoteRaw.([clparams.PtcSize]bool)
70+
votes := voteRaw.([clparams.PtcSize]bool)
7171
presentCount := uint64(0)
72-
for i := range ptcVotes {
73-
if ptcVotes[i] {
72+
for i := range votes {
73+
if votes[i] {
7474
presentCount++
7575
}
7676
}
7777

7878
return presentCount > clparams.PayloadTimelyThreshold
7979
}
8080

81+
// isPayloadDataAvailable returns whether the blob data for the beacon block with root
82+
// was voted as present by the PTC, and was locally determined to be available.
83+
// [New in Gloas:EIP7732]
84+
func (f *ForkChoiceStore) isPayloadDataAvailable(root common.Hash) bool {
85+
// The beacon block root must be known in payload_data_availability_vote
86+
voteRaw, ok := f.payloadDataAvailabilityVote.Load(root)
87+
if !ok {
88+
return false
89+
}
90+
91+
// If the payload is not locally available, the blob data
92+
// is not considered available regardless of the PTC vote
93+
if !f.forkGraph.HasEnvelope(root) {
94+
return false
95+
}
96+
97+
// Count PTC votes for data available
98+
votes := voteRaw.([clparams.PtcSize]bool)
99+
availableCount := uint64(0)
100+
for i := range votes {
101+
if votes[i] {
102+
availableCount++
103+
}
104+
}
105+
106+
return availableCount > clparams.DataAvailabilityTimelyThreshold
107+
}
108+
81109
// getParentPayloadStatus returns the payload status of the parent block.
82110
// Compares current block's parent_block_hash with parent block's block_hash from their bids.
83111
// [New in Gloas:EIP7732]
@@ -148,14 +176,14 @@ func (f *ForkChoiceStore) isSupportingVote(node ForkChoiceNode, message LatestMe
148176

149177
// shouldExtendPayload returns whether the payload for the given root should be extended.
150178
// Returns true if:
151-
// - The payload is timely (received enough PTC votes), OR
179+
// - The payload is timely AND blob data is available (received enough PTC votes for both), OR
152180
// - There's no proposer boost root, OR
153181
// - The proposer boost root's parent is not this root, OR
154182
// - The proposer boost root's parent node has FULL payload status
155183
// [New in Gloas:EIP7732]
156184
func (f *ForkChoiceStore) shouldExtendPayload(root common.Hash) bool {
157-
// Check if payload is timely
158-
if f.isPayloadTimely(root) {
185+
// Check if payload is timely AND blob data is available
186+
if f.isPayloadTimely(root) && f.isPayloadDataAvailable(root) {
159187
return true
160188
}
161189

cl/phase1/forkchoice/utils.go

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -78,15 +78,23 @@ func (f *ForkChoiceStore) onNewFinalized(newFinalized solid.Checkpoint) {
7878
return true
7979
})
8080

81-
// [New in Gloas:EIP7732] Clean up ptcVote for finalized blocks
81+
// [New in Gloas:EIP7732] Clean up payload votes for finalized blocks
8282
// Note: envelope files are cleaned up in forkGraph.Prune()
8383
if newFinalized.Epoch >= f.beaconCfg.GloasForkEpoch {
8484
finalizedSlot := newFinalized.Epoch * f.beaconCfg.SlotsPerEpoch
85-
f.ptcVote.Range(func(k, v any) bool {
85+
f.payloadTimelinessVote.Range(func(k, v any) bool {
8686
// Key is stored as common.Hash
8787
root := k.(common.Hash)
8888
if header, has := f.forkGraph.GetHeader(root); !has || header.Slot <= finalizedSlot {
89-
f.ptcVote.Delete(k)
89+
f.payloadTimelinessVote.Delete(k)
90+
}
91+
return true
92+
})
93+
f.payloadDataAvailabilityVote.Range(func(k, v any) bool {
94+
// Key is stored as common.Hash
95+
root := k.(common.Hash)
96+
if header, has := f.forkGraph.GetHeader(root); !has || header.Slot <= finalizedSlot {
97+
f.payloadDataAvailabilityVote.Delete(k)
9098
}
9199
return true
92100
})

0 commit comments

Comments
 (0)