block_test_util.go 15 KB

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