chain_manager_test.go 8.5 KB

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