mirror of
https://github.com/OffchainLabs/prysm.git
synced 2026-01-09 21:38:05 -05:00
Compare commits
3 Commits
debug-col-
...
db-scale
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c2beb647dd | ||
|
|
35711cac8a | ||
|
|
9238e72a91 |
@@ -14,6 +14,7 @@ go_library(
|
||||
"genesis.go",
|
||||
"kv.go",
|
||||
"log.go",
|
||||
"migrate.go",
|
||||
"migration.go",
|
||||
"migration_archived_index.go",
|
||||
"migration_block_slot_index.go",
|
||||
@@ -40,6 +41,7 @@ go_library(
|
||||
"//beacon-chain/state/genesis:go_default_library",
|
||||
"//beacon-chain/state/v1:go_default_library",
|
||||
"//beacon-chain/state/v2:go_default_library",
|
||||
"//cmd:go_default_library",
|
||||
"//config/features:go_default_library",
|
||||
"//config/params:go_default_library",
|
||||
"//container/slice:go_default_library",
|
||||
@@ -63,6 +65,7 @@ go_library(
|
||||
"@com_github_prysmaticlabs_eth2_types//:go_default_library",
|
||||
"@com_github_prysmaticlabs_prombbolt//:go_default_library",
|
||||
"@com_github_sirupsen_logrus//:go_default_library",
|
||||
"@com_github_urfave_cli_v2//:go_default_library",
|
||||
"@io_etcd_go_bbolt//:go_default_library",
|
||||
"@io_opencensus_go//trace:go_default_library",
|
||||
"@org_golang_google_protobuf//proto:go_default_library",
|
||||
|
||||
241
beacon-chain/db/kv/migrate.go
Normal file
241
beacon-chain/db/kv/migrate.go
Normal file
@@ -0,0 +1,241 @@
|
||||
package kv
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"path"
|
||||
"time"
|
||||
|
||||
"github.com/ethereum/go-ethereum/common/hexutil"
|
||||
"github.com/golang/snappy"
|
||||
"github.com/prysmaticlabs/prysm/monitoring/progress"
|
||||
v1alpha1 "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1"
|
||||
bolt "go.etcd.io/bbolt"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/prysmaticlabs/prysm/cmd"
|
||||
"github.com/prysmaticlabs/prysm/io/file"
|
||||
"github.com/urfave/cli/v2"
|
||||
)
|
||||
|
||||
const batchSize = 10
|
||||
|
||||
var migrationStateKey = []byte("migration_state")
|
||||
|
||||
// MigrateStateDB normalizes the state object and saves space.
|
||||
// it also saves space by not storing the already stored elements in the
|
||||
// circular buffers.
|
||||
func MigrateStateDB(cliCtx *cli.Context) error {
|
||||
dataDir := cliCtx.String(cmd.DataDirFlag.Name)
|
||||
dbDir := path.Join(dataDir, BeaconNodeDbDirName)
|
||||
dbNameWithPath := path.Join(dbDir, DatabaseFileName)
|
||||
|
||||
// check if the database file exists
|
||||
if !file.FileExists(dbNameWithPath) {
|
||||
return errors.New(fmt.Sprintf("database file not found: %s", dbNameWithPath))
|
||||
}
|
||||
|
||||
// open the raw database file. If the file is busy, then exit.
|
||||
db, openErr := bolt.Open(dbNameWithPath, 0600, &bolt.Options{Timeout: 1 * time.Second})
|
||||
if openErr != nil {
|
||||
return errors.New(fmt.Sprintf("could not open db: , %v", openErr))
|
||||
}
|
||||
|
||||
|
||||
|
||||
yes, valErr := isValidatorEntriesAlreadyMigrated(db)
|
||||
if valErr != nil {
|
||||
return errors.New(fmt.Sprintf("could not check if entries migrated : , %v", valErr))
|
||||
}
|
||||
|
||||
if yes {
|
||||
migrateWithValidatorEntries(db)
|
||||
} else {
|
||||
migrateOnlyTheValidatorEntryHashes(db)
|
||||
}
|
||||
|
||||
log.Info("migration completed successfully")
|
||||
return nil
|
||||
}
|
||||
|
||||
func isValidatorEntriesAlreadyMigrated(db *bolt.DB) (bool, error) {
|
||||
// if the flag is not enabled, but the migration is over, then
|
||||
// follow the new code path as if the flag is enabled.
|
||||
returnFlag := false
|
||||
if err := db.View(func(tx *bolt.Tx) error {
|
||||
mb := tx.Bucket(migrationsBucket)
|
||||
b := mb.Get(migrationStateValidatorsKey)
|
||||
returnFlag = bytes.Equal(b, migrationCompleted)
|
||||
return nil
|
||||
}); err != nil {
|
||||
return returnFlag, err
|
||||
}
|
||||
return returnFlag, nil
|
||||
}
|
||||
|
||||
func migrateWithValidatorEntries(db *bolt.DB) error {
|
||||
// create the new buckets
|
||||
// - stateValidatorsBucket
|
||||
// - stateValidatorsHashesBucket
|
||||
if err := createNewBuckets(db, stateValidatorsBucket, stateValidatorHashesBucket); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// get the state bucket row count.
|
||||
// this is used to show the progress bar.
|
||||
keys, err := getStateBucketKeys(db)
|
||||
if err != nil{
|
||||
return err
|
||||
}
|
||||
|
||||
// prepare the progress bar with the total count of the keys to migrate
|
||||
bar := progress.InitializeProgressBar(len(keys), "Migrating state bucket to new schema.")
|
||||
|
||||
|
||||
// for each state, do in batches
|
||||
// - store the unique validator entries in stateValidatorsBucket
|
||||
// - get the ID for the validator entrypoint
|
||||
// compress all the validator entry IDs and store in the "validators" field in state
|
||||
batchNo := 0
|
||||
for batchIndex := 0; batchIndex < len(keys); batchIndex += batchSize {
|
||||
if err := db.Update(func(tx *bolt.Tx) error {
|
||||
//create the source and destination buckets
|
||||
stateBkt := tx.Bucket(stateBucket);
|
||||
if stateBkt == nil {
|
||||
return errors.New("could not open \"state\" bucket")
|
||||
}
|
||||
valEntryBkt := tx.Bucket(stateValidatorsBucket)
|
||||
if valEntryBkt == nil {
|
||||
return errors.New("could not open \"state-validators\" bucket")
|
||||
}
|
||||
valHashBkt := tx.Bucket(stateValidatorHashesBucket)
|
||||
if valHashBkt == nil {
|
||||
return errors.New("could not open \"state-validator-hashes\" bucket")
|
||||
}
|
||||
|
||||
// migrate the key values for this batch
|
||||
cursor := stateBkt.Cursor()
|
||||
count := 0
|
||||
index := batchIndex
|
||||
for _, v := cursor.Seek(keys[index]); count < batchSize && index < len(keys); _, v = cursor.Next() {
|
||||
enc, err := snappy.Decode(nil, v)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
protoState := &v1alpha1.BeaconState{}
|
||||
if err := protoState.UnmarshalSSZ(enc); err != nil {
|
||||
return errors.Wrap(err, "failed to unmarshal encoding for phase0")
|
||||
}
|
||||
// no validators in state to migrate
|
||||
if len(protoState.Validators) == 0 {
|
||||
return fmt.Errorf("no validator entries in state key 0x%s", hexutil.Encode(keys[index]))
|
||||
}
|
||||
|
||||
|
||||
validatorHashes, err := insertValidators(ctx, protoState.Validators, valEntryBkt)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
validaorIndexs, err := insertValidatorHashes(ctx, validatorHashes)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// add the validator entry indexes for a given block root.
|
||||
compValidatorIndexs := snappy.Encode(nil, validaorIndexs)
|
||||
|
||||
|
||||
// zero the validator entries in BeaconState object .
|
||||
protoState.Validators = make([]*v1alpha1.Validator, 0)
|
||||
rawObj, err := protoState.MarshalSSZ()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
stateBytes := snappy.Encode(nil, append(altairKey, rawObj...))
|
||||
if stateErr := stateBkt.Put(keys[index], stateBytes); stateErr != nil {
|
||||
return stateErr
|
||||
}
|
||||
|
||||
|
||||
// add the entry indexs in validator field of BeaconState object .
|
||||
protoState.Validators = compValidatorIndexs
|
||||
rawObj, err := protoState.MarshalSSZ()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
stateBytes, err := encode(ctx, compValidatorIndexs)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if stateErr := stateBkt.Put(keys[index], stateBytes); stateErr != nil {
|
||||
return stateErr
|
||||
}
|
||||
|
||||
count++
|
||||
index++
|
||||
|
||||
if barErr := bar.Add(1); barErr != nil {
|
||||
return barErr
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
batchNo++
|
||||
}
|
||||
|
||||
|
||||
// set the migration entry to done
|
||||
if err := db.Update(func(tx *bolt.Tx) error {
|
||||
mb := tx.Bucket(migrationsBucket)
|
||||
if mb == nil {
|
||||
return nil
|
||||
}
|
||||
return mb.Put(migrationStateKey, migrationCompleted)
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
log.Infof("migration done for bucket %s.", stateBucket)
|
||||
return nil
|
||||
|
||||
}
|
||||
|
||||
func migrateOnlyTheValidatorEntryHashes(db *bolt.DB) {
|
||||
|
||||
}
|
||||
|
||||
func createNewBuckets(db *bolt.DB, buckets ...[]byte) error {
|
||||
if err := db.Update(func(tx *bolt.Tx) error {
|
||||
for _, bucket := range buckets {
|
||||
if _, err := tx.CreateBucket(bucket); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func getStateBucketKeys(db *bolt.DB) ([][]byte, error){
|
||||
var keys [][]byte
|
||||
if err := db.Update(func(tx *bolt.Tx) error {
|
||||
stateBkt := tx.Bucket(stateBucket)
|
||||
if stateBkt == nil {
|
||||
return nil
|
||||
}
|
||||
k, err := stateBucketKeys(stateBkt)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
keys = k
|
||||
return nil
|
||||
}); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return keys, nil
|
||||
}
|
||||
@@ -35,6 +35,7 @@ var (
|
||||
attestationTargetEpochIndicesBucket = []byte("attestation-target-epoch-indices")
|
||||
finalizedBlockRootsIndexBucket = []byte("finalized-block-roots-index")
|
||||
blockRootValidatorHashesBucket = []byte("block-root-validator-hashes")
|
||||
stateValidatorHashesBucket = []byte("state-validator-hashes")
|
||||
|
||||
// Specific item keys.
|
||||
headBlockRootKey = []byte("head-root")
|
||||
|
||||
@@ -7,6 +7,7 @@ go_library(
|
||||
visibility = ["//visibility:public"],
|
||||
deps = [
|
||||
"//beacon-chain/db:go_default_library",
|
||||
"//beacon-chain/db/kv:go_default_library",
|
||||
"//cmd:go_default_library",
|
||||
"//runtime/tos:go_default_library",
|
||||
"@com_github_sirupsen_logrus//:go_default_library",
|
||||
|
||||
@@ -2,6 +2,7 @@ package db
|
||||
|
||||
import (
|
||||
beacondb "github.com/prysmaticlabs/prysm/beacon-chain/db"
|
||||
"github.com/prysmaticlabs/prysm/beacon-chain/db/kv"
|
||||
"github.com/prysmaticlabs/prysm/cmd"
|
||||
"github.com/prysmaticlabs/prysm/runtime/tos"
|
||||
"github.com/sirupsen/logrus"
|
||||
@@ -31,5 +32,19 @@ var Commands = &cli.Command{
|
||||
return nil
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "migrate-state",
|
||||
Description: `migrate the state database to a new format`,
|
||||
Flags: cmd.WrapFlags([]cli.Flag{
|
||||
cmd.DataDirFlag,
|
||||
}),
|
||||
Before: tos.VerifyTosAcceptedOrPrompt,
|
||||
Action: func(cliCtx *cli.Context) error {
|
||||
if err := kv.MigrateStateDB(cliCtx); err != nil {
|
||||
log.Fatalf("Could not migrate the database: %v", err)
|
||||
}
|
||||
return nil
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
32
proto/eth/wrapper/BUILD.bazel
Normal file
32
proto/eth/wrapper/BUILD.bazel
Normal file
@@ -0,0 +1,32 @@
|
||||
load("@rules_proto//proto:defs.bzl", "proto_library")
|
||||
load("@io_bazel_rules_go//proto:def.bzl", "go_proto_library")
|
||||
load("@prysm//tools/go:def.bzl", "go_library")
|
||||
|
||||
# gazelle:ignore
|
||||
proto_library(
|
||||
name = "proto",
|
||||
srcs = ["beacon_wrapper.proto"],
|
||||
visibility = ["//visibility:public"],
|
||||
deps = [
|
||||
"//proto/eth/v1:proto",
|
||||
"//proto/eth/v2:proto",
|
||||
],
|
||||
)
|
||||
|
||||
go_proto_library(
|
||||
name = "go_proto",
|
||||
importpath = "github.com/prysmaticlabs/prysm/proto/eth/wrapper",
|
||||
proto = ":proto",
|
||||
visibility = ["//visibility:public"],
|
||||
deps = [
|
||||
"//proto/eth/v1:go_default_library",
|
||||
"//proto/eth/v2:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
embed = [":go_proto"],
|
||||
importpath = "github.com/prysmaticlabs/prysm/proto/eth/wrapper",
|
||||
visibility = ["//visibility:public"],
|
||||
)
|
||||
230
proto/eth/wrapper/beacon_wrapper.pb.go
generated
Executable file
230
proto/eth/wrapper/beacon_wrapper.pb.go
generated
Executable file
@@ -0,0 +1,230 @@
|
||||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||
// versions:
|
||||
// protoc-gen-go v1.25.0
|
||||
// protoc v3.15.8
|
||||
// source: proto/eth/wrapper/beacon_wrapper.proto
|
||||
|
||||
package ethereum_eth_wrapper
|
||||
|
||||
import (
|
||||
reflect "reflect"
|
||||
sync "sync"
|
||||
|
||||
proto "github.com/golang/protobuf/proto"
|
||||
v1 "github.com/prysmaticlabs/prysm/proto/eth/v1"
|
||||
v2 "github.com/prysmaticlabs/prysm/proto/eth/v2"
|
||||
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
|
||||
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
|
||||
)
|
||||
|
||||
const (
|
||||
// Verify that this generated code is sufficiently up-to-date.
|
||||
_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
|
||||
// Verify that runtime/protoimpl is sufficiently up-to-date.
|
||||
_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
|
||||
)
|
||||
|
||||
// This is a compile-time assertion that a sufficiently up-to-date version
|
||||
// of the legacy proto package is being used.
|
||||
const _ = proto.ProtoPackageIsVersion4
|
||||
|
||||
type WrappedBeaconState struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
Version v2.Version `protobuf:"varint,1001,opt,name=version,proto3,enum=ethereum.eth.v2.Version" json:"version,omitempty"`
|
||||
ValidatorIndexes []byte `protobuf:"bytes,1002,opt,name=validatorIndexes,proto3" json:"validatorIndexes,omitempty"`
|
||||
// Types that are assignable to State:
|
||||
// *WrappedBeaconState_Phase0State
|
||||
// *WrappedBeaconState_AltairState
|
||||
State isWrappedBeaconState_State `protobuf_oneof:"state"`
|
||||
}
|
||||
|
||||
func (x *WrappedBeaconState) Reset() {
|
||||
*x = WrappedBeaconState{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_proto_eth_wrapper_beacon_wrapper_proto_msgTypes[0]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *WrappedBeaconState) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*WrappedBeaconState) ProtoMessage() {}
|
||||
|
||||
func (x *WrappedBeaconState) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_proto_eth_wrapper_beacon_wrapper_proto_msgTypes[0]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use WrappedBeaconState.ProtoReflect.Descriptor instead.
|
||||
func (*WrappedBeaconState) Descriptor() ([]byte, []int) {
|
||||
return file_proto_eth_wrapper_beacon_wrapper_proto_rawDescGZIP(), []int{0}
|
||||
}
|
||||
|
||||
func (x *WrappedBeaconState) GetVersion() v2.Version {
|
||||
if x != nil {
|
||||
return x.Version
|
||||
}
|
||||
return v2.Version_PHASE0
|
||||
}
|
||||
|
||||
func (x *WrappedBeaconState) GetValidatorIndexes() []byte {
|
||||
if x != nil {
|
||||
return x.ValidatorIndexes
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *WrappedBeaconState) GetState() isWrappedBeaconState_State {
|
||||
if m != nil {
|
||||
return m.State
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (x *WrappedBeaconState) GetPhase0State() *v1.BeaconState {
|
||||
if x, ok := x.GetState().(*WrappedBeaconState_Phase0State); ok {
|
||||
return x.Phase0State
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (x *WrappedBeaconState) GetAltairState() *v2.BeaconStateV2 {
|
||||
if x, ok := x.GetState().(*WrappedBeaconState_AltairState); ok {
|
||||
return x.AltairState
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type isWrappedBeaconState_State interface {
|
||||
isWrappedBeaconState_State()
|
||||
}
|
||||
|
||||
type WrappedBeaconState_Phase0State struct {
|
||||
Phase0State *v1.BeaconState `protobuf:"bytes,1,opt,name=phase0_state,json=phase0State,proto3,oneof"`
|
||||
}
|
||||
|
||||
type WrappedBeaconState_AltairState struct {
|
||||
AltairState *v2.BeaconStateV2 `protobuf:"bytes,2,opt,name=altair_state,json=altairState,proto3,oneof"`
|
||||
}
|
||||
|
||||
func (*WrappedBeaconState_Phase0State) isWrappedBeaconState_State() {}
|
||||
|
||||
func (*WrappedBeaconState_AltairState) isWrappedBeaconState_State() {}
|
||||
|
||||
var File_proto_eth_wrapper_beacon_wrapper_proto protoreflect.FileDescriptor
|
||||
|
||||
var file_proto_eth_wrapper_beacon_wrapper_proto_rawDesc = []byte{
|
||||
0x0a, 0x26, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x65, 0x74, 0x68, 0x2f, 0x77, 0x72, 0x61, 0x70,
|
||||
0x70, 0x65, 0x72, 0x2f, 0x62, 0x65, 0x61, 0x63, 0x6f, 0x6e, 0x5f, 0x77, 0x72, 0x61, 0x70, 0x70,
|
||||
0x65, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x14, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65,
|
||||
0x75, 0x6d, 0x2e, 0x65, 0x74, 0x68, 0x2e, 0x77, 0x72, 0x61, 0x70, 0x70, 0x65, 0x72, 0x1a, 0x1a,
|
||||
0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x65, 0x74, 0x68, 0x2f, 0x76, 0x32, 0x2f, 0x76, 0x65, 0x72,
|
||||
0x73, 0x69, 0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1f, 0x70, 0x72, 0x6f, 0x74,
|
||||
0x6f, 0x2f, 0x65, 0x74, 0x68, 0x2f, 0x76, 0x31, 0x2f, 0x62, 0x65, 0x61, 0x63, 0x6f, 0x6e, 0x5f,
|
||||
0x73, 0x74, 0x61, 0x74, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1f, 0x70, 0x72, 0x6f,
|
||||
0x74, 0x6f, 0x2f, 0x65, 0x74, 0x68, 0x2f, 0x76, 0x32, 0x2f, 0x62, 0x65, 0x61, 0x63, 0x6f, 0x6e,
|
||||
0x5f, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x87, 0x02, 0x0a,
|
||||
0x12, 0x57, 0x72, 0x61, 0x70, 0x70, 0x65, 0x64, 0x42, 0x65, 0x61, 0x63, 0x6f, 0x6e, 0x53, 0x74,
|
||||
0x61, 0x74, 0x65, 0x12, 0x33, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0xe9,
|
||||
0x07, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x18, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d,
|
||||
0x2e, 0x65, 0x74, 0x68, 0x2e, 0x76, 0x32, 0x2e, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x52,
|
||||
0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x2b, 0x0a, 0x10, 0x76, 0x61, 0x6c, 0x69,
|
||||
0x64, 0x61, 0x74, 0x6f, 0x72, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x65, 0x73, 0x18, 0xea, 0x07, 0x20,
|
||||
0x01, 0x28, 0x0c, 0x52, 0x10, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x49, 0x6e,
|
||||
0x64, 0x65, 0x78, 0x65, 0x73, 0x12, 0x41, 0x0a, 0x0c, 0x70, 0x68, 0x61, 0x73, 0x65, 0x30, 0x5f,
|
||||
0x73, 0x74, 0x61, 0x74, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x65, 0x74,
|
||||
0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x65, 0x74, 0x68, 0x2e, 0x76, 0x31, 0x2e, 0x42, 0x65,
|
||||
0x61, 0x63, 0x6f, 0x6e, 0x53, 0x74, 0x61, 0x74, 0x65, 0x48, 0x00, 0x52, 0x0b, 0x70, 0x68, 0x61,
|
||||
0x73, 0x65, 0x30, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x43, 0x0a, 0x0c, 0x61, 0x6c, 0x74, 0x61,
|
||||
0x69, 0x72, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1e,
|
||||
0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x65, 0x74, 0x68, 0x2e, 0x76, 0x32,
|
||||
0x2e, 0x42, 0x65, 0x61, 0x63, 0x6f, 0x6e, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x32, 0x48, 0x00,
|
||||
0x52, 0x0b, 0x61, 0x6c, 0x74, 0x61, 0x69, 0x72, 0x53, 0x74, 0x61, 0x74, 0x65, 0x42, 0x07, 0x0a,
|
||||
0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
|
||||
}
|
||||
|
||||
var (
|
||||
file_proto_eth_wrapper_beacon_wrapper_proto_rawDescOnce sync.Once
|
||||
file_proto_eth_wrapper_beacon_wrapper_proto_rawDescData = file_proto_eth_wrapper_beacon_wrapper_proto_rawDesc
|
||||
)
|
||||
|
||||
func file_proto_eth_wrapper_beacon_wrapper_proto_rawDescGZIP() []byte {
|
||||
file_proto_eth_wrapper_beacon_wrapper_proto_rawDescOnce.Do(func() {
|
||||
file_proto_eth_wrapper_beacon_wrapper_proto_rawDescData = protoimpl.X.CompressGZIP(file_proto_eth_wrapper_beacon_wrapper_proto_rawDescData)
|
||||
})
|
||||
return file_proto_eth_wrapper_beacon_wrapper_proto_rawDescData
|
||||
}
|
||||
|
||||
var file_proto_eth_wrapper_beacon_wrapper_proto_msgTypes = make([]protoimpl.MessageInfo, 1)
|
||||
var file_proto_eth_wrapper_beacon_wrapper_proto_goTypes = []interface{}{
|
||||
(*WrappedBeaconState)(nil), // 0: ethereum.eth.wrapper.WrappedBeaconState
|
||||
(v2.Version)(0), // 1: ethereum.eth.v2.Version
|
||||
(*v1.BeaconState)(nil), // 2: ethereum.eth.v1.BeaconState
|
||||
(*v2.BeaconStateV2)(nil), // 3: ethereum.eth.v2.BeaconStateV2
|
||||
}
|
||||
var file_proto_eth_wrapper_beacon_wrapper_proto_depIdxs = []int32{
|
||||
1, // 0: ethereum.eth.wrapper.WrappedBeaconState.version:type_name -> ethereum.eth.v2.Version
|
||||
2, // 1: ethereum.eth.wrapper.WrappedBeaconState.phase0_state:type_name -> ethereum.eth.v1.BeaconState
|
||||
3, // 2: ethereum.eth.wrapper.WrappedBeaconState.altair_state:type_name -> ethereum.eth.v2.BeaconStateV2
|
||||
3, // [3:3] is the sub-list for method output_type
|
||||
3, // [3:3] is the sub-list for method input_type
|
||||
3, // [3:3] is the sub-list for extension type_name
|
||||
3, // [3:3] is the sub-list for extension extendee
|
||||
0, // [0:3] is the sub-list for field type_name
|
||||
}
|
||||
|
||||
func init() { file_proto_eth_wrapper_beacon_wrapper_proto_init() }
|
||||
func file_proto_eth_wrapper_beacon_wrapper_proto_init() {
|
||||
if File_proto_eth_wrapper_beacon_wrapper_proto != nil {
|
||||
return
|
||||
}
|
||||
if !protoimpl.UnsafeEnabled {
|
||||
file_proto_eth_wrapper_beacon_wrapper_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*WrappedBeaconState); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
return &v.sizeCache
|
||||
case 2:
|
||||
return &v.unknownFields
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
}
|
||||
file_proto_eth_wrapper_beacon_wrapper_proto_msgTypes[0].OneofWrappers = []interface{}{
|
||||
(*WrappedBeaconState_Phase0State)(nil),
|
||||
(*WrappedBeaconState_AltairState)(nil),
|
||||
}
|
||||
type x struct{}
|
||||
out := protoimpl.TypeBuilder{
|
||||
File: protoimpl.DescBuilder{
|
||||
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
|
||||
RawDescriptor: file_proto_eth_wrapper_beacon_wrapper_proto_rawDesc,
|
||||
NumEnums: 0,
|
||||
NumMessages: 1,
|
||||
NumExtensions: 0,
|
||||
NumServices: 0,
|
||||
},
|
||||
GoTypes: file_proto_eth_wrapper_beacon_wrapper_proto_goTypes,
|
||||
DependencyIndexes: file_proto_eth_wrapper_beacon_wrapper_proto_depIdxs,
|
||||
MessageInfos: file_proto_eth_wrapper_beacon_wrapper_proto_msgTypes,
|
||||
}.Build()
|
||||
File_proto_eth_wrapper_beacon_wrapper_proto = out.File
|
||||
file_proto_eth_wrapper_beacon_wrapper_proto_rawDesc = nil
|
||||
file_proto_eth_wrapper_beacon_wrapper_proto_goTypes = nil
|
||||
file_proto_eth_wrapper_beacon_wrapper_proto_depIdxs = nil
|
||||
}
|
||||
16
proto/eth/wrapper/beacon_wrapper.proto
Normal file
16
proto/eth/wrapper/beacon_wrapper.proto
Normal file
@@ -0,0 +1,16 @@
|
||||
syntax = "proto3";
|
||||
|
||||
package ethereum.eth.wrapper;
|
||||
|
||||
import "proto/eth/v2/version.proto";
|
||||
import "proto/eth/v1/beacon_state.proto";
|
||||
import "proto/eth/v2/beacon_state.proto";
|
||||
|
||||
message WrappedBeaconState {
|
||||
v2.Version version = 1001;
|
||||
bytes validatorIndexes = 1002;
|
||||
oneof state {
|
||||
v1.BeaconState phase0_state = 1;
|
||||
v2.BeaconStateV2 altair_state = 2;
|
||||
}
|
||||
}
|
||||
@@ -101,6 +101,8 @@ func main() {
|
||||
default:
|
||||
log.Fatal("Oops, given bucket is supported for now.")
|
||||
}
|
||||
case "growth":
|
||||
printBucketGrowth(dbNameWithPath, *bucketName)
|
||||
case "migration-check":
|
||||
destDbNameWithPath := filepath.Join(*destDatadir, *dbName)
|
||||
if _, err := os.Stat(destDbNameWithPath); os.IsNotExist(err) {
|
||||
@@ -445,6 +447,49 @@ func checkValidatorMigration(dbNameWithPath, destDbNameWithPath string) {
|
||||
log.Infof("number of state that did not match: %d", failCount)
|
||||
}
|
||||
|
||||
func printBucketGrowth(dbNameWithPath, bucketName string) {
|
||||
// open the raw database file. If the file is busy, then exit.
|
||||
db, openErr := bolt.Open(dbNameWithPath, 0600, &bolt.Options{Timeout: 1 * time.Second})
|
||||
if openErr != nil {
|
||||
log.Fatalf("could not open db while getting keys of a bucket, %v", openErr)
|
||||
}
|
||||
|
||||
// make sure we close the database before ejecting out of this function.
|
||||
defer func() {
|
||||
closeErr := db.Close()
|
||||
if closeErr != nil {
|
||||
log.Fatalf("could not close db while getting keys of a bucket, %v", closeErr)
|
||||
}
|
||||
}()
|
||||
|
||||
// get all the keys of the given bucket.
|
||||
var keys [][]byte
|
||||
var sizes []uint64
|
||||
if viewErr := db.View(func(tx *bolt.Tx) error {
|
||||
b := tx.Bucket([]byte(bucketName))
|
||||
c := b.Cursor()
|
||||
count := uint64(0)
|
||||
for k, v := c.First(); k != nil; k, v = c.Next() {
|
||||
actualKey := make([]byte, len(k))
|
||||
actualSizes := make([]byte, len(v))
|
||||
copy(actualKey, k)
|
||||
copy(actualSizes, v)
|
||||
keys = append(keys, actualKey)
|
||||
sizes = append(sizes, uint64(len(v)))
|
||||
count++
|
||||
|
||||
if count%25000 == 0 {
|
||||
log.Infof(" row = %d, vale sizes = %d", count, sizes)
|
||||
}
|
||||
|
||||
}
|
||||
return nil
|
||||
}); viewErr != nil {
|
||||
log.Fatalf("could not read keys of bucket from db: %v", viewErr)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
func keysOfBucket(dbNameWithPath string, bucketName []byte, rowLimit uint64) ([][]byte, []uint64) {
|
||||
// open the raw database file. If the file is busy, then exit.
|
||||
db, openErr := bolt.Open(dbNameWithPath, 0600, &bolt.Options{Timeout: 1 * time.Second})
|
||||
|
||||
Reference in New Issue
Block a user