From f1430ae2bbacf64c81f738e3b8b81e2c9c9b0f90 Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Thu, 13 Jun 2024 15:19:48 +0800 Subject: [PATCH] core: check if sender is EOA (#23303) --- core/error.go | 3 +++ core/state_transition.go | 8 ++++++++ tests/init_test.go | 29 +++++++++++++++++++++++++---- tests/state_test.go | 7 +++++++ 4 files changed, 43 insertions(+), 4 deletions(-) diff --git a/core/error.go b/core/error.go index 327e68278b97..35106d0f1c30 100644 --- a/core/error.go +++ b/core/error.go @@ -69,4 +69,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_transition.go b/core/state_transition.go index 0523d4904fd9..eb4f3a5ba6b6 100644 --- a/core/state_transition.go +++ b/core/state_transition.go @@ -26,10 +26,13 @@ import ( cmath "github.com/XinFinOrg/XDPoSChain/common/math" "github.com/XinFinOrg/XDPoSChain/core/types" "github.com/XinFinOrg/XDPoSChain/core/vm" + "github.com/XinFinOrg/XDPoSChain/crypto" "github.com/XinFinOrg/XDPoSChain/log" "github.com/XinFinOrg/XDPoSChain/params" ) +var emptyCodeHash = crypto.Keccak256Hash(nil) + var ( errInsufficientBalanceForGas = errors.New("insufficient balance to pay for gas") ) @@ -222,6 +225,11 @@ func (st *StateTransition) preCheck() error { msg.From().Hex(), 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().IsEIP1559(st.evm.Context.BlockNumber) { // Skip the checks if gas fields are zero and baseFee was explicitly disabled (eth_call) diff --git a/tests/init_test.go b/tests/init_test.go index 53fe8b41201c..b6499a2e199e 100644 --- a/tests/init_test.go +++ b/tests/init_test.go @@ -87,10 +87,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 - skipshortpat []*regexp.Regexp + configpat []testConfig + failpat []testFailure + skiploadpat []*regexp.Regexp + skipshortpat []*regexp.Regexp + runonlylistpat *regexp.Regexp } type testConfig struct { @@ -121,6 +122,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}) @@ -209,6 +214,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]. @@ -262,3 +272,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 79a7dc2a1519..5ad8daaf1bd4 100644 --- a/tests/state_test.go +++ b/tests/state_test.go @@ -31,9 +31,16 @@ func TestState(t *testing.T) { st := new(testMatcher) // Long tests: st.skipShortMode(`^stQuadraticComplexityTest/`) + // Broken tests: st.skipLoad(`^stTransactionTest/OverflowGasRequire\.json`) // gasLimit > 256 bits st.skipLoad(`^stTransactionTest/zeroSigTransa[^/]*\.json`) // EIP-86 is not supported yet + + // 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`) + // Expected failures: st.fails(`^stRevertTest/RevertPrecompiledTouch\.json/EIP158`, "bug in test") st.fails(`^stRevertTest/RevertPrefoundEmptyOOG\.json/EIP158`, "bug in test")