mirror of
https://github.com/OffchainLabs/prysm.git
synced 2026-05-02 03:02:54 -04:00
Implement GetEpochSyncCommittees in the beacon API (#9434)
* initial implementation * get committee for epoch * test * fix failing test # Conflicts: # beacon-chain/rpc/prysm/v1alpha1/validator/assignments_test.go * combine function arguments * review feedback * use sync committee setter * fix failing test * fix build * remove bad test * refactor for single responsibilities * radek suggestions Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com> Co-authored-by: Raul Jordan <raul@prysmaticlabs.com>
This commit is contained in:
@@ -160,7 +160,7 @@ func ApplySyncRewardsPenalties(s state.BeaconStateAltair, votedIndices, didntVot
|
||||
}
|
||||
|
||||
// SyncRewards returns the proposer reward and the sync participant reward given the total active balance in state.
|
||||
func SyncRewards(activeBalance uint64) (proposerReward uint64, participantReward uint64, err error) {
|
||||
func SyncRewards(activeBalance uint64) (proposerReward, participantReward uint64, err error) {
|
||||
cfg := params.BeaconConfig()
|
||||
totalActiveIncrements := activeBalance / cfg.EffectiveBalanceIncrement
|
||||
baseRewardPerInc, err := BaseRewardPerIncrement(activeBalance)
|
||||
|
||||
@@ -16,6 +16,7 @@ go_library(
|
||||
visibility = ["//beacon-chain:__subpackages__"],
|
||||
deps = [
|
||||
"//beacon-chain/blockchain:go_default_library",
|
||||
"//beacon-chain/core/altair:go_default_library",
|
||||
"//beacon-chain/core/blocks:go_default_library",
|
||||
"//beacon-chain/core/feed:go_default_library",
|
||||
"//beacon-chain/core/feed/block:go_default_library",
|
||||
@@ -67,6 +68,7 @@ go_test(
|
||||
"pool_test.go",
|
||||
"server_test.go",
|
||||
"state_test.go",
|
||||
"sync_committee_test.go",
|
||||
"validator_test.go",
|
||||
],
|
||||
embed = [":go_default_library"],
|
||||
@@ -86,6 +88,7 @@ go_test(
|
||||
"//beacon-chain/state/v1:go_default_library",
|
||||
"//proto/eth/service:go_default_library",
|
||||
"//proto/eth/v1:go_default_library",
|
||||
"//proto/eth/v2:go_default_library",
|
||||
"//proto/migration:go_default_library",
|
||||
"//proto/prysm/v1alpha1:go_default_library",
|
||||
"//proto/prysm/v1alpha1/block:go_default_library",
|
||||
|
||||
@@ -3,7 +3,11 @@ package beacon
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"strconv"
|
||||
|
||||
types "github.com/prysmaticlabs/eth2-types"
|
||||
corehelpers "github.com/prysmaticlabs/prysm/beacon-chain/core/helpers"
|
||||
"github.com/prysmaticlabs/prysm/beacon-chain/rpc/eth/helpers"
|
||||
"github.com/prysmaticlabs/prysm/beacon-chain/rpc/statefetcher"
|
||||
"github.com/prysmaticlabs/prysm/beacon-chain/state"
|
||||
ethpb "github.com/prysmaticlabs/prysm/proto/eth/v1"
|
||||
@@ -16,6 +20,11 @@ import (
|
||||
"google.golang.org/protobuf/types/known/timestamppb"
|
||||
)
|
||||
|
||||
type stateRequest struct {
|
||||
epoch *types.Epoch
|
||||
stateId []byte
|
||||
}
|
||||
|
||||
// GetGenesis retrieves details of the chain's genesis which can be used to identify chain.
|
||||
func (bs *Server) GetGenesis(ctx context.Context, _ *emptypb.Empty) (*ethpb.GenesisResponse, error) {
|
||||
ctx, span := trace.StartSpan(ctx, "beaconv1.GetGenesis")
|
||||
@@ -82,12 +91,7 @@ func (bs *Server) GetStateFork(ctx context.Context, req *ethpb.StateRequest) (*e
|
||||
|
||||
state, err = bs.StateFetcher.State(ctx, req.StateId)
|
||||
if err != nil {
|
||||
if stateNotFoundErr, ok := err.(*statefetcher.StateNotFoundError); ok {
|
||||
return nil, status.Errorf(codes.NotFound, "State not found: %v", stateNotFoundErr)
|
||||
} else if parseErr, ok := err.(*statefetcher.StateIdParseError); ok {
|
||||
return nil, status.Errorf(codes.InvalidArgument, "Invalid state ID: %v", parseErr)
|
||||
}
|
||||
return nil, status.Errorf(codes.Internal, "Could not get state: %v", err)
|
||||
return nil, helpers.PrepareStateFetchGRPCError(err)
|
||||
}
|
||||
|
||||
fork := state.Fork()
|
||||
@@ -130,6 +134,31 @@ func (bs *Server) GetFinalityCheckpoints(ctx context.Context, req *ethpb.StateRe
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (bs *Server) stateFromRequest(ctx context.Context, req *stateRequest) (state.BeaconState, error) {
|
||||
if req.epoch != nil {
|
||||
slot, err := corehelpers.StartSlot(*req.epoch)
|
||||
if err != nil {
|
||||
return nil, status.Errorf(
|
||||
codes.Internal,
|
||||
"Could not calculate start slot for epoch %d: %v",
|
||||
*req.epoch,
|
||||
err,
|
||||
)
|
||||
}
|
||||
st, err := bs.StateFetcher.State(ctx, []byte(strconv.FormatUint(uint64(slot), 10)))
|
||||
if err != nil {
|
||||
return nil, helpers.PrepareStateFetchGRPCError(err)
|
||||
}
|
||||
return st, nil
|
||||
}
|
||||
var err error
|
||||
st, err := bs.StateFetcher.State(ctx, req.stateId)
|
||||
if err != nil {
|
||||
return nil, helpers.PrepareStateFetchGRPCError(err)
|
||||
}
|
||||
return st, nil
|
||||
}
|
||||
|
||||
func checkpoint(sourceCheckpoint *eth.Checkpoint) *ethpb.Checkpoint {
|
||||
if sourceCheckpoint != nil {
|
||||
return ðpb.Checkpoint{
|
||||
|
||||
@@ -2,15 +2,98 @@ package beacon
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"github.com/golang/protobuf/ptypes/empty"
|
||||
types "github.com/prysmaticlabs/eth2-types"
|
||||
"github.com/prysmaticlabs/prysm/beacon-chain/core/altair"
|
||||
"github.com/prysmaticlabs/prysm/beacon-chain/state"
|
||||
"github.com/prysmaticlabs/prysm/proto/eth/v2"
|
||||
ethpb "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1"
|
||||
"github.com/prysmaticlabs/prysm/shared/bytesutil"
|
||||
"github.com/prysmaticlabs/prysm/shared/params"
|
||||
"google.golang.org/grpc/codes"
|
||||
"google.golang.org/grpc/status"
|
||||
)
|
||||
|
||||
func (bs *Server) ListSyncCommittees(ctx context.Context, request *eth.StateSyncCommitteesRequest) (*eth.StateSyncCommitteesResponse, error) {
|
||||
panic("implement me")
|
||||
// ListSyncCommittees retrieves the sync committees for the given epoch.
|
||||
// If the epoch is not passed in, then the sync committees for the epoch of the state will be obtained.
|
||||
func (bs *Server) ListSyncCommittees(ctx context.Context, req *eth.StateSyncCommitteesRequest) (*eth.StateSyncCommitteesResponse, error) {
|
||||
st, err := bs.stateFromRequest(ctx, &stateRequest{
|
||||
epoch: req.Epoch,
|
||||
stateId: req.StateId,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, status.Errorf(codes.Internal, "Could not fetch beacon state using request: %v", err)
|
||||
}
|
||||
|
||||
// Get the current sync committee and sync committee indices from the state.
|
||||
committeeIndices, committee, err := currentCommitteeIndicesFromState(st)
|
||||
if err != nil {
|
||||
return nil, status.Errorf(codes.Internal, "Could not get sync committee indices from state: %v", err)
|
||||
}
|
||||
subcommittees, err := extractSyncSubcommittees(st, committee)
|
||||
if err != nil {
|
||||
return nil, status.Errorf(codes.Internal, "Could not extract sync subcommittees: %v", err)
|
||||
}
|
||||
|
||||
return ð.StateSyncCommitteesResponse{
|
||||
Data: ð.SyncCommitteeValidators{
|
||||
Validators: committeeIndices,
|
||||
ValidatorAggregates: subcommittees,
|
||||
},
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (bs *Server) SubmitSyncCommitteeSignature(ctx context.Context, message *eth.SyncCommitteeMessage) (*empty.Empty, error) {
|
||||
panic("implement me")
|
||||
// SubmitSyncCommitteeSignature --
|
||||
func (bs *Server) SubmitSyncCommitteeSignature(_ context.Context, _ *eth.SyncCommitteeMessage) (*empty.Empty, error) {
|
||||
return nil, status.Error(codes.Unimplemented, "Unimplemented")
|
||||
}
|
||||
|
||||
func currentCommitteeIndicesFromState(st state.BeaconState) ([]types.ValidatorIndex, *ethpb.SyncCommittee, error) {
|
||||
committee, err := st.CurrentSyncCommittee()
|
||||
if err != nil {
|
||||
return nil, nil, fmt.Errorf(
|
||||
"could not get sync committee: %v", err,
|
||||
)
|
||||
}
|
||||
|
||||
committeeIndices := make([]types.ValidatorIndex, len(committee.Pubkeys))
|
||||
for i, key := range committee.Pubkeys {
|
||||
index, ok := st.ValidatorIndexByPubkey(bytesutil.ToBytes48(key))
|
||||
if !ok {
|
||||
return nil, nil, fmt.Errorf(
|
||||
"validator index not found for pubkey %#x",
|
||||
bytesutil.Trunc(key),
|
||||
)
|
||||
}
|
||||
committeeIndices[i] = index
|
||||
}
|
||||
return committeeIndices, committee, nil
|
||||
}
|
||||
|
||||
func extractSyncSubcommittees(st state.BeaconState, committee *ethpb.SyncCommittee) ([]*eth.SyncSubcommitteeValidators, error) {
|
||||
subcommitteeCount := params.BeaconConfig().SyncCommitteeSubnetCount
|
||||
subcommittees := make([]*eth.SyncSubcommitteeValidators, subcommitteeCount)
|
||||
for i := uint64(0); i < subcommitteeCount; i++ {
|
||||
pubkeys, err := altair.SyncSubCommitteePubkeys(committee, types.CommitteeIndex(i))
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf(
|
||||
"failed to get subcommittee pubkeys: %v", err,
|
||||
)
|
||||
}
|
||||
subcommittee := ð.SyncSubcommitteeValidators{Validators: make([]types.ValidatorIndex, len(pubkeys))}
|
||||
for j, key := range pubkeys {
|
||||
index, ok := st.ValidatorIndexByPubkey(bytesutil.ToBytes48(key))
|
||||
if !ok {
|
||||
return nil, fmt.Errorf(
|
||||
"validator index not found for pubkey %#x",
|
||||
bytesutil.Trunc(key),
|
||||
)
|
||||
}
|
||||
subcommittee.Validators[j] = index
|
||||
}
|
||||
subcommittees[i] = subcommittee
|
||||
}
|
||||
return subcommittees, nil
|
||||
}
|
||||
|
||||
142
beacon-chain/rpc/eth/beacon/sync_committee_test.go
Normal file
142
beacon-chain/rpc/eth/beacon/sync_committee_test.go
Normal file
@@ -0,0 +1,142 @@
|
||||
package beacon
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
types "github.com/prysmaticlabs/eth2-types"
|
||||
"github.com/prysmaticlabs/prysm/beacon-chain/rpc/testutil"
|
||||
ethpbv2 "github.com/prysmaticlabs/prysm/proto/eth/v2"
|
||||
ethpbalpha "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1"
|
||||
"github.com/prysmaticlabs/prysm/shared/bytesutil"
|
||||
"github.com/prysmaticlabs/prysm/shared/params"
|
||||
sharedtestutil "github.com/prysmaticlabs/prysm/shared/testutil"
|
||||
"github.com/prysmaticlabs/prysm/shared/testutil/assert"
|
||||
"github.com/prysmaticlabs/prysm/shared/testutil/require"
|
||||
)
|
||||
|
||||
func Test_currentCommitteeIndicesFromState(t *testing.T) {
|
||||
st, _ := sharedtestutil.DeterministicGenesisStateAltair(t, params.BeaconConfig().SyncCommitteeSize)
|
||||
vals := st.Validators()
|
||||
wantedCommittee := make([][]byte, params.BeaconConfig().SyncCommitteeSize)
|
||||
wantedIndices := make([]types.ValidatorIndex, len(wantedCommittee))
|
||||
for i := 0; i < len(wantedCommittee); i++ {
|
||||
wantedIndices[i] = types.ValidatorIndex(i)
|
||||
wantedCommittee[i] = vals[i].PublicKey
|
||||
}
|
||||
require.NoError(t, st.SetCurrentSyncCommittee(ðpbalpha.SyncCommittee{
|
||||
Pubkeys: wantedCommittee,
|
||||
AggregatePubkey: bytesutil.PadTo([]byte{}, params.BeaconConfig().BLSPubkeyLength),
|
||||
}))
|
||||
|
||||
t.Run("OK", func(t *testing.T) {
|
||||
indices, committee, err := currentCommitteeIndicesFromState(st)
|
||||
require.NoError(t, err)
|
||||
require.DeepEqual(t, wantedIndices, indices)
|
||||
require.DeepEqual(t, wantedCommittee, committee.Pubkeys)
|
||||
})
|
||||
t.Run("validator in committee not found in state", func(t *testing.T) {
|
||||
wantedCommittee[0] = bytesutil.PadTo([]byte("fakepubkey"), 48)
|
||||
require.NoError(t, st.SetCurrentSyncCommittee(ðpbalpha.SyncCommittee{
|
||||
Pubkeys: wantedCommittee,
|
||||
AggregatePubkey: bytesutil.PadTo([]byte{}, params.BeaconConfig().BLSPubkeyLength),
|
||||
}))
|
||||
_, _, err := currentCommitteeIndicesFromState(st)
|
||||
require.ErrorContains(t, "index not found for pubkey", err)
|
||||
})
|
||||
}
|
||||
|
||||
func Test_extractSyncSubcommittees(t *testing.T) {
|
||||
st, _ := sharedtestutil.DeterministicGenesisStateAltair(t, params.BeaconConfig().SyncCommitteeSize)
|
||||
vals := st.Validators()
|
||||
syncCommittee := make([][]byte, params.BeaconConfig().SyncCommitteeSize)
|
||||
for i := 0; i < len(syncCommittee); i++ {
|
||||
syncCommittee[i] = vals[i].PublicKey
|
||||
}
|
||||
require.NoError(t, st.SetCurrentSyncCommittee(ðpbalpha.SyncCommittee{
|
||||
Pubkeys: syncCommittee,
|
||||
AggregatePubkey: bytesutil.PadTo([]byte{}, params.BeaconConfig().BLSPubkeyLength),
|
||||
}))
|
||||
|
||||
commSize := params.BeaconConfig().SyncCommitteeSize
|
||||
subCommSize := params.BeaconConfig().SyncCommitteeSize / params.BeaconConfig().SyncCommitteeSubnetCount
|
||||
wantedSubcommitteeValidators := make([][]types.ValidatorIndex, 0)
|
||||
|
||||
for i := uint64(0); i < commSize; i += subCommSize {
|
||||
sub := make([]types.ValidatorIndex, 0)
|
||||
start := i
|
||||
end := i + subCommSize
|
||||
if end > commSize {
|
||||
end = commSize
|
||||
}
|
||||
for j := start; j < end; j++ {
|
||||
sub = append(sub, types.ValidatorIndex(j))
|
||||
}
|
||||
wantedSubcommitteeValidators = append(wantedSubcommitteeValidators, sub)
|
||||
}
|
||||
|
||||
t.Run("OK", func(t *testing.T) {
|
||||
committee, err := st.CurrentSyncCommittee()
|
||||
require.NoError(t, err)
|
||||
subcommittee, err := extractSyncSubcommittees(st, committee)
|
||||
require.NoError(t, err)
|
||||
for i, got := range subcommittee {
|
||||
want := wantedSubcommitteeValidators[i]
|
||||
require.DeepEqual(t, want, got.Validators)
|
||||
}
|
||||
})
|
||||
t.Run("validator in subcommittee not found in state", func(t *testing.T) {
|
||||
syncCommittee[0] = bytesutil.PadTo([]byte("fakepubkey"), 48)
|
||||
require.NoError(t, st.SetCurrentSyncCommittee(ðpbalpha.SyncCommittee{
|
||||
Pubkeys: syncCommittee,
|
||||
AggregatePubkey: bytesutil.PadTo([]byte{}, params.BeaconConfig().BLSPubkeyLength),
|
||||
}))
|
||||
committee, err := st.CurrentSyncCommittee()
|
||||
require.NoError(t, err)
|
||||
_, err = extractSyncSubcommittees(st, committee)
|
||||
require.ErrorContains(t, "index not found for pubkey", err)
|
||||
})
|
||||
}
|
||||
|
||||
func TestListSyncCommittees(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
st, _ := sharedtestutil.DeterministicGenesisStateAltair(t, params.BeaconConfig().SyncCommitteeSize)
|
||||
syncCommittee := make([][]byte, params.BeaconConfig().SyncCommitteeSize)
|
||||
vals := st.Validators()
|
||||
for i := 0; i < len(syncCommittee); i++ {
|
||||
syncCommittee[i] = vals[i].PublicKey
|
||||
}
|
||||
require.NoError(t, st.SetCurrentSyncCommittee(ðpbalpha.SyncCommittee{
|
||||
Pubkeys: syncCommittee,
|
||||
AggregatePubkey: bytesutil.PadTo([]byte{}, params.BeaconConfig().BLSPubkeyLength),
|
||||
}))
|
||||
stRoot, err := st.HashTreeRoot(ctx)
|
||||
require.NoError(t, err)
|
||||
|
||||
s := &Server{
|
||||
StateFetcher: &testutil.MockFetcher{
|
||||
BeaconState: st,
|
||||
},
|
||||
}
|
||||
req := ðpbv2.StateSyncCommitteesRequest{StateId: stRoot[:]}
|
||||
resp, err := s.ListSyncCommittees(ctx, req)
|
||||
require.NoError(t, err)
|
||||
require.NotNil(t, resp.Data)
|
||||
committeeVals := resp.Data.Validators
|
||||
require.NotNil(t, committeeVals)
|
||||
require.Equal(t, params.BeaconConfig().SyncCommitteeSize, uint64(len(committeeVals)), "incorrect committee size")
|
||||
for i := uint64(0); i < params.BeaconConfig().SyncCommitteeSize; i++ {
|
||||
assert.Equal(t, types.ValidatorIndex(i), committeeVals[i])
|
||||
}
|
||||
require.NotNil(t, resp.Data.ValidatorAggregates)
|
||||
assert.Equal(t, params.BeaconConfig().SyncCommitteeSubnetCount, uint64(len(resp.Data.ValidatorAggregates)))
|
||||
for i := uint64(0); i < params.BeaconConfig().SyncCommitteeSubnetCount; i++ {
|
||||
vStartIndex := types.ValidatorIndex(params.BeaconConfig().SyncCommitteeSize / params.BeaconConfig().SyncCommitteeSubnetCount * i)
|
||||
vEndIndex := types.ValidatorIndex(params.BeaconConfig().SyncCommitteeSize/params.BeaconConfig().SyncCommitteeSubnetCount*(i+1) - 1)
|
||||
j := 0
|
||||
for vIndex := vStartIndex; vIndex <= vEndIndex; vIndex++ {
|
||||
assert.Equal(t, vIndex, resp.Data.ValidatorAggregates[i].Validators[j])
|
||||
j++
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -6,9 +6,8 @@ import (
|
||||
|
||||
"github.com/pkg/errors"
|
||||
types "github.com/prysmaticlabs/eth2-types"
|
||||
"github.com/prysmaticlabs/prysm/beacon-chain/core/helpers"
|
||||
rpchelpers "github.com/prysmaticlabs/prysm/beacon-chain/rpc/eth/helpers"
|
||||
"github.com/prysmaticlabs/prysm/beacon-chain/rpc/statefetcher"
|
||||
corehelpers "github.com/prysmaticlabs/prysm/beacon-chain/core/helpers"
|
||||
"github.com/prysmaticlabs/prysm/beacon-chain/rpc/eth/helpers"
|
||||
"github.com/prysmaticlabs/prysm/beacon-chain/state"
|
||||
v1 "github.com/prysmaticlabs/prysm/beacon-chain/state/v1"
|
||||
ethpb "github.com/prysmaticlabs/prysm/proto/eth/v1"
|
||||
@@ -40,12 +39,7 @@ func (e *invalidValidatorIdError) Error() string {
|
||||
func (bs *Server) GetValidator(ctx context.Context, req *ethpb.StateValidatorRequest) (*ethpb.StateValidatorResponse, error) {
|
||||
state, err := bs.StateFetcher.State(ctx, req.StateId)
|
||||
if err != nil {
|
||||
if stateNotFoundErr, ok := err.(*statefetcher.StateNotFoundError); ok {
|
||||
return nil, status.Errorf(codes.NotFound, "could not get state: %v", stateNotFoundErr)
|
||||
} else if parseErr, ok := err.(*statefetcher.StateIdParseError); ok {
|
||||
return nil, status.Errorf(codes.InvalidArgument, "Invalid state ID: %v", parseErr)
|
||||
}
|
||||
return nil, status.Errorf(codes.Internal, "State not found: %v", err)
|
||||
return nil, helpers.PrepareStateFetchGRPCError(err)
|
||||
}
|
||||
if len(req.ValidatorId) == 0 {
|
||||
return nil, status.Error(codes.InvalidArgument, "Validator ID is required")
|
||||
@@ -64,12 +58,7 @@ func (bs *Server) GetValidator(ctx context.Context, req *ethpb.StateValidatorReq
|
||||
func (bs *Server) ListValidators(ctx context.Context, req *ethpb.StateValidatorsRequest) (*ethpb.StateValidatorsResponse, error) {
|
||||
state, err := bs.StateFetcher.State(ctx, req.StateId)
|
||||
if err != nil {
|
||||
if stateNotFoundErr, ok := err.(*statefetcher.StateNotFoundError); ok {
|
||||
return nil, status.Errorf(codes.NotFound, "State not found: %v", stateNotFoundErr)
|
||||
} else if parseErr, ok := err.(*statefetcher.StateIdParseError); ok {
|
||||
return nil, status.Errorf(codes.InvalidArgument, "Invalid state ID: %v", parseErr)
|
||||
}
|
||||
return nil, status.Errorf(codes.Internal, "Could not get state: %v", err)
|
||||
return nil, helpers.PrepareStateFetchGRPCError(err)
|
||||
}
|
||||
|
||||
valContainers, err := valContainersByRequestIds(state, req.Id)
|
||||
@@ -90,18 +79,18 @@ func (bs *Server) ListValidators(ctx context.Context, req *ethpb.StateValidators
|
||||
}
|
||||
filterStatus[ss] = true
|
||||
}
|
||||
epoch := helpers.SlotToEpoch(state.Slot())
|
||||
epoch := corehelpers.SlotToEpoch(state.Slot())
|
||||
filteredVals := make([]*ethpb.ValidatorContainer, 0, len(valContainers))
|
||||
for _, vc := range valContainers {
|
||||
readOnlyVal, err := v1.NewValidator(migration.V1ValidatorToV1Alpha1(vc.Validator))
|
||||
if err != nil {
|
||||
return nil, status.Errorf(codes.Internal, "Could not convert validator: %v", err)
|
||||
}
|
||||
valStatus, err := rpchelpers.ValidatorStatus(readOnlyVal, epoch)
|
||||
valStatus, err := helpers.ValidatorStatus(readOnlyVal, epoch)
|
||||
if err != nil {
|
||||
return nil, status.Errorf(codes.Internal, "Could not get validator status: %v", err)
|
||||
}
|
||||
valSubStatus, err := rpchelpers.ValidatorSubStatus(readOnlyVal, epoch)
|
||||
valSubStatus, err := helpers.ValidatorSubStatus(readOnlyVal, epoch)
|
||||
if err != nil {
|
||||
return nil, status.Errorf(codes.Internal, "Could not get validator sub status: %v", err)
|
||||
}
|
||||
@@ -116,12 +105,7 @@ func (bs *Server) ListValidators(ctx context.Context, req *ethpb.StateValidators
|
||||
func (bs *Server) ListValidatorBalances(ctx context.Context, req *ethpb.ValidatorBalancesRequest) (*ethpb.ValidatorBalancesResponse, error) {
|
||||
state, err := bs.StateFetcher.State(ctx, req.StateId)
|
||||
if err != nil {
|
||||
if stateNotFoundErr, ok := err.(*statefetcher.StateNotFoundError); ok {
|
||||
return nil, status.Errorf(codes.NotFound, "State not found: %v", stateNotFoundErr)
|
||||
} else if parseErr, ok := err.(*statefetcher.StateIdParseError); ok {
|
||||
return nil, status.Errorf(codes.InvalidArgument, "Invalid state ID: %v", parseErr)
|
||||
}
|
||||
return nil, status.Errorf(codes.Internal, "Could not get state: %v", err)
|
||||
return nil, helpers.PrepareStateFetchGRPCError(err)
|
||||
}
|
||||
|
||||
valContainers, err := valContainersByRequestIds(state, req.Id)
|
||||
@@ -143,32 +127,27 @@ func (bs *Server) ListValidatorBalances(ctx context.Context, req *ethpb.Validato
|
||||
func (bs *Server) ListCommittees(ctx context.Context, req *ethpb.StateCommitteesRequest) (*ethpb.StateCommitteesResponse, error) {
|
||||
state, err := bs.StateFetcher.State(ctx, req.StateId)
|
||||
if err != nil {
|
||||
if stateNotFoundErr, ok := err.(*statefetcher.StateNotFoundError); ok {
|
||||
return nil, status.Errorf(codes.NotFound, "State not found: %v", stateNotFoundErr)
|
||||
} else if parseErr, ok := err.(*statefetcher.StateIdParseError); ok {
|
||||
return nil, status.Errorf(codes.InvalidArgument, "Invalid state ID: %v", parseErr)
|
||||
}
|
||||
return nil, status.Errorf(codes.Internal, "Could not get state: %v", err)
|
||||
return nil, helpers.PrepareStateFetchGRPCError(err)
|
||||
}
|
||||
|
||||
epoch := helpers.SlotToEpoch(state.Slot())
|
||||
epoch := corehelpers.SlotToEpoch(state.Slot())
|
||||
if req.Epoch != nil {
|
||||
epoch = *req.Epoch
|
||||
}
|
||||
activeCount, err := helpers.ActiveValidatorCount(state, epoch)
|
||||
activeCount, err := corehelpers.ActiveValidatorCount(state, epoch)
|
||||
if err != nil {
|
||||
return nil, status.Errorf(codes.Internal, "Could not get active validator count: %v", err)
|
||||
}
|
||||
|
||||
startSlot, err := helpers.StartSlot(epoch)
|
||||
startSlot, err := corehelpers.StartSlot(epoch)
|
||||
if err != nil {
|
||||
return nil, status.Errorf(codes.InvalidArgument, "Invalid epoch: %v", err)
|
||||
}
|
||||
endSlot, err := helpers.EndSlot(epoch)
|
||||
endSlot, err := corehelpers.EndSlot(epoch)
|
||||
if err != nil {
|
||||
return nil, status.Errorf(codes.InvalidArgument, "Invalid epoch: %v", err)
|
||||
}
|
||||
committeesPerSlot := helpers.SlotCommitteeCount(activeCount)
|
||||
committeesPerSlot := corehelpers.SlotCommitteeCount(activeCount)
|
||||
committees := make([]*ethpb.Committee, 0)
|
||||
for slot := startSlot; slot <= endSlot; slot++ {
|
||||
if req.Slot != nil && slot != *req.Slot {
|
||||
@@ -178,7 +157,7 @@ func (bs *Server) ListCommittees(ctx context.Context, req *ethpb.StateCommittees
|
||||
if req.Index != nil && index != *req.Index {
|
||||
continue
|
||||
}
|
||||
committee, err := helpers.BeaconCommitteeFromState(state, slot, index)
|
||||
committee, err := corehelpers.BeaconCommitteeFromState(state, slot, index)
|
||||
if err != nil {
|
||||
return nil, status.Errorf(codes.Internal, "Could not get committee: %v", err)
|
||||
}
|
||||
@@ -196,7 +175,7 @@ func (bs *Server) ListCommittees(ctx context.Context, req *ethpb.StateCommittees
|
||||
// This function returns the validator object based on the passed in ID. The validator ID could be its public key,
|
||||
// or its index.
|
||||
func valContainersByRequestIds(state state.BeaconState, validatorIds [][]byte) ([]*ethpb.ValidatorContainer, error) {
|
||||
epoch := helpers.SlotToEpoch(state.Slot())
|
||||
epoch := corehelpers.SlotToEpoch(state.Slot())
|
||||
var valContainers []*ethpb.ValidatorContainer
|
||||
if len(validatorIds) == 0 {
|
||||
allValidators := state.Validators()
|
||||
@@ -207,7 +186,7 @@ func valContainersByRequestIds(state state.BeaconState, validatorIds [][]byte) (
|
||||
if err != nil {
|
||||
return nil, status.Errorf(codes.Internal, "Could not convert validator: %v", err)
|
||||
}
|
||||
subStatus, err := rpchelpers.ValidatorSubStatus(readOnlyVal, epoch)
|
||||
subStatus, err := helpers.ValidatorSubStatus(readOnlyVal, epoch)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "could not get validator sub status")
|
||||
}
|
||||
@@ -250,7 +229,7 @@ func valContainersByRequestIds(state state.BeaconState, validatorIds [][]byte) (
|
||||
if err != nil {
|
||||
return nil, status.Errorf(codes.Internal, "Could not convert validator: %v", err)
|
||||
}
|
||||
subStatus, err := rpchelpers.ValidatorSubStatus(readOnlyVal, epoch)
|
||||
subStatus, err := helpers.ValidatorSubStatus(readOnlyVal, epoch)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "could not get validator sub status")
|
||||
}
|
||||
|
||||
@@ -11,6 +11,7 @@ go_library(
|
||||
deps = [
|
||||
"//beacon-chain/blockchain:go_default_library",
|
||||
"//beacon-chain/db:go_default_library",
|
||||
"//beacon-chain/rpc/eth/helpers:go_default_library",
|
||||
"//beacon-chain/rpc/statefetcher:go_default_library",
|
||||
"//proto/eth/v1:go_default_library",
|
||||
"//proto/eth/v2:go_default_library",
|
||||
|
||||
@@ -3,7 +3,7 @@ package debug
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/prysmaticlabs/prysm/beacon-chain/rpc/statefetcher"
|
||||
"github.com/prysmaticlabs/prysm/beacon-chain/rpc/eth/helpers"
|
||||
ethpbv1 "github.com/prysmaticlabs/prysm/proto/eth/v1"
|
||||
ethpbv2 "github.com/prysmaticlabs/prysm/proto/eth/v2"
|
||||
"go.opencensus.io/trace"
|
||||
@@ -19,12 +19,7 @@ func (ds *Server) GetBeaconState(ctx context.Context, req *ethpbv1.StateRequest)
|
||||
|
||||
state, err := ds.StateFetcher.State(ctx, req.StateId)
|
||||
if err != nil {
|
||||
if stateNotFoundErr, ok := err.(*statefetcher.StateNotFoundError); ok {
|
||||
return nil, status.Errorf(codes.NotFound, "State not found: %v", stateNotFoundErr)
|
||||
} else if parseErr, ok := err.(*statefetcher.StateIdParseError); ok {
|
||||
return nil, status.Errorf(codes.InvalidArgument, "Invalid state ID: %v", parseErr)
|
||||
}
|
||||
return nil, status.Errorf(codes.Internal, "Invalid state ID: %v", err)
|
||||
return nil, helpers.PrepareStateFetchGRPCError(err)
|
||||
}
|
||||
|
||||
protoState, err := state.ToProto()
|
||||
@@ -44,12 +39,7 @@ func (ds *Server) GetBeaconStateSSZ(ctx context.Context, req *ethpbv1.StateReque
|
||||
|
||||
state, err := ds.StateFetcher.State(ctx, req.StateId)
|
||||
if err != nil {
|
||||
if stateNotFoundErr, ok := err.(*statefetcher.StateNotFoundError); ok {
|
||||
return nil, status.Errorf(codes.NotFound, "State not found: %v", stateNotFoundErr)
|
||||
} else if parseErr, ok := err.(*statefetcher.StateIdParseError); ok {
|
||||
return nil, status.Errorf(codes.InvalidArgument, "Invalid state ID: %v", parseErr)
|
||||
}
|
||||
return nil, status.Errorf(codes.Internal, "Invalid state ID: %v", err)
|
||||
return nil, helpers.PrepareStateFetchGRPCError(err)
|
||||
}
|
||||
|
||||
sszState, err := state.MarshalSSZ()
|
||||
|
||||
@@ -2,15 +2,21 @@ load("@prysm//tools/go:def.bzl", "go_library", "go_test")
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = ["validator_status.go"],
|
||||
srcs = [
|
||||
"state.go",
|
||||
"validator_status.go",
|
||||
],
|
||||
importpath = "github.com/prysmaticlabs/prysm/beacon-chain/rpc/eth/helpers",
|
||||
visibility = ["//beacon-chain:__subpackages__"],
|
||||
deps = [
|
||||
"//beacon-chain/rpc/statefetcher:go_default_library",
|
||||
"//beacon-chain/state:go_default_library",
|
||||
"//proto/eth/v1:go_default_library",
|
||||
"//shared/params:go_default_library",
|
||||
"@com_github_pkg_errors//:go_default_library",
|
||||
"@com_github_prysmaticlabs_eth2_types//:go_default_library",
|
||||
"@org_golang_google_grpc//codes:go_default_library",
|
||||
"@org_golang_google_grpc//status:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
|
||||
18
beacon-chain/rpc/eth/helpers/state.go
Normal file
18
beacon-chain/rpc/eth/helpers/state.go
Normal file
@@ -0,0 +1,18 @@
|
||||
package helpers
|
||||
|
||||
import (
|
||||
"github.com/prysmaticlabs/prysm/beacon-chain/rpc/statefetcher"
|
||||
"google.golang.org/grpc/codes"
|
||||
"google.golang.org/grpc/status"
|
||||
)
|
||||
|
||||
// PrepareStateFetchGRPCError returns an appropriate gRPC error based on the supplied argument.
|
||||
// The argument error should be a result of fetching state.
|
||||
func PrepareStateFetchGRPCError(err error) error {
|
||||
if stateNotFoundErr, ok := err.(*statefetcher.StateNotFoundError); ok {
|
||||
return status.Errorf(codes.NotFound, "State not found: %v", stateNotFoundErr)
|
||||
} else if parseErr, ok := err.(*statefetcher.StateIdParseError); ok {
|
||||
return status.Errorf(codes.InvalidArgument, "Invalid state ID: %v", parseErr)
|
||||
}
|
||||
return status.Errorf(codes.Internal, "Invalid state ID: %v", err)
|
||||
}
|
||||
Reference in New Issue
Block a user