diff --git a/core/error.go b/core/error.go
index bcbce09ba43125eba4c8799a4b3ca9acac3e6ae6..33cf874d15e469c0bc1f830fa443379d8ca46a2e 100644
--- a/core/error.go
+++ b/core/error.go
@@ -87,4 +87,7 @@ var (
 	// ErrFeeCapTooLow is returned if the transaction fee cap is less than the
 	// the base fee of the block.
 	ErrFeeCapTooLow = errors.New("max fee per gas less than block base fee")
+
+	// ErrSenderNoEOA is returned if the sender of a transaction is a contract.
+	ErrSenderNoEOA = errors.New("sender not an eoa")
 )
diff --git a/core/state_processor_test.go b/core/state_processor_test.go
index ce6d2bcdde8bca4e7f2d5247746628b9c66b5e74..13a9eb810df66f9401b8f40be8a98326e8e0fe37 100644
--- a/core/state_processor_test.go
+++ b/core/state_processor_test.go
@@ -195,7 +195,7 @@ func TestStateProcessorErrors(t *testing.T) {
 		}
 	}
 
-	// One final error is ErrTxTypeNotSupported. For this, we need an older chain
+	// ErrTxTypeNotSupported, For this, we need an older chain
 	{
 		var (
 			db    = rawdb.NewMemoryDatabase()
@@ -244,6 +244,46 @@ func TestStateProcessorErrors(t *testing.T) {
 			}
 		}
 	}
+
+	// ErrSenderNoEOA, for this we need the sender to have contract code
+	{
+		var (
+			db    = rawdb.NewMemoryDatabase()
+			gspec = &Genesis{
+				Config: config,
+				Alloc: GenesisAlloc{
+					common.HexToAddress("0x71562b71999873DB5b286dF957af199Ec94617F7"): GenesisAccount{
+						Balance: big.NewInt(1000000000000000000), // 1 ether
+						Nonce:   0,
+						Code:    common.FromHex("0xB0B0FACE"),
+					},
+				},
+			}
+			genesis       = gspec.MustCommit(db)
+			blockchain, _ = NewBlockChain(db, nil, gspec.Config, ethash.NewFaker(), vm.Config{}, nil, nil)
+		)
+		defer blockchain.Stop()
+		for i, tt := range []struct {
+			txs  []*types.Transaction
+			want string
+		}{
+			{ // ErrSenderNoEOA
+				txs: []*types.Transaction{
+					mkDynamicTx(0, common.Address{}, params.TxGas-1000, big.NewInt(0), big.NewInt(0)),
+				},
+				want: "could not apply tx 0 [0x88626ac0d53cb65308f2416103c62bb1f18b805573d4f96a3640bbbfff13c14f]: sender not an eoa: address 0x71562b71999873DB5b286dF957af199Ec94617F7, codehash: 0x9280914443471259d4570a8661015ae4a5b80186dbc619658fb494bebc3da3d1",
+			},
+		} {
+			block := GenerateBadBlock(genesis, ethash.NewFaker(), tt.txs, gspec.Config)
+			_, err := blockchain.InsertChain(types.Blocks{block})
+			if err == nil {
+				t.Fatal("block imported without errors")
+			}
+			if have, want := err.Error(), tt.want; have != want {
+				t.Errorf("test %d:\nhave \"%v\"\nwant \"%v\"\n", i, have, want)
+			}
+		}
+	}
 }
 
 // GenerateBadBlock constructs a "block" which contains the transactions. The transactions are not expected to be
diff --git a/core/state_transition.go b/core/state_transition.go
index b5b0ae990a417e3d3212630d81cba558d5e16a0b..68f3c74a312196c900f2703a8ab5626294c420ca 100644
--- a/core/state_transition.go
+++ b/core/state_transition.go
@@ -25,9 +25,12 @@ import (
 	cmath "github.com/ethereum/go-ethereum/common/math"
 	"github.com/ethereum/go-ethereum/core/types"
 	"github.com/ethereum/go-ethereum/core/vm"
+	"github.com/ethereum/go-ethereum/crypto"
 	"github.com/ethereum/go-ethereum/params"
 )
 
