forked from cerc-io/plugeth
core/vm, tests: update tests, enable constantinople statetests, fix SAR opcode (#17538)
This commit does a few things at once: - Updates the tests to contain the latest data from ethereum/tests repo. - Enables Constantinople state tests. This is needed to be able to fuzz-test the evm with constantinople rules. - Fixes the error in opSAR that we've known about for some time. I was kind of saving it to see if we hit upon it with the random test generator, but it's difficult to both enable the tests and have the bug there -- we don't want to forget about it, so maybe it's better to just fix it.
This commit is contained in:
parent
6a33954731
commit
32f28a9360
@ -355,7 +355,7 @@ func opSAR(pc *uint64, interpreter *EVMInterpreter, contract *Contract, memory *
|
|||||||
defer interpreter.intPool.put(shift) // First operand back into the pool
|
defer interpreter.intPool.put(shift) // First operand back into the pool
|
||||||
|
|
||||||
if shift.Cmp(common.Big256) >= 0 {
|
if shift.Cmp(common.Big256) >= 0 {
|
||||||
if value.Sign() > 0 {
|
if value.Sign() >= 0 {
|
||||||
value.SetUint64(0)
|
value.SetUint64(0)
|
||||||
} else {
|
} else {
|
||||||
value.SetInt64(-1)
|
value.SetInt64(-1)
|
||||||
|
@ -30,11 +30,11 @@ func TestBlockchain(t *testing.T) {
|
|||||||
bt.skipLoad(`^bcForgedTest/bcForkUncle\.json`)
|
bt.skipLoad(`^bcForgedTest/bcForkUncle\.json`)
|
||||||
bt.skipLoad(`^bcMultiChainTest/(ChainAtoChainB_blockorder|CallContractFromNotBestBlock)`)
|
bt.skipLoad(`^bcMultiChainTest/(ChainAtoChainB_blockorder|CallContractFromNotBestBlock)`)
|
||||||
bt.skipLoad(`^bcTotalDifficultyTest/(lotsOfLeafs|lotsOfBranches|sideChainWithMoreTransactions)`)
|
bt.skipLoad(`^bcTotalDifficultyTest/(lotsOfLeafs|lotsOfBranches|sideChainWithMoreTransactions)`)
|
||||||
// Constantinople is not implemented yet.
|
// This test is broken
|
||||||
bt.skipLoad(`(?i)(constantinople)`)
|
bt.fails(`blockhashNonConstArg_Constantinople`, "Broken test")
|
||||||
|
|
||||||
// Still failing tests
|
// Still failing tests
|
||||||
bt.skipLoad(`^bcWalletTest.*_Byzantium$`)
|
// bt.skipLoad(`^bcWalletTest.*_Byzantium$`)
|
||||||
|
|
||||||
bt.walk(t, blockTestDir, func(t *testing.T, name string, test *BlockTest) {
|
bt.walk(t, blockTestDir, func(t *testing.T, name string, test *BlockTest) {
|
||||||
if err := bt.checkFailure(t, name, test.Run()); err != nil {
|
if err := bt.checkFailure(t, name, test.Run()); err != nil {
|
||||||
|
@ -91,6 +91,7 @@ type testMatcher struct {
|
|||||||
failpat []testFailure
|
failpat []testFailure
|
||||||
skiploadpat []*regexp.Regexp
|
skiploadpat []*regexp.Regexp
|
||||||
skipshortpat []*regexp.Regexp
|
skipshortpat []*regexp.Regexp
|
||||||
|
whitelistpat *regexp.Regexp
|
||||||
}
|
}
|
||||||
|
|
||||||
type testConfig struct {
|
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})
|
tm.failpat = append(tm.failpat, testFailure{regexp.MustCompile(pattern), reason})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (tm *testMatcher) whitelist(pattern string) {
|
||||||
|
tm.whitelistpat = regexp.MustCompile(pattern)
|
||||||
|
}
|
||||||
|
|
||||||
// config defines chain config for tests matching the pattern.
|
// config defines chain config for tests matching the pattern.
|
||||||
func (tm *testMatcher) config(pattern string, cfg params.ChainConfig) {
|
func (tm *testMatcher) config(pattern string, cfg params.ChainConfig) {
|
||||||
tm.configpat = append(tm.configpat, testConfig{regexp.MustCompile(pattern), cfg})
|
tm.configpat = append(tm.configpat, testConfig{regexp.MustCompile(pattern), cfg})
|
||||||
@ -208,6 +213,11 @@ func (tm *testMatcher) runTestFile(t *testing.T, path, name string, runTest inte
|
|||||||
if r, _ := tm.findSkip(name); r != "" {
|
if r, _ := tm.findSkip(name); r != "" {
|
||||||
t.Skip(r)
|
t.Skip(r)
|
||||||
}
|
}
|
||||||
|
if tm.whitelistpat != nil {
|
||||||
|
if !tm.whitelistpat.MatchString(name) {
|
||||||
|
t.Skip("Skipped by whitelist")
|
||||||
|
}
|
||||||
|
}
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
// Load the file as map[string]<testType>.
|
// Load the file as map[string]<testType>.
|
||||||
|
@ -44,9 +44,6 @@ func TestState(t *testing.T) {
|
|||||||
key := fmt.Sprintf("%s/%d", subtest.Fork, subtest.Index)
|
key := fmt.Sprintf("%s/%d", subtest.Fork, subtest.Index)
|
||||||
name := name + "/" + key
|
name := name + "/" + key
|
||||||
t.Run(key, func(t *testing.T) {
|
t.Run(key, func(t *testing.T) {
|
||||||
if subtest.Fork == "Constantinople" {
|
|
||||||
t.Skip("constantinople not supported yet")
|
|
||||||
}
|
|
||||||
withTrace(t, test.gasLimit(subtest), func(vmconfig vm.Config) error {
|
withTrace(t, test.gasLimit(subtest), func(vmconfig vm.Config) error {
|
||||||
_, err := test.Run(subtest, vmconfig)
|
_, err := test.Run(subtest, vmconfig)
|
||||||
return st.checkFailure(t, name, err)
|
return st.checkFailure(t, name, err)
|
||||||
|
@ -146,7 +146,18 @@ func (t *StateTest) Run(subtest StateSubtest, vmconfig vm.Config) (*state.StateD
|
|||||||
if logs := rlpHash(statedb.Logs()); logs != common.Hash(post.Logs) {
|
if logs := rlpHash(statedb.Logs()); logs != common.Hash(post.Logs) {
|
||||||
return statedb, fmt.Errorf("post state logs hash mismatch: got %x, want %x", logs, post.Logs)
|
return statedb, fmt.Errorf("post state logs hash mismatch: got %x, want %x", logs, post.Logs)
|
||||||
}
|
}
|
||||||
root, _ := statedb.Commit(config.IsEIP158(block.Number()))
|
// Commit block
|
||||||
|
statedb.Commit(config.IsEIP158(block.Number()))
|
||||||
|
// Add 0-value mining reward. This only makes a difference in the cases
|
||||||
|
// where
|
||||||
|
// - the coinbase suicided, or
|
||||||
|
// - there are only 'bad' transactions, which aren't executed. In those cases,
|
||||||
|
// the coinbase gets no txfee, so isn't created, and thus needs to be touched
|
||||||
|
statedb.AddBalance(block.Coinbase(), new(big.Int))
|
||||||
|
// And _now_ get the state root
|
||||||
|
root := statedb.IntermediateRoot(config.IsEIP158(block.Number()))
|
||||||
|
// N.B: We need to do this in a two-step process, because the first Commit takes care
|
||||||
|
// of suicides, and we need to touch the coinbase _after_ it has potentially suicided.
|
||||||
if root != common.Hash(post.Root) {
|
if root != common.Hash(post.Root) {
|
||||||
return statedb, fmt.Errorf("post state root mismatch: got %x, want %x", root, post.Root)
|
return statedb, fmt.Errorf("post state root mismatch: got %x, want %x", root, post.Root)
|
||||||
}
|
}
|
||||||
|
@ -1 +1 @@
|
|||||||
Subproject commit 2bb0c3da3bbb15c528bcef2a7e5ac4bd73f81f87
|
Subproject commit ad2184adca367c0b68c65b44519dba16e1d0b9e2
|
Loading…
Reference in New Issue
Block a user