Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
45 commits
Select commit Hold shift + click to select a range
5b057af
moved deposit store to v1 package
abi87 May 17, 2025
5873665
wip: adding deposits store v2
abi87 May 17, 2025
7af6ded
nit
abi87 May 17, 2025
b6e0b37
wip: still on deposits store v2
abi87 May 17, 2025
df562f3
wip: deposits store v2, adding simple UTs
abi87 May 17, 2025
504045e
deposits store v2 fixed logging
abi87 May 17, 2025
a6827bd
added general deposit store
abi87 May 17, 2025
c050991
aligned v1 and v2 deposit stores interfaces
abi87 May 17, 2025
fb67963
general deposit store: instantiated v2
abi87 May 17, 2025
49d1889
nit: introduced cache multi store
abi87 May 17, 2025
ab575f6
simplified ProvideDepositStore
abi87 May 18, 2025
50d1f8a
reduced some code duplication
abi87 May 18, 2025
44013f3
further simplification of deposits v1 + better encapsulation
abi87 May 18, 2025
7f5214d
nits
abi87 May 18, 2025
57e128c
wip: adding data migration logic and deposit version selection
abi87 May 18, 2025
5f001ac
fixed deposit store version selection
abi87 May 18, 2025
c19ea3a
wip: activate deposits v2 in unit tests
abi87 May 18, 2025
87fc2da
wip: added post Electra non-genesis deposits verification
abi87 May 18, 2025
ab25469
added DepositsV2ActivationSlot config
abi87 May 18, 2025
a4eb665
made deposit store migration idempotent
abi87 May 18, 2025
af10c24
simplified StoreManager interface
abi87 May 18, 2025
6f1ca2b
wip: check for migration upon genesis processing
abi87 May 18, 2025
38e932e
moved concurrency protection from v1 deposit to general deposit
abi87 May 18, 2025
c954b29
wip: check for migration upon deposits loading from contract
abi87 May 18, 2025
708a6bd
wip: fixed deposits checks in state processor + fixed UTs
abi87 May 18, 2025
28d88ac
activate deposit store V2 in devnet
abi87 May 18, 2025
5539bd1
wip: fixing block building
abi87 May 18, 2025
d721bc4
wip: some more fork activation fixing
abi87 May 19, 2025
6cea92f
improved deposits store migration logging
abi87 May 19, 2025
4defa2f
wip: fixing some UTs leftover post deposits store V2 activation in de…
abi87 May 19, 2025
613bc8b
nit: drop unused mutex
abi87 May 19, 2025
2192fe3
reused storage.KVStoreService
abi87 May 19, 2025
a5335c4
simplified store v2
abi87 May 19, 2025
5207610
added deposits store benchmarks
abi87 May 19, 2025
d857fe4
Merge branch 'consolidate-deposits-storage-pt2' into consolidate-depo…
abi87 May 20, 2025
6d7d695
Merge branch 'consolidate-deposits-storage-pt2' into consolidate-depo…
abi87 May 20, 2025
d68bf61
fixed DBCheck command
abi87 May 20, 2025
d387f09
logging nit
abi87 May 21, 2025
6ceccd1
fix pruning options for deposits store v2
abi87 May 21, 2025
66e9240
Merge branch 'consolidate-deposits-storage-pt2' into consolidate-depo…
abi87 May 25, 2025
5ab0fdb
Merge branch 'consolidate-deposits-storage-pt2' into consolidate-depo…
abi87 May 27, 2025
e8bcde8
Merge branch 'consolidate-deposits-storage-pt2' into consolidate-depo…
abi87 Jul 7, 2025
5b2e151
Merge branch 'consolidate-deposits-storage-pt2' into consolidate-depo…
abi87 Jul 21, 2025
1217324
Merge branch 'consolidate-deposits-storage-pt2' into consolidate-depo…
abi87 Aug 25, 2025
d7ba879
Merge branch 'consolidate-deposits-storage-pt2' into consolidate-depo…
abi87 Sep 18, 2025
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
16 changes: 15 additions & 1 deletion beacon/blockchain/deposit.go
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,21 @@ func (s *Service) fetchAndStoreDeposits(
)
}

