github.com/dominant-strategies/go-quai@v0.28.2/core/headerchain.go (about)

     1  package core
     2  
     3  import (
     4  	"errors"
     5  	"fmt"
     6  	"io"
     7  	"math/big"
     8  	"sync"
     9  	"sync/atomic"
    10  	"time"
    11  
    12  	"github.com/dominant-strategies/go-quai/common"
    13  	"github.com/dominant-strategies/go-quai/consensus"
    14  	"github.com/dominant-strategies/go-quai/consensus/misc"
    15  	"github.com/dominant-strategies/go-quai/core/rawdb"
    16  	"github.com/dominant-strategies/go-quai/core/state"
    17  	"github.com/dominant-strategies/go-quai/core/types"
    18  	"github.com/dominant-strategies/go-quai/core/vm"
    19  	"github.com/dominant-strategies/go-quai/ethdb"
    20  	"github.com/dominant-strategies/go-quai/event"
    21  	"github.com/dominant-strategies/go-quai/log"
    22  	"github.com/dominant-strategies/go-quai/params"
    23  	"github.com/dominant-strategies/go-quai/rlp"
    24  	"github.com/dominant-strategies/go-quai/trie"
    25  	lru "github.com/hashicorp/golang-lru"
    26  )
    27  
    28  const (
    29  	headerCacheLimit      = 512
    30  	numberCacheLimit      = 2048
    31  	c_subRollupCacheSize  = 50
    32  	primeHorizonThreshold = 20
    33  )
    34  
    35  // getPendingEtxsRollup gets the pendingEtxsRollup rollup from appropriate Region
    36  type getPendingEtxsRollup func(blockHash common.Hash, hash common.Hash, location common.Location) (types.PendingEtxsRollup, error)
    37  
    38  // getPendingEtxs gets the pendingEtxs from the appropriate Zone
    39  type getPendingEtxs func(blockHash common.Hash, hash common.Hash, location common.Location) (types.PendingEtxs, error)
    40  
    41  type HeaderChain struct {
    42  	config *params.ChainConfig
    43  
    44  	bc     *BodyDb
    45  	engine consensus.Engine
    46  	pool   *TxPool
    47  
    48  	chainHeadFeed event.Feed
    49  	chainSideFeed event.Feed
    50  	scope         event.SubscriptionScope
    51  
    52  	headerDb      ethdb.Database
    53  	genesisHeader *types.Header
    54  
    55  	currentHeader atomic.Value // Current head of the header chain (may be above the block chain!)
    56  
    57  	headerCache *lru.Cache // Cache for the most recent block headers
    58  	numberCache *lru.Cache // Cache for the most recent block numbers
    59  
    60  	fetchPEtxRollup getPendingEtxsRollup
    61  	fetchPEtx       getPendingEtxs
    62  
    63  	pendingEtxsRollup *lru.Cache
    64  	pendingEtxs       *lru.Cache
    65  	blooms            *lru.Cache
    66  	subRollupCache    *lru.Cache
    67  
    68  	wg            sync.WaitGroup // chain processing wait group for shutting down
    69  	running       int32          // 0 if chain is running, 1 when stopped
    70  	procInterrupt int32          // interrupt signaler for block processing
    71  
    72  	headermu      sync.RWMutex
    73  	heads         []*types.Header
    74  	slicesRunning []common.Location
    75  }
    76  
    77  // NewHeaderChain creates a new HeaderChain structure. ProcInterrupt points
    78  // to the parent's interrupt semaphore.
    79  func NewHeaderChain(db ethdb.Database, engine consensus.Engine, pEtxsRollupFetcher getPendingEtxsRollup, pEtxsFetcher getPendingEtxs, chainConfig *params.ChainConfig, cacheConfig *CacheConfig, txLookupLimit *uint64, vmConfig vm.Config, slicesRunning []common.Location) (*HeaderChain, error) {
    80  	headerCache, _ := lru.New(headerCacheLimit)
    81  	numberCache, _ := lru.New(numberCacheLimit)
    82  	nodeCtx := common.NodeLocation.Context()
    83  
    84  	hc := &HeaderChain{
    85  		config:          chainConfig,
    86  		headerDb:        db,
    87  		headerCache:     headerCache,
    88  		numberCache:     numberCache,
    89  		engine:          engine,
    90  		slicesRunning:   slicesRunning,
    91  		fetchPEtxRollup: pEtxsRollupFetcher,
    92  		fetchPEtx:       pEtxsFetcher,
    93  	}
    94  
    95  	pendingEtxsRollup, _ := lru.New(c_maxPendingEtxsRollup)
    96  	hc.pendingEtxsRollup = pendingEtxsRollup
    97  
    98  	if nodeCtx == common.PRIME_CTX {
    99  		hc.pendingEtxs, _ = lru.New(c_maxPendingEtxBatchesPrime)
   100  	} else {
   101  		hc.pendingEtxs, _ = lru.New(c_maxPendingEtxBatchesRegion)
   102  	}
   103  
   104  	blooms, _ := lru.New(c_maxBloomFilters)
   105  	hc.blooms = blooms
   106  
   107  	subRollupCache, _ := lru.New(c_subRollupCacheSize)
   108  	hc.subRollupCache = subRollupCache
   109  
   110  	hc.genesisHeader = hc.GetHeaderByNumber(0)
   111  	if hc.genesisHeader.Hash() != chainConfig.GenesisHash {
   112  		return nil, fmt.Errorf("genesis block mismatch: have %x, want %x", hc.genesisHeader.Hash(), chainConfig.GenesisHash)
   113  	}
   114  	log.Info("Genesis", "Hash:", hc.genesisHeader.Hash())
   115  	if hc.genesisHeader == nil {
   116  		return nil, ErrNoGenesis
   117  	}
   118  	//Load any state that is in our db
   119  	if err := hc.loadLastState(); err != nil {
   120  		return nil, err
   121  	}
   122  
   123  	var err error
   124  	hc.bc, err = NewBodyDb(db, engine, hc, chainConfig, cacheConfig, txLookupLimit, vmConfig, slicesRunning)
   125  	if err != nil {
   126  		return nil, err
   127  	}
   128  
   129  	// Initialize the heads slice
   130  	heads := make([]*types.Header, 0)
   131  	hc.heads = heads
   132  
   133  	return hc, nil
   134  }
   135  
   136  // CollectSubRollup collects the rollup of ETXs emitted from the subordinate
   137  // chain in the slice which emitted the given block.
   138  func (hc *HeaderChain) CollectSubRollup(b *types.Block) (types.Transactions, error) {
   139  	nodeCtx := common.NodeLocation.Context()
   140  	subRollup := types.Transactions{}
   141  	if nodeCtx < common.ZONE_CTX {
   142  		// Since in prime the pending etxs are stored in 2 parts, pendingEtxsRollup
   143  		// consists of region header and its sub manifests
   144  		// Prime independently stores the pending etxs for each of the hashes in
   145  		// the sub manifests, so it needs the pendingEtxsRollup to do so.
   146  		for _, hash := range b.SubManifest() {
   147  			if nodeCtx == common.PRIME_CTX {
   148  				pEtxRollup, err := hc.GetPendingEtxsRollup(hash)
   149  				if err == nil {
   150  					for _, pEtxHash := range pEtxRollup.Manifest {
   151  						pendingEtxs, err := hc.GetPendingEtxs(pEtxHash)
   152  						if err != nil {
   153  							// Get the pendingEtx from the appropriate zone
   154  							hc.fetchPEtx(b.Hash(), pEtxHash, pEtxRollup.Header.Location())
   155  							return nil, ErrPendingEtxNotFound
   156  						}
   157  						subRollup = append(subRollup, pendingEtxs.Etxs...)
   158  					}
   159  				} else {
   160  					// Try to get the pending etx from the Regions
   161  					hc.fetchPEtxRollup(b.Hash(), hash, b.Location())
   162  					return nil, ErrPendingEtxNotFound
   163  				}
   164  				// Region works normally as before collecting pendingEtxs for each hash in the manifest
   165  			} else if nodeCtx == common.REGION_CTX {
   166  				pendingEtxs, err := hc.GetPendingEtxs(hash)
   167  				if err != nil {
   168  					// Get the pendingEtx from the appropriate zone
   169  					hc.fetchPEtx(b.Hash(), hash, b.Header().Location())
   170  					return nil, ErrPendingEtxNotFound
   171  				}
   172  				subRollup = append(subRollup, pendingEtxs.Etxs...)
   173  			}
   174  		}
   175  		// Rolluphash is specifically for zone rollup, which can only be validated by region
   176  		if nodeCtx == common.REGION_CTX {
   177  			if subRollupHash := types.DeriveSha(subRollup, trie.NewStackTrie(nil)); subRollupHash != b.EtxRollupHash() {
   178  				return nil, errors.New("sub rollup does not match sub rollup hash")
   179  			}
   180  		}
   181  	}
   182  	return subRollup, nil
   183  }
   184  
   185  // GetPendingEtxs gets the pendingEtxs form the
   186  func (hc *HeaderChain) GetPendingEtxs(hash common.Hash) (*types.PendingEtxs, error) {
   187  	var pendingEtxs types.PendingEtxs
   188  	// Look for pending ETXs first in pending ETX cache, then in database
   189  	if res, ok := hc.pendingEtxs.Get(hash); ok && res != nil {
   190  		pendingEtxs = res.(types.PendingEtxs)
   191  	} else if res := rawdb.ReadPendingEtxs(hc.headerDb, hash); res != nil {
   192  		pendingEtxs = *res
   193  	} else {
   194  		log.Trace("unable to find pending etxs for hash in manifest", "hash:", hash.String())
   195  		return nil, ErrPendingEtxNotFound
   196  	}
   197  	return &pendingEtxs, nil
   198  }
   199  
   200  func (hc *HeaderChain) GetPendingEtxsRollup(hash common.Hash) (*types.PendingEtxsRollup, error) {
   201  	var rollups types.PendingEtxsRollup
   202  	// Look for pending ETXs first in pending ETX cache, then in database
   203  	if res, ok := hc.pendingEtxsRollup.Get(hash); ok && res != nil {
   204  		rollups = res.(types.PendingEtxsRollup)
   205  	} else if res := rawdb.ReadPendingEtxsRollup(hc.headerDb, hash); res != nil {
   206  		rollups = *res
   207  	} else {
   208  		log.Trace("unable to find pending etxs rollups for hash in manifest", "hash:", hash.String())
   209  		return nil, ErrPendingEtxRollupNotFound
   210  	}
   211  	return &rollups, nil
   212  }
   213  
   214  // GetBloom gets the bloom from the cache or database
   215  func (hc *HeaderChain) GetBloom(hash common.Hash) (*types.Bloom, error) {
   216  	var bloom types.Bloom
   217  	// Look for bloom first in bloom cache, then in database
   218  	if res, ok := hc.blooms.Get(hash); ok && res != nil {
   219  		bloom = res.(types.Bloom)
   220  	} else if res := rawdb.ReadBloom(hc.headerDb, hash); res != nil {
   221  		bloom = *res
   222  	} else {
   223  		log.Debug("unable to find bloom for hash in database", "hash:", hash.String())
   224  		return nil, ErrBloomNotFound
   225  	}
   226  	return &bloom, nil
   227  }
   228  
   229  // Collect all emmitted ETXs since the last coincident block, but excluding
   230  // those emitted in this block
   231  func (hc *HeaderChain) CollectEtxRollup(b *types.Block) (types.Transactions, error) {
   232  	if b.NumberU64() == 0 && b.Hash() == hc.config.GenesisHash {
   233  		return b.ExtTransactions(), nil
   234  	}
   235  	parent := hc.GetBlock(b.ParentHash(), b.NumberU64()-1)
   236  	if parent == nil {
   237  		return nil, errors.New("parent not found")
   238  	}
   239  	return hc.collectInclusiveEtxRollup(parent)
   240  }
   241  
   242  func (hc *HeaderChain) collectInclusiveEtxRollup(b *types.Block) (types.Transactions, error) {
   243  	// Initialize the rollup with ETXs emitted by this block
   244  	newEtxs := b.ExtTransactions()
   245  	// Terminate the search if we reached genesis
   246  	if b.NumberU64() == 0 {
   247  		if b.Hash() != hc.config.GenesisHash {
   248  			return nil, fmt.Errorf("manifest builds on incorrect genesis, block0 hash: %s", b.Hash().String())
   249  		} else {
   250  			return newEtxs, nil
   251  		}
   252  	}
   253  	// Terminate the search on coincidence with dom chain
   254  	if hc.engine.IsDomCoincident(hc, b.Header()) {
   255  		return newEtxs, nil
   256  	}
   257  	// Recursively get the ancestor rollup, until a coincident ancestor is found
   258  	ancestor := hc.GetBlock(b.ParentHash(), b.NumberU64()-1)
   259  	if ancestor == nil {
   260  		return nil, errors.New("ancestor not found")
   261  	}
   262  	etxRollup, err := hc.collectInclusiveEtxRollup(ancestor)
   263  	if err != nil {
   264  		return nil, err
   265  	}
   266  	etxRollup = append(etxRollup, newEtxs...)
   267  	return etxRollup, nil
   268  }
   269  
   270  // Append
   271  func (hc *HeaderChain) AppendHeader(header *types.Header) error {
   272  	nodeCtx := common.NodeLocation.Context()
   273  	log.Debug("HeaderChain Append:", "Header information: Hash:", header.Hash(), "header header hash:", header.Hash(), "Number:", header.NumberU64(), "Location:", header.Location, "Parent:", header.ParentHash())
   274  
   275  	err := hc.engine.VerifyHeader(hc, header)
   276  	if err != nil {
   277  		return err
   278  	}
   279  
   280  	// Verify the manifest matches expected
   281  	// Load the manifest of headers preceding this header
   282  	// note: prime manifest is non-existent, because a prime header cannot be
   283  	// coincident with a higher order chain. So, this check is skipped for prime
   284  	// nodes.
   285  	if nodeCtx > common.PRIME_CTX {
   286  		manifest := rawdb.ReadManifest(hc.headerDb, header.ParentHash())
   287  		if manifest == nil {
   288  			return errors.New("manifest not found for parent")
   289  		}
   290  		if header.ManifestHash(nodeCtx) != types.DeriveSha(manifest, trie.NewStackTrie(nil)) {
   291  			return errors.New("manifest does not match hash")
   292  		}
   293  	}
   294  
   295  	return nil
   296  }
   297  func (hc *HeaderChain) ProcessingState() bool {
   298  	return hc.bc.ProcessingState()
   299  }
   300  
   301  // Append
   302  func (hc *HeaderChain) AppendBlock(block *types.Block, newInboundEtxs types.Transactions) error {
   303  	blockappend := time.Now()
   304  	// Append block else revert header append
   305  	logs, err := hc.bc.Append(block, newInboundEtxs)
   306  	if err != nil {
   307  		return err
   308  	}
   309  	log.Debug("Time taken to", "Append in bc", common.PrettyDuration(time.Since(blockappend)))
   310  
   311  	hc.bc.chainFeed.Send(ChainEvent{Block: block, Hash: block.Hash(), Logs: logs})
   312  	if len(logs) > 0 {
   313  		hc.bc.logsFeed.Send(logs)
   314  	}
   315  
   316  	return nil
   317  }
   318  
   319  // SetCurrentHeader sets the current header based on the POEM choice
   320  func (hc *HeaderChain) SetCurrentHeader(head *types.Header) error {
   321  	hc.headermu.Lock()
   322  	defer hc.headermu.Unlock()
   323  
   324  	prevHeader := hc.CurrentHeader()
   325  	// if trying to set the same header, escape
   326  	if prevHeader.Hash() == head.Hash() {
   327  		return nil
   328  	}
   329  
   330  	// write the head block hash to the db
   331  	rawdb.WriteHeadBlockHash(hc.headerDb, head.Hash())
   332  	log.Info("Setting the current header", "Hash", head.Hash(), "Number", head.NumberArray())
   333  	hc.currentHeader.Store(head)
   334  
   335  	// If head is the normal extension of canonical head, we can return by just wiring the canonical hash.
   336  	if prevHeader.Hash() == head.ParentHash() {
   337  		rawdb.WriteCanonicalHash(hc.headerDb, head.Hash(), head.NumberU64())
   338  		return nil
   339  	}
   340  
   341  	//Find a common header
   342  	commonHeader := hc.findCommonAncestor(head)
   343  	newHeader := types.CopyHeader(head)
   344  
   345  	// Delete each header and rollback state processor until common header
   346  	// Accumulate the hash slice stack
   347  	var hashStack []*types.Header
   348  	for {
   349  		if newHeader.Hash() == commonHeader.Hash() {
   350  			break
   351  		}
   352  		hashStack = append(hashStack, newHeader)
   353  		newHeader = hc.GetHeader(newHeader.ParentHash(), newHeader.NumberU64()-1)
   354  
   355  		// genesis check to not delete the genesis block
   356  		if newHeader.Hash() == hc.config.GenesisHash {
   357  			break
   358  		}
   359  	}
   360  
   361  	for {
   362  		if prevHeader.Hash() == commonHeader.Hash() {
   363  			break
   364  		}
   365  		rawdb.DeleteCanonicalHash(hc.headerDb, prevHeader.NumberU64())
   366  		prevHeader = hc.GetHeader(prevHeader.ParentHash(), prevHeader.NumberU64()-1)
   367  
   368  		// genesis check to not delete the genesis block
   369  		if prevHeader.Hash() == hc.config.GenesisHash {
   370  			break
   371  		}
   372  	}
   373  
   374  	// Run through the hash stack to update canonicalHash and forward state processor
   375  	for i := len(hashStack) - 1; i >= 0; i-- {
   376  		rawdb.WriteCanonicalHash(hc.headerDb, hashStack[i].Hash(), hashStack[i].NumberU64())
   377  	}
   378  
   379  	return nil
   380  }
   381  
   382  // SetCurrentHeader sets the in-memory head header marker of the canonical chan
   383  // as the given header.
   384  func (hc *HeaderChain) SetCurrentState(head *types.Header) error {
   385  	hc.headermu.Lock()
   386  	defer hc.headermu.Unlock()
   387  
   388  	nodeCtx := common.NodeLocation.Context()
   389  	if nodeCtx != common.ZONE_CTX || !hc.ProcessingState() {
   390  		return nil
   391  	}
   392  
   393  	current := types.CopyHeader(head)
   394  	var headersWithoutState []*types.Header
   395  	for {
   396  		headersWithoutState = append(headersWithoutState, current)
   397  		header := hc.GetHeader(current.ParentHash(), current.NumberU64()-1)
   398  		if header == nil {
   399  			return ErrSubNotSyncedToDom
   400  		}
   401  		// Checking of the Etx set exists makes sure that we have processed the
   402  		// state of the parent block
   403  		etxSet := rawdb.ReadEtxSet(hc.headerDb, header.Hash(), header.NumberU64())
   404  		if etxSet != nil {
   405  			break
   406  		}
   407  		current = types.CopyHeader(header)
   408  	}
   409  
   410  	// Run through the hash stack to update canonicalHash and forward state processor
   411  	for i := len(headersWithoutState) - 1; i >= 0; i-- {
   412  		err := hc.ReadInboundEtxsAndAppendBlock(headersWithoutState[i])
   413  		if err != nil {
   414  			return err
   415  		}
   416  	}
   417  	return nil
   418  }
   419  
   420  // ReadInboundEtxsAndAppendBlock reads the inbound etxs from database and appends the block
   421  func (hc *HeaderChain) ReadInboundEtxsAndAppendBlock(header *types.Header) error {
   422  	block := hc.GetBlockOrCandidate(header.Hash(), header.NumberU64())
   423  	if block == nil {
   424  		return errors.New("Could not find block during reorg")
   425  	}
   426  	_, order, err := hc.engine.CalcOrder(block.Header())
   427  	if err != nil {
   428  		return err
   429  	}
   430  	nodeCtx := common.NodeLocation.Context()
   431  	var inboundEtxs types.Transactions
   432  	if order < nodeCtx {
   433  		inboundEtxs = rawdb.ReadInboundEtxs(hc.headerDb, header.Hash())
   434  	}
   435  	return hc.AppendBlock(block, inboundEtxs)
   436  }
   437  
   438  // findCommonAncestor
   439  func (hc *HeaderChain) findCommonAncestor(header *types.Header) *types.Header {
   440  	current := types.CopyHeader(header)
   441  	for {
   442  		if current == nil {
   443  			return nil
   444  		}
   445  		canonicalHash := rawdb.ReadCanonicalHash(hc.headerDb, current.NumberU64())
   446  		if canonicalHash == current.Hash() {
   447  			return hc.GetHeaderByHash(canonicalHash)
   448  		}
   449  		current = hc.GetHeader(current.ParentHash(), current.NumberU64()-1)
   450  	}
   451  
   452  }
   453  
   454  func (hc *HeaderChain) AddPendingEtxs(pEtxs types.PendingEtxs) error {
   455  	if !pEtxs.IsValid(trie.NewStackTrie(nil)) {
   456  		log.Info("PendingEtx is not valid")
   457  		return ErrPendingEtxNotValid
   458  	}
   459  	log.Debug("Received pending ETXs", "block: ", pEtxs.Header.Hash())
   460  	// Only write the pending ETXs if we have not seen them before
   461  	if !hc.pendingEtxs.Contains(pEtxs.Header.Hash()) {
   462  		// Write to pending ETX database
   463  		rawdb.WritePendingEtxs(hc.headerDb, pEtxs)
   464  		// Also write to cache for faster access
   465  		hc.pendingEtxs.Add(pEtxs.Header.Hash(), pEtxs)
   466  	} else {
   467  		return ErrPendingEtxAlreadyKnown
   468  	}
   469  	return nil
   470  }
   471  
   472  func (hc *HeaderChain) AddBloom(bloom types.Bloom, hash common.Hash) error {
   473  	// Only write the bloom if we have not seen it before
   474  	if !hc.blooms.Contains(hash) {
   475  		// Write to bloom database
   476  		rawdb.WriteBloom(hc.headerDb, hash, bloom)
   477  		// Also write to cache for faster access
   478  		hc.blooms.Add(hash, bloom)
   479  	} else {
   480  		return ErrBloomAlreadyKnown
   481  	}
   482  	return nil
   483  }
   484  
   485  // loadLastState loads the last known chain state from the database. This method
   486  // assumes that the chain manager mutex is held.
   487  func (hc *HeaderChain) loadLastState() error {
   488  	// TODO: create function to find highest block number and fill Head FIFO
   489  	headsHashes := rawdb.ReadHeadsHashes(hc.headerDb)
   490  
   491  	if head := rawdb.ReadHeadBlockHash(hc.headerDb); head != (common.Hash{}) {
   492  		if chead := hc.GetHeaderByHash(head); chead != nil {
   493  			hc.currentHeader.Store(chead)
   494  		} else {
   495  			// This is only done if during the stop, currenthead hash was not stored
   496  			// properly and it doesn't crash the nodes
   497  			hc.currentHeader.Store(hc.genesisHeader)
   498  		}
   499  	} else {
   500  		// Recover the current header
   501  		log.Warn("Recovering Current Header")
   502  		recoverdHeader := hc.RecoverCurrentHeader()
   503  		rawdb.WriteHeadBlockHash(hc.headerDb, recoverdHeader.Hash())
   504  		hc.currentHeader.Store(recoverdHeader)
   505  	}
   506  
   507  	heads := make([]*types.Header, 0)
   508  	for _, hash := range headsHashes {
   509  		heads = append(heads, hc.GetHeaderByHash(hash))
   510  	}
   511  	hc.heads = heads
   512  
   513  	return nil
   514  }
   515  
   516  // Stop stops the blockchain service. If any imports are currently in progress
   517  // it will abort them using the procInterrupt.
   518  func (hc *HeaderChain) Stop() {
   519  	if !atomic.CompareAndSwapInt32(&hc.running, 0, 1) {
   520  		return
   521  	}
   522  
   523  	hashes := make([]common.Hash, 0)
   524  	for i := 0; i < len(hc.heads); i++ {
   525  		hashes = append(hashes, hc.heads[i].Hash())
   526  	}
   527  	// Save the heads
   528  	rawdb.WriteHeadsHashes(hc.headerDb, hashes)
   529  
   530  	// Unsubscribe all subscriptions registered from blockchain
   531  	hc.scope.Close()
   532  	hc.bc.scope.Close()
   533  	hc.wg.Wait()
   534  	if common.NodeLocation.Context() == common.ZONE_CTX && hc.ProcessingState() {
   535  		hc.bc.processor.Stop()
   536  	}
   537  	log.Info("headerchain stopped")
   538  }
   539  
   540  // Empty checks if the headerchain is empty.
   541  func (hc *HeaderChain) Empty() bool {
   542  	genesis := hc.config.GenesisHash
   543  	for _, hash := range []common.Hash{rawdb.ReadHeadBlockHash(hc.headerDb)} {
   544  		if hash != genesis {
   545  			return false
   546  		}
   547  	}
   548  	return true
   549  }
   550  
   551  // GetBlockNumber retrieves the block number belonging to the given hash
   552  // from the cache or database
   553  func (hc *HeaderChain) GetBlockNumber(hash common.Hash) *uint64 {
   554  	if cached, ok := hc.numberCache.Get(hash); ok {
   555  		number := cached.(uint64)
   556  		return &number
   557  	}
   558  	number := rawdb.ReadHeaderNumber(hc.headerDb, hash)
   559  	if number != nil {
   560  		hc.numberCache.Add(hash, *number)
   561  	}
   562  	return number
   563  }
   564  
   565  func (hc *HeaderChain) GetTerminiByHash(hash common.Hash) *types.Termini {
   566  	termini := rawdb.ReadTermini(hc.headerDb, hash)
   567  	return termini
   568  }
   569  
   570  // GetBlockHashesFromHash retrieves a number of block hashes starting at a given
   571  // hash, fetching towards the genesis block.
   572  func (hc *HeaderChain) GetBlockHashesFromHash(hash common.Hash, max uint64) []common.Hash {
   573  	// Get the origin header from which to fetch
   574  	header := hc.GetHeaderByHash(hash)
   575  	if header == nil {
   576  		return nil
   577  	}
   578  	// Iterate the headers until enough is collected or the genesis reached
   579  	chain := make([]common.Hash, 0, max)
   580  	for i := uint64(0); i < max; i++ {
   581  		next := header.ParentHash()
   582  		if header = hc.GetHeader(next, header.NumberU64()-1); header == nil {
   583  			break
   584  		}
   585  		chain = append(chain, next)
   586  		if header.Number().Sign() == 0 {
   587  			break
   588  		}
   589  	}
   590  	return chain
   591  }
   592  
   593  // GetAncestor retrieves the Nth ancestor of a given block. It assumes that either the given block or
   594  // a close ancestor of it is canonical. maxNonCanonical points to a downwards counter limiting the
   595  // number of blocks to be individually checked before we reach the canonical chain.
   596  //
   597  // Note: ancestor == 0 returns the same block, 1 returns its parent and so on.
   598  func (hc *HeaderChain) GetAncestor(hash common.Hash, number, ancestor uint64, maxNonCanonical *uint64) (common.Hash, uint64) {
   599  	if ancestor > number {
   600  		return common.Hash{}, 0
   601  	}
   602  	if ancestor == 1 {
   603  		// in this case it is cheaper to just read the header
   604  		if header := hc.GetHeader(hash, number); header != nil {
   605  			return header.ParentHash(), number - 1
   606  		}
   607  		return common.Hash{}, 0
   608  	}
   609  	for ancestor != 0 {
   610  		if rawdb.ReadCanonicalHash(hc.headerDb, number) == hash {
   611  			ancestorHash := rawdb.ReadCanonicalHash(hc.headerDb, number-ancestor)
   612  			if rawdb.ReadCanonicalHash(hc.headerDb, number) == hash {
   613  				number -= ancestor
   614  				return ancestorHash, number
   615  			}
   616  		}
   617  		if *maxNonCanonical == 0 {
   618  			return common.Hash{}, 0
   619  		}
   620  		*maxNonCanonical--
   621  		ancestor--
   622  		header := hc.GetHeader(hash, number)
   623  		if header == nil {
   624  			return common.Hash{}, 0
   625  		}
   626  		hash = header.ParentHash()
   627  		number--
   628  	}
   629  	return hash, number
   630  }
   631  
   632  func (hc *HeaderChain) WriteBlock(block *types.Block) {
   633  	hc.bc.WriteBlock(block)
   634  }
   635  
   636  // GetHeader retrieves a block header from the database by hash and number,
   637  // caching it if found.
   638  func (hc *HeaderChain) GetHeader(hash common.Hash, number uint64) *types.Header {
   639  	termini := hc.GetTerminiByHash(hash)
   640  	if termini == nil {
   641  		return nil
   642  	}
   643  	// Short circuit if the header's already in the cache, retrieve otherwise
   644  	if header, ok := hc.headerCache.Get(hash); ok {
   645  		return header.(*types.Header)
   646  	}
   647  	header := rawdb.ReadHeader(hc.headerDb, hash, number)
   648  	if header == nil {
   649  		return nil
   650  	}
   651  	// Cache the found header for next time and return
   652  	hc.headerCache.Add(hash, header)
   653  	return header
   654  }
   655  
   656  // GetHeaderByHash retrieves a block header from the database by hash, caching it if
   657  // found.
   658  func (hc *HeaderChain) GetHeaderByHash(hash common.Hash) *types.Header {
   659  	termini := hc.GetTerminiByHash(hash)
   660  	if termini == nil {
   661  		return nil
   662  	}
   663  	number := hc.GetBlockNumber(hash)
   664  	if number == nil {
   665  		return nil
   666  	}
   667  
   668  	return hc.GetHeader(hash, *number)
   669  }
   670  
   671  // GetHeaderOrCandidate retrieves a block header from the database by hash and number,
   672  // caching it if found.
   673  func (hc *HeaderChain) GetHeaderOrCandidate(hash common.Hash, number uint64) *types.Header {
   674  	// Short circuit if the header's already in the cache, retrieve otherwise
   675  	if header, ok := hc.headerCache.Get(hash); ok {
   676  		return header.(*types.Header)
   677  	}
   678  	header := rawdb.ReadHeader(hc.headerDb, hash, number)
   679  	if header == nil {
   680  		return nil
   681  	}
   682  	// Cache the found header for next time and return
   683  	hc.headerCache.Add(hash, header)
   684  	return header
   685  }
   686  
   687  // RecoverCurrentHeader retrieves the current head header of the canonical chain. The
   688  // header is retrieved from the HeaderChain's internal cache
   689  func (hc *HeaderChain) RecoverCurrentHeader() *types.Header {
   690  	// Start logarithmic ascent to find the upper bound
   691  	high := uint64(1)
   692  	for hc.GetHeaderByNumber(high) != nil {
   693  		high *= 2
   694  	}
   695  	// Run binary search to find the max header
   696  	low := high / 2
   697  	for low <= high {
   698  		mid := (low + high) / 2
   699  		if hc.GetHeaderByNumber(mid) != nil {
   700  			low = mid + 1
   701  		} else {
   702  			high = mid - 1
   703  		}
   704  	}
   705  	header := hc.GetHeaderByNumber(high)
   706  	log.Info("Header Recovered: ", "hash", header.Hash().String())
   707  
   708  	return header
   709  }
   710  
   711  // GetHeaderOrCandidateByHash retrieves a block header from the database by hash, caching it if
   712  // found.
   713  func (hc *HeaderChain) GetHeaderOrCandidateByHash(hash common.Hash) *types.Header {
   714  	number := hc.GetBlockNumber(hash)
   715  	if number == nil {
   716  		return nil
   717  	}
   718  
   719  	return hc.GetHeaderOrCandidate(hash, *number)
   720  }
   721  
   722  // HasHeader checks if a block header is present in the database or not.
   723  // In theory, if header is present in the database, all relative components
   724  // like td and hash->number should be present too.
   725  func (hc *HeaderChain) HasHeader(hash common.Hash, number uint64) bool {
   726  	if hc.numberCache.Contains(hash) || hc.headerCache.Contains(hash) {
   727  		return true
   728  	}
   729  	return rawdb.HasHeader(hc.headerDb, hash, number)
   730  }
   731  
   732  // GetHeaderByNumber retrieves a block header from the database by number,
   733  // caching it (associated with its hash) if found.
   734  func (hc *HeaderChain) GetHeaderByNumber(number uint64) *types.Header {
   735  	hash := rawdb.ReadCanonicalHash(hc.headerDb, number)
   736  	if hash == (common.Hash{}) {
   737  		return nil
   738  	}
   739  	return hc.GetHeader(hash, number)
   740  }
   741  
   742  func (hc *HeaderChain) GetCanonicalHash(number uint64) common.Hash {
   743  	hash := rawdb.ReadCanonicalHash(hc.headerDb, number)
   744  	return hash
   745  }
   746  
   747  // CurrentHeader retrieves the current head header of the canonical chain. The
   748  // header is retrieved from the HeaderChain's internal cache.
   749  func (hc *HeaderChain) CurrentHeader() *types.Header {
   750  	return hc.currentHeader.Load().(*types.Header)
   751  }
   752  
   753  // CurrentBlock returns the block for the current header.
   754  func (hc *HeaderChain) CurrentBlock() *types.Block {
   755  	return hc.GetBlockOrCandidateByHash(hc.CurrentHeader().Hash())
   756  }
   757  
   758  // SetGenesis sets a new genesis block header for the chain
   759  func (hc *HeaderChain) SetGenesis(head *types.Header) {
   760  	hc.genesisHeader = head
   761  }
   762  
   763  // Config retrieves the header chain's chain configuration.
   764  func (hc *HeaderChain) Config() *params.ChainConfig { return hc.config }
   765  
   766  // GetBlock implements consensus.ChainReader, and returns nil for every input as
   767  // a header chain does not have blocks available for retrieval.
   768  func (hc *HeaderChain) GetBlock(hash common.Hash, number uint64) *types.Block {
   769  	return hc.bc.GetBlock(hash, number)
   770  }
   771  
   772  // CheckContext checks to make sure the range of a context or order is valid
   773  func (hc *HeaderChain) CheckContext(context int) error {
   774  	if context < 0 || context > common.HierarchyDepth {
   775  		return errors.New("the provided path is outside the allowable range")
   776  	}
   777  	return nil
   778  }
   779  
   780  // CheckLocationRange checks to make sure the range of r and z are valid
   781  func (hc *HeaderChain) CheckLocationRange(location []byte) error {
   782  	if int(location[0]) < 1 || int(location[0]) > common.NumRegionsInPrime {
   783  		return errors.New("the provided location is outside the allowable region range")
   784  	}
   785  	if int(location[1]) < 1 || int(location[1]) > common.NumZonesInRegion {
   786  		return errors.New("the provided location is outside the allowable zone range")
   787  	}
   788  	return nil
   789  }
   790  
   791  // GasLimit returns the gas limit of the current HEAD block.
   792  func (hc *HeaderChain) GasLimit() uint64 {
   793  	return hc.CurrentHeader().GasLimit()
   794  }
   795  
   796  // GetUnclesInChain retrieves all the uncles from a given block backwards until
   797  // a specific distance is reached.
   798  func (hc *HeaderChain) GetUnclesInChain(block *types.Block, length int) []*types.Header {
   799  	uncles := []*types.Header{}
   800  	for i := 0; block != nil && i < length; i++ {
   801  		uncles = append(uncles, block.Uncles()...)
   802  		block = hc.GetBlock(block.ParentHash(), block.NumberU64()-1)
   803  	}
   804  	return uncles
   805  }
   806  
   807  // GetGasUsedInChain retrieves all the gas used from a given block backwards until
   808  // a specific distance is reached.
   809  func (hc *HeaderChain) GetGasUsedInChain(block *types.Block, length int) int64 {
   810  	gasUsed := 0
   811  	for i := 0; block != nil && i < length; i++ {
   812  		gasUsed += int(block.GasUsed())
   813  		block = hc.GetBlock(block.ParentHash(), block.NumberU64()-1)
   814  	}
   815  	return int64(gasUsed)
   816  }
   817  
   818  // GetGasUsedInChain retrieves all the gas used from a given block backwards until
   819  // a specific distance is reached.
   820  func (hc *HeaderChain) CalculateBaseFee(header *types.Header) *big.Int {
   821  	return misc.CalcBaseFee(hc.Config(), header)
   822  }
   823  
   824  // Export writes the active chain to the given writer.
   825  func (hc *HeaderChain) Export(w io.Writer) error {
   826  	return hc.ExportN(w, uint64(0), hc.CurrentHeader().NumberU64())
   827  }
   828  
   829  // ExportN writes a subset of the active chain to the given writer.
   830  func (hc *HeaderChain) ExportN(w io.Writer, first uint64, last uint64) error {
   831  	hc.headermu.RLock()
   832  	defer hc.headermu.RUnlock()
   833  
   834  	if first > last {
   835  		return fmt.Errorf("export failed: first (%d) is greater than last (%d)", first, last)
   836  	}
   837  	log.Info("Exporting batch of blocks", "count", last-first+1)
   838  
   839  	start, reported := time.Now(), time.Now()
   840  	for nr := first; nr <= last; nr++ {
   841  		block := hc.GetBlockByNumber(nr)
   842  		if block == nil {
   843  			return fmt.Errorf("export failed on #%d: not found", nr)
   844  		}
   845  		if err := block.EncodeRLP(w); err != nil {
   846  			return err
   847  		}
   848  		if time.Since(reported) >= statsReportLimit {
   849  			log.Info("Exporting blocks", "exported", block.NumberU64()-first, "elapsed", common.PrettyDuration(time.Since(start)))
   850  			reported = time.Now()
   851  		}
   852  	}
   853  	return nil
   854  }
   855  
   856  // GetBlockFromCacheOrDb looks up the body cache first and then checks the db
   857  func (hc *HeaderChain) GetBlockFromCacheOrDb(hash common.Hash, number uint64) *types.Block {
   858  	// Short circuit if the block's already in the cache, retrieve otherwise
   859  	if cached, ok := hc.bc.blockCache.Get(hash); ok {
   860  		block := cached.(*types.Block)
   861  		return block
   862  	}
   863  	return hc.GetBlock(hash, number)
   864  }
   865  
   866  // GetBlockByHash retrieves a block from the database by hash, caching it if found.
   867  func (hc *HeaderChain) GetBlockByHash(hash common.Hash) *types.Block {
   868  	number := hc.GetBlockNumber(hash)
   869  	if number == nil {
   870  		return nil
   871  	}
   872  	return hc.GetBlock(hash, *number)
   873  }
   874  
   875  func (hc *HeaderChain) GetBlockOrCandidate(hash common.Hash, number uint64) *types.Block {
   876  	return hc.bc.GetBlockOrCandidate(hash, number)
   877  }
   878  
   879  // GetBlockOrCandidateByHash retrieves any block from the database by hash, caching it if found.
   880  func (hc *HeaderChain) GetBlockOrCandidateByHash(hash common.Hash) *types.Block {
   881  	number := hc.GetBlockNumber(hash)
   882  	if number == nil {
   883  		return nil
   884  	}
   885  	return hc.bc.GetBlockOrCandidate(hash, *number)
   886  }
   887  
   888  // GetBlockByNumber retrieves a block from the database by number, caching it
   889  // (associated with its hash) if found.
   890  func (hc *HeaderChain) GetBlockByNumber(number uint64) *types.Block {
   891  	hash := rawdb.ReadCanonicalHash(hc.headerDb, number)
   892  	if hash == (common.Hash{}) {
   893  		return nil
   894  	}
   895  	return hc.GetBlock(hash, number)
   896  }
   897  
   898  // GetBody retrieves a block body (transactions and uncles) from the database by
   899  // hash, caching it if found.
   900  func (hc *HeaderChain) GetBody(hash common.Hash) *types.Body {
   901  	// Short circuit if the body's already in the cache, retrieve otherwise
   902  	if cached, ok := hc.bc.bodyCache.Get(hash); ok {
   903  		body := cached.(*types.Body)
   904  		return body
   905  	}
   906  	number := hc.GetBlockNumber(hash)
   907  	if number == nil {
   908  		return nil
   909  	}
   910  	body := rawdb.ReadBody(hc.headerDb, hash, *number)
   911  	if body == nil {
   912  		return nil
   913  	}
   914  	// Cache the found body for next time and return
   915  	hc.bc.bodyCache.Add(hash, body)
   916  	return body
   917  }
   918  
   919  // GetBodyRLP retrieves a block body in RLP encoding from the database by hash,
   920  // caching it if found.
   921  func (hc *HeaderChain) GetBodyRLP(hash common.Hash) rlp.RawValue {
   922  	// Short circuit if the body's already in the cache, retrieve otherwise
   923  	if cached, ok := hc.bc.bodyRLPCache.Get(hash); ok {
   924  		return cached.(rlp.RawValue)
   925  	}
   926  	number := hc.GetBlockNumber(hash)
   927  	if number == nil {
   928  		return nil
   929  	}
   930  	body := rawdb.ReadBodyRLP(hc.headerDb, hash, *number)
   931  	if len(body) == 0 {
   932  		return nil
   933  	}
   934  	// Cache the found body for next time and return
   935  	hc.bc.bodyRLPCache.Add(hash, body)
   936  	return body
   937  }
   938  
   939  // GetBlocksFromHash returns the block corresponding to hash and up to n-1 ancestors.
   940  // [deprecated by eth/62]
   941  func (hc *HeaderChain) GetBlocksFromHash(hash common.Hash, n int) (blocks []*types.Block) {
   942  	number := hc.GetBlockNumber(hash)
   943  	if number == nil {
   944  		return nil
   945  	}
   946  	for i := 0; i < n; i++ {
   947  		block := hc.GetBlock(hash, *number)
   948  		if block == nil {
   949  			break
   950  		}
   951  		blocks = append(blocks, block)
   952  		hash = block.ParentHash()
   953  		*number--
   954  	}
   955  	return
   956  }
   957  
   958  // Engine reterives the consensus engine.
   959  func (hc *HeaderChain) Engine() consensus.Engine {
   960  	return hc.engine
   961  }
   962  
   963  // SubscribeChainHeadEvent registers a subscription of ChainHeadEvent.
   964  func (hc *HeaderChain) SubscribeChainHeadEvent(ch chan<- ChainHeadEvent) event.Subscription {
   965  	return hc.scope.Track(hc.chainHeadFeed.Subscribe(ch))
   966  }
   967  
   968  // SubscribeChainSideEvent registers a subscription of ChainSideEvent.
   969  func (hc *HeaderChain) SubscribeChainSideEvent(ch chan<- ChainSideEvent) event.Subscription {
   970  	return hc.scope.Track(hc.chainSideFeed.Subscribe(ch))
   971  }
   972  
   973  func (hc *HeaderChain) StateAt(root common.Hash) (*state.StateDB, error) {
   974  	return hc.bc.processor.StateAt(root)
   975  }