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