From a54cec4595d9649d21d28daf7247379b4173eb65 Mon Sep 17 00:00:00 2001 From: Ferran Borreguero Date: Wed, 22 Sep 2021 08:53:30 +0200 Subject: [PATCH 01/51] Initial spec for an alternative cli --- command/flagset/flagset.go | 95 +++++++++++++++++++++++++ command/main.go | 45 ++++++++++++ command/server/command.go | 137 +++++++++++++++++++++++++++++++++++++ command/server/config.go | 127 ++++++++++++++++++++++++++++++++++ command/server/flags.go | 32 +++++++++ go.mod | 2 + go.sum | 30 +++++++- 7 files changed, 467 insertions(+), 1 deletion(-) create mode 100644 command/flagset/flagset.go create mode 100644 command/main.go create mode 100644 command/server/command.go create mode 100644 command/server/config.go create mode 100644 command/server/flags.go diff --git a/command/flagset/flagset.go b/command/flagset/flagset.go new file mode 100644 index 0000000000..47327ca6d3 --- /dev/null +++ b/command/flagset/flagset.go @@ -0,0 +1,95 @@ +package flagset + +import ( + "flag" + "fmt" + "strings" +) + +type Flagset struct { + flags []*FlagVar + set *flag.FlagSet +} + +func NewFlagSet(name string) *Flagset { + f := &Flagset{ + flags: []*FlagVar{}, + set: flag.NewFlagSet(name, flag.ContinueOnError), + } + return f +} + +type FlagVar struct { + Name string + Usage string +} + +func (f *Flagset) addFlag(fl *FlagVar) { + f.flags = append(f.flags, fl) +} + +func (f *Flagset) Help() string { + str := "Options:\n\n" + items := []string{} + for _, item := range f.flags { + items = append(items, fmt.Sprintf(" -%s\n %s", item.Name, item.Usage)) + } + return str + strings.Join(items, "\n\n") +} + +func (f *Flagset) Parse(args []string) error { + return f.set.Parse(args) +} + +func (f *Flagset) Args() []string { + return f.set.Args() +} + +func (f *Flagset) BoolVar() { + +} + +type BoolFlag struct { + Name string + Usage string + Default bool + Value *bool +} + +func (f *Flagset) BoolFlag(b *BoolFlag) { + f.addFlag(&FlagVar{ + Name: b.Name, + Usage: b.Usage, + }) + f.set.BoolVar(b.Value, b.Name, b.Default, b.Usage) +} + +type StringFlag struct { + Name string + Usage string + Default string + Value *string +} + +func (f *Flagset) StringFlag(b *StringFlag) { + f.addFlag(&FlagVar{ + Name: b.Name, + Usage: b.Usage, + }) + f.set.StringVar(b.Value, b.Name, b.Default, b.Usage) +} + +type IntFlag struct { + Name string + Usage string + Default int + Value *int +} + +func (f *Flagset) IntFlag(i *IntFlag) { + f.addFlag(&FlagVar{ + Name: i.Name, + Usage: i.Usage, + }) + f.set.IntVar(i.Value, i.Name, i.Default, i.Usage) +} diff --git a/command/main.go b/command/main.go new file mode 100644 index 0000000000..e84fa899b0 --- /dev/null +++ b/command/main.go @@ -0,0 +1,45 @@ +package main + +import ( + "fmt" + "os" + + "github.com/ethereum/go-ethereum/command/server" + "github.com/mitchellh/cli" +) + +func main() { + os.Exit(Run(os.Args[1:])) +} + +func Run(args []string) int { + commands := commands() + + cli := &cli.CLI{ + Name: "bor", + Args: args, + Commands: commands, + } + + exitCode, err := cli.Run() + if err != nil { + fmt.Fprintf(os.Stderr, "Error executing CLI: %s\n", err.Error()) + return 1 + } + return exitCode +} + +func commands() map[string]cli.CommandFactory { + ui := &cli.BasicUi{ + Reader: os.Stdin, + Writer: os.Stdout, + ErrorWriter: os.Stderr, + } + return map[string]cli.CommandFactory{ + "server": func() (cli.Command, error) { + return &server.Command{ + UI: ui, + }, nil + }, + } +} diff --git a/command/server/command.go b/command/server/command.go new file mode 100644 index 0000000000..402a9c99d3 --- /dev/null +++ b/command/server/command.go @@ -0,0 +1,137 @@ +package server + +import ( + "fmt" + "io" + "os" + "os/signal" + "strings" + "syscall" + "time" + + "github.com/ethereum/go-ethereum/eth" + "github.com/ethereum/go-ethereum/eth/tracers" + "github.com/ethereum/go-ethereum/log" + "github.com/ethereum/go-ethereum/node" + "github.com/mattn/go-colorable" + "github.com/mattn/go-isatty" + "github.com/mitchellh/cli" +) + +// Command is the command to start the sever +type Command struct { + UI cli.Ui + + // cli configuration + cliConfig *Config + + configFile string + + // bor node + node *node.Node +} + +// Help implements the cli.Command interface +func (c *Command) Help() string { + return "" +} + +// Synopsis implements the cli.Command interface +func (c *Command) Synopsis() string { + return "" +} + +// Run implements the cli.Command interface +func (c *Command) Run(args []string) int { + flags := c.Flags() + if err := flags.Parse(args); err != nil { + c.UI.Error(err.Error()) + return 1 + } + + // read config file + config := DefaultConfig() + if c.configFile != "" { + c, err := readConfigFile(c.configFile) + if err != nil { + panic(err) + } + config.Merge(c) + } + config.Merge(c.cliConfig) + + // start the logger + setupLogger(*config.LogLevel) + + // create the node + nodeCfg, err := config.buildNode() + if err != nil { + panic(err) + } + stack, err := node.New(nodeCfg) + if err != nil { + panic(err) + } + c.node = stack + + // register the ethereum backend + ethCfg, err := config.buildEth() + if err != nil { + panic(err) + } + backend, err := eth.New(stack, ethCfg) + if err != nil { + panic(err) + } + c.node.RegisterAPIs(tracers.APIs(backend.APIBackend)) + + // start the node + if err := c.node.Start(); err != nil { + panic(err) + } + return c.handleSignals() +} + +func (c *Command) handleSignals() int { + signalCh := make(chan os.Signal, 4) + signal.Notify(signalCh, os.Interrupt, syscall.SIGTERM, syscall.SIGHUP) + + sig := <-signalCh + + c.UI.Output(fmt.Sprintf("Caught signal: %v", sig)) + c.UI.Output("Gracefully shutting down agent...") + + gracefulCh := make(chan struct{}) + go func() { + c.node.Close() + close(gracefulCh) + }() + + select { + case <-signalCh: + return 1 + case <-time.After(5 * time.Second): + return 1 + case <-gracefulCh: + return 0 + } +} + +func setupLogger(logLevel string) { + output := io.Writer(os.Stderr) + usecolor := (isatty.IsTerminal(os.Stderr.Fd()) || isatty.IsCygwinTerminal(os.Stderr.Fd())) && os.Getenv("TERM") != "dumb" + if usecolor { + output = colorable.NewColorableStderr() + } + ostream := log.StreamHandler(output, log.TerminalFormat(usecolor)) + glogger := log.NewGlogHandler(ostream) + + // logging + lvl, err := log.LvlFromString(strings.ToLower(logLevel)) + if err == nil { + glogger.Verbosity(lvl) + } else { + glogger.Verbosity(log.LvlInfo) + } + log.Root().SetHandler(glogger) +} diff --git a/command/server/config.go b/command/server/config.go new file mode 100644 index 0000000000..a6d01a1dca --- /dev/null +++ b/command/server/config.go @@ -0,0 +1,127 @@ +package server + +import ( + "strconv" + + "github.com/ethereum/go-ethereum/common/fdlimit" + "github.com/ethereum/go-ethereum/eth/downloader" + "github.com/ethereum/go-ethereum/eth/ethconfig" + "github.com/ethereum/go-ethereum/node" + "github.com/ethereum/go-ethereum/p2p" + "github.com/imdario/mergo" +) + +func stringPtr(s string) *string { + return &s +} + +func uint64Ptr(i uint64) *uint64 { + return &i +} + +func boolPtr(b bool) *bool { + return &b +} + +type Config struct { + Debug *bool + LogLevel *string + DataDir *string + P2P *P2PConfig +} + +type P2PConfig struct { + MaxPeers *uint64 + Bind *string + Port *uint64 +} + +func DefaultConfig() *Config { + return &Config{ + Debug: boolPtr(false), + LogLevel: stringPtr("INFO"), + DataDir: stringPtr(""), + P2P: &P2PConfig{ + MaxPeers: uint64Ptr(30), + Bind: stringPtr("0.0.0.0."), + Port: uint64Ptr(30303), + }, + } +} + +func readConfigFile(path string) (*Config, error) { + return nil, nil +} + +func (c *Config) buildEth() (*ethconfig.Config, error) { + dbHandles, err := makeDatabaseHandles() + if err != nil { + return nil, err + } + n := ethconfig.Defaults + //n.NetworkId = c.genesis.NetworkId + //n.Genesis = c.genesis.Genesis + n.SyncMode = downloader.FastSync + n.DatabaseHandles = dbHandles + return &n, nil +} + +func (c *Config) buildNode() (*node.Config, error) { + /* + bootstrap, err := parseBootnodes(c.genesis.Bootstrap) + if err != nil { + return nil, err + } + static, err := parseBootnodes(c.genesis.Static) + if err != nil { + return nil, err + } + */ + + n := &node.Config{ + Name: "reader", + DataDir: *c.DataDir, + P2P: p2p.Config{ + MaxPeers: int(*c.P2P.MaxPeers), + ListenAddr: *c.P2P.Bind + ":" + strconv.Itoa(int(*c.P2P.Port)), + }, + /* + HTTPHost: *c.BindAddr, + HTTPPort: int(*c.Ports.HTTP), + HTTPVirtualHosts: []string{"*"}, + WSHost: *c.BindAddr, + WSPort: int(*c.Ports.Websocket), + */ + } + /* + if *c.NoDiscovery { + // avoid incoming connections + n.P2P.MaxPeers = 0 + // avoid outgoing connections + n.P2P.NoDiscovery = true + } + */ + + return n, nil +} + +func (c *Config) Merge(cc ...*Config) error { + for _, elem := range cc { + if err := mergo.Merge(&c, elem); err != nil { + return err + } + } + return nil +} + +func makeDatabaseHandles() (int, error) { + limit, err := fdlimit.Maximum() + if err != nil { + return -1, err + } + raised, err := fdlimit.Raise(uint64(limit)) + if err != nil { + return -1, err + } + return int(raised / 2), nil +} diff --git a/command/server/flags.go b/command/server/flags.go new file mode 100644 index 0000000000..48cdecf3f5 --- /dev/null +++ b/command/server/flags.go @@ -0,0 +1,32 @@ +package server + +import "github.com/ethereum/go-ethereum/command/flagset" + +func (c *Command) Flags() *flagset.Flagset { + c.cliConfig = &Config{} + + f := flagset.NewFlagSet("server") + + f.BoolFlag(&flagset.BoolFlag{ + Name: "debug", + Value: c.cliConfig.Debug, + Usage: "Path of the file to apply", + }) + f.StringFlag(&flagset.StringFlag{ + Name: "log-level", + Value: c.cliConfig.LogLevel, + Usage: "Set log level for the server", + }) + f.StringFlag(&flagset.StringFlag{ + Name: "data-dir", + Value: c.cliConfig.DataDir, + Usage: "Path of the data directory to store information", + }) + f.StringFlag(&flagset.StringFlag{ + Name: "config", + Value: &c.configFile, + Usage: "File for the config file", + }) + + return f +} diff --git a/go.mod b/go.mod index 56b0a97fd6..ae93276e23 100644 --- a/go.mod +++ b/go.mod @@ -39,6 +39,7 @@ require ( github.com/holiman/bloomfilter/v2 v2.0.3 github.com/holiman/uint256 v1.2.0 github.com/huin/goupnp v1.0.2 + github.com/imdario/mergo v0.3.11 github.com/influxdata/influxdb v1.8.3 github.com/influxdata/influxdb-client-go/v2 v2.4.0 github.com/influxdata/line-protocol v0.0.0-20210311194329-9aa0e372d097 // indirect @@ -49,6 +50,7 @@ require ( github.com/kylelemons/godebug v1.1.0 // indirect github.com/mattn/go-colorable v0.1.8 github.com/mattn/go-isatty v0.0.12 + github.com/mitchellh/cli v1.1.2 github.com/naoina/go-stringutil v0.1.0 // indirect github.com/naoina/toml v0.1.2-0.20170918210437-9fafd6967416 github.com/olekukonko/tablewriter v0.0.5 diff --git a/go.sum b/go.sum index bf559c2708..c98b75beac 100644 --- a/go.sum +++ b/go.sum @@ -42,6 +42,12 @@ github.com/Azure/go-autorest/tracing v0.5.0/go.mod h1:r/s2XiOKccPW3HrqB+W0TQzfbt github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= github.com/DATA-DOG/go-sqlmock v1.3.3/go.mod h1:f/Ixk793poVmq4qj/V1dPUg2JEAKC73Q5eFN3EC/SaM= +github.com/Masterminds/goutils v1.1.0 h1:zukEsf/1JZwCMgHiK3GZftabmxiCw4apj3a28RPBiVg= +github.com/Masterminds/goutils v1.1.0/go.mod h1:8cTjp+g8YejhMuvIA5y2vz3BpJxksy863GQaJW2MFNU= +github.com/Masterminds/semver v1.5.0 h1:H65muMkzWKEuNDnfl9d70GUjFniHKHRbFPGBuZ3QEww= +github.com/Masterminds/semver v1.5.0/go.mod h1:MB6lktGJrhw8PrUyiEoblNEGEQ+RzHPF078ddwwvV3Y= +github.com/Masterminds/sprig v2.22.0+incompatible h1:z4yfnGrZ7netVz+0EDJ0Wi+5VZCSYp4Z0m2dk6cEM60= +github.com/Masterminds/sprig v2.22.0+incompatible/go.mod h1:y6hNFY5UBTIWBxnzTeuNhlNS5hqE0NB0E6fgfo2Br3o= github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= github.com/StackExchange/wmi v0.0.0-20180116203802-5d049714c4a6 h1:fLjPD/aNc3UIOA6tDi6QXUemppXK3P9BI7mr2hd6gx8= github.com/StackExchange/wmi v0.0.0-20180116203802-5d049714c4a6/go.mod h1:3eOhrUMpNV+6aFIbp5/iudMxNCF27Vw2OZgy4xEx0Fg= @@ -55,6 +61,8 @@ github.com/allegro/bigcache v1.2.1-0.20190218064605-e24eb225f156 h1:eMwmnE/GDgah github.com/allegro/bigcache v1.2.1-0.20190218064605-e24eb225f156/go.mod h1:Cb/ax3seSYIx7SuZdm2G2xzfwmv3TPSk2ucNfQESPXM= github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883/go.mod h1:rCTlJbsFo29Kk6CurOXKm700vrz8f0KW0JNfpkRJY/8= github.com/apache/arrow/go/arrow v0.0.0-20191024131854-af6fa24be0db/go.mod h1:VTxUBvSJ3s3eHAg65PNgrsn5BtqCRPdmyXh6rAfdxN0= +github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310 h1:BUAU3CGlLvorLI26FmByPp2eC2qla6E1Tw+scpcg/to= +github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= github.com/aws/aws-sdk-go-v2 v1.2.0 h1:BS+UYpbsElC82gB+2E2jiCBg36i8HlubTB/dO/moQ9c= github.com/aws/aws-sdk-go-v2 v1.2.0/go.mod h1:zEQs02YRBw1DjK0PoJv3ygDYOFTre1ejlJWl8FwAuQo= github.com/aws/aws-sdk-go-v2/config v1.1.1 h1:ZAoq32boMzcaTW9bcUacBswAmHTbvlvDJICgHFZuECo= @@ -75,6 +83,8 @@ github.com/aws/smithy-go v1.1.0 h1:D6CSsM3gdxaGaqXnPgOBCeL6Mophqzu7KJOu7zW78sU= github.com/aws/smithy-go v1.1.0/go.mod h1:EzMw8dbp/YJL4A5/sbhGddag+NPT7q084agLbB9LgIw= github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= +github.com/bgentry/speakeasy v0.1.0 h1:ByYyxL9InA1OWqxJqqp2A5pYHUrCiAL6K3J+LKSsQkY= +github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= github.com/bmizerany/pat v0.0.0-20170815010413-6226ea591a40/go.mod h1:8rLXio+WjiTceGBHIoTvn60HIbs7Hm7bcHjyrSqYB9c= github.com/boltdb/bolt v1.3.1/go.mod h1:clJnj/oiGkjum5o1McbSZDSLxVThjynRyGBgiAx27Ps= github.com/btcsuite/btcd v0.20.1-beta h1:Ik4hyJqN8Jfyv3S4AGBOmyouMsYE3EdYODkMbQjwPGw= @@ -206,6 +216,7 @@ github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OI github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= +github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.1.5 h1:kxhtnfFVi+rYdOALN0B3k9UT86zVJKfBimRaciULW4I= github.com/google/uuid v1.1.5/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= @@ -216,6 +227,10 @@ github.com/gorilla/websocket v1.4.2 h1:+/TMaTYc4QFitKJxsQ7Yye35DkWvkdLcvGKqM+x0U github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/graph-gophers/graphql-go v0.0.0-20201113091052-beb923fada29 h1:sezaKhEfPFg8W0Enm61B9Gs911H8iesGY5R8NDPtd1M= github.com/graph-gophers/graphql-go v0.0.0-20201113091052-beb923fada29/go.mod h1:9CQHMSxwO4MprSdzoIEobiHpoLtHm77vfxsvsIN5Vuc= +github.com/hashicorp/errwrap v1.0.0 h1:hLrqtEDnRye3+sgx6z4qVLNuviH3MR5aQ0ykNJa/UYA= +github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= +github.com/hashicorp/go-multierror v1.0.0 h1:iVjPR7a6H0tWELX5NxNe7bYopibicUzc7uPribsnS6o= +github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk= github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.5-0.20210104140557-80c98217689d h1:dg1dEPuWpEqDnvIw251EVy4zlP8gWbsGj4BsUKCRpYs= @@ -225,10 +240,14 @@ github.com/holiman/bloomfilter/v2 v2.0.3/go.mod h1:zpoh+gs7qcpqrHr3dB55AMiJwo0iU github.com/holiman/uint256 v1.2.0 h1:gpSYcPLWGv4sG43I2mVLiDZCNDh/EpGjSk8tmtxitHM= github.com/holiman/uint256 v1.2.0/go.mod h1:y4ga/t+u+Xwd7CpDgZESaRcWy0I7XMlTMA25ApIH5Jw= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= +github.com/huandu/xstrings v1.3.2 h1:L18LIDzqlW6xN2rEkpdV8+oL/IXWJ1APd+vsdYy4Wdw= +github.com/huandu/xstrings v1.3.2/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE= github.com/huin/goupnp v1.0.2 h1:RfGLP+h3mvisuWEyybxNq5Eft3NWhHLPeUN72kpKZoI= github.com/huin/goupnp v1.0.2/go.mod h1:0dxJBVBHqTMjIUMkESDTNgOOx/Mw5wYIfyFmdzSamkM= github.com/huin/goutil v0.0.0-20170803182201-1ca381bf3150/go.mod h1:PpLOETDnJ0o3iZrZfqZzyLl6l7F3c6L1oWn7OICBi6o= github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= +github.com/imdario/mergo v0.3.11 h1:3tnifQM4i+fbajXKBHXWEH+KvNHqojZ778UH75j3bGA= +github.com/imdario/mergo v0.3.11/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/influxdata/flux v0.65.1/go.mod h1:J754/zds0vvpfwuq7Gc2wRdVwEodfpCFM7mYlOw2LqY= github.com/influxdata/influxdb v1.8.3 h1:WEypI1BQFTT4teLM+1qkEcvUi0dAvopAI/ir0vAiBg8= @@ -296,6 +315,7 @@ github.com/mattn/go-colorable v0.1.8/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope github.com/mattn/go-ieproxy v0.0.0-20190610004146-91bb50d98149/go.mod h1:31jz6HNzdxOmlERGGEc4v/dMssOfmp2p5bT/okiKFFc= github.com/mattn/go-ieproxy v0.0.0-20190702010315-6dee0af9227d h1:oNAwILwmgWKFpuU+dXvI6dl9jG2mAWAZLX3r9s0PPiw= github.com/mattn/go-ieproxy v0.0.0-20190702010315-6dee0af9227d/go.mod h1:31jz6HNzdxOmlERGGEc4v/dMssOfmp2p5bT/okiKFFc= +github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= github.com/mattn/go-isatty v0.0.9/go.mod h1:YNRxwqDuOph6SZLI9vUUz6OYw3QyUt7WiY2yME+cCiQ= @@ -307,6 +327,12 @@ github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m github.com/mattn/go-sqlite3 v1.11.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc= github.com/mattn/go-tty v0.0.0-20180907095812-13ff1204f104/go.mod h1:XPvLUNfbS4fJH25nqRHfWLMa1ONC8Amw+mIA639KxkE= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= +github.com/mitchellh/cli v1.1.2 h1:PvH+lL2B7IQ101xQL63Of8yFS2y+aDlsFcsqNc+u/Kw= +github.com/mitchellh/cli v1.1.2/go.mod h1:6iaV0fGdElS6dPBx0EApTxHrcWvmJphyh2n8YBLPPZ4= +github.com/mitchellh/copystructure v1.0.0 h1:Laisrj+bAB6b/yJwB5Bt3ITZhGJdqmxquMKeZ+mmkFQ= +github.com/mitchellh/copystructure v1.0.0/go.mod h1:SNtv71yrdKgLRyLFxmLdkAbkKEFWgYaq1OVrnRcwhnw= +github.com/mitchellh/reflectwalk v1.0.0 h1:9D+8oIskB4VJBN5SFlmc27fSlIBZaov1Wpk/IfikLNY= +github.com/mitchellh/reflectwalk v1.0.0/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/mschoch/smat v0.0.0-20160514031455-90eadee771ae/go.mod h1:qAyveg+e4CE+eKJXWVjKXM4ck2QobLqTDytGJbLLhJg= @@ -346,6 +372,8 @@ github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINE github.com/pkg/term v0.0.0-20180730021639-bffc007b7fd5/go.mod h1:eCbImbZ95eXtAUIbLAuAVnBnwf83mjf6QIVH8SHYwqQ= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/posener/complete v1.1.1 h1:ccV59UEOTzVDnDUEFdT95ZzHVZ+5+158q8+SJb2QV5w= +github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI= github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo= github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= @@ -388,6 +416,7 @@ github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXf github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= +github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7 h1:epCh84lMvA70Z7CTTCmYQn2CKbY8j86K7/FAIr141uY= @@ -407,7 +436,6 @@ github.com/willf/bitset v1.1.3/go.mod h1:RjeCKbqT1RxIR/KWY6phxZiaY1IyutSBfGjNPyS github.com/xlab/treeprint v0.0.0-20180616005107-d6fb6747feb6/go.mod h1:ce1O1j6UtZfjr22oyGxGLbauSBp2YVXpARAosm7dHBg= github.com/xsleonard/go-merkle v1.1.0 h1:fHe1fuhJjGH22ZzVTAH0jqHLhTGhOq3wQjJN+8P0jQg= github.com/xsleonard/go-merkle v1.1.0/go.mod h1:cW4z+UZ/4f2n9IJgIiyDCdYguchoDyDAPmpuOWGxdGg= -go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= From 8fe5c5a3297bc353cdefb90b7e13513da784f6c2 Mon Sep 17 00:00:00 2001 From: Ferran Borreguero Date: Mon, 4 Oct 2021 09:48:12 +0200 Subject: [PATCH 02/51] Add more flags and configs --- command/flagset/flagset.go | 37 ++++++++ command/main.go | 5 ++ command/server/chains/allocs/mainnet.json | 35 ++++++++ command/server/chains/allocs/mumbai.json | 30 +++++++ command/server/chains/mainnet.go | 61 +++++++++++++ command/server/chains/mumbai.go | 49 ++++++++++ command/server/chains/utils.go | 27 ++++++ command/server/command.go | 7 +- command/server/config.go | 103 ++++++++++++++++++++-- command/server/flags.go | 38 +++++++- command/version.go | 30 +++++++ 11 files changed, 411 insertions(+), 11 deletions(-) create mode 100644 command/server/chains/allocs/mainnet.json create mode 100644 command/server/chains/allocs/mumbai.json create mode 100644 command/server/chains/mainnet.go create mode 100644 command/server/chains/mumbai.go create mode 100644 command/server/chains/utils.go create mode 100644 command/version.go diff --git a/command/flagset/flagset.go b/command/flagset/flagset.go index 47327ca6d3..696765e8c6 100644 --- a/command/flagset/flagset.go +++ b/command/flagset/flagset.go @@ -4,6 +4,7 @@ import ( "flag" "fmt" "strings" + "time" ) type Flagset struct { @@ -93,3 +94,39 @@ func (f *Flagset) IntFlag(i *IntFlag) { }) f.set.IntVar(i.Value, i.Name, i.Default, i.Usage) } + +type SliceStringFlag struct { + Name string + Usage string + Value []string +} + +func (i *SliceStringFlag) String() string { + return "" +} + +func (i *SliceStringFlag) Set(value string) error { + i.Value = append(i.Value, value) + return nil +} + +func (f *Flagset) SliceStringFlag(s *SliceStringFlag) { + f.addFlag(&FlagVar{ + Name: s.Name, + Usage: s.Usage, + }) + f.set.Var(s, s.Name, s.Usage) +} + +type DurationFlag struct { + Name string + Usage string + Value *time.Duration +} + +func (f *Flagset) DurationFlag(d *DurationFlag) { + f.addFlag(&FlagVar{ + Name: d.Name, + Usage: d.Usage, + }) +} diff --git a/command/main.go b/command/main.go index e84fa899b0..1a1f92e316 100644 --- a/command/main.go +++ b/command/main.go @@ -41,5 +41,10 @@ func commands() map[string]cli.CommandFactory { UI: ui, }, nil }, + "version": func() (cli.Command, error) { + return &VersionCommand{ + UI: ui, + }, nil + }, } } diff --git a/command/server/chains/allocs/mainnet.json b/command/server/chains/allocs/mainnet.json new file mode 100644 index 0000000000..897fb053bf --- /dev/null +++ b/command/server/chains/allocs/mainnet.json @@ -0,0 +1,35 @@ +{ + "0000000000000000000000000000000000001000": { + "balance": "0x0", + "code": "0x608060405234801561001057600080fd5b50600436106101f05760003560e01c806360c8614d1161010f578063af26aa96116100a2578063d5b844eb11610071578063d5b844eb14610666578063dcf2793a14610684578063e3b7c924146106b6578063f59cf565146106d4576101f0565b8063af26aa96146105c7578063b71d7a69146105e7578063b7ab4db514610617578063c1b3c91914610636576101f0565b806370ba5707116100de57806370ba57071461052b57806398ab2b621461055b5780639d11b80714610579578063ae756451146105a9576101f0565b806360c8614d1461049c57806365b3a1e2146104bc57806366332354146104db578063687a9bd6146104f9576101f0565b80633434735f1161018757806344d6528f1161015657806344d6528f146103ee5780634dbc959f1461041e57806355614fcc1461043c578063582a8d081461046c576101f0565b80633434735f1461035257806335ddfeea1461037057806343ee8213146103a057806344c15cb1146103be576101f0565b806323f2a73f116101c357806323f2a73f146102a45780632bc06564146102d45780632de3a180146102f25780632eddf35214610322576101f0565b8063047a6c5b146101f55780630c35b1cb146102275780631270b5741461025857806323c2a2b414610288575b600080fd5b61020f600480360361020a9190810190612c14565b610706565b60405161021e93929190613553565b60405180910390f35b610241600480360361023c9190810190612c14565b61075d565b60405161024f929190613374565b60405180910390f35b610272600480360361026d9190810190612c3d565b610939565b60405161027f91906133ab565b60405180910390f35b6102a2600480360361029d9190810190612d1c565b610a91565b005b6102be60048036036102b99190810190612c3d565b61112a565b6040516102cb91906133ab565b60405180910390f35b6102dc611281565b6040516102e99190613501565b60405180910390f35b61030c60048036036103079190810190612b71565b611286565b60405161031991906133c6565b60405180910390f35b61033c60048036036103379190810190612c14565b611307565b6040516103499190613501565b60405180910390f35b61035a611437565b6040516103679190613359565b60405180910390f35b61038a60048036036103859190810190612bad565b61144f565b60405161039791906133ab565b60405180910390f35b6103a861151a565b6040516103b591906133c6565b60405180910390f35b6103d860048036036103d39190810190612c79565b611531565b6040516103e59190613501565b60405180910390f35b61040860048036036104039190810190612c3d565b611619565b60405161041591906134e6565b60405180910390f35b610426611781565b6040516104339190613501565b60405180910390f35b61045660048036036104519190810190612af6565b611791565b60405161046391906133ab565b60405180910390f35b61048660048036036104819190810190612b1f565b6117ab565b60405161049391906133c6565b60405180910390f35b6104a4611829565b6040516104b393929190613553565b60405180910390f35b6104c461189d565b6040516104d2929190613374565b60405180910390f35b6104e3611c5e565b6040516104f09190613501565b60405180910390f35b610513600480360361050e9190810190612ce0565b611c63565b6040516105229392919061351c565b60405180910390f35b61054560048036036105409190810190612af6565b611cc7565b60405161055291906133ab565b60405180910390f35b610563611ce1565b60405161057091906133c6565b60405180910390f35b610593600480360361058e9190810190612c14565b611cf8565b6040516105a09190613501565b60405180910390f35b6105b1611e29565b6040516105be91906133c6565b60405180910390f35b6105cf611e40565b6040516105de93929190613553565b60405180910390f35b61060160048036036105fc9190810190612c14565b611ea1565b60405161060e9190613501565b60405180910390f35b61061f611fa1565b60405161062d929190613374565b60405180910390f35b610650600480360361064b9190810190612c14565b611fb5565b60405161065d9190613501565b60405180910390f35b61066e611fd6565b60405161067b919061358a565b60405180910390f35b61069e60048036036106999190810190612ce0565b611fdb565b6040516106ad9392919061351c565b60405180910390f35b6106be61203f565b6040516106cb9190613501565b60405180910390f35b6106ee60048036036106e99190810190612c14565b612051565b6040516106fd93929190613553565b60405180910390f35b60008060006002600085815260200190815260200160002060000154600260008681526020019081526020016000206001015460026000878152602001908152602001600020600201549250925092509193909250565b60608060ff83116107795761077061189d565b91509150610934565b600061078484611ea1565b9050606060016000838152602001908152602001600020805490506040519080825280602002602001820160405280156107cd5781602001602082028038833980820191505090505b509050606060016000848152602001908152602001600020805490506040519080825280602002602001820160405280156108175781602001602082028038833980820191505090505b50905060008090505b60016000858152602001908152602001600020805490508110156109295760016000858152602001908152602001600020818154811061085c57fe5b906000526020600020906003020160020160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1683828151811061089a57fe5b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff16815250506001600085815260200190815260200160002081815481106108f257fe5b90600052602060002090600302016001015482828151811061091057fe5b6020026020010181815250508080600101915050610820565b508181945094505050505b915091565b6000606060016000858152602001908152602001600020805480602002602001604051908101604052809291908181526020016000905b82821015610a0c578382906000526020600020906003020160405180606001604052908160008201548152602001600182015481526020016002820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152505081526020019060010190610970565b50505050905060008090505b8151811015610a84578373ffffffffffffffffffffffffffffffffffffffff16828281518110610a4457fe5b60200260200101516040015173ffffffffffffffffffffffffffffffffffffffff161415610a7757600192505050610a8b565b8080600101915050610a18565b5060009150505b92915050565b73fffffffffffffffffffffffffffffffffffffffe73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610b13576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b0a906134c6565b60405180910390fd5b6000610b1d611781565b90506000811415610b3157610b3061207b565b5b610b4560018261239c90919063ffffffff16565b8814610b86576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b7d90613446565b60405180910390fd5b868611610bc8576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610bbf906134a6565b60405180910390fd5b6000604060018989030181610bd957fe5b0614610c1a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c1190613486565b60405180910390fd5b8660026000838152602001908152602001600020600101541115610c73576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c6a90613426565b60405180910390fd5b6000600260008a81526020019081526020016000206000015414610ccc576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610cc390613466565b60405180910390fd5b604051806060016040528089815260200188815260200187815250600260008a8152602001908152602001600020600082015181600001556020820151816001015560408201518160020155905050600388908060018154018082558091505090600182039060005260206000200160009091929091909150555060008060008a815260200190815260200160002081610d6691906128f0565b506000600160008a815260200190815260200160002081610d8791906128f0565b506060610ddf610dda87878080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050506123bb565b6123e9565b905060008090505b8151811015610f51576060610e0e838381518110610e0157fe5b60200260200101516123e9565b90506000808c81526020019081526020016000208054809190600101610e3491906128f0565b506040518060600160405280610e5d83600081518110610e5057fe5b60200260200101516124c6565b8152602001610e7f83600181518110610e7257fe5b60200260200101516124c6565b8152602001610ea183600281518110610e9457fe5b6020026020010151612537565b73ffffffffffffffffffffffffffffffffffffffff168152506000808d81526020019081526020016000208381548110610ed757fe5b9060005260206000209060030201600082015181600001556020820151816001015560408201518160020160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550905050508080600101915050610de7565b506060610fa9610fa486868080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050506123bb565b6123e9565b905060008090505b815181101561111d576060610fd8838381518110610fcb57fe5b60200260200101516123e9565b9050600160008d81526020019081526020016000208054809190600101610fff91906128f0565b5060405180606001604052806110288360008151811061101b57fe5b60200260200101516124c6565b815260200161104a8360018151811061103d57fe5b60200260200101516124c6565b815260200161106c8360028151811061105f57fe5b6020026020010151612537565b73ffffffffffffffffffffffffffffffffffffffff16815250600160008e815260200190815260200160002083815481106110a357fe5b9060005260206000209060030201600082015181600001556020820151816001015560408201518160020160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550905050508080600101915050610fb1565b5050505050505050505050565b60006060600080858152602001908152602001600020805480602002602001604051908101604052809291908181526020016000905b828210156111fc578382906000526020600020906003020160405180606001604052908160008201548152602001600182015481526020016002820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152505081526020019060010190611160565b50505050905060008090505b8151811015611274578373ffffffffffffffffffffffffffffffffffffffff1682828151811061123457fe5b60200260200101516040015173ffffffffffffffffffffffffffffffffffffffff1614156112675760019250505061127b565b8080600101915050611208565b5060009150505b92915050565b604081565b60006002600160f81b84846040516020016112a3939291906132c6565b6040516020818303038152906040526040516112bf9190613303565b602060405180830381855afa1580156112dc573d6000803e3d6000fd5b5050506040513d601f19601f820116820180604052506112ff9190810190612b48565b905092915050565b60006060600080848152602001908152602001600020805480602002602001604051908101604052809291908181526020016000905b828210156113d9578382906000526020600020906003020160405180606001604052908160008201548152602001600182015481526020016002820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815250508152602001906001019061133d565b505050509050600080905060008090505b825181101561142c5761141d83828151811061140257fe5b6020026020010151602001518361239c90919063ffffffff16565b915080806001019150506113ea565b508092505050919050565b73fffffffffffffffffffffffffffffffffffffffe81565b600080600080859050600060218087518161146657fe5b04029050600081111561147f5761147c876117ab565b91505b6000602190505b818111611509576000600182038801519050818801519550806000602081106114ab57fe5b1a60f81b9450600060f81b857effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614156114f0576114e98685611286565b93506114fd565b6114fa8487611286565b93505b50602181019050611486565b508782149450505050509392505050565b60405161152690613344565b604051809103902081565b60008060009050600080905060008090505b84518167ffffffffffffffff16101561160c57606061156e868367ffffffffffffffff16604161255a565b9050600061158582896125e690919063ffffffff16565b905061158f612922565b6115998a83611619565b90506115a58a8361112a565b80156115dc57508473ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16115b156115fe578194506115fb81602001518761239c90919063ffffffff16565b95505b505050604181019050611543565b5081925050509392505050565b611621612922565b6060600080858152602001908152602001600020805480602002602001604051908101604052809291908181526020016000905b828210156116f1578382906000526020600020906003020160405180606001604052908160008201548152602001600182015481526020016002820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152505081526020019060010190611655565b50505050905060008090505b8151811015611779578373ffffffffffffffffffffffffffffffffffffffff1682828151811061172957fe5b60200260200101516040015173ffffffffffffffffffffffffffffffffffffffff16141561176c5781818151811061175d57fe5b60200260200101519250611779565b80806001019150506116fd565b505092915050565b600061178c43611ea1565b905090565b60006117a461179e611781565b8361112a565b9050919050565b60006002600060f81b836040516020016117c692919061329a565b6040516020818303038152906040526040516117e29190613303565b602060405180830381855afa1580156117ff573d6000803e3d6000fd5b5050506040513d601f19601f820116820180604052506118229190810190612b48565b9050919050565b60008060008061184a600161183c611781565b61239c90919063ffffffff16565b905060026000828152602001908152602001600020600001546002600083815260200190815260200160002060010154600260008481526020019081526020016000206002015493509350935050909192565b606080606060076040519080825280602002602001820160405280156118d25781602001602082028038833980820191505090505b509050735973918275c01f50555d44e92c9d9b353cadad54816000815181106118f757fe5b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff168152505073b8bb158b93c94ed35c1970d610d1e2b34e26652c8160018151811061195357fe5b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff168152505073f84c74dea96df0ec22e11e7c33996c73fcc2d822816002815181106119af57fe5b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff168152505073b702f1c9154ac9c08da247a8e30ee6f2f3373f4181600381518110611a0b57fe5b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff1681525050737fcd58c2d53d980b247f1612fdba93e9a76193e681600481518110611a6757fe5b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff1681525050730375b2fc7140977c9c76d45421564e354ed4227781600581518110611ac357fe5b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff16815250507342eefcda06ead475cde3731b8eb138e88cd0bac381600681518110611b1f57fe5b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff168152505060606007604051908082528060200260200182016040528015611b8b5781602001602082028038833980820191505090505b50905061271081600081518110611b9e57fe5b60200260200101818152505061271081600181518110611bba57fe5b60200260200101818152505061271081600281518110611bd657fe5b60200260200101818152505061271081600381518110611bf257fe5b60200260200101818152505061271081600481518110611c0e57fe5b60200260200101818152505061271081600581518110611c2a57fe5b60200260200101818152505061271081600681518110611c4657fe5b60200260200101818152505081819350935050509091565b60ff81565b60016020528160005260406000208181548110611c7c57fe5b9060005260206000209060030201600091509150508060000154908060010154908060020160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905083565b6000611cda611cd4611781565b83610939565b9050919050565b604051611ced9061331a565b604051809103902081565b6000606060016000848152602001908152602001600020805480602002602001604051908101604052809291908181526020016000905b82821015611dcb578382906000526020600020906003020160405180606001604052908160008201548152602001600182015481526020016002820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152505081526020019060010190611d2f565b505050509050600080905060008090505b8251811015611e1e57611e0f838281518110611df457fe5b6020026020010151602001518361239c90919063ffffffff16565b91508080600101915050611ddc565b508092505050919050565b604051611e359061332f565b604051809103902081565b600080600080611e4e611781565b905060026000828152602001908152602001600020600001546002600083815260200190815260200160002060010154600260008481526020019081526020016000206002015493509350935050909192565b60008060038054905090505b6000811115611f6157611ebe612959565b6002600060036001850381548110611ed257fe5b906000526020600020015481526020019081526020016000206040518060600160405290816000820154815260200160018201548152602001600282015481525050905083816020015111158015611f2f57506000816040015114155b8015611f3f575080604001518411155b15611f5257806000015192505050611f9c565b50808060019003915050611ead565b5060006003805490501115611f9757600360016003805490500381548110611f8557fe5b90600052602060002001549050611f9c565b600090505b919050565b606080611fad4361075d565b915091509091565b60038181548110611fc257fe5b906000526020600020016000915090505481565b600281565b60006020528160005260406000208181548110611ff457fe5b9060005260206000209060030201600091509150508060000154908060010154908060020160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905083565b60006040438161204b57fe5b04905090565b60026020528060005260406000206000915090508060000154908060010154908060020154905083565b60608061208661189d565b8092508193505050600080905060405180606001604052808281526020016000815260200160ff81525060026000838152602001908152602001600020600082015181600001556020820151816001015560408201518160020155905050600381908060018154018082558091505090600182039060005260206000200160009091929091909150555060008060008381526020019081526020016000208161212f91906128f0565b506000600160008381526020019081526020016000208161215091906128f0565b5060008090505b835181101561227257600080838152602001908152602001600020805480919060010161218491906128f0565b5060405180606001604052808281526020018483815181106121a257fe5b602002602001015181526020018583815181106121bb57fe5b602002602001015173ffffffffffffffffffffffffffffffffffffffff1681525060008084815260200190815260200160002082815481106121f957fe5b9060005260206000209060030201600082015181600001556020820151816001015560408201518160020160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055509050508080600101915050612157565b5060008090505b8351811015612396576001600083815260200190815260200160002080548091906001016122a791906128f0565b5060405180606001604052808281526020018483815181106122c557fe5b602002602001015181526020018583815181106122de57fe5b602002602001015173ffffffffffffffffffffffffffffffffffffffff1681525060016000848152602001908152602001600020828154811061231d57fe5b9060005260206000209060030201600082015181600001556020820151816001015560408201518160020160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055509050508080600101915050612279565b50505050565b6000808284019050838110156123b157600080fd5b8091505092915050565b6123c361297a565b600060208301905060405180604001604052808451815260200182815250915050919050565b60606123f4826126f0565b6123fd57600080fd5b60006124088361273e565b905060608160405190808252806020026020018201604052801561244657816020015b612433612994565b81526020019060019003908161242b5790505b509050600061245885602001516127af565b8560200151019050600080600090505b848110156124b95761247983612838565b915060405180604001604052808381526020018481525084828151811061249c57fe5b602002602001018190525081830192508080600101915050612468565b5082945050505050919050565b60008082600001511180156124e057506021826000015111155b6124e957600080fd5b60006124f883602001516127af565b9050600081846000015103905060008083866020015101905080519150602083101561252b57826020036101000a820491505b81945050505050919050565b6000601582600001511461254a57600080fd5b612553826124c6565b9050919050565b60608183018451101561256c57600080fd5b6060821560008114612589576040519150602082016040526125da565b6040519150601f8416801560200281840101858101878315602002848b0101015b818310156125c757805183526020830192506020810190506125aa565b50868552601f19601f8301166040525050505b50809150509392505050565b600080600080604185511461260157600093505050506126ea565b602085015192506040850151915060ff6041860151169050601b8160ff16101561262c57601b810190505b601b8160ff16141580156126445750601c8160ff1614155b1561265557600093505050506126ea565b60006001878386866040516000815260200160405260405161267a94939291906133e1565b6020604051602081039080840390855afa15801561269c573d6000803e3d6000fd5b505050602060405103519050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614156126e257600080fd5b809450505050505b92915050565b600080826000015114156127075760009050612739565b60008083602001519050805160001a915060c060ff168260ff16101561273257600092505050612739565b6001925050505b919050565b6000808260000151141561275557600090506127aa565b6000809050600061276984602001516127af565b84602001510190506000846000015185602001510190505b808210156127a35761279282612838565b820191508280600101935050612781565b8293505050505b919050565b600080825160001a9050608060ff168110156127cf576000915050612833565b60b860ff168110806127f4575060c060ff1681101580156127f3575060f860ff1681105b5b15612803576001915050612833565b60c060ff168110156128235760018060b80360ff16820301915050612833565b60018060f80360ff168203019150505b919050565b6000806000835160001a9050608060ff1681101561285957600191506128e6565b60b860ff16811015612876576001608060ff1682030191506128e5565b60c060ff168110156128a65760b78103600185019450806020036101000a855104600182018101935050506128e4565b60f860ff168110156128c357600160c060ff1682030191506128e3565b60f78103600185019450806020036101000a855104600182018101935050505b5b5b5b8192505050919050565b81548183558181111561291d5760030281600302836000526020600020918201910161291c91906129ae565b5b505050565b60405180606001604052806000815260200160008152602001600073ffffffffffffffffffffffffffffffffffffffff1681525090565b60405180606001604052806000815260200160008152602001600081525090565b604051806040016040528060008152602001600081525090565b604051806040016040528060008152602001600081525090565b612a0191905b808211156129fd5760008082016000905560018201600090556002820160006101000a81549073ffffffffffffffffffffffffffffffffffffffff0219169055506003016129b4565b5090565b90565b600081359050612a1381613783565b92915050565b600081359050612a288161379a565b92915050565b600081519050612a3d8161379a565b92915050565b60008083601f840112612a5557600080fd5b8235905067ffffffffffffffff811115612a6e57600080fd5b602083019150836001820283011115612a8657600080fd5b9250929050565b600082601f830112612a9e57600080fd5b8135612ab1612aac826135d2565b6135a5565b91508082526020830160208301858383011115612acd57600080fd5b612ad883828461372d565b50505092915050565b600081359050612af0816137b1565b92915050565b600060208284031215612b0857600080fd5b6000612b1684828501612a04565b91505092915050565b600060208284031215612b3157600080fd5b6000612b3f84828501612a19565b91505092915050565b600060208284031215612b5a57600080fd5b6000612b6884828501612a2e565b91505092915050565b60008060408385031215612b8457600080fd5b6000612b9285828601612a19565b9250506020612ba385828601612a19565b9150509250929050565b600080600060608486031215612bc257600080fd5b6000612bd086828701612a19565b9350506020612be186828701612a19565b925050604084013567ffffffffffffffff811115612bfe57600080fd5b612c0a86828701612a8d565b9150509250925092565b600060208284031215612c2657600080fd5b6000612c3484828501612ae1565b91505092915050565b60008060408385031215612c5057600080fd5b6000612c5e85828601612ae1565b9250506020612c6f85828601612a04565b9150509250929050565b600080600060608486031215612c8e57600080fd5b6000612c9c86828701612ae1565b9350506020612cad86828701612a19565b925050604084013567ffffffffffffffff811115612cca57600080fd5b612cd686828701612a8d565b9150509250925092565b60008060408385031215612cf357600080fd5b6000612d0185828601612ae1565b9250506020612d1285828601612ae1565b9150509250929050565b600080600080600080600060a0888a031215612d3757600080fd5b6000612d458a828b01612ae1565b9750506020612d568a828b01612ae1565b9650506040612d678a828b01612ae1565b955050606088013567ffffffffffffffff811115612d8457600080fd5b612d908a828b01612a43565b9450945050608088013567ffffffffffffffff811115612daf57600080fd5b612dbb8a828b01612a43565b925092505092959891949750929550565b6000612dd88383612dfc565b60208301905092915050565b6000612df0838361326d565b60208301905092915050565b612e05816136a2565b82525050565b612e14816136a2565b82525050565b6000612e258261361e565b612e2f8185613659565b9350612e3a836135fe565b8060005b83811015612e6b578151612e528882612dcc565b9750612e5d8361363f565b925050600181019050612e3e565b5085935050505092915050565b6000612e8382613629565b612e8d818561366a565b9350612e988361360e565b8060005b83811015612ec9578151612eb08882612de4565b9750612ebb8361364c565b925050600181019050612e9c565b5085935050505092915050565b612edf816136b4565b82525050565b612ef6612ef1826136c0565b61376f565b82525050565b612f05816136ec565b82525050565b612f1c612f17826136ec565b613779565b82525050565b6000612f2d82613634565b612f37818561367b565b9350612f4781856020860161373c565b80840191505092915050565b6000612f60600483613697565b91507f766f7465000000000000000000000000000000000000000000000000000000006000830152600482019050919050565b6000612fa0602d83613686565b91507f537461727420626c6f636b206d7573742062652067726561746572207468616e60008301527f2063757272656e74207370616e000000000000000000000000000000000000006020830152604082019050919050565b6000613006600383613697565b91507f31333700000000000000000000000000000000000000000000000000000000006000830152600382019050919050565b6000613046600f83613686565b91507f496e76616c6964207370616e20696400000000000000000000000000000000006000830152602082019050919050565b6000613086601383613686565b91507f5370616e20616c726561647920657869737473000000000000000000000000006000830152602082019050919050565b60006130c6604583613686565b91507f446966666572656e6365206265747765656e20737461727420616e6420656e6460008301527f20626c6f636b206d75737420626520696e206d756c7469706c6573206f66207360208301527f7072696e740000000000000000000000000000000000000000000000000000006040830152606082019050919050565b6000613152600c83613697565b91507f6865696d64616c6c2d31333700000000000000000000000000000000000000006000830152600c82019050919050565b6000613192602a83613686565b91507f456e6420626c6f636b206d7573742062652067726561746572207468616e207360008301527f7461727420626c6f636b000000000000000000000000000000000000000000006020830152604082019050919050565b60006131f8601283613686565b91507f4e6f742053797374656d204164646573732100000000000000000000000000006000830152602082019050919050565b606082016000820151613241600085018261326d565b506020820151613254602085018261326d565b5060408201516132676040850182612dfc565b50505050565b61327681613716565b82525050565b61328581613716565b82525050565b61329481613720565b82525050565b60006132a68285612ee5565b6001820191506132b68284612f0b565b6020820191508190509392505050565b60006132d28286612ee5565b6001820191506132e28285612f0b565b6020820191506132f28284612f0b565b602082019150819050949350505050565b600061330f8284612f22565b915081905092915050565b600061332582612f53565b9150819050919050565b600061333a82612ff9565b9150819050919050565b600061334f82613145565b9150819050919050565b600060208201905061336e6000830184612e0b565b92915050565b6000604082019050818103600083015261338e8185612e1a565b905081810360208301526133a28184612e78565b90509392505050565b60006020820190506133c06000830184612ed6565b92915050565b60006020820190506133db6000830184612efc565b92915050565b60006080820190506133f66000830187612efc565b613403602083018661328b565b6134106040830185612efc565b61341d6060830184612efc565b95945050505050565b6000602082019050818103600083015261343f81612f93565b9050919050565b6000602082019050818103600083015261345f81613039565b9050919050565b6000602082019050818103600083015261347f81613079565b9050919050565b6000602082019050818103600083015261349f816130b9565b9050919050565b600060208201905081810360008301526134bf81613185565b9050919050565b600060208201905081810360008301526134df816131eb565b9050919050565b60006060820190506134fb600083018461322b565b92915050565b6000602082019050613516600083018461327c565b92915050565b6000606082019050613531600083018661327c565b61353e602083018561327c565b61354b6040830184612e0b565b949350505050565b6000606082019050613568600083018661327c565b613575602083018561327c565b613582604083018461327c565b949350505050565b600060208201905061359f600083018461328b565b92915050565b6000604051905081810181811067ffffffffffffffff821117156135c857600080fd5b8060405250919050565b600067ffffffffffffffff8211156135e957600080fd5b601f19601f8301169050602081019050919050565b6000819050602082019050919050565b6000819050602082019050919050565b600081519050919050565b600081519050919050565b600081519050919050565b6000602082019050919050565b6000602082019050919050565b600082825260208201905092915050565b600082825260208201905092915050565b600081905092915050565b600082825260208201905092915050565b600081905092915050565b60006136ad826136f6565b9050919050565b60008115159050919050565b60007fff0000000000000000000000000000000000000000000000000000000000000082169050919050565b6000819050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b600060ff82169050919050565b82818337600083830152505050565b60005b8381101561375a57808201518184015260208101905061373f565b83811115613769576000848401525b50505050565b6000819050919050565b6000819050919050565b61378c816136a2565b811461379757600080fd5b50565b6137a3816136ec565b81146137ae57600080fd5b50565b6137ba81613716565b81146137c557600080fd5b5056fea365627a7a72315820638c74b73aaddeb2f2fb9267028e09737291458f6da93b6619d30c86432701d96c6578706572696d656e74616cf564736f6c634300050b0040" + }, + "0000000000000000000000000000000000001001": { + "balance": "0x0", + "code": "0x608060405234801561001057600080fd5b50600436106100415760003560e01c806319494a17146100465780633434735f146100e15780635407ca671461012b575b600080fd5b6100c76004803603604081101561005c57600080fd5b81019080803590602001909291908035906020019064010000000081111561008357600080fd5b82018360208201111561009557600080fd5b803590602001918460018302840111640100000000831117156100b757600080fd5b9091929391929390505050610149565b604051808215151515815260200191505060405180910390f35b6100e961047a565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b610133610492565b6040518082815260200191505060405180910390f35b600073fffffffffffffffffffffffffffffffffffffffe73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610200576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260128152602001807f4e6f742053797374656d2041646465737321000000000000000000000000000081525060200191505060405180910390fd5b606061025761025285858080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050610498565b6104c6565b905060006102788260008151811061026b57fe5b60200260200101516105a3565b905080600160005401146102f4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601b8152602001807f537461746549647320617265206e6f742073657175656e7469616c000000000081525060200191505060405180910390fd5b600080815480929190600101919050555060006103248360018151811061031757fe5b6020026020010151610614565b905060606103458460028151811061033857fe5b6020026020010151610637565b9050610350826106c3565b1561046f576000624c4b409050606084836040516024018083815260200180602001828103825283818151815260200191508051906020019080838360005b838110156103aa57808201518184015260208101905061038f565b50505050905090810190601f1680156103d75780820380516001836020036101000a031916815260200191505b5093505050506040516020818303038152906040527f26c53bea000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050905060008082516020840160008887f1965050505b505050509392505050565b73fffffffffffffffffffffffffffffffffffffffe81565b60005481565b6104a0610943565b600060208301905060405180604001604052808451815260200182815250915050919050565b60606104d1826106dc565b6104da57600080fd5b60006104e58361072a565b905060608160405190808252806020026020018201604052801561052357816020015b61051061095d565b8152602001906001900390816105085790505b5090506000610535856020015161079b565b8560200151019050600080600090505b848110156105965761055683610824565b915060405180604001604052808381526020018481525084828151811061057957fe5b602002602001018190525081830192508080600101915050610545565b5082945050505050919050565b60008082600001511180156105bd57506021826000015111155b6105c657600080fd5b60006105d5836020015161079b565b9050600081846000015103905060008083866020015101905080519150602083101561060857826020036101000a820491505b81945050505050919050565b6000601582600001511461062757600080fd5b610630826105a3565b9050919050565b6060600082600001511161064a57600080fd5b6000610659836020015161079b565b905060008184600001510390506060816040519080825280601f01601f19166020018201604052801561069b5781602001600182028038833980820191505090505b50905060008160200190506106b78487602001510182856108dc565b81945050505050919050565b600080823b905060008163ffffffff1611915050919050565b600080826000015114156106f35760009050610725565b60008083602001519050805160001a915060c060ff168260ff16101561071e57600092505050610725565b6001925050505b919050565b600080826000015114156107415760009050610796565b60008090506000610755846020015161079b565b84602001510190506000846000015185602001510190505b8082101561078f5761077e82610824565b82019150828060010193505061076d565b8293505050505b919050565b600080825160001a9050608060ff168110156107bb57600091505061081f565b60b860ff168110806107e0575060c060ff1681101580156107df575060f860ff1681105b5b156107ef57600191505061081f565b60c060ff1681101561080f5760018060b80360ff1682030191505061081f565b60018060f80360ff168203019150505b919050565b6000806000835160001a9050608060ff1681101561084557600191506108d2565b60b860ff16811015610862576001608060ff1682030191506108d1565b60c060ff168110156108925760b78103600185019450806020036101000a855104600182018101935050506108d0565b60f860ff168110156108af57600160c060ff1682030191506108cf565b60f78103600185019450806020036101000a855104600182018101935050505b5b5b5b8192505050919050565b60008114156108ea5761093e565b5b602060ff16811061091a5782518252602060ff1683019250602060ff1682019150602060ff16810390506108eb565b6000600182602060ff16036101000a03905080198451168184511681811785525050505b505050565b604051806040016040528060008152602001600081525090565b60405180604001604052806000815260200160008152509056fea265627a7a7231582083fbdacb76f32b4112d0f7db9a596937925824798a0026ba0232322390b5263764736f6c634300050b0032" + }, + "0000000000000000000000000000000000001010": { + "balance": "0x204fcce2c5a141f7f9a00000", + "code": "0x60806040526004361061019c5760003560e01c806377d32e94116100ec578063acd06cb31161008a578063e306f77911610064578063e306f77914610a7b578063e614d0d614610aa6578063f2fde38b14610ad1578063fc0c546a14610b225761019c565b8063acd06cb31461097a578063b789543c146109cd578063cc79f97b14610a505761019c565b80639025e64c116100c65780639025e64c146107c957806395d89b4114610859578063a9059cbb146108e9578063abceeba21461094f5761019c565b806377d32e94146106315780638da5cb5b146107435780638f32d59b1461079a5761019c565b806347e7ef24116101595780637019d41a116101335780637019d41a1461053357806370a082311461058a578063715018a6146105ef578063771282f6146106065761019c565b806347e7ef2414610410578063485cc9551461046b57806360f96a8f146104dc5761019c565b806306fdde03146101a15780631499c5921461023157806318160ddd1461028257806319d27d9c146102ad5780632e1a7d4d146103b1578063313ce567146103df575b600080fd5b3480156101ad57600080fd5b506101b6610b79565b6040518080602001828103825283818151815260200191508051906020019080838360005b838110156101f65780820151818401526020810190506101db565b50505050905090810190601f1680156102235780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561023d57600080fd5b506102806004803603602081101561025457600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610bb6565b005b34801561028e57600080fd5b50610297610c24565b6040518082815260200191505060405180910390f35b3480156102b957600080fd5b5061036f600480360360a08110156102d057600080fd5b81019080803590602001906401000000008111156102ed57600080fd5b8201836020820111156102ff57600080fd5b8035906020019184600183028401116401000000008311171561032157600080fd5b9091929391929390803590602001909291908035906020019092919080359060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610c3a565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6103dd600480360360208110156103c757600080fd5b8101908080359060200190929190505050610e06565b005b3480156103eb57600080fd5b506103f4610f58565b604051808260ff1660ff16815260200191505060405180910390f35b34801561041c57600080fd5b506104696004803603604081101561043357600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050610f61565b005b34801561047757600080fd5b506104da6004803603604081101561048e57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff16906020019092919050505061111d565b005b3480156104e857600080fd5b506104f16111ec565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b34801561053f57600080fd5b50610548611212565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b34801561059657600080fd5b506105d9600480360360208110156105ad57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050611238565b6040518082815260200191505060405180910390f35b3480156105fb57600080fd5b50610604611259565b005b34801561061257600080fd5b5061061b611329565b6040518082815260200191505060405180910390f35b34801561063d57600080fd5b506107016004803603604081101561065457600080fd5b81019080803590602001909291908035906020019064010000000081111561067b57600080fd5b82018360208201111561068d57600080fd5b803590602001918460018302840111640100000000831117156106af57600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050919291929050505061132f565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b34801561074f57600080fd5b506107586114b4565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b3480156107a657600080fd5b506107af6114dd565b604051808215151515815260200191505060405180910390f35b3480156107d557600080fd5b506107de611534565b6040518080602001828103825283818151815260200191508051906020019080838360005b8381101561081e578082015181840152602081019050610803565b50505050905090810190601f16801561084b5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561086557600080fd5b5061086e61156d565b6040518080602001828103825283818151815260200191508051906020019080838360005b838110156108ae578082015181840152602081019050610893565b50505050905090810190601f1680156108db5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b610935600480360360408110156108ff57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803590602001909291905050506115aa565b604051808215151515815260200191505060405180910390f35b34801561095b57600080fd5b506109646115d0565b6040518082815260200191505060405180910390f35b34801561098657600080fd5b506109b36004803603602081101561099d57600080fd5b810190808035906020019092919050505061165d565b604051808215151515815260200191505060405180910390f35b3480156109d957600080fd5b50610a3a600480360360808110156109f057600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190803590602001909291908035906020019092919050505061167d565b6040518082815260200191505060405180910390f35b348015610a5c57600080fd5b50610a6561169d565b6040518082815260200191505060405180910390f35b348015610a8757600080fd5b50610a906116a2565b6040518082815260200191505060405180910390f35b348015610ab257600080fd5b50610abb6116a8565b6040518082815260200191505060405180910390f35b348015610add57600080fd5b50610b2060048036036020811015610af457600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050611735565b005b348015610b2e57600080fd5b50610b37611752565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b60606040518060400160405280600b81526020017f4d6174696320546f6b656e000000000000000000000000000000000000000000815250905090565b6040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260108152602001807f44697361626c656420666561747572650000000000000000000000000000000081525060200191505060405180910390fd5b6000601260ff16600a0a6402540be40002905090565b6000808511610c4857600080fd5b6000831480610c575750824311155b610cc9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260148152602001807f5369676e6174757265206973206578706972656400000000000000000000000081525060200191505060405180910390fd5b6000610cd73387878761167d565b9050600015156005600083815260200190815260200160002060009054906101000a900460ff16151514610d73576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600f8152602001807f536967206465616374697661746564000000000000000000000000000000000081525060200191505060405180910390fd5b60016005600083815260200190815260200160002060006101000a81548160ff021916908315150217905550610ded8189898080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505061132f565b9150610dfa828488611778565b50509695505050505050565b60003390506000610e1682611238565b9050610e2d83600654611b3590919063ffffffff16565b600681905550600083118015610e4257508234145b610eb4576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260138152602001807f496e73756666696369656e7420616d6f756e740000000000000000000000000081525060200191505060405180910390fd5b8173ffffffffffffffffffffffffffffffffffffffff16600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167febff2602b3f468259e1e99f613fed6691f3a6526effe6ef3e768ba7ae7a36c4f8584610f3087611238565b60405180848152602001838152602001828152602001935050505060405180910390a3505050565b60006012905090565b610f696114dd565b610f7257600080fd5b600081118015610faf5750600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614155b611004576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526023815260200180611f036023913960400191505060405180910390fd5b600061100f83611238565b905060008390508073ffffffffffffffffffffffffffffffffffffffff166108fc849081150290604051600060405180830381858888f1935050505015801561105c573d6000803e3d6000fd5b5061107283600654611b5590919063ffffffff16565b6006819055508373ffffffffffffffffffffffffffffffffffffffff16600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f4e2ca0515ed1aef1395f66b5303bb5d6f1bf9d61a353fa53f73f8ac9973fa9f685856110f489611238565b60405180848152602001838152602001828152602001935050505060405180910390a350505050565b600760009054906101000a900460ff1615611183576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526023815260200180611ee06023913960400191505060405180910390fd5b6001600760006101000a81548160ff02191690831515021790555080600260006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506111e882611b74565b5050565b600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60008173ffffffffffffffffffffffffffffffffffffffff16319050919050565b6112616114dd565b61126a57600080fd5b600073ffffffffffffffffffffffffffffffffffffffff166000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a360008060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550565b60065481565b600080600080604185511461134a57600093505050506114ae565b602085015192506040850151915060ff6041860151169050601b8160ff16101561137557601b810190505b601b8160ff161415801561138d5750601c8160ff1614155b1561139e57600093505050506114ae565b60018682858560405160008152602001604052604051808581526020018460ff1660ff1681526020018381526020018281526020019450505050506020604051602081039080840390855afa1580156113fb573d6000803e3d6000fd5b505050602060405103519350600073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1614156114aa576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260128152602001807f4572726f7220696e2065637265636f766572000000000000000000000000000081525060200191505060405180910390fd5b5050505b92915050565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614905090565b6040518060400160405280600181526020017f890000000000000000000000000000000000000000000000000000000000000081525081565b60606040518060400160405280600581526020017f4d41544943000000000000000000000000000000000000000000000000000000815250905090565b60008134146115bc57600090506115ca565b6115c7338484611778565b90505b92915050565b6040518060800160405280605b8152602001611f78605b91396040516020018082805190602001908083835b6020831061161f57805182526020820191506020810190506020830392506115fc565b6001836020036101000a0380198251168184511680821785525050505050509050019150506040516020818303038152906040528051906020012081565b60056020528060005260406000206000915054906101000a900460ff1681565b600061169361168e86868686611c6c565b611d42565b9050949350505050565b608981565b60015481565b604051806080016040528060528152602001611f26605291396040516020018082805190602001908083835b602083106116f757805182526020820191506020810190506020830392506116d4565b6001836020036101000a0380198251168184511680821785525050505050509050019150506040516020818303038152906040528051906020012081565b61173d6114dd565b61174657600080fd5b61174f81611b74565b50565b600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6000803073ffffffffffffffffffffffffffffffffffffffff166370a08231866040518263ffffffff1660e01b8152600401808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060206040518083038186803b1580156117f857600080fd5b505afa15801561180c573d6000803e3d6000fd5b505050506040513d602081101561182257600080fd5b8101908080519060200190929190505050905060003073ffffffffffffffffffffffffffffffffffffffff166370a08231866040518263ffffffff1660e01b8152600401808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060206040518083038186803b1580156118b457600080fd5b505afa1580156118c8573d6000803e3d6000fd5b505050506040513d60208110156118de57600080fd5b810190808051906020019092919050505090506118fc868686611d8c565b8473ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff16600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167fe6497e3ee548a3372136af2fcb0696db31fc6cf20260707645068bd3fe97f3c48786863073ffffffffffffffffffffffffffffffffffffffff166370a082318e6040518263ffffffff1660e01b8152600401808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060206040518083038186803b158015611a0457600080fd5b505afa158015611a18573d6000803e3d6000fd5b505050506040513d6020811015611a2e57600080fd5b81019080805190602001909291905050503073ffffffffffffffffffffffffffffffffffffffff166370a082318e6040518263ffffffff1660e01b8152600401808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060206040518083038186803b158015611abc57600080fd5b505afa158015611ad0573d6000803e3d6000fd5b505050506040513d6020811015611ae657600080fd5b8101908080519060200190929190505050604051808681526020018581526020018481526020018381526020018281526020019550505050505060405180910390a46001925050509392505050565b600082821115611b4457600080fd5b600082840390508091505092915050565b600080828401905083811015611b6a57600080fd5b8091505092915050565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415611bae57600080fd5b8073ffffffffffffffffffffffffffffffffffffffff166000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a3806000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b6000806040518060800160405280605b8152602001611f78605b91396040516020018082805190602001908083835b60208310611cbe5780518252602082019150602081019050602083039250611c9b565b6001836020036101000a03801982511681845116808217855250505050505090500191505060405160208183030381529060405280519060200120905060405181815273ffffffffffffffffffffffffffffffffffffffff8716602082015285604082015284606082015283608082015260a0812092505081915050949350505050565b60008060015490506040517f190100000000000000000000000000000000000000000000000000000000000081528160028201528360228201526042812092505081915050919050565b3073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415611e2e576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260138152602001807f63616e27742073656e6420746f204d524332300000000000000000000000000081525060200191505060405180910390fd5b8173ffffffffffffffffffffffffffffffffffffffff166108fc829081150290604051600060405180830381858888f19350505050158015611e74573d6000803e3d6000fd5b508173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef836040518082815260200191505060405180910390a350505056fe54686520636f6e747261637420697320616c726561647920696e697469616c697a6564496e73756666696369656e7420616d6f756e74206f7220696e76616c69642075736572454950373132446f6d61696e28737472696e67206e616d652c737472696e672076657273696f6e2c75696e7432353620636861696e49642c6164647265737320766572696679696e67436f6e747261637429546f6b656e5472616e736665724f726465722861646472657373207370656e6465722c75696e7432353620746f6b656e49644f72416d6f756e742c6279746573333220646174612c75696e743235362065787069726174696f6e29a265627a7a7231582098247ec3c8d127ebf969c8f317e340b1cd6c481af077234c38e0c7d92aba4d6364736f6c634300050b0032" + }, + "5973918275C01F50555d44e92c9d9b353CaDAD54": { + "balance": "0x3635c9adc5dea00000" + }, + "b8bB158B93c94ed35c1970D610d1E2B34E26652c": { + "balance": "0x3635c9adc5dea00000" + }, + "F84C74dEa96DF0EC22e11e7C33996C73FCC2D822": { + "balance": "0x3635c9adc5dea00000" + }, + "b702f1C9154ac9c08Da247a8e30ee6F2F3373f41": { + "balance": "0x3635c9adc5dea00000" + }, + "7fCD58C2D53D980b247F1612FdbA93E9a76193E6": { + "balance": "0x3635c9adc5dea00000" + }, + "0375b2fc7140977c9c76D45421564e354ED42277": { + "balance": "0x3635c9adc5dea00000" + }, + "42EEfcda06eaD475cdE3731B8eb138e88CD0bAC3": { + "balance": "0x3635c9adc5dea00000" + } +} diff --git a/command/server/chains/allocs/mumbai.json b/command/server/chains/allocs/mumbai.json new file mode 100644 index 0000000000..e90415e319 --- /dev/null +++ b/command/server/chains/allocs/mumbai.json @@ -0,0 +1,30 @@ +{ + "0000000000000000000000000000000000001000": { + "balance": "0x0", + "code": "0x608060405234801561001057600080fd5b50600436106101f05760003560e01c806360c8614d1161010f578063af26aa96116100a2578063d5b844eb11610071578063d5b844eb14610666578063dcf2793a14610684578063e3b7c924146106b6578063f59cf565146106d4576101f0565b8063af26aa96146105c7578063b71d7a69146105e7578063b7ab4db514610617578063c1b3c91914610636576101f0565b806370ba5707116100de57806370ba57071461052b57806398ab2b621461055b5780639d11b80714610579578063ae756451146105a9576101f0565b806360c8614d1461049c57806365b3a1e2146104bc57806366332354146104db578063687a9bd6146104f9576101f0565b80633434735f1161018757806344d6528f1161015657806344d6528f146103ee5780634dbc959f1461041e57806355614fcc1461043c578063582a8d081461046c576101f0565b80633434735f1461035257806335ddfeea1461037057806343ee8213146103a057806344c15cb1146103be576101f0565b806323f2a73f116101c357806323f2a73f146102a45780632bc06564146102d45780632de3a180146102f25780632eddf35214610322576101f0565b8063047a6c5b146101f55780630c35b1cb146102275780631270b5741461025857806323c2a2b414610288575b600080fd5b61020f600480360361020a9190810190612b24565b610706565b60405161021e93929190613463565b60405180910390f35b610241600480360361023c9190810190612b24565b61075d565b60405161024f929190613284565b60405180910390f35b610272600480360361026d9190810190612b4d565b610939565b60405161027f91906132bb565b60405180910390f35b6102a2600480360361029d9190810190612c2c565b610a91565b005b6102be60048036036102b99190810190612b4d565b61112a565b6040516102cb91906132bb565b60405180910390f35b6102dc611281565b6040516102e99190613411565b60405180910390f35b61030c60048036036103079190810190612a81565b611286565b60405161031991906132d6565b60405180910390f35b61033c60048036036103379190810190612b24565b611307565b6040516103499190613411565b60405180910390f35b61035a611437565b6040516103679190613269565b60405180910390f35b61038a60048036036103859190810190612abd565b61144f565b60405161039791906132bb565b60405180910390f35b6103a861151a565b6040516103b591906132d6565b60405180910390f35b6103d860048036036103d39190810190612b89565b611531565b6040516103e59190613411565b60405180910390f35b61040860048036036104039190810190612b4d565b611619565b60405161041591906133f6565b60405180910390f35b610426611781565b6040516104339190613411565b60405180910390f35b61045660048036036104519190810190612a06565b611791565b60405161046391906132bb565b60405180910390f35b61048660048036036104819190810190612a2f565b6117ab565b60405161049391906132d6565b60405180910390f35b6104a4611829565b6040516104b393929190613463565b60405180910390f35b6104c461189d565b6040516104d2929190613284565b60405180910390f35b6104e3611b6e565b6040516104f09190613411565b60405180910390f35b610513600480360361050e9190810190612bf0565b611b73565b6040516105229392919061342c565b60405180910390f35b61054560048036036105409190810190612a06565b611bd7565b60405161055291906132bb565b60405180910390f35b610563611bf1565b60405161057091906132d6565b60405180910390f35b610593600480360361058e9190810190612b24565b611c08565b6040516105a09190613411565b60405180910390f35b6105b1611d39565b6040516105be91906132d6565b60405180910390f35b6105cf611d50565b6040516105de93929190613463565b60405180910390f35b61060160048036036105fc9190810190612b24565b611db1565b60405161060e9190613411565b60405180910390f35b61061f611eb1565b60405161062d929190613284565b60405180910390f35b610650600480360361064b9190810190612b24565b611ec5565b60405161065d9190613411565b60405180910390f35b61066e611ee6565b60405161067b919061349a565b60405180910390f35b61069e60048036036106999190810190612bf0565b611eeb565b6040516106ad9392919061342c565b60405180910390f35b6106be611f4f565b6040516106cb9190613411565b60405180910390f35b6106ee60048036036106e99190810190612b24565b611f61565b6040516106fd93929190613463565b60405180910390f35b60008060006002600085815260200190815260200160002060000154600260008681526020019081526020016000206001015460026000878152602001908152602001600020600201549250925092509193909250565b60608060ff83116107795761077061189d565b91509150610934565b600061078484611db1565b9050606060016000838152602001908152602001600020805490506040519080825280602002602001820160405280156107cd5781602001602082028038833980820191505090505b509050606060016000848152602001908152602001600020805490506040519080825280602002602001820160405280156108175781602001602082028038833980820191505090505b50905060008090505b60016000858152602001908152602001600020805490508110156109295760016000858152602001908152602001600020818154811061085c57fe5b906000526020600020906003020160020160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1683828151811061089a57fe5b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff16815250506001600085815260200190815260200160002081815481106108f257fe5b90600052602060002090600302016001015482828151811061091057fe5b6020026020010181815250508080600101915050610820565b508181945094505050505b915091565b6000606060016000858152602001908152602001600020805480602002602001604051908101604052809291908181526020016000905b82821015610a0c578382906000526020600020906003020160405180606001604052908160008201548152602001600182015481526020016002820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152505081526020019060010190610970565b50505050905060008090505b8151811015610a84578373ffffffffffffffffffffffffffffffffffffffff16828281518110610a4457fe5b60200260200101516040015173ffffffffffffffffffffffffffffffffffffffff161415610a7757600192505050610a8b565b8080600101915050610a18565b5060009150505b92915050565b73fffffffffffffffffffffffffffffffffffffffe73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610b13576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b0a906133d6565b60405180910390fd5b6000610b1d611781565b90506000811415610b3157610b30611f8b565b5b610b456001826122ac90919063ffffffff16565b8814610b86576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b7d90613356565b60405180910390fd5b868611610bc8576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610bbf906133b6565b60405180910390fd5b6000604060018989030181610bd957fe5b0614610c1a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c1190613396565b60405180910390fd5b8660026000838152602001908152602001600020600101541115610c73576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c6a90613336565b60405180910390fd5b6000600260008a81526020019081526020016000206000015414610ccc576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610cc390613376565b60405180910390fd5b604051806060016040528089815260200188815260200187815250600260008a8152602001908152602001600020600082015181600001556020820151816001015560408201518160020155905050600388908060018154018082558091505090600182039060005260206000200160009091929091909150555060008060008a815260200190815260200160002081610d669190612800565b506000600160008a815260200190815260200160002081610d879190612800565b506060610ddf610dda87878080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050506122cb565b6122f9565b905060008090505b8151811015610f51576060610e0e838381518110610e0157fe5b60200260200101516122f9565b90506000808c81526020019081526020016000208054809190600101610e349190612800565b506040518060600160405280610e5d83600081518110610e5057fe5b60200260200101516123d6565b8152602001610e7f83600181518110610e7257fe5b60200260200101516123d6565b8152602001610ea183600281518110610e9457fe5b6020026020010151612447565b73ffffffffffffffffffffffffffffffffffffffff168152506000808d81526020019081526020016000208381548110610ed757fe5b9060005260206000209060030201600082015181600001556020820151816001015560408201518160020160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550905050508080600101915050610de7565b506060610fa9610fa486868080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050506122cb565b6122f9565b905060008090505b815181101561111d576060610fd8838381518110610fcb57fe5b60200260200101516122f9565b9050600160008d81526020019081526020016000208054809190600101610fff9190612800565b5060405180606001604052806110288360008151811061101b57fe5b60200260200101516123d6565b815260200161104a8360018151811061103d57fe5b60200260200101516123d6565b815260200161106c8360028151811061105f57fe5b6020026020010151612447565b73ffffffffffffffffffffffffffffffffffffffff16815250600160008e815260200190815260200160002083815481106110a357fe5b9060005260206000209060030201600082015181600001556020820151816001015560408201518160020160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550905050508080600101915050610fb1565b5050505050505050505050565b60006060600080858152602001908152602001600020805480602002602001604051908101604052809291908181526020016000905b828210156111fc578382906000526020600020906003020160405180606001604052908160008201548152602001600182015481526020016002820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152505081526020019060010190611160565b50505050905060008090505b8151811015611274578373ffffffffffffffffffffffffffffffffffffffff1682828151811061123457fe5b60200260200101516040015173ffffffffffffffffffffffffffffffffffffffff1614156112675760019250505061127b565b8080600101915050611208565b5060009150505b92915050565b604081565b60006002600160f81b84846040516020016112a3939291906131d6565b6040516020818303038152906040526040516112bf9190613213565b602060405180830381855afa1580156112dc573d6000803e3d6000fd5b5050506040513d601f19601f820116820180604052506112ff9190810190612a58565b905092915050565b60006060600080848152602001908152602001600020805480602002602001604051908101604052809291908181526020016000905b828210156113d9578382906000526020600020906003020160405180606001604052908160008201548152602001600182015481526020016002820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815250508152602001906001019061133d565b505050509050600080905060008090505b825181101561142c5761141d83828151811061140257fe5b602002602001015160200151836122ac90919063ffffffff16565b915080806001019150506113ea565b508092505050919050565b73fffffffffffffffffffffffffffffffffffffffe81565b600080600080859050600060218087518161146657fe5b04029050600081111561147f5761147c876117ab565b91505b6000602190505b818111611509576000600182038801519050818801519550806000602081106114ab57fe5b1a60f81b9450600060f81b857effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614156114f0576114e98685611286565b93506114fd565b6114fa8487611286565b93505b50602181019050611486565b508782149450505050509392505050565b60405161152690613254565b604051809103902081565b60008060009050600080905060008090505b84518167ffffffffffffffff16101561160c57606061156e868367ffffffffffffffff16604161246a565b9050600061158582896124f690919063ffffffff16565b905061158f612832565b6115998a83611619565b90506115a58a8361112a565b80156115dc57508473ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16115b156115fe578194506115fb8160200151876122ac90919063ffffffff16565b95505b505050604181019050611543565b5081925050509392505050565b611621612832565b6060600080858152602001908152602001600020805480602002602001604051908101604052809291908181526020016000905b828210156116f1578382906000526020600020906003020160405180606001604052908160008201548152602001600182015481526020016002820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152505081526020019060010190611655565b50505050905060008090505b8151811015611779578373ffffffffffffffffffffffffffffffffffffffff1682828151811061172957fe5b60200260200101516040015173ffffffffffffffffffffffffffffffffffffffff16141561176c5781818151811061175d57fe5b60200260200101519250611779565b80806001019150506116fd565b505092915050565b600061178c43611db1565b905090565b60006117a461179e611781565b8361112a565b9050919050565b60006002600060f81b836040516020016117c69291906131aa565b6040516020818303038152906040526040516117e29190613213565b602060405180830381855afa1580156117ff573d6000803e3d6000fd5b5050506040513d601f19601f820116820180604052506118229190810190612a58565b9050919050565b60008060008061184a600161183c611781565b6122ac90919063ffffffff16565b905060026000828152602001908152602001600020600001546002600083815260200190815260200160002060010154600260008481526020019081526020016000206002015493509350935050909192565b606080606060056040519080825280602002602001820160405280156118d25781602001602082028038833980820191505090505b50905073c26880a0af2ea0c7e8130e6ec47af756465452e8816000815181106118f757fe5b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff168152505073be188d6641e8b680743a4815dfa0f6208038960f8160018151811061195357fe5b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff168152505073c275dc8be39f50d12f66b6a63629c39da5bae5bd816002815181106119af57fe5b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff168152505073f903ba9e006193c1527bfbe65fe2123704ea3f9981600381518110611a0b57fe5b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff168152505073928ed6a3e94437bbd316ccad78479f1d163a6a8c81600481518110611a6757fe5b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff168152505060606005604051908082528060200260200182016040528015611ad35781602001602082028038833980820191505090505b50905061271081600081518110611ae657fe5b60200260200101818152505061271081600181518110611b0257fe5b60200260200101818152505061271081600281518110611b1e57fe5b60200260200101818152505061271081600381518110611b3a57fe5b60200260200101818152505061271081600481518110611b5657fe5b60200260200101818152505081819350935050509091565b60ff81565b60016020528160005260406000208181548110611b8c57fe5b9060005260206000209060030201600091509150508060000154908060010154908060020160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905083565b6000611bea611be4611781565b83610939565b9050919050565b604051611bfd9061322a565b604051809103902081565b6000606060016000848152602001908152602001600020805480602002602001604051908101604052809291908181526020016000905b82821015611cdb578382906000526020600020906003020160405180606001604052908160008201548152602001600182015481526020016002820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152505081526020019060010190611c3f565b505050509050600080905060008090505b8251811015611d2e57611d1f838281518110611d0457fe5b602002602001015160200151836122ac90919063ffffffff16565b91508080600101915050611cec565b508092505050919050565b604051611d459061323f565b604051809103902081565b600080600080611d5e611781565b905060026000828152602001908152602001600020600001546002600083815260200190815260200160002060010154600260008481526020019081526020016000206002015493509350935050909192565b60008060038054905090505b6000811115611e7157611dce612869565b6002600060036001850381548110611de257fe5b906000526020600020015481526020019081526020016000206040518060600160405290816000820154815260200160018201548152602001600282015481525050905083816020015111158015611e3f57506000816040015114155b8015611e4f575080604001518411155b15611e6257806000015192505050611eac565b50808060019003915050611dbd565b5060006003805490501115611ea757600360016003805490500381548110611e9557fe5b90600052602060002001549050611eac565b600090505b919050565b606080611ebd4361075d565b915091509091565b60038181548110611ed257fe5b906000526020600020016000915090505481565b600281565b60006020528160005260406000208181548110611f0457fe5b9060005260206000209060030201600091509150508060000154908060010154908060020160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905083565b600060404381611f5b57fe5b04905090565b60026020528060005260406000206000915090508060000154908060010154908060020154905083565b606080611f9661189d565b8092508193505050600080905060405180606001604052808281526020016000815260200160ff81525060026000838152602001908152602001600020600082015181600001556020820151816001015560408201518160020155905050600381908060018154018082558091505090600182039060005260206000200160009091929091909150555060008060008381526020019081526020016000208161203f9190612800565b50600060016000838152602001908152602001600020816120609190612800565b5060008090505b83518110156121825760008083815260200190815260200160002080548091906001016120949190612800565b5060405180606001604052808281526020018483815181106120b257fe5b602002602001015181526020018583815181106120cb57fe5b602002602001015173ffffffffffffffffffffffffffffffffffffffff16815250600080848152602001908152602001600020828154811061210957fe5b9060005260206000209060030201600082015181600001556020820151816001015560408201518160020160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055509050508080600101915050612067565b5060008090505b83518110156122a6576001600083815260200190815260200160002080548091906001016121b79190612800565b5060405180606001604052808281526020018483815181106121d557fe5b602002602001015181526020018583815181106121ee57fe5b602002602001015173ffffffffffffffffffffffffffffffffffffffff1681525060016000848152602001908152602001600020828154811061222d57fe5b9060005260206000209060030201600082015181600001556020820151816001015560408201518160020160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055509050508080600101915050612189565b50505050565b6000808284019050838110156122c157600080fd5b8091505092915050565b6122d361288a565b600060208301905060405180604001604052808451815260200182815250915050919050565b606061230482612600565b61230d57600080fd5b60006123188361264e565b905060608160405190808252806020026020018201604052801561235657816020015b6123436128a4565b81526020019060019003908161233b5790505b509050600061236885602001516126bf565b8560200151019050600080600090505b848110156123c95761238983612748565b91506040518060400160405280838152602001848152508482815181106123ac57fe5b602002602001018190525081830192508080600101915050612378565b5082945050505050919050565b60008082600001511180156123f057506021826000015111155b6123f957600080fd5b600061240883602001516126bf565b9050600081846000015103905060008083866020015101905080519150602083101561243b57826020036101000a820491505b81945050505050919050565b6000601582600001511461245a57600080fd5b612463826123d6565b9050919050565b60608183018451101561247c57600080fd5b6060821560008114612499576040519150602082016040526124ea565b6040519150601f8416801560200281840101858101878315602002848b0101015b818310156124d757805183526020830192506020810190506124ba565b50868552601f19601f8301166040525050505b50809150509392505050565b600080600080604185511461251157600093505050506125fa565b602085015192506040850151915060ff6041860151169050601b8160ff16101561253c57601b810190505b601b8160ff16141580156125545750601c8160ff1614155b1561256557600093505050506125fa565b60006001878386866040516000815260200160405260405161258a94939291906132f1565b6020604051602081039080840390855afa1580156125ac573d6000803e3d6000fd5b505050602060405103519050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614156125f257600080fd5b809450505050505b92915050565b600080826000015114156126175760009050612649565b60008083602001519050805160001a915060c060ff168260ff16101561264257600092505050612649565b6001925050505b919050565b6000808260000151141561266557600090506126ba565b6000809050600061267984602001516126bf565b84602001510190506000846000015185602001510190505b808210156126b3576126a282612748565b820191508280600101935050612691565b8293505050505b919050565b600080825160001a9050608060ff168110156126df576000915050612743565b60b860ff16811080612704575060c060ff168110158015612703575060f860ff1681105b5b15612713576001915050612743565b60c060ff168110156127335760018060b80360ff16820301915050612743565b60018060f80360ff168203019150505b919050565b6000806000835160001a9050608060ff1681101561276957600191506127f6565b60b860ff16811015612786576001608060ff1682030191506127f5565b60c060ff168110156127b65760b78103600185019450806020036101000a855104600182018101935050506127f4565b60f860ff168110156127d357600160c060ff1682030191506127f3565b60f78103600185019450806020036101000a855104600182018101935050505b5b5b5b8192505050919050565b81548183558181111561282d5760030281600302836000526020600020918201910161282c91906128be565b5b505050565b60405180606001604052806000815260200160008152602001600073ffffffffffffffffffffffffffffffffffffffff1681525090565b60405180606001604052806000815260200160008152602001600081525090565b604051806040016040528060008152602001600081525090565b604051806040016040528060008152602001600081525090565b61291191905b8082111561290d5760008082016000905560018201600090556002820160006101000a81549073ffffffffffffffffffffffffffffffffffffffff0219169055506003016128c4565b5090565b90565b60008135905061292381613693565b92915050565b600081359050612938816136aa565b92915050565b60008151905061294d816136aa565b92915050565b60008083601f84011261296557600080fd5b8235905067ffffffffffffffff81111561297e57600080fd5b60208301915083600182028301111561299657600080fd5b9250929050565b600082601f8301126129ae57600080fd5b81356129c16129bc826134e2565b6134b5565b915080825260208301602083018583830111156129dd57600080fd5b6129e883828461363d565b50505092915050565b600081359050612a00816136c1565b92915050565b600060208284031215612a1857600080fd5b6000612a2684828501612914565b91505092915050565b600060208284031215612a4157600080fd5b6000612a4f84828501612929565b91505092915050565b600060208284031215612a6a57600080fd5b6000612a788482850161293e565b91505092915050565b60008060408385031215612a9457600080fd5b6000612aa285828601612929565b9250506020612ab385828601612929565b9150509250929050565b600080600060608486031215612ad257600080fd5b6000612ae086828701612929565b9350506020612af186828701612929565b925050604084013567ffffffffffffffff811115612b0e57600080fd5b612b1a8682870161299d565b9150509250925092565b600060208284031215612b3657600080fd5b6000612b44848285016129f1565b91505092915050565b60008060408385031215612b6057600080fd5b6000612b6e858286016129f1565b9250506020612b7f85828601612914565b9150509250929050565b600080600060608486031215612b9e57600080fd5b6000612bac868287016129f1565b9350506020612bbd86828701612929565b925050604084013567ffffffffffffffff811115612bda57600080fd5b612be68682870161299d565b9150509250925092565b60008060408385031215612c0357600080fd5b6000612c11858286016129f1565b9250506020612c22858286016129f1565b9150509250929050565b600080600080600080600060a0888a031215612c4757600080fd5b6000612c558a828b016129f1565b9750506020612c668a828b016129f1565b9650506040612c778a828b016129f1565b955050606088013567ffffffffffffffff811115612c9457600080fd5b612ca08a828b01612953565b9450945050608088013567ffffffffffffffff811115612cbf57600080fd5b612ccb8a828b01612953565b925092505092959891949750929550565b6000612ce88383612d0c565b60208301905092915050565b6000612d00838361317d565b60208301905092915050565b612d15816135b2565b82525050565b612d24816135b2565b82525050565b6000612d358261352e565b612d3f8185613569565b9350612d4a8361350e565b8060005b83811015612d7b578151612d628882612cdc565b9750612d6d8361354f565b925050600181019050612d4e565b5085935050505092915050565b6000612d9382613539565b612d9d818561357a565b9350612da88361351e565b8060005b83811015612dd9578151612dc08882612cf4565b9750612dcb8361355c565b925050600181019050612dac565b5085935050505092915050565b612def816135c4565b82525050565b612e06612e01826135d0565b61367f565b82525050565b612e15816135fc565b82525050565b612e2c612e27826135fc565b613689565b82525050565b6000612e3d82613544565b612e47818561358b565b9350612e5781856020860161364c565b80840191505092915050565b6000612e706004836135a7565b91507f766f7465000000000000000000000000000000000000000000000000000000006000830152600482019050919050565b6000612eb0602d83613596565b91507f537461727420626c6f636b206d7573742062652067726561746572207468616e60008301527f2063757272656e74207370616e000000000000000000000000000000000000006020830152604082019050919050565b6000612f16600f83613596565b91507f496e76616c6964207370616e20696400000000000000000000000000000000006000830152602082019050919050565b6000612f56601383613596565b91507f5370616e20616c726561647920657869737473000000000000000000000000006000830152602082019050919050565b6000612f96604583613596565b91507f446966666572656e6365206265747765656e20737461727420616e6420656e6460008301527f20626c6f636b206d75737420626520696e206d756c7469706c6573206f66207360208301527f7072696e740000000000000000000000000000000000000000000000000000006040830152606082019050919050565b6000613022602a83613596565b91507f456e6420626c6f636b206d7573742062652067726561746572207468616e207360008301527f7461727420626c6f636b000000000000000000000000000000000000000000006020830152604082019050919050565b6000613088601283613596565b91507f4e6f742053797374656d204164646573732100000000000000000000000000006000830152602082019050919050565b60006130c86005836135a7565b91507f38303030310000000000000000000000000000000000000000000000000000006000830152600582019050919050565b6000613108600e836135a7565b91507f6865696d64616c6c2d38303030310000000000000000000000000000000000006000830152600e82019050919050565b606082016000820151613151600085018261317d565b506020820151613164602085018261317d565b5060408201516131776040850182612d0c565b50505050565b61318681613626565b82525050565b61319581613626565b82525050565b6131a481613630565b82525050565b60006131b68285612df5565b6001820191506131c68284612e1b565b6020820191508190509392505050565b60006131e28286612df5565b6001820191506131f28285612e1b565b6020820191506132028284612e1b565b602082019150819050949350505050565b600061321f8284612e32565b915081905092915050565b600061323582612e63565b9150819050919050565b600061324a826130bb565b9150819050919050565b600061325f826130fb565b9150819050919050565b600060208201905061327e6000830184612d1b565b92915050565b6000604082019050818103600083015261329e8185612d2a565b905081810360208301526132b28184612d88565b90509392505050565b60006020820190506132d06000830184612de6565b92915050565b60006020820190506132eb6000830184612e0c565b92915050565b60006080820190506133066000830187612e0c565b613313602083018661319b565b6133206040830185612e0c565b61332d6060830184612e0c565b95945050505050565b6000602082019050818103600083015261334f81612ea3565b9050919050565b6000602082019050818103600083015261336f81612f09565b9050919050565b6000602082019050818103600083015261338f81612f49565b9050919050565b600060208201905081810360008301526133af81612f89565b9050919050565b600060208201905081810360008301526133cf81613015565b9050919050565b600060208201905081810360008301526133ef8161307b565b9050919050565b600060608201905061340b600083018461313b565b92915050565b6000602082019050613426600083018461318c565b92915050565b6000606082019050613441600083018661318c565b61344e602083018561318c565b61345b6040830184612d1b565b949350505050565b6000606082019050613478600083018661318c565b613485602083018561318c565b613492604083018461318c565b949350505050565b60006020820190506134af600083018461319b565b92915050565b6000604051905081810181811067ffffffffffffffff821117156134d857600080fd5b8060405250919050565b600067ffffffffffffffff8211156134f957600080fd5b601f19601f8301169050602081019050919050565b6000819050602082019050919050565b6000819050602082019050919050565b600081519050919050565b600081519050919050565b600081519050919050565b6000602082019050919050565b6000602082019050919050565b600082825260208201905092915050565b600082825260208201905092915050565b600081905092915050565b600082825260208201905092915050565b600081905092915050565b60006135bd82613606565b9050919050565b60008115159050919050565b60007fff0000000000000000000000000000000000000000000000000000000000000082169050919050565b6000819050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b600060ff82169050919050565b82818337600083830152505050565b60005b8381101561366a57808201518184015260208101905061364f565b83811115613679576000848401525b50505050565b6000819050919050565b6000819050919050565b61369c816135b2565b81146136a757600080fd5b50565b6136b3816135fc565b81146136be57600080fd5b50565b6136ca81613626565b81146136d557600080fd5b5056fea365627a7a723158208f52ee07630ffe523cc6ad3e15f437f973dcfa36729cd697f9b0fc4a145a48f06c6578706572696d656e74616cf564736f6c634300050b0040" + }, + "0000000000000000000000000000000000001001": { + "balance": "0x0", + "code": "0x608060405234801561001057600080fd5b50600436106100415760003560e01c806319494a17146100465780633434735f146100e15780635407ca671461012b575b600080fd5b6100c76004803603604081101561005c57600080fd5b81019080803590602001909291908035906020019064010000000081111561008357600080fd5b82018360208201111561009557600080fd5b803590602001918460018302840111640100000000831117156100b757600080fd5b9091929391929390505050610149565b604051808215151515815260200191505060405180910390f35b6100e961047a565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b610133610492565b6040518082815260200191505060405180910390f35b600073fffffffffffffffffffffffffffffffffffffffe73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610200576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260128152602001807f4e6f742053797374656d2041646465737321000000000000000000000000000081525060200191505060405180910390fd5b606061025761025285858080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050610498565b6104c6565b905060006102788260008151811061026b57fe5b60200260200101516105a3565b905080600160005401146102f4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601b8152602001807f537461746549647320617265206e6f742073657175656e7469616c000000000081525060200191505060405180910390fd5b600080815480929190600101919050555060006103248360018151811061031757fe5b6020026020010151610614565b905060606103458460028151811061033857fe5b6020026020010151610637565b9050610350826106c3565b1561046f576000624c4b409050606084836040516024018083815260200180602001828103825283818151815260200191508051906020019080838360005b838110156103aa57808201518184015260208101905061038f565b50505050905090810190601f1680156103d75780820380516001836020036101000a031916815260200191505b5093505050506040516020818303038152906040527f26c53bea000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050905060008082516020840160008887f1965050505b505050509392505050565b73fffffffffffffffffffffffffffffffffffffffe81565b60005481565b6104a0610943565b600060208301905060405180604001604052808451815260200182815250915050919050565b60606104d1826106dc565b6104da57600080fd5b60006104e58361072a565b905060608160405190808252806020026020018201604052801561052357816020015b61051061095d565b8152602001906001900390816105085790505b5090506000610535856020015161079b565b8560200151019050600080600090505b848110156105965761055683610824565b915060405180604001604052808381526020018481525084828151811061057957fe5b602002602001018190525081830192508080600101915050610545565b5082945050505050919050565b60008082600001511180156105bd57506021826000015111155b6105c657600080fd5b60006105d5836020015161079b565b9050600081846000015103905060008083866020015101905080519150602083101561060857826020036101000a820491505b81945050505050919050565b6000601582600001511461062757600080fd5b610630826105a3565b9050919050565b6060600082600001511161064a57600080fd5b6000610659836020015161079b565b905060008184600001510390506060816040519080825280601f01601f19166020018201604052801561069b5781602001600182028038833980820191505090505b50905060008160200190506106b78487602001510182856108dc565b81945050505050919050565b600080823b905060008163ffffffff1611915050919050565b600080826000015114156106f35760009050610725565b60008083602001519050805160001a915060c060ff168260ff16101561071e57600092505050610725565b6001925050505b919050565b600080826000015114156107415760009050610796565b60008090506000610755846020015161079b565b84602001510190506000846000015185602001510190505b8082101561078f5761077e82610824565b82019150828060010193505061076d565b8293505050505b919050565b600080825160001a9050608060ff168110156107bb57600091505061081f565b60b860ff168110806107e0575060c060ff1681101580156107df575060f860ff1681105b5b156107ef57600191505061081f565b60c060ff1681101561080f5760018060b80360ff1682030191505061081f565b60018060f80360ff168203019150505b919050565b6000806000835160001a9050608060ff1681101561084557600191506108d2565b60b860ff16811015610862576001608060ff1682030191506108d1565b60c060ff168110156108925760b78103600185019450806020036101000a855104600182018101935050506108d0565b60f860ff168110156108af57600160c060ff1682030191506108cf565b60f78103600185019450806020036101000a855104600182018101935050505b5b5b5b8192505050919050565b60008114156108ea5761093e565b5b602060ff16811061091a5782518252602060ff1683019250602060ff1682019150602060ff16810390506108eb565b6000600182602060ff16036101000a03905080198451168184511681811785525050505b505050565b604051806040016040528060008152602001600081525090565b60405180604001604052806000815260200160008152509056fea265627a7a7231582083fbdacb76f32b4112d0f7db9a596937925824798a0026ba0232322390b5263764736f6c634300050b0032" + }, + "0000000000000000000000000000000000001010": { + "balance": "0x204fcd4f31349d83b6e00000", + "code": "0x60806040526004361061019c5760003560e01c806377d32e94116100ec578063acd06cb31161008a578063e306f77911610064578063e306f77914610a7b578063e614d0d614610aa6578063f2fde38b14610ad1578063fc0c546a14610b225761019c565b8063acd06cb31461097a578063b789543c146109cd578063cc79f97b14610a505761019c565b80639025e64c116100c65780639025e64c146107c957806395d89b4114610859578063a9059cbb146108e9578063abceeba21461094f5761019c565b806377d32e94146106315780638da5cb5b146107435780638f32d59b1461079a5761019c565b806347e7ef24116101595780637019d41a116101335780637019d41a1461053357806370a082311461058a578063715018a6146105ef578063771282f6146106065761019c565b806347e7ef2414610410578063485cc9551461046b57806360f96a8f146104dc5761019c565b806306fdde03146101a15780631499c5921461023157806318160ddd1461028257806319d27d9c146102ad5780632e1a7d4d146103b1578063313ce567146103df575b600080fd5b3480156101ad57600080fd5b506101b6610b79565b6040518080602001828103825283818151815260200191508051906020019080838360005b838110156101f65780820151818401526020810190506101db565b50505050905090810190601f1680156102235780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561023d57600080fd5b506102806004803603602081101561025457600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610bb6565b005b34801561028e57600080fd5b50610297610c24565b6040518082815260200191505060405180910390f35b3480156102b957600080fd5b5061036f600480360360a08110156102d057600080fd5b81019080803590602001906401000000008111156102ed57600080fd5b8201836020820111156102ff57600080fd5b8035906020019184600183028401116401000000008311171561032157600080fd5b9091929391929390803590602001909291908035906020019092919080359060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610c3a565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6103dd600480360360208110156103c757600080fd5b8101908080359060200190929190505050610e06565b005b3480156103eb57600080fd5b506103f4610f58565b604051808260ff1660ff16815260200191505060405180910390f35b34801561041c57600080fd5b506104696004803603604081101561043357600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050610f61565b005b34801561047757600080fd5b506104da6004803603604081101561048e57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff16906020019092919050505061111d565b005b3480156104e857600080fd5b506104f16111ec565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b34801561053f57600080fd5b50610548611212565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b34801561059657600080fd5b506105d9600480360360208110156105ad57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050611238565b6040518082815260200191505060405180910390f35b3480156105fb57600080fd5b50610604611259565b005b34801561061257600080fd5b5061061b611329565b6040518082815260200191505060405180910390f35b34801561063d57600080fd5b506107016004803603604081101561065457600080fd5b81019080803590602001909291908035906020019064010000000081111561067b57600080fd5b82018360208201111561068d57600080fd5b803590602001918460018302840111640100000000831117156106af57600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050919291929050505061132f565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b34801561074f57600080fd5b506107586114b4565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b3480156107a657600080fd5b506107af6114dd565b604051808215151515815260200191505060405180910390f35b3480156107d557600080fd5b506107de611534565b6040518080602001828103825283818151815260200191508051906020019080838360005b8381101561081e578082015181840152602081019050610803565b50505050905090810190601f16801561084b5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561086557600080fd5b5061086e61156d565b6040518080602001828103825283818151815260200191508051906020019080838360005b838110156108ae578082015181840152602081019050610893565b50505050905090810190601f1680156108db5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b610935600480360360408110156108ff57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803590602001909291905050506115aa565b604051808215151515815260200191505060405180910390f35b34801561095b57600080fd5b506109646115d0565b6040518082815260200191505060405180910390f35b34801561098657600080fd5b506109b36004803603602081101561099d57600080fd5b810190808035906020019092919050505061165d565b604051808215151515815260200191505060405180910390f35b3480156109d957600080fd5b50610a3a600480360360808110156109f057600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190803590602001909291908035906020019092919050505061167d565b6040518082815260200191505060405180910390f35b348015610a5c57600080fd5b50610a6561169d565b6040518082815260200191505060405180910390f35b348015610a8757600080fd5b50610a906116a4565b6040518082815260200191505060405180910390f35b348015610ab257600080fd5b50610abb6116aa565b6040518082815260200191505060405180910390f35b348015610add57600080fd5b50610b2060048036036020811015610af457600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050611737565b005b348015610b2e57600080fd5b50610b37611754565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b60606040518060400160405280600b81526020017f4d6174696320546f6b656e000000000000000000000000000000000000000000815250905090565b6040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260108152602001807f44697361626c656420666561747572650000000000000000000000000000000081525060200191505060405180910390fd5b6000601260ff16600a0a6402540be40002905090565b6000808511610c4857600080fd5b6000831480610c575750824311155b610cc9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260148152602001807f5369676e6174757265206973206578706972656400000000000000000000000081525060200191505060405180910390fd5b6000610cd73387878761167d565b9050600015156005600083815260200190815260200160002060009054906101000a900460ff16151514610d73576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600f8152602001807f536967206465616374697661746564000000000000000000000000000000000081525060200191505060405180910390fd5b60016005600083815260200190815260200160002060006101000a81548160ff021916908315150217905550610ded8189898080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505061132f565b9150610dfa82848861177a565b50509695505050505050565b60003390506000610e1682611238565b9050610e2d83600654611b3790919063ffffffff16565b600681905550600083118015610e4257508234145b610eb4576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260138152602001807f496e73756666696369656e7420616d6f756e740000000000000000000000000081525060200191505060405180910390fd5b8173ffffffffffffffffffffffffffffffffffffffff16600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167febff2602b3f468259e1e99f613fed6691f3a6526effe6ef3e768ba7ae7a36c4f8584610f3087611238565b60405180848152602001838152602001828152602001935050505060405180910390a3505050565b60006012905090565b610f696114dd565b610f7257600080fd5b600081118015610faf5750600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614155b611004576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526023815260200180611e636023913960400191505060405180910390fd5b600061100f83611238565b905060008390508073ffffffffffffffffffffffffffffffffffffffff166108fc849081150290604051600060405180830381858888f1935050505015801561105c573d6000803e3d6000fd5b5061107283600654611b5790919063ffffffff16565b6006819055508373ffffffffffffffffffffffffffffffffffffffff16600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f4e2ca0515ed1aef1395f66b5303bb5d6f1bf9d61a353fa53f73f8ac9973fa9f685856110f489611238565b60405180848152602001838152602001828152602001935050505060405180910390a350505050565b600760009054906101000a900460ff1615611183576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526023815260200180611e406023913960400191505060405180910390fd5b6001600760006101000a81548160ff02191690831515021790555080600260006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506111e882611b76565b5050565b600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60008173ffffffffffffffffffffffffffffffffffffffff16319050919050565b6112616114dd565b61126a57600080fd5b600073ffffffffffffffffffffffffffffffffffffffff166000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a360008060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550565b60065481565b600080600080604185511461134a57600093505050506114ae565b602085015192506040850151915060ff6041860151169050601b8160ff16101561137557601b810190505b601b8160ff161415801561138d5750601c8160ff1614155b1561139e57600093505050506114ae565b60018682858560405160008152602001604052604051808581526020018460ff1660ff1681526020018381526020018281526020019450505050506020604051602081039080840390855afa1580156113fb573d6000803e3d6000fd5b505050602060405103519350600073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1614156114aa576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260128152602001807f4572726f7220696e2065637265636f766572000000000000000000000000000081525060200191505060405180910390fd5b5050505b92915050565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614905090565b6040518060400160405280600381526020017f013881000000000000000000000000000000000000000000000000000000000081525081565b60606040518060400160405280600581526020017f4d41544943000000000000000000000000000000000000000000000000000000815250905090565b60008134146115bc57600090506115ca565b6115c733848461177a565b90505b92915050565b6040518060800160405280605b8152602001611ed8605b91396040516020018082805190602001908083835b6020831061161f57805182526020820191506020810190506020830392506115fc565b6001836020036101000a0380198251168184511680821785525050505050509050019150506040516020818303038152906040528051906020012081565b60056020528060005260406000206000915054906101000a900460ff1681565b600061169361168e86868686611c6e565b611d44565b9050949350505050565b6201388181565b60015481565b604051806080016040528060528152602001611e86605291396040516020018082805190602001908083835b602083106116f957805182526020820191506020810190506020830392506116d6565b6001836020036101000a0380198251168184511680821785525050505050509050019150506040516020818303038152906040528051906020012081565b61173f6114dd565b61174857600080fd5b61175181611b76565b50565b600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6000803073ffffffffffffffffffffffffffffffffffffffff166370a08231866040518263ffffffff1660e01b8152600401808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060206040518083038186803b1580156117fa57600080fd5b505afa15801561180e573d6000803e3d6000fd5b505050506040513d602081101561182457600080fd5b8101908080519060200190929190505050905060003073ffffffffffffffffffffffffffffffffffffffff166370a08231866040518263ffffffff1660e01b8152600401808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060206040518083038186803b1580156118b657600080fd5b505afa1580156118ca573d6000803e3d6000fd5b505050506040513d60208110156118e057600080fd5b810190808051906020019092919050505090506118fe868686611d8e565b8473ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff16600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167fe6497e3ee548a3372136af2fcb0696db31fc6cf20260707645068bd3fe97f3c48786863073ffffffffffffffffffffffffffffffffffffffff166370a082318e6040518263ffffffff1660e01b8152600401808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060206040518083038186803b158015611a0657600080fd5b505afa158015611a1a573d6000803e3d6000fd5b505050506040513d6020811015611a3057600080fd5b81019080805190602001909291905050503073ffffffffffffffffffffffffffffffffffffffff166370a082318e6040518263ffffffff1660e01b8152600401808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060206040518083038186803b158015611abe57600080fd5b505afa158015611ad2573d6000803e3d6000fd5b505050506040513d6020811015611ae857600080fd5b8101908080519060200190929190505050604051808681526020018581526020018481526020018381526020018281526020019550505050505060405180910390a46001925050509392505050565b600082821115611b4657600080fd5b600082840390508091505092915050565b600080828401905083811015611b6c57600080fd5b8091505092915050565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415611bb057600080fd5b8073ffffffffffffffffffffffffffffffffffffffff166000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a3806000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b6000806040518060800160405280605b8152602001611ed8605b91396040516020018082805190602001908083835b60208310611cc05780518252602082019150602081019050602083039250611c9d565b6001836020036101000a03801982511681845116808217855250505050505090500191505060405160208183030381529060405280519060200120905060405181815273ffffffffffffffffffffffffffffffffffffffff8716602082015285604082015284606082015283608082015260a0812092505081915050949350505050565b60008060015490506040517f190100000000000000000000000000000000000000000000000000000000000081528160028201528360228201526042812092505081915050919050565b8173ffffffffffffffffffffffffffffffffffffffff166108fc829081150290604051600060405180830381858888f19350505050158015611dd4573d6000803e3d6000fd5b508173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef836040518082815260200191505060405180910390a350505056fe54686520636f6e747261637420697320616c726561647920696e697469616c697a6564496e73756666696369656e7420616d6f756e74206f7220696e76616c69642075736572454950373132446f6d61696e28737472696e67206e616d652c737472696e672076657273696f6e2c75696e7432353620636861696e49642c6164647265737320766572696679696e67436f6e747261637429546f6b656e5472616e736665724f726465722861646472657373207370656e6465722c75696e7432353620746f6b656e49644f72416d6f756e742c6279746573333220646174612c75696e743235362065787069726174696f6e29a265627a7a723158208f81700133738d766ae3d68af591ad588b0125bd91449192179f460893f79f6b64736f6c634300050b0032" + }, + "C26880A0AF2EA0c7E8130e6EC47Af756465452E8": { + "balance": "0x3635c9adc5dea00000" + }, + "be188D6641E8b680743A4815dFA0f6208038960F": { + "balance": "0x3635c9adc5dea00000" + }, + "c275DC8bE39f50D12F66B6a63629C39dA5BAe5bd": { + "balance": "0x3635c9adc5dea00000" + }, + "F903ba9E006193c1527BfBe65fe2123704EA3F99": { + "balance": "0x3635c9adc5dea00000" + }, + "928Ed6A3e94437bbd316cCAD78479f1d163A6A8C": { + "balance": "0x3635c9adc5dea00000" + } + } + \ No newline at end of file diff --git a/command/server/chains/mainnet.go b/command/server/chains/mainnet.go new file mode 100644 index 0000000000..ad92979ff7 --- /dev/null +++ b/command/server/chains/mainnet.go @@ -0,0 +1,61 @@ +package chains + +import ( + "math/big" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core" + "github.com/ethereum/go-ethereum/params" +) + +var BorMainnetGenesisHash = common.HexToHash("0xa9c28ce2141b56c474f1dc504bee9b01eb1bd7d1a507580d5519d4437a97de1b") + +var BorMainnetChainConfig = ¶ms.ChainConfig{ + ChainID: big.NewInt(137), + HomesteadBlock: big.NewInt(0), + DAOForkBlock: nil, + DAOForkSupport: true, + EIP150Hash: common.HexToHash("0x0000000000000000000000000000000000000000000000000000000000000000"), + EIP150Block: big.NewInt(0), + EIP155Block: big.NewInt(0), + EIP158Block: big.NewInt(0), + ByzantiumBlock: big.NewInt(0), + ConstantinopleBlock: big.NewInt(0), + PetersburgBlock: big.NewInt(0), + IstanbulBlock: big.NewInt(3395000), + MuirGlacierBlock: big.NewInt(3395000), + BerlinBlock: big.NewInt(14750000), + Bor: ¶ms.BorConfig{ + Period: 2, + ProducerDelay: 6, + Sprint: 64, + BackupMultiplier: 2, + ValidatorContract: "0x0000000000000000000000000000000000001000", + StateReceiverContract: "0x0000000000000000000000000000000000001001", + OverrideStateSyncRecords: map[string]int{ + "14949120": 8, + "14949184": 0, + "14953472": 0, + "14953536": 5, + "14953600": 0, + "14953664": 0, + "14953728": 0, + "14953792": 0, + "14953856": 0, + }, + }, +} + +//DefaultBorMainnet returns the Bor Mainnet network gensis block. +func DefaultBorMainnetGenesisBlock() *core.Genesis { + return &core.Genesis{ + Config: BorMainnetChainConfig, + Nonce: 0, + Timestamp: 1590824836, + GasLimit: 10000000, + Difficulty: big.NewInt(1), + Mixhash: common.HexToHash("0x0000000000000000000000000000000000000000000000000000000000000000"), + Coinbase: common.HexToAddress("0x0000000000000000000000000000000000000000"), + Alloc: readPrealloc("allocs/bor_mainnet.json"), + } +} diff --git a/command/server/chains/mumbai.go b/command/server/chains/mumbai.go new file mode 100644 index 0000000000..8a0af6dfdc --- /dev/null +++ b/command/server/chains/mumbai.go @@ -0,0 +1,49 @@ +package chains + +import ( + "math/big" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core" + "github.com/ethereum/go-ethereum/params" +) + +var MumbaiGenesisHash = common.HexToHash("0x7b66506a9ebdbf30d32b43c5f15a3b1216269a1ec3a75aa3182b86176a2b1ca7") + +var MumbaiChainConfig = ¶ms.ChainConfig{ + ChainID: big.NewInt(80001), + HomesteadBlock: big.NewInt(0), + DAOForkBlock: nil, + DAOForkSupport: true, + EIP150Hash: common.HexToHash("0x0000000000000000000000000000000000000000000000000000000000000000"), + EIP150Block: big.NewInt(0), + EIP155Block: big.NewInt(0), + EIP158Block: big.NewInt(0), + ByzantiumBlock: big.NewInt(0), + ConstantinopleBlock: big.NewInt(0), + PetersburgBlock: big.NewInt(0), + IstanbulBlock: big.NewInt(2722000), + MuirGlacierBlock: big.NewInt(2722000), + BerlinBlock: big.NewInt(13996000), + Bor: ¶ms.BorConfig{ + Period: 2, + ProducerDelay: 6, + Sprint: 64, + BackupMultiplier: 2, + ValidatorContract: "0x0000000000000000000000000000000000001000", + StateReceiverContract: "0x0000000000000000000000000000000000001001", + }, +} + +func DefaultMumbaiGenesisBlock() *core.Genesis { + return &core.Genesis{ + Config: MumbaiChainConfig, + Nonce: 0, + Timestamp: 1558348305, + GasLimit: 10000000, + Difficulty: big.NewInt(1), + Mixhash: common.HexToHash("0x0000000000000000000000000000000000000000000000000000000000000000"), + Coinbase: common.HexToAddress("0x0000000000000000000000000000000000000000"), + Alloc: readPrealloc("allocs/mumbai.json"), + } +} diff --git a/command/server/chains/utils.go b/command/server/chains/utils.go new file mode 100644 index 0000000000..5f2f761ea4 --- /dev/null +++ b/command/server/chains/utils.go @@ -0,0 +1,27 @@ +package chains + +import ( + "embed" + "encoding/json" + "fmt" + + "github.com/ethereum/go-ethereum/core" +) + +//go:embed allocs +var allocs embed.FS + +func readPrealloc(filename string) core.GenesisAlloc { + f, err := allocs.Open(filename) + if err != nil { + panic(fmt.Sprintf("Could not open genesis preallocation for %s: %v", filename, err)) + } + defer f.Close() + decoder := json.NewDecoder(f) + ga := make(core.GenesisAlloc) + err = decoder.Decode(&ga) + if err != nil { + panic(fmt.Sprintf("Could not parse genesis preallocation for %s: %v", filename, err)) + } + return ga +} diff --git a/command/server/command.go b/command/server/command.go index 402a9c99d3..985971e510 100644 --- a/command/server/command.go +++ b/command/server/command.go @@ -33,12 +33,15 @@ type Command struct { // Help implements the cli.Command interface func (c *Command) Help() string { - return "" + return `Usage: bor [options] + + Run the Bor server. + ` + c.Flags().Help() } // Synopsis implements the cli.Command interface func (c *Command) Synopsis() string { - return "" + return "Run the Bor server" } // Run implements the cli.Command interface diff --git a/command/server/config.go b/command/server/config.go index a6d01a1dca..8977c6372b 100644 --- a/command/server/config.go +++ b/command/server/config.go @@ -1,7 +1,9 @@ package server import ( + "fmt" "strconv" + "time" "github.com/ethereum/go-ethereum/common/fdlimit" "github.com/ethereum/go-ethereum/eth/downloader" @@ -23,28 +25,86 @@ func boolPtr(b bool) *bool { return &b } +func durPtr(d time.Duration) *time.Duration { + return &d +} + type Config struct { + Chain *string Debug *bool LogLevel *string DataDir *string P2P *P2PConfig + SyncMode *string + EthStats *string + TxPool *TxPoolConfig + Sealer *SealerConfig } type P2PConfig struct { - MaxPeers *uint64 - Bind *string - Port *uint64 + MaxPeers *uint64 + Bind *string + Port *uint64 + NoDiscover *bool + V5Disc *bool + Bootnodes []string + BootnodesV4 []string + BootnodesV5 []string +} + +type TxPoolConfig struct { + Locals []string + NoLocals *bool + Journal *string + Rejournal *time.Duration + PriceLimit *uint64 + PriceBump *uint64 + AccountSlots *uint64 + GlobalSlots *uint64 + AccountQueue *uint64 + GlobalQueue *uint64 + LifeTime *time.Duration +} + +type SealerConfig struct { + Seal *bool + Etherbase *string + ExtraData *string } func DefaultConfig() *Config { return &Config{ + Chain: stringPtr("mainnet"), Debug: boolPtr(false), LogLevel: stringPtr("INFO"), DataDir: stringPtr(""), P2P: &P2PConfig{ - MaxPeers: uint64Ptr(30), - Bind: stringPtr("0.0.0.0."), - Port: uint64Ptr(30303), + MaxPeers: uint64Ptr(30), + Bind: stringPtr("0.0.0.0"), + Port: uint64Ptr(30303), + NoDiscover: boolPtr(false), + V5Disc: boolPtr(false), + Bootnodes: []string{}, + BootnodesV4: []string{}, + BootnodesV5: []string{}, + }, + SyncMode: stringPtr("fast"), + EthStats: stringPtr(""), + TxPool: &TxPoolConfig{ + Locals: []string{}, + NoLocals: boolPtr(false), + Journal: stringPtr(""), + Rejournal: durPtr(1 * time.Hour), + PriceLimit: uint64Ptr(1), + PriceBump: uint64Ptr(10), + AccountSlots: uint64Ptr(16), + GlobalSlots: uint64Ptr(4096), + AccountQueue: uint64Ptr(64), + GlobalQueue: uint64Ptr(1024), + LifeTime: durPtr(3 * time.Hour), + }, + Sealer: &SealerConfig{ + Seal: boolPtr(false), }, } } @@ -61,7 +121,36 @@ func (c *Config) buildEth() (*ethconfig.Config, error) { n := ethconfig.Defaults //n.NetworkId = c.genesis.NetworkId //n.Genesis = c.genesis.Genesis - n.SyncMode = downloader.FastSync + + // txpool options + { + cfg := n.TxPool + cfg.NoLocals = *c.TxPool.NoLocals + cfg.Journal = *c.TxPool.Journal + cfg.Rejournal = *c.TxPool.Rejournal + cfg.PriceLimit = *c.TxPool.PriceLimit + cfg.PriceBump = *c.TxPool.PriceBump + cfg.AccountSlots = *c.TxPool.AccountSlots + cfg.GlobalSlots = *c.TxPool.GlobalSlots + cfg.AccountQueue = *c.TxPool.AccountQueue + cfg.GlobalQueue = *c.TxPool.GlobalQueue + cfg.Lifetime = *c.TxPool.LifeTime + } + + // miner options + { + cfg := n.Miner + fmt.Println(cfg) + } + + var syncMode downloader.SyncMode + switch *c.SyncMode { + case "fast": + syncMode = downloader.FastSync + default: + return nil, fmt.Errorf("sync mode '%s' not found", syncMode) + } + n.SyncMode = syncMode n.DatabaseHandles = dbHandles return &n, nil } diff --git a/command/server/flags.go b/command/server/flags.go index 48cdecf3f5..2057f88121 100644 --- a/command/server/flags.go +++ b/command/server/flags.go @@ -3,15 +3,20 @@ package server import "github.com/ethereum/go-ethereum/command/flagset" func (c *Command) Flags() *flagset.Flagset { - c.cliConfig = &Config{} + c.cliConfig = DefaultConfig() - f := flagset.NewFlagSet("server") + f := flagset.NewFlagSet("") f.BoolFlag(&flagset.BoolFlag{ Name: "debug", Value: c.cliConfig.Debug, Usage: "Path of the file to apply", }) + f.StringFlag(&flagset.StringFlag{ + Name: "chain", + Value: c.cliConfig.Chain, + Usage: "Name of the chain to sync", + }) f.StringFlag(&flagset.StringFlag{ Name: "log-level", Value: c.cliConfig.LogLevel, @@ -28,5 +33,34 @@ func (c *Command) Flags() *flagset.Flagset { Usage: "File for the config file", }) + // txpool options + f.SliceStringFlag(&flagset.SliceStringFlag{ + Name: "txpool.locals", + Value: c.cliConfig.TxPool.Locals, + Usage: "Comma separated accounts to treat as locals (no flush, priority inclusion)", + }) + f.BoolFlag(&flagset.BoolFlag{ + Name: "txpool.nolocals", + Value: c.cliConfig.TxPool.NoLocals, + Usage: "Disables price exemptions for locally submitted transactions", + }) + + // sealer options + f.BoolFlag(&flagset.BoolFlag{ + Name: "mine", + Value: c.cliConfig.Sealer.Seal, + Usage: "", + }) + f.StringFlag(&flagset.StringFlag{ + Name: "miner.etherbase", + Value: c.cliConfig.Sealer.Etherbase, + Usage: "", + }) + f.StringFlag(&flagset.StringFlag{ + Name: "miner.extradata", + Value: c.cliConfig.Sealer.ExtraData, + Usage: "", + }) + return f } diff --git a/command/version.go b/command/version.go new file mode 100644 index 0000000000..4523675d2d --- /dev/null +++ b/command/version.go @@ -0,0 +1,30 @@ +package main + +import ( + "github.com/ethereum/go-ethereum/params" + "github.com/mitchellh/cli" +) + +// VersionCommand is the command to show the version of the agent +type VersionCommand struct { + UI cli.Ui +} + +// Help implements the cli.Command interface +func (c *VersionCommand) Help() string { + return `Usage: ensemble version + + Display the Ensemble version` +} + +// Synopsis implements the cli.Command interface +func (c *VersionCommand) Synopsis() string { + return "Display the Bor version" +} + +// Run implements the cli.Command interface +func (c *VersionCommand) Run(args []string) int { + c.UI.Output(params.VersionWithMeta) + + return 0 +} From 74d384b6a4ad233505f766d07b218c39ff100091 Mon Sep 17 00:00:00 2001 From: Ferran Borreguero Date: Mon, 4 Oct 2021 16:19:58 +0200 Subject: [PATCH 03/51] Add account commands --- command/account.go | 32 ++++++++++++++++ command/account_import.go | 74 +++++++++++++++++++++++++++++++++++ command/account_list.go | 62 ++++++++++++++++++++++++++++++ command/account_new.go | 62 ++++++++++++++++++++++++++++++ command/main.go | 81 +++++++++++++++++++++++++++++++++++++++ command/version.go | 4 +- go.mod | 1 + go.sum | 2 + 8 files changed, 316 insertions(+), 2 deletions(-) create mode 100644 command/account.go create mode 100644 command/account_import.go create mode 100644 command/account_list.go create mode 100644 command/account_new.go diff --git a/command/account.go b/command/account.go new file mode 100644 index 0000000000..948ab32999 --- /dev/null +++ b/command/account.go @@ -0,0 +1,32 @@ +package main + +import "github.com/mitchellh/cli" + +type Account struct { + UI cli.Ui +} + +// Help implements the cli.Command interface +func (a *Account) Help() string { + return `Usage: bor account + + This command groups actions to interact with accounts. + + List the running deployments: + + $ bor account new + + Display the status of a specific deployment: + + $ bor account import` +} + +// Synopsis implements the cli.Command interface +func (a *Account) Synopsis() string { + return "Interact with accounts" +} + +// Run implements the cli.Command interface +func (a *Account) Run(args []string) int { + return cli.RunResultHelp +} diff --git a/command/account_import.go b/command/account_import.go new file mode 100644 index 0000000000..331a45aac6 --- /dev/null +++ b/command/account_import.go @@ -0,0 +1,74 @@ +package main + +import ( + "fmt" + + "github.com/ethereum/go-ethereum/cmd/utils" + "github.com/ethereum/go-ethereum/command/flagset" + "github.com/ethereum/go-ethereum/crypto" +) + +type AccountImportCommand struct { + *Meta +} + +// Help implements the cli.Command interface +func (a *AccountImportCommand) Help() string { + return `Usage: bor account import + + Import a private key into a new account. + + Import an account: + + $ bor account import key.json + + ` + a.Flags().Help() +} + +func (a *AccountImportCommand) Flags() *flagset.Flagset { + return a.NewFlagSet("account import") +} + +// Synopsis implements the cli.Command interface +func (a *AccountImportCommand) Synopsis() string { + return "Import a private key into a new account" +} + +// Run implements the cli.Command interface +func (a *AccountImportCommand) Run(args []string) int { + flags := a.Flags() + if err := flags.Parse(args); err != nil { + a.UI.Error(err.Error()) + return 1 + } + + args = flags.Args() + if len(args) != 1 { + a.UI.Error("Expected one argument") + return 1 + } + key, err := crypto.LoadECDSA(args[0]) + if err != nil { + a.UI.Error(fmt.Sprintf("Failed to load the private key '%s': %v", args[0], err)) + return 1 + } + + keystore, err := a.GetKeystore() + if err != nil { + a.UI.Error(fmt.Sprintf("Failed to get keystore: %v", err)) + return 1 + } + + password, err := a.AskPassword() + if err != nil { + a.UI.Error(err.Error()) + return 1 + } + + acct, err := keystore.ImportECDSA(key, password) + if err != nil { + utils.Fatalf("Could not create the account: %v", err) + } + a.UI.Output(fmt.Sprintf("Account created: %s", acct.Address.String())) + return 0 +} diff --git a/command/account_list.go b/command/account_list.go new file mode 100644 index 0000000000..d41e0c0d65 --- /dev/null +++ b/command/account_list.go @@ -0,0 +1,62 @@ +package main + +import ( + "fmt" + + "github.com/ethereum/go-ethereum/accounts" + "github.com/ethereum/go-ethereum/command/flagset" +) + +type AccountListCommand struct { + *Meta +} + +// Help implements the cli.Command interface +func (a *AccountListCommand) Help() string { + return `Usage: bor account list + + List the local accounts. + + ` + a.Flags().Help() +} + +func (a *AccountListCommand) Flags() *flagset.Flagset { + return a.NewFlagSet("account list") +} + +// Synopsis implements the cli.Command interface +func (a *AccountListCommand) Synopsis() string { + return "List the local accounts" +} + +// Run implements the cli.Command interface +func (a *AccountListCommand) Run(args []string) int { + flags := a.Flags() + if err := flags.Parse(args); err != nil { + a.UI.Error(err.Error()) + return 1 + } + + keystore, err := a.GetKeystore() + if err != nil { + a.UI.Error(fmt.Sprintf("Failed to get keystore: %v", err)) + return 1 + } + a.UI.Output(formatAccounts(keystore.Accounts())) + return 0 +} + +func formatAccounts(accts []accounts.Account) string { + if len(accts) == 0 { + return "No accounts found" + } + + rows := make([]string, len(accts)+1) + rows[0] = "Index|Address" + for i, d := range accts { + rows[i+1] = fmt.Sprintf("%d|%s", + i, + d.Address.String()) + } + return formatList(rows) +} diff --git a/command/account_new.go b/command/account_new.go new file mode 100644 index 0000000000..59118a9a37 --- /dev/null +++ b/command/account_new.go @@ -0,0 +1,62 @@ +package main + +import ( + "fmt" + + "github.com/ethereum/go-ethereum/command/flagset" +) + +type AccountNewCommand struct { + *Meta +} + +// Help implements the cli.Command interface +func (a *AccountNewCommand) Help() string { + return `Usage: bor account new + + Create a new local account. + + ` + a.Flags().Help() +} + +func (a *AccountNewCommand) Flags() *flagset.Flagset { + return a.NewFlagSet("account new") +} + +// Synopsis implements the cli.Command interface +func (a *AccountNewCommand) Synopsis() string { + return "Create a new local account" +} + +// Run implements the cli.Command interface +func (a *AccountNewCommand) Run(args []string) int { + flags := a.Flags() + if err := flags.Parse(args); err != nil { + a.UI.Error(err.Error()) + return 1 + } + + keystore, err := a.GetKeystore() + if err != nil { + a.UI.Error(fmt.Sprintf("Failed to get keystore: %v", err)) + return 1 + } + + password, err := a.AskPassword() + if err != nil { + a.UI.Error(err.Error()) + return 1 + } + + account, err := keystore.NewAccount(password) + if err != nil { + a.UI.Error(fmt.Sprintf("Failed to create new account: %v", err)) + return 1 + } + + a.UI.Output("\nYour new key was generated") + a.UI.Output(fmt.Sprintf("Public address of the key: %s", account.Address.Hex())) + a.UI.Output(fmt.Sprintf("Path of the secret key file: %s", account.URL.Path)) + + return 0 +} diff --git a/command/main.go b/command/main.go index 1a1f92e316..67b5a004af 100644 --- a/command/main.go +++ b/command/main.go @@ -4,8 +4,12 @@ import ( "fmt" "os" + "github.com/ethereum/go-ethereum/accounts/keystore" + "github.com/ethereum/go-ethereum/command/flagset" "github.com/ethereum/go-ethereum/command/server" + "github.com/ethereum/go-ethereum/node" "github.com/mitchellh/cli" + "github.com/ryanuber/columnize" ) func main() { @@ -35,6 +39,10 @@ func commands() map[string]cli.CommandFactory { Writer: os.Stdout, ErrorWriter: os.Stderr, } + + meta := &Meta{ + UI: ui, + } return map[string]cli.CommandFactory{ "server": func() (cli.Command, error) { return &server.Command{ @@ -46,5 +54,78 @@ func commands() map[string]cli.CommandFactory { UI: ui, }, nil }, + "account": func() (cli.Command, error) { + return &Account{ + UI: ui, + }, nil + }, + "account new": func() (cli.Command, error) { + return &AccountNewCommand{ + Meta: meta, + }, nil + }, + "account import": func() (cli.Command, error) { + return &AccountImportCommand{ + Meta: meta, + }, nil + }, + "account list": func() (cli.Command, error) { + return &AccountListCommand{ + Meta: meta, + }, nil + }, } } + +// Meta is a helper utility for the commands +type Meta struct { + UI cli.Ui + + dataDir string + keyStoreDir string +} + +func (m *Meta) NewFlagSet(n string) *flagset.Flagset { + f := flagset.NewFlagSet(n) + + f.StringFlag(&flagset.StringFlag{ + Name: "datadir", + Value: &m.dataDir, + Usage: "Path of the data directory to store information", + }) + f.StringFlag(&flagset.StringFlag{ + Name: "keystore", + Value: &m.keyStoreDir, + Usage: "Path of the data directory to store information", + }) + + return f +} + +func (m *Meta) AskPassword() (string, error) { + return m.UI.AskSecret("Your new account is locked with a password. Please give a password. Do not forget this password") +} + +func (m *Meta) GetKeystore() (*keystore.KeyStore, error) { + cfg := node.DefaultConfig + cfg.DataDir = m.dataDir + cfg.KeyStoreDir = m.keyStoreDir + + stack, err := node.New(&cfg) + if err != nil { + return nil, err + } + + keydir := stack.KeyStoreDir() + scryptN := keystore.StandardScryptN + scryptP := keystore.StandardScryptP + + keys := keystore.NewKeyStore(keydir, scryptN, scryptP) + return keys, nil +} + +func formatList(in []string) string { + columnConf := columnize.DefaultConfig() + columnConf.Empty = "" + return columnize.Format(in, columnConf) +} diff --git a/command/version.go b/command/version.go index 4523675d2d..5483ea5402 100644 --- a/command/version.go +++ b/command/version.go @@ -12,9 +12,9 @@ type VersionCommand struct { // Help implements the cli.Command interface func (c *VersionCommand) Help() string { - return `Usage: ensemble version + return `Usage: bor version - Display the Ensemble version` + Display the Bor version` } // Synopsis implements the cli.Command interface diff --git a/go.mod b/go.mod index ae93276e23..296d727ec4 100644 --- a/go.mod +++ b/go.mod @@ -58,6 +58,7 @@ require ( github.com/prometheus/tsdb v0.7.1 github.com/rjeczalik/notify v0.9.1 github.com/rs/cors v1.7.0 + github.com/ryanuber/columnize v2.1.2+incompatible github.com/shirou/gopsutil v3.21.4-0.20210419000835-c7a38de76ee5+incompatible github.com/status-im/keycard-go v0.0.0-20190316090335-8537d3370df4 github.com/stretchr/testify v1.7.0 diff --git a/go.sum b/go.sum index c98b75beac..79bb6c6cf6 100644 --- a/go.sum +++ b/go.sum @@ -393,6 +393,8 @@ github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFR github.com/rs/cors v1.7.0 h1:+88SsELBHx5r+hZ8TCkggzSstaWNbDvThkVK8H6f9ik= github.com/rs/cors v1.7.0/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU= github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= +github.com/ryanuber/columnize v2.1.2+incompatible h1:C89EOx/XBWwIXl8wm8OPJBd7kPF25UfsK2X7Ph/zCAk= +github.com/ryanuber/columnize v2.1.2+incompatible/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= github.com/segmentio/kafka-go v0.1.0/go.mod h1:X6itGqS9L4jDletMsxZ7Dz+JFWxM6JHfPOCvTvk+EJo= github.com/segmentio/kafka-go v0.2.0/go.mod h1:X6itGqS9L4jDletMsxZ7Dz+JFWxM6JHfPOCvTvk+EJo= github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo= From 3acd7a12de1fb460435699b8d6263cc5b1535061 Mon Sep 17 00:00:00 2001 From: Ferran Borreguero Date: Mon, 4 Oct 2021 18:19:31 +0200 Subject: [PATCH 04/51] Add more flags --- command/server/chains/chain.go | 24 ++++++ command/server/chains/mainnet.go | 85 ++++++++++---------- command/server/chains/mumbai.go | 64 ++++++++------- command/server/command.go | 39 ++++++++- command/server/config.go | 133 ++++++++++++++++++++++--------- 5 files changed, 230 insertions(+), 115 deletions(-) create mode 100644 command/server/chains/chain.go diff --git a/command/server/chains/chain.go b/command/server/chains/chain.go new file mode 100644 index 0000000000..05c12ef0b0 --- /dev/null +++ b/command/server/chains/chain.go @@ -0,0 +1,24 @@ +package chains + +import ( + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core" +) + +type Chain struct { + Hash common.Hash + Genesis *core.Genesis + Bootnodes []string + NetworkId uint64 + DNS []string +} + +var chains = map[string]*Chain{ + "mainnet": mainnetBor, + "mumbai": mumbaiTestnet, +} + +func GetChain(name string) (*Chain, bool) { + chain, ok := chains[name] + return chain, ok +} diff --git a/command/server/chains/mainnet.go b/command/server/chains/mainnet.go index ad92979ff7..8d6f163256 100644 --- a/command/server/chains/mainnet.go +++ b/command/server/chains/mainnet.go @@ -8,48 +8,45 @@ import ( "github.com/ethereum/go-ethereum/params" ) -var BorMainnetGenesisHash = common.HexToHash("0xa9c28ce2141b56c474f1dc504bee9b01eb1bd7d1a507580d5519d4437a97de1b") - -var BorMainnetChainConfig = ¶ms.ChainConfig{ - ChainID: big.NewInt(137), - HomesteadBlock: big.NewInt(0), - DAOForkBlock: nil, - DAOForkSupport: true, - EIP150Hash: common.HexToHash("0x0000000000000000000000000000000000000000000000000000000000000000"), - EIP150Block: big.NewInt(0), - EIP155Block: big.NewInt(0), - EIP158Block: big.NewInt(0), - ByzantiumBlock: big.NewInt(0), - ConstantinopleBlock: big.NewInt(0), - PetersburgBlock: big.NewInt(0), - IstanbulBlock: big.NewInt(3395000), - MuirGlacierBlock: big.NewInt(3395000), - BerlinBlock: big.NewInt(14750000), - Bor: ¶ms.BorConfig{ - Period: 2, - ProducerDelay: 6, - Sprint: 64, - BackupMultiplier: 2, - ValidatorContract: "0x0000000000000000000000000000000000001000", - StateReceiverContract: "0x0000000000000000000000000000000000001001", - OverrideStateSyncRecords: map[string]int{ - "14949120": 8, - "14949184": 0, - "14953472": 0, - "14953536": 5, - "14953600": 0, - "14953664": 0, - "14953728": 0, - "14953792": 0, - "14953856": 0, +var mainnetBor = &Chain{ + Hash: common.HexToHash("0xa9c28ce2141b56c474f1dc504bee9b01eb1bd7d1a507580d5519d4437a97de1b"), + NetworkId: 137, + Genesis: &core.Genesis{ + Config: ¶ms.ChainConfig{ + ChainID: big.NewInt(137), + HomesteadBlock: big.NewInt(0), + DAOForkBlock: nil, + DAOForkSupport: true, + EIP150Hash: common.HexToHash("0x0000000000000000000000000000000000000000000000000000000000000000"), + EIP150Block: big.NewInt(0), + EIP155Block: big.NewInt(0), + EIP158Block: big.NewInt(0), + ByzantiumBlock: big.NewInt(0), + ConstantinopleBlock: big.NewInt(0), + PetersburgBlock: big.NewInt(0), + IstanbulBlock: big.NewInt(3395000), + MuirGlacierBlock: big.NewInt(3395000), + BerlinBlock: big.NewInt(14750000), + Bor: ¶ms.BorConfig{ + Period: 2, + ProducerDelay: 6, + Sprint: 64, + BackupMultiplier: 2, + ValidatorContract: "0x0000000000000000000000000000000000001000", + StateReceiverContract: "0x0000000000000000000000000000000000001001", + OverrideStateSyncRecords: map[string]int{ + "14949120": 8, + "14949184": 0, + "14953472": 0, + "14953536": 5, + "14953600": 0, + "14953664": 0, + "14953728": 0, + "14953792": 0, + "14953856": 0, + }, + }, }, - }, -} - -//DefaultBorMainnet returns the Bor Mainnet network gensis block. -func DefaultBorMainnetGenesisBlock() *core.Genesis { - return &core.Genesis{ - Config: BorMainnetChainConfig, Nonce: 0, Timestamp: 1590824836, GasLimit: 10000000, @@ -57,5 +54,9 @@ func DefaultBorMainnetGenesisBlock() *core.Genesis { Mixhash: common.HexToHash("0x0000000000000000000000000000000000000000000000000000000000000000"), Coinbase: common.HexToAddress("0x0000000000000000000000000000000000000000"), Alloc: readPrealloc("allocs/bor_mainnet.json"), - } + }, + Bootnodes: []string{ + "enode://0cb82b395094ee4a2915e9714894627de9ed8498fb881cec6db7c65e8b9a5bd7f2f25cc84e71e89d0947e51c76e85d0847de848c7782b13c0255247a6758178c@44.232.55.71:30303", + "enode://88116f4295f5a31538ae409e4d44ad40d22e44ee9342869e7d68bdec55b0f83c1530355ce8b41fbec0928a7d75a5745d528450d30aec92066ab6ba1ee351d710@159.203.9.164:30303", + }, } diff --git a/command/server/chains/mumbai.go b/command/server/chains/mumbai.go index 8a0af6dfdc..1003380d10 100644 --- a/command/server/chains/mumbai.go +++ b/command/server/chains/mumbai.go @@ -8,36 +8,34 @@ import ( "github.com/ethereum/go-ethereum/params" ) -var MumbaiGenesisHash = common.HexToHash("0x7b66506a9ebdbf30d32b43c5f15a3b1216269a1ec3a75aa3182b86176a2b1ca7") - -var MumbaiChainConfig = ¶ms.ChainConfig{ - ChainID: big.NewInt(80001), - HomesteadBlock: big.NewInt(0), - DAOForkBlock: nil, - DAOForkSupport: true, - EIP150Hash: common.HexToHash("0x0000000000000000000000000000000000000000000000000000000000000000"), - EIP150Block: big.NewInt(0), - EIP155Block: big.NewInt(0), - EIP158Block: big.NewInt(0), - ByzantiumBlock: big.NewInt(0), - ConstantinopleBlock: big.NewInt(0), - PetersburgBlock: big.NewInt(0), - IstanbulBlock: big.NewInt(2722000), - MuirGlacierBlock: big.NewInt(2722000), - BerlinBlock: big.NewInt(13996000), - Bor: ¶ms.BorConfig{ - Period: 2, - ProducerDelay: 6, - Sprint: 64, - BackupMultiplier: 2, - ValidatorContract: "0x0000000000000000000000000000000000001000", - StateReceiverContract: "0x0000000000000000000000000000000000001001", - }, -} - -func DefaultMumbaiGenesisBlock() *core.Genesis { - return &core.Genesis{ - Config: MumbaiChainConfig, +var mumbaiTestnet = &Chain{ + Hash: common.HexToHash("0x7b66506a9ebdbf30d32b43c5f15a3b1216269a1ec3a75aa3182b86176a2b1ca7"), + NetworkId: 80001, + Genesis: &core.Genesis{ + Config: ¶ms.ChainConfig{ + ChainID: big.NewInt(80001), + HomesteadBlock: big.NewInt(0), + DAOForkBlock: nil, + DAOForkSupport: true, + EIP150Hash: common.HexToHash("0x0000000000000000000000000000000000000000000000000000000000000000"), + EIP150Block: big.NewInt(0), + EIP155Block: big.NewInt(0), + EIP158Block: big.NewInt(0), + ByzantiumBlock: big.NewInt(0), + ConstantinopleBlock: big.NewInt(0), + PetersburgBlock: big.NewInt(0), + IstanbulBlock: big.NewInt(2722000), + MuirGlacierBlock: big.NewInt(2722000), + BerlinBlock: big.NewInt(13996000), + Bor: ¶ms.BorConfig{ + Period: 2, + ProducerDelay: 6, + Sprint: 64, + BackupMultiplier: 2, + ValidatorContract: "0x0000000000000000000000000000000000001000", + StateReceiverContract: "0x0000000000000000000000000000000000001001", + }, + }, Nonce: 0, Timestamp: 1558348305, GasLimit: 10000000, @@ -45,5 +43,9 @@ func DefaultMumbaiGenesisBlock() *core.Genesis { Mixhash: common.HexToHash("0x0000000000000000000000000000000000000000000000000000000000000000"), Coinbase: common.HexToAddress("0x0000000000000000000000000000000000000000"), Alloc: readPrealloc("allocs/mumbai.json"), - } + }, + Bootnodes: []string{ + "enode://320553cda00dfc003f499a3ce9598029f364fbb3ed1222fdc20a94d97dcc4d8ba0cd0bfa996579dcc6d17a534741fb0a5da303a90579431259150de66b597251@54.147.31.250:30303", + "enode://f0f48a8781629f95ff02606081e6e43e4aebd503f3d07fc931fad7dd5ca1ba52bd849a6f6c3be0e375cf13c9ae04d859c4a9ae3546dc8ed4f10aa5dbb47d4998@34.226.134.117:30303", + }, } diff --git a/command/server/command.go b/command/server/command.go index 985971e510..cd26e469ee 100644 --- a/command/server/command.go +++ b/command/server/command.go @@ -10,8 +10,9 @@ import ( "time" "github.com/ethereum/go-ethereum/eth" - "github.com/ethereum/go-ethereum/eth/tracers" + "github.com/ethereum/go-ethereum/ethstats" "github.com/ethereum/go-ethereum/log" + "github.com/ethereum/go-ethereum/metrics" "github.com/ethereum/go-ethereum/node" "github.com/mattn/go-colorable" "github.com/mattn/go-isatty" @@ -66,7 +67,12 @@ func (c *Command) Run(args []string) int { // start the logger setupLogger(*config.LogLevel) - // create the node + // load the chain genesis + if err := config.loadChain(); err != nil { + panic(err) + } + + // create the node/stack nodeCfg, err := config.buildNode() if err != nil { panic(err) @@ -77,6 +83,14 @@ func (c *Command) Run(args []string) int { } c.node = stack + // TODO: MakeChain? + // TODO: Metrics + // TODO: Node key, pre generate one + // TODO: apis + // TODO: account management + // TODO: Graphql + // TODO: embed + // register the ethereum backend ethCfg, err := config.buildEth() if err != nil { @@ -86,7 +100,16 @@ func (c *Command) Run(args []string) int { if err != nil { panic(err) } - c.node.RegisterAPIs(tracers.APIs(backend.APIBackend)) + + // This is the tracers api, not sure if this should be here, i do not think so. + // c.node.RegisterAPIs(tracers.APIs(backend.APIBackend)) + + // register ethash service + if config.EthStats != nil { + if err := ethstats.New(stack, backend.APIBackend, backend.Engine(), *config.EthStats); err != nil { + panic(err) + } + } // start the node if err := c.node.Start(); err != nil { @@ -95,6 +118,16 @@ func (c *Command) Run(args []string) int { return c.handleSignals() } +func (c *Command) setupMetrics() { + if !metrics.Enabled { + // metrics are globally disabled + return + } + + // Start system runtime metrics collection + go metrics.CollectProcessMetrics(3 * time.Second) +} + func (c *Command) handleSignals() int { signalCh := make(chan os.Signal, 4) signal.Notify(signalCh, os.Interrupt, syscall.SIGTERM, syscall.SIGHUP) diff --git a/command/server/config.go b/command/server/config.go index 8977c6372b..45734d7316 100644 --- a/command/server/config.go +++ b/command/server/config.go @@ -5,11 +5,13 @@ import ( "strconv" "time" + "github.com/ethereum/go-ethereum/command/server/chains" "github.com/ethereum/go-ethereum/common/fdlimit" "github.com/ethereum/go-ethereum/eth/downloader" "github.com/ethereum/go-ethereum/eth/ethconfig" "github.com/ethereum/go-ethereum/node" "github.com/ethereum/go-ethereum/p2p" + "github.com/ethereum/go-ethereum/p2p/enode" "github.com/imdario/mergo" ) @@ -30,6 +32,8 @@ func durPtr(d time.Duration) *time.Duration { } type Config struct { + chain *chains.Chain + Chain *string Debug *bool LogLevel *string @@ -42,14 +46,21 @@ type Config struct { } type P2PConfig struct { - MaxPeers *uint64 - Bind *string - Port *uint64 - NoDiscover *bool - V5Disc *bool - Bootnodes []string - BootnodesV4 []string - BootnodesV5 []string + MaxPeers *uint64 + Bind *string + Port *uint64 + NoDiscover *bool + V5Disc *bool + Discovery *P2PDiscovery +} + +type P2PDiscovery struct { + Bootnodes []string + BootnodesV4 []string + BootnodesV5 []string + StaticNodes []string + TrustedNodes []string + DNS []string } type TxPoolConfig struct { @@ -79,14 +90,19 @@ func DefaultConfig() *Config { LogLevel: stringPtr("INFO"), DataDir: stringPtr(""), P2P: &P2PConfig{ - MaxPeers: uint64Ptr(30), - Bind: stringPtr("0.0.0.0"), - Port: uint64Ptr(30303), - NoDiscover: boolPtr(false), - V5Disc: boolPtr(false), - Bootnodes: []string{}, - BootnodesV4: []string{}, - BootnodesV5: []string{}, + MaxPeers: uint64Ptr(30), + Bind: stringPtr("0.0.0.0"), + Port: uint64Ptr(30303), + NoDiscover: boolPtr(false), + V5Disc: boolPtr(false), + Discovery: &P2PDiscovery{ + Bootnodes: []string{}, + BootnodesV4: []string{}, + BootnodesV5: []string{}, + StaticNodes: []string{}, + TrustedNodes: []string{}, + DNS: []string{}, + }, }, SyncMode: stringPtr("fast"), EthStats: stringPtr(""), @@ -113,14 +129,31 @@ func readConfigFile(path string) (*Config, error) { return nil, nil } +func (c *Config) loadChain() error { + chain, ok := chains.GetChain(*c.Chain) + if !ok { + return fmt.Errorf("chain '%s' not found", *c.Chain) + } + c.chain = chain + + // preload some default values that are on the chain file + if c.P2P.Discovery.Bootnodes == nil { + c.P2P.Discovery.Bootnodes = c.chain.Bootnodes + } + if c.P2P.Discovery.DNS == nil { + c.P2P.Discovery.DNS = c.chain.DNS + } + return nil +} + func (c *Config) buildEth() (*ethconfig.Config, error) { dbHandles, err := makeDatabaseHandles() if err != nil { return nil, err } n := ethconfig.Defaults - //n.NetworkId = c.genesis.NetworkId - //n.Genesis = c.genesis.Genesis + n.NetworkId = c.chain.NetworkId + n.Genesis = c.chain.Genesis // txpool options { @@ -143,6 +176,12 @@ func (c *Config) buildEth() (*ethconfig.Config, error) { fmt.Println(cfg) } + // discovery (this params should be in node.Config) + { + n.EthDiscoveryURLs = c.P2P.Discovery.DNS + n.SnapDiscoveryURLs = c.P2P.Discovery.DNS + } + var syncMode downloader.SyncMode switch *c.SyncMode { case "fast": @@ -152,22 +191,12 @@ func (c *Config) buildEth() (*ethconfig.Config, error) { } n.SyncMode = syncMode n.DatabaseHandles = dbHandles + return &n, nil } func (c *Config) buildNode() (*node.Config, error) { - /* - bootstrap, err := parseBootnodes(c.genesis.Bootstrap) - if err != nil { - return nil, err - } - static, err := parseBootnodes(c.genesis.Static) - if err != nil { - return nil, err - } - */ - - n := &node.Config{ + cfg := &node.Config{ Name: "reader", DataDir: *c.DataDir, P2P: p2p.Config{ @@ -182,16 +211,28 @@ func (c *Config) buildNode() (*node.Config, error) { WSPort: int(*c.Ports.Websocket), */ } - /* - if *c.NoDiscovery { - // avoid incoming connections - n.P2P.MaxPeers = 0 - // avoid outgoing connections - n.P2P.NoDiscovery = true - } - */ - return n, nil + // Discovery + var err error + if cfg.P2P.BootstrapNodes, err = parseBootnodes(c.P2P.Discovery.Bootnodes); err != nil { + return nil, err + } + if cfg.P2P.BootstrapNodesV5, err = parseBootnodes(c.P2P.Discovery.BootnodesV5); err != nil { + return nil, err + } + if cfg.P2P.StaticNodes, err = parseBootnodes(c.P2P.Discovery.StaticNodes); err != nil { + return nil, err + } + if cfg.P2P.TrustedNodes, err = parseBootnodes(c.P2P.Discovery.TrustedNodes); err != nil { + return nil, err + } + + if *c.P2P.NoDiscover { + // Disable networking, for now, we will not even allow incomming connections + cfg.P2P.MaxPeers = 0 + cfg.P2P.NoDiscovery = true + } + return cfg, nil } func (c *Config) Merge(cc ...*Config) error { @@ -214,3 +255,17 @@ func makeDatabaseHandles() (int, error) { } return int(raised / 2), nil } + +func parseBootnodes(urls []string) ([]*enode.Node, error) { + dst := []*enode.Node{} + for _, url := range urls { + if url != "" { + node, err := enode.Parse(enode.ValidSchemes, url) + if err != nil { + return nil, fmt.Errorf("invalid bootstrap url '%s': %v", url, err) + } + dst = append(dst, node) + } + } + return dst, nil +} From 449e6a517a8af3df00fc23203bf77869f8083a2d Mon Sep 17 00:00:00 2001 From: Ferran Borreguero Date: Tue, 5 Oct 2021 09:59:10 +0200 Subject: [PATCH 05/51] Add P2P private key --- command/server/command.go | 26 +++++++++++++--- command/server/config.go | 64 ++++++++++++++++++++++++++++++++++++--- command/server/flags.go | 2 +- 3 files changed, 82 insertions(+), 10 deletions(-) diff --git a/command/server/command.go b/command/server/command.go index cd26e469ee..2feb0be791 100644 --- a/command/server/command.go +++ b/command/server/command.go @@ -9,6 +9,7 @@ import ( "syscall" "time" + "github.com/ethereum/go-ethereum/accounts/keystore" "github.com/ethereum/go-ethereum/eth" "github.com/ethereum/go-ethereum/ethstats" "github.com/ethereum/go-ethereum/log" @@ -85,9 +86,7 @@ func (c *Command) Run(args []string) int { // TODO: MakeChain? // TODO: Metrics - // TODO: Node key, pre generate one // TODO: apis - // TODO: account management // TODO: Graphql // TODO: embed @@ -111,6 +110,24 @@ func (c *Command) Run(args []string) int { } } + // setup account manager (only keystore) + { + keydir := stack.KeyStoreDir() + scryptN := keystore.StandardScryptN + scryptP := keystore.StandardScryptP + + stack.AccountManager().AddBackend(keystore.NewKeyStore(keydir, scryptN, scryptP)) + } + + // sealing (if enabled) + if *config.Sealer.Enabled { + if err := backend.StartMining(1); err != nil { + panic(err) + } + } + + c.setupMetrics() + // start the node if err := c.node.Start(); err != nil { panic(err) @@ -118,14 +135,15 @@ func (c *Command) Run(args []string) int { return c.handleSignals() } -func (c *Command) setupMetrics() { +func (c *Command) setupMetrics() error { if !metrics.Enabled { // metrics are globally disabled - return + return nil } // Start system runtime metrics collection go metrics.CollectProcessMetrics(3 * time.Second) + return nil } func (c *Command) handleSignals() int { diff --git a/command/server/config.go b/command/server/config.go index 45734d7316..7b01f6885f 100644 --- a/command/server/config.go +++ b/command/server/config.go @@ -1,17 +1,24 @@ package server import ( + "crypto/ecdsa" "fmt" + "math/big" + "os" + "path/filepath" "strconv" "time" "github.com/ethereum/go-ethereum/command/server/chains" + "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/fdlimit" + "github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/eth/downloader" "github.com/ethereum/go-ethereum/eth/ethconfig" "github.com/ethereum/go-ethereum/node" "github.com/ethereum/go-ethereum/p2p" "github.com/ethereum/go-ethereum/p2p/enode" + "github.com/ethereum/go-ethereum/params" "github.com/imdario/mergo" ) @@ -78,9 +85,11 @@ type TxPoolConfig struct { } type SealerConfig struct { - Seal *bool + Enabled *bool Etherbase *string ExtraData *string + GasCeil *uint64 + GasPrice *big.Int } func DefaultConfig() *Config { @@ -120,7 +129,9 @@ func DefaultConfig() *Config { LifeTime: durPtr(3 * time.Hour), }, Sealer: &SealerConfig{ - Seal: boolPtr(false), + Enabled: boolPtr(false), + GasCeil: uint64Ptr(8000000), + GasPrice: big.NewInt(params.GWei), }, } } @@ -173,7 +184,9 @@ func (c *Config) buildEth() (*ethconfig.Config, error) { // miner options { cfg := n.Miner - fmt.Println(cfg) + cfg.Etherbase = common.HexToAddress(*c.Sealer.Etherbase) + cfg.GasPrice = c.Sealer.GasPrice + cfg.GasCeil = *c.Sealer.GasCeil } // discovery (this params should be in node.Config) @@ -195,10 +208,17 @@ func (c *Config) buildEth() (*ethconfig.Config, error) { return &n, nil } +var ( + clientIdentifier = "bor" + gitCommit = "" // Git SHA1 commit hash of the release (set via linker flags) + gitDate = "" // Git commit date YYYYMMDD of the release (set via linker flags) +) + func (c *Config) buildNode() (*node.Config, error) { cfg := &node.Config{ - Name: "reader", + Name: clientIdentifier, DataDir: *c.DataDir, + Version: params.VersionWithCommit(gitCommit, gitDate), P2P: p2p.Config{ MaxPeers: int(*c.P2P.MaxPeers), ListenAddr: *c.P2P.Bind + ":" + strconv.Itoa(int(*c.P2P.Port)), @@ -212,8 +232,14 @@ func (c *Config) buildNode() (*node.Config, error) { */ } + // setup private key for DevP2P if not found + devP2PPrivKey, err := readDevP2PKey(*c.DataDir) + if err != nil { + return nil, err + } + cfg.P2P.PrivateKey = devP2PPrivKey + // Discovery - var err error if cfg.P2P.BootstrapNodes, err = parseBootnodes(c.P2P.Discovery.Bootnodes); err != nil { return nil, err } @@ -269,3 +295,31 @@ func parseBootnodes(urls []string) ([]*enode.Node, error) { } return dst, nil } + +const devP2PKeyPath = "devp2p.key" + +func readDevP2PKey(dataDir string) (*ecdsa.PrivateKey, error) { + path := filepath.Join(dataDir, devP2PKeyPath) + _, err := os.Stat(path) + if err != nil && !os.IsNotExist(err) { + return nil, fmt.Errorf("failed to stat (%s): %v", path, err) + } + + if os.IsNotExist(err) { + priv, err := crypto.GenerateKey() + if err != nil { + return nil, err + } + if err := crypto.SaveECDSA(path, priv); err != nil { + return nil, err + } + return priv, nil + } + + // exists + priv, err := crypto.LoadECDSA(path) + if err != nil { + return nil, err + } + return priv, nil +} diff --git a/command/server/flags.go b/command/server/flags.go index 2057f88121..66d4262798 100644 --- a/command/server/flags.go +++ b/command/server/flags.go @@ -48,7 +48,7 @@ func (c *Command) Flags() *flagset.Flagset { // sealer options f.BoolFlag(&flagset.BoolFlag{ Name: "mine", - Value: c.cliConfig.Sealer.Seal, + Value: c.cliConfig.Sealer.Enabled, Usage: "", }) f.StringFlag(&flagset.StringFlag{ From e98379679f75d91e4512e892a41ae2fd8becee4a Mon Sep 17 00:00:00 2001 From: Ferran Borreguero Date: Sun, 10 Oct 2021 15:06:46 +0200 Subject: [PATCH 06/51] Add legacy config file --- command/server/chains/mainnet.go | 2 +- command/server/command.go | 2 +- command/server/config.go | 19 +++++++++++++++- command/server/config_legacy.go | 33 ++++++++++++++++++++++++++++ command/server/config_legacy_test.go | 21 ++++++++++++++++++ go.mod | 2 +- 6 files changed, 75 insertions(+), 4 deletions(-) create mode 100644 command/server/config_legacy.go create mode 100644 command/server/config_legacy_test.go diff --git a/command/server/chains/mainnet.go b/command/server/chains/mainnet.go index 8d6f163256..ac074ed8cb 100644 --- a/command/server/chains/mainnet.go +++ b/command/server/chains/mainnet.go @@ -53,7 +53,7 @@ var mainnetBor = &Chain{ Difficulty: big.NewInt(1), Mixhash: common.HexToHash("0x0000000000000000000000000000000000000000000000000000000000000000"), Coinbase: common.HexToAddress("0x0000000000000000000000000000000000000000"), - Alloc: readPrealloc("allocs/bor_mainnet.json"), + Alloc: readPrealloc("allocs/mainnet.json"), }, Bootnodes: []string{ "enode://0cb82b395094ee4a2915e9714894627de9ed8498fb881cec6db7c65e8b9a5bd7f2f25cc84e71e89d0947e51c76e85d0847de848c7782b13c0255247a6758178c@44.232.55.71:30303", diff --git a/command/server/command.go b/command/server/command.go index 2feb0be791..59c106fea2 100644 --- a/command/server/command.go +++ b/command/server/command.go @@ -88,7 +88,6 @@ func (c *Command) Run(args []string) int { // TODO: Metrics // TODO: apis // TODO: Graphql - // TODO: embed // register the ethereum backend ethCfg, err := config.buildEth() @@ -143,6 +142,7 @@ func (c *Command) setupMetrics() error { // Start system runtime metrics collection go metrics.CollectProcessMetrics(3 * time.Second) + return nil } diff --git a/command/server/config.go b/command/server/config.go index 7b01f6885f..c8dd5c27c5 100644 --- a/command/server/config.go +++ b/command/server/config.go @@ -3,6 +3,7 @@ package server import ( "crypto/ecdsa" "fmt" + "io/ioutil" "math/big" "os" "path/filepath" @@ -50,6 +51,7 @@ type Config struct { EthStats *string TxPool *TxPoolConfig Sealer *SealerConfig + JsonRPC *JsonRPCConfig } type P2PConfig struct { @@ -92,6 +94,9 @@ type SealerConfig struct { GasPrice *big.Int } +type JsonRPCConfig struct { +} + func DefaultConfig() *Config { return &Config{ Chain: stringPtr("mainnet"), @@ -137,7 +142,18 @@ func DefaultConfig() *Config { } func readConfigFile(path string) (*Config, error) { - return nil, nil + data, err := ioutil.ReadFile(path) + if err != nil { + return nil, err + } + // TODO: Use hcl as config format + ext := filepath.Ext(path) + switch ext { + case ".toml": + return readLegacyConfig(data) + default: + return nil, fmt.Errorf("file path extension '%s' not found", ext) + } } func (c *Config) loadChain() error { @@ -219,6 +235,7 @@ func (c *Config) buildNode() (*node.Config, error) { Name: clientIdentifier, DataDir: *c.DataDir, Version: params.VersionWithCommit(gitCommit, gitDate), + IPCPath: clientIdentifier + ".ipc", P2P: p2p.Config{ MaxPeers: int(*c.P2P.MaxPeers), ListenAddr: *c.P2P.Bind + ":" + strconv.Itoa(int(*c.P2P.Port)), diff --git a/command/server/config_legacy.go b/command/server/config_legacy.go new file mode 100644 index 0000000000..0d96b2e023 --- /dev/null +++ b/command/server/config_legacy.go @@ -0,0 +1,33 @@ +package server + +import ( + "bytes" + + "github.com/naoina/toml" +) + +type legacyConfig struct { + Node struct { + P2P struct { + StaticNodes []string + TrustedNodes []string + } + } +} + +func (l *legacyConfig) Config() *Config { + c := DefaultConfig() + c.P2P.Discovery.StaticNodes = l.Node.P2P.StaticNodes + c.P2P.Discovery.TrustedNodes = l.Node.P2P.TrustedNodes + return c +} + +func readLegacyConfig(data []byte) (*Config, error) { + var legacy legacyConfig + + r := toml.NewDecoder(bytes.NewReader(data)) + if err := r.Decode(&legacy); err != nil { + return nil, err + } + return legacy.Config(), nil +} diff --git a/command/server/config_legacy_test.go b/command/server/config_legacy_test.go new file mode 100644 index 0000000000..399481fc9b --- /dev/null +++ b/command/server/config_legacy_test.go @@ -0,0 +1,21 @@ +package server + +import ( + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestConfigLegacy(t *testing.T) { + toml := `[Node.P2P] +StaticNodes = ["node1"] +TrustedNodes = ["node2"]` + + config, err := readLegacyConfig([]byte(toml)) + if err != nil { + t.Fatal(err) + } + + assert.Equal(t, config.P2P.Discovery.StaticNodes, []string{"node1"}) + assert.Equal(t, config.P2P.Discovery.TrustedNodes, []string{"node2"}) +} diff --git a/go.mod b/go.mod index 296d727ec4..dfc33fc8c7 100644 --- a/go.mod +++ b/go.mod @@ -1,6 +1,6 @@ module github.com/ethereum/go-ethereum -go 1.15 +go 1.16 require ( github.com/Azure/azure-pipeline-go v0.2.2 // indirect From a421570dc0a4b10e733c5bc90b9ed881e47a37eb Mon Sep 17 00:00:00 2001 From: Ferran Borreguero Date: Wed, 13 Oct 2021 11:34:48 +0200 Subject: [PATCH 07/51] Add the rest of the flags --- command/flagset/flagset.go | 123 ++++++++++- command/server/command.go | 102 ++++++--- command/server/config.go | 422 +++++++++++++++++++++++++++++++------ command/server/flags.go | 376 +++++++++++++++++++++++++++++++-- 4 files changed, 914 insertions(+), 109 deletions(-) diff --git a/command/flagset/flagset.go b/command/flagset/flagset.go index 696765e8c6..c272bfbcad 100644 --- a/command/flagset/flagset.go +++ b/command/flagset/flagset.go @@ -3,6 +3,7 @@ package flagset import ( "flag" "fmt" + "math/big" "strings" "time" ) @@ -46,10 +47,6 @@ func (f *Flagset) Args() []string { return f.set.Args() } -func (f *Flagset) BoolVar() { - -} - type BoolFlag struct { Name string Usage string @@ -95,6 +92,56 @@ func (f *Flagset) IntFlag(i *IntFlag) { f.set.IntVar(i.Value, i.Name, i.Default, i.Usage) } +type Uint64Flag struct { + Name string + Usage string + Default uint64 + Value *uint64 +} + +func (f *Flagset) Uint64Flag(i *Uint64Flag) { + f.addFlag(&FlagVar{ + Name: i.Name, + Usage: i.Usage, + }) + f.set.Uint64Var(i.Value, i.Name, i.Default, i.Usage) +} + +type BigIntFlag struct { + Name string + Usage string + Default *big.Int + Value *big.Int +} + +func (b *BigIntFlag) String() string { + return b.Value.String() +} + +func (b *BigIntFlag) Set(value string) error { + num := new(big.Int) + + var ok bool + if strings.HasPrefix(value, "0x") { + num, ok = num.SetString(value[2:], 16) + } else { + num, ok = num.SetString(value, 10) + } + if !ok { + return fmt.Errorf("failed to set big int") + } + b.Value = num + return nil +} + +func (f *Flagset) BigIntFlag(b *BigIntFlag) { + f.addFlag(&FlagVar{ + Name: b.Name, + Usage: b.Usage, + }) + f.set.Var(b, b.Name, b.Usage) +} + type SliceStringFlag struct { Name string Usage string @@ -102,7 +149,7 @@ type SliceStringFlag struct { } func (i *SliceStringFlag) String() string { - return "" + return strings.Join(i.Value, ",") } func (i *SliceStringFlag) Set(value string) error { @@ -124,9 +171,75 @@ type DurationFlag struct { Value *time.Duration } +func (d *DurationFlag) String() string { + return d.Value.String() +} + +func (d *DurationFlag) Set(value string) error { + v, err := time.ParseDuration(value) + if err != nil { + return err + } + d.Value = &v + return nil +} + func (f *Flagset) DurationFlag(d *DurationFlag) { f.addFlag(&FlagVar{ Name: d.Name, Usage: d.Usage, }) + f.set.Var(d, d.Name, d.Usage) +} + +type MapStringFlag struct { + Name string + Usage string + Value *map[string]string +} + +func (m *MapStringFlag) String() string { + ls := []string{} + for k, v := range *m.Value { + ls = append(ls, k+"="+v) + } + return strings.Join(ls, ",") +} + +func (m *MapStringFlag) Set(value string) error { + if m.Value == nil { + m.Value = &map[string]string{} + } + for _, t := range strings.Split(value, ",") { + if t != "" { + kv := strings.Split(t, "=") + + if len(kv) == 2 { + (*m.Value)[kv[0]] = kv[1] + } + } + } + return nil +} + +func (f *Flagset) MapStringFlag(m *MapStringFlag) { + f.addFlag(&FlagVar{ + Name: m.Name, + Usage: m.Usage, + }) + f.set.Var(m, m.Name, m.Usage) +} + +type Float64Flag struct { + Name string + Usage string + Value *float64 +} + +func (f *Flagset) Float64Flag(i *Float64Flag) { + f.addFlag(&FlagVar{ + Name: i.Name, + Usage: i.Usage, + }) + f.set.Float64Var(i.Value, i.Name, *i.Value, "") } diff --git a/command/server/command.go b/command/server/command.go index 59c106fea2..56b1e1f105 100644 --- a/command/server/command.go +++ b/command/server/command.go @@ -11,9 +11,12 @@ import ( "github.com/ethereum/go-ethereum/accounts/keystore" "github.com/ethereum/go-ethereum/eth" + "github.com/ethereum/go-ethereum/eth/tracers" "github.com/ethereum/go-ethereum/ethstats" + "github.com/ethereum/go-ethereum/graphql" "github.com/ethereum/go-ethereum/log" "github.com/ethereum/go-ethereum/metrics" + "github.com/ethereum/go-ethereum/metrics/influxdb" "github.com/ethereum/go-ethereum/node" "github.com/mattn/go-colorable" "github.com/mattn/go-isatty" @@ -57,89 +60,136 @@ func (c *Command) Run(args []string) int { // read config file config := DefaultConfig() if c.configFile != "" { - c, err := readConfigFile(c.configFile) + cfg, err := readConfigFile(c.configFile) if err != nil { - panic(err) + c.UI.Error(err.Error()) + return 1 + } + if err := config.Merge(cfg); err != nil { + c.UI.Error(err.Error()) + return 1 } - config.Merge(c) } - config.Merge(c.cliConfig) + if err := config.Merge(c.cliConfig); err != nil { + c.UI.Error(err.Error()) + return 1 + } // start the logger setupLogger(*config.LogLevel) // load the chain genesis if err := config.loadChain(); err != nil { - panic(err) + c.UI.Error(err.Error()) + return 1 } // create the node/stack nodeCfg, err := config.buildNode() if err != nil { - panic(err) + c.UI.Error(err.Error()) + return 1 } stack, err := node.New(nodeCfg) if err != nil { - panic(err) + c.UI.Error(err.Error()) + return 1 } c.node = stack - // TODO: MakeChain? - // TODO: Metrics - // TODO: apis - // TODO: Graphql - // register the ethereum backend ethCfg, err := config.buildEth() if err != nil { - panic(err) + c.UI.Error(err.Error()) + return 1 } backend, err := eth.New(stack, ethCfg) if err != nil { - panic(err) + c.UI.Error(err.Error()) + return 1 } - // This is the tracers api, not sure if this should be here, i do not think so. - // c.node.RegisterAPIs(tracers.APIs(backend.APIBackend)) + // debug tracing is enabled by default + stack.RegisterAPIs(tracers.APIs(backend.APIBackend)) + + // graphql is started from another place + if *config.JsonRPC.Graphql.Enabled { + if err := graphql.New(stack, backend.APIBackend, config.JsonRPC.Cors, config.JsonRPC.Modules); err != nil { + c.UI.Error(fmt.Sprintf("Failed to register the GraphQL service: %v", err)) + return 1 + } + } // register ethash service if config.EthStats != nil { if err := ethstats.New(stack, backend.APIBackend, backend.Engine(), *config.EthStats); err != nil { - panic(err) + c.UI.Error(err.Error()) + return 1 } } // setup account manager (only keystore) { keydir := stack.KeyStoreDir() - scryptN := keystore.StandardScryptN - scryptP := keystore.StandardScryptP - - stack.AccountManager().AddBackend(keystore.NewKeyStore(keydir, scryptN, scryptP)) + n, p := keystore.StandardScryptN, keystore.StandardScryptP + if *config.UseLightweightKDF { + n, p = keystore.LightScryptN, keystore.LightScryptP + } + stack.AccountManager().AddBackend(keystore.NewKeyStore(keydir, n, p)) } // sealing (if enabled) if *config.Sealer.Enabled { if err := backend.StartMining(1); err != nil { - panic(err) + c.UI.Error(err.Error()) + return 1 } } - c.setupMetrics() + if err := c.setupMetrics(config.Metrics); err != nil { + c.UI.Error(err.Error()) + return 1 + } // start the node if err := c.node.Start(); err != nil { - panic(err) + c.UI.Error(err.Error()) + return 1 } return c.handleSignals() } -func (c *Command) setupMetrics() error { +func (c *Command) setupMetrics(config *MetricsConfig) error { + metrics.Enabled = *config.Enabled + metrics.EnabledExpensive = *config.Expensive + if !metrics.Enabled { - // metrics are globally disabled + // metrics are disabled, do not set up any sink return nil } + log.Info("Enabling metrics collection") + + // influxdb + if v1Enabled, v2Enabled := (*config.InfluxDB.V1Enabled), (*config.InfluxDB.V2Enabled); v1Enabled || v2Enabled { + if v1Enabled && v2Enabled { + return fmt.Errorf("both influx v1 and influx v2 cannot be enabled") + } + + cfg := config.InfluxDB + tags := *cfg.Tags + endpoint := *cfg.Endpoint + + if v1Enabled { + log.Info("Enabling metrics export to InfluxDB (v1)") + go influxdb.InfluxDBWithTags(metrics.DefaultRegistry, 10*time.Second, endpoint, *cfg.Database, *cfg.Username, *cfg.Password, "geth.", tags) + } + if v2Enabled { + log.Info("Enabling metrics export to InfluxDB (v2)") + go influxdb.InfluxDBV2WithTags(metrics.DefaultRegistry, 10*time.Second, endpoint, *cfg.Token, *cfg.Bucket, *cfg.Organization, "geth.", tags) + } + } + // Start system runtime metrics collection go metrics.CollectProcessMetrics(3 * time.Second) diff --git a/command/server/config.go b/command/server/config.go index c8dd5c27c5..5236d20c72 100644 --- a/command/server/config.go +++ b/command/server/config.go @@ -4,29 +4,44 @@ import ( "crypto/ecdsa" "fmt" "io/ioutil" + "math" "math/big" "os" "path/filepath" "strconv" "time" + godebug "runtime/debug" + "github.com/ethereum/go-ethereum/command/server/chains" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/fdlimit" "github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/eth/downloader" "github.com/ethereum/go-ethereum/eth/ethconfig" + "github.com/ethereum/go-ethereum/eth/gasprice" + "github.com/ethereum/go-ethereum/log" "github.com/ethereum/go-ethereum/node" "github.com/ethereum/go-ethereum/p2p" "github.com/ethereum/go-ethereum/p2p/enode" + "github.com/ethereum/go-ethereum/p2p/nat" "github.com/ethereum/go-ethereum/params" "github.com/imdario/mergo" + gopsutil "github.com/shirou/gopsutil/mem" ) +func mapStrPtr(m map[string]string) *map[string]string { + return &m +} + func stringPtr(s string) *string { return &s } +func float64Ptr(f float64) *float64 { + return &f +} + func uint64Ptr(i uint64) *uint64 { return &i } @@ -42,28 +57,39 @@ func durPtr(d time.Duration) *time.Duration { type Config struct { chain *chains.Chain - Chain *string - Debug *bool - LogLevel *string - DataDir *string - P2P *P2PConfig - SyncMode *string - EthStats *string - TxPool *TxPoolConfig - Sealer *SealerConfig - JsonRPC *JsonRPCConfig + Chain *string + Debug *bool + Whitelist *map[string]string + UseLightweightKDF *bool + LogLevel *string + DataDir *string + P2P *P2PConfig + SyncMode *string + GcMode *string + Snapshot *bool + EthStats *string + Heimdall *HeimdallConfig + TxPool *TxPoolConfig + Sealer *SealerConfig + JsonRPC *JsonRPCConfig + Gpo *GpoConfig + Ethstats *string + Metrics *MetricsConfig + Cache *CacheConfig } type P2PConfig struct { - MaxPeers *uint64 - Bind *string - Port *uint64 - NoDiscover *bool - V5Disc *bool - Discovery *P2PDiscovery + MaxPeers *uint64 + MaxPendPeers *uint64 + Bind *string + Port *uint64 + NoDiscover *bool + NAT *string + Discovery *P2PDiscovery } type P2PDiscovery struct { + V5Enabled *bool Bootnodes []string BootnodesV4 []string BootnodesV5 []string @@ -72,6 +98,11 @@ type P2PDiscovery struct { DNS []string } +type HeimdallConfig struct { + URL *string + Without *bool +} + type TxPoolConfig struct { Locals []string NoLocals *bool @@ -95,21 +126,84 @@ type SealerConfig struct { } type JsonRPCConfig struct { + IPCDisable *bool + IPCPath *string + + Modules []string + VHost []string + Cors []string + Bind *string + + GasCap *uint64 + TxFeeCap *float64 + + Http *APIConfig + Ws *APIConfig + Graphql *APIConfig +} + +type APIConfig struct { + Enabled *bool + Port *uint64 + Prefix *string +} + +type GpoConfig struct { + Blocks *uint64 + Percentile *uint64 + MaxPrice *big.Int + IgnorePrice *big.Int +} + +type MetricsConfig struct { + Enabled *bool + Expensive *bool + InfluxDB *InfluxDBConfig +} + +type InfluxDBConfig struct { + V1Enabled *bool + Endpoint *string + Database *string + Username *string + Password *string + Tags *map[string]string + V2Enabled *bool + Token *string + Bucket *string + Organization *string +} + +type CacheConfig struct { + Cache *uint64 + PercGc *uint64 + PercSnapshot *uint64 + PercDatabase *uint64 + PercTrie *uint64 + Journal *string + Rejournal *time.Duration + NoPrefetch *bool + Preimages *bool + TxLookupLimit *uint64 } func DefaultConfig() *Config { return &Config{ - Chain: stringPtr("mainnet"), - Debug: boolPtr(false), - LogLevel: stringPtr("INFO"), - DataDir: stringPtr(""), + Chain: stringPtr("mainnet"), + Debug: boolPtr(false), + UseLightweightKDF: boolPtr(false), + Whitelist: mapStrPtr(map[string]string{}), + LogLevel: stringPtr("INFO"), + DataDir: stringPtr(node.DefaultDataDir()), P2P: &P2PConfig{ - MaxPeers: uint64Ptr(30), - Bind: stringPtr("0.0.0.0"), - Port: uint64Ptr(30303), - NoDiscover: boolPtr(false), - V5Disc: boolPtr(false), + MaxPeers: uint64Ptr(30), + MaxPendPeers: uint64Ptr(50), + Bind: stringPtr("0.0.0.0"), + Port: uint64Ptr(30303), + NoDiscover: boolPtr(false), + NAT: stringPtr("any"), Discovery: &P2PDiscovery{ + V5Enabled: boolPtr(false), Bootnodes: []string{}, BootnodesV4: []string{}, BootnodesV5: []string{}, @@ -118,7 +212,13 @@ func DefaultConfig() *Config { DNS: []string{}, }, }, + Heimdall: &HeimdallConfig{ + URL: stringPtr("http://localhost:1317"), + Without: boolPtr(false), + }, SyncMode: stringPtr("fast"), + GcMode: stringPtr("full"), + Snapshot: boolPtr(true), EthStats: stringPtr(""), TxPool: &TxPoolConfig{ Locals: []string{}, @@ -134,9 +234,66 @@ func DefaultConfig() *Config { LifeTime: durPtr(3 * time.Hour), }, Sealer: &SealerConfig{ - Enabled: boolPtr(false), - GasCeil: uint64Ptr(8000000), - GasPrice: big.NewInt(params.GWei), + Enabled: boolPtr(false), + GasCeil: uint64Ptr(8000000), + GasPrice: big.NewInt(params.GWei), + ExtraData: stringPtr(""), + }, + Gpo: &GpoConfig{ + Blocks: uint64Ptr(20), + Percentile: uint64Ptr(60), + MaxPrice: gasprice.DefaultMaxPrice, + IgnorePrice: gasprice.DefaultIgnorePrice, + }, + JsonRPC: &JsonRPCConfig{ + IPCDisable: boolPtr(false), + Modules: []string{"web3", "net"}, + Cors: []string{"*"}, + VHost: []string{"*"}, + GasCap: uint64Ptr(ethconfig.Defaults.RPCGasCap), + TxFeeCap: float64Ptr(ethconfig.Defaults.RPCTxFeeCap), + Http: &APIConfig{ + Enabled: boolPtr(false), + Port: uint64Ptr(8545), + Prefix: stringPtr(""), + }, + Ws: &APIConfig{ + Enabled: boolPtr(false), + Port: uint64Ptr(8546), + Prefix: stringPtr(""), + }, + Graphql: &APIConfig{ + Enabled: boolPtr(false), + }, + }, + Ethstats: stringPtr(""), + Metrics: &MetricsConfig{ + Enabled: boolPtr(false), + Expensive: boolPtr(false), + InfluxDB: &InfluxDBConfig{ + V1Enabled: boolPtr(false), + Endpoint: stringPtr(""), + Database: stringPtr(""), + Username: stringPtr(""), + Password: stringPtr(""), + Tags: mapStrPtr(map[string]string{}), + V2Enabled: boolPtr(false), + Token: stringPtr(""), + Bucket: stringPtr(""), + Organization: stringPtr(""), + }, + }, + Cache: &CacheConfig{ + Cache: uint64Ptr(1024), + PercDatabase: uint64Ptr(50), + PercTrie: uint64Ptr(15), + PercGc: uint64Ptr(25), + PercSnapshot: uint64Ptr(10), + Journal: stringPtr("triecache"), + Rejournal: durPtr(60 * time.Minute), + NoPrefetch: boolPtr(false), + Preimages: boolPtr(false), + TxLookupLimit: uint64Ptr(2350000), }, } } @@ -163,13 +320,22 @@ func (c *Config) loadChain() error { } c.chain = chain - // preload some default values that are on the chain file + // preload some default values that depend on the chain file + + // the genesis files defines default bootnodes if c.P2P.Discovery.Bootnodes == nil { c.P2P.Discovery.Bootnodes = c.chain.Bootnodes } if c.P2P.Discovery.DNS == nil { c.P2P.Discovery.DNS = c.chain.DNS } + + // depending on the chain we have different cache values + if *c.Chain != "mainnet" { + c.Cache.Cache = uint64Ptr(4096) + } else { + c.Cache.Cache = uint64Ptr(1024) + } return nil } @@ -184,25 +350,30 @@ func (c *Config) buildEth() (*ethconfig.Config, error) { // txpool options { - cfg := n.TxPool - cfg.NoLocals = *c.TxPool.NoLocals - cfg.Journal = *c.TxPool.Journal - cfg.Rejournal = *c.TxPool.Rejournal - cfg.PriceLimit = *c.TxPool.PriceLimit - cfg.PriceBump = *c.TxPool.PriceBump - cfg.AccountSlots = *c.TxPool.AccountSlots - cfg.GlobalSlots = *c.TxPool.GlobalSlots - cfg.AccountQueue = *c.TxPool.AccountQueue - cfg.GlobalQueue = *c.TxPool.GlobalQueue - cfg.Lifetime = *c.TxPool.LifeTime + n.TxPool.NoLocals = *c.TxPool.NoLocals + n.TxPool.Journal = *c.TxPool.Journal + n.TxPool.Rejournal = *c.TxPool.Rejournal + n.TxPool.PriceLimit = *c.TxPool.PriceLimit + n.TxPool.PriceBump = *c.TxPool.PriceBump + n.TxPool.AccountSlots = *c.TxPool.AccountSlots + n.TxPool.GlobalSlots = *c.TxPool.GlobalSlots + n.TxPool.AccountQueue = *c.TxPool.AccountQueue + n.TxPool.GlobalQueue = *c.TxPool.GlobalQueue + n.TxPool.Lifetime = *c.TxPool.LifeTime } // miner options { - cfg := n.Miner - cfg.Etherbase = common.HexToAddress(*c.Sealer.Etherbase) - cfg.GasPrice = c.Sealer.GasPrice - cfg.GasCeil = *c.Sealer.GasCeil + n.Miner.GasPrice = c.Sealer.GasPrice + n.Miner.GasCeil = *c.Sealer.GasCeil + n.Miner.ExtraData = []byte(*c.Sealer.ExtraData) + + if etherbase := c.Sealer.Etherbase; etherbase != nil { + if !common.IsHexAddress(*etherbase) { + return nil, fmt.Errorf("etherbase is not an address: %s", *etherbase) + } + n.Miner.Etherbase = common.HexToAddress(*etherbase) + } } // discovery (this params should be in node.Config) @@ -211,16 +382,106 @@ func (c *Config) buildEth() (*ethconfig.Config, error) { n.SnapDiscoveryURLs = c.P2P.Discovery.DNS } - var syncMode downloader.SyncMode + // whitelist + { + n.Whitelist = map[uint64]common.Hash{} + for k, v := range *c.Whitelist { + number, err := strconv.ParseUint(k, 0, 64) + if err != nil { + return nil, fmt.Errorf("invalid whitelist block number %s: %v", k, err) + } + var hash common.Hash + if err = hash.UnmarshalText([]byte(v)); err != nil { + return nil, fmt.Errorf("invalid whitelist hash %s: %v", v, err) + } + n.Whitelist[number] = hash + } + } + + // cache + { + cache := *c.Cache.Cache + calcPerc := func(val *uint64) int { + return int(cache * (*val) / 100) + } + + // Cap the cache allowance + mem, err := gopsutil.VirtualMemory() + if err == nil { + if 32<<(^uintptr(0)>>63) == 32 && mem.Total > 2*1024*1024*1024 { + log.Warn("Lowering memory allowance on 32bit arch", "available", mem.Total/1024/1024, "addressable", 2*1024) + mem.Total = 2 * 1024 * 1024 * 1024 + } + allowance := uint64(mem.Total / 1024 / 1024 / 3) + if cache > allowance { + log.Warn("Sanitizing cache to Go's GC limits", "provided", cache, "updated", allowance) + cache = allowance + } + } + // Tune the garbage collector + gogc := math.Max(20, math.Min(100, 100/(float64(cache)/1024))) + + log.Debug("Sanitizing Go's GC trigger", "percent", int(gogc)) + godebug.SetGCPercent(int(gogc)) + + n.TrieCleanCacheJournal = *c.Cache.Journal + n.TrieCleanCacheRejournal = *c.Cache.Rejournal + n.DatabaseCache = calcPerc(c.Cache.PercDatabase) + n.SnapshotCache = calcPerc(c.Cache.PercSnapshot) + n.TrieCleanCache = calcPerc(c.Cache.PercTrie) + n.TrieDirtyCache = calcPerc(c.Cache.PercGc) + n.NoPrefetch = *c.Cache.NoPrefetch + n.Preimages = *c.Cache.Preimages + n.TxLookupLimit = *c.Cache.TxLookupLimit + } + + n.RPCGasCap = *c.JsonRPC.GasCap + if n.RPCGasCap != 0 { + log.Info("Set global gas cap", "cap", n.RPCGasCap) + } else { + log.Info("Global gas cap disabled") + } + n.RPCTxFeeCap = *c.JsonRPC.TxFeeCap + + // sync mode. It can either be "fast", "full" or "snap". We disable + // for now the "light" mode. switch *c.SyncMode { case "fast": - syncMode = downloader.FastSync + n.SyncMode = downloader.FastSync + case "full": + n.SyncMode = downloader.FullSync + case "snap": + n.SyncMode = downloader.SnapSync default: - return nil, fmt.Errorf("sync mode '%s' not found", syncMode) + return nil, fmt.Errorf("sync mode '%s' not found", *c.SyncMode) } - n.SyncMode = syncMode - n.DatabaseHandles = dbHandles + // archive mode. It can either be "archive" or "full". + switch *c.GcMode { + case "full": + n.NoPruning = false + case "archive": + n.NoPruning = true + if !n.Preimages { + n.Preimages = true + log.Info("Enabling recording of key preimages since archive mode is used") + } + default: + return nil, fmt.Errorf("gcmode '%s' not found", *c.GcMode) + } + + // snapshot disable check + if *c.Snapshot { + if n.SyncMode == downloader.SnapSync { + log.Info("Snap sync requested, enabling --snapshot") + } else { + // disable snapshot + n.TrieCleanCache += n.SnapshotCache + n.SnapshotCache = 0 + } + } + + n.DatabaseHandles = dbHandles return &n, nil } @@ -231,24 +492,55 @@ var ( ) func (c *Config) buildNode() (*node.Config, error) { - cfg := &node.Config{ - Name: clientIdentifier, - DataDir: *c.DataDir, - Version: params.VersionWithCommit(gitCommit, gitDate), - IPCPath: clientIdentifier + ".ipc", - P2P: p2p.Config{ - MaxPeers: int(*c.P2P.MaxPeers), - ListenAddr: *c.P2P.Bind + ":" + strconv.Itoa(int(*c.P2P.Port)), - }, - /* - HTTPHost: *c.BindAddr, - HTTPPort: int(*c.Ports.HTTP), - HTTPVirtualHosts: []string{"*"}, - WSHost: *c.BindAddr, - WSPort: int(*c.Ports.Websocket), - */ + ipcPath := "" + if !*c.JsonRPC.IPCDisable { + ipcPath = clientIdentifier + ".ipc" + if c.JsonRPC.IPCPath != nil { + ipcPath = *c.JsonRPC.IPCPath + } } + cfg := &node.Config{ + Name: clientIdentifier, + DataDir: *c.DataDir, + UseLightweightKDF: *c.UseLightweightKDF, + Version: params.VersionWithCommit(gitCommit, gitDate), + IPCPath: ipcPath, + P2P: p2p.Config{ + MaxPeers: int(*c.P2P.MaxPeers), + MaxPendingPeers: int(*c.P2P.MaxPendPeers), + ListenAddr: *c.P2P.Bind + ":" + strconv.Itoa(int(*c.P2P.Port)), + DiscoveryV5: *c.P2P.Discovery.V5Enabled, + }, + HTTPModules: c.JsonRPC.Modules, + HTTPCors: c.JsonRPC.Cors, + HTTPVirtualHosts: c.JsonRPC.VHost, + HTTPPathPrefix: *c.JsonRPC.Http.Prefix, + WSModules: c.JsonRPC.Modules, + WSOrigins: c.JsonRPC.Cors, + WSPathPrefix: *c.JsonRPC.Ws.Prefix, + GraphQLCors: c.JsonRPC.Cors, + GraphQLVirtualHosts: c.JsonRPC.VHost, + } + + // enable jsonrpc endpoints + { + if *c.JsonRPC.Http.Enabled { + cfg.HTTPHost = *c.JsonRPC.Bind + cfg.HTTPPort = int(*c.JsonRPC.Http.Port) + } + if *c.JsonRPC.Ws.Enabled { + cfg.WSHost = *c.JsonRPC.Bind + cfg.WSPort = int(*c.JsonRPC.Ws.Port) + } + } + + natif, err := nat.Parse(*c.P2P.NAT) + if err != nil { + return nil, fmt.Errorf("wrong 'nat' flag: %v", err) + } + cfg.P2P.NAT = natif + // setup private key for DevP2P if not found devP2PPrivKey, err := readDevP2PKey(*c.DataDir) if err != nil { diff --git a/command/server/flags.go b/command/server/flags.go index 66d4262798..b0359d525f 100644 --- a/command/server/flags.go +++ b/command/server/flags.go @@ -1,65 +1,415 @@ package server -import "github.com/ethereum/go-ethereum/command/flagset" +import ( + "github.com/ethereum/go-ethereum/command/flagset" +) func (c *Command) Flags() *flagset.Flagset { c.cliConfig = DefaultConfig() - f := flagset.NewFlagSet("") + f := flagset.NewFlagSet("server") f.BoolFlag(&flagset.BoolFlag{ Name: "debug", - Value: c.cliConfig.Debug, Usage: "Path of the file to apply", + Value: c.cliConfig.Debug, }) f.StringFlag(&flagset.StringFlag{ Name: "chain", - Value: c.cliConfig.Chain, Usage: "Name of the chain to sync", + Value: c.cliConfig.Chain, }) f.StringFlag(&flagset.StringFlag{ Name: "log-level", - Value: c.cliConfig.LogLevel, Usage: "Set log level for the server", + Value: c.cliConfig.LogLevel, }) f.StringFlag(&flagset.StringFlag{ - Name: "data-dir", - Value: c.cliConfig.DataDir, + Name: "datadir", Usage: "Path of the data directory to store information", + Value: c.cliConfig.DataDir, }) f.StringFlag(&flagset.StringFlag{ Name: "config", - Value: &c.configFile, Usage: "File for the config file", + Value: &c.configFile, + }) + f.StringFlag(&flagset.StringFlag{ + Name: "syncmode", + Usage: `Blockchain sync mode ("fast", "full", "snap" or "light")`, + Value: c.cliConfig.SyncMode, + }) + f.StringFlag(&flagset.StringFlag{ + Name: "gcmode", + Usage: `Blockchain garbage collection mode ("full", "archive")`, + Value: c.cliConfig.GcMode, + }) + f.BoolFlag(&flagset.BoolFlag{ + Name: "lightkdf", + Usage: "Reduce key-derivation RAM & CPU usage at some expense of KDF strength", + Value: c.cliConfig.UseLightweightKDF, + }) + f.MapStringFlag(&flagset.MapStringFlag{ + Name: "whitelist", + Usage: "Comma separated block number-to-hash mappings to enforce (=)", + Value: c.cliConfig.Whitelist, + }) + f.BoolFlag(&flagset.BoolFlag{ + Name: "snapshot", + Usage: `Enables snapshot-database mode (default = enable)`, + Value: c.cliConfig.Snapshot, + }) + + // heimdall + f.StringFlag(&flagset.StringFlag{ + Name: "bor.heimdall", + Usage: "URL of Heimdall service", + Value: c.cliConfig.Heimdall.URL, + }) + f.BoolFlag(&flagset.BoolFlag{ + Name: "bor.withoutheimdall", + Usage: "Run without Heimdall service (for testing purpose)", + Value: c.cliConfig.Heimdall.Without, }) // txpool options f.SliceStringFlag(&flagset.SliceStringFlag{ Name: "txpool.locals", - Value: c.cliConfig.TxPool.Locals, Usage: "Comma separated accounts to treat as locals (no flush, priority inclusion)", + Value: c.cliConfig.TxPool.Locals, }) f.BoolFlag(&flagset.BoolFlag{ Name: "txpool.nolocals", - Value: c.cliConfig.TxPool.NoLocals, Usage: "Disables price exemptions for locally submitted transactions", + Value: c.cliConfig.TxPool.NoLocals, + }) + f.StringFlag(&flagset.StringFlag{ + Name: "txpool.journal", + Usage: "Disk journal for local transaction to survive node restarts", + Value: c.cliConfig.TxPool.Journal, + }) + f.DurationFlag(&flagset.DurationFlag{ + Name: "txpool.rejournal", + Usage: "Time interval to regenerate the local transaction journal", + Value: c.cliConfig.TxPool.Rejournal, + }) + f.Uint64Flag(&flagset.Uint64Flag{ + Name: "txpool.pricelimit", + Usage: "Minimum gas price limit to enforce for acceptance into the pool", + Value: c.cliConfig.TxPool.PriceLimit, + }) + f.Uint64Flag(&flagset.Uint64Flag{ + Name: "txpool.pricebump", + Usage: "Price bump percentage to replace an already existing transaction", + Value: c.cliConfig.TxPool.PriceBump, + }) + f.Uint64Flag(&flagset.Uint64Flag{ + Name: "txpool.accountslots", + Usage: "Minimum number of executable transaction slots guaranteed per account", + Value: c.cliConfig.TxPool.AccountSlots, + }) + f.Uint64Flag(&flagset.Uint64Flag{ + Name: "txpool.globalslots", + Usage: "Maximum number of executable transaction slots for all accounts", + Value: c.cliConfig.TxPool.GlobalSlots, + }) + f.Uint64Flag(&flagset.Uint64Flag{ + Name: "txpool.accountqueue", + Usage: "Maximum number of non-executable transaction slots permitted per account", + Value: c.cliConfig.TxPool.AccountQueue, + }) + f.Uint64Flag(&flagset.Uint64Flag{ + Name: "txpool.globalqueue", + Usage: "Maximum number of non-executable transaction slots for all accounts", + Value: c.cliConfig.TxPool.GlobalQueue, + }) + f.DurationFlag(&flagset.DurationFlag{ + Name: "txpool.lifetime", + Usage: "Maximum amount of time non-executable transaction are queued", + Value: c.cliConfig.TxPool.LifeTime, }) // sealer options f.BoolFlag(&flagset.BoolFlag{ Name: "mine", + Usage: "Enable mining", Value: c.cliConfig.Sealer.Enabled, - Usage: "", }) f.StringFlag(&flagset.StringFlag{ Name: "miner.etherbase", + Usage: "Public address for block mining rewards (default = first account)", Value: c.cliConfig.Sealer.Etherbase, - Usage: "", }) f.StringFlag(&flagset.StringFlag{ Name: "miner.extradata", + Usage: "Block extra data set by the miner (default = client version)", Value: c.cliConfig.Sealer.ExtraData, - Usage: "", + }) + f.Uint64Flag(&flagset.Uint64Flag{ + Name: "miner.gaslimit", + Usage: "Target gas ceiling for mined blocks", + Value: c.cliConfig.Sealer.GasCeil, + }) + f.BigIntFlag(&flagset.BigIntFlag{ + Name: "miner.gasprice", + Usage: "Minimum gas price for mining a transaction", + Value: c.cliConfig.Sealer.GasPrice, + }) + + // ethstats + f.StringFlag(&flagset.StringFlag{ + Name: "ethstats", + Usage: "Reporting URL of a ethstats service (nodename:secret@host:port)", + Value: c.cliConfig.Ethstats, + }) + + // gas price oracle + f.Uint64Flag(&flagset.Uint64Flag{ + Name: "gpo.blocks", + Usage: "Number of recent blocks to check for gas prices", + Value: c.cliConfig.Gpo.Blocks, + }) + f.Uint64Flag(&flagset.Uint64Flag{ + Name: "gpo.percentile", + Usage: "Suggested gas price is the given percentile of a set of recent transaction gas prices", + Value: c.cliConfig.Gpo.Percentile, + }) + f.BigIntFlag(&flagset.BigIntFlag{ + Name: "gpo.maxprice", + Usage: "Maximum gas price will be recommended by gpo", + Value: c.cliConfig.Gpo.MaxPrice, + }) + f.BigIntFlag(&flagset.BigIntFlag{ + Name: "gpo.ignoreprice", + Usage: "Gas price below which gpo will ignore transactions", + Value: c.cliConfig.Gpo.IgnorePrice, + }) + + // cache options + f.Uint64Flag(&flagset.Uint64Flag{ + Name: "cache", + Usage: "Megabytes of memory allocated to internal caching (default = 4096 mainnet full node)", + Value: c.cliConfig.Cache.Cache, + }) + f.Uint64Flag(&flagset.Uint64Flag{ + Name: "cache.database", + Usage: "Percentage of cache memory allowance to use for database io", + Value: c.cliConfig.Cache.PercDatabase, + }) + f.Uint64Flag(&flagset.Uint64Flag{ + Name: "cache.trie", + Usage: "Percentage of cache memory allowance to use for trie caching (default = 15% full mode, 30% archive mode)", + Value: c.cliConfig.Cache.PercTrie, + }) + f.StringFlag(&flagset.StringFlag{ + Name: "cache.trie.journal", + Usage: "Disk journal directory for trie cache to survive node restarts", + Value: c.cliConfig.Cache.Journal, + }) + f.DurationFlag(&flagset.DurationFlag{ + Name: "cache.trie.rejournal", + Usage: "Time interval to regenerate the trie cache journal", + Value: c.cliConfig.Cache.Rejournal, + }) + f.Uint64Flag(&flagset.Uint64Flag{ + Name: "cache.gc", + Usage: "Percentage of cache memory allowance to use for trie pruning (default = 25% full mode, 0% archive mode)", + Value: c.cliConfig.Cache.PercGc, + }) + f.Uint64Flag(&flagset.Uint64Flag{ + Name: "cache.snapshot", + Usage: "Percentage of cache memory allowance to use for snapshot caching (default = 10% full mode, 20% archive mode)", + Value: c.cliConfig.Cache.PercSnapshot, + }) + f.BoolFlag(&flagset.BoolFlag{ + Name: "cache.noprefetch", + Usage: "Disable heuristic state prefetch during block import (less CPU and disk IO, more time waiting for data)", + Value: c.cliConfig.Cache.NoPrefetch, + }) + f.BoolFlag(&flagset.BoolFlag{ + Name: "cache.preimages", + Usage: "Enable recording the SHA3/keccak preimages of trie keys", + Value: c.cliConfig.Cache.Preimages, + }) + f.Uint64Flag(&flagset.Uint64Flag{ + Name: "txlookuplimit", + Usage: "Number of recent blocks to maintain transactions index for (default = about one year, 0 = entire chain)", + Value: c.cliConfig.Cache.TxLookupLimit, + }) + + // rpc options + f.Uint64Flag(&flagset.Uint64Flag{ + Name: "rpc.gascap", + Usage: "Sets a cap on gas that can be used in eth_call/estimateGas (0=infinite)", + Value: c.cliConfig.JsonRPC.GasCap, + }) + f.Float64Flag(&flagset.Float64Flag{ + Name: "rpc.txfeecap", + Usage: "Sets a cap on transaction fee (in ether) that can be sent via the RPC APIs (0 = no cap)", + Value: c.cliConfig.JsonRPC.TxFeeCap, + }) + f.BoolFlag(&flagset.BoolFlag{ + Name: "ipcdisable", + Usage: "Disable the IPC-RPC server", + Value: c.cliConfig.JsonRPC.IPCDisable, + }) + f.StringFlag(&flagset.StringFlag{ + Name: "ipcpath", + Usage: "Filename for IPC socket/pipe within the datadir (explicit paths escape it)", + Value: c.cliConfig.JsonRPC.IPCPath, + }) + f.SliceStringFlag(&flagset.SliceStringFlag{ + Name: "rpc.corsdomain", + Usage: "Comma separated list of domains from which to accept cross origin requests (browser enforced)", + Value: c.cliConfig.JsonRPC.Cors, + }) + f.SliceStringFlag(&flagset.SliceStringFlag{ + Name: "rpc.vhosts", + Usage: "Comma separated list of virtual hostnames from which to accept requests (server enforced). Accepts '*' wildcard.", + Value: c.cliConfig.JsonRPC.VHost, + }) + // http options + f.BoolFlag(&flagset.BoolFlag{ + Name: "http", + Usage: "Enable the HTTP-RPC server", + Value: c.cliConfig.JsonRPC.Http.Enabled, + }) + f.Uint64Flag(&flagset.Uint64Flag{ + Name: "http.port", + Usage: "HTTP-RPC server listening port", + Value: c.cliConfig.JsonRPC.Http.Port, + }) + f.StringFlag(&flagset.StringFlag{ + Name: "http.rpcprefix", + Usage: "HTTP path path prefix on which JSON-RPC is served. Use '/' to serve on all paths.", + Value: c.cliConfig.JsonRPC.Http.Prefix, + }) + // ws options + f.BoolFlag(&flagset.BoolFlag{ + Name: "ws", + Usage: "Enable the WS-RPC server", + Value: c.cliConfig.JsonRPC.Ws.Enabled, + }) + f.Uint64Flag(&flagset.Uint64Flag{ + Name: "ws.port", + Usage: "WS-RPC server listening port", + Value: c.cliConfig.JsonRPC.Ws.Port, + }) + f.StringFlag(&flagset.StringFlag{ + Name: "ws.rpcprefix", + Usage: "HTTP path prefix on which JSON-RPC is served. Use '/' to serve on all paths.", + Value: c.cliConfig.JsonRPC.Ws.Prefix, + }) + // graphql options + f.BoolFlag(&flagset.BoolFlag{ + Name: "graphql", + Usage: "Enable GraphQL on the HTTP-RPC server. Note that GraphQL can only be started if an HTTP server is started as well.", + Value: c.cliConfig.JsonRPC.Graphql.Enabled, + }) + + // p2p options + f.StringFlag(&flagset.StringFlag{ + Name: "bind", + Usage: "Network binding address", + Value: c.cliConfig.P2P.Bind, + }) + f.Uint64Flag(&flagset.Uint64Flag{ + Name: "port", + Usage: "Network listening port", + Value: c.cliConfig.P2P.Port, + }) + f.SliceStringFlag(&flagset.SliceStringFlag{ + Name: "bootnodes", + Usage: "Comma separated enode URLs for P2P discovery bootstrap", + Value: c.cliConfig.P2P.Discovery.Bootnodes, + }) + f.Uint64Flag(&flagset.Uint64Flag{ + Name: "maxpeers", + Usage: "Maximum number of network peers (network disabled if set to 0)", + Value: c.cliConfig.P2P.MaxPeers, + }) + f.Uint64Flag(&flagset.Uint64Flag{ + Name: "maxpendpeers", + Usage: "Maximum number of pending connection attempts (defaults used if set to 0)", + Value: c.cliConfig.P2P.MaxPendPeers, + }) + f.StringFlag(&flagset.StringFlag{ + Name: "nat", + Usage: "NAT port mapping mechanism (any|none|upnp|pmp|extip:)", + Value: c.cliConfig.P2P.NAT, + }) + f.BoolFlag(&flagset.BoolFlag{ + Name: "nodiscover", + Usage: "Disables the peer discovery mechanism (manual peer addition)", + Value: c.cliConfig.P2P.NoDiscover, + }) + f.BoolFlag(&flagset.BoolFlag{ + Name: "v5disc", + Usage: "Enables the experimental RLPx V5 (Topic Discovery) mechanism", + Value: c.cliConfig.P2P.Discovery.V5Enabled, + }) + + // metrics + f.BoolFlag(&flagset.BoolFlag{ + Name: "metrics", + Usage: "Enable metrics collection and reporting", + Value: c.cliConfig.Metrics.Enabled, + }) + f.BoolFlag(&flagset.BoolFlag{ + Name: "metrics.expensive", + Usage: "Enable expensive metrics collection and reporting", + Value: c.cliConfig.Metrics.Expensive, + }) + f.BoolFlag(&flagset.BoolFlag{ + Name: "metrics.influxdb", + Usage: "Enable metrics export/push to an external InfluxDB database (v1)", + Value: c.cliConfig.Metrics.InfluxDB.V1Enabled, + }) + f.StringFlag(&flagset.StringFlag{ + Name: "metrics.influxdb.endpoint", + Usage: "InfluxDB API endpoint to report metrics to", + Value: c.cliConfig.Metrics.InfluxDB.Endpoint, + }) + f.StringFlag(&flagset.StringFlag{ + Name: "metrics.influxdb.database", + Usage: "InfluxDB database name to push reported metrics to", + Value: c.cliConfig.Metrics.InfluxDB.Database, + }) + f.StringFlag(&flagset.StringFlag{ + Name: "metrics.influxdb.username", + Usage: "Username to authorize access to the database", + Value: c.cliConfig.Metrics.InfluxDB.Username, + }) + f.StringFlag(&flagset.StringFlag{ + Name: "metrics.influxdb.password", + Usage: "Password to authorize access to the database", + Value: c.cliConfig.Metrics.InfluxDB.Password, + }) + f.MapStringFlag(&flagset.MapStringFlag{ + Name: "metrics.influxdb.tags", + Usage: "Comma-separated InfluxDB tags (key/values) attached to all measurements", + Value: c.cliConfig.Metrics.InfluxDB.Tags, + }) + // influx db v2 + f.BoolFlag(&flagset.BoolFlag{ + Name: "metrics.influxdbv2", + Usage: "Enable metrics export/push to an external InfluxDB v2 database", + Value: c.cliConfig.Metrics.InfluxDB.V2Enabled, + }) + f.StringFlag(&flagset.StringFlag{ + Name: "metrics.influxdb.token", + Usage: "Token to authorize access to the database (v2 only)", + Value: c.cliConfig.Metrics.InfluxDB.Token, + }) + f.StringFlag(&flagset.StringFlag{ + Name: "metrics.influxdb.bucket", + Usage: "InfluxDB bucket name to push reported metrics to (v2 only)", + Value: c.cliConfig.Metrics.InfluxDB.Bucket, + }) + f.StringFlag(&flagset.StringFlag{ + Name: "metrics.influxdb.organization", + Usage: "InfluxDB organization name (v2 only)", + Value: c.cliConfig.Metrics.InfluxDB.Organization, }) return f From a9b5e5dfb8d2154b8daf9fe1ec063108ed88a02f Mon Sep 17 00:00:00 2001 From: Ferran Borreguero Date: Wed, 13 Oct 2021 12:01:35 +0200 Subject: [PATCH 08/51] Update README --- README.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/README.md b/README.md index 9e64b4d717..4f035d0113 100644 --- a/README.md +++ b/README.md @@ -17,6 +17,12 @@ or, to build the full suite of utilities: make bor-all ``` +Build the beta client: + +```shell +go build -o bor-beta command/*.go +``` + ## License The go-ethereum library (i.e. all code outside of the `cmd` directory) is licensed under the From 7225eec0f6a26228505a05521e126b7c03ad3c62 Mon Sep 17 00:00:00 2001 From: ferranbt Date: Sun, 17 Oct 2021 16:26:25 +0000 Subject: [PATCH 09/51] Finish flags --- .gitignore | 1 + command/flagset/flagset.go | 55 +++++------ command/flagset/flagset_test.go | 60 ++++++++++++ command/server/command.go | 95 +++++++++++++++++-- command/server/config.go | 160 ++++++++++++++++---------------- command/server/config_test.go | 90 ++++++++++++++++++ command/server/flags.go | 55 ++++++++--- go.mod | 1 + go.sum | 3 +- 9 files changed, 389 insertions(+), 131 deletions(-) create mode 100644 command/flagset/flagset_test.go create mode 100644 command/server/config_test.go diff --git a/.gitignore b/.gitignore index 1ee8b83022..15ccd00ed0 100644 --- a/.gitignore +++ b/.gitignore @@ -47,3 +47,4 @@ profile.cov /dashboard/assets/package-lock.json **/yarn-error.log +./test diff --git a/command/flagset/flagset.go b/command/flagset/flagset.go index c272bfbcad..c3c8704999 100644 --- a/command/flagset/flagset.go +++ b/command/flagset/flagset.go @@ -78,10 +78,9 @@ func (f *Flagset) StringFlag(b *StringFlag) { } type IntFlag struct { - Name string - Usage string - Default int - Value *int + Name string + Usage string + Value *int } func (f *Flagset) IntFlag(i *IntFlag) { @@ -89,14 +88,13 @@ func (f *Flagset) IntFlag(i *IntFlag) { Name: i.Name, Usage: i.Usage, }) - f.set.IntVar(i.Value, i.Name, i.Default, i.Usage) + f.set.IntVar(i.Value, i.Name, *i.Value, i.Usage) } type Uint64Flag struct { - Name string - Usage string - Default uint64 - Value *uint64 + Name string + Usage string + Value *uint64 } func (f *Flagset) Uint64Flag(i *Uint64Flag) { @@ -104,17 +102,19 @@ func (f *Flagset) Uint64Flag(i *Uint64Flag) { Name: i.Name, Usage: i.Usage, }) - f.set.Uint64Var(i.Value, i.Name, i.Default, i.Usage) + f.set.Uint64Var(i.Value, i.Name, *i.Value, i.Usage) } type BigIntFlag struct { - Name string - Usage string - Default *big.Int - Value *big.Int + Name string + Usage string + Value *big.Int } func (b *BigIntFlag) String() string { + if b.Value == nil { + return "" + } return b.Value.String() } @@ -145,15 +145,18 @@ func (f *Flagset) BigIntFlag(b *BigIntFlag) { type SliceStringFlag struct { Name string Usage string - Value []string + Value *[]string } func (i *SliceStringFlag) String() string { - return strings.Join(i.Value, ",") + if i.Value == nil { + return "" + } + return strings.Join(*i.Value, ",") } func (i *SliceStringFlag) Set(value string) error { - i.Value = append(i.Value, value) + *i.Value = append(*i.Value, strings.Split(value, ",")...) return nil } @@ -171,25 +174,12 @@ type DurationFlag struct { Value *time.Duration } -func (d *DurationFlag) String() string { - return d.Value.String() -} - -func (d *DurationFlag) Set(value string) error { - v, err := time.ParseDuration(value) - if err != nil { - return err - } - d.Value = &v - return nil -} - func (f *Flagset) DurationFlag(d *DurationFlag) { f.addFlag(&FlagVar{ Name: d.Name, Usage: d.Usage, }) - f.set.Var(d, d.Name, d.Usage) + f.set.DurationVar(d.Value, d.Name, *d.Value, "") } type MapStringFlag struct { @@ -199,6 +189,9 @@ type MapStringFlag struct { } func (m *MapStringFlag) String() string { + if m.Value == nil { + return "" + } ls := []string{} for k, v := range *m.Value { ls = append(ls, k+"="+v) diff --git a/command/flagset/flagset_test.go b/command/flagset/flagset_test.go new file mode 100644 index 0000000000..2f046c3248 --- /dev/null +++ b/command/flagset/flagset_test.go @@ -0,0 +1,60 @@ +package flagset + +import ( + "testing" + "time" + + "github.com/stretchr/testify/assert" +) + +func TestFlagsetBool(t *testing.T) { + f := NewFlagSet("") + + value := false + f.BoolFlag(&BoolFlag{ + Name: "flag", + Value: &value, + }) + + assert.NoError(t, f.Parse([]string{"--flag", "true"})) + assert.Equal(t, value, true) +} + +func TestFlagsetSliceString(t *testing.T) { + f := NewFlagSet("") + + value := []string{} + f.SliceStringFlag(&SliceStringFlag{ + Name: "flag", + Value: &value, + }) + + assert.NoError(t, f.Parse([]string{"--flag", "a,b", "--flag", "c"})) + assert.Equal(t, value, []string{"a", "b", "c"}) +} + +func TestFlagsetDuration(t *testing.T) { + f := NewFlagSet("") + + value := time.Duration(0) + f.DurationFlag(&DurationFlag{ + Name: "flag", + Value: &value, + }) + + assert.NoError(t, f.Parse([]string{"--flag", "1m"})) + assert.Equal(t, value, 1*time.Minute) +} + +func TestFlagsetMapString(t *testing.T) { + f := NewFlagSet("") + + value := map[string]string{} + f.MapStringFlag(&MapStringFlag{ + Name: "flag", + Value: &value, + }) + + assert.NoError(t, f.Parse([]string{"--flag", "a=b,c=d"})) + assert.Equal(t, value, map[string]string{"a": "b", "c": "d"}) +} diff --git a/command/server/command.go b/command/server/command.go index 56b1e1f105..9e3df6a5fc 100644 --- a/command/server/command.go +++ b/command/server/command.go @@ -3,13 +3,16 @@ package server import ( "fmt" "io" + "io/ioutil" "os" "os/signal" "strings" "syscall" "time" + "github.com/ethereum/go-ethereum/accounts" "github.com/ethereum/go-ethereum/accounts/keystore" + "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/eth" "github.com/ethereum/go-ethereum/eth/tracers" "github.com/ethereum/go-ethereum/ethstats" @@ -30,6 +33,9 @@ type Command struct { // cli configuration cliConfig *Config + // final configuration + config *Config + configFile string // bor node @@ -74,6 +80,7 @@ func (c *Command) Run(args []string) int { c.UI.Error(err.Error()) return 1 } + c.config = config // start the logger setupLogger(*config.LogLevel) @@ -121,7 +128,7 @@ func (c *Command) Run(args []string) int { } // register ethash service - if config.EthStats != nil { + if *config.EthStats != "" { if err := ethstats.New(stack, backend.APIBackend, backend.Engine(), *config.EthStats); err != nil { c.UI.Error(err.Error()) return 1 @@ -129,13 +136,23 @@ func (c *Command) Run(args []string) int { } // setup account manager (only keystore) + var borKeystore *keystore.KeyStore { keydir := stack.KeyStoreDir() n, p := keystore.StandardScryptN, keystore.StandardScryptP - if *config.UseLightweightKDF { + if *config.Accounts.UseLightweightKDF { n, p = keystore.LightScryptN, keystore.LightScryptP } - stack.AccountManager().AddBackend(keystore.NewKeyStore(keydir, n, p)) + borKeystore = keystore.NewKeyStore(keydir, n, p) + stack.AccountManager().AddBackend(borKeystore) + } + + // unlock accounts if necessary + if len(config.Accounts.Unlock) != 0 { + if err := c.unlockAccounts(borKeystore); err != nil { + c.UI.Error(fmt.Sprintf("failed to unlock: %v", err)) + return 1 + } } // sealing (if enabled) @@ -159,6 +176,49 @@ func (c *Command) Run(args []string) int { return c.handleSignals() } +func (c *Command) unlockAccounts(borKeystore *keystore.KeyStore) error { + // If insecure account unlocking is not allowed if node's APIs are exposed to external. + if !c.node.Config().InsecureUnlockAllowed && c.node.Config().ExtRPCEnabled() { + return fmt.Errorf("account unlock with HTTP access is forbidden") + } + + // read passwords from file if possible + passwords := []string{} + if *c.config.Accounts.PasswordFile != "" { + var err error + if passwords, err = readMultilineFile(*c.config.Accounts.PasswordFile); err != nil { + return err + } + } + decodePassword := func(addr common.Address, index int) (string, error) { + if len(passwords) > 0 { + if index < len(passwords) { + return passwords[index], nil + } + return passwords[len(passwords)-1], nil + } + // ask for the password + return c.UI.AskSecret(fmt.Sprintf("Please give a password to unlock '%s'", addr.String())) + } + + for index, addrStr := range c.config.Accounts.Unlock { + if !common.IsHexAddress(addrStr) { + return fmt.Errorf("unlock value '%s' is not an address", addrStr) + } + acct := accounts.Account{Address: common.HexToAddress(addrStr)} + + password, err := decodePassword(acct.Address, index) + if err != nil { + return err + } + if err := borKeystore.Unlock(acct, password); err != nil { + return err + } + log.Info("Unlocked account", "address", acct.Address.Hex()) + } + return nil +} + func (c *Command) setupMetrics(config *MetricsConfig) error { metrics.Enabled = *config.Enabled metrics.EnabledExpensive = *config.Expensive @@ -208,17 +268,19 @@ func (c *Command) handleSignals() int { gracefulCh := make(chan struct{}) go func() { c.node.Close() + c.node.Wait() close(gracefulCh) }() - select { - case <-signalCh: - return 1 - case <-time.After(5 * time.Second): - return 1 - case <-gracefulCh: - return 0 + for i := 10; i > 0; i-- { + select { + case <-signalCh: + log.Warn("Already shutting down, interrupt more force stop.", "times", i-1) + case <-gracefulCh: + return 0 + } } + return 1 } func setupLogger(logLevel string) { @@ -239,3 +301,16 @@ func setupLogger(logLevel string) { } log.Root().SetHandler(glogger) } + +func readMultilineFile(path string) ([]string, error) { + text, err := ioutil.ReadFile(path) + if err != nil { + return nil, err + } + lines := strings.Split(string(text), "\n") + // Sanitise DOS line endings. + for i := range lines { + lines[i] = strings.TrimRight(lines[i], "\r") + } + return lines, nil +} diff --git a/command/server/config.go b/command/server/config.go index 5236d20c72..20cfaa5cfb 100644 --- a/command/server/config.go +++ b/command/server/config.go @@ -1,13 +1,13 @@ package server import ( - "crypto/ecdsa" "fmt" "io/ioutil" "math" "math/big" "os" "path/filepath" + "runtime" "strconv" "time" @@ -16,7 +16,6 @@ import ( "github.com/ethereum/go-ethereum/command/server/chains" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/fdlimit" - "github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/eth/downloader" "github.com/ethereum/go-ethereum/eth/ethconfig" "github.com/ethereum/go-ethereum/eth/gasprice" @@ -27,6 +26,7 @@ import ( "github.com/ethereum/go-ethereum/p2p/nat" "github.com/ethereum/go-ethereum/params" "github.com/imdario/mergo" + "github.com/mitchellh/go-homedir" gopsutil "github.com/shirou/gopsutil/mem" ) @@ -57,25 +57,25 @@ func durPtr(d time.Duration) *time.Duration { type Config struct { chain *chains.Chain - Chain *string - Debug *bool - Whitelist *map[string]string - UseLightweightKDF *bool - LogLevel *string - DataDir *string - P2P *P2PConfig - SyncMode *string - GcMode *string - Snapshot *bool - EthStats *string - Heimdall *HeimdallConfig - TxPool *TxPoolConfig - Sealer *SealerConfig - JsonRPC *JsonRPCConfig - Gpo *GpoConfig - Ethstats *string - Metrics *MetricsConfig - Cache *CacheConfig + Chain *string + Debug *bool + Whitelist *map[string]string + LogLevel *string + DataDir *string + P2P *P2PConfig + SyncMode *string + GcMode *string + Snapshot *bool + EthStats *string + Heimdall *HeimdallConfig + TxPool *TxPoolConfig + Sealer *SealerConfig + JsonRPC *JsonRPCConfig + Gpo *GpoConfig + Ethstats *string + Metrics *MetricsConfig + Cache *CacheConfig + Accounts *AccountsConfig } type P2PConfig struct { @@ -132,7 +132,6 @@ type JsonRPCConfig struct { Modules []string VHost []string Cors []string - Bind *string GasCap *uint64 TxFeeCap *float64 @@ -146,6 +145,7 @@ type APIConfig struct { Enabled *bool Port *uint64 Prefix *string + Host *string } type GpoConfig struct { @@ -187,14 +187,20 @@ type CacheConfig struct { TxLookupLimit *uint64 } +type AccountsConfig struct { + Unlock []string + PasswordFile *string + AllowInsecureUnlock *bool + UseLightweightKDF *bool +} + func DefaultConfig() *Config { return &Config{ - Chain: stringPtr("mainnet"), - Debug: boolPtr(false), - UseLightweightKDF: boolPtr(false), - Whitelist: mapStrPtr(map[string]string{}), - LogLevel: stringPtr("INFO"), - DataDir: stringPtr(node.DefaultDataDir()), + Chain: stringPtr("mainnet"), + Debug: boolPtr(false), + Whitelist: mapStrPtr(map[string]string{}), + LogLevel: stringPtr("INFO"), + DataDir: stringPtr(defaultDataDir()), P2P: &P2PConfig{ MaxPeers: uint64Ptr(30), MaxPendPeers: uint64Ptr(50), @@ -235,6 +241,7 @@ func DefaultConfig() *Config { }, Sealer: &SealerConfig{ Enabled: boolPtr(false), + Etherbase: stringPtr(""), GasCeil: uint64Ptr(8000000), GasPrice: big.NewInt(params.GWei), ExtraData: stringPtr(""), @@ -247,6 +254,7 @@ func DefaultConfig() *Config { }, JsonRPC: &JsonRPCConfig{ IPCDisable: boolPtr(false), + IPCPath: stringPtr(""), Modules: []string{"web3", "net"}, Cors: []string{"*"}, VHost: []string{"*"}, @@ -256,11 +264,13 @@ func DefaultConfig() *Config { Enabled: boolPtr(false), Port: uint64Ptr(8545), Prefix: stringPtr(""), + Host: stringPtr("localhost"), }, Ws: &APIConfig{ Enabled: boolPtr(false), Port: uint64Ptr(8546), Prefix: stringPtr(""), + Host: stringPtr("localhost"), }, Graphql: &APIConfig{ Enabled: boolPtr(false), @@ -295,6 +305,12 @@ func DefaultConfig() *Config { Preimages: boolPtr(false), TxLookupLimit: uint64Ptr(2350000), }, + Accounts: &AccountsConfig{ + Unlock: []string{}, + PasswordFile: stringPtr(""), + AllowInsecureUnlock: boolPtr(false), + UseLightweightKDF: boolPtr(false), + }, } } @@ -321,11 +337,6 @@ func (c *Config) loadChain() error { c.chain = chain // preload some default values that depend on the chain file - - // the genesis files defines default bootnodes - if c.P2P.Discovery.Bootnodes == nil { - c.P2P.Discovery.Bootnodes = c.chain.Bootnodes - } if c.P2P.Discovery.DNS == nil { c.P2P.Discovery.DNS = c.chain.DNS } @@ -368,11 +379,11 @@ func (c *Config) buildEth() (*ethconfig.Config, error) { n.Miner.GasCeil = *c.Sealer.GasCeil n.Miner.ExtraData = []byte(*c.Sealer.ExtraData) - if etherbase := c.Sealer.Etherbase; etherbase != nil { - if !common.IsHexAddress(*etherbase) { - return nil, fmt.Errorf("etherbase is not an address: %s", *etherbase) + if etherbase := *c.Sealer.Etherbase; etherbase != "" { + if !common.IsHexAddress(etherbase) { + return nil, fmt.Errorf("etherbase is not an address: %s", etherbase) } - n.Miner.Etherbase = common.HexToAddress(*etherbase) + n.Miner.Etherbase = common.HexToAddress(etherbase) } } @@ -495,17 +506,18 @@ func (c *Config) buildNode() (*node.Config, error) { ipcPath := "" if !*c.JsonRPC.IPCDisable { ipcPath = clientIdentifier + ".ipc" - if c.JsonRPC.IPCPath != nil { + if *c.JsonRPC.IPCPath != "" { ipcPath = *c.JsonRPC.IPCPath } } cfg := &node.Config{ - Name: clientIdentifier, - DataDir: *c.DataDir, - UseLightweightKDF: *c.UseLightweightKDF, - Version: params.VersionWithCommit(gitCommit, gitDate), - IPCPath: ipcPath, + Name: clientIdentifier, + DataDir: *c.DataDir, + UseLightweightKDF: *c.Accounts.UseLightweightKDF, + InsecureUnlockAllowed: *c.Accounts.AllowInsecureUnlock, + Version: params.VersionWithCommit(gitCommit, gitDate), + IPCPath: ipcPath, P2P: p2p.Config{ MaxPeers: int(*c.P2P.MaxPeers), MaxPendingPeers: int(*c.P2P.MaxPendPeers), @@ -526,11 +538,11 @@ func (c *Config) buildNode() (*node.Config, error) { // enable jsonrpc endpoints { if *c.JsonRPC.Http.Enabled { - cfg.HTTPHost = *c.JsonRPC.Bind + cfg.HTTPHost = *c.JsonRPC.Http.Host cfg.HTTPPort = int(*c.JsonRPC.Http.Port) } if *c.JsonRPC.Ws.Enabled { - cfg.WSHost = *c.JsonRPC.Bind + cfg.WSHost = *c.JsonRPC.Ws.Host cfg.WSPort = int(*c.JsonRPC.Ws.Port) } } @@ -541,15 +553,13 @@ func (c *Config) buildNode() (*node.Config, error) { } cfg.P2P.NAT = natif - // setup private key for DevP2P if not found - devP2PPrivKey, err := readDevP2PKey(*c.DataDir) - if err != nil { - return nil, err - } - cfg.P2P.PrivateKey = devP2PPrivKey - // Discovery - if cfg.P2P.BootstrapNodes, err = parseBootnodes(c.P2P.Discovery.Bootnodes); err != nil { + // if no bootnodes are defined, use the ones from the chain file. + bootnodes := c.P2P.Discovery.Bootnodes + if len(bootnodes) == 0 { + bootnodes = c.chain.Bootnodes + } + if cfg.P2P.BootstrapNodes, err = parseBootnodes(bootnodes); err != nil { return nil, err } if cfg.P2P.BootstrapNodesV5, err = parseBootnodes(c.P2P.Discovery.BootnodesV5); err != nil { @@ -572,8 +582,8 @@ func (c *Config) buildNode() (*node.Config, error) { func (c *Config) Merge(cc ...*Config) error { for _, elem := range cc { - if err := mergo.Merge(&c, elem); err != nil { - return err + if err := mergo.Merge(c, elem, mergo.WithOverride, mergo.WithAppendSlice); err != nil { + return fmt.Errorf("failed to merge configurations: %v", err) } } return nil @@ -605,30 +615,24 @@ func parseBootnodes(urls []string) ([]*enode.Node, error) { return dst, nil } -const devP2PKeyPath = "devp2p.key" - -func readDevP2PKey(dataDir string) (*ecdsa.PrivateKey, error) { - path := filepath.Join(dataDir, devP2PKeyPath) - _, err := os.Stat(path) - if err != nil && !os.IsNotExist(err) { - return nil, fmt.Errorf("failed to stat (%s): %v", path, err) +func defaultDataDir() string { + // Try to place the data folder in the user's home dir + home, _ := homedir.Dir() + if home == "" { + // we cannot guess a stable location + return "" } - - if os.IsNotExist(err) { - priv, err := crypto.GenerateKey() - if err != nil { - return nil, err + switch runtime.GOOS { + case "darwin": + return filepath.Join(home, "Library", "Bor") + case "windows": + appdata := os.Getenv("LOCALAPPDATA") + if appdata == "" { + // Windows XP and below don't have LocalAppData. + panic("environment variable LocalAppData is undefined") } - if err := crypto.SaveECDSA(path, priv); err != nil { - return nil, err - } - return priv, nil + return filepath.Join(appdata, "Bor") + default: + return filepath.Join(home, ".bor") } - - // exists - priv, err := crypto.LoadECDSA(path) - if err != nil { - return nil, err - } - return priv, nil } diff --git a/command/server/config_test.go b/command/server/config_test.go new file mode 100644 index 0000000000..386757a602 --- /dev/null +++ b/command/server/config_test.go @@ -0,0 +1,90 @@ +package server + +import ( + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestConfigDefault(t *testing.T) { + // the default config should work out of the box + config := DefaultConfig() + assert.NoError(t, config.loadChain()) + + _, err := config.buildNode() + assert.NoError(t, err) + + _, err = config.buildEth() + assert.NoError(t, err) +} + +func TestConfigMerge(t *testing.T) { + c0 := &Config{ + Chain: stringPtr("0"), + Debug: boolPtr(false), + Whitelist: mapStrPtr(map[string]string{ + "a": "b", + }), + P2P: &P2PConfig{ + Discovery: &P2PDiscovery{ + StaticNodes: []string{ + "a", + }, + }, + }, + } + c1 := &Config{ + Chain: stringPtr("1"), + Whitelist: mapStrPtr(map[string]string{ + "b": "c", + }), + P2P: &P2PConfig{ + Discovery: &P2PDiscovery{ + StaticNodes: []string{ + "b", + }, + }, + }, + } + expected := &Config{ + Chain: stringPtr("1"), + Debug: boolPtr(false), + Whitelist: mapStrPtr(map[string]string{ + "a": "b", + "b": "c", + }), + P2P: &P2PConfig{ + Discovery: &P2PDiscovery{ + StaticNodes: []string{ + "a", + "b", + }, + }, + }, + } + assert.NoError(t, c0.Merge(c1)) + assert.Equal(t, c0, expected) +} + +var dummyEnodeAddr = "enode://0cb82b395094ee4a2915e9714894627de9ed8498fb881cec6db7c65e8b9a5bd7f2f25cc84e71e89d0947e51c76e85d0847de848c7782b13c0255247a6758178c@44.232.55.71:30303" + +func TestConfigBootnodesDefault(t *testing.T) { + t.Run("EmptyBootnodes", func(t *testing.T) { + // if no bootnodes are specific, we use the ones from the genesis chain + config := DefaultConfig() + assert.NoError(t, config.loadChain()) + + cfg, err := config.buildNode() + assert.NoError(t, err) + assert.NotEmpty(t, cfg.P2P.BootstrapNodes) + }) + t.Run("NotEmptyBootnodes", func(t *testing.T) { + // if bootnodes specific, DO NOT load the genesis bootnodes + config := DefaultConfig() + config.P2P.Discovery.Bootnodes = []string{dummyEnodeAddr} + + cfg, err := config.buildNode() + assert.NoError(t, err) + assert.Len(t, cfg.P2P.BootstrapNodes, 1) + }) +} diff --git a/command/server/flags.go b/command/server/flags.go index b0359d525f..8513e19061 100644 --- a/command/server/flags.go +++ b/command/server/flags.go @@ -44,11 +44,6 @@ func (c *Command) Flags() *flagset.Flagset { Usage: `Blockchain garbage collection mode ("full", "archive")`, Value: c.cliConfig.GcMode, }) - f.BoolFlag(&flagset.BoolFlag{ - Name: "lightkdf", - Usage: "Reduce key-derivation RAM & CPU usage at some expense of KDF strength", - Value: c.cliConfig.UseLightweightKDF, - }) f.MapStringFlag(&flagset.MapStringFlag{ Name: "whitelist", Usage: "Comma separated block number-to-hash mappings to enforce (=)", @@ -76,7 +71,7 @@ func (c *Command) Flags() *flagset.Flagset { f.SliceStringFlag(&flagset.SliceStringFlag{ Name: "txpool.locals", Usage: "Comma separated accounts to treat as locals (no flush, priority inclusion)", - Value: c.cliConfig.TxPool.Locals, + Value: &c.cliConfig.TxPool.Locals, }) f.BoolFlag(&flagset.BoolFlag{ Name: "txpool.nolocals", @@ -259,21 +254,32 @@ func (c *Command) Flags() *flagset.Flagset { Value: c.cliConfig.JsonRPC.IPCPath, }) f.SliceStringFlag(&flagset.SliceStringFlag{ - Name: "rpc.corsdomain", + Name: "jsonrpc.corsdomain", Usage: "Comma separated list of domains from which to accept cross origin requests (browser enforced)", - Value: c.cliConfig.JsonRPC.Cors, + Value: &c.cliConfig.JsonRPC.Cors, }) f.SliceStringFlag(&flagset.SliceStringFlag{ - Name: "rpc.vhosts", + Name: "jsonrpc.vhosts", Usage: "Comma separated list of virtual hostnames from which to accept requests (server enforced). Accepts '*' wildcard.", - Value: c.cliConfig.JsonRPC.VHost, + Value: &c.cliConfig.JsonRPC.VHost, }) + f.SliceStringFlag(&flagset.SliceStringFlag{ + Name: "jsonrpc.modules", + Usage: "API's offered over the HTTP-RPC interface", + Value: &c.cliConfig.JsonRPC.Modules, + }) + // http options f.BoolFlag(&flagset.BoolFlag{ Name: "http", Usage: "Enable the HTTP-RPC server", Value: c.cliConfig.JsonRPC.Http.Enabled, }) + f.StringFlag(&flagset.StringFlag{ + Name: "http.addr", + Usage: "HTTP-RPC server listening interface", + Value: c.cliConfig.JsonRPC.Http.Host, + }) f.Uint64Flag(&flagset.Uint64Flag{ Name: "http.port", Usage: "HTTP-RPC server listening port", @@ -290,6 +296,11 @@ func (c *Command) Flags() *flagset.Flagset { Usage: "Enable the WS-RPC server", Value: c.cliConfig.JsonRPC.Ws.Enabled, }) + f.StringFlag(&flagset.StringFlag{ + Name: "ws.addr", + Usage: "WS-RPC server listening interface", + Value: c.cliConfig.JsonRPC.Ws.Host, + }) f.Uint64Flag(&flagset.Uint64Flag{ Name: "ws.port", Usage: "WS-RPC server listening port", @@ -321,7 +332,7 @@ func (c *Command) Flags() *flagset.Flagset { f.SliceStringFlag(&flagset.SliceStringFlag{ Name: "bootnodes", Usage: "Comma separated enode URLs for P2P discovery bootstrap", - Value: c.cliConfig.P2P.Discovery.Bootnodes, + Value: &c.cliConfig.P2P.Discovery.Bootnodes, }) f.Uint64Flag(&flagset.Uint64Flag{ Name: "maxpeers", @@ -412,5 +423,27 @@ func (c *Command) Flags() *flagset.Flagset { Value: c.cliConfig.Metrics.InfluxDB.Organization, }) + // account + f.SliceStringFlag(&flagset.SliceStringFlag{ + Name: "unlock", + Usage: "Comma separated list of accounts to unlock", + Value: &c.cliConfig.Accounts.Unlock, + }) + f.StringFlag(&flagset.StringFlag{ + Name: "password", + Usage: "Password file to use for non-interactive password input", + Value: c.cliConfig.Accounts.PasswordFile, + }) + f.BoolFlag(&flagset.BoolFlag{ + Name: "allow-insecure-unlock", + Usage: "Allow insecure account unlocking when account-related RPCs are exposed by http", + Value: c.cliConfig.Accounts.AllowInsecureUnlock, + }) + f.BoolFlag(&flagset.BoolFlag{ + Name: "lightkdf", + Usage: "Reduce key-derivation RAM & CPU usage at some expense of KDF strength", + Value: c.cliConfig.Accounts.UseLightweightKDF, + }) + return f } diff --git a/go.mod b/go.mod index dfc33fc8c7..b5f8b0032d 100644 --- a/go.mod +++ b/go.mod @@ -51,6 +51,7 @@ require ( github.com/mattn/go-colorable v0.1.8 github.com/mattn/go-isatty v0.0.12 github.com/mitchellh/cli v1.1.2 + github.com/mitchellh/go-homedir v1.1.0 github.com/naoina/go-stringutil v0.1.0 // indirect github.com/naoina/toml v0.1.2-0.20170918210437-9fafd6967416 github.com/olekukonko/tablewriter v0.0.5 diff --git a/go.sum b/go.sum index 79bb6c6cf6..a4b737eacd 100644 --- a/go.sum +++ b/go.sum @@ -33,7 +33,6 @@ github.com/Azure/go-autorest/autorest/date v0.2.0 h1:yW+Zlqf26583pE43KhfnhFcdmSW github.com/Azure/go-autorest/autorest/date v0.2.0/go.mod h1:vcORJHLJEh643/Ioh9+vPmf1Ij9AEBM5FuBIXLmIy0g= github.com/Azure/go-autorest/autorest/mocks v0.1.0/go.mod h1:OTyCOPRA2IgIlWxVYxBee2F5Gr4kF2zd2J5cFRaIDN0= github.com/Azure/go-autorest/autorest/mocks v0.2.0/go.mod h1:OTyCOPRA2IgIlWxVYxBee2F5Gr4kF2zd2J5cFRaIDN0= -github.com/Azure/go-autorest/autorest/mocks v0.3.0 h1:qJumjCaCudz+OcqE9/XtEPfvtOjOmKaui4EOpFI6zZc= github.com/Azure/go-autorest/autorest/mocks v0.3.0/go.mod h1:a8FDP3DYzQ4RYfVAxAN3SVSiiO77gL2j2ronKKP0syM= github.com/Azure/go-autorest/logger v0.1.0 h1:ruG4BSDXONFRrZZJ2GUXDiUyVpayPmb1GnWeHDdaNKY= github.com/Azure/go-autorest/logger v0.1.0/go.mod h1:oExouG+K6PryycPJfVSxi/koC6LSNgds39diKLz7Vrc= @@ -331,6 +330,8 @@ github.com/mitchellh/cli v1.1.2 h1:PvH+lL2B7IQ101xQL63Of8yFS2y+aDlsFcsqNc+u/Kw= github.com/mitchellh/cli v1.1.2/go.mod h1:6iaV0fGdElS6dPBx0EApTxHrcWvmJphyh2n8YBLPPZ4= github.com/mitchellh/copystructure v1.0.0 h1:Laisrj+bAB6b/yJwB5Bt3ITZhGJdqmxquMKeZ+mmkFQ= github.com/mitchellh/copystructure v1.0.0/go.mod h1:SNtv71yrdKgLRyLFxmLdkAbkKEFWgYaq1OVrnRcwhnw= +github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y= +github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= github.com/mitchellh/reflectwalk v1.0.0 h1:9D+8oIskB4VJBN5SFlmc27fSlIBZaov1Wpk/IfikLNY= github.com/mitchellh/reflectwalk v1.0.0/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= From 2b7bd156cfd9434a9df1e503f57b9c66a7c4c4a7 Mon Sep 17 00:00:00 2001 From: ferranbt Date: Mon, 18 Oct 2021 07:31:48 +0000 Subject: [PATCH 10/51] Add heimdall flag --- command/server/command.go | 2 ++ command/server/config.go | 2 ++ 2 files changed, 4 insertions(+) diff --git a/command/server/command.go b/command/server/command.go index 9e3df6a5fc..77bf246ca1 100644 --- a/command/server/command.go +++ b/command/server/command.go @@ -116,6 +116,8 @@ func (c *Command) Run(args []string) int { return 1 } + log.Info("Heimdall setup", "url", ethCfg.HeimdallURL) + // debug tracing is enabled by default stack.RegisterAPIs(tracers.APIs(backend.APIBackend)) diff --git a/command/server/config.go b/command/server/config.go index 20cfaa5cfb..5f833ff157 100644 --- a/command/server/config.go +++ b/command/server/config.go @@ -358,6 +358,8 @@ func (c *Config) buildEth() (*ethconfig.Config, error) { n := ethconfig.Defaults n.NetworkId = c.chain.NetworkId n.Genesis = c.chain.Genesis + n.HeimdallURL = *c.Heimdall.URL + n.WithoutHeimdall = *c.Heimdall.Without // txpool options { From 3d3f986c5b9a271ee6dda70bd3ab95e50d6c5f6f Mon Sep 17 00:00:00 2001 From: Ferran Borreguero Date: Wed, 20 Oct 2021 11:45:44 +0200 Subject: [PATCH 11/51] Remove pointers in config field --- command/flagset/flagset.go | 36 +-- command/server/command.go | 30 +-- command/server/config.go | 418 ++++++++++++++++------------------ command/server/config_test.go | 31 ++- command/server/flags.go | 146 ++++++------ 5 files changed, 325 insertions(+), 336 deletions(-) diff --git a/command/flagset/flagset.go b/command/flagset/flagset.go index c3c8704999..4388dd03fc 100644 --- a/command/flagset/flagset.go +++ b/command/flagset/flagset.go @@ -78,9 +78,10 @@ func (f *Flagset) StringFlag(b *StringFlag) { } type IntFlag struct { - Name string - Usage string - Value *int + Name string + Usage string + Value *int + Default int } func (f *Flagset) IntFlag(i *IntFlag) { @@ -88,13 +89,14 @@ func (f *Flagset) IntFlag(i *IntFlag) { Name: i.Name, Usage: i.Usage, }) - f.set.IntVar(i.Value, i.Name, *i.Value, i.Usage) + f.set.IntVar(i.Value, i.Name, i.Default, i.Usage) } type Uint64Flag struct { - Name string - Usage string - Value *uint64 + Name string + Usage string + Value *uint64 + Default uint64 } func (f *Flagset) Uint64Flag(i *Uint64Flag) { @@ -102,7 +104,7 @@ func (f *Flagset) Uint64Flag(i *Uint64Flag) { Name: i.Name, Usage: i.Usage, }) - f.set.Uint64Var(i.Value, i.Name, *i.Value, i.Usage) + f.set.Uint64Var(i.Value, i.Name, i.Default, i.Usage) } type BigIntFlag struct { @@ -169,9 +171,10 @@ func (f *Flagset) SliceStringFlag(s *SliceStringFlag) { } type DurationFlag struct { - Name string - Usage string - Value *time.Duration + Name string + Usage string + Value *time.Duration + Default time.Duration } func (f *Flagset) DurationFlag(d *DurationFlag) { @@ -179,7 +182,7 @@ func (f *Flagset) DurationFlag(d *DurationFlag) { Name: d.Name, Usage: d.Usage, }) - f.set.DurationVar(d.Value, d.Name, *d.Value, "") + f.set.DurationVar(d.Value, d.Name, d.Default, "") } type MapStringFlag struct { @@ -224,9 +227,10 @@ func (f *Flagset) MapStringFlag(m *MapStringFlag) { } type Float64Flag struct { - Name string - Usage string - Value *float64 + Name string + Usage string + Value *float64 + Default float64 } func (f *Flagset) Float64Flag(i *Float64Flag) { @@ -234,5 +238,5 @@ func (f *Flagset) Float64Flag(i *Float64Flag) { Name: i.Name, Usage: i.Usage, }) - f.set.Float64Var(i.Value, i.Name, *i.Value, "") + f.set.Float64Var(i.Value, i.Name, i.Default, "") } diff --git a/command/server/command.go b/command/server/command.go index 77bf246ca1..10beeda385 100644 --- a/command/server/command.go +++ b/command/server/command.go @@ -83,7 +83,7 @@ func (c *Command) Run(args []string) int { c.config = config // start the logger - setupLogger(*config.LogLevel) + setupLogger(config.LogLevel) // load the chain genesis if err := config.loadChain(); err != nil { @@ -122,7 +122,7 @@ func (c *Command) Run(args []string) int { stack.RegisterAPIs(tracers.APIs(backend.APIBackend)) // graphql is started from another place - if *config.JsonRPC.Graphql.Enabled { + if config.JsonRPC.Graphql.Enabled { if err := graphql.New(stack, backend.APIBackend, config.JsonRPC.Cors, config.JsonRPC.Modules); err != nil { c.UI.Error(fmt.Sprintf("Failed to register the GraphQL service: %v", err)) return 1 @@ -130,8 +130,8 @@ func (c *Command) Run(args []string) int { } // register ethash service - if *config.EthStats != "" { - if err := ethstats.New(stack, backend.APIBackend, backend.Engine(), *config.EthStats); err != nil { + if config.EthStats != "" { + if err := ethstats.New(stack, backend.APIBackend, backend.Engine(), config.EthStats); err != nil { c.UI.Error(err.Error()) return 1 } @@ -142,7 +142,7 @@ func (c *Command) Run(args []string) int { { keydir := stack.KeyStoreDir() n, p := keystore.StandardScryptN, keystore.StandardScryptP - if *config.Accounts.UseLightweightKDF { + if config.Accounts.UseLightweightKDF { n, p = keystore.LightScryptN, keystore.LightScryptP } borKeystore = keystore.NewKeyStore(keydir, n, p) @@ -158,7 +158,7 @@ func (c *Command) Run(args []string) int { } // sealing (if enabled) - if *config.Sealer.Enabled { + if config.Sealer.Enabled { if err := backend.StartMining(1); err != nil { c.UI.Error(err.Error()) return 1 @@ -186,9 +186,9 @@ func (c *Command) unlockAccounts(borKeystore *keystore.KeyStore) error { // read passwords from file if possible passwords := []string{} - if *c.config.Accounts.PasswordFile != "" { + if c.config.Accounts.PasswordFile != "" { var err error - if passwords, err = readMultilineFile(*c.config.Accounts.PasswordFile); err != nil { + if passwords, err = readMultilineFile(c.config.Accounts.PasswordFile); err != nil { return err } } @@ -222,8 +222,8 @@ func (c *Command) unlockAccounts(borKeystore *keystore.KeyStore) error { } func (c *Command) setupMetrics(config *MetricsConfig) error { - metrics.Enabled = *config.Enabled - metrics.EnabledExpensive = *config.Expensive + metrics.Enabled = config.Enabled + metrics.EnabledExpensive = config.Expensive if !metrics.Enabled { // metrics are disabled, do not set up any sink @@ -233,22 +233,22 @@ func (c *Command) setupMetrics(config *MetricsConfig) error { log.Info("Enabling metrics collection") // influxdb - if v1Enabled, v2Enabled := (*config.InfluxDB.V1Enabled), (*config.InfluxDB.V2Enabled); v1Enabled || v2Enabled { + if v1Enabled, v2Enabled := (config.InfluxDB.V1Enabled), (config.InfluxDB.V2Enabled); v1Enabled || v2Enabled { if v1Enabled && v2Enabled { return fmt.Errorf("both influx v1 and influx v2 cannot be enabled") } cfg := config.InfluxDB - tags := *cfg.Tags - endpoint := *cfg.Endpoint + tags := cfg.Tags + endpoint := cfg.Endpoint if v1Enabled { log.Info("Enabling metrics export to InfluxDB (v1)") - go influxdb.InfluxDBWithTags(metrics.DefaultRegistry, 10*time.Second, endpoint, *cfg.Database, *cfg.Username, *cfg.Password, "geth.", tags) + go influxdb.InfluxDBWithTags(metrics.DefaultRegistry, 10*time.Second, endpoint, cfg.Database, cfg.Username, cfg.Password, "geth.", tags) } if v2Enabled { log.Info("Enabling metrics export to InfluxDB (v2)") - go influxdb.InfluxDBV2WithTags(metrics.DefaultRegistry, 10*time.Second, endpoint, *cfg.Token, *cfg.Bucket, *cfg.Organization, "geth.", tags) + go influxdb.InfluxDBV2WithTags(metrics.DefaultRegistry, 10*time.Second, endpoint, cfg.Token, cfg.Bucket, cfg.Organization, "geth.", tags) } } diff --git a/command/server/config.go b/command/server/config.go index 5f833ff157..27daab7dae 100644 --- a/command/server/config.go +++ b/command/server/config.go @@ -30,66 +30,42 @@ import ( gopsutil "github.com/shirou/gopsutil/mem" ) -func mapStrPtr(m map[string]string) *map[string]string { - return &m -} - -func stringPtr(s string) *string { - return &s -} - -func float64Ptr(f float64) *float64 { - return &f -} - -func uint64Ptr(i uint64) *uint64 { - return &i -} - -func boolPtr(b bool) *bool { - return &b -} - -func durPtr(d time.Duration) *time.Duration { - return &d -} - type Config struct { chain *chains.Chain - Chain *string - Debug *bool - Whitelist *map[string]string - LogLevel *string - DataDir *string + Chain string + Debug bool + Whitelist map[string]string + LogLevel string + DataDir string P2P *P2PConfig - SyncMode *string - GcMode *string - Snapshot *bool - EthStats *string + SyncMode string + GcMode string + Snapshot bool + EthStats string Heimdall *HeimdallConfig TxPool *TxPoolConfig Sealer *SealerConfig JsonRPC *JsonRPCConfig Gpo *GpoConfig - Ethstats *string + Ethstats string Metrics *MetricsConfig Cache *CacheConfig Accounts *AccountsConfig } type P2PConfig struct { - MaxPeers *uint64 - MaxPendPeers *uint64 - Bind *string - Port *uint64 - NoDiscover *bool - NAT *string + MaxPeers uint64 + MaxPendPeers uint64 + Bind string + Port uint64 + NoDiscover bool + NAT string Discovery *P2PDiscovery } type P2PDiscovery struct { - V5Enabled *bool + V5Enabled bool Bootnodes []string BootnodesV4 []string BootnodesV5 []string @@ -99,42 +75,42 @@ type P2PDiscovery struct { } type HeimdallConfig struct { - URL *string - Without *bool + URL string + Without bool } type TxPoolConfig struct { Locals []string - NoLocals *bool - Journal *string - Rejournal *time.Duration - PriceLimit *uint64 - PriceBump *uint64 - AccountSlots *uint64 - GlobalSlots *uint64 - AccountQueue *uint64 - GlobalQueue *uint64 - LifeTime *time.Duration + NoLocals bool + Journal string + Rejournal time.Duration + PriceLimit uint64 + PriceBump uint64 + AccountSlots uint64 + GlobalSlots uint64 + AccountQueue uint64 + GlobalQueue uint64 + LifeTime time.Duration } type SealerConfig struct { - Enabled *bool - Etherbase *string - ExtraData *string - GasCeil *uint64 + Enabled bool + Etherbase string + ExtraData string + GasCeil uint64 GasPrice *big.Int } type JsonRPCConfig struct { - IPCDisable *bool - IPCPath *string + IPCDisable bool + IPCPath string Modules []string VHost []string Cors []string - GasCap *uint64 - TxFeeCap *float64 + GasCap uint64 + TxFeeCap float64 Http *APIConfig Ws *APIConfig @@ -142,74 +118,74 @@ type JsonRPCConfig struct { } type APIConfig struct { - Enabled *bool - Port *uint64 - Prefix *string - Host *string + Enabled bool + Port uint64 + Prefix string + Host string } type GpoConfig struct { - Blocks *uint64 - Percentile *uint64 + Blocks uint64 + Percentile uint64 MaxPrice *big.Int IgnorePrice *big.Int } type MetricsConfig struct { - Enabled *bool - Expensive *bool + Enabled bool + Expensive bool InfluxDB *InfluxDBConfig } type InfluxDBConfig struct { - V1Enabled *bool - Endpoint *string - Database *string - Username *string - Password *string - Tags *map[string]string - V2Enabled *bool - Token *string - Bucket *string - Organization *string + V1Enabled bool + Endpoint string + Database string + Username string + Password string + Tags map[string]string + V2Enabled bool + Token string + Bucket string + Organization string } type CacheConfig struct { - Cache *uint64 - PercGc *uint64 - PercSnapshot *uint64 - PercDatabase *uint64 - PercTrie *uint64 - Journal *string - Rejournal *time.Duration - NoPrefetch *bool - Preimages *bool - TxLookupLimit *uint64 + Cache uint64 + PercGc uint64 + PercSnapshot uint64 + PercDatabase uint64 + PercTrie uint64 + Journal string + Rejournal time.Duration + NoPrefetch bool + Preimages bool + TxLookupLimit uint64 } type AccountsConfig struct { Unlock []string - PasswordFile *string - AllowInsecureUnlock *bool - UseLightweightKDF *bool + PasswordFile string + AllowInsecureUnlock bool + UseLightweightKDF bool } func DefaultConfig() *Config { return &Config{ - Chain: stringPtr("mainnet"), - Debug: boolPtr(false), - Whitelist: mapStrPtr(map[string]string{}), - LogLevel: stringPtr("INFO"), - DataDir: stringPtr(defaultDataDir()), + Chain: "mainnet", + Debug: false, + Whitelist: map[string]string{}, + LogLevel: "INFO", + DataDir: defaultDataDir(), P2P: &P2PConfig{ - MaxPeers: uint64Ptr(30), - MaxPendPeers: uint64Ptr(50), - Bind: stringPtr("0.0.0.0"), - Port: uint64Ptr(30303), - NoDiscover: boolPtr(false), - NAT: stringPtr("any"), + MaxPeers: 30, + MaxPendPeers: 50, + Bind: "0.0.0.0", + Port: 30303, + NoDiscover: false, + NAT: "any", Discovery: &P2PDiscovery{ - V5Enabled: boolPtr(false), + V5Enabled: false, Bootnodes: []string{}, BootnodesV4: []string{}, BootnodesV5: []string{}, @@ -219,97 +195,97 @@ func DefaultConfig() *Config { }, }, Heimdall: &HeimdallConfig{ - URL: stringPtr("http://localhost:1317"), - Without: boolPtr(false), + URL: "http://localhost:1317", + Without: false, }, - SyncMode: stringPtr("fast"), - GcMode: stringPtr("full"), - Snapshot: boolPtr(true), - EthStats: stringPtr(""), + SyncMode: "fast", + GcMode: "full", + Snapshot: true, + EthStats: "", TxPool: &TxPoolConfig{ Locals: []string{}, - NoLocals: boolPtr(false), - Journal: stringPtr(""), - Rejournal: durPtr(1 * time.Hour), - PriceLimit: uint64Ptr(1), - PriceBump: uint64Ptr(10), - AccountSlots: uint64Ptr(16), - GlobalSlots: uint64Ptr(4096), - AccountQueue: uint64Ptr(64), - GlobalQueue: uint64Ptr(1024), - LifeTime: durPtr(3 * time.Hour), + NoLocals: false, + Journal: "", + Rejournal: time.Duration(1 * time.Hour), + PriceLimit: 1, + PriceBump: 10, + AccountSlots: 16, + GlobalSlots: 4096, + AccountQueue: 64, + GlobalQueue: 1024, + LifeTime: time.Duration(3 * time.Hour), }, Sealer: &SealerConfig{ - Enabled: boolPtr(false), - Etherbase: stringPtr(""), - GasCeil: uint64Ptr(8000000), + Enabled: false, + Etherbase: "", + GasCeil: 8000000, GasPrice: big.NewInt(params.GWei), - ExtraData: stringPtr(""), + ExtraData: "", }, Gpo: &GpoConfig{ - Blocks: uint64Ptr(20), - Percentile: uint64Ptr(60), + Blocks: 20, + Percentile: 60, MaxPrice: gasprice.DefaultMaxPrice, IgnorePrice: gasprice.DefaultIgnorePrice, }, JsonRPC: &JsonRPCConfig{ - IPCDisable: boolPtr(false), - IPCPath: stringPtr(""), + IPCDisable: false, + IPCPath: "", Modules: []string{"web3", "net"}, Cors: []string{"*"}, VHost: []string{"*"}, - GasCap: uint64Ptr(ethconfig.Defaults.RPCGasCap), - TxFeeCap: float64Ptr(ethconfig.Defaults.RPCTxFeeCap), + GasCap: ethconfig.Defaults.RPCGasCap, + TxFeeCap: ethconfig.Defaults.RPCTxFeeCap, Http: &APIConfig{ - Enabled: boolPtr(false), - Port: uint64Ptr(8545), - Prefix: stringPtr(""), - Host: stringPtr("localhost"), + Enabled: false, + Port: 8545, + Prefix: "", + Host: "localhost", }, Ws: &APIConfig{ - Enabled: boolPtr(false), - Port: uint64Ptr(8546), - Prefix: stringPtr(""), - Host: stringPtr("localhost"), + Enabled: false, + Port: 8546, + Prefix: "", + Host: "localhost", }, Graphql: &APIConfig{ - Enabled: boolPtr(false), + Enabled: false, }, }, - Ethstats: stringPtr(""), + Ethstats: "", Metrics: &MetricsConfig{ - Enabled: boolPtr(false), - Expensive: boolPtr(false), + Enabled: false, + Expensive: false, InfluxDB: &InfluxDBConfig{ - V1Enabled: boolPtr(false), - Endpoint: stringPtr(""), - Database: stringPtr(""), - Username: stringPtr(""), - Password: stringPtr(""), - Tags: mapStrPtr(map[string]string{}), - V2Enabled: boolPtr(false), - Token: stringPtr(""), - Bucket: stringPtr(""), - Organization: stringPtr(""), + V1Enabled: false, + Endpoint: "", + Database: "", + Username: "", + Password: "", + Tags: map[string]string{}, + V2Enabled: false, + Token: "", + Bucket: "", + Organization: "", }, }, Cache: &CacheConfig{ - Cache: uint64Ptr(1024), - PercDatabase: uint64Ptr(50), - PercTrie: uint64Ptr(15), - PercGc: uint64Ptr(25), - PercSnapshot: uint64Ptr(10), - Journal: stringPtr("triecache"), - Rejournal: durPtr(60 * time.Minute), - NoPrefetch: boolPtr(false), - Preimages: boolPtr(false), - TxLookupLimit: uint64Ptr(2350000), + Cache: 1024, + PercDatabase: 50, + PercTrie: 15, + PercGc: 25, + PercSnapshot: 10, + Journal: "triecache", + Rejournal: 60 * time.Minute, + NoPrefetch: false, + Preimages: false, + TxLookupLimit: 2350000, }, Accounts: &AccountsConfig{ Unlock: []string{}, - PasswordFile: stringPtr(""), - AllowInsecureUnlock: boolPtr(false), - UseLightweightKDF: boolPtr(false), + PasswordFile: "", + AllowInsecureUnlock: false, + UseLightweightKDF: false, }, } } @@ -330,9 +306,9 @@ func readConfigFile(path string) (*Config, error) { } func (c *Config) loadChain() error { - chain, ok := chains.GetChain(*c.Chain) + chain, ok := chains.GetChain(c.Chain) if !ok { - return fmt.Errorf("chain '%s' not found", *c.Chain) + return fmt.Errorf("chain '%s' not found", c.Chain) } c.chain = chain @@ -342,10 +318,10 @@ func (c *Config) loadChain() error { } // depending on the chain we have different cache values - if *c.Chain != "mainnet" { - c.Cache.Cache = uint64Ptr(4096) + if c.Chain != "mainnet" { + c.Cache.Cache = 4096 } else { - c.Cache.Cache = uint64Ptr(1024) + c.Cache.Cache = 1024 } return nil } @@ -358,30 +334,30 @@ func (c *Config) buildEth() (*ethconfig.Config, error) { n := ethconfig.Defaults n.NetworkId = c.chain.NetworkId n.Genesis = c.chain.Genesis - n.HeimdallURL = *c.Heimdall.URL - n.WithoutHeimdall = *c.Heimdall.Without + n.HeimdallURL = c.Heimdall.URL + n.WithoutHeimdall = c.Heimdall.Without // txpool options { - n.TxPool.NoLocals = *c.TxPool.NoLocals - n.TxPool.Journal = *c.TxPool.Journal - n.TxPool.Rejournal = *c.TxPool.Rejournal - n.TxPool.PriceLimit = *c.TxPool.PriceLimit - n.TxPool.PriceBump = *c.TxPool.PriceBump - n.TxPool.AccountSlots = *c.TxPool.AccountSlots - n.TxPool.GlobalSlots = *c.TxPool.GlobalSlots - n.TxPool.AccountQueue = *c.TxPool.AccountQueue - n.TxPool.GlobalQueue = *c.TxPool.GlobalQueue - n.TxPool.Lifetime = *c.TxPool.LifeTime + n.TxPool.NoLocals = c.TxPool.NoLocals + n.TxPool.Journal = c.TxPool.Journal + n.TxPool.Rejournal = c.TxPool.Rejournal + n.TxPool.PriceLimit = c.TxPool.PriceLimit + n.TxPool.PriceBump = c.TxPool.PriceBump + n.TxPool.AccountSlots = c.TxPool.AccountSlots + n.TxPool.GlobalSlots = c.TxPool.GlobalSlots + n.TxPool.AccountQueue = c.TxPool.AccountQueue + n.TxPool.GlobalQueue = c.TxPool.GlobalQueue + n.TxPool.Lifetime = c.TxPool.LifeTime } // miner options { n.Miner.GasPrice = c.Sealer.GasPrice - n.Miner.GasCeil = *c.Sealer.GasCeil - n.Miner.ExtraData = []byte(*c.Sealer.ExtraData) + n.Miner.GasCeil = c.Sealer.GasCeil + n.Miner.ExtraData = []byte(c.Sealer.ExtraData) - if etherbase := *c.Sealer.Etherbase; etherbase != "" { + if etherbase := c.Sealer.Etherbase; etherbase != "" { if !common.IsHexAddress(etherbase) { return nil, fmt.Errorf("etherbase is not an address: %s", etherbase) } @@ -398,7 +374,7 @@ func (c *Config) buildEth() (*ethconfig.Config, error) { // whitelist { n.Whitelist = map[uint64]common.Hash{} - for k, v := range *c.Whitelist { + for k, v := range c.Whitelist { number, err := strconv.ParseUint(k, 0, 64) if err != nil { return nil, fmt.Errorf("invalid whitelist block number %s: %v", k, err) @@ -413,9 +389,9 @@ func (c *Config) buildEth() (*ethconfig.Config, error) { // cache { - cache := *c.Cache.Cache - calcPerc := func(val *uint64) int { - return int(cache * (*val) / 100) + cache := c.Cache.Cache + calcPerc := func(val uint64) int { + return int(cache * (val) / 100) } // Cap the cache allowance @@ -437,28 +413,28 @@ func (c *Config) buildEth() (*ethconfig.Config, error) { log.Debug("Sanitizing Go's GC trigger", "percent", int(gogc)) godebug.SetGCPercent(int(gogc)) - n.TrieCleanCacheJournal = *c.Cache.Journal - n.TrieCleanCacheRejournal = *c.Cache.Rejournal + n.TrieCleanCacheJournal = c.Cache.Journal + n.TrieCleanCacheRejournal = c.Cache.Rejournal n.DatabaseCache = calcPerc(c.Cache.PercDatabase) n.SnapshotCache = calcPerc(c.Cache.PercSnapshot) n.TrieCleanCache = calcPerc(c.Cache.PercTrie) n.TrieDirtyCache = calcPerc(c.Cache.PercGc) - n.NoPrefetch = *c.Cache.NoPrefetch - n.Preimages = *c.Cache.Preimages - n.TxLookupLimit = *c.Cache.TxLookupLimit + n.NoPrefetch = c.Cache.NoPrefetch + n.Preimages = c.Cache.Preimages + n.TxLookupLimit = c.Cache.TxLookupLimit } - n.RPCGasCap = *c.JsonRPC.GasCap + n.RPCGasCap = c.JsonRPC.GasCap if n.RPCGasCap != 0 { log.Info("Set global gas cap", "cap", n.RPCGasCap) } else { log.Info("Global gas cap disabled") } - n.RPCTxFeeCap = *c.JsonRPC.TxFeeCap + n.RPCTxFeeCap = c.JsonRPC.TxFeeCap // sync mode. It can either be "fast", "full" or "snap". We disable // for now the "light" mode. - switch *c.SyncMode { + switch c.SyncMode { case "fast": n.SyncMode = downloader.FastSync case "full": @@ -466,11 +442,11 @@ func (c *Config) buildEth() (*ethconfig.Config, error) { case "snap": n.SyncMode = downloader.SnapSync default: - return nil, fmt.Errorf("sync mode '%s' not found", *c.SyncMode) + return nil, fmt.Errorf("sync mode '%s' not found", c.SyncMode) } // archive mode. It can either be "archive" or "full". - switch *c.GcMode { + switch c.GcMode { case "full": n.NoPruning = false case "archive": @@ -480,11 +456,11 @@ func (c *Config) buildEth() (*ethconfig.Config, error) { log.Info("Enabling recording of key preimages since archive mode is used") } default: - return nil, fmt.Errorf("gcmode '%s' not found", *c.GcMode) + return nil, fmt.Errorf("gcmode '%s' not found", c.GcMode) } // snapshot disable check - if *c.Snapshot { + if c.Snapshot { if n.SyncMode == downloader.SnapSync { log.Info("Snap sync requested, enabling --snapshot") } else { @@ -506,50 +482,50 @@ var ( func (c *Config) buildNode() (*node.Config, error) { ipcPath := "" - if !*c.JsonRPC.IPCDisable { + if !c.JsonRPC.IPCDisable { ipcPath = clientIdentifier + ".ipc" - if *c.JsonRPC.IPCPath != "" { - ipcPath = *c.JsonRPC.IPCPath + if c.JsonRPC.IPCPath != "" { + ipcPath = c.JsonRPC.IPCPath } } cfg := &node.Config{ Name: clientIdentifier, - DataDir: *c.DataDir, - UseLightweightKDF: *c.Accounts.UseLightweightKDF, - InsecureUnlockAllowed: *c.Accounts.AllowInsecureUnlock, + DataDir: c.DataDir, + UseLightweightKDF: c.Accounts.UseLightweightKDF, + InsecureUnlockAllowed: c.Accounts.AllowInsecureUnlock, Version: params.VersionWithCommit(gitCommit, gitDate), IPCPath: ipcPath, P2P: p2p.Config{ - MaxPeers: int(*c.P2P.MaxPeers), - MaxPendingPeers: int(*c.P2P.MaxPendPeers), - ListenAddr: *c.P2P.Bind + ":" + strconv.Itoa(int(*c.P2P.Port)), - DiscoveryV5: *c.P2P.Discovery.V5Enabled, + MaxPeers: int(c.P2P.MaxPeers), + MaxPendingPeers: int(c.P2P.MaxPendPeers), + ListenAddr: c.P2P.Bind + ":" + strconv.Itoa(int(c.P2P.Port)), + DiscoveryV5: c.P2P.Discovery.V5Enabled, }, HTTPModules: c.JsonRPC.Modules, HTTPCors: c.JsonRPC.Cors, HTTPVirtualHosts: c.JsonRPC.VHost, - HTTPPathPrefix: *c.JsonRPC.Http.Prefix, + HTTPPathPrefix: c.JsonRPC.Http.Prefix, WSModules: c.JsonRPC.Modules, WSOrigins: c.JsonRPC.Cors, - WSPathPrefix: *c.JsonRPC.Ws.Prefix, + WSPathPrefix: c.JsonRPC.Ws.Prefix, GraphQLCors: c.JsonRPC.Cors, GraphQLVirtualHosts: c.JsonRPC.VHost, } // enable jsonrpc endpoints { - if *c.JsonRPC.Http.Enabled { - cfg.HTTPHost = *c.JsonRPC.Http.Host - cfg.HTTPPort = int(*c.JsonRPC.Http.Port) + if c.JsonRPC.Http.Enabled { + cfg.HTTPHost = c.JsonRPC.Http.Host + cfg.HTTPPort = int(c.JsonRPC.Http.Port) } - if *c.JsonRPC.Ws.Enabled { - cfg.WSHost = *c.JsonRPC.Ws.Host - cfg.WSPort = int(*c.JsonRPC.Ws.Port) + if c.JsonRPC.Ws.Enabled { + cfg.WSHost = c.JsonRPC.Ws.Host + cfg.WSPort = int(c.JsonRPC.Ws.Port) } } - natif, err := nat.Parse(*c.P2P.NAT) + natif, err := nat.Parse(c.P2P.NAT) if err != nil { return nil, fmt.Errorf("wrong 'nat' flag: %v", err) } @@ -574,7 +550,7 @@ func (c *Config) buildNode() (*node.Config, error) { return nil, err } - if *c.P2P.NoDiscover { + if c.P2P.NoDiscover { // Disable networking, for now, we will not even allow incomming connections cfg.P2P.MaxPeers = 0 cfg.P2P.NoDiscovery = true diff --git a/command/server/config_test.go b/command/server/config_test.go index 386757a602..e11b02766c 100644 --- a/command/server/config_test.go +++ b/command/server/config_test.go @@ -2,6 +2,7 @@ package server import ( "testing" + "time" "github.com/stretchr/testify/assert" ) @@ -20,11 +21,14 @@ func TestConfigDefault(t *testing.T) { func TestConfigMerge(t *testing.T) { c0 := &Config{ - Chain: stringPtr("0"), - Debug: boolPtr(false), - Whitelist: mapStrPtr(map[string]string{ + Chain: "0", + Debug: true, + Whitelist: map[string]string{ "a": "b", - }), + }, + TxPool: &TxPoolConfig{ + LifeTime: 5 * time.Second, + }, P2P: &P2PConfig{ Discovery: &P2PDiscovery{ StaticNodes: []string{ @@ -34,11 +38,12 @@ func TestConfigMerge(t *testing.T) { }, } c1 := &Config{ - Chain: stringPtr("1"), - Whitelist: mapStrPtr(map[string]string{ + Chain: "1", + Whitelist: map[string]string{ "b": "c", - }), + }, P2P: &P2PConfig{ + MaxPeers: 10, Discovery: &P2PDiscovery{ StaticNodes: []string{ "b", @@ -47,13 +52,17 @@ func TestConfigMerge(t *testing.T) { }, } expected := &Config{ - Chain: stringPtr("1"), - Debug: boolPtr(false), - Whitelist: mapStrPtr(map[string]string{ + Chain: "1", + Debug: true, + Whitelist: map[string]string{ "a": "b", "b": "c", - }), + }, + TxPool: &TxPoolConfig{ + LifeTime: 5 * time.Second, + }, P2P: &P2PConfig{ + MaxPeers: 10, Discovery: &P2PDiscovery{ StaticNodes: []string{ "a", diff --git a/command/server/flags.go b/command/server/flags.go index 8513e19061..d9bd017468 100644 --- a/command/server/flags.go +++ b/command/server/flags.go @@ -12,22 +12,22 @@ func (c *Command) Flags() *flagset.Flagset { f.BoolFlag(&flagset.BoolFlag{ Name: "debug", Usage: "Path of the file to apply", - Value: c.cliConfig.Debug, + Value: &c.cliConfig.Debug, }) f.StringFlag(&flagset.StringFlag{ Name: "chain", Usage: "Name of the chain to sync", - Value: c.cliConfig.Chain, + Value: &c.cliConfig.Chain, }) f.StringFlag(&flagset.StringFlag{ Name: "log-level", Usage: "Set log level for the server", - Value: c.cliConfig.LogLevel, + Value: &c.cliConfig.LogLevel, }) f.StringFlag(&flagset.StringFlag{ Name: "datadir", Usage: "Path of the data directory to store information", - Value: c.cliConfig.DataDir, + Value: &c.cliConfig.DataDir, }) f.StringFlag(&flagset.StringFlag{ Name: "config", @@ -37,34 +37,34 @@ func (c *Command) Flags() *flagset.Flagset { f.StringFlag(&flagset.StringFlag{ Name: "syncmode", Usage: `Blockchain sync mode ("fast", "full", "snap" or "light")`, - Value: c.cliConfig.SyncMode, + Value: &c.cliConfig.SyncMode, }) f.StringFlag(&flagset.StringFlag{ Name: "gcmode", Usage: `Blockchain garbage collection mode ("full", "archive")`, - Value: c.cliConfig.GcMode, + Value: &c.cliConfig.GcMode, }) f.MapStringFlag(&flagset.MapStringFlag{ Name: "whitelist", Usage: "Comma separated block number-to-hash mappings to enforce (=)", - Value: c.cliConfig.Whitelist, + Value: &c.cliConfig.Whitelist, }) f.BoolFlag(&flagset.BoolFlag{ Name: "snapshot", Usage: `Enables snapshot-database mode (default = enable)`, - Value: c.cliConfig.Snapshot, + Value: &c.cliConfig.Snapshot, }) // heimdall f.StringFlag(&flagset.StringFlag{ Name: "bor.heimdall", Usage: "URL of Heimdall service", - Value: c.cliConfig.Heimdall.URL, + Value: &c.cliConfig.Heimdall.URL, }) f.BoolFlag(&flagset.BoolFlag{ Name: "bor.withoutheimdall", Usage: "Run without Heimdall service (for testing purpose)", - Value: c.cliConfig.Heimdall.Without, + Value: &c.cliConfig.Heimdall.Without, }) // txpool options @@ -76,74 +76,74 @@ func (c *Command) Flags() *flagset.Flagset { f.BoolFlag(&flagset.BoolFlag{ Name: "txpool.nolocals", Usage: "Disables price exemptions for locally submitted transactions", - Value: c.cliConfig.TxPool.NoLocals, + Value: &c.cliConfig.TxPool.NoLocals, }) f.StringFlag(&flagset.StringFlag{ Name: "txpool.journal", Usage: "Disk journal for local transaction to survive node restarts", - Value: c.cliConfig.TxPool.Journal, + Value: &c.cliConfig.TxPool.Journal, }) f.DurationFlag(&flagset.DurationFlag{ Name: "txpool.rejournal", Usage: "Time interval to regenerate the local transaction journal", - Value: c.cliConfig.TxPool.Rejournal, + Value: &c.cliConfig.TxPool.Rejournal, }) f.Uint64Flag(&flagset.Uint64Flag{ Name: "txpool.pricelimit", Usage: "Minimum gas price limit to enforce for acceptance into the pool", - Value: c.cliConfig.TxPool.PriceLimit, + Value: &c.cliConfig.TxPool.PriceLimit, }) f.Uint64Flag(&flagset.Uint64Flag{ Name: "txpool.pricebump", Usage: "Price bump percentage to replace an already existing transaction", - Value: c.cliConfig.TxPool.PriceBump, + Value: &c.cliConfig.TxPool.PriceBump, }) f.Uint64Flag(&flagset.Uint64Flag{ Name: "txpool.accountslots", Usage: "Minimum number of executable transaction slots guaranteed per account", - Value: c.cliConfig.TxPool.AccountSlots, + Value: &c.cliConfig.TxPool.AccountSlots, }) f.Uint64Flag(&flagset.Uint64Flag{ Name: "txpool.globalslots", Usage: "Maximum number of executable transaction slots for all accounts", - Value: c.cliConfig.TxPool.GlobalSlots, + Value: &c.cliConfig.TxPool.GlobalSlots, }) f.Uint64Flag(&flagset.Uint64Flag{ Name: "txpool.accountqueue", Usage: "Maximum number of non-executable transaction slots permitted per account", - Value: c.cliConfig.TxPool.AccountQueue, + Value: &c.cliConfig.TxPool.AccountQueue, }) f.Uint64Flag(&flagset.Uint64Flag{ Name: "txpool.globalqueue", Usage: "Maximum number of non-executable transaction slots for all accounts", - Value: c.cliConfig.TxPool.GlobalQueue, + Value: &c.cliConfig.TxPool.GlobalQueue, }) f.DurationFlag(&flagset.DurationFlag{ Name: "txpool.lifetime", Usage: "Maximum amount of time non-executable transaction are queued", - Value: c.cliConfig.TxPool.LifeTime, + Value: &c.cliConfig.TxPool.LifeTime, }) // sealer options f.BoolFlag(&flagset.BoolFlag{ Name: "mine", Usage: "Enable mining", - Value: c.cliConfig.Sealer.Enabled, + Value: &c.cliConfig.Sealer.Enabled, }) f.StringFlag(&flagset.StringFlag{ Name: "miner.etherbase", Usage: "Public address for block mining rewards (default = first account)", - Value: c.cliConfig.Sealer.Etherbase, + Value: &c.cliConfig.Sealer.Etherbase, }) f.StringFlag(&flagset.StringFlag{ Name: "miner.extradata", Usage: "Block extra data set by the miner (default = client version)", - Value: c.cliConfig.Sealer.ExtraData, + Value: &c.cliConfig.Sealer.ExtraData, }) f.Uint64Flag(&flagset.Uint64Flag{ Name: "miner.gaslimit", Usage: "Target gas ceiling for mined blocks", - Value: c.cliConfig.Sealer.GasCeil, + Value: &c.cliConfig.Sealer.GasCeil, }) f.BigIntFlag(&flagset.BigIntFlag{ Name: "miner.gasprice", @@ -155,19 +155,19 @@ func (c *Command) Flags() *flagset.Flagset { f.StringFlag(&flagset.StringFlag{ Name: "ethstats", Usage: "Reporting URL of a ethstats service (nodename:secret@host:port)", - Value: c.cliConfig.Ethstats, + Value: &c.cliConfig.Ethstats, }) // gas price oracle f.Uint64Flag(&flagset.Uint64Flag{ Name: "gpo.blocks", Usage: "Number of recent blocks to check for gas prices", - Value: c.cliConfig.Gpo.Blocks, + Value: &c.cliConfig.Gpo.Blocks, }) f.Uint64Flag(&flagset.Uint64Flag{ Name: "gpo.percentile", Usage: "Suggested gas price is the given percentile of a set of recent transaction gas prices", - Value: c.cliConfig.Gpo.Percentile, + Value: &c.cliConfig.Gpo.Percentile, }) f.BigIntFlag(&flagset.BigIntFlag{ Name: "gpo.maxprice", @@ -184,74 +184,74 @@ func (c *Command) Flags() *flagset.Flagset { f.Uint64Flag(&flagset.Uint64Flag{ Name: "cache", Usage: "Megabytes of memory allocated to internal caching (default = 4096 mainnet full node)", - Value: c.cliConfig.Cache.Cache, + Value: &c.cliConfig.Cache.Cache, }) f.Uint64Flag(&flagset.Uint64Flag{ Name: "cache.database", Usage: "Percentage of cache memory allowance to use for database io", - Value: c.cliConfig.Cache.PercDatabase, + Value: &c.cliConfig.Cache.PercDatabase, }) f.Uint64Flag(&flagset.Uint64Flag{ Name: "cache.trie", Usage: "Percentage of cache memory allowance to use for trie caching (default = 15% full mode, 30% archive mode)", - Value: c.cliConfig.Cache.PercTrie, + Value: &c.cliConfig.Cache.PercTrie, }) f.StringFlag(&flagset.StringFlag{ Name: "cache.trie.journal", Usage: "Disk journal directory for trie cache to survive node restarts", - Value: c.cliConfig.Cache.Journal, + Value: &c.cliConfig.Cache.Journal, }) f.DurationFlag(&flagset.DurationFlag{ Name: "cache.trie.rejournal", Usage: "Time interval to regenerate the trie cache journal", - Value: c.cliConfig.Cache.Rejournal, + Value: &c.cliConfig.Cache.Rejournal, }) f.Uint64Flag(&flagset.Uint64Flag{ Name: "cache.gc", Usage: "Percentage of cache memory allowance to use for trie pruning (default = 25% full mode, 0% archive mode)", - Value: c.cliConfig.Cache.PercGc, + Value: &c.cliConfig.Cache.PercGc, }) f.Uint64Flag(&flagset.Uint64Flag{ Name: "cache.snapshot", Usage: "Percentage of cache memory allowance to use for snapshot caching (default = 10% full mode, 20% archive mode)", - Value: c.cliConfig.Cache.PercSnapshot, + Value: &c.cliConfig.Cache.PercSnapshot, }) f.BoolFlag(&flagset.BoolFlag{ Name: "cache.noprefetch", Usage: "Disable heuristic state prefetch during block import (less CPU and disk IO, more time waiting for data)", - Value: c.cliConfig.Cache.NoPrefetch, + Value: &c.cliConfig.Cache.NoPrefetch, }) f.BoolFlag(&flagset.BoolFlag{ Name: "cache.preimages", Usage: "Enable recording the SHA3/keccak preimages of trie keys", - Value: c.cliConfig.Cache.Preimages, + Value: &c.cliConfig.Cache.Preimages, }) f.Uint64Flag(&flagset.Uint64Flag{ Name: "txlookuplimit", Usage: "Number of recent blocks to maintain transactions index for (default = about one year, 0 = entire chain)", - Value: c.cliConfig.Cache.TxLookupLimit, + Value: &c.cliConfig.Cache.TxLookupLimit, }) // rpc options f.Uint64Flag(&flagset.Uint64Flag{ Name: "rpc.gascap", Usage: "Sets a cap on gas that can be used in eth_call/estimateGas (0=infinite)", - Value: c.cliConfig.JsonRPC.GasCap, + Value: &c.cliConfig.JsonRPC.GasCap, }) f.Float64Flag(&flagset.Float64Flag{ Name: "rpc.txfeecap", Usage: "Sets a cap on transaction fee (in ether) that can be sent via the RPC APIs (0 = no cap)", - Value: c.cliConfig.JsonRPC.TxFeeCap, + Value: &c.cliConfig.JsonRPC.TxFeeCap, }) f.BoolFlag(&flagset.BoolFlag{ Name: "ipcdisable", Usage: "Disable the IPC-RPC server", - Value: c.cliConfig.JsonRPC.IPCDisable, + Value: &c.cliConfig.JsonRPC.IPCDisable, }) f.StringFlag(&flagset.StringFlag{ Name: "ipcpath", Usage: "Filename for IPC socket/pipe within the datadir (explicit paths escape it)", - Value: c.cliConfig.JsonRPC.IPCPath, + Value: &c.cliConfig.JsonRPC.IPCPath, }) f.SliceStringFlag(&flagset.SliceStringFlag{ Name: "jsonrpc.corsdomain", @@ -264,7 +264,7 @@ func (c *Command) Flags() *flagset.Flagset { Value: &c.cliConfig.JsonRPC.VHost, }) f.SliceStringFlag(&flagset.SliceStringFlag{ - Name: "jsonrpc.modules", + Name: "jsonrpc.modules", Usage: "API's offered over the HTTP-RPC interface", Value: &c.cliConfig.JsonRPC.Modules, }) @@ -273,61 +273,61 @@ func (c *Command) Flags() *flagset.Flagset { f.BoolFlag(&flagset.BoolFlag{ Name: "http", Usage: "Enable the HTTP-RPC server", - Value: c.cliConfig.JsonRPC.Http.Enabled, + Value: &c.cliConfig.JsonRPC.Http.Enabled, }) f.StringFlag(&flagset.StringFlag{ Name: "http.addr", Usage: "HTTP-RPC server listening interface", - Value: c.cliConfig.JsonRPC.Http.Host, + Value: &c.cliConfig.JsonRPC.Http.Host, }) f.Uint64Flag(&flagset.Uint64Flag{ Name: "http.port", Usage: "HTTP-RPC server listening port", - Value: c.cliConfig.JsonRPC.Http.Port, + Value: &c.cliConfig.JsonRPC.Http.Port, }) f.StringFlag(&flagset.StringFlag{ Name: "http.rpcprefix", Usage: "HTTP path path prefix on which JSON-RPC is served. Use '/' to serve on all paths.", - Value: c.cliConfig.JsonRPC.Http.Prefix, + Value: &c.cliConfig.JsonRPC.Http.Prefix, }) // ws options f.BoolFlag(&flagset.BoolFlag{ Name: "ws", Usage: "Enable the WS-RPC server", - Value: c.cliConfig.JsonRPC.Ws.Enabled, + Value: &c.cliConfig.JsonRPC.Ws.Enabled, }) f.StringFlag(&flagset.StringFlag{ Name: "ws.addr", Usage: "WS-RPC server listening interface", - Value: c.cliConfig.JsonRPC.Ws.Host, + Value: &c.cliConfig.JsonRPC.Ws.Host, }) f.Uint64Flag(&flagset.Uint64Flag{ Name: "ws.port", Usage: "WS-RPC server listening port", - Value: c.cliConfig.JsonRPC.Ws.Port, + Value: &c.cliConfig.JsonRPC.Ws.Port, }) f.StringFlag(&flagset.StringFlag{ Name: "ws.rpcprefix", Usage: "HTTP path prefix on which JSON-RPC is served. Use '/' to serve on all paths.", - Value: c.cliConfig.JsonRPC.Ws.Prefix, + Value: &c.cliConfig.JsonRPC.Ws.Prefix, }) // graphql options f.BoolFlag(&flagset.BoolFlag{ Name: "graphql", Usage: "Enable GraphQL on the HTTP-RPC server. Note that GraphQL can only be started if an HTTP server is started as well.", - Value: c.cliConfig.JsonRPC.Graphql.Enabled, + Value: &c.cliConfig.JsonRPC.Graphql.Enabled, }) // p2p options f.StringFlag(&flagset.StringFlag{ Name: "bind", Usage: "Network binding address", - Value: c.cliConfig.P2P.Bind, + Value: &c.cliConfig.P2P.Bind, }) f.Uint64Flag(&flagset.Uint64Flag{ Name: "port", Usage: "Network listening port", - Value: c.cliConfig.P2P.Port, + Value: &c.cliConfig.P2P.Port, }) f.SliceStringFlag(&flagset.SliceStringFlag{ Name: "bootnodes", @@ -337,90 +337,90 @@ func (c *Command) Flags() *flagset.Flagset { f.Uint64Flag(&flagset.Uint64Flag{ Name: "maxpeers", Usage: "Maximum number of network peers (network disabled if set to 0)", - Value: c.cliConfig.P2P.MaxPeers, + Value: &c.cliConfig.P2P.MaxPeers, }) f.Uint64Flag(&flagset.Uint64Flag{ Name: "maxpendpeers", Usage: "Maximum number of pending connection attempts (defaults used if set to 0)", - Value: c.cliConfig.P2P.MaxPendPeers, + Value: &c.cliConfig.P2P.MaxPendPeers, }) f.StringFlag(&flagset.StringFlag{ Name: "nat", Usage: "NAT port mapping mechanism (any|none|upnp|pmp|extip:)", - Value: c.cliConfig.P2P.NAT, + Value: &c.cliConfig.P2P.NAT, }) f.BoolFlag(&flagset.BoolFlag{ Name: "nodiscover", Usage: "Disables the peer discovery mechanism (manual peer addition)", - Value: c.cliConfig.P2P.NoDiscover, + Value: &c.cliConfig.P2P.NoDiscover, }) f.BoolFlag(&flagset.BoolFlag{ Name: "v5disc", Usage: "Enables the experimental RLPx V5 (Topic Discovery) mechanism", - Value: c.cliConfig.P2P.Discovery.V5Enabled, + Value: &c.cliConfig.P2P.Discovery.V5Enabled, }) // metrics f.BoolFlag(&flagset.BoolFlag{ Name: "metrics", Usage: "Enable metrics collection and reporting", - Value: c.cliConfig.Metrics.Enabled, + Value: &c.cliConfig.Metrics.Enabled, }) f.BoolFlag(&flagset.BoolFlag{ Name: "metrics.expensive", Usage: "Enable expensive metrics collection and reporting", - Value: c.cliConfig.Metrics.Expensive, + Value: &c.cliConfig.Metrics.Expensive, }) f.BoolFlag(&flagset.BoolFlag{ Name: "metrics.influxdb", Usage: "Enable metrics export/push to an external InfluxDB database (v1)", - Value: c.cliConfig.Metrics.InfluxDB.V1Enabled, + Value: &c.cliConfig.Metrics.InfluxDB.V1Enabled, }) f.StringFlag(&flagset.StringFlag{ Name: "metrics.influxdb.endpoint", Usage: "InfluxDB API endpoint to report metrics to", - Value: c.cliConfig.Metrics.InfluxDB.Endpoint, + Value: &c.cliConfig.Metrics.InfluxDB.Endpoint, }) f.StringFlag(&flagset.StringFlag{ Name: "metrics.influxdb.database", Usage: "InfluxDB database name to push reported metrics to", - Value: c.cliConfig.Metrics.InfluxDB.Database, + Value: &c.cliConfig.Metrics.InfluxDB.Database, }) f.StringFlag(&flagset.StringFlag{ Name: "metrics.influxdb.username", Usage: "Username to authorize access to the database", - Value: c.cliConfig.Metrics.InfluxDB.Username, + Value: &c.cliConfig.Metrics.InfluxDB.Username, }) f.StringFlag(&flagset.StringFlag{ Name: "metrics.influxdb.password", Usage: "Password to authorize access to the database", - Value: c.cliConfig.Metrics.InfluxDB.Password, + Value: &c.cliConfig.Metrics.InfluxDB.Password, }) f.MapStringFlag(&flagset.MapStringFlag{ Name: "metrics.influxdb.tags", Usage: "Comma-separated InfluxDB tags (key/values) attached to all measurements", - Value: c.cliConfig.Metrics.InfluxDB.Tags, + Value: &c.cliConfig.Metrics.InfluxDB.Tags, }) // influx db v2 f.BoolFlag(&flagset.BoolFlag{ Name: "metrics.influxdbv2", Usage: "Enable metrics export/push to an external InfluxDB v2 database", - Value: c.cliConfig.Metrics.InfluxDB.V2Enabled, + Value: &c.cliConfig.Metrics.InfluxDB.V2Enabled, }) f.StringFlag(&flagset.StringFlag{ Name: "metrics.influxdb.token", Usage: "Token to authorize access to the database (v2 only)", - Value: c.cliConfig.Metrics.InfluxDB.Token, + Value: &c.cliConfig.Metrics.InfluxDB.Token, }) f.StringFlag(&flagset.StringFlag{ Name: "metrics.influxdb.bucket", Usage: "InfluxDB bucket name to push reported metrics to (v2 only)", - Value: c.cliConfig.Metrics.InfluxDB.Bucket, + Value: &c.cliConfig.Metrics.InfluxDB.Bucket, }) f.StringFlag(&flagset.StringFlag{ Name: "metrics.influxdb.organization", Usage: "InfluxDB organization name (v2 only)", - Value: c.cliConfig.Metrics.InfluxDB.Organization, + Value: &c.cliConfig.Metrics.InfluxDB.Organization, }) // account @@ -432,17 +432,17 @@ func (c *Command) Flags() *flagset.Flagset { f.StringFlag(&flagset.StringFlag{ Name: "password", Usage: "Password file to use for non-interactive password input", - Value: c.cliConfig.Accounts.PasswordFile, + Value: &c.cliConfig.Accounts.PasswordFile, }) f.BoolFlag(&flagset.BoolFlag{ Name: "allow-insecure-unlock", Usage: "Allow insecure account unlocking when account-related RPCs are exposed by http", - Value: c.cliConfig.Accounts.AllowInsecureUnlock, + Value: &c.cliConfig.Accounts.AllowInsecureUnlock, }) f.BoolFlag(&flagset.BoolFlag{ Name: "lightkdf", Usage: "Reduce key-derivation RAM & CPU usage at some expense of KDF strength", - Value: c.cliConfig.Accounts.UseLightweightKDF, + Value: &c.cliConfig.Accounts.UseLightweightKDF, }) return f From c9cc1412a2b63a2d0c6f9e88d7f711cdb6b9fae1 Mon Sep 17 00:00:00 2001 From: Ferran Borreguero Date: Wed, 20 Oct 2021 19:50:42 +0200 Subject: [PATCH 12/51] Add config file --- command/server/command.go | 10 +- command/server/config.go | 208 +++++++++++++++++----------------- command/server/config_test.go | 30 +++++ command/server/flags.go | 2 +- go.mod | 1 + go.sum | 29 +++++ 6 files changed, 173 insertions(+), 107 deletions(-) diff --git a/command/server/command.go b/command/server/command.go index 10beeda385..3e980917f5 100644 --- a/command/server/command.go +++ b/command/server/command.go @@ -36,7 +36,7 @@ type Command struct { // final configuration config *Config - configFile string + configFile []string // bor node node *node.Node @@ -65,8 +65,8 @@ func (c *Command) Run(args []string) int { // read config file config := DefaultConfig() - if c.configFile != "" { - cfg, err := readConfigFile(c.configFile) + for _, configFile := range c.configFile { + cfg, err := readConfigFile(configFile) if err != nil { c.UI.Error(err.Error()) return 1 @@ -130,8 +130,8 @@ func (c *Command) Run(args []string) int { } // register ethash service - if config.EthStats != "" { - if err := ethstats.New(stack, backend.APIBackend, backend.Engine(), config.EthStats); err != nil { + if config.Ethstats != "" { + if err := ethstats.New(stack, backend.APIBackend, backend.Engine(), config.Ethstats); err != nil { c.UI.Error(err.Error()) return 1 } diff --git a/command/server/config.go b/command/server/config.go index 27daab7dae..be42b14127 100644 --- a/command/server/config.go +++ b/command/server/config.go @@ -1,6 +1,7 @@ package server import ( + "encoding/json" "fmt" "io/ioutil" "math" @@ -33,141 +34,140 @@ import ( type Config struct { chain *chains.Chain - Chain string - Debug bool - Whitelist map[string]string - LogLevel string - DataDir string - P2P *P2PConfig - SyncMode string - GcMode string - Snapshot bool - EthStats string - Heimdall *HeimdallConfig - TxPool *TxPoolConfig - Sealer *SealerConfig - JsonRPC *JsonRPCConfig - Gpo *GpoConfig - Ethstats string - Metrics *MetricsConfig - Cache *CacheConfig - Accounts *AccountsConfig + Chain string `json:"chain"` + Debug bool `json:""` + Whitelist map[string]string `json:""` + LogLevel string `json:"log-level"` + DataDir string `json:"data-dir"` + P2P *P2PConfig `json:""` + SyncMode string `json:"sync-mode"` + GcMode string `json:"gc-mode"` + Snapshot bool `json:"snapshot"` + Heimdall *HeimdallConfig `json:"heimdall"` + TxPool *TxPoolConfig `json:"txpool"` + Sealer *SealerConfig `json:"sealer"` + JsonRPC *JsonRPCConfig `json:"jsonrpc"` + Gpo *GpoConfig `json:"gpo"` + Ethstats string `json:"ethstats"` + Metrics *MetricsConfig `json:""` + Cache *CacheConfig `json:""` + Accounts *AccountsConfig `json:""` } type P2PConfig struct { - MaxPeers uint64 - MaxPendPeers uint64 - Bind string - Port uint64 - NoDiscover bool - NAT string - Discovery *P2PDiscovery + MaxPeers uint64 `json:"max_peers"` + MaxPendPeers uint64 `json:"max_pend_peers"` + Bind string `json:""` + Port uint64 `json:""` + NoDiscover bool `json:""` + NAT string `json:""` + Discovery *P2PDiscovery `json:""` } type P2PDiscovery struct { - V5Enabled bool - Bootnodes []string - BootnodesV4 []string - BootnodesV5 []string - StaticNodes []string - TrustedNodes []string - DNS []string + V5Enabled bool `json:""` + Bootnodes []string `json:""` + BootnodesV4 []string `json:""` + BootnodesV5 []string `json:""` + StaticNodes []string `json:""` + TrustedNodes []string `json:""` + DNS []string `json:""` } type HeimdallConfig struct { - URL string - Without bool + URL string `json:""` + Without bool `json:""` } type TxPoolConfig struct { - Locals []string - NoLocals bool - Journal string - Rejournal time.Duration - PriceLimit uint64 - PriceBump uint64 - AccountSlots uint64 - GlobalSlots uint64 - AccountQueue uint64 - GlobalQueue uint64 - LifeTime time.Duration + Locals []string `json:""` + NoLocals bool `json:""` + Journal string `json:""` + Rejournal time.Duration `json:""` + PriceLimit uint64 `json:""` + PriceBump uint64 `json:""` + AccountSlots uint64 `json:""` + GlobalSlots uint64 `json:""` + AccountQueue uint64 `json:""` + GlobalQueue uint64 `json:""` + LifeTime time.Duration `json:""` } type SealerConfig struct { - Enabled bool - Etherbase string - ExtraData string - GasCeil uint64 - GasPrice *big.Int + Enabled bool `json:""` + Etherbase string `json:""` + ExtraData string `json:""` + GasCeil uint64 `json:""` + GasPrice *big.Int `json:""` } type JsonRPCConfig struct { - IPCDisable bool - IPCPath string + IPCDisable bool `json:""` + IPCPath string `json:""` - Modules []string - VHost []string - Cors []string + Modules []string `json:""` + VHost []string `json:""` + Cors []string `json:""` - GasCap uint64 - TxFeeCap float64 + GasCap uint64 `json:""` + TxFeeCap float64 `json:""` - Http *APIConfig - Ws *APIConfig - Graphql *APIConfig + Http *APIConfig `json:""` + Ws *APIConfig `json:""` + Graphql *APIConfig `json:""` } type APIConfig struct { - Enabled bool - Port uint64 - Prefix string - Host string + Enabled bool `json:""` + Port uint64 `json:""` + Prefix string `json:""` + Host string `json:""` } type GpoConfig struct { - Blocks uint64 - Percentile uint64 - MaxPrice *big.Int - IgnorePrice *big.Int + Blocks uint64 `json:""` + Percentile uint64 `json:""` + MaxPrice *big.Int `json:""` + IgnorePrice *big.Int `json:""` } type MetricsConfig struct { - Enabled bool - Expensive bool - InfluxDB *InfluxDBConfig + Enabled bool `json:""` + Expensive bool `json:""` + InfluxDB *InfluxDBConfig `json:""` } type InfluxDBConfig struct { - V1Enabled bool - Endpoint string - Database string - Username string - Password string - Tags map[string]string - V2Enabled bool - Token string - Bucket string - Organization string + V1Enabled bool `json:""` + Endpoint string `json:""` + Database string `json:""` + Username string `json:""` + Password string `json:""` + Tags map[string]string `json:""` + V2Enabled bool `json:""` + Token string `json:""` + Bucket string `json:""` + Organization string `json:""` } type CacheConfig struct { - Cache uint64 - PercGc uint64 - PercSnapshot uint64 - PercDatabase uint64 - PercTrie uint64 - Journal string - Rejournal time.Duration - NoPrefetch bool - Preimages bool - TxLookupLimit uint64 + Cache uint64 `json:""` + PercGc uint64 `json:""` + PercSnapshot uint64 `json:""` + PercDatabase uint64 `json:""` + PercTrie uint64 `json:""` + Journal string `json:""` + Rejournal time.Duration `json:""` + NoPrefetch bool `json:""` + Preimages bool `json:""` + TxLookupLimit uint64 `json:""` } type AccountsConfig struct { - Unlock []string - PasswordFile string - AllowInsecureUnlock bool - UseLightweightKDF bool + Unlock []string `json:""` + PasswordFile string `json:""` + AllowInsecureUnlock bool `json:""` + UseLightweightKDF bool `json:""` } func DefaultConfig() *Config { @@ -201,7 +201,6 @@ func DefaultConfig() *Config { SyncMode: "fast", GcMode: "full", Snapshot: true, - EthStats: "", TxPool: &TxPoolConfig{ Locals: []string{}, NoLocals: false, @@ -297,12 +296,19 @@ func readConfigFile(path string) (*Config, error) { } // TODO: Use hcl as config format ext := filepath.Ext(path) - switch ext { - case ".toml": + if ext == ".toml" { return readLegacyConfig(data) - default: - return nil, fmt.Errorf("file path extension '%s' not found", ext) } + + // read configuration file + if ext != ".json" { + return nil, fmt.Errorf("suffix of %s is not json", path) + } + var config Config + if err := json.Unmarshal(data, &config); err != nil { + return nil, err + } + return &config, nil } func (c *Config) loadChain() error { diff --git a/command/server/config_test.go b/command/server/config_test.go index e11b02766c..6ecc28b5c0 100644 --- a/command/server/config_test.go +++ b/command/server/config_test.go @@ -1,6 +1,8 @@ package server import ( + "io/ioutil" + "path/filepath" "testing" "time" @@ -75,6 +77,34 @@ func TestConfigMerge(t *testing.T) { assert.Equal(t, c0, expected) } +func TestConfigHcl(t *testing.T) { + readConfig := func(data string, format string) *Config { + tmpDir, err := ioutil.TempDir("/tmp", "test-config") + assert.NoError(t, err) + + filename := filepath.Join(tmpDir, "config."+format) + assert.NoError(t, ioutil.WriteFile(filename, []byte(data), 0755)) + + config, err := readConfigFile(filename) + assert.NoError(t, err) + return config + } + + cfg := `{ + "datadir": "datadir", + "p2p": { + "max_peers": 30 + } + }` + config := readConfig(cfg, "json") + assert.Equal(t, config, &Config{ + DataDir: "datadir", + P2P: &P2PConfig{ + MaxPeers: 30, + }, + }) +} + var dummyEnodeAddr = "enode://0cb82b395094ee4a2915e9714894627de9ed8498fb881cec6db7c65e8b9a5bd7f2f25cc84e71e89d0947e51c76e85d0847de848c7782b13c0255247a6758178c@44.232.55.71:30303" func TestConfigBootnodesDefault(t *testing.T) { diff --git a/command/server/flags.go b/command/server/flags.go index d9bd017468..5f4e88e6a6 100644 --- a/command/server/flags.go +++ b/command/server/flags.go @@ -29,7 +29,7 @@ func (c *Command) Flags() *flagset.Flagset { Usage: "Path of the data directory to store information", Value: &c.cliConfig.DataDir, }) - f.StringFlag(&flagset.StringFlag{ + f.SliceStringFlag(&flagset.SliceStringFlag{ Name: "config", Usage: "File for the config file", Value: &c.configFile, diff --git a/go.mod b/go.mod index b5f8b0032d..7a2ed24783 100644 --- a/go.mod +++ b/go.mod @@ -36,6 +36,7 @@ require ( github.com/gorilla/websocket v1.4.2 github.com/graph-gophers/graphql-go v0.0.0-20201113091052-beb923fada29 github.com/hashicorp/golang-lru v0.5.5-0.20210104140557-80c98217689d + github.com/hashicorp/hcl/v2 v2.10.1 github.com/holiman/bloomfilter/v2 v2.0.3 github.com/holiman/uint256 v1.2.0 github.com/huin/goupnp v1.0.2 diff --git a/go.sum b/go.sum index a4b737eacd..cdb8050f37 100644 --- a/go.sum +++ b/go.sum @@ -53,6 +53,8 @@ github.com/StackExchange/wmi v0.0.0-20180116203802-5d049714c4a6/go.mod h1:3eOhrU github.com/VictoriaMetrics/fastcache v1.6.0 h1:C/3Oi3EiBCqufydp1neRZkqcwmEiuRT9c3fqvvgKm5o= github.com/VictoriaMetrics/fastcache v1.6.0/go.mod h1:0qHz5QP0GMX4pfmMA/zt5RgfNuXJrTP0zS7DqpHGGTw= github.com/aead/siphash v1.0.1/go.mod h1:Nywa3cDsYNNK3gaciGTWPwHt0wlpNV15vwmswBAUSII= +github.com/agext/levenshtein v1.2.1 h1:QmvMAjj2aEICytGiWzmxoE0x2KZvE0fvmqMOfy2tjT8= +github.com/agext/levenshtein v1.2.1/go.mod h1:JEDfjyjHDjOF/1e4FlBE/PkbqA9OfWu2ki2W0IB5558= github.com/ajstarks/svgo v0.0.0-20180226025133-644b8db467af/go.mod h1:K08gAheRH3/J6wwsYMMT4xOr94bZjxIelGM0+d/wbFw= github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= @@ -60,6 +62,11 @@ github.com/allegro/bigcache v1.2.1-0.20190218064605-e24eb225f156 h1:eMwmnE/GDgah github.com/allegro/bigcache v1.2.1-0.20190218064605-e24eb225f156/go.mod h1:Cb/ax3seSYIx7SuZdm2G2xzfwmv3TPSk2ucNfQESPXM= github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883/go.mod h1:rCTlJbsFo29Kk6CurOXKm700vrz8f0KW0JNfpkRJY/8= github.com/apache/arrow/go/arrow v0.0.0-20191024131854-af6fa24be0db/go.mod h1:VTxUBvSJ3s3eHAg65PNgrsn5BtqCRPdmyXh6rAfdxN0= +github.com/apparentlymart/go-dump v0.0.0-20180507223929-23540a00eaa3/go.mod h1:oL81AME2rN47vu18xqj1S1jPIPuN7afo62yKTNn3XMM= +github.com/apparentlymart/go-textseg v1.0.0 h1:rRmlIsPEEhUTIKQb7T++Nz/A5Q6C9IuX2wFoYVvnCs0= +github.com/apparentlymart/go-textseg v1.0.0/go.mod h1:z96Txxhf3xSFMPmb5X/1W05FF/Nj9VFpLOpjS5yuumk= +github.com/apparentlymart/go-textseg/v13 v13.0.0 h1:Y+KvPE1NYz0xl601PVImeQfFyEy6iT90AvPUL1NNfNw= +github.com/apparentlymart/go-textseg/v13 v13.0.0/go.mod h1:ZK2fH7c4NqDTLtiYLvIkEghdlcqw7yxLeM89kiTRPUo= github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310 h1:BUAU3CGlLvorLI26FmByPp2eC2qla6E1Tw+scpcg/to= github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= github.com/aws/aws-sdk-go-v2 v1.2.0 h1:BS+UYpbsElC82gB+2E2jiCBg36i8HlubTB/dO/moQ9c= @@ -171,6 +178,8 @@ github.com/go-sourcemap/sourcemap v2.1.2+incompatible/go.mod h1:F8jJfvm2KbVjc5Nq github.com/go-sql-driver/mysql v1.4.1/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= github.com/go-stack/stack v1.8.0 h1:5SgMzNM5HxrEjV0ww2lTmX6E2Izsfxas4+YHWRs3Lsk= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= +github.com/go-test/deep v1.0.3 h1:ZrJSEWsXzPOxaZnFteGEfooLba+ju3FYIbOrS+rQd68= +github.com/go-test/deep v1.0.3/go.mod h1:wGDj63lr65AM2AQyKZd/NYHGb0R+1RLqB8NKt3aSFNA= github.com/gofrs/uuid v3.3.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM= github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= github.com/gogo/protobuf v1.3.1/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o= @@ -182,9 +191,11 @@ github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4er github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y= +github.com/golang/protobuf v1.1.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.4/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= @@ -234,6 +245,8 @@ github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.5-0.20210104140557-80c98217689d h1:dg1dEPuWpEqDnvIw251EVy4zlP8gWbsGj4BsUKCRpYs= github.com/hashicorp/golang-lru v0.5.5-0.20210104140557-80c98217689d/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= +github.com/hashicorp/hcl/v2 v2.10.1 h1:h4Xx4fsrRE26ohAk/1iGF/JBqRQbyUqu5Lvj60U54ys= +github.com/hashicorp/hcl/v2 v2.10.1/go.mod h1:FwWsfWEjyV/CMj8s/gqAuiviY72rJ1/oayI9WftqcKg= github.com/holiman/bloomfilter/v2 v2.0.3 h1:73e0e/V0tCydx14a0SCYS/EWCxgwLZ18CZcZKVu0fao= github.com/holiman/bloomfilter/v2 v2.0.3/go.mod h1:zpoh+gs7qcpqrHr3dB55AMiJwo0iURXE7ZOP9L9hSkA= github.com/holiman/uint256 v1.2.0 h1:gpSYcPLWGv4sG43I2mVLiDZCNDh/EpGjSk8tmtxitHM= @@ -296,6 +309,7 @@ github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORN github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/kylelemons/godebug v0.0.0-20170820004349-d65d576e9348/go.mod h1:B69LEHPfb2qLo0BaaOLcbitczOKLWTsrBG9LczfCD4k= github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc= github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= github.com/labstack/echo/v4 v4.2.1/go.mod h1:AA49e0DZ8kk5jTOOCKNuPR6oTnBS0dYiM4FW1e6jwpg= @@ -332,6 +346,8 @@ github.com/mitchellh/copystructure v1.0.0 h1:Laisrj+bAB6b/yJwB5Bt3ITZhGJdqmxquMK github.com/mitchellh/copystructure v1.0.0/go.mod h1:SNtv71yrdKgLRyLFxmLdkAbkKEFWgYaq1OVrnRcwhnw= github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y= github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= +github.com/mitchellh/go-wordwrap v0.0.0-20150314170334-ad45545899c7 h1:DpOJ2HYzCv8LZP15IdmG+YdwD2luVPHITV96TkirNBM= +github.com/mitchellh/go-wordwrap v0.0.0-20150314170334-ad45545899c7/go.mod h1:ZXFpozHsX6DPmq2I0TCekCxypsnAUbP2oI0UX1GXzOo= github.com/mitchellh/reflectwalk v1.0.0 h1:9D+8oIskB4VJBN5SFlmc27fSlIBZaov1Wpk/IfikLNY= github.com/mitchellh/reflectwalk v1.0.0/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= @@ -398,6 +414,7 @@ github.com/ryanuber/columnize v2.1.2+incompatible h1:C89EOx/XBWwIXl8wm8OPJBd7kPF github.com/ryanuber/columnize v2.1.2+incompatible/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= github.com/segmentio/kafka-go v0.1.0/go.mod h1:X6itGqS9L4jDletMsxZ7Dz+JFWxM6JHfPOCvTvk+EJo= github.com/segmentio/kafka-go v0.2.0/go.mod h1:X6itGqS9L4jDletMsxZ7Dz+JFWxM6JHfPOCvTvk+EJo= +github.com/sergi/go-diff v1.0.0 h1:Kpca3qRNrduNnOQeazBd0ysaKrUJiIuISHxogkT9RPQ= github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo= github.com/shirou/gopsutil v3.21.4-0.20210419000835-c7a38de76ee5+incompatible h1:Bn1aCHHRnjv4Bl16T8rcaFjYSrGrIZvpiGO6P3Q4GpU= github.com/shirou/gopsutil v3.21.4-0.20210419000835-c7a38de76ee5+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA= @@ -408,6 +425,7 @@ github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9 github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ= +github.com/spf13/pflag v1.0.2/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= github.com/status-im/keycard-go v0.0.0-20190316090335-8537d3370df4 h1:Gb2Tyox57NRNuZ2d3rmvB3pcmbu7O1RS3m8WRx7ilrg= github.com/status-im/keycard-go v0.0.0-20190316090335-8537d3370df4/go.mod h1:RZLeN1LMWmRsyYjvAu+I6Dm9QmlDaIIt+Y+4Kd7Tp+Q= @@ -435,11 +453,18 @@ github.com/urfave/cli/v2 v2.3.0/go.mod h1:LJmUH05zAU44vOAcrfzZQKsZbVcdbOG8rtL3/X github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= github.com/valyala/fasttemplate v1.0.1/go.mod h1:UQGH1tvbgY+Nz5t2n7tXsz52dQxojPUpymEIMZ47gx8= github.com/valyala/fasttemplate v1.2.1/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ= +github.com/vmihailenco/msgpack v3.3.3+incompatible/go.mod h1:fy3FlTQTDXWkZ7Bh6AcGMlsjHatGryHQYUTf1ShIgkk= +github.com/vmihailenco/msgpack/v4 v4.3.12/go.mod h1:gborTTJjAo/GWTqqRjrLCn9pgNN+NXzzngzBKDPIqw4= +github.com/vmihailenco/tagparser v0.1.1/go.mod h1:OeAg3pn3UbLjkWt+rN9oFYB6u/cQgqMEUPoW2WPyhdI= github.com/willf/bitset v1.1.3/go.mod h1:RjeCKbqT1RxIR/KWY6phxZiaY1IyutSBfGjNPySAYV4= github.com/xlab/treeprint v0.0.0-20180616005107-d6fb6747feb6/go.mod h1:ce1O1j6UtZfjr22oyGxGLbauSBp2YVXpARAosm7dHBg= github.com/xsleonard/go-merkle v1.1.0 h1:fHe1fuhJjGH22ZzVTAH0jqHLhTGhOq3wQjJN+8P0jQg= github.com/xsleonard/go-merkle v1.1.0/go.mod h1:cW4z+UZ/4f2n9IJgIiyDCdYguchoDyDAPmpuOWGxdGg= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/zclconf/go-cty v1.2.0/go.mod h1:hOPWgoHbaTUnI5k4D2ld+GRpFJSCe6bCM7m1q/N4PQ8= +github.com/zclconf/go-cty v1.8.0 h1:s4AvqaeQzJIu3ndv4gVIhplVD0krU+bgrcLSVUnaWuA= +github.com/zclconf/go-cty v1.8.0/go.mod h1:vVKLxnk3puL4qRAv72AO+W99LUD4da90g3uUAzyuvAk= +github.com/zclconf/go-cty-debug v0.0.0-20191215020915-b22d67c1ba0b/go.mod h1:ZRKQfBXbGkpdV6QMzT3rU1kSTAnfu1dO8dPKjYprgj8= go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= @@ -449,6 +474,7 @@ go.uber.org/zap v1.9.1/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= golang.org/x/crypto v0.0.0-20170930174604-9419663f5a44/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20190426145343-a29dc8fdc734/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190909091759-094676da4a83/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= @@ -487,6 +513,7 @@ golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzB golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20180811021610-c39426892332/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -501,6 +528,7 @@ golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLL golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200813134508-3edf25e44fcc/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= @@ -535,6 +563,7 @@ golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5h golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190502175342-a43fa875dd82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= From 51de433242c354f96a8fb93d85f19034d021cf5c Mon Sep 17 00:00:00 2001 From: Ferran Borreguero Date: Fri, 22 Oct 2021 12:32:55 +0200 Subject: [PATCH 13/51] Add hcl/json config file --- command/server/command.go | 4 +- command/server/config.go | 427 +++++++++++++++++++++------- command/server/config_test.go | 52 ++-- command/server/flags.go | 29 +- command/server/testdata/simple.hcl | 9 + command/server/testdata/simple.json | 9 + 6 files changed, 373 insertions(+), 157 deletions(-) create mode 100644 command/server/testdata/simple.hcl create mode 100644 command/server/testdata/simple.json diff --git a/command/server/command.go b/command/server/command.go index 3e980917f5..361be1ba09 100644 --- a/command/server/command.go +++ b/command/server/command.go @@ -165,7 +165,7 @@ func (c *Command) Run(args []string) int { } } - if err := c.setupMetrics(config.Metrics); err != nil { + if err := c.setupTelemetry(config.Telemetry); err != nil { c.UI.Error(err.Error()) return 1 } @@ -221,7 +221,7 @@ func (c *Command) unlockAccounts(borKeystore *keystore.KeyStore) error { return nil } -func (c *Command) setupMetrics(config *MetricsConfig) error { +func (c *Command) setupTelemetry(config *TelemetryConfig) error { metrics.Enabled = config.Enabled metrics.EnabledExpensive = config.Expensive diff --git a/command/server/config.go b/command/server/config.go index be42b14127..177983a702 100644 --- a/command/server/config.go +++ b/command/server/config.go @@ -1,7 +1,6 @@ package server import ( - "encoding/json" "fmt" "io/ioutil" "math" @@ -26,6 +25,7 @@ import ( "github.com/ethereum/go-ethereum/p2p/enode" "github.com/ethereum/go-ethereum/p2p/nat" "github.com/ethereum/go-ethereum/params" + "github.com/hashicorp/hcl/v2/hclsimple" "github.com/imdario/mergo" "github.com/mitchellh/go-homedir" gopsutil "github.com/shirou/gopsutil/mem" @@ -34,146 +34,319 @@ import ( type Config struct { chain *chains.Chain - Chain string `json:"chain"` - Debug bool `json:""` - Whitelist map[string]string `json:""` - LogLevel string `json:"log-level"` - DataDir string `json:"data-dir"` - P2P *P2PConfig `json:""` - SyncMode string `json:"sync-mode"` - GcMode string `json:"gc-mode"` - Snapshot bool `json:"snapshot"` - Heimdall *HeimdallConfig `json:"heimdall"` - TxPool *TxPoolConfig `json:"txpool"` - Sealer *SealerConfig `json:"sealer"` - JsonRPC *JsonRPCConfig `json:"jsonrpc"` - Gpo *GpoConfig `json:"gpo"` - Ethstats string `json:"ethstats"` - Metrics *MetricsConfig `json:""` - Cache *CacheConfig `json:""` - Accounts *AccountsConfig `json:""` + // Chain is the chain to sync with + Chain string `hcl:"chain,optional"` + + // Whitelist is a list of required (block number, hash) pairs to accept + Whitelist map[string]string `hcl:"whitelist,optional"` + + // LogLevel is the level of the logs to put out + LogLevel string `hcl:"log-level,optional"` + + // DataDir is the directory to store the state in + DataDir string `hcl:"data-dir,optional"` + + // SyncMode selects the sync protocol + SyncMode string `hcl:"sync-mode,optional"` + + // GcMode selects the garbage collection mode for the trie + GcMode string `hcl:"gc-mode,optional"` + + // XXX + Snapshot bool `hcl:"snapshot,optional"` + + // Ethstats is the address of the ethstats server to send telemetry + Ethstats string `hcl:"ethstats,optional"` + + // P2P has the p2p network related settings + P2P *P2PConfig `hcl:"p2p,block"` + + // Heimdall has the heimdall connection related settings + Heimdall *HeimdallConfig `hcl:"heimdall,block"` + + // TxPool has the transaction pool related settings + TxPool *TxPoolConfig `hcl:"txpool,block"` + + // Sealer has the validator related settings + Sealer *SealerConfig `hcl:"sealer,block"` + + // JsonRPC has the json-rpc related settings + JsonRPC *JsonRPCConfig `hcl:"jsonrpc,block"` + + // Gpo has the gas price oracle related settings + Gpo *GpoConfig `hcl:"gpo,block"` + + // Telemetry has the telemetry related settings + Telemetry *TelemetryConfig `hcl:"telemetry,block"` + + // Cache has the cache related settings + Cache *CacheConfig `hcl:"cache,block"` + + // Account has the validator account related settings + Accounts *AccountsConfig `hcl:"accounts,block"` } type P2PConfig struct { - MaxPeers uint64 `json:"max_peers"` - MaxPendPeers uint64 `json:"max_pend_peers"` - Bind string `json:""` - Port uint64 `json:""` - NoDiscover bool `json:""` - NAT string `json:""` - Discovery *P2PDiscovery `json:""` + // MaxPeers sets the maximum number of connected peers + MaxPeers uint64 `hcl:"max-peers,optional"` + + // MaxPendPeers sets the maximum number of pending connected peers + MaxPendPeers uint64 `hcl:"max-pend-peers,optional"` + + // Bind is the bind address + Bind string `hcl:"bind,optional"` + + // Port is the port number + Port uint64 `hcl:"port,optional"` + + // NoDiscover is used to disable discovery + NoDiscover bool `hcl:"no-discover,optional"` + + // NAT it used to set NAT options + NAT string `hcl:"nat,optional"` + + // Discovery has the p2p discovery related settings + Discovery *P2PDiscovery `hcl:"discovery,block"` } type P2PDiscovery struct { - V5Enabled bool `json:""` - Bootnodes []string `json:""` - BootnodesV4 []string `json:""` - BootnodesV5 []string `json:""` - StaticNodes []string `json:""` - TrustedNodes []string `json:""` - DNS []string `json:""` + // V5Enabled is used to enable disc v5 discovery mode + V5Enabled bool `hcl:"v5-enabled,optional"` + + // Bootnodes is the list of initial bootnodes + Bootnodes []string `hcl:"bootnodes,optional"` + + // BootnodesV4 is the list of initial v4 bootnodes + BootnodesV4 []string `hcl:"bootnodesv4,optional"` + + // BootnodesV5 is the list of initial v5 bootnodes + BootnodesV5 []string `hcl:"bootnodesv5,optional"` + + // StaticNodes is the list of static nodes + StaticNodes []string `hcl:"static-nodes,optional"` + + // TrustedNodes is the list of trusted nodes + TrustedNodes []string `hcl:"trusted-nodes,optional"` + + // DNS is the list of enrtree:// URLs which will be queried for nodes to connect to + DNS []string `hcl:"dns,optional"` } type HeimdallConfig struct { - URL string `json:""` - Without bool `json:""` + // URL is the url of the heimdall server + URL string `hcl:"url,optional"` + + // Without is used to disable remote heimdall during testing + Without bool `hcl:"without,optional"` } type TxPoolConfig struct { - Locals []string `json:""` - NoLocals bool `json:""` - Journal string `json:""` - Rejournal time.Duration `json:""` - PriceLimit uint64 `json:""` - PriceBump uint64 `json:""` - AccountSlots uint64 `json:""` - GlobalSlots uint64 `json:""` - AccountQueue uint64 `json:""` - GlobalQueue uint64 `json:""` - LifeTime time.Duration `json:""` + // Locals are the addresses that should be treated by default as local + Locals []string `hcl:"locals,optional"` + + // NoLocals enables whether local transaction handling should be disabled + NoLocals bool `hcl:"no-locals,optional"` + + // Journal is the path to store local transactions to survive node restarts + Journal string `hcl:"journal,optional"` + + // Rejournal is the time interval to regenerate the local transaction journal + Rejournal time.Duration + RejournalRaw string `hcl:"rejournal,optional"` + + // PriceLimit is the minimum gas price to enforce for acceptance into the pool + PriceLimit uint64 `hcl:"price-limit,optional"` + + // PriceBump is the minimum price bump percentage to replace an already existing transaction (nonce) + PriceBump uint64 `hcl:"price-bump,optional"` + + // AccountSlots is the number of executable transaction slots guaranteed per account + AccountSlots uint64 `hcl:"account-slots,optional"` + + // GlobalSlots is the maximum number of executable transaction slots for all accounts + GlobalSlots uint64 `hcl:"global-slots,optional"` + + // AccountQueue is the maximum number of non-executable transaction slots permitted per account + AccountQueue uint64 `hcl:"account-queue,optional"` + + // GlobalQueueis the maximum number of non-executable transaction slots for all accounts + GlobalQueue uint64 `hcl:"global-queue,optional"` + + // Lifetime is the maximum amount of time non-executable transaction are queued + LifeTime time.Duration + LifeTimeRaw string `hcl:"lifetime,optional"` } type SealerConfig struct { - Enabled bool `json:""` - Etherbase string `json:""` - ExtraData string `json:""` - GasCeil uint64 `json:""` - GasPrice *big.Int `json:""` + // Enabled is used to enable validator mode + Enabled bool `hcl:"enabled,optional"` + + // Etherbase is the address of the validator + Etherbase string `hcl:"etherbase,optional"` + + // ExtraData is the block extra data set by the miner + ExtraData string `hcl:"extra-data,optional"` + + // GasCeil is the target gas ceiling for mined blocks. + GasCeil uint64 `hcl:"gas-ceil,optional"` + + // GasPrice is the minimum gas price for mining a transaction + GasPrice *big.Int `hcl:"gas-price,optional"` } type JsonRPCConfig struct { - IPCDisable bool `json:""` - IPCPath string `json:""` + // IPCDisable enables whether ipc is enabled or not + IPCDisable bool `hcl:"ipc-disable,optional"` - Modules []string `json:""` - VHost []string `json:""` - Cors []string `json:""` + // IPCPath is the path of the ipc endpoint + IPCPath string `hcl:"ipc-path,optional"` - GasCap uint64 `json:""` - TxFeeCap float64 `json:""` + // Modules is the list of enabled api modules + Modules []string `hcl:"modules,optional"` - Http *APIConfig `json:""` - Ws *APIConfig `json:""` - Graphql *APIConfig `json:""` + // VHost is the list of valid virtual hosts + VHost []string `hcl:"vhost,optional"` + + // Cors is the list of Cors endpoints + Cors []string `hcl:"cors,optional"` + + // GasCap is the global gas cap for eth-call variants. + GasCap uint64 `hcl:"gas-cap,optional"` + + // TxFeeCap is the global transaction fee cap for send-transaction variants + TxFeeCap float64 `hcl:"tx-fee-cap,optional"` + + // Http has the json-rpc http related settings + Http *APIConfig `hcl:"http,block"` + + // Http has the json-rpc websocket related settings + Ws *APIConfig `hcl:"ws,block"` + + // Http has the json-rpc graphql related settings + Graphql *APIConfig `hcl:"graphql,block"` } type APIConfig struct { - Enabled bool `json:""` - Port uint64 `json:""` - Prefix string `json:""` - Host string `json:""` + // Enabled selects whether the api is enabled + Enabled bool `hcl:"enabled,optional"` + + // Port is the port number for this api + Port uint64 `hcl:"port,optional"` + + // Prefix is the http prefix to expose this api + Prefix string `hcl:"prefix,optional"` + + // Host is the address to bind the api + Host string `hcl:"host,optional"` } type GpoConfig struct { - Blocks uint64 `json:""` - Percentile uint64 `json:""` - MaxPrice *big.Int `json:""` - IgnorePrice *big.Int `json:""` + // Blocks is the number of blocks to track to compute the price oracle + Blocks uint64 `hcl:"blocks,optional"` + + // Percentile sets the weights to new blocks + Percentile uint64 `hcl:"percentile,optional"` + + // MaxPrice is an upper bound gas price + MaxPrice *big.Int `hcl:"max-price,optional"` + + // IgnorePrice is a lower bound gas price + IgnorePrice *big.Int `hcl:"ignore-price,optional"` } -type MetricsConfig struct { - Enabled bool `json:""` - Expensive bool `json:""` - InfluxDB *InfluxDBConfig `json:""` +type TelemetryConfig struct { + // Enabled enables metrics + Enabled bool `hcl:"enabled,optional"` + + // Expensive enables expensive metrics + Expensive bool `hcl:"expensive,optional"` + + // InfluxDB has the influxdb related settings + InfluxDB *InfluxDBConfig `hcl:"influx,block"` } type InfluxDBConfig struct { - V1Enabled bool `json:""` - Endpoint string `json:""` - Database string `json:""` - Username string `json:""` - Password string `json:""` - Tags map[string]string `json:""` - V2Enabled bool `json:""` - Token string `json:""` - Bucket string `json:""` - Organization string `json:""` + // V1Enabled enables influx v1 mode + V1Enabled bool `hcl:"v1-enabled,optional"` + + // Endpoint is the url endpoint of the influxdb service + Endpoint string `hcl:"endpoint,optional"` + + // Database is the name of the database in Influxdb to store the metrics. + Database string `hcl:"database,optional"` + + // Enabled is the username to authorize access to Influxdb + Username string `hcl:"username,optional"` + + // Password is the password to authorize access to Influxdb + Password string `hcl:"password,optional"` + + // Tags are tags attaches to all generated metrics + Tags map[string]string `hcl:"tags,optional"` + + // Enabled enables influx v2 mode + V2Enabled bool `hcl:"v2-enabled,optional"` + + // Token is the token to authorize access to Influxdb V2. + Token string `hcl:"token,optional"` + + // Bucket is the bucket to store metrics in Influxdb V2. + Bucket string `hcl:"bucket,optional"` + + // Organization is the name of the organization for Influxdb V2. + Organization string `hcl:"organization,optional"` } type CacheConfig struct { - Cache uint64 `json:""` - PercGc uint64 `json:""` - PercSnapshot uint64 `json:""` - PercDatabase uint64 `json:""` - PercTrie uint64 `json:""` - Journal string `json:""` - Rejournal time.Duration `json:""` - NoPrefetch bool `json:""` - Preimages bool `json:""` - TxLookupLimit uint64 `json:""` + // Cache is the amount of cache of the node + Cache uint64 `hcl:"cache,optional"` + + // PercGc is percentage of cache used for garbage collection + PercGc uint64 `hcl:"perc-gc,optional"` + + // PercSnapshot is percentage of cache used for snapshots + PercSnapshot uint64 `hcl:"perc-snapshot,optional"` + + // PercDatabase is percentage of cache used for the database + PercDatabase uint64 `hcl:"perc-database,optional"` + + // PercTrie is percentage of cache used for the trie + PercTrie uint64 `hcl:"perc-trie,optional"` + + // Journal is the disk journal directory for trie cache to survive node restarts + Journal string `hcl:"journal,optional"` + + // Rejournal is the time interval to regenerate the journal for clean cache + Rejournal time.Duration + RejournalRaw string `hcl:"rejournal,optional"` + + // NoPrefetch is used to disable prefetch of tries + NoPrefetch bool `hcl:"no-prefetch,optional"` + + // Preimages is used to enable the track of hash preimages + Preimages bool `hcl:"preimages,optional"` + + // TxLookupLimit sets the maximum number of blocks from head whose tx indices are reserved. + TxLookupLimit uint64 `hcl:"tx-lookup-limit,optional"` } type AccountsConfig struct { - Unlock []string `json:""` - PasswordFile string `json:""` - AllowInsecureUnlock bool `json:""` - UseLightweightKDF bool `json:""` + // Unlock is the list of addresses to unlock in the node + Unlock []string `hcl:"unlock,optional"` + + // PasswordFile is the file where the account passwords are stored + PasswordFile string `hcl:"password-file,optional"` + + // AllowInsecureUnlock allows user to unlock accounts in unsafe http environment. + AllowInsecureUnlock bool `hcl:"allow-insecure-unlock,optional"` + + // UseLightweightKDF enables a faster but less secure encryption of accounts + UseLightweightKDF bool `hcl:"use-lightweight-kdf,optional"` } func DefaultConfig() *Config { return &Config{ Chain: "mainnet", - Debug: false, Whitelist: map[string]string{}, LogLevel: "INFO", DataDir: defaultDataDir(), @@ -252,7 +425,7 @@ func DefaultConfig() *Config { }, }, Ethstats: "", - Metrics: &MetricsConfig{ + Telemetry: &TelemetryConfig{ Enabled: false, Expensive: false, InfluxDB: &InfluxDBConfig{ @@ -289,26 +462,52 @@ func DefaultConfig() *Config { } } -func readConfigFile(path string) (*Config, error) { - data, err := ioutil.ReadFile(path) - if err != nil { - return nil, err +func (c *Config) fillTimeDurations() error { + tds := []struct { + path string + td *time.Duration + str *string + }{ + {"txpool.lifetime", &c.TxPool.LifeTime, &c.TxPool.LifeTimeRaw}, + {"txpool.rejournal", &c.TxPool.Rejournal, &c.TxPool.RejournalRaw}, + {"cache.rejournal", &c.Cache.Rejournal, &c.Cache.RejournalRaw}, } - // TODO: Use hcl as config format + + for _, x := range tds { + if x.td != nil && x.str != nil && *x.str != "" { + d, err := time.ParseDuration(*x.str) + if err != nil { + return fmt.Errorf("%s can't parse time duration %s", x.path, *x.str) + } + *x.str = "" + *x.td = d + } + } + return nil +} + +func readConfigFile(path string) (*Config, error) { ext := filepath.Ext(path) if ext == ".toml" { + // read file and apply the legacy config + data, err := ioutil.ReadFile(path) + if err != nil { + return nil, err + } return readLegacyConfig(data) } - // read configuration file - if ext != ".json" { - return nil, fmt.Errorf("suffix of %s is not json", path) + config := &Config{ + TxPool: &TxPoolConfig{}, + Cache: &CacheConfig{}, } - var config Config - if err := json.Unmarshal(data, &config); err != nil { + if err := hclsimple.DecodeFile(path, nil, config); err != nil { + return nil, fmt.Errorf("failed to decode config file '%s': %v", path, err) + } + if err := config.fillTimeDurations(); err != nil { return nil, err } - return &config, nil + return config, nil } func (c *Config) loadChain() error { @@ -343,6 +542,14 @@ func (c *Config) buildEth() (*ethconfig.Config, error) { n.HeimdallURL = c.Heimdall.URL n.WithoutHeimdall = c.Heimdall.Without + // gas price oracle + { + n.GPO.Blocks = int(c.Gpo.Blocks) + n.GPO.Percentile = int(c.Gpo.Percentile) + n.GPO.MaxPrice = c.Gpo.MaxPrice + n.GPO.IgnorePrice = c.Gpo.IgnorePrice + } + // txpool options { n.TxPool.NoLocals = c.TxPool.NoLocals diff --git a/command/server/config_test.go b/command/server/config_test.go index 6ecc28b5c0..537d83be86 100644 --- a/command/server/config_test.go +++ b/command/server/config_test.go @@ -1,8 +1,6 @@ package server import ( - "io/ioutil" - "path/filepath" "testing" "time" @@ -23,8 +21,8 @@ func TestConfigDefault(t *testing.T) { func TestConfigMerge(t *testing.T) { c0 := &Config{ - Chain: "0", - Debug: true, + Chain: "0", + Snapshot: true, Whitelist: map[string]string{ "a": "b", }, @@ -54,8 +52,8 @@ func TestConfigMerge(t *testing.T) { }, } expected := &Config{ - Chain: "1", - Debug: true, + Chain: "1", + Snapshot: true, Whitelist: map[string]string{ "a": "b", "b": "c", @@ -77,31 +75,29 @@ func TestConfigMerge(t *testing.T) { assert.Equal(t, c0, expected) } -func TestConfigHcl(t *testing.T) { - readConfig := func(data string, format string) *Config { - tmpDir, err := ioutil.TempDir("/tmp", "test-config") +func TestConfigLoadFile(t *testing.T) { + readFile := func(path string) { + config, err := readConfigFile(path) assert.NoError(t, err) - - filename := filepath.Join(tmpDir, "config."+format) - assert.NoError(t, ioutil.WriteFile(filename, []byte(data), 0755)) - - config, err := readConfigFile(filename) - assert.NoError(t, err) - return config + assert.Equal(t, config, &Config{ + DataDir: "./data", + P2P: &P2PConfig{ + MaxPeers: 30, + }, + TxPool: &TxPoolConfig{ + LifeTime: time.Duration(1 * time.Second), + }, + Cache: &CacheConfig{}, + }) } - cfg := `{ - "datadir": "datadir", - "p2p": { - "max_peers": 30 - } - }` - config := readConfig(cfg, "json") - assert.Equal(t, config, &Config{ - DataDir: "datadir", - P2P: &P2PConfig{ - MaxPeers: 30, - }, + // read file in hcl format + t.Run("hcl", func(t *testing.T) { + readFile("./testdata/simple.hcl") + }) + // read file in json format + t.Run("json", func(t *testing.T) { + readFile("./testdata/simple.json") }) } diff --git a/command/server/flags.go b/command/server/flags.go index 5f4e88e6a6..98ab599f2f 100644 --- a/command/server/flags.go +++ b/command/server/flags.go @@ -9,11 +9,6 @@ func (c *Command) Flags() *flagset.Flagset { f := flagset.NewFlagSet("server") - f.BoolFlag(&flagset.BoolFlag{ - Name: "debug", - Usage: "Path of the file to apply", - Value: &c.cliConfig.Debug, - }) f.StringFlag(&flagset.StringFlag{ Name: "chain", Usage: "Name of the chain to sync", @@ -364,63 +359,63 @@ func (c *Command) Flags() *flagset.Flagset { f.BoolFlag(&flagset.BoolFlag{ Name: "metrics", Usage: "Enable metrics collection and reporting", - Value: &c.cliConfig.Metrics.Enabled, + Value: &c.cliConfig.Telemetry.Enabled, }) f.BoolFlag(&flagset.BoolFlag{ Name: "metrics.expensive", Usage: "Enable expensive metrics collection and reporting", - Value: &c.cliConfig.Metrics.Expensive, + Value: &c.cliConfig.Telemetry.Expensive, }) f.BoolFlag(&flagset.BoolFlag{ Name: "metrics.influxdb", Usage: "Enable metrics export/push to an external InfluxDB database (v1)", - Value: &c.cliConfig.Metrics.InfluxDB.V1Enabled, + Value: &c.cliConfig.Telemetry.InfluxDB.V1Enabled, }) f.StringFlag(&flagset.StringFlag{ Name: "metrics.influxdb.endpoint", Usage: "InfluxDB API endpoint to report metrics to", - Value: &c.cliConfig.Metrics.InfluxDB.Endpoint, + Value: &c.cliConfig.Telemetry.InfluxDB.Endpoint, }) f.StringFlag(&flagset.StringFlag{ Name: "metrics.influxdb.database", Usage: "InfluxDB database name to push reported metrics to", - Value: &c.cliConfig.Metrics.InfluxDB.Database, + Value: &c.cliConfig.Telemetry.InfluxDB.Database, }) f.StringFlag(&flagset.StringFlag{ Name: "metrics.influxdb.username", Usage: "Username to authorize access to the database", - Value: &c.cliConfig.Metrics.InfluxDB.Username, + Value: &c.cliConfig.Telemetry.InfluxDB.Username, }) f.StringFlag(&flagset.StringFlag{ Name: "metrics.influxdb.password", Usage: "Password to authorize access to the database", - Value: &c.cliConfig.Metrics.InfluxDB.Password, + Value: &c.cliConfig.Telemetry.InfluxDB.Password, }) f.MapStringFlag(&flagset.MapStringFlag{ Name: "metrics.influxdb.tags", Usage: "Comma-separated InfluxDB tags (key/values) attached to all measurements", - Value: &c.cliConfig.Metrics.InfluxDB.Tags, + Value: &c.cliConfig.Telemetry.InfluxDB.Tags, }) // influx db v2 f.BoolFlag(&flagset.BoolFlag{ Name: "metrics.influxdbv2", Usage: "Enable metrics export/push to an external InfluxDB v2 database", - Value: &c.cliConfig.Metrics.InfluxDB.V2Enabled, + Value: &c.cliConfig.Telemetry.InfluxDB.V2Enabled, }) f.StringFlag(&flagset.StringFlag{ Name: "metrics.influxdb.token", Usage: "Token to authorize access to the database (v2 only)", - Value: &c.cliConfig.Metrics.InfluxDB.Token, + Value: &c.cliConfig.Telemetry.InfluxDB.Token, }) f.StringFlag(&flagset.StringFlag{ Name: "metrics.influxdb.bucket", Usage: "InfluxDB bucket name to push reported metrics to (v2 only)", - Value: &c.cliConfig.Metrics.InfluxDB.Bucket, + Value: &c.cliConfig.Telemetry.InfluxDB.Bucket, }) f.StringFlag(&flagset.StringFlag{ Name: "metrics.influxdb.organization", Usage: "InfluxDB organization name (v2 only)", - Value: &c.cliConfig.Metrics.InfluxDB.Organization, + Value: &c.cliConfig.Telemetry.InfluxDB.Organization, }) // account diff --git a/command/server/testdata/simple.hcl b/command/server/testdata/simple.hcl new file mode 100644 index 0000000000..2be98feb42 --- /dev/null +++ b/command/server/testdata/simple.hcl @@ -0,0 +1,9 @@ +data-dir = "./data" + +p2p { + max-peers = 30 +} + +txpool { + lifetime = "1s" +} \ No newline at end of file diff --git a/command/server/testdata/simple.json b/command/server/testdata/simple.json new file mode 100644 index 0000000000..9dbf98f515 --- /dev/null +++ b/command/server/testdata/simple.json @@ -0,0 +1,9 @@ +{ + "data-dir": "./data", + "p2p": { + "max-peers": 30 + }, + "txpool": { + "lifetime": "1s" + } +} \ No newline at end of file From 7282cf9c255062b33e71ae84f9e52877fed1b710 Mon Sep 17 00:00:00 2001 From: Ferran Borreguero Date: Mon, 18 Oct 2021 13:23:22 +0200 Subject: [PATCH 14/51] Resolve merge --- Makefile | 3 + command/debug.go | 44 +++++ command/main.go | 46 +++++ command/server/command.go | 224 +------------------------ command/server/config.go | 9 + command/server/flags.go | 7 + command/server/pprof/pprof.go | 36 ++++ command/server/proto/server.pb.go | 143 ++++++++++++++++ command/server/proto/server.proto | 13 ++ command/server/proto/server_grpc.pb.go | 101 +++++++++++ command/server/server.go | 202 ++++++++++++++++++++++ command/server/service.go | 11 ++ go.mod | 2 + go.sum | 16 +- 14 files changed, 636 insertions(+), 221 deletions(-) create mode 100644 command/debug.go create mode 100644 command/server/pprof/pprof.go create mode 100644 command/server/proto/server.pb.go create mode 100644 command/server/proto/server.proto create mode 100644 command/server/proto/server_grpc.pb.go create mode 100644 command/server/server.go create mode 100644 command/server/service.go diff --git a/Makefile b/Makefile index 8a9fbaa0a2..b9bc9db602 100644 --- a/Makefile +++ b/Makefile @@ -13,6 +13,9 @@ GO ?= latest GORUN = env GO111MODULE=on go run GOPATH = $(shell go env GOPATH) +protoc: + protoc --go_out=. --go-grpc_out=. ./command/server/proto/*.proto + bor: $(GORUN) build/ci.go install ./cmd/geth mkdir -p $(GOPATH)/bin/ diff --git a/command/debug.go b/command/debug.go new file mode 100644 index 0000000000..c62f862a99 --- /dev/null +++ b/command/debug.go @@ -0,0 +1,44 @@ +package main + +import ( + "fmt" + + "github.com/ethereum/go-ethereum/command/flagset" +) + +type DebugCommand struct { + *Meta2 +} + +// Help implements the cli.Command interface +func (d *DebugCommand) Help() string { + return `Usage: bor debug + + Debug` +} + +func (d *DebugCommand) Flags() *flagset.Flagset { + return d.NewFlagSet("debug") +} + +// Synopsis implements the cli.Command interface +func (d *DebugCommand) Synopsis() string { + return "Debug" +} + +// Run implements the cli.Command interface +func (d *DebugCommand) Run(args []string) int { + flags := d.Flags() + if err := flags.Parse(args); err != nil { + d.UI.Error(err.Error()) + return 1 + } + + clt, err := d.BorConn() + if err != nil { + d.UI.Error(err.Error()) + return 1 + } + fmt.Println(clt) + return 0 +} diff --git a/command/main.go b/command/main.go index 67b5a004af..702fce9942 100644 --- a/command/main.go +++ b/command/main.go @@ -7,9 +7,11 @@ import ( "github.com/ethereum/go-ethereum/accounts/keystore" "github.com/ethereum/go-ethereum/command/flagset" "github.com/ethereum/go-ethereum/command/server" + "github.com/ethereum/go-ethereum/command/server/proto" "github.com/ethereum/go-ethereum/node" "github.com/mitchellh/cli" "github.com/ryanuber/columnize" + "google.golang.org/grpc" ) func main() { @@ -40,6 +42,9 @@ func commands() map[string]cli.CommandFactory { ErrorWriter: os.Stderr, } + meta2 := &Meta2{ + UI: ui, + } meta := &Meta{ UI: ui, } @@ -54,6 +59,11 @@ func commands() map[string]cli.CommandFactory { UI: ui, }, nil }, + "debug": func() (cli.Command, error) { + return &DebugCommand{ + Meta2: meta2, + }, nil + }, "account": func() (cli.Command, error) { return &Account{ UI: ui, @@ -77,6 +87,42 @@ func commands() map[string]cli.CommandFactory { } } +type Meta2 struct { + UI cli.Ui + + addr string +} + +func (m *Meta2) NewFlagSet(n string) *flagset.Flagset { + f := flagset.NewFlagSet(n) + + f.StringFlag(&flagset.StringFlag{ + Name: "address", + Value: &m.addr, + Usage: "Address of the grpc endpoint", + }) + return f +} + +func (m *Meta2) Conn() (*grpc.ClientConn, error) { + if m.addr == "" { + m.addr = "http://localhost:3131" + } + conn, err := grpc.Dial(m.addr, grpc.WithInsecure()) + if err != nil { + return nil, fmt.Errorf("failed to connect to server: %v", err) + } + return conn, nil +} + +func (m *Meta2) BorConn() (proto.BorClient, error) { + conn, err := m.Conn() + if err != nil { + return nil, err + } + return proto.NewBorClient(conn), nil +} + // Meta is a helper utility for the commands type Meta struct { UI cli.Ui diff --git a/command/server/command.go b/command/server/command.go index 361be1ba09..4b2374dc42 100644 --- a/command/server/command.go +++ b/command/server/command.go @@ -2,27 +2,11 @@ package server import ( "fmt" - "io" - "io/ioutil" "os" "os/signal" - "strings" "syscall" - "time" - "github.com/ethereum/go-ethereum/accounts" - "github.com/ethereum/go-ethereum/accounts/keystore" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/eth" - "github.com/ethereum/go-ethereum/eth/tracers" - "github.com/ethereum/go-ethereum/ethstats" - "github.com/ethereum/go-ethereum/graphql" "github.com/ethereum/go-ethereum/log" - "github.com/ethereum/go-ethereum/metrics" - "github.com/ethereum/go-ethereum/metrics/influxdb" - "github.com/ethereum/go-ethereum/node" - "github.com/mattn/go-colorable" - "github.com/mattn/go-isatty" "github.com/mitchellh/cli" ) @@ -38,8 +22,7 @@ type Command struct { configFile []string - // bor node - node *node.Node + srv *Server } // Help implements the cli.Command interface @@ -82,182 +65,16 @@ func (c *Command) Run(args []string) int { } c.config = config - // start the logger - setupLogger(config.LogLevel) - - // load the chain genesis - if err := config.loadChain(); err != nil { - c.UI.Error(err.Error()) - return 1 - } - - // create the node/stack - nodeCfg, err := config.buildNode() + srv, err := NewServer(config) if err != nil { c.UI.Error(err.Error()) return 1 } - stack, err := node.New(nodeCfg) - if err != nil { - c.UI.Error(err.Error()) - return 1 - } - c.node = stack + c.srv = srv - // register the ethereum backend - ethCfg, err := config.buildEth() - if err != nil { - c.UI.Error(err.Error()) - return 1 - } - backend, err := eth.New(stack, ethCfg) - if err != nil { - c.UI.Error(err.Error()) - return 1 - } - - log.Info("Heimdall setup", "url", ethCfg.HeimdallURL) - - // debug tracing is enabled by default - stack.RegisterAPIs(tracers.APIs(backend.APIBackend)) - - // graphql is started from another place - if config.JsonRPC.Graphql.Enabled { - if err := graphql.New(stack, backend.APIBackend, config.JsonRPC.Cors, config.JsonRPC.Modules); err != nil { - c.UI.Error(fmt.Sprintf("Failed to register the GraphQL service: %v", err)) - return 1 - } - } - - // register ethash service - if config.Ethstats != "" { - if err := ethstats.New(stack, backend.APIBackend, backend.Engine(), config.Ethstats); err != nil { - c.UI.Error(err.Error()) - return 1 - } - } - - // setup account manager (only keystore) - var borKeystore *keystore.KeyStore - { - keydir := stack.KeyStoreDir() - n, p := keystore.StandardScryptN, keystore.StandardScryptP - if config.Accounts.UseLightweightKDF { - n, p = keystore.LightScryptN, keystore.LightScryptP - } - borKeystore = keystore.NewKeyStore(keydir, n, p) - stack.AccountManager().AddBackend(borKeystore) - } - - // unlock accounts if necessary - if len(config.Accounts.Unlock) != 0 { - if err := c.unlockAccounts(borKeystore); err != nil { - c.UI.Error(fmt.Sprintf("failed to unlock: %v", err)) - return 1 - } - } - - // sealing (if enabled) - if config.Sealer.Enabled { - if err := backend.StartMining(1); err != nil { - c.UI.Error(err.Error()) - return 1 - } - } - - if err := c.setupTelemetry(config.Telemetry); err != nil { - c.UI.Error(err.Error()) - return 1 - } - - // start the node - if err := c.node.Start(); err != nil { - c.UI.Error(err.Error()) - return 1 - } return c.handleSignals() } -func (c *Command) unlockAccounts(borKeystore *keystore.KeyStore) error { - // If insecure account unlocking is not allowed if node's APIs are exposed to external. - if !c.node.Config().InsecureUnlockAllowed && c.node.Config().ExtRPCEnabled() { - return fmt.Errorf("account unlock with HTTP access is forbidden") - } - - // read passwords from file if possible - passwords := []string{} - if c.config.Accounts.PasswordFile != "" { - var err error - if passwords, err = readMultilineFile(c.config.Accounts.PasswordFile); err != nil { - return err - } - } - decodePassword := func(addr common.Address, index int) (string, error) { - if len(passwords) > 0 { - if index < len(passwords) { - return passwords[index], nil - } - return passwords[len(passwords)-1], nil - } - // ask for the password - return c.UI.AskSecret(fmt.Sprintf("Please give a password to unlock '%s'", addr.String())) - } - - for index, addrStr := range c.config.Accounts.Unlock { - if !common.IsHexAddress(addrStr) { - return fmt.Errorf("unlock value '%s' is not an address", addrStr) - } - acct := accounts.Account{Address: common.HexToAddress(addrStr)} - - password, err := decodePassword(acct.Address, index) - if err != nil { - return err - } - if err := borKeystore.Unlock(acct, password); err != nil { - return err - } - log.Info("Unlocked account", "address", acct.Address.Hex()) - } - return nil -} - -func (c *Command) setupTelemetry(config *TelemetryConfig) error { - metrics.Enabled = config.Enabled - metrics.EnabledExpensive = config.Expensive - - if !metrics.Enabled { - // metrics are disabled, do not set up any sink - return nil - } - - log.Info("Enabling metrics collection") - - // influxdb - if v1Enabled, v2Enabled := (config.InfluxDB.V1Enabled), (config.InfluxDB.V2Enabled); v1Enabled || v2Enabled { - if v1Enabled && v2Enabled { - return fmt.Errorf("both influx v1 and influx v2 cannot be enabled") - } - - cfg := config.InfluxDB - tags := cfg.Tags - endpoint := cfg.Endpoint - - if v1Enabled { - log.Info("Enabling metrics export to InfluxDB (v1)") - go influxdb.InfluxDBWithTags(metrics.DefaultRegistry, 10*time.Second, endpoint, cfg.Database, cfg.Username, cfg.Password, "geth.", tags) - } - if v2Enabled { - log.Info("Enabling metrics export to InfluxDB (v2)") - go influxdb.InfluxDBV2WithTags(metrics.DefaultRegistry, 10*time.Second, endpoint, cfg.Token, cfg.Bucket, cfg.Organization, "geth.", tags) - } - } - - // Start system runtime metrics collection - go metrics.CollectProcessMetrics(3 * time.Second) - - return nil -} - func (c *Command) handleSignals() int { signalCh := make(chan os.Signal, 4) signal.Notify(signalCh, os.Interrupt, syscall.SIGTERM, syscall.SIGHUP) @@ -269,8 +86,7 @@ func (c *Command) handleSignals() int { gracefulCh := make(chan struct{}) go func() { - c.node.Close() - c.node.Wait() + c.srv.Stop() close(gracefulCh) }() @@ -284,35 +100,3 @@ func (c *Command) handleSignals() int { } return 1 } - -func setupLogger(logLevel string) { - output := io.Writer(os.Stderr) - usecolor := (isatty.IsTerminal(os.Stderr.Fd()) || isatty.IsCygwinTerminal(os.Stderr.Fd())) && os.Getenv("TERM") != "dumb" - if usecolor { - output = colorable.NewColorableStderr() - } - ostream := log.StreamHandler(output, log.TerminalFormat(usecolor)) - glogger := log.NewGlogHandler(ostream) - - // logging - lvl, err := log.LvlFromString(strings.ToLower(logLevel)) - if err == nil { - glogger.Verbosity(lvl) - } else { - glogger.Verbosity(log.LvlInfo) - } - log.Root().SetHandler(glogger) -} - -func readMultilineFile(path string) ([]string, error) { - text, err := ioutil.ReadFile(path) - if err != nil { - return nil, err - } - lines := strings.Split(string(text), "\n") - // Sanitise DOS line endings. - for i := range lines { - lines[i] = strings.TrimRight(lines[i], "\r") - } - return lines, nil -} diff --git a/command/server/config.go b/command/server/config.go index 177983a702..07118dadc0 100644 --- a/command/server/config.go +++ b/command/server/config.go @@ -84,6 +84,8 @@ type Config struct { // Account has the validator account related settings Accounts *AccountsConfig `hcl:"accounts,block"` + + GRPC *GRPCConfig } type P2PConfig struct { @@ -226,6 +228,10 @@ type JsonRPCConfig struct { Graphql *APIConfig `hcl:"graphql,block"` } +type GRPCConfig struct { + Addr string +} + type APIConfig struct { // Enabled selects whether the api is enabled Enabled bool `hcl:"enabled,optional"` @@ -459,6 +465,9 @@ func DefaultConfig() *Config { AllowInsecureUnlock: false, UseLightweightKDF: false, }, + GRPC: &GRPCConfig{ + Addr: ":3131", + }, } } diff --git a/command/server/flags.go b/command/server/flags.go index 98ab599f2f..bd7ac80de3 100644 --- a/command/server/flags.go +++ b/command/server/flags.go @@ -440,5 +440,12 @@ func (c *Command) Flags() *flagset.Flagset { Value: &c.cliConfig.Accounts.UseLightweightKDF, }) + // grpc + f.StringFlag(&flagset.StringFlag{ + Name: "grpc.addr", + Usage: "Address and port to bind the GRPC server", + Value: &c.cliConfig.GRPC.Addr, + }) + return f } diff --git a/command/server/pprof/pprof.go b/command/server/pprof/pprof.go new file mode 100644 index 0000000000..7b25f43743 --- /dev/null +++ b/command/server/pprof/pprof.go @@ -0,0 +1,36 @@ +package pprof + +import ( + "bytes" + "fmt" + "runtime" + "runtime/pprof" +) + +// Profile generates a pprof.Profile report for the given profile name. +func Profile(profile string, debug, gc int) ([]byte, map[string]string, error) { + p := pprof.Lookup(profile) + if p == nil { + return nil, nil, fmt.Errorf("profile '%s' not found", profile) + } + + if profile == "heap" && gc > 0 { + runtime.GC() + } + + var buf bytes.Buffer + if err := p.WriteTo(&buf, debug); err != nil { + return nil, nil, err + } + + headers := map[string]string{ + "X-Content-Type-Options": "nosniff", + } + if debug != 0 { + headers["Content-Type"] = "text/plain; charset=utf-8" + } else { + headers["Content-Type"] = "application/octet-stream" + headers["Content-Disposition"] = fmt.Sprintf(`attachment; filename="%s"`, profile) + } + return buf.Bytes(), headers, nil +} diff --git a/command/server/proto/server.pb.go b/command/server/proto/server.pb.go new file mode 100644 index 0000000000..c2f6c316a3 --- /dev/null +++ b/command/server/proto/server.pb.go @@ -0,0 +1,143 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.25.0 +// protoc v3.12.0 +// source: command/server/proto/server.proto + +package proto + +import ( + proto "github.com/golang/protobuf/proto" + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" + sync "sync" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +// This is a compile-time assertion that a sufficiently up-to-date version +// of the legacy proto package is being used. +const _ = proto.ProtoPackageIsVersion4 + +type DebugInput struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields +} + +func (x *DebugInput) Reset() { + *x = DebugInput{} + if protoimpl.UnsafeEnabled { + mi := &file_command_server_proto_server_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *DebugInput) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*DebugInput) ProtoMessage() {} + +func (x *DebugInput) ProtoReflect() protoreflect.Message { + mi := &file_command_server_proto_server_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use DebugInput.ProtoReflect.Descriptor instead. +func (*DebugInput) Descriptor() ([]byte, []int) { + return file_command_server_proto_server_proto_rawDescGZIP(), []int{0} +} + +var File_command_server_proto_server_proto protoreflect.FileDescriptor + +var file_command_server_proto_server_proto_rawDesc = []byte{ + 0x0a, 0x21, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x2f, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, + 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x12, 0x05, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x0c, 0x0a, 0x0a, 0x44, 0x65, + 0x62, 0x75, 0x67, 0x49, 0x6e, 0x70, 0x75, 0x74, 0x32, 0x34, 0x0a, 0x03, 0x42, 0x6f, 0x72, 0x12, + 0x2d, 0x0a, 0x05, 0x44, 0x65, 0x62, 0x75, 0x67, 0x12, 0x11, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x2e, 0x44, 0x65, 0x62, 0x75, 0x67, 0x49, 0x6e, 0x70, 0x75, 0x74, 0x1a, 0x11, 0x2e, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x2e, 0x44, 0x65, 0x62, 0x75, 0x67, 0x49, 0x6e, 0x70, 0x75, 0x74, 0x42, 0x17, + 0x5a, 0x15, 0x2f, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x2f, 0x73, 0x65, 0x72, 0x76, 0x65, + 0x72, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, +} + +var ( + file_command_server_proto_server_proto_rawDescOnce sync.Once + file_command_server_proto_server_proto_rawDescData = file_command_server_proto_server_proto_rawDesc +) + +func file_command_server_proto_server_proto_rawDescGZIP() []byte { + file_command_server_proto_server_proto_rawDescOnce.Do(func() { + file_command_server_proto_server_proto_rawDescData = protoimpl.X.CompressGZIP(file_command_server_proto_server_proto_rawDescData) + }) + return file_command_server_proto_server_proto_rawDescData +} + +var file_command_server_proto_server_proto_msgTypes = make([]protoimpl.MessageInfo, 1) +var file_command_server_proto_server_proto_goTypes = []interface{}{ + (*DebugInput)(nil), // 0: proto.DebugInput +} +var file_command_server_proto_server_proto_depIdxs = []int32{ + 0, // 0: proto.Bor.Debug:input_type -> proto.DebugInput + 0, // 1: proto.Bor.Debug:output_type -> proto.DebugInput + 1, // [1:2] is the sub-list for method output_type + 0, // [0:1] is the sub-list for method input_type + 0, // [0:0] is the sub-list for extension type_name + 0, // [0:0] is the sub-list for extension extendee + 0, // [0:0] is the sub-list for field type_name +} + +func init() { file_command_server_proto_server_proto_init() } +func file_command_server_proto_server_proto_init() { + if File_command_server_proto_server_proto != nil { + return + } + if !protoimpl.UnsafeEnabled { + file_command_server_proto_server_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*DebugInput); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_command_server_proto_server_proto_rawDesc, + NumEnums: 0, + NumMessages: 1, + NumExtensions: 0, + NumServices: 1, + }, + GoTypes: file_command_server_proto_server_proto_goTypes, + DependencyIndexes: file_command_server_proto_server_proto_depIdxs, + MessageInfos: file_command_server_proto_server_proto_msgTypes, + }.Build() + File_command_server_proto_server_proto = out.File + file_command_server_proto_server_proto_rawDesc = nil + file_command_server_proto_server_proto_goTypes = nil + file_command_server_proto_server_proto_depIdxs = nil +} diff --git a/command/server/proto/server.proto b/command/server/proto/server.proto new file mode 100644 index 0000000000..64972fa155 --- /dev/null +++ b/command/server/proto/server.proto @@ -0,0 +1,13 @@ +syntax = "proto3"; + +package proto; + +option go_package = "/command/server/proto"; + +service Bor { + rpc Debug(DebugInput) returns (DebugInput); +} + +message DebugInput { + +} diff --git a/command/server/proto/server_grpc.pb.go b/command/server/proto/server_grpc.pb.go new file mode 100644 index 0000000000..e23aa7fda5 --- /dev/null +++ b/command/server/proto/server_grpc.pb.go @@ -0,0 +1,101 @@ +// Code generated by protoc-gen-go-grpc. DO NOT EDIT. + +package proto + +import ( + context "context" + grpc "google.golang.org/grpc" + codes "google.golang.org/grpc/codes" + status "google.golang.org/grpc/status" +) + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the grpc package it is being compiled against. +// Requires gRPC-Go v1.32.0 or later. +const _ = grpc.SupportPackageIsVersion7 + +// BorClient is the client API for Bor service. +// +// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. +type BorClient interface { + Debug(ctx context.Context, in *DebugInput, opts ...grpc.CallOption) (*DebugInput, error) +} + +type borClient struct { + cc grpc.ClientConnInterface +} + +func NewBorClient(cc grpc.ClientConnInterface) BorClient { + return &borClient{cc} +} + +func (c *borClient) Debug(ctx context.Context, in *DebugInput, opts ...grpc.CallOption) (*DebugInput, error) { + out := new(DebugInput) + err := c.cc.Invoke(ctx, "/proto.Bor/Debug", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +// BorServer is the server API for Bor service. +// All implementations must embed UnimplementedBorServer +// for forward compatibility +type BorServer interface { + Debug(context.Context, *DebugInput) (*DebugInput, error) + mustEmbedUnimplementedBorServer() +} + +// UnimplementedBorServer must be embedded to have forward compatible implementations. +type UnimplementedBorServer struct { +} + +func (UnimplementedBorServer) Debug(context.Context, *DebugInput) (*DebugInput, error) { + return nil, status.Errorf(codes.Unimplemented, "method Debug not implemented") +} +func (UnimplementedBorServer) mustEmbedUnimplementedBorServer() {} + +// UnsafeBorServer may be embedded to opt out of forward compatibility for this service. +// Use of this interface is not recommended, as added methods to BorServer will +// result in compilation errors. +type UnsafeBorServer interface { + mustEmbedUnimplementedBorServer() +} + +func RegisterBorServer(s grpc.ServiceRegistrar, srv BorServer) { + s.RegisterService(&Bor_ServiceDesc, srv) +} + +func _Bor_Debug_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(DebugInput) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(BorServer).Debug(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/proto.Bor/Debug", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(BorServer).Debug(ctx, req.(*DebugInput)) + } + return interceptor(ctx, in, info, handler) +} + +// Bor_ServiceDesc is the grpc.ServiceDesc for Bor service. +// It's only intended for direct use with grpc.RegisterService, +// and not to be introspected or modified (even as a copy) +var Bor_ServiceDesc = grpc.ServiceDesc{ + ServiceName: "proto.Bor", + HandlerType: (*BorServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "Debug", + Handler: _Bor_Debug_Handler, + }, + }, + Streams: []grpc.StreamDesc{}, + Metadata: "command/server/proto/server.proto", +} diff --git a/command/server/server.go b/command/server/server.go new file mode 100644 index 0000000000..437a39b906 --- /dev/null +++ b/command/server/server.go @@ -0,0 +1,202 @@ +package server + +import ( + "context" + "fmt" + "io" + "net" + "os" + "strings" + "time" + + "github.com/ethereum/go-ethereum/accounts/keystore" + "github.com/ethereum/go-ethereum/command/server/proto" + "github.com/ethereum/go-ethereum/eth" + "github.com/ethereum/go-ethereum/eth/tracers" + "github.com/ethereum/go-ethereum/ethstats" + "github.com/ethereum/go-ethereum/graphql" + "github.com/ethereum/go-ethereum/log" + "github.com/ethereum/go-ethereum/metrics" + "github.com/ethereum/go-ethereum/metrics/influxdb" + "github.com/ethereum/go-ethereum/node" + "github.com/mattn/go-colorable" + "github.com/mattn/go-isatty" + "google.golang.org/grpc" +) + +type Server struct { + proto.UnimplementedBorServer + node *node.Node + grpcServer *grpc.Server +} + +func NewServer(config *Config) (*Server, error) { + srv := &Server{} + + // start the logger + setupLogger(config.LogLevel) + + if err := srv.setupGRPCServer(config.GRPC.Addr); err != nil { + return nil, err + } + + // load the chain genesis + if err := config.loadChain(); err != nil { + return nil, err + } + + // create the node/stack + nodeCfg, err := config.buildNode() + if err != nil { + return nil, err + } + stack, err := node.New(nodeCfg) + if err != nil { + return nil, err + } + srv.node = stack + + // register the ethereum backend + ethCfg, err := config.buildEth() + if err != nil { + return nil, err + } + backend, err := eth.New(stack, ethCfg) + if err != nil { + return nil, err + } + + // debug tracing is enabled by default + stack.RegisterAPIs(tracers.APIs(backend.APIBackend)) + + // graphql is started from another place + if config.JsonRPC.Graphql.Enabled { + if err := graphql.New(stack, backend.APIBackend, config.JsonRPC.Cors, config.JsonRPC.Modules); err != nil { + return nil, fmt.Errorf("failed to register the GraphQL service: %v", err) + } + } + + // register ethash service + if config.Ethstats != "" { + if err := ethstats.New(stack, backend.APIBackend, backend.Engine(), config.Ethstats); err != nil { + return nil, err + } + } + + // setup account manager (only keystore) + { + keydir := stack.KeyStoreDir() + n, p := keystore.StandardScryptN, keystore.StandardScryptP + if config.Accounts.UseLightweightKDF { + n, p = keystore.LightScryptN, keystore.LightScryptP + } + stack.AccountManager().AddBackend(keystore.NewKeyStore(keydir, n, p)) + } + + // sealing (if enabled) + if config.Sealer.Enabled { + if err := backend.StartMining(1); err != nil { + return nil, err + } + } + + if err := srv.setupMetrics(config.Telemetry); err != nil { + return nil, err + } + + // start the node + if err := srv.node.Start(); err != nil { + return nil, err + } + return srv, nil +} + +func (s *Server) Stop() { + s.node.Close() +} + +func (s *Server) setupMetrics(config *TelemetryConfig) error { + metrics.Enabled = config.Enabled + metrics.EnabledExpensive = config.Expensive + + if !metrics.Enabled { + // metrics are disabled, do not set up any sink + return nil + } + + log.Info("Enabling metrics collection") + + // influxdb + if v1Enabled, v2Enabled := config.InfluxDB.V1Enabled, config.InfluxDB.V2Enabled; v1Enabled || v2Enabled { + if v1Enabled && v2Enabled { + return fmt.Errorf("both influx v1 and influx v2 cannot be enabled") + } + + cfg := config.InfluxDB + tags := cfg.Tags + endpoint := cfg.Endpoint + + if v1Enabled { + log.Info("Enabling metrics export to InfluxDB (v1)") + go influxdb.InfluxDBWithTags(metrics.DefaultRegistry, 10*time.Second, endpoint, cfg.Database, cfg.Username, cfg.Password, "geth.", tags) + } + if v2Enabled { + log.Info("Enabling metrics export to InfluxDB (v2)") + go influxdb.InfluxDBV2WithTags(metrics.DefaultRegistry, 10*time.Second, endpoint, cfg.Token, cfg.Bucket, cfg.Organization, "geth.", tags) + } + } + + // Start system runtime metrics collection + go metrics.CollectProcessMetrics(3 * time.Second) + + return nil +} + +func (s *Server) setupGRPCServer(addr string) error { + s.grpcServer = grpc.NewServer(s.withLoggingUnaryInterceptor()) + proto.RegisterBorServer(s.grpcServer, s) + + lis, err := net.Listen("tcp", addr) + if err != nil { + return err + } + + go func() { + if err := s.grpcServer.Serve(lis); err != nil { + log.Error("failed to serve grpc server", "err", err) + } + }() + + log.Info("GRPC Server started", "addr", addr) + return nil +} + +func (s *Server) withLoggingUnaryInterceptor() grpc.ServerOption { + return grpc.UnaryInterceptor(s.loggingServerInterceptor) +} + +func (s *Server) loggingServerInterceptor(ctx context.Context, req interface{}, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (interface{}, error) { + start := time.Now() + h, err := handler(ctx, req) + log.Trace("Request", "method", info.FullMethod, "duration", time.Since(start), "error", err) + return h, err +} + +func setupLogger(logLevel string) { + output := io.Writer(os.Stderr) + usecolor := (isatty.IsTerminal(os.Stderr.Fd()) || isatty.IsCygwinTerminal(os.Stderr.Fd())) && os.Getenv("TERM") != "dumb" + if usecolor { + output = colorable.NewColorableStderr() + } + ostream := log.StreamHandler(output, log.TerminalFormat(usecolor)) + glogger := log.NewGlogHandler(ostream) + + // logging + lvl, err := log.LvlFromString(strings.ToLower(logLevel)) + if err == nil { + glogger.Verbosity(lvl) + } else { + glogger.Verbosity(log.LvlInfo) + } + log.Root().SetHandler(glogger) +} diff --git a/command/server/service.go b/command/server/service.go new file mode 100644 index 0000000000..f6a41281b0 --- /dev/null +++ b/command/server/service.go @@ -0,0 +1,11 @@ +package server + +import ( + "context" + + "github.com/ethereum/go-ethereum/command/server/proto" +) + +func (s *Server) Debug(ctx context.Context, req *proto.DebugInput) (*proto.DebugInput, error) { + return &proto.DebugInput{}, nil +} diff --git a/go.mod b/go.mod index 7a2ed24783..ee79f9b222 100644 --- a/go.mod +++ b/go.mod @@ -74,6 +74,8 @@ require ( golang.org/x/sys v0.0.0-20210816183151-1e6c022a8912 golang.org/x/text v0.3.6 golang.org/x/time v0.0.0-20210220033141-f8bda1e9f3ba + google.golang.org/grpc v1.37.0 + google.golang.org/protobuf v1.25.0 gopkg.in/natefinch/npipe.v2 v2.0.0-20160621034901-c1b8fa8bdcce gopkg.in/olebedev/go-duktape.v3 v3.0.0-20200619000410-60c24ae608a6 gopkg.in/urfave/cli.v1 v1.20.0 diff --git a/go.sum b/go.sum index cdb8050f37..a8b1df8e13 100644 --- a/go.sum +++ b/go.sum @@ -116,6 +116,7 @@ github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMn github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/cloudflare/cloudflare-go v0.14.0 h1:gFqGlGl/5f9UGXAaKapCGUfaTCgRKKnzu2VvzMZlOFA= github.com/cloudflare/cloudflare-go v0.14.0/go.mod h1:EnwdgGMaFOruiPZRFSgn+TsQ3hQ7C/YWzIGLeu5c304= +github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= github.com/consensys/bavard v0.1.8-0.20210406032232-f3452dc9b572/go.mod h1:Bpd0/3mZuaj6Sj+PqrmIquiOKy397AKGThQPaGzNXAQ= github.com/consensys/gnark-crypto v0.4.1-0.20210426202927-39ac3d4b3f1f h1:C43yEtQ6NIf4ftFXD/V55gnGFgPbMQobd//YlnLjUJ8= github.com/consensys/gnark-crypto v0.4.1-0.20210426202927-39ac3d4b3f1f/go.mod h1:815PAHg3wvysy0SyIqanF8gZ0Y1wjk/hrDHD/iT88+Q= @@ -144,7 +145,9 @@ github.com/dop251/goja v0.0.0-20200721192441-a695b0cdd498/go.mod h1:Mw6PkjjMXWbT github.com/eclipse/paho.mqtt.golang v1.2.0/go.mod h1:H9keYFcgq3Qr5OUJm/JZI/i6U7joQ8SYLhZwfeOo6Ts= github.com/edsrzf/mmap-go v1.0.0 h1:CEBF7HpRnUCSJgGUb5h1Gm7e3VkmVDrR8lvWVLtrOFw= github.com/edsrzf/mmap-go v1.0.0/go.mod h1:YO35OhQPt3KJa3ryjFM5Bs14WD66h8eGKpfaBNrHW5M= +github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= +github.com/envoyproxy/go-control-plane v0.9.9-0.20210217033140-668b12f5399d/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= github.com/fatih/color v1.7.0 h1:DkWD4oS2D8LGGgTQ6IvwJJXSL5Vp2ffcQg58nFV38Ys= github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= @@ -201,6 +204,7 @@ github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:x github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= +github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golang/protobuf v1.4.3 h1:JjCZWpVbqXDqFVmTfYWEVTMIYrL/NPdPSCHPJ0T/raM= github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= @@ -217,6 +221,7 @@ github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMyw github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.4 h1:L8R9j+yAqZuZjsqh/z+F1NCffTKKLShY6zXTItVIZ8M= github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/gofuzz v1.1.1-0.20200604201612-c04b05f3adfa h1:Q75Upo5UN4JbPFURXZ8nLKYUvF85dyFRop/vQ0Rv+64= @@ -672,18 +677,27 @@ google.golang.org/genproto v0.0.0-20191115194625-c23dd37a84c9/go.mod h1:n3cpQtvx google.golang.org/genproto v0.0.0-20191216164720-4f79533eabd1/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= google.golang.org/genproto v0.0.0-20191230161307-f3c370f40bfb/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= google.golang.org/genproto v0.0.0-20200108215221-bd8f9a0ef82f/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013 h1:+kGHl1aib/qcwaRi1CbqBZ1rk19r85MNUf8HaBghugY= +google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= +google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= +google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= +google.golang.org/grpc v1.37.0 h1:uSZWeQJX5j11bIQ4AJoj+McDBo29cY1MCoC1wO3ts+c= +google.golang.org/grpc v1.37.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= -google.golang.org/protobuf v1.23.0 h1:4MY060fB1DLGMB/7MBTLnwQUY6+F09GEiz6SsrNqyzM= +google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.25.0 h1:Ejskq+SyPohKW+1uil0JJMtmHCgJPJ/qWTxr8qp+R4c= +google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY= From 2c9b2c31dc217ee5cfc559005c7f9571b4d7b392 Mon Sep 17 00:00:00 2001 From: Ferran Borreguero Date: Mon, 18 Oct 2021 14:24:46 +0200 Subject: [PATCH 15/51] Add grpc server + debug endpoint --- .gitignore | 1 + command/debug.go | 197 +++++++++++++++++++++- command/main.go | 2 +- command/server/pprof/pprof.go | 57 +++++++ command/server/proto/server.pb.go | 222 ++++++++++++++++++++++--- command/server/proto/server.proto | 19 ++- command/server/proto/server_grpc.pb.go | 28 ++-- command/server/service.go | 26 ++- 8 files changed, 504 insertions(+), 48 deletions(-) diff --git a/.gitignore b/.gitignore index 15ccd00ed0..a56d252322 100644 --- a/.gitignore +++ b/.gitignore @@ -48,3 +48,4 @@ profile.cov **/yarn-error.log ./test +./bor-debug-* diff --git a/command/debug.go b/command/debug.go index c62f862a99..0168bb74a7 100644 --- a/command/debug.go +++ b/command/debug.go @@ -1,13 +1,29 @@ package main import ( + "archive/tar" + "compress/gzip" + "context" + "encoding/hex" "fmt" + "io" + "io/ioutil" + "os" + "os/signal" + "path/filepath" + "strings" + "syscall" + "time" "github.com/ethereum/go-ethereum/command/flagset" + "github.com/ethereum/go-ethereum/command/server/proto" ) type DebugCommand struct { *Meta2 + + seconds uint64 + output string } // Help implements the cli.Command interface @@ -18,7 +34,20 @@ func (d *DebugCommand) Help() string { } func (d *DebugCommand) Flags() *flagset.Flagset { - return d.NewFlagSet("debug") + flags := d.NewFlagSet("debug") + + flags.Uint64Flag(&flagset.Uint64Flag{ + Name: "seconds", + Usage: "seconds to trace", + Value: &d.seconds, + }) + flags.StringFlag(&flagset.StringFlag{ + Name: "output", + Value: &d.output, + Usage: "Output directory", + }) + + return flags } // Synopsis implements the cli.Command interface @@ -39,6 +68,170 @@ func (d *DebugCommand) Run(args []string) int { d.UI.Error(err.Error()) return 1 } - fmt.Println(clt) + + stamped := "bor-debug-" + time.Now().UTC().Format("2006-01-02-150405Z") + + // Create the output directory + var tmp string + if d.output != "" { + // User specified output directory + tmp = filepath.Join(d.output, stamped) + _, err := os.Stat(tmp) + if !os.IsNotExist(err) { + d.UI.Error("Output directory already exists") + return 1 + } + } else { + // Generate temp directory + tmp, err = ioutil.TempDir(os.TempDir(), stamped) + if err != nil { + d.UI.Error(fmt.Sprintf("Error creating tmp directory: %s", err.Error())) + return 1 + } + defer os.RemoveAll(tmp) + } + + d.UI.Output("Starting debugger...") + d.UI.Output("") + + // ensure destine folder exists + if err := os.MkdirAll(tmp, os.ModePerm); err != nil { + d.UI.Error(fmt.Sprintf("failed to create parent directory: %v", err)) + return 1 + } + + pprofProfile := func(ctx context.Context, profile string, filename string) error { + req := &proto.PprofRequest{ + Seconds: int64(d.seconds), + } + switch profile { + case "cpu": + req.Type = proto.PprofRequest_CPU + case "trace": + req.Type = proto.PprofRequest_TRACE + default: + req.Type = proto.PprofRequest_LOOKUP + req.Profile = profile + } + resp, err := clt.Pprof(ctx, req) + if err != nil { + return err + } + // write file + raw, err := hex.DecodeString(resp.Payload) + if err != nil { + return err + } + if err := ioutil.WriteFile(filepath.Join(tmp, filename+".prof"), raw, 0755); err != nil { + return err + } + return nil + } + + ctx, cancelFn := context.WithCancel(context.Background()) + trapSignal(cancelFn) + + profiles := map[string]string{ + "heap": "heap", + "cpu": "cpu", + "trace": "trace", + } + for profile, filename := range profiles { + if err := pprofProfile(ctx, profile, filename); err != nil { + d.UI.Error(fmt.Sprintf("Error creating profile '%s': %v", profile, err)) + return 1 + } + } + + // Exit before archive if output directory was specified + if d.output != "" { + d.UI.Output(fmt.Sprintf("Created debug directory: %s", tmp)) + return 0 + } + + // Create archive tarball + archiveFile := stamped + ".tar.gz" + if err = tarCZF(archiveFile, tmp, stamped); err != nil { + d.UI.Error(fmt.Sprintf("Error creating archive: %s", err.Error())) + return 1 + } + + d.UI.Output(fmt.Sprintf("Created debug archive: %s", archiveFile)) return 0 } + +func trapSignal(cancel func()) { + sigCh := make(chan os.Signal, 1) + signal.Notify(sigCh, + syscall.SIGHUP, + syscall.SIGINT, + syscall.SIGTERM, + syscall.SIGQUIT) + + go func() { + <-sigCh + cancel() + }() +} + +func tarCZF(archive string, src, target string) error { + // ensure the src actually exists before trying to tar it + if _, err := os.Stat(src); err != nil { + return fmt.Errorf("unable to tar files - %v", err.Error()) + } + + // create the archive + fh, err := os.Create(archive) + if err != nil { + return err + } + defer fh.Close() + + zz := gzip.NewWriter(fh) + defer zz.Close() + + tw := tar.NewWriter(zz) + defer tw.Close() + + // tar + return filepath.Walk(src, func(file string, fi os.FileInfo, err error) error { + // return on any error + if err != nil { + return err + } + if !fi.Mode().IsRegular() { + return nil + } + + header, err := tar.FileInfoHeader(fi, fi.Name()) + if err != nil { + return err + } + + // remove leading path to the src, so files are relative to the archive + path := strings.ReplaceAll(file, src, "") + if target != "" { + path = filepath.Join([]string{target, path}...) + } + path = strings.TrimPrefix(path, string(filepath.Separator)) + + header.Name = path + + if err := tw.WriteHeader(header); err != nil { + return err + } + + // copy the file contents + f, err := os.Open(file) + if err != nil { + return err + } + + if _, err := io.Copy(tw, f); err != nil { + return err + } + + f.Close() + return nil + }) +} diff --git a/command/main.go b/command/main.go index 702fce9942..0fd3890830 100644 --- a/command/main.go +++ b/command/main.go @@ -106,7 +106,7 @@ func (m *Meta2) NewFlagSet(n string) *flagset.Flagset { func (m *Meta2) Conn() (*grpc.ClientConn, error) { if m.addr == "" { - m.addr = "http://localhost:3131" + m.addr = "127.0.0.1:3131" } conn, err := grpc.Dial(m.addr, grpc.WithInsecure()) if err != nil { diff --git a/command/server/pprof/pprof.go b/command/server/pprof/pprof.go index 7b25f43743..44034f3bb8 100644 --- a/command/server/pprof/pprof.go +++ b/command/server/pprof/pprof.go @@ -2,9 +2,12 @@ package pprof import ( "bytes" + "context" "fmt" "runtime" "runtime/pprof" + "runtime/trace" + "time" ) // Profile generates a pprof.Profile report for the given profile name. @@ -34,3 +37,57 @@ func Profile(profile string, debug, gc int) ([]byte, map[string]string, error) { } return buf.Bytes(), headers, nil } + +// CPUProfile generates a CPU Profile for a given duration +func CPUProfile(ctx context.Context, sec int) ([]byte, map[string]string, error) { + if sec <= 0 { + sec = 1 + } + + var buf bytes.Buffer + if err := pprof.StartCPUProfile(&buf); err != nil { + return nil, nil, err + } + + sleep(ctx, time.Duration(sec)*time.Second) + + pprof.StopCPUProfile() + + return buf.Bytes(), + map[string]string{ + "X-Content-Type-Options": "nosniff", + "Content-Type": "application/octet-stream", + "Content-Disposition": `attachment; filename="profile"`, + }, nil +} + +// Trace runs a trace profile for a given duration +func Trace(ctx context.Context, sec int) ([]byte, map[string]string, error) { + if sec <= 0 { + sec = 1 + } + + var buf bytes.Buffer + if err := trace.Start(&buf); err != nil { + return nil, nil, err + } + + sleep(ctx, time.Duration(sec)*time.Second) + + trace.Stop() + + return buf.Bytes(), + map[string]string{ + "X-Content-Type-Options": "nosniff", + "Content-Type": "application/octet-stream", + "Content-Disposition": `attachment; filename="trace"`, + }, nil +} + +func sleep(ctx context.Context, d time.Duration) { + // Sleep until duration is met or ctx is cancelled + select { + case <-time.After(d): + case <-ctx.Done(): + } +} diff --git a/command/server/proto/server.pb.go b/command/server/proto/server.pb.go index c2f6c316a3..87ace6509a 100644 --- a/command/server/proto/server.pb.go +++ b/command/server/proto/server.pb.go @@ -25,14 +25,67 @@ const ( // of the legacy proto package is being used. const _ = proto.ProtoPackageIsVersion4 -type DebugInput struct { +type PprofRequest_Type int32 + +const ( + PprofRequest_LOOKUP PprofRequest_Type = 0 + PprofRequest_CPU PprofRequest_Type = 1 + PprofRequest_TRACE PprofRequest_Type = 2 +) + +// Enum value maps for PprofRequest_Type. +var ( + PprofRequest_Type_name = map[int32]string{ + 0: "LOOKUP", + 1: "CPU", + 2: "TRACE", + } + PprofRequest_Type_value = map[string]int32{ + "LOOKUP": 0, + "CPU": 1, + "TRACE": 2, + } +) + +func (x PprofRequest_Type) Enum() *PprofRequest_Type { + p := new(PprofRequest_Type) + *p = x + return p +} + +func (x PprofRequest_Type) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (PprofRequest_Type) Descriptor() protoreflect.EnumDescriptor { + return file_command_server_proto_server_proto_enumTypes[0].Descriptor() +} + +func (PprofRequest_Type) Type() protoreflect.EnumType { + return &file_command_server_proto_server_proto_enumTypes[0] +} + +func (x PprofRequest_Type) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use PprofRequest_Type.Descriptor instead. +func (PprofRequest_Type) EnumDescriptor() ([]byte, []int) { + return file_command_server_proto_server_proto_rawDescGZIP(), []int{0, 0} +} + +type PprofRequest struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields + + Type PprofRequest_Type `protobuf:"varint,1,opt,name=type,proto3,enum=proto.PprofRequest_Type" json:"type,omitempty"` + Profile string `protobuf:"bytes,2,opt,name=profile,proto3" json:"profile,omitempty"` + Seconds int64 `protobuf:"varint,3,opt,name=seconds,proto3" json:"seconds,omitempty"` } -func (x *DebugInput) Reset() { - *x = DebugInput{} +func (x *PprofRequest) Reset() { + *x = PprofRequest{} if protoimpl.UnsafeEnabled { mi := &file_command_server_proto_server_proto_msgTypes[0] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) @@ -40,13 +93,13 @@ func (x *DebugInput) Reset() { } } -func (x *DebugInput) String() string { +func (x *PprofRequest) String() string { return protoimpl.X.MessageStringOf(x) } -func (*DebugInput) ProtoMessage() {} +func (*PprofRequest) ProtoMessage() {} -func (x *DebugInput) ProtoReflect() protoreflect.Message { +func (x *PprofRequest) ProtoReflect() protoreflect.Message { mi := &file_command_server_proto_server_proto_msgTypes[0] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) @@ -58,23 +111,119 @@ func (x *DebugInput) ProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -// Deprecated: Use DebugInput.ProtoReflect.Descriptor instead. -func (*DebugInput) Descriptor() ([]byte, []int) { +// Deprecated: Use PprofRequest.ProtoReflect.Descriptor instead. +func (*PprofRequest) Descriptor() ([]byte, []int) { return file_command_server_proto_server_proto_rawDescGZIP(), []int{0} } +func (x *PprofRequest) GetType() PprofRequest_Type { + if x != nil { + return x.Type + } + return PprofRequest_LOOKUP +} + +func (x *PprofRequest) GetProfile() string { + if x != nil { + return x.Profile + } + return "" +} + +func (x *PprofRequest) GetSeconds() int64 { + if x != nil { + return x.Seconds + } + return 0 +} + +type PprofResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Payload string `protobuf:"bytes,1,opt,name=payload,proto3" json:"payload,omitempty"` + Headers map[string]string `protobuf:"bytes,2,rep,name=headers,proto3" json:"headers,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` +} + +func (x *PprofResponse) Reset() { + *x = PprofResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_command_server_proto_server_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *PprofResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*PprofResponse) ProtoMessage() {} + +func (x *PprofResponse) ProtoReflect() protoreflect.Message { + mi := &file_command_server_proto_server_proto_msgTypes[1] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use PprofResponse.ProtoReflect.Descriptor instead. +func (*PprofResponse) Descriptor() ([]byte, []int) { + return file_command_server_proto_server_proto_rawDescGZIP(), []int{1} +} + +func (x *PprofResponse) GetPayload() string { + if x != nil { + return x.Payload + } + return "" +} + +func (x *PprofResponse) GetHeaders() map[string]string { + if x != nil { + return x.Headers + } + return nil +} + var File_command_server_proto_server_proto protoreflect.FileDescriptor var file_command_server_proto_server_proto_rawDesc = []byte{ 0x0a, 0x21, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x2f, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x70, 0x72, - 0x6f, 0x74, 0x6f, 0x12, 0x05, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x0c, 0x0a, 0x0a, 0x44, 0x65, - 0x62, 0x75, 0x67, 0x49, 0x6e, 0x70, 0x75, 0x74, 0x32, 0x34, 0x0a, 0x03, 0x42, 0x6f, 0x72, 0x12, - 0x2d, 0x0a, 0x05, 0x44, 0x65, 0x62, 0x75, 0x67, 0x12, 0x11, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x2e, 0x44, 0x65, 0x62, 0x75, 0x67, 0x49, 0x6e, 0x70, 0x75, 0x74, 0x1a, 0x11, 0x2e, 0x70, 0x72, - 0x6f, 0x74, 0x6f, 0x2e, 0x44, 0x65, 0x62, 0x75, 0x67, 0x49, 0x6e, 0x70, 0x75, 0x74, 0x42, 0x17, - 0x5a, 0x15, 0x2f, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x2f, 0x73, 0x65, 0x72, 0x76, 0x65, - 0x72, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x6f, 0x74, 0x6f, 0x12, 0x05, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x98, 0x01, 0x0a, 0x0c, 0x50, + 0x70, 0x72, 0x6f, 0x66, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x2c, 0x0a, 0x04, 0x74, + 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x18, 0x2e, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x2e, 0x50, 0x70, 0x72, 0x6f, 0x66, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x2e, 0x54, + 0x79, 0x70, 0x65, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x70, 0x72, 0x6f, + 0x66, 0x69, 0x6c, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x70, 0x72, 0x6f, 0x66, + 0x69, 0x6c, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x73, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x73, 0x18, 0x03, + 0x20, 0x01, 0x28, 0x03, 0x52, 0x07, 0x73, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x73, 0x22, 0x26, 0x0a, + 0x04, 0x54, 0x79, 0x70, 0x65, 0x12, 0x0a, 0x0a, 0x06, 0x4c, 0x4f, 0x4f, 0x4b, 0x55, 0x50, 0x10, + 0x00, 0x12, 0x07, 0x0a, 0x03, 0x43, 0x50, 0x55, 0x10, 0x01, 0x12, 0x09, 0x0a, 0x05, 0x54, 0x52, + 0x41, 0x43, 0x45, 0x10, 0x02, 0x22, 0xa2, 0x01, 0x0a, 0x0d, 0x50, 0x70, 0x72, 0x6f, 0x66, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x70, 0x61, 0x79, 0x6c, 0x6f, + 0x61, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61, + 0x64, 0x12, 0x3b, 0x0a, 0x07, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x73, 0x18, 0x02, 0x20, 0x03, + 0x28, 0x0b, 0x32, 0x21, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x50, 0x70, 0x72, 0x6f, 0x66, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x73, + 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x07, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x73, 0x1a, 0x3a, + 0x0a, 0x0c, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, + 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, + 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x32, 0x39, 0x0a, 0x03, 0x42, 0x6f, + 0x72, 0x12, 0x32, 0x0a, 0x05, 0x50, 0x70, 0x72, 0x6f, 0x66, 0x12, 0x13, 0x2e, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x2e, 0x50, 0x70, 0x72, 0x6f, 0x66, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, + 0x14, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x50, 0x70, 0x72, 0x6f, 0x66, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x42, 0x17, 0x5a, 0x15, 0x2f, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, + 0x64, 0x2f, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x06, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -89,18 +238,24 @@ func file_command_server_proto_server_proto_rawDescGZIP() []byte { return file_command_server_proto_server_proto_rawDescData } -var file_command_server_proto_server_proto_msgTypes = make([]protoimpl.MessageInfo, 1) +var file_command_server_proto_server_proto_enumTypes = make([]protoimpl.EnumInfo, 1) +var file_command_server_proto_server_proto_msgTypes = make([]protoimpl.MessageInfo, 3) var file_command_server_proto_server_proto_goTypes = []interface{}{ - (*DebugInput)(nil), // 0: proto.DebugInput + (PprofRequest_Type)(0), // 0: proto.PprofRequest.Type + (*PprofRequest)(nil), // 1: proto.PprofRequest + (*PprofResponse)(nil), // 2: proto.PprofResponse + nil, // 3: proto.PprofResponse.HeadersEntry } var file_command_server_proto_server_proto_depIdxs = []int32{ - 0, // 0: proto.Bor.Debug:input_type -> proto.DebugInput - 0, // 1: proto.Bor.Debug:output_type -> proto.DebugInput - 1, // [1:2] is the sub-list for method output_type - 0, // [0:1] is the sub-list for method input_type - 0, // [0:0] is the sub-list for extension type_name - 0, // [0:0] is the sub-list for extension extendee - 0, // [0:0] is the sub-list for field type_name + 0, // 0: proto.PprofRequest.type:type_name -> proto.PprofRequest.Type + 3, // 1: proto.PprofResponse.headers:type_name -> proto.PprofResponse.HeadersEntry + 1, // 2: proto.Bor.Pprof:input_type -> proto.PprofRequest + 2, // 3: proto.Bor.Pprof:output_type -> proto.PprofResponse + 3, // [3:4] is the sub-list for method output_type + 2, // [2:3] is the sub-list for method input_type + 2, // [2:2] is the sub-list for extension type_name + 2, // [2:2] is the sub-list for extension extendee + 0, // [0:2] is the sub-list for field type_name } func init() { file_command_server_proto_server_proto_init() } @@ -110,7 +265,19 @@ func file_command_server_proto_server_proto_init() { } if !protoimpl.UnsafeEnabled { file_command_server_proto_server_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*DebugInput); i { + switch v := v.(*PprofRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_command_server_proto_server_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*PprofResponse); i { case 0: return &v.state case 1: @@ -127,13 +294,14 @@ func file_command_server_proto_server_proto_init() { File: protoimpl.DescBuilder{ GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_command_server_proto_server_proto_rawDesc, - NumEnums: 0, - NumMessages: 1, + NumEnums: 1, + NumMessages: 3, NumExtensions: 0, NumServices: 1, }, GoTypes: file_command_server_proto_server_proto_goTypes, DependencyIndexes: file_command_server_proto_server_proto_depIdxs, + EnumInfos: file_command_server_proto_server_proto_enumTypes, MessageInfos: file_command_server_proto_server_proto_msgTypes, }.Build() File_command_server_proto_server_proto = out.File diff --git a/command/server/proto/server.proto b/command/server/proto/server.proto index 64972fa155..2348e6dd6a 100644 --- a/command/server/proto/server.proto +++ b/command/server/proto/server.proto @@ -5,9 +5,24 @@ package proto; option go_package = "/command/server/proto"; service Bor { - rpc Debug(DebugInput) returns (DebugInput); + rpc Pprof(PprofRequest) returns (PprofResponse); } -message DebugInput { +message PprofRequest { + Type type = 1; + string profile = 2; + + int64 seconds = 3; + + enum Type { + LOOKUP = 0; + CPU = 1; + TRACE = 2; + } +} + +message PprofResponse { + string payload = 1; + map headers = 2; } diff --git a/command/server/proto/server_grpc.pb.go b/command/server/proto/server_grpc.pb.go index e23aa7fda5..1c101f5e85 100644 --- a/command/server/proto/server_grpc.pb.go +++ b/command/server/proto/server_grpc.pb.go @@ -18,7 +18,7 @@ const _ = grpc.SupportPackageIsVersion7 // // For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. type BorClient interface { - Debug(ctx context.Context, in *DebugInput, opts ...grpc.CallOption) (*DebugInput, error) + Pprof(ctx context.Context, in *PprofRequest, opts ...grpc.CallOption) (*PprofResponse, error) } type borClient struct { @@ -29,9 +29,9 @@ func NewBorClient(cc grpc.ClientConnInterface) BorClient { return &borClient{cc} } -func (c *borClient) Debug(ctx context.Context, in *DebugInput, opts ...grpc.CallOption) (*DebugInput, error) { - out := new(DebugInput) - err := c.cc.Invoke(ctx, "/proto.Bor/Debug", in, out, opts...) +func (c *borClient) Pprof(ctx context.Context, in *PprofRequest, opts ...grpc.CallOption) (*PprofResponse, error) { + out := new(PprofResponse) + err := c.cc.Invoke(ctx, "/proto.Bor/Pprof", in, out, opts...) if err != nil { return nil, err } @@ -42,7 +42,7 @@ func (c *borClient) Debug(ctx context.Context, in *DebugInput, opts ...grpc.Call // All implementations must embed UnimplementedBorServer // for forward compatibility type BorServer interface { - Debug(context.Context, *DebugInput) (*DebugInput, error) + Pprof(context.Context, *PprofRequest) (*PprofResponse, error) mustEmbedUnimplementedBorServer() } @@ -50,8 +50,8 @@ type BorServer interface { type UnimplementedBorServer struct { } -func (UnimplementedBorServer) Debug(context.Context, *DebugInput) (*DebugInput, error) { - return nil, status.Errorf(codes.Unimplemented, "method Debug not implemented") +func (UnimplementedBorServer) Pprof(context.Context, *PprofRequest) (*PprofResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method Pprof not implemented") } func (UnimplementedBorServer) mustEmbedUnimplementedBorServer() {} @@ -66,20 +66,20 @@ func RegisterBorServer(s grpc.ServiceRegistrar, srv BorServer) { s.RegisterService(&Bor_ServiceDesc, srv) } -func _Bor_Debug_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(DebugInput) +func _Bor_Pprof_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(PprofRequest) if err := dec(in); err != nil { return nil, err } if interceptor == nil { - return srv.(BorServer).Debug(ctx, in) + return srv.(BorServer).Pprof(ctx, in) } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: "/proto.Bor/Debug", + FullMethod: "/proto.Bor/Pprof", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(BorServer).Debug(ctx, req.(*DebugInput)) + return srv.(BorServer).Pprof(ctx, req.(*PprofRequest)) } return interceptor(ctx, in, info, handler) } @@ -92,8 +92,8 @@ var Bor_ServiceDesc = grpc.ServiceDesc{ HandlerType: (*BorServer)(nil), Methods: []grpc.MethodDesc{ { - MethodName: "Debug", - Handler: _Bor_Debug_Handler, + MethodName: "Pprof", + Handler: _Bor_Pprof_Handler, }, }, Streams: []grpc.StreamDesc{}, diff --git a/command/server/service.go b/command/server/service.go index f6a41281b0..86ab38d5e2 100644 --- a/command/server/service.go +++ b/command/server/service.go @@ -2,10 +2,32 @@ package server import ( "context" + "encoding/hex" + "github.com/ethereum/go-ethereum/command/server/pprof" "github.com/ethereum/go-ethereum/command/server/proto" ) -func (s *Server) Debug(ctx context.Context, req *proto.DebugInput) (*proto.DebugInput, error) { - return &proto.DebugInput{}, nil +func (s *Server) Pprof(ctx context.Context, req *proto.PprofRequest) (*proto.PprofResponse, error) { + var payload []byte + var headers map[string]string + var err error + + switch req.Type { + case proto.PprofRequest_CPU: + payload, headers, err = pprof.CPUProfile(ctx, int(req.Seconds)) + case proto.PprofRequest_TRACE: + payload, headers, err = pprof.Trace(ctx, int(req.Seconds)) + case proto.PprofRequest_LOOKUP: + payload, headers, err = pprof.Profile(req.Profile, 0, 0) + } + if err != nil { + return nil, err + } + + resp := &proto.PprofResponse{ + Payload: hex.EncodeToString(payload), + Headers: headers, + } + return resp, nil } From 6bec5c704bf459c2abdfd4297203a501175003ab Mon Sep 17 00:00:00 2001 From: Ferran Borreguero Date: Mon, 18 Oct 2021 14:33:29 +0200 Subject: [PATCH 16/51] Add cli info --- command/debug.go | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/command/debug.go b/command/debug.go index 0168bb74a7..6914b83864 100644 --- a/command/debug.go +++ b/command/debug.go @@ -1,5 +1,7 @@ package main +// Based on https://github.com/hashicorp/nomad/blob/main/command/operator_debug.go + import ( "archive/tar" "compress/gzip" @@ -30,7 +32,9 @@ type DebugCommand struct { func (d *DebugCommand) Help() string { return `Usage: bor debug - Debug` + Build an archive containing Bor pprof traces + + ` + d.Flags().Help() } func (d *DebugCommand) Flags() *flagset.Flagset { @@ -52,7 +56,7 @@ func (d *DebugCommand) Flags() *flagset.Flagset { // Synopsis implements the cli.Command interface func (d *DebugCommand) Synopsis() string { - return "Debug" + return "Build an archive containing Bor pprof traces" } // Run implements the cli.Command interface From a22a68cdc275c9c240b6501e88de7c64d2aa9c5a Mon Sep 17 00:00:00 2001 From: Ferran Borreguero Date: Mon, 25 Oct 2021 14:07:57 +0200 Subject: [PATCH 17/51] Add comments --- command/server/config.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/command/server/config.go b/command/server/config.go index 07118dadc0..d5fbb49110 100644 --- a/command/server/config.go +++ b/command/server/config.go @@ -85,6 +85,7 @@ type Config struct { // Account has the validator account related settings Accounts *AccountsConfig `hcl:"accounts,block"` + // GRPC has the grpc server related settings GRPC *GRPCConfig } @@ -229,6 +230,7 @@ type JsonRPCConfig struct { } type GRPCConfig struct { + // Addr is the bind address for the grpc rpc server Addr string } From 765a4b93d7f02aec7e8bbe106d43c0498dc576c9 Mon Sep 17 00:00:00 2001 From: Ferran Borreguero Date: Mon, 25 Oct 2021 14:14:58 +0200 Subject: [PATCH 18/51] Add default values --- command/debug.go | 7 ++++--- command/main.go | 10 ++++------ 2 files changed, 8 insertions(+), 9 deletions(-) diff --git a/command/debug.go b/command/debug.go index 6914b83864..b182811053 100644 --- a/command/debug.go +++ b/command/debug.go @@ -41,9 +41,10 @@ func (d *DebugCommand) Flags() *flagset.Flagset { flags := d.NewFlagSet("debug") flags.Uint64Flag(&flagset.Uint64Flag{ - Name: "seconds", - Usage: "seconds to trace", - Value: &d.seconds, + Name: "seconds", + Usage: "seconds to trace", + Value: &d.seconds, + Default: 5, }) flags.StringFlag(&flagset.StringFlag{ Name: "output", diff --git a/command/main.go b/command/main.go index 0fd3890830..c4b9f3887a 100644 --- a/command/main.go +++ b/command/main.go @@ -97,17 +97,15 @@ func (m *Meta2) NewFlagSet(n string) *flagset.Flagset { f := flagset.NewFlagSet(n) f.StringFlag(&flagset.StringFlag{ - Name: "address", - Value: &m.addr, - Usage: "Address of the grpc endpoint", + Name: "address", + Value: &m.addr, + Usage: "Address of the grpc endpoint", + Default: "127.0.0.1:3131", }) return f } func (m *Meta2) Conn() (*grpc.ClientConn, error) { - if m.addr == "" { - m.addr = "127.0.0.1:3131" - } conn, err := grpc.Dial(m.addr, grpc.WithInsecure()) if err != nil { return nil, fmt.Errorf("failed to connect to server: %v", err) From 224f4a803c789f88690a2a003c0144df926e3020 Mon Sep 17 00:00:00 2001 From: Ferran Borreguero Date: Mon, 18 Oct 2021 13:23:22 +0200 Subject: [PATCH 19/51] Resolve merge --- command/server/flags.go | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/command/server/flags.go b/command/server/flags.go index bd7ac80de3..e62a3a5c0b 100644 --- a/command/server/flags.go +++ b/command/server/flags.go @@ -447,5 +447,12 @@ func (c *Command) Flags() *flagset.Flagset { Value: &c.cliConfig.GRPC.Addr, }) + // grpc + f.StringFlag(&flagset.StringFlag{ + Name: "grpc.addr", + Usage: "Address and port to bind the GRPC server", + Value: &c.cliConfig.GRPC.Addr, + }) + return f } From 58702220ac523ee43ba643c0d16c40e24e4f240d Mon Sep 17 00:00:00 2001 From: Ferran Borreguero Date: Tue, 19 Oct 2021 09:11:36 +0200 Subject: [PATCH 20/51] Add peers module --- command/account.go | 6 +- command/main.go | 32 ++ command/peers.go | 43 ++ command/peers_add.go | 72 +++ command/peers_list.go | 81 +++ command/peers_remove.go | 72 +++ command/peers_status.go | 81 +++ command/server/proto/server.pb.go | 729 +++++++++++++++++++++++-- command/server/proto/server.proto | 50 ++ command/server/proto/server_grpc.pb.go | 144 +++++ command/server/service.go | 71 +++ 11 files changed, 1333 insertions(+), 48 deletions(-) create mode 100644 command/peers.go create mode 100644 command/peers_add.go create mode 100644 command/peers_list.go create mode 100644 command/peers_remove.go create mode 100644 command/peers_status.go diff --git a/command/account.go b/command/account.go index 948ab32999..747b6b8dba 100644 --- a/command/account.go +++ b/command/account.go @@ -18,7 +18,11 @@ func (a *Account) Help() string { Display the status of a specific deployment: - $ bor account import` + $ bor account import + + List the imported accounts in the keystore: + + $ bor account list` } // Synopsis implements the cli.Command interface diff --git a/command/main.go b/command/main.go index c4b9f3887a..fab6f55ced 100644 --- a/command/main.go +++ b/command/main.go @@ -84,6 +84,31 @@ func commands() map[string]cli.CommandFactory { Meta: meta, }, nil }, + "peers": func() (cli.Command, error) { + return &PeersCommand{ + UI: ui, + }, nil + }, + "peers add": func() (cli.Command, error) { + return &PeersAddCommand{ + Meta2: meta2, + }, nil + }, + "peers remove": func() (cli.Command, error) { + return &PeersRemoveCommand{ + Meta2: meta2, + }, nil + }, + "peers list": func() (cli.Command, error) { + return &PeersListCommand{ + Meta2: meta2, + }, nil + }, + "peers status": func() (cli.Command, error) { + return &PeersStatusCommand{ + Meta2: meta2, + }, nil + }, } } @@ -173,3 +198,10 @@ func formatList(in []string) string { columnConf.Empty = "" return columnize.Format(in, columnConf) } + +func formatKV(in []string) string { + columnConf := columnize.DefaultConfig() + columnConf.Empty = "" + columnConf.Glue = " = " + return columnize.Format(in, columnConf) +} diff --git a/command/peers.go b/command/peers.go new file mode 100644 index 0000000000..bfe56842d9 --- /dev/null +++ b/command/peers.go @@ -0,0 +1,43 @@ +package main + +import ( + "github.com/mitchellh/cli" +) + +// PeersCommand is the command to group the peers commands +type PeersCommand struct { + UI cli.Ui +} + +// Help implements the cli.Command interface +func (c *PeersCommand) Help() string { + return `Usage: bor peers + + This command groups actions to interact with peers. + + List the connected peers: + + $ bor account new + + Add a new peer by enode: + + $ bor account import + + Remove a connected peer by enode: + + $ bor peers remove + + Display information about a peer: + + $ bor peers status ` +} + +// Synopsis implements the cli.Command interface +func (c *PeersCommand) Synopsis() string { + return "Interact with peers" +} + +// Run implements the cli.Command interface +func (c *PeersCommand) Run(args []string) int { + return cli.RunResultHelp +} diff --git a/command/peers_add.go b/command/peers_add.go new file mode 100644 index 0000000000..796b896681 --- /dev/null +++ b/command/peers_add.go @@ -0,0 +1,72 @@ +package main + +import ( + "context" + + "github.com/ethereum/go-ethereum/command/flagset" + "github.com/ethereum/go-ethereum/command/server/proto" +) + +// PeersAddCommand is the command to group the peers commands +type PeersAddCommand struct { + *Meta2 + + trusted bool +} + +// Help implements the cli.Command interface +func (p *PeersAddCommand) Help() string { + return `Usage: bor peers add + + Joins the local client to another remote peer. + + ` + p.Flags().Help() +} + +func (p *PeersAddCommand) Flags() *flagset.Flagset { + flags := p.NewFlagSet("peers add") + + flags.BoolFlag(&flagset.BoolFlag{ + Name: "trusted", + Usage: "Add the peer as a trusted", + Value: &p.trusted, + }) + + return flags +} + +// Synopsis implements the cli.Command interface +func (c *PeersAddCommand) Synopsis() string { + return "Join the client to a remote peer" +} + +// Run implements the cli.Command interface +func (c *PeersAddCommand) Run(args []string) int { + flags := c.Flags() + if err := flags.Parse(args); err != nil { + c.UI.Error(err.Error()) + return 1 + } + + args = flags.Args() + if len(args) != 1 { + c.UI.Error("No enode address provided") + return 1 + } + + borClt, err := c.BorConn() + if err != nil { + c.UI.Error(err.Error()) + return 1 + } + + req := &proto.PeersAddRequest{ + Enode: args[0], + Trusted: c.trusted, + } + if _, err := borClt.PeersAdd(context.Background(), req); err != nil { + c.UI.Error(err.Error()) + return 1 + } + return 0 +} diff --git a/command/peers_list.go b/command/peers_list.go new file mode 100644 index 0000000000..47e9e4caf0 --- /dev/null +++ b/command/peers_list.go @@ -0,0 +1,81 @@ +package main + +import ( + "context" + "fmt" + "strings" + + "github.com/ethereum/go-ethereum/command/flagset" + "github.com/ethereum/go-ethereum/command/server/proto" +) + +// PeersListCommand is the command to group the peers commands +type PeersListCommand struct { + *Meta2 +} + +// Help implements the cli.Command interface +func (p *PeersListCommand) Help() string { + return `Usage: bor peers list + + Build an archive containing Bor pprof traces + + ` + p.Flags().Help() +} + +func (p *PeersListCommand) Flags() *flagset.Flagset { + flags := p.NewFlagSet("peers list") + + return flags +} + +// Synopsis implements the cli.Command interface +func (c *PeersListCommand) Synopsis() string { + return "" +} + +// Run implements the cli.Command interface +func (c *PeersListCommand) Run(args []string) int { + flags := c.Flags() + if err := flags.Parse(args); err != nil { + c.UI.Error(err.Error()) + return 1 + } + + borClt, err := c.BorConn() + if err != nil { + c.UI.Error(err.Error()) + return 1 + } + + req := &proto.PeersListRequest{} + resp, err := borClt.PeersList(context.Background(), req) + if err != nil { + c.UI.Error(err.Error()) + return 1 + } + + c.UI.Output(formatPeers(resp.Peers)) + return 0 +} + +func formatPeers(peers []*proto.Peer) string { + if len(peers) == 0 { + return "No peers found" + } + + rows := make([]string, len(peers)+1) + rows[0] = "ID|Enode|Name|Caps|Static|Trusted" + for i, d := range peers { + enode := strings.TrimPrefix(d.Enode, "enode://") + + rows[i+1] = fmt.Sprintf("%s|%s|%s|%s|%v|%v", + d.Id, + enode[:10], + d.Name, + strings.Join(d.Caps, ","), + d.Static, + d.Trusted) + } + return formatList(rows) +} diff --git a/command/peers_remove.go b/command/peers_remove.go new file mode 100644 index 0000000000..432a35fdcb --- /dev/null +++ b/command/peers_remove.go @@ -0,0 +1,72 @@ +package main + +import ( + "context" + + "github.com/ethereum/go-ethereum/command/flagset" + "github.com/ethereum/go-ethereum/command/server/proto" +) + +// PeersRemoveCommand is the command to group the peers commands +type PeersRemoveCommand struct { + *Meta2 + + trusted bool +} + +// Help implements the cli.Command interface +func (p *PeersRemoveCommand) Help() string { + return `Usage: bor peers remove + + Disconnects the local client from a connected peer if exists. + + ` + p.Flags().Help() +} + +func (p *PeersRemoveCommand) Flags() *flagset.Flagset { + flags := p.NewFlagSet("peers remove") + + flags.BoolFlag(&flagset.BoolFlag{ + Name: "trusted", + Usage: "Add the peer as a trusted", + Value: &p.trusted, + }) + + return flags +} + +// Synopsis implements the cli.Command interface +func (c *PeersRemoveCommand) Synopsis() string { + return "Disconnects a peer from the client" +} + +// Run implements the cli.Command interface +func (c *PeersRemoveCommand) Run(args []string) int { + flags := c.Flags() + if err := flags.Parse(args); err != nil { + c.UI.Error(err.Error()) + return 1 + } + + args = flags.Args() + if len(args) != 1 { + c.UI.Error("No enode address provided") + return 1 + } + + borClt, err := c.BorConn() + if err != nil { + c.UI.Error(err.Error()) + return 1 + } + + req := &proto.PeersRemoveRequest{ + Enode: args[0], + Trusted: c.trusted, + } + if _, err := borClt.PeersRemove(context.Background(), req); err != nil { + c.UI.Error(err.Error()) + return 1 + } + return 0 +} diff --git a/command/peers_status.go b/command/peers_status.go new file mode 100644 index 0000000000..adb7b2e850 --- /dev/null +++ b/command/peers_status.go @@ -0,0 +1,81 @@ +package main + +import ( + "context" + "fmt" + "strings" + + "github.com/ethereum/go-ethereum/command/flagset" + "github.com/ethereum/go-ethereum/command/server/proto" +) + +// PeersStatusCommand is the command to group the peers commands +type PeersStatusCommand struct { + *Meta2 +} + +// Help implements the cli.Command interface +func (p *PeersStatusCommand) Help() string { + return `Usage: bor peers status + + Display the status of a peer by its id. + + ` + p.Flags().Help() +} + +func (p *PeersStatusCommand) Flags() *flagset.Flagset { + flags := p.NewFlagSet("peers status") + + return flags +} + +// Synopsis implements the cli.Command interface +func (c *PeersStatusCommand) Synopsis() string { + return "Display the status of a peer" +} + +// Run implements the cli.Command interface +func (c *PeersStatusCommand) Run(args []string) int { + flags := c.Flags() + if err := flags.Parse(args); err != nil { + c.UI.Error(err.Error()) + return 1 + } + + args = flags.Args() + if len(args) != 1 { + c.UI.Error("No enode address provided") + return 1 + } + + borClt, err := c.BorConn() + if err != nil { + c.UI.Error(err.Error()) + return 1 + } + + req := &proto.PeersStatusRequest{ + Enode: args[0], + } + resp, err := borClt.PeersStatus(context.Background(), req) + if err != nil { + c.UI.Error(err.Error()) + return 1 + } + + c.UI.Output(formatPeer(resp.Peer)) + return 0 +} + +func formatPeer(peer *proto.Peer) string { + base := formatKV([]string{ + fmt.Sprintf("Name|%s", peer.Name), + fmt.Sprintf("ID|%s", peer.Id), + fmt.Sprintf("ENR|%s", peer.Enr), + fmt.Sprintf("Capabilities|%s", strings.Join(peer.Caps, ",")), + fmt.Sprintf("Enode|%s", peer.Enode), + fmt.Sprintf("Static|%v", peer.Static), + fmt.Sprintf("Trusted|%v", peer.Trusted), + }) + return base +} diff --git a/command/server/proto/server.pb.go b/command/server/proto/server.pb.go index 87ace6509a..a6c13fc7d3 100644 --- a/command/server/proto/server.pb.go +++ b/command/server/proto/server.pb.go @@ -71,7 +71,467 @@ func (x PprofRequest_Type) Number() protoreflect.EnumNumber { // Deprecated: Use PprofRequest_Type.Descriptor instead. func (PprofRequest_Type) EnumDescriptor() ([]byte, []int) { - return file_command_server_proto_server_proto_rawDescGZIP(), []int{0, 0} + return file_command_server_proto_server_proto_rawDescGZIP(), []int{9, 0} +} + +type PeersAddRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Enode string `protobuf:"bytes,1,opt,name=enode,proto3" json:"enode,omitempty"` + Trusted bool `protobuf:"varint,2,opt,name=trusted,proto3" json:"trusted,omitempty"` +} + +func (x *PeersAddRequest) Reset() { + *x = PeersAddRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_command_server_proto_server_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *PeersAddRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*PeersAddRequest) ProtoMessage() {} + +func (x *PeersAddRequest) ProtoReflect() protoreflect.Message { + mi := &file_command_server_proto_server_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use PeersAddRequest.ProtoReflect.Descriptor instead. +func (*PeersAddRequest) Descriptor() ([]byte, []int) { + return file_command_server_proto_server_proto_rawDescGZIP(), []int{0} +} + +func (x *PeersAddRequest) GetEnode() string { + if x != nil { + return x.Enode + } + return "" +} + +func (x *PeersAddRequest) GetTrusted() bool { + if x != nil { + return x.Trusted + } + return false +} + +type PeersAddResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields +} + +func (x *PeersAddResponse) Reset() { + *x = PeersAddResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_command_server_proto_server_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *PeersAddResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*PeersAddResponse) ProtoMessage() {} + +func (x *PeersAddResponse) ProtoReflect() protoreflect.Message { + mi := &file_command_server_proto_server_proto_msgTypes[1] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use PeersAddResponse.ProtoReflect.Descriptor instead. +func (*PeersAddResponse) Descriptor() ([]byte, []int) { + return file_command_server_proto_server_proto_rawDescGZIP(), []int{1} +} + +type PeersRemoveRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Enode string `protobuf:"bytes,1,opt,name=enode,proto3" json:"enode,omitempty"` + Trusted bool `protobuf:"varint,2,opt,name=trusted,proto3" json:"trusted,omitempty"` +} + +func (x *PeersRemoveRequest) Reset() { + *x = PeersRemoveRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_command_server_proto_server_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *PeersRemoveRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*PeersRemoveRequest) ProtoMessage() {} + +func (x *PeersRemoveRequest) ProtoReflect() protoreflect.Message { + mi := &file_command_server_proto_server_proto_msgTypes[2] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use PeersRemoveRequest.ProtoReflect.Descriptor instead. +func (*PeersRemoveRequest) Descriptor() ([]byte, []int) { + return file_command_server_proto_server_proto_rawDescGZIP(), []int{2} +} + +func (x *PeersRemoveRequest) GetEnode() string { + if x != nil { + return x.Enode + } + return "" +} + +func (x *PeersRemoveRequest) GetTrusted() bool { + if x != nil { + return x.Trusted + } + return false +} + +type PeersRemoveResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields +} + +func (x *PeersRemoveResponse) Reset() { + *x = PeersRemoveResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_command_server_proto_server_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *PeersRemoveResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*PeersRemoveResponse) ProtoMessage() {} + +func (x *PeersRemoveResponse) ProtoReflect() protoreflect.Message { + mi := &file_command_server_proto_server_proto_msgTypes[3] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use PeersRemoveResponse.ProtoReflect.Descriptor instead. +func (*PeersRemoveResponse) Descriptor() ([]byte, []int) { + return file_command_server_proto_server_proto_rawDescGZIP(), []int{3} +} + +type PeersListRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields +} + +func (x *PeersListRequest) Reset() { + *x = PeersListRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_command_server_proto_server_proto_msgTypes[4] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *PeersListRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*PeersListRequest) ProtoMessage() {} + +func (x *PeersListRequest) ProtoReflect() protoreflect.Message { + mi := &file_command_server_proto_server_proto_msgTypes[4] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use PeersListRequest.ProtoReflect.Descriptor instead. +func (*PeersListRequest) Descriptor() ([]byte, []int) { + return file_command_server_proto_server_proto_rawDescGZIP(), []int{4} +} + +type PeersListResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Peers []*Peer `protobuf:"bytes,1,rep,name=peers,proto3" json:"peers,omitempty"` +} + +func (x *PeersListResponse) Reset() { + *x = PeersListResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_command_server_proto_server_proto_msgTypes[5] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *PeersListResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*PeersListResponse) ProtoMessage() {} + +func (x *PeersListResponse) ProtoReflect() protoreflect.Message { + mi := &file_command_server_proto_server_proto_msgTypes[5] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use PeersListResponse.ProtoReflect.Descriptor instead. +func (*PeersListResponse) Descriptor() ([]byte, []int) { + return file_command_server_proto_server_proto_rawDescGZIP(), []int{5} +} + +func (x *PeersListResponse) GetPeers() []*Peer { + if x != nil { + return x.Peers + } + return nil +} + +type PeersStatusRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Enode string `protobuf:"bytes,1,opt,name=enode,proto3" json:"enode,omitempty"` +} + +func (x *PeersStatusRequest) Reset() { + *x = PeersStatusRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_command_server_proto_server_proto_msgTypes[6] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *PeersStatusRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*PeersStatusRequest) ProtoMessage() {} + +func (x *PeersStatusRequest) ProtoReflect() protoreflect.Message { + mi := &file_command_server_proto_server_proto_msgTypes[6] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use PeersStatusRequest.ProtoReflect.Descriptor instead. +func (*PeersStatusRequest) Descriptor() ([]byte, []int) { + return file_command_server_proto_server_proto_rawDescGZIP(), []int{6} +} + +func (x *PeersStatusRequest) GetEnode() string { + if x != nil { + return x.Enode + } + return "" +} + +type PeersStatusResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Peer *Peer `protobuf:"bytes,1,opt,name=peer,proto3" json:"peer,omitempty"` +} + +func (x *PeersStatusResponse) Reset() { + *x = PeersStatusResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_command_server_proto_server_proto_msgTypes[7] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *PeersStatusResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*PeersStatusResponse) ProtoMessage() {} + +func (x *PeersStatusResponse) ProtoReflect() protoreflect.Message { + mi := &file_command_server_proto_server_proto_msgTypes[7] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use PeersStatusResponse.ProtoReflect.Descriptor instead. +func (*PeersStatusResponse) Descriptor() ([]byte, []int) { + return file_command_server_proto_server_proto_rawDescGZIP(), []int{7} +} + +func (x *PeersStatusResponse) GetPeer() *Peer { + if x != nil { + return x.Peer + } + return nil +} + +type Peer struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` + Enode string `protobuf:"bytes,2,opt,name=enode,proto3" json:"enode,omitempty"` + Enr string `protobuf:"bytes,3,opt,name=enr,proto3" json:"enr,omitempty"` + Caps []string `protobuf:"bytes,4,rep,name=caps,proto3" json:"caps,omitempty"` + Name string `protobuf:"bytes,5,opt,name=name,proto3" json:"name,omitempty"` + Trusted bool `protobuf:"varint,6,opt,name=trusted,proto3" json:"trusted,omitempty"` + Static bool `protobuf:"varint,7,opt,name=static,proto3" json:"static,omitempty"` +} + +func (x *Peer) Reset() { + *x = Peer{} + if protoimpl.UnsafeEnabled { + mi := &file_command_server_proto_server_proto_msgTypes[8] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Peer) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Peer) ProtoMessage() {} + +func (x *Peer) ProtoReflect() protoreflect.Message { + mi := &file_command_server_proto_server_proto_msgTypes[8] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Peer.ProtoReflect.Descriptor instead. +func (*Peer) Descriptor() ([]byte, []int) { + return file_command_server_proto_server_proto_rawDescGZIP(), []int{8} +} + +func (x *Peer) GetId() string { + if x != nil { + return x.Id + } + return "" +} + +func (x *Peer) GetEnode() string { + if x != nil { + return x.Enode + } + return "" +} + +func (x *Peer) GetEnr() string { + if x != nil { + return x.Enr + } + return "" +} + +func (x *Peer) GetCaps() []string { + if x != nil { + return x.Caps + } + return nil +} + +func (x *Peer) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +func (x *Peer) GetTrusted() bool { + if x != nil { + return x.Trusted + } + return false +} + +func (x *Peer) GetStatic() bool { + if x != nil { + return x.Static + } + return false } type PprofRequest struct { @@ -87,7 +547,7 @@ type PprofRequest struct { func (x *PprofRequest) Reset() { *x = PprofRequest{} if protoimpl.UnsafeEnabled { - mi := &file_command_server_proto_server_proto_msgTypes[0] + mi := &file_command_server_proto_server_proto_msgTypes[9] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -100,7 +560,7 @@ func (x *PprofRequest) String() string { func (*PprofRequest) ProtoMessage() {} func (x *PprofRequest) ProtoReflect() protoreflect.Message { - mi := &file_command_server_proto_server_proto_msgTypes[0] + mi := &file_command_server_proto_server_proto_msgTypes[9] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -113,7 +573,7 @@ func (x *PprofRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use PprofRequest.ProtoReflect.Descriptor instead. func (*PprofRequest) Descriptor() ([]byte, []int) { - return file_command_server_proto_server_proto_rawDescGZIP(), []int{0} + return file_command_server_proto_server_proto_rawDescGZIP(), []int{9} } func (x *PprofRequest) GetType() PprofRequest_Type { @@ -149,7 +609,7 @@ type PprofResponse struct { func (x *PprofResponse) Reset() { *x = PprofResponse{} if protoimpl.UnsafeEnabled { - mi := &file_command_server_proto_server_proto_msgTypes[1] + mi := &file_command_server_proto_server_proto_msgTypes[10] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -162,7 +622,7 @@ func (x *PprofResponse) String() string { func (*PprofResponse) ProtoMessage() {} func (x *PprofResponse) ProtoReflect() protoreflect.Message { - mi := &file_command_server_proto_server_proto_msgTypes[1] + mi := &file_command_server_proto_server_proto_msgTypes[10] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -175,7 +635,7 @@ func (x *PprofResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use PprofResponse.ProtoReflect.Descriptor instead. func (*PprofResponse) Descriptor() ([]byte, []int) { - return file_command_server_proto_server_proto_rawDescGZIP(), []int{1} + return file_command_server_proto_server_proto_rawDescGZIP(), []int{10} } func (x *PprofResponse) GetPayload() string { @@ -197,33 +657,81 @@ var File_command_server_proto_server_proto protoreflect.FileDescriptor var file_command_server_proto_server_proto_rawDesc = []byte{ 0x0a, 0x21, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x2f, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x70, 0x72, - 0x6f, 0x74, 0x6f, 0x12, 0x05, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x98, 0x01, 0x0a, 0x0c, 0x50, - 0x70, 0x72, 0x6f, 0x66, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x2c, 0x0a, 0x04, 0x74, - 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x18, 0x2e, 0x70, 0x72, 0x6f, 0x74, - 0x6f, 0x2e, 0x50, 0x70, 0x72, 0x6f, 0x66, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x2e, 0x54, - 0x79, 0x70, 0x65, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x70, 0x72, 0x6f, - 0x66, 0x69, 0x6c, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x70, 0x72, 0x6f, 0x66, - 0x69, 0x6c, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x73, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x73, 0x18, 0x03, - 0x20, 0x01, 0x28, 0x03, 0x52, 0x07, 0x73, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x73, 0x22, 0x26, 0x0a, - 0x04, 0x54, 0x79, 0x70, 0x65, 0x12, 0x0a, 0x0a, 0x06, 0x4c, 0x4f, 0x4f, 0x4b, 0x55, 0x50, 0x10, - 0x00, 0x12, 0x07, 0x0a, 0x03, 0x43, 0x50, 0x55, 0x10, 0x01, 0x12, 0x09, 0x0a, 0x05, 0x54, 0x52, - 0x41, 0x43, 0x45, 0x10, 0x02, 0x22, 0xa2, 0x01, 0x0a, 0x0d, 0x50, 0x70, 0x72, 0x6f, 0x66, 0x52, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x70, 0x61, 0x79, 0x6c, 0x6f, - 0x61, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61, - 0x64, 0x12, 0x3b, 0x0a, 0x07, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x73, 0x18, 0x02, 0x20, 0x03, - 0x28, 0x0b, 0x32, 0x21, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x50, 0x70, 0x72, 0x6f, 0x66, - 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x73, - 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x07, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x73, 0x1a, 0x3a, - 0x0a, 0x0c, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, - 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, - 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x32, 0x39, 0x0a, 0x03, 0x42, 0x6f, + 0x6f, 0x74, 0x6f, 0x12, 0x05, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x41, 0x0a, 0x0f, 0x50, 0x65, + 0x65, 0x72, 0x73, 0x41, 0x64, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x14, 0x0a, + 0x05, 0x65, 0x6e, 0x6f, 0x64, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x65, 0x6e, + 0x6f, 0x64, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x74, 0x72, 0x75, 0x73, 0x74, 0x65, 0x64, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x74, 0x72, 0x75, 0x73, 0x74, 0x65, 0x64, 0x22, 0x12, 0x0a, + 0x10, 0x50, 0x65, 0x65, 0x72, 0x73, 0x41, 0x64, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x22, 0x44, 0x0a, 0x12, 0x50, 0x65, 0x65, 0x72, 0x73, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x65, 0x6e, 0x6f, 0x64, 0x65, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x65, 0x6e, 0x6f, 0x64, 0x65, 0x12, 0x18, 0x0a, + 0x07, 0x74, 0x72, 0x75, 0x73, 0x74, 0x65, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, + 0x74, 0x72, 0x75, 0x73, 0x74, 0x65, 0x64, 0x22, 0x15, 0x0a, 0x13, 0x50, 0x65, 0x65, 0x72, 0x73, + 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x12, + 0x0a, 0x10, 0x50, 0x65, 0x65, 0x72, 0x73, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x22, 0x36, 0x0a, 0x11, 0x50, 0x65, 0x65, 0x72, 0x73, 0x4c, 0x69, 0x73, 0x74, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x21, 0x0a, 0x05, 0x70, 0x65, 0x65, 0x72, 0x73, + 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0b, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x50, + 0x65, 0x65, 0x72, 0x52, 0x05, 0x70, 0x65, 0x65, 0x72, 0x73, 0x22, 0x2a, 0x0a, 0x12, 0x50, 0x65, + 0x65, 0x72, 0x73, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x12, 0x14, 0x0a, 0x05, 0x65, 0x6e, 0x6f, 0x64, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x05, 0x65, 0x6e, 0x6f, 0x64, 0x65, 0x22, 0x36, 0x0a, 0x13, 0x50, 0x65, 0x65, 0x72, 0x73, 0x53, + 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1f, 0x0a, + 0x04, 0x70, 0x65, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0b, 0x2e, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x2e, 0x50, 0x65, 0x65, 0x72, 0x52, 0x04, 0x70, 0x65, 0x65, 0x72, 0x22, 0x98, + 0x01, 0x0a, 0x04, 0x50, 0x65, 0x65, 0x72, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x14, 0x0a, 0x05, 0x65, 0x6e, 0x6f, 0x64, 0x65, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x65, 0x6e, 0x6f, 0x64, 0x65, 0x12, 0x10, 0x0a, + 0x03, 0x65, 0x6e, 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x65, 0x6e, 0x72, 0x12, + 0x12, 0x0a, 0x04, 0x63, 0x61, 0x70, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x09, 0x52, 0x04, 0x63, + 0x61, 0x70, 0x73, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x74, 0x72, 0x75, 0x73, 0x74, + 0x65, 0x64, 0x18, 0x06, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x74, 0x72, 0x75, 0x73, 0x74, 0x65, + 0x64, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x69, 0x63, 0x18, 0x07, 0x20, 0x01, 0x28, + 0x08, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x69, 0x63, 0x22, 0x98, 0x01, 0x0a, 0x0c, 0x50, 0x70, + 0x72, 0x6f, 0x66, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x2c, 0x0a, 0x04, 0x74, 0x79, + 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x18, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x2e, 0x50, 0x70, 0x72, 0x6f, 0x66, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x2e, 0x54, 0x79, + 0x70, 0x65, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x70, 0x72, 0x6f, 0x66, + 0x69, 0x6c, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x70, 0x72, 0x6f, 0x66, 0x69, + 0x6c, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x73, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x73, 0x18, 0x03, 0x20, + 0x01, 0x28, 0x03, 0x52, 0x07, 0x73, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x73, 0x22, 0x26, 0x0a, 0x04, + 0x54, 0x79, 0x70, 0x65, 0x12, 0x0a, 0x0a, 0x06, 0x4c, 0x4f, 0x4f, 0x4b, 0x55, 0x50, 0x10, 0x00, + 0x12, 0x07, 0x0a, 0x03, 0x43, 0x50, 0x55, 0x10, 0x01, 0x12, 0x09, 0x0a, 0x05, 0x54, 0x52, 0x41, + 0x43, 0x45, 0x10, 0x02, 0x22, 0xa2, 0x01, 0x0a, 0x0d, 0x50, 0x70, 0x72, 0x6f, 0x66, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61, + 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, + 0x12, 0x3b, 0x0a, 0x07, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, + 0x0b, 0x32, 0x21, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x50, 0x70, 0x72, 0x6f, 0x66, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x73, 0x45, + 0x6e, 0x74, 0x72, 0x79, 0x52, 0x07, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x73, 0x1a, 0x3a, 0x0a, + 0x0c, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, + 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, + 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, + 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x32, 0xc2, 0x02, 0x0a, 0x03, 0x42, 0x6f, 0x72, 0x12, 0x32, 0x0a, 0x05, 0x50, 0x70, 0x72, 0x6f, 0x66, 0x12, 0x13, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x50, 0x70, 0x72, 0x6f, 0x66, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x14, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x50, 0x70, 0x72, 0x6f, 0x66, 0x52, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x42, 0x17, 0x5a, 0x15, 0x2f, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, - 0x64, 0x2f, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x06, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3b, 0x0a, 0x08, 0x50, 0x65, 0x65, 0x72, 0x73, 0x41, 0x64, + 0x64, 0x12, 0x16, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x50, 0x65, 0x65, 0x72, 0x73, 0x41, + 0x64, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x17, 0x2e, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x2e, 0x50, 0x65, 0x65, 0x72, 0x73, 0x41, 0x64, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x12, 0x44, 0x0a, 0x0b, 0x50, 0x65, 0x65, 0x72, 0x73, 0x52, 0x65, 0x6d, 0x6f, 0x76, + 0x65, 0x12, 0x19, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x50, 0x65, 0x65, 0x72, 0x73, 0x52, + 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1a, 0x2e, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x50, 0x65, 0x65, 0x72, 0x73, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3e, 0x0a, 0x09, 0x50, 0x65, 0x65, 0x72, + 0x73, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x17, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x50, 0x65, + 0x65, 0x72, 0x73, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x18, + 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x50, 0x65, 0x65, 0x72, 0x73, 0x4c, 0x69, 0x73, 0x74, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x44, 0x0a, 0x0b, 0x50, 0x65, 0x65, 0x72, + 0x73, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x19, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, + 0x50, 0x65, 0x65, 0x72, 0x73, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x1a, 0x1a, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x50, 0x65, 0x65, 0x72, 0x73, + 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x42, 0x17, + 0x5a, 0x15, 0x2f, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x2f, 0x73, 0x65, 0x72, 0x76, 0x65, + 0x72, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -239,23 +747,42 @@ func file_command_server_proto_server_proto_rawDescGZIP() []byte { } var file_command_server_proto_server_proto_enumTypes = make([]protoimpl.EnumInfo, 1) -var file_command_server_proto_server_proto_msgTypes = make([]protoimpl.MessageInfo, 3) +var file_command_server_proto_server_proto_msgTypes = make([]protoimpl.MessageInfo, 12) var file_command_server_proto_server_proto_goTypes = []interface{}{ - (PprofRequest_Type)(0), // 0: proto.PprofRequest.Type - (*PprofRequest)(nil), // 1: proto.PprofRequest - (*PprofResponse)(nil), // 2: proto.PprofResponse - nil, // 3: proto.PprofResponse.HeadersEntry + (PprofRequest_Type)(0), // 0: proto.PprofRequest.Type + (*PeersAddRequest)(nil), // 1: proto.PeersAddRequest + (*PeersAddResponse)(nil), // 2: proto.PeersAddResponse + (*PeersRemoveRequest)(nil), // 3: proto.PeersRemoveRequest + (*PeersRemoveResponse)(nil), // 4: proto.PeersRemoveResponse + (*PeersListRequest)(nil), // 5: proto.PeersListRequest + (*PeersListResponse)(nil), // 6: proto.PeersListResponse + (*PeersStatusRequest)(nil), // 7: proto.PeersStatusRequest + (*PeersStatusResponse)(nil), // 8: proto.PeersStatusResponse + (*Peer)(nil), // 9: proto.Peer + (*PprofRequest)(nil), // 10: proto.PprofRequest + (*PprofResponse)(nil), // 11: proto.PprofResponse + nil, // 12: proto.PprofResponse.HeadersEntry } var file_command_server_proto_server_proto_depIdxs = []int32{ - 0, // 0: proto.PprofRequest.type:type_name -> proto.PprofRequest.Type - 3, // 1: proto.PprofResponse.headers:type_name -> proto.PprofResponse.HeadersEntry - 1, // 2: proto.Bor.Pprof:input_type -> proto.PprofRequest - 2, // 3: proto.Bor.Pprof:output_type -> proto.PprofResponse - 3, // [3:4] is the sub-list for method output_type - 2, // [2:3] is the sub-list for method input_type - 2, // [2:2] is the sub-list for extension type_name - 2, // [2:2] is the sub-list for extension extendee - 0, // [0:2] is the sub-list for field type_name + 9, // 0: proto.PeersListResponse.peers:type_name -> proto.Peer + 9, // 1: proto.PeersStatusResponse.peer:type_name -> proto.Peer + 0, // 2: proto.PprofRequest.type:type_name -> proto.PprofRequest.Type + 12, // 3: proto.PprofResponse.headers:type_name -> proto.PprofResponse.HeadersEntry + 10, // 4: proto.Bor.Pprof:input_type -> proto.PprofRequest + 1, // 5: proto.Bor.PeersAdd:input_type -> proto.PeersAddRequest + 3, // 6: proto.Bor.PeersRemove:input_type -> proto.PeersRemoveRequest + 5, // 7: proto.Bor.PeersList:input_type -> proto.PeersListRequest + 7, // 8: proto.Bor.PeersStatus:input_type -> proto.PeersStatusRequest + 11, // 9: proto.Bor.Pprof:output_type -> proto.PprofResponse + 2, // 10: proto.Bor.PeersAdd:output_type -> proto.PeersAddResponse + 4, // 11: proto.Bor.PeersRemove:output_type -> proto.PeersRemoveResponse + 6, // 12: proto.Bor.PeersList:output_type -> proto.PeersListResponse + 8, // 13: proto.Bor.PeersStatus:output_type -> proto.PeersStatusResponse + 9, // [9:14] is the sub-list for method output_type + 4, // [4:9] is the sub-list for method input_type + 4, // [4:4] is the sub-list for extension type_name + 4, // [4:4] is the sub-list for extension extendee + 0, // [0:4] is the sub-list for field type_name } func init() { file_command_server_proto_server_proto_init() } @@ -265,7 +792,7 @@ func file_command_server_proto_server_proto_init() { } if !protoimpl.UnsafeEnabled { file_command_server_proto_server_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*PprofRequest); i { + switch v := v.(*PeersAddRequest); i { case 0: return &v.state case 1: @@ -277,6 +804,114 @@ func file_command_server_proto_server_proto_init() { } } file_command_server_proto_server_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*PeersAddResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_command_server_proto_server_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*PeersRemoveRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_command_server_proto_server_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*PeersRemoveResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_command_server_proto_server_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*PeersListRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_command_server_proto_server_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*PeersListResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_command_server_proto_server_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*PeersStatusRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_command_server_proto_server_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*PeersStatusResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_command_server_proto_server_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Peer); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_command_server_proto_server_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*PprofRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_command_server_proto_server_proto_msgTypes[10].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*PprofResponse); i { case 0: return &v.state @@ -295,7 +930,7 @@ func file_command_server_proto_server_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_command_server_proto_server_proto_rawDesc, NumEnums: 1, - NumMessages: 3, + NumMessages: 12, NumExtensions: 0, NumServices: 1, }, diff --git a/command/server/proto/server.proto b/command/server/proto/server.proto index 2348e6dd6a..0d1de7bef6 100644 --- a/command/server/proto/server.proto +++ b/command/server/proto/server.proto @@ -6,6 +6,56 @@ option go_package = "/command/server/proto"; service Bor { rpc Pprof(PprofRequest) returns (PprofResponse); + + rpc PeersAdd(PeersAddRequest) returns (PeersAddResponse); + + rpc PeersRemove(PeersRemoveRequest) returns (PeersRemoveResponse); + + rpc PeersList(PeersListRequest) returns (PeersListResponse); + + rpc PeersStatus(PeersStatusRequest) returns (PeersStatusResponse); +} + + +message PeersAddRequest { + string enode = 1; + bool trusted = 2; +} + +message PeersAddResponse { +} + +message PeersRemoveRequest { + string enode = 1; + bool trusted = 2; +} + +message PeersRemoveResponse { +} + +message PeersListRequest { +} + +message PeersListResponse { + repeated Peer peers = 1; +} + +message PeersStatusRequest { + string enode = 1; +} + +message PeersStatusResponse { + Peer peer = 1; +} + +message Peer { + string id = 1; + string enode = 2; + string enr = 3; + repeated string caps = 4; + string name = 5; + bool trusted = 6; + bool static = 7; } message PprofRequest { diff --git a/command/server/proto/server_grpc.pb.go b/command/server/proto/server_grpc.pb.go index 1c101f5e85..109911e958 100644 --- a/command/server/proto/server_grpc.pb.go +++ b/command/server/proto/server_grpc.pb.go @@ -19,6 +19,10 @@ const _ = grpc.SupportPackageIsVersion7 // For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. type BorClient interface { Pprof(ctx context.Context, in *PprofRequest, opts ...grpc.CallOption) (*PprofResponse, error) + PeersAdd(ctx context.Context, in *PeersAddRequest, opts ...grpc.CallOption) (*PeersAddResponse, error) + PeersRemove(ctx context.Context, in *PeersRemoveRequest, opts ...grpc.CallOption) (*PeersRemoveResponse, error) + PeersList(ctx context.Context, in *PeersListRequest, opts ...grpc.CallOption) (*PeersListResponse, error) + PeersStatus(ctx context.Context, in *PeersStatusRequest, opts ...grpc.CallOption) (*PeersStatusResponse, error) } type borClient struct { @@ -38,11 +42,51 @@ func (c *borClient) Pprof(ctx context.Context, in *PprofRequest, opts ...grpc.Ca return out, nil } +func (c *borClient) PeersAdd(ctx context.Context, in *PeersAddRequest, opts ...grpc.CallOption) (*PeersAddResponse, error) { + out := new(PeersAddResponse) + err := c.cc.Invoke(ctx, "/proto.Bor/PeersAdd", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *borClient) PeersRemove(ctx context.Context, in *PeersRemoveRequest, opts ...grpc.CallOption) (*PeersRemoveResponse, error) { + out := new(PeersRemoveResponse) + err := c.cc.Invoke(ctx, "/proto.Bor/PeersRemove", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *borClient) PeersList(ctx context.Context, in *PeersListRequest, opts ...grpc.CallOption) (*PeersListResponse, error) { + out := new(PeersListResponse) + err := c.cc.Invoke(ctx, "/proto.Bor/PeersList", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *borClient) PeersStatus(ctx context.Context, in *PeersStatusRequest, opts ...grpc.CallOption) (*PeersStatusResponse, error) { + out := new(PeersStatusResponse) + err := c.cc.Invoke(ctx, "/proto.Bor/PeersStatus", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + // BorServer is the server API for Bor service. // All implementations must embed UnimplementedBorServer // for forward compatibility type BorServer interface { Pprof(context.Context, *PprofRequest) (*PprofResponse, error) + PeersAdd(context.Context, *PeersAddRequest) (*PeersAddResponse, error) + PeersRemove(context.Context, *PeersRemoveRequest) (*PeersRemoveResponse, error) + PeersList(context.Context, *PeersListRequest) (*PeersListResponse, error) + PeersStatus(context.Context, *PeersStatusRequest) (*PeersStatusResponse, error) mustEmbedUnimplementedBorServer() } @@ -53,6 +97,18 @@ type UnimplementedBorServer struct { func (UnimplementedBorServer) Pprof(context.Context, *PprofRequest) (*PprofResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method Pprof not implemented") } +func (UnimplementedBorServer) PeersAdd(context.Context, *PeersAddRequest) (*PeersAddResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method PeersAdd not implemented") +} +func (UnimplementedBorServer) PeersRemove(context.Context, *PeersRemoveRequest) (*PeersRemoveResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method PeersRemove not implemented") +} +func (UnimplementedBorServer) PeersList(context.Context, *PeersListRequest) (*PeersListResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method PeersList not implemented") +} +func (UnimplementedBorServer) PeersStatus(context.Context, *PeersStatusRequest) (*PeersStatusResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method PeersStatus not implemented") +} func (UnimplementedBorServer) mustEmbedUnimplementedBorServer() {} // UnsafeBorServer may be embedded to opt out of forward compatibility for this service. @@ -84,6 +140,78 @@ func _Bor_Pprof_Handler(srv interface{}, ctx context.Context, dec func(interface return interceptor(ctx, in, info, handler) } +func _Bor_PeersAdd_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(PeersAddRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(BorServer).PeersAdd(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/proto.Bor/PeersAdd", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(BorServer).PeersAdd(ctx, req.(*PeersAddRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _Bor_PeersRemove_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(PeersRemoveRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(BorServer).PeersRemove(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/proto.Bor/PeersRemove", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(BorServer).PeersRemove(ctx, req.(*PeersRemoveRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _Bor_PeersList_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(PeersListRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(BorServer).PeersList(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/proto.Bor/PeersList", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(BorServer).PeersList(ctx, req.(*PeersListRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _Bor_PeersStatus_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(PeersStatusRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(BorServer).PeersStatus(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/proto.Bor/PeersStatus", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(BorServer).PeersStatus(ctx, req.(*PeersStatusRequest)) + } + return interceptor(ctx, in, info, handler) +} + // Bor_ServiceDesc is the grpc.ServiceDesc for Bor service. // It's only intended for direct use with grpc.RegisterService, // and not to be introspected or modified (even as a copy) @@ -95,6 +223,22 @@ var Bor_ServiceDesc = grpc.ServiceDesc{ MethodName: "Pprof", Handler: _Bor_Pprof_Handler, }, + { + MethodName: "PeersAdd", + Handler: _Bor_PeersAdd_Handler, + }, + { + MethodName: "PeersRemove", + Handler: _Bor_PeersRemove_Handler, + }, + { + MethodName: "PeersList", + Handler: _Bor_PeersList_Handler, + }, + { + MethodName: "PeersStatus", + Handler: _Bor_PeersStatus_Handler, + }, }, Streams: []grpc.StreamDesc{}, Metadata: "command/server/proto/server.proto", diff --git a/command/server/service.go b/command/server/service.go index 86ab38d5e2..3b8b4d19e8 100644 --- a/command/server/service.go +++ b/command/server/service.go @@ -3,9 +3,13 @@ package server import ( "context" "encoding/hex" + "fmt" + "strings" "github.com/ethereum/go-ethereum/command/server/pprof" "github.com/ethereum/go-ethereum/command/server/proto" + "github.com/ethereum/go-ethereum/p2p" + "github.com/ethereum/go-ethereum/p2p/enode" ) func (s *Server) Pprof(ctx context.Context, req *proto.PprofRequest) (*proto.PprofResponse, error) { @@ -31,3 +35,70 @@ func (s *Server) Pprof(ctx context.Context, req *proto.PprofRequest) (*proto.Ppr } return resp, nil } + +func (s *Server) PeersAdd(ctx context.Context, req *proto.PeersAddRequest) (*proto.PeersAddResponse, error) { + node, err := enode.Parse(enode.ValidSchemes, req.Enode) + if err != nil { + return nil, fmt.Errorf("invalid enode: %v", err) + } + srv := s.node.Server() + if req.Trusted { + srv.AddTrustedPeer(node) + } else { + srv.AddPeer(node) + } + return &proto.PeersAddResponse{}, nil +} + +func (s *Server) PeersRemove(ctx context.Context, req *proto.PeersRemoveRequest) (*proto.PeersRemoveResponse, error) { + node, err := enode.Parse(enode.ValidSchemes, req.Enode) + if err != nil { + return nil, fmt.Errorf("invalid enode: %v", err) + } + srv := s.node.Server() + if req.Trusted { + srv.RemoveTrustedPeer(node) + } else { + srv.RemovePeer(node) + } + return &proto.PeersRemoveResponse{}, nil +} + +func (s *Server) PeersList(ctx context.Context, req *proto.PeersListRequest) (*proto.PeersListResponse, error) { + resp := &proto.PeersListResponse{} + + peers := s.node.Server().PeersInfo() + for _, p := range peers { + resp.Peers = append(resp.Peers, peerInfoToPeer(p)) + } + return resp, nil +} + +func (s *Server) PeersStatus(ctx context.Context, req *proto.PeersStatusRequest) (*proto.PeersStatusResponse, error) { + var peerInfo *p2p.PeerInfo + for _, p := range s.node.Server().PeersInfo() { + if strings.HasPrefix(p.ID, req.Enode) { + if peerInfo != nil { + return nil, fmt.Errorf("more than one peer with the same prefix") + } + peerInfo = p + } + } + resp := &proto.PeersStatusResponse{} + if peerInfo != nil { + resp.Peer = peerInfoToPeer(peerInfo) + } + return resp, nil +} + +func peerInfoToPeer(info *p2p.PeerInfo) *proto.Peer { + return &proto.Peer{ + Id: info.ID, + Enode: info.Enode, + Enr: info.ENR, + Caps: info.Caps, + Name: info.Name, + Trusted: info.Network.Trusted, + Static: info.Network.Static, + } +} From d10f5508b3d466b96159b90e5639fc9497d40ae9 Mon Sep 17 00:00:00 2001 From: Ferran Borreguero Date: Tue, 26 Oct 2021 09:38:43 +0200 Subject: [PATCH 21/51] Cleanup --- command/debug.go | 2 +- command/server/flags.go | 8 -------- 2 files changed, 1 insertion(+), 9 deletions(-) diff --git a/command/debug.go b/command/debug.go index b182811053..5ea2c9f44a 100644 --- a/command/debug.go +++ b/command/debug.go @@ -44,7 +44,7 @@ func (d *DebugCommand) Flags() *flagset.Flagset { Name: "seconds", Usage: "seconds to trace", Value: &d.seconds, - Default: 5, + Default: 2, }) flags.StringFlag(&flagset.StringFlag{ Name: "output", diff --git a/command/server/flags.go b/command/server/flags.go index e62a3a5c0b..303e5e9818 100644 --- a/command/server/flags.go +++ b/command/server/flags.go @@ -446,13 +446,5 @@ func (c *Command) Flags() *flagset.Flagset { Usage: "Address and port to bind the GRPC server", Value: &c.cliConfig.GRPC.Addr, }) - - // grpc - f.StringFlag(&flagset.StringFlag{ - Name: "grpc.addr", - Usage: "Address and port to bind the GRPC server", - Value: &c.cliConfig.GRPC.Addr, - }) - return f } From e9703c7e3fc292f674a4aa09f9a08dce2225ebc1 Mon Sep 17 00:00:00 2001 From: Ferran Borreguero Date: Tue, 26 Oct 2021 14:09:11 +0200 Subject: [PATCH 22/51] Add docs for cli and config file (#218) * Initial docs cli --- docs/README.md | 36 +++++++ docs/cli/README.md | 18 ++++ docs/cli/account.md | 10 ++ docs/cli/account_import.md | 4 + docs/cli/account_list.md | 4 + docs/cli/account_new.md | 4 + docs/cli/debug.md | 30 ++++++ docs/cli/server.md | 192 +++++++++++++++++++++++++++++++++++++ docs/cli/version.md | 11 +++ docs/config.md | 133 +++++++++++++++++++++++++ 10 files changed, 442 insertions(+) create mode 100644 docs/README.md create mode 100644 docs/cli/README.md create mode 100644 docs/cli/account.md create mode 100644 docs/cli/account_import.md create mode 100644 docs/cli/account_list.md create mode 100644 docs/cli/account_new.md create mode 100644 docs/cli/debug.md create mode 100644 docs/cli/server.md create mode 100644 docs/cli/version.md create mode 100644 docs/config.md diff --git a/docs/README.md b/docs/README.md new file mode 100644 index 0000000000..b5d7993d2c --- /dev/null +++ b/docs/README.md @@ -0,0 +1,36 @@ + +# Documentation + +- [Command-line-interface](./cli) + +- [Configuration file](./config.md) + +## Deprecation notes + +- The new entrypoint to run the Bor client is ```server```. + +``` +$ bor server +``` + +- Toml files to configure nodes are being deprecated. Currently, we only allow for static and trusted nodes to be configured using toml files. + +``` +$ bor server --config ./legacy.toml +``` + +- Modules, vhost and Cors configuration are common for all jsonrpc endpoints. + +Before: + +``` +$ bor --http --http.modules "eth,web" --ws --ws.modules "eth,web" +``` + +Now: + +``` +$ bor server --http --ws --jsonrpc.modules "eth,web" +``` + +- ```Admin```, ```Personal``` and account related endpoints in ```Eth``` are being removed from the JsonRPC interface. Some of this functionality will be moved to the new GRPC server for operational tasks. diff --git a/docs/cli/README.md b/docs/cli/README.md new file mode 100644 index 0000000000..c82bbbe047 --- /dev/null +++ b/docs/cli/README.md @@ -0,0 +1,18 @@ + +# Command line interface + +## Commands + +- [```server```](./server.md) + +- [```debug```](./debug.md) + +- [```account```](./account.md) + +- [```account new```](./account_new.md) + +- [```account list```](./account_list.md) + +- [```account import```](./account_import.md) + +- [```version```](./version.md) diff --git a/docs/cli/account.md b/docs/cli/account.md new file mode 100644 index 0000000000..00fd6cbe65 --- /dev/null +++ b/docs/cli/account.md @@ -0,0 +1,10 @@ + +# Account + +The ```account``` command groups actions to interact with accounts: + +- [```account new```](./account_new.md): Create a new account in the Bor client. + +- [```account list```](./account_list.md): List the wallets in the Bor client. + +- [```account import```](./account_import.md): Import an account to the Bor client. diff --git a/docs/cli/account_import.md b/docs/cli/account_import.md new file mode 100644 index 0000000000..2a515866cf --- /dev/null +++ b/docs/cli/account_import.md @@ -0,0 +1,4 @@ + +# Account import + +The ```account import``` command imports an account in Json format to the Bor data directory. diff --git a/docs/cli/account_list.md b/docs/cli/account_list.md new file mode 100644 index 0000000000..4a2d28de92 --- /dev/null +++ b/docs/cli/account_list.md @@ -0,0 +1,4 @@ + +# Account list + +The ```account list``` command lists all the accounts in the Bor data directory. diff --git a/docs/cli/account_new.md b/docs/cli/account_new.md new file mode 100644 index 0000000000..41e53767a1 --- /dev/null +++ b/docs/cli/account_new.md @@ -0,0 +1,4 @@ + +# Account new + +The ```account new``` command creates a new local account file on the Bor data directory. Bor should not be running to execute this command. diff --git a/docs/cli/debug.md b/docs/cli/debug.md new file mode 100644 index 0000000000..c75ae79e49 --- /dev/null +++ b/docs/cli/debug.md @@ -0,0 +1,30 @@ + +# Debug + +The ```bor debug``` command takes a debug dump of the running client. + +## Options + +- ```seconds```: Number of seconds to trace cpu and traces. + +- ```output```: Output directory for the data dump. + +## Examples + +By default it creates a tar.gz file with the output: + +``` +$ bor debug +Starting debugger... + +Created debug archive: bor-debug-2021-10-26-073819Z.tar.gz +``` + +Send the output to a specific directory: + +``` +$ bor debug --output data +Starting debugger... + +Created debug directory: data/bor-debug-2021-10-26-075437Z +``` diff --git a/docs/cli/server.md b/docs/cli/server.md new file mode 100644 index 0000000000..e2d961579a --- /dev/null +++ b/docs/cli/server.md @@ -0,0 +1,192 @@ + +# Server + +The ```bor server``` command runs the Bor client. + +## General Options + +- ```chain```: Name of the chain to sync (mainnet or mumbai). + +- ```log-level```: Set log level for the server (info, warn, debug, trace). + +- ```datadir```: Path of the data directory to store information (defaults to $HOME). + +- ```config```: List of files that contain the configuration. + +- ```syncmode```: Blockchain sync mode ("fast", "full", "snap" or "light"). + +- ```gcmode```: Blockchain garbage collection mode ("full", "archive"). + +- ```whitelist```: Comma separated block number-to-hash mappings to enforce (=). + +- ```snapshot```: Enables snapshot-database mode (default = enable). + +- ```bor.heimdall```: URL of Heimdall service. + +- ```bor.withoutheimdall```: Run without Heimdall service (for testing purpose). + +- ```ethstats```: Reporting URL of a ethstats service (nodename:secret@host:port). + +- ```gpo.blocks```: Number of recent blocks to check for gas prices. + +- ```gpo.percentile```: Suggested gas price is the given percentile of a set of recent transaction gas prices. + +- ```gpo.maxprice```: Maximum gas price will be recommended by gpo. + +- ```gpo.ignoreprice```: Gas price below which gpo will ignore transactions. + +- ```grpc.addr```: Address and port to bind the GRPC server. + +### Transaction Pool Options + +- ```txpool.locals```: Comma separated accounts to treat as locals (no flush, priority inclusion). + +- ```txpool.nolocals```: Disables price exemptions for locally submitted transactions + +- ```txpool.journal```: Disk journal for local transaction to survive node restarts + +- ```txpool.rejournal```: Time interval to regenerate the local transaction journal + +- ```txpool.pricelimit```: Minimum gas price limit to enforce for acceptance into the pool + +- ```txpool.pricebump```: Price bump percentage to replace an already existing transaction + +- ```txpool.accountslots```: Minimum number of executable transaction slots guaranteed per account + +- ```txpool.globalslots```: Maximum number of executable transaction slots for all accounts + +- ```txpool.accountqueue```: Maximum number of non-executable transaction slots permitted per account + +- ```txpool.globalqueue```: Maximum number of non-executable transaction slots for all accounts + +- ```txpool.lifetime```: Maximum amount of time non-executable transaction are queued + +### Sealer Options + +- ```mine```: Enable sealing. + +- ```miner.etherbase```: Public address for block mining rewards (default = first account) + +- ```miner.extradata```: Block extra data set by the miner (default = client version). + +- ```miner.gaslimit```: Target gas ceiling for mined blocks. + +- ```miner.gasprice```: Minimum gas price for mining a transaction. + +### Cache Options + +- ```cache```: Megabytes of memory allocated to internal caching (default = 4096 mainnet full node). + +- ```cache.database```: Percentage of cache memory allowance to use for database io. + +- ```cache.trie```: Percentage of cache memory allowance to use for trie caching (default = 15% full mode, 30% archive mode). + +- ```cache.trie.journal```: Disk journal directory for trie cache to survive node restarts. + +- ```cache.trie.rejournal```: Time interval to regenerate the trie cache journal. + +- ```cache.gc```: Percentage of cache memory allowance to use for trie pruning (default = 25% full mode, 0% archive mode). + +- ```cache.snapshot```: Percentage of cache memory allowance to use for snapshot caching (default = 10% full mode, 20% archive mode). + +- ```cache.noprefetch```: Disable heuristic state prefetch during block import (less CPU and disk IO, more time waiting for data). + +- ```cache.preimages```: Enable recording the SHA3/keccak preimages of trie keys. + +- ```txlookuplimit```: Number of recent blocks to maintain transactions index for (default = about one year, 0 = entire chain). + +### JsonRPC Options + +- ```rpc.gascap```: Sets a cap on gas that can be used in eth_call/estimateGas (0=infinite). + +- ```rpc.txfeecap```: Sets a cap on transaction fee (in ether) that can be sent via the RPC APIs (0 = no cap). + +- ```ipcdisable```: Disable the IPC-RPC server. + +- ```ipcpath```: Filename for IPC socket/pipe within the datadir (explicit paths escape it). + +- ```jsonrpc.corsdomain```: Comma separated list of domains from which to accept cross. + +- ```jsonrpc.vhosts```: Comma separated list of virtual hostnames from which to accept requests (server enforced). Accepts '*' wildcard. + +- ```jsonrpc.modules```: API's offered over the HTTP-RPC interface. + +- ```http```: Enable the HTTP-RPC server. + +- ```http.addr```: HTTP-RPC server listening interface. + +- ```http.port```: HTTP-RPC server listening port. + +- ```http.rpcprefix```: HTTP path path prefix on which JSON-RPC is served. Use '/' to serve on all paths. + +- ```ws```: Enable the WS-RPC server. + +- ```ws.addr```: WS-RPC server listening interface. + +- ```ws.port```: WS-RPC server listening port. + +- ```ws.rpcprefix```: HTTP path prefix on which JSON-RPC is served. Use '/' to serve on all paths. + +- ```graphql```: Enable GraphQL on the HTTP-RPC server. Note that GraphQL can only be started if an HTTP server is started as well. + +### P2P Options + +- ```bind```: Network binding address + +- ```port```: Network listening port + +- ```bootnodes```: Comma separated enode URLs for P2P discovery bootstrap + +- ```maxpeers```: "Maximum number of network peers (network disabled if set to 0) + +- ```maxpendpeers```: Maximum number of pending connection attempts (defaults used if set to 0) + +- ```nat```: "NAT port mapping mechanism (any|none|upnp|pmp|extip:) + +- ```nodiscover```: "Disables the peer discovery mechanism (manual peer addition) + +- ```v5disc```: "Enables the experimental RLPx V5 (Topic Discovery) mechanism + +### Telemetry Options + +- ```metrics```: Enable metrics collection and reporting. + +- ```metrics.expensive```: Enable expensive metrics collection and reporting. + +- ```metrics.influxdb```: Enable metrics export/push to an external InfluxDB database (v1). + +- ```metrics.influxdb.endpoint```: InfluxDB API endpoint to report metrics to. + +- ```metrics.influxdb.database```: InfluxDB database name to push reported metrics to. + +- ```metrics.influxdb.username```: Username to authorize access to the database. + +- ```metrics.influxdb.password```: Password to authorize access to the database. + +- ```metrics.influxdb.tags```: Comma-separated InfluxDB tags (key/values) attached to all measurements. + +- ```metrics.influxdbv2```: Enable metrics export/push to an external InfluxDB v2 database. + +- ```metrics.influxdb.token```: Token to authorize access to the database (v2 only). + +- ```metrics.influxdb.bucket```: InfluxDB bucket name to push reported metrics to (v2 only). + +- ```metrics.influxdb.organization```: InfluxDB organization name (v2 only). + +### Account Management Options + +- ```unlock```: "Comma separated list of accounts to unlock. + +- ```password```: Password file to use for non-interactive password input. + +- ```allow-insecure-unlock```: Allow insecure account unlocking when account-related RPCs are exposed by http. + +- ```lightkdf```: Reduce key-derivation RAM & CPU usage at some expense of KDF strength. + +## Usage + +Use multiple files to configure the client: + +``` +$ bor server --config ./legacy-config.toml --config ./config2.hcl +``` diff --git a/docs/cli/version.md b/docs/cli/version.md new file mode 100644 index 0000000000..156bdf607c --- /dev/null +++ b/docs/cli/version.md @@ -0,0 +1,11 @@ + +# Version + +The ```bor version``` command outputs the version of the binary. + +## Usage + +``` +$ bor version +0.2.9-stable +``` diff --git a/docs/config.md b/docs/config.md new file mode 100644 index 0000000000..4f4dec157b --- /dev/null +++ b/docs/config.md @@ -0,0 +1,133 @@ + +# Config + +Toml files format used in geth are being deprecated. + +Bor uses uses JSON and [HCL](https://github.com/hashicorp/hcl) formats to create configuration files. This is the format in HCL alongside the default values: + +``` +chain = "mainnet" +log-level = "info" +data-dir = "" +sync-mode = "fast" +gc-mode = "full" +snapshot = true +ethstats = "" +whitelist = {} + +p2p { + max-peers = 30 + max-pend-peers = 50 + bind = "0.0.0.0" + port = 30303 + no-discover = false + nat = "any" + discovery { + v5-enabled = false + bootnodes = [] + bootnodesv4 = [] + bootnodesv5 = [] + staticNodes = [] + trustedNodes = [] + dns = [] + } +} + +heimdall { + url = "http://localhost:1317" + without = false +} + +txpool { + locals = [] + no-locals = false + journal = "" + rejournal = "1h" + price-limit = 1 + price-bump = 10 + account-slots = 16 + global-slots = 4096 + account-queue = 64 + global-queue = 1024 + lifetime = "3h" +} + +sealer { + enabled = false + etherbase = "" + gas-ceil = 8000000 + extra-data = "" +} + +gpo { + blocks = 20 + percentile = 60 +} + +jsonrpc { + ipc-disable = false + ipc-path = "" + modules = ["web3", "net"] + cors = ["*"] + vhost = ["*"] + + http { + enabled = false + port = 8545 + prefix = "" + host = "localhost" + } + + ws { + enabled = false + port = 8546 + prefix = "" + host = "localhost" + } + + graphqh { + enabled = false + } +} + +telemetry { + enabled = false + expensive = false + + influxdb { + v1-enabled = false + endpoint = "" + database = "" + username = "" + password = "" + v2-enabled = false + token = "" + bucket = "" + organization = "" + } +} + +cache { + cache = 1024 + perc-database = 50 + perc-trie = 15 + perc-gc = 25 + perc-snapshot = 10 + journal = "triecache" + rejournal = "60m" + no-prefetch = false + preimages = false + tx-lookup-limit = 2350000 +} + +accounts { + unlock = [] + password-file = "" + allow-insecure-unlock = false + use-lightweight-kdf = false +} + +grpc { + addr = ":3131" +} +``` From f94c7ddd6f793f901e3c13f689d0f6ab112dad8f Mon Sep 17 00:00:00 2001 From: Ferran Borreguero Date: Tue, 26 Oct 2021 18:09:46 +0200 Subject: [PATCH 23/51] Decode big.int in config (#219) --- command/server/config.go | 45 +++++++++++++++++++++++++++-- command/server/config_test.go | 10 ++++++- command/server/testdata/simple.hcl | 10 ++++++- command/server/testdata/simple.json | 6 ++++ 4 files changed, 66 insertions(+), 5 deletions(-) diff --git a/command/server/config.go b/command/server/config.go index d5fbb49110..e25870a645 100644 --- a/command/server/config.go +++ b/command/server/config.go @@ -9,6 +9,7 @@ import ( "path/filepath" "runtime" "strconv" + "strings" "time" godebug "runtime/debug" @@ -194,7 +195,8 @@ type SealerConfig struct { GasCeil uint64 `hcl:"gas-ceil,optional"` // GasPrice is the minimum gas price for mining a transaction - GasPrice *big.Int `hcl:"gas-price,optional"` + GasPrice *big.Int + GasPriceRaw string `hcl:"gas-price,optional"` } type JsonRPCConfig struct { @@ -256,10 +258,12 @@ type GpoConfig struct { Percentile uint64 `hcl:"percentile,optional"` // MaxPrice is an upper bound gas price - MaxPrice *big.Int `hcl:"max-price,optional"` + MaxPrice *big.Int + MaxPriceRaw string `hcl:"max-price,optional"` // IgnorePrice is a lower bound gas price - IgnorePrice *big.Int `hcl:"ignore-price,optional"` + IgnorePrice *big.Int + IgnorePriceRaw string `hcl:"ignore-price,optional"` } type TelemetryConfig struct { @@ -473,6 +477,37 @@ func DefaultConfig() *Config { } } +func (c *Config) fillBigInt() error { + tds := []struct { + path string + td **big.Int + str *string + }{ + {"gpo.maxprice", &c.Gpo.MaxPrice, &c.Gpo.MaxPriceRaw}, + {"gpo.ignoreprice", &c.Gpo.IgnorePrice, &c.Gpo.IgnorePriceRaw}, + {"sealer.gasprice", &c.Sealer.GasPrice, &c.Sealer.GasPriceRaw}, + } + + for _, x := range tds { + if *x.str != "" { + b := new(big.Int) + + var ok bool + if strings.HasPrefix(*x.str, "0x") { + b, ok = b.SetString((*x.str)[2:], 16) + } else { + b, ok = b.SetString(*x.str, 10) + } + if !ok { + return fmt.Errorf("%s can't parse big int %s", x.path, *x.str) + } + *x.str = "" + *x.td = b + } + } + return nil +} + func (c *Config) fillTimeDurations() error { tds := []struct { path string @@ -511,10 +546,14 @@ func readConfigFile(path string) (*Config, error) { config := &Config{ TxPool: &TxPoolConfig{}, Cache: &CacheConfig{}, + Sealer: &SealerConfig{}, } if err := hclsimple.DecodeFile(path, nil, config); err != nil { return nil, fmt.Errorf("failed to decode config file '%s': %v", path, err) } + if err := config.fillBigInt(); err != nil { + return nil, err + } if err := config.fillTimeDurations(); err != nil { return nil, err } diff --git a/command/server/config_test.go b/command/server/config_test.go index 537d83be86..6383c3e003 100644 --- a/command/server/config_test.go +++ b/command/server/config_test.go @@ -1,6 +1,7 @@ package server import ( + "math/big" "testing" "time" @@ -81,13 +82,20 @@ func TestConfigLoadFile(t *testing.T) { assert.NoError(t, err) assert.Equal(t, config, &Config{ DataDir: "./data", + Whitelist: map[string]string{ + "a": "b", + }, P2P: &P2PConfig{ MaxPeers: 30, }, TxPool: &TxPoolConfig{ LifeTime: time.Duration(1 * time.Second), }, - Cache: &CacheConfig{}, + Gpo: &GpoConfig{ + MaxPrice: big.NewInt(100), + }, + Sealer: &SealerConfig{}, + Cache: &CacheConfig{}, }) } diff --git a/command/server/testdata/simple.hcl b/command/server/testdata/simple.hcl index 2be98feb42..e276960e6d 100644 --- a/command/server/testdata/simple.hcl +++ b/command/server/testdata/simple.hcl @@ -1,9 +1,17 @@ data-dir = "./data" +whitelist = { + a = "b" +} + p2p { max-peers = 30 } txpool { lifetime = "1s" -} \ No newline at end of file +} + +gpo { + max-price = "100" +} diff --git a/command/server/testdata/simple.json b/command/server/testdata/simple.json index 9dbf98f515..277f05d105 100644 --- a/command/server/testdata/simple.json +++ b/command/server/testdata/simple.json @@ -1,9 +1,15 @@ { "data-dir": "./data", + "whitelist": { + "a": "b" + }, "p2p": { "max-peers": 30 }, "txpool": { "lifetime": "1s" + }, + "gpo": { + "max-price": "100" } } \ No newline at end of file From 0aa8feeb0026eb471764b5419eabef3db126c923 Mon Sep 17 00:00:00 2001 From: Victor Castell Date: Fri, 5 Nov 2021 16:46:59 +0100 Subject: [PATCH 24/51] Apply best practices to Dockerfile --- Dockerfile | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/Dockerfile b/Dockerfile index c03cfacad8..860b18c704 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,18 +1,27 @@ # Build Geth in a stock Go builder container FROM golang:1.17-alpine as builder -RUN apk add --no-cache make gcc musl-dev linux-headers git bash +RUN set -x \ + && buildDeps='bash build-base musl-dev linux-headers git' \ + && apk add --update $buildDeps \ + && rm -rf /var/cache/apk/* \ + && mkdir -p /bor -ADD . /bor -RUN cd /bor && make bor-all +WORKDIR /bor +COPY . . +RUN make bor-all CMD ["/bin/bash"] # Pull Bor into a second stage deploy alpine container -FROM alpine:latest +FROM alpine:3.14 + +RUN set -x \ + && apk add --update --no-cache \ + ca-certificates \ + && rm -rf /var/cache/apk/* -RUN apk add --no-cache ca-certificates COPY --from=builder /bor/build/bin/bor /usr/local/bin/ COPY --from=builder /bor/build/bin/bootnode /usr/local/bin/ -EXPOSE 8545 8546 8547 30303 30303/udp \ No newline at end of file +EXPOSE 8545 8546 8547 30303 30303/udp From 1cd6c844aad88fc5ef0277553fd8e1e5188e52ef Mon Sep 17 00:00:00 2001 From: Rajat Saxena <42701222+rajatlko13@users.noreply.github.com> Date: Tue, 9 Nov 2021 14:53:34 +0530 Subject: [PATCH 25/51] Vendor protobuf and go extension issue PR (#223) * Vendor protobuf and go extension issue PR * Finalized the script * Quick fix --- go.mod | 1 + go.sum | 2 ++ scripts/tools-protobuf.sh | 5 +++++ 3 files changed, 8 insertions(+) create mode 100644 scripts/tools-protobuf.sh diff --git a/go.mod b/go.mod index ee79f9b222..25950738d2 100644 --- a/go.mod +++ b/go.mod @@ -75,6 +75,7 @@ require ( golang.org/x/text v0.3.6 golang.org/x/time v0.0.0-20210220033141-f8bda1e9f3ba google.golang.org/grpc v1.37.0 + google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0 // indirect google.golang.org/protobuf v1.25.0 gopkg.in/natefinch/npipe.v2 v2.0.0-20160621034901-c1b8fa8bdcce gopkg.in/olebedev/go-duktape.v3 v3.0.0-20200619000410-60c24ae608a6 diff --git a/go.sum b/go.sum index a8b1df8e13..356964f8d3 100644 --- a/go.sum +++ b/go.sum @@ -688,6 +688,8 @@ google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8 google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= google.golang.org/grpc v1.37.0 h1:uSZWeQJX5j11bIQ4AJoj+McDBo29cY1MCoC1wO3ts+c= google.golang.org/grpc v1.37.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= +google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0 h1:M1YKkFIboKNieVO5DLUEVzQfGwJD30Nv2jfUgzb5UcE= +google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0/go.mod h1:6Kw0yEErY5E/yWrBtf03jp27GLLJujG4z/JK95pnjjw= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= diff --git a/scripts/tools-protobuf.sh b/scripts/tools-protobuf.sh new file mode 100644 index 0000000000..020639f9d9 --- /dev/null +++ b/scripts/tools-protobuf.sh @@ -0,0 +1,5 @@ +curl -LO https://github.com/protocolbuffers/protobuf/releases/download/v3.12.0/protoc-3.12.0-linux-x86_64.zip +sudo unzip protoc-3.12.0-linux-x86_64.zip -d /usr/local/bin + +go install google.golang.org/protobuf/cmd/protoc-gen-go@v1.25.0 +go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@v1.1 From 57898e43e17b7058e05ad9683a7ee1e1370d5ddc Mon Sep 17 00:00:00 2001 From: Victor Castell Date: Wed, 10 Nov 2021 11:02:37 +0100 Subject: [PATCH 26/51] Final touches to Dockerfiles --- Dockerfile | 2 ++ Dockerfile.alltools | 7 +++++-- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/Dockerfile b/Dockerfile index 860b18c704..c12a8b1f4e 100644 --- a/Dockerfile +++ b/Dockerfile @@ -25,3 +25,5 @@ COPY --from=builder /bor/build/bin/bor /usr/local/bin/ COPY --from=builder /bor/build/bin/bootnode /usr/local/bin/ EXPOSE 8545 8546 8547 30303 30303/udp + +ENTRYPOINT ["bor"] diff --git a/Dockerfile.alltools b/Dockerfile.alltools index 10cf1392e7..53be8bc950 100644 --- a/Dockerfile.alltools +++ b/Dockerfile.alltools @@ -9,7 +9,10 @@ RUN cd /bor && make bor-all # Pull all binaries into a second stage deploy alpine container FROM alpine:latest -RUN apk add --no-cache ca-certificates +RUN set -x \ + && apk add --update --no-cache \ + ca-certificates \ + && rm -rf /var/cache/apk/* COPY --from=builder /bor/build/bin/* /usr/local/bin/ -EXPOSE 8545 8546 30303 30303/udp \ No newline at end of file +EXPOSE 8545 8546 30303 30303/udp From e58bdfa8e8ac96f4aaf6d3911af5001596ea4e82 Mon Sep 17 00:00:00 2001 From: Victor Castell Date: Wed, 10 Nov 2021 11:31:23 +0100 Subject: [PATCH 27/51] Build the new CLI --- Dockerfile | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/Dockerfile b/Dockerfile index c12a8b1f4e..37f0182bdc 100644 --- a/Dockerfile +++ b/Dockerfile @@ -9,9 +9,7 @@ RUN set -x \ WORKDIR /bor COPY . . -RUN make bor-all - -CMD ["/bin/bash"] +RUN go build -o ./build/bin/bor ./command # Pull Bor into a second stage deploy alpine container FROM alpine:3.14 @@ -22,7 +20,6 @@ RUN set -x \ && rm -rf /var/cache/apk/* COPY --from=builder /bor/build/bin/bor /usr/local/bin/ -COPY --from=builder /bor/build/bin/bootnode /usr/local/bin/ EXPOSE 8545 8546 8547 30303 30303/udp From 8ce30321ad46fabb3e3f991794dd028aa84d4f3c Mon Sep 17 00:00:00 2001 From: Victor Castell Date: Wed, 10 Nov 2021 11:31:39 +0100 Subject: [PATCH 28/51] Bump Go --- .github/workflows/ci.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index b55bfbdccb..b1badac12e 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -6,9 +6,9 @@ jobs: steps: - uses: actions/checkout@v2 - name: Install Go - uses: actions/setup-go@v2.1.3 + uses: actions/setup-go@v2 with: - go-version: 1.16.7 + go-version: 1.17 - name: "Build binaries" run: make all - name: "Run tests" From ba25f8447aa0735c1c3e878611c1d53e7d98bf6d Mon Sep 17 00:00:00 2001 From: Victor Castell Date: Wed, 10 Nov 2021 12:07:54 +0100 Subject: [PATCH 29/51] Revert "Build the new CLI" This reverts commit e58bdfa8e8ac96f4aaf6d3911af5001596ea4e82. --- Dockerfile | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index 37f0182bdc..c12a8b1f4e 100644 --- a/Dockerfile +++ b/Dockerfile @@ -9,7 +9,9 @@ RUN set -x \ WORKDIR /bor COPY . . -RUN go build -o ./build/bin/bor ./command +RUN make bor-all + +CMD ["/bin/bash"] # Pull Bor into a second stage deploy alpine container FROM alpine:3.14 @@ -20,6 +22,7 @@ RUN set -x \ && rm -rf /var/cache/apk/* COPY --from=builder /bor/build/bin/bor /usr/local/bin/ +COPY --from=builder /bor/build/bin/bootnode /usr/local/bin/ EXPOSE 8545 8546 8547 30303 30303/udp From 2191490acdd9449a3c8f0e40f8b78b2da5a0cf0f Mon Sep 17 00:00:00 2001 From: Ferran Borreguero Date: Thu, 11 Nov 2021 10:03:45 +0100 Subject: [PATCH 30/51] Add chain set head command (#226) --- command/chain.go | 31 +++ command/chain_sethead.go | 91 +++++++++ command/main.go | 10 + command/server/proto/server.pb.go | 268 ++++++++++++++++++------- command/server/proto/server.proto | 9 + command/server/proto/server_grpc.pb.go | 36 ++++ command/server/server.go | 2 + command/server/service.go | 5 + 8 files changed, 379 insertions(+), 73 deletions(-) create mode 100644 command/chain.go create mode 100644 command/chain_sethead.go diff --git a/command/chain.go b/command/chain.go new file mode 100644 index 0000000000..ed8ca9a5f8 --- /dev/null +++ b/command/chain.go @@ -0,0 +1,31 @@ +package main + +import ( + "github.com/mitchellh/cli" +) + +// ChainCommand is the command to group the peers commands +type ChainCommand struct { + UI cli.Ui +} + +// Help implements the cli.Command interface +func (c *ChainCommand) Help() string { + return `Usage: bor chain + + This command groups actions to interact with the chain. + + Set the new head of the chain: + + $ bor chain sethead ` +} + +// Synopsis implements the cli.Command interface +func (c *ChainCommand) Synopsis() string { + return "Interact with the chain" +} + +// Run implements the cli.Command interface +func (c *ChainCommand) Run(args []string) int { + return cli.RunResultHelp +} diff --git a/command/chain_sethead.go b/command/chain_sethead.go new file mode 100644 index 0000000000..0dfed6268b --- /dev/null +++ b/command/chain_sethead.go @@ -0,0 +1,91 @@ +package main + +import ( + "context" + "fmt" + "strconv" + + "github.com/ethereum/go-ethereum/command/flagset" + "github.com/ethereum/go-ethereum/command/server/proto" +) + +// ChainSetHeadCommand is the command to group the peers commands +type ChainSetHeadCommand struct { + *Meta2 + + yes bool +} + +// Help implements the cli.Command interface +func (c *ChainSetHeadCommand) Help() string { + return `Usage: bor chain sethead [--yes] + + This command sets the current chain to a certain block` +} + +func (c *ChainSetHeadCommand) Flags() *flagset.Flagset { + flags := c.NewFlagSet("chain sethead") + + flags.BoolFlag(&flagset.BoolFlag{ + Name: "yes", + Usage: "Force set head", + Default: false, + Value: &c.yes, + }) + return flags +} + +// Synopsis implements the cli.Command interface +func (c *ChainSetHeadCommand) Synopsis() string { + return "Set the new head of the chain" +} + +// Run implements the cli.Command interface +func (c *ChainSetHeadCommand) Run(args []string) int { + flags := c.Flags() + if err := flags.Parse(args); err != nil { + c.UI.Error(err.Error()) + return 1 + } + + args = flags.Args() + if len(args) != 1 { + c.UI.Error("No number provided") + return 1 + } + + borClt, err := c.BorConn() + if err != nil { + c.UI.Error(err.Error()) + return 1 + } + + arg := args[0] + fmt.Println(arg) + + number, err := strconv.Atoi(arg) + if err != nil { + c.UI.Error(err.Error()) + return 1 + } + + if !c.yes { + response, err := c.UI.Ask("Are you sure you want to reset the database? (y/n)") + if err != nil { + c.UI.Error(err.Error()) + return 1 + } + if response != "y" { + c.UI.Output("set head aborted") + return 0 + } + } + + if _, err := borClt.ChainSetHead(context.Background(), &proto.ChainSetHeadRequest{Number: uint64(number)}); err != nil { + c.UI.Error(err.Error()) + return 1 + } + + c.UI.Output("Done!") + return 0 +} diff --git a/command/main.go b/command/main.go index fab6f55ced..7b276e703b 100644 --- a/command/main.go +++ b/command/main.go @@ -64,6 +64,16 @@ func commands() map[string]cli.CommandFactory { Meta2: meta2, }, nil }, + "chain": func() (cli.Command, error) { + return &ChainCommand{ + UI: ui, + }, nil + }, + "chain sethead": func() (cli.Command, error) { + return &ChainSetHeadCommand{ + Meta2: meta2, + }, nil + }, "account": func() (cli.Command, error) { return &Account{ UI: ui, diff --git a/command/server/proto/server.pb.go b/command/server/proto/server.pb.go index a6c13fc7d3..ab6c06662b 100644 --- a/command/server/proto/server.pb.go +++ b/command/server/proto/server.pb.go @@ -71,7 +71,7 @@ func (x PprofRequest_Type) Number() protoreflect.EnumNumber { // Deprecated: Use PprofRequest_Type.Descriptor instead. func (PprofRequest_Type) EnumDescriptor() ([]byte, []int) { - return file_command_server_proto_server_proto_rawDescGZIP(), []int{9, 0} + return file_command_server_proto_server_proto_rawDescGZIP(), []int{11, 0} } type PeersAddRequest struct { @@ -534,6 +534,91 @@ func (x *Peer) GetStatic() bool { return false } +type ChainSetHeadRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Number uint64 `protobuf:"varint,1,opt,name=number,proto3" json:"number,omitempty"` +} + +func (x *ChainSetHeadRequest) Reset() { + *x = ChainSetHeadRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_command_server_proto_server_proto_msgTypes[9] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ChainSetHeadRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ChainSetHeadRequest) ProtoMessage() {} + +func (x *ChainSetHeadRequest) ProtoReflect() protoreflect.Message { + mi := &file_command_server_proto_server_proto_msgTypes[9] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ChainSetHeadRequest.ProtoReflect.Descriptor instead. +func (*ChainSetHeadRequest) Descriptor() ([]byte, []int) { + return file_command_server_proto_server_proto_rawDescGZIP(), []int{9} +} + +func (x *ChainSetHeadRequest) GetNumber() uint64 { + if x != nil { + return x.Number + } + return 0 +} + +type ChainSetHeadResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields +} + +func (x *ChainSetHeadResponse) Reset() { + *x = ChainSetHeadResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_command_server_proto_server_proto_msgTypes[10] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ChainSetHeadResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ChainSetHeadResponse) ProtoMessage() {} + +func (x *ChainSetHeadResponse) ProtoReflect() protoreflect.Message { + mi := &file_command_server_proto_server_proto_msgTypes[10] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ChainSetHeadResponse.ProtoReflect.Descriptor instead. +func (*ChainSetHeadResponse) Descriptor() ([]byte, []int) { + return file_command_server_proto_server_proto_rawDescGZIP(), []int{10} +} + type PprofRequest struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -547,7 +632,7 @@ type PprofRequest struct { func (x *PprofRequest) Reset() { *x = PprofRequest{} if protoimpl.UnsafeEnabled { - mi := &file_command_server_proto_server_proto_msgTypes[9] + mi := &file_command_server_proto_server_proto_msgTypes[11] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -560,7 +645,7 @@ func (x *PprofRequest) String() string { func (*PprofRequest) ProtoMessage() {} func (x *PprofRequest) ProtoReflect() protoreflect.Message { - mi := &file_command_server_proto_server_proto_msgTypes[9] + mi := &file_command_server_proto_server_proto_msgTypes[11] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -573,7 +658,7 @@ func (x *PprofRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use PprofRequest.ProtoReflect.Descriptor instead. func (*PprofRequest) Descriptor() ([]byte, []int) { - return file_command_server_proto_server_proto_rawDescGZIP(), []int{9} + return file_command_server_proto_server_proto_rawDescGZIP(), []int{11} } func (x *PprofRequest) GetType() PprofRequest_Type { @@ -609,7 +694,7 @@ type PprofResponse struct { func (x *PprofResponse) Reset() { *x = PprofResponse{} if protoimpl.UnsafeEnabled { - mi := &file_command_server_proto_server_proto_msgTypes[10] + mi := &file_command_server_proto_server_proto_msgTypes[12] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -622,7 +707,7 @@ func (x *PprofResponse) String() string { func (*PprofResponse) ProtoMessage() {} func (x *PprofResponse) ProtoReflect() protoreflect.Message { - mi := &file_command_server_proto_server_proto_msgTypes[10] + mi := &file_command_server_proto_server_proto_msgTypes[12] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -635,7 +720,7 @@ func (x *PprofResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use PprofResponse.ProtoReflect.Descriptor instead. func (*PprofResponse) Descriptor() ([]byte, []int) { - return file_command_server_proto_server_proto_rawDescGZIP(), []int{10} + return file_command_server_proto_server_proto_rawDescGZIP(), []int{12} } func (x *PprofResponse) GetPayload() string { @@ -689,47 +774,56 @@ var file_command_server_proto_server_proto_rawDesc = []byte{ 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x74, 0x72, 0x75, 0x73, 0x74, 0x65, 0x64, 0x18, 0x06, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x74, 0x72, 0x75, 0x73, 0x74, 0x65, 0x64, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x69, 0x63, 0x18, 0x07, 0x20, 0x01, 0x28, - 0x08, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x69, 0x63, 0x22, 0x98, 0x01, 0x0a, 0x0c, 0x50, 0x70, - 0x72, 0x6f, 0x66, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x2c, 0x0a, 0x04, 0x74, 0x79, - 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x18, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x2e, 0x50, 0x70, 0x72, 0x6f, 0x66, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x2e, 0x54, 0x79, - 0x70, 0x65, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x70, 0x72, 0x6f, 0x66, - 0x69, 0x6c, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x70, 0x72, 0x6f, 0x66, 0x69, - 0x6c, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x73, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x73, 0x18, 0x03, 0x20, - 0x01, 0x28, 0x03, 0x52, 0x07, 0x73, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x73, 0x22, 0x26, 0x0a, 0x04, - 0x54, 0x79, 0x70, 0x65, 0x12, 0x0a, 0x0a, 0x06, 0x4c, 0x4f, 0x4f, 0x4b, 0x55, 0x50, 0x10, 0x00, - 0x12, 0x07, 0x0a, 0x03, 0x43, 0x50, 0x55, 0x10, 0x01, 0x12, 0x09, 0x0a, 0x05, 0x54, 0x52, 0x41, - 0x43, 0x45, 0x10, 0x02, 0x22, 0xa2, 0x01, 0x0a, 0x0d, 0x50, 0x70, 0x72, 0x6f, 0x66, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61, - 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, - 0x12, 0x3b, 0x0a, 0x07, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, - 0x0b, 0x32, 0x21, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x50, 0x70, 0x72, 0x6f, 0x66, 0x52, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x73, 0x45, - 0x6e, 0x74, 0x72, 0x79, 0x52, 0x07, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x73, 0x1a, 0x3a, 0x0a, - 0x0c, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, - 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, - 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, - 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x32, 0xc2, 0x02, 0x0a, 0x03, 0x42, 0x6f, - 0x72, 0x12, 0x32, 0x0a, 0x05, 0x50, 0x70, 0x72, 0x6f, 0x66, 0x12, 0x13, 0x2e, 0x70, 0x72, 0x6f, - 0x74, 0x6f, 0x2e, 0x50, 0x70, 0x72, 0x6f, 0x66, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, - 0x14, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x50, 0x70, 0x72, 0x6f, 0x66, 0x52, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3b, 0x0a, 0x08, 0x50, 0x65, 0x65, 0x72, 0x73, 0x41, 0x64, - 0x64, 0x12, 0x16, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x50, 0x65, 0x65, 0x72, 0x73, 0x41, - 0x64, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x17, 0x2e, 0x70, 0x72, 0x6f, 0x74, - 0x6f, 0x2e, 0x50, 0x65, 0x65, 0x72, 0x73, 0x41, 0x64, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x12, 0x44, 0x0a, 0x0b, 0x50, 0x65, 0x65, 0x72, 0x73, 0x52, 0x65, 0x6d, 0x6f, 0x76, - 0x65, 0x12, 0x19, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x50, 0x65, 0x65, 0x72, 0x73, 0x52, - 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1a, 0x2e, 0x70, - 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x50, 0x65, 0x65, 0x72, 0x73, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, - 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3e, 0x0a, 0x09, 0x50, 0x65, 0x65, 0x72, - 0x73, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x17, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x50, 0x65, - 0x65, 0x72, 0x73, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x18, - 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x50, 0x65, 0x65, 0x72, 0x73, 0x4c, 0x69, 0x73, 0x74, - 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x44, 0x0a, 0x0b, 0x50, 0x65, 0x65, 0x72, - 0x73, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x19, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, - 0x50, 0x65, 0x65, 0x72, 0x73, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x1a, 0x1a, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x50, 0x65, 0x65, 0x72, 0x73, - 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x42, 0x17, + 0x08, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x69, 0x63, 0x22, 0x2d, 0x0a, 0x13, 0x43, 0x68, 0x61, + 0x69, 0x6e, 0x53, 0x65, 0x74, 0x48, 0x65, 0x61, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x12, 0x16, 0x0a, 0x06, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, + 0x52, 0x06, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x22, 0x16, 0x0a, 0x14, 0x43, 0x68, 0x61, 0x69, + 0x6e, 0x53, 0x65, 0x74, 0x48, 0x65, 0x61, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x22, 0x98, 0x01, 0x0a, 0x0c, 0x50, 0x70, 0x72, 0x6f, 0x66, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x12, 0x2c, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, + 0x18, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x50, 0x70, 0x72, 0x6f, 0x66, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x2e, 0x54, 0x79, 0x70, 0x65, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, + 0x18, 0x0a, 0x07, 0x70, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x07, 0x70, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x73, 0x65, 0x63, + 0x6f, 0x6e, 0x64, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x07, 0x73, 0x65, 0x63, 0x6f, + 0x6e, 0x64, 0x73, 0x22, 0x26, 0x0a, 0x04, 0x54, 0x79, 0x70, 0x65, 0x12, 0x0a, 0x0a, 0x06, 0x4c, + 0x4f, 0x4f, 0x4b, 0x55, 0x50, 0x10, 0x00, 0x12, 0x07, 0x0a, 0x03, 0x43, 0x50, 0x55, 0x10, 0x01, + 0x12, 0x09, 0x0a, 0x05, 0x54, 0x52, 0x41, 0x43, 0x45, 0x10, 0x02, 0x22, 0xa2, 0x01, 0x0a, 0x0d, + 0x50, 0x70, 0x72, 0x6f, 0x66, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x18, 0x0a, + 0x07, 0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, + 0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x12, 0x3b, 0x0a, 0x07, 0x68, 0x65, 0x61, 0x64, 0x65, + 0x72, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x21, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x2e, 0x50, 0x70, 0x72, 0x6f, 0x66, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x48, + 0x65, 0x61, 0x64, 0x65, 0x72, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x07, 0x68, 0x65, 0x61, + 0x64, 0x65, 0x72, 0x73, 0x1a, 0x3a, 0x0a, 0x0c, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x73, 0x45, + 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, + 0x32, 0x8b, 0x03, 0x0a, 0x03, 0x42, 0x6f, 0x72, 0x12, 0x32, 0x0a, 0x05, 0x50, 0x70, 0x72, 0x6f, + 0x66, 0x12, 0x13, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x50, 0x70, 0x72, 0x6f, 0x66, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x14, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x50, + 0x70, 0x72, 0x6f, 0x66, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3b, 0x0a, 0x08, + 0x50, 0x65, 0x65, 0x72, 0x73, 0x41, 0x64, 0x64, 0x12, 0x16, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x2e, 0x50, 0x65, 0x65, 0x72, 0x73, 0x41, 0x64, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x1a, 0x17, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x50, 0x65, 0x65, 0x72, 0x73, 0x41, 0x64, + 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x44, 0x0a, 0x0b, 0x50, 0x65, 0x65, + 0x72, 0x73, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x12, 0x19, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x2e, 0x50, 0x65, 0x65, 0x72, 0x73, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x1a, 0x1a, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x50, 0x65, 0x65, 0x72, + 0x73, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, + 0x3e, 0x0a, 0x09, 0x50, 0x65, 0x65, 0x72, 0x73, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x17, 0x2e, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x50, 0x65, 0x65, 0x72, 0x73, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x18, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x50, 0x65, + 0x65, 0x72, 0x73, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, + 0x44, 0x0a, 0x0b, 0x50, 0x65, 0x65, 0x72, 0x73, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x19, + 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x50, 0x65, 0x65, 0x72, 0x73, 0x53, 0x74, 0x61, 0x74, + 0x75, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1a, 0x2e, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x2e, 0x50, 0x65, 0x65, 0x72, 0x73, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x47, 0x0a, 0x0c, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x53, 0x65, + 0x74, 0x48, 0x65, 0x61, 0x64, 0x12, 0x1a, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x43, 0x68, + 0x61, 0x69, 0x6e, 0x53, 0x65, 0x74, 0x48, 0x65, 0x61, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x1a, 0x1b, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x53, + 0x65, 0x74, 0x48, 0x65, 0x61, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x42, 0x17, 0x5a, 0x15, 0x2f, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x2f, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } @@ -747,39 +841,43 @@ func file_command_server_proto_server_proto_rawDescGZIP() []byte { } var file_command_server_proto_server_proto_enumTypes = make([]protoimpl.EnumInfo, 1) -var file_command_server_proto_server_proto_msgTypes = make([]protoimpl.MessageInfo, 12) +var file_command_server_proto_server_proto_msgTypes = make([]protoimpl.MessageInfo, 14) var file_command_server_proto_server_proto_goTypes = []interface{}{ - (PprofRequest_Type)(0), // 0: proto.PprofRequest.Type - (*PeersAddRequest)(nil), // 1: proto.PeersAddRequest - (*PeersAddResponse)(nil), // 2: proto.PeersAddResponse - (*PeersRemoveRequest)(nil), // 3: proto.PeersRemoveRequest - (*PeersRemoveResponse)(nil), // 4: proto.PeersRemoveResponse - (*PeersListRequest)(nil), // 5: proto.PeersListRequest - (*PeersListResponse)(nil), // 6: proto.PeersListResponse - (*PeersStatusRequest)(nil), // 7: proto.PeersStatusRequest - (*PeersStatusResponse)(nil), // 8: proto.PeersStatusResponse - (*Peer)(nil), // 9: proto.Peer - (*PprofRequest)(nil), // 10: proto.PprofRequest - (*PprofResponse)(nil), // 11: proto.PprofResponse - nil, // 12: proto.PprofResponse.HeadersEntry + (PprofRequest_Type)(0), // 0: proto.PprofRequest.Type + (*PeersAddRequest)(nil), // 1: proto.PeersAddRequest + (*PeersAddResponse)(nil), // 2: proto.PeersAddResponse + (*PeersRemoveRequest)(nil), // 3: proto.PeersRemoveRequest + (*PeersRemoveResponse)(nil), // 4: proto.PeersRemoveResponse + (*PeersListRequest)(nil), // 5: proto.PeersListRequest + (*PeersListResponse)(nil), // 6: proto.PeersListResponse + (*PeersStatusRequest)(nil), // 7: proto.PeersStatusRequest + (*PeersStatusResponse)(nil), // 8: proto.PeersStatusResponse + (*Peer)(nil), // 9: proto.Peer + (*ChainSetHeadRequest)(nil), // 10: proto.ChainSetHeadRequest + (*ChainSetHeadResponse)(nil), // 11: proto.ChainSetHeadResponse + (*PprofRequest)(nil), // 12: proto.PprofRequest + (*PprofResponse)(nil), // 13: proto.PprofResponse + nil, // 14: proto.PprofResponse.HeadersEntry } var file_command_server_proto_server_proto_depIdxs = []int32{ 9, // 0: proto.PeersListResponse.peers:type_name -> proto.Peer 9, // 1: proto.PeersStatusResponse.peer:type_name -> proto.Peer 0, // 2: proto.PprofRequest.type:type_name -> proto.PprofRequest.Type - 12, // 3: proto.PprofResponse.headers:type_name -> proto.PprofResponse.HeadersEntry - 10, // 4: proto.Bor.Pprof:input_type -> proto.PprofRequest + 14, // 3: proto.PprofResponse.headers:type_name -> proto.PprofResponse.HeadersEntry + 12, // 4: proto.Bor.Pprof:input_type -> proto.PprofRequest 1, // 5: proto.Bor.PeersAdd:input_type -> proto.PeersAddRequest 3, // 6: proto.Bor.PeersRemove:input_type -> proto.PeersRemoveRequest 5, // 7: proto.Bor.PeersList:input_type -> proto.PeersListRequest 7, // 8: proto.Bor.PeersStatus:input_type -> proto.PeersStatusRequest - 11, // 9: proto.Bor.Pprof:output_type -> proto.PprofResponse - 2, // 10: proto.Bor.PeersAdd:output_type -> proto.PeersAddResponse - 4, // 11: proto.Bor.PeersRemove:output_type -> proto.PeersRemoveResponse - 6, // 12: proto.Bor.PeersList:output_type -> proto.PeersListResponse - 8, // 13: proto.Bor.PeersStatus:output_type -> proto.PeersStatusResponse - 9, // [9:14] is the sub-list for method output_type - 4, // [4:9] is the sub-list for method input_type + 10, // 9: proto.Bor.ChainSetHead:input_type -> proto.ChainSetHeadRequest + 13, // 10: proto.Bor.Pprof:output_type -> proto.PprofResponse + 2, // 11: proto.Bor.PeersAdd:output_type -> proto.PeersAddResponse + 4, // 12: proto.Bor.PeersRemove:output_type -> proto.PeersRemoveResponse + 6, // 13: proto.Bor.PeersList:output_type -> proto.PeersListResponse + 8, // 14: proto.Bor.PeersStatus:output_type -> proto.PeersStatusResponse + 11, // 15: proto.Bor.ChainSetHead:output_type -> proto.ChainSetHeadResponse + 10, // [10:16] is the sub-list for method output_type + 4, // [4:10] is the sub-list for method input_type 4, // [4:4] is the sub-list for extension type_name 4, // [4:4] is the sub-list for extension extendee 0, // [0:4] is the sub-list for field type_name @@ -900,7 +998,7 @@ func file_command_server_proto_server_proto_init() { } } file_command_server_proto_server_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*PprofRequest); i { + switch v := v.(*ChainSetHeadRequest); i { case 0: return &v.state case 1: @@ -912,6 +1010,30 @@ func file_command_server_proto_server_proto_init() { } } file_command_server_proto_server_proto_msgTypes[10].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ChainSetHeadResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_command_server_proto_server_proto_msgTypes[11].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*PprofRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_command_server_proto_server_proto_msgTypes[12].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*PprofResponse); i { case 0: return &v.state @@ -930,7 +1052,7 @@ func file_command_server_proto_server_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_command_server_proto_server_proto_rawDesc, NumEnums: 1, - NumMessages: 12, + NumMessages: 14, NumExtensions: 0, NumServices: 1, }, diff --git a/command/server/proto/server.proto b/command/server/proto/server.proto index 0d1de7bef6..535aa3f369 100644 --- a/command/server/proto/server.proto +++ b/command/server/proto/server.proto @@ -14,6 +14,8 @@ service Bor { rpc PeersList(PeersListRequest) returns (PeersListResponse); rpc PeersStatus(PeersStatusRequest) returns (PeersStatusResponse); + + rpc ChainSetHead(ChainSetHeadRequest) returns (ChainSetHeadResponse); } @@ -58,6 +60,13 @@ message Peer { bool static = 7; } +message ChainSetHeadRequest { + uint64 number = 1; +} + +message ChainSetHeadResponse { +} + message PprofRequest { Type type = 1; diff --git a/command/server/proto/server_grpc.pb.go b/command/server/proto/server_grpc.pb.go index 109911e958..369419b66f 100644 --- a/command/server/proto/server_grpc.pb.go +++ b/command/server/proto/server_grpc.pb.go @@ -23,6 +23,7 @@ type BorClient interface { PeersRemove(ctx context.Context, in *PeersRemoveRequest, opts ...grpc.CallOption) (*PeersRemoveResponse, error) PeersList(ctx context.Context, in *PeersListRequest, opts ...grpc.CallOption) (*PeersListResponse, error) PeersStatus(ctx context.Context, in *PeersStatusRequest, opts ...grpc.CallOption) (*PeersStatusResponse, error) + ChainSetHead(ctx context.Context, in *ChainSetHeadRequest, opts ...grpc.CallOption) (*ChainSetHeadResponse, error) } type borClient struct { @@ -78,6 +79,15 @@ func (c *borClient) PeersStatus(ctx context.Context, in *PeersStatusRequest, opt return out, nil } +func (c *borClient) ChainSetHead(ctx context.Context, in *ChainSetHeadRequest, opts ...grpc.CallOption) (*ChainSetHeadResponse, error) { + out := new(ChainSetHeadResponse) + err := c.cc.Invoke(ctx, "/proto.Bor/ChainSetHead", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + // BorServer is the server API for Bor service. // All implementations must embed UnimplementedBorServer // for forward compatibility @@ -87,6 +97,7 @@ type BorServer interface { PeersRemove(context.Context, *PeersRemoveRequest) (*PeersRemoveResponse, error) PeersList(context.Context, *PeersListRequest) (*PeersListResponse, error) PeersStatus(context.Context, *PeersStatusRequest) (*PeersStatusResponse, error) + ChainSetHead(context.Context, *ChainSetHeadRequest) (*ChainSetHeadResponse, error) mustEmbedUnimplementedBorServer() } @@ -109,6 +120,9 @@ func (UnimplementedBorServer) PeersList(context.Context, *PeersListRequest) (*Pe func (UnimplementedBorServer) PeersStatus(context.Context, *PeersStatusRequest) (*PeersStatusResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method PeersStatus not implemented") } +func (UnimplementedBorServer) ChainSetHead(context.Context, *ChainSetHeadRequest) (*ChainSetHeadResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method ChainSetHead not implemented") +} func (UnimplementedBorServer) mustEmbedUnimplementedBorServer() {} // UnsafeBorServer may be embedded to opt out of forward compatibility for this service. @@ -212,6 +226,24 @@ func _Bor_PeersStatus_Handler(srv interface{}, ctx context.Context, dec func(int return interceptor(ctx, in, info, handler) } +func _Bor_ChainSetHead_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(ChainSetHeadRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(BorServer).ChainSetHead(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/proto.Bor/ChainSetHead", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(BorServer).ChainSetHead(ctx, req.(*ChainSetHeadRequest)) + } + return interceptor(ctx, in, info, handler) +} + // Bor_ServiceDesc is the grpc.ServiceDesc for Bor service. // It's only intended for direct use with grpc.RegisterService, // and not to be introspected or modified (even as a copy) @@ -239,6 +271,10 @@ var Bor_ServiceDesc = grpc.ServiceDesc{ MethodName: "PeersStatus", Handler: _Bor_PeersStatus_Handler, }, + { + MethodName: "ChainSetHead", + Handler: _Bor_ChainSetHead_Handler, + }, }, Streams: []grpc.StreamDesc{}, Metadata: "command/server/proto/server.proto", diff --git a/command/server/server.go b/command/server/server.go index 437a39b906..0b3e90365b 100644 --- a/command/server/server.go +++ b/command/server/server.go @@ -27,6 +27,7 @@ import ( type Server struct { proto.UnimplementedBorServer node *node.Node + backend *eth.Ethereum grpcServer *grpc.Server } @@ -65,6 +66,7 @@ func NewServer(config *Config) (*Server, error) { if err != nil { return nil, err } + srv.backend = backend // debug tracing is enabled by default stack.RegisterAPIs(tracers.APIs(backend.APIBackend)) diff --git a/command/server/service.go b/command/server/service.go index 3b8b4d19e8..0c6c23b6bf 100644 --- a/command/server/service.go +++ b/command/server/service.go @@ -102,3 +102,8 @@ func peerInfoToPeer(info *p2p.PeerInfo) *proto.Peer { Static: info.Network.Static, } } + +func (s *Server) ChainSetHead(ctx context.Context, req *proto.ChainSetHeadRequest) (*proto.ChainSetHeadResponse, error) { + s.backend.APIBackend.SetHead(req.Number) + return &proto.ChainSetHeadResponse{}, nil +} From fc58176e80800c206e61b720f2169b6b8c344e4e Mon Sep 17 00:00:00 2001 From: Shivam Sharma Date: Thu, 11 Nov 2021 21:11:54 +0530 Subject: [PATCH 31/51] Added Prometheus flag on bor-cli --- command/server/config.go | 11 +++++++++++ command/server/server.go | 30 ++++++++++++++++++++++++++++++ go.mod | 7 +++++-- go.sum | 19 ++++++++++++------- 4 files changed, 58 insertions(+), 9 deletions(-) diff --git a/command/server/config.go b/command/server/config.go index e25870a645..34fa13cf51 100644 --- a/command/server/config.go +++ b/command/server/config.go @@ -88,6 +88,9 @@ type Config struct { // GRPC has the grpc server related settings GRPC *GRPCConfig + + // Prometheus Server + Prometheus *PrometheusConfig `hcl:"prometheus,optional"` } type P2PConfig struct { @@ -236,6 +239,14 @@ type GRPCConfig struct { Addr string } +type PrometheusConfig struct { + // Enabled selects whether the api is enabled + Enabled bool `hcl:"enabled,optional"` + + // Host is the address to bind the api + address string `hcl:"host,optional"` +} + type APIConfig struct { // Enabled selects whether the api is enabled Enabled bool `hcl:"enabled,optional"` diff --git a/command/server/server.go b/command/server/server.go index 437a39b906..5981f0cf48 100644 --- a/command/server/server.go +++ b/command/server/server.go @@ -5,6 +5,7 @@ import ( "fmt" "io" "net" + "net/http" "os" "strings" "time" @@ -17,13 +18,17 @@ import ( "github.com/ethereum/go-ethereum/graphql" "github.com/ethereum/go-ethereum/log" "github.com/ethereum/go-ethereum/metrics" + "github.com/ethereum/go-ethereum/metrics/exp" "github.com/ethereum/go-ethereum/metrics/influxdb" "github.com/ethereum/go-ethereum/node" + "github.com/fjl/memsize/memsizeui" "github.com/mattn/go-colorable" "github.com/mattn/go-isatty" "google.golang.org/grpc" ) +var Memsize memsizeui.Handler + type Server struct { proto.UnimplementedBorServer node *node.Node @@ -45,6 +50,11 @@ func NewServer(config *Config) (*Server, error) { return nil, err } + // start the Prometheus Server + if err := srv.StartPrometheus(config.Prometheus.address, config.Prometheus.Enabled); err != nil { + return nil, err + } + // create the node/stack nodeCfg, err := config.buildNode() if err != nil { @@ -171,6 +181,26 @@ func (s *Server) setupGRPCServer(addr string) error { return nil } +func (s *Server) StartPrometheus(address string, enabled bool) error { + // Hook go-metrics into expvar on any /debug/metrics request, load all vars + // from the registry into expvar, and execute regular expvar handler. + if enabled { + exp.Exp(metrics.DefaultRegistry) + } + + http.Handle("/memsize/", http.StripPrefix("/memsize", &Memsize)) + + log.Info("Starting pprof server", "addr", fmt.Sprintf("http://%s/debug/pprof", address)) + + go func() { + if err := http.ListenAndServe(address, nil); err != nil { + log.Error("Failure in running pprof server", "err", err) + } + }() + + return nil +} + func (s *Server) withLoggingUnaryInterceptor() grpc.ServerOption { return grpc.UnaryInterceptor(s.loggingServerInterceptor) } diff --git a/go.mod b/go.mod index ee79f9b222..c8bc297a8d 100644 --- a/go.mod +++ b/go.mod @@ -26,6 +26,8 @@ require ( github.com/fatih/color v1.7.0 github.com/fjl/memsize v0.0.0-20190710130421-bcb5799ab5e5 github.com/gballet/go-libpcsclite v0.0.0-20190607065134-2772fd86a8ff + github.com/go-kit/kit v0.9.0 // indirect + github.com/go-logfmt/logfmt v0.5.0 // indirect github.com/go-ole/go-ole v1.2.1 // indirect github.com/go-sourcemap/sourcemap v2.1.2+incompatible // indirect github.com/go-stack/stack v1.8.0 @@ -46,7 +48,7 @@ require ( github.com/influxdata/line-protocol v0.0.0-20210311194329-9aa0e372d097 // indirect github.com/jackpal/go-nat-pmp v1.0.2-0.20160603034137-1fa385a6f458 github.com/jedisct1/go-minisign v0.0.0-20190909160543-45766022959e - github.com/julienschmidt/httprouter v1.2.0 + github.com/julienschmidt/httprouter v1.3.0 github.com/karalabe/usb v0.0.0-20190919080040-51dc0efba356 github.com/kylelemons/godebug v1.1.0 // indirect github.com/mattn/go-colorable v0.1.8 @@ -75,7 +77,8 @@ require ( golang.org/x/text v0.3.6 golang.org/x/time v0.0.0-20210220033141-f8bda1e9f3ba google.golang.org/grpc v1.37.0 - google.golang.org/protobuf v1.25.0 + google.golang.org/protobuf v1.26.0-rc.1 + gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 // indirect gopkg.in/natefinch/npipe.v2 v2.0.0-20160621034901-c1b8fa8bdcce gopkg.in/olebedev/go-duktape.v3 v3.0.0-20200619000410-60c24ae608a6 gopkg.in/urfave/cli.v1 v1.20.0 diff --git a/go.sum b/go.sum index a8b1df8e13..5cdca30374 100644 --- a/go.sum +++ b/go.sum @@ -167,11 +167,13 @@ github.com/glycerine/goconvey v0.0.0-20190410193231-58a59202ab31/go.mod h1:Ogl1T github.com/go-chi/chi/v5 v5.0.0/go.mod h1:BBug9lr0cqtdAhsu6R4AAdvufI0/XBzAQSsUqJpoZOs= github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= -github.com/go-kit/kit v0.8.0 h1:Wz+5lgoB0kkuqLEc6NVmwRknTKP6dTGbSqvhZtBI/j0= github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= +github.com/go-kit/kit v0.9.0 h1:wDJmvq38kDhkVxi50ni9ykkdUr1PKgqKOoi01fa0Mdk= +github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= -github.com/go-logfmt/logfmt v0.4.0 h1:MP4Eh7ZCb31lleYCFuwm0oe4/YGak+5l1vA2NOE80nA= github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= +github.com/go-logfmt/logfmt v0.5.0 h1:TrB8swr/68K7m9CcGut2g3UOihhbcbiMAYiuTXdEih4= +github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A= github.com/go-ole/go-ole v1.2.1 h1:2lOsA72HgjxAuMlKpFiCbHTvu44PIVkZ5hqm3RSdI/E= github.com/go-ole/go-ole v1.2.1/go.mod h1:7FAglXiTm7HKlQRDeOQ6ZNUHidzCWXuZWq/1dTyBNF8= github.com/go-openapi/jsonpointer v0.19.5/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg= @@ -222,8 +224,9 @@ github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMyw github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.4 h1:L8R9j+yAqZuZjsqh/z+F1NCffTKKLShY6zXTItVIZ8M= github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU= +github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/gofuzz v1.1.1-0.20200604201612-c04b05f3adfa h1:Q75Upo5UN4JbPFURXZ8nLKYUvF85dyFRop/vQ0Rv+64= github.com/google/gofuzz v1.1.1-0.20200604201612-c04b05f3adfa/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= @@ -293,8 +296,9 @@ github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1 github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= github.com/jsternberg/zap-logfmt v1.0.0/go.mod h1:uvPs/4X51zdkcm5jXl5SYoN+4RK21K8mysFmDaM/h+o= github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= -github.com/julienschmidt/httprouter v1.2.0 h1:TDTW5Yz1mjftljbcKqRcrYhd4XeOoI98t+9HbQbYf7g= github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= +github.com/julienschmidt/httprouter v1.3.0 h1:U0609e9tgbseu3rBINet9P48AI/D3oJs4dN7jwJOQ1U= +github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM= github.com/jung-kurt/gofpdf v1.0.3-0.20190309125859-24315acbbda5/go.mod h1:7Id9E/uU8ce6rXgefFLlgrJj/GYY22cpxn+r32jIOes= github.com/jwilder/encoding v0.0.0-20170811194829-b4e1701a28ef/go.mod h1:Ct9fl0F6iIOGgxJ5npU/IUOhOhqlVrGjyIZc8/MagT0= github.com/karalabe/usb v0.0.0-20190919080040-51dc0efba356 h1:I/yrLt2WilKxlQKCM52clh5rGzTKpVctGT1lH4Dc8Jw= @@ -307,7 +311,6 @@ github.com/klauspost/cpuid v0.0.0-20170728055534-ae7887de9fa5/go.mod h1:Pj4uuM52 github.com/klauspost/crc32 v0.0.0-20161016154125-cb6bfca970f6/go.mod h1:+ZoRqAPRLkC4NPOvfYeR5KNOrY6TD+/sAC3HXPZgDYg= github.com/klauspost/pgzip v1.0.2-0.20170402124221-0bf5dcad4ada/go.mod h1:Ch1tH69qFZu15pkjo5kYi6mth2Zzwzt50oCQKQE9RUs= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= -github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515 h1:T+h1c/A9Gawja4Y9mFVWj2vyii2bbUNDw3kt9VxK2EY= github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= @@ -696,12 +699,14 @@ google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzi google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= -google.golang.org/protobuf v1.25.0 h1:Ejskq+SyPohKW+1uil0JJMtmHCgJPJ/qWTxr8qp+R4c= google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= +google.golang.org/protobuf v1.26.0-rc.1 h1:7QnIQpGRHE5RnLKnESfDoxm2dTapTZua5a0kS0A+VXQ= +google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo= +gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= gopkg.in/natefinch/npipe.v2 v2.0.0-20160621034901-c1b8fa8bdcce h1:+JknDZhAj8YMt7GC73Ei8pv4MzjDUNPHgQWJdtMAaDU= From 7b6bab4986dca3e26566cb02ddfe3e5ca8d4a7f2 Mon Sep 17 00:00:00 2001 From: Victor Castell Date: Tue, 9 Nov 2021 13:14:11 +0100 Subject: [PATCH 32/51] Release multi-platform with goreleaser Packages, docker images CI automated --- .github/workflows/dockerimage-latest.yml | 26 ----- .github/workflows/dockerimage.yml | 25 ----- .github/workflows/linuxpackage.yml | 67 ------------ .github/workflows/release.yml | 43 ++++++++ .gitignore | 2 + .goreleaser.yml | 126 +++++++++++++++++++++++ Dockerfile.release | 10 ++ Makefile | 34 ++++++ builder/files/bor.service | 18 ++++ 9 files changed, 233 insertions(+), 118 deletions(-) delete mode 100644 .github/workflows/dockerimage-latest.yml delete mode 100644 .github/workflows/dockerimage.yml delete mode 100644 .github/workflows/linuxpackage.yml create mode 100644 .github/workflows/release.yml create mode 100644 .goreleaser.yml create mode 100644 Dockerfile.release create mode 100644 builder/files/bor.service diff --git a/.github/workflows/dockerimage-latest.yml b/.github/workflows/dockerimage-latest.yml deleted file mode 100644 index 0bfa73503e..0000000000 --- a/.github/workflows/dockerimage-latest.yml +++ /dev/null @@ -1,26 +0,0 @@ -name: Docker Images For Latest Branches - -on: - push: - branches: - - master - -jobs: - build: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v2 - - name: Build docker image - env: - DOCKERHUB: ${{ secrets.DOCKERHUB }} - DOCKERHUB_KEY: ${{ secrets.DOCKERHUB_KEY }} - run: | - set -x - ls -l - echo "Docker login" - docker login -u $DOCKERHUB -p $DOCKERHUB_KEY - echo "Running build" - docker build -t maticnetwork/bor:${GITHUB_REF/refs\/heads\//} . - echo "Pushing image" - docker push maticnetwork/bor:${GITHUB_REF/refs\/heads\//} - echo "Done" diff --git a/.github/workflows/dockerimage.yml b/.github/workflows/dockerimage.yml deleted file mode 100644 index a357399dfb..0000000000 --- a/.github/workflows/dockerimage.yml +++ /dev/null @@ -1,25 +0,0 @@ -name: Bor Docker Image CI - -on: - push: - tags: - - 'v*.*.*' - -jobs: - build: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v2 - - name: Build the Bor Docker image - env: - DOCKERHUB: ${{ secrets.DOCKERHUB }} - DOCKERHUB_KEY: ${{ secrets.DOCKERHUB_KEY }} - run: | - ls -l - echo "Docker login" - docker login -u $DOCKERHUB -p $DOCKERHUB_KEY - echo "running build" - docker build -t maticnetwork/bor:${GITHUB_REF/refs\/tags\//} . - echo "pushing image" - docker push maticnetwork/bor:${GITHUB_REF/refs\/tags\//} - echo "DONE!" diff --git a/.github/workflows/linuxpackage.yml b/.github/workflows/linuxpackage.yml deleted file mode 100644 index f4937e426f..0000000000 --- a/.github/workflows/linuxpackage.yml +++ /dev/null @@ -1,67 +0,0 @@ -name: Linux package - -on: - push: - tags: - - "v*.*.*" -jobs: - build: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v2 - - - name: Install Go - uses: actions/setup-go@v1 - with: - go-version: 1.17 - - - name: Set up Ruby 2.6 - uses: actions/setup-ruby@v1 - with: - ruby-version: 2.6 - - - name: Retrieve release version - run: | - echo "RELEASE_VERSION=${GITHUB_REF/refs\/tags\/v/}" >> $GITHUB_ENV - - - name: Build package - run: | - set -x - - echo "Release version: ${{ env.RELEASE_VERSION }}" - - sudo apt-get -yqq install libpq-dev build-essential - gem install --no-document fpm - fpm --version - - make bor-all - - fpm -s dir -t deb --deb-user root --deb-group root -n matic-bor -v ${{ env.RELEASE_VERSION }} \ - build/bin/bor=/usr/bin/ \ - build/bin/bootnode=/usr/bin/ - - mkdir packages-v${{ env.RELEASE_VERSION }} - - mv matic-bor_${{ env.RELEASE_VERSION }}_amd64.deb packages-v${{ env.RELEASE_VERSION }}/ - - ls packages-v${{ env.RELEASE_VERSION }}/ - - - name: S3 upload - uses: jakejarvis/s3-sync-action@master - with: - args: --acl public-read - env: - AWS_S3_BUCKET: ${{ secrets.AWS_S3_BUCKET }} - AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }} - AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }} - AWS_REGION: "us-east-1" # optional: defaults to us-east-1 - SOURCE_DIR: "packages-v${{ env.RELEASE_VERSION }}" - DEST_DIR: "v${{ env.RELEASE_VERSION }}" - - - name: Slack Notification - uses: rtCamp/action-slack-notify@v2.0.0 - env: - SLACK_CHANNEL: code-releases - SLACK_WEBHOOK: ${{ secrets.SLACK_WEBHOOK }} - SLACK_TITLE: "New linux package for Bor v${{ env.RELEASE_VERSION }} just got released" - SLACK_MESSAGE: "Package has been uploaded to S3 bucket for public use and available at https://matic-public.s3.amazonaws.com/v${{ env.RELEASE_VERSION }}/matic-bor_${{ env.RELEASE_VERSION }}_amd64.deb" diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 0000000000..b615cf639e --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,43 @@ +name: Release + +on: + push: + branches-ignore: + - '**' + tags: + - 'v*.*.*' + # to be used by fork patch-releases ^^ + - 'v*.*.*-*' + +jobs: + goreleaser: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v2 + with: + fetch-depth: 0 + + - name: Set up Go + uses: actions/setup-go@master + with: + go-version: 1.17.x + + - name: Prepare + id: prepare + run: | + TAG=${GITHUB_REF#refs/tags/} + echo ::set-output name=tag_name::${TAG} + + - name: Set up QEMU + uses: docker/setup-qemu-action@v1 + + - name: Run GoReleaser + run: | + make release + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + VERSION: ${{ steps.prepare.outputs.tag_name }} + SLACK_WEBHOOK: ${{ secrets.SLACK_WEBHOOK }} + DOCKER_USERNAME: ${{ secrets.DOCKERHUB }} + DOCKER_PASSWORD: ${{ secrets.DOCKERHUB_KEY }} diff --git a/.gitignore b/.gitignore index a56d252322..ad4242c519 100644 --- a/.gitignore +++ b/.gitignore @@ -49,3 +49,5 @@ profile.cov **/yarn-error.log ./test ./bor-debug-* + +dist diff --git a/.goreleaser.yml b/.goreleaser.yml new file mode 100644 index 0000000000..b25a316449 --- /dev/null +++ b/.goreleaser.yml @@ -0,0 +1,126 @@ +project_name: bor + +release: + disable: false + draft: true + prerelease: auto + +builds: + - id: darwin-amd64 + main: ./cmd/geth + binary: bor + goos: + - darwin + goarch: + - amd64 + env: + - CC=o64-clang + - CXX=o64-clang++ + ldflags: + -s -w + + - id: darwin-arm64 + main: ./cmd/geth + binary: bor + goos: + - darwin + goarch: + - arm64 + env: + - CC=oa64-clang + - CXX=oa64-clang++ + ldflags: + -s -w + + - id: linux-amd64 + main: ./cmd/geth + binary: bor + goos: + - linux + goarch: + - amd64 + env: + - CC=gcc + - CXX=g++ + ldflags: + # We need to build a static binary because we are building in a glibc based system and running in a musl container + -s -w -linkmode external -extldflags "-static" + + - id: linux-arm64 + main: ./cmd/geth + binary: bor + goos: + - linux + goarch: + - arm64 + env: + - CC=aarch64-linux-gnu-gcc + - CXX=aarch64-linux-gnu-g++ + ldflags: + # We need to build a static binary because we are building in a glibc based system and running in a musl container + -s -w -linkmode external -extldflags "-static" + +nfpms: + - vendor: 0xPolygon + homepage: https://polygon.technology + maintainer: Polygon Team + description: Polygon Blockchain + license: GPLv3 LGPLv3 + + formats: + - apk + - deb + - rpm + + contents: + - src: builder/files/bor.service + dst: /lib/systemd/system/bor.service + type: config + + overrides: + rpm: + replacements: + amd64: x86_64 + +snapshot: + name_template: "{{ .Tag }}.next" + +dockers: + - image_templates: + - 0xpolygon/{{ .ProjectName }}:{{ .Version }}-amd64 + dockerfile: Dockerfile.release + use: buildx + goarch: amd64 + ids: + - linux-amd64 + build_flag_templates: + - --platform=linux/amd64 + skip_push: true + + - image_templates: + - 0xpolygon/{{ .ProjectName }}:{{ .Version }}-arm64 + dockerfile: Dockerfile.release + use: buildx + goarch: arm64 + ids: + - linux-arm64 + build_flag_templates: + - --platform=linux/arm64 + skip_push: true + +docker_manifests: + - name_template: 0xpolygon/{{ .ProjectName }}:{{ .Version }} + image_templates: + - 0xpolygon/{{ .ProjectName }}:{{ .Version }}-amd64 + - 0xpolygon/{{ .ProjectName }}:{{ .Version }}-arm64 + + - name_template: 0xpolygon/{{ .ProjectName }}:latest + image_templates: + - 0xpolygon/{{ .ProjectName }}:{{ .Version }}-amd64 + - 0xpolygon/{{ .ProjectName }}:{{ .Version }}-arm64 + +announce: + slack: + enabled: true + # The name of the channel that the user selected as a destination for webhook messages. + channel: '#code-releases' diff --git a/Dockerfile.release b/Dockerfile.release new file mode 100644 index 0000000000..c0ae7f9c29 --- /dev/null +++ b/Dockerfile.release @@ -0,0 +1,10 @@ +FROM alpine:3.14 + +RUN set -x \ + && apk add --update --no-cache \ + ca-certificates \ + && rm -rf /var/cache/apk/* +COPY bor /usr/local/bin/ + +EXPOSE 8545 8546 8547 30303 30303/udp +ENTRYPOINT ["bor"] diff --git a/Makefile b/Makefile index b9bc9db602..462f129f51 100644 --- a/Makefile +++ b/Makefile @@ -163,3 +163,37 @@ geth-windows-amd64: $(GORUN) build/ci.go xgo -- --go=$(GO) --targets=windows/amd64 -v ./cmd/geth @echo "Windows amd64 cross compilation done:" @ls -ld $(GOBIN)/geth-windows-* | grep amd64 + +PACKAGE_NAME := github.com/maticnetwork/bor +GOLANG_CROSS_VERSION ?= v1.17.2 + +.PHONY: release-dry-run +release-dry-run: + @docker run \ + --rm \ + --privileged \ + -e CGO_ENABLED=1 \ + -e GITHUB_TOKEN \ + -e DOCKER_USERNAME \ + -e DOCKER_PASSWORD \ + -v /var/run/docker.sock:/var/run/docker.sock \ + -v `pwd`:/go/src/$(PACKAGE_NAME) \ + -w /go/src/$(PACKAGE_NAME) \ + ghcr.io/troian/golang-cross:${GOLANG_CROSS_VERSION} \ + --rm-dist --skip-validate --skip-publish + +.PHONY: release +release: + @docker run \ + --rm \ + --privileged \ + -e CGO_ENABLED=1 \ + -e GITHUB_TOKEN \ + -e DOCKER_USERNAME \ + -e DOCKER_PASSWORD \ + -e SLACK_WEBHOOK \ + -v /var/run/docker.sock:/var/run/docker.sock \ + -v `pwd`:/go/src/$(PACKAGE_NAME) \ + -w /go/src/$(PACKAGE_NAME) \ + ghcr.io/troian/golang-cross:${GOLANG_CROSS_VERSION} \ + --rm-dist --skip-validate diff --git a/builder/files/bor.service b/builder/files/bor.service new file mode 100644 index 0000000000..18d075f799 --- /dev/null +++ b/builder/files/bor.service @@ -0,0 +1,18 @@ +[Unit] + Description=bor + StartLimitIntervalSec=500 + StartLimitBurst=5 + +[Service] + Restart=on-failure + RestartSec=5s + WorkingDirectory=$NODE_DIR + EnvironmentFile=/etc/matic/metadata + ExecStart=/usr/local/bin/bor $VALIDATOR_ADDRESS + Type=simple + User=$USER + KillSignal=SIGINT + TimeoutStopSec=120 + +[Install] + WantedBy=multi-user.target From f3a43f947261a0d7b96628c6c059b89e180acc5a Mon Sep 17 00:00:00 2001 From: Shivam Sharma Date: Fri, 12 Nov 2021 13:13:28 +0530 Subject: [PATCH 33/51] Added Prometheus to New CLI: fixes --- command/server/config.go | 14 +++------- command/server/server.go | 57 ++++++++++++++++++++++++++-------------- 2 files changed, 40 insertions(+), 31 deletions(-) diff --git a/command/server/config.go b/command/server/config.go index 34fa13cf51..dd3f5dce95 100644 --- a/command/server/config.go +++ b/command/server/config.go @@ -88,9 +88,6 @@ type Config struct { // GRPC has the grpc server related settings GRPC *GRPCConfig - - // Prometheus Server - Prometheus *PrometheusConfig `hcl:"prometheus,optional"` } type P2PConfig struct { @@ -239,14 +236,6 @@ type GRPCConfig struct { Addr string } -type PrometheusConfig struct { - // Enabled selects whether the api is enabled - Enabled bool `hcl:"enabled,optional"` - - // Host is the address to bind the api - address string `hcl:"host,optional"` -} - type APIConfig struct { // Enabled selects whether the api is enabled Enabled bool `hcl:"enabled,optional"` @@ -286,6 +275,9 @@ type TelemetryConfig struct { // InfluxDB has the influxdb related settings InfluxDB *InfluxDBConfig `hcl:"influx,block"` + + // Prometheus Address + PrometheusAddr string `hcl:"prometheus-addr,optional"` } type InfluxDBConfig struct { diff --git a/command/server/server.go b/command/server/server.go index 5981f0cf48..2c06804cc6 100644 --- a/command/server/server.go +++ b/command/server/server.go @@ -20,6 +20,7 @@ import ( "github.com/ethereum/go-ethereum/metrics" "github.com/ethereum/go-ethereum/metrics/exp" "github.com/ethereum/go-ethereum/metrics/influxdb" + "github.com/ethereum/go-ethereum/metrics/prometheus" "github.com/ethereum/go-ethereum/node" "github.com/fjl/memsize/memsizeui" "github.com/mattn/go-colorable" @@ -50,11 +51,6 @@ func NewServer(config *Config) (*Server, error) { return nil, err } - // start the Prometheus Server - if err := srv.StartPrometheus(config.Prometheus.address, config.Prometheus.Enabled); err != nil { - return nil, err - } - // create the node/stack nodeCfg, err := config.buildNode() if err != nil { @@ -159,6 +155,42 @@ func (s *Server) setupMetrics(config *TelemetryConfig) error { // Start system runtime metrics collection go metrics.CollectProcessMetrics(3 * time.Second) + // Hook go-metrics into expvar on any /debug/metrics request, load all vars + // from the registry into expvar, and execute regular expvar handler. + + if len(config.PrometheusAddr) != 0 { + + prometheusMux := http.NewServeMux() + + // this would cause a panic: + // panic: http: multiple registrations for /debug/vars + // http.HandleFunc("/debug/vars", e.expHandler) + // haven't found an elegant way, so just use a different endpoint + + prometheusMux.HandleFunc("/debug/metrics", func(w http.ResponseWriter, r *http.Request) { + exp.ExpHandler(metrics.DefaultRegistry) + }) + + prometheusMux.HandleFunc("/debug/metrics/prometheus", func(w http.ResponseWriter, r *http.Request) { + prometheus.Handler(metrics.DefaultRegistry) + }) + + promServer := &http.Server{ + Addr: config.PrometheusAddr, + Handler: prometheusMux, + ReadTimeout: 10 * time.Second, + WriteTimeout: 10 * time.Second, + MaxHeaderBytes: 1 << 20, + } + + go func() { + if err := promServer.ListenAndServe(); err != nil { + log.Error("Failure in running Prometheus server", "err", err) + } + }() + + } + return nil } @@ -182,21 +214,6 @@ func (s *Server) setupGRPCServer(addr string) error { } func (s *Server) StartPrometheus(address string, enabled bool) error { - // Hook go-metrics into expvar on any /debug/metrics request, load all vars - // from the registry into expvar, and execute regular expvar handler. - if enabled { - exp.Exp(metrics.DefaultRegistry) - } - - http.Handle("/memsize/", http.StripPrefix("/memsize", &Memsize)) - - log.Info("Starting pprof server", "addr", fmt.Sprintf("http://%s/debug/pprof", address)) - - go func() { - if err := http.ListenAndServe(address, nil); err != nil { - log.Error("Failure in running pprof server", "err", err) - } - }() return nil } From c23cd5e3326a970fcf5714f4e8806c61d2934ac2 Mon Sep 17 00:00:00 2001 From: Shivam Sharma Date: Fri, 12 Nov 2021 13:18:08 +0530 Subject: [PATCH 34/51] minor Clean --- command/server/server.go | 5 ----- 1 file changed, 5 deletions(-) diff --git a/command/server/server.go b/command/server/server.go index 2c06804cc6..09f33d4c80 100644 --- a/command/server/server.go +++ b/command/server/server.go @@ -213,11 +213,6 @@ func (s *Server) setupGRPCServer(addr string) error { return nil } -func (s *Server) StartPrometheus(address string, enabled bool) error { - - return nil -} - func (s *Server) withLoggingUnaryInterceptor() grpc.ServerOption { return grpc.UnaryInterceptor(s.loggingServerInterceptor) } From a5bcab1c658a008446bf6b1895be72fe4016b872 Mon Sep 17 00:00:00 2001 From: Shivam Sharma Date: Fri, 12 Nov 2021 14:24:21 +0530 Subject: [PATCH 35/51] Minor Clean-up --- command/server/server.go | 16 ++++------------ 1 file changed, 4 insertions(+), 12 deletions(-) diff --git a/command/server/server.go b/command/server/server.go index 09f33d4c80..c19f7af713 100644 --- a/command/server/server.go +++ b/command/server/server.go @@ -18,7 +18,6 @@ import ( "github.com/ethereum/go-ethereum/graphql" "github.com/ethereum/go-ethereum/log" "github.com/ethereum/go-ethereum/metrics" - "github.com/ethereum/go-ethereum/metrics/exp" "github.com/ethereum/go-ethereum/metrics/influxdb" "github.com/ethereum/go-ethereum/metrics/prometheus" "github.com/ethereum/go-ethereum/node" @@ -158,7 +157,7 @@ func (s *Server) setupMetrics(config *TelemetryConfig) error { // Hook go-metrics into expvar on any /debug/metrics request, load all vars // from the registry into expvar, and execute regular expvar handler. - if len(config.PrometheusAddr) != 0 { + if config.PrometheusAddr != "" { prometheusMux := http.NewServeMux() @@ -167,20 +166,13 @@ func (s *Server) setupMetrics(config *TelemetryConfig) error { // http.HandleFunc("/debug/vars", e.expHandler) // haven't found an elegant way, so just use a different endpoint - prometheusMux.HandleFunc("/debug/metrics", func(w http.ResponseWriter, r *http.Request) { - exp.ExpHandler(metrics.DefaultRegistry) - }) - - prometheusMux.HandleFunc("/debug/metrics/prometheus", func(w http.ResponseWriter, r *http.Request) { + prometheusMux.HandleFunc("/metrics", func(w http.ResponseWriter, r *http.Request) { prometheus.Handler(metrics.DefaultRegistry) }) promServer := &http.Server{ - Addr: config.PrometheusAddr, - Handler: prometheusMux, - ReadTimeout: 10 * time.Second, - WriteTimeout: 10 * time.Second, - MaxHeaderBytes: 1 << 20, + Addr: config.PrometheusAddr, + Handler: prometheusMux, } go func() { From cd6a1633917002b9ef42499cb5768de74ad4fff5 Mon Sep 17 00:00:00 2001 From: Shivam Sharma Date: Fri, 12 Nov 2021 14:51:18 +0530 Subject: [PATCH 36/51] minor cleanup --- command/server/server.go | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/command/server/server.go b/command/server/server.go index c19f7af713..be745ecce2 100644 --- a/command/server/server.go +++ b/command/server/server.go @@ -21,14 +21,11 @@ import ( "github.com/ethereum/go-ethereum/metrics/influxdb" "github.com/ethereum/go-ethereum/metrics/prometheus" "github.com/ethereum/go-ethereum/node" - "github.com/fjl/memsize/memsizeui" "github.com/mattn/go-colorable" "github.com/mattn/go-isatty" "google.golang.org/grpc" ) -var Memsize memsizeui.Handler - type Server struct { proto.UnimplementedBorServer node *node.Node @@ -154,18 +151,10 @@ func (s *Server) setupMetrics(config *TelemetryConfig) error { // Start system runtime metrics collection go metrics.CollectProcessMetrics(3 * time.Second) - // Hook go-metrics into expvar on any /debug/metrics request, load all vars - // from the registry into expvar, and execute regular expvar handler. - if config.PrometheusAddr != "" { prometheusMux := http.NewServeMux() - // this would cause a panic: - // panic: http: multiple registrations for /debug/vars - // http.HandleFunc("/debug/vars", e.expHandler) - // haven't found an elegant way, so just use a different endpoint - prometheusMux.HandleFunc("/metrics", func(w http.ResponseWriter, r *http.Request) { prometheus.Handler(metrics.DefaultRegistry) }) From 358e68364fa507955c5adc0c3438d65616d7b1a3 Mon Sep 17 00:00:00 2001 From: Shivam Sharma Date: Fri, 12 Nov 2021 18:54:04 +0530 Subject: [PATCH 37/51] Added Prometheus Flag and Default --- command/server/config.go | 5 +++-- command/server/flags.go | 5 +++++ 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/command/server/config.go b/command/server/config.go index dd3f5dce95..7f07015a54 100644 --- a/command/server/config.go +++ b/command/server/config.go @@ -441,8 +441,9 @@ func DefaultConfig() *Config { }, Ethstats: "", Telemetry: &TelemetryConfig{ - Enabled: false, - Expensive: false, + Enabled: false, + Expensive: false, + PrometheusAddr: "", InfluxDB: &InfluxDBConfig{ V1Enabled: false, Endpoint: "", diff --git a/command/server/flags.go b/command/server/flags.go index 303e5e9818..9b13cc44bc 100644 --- a/command/server/flags.go +++ b/command/server/flags.go @@ -396,6 +396,11 @@ func (c *Command) Flags() *flagset.Flagset { Usage: "Comma-separated InfluxDB tags (key/values) attached to all measurements", Value: &c.cliConfig.Telemetry.InfluxDB.Tags, }) + f.StringFlag(&flagset.StringFlag{ + Name: "metrics.prometheus-addr", + Usage: "Address for Prometheus Server", + Value: &c.cliConfig.Telemetry.PrometheusAddr, + }) // influx db v2 f.BoolFlag(&flagset.BoolFlag{ Name: "metrics.influxdbv2", From 322e9642337a754704b6375e1592e774b4ec023e Mon Sep 17 00:00:00 2001 From: Manav Darji Date: Wed, 17 Nov 2021 14:17:04 +0530 Subject: [PATCH 38/51] added opentelemetry config, flags, and setup (#235) * added opentelemetry config, flags, and setup * modifications in opencollector flag and config * bug fix * modified error log --- command/server/config.go | 10 +++++--- command/server/flags.go | 5 ++++ command/server/server.go | 55 ++++++++++++++++++++++++++++++++++++++++ go.mod | 9 ++++--- go.sum | 51 +++++++++++++++++++++++++++++++------ 5 files changed, 116 insertions(+), 14 deletions(-) diff --git a/command/server/config.go b/command/server/config.go index 7f07015a54..45a19553d7 100644 --- a/command/server/config.go +++ b/command/server/config.go @@ -278,6 +278,9 @@ type TelemetryConfig struct { // Prometheus Address PrometheusAddr string `hcl:"prometheus-addr,optional"` + + // Open collector endpoint + OpenCollectorEndpoint string `hcl:"opencollector-endpoint,optional"` } type InfluxDBConfig struct { @@ -441,9 +444,10 @@ func DefaultConfig() *Config { }, Ethstats: "", Telemetry: &TelemetryConfig{ - Enabled: false, - Expensive: false, - PrometheusAddr: "", + Enabled: false, + Expensive: false, + PrometheusAddr: "", + OpenCollectorEndpoint: "", InfluxDB: &InfluxDBConfig{ V1Enabled: false, Endpoint: "", diff --git a/command/server/flags.go b/command/server/flags.go index 9b13cc44bc..8e995c9bfa 100644 --- a/command/server/flags.go +++ b/command/server/flags.go @@ -401,6 +401,11 @@ func (c *Command) Flags() *flagset.Flagset { Usage: "Address for Prometheus Server", Value: &c.cliConfig.Telemetry.PrometheusAddr, }) + f.StringFlag(&flagset.StringFlag{ + Name: "metrics.opencollector-endpoint", + Usage: "OpenCollector Endpoint (host:port)", + Value: &c.cliConfig.Telemetry.OpenCollectorEndpoint, + }) // influx db v2 f.BoolFlag(&flagset.BoolFlag{ Name: "metrics.influxdbv2", diff --git a/command/server/server.go b/command/server/server.go index b2406b276b..8629ef312e 100644 --- a/command/server/server.go +++ b/command/server/server.go @@ -23,6 +23,12 @@ import ( "github.com/ethereum/go-ethereum/node" "github.com/mattn/go-colorable" "github.com/mattn/go-isatty" + "go.opentelemetry.io/otel" + "go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc" + "go.opentelemetry.io/otel/propagation" + "go.opentelemetry.io/otel/sdk/resource" + sdktrace "go.opentelemetry.io/otel/sdk/trace" + semconv "go.opentelemetry.io/otel/semconv/v1.4.0" "google.golang.org/grpc" ) @@ -31,6 +37,7 @@ type Server struct { node *node.Node backend *eth.Ethereum grpcServer *grpc.Server + tracer *sdktrace.TracerProvider } func NewServer(config *Config) (*Server, error) { @@ -117,6 +124,13 @@ func NewServer(config *Config) (*Server, error) { func (s *Server) Stop() { s.node.Close() + + // shutdown the tracer + if s.tracer != nil { + if err := s.tracer.Shutdown(context.Background()); err != nil { + log.Error("Failed to shutdown open telemetry tracer") + } + } } func (s *Server) setupMetrics(config *TelemetryConfig) error { @@ -174,6 +188,47 @@ func (s *Server) setupMetrics(config *TelemetryConfig) error { } + if config.OpenCollectorEndpoint != "" { + // setup open collector tracer + ctx := context.Background() + + res, err := resource.New(ctx, + resource.WithAttributes( + // the service name used to display traces in backends + semconv.ServiceNameKey.String("bor"), // TODO: use the service name from the config + ), + ) + if err != nil { + return fmt.Errorf("failed to create open telemetry resource for service: %v", err) + } + + // Set up a trace exporter + traceExporter, err := otlptracegrpc.New( + ctx, + otlptracegrpc.WithInsecure(), + otlptracegrpc.WithEndpoint(config.OpenCollectorEndpoint), + ) + if err != nil { + return fmt.Errorf("failed to create open telemetry tracer exporter for service: %v", err) + } + + // Register the trace exporter with a TracerProvider, using a batch + // span processor to aggregate spans before export. + bsp := sdktrace.NewBatchSpanProcessor(traceExporter) + tracerProvider := sdktrace.NewTracerProvider( + sdktrace.WithSampler(sdktrace.AlwaysSample()), + sdktrace.WithResource(res), + sdktrace.WithSpanProcessor(bsp), + ) + otel.SetTracerProvider(tracerProvider) + + // set global propagator to tracecontext (the default is no-op). + otel.SetTextMapPropagator(propagation.TraceContext{}) + + // set the tracer + s.tracer = tracerProvider + } + return nil } diff --git a/go.mod b/go.mod index c8bc297a8d..c591ea1951 100644 --- a/go.mod +++ b/go.mod @@ -31,7 +31,7 @@ require ( github.com/go-ole/go-ole v1.2.1 // indirect github.com/go-sourcemap/sourcemap v2.1.2+incompatible // indirect github.com/go-stack/stack v1.8.0 - github.com/golang/protobuf v1.4.3 + github.com/golang/protobuf v1.5.2 github.com/golang/snappy v0.0.4 github.com/google/gofuzz v1.1.1-0.20200604201612-c04b05f3adfa github.com/google/uuid v1.1.5 @@ -70,14 +70,17 @@ require ( github.com/tklauser/go-sysconf v0.3.5 // indirect github.com/tyler-smith/go-bip39 v1.0.1-0.20181017060643-dbb3b84ba2ef github.com/xsleonard/go-merkle v1.1.0 + go.opentelemetry.io/otel v1.2.0 + go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.2.0 + go.opentelemetry.io/otel/sdk v1.2.0 golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2 golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d // indirect golang.org/x/sync v0.0.0-20210220032951-036812b2e83c golang.org/x/sys v0.0.0-20210816183151-1e6c022a8912 golang.org/x/text v0.3.6 golang.org/x/time v0.0.0-20210220033141-f8bda1e9f3ba - google.golang.org/grpc v1.37.0 - google.golang.org/protobuf v1.26.0-rc.1 + google.golang.org/grpc v1.42.0 + google.golang.org/protobuf v1.27.1 gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 // indirect gopkg.in/natefinch/npipe.v2 v2.0.0-20160621034901-c1b8fa8bdcce gopkg.in/olebedev/go-duktape.v3 v3.0.0-20200619000410-60c24ae608a6 diff --git a/go.sum b/go.sum index b150bdcf8e..950974266f 100644 --- a/go.sum +++ b/go.sum @@ -61,6 +61,7 @@ github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRF github.com/allegro/bigcache v1.2.1-0.20190218064605-e24eb225f156 h1:eMwmnE/GDgah4HI848JfFxHt+iPb26b4zyfspmqY0/8= github.com/allegro/bigcache v1.2.1-0.20190218064605-e24eb225f156/go.mod h1:Cb/ax3seSYIx7SuZdm2G2xzfwmv3TPSk2ucNfQESPXM= github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883/go.mod h1:rCTlJbsFo29Kk6CurOXKm700vrz8f0KW0JNfpkRJY/8= +github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= github.com/apache/arrow/go/arrow v0.0.0-20191024131854-af6fa24be0db/go.mod h1:VTxUBvSJ3s3eHAg65PNgrsn5BtqCRPdmyXh6rAfdxN0= github.com/apparentlymart/go-dump v0.0.0-20180507223929-23540a00eaa3/go.mod h1:oL81AME2rN47vu18xqj1S1jPIPuN7afo62yKTNn3XMM= github.com/apparentlymart/go-textseg v1.0.0 h1:rRmlIsPEEhUTIKQb7T++Nz/A5Q6C9IuX2wFoYVvnCs0= @@ -103,6 +104,8 @@ github.com/btcsuite/snappy-go v0.0.0-20151229074030-0bdef8d06723/go.mod h1:8woku github.com/btcsuite/websocket v0.0.0-20150119174127-31079b680792/go.mod h1:ghJtEyQwv5/p4Mg4C0fgbePVuGr935/5ddU9Z3TmDRY= github.com/btcsuite/winsvc v1.0.0/go.mod h1:jsenWakMcC0zFBFurPLEAyrnc/teJEM1O46fmI40EZs= github.com/c-bata/go-prompt v0.2.2/go.mod h1:VzqtzE2ksDBcdln8G7mk2RX9QyGjH+OVqOCSiVIqS34= +github.com/cenkalti/backoff/v4 v4.1.1 h1:G2HAfAmvm/GcKan2oOQpBXOd2tT2G57ZnZGWa1PxPBQ= +github.com/cenkalti/backoff/v4 v4.1.1/go.mod h1:scbssz8iZGpm3xbr14ovlUdkxfGXNInqkPWOWmG2CLw= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/cespare/cp v0.1.0 h1:SE+dxFebS7Iik5LK0tsi1k9ZCxEaFX4AjQmoyA+1dJk= github.com/cespare/cp v0.1.0/go.mod h1:SOGHArjBr4JWaSDEVpWpo/hNg6RoKrls6Oh40hiwW+s= @@ -116,7 +119,12 @@ github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMn github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/cloudflare/cloudflare-go v0.14.0 h1:gFqGlGl/5f9UGXAaKapCGUfaTCgRKKnzu2VvzMZlOFA= github.com/cloudflare/cloudflare-go v0.14.0/go.mod h1:EnwdgGMaFOruiPZRFSgn+TsQ3hQ7C/YWzIGLeu5c304= +github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= +github.com/cncf/udpa/go v0.0.0-20210930031921-04548b0d99d4/go.mod h1:6pvJx4me5XPnfI9Z40ddWsdw2W/uZgQLFXToKeRcDiI= +github.com/cncf/xds/go v0.0.0-20210805033703-aa0b78936158/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= +github.com/cncf/xds/go v0.0.0-20210922020428-25de7278fc84/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= +github.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/consensys/bavard v0.1.8-0.20210406032232-f3452dc9b572/go.mod h1:Bpd0/3mZuaj6Sj+PqrmIquiOKy397AKGThQPaGzNXAQ= github.com/consensys/gnark-crypto v0.4.1-0.20210426202927-39ac3d4b3f1f h1:C43yEtQ6NIf4ftFXD/V55gnGFgPbMQobd//YlnLjUJ8= github.com/consensys/gnark-crypto v0.4.1-0.20210426202927-39ac3d4b3f1f/go.mod h1:815PAHg3wvysy0SyIqanF8gZ0Y1wjk/hrDHD/iT88+Q= @@ -147,7 +155,9 @@ github.com/edsrzf/mmap-go v1.0.0 h1:CEBF7HpRnUCSJgGUb5h1Gm7e3VkmVDrR8lvWVLtrOFw= github.com/edsrzf/mmap-go v1.0.0/go.mod h1:YO35OhQPt3KJa3ryjFM5Bs14WD66h8eGKpfaBNrHW5M= github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= -github.com/envoyproxy/go-control-plane v0.9.9-0.20210217033140-668b12f5399d/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= +github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= +github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= +github.com/envoyproxy/go-control-plane v0.9.10-0.20210907150352-cf90f659a021/go.mod h1:AFq3mo9L8Lqqiid3OhADV3RfLJnjiw63cSpi+fDTRC0= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= github.com/fatih/color v1.7.0 h1:DkWD4oS2D8LGGgTQ6IvwJJXSL5Vp2ffcQg58nFV38Ys= github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= @@ -200,6 +210,7 @@ github.com/golang/protobuf v1.1.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5y github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= github.com/golang/protobuf v1.3.4/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= @@ -208,8 +219,10 @@ github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:W github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= -github.com/golang/protobuf v1.4.3 h1:JjCZWpVbqXDqFVmTfYWEVTMIYrL/NPdPSCHPJ0T/raM= github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= +github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= +github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw= +github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/golang/snappy v0.0.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM= @@ -225,8 +238,9 @@ github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/ github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.6 h1:BKbKCqvP6I+rmFHt06ZmyQtvB8xAkWdhFyr0ZUNZcxQ= +github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/gofuzz v1.1.1-0.20200604201612-c04b05f3adfa h1:Q75Upo5UN4JbPFURXZ8nLKYUvF85dyFRop/vQ0Rv+64= github.com/google/gofuzz v1.1.1-0.20200604201612-c04b05f3adfa/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= @@ -245,6 +259,8 @@ github.com/gorilla/websocket v1.4.2 h1:+/TMaTYc4QFitKJxsQ7Yye35DkWvkdLcvGKqM+x0U github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/graph-gophers/graphql-go v0.0.0-20201113091052-beb923fada29 h1:sezaKhEfPFg8W0Enm61B9Gs911H8iesGY5R8NDPtd1M= github.com/graph-gophers/graphql-go v0.0.0-20201113091052-beb923fada29/go.mod h1:9CQHMSxwO4MprSdzoIEobiHpoLtHm77vfxsvsIN5Vuc= +github.com/grpc-ecosystem/grpc-gateway v1.16.0 h1:gmcG1KaJ57LophUzW0Hy8NmPhnMZb4M0+kPpLofRdBo= +github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= github.com/hashicorp/errwrap v1.0.0 h1:hLrqtEDnRye3+sgx6z4qVLNuviH3MR5aQ0ykNJa/UYA= github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= github.com/hashicorp/go-multierror v1.0.0 h1:iVjPR7a6H0tWELX5NxNe7bYopibicUzc7uPribsnS6o= @@ -414,6 +430,7 @@ github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40T github.com/retailnext/hllpp v1.0.1-0.20180308014038-101a6d2f8b52/go.mod h1:RDpi1RftBQPUCDRw6SmxeaREsAaRKnOclghuzp/WRzc= github.com/rjeczalik/notify v0.9.1 h1:CLCKso/QK1snAlnhNR/CNvNiFU2saUtjV0bx3EwNeCE= github.com/rjeczalik/notify v0.9.1/go.mod h1:rKwnCoCGeuQnwBtTSPL9Dad03Vh2n40ePRrjvIXnJho= +github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rs/cors v1.7.0 h1:+88SsELBHx5r+hZ8TCkggzSstaWNbDvThkVK8H6f9ik= github.com/rs/cors v1.7.0/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU= @@ -476,6 +493,19 @@ github.com/zclconf/go-cty-debug v0.0.0-20191215020915-b22d67c1ba0b/go.mod h1:ZRK go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= +go.opentelemetry.io/otel v1.2.0 h1:YOQDvxO1FayUcT9MIhJhgMyNO1WqoduiyvQHzGN0kUQ= +go.opentelemetry.io/otel v1.2.0/go.mod h1:aT17Fk0Z1Nor9e0uisf98LrntPGMnk4frBO9+dkf69I= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.2.0 h1:xzbcGykysUh776gzD1LUPsNNHKWN0kQWDnJhn1ddUuk= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.2.0/go.mod h1:14T5gr+Y6s2AgHPqBMgnGwp04csUjQmYXFWPeiBoq5s= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.2.0 h1:VsgsSCDwOSuO8eMVh63Cd4nACMqgjpmAeJSIvVNneD0= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.2.0/go.mod h1:9mLBBnPRf3sf+ASVH2p9xREXVBvwib02FxcKnavtExg= +go.opentelemetry.io/otel/sdk v1.2.0 h1:wKN260u4DesJYhyjxDa7LRFkuhH7ncEVKU37LWcyNIo= +go.opentelemetry.io/otel/sdk v1.2.0/go.mod h1:jNN8QtpvbsKhgaC6V5lHiejMoKD+V8uadoSafgHPx1U= +go.opentelemetry.io/otel/trace v1.2.0 h1:Ys3iqbqZhcf28hHzrm5WAquMkDHNZTUkw7KHbuNjej0= +go.opentelemetry.io/otel/trace v1.2.0/go.mod h1:N5FLswTubnxKxOJHM7XZC074qpeEdLy3CgAVsdMucK0= +go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI= +go.opentelemetry.io/proto/otlp v0.10.0 h1:n7brgtEbDvXEgGyKKo8SobKT1e9FewlDtXzkVP5djoE= +go.opentelemetry.io/proto/otlp v0.10.0/go.mod h1:zG20xCK0szZ1xdokeSOwEcmlXu+x9kkdRe6N1DhKcfU= go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= go.uber.org/zap v1.9.1/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= @@ -598,6 +628,7 @@ golang.org/x/sys v0.0.0-20210316164454-77fc1eacc6aa/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20210324051608-47abb6519492/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210420205809-ac73e9fd8988/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210423185535-09eb48e85fd7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210816183151-1e6c022a8912 h1:uCLL3g5wH2xjxVREVuAbP9JM5PPKjRbXKRa6IBjkzmU= golang.org/x/sys v0.0.0-20210816183151-1e6c022a8912/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= @@ -680,6 +711,7 @@ google.golang.org/genproto v0.0.0-20191115194625-c23dd37a84c9/go.mod h1:n3cpQtvx google.golang.org/genproto v0.0.0-20191216164720-4f79533eabd1/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= google.golang.org/genproto v0.0.0-20191230161307-f3c370f40bfb/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= google.golang.org/genproto v0.0.0-20200108215221-bd8f9a0ef82f/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013 h1:+kGHl1aib/qcwaRi1CbqBZ1rk19r85MNUf8HaBghugY= google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= @@ -689,10 +721,11 @@ google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyac google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= -google.golang.org/grpc v1.37.0 h1:uSZWeQJX5j11bIQ4AJoj+McDBo29cY1MCoC1wO3ts+c= -google.golang.org/grpc v1.37.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= -google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0 h1:M1YKkFIboKNieVO5DLUEVzQfGwJD30Nv2jfUgzb5UcE= -google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0/go.mod h1:6Kw0yEErY5E/yWrBtf03jp27GLLJujG4z/JK95pnjjw= +google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0= +google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= +google.golang.org/grpc v1.41.0/go.mod h1:U3l9uK9J0sini8mHphKoXyaqDA/8VyGnDee1zzIUK6k= +google.golang.org/grpc v1.42.0 h1:XT2/MFpuPFsEX2fWh3YQtHkZ+WYZFQRfaUgLZYj/p6A= +google.golang.org/grpc v1.42.0/go.mod h1:k+4IHHFw41K8+bbowsex27ge2rCb65oeWqe4jJ590SU= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= @@ -702,8 +735,10 @@ google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2 google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= -google.golang.org/protobuf v1.26.0-rc.1 h1:7QnIQpGRHE5RnLKnESfDoxm2dTapTZua5a0kS0A+VXQ= google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= +google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= +google.golang.org/protobuf v1.27.1 h1:SnqbnDw1V7RiZcXPx5MEeqPv2s79L9i7BJUlG/+RurQ= +google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= From 78ba316bcb0243ca83be0c3eff8cf8ac1470589c Mon Sep 17 00:00:00 2001 From: Victor Castell Date: Wed, 17 Nov 2021 14:47:37 +0100 Subject: [PATCH 39/51] Adapt Dockerfile for development (#237) * Adapt Dockerfile for development The Dockerfile for release using Alpine is in the included Dockerfile.release and this one was not used for release so doesn't make sense to have it using multistage nor Alpine. --- Dockerfile | 28 ++++++++-------------------- 1 file changed, 8 insertions(+), 20 deletions(-) diff --git a/Dockerfile b/Dockerfile index c12a8b1f4e..c3d13aa17a 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,29 +1,17 @@ -# Build Geth in a stock Go builder container -FROM golang:1.17-alpine as builder +FROM golang:latest -RUN set -x \ - && buildDeps='bash build-base musl-dev linux-headers git' \ - && apk add --update $buildDeps \ - && rm -rf /var/cache/apk/* \ +ARG BOR_DIR=/bor +ENV BOR_DIR=$BOR_DIR + +RUN apt-get update -y && apt-get upgrade -y \ + && apt install build-essential git tini -y \ && mkdir -p /bor -WORKDIR /bor +WORKDIR ${BOR_DIR} COPY . . RUN make bor-all -CMD ["/bin/bash"] - -# Pull Bor into a second stage deploy alpine container -FROM alpine:3.14 - -RUN set -x \ - && apk add --update --no-cache \ - ca-certificates \ - && rm -rf /var/cache/apk/* - -COPY --from=builder /bor/build/bin/bor /usr/local/bin/ -COPY --from=builder /bor/build/bin/bootnode /usr/local/bin/ - +ENV SHELL /bin/bash EXPOSE 8545 8546 8547 30303 30303/udp ENTRYPOINT ["bor"] From 87f9b91b254fd44264d1db353208a722fb818083 Mon Sep 17 00:00:00 2001 From: Manav Darji Date: Wed, 17 Nov 2021 20:00:42 +0530 Subject: [PATCH 40/51] added service name in config and flags (#238) --- command/server/config.go | 12 ++++++++++++ command/server/flags.go | 5 +++++ command/server/server.go | 6 +++--- 3 files changed, 20 insertions(+), 3 deletions(-) diff --git a/command/server/config.go b/command/server/config.go index 45a19553d7..254dbda4be 100644 --- a/command/server/config.go +++ b/command/server/config.go @@ -38,6 +38,9 @@ type Config struct { // Chain is the chain to sync with Chain string `hcl:"chain,optional"` + // Name, or identity of the node + Name string `hcl:"name,optional"` + // Whitelist is a list of required (block number, hash) pairs to accept Whitelist map[string]string `hcl:"whitelist,optional"` @@ -365,6 +368,7 @@ type AccountsConfig struct { func DefaultConfig() *Config { return &Config{ Chain: "mainnet", + Name: Hostname(), Whitelist: map[string]string{}, LogLevel: "INFO", DataDir: defaultDataDir(), @@ -885,3 +889,11 @@ func defaultDataDir() string { return filepath.Join(home, ".bor") } } + +func Hostname() string { + hostname, err := os.Hostname() + if err != nil { + return "bor" + } + return hostname +} diff --git a/command/server/flags.go b/command/server/flags.go index 8e995c9bfa..76828ef6fc 100644 --- a/command/server/flags.go +++ b/command/server/flags.go @@ -14,6 +14,11 @@ func (c *Command) Flags() *flagset.Flagset { Usage: "Name of the chain to sync", Value: &c.cliConfig.Chain, }) + f.StringFlag(&flagset.StringFlag{ + Name: "name", + Usage: "Name/Identity of the node", + Value: &c.cliConfig.Name, + }) f.StringFlag(&flagset.StringFlag{ Name: "log-level", Usage: "Set log level for the server", diff --git a/command/server/server.go b/command/server/server.go index 8629ef312e..bab4673214 100644 --- a/command/server/server.go +++ b/command/server/server.go @@ -111,7 +111,7 @@ func NewServer(config *Config) (*Server, error) { } } - if err := srv.setupMetrics(config.Telemetry); err != nil { + if err := srv.setupMetrics(config.Telemetry, config.Name); err != nil { return nil, err } @@ -133,7 +133,7 @@ func (s *Server) Stop() { } } -func (s *Server) setupMetrics(config *TelemetryConfig) error { +func (s *Server) setupMetrics(config *TelemetryConfig, serviceName string) error { metrics.Enabled = config.Enabled metrics.EnabledExpensive = config.Expensive @@ -195,7 +195,7 @@ func (s *Server) setupMetrics(config *TelemetryConfig) error { res, err := resource.New(ctx, resource.WithAttributes( // the service name used to display traces in backends - semconv.ServiceNameKey.String("bor"), // TODO: use the service name from the config + semconv.ServiceNameKey.String(serviceName), ), ) if err != nil { From 6f5915363e57c61457d35c9f492628a54b0ad110 Mon Sep 17 00:00:00 2001 From: Arpit Temani Date: Thu, 25 Nov 2021 12:46:51 +0530 Subject: [PATCH 41/51] Arpit/reorg fix 2 (#210) * testing * author check * if else fix --- miner/worker.go | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/miner/worker.go b/miner/worker.go index 8bdb1eff7c..9412446eed 100644 --- a/miner/worker.go +++ b/miner/worker.go @@ -606,6 +606,15 @@ func (w *worker) resultLoop() { if w.chain.HasBlock(block.Hash(), block.NumberU64()) { continue } + oldBlock := w.chain.GetBlockByNumber(block.NumberU64()) + if oldBlock != nil { + oldBlockAuthor, _ := w.chain.Engine().Author(oldBlock.Header()) + newBlockAuthor, _ := w.chain.Engine().Author(block.Header()) + if oldBlockAuthor == newBlockAuthor { + log.Info("same block ", "height", block.NumberU64()) + continue + } + } var ( sealhash = w.engine.SealHash(block.Header()) hash = block.Hash() From b1fb79a511104128e0ba1cfa237613e5a0503538 Mon Sep 17 00:00:00 2001 From: Victor Castell Date: Tue, 30 Nov 2021 12:19:27 +0100 Subject: [PATCH 42/51] Small tweeks to Dockerfiles (#247) Standardize Dockerfile between projects (Heimdall) and remove not necessary tini package. --- Dockerfile | 2 +- Dockerfile.release | 5 +---- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/Dockerfile b/Dockerfile index c3d13aa17a..8af791ab3f 100644 --- a/Dockerfile +++ b/Dockerfile @@ -4,7 +4,7 @@ ARG BOR_DIR=/bor ENV BOR_DIR=$BOR_DIR RUN apt-get update -y && apt-get upgrade -y \ - && apt install build-essential git tini -y \ + && apt install build-essential git -y \ && mkdir -p /bor WORKDIR ${BOR_DIR} diff --git a/Dockerfile.release b/Dockerfile.release index c0ae7f9c29..439524edbf 100644 --- a/Dockerfile.release +++ b/Dockerfile.release @@ -1,9 +1,6 @@ FROM alpine:3.14 -RUN set -x \ - && apk add --update --no-cache \ - ca-certificates \ - && rm -rf /var/cache/apk/* +RUN apk add --no-cache ca-certificates COPY bor /usr/local/bin/ EXPOSE 8545 8546 8547 30303 30303/udp From d3010f49bd7be9399e92404e19e35dd7cca397b1 Mon Sep 17 00:00:00 2001 From: Ferran Borreguero Date: Wed, 1 Dec 2021 16:08:13 +0100 Subject: [PATCH 43/51] Fix ancestor bor receipts (#249) --- core/blockchain.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/core/blockchain.go b/core/blockchain.go index 753ca4abb2..05108a9c6b 100644 --- a/core/blockchain.go +++ b/core/blockchain.go @@ -1222,14 +1222,14 @@ func (bc *BlockChain) InsertReceiptChain(blockChain types.Blocks, receiptChain [ } // BOR: Retrieve all the bor receipts. - borReceipts := types.Receipts{} + borReceipts := []types.Receipts{} for _, block := range blockChain { - borReceipts = append(borReceipts, bc.GetBorReceiptByHash(block.Hash())) + borReceipts = append(borReceipts, []*types.Receipt{bc.GetBorReceiptByHash(block.Hash())}) } // Write all chain data to ancients. td := bc.GetTd(first.Hash(), first.NumberU64()) - writeSize, err := rawdb.WriteAncientBlocks(bc.db, blockChain, receiptChain, []types.Receipts{borReceipts}, td) + writeSize, err := rawdb.WriteAncientBlocks(bc.db, blockChain, receiptChain, borReceipts, td) size += writeSize if err != nil { log.Error("Error importing chain data to ancients", "err", err) From cf900a96a7db84b5277a654b0a124cf86a2c67b0 Mon Sep 17 00:00:00 2001 From: Shivam Sharma Date: Thu, 2 Dec 2021 17:18:19 +0530 Subject: [PATCH 44/51] Changed syncmode from fast to full --- command/server/config.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/command/server/config.go b/command/server/config.go index 254dbda4be..c9ffff481d 100644 --- a/command/server/config.go +++ b/command/server/config.go @@ -393,7 +393,7 @@ func DefaultConfig() *Config { URL: "http://localhost:1317", Without: false, }, - SyncMode: "fast", + SyncMode: "full", GcMode: "full", Snapshot: true, TxPool: &TxPoolConfig{ From 533e989b85d9bba14f36f8e3480c1d19f4026ac6 Mon Sep 17 00:00:00 2001 From: Arpit Temani Date: Fri, 10 Dec 2021 16:08:15 +0530 Subject: [PATCH 45/51] london fork (#260) * london fork changes * Update version.go * burn contract address --- Makefile | 4 +- consensus/bor/bor.go | 32 +++- core/state_transition.go | 5 + eth/filters/filter_system_test.go | 16 +- internal/ethapi/bor_api.go | 2 +- params/config.go | 122 +++++++++++++-- params/version.go | 4 +- tests/bor/bor_test.go | 240 +++++++++++++++++++++++++++++- tests/bor/testdata/genesis.json | 18 ++- 9 files changed, 404 insertions(+), 39 deletions(-) diff --git a/Makefile b/Makefile index 462f129f51..50f3abda5e 100644 --- a/Makefile +++ b/Makefile @@ -50,8 +50,8 @@ ios: test: all # $(GORUN) build/ci.go test - go test github.com/ethereum/go-ethereum/consensus/bor - go test github.com/ethereum/go-ethereum/tests/bor + go test github.com/ethereum/go-ethereum/consensus/bor -v + go test github.com/ethereum/go-ethereum/tests/bor -v lint: ## Run linters. $(GORUN) build/ci.go lint diff --git a/consensus/bor/bor.go b/consensus/bor/bor.go index 51e7496559..94774d5032 100644 --- a/consensus/bor/bor.go +++ b/consensus/bor/bor.go @@ -182,12 +182,12 @@ func encodeSigHeader(w io.Writer, header *types.Header) { func CalcProducerDelay(number uint64, succession int, c *params.BorConfig) uint64 { // When the block is the first block of the sprint, it is expected to be delayed by `producerDelay`. // That is to allow time for block propagation in the last sprint - delay := c.Period + delay := c.CalculatePeriod(number) if number%c.Sprint == 0 { delay = c.ProducerDelay } if succession > 0 { - delay += uint64(succession) * c.BackupMultiplier + delay += uint64(succession) * c.CalculateBackupMultiplier(number) } return delay } @@ -353,6 +353,11 @@ func (c *Bor) verifyHeader(chain consensus.ChainHeaderReader, header *types.Head return errInvalidDifficulty } } + // Verify that the gas limit is <= 2^63-1 + cap := uint64(0x7fffffffffffffff) + if header.GasLimit > cap { + return fmt.Errorf("invalid gasLimit: have %v, max %v", header.GasLimit, cap) + } // If all checks passed, validate any special fields for hard forks if err := misc.VerifyForkHashes(chain.Config(), header, false); err != nil { return err @@ -396,7 +401,24 @@ func (c *Bor) verifyCascadingFields(chain consensus.ChainHeaderReader, header *t return consensus.ErrUnknownAncestor } - if parent.Time+c.config.Period > header.Time { + // Verify that the gasUsed is <= gasLimit + if header.GasUsed > header.GasLimit { + return fmt.Errorf("invalid gasUsed: have %d, gasLimit %d", header.GasUsed, header.GasLimit) + } + if !chain.Config().IsLondon(header.Number) { + // Verify BaseFee not present before EIP-1559 fork. + if header.BaseFee != nil { + return fmt.Errorf("invalid baseFee before fork: have %d, want ", header.BaseFee) + } + if err := misc.VerifyGaslimit(parent.GasLimit, header.GasLimit); err != nil { + return err + } + } else if err := misc.VerifyEip1559Header(chain.Config(), parent, header); err != nil { + // Verify the header's EIP-1559 attributes. + return err + } + + if parent.Time+c.config.CalculatePeriod(number) > header.Time { return ErrInvalidTimestamp } @@ -791,7 +813,7 @@ func (c *Bor) Seal(chain consensus.ChainHeaderReader, block *types.Block, result return errUnknownBlock } // For 0-period chains, refuse to seal empty blocks (no reward but would spin sealing) - if c.config.Period == 0 && len(block.Transactions()) == 0 { + if c.config.CalculatePeriod(number) == 0 && len(block.Transactions()) == 0 { log.Info("Sealing paused, waiting for transactions") return nil } @@ -819,7 +841,7 @@ func (c *Bor) Seal(chain consensus.ChainHeaderReader, block *types.Block, result // Sweet, the protocol permits us to sign the block, wait for our time delay := time.Unix(int64(header.Time), 0).Sub(time.Now()) // nolint: gosimple // wiggle was already accounted for in header.Time, this is just for logging - wiggle := time.Duration(successionNumber) * time.Duration(c.config.BackupMultiplier) * time.Second + wiggle := time.Duration(successionNumber) * time.Duration(c.config.CalculateBackupMultiplier(number)) * time.Second // Sign all the things! sighash, err := signFn(accounts.Account{Address: signer}, accounts.MimetypeBor, BorRLP(header)) diff --git a/core/state_transition.go b/core/state_transition.go index 4160c62253..f650922f2f 100644 --- a/core/state_transition.go +++ b/core/state_transition.go @@ -337,6 +337,11 @@ func (st *StateTransition) TransitionDb() (*ExecutionResult, error) { effectiveTip = cmath.BigMin(st.gasTipCap, new(big.Int).Sub(st.gasFeeCap, st.evm.Context.BaseFee)) } amount := new(big.Int).Mul(new(big.Int).SetUint64(st.gasUsed()), effectiveTip) + if london { + burntContractAddress := common.HexToAddress(st.evm.ChainConfig().Bor.CalculateBurntContract(st.evm.Context.BlockNumber.Uint64())) + burnAmount := new(big.Int).Mul(new(big.Int).SetUint64(st.gasUsed()), st.evm.Context.BaseFee) + st.state.AddBalance(burntContractAddress, burnAmount) + } st.state.AddBalance(st.evm.Context.Coinbase, amount) output1 := new(big.Int).SetBytes(input1.Bytes()) output2 := new(big.Int).SetBytes(input2.Bytes()) diff --git a/eth/filters/filter_system_test.go b/eth/filters/filter_system_test.go index 731d13a532..d38d2b0581 100644 --- a/eth/filters/filter_system_test.go +++ b/eth/filters/filter_system_test.go @@ -174,7 +174,7 @@ func TestBlockSubscription(t *testing.T) { var ( db = rawdb.NewMemoryDatabase() backend = &testBackend{db: db} - api = NewPublicFilterAPI(backend, false, deadline) + api = NewPublicFilterAPI(backend, false, deadline, false) genesis = (&core.Genesis{BaseFee: big.NewInt(params.InitialBaseFee)}).MustCommit(db) chain, _ = core.GenerateChain(params.TestChainConfig, genesis, ethash.NewFaker(), db, 10, func(i int, gen *core.BlockGen) {}) chainEvents = []core.ChainEvent{} @@ -226,7 +226,7 @@ func TestPendingTxFilter(t *testing.T) { var ( db = rawdb.NewMemoryDatabase() backend = &testBackend{db: db} - api = NewPublicFilterAPI(backend, false, deadline) + api = NewPublicFilterAPI(backend, false, deadline, false) transactions = []*types.Transaction{ types.NewTransaction(0, common.HexToAddress("0xb794f5ea0ba39494ce83a213fffba74279579268"), new(big.Int), 0, new(big.Int), nil), @@ -281,7 +281,7 @@ func TestLogFilterCreation(t *testing.T) { var ( db = rawdb.NewMemoryDatabase() backend = &testBackend{db: db} - api = NewPublicFilterAPI(backend, false, deadline) + api = NewPublicFilterAPI(backend, false, deadline, false) testCases = []struct { crit FilterCriteria @@ -325,7 +325,7 @@ func TestInvalidLogFilterCreation(t *testing.T) { var ( db = rawdb.NewMemoryDatabase() backend = &testBackend{db: db} - api = NewPublicFilterAPI(backend, false, deadline) + api = NewPublicFilterAPI(backend, false, deadline, false) ) // different situations where log filter creation should fail. @@ -347,7 +347,7 @@ func TestInvalidGetLogsRequest(t *testing.T) { var ( db = rawdb.NewMemoryDatabase() backend = &testBackend{db: db} - api = NewPublicFilterAPI(backend, false, deadline) + api = NewPublicFilterAPI(backend, false, deadline, false) blockHash = common.HexToHash("0x1111111111111111111111111111111111111111111111111111111111111111") ) @@ -372,7 +372,7 @@ func TestLogFilter(t *testing.T) { var ( db = rawdb.NewMemoryDatabase() backend = &testBackend{db: db} - api = NewPublicFilterAPI(backend, false, deadline) + api = NewPublicFilterAPI(backend, false, deadline, false) firstAddr = common.HexToAddress("0x1111111111111111111111111111111111111111") secondAddr = common.HexToAddress("0x2222222222222222222222222222222222222222") @@ -486,7 +486,7 @@ func TestPendingLogsSubscription(t *testing.T) { var ( db = rawdb.NewMemoryDatabase() backend = &testBackend{db: db} - api = NewPublicFilterAPI(backend, false, deadline) + api = NewPublicFilterAPI(backend, false, deadline, false) firstAddr = common.HexToAddress("0x1111111111111111111111111111111111111111") secondAddr = common.HexToAddress("0x2222222222222222222222222222222222222222") @@ -670,7 +670,7 @@ func TestPendingTxFilterDeadlock(t *testing.T) { var ( db = rawdb.NewMemoryDatabase() backend = &testBackend{db: db} - api = NewPublicFilterAPI(backend, false, timeout) + api = NewPublicFilterAPI(backend, false, timeout, false) done = make(chan struct{}) ) diff --git a/internal/ethapi/bor_api.go b/internal/ethapi/bor_api.go index 3796047c8f..2a953e5d9d 100644 --- a/internal/ethapi/bor_api.go +++ b/internal/ethapi/bor_api.go @@ -31,7 +31,7 @@ func (s *PublicBlockChainAPI) appendRPCMarshalBorTransaction(ctx context.Context if borTx != nil { formattedTxs := fields["transactions"].([]interface{}) if fullTx { - marshalledTx := newRPCTransaction(borTx, blockHash, blockNumber, txIndex, nil, s.b.ChainConfig()) + marshalledTx := newRPCTransaction(borTx, blockHash, blockNumber, txIndex, block.BaseFee(), s.b.ChainConfig()) // newRPCTransaction calculates hash based on RLP of the transaction data. // In case of bor block tx, we need simple derived tx hash (same as function argument) instead of RLP hash marshalledTx.Hash = txHash diff --git a/params/config.go b/params/config.go index ca25bb2536..f3a83530b9 100644 --- a/params/config.go +++ b/params/config.go @@ -20,6 +20,8 @@ import ( "encoding/binary" "fmt" "math/big" + "sort" + "strconv" "github.com/ethereum/go-ethereum/common" "golang.org/x/crypto/sha3" @@ -222,6 +224,40 @@ var ( Threshold: 2, } + // BorTestChainConfig contains the chain parameters to run a node on the Test network. + BorTestChainConfig = &ChainConfig{ + ChainID: big.NewInt(80001), + HomesteadBlock: big.NewInt(0), + DAOForkBlock: nil, + DAOForkSupport: true, + EIP150Hash: common.HexToHash("0x0000000000000000000000000000000000000000000000000000000000000000"), + EIP150Block: big.NewInt(0), + EIP155Block: big.NewInt(0), + EIP158Block: big.NewInt(0), + ByzantiumBlock: big.NewInt(0), + ConstantinopleBlock: big.NewInt(0), + PetersburgBlock: big.NewInt(0), + IstanbulBlock: big.NewInt(0), + MuirGlacierBlock: big.NewInt(0), + BerlinBlock: big.NewInt(0), + LondonBlock: big.NewInt(0), + Bor: &BorConfig{ + Period: map[string]uint64{ + "0": 2, + }, + ProducerDelay: 6, + Sprint: 64, + BackupMultiplier: map[string]uint64{ + "0": 2, + }, + ValidatorContract: "0x0000000000000000000000000000000000001000", + StateReceiverContract: "0x0000000000000000000000000000000000001001", + BurntContract: map[string]string{ + "0": "0x00000000000000000000000000000000000000000", + }, + }, + } + // MumbaiChainConfig contains the chain parameters to run a node on the Mumbai test network. MumbaiChainConfig = &ChainConfig{ ChainID: big.NewInt(80001), @@ -238,13 +274,21 @@ var ( IstanbulBlock: big.NewInt(2722000), MuirGlacierBlock: big.NewInt(2722000), BerlinBlock: big.NewInt(13996000), + LondonBlock: big.NewInt(22640000), Bor: &BorConfig{ - Period: 2, - ProducerDelay: 6, - Sprint: 64, - BackupMultiplier: 2, + Period: map[string]uint64{ + "0": 2, + }, + ProducerDelay: 6, + Sprint: 64, + BackupMultiplier: map[string]uint64{ + "0": 2, + }, ValidatorContract: "0x0000000000000000000000000000000000001000", StateReceiverContract: "0x0000000000000000000000000000000000001001", + BurntContract: map[string]string{ + "22640000": "0x70bcA57F4579f58670aB2d18Ef16e02C17553C38", + }, BlockAlloc: map[string]interface{}{ // write as interface since that is how it is decoded in genesis "22244000": map[string]interface{}{ @@ -272,11 +316,16 @@ var ( IstanbulBlock: big.NewInt(3395000), MuirGlacierBlock: big.NewInt(3395000), BerlinBlock: big.NewInt(14750000), + LondonBlock: big.NewInt(0), // TODO - Add london fork block Bor: &BorConfig{ - Period: 2, - ProducerDelay: 6, - Sprint: 64, - BackupMultiplier: 2, + Period: map[string]uint64{ + "0": 2, + }, + ProducerDelay: 6, + Sprint: 64, + BackupMultiplier: map[string]uint64{ + "0": 2, + }, ValidatorContract: "0x0000000000000000000000000000000000001000", StateReceiverContract: "0x0000000000000000000000000000000000001001", OverrideStateSyncRecords: map[string]int{ @@ -290,6 +339,9 @@ var ( "14953792": 0, "14953856": 0, }, + BurntContract: map[string]string{ + "0": "0x0000000000000000000000000000000000000000", + }, // TODO add london fork contract and block BlockAlloc: map[string]interface{}{ // write as interface since that is how it is decoded in genesis "22156660": map[string]interface{}{ @@ -426,15 +478,15 @@ func (c *CliqueConfig) String() string { // BorConfig is the consensus engine configs for Matic bor based sealing. type BorConfig struct { - Period uint64 `json:"period"` // Number of seconds between blocks to enforce - ProducerDelay uint64 `json:"producerDelay"` // Number of seconds delay between two producer interval - Sprint uint64 `json:"sprint"` // Epoch length to proposer - BackupMultiplier uint64 `json:"backupMultiplier"` // Backup multiplier to determine the wiggle time - ValidatorContract string `json:"validatorContract"` // Validator set contract - StateReceiverContract string `json:"stateReceiverContract"` // State receiver contract - + Period map[string]uint64 `json:"period"` // Number of seconds between blocks to enforce + ProducerDelay uint64 `json:"producerDelay"` // Number of seconds delay between two producer interval + Sprint uint64 `json:"sprint"` // Epoch length to proposer + BackupMultiplier map[string]uint64 `json:"backupMultiplier"` // Backup multiplier to determine the wiggle time + ValidatorContract string `json:"validatorContract"` // Validator set contract + StateReceiverContract string `json:"stateReceiverContract"` // State receiver contract OverrideStateSyncRecords map[string]int `json:"overrideStateSyncRecords"` // override state records count BlockAlloc map[string]interface{} `json:"blockAlloc"` + BurntContract map[string]string `json:"burntContract"` // governance contract where the token will be sent to and burnt in london fork } // String implements the stringer interface, returning the consensus engine details. @@ -442,6 +494,46 @@ func (b *BorConfig) String() string { return "bor" } +func (c *BorConfig) CalculateBackupMultiplier(number uint64) uint64 { + return c.calculateBorConfigHelper(c.BackupMultiplier, number) +} + +func (c *BorConfig) CalculatePeriod(number uint64) uint64 { + return c.calculateBorConfigHelper(c.Period, number) +} + +func (c *BorConfig) calculateBorConfigHelper(field map[string]uint64, number uint64) uint64 { + keys := make([]string, 0, len(field)) + for k := range field { + keys = append(keys, k) + } + sort.Strings(keys) + for i := 0; i < len(keys)-1; i++ { + valUint, _ := strconv.ParseUint(keys[i], 10, 64) + valUintNext, _ := strconv.ParseUint(keys[i+1], 10, 64) + if number > valUint && number < valUintNext { + return field[keys[i]] + } + } + return field[keys[len(keys)-1]] +} + +func (c *BorConfig) CalculateBurntContract(number uint64) string { + keys := make([]string, 0, len(c.BurntContract)) + for k := range c.BurntContract { + keys = append(keys, k) + } + sort.Strings(keys) + for i := 0; i < len(keys)-1; i++ { + valUint, _ := strconv.ParseUint(keys[i], 10, 64) + valUintNext, _ := strconv.ParseUint(keys[i+1], 10, 64) + if number > valUint && number < valUintNext { + return c.BurntContract[keys[i]] + } + } + return c.BurntContract[keys[len(keys)-1]] +} + // String implements the fmt.Stringer interface. func (c *ChainConfig) String() string { var engine interface{} diff --git a/params/version.go b/params/version.go index c2362ca76f..26eaaa8fb6 100644 --- a/params/version.go +++ b/params/version.go @@ -23,8 +23,8 @@ import ( const ( VersionMajor = 0 // Major version component of the current release VersionMinor = 2 // Minor version component of the current release - VersionPatch = 12 // Patch version component of the current release - VersionMeta = "stable" // Version metadata to append to the version string + VersionPatch = 13 // Patch version component of the current release + VersionMeta = "beta" // Version metadata to append to the version string ) // Version holds the textual version string. diff --git a/tests/bor/bor_test.go b/tests/bor/bor_test.go index 979a8dc044..850d4fda6c 100644 --- a/tests/bor/bor_test.go +++ b/tests/bor/bor_test.go @@ -7,14 +7,18 @@ import ( "testing" "time" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/mock" - + "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/consensus/bor" + "github.com/ethereum/go-ethereum/consensus/ethash" + "github.com/ethereum/go-ethereum/core" "github.com/ethereum/go-ethereum/core/rawdb" "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/core/vm" "github.com/ethereum/go-ethereum/crypto" + "github.com/ethereum/go-ethereum/params" "github.com/ethereum/go-ethereum/tests/bor/mocks" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/mock" ) var ( @@ -268,3 +272,233 @@ func getSampleEventRecord(t *testing.T) *bor.EventRecordWithTime { _eventRecords[0].Time = time.Unix(1, 0) return _eventRecords[0] } + +// TestEIP1559Transition tests the following: +// +// 1. A transaction whose gasFeeCap is greater than the baseFee is valid. +// 2. Gas accounting for access lists on EIP-1559 transactions is correct. +// 3. Only the transaction's tip will be received by the coinbase. +// 4. The transaction sender pays for both the tip and baseFee. +// 5. The coinbase receives only the partially realized tip when +// gasFeeCap - gasTipCap < baseFee. +// 6. Legacy transaction behave as expected (e.g. gasPrice = gasFeeCap = gasTipCap). +func TestEIP1559Transition(t *testing.T) { + var ( + aa = common.HexToAddress("0x000000000000000000000000000000000000aaaa") + + // Generate a canonical chain to act as the main dataset + db = rawdb.NewMemoryDatabase() + engine = ethash.NewFaker() + + // A sender who makes transactions, has some funds + key1, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291") + key2, _ = crypto.HexToECDSA("8a1f9a8f95be41cd7ccb6168179afb4504aefe388d1e14474d32c45c72ce7b7a") + key3, _ = crypto.HexToECDSA("225171aed3793cba1c029832886d69785b7e77a54a44211226b447aa2d16b058") + + addr1 = crypto.PubkeyToAddress(key1.PublicKey) + addr2 = crypto.PubkeyToAddress(key2.PublicKey) + addr3 = crypto.PubkeyToAddress(key3.PublicKey) + funds = new(big.Int).Mul(common.Big1, big.NewInt(params.Ether)) + gspec = &core.Genesis{ + Config: params.BorTestChainConfig, + Alloc: core.GenesisAlloc{ + addr1: {Balance: funds}, + addr2: {Balance: funds}, + addr3: {Balance: funds}, + // The address 0xAAAA sloads 0x00 and 0x01 + aa: { + Code: []byte{ + byte(vm.PC), + byte(vm.PC), + byte(vm.SLOAD), + byte(vm.SLOAD), + }, + Nonce: 0, + Balance: big.NewInt(0), + }, + }, + } + ) + + gspec.Config.BerlinBlock = common.Big0 + gspec.Config.LondonBlock = common.Big0 + genesis := gspec.MustCommit(db) + signer := types.LatestSigner(gspec.Config) + + blocks, _ := core.GenerateChain(gspec.Config, genesis, engine, db, 1, func(i int, b *core.BlockGen) { + b.SetCoinbase(common.Address{1}) + // One transaction to 0xAAAA + accesses := types.AccessList{types.AccessTuple{ + Address: aa, + StorageKeys: []common.Hash{{0}}, + }} + + txdata := &types.DynamicFeeTx{ + ChainID: gspec.Config.ChainID, + Nonce: 0, + To: &aa, + Gas: 30000, + GasFeeCap: newGwei(5), + GasTipCap: big.NewInt(2), + AccessList: accesses, + Data: []byte{}, + } + tx := types.NewTx(txdata) + tx, _ = types.SignTx(tx, signer, key1) + + b.AddTx(tx) + }) + + diskdb := rawdb.NewMemoryDatabase() + gspec.MustCommit(diskdb) + + chain, err := core.NewBlockChain(diskdb, nil, gspec.Config, engine, vm.Config{}, nil, nil) + if err != nil { + t.Fatalf("failed to create tester chain: %v", err) + } + if n, err := chain.InsertChain(blocks); err != nil { + t.Fatalf("block %d: failed to insert into chain: %v", n, err) + } + + block := chain.GetBlockByNumber(1) + + // 1+2: Ensure EIP-1559 access lists are accounted for via gas usage. + expectedGas := params.TxGas + params.TxAccessListAddressGas + params.TxAccessListStorageKeyGas + + vm.GasQuickStep*2 + params.WarmStorageReadCostEIP2929 + params.ColdSloadCostEIP2929 + if block.GasUsed() != expectedGas { + t.Fatalf("incorrect amount of gas spent: expected %d, got %d", expectedGas, block.GasUsed()) + } + + state, _ := chain.State() + + // 3: Ensure that miner received only the tx's tip. + actual := state.GetBalance(block.Coinbase()) + expected := new(big.Int).Add( + new(big.Int).SetUint64(block.GasUsed()*block.Transactions()[0].GasTipCap().Uint64()), + ethash.ConstantinopleBlockReward, + ) + if actual.Cmp(expected) != 0 { + t.Fatalf("miner balance incorrect: expected %d, got %d", expected, actual) + } + + // check burnt contract balance + actual = state.GetBalance(common.HexToAddress(params.BorTestChainConfig.Bor.CalculateBurntContract(block.NumberU64()))) + expected = new(big.Int).Mul(new(big.Int).SetUint64(block.GasUsed()), block.BaseFee()) + burntContractBalance := expected + if actual.Cmp(expected) != 0 { + t.Fatalf("burnt contract balance incorrect: expected %d, got %d", expected, actual) + } + + // 4: Ensure the tx sender paid for the gasUsed * (tip + block baseFee). + actual = new(big.Int).Sub(funds, state.GetBalance(addr1)) + expected = new(big.Int).SetUint64(block.GasUsed() * (block.Transactions()[0].GasTipCap().Uint64() + block.BaseFee().Uint64())) + if actual.Cmp(expected) != 0 { + t.Fatalf("sender balance incorrect: expected %d, got %d", expected, actual) + } + + blocks, _ = core.GenerateChain(gspec.Config, block, engine, db, 1, func(i int, b *core.BlockGen) { + b.SetCoinbase(common.Address{2}) + + txdata := &types.LegacyTx{ + Nonce: 0, + To: &aa, + Gas: 30000, + GasPrice: newGwei(5), + } + tx := types.NewTx(txdata) + tx, _ = types.SignTx(tx, signer, key2) + + b.AddTx(tx) + }) + + if n, err := chain.InsertChain(blocks); err != nil { + t.Fatalf("block %d: failed to insert into chain: %v", n, err) + } + + block = chain.GetBlockByNumber(2) + state, _ = chain.State() + effectiveTip := block.Transactions()[0].GasTipCap().Uint64() - block.BaseFee().Uint64() + + // 6+5: Ensure that miner received only the tx's effective tip. + actual = state.GetBalance(block.Coinbase()) + expected = new(big.Int).Add( + new(big.Int).SetUint64(block.GasUsed()*effectiveTip), + ethash.ConstantinopleBlockReward, + ) + if actual.Cmp(expected) != 0 { + t.Fatalf("miner balance incorrect: expected %d, got %d", expected, actual) + } + + // check burnt contract balance + actual = state.GetBalance(common.HexToAddress(params.BorTestChainConfig.Bor.CalculateBurntContract(block.NumberU64()))) + expected = new(big.Int).Add(burntContractBalance, new(big.Int).Mul(new(big.Int).SetUint64(block.GasUsed()), block.BaseFee())) + burntContractBalance = expected + if actual.Cmp(expected) != 0 { + t.Fatalf("burnt contract balance incorrect: expected %d, got %d", expected, actual) + } + + // 4: Ensure the tx sender paid for the gasUsed * (effectiveTip + block baseFee). + actual = new(big.Int).Sub(funds, state.GetBalance(addr2)) + expected = new(big.Int).SetUint64(block.GasUsed() * (effectiveTip + block.BaseFee().Uint64())) + if actual.Cmp(expected) != 0 { + t.Fatalf("sender balance incorrect: expected %d, got %d", expected, actual) + } + + blocks, _ = core.GenerateChain(gspec.Config, block, engine, db, 1, func(i int, b *core.BlockGen) { + b.SetCoinbase(common.Address{3}) + + txdata := &types.LegacyTx{ + Nonce: 0, + To: &aa, + Gas: 30000, + GasPrice: newGwei(5), + } + tx := types.NewTx(txdata) + tx, _ = types.SignTx(tx, signer, key3) + + b.AddTx(tx) + + accesses := types.AccessList{types.AccessTuple{ + Address: aa, + StorageKeys: []common.Hash{{0}}, + }} + + txdata2 := &types.DynamicFeeTx{ + ChainID: gspec.Config.ChainID, + Nonce: 1, + To: &aa, + Gas: 30000, + GasFeeCap: newGwei(5), + GasTipCap: big.NewInt(2), + AccessList: accesses, + Data: []byte{}, + } + tx = types.NewTx(txdata2) + tx, _ = types.SignTx(tx, signer, key3) + + b.AddTx(tx) + + }) + + if n, err := chain.InsertChain(blocks); err != nil { + t.Fatalf("block %d: failed to insert into chain: %v", n, err) + } + + block = chain.GetBlockByNumber(3) + state, _ = chain.State() + + // check burnt contract balance + actual = state.GetBalance(common.HexToAddress(params.BorTestChainConfig.Bor.CalculateBurntContract(block.NumberU64()))) + burntAmount := new(big.Int).Mul( + block.BaseFee(), + big.NewInt(int64(block.GasUsed())), + ) + expected = new(big.Int).Add(burntContractBalance, burntAmount) + if actual.Cmp(expected) != 0 { + t.Fatalf("burnt contract balance incorrect: expected %d, got %d", expected, actual) + } +} + +func newGwei(n int64) *big.Int { + return new(big.Int).Mul(big.NewInt(n), big.NewInt(params.GWei)) +} diff --git a/tests/bor/testdata/genesis.json b/tests/bor/testdata/genesis.json index 7c3e34bf35..584f7fc912 100644 --- a/tests/bor/testdata/genesis.json +++ b/tests/bor/testdata/genesis.json @@ -8,13 +8,25 @@ "eip158Block": 0, "byzantiumBlock": 0, "constantinopleBlock": 0, + "petersburgBlock": 0, + "istanbulBlock": 0, + "muirGlacierBlock": 0, + "berlinBlock": 0, + "londonBlock": 10, "bor": { - "period": 1, + "period": { + "0": 1 + }, "producerDelay": 4, "sprint": 4, - "backupMultiplier": 1, + "backupMultiplier": { + "0": 1 + }, "validatorContract": "0x0000000000000000000000000000000000001000", - "stateReceiverContract": "0x0000000000000000000000000000000000001001" + "stateReceiverContract": "0x0000000000000000000000000000000000001001", + "burntContract": { + "0": "0x0000000000000000000000000000000000000000" + } } }, "nonce": "0x0", From f80dc2bc0ff785a58bc707fcbfcd9ad29dd78819 Mon Sep 17 00:00:00 2001 From: Victor Castell Date: Mon, 13 Dec 2021 10:05:54 +0100 Subject: [PATCH 46/51] Build with the previous Dockerfile (#268) * Build with the previous Dockerfile This will recover the classic maticnetwork build in parallel. This will allow to test both images. Also fix the new build manifest. Build on patches too --- .github/workflows/dockerimage.yml | 29 +++++++++++++++++++++++++++++ .goreleaser.yml | 2 -- Dockerfile.classic | 18 ++++++++++++++++++ 3 files changed, 47 insertions(+), 2 deletions(-) create mode 100644 .github/workflows/dockerimage.yml create mode 100644 Dockerfile.classic diff --git a/.github/workflows/dockerimage.yml b/.github/workflows/dockerimage.yml new file mode 100644 index 0000000000..a8dc11949f --- /dev/null +++ b/.github/workflows/dockerimage.yml @@ -0,0 +1,29 @@ +name: Bor Docker Image CI + +on: + push: + branches-ignore: + - '**' + tags: + - 'v*.*.*' + # to be used by fork patch-releases ^^ + - 'v*.*.*-*' + +jobs: + build: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - name: Build the Bor Docker image + env: + DOCKERHUB: ${{ secrets.DOCKERHUB }} + DOCKERHUB_KEY: ${{ secrets.DOCKERHUB_KEY }} + run: | + ls -l + echo "Docker login" + docker login -u $DOCKERHUB -p $DOCKERHUB_KEY + echo "running build" + docker build -f Dockerfile.classic -t maticnetwork/bor:${GITHUB_REF/refs\/tags\//} . + echo "pushing image" + docker push maticnetwork/bor:${GITHUB_REF/refs\/tags\//} + echo "DONE!" diff --git a/.goreleaser.yml b/.goreleaser.yml index b25a316449..aed63c3588 100644 --- a/.goreleaser.yml +++ b/.goreleaser.yml @@ -95,7 +95,6 @@ dockers: - linux-amd64 build_flag_templates: - --platform=linux/amd64 - skip_push: true - image_templates: - 0xpolygon/{{ .ProjectName }}:{{ .Version }}-arm64 @@ -106,7 +105,6 @@ dockers: - linux-arm64 build_flag_templates: - --platform=linux/arm64 - skip_push: true docker_manifests: - name_template: 0xpolygon/{{ .ProjectName }}:{{ .Version }} diff --git a/Dockerfile.classic b/Dockerfile.classic new file mode 100644 index 0000000000..a60c55e7d4 --- /dev/null +++ b/Dockerfile.classic @@ -0,0 +1,18 @@ +# Build Geth in a stock Go builder container +FROM golang:1.17-alpine as builder + +RUN apk add --no-cache make gcc musl-dev linux-headers git bash + +ADD . /bor +RUN cd /bor && make bor-all + +CMD ["/bin/bash"] + +# Pull Bor into a second stage deploy alpine container +FROM alpine:latest + +RUN apk add --no-cache ca-certificates +COPY --from=builder /bor/build/bin/bor /usr/local/bin/ +COPY --from=builder /bor/build/bin/bootnode /usr/local/bin/ + +EXPOSE 8545 8546 8547 30303 30303/udp From e2b938562a3856db77c091e8dd8e693994d17d3f Mon Sep 17 00:00:00 2001 From: Arpit Temani Date: Wed, 15 Dec 2021 17:28:11 +0530 Subject: [PATCH 47/51] jaipur fork (#269) * jaipur fork * add check * review comments * test case * fix few changes * Change condition * review comments * type conversion * Update mumbai.go * Update config.go * Update config.go Co-authored-by: Ferran Borreguero --- command/server/chains/mainnet.go | 12 ++++--- command/server/chains/mumbai.go | 26 +++++++++++--- consensus/bor/bor.go | 35 ++++++++++-------- consensus/bor/bor_test.go | 36 +++++++++++++++++++ consensus/bor/snapshot.go | 2 +- params/config.go | 8 ++++- tests/bor/bor_test.go | 62 ++++++++++++++++++++++++++++++-- tests/bor/helper.go | 15 ++++++-- tests/bor/testdata/genesis.json | 3 +- 9 files changed, 168 insertions(+), 31 deletions(-) diff --git a/command/server/chains/mainnet.go b/command/server/chains/mainnet.go index ac074ed8cb..631b6e6647 100644 --- a/command/server/chains/mainnet.go +++ b/command/server/chains/mainnet.go @@ -28,10 +28,14 @@ var mainnetBor = &Chain{ MuirGlacierBlock: big.NewInt(3395000), BerlinBlock: big.NewInt(14750000), Bor: ¶ms.BorConfig{ - Period: 2, - ProducerDelay: 6, - Sprint: 64, - BackupMultiplier: 2, + Period: map[string]uint64{ + "0": 2, + }, + ProducerDelay: 6, + Sprint: 64, + BackupMultiplier: map[string]uint64{ + "0": 2, + }, ValidatorContract: "0x0000000000000000000000000000000000001000", StateReceiverContract: "0x0000000000000000000000000000000000001001", OverrideStateSyncRecords: map[string]int{ diff --git a/command/server/chains/mumbai.go b/command/server/chains/mumbai.go index 1003380d10..4d250dbf2b 100644 --- a/command/server/chains/mumbai.go +++ b/command/server/chains/mumbai.go @@ -27,13 +27,31 @@ var mumbaiTestnet = &Chain{ IstanbulBlock: big.NewInt(2722000), MuirGlacierBlock: big.NewInt(2722000), BerlinBlock: big.NewInt(13996000), + LondonBlock: big.NewInt(22640000), Bor: ¶ms.BorConfig{ - Period: 2, - ProducerDelay: 6, - Sprint: 64, - BackupMultiplier: 2, + JaipurBlock: 22770000, + Period: map[string]uint64{ + "0": 2, + }, + ProducerDelay: 6, + Sprint: 64, + BackupMultiplier: map[string]uint64{ + "0": 2, + }, ValidatorContract: "0x0000000000000000000000000000000000001000", StateReceiverContract: "0x0000000000000000000000000000000000001001", + BurntContract: map[string]string{ + "22640000": "0x70bcA57F4579f58670aB2d18Ef16e02C17553C38", + }, + BlockAlloc: map[string]interface{}{ + // write as interface since that is how it is decoded in genesis + "22244000": map[string]interface{}{ + "0000000000000000000000000000000000001010": map[string]interface{}{ + "balance": "0x0", + "code": "0x60806040526004361061019c5760003560e01c806377d32e94116100ec578063acd06cb31161008a578063e306f77911610064578063e306f77914610a7b578063e614d0d614610aa6578063f2fde38b14610ad1578063fc0c546a14610b225761019c565b8063acd06cb31461097a578063b789543c146109cd578063cc79f97b14610a505761019c565b80639025e64c116100c65780639025e64c146107c957806395d89b4114610859578063a9059cbb146108e9578063abceeba21461094f5761019c565b806377d32e94146106315780638da5cb5b146107435780638f32d59b1461079a5761019c565b806347e7ef24116101595780637019d41a116101335780637019d41a1461053357806370a082311461058a578063715018a6146105ef578063771282f6146106065761019c565b806347e7ef2414610410578063485cc9551461046b57806360f96a8f146104dc5761019c565b806306fdde03146101a15780631499c5921461023157806318160ddd1461028257806319d27d9c146102ad5780632e1a7d4d146103b1578063313ce567146103df575b600080fd5b3480156101ad57600080fd5b506101b6610b79565b6040518080602001828103825283818151815260200191508051906020019080838360005b838110156101f65780820151818401526020810190506101db565b50505050905090810190601f1680156102235780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561023d57600080fd5b506102806004803603602081101561025457600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610bb6565b005b34801561028e57600080fd5b50610297610c24565b6040518082815260200191505060405180910390f35b3480156102b957600080fd5b5061036f600480360360a08110156102d057600080fd5b81019080803590602001906401000000008111156102ed57600080fd5b8201836020820111156102ff57600080fd5b8035906020019184600183028401116401000000008311171561032157600080fd5b9091929391929390803590602001909291908035906020019092919080359060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610c3a565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6103dd600480360360208110156103c757600080fd5b8101908080359060200190929190505050610caa565b005b3480156103eb57600080fd5b506103f4610dfc565b604051808260ff1660ff16815260200191505060405180910390f35b34801561041c57600080fd5b506104696004803603604081101561043357600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050610e05565b005b34801561047757600080fd5b506104da6004803603604081101561048e57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610fc1565b005b3480156104e857600080fd5b506104f1611090565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b34801561053f57600080fd5b506105486110b6565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b34801561059657600080fd5b506105d9600480360360208110156105ad57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506110dc565b6040518082815260200191505060405180910390f35b3480156105fb57600080fd5b506106046110fd565b005b34801561061257600080fd5b5061061b6111cd565b6040518082815260200191505060405180910390f35b34801561063d57600080fd5b506107016004803603604081101561065457600080fd5b81019080803590602001909291908035906020019064010000000081111561067b57600080fd5b82018360208201111561068d57600080fd5b803590602001918460018302840111640100000000831117156106af57600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505091929192905050506111d3565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b34801561074f57600080fd5b50610758611358565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b3480156107a657600080fd5b506107af611381565b604051808215151515815260200191505060405180910390f35b3480156107d557600080fd5b506107de6113d8565b6040518080602001828103825283818151815260200191508051906020019080838360005b8381101561081e578082015181840152602081019050610803565b50505050905090810190601f16801561084b5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561086557600080fd5b5061086e611411565b6040518080602001828103825283818151815260200191508051906020019080838360005b838110156108ae578082015181840152602081019050610893565b50505050905090810190601f1680156108db5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b610935600480360360408110156108ff57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291908035906020019092919050505061144e565b604051808215151515815260200191505060405180910390f35b34801561095b57600080fd5b50610964611474565b6040518082815260200191505060405180910390f35b34801561098657600080fd5b506109b36004803603602081101561099d57600080fd5b8101908080359060200190929190505050611501565b604051808215151515815260200191505060405180910390f35b3480156109d957600080fd5b50610a3a600480360360808110156109f057600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803590602001909291908035906020019092919080359060200190929190505050611521565b6040518082815260200191505060405180910390f35b348015610a5c57600080fd5b50610a65611541565b6040518082815260200191505060405180910390f35b348015610a8757600080fd5b50610a90611548565b6040518082815260200191505060405180910390f35b348015610ab257600080fd5b50610abb61154e565b6040518082815260200191505060405180910390f35b348015610add57600080fd5b50610b2060048036036020811015610af457600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506115db565b005b348015610b2e57600080fd5b50610b376115f8565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b60606040518060400160405280600b81526020017f4d6174696320546f6b656e000000000000000000000000000000000000000000815250905090565b6040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260108152602001807f44697361626c656420666561747572650000000000000000000000000000000081525060200191505060405180910390fd5b6000601260ff16600a0a6402540be40002905090565b60006040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260108152602001807f44697361626c656420666561747572650000000000000000000000000000000081525060200191505060405180910390fd5b60003390506000610cba826110dc565b9050610cd18360065461161e90919063ffffffff16565b600681905550600083118015610ce657508234145b610d58576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260138152602001807f496e73756666696369656e7420616d6f756e740000000000000000000000000081525060200191505060405180910390fd5b8173ffffffffffffffffffffffffffffffffffffffff16600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167febff2602b3f468259e1e99f613fed6691f3a6526effe6ef3e768ba7ae7a36c4f8584610dd4876110dc565b60405180848152602001838152602001828152602001935050505060405180910390a3505050565b60006012905090565b610e0d611381565b610e1657600080fd5b600081118015610e535750600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614155b610ea8576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526023815260200180611da96023913960400191505060405180910390fd5b6000610eb3836110dc565b905060008390508073ffffffffffffffffffffffffffffffffffffffff166108fc849081150290604051600060405180830381858888f19350505050158015610f00573d6000803e3d6000fd5b50610f168360065461163e90919063ffffffff16565b6006819055508373ffffffffffffffffffffffffffffffffffffffff16600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f4e2ca0515ed1aef1395f66b5303bb5d6f1bf9d61a353fa53f73f8ac9973fa9f68585610f98896110dc565b60405180848152602001838152602001828152602001935050505060405180910390a350505050565b600760009054906101000a900460ff1615611027576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526023815260200180611d866023913960400191505060405180910390fd5b6001600760006101000a81548160ff02191690831515021790555080600260006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555061108c8261165d565b5050565b600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60008173ffffffffffffffffffffffffffffffffffffffff16319050919050565b611105611381565b61110e57600080fd5b600073ffffffffffffffffffffffffffffffffffffffff166000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a360008060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550565b60065481565b60008060008060418551146111ee5760009350505050611352565b602085015192506040850151915060ff6041860151169050601b8160ff16101561121957601b810190505b601b8160ff16141580156112315750601c8160ff1614155b156112425760009350505050611352565b60018682858560405160008152602001604052604051808581526020018460ff1660ff1681526020018381526020018281526020019450505050506020604051602081039080840390855afa15801561129f573d6000803e3d6000fd5b505050602060405103519350600073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff16141561134e576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260128152602001807f4572726f7220696e2065637265636f766572000000000000000000000000000081525060200191505060405180910390fd5b5050505b92915050565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614905090565b6040518060400160405280600381526020017f013881000000000000000000000000000000000000000000000000000000000081525081565b60606040518060400160405280600581526020017f4d41544943000000000000000000000000000000000000000000000000000000815250905090565b6000813414611460576000905061146e565b61146b338484611755565b90505b92915050565b6040518060800160405280605b8152602001611e1e605b91396040516020018082805190602001908083835b602083106114c357805182526020820191506020810190506020830392506114a0565b6001836020036101000a0380198251168184511680821785525050505050509050019150506040516020818303038152906040528051906020012081565b60056020528060005260406000206000915054906101000a900460ff1681565b600061153761153286868686611b12565b611be8565b9050949350505050565b6201388181565b60015481565b604051806080016040528060528152602001611dcc605291396040516020018082805190602001908083835b6020831061159d578051825260208201915060208101905060208303925061157a565b6001836020036101000a0380198251168184511680821785525050505050509050019150506040516020818303038152906040528051906020012081565b6115e3611381565b6115ec57600080fd5b6115f58161165d565b50565b600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60008282111561162d57600080fd5b600082840390508091505092915050565b60008082840190508381101561165357600080fd5b8091505092915050565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16141561169757600080fd5b8073ffffffffffffffffffffffffffffffffffffffff166000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a3806000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b6000803073ffffffffffffffffffffffffffffffffffffffff166370a08231866040518263ffffffff1660e01b8152600401808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060206040518083038186803b1580156117d557600080fd5b505afa1580156117e9573d6000803e3d6000fd5b505050506040513d60208110156117ff57600080fd5b8101908080519060200190929190505050905060003073ffffffffffffffffffffffffffffffffffffffff166370a08231866040518263ffffffff1660e01b8152600401808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060206040518083038186803b15801561189157600080fd5b505afa1580156118a5573d6000803e3d6000fd5b505050506040513d60208110156118bb57600080fd5b810190808051906020019092919050505090506118d9868686611c32565b8473ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff16600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167fe6497e3ee548a3372136af2fcb0696db31fc6cf20260707645068bd3fe97f3c48786863073ffffffffffffffffffffffffffffffffffffffff166370a082318e6040518263ffffffff1660e01b8152600401808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060206040518083038186803b1580156119e157600080fd5b505afa1580156119f5573d6000803e3d6000fd5b505050506040513d6020811015611a0b57600080fd5b81019080805190602001909291905050503073ffffffffffffffffffffffffffffffffffffffff166370a082318e6040518263ffffffff1660e01b8152600401808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060206040518083038186803b158015611a9957600080fd5b505afa158015611aad573d6000803e3d6000fd5b505050506040513d6020811015611ac357600080fd5b8101908080519060200190929190505050604051808681526020018581526020018481526020018381526020018281526020019550505050505060405180910390a46001925050509392505050565b6000806040518060800160405280605b8152602001611e1e605b91396040516020018082805190602001908083835b60208310611b645780518252602082019150602081019050602083039250611b41565b6001836020036101000a03801982511681845116808217855250505050505090500191505060405160208183030381529060405280519060200120905060405181815273ffffffffffffffffffffffffffffffffffffffff8716602082015285604082015284606082015283608082015260a0812092505081915050949350505050565b60008060015490506040517f190100000000000000000000000000000000000000000000000000000000000081528160028201528360228201526042812092505081915050919050565b3073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415611cd4576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260138152602001807f63616e27742073656e6420746f204d524332300000000000000000000000000081525060200191505060405180910390fd5b8173ffffffffffffffffffffffffffffffffffffffff166108fc829081150290604051600060405180830381858888f19350505050158015611d1a573d6000803e3d6000fd5b508173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef836040518082815260200191505060405180910390a350505056fe54686520636f6e747261637420697320616c726561647920696e697469616c697a6564496e73756666696369656e7420616d6f756e74206f7220696e76616c69642075736572454950373132446f6d61696e28737472696e67206e616d652c737472696e672076657273696f6e2c75696e7432353620636861696e49642c6164647265737320766572696679696e67436f6e747261637429546f6b656e5472616e736665724f726465722861646472657373207370656e6465722c75696e7432353620746f6b656e49644f72416d6f756e742c6279746573333220646174612c75696e743235362065787069726174696f6e29a265627a7a72315820ccd6c2a9c259832bbb367986ee06cd87af23022681b0cb22311a864b701d939564736f6c63430005100032", + }, + }, + }, }, }, Nonce: 0, diff --git a/consensus/bor/bor.go b/consensus/bor/bor.go index 94774d5032..7f3c422dfc 100644 --- a/consensus/bor/bor.go +++ b/consensus/bor/bor.go @@ -123,7 +123,7 @@ var ( type SignerFn func(accounts.Account, string, []byte) ([]byte, error) // ecrecover extracts the Ethereum account address from a signed header. -func ecrecover(header *types.Header, sigcache *lru.ARCCache) (common.Address, error) { +func ecrecover(header *types.Header, sigcache *lru.ARCCache, c *params.BorConfig) (common.Address, error) { // If the signature's already cached, return that hash := header.Hash() if address, known := sigcache.Get(hash); known { @@ -136,7 +136,7 @@ func ecrecover(header *types.Header, sigcache *lru.ARCCache) (common.Address, er signature := header.Extra[len(header.Extra)-extraSeal:] // Recover the public key and the Ethereum address - pubkey, err := crypto.Ecrecover(SealHash(header).Bytes(), signature) + pubkey, err := crypto.Ecrecover(SealHash(header, c).Bytes(), signature) if err != nil { return common.Address{}, err } @@ -148,15 +148,15 @@ func ecrecover(header *types.Header, sigcache *lru.ARCCache) (common.Address, er } // SealHash returns the hash of a block prior to it being sealed. -func SealHash(header *types.Header) (hash common.Hash) { +func SealHash(header *types.Header, c *params.BorConfig) (hash common.Hash) { hasher := sha3.NewLegacyKeccak256() - encodeSigHeader(hasher, header) + encodeSigHeader(hasher, header, c) hasher.Sum(hash[:0]) return hash } -func encodeSigHeader(w io.Writer, header *types.Header) { - err := rlp.Encode(w, []interface{}{ +func encodeSigHeader(w io.Writer, header *types.Header, c *params.BorConfig) { + enc := []interface{}{ header.ParentHash, header.UncleHash, header.Coinbase, @@ -172,8 +172,13 @@ func encodeSigHeader(w io.Writer, header *types.Header) { header.Extra[:len(header.Extra)-65], // Yes, this will panic if extra is too short header.MixDigest, header.Nonce, - }) - if err != nil { + } + if c.IsJaipur(header.Number.Uint64()) { + if header.BaseFee != nil { + enc = append(enc, header.BaseFee) + } + } + if err := rlp.Encode(w, enc); err != nil { panic("can't encode: " + err.Error()) } } @@ -199,9 +204,9 @@ func CalcProducerDelay(number uint64, succession int, c *params.BorConfig) uint6 // Note, the method requires the extra data to be at least 65 bytes, otherwise it // panics. This is done to avoid accidentally using both forms (signature present // or not), which could be abused to produce different hashes for the same header. -func BorRLP(header *types.Header) []byte { +func BorRLP(header *types.Header, c *params.BorConfig) []byte { b := new(bytes.Buffer) - encodeSigHeader(b, header) + encodeSigHeader(b, header, c) return b.Bytes() } @@ -280,7 +285,7 @@ func New( // Author implements consensus.Engine, returning the Ethereum address recovered // from the signature in the header's extra-data section. func (c *Bor) Author(header *types.Header) (common.Address, error) { - return ecrecover(header, c.signatures) + return ecrecover(header, c.signatures, c.config) } // VerifyHeader checks whether a header conforms to the consensus rules. @@ -578,7 +583,7 @@ func (c *Bor) verifySeal(chain consensus.ChainHeaderReader, header *types.Header } // Resolve the authorization key and check against signers - signer, err := ecrecover(header, c.signatures) + signer, err := ecrecover(header, c.signatures, c.config) if err != nil { return err } @@ -844,7 +849,7 @@ func (c *Bor) Seal(chain consensus.ChainHeaderReader, block *types.Block, result wiggle := time.Duration(successionNumber) * time.Duration(c.config.CalculateBackupMultiplier(number)) * time.Second // Sign all the things! - sighash, err := signFn(accounts.Account{Address: signer}, accounts.MimetypeBor, BorRLP(header)) + sighash, err := signFn(accounts.Account{Address: signer}, accounts.MimetypeBor, BorRLP(header, c.config)) if err != nil { return err } @@ -876,7 +881,7 @@ func (c *Bor) Seal(chain consensus.ChainHeaderReader, block *types.Block, result select { case results <- block.WithSeal(header): default: - log.Warn("Sealing result was not read by miner", "number", number, "sealhash", SealHash(header)) + log.Warn("Sealing result was not read by miner", "number", number, "sealhash", SealHash(header, c.config)) } }() return nil @@ -895,7 +900,7 @@ func (c *Bor) CalcDifficulty(chain consensus.ChainHeaderReader, time uint64, par // SealHash returns the hash of a block prior to it being sealed. func (c *Bor) SealHash(header *types.Header) common.Hash { - return SealHash(header) + return SealHash(header, c.config) } // APIs implements consensus.Engine, returning the user facing RPC API to allow diff --git a/consensus/bor/bor_test.go b/consensus/bor/bor_test.go index 75beea36d8..b0ebc96861 100644 --- a/consensus/bor/bor_test.go +++ b/consensus/bor/bor_test.go @@ -99,3 +99,39 @@ func TestGenesisContractChange(t *testing.T) { // make sure balance change DOES NOT take effect assert.Equal(t, statedb.GetBalance(addr0), big.NewInt(0)) } + +func TestEncodeSigHeaderJaipur(t *testing.T) { + // As part of the EIP-1559 fork in mumbai, an incorrect seal hash + // was used for Bor that did not included the BaseFee. The Jaipur + // block is a hard fork to fix that. + h := &types.Header{ + Difficulty: new(big.Int), + Number: big.NewInt(1), + Extra: make([]byte, 32+65), + } + + var ( + // hash for the block without the BaseFee + hashWithoutBaseFee = common.HexToHash("0x1be13e83939b3c4701ee57a34e10c9290ce07b0e53af0fe90b812c6881826e36") + // hash for the block with the baseFee + hashWithBaseFee = common.HexToHash("0xc55b0cac99161f71bde1423a091426b1b5b4d7598e5981ad802cce712771965b") + ) + + // Jaipur NOT enabled and BaseFee not set + hash := SealHash(h, ¶ms.BorConfig{JaipurBlock: 10}) + assert.Equal(t, hash, hashWithoutBaseFee) + + // Jaipur enabled (Jaipur=0) and BaseFee not set + hash = SealHash(h, ¶ms.BorConfig{JaipurBlock: 0}) + assert.Equal(t, hash, hashWithoutBaseFee) + + h.BaseFee = big.NewInt(2) + + // Jaipur enabled (Jaipur=Header block) and BaseFee set + hash = SealHash(h, ¶ms.BorConfig{JaipurBlock: 1}) + assert.Equal(t, hash, hashWithBaseFee) + + // Jaipur NOT enabled and BaseFee set + hash = SealHash(h, ¶ms.BorConfig{JaipurBlock: 10}) + assert.Equal(t, hash, hashWithoutBaseFee) +} diff --git a/consensus/bor/snapshot.go b/consensus/bor/snapshot.go index 8405f34fbd..8d212f33ef 100644 --- a/consensus/bor/snapshot.go +++ b/consensus/bor/snapshot.go @@ -131,7 +131,7 @@ func (s *Snapshot) apply(headers []*types.Header) (*Snapshot, error) { } // Resolve the authorization key and check against signers - signer, err := ecrecover(header, s.sigcache) + signer, err := ecrecover(header, s.sigcache, s.config) if err != nil { return nil, err } diff --git a/params/config.go b/params/config.go index f3a83530b9..86bf6430b8 100644 --- a/params/config.go +++ b/params/config.go @@ -276,6 +276,7 @@ var ( BerlinBlock: big.NewInt(13996000), LondonBlock: big.NewInt(22640000), Bor: &BorConfig{ + JaipurBlock: 22770000, Period: map[string]uint64{ "0": 2, }, @@ -486,7 +487,8 @@ type BorConfig struct { StateReceiverContract string `json:"stateReceiverContract"` // State receiver contract OverrideStateSyncRecords map[string]int `json:"overrideStateSyncRecords"` // override state records count BlockAlloc map[string]interface{} `json:"blockAlloc"` - BurntContract map[string]string `json:"burntContract"` // governance contract where the token will be sent to and burnt in london fork + BurntContract map[string]string `json:"burntContract"` // governance contract where the token will be sent to and burnt in london fork + JaipurBlock uint64 `json:"jaipurBlock"` // Jaipur switch block (nil = no fork, 0 = already on jaipur) } // String implements the stringer interface, returning the consensus engine details. @@ -502,6 +504,10 @@ func (c *BorConfig) CalculatePeriod(number uint64) uint64 { return c.calculateBorConfigHelper(c.Period, number) } +func (c *BorConfig) IsJaipur(number uint64) bool { + return number >= c.JaipurBlock +} + func (c *BorConfig) calculateBorConfigHelper(field map[string]uint64, number uint64) uint64 { keys := make([]string, 0, len(field)) for k := range field { diff --git a/tests/bor/bor_test.go b/tests/bor/bor_test.go index 850d4fda6c..7d0ca9372b 100644 --- a/tests/bor/bor_test.go +++ b/tests/bor/bor_test.go @@ -3,6 +3,7 @@ package bor import ( "encoding/hex" "encoding/json" + "io" "math/big" "testing" "time" @@ -16,9 +17,11 @@ import ( "github.com/ethereum/go-ethereum/core/vm" "github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/params" + "github.com/ethereum/go-ethereum/rlp" "github.com/ethereum/go-ethereum/tests/bor/mocks" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" + "golang.org/x/crypto/sha3" ) var ( @@ -192,7 +195,7 @@ func TestOutOfTurnSigning(t *testing.T) { header := block.Header() header.Time += (bor.CalcProducerDelay(header.Number.Uint64(), expectedSuccessionNumber, init.genesis.Config.Bor) - bor.CalcProducerDelay(header.Number.Uint64(), 0, init.genesis.Config.Bor)) - sign(t, header, signerKey) + sign(t, header, signerKey, init.genesis.Config.Bor) block = types.NewBlockWithHeader(header) _, err = chain.InsertChain([]*types.Block{block}) assert.Equal(t, @@ -200,7 +203,7 @@ func TestOutOfTurnSigning(t *testing.T) { bor.WrongDifficultyError{Number: spanSize, Expected: expectedDifficulty, Actual: 3, Signer: addr.Bytes()}) header.Difficulty = new(big.Int).SetUint64(expectedDifficulty) - sign(t, header, signerKey) + sign(t, header, signerKey, init.genesis.Config.Bor) block = types.NewBlockWithHeader(header) _, err = chain.InsertChain([]*types.Block{block}) assert.Nil(t, err) @@ -502,3 +505,58 @@ func TestEIP1559Transition(t *testing.T) { func newGwei(n int64) *big.Int { return new(big.Int).Mul(big.NewInt(n), big.NewInt(params.GWei)) } + +func TestJaipurFork(t *testing.T) { + init := buildEthereumInstance(t, rawdb.NewMemoryDatabase()) + chain := init.ethereum.BlockChain() + engine := init.ethereum.Engine() + _bor := engine.(*bor.Bor) + db := init.ethereum.ChainDb() + block := init.genesis.ToBlock(db) + for i := uint64(1); i < sprintSize; i++ { + block = buildNextBlock(t, _bor, chain, block, nil, init.genesis.Config.Bor) + insertNewBlock(t, chain, block) + if block.Number().Uint64() == init.genesis.Config.Bor.JaipurBlock-1 { + assert.Equal(t, testSealHash(block.Header(), init.genesis.Config.Bor), bor.SealHash(block.Header(), init.genesis.Config.Bor)) + } + if block.Number().Uint64() == init.genesis.Config.Bor.JaipurBlock { + assert.Equal(t, testSealHash(block.Header(), init.genesis.Config.Bor), bor.SealHash(block.Header(), init.genesis.Config.Bor)) + } + } +} + +// SealHash returns the hash of a block prior to it being sealed. +func testSealHash(header *types.Header, c *params.BorConfig) (hash common.Hash) { + hasher := sha3.NewLegacyKeccak256() + testEncodeSigHeader(hasher, header, c) + hasher.Sum(hash[:0]) + return hash +} + +func testEncodeSigHeader(w io.Writer, header *types.Header, c *params.BorConfig) { + enc := []interface{}{ + header.ParentHash, + header.UncleHash, + header.Coinbase, + header.Root, + header.TxHash, + header.ReceiptHash, + header.Bloom, + header.Difficulty, + header.Number, + header.GasLimit, + header.GasUsed, + header.Time, + header.Extra[:len(header.Extra)-65], // Yes, this will panic if extra is too short + header.MixDigest, + header.Nonce, + } + if c.IsJaipur(header.Number.Uint64()) { + if header.BaseFee != nil { + enc = append(enc, header.BaseFee) + } + } + if err := rlp.Encode(w, enc); err != nil { + panic("can't encode: " + err.Error()) + } +} diff --git a/tests/bor/helper.go b/tests/bor/helper.go index 850d826435..a1b6a19742 100644 --- a/tests/bor/helper.go +++ b/tests/bor/helper.go @@ -11,6 +11,7 @@ import ( "github.com/ethereum/go-ethereum/cmd/utils" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/consensus/bor" + "github.com/ethereum/go-ethereum/consensus/misc" "github.com/ethereum/go-ethereum/core" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/crypto" @@ -111,6 +112,14 @@ func buildNextBlock(t *testing.T, _bor *bor.Bor, chain *core.BlockChain, block * copy(header.Extra[32:], validatorBytes) } + if chain.Config().IsLondon(header.Number) { + header.BaseFee = misc.CalcBaseFee(chain.Config(), block.Header()) + if !chain.Config().IsLondon(block.Number()) { + parentGasLimit := block.GasLimit() * params.ElasticityMultiplier + header.GasLimit = core.CalcGasLimit(parentGasLimit, parentGasLimit) + } + } + state, err := chain.State() if err != nil { t.Fatalf("%s", err) @@ -119,12 +128,12 @@ func buildNextBlock(t *testing.T, _bor *bor.Bor, chain *core.BlockChain, block * if err != nil { t.Fatalf("%s", err) } - sign(t, header, signer) + sign(t, header, signer, borConfig) return types.NewBlockWithHeader(header) } -func sign(t *testing.T, header *types.Header, signer []byte) { - sig, err := secp256k1.Sign(crypto.Keccak256(bor.BorRLP(header)), signer) +func sign(t *testing.T, header *types.Header, signer []byte, c *params.BorConfig) { + sig, err := secp256k1.Sign(crypto.Keccak256(bor.BorRLP(header, c)), signer) if err != nil { t.Fatalf("%s", err) } diff --git a/tests/bor/testdata/genesis.json b/tests/bor/testdata/genesis.json index 584f7fc912..b5767b3ed3 100644 --- a/tests/bor/testdata/genesis.json +++ b/tests/bor/testdata/genesis.json @@ -12,8 +12,9 @@ "istanbulBlock": 0, "muirGlacierBlock": 0, "berlinBlock": 0, - "londonBlock": 10, + "londonBlock": 1, "bor": { + "jaipurBlock": 2, "period": { "0": 1 }, From c227a072418626dd758ceabffd2ea7dadac6eecb Mon Sep 17 00:00:00 2001 From: Sandeep Sreenath Date: Wed, 15 Dec 2021 17:55:18 +0530 Subject: [PATCH 48/51] bumped version to beta2 --- params/version.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/params/version.go b/params/version.go index 26eaaa8fb6..1b3eb1a3a4 100644 --- a/params/version.go +++ b/params/version.go @@ -21,10 +21,10 @@ import ( ) const ( - VersionMajor = 0 // Major version component of the current release - VersionMinor = 2 // Minor version component of the current release - VersionPatch = 13 // Patch version component of the current release - VersionMeta = "beta" // Version metadata to append to the version string + VersionMajor = 0 // Major version component of the current release + VersionMinor = 2 // Minor version component of the current release + VersionPatch = 13 // Patch version component of the current release + VersionMeta = "beta2" // Version metadata to append to the version string ) // Version holds the textual version string. From 09ed09124fb5a7290ab0350c8e229d5241106752 Mon Sep 17 00:00:00 2001 From: Arpit Temani Date: Mon, 10 Jan 2022 16:29:28 +0530 Subject: [PATCH 49/51] add london fork --- command/server/chains/mainnet.go | 14 ++++++++++++++ params/config.go | 11 ++++++----- 2 files changed, 20 insertions(+), 5 deletions(-) diff --git a/command/server/chains/mainnet.go b/command/server/chains/mainnet.go index 631b6e6647..2cd26766c8 100644 --- a/command/server/chains/mainnet.go +++ b/command/server/chains/mainnet.go @@ -27,7 +27,9 @@ var mainnetBor = &Chain{ IstanbulBlock: big.NewInt(3395000), MuirGlacierBlock: big.NewInt(3395000), BerlinBlock: big.NewInt(14750000), + LondonBlock: big.NewInt(23850000), Bor: ¶ms.BorConfig{ + JaipurBlock: 23850000, Period: map[string]uint64{ "0": 2, }, @@ -49,6 +51,18 @@ var mainnetBor = &Chain{ "14953792": 0, "14953856": 0, }, + BurntContract: map[string]string{ + "23850000": "0x0000000000000000000000000000000000000000", + }, + BlockAlloc: map[string]interface{}{ + // write as interface since that is how it is decoded in genesis + "22156660": map[string]interface{}{ + "0000000000000000000000000000000000001010": map[string]interface{}{ + "balance": "0x0", + "code": "0x60806040526004361061019c5760003560e01c806377d32e94116100ec578063acd06cb31161008a578063e306f77911610064578063e306f77914610a7b578063e614d0d614610aa6578063f2fde38b14610ad1578063fc0c546a14610b225761019c565b8063acd06cb31461097a578063b789543c146109cd578063cc79f97b14610a505761019c565b80639025e64c116100c65780639025e64c146107c957806395d89b4114610859578063a9059cbb146108e9578063abceeba21461094f5761019c565b806377d32e94146106315780638da5cb5b146107435780638f32d59b1461079a5761019c565b806347e7ef24116101595780637019d41a116101335780637019d41a1461053357806370a082311461058a578063715018a6146105ef578063771282f6146106065761019c565b806347e7ef2414610410578063485cc9551461046b57806360f96a8f146104dc5761019c565b806306fdde03146101a15780631499c5921461023157806318160ddd1461028257806319d27d9c146102ad5780632e1a7d4d146103b1578063313ce567146103df575b600080fd5b3480156101ad57600080fd5b506101b6610b79565b6040518080602001828103825283818151815260200191508051906020019080838360005b838110156101f65780820151818401526020810190506101db565b50505050905090810190601f1680156102235780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561023d57600080fd5b506102806004803603602081101561025457600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610bb6565b005b34801561028e57600080fd5b50610297610c24565b6040518082815260200191505060405180910390f35b3480156102b957600080fd5b5061036f600480360360a08110156102d057600080fd5b81019080803590602001906401000000008111156102ed57600080fd5b8201836020820111156102ff57600080fd5b8035906020019184600183028401116401000000008311171561032157600080fd5b9091929391929390803590602001909291908035906020019092919080359060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610c3a565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6103dd600480360360208110156103c757600080fd5b8101908080359060200190929190505050610caa565b005b3480156103eb57600080fd5b506103f4610dfc565b604051808260ff1660ff16815260200191505060405180910390f35b34801561041c57600080fd5b506104696004803603604081101561043357600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050610e05565b005b34801561047757600080fd5b506104da6004803603604081101561048e57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610fc1565b005b3480156104e857600080fd5b506104f1611090565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b34801561053f57600080fd5b506105486110b6565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b34801561059657600080fd5b506105d9600480360360208110156105ad57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506110dc565b6040518082815260200191505060405180910390f35b3480156105fb57600080fd5b506106046110fd565b005b34801561061257600080fd5b5061061b6111cd565b6040518082815260200191505060405180910390f35b34801561063d57600080fd5b506107016004803603604081101561065457600080fd5b81019080803590602001909291908035906020019064010000000081111561067b57600080fd5b82018360208201111561068d57600080fd5b803590602001918460018302840111640100000000831117156106af57600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505091929192905050506111d3565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b34801561074f57600080fd5b50610758611358565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b3480156107a657600080fd5b506107af611381565b604051808215151515815260200191505060405180910390f35b3480156107d557600080fd5b506107de6113d8565b6040518080602001828103825283818151815260200191508051906020019080838360005b8381101561081e578082015181840152602081019050610803565b50505050905090810190601f16801561084b5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561086557600080fd5b5061086e611411565b6040518080602001828103825283818151815260200191508051906020019080838360005b838110156108ae578082015181840152602081019050610893565b50505050905090810190601f1680156108db5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b610935600480360360408110156108ff57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291908035906020019092919050505061144e565b604051808215151515815260200191505060405180910390f35b34801561095b57600080fd5b50610964611474565b6040518082815260200191505060405180910390f35b34801561098657600080fd5b506109b36004803603602081101561099d57600080fd5b8101908080359060200190929190505050611501565b604051808215151515815260200191505060405180910390f35b3480156109d957600080fd5b50610a3a600480360360808110156109f057600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803590602001909291908035906020019092919080359060200190929190505050611521565b6040518082815260200191505060405180910390f35b348015610a5c57600080fd5b50610a65611541565b6040518082815260200191505060405180910390f35b348015610a8757600080fd5b50610a90611546565b6040518082815260200191505060405180910390f35b348015610ab257600080fd5b50610abb61154c565b6040518082815260200191505060405180910390f35b348015610add57600080fd5b50610b2060048036036020811015610af457600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506115d9565b005b348015610b2e57600080fd5b50610b376115f6565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b60606040518060400160405280600b81526020017f4d6174696320546f6b656e000000000000000000000000000000000000000000815250905090565b6040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260108152602001807f44697361626c656420666561747572650000000000000000000000000000000081525060200191505060405180910390fd5b6000601260ff16600a0a6402540be40002905090565b60006040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260108152602001807f44697361626c656420666561747572650000000000000000000000000000000081525060200191505060405180910390fd5b60003390506000610cba826110dc565b9050610cd18360065461161c90919063ffffffff16565b600681905550600083118015610ce657508234145b610d58576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260138152602001807f496e73756666696369656e7420616d6f756e740000000000000000000000000081525060200191505060405180910390fd5b8173ffffffffffffffffffffffffffffffffffffffff16600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167febff2602b3f468259e1e99f613fed6691f3a6526effe6ef3e768ba7ae7a36c4f8584610dd4876110dc565b60405180848152602001838152602001828152602001935050505060405180910390a3505050565b60006012905090565b610e0d611381565b610e1657600080fd5b600081118015610e535750600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614155b610ea8576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526023815260200180611da76023913960400191505060405180910390fd5b6000610eb3836110dc565b905060008390508073ffffffffffffffffffffffffffffffffffffffff166108fc849081150290604051600060405180830381858888f19350505050158015610f00573d6000803e3d6000fd5b50610f168360065461163c90919063ffffffff16565b6006819055508373ffffffffffffffffffffffffffffffffffffffff16600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f4e2ca0515ed1aef1395f66b5303bb5d6f1bf9d61a353fa53f73f8ac9973fa9f68585610f98896110dc565b60405180848152602001838152602001828152602001935050505060405180910390a350505050565b600760009054906101000a900460ff1615611027576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526023815260200180611d846023913960400191505060405180910390fd5b6001600760006101000a81548160ff02191690831515021790555080600260006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555061108c8261165b565b5050565b600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60008173ffffffffffffffffffffffffffffffffffffffff16319050919050565b611105611381565b61110e57600080fd5b600073ffffffffffffffffffffffffffffffffffffffff166000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a360008060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550565b60065481565b60008060008060418551146111ee5760009350505050611352565b602085015192506040850151915060ff6041860151169050601b8160ff16101561121957601b810190505b601b8160ff16141580156112315750601c8160ff1614155b156112425760009350505050611352565b60018682858560405160008152602001604052604051808581526020018460ff1660ff1681526020018381526020018281526020019450505050506020604051602081039080840390855afa15801561129f573d6000803e3d6000fd5b505050602060405103519350600073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff16141561134e576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260128152602001807f4572726f7220696e2065637265636f766572000000000000000000000000000081525060200191505060405180910390fd5b5050505b92915050565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614905090565b6040518060400160405280600181526020017f890000000000000000000000000000000000000000000000000000000000000081525081565b60606040518060400160405280600581526020017f4d41544943000000000000000000000000000000000000000000000000000000815250905090565b6000813414611460576000905061146e565b61146b338484611753565b90505b92915050565b6040518060800160405280605b8152602001611e1c605b91396040516020018082805190602001908083835b602083106114c357805182526020820191506020810190506020830392506114a0565b6001836020036101000a0380198251168184511680821785525050505050509050019150506040516020818303038152906040528051906020012081565b60056020528060005260406000206000915054906101000a900460ff1681565b600061153761153286868686611b10565b611be6565b9050949350505050565b608981565b60015481565b604051806080016040528060528152602001611dca605291396040516020018082805190602001908083835b6020831061159b5780518252602082019150602081019050602083039250611578565b6001836020036101000a0380198251168184511680821785525050505050509050019150506040516020818303038152906040528051906020012081565b6115e1611381565b6115ea57600080fd5b6115f38161165b565b50565b600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60008282111561162b57600080fd5b600082840390508091505092915050565b60008082840190508381101561165157600080fd5b8091505092915050565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16141561169557600080fd5b8073ffffffffffffffffffffffffffffffffffffffff166000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a3806000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b6000803073ffffffffffffffffffffffffffffffffffffffff166370a08231866040518263ffffffff1660e01b8152600401808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060206040518083038186803b1580156117d357600080fd5b505afa1580156117e7573d6000803e3d6000fd5b505050506040513d60208110156117fd57600080fd5b8101908080519060200190929190505050905060003073ffffffffffffffffffffffffffffffffffffffff166370a08231866040518263ffffffff1660e01b8152600401808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060206040518083038186803b15801561188f57600080fd5b505afa1580156118a3573d6000803e3d6000fd5b505050506040513d60208110156118b957600080fd5b810190808051906020019092919050505090506118d7868686611c30565b8473ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff16600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167fe6497e3ee548a3372136af2fcb0696db31fc6cf20260707645068bd3fe97f3c48786863073ffffffffffffffffffffffffffffffffffffffff166370a082318e6040518263ffffffff1660e01b8152600401808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060206040518083038186803b1580156119df57600080fd5b505afa1580156119f3573d6000803e3d6000fd5b505050506040513d6020811015611a0957600080fd5b81019080805190602001909291905050503073ffffffffffffffffffffffffffffffffffffffff166370a082318e6040518263ffffffff1660e01b8152600401808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060206040518083038186803b158015611a9757600080fd5b505afa158015611aab573d6000803e3d6000fd5b505050506040513d6020811015611ac157600080fd5b8101908080519060200190929190505050604051808681526020018581526020018481526020018381526020018281526020019550505050505060405180910390a46001925050509392505050565b6000806040518060800160405280605b8152602001611e1c605b91396040516020018082805190602001908083835b60208310611b625780518252602082019150602081019050602083039250611b3f565b6001836020036101000a03801982511681845116808217855250505050505090500191505060405160208183030381529060405280519060200120905060405181815273ffffffffffffffffffffffffffffffffffffffff8716602082015285604082015284606082015283608082015260a0812092505081915050949350505050565b60008060015490506040517f190100000000000000000000000000000000000000000000000000000000000081528160028201528360228201526042812092505081915050919050565b3073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415611cd2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260138152602001807f63616e27742073656e6420746f204d524332300000000000000000000000000081525060200191505060405180910390fd5b8173ffffffffffffffffffffffffffffffffffffffff166108fc829081150290604051600060405180830381858888f19350505050158015611d18573d6000803e3d6000fd5b508173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef836040518082815260200191505060405180910390a350505056fe54686520636f6e747261637420697320616c726561647920696e697469616c697a6564496e73756666696369656e7420616d6f756e74206f7220696e76616c69642075736572454950373132446f6d61696e28737472696e67206e616d652c737472696e672076657273696f6e2c75696e7432353620636861696e49642c6164647265737320766572696679696e67436f6e747261637429546f6b656e5472616e736665724f726465722861646472657373207370656e6465722c75696e7432353620746f6b656e49644f72416d6f756e742c6279746573333220646174612c75696e743235362065787069726174696f6e29a265627a7a72315820a4a6f71a98ac3fc613c3a8f1e2e11b9eb9b6b39f125f7d9508916c2b8fb02c7164736f6c63430005100032", + }, + }, + }, }, }, Nonce: 0, diff --git a/params/config.go b/params/config.go index 86bf6430b8..a97cdb68fa 100644 --- a/params/config.go +++ b/params/config.go @@ -317,8 +317,9 @@ var ( IstanbulBlock: big.NewInt(3395000), MuirGlacierBlock: big.NewInt(3395000), BerlinBlock: big.NewInt(14750000), - LondonBlock: big.NewInt(0), // TODO - Add london fork block + LondonBlock: big.NewInt(23850000), Bor: &BorConfig{ + JaipurBlock: 23850000, Period: map[string]uint64{ "0": 2, }, @@ -341,8 +342,8 @@ var ( "14953856": 0, }, BurntContract: map[string]string{ - "0": "0x0000000000000000000000000000000000000000", - }, // TODO add london fork contract and block + "23850000": "0x0000000000000000000000000000000000000000", + }, BlockAlloc: map[string]interface{}{ // write as interface since that is how it is decoded in genesis "22156660": map[string]interface{}{ @@ -487,8 +488,8 @@ type BorConfig struct { StateReceiverContract string `json:"stateReceiverContract"` // State receiver contract OverrideStateSyncRecords map[string]int `json:"overrideStateSyncRecords"` // override state records count BlockAlloc map[string]interface{} `json:"blockAlloc"` - BurntContract map[string]string `json:"burntContract"` // governance contract where the token will be sent to and burnt in london fork - JaipurBlock uint64 `json:"jaipurBlock"` // Jaipur switch block (nil = no fork, 0 = already on jaipur) + BurntContract map[string]string `json:"burntContract"` // governance contract where the token will be sent to and burnt in london fork + JaipurBlock uint64 `json:"jaipurBlock"` // Jaipur switch block (nil = no fork, 0 = already on jaipur) } // String implements the stringer interface, returning the consensus engine details. From d84df0dea5bfe8aa1943afa3df532a57138d6458 Mon Sep 17 00:00:00 2001 From: Arpit Temani Date: Mon, 10 Jan 2022 22:51:42 +0530 Subject: [PATCH 50/51] add burnt contract address --- command/server/chains/mainnet.go | 2 +- params/config.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/command/server/chains/mainnet.go b/command/server/chains/mainnet.go index 2cd26766c8..199fe1a0d7 100644 --- a/command/server/chains/mainnet.go +++ b/command/server/chains/mainnet.go @@ -52,7 +52,7 @@ var mainnetBor = &Chain{ "14953856": 0, }, BurntContract: map[string]string{ - "23850000": "0x0000000000000000000000000000000000000000", + "23850000": "0x70bca57f4579f58670ab2d18ef16e02c17553c38", }, BlockAlloc: map[string]interface{}{ // write as interface since that is how it is decoded in genesis diff --git a/params/config.go b/params/config.go index a97cdb68fa..c01076d28d 100644 --- a/params/config.go +++ b/params/config.go @@ -342,7 +342,7 @@ var ( "14953856": 0, }, BurntContract: map[string]string{ - "23850000": "0x0000000000000000000000000000000000000000", + "23850000": "0x70bca57f4579f58670ab2d18ef16e02c17553c38", }, BlockAlloc: map[string]interface{}{ // write as interface since that is how it is decoded in genesis From c5013ddcb6a8cddf231b5d79f873ca85ba77181d Mon Sep 17 00:00:00 2001 From: Sandeep Sreenath Date: Tue, 11 Jan 2022 00:23:34 +0530 Subject: [PATCH 51/51] Update version.go --- params/version.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/params/version.go b/params/version.go index 1b3eb1a3a4..c9f0f7c956 100644 --- a/params/version.go +++ b/params/version.go @@ -24,7 +24,7 @@ const ( VersionMajor = 0 // Major version component of the current release VersionMinor = 2 // Minor version component of the current release VersionPatch = 13 // Patch version component of the current release - VersionMeta = "beta2" // Version metadata to append to the version string + VersionMeta = "stable" // Version metadata to append to the version string ) // Version holds the textual version string.