mirror of
https://gitlab.com/pulsechaincom/prysm-pulse.git
synced 2025-01-03 08:37:37 +00:00
f7f1d249f2
* fix handlers for get validators * removing log
257 lines
7.8 KiB
Go
257 lines
7.8 KiB
Go
package rpc
|
|
|
|
import (
|
|
"bytes"
|
|
"encoding/json"
|
|
"fmt"
|
|
"net/http"
|
|
"net/http/httptest"
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/ethereum/go-ethereum/common/hexutil"
|
|
"github.com/pkg/errors"
|
|
ethpb "github.com/prysmaticlabs/prysm/v5/proto/prysm/v1alpha1"
|
|
"github.com/prysmaticlabs/prysm/v5/testing/assert"
|
|
"github.com/prysmaticlabs/prysm/v5/testing/require"
|
|
validatormock "github.com/prysmaticlabs/prysm/v5/testing/validator-mock"
|
|
"go.uber.org/mock/gomock"
|
|
"google.golang.org/protobuf/types/known/timestamppb"
|
|
)
|
|
|
|
func TestGetBeaconStatus_NotConnected(t *testing.T) {
|
|
ctrl := gomock.NewController(t)
|
|
nodeClient := validatormock.NewMockNodeClient(ctrl)
|
|
nodeClient.EXPECT().GetSyncStatus(
|
|
gomock.Any(), // ctx
|
|
gomock.Any(),
|
|
).Return(nil /*response*/, errors.New("uh oh"))
|
|
srv := &Server{
|
|
beaconNodeClient: nodeClient,
|
|
}
|
|
req := httptest.NewRequest(http.MethodGet, fmt.Sprintf("/v2/validator/beacon/status"), nil)
|
|
wr := httptest.NewRecorder()
|
|
wr.Body = &bytes.Buffer{}
|
|
srv.GetBeaconStatus(wr, req)
|
|
require.Equal(t, http.StatusOK, wr.Code)
|
|
resp := &BeaconStatusResponse{}
|
|
require.NoError(t, json.Unmarshal(wr.Body.Bytes(), resp))
|
|
want := &BeaconStatusResponse{
|
|
BeaconNodeEndpoint: "",
|
|
Connected: false,
|
|
Syncing: false,
|
|
}
|
|
assert.DeepEqual(t, want, resp)
|
|
}
|
|
|
|
func TestGetBeaconStatus_OK(t *testing.T) {
|
|
ctrl := gomock.NewController(t)
|
|
nodeClient := validatormock.NewMockNodeClient(ctrl)
|
|
beaconChainClient := validatormock.NewMockBeaconChainClient(ctrl)
|
|
nodeClient.EXPECT().GetSyncStatus(
|
|
gomock.Any(), // ctx
|
|
gomock.Any(),
|
|
).Return(ðpb.SyncStatus{Syncing: true}, nil)
|
|
timeStamp := timestamppb.New(time.Unix(0, 0))
|
|
nodeClient.EXPECT().GetGenesis(
|
|
gomock.Any(), // ctx
|
|
gomock.Any(),
|
|
).Return(ðpb.Genesis{
|
|
GenesisTime: timeStamp,
|
|
DepositContractAddress: []byte("hello"),
|
|
}, nil)
|
|
beaconChainClient.EXPECT().GetChainHead(
|
|
gomock.Any(), // ctx
|
|
gomock.Any(),
|
|
).Return(ðpb.ChainHead{
|
|
HeadEpoch: 1,
|
|
}, nil)
|
|
srv := &Server{
|
|
beaconNodeClient: nodeClient,
|
|
beaconChainClient: beaconChainClient,
|
|
}
|
|
|
|
req := httptest.NewRequest(http.MethodGet, fmt.Sprintf("/v2/validator/beacon/status"), nil)
|
|
wr := httptest.NewRecorder()
|
|
wr.Body = &bytes.Buffer{}
|
|
srv.GetBeaconStatus(wr, req)
|
|
require.Equal(t, http.StatusOK, wr.Code)
|
|
resp := &BeaconStatusResponse{}
|
|
require.NoError(t, json.Unmarshal(wr.Body.Bytes(), resp))
|
|
|
|
want := &BeaconStatusResponse{
|
|
BeaconNodeEndpoint: "",
|
|
Connected: true,
|
|
Syncing: true,
|
|
GenesisTime: fmt.Sprintf("%d", time.Unix(0, 0).Unix()),
|
|
DepositContractAddress: "0x68656c6c6f",
|
|
ChainHead: &ChainHead{
|
|
HeadSlot: "0",
|
|
HeadEpoch: "1",
|
|
HeadBlockRoot: "0x",
|
|
FinalizedSlot: "0",
|
|
FinalizedEpoch: "0",
|
|
FinalizedBlockRoot: "0x",
|
|
JustifiedSlot: "0",
|
|
JustifiedEpoch: "0",
|
|
JustifiedBlockRoot: "0x",
|
|
PreviousJustifiedSlot: "0",
|
|
PreviousJustifiedEpoch: "0",
|
|
PreviousJustifiedBlockRoot: "0x",
|
|
OptimisticStatus: false,
|
|
},
|
|
}
|
|
assert.DeepEqual(t, want, resp)
|
|
}
|
|
|
|
func TestServer_GetValidators(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
query string
|
|
expectedReq *ethpb.ListValidatorsRequest
|
|
chainResp *ethpb.Validators
|
|
want *ValidatorsResponse
|
|
wantCode int
|
|
wantErr string
|
|
}{
|
|
{
|
|
name: "happypath on page_size, page_token, public_keys",
|
|
wantCode: http.StatusOK,
|
|
query: "page_size=4&page_token=0&public_keys=0x855ae9c6184d6edd46351b375f16f541b2d33b0ed0da9be4571b13938588aee840ba606a946f0e8023ae3a4b2a43b4d4",
|
|
expectedReq: func() *ethpb.ListValidatorsRequest {
|
|
b, err := hexutil.Decode("0x855ae9c6184d6edd46351b375f16f541b2d33b0ed0da9be4571b13938588aee840ba606a946f0e8023ae3a4b2a43b4d4")
|
|
require.NoError(t, err)
|
|
pubkeys := [][]byte{b}
|
|
return ðpb.ListValidatorsRequest{
|
|
PublicKeys: pubkeys,
|
|
PageSize: int32(4),
|
|
PageToken: "0",
|
|
}
|
|
}(),
|
|
chainResp: func() *ethpb.Validators {
|
|
b, err := hexutil.Decode("0x855ae9c6184d6edd46351b375f16f541b2d33b0ed0da9be4571b13938588aee840ba606a946f0e8023ae3a4b2a43b4d4")
|
|
require.NoError(t, err)
|
|
return ðpb.Validators{
|
|
Epoch: 0,
|
|
ValidatorList: []*ethpb.Validators_ValidatorContainer{
|
|
{
|
|
Index: 0,
|
|
Validator: ðpb.Validator{
|
|
PublicKey: b,
|
|
},
|
|
},
|
|
},
|
|
NextPageToken: "0",
|
|
TotalSize: 0,
|
|
}
|
|
}(),
|
|
want: &ValidatorsResponse{
|
|
Epoch: 0,
|
|
ValidatorList: []*ValidatorContainer{
|
|
{
|
|
Index: 0,
|
|
Validator: &Validator{
|
|
PublicKey: "0x855ae9c6184d6edd46351b375f16f541b2d33b0ed0da9be4571b13938588aee840ba606a946f0e8023ae3a4b2a43b4d4",
|
|
WithdrawalCredentials: "0x",
|
|
EffectiveBalance: 0,
|
|
Slashed: false,
|
|
ActivationEligibilityEpoch: 0,
|
|
ActivationEpoch: 0,
|
|
ExitEpoch: 0,
|
|
WithdrawableEpoch: 0,
|
|
},
|
|
},
|
|
},
|
|
NextPageToken: "0",
|
|
TotalSize: 0,
|
|
},
|
|
},
|
|
{
|
|
name: "extra public key that's empty still returns correct response",
|
|
wantCode: http.StatusOK,
|
|
query: "page_size=4&page_token=0&public_keys=0x855ae9c6184d6edd46351b375f16f541b2d33b0ed0da9be4571b13938588aee840ba606a946f0e8023ae3a4b2a43b4d4&public_keys=",
|
|
expectedReq: func() *ethpb.ListValidatorsRequest {
|
|
b, err := hexutil.Decode("0x855ae9c6184d6edd46351b375f16f541b2d33b0ed0da9be4571b13938588aee840ba606a946f0e8023ae3a4b2a43b4d4")
|
|
require.NoError(t, err)
|
|
pubkeys := [][]byte{b}
|
|
return ðpb.ListValidatorsRequest{
|
|
PublicKeys: pubkeys,
|
|
PageSize: int32(4),
|
|
PageToken: "0",
|
|
}
|
|
}(),
|
|
chainResp: func() *ethpb.Validators {
|
|
b, err := hexutil.Decode("0x855ae9c6184d6edd46351b375f16f541b2d33b0ed0da9be4571b13938588aee840ba606a946f0e8023ae3a4b2a43b4d4")
|
|
require.NoError(t, err)
|
|
return ðpb.Validators{
|
|
Epoch: 0,
|
|
ValidatorList: []*ethpb.Validators_ValidatorContainer{
|
|
{
|
|
Index: 0,
|
|
Validator: ðpb.Validator{
|
|
PublicKey: b,
|
|
},
|
|
},
|
|
},
|
|
NextPageToken: "0",
|
|
TotalSize: 0,
|
|
}
|
|
}(),
|
|
want: &ValidatorsResponse{
|
|
Epoch: 0,
|
|
ValidatorList: []*ValidatorContainer{
|
|
{
|
|
Index: 0,
|
|
Validator: &Validator{
|
|
PublicKey: "0x855ae9c6184d6edd46351b375f16f541b2d33b0ed0da9be4571b13938588aee840ba606a946f0e8023ae3a4b2a43b4d4",
|
|
WithdrawalCredentials: "0x",
|
|
EffectiveBalance: 0,
|
|
Slashed: false,
|
|
ActivationEligibilityEpoch: 0,
|
|
ActivationEpoch: 0,
|
|
ExitEpoch: 0,
|
|
WithdrawableEpoch: 0,
|
|
},
|
|
},
|
|
},
|
|
NextPageToken: "0",
|
|
TotalSize: 0,
|
|
},
|
|
},
|
|
{
|
|
name: "no public keys passed results in error",
|
|
wantCode: http.StatusBadRequest,
|
|
query: "page_size=4&page_token=0&public_keys=",
|
|
wantErr: "no pubkeys provided",
|
|
},
|
|
}
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
ctrl := gomock.NewController(t)
|
|
beaconChainClient := validatormock.NewMockBeaconChainClient(ctrl)
|
|
if tt.wantErr == "" {
|
|
beaconChainClient.EXPECT().ListValidators(
|
|
gomock.Any(), // ctx
|
|
tt.expectedReq,
|
|
).Return(tt.chainResp, nil)
|
|
}
|
|
s := &Server{
|
|
beaconChainClient: beaconChainClient,
|
|
}
|
|
req := httptest.NewRequest(http.MethodGet, fmt.Sprintf("/v2/validator/beacon/validators?%s", tt.query), http.NoBody)
|
|
wr := httptest.NewRecorder()
|
|
wr.Body = &bytes.Buffer{}
|
|
s.GetValidators(wr, req)
|
|
require.Equal(t, tt.wantCode, wr.Code)
|
|
if tt.wantErr != "" {
|
|
require.StringContains(t, tt.wantErr, string(wr.Body.Bytes()))
|
|
} else {
|
|
resp := &ValidatorsResponse{}
|
|
require.NoError(t, json.Unmarshal(wr.Body.Bytes(), resp))
|
|
|
|
require.DeepEqual(t, resp, tt.want)
|
|
}
|
|
})
|
|
}
|
|
}
|