From 157c3d4fdbd166699c01e7c4013bf742e8e8a61c Mon Sep 17 00:00:00 2001 From: pk910 Date: Thu, 20 Aug 2026 15:06:41 +0200 Subject: [PATCH 1/2] updates for spec `v1.7.0-alpha.14` --- indexer/beacon/statetransition/builder.go | 6 ++++++ indexer/beacon/statetransition/fork.go | 16 +++++++++++++--- indexer/beacon/statetransition/operations.go | 10 ++++++---- 3 files changed, 25 insertions(+), 7 deletions(-) diff --git a/indexer/beacon/statetransition/builder.go b/indexer/beacon/statetransition/builder.go index dffff557..f529a167 100644 --- a/indexer/beacon/statetransition/builder.go +++ b/indexer/beacon/statetransition/builder.go @@ -1,6 +1,8 @@ package statetransition import ( + "math" + "github.com/ethpandaops/go-eth2-client/spec" "github.com/ethpandaops/go-eth2-client/spec/gloas" "github.com/ethpandaops/go-eth2-client/spec/phase0" @@ -17,6 +19,10 @@ const ( BuilderPaymentQuorumPercent = 100.0 * BuilderPaymentThresholdNumerator / BuilderPaymentThresholdDenominator ) +// BuilderIndexSelfBuild is BUILDER_INDEX_SELF_BUILD: the sentinel builder index marking a bid that +// the proposer built itself rather than buying from a builder. +const BuilderIndexSelfBuild = gloas.BuilderIndex(math.MaxUint64) + // processBuilderPendingPayments implements process_builder_pending_payments (Gloas). // Evaluates the first SLOTS_PER_EPOCH entries of BuilderPendingPayments against // the quorum threshold. Qualifying payments are promoted to BuilderPendingWithdrawals. diff --git a/indexer/beacon/statetransition/fork.go b/indexer/beacon/statetransition/fork.go index 705c7b8d..bc03187f 100644 --- a/indexer/beacon/statetransition/fork.go +++ b/indexer/beacon/statetransition/fork.go @@ -5,6 +5,7 @@ import ( "github.com/ethpandaops/go-eth2-client/spec/all" "github.com/ethpandaops/go-eth2-client/spec/bellatrix" "github.com/ethpandaops/go-eth2-client/spec/capella" + "github.com/ethpandaops/go-eth2-client/spec/deneb" "github.com/ethpandaops/go-eth2-client/spec/electra" "github.com/ethpandaops/go-eth2-client/spec/gloas" "github.com/ethpandaops/go-eth2-client/spec/phase0" @@ -87,21 +88,30 @@ func upgradeToGloas(s *stateAccessor) []*electra.PendingDeposit { s.BuilderPendingPayments = payments s.BuilderPendingWithdrawals = make([]*gloas.BuilderPendingWithdrawal, 0) - // [New in Gloas:EIP7732] latest_execution_payload_bid seeded from the header, with the root of - // an empty ExecutionRequests. A HTR failure leaves a zero root (best effort; only affects the - // state root used to short-circuit later replays, never the extracted field values). + // [New in Gloas:EIP7732] latest_execution_payload_bid seeded from the pre-state's execution + // payload header and block header, marked as a self-build, with the root of an empty + // ExecutionRequests. A HTR failure leaves a zero root (best effort; only affects the state root + // used to short-circuit later replays, never the extracted field values). var execRequestsRoot phase0.Root if root, err := s.dynSsz.HashTreeRoot(&all.ExecutionRequests{Version: spec.DataVersionGloas}); err == nil { execRequestsRoot = phase0.Root(root) } bid := &all.ExecutionPayloadBid{ Version: spec.DataVersionGloas, + BuilderIndex: BuilderIndexSelfBuild, + BlobKZGCommitments: make([]deneb.KZGCommitment, 0), ExecutionRequestsRoot: execRequestsRoot, } if header != nil { + bid.ParentBlockHash = header.ParentHash bid.BlockHash = header.BlockHash + bid.PrevRandao = phase0.Root(header.PrevRandao) bid.GasLimit = header.GasLimit } + if s.LatestBlockHeader != nil { + bid.ParentBlockRoot = s.LatestBlockHeader.ParentRoot + bid.Slot = s.LatestBlockHeader.Slot + } s.LatestExecutionPayloadBid = bid s.PayloadExpectedWithdrawals = make([]*capella.Withdrawal, 0) diff --git a/indexer/beacon/statetransition/operations.go b/indexer/beacon/statetransition/operations.go index 2563f712..0e8bc9a4 100644 --- a/indexer/beacon/statetransition/operations.go +++ b/indexer/beacon/statetransition/operations.go @@ -443,6 +443,7 @@ func processAttestation(s *stateAccessor, att *all.Attestation, cc *committeeCac continue } + hadNoParticipation := participation[index] == 0 willSetNewFlag := false for fi := 0; fi < 3; fi++ { if !participationFlags[fi] { @@ -456,10 +457,11 @@ func processAttestation(s *stateAccessor, att *all.Attestation, cc *committeeCac } // Gloas: each validator contributes its effective balance to the - // builder payment weight at most once per slot, when it first sets a - // new flag on a same-slot attestation. Only counted when the slot - // actually has a builder payment with non-zero amount. - if willSetNewFlag && sameSlot && builderPayment != nil && + // builder payment weight at most once per slot, when it sets a new flag + // on a same-slot attestation while holding no prior flags for that + // epoch. Only counted when the slot actually has a builder payment with + // non-zero amount. + if willSetNewFlag && hadNoParticipation && sameSlot && builderPayment != nil && builderPayment.Withdrawal != nil && builderPayment.Withdrawal.Amount > 0 { builderPayment.Weight += s.Validators[index].EffectiveBalance } From 9c31744db857eb80701f9b0c6ed4dcc2cdbe0cb8 Mon Sep 17 00:00:00 2001 From: pk910 Date: Thu, 20 Aug 2026 15:22:21 +0200 Subject: [PATCH 2/2] fix(db): drop dead argIdx assignment flagged by staticcheck (SA4006) --- db/slots.go | 1 - 1 file changed, 1 deletion(-) diff --git a/db/slots.go b/db/slots.go index 74f3ec33..4cbdafa7 100644 --- a/db/slots.go +++ b/db/slots.go @@ -610,7 +610,6 @@ func GetFilteredSlots(ctx context.Context, filter *dbtypes.BlockFilter, firstSlo fmt.Fprintf(&sql, ` ORDER BY slots.slot DESC `) fmt.Fprintf(&sql, ` LIMIT $%v OFFSET $%v `, argIdx+1, argIdx+2) - argIdx += 2 args = append(args, limit) args = append(args, offset)