Skip to content

Commit

Permalink
feat: rollback cmd
Browse files Browse the repository at this point in the history
add cometBFT's one block rollback cmd
  • Loading branch information
zsystm committed Oct 1, 2024
1 parent 0d090ff commit 4c9b10d
Show file tree
Hide file tree
Showing 4 changed files with 107 additions and 2 deletions.
43 changes: 43 additions & 0 deletions client/app/start.go
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,49 @@ func Start(ctx context.Context, cfg Config) (func(context.Context) error, error)
}, nil
}

func CreateApp(ctx context.Context, cfg Config) *App {
privVal, err := loadPrivVal(cfg)
if err != nil {
panic(errors.Wrap(err, "load validator key"))
}

db, err := dbm.NewDB("application", cfg.BackendType(), cfg.DataDir())
if err != nil {
panic(errors.Wrap(err, "create db"))
}

baseAppOpts, err := makeBaseAppOpts(cfg)
if err != nil {
panic(errors.Wrap(err, "make base app opts"))
}

engineCl, err := newEngineClient(ctx, cfg)
if err != nil {
panic(err)
}

//nolint:contextcheck // False positive
app, err := newApp(
newSDKLogger(ctx),
db,
engineCl,
baseAppOpts...,
)
if err != nil {
panic(errors.Wrap(err, "create app"))
}
app.Keepers.EVMEngKeeper.SetBuildDelay(cfg.EVMBuildDelay)
app.Keepers.EVMEngKeeper.SetBuildOptimistic(cfg.EVMBuildOptimistic)

addr, err := k1util.PubKeyToAddress(privVal.Key.PrivKey.PubKey())
if err != nil {
panic(errors.Wrap(err, "convert validator pubkey to address"))
}
app.Keepers.EVMEngKeeper.SetValidatorAddress(addr)

return app
}

func newCometNode(ctx context.Context, cfg *cmtcfg.Config, app *App, privVal cmttypes.PrivValidator,
) (*node.Node, error) {
nodeKey, err := p2p.LoadOrGenNodeKey(cfg.NodeKeyFile())
Expand Down
58 changes: 58 additions & 0 deletions client/cmd/cmd.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@ package cmd

import (
"context"
"fmt"

cmtcmd "github.com/cometbft/cometbft/cmd/cometbft/commands"
"github.com/spf13/cobra"

"github.com/piplabs/story/client/app"
Expand All @@ -23,6 +25,7 @@ func New() *cobra.Command {
buildinfo.NewVersionCmd(),
newValidatorCmds(),
newStatusCmd(),
newRollbackCmd(app.CreateApp),
)
}

Expand Down Expand Up @@ -60,3 +63,58 @@ func newRunCmd(name string, runFunc func(context.Context, app.Config) error) *co

return cmd
}

func newRollbackCmd(appCreateFunc func(context.Context, app.Config) *app.App) *cobra.Command {
storyCfg := storycfg.DefaultConfig()
logCfg := log.DefaultConfig()

cmd := &cobra.Command{
Use: "rollback",
Short: "rollback Cosmos SDK and CometBFT state by one height",
Long: `
A state rollback is performed to recover from an incorrect application state transition,
when CometBFT has persisted an incorrect app hash and is thus unable to make
progress. Rollback overwrites a state at height n with the state at height n - 1.
The application also rolls back to height n - 1. No blocks are removed, so upon
restarting CometBFT the transactions in block n will be re-executed against the
application.
`,
RunE: func(cmd *cobra.Command, _ []string) error {
ctx, err := log.Init(cmd.Context(), logCfg)
if err != nil {
return err
}
if err := libcmd.LogFlags(ctx, cmd.Flags()); err != nil {
return err
}

cometCfg, err := parseCometConfig(ctx, storyCfg.HomeDir)
if err != nil {
return err
}

app := appCreateFunc(ctx, app.Config{
Config: storyCfg,
Comet: cometCfg,
})
height, hash, err := cmtcmd.RollbackState(&cometCfg, storyCfg.RemoveBlock)
if err != nil {
return err
}

if err := app.CommitMultiStore().RollbackToVersion(height); err != nil {
return err
}

fmt.Printf("Rolled back state to height %d and hash %X", height, hash)
return nil
},
}

bindRunFlags(cmd, &storyCfg)
bindRollbackFlags(cmd, &storyCfg)
log.BindFlags(cmd.Flags(), &logCfg)

return cmd

}
4 changes: 4 additions & 0 deletions client/cmd/flags.go
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,10 @@ func bindStatusFlags(flags *pflag.FlagSet, cfg *StatusConfig) {
libcmd.BindHomeFlag(flags, &cfg.HomeDir)
}

func bindRollbackFlags(cmd *cobra.Command, cfg *config.Config) {
cmd.Flags().BoolVar(&cfg.RemoveBlock, "hard", false, "remove last block as well as state")
}

// Flag Validation

func validateFlags(flags map[string]string) error {
Expand Down
4 changes: 2 additions & 2 deletions client/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package config

import (
"bytes"
_ "embed"
"os"
"os/user"
"path/filepath"
Expand All @@ -19,8 +20,6 @@ import (
"github.com/piplabs/story/lib/log"
"github.com/piplabs/story/lib/netconf"
"github.com/piplabs/story/lib/tracer"

_ "embed"
)

const (
Expand Down Expand Up @@ -160,6 +159,7 @@ type Config struct {
ExternalAddress string
Seeds string
SeedMode bool
RemoveBlock bool // See cosmos-sdk/server/rollback.go
}

// ConfigFile returns the default path to the toml story config file.
Expand Down

0 comments on commit 4c9b10d

Please sign in to comment.