| 
									
										
										
										
											2015-07-07 02:54:22 +02:00
										 |  |  | // Copyright 2015 The go-ethereum Authors | 
					
						
							| 
									
										
										
										
											2015-07-22 18:48:40 +02:00
										 |  |  | // This file is part of the go-ethereum library. | 
					
						
							| 
									
										
										
										
											2015-07-07 02:54:22 +02:00
										 |  |  | // | 
					
						
							| 
									
										
										
										
											2015-07-23 18:35:11 +02:00
										 |  |  | // The go-ethereum library is free software: you can redistribute it and/or modify | 
					
						
							| 
									
										
										
										
											2015-07-07 02:54:22 +02:00
										 |  |  | // 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. | 
					
						
							|  |  |  | // | 
					
						
							| 
									
										
										
										
											2015-07-22 18:48:40 +02:00
										 |  |  | // The go-ethereum library is distributed in the hope that it will be useful, | 
					
						
							| 
									
										
										
										
											2015-07-07 02:54:22 +02:00
										 |  |  | // but WITHOUT ANY WARRANTY; without even the implied warranty of | 
					
						
							| 
									
										
										
										
											2015-07-22 18:48:40 +02:00
										 |  |  | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 
					
						
							| 
									
										
										
										
											2015-07-07 02:54:22 +02:00
										 |  |  | // GNU Lesser General Public License for more details. | 
					
						
							|  |  |  | // | 
					
						
							|  |  |  | // You should have received a copy of the GNU Lesser General Public License | 
					
						
							| 
									
										
										
										
											2015-07-22 18:48:40 +02:00
										 |  |  | // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>. | 
					
						
							| 
									
										
										
										
											2015-07-07 02:54:22 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-07-11 13:49:14 +02:00
										 |  |  | // Package tests implements execution of Ethereum JSON tests. | 
					
						
							| 
									
										
										
										
											2015-03-13 18:01:51 +01:00
										 |  |  | package tests | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | import ( | 
					
						
							|  |  |  | 	"bytes" | 
					
						
							|  |  |  | 	"encoding/hex" | 
					
						
							| 
									
										
										
										
											2017-07-11 13:49:14 +02:00
										 |  |  | 	"encoding/json" | 
					
						
							| 
									
										
										
										
											2015-03-13 18:01:51 +01:00
										 |  |  | 	"fmt" | 
					
						
							|  |  |  | 	"math/big" | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-03-16 11:27:38 +01:00
										 |  |  | 	"github.com/ethereum/go-ethereum/common" | 
					
						
							| 
									
										
										
										
											2017-07-11 13:49:14 +02:00
										 |  |  | 	"github.com/ethereum/go-ethereum/common/hexutil" | 
					
						
							|  |  |  | 	"github.com/ethereum/go-ethereum/common/math" | 
					
						
							| 
									
										
										
										
											2017-04-05 01:16:29 +03:00
										 |  |  | 	"github.com/ethereum/go-ethereum/consensus/ethash" | 
					
						
							| 
									
										
										
										
											2015-04-17 16:30:15 +02:00
										 |  |  | 	"github.com/ethereum/go-ethereum/core" | 
					
						
							| 
									
										
										
										
											2015-03-23 22:05:12 +01:00
										 |  |  | 	"github.com/ethereum/go-ethereum/core/state" | 
					
						
							| 
									
										
										
										
											2015-03-16 23:10:26 +01:00
										 |  |  | 	"github.com/ethereum/go-ethereum/core/types" | 
					
						
							| 
									
										
										
										
											2017-01-17 11:19:50 +00:00
										 |  |  | 	"github.com/ethereum/go-ethereum/core/vm" | 
					
						
							| 
									
										
										
										
											2015-06-10 12:04:56 -04:00
										 |  |  | 	"github.com/ethereum/go-ethereum/ethdb" | 
					
						
							| 
									
										
										
										
											2016-10-20 13:36:29 +02:00
										 |  |  | 	"github.com/ethereum/go-ethereum/params" | 
					
						
							| 
									
										
										
										
											2015-03-13 18:01:51 +01:00
										 |  |  | 	"github.com/ethereum/go-ethereum/rlp" | 
					
						
							|  |  |  | ) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-07-11 13:49:14 +02:00
										 |  |  | // A BlockTest checks handling of entire blocks. | 
					
						
							| 
									
										
										
										
											2015-04-20 18:14:57 +02:00
										 |  |  | type BlockTest struct { | 
					
						
							| 
									
										
										
										
											2017-07-11 13:49:14 +02:00
										 |  |  | 	json btJSON | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2015-04-20 18:14:57 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-06-05 03:31:34 -07:00
										 |  |  | // UnmarshalJSON implements json.Unmarshaler interface. | 
					
						
							| 
									
										
										
										
											2017-07-11 13:49:14 +02:00
										 |  |  | func (t *BlockTest) UnmarshalJSON(in []byte) error { | 
					
						
							|  |  |  | 	return json.Unmarshal(in, &t.json) | 
					
						
							| 
									
										
										
										
											2015-04-20 18:14:57 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-03-13 18:01:51 +01:00
										 |  |  | type btJSON struct { | 
					
						
							| 
									
										
										
										
											2017-07-11 13:49:14 +02:00
										 |  |  | 	Blocks    []btBlock             `json:"blocks"` | 
					
						
							|  |  |  | 	Genesis   btHeader              `json:"genesisBlockHeader"` | 
					
						
							|  |  |  | 	Pre       core.GenesisAlloc     `json:"pre"` | 
					
						
							|  |  |  | 	Post      core.GenesisAlloc     `json:"postState"` | 
					
						
							|  |  |  | 	BestBlock common.UnprefixedHash `json:"lastblockhash"` | 
					
						
							| 
									
										
										
										
											2017-08-10 11:38:17 +02:00
										 |  |  | 	Network   string                `json:"network"` | 
					
						
							| 
									
										
										
										
											2015-03-13 18:01:51 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-04-20 18:14:57 +02:00
										 |  |  | type btBlock struct { | 
					
						
							|  |  |  | 	BlockHeader  *btHeader | 
					
						
							|  |  |  | 	Rlp          string | 
					
						
							|  |  |  | 	UncleHeaders []*btHeader | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-07-11 13:49:14 +02:00
										 |  |  | //go:generate gencodec -type btHeader -field-override btHeaderMarshaling -out gen_btheader.go | 
					
						
							| 
									
										
										
										
											2015-03-13 18:01:51 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | type btHeader struct { | 
					
						
							| 
									
										
										
										
											2017-07-11 13:49:14 +02:00
										 |  |  | 	Bloom            types.Bloom | 
					
						
							|  |  |  | 	Coinbase         common.Address | 
					
						
							|  |  |  | 	MixHash          common.Hash | 
					
						
							|  |  |  | 	Nonce            types.BlockNonce | 
					
						
							|  |  |  | 	Number           *big.Int | 
					
						
							|  |  |  | 	Hash             common.Hash | 
					
						
							|  |  |  | 	ParentHash       common.Hash | 
					
						
							|  |  |  | 	ReceiptTrie      common.Hash | 
					
						
							|  |  |  | 	StateRoot        common.Hash | 
					
						
							|  |  |  | 	TransactionsTrie common.Hash | 
					
						
							|  |  |  | 	UncleHash        common.Hash | 
					
						
							|  |  |  | 	ExtraData        []byte | 
					
						
							|  |  |  | 	Difficulty       *big.Int | 
					
						
							| 
									
										
										
										
											2017-11-13 13:47:27 +02:00
										 |  |  | 	GasLimit         uint64 | 
					
						
							|  |  |  | 	GasUsed          uint64 | 
					
						
							| 
									
										
										
										
											2017-07-11 13:49:14 +02:00
										 |  |  | 	Timestamp        *big.Int | 
					
						
							| 
									
										
										
										
											2015-03-13 18:01:51 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-07-11 13:49:14 +02:00
										 |  |  | type btHeaderMarshaling struct { | 
					
						
							|  |  |  | 	ExtraData  hexutil.Bytes | 
					
						
							|  |  |  | 	Number     *math.HexOrDecimal256 | 
					
						
							|  |  |  | 	Difficulty *math.HexOrDecimal256 | 
					
						
							| 
									
										
										
										
											2018-01-08 13:15:57 +01:00
										 |  |  | 	GasLimit   math.HexOrDecimal64 | 
					
						
							|  |  |  | 	GasUsed    math.HexOrDecimal64 | 
					
						
							| 
									
										
										
										
											2017-07-11 13:49:14 +02:00
										 |  |  | 	Timestamp  *math.HexOrDecimal256 | 
					
						
							| 
									
										
										
										
											2015-06-14 17:55:03 -04:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-08-10 11:38:17 +02:00
										 |  |  | func (t *BlockTest) Run() error { | 
					
						
							|  |  |  | 	config, ok := Forks[t.json.Network] | 
					
						
							|  |  |  | 	if !ok { | 
					
						
							|  |  |  | 		return UnsupportedForkError{t.json.Network} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-07-11 13:49:14 +02:00
										 |  |  | 	// import pre accounts & construct test genesis block & state root | 
					
						
							| 
									
										
										
										
											2018-05-09 20:24:25 +08:00
										 |  |  | 	db := ethdb.NewMemDatabase() | 
					
						
							| 
									
										
										
										
											2017-07-11 13:49:14 +02:00
										 |  |  | 	gblock, err := t.genesis(config).Commit(db) | 
					
						
							| 
									
										
										
										
											2015-06-14 17:55:03 -04:00
										 |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		return err | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2017-07-11 13:49:14 +02:00
										 |  |  | 	if gblock.Hash() != t.json.Genesis.Hash { | 
					
						
							| 
									
										
										
										
											2018-05-02 01:20:19 -07:00
										 |  |  | 		return fmt.Errorf("genesis block hash doesn't match test: computed=%x, test=%x", gblock.Hash().Bytes()[:6], t.json.Genesis.Hash[:6]) | 
					
						
							| 
									
										
										
										
											2015-06-10 12:04:56 -04:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2017-07-11 13:49:14 +02:00
										 |  |  | 	if gblock.Root() != t.json.Genesis.StateRoot { | 
					
						
							|  |  |  | 		return fmt.Errorf("genesis block state root does not match test: computed=%x, test=%x", gblock.Root().Bytes()[:6], t.json.Genesis.StateRoot[:6]) | 
					
						
							| 
									
										
										
										
											2015-06-10 12:04:56 -04:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-05 18:40:32 +02:00
										 |  |  | 	chain, err := core.NewBlockChain(db, nil, config, ethash.NewShared(), vm.Config{}) | 
					
						
							| 
									
										
										
										
											2015-06-10 12:04:56 -04:00
										 |  |  | 	if err != nil { | 
					
						
							| 
									
										
										
										
											2015-10-06 16:35:55 +02:00
										 |  |  | 		return err | 
					
						
							| 
									
										
										
										
											2015-06-10 12:04:56 -04:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2017-02-20 12:54:23 +02:00
										 |  |  | 	defer chain.Stop() | 
					
						
							| 
									
										
										
										
											2016-03-21 23:00:39 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-07-11 13:49:14 +02:00
										 |  |  | 	validBlocks, err := t.insertBlocks(chain) | 
					
						
							| 
									
										
										
										
											2015-06-10 12:04:56 -04:00
										 |  |  | 	if err != nil { | 
					
						
							| 
									
										
										
										
											2015-06-10 16:10:33 -04:00
										 |  |  | 		return err | 
					
						
							| 
									
										
										
										
											2015-06-10 12:04:56 -04:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2018-01-30 18:39:32 +02:00
										 |  |  | 	cmlast := chain.CurrentBlock().Hash() | 
					
						
							| 
									
										
										
										
											2017-07-11 13:49:14 +02:00
										 |  |  | 	if common.Hash(t.json.BestBlock) != cmlast { | 
					
						
							|  |  |  | 		return fmt.Errorf("last block hash validation mismatch: want: %x, have: %x", t.json.BestBlock, cmlast) | 
					
						
							| 
									
										
										
										
											2015-09-18 17:15:59 +02:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2016-03-21 23:00:39 +01:00
										 |  |  | 	newDB, err := chain.State() | 
					
						
							| 
									
										
										
										
											2015-10-06 16:35:55 +02:00
										 |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		return err | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2017-07-11 13:49:14 +02:00
										 |  |  | 	if err = t.validatePostState(newDB); err != nil { | 
					
						
							| 
									
										
										
										
											2015-06-10 16:10:33 -04:00
										 |  |  | 		return fmt.Errorf("post state validation failed: %v", err) | 
					
						
							| 
									
										
										
										
											2015-06-10 12:04:56 -04:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2017-07-11 13:49:14 +02:00
										 |  |  | 	return t.validateImportedHeaders(chain, validBlocks) | 
					
						
							| 
									
										
										
										
											2015-06-10 12:04:56 -04:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-07-11 13:49:14 +02:00
										 |  |  | func (t *BlockTest) genesis(config *params.ChainConfig) *core.Genesis { | 
					
						
							|  |  |  | 	return &core.Genesis{ | 
					
						
							|  |  |  | 		Config:     config, | 
					
						
							|  |  |  | 		Nonce:      t.json.Genesis.Nonce.Uint64(), | 
					
						
							|  |  |  | 		Timestamp:  t.json.Genesis.Timestamp.Uint64(), | 
					
						
							|  |  |  | 		ParentHash: t.json.Genesis.ParentHash, | 
					
						
							|  |  |  | 		ExtraData:  t.json.Genesis.ExtraData, | 
					
						
							| 
									
										
										
										
											2017-11-13 13:47:27 +02:00
										 |  |  | 		GasLimit:   t.json.Genesis.GasLimit, | 
					
						
							|  |  |  | 		GasUsed:    t.json.Genesis.GasUsed, | 
					
						
							| 
									
										
										
										
											2017-07-11 13:49:14 +02:00
										 |  |  | 		Difficulty: t.json.Genesis.Difficulty, | 
					
						
							|  |  |  | 		Mixhash:    t.json.Genesis.MixHash, | 
					
						
							|  |  |  | 		Coinbase:   t.json.Genesis.Coinbase, | 
					
						
							|  |  |  | 		Alloc:      t.json.Pre, | 
					
						
							| 
									
										
										
										
											2015-03-20 09:10:13 +01:00
										 |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-04-20 18:14:57 +02:00
										 |  |  | /* See https://github.com/ethereum/tests/wiki/Blockchain-Tests-II | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |    Whether a block is valid or not is a bit subtle, it's defined by presence of | 
					
						
							|  |  |  |    blockHeader, transactions and uncleHeaders fields. If they are missing, the block is | 
					
						
							|  |  |  |    invalid and we must verify that we do not accept it. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |    Since some tests mix valid and invalid blocks we need to check this for every block. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |    If a block is invalid it does not necessarily fail the test, if it's invalidness is | 
					
						
							|  |  |  |    expected we are expected to ignore it and continue processing and then validate the | 
					
						
							|  |  |  |    post state. | 
					
						
							|  |  |  | */ | 
					
						
							| 
									
										
										
										
											2017-07-11 13:49:14 +02:00
										 |  |  | func (t *BlockTest) insertBlocks(blockchain *core.BlockChain) ([]btBlock, error) { | 
					
						
							| 
									
										
										
										
											2015-09-18 17:15:59 +02:00
										 |  |  | 	validBlocks := make([]btBlock, 0) | 
					
						
							| 
									
										
										
										
											2015-04-20 18:14:57 +02:00
										 |  |  | 	// insert the test blocks, which will execute all transactions | 
					
						
							| 
									
										
										
										
											2017-07-11 13:49:14 +02:00
										 |  |  | 	for _, b := range t.json.Blocks { | 
					
						
							|  |  |  | 		cb, err := b.decode() | 
					
						
							| 
									
										
										
										
											2015-04-20 18:14:57 +02:00
										 |  |  | 		if err != nil { | 
					
						
							|  |  |  | 			if b.BlockHeader == nil { | 
					
						
							|  |  |  | 				continue // OK - block is supposed to be invalid, continue with next block | 
					
						
							|  |  |  | 			} else { | 
					
						
							| 
									
										
										
										
											2015-09-18 17:15:59 +02:00
										 |  |  | 				return nil, fmt.Errorf("Block RLP decoding failed when expected to succeed: %v", err) | 
					
						
							| 
									
										
										
										
											2015-04-20 18:14:57 +02:00
										 |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		// RLP decoding worked, try to insert into chain: | 
					
						
							| 
									
										
										
										
											2016-01-19 23:48:50 +01:00
										 |  |  | 		blocks := types.Blocks{cb} | 
					
						
							|  |  |  | 		i, err := blockchain.InsertChain(blocks) | 
					
						
							| 
									
										
										
										
											2015-04-20 18:14:57 +02:00
										 |  |  | 		if err != nil { | 
					
						
							|  |  |  | 			if b.BlockHeader == nil { | 
					
						
							|  |  |  | 				continue // OK - block is supposed to be invalid, continue with next block | 
					
						
							|  |  |  | 			} else { | 
					
						
							| 
									
										
										
										
											2016-01-19 23:48:50 +01:00
										 |  |  | 				return nil, fmt.Errorf("Block #%v insertion into chain failed: %v", blocks[i].Number(), err) | 
					
						
							| 
									
										
										
										
											2015-04-20 18:14:57 +02:00
										 |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		if b.BlockHeader == nil { | 
					
						
							| 
									
										
										
										
											2015-09-18 17:15:59 +02:00
										 |  |  | 			return nil, fmt.Errorf("Block insertion should have failed") | 
					
						
							| 
									
										
										
										
											2015-04-20 18:14:57 +02:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2015-09-14 14:27:25 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		// validate RLP decoding by checking all values against test file JSON | 
					
						
							| 
									
										
										
										
											2015-09-18 17:15:59 +02:00
										 |  |  | 		if err = validateHeader(b.BlockHeader, cb.Header()); err != nil { | 
					
						
							|  |  |  | 			return nil, fmt.Errorf("Deserialised block header validation failed: %v", err) | 
					
						
							| 
									
										
										
										
											2015-04-23 04:38:47 +02:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2015-09-18 17:15:59 +02:00
										 |  |  | 		validBlocks = append(validBlocks, b) | 
					
						
							| 
									
										
										
										
											2015-04-23 04:38:47 +02:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2015-09-18 17:15:59 +02:00
										 |  |  | 	return validBlocks, nil | 
					
						
							| 
									
										
										
										
											2015-04-23 04:38:47 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-18 17:15:59 +02:00
										 |  |  | func validateHeader(h *btHeader, h2 *types.Header) error { | 
					
						
							| 
									
										
										
										
											2017-07-11 13:49:14 +02:00
										 |  |  | 	if h.Bloom != h2.Bloom { | 
					
						
							|  |  |  | 		return fmt.Errorf("Bloom: want: %x have: %x", h.Bloom, h2.Bloom) | 
					
						
							| 
									
										
										
										
											2015-04-23 04:38:47 +02:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2017-07-11 13:49:14 +02:00
										 |  |  | 	if h.Coinbase != h2.Coinbase { | 
					
						
							|  |  |  | 		return fmt.Errorf("Coinbase: want: %x have: %x", h.Coinbase, h2.Coinbase) | 
					
						
							| 
									
										
										
										
											2015-04-23 04:38:47 +02:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2017-07-11 13:49:14 +02:00
										 |  |  | 	if h.MixHash != h2.MixDigest { | 
					
						
							|  |  |  | 		return fmt.Errorf("MixHash: want: %x have: %x", h.MixHash, h2.MixDigest) | 
					
						
							| 
									
										
										
										
											2015-04-23 04:38:47 +02:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2017-07-11 13:49:14 +02:00
										 |  |  | 	if h.Nonce != h2.Nonce { | 
					
						
							|  |  |  | 		return fmt.Errorf("Nonce: want: %x have: %x", h.Nonce, h2.Nonce) | 
					
						
							| 
									
										
										
										
											2015-04-23 04:38:47 +02:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2017-07-11 13:49:14 +02:00
										 |  |  | 	if h.Number.Cmp(h2.Number) != 0 { | 
					
						
							|  |  |  | 		return fmt.Errorf("Number: want: %v have: %v", h.Number, h2.Number) | 
					
						
							| 
									
										
										
										
											2015-04-23 04:38:47 +02:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2017-07-11 13:49:14 +02:00
										 |  |  | 	if h.ParentHash != h2.ParentHash { | 
					
						
							|  |  |  | 		return fmt.Errorf("Parent hash: want: %x have: %x", h.ParentHash, h2.ParentHash) | 
					
						
							| 
									
										
										
										
											2015-04-23 04:38:47 +02:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2017-07-11 13:49:14 +02:00
										 |  |  | 	if h.ReceiptTrie != h2.ReceiptHash { | 
					
						
							|  |  |  | 		return fmt.Errorf("Receipt hash: want: %x have: %x", h.ReceiptTrie, h2.ReceiptHash) | 
					
						
							| 
									
										
										
										
											2015-04-23 04:38:47 +02:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2017-07-11 13:49:14 +02:00
										 |  |  | 	if h.TransactionsTrie != h2.TxHash { | 
					
						
							|  |  |  | 		return fmt.Errorf("Tx hash: want: %x have: %x", h.TransactionsTrie, h2.TxHash) | 
					
						
							| 
									
										
										
										
											2015-04-23 04:38:47 +02:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2017-07-11 13:49:14 +02:00
										 |  |  | 	if h.StateRoot != h2.Root { | 
					
						
							|  |  |  | 		return fmt.Errorf("State hash: want: %x have: %x", h.StateRoot, h2.Root) | 
					
						
							| 
									
										
										
										
											2015-04-23 04:38:47 +02:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2017-07-11 13:49:14 +02:00
										 |  |  | 	if h.UncleHash != h2.UncleHash { | 
					
						
							|  |  |  | 		return fmt.Errorf("Uncle hash: want: %x have: %x", h.UncleHash, h2.UncleHash) | 
					
						
							| 
									
										
										
										
											2015-04-23 04:38:47 +02:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2017-07-11 13:49:14 +02:00
										 |  |  | 	if !bytes.Equal(h.ExtraData, h2.Extra) { | 
					
						
							|  |  |  | 		return fmt.Errorf("Extra data: want: %x have: %x", h.ExtraData, h2.Extra) | 
					
						
							| 
									
										
										
										
											2015-04-17 16:30:15 +02:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2017-07-11 13:49:14 +02:00
										 |  |  | 	if h.Difficulty.Cmp(h2.Difficulty) != 0 { | 
					
						
							|  |  |  | 		return fmt.Errorf("Difficulty: want: %v have: %v", h.Difficulty, h2.Difficulty) | 
					
						
							| 
									
										
										
										
											2015-04-23 04:38:47 +02:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2017-11-13 13:47:27 +02:00
										 |  |  | 	if h.GasLimit != h2.GasLimit { | 
					
						
							|  |  |  | 		return fmt.Errorf("GasLimit: want: %d have: %d", h.GasLimit, h2.GasLimit) | 
					
						
							| 
									
										
										
										
											2015-04-23 04:38:47 +02:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2017-11-13 13:47:27 +02:00
										 |  |  | 	if h.GasUsed != h2.GasUsed { | 
					
						
							|  |  |  | 		return fmt.Errorf("GasUsed: want: %d have: %d", h.GasUsed, h2.GasUsed) | 
					
						
							| 
									
										
										
										
											2015-04-23 04:38:47 +02:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2017-07-11 13:49:14 +02:00
										 |  |  | 	if h.Timestamp.Cmp(h2.Time) != 0 { | 
					
						
							|  |  |  | 		return fmt.Errorf("Timestamp: want: %v have: %v", h.Timestamp, h2.Time) | 
					
						
							| 
									
										
										
										
											2015-04-23 04:38:47 +02:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2015-04-20 18:14:57 +02:00
										 |  |  | 	return nil | 
					
						
							| 
									
										
										
										
											2015-04-17 16:30:15 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-07-11 13:49:14 +02:00
										 |  |  | func (t *BlockTest) validatePostState(statedb *state.StateDB) error { | 
					
						
							| 
									
										
										
										
											2015-09-14 14:27:25 +02:00
										 |  |  | 	// validate post state accounts in test file against what we have in state db | 
					
						
							| 
									
										
										
										
											2017-07-11 13:49:14 +02:00
										 |  |  | 	for addr, acct := range t.json.Post { | 
					
						
							| 
									
										
										
										
											2015-03-20 09:10:13 +01:00
										 |  |  | 		// address is indirectly verified by the other fields, as it's the db key | 
					
						
							| 
									
										
										
										
											2017-07-11 13:49:14 +02:00
										 |  |  | 		code2 := statedb.GetCode(addr) | 
					
						
							|  |  |  | 		balance2 := statedb.GetBalance(addr) | 
					
						
							|  |  |  | 		nonce2 := statedb.GetNonce(addr) | 
					
						
							|  |  |  | 		if !bytes.Equal(code2, acct.Code) { | 
					
						
							|  |  |  | 			return fmt.Errorf("account code mismatch for addr: %s want: %v have: %s", addr, acct.Code, hex.EncodeToString(code2)) | 
					
						
							| 
									
										
										
										
											2015-03-20 09:10:13 +01:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2017-07-11 13:49:14 +02:00
										 |  |  | 		if balance2.Cmp(acct.Balance) != 0 { | 
					
						
							|  |  |  | 			return fmt.Errorf("account balance mismatch for addr: %s, want: %d, have: %d", addr, acct.Balance, balance2) | 
					
						
							| 
									
										
										
										
											2015-03-20 09:10:13 +01:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2017-07-11 13:49:14 +02:00
										 |  |  | 		if nonce2 != acct.Nonce { | 
					
						
							|  |  |  | 			return fmt.Errorf("account nonce mismatch for addr: %s want: %d have: %d", addr, acct.Nonce, nonce2) | 
					
						
							| 
									
										
										
										
											2015-03-20 09:10:13 +01:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2015-03-13 18:01:51 +01:00
										 |  |  | 	} | 
					
						
							|  |  |  | 	return nil | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-07-11 13:49:14 +02:00
										 |  |  | func (t *BlockTest) validateImportedHeaders(cm *core.BlockChain, validBlocks []btBlock) error { | 
					
						
							| 
									
										
										
										
											2015-09-18 17:15:59 +02:00
										 |  |  | 	// to get constant lookup when verifying block headers by hash (some tests have many blocks) | 
					
						
							| 
									
										
										
										
											2017-07-11 13:49:14 +02:00
										 |  |  | 	bmap := make(map[common.Hash]btBlock, len(t.json.Blocks)) | 
					
						
							| 
									
										
										
										
											2015-09-18 17:15:59 +02:00
										 |  |  | 	for _, b := range validBlocks { | 
					
						
							|  |  |  | 		bmap[b.BlockHeader.Hash] = b | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	// iterate over blocks backwards from HEAD and validate imported | 
					
						
							|  |  |  | 	// headers vs test file. some tests have reorgs, and we import | 
					
						
							|  |  |  | 	// block-by-block, so we can only validate imported headers after | 
					
						
							| 
									
										
										
										
											2017-07-11 13:49:14 +02:00
										 |  |  | 	// all blocks have been processed by BlockChain, as they may not | 
					
						
							| 
									
										
										
										
											2015-09-18 17:15:59 +02:00
										 |  |  | 	// be part of the longest chain until last block is imported. | 
					
						
							| 
									
										
										
										
											2016-04-05 15:22:04 +02:00
										 |  |  | 	for b := cm.CurrentBlock(); b != nil && b.NumberU64() != 0; b = cm.GetBlockByHash(b.Header().ParentHash) { | 
					
						
							| 
									
										
										
										
											2017-07-11 13:49:14 +02:00
										 |  |  | 		if err := validateHeader(bmap[b.Hash()].BlockHeader, b.Header()); err != nil { | 
					
						
							| 
									
										
										
										
											2015-09-18 17:15:59 +02:00
										 |  |  | 			return fmt.Errorf("Imported block header validation failed: %v", err) | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return nil | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-07-11 13:49:14 +02:00
										 |  |  | func (bb *btBlock) decode() (*types.Block, error) { | 
					
						
							|  |  |  | 	data, err := hexutil.Decode(bb.Rlp) | 
					
						
							| 
									
										
										
										
											2015-03-13 18:01:51 +01:00
										 |  |  | 	if err != nil { | 
					
						
							| 
									
										
										
										
											2015-06-10 18:11:30 -04:00
										 |  |  | 		return nil, err | 
					
						
							| 
									
										
										
										
											2015-03-13 18:01:51 +01:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2017-07-11 13:49:14 +02:00
										 |  |  | 	var b types.Block | 
					
						
							|  |  |  | 	err = rlp.DecodeBytes(data, &b) | 
					
						
							|  |  |  | 	return &b, err | 
					
						
							| 
									
										
										
										
											2015-04-15 22:37:16 +02:00
										 |  |  | } |