if err = s.storageBackend.DepositStore().EnqueueDeposits(ctx, deposits); err != nil {
// before enqueuing deposits verify we are using the right deposit store version
depositsStore := s.storageBackend.DepositStore()
if s.chainSpec.DepositsV2ActivationSlot() == blockNum {
if err = depositsStore.MigrateV1ToV2(ctx); err != nil {
s.logger.Error("fetch store deposits, failed migration", "error", err)
s.metrics.sink.IncrementCounter(
"beacon_kit.execution.deposit.failed_to_enqueue_deposits",
"block_num",
blockNumStr,
)
return
}
}

if err = depositsStore.EnqueueDeposits(ctx, deposits); err != nil {
s.logger.Error("Failed to store deposits", "error", err)
s.metrics.sink.IncrementCounter(
"beacon_kit.execution.deposit.failed_to_enqueue_deposits",
Expand Down
19 changes: 13 additions & 6 deletions beacon/blockchain/init_chain.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import (
"fmt"

ctypes "github.com/berachain/beacon-kit/consensus-types/types"
"github.com/berachain/beacon-kit/primitives/constants"
"github.com/berachain/beacon-kit/primitives/transition"
"github.com/berachain/beacon-kit/primitives/version"
)
Expand Down Expand Up @@ -61,22 +62,28 @@ func (s *Service) ProcessGenesisData(
}

// Initialize the beacon state from the genesis deposits.
genDeposits := genesisData.GetDeposits()
validatorUpdates, err := s.stateProcessor.InitializeBeaconStateFromEth1(
s.storageBackend.StateFromContext(ctx),
genesisData.GetDeposits(),
genDeposits,
execPayloadHeader,
genesisVersion,
)
if err != nil {
return nil, err
}

// before enqueuing deposits verify we are using the right deposit store version
depositsStore := s.storageBackend.DepositStore()
if s.chainSpec.DepositsV2ActivationSlot() == constants.GenesisSlot {
if err = depositsStore.MigrateV1ToV2(ctx); err != nil {
return nil, fmt.Errorf("process genesis data, failed migration: %w", err)
}
}

// After deposits are validated, store the genesis deposits in the deposit store.
if err = s.storageBackend.DepositStore().EnqueueDeposits(
ctx,
genesisData.GetDeposits(),
); err != nil {
return nil, err
if err = depositsStore.EnqueueDeposits(ctx, genDeposits); err != nil {
return nil, fmt.Errorf("process genesis data, failed deposits enqueuing: %w", err)
}

return validatorUpdates, nil
Expand Down
1 change: 1 addition & 0 deletions beacon/blockchain/interfaces.go
Original file line number Diff line number Diff line change
Expand Up @@ -185,6 +185,7 @@ type PruningChainSpec interface {

type ServiceChainSpec interface {
PruningChainSpec
chain.DepositSpec
chain.BlobSpec
chain.ForkSpec
chain.ForkVersionSpec
Expand Down
35 changes: 22 additions & 13 deletions beacon/validator/block_builder.go
Original file line number Diff line number Diff line change
Expand Up @@ -323,29 +323,38 @@ func (s *Service) buildBlockBody(
return fmt.Errorf("failed loading eth1 deposit index: %w", err)
}

// Grab all previous deposits from genesis up to the current index + max deposits per block.
deposits, localDepositRoot, err := s.sb.DepositStore().GetDepositsByIndex(
ctx,
constants.FirstDepositIndex,
depositIndex+s.chainSpec.MaxDepositsPerBlock(),
)
// Load deposits and their root
startIdx := constants.FirstDepositIndex
depRange := depositIndex + s.chainSpec.MaxDepositsPerBlock()
depositMigrationDone := s.chainSpec.DepositsV2ActivationSlot() < blk.GetSlot()
if depositMigrationDone {
// migration must have done, just load strictly necessary deposits
startIdx = depositIndex
depRange = s.chainSpec.MaxDepositsPerBlock()
}

deposits, localDepositRoot, err := s.sb.DepositStore().GetDepositsByIndex(ctx, startIdx, depRange)
if err != nil {
return err
}
if uint64(len(deposits)) < depositIndex {
return errors.Wrapf(ErrDepositStoreIncomplete,
"all historical deposits not available, expected: %d, got: %d",
depositIndex, len(deposits),
)

if !depositMigrationDone {
if uint64(len(deposits)) < depositIndex {
return errors.Wrapf(ErrDepositStoreIncomplete,
"all historical deposits not available, expected: %d, got: %d",
depositIndex, len(deposits),
)
}
deposits = deposits[depositIndex:]
}
s.logger.Info(
"Building block body with local deposits",
"start_index", depositIndex, "num_deposits", uint64(len(deposits))-depositIndex,
"start_index", depositIndex, "num_deposits", uint64(len(deposits)),
)

eth1Data := ctypes.NewEth1Data(localDepositRoot)
body.SetEth1Data(eth1Data)
body.SetDeposits(deposits[depositIndex:])
body.SetDeposits(deposits)

// Set the graffiti on the block body.
sizedGraffiti := bytes.ExtendToSize([]byte(s.cfg.Graffiti), bytes.B32Size)
Expand Down
5 changes: 3 additions & 2 deletions beacon/validator/interfaces.go
Original file line number Diff line number Diff line change
Expand Up @@ -111,12 +111,13 @@ type BlockBuilderI interface {

// ChainSpec defines an interface for accessing chain-specific parameters.
type ChainSpec interface {
ctypes.ProposerDomain

SlotsPerHistoricalRoot() uint64
DomainTypeRandao() common.DomainType
MaxDepositsPerBlock() uint64
ActiveForkVersionForTimestamp(timestamp math.U64) common.Version
SlotToEpoch(slot math.Slot) math.Epoch
DepositsV2ActivationSlot() math.Slot
EpochsPerHistoricalVector() uint64

ctypes.ProposerDomain
}
3 changes: 3 additions & 0 deletions chain/data.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ package chain
import (
"github.com/berachain/beacon-kit/consensus/cometbft/service/delay"
"github.com/berachain/beacon-kit/primitives/common"
"github.com/berachain/beacon-kit/primitives/math"
)

// SpecData is the underlying data structure for chain-specific parameters. All fields with a
Expand Down Expand Up @@ -86,6 +87,8 @@ type SpecData struct {
MaxDepositsPerBlock uint64 `mapstructure:"max-deposits-per-block"`
// DepositEth1ChainID is the chain ID of the execution client.
DepositEth1ChainID uint64 `mapstructure:"deposit-eth1-chain-id"`
// DepositsV2ActivationSlot returns the slot store v2 is activated
DepositsV2ActivationSlot math.Slot `mapstructure:"deposit-v2-activation-slot"`
// Eth1FollowDistance is the distance between the eth1 chain and the beacon
// chain with respect to reading deposits.
Eth1FollowDistance uint64 `mapstructure:"eth1-follow-distance"`
Expand Down
9 changes: 9 additions & 0 deletions chain/spec.go
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,10 @@ type DepositSpec interface {

// DepositEth1ChainID returns the chain ID of the deposit contract.
DepositEth1ChainID() uint64

// DepositsV2ActivationSlot returns the slot were we should carry out
// data migration from deposit store v1 to v2 and start using v2 instead of v1.
DepositsV2ActivationSlot() math.Slot
}

type DomainTypeSpec interface {
Expand Down Expand Up @@ -416,6 +420,11 @@ func (s spec) DepositEth1ChainID() uint64 {
return s.Data.DepositEth1ChainID
}

// DepositsV2ActivationSlot returns the slot store v2 is activated
func (s spec) DepositsV2ActivationSlot() math.Slot {
return s.Data.DepositsV2ActivationSlot
}

// Eth1FollowDistance returns the distance between the eth1 chain and the beacon
// chain.
func (s spec) Eth1FollowDistance() uint64 {
Expand Down
2 changes: 1 addition & 1 deletion cli/commands/deposit/commands.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ func Commands(chainSpecCreator servertypes.ChainSpecCreator, appCreator serverty
GetValidateDepositCmd(chainSpecCreator),
GetCreateValidatorCmd(chainSpecCreator),
GetValidatorKeysCmd(),
GetDBCheckCmd(appCreator),
GetDBCheckCmd(chainSpecCreator, appCreator),
)

return cmd
Expand Down
57 changes: 42 additions & 15 deletions cli/commands/deposit/db_check.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,13 +33,17 @@ import (

// GetDBCheckCmd returns a command for checking that the deposit store
// is in sync with the beacon state.
func GetDBCheckCmd(appCreator servertypes.AppCreator) *cobra.Command {
func GetDBCheckCmd(chainSpecCreator servertypes.ChainSpecCreator, appCreator servertypes.AppCreator) *cobra.Command {
cmd := &cobra.Command{
Use: "db-check",
Short: `Checks if the deposit store is in sync with the beacon state. Fails if either of the beacon or deposit DBs are not available.`,
RunE: func(cmd *cobra.Command, _ []string) error {
// Create the application from home directory configs and data.
v := clicontext.GetViperFromCmd(cmd)
cs, err := chainSpecCreator(v)
if err != nil {
return err
}
logger := clicontext.GetLoggerFromCmd(cmd)
cfg := clicontext.GetConfigFromCmd(cmd)
db, err := db.OpenDB(cfg.RootDir, dbm.PebbleDBBackend)
Expand All @@ -60,20 +64,43 @@ func GetDBCheckCmd(appCreator servertypes.AppCreator) *cobra.Command {
if err != nil {
return err
}
if err = core.ValidateNonGenesisDeposits(
ctx,
beaconState,
depositStore,
// maxDepositsPerBlock: 0
// In this snapshotted state, we will check up to the existing deposits and not any more.
0,
// blkDeposits: nil
// There are no new block deposits as we are checking at this snapshotted state.
nil,
// blkDepositRoot: eth1Data.DepositRoot
// We will compare against the beacon state's deposit root at this snapshotted state.
eth1Data.DepositRoot,
); err != nil {
stateSlot, err := beaconState.GetSlot()
if err != nil {
return err
}

if cs.DepositsV2ActivationSlot() < stateSlot {
err = core.ValidateNonGenesisDepositsV2(
ctx,
beaconState,
depositStore,
// maxDepositsPerBlock: 0
// In this snapshotted state, we will check up to the existing deposits and not any more.
0,
// blkDeposits: nil
// There are no new block deposits as we are checking at this snapshotted state.
nil,
// blkDepositRoot: eth1Data.DepositRoot
// We will compare against the beacon state's deposit root at this snapshotted state.
eth1Data.DepositRoot,
)
} else {
err = core.ValidateNonGenesisDepositsV1(
ctx,
beaconState,
depositStore,
// maxDepositsPerBlock: 0
// In this snapshotted state, we will check up to the existing deposits and not any more.
0,
// blkDeposits: nil
// There are no new block deposits as we are checking at this snapshotted state.
nil,
// blkDepositRoot: eth1Data.DepositRoot
// We will compare against the beacon state's deposit root at this snapshotted state.
eth1Data.DepositRoot,
)
}
if err != nil {
return err
}

Expand Down
5 changes: 5 additions & 0 deletions config/spec/devnet.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ package spec
import (
"github.com/berachain/beacon-kit/chain"
"github.com/berachain/beacon-kit/primitives/common"
"github.com/berachain/beacon-kit/primitives/constants"
"github.com/ethereum/go-ethereum/params"
)

Expand Down Expand Up @@ -61,6 +62,9 @@ const (

// devnetMinValidatorWithdrawabilityDelay is the delay (in epochs) before a validator can withdraw their stake.
devnetMinValidatorWithdrawabilityDelay = 32

// DepositsV2ActivationSlot returns the slot store v2 is activated
devnetDepositsV2ActivationSlot = constants.GenesisSlot
)

// DevnetChainSpecData is the chain.SpecData for a devnet. It is similar to mainnet but
Expand All @@ -70,6 +74,7 @@ const (
func DevnetChainSpecData() *chain.SpecData {
specData := MainnetChainSpecData()
specData.DepositEth1ChainID = chain.DevnetEth1ChainID
specData.DepositsV2ActivationSlot = devnetDepositsV2ActivationSlot

specData.Config.ConsensusUpdateHeight = 1
specData.Config.ConsensusEnableHeight = 2
Expand Down
7 changes: 7 additions & 0 deletions config/spec/mainnet.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,13 @@
package spec

import (
stdmath "math"

"github.com/berachain/beacon-kit/chain"
"github.com/berachain/beacon-kit/consensus/cometbft/service/delay"
"github.com/berachain/beacon-kit/primitives/bytes"
"github.com/berachain/beacon-kit/primitives/common"
"github.com/berachain/beacon-kit/primitives/math"
"github.com/ethereum/go-ethereum/params"
)

Expand Down Expand Up @@ -102,6 +105,9 @@ const (
// These are the heights at which SBT is activated on mainnet.
mainnetSBTConsensusUpdateHeight = 9_983_085
mainnetSBTConsensusEnableHeight = 9_983_086

// DepositsV2ActivationSlot returns the slot store v2 is activated
mainnetDepositsV2ActivationSlot = math.Slot(stdmath.MaxInt64)
)

// MainnetChainSpecData is the chain.SpecData for the Berachain mainnet.
Expand Down Expand Up @@ -136,6 +142,7 @@ func MainnetChainSpecData() *chain.SpecData {
DepositContractAddress: common.MustNewExecutionAddressFromHex(mainnetDepositContractAddress),
MaxDepositsPerBlock: defaultMaxDepositsPerBlock,
DepositEth1ChainID: chain.MainnetEth1ChainID,
DepositsV2ActivationSlot: mainnetDepositsV2ActivationSlot,
Eth1FollowDistance: defaultEth1FollowDistance,
TargetSecondsPerEth1Block: defaultTargetSecondsPerEth1Block,

Expand Down
5 changes: 5 additions & 0 deletions config/spec/testnet.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,10 @@
package spec

import (
stdmath "math"

"github.com/berachain/beacon-kit/chain"
"github.com/berachain/beacon-kit/primitives/math"
)

// TestnetChainSpecData is the chain.SpecData for Berachain's public testnet, Bepolia.
Expand All @@ -31,6 +34,8 @@ func TestnetChainSpecData() *chain.SpecData {
// Testnet uses chain ID of 80069.
specData.DepositEth1ChainID = chain.TestnetEth1ChainID

specData.DepositsV2ActivationSlot = math.Slot(stdmath.MaxInt64) // TODO: set right value

// Timestamp of the genesis block of Bepolia testnet.
specData.GenesisTime = 1_739_976_735

Expand Down
2 changes: 1 addition & 1 deletion node-api/backend/backend_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,7 @@ func TestBackendLoadData(t *testing.T) {

cmtCfg := buildTestCometConfig(t)

_, kvStore, depositStore, err := statetransition.BuildTestStores()
_, kvStore, depositStore, err := statetransition.BuildTestStores(cs)
require.NoError(t, err)
sb := storage.NewBackend(
cs, nil, kvStore, depositStore, nil, log.NewNopLogger(), metrics.NewNoOpTelemetrySink(),
Expand Down
2 changes: 1 addition & 1 deletion node-api/handlers/beacon/validators_filters_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -546,7 +546,7 @@ func addTestValidators(t *testing.T, stateValidators []*beacontypes.ValidatorDat
func makeTestState(t *testing.T, cs chain.Spec) *statedb.StateDB {
t.Helper()

cms, kvStore, _, errSt := statetransition.BuildTestStores()
cms, kvStore, _, errSt := statetransition.BuildTestStores(cs)
require.NoError(t, errSt)
sdkCtx := sdk.NewContext(cms.CacheMultiStore(), true, cosmoslog.NewNopLogger())
st := statedb.NewBeaconStateFromDB(
Expand Down
5 changes: 2 additions & 3 deletions state-transition/core/state_processor_payload_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,6 @@ import (
"github.com/berachain/beacon-kit/consensus-types/types"
"github.com/berachain/beacon-kit/node-core/components/metrics"
"github.com/berachain/beacon-kit/primitives/common"
"github.com/berachain/beacon-kit/primitives/constants"
"github.com/berachain/beacon-kit/primitives/math"
"github.com/berachain/beacon-kit/primitives/transition"
statedb "github.com/berachain/beacon-kit/state-transition/core/state"
Expand Down Expand Up @@ -146,8 +145,8 @@ func TestPayloadTimestampVerification(t *testing.T) {
var depRoot common.Root
_, depRoot, err = ds.GetDepositsByIndex(
ctx.ConsensusCtx(),
constants.FirstDepositIndex,
uint64(len(genDeposits))+cs.MaxDepositsPerBlock(),
uint64(len(genDeposits)),
cs.MaxDepositsPerBlock(),
)
require.NoError(t, err)

Expand Down
Loading
Loading