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 }