headerchain.go 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668
  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 core
  17. import (
  18. crand "crypto/rand"
  19. "errors"
  20. "fmt"
  21. "math"
  22. "math/big"
  23. mrand "math/rand"
  24. "sync/atomic"
  25. "time"
  26. "github.com/ethereum/go-ethereum/common"
  27. "github.com/ethereum/go-ethereum/consensus"
  28. "github.com/ethereum/go-ethereum/core/rawdb"
  29. "github.com/ethereum/go-ethereum/core/types"
  30. "github.com/ethereum/go-ethereum/ethdb"
  31. "github.com/ethereum/go-ethereum/log"
  32. "github.com/ethereum/go-ethereum/params"
  33. "github.com/ethereum/go-ethereum/rlp"
  34. lru "github.com/hashicorp/golang-lru"
  35. )
  36. const (
  37. headerCacheLimit = 512
  38. tdCacheLimit = 1024
  39. numberCacheLimit = 2048
  40. )
  41. // HeaderChain implements the basic block header chain logic that is shared by
  42. // core.BlockChain and light.LightChain. It is not usable in itself, only as
  43. // a part of either structure.
  44. //
  45. // HeaderChain is responsible for maintaining the header chain including the
  46. // header query and updating.
  47. //
  48. // The components maintained by headerchain includes: (1) total difficulty
  49. // (2) header (3) block hash -> number mapping (4) canonical number -> hash mapping
  50. // and (5) head header flag.
  51. //
  52. // It is not thread safe either, the encapsulating chain structures should do
  53. // the necessary mutex locking/unlocking.
  54. type HeaderChain struct {
  55. config *params.ChainConfig
  56. chainDb ethdb.Database
  57. genesisHeader *types.Header
  58. currentHeader atomic.Value // Current head of the header chain (may be above the block chain!)
  59. currentHeaderHash common.Hash // Hash of the current head of the header chain (prevent recomputing all the time)
  60. headerCache *lru.Cache // Cache for the most recent block headers
  61. tdCache *lru.Cache // Cache for the most recent block total difficulties
  62. numberCache *lru.Cache // Cache for the most recent block numbers
  63. procInterrupt func() bool
  64. rand *mrand.Rand
  65. engine consensus.Engine
  66. }
  67. // NewHeaderChain creates a new HeaderChain structure. ProcInterrupt points
  68. // to the parent's interrupt semaphore.
  69. func NewHeaderChain(chainDb ethdb.Database, config *params.ChainConfig, engine consensus.Engine, procInterrupt func() bool) (*HeaderChain, error) {
  70. headerCache, _ := lru.New(headerCacheLimit)
  71. tdCache, _ := lru.New(tdCacheLimit)
  72. numberCache, _ := lru.New(numberCacheLimit)
  73. // Seed a fast but crypto originating random generator
  74. seed, err := crand.Int(crand.Reader, big.NewInt(math.MaxInt64))
  75. if err != nil {
  76. return nil, err
  77. }
  78. hc := &HeaderChain{
  79. config: config,
  80. chainDb: chainDb,
  81. headerCache: headerCache,
  82. tdCache: tdCache,
  83. numberCache: numberCache,
  84. procInterrupt: procInterrupt,
  85. rand: mrand.New(mrand.NewSource(seed.Int64())),
  86. engine: engine,
  87. }
  88. hc.genesisHeader = hc.GetHeaderByNumber(0)
  89. if hc.genesisHeader == nil {
  90. return nil, ErrNoGenesis
  91. }
  92. hc.currentHeader.Store(hc.genesisHeader)
  93. if head := rawdb.ReadHeadBlockHash(chainDb); head != (common.Hash{}) {
  94. if chead := hc.GetHeaderByHash(head); chead != nil {
  95. hc.currentHeader.Store(chead)
  96. }
  97. }
  98. hc.currentHeaderHash = hc.CurrentHeader().Hash()
  99. headHeaderGauge.Update(hc.CurrentHeader().Number.Int64())
  100. return hc, nil
  101. }
  102. // GetBlockNumber retrieves the block number belonging to the given hash
  103. // from the cache or database
  104. func (hc *HeaderChain) GetBlockNumber(hash common.Hash) *uint64 {
  105. if cached, ok := hc.numberCache.Get(hash); ok {
  106. number := cached.(uint64)
  107. return &number
  108. }
  109. number := rawdb.ReadHeaderNumber(hc.chainDb, hash)
  110. if number != nil {
  111. hc.numberCache.Add(hash, *number)
  112. }
  113. return number
  114. }
  115. type headerWriteResult struct {
  116. status WriteStatus
  117. ignored int
  118. imported int
  119. lastHash common.Hash
  120. lastHeader *types.Header
  121. }
  122. // Reorg reorgs the local canonical chain into the specified chain. The reorg
  123. // can be classified into two cases: (a) extend the local chain (b) switch the
  124. // head to the given header.
  125. func (hc *HeaderChain) Reorg(headers []*types.Header) error {
  126. // Short circuit if nothing to reorg.
  127. if len(headers) == 0 {
  128. return nil
  129. }
  130. // If the parent of the (first) block is already the canon header,
  131. // we don't have to go backwards to delete canon blocks, but simply
  132. // pile them onto the existing chain. Otherwise, do the necessary
  133. // reorgs.
  134. var (
  135. first = headers[0]
  136. last = headers[len(headers)-1]
  137. batch = hc.chainDb.NewBatch()
  138. )
  139. if first.ParentHash != hc.currentHeaderHash {
  140. // Delete any canonical number assignments above the new head
  141. for i := last.Number.Uint64() + 1; ; i++ {
  142. hash := rawdb.ReadCanonicalHash(hc.chainDb, i)
  143. if hash == (common.Hash{}) {
  144. break
  145. }
  146. rawdb.DeleteCanonicalHash(batch, i)
  147. }
  148. // Overwrite any stale canonical number assignments, going
  149. // backwards from the first header in this import until the
  150. // cross link between two chains.
  151. var (
  152. header = first
  153. headNumber = header.Number.Uint64()
  154. headHash = header.Hash()
  155. )
  156. for rawdb.ReadCanonicalHash(hc.chainDb, headNumber) != headHash {
  157. rawdb.WriteCanonicalHash(batch, headHash, headNumber)
  158. if headNumber == 0 {
  159. break // It shouldn't be reached
  160. }
  161. headHash, headNumber = header.ParentHash, header.Number.Uint64()-1
  162. header = hc.GetHeader(headHash, headNumber)
  163. if header == nil {
  164. return fmt.Errorf("missing parent %d %x", headNumber, headHash)
  165. }
  166. }
  167. }
  168. // Extend the canonical chain with the new headers
  169. for i := 0; i < len(headers)-1; i++ {
  170. hash := headers[i+1].ParentHash // Save some extra hashing
  171. num := headers[i].Number.Uint64()
  172. rawdb.WriteCanonicalHash(batch, hash, num)
  173. rawdb.WriteHeadHeaderHash(batch, hash)
  174. }
  175. // Write the last header
  176. hash := headers[len(headers)-1].Hash()
  177. num := headers[len(headers)-1].Number.Uint64()
  178. rawdb.WriteCanonicalHash(batch, hash, num)
  179. rawdb.WriteHeadHeaderHash(batch, hash)
  180. if err := batch.Write(); err != nil {
  181. return err
  182. }
  183. // Last step update all in-memory head header markers
  184. hc.currentHeaderHash = last.Hash()
  185. hc.currentHeader.Store(types.CopyHeader(last))
  186. headHeaderGauge.Update(last.Number.Int64())
  187. return nil
  188. }
  189. // WriteHeaders writes a chain of headers into the local chain, given that the
  190. // parents are already known. The chain head header won't be updated in this
  191. // function, the additional SetCanonical is expected in order to finish the entire
  192. // procedure.
  193. func (hc *HeaderChain) WriteHeaders(headers []*types.Header) (int, error) {
  194. if len(headers) == 0 {
  195. return 0, nil
  196. }
  197. ptd := hc.GetTd(headers[0].ParentHash, headers[0].Number.Uint64()-1)
  198. if ptd == nil {
  199. return 0, consensus.ErrUnknownAncestor
  200. }
  201. var (
  202. newTD = new(big.Int).Set(ptd) // Total difficulty of inserted chain
  203. inserted []rawdb.NumberHash // Ephemeral lookup of number/hash for the chain
  204. parentKnown = true // Set to true to force hc.HasHeader check the first iteration
  205. batch = hc.chainDb.NewBatch()
  206. )
  207. for i, header := range headers {
  208. var hash common.Hash
  209. // The headers have already been validated at this point, so we already
  210. // know that it's a contiguous chain, where
  211. // headers[i].Hash() == headers[i+1].ParentHash
  212. if i < len(headers)-1 {
  213. hash = headers[i+1].ParentHash
  214. } else {
  215. hash = header.Hash()
  216. }
  217. number := header.Number.Uint64()
  218. newTD.Add(newTD, header.Difficulty)
  219. // If the parent was not present, store it
  220. // If the header is already known, skip it, otherwise store
  221. alreadyKnown := parentKnown && hc.HasHeader(hash, number)
  222. if !alreadyKnown {
  223. // Irrelevant of the canonical status, write the TD and header to the database.
  224. rawdb.WriteTd(batch, hash, number, newTD)
  225. hc.tdCache.Add(hash, new(big.Int).Set(newTD))
  226. rawdb.WriteHeader(batch, header)
  227. inserted = append(inserted, rawdb.NumberHash{Number: number, Hash: hash})
  228. hc.headerCache.Add(hash, header)
  229. hc.numberCache.Add(hash, number)
  230. }
  231. parentKnown = alreadyKnown
  232. }
  233. // Skip the slow disk write of all headers if interrupted.
  234. if hc.procInterrupt() {
  235. log.Debug("Premature abort during headers import")
  236. return 0, errors.New("aborted")
  237. }
  238. // Commit to disk!
  239. if err := batch.Write(); err != nil {
  240. log.Crit("Failed to write headers", "error", err)
  241. }
  242. return len(inserted), nil
  243. }
  244. // writeHeadersAndSetHead writes a batch of block headers and applies the last
  245. // header as the chain head if the fork choicer says it's ok to update the chain.
  246. // Note: This method is not concurrent-safe with inserting blocks simultaneously
  247. // into the chain, as side effects caused by reorganisations cannot be emulated
  248. // without the real blocks. Hence, writing headers directly should only be done
  249. // in two scenarios: pure-header mode of operation (light clients), or properly
  250. // separated header/block phases (non-archive clients).
  251. func (hc *HeaderChain) writeHeadersAndSetHead(headers []*types.Header, forker *ForkChoice) (*headerWriteResult, error) {
  252. inserted, err := hc.WriteHeaders(headers)
  253. if err != nil {
  254. return nil, err
  255. }
  256. var (
  257. lastHeader = headers[len(headers)-1]
  258. lastHash = headers[len(headers)-1].Hash()
  259. result = &headerWriteResult{
  260. status: NonStatTy,
  261. ignored: len(headers) - inserted,
  262. imported: inserted,
  263. lastHash: lastHash,
  264. lastHeader: lastHeader,
  265. }
  266. )
  267. // Ask the fork choicer if the reorg is necessary
  268. if reorg, err := forker.ReorgNeeded(hc.CurrentHeader(), lastHeader); err != nil {
  269. return nil, err
  270. } else if !reorg {
  271. if inserted != 0 {
  272. result.status = SideStatTy
  273. }
  274. return result, nil
  275. }
  276. // Special case, all the inserted headers are already on the canonical
  277. // header chain, skip the reorg operation.
  278. if hc.GetCanonicalHash(lastHeader.Number.Uint64()) == lastHash && lastHeader.Number.Uint64() <= hc.CurrentHeader().Number.Uint64() {
  279. return result, nil
  280. }
  281. // Apply the reorg operation
  282. if err := hc.Reorg(headers); err != nil {
  283. return nil, err
  284. }
  285. result.status = CanonStatTy
  286. return result, nil
  287. }
  288. func (hc *HeaderChain) ValidateHeaderChain(chain []*types.Header, checkFreq int) (int, error) {
  289. // Do a sanity check that the provided chain is actually ordered and linked
  290. for i := 1; i < len(chain); i++ {
  291. if chain[i].Number.Uint64() != chain[i-1].Number.Uint64()+1 {
  292. hash := chain[i].Hash()
  293. parentHash := chain[i-1].Hash()
  294. // Chain broke ancestry, log a message (programming error) and skip insertion
  295. log.Error("Non contiguous header insert", "number", chain[i].Number, "hash", hash,
  296. "parent", chain[i].ParentHash, "prevnumber", chain[i-1].Number, "prevhash", parentHash)
  297. return 0, fmt.Errorf("non contiguous insert: item %d is #%d [%x..], item %d is #%d [%x..] (parent [%x..])", i-1, chain[i-1].Number,
  298. parentHash.Bytes()[:4], i, chain[i].Number, hash.Bytes()[:4], chain[i].ParentHash[:4])
  299. }
  300. // If the header is a banned one, straight out abort
  301. if BadHashes[chain[i].ParentHash] {
  302. return i - 1, ErrBannedHash
  303. }
  304. // If it's the last header in the cunk, we need to check it too
  305. if i == len(chain)-1 && BadHashes[chain[i].Hash()] {
  306. return i, ErrBannedHash
  307. }
  308. }
  309. // Generate the list of seal verification requests, and start the parallel verifier
  310. seals := make([]bool, len(chain))
  311. if checkFreq != 0 {
  312. // In case of checkFreq == 0 all seals are left false.
  313. for i := 0; i <= len(seals)/checkFreq; i++ {
  314. index := i*checkFreq + hc.rand.Intn(checkFreq)
  315. if index >= len(seals) {
  316. index = len(seals) - 1
  317. }
  318. seals[index] = true
  319. }
  320. // Last should always be verified to avoid junk.
  321. seals[len(seals)-1] = true
  322. }
  323. abort, results := hc.engine.VerifyHeaders(hc, chain, seals)
  324. defer close(abort)
  325. // Iterate over the headers and ensure they all check out
  326. for i := range chain {
  327. // If the chain is terminating, stop processing blocks
  328. if hc.procInterrupt() {
  329. log.Debug("Premature abort during headers verification")
  330. return 0, errors.New("aborted")
  331. }
  332. // Otherwise wait for headers checks and ensure they pass
  333. if err := <-results; err != nil {
  334. return i, err
  335. }
  336. }
  337. return 0, nil
  338. }
  339. // InsertHeaderChain inserts the given headers and does the reorganisations.
  340. //
  341. // The validity of the headers is NOT CHECKED by this method, i.e. they need to be
  342. // validated by ValidateHeaderChain before calling InsertHeaderChain.
  343. //
  344. // This insert is all-or-nothing. If this returns an error, no headers were written,
  345. // otherwise they were all processed successfully.
  346. //
  347. // The returned 'write status' says if the inserted headers are part of the canonical chain
  348. // or a side chain.
  349. func (hc *HeaderChain) InsertHeaderChain(chain []*types.Header, start time.Time, forker *ForkChoice) (WriteStatus, error) {
  350. if hc.procInterrupt() {
  351. return 0, errors.New("aborted")
  352. }
  353. res, err := hc.writeHeadersAndSetHead(chain, forker)
  354. if err != nil {
  355. return 0, err
  356. }
  357. // Report some public statistics so the user has a clue what's going on
  358. context := []interface{}{
  359. "count", res.imported,
  360. "elapsed", common.PrettyDuration(time.Since(start)),
  361. }
  362. if last := res.lastHeader; last != nil {
  363. context = append(context, "number", last.Number, "hash", res.lastHash)
  364. if timestamp := time.Unix(int64(last.Time), 0); time.Since(timestamp) > time.Minute {
  365. context = append(context, []interface{}{"age", common.PrettyAge(timestamp)}...)
  366. }
  367. }
  368. if res.ignored > 0 {
  369. context = append(context, []interface{}{"ignored", res.ignored}...)
  370. }
  371. log.Info("Imported new block headers", context...)
  372. return res.status, err
  373. }
  374. // GetAncestor retrieves the Nth ancestor of a given block. It assumes that either the given block or
  375. // a close ancestor of it is canonical. maxNonCanonical points to a downwards counter limiting the
  376. // number of blocks to be individually checked before we reach the canonical chain.
  377. //
  378. // Note: ancestor == 0 returns the same block, 1 returns its parent and so on.
  379. func (hc *HeaderChain) GetAncestor(hash common.Hash, number, ancestor uint64, maxNonCanonical *uint64) (common.Hash, uint64) {
  380. if ancestor > number {
  381. return common.Hash{}, 0
  382. }
  383. if ancestor == 1 {
  384. // in this case it is cheaper to just read the header
  385. if header := hc.GetHeader(hash, number); header != nil {
  386. return header.ParentHash, number - 1
  387. }
  388. return common.Hash{}, 0
  389. }
  390. for ancestor != 0 {
  391. if rawdb.ReadCanonicalHash(hc.chainDb, number) == hash {
  392. ancestorHash := rawdb.ReadCanonicalHash(hc.chainDb, number-ancestor)
  393. if rawdb.ReadCanonicalHash(hc.chainDb, number) == hash {
  394. number -= ancestor
  395. return ancestorHash, number
  396. }
  397. }
  398. if *maxNonCanonical == 0 {
  399. return common.Hash{}, 0
  400. }
  401. *maxNonCanonical--
  402. ancestor--
  403. header := hc.GetHeader(hash, number)
  404. if header == nil {
  405. return common.Hash{}, 0
  406. }
  407. hash = header.ParentHash
  408. number--
  409. }
  410. return hash, number
  411. }
  412. // GetTd retrieves a block's total difficulty in the canonical chain from the
  413. // database by hash and number, caching it if found.
  414. func (hc *HeaderChain) GetTd(hash common.Hash, number uint64) *big.Int {
  415. // Short circuit if the td's already in the cache, retrieve otherwise
  416. if cached, ok := hc.tdCache.Get(hash); ok {
  417. return cached.(*big.Int)
  418. }
  419. td := rawdb.ReadTd(hc.chainDb, hash, number)
  420. if td == nil {
  421. return nil
  422. }
  423. // Cache the found body for next time and return
  424. hc.tdCache.Add(hash, td)
  425. return td
  426. }
  427. // GetHeader retrieves a block header from the database by hash and number,
  428. // caching it if found.
  429. func (hc *HeaderChain) GetHeader(hash common.Hash, number uint64) *types.Header {
  430. // Short circuit if the header's already in the cache, retrieve otherwise
  431. if header, ok := hc.headerCache.Get(hash); ok {
  432. return header.(*types.Header)
  433. }
  434. header := rawdb.ReadHeader(hc.chainDb, hash, number)
  435. if header == nil {
  436. return nil
  437. }
  438. // Cache the found header for next time and return
  439. hc.headerCache.Add(hash, header)
  440. return header
  441. }
  442. // GetHeaderByHash retrieves a block header from the database by hash, caching it if
  443. // found.
  444. func (hc *HeaderChain) GetHeaderByHash(hash common.Hash) *types.Header {
  445. number := hc.GetBlockNumber(hash)
  446. if number == nil {
  447. return nil
  448. }
  449. return hc.GetHeader(hash, *number)
  450. }
  451. // HasHeader checks if a block header is present in the database or not.
  452. // In theory, if header is present in the database, all relative components
  453. // like td and hash->number should be present too.
  454. func (hc *HeaderChain) HasHeader(hash common.Hash, number uint64) bool {
  455. if hc.numberCache.Contains(hash) || hc.headerCache.Contains(hash) {
  456. return true
  457. }
  458. return rawdb.HasHeader(hc.chainDb, hash, number)
  459. }
  460. // GetHeaderByNumber retrieves a block header from the database by number,
  461. // caching it (associated with its hash) if found.
  462. func (hc *HeaderChain) GetHeaderByNumber(number uint64) *types.Header {
  463. hash := rawdb.ReadCanonicalHash(hc.chainDb, number)
  464. if hash == (common.Hash{}) {
  465. return nil
  466. }
  467. return hc.GetHeader(hash, number)
  468. }
  469. // GetHeadersFrom returns a contiguous segment of headers, in rlp-form, going
  470. // backwards from the given number.
  471. // If the 'number' is higher than the highest local header, this method will
  472. // return a best-effort response, containing the headers that we do have.
  473. func (hc *HeaderChain) GetHeadersFrom(number, count uint64) []rlp.RawValue {
  474. // If the request is for future headers, we still return the portion of
  475. // headers that we are able to serve
  476. if current := hc.CurrentHeader().Number.Uint64(); current < number {
  477. if count > number-current {
  478. count -= number - current
  479. number = current
  480. } else {
  481. return nil
  482. }
  483. }
  484. var headers []rlp.RawValue
  485. // If we have some of the headers in cache already, use that before going to db.
  486. hash := rawdb.ReadCanonicalHash(hc.chainDb, number)
  487. if hash == (common.Hash{}) {
  488. return nil
  489. }
  490. for count > 0 {
  491. header, ok := hc.headerCache.Get(hash)
  492. if !ok {
  493. break
  494. }
  495. h := header.(*types.Header)
  496. rlpData, _ := rlp.EncodeToBytes(h)
  497. headers = append(headers, rlpData)
  498. hash = h.ParentHash
  499. count--
  500. number--
  501. }
  502. // Read remaining from db
  503. if count > 0 {
  504. headers = append(headers, rawdb.ReadHeaderRange(hc.chainDb, number, count)...)
  505. }
  506. return headers
  507. }
  508. func (hc *HeaderChain) GetCanonicalHash(number uint64) common.Hash {
  509. return rawdb.ReadCanonicalHash(hc.chainDb, number)
  510. }
  511. // CurrentHeader retrieves the current head header of the canonical chain. The
  512. // header is retrieved from the HeaderChain's internal cache.
  513. func (hc *HeaderChain) CurrentHeader() *types.Header {
  514. return hc.currentHeader.Load().(*types.Header)
  515. }
  516. // SetCurrentHeader sets the in-memory head header marker of the canonical chan
  517. // as the given header.
  518. func (hc *HeaderChain) SetCurrentHeader(head *types.Header) {
  519. hc.currentHeader.Store(head)
  520. hc.currentHeaderHash = head.Hash()
  521. headHeaderGauge.Update(head.Number.Int64())
  522. }
  523. type (
  524. // UpdateHeadBlocksCallback is a callback function that is called by SetHead
  525. // before head header is updated. The method will return the actual block it
  526. // updated the head to (missing state) and a flag if setHead should continue
  527. // rewinding till that forcefully (exceeded ancient limits)
  528. UpdateHeadBlocksCallback func(ethdb.KeyValueWriter, *types.Header) (uint64, bool)
  529. // DeleteBlockContentCallback is a callback function that is called by SetHead
  530. // before each header is deleted.
  531. DeleteBlockContentCallback func(ethdb.KeyValueWriter, common.Hash, uint64)
  532. )
  533. // SetHead rewinds the local chain to a new head. Everything above the new head
  534. // will be deleted and the new one set.
  535. func (hc *HeaderChain) SetHead(head uint64, updateFn UpdateHeadBlocksCallback, delFn DeleteBlockContentCallback) {
  536. var (
  537. parentHash common.Hash
  538. batch = hc.chainDb.NewBatch()
  539. origin = true
  540. )
  541. for hdr := hc.CurrentHeader(); hdr != nil && hdr.Number.Uint64() > head; hdr = hc.CurrentHeader() {
  542. num := hdr.Number.Uint64()
  543. // Rewind block chain to new head.
  544. parent := hc.GetHeader(hdr.ParentHash, num-1)
  545. if parent == nil {
  546. parent = hc.genesisHeader
  547. }
  548. parentHash = parent.Hash()
  549. // Notably, since geth has the possibility for setting the head to a low
  550. // height which is even lower than ancient head.
  551. // In order to ensure that the head is always no higher than the data in
  552. // the database (ancient store or active store), we need to update head
  553. // first then remove the relative data from the database.
  554. //
  555. // Update head first(head fast block, head full block) before deleting the data.
  556. markerBatch := hc.chainDb.NewBatch()
  557. if updateFn != nil {
  558. newHead, force := updateFn(markerBatch, parent)
  559. if force && newHead < head {
  560. log.Warn("Force rewinding till ancient limit", "head", newHead)
  561. head = newHead
  562. }
  563. }
  564. // Update head header then.
  565. rawdb.WriteHeadHeaderHash(markerBatch, parentHash)
  566. if err := markerBatch.Write(); err != nil {
  567. log.Crit("Failed to update chain markers", "error", err)
  568. }
  569. hc.currentHeader.Store(parent)
  570. hc.currentHeaderHash = parentHash
  571. headHeaderGauge.Update(parent.Number.Int64())
  572. // If this is the first iteration, wipe any leftover data upwards too so
  573. // we don't end up with dangling daps in the database
  574. var nums []uint64
  575. if origin {
  576. for n := num + 1; len(rawdb.ReadAllHashes(hc.chainDb, n)) > 0; n++ {
  577. nums = append([]uint64{n}, nums...) // suboptimal, but we don't really expect this path
  578. }
  579. origin = false
  580. }
  581. nums = append(nums, num)
  582. // Remove the related data from the database on all sidechains
  583. for _, num := range nums {
  584. // Gather all the side fork hashes
  585. hashes := rawdb.ReadAllHashes(hc.chainDb, num)
  586. if len(hashes) == 0 {
  587. // No hashes in the database whatsoever, probably frozen already
  588. hashes = append(hashes, hdr.Hash())
  589. }
  590. for _, hash := range hashes {
  591. if delFn != nil {
  592. delFn(batch, hash, num)
  593. }
  594. rawdb.DeleteHeader(batch, hash, num)
  595. rawdb.DeleteTd(batch, hash, num)
  596. }
  597. rawdb.DeleteCanonicalHash(batch, num)
  598. }
  599. }
  600. // Flush all accumulated deletions.
  601. if err := batch.Write(); err != nil {
  602. log.Crit("Failed to rewind block", "error", err)
  603. }
  604. // Clear out any stale content from the caches
  605. hc.headerCache.Purge()
  606. hc.tdCache.Purge()
  607. hc.numberCache.Purge()
  608. }
  609. // SetGenesis sets a new genesis block header for the chain
  610. func (hc *HeaderChain) SetGenesis(head *types.Header) {
  611. hc.genesisHeader = head
  612. }
  613. // Config retrieves the header chain's chain configuration.
  614. func (hc *HeaderChain) Config() *params.ChainConfig { return hc.config }
  615. // Engine retrieves the header chain's consensus engine.
  616. func (hc *HeaderChain) Engine() consensus.Engine { return hc.engine }
  617. // GetBlock implements consensus.ChainReader, and returns nil for every input as
  618. // a header chain does not have blocks available for retrieval.
  619. func (hc *HeaderChain) GetBlock(hash common.Hash, number uint64) *types.Block {
  620. return nil
  621. }