Commit 5905f3dc authored by Matthew Slipper's avatar Matthew Slipper

go/batch-submitter: HTTP/2 fixes

The built-in geth client has a bugger implementation of HTTP/2: https://github.com/ethereum/go-ethereum/pull/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.
parent 22234b1d
---
'@eth-optimism/batch-submitter-service': patch
---
Update golang version to support HTTP/2
......@@ -3,10 +3,13 @@ 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"
......@@ -14,6 +17,7 @@ import (
"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"
......@@ -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
}
......@@ -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)
}
......
......@@ -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.
......@@ -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)
......
......@@ -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{
......@@ -245,6 +250,7 @@ var optionalFlags = []cli.Flag{
MetricsServerEnableFlag,
MetricsHostnameFlag,
MetricsPortFlag,
HTTP2DisableFlag,
}
// Flags contains the list of configuration options available to the binary.
......
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
......@@ -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/
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment