Skip to content

Commit

Permalink
go/batch-submitter: HTTP/2 fixes
Browse files Browse the repository at this point in the history
The built-in geth client has a bugger implementation of HTTP/2: ethereum/go-ethereum#24292. Additionally, Go 1.17 has better HTTP/2 support than Go 1.15. This PR updates the BSS to use Go 1.17 in built binaries, and adds a flag to disable HTTP/2 support if necessary.
  • Loading branch information
mslipper committed Jan 25, 2022
1 parent 22234b1 commit 5905f3d
Show file tree
Hide file tree
Showing 5 changed files with 59 additions and 6 deletions.
5 changes: 5 additions & 0 deletions .changeset/empty-coats-beam.md
@@ -0,0 +1,5 @@
---
'@eth-optimism/batch-submitter-service': patch
---

Update golang version to support HTTP/2
46 changes: 42 additions & 4 deletions go/batch-submitter/batch_submitter.go
Expand Up @@ -3,17 +3,21 @@ package batchsubmitter
import (
"context"
"crypto/ecdsa"
"crypto/tls"
"fmt"
"github.com/ethereum/go-ethereum/rpc"
"net/http"
"os"
"strconv"
"strings"
"time"

"github.com/ethereum-optimism/optimism/go/batch-submitter/drivers/proposer"
"github.com/ethereum-optimism/optimism/go/batch-submitter/drivers/sequencer"
"github.com/ethereum-optimism/optimism/go/batch-submitter/txmgr"
"github.com/ethereum-optimism/optimism/go/batch-submitter/utils"
l2ethclient "github.com/ethereum-optimism/optimism/l2geth/ethclient"
l2rpc "github.com/ethereum-optimism/optimism/l2geth/rpc"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/ethclient"
Expand Down Expand Up @@ -139,12 +143,12 @@ func NewBatchSubmitter(cfg Config, gitVersion string) (*BatchSubmitter, error) {

// Connect to L1 and L2 providers. Perform these last since they are the
// most expensive.
l1Client, err := dialL1EthClientWithTimeout(ctx, cfg.L1EthRpc)
l1Client, err := dialL1EthClientWithTimeout(ctx, cfg.L1EthRpc, cfg.DisableHTTP2)
if err != nil {
return nil, err
}

l2Client, err := dialL2EthClientWithTimeout(ctx, cfg.L2EthRpc)
l2Client, err := dialL2EthClientWithTimeout(ctx, cfg.L2EthRpc, cfg.DisableHTTP2)
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -305,24 +309,58 @@ func runMetricsServer(hostname string, port uint64) {
// dialL1EthClientWithTimeout attempts to dial the L1 provider using the
// provided URL. If the dial doesn't complete within defaultDialTimeout seconds,
// this method will return an error.
func dialL1EthClientWithTimeout(ctx context.Context, url string) (
func dialL1EthClientWithTimeout(ctx context.Context, url string, disableHTTP2 bool) (
*ethclient.Client, error) {

ctxt, cancel := context.WithTimeout(ctx, defaultDialTimeout)
defer cancel()

if strings.HasPrefix(url, "http") {
httpClient := new(http.Client)
if disableHTTP2 {
log.Info("Disabled HTTP/2 support in L1 eth client")
httpClient.Transport = &http.Transport{
TLSNextProto: make(map[string]func(authority string, c *tls.Conn) http.RoundTripper),
}
}

rpcClient, err := rpc.DialHTTPWithClient(url, httpClient)
if err != nil {
return nil, err
}

return ethclient.NewClient(rpcClient), nil
}

return ethclient.DialContext(ctxt, url)
}

// dialL2EthClientWithTimeout attempts to dial the L2 provider using the
// provided URL. If the dial doesn't complete within defaultDialTimeout seconds,
// this method will return an error.
func dialL2EthClientWithTimeout(ctx context.Context, url string) (
func dialL2EthClientWithTimeout(ctx context.Context, url string, disableHTTP2 bool) (
*l2ethclient.Client, error) {

ctxt, cancel := context.WithTimeout(ctx, defaultDialTimeout)
defer cancel()

if strings.HasPrefix(url, "http") {
httpClient := new(http.Client)
if disableHTTP2 {
log.Info("Disabled HTTP/2 support in L2 eth client")
httpClient.Transport = &http.Transport{
TLSNextProto: make(map[string]func(authority string, c *tls.Conn) http.RoundTripper),
}
}

rpcClient, err := l2rpc.DialHTTPWithClient(url, httpClient)
if err != nil {
return nil, err
}

return l2ethclient.NewClient(rpcClient), nil
}

return l2ethclient.DialContext(ctxt, url)
}

Expand Down
4 changes: 4 additions & 0 deletions go/batch-submitter/config.go
Expand Up @@ -171,6 +171,9 @@ type Config struct {

// MetricsPort is the port at which the metrics server is running.
MetricsPort uint64

// DisableHTTP2 disables HTTP2 support.
DisableHTTP2 bool
}

// NewConfig parses the Config from the provided flags or environment variables.
Expand Down Expand Up @@ -209,6 +212,7 @@ func NewConfig(ctx *cli.Context) (Config, error) {
MetricsServerEnable: ctx.GlobalBool(flags.MetricsServerEnableFlag.Name),
MetricsHostname: ctx.GlobalString(flags.MetricsHostnameFlag.Name),
MetricsPort: ctx.GlobalUint64(flags.MetricsPortFlag.Name),
DisableHTTP2: ctx.GlobalBool(flags.HTTP2DisableFlag.Name),
}

err := ValidateConfig(&cfg)
Expand Down
6 changes: 6 additions & 0 deletions go/batch-submitter/flags/flags.go
Expand Up @@ -208,6 +208,11 @@ var (
Value: 7300,
EnvVar: prefixEnvVar("METRICS_PORT"),
}
HTTP2DisableFlag = cli.BoolFlag{
Name: "http2-disable",
Usage: "Whether or not to disable HTTP/2 support.",
EnvVar: prefixEnvVar("HTTP2_DISABLE"),
}
)

var requiredFlags = []cli.Flag{
Expand Down Expand Up @@ -245,6 +250,7 @@ var optionalFlags = []cli.Flag{
MetricsServerEnableFlag,
MetricsHostnameFlag,
MetricsPortFlag,
HTTP2DisableFlag,
}

// Flags contains the list of configuration options available to the binary.
Expand Down
4 changes: 2 additions & 2 deletions ops/docker/Dockerfile.batch-submitter-service
@@ -1,4 +1,4 @@
FROM golang:1.15-alpine3.13 as builder
FROM golang:1.17.6-alpine3.15 as builder

RUN apk add --no-cache make gcc musl-dev linux-headers git jq bash

Expand All @@ -9,7 +9,7 @@ RUN go mod graph | grep -v l2geth | awk '{if ($1 !~ "@") print $2}' | xargs -n 1
COPY ./go/batch-submitter/ ./
RUN make

FROM alpine:3.13
FROM alpine:3.15

RUN apk add --no-cache ca-certificates jq curl
COPY --from=builder /go/batch-submitter/batch-submitter /usr/local/bin/
Expand Down

0 comments on commit 5905f3d

Please sign in to comment.