Compare commits

..

1 Commits

Author SHA1 Message Date
james-prysm
cde4f3b009 wip 2026-01-30 16:58:23 -06:00
129 changed files with 1385 additions and 2929 deletions

View File

@@ -2,7 +2,7 @@ name: Go
on:
push:
branches: [ master, develop ]
branches: [ master ]
pull_request:
branches: [ '*' ]
merge_group:

View File

@@ -33,8 +33,9 @@ formatters:
generated: lax
paths:
- validator/web/site_data.go
- .*_test.go
- proto
- tools/analyzers
- third_party$
- builtin$
- examples$
- examples$

View File

@@ -34,6 +34,18 @@ type Event struct {
Data []byte
}
// PublishEvent enqueues an event without blocking the producer. If the channel is full,
// the event is dropped since only the most recent heads are relevant.
func PublishEvent(eventsChannel chan<- *Event, event *Event) {
if eventsChannel == nil || event == nil {
return
}
select {
case eventsChannel <- event:
default:
}
}
// EventStream is responsible for subscribing to the Beacon API events endpoint
// and dispatching received events to subscribers.
type EventStream struct {
@@ -67,19 +79,20 @@ func (h *EventStream) Subscribe(eventsChannel chan<- *Event) {
fullUrl := h.host + "/eth/v1/events?topics=" + allTopics
req, err := http.NewRequestWithContext(h.ctx, http.MethodGet, fullUrl, nil)
if err != nil {
eventsChannel <- &Event{
PublishEvent(eventsChannel, &Event{
EventType: EventConnectionError,
Data: []byte(errors.Wrap(err, "failed to create HTTP request").Error()),
}
})
return
}
req.Header.Set("Accept", api.EventStreamMediaType)
req.Header.Set("Connection", api.KeepAlive)
resp, err := h.httpClient.Do(req)
if err != nil {
eventsChannel <- &Event{
PublishEvent(eventsChannel, &Event{
EventType: EventConnectionError,
Data: []byte(errors.Wrap(err, client.ErrConnectionIssue.Error()).Error()),
}
})
return
}
@@ -100,7 +113,6 @@ func (h *EventStream) Subscribe(eventsChannel chan<- *Event) {
select {
case <-h.ctx.Done():
log.Info("Context canceled, stopping event stream")
close(eventsChannel)
return
default:
line := scanner.Text()
@@ -109,7 +121,7 @@ func (h *EventStream) Subscribe(eventsChannel chan<- *Event) {
// Empty line indicates the end of an event
if eventType != "" && data != "" {
// Process the event when both eventType and data are set
eventsChannel <- &Event{EventType: eventType, Data: []byte(data)}
PublishEvent(eventsChannel, &Event{EventType: eventType, Data: []byte(data)})
}
// Reset eventType and data for the next event
@@ -130,9 +142,9 @@ func (h *EventStream) Subscribe(eventsChannel chan<- *Event) {
}
if err := scanner.Err(); err != nil {
eventsChannel <- &Event{
PublishEvent(eventsChannel, &Event{
EventType: EventConnectionError,
Data: []byte(errors.Wrap(err, errors.Wrap(client.ErrConnectionIssue, "scanner failed").Error()).Error()),
}
})
}
}

View File

@@ -53,7 +53,7 @@ func TestEventStream(t *testing.T) {
defer server.Close()
topics := []string{"head"}
eventsChannel := make(chan *Event, 1)
eventsChannel := make(chan *Event, 4)
stream, err := NewEventStream(t.Context(), http.DefaultClient, server.URL, topics)
require.NoError(t, err)
go stream.Subscribe(eventsChannel)
@@ -80,7 +80,7 @@ func TestEventStream(t *testing.T) {
func TestEventStreamRequestError(t *testing.T) {
topics := []string{"head"}
eventsChannel := make(chan *Event, 1)
eventsChannel := make(chan *Event, 4)
ctx := t.Context()
// use valid url that will result in failed request with nil body

View File

@@ -1,19 +0,0 @@
load("@prysm//tools/go:def.bzl", "go_library", "go_test")
go_library(
name = "go_default_library",
srcs = [
"failover.go",
"log.go",
],
importpath = "github.com/OffchainLabs/prysm/v7/api/failover",
visibility = ["//visibility:public"],
deps = ["@com_github_sirupsen_logrus//:go_default_library"],
)
go_test(
name = "go_default_test",
srcs = ["failover_test.go"],
embed = [":go_default_library"],
deps = ["//testing/assert:go_default_library"],
)

View File

@@ -1,75 +0,0 @@
package failover
import (
"context"
"github.com/sirupsen/logrus"
)
// HostProvider is the subset of connection-provider methods that EnsureReady
// needs. Both grpc.GrpcConnectionProvider and rest.RestConnectionProvider
// satisfy this interface.
type HostProvider interface {
Hosts() []string
CurrentHost() string
SwitchHost(index int) error
}
// ReadyChecker can report whether the current endpoint is ready.
// iface.NodeClient satisfies this implicitly.
type ReadyChecker interface {
IsReady(ctx context.Context) bool
}
// EnsureReady iterates through the configured hosts and returns true as soon as
// one responds as ready. It starts from the provider's current host and wraps
// around using modular arithmetic, performing failover when a host is not ready.
func EnsureReady(ctx context.Context, provider HostProvider, checker ReadyChecker) bool {
hosts := provider.Hosts()
numHosts := len(hosts)
startingHost := provider.CurrentHost()
var attemptedHosts []string
// Find current index
currentIdx := 0
for i, h := range hosts {
if h == startingHost {
currentIdx = i
break
}
}
for i := range numHosts {
if checker.IsReady(ctx) {
if len(attemptedHosts) > 0 {
log.WithFields(logrus.Fields{
"previousHost": startingHost,
"newHost": provider.CurrentHost(),
"failedAttempts": attemptedHosts,
}).Info("Failover succeeded: connected to healthy beacon node")
}
return true
}
log.WithField("host", provider.CurrentHost()).Debug("Beacon node not fully synced")
attemptedHosts = append(attemptedHosts, provider.CurrentHost())
// Try next host if not the last iteration
if i < numHosts-1 {
nextIdx := (currentIdx + i + 1) % numHosts
log.WithFields(logrus.Fields{
"currentHost": hosts[currentIdx],
"nextHost": hosts[nextIdx],
}).Warn("Beacon node is not responding, switching host")
if err := provider.SwitchHost(nextIdx); err != nil {
log.WithError(err).Error("Failed to switch host")
}
}
}
if numHosts == 1 {
log.WithField("host", provider.CurrentHost()).Warn("Beacon node is not fully synced, no backup node configured")
} else {
log.Warn("No fully synced beacon node found")
}
return false
}

View File

@@ -1,94 +0,0 @@
package failover
import (
"context"
"testing"
"github.com/OffchainLabs/prysm/v7/testing/assert"
)
// mockHostProvider is a minimal HostProvider for unit tests.
type mockHostProvider struct {
hosts []string
hostIndex int
}
func (m *mockHostProvider) Hosts() []string { return m.hosts }
func (m *mockHostProvider) CurrentHost() string {
return m.hosts[m.hostIndex%len(m.hosts)]
}
func (m *mockHostProvider) SwitchHost(index int) error { m.hostIndex = index; return nil }
// mockReadyChecker records per-call IsReady results in sequence.
type mockReadyChecker struct {
results []bool
idx int
}
func (m *mockReadyChecker) IsReady(_ context.Context) bool {
if m.idx >= len(m.results) {
return false
}
r := m.results[m.idx]
m.idx++
return r
}
func TestEnsureReady_SingleHostReady(t *testing.T) {
provider := &mockHostProvider{hosts: []string{"http://host1:3500"}, hostIndex: 0}
checker := &mockReadyChecker{results: []bool{true}}
assert.Equal(t, true, EnsureReady(t.Context(), provider, checker))
assert.Equal(t, 0, provider.hostIndex)
}
func TestEnsureReady_SingleHostNotReady(t *testing.T) {
provider := &mockHostProvider{hosts: []string{"http://host1:3500"}, hostIndex: 0}
checker := &mockReadyChecker{results: []bool{false}}
assert.Equal(t, false, EnsureReady(t.Context(), provider, checker))
}
func TestEnsureReady_SingleHostError(t *testing.T) {
provider := &mockHostProvider{hosts: []string{"http://host1:3500"}, hostIndex: 0}
checker := &mockReadyChecker{results: []bool{false}}
assert.Equal(t, false, EnsureReady(t.Context(), provider, checker))
}
func TestEnsureReady_MultipleHostsFirstReady(t *testing.T) {
provider := &mockHostProvider{
hosts: []string{"http://host1:3500", "http://host2:3500"},
hostIndex: 0,
}
checker := &mockReadyChecker{results: []bool{true}}
assert.Equal(t, true, EnsureReady(t.Context(), provider, checker))
assert.Equal(t, 0, provider.hostIndex)
}
func TestEnsureReady_MultipleHostsFailoverToSecond(t *testing.T) {
provider := &mockHostProvider{
hosts: []string{"http://host1:3500", "http://host2:3500"},
hostIndex: 0,
}
checker := &mockReadyChecker{results: []bool{false, true}}
assert.Equal(t, true, EnsureReady(t.Context(), provider, checker))
assert.Equal(t, 1, provider.hostIndex)
}
func TestEnsureReady_MultipleHostsNoneReady(t *testing.T) {
provider := &mockHostProvider{
hosts: []string{"http://host1:3500", "http://host2:3500", "http://host3:3500"},
hostIndex: 0,
}
checker := &mockReadyChecker{results: []bool{false, false, false}}
assert.Equal(t, false, EnsureReady(t.Context(), provider, checker))
}
func TestEnsureReady_WrapAroundFromNonZeroIndex(t *testing.T) {
provider := &mockHostProvider{
hosts: []string{"http://host0:3500", "http://host1:3500", "http://host2:3500"},
hostIndex: 1,
}
// host1 (start) fails, host2 fails, host0 succeeds
checker := &mockReadyChecker{results: []bool{false, false, true}}
assert.Equal(t, true, EnsureReady(t.Context(), provider, checker))
assert.Equal(t, 0, provider.hostIndex)
}

View File

@@ -1,9 +0,0 @@
// Code generated by hack/gen-logs.sh; DO NOT EDIT.
// This file is created and regenerated automatically. Anything added here might get removed.
package failover
import "github.com/sirupsen/logrus"
// The prefix for logs from this package will be the text after the last slash in the package path.
// If you wish to change this, you should add your desired name in the runtime/logging/logrus-prefixed-formatter/prefix-replacement.go file.
var log = logrus.WithField("package", "api/failover")

View File

@@ -3,16 +3,13 @@ load("@prysm//tools/go:def.bzl", "go_library", "go_test")
go_library(
name = "go_default_library",
srcs = [
"grpc_connection_provider.go",
"grpcutils.go",
"log.go",
"mock_grpc_provider.go",
"parameters.go",
],
importpath = "github.com/OffchainLabs/prysm/v7/api/grpc",
visibility = ["//visibility:public"],
deps = [
"@com_github_pkg_errors//:go_default_library",
"@com_github_sirupsen_logrus//:go_default_library",
"@org_golang_google_grpc//:go_default_library",
"@org_golang_google_grpc//metadata:go_default_library",
@@ -21,17 +18,12 @@ go_library(
go_test(
name = "go_default_test",
srcs = [
"grpc_connection_provider_test.go",
"grpcutils_test.go",
],
srcs = ["grpcutils_test.go"],
embed = [":go_default_library"],
deps = [
"//testing/assert:go_default_library",
"//testing/require:go_default_library",
"@com_github_sirupsen_logrus//hooks/test:go_default_library",
"@org_golang_google_grpc//:go_default_library",
"@org_golang_google_grpc//credentials/insecure:go_default_library",
"@org_golang_google_grpc//metadata:go_default_library",
],
)

View File

@@ -1,186 +0,0 @@
package grpc
import (
"context"
"strings"
"sync"
"github.com/pkg/errors"
"github.com/sirupsen/logrus"
"google.golang.org/grpc"
)
// GrpcConnectionProvider manages gRPC connections for failover support.
// It allows switching between different beacon node endpoints when the current one becomes unavailable.
// Only one connection is maintained at a time - when switching hosts, the old connection is closed.
type GrpcConnectionProvider interface {
// CurrentConn returns the currently active gRPC connection.
// The connection is created lazily on first call.
// Returns nil if the provider has been closed.
CurrentConn() *grpc.ClientConn
// CurrentHost returns the address of the currently active endpoint.
CurrentHost() string
// Hosts returns all configured endpoint addresses.
Hosts() []string
// SwitchHost switches to the endpoint at the given index.
// The new connection is created lazily on next CurrentConn() call.
SwitchHost(index int) error
// ConnectionCounter returns a monotonically increasing counter that increments
// each time SwitchHost changes the active endpoint. This allows consumers to
// detect connection changes even when the host string returns to a previous value
// (e.g., host0 → host1 → host0).
ConnectionCounter() uint64
// Close closes the current connection.
Close()
}
type grpcConnectionProvider struct {
// Immutable after construction - no lock needed for reads
endpoints []string
ctx context.Context
dialOpts []grpc.DialOption
// Current connection state (protected by mutex)
currentIndex uint64
conn *grpc.ClientConn
connCounter uint64
mu sync.Mutex
closed bool
}
// NewGrpcConnectionProvider creates a new connection provider that manages gRPC connections.
// The endpoint parameter can be a comma-separated list of addresses (e.g., "host1:4000,host2:4000").
// Only one connection is maintained at a time, created lazily on first use.
func NewGrpcConnectionProvider(
ctx context.Context,
endpoint string,
dialOpts []grpc.DialOption,
) (GrpcConnectionProvider, error) {
endpoints := parseEndpoints(endpoint)
if len(endpoints) == 0 {
return nil, errors.New("no gRPC endpoints provided")
}
log.WithFields(logrus.Fields{
"endpoints": endpoints,
"count": len(endpoints),
}).Info("Initialized gRPC connection provider")
return &grpcConnectionProvider{
endpoints: endpoints,
ctx: ctx,
dialOpts: dialOpts,
}, nil
}
// parseEndpoints splits a comma-separated endpoint string into individual endpoints.
func parseEndpoints(endpoint string) []string {
if endpoint == "" {
return nil
}
endpoints := make([]string, 0, 1)
for p := range strings.SplitSeq(endpoint, ",") {
if p = strings.TrimSpace(p); p != "" {
endpoints = append(endpoints, p)
}
}
return endpoints
}
func (p *grpcConnectionProvider) CurrentConn() *grpc.ClientConn {
p.mu.Lock()
defer p.mu.Unlock()
if p.closed {
return nil
}
// Return existing connection if available
if p.conn != nil {
return p.conn
}
// Create connection lazily
ep := p.endpoints[p.currentIndex]
conn, err := grpc.DialContext(p.ctx, ep, p.dialOpts...)
if err != nil {
log.WithError(err).WithField("endpoint", ep).Error("Failed to create gRPC connection")
return nil
}
p.conn = conn
log.WithField("endpoint", ep).Debug("Created gRPC connection")
return conn
}
func (p *grpcConnectionProvider) CurrentHost() string {
p.mu.Lock()
defer p.mu.Unlock()
return p.endpoints[p.currentIndex]
}
func (p *grpcConnectionProvider) Hosts() []string {
// Return a copy to maintain immutability
hosts := make([]string, len(p.endpoints))
copy(hosts, p.endpoints)
return hosts
}
func (p *grpcConnectionProvider) SwitchHost(index int) error {
if index < 0 || index >= len(p.endpoints) {
return errors.Errorf("invalid host index %d, must be between 0 and %d", index, len(p.endpoints)-1)
}
p.mu.Lock()
defer p.mu.Unlock()
if uint64(index) == p.currentIndex {
return nil // Already on this host
}
oldHost := p.endpoints[p.currentIndex]
oldConn := p.conn
p.conn = nil // Clear immediately - new connection created lazily
p.currentIndex = uint64(index)
p.connCounter++
// Close old connection asynchronously to avoid blocking the caller
if oldConn != nil {
go func() {
if err := oldConn.Close(); err != nil {
log.WithError(err).WithField("endpoint", oldHost).Debug("Failed to close previous connection")
}
}()
}
log.WithFields(logrus.Fields{
"previousHost": oldHost,
"newHost": p.endpoints[index],
}).Debug("Switched gRPC endpoint")
return nil
}
func (p *grpcConnectionProvider) ConnectionCounter() uint64 {
p.mu.Lock()
defer p.mu.Unlock()
return p.connCounter
}
func (p *grpcConnectionProvider) Close() {
p.mu.Lock()
defer p.mu.Unlock()
if p.closed {
return
}
p.closed = true
if p.conn != nil {
if err := p.conn.Close(); err != nil {
log.WithError(err).WithField("endpoint", p.endpoints[p.currentIndex]).Debug("Failed to close gRPC connection")
}
p.conn = nil
}
}

View File

@@ -1,207 +0,0 @@
package grpc
import (
"context"
"net"
"reflect"
"strings"
"testing"
"github.com/OffchainLabs/prysm/v7/testing/assert"
"github.com/OffchainLabs/prysm/v7/testing/require"
"google.golang.org/grpc"
"google.golang.org/grpc/credentials/insecure"
)
func TestParseEndpoints(t *testing.T) {
tests := []struct {
name string
input string
expected []string
}{
{"single endpoint", "localhost:4000", []string{"localhost:4000"}},
{"multiple endpoints", "host1:4000,host2:4000,host3:4000", []string{"host1:4000", "host2:4000", "host3:4000"}},
{"endpoints with spaces", "host1:4000, host2:4000 , host3:4000", []string{"host1:4000", "host2:4000", "host3:4000"}},
{"empty string", "", nil},
{"only commas", ",,,", []string{}},
{"trailing comma", "host1:4000,host2:4000,", []string{"host1:4000", "host2:4000"}},
{"leading comma", ",host1:4000,host2:4000", []string{"host1:4000", "host2:4000"}},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got := parseEndpoints(tt.input)
if !reflect.DeepEqual(tt.expected, got) {
t.Errorf("parseEndpoints(%q) = %v, want %v", tt.input, got, tt.expected)
}
})
}
}
func TestNewGrpcConnectionProvider_Errors(t *testing.T) {
t.Run("no endpoints", func(t *testing.T) {
dialOpts := []grpc.DialOption{grpc.WithTransportCredentials(insecure.NewCredentials())}
_, err := NewGrpcConnectionProvider(context.Background(), "", dialOpts)
require.ErrorContains(t, "no gRPC endpoints provided", err)
})
}
func TestGrpcConnectionProvider_LazyConnection(t *testing.T) {
// Start only one server but configure provider with two endpoints
lis, err := net.Listen("tcp", "127.0.0.1:0")
require.NoError(t, err)
server := grpc.NewServer()
go func() { _ = server.Serve(lis) }()
defer server.Stop()
validAddr := lis.Addr().String()
invalidAddr := "127.0.0.1:1" // Port 1 is unlikely to be listening
// Provider should succeed even though second endpoint is invalid (lazy connections)
endpoint := validAddr + "," + invalidAddr
ctx := context.Background()
dialOpts := []grpc.DialOption{grpc.WithTransportCredentials(insecure.NewCredentials())}
provider, err := NewGrpcConnectionProvider(ctx, endpoint, dialOpts)
require.NoError(t, err, "Provider creation should succeed with lazy connections")
defer func() { provider.Close() }()
// First endpoint should work
conn := provider.CurrentConn()
assert.NotNil(t, conn, "First connection should be created lazily")
}
func TestGrpcConnectionProvider_SingleConnectionModel(t *testing.T) {
// Create provider with 3 endpoints
var addrs []string
var servers []*grpc.Server
for range 3 {
lis, err := net.Listen("tcp", "127.0.0.1:0")
require.NoError(t, err)
server := grpc.NewServer()
go func() { _ = server.Serve(lis) }()
addrs = append(addrs, lis.Addr().String())
servers = append(servers, server)
}
defer func() {
for _, s := range servers {
s.Stop()
}
}()
endpoint := strings.Join(addrs, ",")
ctx := context.Background()
dialOpts := []grpc.DialOption{grpc.WithTransportCredentials(insecure.NewCredentials())}
provider, err := NewGrpcConnectionProvider(ctx, endpoint, dialOpts)
require.NoError(t, err)
defer func() { provider.Close() }()
// Access the internal state to verify single connection behavior
p := provider.(*grpcConnectionProvider)
// Initially no connection
p.mu.Lock()
assert.Equal(t, (*grpc.ClientConn)(nil), p.conn, "Connection should be nil before access")
p.mu.Unlock()
// Access connection - should create one
conn0 := provider.CurrentConn()
assert.NotNil(t, conn0)
p.mu.Lock()
assert.NotNil(t, p.conn, "Connection should be created after CurrentConn()")
firstConn := p.conn
p.mu.Unlock()
// Call CurrentConn again - should return same connection
conn0Again := provider.CurrentConn()
assert.Equal(t, conn0, conn0Again, "Should return same connection")
// Switch to different host - old connection should be closed, new one created lazily
require.NoError(t, provider.SwitchHost(1))
p.mu.Lock()
assert.Equal(t, (*grpc.ClientConn)(nil), p.conn, "Connection should be nil after SwitchHost (lazy)")
p.mu.Unlock()
// Get new connection
conn1 := provider.CurrentConn()
assert.NotNil(t, conn1)
assert.NotEqual(t, firstConn, conn1, "Should be a different connection after switching hosts")
}
// testProvider creates a provider with n test servers and returns cleanup function.
func testProvider(t *testing.T, n int) (GrpcConnectionProvider, []string, func()) {
var addrs []string
var cleanups []func()
for range n {
lis, err := net.Listen("tcp", "127.0.0.1:0")
require.NoError(t, err)
server := grpc.NewServer()
go func() { _ = server.Serve(lis) }()
addrs = append(addrs, lis.Addr().String())
cleanups = append(cleanups, server.Stop)
}
endpoint := strings.Join(addrs, ",")
ctx := context.Background()
dialOpts := []grpc.DialOption{grpc.WithTransportCredentials(insecure.NewCredentials())}
provider, err := NewGrpcConnectionProvider(ctx, endpoint, dialOpts)
require.NoError(t, err)
cleanup := func() {
provider.Close()
for _, c := range cleanups {
c()
}
}
return provider, addrs, cleanup
}
func TestGrpcConnectionProvider(t *testing.T) {
provider, addrs, cleanup := testProvider(t, 3)
defer cleanup()
t.Run("initial state", func(t *testing.T) {
assert.Equal(t, 3, len(provider.Hosts()))
assert.Equal(t, addrs[0], provider.CurrentHost())
assert.NotNil(t, provider.CurrentConn())
})
t.Run("SwitchHost", func(t *testing.T) {
require.NoError(t, provider.SwitchHost(1))
assert.Equal(t, addrs[1], provider.CurrentHost())
assert.NotNil(t, provider.CurrentConn()) // New connection created lazily
require.NoError(t, provider.SwitchHost(0))
assert.Equal(t, addrs[0], provider.CurrentHost())
require.ErrorContains(t, "invalid host index", provider.SwitchHost(-1))
require.ErrorContains(t, "invalid host index", provider.SwitchHost(3))
})
t.Run("SwitchHost circular", func(t *testing.T) {
// Test round-robin style switching using SwitchHost with manual index
indices := []int{1, 2, 0, 1} // Simulate circular switching
for i, idx := range indices {
require.NoError(t, provider.SwitchHost(idx))
assert.Equal(t, addrs[idx], provider.CurrentHost(), "iteration %d", i)
}
})
t.Run("Hosts returns copy", func(t *testing.T) {
hosts := provider.Hosts()
original := hosts[0]
hosts[0] = "modified"
assert.Equal(t, original, provider.Hosts()[0])
})
}
func TestGrpcConnectionProvider_Close(t *testing.T) {
provider, _, cleanup := testProvider(t, 1)
defer cleanup()
assert.NotNil(t, provider.CurrentConn())
provider.Close()
assert.Equal(t, (*grpc.ClientConn)(nil), provider.CurrentConn())
provider.Close() // Double close is safe
}

View File

@@ -1,27 +0,0 @@
package grpc
import "google.golang.org/grpc"
// MockGrpcProvider implements GrpcConnectionProvider for testing.
type MockGrpcProvider struct {
MockConn *grpc.ClientConn
MockHosts []string
CurrentIndex int
ConnCounter uint64
}
func (m *MockGrpcProvider) CurrentConn() *grpc.ClientConn { return m.MockConn }
func (m *MockGrpcProvider) CurrentHost() string {
if len(m.MockHosts) > 0 {
return m.MockHosts[m.CurrentIndex]
}
return ""
}
func (m *MockGrpcProvider) Hosts() []string { return m.MockHosts }
func (m *MockGrpcProvider) SwitchHost(idx int) error {
m.CurrentIndex = idx
m.ConnCounter++
return nil
}
func (m *MockGrpcProvider) ConnectionCounter() uint64 { return m.ConnCounter }
func (m *MockGrpcProvider) Close() {}

View File

@@ -1,34 +0,0 @@
load("@prysm//tools/go:def.bzl", "go_library", "go_test")
go_library(
name = "go_default_library",
srcs = [
"log.go",
"mock_rest_provider.go",
"rest_connection_provider.go",
"rest_handler.go",
],
importpath = "github.com/OffchainLabs/prysm/v7/api/rest",
visibility = ["//visibility:public"],
deps = [
"//api:go_default_library",
"//api/apiutil:go_default_library",
"//api/client:go_default_library",
"//config/params:go_default_library",
"//network/httputil:go_default_library",
"//runtime/version:go_default_library",
"@com_github_pkg_errors//:go_default_library",
"@com_github_sirupsen_logrus//:go_default_library",
"@io_opentelemetry_go_contrib_instrumentation_net_http_otelhttp//:go_default_library",
],
)
go_test(
name = "go_default_test",
srcs = ["rest_connection_provider_test.go"],
embed = [":go_default_library"],
deps = [
"//testing/assert:go_default_library",
"//testing/require:go_default_library",
],
)

View File

@@ -1,9 +0,0 @@
// Code generated by hack/gen-logs.sh; DO NOT EDIT.
// This file is created and regenerated automatically. Anything added here might get removed.
package rest
import "github.com/sirupsen/logrus"
// The prefix for logs from this package will be the text after the last slash in the package path.
// If you wish to change this, you should add your desired name in the runtime/logging/logrus-prefixed-formatter/prefix-replacement.go file.
var log = logrus.WithField("package", "api/rest")

View File

@@ -1,46 +0,0 @@
package rest
import (
"bytes"
"context"
"net/http"
)
// MockRestProvider implements RestConnectionProvider for testing.
type MockRestProvider struct {
MockClient *http.Client
MockHandler Handler
MockHosts []string
HostIndex int
}
func (m *MockRestProvider) HttpClient() *http.Client { return m.MockClient }
func (m *MockRestProvider) Handler() Handler { return m.MockHandler }
func (m *MockRestProvider) CurrentHost() string {
if len(m.MockHosts) > 0 {
return m.MockHosts[m.HostIndex%len(m.MockHosts)]
}
return ""
}
func (m *MockRestProvider) Hosts() []string { return m.MockHosts }
func (m *MockRestProvider) SwitchHost(index int) error { m.HostIndex = index; return nil }
// MockHandler implements Handler for testing.
type MockHandler struct {
MockHost string
}
func (m *MockHandler) Get(_ context.Context, _ string, _ any) error { return nil }
func (m *MockHandler) GetStatusCode(_ context.Context, _ string) (int, error) {
return http.StatusOK, nil
}
func (m *MockHandler) GetSSZ(_ context.Context, _ string) ([]byte, http.Header, error) {
return nil, nil, nil
}
func (m *MockHandler) Post(_ context.Context, _ string, _ map[string]string, _ *bytes.Buffer, _ any) error {
return nil
}
func (m *MockHandler) PostSSZ(_ context.Context, _ string, _ map[string]string, _ *bytes.Buffer) ([]byte, http.Header, error) {
return nil, nil, nil
}
func (m *MockHandler) Host() string { return m.MockHost }

View File

@@ -1,158 +0,0 @@
package rest
import (
"net/http"
"strings"
"sync/atomic"
"time"
"github.com/OffchainLabs/prysm/v7/api/client"
"github.com/pkg/errors"
"github.com/sirupsen/logrus"
"go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp"
)
// RestConnectionProvider manages HTTP client configuration for REST API with failover support.
// It allows switching between different beacon node REST endpoints when the current one becomes unavailable.
type RestConnectionProvider interface {
// HttpClient returns the configured HTTP client with headers, timeout, and optional tracing.
HttpClient() *http.Client
// Handler returns the REST handler for making API requests.
Handler() Handler
// CurrentHost returns the current REST API endpoint URL.
CurrentHost() string
// Hosts returns all configured REST API endpoint URLs.
Hosts() []string
// SwitchHost switches to the endpoint at the given index.
SwitchHost(index int) error
}
// RestConnectionProviderOption is a functional option for configuring the REST connection provider.
type RestConnectionProviderOption func(*restConnectionProvider)
// WithHttpTimeout sets the HTTP client timeout.
func WithHttpTimeout(timeout time.Duration) RestConnectionProviderOption {
return func(p *restConnectionProvider) {
p.timeout = timeout
}
}
// WithHttpHeaders sets custom HTTP headers to include in all requests.
func WithHttpHeaders(headers map[string][]string) RestConnectionProviderOption {
return func(p *restConnectionProvider) {
p.headers = headers
}
}
// WithTracing enables OpenTelemetry tracing for HTTP requests.
func WithTracing() RestConnectionProviderOption {
return func(p *restConnectionProvider) {
p.enableTracing = true
}
}
type restConnectionProvider struct {
endpoints []string
httpClient *http.Client
restHandler *handler
currentIndex atomic.Uint64
timeout time.Duration
headers map[string][]string
enableTracing bool
}
// NewRestConnectionProvider creates a new REST connection provider that manages HTTP client configuration.
// The endpoint parameter can be a comma-separated list of URLs (e.g., "http://host1:3500,http://host2:3500").
func NewRestConnectionProvider(endpoint string, opts ...RestConnectionProviderOption) (RestConnectionProvider, error) {
endpoints := parseEndpoints(endpoint)
if len(endpoints) == 0 {
return nil, errors.New("no REST API endpoints provided")
}
p := &restConnectionProvider{
endpoints: endpoints,
}
for _, opt := range opts {
opt(p)
}
// Build the HTTP transport chain
var transport http.RoundTripper = http.DefaultTransport
// Add custom headers if configured
if len(p.headers) > 0 {
transport = client.NewCustomHeadersTransport(transport, p.headers)
}
// Add tracing if enabled
if p.enableTracing {
transport = otelhttp.NewTransport(transport)
}
p.httpClient = &http.Client{
Timeout: p.timeout,
Transport: transport,
}
// Create the REST handler with the HTTP client and initial host
p.restHandler = newHandler(*p.httpClient, endpoints[0])
log.WithFields(logrus.Fields{
"endpoints": endpoints,
"count": len(endpoints),
}).Info("Initialized REST connection provider")
return p, nil
}
// parseEndpoints splits a comma-separated endpoint string into individual endpoints.
func parseEndpoints(endpoint string) []string {
if endpoint == "" {
return nil
}
endpoints := make([]string, 0, 1)
for p := range strings.SplitSeq(endpoint, ",") {
if p = strings.TrimSpace(p); p != "" {
endpoints = append(endpoints, p)
}
}
return endpoints
}
func (p *restConnectionProvider) HttpClient() *http.Client {
return p.httpClient
}
func (p *restConnectionProvider) Handler() Handler {
return p.restHandler
}
func (p *restConnectionProvider) CurrentHost() string {
return p.endpoints[p.currentIndex.Load()]
}
func (p *restConnectionProvider) Hosts() []string {
// Return a copy to maintain immutability
hosts := make([]string, len(p.endpoints))
copy(hosts, p.endpoints)
return hosts
}
func (p *restConnectionProvider) SwitchHost(index int) error {
if index < 0 || index >= len(p.endpoints) {
return errors.Errorf("invalid host index %d, must be between 0 and %d", index, len(p.endpoints)-1)
}
oldIdx := p.currentIndex.Load()
p.currentIndex.Store(uint64(index))
// Update the rest handler's host
p.restHandler.SwitchHost(p.endpoints[index])
log.WithFields(logrus.Fields{
"previousHost": p.endpoints[oldIdx],
"newHost": p.endpoints[index],
}).Debug("Switched REST endpoint")
return nil
}

View File

@@ -1,80 +0,0 @@
package rest
import (
"reflect"
"testing"
"github.com/OffchainLabs/prysm/v7/testing/assert"
"github.com/OffchainLabs/prysm/v7/testing/require"
)
func TestParseEndpoints(t *testing.T) {
tests := []struct {
name string
input string
expected []string
}{
{"single endpoint", "http://localhost:3500", []string{"http://localhost:3500"}},
{"multiple endpoints", "http://host1:3500,http://host2:3500,http://host3:3500", []string{"http://host1:3500", "http://host2:3500", "http://host3:3500"}},
{"endpoints with spaces", "http://host1:3500, http://host2:3500 , http://host3:3500", []string{"http://host1:3500", "http://host2:3500", "http://host3:3500"}},
{"empty string", "", nil},
{"only commas", ",,,", []string{}},
{"trailing comma", "http://host1:3500,http://host2:3500,", []string{"http://host1:3500", "http://host2:3500"}},
{"leading comma", ",http://host1:3500,http://host2:3500", []string{"http://host1:3500", "http://host2:3500"}},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got := parseEndpoints(tt.input)
if !reflect.DeepEqual(tt.expected, got) {
t.Errorf("parseEndpoints(%q) = %v, want %v", tt.input, got, tt.expected)
}
})
}
}
func TestNewRestConnectionProvider_Errors(t *testing.T) {
t.Run("no endpoints", func(t *testing.T) {
_, err := NewRestConnectionProvider("")
require.ErrorContains(t, "no REST API endpoints provided", err)
})
}
func TestRestConnectionProvider(t *testing.T) {
provider, err := NewRestConnectionProvider("http://host1:3500,http://host2:3500,http://host3:3500")
require.NoError(t, err)
t.Run("initial state", func(t *testing.T) {
assert.Equal(t, 3, len(provider.Hosts()))
assert.Equal(t, "http://host1:3500", provider.CurrentHost())
assert.NotNil(t, provider.HttpClient())
})
t.Run("SwitchHost", func(t *testing.T) {
require.NoError(t, provider.SwitchHost(1))
assert.Equal(t, "http://host2:3500", provider.CurrentHost())
require.NoError(t, provider.SwitchHost(0))
assert.Equal(t, "http://host1:3500", provider.CurrentHost())
require.ErrorContains(t, "invalid host index", provider.SwitchHost(-1))
require.ErrorContains(t, "invalid host index", provider.SwitchHost(3))
})
t.Run("Hosts returns copy", func(t *testing.T) {
hosts := provider.Hosts()
original := hosts[0]
hosts[0] = "modified"
assert.Equal(t, original, provider.Hosts()[0])
})
}
func TestRestConnectionProvider_WithOptions(t *testing.T) {
headers := map[string][]string{"Authorization": {"Bearer token"}}
provider, err := NewRestConnectionProvider(
"http://localhost:3500",
WithHttpHeaders(headers),
WithHttpTimeout(30000000000), // 30 seconds in nanoseconds
WithTracing(),
)
require.NoError(t, err)
assert.NotNil(t, provider.HttpClient())
assert.Equal(t, "http://localhost:3500", provider.CurrentHost())
}

View File

@@ -67,6 +67,7 @@ func getSubscriptionStatusFromDB(t *testing.T, db *Store) bool {
return subscribed
}
func TestUpdateCustodyInfo(t *testing.T) {
ctx := t.Context()

View File

@@ -26,8 +26,8 @@ import (
"github.com/OffchainLabs/prysm/v7/beacon-chain/operations/voluntaryexits/mock"
p2pMock "github.com/OffchainLabs/prysm/v7/beacon-chain/p2p/testing"
"github.com/OffchainLabs/prysm/v7/beacon-chain/rpc/core"
state_native "github.com/OffchainLabs/prysm/v7/beacon-chain/state/state-native"
mockSync "github.com/OffchainLabs/prysm/v7/beacon-chain/sync/initial-sync/testing"
state_native "github.com/OffchainLabs/prysm/v7/beacon-chain/state/state-native"
"github.com/OffchainLabs/prysm/v7/config/params"
"github.com/OffchainLabs/prysm/v7/consensus-types/primitives"
"github.com/OffchainLabs/prysm/v7/crypto/bls"

View File

@@ -1027,10 +1027,10 @@ func TestGetVerifyingStateEdgeCases(t *testing.T) {
sc: signatureCache,
sr: &mockStateByRooter{sbr: sbrErrorIfCalled(t)}, // Should not be called
hsp: &mockHeadStateProvider{
headRoot: parentRoot[:], // Same as parent
headSlot: 32, // Epoch 1
headState: fuluState.Copy(), // HeadState (not ReadOnly) for ProcessSlots
headStateReadOnly: nil, // Should not use ReadOnly path
headRoot: parentRoot[:], // Same as parent
headSlot: 32, // Epoch 1
headState: fuluState.Copy(), // HeadState (not ReadOnly) for ProcessSlots
headStateReadOnly: nil, // Should not use ReadOnly path
},
fc: &mockForkchoicer{
// Return same root for both to simulate same chain
@@ -1045,8 +1045,8 @@ func TestGetVerifyingStateEdgeCases(t *testing.T) {
// Wrap to detect HeadState call
originalHsp := initializer.shared.hsp.(*mockHeadStateProvider)
wrappedHsp := &mockHeadStateProvider{
headRoot: originalHsp.headRoot,
headSlot: originalHsp.headSlot,
headRoot: originalHsp.headRoot,
headSlot: originalHsp.headSlot,
headState: originalHsp.headState,
}
initializer.shared.hsp = &headStateCallTracker{

View File

@@ -1,7 +0,0 @@
### Changed
- gRPC fallback now matches rest api implementation and will also check and connect to only synced nodes.
### Removed
- gRPC resolver for load balancing, the new implementation matches rest api's so we should remove the resolver so it's handled the same way for consistency.

View File

@@ -1,11 +0,0 @@
### Ignored
- moved finding healthy node logic to connection provider and other various cleanup on naming.
### Changed
- Improved node fallback logs.
### Fixed
- a potential race condition when switching hosts quickly and reconnecting to same host on an old connection.

View File

@@ -1,3 +0,0 @@
### Added
- Added README for maintaining specrefs.

View File

@@ -1,3 +0,0 @@
### Added
- The ability to download the nightly reference tests from a specific day.

View File

@@ -1,3 +0,0 @@
### Ignored
- Updated golangci to run lint on tests too.

View File

@@ -1,3 +0,0 @@
### Ignored
- Add handy documentation for SSZ Query package (`encoding/ssz/query`).

View File

@@ -1,2 +0,0 @@
### Ignored
- Run go fmt

View File

@@ -1,190 +0,0 @@
# SSZ Query Package
The `encoding/ssz/query` package provides a system for analyzing and querying SSZ ([Simple Serialize](https://github.com/ethereum/consensus-specs/blob/master/ssz/simple-serialize.md)) data structures, as well as generating Merkle proofs from them. It enables runtime analysis of SSZ-serialized Go objects with reflection, path-based queries through nested structures, generalized index calculation, and Merkle proof generation.
This package is designed to be generic. It operates on arbitrary SSZ-serialized Go values at runtime, so the same query/proof machinery applies equally to any SSZ type, including the BeaconState/BeaconBlock.
## Usage Example
```go
// 1. Analyze an SSZ object
block := &ethpb.BeaconBlock{...}
info, err := query.AnalyzeObject(block)
// 2. Parse a path
path, err := query.ParsePath(".body.attestations[0].data.slot")
// 3. Get the generalized index
gindex, err := query.GetGeneralizedIndexFromPath(info, path)
// 4. Generate a Merkle proof
proof, err := info.Prove(gindex)
// 5. Get offset and length to slice the SSZ-encoded bytes
sszBytes, _ := block.MarshalSSZ()
_, offset, length, err := query.CalculateOffsetAndLength(info, path)
// slotBytes contains the SSZ-encoded value at the queried path
slotBytes := sszBytes[offset : offset+length]
```
## Exported API
The main exported API consists of:
```go
// AnalyzeObject analyzes an SSZ object and returns its structural information
func AnalyzeObject(obj SSZObject) (*SszInfo, error)
// ParsePath parses a path string like ".field1.field2[0].field3"
func ParsePath(rawPath string) (Path, error)
// CalculateOffsetAndLength computes byte offset and length for a path within an SSZ object
func CalculateOffsetAndLength(sszInfo *SszInfo, path Path) (*SszInfo, uint64, uint64, error)
// GetGeneralizedIndexFromPath calculates the generalized index for a given path
func GetGeneralizedIndexFromPath(info *SszInfo, path Path) (uint64, error)
// Prove generates a Merkle proof for a target generalized index
func (s *SszInfo) Prove(gindex uint64) (*fastssz.Proof, error)
```
## Type System
### SSZ Types
The package now supports [all standard SSZ types](https://github.com/ethereum/consensus-specs/blob/master/ssz/simple-serialize.md#typing) except `ProgressiveList`, `ProgressiveContainer`, `ProgressiveBitlist`, `Union`, and `CompatibleUnion`.
### Core Data Structures
#### `SszInfo`
The `SszInfo` structure contains complete structural metadata for an SSZ type:
```go
type SszInfo struct {
sszType SszType // SSZ Type classification
typ reflect.Type // Go reflect.Type
source SSZObject // Original SSZObject reference. Mostly used for reusing SSZ methods like `HashTreeRoot`.
isVariable bool // True if contains variable-size fields
// Composite types have corresponding metadata. Other fields would be nil except for the current type.
containerInfo *containerInfo
listInfo *listInfo
vectorInfo *vectorInfo
bitlistInfo *bitlistInfo
bitvectorInfo *bitvectorInfo
}
```
#### `Path`
The `Path` structure represents navigation paths through SSZ structures. It supports accessing a field by field name, accessing an element by index (list/vector type), and finding the length of homogenous collection types. The `ParsePath` function parses a raw string into a `Path` instance, which is commonly used in other APIs like `CalculateOffsetAndLength` and `GetGeneralizedIndexFromPath`.
```go
type Path struct {
Length bool // Flag for length queries (e.g., len(.field))
Elements []PathElement // Sequence of field accesses and indices
}
type PathElement struct {
Name string // Field name
Index *uint64 // list/vector index (nil if not an index access)
}
```
## Implementation Details
### Type Analysis (`analyzer.go`)
The `AnalyzeObject` function performs recursive type introspection using Go reflection:
1. **Type Inspection** - Examines Go `reflect.Value` to determine SSZ type
- Basic types (`uint8`, `uint16`, `uint32`, `uint64`, `bool`): `SSZType` constants
- Slices: Determined from struct tags (`ssz-size` for vectors, `ssz-max` for lists). There is a related [write-up](https://hackmd.io/@junsong/H101DKnwxl) regarding struct tags.
- Structs: Analyzed as Containers with field ordering from JSON tags
- Pointers: Dereferenced automatically
2. **Variable-Length Population** - Determines actual sizes at runtime
- For lists: Iterates elements, caches sizes for variable-element lists
- For containers: Recursively populates variable fields, adjusts offsets
- For bitlists: Decodes bit length from bitvector
3. **Offset Calculation** - Computes byte positions within serialized data
- Fixed-size fields: Offset = sum of preceding field sizes
- Variable-size fields: Offset stored as 4-byte pointer entries
### Path Parsing (`path.go`)
The `ParsePath` function parses path strings with the following rules:
- **Dot notation**: `.field1.field2` for field access
- **Array indexing**: `[0]`, `[42]` for element access
- **Length queries**: `len(.field)` for list/vector lengths
- **Character set**: Only `[A-Za-z0-9._\[\]\(\)]` allowed
Example:
```go
path, _ := ParsePath(".nested.array_field[5].inner_field")
// Returns: Path{
// Elements: [
// PathElement{Name: "nested"},
// PathElement{Name: "array_field", Index: <Pointer to uint64(5)>},
// PathElement{Name: "inner_field"}
// ]
// }
```
### Generalized Index Calculation (`generalized_index.go`)
The generalized index is a tree position identifier. This package follows the [Ethereum consensus-specs](https://github.com/ethereum/consensus-specs/blob/master/ssz/merkle-proofs.md#generalized-merkle-tree-index) to calculate the generalized index.
### Merkle Proof Generation (`merkle_proof.go`, `proof_collector.go`)
The `Prove` method generates Merkle proofs using a single-sweep merkleization algorithm:
#### Algorithm Overview
**Key Terms:**
- **Target gindex** (generalized index): The position of the SSZ element you want to prove, expressed as a generalized Merkle tree index. Stored in `Proof.Index`.
- Note: The generalized index for root is 1.
- **Registered gindices**: The set of tree positions whose node hashes must be captured during merkleization in order to later assemble the proof.
- **Sibling node**: The node that shares the same parent as another node.
- **Leaf value**: The 32-byte hash of the target node (the node being proven). Stored in `Proof.Leaf`.
**Phases:**
1. **Registration Phase** (`addTarget`)
> Goal: determine exactly which sibling hashes are needed for the proof.
- Record the target gindex as the proof target.
- Starting from the target node, walk the Merkle tree from the leaf (target gindex) to the root (gindex = 1).
- At each step:
- Compute and register the sibling gindex (`i XOR 1`) as “must collect”.
- Move to the parent (`i = i/2`).
- This produces the full set of registered gindices (the sibling nodes on the target-to-root path).
2. **Merkleization Phase** (`merkleize`)
> Goal: recursively merkleize the tree and capture the needed hashes.
- Recursively traverse the SSZ structure and compute Merkle tree node hashes from leaves to root.
- Whenever the traversal computes a node whose gindex is in registered gindices, store that nodes hash for later proof construction.
3. **Proof Assembly Phase** (`toProof`)
> Goal: create the final `fastssz.Proof` object in the correct format and order.
```go
// Proof represents a merkle proof against a general index.
type Proof struct {
Index int
Leaf []byte
Hashes [][]byte
}
```
- Set `Proof.Index` to the target gindex.
- Set `Proof.Leaf` to the 32-byte hash of the target node.
- Build `Proof.Hashes` by walking from the target node up to (but not including) the root:
- At node `i`, append the stored hash for the sibling (`i XOR 1`).
- Move to the parent (`i = i/2`).
- The resulting `Proof.Hashes` is ordered from the target level upward, containing one sibling hash per tree level on the path to the root.

View File

@@ -26,21 +26,21 @@ func TestLifecycle(t *testing.T) {
port := 1000 + rand.Intn(1000)
prometheusService := NewService(t.Context(), fmt.Sprintf(":%d", port), nil)
prometheusService.Start()
// Actively wait until the service responds on /metrics (faster and less flaky than a fixed sleep)
deadline := time.Now().Add(3 * time.Second)
for {
if time.Now().After(deadline) {
t.Fatalf("metrics endpoint not ready within timeout")
}
resp, err := http.Get(fmt.Sprintf("http://localhost:%d/metrics", port))
if err == nil {
_ = resp.Body.Close()
if resp.StatusCode == http.StatusOK {
break
}
}
time.Sleep(50 * time.Millisecond)
}
// Actively wait until the service responds on /metrics (faster and less flaky than a fixed sleep)
deadline := time.Now().Add(3 * time.Second)
for {
if time.Now().After(deadline) {
t.Fatalf("metrics endpoint not ready within timeout")
}
resp, err := http.Get(fmt.Sprintf("http://localhost:%d/metrics", port))
if err == nil {
_ = resp.Body.Close()
if resp.StatusCode == http.StatusOK {
break
}
}
time.Sleep(50 * time.Millisecond)
}
// Query the service to ensure it really started.
resp, err := http.Get(fmt.Sprintf("http://localhost:%d/metrics", port))
@@ -49,18 +49,18 @@ func TestLifecycle(t *testing.T) {
err = prometheusService.Stop()
require.NoError(t, err)
// Actively wait until the service stops responding on /metrics
deadline = time.Now().Add(3 * time.Second)
for {
if time.Now().After(deadline) {
t.Fatalf("metrics endpoint still reachable after timeout")
}
_, err = http.Get(fmt.Sprintf("http://localhost:%d/metrics", port))
if err != nil {
break
}
time.Sleep(50 * time.Millisecond)
}
// Actively wait until the service stops responding on /metrics
deadline = time.Now().Add(3 * time.Second)
for {
if time.Now().After(deadline) {
t.Fatalf("metrics endpoint still reachable after timeout")
}
_, err = http.Get(fmt.Sprintf("http://localhost:%d/metrics", port))
if err != nil {
break
}
time.Sleep(50 * time.Millisecond)
}
// Query the service to ensure it really stopped.
_, err = http.Get(fmt.Sprintf("http://localhost:%d/metrics", port))

View File

@@ -1,35 +0,0 @@
# Specification References
This directory contains specification reference tracking files managed by
[ethspecify](https://github.com/jtraglia/ethspecify).
## Installation
Install `ethspecify` with the following command:
```bash
pipx install ethspecify
```
> [!NOTE]
> You can run `ethspecify <cmd>` in the `specrefs` directory or
> `ethspecify <cmd> --path=specrefs` from the project's root directory.
## Maintenance
When adding support for a new specification version, follow these steps:
0. Change directory into the `specrefs` directory.
1. Update the version in `.ethspecify.yml` configuration.
2. Run `ethspecify process` to update/populate specrefs.
3. Run `ethspecify check` to check specrefs.
4. If there are errors, use the error message as a guide to fix the issue. If
there are new specrefs with empty sources, implement/locate each item and
update each specref source list. If you choose not to implement an item,
add an exception to the appropriate section the the `.ethspecify.yml`
configuration.
5. Repeat steps 3 and 4 until `ethspecify check` passes.
6. Run `git diff` to view updated specrefs. If an object/function/etc has
changed, make the necessary updates to the implementation.
7. Lastly, in the project's root directory, run `act -j check-specrefs` to
ensure everything is correct.

View File

@@ -225,9 +225,9 @@ func (r *testRunner) testDepositsAndTx(ctx context.Context, g *errgroup.Group,
if err := helpers.ComponentsStarted(ctx, []e2etypes.ComponentRunner{r.depositor}); err != nil {
return errors.Wrap(err, "testDepositsAndTx unable to run, depositor did not Start")
}
go func() {
if r.config.TestDeposits {
log.Info("Running deposit tests")
go func() {
if r.config.TestDeposits {
log.Info("Running deposit tests")
// The validators with an index < minGenesisActiveCount all have deposits already from the chain start.
// Skip all of those chain start validators by seeking to minGenesisActiveCount in the validator list
// for further deposit testing.
@@ -238,12 +238,12 @@ func (r *testRunner) testDepositsAndTx(ctx context.Context, g *errgroup.Group,
r.t.Error(errors.Wrap(err, "depositor.SendAndMine failed"))
}
}
}
// Only generate background transactions when relevant for the test.
if r.config.TestDeposits || r.config.TestFeature || r.config.UseBuilder {
r.testTxGeneration(ctx, g, keystorePath, []e2etypes.ComponentRunner{})
}
}()
}
// Only generate background transactions when relevant for the test.
if r.config.TestDeposits || r.config.TestFeature || r.config.UseBuilder {
r.testTxGeneration(ctx, g, keystorePath, []e2etypes.ComponentRunner{})
}
}()
if r.config.TestDeposits {
return depositCheckValidator.Start(ctx)
}

View File

@@ -38,8 +38,8 @@ func TestEndToEnd_MinimalConfig(t *testing.T) {
r := e2eMinimal(t, cfg,
types.WithCheckpointSync(),
types.WithEpochs(10),
types.WithExitEpoch(4), // Minimum due to ShardCommitteePeriod=4
types.WithLargeBlobs(), // Use large blob transactions for BPO testing
types.WithExitEpoch(4), // Minimum due to ShardCommitteePeriod=4
types.WithLargeBlobs(), // Use large blob transactions for BPO testing
)
r.run()
}
}

View File

@@ -21,14 +21,10 @@ There are tests for mainnet and minimal config, so for each config we will add a
## Running nightly spectests
Since [PR 15312](https://github.com/OffchainLabs/prysm/pull/15312), Prysm has support to download "nightly" spectests from github via a starlark rule configuration by environment variable.
Set `--repo_env=CONSENSUS_SPEC_TESTS_VERSION=nightly` or `--repo_env=CONSENSUS_SPEC_TESTS_VERSION=nightly-<run_id>` when running spectest to download the "nightly" spectests.
Note: A GITHUB_TOKEN environment variable is required to be set. The github token does not need to be associated with your main account; it can be from a "burner account". And the token does not need to be a fine-grained token; it can be a classic token.
Since [PR 15312](https://github.com/OffchainLabs/prysm/pull/15312), Prysm has support to download "nightly" spectests from github via a starlark rule configuration by environment variable.
Set `--repo_env=CONSENSUS_SPEC_TESTS_VERSION=nightly` when running spectest to download the "nightly" spectests.
Note: A GITHUB_TOKEN environment variable is required to be set. The github token must be a [fine grained token](https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/managing-your-personal-access-tokens#creating-a-fine-grained-personal-access-token).
```
bazel test //... --test_tag_filters=spectest --repo_env=CONSENSUS_SPEC_TESTS_VERSION=nightly
```
```
bazel test //... --test_tag_filters=spectest --repo_env=CONSENSUS_SPEC_TESTS_VERSION=nightly-21422848633
```

View File

@@ -283,18 +283,16 @@ func (mr *MockValidatorClientMockRecorder) ProposeExit(ctx, in any) *gomock.Call
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ProposeExit", reflect.TypeOf((*MockValidatorClient)(nil).ProposeExit), ctx, in)
}
// EnsureReady mocks base method.
func (m *MockValidatorClient) EnsureReady(ctx context.Context) bool {
// SetHost mocks base method.
func (m *MockValidatorClient) SetHost(host string) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "EnsureReady", ctx)
ret0, _ := ret[0].(bool)
return ret0
m.ctrl.Call(m, "SetHost", host)
}
// EnsureReady indicates an expected call of EnsureReady.
func (mr *MockValidatorClientMockRecorder) EnsureReady(ctx any) *gomock.Call {
// SetHost indicates an expected call of SetHost.
func (mr *MockValidatorClientMockRecorder) SetHost(host any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "EnsureReady", reflect.TypeOf((*MockValidatorClient)(nil).EnsureReady), ctx)
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetHost", reflect.TypeOf((*MockValidatorClient)(nil).SetHost), host)
}
// StartEventStream mocks base method.

View File

@@ -128,18 +128,18 @@ func (mr *MockValidatorMockRecorder) EventsChan() *gomock.Call {
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "EventsChan", reflect.TypeOf((*MockValidator)(nil).EventsChan))
}
// EnsureReady mocks base method.
func (m *MockValidator) EnsureReady(arg0 context.Context) bool {
// FindHealthyHost mocks base method.
func (m *MockValidator) FindHealthyHost(arg0 context.Context) bool {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "EnsureReady", arg0)
ret := m.ctrl.Call(m, "FindHealthyHost", arg0)
ret0, _ := ret[0].(bool)
return ret0
}
// EnsureReady indicates an expected call of EnsureReady.
func (mr *MockValidatorMockRecorder) EnsureReady(arg0 any) *gomock.Call {
// FindHealthyHost indicates an expected call of FindHealthyHost.
func (mr *MockValidatorMockRecorder) FindHealthyHost(arg0 any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "EnsureReady", reflect.TypeOf((*MockValidator)(nil).EnsureReady), arg0)
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "FindHealthyHost", reflect.TypeOf((*MockValidator)(nil).FindHealthyHost), arg0)
}
// GenesisTime mocks base method.

View File

@@ -1,6 +1,5 @@
# bazel build @consensus_spec_tests//:test_data
# bazel build @consensus_spec_tests//:test_data --repo_env=CONSENSUS_SPEC_TESTS_VERSION=nightly
# bazel build @consensus_spec_tests//:test_data --repo_env=CONSENSUS_SPEC_TESTS_VERSION=nightly-<run_id>
def _get_redirected_url(repository_ctx, url, headers):
if not repository_ctx.which("curl"):
@@ -25,7 +24,7 @@ def _impl(repository_ctx):
version = repository_ctx.getenv("CONSENSUS_SPEC_TESTS_VERSION") or repository_ctx.attr.version
token = repository_ctx.getenv("GITHUB_TOKEN") or ""
if version == "nightly" or version.startswith("nightly-"):
if version == "nightly":
print("Downloading nightly tests")
if not token:
fail("Error GITHUB_TOKEN is not set")
@@ -35,22 +34,16 @@ def _impl(repository_ctx):
"Accept": "application/vnd.github+json",
}
if version.startswith("nightly-"):
run_id = version.split("nightly-", 1)[1]
if not run_id:
fail("Error invalid run id")
else:
repository_ctx.download(
"https://api.github.com/repos/%s/actions/workflows/%s/runs?branch=%s&status=success&per_page=1"
% (repository_ctx.attr.repo, repository_ctx.attr.workflow, repository_ctx.attr.branch),
headers = headers,
output = "runs.json"
)
repository_ctx.download(
"https://api.github.com/repos/%s/actions/workflows/%s/runs?branch=%s&status=success&per_page=1"
% (repository_ctx.attr.repo, repository_ctx.attr.workflow, repository_ctx.attr.branch),
headers = headers,
output = "runs.json"
)
run_id = json.decode(repository_ctx.read("runs.json"))["workflow_runs"][0]["id"]
repository_ctx.delete("runs.json")
run_id = json.decode(repository_ctx.read("runs.json"))["workflow_runs"][0]["id"]
repository_ctx.delete("runs.json")
print("Run id:", run_id)
repository_ctx.download(
"https://api.github.com/repos/%s/actions/runs/%s/artifacts"
% (repository_ctx.attr.repo, run_id),
@@ -115,8 +108,8 @@ consensus_spec_tests = repository_rule(
"version": attr.string(mandatory = True),
"flavors": attr.string_dict(mandatory = True),
"repo": attr.string(default = "ethereum/consensus-specs"),
"workflow": attr.string(default = "nightly-reftests.yml"),
"branch": attr.string(default = "master"),
"workflow": attr.string(default = "generate_vectors.yml"),
"branch": attr.string(default = "dev"),
"release_url_template": attr.string(default = "https://github.com/ethereum/consensus-specs/releases/download/%s"),
},
)

View File

@@ -25,7 +25,6 @@ go_library(
],
deps = [
"//api/grpc:go_default_library",
"//api/rest:go_default_library",
"//beacon-chain/core/blocks:go_default_library",
"//cmd/validator/flags:go_default_library",
"//config/fieldparams:go_default_library",

View File

@@ -3,13 +3,14 @@ package accounts
import (
"context"
"io"
"net/http"
"os"
"time"
grpcutil "github.com/OffchainLabs/prysm/v7/api/grpc"
"github.com/OffchainLabs/prysm/v7/api/rest"
"github.com/OffchainLabs/prysm/v7/crypto/bls"
"github.com/OffchainLabs/prysm/v7/validator/accounts/wallet"
beaconApi "github.com/OffchainLabs/prysm/v7/validator/client/beacon-api"
iface "github.com/OffchainLabs/prysm/v7/validator/client/iface"
nodeClientFactory "github.com/OffchainLabs/prysm/v7/validator/client/node-client-factory"
validatorClientFactory "github.com/OffchainLabs/prysm/v7/validator/client/validator-client-factory"
@@ -76,17 +77,22 @@ func (acm *CLIManager) prepareBeaconClients(ctx context.Context) (*iface.Validat
}
ctx = grpcutil.AppendHeaders(ctx, acm.grpcHeaders)
conn, err := validatorHelpers.NewNodeConnection(
validatorHelpers.WithGRPC(ctx, acm.beaconRPCProvider, acm.dialOpts),
validatorHelpers.WithREST(acm.beaconApiEndpoint, rest.WithHttpTimeout(acm.beaconApiTimeout)),
)
grpcConn, err := grpc.DialContext(ctx, acm.beaconRPCProvider, acm.dialOpts...)
if err != nil {
return nil, nil, err
return nil, nil, errors.Wrapf(err, "could not dial endpoint %s", acm.beaconRPCProvider)
}
conn := validatorHelpers.NewNodeConnection(
grpcConn,
acm.beaconApiEndpoint,
validatorHelpers.WithBeaconApiTimeout(acm.beaconApiTimeout),
)
validatorClient := validatorClientFactory.NewValidatorClient(conn)
nodeClient := nodeClientFactory.NewNodeClient(conn)
restHandler := beaconApi.NewBeaconApiRestHandler(
http.Client{Timeout: acm.beaconApiTimeout},
acm.beaconApiEndpoint,
)
validatorClient := validatorClientFactory.NewValidatorClient(conn, restHandler)
nodeClient := nodeClientFactory.NewNodeClient(conn, restHandler)
return &validatorClient, &nodeClient, nil
}

View File

@@ -10,6 +10,7 @@ go_library(
"log.go",
"log_helpers.go",
"metrics.go",
"multiple_endpoints_grpc_resolver.go",
"propose.go",
"registration.go",
"runner.go",
@@ -28,7 +29,6 @@ go_library(
"//api/client:go_default_library",
"//api/client/event:go_default_library",
"//api/grpc:go_default_library",
"//api/rest:go_default_library",
"//api/server/structs:go_default_library",
"//async:go_default_library",
"//async/event:go_default_library",
@@ -58,6 +58,7 @@ go_library(
"//time/slots:go_default_library",
"//validator/accounts/iface:go_default_library",
"//validator/accounts/wallet:go_default_library",
"//validator/client/beacon-api:go_default_library",
"//validator/client/beacon-chain-client-factory:go_default_library",
"//validator/client/iface:go_default_library",
"//validator/client/node-client-factory:go_default_library",
@@ -85,11 +86,13 @@ go_library(
"@com_github_prysmaticlabs_go_bitfield//:go_default_library",
"@com_github_sirupsen_logrus//:go_default_library",
"@io_opentelemetry_go_contrib_instrumentation_google_golang_org_grpc_otelgrpc//:go_default_library",
"@io_opentelemetry_go_contrib_instrumentation_net_http_otelhttp//:go_default_library",
"@io_opentelemetry_go_otel_trace//:go_default_library",
"@org_golang_google_grpc//:go_default_library",
"@org_golang_google_grpc//codes:go_default_library",
"@org_golang_google_grpc//credentials:go_default_library",
"@org_golang_google_grpc//metadata:go_default_library",
"@org_golang_google_grpc//resolver:go_default_library",
"@org_golang_google_grpc//status:go_default_library",
"@org_golang_google_protobuf//proto:go_default_library",
"@org_golang_google_protobuf//types/known/emptypb:go_default_library",
@@ -121,7 +124,6 @@ go_test(
],
embed = [":go_default_library"],
deps = [
"//api/grpc:go_default_library",
"//api/server/structs:go_default_library",
"//async/event:go_default_library",
"//beacon-chain/core/signing:go_default_library",

View File

@@ -26,6 +26,7 @@ go_library(
"propose_exit.go",
"prysm_beacon_chain_client.go",
"registration.go",
"rest_handler_client.go",
"state_validators.go",
"status.go",
"stream_blocks.go",
@@ -42,8 +43,6 @@ go_library(
"//api:go_default_library",
"//api/apiutil:go_default_library",
"//api/client/event:go_default_library",
"//api/failover:go_default_library",
"//api/rest:go_default_library",
"//api/server/structs:go_default_library",
"//beacon-chain/core/helpers:go_default_library",
"//beacon-chain/core/signing:go_default_library",
@@ -112,7 +111,6 @@ go_test(
deps = [
"//api:go_default_library",
"//api/apiutil:go_default_library",
"//api/rest:go_default_library",
"//api/server/structs:go_default_library",
"//beacon-chain/core/helpers:go_default_library",
"//beacon-chain/rpc/eth/shared/testing:go_default_library",

View File

@@ -26,7 +26,7 @@ func (c *beaconApiValidatorClient) attestationData(
query := apiutil.BuildURL("/eth/v1/validator/attestation_data", params)
produceAttestationDataResponseJson := structs.GetAttestationDataResponse{}
if err := c.handler.Get(ctx, query, &produceAttestationDataResponseJson); err != nil {
if err := c.jsonRestHandler.Get(ctx, query, &produceAttestationDataResponseJson); err != nil {
return nil, err
}

View File

@@ -28,10 +28,10 @@ func TestGetAttestationData_ValidAttestation(t *testing.T) {
ctrl := gomock.NewController(t)
defer ctrl.Finish()
handler := mock.NewMockJsonRestHandler(ctrl)
jsonRestHandler := mock.NewMockJsonRestHandler(ctrl)
produceAttestationDataResponseJson := structs.GetAttestationDataResponse{}
handler.EXPECT().Get(
jsonRestHandler.EXPECT().Get(
gomock.Any(),
fmt.Sprintf("/eth/v1/validator/attestation_data?committee_index=%d&slot=%d", expectedCommitteeIndex, expectedSlot),
&produceAttestationDataResponseJson,
@@ -56,7 +56,7 @@ func TestGetAttestationData_ValidAttestation(t *testing.T) {
},
).Times(1)
validatorClient := &beaconApiValidatorClient{handler: handler}
validatorClient := &beaconApiValidatorClient{jsonRestHandler: jsonRestHandler}
resp, err := validatorClient.attestationData(ctx, primitives.Slot(expectedSlot), primitives.CommitteeIndex(expectedCommitteeIndex))
assert.NoError(t, err)
@@ -180,8 +180,8 @@ func TestGetAttestationData_InvalidData(t *testing.T) {
defer ctrl.Finish()
produceAttestationDataResponseJson := structs.GetAttestationDataResponse{}
handler := mock.NewMockJsonRestHandler(ctrl)
handler.EXPECT().Get(
jsonRestHandler := mock.NewMockJsonRestHandler(ctrl)
jsonRestHandler.EXPECT().Get(
gomock.Any(),
"/eth/v1/validator/attestation_data?committee_index=2&slot=1",
&produceAttestationDataResponseJson,
@@ -192,7 +192,7 @@ func TestGetAttestationData_InvalidData(t *testing.T) {
testCase.generateData(),
).Times(1)
validatorClient := &beaconApiValidatorClient{handler: handler}
validatorClient := &beaconApiValidatorClient{jsonRestHandler: jsonRestHandler}
_, err := validatorClient.attestationData(ctx, 1, 2)
assert.ErrorContains(t, testCase.expectedErrorMessage, err)
})
@@ -208,9 +208,9 @@ func TestGetAttestationData_JsonResponseError(t *testing.T) {
ctrl := gomock.NewController(t)
defer ctrl.Finish()
handler := mock.NewMockJsonRestHandler(ctrl)
jsonRestHandler := mock.NewMockJsonRestHandler(ctrl)
produceAttestationDataResponseJson := structs.GetAttestationDataResponse{}
handler.EXPECT().Get(
jsonRestHandler.EXPECT().Get(
gomock.Any(),
fmt.Sprintf("/eth/v1/validator/attestation_data?committee_index=%d&slot=%d", committeeIndex, slot),
&produceAttestationDataResponseJson,
@@ -218,7 +218,7 @@ func TestGetAttestationData_JsonResponseError(t *testing.T) {
errors.New("some specific json response error"),
).Times(1)
validatorClient := &beaconApiValidatorClient{handler: handler}
validatorClient := &beaconApiValidatorClient{jsonRestHandler: jsonRestHandler}
_, err := validatorClient.attestationData(ctx, slot, committeeIndex)
assert.ErrorContains(t, "some specific json response error", err)
}

View File

@@ -5,7 +5,6 @@ import (
"reflect"
"strconv"
"github.com/OffchainLabs/prysm/v7/api/rest"
"github.com/OffchainLabs/prysm/v7/api/server/structs"
"github.com/OffchainLabs/prysm/v7/consensus-types/primitives"
ethpb "github.com/OffchainLabs/prysm/v7/proto/prysm/v1alpha1"
@@ -18,13 +17,13 @@ import (
type beaconApiChainClient struct {
fallbackClient iface.ChainClient
handler rest.Handler
jsonRestHandler RestHandler
stateValidatorsProvider StateValidatorsProvider
}
func (c beaconApiChainClient) headBlockHeaders(ctx context.Context) (*structs.GetBlockHeaderResponse, error) {
blockHeader := structs.GetBlockHeaderResponse{}
err := c.handler.Get(ctx, "/eth/v1/beacon/headers/head", &blockHeader)
err := c.jsonRestHandler.Get(ctx, "/eth/v1/beacon/headers/head", &blockHeader)
if err != nil {
return nil, err
}
@@ -44,7 +43,7 @@ func (c beaconApiChainClient) ChainHead(ctx context.Context, _ *empty.Empty) (*e
const endpoint = "/eth/v1/beacon/states/head/finality_checkpoints"
finalityCheckpoints := structs.GetFinalityCheckpointsResponse{}
if err := c.handler.Get(ctx, endpoint, &finalityCheckpoints); err != nil {
if err := c.jsonRestHandler.Get(ctx, endpoint, &finalityCheckpoints); err != nil {
return nil, err
}
@@ -328,10 +327,10 @@ func (c beaconApiChainClient) ValidatorParticipation(ctx context.Context, in *et
return nil, errors.New("beaconApiChainClient.ValidatorParticipation is not implemented. To use a fallback client, pass a fallback client as the last argument of NewBeaconApiChainClientWithFallback.")
}
func NewBeaconApiChainClientWithFallback(handler rest.Handler, fallbackClient iface.ChainClient) iface.ChainClient {
func NewBeaconApiChainClientWithFallback(jsonRestHandler RestHandler, fallbackClient iface.ChainClient) iface.ChainClient {
return &beaconApiChainClient{
handler: handler,
jsonRestHandler: jsonRestHandler,
fallbackClient: fallbackClient,
stateValidatorsProvider: beaconApiStateValidatorsProvider{handler: handler},
stateValidatorsProvider: beaconApiStateValidatorsProvider{jsonRestHandler: jsonRestHandler},
}
}

View File

@@ -115,12 +115,12 @@ func TestListValidators(t *testing.T) {
nil,
)
handler := mock.NewMockJsonRestHandler(ctrl)
handler.EXPECT().Get(gomock.Any(), blockHeaderEndpoint, gomock.Any()).Return(errors.New("bar error"))
jsonRestHandler := mock.NewMockJsonRestHandler(ctrl)
jsonRestHandler.EXPECT().Get(gomock.Any(), blockHeaderEndpoint, gomock.Any()).Return(errors.New("bar error"))
beaconChainClient := beaconApiChainClient{
stateValidatorsProvider: stateValidatorsProvider,
handler: handler,
jsonRestHandler: jsonRestHandler,
}
_, err := beaconChainClient.Validators(ctx, &ethpb.ListValidatorsRequest{
QueryFilter: nil,
@@ -188,8 +188,8 @@ func TestListValidators(t *testing.T) {
nil,
)
handler := mock.NewMockJsonRestHandler(ctrl)
handler.EXPECT().Get(gomock.Any(), blockHeaderEndpoint, gomock.Any()).Return(
jsonRestHandler := mock.NewMockJsonRestHandler(ctrl)
jsonRestHandler.EXPECT().Get(gomock.Any(), blockHeaderEndpoint, gomock.Any()).Return(
nil,
).SetArg(
2,
@@ -198,7 +198,7 @@ func TestListValidators(t *testing.T) {
beaconChainClient := beaconApiChainClient{
stateValidatorsProvider: stateValidatorsProvider,
handler: handler,
jsonRestHandler: jsonRestHandler,
}
_, err := beaconChainClient.Validators(ctx, &ethpb.ListValidatorsRequest{
QueryFilter: nil,
@@ -740,15 +740,15 @@ func TestGetChainHead(t *testing.T) {
ctx := t.Context()
finalityCheckpointsResponse := structs.GetFinalityCheckpointsResponse{}
handler := mock.NewMockJsonRestHandler(ctrl)
handler.EXPECT().Get(gomock.Any(), finalityCheckpointsEndpoint, &finalityCheckpointsResponse).Return(
jsonRestHandler := mock.NewMockJsonRestHandler(ctrl)
jsonRestHandler.EXPECT().Get(gomock.Any(), finalityCheckpointsEndpoint, &finalityCheckpointsResponse).Return(
testCase.finalityCheckpointsError,
).SetArg(
2,
testCase.generateFinalityCheckpointsResponse(),
)
beaconChainClient := beaconApiChainClient{handler: handler}
beaconChainClient := beaconApiChainClient{jsonRestHandler: jsonRestHandler}
_, err := beaconChainClient.ChainHead(ctx, &emptypb.Empty{})
assert.ErrorContains(t, testCase.expectedError, err)
})
@@ -837,10 +837,10 @@ func TestGetChainHead(t *testing.T) {
defer ctrl.Finish()
ctx := t.Context()
handler := mock.NewMockJsonRestHandler(ctrl)
jsonRestHandler := mock.NewMockJsonRestHandler(ctrl)
finalityCheckpointsResponse := structs.GetFinalityCheckpointsResponse{}
handler.EXPECT().Get(gomock.Any(), finalityCheckpointsEndpoint, &finalityCheckpointsResponse).Return(
jsonRestHandler.EXPECT().Get(gomock.Any(), finalityCheckpointsEndpoint, &finalityCheckpointsResponse).Return(
nil,
).SetArg(
2,
@@ -848,14 +848,14 @@ func TestGetChainHead(t *testing.T) {
)
headBlockHeadersResponse := structs.GetBlockHeaderResponse{}
handler.EXPECT().Get(gomock.Any(), headBlockHeadersEndpoint, &headBlockHeadersResponse).Return(
jsonRestHandler.EXPECT().Get(gomock.Any(), headBlockHeadersEndpoint, &headBlockHeadersResponse).Return(
testCase.headBlockHeadersError,
).SetArg(
2,
testCase.generateHeadBlockHeadersResponse(),
)
beaconChainClient := beaconApiChainClient{handler: handler}
beaconChainClient := beaconApiChainClient{jsonRestHandler: jsonRestHandler}
_, err := beaconChainClient.ChainHead(ctx, &emptypb.Empty{})
assert.ErrorContains(t, testCase.expectedError, err)
})
@@ -867,10 +867,10 @@ func TestGetChainHead(t *testing.T) {
defer ctrl.Finish()
ctx := t.Context()
handler := mock.NewMockJsonRestHandler(ctrl)
jsonRestHandler := mock.NewMockJsonRestHandler(ctrl)
finalityCheckpointsResponse := structs.GetFinalityCheckpointsResponse{}
handler.EXPECT().Get(gomock.Any(), finalityCheckpointsEndpoint, &finalityCheckpointsResponse).Return(
jsonRestHandler.EXPECT().Get(gomock.Any(), finalityCheckpointsEndpoint, &finalityCheckpointsResponse).Return(
nil,
).SetArg(
2,
@@ -878,7 +878,7 @@ func TestGetChainHead(t *testing.T) {
)
headBlockHeadersResponse := structs.GetBlockHeaderResponse{}
handler.EXPECT().Get(gomock.Any(), headBlockHeadersEndpoint, &headBlockHeadersResponse).Return(
jsonRestHandler.EXPECT().Get(gomock.Any(), headBlockHeadersEndpoint, &headBlockHeadersResponse).Return(
nil,
).SetArg(
2,
@@ -909,7 +909,7 @@ func TestGetChainHead(t *testing.T) {
HeadEpoch: slots.ToEpoch(8),
}
beaconChainClient := beaconApiChainClient{handler: handler}
beaconChainClient := beaconApiChainClient{jsonRestHandler: jsonRestHandler}
chainHead, err := beaconChainClient.ChainHead(ctx, &emptypb.Empty{})
require.NoError(t, err)
assert.DeepEqual(t, expectedChainHead, chainHead)

View File

@@ -29,7 +29,7 @@ func (c *beaconApiValidatorClient) fork(ctx context.Context) (*structs.GetStateF
stateForkResponseJson := &structs.GetStateForkResponse{}
if err := c.handler.Get(ctx, endpoint, stateForkResponseJson); err != nil {
if err := c.jsonRestHandler.Get(ctx, endpoint, stateForkResponseJson); err != nil {
return nil, err
}
@@ -41,7 +41,7 @@ func (c *beaconApiValidatorClient) headers(ctx context.Context) (*structs.GetBlo
blockHeadersResponseJson := &structs.GetBlockHeadersResponse{}
if err := c.handler.Get(ctx, endpoint, blockHeadersResponseJson); err != nil {
if err := c.jsonRestHandler.Get(ctx, endpoint, blockHeadersResponseJson); err != nil {
return nil, err
}
@@ -59,7 +59,7 @@ func (c *beaconApiValidatorClient) liveness(ctx context.Context, epoch primitive
return nil, errors.Wrapf(err, "failed to marshal validator indexes")
}
if err = c.handler.Post(ctx, url, nil, bytes.NewBuffer(marshalledJsonValidatorIndexes), livenessResponseJson); err != nil {
if err = c.jsonRestHandler.Post(ctx, url, nil, bytes.NewBuffer(marshalledJsonValidatorIndexes), livenessResponseJson); err != nil {
return nil, err
}
@@ -71,7 +71,7 @@ func (c *beaconApiValidatorClient) syncing(ctx context.Context) (*structs.SyncSt
syncingResponseJson := &structs.SyncStatusResponse{}
if err := c.handler.Get(ctx, endpoint, syncingResponseJson); err != nil {
if err := c.jsonRestHandler.Get(ctx, endpoint, syncingResponseJson); err != nil {
return nil, err
}

View File

@@ -20,7 +20,7 @@ func TestGetFork_Nominal(t *testing.T) {
defer ctrl.Finish()
stateForkResponseJson := structs.GetStateForkResponse{}
handler := mock.NewMockJsonRestHandler(ctrl)
jsonRestHandler := mock.NewMockJsonRestHandler(ctrl)
expected := structs.GetStateForkResponse{
Data: &structs.Fork{
@@ -32,7 +32,7 @@ func TestGetFork_Nominal(t *testing.T) {
ctx := t.Context()
handler.EXPECT().Get(
jsonRestHandler.EXPECT().Get(
gomock.Any(),
forkEndpoint,
&stateForkResponseJson,
@@ -44,7 +44,7 @@ func TestGetFork_Nominal(t *testing.T) {
).Times(1)
validatorClient := beaconApiValidatorClient{
handler: handler,
jsonRestHandler: jsonRestHandler,
}
fork, err := validatorClient.fork(ctx)
@@ -56,11 +56,11 @@ func TestGetFork_Invalid(t *testing.T) {
ctrl := gomock.NewController(t)
defer ctrl.Finish()
handler := mock.NewMockJsonRestHandler(ctrl)
jsonRestHandler := mock.NewMockJsonRestHandler(ctrl)
ctx := t.Context()
handler.EXPECT().Get(
jsonRestHandler.EXPECT().Get(
gomock.Any(),
forkEndpoint,
gomock.Any(),
@@ -69,7 +69,7 @@ func TestGetFork_Invalid(t *testing.T) {
).Times(1)
validatorClient := beaconApiValidatorClient{
handler: handler,
jsonRestHandler: jsonRestHandler,
}
_, err := validatorClient.fork(ctx)
@@ -83,7 +83,7 @@ func TestGetHeaders_Nominal(t *testing.T) {
defer ctrl.Finish()
blockHeadersResponseJson := structs.GetBlockHeadersResponse{}
handler := mock.NewMockJsonRestHandler(ctrl)
jsonRestHandler := mock.NewMockJsonRestHandler(ctrl)
expected := structs.GetBlockHeadersResponse{
Data: []*structs.SignedBeaconBlockHeaderContainer{
@@ -99,7 +99,7 @@ func TestGetHeaders_Nominal(t *testing.T) {
ctx := t.Context()
handler.EXPECT().Get(
jsonRestHandler.EXPECT().Get(
gomock.Any(),
headersEndpoint,
&blockHeadersResponseJson,
@@ -111,7 +111,7 @@ func TestGetHeaders_Nominal(t *testing.T) {
).Times(1)
validatorClient := beaconApiValidatorClient{
handler: handler,
jsonRestHandler: jsonRestHandler,
}
headers, err := validatorClient.headers(ctx)
@@ -123,11 +123,11 @@ func TestGetHeaders_Invalid(t *testing.T) {
ctrl := gomock.NewController(t)
defer ctrl.Finish()
handler := mock.NewMockJsonRestHandler(ctrl)
jsonRestHandler := mock.NewMockJsonRestHandler(ctrl)
ctx := t.Context()
handler.EXPECT().Get(
jsonRestHandler.EXPECT().Get(
gomock.Any(),
headersEndpoint,
gomock.Any(),
@@ -136,7 +136,7 @@ func TestGetHeaders_Invalid(t *testing.T) {
).Times(1)
validatorClient := beaconApiValidatorClient{
handler: handler,
jsonRestHandler: jsonRestHandler,
}
_, err := validatorClient.headers(ctx)
@@ -170,8 +170,8 @@ func TestGetLiveness_Nominal(t *testing.T) {
ctx := t.Context()
handler := mock.NewMockJsonRestHandler(ctrl)
handler.EXPECT().Post(
jsonRestHandler := mock.NewMockJsonRestHandler(ctrl)
jsonRestHandler.EXPECT().Post(
gomock.Any(),
livenessEndpoint,
nil,
@@ -184,7 +184,7 @@ func TestGetLiveness_Nominal(t *testing.T) {
nil,
).Times(1)
validatorClient := &beaconApiValidatorClient{handler: handler}
validatorClient := &beaconApiValidatorClient{jsonRestHandler: jsonRestHandler}
liveness, err := validatorClient.liveness(ctx, 42, indexes)
require.NoError(t, err)
@@ -197,8 +197,8 @@ func TestGetLiveness_Invalid(t *testing.T) {
ctx := t.Context()
handler := mock.NewMockJsonRestHandler(ctrl)
handler.EXPECT().Post(
jsonRestHandler := mock.NewMockJsonRestHandler(ctrl)
jsonRestHandler.EXPECT().Post(
gomock.Any(),
livenessEndpoint,
nil,
@@ -208,7 +208,7 @@ func TestGetLiveness_Invalid(t *testing.T) {
errors.New("custom error"),
).Times(1)
validatorClient := &beaconApiValidatorClient{handler: handler}
validatorClient := &beaconApiValidatorClient{jsonRestHandler: jsonRestHandler}
_, err := validatorClient.liveness(ctx, 42, nil)
require.ErrorContains(t, "custom error", err)
@@ -237,7 +237,7 @@ func TestGetIsSyncing_Nominal(t *testing.T) {
defer ctrl.Finish()
syncingResponseJson := structs.SyncStatusResponse{}
handler := mock.NewMockJsonRestHandler(ctrl)
jsonRestHandler := mock.NewMockJsonRestHandler(ctrl)
expected := structs.SyncStatusResponse{
Data: &structs.SyncStatusResponseData{
@@ -247,7 +247,7 @@ func TestGetIsSyncing_Nominal(t *testing.T) {
ctx := t.Context()
handler.EXPECT().Get(
jsonRestHandler.EXPECT().Get(
gomock.Any(),
syncingEndpoint,
&syncingResponseJson,
@@ -259,7 +259,7 @@ func TestGetIsSyncing_Nominal(t *testing.T) {
).Times(1)
validatorClient := beaconApiValidatorClient{
handler: handler,
jsonRestHandler: jsonRestHandler,
}
isSyncing, err := validatorClient.isSyncing(ctx)
@@ -274,11 +274,11 @@ func TestGetIsSyncing_Invalid(t *testing.T) {
defer ctrl.Finish()
syncingResponseJson := structs.SyncStatusResponse{}
handler := mock.NewMockJsonRestHandler(ctrl)
jsonRestHandler := mock.NewMockJsonRestHandler(ctrl)
ctx := t.Context()
handler.EXPECT().Get(
jsonRestHandler.EXPECT().Get(
gomock.Any(),
syncingEndpoint,
&syncingResponseJson,
@@ -287,7 +287,7 @@ func TestGetIsSyncing_Invalid(t *testing.T) {
).Times(1)
validatorClient := beaconApiValidatorClient{
handler: handler,
jsonRestHandler: jsonRestHandler,
}
isSyncing, err := validatorClient.isSyncing(ctx)

View File

@@ -5,7 +5,6 @@ import (
"net/http"
"strconv"
"github.com/OffchainLabs/prysm/v7/api/rest"
"github.com/OffchainLabs/prysm/v7/api/server/structs"
ethpb "github.com/OffchainLabs/prysm/v7/proto/prysm/v1alpha1"
"github.com/OffchainLabs/prysm/v7/validator/client/iface"
@@ -21,13 +20,13 @@ var (
type beaconApiNodeClient struct {
fallbackClient iface.NodeClient
handler rest.Handler
jsonRestHandler RestHandler
genesisProvider GenesisProvider
}
func (c *beaconApiNodeClient) SyncStatus(ctx context.Context, _ *empty.Empty) (*ethpb.SyncStatus, error) {
syncingResponse := structs.SyncStatusResponse{}
if err := c.handler.Get(ctx, "/eth/v1/node/syncing", &syncingResponse); err != nil {
if err := c.jsonRestHandler.Get(ctx, "/eth/v1/node/syncing", &syncingResponse); err != nil {
return nil, err
}
@@ -57,7 +56,7 @@ func (c *beaconApiNodeClient) Genesis(ctx context.Context, _ *empty.Empty) (*eth
}
depositContractJson := structs.GetDepositContractResponse{}
if err = c.handler.Get(ctx, "/eth/v1/config/deposit_contract", &depositContractJson); err != nil {
if err = c.jsonRestHandler.Get(ctx, "/eth/v1/config/deposit_contract", &depositContractJson); err != nil {
return nil, err
}
@@ -81,7 +80,7 @@ func (c *beaconApiNodeClient) Genesis(ctx context.Context, _ *empty.Empty) (*eth
func (c *beaconApiNodeClient) Version(ctx context.Context, _ *empty.Empty) (*ethpb.Version, error) {
var versionResponse structs.GetVersionResponse
if err := c.handler.Get(ctx, "/eth/v1/node/version", &versionResponse); err != nil {
if err := c.jsonRestHandler.Get(ctx, "/eth/v1/node/version", &versionResponse); err != nil {
return nil, err
}
@@ -106,9 +105,9 @@ func (c *beaconApiNodeClient) Peers(ctx context.Context, in *empty.Empty) (*ethp
// IsReady returns true only if the node is fully synced (200 OK).
// A 206 Partial Content response indicates the node is syncing and not ready.
func (c *beaconApiNodeClient) IsReady(ctx context.Context) bool {
statusCode, err := c.handler.GetStatusCode(ctx, "/eth/v1/node/health")
statusCode, err := c.jsonRestHandler.GetStatusCode(ctx, "/eth/v1/node/health")
if err != nil {
log.WithError(err).WithField("beaconNodeUrl", c.handler.Host()).Error("failed to get health of node")
log.WithError(err).Error("failed to get health of node")
return false
}
// Only 200 OK means the node is fully synced and ready.
@@ -116,11 +115,11 @@ func (c *beaconApiNodeClient) IsReady(ctx context.Context) bool {
return statusCode == http.StatusOK
}
func NewNodeClientWithFallback(handler rest.Handler, fallbackClient iface.NodeClient) iface.NodeClient {
func NewNodeClientWithFallback(jsonRestHandler RestHandler, fallbackClient iface.NodeClient) iface.NodeClient {
b := &beaconApiNodeClient{
handler: handler,
jsonRestHandler: jsonRestHandler,
fallbackClient: fallbackClient,
genesisProvider: &beaconApiGenesisProvider{handler: handler},
genesisProvider: &beaconApiGenesisProvider{jsonRestHandler: jsonRestHandler},
}
return b
}

View File

@@ -120,10 +120,10 @@ func TestGetGenesis(t *testing.T) {
)
depositContractJson := structs.GetDepositContractResponse{}
handler := mock.NewMockJsonRestHandler(ctrl)
jsonRestHandler := mock.NewMockJsonRestHandler(ctrl)
if testCase.queriesDepositContract {
handler.EXPECT().Get(
jsonRestHandler.EXPECT().Get(
gomock.Any(),
"/eth/v1/config/deposit_contract",
&depositContractJson,
@@ -137,7 +137,7 @@ func TestGetGenesis(t *testing.T) {
nodeClient := &beaconApiNodeClient{
genesisProvider: genesisProvider,
handler: handler,
jsonRestHandler: jsonRestHandler,
}
response, err := nodeClient.Genesis(ctx, &emptypb.Empty{})
@@ -201,8 +201,8 @@ func TestGetSyncStatus(t *testing.T) {
ctx := t.Context()
syncingResponse := structs.SyncStatusResponse{}
handler := mock.NewMockJsonRestHandler(ctrl)
handler.EXPECT().Get(
jsonRestHandler := mock.NewMockJsonRestHandler(ctrl)
jsonRestHandler.EXPECT().Get(
gomock.Any(),
syncingEndpoint,
&syncingResponse,
@@ -213,7 +213,7 @@ func TestGetSyncStatus(t *testing.T) {
testCase.restEndpointResponse,
)
nodeClient := &beaconApiNodeClient{handler: handler}
nodeClient := &beaconApiNodeClient{jsonRestHandler: jsonRestHandler}
syncStatus, err := nodeClient.SyncStatus(ctx, &emptypb.Empty{})
if testCase.expectedResponse == nil {
@@ -265,8 +265,8 @@ func TestGetVersion(t *testing.T) {
ctx := t.Context()
var versionResponse structs.GetVersionResponse
handler := mock.NewMockJsonRestHandler(ctrl)
handler.EXPECT().Get(
jsonRestHandler := mock.NewMockJsonRestHandler(ctrl)
jsonRestHandler.EXPECT().Get(
gomock.Any(),
versionEndpoint,
&versionResponse,
@@ -277,7 +277,7 @@ func TestGetVersion(t *testing.T) {
testCase.restEndpointResponse,
)
nodeClient := &beaconApiNodeClient{handler: handler}
nodeClient := &beaconApiNodeClient{jsonRestHandler: jsonRestHandler}
version, err := nodeClient.Version(ctx, &emptypb.Empty{})
if testCase.expectedResponse == nil {
@@ -331,14 +331,13 @@ func TestIsReady(t *testing.T) {
defer ctrl.Finish()
ctx := t.Context()
handler := mock.NewMockJsonRestHandler(ctrl)
handler.EXPECT().GetStatusCode(
jsonRestHandler := mock.NewMockJsonRestHandler(ctrl)
jsonRestHandler.EXPECT().GetStatusCode(
gomock.Any(),
healthEndpoint,
).Return(tc.statusCode, tc.err)
handler.EXPECT().Host().Return("http://localhost:3500").AnyTimes()
nodeClient := &beaconApiNodeClient{handler: handler}
nodeClient := &beaconApiNodeClient{jsonRestHandler: jsonRestHandler}
result := nodeClient.IsReady(ctx)
assert.Equal(t, tc.expectedResult, result)

View File

@@ -6,8 +6,6 @@ import (
"time"
"github.com/OffchainLabs/prysm/v7/api/client/event"
"github.com/OffchainLabs/prysm/v7/api/failover"
"github.com/OffchainLabs/prysm/v7/api/rest"
"github.com/OffchainLabs/prysm/v7/consensus-types/primitives"
"github.com/OffchainLabs/prysm/v7/encoding/bytesutil"
"github.com/OffchainLabs/prysm/v7/monitoring/tracing/trace"
@@ -24,28 +22,22 @@ type beaconApiValidatorClient struct {
genesisProvider GenesisProvider
dutiesProvider dutiesProvider
stateValidatorsProvider StateValidatorsProvider
restProvider rest.RestConnectionProvider
handler rest.Handler
nodeClient *beaconApiNodeClient
jsonRestHandler RestHandler
beaconBlockConverter BeaconBlockConverter
prysmChainClient iface.PrysmChainClient
isEventStreamRunning bool
}
func NewBeaconApiValidatorClient(provider rest.RestConnectionProvider, opts ...ValidatorClientOpt) iface.ValidatorClient {
handler := provider.Handler()
nc := &beaconApiNodeClient{handler: handler}
func NewBeaconApiValidatorClient(jsonRestHandler RestHandler, opts ...ValidatorClientOpt) iface.ValidatorClient {
c := &beaconApiValidatorClient{
genesisProvider: &beaconApiGenesisProvider{handler: handler},
dutiesProvider: beaconApiDutiesProvider{handler: handler},
stateValidatorsProvider: beaconApiStateValidatorsProvider{handler: handler},
restProvider: provider,
handler: handler,
nodeClient: nc,
genesisProvider: &beaconApiGenesisProvider{jsonRestHandler: jsonRestHandler},
dutiesProvider: beaconApiDutiesProvider{jsonRestHandler: jsonRestHandler},
stateValidatorsProvider: beaconApiStateValidatorsProvider{jsonRestHandler: jsonRestHandler},
jsonRestHandler: jsonRestHandler,
beaconBlockConverter: beaconApiBeaconBlockConverter{},
prysmChainClient: prysmChainClient{
nodeClient: nc,
handler: handler,
nodeClient: &beaconApiNodeClient{jsonRestHandler: jsonRestHandler},
jsonRestHandler: jsonRestHandler,
},
isEventStreamRunning: false,
}
@@ -287,8 +279,8 @@ func (c *beaconApiValidatorClient) WaitForChainStart(ctx context.Context, _ *emp
}
func (c *beaconApiValidatorClient) StartEventStream(ctx context.Context, topics []string, eventsChannel chan<- *event.Event) {
client := &http.Client{} // event stream should not be subject to the same settings as other api calls
eventStream, err := event.NewEventStream(ctx, client, c.handler.Host(), topics)
client := &http.Client{} // event stream should not be subject to the same settings as other api calls, so we won't use c.jsonRestHandler.HttpClient()
eventStream, err := event.NewEventStream(ctx, client, c.jsonRestHandler.Host(), topics)
if err != nil {
eventsChannel <- &event.Event{
EventType: event.EventError,
@@ -336,9 +328,9 @@ func wrapInMetrics[Resp any](action string, f func() (Resp, error)) (Resp, error
}
func (c *beaconApiValidatorClient) Host() string {
return c.handler.Host()
return c.jsonRestHandler.Host()
}
func (c *beaconApiValidatorClient) EnsureReady(ctx context.Context) bool {
return failover.EnsureReady(ctx, c.restProvider, c.nodeClient)
func (c *beaconApiValidatorClient) SetHost(host string) {
c.jsonRestHandler.SetHost(host)
}

View File

@@ -31,9 +31,9 @@ func TestBeaconApiValidatorClient_GetAttestationDataValid(t *testing.T) {
ctx := t.Context()
handler := mock.NewMockJsonRestHandler(ctrl)
jsonRestHandler := mock.NewMockJsonRestHandler(ctrl)
produceAttestationDataResponseJson := structs.GetAttestationDataResponse{}
handler.EXPECT().Get(
jsonRestHandler.EXPECT().Get(
gomock.Any(),
fmt.Sprintf("/eth/v1/validator/attestation_data?committee_index=%d&slot=%d", committeeIndex, slot),
&produceAttestationDataResponseJson,
@@ -44,7 +44,7 @@ func TestBeaconApiValidatorClient_GetAttestationDataValid(t *testing.T) {
generateValidAttestation(uint64(slot), uint64(committeeIndex)),
).Times(2)
validatorClient := beaconApiValidatorClient{handler: handler}
validatorClient := beaconApiValidatorClient{jsonRestHandler: jsonRestHandler}
expectedResp, expectedErr := validatorClient.attestationData(ctx, slot, committeeIndex)
resp, err := validatorClient.AttestationData(
@@ -65,9 +65,9 @@ func TestBeaconApiValidatorClient_GetAttestationDataError(t *testing.T) {
ctx := t.Context()
handler := mock.NewMockJsonRestHandler(ctrl)
jsonRestHandler := mock.NewMockJsonRestHandler(ctrl)
produceAttestationDataResponseJson := structs.GetAttestationDataResponse{}
handler.EXPECT().Get(
jsonRestHandler.EXPECT().Get(
gomock.Any(),
fmt.Sprintf("/eth/v1/validator/attestation_data?committee_index=%d&slot=%d", committeeIndex, slot),
&produceAttestationDataResponseJson,
@@ -78,7 +78,7 @@ func TestBeaconApiValidatorClient_GetAttestationDataError(t *testing.T) {
generateValidAttestation(uint64(slot), uint64(committeeIndex)),
).Times(2)
validatorClient := beaconApiValidatorClient{handler: handler}
validatorClient := beaconApiValidatorClient{jsonRestHandler: jsonRestHandler}
expectedResp, expectedErr := validatorClient.attestationData(ctx, slot, committeeIndex)
resp, err := validatorClient.AttestationData(
@@ -139,8 +139,8 @@ func TestBeaconApiValidatorClient_ProposeBeaconBlockValid(t *testing.T) {
ctx := t.Context()
handler := mock.NewMockJsonRestHandler(ctrl)
handler.EXPECT().PostSSZ(
jsonRestHandler := mock.NewMockJsonRestHandler(ctrl)
jsonRestHandler.EXPECT().PostSSZ(
gomock.Any(),
"/eth/v2/beacon/blocks",
gomock.Any(),
@@ -149,7 +149,7 @@ func TestBeaconApiValidatorClient_ProposeBeaconBlockValid(t *testing.T) {
nil, nil, nil,
).Times(1)
validatorClient := beaconApiValidatorClient{handler: handler}
validatorClient := beaconApiValidatorClient{jsonRestHandler: jsonRestHandler}
expectedResp, expectedErr := validatorClient.proposeBeaconBlock(
ctx,
&ethpb.GenericSignedBeaconBlock{
@@ -166,8 +166,8 @@ func TestBeaconApiValidatorClient_ProposeBeaconBlockError_ThenPass(t *testing.T)
ctx := t.Context()
handler := mock.NewMockJsonRestHandler(ctrl)
handler.EXPECT().PostSSZ(
jsonRestHandler := mock.NewMockJsonRestHandler(ctrl)
jsonRestHandler.EXPECT().PostSSZ(
gomock.Any(),
"/eth/v2/beacon/blocks",
gomock.Any(),
@@ -179,7 +179,7 @@ func TestBeaconApiValidatorClient_ProposeBeaconBlockError_ThenPass(t *testing.T)
},
).Times(1)
handler.EXPECT().Post(
jsonRestHandler.EXPECT().Post(
gomock.Any(),
"/eth/v2/beacon/blocks",
gomock.Any(),
@@ -189,7 +189,7 @@ func TestBeaconApiValidatorClient_ProposeBeaconBlockError_ThenPass(t *testing.T)
nil,
).Times(1)
validatorClient := beaconApiValidatorClient{handler: handler}
validatorClient := beaconApiValidatorClient{jsonRestHandler: jsonRestHandler}
expectedResp, expectedErr := validatorClient.proposeBeaconBlock(
ctx,
&ethpb.GenericSignedBeaconBlock{
@@ -308,10 +308,10 @@ func TestBeaconApiValidatorClient_ProposeBeaconBlockAllTypes(t *testing.T) {
defer ctrl.Finish()
ctx := t.Context()
handler := mock.NewMockJsonRestHandler(ctrl)
jsonRestHandler := mock.NewMockJsonRestHandler(ctrl)
if !tt.wantErr {
handler.EXPECT().PostSSZ(
jsonRestHandler.EXPECT().PostSSZ(
gomock.Any(),
tt.expectedPath,
gomock.Any(),
@@ -319,7 +319,7 @@ func TestBeaconApiValidatorClient_ProposeBeaconBlockAllTypes(t *testing.T) {
).Return(nil, nil, nil).Times(1)
}
validatorClient := beaconApiValidatorClient{handler: handler}
validatorClient := beaconApiValidatorClient{jsonRestHandler: jsonRestHandler}
resp, err := validatorClient.proposeBeaconBlock(ctx, tt.block)
if tt.wantErr {
@@ -366,9 +366,9 @@ func TestBeaconApiValidatorClient_ProposeBeaconBlockHTTPErrors(t *testing.T) {
defer ctrl.Finish()
ctx := t.Context()
handler := mock.NewMockJsonRestHandler(ctrl)
jsonRestHandler := mock.NewMockJsonRestHandler(ctrl)
handler.EXPECT().PostSSZ(
jsonRestHandler.EXPECT().PostSSZ(
gomock.Any(),
"/eth/v2/beacon/blocks",
gomock.Any(),
@@ -377,7 +377,7 @@ func TestBeaconApiValidatorClient_ProposeBeaconBlockHTTPErrors(t *testing.T) {
if tt.expectJSON {
// When SSZ fails, it falls back to JSON
handler.EXPECT().Post(
jsonRestHandler.EXPECT().Post(
gomock.Any(),
"/eth/v2/beacon/blocks",
gomock.Any(),
@@ -386,7 +386,7 @@ func TestBeaconApiValidatorClient_ProposeBeaconBlockHTTPErrors(t *testing.T) {
).Return(tt.sszError).Times(1)
}
validatorClient := beaconApiValidatorClient{handler: handler}
validatorClient := beaconApiValidatorClient{jsonRestHandler: jsonRestHandler}
_, err := validatorClient.proposeBeaconBlock(
ctx,
&ethpb.GenericSignedBeaconBlock{
@@ -507,10 +507,10 @@ func TestBeaconApiValidatorClient_ProposeBeaconBlockJSONFallback(t *testing.T) {
defer ctrl.Finish()
ctx := t.Context()
handler := mock.NewMockJsonRestHandler(ctrl)
jsonRestHandler := mock.NewMockJsonRestHandler(ctrl)
// SSZ call fails with 406 to trigger JSON fallback
handler.EXPECT().PostSSZ(
jsonRestHandler.EXPECT().PostSSZ(
gomock.Any(),
tt.expectedPath,
gomock.Any(),
@@ -521,7 +521,7 @@ func TestBeaconApiValidatorClient_ProposeBeaconBlockJSONFallback(t *testing.T) {
}).Times(1)
// JSON fallback
handler.EXPECT().Post(
jsonRestHandler.EXPECT().Post(
gomock.Any(),
tt.expectedPath,
gomock.Any(),
@@ -529,7 +529,7 @@ func TestBeaconApiValidatorClient_ProposeBeaconBlockJSONFallback(t *testing.T) {
gomock.Any(),
).Return(tt.jsonError).Times(1)
validatorClient := beaconApiValidatorClient{handler: handler}
validatorClient := beaconApiValidatorClient{jsonRestHandler: jsonRestHandler}
resp, err := validatorClient.proposeBeaconBlock(ctx, tt.block)
if tt.wantErr {
@@ -547,12 +547,29 @@ func TestBeaconApiValidatorClient_Host(t *testing.T) {
ctrl := gomock.NewController(t)
defer ctrl.Finish()
handler := mock.NewMockJsonRestHandler(ctrl)
handler.EXPECT().Host().Return("http://localhost:8080").Times(1)
hosts := []string{"http://localhost:8080", "http://localhost:8081"}
jsonRestHandler := mock.NewMockJsonRestHandler(ctrl)
jsonRestHandler.EXPECT().SetHost(
hosts[0],
).Times(1)
jsonRestHandler.EXPECT().Host().Return(
hosts[0],
).Times(1)
validatorClient := beaconApiValidatorClient{handler: handler}
validatorClient := beaconApiValidatorClient{jsonRestHandler: jsonRestHandler}
validatorClient.SetHost(hosts[0])
host := validatorClient.Host()
require.Equal(t, "http://localhost:8080", host)
require.Equal(t, hosts[0], host)
jsonRestHandler.EXPECT().SetHost(
hosts[1],
).Times(1)
jsonRestHandler.EXPECT().Host().Return(
hosts[1],
).Times(1)
validatorClient.SetHost(hosts[1])
host = validatorClient.Host()
require.Equal(t, hosts[1], host)
}
// Helper functions for generating test blocks for newer consensus versions

View File

@@ -20,7 +20,7 @@ func (c *beaconApiValidatorClient) aggregatedSelection(ctx context.Context, sele
}
var resp aggregatedSelectionResponse
err = c.handler.Post(ctx, "/eth/v1/validator/beacon_committee_selections", nil, bytes.NewBuffer(body), &resp)
err = c.jsonRestHandler.Post(ctx, "/eth/v1/validator/beacon_committee_selections", nil, bytes.NewBuffer(body), &resp)
if err != nil {
return nil, errors.Wrap(err, "error calling post endpoint")
}

View File

@@ -89,13 +89,13 @@ func TestGetAggregatedSelections(t *testing.T) {
for _, test := range testcases {
t.Run(test.name, func(t *testing.T) {
ctrl := gomock.NewController(t)
handler := mock.NewMockJsonRestHandler(ctrl)
jsonRestHandler := mock.NewMockJsonRestHandler(ctrl)
reqBody, err := json.Marshal(test.req)
require.NoError(t, err)
ctx := t.Context()
handler.EXPECT().Post(
jsonRestHandler.EXPECT().Post(
gomock.Any(),
"/eth/v1/validator/beacon_committee_selections",
nil,
@@ -108,7 +108,7 @@ func TestGetAggregatedSelections(t *testing.T) {
test.endpointError,
).Times(1)
validatorClient := &beaconApiValidatorClient{handler: handler}
validatorClient := &beaconApiValidatorClient{jsonRestHandler: jsonRestHandler}
res, err := validatorClient.AggregatedSelections(ctx, test.req)
if test.expectedErrorMessage != "" {
require.ErrorContains(t, test.expectedErrorMessage, err)

View File

@@ -288,12 +288,12 @@ func TestCheckDoppelGanger_Nominal(t *testing.T) {
ctrl := gomock.NewController(t)
defer ctrl.Finish()
handler := mock.NewMockJsonRestHandler(ctrl)
jsonRestHandler := mock.NewMockJsonRestHandler(ctrl)
if testCase.getSyncingOutput != nil {
syncingResponseJson := structs.SyncStatusResponse{}
handler.EXPECT().Get(
jsonRestHandler.EXPECT().Get(
gomock.Any(),
syncingEndpoint,
&syncingResponseJson,
@@ -308,7 +308,7 @@ func TestCheckDoppelGanger_Nominal(t *testing.T) {
if testCase.getForkOutput != nil {
stateForkResponseJson := structs.GetStateForkResponse{}
handler.EXPECT().Get(
jsonRestHandler.EXPECT().Get(
gomock.Any(),
forkEndpoint,
&stateForkResponseJson,
@@ -323,7 +323,7 @@ func TestCheckDoppelGanger_Nominal(t *testing.T) {
if testCase.getHeadersOutput != nil {
blockHeadersResponseJson := structs.GetBlockHeadersResponse{}
handler.EXPECT().Get(
jsonRestHandler.EXPECT().Get(
gomock.Any(),
headersEndpoint,
&blockHeadersResponseJson,
@@ -342,7 +342,7 @@ func TestCheckDoppelGanger_Nominal(t *testing.T) {
marshalledIndexes, err := json.Marshal(iface.inputStringIndexes)
require.NoError(t, err)
handler.EXPECT().Post(
jsonRestHandler.EXPECT().Post(
gomock.Any(),
iface.inputUrl,
nil,
@@ -372,7 +372,7 @@ func TestCheckDoppelGanger_Nominal(t *testing.T) {
}
validatorClient := beaconApiValidatorClient{
handler: handler,
jsonRestHandler: jsonRestHandler,
stateValidatorsProvider: stateValidatorsProvider,
}
@@ -722,12 +722,12 @@ func TestCheckDoppelGanger_Errors(t *testing.T) {
ctrl := gomock.NewController(t)
defer ctrl.Finish()
handler := mock.NewMockJsonRestHandler(ctrl)
jsonRestHandler := mock.NewMockJsonRestHandler(ctrl)
if testCase.getSyncingOutput != nil {
syncingResponseJson := structs.SyncStatusResponse{}
handler.EXPECT().Get(
jsonRestHandler.EXPECT().Get(
gomock.Any(),
syncingEndpoint,
&syncingResponseJson,
@@ -742,7 +742,7 @@ func TestCheckDoppelGanger_Errors(t *testing.T) {
if testCase.getForkOutput != nil {
stateForkResponseJson := structs.GetStateForkResponse{}
handler.EXPECT().Get(
jsonRestHandler.EXPECT().Get(
gomock.Any(),
forkEndpoint,
&stateForkResponseJson,
@@ -757,7 +757,7 @@ func TestCheckDoppelGanger_Errors(t *testing.T) {
if testCase.getHeadersOutput != nil {
blockHeadersResponseJson := structs.GetBlockHeadersResponse{}
handler.EXPECT().Get(
jsonRestHandler.EXPECT().Get(
gomock.Any(),
headersEndpoint,
&blockHeadersResponseJson,
@@ -790,7 +790,7 @@ func TestCheckDoppelGanger_Errors(t *testing.T) {
marshalledIndexes, err := json.Marshal(iface.inputStringIndexes)
require.NoError(t, err)
handler.EXPECT().Post(
jsonRestHandler.EXPECT().Post(
gomock.Any(),
iface.inputUrl,
nil,
@@ -806,7 +806,7 @@ func TestCheckDoppelGanger_Errors(t *testing.T) {
}
validatorClient := beaconApiValidatorClient{
handler: handler,
jsonRestHandler: jsonRestHandler,
stateValidatorsProvider: stateValidatorsProvider,
}

View File

@@ -9,7 +9,6 @@ import (
"strconv"
"github.com/OffchainLabs/prysm/v7/api/apiutil"
"github.com/OffchainLabs/prysm/v7/api/rest"
"github.com/OffchainLabs/prysm/v7/api/server/structs"
"github.com/OffchainLabs/prysm/v7/config/params"
"github.com/OffchainLabs/prysm/v7/consensus-types/primitives"
@@ -28,7 +27,7 @@ type dutiesProvider interface {
}
type beaconApiDutiesProvider struct {
handler rest.Handler
jsonRestHandler RestHandler
}
type attesterDuty struct {
@@ -279,7 +278,7 @@ func (c beaconApiDutiesProvider) Committees(ctx context.Context, epoch primitive
committeesRequest := apiutil.BuildURL("/eth/v1/beacon/states/head/committees", committeeParams)
var stateCommittees structs.GetCommitteesResponse
if err := c.handler.Get(ctx, committeesRequest, &stateCommittees); err != nil {
if err := c.jsonRestHandler.Get(ctx, committeesRequest, &stateCommittees); err != nil {
return nil, err
}
@@ -309,7 +308,7 @@ func (c beaconApiDutiesProvider) AttesterDuties(ctx context.Context, epoch primi
}
attesterDuties := &structs.GetAttesterDutiesResponse{}
if err = c.handler.Post(
if err = c.jsonRestHandler.Post(
ctx,
fmt.Sprintf("/eth/v1/validator/duties/attester/%d", epoch),
nil,
@@ -331,7 +330,7 @@ func (c beaconApiDutiesProvider) AttesterDuties(ctx context.Context, epoch primi
// ProposerDuties retrieves the proposer duties for the given epoch
func (c beaconApiDutiesProvider) ProposerDuties(ctx context.Context, epoch primitives.Epoch) (*structs.GetProposerDutiesResponse, error) {
proposerDuties := &structs.GetProposerDutiesResponse{}
if err := c.handler.Get(ctx, fmt.Sprintf("/eth/v1/validator/duties/proposer/%d", epoch), proposerDuties); err != nil {
if err := c.jsonRestHandler.Get(ctx, fmt.Sprintf("/eth/v1/validator/duties/proposer/%d", epoch), proposerDuties); err != nil {
return nil, err
}
@@ -361,7 +360,7 @@ func (c beaconApiDutiesProvider) SyncDuties(ctx context.Context, epoch primitive
}
syncDuties := structs.GetSyncCommitteeDutiesResponse{}
if err = c.handler.Post(
if err = c.jsonRestHandler.Post(
ctx,
fmt.Sprintf("/eth/v1/validator/duties/sync/%d", epoch),
nil,

View File

@@ -60,8 +60,8 @@ func TestGetAttesterDuties_Valid(t *testing.T) {
ctx := t.Context()
validatorIndices := []primitives.ValidatorIndex{2, 9}
handler := mock.NewMockJsonRestHandler(ctrl)
handler.EXPECT().Post(
jsonRestHandler := mock.NewMockJsonRestHandler(ctrl)
jsonRestHandler.EXPECT().Post(
gomock.Any(),
fmt.Sprintf("%s/%d", getAttesterDutiesTestEndpoint, epoch),
nil,
@@ -74,7 +74,7 @@ func TestGetAttesterDuties_Valid(t *testing.T) {
expectedAttesterDuties,
).Times(1)
dutiesProvider := &beaconApiDutiesProvider{handler: handler}
dutiesProvider := &beaconApiDutiesProvider{jsonRestHandler: jsonRestHandler}
attesterDuties, err := dutiesProvider.AttesterDuties(ctx, epoch, validatorIndices)
require.NoError(t, err)
assert.DeepEqual(t, expectedAttesterDuties.Data, attesterDuties.Data)
@@ -88,8 +88,8 @@ func TestGetAttesterDuties_HttpError(t *testing.T) {
ctx := t.Context()
handler := mock.NewMockJsonRestHandler(ctrl)
handler.EXPECT().Post(
jsonRestHandler := mock.NewMockJsonRestHandler(ctrl)
jsonRestHandler.EXPECT().Post(
gomock.Any(),
fmt.Sprintf("%s/%d", getAttesterDutiesTestEndpoint, epoch),
gomock.Any(),
@@ -99,7 +99,7 @@ func TestGetAttesterDuties_HttpError(t *testing.T) {
errors.New("foo error"),
).Times(1)
dutiesProvider := &beaconApiDutiesProvider{handler: handler}
dutiesProvider := &beaconApiDutiesProvider{jsonRestHandler: jsonRestHandler}
_, err := dutiesProvider.AttesterDuties(ctx, epoch, nil)
assert.ErrorContains(t, "foo error", err)
}
@@ -112,8 +112,8 @@ func TestGetAttesterDuties_NilAttesterDuty(t *testing.T) {
ctx := t.Context()
handler := mock.NewMockJsonRestHandler(ctrl)
handler.EXPECT().Post(
jsonRestHandler := mock.NewMockJsonRestHandler(ctrl)
jsonRestHandler.EXPECT().Post(
gomock.Any(),
fmt.Sprintf("%s/%d", getAttesterDutiesTestEndpoint, epoch),
gomock.Any(),
@@ -128,7 +128,7 @@ func TestGetAttesterDuties_NilAttesterDuty(t *testing.T) {
},
).Times(1)
dutiesProvider := &beaconApiDutiesProvider{handler: handler}
dutiesProvider := &beaconApiDutiesProvider{jsonRestHandler: jsonRestHandler}
_, err := dutiesProvider.AttesterDuties(ctx, epoch, nil)
assert.ErrorContains(t, "attester duty at index `0` is nil", err)
}
@@ -156,8 +156,8 @@ func TestGetProposerDuties_Valid(t *testing.T) {
ctx := t.Context()
handler := mock.NewMockJsonRestHandler(ctrl)
handler.EXPECT().Get(
jsonRestHandler := mock.NewMockJsonRestHandler(ctrl)
jsonRestHandler.EXPECT().Get(
gomock.Any(),
fmt.Sprintf("%s/%d", getProposerDutiesTestEndpoint, epoch),
&structs.GetProposerDutiesResponse{},
@@ -168,7 +168,7 @@ func TestGetProposerDuties_Valid(t *testing.T) {
expectedProposerDuties,
).Times(1)
dutiesProvider := &beaconApiDutiesProvider{handler: handler}
dutiesProvider := &beaconApiDutiesProvider{jsonRestHandler: jsonRestHandler}
proposerDuties, err := dutiesProvider.ProposerDuties(ctx, epoch)
require.NoError(t, err)
assert.DeepEqual(t, expectedProposerDuties.Data, proposerDuties.Data)
@@ -182,8 +182,8 @@ func TestGetProposerDuties_HttpError(t *testing.T) {
ctx := t.Context()
handler := mock.NewMockJsonRestHandler(ctrl)
handler.EXPECT().Get(
jsonRestHandler := mock.NewMockJsonRestHandler(ctrl)
jsonRestHandler.EXPECT().Get(
gomock.Any(),
fmt.Sprintf("%s/%d", getProposerDutiesTestEndpoint, epoch),
gomock.Any(),
@@ -191,7 +191,7 @@ func TestGetProposerDuties_HttpError(t *testing.T) {
errors.New("foo error"),
).Times(1)
dutiesProvider := &beaconApiDutiesProvider{handler: handler}
dutiesProvider := &beaconApiDutiesProvider{jsonRestHandler: jsonRestHandler}
_, err := dutiesProvider.ProposerDuties(ctx, epoch)
assert.ErrorContains(t, "foo error", err)
}
@@ -204,8 +204,8 @@ func TestGetProposerDuties_NilData(t *testing.T) {
ctx := t.Context()
handler := mock.NewMockJsonRestHandler(ctrl)
handler.EXPECT().Get(
jsonRestHandler := mock.NewMockJsonRestHandler(ctrl)
jsonRestHandler.EXPECT().Get(
gomock.Any(),
fmt.Sprintf("%s/%d", getProposerDutiesTestEndpoint, epoch),
gomock.Any(),
@@ -218,7 +218,7 @@ func TestGetProposerDuties_NilData(t *testing.T) {
},
).Times(1)
dutiesProvider := &beaconApiDutiesProvider{handler: handler}
dutiesProvider := &beaconApiDutiesProvider{jsonRestHandler: jsonRestHandler}
_, err := dutiesProvider.ProposerDuties(ctx, epoch)
assert.ErrorContains(t, "proposer duties data is nil", err)
}
@@ -231,8 +231,8 @@ func TestGetProposerDuties_NilProposerDuty(t *testing.T) {
ctx := t.Context()
handler := mock.NewMockJsonRestHandler(ctrl)
handler.EXPECT().Get(
jsonRestHandler := mock.NewMockJsonRestHandler(ctrl)
jsonRestHandler.EXPECT().Get(
gomock.Any(),
fmt.Sprintf("%s/%d", getProposerDutiesTestEndpoint, epoch),
gomock.Any(),
@@ -245,7 +245,7 @@ func TestGetProposerDuties_NilProposerDuty(t *testing.T) {
},
).Times(1)
dutiesProvider := &beaconApiDutiesProvider{handler: handler}
dutiesProvider := &beaconApiDutiesProvider{jsonRestHandler: jsonRestHandler}
_, err := dutiesProvider.ProposerDuties(ctx, epoch)
assert.ErrorContains(t, "proposer duty at index `0` is nil", err)
}
@@ -284,8 +284,8 @@ func TestGetSyncDuties_Valid(t *testing.T) {
ctx := t.Context()
validatorIndices := []primitives.ValidatorIndex{2, 6}
handler := mock.NewMockJsonRestHandler(ctrl)
handler.EXPECT().Post(
jsonRestHandler := mock.NewMockJsonRestHandler(ctrl)
jsonRestHandler.EXPECT().Post(
gomock.Any(),
fmt.Sprintf("%s/%d", getSyncDutiesTestEndpoint, epoch),
nil,
@@ -298,7 +298,7 @@ func TestGetSyncDuties_Valid(t *testing.T) {
expectedSyncDuties,
).Times(1)
dutiesProvider := &beaconApiDutiesProvider{handler: handler}
dutiesProvider := &beaconApiDutiesProvider{jsonRestHandler: jsonRestHandler}
syncDuties, err := dutiesProvider.SyncDuties(ctx, epoch, validatorIndices)
require.NoError(t, err)
assert.DeepEqual(t, expectedSyncDuties.Data, syncDuties)
@@ -312,8 +312,8 @@ func TestGetSyncDuties_HttpError(t *testing.T) {
ctx := t.Context()
handler := mock.NewMockJsonRestHandler(ctrl)
handler.EXPECT().Post(
jsonRestHandler := mock.NewMockJsonRestHandler(ctrl)
jsonRestHandler.EXPECT().Post(
gomock.Any(),
fmt.Sprintf("%s/%d", getSyncDutiesTestEndpoint, epoch),
gomock.Any(),
@@ -323,7 +323,7 @@ func TestGetSyncDuties_HttpError(t *testing.T) {
errors.New("foo error"),
).Times(1)
dutiesProvider := &beaconApiDutiesProvider{handler: handler}
dutiesProvider := &beaconApiDutiesProvider{jsonRestHandler: jsonRestHandler}
_, err := dutiesProvider.SyncDuties(ctx, epoch, nil)
assert.ErrorContains(t, "foo error", err)
}
@@ -336,8 +336,8 @@ func TestGetSyncDuties_NilData(t *testing.T) {
ctx := t.Context()
handler := mock.NewMockJsonRestHandler(ctrl)
handler.EXPECT().Post(
jsonRestHandler := mock.NewMockJsonRestHandler(ctrl)
jsonRestHandler.EXPECT().Post(
gomock.Any(),
fmt.Sprintf("%s/%d", getSyncDutiesTestEndpoint, epoch),
gomock.Any(),
@@ -352,7 +352,7 @@ func TestGetSyncDuties_NilData(t *testing.T) {
},
).Times(1)
dutiesProvider := &beaconApiDutiesProvider{handler: handler}
dutiesProvider := &beaconApiDutiesProvider{jsonRestHandler: jsonRestHandler}
_, err := dutiesProvider.SyncDuties(ctx, epoch, nil)
assert.ErrorContains(t, "sync duties data is nil", err)
}
@@ -365,8 +365,8 @@ func TestGetSyncDuties_NilSyncDuty(t *testing.T) {
ctx := t.Context()
handler := mock.NewMockJsonRestHandler(ctrl)
handler.EXPECT().Post(
jsonRestHandler := mock.NewMockJsonRestHandler(ctrl)
jsonRestHandler.EXPECT().Post(
gomock.Any(),
fmt.Sprintf("%s/%d", getSyncDutiesTestEndpoint, epoch),
gomock.Any(),
@@ -381,7 +381,7 @@ func TestGetSyncDuties_NilSyncDuty(t *testing.T) {
},
).Times(1)
dutiesProvider := &beaconApiDutiesProvider{handler: handler}
dutiesProvider := &beaconApiDutiesProvider{jsonRestHandler: jsonRestHandler}
_, err := dutiesProvider.SyncDuties(ctx, epoch, nil)
assert.ErrorContains(t, "sync duty at index `0` is nil", err)
}
@@ -415,8 +415,8 @@ func TestGetCommittees_Valid(t *testing.T) {
ctx := t.Context()
handler := mock.NewMockJsonRestHandler(ctrl)
handler.EXPECT().Get(
jsonRestHandler := mock.NewMockJsonRestHandler(ctrl)
jsonRestHandler.EXPECT().Get(
gomock.Any(),
fmt.Sprintf("%s?epoch=%d", getCommitteesTestEndpoint, epoch),
&structs.GetCommitteesResponse{},
@@ -427,7 +427,7 @@ func TestGetCommittees_Valid(t *testing.T) {
expectedCommittees,
).Times(1)
dutiesProvider := &beaconApiDutiesProvider{handler: handler}
dutiesProvider := &beaconApiDutiesProvider{jsonRestHandler: jsonRestHandler}
committees, err := dutiesProvider.Committees(ctx, epoch)
require.NoError(t, err)
assert.DeepEqual(t, expectedCommittees.Data, committees)
@@ -441,8 +441,8 @@ func TestGetCommittees_HttpError(t *testing.T) {
ctx := t.Context()
handler := mock.NewMockJsonRestHandler(ctrl)
handler.EXPECT().Get(
jsonRestHandler := mock.NewMockJsonRestHandler(ctrl)
jsonRestHandler.EXPECT().Get(
gomock.Any(),
fmt.Sprintf("%s?epoch=%d", getCommitteesTestEndpoint, epoch),
gomock.Any(),
@@ -450,7 +450,7 @@ func TestGetCommittees_HttpError(t *testing.T) {
errors.New("foo error"),
).Times(1)
dutiesProvider := &beaconApiDutiesProvider{handler: handler}
dutiesProvider := &beaconApiDutiesProvider{jsonRestHandler: jsonRestHandler}
_, err := dutiesProvider.Committees(ctx, epoch)
assert.ErrorContains(t, "foo error", err)
}
@@ -463,8 +463,8 @@ func TestGetCommittees_NilData(t *testing.T) {
ctx := t.Context()
handler := mock.NewMockJsonRestHandler(ctrl)
handler.EXPECT().Get(
jsonRestHandler := mock.NewMockJsonRestHandler(ctrl)
jsonRestHandler.EXPECT().Get(
gomock.Any(),
fmt.Sprintf("%s?epoch=%d", getCommitteesTestEndpoint, epoch),
gomock.Any(),
@@ -477,7 +477,7 @@ func TestGetCommittees_NilData(t *testing.T) {
},
).Times(1)
dutiesProvider := &beaconApiDutiesProvider{handler: handler}
dutiesProvider := &beaconApiDutiesProvider{jsonRestHandler: jsonRestHandler}
_, err := dutiesProvider.Committees(ctx, epoch)
assert.ErrorContains(t, "state committees data is nil", err)
}
@@ -490,8 +490,8 @@ func TestGetCommittees_NilCommittee(t *testing.T) {
ctx := t.Context()
handler := mock.NewMockJsonRestHandler(ctrl)
handler.EXPECT().Get(
jsonRestHandler := mock.NewMockJsonRestHandler(ctrl)
jsonRestHandler.EXPECT().Get(
gomock.Any(),
fmt.Sprintf("%s?epoch=%d", getCommitteesTestEndpoint, epoch),
gomock.Any(),
@@ -504,7 +504,7 @@ func TestGetCommittees_NilCommittee(t *testing.T) {
},
).Times(1)
dutiesProvider := &beaconApiDutiesProvider{handler: handler}
dutiesProvider := &beaconApiDutiesProvider{jsonRestHandler: jsonRestHandler}
_, err := dutiesProvider.Committees(ctx, epoch)
assert.ErrorContains(t, "committee at index `0` is nil", err)
}

View File

@@ -7,7 +7,6 @@ import (
"sync"
"time"
"github.com/OffchainLabs/prysm/v7/api/rest"
"github.com/OffchainLabs/prysm/v7/api/server/structs"
fieldparams "github.com/OffchainLabs/prysm/v7/config/fieldparams"
"github.com/OffchainLabs/prysm/v7/encoding/bytesutil"
@@ -21,9 +20,9 @@ type GenesisProvider interface {
}
type beaconApiGenesisProvider struct {
handler rest.Handler
genesis *structs.Genesis
once sync.Once
jsonRestHandler RestHandler
genesis *structs.Genesis
once sync.Once
}
func (c *beaconApiValidatorClient) waitForChainStart(ctx context.Context) (*ethpb.ChainStartResponse, error) {
@@ -69,7 +68,7 @@ func (c *beaconApiGenesisProvider) Genesis(ctx context.Context) (*structs.Genesi
genesisJson := &structs.GetGenesisResponse{}
var doErr error
c.once.Do(func() {
if err := c.handler.Get(ctx, "/eth/v1/beacon/genesis", genesisJson); err != nil {
if err := c.jsonRestHandler.Get(ctx, "/eth/v1/beacon/genesis", genesisJson); err != nil {
doErr = err
return
}

View File

@@ -18,8 +18,8 @@ func TestGetGenesis_ValidGenesis(t *testing.T) {
ctx := t.Context()
genesisResponseJson := structs.GetGenesisResponse{}
handler := mock.NewMockJsonRestHandler(ctrl)
handler.EXPECT().Get(
jsonRestHandler := mock.NewMockJsonRestHandler(ctrl)
jsonRestHandler.EXPECT().Get(
gomock.Any(),
"/eth/v1/beacon/genesis",
&genesisResponseJson,
@@ -35,7 +35,7 @@ func TestGetGenesis_ValidGenesis(t *testing.T) {
},
).Times(1)
genesisProvider := &beaconApiGenesisProvider{handler: handler}
genesisProvider := &beaconApiGenesisProvider{jsonRestHandler: jsonRestHandler}
resp, err := genesisProvider.Genesis(ctx)
assert.NoError(t, err)
require.NotNil(t, resp)
@@ -50,8 +50,8 @@ func TestGetGenesis_NilData(t *testing.T) {
ctx := t.Context()
genesisResponseJson := structs.GetGenesisResponse{}
handler := mock.NewMockJsonRestHandler(ctrl)
handler.EXPECT().Get(
jsonRestHandler := mock.NewMockJsonRestHandler(ctrl)
jsonRestHandler.EXPECT().Get(
gomock.Any(),
"/eth/v1/beacon/genesis",
&genesisResponseJson,
@@ -62,7 +62,7 @@ func TestGetGenesis_NilData(t *testing.T) {
structs.GetGenesisResponse{Data: nil},
).Times(1)
genesisProvider := &beaconApiGenesisProvider{handler: handler}
genesisProvider := &beaconApiGenesisProvider{jsonRestHandler: jsonRestHandler}
_, err := genesisProvider.Genesis(ctx)
assert.ErrorContains(t, "genesis data is nil", err)
}
@@ -74,8 +74,8 @@ func TestGetGenesis_EndpointCalledOnlyOnce(t *testing.T) {
ctx := t.Context()
genesisResponseJson := structs.GetGenesisResponse{}
handler := mock.NewMockJsonRestHandler(ctrl)
handler.EXPECT().Get(
jsonRestHandler := mock.NewMockJsonRestHandler(ctrl)
jsonRestHandler.EXPECT().Get(
gomock.Any(),
"/eth/v1/beacon/genesis",
&genesisResponseJson,
@@ -91,7 +91,7 @@ func TestGetGenesis_EndpointCalledOnlyOnce(t *testing.T) {
},
).Times(1)
genesisProvider := &beaconApiGenesisProvider{handler: handler}
genesisProvider := &beaconApiGenesisProvider{jsonRestHandler: jsonRestHandler}
_, err := genesisProvider.Genesis(ctx)
assert.NoError(t, err)
resp, err := genesisProvider.Genesis(ctx)
@@ -108,15 +108,15 @@ func TestGetGenesis_EndpointCanBeCalledAgainAfterError(t *testing.T) {
ctx := t.Context()
genesisResponseJson := structs.GetGenesisResponse{}
handler := mock.NewMockJsonRestHandler(ctrl)
handler.EXPECT().Get(
jsonRestHandler := mock.NewMockJsonRestHandler(ctrl)
jsonRestHandler.EXPECT().Get(
gomock.Any(),
"/eth/v1/beacon/genesis",
&genesisResponseJson,
).Return(
errors.New("foo"),
).Times(1)
handler.EXPECT().Get(
jsonRestHandler.EXPECT().Get(
gomock.Any(),
"/eth/v1/beacon/genesis",
&genesisResponseJson,
@@ -132,7 +132,7 @@ func TestGetGenesis_EndpointCanBeCalledAgainAfterError(t *testing.T) {
},
).Times(1)
genesisProvider := &beaconApiGenesisProvider{handler: handler}
genesisProvider := &beaconApiGenesisProvider{jsonRestHandler: jsonRestHandler}
_, err := genesisProvider.Genesis(ctx)
require.ErrorContains(t, "foo", err)
resp, err := genesisProvider.Genesis(ctx)

View File

@@ -26,7 +26,7 @@ func (c *beaconApiValidatorClient) beaconBlock(ctx context.Context, slot primiti
queryParams.Add("graffiti", hexutil.Encode(graffiti))
}
queryUrl := apiutil.BuildURL(fmt.Sprintf("/eth/v3/validator/blocks/%d", slot), queryParams)
data, header, err := c.handler.GetSSZ(ctx, queryUrl)
data, header, err := c.jsonRestHandler.GetSSZ(ctx, queryUrl)
if err != nil {
return nil, err
}

View File

@@ -25,8 +25,8 @@ func TestGetBeaconBlock_RequestFailed(t *testing.T) {
ctx := t.Context()
handler := mock.NewMockJsonRestHandler(ctrl)
handler.EXPECT().GetSSZ(
jsonRestHandler := mock.NewMockJsonRestHandler(ctrl)
jsonRestHandler.EXPECT().GetSSZ(
gomock.Any(),
gomock.Any(),
).Return(
@@ -35,7 +35,7 @@ func TestGetBeaconBlock_RequestFailed(t *testing.T) {
errors.New("foo error"),
).Times(1)
validatorClient := &beaconApiValidatorClient{handler: handler}
validatorClient := &beaconApiValidatorClient{jsonRestHandler: jsonRestHandler}
_, err := validatorClient.beaconBlock(ctx, 1, []byte{1}, []byte{2})
assert.ErrorContains(t, "foo error", err)
}
@@ -149,8 +149,8 @@ func TestGetBeaconBlock_Error(t *testing.T) {
b, err := json.Marshal(resp)
require.NoError(t, err)
handler := mock.NewMockJsonRestHandler(ctrl)
handler.EXPECT().GetSSZ(
jsonRestHandler := mock.NewMockJsonRestHandler(ctrl)
jsonRestHandler.EXPECT().GetSSZ(
gomock.Any(),
gomock.Any(),
).Return(
@@ -159,7 +159,7 @@ func TestGetBeaconBlock_Error(t *testing.T) {
nil,
).Times(1)
validatorClient := &beaconApiValidatorClient{handler: handler}
validatorClient := &beaconApiValidatorClient{jsonRestHandler: jsonRestHandler}
_, err = validatorClient.beaconBlock(ctx, 1, []byte{1}, []byte{2})
assert.ErrorContains(t, testCase.expectedErrorMessage, err)
})
@@ -185,8 +185,8 @@ func TestGetBeaconBlock_Phase0Valid(t *testing.T) {
Data: bytes,
})
require.NoError(t, err)
handler := mock.NewMockJsonRestHandler(ctrl)
handler.EXPECT().GetSSZ(
jsonRestHandler := mock.NewMockJsonRestHandler(ctrl)
jsonRestHandler.EXPECT().GetSSZ(
gomock.Any(),
fmt.Sprintf("/eth/v3/validator/blocks/%d?graffiti=%s&randao_reveal=%s", slot, hexutil.Encode(graffiti), hexutil.Encode(randaoReveal)),
).Return(
@@ -195,7 +195,7 @@ func TestGetBeaconBlock_Phase0Valid(t *testing.T) {
nil,
).Times(1)
validatorClient := &beaconApiValidatorClient{handler: handler}
validatorClient := &beaconApiValidatorClient{jsonRestHandler: jsonRestHandler}
beaconBlock, err := validatorClient.beaconBlock(ctx, slot, randaoReveal, graffiti)
require.NoError(t, err)
@@ -224,8 +224,8 @@ func TestGetBeaconBlock_SSZ_BellatrixValid(t *testing.T) {
ctx := t.Context()
handler := mock.NewMockJsonRestHandler(ctrl)
handler.EXPECT().GetSSZ(
jsonRestHandler := mock.NewMockJsonRestHandler(ctrl)
jsonRestHandler.EXPECT().GetSSZ(
gomock.Any(),
fmt.Sprintf("/eth/v3/validator/blocks/%d?graffiti=%s&randao_reveal=%s", slot, hexutil.Encode(graffiti), hexutil.Encode(randaoReveal)),
).Return(
@@ -238,7 +238,7 @@ func TestGetBeaconBlock_SSZ_BellatrixValid(t *testing.T) {
nil,
).Times(1)
validatorClient := &beaconApiValidatorClient{handler: handler}
validatorClient := &beaconApiValidatorClient{jsonRestHandler: jsonRestHandler}
beaconBlock, err := validatorClient.beaconBlock(ctx, slot, randaoReveal, graffiti)
require.NoError(t, err)
@@ -266,8 +266,8 @@ func TestGetBeaconBlock_SSZ_BlindedBellatrixValid(t *testing.T) {
ctx := t.Context()
handler := mock.NewMockJsonRestHandler(ctrl)
handler.EXPECT().GetSSZ(
jsonRestHandler := mock.NewMockJsonRestHandler(ctrl)
jsonRestHandler.EXPECT().GetSSZ(
gomock.Any(),
fmt.Sprintf("/eth/v3/validator/blocks/%d?graffiti=%s&randao_reveal=%s", slot, hexutil.Encode(graffiti), hexutil.Encode(randaoReveal)),
).Return(
@@ -280,7 +280,7 @@ func TestGetBeaconBlock_SSZ_BlindedBellatrixValid(t *testing.T) {
nil,
).Times(1)
validatorClient := &beaconApiValidatorClient{handler: handler}
validatorClient := &beaconApiValidatorClient{jsonRestHandler: jsonRestHandler}
beaconBlock, err := validatorClient.beaconBlock(ctx, slot, randaoReveal, graffiti)
require.NoError(t, err)
@@ -308,8 +308,8 @@ func TestGetBeaconBlock_SSZ_CapellaValid(t *testing.T) {
ctx := t.Context()
handler := mock.NewMockJsonRestHandler(ctrl)
handler.EXPECT().GetSSZ(
jsonRestHandler := mock.NewMockJsonRestHandler(ctrl)
jsonRestHandler.EXPECT().GetSSZ(
gomock.Any(),
fmt.Sprintf("/eth/v3/validator/blocks/%d?graffiti=%s&randao_reveal=%s", slot, hexutil.Encode(graffiti), hexutil.Encode(randaoReveal)),
).Return(
@@ -322,7 +322,7 @@ func TestGetBeaconBlock_SSZ_CapellaValid(t *testing.T) {
nil,
).Times(1)
validatorClient := &beaconApiValidatorClient{handler: handler}
validatorClient := &beaconApiValidatorClient{jsonRestHandler: jsonRestHandler}
beaconBlock, err := validatorClient.beaconBlock(ctx, slot, randaoReveal, graffiti)
require.NoError(t, err)
@@ -350,8 +350,8 @@ func TestGetBeaconBlock_SSZ_BlindedCapellaValid(t *testing.T) {
ctx := t.Context()
handler := mock.NewMockJsonRestHandler(ctrl)
handler.EXPECT().GetSSZ(
jsonRestHandler := mock.NewMockJsonRestHandler(ctrl)
jsonRestHandler.EXPECT().GetSSZ(
gomock.Any(),
fmt.Sprintf("/eth/v3/validator/blocks/%d?graffiti=%s&randao_reveal=%s", slot, hexutil.Encode(graffiti), hexutil.Encode(randaoReveal)),
).Return(
@@ -364,7 +364,7 @@ func TestGetBeaconBlock_SSZ_BlindedCapellaValid(t *testing.T) {
nil,
).Times(1)
validatorClient := &beaconApiValidatorClient{handler: handler}
validatorClient := &beaconApiValidatorClient{jsonRestHandler: jsonRestHandler}
beaconBlock, err := validatorClient.beaconBlock(ctx, slot, randaoReveal, graffiti)
require.NoError(t, err)
@@ -392,8 +392,8 @@ func TestGetBeaconBlock_SSZ_DenebValid(t *testing.T) {
ctx := t.Context()
handler := mock.NewMockJsonRestHandler(ctrl)
handler.EXPECT().GetSSZ(
jsonRestHandler := mock.NewMockJsonRestHandler(ctrl)
jsonRestHandler.EXPECT().GetSSZ(
gomock.Any(),
fmt.Sprintf("/eth/v3/validator/blocks/%d?graffiti=%s&randao_reveal=%s", slot, hexutil.Encode(graffiti), hexutil.Encode(randaoReveal)),
).Return(
@@ -406,7 +406,7 @@ func TestGetBeaconBlock_SSZ_DenebValid(t *testing.T) {
nil,
).Times(1)
validatorClient := &beaconApiValidatorClient{handler: handler}
validatorClient := &beaconApiValidatorClient{jsonRestHandler: jsonRestHandler}
beaconBlock, err := validatorClient.beaconBlock(ctx, slot, randaoReveal, graffiti)
require.NoError(t, err)
@@ -434,8 +434,8 @@ func TestGetBeaconBlock_SSZ_BlindedDenebValid(t *testing.T) {
ctx := t.Context()
handler := mock.NewMockJsonRestHandler(ctrl)
handler.EXPECT().GetSSZ(
jsonRestHandler := mock.NewMockJsonRestHandler(ctrl)
jsonRestHandler.EXPECT().GetSSZ(
gomock.Any(),
fmt.Sprintf("/eth/v3/validator/blocks/%d?graffiti=%s&randao_reveal=%s", slot, hexutil.Encode(graffiti), hexutil.Encode(randaoReveal)),
).Return(
@@ -448,7 +448,7 @@ func TestGetBeaconBlock_SSZ_BlindedDenebValid(t *testing.T) {
nil,
).Times(1)
validatorClient := &beaconApiValidatorClient{handler: handler}
validatorClient := &beaconApiValidatorClient{jsonRestHandler: jsonRestHandler}
beaconBlock, err := validatorClient.beaconBlock(ctx, slot, randaoReveal, graffiti)
require.NoError(t, err)
@@ -476,8 +476,8 @@ func TestGetBeaconBlock_SSZ_ElectraValid(t *testing.T) {
ctx := t.Context()
handler := mock.NewMockJsonRestHandler(ctrl)
handler.EXPECT().GetSSZ(
jsonRestHandler := mock.NewMockJsonRestHandler(ctrl)
jsonRestHandler.EXPECT().GetSSZ(
gomock.Any(),
fmt.Sprintf("/eth/v3/validator/blocks/%d?graffiti=%s&randao_reveal=%s", slot, hexutil.Encode(graffiti), hexutil.Encode(randaoReveal)),
).Return(
@@ -490,7 +490,7 @@ func TestGetBeaconBlock_SSZ_ElectraValid(t *testing.T) {
nil,
).Times(1)
validatorClient := &beaconApiValidatorClient{handler: handler}
validatorClient := &beaconApiValidatorClient{jsonRestHandler: jsonRestHandler}
beaconBlock, err := validatorClient.beaconBlock(ctx, slot, randaoReveal, graffiti)
require.NoError(t, err)
@@ -518,8 +518,8 @@ func TestGetBeaconBlock_SSZ_BlindedElectraValid(t *testing.T) {
ctx := t.Context()
handler := mock.NewMockJsonRestHandler(ctrl)
handler.EXPECT().GetSSZ(
jsonRestHandler := mock.NewMockJsonRestHandler(ctrl)
jsonRestHandler.EXPECT().GetSSZ(
gomock.Any(),
fmt.Sprintf("/eth/v3/validator/blocks/%d?graffiti=%s&randao_reveal=%s", slot, hexutil.Encode(graffiti), hexutil.Encode(randaoReveal)),
).Return(
@@ -532,7 +532,7 @@ func TestGetBeaconBlock_SSZ_BlindedElectraValid(t *testing.T) {
nil,
).Times(1)
validatorClient := &beaconApiValidatorClient{handler: handler}
validatorClient := &beaconApiValidatorClient{jsonRestHandler: jsonRestHandler}
beaconBlock, err := validatorClient.beaconBlock(ctx, slot, randaoReveal, graffiti)
require.NoError(t, err)
@@ -556,8 +556,8 @@ func TestGetBeaconBlock_SSZ_UnsupportedVersion(t *testing.T) {
ctx := t.Context()
handler := mock.NewMockJsonRestHandler(ctrl)
handler.EXPECT().GetSSZ(
jsonRestHandler := mock.NewMockJsonRestHandler(ctrl)
jsonRestHandler.EXPECT().GetSSZ(
gomock.Any(),
fmt.Sprintf("/eth/v3/validator/blocks/%d?graffiti=%s&randao_reveal=%s", slot, hexutil.Encode(graffiti), hexutil.Encode(randaoReveal)),
).Return(
@@ -570,7 +570,7 @@ func TestGetBeaconBlock_SSZ_UnsupportedVersion(t *testing.T) {
nil,
).Times(1)
validatorClient := &beaconApiValidatorClient{handler: handler}
validatorClient := &beaconApiValidatorClient{jsonRestHandler: jsonRestHandler}
_, err := validatorClient.beaconBlock(ctx, slot, randaoReveal, graffiti)
assert.ErrorContains(t, "version name doesn't map to a known value in the enum", err)
}
@@ -589,8 +589,8 @@ func TestGetBeaconBlock_SSZ_InvalidBlindedHeader(t *testing.T) {
ctx := t.Context()
handler := mock.NewMockJsonRestHandler(ctrl)
handler.EXPECT().GetSSZ(
jsonRestHandler := mock.NewMockJsonRestHandler(ctrl)
jsonRestHandler.EXPECT().GetSSZ(
gomock.Any(),
fmt.Sprintf("/eth/v3/validator/blocks/%d?graffiti=%s&randao_reveal=%s", slot, hexutil.Encode(graffiti), hexutil.Encode(randaoReveal)),
).Return(
@@ -603,7 +603,7 @@ func TestGetBeaconBlock_SSZ_InvalidBlindedHeader(t *testing.T) {
nil,
).Times(1)
validatorClient := &beaconApiValidatorClient{handler: handler}
validatorClient := &beaconApiValidatorClient{jsonRestHandler: jsonRestHandler}
_, err = validatorClient.beaconBlock(ctx, slot, randaoReveal, graffiti)
assert.ErrorContains(t, "strconv.ParseBool: parsing \"invalid\": invalid syntax", err)
}
@@ -622,8 +622,8 @@ func TestGetBeaconBlock_SSZ_InvalidVersionHeader(t *testing.T) {
ctx := t.Context()
handler := mock.NewMockJsonRestHandler(ctrl)
handler.EXPECT().GetSSZ(
jsonRestHandler := mock.NewMockJsonRestHandler(ctrl)
jsonRestHandler.EXPECT().GetSSZ(
gomock.Any(),
fmt.Sprintf("/eth/v3/validator/blocks/%d?graffiti=%s&randao_reveal=%s", slot, hexutil.Encode(graffiti), hexutil.Encode(randaoReveal)),
).Return(
@@ -636,7 +636,7 @@ func TestGetBeaconBlock_SSZ_InvalidVersionHeader(t *testing.T) {
nil,
).Times(1)
validatorClient := &beaconApiValidatorClient{handler: handler}
validatorClient := &beaconApiValidatorClient{jsonRestHandler: jsonRestHandler}
_, err = validatorClient.beaconBlock(ctx, slot, randaoReveal, graffiti)
assert.ErrorContains(t, "unsupported header version invalid", err)
}
@@ -651,8 +651,8 @@ func TestGetBeaconBlock_SSZ_GetSSZError(t *testing.T) {
ctx := t.Context()
handler := mock.NewMockJsonRestHandler(ctrl)
handler.EXPECT().GetSSZ(
jsonRestHandler := mock.NewMockJsonRestHandler(ctrl)
jsonRestHandler.EXPECT().GetSSZ(
gomock.Any(),
fmt.Sprintf("/eth/v3/validator/blocks/%d?graffiti=%s&randao_reveal=%s", slot, hexutil.Encode(graffiti), hexutil.Encode(randaoReveal)),
).Return(
@@ -661,7 +661,7 @@ func TestGetBeaconBlock_SSZ_GetSSZError(t *testing.T) {
errors.New("get ssz error"),
).Times(1)
validatorClient := &beaconApiValidatorClient{handler: handler}
validatorClient := &beaconApiValidatorClient{jsonRestHandler: jsonRestHandler}
_, err := validatorClient.beaconBlock(ctx, slot, randaoReveal, graffiti)
assert.ErrorContains(t, "get ssz error", err)
}
@@ -680,8 +680,8 @@ func TestGetBeaconBlock_SSZ_Phase0Valid(t *testing.T) {
ctx := t.Context()
handler := mock.NewMockJsonRestHandler(ctrl)
handler.EXPECT().GetSSZ(
jsonRestHandler := mock.NewMockJsonRestHandler(ctrl)
jsonRestHandler.EXPECT().GetSSZ(
gomock.Any(),
fmt.Sprintf("/eth/v3/validator/blocks/%d?graffiti=%s&randao_reveal=%s", slot, hexutil.Encode(graffiti), hexutil.Encode(randaoReveal)),
).Return(
@@ -694,7 +694,7 @@ func TestGetBeaconBlock_SSZ_Phase0Valid(t *testing.T) {
nil,
).Times(1)
validatorClient := &beaconApiValidatorClient{handler: handler}
validatorClient := &beaconApiValidatorClient{jsonRestHandler: jsonRestHandler}
beaconBlock, err := validatorClient.beaconBlock(ctx, slot, randaoReveal, graffiti)
require.NoError(t, err)
@@ -722,8 +722,8 @@ func TestGetBeaconBlock_SSZ_AltairValid(t *testing.T) {
ctx := t.Context()
handler := mock.NewMockJsonRestHandler(ctrl)
handler.EXPECT().GetSSZ(
jsonRestHandler := mock.NewMockJsonRestHandler(ctrl)
jsonRestHandler.EXPECT().GetSSZ(
gomock.Any(),
fmt.Sprintf("/eth/v3/validator/blocks/%d?graffiti=%s&randao_reveal=%s", slot, hexutil.Encode(graffiti), hexutil.Encode(randaoReveal)),
).Return(
@@ -736,7 +736,7 @@ func TestGetBeaconBlock_SSZ_AltairValid(t *testing.T) {
nil,
).Times(1)
validatorClient := &beaconApiValidatorClient{handler: handler}
validatorClient := &beaconApiValidatorClient{jsonRestHandler: jsonRestHandler}
beaconBlock, err := validatorClient.beaconBlock(ctx, slot, randaoReveal, graffiti)
require.NoError(t, err)
@@ -770,8 +770,8 @@ func TestGetBeaconBlock_AltairValid(t *testing.T) {
Data: bytes,
})
require.NoError(t, err)
handler := mock.NewMockJsonRestHandler(ctrl)
handler.EXPECT().GetSSZ(
jsonRestHandler := mock.NewMockJsonRestHandler(ctrl)
jsonRestHandler.EXPECT().GetSSZ(
gomock.Any(),
fmt.Sprintf("/eth/v3/validator/blocks/%d?graffiti=%s&randao_reveal=%s", slot, hexutil.Encode(graffiti), hexutil.Encode(randaoReveal)),
).Return(
@@ -780,7 +780,7 @@ func TestGetBeaconBlock_AltairValid(t *testing.T) {
nil,
).Times(1)
validatorClient := &beaconApiValidatorClient{handler: handler}
validatorClient := &beaconApiValidatorClient{jsonRestHandler: jsonRestHandler}
beaconBlock, err := validatorClient.beaconBlock(ctx, slot, randaoReveal, graffiti)
require.NoError(t, err)
@@ -814,8 +814,8 @@ func TestGetBeaconBlock_BellatrixValid(t *testing.T) {
Data: bytes,
})
require.NoError(t, err)
handler := mock.NewMockJsonRestHandler(ctrl)
handler.EXPECT().GetSSZ(
jsonRestHandler := mock.NewMockJsonRestHandler(ctrl)
jsonRestHandler.EXPECT().GetSSZ(
gomock.Any(),
fmt.Sprintf("/eth/v3/validator/blocks/%d?graffiti=%s&randao_reveal=%s", slot, hexutil.Encode(graffiti), hexutil.Encode(randaoReveal)),
).Return(
@@ -824,7 +824,7 @@ func TestGetBeaconBlock_BellatrixValid(t *testing.T) {
nil,
).Times(1)
validatorClient := &beaconApiValidatorClient{handler: handler}
validatorClient := &beaconApiValidatorClient{jsonRestHandler: jsonRestHandler}
beaconBlock, err := validatorClient.beaconBlock(ctx, slot, randaoReveal, graffiti)
require.NoError(t, err)
@@ -859,8 +859,8 @@ func TestGetBeaconBlock_BlindedBellatrixValid(t *testing.T) {
Data: bytes,
})
require.NoError(t, err)
handler := mock.NewMockJsonRestHandler(ctrl)
handler.EXPECT().GetSSZ(
jsonRestHandler := mock.NewMockJsonRestHandler(ctrl)
jsonRestHandler.EXPECT().GetSSZ(
gomock.Any(),
fmt.Sprintf("/eth/v3/validator/blocks/%d?graffiti=%s&randao_reveal=%s", slot, hexutil.Encode(graffiti), hexutil.Encode(randaoReveal)),
).Return(
@@ -869,7 +869,7 @@ func TestGetBeaconBlock_BlindedBellatrixValid(t *testing.T) {
nil,
).Times(1)
validatorClient := &beaconApiValidatorClient{handler: handler}
validatorClient := &beaconApiValidatorClient{jsonRestHandler: jsonRestHandler}
beaconBlock, err := validatorClient.beaconBlock(ctx, slot, randaoReveal, graffiti)
require.NoError(t, err)
@@ -904,8 +904,8 @@ func TestGetBeaconBlock_CapellaValid(t *testing.T) {
Data: bytes,
})
require.NoError(t, err)
handler := mock.NewMockJsonRestHandler(ctrl)
handler.EXPECT().GetSSZ(
jsonRestHandler := mock.NewMockJsonRestHandler(ctrl)
jsonRestHandler.EXPECT().GetSSZ(
gomock.Any(),
fmt.Sprintf("/eth/v3/validator/blocks/%d?graffiti=%s&randao_reveal=%s", slot, hexutil.Encode(graffiti), hexutil.Encode(randaoReveal)),
).Return(
@@ -914,7 +914,7 @@ func TestGetBeaconBlock_CapellaValid(t *testing.T) {
nil,
).Times(1)
validatorClient := &beaconApiValidatorClient{handler: handler}
validatorClient := &beaconApiValidatorClient{jsonRestHandler: jsonRestHandler}
beaconBlock, err := validatorClient.beaconBlock(ctx, slot, randaoReveal, graffiti)
require.NoError(t, err)
@@ -949,8 +949,8 @@ func TestGetBeaconBlock_BlindedCapellaValid(t *testing.T) {
Data: bytes,
})
require.NoError(t, err)
handler := mock.NewMockJsonRestHandler(ctrl)
handler.EXPECT().GetSSZ(
jsonRestHandler := mock.NewMockJsonRestHandler(ctrl)
jsonRestHandler.EXPECT().GetSSZ(
gomock.Any(),
fmt.Sprintf("/eth/v3/validator/blocks/%d?graffiti=%s&randao_reveal=%s", slot, hexutil.Encode(graffiti), hexutil.Encode(randaoReveal)),
).Return(
@@ -959,7 +959,7 @@ func TestGetBeaconBlock_BlindedCapellaValid(t *testing.T) {
nil,
).Times(1)
validatorClient := &beaconApiValidatorClient{handler: handler}
validatorClient := &beaconApiValidatorClient{jsonRestHandler: jsonRestHandler}
beaconBlock, err := validatorClient.beaconBlock(ctx, slot, randaoReveal, graffiti)
require.NoError(t, err)
@@ -994,8 +994,8 @@ func TestGetBeaconBlock_DenebValid(t *testing.T) {
Data: bytes,
})
require.NoError(t, err)
handler := mock.NewMockJsonRestHandler(ctrl)
handler.EXPECT().GetSSZ(
jsonRestHandler := mock.NewMockJsonRestHandler(ctrl)
jsonRestHandler.EXPECT().GetSSZ(
gomock.Any(),
fmt.Sprintf("/eth/v3/validator/blocks/%d?graffiti=%s&randao_reveal=%s", slot, hexutil.Encode(graffiti), hexutil.Encode(randaoReveal)),
).Return(
@@ -1004,7 +1004,7 @@ func TestGetBeaconBlock_DenebValid(t *testing.T) {
nil,
).Times(1)
validatorClient := &beaconApiValidatorClient{handler: handler}
validatorClient := &beaconApiValidatorClient{jsonRestHandler: jsonRestHandler}
beaconBlock, err := validatorClient.beaconBlock(ctx, slot, randaoReveal, graffiti)
require.NoError(t, err)
@@ -1039,8 +1039,8 @@ func TestGetBeaconBlock_BlindedDenebValid(t *testing.T) {
Data: bytes,
})
require.NoError(t, err)
handler := mock.NewMockJsonRestHandler(ctrl)
handler.EXPECT().GetSSZ(
jsonRestHandler := mock.NewMockJsonRestHandler(ctrl)
jsonRestHandler.EXPECT().GetSSZ(
gomock.Any(),
fmt.Sprintf("/eth/v3/validator/blocks/%d?graffiti=%s&randao_reveal=%s", slot, hexutil.Encode(graffiti), hexutil.Encode(randaoReveal)),
).Return(
@@ -1049,7 +1049,7 @@ func TestGetBeaconBlock_BlindedDenebValid(t *testing.T) {
nil,
).Times(1)
validatorClient := &beaconApiValidatorClient{handler: handler}
validatorClient := &beaconApiValidatorClient{jsonRestHandler: jsonRestHandler}
beaconBlock, err := validatorClient.beaconBlock(ctx, slot, randaoReveal, graffiti)
require.NoError(t, err)
@@ -1084,8 +1084,8 @@ func TestGetBeaconBlock_ElectraValid(t *testing.T) {
Data: bytes,
})
require.NoError(t, err)
handler := mock.NewMockJsonRestHandler(ctrl)
handler.EXPECT().GetSSZ(
jsonRestHandler := mock.NewMockJsonRestHandler(ctrl)
jsonRestHandler.EXPECT().GetSSZ(
gomock.Any(),
fmt.Sprintf("/eth/v3/validator/blocks/%d?graffiti=%s&randao_reveal=%s", slot, hexutil.Encode(graffiti), hexutil.Encode(randaoReveal)),
).Return(
@@ -1094,7 +1094,7 @@ func TestGetBeaconBlock_ElectraValid(t *testing.T) {
nil,
).Times(1)
validatorClient := &beaconApiValidatorClient{handler: handler}
validatorClient := &beaconApiValidatorClient{jsonRestHandler: jsonRestHandler}
beaconBlock, err := validatorClient.beaconBlock(ctx, slot, randaoReveal, graffiti)
require.NoError(t, err)
@@ -1129,8 +1129,8 @@ func TestGetBeaconBlock_BlindedElectraValid(t *testing.T) {
Data: bytes,
})
require.NoError(t, err)
handler := mock.NewMockJsonRestHandler(ctrl)
handler.EXPECT().GetSSZ(
jsonRestHandler := mock.NewMockJsonRestHandler(ctrl)
jsonRestHandler.EXPECT().GetSSZ(
gomock.Any(),
fmt.Sprintf("/eth/v3/validator/blocks/%d?graffiti=%s&randao_reveal=%s", slot, hexutil.Encode(graffiti), hexutil.Encode(randaoReveal)),
).Return(
@@ -1139,7 +1139,7 @@ func TestGetBeaconBlock_BlindedElectraValid(t *testing.T) {
nil,
).Times(1)
validatorClient := &beaconApiValidatorClient{handler: handler}
validatorClient := &beaconApiValidatorClient{jsonRestHandler: jsonRestHandler}
beaconBlock, err := validatorClient.beaconBlock(ctx, slot, randaoReveal, graffiti)
require.NoError(t, err)

View File

@@ -41,9 +41,9 @@ func TestIndex_Nominal(t *testing.T) {
ctx := t.Context()
stateValidatorsResponseJson := structs.GetValidatorsResponse{}
handler := mock.NewMockJsonRestHandler(ctrl)
jsonRestHandler := mock.NewMockJsonRestHandler(ctrl)
handler.EXPECT().Post(
jsonRestHandler.EXPECT().Post(
gomock.Any(),
"/eth/v1/beacon/states/head/validators",
nil,
@@ -68,7 +68,7 @@ func TestIndex_Nominal(t *testing.T) {
validatorClient := beaconApiValidatorClient{
stateValidatorsProvider: beaconApiStateValidatorsProvider{
handler: handler,
jsonRestHandler: jsonRestHandler,
},
}
@@ -91,9 +91,9 @@ func TestIndex_UnexistingValidator(t *testing.T) {
ctx := t.Context()
stateValidatorsResponseJson := structs.GetValidatorsResponse{}
handler := mock.NewMockJsonRestHandler(ctrl)
jsonRestHandler := mock.NewMockJsonRestHandler(ctrl)
handler.EXPECT().Post(
jsonRestHandler.EXPECT().Post(
gomock.Any(),
"/eth/v1/beacon/states/head/validators",
nil,
@@ -110,7 +110,7 @@ func TestIndex_UnexistingValidator(t *testing.T) {
validatorClient := beaconApiValidatorClient{
stateValidatorsProvider: beaconApiStateValidatorsProvider{
handler: handler,
jsonRestHandler: jsonRestHandler,
},
}
@@ -133,9 +133,9 @@ func TestIndex_BadIndexError(t *testing.T) {
ctx := t.Context()
stateValidatorsResponseJson := structs.GetValidatorsResponse{}
handler := mock.NewMockJsonRestHandler(ctrl)
jsonRestHandler := mock.NewMockJsonRestHandler(ctrl)
handler.EXPECT().Post(
jsonRestHandler.EXPECT().Post(
gomock.Any(),
"/eth/v1/beacon/states/head/validators",
nil,
@@ -160,7 +160,7 @@ func TestIndex_BadIndexError(t *testing.T) {
validatorClient := beaconApiValidatorClient{
stateValidatorsProvider: beaconApiStateValidatorsProvider{
handler: handler,
jsonRestHandler: jsonRestHandler,
},
}
@@ -182,9 +182,9 @@ func TestIndex_JsonResponseError(t *testing.T) {
ctx := t.Context()
stateValidatorsResponseJson := structs.GetValidatorsResponse{}
handler := mock.NewMockJsonRestHandler(ctrl)
jsonRestHandler := mock.NewMockJsonRestHandler(ctrl)
handler.EXPECT().Post(
jsonRestHandler.EXPECT().Post(
gomock.Any(),
"/eth/v1/beacon/states/head/validators",
nil,
@@ -207,7 +207,7 @@ func TestIndex_JsonResponseError(t *testing.T) {
queryParams.Add("status", st)
}
handler.EXPECT().Get(
jsonRestHandler.EXPECT().Get(
gomock.Any(),
apiutil.BuildURL("/eth/v1/beacon/states/head/validators", queryParams),
&stateValidatorsResponseJson,
@@ -217,7 +217,7 @@ func TestIndex_JsonResponseError(t *testing.T) {
validatorClient := beaconApiValidatorClient{
stateValidatorsProvider: beaconApiStateValidatorsProvider{
handler: handler,
jsonRestHandler: jsonRestHandler,
},
}

View File

@@ -1,9 +1,9 @@
// Code generated by MockGen. DO NOT EDIT.
// Source: api/rest/rest_handler.go
// Source: validator/client/beacon-api/rest_handler_client.go
//
// Generated by this command:
//
// mockgen -package=mock -source=api/rest/rest_handler.go -destination=validator/client/beacon-api/mock/json_rest_handler_mock.go Handler
// mockgen -package=mock -source=validator/client/beacon-api/rest_handler_client.go -destination=validator/client/beacon-api/mock/json_rest_handler_mock.go RestHandler
//
// Package mock is a generated GoMock package.
@@ -19,39 +19,36 @@ import (
)
// Backward compatibility aliases for the renamed mock type.
type MockJsonRestHandler = MockHandler
type MockJsonRestHandlerMockRecorder = MockHandlerMockRecorder
type MockRestHandler = MockHandler
type MockRestHandlerMockRecorder = MockHandlerMockRecorder
type MockJsonRestHandler = MockRestHandler
type MockJsonRestHandlerMockRecorder = MockRestHandlerMockRecorder
var NewMockJsonRestHandler = NewMockHandler
var NewMockRestHandler = NewMockHandler
var NewMockJsonRestHandler = NewMockRestHandler
// MockHandler is a mock of Handler interface.
type MockHandler struct {
// MockRestHandler is a mock of RestHandler interface.
type MockRestHandler struct {
ctrl *gomock.Controller
recorder *MockHandlerMockRecorder
recorder *MockRestHandlerMockRecorder
}
// MockHandlerMockRecorder is the mock recorder for MockHandler.
type MockHandlerMockRecorder struct {
mock *MockHandler
// MockRestHandlerMockRecorder is the mock recorder for MockRestHandler.
type MockRestHandlerMockRecorder struct {
mock *MockRestHandler
}
// NewMockHandler creates a new mock instance.
func NewMockHandler(ctrl *gomock.Controller) *MockHandler {
mock := &MockHandler{ctrl: ctrl}
mock.recorder = &MockHandlerMockRecorder{mock}
// NewMockRestHandler creates a new mock instance.
func NewMockRestHandler(ctrl *gomock.Controller) *MockRestHandler {
mock := &MockRestHandler{ctrl: ctrl}
mock.recorder = &MockRestHandlerMockRecorder{mock}
return mock
}
// EXPECT returns an object that allows the caller to indicate expected use.
func (m *MockHandler) EXPECT() *MockHandlerMockRecorder {
func (m *MockRestHandler) EXPECT() *MockRestHandlerMockRecorder {
return m.recorder
}
// Get mocks base method.
func (m *MockHandler) Get(ctx context.Context, endpoint string, resp any) error {
func (m *MockRestHandler) Get(ctx context.Context, endpoint string, resp any) error {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "Get", ctx, endpoint, resp)
ret0, _ := ret[0].(error)
@@ -59,13 +56,13 @@ func (m *MockHandler) Get(ctx context.Context, endpoint string, resp any) error
}
// Get indicates an expected call of Get.
func (mr *MockHandlerMockRecorder) Get(ctx, endpoint, resp any) *gomock.Call {
func (mr *MockRestHandlerMockRecorder) Get(ctx, endpoint, resp any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Get", reflect.TypeOf((*MockHandler)(nil).Get), ctx, endpoint, resp)
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Get", reflect.TypeOf((*MockRestHandler)(nil).Get), ctx, endpoint, resp)
}
// GetSSZ mocks base method.
func (m *MockHandler) GetSSZ(ctx context.Context, endpoint string) ([]byte, http.Header, error) {
func (m *MockRestHandler) GetSSZ(ctx context.Context, endpoint string) ([]byte, http.Header, error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "GetSSZ", ctx, endpoint)
ret0, _ := ret[0].([]byte)
@@ -75,13 +72,13 @@ func (m *MockHandler) GetSSZ(ctx context.Context, endpoint string) ([]byte, http
}
// GetSSZ indicates an expected call of GetSSZ.
func (mr *MockHandlerMockRecorder) GetSSZ(ctx, endpoint any) *gomock.Call {
func (mr *MockRestHandlerMockRecorder) GetSSZ(ctx, endpoint any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetSSZ", reflect.TypeOf((*MockHandler)(nil).GetSSZ), ctx, endpoint)
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetSSZ", reflect.TypeOf((*MockRestHandler)(nil).GetSSZ), ctx, endpoint)
}
// GetStatusCode mocks base method.
func (m *MockHandler) GetStatusCode(ctx context.Context, endpoint string) (int, error) {
func (m *MockRestHandler) GetStatusCode(ctx context.Context, endpoint string) (int, error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "GetStatusCode", ctx, endpoint)
ret0, _ := ret[0].(int)
@@ -90,13 +87,13 @@ func (m *MockHandler) GetStatusCode(ctx context.Context, endpoint string) (int,
}
// GetStatusCode indicates an expected call of GetStatusCode.
func (mr *MockHandlerMockRecorder) GetStatusCode(ctx, endpoint any) *gomock.Call {
func (mr *MockRestHandlerMockRecorder) GetStatusCode(ctx, endpoint any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetStatusCode", reflect.TypeOf((*MockHandler)(nil).GetStatusCode), ctx, endpoint)
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetStatusCode", reflect.TypeOf((*MockRestHandler)(nil).GetStatusCode), ctx, endpoint)
}
// Host mocks base method.
func (m *MockHandler) Host() string {
func (m *MockRestHandler) Host() string {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "Host")
ret0, _ := ret[0].(string)
@@ -104,13 +101,27 @@ func (m *MockHandler) Host() string {
}
// Host indicates an expected call of Host.
func (mr *MockHandlerMockRecorder) Host() *gomock.Call {
func (mr *MockRestHandlerMockRecorder) Host() *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Host", reflect.TypeOf((*MockHandler)(nil).Host))
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Host", reflect.TypeOf((*MockRestHandler)(nil).Host))
}
// HttpClient mocks base method.
func (m *MockRestHandler) HttpClient() *http.Client {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "HttpClient")
ret0, _ := ret[0].(*http.Client)
return ret0
}
// HttpClient indicates an expected call of HttpClient.
func (mr *MockRestHandlerMockRecorder) HttpClient() *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "HttpClient", reflect.TypeOf((*MockRestHandler)(nil).HttpClient))
}
// Post mocks base method.
func (m *MockHandler) Post(ctx context.Context, endpoint string, headers map[string]string, data *bytes.Buffer, resp any) error {
func (m *MockRestHandler) Post(ctx context.Context, endpoint string, headers map[string]string, data *bytes.Buffer, resp any) error {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "Post", ctx, endpoint, headers, data, resp)
ret0, _ := ret[0].(error)
@@ -118,13 +129,13 @@ func (m *MockHandler) Post(ctx context.Context, endpoint string, headers map[str
}
// Post indicates an expected call of Post.
func (mr *MockHandlerMockRecorder) Post(ctx, endpoint, headers, data, resp any) *gomock.Call {
func (mr *MockRestHandlerMockRecorder) Post(ctx, endpoint, headers, data, resp any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Post", reflect.TypeOf((*MockHandler)(nil).Post), ctx, endpoint, headers, data, resp)
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Post", reflect.TypeOf((*MockRestHandler)(nil).Post), ctx, endpoint, headers, data, resp)
}
// PostSSZ mocks base method.
func (m *MockHandler) PostSSZ(ctx context.Context, endpoint string, headers map[string]string, data *bytes.Buffer) ([]byte, http.Header, error) {
func (m *MockRestHandler) PostSSZ(ctx context.Context, endpoint string, headers map[string]string, data *bytes.Buffer) ([]byte, http.Header, error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "PostSSZ", ctx, endpoint, headers, data)
ret0, _ := ret[0].([]byte)
@@ -134,7 +145,19 @@ func (m *MockHandler) PostSSZ(ctx context.Context, endpoint string, headers map[
}
// PostSSZ indicates an expected call of PostSSZ.
func (mr *MockHandlerMockRecorder) PostSSZ(ctx, endpoint, headers, data any) *gomock.Call {
func (mr *MockRestHandlerMockRecorder) PostSSZ(ctx, endpoint, headers, data any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PostSSZ", reflect.TypeOf((*MockHandler)(nil).PostSSZ), ctx, endpoint, headers, data)
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PostSSZ", reflect.TypeOf((*MockRestHandler)(nil).PostSSZ), ctx, endpoint, headers, data)
}
// SetHost mocks base method.
func (m *MockRestHandler) SetHost(host string) {
m.ctrl.T.Helper()
m.ctrl.Call(m, "SetHost", host)
}
// SetHost indicates an expected call of SetHost.
func (mr *MockRestHandlerMockRecorder) SetHost(host any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetHost", reflect.TypeOf((*MockRestHandler)(nil).SetHost), host)
}

View File

@@ -26,5 +26,5 @@ func (c *beaconApiValidatorClient) prepareBeaconProposer(ctx context.Context, re
return errors.Wrap(err, "failed to marshal recipients")
}
return c.handler.Post(ctx, "/eth/v1/validator/prepare_beacon_proposer", nil, bytes.NewBuffer(marshalledJsonRecipients), nil)
return c.jsonRestHandler.Post(ctx, "/eth/v1/validator/prepare_beacon_proposer", nil, bytes.NewBuffer(marshalledJsonRecipients), nil)
}

View File

@@ -45,8 +45,8 @@ func TestPrepareBeaconProposer_Valid(t *testing.T) {
marshalledJsonRecipients, err := json.Marshal(jsonRecipients)
require.NoError(t, err)
handler := mock.NewMockJsonRestHandler(ctrl)
handler.EXPECT().Post(
jsonRestHandler := mock.NewMockJsonRestHandler(ctrl)
jsonRestHandler.EXPECT().Post(
gomock.Any(),
prepareBeaconProposerTestEndpoint,
nil,
@@ -78,7 +78,7 @@ func TestPrepareBeaconProposer_Valid(t *testing.T) {
},
}
validatorClient := &beaconApiValidatorClient{handler: handler}
validatorClient := &beaconApiValidatorClient{jsonRestHandler: jsonRestHandler}
err = validatorClient.prepareBeaconProposer(ctx, protoRecipients)
require.NoError(t, err)
}
@@ -89,8 +89,8 @@ func TestPrepareBeaconProposer_BadRequest(t *testing.T) {
ctx := t.Context()
handler := mock.NewMockJsonRestHandler(ctrl)
handler.EXPECT().Post(
jsonRestHandler := mock.NewMockJsonRestHandler(ctrl)
jsonRestHandler.EXPECT().Post(
gomock.Any(),
prepareBeaconProposerTestEndpoint,
nil,
@@ -100,7 +100,7 @@ func TestPrepareBeaconProposer_BadRequest(t *testing.T) {
errors.New("foo error"),
).Times(1)
validatorClient := &beaconApiValidatorClient{handler: handler}
validatorClient := &beaconApiValidatorClient{jsonRestHandler: jsonRestHandler}
err := validatorClient.prepareBeaconProposer(ctx, nil)
assert.ErrorContains(t, "foo error", err)
}

View File

@@ -22,7 +22,7 @@ func (c *beaconApiValidatorClient) proposeAttestation(ctx context.Context, attes
}
headers := map[string]string{"Eth-Consensus-Version": version.String(attestation.Version())}
err = c.handler.Post(
err = c.jsonRestHandler.Post(
ctx,
"/eth/v2/beacon/pool/attestations",
headers,
@@ -51,7 +51,7 @@ func (c *beaconApiValidatorClient) proposeAttestationElectra(ctx context.Context
}
consensusVersion := version.String(slots.ToForkVersion(attestation.Data.Slot))
headers := map[string]string{"Eth-Consensus-Version": consensusVersion}
if err = c.handler.Post(
if err = c.jsonRestHandler.Post(
ctx,
"/eth/v2/beacon/pool/attestations",
headers,

View File

@@ -107,7 +107,7 @@ func TestProposeAttestation(t *testing.T) {
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
ctrl := gomock.NewController(t)
handler := mock.NewMockJsonRestHandler(ctrl)
jsonRestHandler := mock.NewMockJsonRestHandler(ctrl)
var marshalledAttestations []byte
if helpers.ValidateNilAttestation(test.attestation) == nil {
@@ -119,7 +119,7 @@ func TestProposeAttestation(t *testing.T) {
ctx := t.Context()
headers := map[string]string{"Eth-Consensus-Version": version.String(test.attestation.Version())}
handler.EXPECT().Post(
jsonRestHandler.EXPECT().Post(
gomock.Any(),
"/eth/v2/beacon/pool/attestations",
headers,
@@ -129,7 +129,7 @@ func TestProposeAttestation(t *testing.T) {
test.endpointError,
).Times(test.endpointCall)
validatorClient := &beaconApiValidatorClient{handler: handler}
validatorClient := &beaconApiValidatorClient{jsonRestHandler: jsonRestHandler}
proposeResponse, err := validatorClient.proposeAttestation(ctx, test.attestation)
if test.expectedErrorMessage != "" {
require.ErrorContains(t, test.expectedErrorMessage, err)
@@ -254,7 +254,7 @@ func TestProposeAttestationElectra(t *testing.T) {
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
ctrl := gomock.NewController(t)
handler := mock.NewMockJsonRestHandler(ctrl)
jsonRestHandler := mock.NewMockJsonRestHandler(ctrl)
var marshalledAttestations []byte
if helpers.ValidateNilAttestation(test.attestation) == nil {
@@ -268,7 +268,7 @@ func TestProposeAttestationElectra(t *testing.T) {
if test.expectedConsensusVersion != "" {
headerMatcher = gomock.Eq(map[string]string{"Eth-Consensus-Version": test.expectedConsensusVersion})
}
handler.EXPECT().Post(
jsonRestHandler.EXPECT().Post(
gomock.Any(),
"/eth/v2/beacon/pool/attestations",
headerMatcher,
@@ -278,7 +278,7 @@ func TestProposeAttestationElectra(t *testing.T) {
test.endpointError,
).Times(test.endpointCall)
validatorClient := &beaconApiValidatorClient{handler: handler}
validatorClient := &beaconApiValidatorClient{jsonRestHandler: jsonRestHandler}
proposeResponse, err := validatorClient.proposeAttestationElectra(ctx, test.attestation)
if test.expectedErrorMessage != "" {
require.ErrorContains(t, test.expectedErrorMessage, err)

View File

@@ -67,7 +67,7 @@ func (c *beaconApiValidatorClient) proposeBeaconBlock(ctx context.Context, in *e
// Try PostSSZ first with SSZ data
if res.marshalledSSZ != nil {
_, _, err = c.handler.PostSSZ(ctx, endpoint, headers, bytes.NewBuffer(res.marshalledSSZ))
_, _, err = c.jsonRestHandler.PostSSZ(ctx, endpoint, headers, bytes.NewBuffer(res.marshalledSSZ))
if err != nil {
errJson := &httputil.DefaultJsonError{}
// If PostSSZ fails with 406 (Not Acceptable), fall back to JSON
@@ -81,7 +81,7 @@ func (c *beaconApiValidatorClient) proposeBeaconBlock(ctx context.Context, in *e
return nil, errors.Wrap(jsonErr, "failed to marshal JSON")
}
// Reset headers for JSON
err = c.handler.Post(ctx, endpoint, headers, bytes.NewBuffer(jsonData), nil)
err = c.jsonRestHandler.Post(ctx, endpoint, headers, bytes.NewBuffer(jsonData), nil)
// If JSON also fails, return that error
if err != nil {
return nil, errors.Wrap(err, "failed to submit block via JSON fallback")
@@ -100,7 +100,7 @@ func (c *beaconApiValidatorClient) proposeBeaconBlock(ctx context.Context, in *e
return nil, errors.Wrap(jsonErr, "failed to marshal JSON")
}
// Reset headers for JSON
err = c.handler.Post(ctx, endpoint, headers, bytes.NewBuffer(jsonData), nil)
err = c.jsonRestHandler.Post(ctx, endpoint, headers, bytes.NewBuffer(jsonData), nil)
errJson := &httputil.DefaultJsonError{}
if err != nil {
if !errors.As(err, &errJson) {

View File

@@ -103,13 +103,13 @@ func TestProposeBeaconBlock_SSZ_Error(t *testing.T) {
defer ctrl.Finish()
ctx := t.Context()
handler := mock.NewMockJsonRestHandler(ctrl)
jsonRestHandler := mock.NewMockJsonRestHandler(ctrl)
// Expect PostSSZ to be called first with SSZ data
headers := map[string]string{
"Eth-Consensus-Version": testCase.consensusVersion,
}
handler.EXPECT().PostSSZ(
jsonRestHandler.EXPECT().PostSSZ(
gomock.Any(),
testCase.endpoint,
headers,
@@ -120,7 +120,7 @@ func TestProposeBeaconBlock_SSZ_Error(t *testing.T) {
// No JSON fallback expected for non-406 errors
validatorClient := &beaconApiValidatorClient{handler: handler}
validatorClient := &beaconApiValidatorClient{jsonRestHandler: jsonRestHandler}
_, err := validatorClient.proposeBeaconBlock(ctx, testCase.block)
assert.ErrorContains(t, testSuite.expectedErrorMessage, err)
})
@@ -165,13 +165,13 @@ func TestProposeBeaconBlock_SSZSuccess_NoFallback(t *testing.T) {
defer ctrl.Finish()
ctx := t.Context()
handler := mock.NewMockJsonRestHandler(ctrl)
jsonRestHandler := mock.NewMockJsonRestHandler(ctrl)
// Expect PostSSZ to be called and succeed
headers := map[string]string{
"Eth-Consensus-Version": testCase.consensusVersion,
}
handler.EXPECT().PostSSZ(
jsonRestHandler.EXPECT().PostSSZ(
gomock.Any(),
testCase.endpoint,
headers,
@@ -181,7 +181,7 @@ func TestProposeBeaconBlock_SSZSuccess_NoFallback(t *testing.T) {
).Times(1)
// Post should NOT be called when PostSSZ succeeds
handler.EXPECT().Post(
jsonRestHandler.EXPECT().Post(
gomock.Any(),
gomock.Any(),
gomock.Any(),
@@ -189,7 +189,7 @@ func TestProposeBeaconBlock_SSZSuccess_NoFallback(t *testing.T) {
gomock.Any(),
).Times(0)
validatorClient := &beaconApiValidatorClient{handler: handler}
validatorClient := &beaconApiValidatorClient{jsonRestHandler: jsonRestHandler}
_, err := validatorClient.proposeBeaconBlock(ctx, testCase.block)
assert.NoError(t, err)
})
@@ -200,7 +200,7 @@ func TestProposeBeaconBlock_NewerTypes_SSZMarshal(t *testing.T) {
t.Run("deneb", func(t *testing.T) {
ctrl := gomock.NewController(t)
defer ctrl.Finish()
handler := mock.NewMockJsonRestHandler(ctrl)
jsonRestHandler := mock.NewMockJsonRestHandler(ctrl)
var blockContents structs.SignedBeaconBlockContentsDeneb
err := json.Unmarshal([]byte(rpctesting.DenebBlockContents), &blockContents)
@@ -211,14 +211,14 @@ func TestProposeBeaconBlock_NewerTypes_SSZMarshal(t *testing.T) {
denebBytes, err := genericSignedBlock.GetDeneb().MarshalSSZ()
require.NoError(t, err)
handler.EXPECT().PostSSZ(
jsonRestHandler.EXPECT().PostSSZ(
gomock.Any(),
"/eth/v2/beacon/blocks",
gomock.Any(),
bytes.NewBuffer(denebBytes),
)
validatorClient := &beaconApiValidatorClient{handler: handler}
validatorClient := &beaconApiValidatorClient{jsonRestHandler: jsonRestHandler}
proposeResponse, err := validatorClient.proposeBeaconBlock(t.Context(), genericSignedBlock)
assert.NoError(t, err)
require.NotNil(t, proposeResponse)
@@ -231,7 +231,7 @@ func TestProposeBeaconBlock_NewerTypes_SSZMarshal(t *testing.T) {
t.Run("blinded_deneb", func(t *testing.T) {
ctrl := gomock.NewController(t)
defer ctrl.Finish()
handler := mock.NewMockJsonRestHandler(ctrl)
jsonRestHandler := mock.NewMockJsonRestHandler(ctrl)
var blindedBlock structs.SignedBlindedBeaconBlockDeneb
err := json.Unmarshal([]byte(rpctesting.BlindedDenebBlock), &blindedBlock)
@@ -242,14 +242,14 @@ func TestProposeBeaconBlock_NewerTypes_SSZMarshal(t *testing.T) {
blindedDenebBytes, err := genericSignedBlock.GetBlindedDeneb().MarshalSSZ()
require.NoError(t, err)
handler.EXPECT().PostSSZ(
jsonRestHandler.EXPECT().PostSSZ(
gomock.Any(),
"/eth/v2/beacon/blinded_blocks",
gomock.Any(),
bytes.NewBuffer(blindedDenebBytes),
)
validatorClient := &beaconApiValidatorClient{handler: handler}
validatorClient := &beaconApiValidatorClient{jsonRestHandler: jsonRestHandler}
proposeResponse, err := validatorClient.proposeBeaconBlock(t.Context(), genericSignedBlock)
assert.NoError(t, err)
require.NotNil(t, proposeResponse)
@@ -262,7 +262,7 @@ func TestProposeBeaconBlock_NewerTypes_SSZMarshal(t *testing.T) {
t.Run("electra", func(t *testing.T) {
ctrl := gomock.NewController(t)
defer ctrl.Finish()
handler := mock.NewMockJsonRestHandler(ctrl)
jsonRestHandler := mock.NewMockJsonRestHandler(ctrl)
var blockContents structs.SignedBeaconBlockContentsElectra
err := json.Unmarshal([]byte(rpctesting.ElectraBlockContents), &blockContents)
@@ -273,14 +273,14 @@ func TestProposeBeaconBlock_NewerTypes_SSZMarshal(t *testing.T) {
electraBytes, err := genericSignedBlock.GetElectra().MarshalSSZ()
require.NoError(t, err)
handler.EXPECT().PostSSZ(
jsonRestHandler.EXPECT().PostSSZ(
gomock.Any(),
"/eth/v2/beacon/blocks",
gomock.Any(),
bytes.NewBuffer(electraBytes),
)
validatorClient := &beaconApiValidatorClient{handler: handler}
validatorClient := &beaconApiValidatorClient{jsonRestHandler: jsonRestHandler}
proposeResponse, err := validatorClient.proposeBeaconBlock(t.Context(), genericSignedBlock)
assert.NoError(t, err)
require.NotNil(t, proposeResponse)
@@ -293,7 +293,7 @@ func TestProposeBeaconBlock_NewerTypes_SSZMarshal(t *testing.T) {
t.Run("blinded_electra", func(t *testing.T) {
ctrl := gomock.NewController(t)
defer ctrl.Finish()
handler := mock.NewMockJsonRestHandler(ctrl)
jsonRestHandler := mock.NewMockJsonRestHandler(ctrl)
var blindedBlock structs.SignedBlindedBeaconBlockElectra
err := json.Unmarshal([]byte(rpctesting.BlindedElectraBlock), &blindedBlock)
@@ -304,14 +304,14 @@ func TestProposeBeaconBlock_NewerTypes_SSZMarshal(t *testing.T) {
blindedElectraBytes, err := genericSignedBlock.GetBlindedElectra().MarshalSSZ()
require.NoError(t, err)
handler.EXPECT().PostSSZ(
jsonRestHandler.EXPECT().PostSSZ(
gomock.Any(),
"/eth/v2/beacon/blinded_blocks",
gomock.Any(),
bytes.NewBuffer(blindedElectraBytes),
)
validatorClient := &beaconApiValidatorClient{handler: handler}
validatorClient := &beaconApiValidatorClient{jsonRestHandler: jsonRestHandler}
proposeResponse, err := validatorClient.proposeBeaconBlock(t.Context(), genericSignedBlock)
assert.NoError(t, err)
require.NotNil(t, proposeResponse)
@@ -324,7 +324,7 @@ func TestProposeBeaconBlock_NewerTypes_SSZMarshal(t *testing.T) {
t.Run("fulu", func(t *testing.T) {
ctrl := gomock.NewController(t)
defer ctrl.Finish()
handler := mock.NewMockJsonRestHandler(ctrl)
jsonRestHandler := mock.NewMockJsonRestHandler(ctrl)
var blockContents structs.SignedBeaconBlockContentsFulu
err := json.Unmarshal([]byte(rpctesting.FuluBlockContents), &blockContents)
@@ -335,14 +335,14 @@ func TestProposeBeaconBlock_NewerTypes_SSZMarshal(t *testing.T) {
fuluBytes, err := genericSignedBlock.GetFulu().MarshalSSZ()
require.NoError(t, err)
handler.EXPECT().PostSSZ(
jsonRestHandler.EXPECT().PostSSZ(
gomock.Any(),
"/eth/v2/beacon/blocks",
gomock.Any(),
bytes.NewBuffer(fuluBytes),
)
validatorClient := &beaconApiValidatorClient{handler: handler}
validatorClient := &beaconApiValidatorClient{jsonRestHandler: jsonRestHandler}
proposeResponse, err := validatorClient.proposeBeaconBlock(t.Context(), genericSignedBlock)
assert.NoError(t, err)
require.NotNil(t, proposeResponse)
@@ -355,7 +355,7 @@ func TestProposeBeaconBlock_NewerTypes_SSZMarshal(t *testing.T) {
t.Run("blinded_fulu", func(t *testing.T) {
ctrl := gomock.NewController(t)
defer ctrl.Finish()
handler := mock.NewMockJsonRestHandler(ctrl)
jsonRestHandler := mock.NewMockJsonRestHandler(ctrl)
var blindedBlock structs.SignedBlindedBeaconBlockFulu
err := json.Unmarshal([]byte(rpctesting.BlindedFuluBlock), &blindedBlock)
@@ -366,14 +366,14 @@ func TestProposeBeaconBlock_NewerTypes_SSZMarshal(t *testing.T) {
blindedFuluBytes, err := genericSignedBlock.GetBlindedFulu().MarshalSSZ()
require.NoError(t, err)
handler.EXPECT().PostSSZ(
jsonRestHandler.EXPECT().PostSSZ(
gomock.Any(),
"/eth/v2/beacon/blinded_blocks",
gomock.Any(),
bytes.NewBuffer(blindedFuluBytes),
)
validatorClient := &beaconApiValidatorClient{handler: handler}
validatorClient := &beaconApiValidatorClient{jsonRestHandler: jsonRestHandler}
proposeResponse, err := validatorClient.proposeBeaconBlock(t.Context(), genericSignedBlock)
assert.NoError(t, err)
require.NotNil(t, proposeResponse)
@@ -588,10 +588,10 @@ func TestProposeBeaconBlock_SSZFails_406_FallbackToJSON(t *testing.T) {
defer ctrl.Finish()
ctx := t.Context()
handler := mock.NewMockJsonRestHandler(ctrl)
jsonRestHandler := mock.NewMockJsonRestHandler(ctrl)
// Expect PostSSZ to be called first and fail
handler.EXPECT().PostSSZ(
jsonRestHandler.EXPECT().PostSSZ(
gomock.Any(),
testCase.endpoint,
gomock.Any(),
@@ -603,7 +603,7 @@ func TestProposeBeaconBlock_SSZFails_406_FallbackToJSON(t *testing.T) {
},
).Times(1)
handler.EXPECT().Post(
jsonRestHandler.EXPECT().Post(
gomock.Any(),
testCase.endpoint,
gomock.Any(),
@@ -613,7 +613,7 @@ func TestProposeBeaconBlock_SSZFails_406_FallbackToJSON(t *testing.T) {
nil,
).Times(1)
validatorClient := &beaconApiValidatorClient{handler: handler}
validatorClient := &beaconApiValidatorClient{jsonRestHandler: jsonRestHandler}
_, err := validatorClient.proposeBeaconBlock(ctx, testCase.block)
assert.NoError(t, err)
})
@@ -643,13 +643,13 @@ func TestProposeBeaconBlock_SSZFails_Non406_NoFallback(t *testing.T) {
defer ctrl.Finish()
ctx := t.Context()
handler := mock.NewMockJsonRestHandler(ctrl)
jsonRestHandler := mock.NewMockJsonRestHandler(ctrl)
// Expect PostSSZ to be called first and fail with non-406 error
sszHeaders := map[string]string{
"Eth-Consensus-Version": testCase.consensusVersion,
}
handler.EXPECT().PostSSZ(
jsonRestHandler.EXPECT().PostSSZ(
gomock.Any(),
testCase.endpoint,
sszHeaders,
@@ -662,7 +662,7 @@ func TestProposeBeaconBlock_SSZFails_Non406_NoFallback(t *testing.T) {
).Times(1)
// Post should NOT be called for non-406 errors
handler.EXPECT().Post(
jsonRestHandler.EXPECT().Post(
gomock.Any(),
gomock.Any(),
gomock.Any(),
@@ -670,7 +670,7 @@ func TestProposeBeaconBlock_SSZFails_Non406_NoFallback(t *testing.T) {
gomock.Any(),
).Times(0)
validatorClient := &beaconApiValidatorClient{handler: handler}
validatorClient := &beaconApiValidatorClient{jsonRestHandler: jsonRestHandler}
_, err := validatorClient.proposeBeaconBlock(ctx, testCase.block)
require.ErrorContains(t, "Internal server error", err)
})

View File

@@ -34,7 +34,7 @@ func (c *beaconApiValidatorClient) proposeExit(ctx context.Context, signedVolunt
return nil, errors.Wrap(err, "failed to marshal signed voluntary exit")
}
if err = c.handler.Post(
if err = c.jsonRestHandler.Post(
ctx,
"/eth/v1/beacon/pool/voluntary_exits",
nil,

View File

@@ -36,8 +36,8 @@ func TestProposeExit_Valid(t *testing.T) {
ctx := t.Context()
handler := mock.NewMockJsonRestHandler(ctrl)
handler.EXPECT().Post(
jsonRestHandler := mock.NewMockJsonRestHandler(ctrl)
jsonRestHandler.EXPECT().Post(
gomock.Any(),
proposeExitTestEndpoint,
nil,
@@ -61,7 +61,7 @@ func TestProposeExit_Valid(t *testing.T) {
expectedExitRoot, err := protoSignedVoluntaryExit.Exit.HashTreeRoot()
require.NoError(t, err)
validatorClient := &beaconApiValidatorClient{handler: handler}
validatorClient := &beaconApiValidatorClient{jsonRestHandler: jsonRestHandler}
exitResponse, err := validatorClient.proposeExit(ctx, protoSignedVoluntaryExit)
require.NoError(t, err)
assert.DeepEqual(t, expectedExitRoot[:], exitResponse.ExitRoot)
@@ -85,8 +85,8 @@ func TestProposeExit_BadRequest(t *testing.T) {
ctx := t.Context()
handler := mock.NewMockJsonRestHandler(ctrl)
handler.EXPECT().Post(
jsonRestHandler := mock.NewMockJsonRestHandler(ctrl)
jsonRestHandler.EXPECT().Post(
gomock.Any(),
proposeExitTestEndpoint,
nil,
@@ -104,7 +104,7 @@ func TestProposeExit_BadRequest(t *testing.T) {
Signature: []byte{3},
}
validatorClient := &beaconApiValidatorClient{handler: handler}
validatorClient := &beaconApiValidatorClient{jsonRestHandler: jsonRestHandler}
_, err := validatorClient.proposeExit(ctx, protoSignedVoluntaryExit)
assert.ErrorContains(t, "foo error", err)
}

View File

@@ -10,7 +10,6 @@ import (
"strings"
"github.com/OffchainLabs/prysm/v7/api/apiutil"
"github.com/OffchainLabs/prysm/v7/api/rest"
"github.com/OffchainLabs/prysm/v7/api/server/structs"
validator2 "github.com/OffchainLabs/prysm/v7/consensus-types/validator"
ethpb "github.com/OffchainLabs/prysm/v7/proto/prysm/v1alpha1"
@@ -19,16 +18,16 @@ import (
)
// NewPrysmChainClient returns implementation of iface.PrysmChainClient.
func NewPrysmChainClient(handler rest.Handler, nodeClient iface.NodeClient) iface.PrysmChainClient {
func NewPrysmChainClient(jsonRestHandler RestHandler, nodeClient iface.NodeClient) iface.PrysmChainClient {
return prysmChainClient{
handler: handler,
nodeClient: nodeClient,
jsonRestHandler: jsonRestHandler,
nodeClient: nodeClient,
}
}
type prysmChainClient struct {
handler rest.Handler
nodeClient iface.NodeClient
jsonRestHandler RestHandler
nodeClient iface.NodeClient
}
func (c prysmChainClient) ValidatorCount(ctx context.Context, stateID string, statuses []validator2.Status) ([]iface.ValidatorCount, error) {
@@ -50,7 +49,7 @@ func (c prysmChainClient) ValidatorCount(ctx context.Context, stateID string, st
queryUrl := apiutil.BuildURL(fmt.Sprintf("/eth/v1/beacon/states/%s/validator_count", stateID), queryParams)
var validatorCountResponse structs.GetValidatorCountResponse
if err = c.handler.Get(ctx, queryUrl, &validatorCountResponse); err != nil {
if err = c.jsonRestHandler.Get(ctx, queryUrl, &validatorCountResponse); err != nil {
return nil, err
}
@@ -97,7 +96,7 @@ func (c prysmChainClient) ValidatorPerformance(ctx context.Context, in *ethpb.Va
return nil, errors.Wrap(err, "failed to marshal request")
}
resp := &structs.GetValidatorPerformanceResponse{}
if err = c.handler.Post(ctx, "/prysm/validators/performance", nil, bytes.NewBuffer(request), resp); err != nil {
if err = c.jsonRestHandler.Post(ctx, "/prysm/validators/performance", nil, bytes.NewBuffer(request), resp); err != nil {
return nil, err
}

View File

@@ -116,11 +116,11 @@ func TestGetValidatorCount(t *testing.T) {
defer ctrl.Finish()
ctx := t.Context()
handler := mock.NewMockJsonRestHandler(ctrl)
jsonRestHandler := mock.NewMockJsonRestHandler(ctrl)
// Expect node version endpoint call.
var nodeVersionResponse structs.GetVersionResponse
handler.EXPECT().Get(
jsonRestHandler.EXPECT().Get(
gomock.Any(),
"/eth/v1/node/version",
&nodeVersionResponse,
@@ -132,7 +132,7 @@ func TestGetValidatorCount(t *testing.T) {
)
var validatorCountResponse structs.GetValidatorCountResponse
handler.EXPECT().Get(
jsonRestHandler.EXPECT().Get(
gomock.Any(),
"/eth/v1/beacon/states/head/validator_count?status=active",
&validatorCountResponse,
@@ -145,8 +145,8 @@ func TestGetValidatorCount(t *testing.T) {
// Type assertion.
var client iface.PrysmChainClient = &prysmChainClient{
nodeClient: &beaconApiNodeClient{handler: handler},
handler: handler,
nodeClient: &beaconApiNodeClient{jsonRestHandler: jsonRestHandler},
jsonRestHandler: jsonRestHandler,
}
countResponse, err := client.ValidatorCount(ctx, "head", []validator.Status{validator.Active})
@@ -177,10 +177,10 @@ func Test_beaconApiBeaconChainClient_GetValidatorPerformance(t *testing.T) {
PublicKeys: [][]byte{publicKeys[0][:], publicKeys[2][:], publicKeys[1][:]},
})
require.NoError(t, err)
handler := mock.NewMockJsonRestHandler(ctrl)
jsonRestHandler := mock.NewMockJsonRestHandler(ctrl)
// Expect node version endpoint call.
var nodeVersionResponse structs.GetVersionResponse
handler.EXPECT().Get(
jsonRestHandler.EXPECT().Get(
gomock.Any(),
"/eth/v1/node/version",
&nodeVersionResponse,
@@ -196,7 +196,7 @@ func Test_beaconApiBeaconChainClient_GetValidatorPerformance(t *testing.T) {
wantResponse := &structs.GetValidatorPerformanceResponse{}
want := &ethpb.ValidatorPerformanceResponse{}
handler.EXPECT().Post(
jsonRestHandler.EXPECT().Post(
gomock.Any(),
"/prysm/validators/performance",
nil,
@@ -207,8 +207,8 @@ func Test_beaconApiBeaconChainClient_GetValidatorPerformance(t *testing.T) {
)
var client iface.PrysmChainClient = &prysmChainClient{
nodeClient: &beaconApiNodeClient{handler: handler},
handler: handler,
nodeClient: &beaconApiNodeClient{jsonRestHandler: jsonRestHandler},
jsonRestHandler: jsonRestHandler,
}
got, err := client.ValidatorPerformance(ctx, &ethpb.ValidatorPerformanceRequest{

View File

@@ -24,5 +24,5 @@ func (c *beaconApiValidatorClient) submitValidatorRegistrations(ctx context.Cont
return errors.Wrap(err, "failed to marshal registration")
}
return c.handler.Post(ctx, endpoint, nil, bytes.NewBuffer(marshalledJsonRegistration), nil)
return c.jsonRestHandler.Post(ctx, endpoint, nil, bytes.NewBuffer(marshalledJsonRegistration), nil)
}

View File

@@ -65,8 +65,8 @@ func TestRegistration_Valid(t *testing.T) {
marshalledJsonRegistrations, err := json.Marshal(jsonRegistrations)
require.NoError(t, err)
handler := mock.NewMockJsonRestHandler(ctrl)
handler.EXPECT().Post(
jsonRestHandler := mock.NewMockJsonRestHandler(ctrl)
jsonRestHandler.EXPECT().Post(
gomock.Any(),
"/eth/v1/validator/register_validator",
nil,
@@ -129,7 +129,7 @@ func TestRegistration_Valid(t *testing.T) {
},
}
validatorClient := &beaconApiValidatorClient{handler: handler}
validatorClient := &beaconApiValidatorClient{jsonRestHandler: jsonRestHandler}
res, err := validatorClient.SubmitValidatorRegistrations(t.Context(), &protoRegistrations)
assert.DeepEqual(t, new(empty.Empty), res)
@@ -140,8 +140,8 @@ func TestRegistration_BadRequest(t *testing.T) {
ctrl := gomock.NewController(t)
defer ctrl.Finish()
handler := mock.NewMockJsonRestHandler(ctrl)
handler.EXPECT().Post(
jsonRestHandler := mock.NewMockJsonRestHandler(ctrl)
jsonRestHandler.EXPECT().Post(
gomock.Any(),
"/eth/v1/validator/register_validator",
nil,
@@ -151,7 +151,7 @@ func TestRegistration_BadRequest(t *testing.T) {
errors.New("foo error"),
).Times(1)
validatorClient := &beaconApiValidatorClient{handler: handler}
validatorClient := &beaconApiValidatorClient{jsonRestHandler: jsonRestHandler}
_, err := validatorClient.SubmitValidatorRegistrations(t.Context(), &ethpb.SignedValidatorRegistrationsV1{})
assert.ErrorContains(t, "foo error", err)
}

View File

@@ -1,4 +1,4 @@
package rest
package beacon_api
import (
"bytes"
@@ -21,46 +21,37 @@ import (
type reqOption func(*http.Request)
// Handler defines the interface for making REST API requests.
type Handler interface {
type RestHandler interface {
Get(ctx context.Context, endpoint string, resp any) error
GetStatusCode(ctx context.Context, endpoint string) (int, error)
GetSSZ(ctx context.Context, endpoint string) ([]byte, http.Header, error)
Post(ctx context.Context, endpoint string, headers map[string]string, data *bytes.Buffer, resp any) error
PostSSZ(ctx context.Context, endpoint string, headers map[string]string, data *bytes.Buffer) ([]byte, http.Header, error)
HttpClient() *http.Client
Host() string
SetHost(host string)
}
type handler struct {
type BeaconApiRestHandler struct {
client http.Client
host string
reqOverrides []reqOption
}
// newHandler returns a *handler for internal use within the rest package.
func newHandler(client http.Client, host string) *handler {
rh := &handler{
// NewBeaconApiRestHandler returns a RestHandler
func NewBeaconApiRestHandler(client http.Client, host string) RestHandler {
brh := &BeaconApiRestHandler{
client: client,
host: host,
}
rh.appendAcceptOverride()
return rh
}
// NewHandler returns a Handler
func NewHandler(client http.Client, host string) Handler {
rh := &handler{
client: client,
host: host,
}
rh.appendAcceptOverride()
return rh
brh.appendAcceptOverride()
return brh
}
// appendAcceptOverride enables the Accept header to be customized at runtime via an environment variable.
// This is specified as an env var because it is a niche option that prysm may use for performance testing or debugging
// bug which users are unlikely to need. Using an env var keeps the set of user-facing flags cleaner.
func (c *handler) appendAcceptOverride() {
func (c *BeaconApiRestHandler) appendAcceptOverride() {
if accept := os.Getenv(params.EnvNameOverrideAccept); accept != "" {
c.reqOverrides = append(c.reqOverrides, func(req *http.Request) {
req.Header.Set("Accept", accept)
@@ -69,18 +60,18 @@ func (c *handler) appendAcceptOverride() {
}
// HttpClient returns the underlying HTTP client of the handler
func (c *handler) HttpClient() *http.Client {
func (c *BeaconApiRestHandler) HttpClient() *http.Client {
return &c.client
}
// Host returns the underlying HTTP host
func (c *handler) Host() string {
func (c *BeaconApiRestHandler) Host() string {
return c.host
}
// Get sends a GET request and decodes the response body as a JSON object into the passed in object.
// If an HTTP error is returned, the body is decoded as a DefaultJsonError JSON object and returned as the first return value.
func (c *handler) Get(ctx context.Context, endpoint string, resp any) error {
func (c *BeaconApiRestHandler) Get(ctx context.Context, endpoint string, resp any) error {
url := c.host + endpoint
req, err := http.NewRequestWithContext(ctx, http.MethodGet, url, nil)
if err != nil {
@@ -103,7 +94,7 @@ func (c *handler) Get(ctx context.Context, endpoint string, resp any) error {
// GetStatusCode sends a GET request and returns only the HTTP status code.
// This is useful for endpoints like /eth/v1/node/health that communicate status via HTTP codes
// (200 = ready, 206 = syncing, 503 = unavailable) rather than response bodies.
func (c *handler) GetStatusCode(ctx context.Context, endpoint string) (int, error) {
func (c *BeaconApiRestHandler) GetStatusCode(ctx context.Context, endpoint string) (int, error) {
url := c.host + endpoint
req, err := http.NewRequestWithContext(ctx, http.MethodGet, url, nil)
if err != nil {
@@ -122,7 +113,7 @@ func (c *handler) GetStatusCode(ctx context.Context, endpoint string) (int, erro
return httpResp.StatusCode, nil
}
func (c *handler) GetSSZ(ctx context.Context, endpoint string) ([]byte, http.Header, error) {
func (c *BeaconApiRestHandler) GetSSZ(ctx context.Context, endpoint string) ([]byte, http.Header, error) {
url := c.host + endpoint
req, err := http.NewRequestWithContext(ctx, http.MethodGet, url, nil)
if err != nil {
@@ -177,7 +168,7 @@ func (c *handler) GetSSZ(ctx context.Context, endpoint string) ([]byte, http.Hea
// Post sends a POST request and decodes the response body as a JSON object into the passed in object.
// If an HTTP error is returned, the body is decoded as a DefaultJsonError JSON object and returned as the first return value.
func (c *handler) Post(
func (c *BeaconApiRestHandler) Post(
ctx context.Context,
apiEndpoint string,
headers map[string]string,
@@ -213,7 +204,7 @@ func (c *handler) Post(
}
// PostSSZ sends a POST request and prefers an SSZ (application/octet-stream) response body.
func (c *handler) PostSSZ(
func (c *BeaconApiRestHandler) PostSSZ(
ctx context.Context,
apiEndpoint string,
headers map[string]string,
@@ -314,6 +305,6 @@ func decodeResp(httpResp *http.Response, resp any) error {
return nil
}
func (c *handler) SwitchHost(host string) {
func (c *BeaconApiRestHandler) SetHost(host string) {
c.host = host
}

View File

@@ -12,12 +12,13 @@ import (
"time"
"github.com/OffchainLabs/prysm/v7/api"
"github.com/OffchainLabs/prysm/v7/api/rest"
"github.com/OffchainLabs/prysm/v7/api/server/structs"
"github.com/OffchainLabs/prysm/v7/config/params"
"github.com/OffchainLabs/prysm/v7/network/httputil"
"github.com/OffchainLabs/prysm/v7/runtime/version"
"github.com/OffchainLabs/prysm/v7/testing/assert"
"github.com/OffchainLabs/prysm/v7/testing/require"
"github.com/pkg/errors"
"github.com/sirupsen/logrus"
"github.com/sirupsen/logrus/hooks/test"
)
@@ -44,9 +45,12 @@ func TestGet(t *testing.T) {
server := httptest.NewServer(mux)
defer server.Close()
handler := rest.NewHandler(http.Client{Timeout: time.Second * 5}, server.URL)
jsonRestHandler := BeaconApiRestHandler{
client: http.Client{Timeout: time.Second * 5},
host: server.URL,
}
resp := &structs.GetGenesisResponse{}
require.NoError(t, handler.Get(ctx, endpoint+"?arg1=abc&arg2=def", resp))
require.NoError(t, jsonRestHandler.Get(ctx, endpoint+"?arg1=abc&arg2=def", resp))
assert.DeepEqual(t, genesisJson, resp)
}
@@ -75,9 +79,12 @@ func TestGetSSZ(t *testing.T) {
server := httptest.NewServer(mux)
defer server.Close()
handler := rest.NewHandler(http.Client{Timeout: time.Second * 5}, server.URL)
jsonRestHandler := BeaconApiRestHandler{
client: http.Client{Timeout: time.Second * 5},
host: server.URL,
}
body, header, err := handler.GetSSZ(ctx, endpoint)
body, header, err := jsonRestHandler.GetSSZ(ctx, endpoint)
require.NoError(t, err)
assert.DeepEqual(t, expectedBody, body)
require.StringContains(t, api.OctetStreamMediaType, header.Get("Content-Type"))
@@ -101,9 +108,12 @@ func TestGetSSZ(t *testing.T) {
server := httptest.NewServer(mux)
defer server.Close()
handler := rest.NewHandler(http.Client{Timeout: time.Second * 5}, server.URL)
jsonRestHandler := BeaconApiRestHandler{
client: http.Client{Timeout: time.Second * 5},
host: server.URL,
}
body, header, err := handler.GetSSZ(ctx, endpoint)
body, header, err := jsonRestHandler.GetSSZ(ctx, endpoint)
require.NoError(t, err)
assert.LogsContain(t, logHook, "Server responded with non primary accept type")
require.Equal(t, api.JsonMediaType, header.Get("Content-Type"))
@@ -126,9 +136,12 @@ func TestGetSSZ(t *testing.T) {
server := httptest.NewServer(mux)
defer server.Close()
handler := rest.NewHandler(http.Client{Timeout: time.Second * 5}, server.URL)
jsonRestHandler := BeaconApiRestHandler{
client: http.Client{Timeout: time.Second * 5},
host: server.URL,
}
_, _, err := handler.GetSSZ(ctx, endpoint)
_, _, err := jsonRestHandler.GetSSZ(ctx, endpoint)
require.NoError(t, err)
assert.LogsContain(t, logHook, "Server responded with non primary accept type")
})
@@ -148,7 +161,7 @@ func TestAcceptOverrideSSZ(t *testing.T) {
require.NoError(t, err)
}))
defer srv.Close()
c := rest.NewHandler(http.Client{Timeout: time.Second * 5}, srv.URL)
c := NewBeaconApiRestHandler(http.Client{Timeout: time.Second * 5}, srv.URL)
_, _, err := c.GetSSZ(t.Context(), "/test")
require.NoError(t, err)
}
@@ -191,12 +204,162 @@ func TestPost(t *testing.T) {
server := httptest.NewServer(mux)
defer server.Close()
handler := rest.NewHandler(http.Client{Timeout: time.Second * 5}, server.URL)
jsonRestHandler := BeaconApiRestHandler{
client: http.Client{Timeout: time.Second * 5},
host: server.URL,
}
resp := &structs.GetGenesisResponse{}
require.NoError(t, handler.Post(ctx, endpoint, headers, bytes.NewBuffer(dataBytes), resp))
require.NoError(t, jsonRestHandler.Post(ctx, endpoint, headers, bytes.NewBuffer(dataBytes), resp))
assert.DeepEqual(t, genesisJson, resp)
}
func Test_decodeResp(t *testing.T) {
type j struct {
Foo string `json:"foo"`
}
t.Run("200 JSON with charset", func(t *testing.T) {
body := bytes.Buffer{}
r := &http.Response{
Status: "200",
StatusCode: http.StatusOK,
Body: io.NopCloser(&body),
Header: map[string][]string{"Content-Type": {"application/json; charset=utf-8"}},
}
require.NoError(t, decodeResp(r, nil))
})
t.Run("200 non-JSON", func(t *testing.T) {
body := bytes.Buffer{}
r := &http.Response{
Status: "200",
StatusCode: http.StatusOK,
Body: io.NopCloser(&body),
Header: map[string][]string{"Content-Type": {api.OctetStreamMediaType}},
}
require.NoError(t, decodeResp(r, nil))
})
t.Run("204 non-JSON", func(t *testing.T) {
body := bytes.Buffer{}
r := &http.Response{
Status: "204",
StatusCode: http.StatusNoContent,
Body: io.NopCloser(&body),
Header: map[string][]string{"Content-Type": {api.OctetStreamMediaType}},
}
require.NoError(t, decodeResp(r, nil))
})
t.Run("500 non-JSON", func(t *testing.T) {
body := bytes.Buffer{}
_, err := body.WriteString("foo")
require.NoError(t, err)
r := &http.Response{
Status: "500",
StatusCode: http.StatusInternalServerError,
Body: io.NopCloser(&body),
Header: map[string][]string{"Content-Type": {api.OctetStreamMediaType}},
}
err = decodeResp(r, nil)
errJson := &httputil.DefaultJsonError{}
require.Equal(t, true, errors.As(err, &errJson))
assert.Equal(t, http.StatusInternalServerError, errJson.Code)
assert.Equal(t, "foo", errJson.Message)
})
t.Run("200 JSON with resp", func(t *testing.T) {
body := bytes.Buffer{}
b, err := json.Marshal(&j{Foo: "foo"})
require.NoError(t, err)
body.Write(b)
r := &http.Response{
Status: "200",
StatusCode: http.StatusOK,
Body: io.NopCloser(&body),
Header: map[string][]string{"Content-Type": {api.JsonMediaType}},
}
resp := &j{}
require.NoError(t, decodeResp(r, resp))
assert.Equal(t, "foo", resp.Foo)
})
t.Run("200 JSON without resp", func(t *testing.T) {
body := bytes.Buffer{}
r := &http.Response{
Status: "200",
StatusCode: http.StatusOK,
Body: io.NopCloser(&body),
Header: map[string][]string{"Content-Type": {api.JsonMediaType}},
}
require.NoError(t, decodeResp(r, nil))
})
t.Run("204 JSON", func(t *testing.T) {
body := bytes.Buffer{}
r := &http.Response{
Status: "204",
StatusCode: http.StatusNoContent,
Body: io.NopCloser(&body),
Header: map[string][]string{"Content-Type": {api.JsonMediaType}},
}
require.NoError(t, decodeResp(r, nil))
})
t.Run("500 JSON", func(t *testing.T) {
body := bytes.Buffer{}
b, err := json.Marshal(&httputil.DefaultJsonError{Code: http.StatusInternalServerError, Message: "error"})
require.NoError(t, err)
body.Write(b)
r := &http.Response{
Status: "500",
StatusCode: http.StatusInternalServerError,
Body: io.NopCloser(&body),
Header: map[string][]string{"Content-Type": {api.JsonMediaType}},
}
err = decodeResp(r, nil)
errJson := &httputil.DefaultJsonError{}
require.Equal(t, true, errors.As(err, &errJson))
assert.Equal(t, http.StatusInternalServerError, errJson.Code)
assert.Equal(t, "error", errJson.Message)
})
t.Run("200 JSON cannot decode", func(t *testing.T) {
body := bytes.Buffer{}
_, err := body.WriteString("foo")
require.NoError(t, err)
r := &http.Response{
Status: "200",
StatusCode: http.StatusOK,
Body: io.NopCloser(&body),
Header: map[string][]string{"Content-Type": {api.JsonMediaType}},
Request: &http.Request{},
}
resp := &j{}
err = decodeResp(r, resp)
assert.ErrorContains(t, "failed to decode response body into json", err)
})
t.Run("500 JSON cannot decode", func(t *testing.T) {
body := bytes.Buffer{}
_, err := body.WriteString("foo")
require.NoError(t, err)
r := &http.Response{
Status: "500",
StatusCode: http.StatusInternalServerError,
Body: io.NopCloser(&body),
Header: map[string][]string{"Content-Type": {api.JsonMediaType}},
Request: &http.Request{},
}
err = decodeResp(r, nil)
assert.ErrorContains(t, "failed to decode response body into error json", err)
})
t.Run("500 not JSON", func(t *testing.T) {
body := bytes.Buffer{}
_, err := body.WriteString("foo")
require.NoError(t, err)
r := &http.Response{
Status: "500",
StatusCode: http.StatusInternalServerError,
Body: io.NopCloser(&body),
Header: map[string][]string{"Content-Type": {"text/plain"}},
Request: &http.Request{},
}
err = decodeResp(r, nil)
assert.ErrorContains(t, "HTTP request unsuccessful (500: foo)", err)
})
}
func TestGetStatusCode(t *testing.T) {
ctx := t.Context()
const endpoint = "/eth/v1/node/health"
@@ -238,18 +401,24 @@ func TestGetStatusCode(t *testing.T) {
server := httptest.NewServer(mux)
defer server.Close()
handler := rest.NewHandler(http.Client{Timeout: time.Second * 5}, server.URL)
jsonRestHandler := BeaconApiRestHandler{
client: http.Client{Timeout: time.Second * 5},
host: server.URL,
}
statusCode, err := handler.GetStatusCode(ctx, endpoint)
statusCode, err := jsonRestHandler.GetStatusCode(ctx, endpoint)
require.NoError(t, err)
assert.Equal(t, tc.expectedStatusCode, statusCode)
})
}
t.Run("returns error on connection failure", func(t *testing.T) {
handler := rest.NewHandler(http.Client{Timeout: time.Millisecond * 100}, "http://localhost:99999")
jsonRestHandler := BeaconApiRestHandler{
client: http.Client{Timeout: time.Millisecond * 100},
host: "http://localhost:99999", // Invalid port
}
_, err := handler.GetStatusCode(ctx, endpoint)
_, err := jsonRestHandler.GetStatusCode(ctx, endpoint)
require.ErrorContains(t, "failed to perform request", err)
})
}

View File

@@ -9,7 +9,6 @@ import (
"strconv"
"github.com/OffchainLabs/prysm/v7/api/apiutil"
"github.com/OffchainLabs/prysm/v7/api/rest"
"github.com/OffchainLabs/prysm/v7/api/server/structs"
"github.com/OffchainLabs/prysm/v7/consensus-types/primitives"
"github.com/pkg/errors"
@@ -22,7 +21,7 @@ type StateValidatorsProvider interface {
}
type beaconApiStateValidatorsProvider struct {
handler rest.Handler
jsonRestHandler RestHandler
}
func (c beaconApiStateValidatorsProvider) StateValidators(
@@ -94,7 +93,7 @@ func (c beaconApiStateValidatorsProvider) getStateValidatorsHelper(
}
stateValidatorsJson := &structs.GetValidatorsResponse{}
// First try POST endpoint to check whether it is supported by the beacon node.
if err = c.handler.Post(ctx, endpoint, nil, bytes.NewBuffer(reqBytes), stateValidatorsJson); err == nil {
if err = c.jsonRestHandler.Post(ctx, endpoint, nil, bytes.NewBuffer(reqBytes), stateValidatorsJson); err == nil {
if stateValidatorsJson.Data == nil {
return nil, errors.New("stateValidatorsJson.Data is nil")
}
@@ -116,7 +115,7 @@ func (c beaconApiStateValidatorsProvider) getStateValidatorsHelper(
query := apiutil.BuildURL(endpoint, queryParams)
err = c.handler.Get(ctx, query, stateValidatorsJson)
err = c.jsonRestHandler.Get(ctx, query, stateValidatorsJson)
if err != nil {
return nil, err
}

View File

@@ -34,7 +34,7 @@ func TestGetStateValidators_Nominal_POST(t *testing.T) {
require.NoError(t, err)
stateValidatorsResponseJson := structs.GetValidatorsResponse{}
handler := mock.NewMockJsonRestHandler(ctrl)
jsonRestHandler := mock.NewMockJsonRestHandler(ctrl)
wanted := []*structs.ValidatorContainer{
{
@@ -69,7 +69,7 @@ func TestGetStateValidators_Nominal_POST(t *testing.T) {
ctx := t.Context()
handler.EXPECT().Post(
jsonRestHandler.EXPECT().Post(
gomock.Any(),
"/eth/v1/beacon/states/head/validators",
nil,
@@ -84,7 +84,7 @@ func TestGetStateValidators_Nominal_POST(t *testing.T) {
},
).Times(1)
stateValidatorsProvider := beaconApiStateValidatorsProvider{handler: handler}
stateValidatorsProvider := beaconApiStateValidatorsProvider{jsonRestHandler: jsonRestHandler}
actual, err := stateValidatorsProvider.StateValidators(ctx, []string{
"0x8000091c2ae64ee414a54c1cc1fc67dec663408bc636cb86756e0200e41a75c8f86603f104f02c856983d2783116be13", // active_ongoing
"0x80000e851c0f53c3246ff726d7ff7766661ca5e12a07c45c114d208d54f0f8233d4380b2e9aff759d69795d1df905526", // active_exiting
@@ -120,7 +120,7 @@ func TestGetStateValidators_Nominal_GET(t *testing.T) {
require.NoError(t, err)
stateValidatorsResponseJson := structs.GetValidatorsResponse{}
handler := mock.NewMockJsonRestHandler(ctrl)
jsonRestHandler := mock.NewMockJsonRestHandler(ctrl)
wanted := []*structs.ValidatorContainer{
{
@@ -156,7 +156,7 @@ func TestGetStateValidators_Nominal_GET(t *testing.T) {
ctx := t.Context()
// First return an error from POST call.
handler.EXPECT().Post(
jsonRestHandler.EXPECT().Post(
gomock.Any(),
"/eth/v1/beacon/states/head/validators",
nil,
@@ -177,7 +177,7 @@ func TestGetStateValidators_Nominal_GET(t *testing.T) {
query := apiutil.BuildURL("/eth/v1/beacon/states/head/validators", queryParams)
handler.EXPECT().Get(
jsonRestHandler.EXPECT().Get(
gomock.Any(),
query,
&stateValidatorsResponseJson,
@@ -190,7 +190,7 @@ func TestGetStateValidators_Nominal_GET(t *testing.T) {
},
).Times(1)
stateValidatorsProvider := beaconApiStateValidatorsProvider{handler: handler}
stateValidatorsProvider := beaconApiStateValidatorsProvider{jsonRestHandler: jsonRestHandler}
actual, err := stateValidatorsProvider.StateValidators(ctx, []string{
"0x8000091c2ae64ee414a54c1cc1fc67dec663408bc636cb86756e0200e41a75c8f86603f104f02c856983d2783116be13", // active_ongoing
"0x80000e851c0f53c3246ff726d7ff7766661ca5e12a07c45c114d208d54f0f8233d4380b2e9aff759d69795d1df905526", // active_exiting
@@ -220,12 +220,12 @@ func TestGetStateValidators_GetRestJsonResponseOnError(t *testing.T) {
require.NoError(t, err)
stateValidatorsResponseJson := structs.GetValidatorsResponse{}
handler := mock.NewMockJsonRestHandler(ctrl)
jsonRestHandler := mock.NewMockJsonRestHandler(ctrl)
ctx := t.Context()
// First call POST.
handler.EXPECT().Post(
jsonRestHandler.EXPECT().Post(
gomock.Any(),
"/eth/v1/beacon/states/head/validators",
nil,
@@ -246,7 +246,7 @@ func TestGetStateValidators_GetRestJsonResponseOnError(t *testing.T) {
query := apiutil.BuildURL("/eth/v1/beacon/states/head/validators", queryParams)
handler.EXPECT().Get(
jsonRestHandler.EXPECT().Get(
gomock.Any(),
query,
&stateValidatorsResponseJson,
@@ -254,7 +254,7 @@ func TestGetStateValidators_GetRestJsonResponseOnError(t *testing.T) {
errors.New("an error"),
).Times(1)
stateValidatorsProvider := beaconApiStateValidatorsProvider{handler: handler}
stateValidatorsProvider := beaconApiStateValidatorsProvider{jsonRestHandler: jsonRestHandler}
_, err = stateValidatorsProvider.StateValidators(ctx, []string{
"0x8000091c2ae64ee414a54c1cc1fc67dec663408bc636cb86756e0200e41a75c8f86603f104f02c856983d2783116be13", // active_ongoing
},
@@ -277,9 +277,9 @@ func TestGetStateValidators_DataIsNil_POST(t *testing.T) {
ctx := t.Context()
stateValidatorsResponseJson := structs.GetValidatorsResponse{}
handler := mock.NewMockJsonRestHandler(ctrl)
jsonRestHandler := mock.NewMockJsonRestHandler(ctrl)
handler.EXPECT().Post(
jsonRestHandler.EXPECT().Post(
gomock.Any(),
"/eth/v1/beacon/states/head/validators",
nil, bytes.NewBuffer(reqBytes),
@@ -293,7 +293,7 @@ func TestGetStateValidators_DataIsNil_POST(t *testing.T) {
},
).Times(1)
stateValidatorsProvider := beaconApiStateValidatorsProvider{handler: handler}
stateValidatorsProvider := beaconApiStateValidatorsProvider{jsonRestHandler: jsonRestHandler}
_, err = stateValidatorsProvider.StateValidators(ctx, []string{
"0x8000091c2ae64ee414a54c1cc1fc67dec663408bc636cb86756e0200e41a75c8f86603f104f02c856983d2783116be13", // active_ongoing
},
@@ -316,10 +316,10 @@ func TestGetStateValidators_DataIsNil_GET(t *testing.T) {
ctx := t.Context()
stateValidatorsResponseJson := structs.GetValidatorsResponse{}
handler := mock.NewMockJsonRestHandler(ctrl)
jsonRestHandler := mock.NewMockJsonRestHandler(ctrl)
// First call POST which will return an error.
handler.EXPECT().Post(
jsonRestHandler.EXPECT().Post(
gomock.Any(),
"/eth/v1/beacon/states/head/validators",
nil,
@@ -340,7 +340,7 @@ func TestGetStateValidators_DataIsNil_GET(t *testing.T) {
query := apiutil.BuildURL("/eth/v1/beacon/states/head/validators", queryParams)
handler.EXPECT().Get(
jsonRestHandler.EXPECT().Get(
gomock.Any(),
query,
&stateValidatorsResponseJson,
@@ -353,7 +353,7 @@ func TestGetStateValidators_DataIsNil_GET(t *testing.T) {
},
).Times(1)
stateValidatorsProvider := beaconApiStateValidatorsProvider{handler: handler}
stateValidatorsProvider := beaconApiStateValidatorsProvider{jsonRestHandler: jsonRestHandler}
_, err = stateValidatorsProvider.StateValidators(ctx, []string{
"0x8000091c2ae64ee414a54c1cc1fc67dec663408bc636cb86756e0200e41a75c8f86603f104f02c856983d2783116be13", // active_ongoing
},

View File

@@ -50,19 +50,19 @@ func TestValidatorStatus_Nominal(t *testing.T) {
nil,
).Times(1)
handler := mock.NewMockJsonRestHandler(ctrl)
jsonRestHandler := mock.NewMockJsonRestHandler(ctrl)
validatorClient := beaconApiValidatorClient{
stateValidatorsProvider: stateValidatorsProvider,
prysmChainClient: prysmChainClient{
nodeClient: &beaconApiNodeClient{
handler: handler,
jsonRestHandler: jsonRestHandler,
},
},
}
// Expect node version endpoint call.
var nodeVersionResponse structs.GetVersionResponse
handler.EXPECT().Get(
jsonRestHandler.EXPECT().Get(
gomock.Any(),
"/eth/v1/node/version",
&nodeVersionResponse,
@@ -165,11 +165,11 @@ func TestMultipleValidatorStatus_Nominal(t *testing.T) {
nil,
).Times(1)
handler := mock.NewMockJsonRestHandler(ctrl)
jsonRestHandler := mock.NewMockJsonRestHandler(ctrl)
// Expect node version endpoint call.
var nodeVersionResponse structs.GetVersionResponse
handler.EXPECT().Get(
jsonRestHandler.EXPECT().Get(
gomock.Any(),
"/eth/v1/node/version",
&nodeVersionResponse,
@@ -181,7 +181,7 @@ func TestMultipleValidatorStatus_Nominal(t *testing.T) {
stateValidatorsProvider: stateValidatorsProvider,
prysmChainClient: prysmChainClient{
nodeClient: &beaconApiNodeClient{
handler: handler,
jsonRestHandler: jsonRestHandler,
},
},
}
@@ -317,11 +317,11 @@ func TestGetValidatorsStatusResponse_Nominal_SomeActiveValidators(t *testing.T)
nil,
).Times(1)
handler := mock.NewMockJsonRestHandler(ctrl)
jsonRestHandler := mock.NewMockJsonRestHandler(ctrl)
// Expect node version endpoint call.
var nodeVersionResponse structs.GetVersionResponse
handler.EXPECT().Get(
jsonRestHandler.EXPECT().Get(
gomock.Any(),
"/eth/v1/node/version",
&nodeVersionResponse,
@@ -333,7 +333,7 @@ func TestGetValidatorsStatusResponse_Nominal_SomeActiveValidators(t *testing.T)
).Times(1)
var validatorCountResponse structs.GetValidatorCountResponse
handler.EXPECT().Get(
jsonRestHandler.EXPECT().Get(
gomock.Any(),
"/eth/v1/beacon/states/head/validator_count?",
&validatorCountResponse,
@@ -420,9 +420,9 @@ func TestGetValidatorsStatusResponse_Nominal_SomeActiveValidators(t *testing.T)
stateValidatorsProvider: stateValidatorsProvider,
prysmChainClient: prysmChainClient{
nodeClient: &beaconApiNodeClient{
handler: handler,
jsonRestHandler: jsonRestHandler,
},
handler: handler,
jsonRestHandler: jsonRestHandler,
},
}
actualValidatorsPubKey, actualValidatorsIndex, actualValidatorsStatusResponse, err := validatorClient.validatorsStatusResponse(ctx, validatorsPubKey, validatorsIndex)
@@ -465,11 +465,11 @@ func TestGetValidatorsStatusResponse_Nominal_NoActiveValidators(t *testing.T) {
nil,
).Times(1)
handler := mock.NewMockJsonRestHandler(ctrl)
jsonRestHandler := mock.NewMockJsonRestHandler(ctrl)
// Expect node version endpoint call.
var nodeVersionResponse structs.GetVersionResponse
handler.EXPECT().Get(
jsonRestHandler.EXPECT().Get(
gomock.Any(),
"/eth/v1/node/version",
&nodeVersionResponse,
@@ -490,9 +490,9 @@ func TestGetValidatorsStatusResponse_Nominal_NoActiveValidators(t *testing.T) {
stateValidatorsProvider: stateValidatorsProvider,
prysmChainClient: prysmChainClient{
nodeClient: &beaconApiNodeClient{
handler: handler,
jsonRestHandler: jsonRestHandler,
},
handler: handler,
jsonRestHandler: jsonRestHandler,
},
}
actualValidatorsPubKey, actualValidatorsIndex, actualValidatorsStatusResponse, err := validatorClient.validatorsStatusResponse(ctx, wantedValidatorsPubKey, nil)
@@ -704,11 +704,11 @@ func TestValidatorStatusResponse_InvalidData(t *testing.T) {
testCase.inputGetStateValidatorsInterface.outputErr,
).Times(1)
handler := mock.NewMockJsonRestHandler(ctrl)
jsonRestHandler := mock.NewMockJsonRestHandler(ctrl)
// Expect node version endpoint call.
var nodeVersionResponse structs.GetVersionResponse
handler.EXPECT().Get(
jsonRestHandler.EXPECT().Get(
gomock.Any(),
"/eth/v1/node/version",
&nodeVersionResponse,
@@ -720,9 +720,9 @@ func TestValidatorStatusResponse_InvalidData(t *testing.T) {
stateValidatorsProvider: stateValidatorsProvider,
prysmChainClient: prysmChainClient{
nodeClient: &beaconApiNodeClient{
handler: handler,
jsonRestHandler: jsonRestHandler,
},
handler: handler,
jsonRestHandler: jsonRestHandler,
},
}

View File

@@ -72,7 +72,7 @@ func (c *beaconApiValidatorClient) headSignedBeaconBlock(ctx context.Context) (*
// Since we don't know yet what the json looks like, we unmarshal into an abstract structure that has only a version
// and a blob of data
signedBlockResponseJson := abstractSignedBlockResponseJson{}
if err := c.handler.Get(ctx, "/eth/v2/beacon/blocks/head", &signedBlockResponseJson); err != nil {
if err := c.jsonRestHandler.Get(ctx, "/eth/v2/beacon/blocks/head", &signedBlockResponseJson); err != nil {
return nil, err
}

View File

@@ -24,8 +24,8 @@ func TestStreamBlocks_UnsupportedConsensusVersion(t *testing.T) {
ctx := t.Context()
handler := mock.NewMockJsonRestHandler(ctrl)
handler.EXPECT().Get(
jsonRestHandler := mock.NewMockJsonRestHandler(ctrl)
jsonRestHandler.EXPECT().Get(
gomock.Any(),
gomock.Any(),
&abstractSignedBlockResponseJson{},
@@ -36,7 +36,7 @@ func TestStreamBlocks_UnsupportedConsensusVersion(t *testing.T) {
nil,
).Times(1)
validatorClient := &beaconApiValidatorClient{handler: handler}
validatorClient := &beaconApiValidatorClient{jsonRestHandler: jsonRestHandler}
streamBlocksClient := validatorClient.streamBlocks(ctx, &eth.StreamBlocksRequest{}, time.Millisecond*100)
_, err := streamBlocksClient.Recv()
assert.ErrorContains(t, "unsupported consensus version `foo`", err)
@@ -146,8 +146,8 @@ func TestStreamBlocks_Error(t *testing.T) {
ctx := t.Context()
handler := mock.NewMockJsonRestHandler(ctrl)
handler.EXPECT().Get(
jsonRestHandler := mock.NewMockJsonRestHandler(ctrl)
jsonRestHandler.EXPECT().Get(
gomock.Any(),
gomock.Any(),
&abstractSignedBlockResponseJson{},
@@ -162,7 +162,7 @@ func TestStreamBlocks_Error(t *testing.T) {
).Times(1)
beaconBlockConverter := testSuite.generateBeaconBlockConverter(ctrl, testCase.conversionError)
validatorClient := &beaconApiValidatorClient{handler: handler, beaconBlockConverter: beaconBlockConverter}
validatorClient := &beaconApiValidatorClient{jsonRestHandler: jsonRestHandler, beaconBlockConverter: beaconBlockConverter}
streamBlocksClient := validatorClient.streamBlocks(ctx, &eth.StreamBlocksRequest{}, time.Millisecond*100)
_, err := streamBlocksClient.Recv()
@@ -197,7 +197,7 @@ func TestStreamBlocks_Phase0Valid(t *testing.T) {
ctx := t.Context()
signedBlockResponseJson := abstractSignedBlockResponseJson{}
handler := mock.NewMockJsonRestHandler(ctrl)
jsonRestHandler := mock.NewMockJsonRestHandler(ctrl)
beaconBlockConverter := mock.NewMockBeaconBlockConverter(ctrl)
// For the first call, return a block that satisfies the verifiedOnly condition. This block should be returned by the first Recv().
@@ -212,7 +212,7 @@ func TestStreamBlocks_Phase0Valid(t *testing.T) {
marshalledSignedBeaconBlockContainer1, err := json.Marshal(signedBeaconBlockContainer1)
require.NoError(t, err)
handler.EXPECT().Get(
jsonRestHandler.EXPECT().Get(
gomock.Any(),
"/eth/v2/beacon/blocks/head",
&signedBlockResponseJson,
@@ -249,7 +249,7 @@ func TestStreamBlocks_Phase0Valid(t *testing.T) {
marshalledSignedBeaconBlockContainer2, err := json.Marshal(signedBeaconBlockContainer2)
require.NoError(t, err)
handler.EXPECT().Get(
jsonRestHandler.EXPECT().Get(
gomock.Any(),
"/eth/v2/beacon/blocks/head",
&signedBlockResponseJson,
@@ -276,7 +276,7 @@ func TestStreamBlocks_Phase0Valid(t *testing.T) {
// The fourth call is only necessary when verifiedOnly == true since the previous block was optimistic
if testCase.verifiedOnly {
handler.EXPECT().Get(
jsonRestHandler.EXPECT().Get(
gomock.Any(),
"/eth/v2/beacon/blocks/head",
&signedBlockResponseJson,
@@ -299,7 +299,7 @@ func TestStreamBlocks_Phase0Valid(t *testing.T) {
).Times(1)
}
validatorClient := &beaconApiValidatorClient{handler: handler, beaconBlockConverter: beaconBlockConverter}
validatorClient := &beaconApiValidatorClient{jsonRestHandler: jsonRestHandler, beaconBlockConverter: beaconBlockConverter}
streamBlocksClient := validatorClient.streamBlocks(ctx, &eth.StreamBlocksRequest{VerifiedOnly: testCase.verifiedOnly}, time.Millisecond*100)
// Get the first block
@@ -358,7 +358,7 @@ func TestStreamBlocks_AltairValid(t *testing.T) {
ctx := t.Context()
signedBlockResponseJson := abstractSignedBlockResponseJson{}
handler := mock.NewMockJsonRestHandler(ctrl)
jsonRestHandler := mock.NewMockJsonRestHandler(ctrl)
beaconBlockConverter := mock.NewMockBeaconBlockConverter(ctrl)
// For the first call, return a block that satisfies the verifiedOnly condition. This block should be returned by the first Recv().
@@ -373,7 +373,7 @@ func TestStreamBlocks_AltairValid(t *testing.T) {
marshalledSignedBeaconBlockContainer1, err := json.Marshal(signedBeaconBlockContainer1)
require.NoError(t, err)
handler.EXPECT().Get(
jsonRestHandler.EXPECT().Get(
gomock.Any(),
"/eth/v2/beacon/blocks/head",
&signedBlockResponseJson,
@@ -410,7 +410,7 @@ func TestStreamBlocks_AltairValid(t *testing.T) {
marshalledSignedBeaconBlockContainer2, err := json.Marshal(signedBeaconBlockContainer2)
require.NoError(t, err)
handler.EXPECT().Get(
jsonRestHandler.EXPECT().Get(
gomock.Any(),
"/eth/v2/beacon/blocks/head",
&signedBlockResponseJson,
@@ -437,7 +437,7 @@ func TestStreamBlocks_AltairValid(t *testing.T) {
// The fourth call is only necessary when verifiedOnly == true since the previous block was optimistic
if testCase.verifiedOnly {
handler.EXPECT().Get(
jsonRestHandler.EXPECT().Get(
gomock.Any(),
"/eth/v2/beacon/blocks/head",
&signedBlockResponseJson,
@@ -460,7 +460,7 @@ func TestStreamBlocks_AltairValid(t *testing.T) {
).Times(1)
}
validatorClient := &beaconApiValidatorClient{handler: handler, beaconBlockConverter: beaconBlockConverter}
validatorClient := &beaconApiValidatorClient{jsonRestHandler: jsonRestHandler, beaconBlockConverter: beaconBlockConverter}
streamBlocksClient := validatorClient.streamBlocks(ctx, &eth.StreamBlocksRequest{VerifiedOnly: testCase.verifiedOnly}, time.Millisecond*100)
// Get the first block
@@ -519,7 +519,7 @@ func TestStreamBlocks_BellatrixValid(t *testing.T) {
ctx := t.Context()
signedBlockResponseJson := abstractSignedBlockResponseJson{}
handler := mock.NewMockJsonRestHandler(ctrl)
jsonRestHandler := mock.NewMockJsonRestHandler(ctrl)
beaconBlockConverter := mock.NewMockBeaconBlockConverter(ctrl)
// For the first call, return a block that satisfies the verifiedOnly condition. This block should be returned by the first Recv().
@@ -534,7 +534,7 @@ func TestStreamBlocks_BellatrixValid(t *testing.T) {
marshalledSignedBeaconBlockContainer1, err := json.Marshal(signedBeaconBlockContainer1)
require.NoError(t, err)
handler.EXPECT().Get(
jsonRestHandler.EXPECT().Get(
gomock.Any(),
"/eth/v2/beacon/blocks/head",
&signedBlockResponseJson,
@@ -571,7 +571,7 @@ func TestStreamBlocks_BellatrixValid(t *testing.T) {
marshalledSignedBeaconBlockContainer2, err := json.Marshal(signedBeaconBlockContainer2)
require.NoError(t, err)
handler.EXPECT().Get(
jsonRestHandler.EXPECT().Get(
gomock.Any(),
"/eth/v2/beacon/blocks/head",
&signedBlockResponseJson,
@@ -598,7 +598,7 @@ func TestStreamBlocks_BellatrixValid(t *testing.T) {
// The fourth call is only necessary when verifiedOnly == true since the previous block was optimistic
if testCase.verifiedOnly {
handler.EXPECT().Get(
jsonRestHandler.EXPECT().Get(
gomock.Any(),
"/eth/v2/beacon/blocks/head",
&signedBlockResponseJson,
@@ -621,7 +621,7 @@ func TestStreamBlocks_BellatrixValid(t *testing.T) {
).Times(1)
}
validatorClient := &beaconApiValidatorClient{handler: handler, beaconBlockConverter: beaconBlockConverter}
validatorClient := &beaconApiValidatorClient{jsonRestHandler: jsonRestHandler, beaconBlockConverter: beaconBlockConverter}
streamBlocksClient := validatorClient.streamBlocks(ctx, &eth.StreamBlocksRequest{VerifiedOnly: testCase.verifiedOnly}, time.Millisecond*100)
// Get the first block
@@ -680,7 +680,7 @@ func TestStreamBlocks_CapellaValid(t *testing.T) {
ctx := t.Context()
signedBlockResponseJson := abstractSignedBlockResponseJson{}
handler := mock.NewMockJsonRestHandler(ctrl)
jsonRestHandler := mock.NewMockJsonRestHandler(ctrl)
beaconBlockConverter := mock.NewMockBeaconBlockConverter(ctrl)
// For the first call, return a block that satisfies the verifiedOnly condition. This block should be returned by the first Recv().
@@ -695,7 +695,7 @@ func TestStreamBlocks_CapellaValid(t *testing.T) {
marshalledSignedBeaconBlockContainer1, err := json.Marshal(signedBeaconBlockContainer1)
require.NoError(t, err)
handler.EXPECT().Get(
jsonRestHandler.EXPECT().Get(
gomock.Any(),
"/eth/v2/beacon/blocks/head",
&signedBlockResponseJson,
@@ -732,7 +732,7 @@ func TestStreamBlocks_CapellaValid(t *testing.T) {
marshalledSignedBeaconBlockContainer2, err := json.Marshal(signedBeaconBlockContainer2)
require.NoError(t, err)
handler.EXPECT().Get(
jsonRestHandler.EXPECT().Get(
gomock.Any(),
"/eth/v2/beacon/blocks/head",
&signedBlockResponseJson,
@@ -759,7 +759,7 @@ func TestStreamBlocks_CapellaValid(t *testing.T) {
// The fourth call is only necessary when verifiedOnly == true since the previous block was optimistic
if testCase.verifiedOnly {
handler.EXPECT().Get(
jsonRestHandler.EXPECT().Get(
gomock.Any(),
"/eth/v2/beacon/blocks/head",
&signedBlockResponseJson,
@@ -782,7 +782,7 @@ func TestStreamBlocks_CapellaValid(t *testing.T) {
).Times(1)
}
validatorClient := &beaconApiValidatorClient{handler: handler, beaconBlockConverter: beaconBlockConverter}
validatorClient := &beaconApiValidatorClient{jsonRestHandler: jsonRestHandler, beaconBlockConverter: beaconBlockConverter}
streamBlocksClient := validatorClient.streamBlocks(ctx, &eth.StreamBlocksRequest{VerifiedOnly: testCase.verifiedOnly}, time.Millisecond*100)
// Get the first block
@@ -841,7 +841,7 @@ func TestStreamBlocks_DenebValid(t *testing.T) {
ctx := t.Context()
signedBlockResponseJson := abstractSignedBlockResponseJson{}
handler := mock.NewMockJsonRestHandler(ctrl)
jsonRestHandler := mock.NewMockJsonRestHandler(ctrl)
beaconBlockConverter := mock.NewMockBeaconBlockConverter(ctrl)
// For the first call, return a block that satisfies the verifiedOnly condition. This block should be returned by the first Recv().
@@ -856,7 +856,7 @@ func TestStreamBlocks_DenebValid(t *testing.T) {
marshalledSignedBeaconBlockContainer1, err := json.Marshal(denebBlock)
require.NoError(t, err)
handler.EXPECT().Get(
jsonRestHandler.EXPECT().Get(
gomock.Any(),
"/eth/v2/beacon/blocks/head",
&signedBlockResponseJson,
@@ -885,7 +885,7 @@ func TestStreamBlocks_DenebValid(t *testing.T) {
marshalledSignedBeaconBlockContainer2, err := json.Marshal(denebBlock2)
require.NoError(t, err)
handler.EXPECT().Get(
jsonRestHandler.EXPECT().Get(
gomock.Any(),
"/eth/v2/beacon/blocks/head",
&signedBlockResponseJson,
@@ -902,7 +902,7 @@ func TestStreamBlocks_DenebValid(t *testing.T) {
// The fourth call is only necessary when verifiedOnly == true since the previous block was optimistic
if testCase.verifiedOnly {
handler.EXPECT().Get(
jsonRestHandler.EXPECT().Get(
gomock.Any(),
"/eth/v2/beacon/blocks/head",
&signedBlockResponseJson,
@@ -918,7 +918,7 @@ func TestStreamBlocks_DenebValid(t *testing.T) {
).Times(1)
}
validatorClient := &beaconApiValidatorClient{handler: handler, beaconBlockConverter: beaconBlockConverter}
validatorClient := &beaconApiValidatorClient{jsonRestHandler: jsonRestHandler, beaconBlockConverter: beaconBlockConverter}
streamBlocksClient := validatorClient.streamBlocks(ctx, &eth.StreamBlocksRequest{VerifiedOnly: testCase.verifiedOnly}, time.Millisecond*100)
// Get the first block

View File

@@ -129,7 +129,7 @@ func (c *beaconApiValidatorClient) aggregateAttestation(
endpoint := apiutil.BuildURL("/eth/v2/validator/aggregate_attestation", params)
var aggregateAttestationResponse structs.AggregateAttestationResponse
err := c.handler.Get(ctx, endpoint, &aggregateAttestationResponse)
err := c.jsonRestHandler.Get(ctx, endpoint, &aggregateAttestationResponse)
if err != nil {
return nil, err
}
@@ -150,7 +150,7 @@ func (c *beaconApiValidatorClient) aggregateAttestationElectra(
endpoint := apiutil.BuildURL("/eth/v2/validator/aggregate_attestation", params)
var aggregateAttestationResponse structs.AggregateAttestationResponse
if err := c.handler.Get(ctx, endpoint, &aggregateAttestationResponse); err != nil {
if err := c.jsonRestHandler.Get(ctx, endpoint, &aggregateAttestationResponse); err != nil {
return nil, err
}

View File

@@ -94,10 +94,10 @@ func TestSubmitAggregateSelectionProof(t *testing.T) {
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
ctx := t.Context()
handler := mock.NewMockJsonRestHandler(ctrl)
jsonRestHandler := mock.NewMockJsonRestHandler(ctrl)
// Call node syncing endpoint to check if head is optimistic.
handler.EXPECT().Get(
jsonRestHandler.EXPECT().Get(
gomock.Any(),
syncingEndpoint,
&structs.SyncStatusResponse{},
@@ -113,7 +113,7 @@ func TestSubmitAggregateSelectionProof(t *testing.T) {
).Times(1)
// Call attestation data to get attestation data root to query aggregate attestation.
handler.EXPECT().Get(
jsonRestHandler.EXPECT().Get(
gomock.Any(),
fmt.Sprintf("%s?committee_index=%d&slot=%d", attestationDataEndpoint, committeeIndex, slot),
&structs.GetAttestationDataResponse{},
@@ -128,7 +128,7 @@ func TestSubmitAggregateSelectionProof(t *testing.T) {
require.NoError(t, err)
// Call attestation data to get attestation data root to query aggregate attestation.
handler.EXPECT().Get(
jsonRestHandler.EXPECT().Get(
gomock.Any(),
fmt.Sprintf("%s?attestation_data_root=%s&committee_index=%d&slot=%d", aggregateAttestationEndpoint, hexutil.Encode(attestationDataRootBytes[:]), committeeIndex, slot),
&structs.AggregateAttestationResponse{},
@@ -156,12 +156,12 @@ func TestSubmitAggregateSelectionProof(t *testing.T) {
}
validatorClient := &beaconApiValidatorClient{
handler: handler,
jsonRestHandler: jsonRestHandler,
stateValidatorsProvider: beaconApiStateValidatorsProvider{
handler: handler,
jsonRestHandler: jsonRestHandler,
},
dutiesProvider: beaconApiDutiesProvider{
handler: handler,
jsonRestHandler: jsonRestHandler,
},
}
@@ -263,10 +263,10 @@ func TestSubmitAggregateSelectionProofElectra(t *testing.T) {
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
ctx := t.Context()
handler := mock.NewMockJsonRestHandler(ctrl)
jsonRestHandler := mock.NewMockJsonRestHandler(ctrl)
// Call node syncing endpoint to check if head is optimistic.
handler.EXPECT().Get(
jsonRestHandler.EXPECT().Get(
gomock.Any(),
syncingEndpoint,
&structs.SyncStatusResponse{},
@@ -282,7 +282,7 @@ func TestSubmitAggregateSelectionProofElectra(t *testing.T) {
).Times(1)
// Call attestation data to get attestation data root to query aggregate attestation.
handler.EXPECT().Get(
jsonRestHandler.EXPECT().Get(
gomock.Any(),
fmt.Sprintf("%s?committee_index=%d&slot=%d", attestationDataEndpoint, committeeIndex, slot),
&structs.GetAttestationDataResponse{},
@@ -297,7 +297,7 @@ func TestSubmitAggregateSelectionProofElectra(t *testing.T) {
require.NoError(t, err)
// Call attestation data to get attestation data root to query aggregate attestation.
handler.EXPECT().Get(
jsonRestHandler.EXPECT().Get(
gomock.Any(),
fmt.Sprintf("%s?attestation_data_root=%s&committee_index=%d&slot=%d", aggregateAttestationEndpoint, hexutil.Encode(attestationDataRootBytes[:]), committeeIndex, slot),
&structs.AggregateAttestationResponse{},
@@ -325,12 +325,12 @@ func TestSubmitAggregateSelectionProofElectra(t *testing.T) {
}
validatorClient := &beaconApiValidatorClient{
handler: handler,
jsonRestHandler: jsonRestHandler,
stateValidatorsProvider: beaconApiStateValidatorsProvider{
handler: handler,
jsonRestHandler: jsonRestHandler,
},
dutiesProvider: beaconApiDutiesProvider{
handler: handler,
jsonRestHandler: jsonRestHandler,
},
}

View File

@@ -18,7 +18,7 @@ func (c *beaconApiValidatorClient) submitSignedAggregateSelectionProof(ctx conte
return nil, errors.Wrap(err, "failed to marshal SignedAggregateAttestationAndProof")
}
headers := map[string]string{"Eth-Consensus-Version": version.String(in.SignedAggregateAndProof.Version())}
err = c.handler.Post(ctx, "/eth/v2/validator/aggregate_and_proofs", headers, bytes.NewBuffer(body), nil)
err = c.jsonRestHandler.Post(ctx, "/eth/v2/validator/aggregate_and_proofs", headers, bytes.NewBuffer(body), nil)
if err != nil {
return nil, err
}
@@ -39,7 +39,7 @@ func (c *beaconApiValidatorClient) submitSignedAggregateSelectionProofElectra(ct
dataSlot := in.SignedAggregateAndProof.Message.Aggregate.Data.Slot
consensusVersion := version.String(slots.ToForkVersion(dataSlot))
headers := map[string]string{"Eth-Consensus-Version": consensusVersion}
if err = c.handler.Post(ctx, "/eth/v2/validator/aggregate_and_proofs", headers, bytes.NewBuffer(body), nil); err != nil {
if err = c.jsonRestHandler.Post(ctx, "/eth/v2/validator/aggregate_and_proofs", headers, bytes.NewBuffer(body), nil); err != nil {
return nil, err
}

View File

@@ -28,8 +28,8 @@ func TestSubmitSignedAggregateSelectionProof_Valid(t *testing.T) {
ctx := t.Context()
headers := map[string]string{"Eth-Consensus-Version": version.String(signedAggregateAndProof.Message.Version())}
handler := mock.NewMockJsonRestHandler(ctrl)
handler.EXPECT().Post(
jsonRestHandler := mock.NewMockJsonRestHandler(ctrl)
jsonRestHandler.EXPECT().Post(
gomock.Any(),
"/eth/v2/validator/aggregate_and_proofs",
headers,
@@ -42,7 +42,7 @@ func TestSubmitSignedAggregateSelectionProof_Valid(t *testing.T) {
attestationDataRoot, err := signedAggregateAndProof.Message.Aggregate.Data.HashTreeRoot()
require.NoError(t, err)
validatorClient := &beaconApiValidatorClient{handler: handler}
validatorClient := &beaconApiValidatorClient{jsonRestHandler: jsonRestHandler}
resp, err := validatorClient.submitSignedAggregateSelectionProof(ctx, &ethpb.SignedAggregateSubmitRequest{
SignedAggregateAndProof: signedAggregateAndProof,
})
@@ -60,8 +60,8 @@ func TestSubmitSignedAggregateSelectionProof_BadRequest(t *testing.T) {
ctx := t.Context()
headers := map[string]string{"Eth-Consensus-Version": version.String(signedAggregateAndProof.Message.Version())}
handler := mock.NewMockJsonRestHandler(ctrl)
handler.EXPECT().Post(
jsonRestHandler := mock.NewMockJsonRestHandler(ctrl)
jsonRestHandler.EXPECT().Post(
gomock.Any(),
"/eth/v2/validator/aggregate_and_proofs",
headers,
@@ -71,7 +71,7 @@ func TestSubmitSignedAggregateSelectionProof_BadRequest(t *testing.T) {
errors.New("bad request"),
).Times(1)
validatorClient := &beaconApiValidatorClient{handler: handler}
validatorClient := &beaconApiValidatorClient{jsonRestHandler: jsonRestHandler}
_, err = validatorClient.submitSignedAggregateSelectionProof(ctx, &ethpb.SignedAggregateSubmitRequest{
SignedAggregateAndProof: signedAggregateAndProof,
})
@@ -93,8 +93,8 @@ func TestSubmitSignedAggregateSelectionProofElectra_Valid(t *testing.T) {
ctx := t.Context()
expectedVersion := version.String(slots.ToForkVersion(signedAggregateAndProofElectra.Message.Aggregate.Data.Slot))
headers := map[string]string{"Eth-Consensus-Version": expectedVersion}
handler := mock.NewMockJsonRestHandler(ctrl)
handler.EXPECT().Post(
jsonRestHandler := mock.NewMockJsonRestHandler(ctrl)
jsonRestHandler.EXPECT().Post(
gomock.Any(),
"/eth/v2/validator/aggregate_and_proofs",
headers,
@@ -107,7 +107,7 @@ func TestSubmitSignedAggregateSelectionProofElectra_Valid(t *testing.T) {
attestationDataRoot, err := signedAggregateAndProofElectra.Message.Aggregate.Data.HashTreeRoot()
require.NoError(t, err)
validatorClient := &beaconApiValidatorClient{handler: handler}
validatorClient := &beaconApiValidatorClient{jsonRestHandler: jsonRestHandler}
resp, err := validatorClient.submitSignedAggregateSelectionProofElectra(ctx, &ethpb.SignedAggregateSubmitElectraRequest{
SignedAggregateAndProof: signedAggregateAndProofElectra,
})
@@ -130,8 +130,8 @@ func TestSubmitSignedAggregateSelectionProofElectra_BadRequest(t *testing.T) {
ctx := t.Context()
expectedVersion := version.String(slots.ToForkVersion(signedAggregateAndProofElectra.Message.Aggregate.Data.Slot))
headers := map[string]string{"Eth-Consensus-Version": expectedVersion}
handler := mock.NewMockJsonRestHandler(ctrl)
handler.EXPECT().Post(
jsonRestHandler := mock.NewMockJsonRestHandler(ctrl)
jsonRestHandler.EXPECT().Post(
gomock.Any(),
"/eth/v2/validator/aggregate_and_proofs",
headers,
@@ -141,7 +141,7 @@ func TestSubmitSignedAggregateSelectionProofElectra_BadRequest(t *testing.T) {
errors.New("bad request"),
).Times(1)
validatorClient := &beaconApiValidatorClient{handler: handler}
validatorClient := &beaconApiValidatorClient{jsonRestHandler: jsonRestHandler}
_, err = validatorClient.submitSignedAggregateSelectionProofElectra(ctx, &ethpb.SignedAggregateSubmitElectraRequest{
SignedAggregateAndProof: signedAggregateAndProofElectra,
})
@@ -163,8 +163,8 @@ func TestSubmitSignedAggregateSelectionProofElectra_FuluVersion(t *testing.T) {
ctx := t.Context()
expectedVersion := version.String(slots.ToForkVersion(signedAggregateAndProofElectra.Message.Aggregate.Data.Slot))
headers := map[string]string{"Eth-Consensus-Version": expectedVersion}
handler := mock.NewMockJsonRestHandler(ctrl)
handler.EXPECT().Post(
jsonRestHandler := mock.NewMockJsonRestHandler(ctrl)
jsonRestHandler.EXPECT().Post(
gomock.Any(),
"/eth/v2/validator/aggregate_and_proofs",
headers,
@@ -177,7 +177,7 @@ func TestSubmitSignedAggregateSelectionProofElectra_FuluVersion(t *testing.T) {
attestationDataRoot, err := signedAggregateAndProofElectra.Message.Aggregate.Data.HashTreeRoot()
require.NoError(t, err)
validatorClient := &beaconApiValidatorClient{handler: handler}
validatorClient := &beaconApiValidatorClient{jsonRestHandler: jsonRestHandler}
resp, err := validatorClient.submitSignedAggregateSelectionProofElectra(ctx, &ethpb.SignedAggregateSubmitElectraRequest{
SignedAggregateAndProof: signedAggregateAndProofElectra,
})

View File

@@ -47,7 +47,7 @@ func (c *beaconApiValidatorClient) submitSignedContributionAndProof(ctx context.
return errors.Wrap(err, "failed to marshall signed contribution and proof")
}
return c.handler.Post(
return c.jsonRestHandler.Post(
ctx,
"/eth/v1/validator/contribution_and_proofs",
nil,

View File

@@ -43,8 +43,8 @@ func TestSubmitSignedContributionAndProof_Valid(t *testing.T) {
ctx := t.Context()
handler := mock.NewMockJsonRestHandler(ctrl)
handler.EXPECT().Post(
jsonRestHandler := mock.NewMockJsonRestHandler(ctrl)
jsonRestHandler.EXPECT().Post(
gomock.Any(),
submitSignedContributionAndProofTestEndpoint,
nil,
@@ -69,7 +69,7 @@ func TestSubmitSignedContributionAndProof_Valid(t *testing.T) {
Signature: []byte{8},
}
validatorClient := &beaconApiValidatorClient{handler: handler}
validatorClient := &beaconApiValidatorClient{jsonRestHandler: jsonRestHandler}
err = validatorClient.submitSignedContributionAndProof(ctx, contributionAndProof)
require.NoError(t, err)
}
@@ -117,9 +117,9 @@ func TestSubmitSignedContributionAndProof_Error(t *testing.T) {
ctx := t.Context()
handler := mock.NewMockJsonRestHandler(ctrl)
jsonRestHandler := mock.NewMockJsonRestHandler(ctrl)
if testCase.httpRequestExpected {
handler.EXPECT().Post(
jsonRestHandler.EXPECT().Post(
gomock.Any(),
submitSignedContributionAndProofTestEndpoint,
gomock.Any(),
@@ -130,7 +130,7 @@ func TestSubmitSignedContributionAndProof_Error(t *testing.T) {
).Times(1)
}
validatorClient := &beaconApiValidatorClient{handler: handler}
validatorClient := &beaconApiValidatorClient{jsonRestHandler: jsonRestHandler}
err := validatorClient.submitSignedContributionAndProof(ctx, testCase.data)
assert.ErrorContains(t, testCase.expectedErrorMessage, err)
})

View File

@@ -36,7 +36,7 @@ func (c *beaconApiValidatorClient) subscribeCommitteeSubnets(ctx context.Context
return errors.Wrap(err, "failed to marshal committees subscriptions")
}
return c.handler.Post(
return c.jsonRestHandler.Post(
ctx,
"/eth/v1/validator/beacon_committee_subscriptions",
nil,

View File

@@ -44,8 +44,8 @@ func TestSubscribeCommitteeSubnets_Valid(t *testing.T) {
ctx := t.Context()
handler := mock.NewMockJsonRestHandler(ctrl)
handler.EXPECT().Post(
jsonRestHandler := mock.NewMockJsonRestHandler(ctrl)
jsonRestHandler.EXPECT().Post(
gomock.Any(),
subscribeCommitteeSubnetsTestEndpoint,
nil,
@@ -66,7 +66,7 @@ func TestSubscribeCommitteeSubnets_Valid(t *testing.T) {
}
validatorClient := &beaconApiValidatorClient{
handler: handler,
jsonRestHandler: jsonRestHandler,
}
err = validatorClient.subscribeCommitteeSubnets(
ctx,
@@ -205,9 +205,9 @@ func TestSubscribeCommitteeSubnets_Error(t *testing.T) {
ctx := t.Context()
handler := mock.NewMockJsonRestHandler(ctrl)
jsonRestHandler := mock.NewMockJsonRestHandler(ctrl)
if testCase.expectSubscribeRestCall {
handler.EXPECT().Post(
jsonRestHandler.EXPECT().Post(
gomock.Any(),
subscribeCommitteeSubnetsTestEndpoint,
gomock.Any(),
@@ -219,7 +219,7 @@ func TestSubscribeCommitteeSubnets_Error(t *testing.T) {
}
validatorClient := &beaconApiValidatorClient{
handler: handler,
jsonRestHandler: jsonRestHandler,
}
err := validatorClient.subscribeCommitteeSubnets(ctx, testCase.subscribeRequest, testCase.duties)
assert.ErrorContains(t, testCase.expectedErrorMessage, err)

View File

@@ -31,13 +31,13 @@ func (c *beaconApiValidatorClient) submitSyncMessage(ctx context.Context, syncMe
return errors.Wrap(err, "failed to marshal sync committee message")
}
return c.handler.Post(ctx, endpoint, nil, bytes.NewBuffer(marshalledJsonSyncCommitteeMessage), nil)
return c.jsonRestHandler.Post(ctx, endpoint, nil, bytes.NewBuffer(marshalledJsonSyncCommitteeMessage), nil)
}
func (c *beaconApiValidatorClient) syncMessageBlockRoot(ctx context.Context) (*ethpb.SyncMessageBlockRootResponse, error) {
// Get head beacon block root.
var resp structs.BlockRootResponse
if err := c.handler.Get(ctx, "/eth/v1/beacon/blocks/head/root", &resp); err != nil {
if err := c.jsonRestHandler.Get(ctx, "/eth/v1/beacon/blocks/head/root", &resp); err != nil {
return nil, err
}
@@ -82,7 +82,7 @@ func (c *beaconApiValidatorClient) syncCommitteeContribution(
params.Add("beacon_block_root", blockRoot)
var resp structs.ProduceSyncCommitteeContributionResponse
if err = c.handler.Get(ctx, apiutil.BuildURL("/eth/v1/validator/sync_committee_contribution", params), &resp); err != nil {
if err = c.jsonRestHandler.Get(ctx, apiutil.BuildURL("/eth/v1/validator/sync_committee_contribution", params), &resp); err != nil {
return nil, err
}

View File

@@ -20,7 +20,7 @@ func (c *beaconApiValidatorClient) aggregatedSyncSelections(ctx context.Context,
}
var resp aggregatedSyncSelectionResponse
err = c.handler.Post(ctx, "/eth/v1/validator/sync_committee_selections", nil, bytes.NewBuffer(body), &resp)
err = c.jsonRestHandler.Post(ctx, "/eth/v1/validator/sync_committee_selections", nil, bytes.NewBuffer(body), &resp)
if err != nil {
return nil, errors.Wrap(err, "error calling post endpoint")
}

View File

@@ -96,13 +96,13 @@ func TestGetAggregatedSyncSelections(t *testing.T) {
for _, test := range testcases {
t.Run(test.name, func(t *testing.T) {
ctrl := gomock.NewController(t)
handler := mock.NewMockJsonRestHandler(ctrl)
jsonRestHandler := mock.NewMockJsonRestHandler(ctrl)
reqBody, err := json.Marshal(test.req)
require.NoError(t, err)
ctx := t.Context()
handler.EXPECT().Post(
jsonRestHandler.EXPECT().Post(
gomock.Any(),
"/eth/v1/validator/sync_committee_selections",
nil,
@@ -115,7 +115,7 @@ func TestGetAggregatedSyncSelections(t *testing.T) {
test.endpointError,
).Times(1)
validatorClient := &beaconApiValidatorClient{handler: handler}
validatorClient := &beaconApiValidatorClient{jsonRestHandler: jsonRestHandler}
res, err := validatorClient.AggregatedSyncSelections(ctx, test.req)
if test.expectedErrorMessage != "" {
require.ErrorContains(t, test.expectedErrorMessage, err)

View File

@@ -44,8 +44,8 @@ func TestSubmitSyncMessage_Valid(t *testing.T) {
marshalledJsonRegistrations, err := json.Marshal([]*structs.SyncCommitteeMessage{jsonSyncCommitteeMessage})
require.NoError(t, err)
handler := mock.NewMockJsonRestHandler(ctrl)
handler.EXPECT().Post(
jsonRestHandler := mock.NewMockJsonRestHandler(ctrl)
jsonRestHandler.EXPECT().Post(
gomock.Any(),
"/eth/v1/beacon/pool/sync_committees",
nil,
@@ -62,7 +62,7 @@ func TestSubmitSyncMessage_Valid(t *testing.T) {
Signature: decodedSignature,
}
validatorClient := &beaconApiValidatorClient{handler: handler}
validatorClient := &beaconApiValidatorClient{jsonRestHandler: jsonRestHandler}
res, err := validatorClient.SubmitSyncMessage(t.Context(), &protoSyncCommitteeMessage)
assert.DeepEqual(t, new(empty.Empty), res)
@@ -73,8 +73,8 @@ func TestSubmitSyncMessage_BadRequest(t *testing.T) {
ctrl := gomock.NewController(t)
defer ctrl.Finish()
handler := mock.NewMockJsonRestHandler(ctrl)
handler.EXPECT().Post(
jsonRestHandler := mock.NewMockJsonRestHandler(ctrl)
jsonRestHandler.EXPECT().Post(
gomock.Any(),
"/eth/v1/beacon/pool/sync_committees",
nil,
@@ -84,7 +84,7 @@ func TestSubmitSyncMessage_BadRequest(t *testing.T) {
errors.New("foo error"),
).Times(1)
validatorClient := &beaconApiValidatorClient{handler: handler}
validatorClient := &beaconApiValidatorClient{jsonRestHandler: jsonRestHandler}
_, err := validatorClient.SubmitSyncMessage(t.Context(), &ethpb.SyncCommitteeMessage{})
assert.ErrorContains(t, "foo error", err)
}
@@ -137,8 +137,8 @@ func TestGetSyncMessageBlockRoot(t *testing.T) {
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
ctx := t.Context()
handler := mock.NewMockJsonRestHandler(ctrl)
handler.EXPECT().Get(
jsonRestHandler := mock.NewMockJsonRestHandler(ctrl)
jsonRestHandler.EXPECT().Get(
gomock.Any(),
"/eth/v1/beacon/blocks/head/root",
&structs.BlockRootResponse{},
@@ -149,7 +149,7 @@ func TestGetSyncMessageBlockRoot(t *testing.T) {
test.endpointError,
).Times(1)
validatorClient := &beaconApiValidatorClient{handler: handler}
validatorClient := &beaconApiValidatorClient{jsonRestHandler: jsonRestHandler}
actualResponse, err := validatorClient.syncMessageBlockRoot(ctx)
if test.expectedErrorMessage != "" {
require.ErrorContains(t, test.expectedErrorMessage, err)
@@ -207,8 +207,8 @@ func TestGetSyncCommitteeContribution(t *testing.T) {
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
ctx := t.Context()
handler := mock.NewMockJsonRestHandler(ctrl)
handler.EXPECT().Get(
jsonRestHandler := mock.NewMockJsonRestHandler(ctrl)
jsonRestHandler.EXPECT().Get(
gomock.Any(),
"/eth/v1/beacon/blocks/head/root",
&structs.BlockRootResponse{},
@@ -223,7 +223,7 @@ func TestGetSyncCommitteeContribution(t *testing.T) {
nil,
).Times(1)
handler.EXPECT().Get(
jsonRestHandler.EXPECT().Get(
gomock.Any(),
fmt.Sprintf("/eth/v1/validator/sync_committee_contribution?beacon_block_root=%s&slot=%d&subcommittee_index=%d",
blockRoot, uint64(request.Slot), request.SubnetId),
@@ -235,7 +235,7 @@ func TestGetSyncCommitteeContribution(t *testing.T) {
test.endpointErr,
).Times(1)
validatorClient := &beaconApiValidatorClient{handler: handler}
validatorClient := &beaconApiValidatorClient{jsonRestHandler: jsonRestHandler}
actualResponse, err := validatorClient.syncCommitteeContribution(ctx, request)
if test.expectedErrMsg != "" {
require.ErrorContains(t, test.expectedErrMsg, err)
@@ -314,8 +314,8 @@ func TestGetSyncSubCommitteeIndex(t *testing.T) {
}
valsReqBytes, err := json.Marshal(valsReq)
require.NoError(t, err)
handler := mock.NewMockJsonRestHandler(ctrl)
handler.EXPECT().Post(
jsonRestHandler := mock.NewMockJsonRestHandler(ctrl)
jsonRestHandler.EXPECT().Post(
gomock.Any(),
validatorsEndpoint,
nil,
@@ -350,7 +350,7 @@ func TestGetSyncSubCommitteeIndex(t *testing.T) {
query := apiutil.BuildURL("/eth/v1/beacon/states/head/validators", queryParams)
handler.EXPECT().Get(
jsonRestHandler.EXPECT().Get(
gomock.Any(),
query,
&structs.GetValidatorsResponse{},
@@ -367,7 +367,7 @@ func TestGetSyncSubCommitteeIndex(t *testing.T) {
syncDutiesCalled = 1
}
handler.EXPECT().Post(
jsonRestHandler.EXPECT().Post(
gomock.Any(),
fmt.Sprintf("%s/%d", syncDutiesEndpoint, slots.ToEpoch(slot)),
nil,
@@ -386,12 +386,12 @@ func TestGetSyncSubCommitteeIndex(t *testing.T) {
require.NoError(t, err)
validatorClient := &beaconApiValidatorClient{
handler: handler,
jsonRestHandler: jsonRestHandler,
stateValidatorsProvider: beaconApiStateValidatorsProvider{
handler: handler,
jsonRestHandler: jsonRestHandler,
},
dutiesProvider: beaconApiDutiesProvider{
handler: handler,
jsonRestHandler: jsonRestHandler,
},
}
actualResponse, err := validatorClient.syncSubcommitteeIndex(ctx, &ethpb.SyncSubcommitteeIndexRequest{

View File

@@ -21,8 +21,8 @@ func TestWaitForChainStart_ValidGenesis(t *testing.T) {
ctx := t.Context()
genesisResponseJson := structs.GetGenesisResponse{}
handler := mock.NewMockJsonRestHandler(ctrl)
handler.EXPECT().Get(
jsonRestHandler := mock.NewMockJsonRestHandler(ctrl)
jsonRestHandler.EXPECT().Get(
gomock.Any(),
"/eth/v1/beacon/genesis",
&genesisResponseJson,
@@ -38,7 +38,7 @@ func TestWaitForChainStart_ValidGenesis(t *testing.T) {
},
).Times(1)
genesisProvider := beaconApiGenesisProvider{handler: handler}
genesisProvider := beaconApiGenesisProvider{jsonRestHandler: jsonRestHandler}
validatorClient := beaconApiValidatorClient{genesisProvider: &genesisProvider}
resp, err := validatorClient.WaitForChainStart(ctx, &emptypb.Empty{})
assert.NoError(t, err)
@@ -88,8 +88,8 @@ func TestWaitForChainStart_BadGenesis(t *testing.T) {
ctx := t.Context()
genesisResponseJson := structs.GetGenesisResponse{}
handler := mock.NewMockJsonRestHandler(ctrl)
handler.EXPECT().Get(
jsonRestHandler := mock.NewMockJsonRestHandler(ctrl)
jsonRestHandler.EXPECT().Get(
gomock.Any(),
"/eth/v1/beacon/genesis",
&genesisResponseJson,
@@ -102,7 +102,7 @@ func TestWaitForChainStart_BadGenesis(t *testing.T) {
},
).Times(1)
genesisProvider := beaconApiGenesisProvider{handler: handler}
genesisProvider := beaconApiGenesisProvider{jsonRestHandler: jsonRestHandler}
validatorClient := beaconApiValidatorClient{genesisProvider: &genesisProvider}
_, err := validatorClient.WaitForChainStart(ctx, &emptypb.Empty{})
assert.ErrorContains(t, testCase.errorMessage, err)
@@ -116,8 +116,8 @@ func TestWaitForChainStart_JsonResponseError(t *testing.T) {
ctx := t.Context()
genesisResponseJson := structs.GetGenesisResponse{}
handler := mock.NewMockJsonRestHandler(ctrl)
handler.EXPECT().Get(
jsonRestHandler := mock.NewMockJsonRestHandler(ctrl)
jsonRestHandler.EXPECT().Get(
gomock.Any(),
"/eth/v1/beacon/genesis",
&genesisResponseJson,
@@ -125,7 +125,7 @@ func TestWaitForChainStart_JsonResponseError(t *testing.T) {
errors.New("some specific json error"),
).Times(1)
genesisProvider := beaconApiGenesisProvider{handler: handler}
genesisProvider := beaconApiGenesisProvider{jsonRestHandler: jsonRestHandler}
validatorClient := beaconApiValidatorClient{genesisProvider: &genesisProvider}
_, err := validatorClient.WaitForChainStart(ctx, &emptypb.Empty{})
assert.ErrorContains(t, "failed to get genesis data", err)
@@ -139,10 +139,10 @@ func TestWaitForChainStart_JsonResponseError404(t *testing.T) {
ctx := t.Context()
genesisResponseJson := structs.GetGenesisResponse{}
handler := mock.NewMockJsonRestHandler(ctrl)
jsonRestHandler := mock.NewMockJsonRestHandler(ctrl)
// First, mock a request that receives a 404 error (which means that the genesis data is not available yet)
handler.EXPECT().Get(
jsonRestHandler.EXPECT().Get(
gomock.Any(),
"/eth/v1/beacon/genesis",
&genesisResponseJson,
@@ -154,7 +154,7 @@ func TestWaitForChainStart_JsonResponseError404(t *testing.T) {
).Times(1)
// After receiving a 404 error, mock a request that actually has genesis data available
handler.EXPECT().Get(
jsonRestHandler.EXPECT().Get(
gomock.Any(),
"/eth/v1/beacon/genesis",
&genesisResponseJson,
@@ -170,7 +170,7 @@ func TestWaitForChainStart_JsonResponseError404(t *testing.T) {
},
).Times(1)
genesisProvider := beaconApiGenesisProvider{handler: handler}
genesisProvider := beaconApiGenesisProvider{jsonRestHandler: jsonRestHandler}
validatorClient := beaconApiValidatorClient{genesisProvider: &genesisProvider}
resp, err := validatorClient.WaitForChainStart(ctx, &emptypb.Empty{})
assert.NoError(t, err)

View File

@@ -9,17 +9,19 @@ import (
validatorHelpers "github.com/OffchainLabs/prysm/v7/validator/helpers"
)
func NewChainClient(validatorConn validatorHelpers.NodeConnection) iface.ChainClient {
grpcClient := grpcApi.NewGrpcChainClient(validatorConn)
func NewChainClient(validatorConn validatorHelpers.NodeConnection, jsonRestHandler beaconApi.RestHandler) iface.ChainClient {
grpcClient := grpcApi.NewGrpcChainClient(validatorConn.GetGrpcClientConn())
if features.Get().EnableBeaconRESTApi {
return beaconApi.NewBeaconApiChainClientWithFallback(validatorConn.GetRestHandler(), grpcClient)
return beaconApi.NewBeaconApiChainClientWithFallback(jsonRestHandler, grpcClient)
} else {
return grpcClient
}
return grpcClient
}
func NewPrysmChainClient(validatorConn validatorHelpers.NodeConnection) iface.PrysmChainClient {
func NewPrysmChainClient(validatorConn validatorHelpers.NodeConnection, jsonRestHandler beaconApi.RestHandler) iface.PrysmChainClient {
if features.Get().EnableBeaconRESTApi {
return beaconApi.NewPrysmChainClient(validatorConn.GetRestHandler(), nodeClientFactory.NewNodeClient(validatorConn))
return beaconApi.NewPrysmChainClient(jsonRestHandler, nodeClientFactory.NewNodeClient(validatorConn, jsonRestHandler))
} else {
return grpcApi.NewGrpcPrysmChainClient(validatorConn.GetGrpcClientConn())
}
return grpcApi.NewGrpcPrysmChainClient(validatorConn)
}

View File

@@ -4,7 +4,6 @@ go_library(
name = "go_default_library",
srcs = [
"grpc_beacon_chain_client.go",
"grpc_client_manager.go",
"grpc_node_client.go",
"grpc_prysm_beacon_chain_client.go",
"grpc_validator_client.go",
@@ -15,7 +14,6 @@ go_library(
deps = [
"//api/client:go_default_library",
"//api/client/event:go_default_library",
"//api/failover:go_default_library",
"//api/server/structs:go_default_library",
"//beacon-chain/rpc/eth/helpers:go_default_library",
"//beacon-chain/state/state-native:go_default_library",
@@ -27,7 +25,6 @@ go_library(
"//proto/eth/v1:go_default_library",
"//proto/prysm/v1alpha1:go_default_library",
"//validator/client/iface:go_default_library",
"//validator/helpers:go_default_library",
"@com_github_ethereum_go_ethereum//common/hexutil:go_default_library",
"@com_github_golang_protobuf//ptypes/empty",
"@com_github_pkg_errors//:go_default_library",
@@ -42,15 +39,12 @@ go_test(
name = "go_default_test",
size = "small",
srcs = [
"grpc_client_manager_test.go",
"grpc_node_client_test.go",
"grpc_prysm_beacon_chain_client_test.go",
"grpc_validator_client_test.go",
],
embed = [":go_default_library"],
deps = [
"//api/client/event:go_default_library",
"//api/grpc:go_default_library",
"//api/server/structs:go_default_library",
"//config/params:go_default_library",
"//consensus-types/primitives:go_default_library",
@@ -62,11 +56,7 @@ go_test(
"//testing/util:go_default_library",
"//testing/validator-mock:go_default_library",
"//validator/client/iface:go_default_library",
"//validator/helpers:go_default_library",
"//validator/testing:go_default_library",
"@com_github_golang_protobuf//ptypes/empty",
"@com_github_sirupsen_logrus//hooks/test:go_default_library",
"@org_golang_google_grpc//:go_default_library",
"@org_golang_google_protobuf//types/known/emptypb:go_default_library",
"@org_uber_go_mock//gomock:go_default_library",
],

View File

@@ -5,42 +5,38 @@ import (
ethpb "github.com/OffchainLabs/prysm/v7/proto/prysm/v1alpha1"
"github.com/OffchainLabs/prysm/v7/validator/client/iface"
validatorHelpers "github.com/OffchainLabs/prysm/v7/validator/helpers"
"github.com/golang/protobuf/ptypes/empty"
"google.golang.org/grpc"
)
type grpcChainClient struct {
*grpcClientManager[ethpb.BeaconChainClient]
beaconChainClient ethpb.BeaconChainClient
}
func (c *grpcChainClient) ChainHead(ctx context.Context, in *empty.Empty) (*ethpb.ChainHead, error) {
return c.getClient().GetChainHead(ctx, in)
return c.beaconChainClient.GetChainHead(ctx, in)
}
func (c *grpcChainClient) ValidatorBalances(ctx context.Context, in *ethpb.ListValidatorBalancesRequest) (*ethpb.ValidatorBalances, error) {
return c.getClient().ListValidatorBalances(ctx, in)
return c.beaconChainClient.ListValidatorBalances(ctx, in)
}
func (c *grpcChainClient) Validators(ctx context.Context, in *ethpb.ListValidatorsRequest) (*ethpb.Validators, error) {
return c.getClient().ListValidators(ctx, in)
return c.beaconChainClient.ListValidators(ctx, in)
}
func (c *grpcChainClient) ValidatorQueue(ctx context.Context, in *empty.Empty) (*ethpb.ValidatorQueue, error) {
return c.getClient().GetValidatorQueue(ctx, in)
return c.beaconChainClient.GetValidatorQueue(ctx, in)
}
func (c *grpcChainClient) ValidatorPerformance(ctx context.Context, in *ethpb.ValidatorPerformanceRequest) (*ethpb.ValidatorPerformanceResponse, error) {
return c.getClient().GetValidatorPerformance(ctx, in)
return c.beaconChainClient.GetValidatorPerformance(ctx, in)
}
func (c *grpcChainClient) ValidatorParticipation(ctx context.Context, in *ethpb.GetValidatorParticipationRequest) (*ethpb.ValidatorParticipationResponse, error) {
return c.getClient().GetValidatorParticipation(ctx, in)
return c.beaconChainClient.GetValidatorParticipation(ctx, in)
}
// NewGrpcChainClient creates a new gRPC chain client that supports
// dynamic connection switching via the NodeConnection's GrpcConnectionProvider.
func NewGrpcChainClient(conn validatorHelpers.NodeConnection) iface.ChainClient {
return &grpcChainClient{
grpcClientManager: newGrpcClientManager(conn, ethpb.NewBeaconChainClient),
}
func NewGrpcChainClient(cc grpc.ClientConnInterface) iface.ChainClient {
return &grpcChainClient{ethpb.NewBeaconChainClient(cc)}
}

View File

@@ -1,47 +0,0 @@
package grpc_api
import (
"sync"
validatorHelpers "github.com/OffchainLabs/prysm/v7/validator/helpers"
"google.golang.org/grpc"
)
// grpcClientManager handles dynamic gRPC client recreation when the connection changes.
// It uses generics to work with any gRPC client type.
type grpcClientManager[T any] struct {
mu sync.Mutex
conn validatorHelpers.NodeConnection
client T
lastConnCounter uint64 // connection counter when client was last created; compared to detect host switches
newClient func(grpc.ClientConnInterface) T
}
// newGrpcClientManager creates a new client manager with the given connection and client constructor.
func newGrpcClientManager[T any](
conn validatorHelpers.NodeConnection,
newClient func(grpc.ClientConnInterface) T,
) *grpcClientManager[T] {
return &grpcClientManager[T]{
conn: conn,
newClient: newClient,
client: newClient(conn.GetGrpcClientConn()),
lastConnCounter: conn.GetGrpcConnectionProvider().ConnectionCounter(),
}
}
// getClient returns the current client, recreating it if the connection has changed.
// It uses the provider's connection counter rather than the host string to detect changes,
// which correctly handles host bounces (e.g., host0 → host1 → host0) where the host
// string returns to its original value but the underlying connection has been replaced.
func (m *grpcClientManager[T]) getClient() T {
m.mu.Lock()
defer m.mu.Unlock()
currentCounter := m.conn.GetGrpcConnectionProvider().ConnectionCounter()
if m.lastConnCounter != currentCounter {
m.client = m.newClient(m.conn.GetGrpcClientConn())
m.lastConnCounter = currentCounter
}
return m.client
}

View File

@@ -1,201 +0,0 @@
package grpc_api
import (
"sync"
"testing"
"github.com/OffchainLabs/prysm/v7/testing/assert"
"github.com/OffchainLabs/prysm/v7/testing/require"
validatorHelpers "github.com/OffchainLabs/prysm/v7/validator/helpers"
"google.golang.org/grpc"
)
// mockProvider implements grpcutil.GrpcConnectionProvider for testing.
type mockProvider struct {
hosts []string
currentIndex int
connCounter uint64
mu sync.Mutex
}
func (m *mockProvider) CurrentConn() *grpc.ClientConn { return nil }
func (m *mockProvider) Hosts() []string { return m.hosts }
func (m *mockProvider) Close() {}
func (m *mockProvider) CurrentHost() string {
m.mu.Lock()
defer m.mu.Unlock()
return m.hosts[m.currentIndex]
}
func (m *mockProvider) SwitchHost(index int) error {
m.mu.Lock()
defer m.mu.Unlock()
m.currentIndex = index
m.connCounter++
return nil
}
func (m *mockProvider) ConnectionCounter() uint64 {
m.mu.Lock()
defer m.mu.Unlock()
return m.connCounter
}
// nextHost is a test helper for round-robin simulation (not part of the interface).
func (m *mockProvider) nextHost() {
m.mu.Lock()
defer m.mu.Unlock()
m.currentIndex = (m.currentIndex + 1) % len(m.hosts)
m.connCounter++
}
// testClient is a simple type for testing the generic client manager.
type testClient struct{ id int }
// testManager creates a manager with client creation counting.
func testManager(t *testing.T, provider *mockProvider) (*grpcClientManager[*testClient], *int) {
conn, err := validatorHelpers.NewNodeConnection(validatorHelpers.WithGRPCProvider(provider))
require.NoError(t, err)
clientCount := new(int)
newClient := func(grpc.ClientConnInterface) *testClient {
*clientCount++
return &testClient{id: *clientCount}
}
manager := newGrpcClientManager(conn, newClient)
require.NotNil(t, manager)
return manager, clientCount
}
func TestGrpcClientManager(t *testing.T) {
t.Run("tracks connection counter", func(t *testing.T) {
provider := &mockProvider{hosts: []string{"host1:4000", "host2:4000"}}
manager, count := testManager(t, provider)
assert.Equal(t, 1, *count)
assert.Equal(t, uint64(0), manager.lastConnCounter)
})
t.Run("same host returns same client", func(t *testing.T) {
provider := &mockProvider{hosts: []string{"host1:4000", "host2:4000"}}
manager, count := testManager(t, provider)
c1, c2, c3 := manager.getClient(), manager.getClient(), manager.getClient()
assert.Equal(t, 1, *count)
assert.Equal(t, c1, c2)
assert.Equal(t, c2, c3)
})
t.Run("host change recreates client", func(t *testing.T) {
provider := &mockProvider{hosts: []string{"host1:4000", "host2:4000"}}
manager, count := testManager(t, provider)
c1 := manager.getClient()
assert.Equal(t, 1, c1.id)
provider.nextHost()
c2 := manager.getClient()
assert.Equal(t, 2, *count)
assert.Equal(t, 2, c2.id)
// Same host again - no recreation
c3 := manager.getClient()
assert.Equal(t, 2, *count)
assert.Equal(t, c2, c3)
})
t.Run("host bounce recreates client", func(t *testing.T) {
// Regression test: when host bounces (host0 → host1 → host0), the client
// must be recreated even though the host string returns to its original value,
// because the underlying *grpc.ClientConn was destroyed and replaced.
provider := &mockProvider{hosts: []string{"host1:4000", "host2:4000"}}
manager, count := testManager(t, provider)
c1 := manager.getClient()
assert.Equal(t, 1, c1.id)
// Switch to host2
provider.nextHost()
c2 := manager.getClient()
assert.Equal(t, 2, *count)
assert.Equal(t, 2, c2.id)
// Switch back to host1 — same host string but new connection
provider.nextHost()
assert.Equal(t, "host1:4000", provider.CurrentHost())
c3 := manager.getClient()
assert.Equal(t, 3, *count, "client should be recreated on host bounce")
assert.Equal(t, 3, c3.id)
})
t.Run("multiple host switches", func(t *testing.T) {
provider := &mockProvider{hosts: []string{"host1:4000", "host2:4000", "host3:4000"}}
manager, count := testManager(t, provider)
assert.Equal(t, 1, *count)
for expected := 2; expected <= 4; expected++ {
provider.nextHost()
_ = manager.getClient()
assert.Equal(t, expected, *count)
}
})
}
func TestGrpcClientManager_Concurrent(t *testing.T) {
t.Run("concurrent access same host", func(t *testing.T) {
provider := &mockProvider{hosts: []string{"host1:4000", "host2:4000"}}
manager, _ := testManager(t, provider)
var clientCount int
var countMu sync.Mutex
// Override with thread-safe counter
manager.newClient = func(grpc.ClientConnInterface) *testClient {
countMu.Lock()
clientCount++
id := clientCount
countMu.Unlock()
return &testClient{id: id}
}
manager.client = manager.newClient(nil)
clientCount = 1
var wg sync.WaitGroup
for range 100 {
wg.Go(func() { _ = manager.getClient() })
}
wg.Wait()
countMu.Lock()
assert.Equal(t, 1, clientCount)
countMu.Unlock()
})
t.Run("concurrent with host changes", func(t *testing.T) {
provider := &mockProvider{hosts: []string{"host1:4000", "host2:4000"}}
manager, _ := testManager(t, provider)
var clientCount int
var countMu sync.Mutex
manager.newClient = func(grpc.ClientConnInterface) *testClient {
countMu.Lock()
clientCount++
id := clientCount
countMu.Unlock()
return &testClient{id: id}
}
manager.client = manager.newClient(nil)
clientCount = 1
var wg sync.WaitGroup
for range 50 {
wg.Go(func() { _ = manager.getClient() })
wg.Go(func() { provider.nextHost() })
}
wg.Wait()
countMu.Lock()
assert.NotEqual(t, 0, clientCount, "Should have created at least one client")
countMu.Unlock()
})
}

View File

@@ -5,8 +5,8 @@ import (
ethpb "github.com/OffchainLabs/prysm/v7/proto/prysm/v1alpha1"
"github.com/OffchainLabs/prysm/v7/validator/client/iface"
validatorHelpers "github.com/OffchainLabs/prysm/v7/validator/helpers"
"github.com/golang/protobuf/ptypes/empty"
"google.golang.org/grpc"
)
var (
@@ -14,40 +14,35 @@ var (
)
type grpcNodeClient struct {
*grpcClientManager[ethpb.NodeClient]
nodeClient ethpb.NodeClient
}
func (c *grpcNodeClient) SyncStatus(ctx context.Context, in *empty.Empty) (*ethpb.SyncStatus, error) {
return c.getClient().GetSyncStatus(ctx, in)
return c.nodeClient.GetSyncStatus(ctx, in)
}
func (c *grpcNodeClient) Genesis(ctx context.Context, in *empty.Empty) (*ethpb.Genesis, error) {
return c.getClient().GetGenesis(ctx, in)
return c.nodeClient.GetGenesis(ctx, in)
}
func (c *grpcNodeClient) Version(ctx context.Context, in *empty.Empty) (*ethpb.Version, error) {
return c.getClient().GetVersion(ctx, in)
return c.nodeClient.GetVersion(ctx, in)
}
func (c *grpcNodeClient) Peers(ctx context.Context, in *empty.Empty) (*ethpb.Peers, error) {
return c.getClient().ListPeers(ctx, in)
return c.nodeClient.ListPeers(ctx, in)
}
func (c *grpcNodeClient) IsReady(ctx context.Context) bool {
// GetHealth returns 200 OK only if node is synced and not optimistic.
// otherwise it will throw an error
_, err := c.getClient().GetHealth(ctx, &ethpb.HealthRequest{})
_, err := c.nodeClient.GetHealth(ctx, &ethpb.HealthRequest{})
if err != nil {
log.WithError(err).WithField("beaconNodeUrl", c.conn.GetGrpcConnectionProvider().CurrentHost()).Debug("Node is not ready")
log.WithError(err).Error("Failed to get health of node")
return false
}
return true
}
// NewNodeClient creates a new gRPC node client that supports
// dynamic connection switching via the NodeConnection's GrpcConnectionProvider.
func NewNodeClient(conn validatorHelpers.NodeConnection) iface.NodeClient {
return &grpcNodeClient{
grpcClientManager: newGrpcClientManager(conn, ethpb.NewNodeClient),
}
func NewNodeClient(cc grpc.ClientConnInterface) iface.NodeClient {
g := &grpcNodeClient{nodeClient: ethpb.NewNodeClient(cc)}
return g
}

View File

@@ -1,72 +0,0 @@
package grpc_api
import (
"errors"
"testing"
ethpb "github.com/OffchainLabs/prysm/v7/proto/prysm/v1alpha1"
"github.com/OffchainLabs/prysm/v7/testing/assert"
"github.com/OffchainLabs/prysm/v7/testing/mock"
"github.com/OffchainLabs/prysm/v7/testing/require"
validatorHelpers "github.com/OffchainLabs/prysm/v7/validator/helpers"
"github.com/golang/protobuf/ptypes/empty"
"go.uber.org/mock/gomock"
"google.golang.org/grpc"
)
func TestGrpcNodeClient_IsReady(t *testing.T) {
// The IsReady function now relies on GetHealth which returns:
// - 200 OK (nil error) only if node is synced AND not optimistic
// - 206 Partial Content (error) if syncing or optimistic
// - 503 Unavailable (error) if unavailable
testCases := []struct {
name string
healthErr error
expectedResult bool
}{
{
name: "returns true when health check succeeds (synced and not optimistic)",
healthErr: nil,
expectedResult: true,
},
{
name: "returns false when health check fails (syncing, optimistic, or unavailable)",
healthErr: errors.New("node not ready"),
expectedResult: false,
},
}
for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
ctrl := gomock.NewController(t)
defer ctrl.Finish()
ctx := t.Context()
mockNodeClient := mock.NewMockNodeClient(ctrl)
// Set up health check expectation
mockNodeClient.EXPECT().GetHealth(
gomock.Any(),
gomock.Any(),
).Return(&empty.Empty{}, tc.healthErr)
// Create a mock provider
provider := &mockProvider{hosts: []string{"host1:4000"}}
conn, err := validatorHelpers.NewNodeConnection(validatorHelpers.WithGRPCProvider(provider))
require.NoError(t, err)
// Create client with injected mock
client := &grpcNodeClient{
grpcClientManager: &grpcClientManager[ethpb.NodeClient]{
conn: conn,
client: mockNodeClient,
lastConnCounter: 0,
newClient: func(grpc.ClientConnInterface) ethpb.NodeClient { return mockNodeClient },
},
}
result := client.IsReady(ctx)
assert.Equal(t, tc.expectedResult, result)
})
}
}

Some files were not shown because too many files have changed in this diff Show More