github.com/jeffallen/go-ethereum@v1.1.4-0.20150910155051-571d3236c49c/tests/block_test_util.go (about)

     1  // Copyright 2015 The go-ethereum Authors
     2  // This file is part of the go-ethereum library.
     3  //
     4  // The go-ethereum library is free software: you can redistribute it and/or modify
     5  // it under the terms of the GNU Lesser General Public License as published by
     6  // the Free Software Foundation, either version 3 of the License, or
     7  // (at your option) any later version.
     8  //
     9  // The go-ethereum library is distributed in the hope that it will be useful,
    10  // but WITHOUT ANY WARRANTY; without even the implied warranty of
    11  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    12  // GNU Lesser General Public License for more details.
    13  //
    14  // You should have received a copy of the GNU Lesser General Public License
    15  // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
    16  
    17  package tests
    18  
    19  import (
    20  	"bytes"
    21  	"encoding/hex"
    22  	"fmt"
    23  	"io"
    24  	"math/big"
    25  	"path/filepath"
    26  	"runtime"
    27  	"strconv"
    28  	"strings"
    29  	"time"
    30  
    31  	"github.com/ethereum/go-ethereum/accounts"
    32  	"github.com/ethereum/go-ethereum/common"
    33  	"github.com/ethereum/go-ethereum/core"
    34  	"github.com/ethereum/go-ethereum/core/state"
    35  	"github.com/ethereum/go-ethereum/core/types"
    36  	"github.com/ethereum/go-ethereum/crypto"
    37  	"github.com/ethereum/go-ethereum/eth"
    38  	"github.com/ethereum/go-ethereum/ethdb"
    39  	"github.com/ethereum/go-ethereum/logger/glog"
    40  	"github.com/ethereum/go-ethereum/rlp"
    41  )
    42  
    43  // Block Test JSON Format
    44  type BlockTest struct {
    45  	Genesis *types.Block
    46  
    47  	Json        *btJSON
    48  	preAccounts map[string]btAccount
    49  }
    50  
    51  type btJSON struct {
    52  	Blocks             []btBlock
    53  	GenesisBlockHeader btHeader
    54  	Pre                map[string]btAccount
    55  	PostState          map[string]btAccount
    56  }
    57  
    58  type btBlock struct {
    59  	BlockHeader  *btHeader
    60  	Rlp          string
    61  	Transactions []btTransaction
    62  	UncleHeaders []*btHeader
    63  }
    64  
    65  type btAccount struct {
    66  	Balance    string
    67  	Code       string
    68  	Nonce      string
    69  	Storage    map[string]string
    70  	PrivateKey string
    71  }
    72  
    73  type btHeader struct {
    74  	Bloom            string
    75  	Coinbase         string
    76  	MixHash          string
    77  	Nonce            string
    78  	Number           string
    79  	ParentHash       string
    80  	ReceiptTrie      string
    81  	SeedHash         string
    82  	StateRoot        string
    83  	TransactionsTrie string
    84  	UncleHash        string
    85  
    86  	ExtraData  string
    87  	Difficulty string
    88  	GasLimit   string
    89  	GasUsed    string
    90  	Timestamp  string
    91  }
    92  
    93  type btTransaction struct {
    94  	Data     string
    95  	GasLimit string
    96  	GasPrice string
    97  	Nonce    string
    98  	R        string
    99  	S        string
   100  	To       string
   101  	V        string
   102  	Value    string
   103  }
   104  
   105  func RunBlockTestWithReader(r io.Reader, skipTests []string) error {
   106  	btjs := make(map[string]*btJSON)
   107  	if err := readJson(r, &btjs); err != nil {
   108  		return err
   109  	}
   110  
   111  	bt, err := convertBlockTests(btjs)
   112  	if err != nil {
   113  		return err
   114  	}
   115  
   116  	if err := runBlockTests(bt, skipTests); err != nil {
   117  		return err
   118  	}
   119  	return nil
   120  }
   121  
   122  func RunBlockTest(file string, skipTests []string) error {
   123  	btjs := make(map[string]*btJSON)
   124  	if err := readJsonFile(file, &btjs); err != nil {
   125  		return err
   126  	}
   127  
   128  	bt, err := convertBlockTests(btjs)
   129  	if err != nil {
   130  		return err
   131  	}
   132  	if err := runBlockTests(bt, skipTests); err != nil {
   133  		return err
   134  	}
   135  	return nil
   136  }
   137  
   138  func runBlockTests(bt map[string]*BlockTest, skipTests []string) error {
   139  	skipTest := make(map[string]bool, len(skipTests))
   140  	for _, name := range skipTests {
   141  		skipTest[name] = true
   142  	}
   143  
   144  	for name, test := range bt {
   145  		// if the test should be skipped, return
   146  		if skipTest[name] {
   147  			glog.Infoln("Skipping block test", name)
   148  			continue
   149  		}
   150  
   151  		// test the block
   152  		if err := runBlockTest(test); err != nil {
   153  			return fmt.Errorf("%s: %v", name, err)
   154  		}
   155  		glog.Infoln("Block test passed: ", name)
   156  
   157  	}
   158  	return nil
   159  
   160  }
   161  func runBlockTest(test *BlockTest) error {
   162  	cfg := test.makeEthConfig()
   163  	cfg.GenesisBlock = test.Genesis
   164  
   165  	ethereum, err := eth.New(cfg)
   166  	if err != nil {
   167  		return err
   168  	}
   169  
   170  	err = ethereum.Start()
   171  	if err != nil {
   172  		return err
   173  	}
   174  
   175  	// import pre accounts
   176  	statedb, err := test.InsertPreState(ethereum)
   177  	if err != nil {
   178  		return fmt.Errorf("InsertPreState: %v", err)
   179  	}
   180  
   181  	err = test.TryBlocksInsert(ethereum.ChainManager())
   182  	if err != nil {
   183  		return err
   184  	}
   185  
   186  	if err = test.ValidatePostState(statedb); err != nil {
   187  		return fmt.Errorf("post state validation failed: %v", err)
   188  	}
   189  	return nil
   190  }
   191  
   192  func (test *BlockTest) makeEthConfig() *eth.Config {
   193  	ks := crypto.NewKeyStorePassphrase(filepath.Join(common.DefaultDataDir(), "keystore"))
   194  
   195  	return &eth.Config{
   196  		DataDir:        common.DefaultDataDir(),
   197  		Verbosity:      5,
   198  		Etherbase:      common.Address{},
   199  		AccountManager: accounts.NewManager(ks),
   200  		NewDB:          func(path string) (common.Database, error) { return ethdb.NewMemDatabase() },
   201  	}
   202  }
   203  
   204  // InsertPreState populates the given database with the genesis
   205  // accounts defined by the test.
   206  func (t *BlockTest) InsertPreState(ethereum *eth.Ethereum) (*state.StateDB, error) {
   207  	db := ethereum.ChainDb()
   208  	statedb := state.New(common.Hash{}, db)
   209  	for addrString, acct := range t.preAccounts {
   210  		addr, err := hex.DecodeString(addrString)
   211  		if err != nil {
   212  			return nil, err
   213  		}
   214  		code, err := hex.DecodeString(strings.TrimPrefix(acct.Code, "0x"))
   215  		if err != nil {
   216  			return nil, err
   217  		}
   218  		balance, ok := new(big.Int).SetString(acct.Balance, 0)
   219  		if !ok {
   220  			return nil, err
   221  		}
   222  		nonce, err := strconv.ParseUint(prepInt(16, acct.Nonce), 16, 64)
   223  		if err != nil {
   224  			return nil, err
   225  		}
   226  
   227  		if acct.PrivateKey != "" {
   228  			privkey, err := hex.DecodeString(strings.TrimPrefix(acct.PrivateKey, "0x"))
   229  			err = crypto.ImportBlockTestKey(privkey)
   230  			err = ethereum.AccountManager().TimedUnlock(common.BytesToAddress(addr), "", 999999*time.Second)
   231  			if err != nil {
   232  				return nil, err
   233  			}
   234  		}
   235  
   236  		obj := statedb.CreateAccount(common.HexToAddress(addrString))
   237  		obj.SetCode(code)
   238  		obj.SetBalance(balance)
   239  		obj.SetNonce(nonce)
   240  		for k, v := range acct.Storage {
   241  			statedb.SetState(common.HexToAddress(addrString), common.HexToHash(k), common.HexToHash(v))
   242  		}
   243  	}
   244  	// sync objects to trie
   245  	statedb.SyncObjects()
   246  	// sync trie to disk
   247  	statedb.Sync()
   248  
   249  	if !bytes.Equal(t.Genesis.Root().Bytes(), statedb.Root().Bytes()) {
   250  		return nil, fmt.Errorf("computed state root does not match genesis block %x %x", t.Genesis.Root().Bytes()[:4], statedb.Root().Bytes()[:4])
   251  	}
   252  	return statedb, nil
   253  }
   254  
   255  /* See https://github.com/ethereum/tests/wiki/Blockchain-Tests-II
   256  
   257     Whether a block is valid or not is a bit subtle, it's defined by presence of
   258     blockHeader, transactions and uncleHeaders fields. If they are missing, the block is
   259     invalid and we must verify that we do not accept it.
   260  
   261     Since some tests mix valid and invalid blocks we need to check this for every block.
   262  
   263     If a block is invalid it does not necessarily fail the test, if it's invalidness is
   264     expected we are expected to ignore it and continue processing and then validate the
   265     post state.
   266  */
   267  func (t *BlockTest) TryBlocksInsert(chainManager *core.ChainManager) error {
   268  	// insert the test blocks, which will execute all transactions
   269  	for _, b := range t.Json.Blocks {
   270  		cb, err := mustConvertBlock(b)
   271  		if err != nil {
   272  			if b.BlockHeader == nil {
   273  				continue // OK - block is supposed to be invalid, continue with next block
   274  			} else {
   275  				return fmt.Errorf("Block RLP decoding failed when expected to succeed: %v", err)
   276  			}
   277  		}
   278  		// RLP decoding worked, try to insert into chain:
   279  		_, err = chainManager.InsertChain(types.Blocks{cb})
   280  		if err != nil {
   281  			if b.BlockHeader == nil {
   282  				continue // OK - block is supposed to be invalid, continue with next block
   283  			} else {
   284  				return fmt.Errorf("Block insertion into chain failed: %v", err)
   285  			}
   286  		}
   287  		if b.BlockHeader == nil {
   288  			return fmt.Errorf("Block insertion should have failed")
   289  		}
   290  		err = t.validateBlockHeader(b.BlockHeader, cb.Header())
   291  		if err != nil {
   292  			return fmt.Errorf("Block header validation failed: %v", err)
   293  		}
   294  	}
   295  	return nil
   296  }
   297  
   298  func (s *BlockTest) validateBlockHeader(h *btHeader, h2 *types.Header) error {
   299  	expectedBloom := mustConvertBytes(h.Bloom)
   300  	if !bytes.Equal(expectedBloom, h2.Bloom.Bytes()) {
   301  		return fmt.Errorf("Bloom: expected: %v, decoded: %v", expectedBloom, h2.Bloom.Bytes())
   302  	}
   303  
   304  	expectedCoinbase := mustConvertBytes(h.Coinbase)
   305  	if !bytes.Equal(expectedCoinbase, h2.Coinbase.Bytes()) {
   306  		return fmt.Errorf("Coinbase: expected: %v, decoded: %v", expectedCoinbase, h2.Coinbase.Bytes())
   307  	}
   308  
   309  	expectedMixHashBytes := mustConvertBytes(h.MixHash)
   310  	if !bytes.Equal(expectedMixHashBytes, h2.MixDigest.Bytes()) {
   311  		return fmt.Errorf("MixHash: expected: %v, decoded: %v", expectedMixHashBytes, h2.MixDigest.Bytes())
   312  	}
   313  
   314  	expectedNonce := mustConvertBytes(h.Nonce)
   315  	if !bytes.Equal(expectedNonce, h2.Nonce[:]) {
   316  		return fmt.Errorf("Nonce: expected: %v, decoded: %v", expectedNonce, h2.Nonce)
   317  	}
   318  
   319  	expectedNumber := mustConvertBigInt(h.Number, 16)
   320  	if expectedNumber.Cmp(h2.Number) != 0 {
   321  		return fmt.Errorf("Number: expected: %v, decoded: %v", expectedNumber, h2.Number)
   322  	}
   323  
   324  	expectedParentHash := mustConvertBytes(h.ParentHash)
   325  	if !bytes.Equal(expectedParentHash, h2.ParentHash.Bytes()) {
   326  		return fmt.Errorf("Parent hash: expected: %v, decoded: %v", expectedParentHash, h2.ParentHash.Bytes())
   327  	}
   328  
   329  	expectedReceiptHash := mustConvertBytes(h.ReceiptTrie)
   330  	if !bytes.Equal(expectedReceiptHash, h2.ReceiptHash.Bytes()) {
   331  		return fmt.Errorf("Receipt hash: expected: %v, decoded: %v", expectedReceiptHash, h2.ReceiptHash.Bytes())
   332  	}
   333  
   334  	expectedTxHash := mustConvertBytes(h.TransactionsTrie)
   335  	if !bytes.Equal(expectedTxHash, h2.TxHash.Bytes()) {
   336  		return fmt.Errorf("Tx hash: expected: %v, decoded: %v", expectedTxHash, h2.TxHash.Bytes())
   337  	}
   338  
   339  	expectedStateHash := mustConvertBytes(h.StateRoot)
   340  	if !bytes.Equal(expectedStateHash, h2.Root.Bytes()) {
   341  		return fmt.Errorf("State hash: expected: %v, decoded: %v", expectedStateHash, h2.Root.Bytes())
   342  	}
   343  
   344  	expectedUncleHash := mustConvertBytes(h.UncleHash)
   345  	if !bytes.Equal(expectedUncleHash, h2.UncleHash.Bytes()) {
   346  		return fmt.Errorf("Uncle hash: expected: %v, decoded: %v", expectedUncleHash, h2.UncleHash.Bytes())
   347  	}
   348  
   349  	expectedExtraData := mustConvertBytes(h.ExtraData)
   350  	if !bytes.Equal(expectedExtraData, h2.Extra) {
   351  		return fmt.Errorf("Extra data: expected: %v, decoded: %v", expectedExtraData, h2.Extra)
   352  	}
   353  
   354  	expectedDifficulty := mustConvertBigInt(h.Difficulty, 16)
   355  	if expectedDifficulty.Cmp(h2.Difficulty) != 0 {
   356  		return fmt.Errorf("Difficulty: expected: %v, decoded: %v", expectedDifficulty, h2.Difficulty)
   357  	}
   358  
   359  	expectedGasLimit := mustConvertBigInt(h.GasLimit, 16)
   360  	if expectedGasLimit.Cmp(h2.GasLimit) != 0 {
   361  		return fmt.Errorf("GasLimit: expected: %v, decoded: %v", expectedGasLimit, h2.GasLimit)
   362  	}
   363  	expectedGasUsed := mustConvertBigInt(h.GasUsed, 16)
   364  	if expectedGasUsed.Cmp(h2.GasUsed) != 0 {
   365  		return fmt.Errorf("GasUsed: expected: %v, decoded: %v", expectedGasUsed, h2.GasUsed)
   366  	}
   367  
   368  	expectedTimestamp := mustConvertBigInt(h.Timestamp, 16)
   369  	if expectedTimestamp.Cmp(h2.Time) != 0 {
   370  		return fmt.Errorf("Timestamp: expected: %v, decoded: %v", expectedTimestamp, h2.Time)
   371  	}
   372  
   373  	return nil
   374  }
   375  
   376  func (t *BlockTest) ValidatePostState(statedb *state.StateDB) error {
   377  	for addrString, acct := range t.preAccounts {
   378  		// XXX: is is worth it checking for errors here?
   379  		addr, err := hex.DecodeString(addrString)
   380  		if err != nil {
   381  			return err
   382  		}
   383  		code, err := hex.DecodeString(strings.TrimPrefix(acct.Code, "0x"))
   384  		if err != nil {
   385  			return err
   386  		}
   387  		balance, ok := new(big.Int).SetString(acct.Balance, 0)
   388  		if !ok {
   389  			return err
   390  		}
   391  		nonce, err := strconv.ParseUint(prepInt(16, acct.Nonce), 16, 64)
   392  		if err != nil {
   393  			return err
   394  		}
   395  
   396  		// address is indirectly verified by the other fields, as it's the db key
   397  		code2 := statedb.GetCode(common.BytesToAddress(addr))
   398  		balance2 := statedb.GetBalance(common.BytesToAddress(addr))
   399  		nonce2 := statedb.GetNonce(common.BytesToAddress(addr))
   400  		if !bytes.Equal(code2, code) {
   401  			return fmt.Errorf("account code mismatch, addr, found, expected: ", addrString, hex.EncodeToString(code2), hex.EncodeToString(code))
   402  		}
   403  		if balance2.Cmp(balance) != 0 {
   404  			return fmt.Errorf("account balance mismatch, addr, found, expected: ", addrString, balance2, balance)
   405  		}
   406  		if nonce2 != nonce {
   407  			return fmt.Errorf("account nonce mismatch, addr, found, expected: ", addrString, nonce2, nonce)
   408  		}
   409  	}
   410  	return nil
   411  }
   412  
   413  func convertBlockTests(in map[string]*btJSON) (map[string]*BlockTest, error) {
   414  	out := make(map[string]*BlockTest)
   415  	for name, test := range in {
   416  		var err error
   417  		if out[name], err = convertBlockTest(test); err != nil {
   418  			return out, fmt.Errorf("bad test %q: %v", name, err)
   419  		}
   420  	}
   421  	return out, nil
   422  }
   423  
   424  func convertBlockTest(in *btJSON) (out *BlockTest, err error) {
   425  	// the conversion handles errors by catching panics.
   426  	// you might consider this ugly, but the alternative (passing errors)
   427  	// would be much harder to read.
   428  	defer func() {
   429  		if recovered := recover(); recovered != nil {
   430  			buf := make([]byte, 64<<10)
   431  			buf = buf[:runtime.Stack(buf, false)]
   432  			err = fmt.Errorf("%v\n%s", recovered, buf)
   433  		}
   434  	}()
   435  	out = &BlockTest{preAccounts: in.Pre, Json: in}
   436  	out.Genesis = mustConvertGenesis(in.GenesisBlockHeader)
   437  	return out, err
   438  }
   439  
   440  func mustConvertGenesis(testGenesis btHeader) *types.Block {
   441  	hdr := mustConvertHeader(testGenesis)
   442  	hdr.Number = big.NewInt(0)
   443  	b := types.NewBlockWithHeader(hdr)
   444  	b.Td = new(big.Int)
   445  	return b
   446  }
   447  
   448  func mustConvertHeader(in btHeader) *types.Header {
   449  	// hex decode these fields
   450  	header := &types.Header{
   451  		//SeedHash:    mustConvertBytes(in.SeedHash),
   452  		MixDigest:   mustConvertHash(in.MixHash),
   453  		Bloom:       mustConvertBloom(in.Bloom),
   454  		ReceiptHash: mustConvertHash(in.ReceiptTrie),
   455  		TxHash:      mustConvertHash(in.TransactionsTrie),
   456  		Root:        mustConvertHash(in.StateRoot),
   457  		Coinbase:    mustConvertAddress(in.Coinbase),
   458  		UncleHash:   mustConvertHash(in.UncleHash),
   459  		ParentHash:  mustConvertHash(in.ParentHash),
   460  		Extra:       mustConvertBytes(in.ExtraData),
   461  		GasUsed:     mustConvertBigInt(in.GasUsed, 16),
   462  		GasLimit:    mustConvertBigInt(in.GasLimit, 16),
   463  		Difficulty:  mustConvertBigInt(in.Difficulty, 16),
   464  		Time:        mustConvertBigInt(in.Timestamp, 16),
   465  		Nonce:       types.EncodeNonce(mustConvertUint(in.Nonce, 16)),
   466  	}
   467  	return header
   468  }
   469  
   470  func mustConvertBlock(testBlock btBlock) (*types.Block, error) {
   471  	var b types.Block
   472  	r := bytes.NewReader(mustConvertBytes(testBlock.Rlp))
   473  	err := rlp.Decode(r, &b)
   474  	return &b, err
   475  }
   476  
   477  func mustConvertBytes(in string) []byte {
   478  	if in == "0x" {
   479  		return []byte{}
   480  	}
   481  	h := unfuckFuckedHex(strings.TrimPrefix(in, "0x"))
   482  	out, err := hex.DecodeString(h)
   483  	if err != nil {
   484  		panic(fmt.Errorf("invalid hex: %q: ", h, err))
   485  	}
   486  	return out
   487  }
   488  
   489  func mustConvertHash(in string) common.Hash {
   490  	out, err := hex.DecodeString(strings.TrimPrefix(in, "0x"))
   491  	if err != nil {
   492  		panic(fmt.Errorf("invalid hex: %q", in))
   493  	}
   494  	return common.BytesToHash(out)
   495  }
   496  
   497  func mustConvertAddress(in string) common.Address {
   498  	out, err := hex.DecodeString(strings.TrimPrefix(in, "0x"))
   499  	if err != nil {
   500  		panic(fmt.Errorf("invalid hex: %q", in))
   501  	}
   502  	return common.BytesToAddress(out)
   503  }
   504  
   505  func mustConvertBloom(in string) types.Bloom {
   506  	out, err := hex.DecodeString(strings.TrimPrefix(in, "0x"))
   507  	if err != nil {
   508  		panic(fmt.Errorf("invalid hex: %q", in))
   509  	}
   510  	return types.BytesToBloom(out)
   511  }
   512  
   513  func mustConvertBigInt(in string, base int) *big.Int {
   514  	in = prepInt(base, in)
   515  	out, ok := new(big.Int).SetString(in, base)
   516  	if !ok {
   517  		panic(fmt.Errorf("invalid integer: %q", in))
   518  	}
   519  	return out
   520  }
   521  
   522  func mustConvertUint(in string, base int) uint64 {
   523  	in = prepInt(base, in)
   524  	out, err := strconv.ParseUint(in, base, 64)
   525  	if err != nil {
   526  		panic(fmt.Errorf("invalid integer: %q", in))
   527  	}
   528  	return out
   529  }
   530  
   531  func LoadBlockTests(file string) (map[string]*BlockTest, error) {
   532  	btjs := make(map[string]*btJSON)
   533  	if err := readJsonFile(file, &btjs); err != nil {
   534  		return nil, err
   535  	}
   536  
   537  	return convertBlockTests(btjs)
   538  }
   539  
   540  // Nothing to see here, please move along...
   541  func prepInt(base int, s string) string {
   542  	if base == 16 {
   543  		if strings.HasPrefix(s, "0x") {
   544  			s = s[2:]
   545  		}
   546  		if len(s) == 0 {
   547  			s = "00"
   548  		}
   549  		s = nibbleFix(s)
   550  	}
   551  	return s
   552  }
   553  
   554  // don't ask
   555  func unfuckFuckedHex(almostHex string) string {
   556  	return nibbleFix(strings.Replace(almostHex, "v", "", -1))
   557  }
   558  
   559  func nibbleFix(s string) string {
   560  	if len(s)%2 != 0 {
   561  		s = "0" + s
   562  	}
   563  	return s
   564  }