sync_test.go 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362
  1. // Copyright 2019 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 les
  17. import (
  18. "fmt"
  19. "math/big"
  20. "testing"
  21. "time"
  22. "github.com/ethereum/go-ethereum/accounts/abi/bind"
  23. "github.com/ethereum/go-ethereum/core"
  24. "github.com/ethereum/go-ethereum/core/types"
  25. "github.com/ethereum/go-ethereum/crypto"
  26. "github.com/ethereum/go-ethereum/light"
  27. "github.com/ethereum/go-ethereum/params"
  28. )
  29. // Test light syncing which will download all headers from genesis.
  30. func TestLightSyncingLes3(t *testing.T) { testCheckpointSyncing(t, 3, 0) }
  31. // Test legacy checkpoint syncing which will download tail headers
  32. // based on a hardcoded checkpoint.
  33. func TestLegacyCheckpointSyncingLes3(t *testing.T) { testCheckpointSyncing(t, 3, 1) }
  34. // Test checkpoint syncing which will download tail headers based
  35. // on a verified checkpoint.
  36. func TestCheckpointSyncingLes3(t *testing.T) { testCheckpointSyncing(t, 3, 2) }
  37. func testCheckpointSyncing(t *testing.T, protocol int, syncMode int) {
  38. config := light.TestServerIndexerConfig
  39. waitIndexers := func(cIndexer, bIndexer, btIndexer *core.ChainIndexer) {
  40. for {
  41. cs, _, _ := cIndexer.Sections()
  42. bts, _, _ := btIndexer.Sections()
  43. if cs >= 1 && bts >= 1 {
  44. break
  45. }
  46. time.Sleep(10 * time.Millisecond)
  47. }
  48. }
  49. // Generate 128+1 blocks (totally 1 CHT section)
  50. server, client, tearDown := newClientServerEnv(t, int(config.ChtSize+config.ChtConfirms), protocol, waitIndexers, nil, 0, false, false, true)
  51. defer tearDown()
  52. expected := config.ChtSize + config.ChtConfirms
  53. // Checkpoint syncing or legacy checkpoint syncing.
  54. if syncMode == 1 || syncMode == 2 {
  55. // Assemble checkpoint 0
  56. s, _, head := server.chtIndexer.Sections()
  57. cp := &params.TrustedCheckpoint{
  58. SectionIndex: 0,
  59. SectionHead: head,
  60. CHTRoot: light.GetChtRoot(server.db, s-1, head),
  61. BloomRoot: light.GetBloomTrieRoot(server.db, s-1, head),
  62. }
  63. if syncMode == 1 {
  64. // Register the assembled checkpoint as hardcoded one.
  65. client.handler.checkpoint = cp
  66. client.handler.backend.blockchain.AddTrustedCheckpoint(cp)
  67. } else {
  68. // Register the assembled checkpoint into oracle.
  69. header := server.backend.Blockchain().CurrentHeader()
  70. data := append([]byte{0x19, 0x00}, append(registrarAddr.Bytes(), append([]byte{0, 0, 0, 0, 0, 0, 0, 0}, cp.Hash().Bytes()...)...)...)
  71. sig, _ := crypto.Sign(crypto.Keccak256(data), signerKey)
  72. sig[64] += 27 // Transform V from 0/1 to 27/28 according to the yellow paper
  73. auth, _ := bind.NewKeyedTransactorWithChainID(signerKey, big.NewInt(1337))
  74. if _, err := server.handler.server.oracle.Contract().RegisterCheckpoint(auth, cp.SectionIndex, cp.Hash().Bytes(), new(big.Int).Sub(header.Number, big.NewInt(1)), header.ParentHash, [][]byte{sig}); err != nil {
  75. t.Error("register checkpoint failed", err)
  76. }
  77. server.backend.Commit()
  78. // Wait for the checkpoint registration
  79. for {
  80. _, hash, _, err := server.handler.server.oracle.Contract().Contract().GetLatestCheckpoint(nil)
  81. if err != nil || hash == [32]byte{} {
  82. time.Sleep(10 * time.Millisecond)
  83. continue
  84. }
  85. break
  86. }
  87. expected += 1
  88. }
  89. }
  90. done := make(chan error)
  91. client.handler.syncEnd = func(header *types.Header) {
  92. if header.Number.Uint64() == expected {
  93. done <- nil
  94. } else {
  95. done <- fmt.Errorf("blockchain length mismatch, want %d, got %d", expected, header.Number)
  96. }
  97. }
  98. // Create connected peer pair.
  99. peer1, peer2, err := newTestPeerPair("peer", protocol, server.handler, client.handler)
  100. if err != nil {
  101. t.Fatalf("Failed to connect testing peers %v", err)
  102. }
  103. defer peer1.close()
  104. defer peer2.close()
  105. select {
  106. case err := <-done:
  107. if err != nil {
  108. t.Error("sync failed", err)
  109. }
  110. return
  111. case <-time.NewTimer(10 * time.Second).C:
  112. t.Error("checkpoint syncing timeout")
  113. }
  114. }
  115. func TestMissOracleBackend(t *testing.T) { testMissOracleBackend(t, true) }
  116. func TestMissOracleBackendNoCheckpoint(t *testing.T) { testMissOracleBackend(t, false) }
  117. func testMissOracleBackend(t *testing.T, hasCheckpoint bool) {
  118. config := light.TestServerIndexerConfig
  119. waitIndexers := func(cIndexer, bIndexer, btIndexer *core.ChainIndexer) {
  120. for {
  121. cs, _, _ := cIndexer.Sections()
  122. bts, _, _ := btIndexer.Sections()
  123. if cs >= 1 && bts >= 1 {
  124. break
  125. }
  126. time.Sleep(10 * time.Millisecond)
  127. }
  128. }
  129. // Generate 128+1 blocks (totally 1 CHT section)
  130. server, client, tearDown := newClientServerEnv(t, int(config.ChtSize+config.ChtConfirms), 3, waitIndexers, nil, 0, false, false, true)
  131. defer tearDown()
  132. expected := config.ChtSize + config.ChtConfirms
  133. s, _, head := server.chtIndexer.Sections()
  134. cp := &params.TrustedCheckpoint{
  135. SectionIndex: 0,
  136. SectionHead: head,
  137. CHTRoot: light.GetChtRoot(server.db, s-1, head),
  138. BloomRoot: light.GetBloomTrieRoot(server.db, s-1, head),
  139. }
  140. // Register the assembled checkpoint into oracle.
  141. header := server.backend.Blockchain().CurrentHeader()
  142. data := append([]byte{0x19, 0x00}, append(registrarAddr.Bytes(), append([]byte{0, 0, 0, 0, 0, 0, 0, 0}, cp.Hash().Bytes()...)...)...)
  143. sig, _ := crypto.Sign(crypto.Keccak256(data), signerKey)
  144. sig[64] += 27 // Transform V from 0/1 to 27/28 according to the yellow paper
  145. auth, _ := bind.NewKeyedTransactorWithChainID(signerKey, big.NewInt(1337))
  146. if _, err := server.handler.server.oracle.Contract().RegisterCheckpoint(auth, cp.SectionIndex, cp.Hash().Bytes(), new(big.Int).Sub(header.Number, big.NewInt(1)), header.ParentHash, [][]byte{sig}); err != nil {
  147. t.Error("register checkpoint failed", err)
  148. }
  149. server.backend.Commit()
  150. // Wait for the checkpoint registration
  151. for {
  152. _, hash, _, err := server.handler.server.oracle.Contract().Contract().GetLatestCheckpoint(nil)
  153. if err != nil || hash == [32]byte{} {
  154. time.Sleep(100 * time.Millisecond)
  155. continue
  156. }
  157. break
  158. }
  159. expected += 1
  160. // Explicitly set the oracle as nil. In normal use case it can happen
  161. // that user wants to unlock something which blocks the oracle backend
  162. // initialisation. But at the same time syncing starts.
  163. //
  164. // See https://github.com/ethereum/go-ethereum/issues/20097 for more detail.
  165. //
  166. // In this case, client should run light sync or legacy checkpoint sync
  167. // if hardcoded checkpoint is configured.
  168. client.handler.backend.oracle = nil
  169. // For some private networks it can happen checkpoint syncing is enabled
  170. // but there is no hardcoded checkpoint configured.
  171. if hasCheckpoint {
  172. client.handler.checkpoint = cp
  173. client.handler.backend.blockchain.AddTrustedCheckpoint(cp)
  174. }
  175. done := make(chan error)
  176. client.handler.syncEnd = func(header *types.Header) {
  177. if header.Number.Uint64() == expected {
  178. done <- nil
  179. } else {
  180. done <- fmt.Errorf("blockchain length mismatch, want %d, got %d", expected, header.Number)
  181. }
  182. }
  183. // Create connected peer pair.
  184. if _, _, err := newTestPeerPair("peer", 2, server.handler, client.handler); err != nil {
  185. t.Fatalf("Failed to connect testing peers %v", err)
  186. }
  187. select {
  188. case err := <-done:
  189. if err != nil {
  190. t.Error("sync failed", err)
  191. }
  192. return
  193. case <-time.NewTimer(10 * time.Second).C:
  194. t.Error("checkpoint syncing timeout")
  195. }
  196. }
  197. func TestSyncFromConfiguredCheckpoint(t *testing.T) {
  198. config := light.TestServerIndexerConfig
  199. waitIndexers := func(cIndexer, bIndexer, btIndexer *core.ChainIndexer) {
  200. for {
  201. cs, _, _ := cIndexer.Sections()
  202. bts, _, _ := btIndexer.Sections()
  203. if cs >= 2 && bts >= 2 {
  204. break
  205. }
  206. time.Sleep(10 * time.Millisecond)
  207. }
  208. }
  209. // Generate 256+1 blocks (totally 2 CHT sections)
  210. server, client, tearDown := newClientServerEnv(t, int(2*config.ChtSize+config.ChtConfirms), 3, waitIndexers, nil, 0, false, false, true)
  211. defer tearDown()
  212. // Configure the local checkpoint(the first section)
  213. head := server.handler.blockchain.GetHeaderByNumber(config.ChtSize - 1).Hash()
  214. cp := &params.TrustedCheckpoint{
  215. SectionIndex: 0,
  216. SectionHead: head,
  217. CHTRoot: light.GetChtRoot(server.db, 0, head),
  218. BloomRoot: light.GetBloomTrieRoot(server.db, 0, head),
  219. }
  220. client.handler.backend.config.SyncFromCheckpoint = true
  221. client.handler.backend.config.Checkpoint = cp
  222. client.handler.checkpoint = cp
  223. client.handler.backend.blockchain.AddTrustedCheckpoint(cp)
  224. var (
  225. start = make(chan error, 1)
  226. end = make(chan error, 1)
  227. expectStart = config.ChtSize - 1
  228. expectEnd = 2*config.ChtSize + config.ChtConfirms
  229. )
  230. client.handler.syncStart = func(header *types.Header) {
  231. if header.Number.Uint64() == expectStart {
  232. start <- nil
  233. } else {
  234. start <- fmt.Errorf("blockchain length mismatch, want %d, got %d", expectStart, header.Number)
  235. }
  236. }
  237. client.handler.syncEnd = func(header *types.Header) {
  238. if header.Number.Uint64() == expectEnd {
  239. end <- nil
  240. } else {
  241. end <- fmt.Errorf("blockchain length mismatch, want %d, got %d", expectEnd, header.Number)
  242. }
  243. }
  244. // Create connected peer pair.
  245. if _, _, err := newTestPeerPair("peer", 2, server.handler, client.handler); err != nil {
  246. t.Fatalf("Failed to connect testing peers %v", err)
  247. }
  248. select {
  249. case err := <-start:
  250. if err != nil {
  251. t.Error("sync failed", err)
  252. }
  253. return
  254. case <-time.NewTimer(10 * time.Second).C:
  255. t.Error("checkpoint syncing timeout")
  256. }
  257. select {
  258. case err := <-end:
  259. if err != nil {
  260. t.Error("sync failed", err)
  261. }
  262. return
  263. case <-time.NewTimer(10 * time.Second).C:
  264. t.Error("checkpoint syncing timeout")
  265. }
  266. }
  267. func TestSyncAll(t *testing.T) {
  268. config := light.TestServerIndexerConfig
  269. waitIndexers := func(cIndexer, bIndexer, btIndexer *core.ChainIndexer) {
  270. for {
  271. cs, _, _ := cIndexer.Sections()
  272. bts, _, _ := btIndexer.Sections()
  273. if cs >= 2 && bts >= 2 {
  274. break
  275. }
  276. time.Sleep(10 * time.Millisecond)
  277. }
  278. }
  279. // Generate 256+1 blocks (totally 2 CHT sections)
  280. server, client, tearDown := newClientServerEnv(t, int(2*config.ChtSize+config.ChtConfirms), 3, waitIndexers, nil, 0, false, false, true)
  281. defer tearDown()
  282. client.handler.backend.config.SyncFromCheckpoint = true
  283. var (
  284. start = make(chan error, 1)
  285. end = make(chan error, 1)
  286. expectStart = uint64(0)
  287. expectEnd = 2*config.ChtSize + config.ChtConfirms
  288. )
  289. client.handler.syncStart = func(header *types.Header) {
  290. if header.Number.Uint64() == expectStart {
  291. start <- nil
  292. } else {
  293. start <- fmt.Errorf("blockchain length mismatch, want %d, got %d", expectStart, header.Number)
  294. }
  295. }
  296. client.handler.syncEnd = func(header *types.Header) {
  297. if header.Number.Uint64() == expectEnd {
  298. end <- nil
  299. } else {
  300. end <- fmt.Errorf("blockchain length mismatch, want %d, got %d", expectEnd, header.Number)
  301. }
  302. }
  303. // Create connected peer pair.
  304. if _, _, err := newTestPeerPair("peer", 2, server.handler, client.handler); err != nil {
  305. t.Fatalf("Failed to connect testing peers %v", err)
  306. }
  307. select {
  308. case err := <-start:
  309. if err != nil {
  310. t.Error("sync failed", err)
  311. }
  312. return
  313. case <-time.NewTimer(10 * time.Second).C:
  314. t.Error("checkpoint syncing timeout")
  315. }
  316. select {
  317. case err := <-end:
  318. if err != nil {
  319. t.Error("sync failed", err)
  320. }
  321. return
  322. case <-time.NewTimer(10 * time.Second).C:
  323. t.Error("checkpoint syncing timeout")
  324. }
  325. }