Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 8 additions & 2 deletions cl/beacon/handler/states.go
Original file line number Diff line number Diff line change
Expand Up @@ -510,7 +510,7 @@ func (a *ApiHandler) GetEthV1BeaconStatesPendingConsolidations(w http.ResponseWr
var ok bool
pendingConsolidations, ok = a.forkchoiceStore.GetPendingConsolidations(blockRoot)
if !ok {
return nil, beaconhttp.NewEndpointError(http.StatusNotFound, fmt.Errorf("no pending consolidations found for block root: %x", blockRoot))
return nil, beaconhttp.NewEndpointError(http.StatusNotFound, fmt.Errorf("no pending consolidations found for block root: %x", blockRoot))
}
// If we have the pending consolidations in memory, we can return them directly.
} else {
Expand All @@ -522,7 +522,10 @@ func (a *ApiHandler) GetEthV1BeaconStatesPendingConsolidations(w http.ResponseWr
}
}

version := a.ethClock.StateVersionByEpoch(*slot / a.beaconChainCfg.SlotsPerEpoch)
return newBeaconResponse(pendingConsolidations).
WithHeader("Eth-Consensus-Version", version.String()).
WithVersion(version).
WithOptimistic(isOptimistic).
WithFinalized(canonicalRoot == blockRoot && *slot <= a.forkchoiceStore.FinalizedSlot()), nil
}
Expand Down Expand Up @@ -569,7 +572,7 @@ func (a *ApiHandler) GetEthV1BeaconStatesPendingDeposits(w http.ResponseWriter,
var ok bool
pendingDeposits, ok = a.forkchoiceStore.GetPendingDeposits(blockRoot)
if !ok {
return nil, beaconhttp.NewEndpointError(http.StatusNotFound, fmt.Errorf("no pending deposits found for block root: %x", blockRoot))
return nil, beaconhttp.NewEndpointError(http.StatusNotFound, fmt.Errorf("no pending deposits found for block root: %x", blockRoot))
}
} else {
stateView := a.caplinStateSnapshots.View()
Expand All @@ -580,7 +583,10 @@ func (a *ApiHandler) GetEthV1BeaconStatesPendingDeposits(w http.ResponseWriter,
}
}

version := a.ethClock.StateVersionByEpoch(*slot / a.beaconChainCfg.SlotsPerEpoch)
return newBeaconResponse(pendingDeposits).
WithHeader("Eth-Consensus-Version", version.String()).
WithVersion(version).
WithOptimistic(isOptimistic).
WithFinalized(canonicalRoot == blockRoot && *slot <= a.forkchoiceStore.FinalizedSlot()), nil
}
Expand Down
36 changes: 36 additions & 0 deletions cl/beacon/handler/states_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -554,3 +554,39 @@ func TestGetRandao(t *testing.T) {
})
}
}

