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 = &ethpb.Attestation{}
    99  	case "AttestationData":
   100  		obj = &ethpb.AttestationData{}
   101  	case "AttesterSlashing":
   102  		obj = &ethpb.AttesterSlashing{}
   103  	case "AggregateAndProof":
   104  		obj = &ethpb.AggregateAttestationAndProof{}
   105  	case "BeaconBlock":
   106  		obj = &ethpb.BeaconBlock{}
   107  	case "BeaconBlockBody":
   108  		obj = &ethpb.BeaconBlockBody{}
   109  	case "BeaconBlockHeader":
   110  		obj = &ethpb.BeaconBlockHeader{}
   111  	case "BeaconState":
   112  		obj = &pb.BeaconState{}
   113  	case "Checkpoint":
   114  		obj = &ethpb.Checkpoint{}
   115  	case "Deposit":
   116  		obj = &ethpb.Deposit{}
   117  	case "DepositMessage":
   118  		obj = &pb.DepositMessage{}
   119  	case "DepositData":
   120  		obj = &ethpb.Deposit_Data{}
   121  	case "Eth1Data":
   122  		obj = &ethpb.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 = &ethpb.IndexedAttestation{}
   134  	case "PendingAttestation":
   135  		obj = &pb.PendingAttestation{}
   136  	case "ProposerSlashing":
   137  		obj = &ethpb.ProposerSlashing{}
   138  	case "SignedAggregateAndProof":
   139  		obj = &ethpb.SignedAggregateAttestationAndProof{}
   140  	case "SignedBeaconBlock":
   141  		obj = &ethpb.SignedBeaconBlock{}
   142  	case "SignedBeaconBlockHeader":
   143  		obj = &ethpb.SignedBeaconBlockHeader{}
   144  	case "SignedVoluntaryExit":
   145  		obj = &ethpb.SignedVoluntaryExit{}
   146  	case "SigningData":
   147  		obj = &pb.SigningData{}
   148  	case "Validator":
   149  		obj = &ethpb.Validator{}
   150  	case "VoluntaryExit":
   151  		obj = &ethpb.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  }