From dfd740414f9d5c39b637af07237d7f5f77f26d36 Mon Sep 17 00:00:00 2001 From: Preston Van Loon Date: Wed, 18 Aug 2021 17:01:05 -0500 Subject: [PATCH] Altair: operations spectests (#9413) * Update spectests to v1.1.0-beta.1 from hf1 branch * fix params loading * Altair: operations spectests * gazelle and nosec on trusted variable inputs * remove legacy statement from spectest/minimal/altair/operations/BUILD.bazel --- beacon-chain/core/altair/BUILD.bazel | 1 + beacon-chain/state/v2/BUILD.bazel | 1 + .../mainnet/altair/operations/BUILD.bazel | 21 +++++ .../altair/operations/attestation_test.go | 11 +++ .../operations/attester_slashing_test.go | 11 +++ .../altair/operations/block_header_test.go | 11 +++ .../mainnet/altair/operations/deposit_test.go | 11 +++ .../operations/proposer_slashing_test.go | 11 +++ .../altair/operations/sync_committee_test.go | 11 +++ .../altair/operations/voluntary_exit_test.go | 11 +++ .../minimal/altair/operations/BUILD.bazel | 24 +++++ .../altair/operations/attestation_test.go | 11 +++ .../operations/attester_slashing_test.go | 11 +++ .../altair/operations/block_header_test.go | 11 +++ .../minimal/altair/operations/deposit_test.go | 11 +++ .../operations/proposer_slashing_test.go | 11 +++ .../altair/operations/sync_committee_test.go | 11 +++ .../altair/operations/voluntary_exit_test.go | 11 +++ spectest/shared/altair/operations/BUILD.bazel | 36 ++++++++ .../shared/altair/operations/attestation.go | 56 ++++++++++++ .../altair/operations/attester_slashing.go | 38 ++++++++ .../shared/altair/operations/block_header.go | 83 +++++++++++++++++ spectest/shared/altair/operations/deposit.go | 38 ++++++++ spectest/shared/altair/operations/helpers.go | 88 +++++++++++++++++++ .../altair/operations/proposer_slashing.go | 38 ++++++++ .../altair/operations/sync_committee.go | 37 ++++++++ .../altair/operations/voluntary_exit.go | 37 ++++++++ 27 files changed, 652 insertions(+) create mode 100644 spectest/mainnet/altair/operations/BUILD.bazel create mode 100644 spectest/mainnet/altair/operations/attestation_test.go create mode 100644 spectest/mainnet/altair/operations/attester_slashing_test.go create mode 100644 spectest/mainnet/altair/operations/block_header_test.go create mode 100644 spectest/mainnet/altair/operations/deposit_test.go create mode 100644 spectest/mainnet/altair/operations/proposer_slashing_test.go create mode 100644 spectest/mainnet/altair/operations/sync_committee_test.go create mode 100644 spectest/mainnet/altair/operations/voluntary_exit_test.go create mode 100644 spectest/minimal/altair/operations/BUILD.bazel create mode 100644 spectest/minimal/altair/operations/attestation_test.go create mode 100644 spectest/minimal/altair/operations/attester_slashing_test.go create mode 100644 spectest/minimal/altair/operations/block_header_test.go create mode 100644 spectest/minimal/altair/operations/deposit_test.go create mode 100644 spectest/minimal/altair/operations/proposer_slashing_test.go create mode 100644 spectest/minimal/altair/operations/sync_committee_test.go create mode 100644 spectest/minimal/altair/operations/voluntary_exit_test.go create mode 100644 spectest/shared/altair/operations/BUILD.bazel create mode 100644 spectest/shared/altair/operations/attestation.go create mode 100644 spectest/shared/altair/operations/attester_slashing.go create mode 100644 spectest/shared/altair/operations/block_header.go create mode 100644 spectest/shared/altair/operations/deposit.go create mode 100644 spectest/shared/altair/operations/helpers.go create mode 100644 spectest/shared/altair/operations/proposer_slashing.go create mode 100644 spectest/shared/altair/operations/sync_committee.go create mode 100644 spectest/shared/altair/operations/voluntary_exit.go diff --git a/beacon-chain/core/altair/BUILD.bazel b/beacon-chain/core/altair/BUILD.bazel index 86510de7f9..e8a0a570fb 100644 --- a/beacon-chain/core/altair/BUILD.bazel +++ b/beacon-chain/core/altair/BUILD.bazel @@ -15,6 +15,7 @@ go_library( visibility = [ "//beacon-chain:__subpackages__", "//shared/testutil:__pkg__", + "//spectest:__subpackages__", ], deps = [ "//beacon-chain/core/blocks:go_default_library", diff --git a/beacon-chain/state/v2/BUILD.bazel b/beacon-chain/state/v2/BUILD.bazel index 0dfadde849..6764a639c0 100644 --- a/beacon-chain/state/v2/BUILD.bazel +++ b/beacon-chain/state/v2/BUILD.bazel @@ -20,6 +20,7 @@ go_library( visibility = [ "//beacon-chain:__subpackages__", "//shared/testutil:__pkg__", + "//spectest:__subpackages__", ], deps = [ "//beacon-chain/state:go_default_library", diff --git a/spectest/mainnet/altair/operations/BUILD.bazel b/spectest/mainnet/altair/operations/BUILD.bazel new file mode 100644 index 0000000000..7307b21c78 --- /dev/null +++ b/spectest/mainnet/altair/operations/BUILD.bazel @@ -0,0 +1,21 @@ +load("@prysm//tools/go:def.bzl", "go_test") + +go_test( + name = "go_default_test", + size = "small", + srcs = [ + "attestation_test.go", + "attester_slashing_test.go", + "block_header_test.go", + "deposit_test.go", + "proposer_slashing_test.go", + "sync_committee_test.go", + "voluntary_exit_test.go", + ], + data = glob(["*.yaml"]) + [ + "@eth2_spec_tests_mainnet//:test_data", + ], + shard_count = 4, + tags = ["spectest"], + deps = ["//spectest/shared/altair/operations:go_default_library"], +) diff --git a/spectest/mainnet/altair/operations/attestation_test.go b/spectest/mainnet/altair/operations/attestation_test.go new file mode 100644 index 0000000000..ff734edef8 --- /dev/null +++ b/spectest/mainnet/altair/operations/attestation_test.go @@ -0,0 +1,11 @@ +package operations + +import ( + "testing" + + "github.com/prysmaticlabs/prysm/spectest/shared/altair/operations" +) + +func TestMainnet_Altair_Operations_Attestation(t *testing.T) { + operations.RunAttestationTest(t, "mainnet") +} diff --git a/spectest/mainnet/altair/operations/attester_slashing_test.go b/spectest/mainnet/altair/operations/attester_slashing_test.go new file mode 100644 index 0000000000..187c57b3de --- /dev/null +++ b/spectest/mainnet/altair/operations/attester_slashing_test.go @@ -0,0 +1,11 @@ +package operations + +import ( + "testing" + + "github.com/prysmaticlabs/prysm/spectest/shared/altair/operations" +) + +func TestMainnet_Altair_Operations_AttesterSlashing(t *testing.T) { + operations.RunAttesterSlashingTest(t, "mainnet") +} diff --git a/spectest/mainnet/altair/operations/block_header_test.go b/spectest/mainnet/altair/operations/block_header_test.go new file mode 100644 index 0000000000..4d4d7671d3 --- /dev/null +++ b/spectest/mainnet/altair/operations/block_header_test.go @@ -0,0 +1,11 @@ +package operations + +import ( + "testing" + + "github.com/prysmaticlabs/prysm/spectest/shared/altair/operations" +) + +func TestMainnet_Altair_Operations_BlockHeader(t *testing.T) { + operations.RunBlockHeaderTest(t, "mainnet") +} diff --git a/spectest/mainnet/altair/operations/deposit_test.go b/spectest/mainnet/altair/operations/deposit_test.go new file mode 100644 index 0000000000..1bac2c6f02 --- /dev/null +++ b/spectest/mainnet/altair/operations/deposit_test.go @@ -0,0 +1,11 @@ +package operations + +import ( + "testing" + + "github.com/prysmaticlabs/prysm/spectest/shared/altair/operations" +) + +func TestMainnet_Altair_Operations_Deposit(t *testing.T) { + operations.RunDepositTest(t, "mainnet") +} diff --git a/spectest/mainnet/altair/operations/proposer_slashing_test.go b/spectest/mainnet/altair/operations/proposer_slashing_test.go new file mode 100644 index 0000000000..205e0f3eff --- /dev/null +++ b/spectest/mainnet/altair/operations/proposer_slashing_test.go @@ -0,0 +1,11 @@ +package operations + +import ( + "testing" + + "github.com/prysmaticlabs/prysm/spectest/shared/altair/operations" +) + +func TestMainnet_Altair_Operations_ProposerSlashing(t *testing.T) { + operations.RunProposerSlashingTest(t, "mainnet") +} diff --git a/spectest/mainnet/altair/operations/sync_committee_test.go b/spectest/mainnet/altair/operations/sync_committee_test.go new file mode 100644 index 0000000000..375973739e --- /dev/null +++ b/spectest/mainnet/altair/operations/sync_committee_test.go @@ -0,0 +1,11 @@ +package operations + +import ( + "testing" + + "github.com/prysmaticlabs/prysm/spectest/shared/altair/operations" +) + +func TestMainnet_Altair_Operations_SyncCommittee(t *testing.T) { + operations.RunSyncCommitteeTest(t, "mainnet") +} diff --git a/spectest/mainnet/altair/operations/voluntary_exit_test.go b/spectest/mainnet/altair/operations/voluntary_exit_test.go new file mode 100644 index 0000000000..462d089f71 --- /dev/null +++ b/spectest/mainnet/altair/operations/voluntary_exit_test.go @@ -0,0 +1,11 @@ +package operations + +import ( + "testing" + + "github.com/prysmaticlabs/prysm/spectest/shared/altair/operations" +) + +func TestMainnet_Altair_Operations_VoluntaryExit(t *testing.T) { + operations.RunVoluntaryExitTest(t, "mainnet") +} diff --git a/spectest/minimal/altair/operations/BUILD.bazel b/spectest/minimal/altair/operations/BUILD.bazel new file mode 100644 index 0000000000..361dac60b8 --- /dev/null +++ b/spectest/minimal/altair/operations/BUILD.bazel @@ -0,0 +1,24 @@ +load("@prysm//tools/go:def.bzl", "go_test") + +go_test( + name = "go_default_test", + size = "small", + srcs = [ + "attestation_test.go", + "attester_slashing_test.go", + "block_header_test.go", + "deposit_test.go", + "proposer_slashing_test.go", + "sync_committee_test.go", + "voluntary_exit_test.go", + ], + data = glob(["*.yaml"]) + [ + "@eth2_spec_tests_minimal//:test_data", + ], + eth_network = "minimal", + tags = [ + "minimal", + "spectest", + ], + deps = ["//spectest/shared/altair/operations:go_default_library"], +) diff --git a/spectest/minimal/altair/operations/attestation_test.go b/spectest/minimal/altair/operations/attestation_test.go new file mode 100644 index 0000000000..07b87d8251 --- /dev/null +++ b/spectest/minimal/altair/operations/attestation_test.go @@ -0,0 +1,11 @@ +package operations + +import ( + "testing" + + "github.com/prysmaticlabs/prysm/spectest/shared/altair/operations" +) + +func TestMinimal_Altair_Operations_Attestation(t *testing.T) { + operations.RunAttestationTest(t, "minimal") +} diff --git a/spectest/minimal/altair/operations/attester_slashing_test.go b/spectest/minimal/altair/operations/attester_slashing_test.go new file mode 100644 index 0000000000..ad3efa1eaa --- /dev/null +++ b/spectest/minimal/altair/operations/attester_slashing_test.go @@ -0,0 +1,11 @@ +package operations + +import ( + "testing" + + "github.com/prysmaticlabs/prysm/spectest/shared/altair/operations" +) + +func TestMinimal_Altair_Operations_AttesterSlashing(t *testing.T) { + operations.RunAttesterSlashingTest(t, "minimal") +} diff --git a/spectest/minimal/altair/operations/block_header_test.go b/spectest/minimal/altair/operations/block_header_test.go new file mode 100644 index 0000000000..aab42869a7 --- /dev/null +++ b/spectest/minimal/altair/operations/block_header_test.go @@ -0,0 +1,11 @@ +package operations + +import ( + "testing" + + "github.com/prysmaticlabs/prysm/spectest/shared/altair/operations" +) + +func TestMinimal_Altair_Operations_BlockHeader(t *testing.T) { + operations.RunBlockHeaderTest(t, "minimal") +} diff --git a/spectest/minimal/altair/operations/deposit_test.go b/spectest/minimal/altair/operations/deposit_test.go new file mode 100644 index 0000000000..9ba8026aac --- /dev/null +++ b/spectest/minimal/altair/operations/deposit_test.go @@ -0,0 +1,11 @@ +package operations + +import ( + "testing" + + "github.com/prysmaticlabs/prysm/spectest/shared/altair/operations" +) + +func TestMinimal_Altair_Operations_Deposit(t *testing.T) { + operations.RunDepositTest(t, "minimal") +} diff --git a/spectest/minimal/altair/operations/proposer_slashing_test.go b/spectest/minimal/altair/operations/proposer_slashing_test.go new file mode 100644 index 0000000000..702eebb052 --- /dev/null +++ b/spectest/minimal/altair/operations/proposer_slashing_test.go @@ -0,0 +1,11 @@ +package operations + +import ( + "testing" + + "github.com/prysmaticlabs/prysm/spectest/shared/altair/operations" +) + +func TestMinimal_Altair_Operations_ProposerSlashing(t *testing.T) { + operations.RunProposerSlashingTest(t, "minimal") +} diff --git a/spectest/minimal/altair/operations/sync_committee_test.go b/spectest/minimal/altair/operations/sync_committee_test.go new file mode 100644 index 0000000000..610a9b3365 --- /dev/null +++ b/spectest/minimal/altair/operations/sync_committee_test.go @@ -0,0 +1,11 @@ +package operations + +import ( + "testing" + + "github.com/prysmaticlabs/prysm/spectest/shared/altair/operations" +) + +func TestMinimal_Altair_Operations_SyncCommittee(t *testing.T) { + operations.RunProposerSlashingTest(t, "minimal") +} diff --git a/spectest/minimal/altair/operations/voluntary_exit_test.go b/spectest/minimal/altair/operations/voluntary_exit_test.go new file mode 100644 index 0000000000..3cdee57539 --- /dev/null +++ b/spectest/minimal/altair/operations/voluntary_exit_test.go @@ -0,0 +1,11 @@ +package operations + +import ( + "testing" + + "github.com/prysmaticlabs/prysm/spectest/shared/altair/operations" +) + +func TestMinimal_Altair_Operations_VoluntaryExit(t *testing.T) { + operations.RunVoluntaryExitTest(t, "minimal") +} diff --git a/spectest/shared/altair/operations/BUILD.bazel b/spectest/shared/altair/operations/BUILD.bazel new file mode 100644 index 0000000000..1d8c337dcd --- /dev/null +++ b/spectest/shared/altair/operations/BUILD.bazel @@ -0,0 +1,36 @@ +load("@prysm//tools/go:def.bzl", "go_library") + +go_library( + name = "go_default_library", + testonly = True, + srcs = [ + "attestation.go", + "attester_slashing.go", + "block_header.go", + "deposit.go", + "helpers.go", + "proposer_slashing.go", + "sync_committee.go", + "voluntary_exit.go", + ], + importpath = "github.com/prysmaticlabs/prysm/spectest/shared/altair/operations", + visibility = ["//spectest:__subpackages__"], + deps = [ + "//beacon-chain/core/altair:go_default_library", + "//beacon-chain/core/blocks:go_default_library", + "//beacon-chain/core/helpers:go_default_library", + "//beacon-chain/core/validators:go_default_library", + "//beacon-chain/state:go_default_library", + "//beacon-chain/state/v2:go_default_library", + "//proto/prysm/v1alpha1:go_default_library", + "//proto/prysm/v1alpha1/block:go_default_library", + "//proto/prysm/v1alpha1/wrapper:go_default_library", + "//shared/testutil:go_default_library", + "//shared/testutil/require:go_default_library", + "//spectest/utils:go_default_library", + "@com_github_golang_snappy//:go_default_library", + "@in_gopkg_d4l3k_messagediff_v1//:go_default_library", + "@io_bazel_rules_go//go/tools/bazel:go_default_library", + "@org_golang_google_protobuf//proto:go_default_library", + ], +) diff --git a/spectest/shared/altair/operations/attestation.go b/spectest/shared/altair/operations/attestation.go new file mode 100644 index 0000000000..c5f9738d6b --- /dev/null +++ b/spectest/shared/altair/operations/attestation.go @@ -0,0 +1,56 @@ +package operations + +import ( + "context" + "errors" + "path" + "testing" + + "github.com/golang/snappy" + "github.com/prysmaticlabs/prysm/beacon-chain/core/altair" + b "github.com/prysmaticlabs/prysm/beacon-chain/core/blocks" + "github.com/prysmaticlabs/prysm/beacon-chain/state" + ethpb "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1" + "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1/block" + "github.com/prysmaticlabs/prysm/shared/testutil" + "github.com/prysmaticlabs/prysm/shared/testutil/require" + "github.com/prysmaticlabs/prysm/spectest/utils" +) + +func RunAttestationTest(t *testing.T, config string) { + require.NoError(t, utils.SetConfig(t, config)) + testFolders, testsFolderPath := utils.TestFolders(t, config, "altair", "operations/attestation/pyspec_tests") + for _, folder := range testFolders { + t.Run(folder.Name(), func(t *testing.T) { + folderPath := path.Join(testsFolderPath, folder.Name()) + attestationFile, err := testutil.BazelFileBytes(folderPath, "attestation.ssz_snappy") + require.NoError(t, err) + attestationSSZ, err := snappy.Decode(nil /* dst */, attestationFile) + require.NoError(t, err, "Failed to decompress") + att := ðpb.Attestation{} + require.NoError(t, att.UnmarshalSSZ(attestationSSZ), "Failed to unmarshal") + + body := ðpb.BeaconBlockBodyAltair{Attestations: []*ethpb.Attestation{att}} + processAtt := func(ctx context.Context, st state.BeaconState, blk block.SignedBeaconBlock) (state.BeaconState, error) { + st, err = altair.ProcessAttestationsNoVerifySignature(ctx, st, blk) + if err != nil { + return nil, err + } + aSet, err := b.AttestationSignatureSet(ctx, st, blk.Block().Body().Attestations()) + if err != nil { + return nil, err + } + verified, err := aSet.Verify() + if err != nil { + return nil, err + } + if !verified { + return nil, errors.New("could not batch verify attestation signature") + } + return st, nil + } + + RunBlockOperationTest(t, folderPath, body, processAtt) + }) + } +} diff --git a/spectest/shared/altair/operations/attester_slashing.go b/spectest/shared/altair/operations/attester_slashing.go new file mode 100644 index 0000000000..702e3dda75 --- /dev/null +++ b/spectest/shared/altair/operations/attester_slashing.go @@ -0,0 +1,38 @@ +package operations + +import ( + "context" + "path" + "testing" + + "github.com/golang/snappy" + "github.com/prysmaticlabs/prysm/beacon-chain/core/blocks" + "github.com/prysmaticlabs/prysm/beacon-chain/core/validators" + "github.com/prysmaticlabs/prysm/beacon-chain/state" + ethpb "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1" + "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1/block" + "github.com/prysmaticlabs/prysm/shared/testutil" + "github.com/prysmaticlabs/prysm/shared/testutil/require" + "github.com/prysmaticlabs/prysm/spectest/utils" +) + +func RunAttesterSlashingTest(t *testing.T, config string) { + require.NoError(t, utils.SetConfig(t, config)) + testFolders, testsFolderPath := utils.TestFolders(t, config, "altair", "operations/attester_slashing/pyspec_tests") + for _, folder := range testFolders { + t.Run(folder.Name(), func(t *testing.T) { + folderPath := path.Join(testsFolderPath, folder.Name()) + attSlashingFile, err := testutil.BazelFileBytes(folderPath, "attester_slashing.ssz_snappy") + require.NoError(t, err) + attSlashingSSZ, err := snappy.Decode(nil /* dst */, attSlashingFile) + require.NoError(t, err, "Failed to decompress") + attSlashing := ðpb.AttesterSlashing{} + require.NoError(t, attSlashing.UnmarshalSSZ(attSlashingSSZ), "Failed to unmarshal") + + body := ðpb.BeaconBlockBodyAltair{AttesterSlashings: []*ethpb.AttesterSlashing{attSlashing}} + RunBlockOperationTest(t, folderPath, body, func(ctx context.Context, s state.BeaconState, b block.SignedBeaconBlock) (state.BeaconState, error) { + return blocks.ProcessAttesterSlashings(ctx, s, b.Block().Body().AttesterSlashings(), validators.SlashValidator) + }) + }) + } +} diff --git a/spectest/shared/altair/operations/block_header.go b/spectest/shared/altair/operations/block_header.go new file mode 100644 index 0000000000..28cf70cfb2 --- /dev/null +++ b/spectest/shared/altair/operations/block_header.go @@ -0,0 +1,83 @@ +package operations + +import ( + "io/ioutil" + "path" + "strings" + "testing" + + "github.com/bazelbuild/rules_go/go/tools/bazel" + "github.com/golang/snappy" + "github.com/prysmaticlabs/prysm/beacon-chain/core/blocks" + stateAltair "github.com/prysmaticlabs/prysm/beacon-chain/state/v2" + ethpb "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1" + "github.com/prysmaticlabs/prysm/shared/testutil" + "github.com/prysmaticlabs/prysm/shared/testutil/require" + "github.com/prysmaticlabs/prysm/spectest/utils" + "google.golang.org/protobuf/proto" + "gopkg.in/d4l3k/messagediff.v1" +) + +func RunBlockHeaderTest(t *testing.T, config string) { + require.NoError(t, utils.SetConfig(t, config)) + testFolders, testsFolderPath := utils.TestFolders(t, config, "altair", "operations/block_header/pyspec_tests") + for _, folder := range testFolders { + t.Run(folder.Name(), func(t *testing.T) { + blockFile, err := testutil.BazelFileBytes(testsFolderPath, folder.Name(), "block.ssz_snappy") + require.NoError(t, err) + blockSSZ, err := snappy.Decode(nil /* dst */, blockFile) + require.NoError(t, err, "Failed to decompress") + block := ðpb.BeaconBlockAltair{} + require.NoError(t, block.UnmarshalSSZ(blockSSZ), "Failed to unmarshal") + + preBeaconStateFile, err := testutil.BazelFileBytes(testsFolderPath, folder.Name(), "pre.ssz_snappy") + require.NoError(t, err) + preBeaconStateSSZ, err := snappy.Decode(nil /* dst */, preBeaconStateFile) + require.NoError(t, err, "Failed to decompress") + preBeaconStateBase := ðpb.BeaconStateAltair{} + require.NoError(t, preBeaconStateBase.UnmarshalSSZ(preBeaconStateSSZ), "Failed to unmarshal") + preBeaconState, err := stateAltair.InitializeFromProto(preBeaconStateBase) + require.NoError(t, err) + + // If the post.ssz is not present, it means the test should fail on our end. + postSSZFilepath, err := bazel.Runfile(path.Join(testsFolderPath, folder.Name(), "post.ssz_snappy")) + postSSZExists := true + if err != nil && strings.Contains(err.Error(), "could not locate file") { + postSSZExists = false + } else { + require.NoError(t, err) + } + + // Spectest blocks are not signed, so we'll call NoVerify to skip sig verification. + bodyRoot, err := block.Body.HashTreeRoot() + require.NoError(t, err) + beaconState, err := blocks.ProcessBlockHeaderNoVerify(preBeaconState, block.Slot, block.ProposerIndex, block.ParentRoot, bodyRoot[:]) + if postSSZExists { + require.NoError(t, err) + + postBeaconStateFile, err := ioutil.ReadFile(postSSZFilepath) // #nosec G304 + require.NoError(t, err) + postBeaconStateSSZ, err := snappy.Decode(nil /* dst */, postBeaconStateFile) + require.NoError(t, err, "Failed to decompress") + + postBeaconState := ðpb.BeaconStateAltair{} + require.NoError(t, postBeaconState.UnmarshalSSZ(postBeaconStateSSZ), "Failed to unmarshal") + pbState, err := stateAltair.ProtobufBeaconState(beaconState.CloneInnerState()) + require.NoError(t, err) + if !proto.Equal(pbState, postBeaconState) { + diff, _ := messagediff.PrettyDiff(beaconState.CloneInnerState(), postBeaconState) + t.Log(diff) + t.Fatal("Post state does not match expected") + } + } else { + // Note: This doesn't test anything worthwhile. It essentially tests + // that *any* error has occurred, not any specific error. + if err == nil { + t.Fatal("Did not fail when expected") + } + t.Logf("Expected failure; failure reason = %v", err) + return + } + }) + } +} diff --git a/spectest/shared/altair/operations/deposit.go b/spectest/shared/altair/operations/deposit.go new file mode 100644 index 0000000000..9aec368a43 --- /dev/null +++ b/spectest/shared/altair/operations/deposit.go @@ -0,0 +1,38 @@ +package operations + +import ( + "context" + "path" + "testing" + + "github.com/golang/snappy" + "github.com/prysmaticlabs/prysm/beacon-chain/core/altair" + "github.com/prysmaticlabs/prysm/beacon-chain/state" + ethpb "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1" + "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1/block" + "github.com/prysmaticlabs/prysm/shared/testutil" + "github.com/prysmaticlabs/prysm/shared/testutil/require" + "github.com/prysmaticlabs/prysm/spectest/utils" +) + +func RunDepositTest(t *testing.T, config string) { + require.NoError(t, utils.SetConfig(t, config)) + testFolders, testsFolderPath := utils.TestFolders(t, config, "altair", "operations/deposit/pyspec_tests") + for _, folder := range testFolders { + t.Run(folder.Name(), func(t *testing.T) { + folderPath := path.Join(testsFolderPath, folder.Name()) + depositFile, err := testutil.BazelFileBytes(folderPath, "deposit.ssz_snappy") + require.NoError(t, err) + depositSSZ, err := snappy.Decode(nil /* dst */, depositFile) + require.NoError(t, err, "Failed to decompress") + deposit := ðpb.Deposit{} + require.NoError(t, deposit.UnmarshalSSZ(depositSSZ), "Failed to unmarshal") + + body := ðpb.BeaconBlockBodyAltair{Deposits: []*ethpb.Deposit{deposit}} + processDepositsFunc := func(ctx context.Context, s state.BeaconState, b block.SignedBeaconBlock) (state.BeaconState, error) { + return altair.ProcessDeposits(ctx, s, b.Block().Body().Deposits()) + } + RunBlockOperationTest(t, folderPath, body, processDepositsFunc) + }) + } +} diff --git a/spectest/shared/altair/operations/helpers.go b/spectest/shared/altair/operations/helpers.go new file mode 100644 index 0000000000..2c701bc579 --- /dev/null +++ b/spectest/shared/altair/operations/helpers.go @@ -0,0 +1,88 @@ +package operations + +import ( + "context" + "io/ioutil" + "path" + "strings" + "testing" + + "github.com/bazelbuild/rules_go/go/tools/bazel" + "github.com/golang/snappy" + "github.com/prysmaticlabs/prysm/beacon-chain/core/helpers" + "github.com/prysmaticlabs/prysm/beacon-chain/state" + stateAltair "github.com/prysmaticlabs/prysm/beacon-chain/state/v2" + ethpb "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1" + "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1/block" + "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1/wrapper" + "github.com/prysmaticlabs/prysm/shared/testutil" + "github.com/prysmaticlabs/prysm/shared/testutil/require" + "google.golang.org/protobuf/proto" + "gopkg.in/d4l3k/messagediff.v1" +) + +type blockOperation func(context.Context, state.BeaconState, block.SignedBeaconBlock) (state.BeaconState, error) + +// RunBlockOperationTest takes in the prestate and the beacon block body, processes it through the +// passed in block operation function and checks the post state with the expected post state. +func RunBlockOperationTest( + t *testing.T, + folderPath string, + body *ethpb.BeaconBlockBodyAltair, + operationFn blockOperation, +) { + preBeaconStateFile, err := testutil.BazelFileBytes(path.Join(folderPath, "pre.ssz_snappy")) + require.NoError(t, err) + preBeaconStateSSZ, err := snappy.Decode(nil /* dst */, preBeaconStateFile) + require.NoError(t, err, "Failed to decompress") + preStateBase := ðpb.BeaconStateAltair{} + if err := preStateBase.UnmarshalSSZ(preBeaconStateSSZ); err != nil { + t.Fatalf("Failed to unmarshal: %v", err) + } + preState, err := stateAltair.InitializeFromProto(preStateBase) + require.NoError(t, err) + + // If the post.ssz is not present, it means the test should fail on our end. + postSSZFilepath, err := bazel.Runfile(path.Join(folderPath, "post.ssz_snappy")) + postSSZExists := true + if err != nil && strings.Contains(err.Error(), "could not locate file") { + postSSZExists = false + } else if err != nil { + t.Fatal(err) + } + + helpers.ClearCache() + b := testutil.NewBeaconBlockAltair() + b.Block.Body = body + wsb, err := wrapper.WrappedAltairSignedBeaconBlock(b) + require.NoError(t, err) + beaconState, err := operationFn(context.Background(), preState, wsb) + if postSSZExists { + require.NoError(t, err) + + postBeaconStateFile, err := ioutil.ReadFile(postSSZFilepath) // #nosec G304 + require.NoError(t, err) + postBeaconStateSSZ, err := snappy.Decode(nil /* dst */, postBeaconStateFile) + require.NoError(t, err, "Failed to decompress") + + postBeaconState := ðpb.BeaconStateAltair{} + if err := postBeaconState.UnmarshalSSZ(postBeaconStateSSZ); err != nil { + t.Fatalf("Failed to unmarshal: %v", err) + } + pbState, err := stateAltair.ProtobufBeaconState(beaconState.InnerStateUnsafe()) + require.NoError(t, err) + if !proto.Equal(pbState, postBeaconState) { + diff, _ := messagediff.PrettyDiff(beaconState.InnerStateUnsafe(), postBeaconState) + t.Log(diff) + t.Fatal("Post state does not match expected") + } + } else { + // Note: This doesn't test anything worthwhile. It essentially tests + // that *any* error has occurred, not any specific error. + if err == nil { + t.Fatal("Did not fail when expected") + } + t.Logf("Expected failure; failure reason = %v", err) + return + } +} diff --git a/spectest/shared/altair/operations/proposer_slashing.go b/spectest/shared/altair/operations/proposer_slashing.go new file mode 100644 index 0000000000..25e3c6a5d3 --- /dev/null +++ b/spectest/shared/altair/operations/proposer_slashing.go @@ -0,0 +1,38 @@ +package operations + +import ( + "context" + "path" + "testing" + + "github.com/golang/snappy" + "github.com/prysmaticlabs/prysm/beacon-chain/core/blocks" + "github.com/prysmaticlabs/prysm/beacon-chain/core/validators" + "github.com/prysmaticlabs/prysm/beacon-chain/state" + ethpb "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1" + "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1/block" + "github.com/prysmaticlabs/prysm/shared/testutil" + "github.com/prysmaticlabs/prysm/shared/testutil/require" + "github.com/prysmaticlabs/prysm/spectest/utils" +) + +func RunProposerSlashingTest(t *testing.T, config string) { + require.NoError(t, utils.SetConfig(t, config)) + testFolders, testsFolderPath := utils.TestFolders(t, config, "altair", "operations/proposer_slashing/pyspec_tests") + for _, folder := range testFolders { + t.Run(folder.Name(), func(t *testing.T) { + folderPath := path.Join(testsFolderPath, folder.Name()) + proposerSlashingFile, err := testutil.BazelFileBytes(folderPath, "proposer_slashing.ssz_snappy") + require.NoError(t, err) + proposerSlashingSSZ, err := snappy.Decode(nil /* dst */, proposerSlashingFile) + require.NoError(t, err, "Failed to decompress") + proposerSlashing := ðpb.ProposerSlashing{} + require.NoError(t, proposerSlashing.UnmarshalSSZ(proposerSlashingSSZ), "Failed to unmarshal") + + body := ðpb.BeaconBlockBodyAltair{ProposerSlashings: []*ethpb.ProposerSlashing{proposerSlashing}} + RunBlockOperationTest(t, folderPath, body, func(ctx context.Context, s state.BeaconState, b block.SignedBeaconBlock) (state.BeaconState, error) { + return blocks.ProcessProposerSlashings(ctx, s, b.Block().Body().ProposerSlashings(), validators.SlashValidator) + }) + }) + } +} diff --git a/spectest/shared/altair/operations/sync_committee.go b/spectest/shared/altair/operations/sync_committee.go new file mode 100644 index 0000000000..ffa0853271 --- /dev/null +++ b/spectest/shared/altair/operations/sync_committee.go @@ -0,0 +1,37 @@ +package operations + +import ( + "context" + "path" + "testing" + + "github.com/golang/snappy" + "github.com/prysmaticlabs/prysm/beacon-chain/core/altair" + "github.com/prysmaticlabs/prysm/beacon-chain/state" + ethpb "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1" + "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1/block" + "github.com/prysmaticlabs/prysm/shared/testutil" + "github.com/prysmaticlabs/prysm/shared/testutil/require" + "github.com/prysmaticlabs/prysm/spectest/utils" +) + +func RunSyncCommitteeTest(t *testing.T, config string) { + require.NoError(t, utils.SetConfig(t, config)) + testFolders, testsFolderPath := utils.TestFolders(t, config, "altair", "operations/sync_aggregate/pyspec_tests") + for _, folder := range testFolders { + t.Run(folder.Name(), func(t *testing.T) { + folderPath := path.Join(testsFolderPath, folder.Name()) + syncCommitteeFile, err := testutil.BazelFileBytes(folderPath, "sync_aggregate.ssz_snappy") + require.NoError(t, err) + syncCommitteeSSZ, err := snappy.Decode(nil /* dst */, syncCommitteeFile) + require.NoError(t, err, "Failed to decompress") + sc := ðpb.SyncAggregate{} + require.NoError(t, sc.UnmarshalSSZ(syncCommitteeSSZ), "Failed to unmarshal") + + body := ðpb.BeaconBlockBodyAltair{SyncAggregate: sc} + RunBlockOperationTest(t, folderPath, body, func(ctx context.Context, s state.BeaconState, b block.SignedBeaconBlock) (state.BeaconState, error) { + return altair.ProcessSyncAggregate(s, body.SyncAggregate) + }) + }) + } +} diff --git a/spectest/shared/altair/operations/voluntary_exit.go b/spectest/shared/altair/operations/voluntary_exit.go new file mode 100644 index 0000000000..b149fd2364 --- /dev/null +++ b/spectest/shared/altair/operations/voluntary_exit.go @@ -0,0 +1,37 @@ +package operations + +import ( + "context" + "path" + "testing" + + "github.com/golang/snappy" + "github.com/prysmaticlabs/prysm/beacon-chain/core/blocks" + "github.com/prysmaticlabs/prysm/beacon-chain/state" + ethpb "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1" + "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1/block" + "github.com/prysmaticlabs/prysm/shared/testutil" + "github.com/prysmaticlabs/prysm/shared/testutil/require" + "github.com/prysmaticlabs/prysm/spectest/utils" +) + +func RunVoluntaryExitTest(t *testing.T, config string) { + require.NoError(t, utils.SetConfig(t, config)) + testFolders, testsFolderPath := utils.TestFolders(t, config, "altair", "operations/voluntary_exit/pyspec_tests") + for _, folder := range testFolders { + t.Run(folder.Name(), func(t *testing.T) { + folderPath := path.Join(testsFolderPath, folder.Name()) + exitFile, err := testutil.BazelFileBytes(folderPath, "voluntary_exit.ssz_snappy") + require.NoError(t, err) + exitSSZ, err := snappy.Decode(nil /* dst */, exitFile) + require.NoError(t, err, "Failed to decompress") + voluntaryExit := ðpb.SignedVoluntaryExit{} + require.NoError(t, voluntaryExit.UnmarshalSSZ(exitSSZ), "Failed to unmarshal") + + body := ðpb.BeaconBlockBodyAltair{VoluntaryExits: []*ethpb.SignedVoluntaryExit{voluntaryExit}} + RunBlockOperationTest(t, folderPath, body, func(ctx context.Context, s state.BeaconState, b block.SignedBeaconBlock) (state.BeaconState, error) { + return blocks.ProcessVoluntaryExits(ctx, s, b.Block().Body().VoluntaryExits()) + }) + }) + } +}