Skip to content

Commit e40b447

Browse files
committed
Merge pull request ethereum#1814 from Gustav-Simonsson/common_tests
tests: update common test wrappers and test files
2 parents b94b9b0 + 47ca690 commit e40b447

File tree

8 files changed

+13127
-439
lines changed

8 files changed

+13127
-439
lines changed

cmd/geth/blocktestcmd.go

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -111,25 +111,27 @@ func runOneBlockTest(ctx *cli.Context, test *tests.BlockTest) (*eth.Ethereum, er
111111
if err != nil {
112112
return nil, err
113113
}
114-
// if err := ethereum.Start(); err != nil {
115-
// return nil, err
116-
// }
117114

118115
// import the genesis block
119116
ethereum.ResetWithGenesisBlock(test.Genesis)
120117

121118
// import pre accounts
122-
statedb, err := test.InsertPreState(ethereum)
119+
_, err = test.InsertPreState(ethereum)
123120
if err != nil {
124121
return ethereum, fmt.Errorf("InsertPreState: %v", err)
125122
}
126123

127-
if err := test.TryBlocksInsert(ethereum.ChainManager()); err != nil {
124+
cm := ethereum.ChainManager()
125+
126+
validBlocks, err := test.TryBlocksInsert(cm)
127+
if err != nil {
128128
return ethereum, fmt.Errorf("Block Test load error: %v", err)
129129
}
130130

131-
if err := test.ValidatePostState(statedb); err != nil {
131+
newDB := cm.State()
132+
if err := test.ValidatePostState(newDB); err != nil {
132133
return ethereum, fmt.Errorf("post state validation failed: %v", err)
133134
}
134-
return ethereum, nil
135+
136+
return ethereum, test.ValidateImportedHeaders(cm, validBlocks)
135137
}

tests/block_test_util.go

Lines changed: 73 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -44,15 +44,18 @@ import (
4444
type BlockTest struct {
4545
Genesis *types.Block
4646

47-
Json *btJSON
48-
preAccounts map[string]btAccount
47+
Json *btJSON
48+
preAccounts map[string]btAccount
49+
postAccounts map[string]btAccount
50+
lastblockhash string
4951
}
5052

5153
type btJSON struct {
5254
Blocks []btBlock
5355
GenesisBlockHeader btHeader
5456
Pre map[string]btAccount
5557
PostState map[string]btAccount
58+
Lastblockhash string
5659
}
5760

5861
type btBlock struct {
@@ -76,6 +79,7 @@ type btHeader struct {
7679
MixHash string
7780
Nonce string
7881
Number string
82+
Hash string
7983
ParentHash string
8084
ReceiptTrie string
8185
SeedHash string
@@ -147,7 +151,6 @@ func runBlockTests(bt map[string]*BlockTest, skipTests []string) error {
147151
glog.Infoln("Skipping block test", name)
148152
continue
149153
}
150-
151154
// test the block
152155
if err := runBlockTest(test); err != nil {
153156
return fmt.Errorf("%s: %v", name, err)
@@ -173,20 +176,29 @@ func runBlockTest(test *BlockTest) error {
173176
}
174177

175178
// import pre accounts
176-
statedb, err := test.InsertPreState(ethereum)
179+
_, err = test.InsertPreState(ethereum)
177180
if err != nil {
178181
return fmt.Errorf("InsertPreState: %v", err)
179182
}
180183

181-
err = test.TryBlocksInsert(ethereum.ChainManager())
184+
cm := ethereum.ChainManager()
185+
validBlocks, err := test.TryBlocksInsert(cm)
182186
if err != nil {
183187
return err
184188
}
185189

186-
if err = test.ValidatePostState(statedb); err != nil {
190+
lastblockhash := common.HexToHash(test.lastblockhash)
191+
cmlast := cm.LastBlockHash()
192+
if lastblockhash != cmlast {
193+
return fmt.Errorf("lastblockhash validation mismatch: want: %x, have: %x", lastblockhash, cmlast)
194+
}
195+
196+
newDB := cm.State()
197+
if err = test.ValidatePostState(newDB); err != nil {
187198
return fmt.Errorf("post state validation failed: %v", err)
188199
}
189-
return nil
200+
201+
return test.ValidateImportedHeaders(cm, validBlocks)
190202
}
191203

192204
func (test *BlockTest) makeEthConfig() *eth.Config {
@@ -264,15 +276,16 @@ func (t *BlockTest) InsertPreState(ethereum *eth.Ethereum) (*state.StateDB, erro
264276
expected we are expected to ignore it and continue processing and then validate the
265277
post state.
266278
*/
267-
func (t *BlockTest) TryBlocksInsert(chainManager *core.ChainManager) error {
279+
func (t *BlockTest) TryBlocksInsert(chainManager *core.ChainManager) ([]btBlock, error) {
280+
validBlocks := make([]btBlock, 0)
268281
// insert the test blocks, which will execute all transactions
269282
for _, b := range t.Json.Blocks {
270283
cb, err := mustConvertBlock(b)
271284
if err != nil {
272285
if b.BlockHeader == nil {
273286
continue // OK - block is supposed to be invalid, continue with next block
274287
} else {
275-
return fmt.Errorf("Block RLP decoding failed when expected to succeed: %v", err)
288+
return nil, fmt.Errorf("Block RLP decoding failed when expected to succeed: %v", err)
276289
}
277290
}
278291
// RLP decoding worked, try to insert into chain:
@@ -281,100 +294,103 @@ func (t *BlockTest) TryBlocksInsert(chainManager *core.ChainManager) error {
281294
if b.BlockHeader == nil {
282295
continue // OK - block is supposed to be invalid, continue with next block
283296
} else {
284-
return fmt.Errorf("Block insertion into chain failed: %v", err)
297+
return nil, fmt.Errorf("Block insertion into chain failed: %v", err)
285298
}
286299
}
287300
if b.BlockHeader == nil {
288-
return fmt.Errorf("Block insertion should have failed")
301+
return nil, fmt.Errorf("Block insertion should have failed")
289302
}
290-
err = t.validateBlockHeader(b.BlockHeader, cb.Header())
291-
if err != nil {
292-
return fmt.Errorf("Block header validation failed: %v", err)
303+
304+
// validate RLP decoding by checking all values against test file JSON
305+
if err = validateHeader(b.BlockHeader, cb.Header()); err != nil {
306+
return nil, fmt.Errorf("Deserialised block header validation failed: %v", err)
293307
}
308+
validBlocks = append(validBlocks, b)
294309
}
295-
return nil
310+
return validBlocks, nil
296311
}
297312

298-
func (s *BlockTest) validateBlockHeader(h *btHeader, h2 *types.Header) error {
313+
func validateHeader(h *btHeader, h2 *types.Header) error {
299314
expectedBloom := mustConvertBytes(h.Bloom)
300315
if !bytes.Equal(expectedBloom, h2.Bloom.Bytes()) {
301-
return fmt.Errorf("Bloom: expected: %v, decoded: %v", expectedBloom, h2.Bloom.Bytes())
316+
return fmt.Errorf("Bloom: want: %x have: %x", expectedBloom, h2.Bloom.Bytes())
302317
}
303318

304319
expectedCoinbase := mustConvertBytes(h.Coinbase)
305320
if !bytes.Equal(expectedCoinbase, h2.Coinbase.Bytes()) {
306-
return fmt.Errorf("Coinbase: expected: %v, decoded: %v", expectedCoinbase, h2.Coinbase.Bytes())
321+
return fmt.Errorf("Coinbase: want: %x have: %x", expectedCoinbase, h2.Coinbase.Bytes())
307322
}
308323

309324
expectedMixHashBytes := mustConvertBytes(h.MixHash)
310325
if !bytes.Equal(expectedMixHashBytes, h2.MixDigest.Bytes()) {
311-
return fmt.Errorf("MixHash: expected: %v, decoded: %v", expectedMixHashBytes, h2.MixDigest.Bytes())
326+
return fmt.Errorf("MixHash: want: %x have: %x", expectedMixHashBytes, h2.MixDigest.Bytes())
312327
}
313328

314329
expectedNonce := mustConvertBytes(h.Nonce)
315330
if !bytes.Equal(expectedNonce, h2.Nonce[:]) {
316-
return fmt.Errorf("Nonce: expected: %v, decoded: %v", expectedNonce, h2.Nonce)
331+
return fmt.Errorf("Nonce: want: %x have: %x", expectedNonce, h2.Nonce)
317332
}
318333

319334
expectedNumber := mustConvertBigInt(h.Number, 16)
320335
if expectedNumber.Cmp(h2.Number) != 0 {
321-
return fmt.Errorf("Number: expected: %v, decoded: %v", expectedNumber, h2.Number)
336+
return fmt.Errorf("Number: want: %v have: %v", expectedNumber, h2.Number)
322337
}
323338

324339
expectedParentHash := mustConvertBytes(h.ParentHash)
325340
if !bytes.Equal(expectedParentHash, h2.ParentHash.Bytes()) {
326-
return fmt.Errorf("Parent hash: expected: %v, decoded: %v", expectedParentHash, h2.ParentHash.Bytes())
341+
return fmt.Errorf("Parent hash: want: %x have: %x", expectedParentHash, h2.ParentHash.Bytes())
327342
}
328343

329344
expectedReceiptHash := mustConvertBytes(h.ReceiptTrie)
330345
if !bytes.Equal(expectedReceiptHash, h2.ReceiptHash.Bytes()) {
331-
return fmt.Errorf("Receipt hash: expected: %v, decoded: %v", expectedReceiptHash, h2.ReceiptHash.Bytes())
346+
return fmt.Errorf("Receipt hash: want: %x have: %x", expectedReceiptHash, h2.ReceiptHash.Bytes())
332347
}
333348

334349
expectedTxHash := mustConvertBytes(h.TransactionsTrie)
335350
if !bytes.Equal(expectedTxHash, h2.TxHash.Bytes()) {
336-
return fmt.Errorf("Tx hash: expected: %v, decoded: %v", expectedTxHash, h2.TxHash.Bytes())
351+
return fmt.Errorf("Tx hash: want: %x have: %x", expectedTxHash, h2.TxHash.Bytes())
337352
}
338353

339354
expectedStateHash := mustConvertBytes(h.StateRoot)
340355
if !bytes.Equal(expectedStateHash, h2.Root.Bytes()) {
341-
return fmt.Errorf("State hash: expected: %v, decoded: %v", expectedStateHash, h2.Root.Bytes())
356+
return fmt.Errorf("State hash: want: %x have: %x", expectedStateHash, h2.Root.Bytes())
342357
}
343358

344359
expectedUncleHash := mustConvertBytes(h.UncleHash)
345360
if !bytes.Equal(expectedUncleHash, h2.UncleHash.Bytes()) {
346-
return fmt.Errorf("Uncle hash: expected: %v, decoded: %v", expectedUncleHash, h2.UncleHash.Bytes())
361+
return fmt.Errorf("Uncle hash: want: %x have: %x", expectedUncleHash, h2.UncleHash.Bytes())
347362
}
348363

349364
expectedExtraData := mustConvertBytes(h.ExtraData)
350365
if !bytes.Equal(expectedExtraData, h2.Extra) {
351-
return fmt.Errorf("Extra data: expected: %v, decoded: %v", expectedExtraData, h2.Extra)
366+
return fmt.Errorf("Extra data: want: %x have: %x", expectedExtraData, h2.Extra)
352367
}
353368

354369
expectedDifficulty := mustConvertBigInt(h.Difficulty, 16)
355370
if expectedDifficulty.Cmp(h2.Difficulty) != 0 {
356-
return fmt.Errorf("Difficulty: expected: %v, decoded: %v", expectedDifficulty, h2.Difficulty)
371+
return fmt.Errorf("Difficulty: want: %v have: %v", expectedDifficulty, h2.Difficulty)
357372
}
358373

359374
expectedGasLimit := mustConvertBigInt(h.GasLimit, 16)
360375
if expectedGasLimit.Cmp(h2.GasLimit) != 0 {
361-
return fmt.Errorf("GasLimit: expected: %v, decoded: %v", expectedGasLimit, h2.GasLimit)
376+
return fmt.Errorf("GasLimit: want: %v have: %v", expectedGasLimit, h2.GasLimit)
362377
}
363378
expectedGasUsed := mustConvertBigInt(h.GasUsed, 16)
364379
if expectedGasUsed.Cmp(h2.GasUsed) != 0 {
365-
return fmt.Errorf("GasUsed: expected: %v, decoded: %v", expectedGasUsed, h2.GasUsed)
380+
return fmt.Errorf("GasUsed: want: %v have: %v", expectedGasUsed, h2.GasUsed)
366381
}
367382

368383
expectedTimestamp := mustConvertBigInt(h.Timestamp, 16)
369384
if expectedTimestamp.Cmp(h2.Time) != 0 {
370-
return fmt.Errorf("Timestamp: expected: %v, decoded: %v", expectedTimestamp, h2.Time)
385+
return fmt.Errorf("Timestamp: want: %v have: %v", expectedTimestamp, h2.Time)
371386
}
372387

373388
return nil
374389
}
375390

376391
func (t *BlockTest) ValidatePostState(statedb *state.StateDB) error {
377-
for addrString, acct := range t.preAccounts {
392+
// validate post state accounts in test file against what we have in state db
393+
for addrString, acct := range t.postAccounts {
378394
// XXX: is is worth it checking for errors here?
379395
addr, err := hex.DecodeString(addrString)
380396
if err != nil {
@@ -398,13 +414,34 @@ func (t *BlockTest) ValidatePostState(statedb *state.StateDB) error {
398414
balance2 := statedb.GetBalance(common.BytesToAddress(addr))
399415
nonce2 := statedb.GetNonce(common.BytesToAddress(addr))
400416
if !bytes.Equal(code2, code) {
401-
return fmt.Errorf("account code mismatch, addr, found, expected: ", addrString, hex.EncodeToString(code2), hex.EncodeToString(code))
417+
return fmt.Errorf("account code mismatch for addr: %s want: %s have: %s", addrString, hex.EncodeToString(code), hex.EncodeToString(code2))
402418
}
403419
if balance2.Cmp(balance) != 0 {
404-
return fmt.Errorf("account balance mismatch, addr, found, expected: ", addrString, balance2, balance)
420+
return fmt.Errorf("account balance mismatch for addr: %s, want: %d, have: %d", addrString, balance, balance2)
405421
}
406422
if nonce2 != nonce {
407-
return fmt.Errorf("account nonce mismatch, addr, found, expected: ", addrString, nonce2, nonce)
423+
return fmt.Errorf("account nonce mismatch for addr: %s want: %d have: %d", addrString, nonce, nonce2)
424+
}
425+
}
426+
return nil
427+
}
428+
429+
func (test *BlockTest) ValidateImportedHeaders(cm *core.ChainManager, validBlocks []btBlock) error {
430+
// to get constant lookup when verifying block headers by hash (some tests have many blocks)
431+
bmap := make(map[string]btBlock, len(test.Json.Blocks))
432+
for _, b := range validBlocks {
433+
bmap[b.BlockHeader.Hash] = b
434+
}
435+
436+
// iterate over blocks backwards from HEAD and validate imported
437+
// headers vs test file. some tests have reorgs, and we import
438+
// block-by-block, so we can only validate imported headers after
439+
// all blocks have been processed by ChainManager, as they may not
440+
// be part of the longest chain until last block is imported.
441+
for b := cm.CurrentBlock(); b != nil && b.NumberU64() != 0; b = cm.GetBlock(b.Header().ParentHash) {
442+
bHash := common.Bytes2Hex(b.Hash().Bytes()) // hex without 0x prefix
443+
if err := validateHeader(bmap[bHash].BlockHeader, b.Header()); err != nil {
444+
return fmt.Errorf("Imported block header validation failed: %v", err)
408445
}
409446
}
410447
return nil
@@ -432,7 +469,7 @@ func convertBlockTest(in *btJSON) (out *BlockTest, err error) {
432469
err = fmt.Errorf("%v\n%s", recovered, buf)
433470
}
434471
}()
435-
out = &BlockTest{preAccounts: in.Pre, Json: in}
472+
out = &BlockTest{preAccounts: in.Pre, postAccounts: in.PostState, Json: in, lastblockhash: in.Lastblockhash}
436473
out.Genesis = mustConvertGenesis(in.GenesisBlockHeader)
437474
return out, err
438475
}

0 commit comments

Comments
 (0)