2021-08-09 21:54:24 +00:00
|
|
|
package fieldtrie
|
2021-04-12 14:23:55 +00:00
|
|
|
|
|
|
|
import (
|
|
|
|
"fmt"
|
|
|
|
"reflect"
|
|
|
|
|
|
|
|
"github.com/pkg/errors"
|
|
|
|
"github.com/prysmaticlabs/prysm/beacon-chain/state/stateutil"
|
2021-08-09 21:54:24 +00:00
|
|
|
"github.com/prysmaticlabs/prysm/beacon-chain/state/types"
|
2021-09-15 22:55:11 +00:00
|
|
|
"github.com/prysmaticlabs/prysm/crypto/hash"
|
2021-07-21 21:34:07 +00:00
|
|
|
ethpb "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1"
|
2021-09-16 09:46:29 +00:00
|
|
|
"github.com/prysmaticlabs/prysm/runtime/version"
|
2021-04-12 14:23:55 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
func (f *FieldTrie) validateIndices(idxs []uint64) error {
|
|
|
|
for _, idx := range idxs {
|
|
|
|
if idx >= f.length {
|
2021-08-09 21:54:24 +00:00
|
|
|
return errors.Errorf("invalid index for field %s: %d >= length %d", f.field.String(version.Phase0), idx, f.length)
|
2021-04-12 14:23:55 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2021-08-09 21:54:24 +00:00
|
|
|
func validateElements(field types.FieldIndex, elements interface{}, length uint64) error {
|
2021-04-12 14:23:55 +00:00
|
|
|
val := reflect.ValueOf(elements)
|
|
|
|
if val.Len() > int(length) {
|
2021-08-09 21:54:24 +00:00
|
|
|
return errors.Errorf("elements length is larger than expected for field %s: %d > %d", field.String(version.Phase0), val.Len(), length)
|
2021-04-12 14:23:55 +00:00
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2021-08-06 10:47:50 +00:00
|
|
|
// fieldConverters converts the corresponding field and the provided elements to the appropriate roots.
|
2021-08-09 21:54:24 +00:00
|
|
|
func fieldConverters(field types.FieldIndex, indices []uint64, elements interface{}, convertAll bool) ([][32]byte, error) {
|
2021-04-12 14:23:55 +00:00
|
|
|
switch field {
|
2021-08-09 21:54:24 +00:00
|
|
|
case types.BlockRoots, types.StateRoots, types.RandaoMixes:
|
2021-04-12 14:23:55 +00:00
|
|
|
val, ok := elements.([][]byte)
|
|
|
|
if !ok {
|
|
|
|
return nil, errors.Errorf("Wanted type of %v but got %v",
|
|
|
|
reflect.TypeOf([][]byte{}).Name(), reflect.TypeOf(elements).Name())
|
|
|
|
}
|
|
|
|
return stateutil.HandleByteArrays(val, indices, convertAll)
|
2021-08-09 21:54:24 +00:00
|
|
|
case types.Eth1DataVotes:
|
2021-04-12 14:23:55 +00:00
|
|
|
val, ok := elements.([]*ethpb.Eth1Data)
|
|
|
|
if !ok {
|
|
|
|
return nil, errors.Errorf("Wanted type of %v but got %v",
|
|
|
|
reflect.TypeOf([]*ethpb.Eth1Data{}).Name(), reflect.TypeOf(elements).Name())
|
|
|
|
}
|
2021-05-19 16:11:48 +00:00
|
|
|
return HandleEth1DataSlice(val, indices, convertAll)
|
2021-08-09 21:54:24 +00:00
|
|
|
case types.Validators:
|
2021-04-12 14:23:55 +00:00
|
|
|
val, ok := elements.([]*ethpb.Validator)
|
|
|
|
if !ok {
|
|
|
|
return nil, errors.Errorf("Wanted type of %v but got %v",
|
|
|
|
reflect.TypeOf([]*ethpb.Validator{}).Name(), reflect.TypeOf(elements).Name())
|
|
|
|
}
|
|
|
|
return stateutil.HandleValidatorSlice(val, indices, convertAll)
|
2021-08-09 21:54:24 +00:00
|
|
|
case types.PreviousEpochAttestations, types.CurrentEpochAttestations:
|
2021-07-29 21:45:17 +00:00
|
|
|
val, ok := elements.([]*ethpb.PendingAttestation)
|
2021-04-12 14:23:55 +00:00
|
|
|
if !ok {
|
|
|
|
return nil, errors.Errorf("Wanted type of %v but got %v",
|
2021-07-29 21:45:17 +00:00
|
|
|
reflect.TypeOf([]*ethpb.PendingAttestation{}).Name(), reflect.TypeOf(elements).Name())
|
2021-04-12 14:23:55 +00:00
|
|
|
}
|
|
|
|
return handlePendingAttestation(val, indices, convertAll)
|
|
|
|
default:
|
|
|
|
return [][32]byte{}, errors.Errorf("got unsupported type of %v", reflect.TypeOf(elements).Name())
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-05-19 16:11:48 +00:00
|
|
|
// HandleEth1DataSlice processes a list of eth1data and indices into the appropriate roots.
|
|
|
|
func HandleEth1DataSlice(val []*ethpb.Eth1Data, indices []uint64, convertAll bool) ([][32]byte, error) {
|
2021-04-12 14:23:55 +00:00
|
|
|
length := len(indices)
|
|
|
|
if convertAll {
|
|
|
|
length = len(val)
|
|
|
|
}
|
|
|
|
roots := make([][32]byte, 0, length)
|
2021-09-15 22:55:11 +00:00
|
|
|
hasher := hash.CustomSHA256Hasher()
|
2021-04-12 14:23:55 +00:00
|
|
|
rootCreator := func(input *ethpb.Eth1Data) error {
|
2021-08-09 21:54:24 +00:00
|
|
|
newRoot, err := stateutil.Eth1DataRootWithHasher(hasher, input)
|
2021-04-12 14:23:55 +00:00
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
roots = append(roots, newRoot)
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
if convertAll {
|
|
|
|
for i := range val {
|
|
|
|
err := rootCreator(val[i])
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return roots, nil
|
|
|
|
}
|
|
|
|
if len(val) > 0 {
|
|
|
|
for _, idx := range indices {
|
|
|
|
if idx > uint64(len(val))-1 {
|
|
|
|
return nil, fmt.Errorf("index %d greater than number of items in eth1 data slice %d", idx, len(val))
|
|
|
|
}
|
|
|
|
err := rootCreator(val[idx])
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return roots, nil
|
|
|
|
}
|
|
|
|
|
2021-07-29 21:45:17 +00:00
|
|
|
func handlePendingAttestation(val []*ethpb.PendingAttestation, indices []uint64, convertAll bool) ([][32]byte, error) {
|
2021-04-12 14:23:55 +00:00
|
|
|
length := len(indices)
|
|
|
|
if convertAll {
|
|
|
|
length = len(val)
|
|
|
|
}
|
|
|
|
roots := make([][32]byte, 0, length)
|
2021-09-15 22:55:11 +00:00
|
|
|
hasher := hash.CustomSHA256Hasher()
|
2021-07-29 21:45:17 +00:00
|
|
|
rootCreator := func(input *ethpb.PendingAttestation) error {
|
2021-04-12 14:23:55 +00:00
|
|
|
newRoot, err := stateutil.PendingAttRootWithHasher(hasher, input)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
roots = append(roots, newRoot)
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
if convertAll {
|
|
|
|
for i := range val {
|
|
|
|
err := rootCreator(val[i])
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return roots, nil
|
|
|
|
}
|
|
|
|
if len(val) > 0 {
|
|
|
|
for _, idx := range indices {
|
|
|
|
if idx > uint64(len(val))-1 {
|
|
|
|
return nil, fmt.Errorf("index %d greater than number of pending attestations %d", idx, len(val))
|
|
|
|
}
|
|
|
|
err := rootCreator(val[idx])
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return roots, nil
|
|
|
|
}
|