| 
									
										
										
										
											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
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-03-13 18:01:51 +01:00
										 |  |  | package tests | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | import ( | 
					
						
							|  |  |  | 	"bytes" | 
					
						
							|  |  |  | 	"encoding/hex" | 
					
						
							|  |  |  | 	"fmt" | 
					
						
							| 
									
										
										
										
											2015-06-14 17:55:03 -04:00
										 |  |  | 	"io" | 
					
						
							| 
									
										
										
										
											2015-03-13 18:01:51 +01:00
										 |  |  | 	"math/big" | 
					
						
							|  |  |  | 	"runtime" | 
					
						
							|  |  |  | 	"strconv" | 
					
						
							|  |  |  | 	"strings" | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-03-16 11:27:38 +01:00
										 |  |  | 	"github.com/ethereum/go-ethereum/common" | 
					
						
							| 
									
										
										
										
											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" | 
					
						
							| 
									
										
										
										
											2015-11-17 18:33:25 +02:00
										 |  |  | 	"github.com/ethereum/go-ethereum/event" | 
					
						
							| 
									
										
										
										
											2017-02-22 14:10:07 +02:00
										 |  |  | 	"github.com/ethereum/go-ethereum/log" | 
					
						
							| 
									
										
										
										
											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" | 
					
						
							|  |  |  | ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // Block Test JSON Format | 
					
						
							| 
									
										
										
										
											2015-04-20 18:14:57 +02:00
										 |  |  | type BlockTest struct { | 
					
						
							|  |  |  | 	Genesis *types.Block | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-18 17:15:59 +02:00
										 |  |  | 	Json          *btJSON | 
					
						
							|  |  |  | 	preAccounts   map[string]btAccount | 
					
						
							|  |  |  | 	postAccounts  map[string]btAccount | 
					
						
							|  |  |  | 	lastblockhash string | 
					
						
							| 
									
										
										
										
											2015-04-20 18:14:57 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-03-13 18:01:51 +01:00
										 |  |  | type btJSON struct { | 
					
						
							|  |  |  | 	Blocks             []btBlock | 
					
						
							|  |  |  | 	GenesisBlockHeader btHeader | 
					
						
							|  |  |  | 	Pre                map[string]btAccount | 
					
						
							| 
									
										
										
										
											2015-03-20 09:10:13 +01:00
										 |  |  | 	PostState          map[string]btAccount | 
					
						
							| 
									
										
										
										
											2015-09-18 17:15:59 +02:00
										 |  |  | 	Lastblockhash      string | 
					
						
							| 
									
										
										
										
											2015-03-13 18:01:51 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-04-20 18:14:57 +02:00
										 |  |  | type btBlock struct { | 
					
						
							|  |  |  | 	BlockHeader  *btHeader | 
					
						
							|  |  |  | 	Rlp          string | 
					
						
							|  |  |  | 	Transactions []btTransaction | 
					
						
							|  |  |  | 	UncleHeaders []*btHeader | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-03-13 18:01:51 +01:00
										 |  |  | type btAccount struct { | 
					
						
							| 
									
										
										
										
											2015-04-27 19:32:45 +02:00
										 |  |  | 	Balance    string | 
					
						
							|  |  |  | 	Code       string | 
					
						
							|  |  |  | 	Nonce      string | 
					
						
							|  |  |  | 	Storage    map[string]string | 
					
						
							|  |  |  | 	PrivateKey string | 
					
						
							| 
									
										
										
										
											2015-03-13 18:01:51 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | type btHeader struct { | 
					
						
							|  |  |  | 	Bloom            string | 
					
						
							|  |  |  | 	Coinbase         string | 
					
						
							|  |  |  | 	MixHash          string | 
					
						
							|  |  |  | 	Nonce            string | 
					
						
							|  |  |  | 	Number           string | 
					
						
							| 
									
										
										
										
											2015-09-18 17:15:59 +02:00
										 |  |  | 	Hash             string | 
					
						
							| 
									
										
										
										
											2015-03-13 18:01:51 +01:00
										 |  |  | 	ParentHash       string | 
					
						
							|  |  |  | 	ReceiptTrie      string | 
					
						
							|  |  |  | 	SeedHash         string | 
					
						
							|  |  |  | 	StateRoot        string | 
					
						
							|  |  |  | 	TransactionsTrie string | 
					
						
							|  |  |  | 	UncleHash        string | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	ExtraData  string | 
					
						
							|  |  |  | 	Difficulty string | 
					
						
							|  |  |  | 	GasLimit   string | 
					
						
							|  |  |  | 	GasUsed    string | 
					
						
							|  |  |  | 	Timestamp  string | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | type btTransaction struct { | 
					
						
							|  |  |  | 	Data     string | 
					
						
							|  |  |  | 	GasLimit string | 
					
						
							|  |  |  | 	GasPrice string | 
					
						
							|  |  |  | 	Nonce    string | 
					
						
							|  |  |  | 	R        string | 
					
						
							|  |  |  | 	S        string | 
					
						
							|  |  |  | 	To       string | 
					
						
							|  |  |  | 	V        string | 
					
						
							|  |  |  | 	Value    string | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-08 00:23:45 +02:00
										 |  |  | func RunBlockTestWithReader(homesteadBlock, daoForkBlock, gasPriceFork *big.Int, r io.Reader, skipTests []string) error { | 
					
						
							| 
									
										
										
										
											2015-06-14 17:55:03 -04:00
										 |  |  | 	btjs := make(map[string]*btJSON) | 
					
						
							|  |  |  | 	if err := readJson(r, &btjs); err != nil { | 
					
						
							|  |  |  | 		return err | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	bt, err := convertBlockTests(btjs) | 
					
						
							| 
									
										
										
										
											2015-06-10 12:04:56 -04:00
										 |  |  | 	if err != nil { | 
					
						
							| 
									
										
										
										
											2015-06-10 18:11:30 -04:00
										 |  |  | 		return err | 
					
						
							| 
									
										
										
										
											2015-06-10 12:04:56 -04:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-08 00:23:45 +02:00
										 |  |  | 	if err := runBlockTests(homesteadBlock, daoForkBlock, gasPriceFork, bt, skipTests); err != nil { | 
					
						
							| 
									
										
										
										
											2015-06-14 17:55:03 -04:00
										 |  |  | 		return err | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return nil | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-08 00:23:45 +02:00
										 |  |  | func RunBlockTest(homesteadBlock, daoForkBlock, gasPriceFork *big.Int, file string, skipTests []string) error { | 
					
						
							| 
									
										
										
										
											2015-06-14 17:55:03 -04:00
										 |  |  | 	btjs := make(map[string]*btJSON) | 
					
						
							|  |  |  | 	if err := readJsonFile(file, &btjs); err != nil { | 
					
						
							|  |  |  | 		return err | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	bt, err := convertBlockTests(btjs) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		return err | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2016-10-08 00:23:45 +02:00
										 |  |  | 	if err := runBlockTests(homesteadBlock, daoForkBlock, gasPriceFork, bt, skipTests); err != nil { | 
					
						
							| 
									
										
										
										
											2015-06-14 17:55:03 -04:00
										 |  |  | 		return err | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return nil | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-08 00:23:45 +02:00
										 |  |  | func runBlockTests(homesteadBlock, daoForkBlock, gasPriceFork *big.Int, bt map[string]*BlockTest, skipTests []string) error { | 
					
						
							| 
									
										
										
										
											2015-06-19 11:38:23 +02:00
										 |  |  | 	skipTest := make(map[string]bool, len(skipTests)) | 
					
						
							|  |  |  | 	for _, name := range skipTests { | 
					
						
							| 
									
										
										
										
											2015-06-10 17:04:06 -04:00
										 |  |  | 		skipTest[name] = true | 
					
						
							| 
									
										
										
										
											2015-06-10 12:04:56 -04:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	for name, test := range bt { | 
					
						
							| 
									
										
										
										
											2017-01-04 20:17:24 +01:00
										 |  |  | 		if skipTest[name] /*|| name != "CallingCanonicalContractFromFork_CALLCODE"*/ { | 
					
						
							| 
									
										
										
										
											2017-02-22 14:10:07 +02:00
										 |  |  | 			log.Info(fmt.Sprint("Skipping block test", name)) | 
					
						
							| 
									
										
										
										
											2015-07-03 09:40:07 +02:00
										 |  |  | 			continue | 
					
						
							| 
									
										
										
										
											2015-06-10 12:04:56 -04:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2015-06-10 17:04:06 -04:00
										 |  |  | 		// test the block | 
					
						
							| 
									
										
										
										
											2016-10-08 00:23:45 +02:00
										 |  |  | 		if err := runBlockTest(homesteadBlock, daoForkBlock, gasPriceFork, test); err != nil { | 
					
						
							| 
									
										
										
										
											2015-08-20 18:22:50 +02:00
										 |  |  | 			return fmt.Errorf("%s: %v", name, err) | 
					
						
							| 
									
										
										
										
											2015-06-10 17:04:06 -04:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2017-02-22 14:10:07 +02:00
										 |  |  | 		log.Info(fmt.Sprint("Block test passed: ", name)) | 
					
						
							| 
									
										
										
										
											2015-06-14 17:55:03 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-06-10 12:04:56 -04:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2015-06-10 16:10:33 -04:00
										 |  |  | 	return nil | 
					
						
							| 
									
										
										
										
											2015-06-14 17:55:03 -04:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2015-07-10 14:29:40 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-08 00:23:45 +02:00
										 |  |  | func runBlockTest(homesteadBlock, daoForkBlock, gasPriceFork *big.Int, test *BlockTest) error { | 
					
						
							| 
									
										
										
										
											2015-10-06 16:35:55 +02:00
										 |  |  | 	// import pre accounts & construct test genesis block & state root | 
					
						
							| 
									
										
										
										
											2016-03-21 23:00:39 +01:00
										 |  |  | 	db, _ := ethdb.NewMemDatabase() | 
					
						
							|  |  |  | 	if _, err := test.InsertPreState(db); err != nil { | 
					
						
							| 
									
										
										
										
											2015-10-06 16:35:55 +02:00
										 |  |  | 		return fmt.Errorf("InsertPreState: %v", err) | 
					
						
							| 
									
										
										
										
											2015-06-10 12:04:56 -04:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-05 15:22:04 +02:00
										 |  |  | 	core.WriteTd(db, test.Genesis.Hash(), 0, test.Genesis.Difficulty()) | 
					
						
							| 
									
										
										
										
											2016-03-21 23:00:39 +01:00
										 |  |  | 	core.WriteBlock(db, test.Genesis) | 
					
						
							|  |  |  | 	core.WriteCanonicalHash(db, test.Genesis.Hash(), test.Genesis.NumberU64()) | 
					
						
							|  |  |  | 	core.WriteHeadBlockHash(db, test.Genesis.Hash()) | 
					
						
							|  |  |  | 	evmux := new(event.TypeMux) | 
					
						
							| 
									
										
										
										
											2016-10-20 13:36:29 +02:00
										 |  |  | 	config := ¶ms.ChainConfig{HomesteadBlock: homesteadBlock, DAOForkBlock: daoForkBlock, DAOForkSupport: true, EIP150Block: gasPriceFork} | 
					
						
							| 
									
										
										
										
											2017-04-05 01:16:29 +03:00
										 |  |  | 	chain, err := core.NewBlockChain(db, config, ethash.NewShared(), evmux, 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
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-11-27 15:40:29 +01:00
										 |  |  | 	//vm.Debug = true | 
					
						
							| 
									
										
										
										
											2016-03-21 23:00:39 +01:00
										 |  |  | 	validBlocks, err := test.TryBlocksInsert(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
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-18 17:15:59 +02:00
										 |  |  | 	lastblockhash := common.HexToHash(test.lastblockhash) | 
					
						
							| 
									
										
										
										
											2016-03-21 23:00:39 +01:00
										 |  |  | 	cmlast := chain.LastBlockHash() | 
					
						
							| 
									
										
										
										
											2015-09-18 17:15:59 +02:00
										 |  |  | 	if lastblockhash != cmlast { | 
					
						
							|  |  |  | 		return fmt.Errorf("lastblockhash validation mismatch: want: %x, have: %x", lastblockhash, cmlast) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											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 | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2015-09-14 14:27:25 +02:00
										 |  |  | 	if err = test.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
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2015-09-18 17:15:59 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-03-21 23:00:39 +01:00
										 |  |  | 	return test.ValidateImportedHeaders(chain, validBlocks) | 
					
						
							| 
									
										
										
										
											2015-06-10 12:04:56 -04:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-03-13 18:01:51 +01:00
										 |  |  | // InsertPreState populates the given database with the genesis | 
					
						
							|  |  |  | // accounts defined by the test. | 
					
						
							| 
									
										
										
										
											2016-03-21 23:00:39 +01:00
										 |  |  | func (t *BlockTest) InsertPreState(db ethdb.Database) (*state.StateDB, error) { | 
					
						
							| 
									
										
										
										
											2015-10-06 16:35:55 +02:00
										 |  |  | 	statedb, err := state.New(common.Hash{}, db) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		return nil, err | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2015-03-13 18:01:51 +01:00
										 |  |  | 	for addrString, acct := range t.preAccounts { | 
					
						
							| 
									
										
										
										
											2015-07-07 23:57:54 +02:00
										 |  |  | 		code, err := hex.DecodeString(strings.TrimPrefix(acct.Code, "0x")) | 
					
						
							|  |  |  | 		if err != nil { | 
					
						
							|  |  |  | 			return nil, err | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		balance, ok := new(big.Int).SetString(acct.Balance, 0) | 
					
						
							|  |  |  | 		if !ok { | 
					
						
							|  |  |  | 			return nil, err | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		nonce, err := strconv.ParseUint(prepInt(16, acct.Nonce), 16, 64) | 
					
						
							|  |  |  | 		if err != nil { | 
					
						
							|  |  |  | 			return nil, err | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2017-02-22 23:29:59 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		addr := common.HexToAddress(addrString) | 
					
						
							|  |  |  | 		statedb.CreateAccount(addr) | 
					
						
							|  |  |  | 		statedb.SetCode(addr, code) | 
					
						
							|  |  |  | 		statedb.SetBalance(addr, balance) | 
					
						
							|  |  |  | 		statedb.SetNonce(addr, nonce) | 
					
						
							| 
									
										
										
										
											2015-04-01 10:53:32 +02:00
										 |  |  | 		for k, v := range acct.Storage { | 
					
						
							| 
									
										
										
										
											2015-06-17 11:44:40 +02:00
										 |  |  | 			statedb.SetState(common.HexToAddress(addrString), common.HexToHash(k), common.HexToHash(v)) | 
					
						
							| 
									
										
										
										
											2015-04-01 10:53:32 +02:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2015-03-13 18:01:51 +01:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-20 13:36:29 +02:00
										 |  |  | 	root, err := statedb.Commit(false) | 
					
						
							| 
									
										
										
										
											2015-08-18 14:14:45 +02:00
										 |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		return nil, fmt.Errorf("error writing state: %v", err) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	if t.Genesis.Root() != root { | 
					
						
							|  |  |  | 		return nil, fmt.Errorf("computed state root does not match genesis block: genesis=%x computed=%x", t.Genesis.Root().Bytes()[:4], root.Bytes()[:4]) | 
					
						
							| 
									
										
										
										
											2015-03-20 09:10:13 +01:00
										 |  |  | 	} | 
					
						
							|  |  |  | 	return statedb, nil | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											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. | 
					
						
							|  |  |  | */ | 
					
						
							| 
									
										
										
										
											2015-08-31 17:09:50 +02:00
										 |  |  | func (t *BlockTest) TryBlocksInsert(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 | 
					
						
							|  |  |  | 	for _, b := range t.Json.Blocks { | 
					
						
							|  |  |  | 		cb, err := mustConvertBlock(b) | 
					
						
							|  |  |  | 		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 { | 
					
						
							| 
									
										
										
										
											2015-04-23 04:38:47 +02:00
										 |  |  | 	expectedBloom := mustConvertBytes(h.Bloom) | 
					
						
							|  |  |  | 	if !bytes.Equal(expectedBloom, h2.Bloom.Bytes()) { | 
					
						
							| 
									
										
										
										
											2015-09-14 14:27:25 +02:00
										 |  |  | 		return fmt.Errorf("Bloom: want: %x have: %x", expectedBloom, h2.Bloom.Bytes()) | 
					
						
							| 
									
										
										
										
											2015-04-23 04:38:47 +02:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	expectedCoinbase := mustConvertBytes(h.Coinbase) | 
					
						
							|  |  |  | 	if !bytes.Equal(expectedCoinbase, h2.Coinbase.Bytes()) { | 
					
						
							| 
									
										
										
										
											2015-09-14 14:27:25 +02:00
										 |  |  | 		return fmt.Errorf("Coinbase: want: %x have: %x", expectedCoinbase, h2.Coinbase.Bytes()) | 
					
						
							| 
									
										
										
										
											2015-04-23 04:38:47 +02:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	expectedMixHashBytes := mustConvertBytes(h.MixHash) | 
					
						
							|  |  |  | 	if !bytes.Equal(expectedMixHashBytes, h2.MixDigest.Bytes()) { | 
					
						
							| 
									
										
										
										
											2015-09-14 14:27:25 +02:00
										 |  |  | 		return fmt.Errorf("MixHash: want: %x have: %x", expectedMixHashBytes, h2.MixDigest.Bytes()) | 
					
						
							| 
									
										
										
										
											2015-04-23 04:38:47 +02:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	expectedNonce := mustConvertBytes(h.Nonce) | 
					
						
							|  |  |  | 	if !bytes.Equal(expectedNonce, h2.Nonce[:]) { | 
					
						
							| 
									
										
										
										
											2015-09-14 14:27:25 +02:00
										 |  |  | 		return fmt.Errorf("Nonce: want: %x have: %x", expectedNonce, h2.Nonce) | 
					
						
							| 
									
										
										
										
											2015-04-23 04:38:47 +02:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	expectedNumber := mustConvertBigInt(h.Number, 16) | 
					
						
							|  |  |  | 	if expectedNumber.Cmp(h2.Number) != 0 { | 
					
						
							| 
									
										
										
										
											2015-09-14 14:27:25 +02:00
										 |  |  | 		return fmt.Errorf("Number: want: %v have: %v", expectedNumber, h2.Number) | 
					
						
							| 
									
										
										
										
											2015-04-23 04:38:47 +02:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	expectedParentHash := mustConvertBytes(h.ParentHash) | 
					
						
							|  |  |  | 	if !bytes.Equal(expectedParentHash, h2.ParentHash.Bytes()) { | 
					
						
							| 
									
										
										
										
											2015-09-14 14:27:25 +02:00
										 |  |  | 		return fmt.Errorf("Parent hash: want: %x have: %x", expectedParentHash, h2.ParentHash.Bytes()) | 
					
						
							| 
									
										
										
										
											2015-04-23 04:38:47 +02:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	expectedReceiptHash := mustConvertBytes(h.ReceiptTrie) | 
					
						
							|  |  |  | 	if !bytes.Equal(expectedReceiptHash, h2.ReceiptHash.Bytes()) { | 
					
						
							| 
									
										
										
										
											2015-09-14 14:27:25 +02:00
										 |  |  | 		return fmt.Errorf("Receipt hash: want: %x have: %x", expectedReceiptHash, h2.ReceiptHash.Bytes()) | 
					
						
							| 
									
										
										
										
											2015-04-23 04:38:47 +02:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	expectedTxHash := mustConvertBytes(h.TransactionsTrie) | 
					
						
							|  |  |  | 	if !bytes.Equal(expectedTxHash, h2.TxHash.Bytes()) { | 
					
						
							| 
									
										
										
										
											2015-09-14 14:27:25 +02:00
										 |  |  | 		return fmt.Errorf("Tx hash: want: %x have: %x", expectedTxHash, h2.TxHash.Bytes()) | 
					
						
							| 
									
										
										
										
											2015-04-23 04:38:47 +02:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	expectedStateHash := mustConvertBytes(h.StateRoot) | 
					
						
							|  |  |  | 	if !bytes.Equal(expectedStateHash, h2.Root.Bytes()) { | 
					
						
							| 
									
										
										
										
											2015-09-14 14:27:25 +02:00
										 |  |  | 		return fmt.Errorf("State hash: want: %x have: %x", expectedStateHash, h2.Root.Bytes()) | 
					
						
							| 
									
										
										
										
											2015-04-23 04:38:47 +02:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	expectedUncleHash := mustConvertBytes(h.UncleHash) | 
					
						
							|  |  |  | 	if !bytes.Equal(expectedUncleHash, h2.UncleHash.Bytes()) { | 
					
						
							| 
									
										
										
										
											2015-09-14 14:27:25 +02:00
										 |  |  | 		return fmt.Errorf("Uncle hash: want: %x have: %x", expectedUncleHash, h2.UncleHash.Bytes()) | 
					
						
							| 
									
										
										
										
											2015-04-23 04:38:47 +02:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	expectedExtraData := mustConvertBytes(h.ExtraData) | 
					
						
							|  |  |  | 	if !bytes.Equal(expectedExtraData, h2.Extra) { | 
					
						
							| 
									
										
										
										
											2015-09-14 14:27:25 +02:00
										 |  |  | 		return fmt.Errorf("Extra data: want: %x have: %x", expectedExtraData, h2.Extra) | 
					
						
							| 
									
										
										
										
											2015-04-17 16:30:15 +02:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2015-04-23 04:38:47 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	expectedDifficulty := mustConvertBigInt(h.Difficulty, 16) | 
					
						
							|  |  |  | 	if expectedDifficulty.Cmp(h2.Difficulty) != 0 { | 
					
						
							| 
									
										
										
										
											2015-09-14 14:27:25 +02:00
										 |  |  | 		return fmt.Errorf("Difficulty: want: %v have: %v", expectedDifficulty, h2.Difficulty) | 
					
						
							| 
									
										
										
										
											2015-04-23 04:38:47 +02:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	expectedGasLimit := mustConvertBigInt(h.GasLimit, 16) | 
					
						
							|  |  |  | 	if expectedGasLimit.Cmp(h2.GasLimit) != 0 { | 
					
						
							| 
									
										
										
										
											2015-09-14 14:27:25 +02:00
										 |  |  | 		return fmt.Errorf("GasLimit: want: %v have: %v", expectedGasLimit, h2.GasLimit) | 
					
						
							| 
									
										
										
										
											2015-04-23 04:38:47 +02:00
										 |  |  | 	} | 
					
						
							|  |  |  | 	expectedGasUsed := mustConvertBigInt(h.GasUsed, 16) | 
					
						
							|  |  |  | 	if expectedGasUsed.Cmp(h2.GasUsed) != 0 { | 
					
						
							| 
									
										
										
										
											2015-09-14 14:27:25 +02:00
										 |  |  | 		return fmt.Errorf("GasUsed: want: %v have: %v", expectedGasUsed, h2.GasUsed) | 
					
						
							| 
									
										
										
										
											2015-04-23 04:38:47 +02:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-08-24 02:52:53 +02:00
										 |  |  | 	expectedTimestamp := mustConvertBigInt(h.Timestamp, 16) | 
					
						
							|  |  |  | 	if expectedTimestamp.Cmp(h2.Time) != 0 { | 
					
						
							| 
									
										
										
										
											2015-09-14 14:27:25 +02:00
										 |  |  | 		return fmt.Errorf("Timestamp: want: %v have: %v", expectedTimestamp, 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
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-03-20 09:10:13 +01: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 | 
					
						
							|  |  |  | 	for addrString, acct := range t.postAccounts { | 
					
						
							| 
									
										
										
										
											2015-03-20 09:10:13 +01:00
										 |  |  | 		// XXX: is is worth it checking for errors here? | 
					
						
							| 
									
										
										
										
											2015-07-07 23:57:54 +02:00
										 |  |  | 		addr, err := hex.DecodeString(addrString) | 
					
						
							|  |  |  | 		if err != nil { | 
					
						
							|  |  |  | 			return err | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		code, err := hex.DecodeString(strings.TrimPrefix(acct.Code, "0x")) | 
					
						
							|  |  |  | 		if err != nil { | 
					
						
							|  |  |  | 			return err | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		balance, ok := new(big.Int).SetString(acct.Balance, 0) | 
					
						
							|  |  |  | 		if !ok { | 
					
						
							|  |  |  | 			return err | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		nonce, err := strconv.ParseUint(prepInt(16, acct.Nonce), 16, 64) | 
					
						
							|  |  |  | 		if err != nil { | 
					
						
							|  |  |  | 			return err | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2015-03-20 09:10:13 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		// address is indirectly verified by the other fields, as it's the db key | 
					
						
							| 
									
										
										
										
											2015-03-21 20:29:12 +01:00
										 |  |  | 		code2 := statedb.GetCode(common.BytesToAddress(addr)) | 
					
						
							|  |  |  | 		balance2 := statedb.GetBalance(common.BytesToAddress(addr)) | 
					
						
							|  |  |  | 		nonce2 := statedb.GetNonce(common.BytesToAddress(addr)) | 
					
						
							| 
									
										
										
										
											2015-03-20 09:10:13 +01:00
										 |  |  | 		if !bytes.Equal(code2, code) { | 
					
						
							| 
									
										
										
										
											2015-09-14 14:27:25 +02:00
										 |  |  | 			return fmt.Errorf("account code mismatch for addr: %s want: %s have: %s", addrString, hex.EncodeToString(code), hex.EncodeToString(code2)) | 
					
						
							| 
									
										
										
										
											2015-03-20 09:10:13 +01:00
										 |  |  | 		} | 
					
						
							|  |  |  | 		if balance2.Cmp(balance) != 0 { | 
					
						
							| 
									
										
										
										
											2015-09-14 14:27:25 +02:00
										 |  |  | 			return fmt.Errorf("account balance mismatch for addr: %s, want: %d, have: %d", addrString, balance, balance2) | 
					
						
							| 
									
										
										
										
											2015-03-20 09:10:13 +01:00
										 |  |  | 		} | 
					
						
							|  |  |  | 		if nonce2 != nonce { | 
					
						
							| 
									
										
										
										
											2015-09-14 14:27:25 +02:00
										 |  |  | 			return fmt.Errorf("account nonce mismatch for addr: %s want: %d have: %d", addrString, nonce, nonce2) | 
					
						
							| 
									
										
										
										
											2015-03-20 09:10:13 +01:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2015-03-13 18:01:51 +01:00
										 |  |  | 	} | 
					
						
							|  |  |  | 	return nil | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-08-31 17:09:50 +02:00
										 |  |  | func (test *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) | 
					
						
							|  |  |  | 	bmap := make(map[string]btBlock, len(test.Json.Blocks)) | 
					
						
							|  |  |  | 	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 | 
					
						
							|  |  |  | 	// all blocks have been processed by ChainManager, as they may not | 
					
						
							|  |  |  | 	// 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) { | 
					
						
							| 
									
										
										
										
											2015-09-18 17:15:59 +02:00
										 |  |  | 		bHash := common.Bytes2Hex(b.Hash().Bytes()) // hex without 0x prefix | 
					
						
							|  |  |  | 		if err := validateHeader(bmap[bHash].BlockHeader, b.Header()); err != nil { | 
					
						
							|  |  |  | 			return fmt.Errorf("Imported block header validation failed: %v", err) | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return nil | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-06-14 17:55:03 -04:00
										 |  |  | func convertBlockTests(in map[string]*btJSON) (map[string]*BlockTest, error) { | 
					
						
							|  |  |  | 	out := make(map[string]*BlockTest) | 
					
						
							|  |  |  | 	for name, test := range in { | 
					
						
							|  |  |  | 		var err error | 
					
						
							|  |  |  | 		if out[name], err = convertBlockTest(test); err != nil { | 
					
						
							|  |  |  | 			return out, fmt.Errorf("bad test %q: %v", name, err) | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return out, nil | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func convertBlockTest(in *btJSON) (out *BlockTest, err error) { | 
					
						
							| 
									
										
										
										
											2015-03-13 18:01:51 +01:00
										 |  |  | 	// the conversion handles errors by catching panics. | 
					
						
							|  |  |  | 	// you might consider this ugly, but the alternative (passing errors) | 
					
						
							|  |  |  | 	// would be much harder to read. | 
					
						
							|  |  |  | 	defer func() { | 
					
						
							|  |  |  | 		if recovered := recover(); recovered != nil { | 
					
						
							|  |  |  | 			buf := make([]byte, 64<<10) | 
					
						
							|  |  |  | 			buf = buf[:runtime.Stack(buf, false)] | 
					
						
							|  |  |  | 			err = fmt.Errorf("%v\n%s", recovered, buf) | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	}() | 
					
						
							| 
									
										
										
										
											2015-09-18 17:15:59 +02:00
										 |  |  | 	out = &BlockTest{preAccounts: in.Pre, postAccounts: in.PostState, Json: in, lastblockhash: in.Lastblockhash} | 
					
						
							| 
									
										
										
										
											2015-03-13 18:01:51 +01:00
										 |  |  | 	out.Genesis = mustConvertGenesis(in.GenesisBlockHeader) | 
					
						
							|  |  |  | 	return out, err | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func mustConvertGenesis(testGenesis btHeader) *types.Block { | 
					
						
							|  |  |  | 	hdr := mustConvertHeader(testGenesis) | 
					
						
							|  |  |  | 	hdr.Number = big.NewInt(0) | 
					
						
							| 
									
										
										
										
											2015-09-07 20:43:01 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	return types.NewBlockWithHeader(hdr) | 
					
						
							| 
									
										
										
										
											2015-03-13 18:01:51 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func mustConvertHeader(in btHeader) *types.Header { | 
					
						
							|  |  |  | 	// hex decode these fields | 
					
						
							| 
									
										
										
										
											2015-03-16 23:10:26 +01:00
										 |  |  | 	header := &types.Header{ | 
					
						
							| 
									
										
										
										
											2015-03-14 23:37:21 +01:00
										 |  |  | 		//SeedHash:    mustConvertBytes(in.SeedHash), | 
					
						
							| 
									
										
										
										
											2015-03-16 23:10:26 +01:00
										 |  |  | 		MixDigest:   mustConvertHash(in.MixHash), | 
					
						
							|  |  |  | 		Bloom:       mustConvertBloom(in.Bloom), | 
					
						
							|  |  |  | 		ReceiptHash: mustConvertHash(in.ReceiptTrie), | 
					
						
							|  |  |  | 		TxHash:      mustConvertHash(in.TransactionsTrie), | 
					
						
							|  |  |  | 		Root:        mustConvertHash(in.StateRoot), | 
					
						
							|  |  |  | 		Coinbase:    mustConvertAddress(in.Coinbase), | 
					
						
							|  |  |  | 		UncleHash:   mustConvertHash(in.UncleHash), | 
					
						
							|  |  |  | 		ParentHash:  mustConvertHash(in.ParentHash), | 
					
						
							| 
									
										
										
										
											2015-04-05 18:57:03 +02:00
										 |  |  | 		Extra:       mustConvertBytes(in.ExtraData), | 
					
						
							| 
									
										
										
										
											2015-04-22 15:21:02 +02:00
										 |  |  | 		GasUsed:     mustConvertBigInt(in.GasUsed, 16), | 
					
						
							|  |  |  | 		GasLimit:    mustConvertBigInt(in.GasLimit, 16), | 
					
						
							|  |  |  | 		Difficulty:  mustConvertBigInt(in.Difficulty, 16), | 
					
						
							| 
									
										
										
										
											2015-08-24 02:52:53 +02:00
										 |  |  | 		Time:        mustConvertBigInt(in.Timestamp, 16), | 
					
						
							| 
									
										
										
										
											2015-06-16 12:41:50 +02:00
										 |  |  | 		Nonce:       types.EncodeNonce(mustConvertUint(in.Nonce, 16)), | 
					
						
							| 
									
										
										
										
											2015-03-13 18:01:51 +01:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2015-03-16 23:10:26 +01:00
										 |  |  | 	return header | 
					
						
							| 
									
										
										
										
											2015-03-13 18:01:51 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-04-20 18:14:57 +02:00
										 |  |  | func mustConvertBlock(testBlock btBlock) (*types.Block, error) { | 
					
						
							|  |  |  | 	var b types.Block | 
					
						
							|  |  |  | 	r := bytes.NewReader(mustConvertBytes(testBlock.Rlp)) | 
					
						
							|  |  |  | 	err := rlp.Decode(r, &b) | 
					
						
							|  |  |  | 	return &b, err | 
					
						
							| 
									
										
										
										
											2015-03-13 18:01:51 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func mustConvertBytes(in string) []byte { | 
					
						
							| 
									
										
										
										
											2015-04-15 22:37:16 +02:00
										 |  |  | 	if in == "0x" { | 
					
						
							|  |  |  | 		return []byte{} | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2015-04-19 00:35:48 +02:00
										 |  |  | 	h := unfuckFuckedHex(strings.TrimPrefix(in, "0x")) | 
					
						
							| 
									
										
										
										
											2015-04-15 22:37:16 +02:00
										 |  |  | 	out, err := hex.DecodeString(h) | 
					
						
							| 
									
										
										
										
											2015-03-13 18:01:51 +01:00
										 |  |  | 	if err != nil { | 
					
						
							| 
									
										
										
										
											2016-04-15 11:06:57 +02:00
										 |  |  | 		panic(fmt.Errorf("invalid hex: %q", h)) | 
					
						
							| 
									
										
										
										
											2015-03-13 18:01:51 +01:00
										 |  |  | 	} | 
					
						
							|  |  |  | 	return out | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-03-16 23:10:26 +01:00
										 |  |  | func mustConvertHash(in string) common.Hash { | 
					
						
							|  |  |  | 	out, err := hex.DecodeString(strings.TrimPrefix(in, "0x")) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		panic(fmt.Errorf("invalid hex: %q", in)) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return common.BytesToHash(out) | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func mustConvertAddress(in string) common.Address { | 
					
						
							| 
									
										
										
										
											2015-04-19 00:35:48 +02:00
										 |  |  | 	out, err := hex.DecodeString(strings.TrimPrefix(in, "0x")) | 
					
						
							| 
									
										
										
										
											2015-03-16 23:10:26 +01:00
										 |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		panic(fmt.Errorf("invalid hex: %q", in)) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return common.BytesToAddress(out) | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-03-18 11:44:25 +01:00
										 |  |  | func mustConvertBloom(in string) types.Bloom { | 
					
						
							| 
									
										
										
										
											2015-03-16 23:10:26 +01:00
										 |  |  | 	out, err := hex.DecodeString(strings.TrimPrefix(in, "0x")) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		panic(fmt.Errorf("invalid hex: %q", in)) | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2015-03-18 11:44:25 +01:00
										 |  |  | 	return types.BytesToBloom(out) | 
					
						
							| 
									
										
										
										
											2015-03-16 23:10:26 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-04-17 18:20:32 +02:00
										 |  |  | func mustConvertBigInt(in string, base int) *big.Int { | 
					
						
							|  |  |  | 	in = prepInt(base, in) | 
					
						
							|  |  |  | 	out, ok := new(big.Int).SetString(in, base) | 
					
						
							| 
									
										
										
										
											2015-04-10 11:55:31 +02:00
										 |  |  | 	if !ok { | 
					
						
							|  |  |  | 		panic(fmt.Errorf("invalid integer: %q", in)) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return out | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-04-17 18:20:32 +02:00
										 |  |  | func mustConvertUint(in string, base int) uint64 { | 
					
						
							|  |  |  | 	in = prepInt(base, in) | 
					
						
							|  |  |  | 	out, err := strconv.ParseUint(in, base, 64) | 
					
						
							| 
									
										
										
										
											2015-04-10 11:55:31 +02:00
										 |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		panic(fmt.Errorf("invalid integer: %q", in)) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return out | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-06-11 12:20:30 -04:00
										 |  |  | func LoadBlockTests(file string) (map[string]*BlockTest, error) { | 
					
						
							| 
									
										
										
										
											2015-06-14 17:55:03 -04:00
										 |  |  | 	btjs := make(map[string]*btJSON) | 
					
						
							|  |  |  | 	if err := readJsonFile(file, &btjs); err != nil { | 
					
						
							| 
									
										
										
										
											2015-06-10 18:11:30 -04:00
										 |  |  | 		return nil, err | 
					
						
							| 
									
										
										
										
											2015-03-13 18:01:51 +01:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-06-14 17:55:03 -04:00
										 |  |  | 	return convertBlockTests(btjs) | 
					
						
							| 
									
										
										
										
											2015-03-13 18:01:51 +01:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2015-04-15 22:37:16 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-04-19 00:35:48 +02:00
										 |  |  | // Nothing to see here, please move along... | 
					
						
							| 
									
										
										
										
											2015-04-17 18:20:32 +02:00
										 |  |  | func prepInt(base int, s string) string { | 
					
						
							|  |  |  | 	if base == 16 { | 
					
						
							| 
									
										
										
										
											2017-01-06 16:44:20 +01:00
										 |  |  | 		s = strings.TrimPrefix(s, "0x") | 
					
						
							| 
									
										
										
										
											2015-04-17 18:20:32 +02:00
										 |  |  | 		if len(s) == 0 { | 
					
						
							|  |  |  | 			s = "00" | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		s = nibbleFix(s) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return s | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-04-19 00:35:48 +02:00
										 |  |  | // don't ask | 
					
						
							|  |  |  | func unfuckFuckedHex(almostHex string) string { | 
					
						
							|  |  |  | 	return nibbleFix(strings.Replace(almostHex, "v", "", -1)) | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-04-17 18:20:32 +02:00
										 |  |  | func nibbleFix(s string) string { | 
					
						
							|  |  |  | 	if len(s)%2 != 0 { | 
					
						
							|  |  |  | 		s = "0" + s | 
					
						
							| 
									
										
										
										
											2015-04-15 22:37:16 +02:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2015-04-17 18:20:32 +02:00
										 |  |  | 	return s | 
					
						
							| 
									
										
										
										
											2015-04-15 22:37:16 +02:00
										 |  |  | } |