github.com/prysmaticlabs/prysm@v1.4.4/spectest/shared/phase0/sanity/block_processing.go (about)

     1  package sanity
     2  
     3  import (
     4  	"context"
     5  	"fmt"
     6  	"io/ioutil"
     7  	"path"
     8  	"strings"
     9  	"testing"
    10  
    11  	"github.com/bazelbuild/rules_go/go/tools/bazel"
    12  	"github.com/golang/snappy"
    13  	"github.com/prysmaticlabs/prysm/beacon-chain/core/helpers"
    14  	"github.com/prysmaticlabs/prysm/beacon-chain/core/state"
    15  	iface "github.com/prysmaticlabs/prysm/beacon-chain/state/interface"
    16  	"github.com/prysmaticlabs/prysm/beacon-chain/state/v1"
    17  	pb "github.com/prysmaticlabs/prysm/proto/beacon/p2p/v1"
    18  	ethpb "github.com/prysmaticlabs/prysm/proto/eth/v1alpha1"
    19  	"github.com/prysmaticlabs/prysm/proto/eth/v1alpha1/wrapper"
    20  	"github.com/prysmaticlabs/prysm/shared/testutil"
    21  	"github.com/prysmaticlabs/prysm/shared/testutil/require"
    22  	"github.com/prysmaticlabs/prysm/spectest/utils"
    23  	"google.golang.org/protobuf/proto"
    24  	"gopkg.in/d4l3k/messagediff.v1"
    25  )
    26  
    27  func init() {
    28  	state.SkipSlotCache.Disable()
    29  }
    30  
    31  // RunBlockProcessingTest executes "sanity/blocks" tests.
    32  func RunBlockProcessingTest(t *testing.T, config string) {
    33  	require.NoError(t, utils.SetConfig(t, config))
    34  
    35  	testFolders, testsFolderPath := utils.TestFolders(t, config, "phase0", "sanity/blocks/pyspec_tests")
    36  	for _, folder := range testFolders {
    37  		t.Run(folder.Name(), func(t *testing.T) {
    38  			helpers.ClearCache()
    39  			preBeaconStateFile, err := testutil.BazelFileBytes(testsFolderPath, folder.Name(), "pre.ssz_snappy")
    40  			require.NoError(t, err)
    41  			preBeaconStateSSZ, err := snappy.Decode(nil /* dst */, preBeaconStateFile)
    42  			require.NoError(t, err, "Failed to decompress")
    43  			beaconStateBase := &pb.BeaconState{}
    44  			require.NoError(t, beaconStateBase.UnmarshalSSZ(preBeaconStateSSZ), "Failed to unmarshal")
    45  			beaconState, err := v1.InitializeFromProto(beaconStateBase)
    46  			require.NoError(t, err)
    47  
    48  			file, err := testutil.BazelFileBytes(testsFolderPath, folder.Name(), "meta.yaml")
    49  			require.NoError(t, err)
    50  
    51  			metaYaml := &SanityConfig{}
    52  			require.NoError(t, utils.UnmarshalYaml(file, metaYaml), "Failed to Unmarshal")
    53  
    54  			var transitionError error
    55  			var processedState iface.BeaconState
    56  			var ok bool
    57  			for i := 0; i < metaYaml.BlocksCount; i++ {
    58  				filename := fmt.Sprintf("blocks_%d.ssz_snappy", i)
    59  				blockFile, err := testutil.BazelFileBytes(testsFolderPath, folder.Name(), filename)
    60  				require.NoError(t, err)
    61  				blockSSZ, err := snappy.Decode(nil /* dst */, blockFile)
    62  				require.NoError(t, err, "Failed to decompress")
    63  				block := &ethpb.SignedBeaconBlock{}
    64  				require.NoError(t, block.UnmarshalSSZ(blockSSZ), "Failed to unmarshal")
    65  				processedState, transitionError = state.ExecuteStateTransition(context.Background(), beaconState, wrapper.WrappedPhase0SignedBeaconBlock(block))
    66  				if transitionError != nil {
    67  					break
    68  				}
    69  				beaconState, ok = processedState.(*v1.BeaconState)
    70  				require.Equal(t, true, ok)
    71  			}
    72  
    73  			// If the post.ssz is not present, it means the test should fail on our end.
    74  			postSSZFilepath, readError := bazel.Runfile(path.Join(testsFolderPath, folder.Name(), "post.ssz_snappy"))
    75  			postSSZExists := true
    76  			if readError != nil && strings.Contains(readError.Error(), "could not locate file") {
    77  				postSSZExists = false
    78  			} else if readError != nil {
    79  				t.Fatal(readError)
    80  			}
    81  
    82  			if postSSZExists {
    83  				if transitionError != nil {
    84  					t.Errorf("Unexpected error: %v", transitionError)
    85  				}
    86  
    87  				postBeaconStateFile, err := ioutil.ReadFile(postSSZFilepath)
    88  				require.NoError(t, err)
    89  				postBeaconStateSSZ, err := snappy.Decode(nil /* dst */, postBeaconStateFile)
    90  				require.NoError(t, err, "Failed to decompress")
    91  
    92  				postBeaconState := &pb.BeaconState{}
    93  				require.NoError(t, postBeaconState.UnmarshalSSZ(postBeaconStateSSZ), "Failed to unmarshal")
    94  				pbState, err := v1.ProtobufBeaconState(beaconState.InnerStateUnsafe())
    95  				require.NoError(t, err)
    96  				if !proto.Equal(pbState, postBeaconState) {
    97  					diff, _ := messagediff.PrettyDiff(beaconState.InnerStateUnsafe(), postBeaconState)
    98  					t.Log(diff)
    99  					t.Fatal("Post state does not match expected")
   100  				}
   101  			} else {
   102  				// Note: This doesn't test anything worthwhile. It essentially tests
   103  				// that *any* error has occurred, not any specific error.
   104  				if transitionError == nil {
   105  					t.Fatal("Did not fail when expected")
   106  				}
   107  				t.Logf("Expected failure; failure reason = %v", transitionError)
   108  				return
   109  			}
   110  		})
   111  	}
   112  }