forked from TrueCloudLab/neoneo-go
vm: add 'env' command showing state of the blockchain-backed VM CLI
A useful one.
This commit is contained in:
parent
f1ecdb82cc
commit
0036c89d63
2 changed files with 69 additions and 0 deletions
|
@ -39,6 +39,7 @@ import (
|
||||||
|
|
||||||
const (
|
const (
|
||||||
chainKey = "chain"
|
chainKey = "chain"
|
||||||
|
chainCfgKey = "chainCfg"
|
||||||
icKey = "ic"
|
icKey = "ic"
|
||||||
manifestKey = "manifest"
|
manifestKey = "manifest"
|
||||||
exitFuncKey = "exitFunc"
|
exitFuncKey = "exitFunc"
|
||||||
|
@ -51,6 +52,11 @@ const (
|
||||||
stringType = "string"
|
stringType = "string"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// Various flag names.
|
||||||
|
const (
|
||||||
|
verboseFlagFullName = "verbose"
|
||||||
|
)
|
||||||
|
|
||||||
var commands = []cli.Command{
|
var commands = []cli.Command{
|
||||||
{
|
{
|
||||||
Name: "exit",
|
Name: "exit",
|
||||||
|
@ -231,6 +237,24 @@ example:
|
||||||
Description: "Dump events emitted by the current loaded program",
|
Description: "Dump events emitted by the current loaded program",
|
||||||
Action: handleEvents,
|
Action: handleEvents,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
Name: "env",
|
||||||
|
Usage: "Dump state of the chain that is used for VM CLI invocations (use -v for verbose node configuration)",
|
||||||
|
UsageText: `env [-v]`,
|
||||||
|
Flags: []cli.Flag{
|
||||||
|
cli.BoolFlag{
|
||||||
|
Name: verboseFlagFullName + ",v",
|
||||||
|
Usage: "Print the whole blockchain node configuration.",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Description: `env [-v]
|
||||||
|
|
||||||
|
Dump state of the chain that is used for VM CLI invocations (use -v for verbose node configuration).
|
||||||
|
|
||||||
|
Example:
|
||||||
|
> env -v`,
|
||||||
|
Action: handleEnv,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
var completer *readline.PrefixCompleter
|
var completer *readline.PrefixCompleter
|
||||||
|
@ -318,6 +342,7 @@ func NewWithConfig(printLogotype bool, onExit func(int), c *readline.Config, cfg
|
||||||
|
|
||||||
vmcli.shell.Metadata = map[string]interface{}{
|
vmcli.shell.Metadata = map[string]interface{}{
|
||||||
chainKey: chain,
|
chainKey: chain,
|
||||||
|
chainCfgKey: cfg,
|
||||||
icKey: ic,
|
icKey: ic,
|
||||||
manifestKey: new(manifest.Manifest),
|
manifestKey: new(manifest.Manifest),
|
||||||
exitFuncKey: exitF,
|
exitFuncKey: exitF,
|
||||||
|
@ -344,6 +369,10 @@ func getChainFromContext(app *cli.App) *core.Blockchain {
|
||||||
return app.Metadata[chainKey].(*core.Blockchain)
|
return app.Metadata[chainKey].(*core.Blockchain)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func getChainConfigFromContext(app *cli.App) config.Config {
|
||||||
|
return app.Metadata[chainCfgKey].(config.Config)
|
||||||
|
}
|
||||||
|
|
||||||
func getInteropContextFromContext(app *cli.App) *interop.Context {
|
func getInteropContextFromContext(app *cli.App) *interop.Context {
|
||||||
return app.Metadata[icKey].(*interop.Context)
|
return app.Metadata[icKey].(*interop.Context)
|
||||||
}
|
}
|
||||||
|
@ -764,6 +793,21 @@ func handleEvents(c *cli.Context) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func handleEnv(c *cli.Context) error {
|
||||||
|
bc := getChainFromContext(c.App)
|
||||||
|
cfg := getChainConfigFromContext(c.App)
|
||||||
|
message := fmt.Sprintf("Chain height: %d\nNetwork magic: %d\nDB type: %s\n", bc.BlockHeight(), bc.GetConfig().Magic, cfg.ApplicationConfiguration.DBConfiguration.Type)
|
||||||
|
if c.Bool(verboseFlagFullName) {
|
||||||
|
cfgBytes, err := json.MarshalIndent(cfg, "", "\t")
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("failed to marshal node configuration: %w", err)
|
||||||
|
}
|
||||||
|
message += "Node config:\n" + string(cfgBytes) + "\n"
|
||||||
|
}
|
||||||
|
fmt.Fprint(c.App.Writer, message)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func dumpEvents(app *cli.App) (string, error) {
|
func dumpEvents(app *cli.App) (string, error) {
|
||||||
ic := getInteropContextFromContext(app)
|
ic := getInteropContextFromContext(app)
|
||||||
if len(ic.Notifications) == 0 {
|
if len(ic.Notifications) == 0 {
|
||||||
|
|
|
@ -786,3 +786,28 @@ func TestEvents(t *testing.T) {
|
||||||
e.checkEvents(t, true, expectedEvent) // automatically printed after `run` command
|
e.checkEvents(t, true, expectedEvent) // automatically printed after `run` command
|
||||||
e.checkEvents(t, false, expectedEvent) // printed after `events` command
|
e.checkEvents(t, false, expectedEvent) // printed after `events` command
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestEnv(t *testing.T) {
|
||||||
|
t.Run("default setup", func(t *testing.T) {
|
||||||
|
e := newTestVMCLI(t)
|
||||||
|
e.runProg(t, "env")
|
||||||
|
e.checkNextLine(t, "Chain height: 0")
|
||||||
|
e.checkNextLine(t, "Network magic: 42")
|
||||||
|
e.checkNextLine(t, "DB type: inmemory")
|
||||||
|
})
|
||||||
|
t.Run("setup with state", func(t *testing.T) {
|
||||||
|
e := newTestVMClIWithState(t)
|
||||||
|
e.runProg(t, "env")
|
||||||
|
e.checkNextLine(t, "Chain height: 5")
|
||||||
|
e.checkNextLine(t, "Network magic: 42")
|
||||||
|
e.checkNextLine(t, "DB type: leveldb")
|
||||||
|
})
|
||||||
|
t.Run("verbose", func(t *testing.T) {
|
||||||
|
e := newTestVMClIWithState(t)
|
||||||
|
e.runProg(t, "env -v")
|
||||||
|
e.checkNextLine(t, "Chain height: 5")
|
||||||
|
e.checkNextLine(t, "Network magic: 42")
|
||||||
|
e.checkNextLine(t, "DB type: leveldb")
|
||||||
|
e.checkNextLine(t, "Node config:") // Do not check exact node config.
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue