-
Notifications
You must be signed in to change notification settings - Fork 33
/
Copy pathstate_test.go
181 lines (161 loc) · 6.45 KB
/
state_test.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
// Modifications Copyright 2024 The Kaia Authors
// Modifications Copyright 2018 The klaytn Authors
// Copyright 2015 The go-ethereum Authors
// This file is part of the go-ethereum library.
//
// The go-ethereum library is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// The go-ethereum library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
//
// This file is derived from tests/state_test.go (2018/06/04).
// Modified and improved for the klaytn development.
// Modified and improved for the Kaia development.
package tests
import (
"bytes"
"fmt"
"reflect"
"testing"
"github.com/kaiachain/kaia/blockchain/vm"
"github.com/kaiachain/kaia/common"
"github.com/kaiachain/kaia/params"
"github.com/stretchr/testify/suite"
)
// TestCoreSpecState runs the StateTests fixtures from kaia-core-tests
func TestKaiaSpecState(t *testing.T) {
t.Parallel()
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
// Expected failures:
st.fails(`^stRevertTest/RevertPrecompiledTouch\.json/Byzantium`, "bug in test")
st.skipLoad(`^stZeroKnowledge2/ecmul_0-3_5616_28000_96\.json`)
// Skip since the tests transfer values to precompiled contracts
st.skipLoad(`^stPreCompiledContracts2/CallSha256_1_nonzeroValue.json`)
st.skipLoad(`^stPreCompiledContracts2/CallIdentity_1_nonzeroValue.json`)
st.skipLoad(`^stPreCompiledContracts2/CallEcrecover0_NoGas.json`)
st.skipLoad(`^stRandom2/randomStatetest644.json`)
st.skipLoad(`^stRandom2/randomStatetest645.json`)
st.skipLoad(`^stStaticCall/static_CallIdentity_1_nonzeroValue.json`)
st.skipLoad(`^stStaticCall/static_CallSha256_1_nonzeroValue.json`)
st.skipLoad(`^stArgsZeroOneBalance/callNonConst.json`)
st.skipLoad(`^stPreCompiledContracts2/modexpRandomInput.json`)
st.skipLoad(`^stRandom2/randomStatetest642.json`)
st.walk(t, stateTestDir, func(t *testing.T, name string, test *StateTest) {
execStateTest(t, st, test, name, []string{"Constantinople"}, false)
})
}
// TestExecutionSpecState runs the state_test fixtures from execution-spec-tests.
type ExecutionSpecStateTestSuite struct {
suite.Suite
}
func (suite *ExecutionSpecStateTestSuite) SetupSuite() {
vm.RelaxPrecompileRangeForTest(true)
}
func (suite *ExecutionSpecStateTestSuite) TearDownSuite() {
vm.RelaxPrecompileRangeForTest(false)
}
func (suite *ExecutionSpecStateTestSuite) TestExecutionSpecState() {
t := suite.T()
if !common.FileExist(executionSpecStateTestDir) {
t.Skipf("directory %s does not exist", executionSpecStateTestDir)
}
st := new(testMatcher)
// TODO-Kaia: should remove these skip
// json format error
st.skipLoad(`^prague\/eip7702_set_code_tx\/set_code_txs\/invalid_tx_invalid_auth_signature.json`)
st.skipLoad(`^prague\/eip7702_set_code_tx\/set_code_txs\/tx_validity_chain_id.json`)
st.skipLoad(`^prague\/eip7702_set_code_tx\/set_code_txs\/tx_validity_nonce.json`)
// not yet supported EIPs
st.skipLoad(`^prague\/eip2537_bls_12_381_precompiles\/`)
st.skipLoad(`^prague\/eip7702_set_code_tx\/`)
// temporary skip failing frontier tests
st.skipLoad(`^frontier\/opcodes\/all_opcodes\/all_opcodes.json`)
st.skipLoad(`^frontier\/precompiles\/precompile_absence\/precompile_absence.json`)
// tests to skip
// unsupported EIPs
st.skipLoad(`^cancun\/eip4788_beacon_root\/`)
st.skipLoad(`^cancun\/eip4844_blobs\/`)
// calculate the different consumed gas because 0x0a and 0x0b contract is set to access list by ActivePrecompiles in Cancun
st.skipLoad(`^prague\/eip2537_bls_12_381_precompiles\/bls12_precompiles_before_fork\/precompile_before_fork.json\/tests\/prague\/eip2537_bls_12_381_precompiles\/test_bls12_precompiles_before_fork.py::test_precompile_before_fork`)
// type 3 tx (EIP-4844) is not supported
st.skipLoad(`^prague\/eip7623_increase_calldata_cost\/.*type_3.*`)
st.walk(t, executionSpecStateTestDir, func(t *testing.T, name string, test *StateTest) {
execStateTest(t, st, test, name, []string{
"Frontier",
"Homestead",
"Byzantium",
"Constantinople",
"ConstantinopleFix",
"Istanbul",
"Berlin",
"London",
"Merge",
"Paris",
"Shanghai",
// "Cancun",
// "Prague",
}, true)
})
}
func TestExecutionSpecStateTestSuite(t *testing.T) {
suite.Run(t, new(ExecutionSpecStateTestSuite))
}
func execStateTest(t *testing.T, st *testMatcher, test *StateTest, name string, skipForks []string, isTestExecutionSpecState bool) {
for _, subtest := range test.Subtests() {
subtest := subtest
key := fmt.Sprintf("%s/%d", subtest.Fork, subtest.Index)
name := name + "/" + key
t.Run(key, func(t *testing.T) {
for _, skip := range skipForks {
if skip == subtest.Fork {
t.Skipf("%s not supported yet", subtest.Fork)
}
}
withTrace(t, test.gasLimit(subtest), func(vmconfig vm.Config) error {
err := test.Run(subtest, vmconfig, isTestExecutionSpecState)
return st.checkFailure(t, name, err)
})
})
}
}
// Transactions with gasLimit above this value will not get a VM trace on failure.
const traceErrorLimit = 400000
func withTrace(t *testing.T, gasLimit uint64, test func(vm.Config) error) {
// Set ComputationCostLimit as infinite
err := test(vm.Config{ComputationCostLimit: params.OpcodeComputationCostLimitInfinite})
if err == nil {
return
}
t.Error(err)
if gasLimit > traceErrorLimit {
t.Log("gas limit too high for EVM trace")
return
}
tracer := vm.NewStructLogger(nil)
err2 := test(vm.Config{Debug: true, Tracer: tracer, ComputationCostLimit: params.OpcodeComputationCostLimitInfinite})
if !reflect.DeepEqual(err, err2) {
t.Errorf("different error for second run: %v", err2)
}
buf := new(bytes.Buffer)
vm.WriteTrace(buf, tracer.StructLogs())
if buf.Len() == 0 {
t.Log("no EVM operation logs generated")
} else {
t.Log("EVM operation log:\n" + buf.String())
}
t.Logf("EVM output: 0x%x", tracer.Output())
t.Logf("EVM error: %v", tracer.Error())
}