HTTP endpoints cleanup (#13251)

* remove validation package

* structs cleanup

* merge with apimiddleware removal

* more validation and Bls capitalization

* builder test fix

* use strconv for uint->str conversions

* use DecodeHexWithLength

* use exact param names

* rename http package to httputil

* change conversions to fmt.Sprintf

* handle query paramsd and route variables

* spans and receiver name

* split structs, move bytes helper

* missing ok check

* fix reference to indexed failure

* errors fixup

* add godoc to helper

* fix BLS casing and chainhead ref

* review

* fix import in tests

* gzl
This commit is contained in:
Radosław Kapka
2023-12-08 21:37:20 +01:00
committed by GitHub
parent 440841d565
commit 4c47756aed
121 changed files with 6048 additions and 6491 deletions

View File

@@ -53,7 +53,7 @@ go_library(
"//consensus-types/validator:go_default_library",
"//encoding/bytesutil:go_default_library",
"//network/forks:go_default_library",
"//network/http:go_default_library",
"//network/httputil:go_default_library",
"//proto/engine/v1:go_default_library",
"//proto/prysm/v1alpha1:go_default_library",
"//runtime/version:go_default_library",
@@ -126,7 +126,7 @@ go_test(
"//consensus-types/primitives:go_default_library",
"//consensus-types/validator:go_default_library",
"//encoding/bytesutil:go_default_library",
"//network/http:go_default_library",
"//network/httputil:go_default_library",
"//proto/engine/v1:go_default_library",
"//proto/prysm/v1alpha1:go_default_library",
"//testing/assert:go_default_library",

View File

@@ -380,7 +380,7 @@ func (c beaconApiBeaconBlockConverter) ConvertRESTCapellaBlockToProto(block *sha
return nil, errors.Wrap(err, "failed to get withdrawals")
}
blsToExecutionChanges, err := convertBlsToExecutionChangesToProto(block.Body.BlsToExecutionChanges)
blsToExecutionChanges, err := convertBlsToExecutionChangesToProto(block.Body.BLSToExecutionChanges)
if err != nil {
return nil, errors.Wrap(err, "failed to get bls to execution changes")
}

View File

@@ -487,7 +487,7 @@ func TestGetBeaconBlockConverter_CapellaError(t *testing.T) {
expectedErrorMessage: "failed to get bls to execution changes",
generateData: func() *shared.BeaconBlockCapella {
beaconBlock := test_helpers.GenerateJsonCapellaBeaconBlock()
beaconBlock.Body.BlsToExecutionChanges[0] = nil
beaconBlock.Body.BLSToExecutionChanges[0] = nil
return beaconBlock
},
},

View File

@@ -8,7 +8,6 @@ import (
enginev1 "github.com/prysmaticlabs/prysm/v4/proto/engine/v1"
ethpb "github.com/prysmaticlabs/prysm/v4/proto/prysm/v1alpha1"
"github.com/prysmaticlabs/prysm/v4/testing/assert"
"github.com/prysmaticlabs/prysm/v4/testing/require"
)
func TestBeaconBlockJsonHelpers_JsonifyTransactions(t *testing.T) {
@@ -64,9 +63,7 @@ func TestBeaconBlockJsonHelpers_JsonifyBlsToExecutionChanges(t *testing.T) {
},
}
result, err := shared.SignedBlsToExecutionChangesFromConsensus(input)
require.NoError(t, err)
assert.DeepEqual(t, expectedResult, result)
assert.DeepEqual(t, expectedResult, shared.SignedBLSChangesFromConsensus(input))
}
func TestBeaconBlockJsonHelpers_JsonifyEth1Data(t *testing.T) {

View File

@@ -9,12 +9,12 @@ import (
"github.com/ethereum/go-ethereum/common/hexutil"
"github.com/pkg/errors"
"github.com/prysmaticlabs/prysm/v4/beacon-chain/rpc/eth/beacon"
http2 "github.com/prysmaticlabs/prysm/v4/network/http"
"github.com/prysmaticlabs/prysm/v4/network/httputil"
ethpb "github.com/prysmaticlabs/prysm/v4/proto/prysm/v1alpha1"
)
type GenesisProvider interface {
GetGenesis(ctx context.Context) (*beacon.Genesis, *http2.DefaultErrorJson, error)
GetGenesis(ctx context.Context) (*beacon.Genesis, *httputil.DefaultErrorJson, error)
}
type beaconApiGenesisProvider struct {
@@ -61,7 +61,7 @@ func (c beaconApiValidatorClient) waitForChainStart(ctx context.Context) (*ethpb
}
// GetGenesis gets the genesis information from the beacon node via the /eth/v1/beacon/genesis endpoint
func (c beaconApiGenesisProvider) GetGenesis(ctx context.Context) (*beacon.Genesis, *http2.DefaultErrorJson, error) {
func (c beaconApiGenesisProvider) GetGenesis(ctx context.Context) (*beacon.Genesis, *httputil.DefaultErrorJson, error) {
genesisJson := &beacon.GetGenesisResponse{}
errorJson, err := c.jsonRestHandler.Get(ctx, "/eth/v1/beacon/genesis", genesisJson)
if err != nil {

View File

@@ -7,7 +7,7 @@ import (
"github.com/golang/mock/gomock"
"github.com/pkg/errors"
"github.com/prysmaticlabs/prysm/v4/beacon-chain/rpc/eth/beacon"
http2 "github.com/prysmaticlabs/prysm/v4/network/http"
"github.com/prysmaticlabs/prysm/v4/network/httputil"
"github.com/prysmaticlabs/prysm/v4/testing/assert"
"github.com/prysmaticlabs/prysm/v4/testing/require"
"github.com/prysmaticlabs/prysm/v4/validator/client/beacon-api/mock"
@@ -41,7 +41,7 @@ func TestGetGenesis_ValidGenesis(t *testing.T) {
genesisProvider := &beaconApiGenesisProvider{jsonRestHandler: jsonRestHandler}
resp, httpError, err := genesisProvider.GetGenesis(ctx)
assert.NoError(t, err)
assert.Equal(t, (*http2.DefaultErrorJson)(nil), httpError)
assert.Equal(t, (*httputil.DefaultErrorJson)(nil), httpError)
require.NotNil(t, resp)
assert.Equal(t, "1234", resp.GenesisTime)
assert.Equal(t, "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2", resp.GenesisValidatorsRoot)
@@ -69,7 +69,7 @@ func TestGetGenesis_NilData(t *testing.T) {
genesisProvider := &beaconApiGenesisProvider{jsonRestHandler: jsonRestHandler}
_, httpError, err := genesisProvider.GetGenesis(ctx)
assert.Equal(t, (*http2.DefaultErrorJson)(nil), httpError)
assert.Equal(t, (*httputil.DefaultErrorJson)(nil), httpError)
assert.ErrorContains(t, "genesis data is nil", err)
}
@@ -79,7 +79,7 @@ func TestGetGenesis_JsonResponseError(t *testing.T) {
ctx := context.Background()
expectedHttpErrorJson := &http2.DefaultErrorJson{
expectedHttpErrorJson := &httputil.DefaultErrorJson{
Message: "http error message",
Code: 999,
}

View File

@@ -12,7 +12,7 @@ import (
"github.com/golang/mock/gomock"
"github.com/prysmaticlabs/prysm/v4/beacon-chain/rpc/eth/validator"
"github.com/prysmaticlabs/prysm/v4/consensus-types/primitives"
http2 "github.com/prysmaticlabs/prysm/v4/network/http"
"github.com/prysmaticlabs/prysm/v4/network/httputil"
ethpb "github.com/prysmaticlabs/prysm/v4/proto/prysm/v1alpha1"
"github.com/prysmaticlabs/prysm/v4/testing/assert"
"github.com/prysmaticlabs/prysm/v4/testing/require"
@@ -532,7 +532,7 @@ func TestGetBeaconBlock_FallbackToBlindedBlock(t *testing.T) {
fmt.Sprintf("/eth/v3/validator/blocks/%d?graffiti=%s&randao_reveal=%s", slot, hexutil.Encode(graffiti), hexutil.Encode(randaoReveal)),
&validator.ProduceBlockV3Response{},
).Return(
&http2.DefaultErrorJson{Code: http.StatusNotFound},
&httputil.DefaultErrorJson{Code: http.StatusNotFound},
errors.New("foo"),
).Times(1)
jsonRestHandler.EXPECT().Get(
@@ -585,7 +585,7 @@ func TestGetBeaconBlock_FallbackToFullBlock(t *testing.T) {
fmt.Sprintf("/eth/v3/validator/blocks/%d?graffiti=%s&randao_reveal=%s", slot, hexutil.Encode(graffiti), hexutil.Encode(randaoReveal)),
&validator.ProduceBlockV3Response{},
).Return(
&http2.DefaultErrorJson{Code: http.StatusNotFound},
&httputil.DefaultErrorJson{Code: http.StatusNotFound},
errors.New("foo"),
).Times(1)
jsonRestHandler.EXPECT().Get(
@@ -593,7 +593,7 @@ func TestGetBeaconBlock_FallbackToFullBlock(t *testing.T) {
fmt.Sprintf("/eth/v1/validator/blinded_blocks/%d?graffiti=%s&randao_reveal=%s", slot, hexutil.Encode(graffiti), hexutil.Encode(randaoReveal)),
&abstractProduceBlockResponseJson{},
).Return(
&http2.DefaultErrorJson{Code: http.StatusInternalServerError},
&httputil.DefaultErrorJson{Code: http.StatusInternalServerError},
errors.New("foo"),
).Times(1)
jsonRestHandler.EXPECT().Get(

View File

@@ -9,12 +9,12 @@ import (
"github.com/pkg/errors"
"github.com/prysmaticlabs/prysm/v4/api"
http2 "github.com/prysmaticlabs/prysm/v4/network/http"
"github.com/prysmaticlabs/prysm/v4/network/httputil"
)
type JsonRestHandler interface {
Get(ctx context.Context, query string, resp interface{}) (*http2.DefaultErrorJson, error)
Post(ctx context.Context, endpoint string, headers map[string]string, data *bytes.Buffer, resp interface{}) (*http2.DefaultErrorJson, error)
Get(ctx context.Context, query string, resp interface{}) (*httputil.DefaultErrorJson, error)
Post(ctx context.Context, endpoint string, headers map[string]string, data *bytes.Buffer, resp interface{}) (*httputil.DefaultErrorJson, error)
}
type beaconApiJsonRestHandler struct {
@@ -24,7 +24,7 @@ type beaconApiJsonRestHandler struct {
// 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 DefaultErrorJson JSON object and returned as the first return value.
func (c beaconApiJsonRestHandler) Get(ctx context.Context, endpoint string, resp interface{}) (*http2.DefaultErrorJson, error) {
func (c beaconApiJsonRestHandler) Get(ctx context.Context, endpoint string, resp interface{}) (*httputil.DefaultErrorJson, error) {
if resp == nil {
return nil, errors.New("resp is nil")
}
@@ -56,7 +56,7 @@ func (c beaconApiJsonRestHandler) Post(
headers map[string]string,
data *bytes.Buffer,
resp interface{},
) (*http2.DefaultErrorJson, error) {
) (*httputil.DefaultErrorJson, error) {
if data == nil {
return nil, errors.New("data is nil")
}
@@ -85,7 +85,7 @@ func (c beaconApiJsonRestHandler) Post(
return decodeResp(httpResp, resp)
}
func decodeResp(httpResp *http.Response, resp interface{}) (*http2.DefaultErrorJson, error) {
func decodeResp(httpResp *http.Response, resp interface{}) (*httputil.DefaultErrorJson, error) {
body, err := io.ReadAll(httpResp.Body)
if err != nil {
return nil, errors.Wrapf(err, "failed to read response body for %s", httpResp.Request.URL)
@@ -95,12 +95,12 @@ func decodeResp(httpResp *http.Response, resp interface{}) (*http2.DefaultErrorJ
if httpResp.StatusCode == http.StatusOK {
return nil, nil
}
return &http2.DefaultErrorJson{Code: httpResp.StatusCode, Message: string(body)}, nil
return &httputil.DefaultErrorJson{Code: httpResp.StatusCode, Message: string(body)}, nil
}
decoder := json.NewDecoder(bytes.NewBuffer(body))
if httpResp.StatusCode != http.StatusOK {
errorJson := &http2.DefaultErrorJson{}
errorJson := &httputil.DefaultErrorJson{}
if err = decoder.Decode(errorJson); err != nil {
return nil, errors.Wrapf(err, "failed to decode response body into error json for %s", httpResp.Request.URL)
}

View File

@@ -12,7 +12,7 @@ import (
"github.com/prysmaticlabs/prysm/v4/api"
"github.com/prysmaticlabs/prysm/v4/beacon-chain/rpc/eth/beacon"
http2 "github.com/prysmaticlabs/prysm/v4/network/http"
"github.com/prysmaticlabs/prysm/v4/network/httputil"
"github.com/prysmaticlabs/prysm/v4/testing/assert"
"github.com/prysmaticlabs/prysm/v4/testing/require"
)
@@ -146,7 +146,7 @@ func decodeRespTest(t *testing.T) {
})
t.Run("non-200 JSON", func(t *testing.T) {
body := bytes.Buffer{}
b, err := json.Marshal(&http2.DefaultErrorJson{Code: http.StatusInternalServerError, Message: "error"})
b, err := json.Marshal(&httputil.DefaultErrorJson{Code: http.StatusInternalServerError, Message: "error"})
require.NoError(t, err)
body.Write(b)
r := &http.Response{StatusCode: http.StatusInternalServerError, Body: io.NopCloser(&body), Header: map[string][]string{"Content-Type": {api.JsonMediaType}}}

View File

@@ -16,7 +16,7 @@ go_library(
"//beacon-chain/rpc/eth/shared:go_default_library",
"//beacon-chain/rpc/eth/validator:go_default_library",
"//consensus-types/primitives:go_default_library",
"//network/http:go_default_library",
"//network/httputil:go_default_library",
"//proto/prysm/v1alpha1:go_default_library",
"@com_github_golang_mock//gomock:go_default_library",
],

View File

@@ -10,7 +10,7 @@ import (
gomock "github.com/golang/mock/gomock"
beacon "github.com/prysmaticlabs/prysm/v4/beacon-chain/rpc/eth/beacon"
http "github.com/prysmaticlabs/prysm/v4/network/http"
httputil "github.com/prysmaticlabs/prysm/v4/network/httputil"
)
// MockGenesisProvider is a mock of GenesisProvider interface.
@@ -37,11 +37,11 @@ func (m *MockGenesisProvider) EXPECT() *MockGenesisProviderMockRecorder {
}
// GetGenesis mocks base method.
func (m *MockGenesisProvider) GetGenesis(arg0 context.Context) (*beacon.Genesis, *http.DefaultErrorJson, error) {
func (m *MockGenesisProvider) GetGenesis(arg0 context.Context) (*beacon.Genesis, *httputil.DefaultErrorJson, error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "GetGenesis", arg0)
ret0, _ := ret[0].(*beacon.Genesis)
ret1, _ := ret[1].(*http.DefaultErrorJson)
ret1, _ := ret[1].(*httputil.DefaultErrorJson)
ret2, _ := ret[2].(error)
return ret0, ret1, ret2
}

View File

@@ -10,7 +10,7 @@ import (
reflect "reflect"
gomock "github.com/golang/mock/gomock"
http "github.com/prysmaticlabs/prysm/v4/network/http"
http "github.com/prysmaticlabs/prysm/v4/network/httputil"
)
// MockJsonRestHandler is a mock of JsonRestHandler interface.

View File

@@ -322,7 +322,7 @@ func marshallBeaconBlockCapella(block *ethpb.SignedBeaconBlockCapella) ([]byte,
Transactions: jsonifyTransactions(block.Block.Body.ExecutionPayload.Transactions),
Withdrawals: jsonifyWithdrawals(block.Block.Body.ExecutionPayload.Withdrawals),
},
BlsToExecutionChanges: jsonifyBlsToExecutionChanges(block.Block.Body.BlsToExecutionChanges),
BLSToExecutionChanges: jsonifyBlsToExecutionChanges(block.Block.Body.BlsToExecutionChanges),
},
},
}
@@ -368,7 +368,7 @@ func marshallBeaconBlockBlindedCapella(block *ethpb.SignedBlindedBeaconBlockCape
TransactionsRoot: hexutil.Encode(block.Block.Body.ExecutionPayloadHeader.TransactionsRoot),
WithdrawalsRoot: hexutil.Encode(block.Block.Body.ExecutionPayloadHeader.WithdrawalsRoot),
},
BlsToExecutionChanges: jsonifyBlsToExecutionChanges(block.Block.Body.BlsToExecutionChanges),
BLSToExecutionChanges: jsonifyBlsToExecutionChanges(block.Block.Body.BlsToExecutionChanges),
},
},
}

View File

@@ -65,7 +65,7 @@ func TestProposeBeaconBlock_BlindedCapella(t *testing.T) {
TransactionsRoot: hexutil.Encode(blindedCapellaBlock.BlindedCapella.Block.Body.ExecutionPayloadHeader.TransactionsRoot),
WithdrawalsRoot: hexutil.Encode(blindedCapellaBlock.BlindedCapella.Block.Body.ExecutionPayloadHeader.WithdrawalsRoot),
},
BlsToExecutionChanges: jsonifyBlsToExecutionChanges(blindedCapellaBlock.BlindedCapella.Block.Body.BlsToExecutionChanges),
BLSToExecutionChanges: jsonifyBlsToExecutionChanges(blindedCapellaBlock.BlindedCapella.Block.Body.BlsToExecutionChanges),
},
},
}

View File

@@ -64,7 +64,7 @@ func TestProposeBeaconBlock_Capella(t *testing.T) {
Transactions: jsonifyTransactions(capellaBlock.Capella.Block.Body.ExecutionPayload.Transactions),
Withdrawals: jsonifyWithdrawals(capellaBlock.Capella.Block.Body.ExecutionPayload.Withdrawals),
},
BlsToExecutionChanges: jsonifyBlsToExecutionChanges(capellaBlock.Capella.Block.Body.BlsToExecutionChanges),
BLSToExecutionChanges: jsonifyBlsToExecutionChanges(capellaBlock.Capella.Block.Body.BlsToExecutionChanges),
},
},
}

View File

@@ -7,7 +7,7 @@ import (
"testing"
"github.com/golang/mock/gomock"
http2 "github.com/prysmaticlabs/prysm/v4/network/http"
"github.com/prysmaticlabs/prysm/v4/network/httputil"
ethpb "github.com/prysmaticlabs/prysm/v4/proto/prysm/v1alpha1"
"github.com/prysmaticlabs/prysm/v4/testing/assert"
"github.com/prysmaticlabs/prysm/v4/validator/client/beacon-api/mock"
@@ -17,12 +17,12 @@ func TestProposeBeaconBlock_Error(t *testing.T) {
testSuites := []struct {
name string
expectedErrorMessage string
expectedHttpError *http2.DefaultErrorJson
expectedHttpError *httputil.DefaultErrorJson
}{
{
name: "error 202",
expectedErrorMessage: "block was successfully broadcasted but failed validation",
expectedHttpError: &http2.DefaultErrorJson{
expectedHttpError: &httputil.DefaultErrorJson{
Code: http.StatusAccepted,
Message: "202 error",
},

View File

@@ -4,7 +4,6 @@ import (
"bytes"
"context"
"encoding/json"
"fmt"
"github.com/pkg/errors"
"github.com/prysmaticlabs/prysm/v4/beacon-chain/rpc/eth/shared"
@@ -17,11 +16,7 @@ func (c *beaconApiValidatorClient) submitValidatorRegistrations(ctx context.Cont
jsonRegistration := make([]*shared.SignedValidatorRegistration, len(registrations))
for index, registration := range registrations {
outMessage, err := shared.SignedValidatorRegistrationFromConsensus(registration)
if err != nil {
return errors.Wrap(err, fmt.Sprintf("failed to encode to SignedValidatorRegistration at index %d", index))
}
jsonRegistration[index] = outMessage
jsonRegistration[index] = shared.SignedValidatorRegistrationFromConsensus(registration)
}
marshalledJsonRegistration, err := json.Marshal(jsonRegistration)

View File

@@ -764,7 +764,7 @@ func GenerateJsonCapellaBeaconBlock() *shared.BeaconBlockCapella {
},
},
},
BlsToExecutionChanges: []*shared.SignedBLSToExecutionChange{
BLSToExecutionChanges: []*shared.SignedBLSToExecutionChange{
{
Message: &shared.BLSToExecutionChange{
ValidatorIndex: "135",
@@ -1013,7 +1013,7 @@ func GenerateJsonBlindedCapellaBeaconBlock() *shared.BlindedBeaconBlockCapella {
TransactionsRoot: FillEncodedByteSlice(32, 125),
WithdrawalsRoot: FillEncodedByteSlice(32, 126),
},
BlsToExecutionChanges: []*shared.SignedBLSToExecutionChange{
BLSToExecutionChanges: []*shared.SignedBLSToExecutionChange{
{
Message: &shared.BLSToExecutionChange{
ValidatorIndex: "135",

View File

@@ -777,7 +777,7 @@ func GenerateJsonDenebBeaconBlockContents() *shared.BeaconBlockContentsDeneb {
BlobGasUsed: "135",
ExcessBlobGas: "136",
},
BlsToExecutionChanges: []*shared.SignedBLSToExecutionChange{
BLSToExecutionChanges: []*shared.SignedBLSToExecutionChange{
{
Message: &shared.BLSToExecutionChange{
ValidatorIndex: "137",
@@ -1032,7 +1032,7 @@ func GenerateJsonBlindedDenebBeaconBlock() *shared.BlindedBeaconBlockDeneb {
BlobGasUsed: "127",
ExcessBlobGas: "128",
},
BlsToExecutionChanges: []*shared.SignedBLSToExecutionChange{
BLSToExecutionChanges: []*shared.SignedBLSToExecutionChange{
{
Message: &shared.BLSToExecutionChange{
ValidatorIndex: "129",

View File

@@ -9,7 +9,7 @@ import (
"github.com/ethereum/go-ethereum/common/hexutil"
"github.com/golang/mock/gomock"
"github.com/prysmaticlabs/prysm/v4/beacon-chain/rpc/eth/beacon"
http2 "github.com/prysmaticlabs/prysm/v4/network/http"
"github.com/prysmaticlabs/prysm/v4/network/httputil"
"github.com/prysmaticlabs/prysm/v4/testing/assert"
"github.com/prysmaticlabs/prysm/v4/testing/require"
"github.com/prysmaticlabs/prysm/v4/validator/client/beacon-api/mock"
@@ -151,7 +151,7 @@ func TestWaitForChainStart_JsonResponseError404(t *testing.T) {
"/eth/v1/beacon/genesis",
&genesisResponseJson,
).Return(
&http2.DefaultErrorJson{
&httputil.DefaultErrorJson{
Code: http.StatusNotFound,
Message: "404 error",
},

View File

@@ -25,6 +25,7 @@ go_library(
"//api:go_default_library",
"//api/grpc:go_default_library",
"//api/pagination:go_default_library",
"//api/server:go_default_library",
"//async/event:go_default_library",
"//beacon-chain/rpc/eth/shared:go_default_library",
"//cmd:go_default_library",
@@ -41,7 +42,7 @@ go_library(
"//io/logs:go_default_library",
"//io/prompt:go_default_library",
"//monitoring/tracing:go_default_library",
"//network/http:go_default_library",
"//network/httputil:go_default_library",
"//proto/prysm/v1alpha1:go_default_library",
"//runtime/version:go_default_library",
"//validator/accounts:go_default_library",
@@ -105,7 +106,6 @@ go_test(
deps = [
"//api:go_default_library",
"//async/event:go_default_library",
"//beacon-chain/rpc/eth/shared:go_default_library",
"//cmd/validator/flags:go_default_library",
"//config/features:go_default_library",
"//config/fieldparams:go_default_library",

View File

@@ -13,7 +13,7 @@ import (
"github.com/prysmaticlabs/prysm/v4/config/features"
"github.com/prysmaticlabs/prysm/v4/io/file"
"github.com/prysmaticlabs/prysm/v4/io/prompt"
httputil "github.com/prysmaticlabs/prysm/v4/network/http"
"github.com/prysmaticlabs/prysm/v4/network/httputil"
"github.com/prysmaticlabs/prysm/v4/validator/accounts"
"github.com/prysmaticlabs/prysm/v4/validator/accounts/wallet"
"github.com/prysmaticlabs/prysm/v4/validator/keymanager"

View File

@@ -18,7 +18,7 @@ import (
fieldparams "github.com/prysmaticlabs/prysm/v4/config/fieldparams"
"github.com/prysmaticlabs/prysm/v4/crypto/bls"
"github.com/prysmaticlabs/prysm/v4/encoding/bytesutil"
httputil "github.com/prysmaticlabs/prysm/v4/network/http"
"github.com/prysmaticlabs/prysm/v4/network/httputil"
"github.com/prysmaticlabs/prysm/v4/validator/accounts"
"github.com/prysmaticlabs/prysm/v4/validator/accounts/petnames"
"github.com/prysmaticlabs/prysm/v4/validator/keymanager"

View File

@@ -6,7 +6,7 @@ import (
"github.com/pkg/errors"
"github.com/prysmaticlabs/prysm/v4/io/file"
httputil "github.com/prysmaticlabs/prysm/v4/network/http"
"github.com/prysmaticlabs/prysm/v4/network/httputil"
"github.com/prysmaticlabs/prysm/v4/validator/accounts/wallet"
"go.opencensus.io/trace"
)

View File

@@ -13,7 +13,7 @@ import (
"github.com/prysmaticlabs/prysm/v4/beacon-chain/rpc/eth/shared"
fieldparams "github.com/prysmaticlabs/prysm/v4/config/fieldparams"
"github.com/prysmaticlabs/prysm/v4/encoding/bytesutil"
httputil "github.com/prysmaticlabs/prysm/v4/network/http"
"github.com/prysmaticlabs/prysm/v4/network/httputil"
ethpb "github.com/prysmaticlabs/prysm/v4/proto/prysm/v1alpha1"
"go.opencensus.io/trace"
"google.golang.org/protobuf/types/known/emptypb"
@@ -53,7 +53,7 @@ func (s *Server) GetBeaconStatus(w http.ResponseWriter, r *http.Request) {
Syncing: syncStatus.Syncing,
GenesisTime: fmt.Sprintf("%d", genesisTime),
DepositContractAddress: hexutil.Encode(address),
ChainHead: shared.ChainHeadResponseFromConsensus(chainHead),
ChainHead: ChainHeadResponseFromConsensus(chainHead),
})
}
@@ -90,7 +90,7 @@ func (s *Server) GetValidatorPerformance(w http.ResponseWriter, r *http.Request)
httputil.HandleError(w, errors.Wrap(err, "GetValidatorPerformance call failed").Error(), http.StatusInternalServerError)
return
}
httputil.WriteJson(w, shared.ValidatorPerformanceResponseFromConsensus(validatorPerformance))
httputil.WriteJson(w, ValidatorPerformanceResponseFromConsensus(validatorPerformance))
}
// GetValidatorBalances is a wrapper around the /eth/v1alpha1 endpoint of the same name.
@@ -138,7 +138,7 @@ func (s *Server) GetValidatorBalances(w http.ResponseWriter, r *http.Request) {
httputil.HandleError(w, errors.Wrap(err, "ListValidatorBalances call failed").Error(), http.StatusInternalServerError)
return
}
response, err := shared.ValidatorBalancesResponseFromConsensus(listValidatorBalances)
response, err := ValidatorBalancesResponseFromConsensus(listValidatorBalances)
if err != nil {
httputil.HandleError(w, errors.Wrap(err, "Failed to convert to json").Error(), http.StatusInternalServerError)
return
@@ -187,7 +187,7 @@ func (s *Server) GetValidators(w http.ResponseWriter, r *http.Request) {
httputil.HandleError(w, errors.Wrap(err, "ListValidators call failed").Error(), http.StatusInternalServerError)
return
}
response, err := shared.ValidatorsResponseFromConsensus(validators)
response, err := ValidatorsResponseFromConsensus(validators)
if err != nil {
httputil.HandleError(w, errors.Wrap(err, "Failed to convert to json").Error(), http.StatusInternalServerError)
return

View File

@@ -11,7 +11,6 @@ import (
"github.com/golang/mock/gomock"
"github.com/pkg/errors"
"github.com/prysmaticlabs/prysm/v4/beacon-chain/rpc/eth/shared"
ethpb "github.com/prysmaticlabs/prysm/v4/proto/prysm/v1alpha1"
"github.com/prysmaticlabs/prysm/v4/testing/assert"
"github.com/prysmaticlabs/prysm/v4/testing/require"
@@ -85,7 +84,7 @@ func TestGetBeaconStatus_OK(t *testing.T) {
Syncing: true,
GenesisTime: fmt.Sprintf("%d", time.Unix(0, 0).Unix()),
DepositContractAddress: "0x68656c6c6f",
ChainHead: &shared.ChainHead{
ChainHead: &ChainHead{
HeadSlot: "0",
HeadEpoch: "1",
HeadBlockRoot: "0x",

View File

@@ -5,7 +5,7 @@ import (
"fmt"
"net/http"
http2 "github.com/prysmaticlabs/prysm/v4/network/http"
"github.com/prysmaticlabs/prysm/v4/network/httputil"
pb "github.com/prysmaticlabs/prysm/v4/proto/prysm/v1alpha1"
"github.com/prysmaticlabs/prysm/v4/runtime/version"
"go.opencensus.io/trace"
@@ -19,11 +19,11 @@ func (s *Server) GetVersion(w http.ResponseWriter, r *http.Request) {
beacon, err := s.beaconNodeClient.GetVersion(ctx, &emptypb.Empty{})
if err != nil {
http2.HandleError(w, err.Error(), http.StatusInternalServerError)
httputil.HandleError(w, err.Error(), http.StatusInternalServerError)
return
}
http2.WriteJson(w, struct {
httputil.WriteJson(w, struct {
Beacon string `json:"beacon"`
Validator string `json:"validator"`
}{
@@ -46,13 +46,13 @@ func (s *Server) StreamBeaconLogs(w http.ResponseWriter, r *http.Request) {
// Flush helper function to ensure data is sent to client
flusher, ok := w.(http.Flusher)
if !ok {
http2.HandleError(w, "Streaming unsupported!", http.StatusInternalServerError)
httputil.HandleError(w, "Streaming unsupported!", http.StatusInternalServerError)
return
}
// TODO: StreamBeaconLogs grpc will need to be replaced in the future
client, err := s.beaconNodeHealthClient.StreamBeaconLogs(ctx, &emptypb.Empty{})
if err != nil {
http2.HandleError(w, err.Error(), http.StatusInternalServerError)
httputil.HandleError(w, err.Error(), http.StatusInternalServerError)
return
}
@@ -67,12 +67,12 @@ func (s *Server) StreamBeaconLogs(w http.ResponseWriter, r *http.Request) {
default:
logResp, err := client.Recv()
if err != nil {
http2.HandleError(w, "could not receive beacon logs from stream: "+err.Error(), http.StatusInternalServerError)
httputil.HandleError(w, "could not receive beacon logs from stream: "+err.Error(), http.StatusInternalServerError)
return
}
jsonResp, err := json.Marshal(logResp)
if err != nil {
http2.HandleError(w, "could not encode log response into JSON: "+err.Error(), http.StatusInternalServerError)
httputil.HandleError(w, "could not encode log response into JSON: "+err.Error(), http.StatusInternalServerError)
return
}
@@ -80,7 +80,7 @@ func (s *Server) StreamBeaconLogs(w http.ResponseWriter, r *http.Request) {
// Assuming resp has a String() method for simplicity
_, err = fmt.Fprintf(w, "%s\n", jsonResp)
if err != nil {
http2.HandleError(w, err.Error(), http.StatusInternalServerError)
httputil.HandleError(w, err.Error(), http.StatusInternalServerError)
return
}
// Flush the data to the client immediately
@@ -97,7 +97,7 @@ func (s *Server) StreamValidatorLogs(w http.ResponseWriter, r *http.Request) {
// Ensure that the writer supports flushing.
flusher, ok := w.(http.Flusher)
if !ok {
http2.HandleError(w, "Streaming unsupported!", http.StatusInternalServerError)
httputil.HandleError(w, "Streaming unsupported!", http.StatusInternalServerError)
return
}
@@ -122,12 +122,12 @@ func (s *Server) StreamValidatorLogs(w http.ResponseWriter, r *http.Request) {
}
jsonLogs, err := json.Marshal(ls)
if err != nil {
http2.HandleError(w, "Failed to marshal logs: "+err.Error(), http.StatusInternalServerError)
httputil.HandleError(w, "Failed to marshal logs: "+err.Error(), http.StatusInternalServerError)
return
}
_, err = fmt.Fprintf(w, "%s\n", jsonLogs)
if err != nil {
http2.HandleError(w, "Error sending data: "+err.Error(), http.StatusInternalServerError)
httputil.HandleError(w, "Error sending data: "+err.Error(), http.StatusInternalServerError)
return
}
flusher.Flush()
@@ -141,12 +141,12 @@ func (s *Server) StreamValidatorLogs(w http.ResponseWriter, r *http.Request) {
}
jsonLogs, err = json.Marshal(ls)
if err != nil {
http2.HandleError(w, "Failed to marshal logs: "+err.Error(), http.StatusInternalServerError)
httputil.HandleError(w, "Failed to marshal logs: "+err.Error(), http.StatusInternalServerError)
return
}
_, err = fmt.Fprintf(w, "%s\n", jsonLogs)
if err != nil {
http2.HandleError(w, "Error sending data: "+err.Error(), http.StatusInternalServerError)
httputil.HandleError(w, "Error sending data: "+err.Error(), http.StatusInternalServerError)
return
}
@@ -154,7 +154,7 @@ func (s *Server) StreamValidatorLogs(w http.ResponseWriter, r *http.Request) {
case <-s.ctx.Done():
return
case err := <-sub.Err():
http2.HandleError(w, "Subscriber error: "+err.Error(), http.StatusInternalServerError)
httputil.HandleError(w, "Subscriber error: "+err.Error(), http.StatusInternalServerError)
return
case <-ctx.Done():
return

View File

@@ -19,7 +19,7 @@ import (
"github.com/prysmaticlabs/prysm/v4/consensus-types/primitives"
"github.com/prysmaticlabs/prysm/v4/consensus-types/validator"
"github.com/prysmaticlabs/prysm/v4/encoding/bytesutil"
httputil "github.com/prysmaticlabs/prysm/v4/network/http"
"github.com/prysmaticlabs/prysm/v4/network/httputil"
"github.com/prysmaticlabs/prysm/v4/validator/client"
"github.com/prysmaticlabs/prysm/v4/validator/keymanager"
"github.com/prysmaticlabs/prysm/v4/validator/keymanager/derived"
@@ -216,7 +216,7 @@ func (s *Server) DeleteKeystores(w http.ResponseWriter, r *http.Request) {
}
bytePubKeys := make([][]byte, len(req.Pubkeys))
for i, pubkey := range req.Pubkeys {
key, ok := shared.ValidateHex(w, "Pubkey", pubkey, fieldparams.BLSPubkeyLength)
key, ok := shared.ValidateHex(w, fmt.Sprintf("pubkeys[%d]", i), pubkey, fieldparams.BLSPubkeyLength)
if !ok {
return
}
@@ -336,27 +336,17 @@ func (s *Server) SetVoluntaryExit(w http.ResponseWriter, r *http.Request) {
httputil.HandleError(w, err.Error(), http.StatusInternalServerError)
return
}
rawPubkey := mux.Vars(r)["pubkey"]
if rawPubkey == "" {
httputil.HandleError(w, "pubkey is required in URL params", http.StatusBadRequest)
return
}
pubkey, valid := shared.ValidateHex(w, "pubkey", rawPubkey, fieldparams.BLSPubkeyLength)
if !valid {
return
}
var epoch primitives.Epoch
ok, _, e := shared.UintFromQuery(w, r, "epoch")
_, pubkey, ok := shared.HexFromRoute(w, r, "pubkey", fieldparams.BLSPubkeyLength)
if !ok {
httputil.HandleError(w, "Invalid epoch", http.StatusBadRequest)
return
}
epoch = primitives.Epoch(e)
rawEpoch, e, ok := shared.UintFromQuery(w, r, "epoch", false)
if !ok {
return
}
epoch := primitives.Epoch(e)
if epoch == 0 {
if rawEpoch == "" {
genesisResponse, err := s.beaconNodeClient.GetGenesis(ctx, &emptypb.Empty{})
if err != nil {
httputil.HandleError(w, errors.Wrap(err, "Failed to get genesis time").Error(), http.StatusInternalServerError)
@@ -556,15 +546,8 @@ func (s *Server) ListFeeRecipientByPubkey(w http.ResponseWriter, r *http.Request
httputil.HandleError(w, "Validator service not ready.", http.StatusServiceUnavailable)
return
}
rawPubkey := mux.Vars(r)["pubkey"]
if rawPubkey == "" {
httputil.HandleError(w, "pubkey is required in URL params", http.StatusBadRequest)
return
}
pubkey, valid := shared.ValidateHex(w, "pubkey", rawPubkey, fieldparams.BLSPubkeyLength)
if !valid {
rawPubkey, pubkey, ok := shared.HexFromRoute(w, r, "pubkey", fieldparams.BLSPubkeyLength)
if !ok {
return
}
finalResp := &GetFeeRecipientByPubkeyResponse{
@@ -605,15 +588,8 @@ func (s *Server) SetFeeRecipientByPubkey(w http.ResponseWriter, r *http.Request)
httputil.HandleError(w, "Validator service not ready.", http.StatusServiceUnavailable)
return
}
rawPubkey := mux.Vars(r)["pubkey"]
if rawPubkey == "" {
httputil.HandleError(w, "pubkey is required in URL params", http.StatusBadRequest)
return
}
pubkey, valid := shared.ValidateHex(w, "pubkey", rawPubkey, fieldparams.BLSPubkeyLength)
if !valid {
_, pubkey, ok := shared.HexFromRoute(w, r, "pubkey", fieldparams.BLSPubkeyLength)
if !ok {
return
}
@@ -627,8 +603,7 @@ func (s *Server) SetFeeRecipientByPubkey(w http.ResponseWriter, r *http.Request)
httputil.HandleError(w, "Could not decode request body: "+err.Error(), http.StatusBadRequest)
return
}
ethAddress, valid := shared.ValidateHex(w, "Ethereum Address", req.Ethaddress, fieldparams.FeeRecipientLength)
ethAddress, valid := shared.ValidateHex(w, "ethaddress", req.Ethaddress, fieldparams.FeeRecipientLength)
if !valid {
return
}
@@ -697,18 +672,12 @@ func (s *Server) DeleteFeeRecipientByPubkey(w http.ResponseWriter, r *http.Reque
httputil.HandleError(w, "Validator service not ready.", http.StatusServiceUnavailable)
return
}
rawPubkey := mux.Vars(r)["pubkey"]
if rawPubkey == "" {
httputil.HandleError(w, "pubkey is required in URL params", http.StatusBadRequest)
_, pubkey, ok := shared.HexFromRoute(w, r, "pubkey", fieldparams.BLSPubkeyLength)
if !ok {
return
}
pubkey, valid := shared.ValidateHex(w, "pubkey", rawPubkey, fieldparams.BLSPubkeyLength)
if !valid {
return
}
settings := s.validatorService.ProposerSettings()
if settings != nil && settings.ProposeConfig != nil {
proposerOption, found := settings.ProposeConfig[bytesutil.ToBytes48(pubkey)]
if found {
@@ -776,14 +745,8 @@ func (s *Server) SetGasLimit(w http.ResponseWriter, r *http.Request) {
httputil.HandleError(w, "Validator service not ready", http.StatusServiceUnavailable)
return
}
rawPubkey := mux.Vars(r)["pubkey"]
if rawPubkey == "" {
httputil.HandleError(w, "pubkey is required in URL params", http.StatusBadRequest)
return
}
pubkey, valid := shared.ValidateHex(w, "pubkey", rawPubkey, fieldparams.BLSPubkeyLength)
if !valid {
_, pubkey, ok := shared.HexFromRoute(w, r, "pubkey", fieldparams.BLSPubkeyLength)
if !ok {
return
}
@@ -798,7 +761,7 @@ func (s *Server) SetGasLimit(w http.ResponseWriter, r *http.Request) {
return
}
gasLimit, valid := shared.ValidateUint(w, "Gas Limit", req.GasLimit)
gasLimit, valid := shared.ValidateUint(w, "gas_limit", req.GasLimit)
if !valid {
return
}
@@ -852,14 +815,8 @@ func (s *Server) DeleteGasLimit(w http.ResponseWriter, r *http.Request) {
httputil.HandleError(w, "Validator service not ready", http.StatusServiceUnavailable)
return
}
rawPubkey := mux.Vars(r)["pubkey"]
if rawPubkey == "" {
httputil.HandleError(w, "pubkey is required in URL params", http.StatusBadRequest)
return
}
pubkey, valid := shared.ValidateHex(w, "pubkey", rawPubkey, fieldparams.BLSPubkeyLength)
if !valid {
rawPubkey, pubkey, ok := shared.HexFromRoute(w, r, "pubkey", fieldparams.BLSPubkeyLength)
if !ok {
return
}
@@ -887,5 +844,5 @@ func (s *Server) DeleteGasLimit(w http.ResponseWriter, r *http.Request) {
}
// Otherwise, either no proposerOption is found for the pubkey or proposerOption.BuilderConfig is not enabled at all,
// we respond "not found".
httputil.HandleError(w, fmt.Sprintf("No gas limit found for pubkey: %q", rawPubkey), http.StatusNotFound)
httputil.HandleError(w, fmt.Sprintf("No gas limit found for pubkey %q", rawPubkey), http.StatusNotFound)
}

View File

@@ -728,7 +728,7 @@ func TestServer_SetVoluntaryExit(t *testing.T) {
tests := []struct {
name string
epoch int
epoch string
pubkey string
w want
wError *wantError
@@ -736,7 +736,7 @@ func TestServer_SetVoluntaryExit(t *testing.T) {
}{
{
name: "Ok: with epoch",
epoch: 30000000,
epoch: "30000000",
pubkey: hexutil.Encode(pubKeys[0][:]),
w: want{
epoch: 30000000,
@@ -755,15 +755,15 @@ func TestServer_SetVoluntaryExit(t *testing.T) {
},
{
name: "Error: Missing Public Key in URL Params",
epoch: 30000000,
epoch: "30000000",
wError: &wantError{
expectedStatusCode: http.StatusBadRequest,
expectedErrorMsg: "pubkey is required in URL params",
expectedErrorMsg: "pubkey is required",
},
},
{
name: "Error: Invalid Public Key Length",
epoch: 30000000,
epoch: "30000000",
pubkey: "0x1asd1231",
wError: &wantError{
expectedStatusCode: http.StatusBadRequest,
@@ -772,7 +772,7 @@ func TestServer_SetVoluntaryExit(t *testing.T) {
},
{
name: "Error: No Wallet Found",
epoch: 30000000,
epoch: "30000000",
pubkey: hexutil.Encode(pubKeys[0][:]),
wError: &wantError{
expectedStatusCode: http.StatusServiceUnavailable,
@@ -790,7 +790,7 @@ func TestServer_SetVoluntaryExit(t *testing.T) {
if tt.mockSetup != nil {
require.NoError(t, tt.mockSetup(s))
}
req := httptest.NewRequest("POST", fmt.Sprintf("/eth/v1/validator/{pubkey}/voluntary_exit?epoch=%d", tt.epoch), nil)
req := httptest.NewRequest("POST", fmt.Sprintf("/eth/v1/validator/{pubkey}/voluntary_exit?epoch=%s", tt.epoch), nil)
req = mux.SetURLVars(req, map[string]string{"pubkey": tt.pubkey})
w := httptest.NewRecorder()
w.Body = &bytes.Buffer{}
@@ -810,7 +810,7 @@ func TestServer_SetVoluntaryExit(t *testing.T) {
require.NoError(t, err)
tt.w.epoch, err = client.CurrentEpoch(genesisResponse.GenesisTime)
require.NoError(t, err)
req2 := httptest.NewRequest("POST", fmt.Sprintf("/eth/v1/validator/{pubkey}/voluntary_exit?epoch=%d", tt.epoch), nil)
req2 := httptest.NewRequest("POST", fmt.Sprintf("/eth/v1/validator/{pubkey}/voluntary_exit?epoch=%s", tt.epoch), nil)
req2 = mux.SetURLVars(req2, map[string]string{"pubkey": hexutil.Encode(pubKeys[0][:])})
w2 := httptest.NewRecorder()
w2.Body = &bytes.Buffer{}
@@ -1764,7 +1764,7 @@ func TestServer_SetFeeRecipientByPubkey_InvalidFeeRecipient(t *testing.T) {
s.SetFeeRecipientByPubkey(w, req)
assert.NotEqual(t, http.StatusAccepted, w.Code)
require.StringContains(t, "Invalid Ethereum Address", w.Body.String())
require.StringContains(t, "Invalid ethaddress", w.Body.String())
}
func TestServer_DeleteFeeRecipientByPubkey(t *testing.T) {

View File

@@ -7,7 +7,7 @@ import (
"net/http"
"github.com/pkg/errors"
httputil "github.com/prysmaticlabs/prysm/v4/network/http"
"github.com/prysmaticlabs/prysm/v4/network/httputil"
slashing "github.com/prysmaticlabs/prysm/v4/validator/slashing-protection-history"
"go.opencensus.io/trace"
)

View File

@@ -1,7 +1,16 @@
package rpc
import (
"fmt"
"strconv"
"github.com/ethereum/go-ethereum/common/hexutil"
"github.com/prysmaticlabs/prysm/v4/api/server"
"github.com/prysmaticlabs/prysm/v4/beacon-chain/rpc/eth/shared"
fieldparams "github.com/prysmaticlabs/prysm/v4/config/fieldparams"
"github.com/prysmaticlabs/prysm/v4/consensus-types/primitives"
"github.com/prysmaticlabs/prysm/v4/encoding/bytesutil"
eth "github.com/prysmaticlabs/prysm/v4/proto/prysm/v1alpha1"
"github.com/prysmaticlabs/prysm/v4/validator/keymanager"
)
@@ -91,12 +100,12 @@ type SetFeeRecipientByPubkeyRequest struct {
}
type BeaconStatusResponse struct {
BeaconNodeEndpoint string `json:"beacon_node_endpoint"`
Connected bool `json:"connected"`
Syncing bool `json:"syncing"`
GenesisTime string `json:"genesis_time"`
DepositContractAddress string `json:"deposit_contract_address"`
ChainHead *shared.ChainHead `json:"chain_head"`
BeaconNodeEndpoint string `json:"beacon_node_endpoint"`
Connected bool `json:"connected"`
Syncing bool `json:"syncing"`
GenesisTime string `json:"genesis_time"`
DepositContractAddress string `json:"deposit_contract_address"`
ChainHead *ChainHead `json:"chain_head"`
}
// KeymanagerKind is a type of key manager for the wallet
@@ -184,3 +193,254 @@ type InitializeAuthResponse struct {
HasSignedUp bool `json:"has_signed_up"`
HasWallet bool `json:"has_wallet"`
}
type ValidatorPerformanceResponse struct {
CurrentEffectiveBalances []uint64 `json:"current_effective_balances"`
InclusionSlots []uint64 `json:"inclusion_slots"`
InclusionDistances []uint64 `json:"inclusion_distances"`
CorrectlyVotedSource []bool `json:"correctly_voted_source"`
CorrectlyVotedTarget []bool `json:"correctly_voted_target"`
CorrectlyVotedHead []bool `json:"correctly_voted_head"`
BalancesBeforeEpochTransition []uint64 `json:"balances_before_epoch_transition"`
BalancesAfterEpochTransition []uint64 `json:"balances_after_epoch_transition"`
MissingValidators []string `json:"missing_validators"`
AverageActiveValidatorBalance float32 `json:"average_active_validator_balance"`
PublicKeys []string `json:"public_keys"`
InactivityScores []uint64 `json:"inactivity_scores"`
}
func ValidatorPerformanceResponseFromConsensus(e *eth.ValidatorPerformanceResponse) *ValidatorPerformanceResponse {
inclusionSlots := make([]uint64, len(e.InclusionSlots))
for i, index := range e.InclusionSlots {
inclusionSlots[i] = uint64(index)
}
inclusionDistances := make([]uint64, len(e.InclusionDistances))
for i, index := range e.InclusionDistances {
inclusionDistances[i] = uint64(index)
}
missingValidators := make([]string, len(e.MissingValidators))
for i, key := range e.MissingValidators {
missingValidators[i] = hexutil.Encode(key)
}
publicKeys := make([]string, len(e.PublicKeys))
for i, key := range e.PublicKeys {
publicKeys[i] = hexutil.Encode(key)
}
if len(e.CurrentEffectiveBalances) == 0 {
e.CurrentEffectiveBalances = make([]uint64, 0)
}
if len(e.BalancesBeforeEpochTransition) == 0 {
e.BalancesBeforeEpochTransition = make([]uint64, 0)
}
if len(e.BalancesAfterEpochTransition) == 0 {
e.BalancesAfterEpochTransition = make([]uint64, 0)
}
if len(e.CorrectlyVotedSource) == 0 {
e.CorrectlyVotedSource = make([]bool, 0)
}
if len(e.CorrectlyVotedTarget) == 0 {
e.CorrectlyVotedTarget = make([]bool, 0)
}
if len(e.CorrectlyVotedHead) == 0 {
e.CorrectlyVotedHead = make([]bool, 0)
}
if len(e.InactivityScores) == 0 {
e.InactivityScores = make([]uint64, 0)
}
return &ValidatorPerformanceResponse{
CurrentEffectiveBalances: e.CurrentEffectiveBalances,
InclusionSlots: inclusionSlots,
InclusionDistances: inclusionDistances,
CorrectlyVotedSource: e.CorrectlyVotedSource,
CorrectlyVotedTarget: e.CorrectlyVotedTarget,
CorrectlyVotedHead: e.CorrectlyVotedHead,
BalancesBeforeEpochTransition: e.BalancesBeforeEpochTransition,
BalancesAfterEpochTransition: e.BalancesAfterEpochTransition,
MissingValidators: missingValidators,
AverageActiveValidatorBalance: e.AverageActiveValidatorBalance,
PublicKeys: publicKeys,
InactivityScores: e.InactivityScores,
}
}
type ValidatorBalancesResponse struct {
Epoch uint64 `json:"epoch"`
Balances []*ValidatorBalance `json:"balances"`
NextPageToken string `json:"next_page_token"`
TotalSize int32 `json:"total_size,omitempty"`
}
type ValidatorBalance struct {
PublicKey string `json:"public_key"`
Index uint64 `json:"index"`
Balance uint64 `json:"balance"`
Status string `json:"status"`
}
func ValidatorBalancesResponseFromConsensus(e *eth.ValidatorBalances) (*ValidatorBalancesResponse, error) {
balances := make([]*ValidatorBalance, len(e.Balances))
for i, balance := range e.Balances {
balances[i] = &ValidatorBalance{
PublicKey: hexutil.Encode(balance.PublicKey),
Index: uint64(balance.Index),
Balance: balance.Balance,
Status: balance.Status,
}
}
return &ValidatorBalancesResponse{
Epoch: uint64(e.Epoch),
Balances: balances,
NextPageToken: e.NextPageToken,
TotalSize: e.TotalSize,
}, nil
}
type ValidatorsResponse struct {
Epoch uint64 `json:"epoch"`
ValidatorList []*ValidatorContainer `json:"validator_list"`
NextPageToken string `json:"next_page_token"`
TotalSize int32 `json:"total_size"`
}
type ValidatorContainer struct {
Index uint64 `json:"index"`
Validator *Validator `json:"validator"`
}
type Validator struct {
PublicKey string `json:"public_key,omitempty"`
WithdrawalCredentials string `json:"withdrawal_credentials"`
EffectiveBalance uint64 `json:"effective_balance"`
Slashed bool `json:"slashed"`
ActivationEligibilityEpoch uint64 `json:"activation_eligibility_epoch"`
ActivationEpoch uint64 `json:"activation_epoch"`
ExitEpoch uint64 `json:"exit_epoch"`
WithdrawableEpoch uint64 `json:"withdrawable_epoch"`
}
func ValidatorsResponseFromConsensus(e *eth.Validators) (*ValidatorsResponse, error) {
validatorList := make([]*ValidatorContainer, len(e.ValidatorList))
for i, validatorContainer := range e.ValidatorList {
val := validatorContainer.Validator
validatorList[i] = &ValidatorContainer{
Index: uint64(validatorContainer.Index),
Validator: &Validator{
PublicKey: hexutil.Encode(val.PublicKey),
WithdrawalCredentials: hexutil.Encode(val.WithdrawalCredentials),
EffectiveBalance: val.EffectiveBalance,
Slashed: val.Slashed,
ActivationEligibilityEpoch: uint64(val.ActivationEligibilityEpoch),
ActivationEpoch: uint64(val.ActivationEpoch),
ExitEpoch: uint64(val.ExitEpoch),
WithdrawableEpoch: uint64(val.WithdrawableEpoch),
},
}
}
return &ValidatorsResponse{
Epoch: uint64(e.Epoch),
ValidatorList: validatorList,
NextPageToken: e.NextPageToken,
TotalSize: e.TotalSize,
}, nil
}
// ChainHead is the response for api endpoint /beacon/chainhead
type ChainHead struct {
HeadSlot string `json:"head_slot"`
HeadEpoch string `json:"head_epoch"`
HeadBlockRoot string `json:"head_block_root"`
FinalizedSlot string `json:"finalized_slot"`
FinalizedEpoch string `json:"finalized_epoch"`
FinalizedBlockRoot string `json:"finalized_block_root"`
JustifiedSlot string `json:"justified_slot"`
JustifiedEpoch string `json:"justified_epoch"`
JustifiedBlockRoot string `json:"justified_block_root"`
PreviousJustifiedSlot string `json:"previous_justified_slot"`
PreviousJustifiedEpoch string `json:"previous_justified_epoch"`
PreviousJustifiedBlockRoot string `json:"previous_justified_block_root"`
OptimisticStatus bool `json:"optimistic_status"`
}
func ChainHeadResponseFromConsensus(e *eth.ChainHead) *ChainHead {
return &ChainHead{
HeadSlot: fmt.Sprintf("%d", e.HeadSlot),
HeadEpoch: fmt.Sprintf("%d", e.HeadEpoch),
HeadBlockRoot: hexutil.Encode(e.HeadBlockRoot),
FinalizedSlot: fmt.Sprintf("%d", e.FinalizedSlot),
FinalizedEpoch: fmt.Sprintf("%d", e.FinalizedEpoch),
FinalizedBlockRoot: hexutil.Encode(e.FinalizedBlockRoot),
JustifiedSlot: fmt.Sprintf("%d", e.JustifiedSlot),
JustifiedEpoch: fmt.Sprintf("%d", e.JustifiedEpoch),
JustifiedBlockRoot: hexutil.Encode(e.JustifiedBlockRoot),
PreviousJustifiedSlot: fmt.Sprintf("%d", e.PreviousJustifiedSlot),
PreviousJustifiedEpoch: fmt.Sprintf("%d", e.PreviousJustifiedEpoch),
PreviousJustifiedBlockRoot: hexutil.Encode(e.PreviousJustifiedBlockRoot),
OptimisticStatus: e.OptimisticStatus,
}
}
func (m *ChainHead) ToConsensus() (*eth.ChainHead, error) {
headSlot, err := strconv.ParseUint(m.HeadSlot, 10, 64)
if err != nil {
return nil, server.NewDecodeError(err, "HeadSlot")
}
headEpoch, err := strconv.ParseUint(m.HeadEpoch, 10, 64)
if err != nil {
return nil, server.NewDecodeError(err, "HeadEpoch")
}
headBlockRoot, err := bytesutil.DecodeHexWithLength(m.HeadBlockRoot, fieldparams.RootLength)
if err != nil {
return nil, server.NewDecodeError(err, "HeadBlockRoot")
}
finalizedSlot, err := strconv.ParseUint(m.FinalizedSlot, 10, 64)
if err != nil {
return nil, server.NewDecodeError(err, "FinalizedSlot")
}
finalizedEpoch, err := strconv.ParseUint(m.FinalizedEpoch, 10, 64)
if err != nil {
return nil, server.NewDecodeError(err, "FinalizedEpoch")
}
finalizedBlockRoot, err := bytesutil.DecodeHexWithLength(m.FinalizedBlockRoot, fieldparams.RootLength)
if err != nil {
return nil, server.NewDecodeError(err, "FinalizedBlockRoot")
}
justifiedSlot, err := strconv.ParseUint(m.JustifiedSlot, 10, 64)
if err != nil {
return nil, server.NewDecodeError(err, "JustifiedSlot")
}
justifiedEpoch, err := strconv.ParseUint(m.JustifiedEpoch, 10, 64)
if err != nil {
return nil, server.NewDecodeError(err, "JustifiedEpoch")
}
justifiedBlockRoot, err := bytesutil.DecodeHexWithLength(m.JustifiedBlockRoot, fieldparams.RootLength)
if err != nil {
return nil, server.NewDecodeError(err, "JustifiedBlockRoot")
}
previousjustifiedSlot, err := strconv.ParseUint(m.PreviousJustifiedSlot, 10, 64)
if err != nil {
return nil, server.NewDecodeError(err, "PreviousJustifiedSlot")
}
previousjustifiedEpoch, err := strconv.ParseUint(m.PreviousJustifiedEpoch, 10, 64)
if err != nil {
return nil, server.NewDecodeError(err, "PreviousJustifiedEpoch")
}
previousjustifiedBlockRoot, err := bytesutil.DecodeHexWithLength(m.PreviousJustifiedBlockRoot, fieldparams.RootLength)
if err != nil {
return nil, server.NewDecodeError(err, "PreviousJustifiedBlockRoot")
}
return &eth.ChainHead{
HeadSlot: primitives.Slot(headSlot),
HeadEpoch: primitives.Epoch(headEpoch),
HeadBlockRoot: headBlockRoot,
FinalizedSlot: primitives.Slot(finalizedSlot),
FinalizedEpoch: primitives.Epoch(finalizedEpoch),
FinalizedBlockRoot: finalizedBlockRoot,
JustifiedSlot: primitives.Slot(justifiedSlot),
JustifiedEpoch: primitives.Epoch(justifiedEpoch),
JustifiedBlockRoot: justifiedBlockRoot,
PreviousJustifiedSlot: primitives.Slot(previousjustifiedSlot),
PreviousJustifiedEpoch: primitives.Epoch(previousjustifiedEpoch),
PreviousJustifiedBlockRoot: previousjustifiedBlockRoot,
OptimisticStatus: m.OptimisticStatus,
}, nil
}