diff --git a/go.mod b/go.mod index 7af6dcb..8c3625f 100644 --- a/go.mod +++ b/go.mod @@ -14,6 +14,7 @@ require ( github.com/sirupsen/logrus v1.9.3 github.com/spf13/cobra v1.8.0 github.com/wealdtech/go-eth2-wallet-encryptor-keystorev4 v1.1.3 + golang.org/x/mod v0.21.0 gopkg.in/yaml.v2 v2.4.0 ) @@ -131,7 +132,6 @@ require ( go.uber.org/zap v1.27.0 // indirect golang.org/x/crypto v0.26.0 // indirect golang.org/x/exp v0.0.0-20240808152545-0cdaa3abc0fa // indirect - golang.org/x/mod v0.20.0 // indirect golang.org/x/net v0.28.0 // indirect golang.org/x/oauth2 v0.21.0 // indirect golang.org/x/sync v0.8.0 // indirect diff --git a/go.sum b/go.sum index 5f1ed80..7c04079 100644 --- a/go.sum +++ b/go.sum @@ -433,8 +433,8 @@ golang.org/x/exp v0.0.0-20240808152545-0cdaa3abc0fa h1:ELnwvuAXPNtPk1TJRuGkI9fDT golang.org/x/exp v0.0.0-20240808152545-0cdaa3abc0fa/go.mod h1:akd2r19cwCdwSwWeIdzYQGa/EZZyqcOdwWiwj5L5eKQ= golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.20.0 h1:utOm6MM3R3dnawAiJgn0y+xvuYRsm1RKM/4giyfDgV0= -golang.org/x/mod v0.20.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= +golang.org/x/mod v0.21.0 h1:vvrHzRwRfVKSiLrG+d4FMl/Qi4ukBCE6kZlTUkDYRT0= +golang.org/x/mod v0.21.0/go.mod h1:6SkKJ3Xj0I0BrPOZoBy3bdMptDDU9oJrpohJ3eWZ1fY= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= diff --git a/main.go b/main.go index 9eaa7f4..58d0608 100644 --- a/main.go +++ b/main.go @@ -24,6 +24,7 @@ import ( "github.com/flashbots/mev-boost-relay/beaconclient" mevRCommon "github.com/flashbots/mev-boost-relay/common" + "golang.org/x/mod/semver" "github.com/ethereum/go-ethereum/core/types" ecrypto "github.com/ethereum/go-ethereum/crypto" @@ -58,6 +59,7 @@ var validateFlag bool var genesisDelayFlag uint64 var watchPayloadsFlag bool var latestForkFlag bool +var useRethForValidation bool var rootCmd = &cobra.Command{ Use: "playground", @@ -164,6 +166,7 @@ func main() { rootCmd.Flags().Uint64Var(&genesisDelayFlag, "genesis-delay", 5, "") rootCmd.Flags().BoolVar(&watchPayloadsFlag, "watch-payloads", false, "") rootCmd.Flags().BoolVar(&latestForkFlag, "electra", false, "") + rootCmd.Flags().BoolVar(&useRethForValidation, "use-reth-for-validation", false, "enable flashbots_validateBuilderSubmissionV* on reth and use them for validation") downloadArtifactsCmd.Flags().BoolVar(&validateFlag, "validate", false, "") validateCmd.Flags().Uint64Var(&numBlocksValidate, "num-blocks", 5, "") @@ -361,12 +364,32 @@ func setupServices(svcManager *serviceManager, out *output) error { fmt.Printf("(%d) %s (%s)\n", indx, acc, ecrypto.PubkeyToAddress(priv.PublicKey).Hex()) } fmt.Println("") - if err := os.WriteFile(defaultRethDiscoveryPrivKeyLoc, []byte(defaultRethDiscoveryPrivKey), 0644); err != nil { return err } + rethVersion := func() string { + cmd := exec.Command(rethBin, "--version") + out, err := cmd.Output() + if err != nil { + return "unknown" + } + // find the line of the form: + // reth Version: x.y.z + for _, line := range strings.Split(string(out), "\n") { + if strings.HasPrefix(line, "reth Version: ") { + v := strings.TrimSpace(strings.TrimPrefix(line, "reth Version: ")) + if !strings.HasPrefix(v, "v") { + v = "v" + v + } + return semver.Canonical(v) + } + } + return "unknown" + }() + // start the reth el client + fmt.Println("Starting reth version " + rethVersion) svcManager. NewService("reth"). WithArgs( @@ -387,6 +410,16 @@ func setupServices(svcManager *serviceManager, out *output) error { "--authrpc.port", "8551", "--authrpc.jwtsecret", "{{.Dir}}/jwtsecret", ). + If(useRethForValidation, func(s *service) *service { + return s.WithArgs("--http.api", "eth,web3,net,rpc,flashbots") + }). + If( + semver.Compare(rethVersion, "v1.1.0") >= 0, + func(s *service) *service { + // For versions >= v1.1.0, we need to run with --engine.legacy, at least for now + return s.WithArgs("--engine.legacy") + }, + ). WithPort("rpc", 30303). WithPort("http", 8545). WithPort("authrpc", 8551). @@ -444,6 +477,7 @@ func setupServices(svcManager *serviceManager, out *output) error { if cfg.LogOutput, err = out.LogOutput("mev-boost-relay"); err != nil { return err } + cfg.UseRethForValidation = useRethForValidation relay, err := mevboostrelay.New(cfg) if err != nil { return fmt.Errorf("failed to create relay: %w", err) @@ -731,6 +765,13 @@ func (s *service) WithArgs(args ...string) *service { return s } +func (s *service) If(cond bool, fn func(*service) *service) *service { + if cond { + return fn(s) + } + return s +} + func (s *service) Run() { s.srvMng.Run(s) } diff --git a/mev-boost-relay/mev-boost-relay.go b/mev-boost-relay/mev-boost-relay.go index 2e64dde..0975800 100644 --- a/mev-boost-relay/mev-boost-relay.go +++ b/mev-boost-relay/mev-boost-relay.go @@ -33,15 +33,18 @@ type Config struct { ApiSecretKey string BeaconClientAddr string LogOutput io.Writer + + UseRethForValidation bool } func DefaultConfig() *Config { return &Config{ - ApiListenAddr: "127.0.0.1", - ApiListenPort: 5555, - ApiSecretKey: defaultSecretKey, - BeaconClientAddr: "http://localhost:3500", - LogOutput: os.Stdout, + ApiListenAddr: "127.0.0.1", + ApiListenPort: 5555, + ApiSecretKey: defaultSecretKey, + BeaconClientAddr: "http://localhost:3500", + LogOutput: os.Stdout, + UseRethForValidation: false, } } @@ -119,13 +122,20 @@ func New(config *Config) (*MevBoostRelay, error) { housekeeperSrv := housekeeper.NewHousekeeper(housekeeperOpts) - // start a mock block validation service that always - // returns the blocks as valids. - apiBlockSimURL, err := startMockBlockValidationServiceServer() - if err != nil { - return nil, fmt.Errorf("failed to start mock block validation service: %w", err) + var blockSimURL string + if config.UseRethForValidation { + log.Info("Using reth for block validation") + blockSimURL = "http://localhost:8545" + } else { + // start a mock block validation service that always + // returns the blocks as valids. + apiBlockSimURL, err := startMockBlockValidationServiceServer() + if err != nil { + return nil, fmt.Errorf("failed to start mock block validation service: %w", err) + } + log.Info("Started mock block validation service, addr: ", apiBlockSimURL) + blockSimURL = apiBlockSimURL } - log.Info("Started mock block validation service, addr: ", apiBlockSimURL) // decode the secret key envSkBytes, err := hex.DecodeString(strings.TrimPrefix(config.ApiSecretKey, "0x")) @@ -146,7 +156,7 @@ func New(config *Config) (*MevBoostRelay, error) { DB: pqDB, SecretKey: secretKey, EthNetDetails: *ethNetworkDetails, - BlockSimURL: apiBlockSimURL, + BlockSimURL: blockSimURL, ProposerAPI: true, BlockBuilderAPI: true, DataAPI: true,