downloader_test.go 58 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423
  1. // Copyright 2015 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 downloader
  17. import (
  18. "errors"
  19. "fmt"
  20. "math/big"
  21. "sync"
  22. "sync/atomic"
  23. "testing"
  24. "time"
  25. "github.com/ethereum/go-ethereum/common"
  26. "github.com/ethereum/go-ethereum/core"
  27. "github.com/ethereum/go-ethereum/core/state"
  28. "github.com/ethereum/go-ethereum/core/types"
  29. "github.com/ethereum/go-ethereum/crypto"
  30. "github.com/ethereum/go-ethereum/ethdb"
  31. "github.com/ethereum/go-ethereum/event"
  32. "github.com/ethereum/go-ethereum/params"
  33. "github.com/ethereum/go-ethereum/trie"
  34. )
  35. var (
  36. testdb, _ = ethdb.NewMemDatabase()
  37. testKey, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
  38. testAddress = crypto.PubkeyToAddress(testKey.PublicKey)
  39. genesis = core.GenesisBlockForTesting(testdb, testAddress, big.NewInt(1000000000))
  40. )
  41. // makeChain creates a chain of n blocks starting at and including parent.
  42. // the returned hash chain is ordered head->parent. In addition, every 3rd block
  43. // contains a transaction and every 5th an uncle to allow testing correct block
  44. // reassembly.
  45. func makeChain(n int, seed byte, parent *types.Block, parentReceipts types.Receipts) ([]common.Hash, map[common.Hash]*types.Header, map[common.Hash]*types.Block, map[common.Hash]types.Receipts) {
  46. // Generate the block chain
  47. blocks, receipts := core.GenerateChain(parent, testdb, n, func(i int, block *core.BlockGen) {
  48. block.SetCoinbase(common.Address{seed})
  49. // If the block number is multiple of 3, send a bonus transaction to the miner
  50. if parent == genesis && i%3 == 0 {
  51. tx, err := types.NewTransaction(block.TxNonce(testAddress), common.Address{seed}, big.NewInt(1000), params.TxGas, nil, nil).SignECDSA(testKey)
  52. if err != nil {
  53. panic(err)
  54. }
  55. block.AddTx(tx)
  56. }
  57. // If the block number is a multiple of 5, add a bonus uncle to the block
  58. if i%5 == 0 {
  59. block.AddUncle(&types.Header{ParentHash: block.PrevBlock(i - 1).Hash(), Number: big.NewInt(int64(i - 1))})
  60. }
  61. })
  62. // Convert the block-chain into a hash-chain and header/block maps
  63. hashes := make([]common.Hash, n+1)
  64. hashes[len(hashes)-1] = parent.Hash()
  65. headerm := make(map[common.Hash]*types.Header, n+1)
  66. headerm[parent.Hash()] = parent.Header()
  67. blockm := make(map[common.Hash]*types.Block, n+1)
  68. blockm[parent.Hash()] = parent
  69. receiptm := make(map[common.Hash]types.Receipts, n+1)
  70. receiptm[parent.Hash()] = parentReceipts
  71. for i, b := range blocks {
  72. hashes[len(hashes)-i-2] = b.Hash()
  73. headerm[b.Hash()] = b.Header()
  74. blockm[b.Hash()] = b
  75. receiptm[b.Hash()] = receipts[i]
  76. }
  77. return hashes, headerm, blockm, receiptm
  78. }
  79. // makeChainFork creates two chains of length n, such that h1[:f] and
  80. // h2[:f] are different but have a common suffix of length n-f.
  81. func makeChainFork(n, f int, parent *types.Block, parentReceipts types.Receipts) ([]common.Hash, []common.Hash, map[common.Hash]*types.Header, map[common.Hash]*types.Header, map[common.Hash]*types.Block, map[common.Hash]*types.Block, map[common.Hash]types.Receipts, map[common.Hash]types.Receipts) {
  82. // Create the common suffix
  83. hashes, headers, blocks, receipts := makeChain(n-f, 0, parent, parentReceipts)
  84. // Create the forks
  85. hashes1, headers1, blocks1, receipts1 := makeChain(f, 1, blocks[hashes[0]], receipts[hashes[0]])
  86. hashes1 = append(hashes1, hashes[1:]...)
  87. hashes2, headers2, blocks2, receipts2 := makeChain(f, 2, blocks[hashes[0]], receipts[hashes[0]])
  88. hashes2 = append(hashes2, hashes[1:]...)
  89. for hash, header := range headers {
  90. headers1[hash] = header
  91. headers2[hash] = header
  92. }
  93. for hash, block := range blocks {
  94. blocks1[hash] = block
  95. blocks2[hash] = block
  96. }
  97. for hash, receipt := range receipts {
  98. receipts1[hash] = receipt
  99. receipts2[hash] = receipt
  100. }
  101. return hashes1, hashes2, headers1, headers2, blocks1, blocks2, receipts1, receipts2
  102. }
  103. // downloadTester is a test simulator for mocking out local block chain.
  104. type downloadTester struct {
  105. stateDb ethdb.Database
  106. downloader *Downloader
  107. ownHashes []common.Hash // Hash chain belonging to the tester
  108. ownHeaders map[common.Hash]*types.Header // Headers belonging to the tester
  109. ownBlocks map[common.Hash]*types.Block // Blocks belonging to the tester
  110. ownReceipts map[common.Hash]types.Receipts // Receipts belonging to the tester
  111. ownChainTd map[common.Hash]*big.Int // Total difficulties of the blocks in the local chain
  112. peerHashes map[string][]common.Hash // Hash chain belonging to different test peers
  113. peerHeaders map[string]map[common.Hash]*types.Header // Headers belonging to different test peers
  114. peerBlocks map[string]map[common.Hash]*types.Block // Blocks belonging to different test peers
  115. peerReceipts map[string]map[common.Hash]types.Receipts // Receipts belonging to different test peers
  116. peerChainTds map[string]map[common.Hash]*big.Int // Total difficulties of the blocks in the peer chains
  117. lock sync.RWMutex
  118. }
  119. // newTester creates a new downloader test mocker.
  120. func newTester(mode SyncMode) *downloadTester {
  121. tester := &downloadTester{
  122. ownHashes: []common.Hash{genesis.Hash()},
  123. ownHeaders: map[common.Hash]*types.Header{genesis.Hash(): genesis.Header()},
  124. ownBlocks: map[common.Hash]*types.Block{genesis.Hash(): genesis},
  125. ownReceipts: map[common.Hash]types.Receipts{genesis.Hash(): nil},
  126. ownChainTd: map[common.Hash]*big.Int{genesis.Hash(): genesis.Difficulty()},
  127. peerHashes: make(map[string][]common.Hash),
  128. peerHeaders: make(map[string]map[common.Hash]*types.Header),
  129. peerBlocks: make(map[string]map[common.Hash]*types.Block),
  130. peerReceipts: make(map[string]map[common.Hash]types.Receipts),
  131. peerChainTds: make(map[string]map[common.Hash]*big.Int),
  132. }
  133. tester.stateDb, _ = ethdb.NewMemDatabase()
  134. tester.downloader = New(mode, tester.stateDb, new(event.TypeMux), tester.hasHeader, tester.hasBlock, tester.getHeader,
  135. tester.getBlock, tester.headHeader, tester.headBlock, tester.headFastBlock, tester.commitHeadBlock, tester.getTd,
  136. tester.insertHeaders, tester.insertBlocks, tester.insertReceipts, tester.dropPeer)
  137. return tester
  138. }
  139. // sync starts synchronizing with a remote peer, blocking until it completes.
  140. func (dl *downloadTester) sync(id string, td *big.Int) error {
  141. dl.lock.RLock()
  142. hash := dl.peerHashes[id][0]
  143. // If no particular TD was requested, load from the peer's blockchain
  144. if td == nil {
  145. td = big.NewInt(1)
  146. if diff, ok := dl.peerChainTds[id][hash]; ok {
  147. td = diff
  148. }
  149. }
  150. dl.lock.RUnlock()
  151. err := dl.downloader.synchronise(id, hash, td)
  152. for {
  153. // If the queue is empty and processing stopped, break
  154. if dl.downloader.queue.Idle() && atomic.LoadInt32(&dl.downloader.processing) == 0 {
  155. break
  156. }
  157. // Otherwise sleep a bit and retry
  158. time.Sleep(time.Millisecond)
  159. }
  160. return err
  161. }
  162. // hasHeader checks if a header is present in the testers canonical chain.
  163. func (dl *downloadTester) hasHeader(hash common.Hash) bool {
  164. return dl.getHeader(hash) != nil
  165. }
  166. // hasBlock checks if a block is present in the testers canonical chain.
  167. func (dl *downloadTester) hasBlock(hash common.Hash) bool {
  168. return dl.getBlock(hash) != nil
  169. }
  170. // getHeader retrieves a header from the testers canonical chain.
  171. func (dl *downloadTester) getHeader(hash common.Hash) *types.Header {
  172. dl.lock.RLock()
  173. defer dl.lock.RUnlock()
  174. return dl.ownHeaders[hash]
  175. }
  176. // getBlock retrieves a block from the testers canonical chain.
  177. func (dl *downloadTester) getBlock(hash common.Hash) *types.Block {
  178. dl.lock.RLock()
  179. defer dl.lock.RUnlock()
  180. return dl.ownBlocks[hash]
  181. }
  182. // headHeader retrieves the current head header from the canonical chain.
  183. func (dl *downloadTester) headHeader() *types.Header {
  184. dl.lock.RLock()
  185. defer dl.lock.RUnlock()
  186. for i := len(dl.ownHashes) - 1; i >= 0; i-- {
  187. if header := dl.getHeader(dl.ownHashes[i]); header != nil {
  188. return header
  189. }
  190. }
  191. return genesis.Header()
  192. }
  193. // headBlock retrieves the current head block from the canonical chain.
  194. func (dl *downloadTester) headBlock() *types.Block {
  195. dl.lock.RLock()
  196. defer dl.lock.RUnlock()
  197. for i := len(dl.ownHashes) - 1; i >= 0; i-- {
  198. if block := dl.getBlock(dl.ownHashes[i]); block != nil {
  199. if _, err := dl.stateDb.Get(block.Root().Bytes()); err == nil {
  200. return block
  201. }
  202. }
  203. }
  204. return genesis
  205. }
  206. // headFastBlock retrieves the current head fast-sync block from the canonical chain.
  207. func (dl *downloadTester) headFastBlock() *types.Block {
  208. dl.lock.RLock()
  209. defer dl.lock.RUnlock()
  210. for i := len(dl.ownHashes) - 1; i >= 0; i-- {
  211. if block := dl.getBlock(dl.ownHashes[i]); block != nil {
  212. return block
  213. }
  214. }
  215. return genesis
  216. }
  217. // commitHeadBlock manually sets the head block to a given hash.
  218. func (dl *downloadTester) commitHeadBlock(hash common.Hash) error {
  219. // For now only check that the state trie is correct
  220. if block := dl.getBlock(hash); block != nil {
  221. _, err := trie.NewSecure(block.Root(), dl.stateDb)
  222. return err
  223. }
  224. return fmt.Errorf("non existent block: %x", hash[:4])
  225. }
  226. // getTd retrieves the block's total difficulty from the canonical chain.
  227. func (dl *downloadTester) getTd(hash common.Hash) *big.Int {
  228. dl.lock.RLock()
  229. defer dl.lock.RUnlock()
  230. return dl.ownChainTd[hash]
  231. }
  232. // insertHeaders injects a new batch of headers into the simulated chain.
  233. func (dl *downloadTester) insertHeaders(headers []*types.Header, checkFreq int) (int, error) {
  234. dl.lock.Lock()
  235. defer dl.lock.Unlock()
  236. for i, header := range headers {
  237. if _, ok := dl.ownHeaders[header.Hash()]; ok {
  238. continue
  239. }
  240. if _, ok := dl.ownHeaders[header.ParentHash]; !ok {
  241. return i, errors.New("unknown parent")
  242. }
  243. dl.ownHashes = append(dl.ownHashes, header.Hash())
  244. dl.ownHeaders[header.Hash()] = header
  245. dl.ownChainTd[header.Hash()] = dl.ownChainTd[header.ParentHash]
  246. }
  247. return len(headers), nil
  248. }
  249. // insertBlocks injects a new batch of blocks into the simulated chain.
  250. func (dl *downloadTester) insertBlocks(blocks types.Blocks) (int, error) {
  251. dl.lock.Lock()
  252. defer dl.lock.Unlock()
  253. for i, block := range blocks {
  254. if _, ok := dl.ownBlocks[block.ParentHash()]; !ok {
  255. return i, errors.New("unknown parent")
  256. }
  257. dl.ownHashes = append(dl.ownHashes, block.Hash())
  258. dl.ownHeaders[block.Hash()] = block.Header()
  259. dl.ownBlocks[block.Hash()] = block
  260. dl.stateDb.Put(block.Root().Bytes(), []byte{})
  261. dl.ownChainTd[block.Hash()] = dl.ownChainTd[block.ParentHash()]
  262. }
  263. return len(blocks), nil
  264. }
  265. // insertReceipts injects a new batch of blocks into the simulated chain.
  266. func (dl *downloadTester) insertReceipts(blocks types.Blocks, receipts []types.Receipts) (int, error) {
  267. dl.lock.Lock()
  268. defer dl.lock.Unlock()
  269. for i := 0; i < len(blocks) && i < len(receipts); i++ {
  270. if _, ok := dl.ownHeaders[blocks[i].Hash()]; !ok {
  271. return i, errors.New("unknown owner")
  272. }
  273. if _, ok := dl.ownBlocks[blocks[i].ParentHash()]; !ok {
  274. return i, errors.New("unknown parent")
  275. }
  276. dl.ownBlocks[blocks[i].Hash()] = blocks[i]
  277. dl.ownReceipts[blocks[i].Hash()] = receipts[i]
  278. }
  279. return len(blocks), nil
  280. }
  281. // newPeer registers a new block download source into the downloader.
  282. func (dl *downloadTester) newPeer(id string, version int, hashes []common.Hash, headers map[common.Hash]*types.Header, blocks map[common.Hash]*types.Block, receipts map[common.Hash]types.Receipts) error {
  283. return dl.newSlowPeer(id, version, hashes, headers, blocks, receipts, 0)
  284. }
  285. // newSlowPeer registers a new block download source into the downloader, with a
  286. // specific delay time on processing the network packets sent to it, simulating
  287. // potentially slow network IO.
  288. func (dl *downloadTester) newSlowPeer(id string, version int, hashes []common.Hash, headers map[common.Hash]*types.Header, blocks map[common.Hash]*types.Block, receipts map[common.Hash]types.Receipts, delay time.Duration) error {
  289. dl.lock.Lock()
  290. defer dl.lock.Unlock()
  291. var err error
  292. switch version {
  293. case 61:
  294. err = dl.downloader.RegisterPeer(id, version, hashes[0], dl.peerGetRelHashesFn(id, delay), dl.peerGetAbsHashesFn(id, delay), dl.peerGetBlocksFn(id, delay), nil, nil, nil, nil, nil)
  295. case 62:
  296. err = dl.downloader.RegisterPeer(id, version, hashes[0], nil, nil, nil, dl.peerGetRelHeadersFn(id, delay), dl.peerGetAbsHeadersFn(id, delay), dl.peerGetBodiesFn(id, delay), nil, nil)
  297. case 63:
  298. err = dl.downloader.RegisterPeer(id, version, hashes[0], nil, nil, nil, dl.peerGetRelHeadersFn(id, delay), dl.peerGetAbsHeadersFn(id, delay), dl.peerGetBodiesFn(id, delay), dl.peerGetReceiptsFn(id, delay), dl.peerGetNodeDataFn(id, delay))
  299. case 64:
  300. err = dl.downloader.RegisterPeer(id, version, hashes[0], nil, nil, nil, dl.peerGetRelHeadersFn(id, delay), dl.peerGetAbsHeadersFn(id, delay), dl.peerGetBodiesFn(id, delay), dl.peerGetReceiptsFn(id, delay), dl.peerGetNodeDataFn(id, delay))
  301. }
  302. if err == nil {
  303. // Assign the owned hashes, headers and blocks to the peer (deep copy)
  304. dl.peerHashes[id] = make([]common.Hash, len(hashes))
  305. copy(dl.peerHashes[id], hashes)
  306. dl.peerHeaders[id] = make(map[common.Hash]*types.Header)
  307. dl.peerBlocks[id] = make(map[common.Hash]*types.Block)
  308. dl.peerReceipts[id] = make(map[common.Hash]types.Receipts)
  309. dl.peerChainTds[id] = make(map[common.Hash]*big.Int)
  310. for _, hash := range hashes {
  311. if header, ok := headers[hash]; ok {
  312. dl.peerHeaders[id][hash] = header
  313. if _, ok := dl.peerHeaders[id][header.ParentHash]; ok {
  314. dl.peerChainTds[id][hash] = new(big.Int).Add(header.Difficulty, dl.peerChainTds[id][header.ParentHash])
  315. }
  316. }
  317. if block, ok := blocks[hash]; ok {
  318. dl.peerBlocks[id][hash] = block
  319. if _, ok := dl.peerBlocks[id][block.ParentHash()]; ok {
  320. dl.peerChainTds[id][hash] = new(big.Int).Add(block.Difficulty(), dl.peerChainTds[id][block.ParentHash()])
  321. }
  322. }
  323. if receipt, ok := receipts[hash]; ok {
  324. dl.peerReceipts[id][hash] = receipt
  325. }
  326. }
  327. }
  328. return err
  329. }
  330. // dropPeer simulates a hard peer removal from the connection pool.
  331. func (dl *downloadTester) dropPeer(id string) {
  332. dl.lock.Lock()
  333. defer dl.lock.Unlock()
  334. delete(dl.peerHashes, id)
  335. delete(dl.peerHeaders, id)
  336. delete(dl.peerBlocks, id)
  337. delete(dl.peerChainTds, id)
  338. dl.downloader.UnregisterPeer(id)
  339. }
  340. // peerGetRelHashesFn constructs a GetHashes function associated with a specific
  341. // peer in the download tester. The returned function can be used to retrieve
  342. // batches of hashes from the particularly requested peer.
  343. func (dl *downloadTester) peerGetRelHashesFn(id string, delay time.Duration) func(head common.Hash) error {
  344. return func(head common.Hash) error {
  345. time.Sleep(delay)
  346. dl.lock.RLock()
  347. defer dl.lock.RUnlock()
  348. // Gather the next batch of hashes
  349. hashes := dl.peerHashes[id]
  350. result := make([]common.Hash, 0, MaxHashFetch)
  351. for i, hash := range hashes {
  352. if hash == head {
  353. i++
  354. for len(result) < cap(result) && i < len(hashes) {
  355. result = append(result, hashes[i])
  356. i++
  357. }
  358. break
  359. }
  360. }
  361. // Delay delivery a bit to allow attacks to unfold
  362. go func() {
  363. time.Sleep(time.Millisecond)
  364. dl.downloader.DeliverHashes(id, result)
  365. }()
  366. return nil
  367. }
  368. }
  369. // peerGetAbsHashesFn constructs a GetHashesFromNumber function associated with
  370. // a particular peer in the download tester. The returned function can be used to
  371. // retrieve batches of hashes from the particularly requested peer.
  372. func (dl *downloadTester) peerGetAbsHashesFn(id string, delay time.Duration) func(uint64, int) error {
  373. return func(head uint64, count int) error {
  374. time.Sleep(delay)
  375. dl.lock.RLock()
  376. defer dl.lock.RUnlock()
  377. // Gather the next batch of hashes
  378. hashes := dl.peerHashes[id]
  379. result := make([]common.Hash, 0, count)
  380. for i := 0; i < count && len(hashes)-int(head)-1-i >= 0; i++ {
  381. result = append(result, hashes[len(hashes)-int(head)-1-i])
  382. }
  383. // Delay delivery a bit to allow attacks to unfold
  384. go func() {
  385. time.Sleep(time.Millisecond)
  386. dl.downloader.DeliverHashes(id, result)
  387. }()
  388. return nil
  389. }
  390. }
  391. // peerGetBlocksFn constructs a getBlocks function associated with a particular
  392. // peer in the download tester. The returned function can be used to retrieve
  393. // batches of blocks from the particularly requested peer.
  394. func (dl *downloadTester) peerGetBlocksFn(id string, delay time.Duration) func([]common.Hash) error {
  395. return func(hashes []common.Hash) error {
  396. time.Sleep(delay)
  397. dl.lock.RLock()
  398. defer dl.lock.RUnlock()
  399. blocks := dl.peerBlocks[id]
  400. result := make([]*types.Block, 0, len(hashes))
  401. for _, hash := range hashes {
  402. if block, ok := blocks[hash]; ok {
  403. result = append(result, block)
  404. }
  405. }
  406. go dl.downloader.DeliverBlocks(id, result)
  407. return nil
  408. }
  409. }
  410. // peerGetRelHeadersFn constructs a GetBlockHeaders function based on a hashed
  411. // origin; associated with a particular peer in the download tester. The returned
  412. // function can be used to retrieve batches of headers from the particular peer.
  413. func (dl *downloadTester) peerGetRelHeadersFn(id string, delay time.Duration) func(common.Hash, int, int, bool) error {
  414. return func(origin common.Hash, amount int, skip int, reverse bool) error {
  415. // Find the canonical number of the hash
  416. dl.lock.RLock()
  417. number := uint64(0)
  418. for num, hash := range dl.peerHashes[id] {
  419. if hash == origin {
  420. number = uint64(len(dl.peerHashes[id]) - num - 1)
  421. break
  422. }
  423. }
  424. dl.lock.RUnlock()
  425. // Use the absolute header fetcher to satisfy the query
  426. return dl.peerGetAbsHeadersFn(id, delay)(number, amount, skip, reverse)
  427. }
  428. }
  429. // peerGetAbsHeadersFn constructs a GetBlockHeaders function based on a numbered
  430. // origin; associated with a particular peer in the download tester. The returned
  431. // function can be used to retrieve batches of headers from the particular peer.
  432. func (dl *downloadTester) peerGetAbsHeadersFn(id string, delay time.Duration) func(uint64, int, int, bool) error {
  433. return func(origin uint64, amount int, skip int, reverse bool) error {
  434. time.Sleep(delay)
  435. dl.lock.RLock()
  436. defer dl.lock.RUnlock()
  437. // Gather the next batch of headers
  438. hashes := dl.peerHashes[id]
  439. headers := dl.peerHeaders[id]
  440. result := make([]*types.Header, 0, amount)
  441. for i := 0; i < amount && len(hashes)-int(origin)-1-i >= 0; i++ {
  442. if header, ok := headers[hashes[len(hashes)-int(origin)-1-i]]; ok {
  443. result = append(result, header)
  444. }
  445. }
  446. // Delay delivery a bit to allow attacks to unfold
  447. go func() {
  448. time.Sleep(time.Millisecond)
  449. dl.downloader.DeliverHeaders(id, result)
  450. }()
  451. return nil
  452. }
  453. }
  454. // peerGetBodiesFn constructs a getBlockBodies method associated with a particular
  455. // peer in the download tester. The returned function can be used to retrieve
  456. // batches of block bodies from the particularly requested peer.
  457. func (dl *downloadTester) peerGetBodiesFn(id string, delay time.Duration) func([]common.Hash) error {
  458. return func(hashes []common.Hash) error {
  459. time.Sleep(delay)
  460. dl.lock.RLock()
  461. defer dl.lock.RUnlock()
  462. blocks := dl.peerBlocks[id]
  463. transactions := make([][]*types.Transaction, 0, len(hashes))
  464. uncles := make([][]*types.Header, 0, len(hashes))
  465. for _, hash := range hashes {
  466. if block, ok := blocks[hash]; ok {
  467. transactions = append(transactions, block.Transactions())
  468. uncles = append(uncles, block.Uncles())
  469. }
  470. }
  471. go dl.downloader.DeliverBodies(id, transactions, uncles)
  472. return nil
  473. }
  474. }
  475. // peerGetReceiptsFn constructs a getReceipts method associated with a particular
  476. // peer in the download tester. The returned function can be used to retrieve
  477. // batches of block receipts from the particularly requested peer.
  478. func (dl *downloadTester) peerGetReceiptsFn(id string, delay time.Duration) func([]common.Hash) error {
  479. return func(hashes []common.Hash) error {
  480. time.Sleep(delay)
  481. dl.lock.RLock()
  482. defer dl.lock.RUnlock()
  483. receipts := dl.peerReceipts[id]
  484. results := make([][]*types.Receipt, 0, len(hashes))
  485. for _, hash := range hashes {
  486. if receipt, ok := receipts[hash]; ok {
  487. results = append(results, receipt)
  488. }
  489. }
  490. go dl.downloader.DeliverReceipts(id, results)
  491. return nil
  492. }
  493. }
  494. // peerGetNodeDataFn constructs a getNodeData method associated with a particular
  495. // peer in the download tester. The returned function can be used to retrieve
  496. // batches of node state data from the particularly requested peer.
  497. func (dl *downloadTester) peerGetNodeDataFn(id string, delay time.Duration) func([]common.Hash) error {
  498. return func(hashes []common.Hash) error {
  499. time.Sleep(delay)
  500. dl.lock.RLock()
  501. defer dl.lock.RUnlock()
  502. results := make([][]byte, 0, len(hashes))
  503. for _, hash := range hashes {
  504. if data, err := testdb.Get(hash.Bytes()); err == nil {
  505. results = append(results, data)
  506. }
  507. }
  508. go dl.downloader.DeliverNodeData(id, results)
  509. return nil
  510. }
  511. }
  512. // assertOwnChain checks if the local chain contains the correct number of items
  513. // of the various chain components.
  514. func assertOwnChain(t *testing.T, tester *downloadTester, length int) {
  515. assertOwnForkedChain(t, tester, 1, []int{length})
  516. }
  517. // assertOwnForkedChain checks if the local forked chain contains the correct
  518. // number of items of the various chain components.
  519. func assertOwnForkedChain(t *testing.T, tester *downloadTester, common int, lengths []int) {
  520. // Initialize the counters for the first fork
  521. headers, blocks, receipts := lengths[0], lengths[0], lengths[0]-minFullBlocks
  522. if receipts < 0 {
  523. receipts = 1
  524. }
  525. // Update the counters for each subsequent fork
  526. for _, length := range lengths[1:] {
  527. headers += length - common
  528. blocks += length - common
  529. receipts += length - common - minFullBlocks
  530. }
  531. switch tester.downloader.mode {
  532. case FullSync:
  533. receipts = 1
  534. case LightSync:
  535. blocks, receipts = 1, 1
  536. }
  537. if hs := len(tester.ownHeaders); hs != headers {
  538. t.Fatalf("synchronised headers mismatch: have %v, want %v", hs, headers)
  539. }
  540. if bs := len(tester.ownBlocks); bs != blocks {
  541. t.Fatalf("synchronised blocks mismatch: have %v, want %v", bs, blocks)
  542. }
  543. if rs := len(tester.ownReceipts); rs != receipts {
  544. t.Fatalf("synchronised receipts mismatch: have %v, want %v", rs, receipts)
  545. }
  546. // Verify the state trie too for fast syncs
  547. if tester.downloader.mode == FastSync {
  548. if index := lengths[len(lengths)-1] - minFullBlocks - 1; index > 0 {
  549. if statedb := state.New(tester.ownHeaders[tester.ownHashes[index]].Root, tester.stateDb); statedb == nil {
  550. t.Fatalf("state reconstruction failed")
  551. }
  552. }
  553. }
  554. }
  555. // Tests that simple synchronization against a canonical chain works correctly.
  556. // In this test common ancestor lookup should be short circuited and not require
  557. // binary searching.
  558. func TestCanonicalSynchronisation61(t *testing.T) { testCanonicalSynchronisation(t, 61, FullSync) }
  559. func TestCanonicalSynchronisation62(t *testing.T) { testCanonicalSynchronisation(t, 62, FullSync) }
  560. func TestCanonicalSynchronisation63Full(t *testing.T) { testCanonicalSynchronisation(t, 63, FullSync) }
  561. func TestCanonicalSynchronisation63Fast(t *testing.T) { testCanonicalSynchronisation(t, 63, FastSync) }
  562. func TestCanonicalSynchronisation64Full(t *testing.T) { testCanonicalSynchronisation(t, 64, FullSync) }
  563. func TestCanonicalSynchronisation64Fast(t *testing.T) { testCanonicalSynchronisation(t, 64, FastSync) }
  564. func TestCanonicalSynchronisation64Light(t *testing.T) { testCanonicalSynchronisation(t, 64, LightSync) }
  565. func testCanonicalSynchronisation(t *testing.T, protocol int, mode SyncMode) {
  566. // Create a small enough block chain to download
  567. targetBlocks := blockCacheLimit - 15
  568. hashes, headers, blocks, receipts := makeChain(targetBlocks, 0, genesis, nil)
  569. tester := newTester(mode)
  570. tester.newPeer("peer", protocol, hashes, headers, blocks, receipts)
  571. // Synchronise with the peer and make sure all relevant data was retrieved
  572. if err := tester.sync("peer", nil); err != nil {
  573. t.Fatalf("failed to synchronise blocks: %v", err)
  574. }
  575. assertOwnChain(t, tester, targetBlocks+1)
  576. }
  577. // Tests that if a large batch of blocks are being downloaded, it is throttled
  578. // until the cached blocks are retrieved.
  579. func TestThrottling61(t *testing.T) { testThrottling(t, 61, FullSync) }
  580. func TestThrottling62(t *testing.T) { testThrottling(t, 62, FullSync) }
  581. func TestThrottling63Full(t *testing.T) { testThrottling(t, 63, FullSync) }
  582. func TestThrottling63Fast(t *testing.T) { testThrottling(t, 63, FastSync) }
  583. func TestThrottling64Full(t *testing.T) { testThrottling(t, 64, FullSync) }
  584. func TestThrottling64Fast(t *testing.T) { testThrottling(t, 64, FastSync) }
  585. func testThrottling(t *testing.T, protocol int, mode SyncMode) {
  586. // Create a long block chain to download and the tester
  587. targetBlocks := 8 * blockCacheLimit
  588. hashes, headers, blocks, receipts := makeChain(targetBlocks, 0, genesis, nil)
  589. tester := newTester(mode)
  590. tester.newPeer("peer", protocol, hashes, headers, blocks, receipts)
  591. // Wrap the importer to allow stepping
  592. blocked, proceed := uint32(0), make(chan struct{})
  593. tester.downloader.chainInsertHook = func(results []*fetchResult) {
  594. atomic.StoreUint32(&blocked, uint32(len(results)))
  595. <-proceed
  596. }
  597. // Start a synchronisation concurrently
  598. errc := make(chan error)
  599. go func() {
  600. errc <- tester.sync("peer", nil)
  601. }()
  602. // Iteratively take some blocks, always checking the retrieval count
  603. for {
  604. // Check the retrieval count synchronously (! reason for this ugly block)
  605. tester.lock.RLock()
  606. retrieved := len(tester.ownBlocks)
  607. tester.lock.RUnlock()
  608. if retrieved >= targetBlocks+1 {
  609. break
  610. }
  611. // Wait a bit for sync to throttle itself
  612. var cached int
  613. for start := time.Now(); time.Since(start) < time.Second; {
  614. time.Sleep(25 * time.Millisecond)
  615. tester.downloader.queue.lock.RLock()
  616. cached = len(tester.downloader.queue.blockDonePool)
  617. if mode == FastSync {
  618. if receipts := len(tester.downloader.queue.receiptDonePool); receipts < cached {
  619. if tester.downloader.queue.resultCache[receipts].Header.Number.Uint64() < tester.downloader.queue.fastSyncPivot {
  620. cached = receipts
  621. }
  622. }
  623. }
  624. tester.downloader.queue.lock.RUnlock()
  625. if cached == blockCacheLimit || len(tester.ownBlocks)+cached+int(atomic.LoadUint32(&blocked)) == targetBlocks+1 {
  626. break
  627. }
  628. }
  629. // Make sure we filled up the cache, then exhaust it
  630. time.Sleep(25 * time.Millisecond) // give it a chance to screw up
  631. if cached != blockCacheLimit && len(tester.ownBlocks)+cached+int(atomic.LoadUint32(&blocked)) != targetBlocks+1 {
  632. t.Fatalf("block count mismatch: have %v, want %v (owned %v, target %v)", cached, blockCacheLimit, len(tester.ownBlocks), targetBlocks+1)
  633. }
  634. // Permit the blocked blocks to import
  635. if atomic.LoadUint32(&blocked) > 0 {
  636. atomic.StoreUint32(&blocked, uint32(0))
  637. proceed <- struct{}{}
  638. }
  639. }
  640. // Check that we haven't pulled more blocks than available
  641. assertOwnChain(t, tester, targetBlocks+1)
  642. if err := <-errc; err != nil {
  643. t.Fatalf("block synchronization failed: %v", err)
  644. }
  645. }
  646. // Tests that simple synchronization against a forked chain works correctly. In
  647. // this test common ancestor lookup should *not* be short circuited, and a full
  648. // binary search should be executed.
  649. func TestForkedSynchronisation61(t *testing.T) { testForkedSynchronisation(t, 61, FullSync) }
  650. func TestForkedSynchronisation62(t *testing.T) { testForkedSynchronisation(t, 62, FullSync) }
  651. func TestForkedSynchronisation63Full(t *testing.T) { testForkedSynchronisation(t, 63, FullSync) }
  652. func TestForkedSynchronisation63Fast(t *testing.T) { testForkedSynchronisation(t, 63, FastSync) }
  653. func TestForkedSynchronisation64Full(t *testing.T) { testForkedSynchronisation(t, 64, FullSync) }
  654. func TestForkedSynchronisation64Fast(t *testing.T) { testForkedSynchronisation(t, 64, FastSync) }
  655. func TestForkedSynchronisation64Light(t *testing.T) { testForkedSynchronisation(t, 64, LightSync) }
  656. func testForkedSynchronisation(t *testing.T, protocol int, mode SyncMode) {
  657. // Create a long enough forked chain
  658. common, fork := MaxHashFetch, 2*MaxHashFetch
  659. hashesA, hashesB, headersA, headersB, blocksA, blocksB, receiptsA, receiptsB := makeChainFork(common+fork, fork, genesis, nil)
  660. tester := newTester(mode)
  661. tester.newPeer("fork A", protocol, hashesA, headersA, blocksA, receiptsA)
  662. tester.newPeer("fork B", protocol, hashesB, headersB, blocksB, receiptsB)
  663. // Synchronise with the peer and make sure all blocks were retrieved
  664. if err := tester.sync("fork A", nil); err != nil {
  665. t.Fatalf("failed to synchronise blocks: %v", err)
  666. }
  667. assertOwnChain(t, tester, common+fork+1)
  668. // Synchronise with the second peer and make sure that fork is pulled too
  669. if err := tester.sync("fork B", nil); err != nil {
  670. t.Fatalf("failed to synchronise blocks: %v", err)
  671. }
  672. assertOwnForkedChain(t, tester, common+1, []int{common + fork + 1, common + fork + 1})
  673. }
  674. // Tests that an inactive downloader will not accept incoming hashes and blocks.
  675. func TestInactiveDownloader61(t *testing.T) {
  676. tester := newTester(FullSync)
  677. // Check that neither hashes nor blocks are accepted
  678. if err := tester.downloader.DeliverHashes("bad peer", []common.Hash{}); err != errNoSyncActive {
  679. t.Errorf("error mismatch: have %v, want %v", err, errNoSyncActive)
  680. }
  681. if err := tester.downloader.DeliverBlocks("bad peer", []*types.Block{}); err != errNoSyncActive {
  682. t.Errorf("error mismatch: have %v, want %v", err, errNoSyncActive)
  683. }
  684. }
  685. // Tests that an inactive downloader will not accept incoming block headers and
  686. // bodies.
  687. func TestInactiveDownloader62(t *testing.T) {
  688. tester := newTester(FullSync)
  689. // Check that neither block headers nor bodies are accepted
  690. if err := tester.downloader.DeliverHeaders("bad peer", []*types.Header{}); err != errNoSyncActive {
  691. t.Errorf("error mismatch: have %v, want %v", err, errNoSyncActive)
  692. }
  693. if err := tester.downloader.DeliverBodies("bad peer", [][]*types.Transaction{}, [][]*types.Header{}); err != errNoSyncActive {
  694. t.Errorf("error mismatch: have %v, want %v", err, errNoSyncActive)
  695. }
  696. }
  697. // Tests that an inactive downloader will not accept incoming block headers,
  698. // bodies and receipts.
  699. func TestInactiveDownloader63(t *testing.T) {
  700. tester := newTester(FullSync)
  701. // Check that neither block headers nor bodies are accepted
  702. if err := tester.downloader.DeliverHeaders("bad peer", []*types.Header{}); err != errNoSyncActive {
  703. t.Errorf("error mismatch: have %v, want %v", err, errNoSyncActive)
  704. }
  705. if err := tester.downloader.DeliverBodies("bad peer", [][]*types.Transaction{}, [][]*types.Header{}); err != errNoSyncActive {
  706. t.Errorf("error mismatch: have %v, want %v", err, errNoSyncActive)
  707. }
  708. if err := tester.downloader.DeliverReceipts("bad peer", [][]*types.Receipt{}); err != errNoSyncActive {
  709. t.Errorf("error mismatch: have %v, want %v", err, errNoSyncActive)
  710. }
  711. }
  712. // Tests that a canceled download wipes all previously accumulated state.
  713. func TestCancel61(t *testing.T) { testCancel(t, 61, FullSync) }
  714. func TestCancel62(t *testing.T) { testCancel(t, 62, FullSync) }
  715. func TestCancel63Full(t *testing.T) { testCancel(t, 63, FullSync) }
  716. func TestCancel63Fast(t *testing.T) { testCancel(t, 63, FastSync) }
  717. func TestCancel64Full(t *testing.T) { testCancel(t, 64, FullSync) }
  718. func TestCancel64Fast(t *testing.T) { testCancel(t, 64, FastSync) }
  719. func TestCancel64Light(t *testing.T) { testCancel(t, 64, LightSync) }
  720. func testCancel(t *testing.T, protocol int, mode SyncMode) {
  721. // Create a small enough block chain to download and the tester
  722. targetBlocks := blockCacheLimit - 15
  723. if targetBlocks >= MaxHashFetch {
  724. targetBlocks = MaxHashFetch - 15
  725. }
  726. if targetBlocks >= MaxHeaderFetch {
  727. targetBlocks = MaxHeaderFetch - 15
  728. }
  729. hashes, headers, blocks, receipts := makeChain(targetBlocks, 0, genesis, nil)
  730. tester := newTester(mode)
  731. tester.newPeer("peer", protocol, hashes, headers, blocks, receipts)
  732. // Make sure canceling works with a pristine downloader
  733. tester.downloader.cancel()
  734. if !tester.downloader.queue.Idle() {
  735. t.Errorf("download queue not idle")
  736. }
  737. // Synchronise with the peer, but cancel afterwards
  738. if err := tester.sync("peer", nil); err != nil {
  739. t.Fatalf("failed to synchronise blocks: %v", err)
  740. }
  741. tester.downloader.cancel()
  742. if !tester.downloader.queue.Idle() {
  743. t.Errorf("download queue not idle")
  744. }
  745. }
  746. // Tests that synchronisation from multiple peers works as intended (multi thread sanity test).
  747. func TestMultiSynchronisation61(t *testing.T) { testMultiSynchronisation(t, 61, FullSync) }
  748. func TestMultiSynchronisation62(t *testing.T) { testMultiSynchronisation(t, 62, FullSync) }
  749. func TestMultiSynchronisation63Full(t *testing.T) { testMultiSynchronisation(t, 63, FullSync) }
  750. func TestMultiSynchronisation63Fast(t *testing.T) { testMultiSynchronisation(t, 63, FastSync) }
  751. func TestMultiSynchronisation64Full(t *testing.T) { testMultiSynchronisation(t, 64, FullSync) }
  752. func TestMultiSynchronisation64Fast(t *testing.T) { testMultiSynchronisation(t, 64, FastSync) }
  753. func TestMultiSynchronisation64Light(t *testing.T) { testMultiSynchronisation(t, 64, LightSync) }
  754. func testMultiSynchronisation(t *testing.T, protocol int, mode SyncMode) {
  755. // Create various peers with various parts of the chain
  756. targetPeers := 8
  757. targetBlocks := targetPeers*blockCacheLimit - 15
  758. hashes, headers, blocks, receipts := makeChain(targetBlocks, 0, genesis, nil)
  759. tester := newTester(mode)
  760. for i := 0; i < targetPeers; i++ {
  761. id := fmt.Sprintf("peer #%d", i)
  762. tester.newPeer(id, protocol, hashes[i*blockCacheLimit:], headers, blocks, receipts)
  763. }
  764. if err := tester.sync("peer #0", nil); err != nil {
  765. t.Fatalf("failed to synchronise blocks: %v", err)
  766. }
  767. assertOwnChain(t, tester, targetBlocks+1)
  768. }
  769. // Tests that synchronisations behave well in multi-version protocol environments
  770. // and not wreak havok on other nodes in the network.
  771. func TestMultiProtoSynchronisation61(t *testing.T) { testMultiProtoSync(t, 61, FullSync) }
  772. func TestMultiProtoSynchronisation62(t *testing.T) { testMultiProtoSync(t, 62, FullSync) }
  773. func TestMultiProtoSynchronisation63Full(t *testing.T) { testMultiProtoSync(t, 63, FullSync) }
  774. func TestMultiProtoSynchronisation63Fast(t *testing.T) { testMultiProtoSync(t, 63, FastSync) }
  775. func TestMultiProtoSynchronisation64Full(t *testing.T) { testMultiProtoSync(t, 64, FullSync) }
  776. func TestMultiProtoSynchronisation64Fast(t *testing.T) { testMultiProtoSync(t, 64, FastSync) }
  777. func TestMultiProtoSynchronisation64Light(t *testing.T) { testMultiProtoSync(t, 64, LightSync) }
  778. func testMultiProtoSync(t *testing.T, protocol int, mode SyncMode) {
  779. // Create a small enough block chain to download
  780. targetBlocks := blockCacheLimit - 15
  781. hashes, headers, blocks, receipts := makeChain(targetBlocks, 0, genesis, nil)
  782. // Create peers of every type
  783. tester := newTester(mode)
  784. tester.newPeer("peer 61", 61, hashes, headers, blocks, receipts)
  785. tester.newPeer("peer 62", 62, hashes, headers, blocks, receipts)
  786. tester.newPeer("peer 63", 63, hashes, headers, blocks, receipts)
  787. tester.newPeer("peer 64", 64, hashes, headers, blocks, receipts)
  788. // Synchronise with the requestd peer and make sure all blocks were retrieved
  789. if err := tester.sync(fmt.Sprintf("peer %d", protocol), nil); err != nil {
  790. t.Fatalf("failed to synchronise blocks: %v", err)
  791. }
  792. assertOwnChain(t, tester, targetBlocks+1)
  793. // Check that no peers have been dropped off
  794. for _, version := range []int{61, 62, 63, 64} {
  795. peer := fmt.Sprintf("peer %d", version)
  796. if _, ok := tester.peerHashes[peer]; !ok {
  797. t.Errorf("%s dropped", peer)
  798. }
  799. }
  800. }
  801. // Tests that if a block is empty (e.g. header only), no body request should be
  802. // made, and instead the header should be assembled into a whole block in itself.
  803. func TestEmptyShortCircuit62(t *testing.T) { testEmptyShortCircuit(t, 62, FullSync) }
  804. func TestEmptyShortCircuit63Full(t *testing.T) { testEmptyShortCircuit(t, 63, FullSync) }
  805. func TestEmptyShortCircuit63Fast(t *testing.T) { testEmptyShortCircuit(t, 63, FastSync) }
  806. func TestEmptyShortCircuit64Full(t *testing.T) { testEmptyShortCircuit(t, 64, FullSync) }
  807. func TestEmptyShortCircuit64Fast(t *testing.T) { testEmptyShortCircuit(t, 64, FastSync) }
  808. func TestEmptyShortCircuit64Light(t *testing.T) { testEmptyShortCircuit(t, 64, LightSync) }
  809. func testEmptyShortCircuit(t *testing.T, protocol int, mode SyncMode) {
  810. // Create a block chain to download
  811. targetBlocks := 2*blockCacheLimit - 15
  812. hashes, headers, blocks, receipts := makeChain(targetBlocks, 0, genesis, nil)
  813. tester := newTester(mode)
  814. tester.newPeer("peer", protocol, hashes, headers, blocks, receipts)
  815. // Instrument the downloader to signal body requests
  816. bodiesHave, receiptsHave := int32(0), int32(0)
  817. tester.downloader.bodyFetchHook = func(headers []*types.Header) {
  818. atomic.AddInt32(&bodiesHave, int32(len(headers)))
  819. }
  820. tester.downloader.receiptFetchHook = func(headers []*types.Header) {
  821. atomic.AddInt32(&receiptsHave, int32(len(headers)))
  822. }
  823. // Synchronise with the peer and make sure all blocks were retrieved
  824. if err := tester.sync("peer", nil); err != nil {
  825. t.Fatalf("failed to synchronise blocks: %v", err)
  826. }
  827. assertOwnChain(t, tester, targetBlocks+1)
  828. // Validate the number of block bodies that should have been requested
  829. bodiesNeeded, receiptsNeeded := 0, 0
  830. for _, block := range blocks {
  831. if mode != LightSync && block != genesis && (len(block.Transactions()) > 0 || len(block.Uncles()) > 0) {
  832. bodiesNeeded++
  833. }
  834. }
  835. for hash, receipt := range receipts {
  836. if mode == FastSync && len(receipt) > 0 && headers[hash].Number.Uint64() <= uint64(targetBlocks-minFullBlocks) {
  837. receiptsNeeded++
  838. }
  839. }
  840. if int(bodiesHave) != bodiesNeeded {
  841. t.Errorf("body retrieval count mismatch: have %v, want %v", bodiesHave, bodiesNeeded)
  842. }
  843. if int(receiptsHave) != receiptsNeeded {
  844. t.Errorf("receipt retrieval count mismatch: have %v, want %v", receiptsHave, receiptsNeeded)
  845. }
  846. }
  847. // Tests that headers are enqueued continuously, preventing malicious nodes from
  848. // stalling the downloader by feeding gapped header chains.
  849. func TestMissingHeaderAttack62(t *testing.T) { testMissingHeaderAttack(t, 62, FullSync) }
  850. func TestMissingHeaderAttack63Full(t *testing.T) { testMissingHeaderAttack(t, 63, FullSync) }
  851. func TestMissingHeaderAttack63Fast(t *testing.T) { testMissingHeaderAttack(t, 63, FastSync) }
  852. func TestMissingHeaderAttack64Full(t *testing.T) { testMissingHeaderAttack(t, 64, FullSync) }
  853. func TestMissingHeaderAttack64Fast(t *testing.T) { testMissingHeaderAttack(t, 64, FastSync) }
  854. func TestMissingHeaderAttack64Light(t *testing.T) { testMissingHeaderAttack(t, 64, LightSync) }
  855. func testMissingHeaderAttack(t *testing.T, protocol int, mode SyncMode) {
  856. // Create a small enough block chain to download
  857. targetBlocks := blockCacheLimit - 15
  858. hashes, headers, blocks, receipts := makeChain(targetBlocks, 0, genesis, nil)
  859. tester := newTester(mode)
  860. // Attempt a full sync with an attacker feeding gapped headers
  861. tester.newPeer("attack", protocol, hashes, headers, blocks, receipts)
  862. missing := targetBlocks / 2
  863. delete(tester.peerHeaders["attack"], hashes[missing])
  864. if err := tester.sync("attack", nil); err == nil {
  865. t.Fatalf("succeeded attacker synchronisation")
  866. }
  867. // Synchronise with the valid peer and make sure sync succeeds
  868. tester.newPeer("valid", protocol, hashes, headers, blocks, receipts)
  869. if err := tester.sync("valid", nil); err != nil {
  870. t.Fatalf("failed to synchronise blocks: %v", err)
  871. }
  872. assertOwnChain(t, tester, targetBlocks+1)
  873. }
  874. // Tests that if requested headers are shifted (i.e. first is missing), the queue
  875. // detects the invalid numbering.
  876. func TestShiftedHeaderAttack62(t *testing.T) { testShiftedHeaderAttack(t, 62, FullSync) }
  877. func TestShiftedHeaderAttack63Full(t *testing.T) { testShiftedHeaderAttack(t, 63, FullSync) }
  878. func TestShiftedHeaderAttack63Fast(t *testing.T) { testShiftedHeaderAttack(t, 63, FastSync) }
  879. func TestShiftedHeaderAttack64Full(t *testing.T) { testShiftedHeaderAttack(t, 64, FullSync) }
  880. func TestShiftedHeaderAttack64Fast(t *testing.T) { testShiftedHeaderAttack(t, 64, FastSync) }
  881. func TestShiftedHeaderAttack64Light(t *testing.T) { testShiftedHeaderAttack(t, 64, LightSync) }
  882. func testShiftedHeaderAttack(t *testing.T, protocol int, mode SyncMode) {
  883. // Create a small enough block chain to download
  884. targetBlocks := blockCacheLimit - 15
  885. hashes, headers, blocks, receipts := makeChain(targetBlocks, 0, genesis, nil)
  886. tester := newTester(mode)
  887. // Attempt a full sync with an attacker feeding shifted headers
  888. tester.newPeer("attack", protocol, hashes, headers, blocks, receipts)
  889. delete(tester.peerHeaders["attack"], hashes[len(hashes)-2])
  890. delete(tester.peerBlocks["attack"], hashes[len(hashes)-2])
  891. delete(tester.peerReceipts["attack"], hashes[len(hashes)-2])
  892. if err := tester.sync("attack", nil); err == nil {
  893. t.Fatalf("succeeded attacker synchronisation")
  894. }
  895. // Synchronise with the valid peer and make sure sync succeeds
  896. tester.newPeer("valid", protocol, hashes, headers, blocks, receipts)
  897. if err := tester.sync("valid", nil); err != nil {
  898. t.Fatalf("failed to synchronise blocks: %v", err)
  899. }
  900. assertOwnChain(t, tester, targetBlocks+1)
  901. }
  902. // Tests that if a peer sends an invalid block piece (body or receipt) for a
  903. // requested block, it gets dropped immediately by the downloader.
  904. func TestInvalidContentAttack62(t *testing.T) { testInvalidContentAttack(t, 62, FullSync) }
  905. func TestInvalidContentAttack63Full(t *testing.T) { testInvalidContentAttack(t, 63, FullSync) }
  906. func TestInvalidContentAttack63Fast(t *testing.T) { testInvalidContentAttack(t, 63, FastSync) }
  907. func TestInvalidContentAttack64Full(t *testing.T) { testInvalidContentAttack(t, 64, FullSync) }
  908. func TestInvalidContentAttack64Fast(t *testing.T) { testInvalidContentAttack(t, 64, FastSync) }
  909. func TestInvalidContentAttack64Light(t *testing.T) { testInvalidContentAttack(t, 64, LightSync) }
  910. func testInvalidContentAttack(t *testing.T, protocol int, mode SyncMode) {
  911. // Create two peers, one feeding invalid block bodies
  912. targetBlocks := 4*blockCacheLimit - 15
  913. hashes, headers, validBlocks, validReceipts := makeChain(targetBlocks, 0, genesis, nil)
  914. invalidBlocks := make(map[common.Hash]*types.Block)
  915. for hash, block := range validBlocks {
  916. invalidBlocks[hash] = types.NewBlockWithHeader(block.Header())
  917. }
  918. invalidReceipts := make(map[common.Hash]types.Receipts)
  919. for hash, _ := range validReceipts {
  920. invalidReceipts[hash] = types.Receipts{&types.Receipt{}}
  921. }
  922. tester := newTester(mode)
  923. tester.newPeer("valid", protocol, hashes, headers, validBlocks, validReceipts)
  924. if mode != LightSync {
  925. tester.newPeer("body attack", protocol, hashes, headers, invalidBlocks, validReceipts)
  926. }
  927. if mode == FastSync {
  928. tester.newPeer("receipt attack", protocol, hashes, headers, validBlocks, invalidReceipts)
  929. }
  930. // Synchronise with the valid peer (will pull contents from the attacker too)
  931. if err := tester.sync("valid", nil); err != nil {
  932. t.Fatalf("failed to synchronise blocks: %v", err)
  933. }
  934. assertOwnChain(t, tester, targetBlocks+1)
  935. // Make sure the attacker was detected and dropped in the mean time
  936. if _, ok := tester.peerHashes["body attack"]; ok {
  937. t.Fatalf("block body attacker not detected/dropped")
  938. }
  939. if _, ok := tester.peerHashes["receipt attack"]; ok {
  940. t.Fatalf("receipt attacker not detected/dropped")
  941. }
  942. }
  943. // Tests that a peer advertising an high TD doesn't get to stall the downloader
  944. // afterwards by not sending any useful hashes.
  945. func TestHighTDStarvationAttack61(t *testing.T) { testHighTDStarvationAttack(t, 61, FullSync) }
  946. func TestHighTDStarvationAttack62(t *testing.T) { testHighTDStarvationAttack(t, 62, FullSync) }
  947. func TestHighTDStarvationAttack63Full(t *testing.T) { testHighTDStarvationAttack(t, 63, FullSync) }
  948. func TestHighTDStarvationAttack63Fast(t *testing.T) { testHighTDStarvationAttack(t, 63, FastSync) }
  949. func TestHighTDStarvationAttack64Full(t *testing.T) { testHighTDStarvationAttack(t, 64, FullSync) }
  950. func TestHighTDStarvationAttack64Fast(t *testing.T) { testHighTDStarvationAttack(t, 64, FastSync) }
  951. func TestHighTDStarvationAttack64Light(t *testing.T) { testHighTDStarvationAttack(t, 64, LightSync) }
  952. func testHighTDStarvationAttack(t *testing.T, protocol int, mode SyncMode) {
  953. tester := newTester(mode)
  954. hashes, headers, blocks, receipts := makeChain(0, 0, genesis, nil)
  955. tester.newPeer("attack", protocol, []common.Hash{hashes[0]}, headers, blocks, receipts)
  956. if err := tester.sync("attack", big.NewInt(1000000)); err != errStallingPeer {
  957. t.Fatalf("synchronisation error mismatch: have %v, want %v", err, errStallingPeer)
  958. }
  959. }
  960. // Tests that misbehaving peers are disconnected, whilst behaving ones are not.
  961. func TestBlockHeaderAttackerDropping61(t *testing.T) { testBlockHeaderAttackerDropping(t, 61) }
  962. func TestBlockHeaderAttackerDropping62(t *testing.T) { testBlockHeaderAttackerDropping(t, 62) }
  963. func TestBlockHeaderAttackerDropping63(t *testing.T) { testBlockHeaderAttackerDropping(t, 63) }
  964. func TestBlockHeaderAttackerDropping64(t *testing.T) { testBlockHeaderAttackerDropping(t, 64) }
  965. func testBlockHeaderAttackerDropping(t *testing.T, protocol int) {
  966. // Define the disconnection requirement for individual hash fetch errors
  967. tests := []struct {
  968. result error
  969. drop bool
  970. }{
  971. {nil, false}, // Sync succeeded, all is well
  972. {errBusy, false}, // Sync is already in progress, no problem
  973. {errUnknownPeer, false}, // Peer is unknown, was already dropped, don't double drop
  974. {errBadPeer, true}, // Peer was deemed bad for some reason, drop it
  975. {errStallingPeer, true}, // Peer was detected to be stalling, drop it
  976. {errNoPeers, false}, // No peers to download from, soft race, no issue
  977. {errPendingQueue, false}, // There are blocks still cached, wait to exhaust, no issue
  978. {errTimeout, true}, // No hashes received in due time, drop the peer
  979. {errEmptyHashSet, true}, // No hashes were returned as a response, drop as it's a dead end
  980. {errEmptyHeaderSet, true}, // No headers were returned as a response, drop as it's a dead end
  981. {errPeersUnavailable, true}, // Nobody had the advertised blocks, drop the advertiser
  982. {errInvalidChain, true}, // Hash chain was detected as invalid, definitely drop
  983. {errInvalidBlock, false}, // A bad peer was detected, but not the sync origin
  984. {errInvalidBody, false}, // A bad peer was detected, but not the sync origin
  985. {errInvalidReceipt, false}, // A bad peer was detected, but not the sync origin
  986. {errCancelHashFetch, false}, // Synchronisation was canceled, origin may be innocent, don't drop
  987. {errCancelBlockFetch, false}, // Synchronisation was canceled, origin may be innocent, don't drop
  988. {errCancelHeaderFetch, false}, // Synchronisation was canceled, origin may be innocent, don't drop
  989. {errCancelBodyFetch, false}, // Synchronisation was canceled, origin may be innocent, don't drop
  990. }
  991. // Run the tests and check disconnection status
  992. tester := newTester(FullSync)
  993. for i, tt := range tests {
  994. // Register a new peer and ensure it's presence
  995. id := fmt.Sprintf("test %d", i)
  996. if err := tester.newPeer(id, protocol, []common.Hash{genesis.Hash()}, nil, nil, nil); err != nil {
  997. t.Fatalf("test %d: failed to register new peer: %v", i, err)
  998. }
  999. if _, ok := tester.peerHashes[id]; !ok {
  1000. t.Fatalf("test %d: registered peer not found", i)
  1001. }
  1002. // Simulate a synchronisation and check the required result
  1003. tester.downloader.synchroniseMock = func(string, common.Hash) error { return tt.result }
  1004. tester.downloader.Synchronise(id, genesis.Hash(), big.NewInt(1000))
  1005. if _, ok := tester.peerHashes[id]; !ok != tt.drop {
  1006. t.Errorf("test %d: peer drop mismatch for %v: have %v, want %v", i, tt.result, !ok, tt.drop)
  1007. }
  1008. }
  1009. }
  1010. // Tests that synchronisation boundaries (origin block number and highest block
  1011. // number) is tracked and updated correctly.
  1012. func TestSyncBoundaries61(t *testing.T) { testSyncBoundaries(t, 61, FullSync) }
  1013. func TestSyncBoundaries62(t *testing.T) { testSyncBoundaries(t, 62, FullSync) }
  1014. func TestSyncBoundaries63Full(t *testing.T) { testSyncBoundaries(t, 63, FullSync) }
  1015. func TestSyncBoundaries63Fast(t *testing.T) { testSyncBoundaries(t, 63, FastSync) }
  1016. func TestSyncBoundaries64Full(t *testing.T) { testSyncBoundaries(t, 64, FullSync) }
  1017. func TestSyncBoundaries64Fast(t *testing.T) { testSyncBoundaries(t, 64, FastSync) }
  1018. func TestSyncBoundaries64Light(t *testing.T) { testSyncBoundaries(t, 64, LightSync) }
  1019. func testSyncBoundaries(t *testing.T, protocol int, mode SyncMode) {
  1020. // Create a small enough block chain to download
  1021. targetBlocks := blockCacheLimit - 15
  1022. hashes, headers, blocks, receipts := makeChain(targetBlocks, 0, genesis, nil)
  1023. // Set a sync init hook to catch boundary changes
  1024. starting := make(chan struct{})
  1025. progress := make(chan struct{})
  1026. tester := newTester(mode)
  1027. tester.downloader.syncInitHook = func(origin, latest uint64) {
  1028. starting <- struct{}{}
  1029. <-progress
  1030. }
  1031. // Retrieve the sync boundaries and ensure they are zero (pristine sync)
  1032. if origin, latest := tester.downloader.Boundaries(); origin != 0 || latest != 0 {
  1033. t.Fatalf("Pristine boundary mismatch: have %v/%v, want %v/%v", origin, latest, 0, 0)
  1034. }
  1035. // Synchronise half the blocks and check initial boundaries
  1036. tester.newPeer("peer-half", protocol, hashes[targetBlocks/2:], headers, blocks, receipts)
  1037. pending := new(sync.WaitGroup)
  1038. pending.Add(1)
  1039. go func() {
  1040. defer pending.Done()
  1041. if err := tester.sync("peer-half", nil); err != nil {
  1042. t.Fatalf("failed to synchronise blocks: %v", err)
  1043. }
  1044. }()
  1045. <-starting
  1046. if origin, latest := tester.downloader.Boundaries(); origin != 0 || latest != uint64(targetBlocks/2+1) {
  1047. t.Fatalf("Initial boundary mismatch: have %v/%v, want %v/%v", origin, latest, 0, targetBlocks/2+1)
  1048. }
  1049. progress <- struct{}{}
  1050. pending.Wait()
  1051. // Synchronise all the blocks and check continuation boundaries
  1052. tester.newPeer("peer-full", protocol, hashes, headers, blocks, receipts)
  1053. pending.Add(1)
  1054. go func() {
  1055. defer pending.Done()
  1056. if err := tester.sync("peer-full", nil); err != nil {
  1057. t.Fatalf("failed to synchronise blocks: %v", err)
  1058. }
  1059. }()
  1060. <-starting
  1061. if origin, latest := tester.downloader.Boundaries(); origin != uint64(targetBlocks/2+1) || latest != uint64(targetBlocks) {
  1062. t.Fatalf("Completing boundary mismatch: have %v/%v, want %v/%v", origin, latest, targetBlocks/2+1, targetBlocks)
  1063. }
  1064. progress <- struct{}{}
  1065. pending.Wait()
  1066. }
  1067. // Tests that synchronisation boundaries (origin block number and highest block
  1068. // number) is tracked and updated correctly in case of a fork (or manual head
  1069. // revertal).
  1070. func TestForkedSyncBoundaries61(t *testing.T) { testForkedSyncBoundaries(t, 61, FullSync) }
  1071. func TestForkedSyncBoundaries62(t *testing.T) { testForkedSyncBoundaries(t, 62, FullSync) }
  1072. func TestForkedSyncBoundaries63Full(t *testing.T) { testForkedSyncBoundaries(t, 63, FullSync) }
  1073. func TestForkedSyncBoundaries63Fast(t *testing.T) { testForkedSyncBoundaries(t, 63, FastSync) }
  1074. func TestForkedSyncBoundaries64Full(t *testing.T) { testForkedSyncBoundaries(t, 64, FullSync) }
  1075. func TestForkedSyncBoundaries64Fast(t *testing.T) { testForkedSyncBoundaries(t, 64, FastSync) }
  1076. func TestForkedSyncBoundaries64Light(t *testing.T) { testForkedSyncBoundaries(t, 64, LightSync) }
  1077. func testForkedSyncBoundaries(t *testing.T, protocol int, mode SyncMode) {
  1078. // Create a forked chain to simulate origin revertal
  1079. common, fork := MaxHashFetch, 2*MaxHashFetch
  1080. hashesA, hashesB, headersA, headersB, blocksA, blocksB, receiptsA, receiptsB := makeChainFork(common+fork, fork, genesis, nil)
  1081. // Set a sync init hook to catch boundary changes
  1082. starting := make(chan struct{})
  1083. progress := make(chan struct{})
  1084. tester := newTester(mode)
  1085. tester.downloader.syncInitHook = func(origin, latest uint64) {
  1086. starting <- struct{}{}
  1087. <-progress
  1088. }
  1089. // Retrieve the sync boundaries and ensure they are zero (pristine sync)
  1090. if origin, latest := tester.downloader.Boundaries(); origin != 0 || latest != 0 {
  1091. t.Fatalf("Pristine boundary mismatch: have %v/%v, want %v/%v", origin, latest, 0, 0)
  1092. }
  1093. // Synchronise with one of the forks and check boundaries
  1094. tester.newPeer("fork A", protocol, hashesA, headersA, blocksA, receiptsA)
  1095. pending := new(sync.WaitGroup)
  1096. pending.Add(1)
  1097. go func() {
  1098. defer pending.Done()
  1099. if err := tester.sync("fork A", nil); err != nil {
  1100. t.Fatalf("failed to synchronise blocks: %v", err)
  1101. }
  1102. }()
  1103. <-starting
  1104. if origin, latest := tester.downloader.Boundaries(); origin != 0 || latest != uint64(len(hashesA)-1) {
  1105. t.Fatalf("Initial boundary mismatch: have %v/%v, want %v/%v", origin, latest, 0, len(hashesA)-1)
  1106. }
  1107. progress <- struct{}{}
  1108. pending.Wait()
  1109. // Simulate a successful sync above the fork
  1110. tester.downloader.syncStatsChainOrigin = tester.downloader.syncStatsChainHeight
  1111. // Synchronise with the second fork and check boundary resets
  1112. tester.newPeer("fork B", protocol, hashesB, headersB, blocksB, receiptsB)
  1113. pending.Add(1)
  1114. go func() {
  1115. defer pending.Done()
  1116. if err := tester.sync("fork B", nil); err != nil {
  1117. t.Fatalf("failed to synchronise blocks: %v", err)
  1118. }
  1119. }()
  1120. <-starting
  1121. if origin, latest := tester.downloader.Boundaries(); origin != uint64(common) || latest != uint64(len(hashesB)-1) {
  1122. t.Fatalf("Forking boundary mismatch: have %v/%v, want %v/%v", origin, latest, common, len(hashesB)-1)
  1123. }
  1124. progress <- struct{}{}
  1125. pending.Wait()
  1126. }
  1127. // Tests that if synchronisation is aborted due to some failure, then the boundary
  1128. // origin is not updated in the next sync cycle, as it should be considered the
  1129. // continuation of the previous sync and not a new instance.
  1130. func TestFailedSyncBoundaries61(t *testing.T) { testFailedSyncBoundaries(t, 61, FullSync) }
  1131. func TestFailedSyncBoundaries62(t *testing.T) { testFailedSyncBoundaries(t, 62, FullSync) }
  1132. func TestFailedSyncBoundaries63Full(t *testing.T) { testFailedSyncBoundaries(t, 63, FullSync) }
  1133. func TestFailedSyncBoundaries63Fast(t *testing.T) { testFailedSyncBoundaries(t, 63, FastSync) }
  1134. func TestFailedSyncBoundaries64Full(t *testing.T) { testFailedSyncBoundaries(t, 64, FullSync) }
  1135. func TestFailedSyncBoundaries64Fast(t *testing.T) { testFailedSyncBoundaries(t, 64, FastSync) }
  1136. func TestFailedSyncBoundaries64Light(t *testing.T) { testFailedSyncBoundaries(t, 64, LightSync) }
  1137. func testFailedSyncBoundaries(t *testing.T, protocol int, mode SyncMode) {
  1138. // Create a small enough block chain to download
  1139. targetBlocks := blockCacheLimit - 15
  1140. hashes, headers, blocks, receipts := makeChain(targetBlocks, 0, genesis, nil)
  1141. // Set a sync init hook to catch boundary changes
  1142. starting := make(chan struct{})
  1143. progress := make(chan struct{})
  1144. tester := newTester(mode)
  1145. tester.downloader.syncInitHook = func(origin, latest uint64) {
  1146. starting <- struct{}{}
  1147. <-progress
  1148. }
  1149. // Retrieve the sync boundaries and ensure they are zero (pristine sync)
  1150. if origin, latest := tester.downloader.Boundaries(); origin != 0 || latest != 0 {
  1151. t.Fatalf("Pristine boundary mismatch: have %v/%v, want %v/%v", origin, latest, 0, 0)
  1152. }
  1153. // Attempt a full sync with a faulty peer
  1154. tester.newPeer("faulty", protocol, hashes, headers, blocks, receipts)
  1155. missing := targetBlocks / 2
  1156. delete(tester.peerHeaders["faulty"], hashes[missing])
  1157. delete(tester.peerBlocks["faulty"], hashes[missing])
  1158. delete(tester.peerReceipts["faulty"], hashes[missing])
  1159. pending := new(sync.WaitGroup)
  1160. pending.Add(1)
  1161. go func() {
  1162. defer pending.Done()
  1163. if err := tester.sync("faulty", nil); err == nil {
  1164. t.Fatalf("succeeded faulty synchronisation")
  1165. }
  1166. }()
  1167. <-starting
  1168. if origin, latest := tester.downloader.Boundaries(); origin != 0 || latest != uint64(targetBlocks) {
  1169. t.Fatalf("Initial boundary mismatch: have %v/%v, want %v/%v", origin, latest, 0, targetBlocks)
  1170. }
  1171. progress <- struct{}{}
  1172. pending.Wait()
  1173. // Synchronise with a good peer and check that the boundary origin remind the same after a failure
  1174. tester.newPeer("valid", protocol, hashes, headers, blocks, receipts)
  1175. pending.Add(1)
  1176. go func() {
  1177. defer pending.Done()
  1178. if err := tester.sync("valid", nil); err != nil {
  1179. t.Fatalf("failed to synchronise blocks: %v", err)
  1180. }
  1181. }()
  1182. <-starting
  1183. if origin, latest := tester.downloader.Boundaries(); origin != 0 || latest != uint64(targetBlocks) {
  1184. t.Fatalf("Completing boundary mismatch: have %v/%v, want %v/%v", origin, latest, 0, targetBlocks)
  1185. }
  1186. progress <- struct{}{}
  1187. pending.Wait()
  1188. }
  1189. // Tests that if an attacker fakes a chain height, after the attack is detected,
  1190. // the boundary height is successfully reduced at the next sync invocation.
  1191. func TestFakedSyncBoundaries61(t *testing.T) { testFakedSyncBoundaries(t, 61, FullSync) }
  1192. func TestFakedSyncBoundaries62(t *testing.T) { testFakedSyncBoundaries(t, 62, FullSync) }
  1193. func TestFakedSyncBoundaries63Full(t *testing.T) { testFakedSyncBoundaries(t, 63, FullSync) }
  1194. func TestFakedSyncBoundaries63Fast(t *testing.T) { testFakedSyncBoundaries(t, 63, FastSync) }
  1195. func TestFakedSyncBoundaries64Full(t *testing.T) { testFakedSyncBoundaries(t, 64, FullSync) }
  1196. func TestFakedSyncBoundaries64Fast(t *testing.T) { testFakedSyncBoundaries(t, 64, FastSync) }
  1197. func TestFakedSyncBoundaries64Light(t *testing.T) { testFakedSyncBoundaries(t, 64, LightSync) }
  1198. func testFakedSyncBoundaries(t *testing.T, protocol int, mode SyncMode) {
  1199. // Create a small block chain
  1200. targetBlocks := blockCacheLimit - 15
  1201. hashes, headers, blocks, receipts := makeChain(targetBlocks+3, 0, genesis, nil)
  1202. // Set a sync init hook to catch boundary changes
  1203. starting := make(chan struct{})
  1204. progress := make(chan struct{})
  1205. tester := newTester(mode)
  1206. tester.downloader.syncInitHook = func(origin, latest uint64) {
  1207. starting <- struct{}{}
  1208. <-progress
  1209. }
  1210. // Retrieve the sync boundaries and ensure they are zero (pristine sync)
  1211. if origin, latest := tester.downloader.Boundaries(); origin != 0 || latest != 0 {
  1212. t.Fatalf("Pristine boundary mismatch: have %v/%v, want %v/%v", origin, latest, 0, 0)
  1213. }
  1214. // Create and sync with an attacker that promises a higher chain than available
  1215. tester.newPeer("attack", protocol, hashes, headers, blocks, receipts)
  1216. for i := 1; i < 3; i++ {
  1217. delete(tester.peerHeaders["attack"], hashes[i])
  1218. delete(tester.peerBlocks["attack"], hashes[i])
  1219. delete(tester.peerReceipts["attack"], hashes[i])
  1220. }
  1221. pending := new(sync.WaitGroup)
  1222. pending.Add(1)
  1223. go func() {
  1224. defer pending.Done()
  1225. if err := tester.sync("attack", nil); err == nil {
  1226. t.Fatalf("succeeded attacker synchronisation")
  1227. }
  1228. }()
  1229. <-starting
  1230. if origin, latest := tester.downloader.Boundaries(); origin != 0 || latest != uint64(targetBlocks+3) {
  1231. t.Fatalf("Initial boundary mismatch: have %v/%v, want %v/%v", origin, latest, 0, targetBlocks+3)
  1232. }
  1233. progress <- struct{}{}
  1234. pending.Wait()
  1235. // Synchronise with a good peer and check that the boundary height has been reduced to the true value
  1236. tester.newPeer("valid", protocol, hashes[3:], headers, blocks, receipts)
  1237. pending.Add(1)
  1238. go func() {
  1239. defer pending.Done()
  1240. if err := tester.sync("valid", nil); err != nil {
  1241. t.Fatalf("failed to synchronise blocks: %v", err)
  1242. }
  1243. }()
  1244. <-starting
  1245. if origin, latest := tester.downloader.Boundaries(); origin != 0 || latest != uint64(targetBlocks) {
  1246. t.Fatalf("Initial boundary mismatch: have %v/%v, want %v/%v", origin, latest, 0, targetBlocks)
  1247. }
  1248. progress <- struct{}{}
  1249. pending.Wait()
  1250. }