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

     1  package operations
     2  
     3  import (
     4  	"context"
     5  	"io/ioutil"
     6  	"path"
     7  	"strings"
     8  	"testing"
     9  
    10  	"github.com/bazelbuild/rules_go/go/tools/bazel"
    11  	"github.com/golang/snappy"
    12  	"github.com/prysmaticlabs/prysm/beacon-chain/core/helpers"
    13  	iface "github.com/prysmaticlabs/prysm/beacon-chain/state/interface"
    14  	"github.com/prysmaticlabs/prysm/beacon-chain/state/v1"
    15  	pb "github.com/prysmaticlabs/prysm/proto/beacon/p2p/v1"
    16  	ethpb "github.com/prysmaticlabs/prysm/proto/eth/v1alpha1"
    17  	"github.com/prysmaticlabs/prysm/proto/eth/v1alpha1/wrapper"
    18  	"github.com/prysmaticlabs/prysm/proto/interfaces"
    19  	"github.com/prysmaticlabs/prysm/shared/testutil"
    20  	"github.com/prysmaticlabs/prysm/shared/testutil/require"
    21  	"google.golang.org/protobuf/proto"
    22  	"gopkg.in/d4l3k/messagediff.v1"
    23  )
    24  
    25  type blockOperation func(context.Context, iface.BeaconState, interfaces.SignedBeaconBlock) (iface.BeaconState, error)
    26  
    27  // RunBlockOperationTest takes in the prestate and the beacon block body, processes it through the
    28  // passed in block operation function and checks the post state with the expected post state.
    29  func RunBlockOperationTest(
    30  	t *testing.T,
    31  	folderPath string,
    32  	body *ethpb.BeaconBlockBody,
    33  	operationFn blockOperation,
    34  ) {
    35  	preBeaconStateFile, err := testutil.BazelFileBytes(path.Join(folderPath, "pre.ssz_snappy"))
    36  	require.NoError(t, err)
    37  	preBeaconStateSSZ, err := snappy.Decode(nil /* dst */, preBeaconStateFile)
    38  	require.NoError(t, err, "Failed to decompress")
    39  	preStateBase := &pb.BeaconState{}
    40  	if err := preStateBase.UnmarshalSSZ(preBeaconStateSSZ); err != nil {
    41  		t.Fatalf("Failed to unmarshal: %v", err)
    42  	}
    43  	preState, err := v1.InitializeFromProto(preStateBase)
    44  	require.NoError(t, err)
    45  
    46  	// If the post.ssz is not present, it means the test should fail on our end.
    47  	postSSZFilepath, err := bazel.Runfile(path.Join(folderPath, "post.ssz_snappy"))
    48  	postSSZExists := true
    49  	if err != nil && strings.Contains(err.Error(), "could not locate file") {
    50  		postSSZExists = false
    51  	} else if err != nil {
    52  		t.Fatal(err)
    53  	}
    54  
    55  	helpers.ClearCache()
    56  	b := testutil.NewBeaconBlock()
    57  	b.Block.Body = body
    58  	beaconState, err := operationFn(context.Background(), preState, wrapper.WrappedPhase0SignedBeaconBlock(b))
    59  	if postSSZExists {
    60  		require.NoError(t, err)
    61  
    62  		postBeaconStateFile, err := ioutil.ReadFile(postSSZFilepath)
    63  		require.NoError(t, err)
    64  		postBeaconStateSSZ, err := snappy.Decode(nil /* dst */, postBeaconStateFile)
    65  		require.NoError(t, err, "Failed to decompress")
    66  
    67  		postBeaconState := &pb.BeaconState{}
    68  		if err := postBeaconState.UnmarshalSSZ(postBeaconStateSSZ); err != nil {
    69  			t.Fatalf("Failed to unmarshal: %v", err)
    70  		}
    71  		pbState, err := v1.ProtobufBeaconState(beaconState.InnerStateUnsafe())
    72  		require.NoError(t, err)
    73  		if !proto.Equal(pbState, postBeaconState) {
    74  			diff, _ := messagediff.PrettyDiff(beaconState.InnerStateUnsafe(), postBeaconState)
    75  			t.Log(diff)
    76  			t.Fatal("Post state does not match expected")
    77  		}
    78  	} else {
    79  		// Note: This doesn't test anything worthwhile. It essentially tests
    80  		// that *any* error has occurred, not any specific error.
    81  		if err == nil {
    82  			t.Fatal("Did not fail when expected")
    83  		}
    84  		t.Logf("Expected failure; failure reason = %v", err)
    85  		return
    86  	}
    87  }