tests: update tests, use blockchain test "network" field

Blockchain tests now include the "network" which determines the chain
config to use. Remove config matching based on test name and share the
name-to-config index with state tests.

Byzantium/Constantinople tests are still skipped because most of them
fail anyway.
This commit is contained in:
Felix Lange 2017-08-10 11:38:17 +02:00
parent 17ce0a37de
commit 6a56b15019
6 changed files with 111 additions and 85 deletions

View File

@ -17,10 +17,7 @@
package tests package tests
import ( import (
"math/big"
"testing" "testing"
"github.com/ethereum/go-ethereum/params"
) )
func TestBlockchain(t *testing.T) { func TestBlockchain(t *testing.T) {
@ -30,51 +27,19 @@ func TestBlockchain(t *testing.T) {
// General state tests are 'exported' as blockchain tests, but we can run them natively. // General state tests are 'exported' as blockchain tests, but we can run them natively.
bt.skipLoad(`^GeneralStateTests/`) bt.skipLoad(`^GeneralStateTests/`)
// Skip random failures due to selfish mining test. // Skip random failures due to selfish mining test.
bt.skipLoad(`bcForkUncle\.json/ForkUncle`) bt.skipLoad(`^bcForgedTest/bcForkUncle\.json`)
bt.skipLoad(`^bcMultiChainTest\.json/ChainAtoChainB_blockorder`) bt.skipLoad(`^bcMultiChainTest/(ChainAtoChainB_blockorder|CallContractFromNotBestBlock)`)
bt.skipLoad(`^bcTotalDifficultyTest\.json/(lotsOfLeafs|lotsOfBranches|sideChainWithMoreTransactions)$`) bt.skipLoad(`^bcTotalDifficultyTest/(lotsOfLeafs|lotsOfBranches|sideChainWithMoreTransactions)`)
bt.skipLoad(`^bcMultiChainTest\.json/CallContractFromNotBestBlock`) // Constantinople is not implemented yet.
bt.skipLoad(`(?i)(constantinople)`)
// Expected failures: // Expected failures:
bt.fails(`(?i)metropolis`, "metropolis is not supported yet") bt.fails("^TransitionTests/bcEIP158ToByzantium", "byzantium not supported")
bt.fails(`^TestNetwork/bcTheDaoTest\.json/(DaoTransactions$|DaoTransactions_UncleExtradata$)`, "issue in test") bt.fails(`^TransitionTests/bcHomesteadToDao/DaoTransactions(|_UncleExtradata|_EmptyTransactionAndForkBlocksAhead)\.json`, "issue in test")
bt.fails(`^bc(Exploit|Fork|Gas|Multi|Total|State|Random|Uncle|Valid|Wallet).*_Byzantium$`, "byzantium not supported")
bt.config(`^TestNetwork/`, params.ChainConfig{ bt.fails(`^bcBlockGasLimitTest/(BlockGasLimit2p63m1|TransactionGasHigherThanLimit2p63m1|SuicideTransaction|GasUsedHigherThanBlockGasLimitButNotWithRefundsSuicideFirst|TransactionGasHigherThanLimit2p63m1_2).*_Byzantium$`, "byzantium not supported")
HomesteadBlock: big.NewInt(5),
DAOForkBlock: big.NewInt(8),
DAOForkSupport: true,
EIP150Block: big.NewInt(10),
EIP155Block: big.NewInt(10),
EIP158Block: big.NewInt(14),
// MetropolisBlock: big.NewInt(16),
})
bt.config(`^RandomTests/.*EIP150`, params.ChainConfig{
HomesteadBlock: big.NewInt(0),
EIP150Block: big.NewInt(0),
})
bt.config(`^RandomTests/.*EIP158`, params.ChainConfig{
HomesteadBlock: big.NewInt(0),
EIP150Block: big.NewInt(0),
EIP155Block: big.NewInt(0),
EIP158Block: big.NewInt(0),
})
bt.config(`^RandomTests/`, params.ChainConfig{
HomesteadBlock: big.NewInt(0),
EIP150Block: big.NewInt(10),
})
bt.config(`^Homestead/`, params.ChainConfig{
HomesteadBlock: big.NewInt(0),
})
bt.config(`^EIP150/`, params.ChainConfig{
HomesteadBlock: big.NewInt(0),
EIP150Block: big.NewInt(0),
})
bt.config(`^[^/]+\.json`, params.ChainConfig{
HomesteadBlock: big.NewInt(1000000),
})
bt.walk(t, blockTestDir, func(t *testing.T, name string, test *BlockTest) { bt.walk(t, blockTestDir, func(t *testing.T, name string, test *BlockTest) {
cfg := bt.findConfig(name) if err := bt.checkFailure(t, name, test.Run()); err != nil {
if err := bt.checkFailure(t, name, test.Run(cfg)); err != nil {
t.Error(err) t.Error(err)
} }
}) })

View File

@ -53,6 +53,7 @@ type btJSON struct {
Pre core.GenesisAlloc `json:"pre"` Pre core.GenesisAlloc `json:"pre"`
Post core.GenesisAlloc `json:"postState"` Post core.GenesisAlloc `json:"postState"`
BestBlock common.UnprefixedHash `json:"lastblockhash"` BestBlock common.UnprefixedHash `json:"lastblockhash"`
Network string `json:"network"`
} }
type btBlock struct { type btBlock struct {
@ -91,7 +92,12 @@ type btHeaderMarshaling struct {
Timestamp *math.HexOrDecimal256 Timestamp *math.HexOrDecimal256
} }
func (t *BlockTest) Run(config *params.ChainConfig) error { func (t *BlockTest) Run() error {
config, ok := Forks[t.json.Network]
if !ok {
return UnsupportedForkError{t.json.Network}
}
// import pre accounts & construct test genesis block & state root // import pre accounts & construct test genesis block & state root
db, _ := ethdb.NewMemDatabase() db, _ := ethdb.NewMemDatabase()
gblock, err := t.genesis(config).Commit(db) gblock, err := t.genesis(config).Commit(db)

88
tests/init.go Normal file
View File

@ -0,0 +1,88 @@
// Copyright 2017 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/>.
package tests
import (
"fmt"
"math/big"
"github.com/ethereum/go-ethereum/params"
)
// This table defines supported forks and their chain config.
var Forks = map[string]*params.ChainConfig{
"Frontier": &params.ChainConfig{
ChainId: big.NewInt(1),
},
"Homestead": &params.ChainConfig{
ChainId: big.NewInt(1),
HomesteadBlock: big.NewInt(0),
},
"EIP150": &params.ChainConfig{
ChainId: big.NewInt(1),
HomesteadBlock: big.NewInt(0),
EIP150Block: big.NewInt(0),
},
"EIP158": &params.ChainConfig{
ChainId: big.NewInt(1),
HomesteadBlock: big.NewInt(0),
EIP150Block: big.NewInt(0),
EIP155Block: big.NewInt(0),
EIP158Block: big.NewInt(0),
},
"Byzantium": &params.ChainConfig{
ChainId: big.NewInt(1),
HomesteadBlock: big.NewInt(0),
EIP150Block: big.NewInt(0),
EIP155Block: big.NewInt(0),
EIP158Block: big.NewInt(0),
DAOForkBlock: big.NewInt(0),
MetropolisBlock: big.NewInt(0),
},
"FrontierToHomesteadAt5": &params.ChainConfig{
ChainId: big.NewInt(1),
HomesteadBlock: big.NewInt(5),
},
"HomesteadToEIP150At5": &params.ChainConfig{
ChainId: big.NewInt(1),
HomesteadBlock: big.NewInt(0),
EIP150Block: big.NewInt(5),
},
"HomesteadToDaoAt5": &params.ChainConfig{
ChainId: big.NewInt(1),
HomesteadBlock: big.NewInt(0),
DAOForkBlock: big.NewInt(5),
DAOForkSupport: true,
},
"EIP158ToByzantiumAt5": &params.ChainConfig{
ChainId: big.NewInt(1),
HomesteadBlock: big.NewInt(0),
EIP150Block: big.NewInt(0),
EIP155Block: big.NewInt(0),
EIP158Block: big.NewInt(0),
MetropolisBlock: big.NewInt(5),
},
}
// UnsupportedForkError is returned when a test requests a fork that isn't implemented.
type UnsupportedForkError struct {
Name string
}
func (e UnsupportedForkError) Error() string {
return fmt.Sprintf("unsupported fork %q", e.Name)
}

View File

@ -33,11 +33,9 @@ func TestState(t *testing.T) {
st.skipShortMode(`^stQuadraticComplexityTest/`) st.skipShortMode(`^stQuadraticComplexityTest/`)
// Broken tests: // Broken tests:
st.skipLoad(`^stTransactionTest/OverflowGasRequire\.json`) // gasLimit > 256 bits st.skipLoad(`^stTransactionTest/OverflowGasRequire\.json`) // gasLimit > 256 bits
st.skipLoad(`^stStackTests/shallowStackOK\.json`) // bad hex encoding
st.skipLoad(`^stTransactionTest/zeroSigTransa[^/]*\.json`) // EIP-86 is not supported yet st.skipLoad(`^stTransactionTest/zeroSigTransa[^/]*\.json`) // EIP-86 is not supported yet
// Expected failures: // Expected failures:
st.fails(`^stCallCreateCallCodeTest/createJS_ExampleContract\.json`, "bug in test") st.fails(`^stCodeSizeLimit/codesizeOOGInvalidSize\.json/(Frontier|Homestead|EIP150)`,
st.fails(`^stCodeSizeLimit/codesizeOOGInvalidSize\.json/(Frontier|Homestead)`,
"code size limit implementation is not conditional on fork") "code size limit implementation is not conditional on fork")
st.fails(`^stRevertTest/RevertDepthCreateAddressCollision\.json/EIP15[08]/[67]`, "bug in test") st.fails(`^stRevertTest/RevertDepthCreateAddressCollision\.json/EIP15[08]/[67]`, "bug in test")
st.fails(`^stRevertTest/RevertPrecompiledTouch\.json/EIP158`, "bug in test") st.fails(`^stRevertTest/RevertPrecompiledTouch\.json/EIP158`, "bug in test")
@ -49,8 +47,8 @@ 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 == "Metropolis" { if subtest.Fork == "Constantinople" || subtest.Fork == "Byzantium" {
t.Skip("metropolis not supported yet") t.Skip("constantinople, byzantium not supported yet")
} }
withTrace(t, test.gasLimit(subtest), func(vmconfig vm.Config) error { withTrace(t, test.gasLimit(subtest), func(vmconfig vm.Config) error {
return st.checkFailure(t, name, test.Run(subtest, vmconfig)) return st.checkFailure(t, name, test.Run(subtest, vmconfig))

View File

@ -37,37 +37,6 @@ import (
"github.com/ethereum/go-ethereum/params" "github.com/ethereum/go-ethereum/params"
) )
// This table defines supported forks and their chain config.
var stateTestForks = map[string]*params.ChainConfig{
"Frontier": &params.ChainConfig{
ChainId: big.NewInt(1),
},
"Homestead": &params.ChainConfig{
HomesteadBlock: big.NewInt(0),
ChainId: big.NewInt(1),
},
"EIP150": &params.ChainConfig{
HomesteadBlock: big.NewInt(0),
EIP150Block: big.NewInt(0),
ChainId: big.NewInt(1),
},
"EIP158": &params.ChainConfig{
HomesteadBlock: big.NewInt(0),
EIP150Block: big.NewInt(0),
EIP155Block: big.NewInt(0),
EIP158Block: big.NewInt(0),
ChainId: big.NewInt(1),
},
"Metropolis": &params.ChainConfig{
HomesteadBlock: big.NewInt(0),
EIP150Block: big.NewInt(0),
EIP155Block: big.NewInt(0),
EIP158Block: big.NewInt(0),
MetropolisBlock: big.NewInt(0),
ChainId: big.NewInt(1),
},
}
// StateTest checks transaction processing without block context. // StateTest checks transaction processing without block context.
// See https://github.com/ethereum/EIPs/issues/176 for the test format specification. // See https://github.com/ethereum/EIPs/issues/176 for the test format specification.
type StateTest struct { type StateTest struct {
@ -167,9 +136,9 @@ func (t *StateTest) Subtests() []StateSubtest {
// Run executes a specific subtest. // Run executes a specific subtest.
func (t *StateTest) Run(subtest StateSubtest, vmconfig vm.Config) error { func (t *StateTest) Run(subtest StateSubtest, vmconfig vm.Config) error {
config, ok := stateTestForks[subtest.Fork] config, ok := Forks[subtest.Fork]
if !ok { if !ok {
return fmt.Errorf("no config for fork %q", subtest.Fork) return UnsupportedForkError{subtest.Fork}
} }
block, _ := t.genesis(config).ToBlock() block, _ := t.genesis(config).ToBlock()
db, _ := ethdb.NewMemDatabase() db, _ := ethdb.NewMemDatabase()

@ -1 +1 @@
Subproject commit f1de8c3b7fa2c2c0aa281b6b3a1ad7010356c5ff Subproject commit 815151e4cea4e73328f8586b4e61c3d7e1e9e543