From a69b6ffd4030b305fda8f6163266131c9835085b Mon Sep 17 00:00:00 2001 From: Marius van der Wijden Date: Sat, 13 Jul 2024 22:54:45 +0200 Subject: [PATCH 1/6] cmd/mev-boost: add urfave as cli framework --- Makefile | 2 +- cli/main.go | 265 ---------------------------- cmd/mev-boost/flags.go | 173 ++++++++++++++++++ {cli => cmd/mev-boost}/main_test.go | 2 +- {cli => cmd/mev-boost}/types.go | 2 +- go.mod | 2 + go.sum | 4 + main.go | 222 ++++++++++++++++++++++- 8 files changed, 402 insertions(+), 270 deletions(-) delete mode 100644 cli/main.go create mode 100644 cmd/mev-boost/flags.go rename {cli => cmd/mev-boost}/main_test.go (98%) rename {cli => cmd/mev-boost}/types.go (99%) diff --git a/Makefile b/Makefile index 06fc69fe..5ddb87cc 100644 --- a/Makefile +++ b/Makefile @@ -24,7 +24,7 @@ v: .PHONY: build build: @go version - CGO_ENABLED=0 go build $(GO_BUILD_FLAGS) -o mev-boost + CGO_ENABLED=0 go build $(GO_BUILD_FLAGS) -o mev-boost ./cmd/mev-boost .PHONY: build-testcli build-testcli: diff --git a/cli/main.go b/cli/main.go deleted file mode 100644 index cc16b1bb..00000000 --- a/cli/main.go +++ /dev/null @@ -1,265 +0,0 @@ -package cli - -import ( - "errors" - "flag" - "fmt" - "os" - "strings" - "time" - - "github.com/flashbots/go-boost-utils/types" - "github.com/flashbots/mev-boost/common" - "github.com/flashbots/mev-boost/config" - "github.com/flashbots/mev-boost/server" - "github.com/sirupsen/logrus" -) - -const ( - genesisForkVersionMainnet = "0x00000000" - genesisForkVersionSepolia = "0x90000069" - genesisForkVersionGoerli = "0x00001020" - genesisForkVersionHolesky = "0x01017000" - - genesisTimeMainnet = 1606824023 - genesisTimeSepolia = 1655733600 - genesisTimeGoerli = 1614588812 - genesisTimeHolesky = 1695902400 -) - -var ( - // errors - errInvalidLoglevel = errors.New("invalid loglevel") - - // defaults - defaultLogJSON = os.Getenv("LOG_JSON") != "" - defaultLogLevel = common.GetEnv("LOG_LEVEL", "info") - defaultListenAddr = common.GetEnv("BOOST_LISTEN_ADDR", "localhost:18550") - defaultRelayCheck = os.Getenv("RELAY_STARTUP_CHECK") != "" - defaultRelayMinBidEth = common.GetEnvFloat64("MIN_BID_ETH", 0) - defaultDisableLogVersion = os.Getenv("DISABLE_LOG_VERSION") == "1" // disables adding the version to every log entry - defaultDebug = os.Getenv("DEBUG") != "" - defaultLogServiceTag = os.Getenv("LOG_SERVICE_TAG") - defaultRelays = os.Getenv("RELAYS") - defaultRelayMonitors = os.Getenv("RELAY_MONITORS") - defaultMaxRetries = common.GetEnvInt("REQUEST_MAX_RETRIES", 5) - - defaultGenesisForkVersion = common.GetEnv("GENESIS_FORK_VERSION", "") - defaultGenesisTime = common.GetEnvInt("GENESIS_TIMESTAMP", -1) - defaultUseSepolia = os.Getenv("SEPOLIA") != "" - defaultUseGoerli = os.Getenv("GOERLI") != "" - defaultUseHolesky = os.Getenv("HOLESKY") != "" - - // mev-boost relay request timeouts (see also https://github.com/flashbots/mev-boost/issues/287) - defaultTimeoutMsGetHeader = common.GetEnvInt("RELAY_TIMEOUT_MS_GETHEADER", 950) // timeout for getHeader requests - defaultTimeoutMsGetPayload = common.GetEnvInt("RELAY_TIMEOUT_MS_GETPAYLOAD", 4000) // timeout for getPayload requests - defaultTimeoutMsRegisterValidator = common.GetEnvInt("RELAY_TIMEOUT_MS_REGVAL", 3000) // timeout for registerValidator requests - - relays relayList - relayMonitors relayMonitorList - - // cli flags - printVersion = flag.Bool("version", false, "only print version") - logJSON = flag.Bool("json", defaultLogJSON, "log in JSON format instead of text") - logLevel = flag.String("loglevel", defaultLogLevel, "minimum loglevel: trace, debug, info, warn/warning, error, fatal, panic") - logDebug = flag.Bool("debug", defaultDebug, "shorthand for '-loglevel debug'") - logService = flag.String("log-service", defaultLogServiceTag, "add a 'service=...' tag to all log messages") - logNoVersion = flag.Bool("log-no-version", defaultDisableLogVersion, "disables adding the version to every log entry") - - listenAddr = flag.String("addr", defaultListenAddr, "listen-address for mev-boost server") - relayURLs = flag.String("relays", defaultRelays, "relay urls - single entry or comma-separated list (scheme://pubkey@host)") - relayCheck = flag.Bool("relay-check", defaultRelayCheck, "check relay status on startup and on the status API call") - relayMinBidEth = flag.Float64("min-bid", defaultRelayMinBidEth, "minimum bid to accept from a relay [eth]") - relayMonitorURLs = flag.String("relay-monitors", defaultRelayMonitors, "relay monitor urls - single entry or comma-separated list (scheme://host)") - - relayTimeoutMsGetHeader = flag.Int("request-timeout-getheader", defaultTimeoutMsGetHeader, "timeout for getHeader requests to the relay [ms]") - relayTimeoutMsGetPayload = flag.Int("request-timeout-getpayload", defaultTimeoutMsGetPayload, "timeout for getPayload requests to the relay [ms]") - relayTimeoutMsRegVal = flag.Int("request-timeout-regval", defaultTimeoutMsRegisterValidator, "timeout for registerValidator requests [ms]") - - relayRequestMaxRetries = flag.Int("request-max-retries", defaultMaxRetries, "maximum number of retries for a relay get payload request") - - // helpers - mainnet = flag.Bool("mainnet", true, "use Mainnet") - sepolia = flag.Bool("sepolia", defaultUseSepolia, "use Sepolia") - goerli = flag.Bool("goerli", defaultUseGoerli, "use Goerli") - holesky = flag.Bool("holesky", defaultUseHolesky, "use Holesky") - - useCustomGenesisForkVersion = flag.String("genesis-fork-version", defaultGenesisForkVersion, "use a custom genesis fork version") - useCustomGenesisTime = flag.Int("genesis-timestamp", defaultGenesisTime, "use a custom genesis timestamp (unix seconds)") -) - -var log = logrus.NewEntry(logrus.New()) - -// Main starts the mev-boost cli -func Main() { - // process repeatable flags - flag.Var(&relays, "relay", "a single relay, can be specified multiple times") - flag.Var(&relayMonitors, "relay-monitor", "a single relay monitor, can be specified multiple times") - - // parse flags and get started - flag.Parse() - - // perhaps only print the version - if *printVersion { - fmt.Printf("mev-boost %s\n", config.Version) //nolint - return - } - - err := setupLogging() - if err != nil { - flag.Usage() - log.WithError(err).Fatal("failed setting up logging") - } - - genesisForkVersionHex := "" - var genesisTime uint64 - - switch { - case *useCustomGenesisForkVersion != "": - genesisForkVersionHex = *useCustomGenesisForkVersion - case *sepolia: - genesisForkVersionHex = genesisForkVersionSepolia - genesisTime = genesisTimeSepolia - case *goerli: - genesisForkVersionHex = genesisForkVersionGoerli - genesisTime = genesisTimeGoerli - case *holesky: - genesisForkVersionHex = genesisForkVersionHolesky - genesisTime = genesisTimeHolesky - case *mainnet: - genesisForkVersionHex = genesisForkVersionMainnet - genesisTime = genesisTimeMainnet - default: - flag.Usage() - log.Fatal("please specify a genesis fork version (eg. -mainnet / -sepolia / -goerli / -holesky / -genesis-fork-version flags)") - } - log.Infof("using genesis fork version: %s", genesisForkVersionHex) - - if *useCustomGenesisTime > -1 { - genesisTime = uint64(*useCustomGenesisTime) - } - - // For backwards compatibility with the -relays flag. - if *relayURLs != "" { - for _, relayURL := range strings.Split(*relayURLs, ",") { - err := relays.Set(strings.TrimSpace(relayURL)) - if err != nil { - log.WithError(err).WithField("relay", relayURL).Fatal("Invalid relay URL") - } - } - } - - if len(relays) == 0 { - flag.Usage() - log.Fatal("no relays specified") - } - log.Infof("using %d relays", len(relays)) - for index, relay := range relays { - log.Infof("relay #%d: %s", index+1, relay.String()) - } - - // For backwards compatibility with the -relay-monitors flag. - if *relayMonitorURLs != "" { - for _, relayMonitorURL := range strings.Split(*relayMonitorURLs, ",") { - err := relayMonitors.Set(strings.TrimSpace(relayMonitorURL)) - if err != nil { - log.WithError(err).WithField("relayMonitor", relayMonitorURL).Fatal("Invalid relay monitor URL") - } - } - } - - if len(relayMonitors) > 0 { - log.Infof("using %d relay monitors", len(relayMonitors)) - for index, relayMonitor := range relayMonitors { - log.Infof("relay-monitor #%d: %s", index+1, relayMonitor.String()) - } - } - - relayMinBidWei, err := sanitizeMinBid(*relayMinBidEth) - if err != nil { - log.WithError(err).Fatal("Failed sanitizing min bid") - } - if relayMinBidWei.BigInt().Sign() > 0 { - log.Infof("Min bid set to %v eth (%v wei)", relayMinBidEth, relayMinBidWei) - } - - opts := server.BoostServiceOpts{ - Log: log, - ListenAddr: *listenAddr, - Relays: relays, - RelayMonitors: relayMonitors, - GenesisForkVersionHex: genesisForkVersionHex, - GenesisTime: genesisTime, - RelayCheck: *relayCheck, - RelayMinBid: *relayMinBidWei, - RequestTimeoutGetHeader: time.Duration(*relayTimeoutMsGetHeader) * time.Millisecond, - RequestTimeoutGetPayload: time.Duration(*relayTimeoutMsGetPayload) * time.Millisecond, - RequestTimeoutRegVal: time.Duration(*relayTimeoutMsRegVal) * time.Millisecond, - RequestMaxRetries: *relayRequestMaxRetries, - } - service, err := server.NewBoostService(opts) - if err != nil { - log.WithError(err).Fatal("failed creating the server") - } - - if *relayCheck && service.CheckRelays() == 0 { - log.Error("no relay passed the health-check!") - } - - log.Println("listening on", *listenAddr) - log.Fatal(service.StartHTTPServer()) -} - -func setupLogging() error { - // setup logging - log.Logger.SetOutput(os.Stdout) - if *logJSON { - log.Logger.SetFormatter(&logrus.JSONFormatter{ - TimestampFormat: config.RFC3339Milli, - }) - } else { - log.Logger.SetFormatter(&logrus.TextFormatter{ - FullTimestamp: true, - TimestampFormat: config.RFC3339Milli, - }) - } - if *logDebug { - *logLevel = "debug" - } - if *logLevel != "" { - lvl, err := logrus.ParseLevel(*logLevel) - if err != nil { - return fmt.Errorf("%w: %s", errInvalidLoglevel, *logLevel) - } - log.Logger.SetLevel(lvl) - } - if *logService != "" { - log = log.WithField("service", *logService) - } - - // Add version to logs and say hello - addVersionToLogs := !*logNoVersion - if addVersionToLogs { - log = log.WithField("version", config.Version) - log.Infof("starting mev-boost") - } else { - log.Infof("starting mev-boost %s", config.Version) - } - log.Debug("debug logging enabled") - return nil -} - -var ( - errNegativeBid = errors.New("please specify a non-negative minimum bid") - errLargeMinBid = errors.New("minimum bid is too large, please ensure min-bid is denominated in Ethers") -) - -func sanitizeMinBid(minBid float64) (*types.U256Str, error) { - if minBid < 0.0 { - return nil, errNegativeBid - } - if minBid > 1000000.0 { - return nil, errLargeMinBid - } - return common.FloatEthTo256Wei(minBid) -} diff --git a/cmd/mev-boost/flags.go b/cmd/mev-boost/flags.go new file mode 100644 index 00000000..485e86a8 --- /dev/null +++ b/cmd/mev-boost/flags.go @@ -0,0 +1,173 @@ +package main + +import "github.com/urfave/cli/v3" + +const ( + LoggingCategory = "LOGGING AND DEBUGGING" + GenesisCategory = "GENESIS" + RelayCategory = "RELAYS" + GeneralCategory = "GENERAL" +) + +var flags = []cli.Flag{ + // general + addrFlag, + versionFlag, + // logging + jsonFlag, + debugFlag, + logLevelFlag, + logServiceFlag, + logNoVersionFlag, + // genesis + customGenesisForkFlag, + customGenesisTimeFlag, + mainnetFlag, + sepoliaFlag, + holeskyFlag, + // relay + relaysFlag, + relayMonitorFlag, + minBidFlag, + relayCheckFlag, + timeoutGetHeaderFlag, + timeoutGetPayloadFlag, + timeoutRegValFlag, + maxRetriesFlag, +} + +var ( + // General + addrFlag = &cli.StringFlag{ + Name: "addr", + Sources: cli.EnvVars("LOG_LEVEL"), + Value: "localhost:18550", + Usage: "listen-address for mev-boost server", + Category: GeneralCategory, + } + versionFlag = &cli.BoolFlag{ + Name: "version", + Usage: "print version", + Category: GeneralCategory, + } + // Logging and debugging + jsonFlag = &cli.BoolFlag{ + Name: "json", + Sources: cli.EnvVars("LOG_JSON"), + Usage: "log in JSON format instead of text", + Category: LoggingCategory, + } + debugFlag = &cli.BoolFlag{ + Name: "debug", + Sources: cli.EnvVars("DEBUG"), + Usage: "shorthand for '--loglevel debug'", + Category: LoggingCategory, + } + logLevelFlag = &cli.StringFlag{ + Name: "loglevel", + Sources: cli.EnvVars("LOG_LEVEL"), + Value: "info", + Usage: "minimum loglevel: trace, debug, info, warn/warning, error, fatal, panic", + Category: LoggingCategory, + } + logServiceFlag = &cli.StringFlag{ + Name: "log-service", + Sources: cli.EnvVars("LOG_SERVICE_TAG"), + Value: "", + Usage: "add a 'service=...' tag to all log messages", + Category: LoggingCategory, + } + logNoVersionFlag = &cli.BoolFlag{ + Name: "log-no-version", + Sources: cli.EnvVars("DISABLE_LOG_VERSION"), + Usage: "disables adding the version to every log entry", + Category: LoggingCategory, + } + // Genesis Flags + customGenesisForkFlag = &cli.StringFlag{ + Name: "genesis-fork-version", + Sources: cli.EnvVars("GENESIS_FORK_VERSION"), + Usage: "use a custom genesis fork version", + Category: GenesisCategory, + } + customGenesisTimeFlag = &cli.UintFlag{ + Name: "genesis-timestamp", + Sources: cli.EnvVars("GENESIS_TIMESTAMP"), + Usage: "use a custom genesis timestamp (unix seconds)", + Category: GenesisCategory, + } + mainnetFlag = &cli.BoolFlag{ + Name: "mainnet", + Sources: cli.EnvVars("GENESIS_FORK_VERSION"), + Usage: "use Mainnet", + Value: true, + Category: GenesisCategory, + } + sepoliaFlag = &cli.BoolFlag{ + Name: "sepolia", + Sources: cli.EnvVars("SEPOLIA"), + Usage: "use Sepolia", + Category: GenesisCategory, + } + holeskyFlag = &cli.BoolFlag{ + Name: "holesky", + Sources: cli.EnvVars("HOLESKY"), + Usage: "use Holesky", + Category: GenesisCategory, + } + // Relay + relaysFlag = &cli.StringFlag{ + Name: "relay", + Aliases: []string{"relays"}, + Sources: cli.EnvVars("RELAYS"), + Usage: "relay urls - single entry or comma-separated list (scheme://pubkey@host)", + Category: RelayCategory, + } + relayMonitorFlag = &cli.StringFlag{ + Name: "relay-monitors", + Sources: cli.EnvVars("RELAY_MONITORS"), + Usage: "relay monitor urls - single entry or comma-separated list (scheme://host)", + Category: RelayCategory, + } + minBidFlag = &cli.FloatFlag{ + Name: "min-bid", + Sources: cli.EnvVars("MIN_BID_ETH"), + Usage: "minimum bid to accept from a relay [eth]", + Category: RelayCategory, + } + relayCheckFlag = &cli.BoolFlag{ + Name: "relay-check", + Sources: cli.EnvVars("RELAY_STARTUP_CHECK"), + Usage: "check relay status on startup and on the status API call", + Category: RelayCategory, + } + // mev-boost relay request timeouts (see also https://github.com/flashbots/mev-boost/issues/287) + timeoutGetHeaderFlag = &cli.IntFlag{ + Name: "request-timeout-getheader", + Sources: cli.EnvVars("RELAY_TIMEOUT_MS_GETHEADER"), + Usage: "timeout for getHeader requests to the relay [ms]", + Value: 950, + Category: RelayCategory, + } + timeoutGetPayloadFlag = &cli.IntFlag{ + Name: "request-timeout-getpayload", + Sources: cli.EnvVars("RELAY_TIMEOUT_MS_GETPAYLOAD"), + Usage: "timeout for getPayload requests to the relay [ms]", + Value: 4000, + Category: RelayCategory, + } + timeoutRegValFlag = &cli.IntFlag{ + Name: "request-timeout-regval", + Sources: cli.EnvVars("RELAY_TIMEOUT_MS_REGVAL"), + Usage: "timeout for registerValidator requests [ms]", + Value: 3000, + Category: RelayCategory, + } + maxRetriesFlag = &cli.IntFlag{ + Name: "request-max-retries", + Sources: cli.EnvVars("REQUEST_MAX_RETRIES"), + Usage: "maximum number of retries for a relay get payload request", + Value: 5, + Category: RelayCategory, + } +) diff --git a/cli/main_test.go b/cmd/mev-boost/main_test.go similarity index 98% rename from cli/main_test.go rename to cmd/mev-boost/main_test.go index fddd7c15..d45b8ffe 100644 --- a/cli/main_test.go +++ b/cmd/mev-boost/main_test.go @@ -1,4 +1,4 @@ -package cli +package main import ( "math/big" diff --git a/cli/types.go b/cmd/mev-boost/types.go similarity index 99% rename from cli/types.go rename to cmd/mev-boost/types.go index 28c99b39..e96d9fc4 100644 --- a/cli/types.go +++ b/cmd/mev-boost/types.go @@ -1,4 +1,4 @@ -package cli +package main import ( "errors" diff --git a/go.mod b/go.mod index 5157afe7..7baa8234 100644 --- a/go.mod +++ b/go.mod @@ -12,6 +12,7 @@ require ( github.com/prysmaticlabs/go-bitfield v0.0.0-20210809151128-385d8c5e3fb7 github.com/sirupsen/logrus v1.9.3 github.com/stretchr/testify v1.9.0 + github.com/urfave/cli/v3 v3.0.0-alpha9 ) require ( @@ -50,6 +51,7 @@ require ( github.com/rivo/uniseg v0.2.0 // indirect github.com/rogpeppe/go-internal v1.11.0 // indirect github.com/supranational/blst v0.3.11 // indirect + github.com/xrash/smetrics v0.0.0-20240312152122-5f08fbb34913 // indirect golang.org/x/exp v0.0.0-20231110203233-9a3e6036ecaa // indirect golang.org/x/sync v0.7.0 // indirect golang.org/x/text v0.14.0 // indirect diff --git a/go.sum b/go.sum index 14ce2701..53c9f81a 100644 --- a/go.sum +++ b/go.sum @@ -224,6 +224,10 @@ github.com/trailofbits/go-fuzz-utils v0.0.0-20210901195358-9657fcfd256c h1:4WU+p github.com/trailofbits/go-fuzz-utils v0.0.0-20210901195358-9657fcfd256c/go.mod h1:f3jBhpWvuZmue0HZK52GzRHJOYHYSILs/c8+K2S/J+o= github.com/umbracle/gohashtree v0.0.2-alpha.0.20230207094856-5b775a815c10 h1:CQh33pStIp/E30b7TxDlXfM0145bn2e8boI30IxAhTg= github.com/umbracle/gohashtree v0.0.2-alpha.0.20230207094856-5b775a815c10/go.mod h1:x/Pa0FF5Te9kdrlZKJK82YmAkvL8+f989USgz6Jiw7M= +github.com/urfave/cli/v3 v3.0.0-alpha9 h1:P0RMy5fQm1AslQS+XCmy9UknDXctOmG/q/FZkUFnJSo= +github.com/urfave/cli/v3 v3.0.0-alpha9/go.mod h1:0kK/RUFHyh+yIKSfWxwheGndfnrvYSmYFVeKCh03ZUc= +github.com/xrash/smetrics v0.0.0-20240312152122-5f08fbb34913 h1:+qGGcbkzsfDQNPPe9UDgpxAWQrhbbBXOYJFQDq/dtJw= +github.com/xrash/smetrics v0.0.0-20240312152122-5f08fbb34913/go.mod h1:4aEEwZQutDLsQv2Deui4iYQ6DWTxR14g6m8Wv88+Xqk= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= go.uber.org/goleak v1.2.0 h1:xqgm/S+aQvhWFTtR0XK3Jvg7z8kGV8P4X14IzwN3Eqk= diff --git a/main.go b/main.go index a3728342..e7103147 100644 --- a/main.go +++ b/main.go @@ -1,9 +1,227 @@ package main import ( - "github.com/flashbots/mev-boost/cli" + "context" + "errors" + "flag" + "fmt" + "os" + "strings" + "time" + + "github.com/flashbots/go-boost-utils/types" + "github.com/flashbots/mev-boost/common" + "github.com/flashbots/mev-boost/config" + "github.com/flashbots/mev-boost/server" + "github.com/sirupsen/logrus" + "github.com/urfave/cli/v3" +) + +const ( + genesisForkVersionMainnet = "0x00000000" + genesisForkVersionSepolia = "0x90000069" + genesisForkVersionGoerli = "0x00001020" + genesisForkVersionHolesky = "0x01017000" + + genesisTimeMainnet = 1606824023 + genesisTimeSepolia = 1655733600 + genesisTimeGoerli = 1614588812 + genesisTimeHolesky = 1695902400 +) + +var ( + // errors + errInvalidLoglevel = errors.New("invalid loglevel") + errNegativeBid = errors.New("please specify a non-negative minimum bid") + errLargeMinBid = errors.New("minimum bid is too large, please ensure min-bid is denominated in Ethers") + + log = logrus.NewEntry(logrus.New()) ) func main() { - cli.Main() + cmd := &cli.Command{ + Name: "mev-boost", + Usage: "mev-boost implementation, see help for more info", + Action: Main, + Flags: flags, + } + + if err := cmd.Run(context.Background(), os.Args); err != nil { + log.Fatal(err) + } +} + +// Main starts the mev-boost cli +func Main(ctx context.Context, cmd *cli.Command) error { + // Only print the version if the flag is set + if cmd.IsSet(versionFlag.Name) { + fmt.Printf("mev-boost %s\n", config.Version) + return nil + } + + if err := setupLogging(cmd); err != nil { + flag.Usage() + log.WithError(err).Fatal("failed setting up logging") + } + + var ( + genesisForkVersion, genesisTime = setupGenesis(cmd) + relays, monitors, minBid, relayCheck = setupRelays(cmd) + listenAddr = cmd.String(addrFlag.Name) + ) + + opts := server.BoostServiceOpts{ + Log: log, + ListenAddr: listenAddr, + Relays: relays, + RelayMonitors: monitors, + GenesisForkVersionHex: genesisForkVersion, + GenesisTime: genesisTime, + RelayCheck: relayCheck, + RelayMinBid: minBid, + RequestTimeoutGetHeader: time.Duration(cmd.Int(timeoutGetHeaderFlag.Name)) * time.Millisecond, + RequestTimeoutGetPayload: time.Duration(cmd.Int(timeoutGetPayloadFlag.Name)) * time.Millisecond, + RequestTimeoutRegVal: time.Duration(cmd.Int(timeoutRegValFlag.Name)) * time.Millisecond, + RequestMaxRetries: int(cmd.Int(maxRetriesFlag.Name)), + } + service, err := server.NewBoostService(opts) + if err != nil { + log.WithError(err).Fatal("failed creating the server") + } + + if relayCheck && service.CheckRelays() == 0 { + log.Error("no relay passed the health-check!") + } + + log.Infof("Listening on %v", listenAddr) + return service.StartHTTPServer() +} + +func setupRelays(cmd *cli.Command) (relayList, relayMonitorList, types.U256Str, bool) { + // For backwards compatibility with the -relays flag. + var ( + relays relayList + monitors relayMonitorList + ) + if cmd.IsSet(relaysFlag.Name) { + urls := cmd.String(relaysFlag.Name) + for _, url := range strings.Split(urls, ",") { + if err := relays.Set(strings.TrimSpace(url)); err != nil { + log.WithError(err).WithField("relay", url).Fatal("Invalid relay URL") + } + } + } + + if len(relays) == 0 { + log.Fatal("no relays specified") + } + log.Infof("using %d relays", len(relays)) + for index, relay := range relays { + log.Infof("relay #%d: %s", index+1, relay.String()) + } + + // For backwards compatibility with the -relay-monitors flag. + if cmd.IsSet(relayMonitorFlag.Name) { + urls := cmd.String(relayMonitorFlag.Name) + for _, url := range strings.Split(urls, ",") { + if err := monitors.Set(strings.TrimSpace(url)); err != nil { + log.WithError(err).WithField("relayMonitor", url).Fatal("Invalid relay monitor URL") + } + } + } + + if len(monitors) > 0 { + log.Infof("using %d relay monitors", len(monitors)) + for index, relayMonitor := range monitors { + log.Infof("relay-monitor #%d: %s", index+1, relayMonitor.String()) + } + } + + relayMinBidWei, err := sanitizeMinBid(cmd.Float(minBidFlag.Name)) + if err != nil { + log.WithError(err).Fatal("Failed sanitizing min bid") + } + if relayMinBidWei.BigInt().Sign() > 0 { + log.Infof("Min bid set to %v eth (%v wei)", cmd.Float(minBidFlag.Name), relayMinBidWei) + } + return relays, monitors, *relayMinBidWei, cmd.Bool(relayCheckFlag.Name) +} + +func setupGenesis(cmd *cli.Command) (string, uint64) { + var ( + genesisForkVersion string + genesisTime uint64 + ) + + switch { + case cmd.Bool(customGenesisForkFlag.Name): + genesisForkVersion = cmd.String(customGenesisForkFlag.Name) + case cmd.Bool(sepoliaFlag.Name): + genesisForkVersion = genesisForkVersionSepolia + genesisTime = genesisTimeSepolia + case cmd.Bool(holeskyFlag.Name): + genesisForkVersion = genesisForkVersionHolesky + genesisTime = genesisTimeHolesky + case cmd.Bool(mainnetFlag.Name): + genesisForkVersion = genesisForkVersionMainnet + genesisTime = genesisTimeMainnet + default: + flag.Usage() + log.Fatal("please specify a genesis fork version (eg. -mainnet / -sepolia / -goerli / -holesky / -genesis-fork-version flags)") + } + + if cmd.IsSet(customGenesisTimeFlag.Name) { + genesisTime = cmd.Uint(customGenesisTimeFlag.Name) + } + log.Infof("using genesis fork version: %s time: %d", genesisForkVersion, genesisTime) + return genesisForkVersion, genesisTime +} + +func setupLogging(cmd *cli.Command) error { + // setup logging + log.Logger.SetOutput(os.Stdout) + if cmd.IsSet(jsonFlag.Name) { + log.Logger.SetFormatter(&logrus.JSONFormatter{ + TimestampFormat: config.RFC3339Milli, + }) + } else { + log.Logger.SetFormatter(&logrus.TextFormatter{ + FullTimestamp: true, + TimestampFormat: config.RFC3339Milli, + }) + } + + logLevel := cmd.String(logLevelFlag.Name) + if cmd.IsSet(debugFlag.Name) { + logLevel = "debug" + } + lvl, err := logrus.ParseLevel(logLevel) + if err != nil { + return fmt.Errorf("%w: %s", errInvalidLoglevel, logLevel) + } + log.Logger.SetLevel(lvl) + + if cmd.IsSet(logServiceFlag.Name) { + log = log.WithField("service", cmd.String(logServiceFlag.Name)) + } + + // Add version to logs and say hello + if cmd.Bool(logNoVersionFlag.Name) { + log.Infof("starting mev-boost %s", config.Version) + } else { + log = log.WithField("version", config.Version) + log.Infof("starting mev-boost") + } + log.Debug("debug logging enabled") + return nil +} + +func sanitizeMinBid(minBid float64) (*types.U256Str, error) { + if minBid < 0.0 { + return nil, errNegativeBid + } + if minBid > 1000000.0 { + return nil, errLargeMinBid + } + return common.FloatEthTo256Wei(minBid) } From d32a58af3ed75b43ed235635ee751b6ee16fdd3f Mon Sep 17 00:00:00 2001 From: Marius van der Wijden Date: Sat, 13 Jul 2024 22:59:32 +0200 Subject: [PATCH 2/6] cmd/mev-boost: remove weird symlink --- cmd/mev-boost/main.go | 228 +++++++++++++++++++++++++++++++++++++++++- main.go | 227 ----------------------------------------- 2 files changed, 227 insertions(+), 228 deletions(-) mode change 120000 => 100644 cmd/mev-boost/main.go delete mode 100644 main.go diff --git a/cmd/mev-boost/main.go b/cmd/mev-boost/main.go deleted file mode 120000 index f67563dc..00000000 --- a/cmd/mev-boost/main.go +++ /dev/null @@ -1 +0,0 @@ -../../main.go \ No newline at end of file diff --git a/cmd/mev-boost/main.go b/cmd/mev-boost/main.go new file mode 100644 index 00000000..e7103147 --- /dev/null +++ b/cmd/mev-boost/main.go @@ -0,0 +1,227 @@ +package main + +import ( + "context" + "errors" + "flag" + "fmt" + "os" + "strings" + "time" + + "github.com/flashbots/go-boost-utils/types" + "github.com/flashbots/mev-boost/common" + "github.com/flashbots/mev-boost/config" + "github.com/flashbots/mev-boost/server" + "github.com/sirupsen/logrus" + "github.com/urfave/cli/v3" +) + +const ( + genesisForkVersionMainnet = "0x00000000" + genesisForkVersionSepolia = "0x90000069" + genesisForkVersionGoerli = "0x00001020" + genesisForkVersionHolesky = "0x01017000" + + genesisTimeMainnet = 1606824023 + genesisTimeSepolia = 1655733600 + genesisTimeGoerli = 1614588812 + genesisTimeHolesky = 1695902400 +) + +var ( + // errors + errInvalidLoglevel = errors.New("invalid loglevel") + errNegativeBid = errors.New("please specify a non-negative minimum bid") + errLargeMinBid = errors.New("minimum bid is too large, please ensure min-bid is denominated in Ethers") + + log = logrus.NewEntry(logrus.New()) +) + +func main() { + cmd := &cli.Command{ + Name: "mev-boost", + Usage: "mev-boost implementation, see help for more info", + Action: Main, + Flags: flags, + } + + if err := cmd.Run(context.Background(), os.Args); err != nil { + log.Fatal(err) + } +} + +// Main starts the mev-boost cli +func Main(ctx context.Context, cmd *cli.Command) error { + // Only print the version if the flag is set + if cmd.IsSet(versionFlag.Name) { + fmt.Printf("mev-boost %s\n", config.Version) + return nil + } + + if err := setupLogging(cmd); err != nil { + flag.Usage() + log.WithError(err).Fatal("failed setting up logging") + } + + var ( + genesisForkVersion, genesisTime = setupGenesis(cmd) + relays, monitors, minBid, relayCheck = setupRelays(cmd) + listenAddr = cmd.String(addrFlag.Name) + ) + + opts := server.BoostServiceOpts{ + Log: log, + ListenAddr: listenAddr, + Relays: relays, + RelayMonitors: monitors, + GenesisForkVersionHex: genesisForkVersion, + GenesisTime: genesisTime, + RelayCheck: relayCheck, + RelayMinBid: minBid, + RequestTimeoutGetHeader: time.Duration(cmd.Int(timeoutGetHeaderFlag.Name)) * time.Millisecond, + RequestTimeoutGetPayload: time.Duration(cmd.Int(timeoutGetPayloadFlag.Name)) * time.Millisecond, + RequestTimeoutRegVal: time.Duration(cmd.Int(timeoutRegValFlag.Name)) * time.Millisecond, + RequestMaxRetries: int(cmd.Int(maxRetriesFlag.Name)), + } + service, err := server.NewBoostService(opts) + if err != nil { + log.WithError(err).Fatal("failed creating the server") + } + + if relayCheck && service.CheckRelays() == 0 { + log.Error("no relay passed the health-check!") + } + + log.Infof("Listening on %v", listenAddr) + return service.StartHTTPServer() +} + +func setupRelays(cmd *cli.Command) (relayList, relayMonitorList, types.U256Str, bool) { + // For backwards compatibility with the -relays flag. + var ( + relays relayList + monitors relayMonitorList + ) + if cmd.IsSet(relaysFlag.Name) { + urls := cmd.String(relaysFlag.Name) + for _, url := range strings.Split(urls, ",") { + if err := relays.Set(strings.TrimSpace(url)); err != nil { + log.WithError(err).WithField("relay", url).Fatal("Invalid relay URL") + } + } + } + + if len(relays) == 0 { + log.Fatal("no relays specified") + } + log.Infof("using %d relays", len(relays)) + for index, relay := range relays { + log.Infof("relay #%d: %s", index+1, relay.String()) + } + + // For backwards compatibility with the -relay-monitors flag. + if cmd.IsSet(relayMonitorFlag.Name) { + urls := cmd.String(relayMonitorFlag.Name) + for _, url := range strings.Split(urls, ",") { + if err := monitors.Set(strings.TrimSpace(url)); err != nil { + log.WithError(err).WithField("relayMonitor", url).Fatal("Invalid relay monitor URL") + } + } + } + + if len(monitors) > 0 { + log.Infof("using %d relay monitors", len(monitors)) + for index, relayMonitor := range monitors { + log.Infof("relay-monitor #%d: %s", index+1, relayMonitor.String()) + } + } + + relayMinBidWei, err := sanitizeMinBid(cmd.Float(minBidFlag.Name)) + if err != nil { + log.WithError(err).Fatal("Failed sanitizing min bid") + } + if relayMinBidWei.BigInt().Sign() > 0 { + log.Infof("Min bid set to %v eth (%v wei)", cmd.Float(minBidFlag.Name), relayMinBidWei) + } + return relays, monitors, *relayMinBidWei, cmd.Bool(relayCheckFlag.Name) +} + +func setupGenesis(cmd *cli.Command) (string, uint64) { + var ( + genesisForkVersion string + genesisTime uint64 + ) + + switch { + case cmd.Bool(customGenesisForkFlag.Name): + genesisForkVersion = cmd.String(customGenesisForkFlag.Name) + case cmd.Bool(sepoliaFlag.Name): + genesisForkVersion = genesisForkVersionSepolia + genesisTime = genesisTimeSepolia + case cmd.Bool(holeskyFlag.Name): + genesisForkVersion = genesisForkVersionHolesky + genesisTime = genesisTimeHolesky + case cmd.Bool(mainnetFlag.Name): + genesisForkVersion = genesisForkVersionMainnet + genesisTime = genesisTimeMainnet + default: + flag.Usage() + log.Fatal("please specify a genesis fork version (eg. -mainnet / -sepolia / -goerli / -holesky / -genesis-fork-version flags)") + } + + if cmd.IsSet(customGenesisTimeFlag.Name) { + genesisTime = cmd.Uint(customGenesisTimeFlag.Name) + } + log.Infof("using genesis fork version: %s time: %d", genesisForkVersion, genesisTime) + return genesisForkVersion, genesisTime +} + +func setupLogging(cmd *cli.Command) error { + // setup logging + log.Logger.SetOutput(os.Stdout) + if cmd.IsSet(jsonFlag.Name) { + log.Logger.SetFormatter(&logrus.JSONFormatter{ + TimestampFormat: config.RFC3339Milli, + }) + } else { + log.Logger.SetFormatter(&logrus.TextFormatter{ + FullTimestamp: true, + TimestampFormat: config.RFC3339Milli, + }) + } + + logLevel := cmd.String(logLevelFlag.Name) + if cmd.IsSet(debugFlag.Name) { + logLevel = "debug" + } + lvl, err := logrus.ParseLevel(logLevel) + if err != nil { + return fmt.Errorf("%w: %s", errInvalidLoglevel, logLevel) + } + log.Logger.SetLevel(lvl) + + if cmd.IsSet(logServiceFlag.Name) { + log = log.WithField("service", cmd.String(logServiceFlag.Name)) + } + + // Add version to logs and say hello + if cmd.Bool(logNoVersionFlag.Name) { + log.Infof("starting mev-boost %s", config.Version) + } else { + log = log.WithField("version", config.Version) + log.Infof("starting mev-boost") + } + log.Debug("debug logging enabled") + return nil +} + +func sanitizeMinBid(minBid float64) (*types.U256Str, error) { + if minBid < 0.0 { + return nil, errNegativeBid + } + if minBid > 1000000.0 { + return nil, errLargeMinBid + } + return common.FloatEthTo256Wei(minBid) +} diff --git a/main.go b/main.go deleted file mode 100644 index e7103147..00000000 --- a/main.go +++ /dev/null @@ -1,227 +0,0 @@ -package main - -import ( - "context" - "errors" - "flag" - "fmt" - "os" - "strings" - "time" - - "github.com/flashbots/go-boost-utils/types" - "github.com/flashbots/mev-boost/common" - "github.com/flashbots/mev-boost/config" - "github.com/flashbots/mev-boost/server" - "github.com/sirupsen/logrus" - "github.com/urfave/cli/v3" -) - -const ( - genesisForkVersionMainnet = "0x00000000" - genesisForkVersionSepolia = "0x90000069" - genesisForkVersionGoerli = "0x00001020" - genesisForkVersionHolesky = "0x01017000" - - genesisTimeMainnet = 1606824023 - genesisTimeSepolia = 1655733600 - genesisTimeGoerli = 1614588812 - genesisTimeHolesky = 1695902400 -) - -var ( - // errors - errInvalidLoglevel = errors.New("invalid loglevel") - errNegativeBid = errors.New("please specify a non-negative minimum bid") - errLargeMinBid = errors.New("minimum bid is too large, please ensure min-bid is denominated in Ethers") - - log = logrus.NewEntry(logrus.New()) -) - -func main() { - cmd := &cli.Command{ - Name: "mev-boost", - Usage: "mev-boost implementation, see help for more info", - Action: Main, - Flags: flags, - } - - if err := cmd.Run(context.Background(), os.Args); err != nil { - log.Fatal(err) - } -} - -// Main starts the mev-boost cli -func Main(ctx context.Context, cmd *cli.Command) error { - // Only print the version if the flag is set - if cmd.IsSet(versionFlag.Name) { - fmt.Printf("mev-boost %s\n", config.Version) - return nil - } - - if err := setupLogging(cmd); err != nil { - flag.Usage() - log.WithError(err).Fatal("failed setting up logging") - } - - var ( - genesisForkVersion, genesisTime = setupGenesis(cmd) - relays, monitors, minBid, relayCheck = setupRelays(cmd) - listenAddr = cmd.String(addrFlag.Name) - ) - - opts := server.BoostServiceOpts{ - Log: log, - ListenAddr: listenAddr, - Relays: relays, - RelayMonitors: monitors, - GenesisForkVersionHex: genesisForkVersion, - GenesisTime: genesisTime, - RelayCheck: relayCheck, - RelayMinBid: minBid, - RequestTimeoutGetHeader: time.Duration(cmd.Int(timeoutGetHeaderFlag.Name)) * time.Millisecond, - RequestTimeoutGetPayload: time.Duration(cmd.Int(timeoutGetPayloadFlag.Name)) * time.Millisecond, - RequestTimeoutRegVal: time.Duration(cmd.Int(timeoutRegValFlag.Name)) * time.Millisecond, - RequestMaxRetries: int(cmd.Int(maxRetriesFlag.Name)), - } - service, err := server.NewBoostService(opts) - if err != nil { - log.WithError(err).Fatal("failed creating the server") - } - - if relayCheck && service.CheckRelays() == 0 { - log.Error("no relay passed the health-check!") - } - - log.Infof("Listening on %v", listenAddr) - return service.StartHTTPServer() -} - -func setupRelays(cmd *cli.Command) (relayList, relayMonitorList, types.U256Str, bool) { - // For backwards compatibility with the -relays flag. - var ( - relays relayList - monitors relayMonitorList - ) - if cmd.IsSet(relaysFlag.Name) { - urls := cmd.String(relaysFlag.Name) - for _, url := range strings.Split(urls, ",") { - if err := relays.Set(strings.TrimSpace(url)); err != nil { - log.WithError(err).WithField("relay", url).Fatal("Invalid relay URL") - } - } - } - - if len(relays) == 0 { - log.Fatal("no relays specified") - } - log.Infof("using %d relays", len(relays)) - for index, relay := range relays { - log.Infof("relay #%d: %s", index+1, relay.String()) - } - - // For backwards compatibility with the -relay-monitors flag. - if cmd.IsSet(relayMonitorFlag.Name) { - urls := cmd.String(relayMonitorFlag.Name) - for _, url := range strings.Split(urls, ",") { - if err := monitors.Set(strings.TrimSpace(url)); err != nil { - log.WithError(err).WithField("relayMonitor", url).Fatal("Invalid relay monitor URL") - } - } - } - - if len(monitors) > 0 { - log.Infof("using %d relay monitors", len(monitors)) - for index, relayMonitor := range monitors { - log.Infof("relay-monitor #%d: %s", index+1, relayMonitor.String()) - } - } - - relayMinBidWei, err := sanitizeMinBid(cmd.Float(minBidFlag.Name)) - if err != nil { - log.WithError(err).Fatal("Failed sanitizing min bid") - } - if relayMinBidWei.BigInt().Sign() > 0 { - log.Infof("Min bid set to %v eth (%v wei)", cmd.Float(minBidFlag.Name), relayMinBidWei) - } - return relays, monitors, *relayMinBidWei, cmd.Bool(relayCheckFlag.Name) -} - -func setupGenesis(cmd *cli.Command) (string, uint64) { - var ( - genesisForkVersion string - genesisTime uint64 - ) - - switch { - case cmd.Bool(customGenesisForkFlag.Name): - genesisForkVersion = cmd.String(customGenesisForkFlag.Name) - case cmd.Bool(sepoliaFlag.Name): - genesisForkVersion = genesisForkVersionSepolia - genesisTime = genesisTimeSepolia - case cmd.Bool(holeskyFlag.Name): - genesisForkVersion = genesisForkVersionHolesky - genesisTime = genesisTimeHolesky - case cmd.Bool(mainnetFlag.Name): - genesisForkVersion = genesisForkVersionMainnet - genesisTime = genesisTimeMainnet - default: - flag.Usage() - log.Fatal("please specify a genesis fork version (eg. -mainnet / -sepolia / -goerli / -holesky / -genesis-fork-version flags)") - } - - if cmd.IsSet(customGenesisTimeFlag.Name) { - genesisTime = cmd.Uint(customGenesisTimeFlag.Name) - } - log.Infof("using genesis fork version: %s time: %d", genesisForkVersion, genesisTime) - return genesisForkVersion, genesisTime -} - -func setupLogging(cmd *cli.Command) error { - // setup logging - log.Logger.SetOutput(os.Stdout) - if cmd.IsSet(jsonFlag.Name) { - log.Logger.SetFormatter(&logrus.JSONFormatter{ - TimestampFormat: config.RFC3339Milli, - }) - } else { - log.Logger.SetFormatter(&logrus.TextFormatter{ - FullTimestamp: true, - TimestampFormat: config.RFC3339Milli, - }) - } - - logLevel := cmd.String(logLevelFlag.Name) - if cmd.IsSet(debugFlag.Name) { - logLevel = "debug" - } - lvl, err := logrus.ParseLevel(logLevel) - if err != nil { - return fmt.Errorf("%w: %s", errInvalidLoglevel, logLevel) - } - log.Logger.SetLevel(lvl) - - if cmd.IsSet(logServiceFlag.Name) { - log = log.WithField("service", cmd.String(logServiceFlag.Name)) - } - - // Add version to logs and say hello - if cmd.Bool(logNoVersionFlag.Name) { - log.Infof("starting mev-boost %s", config.Version) - } else { - log = log.WithField("version", config.Version) - log.Infof("starting mev-boost") - } - log.Debug("debug logging enabled") - return nil -} - -func sanitizeMinBid(minBid float64) (*types.U256Str, error) { - if minBid < 0.0 { - return nil, errNegativeBid - } - if minBid > 1000000.0 { - return nil, errLargeMinBid - } - return common.FloatEthTo256Wei(minBid) -} From 2a42007d9a9b471bf1277459edf506fe7ce9bf71 Mon Sep 17 00:00:00 2001 From: Marius van der Wijden Date: Sat, 13 Jul 2024 23:01:03 +0200 Subject: [PATCH 3/6] happy lint, happy life --- cmd/mev-boost/main.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cmd/mev-boost/main.go b/cmd/mev-boost/main.go index e7103147..e2e7dc40 100644 --- a/cmd/mev-boost/main.go +++ b/cmd/mev-boost/main.go @@ -52,10 +52,10 @@ func main() { } // Main starts the mev-boost cli -func Main(ctx context.Context, cmd *cli.Command) error { +func Main(_ context.Context, cmd *cli.Command) error { // Only print the version if the flag is set if cmd.IsSet(versionFlag.Name) { - fmt.Printf("mev-boost %s\n", config.Version) + log.Infof("mev-boost %s\n", config.Version) return nil } From 99d879a2b06fff659f6e5e8a3773715260d3f590 Mon Sep 17 00:00:00 2001 From: Marius van der Wijden Date: Tue, 23 Jul 2024 11:08:44 +0200 Subject: [PATCH 4/6] cmd/mev-boost: use StringSlice instead of String for relays/monitors --- cmd/mev-boost/flags.go | 5 +++-- cmd/mev-boost/main.go | 20 ++++++++++++-------- 2 files changed, 15 insertions(+), 10 deletions(-) diff --git a/cmd/mev-boost/flags.go b/cmd/mev-boost/flags.go index 485e86a8..8b4c3aa7 100644 --- a/cmd/mev-boost/flags.go +++ b/cmd/mev-boost/flags.go @@ -116,15 +116,16 @@ var ( Category: GenesisCategory, } // Relay - relaysFlag = &cli.StringFlag{ + relaysFlag = &cli.StringSliceFlag{ Name: "relay", Aliases: []string{"relays"}, Sources: cli.EnvVars("RELAYS"), Usage: "relay urls - single entry or comma-separated list (scheme://pubkey@host)", Category: RelayCategory, } - relayMonitorFlag = &cli.StringFlag{ + relayMonitorFlag = &cli.StringSliceFlag{ Name: "relay-monitors", + Aliases: []string{"relay-monitor"}, Sources: cli.EnvVars("RELAY_MONITORS"), Usage: "relay monitor urls - single entry or comma-separated list (scheme://host)", Category: RelayCategory, diff --git a/cmd/mev-boost/main.go b/cmd/mev-boost/main.go index e2e7dc40..f7e70c22 100644 --- a/cmd/mev-boost/main.go +++ b/cmd/mev-boost/main.go @@ -104,10 +104,12 @@ func setupRelays(cmd *cli.Command) (relayList, relayMonitorList, types.U256Str, monitors relayMonitorList ) if cmd.IsSet(relaysFlag.Name) { - urls := cmd.String(relaysFlag.Name) - for _, url := range strings.Split(urls, ",") { - if err := relays.Set(strings.TrimSpace(url)); err != nil { - log.WithError(err).WithField("relay", url).Fatal("Invalid relay URL") + relayURLs := cmd.StringSlice(relaysFlag.Name) + for _, urls := range relayURLs { + for _, url := range strings.Split(urls, ",") { + if err := relays.Set(strings.TrimSpace(url)); err != nil { + log.WithError(err).WithField("relay", url).Fatal("Invalid relay URL") + } } } } @@ -122,10 +124,12 @@ func setupRelays(cmd *cli.Command) (relayList, relayMonitorList, types.U256Str, // For backwards compatibility with the -relay-monitors flag. if cmd.IsSet(relayMonitorFlag.Name) { - urls := cmd.String(relayMonitorFlag.Name) - for _, url := range strings.Split(urls, ",") { - if err := monitors.Set(strings.TrimSpace(url)); err != nil { - log.WithError(err).WithField("relayMonitor", url).Fatal("Invalid relay monitor URL") + monitorURLs := cmd.StringSlice(relayMonitorFlag.Name) + for _, urls := range monitorURLs { + for _, url := range strings.Split(urls, ",") { + if err := monitors.Set(strings.TrimSpace(url)); err != nil { + log.WithError(err).WithField("relayMonitor", url).Fatal("Invalid relay monitor URL") + } } } } From 640c1001bd3c96aca87bc604249efc210b54faef Mon Sep 17 00:00:00 2001 From: Marius van der Wijden Date: Wed, 24 Jul 2024 13:41:05 +0200 Subject: [PATCH 5/6] cmd/mev-boost: re-add the weird indirection for backwards comp --- {cmd/mev-boost => cli}/flags.go | 2 +- cli/main.go | 231 ++++++++++++++++++++++++++++ {cmd/mev-boost => cli}/main_test.go | 2 +- {cmd/mev-boost => cli}/types.go | 2 +- cmd/mev-boost/main.go | 228 +-------------------------- main.go | 7 + 6 files changed, 243 insertions(+), 229 deletions(-) rename {cmd/mev-boost => cli}/flags.go (99%) create mode 100644 cli/main.go rename {cmd/mev-boost => cli}/main_test.go (98%) rename {cmd/mev-boost => cli}/types.go (99%) create mode 100644 main.go diff --git a/cmd/mev-boost/flags.go b/cli/flags.go similarity index 99% rename from cmd/mev-boost/flags.go rename to cli/flags.go index 8b4c3aa7..81ab7a08 100644 --- a/cmd/mev-boost/flags.go +++ b/cli/flags.go @@ -1,4 +1,4 @@ -package main +package cli import "github.com/urfave/cli/v3" diff --git a/cli/main.go b/cli/main.go new file mode 100644 index 00000000..eaaa5b29 --- /dev/null +++ b/cli/main.go @@ -0,0 +1,231 @@ +package cli + +import ( + "context" + "errors" + "flag" + "fmt" + "os" + "strings" + "time" + + "github.com/flashbots/go-boost-utils/types" + "github.com/flashbots/mev-boost/common" + "github.com/flashbots/mev-boost/config" + "github.com/flashbots/mev-boost/server" + "github.com/sirupsen/logrus" + "github.com/urfave/cli/v3" +) + +const ( + genesisForkVersionMainnet = "0x00000000" + genesisForkVersionSepolia = "0x90000069" + genesisForkVersionGoerli = "0x00001020" + genesisForkVersionHolesky = "0x01017000" + + genesisTimeMainnet = 1606824023 + genesisTimeSepolia = 1655733600 + genesisTimeGoerli = 1614588812 + genesisTimeHolesky = 1695902400 +) + +var ( + // errors + errInvalidLoglevel = errors.New("invalid loglevel") + errNegativeBid = errors.New("please specify a non-negative minimum bid") + errLargeMinBid = errors.New("minimum bid is too large, please ensure min-bid is denominated in Ethers") + + log = logrus.NewEntry(logrus.New()) +) + +func Main() { + cmd := &cli.Command{ + Name: "mev-boost", + Usage: "mev-boost implementation, see help for more info", + Action: start, + Flags: flags, + } + + if err := cmd.Run(context.Background(), os.Args); err != nil { + log.Fatal(err) + } +} + +// start starts the mev-boost cli +func start(_ context.Context, cmd *cli.Command) error { + // Only print the version if the flag is set + if cmd.IsSet(versionFlag.Name) { + log.Infof("mev-boost %s\n", config.Version) + return nil + } + + if err := setupLogging(cmd); err != nil { + flag.Usage() + log.WithError(err).Fatal("failed setting up logging") + } + + var ( + genesisForkVersion, genesisTime = setupGenesis(cmd) + relays, monitors, minBid, relayCheck = setupRelays(cmd) + listenAddr = cmd.String(addrFlag.Name) + ) + + opts := server.BoostServiceOpts{ + Log: log, + ListenAddr: listenAddr, + Relays: relays, + RelayMonitors: monitors, + GenesisForkVersionHex: genesisForkVersion, + GenesisTime: genesisTime, + RelayCheck: relayCheck, + RelayMinBid: minBid, + RequestTimeoutGetHeader: time.Duration(cmd.Int(timeoutGetHeaderFlag.Name)) * time.Millisecond, + RequestTimeoutGetPayload: time.Duration(cmd.Int(timeoutGetPayloadFlag.Name)) * time.Millisecond, + RequestTimeoutRegVal: time.Duration(cmd.Int(timeoutRegValFlag.Name)) * time.Millisecond, + RequestMaxRetries: int(cmd.Int(maxRetriesFlag.Name)), + } + service, err := server.NewBoostService(opts) + if err != nil { + log.WithError(err).Fatal("failed creating the server") + } + + if relayCheck && service.CheckRelays() == 0 { + log.Error("no relay passed the health-check!") + } + + log.Infof("Listening on %v", listenAddr) + return service.StartHTTPServer() +} + +func setupRelays(cmd *cli.Command) (relayList, relayMonitorList, types.U256Str, bool) { + // For backwards compatibility with the -relays flag. + var ( + relays relayList + monitors relayMonitorList + ) + if cmd.IsSet(relaysFlag.Name) { + relayURLs := cmd.StringSlice(relaysFlag.Name) + for _, urls := range relayURLs { + for _, url := range strings.Split(urls, ",") { + if err := relays.Set(strings.TrimSpace(url)); err != nil { + log.WithError(err).WithField("relay", url).Fatal("Invalid relay URL") + } + } + } + } + + if len(relays) == 0 { + log.Fatal("no relays specified") + } + log.Infof("using %d relays", len(relays)) + for index, relay := range relays { + log.Infof("relay #%d: %s", index+1, relay.String()) + } + + // For backwards compatibility with the -relay-monitors flag. + if cmd.IsSet(relayMonitorFlag.Name) { + monitorURLs := cmd.StringSlice(relayMonitorFlag.Name) + for _, urls := range monitorURLs { + for _, url := range strings.Split(urls, ",") { + if err := monitors.Set(strings.TrimSpace(url)); err != nil { + log.WithError(err).WithField("relayMonitor", url).Fatal("Invalid relay monitor URL") + } + } + } + } + + if len(monitors) > 0 { + log.Infof("using %d relay monitors", len(monitors)) + for index, relayMonitor := range monitors { + log.Infof("relay-monitor #%d: %s", index+1, relayMonitor.String()) + } + } + + relayMinBidWei, err := sanitizeMinBid(cmd.Float(minBidFlag.Name)) + if err != nil { + log.WithError(err).Fatal("Failed sanitizing min bid") + } + if relayMinBidWei.BigInt().Sign() > 0 { + log.Infof("Min bid set to %v eth (%v wei)", cmd.Float(minBidFlag.Name), relayMinBidWei) + } + return relays, monitors, *relayMinBidWei, cmd.Bool(relayCheckFlag.Name) +} + +func setupGenesis(cmd *cli.Command) (string, uint64) { + var ( + genesisForkVersion string + genesisTime uint64 + ) + + switch { + case cmd.Bool(customGenesisForkFlag.Name): + genesisForkVersion = cmd.String(customGenesisForkFlag.Name) + case cmd.Bool(sepoliaFlag.Name): + genesisForkVersion = genesisForkVersionSepolia + genesisTime = genesisTimeSepolia + case cmd.Bool(holeskyFlag.Name): + genesisForkVersion = genesisForkVersionHolesky + genesisTime = genesisTimeHolesky + case cmd.Bool(mainnetFlag.Name): + genesisForkVersion = genesisForkVersionMainnet + genesisTime = genesisTimeMainnet + default: + flag.Usage() + log.Fatal("please specify a genesis fork version (eg. -mainnet / -sepolia / -goerli / -holesky / -genesis-fork-version flags)") + } + + if cmd.IsSet(customGenesisTimeFlag.Name) { + genesisTime = cmd.Uint(customGenesisTimeFlag.Name) + } + log.Infof("using genesis fork version: %s time: %d", genesisForkVersion, genesisTime) + return genesisForkVersion, genesisTime +} + +func setupLogging(cmd *cli.Command) error { + // setup logging + log.Logger.SetOutput(os.Stdout) + if cmd.IsSet(jsonFlag.Name) { + log.Logger.SetFormatter(&logrus.JSONFormatter{ + TimestampFormat: config.RFC3339Milli, + }) + } else { + log.Logger.SetFormatter(&logrus.TextFormatter{ + FullTimestamp: true, + TimestampFormat: config.RFC3339Milli, + }) + } + + logLevel := cmd.String(logLevelFlag.Name) + if cmd.IsSet(debugFlag.Name) { + logLevel = "debug" + } + lvl, err := logrus.ParseLevel(logLevel) + if err != nil { + return fmt.Errorf("%w: %s", errInvalidLoglevel, logLevel) + } + log.Logger.SetLevel(lvl) + + if cmd.IsSet(logServiceFlag.Name) { + log = log.WithField("service", cmd.String(logServiceFlag.Name)) + } + + // Add version to logs and say hello + if cmd.Bool(logNoVersionFlag.Name) { + log.Infof("starting mev-boost %s", config.Version) + } else { + log = log.WithField("version", config.Version) + log.Infof("starting mev-boost") + } + log.Debug("debug logging enabled") + return nil +} + +func sanitizeMinBid(minBid float64) (*types.U256Str, error) { + if minBid < 0.0 { + return nil, errNegativeBid + } + if minBid > 1000000.0 { + return nil, errLargeMinBid + } + return common.FloatEthTo256Wei(minBid) +} diff --git a/cmd/mev-boost/main_test.go b/cli/main_test.go similarity index 98% rename from cmd/mev-boost/main_test.go rename to cli/main_test.go index d45b8ffe..fddd7c15 100644 --- a/cmd/mev-boost/main_test.go +++ b/cli/main_test.go @@ -1,4 +1,4 @@ -package main +package cli import ( "math/big" diff --git a/cmd/mev-boost/types.go b/cli/types.go similarity index 99% rename from cmd/mev-boost/types.go rename to cli/types.go index e96d9fc4..28c99b39 100644 --- a/cmd/mev-boost/types.go +++ b/cli/types.go @@ -1,4 +1,4 @@ -package main +package cli import ( "errors" diff --git a/cmd/mev-boost/main.go b/cmd/mev-boost/main.go index f7e70c22..2471004c 100644 --- a/cmd/mev-boost/main.go +++ b/cmd/mev-boost/main.go @@ -1,231 +1,7 @@ package main -import ( - "context" - "errors" - "flag" - "fmt" - "os" - "strings" - "time" - - "github.com/flashbots/go-boost-utils/types" - "github.com/flashbots/mev-boost/common" - "github.com/flashbots/mev-boost/config" - "github.com/flashbots/mev-boost/server" - "github.com/sirupsen/logrus" - "github.com/urfave/cli/v3" -) - -const ( - genesisForkVersionMainnet = "0x00000000" - genesisForkVersionSepolia = "0x90000069" - genesisForkVersionGoerli = "0x00001020" - genesisForkVersionHolesky = "0x01017000" - - genesisTimeMainnet = 1606824023 - genesisTimeSepolia = 1655733600 - genesisTimeGoerli = 1614588812 - genesisTimeHolesky = 1695902400 -) - -var ( - // errors - errInvalidLoglevel = errors.New("invalid loglevel") - errNegativeBid = errors.New("please specify a non-negative minimum bid") - errLargeMinBid = errors.New("minimum bid is too large, please ensure min-bid is denominated in Ethers") - - log = logrus.NewEntry(logrus.New()) -) +import "github.com/flashbots/mev-boost/cli" func main() { - cmd := &cli.Command{ - Name: "mev-boost", - Usage: "mev-boost implementation, see help for more info", - Action: Main, - Flags: flags, - } - - if err := cmd.Run(context.Background(), os.Args); err != nil { - log.Fatal(err) - } -} - -// Main starts the mev-boost cli -func Main(_ context.Context, cmd *cli.Command) error { - // Only print the version if the flag is set - if cmd.IsSet(versionFlag.Name) { - log.Infof("mev-boost %s\n", config.Version) - return nil - } - - if err := setupLogging(cmd); err != nil { - flag.Usage() - log.WithError(err).Fatal("failed setting up logging") - } - - var ( - genesisForkVersion, genesisTime = setupGenesis(cmd) - relays, monitors, minBid, relayCheck = setupRelays(cmd) - listenAddr = cmd.String(addrFlag.Name) - ) - - opts := server.BoostServiceOpts{ - Log: log, - ListenAddr: listenAddr, - Relays: relays, - RelayMonitors: monitors, - GenesisForkVersionHex: genesisForkVersion, - GenesisTime: genesisTime, - RelayCheck: relayCheck, - RelayMinBid: minBid, - RequestTimeoutGetHeader: time.Duration(cmd.Int(timeoutGetHeaderFlag.Name)) * time.Millisecond, - RequestTimeoutGetPayload: time.Duration(cmd.Int(timeoutGetPayloadFlag.Name)) * time.Millisecond, - RequestTimeoutRegVal: time.Duration(cmd.Int(timeoutRegValFlag.Name)) * time.Millisecond, - RequestMaxRetries: int(cmd.Int(maxRetriesFlag.Name)), - } - service, err := server.NewBoostService(opts) - if err != nil { - log.WithError(err).Fatal("failed creating the server") - } - - if relayCheck && service.CheckRelays() == 0 { - log.Error("no relay passed the health-check!") - } - - log.Infof("Listening on %v", listenAddr) - return service.StartHTTPServer() -} - -func setupRelays(cmd *cli.Command) (relayList, relayMonitorList, types.U256Str, bool) { - // For backwards compatibility with the -relays flag. - var ( - relays relayList - monitors relayMonitorList - ) - if cmd.IsSet(relaysFlag.Name) { - relayURLs := cmd.StringSlice(relaysFlag.Name) - for _, urls := range relayURLs { - for _, url := range strings.Split(urls, ",") { - if err := relays.Set(strings.TrimSpace(url)); err != nil { - log.WithError(err).WithField("relay", url).Fatal("Invalid relay URL") - } - } - } - } - - if len(relays) == 0 { - log.Fatal("no relays specified") - } - log.Infof("using %d relays", len(relays)) - for index, relay := range relays { - log.Infof("relay #%d: %s", index+1, relay.String()) - } - - // For backwards compatibility with the -relay-monitors flag. - if cmd.IsSet(relayMonitorFlag.Name) { - monitorURLs := cmd.StringSlice(relayMonitorFlag.Name) - for _, urls := range monitorURLs { - for _, url := range strings.Split(urls, ",") { - if err := monitors.Set(strings.TrimSpace(url)); err != nil { - log.WithError(err).WithField("relayMonitor", url).Fatal("Invalid relay monitor URL") - } - } - } - } - - if len(monitors) > 0 { - log.Infof("using %d relay monitors", len(monitors)) - for index, relayMonitor := range monitors { - log.Infof("relay-monitor #%d: %s", index+1, relayMonitor.String()) - } - } - - relayMinBidWei, err := sanitizeMinBid(cmd.Float(minBidFlag.Name)) - if err != nil { - log.WithError(err).Fatal("Failed sanitizing min bid") - } - if relayMinBidWei.BigInt().Sign() > 0 { - log.Infof("Min bid set to %v eth (%v wei)", cmd.Float(minBidFlag.Name), relayMinBidWei) - } - return relays, monitors, *relayMinBidWei, cmd.Bool(relayCheckFlag.Name) -} - -func setupGenesis(cmd *cli.Command) (string, uint64) { - var ( - genesisForkVersion string - genesisTime uint64 - ) - - switch { - case cmd.Bool(customGenesisForkFlag.Name): - genesisForkVersion = cmd.String(customGenesisForkFlag.Name) - case cmd.Bool(sepoliaFlag.Name): - genesisForkVersion = genesisForkVersionSepolia - genesisTime = genesisTimeSepolia - case cmd.Bool(holeskyFlag.Name): - genesisForkVersion = genesisForkVersionHolesky - genesisTime = genesisTimeHolesky - case cmd.Bool(mainnetFlag.Name): - genesisForkVersion = genesisForkVersionMainnet - genesisTime = genesisTimeMainnet - default: - flag.Usage() - log.Fatal("please specify a genesis fork version (eg. -mainnet / -sepolia / -goerli / -holesky / -genesis-fork-version flags)") - } - - if cmd.IsSet(customGenesisTimeFlag.Name) { - genesisTime = cmd.Uint(customGenesisTimeFlag.Name) - } - log.Infof("using genesis fork version: %s time: %d", genesisForkVersion, genesisTime) - return genesisForkVersion, genesisTime -} - -func setupLogging(cmd *cli.Command) error { - // setup logging - log.Logger.SetOutput(os.Stdout) - if cmd.IsSet(jsonFlag.Name) { - log.Logger.SetFormatter(&logrus.JSONFormatter{ - TimestampFormat: config.RFC3339Milli, - }) - } else { - log.Logger.SetFormatter(&logrus.TextFormatter{ - FullTimestamp: true, - TimestampFormat: config.RFC3339Milli, - }) - } - - logLevel := cmd.String(logLevelFlag.Name) - if cmd.IsSet(debugFlag.Name) { - logLevel = "debug" - } - lvl, err := logrus.ParseLevel(logLevel) - if err != nil { - return fmt.Errorf("%w: %s", errInvalidLoglevel, logLevel) - } - log.Logger.SetLevel(lvl) - - if cmd.IsSet(logServiceFlag.Name) { - log = log.WithField("service", cmd.String(logServiceFlag.Name)) - } - - // Add version to logs and say hello - if cmd.Bool(logNoVersionFlag.Name) { - log.Infof("starting mev-boost %s", config.Version) - } else { - log = log.WithField("version", config.Version) - log.Infof("starting mev-boost") - } - log.Debug("debug logging enabled") - return nil -} - -func sanitizeMinBid(minBid float64) (*types.U256Str, error) { - if minBid < 0.0 { - return nil, errNegativeBid - } - if minBid > 1000000.0 { - return nil, errLargeMinBid - } - return common.FloatEthTo256Wei(minBid) + cli.Main() } diff --git a/main.go b/main.go new file mode 100644 index 00000000..2471004c --- /dev/null +++ b/main.go @@ -0,0 +1,7 @@ +package main + +import "github.com/flashbots/mev-boost/cli" + +func main() { + cli.Main() +} From bca06018fd789139aa9ee826f20df2df41d5475a Mon Sep 17 00:00:00 2001 From: Marius van der Wijden Date: Wed, 24 Jul 2024 13:43:14 +0200 Subject: [PATCH 6/6] cmd/mev-boost: symlink the other direction --- main.go | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) mode change 100644 => 120000 main.go diff --git a/main.go b/main.go deleted file mode 100644 index 2471004c..00000000 --- a/main.go +++ /dev/null @@ -1,7 +0,0 @@ -package main - -import "github.com/flashbots/mev-boost/cli" - -func main() { - cli.Main() -} diff --git a/main.go b/main.go new file mode 120000 index 00000000..886ac080 --- /dev/null +++ b/main.go @@ -0,0 +1 @@ +cmd/mev-boost/main.go \ No newline at end of file