HTTP validator API: beacon and account endpoints (#13191)

* fixing squashing changes, migrates beacon , account, and auth endpoints on validator client

* adding accounts endpoints

* fixing tests and query endpoints

* adding auth endpoint and fixing unit tests

* removing unused files and updating node file to skip gRPC

* ineffectual assignment fix

* rolling back a change to fix e2e

* fixing issues with ui

* updating with webui version 2.0.5

* updating package name flag in readme

* removing restore assets functions

* adding nomemcopy flag to see if vulenerability scan passes

* making data non compressed to avoid copy vulnerability

* Update beacon-chain/rpc/eth/shared/structs_validator.go

Co-authored-by: Raul Jordan <raul@prysmaticlabs.com>

* updating site_data, and skipping static analysis on file

* adding back deprecation comment notice

* updating workflows to ignore generated

* addressing radek comments

* missed a conversion

---------

Co-authored-by: Raul Jordan <raul@prysmaticlabs.com>
This commit is contained in:
james-prysm
2023-12-01 14:40:09 -06:00
committed by GitHub
parent 461af4baa6
commit 394bd1786a
38 changed files with 2052 additions and 4623 deletions

View File

@@ -34,7 +34,7 @@ jobs:
run: | # https://github.com/securego/gosec/issues/469
export PATH=$PATH:$(go env GOPATH)/bin
go install github.com/securego/gosec/v2/cmd/gosec@v2.15.0
gosec -exclude=G307 -exclude-dir=crypto/bls/herumi ./...
gosec -exclude-generated -exclude=G307 -exclude-dir=crypto/bls/herumi ./...
lint:
name: Lint

View File

@@ -2,7 +2,10 @@ load("@prysm//tools/go:def.bzl", "go_library")
go_library(
name = "go_default_library",
srcs = ["headers.go"],
srcs = [
"constants.go",
"headers.go",
],
importpath = "github.com/prysmaticlabs/prysm/v4/api",
visibility = ["//visibility:public"],
)

3
api/constants.go Normal file
View File

@@ -0,0 +1,3 @@
package api
const WebUrlPrefix = "/v2/validator/"

View File

@@ -8,6 +8,7 @@ go_library(
"structs.go",
"structs_blocks.go",
"structs_blocks_conversions.go",
"structs_validator.go",
],
importpath = "github.com/prysmaticlabs/prysm/v4/beacon-chain/rpc/eth/shared",
visibility = ["//visibility:public"],

View File

@@ -701,3 +701,104 @@ type SyncDetails struct {
type SyncDetailsContainer struct {
Data *SyncDetails `json:"data"`
}
// 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, NewDecodeError(err, "HeadSlot")
}
headEpoch, err := strconv.ParseUint(m.HeadEpoch, 10, 64)
if err != nil {
return nil, NewDecodeError(err, "HeadEpoch")
}
headBlockRoot, err := DecodeHexWithLength(m.HeadBlockRoot, fieldparams.RootLength)
if err != nil {
return nil, NewDecodeError(err, "HeadBlockRoot")
}
finalizedSlot, err := strconv.ParseUint(m.FinalizedSlot, 10, 64)
if err != nil {
return nil, NewDecodeError(err, "FinalizedSlot")
}
finalizedEpoch, err := strconv.ParseUint(m.FinalizedEpoch, 10, 64)
if err != nil {
return nil, NewDecodeError(err, "FinalizedEpoch")
}
finalizedBlockRoot, err := DecodeHexWithLength(m.FinalizedBlockRoot, fieldparams.RootLength)
if err != nil {
return nil, NewDecodeError(err, "FinalizedBlockRoot")
}
justifiedSlot, err := strconv.ParseUint(m.JustifiedSlot, 10, 64)
if err != nil {
return nil, NewDecodeError(err, "JustifiedSlot")
}
justifiedEpoch, err := strconv.ParseUint(m.JustifiedEpoch, 10, 64)
if err != nil {
return nil, NewDecodeError(err, "JustifiedEpoch")
}
justifiedBlockRoot, err := DecodeHexWithLength(m.JustifiedBlockRoot, fieldparams.RootLength)
if err != nil {
return nil, NewDecodeError(err, "JustifiedBlockRoot")
}
previousjustifiedSlot, err := strconv.ParseUint(m.PreviousJustifiedSlot, 10, 64)
if err != nil {
return nil, NewDecodeError(err, "PreviousJustifiedSlot")
}
previousjustifiedEpoch, err := strconv.ParseUint(m.PreviousJustifiedEpoch, 10, 64)
if err != nil {
return nil, NewDecodeError(err, "PreviousJustifiedEpoch")
}
previousjustifiedBlockRoot, err := DecodeHexWithLength(m.PreviousJustifiedBlockRoot, fieldparams.RootLength)
if err != nil {
return nil, 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
}

View File

@@ -0,0 +1,156 @@
package shared
import (
"github.com/ethereum/go-ethereum/common/hexutil"
eth "github.com/prysmaticlabs/prysm/v4/proto/prysm/v1alpha1"
)
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
}

View File

