chain_manager_test.go 8.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346
  1. package core
  2. import (
  3. "fmt"
  4. "math/big"
  5. "os"
  6. "path"
  7. "runtime"
  8. "strconv"
  9. "testing"
  10. "github.com/ethereum/go-ethereum/core/types"
  11. "github.com/ethereum/go-ethereum/ethdb"
  12. "github.com/ethereum/go-ethereum/event"
  13. "github.com/ethereum/go-ethereum/rlp"
  14. )
  15. func init() {
  16. runtime.GOMAXPROCS(runtime.NumCPU())
  17. }
  18. // Test fork of length N starting from block i
  19. func testFork(t *testing.T, bman *BlockProcessor, i, N int, f func(td1, td2 *big.Int)) {
  20. // switch databases to process the new chain
  21. db, err := ethdb.NewMemDatabase()
  22. if err != nil {
  23. t.Fatal("Failed to create db:", err)
  24. }
  25. // copy old chain up to i into new db with deterministic canonical
  26. bman2, err := newCanonical(i, db)
  27. if err != nil {
  28. t.Fatal("could not make new canonical in testFork", err)
  29. }
  30. // asert the bmans have the same block at i
  31. bi1 := bman.bc.GetBlockByNumber(uint64(i)).Hash()
  32. bi2 := bman2.bc.GetBlockByNumber(uint64(i)).Hash()
  33. if bi1 != bi2 {
  34. t.Fatal("chains do not have the same hash at height", i)
  35. }
  36. bman2.bc.SetProcessor(bman2)
  37. // extend the fork
  38. parent := bman2.bc.CurrentBlock()
  39. chainB := makeChain(bman2, parent, N, db, ForkSeed)
  40. err = bman2.bc.InsertChain(chainB)
  41. if err != nil {
  42. t.Fatal("Insert chain error for fork:", err)
  43. }
  44. tdpre := bman.bc.Td()
  45. // Test the fork's blocks on the original chain
  46. td, err := testChain(chainB, bman)
  47. if err != nil {
  48. t.Fatal("expected chainB not to give errors:", err)
  49. }
  50. // Compare difficulties
  51. f(tdpre, td)
  52. }
  53. func printChain(bc *ChainManager) {
  54. for i := bc.CurrentBlock().Number().Uint64(); i > 0; i-- {
  55. b := bc.GetBlockByNumber(uint64(i))
  56. fmt.Printf("\t%x\n", b.Hash())
  57. }
  58. }
  59. // process blocks against a chain
  60. func testChain(chainB types.Blocks, bman *BlockProcessor) (*big.Int, error) {
  61. td := new(big.Int)
  62. for _, block := range chainB {
  63. _, err := bman.bc.processor.Process(block)
  64. if err != nil {
  65. if IsKnownBlockErr(err) {
  66. continue
  67. }
  68. return nil, err
  69. }
  70. parent := bman.bc.GetBlock(block.ParentHash())
  71. block.Td = CalculateTD(block, parent)
  72. td = block.Td
  73. bman.bc.mu.Lock()
  74. {
  75. bman.bc.write(block)
  76. }
  77. bman.bc.mu.Unlock()
  78. }
  79. return td, nil
  80. }
  81. func loadChain(fn string, t *testing.T) (types.Blocks, error) {
  82. fh, err := os.OpenFile(path.Join(os.Getenv("GOPATH"), "src", "github.com", "ethereum", "go-ethereum", "_data", fn), os.O_RDONLY, os.ModePerm)
  83. if err != nil {
  84. return nil, err
  85. }
  86. defer fh.Close()
  87. var chain types.Blocks
  88. if err := rlp.Decode(fh, &chain); err != nil {
  89. return nil, err
  90. }
  91. return chain, nil
  92. }
  93. func insertChain(done chan bool, chainMan *ChainManager, chain types.Blocks, t *testing.T) {
  94. err := chainMan.InsertChain(chain)
  95. if err != nil {
  96. fmt.Println(err)
  97. t.FailNow()
  98. }
  99. done <- true
  100. }
  101. func TestExtendCanonical(t *testing.T) {
  102. CanonicalLength := 5
  103. db, err := ethdb.NewMemDatabase()
  104. if err != nil {
  105. t.Fatal("Failed to create db:", err)
  106. }
  107. // make first chain starting from genesis
  108. bman, err := newCanonical(CanonicalLength, db)
  109. if err != nil {
  110. t.Fatal("Could not make new canonical chain:", err)
  111. }
  112. f := func(td1, td2 *big.Int) {
  113. if td2.Cmp(td1) <= 0 {
  114. t.Error("expected chainB to have higher difficulty. Got", td2, "expected more than", td1)
  115. }
  116. }
  117. // Start fork from current height (CanonicalLength)
  118. testFork(t, bman, CanonicalLength, 1, f)
  119. testFork(t, bman, CanonicalLength, 2, f)
  120. testFork(t, bman, CanonicalLength, 5, f)
  121. testFork(t, bman, CanonicalLength, 10, f)
  122. }
  123. func TestShorterFork(t *testing.T) {
  124. db, err := ethdb.NewMemDatabase()
  125. if err != nil {
  126. t.Fatal("Failed to create db:", err)
  127. }
  128. // make first chain starting from genesis
  129. bman, err := newCanonical(10, db)
  130. if err != nil {
  131. t.Fatal("Could not make new canonical chain:", err)
  132. }
  133. f := func(td1, td2 *big.Int) {
  134. if td2.Cmp(td1) >= 0 {
  135. t.Error("expected chainB to have lower difficulty. Got", td2, "expected less than", td1)
  136. }
  137. }
  138. // Sum of numbers must be less than 10
  139. // for this to be a shorter fork
  140. testFork(t, bman, 0, 3, f)
  141. testFork(t, bman, 0, 7, f)
  142. testFork(t, bman, 1, 1, f)
  143. testFork(t, bman, 1, 7, f)
  144. testFork(t, bman, 5, 3, f)
  145. testFork(t, bman, 5, 4, f)
  146. }
  147. func TestLongerFork(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 higher difficulty. Got", td2, "expected more than", td1)
  160. }
  161. }
  162. // Sum of numbers must be greater than 10
  163. // for this to be a longer fork
  164. testFork(t, bman, 0, 11, f)
  165. testFork(t, bman, 0, 15, f)
  166. testFork(t, bman, 1, 10, f)
  167. testFork(t, bman, 1, 12, f)
  168. testFork(t, bman, 5, 6, f)
  169. testFork(t, bman, 5, 8, f)
  170. }
  171. func TestEqualFork(t *testing.T) {
  172. db, err := ethdb.NewMemDatabase()
  173. if err != nil {
  174. t.Fatal("Failed to create db:", err)
  175. }
  176. bman, err := newCanonical(10, db)
  177. if err != nil {
  178. t.Fatal("Could not make new canonical chain:", err)
  179. }
  180. f := func(td1, td2 *big.Int) {
  181. if td2.Cmp(td1) != 0 {
  182. t.Error("expected chainB to have equal difficulty. Got", td2, "expected ", td1)
  183. }
  184. }
  185. // Sum of numbers must be equal to 10
  186. // for this to be an equal fork
  187. testFork(t, bman, 0, 10, f)
  188. testFork(t, bman, 1, 9, f)
  189. testFork(t, bman, 2, 8, f)
  190. testFork(t, bman, 5, 5, f)
  191. testFork(t, bman, 6, 4, f)
  192. testFork(t, bman, 9, 1, f)
  193. }
  194. func TestBrokenChain(t *testing.T) {
  195. db, err := ethdb.NewMemDatabase()
  196. if err != nil {
  197. t.Fatal("Failed to create db:", err)
  198. }
  199. bman, err := newCanonical(10, db)
  200. if err != nil {
  201. t.Fatal("Could not make new canonical chain:", err)
  202. }
  203. db2, err := ethdb.NewMemDatabase()
  204. if err != nil {
  205. t.Fatal("Failed to create db:", err)
  206. }
  207. bman2, err := newCanonical(10, db2)
  208. if err != nil {
  209. t.Fatal("Could not make new canonical chain:", err)
  210. }
  211. bman2.bc.SetProcessor(bman2)
  212. parent := bman2.bc.CurrentBlock()
  213. chainB := makeChain(bman2, parent, 5, db2, ForkSeed)
  214. chainB = chainB[1:]
  215. _, err = testChain(chainB, bman)
  216. if err == nil {
  217. t.Error("expected broken chain to return error")
  218. }
  219. }
  220. func TestChainInsertions(t *testing.T) {
  221. t.Skip() // travil fails.
  222. db, _ := ethdb.NewMemDatabase()
  223. chain1, err := loadChain("valid1", t)
  224. if err != nil {
  225. fmt.Println(err)
  226. t.FailNow()
  227. }
  228. chain2, err := loadChain("valid2", t)
  229. if err != nil {
  230. fmt.Println(err)
  231. t.FailNow()
  232. }
  233. var eventMux event.TypeMux
  234. chainMan := NewChainManager(db, db, &eventMux)
  235. txPool := NewTxPool(&eventMux, chainMan.State, func() *big.Int { return big.NewInt(100000000) })
  236. blockMan := NewBlockProcessor(db, db, nil, txPool, chainMan, &eventMux)
  237. chainMan.SetProcessor(blockMan)
  238. const max = 2
  239. done := make(chan bool, max)
  240. go insertChain(done, chainMan, chain1, t)
  241. go insertChain(done, chainMan, chain2, t)
  242. for i := 0; i < max; i++ {
  243. <-done
  244. }
  245. if chain2[len(chain2)-1].Hash() != chainMan.CurrentBlock().Hash() {
  246. t.Error("chain2 is canonical and shouldn't be")
  247. }
  248. if chain1[len(chain1)-1].Hash() != chainMan.CurrentBlock().Hash() {
  249. t.Error("chain1 isn't canonical and should be")
  250. }
  251. }
  252. func TestChainMultipleInsertions(t *testing.T) {
  253. t.Skip() // travil fails.
  254. db, _ := ethdb.NewMemDatabase()
  255. const max = 4
  256. chains := make([]types.Blocks, max)
  257. var longest int
  258. for i := 0; i < max; i++ {
  259. var err error
  260. name := "valid" + strconv.Itoa(i+1)
  261. chains[i], err = loadChain(name, t)
  262. if len(chains[i]) >= len(chains[longest]) {
  263. longest = i
  264. }
  265. fmt.Println("loaded", name, "with a length of", len(chains[i]))
  266. if err != nil {
  267. fmt.Println(err)
  268. t.FailNow()
  269. }
  270. }
  271. var eventMux event.TypeMux
  272. chainMan := NewChainManager(db, db, &eventMux)
  273. txPool := NewTxPool(&eventMux, chainMan.State, func() *big.Int { return big.NewInt(100000000) })
  274. blockMan := NewBlockProcessor(db, db, nil, txPool, chainMan, &eventMux)
  275. chainMan.SetProcessor(blockMan)
  276. done := make(chan bool, max)
  277. for i, chain := range chains {
  278. // XXX the go routine would otherwise reference the same (chain[3]) variable and fail
  279. i := i
  280. chain := chain
  281. go func() {
  282. insertChain(done, chainMan, chain, t)
  283. fmt.Println(i, "done")
  284. }()
  285. }
  286. for i := 0; i < max; i++ {
  287. <-done
  288. }
  289. if chains[longest][len(chains[longest])-1].Hash() != chainMan.CurrentBlock().Hash() {
  290. t.Error("Invalid canonical chain")
  291. }
  292. }
  293. func TestGetAncestors(t *testing.T) {
  294. t.Skip() // travil fails.
  295. db, _ := ethdb.NewMemDatabase()
  296. var eventMux event.TypeMux
  297. chainMan := NewChainManager(db, db, &eventMux)
  298. chain, err := loadChain("valid1", t)
  299. if err != nil {
  300. fmt.Println(err)
  301. t.FailNow()
  302. }
  303. for _, block := range chain {
  304. chainMan.write(block)
  305. }
  306. ancestors := chainMan.GetAncestors(chain[len(chain)-1], 4)
  307. fmt.Println(ancestors)
  308. }