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