feat!: bootstrap comet cmd for local state sync (#16061)

Co-authored-by: Aleksandr Bezobchuk <alexanderbez@users.noreply.github.com>
Co-authored-by: HuangYi <huang@crypto.com>
This commit is contained in:
Marko
2023-05-10 10:25:07 +00:00
committed by GitHub
co-authored by Aleksandr Bezobchuk HuangYi
parent 7e160b0e85
commit 25df90d0fc
4 changed files with 112 additions and 0 deletions
+98
View File
@@ -5,8 +5,15 @@ import (
"strconv"
"strings"
"cosmossdk.io/log"
"github.com/cometbft/cometbft/light"
"github.com/cometbft/cometbft/node"
"github.com/cometbft/cometbft/p2p"
pvm "github.com/cometbft/cometbft/privval"
cmtstore "github.com/cometbft/cometbft/proto/tendermint/store"
sm "github.com/cometbft/cometbft/state"
"github.com/cometbft/cometbft/statesync"
"github.com/cometbft/cometbft/store"
cmtversion "github.com/cometbft/cometbft/version"
"github.com/spf13/cobra"
"sigs.k8s.io/yaml"
@@ -15,6 +22,8 @@ import (
"github.com/cosmos/cosmos-sdk/client/flags"
rpc "github.com/cosmos/cosmos-sdk/client/rpc"
cryptocodec "github.com/cosmos/cosmos-sdk/crypto/codec"
servercmtlog "github.com/cosmos/cosmos-sdk/server/log"
"github.com/cosmos/cosmos-sdk/server/types"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/types/query"
"github.com/cosmos/cosmos-sdk/version"
@@ -249,3 +258,92 @@ $ %s query block --%s=%s <hash>
return cmd
}
func BootstrapStateCmd(appCreator types.AppCreator) *cobra.Command {
cmd := &cobra.Command{
Use: "bootstrap-state",
Short: "Bootstrap CometBFT state at an arbitrary block height using a light client",
Args: cobra.NoArgs,
RunE: func(cmd *cobra.Command, args []string) error {
serverCtx := GetServerContextFromCmd(cmd)
logger := log.NewLogger(cmd.OutOrStdout())
cfg := serverCtx.Config
height, err := cmd.Flags().GetInt64("height")
if err != nil {
return err
}
if height == 0 {
home := serverCtx.Viper.GetString(flags.FlagHome)
db, err := openDB(home, GetAppDBBackend(serverCtx.Viper))
if err != nil {
return err
}
app := appCreator(logger, db, nil, serverCtx.Viper)
height = app.CommitMultiStore().LastCommitID().Version
}
blockStoreDB, err := node.DefaultDBProvider(&node.DBContext{ID: "blockstore", Config: cfg})
if err != nil {
return err
}
blockStore := store.NewBlockStore(blockStoreDB)
stateDB, err := node.DefaultDBProvider(&node.DBContext{ID: "state", Config: cfg})
if err != nil {
return err
}
stateStore := sm.NewStore(stateDB, sm.StoreOptions{
DiscardABCIResponses: cfg.Storage.DiscardABCIResponses,
})
genState, _, err := node.LoadStateFromDBOrGenesisDocProvider(stateDB, node.DefaultGenesisDocProviderFunc(cfg))
if err != nil {
return err
}
stateProvider, err := statesync.NewLightClientStateProvider(
cmd.Context(),
genState.ChainID, genState.Version, genState.InitialHeight,
cfg.StateSync.RPCServers, light.TrustOptions{
Period: cfg.StateSync.TrustPeriod,
Height: cfg.StateSync.TrustHeight,
Hash: cfg.StateSync.TrustHashBytes(),
}, servercmtlog.CometLoggerWrapper{Logger: logger.With("module", "light")})
if err != nil {
return fmt.Errorf("failed to set up light client state provider: %w", err)
}
state, err := stateProvider.State(cmd.Context(), uint64(height))
if err != nil {
return fmt.Errorf("failed to get state: %w", err)
}
commit, err := stateProvider.Commit(cmd.Context(), uint64(height))
if err != nil {
return fmt.Errorf("failed to get commit: %w", err)
}
if err := stateStore.Bootstrap(state); err != nil {
return fmt.Errorf("failed to bootstrap state: %w", err)
}
if err := blockStore.SaveSeenCommit(state.LastBlockHeight, commit); err != nil {
return fmt.Errorf("failed to save seen commit: %w", err)
}
store.SaveBlockStoreState(&cmtstore.BlockStoreState{
// it breaks the invariant that blocks in range [Base, Height] must exists, but it do works in practice.
Base: state.LastBlockHeight,
Height: state.LastBlockHeight,
}, blockStoreDB)
return nil
},
}
cmd.Flags().Int64("height", 0, "Block height to bootstrap state at, if not provided will use the latest block height in app state")
return cmd
}
+1
View File
@@ -320,6 +320,7 @@ func AddCommands(rootCmd *cobra.Command, defaultNodeHome string, appCreator type
VersionCmd(),
cmtcmd.ResetAllCmd,
cmtcmd.ResetStateCmd,
BootstrapStateCmd(appCreator),
)
startCmd := StartCmd(appCreator, defaultNodeHome)