chain_manager_test.go 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501
  1. // Copyright 2014 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. package core
  17. import (
  18. "fmt"
  19. "math/big"
  20. "math/rand"
  21. "os"
  22. "path/filepath"
  23. "runtime"
  24. "strconv"
  25. "testing"
  26. "github.com/ethereum/ethash"
  27. "github.com/ethereum/go-ethereum/common"
  28. "github.com/ethereum/go-ethereum/core/state"
  29. "github.com/ethereum/go-ethereum/core/types"
  30. "github.com/ethereum/go-ethereum/ethdb"
  31. "github.com/ethereum/go-ethereum/event"
  32. "github.com/ethereum/go-ethereum/pow"
  33. "github.com/ethereum/go-ethereum/rlp"
  34. "github.com/hashicorp/golang-lru"
  35. )
  36. func init() {
  37. runtime.GOMAXPROCS(runtime.NumCPU())
  38. }
  39. func thePow() pow.PoW {
  40. pow, _ := ethash.NewForTesting()
  41. return pow
  42. }
  43. func theChainManager(db ethdb.Database, t *testing.T) *ChainManager {
  44. var eventMux event.TypeMux
  45. WriteTestNetGenesisBlock(db, 0)
  46. chainMan, err := NewChainManager(db, thePow(), &eventMux)
  47. if err != nil {
  48. t.Error("failed creating chainmanager:", err)
  49. t.FailNow()
  50. return nil
  51. }
  52. blockMan := NewBlockProcessor(db, nil, chainMan, &eventMux)
  53. chainMan.SetProcessor(blockMan)
  54. return chainMan
  55. }
  56. // Test fork of length N starting from block i
  57. func testFork(t *testing.T, bman *BlockProcessor, i, N int, f func(td1, td2 *big.Int)) {
  58. // switch databases to process the new chain
  59. db, err := ethdb.NewMemDatabase()
  60. if err != nil {
  61. t.Fatal("Failed to create db:", err)
  62. }
  63. // copy old chain up to i into new db with deterministic canonical
  64. bman2, err := newCanonical(i, db)
  65. if err != nil {
  66. t.Fatal("could not make new canonical in testFork", err)
  67. }
  68. // asert the bmans have the same block at i
  69. bi1 := bman.bc.GetBlockByNumber(uint64(i)).Hash()
  70. bi2 := bman2.bc.GetBlockByNumber(uint64(i)).Hash()
  71. if bi1 != bi2 {
  72. fmt.Printf("%+v\n%+v\n\n", bi1, bi2)
  73. t.Fatal("chains do not have the same hash at height", i)
  74. }
  75. bman2.bc.SetProcessor(bman2)
  76. // extend the fork
  77. parent := bman2.bc.CurrentBlock()
  78. chainB := makeChain(parent, N, db, forkSeed)
  79. _, err = bman2.bc.InsertChain(chainB)
  80. if err != nil {
  81. t.Fatal("Insert chain error for fork:", err)
  82. }
  83. tdpre := bman.bc.Td()
  84. // Test the fork's blocks on the original chain
  85. td, err := testChain(chainB, bman)
  86. if err != nil {
  87. t.Fatal("expected chainB not to give errors:", err)
  88. }
  89. // Compare difficulties
  90. f(tdpre, td)
  91. // Loop over parents making sure reconstruction is done properly
  92. }
  93. func printChain(bc *ChainManager) {
  94. for i := bc.CurrentBlock().Number().Uint64(); i > 0; i-- {
  95. b := bc.GetBlockByNumber(uint64(i))
  96. fmt.Printf("\t%x %v\n", b.Hash(), b.Difficulty())
  97. }
  98. }
  99. // process blocks against a chain
  100. func testChain(chainB types.Blocks, bman *BlockProcessor) (*big.Int, error) {
  101. for _, block := range chainB {
  102. _, _, err := bman.bc.processor.Process(block)
  103. if err != nil {
  104. if IsKnownBlockErr(err) {
  105. continue
  106. }
  107. return nil, err
  108. }
  109. bman.bc.mu.Lock()
  110. WriteTd(bman.bc.chainDb, block.Hash(), new(big.Int).Add(block.Difficulty(), bman.bc.GetTd(block.ParentHash())))
  111. WriteBlock(bman.bc.chainDb, block)
  112. bman.bc.mu.Unlock()
  113. }
  114. return bman.bc.GetTd(chainB[len(chainB)-1].Hash()), nil
  115. }
  116. func loadChain(fn string, t *testing.T) (types.Blocks, error) {
  117. fh, err := os.OpenFile(filepath.Join("..", "_data", fn), os.O_RDONLY, os.ModePerm)
  118. if err != nil {
  119. return nil, err
  120. }
  121. defer fh.Close()
  122. var chain types.Blocks
  123. if err := rlp.Decode(fh, &chain); err != nil {
  124. return nil, err
  125. }
  126. return chain, nil
  127. }
  128. func insertChain(done chan bool, chainMan *ChainManager, chain types.Blocks, t *testing.T) {
  129. _, err := chainMan.InsertChain(chain)
  130. if err != nil {
  131. fmt.Println(err)
  132. t.FailNow()
  133. }
  134. done <- true
  135. }
  136. func TestExtendCanonical(t *testing.T) {
  137. CanonicalLength := 5
  138. db, err := ethdb.NewMemDatabase()
  139. if err != nil {
  140. t.Fatal("Failed to create db:", err)
  141. }
  142. // make first chain starting from genesis
  143. bman, err := newCanonical(CanonicalLength, db)
  144. if err != nil {
  145. t.Fatal("Could not make new canonical chain:", err)
  146. }
  147. f := func(td1, td2 *big.Int) {
  148. if td2.Cmp(td1) <= 0 {
  149. t.Error("expected chainB to have higher difficulty. Got", td2, "expected more than", td1)
  150. }
  151. }
  152. // Start fork from current height (CanonicalLength)
  153. testFork(t, bman, CanonicalLength, 1, f)
  154. testFork(t, bman, CanonicalLength, 2, f)
  155. testFork(t, bman, CanonicalLength, 5, f)
  156. testFork(t, bman, CanonicalLength, 10, f)
  157. }
  158. func TestShorterFork(t *testing.T) {
  159. db, err := ethdb.NewMemDatabase()
  160. if err != nil {
  161. t.Fatal("Failed to create db:", err)
  162. }
  163. // make first chain starting from genesis
  164. bman, err := newCanonical(10, db)
  165. if err != nil {
  166. t.Fatal("Could not make new canonical chain:", err)
  167. }
  168. f := func(td1, td2 *big.Int) {
  169. if td2.Cmp(td1) >= 0 {
  170. t.Error("expected chainB to have lower difficulty. Got", td2, "expected less than", td1)
  171. }
  172. }
  173. // Sum of numbers must be less than 10
  174. // for this to be a shorter fork
  175. testFork(t, bman, 0, 3, f)
  176. testFork(t, bman, 0, 7, f)
  177. testFork(t, bman, 1, 1, f)
  178. testFork(t, bman, 1, 7, f)
  179. testFork(t, bman, 5, 3, f)
  180. testFork(t, bman, 5, 4, f)
  181. }
  182. func TestLongerFork(t *testing.T) {
  183. db, err := ethdb.NewMemDatabase()
  184. if err != nil {
  185. t.Fatal("Failed to create db:", err)
  186. }
  187. // make first chain starting from genesis
  188. bman, err := newCanonical(10, db)
  189. if err != nil {
  190. t.Fatal("Could not make new canonical chain:", err)
  191. }
  192. f := func(td1, td2 *big.Int) {
  193. if td2.Cmp(td1) <= 0 {
  194. t.Error("expected chainB to have higher difficulty. Got", td2, "expected more than", td1)
  195. }
  196. }
  197. // Sum of numbers must be greater than 10
  198. // for this to be a longer fork
  199. testFork(t, bman, 0, 11, f)
  200. testFork(t, bman, 0, 15, f)
  201. testFork(t, bman, 1, 10, f)
  202. testFork(t, bman, 1, 12, f)
  203. testFork(t, bman, 5, 6, f)
  204. testFork(t, bman, 5, 8, f)
  205. }
  206. func TestEqualFork(t *testing.T) {
  207. db, err := ethdb.NewMemDatabase()
  208. if err != nil {
  209. t.Fatal("Failed to create db:", err)
  210. }
  211. bman, err := newCanonical(10, db)
  212. if err != nil {
  213. t.Fatal("Could not make new canonical chain:", err)
  214. }
  215. f := func(td1, td2 *big.Int) {
  216. if td2.Cmp(td1) != 0 {
  217. t.Error("expected chainB to have equal difficulty. Got", td2, "expected ", td1)
  218. }
  219. }
  220. // Sum of numbers must be equal to 10
  221. // for this to be an equal fork
  222. testFork(t, bman, 0, 10, f)
  223. testFork(t, bman, 1, 9, f)
  224. testFork(t, bman, 2, 8, f)
  225. testFork(t, bman, 5, 5, f)
  226. testFork(t, bman, 6, 4, f)
  227. testFork(t, bman, 9, 1, f)
  228. }
  229. func TestBrokenChain(t *testing.T) {
  230. db, err := ethdb.NewMemDatabase()
  231. if err != nil {
  232. t.Fatal("Failed to create db:", err)
  233. }
  234. bman, err := newCanonical(10, db)
  235. if err != nil {
  236. t.Fatal("Could not make new canonical chain:", err)
  237. }
  238. db2, err := ethdb.NewMemDatabase()
  239. if err != nil {
  240. t.Fatal("Failed to create db:", err)
  241. }
  242. bman2, err := newCanonical(10, db2)
  243. if err != nil {
  244. t.Fatal("Could not make new canonical chain:", err)
  245. }
  246. bman2.bc.SetProcessor(bman2)
  247. parent := bman2.bc.CurrentBlock()
  248. chainB := makeChain(parent, 5, db2, forkSeed)
  249. chainB = chainB[1:]
  250. _, err = testChain(chainB, bman)
  251. if err == nil {
  252. t.Error("expected broken chain to return error")
  253. }
  254. }
  255. func TestChainInsertions(t *testing.T) {
  256. t.Skip("Skipped: outdated test files")
  257. db, _ := ethdb.NewMemDatabase()
  258. chain1, err := loadChain("valid1", t)
  259. if err != nil {
  260. fmt.Println(err)
  261. t.FailNow()
  262. }
  263. chain2, err := loadChain("valid2", t)
  264. if err != nil {
  265. fmt.Println(err)
  266. t.FailNow()
  267. }
  268. chainMan := theChainManager(db, t)
  269. const max = 2
  270. done := make(chan bool, max)
  271. go insertChain(done, chainMan, chain1, t)
  272. go insertChain(done, chainMan, chain2, t)
  273. for i := 0; i < max; i++ {
  274. <-done
  275. }
  276. if chain2[len(chain2)-1].Hash() != chainMan.CurrentBlock().Hash() {
  277. t.Error("chain2 is canonical and shouldn't be")
  278. }
  279. if chain1[len(chain1)-1].Hash() != chainMan.CurrentBlock().Hash() {
  280. t.Error("chain1 isn't canonical and should be")
  281. }
  282. }
  283. func TestChainMultipleInsertions(t *testing.T) {
  284. t.Skip("Skipped: outdated test files")
  285. db, _ := ethdb.NewMemDatabase()
  286. const max = 4
  287. chains := make([]types.Blocks, max)
  288. var longest int
  289. for i := 0; i < max; i++ {
  290. var err error
  291. name := "valid" + strconv.Itoa(i+1)
  292. chains[i], err = loadChain(name, t)
  293. if len(chains[i]) >= len(chains[longest]) {
  294. longest = i
  295. }
  296. fmt.Println("loaded", name, "with a length of", len(chains[i]))
  297. if err != nil {
  298. fmt.Println(err)
  299. t.FailNow()
  300. }
  301. }
  302. chainMan := theChainManager(db, t)
  303. done := make(chan bool, max)
  304. for i, chain := range chains {
  305. // XXX the go routine would otherwise reference the same (chain[3]) variable and fail
  306. i := i
  307. chain := chain
  308. go func() {
  309. insertChain(done, chainMan, chain, t)
  310. fmt.Println(i, "done")
  311. }()
  312. }
  313. for i := 0; i < max; i++ {
  314. <-done
  315. }
  316. if chains[longest][len(chains[longest])-1].Hash() != chainMan.CurrentBlock().Hash() {
  317. t.Error("Invalid canonical chain")
  318. }
  319. }
  320. type bproc struct{}
  321. func (bproc) Process(*types.Block) (state.Logs, types.Receipts, error) { return nil, nil, nil }
  322. func makeChainWithDiff(genesis *types.Block, d []int, seed byte) []*types.Block {
  323. var chain []*types.Block
  324. for i, difficulty := range d {
  325. header := &types.Header{
  326. Coinbase: common.Address{seed},
  327. Number: big.NewInt(int64(i + 1)),
  328. Difficulty: big.NewInt(int64(difficulty)),
  329. }
  330. if i == 0 {
  331. header.ParentHash = genesis.Hash()
  332. } else {
  333. header.ParentHash = chain[i-1].Hash()
  334. }
  335. block := types.NewBlockWithHeader(header)
  336. chain = append(chain, block)
  337. }
  338. return chain
  339. }
  340. func chm(genesis *types.Block, db ethdb.Database) *ChainManager {
  341. var eventMux event.TypeMux
  342. bc := &ChainManager{chainDb: db, genesisBlock: genesis, eventMux: &eventMux, pow: FakePow{}}
  343. bc.headerCache, _ = lru.New(100)
  344. bc.bodyCache, _ = lru.New(100)
  345. bc.bodyRLPCache, _ = lru.New(100)
  346. bc.tdCache, _ = lru.New(100)
  347. bc.blockCache, _ = lru.New(100)
  348. bc.futureBlocks, _ = lru.New(100)
  349. bc.processor = bproc{}
  350. bc.ResetWithGenesisBlock(genesis)
  351. return bc
  352. }
  353. func TestReorgLongest(t *testing.T) {
  354. db, _ := ethdb.NewMemDatabase()
  355. genesis, err := WriteTestNetGenesisBlock(db, 0)
  356. if err != nil {
  357. t.Error(err)
  358. t.FailNow()
  359. }
  360. bc := chm(genesis, db)
  361. chain1 := makeChainWithDiff(genesis, []int{1, 2, 4}, 10)
  362. chain2 := makeChainWithDiff(genesis, []int{1, 2, 3, 4}, 11)
  363. bc.InsertChain(chain1)
  364. bc.InsertChain(chain2)
  365. prev := bc.CurrentBlock()
  366. for block := bc.GetBlockByNumber(bc.CurrentBlock().NumberU64() - 1); block.NumberU64() != 0; prev, block = block, bc.GetBlockByNumber(block.NumberU64()-1) {
  367. if prev.ParentHash() != block.Hash() {
  368. t.Errorf("parent hash mismatch %x - %x", prev.ParentHash(), block.Hash())
  369. }
  370. }
  371. }
  372. func TestReorgShortest(t *testing.T) {
  373. db, _ := ethdb.NewMemDatabase()
  374. genesis, err := WriteTestNetGenesisBlock(db, 0)
  375. if err != nil {
  376. t.Error(err)
  377. t.FailNow()
  378. }
  379. bc := chm(genesis, db)
  380. chain1 := makeChainWithDiff(genesis, []int{1, 2, 3, 4}, 10)
  381. chain2 := makeChainWithDiff(genesis, []int{1, 10}, 11)
  382. bc.InsertChain(chain1)
  383. bc.InsertChain(chain2)
  384. prev := bc.CurrentBlock()
  385. for block := bc.GetBlockByNumber(bc.CurrentBlock().NumberU64() - 1); block.NumberU64() != 0; prev, block = block, bc.GetBlockByNumber(block.NumberU64()-1) {
  386. if prev.ParentHash() != block.Hash() {
  387. t.Errorf("parent hash mismatch %x - %x", prev.ParentHash(), block.Hash())
  388. }
  389. }
  390. }
  391. func TestInsertNonceError(t *testing.T) {
  392. for i := 1; i < 25 && !t.Failed(); i++ {
  393. db, _ := ethdb.NewMemDatabase()
  394. genesis, err := WriteTestNetGenesisBlock(db, 0)
  395. if err != nil {
  396. t.Error(err)
  397. t.FailNow()
  398. }
  399. bc := chm(genesis, db)
  400. bc.processor = NewBlockProcessor(db, bc.pow, bc, bc.eventMux)
  401. blocks := makeChain(bc.currentBlock, i, db, 0)
  402. fail := rand.Int() % len(blocks)
  403. failblock := blocks[fail]
  404. bc.pow = failPow{failblock.NumberU64()}
  405. n, err := bc.InsertChain(blocks)
  406. // Check that the returned error indicates the nonce failure.
  407. if n != fail {
  408. t.Errorf("(i=%d) wrong failed block index: got %d, want %d", i, n, fail)
  409. }
  410. if !IsBlockNonceErr(err) {
  411. t.Fatalf("(i=%d) got %q, want a nonce error", i, err)
  412. }
  413. nerr := err.(*BlockNonceErr)
  414. if nerr.Number.Cmp(failblock.Number()) != 0 {
  415. t.Errorf("(i=%d) wrong block number in error, got %v, want %v", i, nerr.Number, failblock.Number())
  416. }
  417. if nerr.Hash != failblock.Hash() {
  418. t.Errorf("(i=%d) wrong block hash in error, got %v, want %v", i, nerr.Hash, failblock.Hash())
  419. }
  420. // Check that all no blocks after the failing block have been inserted.
  421. for _, block := range blocks[fail:] {
  422. if bc.HasBlock(block.Hash()) {
  423. t.Errorf("(i=%d) invalid block %d present in chain", i, block.NumberU64())
  424. }
  425. }
  426. }
  427. }
  428. /*
  429. func TestGenesisMismatch(t *testing.T) {
  430. db, _ := ethdb.NewMemDatabase()
  431. var mux event.TypeMux
  432. genesis := GenesisBlock(0, db)
  433. _, err := NewChainManager(genesis, db, db, db, thePow(), &mux)
  434. if err != nil {
  435. t.Error(err)
  436. }
  437. genesis = GenesisBlock(1, db)
  438. _, err = NewChainManager(genesis, db, db, db, thePow(), &mux)
  439. if err == nil {
  440. t.Error("expected genesis mismatch error")
  441. }
  442. }
  443. */