2022-01-20 07:34:50 +00:00
// Package app contains framework for building a command-line based Erigon node.
package app
2020-09-05 16:07:27 +00:00
import (
2023-04-27 03:42:12 +00:00
"fmt"
2022-11-15 20:38:31 +00:00
"strings"
2022-11-20 03:41:30 +00:00
"github.com/ledgerwatch/erigon-lib/common/datadir"
2023-05-05 02:36:02 +00:00
"github.com/ledgerwatch/erigon/turbo/logging"
2023-04-27 03:42:12 +00:00
"github.com/ledgerwatch/log/v3"
2022-11-14 16:33:57 +00:00
"github.com/urfave/cli/v2"
2022-10-31 10:46:49 +00:00
2021-09-07 06:44:40 +00:00
"github.com/ledgerwatch/erigon/cmd/utils"
"github.com/ledgerwatch/erigon/node"
2022-05-26 05:27:44 +00:00
"github.com/ledgerwatch/erigon/node/nodecfg"
2021-09-07 06:44:40 +00:00
"github.com/ledgerwatch/erigon/params"
2022-10-25 02:58:25 +00:00
cli2 "github.com/ledgerwatch/erigon/turbo/cli"
"github.com/ledgerwatch/erigon/turbo/debug"
2020-09-05 16:07:27 +00:00
)
2020-09-21 14:10:25 +00:00
// MakeApp creates a cli application (based on `github.com/urlfave/cli` package).
// The application exits when `action` returns.
// Parameters:
2022-11-14 16:33:57 +00:00
// * action: the main function for the application. receives `*cli.Context` with parsed command-line flags.
2020-09-21 14:10:25 +00:00
// * cliFlags: the list of flags `cli.Flag` that the app should set and parse. By default, use `DefaultFlags()`. If you want to specify your own flag, use `append(DefaultFlags(), myFlag)` for this parameter.
2023-04-27 03:42:12 +00:00
func MakeApp ( name string , action cli . ActionFunc , cliFlags [ ] cli . Flag ) * cli . App {
app := cli2 . NewApp ( params . GitCommit , "erigon" )
app . Name = name
app . UsageText = app . Name + ` [command] [flags] `
app . Action = func ( context * cli . Context ) error {
// handle case: unknown sub-command
if context . Args ( ) . Present ( ) {
var goodNames [ ] string
for _ , c := range app . VisibleCommands ( ) {
goodNames = append ( goodNames , c . Name )
}
log . Error ( fmt . Sprintf ( "Command '%s' not found. Available commands: %s" , context . Args ( ) . First ( ) , goodNames ) )
cli . ShowAppHelpAndExit ( context , 1 )
}
// run default action
return action ( context )
}
2020-09-05 16:07:27 +00:00
app . Flags = append ( cliFlags , debug . Flags ... ) // debug flags are required
2023-05-04 13:18:42 +00:00
app . Flags = append ( app . Flags , utils . MetricFlags ... )
2023-05-05 02:36:02 +00:00
app . Flags = append ( app . Flags , logging . Flags ... )
2023-08-08 23:21:19 +00:00
2020-09-05 16:07:27 +00:00
app . After = func ( ctx * cli . Context ) error {
debug . Exit ( )
return nil
}
2023-04-27 03:42:12 +00:00
app . Commands = [ ] * cli . Command {
& initCommand ,
& importCommand ,
& snapshotCommand ,
& supportCommand ,
2023-05-02 06:06:22 +00:00
//&backupCommand,
2023-04-27 03:42:12 +00:00
}
2020-09-05 16:07:27 +00:00
return app
}
2021-09-07 06:44:40 +00:00
2022-11-15 20:38:31 +00:00
// MigrateFlags makes all global flag values available in the
// context. This should be called as early as possible in app.Before.
//
// Example:
//
// geth account new --keystore /tmp/mykeystore --lightkdf
//
// is equivalent after calling this method with:
//
// geth --keystore /tmp/mykeystore --lightkdf account new
//
// i.e. in the subcommand Action function of 'account new', ctx.Bool("lightkdf)
// will return true even if --lightkdf is set as a global option.
//
// This function may become unnecessary when https://github.com/urfave/cli/pull/1245 is merged.
func MigrateFlags ( action cli . ActionFunc ) cli . ActionFunc {
return func ( ctx * cli . Context ) error {
doMigrateFlags ( ctx )
return action ( ctx )
}
}
func doMigrateFlags ( ctx * cli . Context ) {
// Figure out if there are any aliases of commands. If there are, we want
// to ignore them when iterating over the flags.
var aliases = make ( map [ string ] bool )
for _ , fl := range ctx . Command . Flags {
for _ , alias := range fl . Names ( ) [ 1 : ] {
aliases [ alias ] = true
}
}
for _ , name := range ctx . FlagNames ( ) {
for _ , parent := range ctx . Lineage ( ) [ 1 : ] {
if parent . IsSet ( name ) {
// When iterating across the lineage, we will be served both
// the 'canon' and alias formats of all commands. In most cases,
// it's fine to set it in the ctx multiple times (one for each
// name), however, the Slice-flags are not fine.
// The slice-flags accumulate, so if we set it once as
// "foo" and once as alias "F", then both will be present in the slice.
if _ , isAlias := aliases [ name ] ; isAlias {
continue
}
// If it is a string-slice, we need to set it as
// "alfa, beta, gamma" instead of "[alfa beta gamma]", in order
// for the backing StringSlice to parse it properly.
if result := parent . StringSlice ( name ) ; len ( result ) > 0 {
ctx . Set ( name , strings . Join ( result , "," ) )
} else {
ctx . Set ( name , parent . String ( name ) )
}
break
}
}
}
}
2022-05-26 05:27:44 +00:00
func NewNodeConfig ( ctx * cli . Context ) * nodecfg . Config {
nodeConfig := nodecfg . DefaultConfig
2021-09-07 06:44:40 +00:00
// see simiar changes in `cmd/geth/config.go#defaultNodeConfig`
if commit := params . GitCommit ; commit != "" {
2023-02-13 05:17:01 +00:00
nodeConfig . Version = params . VersionWithCommit ( commit )
2021-09-07 06:44:40 +00:00
} else {
nodeConfig . Version = params . Version
}
2021-09-08 08:25:10 +00:00
nodeConfig . IPCPath = "" // force-disable IPC endpoint
2021-09-07 06:44:40 +00:00
nodeConfig . Name = "erigon"
2022-11-14 16:33:57 +00:00
if ctx . IsSet ( utils . DataDirFlag . Name ) {
nodeConfig . Dirs = datadir . New ( ctx . String ( utils . DataDirFlag . Name ) )
2021-09-07 06:44:40 +00:00
}
return & nodeConfig
}
2023-05-07 06:28:15 +00:00
func MakeConfigNodeDefault ( ctx * cli . Context , logger log . Logger ) * node . Node {
return makeConfigNode ( NewNodeConfig ( ctx ) , logger )
2021-09-07 06:44:40 +00:00
}
2023-05-07 06:28:15 +00:00
func makeConfigNode ( config * nodecfg . Config , logger log . Logger ) * node . Node {
stack , err := node . New ( config , logger )
2021-09-07 06:44:40 +00:00
if err != nil {
utils . Fatalf ( "Failed to create Erigon node: %v" , err )
}
return stack
}