+var emptyCodeHash = crypto.Keccak256Hash(nil)
+
 /*
 The State Transitioning Model
 
@@ -220,6 +223,11 @@ func (st *StateTransition) preCheck() error {
 				st.msg.From().Hex(), msgNonce, stNonce)
 		}
 	}
+	// Make sure the sender is an EOA
+	if codeHash := st.state.GetCodeHash(st.msg.From()); codeHash != emptyCodeHash && codeHash != (common.Hash{}) {
+		return fmt.Errorf("%w: address %v, codehash: %s", ErrSenderNoEOA,
+			st.msg.From().Hex(), codeHash)
+	}
 	// Make sure that transaction gasFeeCap is greater than the baseFee (post london)
 	if st.evm.ChainConfig().IsLondon(st.evm.Context.BlockNumber) {
 		// Skip the checks if gas fields are zero and baseFee was explicitly disabled (eth_call)
diff --git a/eth/tracers/api_test.go b/eth/tracers/api_test.go
index 4a4e5bbc33d2a6801f1f3fed65cb5c061d4a568b..9afd59d596bc2231f2d252adf3911d6165e53d1a 100644
--- a/eth/tracers/api_test.go
+++ b/eth/tracers/api_test.go
@@ -417,24 +417,24 @@ func TestOverriddenTraceCall(t *testing.T) {
 			},
 		},
 	}
-	for _, testspec := range testSuite {
+	for i, testspec := range testSuite {
 		result, err := api.TraceCall(context.Background(), testspec.call, rpc.BlockNumberOrHash{BlockNumber: &testspec.blockNumber}, testspec.config)
 		if testspec.expectErr != nil {
 			if err == nil {
-				t.Errorf("Expect error %v, get nothing", testspec.expectErr)
+				t.Errorf("test %d: want error %v, have nothing", i, testspec.expectErr)
 				continue
 			}
 			if !errors.Is(err, testspec.expectErr) {
-				t.Errorf("Error mismatch, want %v, get %v", testspec.expectErr, err)
+				t.Errorf("test %d: error mismatch, want %v, have %v", i, testspec.expectErr, err)
 			}
 		} else {
 			if err != nil {
-				t.Errorf("Expect no error, get %v", err)
+				t.Errorf("test %d: want no error, have %v", i, err)
 				continue
 			}
 			ret := new(callTrace)
 			if err := json.Unmarshal(result.(json.RawMessage), ret); err != nil {
-				t.Fatalf("failed to unmarshal trace result: %v", err)
+				t.Fatalf("test %d: failed to unmarshal trace result: %v", i, err)
 			}
 			if !jsonEqual(ret, testspec.expect) {
 				// uncomment this for easier debugging
diff --git a/tests/init_test.go b/tests/init_test.go
index f1a4ca2cf087c93d034d87b70c4467d1a2da1028..969cf71399154f66cc981a74baf54497f497e373 100644
--- a/tests/init_test.go
+++ b/tests/init_test.go
@@ -34,10 +34,10 @@ import (
 )
 
 var (
-	baseDir            = filepath.Join(".", "testdata")
-	blockTestDir       = filepath.Join(baseDir, "BlockchainTests")
-	stateTestDir       = filepath.Join(baseDir, "GeneralStateTests")
-	legacyStateTestDir = filepath.Join(baseDir, "LegacyTests", "Constantinople", "GeneralStateTests")
+	baseDir      = filepath.Join(".", "testdata")
+	blockTestDir = filepath.Join(baseDir, "BlockchainTests")
+	stateTestDir = filepath.Join(baseDir, "GeneralStateTests")
+	//legacyStateTestDir = filepath.Join(baseDir, "LegacyTests", "Constantinople", "GeneralStateTests")
 	transactionTestDir = filepath.Join(baseDir, "TransactionTests")
 	vmTestDir          = filepath.Join(baseDir, "VMTests")
 	rlpTestDir         = filepath.Join(baseDir, "RLPTests")
@@ -89,10 +89,11 @@ func findLine(data []byte, offset int64) (line int) {
 
 // testMatcher controls skipping and chain config assignment to tests.
 type testMatcher struct {
-	configpat   []testConfig
-	failpat     []testFailure
-	skiploadpat []*regexp.Regexp
-	slowpat     []*regexp.Regexp
+	configpat      []testConfig
+	failpat        []testFailure
+	skiploadpat    []*regexp.Regexp
+	slowpat        []*regexp.Regexp
+	runonlylistpat *regexp.Regexp
 }
 
 type testConfig struct {
@@ -123,6 +124,10 @@ func (tm *testMatcher) fails(pattern string, reason string) {
 	tm.failpat = append(tm.failpat, testFailure{regexp.MustCompile(pattern), reason})
 }
 
+func (tm *testMatcher) runonly(pattern string) {
+	tm.runonlylistpat = regexp.MustCompile(pattern)
+}
+
 // config defines chain config for tests matching the pattern.
 func (tm *testMatcher) config(pattern string, cfg params.ChainConfig) {
 	tm.configpat = append(tm.configpat, testConfig{regexp.MustCompile(pattern), cfg})
@@ -212,6 +217,11 @@ func (tm *testMatcher) runTestFile(t *testing.T, path, name string, runTest inte
 	if r, _ := tm.findSkip(name); r != "" {
 		t.Skip(r)
 	}
+	if tm.runonlylistpat != nil {
+		if !tm.runonlylistpat.MatchString(name) {
+			t.Skip("Skipped by runonly")
+		}
+	}
 	t.Parallel()
 
 	// Load the file as map[string]<testType>.
@@ -265,3 +275,14 @@ func runTestFunc(runTest interface{}, t *testing.T, name string, m reflect.Value
 		m.MapIndex(reflect.ValueOf(key)),
 	})
 }
+
+func TestMatcherRunonlylist(t *testing.T) {
+	t.Parallel()
+	tm := new(testMatcher)
+	tm.runonly("invalid*")
+	tm.walk(t, rlpTestDir, func(t *testing.T, name string, test *RLPTest) {
+		if name[:len("invalidRLPTest.json")] != "invalidRLPTest.json" {
+			t.Fatalf("invalid test found: %s != invalidRLPTest.json", name)
+		}
+	})
+}
diff --git a/tests/state_test.go b/tests/state_test.go
index c2ca0e8d694861a4dff6fb61c30d2aae9c2bd18f..242e9712a3120f2ee5ccff22f1ab569562d0acb3 100644
--- a/tests/state_test.go
+++ b/tests/state_test.go
@@ -45,7 +45,8 @@ func TestState(t *testing.T) {
 
 	// Uses 1GB RAM per tested fork
 	st.skipLoad(`^stStaticCall/static_Call1MB`)
-
+	// Un-skip this when https://github.com/ethereum/tests/issues/908 is closed
+	st.skipLoad(`^stQuadraticComplexityTest/QuadraticComplexitySolidity_CallDataCopy`)
 	// Broken tests:
 	// Expected failures:
 	//st.fails(`^stRevertTest/RevertPrecompiledTouch(_storage)?\.json/Byzantium/0`, "bug in test")
@@ -58,7 +59,9 @@ func TestState(t *testing.T) {
 	// For Istanbul, older tests were moved into LegacyTests
 	for _, dir := range []string{
 		stateTestDir,
-		legacyStateTestDir,
+		// legacy state tests are disabled, due to them not being
+		// regenerated for the no-sender-eoa change.
+		//legacyStateTestDir,
 	} {
 		st.walk(t, dir, func(t *testing.T, name string, test *StateTest) {
 			for _, subtest := range test.Subtests() {