block_test_util.go 13 KB

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