Commit 075815e5 authored by Gustav Simonsson's avatar Gustav Simonsson

tests: update common test wrappers and test files

parent 216c486a
...@@ -44,8 +44,9 @@ import ( ...@@ -44,8 +44,9 @@ import (
type BlockTest struct { type BlockTest struct {
Genesis *types.Block Genesis *types.Block
Json *btJSON Json *btJSON
preAccounts map[string]btAccount preAccounts map[string]btAccount
postAccounts map[string]btAccount
} }
type btJSON struct { type btJSON struct {
...@@ -147,7 +148,6 @@ func runBlockTests(bt map[string]*BlockTest, skipTests []string) error { ...@@ -147,7 +148,6 @@ func runBlockTests(bt map[string]*BlockTest, skipTests []string) error {
glog.Infoln("Skipping block test", name) glog.Infoln("Skipping block test", name)
continue continue
} }
// test the block // test the block
if err := runBlockTest(test); err != nil { if err := runBlockTest(test); err != nil {
return fmt.Errorf("%s: %v", name, err) return fmt.Errorf("%s: %v", name, err)
...@@ -173,7 +173,7 @@ func runBlockTest(test *BlockTest) error { ...@@ -173,7 +173,7 @@ func runBlockTest(test *BlockTest) error {
} }
// import pre accounts // import pre accounts
statedb, err := test.InsertPreState(ethereum) _, err = test.InsertPreState(ethereum)
if err != nil { if err != nil {
return fmt.Errorf("InsertPreState: %v", err) return fmt.Errorf("InsertPreState: %v", err)
} }
...@@ -183,7 +183,8 @@ func runBlockTest(test *BlockTest) error { ...@@ -183,7 +183,8 @@ func runBlockTest(test *BlockTest) error {
return err return err
} }
if err = test.ValidatePostState(statedb); err != nil { newDB := ethereum.ChainManager().State()
if err = test.ValidatePostState(newDB); err != nil {
return fmt.Errorf("post state validation failed: %v", err) return fmt.Errorf("post state validation failed: %v", err)
} }
return nil return nil
...@@ -265,6 +266,7 @@ func (t *BlockTest) InsertPreState(ethereum *eth.Ethereum) (*state.StateDB, erro ...@@ -265,6 +266,7 @@ func (t *BlockTest) InsertPreState(ethereum *eth.Ethereum) (*state.StateDB, erro
post state. post state.
*/ */
func (t *BlockTest) TryBlocksInsert(chainManager *core.ChainManager) error { func (t *BlockTest) TryBlocksInsert(chainManager *core.ChainManager) error {
blockNums := make(map[string]bool)
// insert the test blocks, which will execute all transactions // insert the test blocks, which will execute all transactions
for _, b := range t.Json.Blocks { for _, b := range t.Json.Blocks {
cb, err := mustConvertBlock(b) cb, err := mustConvertBlock(b)
...@@ -287,9 +289,35 @@ func (t *BlockTest) TryBlocksInsert(chainManager *core.ChainManager) error { ...@@ -287,9 +289,35 @@ func (t *BlockTest) TryBlocksInsert(chainManager *core.ChainManager) error {
if b.BlockHeader == nil { if b.BlockHeader == nil {
return fmt.Errorf("Block insertion should have failed") return fmt.Errorf("Block insertion should have failed")
} }
err = t.validateBlockHeader(b.BlockHeader, cb.Header())
if err != nil { // validate RLP decoding by checking all values against test file JSON
return fmt.Errorf("Block header validation failed: %v", err) if err = t.validateBlockHeader(b.BlockHeader, cb.Header()); err != nil {
return fmt.Errorf("Deserialised block header validation failed: %v", err)
}
// validate the imported header against test file JSON
/*
TODO: currently test files do not contain information on what
reorg is expected other than possibly the post state (which may
or may not depend on a specific chain).
discussed with winswega and it was agreed to add this information
to the test files explicitly.
meanwhile we skip header validation on blocks with the same block
number as a prior block, since this test code cannot know what
blocks are in the longest chain without making use of the very
protocol rules the tests verify or rely on the correctness of the
code that is being tested.
*/
if !blockNums[b.BlockHeader.Number] {
importedBlock := chainManager.CurrentBlock()
if err = t.validateBlockHeader(b.BlockHeader, importedBlock.Header()); err != nil {
return fmt.Errorf("Imported block header validation failed: %v", err)
}
blockNums[b.BlockHeader.Number] = true
} }
} }
return nil return nil
...@@ -298,83 +326,84 @@ func (t *BlockTest) TryBlocksInsert(chainManager *core.ChainManager) error { ...@@ -298,83 +326,84 @@ func (t *BlockTest) TryBlocksInsert(chainManager *core.ChainManager) error {
func (s *BlockTest) validateBlockHeader(h *btHeader, h2 *types.Header) error { func (s *BlockTest) validateBlockHeader(h *btHeader, h2 *types.Header) error {
expectedBloom := mustConvertBytes(h.Bloom) expectedBloom := mustConvertBytes(h.Bloom)
if !bytes.Equal(expectedBloom, h2.Bloom.Bytes()) { if !bytes.Equal(expectedBloom, h2.Bloom.Bytes()) {
return fmt.Errorf("Bloom: expected: %v, decoded: %v", expectedBloom, h2.Bloom.Bytes()) return fmt.Errorf("Bloom: want: %x have: %x", expectedBloom, h2.Bloom.Bytes())
} }
expectedCoinbase := mustConvertBytes(h.Coinbase) expectedCoinbase := mustConvertBytes(h.Coinbase)
if !bytes.Equal(expectedCoinbase, h2.Coinbase.Bytes()) { if !bytes.Equal(expectedCoinbase, h2.Coinbase.Bytes()) {
return fmt.Errorf("Coinbase: expected: %v, decoded: %v", expectedCoinbase, h2.Coinbase.Bytes()) return fmt.Errorf("Coinbase: want: %x have: %x", expectedCoinbase, h2.Coinbase.Bytes())
} }
expectedMixHashBytes := mustConvertBytes(h.MixHash) expectedMixHashBytes := mustConvertBytes(h.MixHash)
if !bytes.Equal(expectedMixHashBytes, h2.MixDigest.Bytes()) { if !bytes.Equal(expectedMixHashBytes, h2.MixDigest.Bytes()) {
return fmt.Errorf("MixHash: expected: %v, decoded: %v", expectedMixHashBytes, h2.MixDigest.Bytes()) return fmt.Errorf("MixHash: want: %x have: %x", expectedMixHashBytes, h2.MixDigest.Bytes())
} }
expectedNonce := mustConvertBytes(h.Nonce) expectedNonce := mustConvertBytes(h.Nonce)
if !bytes.Equal(expectedNonce, h2.Nonce[:]) { if !bytes.Equal(expectedNonce, h2.Nonce[:]) {
return fmt.Errorf("Nonce: expected: %v, decoded: %v", expectedNonce, h2.Nonce) return fmt.Errorf("Nonce: want: %x have: %x", expectedNonce, h2.Nonce)
} }
expectedNumber := mustConvertBigInt(h.Number, 16) expectedNumber := mustConvertBigInt(h.Number, 16)
if expectedNumber.Cmp(h2.Number) != 0 { if expectedNumber.Cmp(h2.Number) != 0 {
return fmt.Errorf("Number: expected: %v, decoded: %v", expectedNumber, h2.Number) return fmt.Errorf("Number: want: %v have: %v", expectedNumber, h2.Number)
} }
expectedParentHash := mustConvertBytes(h.ParentHash) expectedParentHash := mustConvertBytes(h.ParentHash)
if !bytes.Equal(expectedParentHash, h2.ParentHash.Bytes()) { if !bytes.Equal(expectedParentHash, h2.ParentHash.Bytes()) {
return fmt.Errorf("Parent hash: expected: %v, decoded: %v", expectedParentHash, h2.ParentHash.Bytes()) return fmt.Errorf("Parent hash: want: %x have: %x", expectedParentHash, h2.ParentHash.Bytes())
} }
expectedReceiptHash := mustConvertBytes(h.ReceiptTrie) expectedReceiptHash := mustConvertBytes(h.ReceiptTrie)
if !bytes.Equal(expectedReceiptHash, h2.ReceiptHash.Bytes()) { if !bytes.Equal(expectedReceiptHash, h2.ReceiptHash.Bytes()) {
return fmt.Errorf("Receipt hash: expected: %v, decoded: %v", expectedReceiptHash, h2.ReceiptHash.Bytes()) return fmt.Errorf("Receipt hash: want: %x have: %x", expectedReceiptHash, h2.ReceiptHash.Bytes())
} }
expectedTxHash := mustConvertBytes(h.TransactionsTrie) expectedTxHash := mustConvertBytes(h.TransactionsTrie)
if !bytes.Equal(expectedTxHash, h2.TxHash.Bytes()) { if !bytes.Equal(expectedTxHash, h2.TxHash.Bytes()) {
return fmt.Errorf("Tx hash: expected: %v, decoded: %v", expectedTxHash, h2.TxHash.Bytes()) return fmt.Errorf("Tx hash: want: %x have: %x", expectedTxHash, h2.TxHash.Bytes())
} }
expectedStateHash := mustConvertBytes(h.StateRoot) expectedStateHash := mustConvertBytes(h.StateRoot)
if !bytes.Equal(expectedStateHash, h2.Root.Bytes()) { if !bytes.Equal(expectedStateHash, h2.Root.Bytes()) {
return fmt.Errorf("State hash: expected: %v, decoded: %v", expectedStateHash, h2.Root.Bytes()) return fmt.Errorf("State hash: want: %x have: %x", expectedStateHash, h2.Root.Bytes())
} }
expectedUncleHash := mustConvertBytes(h.UncleHash) expectedUncleHash := mustConvertBytes(h.UncleHash)
if !bytes.Equal(expectedUncleHash, h2.UncleHash.Bytes()) { if !bytes.Equal(expectedUncleHash, h2.UncleHash.Bytes()) {
return fmt.Errorf("Uncle hash: expected: %v, decoded: %v", expectedUncleHash, h2.UncleHash.Bytes()) return fmt.Errorf("Uncle hash: want: %x have: %x", expectedUncleHash, h2.UncleHash.Bytes())
} }
expectedExtraData := mustConvertBytes(h.ExtraData) expectedExtraData := mustConvertBytes(h.ExtraData)
if !bytes.Equal(expectedExtraData, h2.Extra) { if !bytes.Equal(expectedExtraData, h2.Extra) {
return fmt.Errorf("Extra data: expected: %v, decoded: %v", expectedExtraData, h2.Extra) return fmt.Errorf("Extra data: want: %x have: %x", expectedExtraData, h2.Extra)
} }
expectedDifficulty := mustConvertBigInt(h.Difficulty, 16) expectedDifficulty := mustConvertBigInt(h.Difficulty, 16)
if expectedDifficulty.Cmp(h2.Difficulty) != 0 { if expectedDifficulty.Cmp(h2.Difficulty) != 0 {
return fmt.Errorf("Difficulty: expected: %v, decoded: %v", expectedDifficulty, h2.Difficulty) return fmt.Errorf("Difficulty: want: %v have: %v", expectedDifficulty, h2.Difficulty)
} }
expectedGasLimit := mustConvertBigInt(h.GasLimit, 16) expectedGasLimit := mustConvertBigInt(h.GasLimit, 16)
if expectedGasLimit.Cmp(h2.GasLimit) != 0 { if expectedGasLimit.Cmp(h2.GasLimit) != 0 {
return fmt.Errorf("GasLimit: expected: %v, decoded: %v", expectedGasLimit, h2.GasLimit) return fmt.Errorf("GasLimit: want: %v have: %v", expectedGasLimit, h2.GasLimit)
} }
expectedGasUsed := mustConvertBigInt(h.GasUsed, 16) expectedGasUsed := mustConvertBigInt(h.GasUsed, 16)
if expectedGasUsed.Cmp(h2.GasUsed) != 0 { if expectedGasUsed.Cmp(h2.GasUsed) != 0 {
return fmt.Errorf("GasUsed: expected: %v, decoded: %v", expectedGasUsed, h2.GasUsed) return fmt.Errorf("GasUsed: want: %v have: %v", expectedGasUsed, h2.GasUsed)
} }
expectedTimestamp := mustConvertBigInt(h.Timestamp, 16) expectedTimestamp := mustConvertBigInt(h.Timestamp, 16)
if expectedTimestamp.Cmp(h2.Time) != 0 { if expectedTimestamp.Cmp(h2.Time) != 0 {
return fmt.Errorf("Timestamp: expected: %v, decoded: %v", expectedTimestamp, h2.Time) return fmt.Errorf("Timestamp: want: %v have: %v", expectedTimestamp, h2.Time)
} }
return nil return nil
} }
func (t *BlockTest) ValidatePostState(statedb *state.StateDB) error { func (t *BlockTest) ValidatePostState(statedb *state.StateDB) error {
for addrString, acct := range t.preAccounts { // validate post state accounts in test file against what we have in state db
for addrString, acct := range t.postAccounts {
// XXX: is is worth it checking for errors here? // XXX: is is worth it checking for errors here?
addr, err := hex.DecodeString(addrString) addr, err := hex.DecodeString(addrString)
if err != nil { if err != nil {
...@@ -398,13 +427,13 @@ func (t *BlockTest) ValidatePostState(statedb *state.StateDB) error { ...@@ -398,13 +427,13 @@ func (t *BlockTest) ValidatePostState(statedb *state.StateDB) error {
balance2 := statedb.GetBalance(common.BytesToAddress(addr)) balance2 := statedb.GetBalance(common.BytesToAddress(addr))
nonce2 := statedb.GetNonce(common.BytesToAddress(addr)) nonce2 := statedb.GetNonce(common.BytesToAddress(addr))
if !bytes.Equal(code2, code) { if !bytes.Equal(code2, code) {
return fmt.Errorf("account code mismatch, addr, found, expected: ", addrString, hex.EncodeToString(code2), hex.EncodeToString(code)) return fmt.Errorf("account code mismatch for addr: %s want: %s have: %s", addrString, hex.EncodeToString(code), hex.EncodeToString(code2))
} }
if balance2.Cmp(balance) != 0 { if balance2.Cmp(balance) != 0 {
return fmt.Errorf("account balance mismatch, addr, found, expected: ", addrString, balance2, balance) return fmt.Errorf("account balance mismatch for addr: %s, want: %d, have: %d", addrString, balance, balance2)
} }
if nonce2 != nonce { if nonce2 != nonce {
return fmt.Errorf("account nonce mismatch, addr, found, expected: ", addrString, nonce2, nonce) return fmt.Errorf("account nonce mismatch for addr: %s want: %d have: %d", addrString, nonce, nonce2)
} }
} }
return nil return nil
...@@ -432,7 +461,7 @@ func convertBlockTest(in *btJSON) (out *BlockTest, err error) { ...@@ -432,7 +461,7 @@ func convertBlockTest(in *btJSON) (out *BlockTest, err error) {
err = fmt.Errorf("%v\n%s", recovered, buf) err = fmt.Errorf("%v\n%s", recovered, buf)
} }
}() }()
out = &BlockTest{preAccounts: in.Pre, Json: in} out = &BlockTest{preAccounts: in.Pre, postAccounts: in.PostState, Json: in}
out.Genesis = mustConvertGenesis(in.GenesisBlockHeader) out.Genesis = mustConvertGenesis(in.GenesisBlockHeader)
return out, err return out, err
} }
......
This diff is collapsed.
...@@ -4826,23 +4826,23 @@ ...@@ -4826,23 +4826,23 @@
"lastblockhash" : "eed1b4da708283370856fc76352d68f36d9766b7f366da372e2992ced9a1f663", "lastblockhash" : "eed1b4da708283370856fc76352d68f36d9766b7f366da372e2992ced9a1f663",
"postState" : { "postState" : {
"095e7baea6a6c7c4c2dfeb977efac326af552d87" : { "095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
"balance" : "0x14", "balance" : "0x1e",
"code" : "0x", "code" : "0x",
"nonce" : "0x00", "nonce" : "0x00",
"storage" : { "storage" : {
} }
}, },
"8888f1f195afa192cfee860698584c030f4c9db1" : { "8888f1f195afa192cfee860698584c030f4c9db1" : {
"balance" : "0x8ac7230489e8a410", "balance" : "0xd255d112e1049618",
"code" : "0x", "code" : "0x",
"nonce" : "0x00", "nonce" : "0x00",
"storage" : { "storage" : {
} }
}, },
"a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
"balance" : "0x09184e71fbdc", "balance" : "0x09184e71a9ca",
"code" : "0x", "code" : "0x",
"nonce" : "0x02", "nonce" : "0x03",
"storage" : { "storage" : {
} }
} }
......
This diff is collapsed.
...@@ -4845,6 +4845,41 @@ ...@@ -4845,6 +4845,41 @@
} }
} }
}, },
"sstore_underflow" : {
"env" : {
"currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba",
"currentDifficulty" : "0x0100",
"currentGasLimit" : "0x0f4240",
"currentNumber" : "0x00",
"currentTimestamp" : "0x01"
},
"exec" : {
"address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6",
"caller" : "cd1722f3947def4cf144679da39c4c32bdc35681",
"code" : "0x600155",
"data" : "0x",
"gas" : "0x0186a0",
"gasPrice" : "0x5af3107a4000",
"origin" : "cd1722f3947def4cf144679da39c4c32bdc35681",
"value" : "0x0de0b6b3a7640000"
},
"expect" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
"storage" : {
"0x01" : "0x00"
}
}
},
"pre" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
"balance" : "0x152d02c7e14af6800000",
"code" : "0x600155",
"nonce" : "0x00",
"storage" : {
}
}
}
},
"stack_loop" : { "stack_loop" : {
"callcreates" : [ "callcreates" : [
], ],
......
...@@ -181,9 +181,6 @@ func runStateTest(test VmTest) error { ...@@ -181,9 +181,6 @@ func runStateTest(test VmTest) error {
// check post state // check post state
for addr, account := range test.Post { for addr, account := range test.Post {
obj := statedb.GetStateObject(common.HexToAddress(addr)) obj := statedb.GetStateObject(common.HexToAddress(addr))
if obj == nil {
continue
}
if obj.Balance().Cmp(common.Big(account.Balance)) != 0 { if obj.Balance().Cmp(common.Big(account.Balance)) != 0 {
return fmt.Errorf("(%x) balance failed. Expected %v, got %v => %v\n", obj.Address().Bytes()[:4], account.Balance, obj.Balance(), new(big.Int).Sub(common.Big(account.Balance), obj.Balance())) return fmt.Errorf("(%x) balance failed. Expected %v, got %v => %v\n", obj.Address().Bytes()[:4], account.Balance, obj.Balance(), new(big.Int).Sub(common.Big(account.Balance), obj.Balance()))
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment