chain_manager_test.go 13 KB

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