func TestGetPendingQueuesConsensusVersionHeader(t *testing.T) {
_, blocks, _, _, _, handler, _, _, fcu, _ := setupTestingHandler(t, clparams.ElectraVersion, log.Root(), false)

var err error
fcu.HeadVal, err = blocks[len(blocks)-1].Block.HashSSZ()
require.NoError(t, err)
fcu.HeadSlotVal = blocks[len(blocks)-1].Block.Slot
lowest := uint64(0)
fcu.LowestAvailableSlotVal = &lowest
fcu.PendingConsolidationsVal = map[common.Hash]*solid.ListSSZ[*solid.PendingConsolidation]{
fcu.HeadVal: solid.NewPendingConsolidationList(&clparams.MainnetBeaconConfig),
}
fcu.PendingDepositsVal = map[common.Hash]*solid.ListSSZ[*solid.PendingDeposit]{
fcu.HeadVal: solid.NewPendingDepositList(&clparams.MainnetBeaconConfig),
}
fcu.PendingPartialWithdrawalsVal = map[common.Hash]*solid.ListSSZ[*solid.PendingPartialWithdrawal]{
fcu.HeadVal: solid.NewPendingWithdrawalList(&clparams.MainnetBeaconConfig),
}

server := httptest.NewServer(handler.mux)
defer server.Close()

versions := map[string]string{}
for _, endpoint := range []string{"pending_consolidations", "pending_deposits", "pending_partial_withdrawals"} {
resp, err := http.Get(server.URL + "/eth/v1/beacon/states/head/" + endpoint)
require.NoError(t, err)
resp.Body.Close()
require.Equal(t, http.StatusOK, resp.StatusCode, endpoint)
v := resp.Header.Get("Eth-Consensus-Version")
require.NotEmpty(t, v, "%s must set Eth-Consensus-Version", endpoint)
versions[endpoint] = v
}
require.Equal(t, versions["pending_partial_withdrawals"], versions["pending_consolidations"])
require.Equal(t, versions["pending_partial_withdrawals"], versions["pending_deposits"])
}
4 changes: 2 additions & 2 deletions cl/cltypes/beacon_block_blinded.go
Original file line number Diff line number Diff line change
Expand Up @@ -276,7 +276,7 @@ func NewBlindedBeaconBody(beaconCfg *clparams.BeaconChainConfig, version clparam
ExecutionChanges: solid.NewStaticListSSZ[*SignedBLSToExecutionChange](MaxExecutionChanges, 172),
BlobKzgCommitments: solid.NewStaticListSSZ[*KZGCommitment](int(beaconCfg.MaxBlobCommittmentsPerBlock), 48),
ExecutionRequests: executionRequests,
Version: 0,
Version: version,
beaconCfg: beaconCfg,
}
}
Expand Down Expand Up @@ -360,7 +360,7 @@ func (b *BlindedBeaconBody) EncodingSizeSSZ() (size int) {
size += b.ExecutionChanges.EncodingSizeSSZ()
}
if b.Version >= clparams.DenebVersion {
size += b.ExecutionChanges.EncodingSizeSSZ()
size += b.BlobKzgCommitments.EncodingSizeSSZ()
}
if b.Version >= clparams.ElectraVersion {
if b.ExecutionRequests != nil {
Expand Down
52 changes: 52 additions & 0 deletions cl/cltypes/beacon_block_blinded_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
// Copyright 2026 The Erigon Authors
// This file is part of Erigon.
//
// Erigon is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Erigon is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with Erigon. If not, see <http://www.gnu.org/licenses/>.

package cltypes

import (
"testing"

"github.com/stretchr/testify/require"

"github.com/erigontech/erigon/cl/clparams"
)

// EncodingSizeSSZ must grow by exactly the encoded delta when a field's
// content grows, for every field gated by a fork version.
func TestBlindedBeaconBodyEncodingSizeTracksEncoding(t *testing.T) {
for _, v := range []clparams.StateVersion{clparams.DenebVersion, clparams.ElectraVersion} {
t.Run(v.String(), func(t *testing.T) {
body := NewBlindedBeaconBody(&clparams.MainnetBeaconConfig, v)
require.Equal(t, v, body.Version, "constructor must honor the version argument")

enc0, err := body.EncodeSSZ(nil)
require.NoError(t, err)
size0 := body.EncodingSizeSSZ()

body.BlobKzgCommitments.Append(&KZGCommitment{})
enc1, err := body.EncodeSSZ(nil)
require.NoError(t, err)
size1 := body.EncodingSizeSSZ()
require.Equal(t, len(enc1)-len(enc0), size1-size0, "BlobKzgCommitments not reflected in EncodingSizeSSZ")

body.ExecutionChanges.Append(&SignedBLSToExecutionChange{Message: &BLSToExecutionChange{}})
enc2, err := body.EncodeSSZ(nil)
require.NoError(t, err)
size2 := body.EncodingSizeSSZ()
require.Equal(t, len(enc2)-len(enc1), size2-size1, "ExecutionChanges over-counted in EncodingSizeSSZ")
})
}
}
42 changes: 24 additions & 18 deletions cl/phase1/forkchoice/mock_services/forkchoice_mock.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,21 +58,24 @@ type ForkChoiceStorageMock struct {

ParticipationVal map[uint64]*solid.ParticipationBitList

StateAtBlockRootVal map[common.Hash]*state.CachingBeaconState
StateAtSlotVal map[uint64]*state.CachingBeaconState
GetSyncCommitteesVal map[uint64][2]*solid.SyncCommittee
GetFinalityCheckpointsVal map[common.Hash][3]solid.Checkpoint
WeightsMock []forkchoice.ForkNode
LightClientBootstraps map[common.Hash]*cltypes.LightClientBootstrap
NewestLCUpdate *cltypes.LightClientUpdate
LCUpdates map[uint64]*cltypes.LightClientUpdate
SyncContributionPool sync_contribution_pool.SyncContributionPool
Headers map[common.Hash]*cltypes.BeaconBlockHeader
Blocks map[common.Hash]*cltypes.SignedBeaconBlock
Envelopes map[common.Hash]*cltypes.SignedExecutionPayloadEnvelope
VerifiedPayloads map[common.Hash]bool
OnExecutionPayloadErr error
GetBeaconCommitteeMock func(slot, committeeIndex uint64) ([]uint64, error)
StateAtBlockRootVal map[common.Hash]*state.CachingBeaconState
StateAtSlotVal map[uint64]*state.CachingBeaconState
GetSyncCommitteesVal map[uint64][2]*solid.SyncCommittee
GetFinalityCheckpointsVal map[common.Hash][3]solid.Checkpoint
PendingConsolidationsVal map[common.Hash]*solid.ListSSZ[*solid.PendingConsolidation]
PendingDepositsVal map[common.Hash]*solid.ListSSZ[*solid.PendingDeposit]
PendingPartialWithdrawalsVal map[common.Hash]*solid.ListSSZ[*solid.PendingPartialWithdrawal]
WeightsMock []forkchoice.ForkNode
LightClientBootstraps map[common.Hash]*cltypes.LightClientBootstrap
NewestLCUpdate *cltypes.LightClientUpdate
LCUpdates map[uint64]*cltypes.LightClientUpdate
SyncContributionPool sync_contribution_pool.SyncContributionPool
Headers map[common.Hash]*cltypes.BeaconBlockHeader
Blocks map[common.Hash]*cltypes.SignedBeaconBlock
Envelopes map[common.Hash]*cltypes.SignedExecutionPayloadEnvelope
VerifiedPayloads map[common.Hash]bool
OnExecutionPayloadErr error
GetBeaconCommitteeMock func(slot, committeeIndex uint64) ([]uint64, error)

Pool pool.OperationsPool

Expand Down Expand Up @@ -523,15 +526,18 @@ func (f *ForkChoiceStorageMock) IsHeadOptimistic() bool {
}

func (f *ForkChoiceStorageMock) GetPendingConsolidations(blockRoot common.Hash) (*solid.ListSSZ[*solid.PendingConsolidation], bool) {
return nil, false
v, ok := f.PendingConsolidationsVal[blockRoot]
return v, ok
}

func (f *ForkChoiceStorageMock) GetPendingDeposits(blockRoot common.Hash) (*solid.ListSSZ[*solid.PendingDeposit], bool) {
return nil, false
v, ok := f.PendingDepositsVal[blockRoot]
return v, ok
}

func (f *ForkChoiceStorageMock) GetPendingPartialWithdrawals(blockRoot common.Hash) (*solid.ListSSZ[*solid.PendingPartialWithdrawal], bool) {
return nil, false
v, ok := f.PendingPartialWithdrawalsVal[blockRoot]
return v, ok
}

func (f *ForkChoiceStorageMock) GetProposerLookahead(slot uint64) (solid.Uint64VectorSSZ, bool) {
Expand Down
2 changes: 1 addition & 1 deletion cmd/txpool/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ var rootCmd = &cobra.Command{
debug.Exit()
},
Run: func(cmd *cobra.Command, args []string) {
logger := debug.SetupCobra(cmd, "integration")
logger := debug.SetupCobra(cmd, "txpool")
if err := doTxpool(cmd.Context(), logger); err != nil {
if !errors.Is(err, context.Canceled) {
log.Error(err.Error())
Expand Down
2 changes: 1 addition & 1 deletion db/kv/mdbx/kv_mdbx.go
Original file line number Diff line number Diff line change
Expand Up @@ -1591,7 +1591,7 @@ func (c *MdbxCursorPseudoDupSort) LastDup() ([]byte, error) {
if mdbx.IsNotFound(err) {
return nil, nil
}
return nil, fmt.Errorf("in FirstDup: tbl=%s, %w", c.bucketName, err)
return nil, fmt.Errorf("in LastDup: tbl=%s, %w", c.bucketName, err)
}
return v, nil
}
Expand Down
31 changes: 0 additions & 31 deletions db/snapshotsync/freezeblocks/block_snapshots.go
Original file line number Diff line number Diff line change
Expand Up @@ -93,37 +93,6 @@ func NewRoSnapshots(cfg ethconfig.BlocksFreezing, snapDir string, logger log.Log
// transaction_hash -> transactions_segment_offset
// transaction_hash -> block_number

func SegmentsCaplin(dir string, minBlock uint64) (res []snaptype.FileInfo, missingSnapshots []snapshotsync.Range, err error) {
list, err := snaptype.Segments(dir)
if err != nil {
return nil, missingSnapshots, err
}

{
var l, lSidecars []snaptype.FileInfo
var m []snapshotsync.Range
for _, f := range list {
if f.Type.Enum() != snaptype.CaplinEnums.BeaconBlocks && f.Type.Enum() != snaptype.CaplinEnums.BlobSidecars {
continue
}
if f.Type.Enum() == snaptype.CaplinEnums.BlobSidecars {
lSidecars = append(lSidecars, f) // blobs are an exception
continue
}
l = append(l, f)
}
l, m = snapshotsync.NoGaps(snapshotsync.NoOverlaps(l))
if len(m) > 0 {
lst := m[len(m)-1]
log.Debug("[snapshots] see gap", "type", snaptype.CaplinEnums.BeaconBlocks, "from", lst.From())
}
res = append(res, l...)
res = append(res, lSidecars...)
missingSnapshots = append(missingSnapshots, m...)
}
return res, missingSnapshots, nil
}

func chooseSegmentEnd(from, to uint64, snapType snaptype.Enum, snCfg *snapcfg.Cfg) uint64 {
blocksPerFile := snapcfg.MergeLimitFromCfg(snCfg, snapType, from)

Expand Down
4 changes: 2 additions & 2 deletions db/state/integrity.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,12 +43,12 @@ func (at *AggregatorRoTx) IntegrityInvertedIndexAllValuesAreInRange(ctx context.
return err
}
case kv.StorageHistoryIdx:
err := at.d[kv.CodeDomain].ht.iit.IntegrityInvertedIndexAllValuesAreInRange(ctx, failFast, fromStep)
err := at.d[kv.StorageDomain].ht.iit.IntegrityInvertedIndexAllValuesAreInRange(ctx, failFast, fromStep)
if err != nil {
return err
}
case kv.CodeHistoryIdx:
err := at.d[kv.StorageDomain].ht.iit.IntegrityInvertedIndexAllValuesAreInRange(ctx, failFast, fromStep)
err := at.d[kv.CodeDomain].ht.iit.IntegrityInvertedIndexAllValuesAreInRange(ctx, failFast, fromStep)
if err != nil {
return err
}
Expand Down
2 changes: 1 addition & 1 deletion execution/exec/txtask.go
Original file line number Diff line number Diff line change
Expand Up @@ -673,7 +673,7 @@ func (txTask *TxTask) executeAA(aaTxn *types.AccountAbstractionTransaction,
result.Err = outerErr
return &result
}
log.Info("✅[aa] validated AA bundle", "len", startIdx-endIdx)
log.Info("✅[aa] validated AA bundle", "len", endIdx-startIdx+1)

result.ValidationResults = validationResults
}
Expand Down
Loading
Loading