From a07fe5e4b41a712e164614969b1160983c4f1bbc Mon Sep 17 00:00:00 2001 From: Chris Ziogas Date: Wed, 25 Nov 2020 11:41:37 +0200 Subject: [PATCH 1/5] cmd/geth, eth: add `ethprotocol=[65|64|63]` cli arg --- cmd/geth/main.go | 1 + cmd/geth/misccmd.go | 2 +- cmd/geth/usage.go | 1 + cmd/utils/flags.go | 40 ++++++++++++++++++++++++++++++++++++++++ eth/backend.go | 8 ++++---- eth/config.go | 5 +++-- eth/protocol.go | 4 ++-- ethstats/ethstats.go | 3 ++- 8 files changed, 54 insertions(+), 10 deletions(-) diff --git a/cmd/geth/main.go b/cmd/geth/main.go index 333d54b514..3cecd61d11 100644 --- a/cmd/geth/main.go +++ b/cmd/geth/main.go @@ -142,6 +142,7 @@ var ( utils.NodeKeyFileFlag, utils.NodeKeyHexFlag, utils.DNSDiscoveryFlag, + utils.EthProtocolsFlag, utils.DeveloperFlag, utils.DeveloperPeriodFlag, utils.ClassicFlag, diff --git a/cmd/geth/misccmd.go b/cmd/geth/misccmd.go index 4dcb299716..97e4fe806a 100644 --- a/cmd/geth/misccmd.go +++ b/cmd/geth/misccmd.go @@ -132,7 +132,7 @@ func version(ctx *cli.Context) error { fmt.Println("Git Commit Date:", gitDate) } fmt.Println("Architecture:", runtime.GOARCH) - fmt.Println("Protocol Versions:", eth.ProtocolVersions) + fmt.Println("Protocol Versions:", eth.DefaultProtocolVersions) fmt.Println("Go Version:", runtime.Version()) fmt.Println("Operating System:", runtime.GOOS) fmt.Printf("GOPATH=%s\n", os.Getenv("GOPATH")) diff --git a/cmd/geth/usage.go b/cmd/geth/usage.go index 9703463d7d..6506b6e30c 100644 --- a/cmd/geth/usage.go +++ b/cmd/geth/usage.go @@ -167,6 +167,7 @@ var AppHelpFlagGroups = []flags.FlagGroup{ utils.LegacyBootnodesV4Flag, utils.LegacyBootnodesV5Flag, utils.DNSDiscoveryFlag, + utils.EthProtocolsFlag, utils.ListenPortFlag, utils.MaxPeersFlag, utils.MaxPendingPeersFlag, diff --git a/cmd/utils/flags.go b/cmd/utils/flags.go index 60ea2d4d70..d703b993a6 100644 --- a/cmd/utils/flags.go +++ b/cmd/utils/flags.go @@ -27,6 +27,7 @@ import ( "os/user" "path/filepath" "runtime" + "sort" "strconv" "strings" "text/tabwriter" @@ -141,6 +142,11 @@ var ( Usage: "Explicitly set network id (integer)(For testnets: use --ropsten, --rinkeby, --goerli, --kotti, --mordor, --yolov1 instead)", Value: eth.DefaultConfig.NetworkId, } + EthProtocolsFlag = cli.StringFlag{ + Name: "ethprotocols", + Usage: "Sets the Ethereum Protocol versions (65|64|63) (default=65,64,63)", + Value: "", + } ClassicFlag = cli.BoolFlag{ Name: "classic", Usage: "Ethereum Classic network: pre-configured Ethereum Classic mainnet", @@ -1726,6 +1732,40 @@ func SetEthConfig(ctx *cli.Context, stack *node.Node, cfg *eth.Config) { cfg.NetworkId = *cfg.Genesis.GetNetworkID() } + if ctx.GlobalIsSet(EthProtocolsFlag.Name) { + protocolVersions := SplitAndTrim(ctx.GlobalString(EthProtocolsFlag.Name)) + if len(protocolVersions) > 0 { + for _, versionString := range protocolVersions { + version, err := strconv.ParseUint(versionString, 10, 0) + if err != nil { + continue + } + + isValid := false + for _, proto := range eth.DefaultProtocolVersions { + if proto == uint(version) { + isValid = true + } + } + + if !isValid { + Fatalf("--%s must be one of %s", EthProtocolsFlag.Name, strings.Join(strings.Fields(fmt.Sprint(eth.DefaultProtocolVersions)), ",")) + } + cfg.ProtocolVersions = append(cfg.ProtocolVersions, uint(version)) + } + } + + // sort protocol version desceding + sort.Slice(cfg.ProtocolVersions, func(i, j int) bool { return cfg.ProtocolVersions[i] > cfg.ProtocolVersions[j] }) + fmt.Printf("ProtocolVersions: %#v\n", cfg.ProtocolVersions) + } + + // set default protocol versions + if len(cfg.ProtocolVersions) == 0 { + fmt.Printf("default ProtocolVersions: %#v\n", cfg.ProtocolVersions) + cfg.ProtocolVersions = eth.DefaultProtocolVersions + } + // Set DNS discovery defaults for hard coded networks with DNS defaults. switch { case ctx.GlobalBool(LegacyTestnetFlag.Name) || ctx.GlobalBool(RopstenFlag.Name): diff --git a/eth/backend.go b/eth/backend.go index f253c3aad6..284f938565 100644 --- a/eth/backend.go +++ b/eth/backend.go @@ -157,7 +157,7 @@ func New(stack *node.Node, config *Config) (*Ethereum, error) { if bcVersion != nil { dbVer = fmt.Sprintf("%d", *bcVersion) } - log.Info("Initialising Ethereum protocol", "versions", ProtocolVersions, "network", config.NetworkId, "dbversion", dbVer) + log.Info("Initialising Ethereum protocol", "versions", config.ProtocolVersions, "network", config.NetworkId, "dbversion", dbVer) if !config.SkipBcVersionCheck { if bcVersion != nil && *bcVersion > core.BlockChainVersion { @@ -514,7 +514,7 @@ func (s *Ethereum) EventMux() *event.TypeMux { return s.eventMux } func (s *Ethereum) Engine() consensus.Engine { return s.engine } func (s *Ethereum) ChainDb() ethdb.Database { return s.chainDb } func (s *Ethereum) IsListening() bool { return true } // Always listening -func (s *Ethereum) EthVersion() int { return int(ProtocolVersions[0]) } +func (s *Ethereum) EthVersion() int { return int(s.config.ProtocolVersions[0]) } func (s *Ethereum) NetVersion() uint64 { return s.networkID } func (s *Ethereum) Downloader() *downloader.Downloader { return s.protocolManager.downloader } func (s *Ethereum) Synced() bool { return atomic.LoadUint32(&s.protocolManager.acceptTxs) == 1 } @@ -524,8 +524,8 @@ func (s *Ethereum) BloomIndexer() *core.ChainIndexer { return s.bloomIndexer } // Protocols returns all the currently configured // network protocols to start. func (s *Ethereum) Protocols() []p2p.Protocol { - protos := make([]p2p.Protocol, len(ProtocolVersions)) - for i, vsn := range ProtocolVersions { + protos := make([]p2p.Protocol, len(s.config.ProtocolVersions)) + for i, vsn := range s.config.ProtocolVersions { protos[i] = s.protocolManager.makeProtocol(vsn) protos[i].Attributes = []enr.Entry{s.currentEthEntry()} protos[i].DialCandidates = s.dialCandidates diff --git a/eth/config.go b/eth/config.go index 9e5cef305c..f71e279d9f 100644 --- a/eth/config.go +++ b/eth/config.go @@ -112,8 +112,9 @@ type Config struct { Genesis *genesisT.Genesis `toml:",omitempty"` // Protocol options - NetworkId uint64 // Network ID to use for selecting peers to connect to - SyncMode downloader.SyncMode + NetworkId uint64 // Network ID to use for selecting peers to connect to + ProtocolVersions []uint // Protocol versions are the supported versions of the eth protocol (first is primary). + SyncMode downloader.SyncMode // This can be set to list of enrtree:// URLs which will be queried for // for nodes to connect to. diff --git a/eth/protocol.go b/eth/protocol.go index dc75d6b31a..ff38da3df0 100644 --- a/eth/protocol.go +++ b/eth/protocol.go @@ -39,8 +39,8 @@ const ( // protocolName is the official short name of the protocol used during capability negotiation. const protocolName = "eth" -// ProtocolVersions are the supported versions of the eth protocol (first is primary). -var ProtocolVersions = []uint{eth65, eth64, eth63} +// DefaultProtocolVersions are the supported versions of the eth protocol (first is primary). +var DefaultProtocolVersions = []uint{eth65, eth64, eth63} // protocolLengths are the number of implemented message corresponding to different protocol versions. var protocolLengths = map[uint]uint64{eth65: 17, eth64: 17, eth63: 17} diff --git a/ethstats/ethstats.go b/ethstats/ethstats.go index eb21595bfe..f82cffab1f 100644 --- a/ethstats/ethstats.go +++ b/ethstats/ethstats.go @@ -61,6 +61,7 @@ const ( // backend encompasses the bare-minimum functionality needed for ethstats reporting type backend interface { + ProtocolVersion() int SubscribeChainHeadEvent(ch chan<- core.ChainHeadEvent) event.Subscription SubscribeNewTxsEvent(ch chan<- core.NewTxsEvent) event.Subscription CurrentHeader() *types.Header @@ -468,7 +469,7 @@ func (s *Service) login(conn *connWrapper) error { var network, protocol string if info := infos.Protocols["eth"]; info != nil { network = fmt.Sprintf("%d", info.(*eth.NodeInfo).Network) - protocol = fmt.Sprintf("eth/%d", eth.ProtocolVersions[0]) + protocol = fmt.Sprintf("eth/%d", s.backend.ProtocolVersion()) } else { network = fmt.Sprintf("%d", infos.Protocols["les"].(*les.NodeInfo).Network) protocol = fmt.Sprintf("les/%d", les.ClientProtocolVersions[0]) From 5c9dc79e9f6ceb879557b0475e31807db01d1068 Mon Sep 17 00:00:00 2001 From: Chris Ziogas Date: Fri, 27 Nov 2020 01:12:40 +0200 Subject: [PATCH 2/5] cmd: remove forgotten debug logs --- cmd/utils/flags.go | 2 -- 1 file changed, 2 deletions(-) diff --git a/cmd/utils/flags.go b/cmd/utils/flags.go index d703b993a6..927d12287d 100644 --- a/cmd/utils/flags.go +++ b/cmd/utils/flags.go @@ -1757,12 +1757,10 @@ func SetEthConfig(ctx *cli.Context, stack *node.Node, cfg *eth.Config) { // sort protocol version desceding sort.Slice(cfg.ProtocolVersions, func(i, j int) bool { return cfg.ProtocolVersions[i] > cfg.ProtocolVersions[j] }) - fmt.Printf("ProtocolVersions: %#v\n", cfg.ProtocolVersions) } // set default protocol versions if len(cfg.ProtocolVersions) == 0 { - fmt.Printf("default ProtocolVersions: %#v\n", cfg.ProtocolVersions) cfg.ProtocolVersions = eth.DefaultProtocolVersions } From 98cb6242512a8490b4d1e391770651037cabe78b Mon Sep 17 00:00:00 2001 From: Chris Ziogas Date: Fri, 27 Nov 2020 16:31:36 +0200 Subject: [PATCH 3/5] cmd: use `eth.protocols` instead of `ethprotocols` based on @meowsbits advice --- cmd/utils/flags.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmd/utils/flags.go b/cmd/utils/flags.go index 927d12287d..e8c206876a 100644 --- a/cmd/utils/flags.go +++ b/cmd/utils/flags.go @@ -143,7 +143,7 @@ var ( Value: eth.DefaultConfig.NetworkId, } EthProtocolsFlag = cli.StringFlag{ - Name: "ethprotocols", + Name: "eth.protocols", Usage: "Sets the Ethereum Protocol versions (65|64|63) (default=65,64,63)", Value: "", } From 5a4d412a5966e9c296d251e88293bbc4ab895de0 Mon Sep 17 00:00:00 2001 From: Chris Ziogas Date: Fri, 27 Nov 2020 16:45:24 +0200 Subject: [PATCH 4/5] =?UTF-8?q?cmd:=20fatal=20error=20when=20`=E2=80=94eth?= =?UTF-8?q?.protocols`=20set=20and=20empty;=20better=20cli=20arg=20comment?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- cmd/utils/flags.go | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/cmd/utils/flags.go b/cmd/utils/flags.go index e8c206876a..01285015db 100644 --- a/cmd/utils/flags.go +++ b/cmd/utils/flags.go @@ -27,7 +27,6 @@ import ( "os/user" "path/filepath" "runtime" - "sort" "strconv" "strings" "text/tabwriter" @@ -144,7 +143,7 @@ var ( } EthProtocolsFlag = cli.StringFlag{ Name: "eth.protocols", - Usage: "Sets the Ethereum Protocol versions (65|64|63) (default=65,64,63)", + Usage: "Sets the Ethereum Protocol versions (65|64|63) (default = 65,64,63 first is primary)", Value: "", } ClassicFlag = cli.BoolFlag{ @@ -1749,14 +1748,13 @@ func SetEthConfig(ctx *cli.Context, stack *node.Node, cfg *eth.Config) { } if !isValid { - Fatalf("--%s must be one of %s", EthProtocolsFlag.Name, strings.Join(strings.Fields(fmt.Sprint(eth.DefaultProtocolVersions)), ",")) + Fatalf("--%s must be comma separated list of %s", EthProtocolsFlag.Name, strings.Join(strings.Fields(fmt.Sprint(eth.DefaultProtocolVersions)), ",")) } cfg.ProtocolVersions = append(cfg.ProtocolVersions, uint(version)) } + } else { + Fatalf("--%s must be comma separated list of %s", EthProtocolsFlag.Name, strings.Join(strings.Fields(fmt.Sprint(eth.DefaultProtocolVersions)), ",")) } - - // sort protocol version desceding - sort.Slice(cfg.ProtocolVersions, func(i, j int) bool { return cfg.ProtocolVersions[i] > cfg.ProtocolVersions[j] }) } // set default protocol versions From 4f7e7cc3974a73be0a214d0efa653b9752402f41 Mon Sep 17 00:00:00 2001 From: Chris Ziogas Date: Fri, 27 Nov 2020 17:37:52 +0200 Subject: [PATCH 5/5] cmd: better error handling --- cmd/utils/flags.go | 41 ++++++++++++++++++++++++----------------- 1 file changed, 24 insertions(+), 17 deletions(-) diff --git a/cmd/utils/flags.go b/cmd/utils/flags.go index 01285015db..98996fd7fe 100644 --- a/cmd/utils/flags.go +++ b/cmd/utils/flags.go @@ -1733,27 +1733,34 @@ func SetEthConfig(ctx *cli.Context, stack *node.Node, cfg *eth.Config) { if ctx.GlobalIsSet(EthProtocolsFlag.Name) { protocolVersions := SplitAndTrim(ctx.GlobalString(EthProtocolsFlag.Name)) - if len(protocolVersions) > 0 { - for _, versionString := range protocolVersions { - version, err := strconv.ParseUint(versionString, 10, 0) - if err != nil { - continue - } + if len(protocolVersions) == 0 { + Fatalf("--%s must be comma separated list of %s", EthProtocolsFlag.Name, strings.Join(strings.Fields(fmt.Sprint(eth.DefaultProtocolVersions)), ",")) + } - isValid := false - for _, proto := range eth.DefaultProtocolVersions { - if proto == uint(version) { - isValid = true - } - } + seenVersions := map[uint]interface{}{} + for _, versionString := range protocolVersions { + version, err := strconv.ParseUint(versionString, 10, 0) + if err != nil { + Fatalf("--%s has invalid value \"%v\" with error: %v", EthProtocolsFlag.Name, versionString, err) + } - if !isValid { - Fatalf("--%s must be comma separated list of %s", EthProtocolsFlag.Name, strings.Join(strings.Fields(fmt.Sprint(eth.DefaultProtocolVersions)), ",")) + if _, duplicate := seenVersions[uint(version)]; duplicate { + Fatalf("--%s has duplicate version of %v", EthProtocolsFlag.Name, versionString) + } + + isValid := false + for _, proto := range eth.DefaultProtocolVersions { + if proto == uint(version) { + isValid = true + seenVersions[uint(version)] = nil + break } - cfg.ProtocolVersions = append(cfg.ProtocolVersions, uint(version)) } - } else { - Fatalf("--%s must be comma separated list of %s", EthProtocolsFlag.Name, strings.Join(strings.Fields(fmt.Sprint(eth.DefaultProtocolVersions)), ",")) + + if !isValid { + Fatalf("--%s must be comma separated list of %s", EthProtocolsFlag.Name, strings.Join(strings.Fields(fmt.Sprint(eth.DefaultProtocolVersions)), ",")) + } + cfg.ProtocolVersions = append(cfg.ProtocolVersions, uint(version)) } }