Skip to content
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
ebdcde6
add beacon node headers cli flag to run and exit command
DiogoSantoss Jan 9, 2025
c9ada9a
remove unused parameter
DiogoSantoss Jan 9, 2025
ae0119b
lint
DiogoSantoss Jan 9, 2025
fa2c09b
add condition to only perform verification when headers are present
DiogoSantoss Jan 9, 2025
e7cefd3
extract validation and parsing logic to helper function
DiogoSantoss Jan 9, 2025
b5f2a58
add tests for validation and parsing of beacon node headers
DiogoSantoss Jan 9, 2025
1d51014
add comment to exported functions
DiogoSantoss Jan 10, 2025
41592b7
change BeaconNodeHeaders from string to slice for improved handling
DiogoSantoss Jan 14, 2025
7feef7a
build: allow golangci-lint parallel on .pre-commit (#3455)
KaloyanTanev Jan 13, 2025
1ca4d41
fix: chown -R runner:docker 001 folder (#3441)
apham0001 Jan 13, 2025
a58b735
docs: contributing discord channel (#3452)
KaloyanTanev Jan 14, 2025
01082ab
build(deps): Bump github.com/showwin/speedtest-go from 1.7.9 to 1.7.1…
dependabot[bot] Jan 14, 2025
bb28e3d
build(deps): Bump golang.org/x/time from 0.8.0 to 0.9.0 (#3446)
dependabot[bot] Jan 14, 2025
a0a0c8a
build(deps): Bump sigp/lighthouse from v6.0.0 to v6.0.1 in /testutil/…
dependabot[bot] Jan 14, 2025
340a897
build(deps): Bump chainsafe/lodestar from v1.23.1 to v1.24.0 in /test…
dependabot[bot] Jan 14, 2025
72523aa
build(deps): Bump github.com/attestantio/go-builder-client from 0.5.2…
dependabot[bot] Jan 14, 2025
2cbc8d2
core/consensus: add new consensus round timer (#3440)
DiogoSantoss Jan 14, 2025
8e51320
build(deps): Bump github.com/bufbuild/buf from 1.35.1 to 1.49.0 (#3447)
dependabot[bot] Jan 14, 2025
f095412
*: trigger dispatch for LCDVN and Launchpad (#3438)
apham0001 Jan 15, 2025
fd67c15
fix formatting
DiogoSantoss Jan 15, 2025
cec4ba4
fix protoc-gen-go version
DiogoSantoss Jan 15, 2025
1c3c49c
update configuration
DiogoSantoss Jan 16, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 21 additions & 4 deletions app/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
"encoding/hex"
"encoding/json"
"net/http"
"regexp"
"strings"
"sync"
"time"
Expand Down Expand Up @@ -95,6 +96,7 @@
ProcDirectory string
ConsensusProtocol string
Nickname string
BeaconNodeHeaders string

TestConfig TestConfig
}
Expand Down Expand Up @@ -909,12 +911,27 @@
log.Info(ctx, "Synthetic block proposals enabled")
}

eth2Cl, err := configureEth2Client(ctx, forkVersion, conf.BeaconNodeAddrs, bnTimeout, conf.SyntheticBlockProposals)
beaconNodeHeaders := make(map[string]string)
if len(conf.BeaconNodeHeaders) > 0 {
// Headers must be comma separated values of format <key>=<value>.
// The pattern ([^=,]+) matches any string without '=' and ','.
// Hence we are looking for a pair of <pattern>=<pattern> with optionally more pairs
if !regexp.MustCompile(`^([^=,]+)=([^=,]+)(,([^=,]+)=([^=,]+))*$`).MatchString(conf.BeaconNodeHeaders) {
return nil, nil, errors.New("beacon node headers must be comma separated values formatted as header=value")
}

Check warning on line 921 in app/app.go

View check run for this annotation

Codecov / codecov/patch

app/app.go#L914-L921

Added lines #L914 - L921 were not covered by tests

pairs := regexp.MustCompile(`([^=,]+)=([^=,]+)`).FindAllStringSubmatch(conf.BeaconNodeHeaders, -1)
for _, pair := range pairs {
beaconNodeHeaders[pair[1]] = pair[2]
}

Check warning on line 926 in app/app.go

View check run for this annotation

Codecov / codecov/patch

app/app.go#L923-L926

Added lines #L923 - L926 were not covered by tests
}

eth2Cl, err := configureEth2Client(ctx, forkVersion, conf.BeaconNodeAddrs, beaconNodeHeaders, bnTimeout, conf.SyntheticBlockProposals)

Check warning on line 929 in app/app.go

View check run for this annotation

Codecov / codecov/patch

app/app.go#L929

Added line #L929 was not covered by tests
if err != nil {
return nil, nil, errors.Wrap(err, "new eth2 http client")
}

submissionEth2Cl, err := configureEth2Client(ctx, forkVersion, conf.BeaconNodeAddrs, submissionBnTimeout, conf.SyntheticBlockProposals)
submissionEth2Cl, err := configureEth2Client(ctx, forkVersion, conf.BeaconNodeAddrs, beaconNodeHeaders, submissionBnTimeout, conf.SyntheticBlockProposals)

Check warning on line 934 in app/app.go

View check run for this annotation

Codecov / codecov/patch

app/app.go#L934

Added line #L934 was not covered by tests
if err != nil {
return nil, nil, errors.Wrap(err, "new submission eth2 http client")
}
Expand All @@ -923,8 +940,8 @@
}

// configureEth2Client configures a beacon node client with the provided settings.
func configureEth2Client(ctx context.Context, forkVersion []byte, addrs []string, timeout time.Duration, syntheticBlockProposals bool) (eth2wrap.Client, error) {
eth2Cl, err := eth2wrap.NewMultiHTTP(timeout, [4]byte(forkVersion), addrs...)
func configureEth2Client(ctx context.Context, forkVersion []byte, addrs []string, headers map[string]string, timeout time.Duration, syntheticBlockProposals bool) (eth2wrap.Client, error) {
eth2Cl, err := eth2wrap.NewMultiHTTP(timeout, [4]byte(forkVersion), headers, addrs...)

Check warning on line 944 in app/app.go

View check run for this annotation

Codecov / codecov/patch

app/app.go#L943-L944

Added lines #L943 - L944 were not covered by tests
if err != nil {
return nil, errors.Wrap(err, "new eth2 http client")
}
Expand Down
11 changes: 6 additions & 5 deletions app/eth2wrap/eth2wrap.go
Original file line number Diff line number Diff line change
Expand Up @@ -85,28 +85,29 @@ func WithSyntheticDuties(cl Client) Client {
}

// NewMultiHTTP returns a new instrumented multi eth2 http client.
func NewMultiHTTP(timeout time.Duration, forkVersion [4]byte, addresses ...string) (Client, error) {
return Instrument(newClients(timeout, forkVersion, addresses)...)
func NewMultiHTTP(timeout time.Duration, forkVersion [4]byte, headers map[string]string, addresses ...string) (Client, error) {
return Instrument(newClients(timeout, forkVersion, headers, addresses)...)
}

// newClients returns a slice of Client initialized with the provided settings.
func newClients(timeout time.Duration, forkVersion [4]byte, addresses []string) []Client {
func newClients(timeout time.Duration, forkVersion [4]byte, headers map[string]string, addresses []string) []Client {
var clients []Client
for _, address := range addresses {
clients = append(clients, newBeaconClient(timeout, forkVersion, address))
clients = append(clients, newBeaconClient(timeout, forkVersion, headers, address))
}

return clients
}

// newBeaconClient returns a Client with the provided settings.
func newBeaconClient(timeout time.Duration, forkVersion [4]byte, address string) Client {
func newBeaconClient(timeout time.Duration, forkVersion [4]byte, headers map[string]string, address string) Client {
parameters := []eth2http.Parameter{
eth2http.WithLogLevel(zeroLogInfo),
eth2http.WithAddress(address),
eth2http.WithTimeout(timeout),
eth2http.WithAllowDelayedStart(true),
eth2http.WithEnforceJSON(featureset.Enabled(featureset.JSONRequests)),
eth2http.WithExtraHeaders(headers),
}

cl := newLazy(func(ctx context.Context) (Client, error) {
Expand Down
18 changes: 9 additions & 9 deletions app/eth2wrap/eth2wrap_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,7 @@ func TestErrors(t *testing.T) {
ctx := context.Background()

t.Run("network dial error", func(t *testing.T) {
cl, err := eth2wrap.NewMultiHTTP(time.Hour, [4]byte{}, "localhost:22222")
cl, err := eth2wrap.NewMultiHTTP(time.Hour, [4]byte{}, map[string]string{}, "localhost:22222")
require.NoError(t, err)

_, err = cl.SlotsPerEpoch(ctx)
Expand All @@ -186,7 +186,7 @@ func TestErrors(t *testing.T) {
}))

t.Run("http timeout", func(t *testing.T) {
cl, err := eth2wrap.NewMultiHTTP(time.Millisecond, [4]byte{}, srv.URL)
cl, err := eth2wrap.NewMultiHTTP(time.Millisecond, [4]byte{}, map[string]string{}, srv.URL)
require.NoError(t, err)

_, err = cl.SlotsPerEpoch(ctx)
Expand All @@ -199,7 +199,7 @@ func TestErrors(t *testing.T) {
ctx, cancel := context.WithCancel(ctx)
cancel()

cl, err := eth2wrap.NewMultiHTTP(time.Millisecond, [4]byte{}, srv.URL)
cl, err := eth2wrap.NewMultiHTTP(time.Millisecond, [4]byte{}, map[string]string{}, srv.URL)
require.NoError(t, err)

_, err = cl.SlotsPerEpoch(ctx)
Expand Down Expand Up @@ -251,7 +251,7 @@ func TestCtxCancel(t *testing.T) {

bmock, err := beaconmock.New()
require.NoError(t, err)
eth2Cl, err := eth2wrap.NewMultiHTTP(time.Second, [4]byte{}, bmock.Address())
eth2Cl, err := eth2wrap.NewMultiHTTP(time.Second, [4]byte{}, map[string]string{}, bmock.Address())
require.NoError(t, err)

cancel() // Cancel context before calling method.
Expand Down Expand Up @@ -310,7 +310,7 @@ func TestOneError(t *testing.T) {
bmock.Address(), // Valid
}

eth2Cl, err := eth2wrap.NewMultiHTTP(time.Second, [4]byte{}, addresses...)
eth2Cl, err := eth2wrap.NewMultiHTTP(time.Second, [4]byte{}, map[string]string{}, addresses...)
require.NoError(t, err)

eth2Resp, err := eth2Cl.Spec(ctx, &eth2api.SpecOpts{})
Expand Down Expand Up @@ -341,7 +341,7 @@ func TestOneTimeout(t *testing.T) {
bmock.Address(), // Valid
}

eth2Cl, err := eth2wrap.NewMultiHTTP(time.Minute, [4]byte{}, addresses...)
eth2Cl, err := eth2wrap.NewMultiHTTP(time.Minute, [4]byte{}, map[string]string{}, addresses...)
require.NoError(t, err)

eth2Resp, err := eth2Cl.Spec(ctx, &eth2api.SpecOpts{})
Expand All @@ -364,7 +364,7 @@ func TestOnlyTimeout(t *testing.T) {
defer srv.Close()
defer cancel() // Cancel the context before stopping the server.

eth2Cl, err := eth2wrap.NewMultiHTTP(time.Minute, [4]byte{}, srv.URL)
eth2Cl, err := eth2wrap.NewMultiHTTP(time.Minute, [4]byte{}, map[string]string{}, srv.URL)
require.NoError(t, err)

// Start goroutine that is blocking trying to create the client.
Expand Down Expand Up @@ -426,7 +426,7 @@ func TestLazy(t *testing.T) {
httputil.NewSingleHostReverseProxy(target).ServeHTTP(w, r)
}))

eth2Cl, err := eth2wrap.NewMultiHTTP(time.Second, [4]byte{}, srv1.URL, srv2.URL)
eth2Cl, err := eth2wrap.NewMultiHTTP(time.Second, [4]byte{}, map[string]string{}, srv1.URL, srv2.URL)
require.NoError(t, err)

// Both proxies are disabled, so this should fail.
Expand Down Expand Up @@ -505,7 +505,7 @@ func TestLazyDomain(t *testing.T) {

forkVersionHex, err := hex.DecodeString(test.in)
require.NoError(t, err)
eth2Cl, err := eth2wrap.NewMultiHTTP(time.Second, [4]byte(forkVersionHex), srv.URL)
eth2Cl, err := eth2wrap.NewMultiHTTP(time.Second, [4]byte(forkVersionHex), map[string]string{}, srv.URL)
require.NoError(t, err)

voluntaryExitDomain := eth2p0.DomainType{0x04, 0x00, 0x00, 0x00}
Expand Down
2 changes: 1 addition & 1 deletion app/eth2wrap/fallback.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ type FallbackClient struct {
// NewFallbackClient initializes a FallbackClient with the provided settings
func NewFallbackClient(timeout time.Duration, forkVersion [4]byte, addresses []string) *FallbackClient {
return &FallbackClient{
clients: newClients(timeout, forkVersion, addresses),
clients: newClients(timeout, forkVersion, map[string]string{}, addresses),
}
}

Expand Down
2 changes: 1 addition & 1 deletion app/peerinfo/peerinfo.go
Original file line number Diff line number Diff line change
Expand Up @@ -202,7 +202,7 @@ func (p *PeerInfo) sendOnce(ctx context.Context, now time.Time) {

name := p2p.PeerName(peerID)

p.nicknames[name] = resp.Nickname
p.nicknames[name] = resp.GetNickname()
log.Info(ctx, "Peer name to nickname mappings", z.Any("nicknames", p.nicknames))

// Validator git hash with regex.
Expand Down
10 changes: 8 additions & 2 deletions cmd/exit.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
Log log.Config
All bool
testnetConfig eth2util.Network
BeaconNodeHeaders string
}

func newExitCmd(cmds ...*cobra.Command) *cobra.Command {
Expand Down Expand Up @@ -74,6 +75,7 @@
testnetChainID
testnetGenesisTimestamp
testnetCapellaHardFork
beaconNodeHeaders
)

func (ef exitFlag) String() string {
Expand Down Expand Up @@ -116,6 +118,8 @@
return "testnet-genesis-timestamp"
case testnetCapellaHardFork:
return "testnet-capella-hard-fork"
case beaconNodeHeaders:
return "beacon-node-headers"

Check warning on line 122 in cmd/exit.go

View check run for this annotation

Codecov / codecov/patch

cmd/exit.go#L121-L122

Added lines #L121 - L122 were not covered by tests
default:
return "unknown"
}
Expand Down Expand Up @@ -177,6 +181,8 @@
cmd.Flags().Int64Var(&config.testnetConfig.GenesisTimestamp, "testnet-genesis-timestamp", 0, "Genesis timestamp of the custom test network.")
case testnetCapellaHardFork:
cmd.Flags().StringVar(&config.testnetConfig.CapellaHardFork, "testnet-capella-hard-fork", "", "Capella hard fork version of the custom test network.")
case beaconNodeHeaders:
cmd.Flags().StringVar(&config.BeaconNodeHeaders, "beacon-node-headers", "", "Comma separated list of headers formatted as header=value")
}

if f.required {
Expand All @@ -185,8 +191,8 @@
}
}

func eth2Client(ctx context.Context, u []string, timeout time.Duration, forkVersion [4]byte) (eth2wrap.Client, error) {
cl, err := eth2wrap.NewMultiHTTP(timeout, forkVersion, u...)
func eth2Client(ctx context.Context, headers map[string]string, u []string, timeout time.Duration, forkVersion [4]byte) (eth2wrap.Client, error) {
cl, err := eth2wrap.NewMultiHTTP(timeout, forkVersion, headers, u...)
if err != nil {
return nil, err
}
Expand Down
23 changes: 22 additions & 1 deletion cmd/exit_broadcast.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
"fmt"
"os"
"path/filepath"
"regexp"
"strings"
"time"

Expand Down Expand Up @@ -69,6 +70,7 @@
{testnetChainID, false},
{testnetGenesisTimestamp, false},
{testnetCapellaHardFork, false},
{beaconNodeHeaders, false},
})

bindLogFlags(cmd.Flags(), &config.Log)
Expand Down Expand Up @@ -98,6 +100,10 @@
return errors.New(fmt.Sprintf("if you want to specify exit file directory for all validators, you must provide %s and not %s.", exitFromDir.String(), exitFromFile.String()))
}

if len(config.BeaconNodeHeaders) > 0 && !regexp.MustCompile(`^([^=,]+)=([^=,]+)(,([^=,]+)=([^=,]+))*$`).MatchString(config.BeaconNodeHeaders) {
return errors.New("beacon node headers must be comma separated values formatted as <header>=<value>")
}

Check warning on line 105 in cmd/exit_broadcast.go

View check run for this annotation

Codecov / codecov/patch

cmd/exit_broadcast.go#L104-L105

Added lines #L104 - L105 were not covered by tests

return nil
})

Expand All @@ -121,7 +127,22 @@
return errors.Wrap(err, "load cluster lock", z.Str("lock_file_path", config.LockFilePath))
}

eth2Cl, err := eth2Client(ctx, config.BeaconNodeEndpoints, config.BeaconNodeTimeout, [4]byte(cl.GetForkVersion()))
beaconNodeHeaders := make(map[string]string)
if len(config.BeaconNodeHeaders) > 0 {
// Headers must be comma separated values of format <key>=<value>.
// The pattern ([^=,]+) matches any string without '=' and ','.
// Hence we are looking for a pair of <pattern>=<pattern> with optionally more pairs
if !regexp.MustCompile(`^([^=,]+)=([^=,]+)(,([^=,]+)=([^=,]+))*$`).MatchString(config.BeaconNodeHeaders) {
return errors.New("beacon node headers must be comma separated values formatted as header=value")
}

Check warning on line 137 in cmd/exit_broadcast.go

View check run for this annotation

Codecov / codecov/patch

cmd/exit_broadcast.go#L132-L137

Added lines #L132 - L137 were not covered by tests

pairs := regexp.MustCompile(`([^=,]+)=([^=,]+)`).FindAllStringSubmatch(config.BeaconNodeHeaders, -1)
for _, pair := range pairs {
beaconNodeHeaders[pair[1]] = pair[2]
}

Check warning on line 142 in cmd/exit_broadcast.go

View check run for this annotation

Codecov / codecov/patch

cmd/exit_broadcast.go#L139-L142

Added lines #L139 - L142 were not covered by tests
}

eth2Cl, err := eth2Client(ctx, beaconNodeHeaders, config.BeaconNodeEndpoints, config.BeaconNodeTimeout, [4]byte(cl.GetForkVersion()))
if err != nil {
return errors.Wrap(err, "create eth2 client for specified beacon node(s)", z.Any("beacon_nodes_endpoints", config.BeaconNodeEndpoints))
}
Expand Down
2 changes: 1 addition & 1 deletion cmd/exit_broadcast_internal_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ func testRunBcastFullExitCmdFlow(t *testing.T, fromFile bool, all bool) {
require.NoError(t, beaconMock.Close())
}()

eth2Cl, err := eth2Client(ctx, []string{beaconMock.Address()}, 10*time.Second, [4]byte(lock.ForkVersion))
eth2Cl, err := eth2Client(ctx, map[string]string{}, []string{beaconMock.Address()}, 10*time.Second, [4]byte(lock.ForkVersion))
require.NoError(t, err)

handler, addLockFiles := obolapimock.MockServer(false, eth2Cl)
Expand Down
2 changes: 1 addition & 1 deletion cmd/exit_fetch_internal_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ func testRunFetchExitFullFlow(t *testing.T, all bool) {
require.NoError(t, beaconMock.Close())
}()

eth2Cl, err := eth2Client(ctx, []string{beaconMock.Address()}, 10*time.Second, [4]byte(lock.ForkVersion))
eth2Cl, err := eth2Client(ctx, map[string]string{}, []string{beaconMock.Address()}, 10*time.Second, [4]byte(lock.ForkVersion))
require.NoError(t, err)

handler, addLockFiles := obolapimock.MockServer(false, eth2Cl)
Expand Down
27 changes: 26 additions & 1 deletion cmd/exit_list.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import (
"context"
"fmt"
"regexp"

eth2api "github.com/attestantio/go-eth2-client/api"
eth2v1 "github.com/attestantio/go-eth2-client/api/v1"
Expand Down Expand Up @@ -49,10 +50,19 @@
{testnetChainID, false},
{testnetGenesisTimestamp, false},
{testnetCapellaHardFork, false},
{beaconNodeHeaders, false},
})

bindLogFlags(cmd.Flags(), &config.Log)

wrapPreRunE(cmd, func(*cobra.Command, []string) error {
if len(config.BeaconNodeHeaders) > 0 && !regexp.MustCompile(`^([^=,]+)=([^=,]+)(,([^=,]+)=([^=,]+))*$`).MatchString(config.BeaconNodeHeaders) {
return errors.New("beacon node headers must be comma separated values formatted as <header>=<value>")
}

Check warning on line 61 in cmd/exit_list.go

View check run for this annotation

Codecov / codecov/patch

cmd/exit_list.go#L60-L61

Added lines #L60 - L61 were not covered by tests

return nil
})

return cmd
}

Expand Down Expand Up @@ -87,7 +97,22 @@
return nil, errors.Wrap(err, "load cluster lock", z.Str("lock_file_path", config.LockFilePath))
}

eth2Cl, err := eth2Client(ctx, config.BeaconNodeEndpoints, config.BeaconNodeTimeout, [4]byte{}) // fine to avoid initializing a fork version, we're just querying the BN
beaconNodeHeaders := make(map[string]string)
if len(config.BeaconNodeHeaders) > 0 {
// Headers must be comma separated values of format <key>=<value>.
// The pattern ([^=,]+) matches any string without '=' and ','.
// Hence we are looking for a pair of <pattern>=<pattern> with optionally more pairs
if !regexp.MustCompile(`^([^=,]+)=([^=,]+)(,([^=,]+)=([^=,]+))*$`).MatchString(config.BeaconNodeHeaders) {
return nil, errors.New("beacon node headers must be comma separated values formatted as header=value")
}

Check warning on line 107 in cmd/exit_list.go

View check run for this annotation

Codecov / codecov/patch

cmd/exit_list.go#L102-L107

Added lines #L102 - L107 were not covered by tests

pairs := regexp.MustCompile(`([^=,]+)=([^=,]+)`).FindAllStringSubmatch(config.BeaconNodeHeaders, -1)
for _, pair := range pairs {
beaconNodeHeaders[pair[1]] = pair[2]
}

Check warning on line 112 in cmd/exit_list.go

View check run for this annotation

Codecov / codecov/patch

cmd/exit_list.go#L109-L112

Added lines #L109 - L112 were not covered by tests
}

eth2Cl, err := eth2Client(ctx, beaconNodeHeaders, config.BeaconNodeEndpoints, config.BeaconNodeTimeout, [4]byte{}) // fine to avoid initializing a fork version, we're just querying the BN
if err != nil {
return nil, errors.Wrap(err, "create eth2 client for specified beacon node(s)", z.Any("beacon_nodes_endpoints", config.BeaconNodeEndpoints))
}
Expand Down
Loading
Loading