diff --git a/beacon-chain/rpc/eth/beacon/handlers_validator.go b/beacon-chain/rpc/eth/beacon/handlers_validator.go index 1339576450ab..bc79f890cc2a 100644 --- a/beacon-chain/rpc/eth/beacon/handlers_validator.go +++ b/beacon-chain/rpc/eth/beacon/handlers_validator.go @@ -369,16 +369,7 @@ func decodeIds(w http.ResponseWriter, st state.BeaconState, rawIds []string, ign func valsFromIds(w http.ResponseWriter, st state.BeaconState, ids []primitives.ValidatorIndex) ([]state.ReadOnlyValidator, bool) { var vals []state.ReadOnlyValidator if len(ids) == 0 { - allVals := st.Validators() - vals = make([]state.ReadOnlyValidator, len(allVals)) - for i, val := range allVals { - readOnlyVal, err := statenative.NewValidator(val) - if err != nil { - httputil.HandleError(w, "Could not convert validator: "+err.Error(), http.StatusInternalServerError) - return nil, false - } - vals[i] = readOnlyVal - } + vals = st.ValidatorsReadOnly() } else { vals = make([]state.ReadOnlyValidator, 0, len(ids)) for _, id := range ids { diff --git a/beacon-chain/state/interfaces.go b/beacon-chain/state/interfaces.go index 11d063ebf43f..0a6a92a27772 100644 --- a/beacon-chain/state/interfaces.go +++ b/beacon-chain/state/interfaces.go @@ -118,6 +118,7 @@ type ReadOnlyValidator interface { // ReadOnlyValidators defines a struct which only has read access to validators methods. type ReadOnlyValidators interface { Validators() []*ethpb.Validator + ValidatorsReadOnly() []ReadOnlyValidator ValidatorAtIndex(idx primitives.ValidatorIndex) (*ethpb.Validator, error) ValidatorAtIndexReadOnly(idx primitives.ValidatorIndex) (ReadOnlyValidator, error) ValidatorIndexByPubkey(key [fieldparams.BLSPubkeyLength]byte) (primitives.ValidatorIndex, bool) diff --git a/beacon-chain/state/state-native/getters_validator.go b/beacon-chain/state/state-native/getters_validator.go index 89cbbf461ec5..979a8d9163c6 100644 --- a/beacon-chain/state/state-native/getters_validator.go +++ b/beacon-chain/state/state-native/getters_validator.go @@ -21,6 +21,14 @@ func (b *BeaconState) Validators() []*ethpb.Validator { return b.validatorsVal() } +// ValidatorsReadOnly participating in consensus on the beacon chain. +func (b *BeaconState) ValidatorsReadOnly() []state.ReadOnlyValidator { + b.lock.RLock() + defer b.lock.RUnlock() + + return b.validatorsReadOnlyVal() +} + func (b *BeaconState) validatorsVal() []*ethpb.Validator { var v []*ethpb.Validator if features.Get().EnableExperimentalState { @@ -46,6 +54,35 @@ func (b *BeaconState) validatorsVal() []*ethpb.Validator { return res } +func (b *BeaconState) validatorsReadOnlyVal() []state.ReadOnlyValidator { + var v []*ethpb.Validator + if features.Get().EnableExperimentalState { + if b.validatorsMultiValue == nil { + return nil + } + v = b.validatorsMultiValue.Value(b) + } else { + if b.validators == nil { + return nil + } + v = b.validators + } + + res := make([]state.ReadOnlyValidator, len(v)) + var err error + for i := 0; i < len(res); i++ { + val := v[i] + if val == nil { + continue + } + res[i], err = NewValidator(val) + if err != nil { + continue + } + } + return res +} + // references of validators participating in consensus on the beacon chain. // This assumes that a lock is already held on BeaconState. This does not // copy fully and instead just copies the reference.