@@ -164,7 +164,8 @@
},
"exclude_files": {
".*_test\\.go": "Tests are ok",
"io/file/fileutil.go": "Package which defines the proper rules"
"io/file/fileutil.go": "Package which defines the proper rules",
"validator/web/site_data.go": "Generated web ui assets"
}
},
"uintcast": {

View File

@@ -20,7 +20,6 @@ proto_library(
name = "proto",
srcs = [
"keymanager.proto",
"web_api.proto",
],
visibility = ["//visibility:public"],
deps = [

View File

@@ -7,7 +7,6 @@
package validatorpb
import (
context "context"
reflect "reflect"
sync "sync"
@@ -15,13 +14,8 @@ import (
github_com_prysmaticlabs_prysm_v4_consensus_types_validator "github.com/prysmaticlabs/prysm/v4/consensus-types/validator"
_ "github.com/prysmaticlabs/prysm/v4/proto/eth/ext"
v1alpha1 "github.com/prysmaticlabs/prysm/v4/proto/prysm/v1alpha1"
_ "google.golang.org/genproto/googleapis/api/annotations"
grpc "google.golang.org/grpc"
codes "google.golang.org/grpc/codes"
status "google.golang.org/grpc/status"
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
emptypb "google.golang.org/protobuf/types/known/emptypb"
)
const (
@@ -80,54 +74,7 @@ func (x SignResponse_Status) Number() protoreflect.EnumNumber {
// Deprecated: Use SignResponse_Status.Descriptor instead.
func (SignResponse_Status) EnumDescriptor() ([]byte, []int) {
return file_proto_prysm_v1alpha1_validator_client_keymanager_proto_rawDescGZIP(), []int{2, 0}
}
type ListPublicKeysResponse struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
ValidatingPublicKeys [][]byte `protobuf:"bytes,2,rep,name=validating_public_keys,json=validatingPublicKeys,proto3" json:"validating_public_keys,omitempty"`
}
func (x *ListPublicKeysResponse) Reset() {
*x = ListPublicKeysResponse{}
if protoimpl.UnsafeEnabled {
mi := &file_proto_prysm_v1alpha1_validator_client_keymanager_proto_msgTypes[0]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *ListPublicKeysResponse) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*ListPublicKeysResponse) ProtoMessage() {}
func (x *ListPublicKeysResponse) ProtoReflect() protoreflect.Message {
mi := &file_proto_prysm_v1alpha1_validator_client_keymanager_proto_msgTypes[0]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use ListPublicKeysResponse.ProtoReflect.Descriptor instead.
func (*ListPublicKeysResponse) Descriptor() ([]byte, []int) {
return file_proto_prysm_v1alpha1_validator_client_keymanager_proto_rawDescGZIP(), []int{0}
}
func (x *ListPublicKeysResponse) GetValidatingPublicKeys() [][]byte {
if x != nil {
return x.ValidatingPublicKeys
}
return nil
return file_proto_prysm_v1alpha1_validator_client_keymanager_proto_rawDescGZIP(), []int{1, 0}
}
type SignRequest struct {
@@ -164,7 +111,7 @@ type SignRequest struct {
func (x *SignRequest) Reset() {
*x = SignRequest{}
if protoimpl.UnsafeEnabled {
mi := &file_proto_prysm_v1alpha1_validator_client_keymanager_proto_msgTypes[1]
mi := &file_proto_prysm_v1alpha1_validator_client_keymanager_proto_msgTypes[0]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -177,7 +124,7 @@ func (x *SignRequest) String() string {
func (*SignRequest) ProtoMessage() {}
func (x *SignRequest) ProtoReflect() protoreflect.Message {
mi := &file_proto_prysm_v1alpha1_validator_client_keymanager_proto_msgTypes[1]
mi := &file_proto_prysm_v1alpha1_validator_client_keymanager_proto_msgTypes[0]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -190,7 +137,7 @@ func (x *SignRequest) ProtoReflect() protoreflect.Message {
// Deprecated: Use SignRequest.ProtoReflect.Descriptor instead.
func (*SignRequest) Descriptor() ([]byte, []int) {
return file_proto_prysm_v1alpha1_validator_client_keymanager_proto_rawDescGZIP(), []int{1}
return file_proto_prysm_v1alpha1_validator_client_keymanager_proto_rawDescGZIP(), []int{0}
}
func (x *SignRequest) GetPublicKey() []byte {
@@ -465,7 +412,7 @@ type SignResponse struct {
func (x *SignResponse) Reset() {
*x = SignResponse{}
if protoimpl.UnsafeEnabled {
mi := &file_proto_prysm_v1alpha1_validator_client_keymanager_proto_msgTypes[2]
mi := &file_proto_prysm_v1alpha1_validator_client_keymanager_proto_msgTypes[1]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -478,7 +425,7 @@ func (x *SignResponse) String() string {
func (*SignResponse) ProtoMessage() {}
func (x *SignResponse) ProtoReflect() protoreflect.Message {
mi := &file_proto_prysm_v1alpha1_validator_client_keymanager_proto_msgTypes[2]
mi := &file_proto_prysm_v1alpha1_validator_client_keymanager_proto_msgTypes[1]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -491,7 +438,7 @@ func (x *SignResponse) ProtoReflect() protoreflect.Message {
// Deprecated: Use SignResponse.ProtoReflect.Descriptor instead.
func (*SignResponse) Descriptor() ([]byte, []int) {
return file_proto_prysm_v1alpha1_validator_client_keymanager_proto_rawDescGZIP(), []int{2}
return file_proto_prysm_v1alpha1_validator_client_keymanager_proto_rawDescGZIP(), []int{1}
}
func (x *SignResponse) GetSignature() []byte {
@@ -520,7 +467,7 @@ type ProposerOptionPayload struct {
func (x *ProposerOptionPayload) Reset() {
*x = ProposerOptionPayload{}
if protoimpl.UnsafeEnabled {
mi := &file_proto_prysm_v1alpha1_validator_client_keymanager_proto_msgTypes[3]
mi := &file_proto_prysm_v1alpha1_validator_client_keymanager_proto_msgTypes[2]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -533,7 +480,7 @@ func (x *ProposerOptionPayload) String() string {
func (*ProposerOptionPayload) ProtoMessage() {}
func (x *ProposerOptionPayload) ProtoReflect() protoreflect.Message {
mi := &file_proto_prysm_v1alpha1_validator_client_keymanager_proto_msgTypes[3]
mi := &file_proto_prysm_v1alpha1_validator_client_keymanager_proto_msgTypes[2]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -546,7 +493,7 @@ func (x *ProposerOptionPayload) ProtoReflect() protoreflect.Message {
// Deprecated: Use ProposerOptionPayload.ProtoReflect.Descriptor instead.
func (*ProposerOptionPayload) Descriptor() ([]byte, []int) {
return file_proto_prysm_v1alpha1_validator_client_keymanager_proto_rawDescGZIP(), []int{3}
return file_proto_prysm_v1alpha1_validator_client_keymanager_proto_rawDescGZIP(), []int{2}
}
func (x *ProposerOptionPayload) GetFeeRecipient() string {
@@ -576,7 +523,7 @@ type BuilderConfig struct {
func (x *BuilderConfig) Reset() {
*x = BuilderConfig{}
if protoimpl.UnsafeEnabled {
mi := &file_proto_prysm_v1alpha1_validator_client_keymanager_proto_msgTypes[4]
mi := &file_proto_prysm_v1alpha1_validator_client_keymanager_proto_msgTypes[3]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -589,7 +536,7 @@ func (x *BuilderConfig) String() string {
func (*BuilderConfig) ProtoMessage() {}
func (x *BuilderConfig) ProtoReflect() protoreflect.Message {
mi := &file_proto_prysm_v1alpha1_validator_client_keymanager_proto_msgTypes[4]
mi := &file_proto_prysm_v1alpha1_validator_client_keymanager_proto_msgTypes[3]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -602,7 +549,7 @@ func (x *BuilderConfig) ProtoReflect() protoreflect.Message {
// Deprecated: Use BuilderConfig.ProtoReflect.Descriptor instead.
func (*BuilderConfig) Descriptor() ([]byte, []int) {
return file_proto_prysm_v1alpha1_validator_client_keymanager_proto_rawDescGZIP(), []int{4}
return file_proto_prysm_v1alpha1_validator_client_keymanager_proto_rawDescGZIP(), []int{3}
}
func (x *BuilderConfig) GetEnabled() bool {
@@ -638,7 +585,7 @@ type ProposerSettingsPayload struct {
func (x *ProposerSettingsPayload) Reset() {
*x = ProposerSettingsPayload{}
if protoimpl.UnsafeEnabled {
mi := &file_proto_prysm_v1alpha1_validator_client_keymanager_proto_msgTypes[5]
mi := &file_proto_prysm_v1alpha1_validator_client_keymanager_proto_msgTypes[4]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -651,7 +598,7 @@ func (x *ProposerSettingsPayload) String() string {
func (*ProposerSettingsPayload) ProtoMessage() {}
func (x *ProposerSettingsPayload) ProtoReflect() protoreflect.Message {
mi := &file_proto_prysm_v1alpha1_validator_client_keymanager_proto_msgTypes[5]
mi := &file_proto_prysm_v1alpha1_validator_client_keymanager_proto_msgTypes[4]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -664,7 +611,7 @@ func (x *ProposerSettingsPayload) ProtoReflect() protoreflect.Message {
// Deprecated: Use ProposerSettingsPayload.ProtoReflect.Descriptor instead.
func (*ProposerSettingsPayload) Descriptor() ([]byte, []int) {
return file_proto_prysm_v1alpha1_validator_client_keymanager_proto_rawDescGZIP(), []int{5}
return file_proto_prysm_v1alpha1_validator_client_keymanager_proto_rawDescGZIP(), []int{4}
}
func (x *ProposerSettingsPayload) GetProposerConfig() map[string]*ProposerOptionPayload {
@@ -701,212 +648,185 @@ var file_proto_prysm_v1alpha1_validator_client_keymanager_proto_rawDesc = []byte
0x63, 0x6f, 0x6e, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a,
0x29, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x70, 0x72, 0x79, 0x73, 0x6d, 0x2f, 0x76, 0x31, 0x61,
0x6c, 0x70, 0x68, 0x61, 0x31, 0x2f, 0x73, 0x79, 0x6e, 0x63, 0x5f, 0x63, 0x6f, 0x6d, 0x6d, 0x69,
0x74, 0x74, 0x65, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1c, 0x67, 0x6f, 0x6f, 0x67,
0x6c, 0x65, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f,
0x6e, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1b, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65,
0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x65, 0x6d, 0x70, 0x74, 0x79, 0x2e,
0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x4e, 0x0a, 0x16, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x75, 0x62,
0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12,
0x34, 0x0a, 0x16, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x69, 0x6e, 0x67, 0x5f, 0x70, 0x75,
0x62, 0x6c, 0x69, 0x63, 0x5f, 0x6b, 0x65, 0x79, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0c, 0x52,
0x14, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x69, 0x6e, 0x67, 0x50, 0x75, 0x62, 0x6c, 0x69,
0x63, 0x4b, 0x65, 0x79, 0x73, 0x22, 0xee, 0x0d, 0x0a, 0x0b, 0x53, 0x69, 0x67, 0x6e, 0x52, 0x65,
0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x5f,
0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x70, 0x75, 0x62, 0x6c, 0x69,
0x63, 0x4b, 0x65, 0x79, 0x12, 0x21, 0x0a, 0x0c, 0x73, 0x69, 0x67, 0x6e, 0x69, 0x6e, 0x67, 0x5f,
0x72, 0x6f, 0x6f, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0b, 0x73, 0x69, 0x67, 0x6e,
0x69, 0x6e, 0x67, 0x52, 0x6f, 0x6f, 0x74, 0x12, 0x29, 0x0a, 0x10, 0x73, 0x69, 0x67, 0x6e, 0x61,
0x74, 0x75, 0x72, 0x65, 0x5f, 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28,
0x0c, 0x52, 0x0f, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x44, 0x6f, 0x6d, 0x61,
0x69, 0x6e, 0x12, 0x3a, 0x0a, 0x05, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x18, 0x65, 0x20, 0x01, 0x28,
0x0b, 0x32, 0x22, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x65, 0x74, 0x68,
0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x42, 0x65, 0x61, 0x63, 0x6f, 0x6e,
0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x48, 0x00, 0x52, 0x05, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x12, 0x53,
0x0a, 0x10, 0x61, 0x74, 0x74, 0x65, 0x73, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x64, 0x61,
0x74, 0x61, 0x18, 0x66, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x26, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72,
0x65, 0x75, 0x6d, 0x2e, 0x65, 0x74, 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31,
0x2e, 0x41, 0x74, 0x74, 0x65, 0x73, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x44, 0x61, 0x74, 0x61,
0x48, 0x00, 0x52, 0x0f, 0x61, 0x74, 0x74, 0x65, 0x73, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x44,
0x61, 0x74, 0x61, 0x12, 0x7c, 0x0a, 0x1f, 0x61, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, 0x74, 0x65,
0x5f, 0x61, 0x74, 0x74, 0x65, 0x73, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x61, 0x6e, 0x64,
0x5f, 0x70, 0x72, 0x6f, 0x6f, 0x66, 0x18, 0x67, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x33, 0x2e, 0x65,
0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x65, 0x74, 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c,
0x70, 0x68, 0x61, 0x31, 0x2e, 0x41, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, 0x74, 0x65, 0x41, 0x74,
0x74, 0x65, 0x73, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x41, 0x6e, 0x64, 0x50, 0x72, 0x6f, 0x6f,
0x66, 0x48, 0x00, 0x52, 0x1c, 0x61, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, 0x74, 0x65, 0x41, 0x74,
0x74, 0x65, 0x73, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x41, 0x6e, 0x64, 0x50, 0x72, 0x6f, 0x6f,
0x66, 0x12, 0x3a, 0x0a, 0x04, 0x65, 0x78, 0x69, 0x74, 0x18, 0x68, 0x20, 0x01, 0x28, 0x0b, 0x32,
0x24, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x65, 0x74, 0x68, 0x2e, 0x76,
0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x56, 0x6f, 0x6c, 0x75, 0x6e, 0x74, 0x61, 0x72,
0x79, 0x45, 0x78, 0x69, 0x74, 0x48, 0x00, 0x52, 0x04, 0x65, 0x78, 0x69, 0x74, 0x12, 0x5b, 0x0a,
0x04, 0x73, 0x6c, 0x6f, 0x74, 0x18, 0x69, 0x20, 0x01, 0x28, 0x04, 0x42, 0x45, 0x82, 0xb5, 0x18,
0x41, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x70, 0x72, 0x79, 0x73,
0x6d, 0x61, 0x74, 0x69, 0x63, 0x6c, 0x61, 0x62, 0x73, 0x2f, 0x70, 0x72, 0x79, 0x73, 0x6d, 0x2f,
0x76, 0x34, 0x2f, 0x63, 0x6f, 0x6e, 0x73, 0x65, 0x6e, 0x73, 0x75, 0x73, 0x2d, 0x74, 0x79, 0x70,
0x65, 0x73, 0x2f, 0x70, 0x72, 0x69, 0x6d, 0x69, 0x74, 0x69, 0x76, 0x65, 0x73, 0x2e, 0x53, 0x6c,
0x6f, 0x74, 0x48, 0x00, 0x52, 0x04, 0x73, 0x6c, 0x6f, 0x74, 0x12, 0x5e, 0x0a, 0x05, 0x65, 0x70,
0x6f, 0x63, 0x68, 0x18, 0x6a, 0x20, 0x01, 0x28, 0x04, 0x42, 0x46, 0x82, 0xb5, 0x18, 0x42, 0x67,
0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x70, 0x72, 0x79, 0x73, 0x6d, 0x61,
0x74, 0x69, 0x63, 0x6c, 0x61, 0x62, 0x73, 0x2f, 0x70, 0x72, 0x79, 0x73, 0x6d, 0x2f, 0x76, 0x34,
0x2f, 0x63, 0x6f, 0x6e, 0x73, 0x65, 0x6e, 0x73, 0x75, 0x73, 0x2d, 0x74, 0x79, 0x70, 0x65, 0x73,
0x2f, 0x70, 0x72, 0x69, 0x6d, 0x69, 0x74, 0x69, 0x76, 0x65, 0x73, 0x2e, 0x45, 0x70, 0x6f, 0x63,
0x68, 0x48, 0x00, 0x52, 0x05, 0x65, 0x70, 0x6f, 0x63, 0x68, 0x12, 0x4d, 0x0a, 0x0c, 0x62, 0x6c,
0x6f, 0x63, 0x6b, 0x5f, 0x61, 0x6c, 0x74, 0x61, 0x69, 0x72, 0x18, 0x6b, 0x20, 0x01, 0x28, 0x0b,
0x32, 0x28, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x65, 0x74, 0x68, 0x2e,
0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x42, 0x65, 0x61, 0x63, 0x6f, 0x6e, 0x42,
0x6c, 0x6f, 0x63, 0x6b, 0x41, 0x6c, 0x74, 0x61, 0x69, 0x72, 0x48, 0x00, 0x52, 0x0b, 0x62, 0x6c,
0x6f, 0x63, 0x6b, 0x41, 0x6c, 0x74, 0x61, 0x69, 0x72, 0x12, 0x79, 0x0a, 0x1e, 0x73, 0x79, 0x6e,
0x63, 0x5f, 0x61, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, 0x74, 0x6f, 0x72, 0x5f, 0x73, 0x65, 0x6c,
0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x64, 0x61, 0x74, 0x61, 0x18, 0x6c, 0x20, 0x01, 0x28,
0x0b, 0x32, 0x32, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x65, 0x74, 0x68,
0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x53, 0x79, 0x6e, 0x63, 0x41, 0x67,
0x67, 0x72, 0x65, 0x67, 0x61, 0x74, 0x6f, 0x72, 0x53, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f,
0x6e, 0x44, 0x61, 0x74, 0x61, 0x48, 0x00, 0x52, 0x1b, 0x73, 0x79, 0x6e, 0x63, 0x41, 0x67, 0x67,
0x72, 0x65, 0x67, 0x61, 0x74, 0x6f, 0x72, 0x53, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e,
0x44, 0x61, 0x74, 0x61, 0x12, 0x63, 0x0a, 0x16, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x69, 0x62, 0x75,
0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x61, 0x6e, 0x64, 0x5f, 0x70, 0x72, 0x6f, 0x6f, 0x66, 0x18, 0x6d,
0x20, 0x01, 0x28, 0x0b, 0x32, 0x2b, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e,
0x65, 0x74, 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x43, 0x6f, 0x6e,
0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x41, 0x6e, 0x64, 0x50, 0x72, 0x6f, 0x6f,
0x66, 0x48, 0x00, 0x52, 0x14, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x69, 0x6f,
0x6e, 0x41, 0x6e, 0x64, 0x50, 0x72, 0x6f, 0x6f, 0x66, 0x12, 0x37, 0x0a, 0x17, 0x73, 0x79, 0x6e,
0x63, 0x5f, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x5f, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x5f,
0x72, 0x6f, 0x6f, 0x74, 0x18, 0x6e, 0x20, 0x01, 0x28, 0x0c, 0x48, 0x00, 0x52, 0x14, 0x73, 0x79,
0x6e, 0x63, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x52, 0x6f,
0x6f, 0x74, 0x12, 0x56, 0x0a, 0x0f, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x5f, 0x62, 0x65, 0x6c, 0x6c,
0x61, 0x74, 0x72, 0x69, 0x78, 0x18, 0x6f, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2b, 0x2e, 0x65, 0x74,
0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x65, 0x74, 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70,
0x68, 0x61, 0x31, 0x2e, 0x42, 0x65, 0x61, 0x63, 0x6f, 0x6e, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x42,
0x65, 0x6c, 0x6c, 0x61, 0x74, 0x72, 0x69, 0x78, 0x48, 0x00, 0x52, 0x0e, 0x62, 0x6c, 0x6f, 0x63,
0x6b, 0x42, 0x65, 0x6c, 0x6c, 0x61, 0x74, 0x72, 0x69, 0x78, 0x12, 0x6c, 0x0a, 0x17, 0x62, 0x6c,
0x69, 0x6e, 0x64, 0x65, 0x64, 0x5f, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x5f, 0x62, 0x65, 0x6c, 0x6c,
0x61, 0x74, 0x72, 0x69, 0x78, 0x18, 0x70, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x32, 0x2e, 0x65, 0x74,
0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x65, 0x74, 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70,
0x68, 0x61, 0x31, 0x2e, 0x42, 0x6c, 0x69, 0x6e, 0x64, 0x65, 0x64, 0x42, 0x65, 0x61, 0x63, 0x6f,
0x6e, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x42, 0x65, 0x6c, 0x6c, 0x61, 0x74, 0x72, 0x69, 0x78, 0x48,
0x00, 0x52, 0x15, 0x62, 0x6c, 0x69, 0x6e, 0x64, 0x65, 0x64, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x42,
0x65, 0x6c, 0x6c, 0x61, 0x74, 0x72, 0x69, 0x78, 0x12, 0x54, 0x0a, 0x0c, 0x72, 0x65, 0x67, 0x69,
0x73, 0x74, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x71, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2e,
0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x65, 0x74, 0x68, 0x2e, 0x76, 0x31,
0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72,
0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x56, 0x31, 0x48, 0x00,
0x52, 0x0c, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x50,
0x0a, 0x0d, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x5f, 0x63, 0x61, 0x70, 0x65, 0x6c, 0x6c, 0x61, 0x18,
0x72, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x29, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d,
0x2e, 0x65, 0x74, 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x42, 0x65,
0x61, 0x63, 0x6f, 0x6e, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x43, 0x61, 0x70, 0x65, 0x6c, 0x6c, 0x61,
0x48, 0x00, 0x52, 0x0c, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x43, 0x61, 0x70, 0x65, 0x6c, 0x6c, 0x61,
0x12, 0x66, 0x0a, 0x15, 0x62, 0x6c, 0x69, 0x6e, 0x64, 0x65, 0x64, 0x5f, 0x62, 0x6c, 0x6f, 0x63,
0x6b, 0x5f, 0x63, 0x61, 0x70, 0x65, 0x6c, 0x6c, 0x61, 0x18, 0x73, 0x20, 0x01, 0x28, 0x0b, 0x32,
0x30, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x65, 0x74, 0x68, 0x2e, 0x76,
0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x42, 0x6c, 0x69, 0x6e, 0x64, 0x65, 0x64, 0x42,
0x65, 0x61, 0x63, 0x6f, 0x6e, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x43, 0x61, 0x70, 0x65, 0x6c, 0x6c,
0x61, 0x48, 0x00, 0x52, 0x13, 0x62, 0x6c, 0x69, 0x6e, 0x64, 0x65, 0x64, 0x42, 0x6c, 0x6f, 0x63,
0x6b, 0x43, 0x61, 0x70, 0x65, 0x6c, 0x6c, 0x61, 0x12, 0x4a, 0x0a, 0x0b, 0x62, 0x6c, 0x6f, 0x63,
0x6b, 0x5f, 0x64, 0x65, 0x6e, 0x65, 0x62, 0x18, 0x74, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x27, 0x2e,
0x74, 0x74, 0x65, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xee, 0x0d, 0x0a, 0x0b, 0x53,
0x69, 0x67, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x70, 0x75,
0x62, 0x6c, 0x69, 0x63, 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09,
0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x12, 0x21, 0x0a, 0x0c, 0x73, 0x69, 0x67,
0x6e, 0x69, 0x6e, 0x67, 0x5f, 0x72, 0x6f, 0x6f, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52,
0x0b, 0x73, 0x69, 0x67, 0x6e, 0x69, 0x6e, 0x67, 0x52, 0x6f, 0x6f, 0x74, 0x12, 0x29, 0x0a, 0x10,
0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x5f, 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e,
0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0f, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72,
0x65, 0x44, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x12, 0x3a, 0x0a, 0x05, 0x62, 0x6c, 0x6f, 0x63, 0x6b,
0x18, 0x65, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75,
0x6d, 0x2e, 0x65, 0x74, 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x42,
0x65, 0x61, 0x63, 0x6f, 0x6e, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x48, 0x00, 0x52, 0x05, 0x62, 0x6c,
0x6f, 0x63, 0x6b, 0x12, 0x53, 0x0a, 0x10, 0x61, 0x74, 0x74, 0x65, 0x73, 0x74, 0x61, 0x74, 0x69,
0x6f, 0x6e, 0x5f, 0x64, 0x61, 0x74, 0x61, 0x18, 0x66, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x26, 0x2e,
0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x65, 0x74, 0x68, 0x2e, 0x76, 0x31, 0x61,
0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x42, 0x65, 0x61, 0x63, 0x6f, 0x6e, 0x42, 0x6c, 0x6f, 0x63,
0x6b, 0x44, 0x65, 0x6e, 0x65, 0x62, 0x48, 0x00, 0x52, 0x0a, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x44,
0x65, 0x6e, 0x65, 0x62, 0x12, 0x60, 0x0a, 0x13, 0x62, 0x6c, 0x69, 0x6e, 0x64, 0x65, 0x64, 0x5f,
0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x5f, 0x64, 0x65, 0x6e, 0x65, 0x62, 0x18, 0x75, 0x20, 0x01, 0x28,
0x0b, 0x32, 0x2e, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x65, 0x74, 0x68,
0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x42, 0x6c, 0x69, 0x6e, 0x64, 0x65,
0x64, 0x42, 0x65, 0x61, 0x63, 0x6f, 0x6e, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x44, 0x65, 0x6e, 0x65,
0x62, 0x48, 0x00, 0x52, 0x11, 0x62, 0x6c, 0x69, 0x6e, 0x64, 0x65, 0x64, 0x42, 0x6c, 0x6f, 0x63,
0x6b, 0x44, 0x65, 0x6e, 0x65, 0x62, 0x12, 0x68, 0x0a, 0x0c, 0x73, 0x69, 0x67, 0x6e, 0x69, 0x6e,
0x67, 0x5f, 0x73, 0x6c, 0x6f, 0x74, 0x18, 0x06, 0x20, 0x01, 0x28, 0x04, 0x42, 0x45, 0x82, 0xb5,
0x18, 0x41, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x70, 0x72, 0x79,
0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x41, 0x74, 0x74, 0x65, 0x73, 0x74, 0x61, 0x74, 0x69, 0x6f,
0x6e, 0x44, 0x61, 0x74, 0x61, 0x48, 0x00, 0x52, 0x0f, 0x61, 0x74, 0x74, 0x65, 0x73, 0x74, 0x61,
0x74, 0x69, 0x6f, 0x6e, 0x44, 0x61, 0x74, 0x61, 0x12, 0x7c, 0x0a, 0x1f, 0x61, 0x67, 0x67, 0x72,
0x65, 0x67, 0x61, 0x74, 0x65, 0x5f, 0x61, 0x74, 0x74, 0x65, 0x73, 0x74, 0x61, 0x74, 0x69, 0x6f,
0x6e, 0x5f, 0x61, 0x6e, 0x64, 0x5f, 0x70, 0x72, 0x6f, 0x6f, 0x66, 0x18, 0x67, 0x20, 0x01, 0x28,
0x0b, 0x32, 0x33, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x65, 0x74, 0x68,
0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x41, 0x67, 0x67, 0x72, 0x65, 0x67,
0x61, 0x74, 0x65, 0x41, 0x74, 0x74, 0x65, 0x73, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x41, 0x6e,
0x64, 0x50, 0x72, 0x6f, 0x6f, 0x66, 0x48, 0x00, 0x52, 0x1c, 0x61, 0x67, 0x67, 0x72, 0x65, 0x67,
0x61, 0x74, 0x65, 0x41, 0x74, 0x74, 0x65, 0x73, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x41, 0x6e,
0x64, 0x50, 0x72, 0x6f, 0x6f, 0x66, 0x12, 0x3a, 0x0a, 0x04, 0x65, 0x78, 0x69, 0x74, 0x18, 0x68,
0x20, 0x01, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e,
0x65, 0x74, 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x56, 0x6f, 0x6c,
0x75, 0x6e, 0x74, 0x61, 0x72, 0x79, 0x45, 0x78, 0x69, 0x74, 0x48, 0x00, 0x52, 0x04, 0x65, 0x78,
0x69, 0x74, 0x12, 0x5b, 0x0a, 0x04, 0x73, 0x6c, 0x6f, 0x74, 0x18, 0x69, 0x20, 0x01, 0x28, 0x04,
0x42, 0x45, 0x82, 0xb5, 0x18, 0x41, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d,
0x2f, 0x70, 0x72, 0x79, 0x73, 0x6d, 0x61, 0x74, 0x69, 0x63, 0x6c, 0x61, 0x62, 0x73, 0x2f, 0x70,
0x72, 0x79, 0x73, 0x6d, 0x2f, 0x76, 0x34, 0x2f, 0x63, 0x6f, 0x6e, 0x73, 0x65, 0x6e, 0x73, 0x75,
0x73, 0x2d, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2f, 0x70, 0x72, 0x69, 0x6d, 0x69, 0x74, 0x69, 0x76,
0x65, 0x73, 0x2e, 0x53, 0x6c, 0x6f, 0x74, 0x48, 0x00, 0x52, 0x04, 0x73, 0x6c, 0x6f, 0x74, 0x12,
0x5e, 0x0a, 0x05, 0x65, 0x70, 0x6f, 0x63, 0x68, 0x18, 0x6a, 0x20, 0x01, 0x28, 0x04, 0x42, 0x46,
0x82, 0xb5, 0x18, 0x42, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x70,
0x72, 0x79, 0x73, 0x6d, 0x61, 0x74, 0x69, 0x63, 0x6c, 0x61, 0x62, 0x73, 0x2f, 0x70, 0x72, 0x79,
0x73, 0x6d, 0x2f, 0x76, 0x34, 0x2f, 0x63, 0x6f, 0x6e, 0x73, 0x65, 0x6e, 0x73, 0x75, 0x73, 0x2d,
0x74, 0x79, 0x70, 0x65, 0x73, 0x2f, 0x70, 0x72, 0x69, 0x6d, 0x69, 0x74, 0x69, 0x76, 0x65, 0x73,
0x2e, 0x45, 0x70, 0x6f, 0x63, 0x68, 0x48, 0x00, 0x52, 0x05, 0x65, 0x70, 0x6f, 0x63, 0x68, 0x12,
0x4d, 0x0a, 0x0c, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x5f, 0x61, 0x6c, 0x74, 0x61, 0x69, 0x72, 0x18,
0x6b, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x28, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d,
0x2e, 0x65, 0x74, 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x42, 0x65,
0x61, 0x63, 0x6f, 0x6e, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x41, 0x6c, 0x74, 0x61, 0x69, 0x72, 0x48,
0x00, 0x52, 0x0b, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x41, 0x6c, 0x74, 0x61, 0x69, 0x72, 0x12, 0x79,
0x0a, 0x1e, 0x73, 0x79, 0x6e, 0x63, 0x5f, 0x61, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, 0x74, 0x6f,
0x72, 0x5f, 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x64, 0x61, 0x74, 0x61,
0x18, 0x6c, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x32, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75,
0x6d, 0x2e, 0x65, 0x74, 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x53,
0x79, 0x6e, 0x63, 0x41, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, 0x74, 0x6f, 0x72, 0x53, 0x65, 0x6c,
0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x44, 0x61, 0x74, 0x61, 0x48, 0x00, 0x52, 0x1b, 0x73, 0x79,
0x6e, 0x63, 0x41, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, 0x74, 0x6f, 0x72, 0x53, 0x65, 0x6c, 0x65,
0x63, 0x74, 0x69, 0x6f, 0x6e, 0x44, 0x61, 0x74, 0x61, 0x12, 0x63, 0x0a, 0x16, 0x63, 0x6f, 0x6e,
0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x61, 0x6e, 0x64, 0x5f, 0x70, 0x72,
0x6f, 0x6f, 0x66, 0x18, 0x6d, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2b, 0x2e, 0x65, 0x74, 0x68, 0x65,
0x72, 0x65, 0x75, 0x6d, 0x2e, 0x65, 0x74, 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61,
0x31, 0x2e, 0x43, 0x6f, 0x6e, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x41, 0x6e,
0x64, 0x50, 0x72, 0x6f, 0x6f, 0x66, 0x48, 0x00, 0x52, 0x14, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x69,
0x62, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x41, 0x6e, 0x64, 0x50, 0x72, 0x6f, 0x6f, 0x66, 0x12, 0x37,
0x0a, 0x17, 0x73, 0x79, 0x6e, 0x63, 0x5f, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x5f, 0x62,
0x6c, 0x6f, 0x63, 0x6b, 0x5f, 0x72, 0x6f, 0x6f, 0x74, 0x18, 0x6e, 0x20, 0x01, 0x28, 0x0c, 0x48,
0x00, 0x52, 0x14, 0x73, 0x79, 0x6e, 0x63, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x42, 0x6c,
0x6f, 0x63, 0x6b, 0x52, 0x6f, 0x6f, 0x74, 0x12, 0x56, 0x0a, 0x0f, 0x62, 0x6c, 0x6f, 0x63, 0x6b,
0x5f, 0x62, 0x65, 0x6c, 0x6c, 0x61, 0x74, 0x72, 0x69, 0x78, 0x18, 0x6f, 0x20, 0x01, 0x28, 0x0b,
0x32, 0x2b, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x65, 0x74, 0x68, 0x2e,
0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x42, 0x65, 0x61, 0x63, 0x6f, 0x6e, 0x42,
0x6c, 0x6f, 0x63, 0x6b, 0x42, 0x65, 0x6c, 0x6c, 0x61, 0x74, 0x72, 0x69, 0x78, 0x48, 0x00, 0x52,
0x0e, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x42, 0x65, 0x6c, 0x6c, 0x61, 0x74, 0x72, 0x69, 0x78, 0x12,
0x6c, 0x0a, 0x17, 0x62, 0x6c, 0x69, 0x6e, 0x64, 0x65, 0x64, 0x5f, 0x62, 0x6c, 0x6f, 0x63, 0x6b,
0x5f, 0x62, 0x65, 0x6c, 0x6c, 0x61, 0x74, 0x72, 0x69, 0x78, 0x18, 0x70, 0x20, 0x01, 0x28, 0x0b,
0x32, 0x32, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x65, 0x74, 0x68, 0x2e,
0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x42, 0x6c, 0x69, 0x6e, 0x64, 0x65, 0x64,
0x42, 0x65, 0x61, 0x63, 0x6f, 0x6e, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x42, 0x65, 0x6c, 0x6c, 0x61,
0x74, 0x72, 0x69, 0x78, 0x48, 0x00, 0x52, 0x15, 0x62, 0x6c, 0x69, 0x6e, 0x64, 0x65, 0x64, 0x42,
0x6c, 0x6f, 0x63, 0x6b, 0x42, 0x65, 0x6c, 0x6c, 0x61, 0x74, 0x72, 0x69, 0x78, 0x12, 0x54, 0x0a,
0x0c, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x71, 0x20,
0x01, 0x28, 0x0b, 0x32, 0x2e, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x65,
0x74, 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x56, 0x61, 0x6c, 0x69,
0x64, 0x61, 0x74, 0x6f, 0x72, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x61, 0x74, 0x69, 0x6f,
0x6e, 0x56, 0x31, 0x48, 0x00, 0x52, 0x0c, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x61, 0x74,
0x69, 0x6f, 0x6e, 0x12, 0x50, 0x0a, 0x0d, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x5f, 0x63, 0x61, 0x70,
0x65, 0x6c, 0x6c, 0x61, 0x18, 0x72, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x29, 0x2e, 0x65, 0x74, 0x68,
0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x65, 0x74, 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68,
0x61, 0x31, 0x2e, 0x42, 0x65, 0x61, 0x63, 0x6f, 0x6e, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x43, 0x61,
0x70, 0x65, 0x6c, 0x6c, 0x61, 0x48, 0x00, 0x52, 0x0c, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x43, 0x61,
0x70, 0x65, 0x6c, 0x6c, 0x61, 0x12, 0x66, 0x0a, 0x15, 0x62, 0x6c, 0x69, 0x6e, 0x64, 0x65, 0x64,
0x5f, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x5f, 0x63, 0x61, 0x70, 0x65, 0x6c, 0x6c, 0x61, 0x18, 0x73,
0x20, 0x01, 0x28, 0x0b, 0x32, 0x30, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e,
0x65, 0x74, 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x42, 0x6c, 0x69,
0x6e, 0x64, 0x65, 0x64, 0x42, 0x65, 0x61, 0x63, 0x6f, 0x6e, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x43,
0x61, 0x70, 0x65, 0x6c, 0x6c, 0x61, 0x48, 0x00, 0x52, 0x13, 0x62, 0x6c, 0x69, 0x6e, 0x64, 0x65,
0x64, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x43, 0x61, 0x70, 0x65, 0x6c, 0x6c, 0x61, 0x12, 0x4a, 0x0a,
0x0b, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x5f, 0x64, 0x65, 0x6e, 0x65, 0x62, 0x18, 0x74, 0x20, 0x01,
0x28, 0x0b, 0x32, 0x27, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x65, 0x74,
0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x42, 0x65, 0x61, 0x63, 0x6f,
0x6e, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x44, 0x65, 0x6e, 0x65, 0x62, 0x48, 0x00, 0x52, 0x0a, 0x62,
0x6c, 0x6f, 0x63, 0x6b, 0x44, 0x65, 0x6e, 0x65, 0x62, 0x12, 0x60, 0x0a, 0x13, 0x62, 0x6c, 0x69,
0x6e, 0x64, 0x65, 0x64, 0x5f, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x5f, 0x64, 0x65, 0x6e, 0x65, 0x62,
0x18, 0x75, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2e, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75,
0x6d, 0x2e, 0x65, 0x74, 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x42,
0x6c, 0x69, 0x6e, 0x64, 0x65, 0x64, 0x42, 0x65, 0x61, 0x63, 0x6f, 0x6e, 0x42, 0x6c, 0x6f, 0x63,
0x6b, 0x44, 0x65, 0x6e, 0x65, 0x62, 0x48, 0x00, 0x52, 0x11, 0x62, 0x6c, 0x69, 0x6e, 0x64, 0x65,
0x64, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x44, 0x65, 0x6e, 0x65, 0x62, 0x12, 0x68, 0x0a, 0x0c, 0x73,
0x69, 0x67, 0x6e, 0x69, 0x6e, 0x67, 0x5f, 0x73, 0x6c, 0x6f, 0x74, 0x18, 0x06, 0x20, 0x01, 0x28,
0x04, 0x42, 0x45, 0x82, 0xb5, 0x18, 0x41, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f,
0x6d, 0x2f, 0x70, 0x72, 0x79, 0x73, 0x6d, 0x61, 0x74, 0x69, 0x63, 0x6c, 0x61, 0x62, 0x73, 0x2f,
0x70, 0x72, 0x79, 0x73, 0x6d, 0x2f, 0x76, 0x34, 0x2f, 0x63, 0x6f, 0x6e, 0x73, 0x65, 0x6e, 0x73,
0x75, 0x73, 0x2d, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2f, 0x70, 0x72, 0x69, 0x6d, 0x69, 0x74, 0x69,
0x76, 0x65, 0x73, 0x2e, 0x53, 0x6c, 0x6f, 0x74, 0x52, 0x0b, 0x73, 0x69, 0x67, 0x6e, 0x69, 0x6e,
0x67, 0x53, 0x6c, 0x6f, 0x74, 0x42, 0x08, 0x0a, 0x06, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x4a,
0x04, 0x08, 0x04, 0x10, 0x05, 0x4a, 0x04, 0x08, 0x05, 0x10, 0x06, 0x22, 0xb7, 0x01, 0x0a, 0x0c,
0x53, 0x69, 0x67, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1c, 0x0a, 0x09,
0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52,
0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x12, 0x4b, 0x0a, 0x06, 0x73, 0x74,
0x61, 0x74, 0x75, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x33, 0x2e, 0x65, 0x74, 0x68,
0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x2e,
0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x73, 0x2e, 0x76, 0x32, 0x2e, 0x53, 0x69, 0x67, 0x6e,
0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52,
0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x22, 0x3c, 0x0a, 0x06, 0x53, 0x74, 0x61, 0x74, 0x75,
0x73, 0x12, 0x0b, 0x0a, 0x07, 0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x10, 0x00, 0x12, 0x0d,
0x0a, 0x09, 0x53, 0x55, 0x43, 0x43, 0x45, 0x45, 0x44, 0x45, 0x44, 0x10, 0x01, 0x12, 0x0a, 0x0a,
0x06, 0x44, 0x45, 0x4e, 0x49, 0x45, 0x44, 0x10, 0x02, 0x12, 0x0a, 0x0a, 0x06, 0x46, 0x41, 0x49,
0x4c, 0x45, 0x44, 0x10, 0x03, 0x22, 0x85, 0x01, 0x0a, 0x15, 0x50, 0x72, 0x6f, 0x70, 0x6f, 0x73,
0x65, 0x72, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x12,
0x23, 0x0a, 0x0d, 0x66, 0x65, 0x65, 0x5f, 0x72, 0x65, 0x63, 0x69, 0x70, 0x69, 0x65, 0x6e, 0x74,
0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x66, 0x65, 0x65, 0x52, 0x65, 0x63, 0x69, 0x70,
0x69, 0x65, 0x6e, 0x74, 0x12, 0x47, 0x0a, 0x07, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x65, 0x72, 0x18,
0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2d, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d,
0x2e, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x2e, 0x61, 0x63, 0x63, 0x6f, 0x75,
0x6e, 0x74, 0x73, 0x2e, 0x76, 0x32, 0x2e, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x65, 0x72, 0x43, 0x6f,
0x6e, 0x66, 0x69, 0x67, 0x52, 0x07, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x65, 0x72, 0x22, 0xa6, 0x01,
0x0a, 0x0d, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x65, 0x72, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12,
0x18, 0x0a, 0x07, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08,
0x52, 0x07, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x12, 0x63, 0x0a, 0x09, 0x67, 0x61, 0x73,
0x5f, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x42, 0x46, 0x82, 0xb5,
0x18, 0x42, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x70, 0x72, 0x79,
0x73, 0x6d, 0x61, 0x74, 0x69, 0x63, 0x6c, 0x61, 0x62, 0x73, 0x2f, 0x70, 0x72, 0x79, 0x73, 0x6d,
0x2f, 0x76, 0x34, 0x2f, 0x63, 0x6f, 0x6e, 0x73, 0x65, 0x6e, 0x73, 0x75, 0x73, 0x2d, 0x74, 0x79,
0x70, 0x65, 0x73, 0x2f, 0x70, 0x72, 0x69, 0x6d, 0x69, 0x74, 0x69, 0x76, 0x65, 0x73, 0x2e, 0x53,
0x6c, 0x6f, 0x74, 0x52, 0x0b, 0x73, 0x69, 0x67, 0x6e, 0x69, 0x6e, 0x67, 0x53, 0x6c, 0x6f, 0x74,
0x42, 0x08, 0x0a, 0x06, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x4a, 0x04, 0x08, 0x04, 0x10, 0x05,
0x4a, 0x04, 0x08, 0x05, 0x10, 0x06, 0x22, 0xb7, 0x01, 0x0a, 0x0c, 0x53, 0x69, 0x67, 0x6e, 0x52,
0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61,
0x74, 0x75, 0x72, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x73, 0x69, 0x67, 0x6e,
0x61, 0x74, 0x75, 0x72, 0x65, 0x12, 0x4b, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18,
0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x33, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d,
0x2e, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x2e, 0x61, 0x63, 0x63, 0x6f, 0x75,
0x6e, 0x74, 0x73, 0x2e, 0x76, 0x32, 0x2e, 0x53, 0x69, 0x67, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f,
0x6e, 0x73, 0x65, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74,
0x75, 0x73, 0x22, 0x3c, 0x0a, 0x06, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x0b, 0x0a, 0x07,
0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x10, 0x00, 0x12, 0x0d, 0x0a, 0x09, 0x53, 0x55, 0x43,
0x43, 0x45, 0x45, 0x44, 0x45, 0x44, 0x10, 0x01, 0x12, 0x0a, 0x0a, 0x06, 0x44, 0x45, 0x4e, 0x49,
0x45, 0x44, 0x10, 0x02, 0x12, 0x0a, 0x0a, 0x06, 0x46, 0x41, 0x49, 0x4c, 0x45, 0x44, 0x10, 0x03,
0x22, 0x85, 0x01, 0x0a, 0x15, 0x50, 0x72, 0x6f, 0x70, 0x6f, 0x73, 0x65, 0x72, 0x4f, 0x70, 0x74,
0x69, 0x6f, 0x6e, 0x50, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x12, 0x23, 0x0a, 0x0d, 0x66, 0x65,
0x65, 0x5f, 0x72, 0x65, 0x63, 0x69, 0x70, 0x69, 0x65, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28,
0x09, 0x52, 0x0c, 0x66, 0x65, 0x65, 0x52, 0x65, 0x63, 0x69, 0x70, 0x69, 0x65, 0x6e, 0x74, 0x12,
0x47, 0x0a, 0x07, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x65, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b,
0x32, 0x2d, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x76, 0x61, 0x6c, 0x69,
0x64, 0x61, 0x74, 0x6f, 0x72, 0x2e, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x73, 0x2e, 0x76,
0x32, 0x2e, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x65, 0x72, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52,
0x07, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x65, 0x72, 0x22, 0xa6, 0x01, 0x0a, 0x0d, 0x42, 0x75, 0x69,
0x6c, 0x64, 0x65, 0x72, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x18, 0x0a, 0x07, 0x65, 0x6e,
0x61, 0x62, 0x6c, 0x65, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x65, 0x6e, 0x61,
0x62, 0x6c, 0x65, 0x64, 0x12, 0x63, 0x0a, 0x09, 0x67, 0x61, 0x73, 0x5f, 0x6c, 0x69, 0x6d, 0x69,
0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x42, 0x46, 0x82, 0xb5, 0x18, 0x42, 0x67, 0x69, 0x74,
0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x70, 0x72, 0x79, 0x73, 0x6d, 0x61, 0x74, 0x69,
0x63, 0x6c, 0x61, 0x62, 0x73, 0x2f, 0x70, 0x72, 0x79, 0x73, 0x6d, 0x2f, 0x76, 0x34, 0x2f, 0x63,
0x6f, 0x6e, 0x73, 0x65, 0x6e, 0x73, 0x75, 0x73, 0x2d, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2f, 0x76,
0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x2e, 0x55, 0x69, 0x6e, 0x74, 0x36, 0x34, 0x52,
0x08, 0x67, 0x61, 0x73, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x72, 0x65, 0x6c,
0x61, 0x79, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x09, 0x52, 0x06, 0x72, 0x65, 0x6c, 0x61, 0x79,
0x73, 0x22, 0xe7, 0x02, 0x0a, 0x17, 0x50, 0x72, 0x6f, 0x70, 0x6f, 0x73, 0x65, 0x72, 0x53, 0x65,
0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x50, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x12, 0x74, 0x0a,
0x0f, 0x70, 0x72, 0x6f, 0x70, 0x6f, 0x73, 0x65, 0x72, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67,
0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x4b, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75,
0x6d, 0x2e, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x2e, 0x61, 0x63, 0x63, 0x6f,
0x75, 0x6e, 0x74, 0x73, 0x2e, 0x76, 0x32, 0x2e, 0x50, 0x72, 0x6f, 0x70, 0x6f, 0x73, 0x65, 0x72,
0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x50, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x2e,
0x50, 0x72, 0x6f, 0x70, 0x6f, 0x73, 0x65, 0x72, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x45, 0x6e,
0x74, 0x72, 0x79, 0x52, 0x0e, 0x70, 0x72, 0x6f, 0x70, 0x6f, 0x73, 0x65, 0x72, 0x43, 0x6f, 0x6e,
0x66, 0x69, 0x67, 0x12, 0x5c, 0x0a, 0x0e, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x5f, 0x63,
0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x35, 0x2e, 0x65, 0x74,
0x70, 0x65, 0x73, 0x2f, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x2e, 0x55, 0x69,
0x6e, 0x74, 0x36, 0x34, 0x52, 0x08, 0x67, 0x61, 0x73, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x12, 0x16,
0x0a, 0x06, 0x72, 0x65, 0x6c, 0x61, 0x79, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x09, 0x52, 0x06,
0x72, 0x65, 0x6c, 0x61, 0x79, 0x73, 0x22, 0xe7, 0x02, 0x0a, 0x17, 0x50, 0x72, 0x6f, 0x70, 0x6f,
0x73, 0x65, 0x72, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x50, 0x61, 0x79, 0x6c, 0x6f,
0x61, 0x64, 0x12, 0x74, 0x0a, 0x0f, 0x70, 0x72, 0x6f, 0x70, 0x6f, 0x73, 0x65, 0x72, 0x5f, 0x63,
0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x4b, 0x2e, 0x65, 0x74,
0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72,
0x2e, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x73, 0x2e, 0x76, 0x32, 0x2e, 0x50, 0x72, 0x6f,
0x70, 0x6f, 0x73, 0x65, 0x72, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x61, 0x79, 0x6c, 0x6f,
0x61, 0x64, 0x52, 0x0d, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69,
0x67, 0x1a, 0x78, 0x0a, 0x13, 0x50, 0x72, 0x6f, 0x70, 0x6f, 0x73, 0x65, 0x72, 0x43, 0x6f, 0x6e,
0x66, 0x69, 0x67, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18,
0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x4b, 0x0a, 0x05, 0x76, 0x61,
0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x35, 0x2e, 0x65, 0x74, 0x68, 0x65,
0x72, 0x65, 0x75, 0x6d, 0x2e, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x2e, 0x61,
0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x73, 0x2e, 0x76, 0x32, 0x2e, 0x50, 0x72, 0x6f, 0x70, 0x6f,
0x73, 0x65, 0x72, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64,
0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x32, 0xa7, 0x02, 0x0a, 0x0c,
0x52, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x53, 0x69, 0x67, 0x6e, 0x65, 0x72, 0x12, 0x90, 0x01, 0x0a,
0x18, 0x4c, 0x69, 0x73, 0x74, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x69, 0x6e, 0x67, 0x50,
0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x73, 0x12, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67,
0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74,
0x79, 0x1a, 0x36, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x76, 0x61, 0x6c,
0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x2e, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x73, 0x2e,
0x76, 0x32, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79,
0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x24, 0x82, 0xd3, 0xe4, 0x93, 0x02,
0x1e, 0x12, 0x1c, 0x2f, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x73, 0x2f, 0x76, 0x32, 0x2f,
0x72, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x2f, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x73, 0x12,
0x83, 0x01, 0x0a, 0x04, 0x53, 0x69, 0x67, 0x6e, 0x12, 0x2b, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72,
0x65, 0x75, 0x6d, 0x2e, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x2e, 0x61, 0x63,
0x63, 0x6f, 0x75, 0x6e, 0x74, 0x73, 0x2e, 0x76, 0x32, 0x2e, 0x53, 0x69, 0x67, 0x6e, 0x52, 0x65,
0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2c, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d,
0x2e, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x2e, 0x61, 0x63, 0x63, 0x6f, 0x75,
0x6e, 0x74, 0x73, 0x2e, 0x76, 0x32, 0x2e, 0x53, 0x69, 0x67, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f,
0x6e, 0x73, 0x65, 0x22, 0x20, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1a, 0x22, 0x18, 0x2f, 0x61, 0x63,
0x63, 0x6f, 0x75, 0x6e, 0x74, 0x73, 0x2f, 0x76, 0x32, 0x2f, 0x72, 0x65, 0x6d, 0x6f, 0x74, 0x65,
0x2f, 0x73, 0x69, 0x67, 0x6e, 0x42, 0xce, 0x01, 0x0a, 0x22, 0x6f, 0x72, 0x67, 0x2e, 0x65, 0x74,
0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72,
0x2e, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x73, 0x2e, 0x76, 0x32, 0x42, 0x0f, 0x4b, 0x65,
0x79, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a,
0x53, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x70, 0x72, 0x79, 0x73,
0x6d, 0x61, 0x74, 0x69, 0x63, 0x6c, 0x61, 0x62, 0x73, 0x2f, 0x70, 0x72, 0x79, 0x73, 0x6d, 0x2f,
0x76, 0x34, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x70, 0x72, 0x79, 0x73, 0x6d, 0x2f, 0x76,
0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2f, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f,
0x72, 0x2d, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x3b, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74,
0x6f, 0x72, 0x70, 0x62, 0xaa, 0x02, 0x1e, 0x45, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e,
0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x2e, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e,
0x74, 0x73, 0x2e, 0x56, 0x32, 0xca, 0x02, 0x1e, 0x45, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d,
0x5c, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x5c, 0x41, 0x63, 0x63, 0x6f, 0x75,
0x6e, 0x74, 0x73, 0x5c, 0x56, 0x32, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
0x70, 0x6f, 0x73, 0x65, 0x72, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x50, 0x61, 0x79,
0x6c, 0x6f, 0x61, 0x64, 0x2e, 0x50, 0x72, 0x6f, 0x70, 0x6f, 0x73, 0x65, 0x72, 0x43, 0x6f, 0x6e,
0x66, 0x69, 0x67, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x0e, 0x70, 0x72, 0x6f, 0x70, 0x6f, 0x73,
0x65, 0x72, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x5c, 0x0a, 0x0e, 0x64, 0x65, 0x66, 0x61,
0x75, 0x6c, 0x74, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b,
0x32, 0x35, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x76, 0x61, 0x6c, 0x69,
0x64, 0x61, 0x74, 0x6f, 0x72, 0x2e, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x73, 0x2e, 0x76,
0x32, 0x2e, 0x50, 0x72, 0x6f, 0x70, 0x6f, 0x73, 0x65, 0x72, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e,
0x50, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x52, 0x0d, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74,
0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x1a, 0x78, 0x0a, 0x13, 0x50, 0x72, 0x6f, 0x70, 0x6f, 0x73,
0x65, 0x72, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a,
0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12,
0x4b, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x35,
0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61,
0x74, 0x6f, 0x72, 0x2e, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x73, 0x2e, 0x76, 0x32, 0x2e,
0x50, 0x72, 0x6f, 0x70, 0x6f, 0x73, 0x65, 0x72, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x61,
0x79, 0x6c, 0x6f, 0x61, 0x64, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01,
0x42, 0xce, 0x01, 0x0a, 0x22, 0x6f, 0x72, 0x67, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75,
0x6d, 0x2e, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x2e, 0x61, 0x63, 0x63, 0x6f,
0x75, 0x6e, 0x74, 0x73, 0x2e, 0x76, 0x32, 0x42, 0x0f, 0x4b, 0x65, 0x79, 0x6d, 0x61, 0x6e, 0x61,
0x67, 0x65, 0x72, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x53, 0x67, 0x69, 0x74, 0x68,
0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x70, 0x72, 0x79, 0x73, 0x6d, 0x61, 0x74, 0x69, 0x63,
0x6c, 0x61, 0x62, 0x73, 0x2f, 0x70, 0x72, 0x79, 0x73, 0x6d, 0x2f, 0x76, 0x34, 0x2f, 0x70, 0x72,
0x6f, 0x74, 0x6f, 0x2f, 0x70, 0x72, 0x79, 0x73, 0x6d, 0x2f, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68,
0x61, 0x31, 0x2f, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x2d, 0x63, 0x6c, 0x69,
0x65, 0x6e, 0x74, 0x3b, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x70, 0x62, 0xaa,
0x02, 0x1e, 0x45, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x56, 0x61, 0x6c, 0x69, 0x64,
0x61, 0x74, 0x6f, 0x72, 0x2e, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x73, 0x2e, 0x56, 0x32,
0xca, 0x02, 0x1e, 0x45, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x5c, 0x56, 0x61, 0x6c, 0x69,
0x64, 0x61, 0x74, 0x6f, 0x72, 0x5c, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x73, 0x5c, 0x56,
0x32, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
}
var (
@@ -922,58 +842,52 @@ func file_proto_prysm_v1alpha1_validator_client_keymanager_proto_rawDescGZIP() [
}
var file_proto_prysm_v1alpha1_validator_client_keymanager_proto_enumTypes = make([]protoimpl.EnumInfo, 1)
var file_proto_prysm_v1alpha1_validator_client_keymanager_proto_msgTypes = make([]protoimpl.MessageInfo, 7)
var file_proto_prysm_v1alpha1_validator_client_keymanager_proto_msgTypes = make([]protoimpl.MessageInfo, 6)
var file_proto_prysm_v1alpha1_validator_client_keymanager_proto_goTypes = []interface{}{
(SignResponse_Status)(0), // 0: ethereum.validator.accounts.v2.SignResponse.Status
(*ListPublicKeysResponse)(nil), // 1: ethereum.validator.accounts.v2.ListPublicKeysResponse
(*SignRequest)(nil), // 2: ethereum.validator.accounts.v2.SignRequest
(*SignResponse)(nil), // 3: ethereum.validator.accounts.v2.SignResponse
(*ProposerOptionPayload)(nil), // 4: ethereum.validator.accounts.v2.ProposerOptionPayload
(*BuilderConfig)(nil), // 5: ethereum.validator.accounts.v2.BuilderConfig
(*ProposerSettingsPayload)(nil), // 6: ethereum.validator.accounts.v2.ProposerSettingsPayload
nil, // 7: ethereum.validator.accounts.v2.ProposerSettingsPayload.ProposerConfigEntry
(*v1alpha1.BeaconBlock)(nil), // 8: ethereum.eth.v1alpha1.BeaconBlock
(*v1alpha1.AttestationData)(nil), // 9: ethereum.eth.v1alpha1.AttestationData
(*v1alpha1.AggregateAttestationAndProof)(nil), // 10: ethereum.eth.v1alpha1.AggregateAttestationAndProof
(*v1alpha1.VoluntaryExit)(nil), // 11: ethereum.eth.v1alpha1.VoluntaryExit
(*v1alpha1.BeaconBlockAltair)(nil), // 12: ethereum.eth.v1alpha1.BeaconBlockAltair
(*v1alpha1.SyncAggregatorSelectionData)(nil), // 13: ethereum.eth.v1alpha1.SyncAggregatorSelectionData
(*v1alpha1.ContributionAndProof)(nil), // 14: ethereum.eth.v1alpha1.ContributionAndProof
(*v1alpha1.BeaconBlockBellatrix)(nil), // 15: ethereum.eth.v1alpha1.BeaconBlockBellatrix
(*v1alpha1.BlindedBeaconBlockBellatrix)(nil), // 16: ethereum.eth.v1alpha1.BlindedBeaconBlockBellatrix
(*v1alpha1.ValidatorRegistrationV1)(nil), // 17: ethereum.eth.v1alpha1.ValidatorRegistrationV1
(*v1alpha1.BeaconBlockCapella)(nil), // 18: ethereum.eth.v1alpha1.BeaconBlockCapella
(*v1alpha1.BlindedBeaconBlockCapella)(nil), // 19: ethereum.eth.v1alpha1.BlindedBeaconBlockCapella
(*v1alpha1.BeaconBlockDeneb)(nil), // 20: ethereum.eth.v1alpha1.BeaconBlockDeneb
(*v1alpha1.BlindedBeaconBlockDeneb)(nil), // 21: ethereum.eth.v1alpha1.BlindedBeaconBlockDeneb
(*emptypb.Empty)(nil), // 22: google.protobuf.Empty
(*SignRequest)(nil), // 1: ethereum.validator.accounts.v2.SignRequest
(*SignResponse)(nil), // 2: ethereum.validator.accounts.v2.SignResponse
(*ProposerOptionPayload)(nil), // 3: ethereum.validator.accounts.v2.ProposerOptionPayload
(*BuilderConfig)(nil), // 4: ethereum.validator.accounts.v2.BuilderConfig
(*ProposerSettingsPayload)(nil), // 5: ethereum.validator.accounts.v2.ProposerSettingsPayload
nil, // 6: ethereum.validator.accounts.v2.ProposerSettingsPayload.ProposerConfigEntry
(*v1alpha1.BeaconBlock)(nil), // 7: ethereum.eth.v1alpha1.BeaconBlock
(*v1alpha1.AttestationData)(nil), // 8: ethereum.eth.v1alpha1.AttestationData
(*v1alpha1.AggregateAttestationAndProof)(nil), // 9: ethereum.eth.v1alpha1.AggregateAttestationAndProof
(*v1alpha1.VoluntaryExit)(nil), // 10: ethereum.eth.v1alpha1.VoluntaryExit
(*v1alpha1.BeaconBlockAltair)(nil), // 11: ethereum.eth.v1alpha1.BeaconBlockAltair
(*v1alpha1.SyncAggregatorSelectionData)(nil), // 12: ethereum.eth.v1alpha1.SyncAggregatorSelectionData
(*v1alpha1.ContributionAndProof)(nil), // 13: ethereum.eth.v1alpha1.ContributionAndProof
(*v1alpha1.BeaconBlockBellatrix)(nil), // 14: ethereum.eth.v1alpha1.BeaconBlockBellatrix
(*v1alpha1.BlindedBeaconBlockBellatrix)(nil), // 15: ethereum.eth.v1alpha1.BlindedBeaconBlockBellatrix
(*v1alpha1.ValidatorRegistrationV1)(nil), // 16: ethereum.eth.v1alpha1.ValidatorRegistrationV1
(*v1alpha1.BeaconBlockCapella)(nil), // 17: ethereum.eth.v1alpha1.BeaconBlockCapella
(*v1alpha1.BlindedBeaconBlockCapella)(nil), // 18: ethereum.eth.v1alpha1.BlindedBeaconBlockCapella
(*v1alpha1.BeaconBlockDeneb)(nil), // 19: ethereum.eth.v1alpha1.BeaconBlockDeneb
(*v1alpha1.BlindedBeaconBlockDeneb)(nil), // 20: ethereum.eth.v1alpha1.BlindedBeaconBlockDeneb
}
var file_proto_prysm_v1alpha1_validator_client_keymanager_proto_depIdxs = []int32{
8, // 0: ethereum.validator.accounts.v2.SignRequest.block:type_name -> ethereum.eth.v1alpha1.BeaconBlock
9, // 1: ethereum.validator.accounts.v2.SignRequest.attestation_data:type_name -> ethereum.eth.v1alpha1.AttestationData
10, // 2: ethereum.validator.accounts.v2.SignRequest.aggregate_attestation_and_proof:type_name -> ethereum.eth.v1alpha1.AggregateAttestationAndProof
11, // 3: ethereum.validator.accounts.v2.SignRequest.exit:type_name -> ethereum.eth.v1alpha1.VoluntaryExit
12, // 4: ethereum.validator.accounts.v2.SignRequest.block_altair:type_name -> ethereum.eth.v1alpha1.BeaconBlockAltair
13, // 5: ethereum.validator.accounts.v2.SignRequest.sync_aggregator_selection_data:type_name -> ethereum.eth.v1alpha1.SyncAggregatorSelectionData
14, // 6: ethereum.validator.accounts.v2.SignRequest.contribution_and_proof:type_name -> ethereum.eth.v1alpha1.ContributionAndProof
15, // 7: ethereum.validator.accounts.v2.SignRequest.block_bellatrix:type_name -> ethereum.eth.v1alpha1.BeaconBlockBellatrix
16, // 8: ethereum.validator.accounts.v2.SignRequest.blinded_block_bellatrix:type_name -> ethereum.eth.v1alpha1.BlindedBeaconBlockBellatrix
17, // 9: ethereum.validator.accounts.v2.SignRequest.registration:type_name -> ethereum.eth.v1alpha1.ValidatorRegistrationV1
18, // 10: ethereum.validator.accounts.v2.SignRequest.block_capella:type_name -> ethereum.eth.v1alpha1.BeaconBlockCapella
19, // 11: ethereum.validator.accounts.v2.SignRequest.blinded_block_capella:type_name -> ethereum.eth.v1alpha1.BlindedBeaconBlockCapella
20, // 12: ethereum.validator.accounts.v2.SignRequest.block_deneb:type_name -> ethereum.eth.v1alpha1.BeaconBlockDeneb
21, // 13: ethereum.validator.accounts.v2.SignRequest.blinded_block_deneb:type_name -> ethereum.eth.v1alpha1.BlindedBeaconBlockDeneb
7, // 0: ethereum.validator.accounts.v2.SignRequest.block:type_name -> ethereum.eth.v1alpha1.BeaconBlock
8, // 1: ethereum.validator.accounts.v2.SignRequest.attestation_data:type_name -> ethereum.eth.v1alpha1.AttestationData
9, // 2: ethereum.validator.accounts.v2.SignRequest.aggregate_attestation_and_proof:type_name -> ethereum.eth.v1alpha1.AggregateAttestationAndProof
10, // 3: ethereum.validator.accounts.v2.SignRequest.exit:type_name -> ethereum.eth.v1alpha1.VoluntaryExit
11, // 4: ethereum.validator.accounts.v2.SignRequest.block_altair:type_name -> ethereum.eth.v1alpha1.BeaconBlockAltair
12, // 5: ethereum.validator.accounts.v2.SignRequest.sync_aggregator_selection_data:type_name -> ethereum.eth.v1alpha1.SyncAggregatorSelectionData
13, // 6: ethereum.validator.accounts.v2.SignRequest.contribution_and_proof:type_name -> ethereum.eth.v1alpha1.ContributionAndProof
14, // 7: ethereum.validator.accounts.v2.SignRequest.block_bellatrix:type_name -> ethereum.eth.v1alpha1.BeaconBlockBellatrix
15, // 8: ethereum.validator.accounts.v2.SignRequest.blinded_block_bellatrix:type_name -> ethereum.eth.v1alpha1.BlindedBeaconBlockBellatrix
16, // 9: ethereum.validator.accounts.v2.SignRequest.registration:type_name -> ethereum.eth.v1alpha1.ValidatorRegistrationV1
17, // 10: ethereum.validator.accounts.v2.SignRequest.block_capella:type_name -> ethereum.eth.v1alpha1.BeaconBlockCapella
18, // 11: ethereum.validator.accounts.v2.SignRequest.blinded_block_capella:type_name -> ethereum.eth.v1alpha1.BlindedBeaconBlockCapella
19, // 12: ethereum.validator.accounts.v2.SignRequest.block_deneb:type_name -> ethereum.eth.v1alpha1.BeaconBlockDeneb
20, // 13: ethereum.validator.accounts.v2.SignRequest.blinded_block_deneb:type_name -> ethereum.eth.v1alpha1.BlindedBeaconBlockDeneb
0, // 14: ethereum.validator.accounts.v2.SignResponse.status:type_name -> ethereum.validator.accounts.v2.SignResponse.Status
5, // 15: ethereum.validator.accounts.v2.ProposerOptionPayload.builder:type_name -> ethereum.validator.accounts.v2.BuilderConfig
7, // 16: ethereum.validator.accounts.v2.ProposerSettingsPayload.proposer_config:type_name -> ethereum.validator.accounts.v2.ProposerSettingsPayload.ProposerConfigEntry
4, // 17: ethereum.validator.accounts.v2.ProposerSettingsPayload.default_config:type_name -> ethereum.validator.accounts.v2.ProposerOptionPayload
4, // 18: ethereum.validator.accounts.v2.ProposerSettingsPayload.ProposerConfigEntry.value:type_name -> ethereum.validator.accounts.v2.ProposerOptionPayload
22, // 19: ethereum.validator.accounts.v2.RemoteSigner.ListValidatingPublicKeys:input_type -> google.protobuf.Empty
2, // 20: ethereum.validator.accounts.v2.RemoteSigner.Sign:input_type -> ethereum.validator.accounts.v2.SignRequest
1, // 21: ethereum.validator.accounts.v2.RemoteSigner.ListValidatingPublicKeys:output_type -> ethereum.validator.accounts.v2.ListPublicKeysResponse
3, // 22: ethereum.validator.accounts.v2.RemoteSigner.Sign:output_type -> ethereum.validator.accounts.v2.SignResponse
21, // [21:23] is the sub-list for method output_type
19, // [19:21] is the sub-list for method input_type
4, // 15: ethereum.validator.accounts.v2.ProposerOptionPayload.builder:type_name -> ethereum.validator.accounts.v2.BuilderConfig
6, // 16: ethereum.validator.accounts.v2.ProposerSettingsPayload.proposer_config:type_name -> ethereum.validator.accounts.v2.ProposerSettingsPayload.ProposerConfigEntry
3, // 17: ethereum.validator.accounts.v2.ProposerSettingsPayload.default_config:type_name -> ethereum.validator.accounts.v2.ProposerOptionPayload
3, // 18: ethereum.validator.accounts.v2.ProposerSettingsPayload.ProposerConfigEntry.value:type_name -> ethereum.validator.accounts.v2.ProposerOptionPayload
19, // [19:19] is the sub-list for method output_type
19, // [19:19] is the sub-list for method input_type
19, // [19:19] is the sub-list for extension type_name
19, // [19:19] is the sub-list for extension extendee
0, // [0:19] is the sub-list for field type_name
@@ -986,18 +900,6 @@ func file_proto_prysm_v1alpha1_validator_client_keymanager_proto_init() {
}
if !protoimpl.UnsafeEnabled {
file_proto_prysm_v1alpha1_validator_client_keymanager_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*ListPublicKeysResponse); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_proto_prysm_v1alpha1_validator_client_keymanager_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*SignRequest); i {
case 0:
return &v.state
@@ -1009,7 +911,7 @@ func file_proto_prysm_v1alpha1_validator_client_keymanager_proto_init() {
return nil
}
}
file_proto_prysm_v1alpha1_validator_client_keymanager_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} {
file_proto_prysm_v1alpha1_validator_client_keymanager_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*SignResponse); i {
case 0:
return &v.state
@@ -1021,7 +923,7 @@ func file_proto_prysm_v1alpha1_validator_client_keymanager_proto_init() {
return nil
}
}
file_proto_prysm_v1alpha1_validator_client_keymanager_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} {
file_proto_prysm_v1alpha1_validator_client_keymanager_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*ProposerOptionPayload); i {
case 0:
return &v.state
@@ -1033,7 +935,7 @@ func file_proto_prysm_v1alpha1_validator_client_keymanager_proto_init() {
return nil
}
}
file_proto_prysm_v1alpha1_validator_client_keymanager_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} {
file_proto_prysm_v1alpha1_validator_client_keymanager_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*BuilderConfig); i {
case 0:
return &v.state
@@ -1045,7 +947,7 @@ func file_proto_prysm_v1alpha1_validator_client_keymanager_proto_init() {
return nil
}
}
file_proto_prysm_v1alpha1_validator_client_keymanager_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} {
file_proto_prysm_v1alpha1_validator_client_keymanager_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*ProposerSettingsPayload); i {
case 0:
return &v.state
@@ -1058,7 +960,7 @@ func file_proto_prysm_v1alpha1_validator_client_keymanager_proto_init() {
}
}
}
file_proto_prysm_v1alpha1_validator_client_keymanager_proto_msgTypes[1].OneofWrappers = []interface{}{
file_proto_prysm_v1alpha1_validator_client_keymanager_proto_msgTypes[0].OneofWrappers = []interface{}{
(*SignRequest_Block)(nil),
(*SignRequest_AttestationData)(nil),
(*SignRequest_AggregateAttestationAndProof)(nil),
@@ -1083,9 +985,9 @@ func file_proto_prysm_v1alpha1_validator_client_keymanager_proto_init() {
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
RawDescriptor: file_proto_prysm_v1alpha1_validator_client_keymanager_proto_rawDesc,
NumEnums: 1,
NumMessages: 7,
NumMessages: 6,
NumExtensions: 0,
NumServices: 1,
NumServices: 0,
},
GoTypes: file_proto_prysm_v1alpha1_validator_client_keymanager_proto_goTypes,
DependencyIndexes: file_proto_prysm_v1alpha1_validator_client_keymanager_proto_depIdxs,
@@ -1097,119 +999,3 @@ func file_proto_prysm_v1alpha1_validator_client_keymanager_proto_init() {
file_proto_prysm_v1alpha1_validator_client_keymanager_proto_goTypes = nil
file_proto_prysm_v1alpha1_validator_client_keymanager_proto_depIdxs = nil
}
// Reference imports to suppress errors if they are not otherwise used.
var _ context.Context
var _ grpc.ClientConnInterface
// This is a compile-time assertion to ensure that this generated file
// is compatible with the grpc package it is being compiled against.
const _ = grpc.SupportPackageIsVersion6
// RemoteSignerClient is the client API for RemoteSigner service.
//
// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream.
type RemoteSignerClient interface {
ListValidatingPublicKeys(ctx context.Context, in *emptypb.Empty, opts ...grpc.CallOption) (*ListPublicKeysResponse, error)
Sign(ctx context.Context, in *SignRequest, opts ...grpc.CallOption) (*SignResponse, error)
}
type remoteSignerClient struct {
cc grpc.ClientConnInterface
}
func NewRemoteSignerClient(cc grpc.ClientConnInterface) RemoteSignerClient {
return &remoteSignerClient{cc}
}
func (c *remoteSignerClient) ListValidatingPublicKeys(ctx context.Context, in *emptypb.Empty, opts ...grpc.CallOption) (*ListPublicKeysResponse, error) {
out := new(ListPublicKeysResponse)
err := c.cc.Invoke(ctx, "/ethereum.validator.accounts.v2.RemoteSigner/ListValidatingPublicKeys", in, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *remoteSignerClient) Sign(ctx context.Context, in *SignRequest, opts ...grpc.CallOption) (*SignResponse, error) {
out := new(SignResponse)
err := c.cc.Invoke(ctx, "/ethereum.validator.accounts.v2.RemoteSigner/Sign", in, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
// RemoteSignerServer is the server API for RemoteSigner service.
type RemoteSignerServer interface {
ListValidatingPublicKeys(context.Context, *emptypb.Empty) (*ListPublicKeysResponse, error)
Sign(context.Context, *SignRequest) (*SignResponse, error)
}
// UnimplementedRemoteSignerServer can be embedded to have forward compatible implementations.
type UnimplementedRemoteSignerServer struct {
}
func (*UnimplementedRemoteSignerServer) ListValidatingPublicKeys(context.Context, *emptypb.Empty) (*ListPublicKeysResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method ListValidatingPublicKeys not implemented")
}
func (*UnimplementedRemoteSignerServer) Sign(context.Context, *SignRequest) (*SignResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method Sign not implemented")
}
func RegisterRemoteSignerServer(s *grpc.Server, srv RemoteSignerServer) {
s.RegisterService(&_RemoteSigner_serviceDesc, srv)
}
func _RemoteSigner_ListValidatingPublicKeys_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(emptypb.Empty)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(RemoteSignerServer).ListValidatingPublicKeys(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/ethereum.validator.accounts.v2.RemoteSigner/ListValidatingPublicKeys",
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(RemoteSignerServer).ListValidatingPublicKeys(ctx, req.(*emptypb.Empty))
}
return interceptor(ctx, in, info, handler)
}
func _RemoteSigner_Sign_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(SignRequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(RemoteSignerServer).Sign(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/ethereum.validator.accounts.v2.RemoteSigner/Sign",
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(RemoteSignerServer).Sign(ctx, req.(*SignRequest))
}
return interceptor(ctx, in, info, handler)
}
var _RemoteSigner_serviceDesc = grpc.ServiceDesc{
ServiceName: "ethereum.validator.accounts.v2.RemoteSigner",
HandlerType: (*RemoteSignerServer)(nil),
Methods: []grpc.MethodDesc{
{
MethodName: "ListValidatingPublicKeys",
Handler: _RemoteSigner_ListValidatingPublicKeys_Handler,
},
{
MethodName: "Sign",
Handler: _RemoteSigner_Sign_Handler,
},
},
Streams: []grpc.StreamDesc{},
Metadata: "proto/prysm/v1alpha1/validator-client/keymanager.proto",
}

View File

@@ -1,238 +1,4 @@
// Code generated by protoc-gen-grpc-gateway. DO NOT EDIT.
// source: proto/prysm/v1alpha1/validator-client/keymanager.proto
//go:build ignore
// +build ignore
/*
Package validatorpb is a reverse proxy.
It translates gRPC into RESTful JSON APIs.
*/
package validatorpb
import (
"context"
"io"
"net/http"
"github.com/grpc-ecosystem/grpc-gateway/v2/runtime"
"github.com/grpc-ecosystem/grpc-gateway/v2/utilities"
github_com_prysmaticlabs_prysm_v4_consensus_types_primitives "github.com/prysmaticlabs/prysm/v4/consensus-types/primitives"
"google.golang.org/grpc"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/grpclog"
"google.golang.org/grpc/metadata"
"google.golang.org/grpc/status"
"google.golang.org/protobuf/proto"
"google.golang.org/protobuf/types/known/emptypb"
)
// Suppress "imported and not used" errors
var _ codes.Code
var _ io.Reader
var _ status.Status
var _ = runtime.String
var _ = utilities.NewDoubleArray
var _ = metadata.Join
var _ = github_com_prysmaticlabs_prysm_v4_consensus_types_primitives.Epoch(0)
var _ = emptypb.Empty{}
func request_RemoteSigner_ListValidatingPublicKeys_0(ctx context.Context, marshaler runtime.Marshaler, client RemoteSignerClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
var protoReq emptypb.Empty
var metadata runtime.ServerMetadata
msg, err := client.ListValidatingPublicKeys(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
return msg, metadata, err
}
func local_request_RemoteSigner_ListValidatingPublicKeys_0(ctx context.Context, marshaler runtime.Marshaler, server RemoteSignerServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
var protoReq emptypb.Empty
var metadata runtime.ServerMetadata
msg, err := server.ListValidatingPublicKeys(ctx, &protoReq)
return msg, metadata, err
}
var (
filter_RemoteSigner_Sign_0 = &utilities.DoubleArray{Encoding: map[string]int{}, Base: []int(nil), Check: []int(nil)}
)
func request_RemoteSigner_Sign_0(ctx context.Context, marshaler runtime.Marshaler, client RemoteSignerClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
var protoReq SignRequest
var metadata runtime.ServerMetadata
if err := req.ParseForm(); err != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
}
if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_RemoteSigner_Sign_0); err != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
}
msg, err := client.Sign(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
return msg, metadata, err
}
func local_request_RemoteSigner_Sign_0(ctx context.Context, marshaler runtime.Marshaler, server RemoteSignerServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
var protoReq SignRequest
var metadata runtime.ServerMetadata
if err := req.ParseForm(); err != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
}
if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_RemoteSigner_Sign_0); err != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
}
msg, err := server.Sign(ctx, &protoReq)
return msg, metadata, err
}
// RegisterRemoteSignerHandlerServer registers the http handlers for service RemoteSigner to "mux".
// UnaryRPC :call RemoteSignerServer directly.
// StreamingRPC :currently unsupported pending https://github.com/grpc/grpc-go/issues/906.
// Note that using this registration option will cause many gRPC library features to stop working. Consider using RegisterRemoteSignerHandlerFromEndpoint instead.
func RegisterRemoteSignerHandlerServer(ctx context.Context, mux *runtime.ServeMux, server RemoteSignerServer) error {
mux.Handle("GET", pattern_RemoteSigner_ListValidatingPublicKeys_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
ctx, cancel := context.WithCancel(req.Context())
defer cancel()
var stream runtime.ServerTransportStream
ctx = grpc.NewContextWithServerTransportStream(ctx, &stream)
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/ethereum.validator.accounts.v2.RemoteSigner/ListValidatingPublicKeys")
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
resp, md, err := local_request_RemoteSigner_ListValidatingPublicKeys_0(rctx, inboundMarshaler, server, req, pathParams)
md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer())
ctx = runtime.NewServerMetadataContext(ctx, md)
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
forward_RemoteSigner_ListValidatingPublicKeys_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
})
mux.Handle("POST", pattern_RemoteSigner_Sign_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
ctx, cancel := context.WithCancel(req.Context())
defer cancel()
var stream runtime.ServerTransportStream
ctx = grpc.NewContextWithServerTransportStream(ctx, &stream)
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/ethereum.validator.accounts.v2.RemoteSigner/Sign")
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
resp, md, err := local_request_RemoteSigner_Sign_0(rctx, inboundMarshaler, server, req, pathParams)
md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer())
ctx = runtime.NewServerMetadataContext(ctx, md)
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
forward_RemoteSigner_Sign_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
})
return nil
}
// RegisterRemoteSignerHandlerFromEndpoint is same as RegisterRemoteSignerHandler but
// automatically dials to "endpoint" and closes the connection when "ctx" gets done.
func RegisterRemoteSignerHandlerFromEndpoint(ctx context.Context, mux *runtime.ServeMux, endpoint string, opts []grpc.DialOption) (err error) {
conn, err := grpc.Dial(endpoint, opts...)
if err != nil {
return err
}
defer func() {
if err != nil {
if cerr := conn.Close(); cerr != nil {
grpclog.Infof("Failed to close conn to %s: %v", endpoint, cerr)
}
return
}
go func() {
<-ctx.Done()
if cerr := conn.Close(); cerr != nil {
grpclog.Infof("Failed to close conn to %s: %v", endpoint, cerr)
}
}()
}()
return RegisterRemoteSignerHandler(ctx, mux, conn)
}
// RegisterRemoteSignerHandler registers the http handlers for service RemoteSigner to "mux".
// The handlers forward requests to the grpc endpoint over "conn".
func RegisterRemoteSignerHandler(ctx context.Context, mux *runtime.ServeMux, conn *grpc.ClientConn) error {
return RegisterRemoteSignerHandlerClient(ctx, mux, NewRemoteSignerClient(conn))
}
// RegisterRemoteSignerHandlerClient registers the http handlers for service RemoteSigner
// to "mux". The handlers forward requests to the grpc endpoint over the given implementation of "RemoteSignerClient".
// Note: the gRPC framework executes interceptors within the gRPC handler. If the passed in "RemoteSignerClient"
// doesn't go through the normal gRPC flow (creating a gRPC client etc.) then it will be up to the passed in
// "RemoteSignerClient" to call the correct interceptors.
func RegisterRemoteSignerHandlerClient(ctx context.Context, mux *runtime.ServeMux, client RemoteSignerClient) error {
mux.Handle("GET", pattern_RemoteSigner_ListValidatingPublicKeys_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
ctx, cancel := context.WithCancel(req.Context())
defer cancel()
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
rctx, err := runtime.AnnotateContext(ctx, mux, req, "/ethereum.validator.accounts.v2.RemoteSigner/ListValidatingPublicKeys")
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
resp, md, err := request_RemoteSigner_ListValidatingPublicKeys_0(rctx, inboundMarshaler, client, req, pathParams)
ctx = runtime.NewServerMetadataContext(ctx, md)
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
forward_RemoteSigner_ListValidatingPublicKeys_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
})
mux.Handle("POST", pattern_RemoteSigner_Sign_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
ctx, cancel := context.WithCancel(req.Context())
defer cancel()
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
rctx, err := runtime.AnnotateContext(ctx, mux, req, "/ethereum.validator.accounts.v2.RemoteSigner/Sign")
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
resp, md, err := request_RemoteSigner_Sign_0(rctx, inboundMarshaler, client, req, pathParams)
ctx = runtime.NewServerMetadataContext(ctx, md)
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
forward_RemoteSigner_Sign_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
})
return nil
}
var (
pattern_RemoteSigner_ListValidatingPublicKeys_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 0}, []string{"accounts", "v2", "remote"}, ""))
pattern_RemoteSigner_Sign_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3}, []string{"accounts", "v2", "remote", "sign"}, ""))
)
var (
forward_RemoteSigner_ListValidatingPublicKeys_0 = runtime.ForwardResponseMessage
forward_RemoteSigner_Sign_0 = runtime.ForwardResponseMessage
)
package ignore

View File

@@ -6,8 +6,6 @@ import "proto/prysm/v1alpha1/attestation.proto";
import "proto/prysm/v1alpha1/beacon_block.proto";
import "proto/prysm/v1alpha1/beacon_state.proto";
import "proto/prysm/v1alpha1/sync_committee.proto";
import "google/api/annotations.proto";
import "google/protobuf/empty.proto";
option csharp_namespace = "Ethereum.Validator.Accounts.V2";
option go_package = "github.com/prysmaticlabs/prysm/v4/proto/prysm/v1alpha1/validator-client;validatorpb";
@@ -16,33 +14,6 @@ option java_outer_classname = "KeymanagerProto";
option java_package = "org.ethereum.validator.accounts.v2";
option php_namespace = "Ethereum\\Validator\\Accounts\\V2";
// RemoteSigner service API.
//
// Defines a remote-signing keymanager which manages eth2
// validator accounts and can sign respective messages.
service RemoteSigner {
// ListPublicKeysResponse managed by a remote signer.
rpc ListValidatingPublicKeys(google.protobuf.Empty) returns (ListPublicKeysResponse) {
option (google.api.http) = {
get: "/accounts/v2/remote/accounts"
};
}
// Sign a remote request via gRPC.
rpc Sign(SignRequest) returns (SignResponse) {
option (google.api.http) = {
post: "/accounts/v2/remote/sign"
};
}
}
// ListPublicKeysResponse contains public keys
// for the validator secrets managed by the remote signer.
message ListPublicKeysResponse {
// List of 48 byte, BLS12-381 validating public keys.
repeated bytes validating_public_keys = 2;
}
// SignRequest is a message type used by a keymanager
// as part of Prysm's accounts v2 implementation.
message SignRequest {

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -1,253 +0,0 @@
syntax = "proto3";
package ethereum.validator.accounts.v2;
import "proto/prysm/v1alpha1/beacon_chain.proto";
import "proto/prysm/v1alpha1/node.proto";
import "google/api/annotations.proto";
import "google/protobuf/empty.proto";
option csharp_namespace = "Ethereum.Validator.Accounts.V2";
option go_package = "github.com/prysmaticlabs/prysm/v4/proto/prysm/v1alpha1/validator-client;validatorpb";
option java_multiple_files = true;
option java_outer_classname = "WebProto";
option java_package = "org.ethereum.validator.accounts.v2";
option php_namespace = "Ethereum\\Validator\\Accounts\\V2";
// Account related commands will either need to be done through the Keymanager APIs https://ethereum.github.io/keymanager-APIs/
// or through validator client CLI commands
// DEPRECATED: Prysm Web UI and associated endpoints will be fully removed in a future hard fork.
service Accounts {
rpc ListAccounts(ListAccountsRequest) returns (ListAccountsResponse) {
option deprecated = true;
option (google.api.http) = {
get: "/v2/validator/accounts"
};
}
rpc BackupAccounts(BackupAccountsRequest) returns (BackupAccountsResponse) {
option deprecated = true;
option (google.api.http) = {
post: "/v2/validator/accounts/backup",
body: "*"
};
}
rpc VoluntaryExit(VoluntaryExitRequest) returns (VoluntaryExitResponse) {
option deprecated = true;
option (google.api.http) = {
post: "/v2/validator/accounts/voluntary-exit",
body: "*"
};
}
}
// Validator metrics should be viewed in the grafana dashboards and other relevant beacon node information through beacon APIs.
// DEPRECATED: Prysm Web UI and associated endpoints will be fully removed in a future hard fork.
service Beacon {
rpc GetBeaconStatus(google.protobuf.Empty) returns (BeaconStatusResponse) {
option deprecated = true;
option (google.api.http) = {
get: "/v2/validator/beacon/status"
};
}
rpc GetValidatorParticipation(
ethereum.eth.v1alpha1.GetValidatorParticipationRequest
) returns (ethereum.eth.v1alpha1.ValidatorParticipationResponse) {
option deprecated = true;
option (google.api.http) = {
get: "/v2/validator/beacon/participation"
};
}
rpc GetValidatorPerformance(
ethereum.eth.v1alpha1.ValidatorPerformanceRequest
) returns (ethereum.eth.v1alpha1.ValidatorPerformanceResponse) {
option deprecated = true;
option (google.api.http) = {
get: "/v2/validator/beacon/summary"
};
}
rpc GetValidators(
ethereum.eth.v1alpha1.ListValidatorsRequest
) returns (ethereum.eth.v1alpha1.Validators) {
option deprecated = true;
option (google.api.http) = {
get: "/v2/validator/beacon/validators"
};
}
rpc GetValidatorBalances(
ethereum.eth.v1alpha1.ListValidatorBalancesRequest
) returns (ethereum.eth.v1alpha1.ValidatorBalances) {
option deprecated = true;
option (google.api.http) = {
get: "/v2/validator/beacon/balances"
};
}
rpc GetValidatorQueue(google.protobuf.Empty) returns (ethereum.eth.v1alpha1.ValidatorQueue) {
option deprecated = true;
option (google.api.http) = {
get: "/v2/validator/beacon/queue"
};
}
rpc GetPeers(google.protobuf.Empty) returns (ethereum.eth.v1alpha1.Peers) {
option deprecated = true;
option (google.api.http) = {
get: "/v2/validator/beacon/peers"
};
}
}
// Web APIs such as the Keymanager APIs will no longer validate JWTs on the endpoint. Users should no longer expose the validator APIs to the public.
// option deprecated = true; can't be added yet as it's used for keymanager API
// DEPRECATED: Prysm Web UI and associated endpoints will be fully removed in a future hard fork.
service Auth {
rpc Initialize(google.protobuf.Empty) returns (InitializeAuthResponse) {
option (google.api.http) = {
get: "/v2/validator/initialize",
};
}
}
// DEPRECATED: Prysm Web UI and associated endpoints will be fully removed in a future hard fork.
message ListAccountsRequest {
option deprecated = true;
// Whether or not to return the raw RLP deposit tx data.
bool get_deposit_tx_data = 1;
// The maximum number of accounts to return in the response.
// This field is optional.
int32 page_size = 2;
// A pagination token returned from a previous call to `ListAccounts`
// that indicates where this listing should continue from.
// This field is optional.
string page_token = 3;
// Whether to return all available accounts in a single response.
bool all = 4;
}
// DEPRECATED: Prysm Web UI and associated endpoints will be fully removed in a future hard fork.
message ListAccountsResponse {
option deprecated = true;
repeated Account accounts = 1;
// A pagination token returned from a previous call to `ListAccounts`
// that indicates from where listing should continue.
// This field is optional.
string next_page_token = 2;
// Total count matching the request.
int32 total_size = 3;
}
// DEPRECATED: Prysm Web UI and associated endpoints will be fully removed in a future hard fork.
message Account {
option deprecated = true;
// The validating public key.
bytes validating_public_key = 1;
// The human readable account name.
string account_name = 2;
// The deposit data transaction RLP bytes.
bytes deposit_tx_data = 3;
// The derivation path (if using HD wallet).
string derivation_path = 4;
}
// DEPRECATED: Prysm Web UI and associated endpoints will be fully removed in a future hard fork.
message AccountRequest {
option deprecated = true;
// A list of validator public keys.
repeated bytes public_keys = 1;
// A list of validator indices.
repeated uint64 indices = 2;
}
// DEPRECATED: Prysm Web UI and associated endpoints will be fully removed in a future hard fork.
message ImportAccountsRequest {
option deprecated = true;
// JSON-encoded keystore files to import during wallet creation.
repeated string keystores_imported = 1;
// Password to unlock imported keystore files.
string keystores_password = 2;
}
// DEPRECATED: Prysm Web UI and associated endpoints will be fully removed in a future hard fork.
message ImportAccountsResponse {
option deprecated = true;
repeated bytes imported_public_keys = 1;
}
// DEPRECATED: Prysm Web UI and associated endpoints will be fully removed in a future hard fork.
message InitializeAuthRequest {
option deprecated = true;
string token = 1;
}
// DEPRECATED: Prysm Web UI and associated endpoints will be fully removed in a future hard fork.
message InitializeAuthResponse {
option deprecated = true;
bool has_signed_up = 1;
bool has_wallet = 2;
}
// DEPRECATED: Prysm Web UI and associated endpoints will be fully removed in a future hard fork.
message BeaconStatusResponse {
option deprecated = true;
// The host address of the beacon node the validator
// client is connected to.
string beacon_node_endpoint = 1;
// Whether the connection is active.
bool connected = 2;
// Whether the beacon node is currently synchronizing to chain head.
bool syncing = 3;
// The chain genesis time.
uint64 genesis_time = 4;
// Address of the validator deposit contract in the eth1 chain.
bytes deposit_contract_address = 5;
// The head of the chain from the beacon node.
ethereum.eth.v1alpha1.ChainHead chain_head = 6;
}
// DEPRECATED: Prysm Web UI and associated endpoints will be fully removed in a future hard fork.
message VoluntaryExitRequest {
option deprecated = true;
// List of public keys to voluntarily exit.
repeated bytes public_keys = 1;
}
// DEPRECATED: Prysm Web UI and associated endpoints will be fully removed in a future hard fork.
message VoluntaryExitResponse {
option deprecated = true;
// List of keys that successfully exited.
repeated bytes exited_keys = 1;
}
// DEPRECATED: Prysm Web UI and associated endpoints will be fully removed in a future hard fork.
message BackupAccountsRequest {
option deprecated = true;
// List of public keys to backup.
repeated bytes public_keys = 1;
string backup_password = 2;
}
// DEPRECATED: Prysm Web UI and associated endpoints will be fully removed in a future hard fork.
message BackupAccountsResponse {
option deprecated = true;
// Zip file containing backed up keystores.
bytes zip_file = 1;
}
// DEPRECATED: Prysm Web UI and associated endpoints will be fully removed in a future hard fork.
message DeleteAccountsRequest {
option deprecated = true;
// List of public keys to delete.
repeated bytes public_keys_to_delete = 1;
}
// DEPRECATED: Prysm Web UI and associated endpoints will be fully removed in a future hard fork.
message DeleteAccountsResponse {
option deprecated = true;
// List of public keys successfully deleted.
repeated bytes deleted_keys = 1;
}

View File

@@ -363,16 +363,20 @@ func withCompareValidators(beaconNodeIdx int, conn *grpc.ClientConn) error {
// Compares a regular beacon chain head GET request with no arguments gRPC and gRPC gateway.
func withCompareChainHead(beaconNodeIdx int, conn *grpc.ClientConn) error {
// used for gateway, if using pure HTTP use shared.ChainHead
type chainHeadResponseJSON struct {
HeadSlot string `json:"headSlot"`
HeadEpoch string `json:"headEpoch"`
HeadBlockRoot string `json:"headBlockRoot"`
FinalizedSlot string `json:"finalizedSlot"`
FinalizedEpoch string `json:"finalizedEpoch"`
FinalizedBlockRoot string `json:"finalizedBlockRoot"`
JustifiedSlot string `json:"justifiedSlot"`
JustifiedEpoch string `json:"justifiedEpoch"`
JustifiedBlockRoot string `json:"justifiedBlockRoot"`
HeadSlot string `json:"headSlot"`
HeadEpoch string `json:"headEpoch"`
HeadBlockRoot string `json:"headBlockRoot"`
FinalizedSlot string `json:"finalizedSlot"`
FinalizedEpoch string `json:"finalizedEpoch"`
FinalizedBlockRoot string `json:"finalizedBlockRoot"`
JustifiedSlot string `json:"justifiedSlot"`
JustifiedEpoch string `json:"justifiedEpoch"`
JustifiedBlockRoot string `json:"justifiedBlockRoot"`
PreviousJustifiedSlot string `json:"previousJustifiedSlot"`
PreviousJustifiedEpoch string `json:"previousJustifiedEpoch"`
PreviousJustifiedBlockRoot string `json:"previousJustifiedBlockRoot"`
}
beaconClient := ethpb.NewBeaconChainClient(conn)
ctx := context.Background()
@@ -432,20 +436,41 @@ func withCompareChainHead(beaconNodeIdx int, conn *grpc.ClientConn) error {
)
}
if respJSON.JustifiedSlot != fmt.Sprintf("%d", resp.JustifiedSlot) {
return fmt.Errorf(
"HTTP gateway justified slot %s does not match gRPC %d",
respJSON.JustifiedSlot,
resp.JustifiedSlot,
)
}
if respJSON.JustifiedEpoch != fmt.Sprintf("%d", resp.JustifiedEpoch) {
return fmt.Errorf(
"HTTP gateway justified epoch %s does not match gRPC %d",
respJSON.JustifiedEpoch,
resp.JustifiedEpoch,
)
}
if respJSON.JustifiedBlockRoot != base64.StdEncoding.EncodeToString(resp.JustifiedBlockRoot) {
return fmt.Errorf(
"HTTP gateway justified block root %s does not match gRPC %s",
respJSON.JustifiedBlockRoot,
resp.JustifiedBlockRoot,
)
}
if respJSON.PreviousJustifiedSlot != fmt.Sprintf("%d", resp.PreviousJustifiedSlot) {
return fmt.Errorf(
"HTTP gateway justified slot %s does not match gRPC %d",
respJSON.FinalizedSlot,
resp.FinalizedSlot,
)
}
if respJSON.JustifiedEpoch != fmt.Sprintf("%d", resp.JustifiedEpoch) {
if respJSON.PreviousJustifiedEpoch != fmt.Sprintf("%d", resp.PreviousJustifiedEpoch) {
return fmt.Errorf(
"HTTP gateway justified epoch %s does not match gRPC %d",
respJSON.FinalizedEpoch,
resp.FinalizedEpoch,
)
}
if respJSON.JustifiedBlockRoot != base64.StdEncoding.EncodeToString(resp.JustifiedBlockRoot) {
if respJSON.PreviousJustifiedBlockRoot != base64.StdEncoding.EncodeToString(resp.PreviousJustifiedBlockRoot) {
return fmt.Errorf(
"HTTP gateway justified block root %s does not match gRPC %s",
respJSON.JustifiedBlockRoot,

View File

@@ -11,14 +11,12 @@ go_library(
"beacon_service_mock.go",
"beacon_validator_client_mock.go",
"beacon_validator_server_mock.go",
"keymanager_mock.go",
"node_service_mock.go",
],
importpath = "github.com/prysmaticlabs/prysm/v4/testing/mock",
visibility = ["//visibility:public"],
deps = [
"//proto/prysm/v1alpha1:go_default_library",
"//proto/prysm/v1alpha1/validator-client:go_default_library",
"@com_github_golang_mock//gomock:go_default_library",
"@org_golang_google_grpc//:go_default_library",
"@org_golang_google_grpc//metadata:go_default_library",

View File

@@ -1,78 +0,0 @@
// Code generated by MockGen. DO NOT EDIT.
// Source: github.com/prysmaticlabs/prysm/v4/proto/prysm/v1alpha1/validator-client (interfaces: RemoteSignerClient)
// Package mock is a generated GoMock package.
package mock
import (
context "context"
reflect "reflect"
gomock "github.com/golang/mock/gomock"
validatorpb "github.com/prysmaticlabs/prysm/v4/proto/prysm/v1alpha1/validator-client"
grpc "google.golang.org/grpc"
emptypb "google.golang.org/protobuf/types/known/emptypb"
)
// RemoteSignerClient is a mock of RemoteSignerClient interface.
type RemoteSignerClient struct {
ctrl *gomock.Controller
recorder *RemoteSignerClientMockRecorder
}
// RemoteSignerClientMockRecorder is the mock recorder for MockRemoteSignerClient.
type RemoteSignerClientMockRecorder struct {
mock *RemoteSignerClient
}
// NewMockRemoteSignerClient creates a new mock instance.
func NewMockRemoteSignerClient(ctrl *gomock.Controller) *RemoteSignerClient {
mock := &RemoteSignerClient{ctrl: ctrl}
mock.recorder = &RemoteSignerClientMockRecorder{mock}
return mock
}
// EXPECT returns an object that allows the caller to indicate expected use.
func (m *RemoteSignerClient) EXPECT() *RemoteSignerClientMockRecorder {
return m.recorder
}
// ListValidatingPublicKeys mocks base method.
func (m *RemoteSignerClient) ListValidatingPublicKeys(arg0 context.Context, arg1 *emptypb.Empty, arg2 ...grpc.CallOption) (*validatorpb.ListPublicKeysResponse, error) {
m.ctrl.T.Helper()
varargs := []interface{}{arg0, arg1}
for _, a := range arg2 {
varargs = append(varargs, a)
}
ret := m.ctrl.Call(m, "ListValidatingPublicKeys", varargs...)
ret0, _ := ret[0].(*validatorpb.ListPublicKeysResponse)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// ListValidatingPublicKeys indicates an expected call of ListValidatingPublicKeys.
func (mr *RemoteSignerClientMockRecorder) ListValidatingPublicKeys(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
varargs := append([]interface{}{arg0, arg1}, arg2...)
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListValidatingPublicKeys", reflect.TypeOf((*RemoteSignerClient)(nil).ListValidatingPublicKeys), varargs...)
}
// Sign mocks base method.
func (m *RemoteSignerClient) Sign(arg0 context.Context, arg1 *validatorpb.SignRequest, arg2 ...grpc.CallOption) (*validatorpb.SignResponse, error) {
m.ctrl.T.Helper()
varargs := []interface{}{arg0, arg1}
for _, a := range arg2 {
varargs = append(varargs, a)
}
ret := m.ctrl.Call(m, "Sign", varargs...)
ret0, _ := ret[0].(*validatorpb.SignResponse)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// Sign indicates an expected call of Sign.
func (mr *RemoteSignerClientMockRecorder) Sign(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
varargs := append([]interface{}{arg0, arg1}, arg2...)
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Sign", reflect.TypeOf((*RemoteSignerClient)(nil).Sign), varargs...)
}

View File

@@ -794,10 +794,7 @@ func (c *ValidatorClient) registerRPCGatewayService(router *mux.Router) error {
maxCallSize := c.cliCtx.Uint64(cmd.GrpcMaxCallRecvMsgSizeFlag.Name)
registrations := []gateway.PbHandlerRegistration{
validatorpb.RegisterAuthHandler,
pb.RegisterHealthHandler,
validatorpb.RegisterAccountsHandler,
validatorpb.RegisterBeaconHandler,
}
gwmux := gwruntime.NewServeMux(
gwruntime.WithMarshalerOption(gwruntime.MIMEWildcard, &gwruntime.HTTPBodyMarshaler{
@@ -812,7 +809,7 @@ func (c *ValidatorClient) registerRPCGatewayService(router *mux.Router) error {
},
}),
gwruntime.WithMarshalerOption(
"text/event-stream", &gwruntime.EventSourceJSONPb{},
"text/event-stream", &gwruntime.EventSourceJSONPb{}, // TODO: remove this
),
gwruntime.WithForwardResponseOption(gateway.HttpResponseModifier),
)
@@ -825,19 +822,13 @@ func (c *ValidatorClient) registerRPCGatewayService(router *mux.Router) error {
h(w, req)
} else {
// Finally, we handle with the web server.
// DEPRECATED: Prysm Web UI and associated endpoints will be fully removed in a future hard fork.
web.Handler(w, req)
}
}
// remove "/accounts/", "/v2/" after WebUI DEPRECATED
pbHandler := &gateway.PbMux{
Registrations: registrations,
Patterns: []string{
"/accounts/",
"/v2/",
},
Mux: gwmux,
Mux: gwmux,
}
opts := []gateway.Option{
gateway.WithMuxHandler(muxHandler),

View File

@@ -3,10 +3,12 @@ load("@prysm//tools/go:def.bzl", "go_library", "go_test")
go_library(
name = "go_default_library",
srcs = [
"accounts.go",
"auth_token.go",
"beacon.go",
"handler_wallet.go",
"handlers_accounts.go",
"handlers_auth.go",
"handlers_beacon.go",
"handlers_health.go",
"handlers_keymanager.go",
"handlers_slashing.go",
@@ -20,6 +22,7 @@ go_library(
"//visibility:public",
],
deps = [
"//api:go_default_library",
"//api/grpc:go_default_library",
"//api/pagination:go_default_library",
"//async/event:go_default_library",
@@ -40,7 +43,6 @@ go_library(
"//monitoring/tracing:go_default_library",
"//network/http:go_default_library",
"//proto/prysm/v1alpha1:go_default_library",
"//proto/prysm/v1alpha1/validator-client:go_default_library",
"//runtime/version:go_default_library",
"//validator/accounts:go_default_library",
"//validator/accounts/petnames:go_default_library",
@@ -61,7 +63,6 @@ go_library(
"@com_github_ethereum_go_ethereum//common/hexutil:go_default_library",
"@com_github_fsnotify_fsnotify//:go_default_library",
"@com_github_golang_jwt_jwt_v4//:go_default_library",
"@com_github_golang_protobuf//ptypes/empty",
"@com_github_gorilla_mux//:go_default_library",
"@com_github_grpc_ecosystem_go_grpc_middleware//:go_default_library",
"@com_github_grpc_ecosystem_go_grpc_middleware//recovery:go_default_library",
@@ -88,10 +89,12 @@ go_library(
go_test(
name = "go_default_test",
srcs = [
"accounts_test.go",
"auth_token_test.go",
"beacon_test.go",
"handler_wallet_test.go",
"handlers_accounts_test.go",
"handlers_auth_test.go",
"handlers_beacon_test.go",
"handlers_health_test.go",
"handlers_keymanager_test.go",
"handlers_slashing_test.go",
@@ -100,7 +103,9 @@ go_test(
],
embed = [":go_default_library"],
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",
@@ -114,7 +119,6 @@ go_test(
"//io/file:go_default_library",
"//io/logs/mock:go_default_library",
"//proto/prysm/v1alpha1:go_default_library",
"//proto/prysm/v1alpha1/validator-client:go_default_library",
"//testing/assert:go_default_library",
"//testing/require:go_default_library",
"//testing/validator-mock:go_default_library",

View File

@@ -1,197 +0,0 @@
package rpc
import (
"archive/zip"
"bytes"
"context"
"encoding/json"
"fmt"
"github.com/prysmaticlabs/prysm/v4/api/pagination"
"github.com/prysmaticlabs/prysm/v4/cmd"
"github.com/prysmaticlabs/prysm/v4/crypto/bls"
pb "github.com/prysmaticlabs/prysm/v4/proto/prysm/v1alpha1/validator-client"
"github.com/prysmaticlabs/prysm/v4/validator/accounts"
"github.com/prysmaticlabs/prysm/v4/validator/accounts/petnames"
"github.com/prysmaticlabs/prysm/v4/validator/keymanager"
"github.com/prysmaticlabs/prysm/v4/validator/keymanager/derived"
"github.com/prysmaticlabs/prysm/v4/validator/keymanager/local"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/status"
)
// ListAccounts allows retrieval of validating keys and their petnames
// for a user's wallet via RPC.
// DEPRECATED: Prysm Web UI and associated endpoints will be fully removed in a future hard fork.
func (s *Server) ListAccounts(ctx context.Context, req *pb.ListAccountsRequest) (*pb.ListAccountsResponse, error) {
if s.validatorService == nil {
return nil, status.Error(codes.FailedPrecondition, "Validator service not yet initialized")
}
if !s.walletInitialized {
return nil, status.Error(codes.FailedPrecondition, "Wallet not yet initialized")
}
if int(req.PageSize) > cmd.Get().MaxRPCPageSize {
return nil, status.Errorf(codes.InvalidArgument, "Requested page size %d can not be greater than max size %d",
req.PageSize, cmd.Get().MaxRPCPageSize)
}
km, err := s.validatorService.Keymanager()
if err != nil {
return nil, err
}
keys, err := km.FetchValidatingPublicKeys(ctx)
if err != nil {
return nil, err
}
accs := make([]*pb.Account, len(keys))
for i := 0; i < len(keys); i++ {
accs[i] = &pb.Account{
ValidatingPublicKey: keys[i][:],
AccountName: petnames.DeterministicName(keys[i][:], "-"),
}
if s.wallet.KeymanagerKind() == keymanager.Derived {
accs[i].DerivationPath = fmt.Sprintf(derived.ValidatingKeyDerivationPathTemplate, i)
}
}
if req.All {
return &pb.ListAccountsResponse{
Accounts: accs,
TotalSize: int32(len(keys)),
NextPageToken: "",
}, nil
}
start, end, nextPageToken, err := pagination.StartAndEndPage(req.PageToken, int(req.PageSize), len(keys))
if err != nil {
return nil, status.Errorf(
codes.Internal,
"Could not paginate results: %v",
err,
)
}
return &pb.ListAccountsResponse{
Accounts: accs[start:end],
TotalSize: int32(len(keys)),
NextPageToken: nextPageToken,
}, nil
}
// BackupAccounts creates a zip file containing EIP-2335 keystores for the user's
// specified public keys by encrypting them with the specified password.
// DEPRECATED: Prysm Web UI and associated endpoints will be fully removed in a future hard fork.
func (s *Server) BackupAccounts(
ctx context.Context, req *pb.BackupAccountsRequest,
) (*pb.BackupAccountsResponse, error) {
if s.validatorService == nil {
return nil, status.Error(codes.FailedPrecondition, "Validator service not yet initialized")
}
if req.PublicKeys == nil || len(req.PublicKeys) < 1 {
return nil, status.Error(codes.InvalidArgument, "No public keys specified to backup")
}
if req.BackupPassword == "" {
return nil, status.Error(codes.InvalidArgument, "Backup password cannot be empty")
}
if s.wallet == nil {
return nil, status.Error(codes.FailedPrecondition, "No wallet found")
}
var err error
km, err := s.validatorService.Keymanager()
if err != nil {
return nil, err
}
pubKeys := make([]bls.PublicKey, len(req.PublicKeys))
for i, key := range req.PublicKeys {
pubKey, err := bls.PublicKeyFromBytes(key)
if err != nil {
return nil, status.Errorf(codes.InvalidArgument, "%#x Not a valid BLS public key: %v", key, err)
}
pubKeys[i] = pubKey
}
var keystoresToBackup []*keymanager.Keystore
switch km := km.(type) {
case *local.Keymanager:
keystoresToBackup, err = km.ExtractKeystores(ctx, pubKeys, req.BackupPassword)
if err != nil {
return nil, status.Errorf(codes.Internal, "Could not backup accounts for local keymanager: %v", err)
}
case *derived.Keymanager:
keystoresToBackup, err = km.ExtractKeystores(ctx, pubKeys, req.BackupPassword)
if err != nil {
return nil, status.Errorf(codes.Internal, "Could not backup accounts for derived keymanager: %v", err)
}
default:
return nil, status.Error(codes.FailedPrecondition, "Only HD or IMPORTED wallets can backup accounts")
}
if len(keystoresToBackup) == 0 {
return nil, status.Error(codes.InvalidArgument, "No keystores to backup")
}
buf := new(bytes.Buffer)
writer := zip.NewWriter(buf)
for i, k := range keystoresToBackup {
encodedFile, err := json.MarshalIndent(k, "", "\t")
if err != nil {
if err := writer.Close(); err != nil {
log.WithError(err).Error("Could not close zip file after writing")
}
return nil, status.Errorf(codes.Internal, "could not marshal keystore to JSON file: %v", err)
}
f, err := writer.Create(fmt.Sprintf("keystore-%d.json", i))
if err != nil {
if err := writer.Close(); err != nil {
log.WithError(err).Error("Could not close zip file after writing")
}
return nil, status.Errorf(codes.Internal, "Could not write keystore file to zip: %v", err)
}
if _, err = f.Write(encodedFile); err != nil {
if err := writer.Close(); err != nil {
log.WithError(err).Error("Could not close zip file after writing")
}
return nil, status.Errorf(codes.Internal, "Could not write keystore file contents")
}
}
if err := writer.Close(); err != nil {
log.WithError(err).Error("Could not close zip file after writing")
}
return &pb.BackupAccountsResponse{
ZipFile: buf.Bytes(),
}, nil
}
// VoluntaryExit performs a voluntary exit for the validator keys specified in a request.
// DEPRECATE: Prysm Web UI and associated endpoints will be fully removed in a future hard fork. There is a similar endpoint that is still used /eth/v1alpha1/validator/exit.
func (s *Server) VoluntaryExit(
ctx context.Context, req *pb.VoluntaryExitRequest,
) (*pb.VoluntaryExitResponse, error) {
if s.validatorService == nil {
return nil, status.Error(codes.FailedPrecondition, "Validator service not yet initialized")
}
if len(req.PublicKeys) == 0 {
return nil, status.Error(codes.InvalidArgument, "No public keys specified to delete")
}
if s.wallet == nil {
return nil, status.Error(codes.FailedPrecondition, "No wallet found")
}
km, err := s.validatorService.Keymanager()
if err != nil {
return nil, err
}
formattedKeys := make([]string, len(req.PublicKeys))
for i, key := range req.PublicKeys {
formattedKeys[i] = fmt.Sprintf("%#x", key)
}
cfg := accounts.PerformExitCfg{
ValidatorClient: s.beaconNodeValidatorClient,
NodeClient: s.beaconNodeClient,
Keymanager: km,
RawPubKeys: req.PublicKeys,
FormattedPubKeys: formattedKeys,
}
rawExitedKeys, _, err := accounts.PerformVoluntaryExit(ctx, cfg)
if err != nil {
return nil, status.Errorf(codes.Internal, "Could not perform voluntary exit: %v", err)
}
return &pb.VoluntaryExitResponse{
ExitedKeys: rawExitedKeys,
}, nil
}

View File

@@ -17,36 +17,15 @@ import (
"github.com/pkg/errors"
"github.com/prysmaticlabs/prysm/v4/crypto/rand"
"github.com/prysmaticlabs/prysm/v4/io/file"
pb "github.com/prysmaticlabs/prysm/v4/proto/prysm/v1alpha1/validator-client"
"github.com/prysmaticlabs/prysm/v4/validator/accounts/wallet"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/status"
"google.golang.org/protobuf/types/known/emptypb"
)
const (
authTokenFileName = "auth-token"
AuthTokenFileName = "auth-token"
)
// Initialize returns metadata regarding whether the caller has authenticated and has a wallet.
// DEPRECATED: Prysm Web UI and associated endpoints will be fully removed in a future hard fork. Web APIs won't require JWT in the future.
// Still used by Keymanager API until web ui is fully removed.
func (s *Server) Initialize(_ context.Context, _ *emptypb.Empty) (*pb.InitializeAuthResponse, error) {
walletExists, err := wallet.Exists(s.walletDir)
if err != nil {
return nil, status.Error(codes.Internal, "Could not check if wallet exists")
}
authTokenPath := filepath.Join(s.walletDir, authTokenFileName)
return &pb.InitializeAuthResponse{
HasSignedUp: file.Exists(authTokenPath),
HasWallet: walletExists,
}, nil
}
// CreateAuthToken generates a new jwt key, token and writes them
// to a file in the specified directory. Also, it logs out a prepared URL
// for the user to navigate to and authenticate with the Prysm web interface.
// DEPRECATED: associated to Initialize Web UI API
func CreateAuthToken(walletDirPath, validatorWebAddr string) error {
jwtKey, err := createRandomJWTSecret()
if err != nil {
@@ -56,7 +35,7 @@ func CreateAuthToken(walletDirPath, validatorWebAddr string) error {
if err != nil {
return err
}
authTokenPath := filepath.Join(walletDirPath, authTokenFileName)
authTokenPath := filepath.Join(walletDirPath, AuthTokenFileName)
log.Infof("Generating auth token and saving it to %s", authTokenPath)
if err := saveAuthToken(walletDirPath, jwtKey, token); err != nil {
return err
@@ -70,9 +49,8 @@ func CreateAuthToken(walletDirPath, validatorWebAddr string) error {
// user via stdout and the validator client should then attempt to open the default
// browser. The web interface authenticates by looking for this token in the query parameters
// of the URL. This token is then used as the bearer token for jwt auth.
// DEPRECATED: associated to Initialize Web UI API
func (s *Server) initializeAuthToken(walletDir string) (string, error) {
authTokenFile := filepath.Join(walletDir, authTokenFileName)
authTokenFile := filepath.Join(walletDir, AuthTokenFileName)
if file.Exists(authTokenFile) {
// #nosec G304
f, err := os.Open(authTokenFile)
@@ -106,7 +84,6 @@ func (s *Server) initializeAuthToken(walletDir string) (string, error) {
return token, nil
}
// DEPRECATED: associated to Initialize Web UI API
func (s *Server) refreshAuthTokenFromFileChanges(ctx context.Context, authTokenPath string) {
watcher, err := fsnotify.NewWatcher()
if err != nil {
@@ -142,7 +119,6 @@ func (s *Server) refreshAuthTokenFromFileChanges(ctx context.Context, authTokenP
}
}
// DEPRECATED: associated to Initialize Web UI API
func logValidatorWebAuth(validatorWebAddr, token string, tokenPath string) {
webAuthURLTemplate := "http://%s/initialize?token=%s"
webAuthURL := fmt.Sprintf(
@@ -158,9 +134,8 @@ func logValidatorWebAuth(validatorWebAddr, token string, tokenPath string) {
log.Infof("Validator CLient JWT for RPC and REST authentication set at:%s", tokenPath)
}
// DEPRECATED: associated to Initialize Web UI API
func saveAuthToken(walletDirPath string, jwtKey []byte, token string) error {
hashFilePath := filepath.Join(walletDirPath, authTokenFileName)
hashFilePath := filepath.Join(walletDirPath, AuthTokenFileName)
bytesBuf := new(bytes.Buffer)
if _, err := bytesBuf.Write([]byte(fmt.Sprintf("%x", jwtKey))); err != nil {
return err
@@ -177,7 +152,6 @@ func saveAuthToken(walletDirPath string, jwtKey []byte, token string) error {
return file.WriteFile(hashFilePath, bytesBuf.Bytes())
}
// DEPRECATED: associated to Initialize Web UI API
func readAuthTokenFile(r io.Reader) (secret []byte, token string, err error) {
br := bufio.NewReader(r)
var jwtKeyHex string
@@ -198,7 +172,6 @@ func readAuthTokenFile(r io.Reader) (secret []byte, token string, err error) {
}
// Creates a JWT token string using the JWT key.
// DEPRECATED: associated to Initialize Web UI API
func createTokenString(jwtKey []byte) (string, error) {
token := jwt.NewWithClaims(jwt.SigningMethodHS256, jwt.RegisteredClaims{})
// Sign and get the complete encoded token as a string using the secret

View File

@@ -64,7 +64,7 @@ func TestServer_RefreshJWTSecretOnFileChange(t *testing.T) {
currentSecret := srv.jwtSecret
require.Equal(t, true, len(currentSecret) > 0)
authTokenPath := filepath.Join(walletDir, authTokenFileName)
authTokenPath := filepath.Join(walletDir, AuthTokenFileName)
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
@@ -81,7 +81,7 @@ func TestServer_RefreshJWTSecretOnFileChange(t *testing.T) {
newSecret := srv.jwtSecret
require.Equal(t, true, len(newSecret) > 0)
require.Equal(t, true, !bytes.Equal(currentSecret, newSecret))
err = os.Remove(authTokenFileName)
err = os.Remove(AuthTokenFileName)
require.NoError(t, err)
}

View File

@@ -1,10 +1,6 @@
package rpc
import (
"context"
"time"
"github.com/golang/protobuf/ptypes/empty"
middleware "github.com/grpc-ecosystem/go-grpc-middleware"
grpcretry "github.com/grpc-ecosystem/go-grpc-middleware/retry"
grpcopentracing "github.com/grpc-ecosystem/go-grpc-middleware/tracing/opentracing"
@@ -12,14 +8,12 @@ import (
"github.com/pkg/errors"
grpcutil "github.com/prysmaticlabs/prysm/v4/api/grpc"
ethpb "github.com/prysmaticlabs/prysm/v4/proto/prysm/v1alpha1"
validatorpb "github.com/prysmaticlabs/prysm/v4/proto/prysm/v1alpha1/validator-client"
"github.com/prysmaticlabs/prysm/v4/validator/client"
beaconChainClientFactory "github.com/prysmaticlabs/prysm/v4/validator/client/beacon-chain-client-factory"
nodeClientFactory "github.com/prysmaticlabs/prysm/v4/validator/client/node-client-factory"
validatorClientFactory "github.com/prysmaticlabs/prysm/v4/validator/client/validator-client-factory"
validatorHelpers "github.com/prysmaticlabs/prysm/v4/validator/helpers"
"google.golang.org/grpc"
"google.golang.org/protobuf/types/known/emptypb"
)
// Initialize a client connect to a beacon node gRPC endpoint.
@@ -62,85 +56,3 @@ func (s *Server) registerBeaconClient() error {
s.beaconNodeValidatorClient = validatorClientFactory.NewValidatorClient(conn)
return nil
}
// GetBeaconStatus retrieves information about the beacon node gRPC connection
// and certain chain metadata, such as the genesis time, the chain head, and the
// deposit contract address.
// DEPRECATED: Prysm Web UI and associated endpoints will be fully removed in a future hard fork.
func (s *Server) GetBeaconStatus(ctx context.Context, _ *empty.Empty) (*validatorpb.BeaconStatusResponse, error) {
syncStatus, err := s.beaconNodeClient.GetSyncStatus(ctx, &emptypb.Empty{})
if err != nil {
//nolint:nilerr
return &validatorpb.BeaconStatusResponse{
BeaconNodeEndpoint: s.nodeGatewayEndpoint,
Connected: false,
Syncing: false,
}, nil
}
genesis, err := s.beaconNodeClient.GetGenesis(ctx, &emptypb.Empty{})
if err != nil {
return nil, err
}
genesisTime := uint64(time.Unix(genesis.GenesisTime.Seconds, 0).Unix())
address := genesis.DepositContractAddress
chainHead, err := s.beaconChainClient.GetChainHead(ctx, &emptypb.Empty{})
if err != nil {
return nil, err
}
return &validatorpb.BeaconStatusResponse{
BeaconNodeEndpoint: s.beaconClientEndpoint,
Connected: true,
Syncing: syncStatus.Syncing,
GenesisTime: genesisTime,
DepositContractAddress: address,
ChainHead: chainHead,
}, nil
}
// GetValidatorParticipation is a wrapper around the /eth/v1alpha1 endpoint of the same name.
// DEPRECATED: Prysm Web UI and associated endpoints will be fully removed in a future hard fork.
func (s *Server) GetValidatorParticipation(
ctx context.Context, req *ethpb.GetValidatorParticipationRequest,
) (*ethpb.ValidatorParticipationResponse, error) {
return s.beaconChainClient.GetValidatorParticipation(ctx, req)
}
// GetValidatorPerformance is a wrapper around the /eth/v1alpha1 endpoint of the same name.
// DEPRECATED: Prysm Web UI and associated endpoints will be fully removed in a future hard fork.
func (s *Server) GetValidatorPerformance(
ctx context.Context, req *ethpb.ValidatorPerformanceRequest,
) (*ethpb.ValidatorPerformanceResponse, error) {
return s.beaconChainClient.GetValidatorPerformance(ctx, req)
}
// GetValidatorBalances is a wrapper around the /eth/v1alpha1 endpoint of the same name.
// DEPRECATED: Prysm Web UI and associated endpoints will be fully removed in a future hard fork.
func (s *Server) GetValidatorBalances(
ctx context.Context, req *ethpb.ListValidatorBalancesRequest,
) (*ethpb.ValidatorBalances, error) {
return s.beaconChainClient.ListValidatorBalances(ctx, req)
}
// GetValidators is a wrapper around the /eth/v1alpha1 endpoint of the same name.
// DEPRECATED: Prysm Web UI and associated endpoints will be fully removed in a future hard fork.
func (s *Server) GetValidators(
ctx context.Context, req *ethpb.ListValidatorsRequest,
) (*ethpb.Validators, error) {
return s.beaconChainClient.ListValidators(ctx, req)
}
// GetValidatorQueue is a wrapper around the /eth/v1alpha1 endpoint of the same name.
// DEPRECATED: Prysm Web UI and associated endpoints will be fully removed in a future hard fork.
func (s *Server) GetValidatorQueue(
ctx context.Context, _ *empty.Empty,
) (*ethpb.ValidatorQueue, error) {
return s.beaconChainClient.GetValidatorQueue(ctx, &emptypb.Empty{})
}
// GetPeers is a wrapper around the /eth/v1alpha1 endpoint of the same name.
// DEPRECATED: Prysm Web UI and associated endpoints will be fully removed in a future hard fork.
func (s *Server) GetPeers(
ctx context.Context, _ *empty.Empty,
) (*ethpb.Peers, error) {
return s.beaconNodeClient.ListPeers(ctx, &emptypb.Empty{})
}

View File

@@ -3,83 +3,12 @@ package rpc
import (
"context"
"testing"
"time"
"github.com/golang/mock/gomock"
"github.com/golang/protobuf/ptypes/empty"
"github.com/pkg/errors"
ethpb "github.com/prysmaticlabs/prysm/v4/proto/prysm/v1alpha1"
pb "github.com/prysmaticlabs/prysm/v4/proto/prysm/v1alpha1/validator-client"
"github.com/prysmaticlabs/prysm/v4/testing/assert"
"github.com/prysmaticlabs/prysm/v4/testing/require"
validatormock "github.com/prysmaticlabs/prysm/v4/testing/validator-mock"
"google.golang.org/grpc/metadata"
"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,
}
ctx := context.Background()
resp, err := srv.GetBeaconStatus(ctx, &empty.Empty{})
require.NoError(t, err)
want := &pb.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(&ethpb.SyncStatus{Syncing: true}, nil)
timeStamp := timestamppb.New(time.Unix(0, 0))
nodeClient.EXPECT().GetGenesis(
gomock.Any(), // ctx
gomock.Any(),
).Return(&ethpb.Genesis{
GenesisTime: timeStamp,
DepositContractAddress: []byte("hello"),
}, nil)
beaconChainClient.EXPECT().GetChainHead(
gomock.Any(), // ctx
gomock.Any(),
).Return(&ethpb.ChainHead{
HeadEpoch: 1,
}, nil)
srv := &Server{
beaconNodeClient: nodeClient,
beaconChainClient: beaconChainClient,
}
ctx := context.Background()
resp, err := srv.GetBeaconStatus(ctx, &empty.Empty{})
require.NoError(t, err)
want := &pb.BeaconStatusResponse{
BeaconNodeEndpoint: "",
Connected: true,
Syncing: true,
GenesisTime: uint64(time.Unix(0, 0).Unix()),
DepositContractAddress: []byte("hello"),
ChainHead: &ethpb.ChainHead{
HeadEpoch: 1,
},
}
assert.DeepEqual(t, want, resp)
}
func TestGrpcHeaders(t *testing.T) {
s := &Server{
ctx: context.Background(),

View File

@@ -0,0 +1,274 @@
package rpc
import (
"archive/zip"
"bytes"
"encoding/base64"
"encoding/json"
"fmt"
"io"
"net/http"
"strconv"
"github.com/ethereum/go-ethereum/common/hexutil"
"github.com/pkg/errors"
"github.com/prysmaticlabs/prysm/v4/api/pagination"
"github.com/prysmaticlabs/prysm/v4/beacon-chain/rpc/eth/shared"
"github.com/prysmaticlabs/prysm/v4/cmd"
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/validator/accounts"
"github.com/prysmaticlabs/prysm/v4/validator/accounts/petnames"
"github.com/prysmaticlabs/prysm/v4/validator/keymanager"
"github.com/prysmaticlabs/prysm/v4/validator/keymanager/derived"
"github.com/prysmaticlabs/prysm/v4/validator/keymanager/local"
"go.opencensus.io/trace"
)
// ListAccounts allows retrieval of validating keys and their petnames
// for a user's wallet via RPC.
func (s *Server) ListAccounts(w http.ResponseWriter, r *http.Request) {
ctx, span := trace.StartSpan(r.Context(), "validator.web.accounts.ListAccounts")
defer span.End()
if s.validatorService == nil {
httputil.HandleError(w, "Validator service not ready.", http.StatusServiceUnavailable)
return
}
if !s.walletInitialized {
httputil.HandleError(w, "Prysm Wallet not initialized. Please create a new wallet.", http.StatusServiceUnavailable)
return
}
pageSize := r.URL.Query().Get("page_size")
var ps int64
if pageSize != "" {
psi, err := strconv.ParseInt(pageSize, 10, 32)
if err != nil {
httputil.HandleError(w, errors.Wrap(err, "Failed to parse page_size").Error(), http.StatusBadRequest)
return
}
ps = psi
}
pageToken := r.URL.Query().Get("page_token")
publicKeys := r.URL.Query()["public_keys"]
pubkeys := make([][]byte, len(publicKeys))
for i, key := range publicKeys {
k, ok := shared.ValidateHex(w, fmt.Sprintf("PublicKeys[%d]", i), key, fieldparams.BLSPubkeyLength)
if !ok {
return
}
pubkeys[i] = bytesutil.SafeCopyBytes(k)
}
if int(ps) > cmd.Get().MaxRPCPageSize {
httputil.HandleError(w, fmt.Sprintf("Requested page size %d can not be greater than max size %d",
ps, cmd.Get().MaxRPCPageSize), http.StatusBadRequest)
return
}
km, err := s.validatorService.Keymanager()
if err != nil {
httputil.HandleError(w, err.Error(), http.StatusInternalServerError)
return
}
keys, err := km.FetchValidatingPublicKeys(ctx)
if err != nil {
httputil.HandleError(w, errors.Errorf("Could not retrieve public keys: %v", err).Error(), http.StatusInternalServerError)
return
}
accs := make([]*Account, len(keys))
for i := 0; i < len(keys); i++ {
accs[i] = &Account{
ValidatingPublicKey: hexutil.Encode(keys[i][:]),
AccountName: petnames.DeterministicName(keys[i][:], "-"),
}
if s.wallet.KeymanagerKind() == keymanager.Derived {
accs[i].DerivationPath = fmt.Sprintf(derived.ValidatingKeyDerivationPathTemplate, i)
}
}
if r.URL.Query().Get("all") == "true" {
httputil.WriteJson(w, &ListAccountsResponse{
Accounts: accs,
TotalSize: int32(len(keys)),
NextPageToken: "",
})
return
}
start, end, nextPageToken, err := pagination.StartAndEndPage(pageToken, int(ps), len(keys))
if err != nil {
httputil.HandleError(w, fmt.Errorf("Could not paginate results: %v",
err).Error(), http.StatusInternalServerError)
return
}
httputil.WriteJson(w, &ListAccountsResponse{
Accounts: accs[start:end],
TotalSize: int32(len(keys)),
NextPageToken: nextPageToken,
})
}
// BackupAccounts creates a zip file containing EIP-2335 keystores for the user's
// specified public keys by encrypting them with the specified password.
func (s *Server) BackupAccounts(w http.ResponseWriter, r *http.Request) {
ctx, span := trace.StartSpan(r.Context(), "validator.web.accounts.ListAccounts")
defer span.End()
if s.validatorService == nil {
httputil.HandleError(w, "Validator service not ready.", http.StatusServiceUnavailable)
return
}
if !s.walletInitialized {
httputil.HandleError(w, "Prysm Wallet not initialized. Please create a new wallet.", http.StatusServiceUnavailable)
return
}
var req BackupAccountsRequest
err := json.NewDecoder(r.Body).Decode(&req)
switch {
case err == io.EOF:
httputil.HandleError(w, "No data submitted", http.StatusBadRequest)
return
case err != nil:
httputil.HandleError(w, "Could not decode request body: "+err.Error(), http.StatusBadRequest)
return
}
if req.PublicKeys == nil || len(req.PublicKeys) < 1 {
httputil.HandleError(w, "No public keys specified to backup", http.StatusBadRequest)
return
}
if req.BackupPassword == "" {
httputil.HandleError(w, "Backup password cannot be empty", http.StatusBadRequest)
return
}
km, err := s.validatorService.Keymanager()
if err != nil {
httputil.HandleError(w, err.Error(), http.StatusInternalServerError)
return
}
pubKeys := make([]bls.PublicKey, len(req.PublicKeys))
for i, key := range req.PublicKeys {
byteskey, ok := shared.ValidateHex(w, "pubkey", key, fieldparams.BLSPubkeyLength)
if !ok {
return
}
pubKey, err := bls.PublicKeyFromBytes(byteskey)
if err != nil {
httputil.HandleError(w, errors.Wrap(err, fmt.Sprintf("%s Not a valid BLS public key", key)).Error(), http.StatusBadRequest)
return
}
pubKeys[i] = pubKey
}
var keystoresToBackup []*keymanager.Keystore
switch km := km.(type) {
case *local.Keymanager:
keystoresToBackup, err = km.ExtractKeystores(ctx, pubKeys, req.BackupPassword)
if err != nil {
httputil.HandleError(w, errors.Wrap(err, "Could not backup accounts for local keymanager").Error(), http.StatusInternalServerError)
return
}
case *derived.Keymanager:
keystoresToBackup, err = km.ExtractKeystores(ctx, pubKeys, req.BackupPassword)
if err != nil {
httputil.HandleError(w, errors.Wrap(err, "Could not backup accounts for derived keymanager").Error(), http.StatusInternalServerError)
return
}
default:
httputil.HandleError(w, "Only HD or IMPORTED wallets can backup accounts", http.StatusBadRequest)
return
}
if len(keystoresToBackup) == 0 {
httputil.HandleError(w, "No keystores to backup", http.StatusBadRequest)
return
}
buf := new(bytes.Buffer)
writer := zip.NewWriter(buf)
for i, k := range keystoresToBackup {
encodedFile, err := json.MarshalIndent(k, "", "\t")
if err != nil {
if err := writer.Close(); err != nil {
log.WithError(err).Error("Could not close zip file after writing")
}
httputil.HandleError(w, "could not marshal keystore to JSON file", http.StatusInternalServerError)
return
}
f, err := writer.Create(fmt.Sprintf("keystore-%d.json", i))
if err != nil {
if err := writer.Close(); err != nil {
log.WithError(err).Error("Could not close zip file after writing")
}
httputil.HandleError(w, "Could not write keystore file to zip", http.StatusInternalServerError)
return
}
if _, err = f.Write(encodedFile); err != nil {
if err := writer.Close(); err != nil {
log.WithError(err).Error("Could not close zip file after writing")
}
httputil.HandleError(w, "Could not write keystore file contents", http.StatusBadRequest)
return
}
}
if err := writer.Close(); err != nil {
log.WithError(err).Error("Could not close zip file after writing")
}
httputil.WriteJson(w, &BackupAccountsResponse{
ZipFile: base64.StdEncoding.EncodeToString(buf.Bytes()), // convert to base64 string for processing
})
}
// VoluntaryExit performs a voluntary exit for the validator keys specified in a request.
func (s *Server) VoluntaryExit(w http.ResponseWriter, r *http.Request) {
ctx, span := trace.StartSpan(r.Context(), "validator.web.accounts.VoluntaryExit")
defer span.End()
if s.validatorService == nil {
httputil.HandleError(w, "Validator service not ready.", http.StatusServiceUnavailable)
return
}
if !s.walletInitialized {
httputil.HandleError(w, "Prysm Wallet not initialized. Please create a new wallet.", http.StatusServiceUnavailable)
return
}
var req VoluntaryExitRequest
err := json.NewDecoder(r.Body).Decode(&req)
switch {
case err == io.EOF:
httputil.HandleError(w, "No data submitted", http.StatusBadRequest)
return
case err != nil:
httputil.HandleError(w, "Could not decode request body: "+err.Error(), http.StatusBadRequest)
return
}
if len(req.PublicKeys) == 0 {
httputil.HandleError(w, "No public keys specified to delete", http.StatusBadRequest)
return
}
km, err := s.validatorService.Keymanager()
if err != nil {
httputil.HandleError(w, err.Error(), http.StatusInternalServerError)
return
}
pubKeys := make([][]byte, len(req.PublicKeys))
for i, key := range req.PublicKeys {
byteskey, ok := shared.ValidateHex(w, "pubkey", key, fieldparams.BLSPubkeyLength)
if !ok {
return
}
pubKeys[i] = byteskey
}
cfg := accounts.PerformExitCfg{
ValidatorClient: s.beaconNodeValidatorClient,
NodeClient: s.beaconNodeClient,
Keymanager: km,
RawPubKeys: pubKeys,
FormattedPubKeys: req.PublicKeys,
}
rawExitedKeys, _, err := accounts.PerformVoluntaryExit(ctx, cfg)
if err != nil {
httputil.HandleError(w, errors.Wrap(err, "Could not perform voluntary exit").Error(), http.StatusInternalServerError)
return
}
httputil.WriteJson(w, &VoluntaryExitResponse{
ExitedKeys: rawExitedKeys,
})
}

View File

@@ -4,17 +4,21 @@ import (
"archive/zip"
"bytes"
"context"
"encoding/base64"
"encoding/json"
"fmt"
"io"
"net/http"
"net/http/httptest"
"path/filepath"
"testing"
"time"
"github.com/ethereum/go-ethereum/common/hexutil"
"github.com/golang/mock/gomock"
"github.com/prysmaticlabs/prysm/v4/api"
"github.com/prysmaticlabs/prysm/v4/cmd/validator/flags"
ethpb "github.com/prysmaticlabs/prysm/v4/proto/prysm/v1alpha1"
pb "github.com/prysmaticlabs/prysm/v4/proto/prysm/v1alpha1/validator-client"
"github.com/prysmaticlabs/prysm/v4/testing/assert"
"github.com/prysmaticlabs/prysm/v4/testing/require"
validatormock "github.com/prysmaticlabs/prysm/v4/testing/validator-mock"
@@ -66,42 +70,74 @@ func TestServer_ListAccounts(t *testing.T) {
require.Equal(t, true, ok)
err = dr.RecoverAccountsFromMnemonic(ctx, constant.TestMnemonic, derived.DefaultMnemonicLanguage, "", numAccounts)
require.NoError(t, err)
resp, err := s.ListAccounts(ctx, &pb.ListAccountsRequest{
PageSize: int32(numAccounts),
})
require.NoError(t, err)
req := httptest.NewRequest(http.MethodGet, fmt.Sprintf(api.WebUrlPrefix+"accounts?page_size=%d", int32(numAccounts)), nil)
wr := httptest.NewRecorder()
wr.Body = &bytes.Buffer{}
s.ListAccounts(wr, req)
require.Equal(t, http.StatusOK, wr.Code)
resp := &ListAccountsResponse{}
require.NoError(t, json.Unmarshal(wr.Body.Bytes(), resp))
require.Equal(t, len(resp.Accounts), numAccounts)
tests := []struct {
req *pb.ListAccountsRequest
res *pb.ListAccountsResponse
PageSize int
PageToken string
All bool
res *ListAccountsResponse
}{
{
req: &pb.ListAccountsRequest{
PageSize: 5,
},
res: &pb.ListAccountsResponse{
PageSize: 5,
res: &ListAccountsResponse{
Accounts: resp.Accounts[0:5],
NextPageToken: "1",
TotalSize: int32(numAccounts),
},
},
{
req: &pb.ListAccountsRequest{
PageSize: 5,
PageToken: "1",
},
res: &pb.ListAccountsResponse{
PageSize: 5,
PageToken: "1",
res: &ListAccountsResponse{
Accounts: resp.Accounts[5:10],
NextPageToken: "2",
TotalSize: int32(numAccounts),
},
},
{
All: true,
res: &ListAccountsResponse{
Accounts: resp.Accounts,
NextPageToken: "",
TotalSize: int32(numAccounts),
},
},
}
for _, test := range tests {
res, err := s.ListAccounts(context.Background(), test.req)
require.NoError(t, err)
assert.DeepEqual(t, res, test.res)
url := api.WebUrlPrefix + "accounts"
if test.PageSize != 0 || test.PageToken != "" || test.All {
url = url + "?"
}
if test.All {
url = url + "all=true"
} else {
if test.PageSize != 0 {
url = url + fmt.Sprintf("page_size=%d", test.PageSize)
}
if test.PageToken != "" {
url = url + fmt.Sprintf("&page_token=%s", test.PageToken)
}
}
req = httptest.NewRequest(http.MethodGet, url, nil)
wr = httptest.NewRecorder()
wr.Body = &bytes.Buffer{}
s.ListAccounts(wr, req)
require.Equal(t, http.StatusOK, wr.Code)
resp = &ListAccountsResponse{}
require.NoError(t, json.Unmarshal(wr.Body.Bytes(), resp))
assert.DeepEqual(t, resp, test.res)
}
}
@@ -139,32 +175,45 @@ func TestServer_BackupAccounts(t *testing.T) {
require.Equal(t, true, ok)
err = dr.RecoverAccountsFromMnemonic(ctx, constant.TestMnemonic, derived.DefaultMnemonicLanguage, "", numAccounts)
require.NoError(t, err)
resp, err := s.ListAccounts(ctx, &pb.ListAccountsRequest{
PageSize: int32(numAccounts),
})
require.NoError(t, err)
req := httptest.NewRequest(http.MethodGet, fmt.Sprintf("/v2/validator/accounts?page_size=%d", int32(numAccounts)), nil)
wr := httptest.NewRecorder()
wr.Body = &bytes.Buffer{}
s.ListAccounts(wr, req)
require.Equal(t, http.StatusOK, wr.Code)
resp := &ListAccountsResponse{}
require.NoError(t, json.Unmarshal(wr.Body.Bytes(), resp))
require.Equal(t, len(resp.Accounts), numAccounts)
pubKeys := make([][]byte, numAccounts)
pubKeys := make([]string, numAccounts)
for i, aa := range resp.Accounts {
pubKeys[i] = aa.ValidatingPublicKey
}
// We now attempt to backup all public keys from the wallet.
res, err := s.BackupAccounts(context.Background(), &pb.BackupAccountsRequest{
request := &BackupAccountsRequest{
PublicKeys: pubKeys,
BackupPassword: s.wallet.Password(),
})
}
var buf bytes.Buffer
err = json.NewEncoder(&buf).Encode(request)
require.NoError(t, err)
req = httptest.NewRequest(http.MethodPost, api.WebUrlPrefix+"accounts/backup", &buf)
wr = httptest.NewRecorder()
wr.Body = &bytes.Buffer{}
// We now attempt to backup all public keys from the wallet.
s.BackupAccounts(wr, req)
require.Equal(t, http.StatusOK, wr.Code)
res := &BackupAccountsResponse{}
require.NoError(t, json.Unmarshal(wr.Body.Bytes(), res))
// decode the base64 string
decodedBytes, err := base64.StdEncoding.DecodeString(res.ZipFile)
require.NoError(t, err)
require.NotNil(t, res.ZipFile)
// Open a zip archive for reading.
buf := bytes.NewReader(res.ZipFile)
r, err := zip.NewReader(buf, int64(len(res.ZipFile)))
bu := bytes.NewReader(decodedBytes)
r, err := zip.NewReader(bu, int64(len(decodedBytes)))
require.NoError(t, err)
require.Equal(t, len(pubKeys), len(r.File))
// Iterate through the files in the archive, checking they
// match the keystores we wanted to backup.
// match the keystores we wanted to back up.
for i, f := range r.File {
keystoreFile, err := f.Open()
require.NoError(t, err)
@@ -178,7 +227,7 @@ func TestServer_BackupAccounts(t *testing.T) {
require.NoError(t, keystoreFile.Close())
t.Fatal(err)
}
assert.Equal(t, keystore.Pubkey, fmt.Sprintf("%x", pubKeys[i]))
assert.Equal(t, "0x"+keystore.Pubkey, pubKeys[i])
require.NoError(t, keystoreFile.Close())
}
}
@@ -255,13 +304,25 @@ func TestServer_VoluntaryExit(t *testing.T) {
pubKeys, err := dr.FetchValidatingPublicKeys(ctx)
require.NoError(t, err)
rawPubKeys := make([][]byte, len(pubKeys))
rawPubKeys := make([]string, len(pubKeys))
for i, key := range pubKeys {
rawPubKeys[i] = key[:]
rawPubKeys[i] = hexutil.Encode(key[:])
}
res, err := s.VoluntaryExit(ctx, &pb.VoluntaryExitRequest{
request := &VoluntaryExitRequest{
PublicKeys: rawPubKeys,
})
}
var buf bytes.Buffer
err = json.NewEncoder(&buf).Encode(request)
require.NoError(t, err)
require.DeepEqual(t, rawPubKeys, res.ExitedKeys)
req := httptest.NewRequest(http.MethodPost, api.WebUrlPrefix+"accounts/voluntary-exit", &buf)
wr := httptest.NewRecorder()
wr.Body = &bytes.Buffer{}
s.VoluntaryExit(wr, req)
require.Equal(t, http.StatusOK, wr.Code)
res := &VoluntaryExitResponse{}
require.NoError(t, json.Unmarshal(wr.Body.Bytes(), res))
for i := range res.ExitedKeys {
require.Equal(t, rawPubKeys[i], hexutil.Encode(res.ExitedKeys[i]))
}
}

View File

@@ -0,0 +1,28 @@
package rpc
import (
"net/http"
"path/filepath"
"github.com/pkg/errors"
"github.com/prysmaticlabs/prysm/v4/io/file"
httputil "github.com/prysmaticlabs/prysm/v4/network/http"
"github.com/prysmaticlabs/prysm/v4/validator/accounts/wallet"
"go.opencensus.io/trace"
)
// Initialize returns metadata regarding whether the caller has authenticated and has a wallet.
func (s *Server) Initialize(w http.ResponseWriter, r *http.Request) {
_, span := trace.StartSpan(r.Context(), "validator.web.Initialize")
defer span.End()
walletExists, err := wallet.Exists(s.walletDir)
if err != nil {
httputil.HandleError(w, errors.Wrap(err, "Could not check if wallet exists").Error(), http.StatusInternalServerError)
return
}
authTokenPath := filepath.Join(s.walletDir, AuthTokenFileName)
httputil.WriteJson(w, &InitializeAuthResponse{
HasSignedUp: file.Exists(authTokenPath),
HasWallet: walletExists,
})
}

View File

@@ -0,0 +1,60 @@
package rpc
import (
"context"
"encoding/json"
"net/http"
"net/http/httptest"
"os"
"path/filepath"
"testing"
"github.com/prysmaticlabs/prysm/v4/testing/require"
"github.com/prysmaticlabs/prysm/v4/validator/accounts"
"github.com/prysmaticlabs/prysm/v4/validator/keymanager"
)
func TestInitialize(t *testing.T) {
// Step 1: Create a temporary directory
localWalletDir := setupWalletDir(t)
// Step 2: Optionally create a temporary 'auth-token' file
authTokenPath := filepath.Join(localWalletDir, AuthTokenFileName)
_, err := os.Create(authTokenPath)
require.NoError(t, err)
// Create an instance of the Server with the temporary directory
opts := []accounts.Option{
accounts.WithWalletDir(localWalletDir),
accounts.WithKeymanagerType(keymanager.Derived),
accounts.WithWalletPassword(strongPass),
accounts.WithSkipMnemonicConfirm(true),
}
acc, err := accounts.NewCLIManager(opts...)
require.NoError(t, err)
_, err = acc.WalletCreate(context.Background())
require.NoError(t, err)
server := &Server{walletDir: localWalletDir}
// Step 4: Create an HTTP request and response recorder
req := httptest.NewRequest(http.MethodGet, "/initialize", nil)
w := httptest.NewRecorder()
// Step 5: Call the Initialize function
server.Initialize(w, req)
// Step 6: Assert expectations
result := w.Result()
defer func() {
err := result.Body.Close()
require.NoError(t, err)
}()
var response InitializeAuthResponse
err = json.NewDecoder(result.Body).Decode(&response)
require.NoError(t, err)
// Assert the expected response
require.Equal(t, true, response.HasSignedUp)
require.Equal(t, true, response.HasWallet)
}

View File

@@ -0,0 +1,208 @@
package rpc
import (
"encoding/base64"
"fmt"
"net/http"
"strconv"
"strings"
"time"
"github.com/ethereum/go-ethereum/common/hexutil"
"github.com/pkg/errors"
"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"
ethpb "github.com/prysmaticlabs/prysm/v4/proto/prysm/v1alpha1"
"go.opencensus.io/trace"
"google.golang.org/protobuf/types/known/emptypb"
)
// GetBeaconStatus retrieves information about the beacon node gRPC connection
// and certain chain metadata, such as the genesis time, the chain head, and the
// deposit contract address.
func (s *Server) GetBeaconStatus(w http.ResponseWriter, r *http.Request) {
ctx, span := trace.StartSpan(r.Context(), "validator.web.beacon.GetBeaconStatus")
defer span.End()
syncStatus, err := s.beaconNodeClient.GetSyncStatus(ctx, &emptypb.Empty{})
if err != nil {
log.WithError(err).Error("beacon node call to get sync status failed")
httputil.WriteJson(w, &BeaconStatusResponse{
BeaconNodeEndpoint: s.nodeGatewayEndpoint,
Connected: false,
Syncing: false,
})
return
}
genesis, err := s.beaconNodeClient.GetGenesis(ctx, &emptypb.Empty{})
if err != nil {
httputil.HandleError(w, errors.Wrap(err, "GetGenesis call failed").Error(), http.StatusInternalServerError)
return
}
genesisTime := uint64(time.Unix(genesis.GenesisTime.Seconds, 0).Unix())
address := genesis.DepositContractAddress
chainHead, err := s.beaconChainClient.GetChainHead(ctx, &emptypb.Empty{})
if err != nil {
httputil.HandleError(w, errors.Wrap(err, "GetChainHead").Error(), http.StatusInternalServerError)
return
}
httputil.WriteJson(w, &BeaconStatusResponse{
BeaconNodeEndpoint: s.beaconClientEndpoint,
Connected: true,
Syncing: syncStatus.Syncing,
GenesisTime: fmt.Sprintf("%d", genesisTime),
DepositContractAddress: hexutil.Encode(address),
ChainHead: shared.ChainHeadResponseFromConsensus(chainHead),
})
}
// GetValidatorPerformance is a wrapper around the /eth/v1alpha1 endpoint of the same name.
func (s *Server) GetValidatorPerformance(w http.ResponseWriter, r *http.Request) {
ctx, span := trace.StartSpan(r.Context(), "validator.web.beacon.GetValidatorPerformance")
defer span.End()
publicKeys := r.URL.Query()["public_keys"]
pubkeys := make([][]byte, len(publicKeys))
for i, key := range publicKeys {
var pk []byte
if strings.HasPrefix(key, "0x") {
k, ok := shared.ValidateHex(w, fmt.Sprintf("PublicKeys[%d]", i), key, fieldparams.BLSPubkeyLength)
if !ok {
return
}
pk = bytesutil.SafeCopyBytes(k)
} else {
data, err := base64.StdEncoding.DecodeString(key)
if err != nil {
httputil.HandleError(w, errors.Wrap(err, "Failed to decode base64").Error(), http.StatusBadRequest)
return
}
pk = bytesutil.SafeCopyBytes(data)
}
pubkeys[i] = pk
}
req := &ethpb.ValidatorPerformanceRequest{
PublicKeys: pubkeys,
}
validatorPerformance, err := s.beaconChainClient.GetValidatorPerformance(ctx, req)
if err != nil {
httputil.HandleError(w, errors.Wrap(err, "GetValidatorPerformance call failed").Error(), http.StatusInternalServerError)
return
}
httputil.WriteJson(w, shared.ValidatorPerformanceResponseFromConsensus(validatorPerformance))
}
// GetValidatorBalances is a wrapper around the /eth/v1alpha1 endpoint of the same name.
func (s *Server) GetValidatorBalances(w http.ResponseWriter, r *http.Request) {
ctx, span := trace.StartSpan(r.Context(), "validator.web.beacon.GetValidatorBalances")
defer span.End()
pageSize := r.URL.Query().Get("page_size")
var ps int64
if pageSize != "" {
psi, err := strconv.ParseInt(pageSize, 10, 32)
if err != nil {
httputil.HandleError(w, errors.Wrap(err, "Failed to parse page_size").Error(), http.StatusBadRequest)
return
}
ps = psi
}
pageToken := r.URL.Query().Get("page_token")
publicKeys := r.URL.Query()["public_keys"]
pubkeys := make([][]byte, len(publicKeys))
for i, key := range publicKeys {
var pk []byte
if strings.HasPrefix(key, "0x") {
k, ok := shared.ValidateHex(w, fmt.Sprintf("PublicKeys[%d]", i), key, fieldparams.BLSPubkeyLength)
if !ok {
return
}
pk = bytesutil.SafeCopyBytes(k)
} else {
data, err := base64.StdEncoding.DecodeString(key)
if err != nil {
httputil.HandleError(w, errors.Wrap(err, "Failed to decode base64").Error(), http.StatusBadRequest)
return
}
pk = bytesutil.SafeCopyBytes(data)
}
pubkeys[i] = pk
}
req := &ethpb.ListValidatorBalancesRequest{
PublicKeys: pubkeys,
PageSize: int32(ps),
PageToken: pageToken,
}
listValidatorBalances, err := s.beaconChainClient.ListValidatorBalances(ctx, req)
if err != nil {
httputil.HandleError(w, errors.Wrap(err, "ListValidatorBalances call failed").Error(), http.StatusInternalServerError)
return
}
response, err := shared.ValidatorBalancesResponseFromConsensus(listValidatorBalances)
if err != nil {
httputil.HandleError(w, errors.Wrap(err, "Failed to convert to json").Error(), http.StatusInternalServerError)
return
}
httputil.WriteJson(w, response)
}
// GetValidators is a wrapper around the /eth/v1alpha1 endpoint of the same name.
func (s *Server) GetValidators(w http.ResponseWriter, r *http.Request) {
ctx, span := trace.StartSpan(r.Context(), "validator.web.beacon.GetValidators")
defer span.End()
pageSize := r.URL.Query().Get("page_size")
ps, err := strconv.ParseInt(pageSize, 10, 32)
if err != nil {
httputil.HandleError(w, errors.Wrap(err, "Failed to parse page_size").Error(), http.StatusBadRequest)
return
}
pageToken := r.URL.Query().Get("page_token")
publicKeys := r.URL.Query()["public_keys"]
pubkeys := make([][]byte, len(publicKeys))
for i, key := range publicKeys {
var pk []byte
if strings.HasPrefix(key, "0x") {
k, ok := shared.ValidateHex(w, fmt.Sprintf("PublicKeys[%d]", i), key, fieldparams.BLSPubkeyLength)
if !ok {
return
}
pk = bytesutil.SafeCopyBytes(k)
} else {
data, err := base64.StdEncoding.DecodeString(key)
if err != nil {
httputil.HandleError(w, errors.Wrap(err, "Failed to decode base64").Error(), http.StatusBadRequest)
return
}
pk = bytesutil.SafeCopyBytes(data)
}
pubkeys[i] = pk
}
req := &ethpb.ListValidatorsRequest{
PublicKeys: pubkeys,
PageSize: int32(ps),
PageToken: pageToken,
}
validators, err := s.beaconChainClient.ListValidators(ctx, req)
if err != nil {
httputil.HandleError(w, errors.Wrap(err, "ListValidators call failed").Error(), http.StatusInternalServerError)
return
}
response, err := shared.ValidatorsResponseFromConsensus(validators)
if err != nil {
httputil.HandleError(w, errors.Wrap(err, "Failed to convert to json").Error(), http.StatusInternalServerError)
return
}
httputil.WriteJson(w, response)
}
// GetPeers is a wrapper around the /eth/v1alpha1 endpoint of the same name.
func (s *Server) GetPeers(w http.ResponseWriter, r *http.Request) {
ctx, span := trace.StartSpan(r.Context(), "validator.web.beacon.GetPeers")
defer span.End()
peers, err := s.beaconNodeClient.ListPeers(ctx, &emptypb.Empty{})
if err != nil {
httputil.HandleError(w, errors.Wrap(err, "ListPeers call failed").Error(), http.StatusInternalServerError)
return
}
httputil.WriteJson(w, peers)
}

View File

@@ -0,0 +1,105 @@
package rpc
import (
"bytes"
"encoding/json"
"fmt"
"net/http"
"net/http/httptest"
"testing"
"time"
"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"
validatormock "github.com/prysmaticlabs/prysm/v4/testing/validator-mock"
"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(&ethpb.SyncStatus{Syncing: true}, nil)
timeStamp := timestamppb.New(time.Unix(0, 0))
nodeClient.EXPECT().GetGenesis(
gomock.Any(), // ctx
gomock.Any(),
).Return(&ethpb.Genesis{
GenesisTime: timeStamp,
DepositContractAddress: []byte("hello"),
}, nil)
beaconChainClient.EXPECT().GetChainHead(
gomock.Any(), // ctx
gomock.Any(),
).Return(&ethpb.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: &shared.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)
}

View File

@@ -5,6 +5,7 @@ import (
"context"
"encoding/json"
"fmt"
"io"
"net/http"
"github.com/ethereum/go-ethereum/common"
@@ -90,7 +91,12 @@ func (s *Server) ImportKeystores(w http.ResponseWriter, r *http.Request) {
}
var req ImportKeystoresRequest
if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
err = json.NewDecoder(r.Body).Decode(&req)
switch {
case err == io.EOF:
httputil.HandleError(w, "No data submitted", http.StatusBadRequest)
return
case err != nil:
httputil.HandleError(w, "Could not decode request body: "+err.Error(), http.StatusBadRequest)
return
}
@@ -182,10 +188,16 @@ func (s *Server) DeleteKeystores(w http.ResponseWriter, r *http.Request) {
return
}
var req DeleteKeystoresRequest
if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
err = json.NewDecoder(r.Body).Decode(&req)
switch {
case err == io.EOF:
httputil.HandleError(w, "No data submitted", http.StatusBadRequest)
return
case err != nil:
httputil.HandleError(w, "Could not decode request body: "+err.Error(), http.StatusBadRequest)
return
}
if len(req.Pubkeys) == 0 {
httputil.WriteJson(w, &DeleteKeystoresResponse{Data: make([]*keymanager.KeyStatus, 0)})
return
@@ -447,10 +459,16 @@ func (s *Server) ImportRemoteKeys(w http.ResponseWriter, r *http.Request) {
}
var req ImportRemoteKeysRequest
if err = json.NewDecoder(r.Body).Decode(&req); err != nil {
err = json.NewDecoder(r.Body).Decode(&req)
switch {
case err == io.EOF:
httputil.HandleError(w, "No data submitted", http.StatusBadRequest)
return
case err != nil:
httputil.HandleError(w, "Could not decode request body: "+err.Error(), http.StatusBadRequest)
return
}
adder, ok := km.(keymanager.PublicKeyAdder)
if !ok {
statuses := make([]*keymanager.KeyStatus, len(req.RemoteKeys))
@@ -501,8 +519,14 @@ func (s *Server) DeleteRemoteKeys(w http.ResponseWriter, r *http.Request) {
httputil.HandleError(w, "Prysm Wallet is not of type Web3Signer. Please execute validator client with web3signer flags.", http.StatusInternalServerError)
return
}
var req DeleteRemoteKeysRequest
if err = json.NewDecoder(r.Body).Decode(&req); err != nil {
err = json.NewDecoder(r.Body).Decode(&req)
switch {
case err == io.EOF:
httputil.HandleError(w, "No data submitted", http.StatusBadRequest)
return
case err != nil:
httputil.HandleError(w, "Could not decode request body: "+err.Error(), http.StatusBadRequest)
return
}
@@ -592,11 +616,18 @@ func (s *Server) SetFeeRecipientByPubkey(w http.ResponseWriter, r *http.Request)
if !valid {
return
}
var req SetFeeRecipientByPubkeyRequest
if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
err := json.NewDecoder(r.Body).Decode(&req)
switch {
case err == io.EOF:
httputil.HandleError(w, "No data submitted", http.StatusBadRequest)
return
case err != nil:
httputil.HandleError(w, "Could not decode request body: "+err.Error(), http.StatusBadRequest)
return
}
ethAddress, valid := shared.ValidateHex(w, "Ethereum Address", req.Ethaddress, fieldparams.FeeRecipientLength)
if !valid {
return
@@ -757,7 +788,12 @@ func (s *Server) SetGasLimit(w http.ResponseWriter, r *http.Request) {
}
var req SetGasLimitRequest
if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
err := json.NewDecoder(r.Body).Decode(&req)
switch {
case err == io.EOF:
httputil.HandleError(w, "No data submitted", http.StatusBadRequest)
return
case err != nil:
httputil.HandleError(w, "Could not decode request body: "+err.Error(), http.StatusBadRequest)
return
}

View File

@@ -3,9 +3,11 @@ package rpc
import (
"context"
"fmt"
"net/http"
"strings"
"github.com/golang-jwt/jwt/v4"
"github.com/prysmaticlabs/prysm/v4/api"
"github.com/sirupsen/logrus"
"google.golang.org/grpc"
"google.golang.org/grpc/codes"
@@ -33,6 +35,29 @@ func (s *Server) JWTInterceptor() grpc.UnaryServerInterceptor {
}
}
// JwtHttpInterceptor is an HTTP handler to authorize a route.
func (s *Server) JwtHttpInterceptor(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
// if it's not initialize or has a web prefix
if !strings.Contains(r.URL.Path, api.WebUrlPrefix+"initialize") && // ignore some routes
!strings.Contains(r.URL.Path, api.WebUrlPrefix+"health/logs") &&
strings.Contains(r.URL.Path, api.WebUrlPrefix) {
reqToken := r.Header.Get("Authorization")
if reqToken == "" {
http.Error(w, "unauthorized: no Authorization header passed. Please use an Authorization header with the jwt created in the prysm wallet", http.StatusUnauthorized)
return
}
token := strings.Split(reqToken, "Bearer ")[1]
_, err := jwt.Parse(token, s.validateJWT)
if err != nil {
http.Error(w, fmt.Errorf("unauthorized:could not parse JWT token: %v", err).Error(), http.StatusUnauthorized)
return
}
}
next.ServeHTTP(w, r)
})
}
// Authorize the token received is valid.
func (s *Server) authorize(ctx context.Context) error {
md, ok := metadata.FromIncomingContext(ctx)

View File

@@ -14,11 +14,11 @@ import (
grpcopentracing "github.com/grpc-ecosystem/go-grpc-middleware/tracing/opentracing"
grpcprometheus "github.com/grpc-ecosystem/go-grpc-prometheus"
"github.com/pkg/errors"
"github.com/prysmaticlabs/prysm/v4/api"
"github.com/prysmaticlabs/prysm/v4/async/event"
"github.com/prysmaticlabs/prysm/v4/io/logs"
"github.com/prysmaticlabs/prysm/v4/monitoring/tracing"
ethpb "github.com/prysmaticlabs/prysm/v4/proto/prysm/v1alpha1"
validatorpb "github.com/prysmaticlabs/prysm/v4/proto/prysm/v1alpha1/validator-client"
"github.com/prysmaticlabs/prysm/v4/validator/accounts/wallet"
"github.com/prysmaticlabs/prysm/v4/validator/client"
iface "github.com/prysmaticlabs/prysm/v4/validator/client/iface"
@@ -183,9 +183,6 @@ func (s *Server) Start() {
// Register services available for the gRPC server.
reflection.Register(s.grpcServer)
validatorpb.RegisterAuthServer(s.grpcServer, s)
validatorpb.RegisterBeaconServer(s.grpcServer, s)
validatorpb.RegisterAccountsServer(s.grpcServer, s)
// routes needs to be set before the server calls the server function
go func() {
@@ -204,7 +201,7 @@ func (s *Server) Start() {
return
}
validatorWebAddr := fmt.Sprintf("%s:%d", s.validatorGatewayHost, s.validatorGatewayPort)
authTokenPath := filepath.Join(s.walletDir, authTokenFileName)
authTokenPath := filepath.Join(s.walletDir, AuthTokenFileName)
logValidatorWebAuth(validatorWebAddr, token, authTokenPath)
go s.refreshAuthTokenFromFileChanges(s.ctx, authTokenPath)
}
@@ -216,6 +213,8 @@ func (s *Server) InitializeRoutes() error {
if s.router == nil {
return errors.New("no router found on server")
}
// Adding Auth Interceptor for the routes below
s.router.Use(s.JwtHttpInterceptor)
// Register all services, HandleFunc calls, etc.
// ...
s.router.HandleFunc("/eth/v1/keystores", s.ListKeystores).Methods(http.MethodGet)
@@ -231,18 +230,30 @@ func (s *Server) InitializeRoutes() error {
s.router.HandleFunc("/eth/v1/validator/{pubkey}/feerecipient", s.SetFeeRecipientByPubkey).Methods(http.MethodPost)
s.router.HandleFunc("/eth/v1/validator/{pubkey}/feerecipient", s.DeleteFeeRecipientByPubkey).Methods(http.MethodDelete)
s.router.HandleFunc("/eth/v1/validator/{pubkey}/voluntary_exit", s.SetVoluntaryExit).Methods(http.MethodPost)
// auth endpoint
s.router.HandleFunc(api.WebUrlPrefix+"initialize", s.Initialize).Methods(http.MethodGet)
// accounts endpoints
s.router.HandleFunc(api.WebUrlPrefix+"accounts", s.ListAccounts).Methods(http.MethodGet)
s.router.HandleFunc(api.WebUrlPrefix+"accounts/backup", s.BackupAccounts).Methods(http.MethodPost)
s.router.HandleFunc(api.WebUrlPrefix+"accounts/voluntary-exit", s.VoluntaryExit).Methods(http.MethodPost)
// web health endpoints
s.router.HandleFunc("/v2/validator/health/version", s.GetVersion).Methods(http.MethodGet)
s.router.HandleFunc("/v2/validator/health/logs/validator/stream", s.StreamValidatorLogs).Methods(http.MethodGet)
s.router.HandleFunc("/v2/validator/health/logs/beacon/stream", s.StreamBeaconLogs).Methods(http.MethodGet)
s.router.HandleFunc(api.WebUrlPrefix+"health/version", s.GetVersion).Methods(http.MethodGet)
s.router.HandleFunc(api.WebUrlPrefix+"health/logs/validator/stream", s.StreamValidatorLogs).Methods(http.MethodGet)
s.router.HandleFunc(api.WebUrlPrefix+"health/logs/beacon/stream", s.StreamBeaconLogs).Methods(http.MethodGet)
// Beacon calls
s.router.HandleFunc(api.WebUrlPrefix+"beacon/status", s.GetBeaconStatus).Methods(http.MethodGet)
s.router.HandleFunc(api.WebUrlPrefix+"beacon/summary", s.GetValidatorPerformance).Methods(http.MethodGet)
s.router.HandleFunc(api.WebUrlPrefix+"beacon/validators", s.GetValidators).Methods(http.MethodGet)
s.router.HandleFunc(api.WebUrlPrefix+"beacon/balances", s.GetValidatorBalances).Methods(http.MethodGet)
s.router.HandleFunc(api.WebUrlPrefix+"beacon/peers", s.GetPeers).Methods(http.MethodGet)
// web wallet endpoints
s.router.HandleFunc("/v2/validator/wallet", s.WalletConfig).Methods(http.MethodGet)
s.router.HandleFunc("/v2/validator/wallet/create", s.CreateWallet).Methods(http.MethodPost)
s.router.HandleFunc("/v2/validator/wallet/keystores/validate", s.ValidateKeystores).Methods(http.MethodPost)
s.router.HandleFunc("/v2/validator/wallet/recover", s.RecoverWallet).Methods(http.MethodPost)
s.router.HandleFunc(api.WebUrlPrefix+"wallet", s.WalletConfig).Methods(http.MethodGet)
s.router.HandleFunc(api.WebUrlPrefix+"wallet/create", s.CreateWallet).Methods(http.MethodPost)
s.router.HandleFunc(api.WebUrlPrefix+"wallet/keystores/validate", s.ValidateKeystores).Methods(http.MethodPost)
s.router.HandleFunc(api.WebUrlPrefix+"wallet/recover", s.RecoverWallet).Methods(http.MethodPost)
// slashing protection endpoints
s.router.HandleFunc("/v2/validator/slashing-protection/export", s.ExportSlashingProtection).Methods(http.MethodGet)
s.router.HandleFunc("/v2/validator/slashing-protection/import", s.ImportSlashingProtection).Methods(http.MethodPost)
s.router.HandleFunc(api.WebUrlPrefix+"slashing-protection/export", s.ExportSlashingProtection).Methods(http.MethodGet)
s.router.HandleFunc(api.WebUrlPrefix+"slashing-protection/import", s.ImportSlashingProtection).Methods(http.MethodPost)
log.Info("Initialized REST API routes")
return nil
}

View File

@@ -5,12 +5,9 @@ import (
"testing"
"github.com/gorilla/mux"
pb "github.com/prysmaticlabs/prysm/v4/proto/prysm/v1alpha1/validator-client"
"github.com/prysmaticlabs/prysm/v4/testing/require"
)
var _ pb.AuthServer = (*Server)(nil)
func TestServer_InitializeRoutes(t *testing.T) {
s := Server{
router: mux.NewRouter(),
@@ -33,6 +30,15 @@ func TestServer_InitializeRoutes(t *testing.T) {
"/v2/validator/wallet/recover": {http.MethodPost},
"/v2/validator/slashing-protection/export": {http.MethodGet},
"/v2/validator/slashing-protection/import": {http.MethodPost},
"/v2/validator/accounts": {http.MethodGet},
"/v2/validator/accounts/backup": {http.MethodPost},
"/v2/validator/accounts/voluntary-exit": {http.MethodPost},
"/v2/validator/beacon/balances": {http.MethodGet},
"/v2/validator/beacon/peers": {http.MethodGet},
"/v2/validator/beacon/status": {http.MethodGet},
"/v2/validator/beacon/summary": {http.MethodGet},
"/v2/validator/beacon/validators": {http.MethodGet},
"/v2/validator/initialize": {http.MethodGet},
}
gotRouteList := make(map[string][]string)
err = s.router.Walk(func(route *mux.Route, router *mux.Router, ancestors []*mux.Route) error {

View File

@@ -90,6 +90,15 @@ type SetFeeRecipientByPubkeyRequest struct {
Ethaddress string `json:"ethaddress"`
}
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"`
}
// KeymanagerKind is a type of key manager for the wallet
type KeymanagerKind string
@@ -140,3 +149,38 @@ type ImportSlashingProtectionRequest struct {
type ExportSlashingProtectionResponse struct {
File string `json:"file"`
}
type BackupAccountsRequest struct {
PublicKeys []string `json:"public_keys"`
BackupPassword string `json:"backup_password"`
}
type VoluntaryExitRequest struct {
PublicKeys []string `json:"public_keys"`
}
type BackupAccountsResponse struct {
ZipFile string `json:"zip_file"`
}
type ListAccountsResponse struct {
Accounts []*Account `json:"accounts"`
NextPageToken string `json:"next_page_token"`
TotalSize int32 `json:"total_size"`
}
type Account struct {
ValidatingPublicKey string `json:"validating_public_key"`
AccountName string `json:"account_name"`
DepositTxData string `json:"deposit_tx_data"`
DerivationPath string `json:"derivation_path"`
}
type VoluntaryExitResponse struct {
ExitedKeys [][]byte `protobuf:"bytes,1,rep,name=exited_keys,json=exitedKeys,proto3" json:"exited_keys,omitempty"`
}
type InitializeAuthResponse struct {
HasSignedUp bool `json:"has_signed_up"`
HasWallet bool `json:"has_wallet"`
}

11
validator/web/README.md Normal file
View File

@@ -0,0 +1,11 @@
## Note on future releases
** There is no longer an automated PR workflow for releasing the web ui due to its frozen state **
This is due to this PR removal of build content:https://github.com/prysmaticlabs/prysm/pull/12719
in order to update the `site_data.go` follow the following steps to update the specific release of https://github.com/prysmaticlabs/prysm-web-ui/releases
1. download and install https://github.com/kevinburke/go-bindata. (working as of version `4.0.2`) This tool will be used to generate the site_data.go file.
2. download the specific release from https://github.com/prysmaticlabs/prysm-web-ui/releases
3. run `go-bindata -pkg web -nometadata -modtime 0 -o site_data.go prysm-web-ui/` . `prysm-web-ui/` represents the extracted folder from the release.
4. copy and replace the site_data.go in this package.
5. Open a PR

View File

@@ -7,7 +7,7 @@ import (
"path"
)
const prefix = "external/prysm_web_ui/prysm-web-ui"
const prefix = "prysm-web-ui"
// Handler serves web requests from the bundled site data.
// DEPRECATED: Prysm Web UI and associated endpoints will be fully removed in a future hard fork.
@@ -24,20 +24,28 @@ var Handler = func(res http.ResponseWriter, req *http.Request) {
}
p = path.Join(prefix, p)
if d, ok := site[p]; ok {
if d, ok := _bindata[p]; ok {
m := mime.TypeByExtension(path.Ext(p))
res.Header().Add("Content-Type", m)
res.WriteHeader(200)
if _, err := res.Write(d); err != nil {
asset, err := d()
if err != nil {
log.WithError(err).Error("Failed to unwrap asset data for http response")
}
if _, err := res.Write(asset.bytes); err != nil {
log.WithError(err).Error("Failed to write http response")
}
} else if d, ok := site[path.Join(prefix, "index.html")]; ok {
} else if d, ok := _bindata[path.Join(prefix, "index.html")]; ok {
// Angular routing expects that routes are rewritten to serve index.html. For example, if
// requesting /login, this should serve the single page app index.html.
m := mime.TypeByExtension(".html")
res.Header().Add("Content-Type", m)
res.WriteHeader(200)
if _, err := res.Write(d); err != nil {
asset, err := d()
if err != nil {
log.WithError(err).Error("Failed to unwrap asset data for http response")
}
if _, err := res.Write(asset.bytes); err != nil {
log.WithError(err).Error("Failed to write http response")
}
} else { // If index.html is not present, serve 404. This should never happen.

File diff suppressed because one or more lines are too long