diff --git a/beacon-chain/execution/BUILD.bazel b/beacon-chain/execution/BUILD.bazel index 0bf59c2528af..0f4a11f5fe2d 100644 --- a/beacon-chain/execution/BUILD.bazel +++ b/beacon-chain/execution/BUILD.bazel @@ -23,6 +23,7 @@ go_library( "//beacon-chain:__subpackages__", "//cmd/beacon-chain:__subpackages__", "//contracts:__subpackages__", + "//testing/spectest:__subpackages__", ], deps = [ "//beacon-chain/cache/depositcache:go_default_library", diff --git a/testing/spectest/shared/common/forkchoice/BUILD.bazel b/testing/spectest/shared/common/forkchoice/BUILD.bazel index f238e42872b5..7bfc529121b1 100644 --- a/testing/spectest/shared/common/forkchoice/BUILD.bazel +++ b/testing/spectest/shared/common/forkchoice/BUILD.bazel @@ -19,6 +19,7 @@ go_library( "//beacon-chain/core/time:go_default_library", "//beacon-chain/core/transition:go_default_library", "//beacon-chain/db/testing:go_default_library", + "//beacon-chain/execution:go_default_library", "//beacon-chain/forkchoice/protoarray:go_default_library", "//beacon-chain/operations/attestations:go_default_library", "//beacon-chain/state:go_default_library", diff --git a/testing/spectest/shared/common/forkchoice/builder.go b/testing/spectest/shared/common/forkchoice/builder.go index 519edc8dbd2d..2c01c3de0c54 100644 --- a/testing/spectest/shared/common/forkchoice/builder.go +++ b/testing/spectest/shared/common/forkchoice/builder.go @@ -2,12 +2,14 @@ package forkchoice import ( "context" + "errors" "fmt" "testing" "time" "github.com/ethereum/go-ethereum/common" "github.com/prysmaticlabs/prysm/v3/beacon-chain/blockchain" + "github.com/prysmaticlabs/prysm/v3/beacon-chain/execution" "github.com/prysmaticlabs/prysm/v3/beacon-chain/state" "github.com/prysmaticlabs/prysm/v3/config/params" "github.com/prysmaticlabs/prysm/v3/consensus-types/interfaces" @@ -50,6 +52,32 @@ func (bb *Builder) Tick(t testing.TB, tick int64) { bb.lastTick = tick } +// SetPayloadStatus sets the payload status that the engine will return +func (bb *Builder) SetPayloadStatus(resp *MockEngineResp) error { + if resp == nil { + return errors.New("invalid nil payload status") + } + if resp.LatestValidHash == nil { + bb.execMock.latestValidHash = common.FromHex("0x0000000000000000000000000000000000000000000000000000000000000000") + } else { + bb.execMock.latestValidHash = common.FromHex(*resp.LatestValidHash) + } + if resp.Status == nil { + return errors.New("invalid nil status") + } + switch *resp.Status { + case "SYNCING": + bb.execMock.payloadStatus = execution.ErrAcceptedSyncingPayloadStatus + case "VALID": + bb.execMock.payloadStatus = nil + case "INVALID": + bb.execMock.payloadStatus = execution.ErrInvalidPayloadStatus + default: + return errors.New("unknown payload status") + } + return nil +} + // block returns the block root. func (bb *Builder) block(t testing.TB, b interfaces.SignedBeaconBlock) [32]byte { r, err := b.Block().HashTreeRoot() diff --git a/testing/spectest/shared/common/forkchoice/runner.go b/testing/spectest/shared/common/forkchoice/runner.go index 38997fce4829..c7885722f416 100644 --- a/testing/spectest/shared/common/forkchoice/runner.go +++ b/testing/spectest/shared/common/forkchoice/runner.go @@ -25,13 +25,21 @@ func init() { transition.SkipSlotCache.Disable() } -// Run executes "forkchoice" test. +// Run executes "forkchoice" and "sync" test. func Run(t *testing.T, config string, fork int) { + runTest(t, config, fork, "fork_choice") + runTest(t, config, fork, "sync") +} + +func runTest(t *testing.T, config string, fork int, basePath string) { require.NoError(t, utils.SetConfig(t, config)) - testFolders, _ := utils.TestFolders(t, config, version.String(fork), "fork_choice") + testFolders, _ := utils.TestFolders(t, config, version.String(fork), basePath) + if testFolders == nil { + return + } for _, folder := range testFolders { - folderPath := path.Join("fork_choice", folder.Name(), "pyspec_tests") + folderPath := path.Join(basePath, folder.Name(), "pyspec_tests") testFolders, testsFolderPath := utils.TestFolders(t, config, version.String(fork), folderPath) for _, folder := range testFolders { @@ -113,6 +121,10 @@ func Run(t *testing.T, config string, fork int) { require.NoError(t, att.UnmarshalSSZ(attSSZ), "Failed to unmarshal") builder.Attestation(t, att) } + if step.PayloadStatus != nil { + require.NoError(t, builder.SetPayloadStatus(step.PayloadStatus)) + + } if step.PowBlock != nil { powBlockFile, err := util.BazelFileBytes(testsFolderPath, folder.Name(), fmt.Sprint(*step.PowBlock, ".ssz_snappy")) require.NoError(t, err) diff --git a/testing/spectest/shared/common/forkchoice/service.go b/testing/spectest/shared/common/forkchoice/service.go index 98c5967116b7..74496deb8b01 100644 --- a/testing/spectest/shared/common/forkchoice/service.go +++ b/testing/spectest/shared/common/forkchoice/service.go @@ -25,7 +25,11 @@ import ( "github.com/prysmaticlabs/prysm/v3/testing/require" ) -func startChainService(t testing.TB, st state.BeaconState, block interfaces.SignedBeaconBlock, engineMock *engineMock) *blockchain.Service { +func startChainService(t testing.TB, + st state.BeaconState, + block interfaces.SignedBeaconBlock, + engineMock *engineMock, +) *blockchain.Service { db := testDB.SetupDB(t) ctx := context.Background() require.NoError(t, db.SaveBlock(ctx, block)) @@ -67,7 +71,9 @@ func startChainService(t testing.TB, st state.BeaconState, block interfaces.Sign } type engineMock struct { - powBlocks map[[32]byte]*ethpb.PowBlock + powBlocks map[[32]byte]*ethpb.PowBlock + latestValidHash []byte + payloadStatus error } func (m *engineMock) GetPayload(context.Context, [8]byte) (*pb.ExecutionPayload, error) { @@ -77,7 +83,7 @@ func (m *engineMock) ForkchoiceUpdated(context.Context, *pb.ForkchoiceState, *pb return nil, nil, nil } func (m *engineMock) NewPayload(context.Context, interfaces.ExecutionData) ([]byte, error) { - return nil, nil + return m.latestValidHash, m.payloadStatus } func (m *engineMock) LatestExecutionBlock(context.Context) (*pb.ExecutionBlock, error) { diff --git a/testing/spectest/shared/common/forkchoice/type.go b/testing/spectest/shared/common/forkchoice/type.go index 93f16eca3039..7e7bace891c4 100644 --- a/testing/spectest/shared/common/forkchoice/type.go +++ b/testing/spectest/shared/common/forkchoice/type.go @@ -1,13 +1,14 @@ package forkchoice type Step struct { - Tick *int `json:"tick"` - Block *string `json:"block"` - Valid *bool `json:"valid"` - Attestation *string `json:"attestation"` - AttesterSlashing *string `json:"attester_slashing"` - PowBlock *string `json:"pow_block"` - Check *Check `json:"checks"` + Tick *int `json:"tick"` + Block *string `json:"block"` + Valid *bool `json:"valid"` + Attestation *string `json:"attestation"` + AttesterSlashing *string `json:"attester_slashing"` + PayloadStatus *MockEngineResp `json:"payload_status"` + PowBlock *string `json:"pow_block"` + Check *Check `json:"checks"` } type Check struct { @@ -29,3 +30,9 @@ type EpochRoot struct { Epoch int `json:"epoch"` Root string `json:"root"` } + +type MockEngineResp struct { + Status *string `json:"status"` + LatestValidHash *string `json:"latest_valid_hash"` + ValidationError *string `json:"validation_error"` +} diff --git a/testing/spectest/utils/utils.go b/testing/spectest/utils/utils.go index 5e90fcff9d68..177b5aa6aa72 100644 --- a/testing/spectest/utils/utils.go +++ b/testing/spectest/utils/utils.go @@ -33,7 +33,9 @@ func UnmarshalYaml(y []byte, dest interface{}) error { func TestFolders(t testing.TB, config, forkOrPhase, folderPath string) ([]os.DirEntry, string) { testsFolderPath := path.Join("tests", config, forkOrPhase, folderPath) filepath, err := bazel.Runfile(testsFolderPath) - require.NoError(t, err) + if err != nil { + return nil, "" + } testFolders, err := os.ReadDir(filepath) require.NoError(t, err)