github.com/prysmaticlabs/prysm@v1.4.4/beacon-chain/state/v1/field_trie_helpers.go (about)

     1  package v1
     2  
     3  import (
     4  	"fmt"
     5  	"reflect"
     6  
     7  	"github.com/pkg/errors"
     8  	"github.com/prysmaticlabs/prysm/beacon-chain/state/stateutil"
     9  	pb "github.com/prysmaticlabs/prysm/proto/beacon/p2p/v1"
    10  	ethpb "github.com/prysmaticlabs/prysm/proto/eth/v1alpha1"
    11  	"github.com/prysmaticlabs/prysm/shared/hashutil"
    12  )
    13  
    14  func (f *FieldTrie) validateIndices(idxs []uint64) error {
    15  	for _, idx := range idxs {
    16  		if idx >= f.length {
    17  			return errors.Errorf("invalid index for field %s: %d >= length %d", f.field.String(), idx, f.length)
    18  		}
    19  	}
    20  	return nil
    21  }
    22  
    23  func validateElements(field fieldIndex, elements interface{}, length uint64) error {
    24  	val := reflect.ValueOf(elements)
    25  	if val.Len() > int(length) {
    26  		return errors.Errorf("elements length is larger than expected for field %s: %d > %d", field.String(), val.Len(), length)
    27  	}
    28  	return nil
    29  }
    30  
    31  // this converts the corresponding field and the provided elements to the appropriate roots.
    32  func fieldConverters(field fieldIndex, indices []uint64, elements interface{}, convertAll bool) ([][32]byte, error) {
    33  	switch field {
    34  	case blockRoots, stateRoots, randaoMixes:
    35  		val, ok := elements.([][]byte)
    36  		if !ok {
    37  			return nil, errors.Errorf("Wanted type of %v but got %v",
    38  				reflect.TypeOf([][]byte{}).Name(), reflect.TypeOf(elements).Name())
    39  		}
    40  		return stateutil.HandleByteArrays(val, indices, convertAll)
    41  	case eth1DataVotes:
    42  		val, ok := elements.([]*ethpb.Eth1Data)
    43  		if !ok {
    44  			return nil, errors.Errorf("Wanted type of %v but got %v",
    45  				reflect.TypeOf([]*ethpb.Eth1Data{}).Name(), reflect.TypeOf(elements).Name())
    46  		}
    47  		return HandleEth1DataSlice(val, indices, convertAll)
    48  	case validators:
    49  		val, ok := elements.([]*ethpb.Validator)
    50  		if !ok {
    51  			return nil, errors.Errorf("Wanted type of %v but got %v",
    52  				reflect.TypeOf([]*ethpb.Validator{}).Name(), reflect.TypeOf(elements).Name())
    53  		}
    54  		return stateutil.HandleValidatorSlice(val, indices, convertAll)
    55  	case previousEpochAttestations, currentEpochAttestations:
    56  		val, ok := elements.([]*pb.PendingAttestation)
    57  		if !ok {
    58  			return nil, errors.Errorf("Wanted type of %v but got %v",
    59  				reflect.TypeOf([]*pb.PendingAttestation{}).Name(), reflect.TypeOf(elements).Name())
    60  		}
    61  		return handlePendingAttestation(val, indices, convertAll)
    62  	default:
    63  		return [][32]byte{}, errors.Errorf("got unsupported type of %v", reflect.TypeOf(elements).Name())
    64  	}
    65  }
    66  
    67  // HandleEth1DataSlice processes a list of eth1data and indices into the appropriate roots.
    68  func HandleEth1DataSlice(val []*ethpb.Eth1Data, indices []uint64, convertAll bool) ([][32]byte, error) {
    69  	length := len(indices)
    70  	if convertAll {
    71  		length = len(val)
    72  	}
    73  	roots := make([][32]byte, 0, length)
    74  	hasher := hashutil.CustomSHA256Hasher()
    75  	rootCreator := func(input *ethpb.Eth1Data) error {
    76  		newRoot, err := eth1Root(hasher, input)
    77  		if err != nil {
    78  			return err
    79  		}
    80  		roots = append(roots, newRoot)
    81  		return nil
    82  	}
    83  	if convertAll {
    84  		for i := range val {
    85  			err := rootCreator(val[i])
    86  			if err != nil {
    87  				return nil, err
    88  			}
    89  		}
    90  		return roots, nil
    91  	}
    92  	if len(val) > 0 {
    93  		for _, idx := range indices {
    94  			if idx > uint64(len(val))-1 {
    95  				return nil, fmt.Errorf("index %d greater than number of items in eth1 data slice %d", idx, len(val))
    96  			}
    97  			err := rootCreator(val[idx])
    98  			if err != nil {
    99  				return nil, err
   100  			}
   101  		}
   102  	}
   103  	return roots, nil
   104  }
   105  
   106  func handlePendingAttestation(val []*pb.PendingAttestation, indices []uint64, convertAll bool) ([][32]byte, error) {
   107  	length := len(indices)
   108  	if convertAll {
   109  		length = len(val)
   110  	}
   111  	roots := make([][32]byte, 0, length)
   112  	hasher := hashutil.CustomSHA256Hasher()
   113  	rootCreator := func(input *pb.PendingAttestation) error {
   114  		newRoot, err := stateutil.PendingAttRootWithHasher(hasher, input)
   115  		if err != nil {
   116  			return err
   117  		}
   118  		roots = append(roots, newRoot)
   119  		return nil
   120  	}
   121  	if convertAll {
   122  		for i := range val {
   123  			err := rootCreator(val[i])
   124  			if err != nil {
   125  				return nil, err
   126  			}
   127  		}
   128  		return roots, nil
   129  	}
   130  	if len(val) > 0 {
   131  		for _, idx := range indices {
   132  			if idx > uint64(len(val))-1 {
   133  				return nil, fmt.Errorf("index %d greater than number of pending attestations %d", idx, len(val))
   134  			}
   135  			err := rootCreator(val[idx])
   136  			if err != nil {
   137  				return nil, err
   138  			}
   139  		}
   140  	}
   141  	return roots, nil
   142  }