Skip to content

Commit

Permalink
feat(state-transition): add deposits root to beacon state (berachain#…
Browse files Browse the repository at this point in the history
…2296)

Signed-off-by: Cal Bera <[email protected]>
Co-authored-by: Cal Bera <[email protected]>
Co-authored-by: Shota Ehrlich <[email protected]>
  • Loading branch information
3 people authored Dec 20, 2024
1 parent c08698e commit bd74b71
Show file tree
Hide file tree
Showing 12 changed files with 90 additions and 91 deletions.
15 changes: 14 additions & 1 deletion beacon/blockchain/init_chain.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,10 +40,23 @@ func (s *Service[
s.logger.Error("Failed to unmarshal genesis data", "error", err)
return nil, err
}
return s.stateProcessor.InitializePreminedBeaconStateFromEth1(

validatorUpdates, err := s.stateProcessor.InitializePreminedBeaconStateFromEth1(
s.storageBackend.StateFromContext(ctx),
genesisData.GetDeposits(),
genesisData.GetExecutionPayloadHeader(),
genesisData.GetForkVersion(),
)
if err != nil {
return nil, err
}

// After deposits are validated, store the genesis deposits in the deposit store.
if err = s.storageBackend.DepositStore().EnqueueDeposits(
genesisData.GetDeposits(),
); err != nil {
return nil, err
}

return validatorUpdates, nil
}
18 changes: 5 additions & 13 deletions beacon/blockchain/pruning.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ package blockchain
import (
"github.com/berachain/beacon-kit/chain-spec/chain"
ctypes "github.com/berachain/beacon-kit/consensus-types/types"
"github.com/berachain/beacon-kit/primitives/math"
)

func (s *Service[
Expand All @@ -49,18 +48,11 @@ func (s *Service[
return nil
}

func depositPruneRangeFn(deposits []*ctypes.Deposit, cs chain.ChainSpec) (uint64, uint64) {
if len(deposits) == 0 || cs.MaxDepositsPerBlock() == 0 {
return 0, 0
}
index := deposits[len(deposits)-1].GetIndex()

end := min(index.Unwrap(), cs.MaxDepositsPerBlock())
if index < math.U64(cs.MaxDepositsPerBlock()) {
return 0, end
}

return index.Unwrap() - cs.MaxDepositsPerBlock(), end
func depositPruneRangeFn([]*ctypes.Deposit, chain.ChainSpec) (uint64, uint64) {
// The whole deposit list is validated in consensus and its Merkle root is part of
// Beacon State. Therefore every node must keep the full deposit list and deposits
// pruning must be turned off.
return 0, 0
}

//nolint:unparam // this is ok
Expand Down
20 changes: 15 additions & 5 deletions beacon/validator/block_builder.go
Original file line number Diff line number Diff line change
Expand Up @@ -319,7 +319,7 @@ func (s *Service[
blk.GetSlot() < math.U64(spec.BoonetFork2Height))) {
depositIndex++
}
deposits, err := s.sb.DepositStore().GetDepositsByIndex(
blkDeposits, err := s.sb.DepositStore().GetDepositsByIndex(
depositIndex,
s.chainSpec.MaxDepositsPerBlock(),
)
Expand All @@ -330,14 +330,24 @@ func (s *Service[
// Set the deposits on the block body.
s.logger.Info(
"Building block body with local deposits",
"start_index", depositIndex, "num_deposits", len(deposits),
"start_index", depositIndex, "num_deposits", len(blkDeposits),
)
body.SetDeposits(deposits)
body.SetDeposits(blkDeposits)

// Grab all previous deposits from genesis up to the current index
// to calculate deposit root.
deposits, err := s.sb.DepositStore().GetDepositsByIndex(
0,
depositIndex,
)
if err != nil {
return err
}
deposits = append(deposits, blkDeposits...)

var eth1Data *ctypes.Eth1Data
// TODO: assemble real eth1data.
body.SetEth1Data(eth1Data.New(
common.Root{},
ctypes.Deposits(deposits).HashTreeRoot(),
0,
common.ExecutionHash{},
))
Expand Down
9 changes: 3 additions & 6 deletions consensus-types/types/deposits.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,16 +41,13 @@ func (ds Deposits) SizeSSZ(siz *ssz.Sizer, _ bool) uint32 {
// DefineSSZ defines the SSZ encoding for the Deposits object.
func (ds Deposits) DefineSSZ(c *ssz.Codec) {
c.DefineDecoder(func(*ssz.Decoder) {
ssz.DefineSliceOfStaticObjectsContent(
c, (*[]*Deposit)(&ds), constants.MaxDepositsPerBlock)
ssz.DefineSliceOfStaticObjectsContent(c, (*[]*Deposit)(&ds), constants.MaxDeposits)
})
c.DefineEncoder(func(*ssz.Encoder) {
ssz.DefineSliceOfStaticObjectsContent(
c, (*[]*Deposit)(&ds), constants.MaxDepositsPerBlock)
ssz.DefineSliceOfStaticObjectsContent(c, (*[]*Deposit)(&ds), constants.MaxDeposits)
})
c.DefineHasher(func(*ssz.Hasher) {
ssz.DefineSliceOfStaticObjectsOffset(
c, (*[]*Deposit)(&ds), constants.MaxDepositsPerBlock)
ssz.DefineSliceOfStaticObjectsOffset(c, (*[]*Deposit)(&ds), constants.MaxDeposits)
})
}

Expand Down
8 changes: 6 additions & 2 deletions primitives/constants/payload.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,12 @@ const (
// payload.
MaxTxsPerPayload uint64 = 1048576

// MaxDepositsPerBlock is the maximum number of deposits per block.
MaxDepositsPerBlock uint64 = 16
// DepositContractDepth is the depth of the deposit contract merkle tree.
DepositContractDepth uint64 = 32

// MaxDeposits is the maximum number of deposits supported by the
// deposit tree (2**32).
MaxDeposits uint64 = 1 << DepositContractDepth

// MaxWithdrawalsPerPayload is the maximum number of withdrawals in a
// execution payload.
Expand Down
7 changes: 7 additions & 0 deletions state-transition/core/core_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -227,3 +227,10 @@ func buildNextBlock(
Body: nextBlkBody,
}
}

// We verify DepositRoot in Eth1Data, but we don't really update
// the store once we store deposits (it's not StateProcessor responsibility).
// So we just keep using the dummyEth1Data most of the time.
var dummyEth1Data = &types.Eth1Data{
DepositRoot: types.Deposits(nil).HashTreeRoot(),
}
2 changes: 2 additions & 0 deletions state-transition/core/errors.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@ var (
// with the proposer reported by consensus.
ErrProposerMismatch = errors.New("proposer key mismatch")

ErrDepositsRootMismatch = errors.New("deposits root mismatch")

// ErrDepositsLengthMismatch is returned when length of deposits
// listed in block is different from deposits from store.
ErrDepositsLengthMismatch = errors.New("deposits lengths mismatched")
Expand Down
4 changes: 1 addition & 3 deletions state-transition/core/state/interfaces.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,9 +49,7 @@ type KVStore[T any] interface {
// GetEth1DepositIndex retrieves the eth1 deposit index.
GetEth1DepositIndex() (uint64, error)
// SetEth1DepositIndex sets the eth1 deposit index.
SetEth1DepositIndex(
index uint64,
) error
SetEth1DepositIndex(index uint64) error
// GetBalance retrieves the balance of a validator.
GetBalance(idx math.ValidatorIndex) (math.Gwei, error)
// SetBalance sets the balance of a validator.
Expand Down
2 changes: 1 addition & 1 deletion state-transition/core/state_processor_genesis.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ func (sp *StateProcessor[

var eth1Data *ctypes.Eth1Data
eth1Data = eth1Data.New(
common.Root{},
ctypes.Deposits(deposits).HashTreeRoot(),
0,
execPayloadHeader.GetBlockHash(),
)
Expand Down
8 changes: 6 additions & 2 deletions state-transition/core/state_processor_staking.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,15 +52,19 @@ func (sp *StateProcessor[
sp.cs.MaxDepositsPerBlock(), len(deposits),
)
}
if err := sp.validateNonGenesisDeposits(st, deposits); err != nil {
if err := sp.validateNonGenesisDeposits(
st,
deposits,
blk.GetBody().GetEth1Data().DepositRoot,
); err != nil {
return err
}
for _, dep := range deposits {
if err := sp.processDeposit(st, dep); err != nil {
return err
}
}
return nil
return st.SetEth1Data(blk.GetBody().Eth1Data)
}

// processDeposit processes the deposit and ensures it matches the local state.
Expand Down
36 changes: 19 additions & 17 deletions state-transition/core/state_processor_staking_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ func TestTransitionUpdateValidators(t *testing.T) {
},
BaseFeePerGas: math.NewU256(0),
},
Eth1Data: &types.Eth1Data{},
Eth1Data: dummyEth1Data,
Deposits: []*types.Deposit{blkDeposit},
},
)
Expand Down Expand Up @@ -159,7 +159,7 @@ func TestTransitionUpdateValidators(t *testing.T) {
},
BaseFeePerGas: math.NewU256(0),
},
Eth1Data: &types.Eth1Data{},
Eth1Data: dummyEth1Data,
Deposits: []*types.Deposit{},
},
)
Expand Down Expand Up @@ -247,7 +247,7 @@ func TestTransitionCreateValidator(t *testing.T) {
},
BaseFeePerGas: math.NewU256(0),
},
Eth1Data: &types.Eth1Data{},
Eth1Data: dummyEth1Data,
Deposits: []*types.Deposit{blkDeposit},
},
)
Expand Down Expand Up @@ -299,7 +299,7 @@ func TestTransitionCreateValidator(t *testing.T) {
},
BaseFeePerGas: math.NewU256(0),
},
Eth1Data: &types.Eth1Data{},
Eth1Data: dummyEth1Data,
Deposits: []*types.Deposit{},
},
)
Expand Down Expand Up @@ -343,7 +343,7 @@ func TestTransitionCreateValidator(t *testing.T) {
},
BaseFeePerGas: math.NewU256(0),
},
Eth1Data: &types.Eth1Data{},
Eth1Data: dummyEth1Data,
Deposits: []*types.Deposit{},
},
)
Expand Down Expand Up @@ -452,7 +452,7 @@ func TestTransitionWithdrawals(t *testing.T) {
},
BaseFeePerGas: math.NewU256(0),
},
Eth1Data: &types.Eth1Data{},
Eth1Data: dummyEth1Data,
Deposits: []*types.Deposit{},
},
)
Expand Down Expand Up @@ -548,7 +548,7 @@ func TestTransitionMaxWithdrawals(t *testing.T) {
},
BaseFeePerGas: math.NewU256(0),
},
Eth1Data: &types.Eth1Data{},
Eth1Data: dummyEth1Data,
Deposits: []*types.Deposit{},
},
)
Expand Down Expand Up @@ -594,7 +594,7 @@ func TestTransitionMaxWithdrawals(t *testing.T) {
},
BaseFeePerGas: math.NewU256(0),
},
Eth1Data: &types.Eth1Data{},
Eth1Data: dummyEth1Data,
Deposits: []*types.Deposit{},
},
)
Expand Down Expand Up @@ -688,7 +688,7 @@ func TestTransitionHittingValidatorsCap_ExtraSmall(t *testing.T) {
},
BaseFeePerGas: math.NewU256(0),
},
Eth1Data: &types.Eth1Data{},
Eth1Data: dummyEth1Data,
Deposits: []*types.Deposit{extraValDeposit},
},
)
Expand Down Expand Up @@ -740,7 +740,7 @@ func TestTransitionHittingValidatorsCap_ExtraSmall(t *testing.T) {
},
BaseFeePerGas: math.NewU256(0),
},
Eth1Data: &types.Eth1Data{},
Eth1Data: dummyEth1Data,
Deposits: []*types.Deposit{},
},
)
Expand Down Expand Up @@ -785,7 +785,7 @@ func TestTransitionHittingValidatorsCap_ExtraSmall(t *testing.T) {
},
BaseFeePerGas: math.NewU256(0),
},
Eth1Data: &types.Eth1Data{},
Eth1Data: dummyEth1Data,
Deposits: []*types.Deposit{},
},
)
Expand Down Expand Up @@ -828,7 +828,7 @@ func TestTransitionHittingValidatorsCap_ExtraSmall(t *testing.T) {
},
BaseFeePerGas: math.NewU256(0),
},
Eth1Data: &types.Eth1Data{},
Eth1Data: dummyEth1Data,
Deposits: []*types.Deposit{},
},
)
Expand Down Expand Up @@ -920,7 +920,7 @@ func TestTransitionHittingValidatorsCap_ExtraBig(t *testing.T) {
},
BaseFeePerGas: math.NewU256(0),
},
Eth1Data: &types.Eth1Data{},
Eth1Data: dummyEth1Data,
Deposits: []*types.Deposit{extraValDeposit},
},
)
Expand Down Expand Up @@ -989,7 +989,7 @@ func TestTransitionHittingValidatorsCap_ExtraBig(t *testing.T) {
},
BaseFeePerGas: math.NewU256(0),
},
Eth1Data: &types.Eth1Data{},
Eth1Data: dummyEth1Data,
Deposits: []*types.Deposit{},
},
)
Expand Down Expand Up @@ -1049,7 +1049,7 @@ func TestTransitionHittingValidatorsCap_ExtraBig(t *testing.T) {
},
BaseFeePerGas: math.NewU256(0),
},
Eth1Data: &types.Eth1Data{},
Eth1Data: dummyEth1Data,
Deposits: []*types.Deposit{},
},
)
Expand Down Expand Up @@ -1121,7 +1121,7 @@ func TestTransitionHittingValidatorsCap_ExtraBig(t *testing.T) {
},
BaseFeePerGas: math.NewU256(0),
},
Eth1Data: &types.Eth1Data{},
Eth1Data: dummyEth1Data,
Deposits: []*types.Deposit{},
},
)
Expand Down Expand Up @@ -1182,7 +1182,9 @@ func moveToEndOfEpoch(
},
BaseFeePerGas: math.NewU256(0),
},
Eth1Data: &types.Eth1Data{},
Eth1Data: &types.Eth1Data{
DepositRoot: types.Deposits(nil).HashTreeRoot(),
},
Deposits: []*types.Deposit{},
},
)
Expand Down
Loading

0 comments on commit bd74b71

Please sign in to comment.