github.com/prysmaticlabs/prysm@v1.4.4/spectest/shared/phase0/ssz_static/ssz_static.go (about) 1 package ssz_static 2 3 import ( 4 "context" 5 "encoding/hex" 6 "errors" 7 "path" 8 "testing" 9 10 fssz "github.com/ferranbt/fastssz" 11 "github.com/golang/snappy" 12 "github.com/prysmaticlabs/prysm/beacon-chain/state/v1" 13 pb "github.com/prysmaticlabs/prysm/proto/beacon/p2p/v1" 14 ethpb "github.com/prysmaticlabs/prysm/proto/eth/v1alpha1" 15 "github.com/prysmaticlabs/prysm/shared/testutil" 16 "github.com/prysmaticlabs/prysm/shared/testutil/require" 17 "github.com/prysmaticlabs/prysm/spectest/utils" 18 ) 19 20 // SSZRoots -- 21 type SSZRoots struct { 22 Root string `json:"root"` 23 SigningRoot string `json:"signing_root"` 24 } 25 26 // RunSSZStaticTests executes "ssz_static" tests. 27 func RunSSZStaticTests(t *testing.T, config string) { 28 require.NoError(t, utils.SetConfig(t, config)) 29 30 testFolders, _ := utils.TestFolders(t, config, "phase0", "ssz_static") 31 for _, folder := range testFolders { 32 innerPath := path.Join("ssz_static", folder.Name(), "ssz_random") 33 innerTestFolders, innerTestsFolderPath := utils.TestFolders(t, config, "phase0", innerPath) 34 35 for _, innerFolder := range innerTestFolders { 36 t.Run(path.Join(folder.Name(), innerFolder.Name()), func(t *testing.T) { 37 serializedBytes, err := testutil.BazelFileBytes(innerTestsFolderPath, innerFolder.Name(), "serialized.ssz_snappy") 38 require.NoError(t, err) 39 serializedSSZ, err := snappy.Decode(nil /* dst */, serializedBytes) 40 require.NoError(t, err, "Failed to decompress") 41 object, err := UnmarshalledSSZ(t, serializedSSZ, folder.Name()) 42 require.NoError(t, err, "Could not unmarshall serialized SSZ") 43 44 rootsYamlFile, err := testutil.BazelFileBytes(innerTestsFolderPath, innerFolder.Name(), "roots.yaml") 45 require.NoError(t, err) 46 rootsYaml := &SSZRoots{} 47 require.NoError(t, utils.UnmarshalYaml(rootsYamlFile, rootsYaml), "Failed to Unmarshal") 48 49 // Custom hash tree root for beacon state. 50 var htr func(interface{}) ([32]byte, error) 51 if _, ok := object.(*pb.BeaconState); ok { 52 htr = func(s interface{}) ([32]byte, error) { 53 beaconState, err := v1.InitializeFromProto(s.(*pb.BeaconState)) 54 require.NoError(t, err) 55 return beaconState.HashTreeRoot(context.Background()) 56 } 57 } else { 58 htr = func(s interface{}) ([32]byte, error) { 59 sszObj, ok := s.(fssz.HashRoot) 60 if !ok { 61 return [32]byte{}, errors.New("could not get hash root, not compatible object") 62 } 63 return sszObj.HashTreeRoot() 64 } 65 } 66 67 root, err := htr(object) 68 require.NoError(t, err) 69 rootBytes, err := hex.DecodeString(rootsYaml.Root[2:]) 70 require.NoError(t, err) 71 require.DeepEqual(t, rootBytes, root[:], "Did not receive expected hash tree root") 72 73 if rootsYaml.SigningRoot == "" { 74 return 75 } 76 77 var signingRoot [32]byte 78 if v, ok := object.(fssz.HashRoot); ok { 79 signingRoot, err = v.HashTreeRoot() 80 } else { 81 t.Fatal("object does not meet fssz.HashRoot") 82 } 83 84 require.NoError(t, err) 85 signingRootBytes, err := hex.DecodeString(rootsYaml.SigningRoot[2:]) 86 require.NoError(t, err) 87 require.DeepEqual(t, signingRootBytes, signingRoot[:], "Did not receive expected signing root") 88 }) 89 } 90 } 91 } 92 93 // UnmarshalledSSZ unmarshalls serialized input. 94 func UnmarshalledSSZ(t *testing.T, serializedBytes []byte, folderName string) (interface{}, error) { 95 var obj interface{} 96 switch folderName { 97 case "Attestation": 98 obj = ðpb.Attestation{} 99 case "AttestationData": 100 obj = ðpb.AttestationData{} 101 case "AttesterSlashing": 102 obj = ðpb.AttesterSlashing{} 103 case "AggregateAndProof": 104 obj = ðpb.AggregateAttestationAndProof{} 105 case "BeaconBlock": 106 obj = ðpb.BeaconBlock{} 107 case "BeaconBlockBody": 108 obj = ðpb.BeaconBlockBody{} 109 case "BeaconBlockHeader": 110 obj = ðpb.BeaconBlockHeader{} 111 case "BeaconState": 112 obj = &pb.BeaconState{} 113 case "Checkpoint": 114 obj = ðpb.Checkpoint{} 115 case "Deposit": 116 obj = ðpb.Deposit{} 117 case "DepositMessage": 118 obj = &pb.DepositMessage{} 119 case "DepositData": 120 obj = ðpb.Deposit_Data{} 121 case "Eth1Data": 122 obj = ðpb.Eth1Data{} 123 case "Eth1Block": 124 t.Skip("Unused type") 125 return nil, nil 126 case "Fork": 127 obj = &pb.Fork{} 128 case "ForkData": 129 obj = &pb.ForkData{} 130 case "HistoricalBatch": 131 obj = &pb.HistoricalBatch{} 132 case "IndexedAttestation": 133 obj = ðpb.IndexedAttestation{} 134 case "PendingAttestation": 135 obj = &pb.PendingAttestation{} 136 case "ProposerSlashing": 137 obj = ðpb.ProposerSlashing{} 138 case "SignedAggregateAndProof": 139 obj = ðpb.SignedAggregateAttestationAndProof{} 140 case "SignedBeaconBlock": 141 obj = ðpb.SignedBeaconBlock{} 142 case "SignedBeaconBlockHeader": 143 obj = ðpb.SignedBeaconBlockHeader{} 144 case "SignedVoluntaryExit": 145 obj = ðpb.SignedVoluntaryExit{} 146 case "SigningData": 147 obj = &pb.SigningData{} 148 case "Validator": 149 obj = ðpb.Validator{} 150 case "VoluntaryExit": 151 obj = ðpb.VoluntaryExit{} 152 default: 153 return nil, errors.New("type not found") 154 } 155 var err error 156 if o, ok := obj.(fssz.Unmarshaler); ok { 157 err = o.UnmarshalSSZ(serializedBytes) 158 } else { 159 err = errors.New("could not unmarshal object, not a fastssz compatible object") 160 } 161 return obj, err 162 }