cli: add db reset command

Close #2576.
This commit is contained in:
Anna Shaleva 2022-10-20 13:59:35 +03:00
parent bd6bb9e9e2
commit 30cfe4d8c8
3 changed files with 69 additions and 1 deletions

View file

@ -73,6 +73,13 @@ func NewCommands() []cli.Command {
Usage: "use if dump is incremental", Usage: "use if dump is incremental",
}, },
) )
var cfgHeightFlags = make([]cli.Flag, len(cfgFlags)+1)
copy(cfgHeightFlags, cfgFlags)
cfgHeightFlags[len(cfgHeightFlags)-1] = cli.UintFlag{
Name: "height",
Usage: "Height of the state to reset DB to",
Required: true,
}
return []cli.Command{ return []cli.Command{
{ {
Name: "node", Name: "node",
@ -99,6 +106,13 @@ func NewCommands() []cli.Command {
Action: restoreDB, Action: restoreDB,
Flags: cfgCountInFlags, Flags: cfgCountInFlags,
}, },
{
Name: "reset",
Usage: "reset database to the previous state",
UsageText: "neo-go db reset --height height [--config-path path] [-p/-m/-t]",
Action: resetDB,
Flags: cfgHeightFlags,
},
}, },
}, },
} }
@ -302,6 +316,35 @@ func restoreDB(ctx *cli.Context) error {
return nil return nil
} }
func resetDB(ctx *cli.Context) error {
if err := cmdargs.EnsureNone(ctx); err != nil {
return err
}
cfg, err := options.GetConfigFromContext(ctx)
if err != nil {
return cli.NewExitError(err, 1)
}
h := uint32(ctx.Uint("height"))
log, logCloser, err := options.HandleLoggingParams(ctx.Bool("debug"), cfg.ApplicationConfiguration)
if err != nil {
return cli.NewExitError(err, 1)
}
if logCloser != nil {
defer func() { _ = logCloser() }()
}
chain, err := initBlockChain(cfg, log)
if err != nil {
return cli.NewExitError(fmt.Errorf("failed to create Blockchain instance: %w", err), 1)
}
err = chain.Reset(h)
if err != nil {
return cli.NewExitError(fmt.Errorf("failed to reset chain state to height %d: %w", h, err), 1)
}
return nil
}
func mkOracle(config config.OracleConfiguration, magic netmode.Magic, chain *core.Blockchain, serv *network.Server, log *zap.Logger) (*oracle.Oracle, error) { func mkOracle(config config.OracleConfiguration, magic netmode.Magic, chain *core.Blockchain, serv *network.Server, log *zap.Logger) (*oracle.Oracle, error) {
if !config.Enabled { if !config.Enabled {
return nil, nil return nil, nil

View file

@ -351,3 +351,18 @@ func TestInitBlockChain(t *testing.T) {
require.Error(t, err) require.Error(t, err)
}) })
} }
func TestResetDB(t *testing.T) {
d := t.TempDir()
err := os.Chdir(d)
require.NoError(t, err)
t.Cleanup(func() { require.NoError(t, os.Chdir(serverTestWD)) })
set := flag.NewFlagSet("flagSet", flag.ExitOnError)
set.String("config-path", filepath.Join(serverTestWD, "..", "..", "config"), "")
set.Bool("privnet", true, "")
set.Bool("debug", true, "")
set.Int("height", 0, "")
ctx := cli.NewContext(cli.NewApp(), set, nil)
err = resetDB(ctx)
require.NoError(t, err)
}

View file

@ -89,13 +89,23 @@ Typical scenarios when this can be useful (without full node restart):
* updating TLS certificates for the RPC server * updating TLS certificates for the RPC server
* resolving operational issues * resolving operational issues
### DB import/exports ### DB import/exports/reset
Node operates using some database as a backend to store blockchain data. NeoGo Node operates using some database as a backend to store blockchain data. NeoGo
allows to dump chain into a file from the database (when node is stopped) or to allows to dump chain into a file from the database (when node is stopped) or to
import blocks from a file into the database (also when node is stopped). Use import blocks from a file into the database (also when node is stopped). Use
`db` command for that. `db` command for that.
NeoGo allows to reset the node state to a particular point. It is possible for
those nodes that do store complete chain state or for nodes with `RemoveUntraceableBlocks`
setting on that are not yet reached `MaxTraceableBlocks` number of blocks. Use
`db reset` command with the target block specified to roll back all the changes
made since the target block (not including changes made by the specified block
acceptance). The set of changes to be removed includes blocks, transactions,
execution results, contract storage changes, MPT-related auxiliary data and NEP
transfers data. Some stale MPT nodes may be left in storage after reset.
Once DB reset is finished, the node can be started in a regular manner.
## Smart contracts ## Smart contracts
Use `contract` command to create/compile/deploy/invoke/debug smart contracts, Use `contract` command to create/compile/deploy/invoke/debug smart contracts,