@@ -44,15 +44,18 @@ import (
44
44
type BlockTest struct {
45
45
Genesis * types.Block
46
46
47
- Json * btJSON
48
- preAccounts map [string ]btAccount
47
+ Json * btJSON
48
+ preAccounts map [string ]btAccount
49
+ postAccounts map [string ]btAccount
50
+ lastblockhash string
49
51
}
50
52
51
53
type btJSON struct {
52
54
Blocks []btBlock
53
55
GenesisBlockHeader btHeader
54
56
Pre map [string ]btAccount
55
57
PostState map [string ]btAccount
58
+ Lastblockhash string
56
59
}
57
60
58
61
type btBlock struct {
@@ -76,6 +79,7 @@ type btHeader struct {
76
79
MixHash string
77
80
Nonce string
78
81
Number string
82
+ Hash string
79
83
ParentHash string
80
84
ReceiptTrie string
81
85
SeedHash string
@@ -147,7 +151,6 @@ func runBlockTests(bt map[string]*BlockTest, skipTests []string) error {
147
151
glog .Infoln ("Skipping block test" , name )
148
152
continue
149
153
}
150
-
151
154
// test the block
152
155
if err := runBlockTest (test ); err != nil {
153
156
return fmt .Errorf ("%s: %v" , name , err )
@@ -173,20 +176,29 @@ func runBlockTest(test *BlockTest) error {
173
176
}
174
177
175
178
// import pre accounts
176
- statedb , err : = test .InsertPreState (ethereum )
179
+ _ , err = test .InsertPreState (ethereum )
177
180
if err != nil {
178
181
return fmt .Errorf ("InsertPreState: %v" , err )
179
182
}
180
183
181
- err = test .TryBlocksInsert (ethereum .ChainManager ())
184
+ cm := ethereum .ChainManager ()
185
+ validBlocks , err := test .TryBlocksInsert (cm )
182
186
if err != nil {
183
187
return err
184
188
}
185
189
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 {
187
198
return fmt .Errorf ("post state validation failed: %v" , err )
188
199
}
189
- return nil
200
+
201
+ return test .ValidateImportedHeaders (cm , validBlocks )
190
202
}
191
203
192
204
func (test * BlockTest ) makeEthConfig () * eth.Config {
@@ -264,15 +276,16 @@ func (t *BlockTest) InsertPreState(ethereum *eth.Ethereum) (*state.StateDB, erro
264
276
expected we are expected to ignore it and continue processing and then validate the
265
277
post state.
266
278
*/
267
- func (t * BlockTest ) TryBlocksInsert (chainManager * core.ChainManager ) error {
279
+ func (t * BlockTest ) TryBlocksInsert (chainManager * core.ChainManager ) ([]btBlock , error ) {
280
+ validBlocks := make ([]btBlock , 0 )
268
281
// insert the test blocks, which will execute all transactions
269
282
for _ , b := range t .Json .Blocks {
270
283
cb , err := mustConvertBlock (b )
271
284
if err != nil {
272
285
if b .BlockHeader == nil {
273
286
continue // OK - block is supposed to be invalid, continue with next block
274
287
} 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 )
276
289
}
277
290
}
278
291
// RLP decoding worked, try to insert into chain:
@@ -281,100 +294,103 @@ func (t *BlockTest) TryBlocksInsert(chainManager *core.ChainManager) error {
281
294
if b .BlockHeader == nil {
282
295
continue // OK - block is supposed to be invalid, continue with next block
283
296
} else {
284
- return fmt .Errorf ("Block insertion into chain failed: %v" , err )
297
+ return nil , fmt .Errorf ("Block insertion into chain failed: %v" , err )
285
298
}
286
299
}
287
300
if b .BlockHeader == nil {
288
- return fmt .Errorf ("Block insertion should have failed" )
301
+ return nil , fmt .Errorf ("Block insertion should have failed" )
289
302
}
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 )
293
307
}
308
+ validBlocks = append (validBlocks , b )
294
309
}
295
- return nil
310
+ return validBlocks , nil
296
311
}
297
312
298
- func ( s * BlockTest ) validateBlockHeader (h * btHeader , h2 * types.Header ) error {
313
+ func validateHeader (h * btHeader , h2 * types.Header ) error {
299
314
expectedBloom := mustConvertBytes (h .Bloom )
300
315
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 ())
302
317
}
303
318
304
319
expectedCoinbase := mustConvertBytes (h .Coinbase )
305
320
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 ())
307
322
}
308
323
309
324
expectedMixHashBytes := mustConvertBytes (h .MixHash )
310
325
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 ())
312
327
}
313
328
314
329
expectedNonce := mustConvertBytes (h .Nonce )
315
330
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 )
317
332
}
318
333
319
334
expectedNumber := mustConvertBigInt (h .Number , 16 )
320
335
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 )
322
337
}
323
338
324
339
expectedParentHash := mustConvertBytes (h .ParentHash )
325
340
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 ())
327
342
}
328
343
329
344
expectedReceiptHash := mustConvertBytes (h .ReceiptTrie )
330
345
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 ())
332
347
}
333
348
334
349
expectedTxHash := mustConvertBytes (h .TransactionsTrie )
335
350
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 ())
337
352
}
338
353
339
354
expectedStateHash := mustConvertBytes (h .StateRoot )
340
355
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 ())
342
357
}
343
358
344
359
expectedUncleHash := mustConvertBytes (h .UncleHash )
345
360
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 ())
347
362
}
348
363
349
364
expectedExtraData := mustConvertBytes (h .ExtraData )
350
365
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 )
352
367
}
353
368
354
369
expectedDifficulty := mustConvertBigInt (h .Difficulty , 16 )
355
370
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 )
357
372
}
358
373
359
374
expectedGasLimit := mustConvertBigInt (h .GasLimit , 16 )
360
375
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 )
362
377
}
363
378
expectedGasUsed := mustConvertBigInt (h .GasUsed , 16 )
364
379
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 )
366
381
}
367
382
368
383
expectedTimestamp := mustConvertBigInt (h .Timestamp , 16 )
369
384
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 )
371
386
}
372
387
373
388
return nil
374
389
}
375
390
376
391
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 {
378
394
// XXX: is is worth it checking for errors here?
379
395
addr , err := hex .DecodeString (addrString )
380
396
if err != nil {
@@ -398,13 +414,34 @@ func (t *BlockTest) ValidatePostState(statedb *state.StateDB) error {
398
414
balance2 := statedb .GetBalance (common .BytesToAddress (addr ))
399
415
nonce2 := statedb .GetNonce (common .BytesToAddress (addr ))
400
416
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 ))
402
418
}
403
419
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 )
405
421
}
406
422
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 )
408
445
}
409
446
}
410
447
return nil
@@ -432,7 +469,7 @@ func convertBlockTest(in *btJSON) (out *BlockTest, err error) {
432
469
err = fmt .Errorf ("%v\n %s" , recovered , buf )
433
470
}
434
471
}()
435
- out = & BlockTest {preAccounts : in .Pre , Json : in }
472
+ out = & BlockTest {preAccounts : in .Pre , postAccounts : in . PostState , Json : in , lastblockhash : in . Lastblockhash }
436
473
out .Genesis = mustConvertGenesis (in .GenesisBlockHeader )
437
474
return out , err
438
475
}
0 commit comments