Commit 3e070e43 authored by Sebastian Stammler's avatar Sebastian Stammler Committed by GitHub

op-node: Add optional Beacon header flag (#9604)

* op-service/client: Add http header option to BasicHTTPClient

* op-node: Add optional Beacon header flag
parent 49ba77a4
......@@ -50,6 +50,12 @@ var (
Required: false,
EnvVars: prefixEnvVars("L1_BEACON"),
}
BeaconHeader = &cli.StringFlag{
Name: "l1.beacon-header",
Usage: "Optional HTTP header to add to all requests to the L1 Beacon endpoint. Format: 'X-Key: Value'",
Required: false,
EnvVars: prefixEnvVars("L1_BEACON_HEADER"),
}
BeaconArchiverAddr = &cli.StringFlag{
Name: "l1.beacon-archiver",
Usage: "Address of L1 Beacon-node compatible HTTP endpoint to use. This is used to fetch blobs that the --l1.beacon does not have (i.e expired blobs).",
......@@ -298,6 +304,7 @@ var requiredFlags = []cli.Flag{
var optionalFlags = []cli.Flag{
BeaconAddr,
BeaconHeader,
BeaconArchiverAddr,
BeaconCheckIgnore,
BeaconFetchAllSidecars,
......
......@@ -4,6 +4,8 @@ import (
"context"
"errors"
"fmt"
"net/http"
"strings"
"time"
"github.com/ethereum-optimism/optimism/op-node/rollup"
......@@ -177,6 +179,7 @@ func (cfg *PreparedL1Endpoint) Check() error {
type L1BeaconEndpointConfig struct {
BeaconAddr string // Address of L1 User Beacon-API endpoint to use (beacon namespace required)
BeaconHeader string // Optional HTTP header for all requests to L1 Beacon
BeaconArchiverAddr string // Address of L1 User Beacon-API Archive endpoint to use for expired blobs (beacon namespace required)
BeaconCheckIgnore bool // When false, halt startup if the beacon version endpoint fails
BeaconFetchAllSidecars bool // Whether to fetch all blob sidecars and filter locally
......@@ -185,7 +188,16 @@ type L1BeaconEndpointConfig struct {
var _ L1BeaconEndpointSetup = (*L1BeaconEndpointConfig)(nil)
func (cfg *L1BeaconEndpointConfig) Setup(ctx context.Context, log log.Logger) (cl sources.BeaconClient, fb []sources.BlobSideCarsFetcher, err error) {
a := client.NewBasicHTTPClient(cfg.BeaconAddr, log)
var opts []client.BasicHTTPClientOption
if cfg.BeaconHeader != "" {
hdr, err := parseHTTPHeader(cfg.BeaconHeader)
if err != nil {
return nil, nil, fmt.Errorf("parsing beacon header: %w", err)
}
opts = append(opts, client.WithHeader(hdr))
}
a := client.NewBasicHTTPClient(cfg.BeaconAddr, log, opts...)
if cfg.BeaconArchiverAddr != "" {
b := client.NewBasicHTTPClient(cfg.BeaconArchiverAddr, log)
fb = append(fb, sources.NewBeaconHTTPClient(b))
......@@ -207,3 +219,13 @@ func (cfg *L1BeaconEndpointConfig) ShouldIgnoreBeaconCheck() bool {
func (cfg *L1BeaconEndpointConfig) ShouldFetchAllSidecars() bool {
return cfg.BeaconFetchAllSidecars
}
func parseHTTPHeader(headerStr string) (http.Header, error) {
h := make(http.Header, 1)
s := strings.SplitN(headerStr, ": ", 2)
if len(s) != 2 {
return nil, errors.New("invalid header format")
}
h.Add(s[0], s[1])
return h, nil
}
package node
import (
"net/http"
"testing"
"github.com/stretchr/testify/require"
)
func TestParseHTTPHeader(t *testing.T) {
for _, test := range []struct {
desc string
str string
expHdr http.Header
expErr bool
}{
{
desc: "err-empty",
expErr: true,
},
{
desc: "err-no-colon",
str: "Key",
expErr: true,
},
{
desc: "err-only-key",
str: "Key:",
expErr: true,
},
{
desc: "err-no-space",
str: "Key:value",
expErr: true,
},
{
desc: "valid",
str: "Key: value",
expHdr: http.Header{"Key": []string{"value"}},
},
{
desc: "valid-small",
str: "key: value",
expHdr: http.Header{"Key": []string{"value"}},
},
{
desc: "valid-spaces-colons",
str: "X-Key: a long value with spaces: and: colons",
expHdr: http.Header{"X-Key": []string{"a long value with spaces: and: colons"}},
},
} {
t.Run(test.desc, func(t *testing.T) {
h, err := parseHTTPHeader(test.str)
if test.expErr {
require.Error(t, err)
} else {
require.NoError(t, err)
require.Equal(t, test.expHdr, h)
}
})
}
}
......@@ -130,6 +130,7 @@ func NewConfig(ctx *cli.Context, log log.Logger) (*node.Config, error) {
func NewBeaconEndpointConfig(ctx *cli.Context) node.L1BeaconEndpointSetup {
return &node.L1BeaconEndpointConfig{
BeaconAddr: ctx.String(flags.BeaconAddr.Name),
BeaconHeader: ctx.String(flags.BeaconHeader.Name),
BeaconArchiverAddr: ctx.String(flags.BeaconArchiverAddr.Name),
BeaconCheckIgnore: ctx.Bool(flags.BeaconCheckIgnore.Name),
BeaconFetchAllSidecars: ctx.Bool(flags.BeaconFetchAllSidecars.Name),
......
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