chain_manager_test.go 7.9 KB

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