github.1485827954.workers.dev/ethereum/go-ethereum@v1.14.3/core/blockchain_reader.go (about)

     1  // Copyright 2021 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  
    17  package core
    18  
    19  import (
    20  	"errors"
    21  	"math/big"
    22  
    23  	"github.com/ethereum/go-ethereum/common"
    24  	"github.com/ethereum/go-ethereum/consensus"
    25  	"github.com/ethereum/go-ethereum/core/rawdb"
    26  	"github.com/ethereum/go-ethereum/core/state"
    27  	"github.com/ethereum/go-ethereum/core/state/snapshot"
    28  	"github.com/ethereum/go-ethereum/core/types"
    29  	"github.com/ethereum/go-ethereum/core/vm"
    30  	"github.com/ethereum/go-ethereum/event"
    31  	"github.com/ethereum/go-ethereum/params"
    32  	"github.com/ethereum/go-ethereum/rlp"
    33  	"github.com/ethereum/go-ethereum/triedb"
    34  )
    35  
    36  // CurrentHeader retrieves the current head header of the canonical chain. The
    37  // header is retrieved from the HeaderChain's internal cache.
    38  func (bc *BlockChain) CurrentHeader() *types.Header {
    39  	return bc.hc.CurrentHeader()
    40  }
    41  
    42  // CurrentBlock retrieves the current head block of the canonical chain. The
    43  // block is retrieved from the blockchain's internal cache.
    44  func (bc *BlockChain) CurrentBlock() *types.Header {
    45  	return bc.currentBlock.Load()
    46  }
    47  
    48  // CurrentSnapBlock retrieves the current snap-sync head block of the canonical
    49  // chain. The block is retrieved from the blockchain's internal cache.
    50  func (bc *BlockChain) CurrentSnapBlock() *types.Header {
    51  	return bc.currentSnapBlock.Load()
    52  }
    53  
    54  // CurrentFinalBlock retrieves the current finalized block of the canonical
    55  // chain. The block is retrieved from the blockchain's internal cache.
    56  func (bc *BlockChain) CurrentFinalBlock() *types.Header {
    57  	return bc.currentFinalBlock.Load()
    58  }
    59  
    60  // CurrentSafeBlock retrieves the current safe block of the canonical
    61  // chain. The block is retrieved from the blockchain's internal cache.
    62  func (bc *BlockChain) CurrentSafeBlock() *types.Header {
    63  	return bc.currentSafeBlock.Load()
    64  }
    65  
    66  // HasHeader checks if a block header is present in the database or not, caching
    67  // it if present.
    68  func (bc *BlockChain) HasHeader(hash common.Hash, number uint64) bool {
    69  	return bc.hc.HasHeader(hash, number)
    70  }
    71  
    72  // GetHeader retrieves a block header from the database by hash and number,
    73  // caching it if found.
    74  func (bc *BlockChain) GetHeader(hash common.Hash, number uint64) *types.Header {
    75  	return bc.hc.GetHeader(hash, number)
    76  }
    77  
    78  // GetHeaderByHash retrieves a block header from the database by hash, caching it if
    79  // found.
    80  func (bc *BlockChain) GetHeaderByHash(hash common.Hash) *types.Header {
    81  	return bc.hc.GetHeaderByHash(hash)
    82  }
    83  
    84  // GetHeaderByNumber retrieves a block header from the database by number,
    85  // caching it (associated with its hash) if found.
    86  func (bc *BlockChain) GetHeaderByNumber(number uint64) *types.Header {
    87  	return bc.hc.GetHeaderByNumber(number)
    88  }
    89  
    90  // GetHeadersFrom returns a contiguous segment of headers, in rlp-form, going
    91  // backwards from the given number.
    92  func (bc *BlockChain) GetHeadersFrom(number, count uint64) []rlp.RawValue {
    93  	return bc.hc.GetHeadersFrom(number, count)
    94  }
    95  
    96  // GetBody retrieves a block body (transactions and uncles) from the database by
    97  // hash, caching it if found.
    98  func (bc *BlockChain) GetBody(hash common.Hash) *types.Body {
    99  	// Short circuit if the body's already in the cache, retrieve otherwise
   100  	if cached, ok := bc.bodyCache.Get(hash); ok {
   101  		return cached
   102  	}
   103  	number := bc.hc.GetBlockNumber(hash)
   104  	if number == nil {
   105  		return nil
   106  	}
   107  	body := rawdb.ReadBody(bc.db, hash, *number)
   108  	if body == nil {
   109  		return nil
   110  	}
   111  	// Cache the found body for next time and return
   112  	bc.bodyCache.Add(hash, body)
   113  	return body
   114  }
   115  
   116  // GetBodyRLP retrieves a block body in RLP encoding from the database by hash,
   117  // caching it if found.
   118  func (bc *BlockChain) GetBodyRLP(hash common.Hash) rlp.RawValue {
   119  	// Short circuit if the body's already in the cache, retrieve otherwise
   120  	if cached, ok := bc.bodyRLPCache.Get(hash); ok {
   121  		return cached
   122  	}
   123  	number := bc.hc.GetBlockNumber(hash)
   124  	if number == nil {
   125  		return nil
   126  	}
   127  	body := rawdb.ReadBodyRLP(bc.db, hash, *number)
   128  	if len(body) == 0 {
   129  		return nil
   130  	}
   131  	// Cache the found body for next time and return
   132  	bc.bodyRLPCache.Add(hash, body)
   133  	return body
   134  }
   135  
   136  // HasBlock checks if a block is fully present in the database or not.
   137  func (bc *BlockChain) HasBlock(hash common.Hash, number uint64) bool {
   138  	if bc.blockCache.Contains(hash) {
   139  		return true
   140  	}
   141  	if !bc.HasHeader(hash, number) {
   142  		return false
   143  	}
   144  	return rawdb.HasBody(bc.db, hash, number)
   145  }
   146  
   147  // HasFastBlock checks if a fast block is fully present in the database or not.
   148  func (bc *BlockChain) HasFastBlock(hash common.Hash, number uint64) bool {
   149  	if !bc.HasBlock(hash, number) {
   150  		return false
   151  	}
   152  	if bc.receiptsCache.Contains(hash) {
   153  		return true
   154  	}
   155  	return rawdb.HasReceipts(bc.db, hash, number)
   156  }
   157  
   158  // GetBlock retrieves a block from the database by hash and number,
   159  // caching it if found.
   160  func (bc *BlockChain) GetBlock(hash common.Hash, number uint64) *types.Block {
   161  	// Short circuit if the block's already in the cache, retrieve otherwise
   162  	if block, ok := bc.blockCache.Get(hash); ok {
   163  		return block
   164  	}
   165  	block := rawdb.ReadBlock(bc.db, hash, number)
   166  	if block == nil {
   167  		return nil
   168  	}
   169  	// Cache the found block for next time and return
   170  	bc.blockCache.Add(block.Hash(), block)
   171  	return block
   172  }
   173  
   174  // GetBlockByHash retrieves a block from the database by hash, caching it if found.
   175  func (bc *BlockChain) GetBlockByHash(hash common.Hash) *types.Block {
   176  	number := bc.hc.GetBlockNumber(hash)
   177  	if number == nil {
   178  		return nil
   179  	}
   180  	return bc.GetBlock(hash, *number)
   181  }
   182  
   183  // GetBlockByNumber retrieves a block from the database by number, caching it
   184  // (associated with its hash) if found.
   185  func (bc *BlockChain) GetBlockByNumber(number uint64) *types.Block {
   186  	hash := rawdb.ReadCanonicalHash(bc.db, number)
   187  	if hash == (common.Hash{}) {
   188  		return nil
   189  	}
   190  	return bc.GetBlock(hash, number)
   191  }
   192  
   193  // GetBlocksFromHash returns the block corresponding to hash and up to n-1 ancestors.
   194  // [deprecated by eth/62]
   195  func (bc *BlockChain) GetBlocksFromHash(hash common.Hash, n int) (blocks []*types.Block) {
   196  	number := bc.hc.GetBlockNumber(hash)
   197  	if number == nil {
   198  		return nil
   199  	}
   200  	for i := 0; i < n; i++ {
   201  		block := bc.GetBlock(hash, *number)
   202  		if block == nil {
   203  			break
   204  		}
   205  		blocks = append(blocks, block)
   206  		hash = block.ParentHash()
   207  		*number--
   208  	}
   209  	return
   210  }
   211  
   212  // GetReceiptsByHash retrieves the receipts for all transactions in a given block.
   213  func (bc *BlockChain) GetReceiptsByHash(hash common.Hash) types.Receipts {
   214  	if receipts, ok := bc.receiptsCache.Get(hash); ok {
   215  		return receipts
   216  	}
   217  	number := rawdb.ReadHeaderNumber(bc.db, hash)
   218  	if number == nil {
   219  		return nil
   220  	}
   221  	header := bc.GetHeader(hash, *number)
   222  	if header == nil {
   223  		return nil
   224  	}
   225  	receipts := rawdb.ReadReceipts(bc.db, hash, *number, header.Time, bc.chainConfig)
   226  	if receipts == nil {
   227  		return nil
   228  	}
   229  	bc.receiptsCache.Add(hash, receipts)
   230  	return receipts
   231  }
   232  
   233  // GetUnclesInChain retrieves all the uncles from a given block backwards until
   234  // a specific distance is reached.
   235  func (bc *BlockChain) GetUnclesInChain(block *types.Block, length int) []*types.Header {
   236  	uncles := []*types.Header{}
   237  	for i := 0; block != nil && i < length; i++ {
   238  		uncles = append(uncles, block.Uncles()...)
   239  		block = bc.GetBlock(block.ParentHash(), block.NumberU64()-1)
   240  	}
   241  	return uncles
   242  }
   243  
   244  // GetCanonicalHash returns the canonical hash for a given block number
   245  func (bc *BlockChain) GetCanonicalHash(number uint64) common.Hash {
   246  	return bc.hc.GetCanonicalHash(number)
   247  }
   248  
   249  // GetAncestor retrieves the Nth ancestor of a given block. It assumes that either the given block or
   250  // a close ancestor of it is canonical. maxNonCanonical points to a downwards counter limiting the
   251  // number of blocks to be individually checked before we reach the canonical chain.
   252  //
   253  // Note: ancestor == 0 returns the same block, 1 returns its parent and so on.
   254  func (bc *BlockChain) GetAncestor(hash common.Hash, number, ancestor uint64, maxNonCanonical *uint64) (common.Hash, uint64) {
   255  	return bc.hc.GetAncestor(hash, number, ancestor, maxNonCanonical)
   256  }
   257  
   258  // GetTransactionLookup retrieves the lookup along with the transaction
   259  // itself associate with the given transaction hash.
   260  //
   261  // An error will be returned if the transaction is not found, and background
   262  // indexing for transactions is still in progress. The transaction might be
   263  // reachable shortly once it's indexed.
   264  //
   265  // A null will be returned in the transaction is not found and background
   266  // transaction indexing is already finished. The transaction is not existent
   267  // from the node's perspective.
   268  func (bc *BlockChain) GetTransactionLookup(hash common.Hash) (*rawdb.LegacyTxLookupEntry, *types.Transaction, error) {
   269  	bc.txLookupLock.RLock()
   270  	defer bc.txLookupLock.RUnlock()
   271  
   272  	// Short circuit if the txlookup already in the cache, retrieve otherwise
   273  	if item, exist := bc.txLookupCache.Get(hash); exist {
   274  		return item.lookup, item.transaction, nil
   275  	}
   276  	tx, blockHash, blockNumber, txIndex := rawdb.ReadTransaction(bc.db, hash)
   277  	if tx == nil {
   278  		progress, err := bc.TxIndexProgress()
   279  		if err != nil {
   280  			return nil, nil, nil
   281  		}
   282  		// The transaction indexing is not finished yet, returning an
   283  		// error to explicitly indicate it.
   284  		if !progress.Done() {
   285  			return nil, nil, errors.New("transaction indexing still in progress")
   286  		}
   287  		// The transaction is already indexed, the transaction is either
   288  		// not existent or not in the range of index, returning null.
   289  		return nil, nil, nil
   290  	}
   291  	lookup := &rawdb.LegacyTxLookupEntry{
   292  		BlockHash:  blockHash,
   293  		BlockIndex: blockNumber,
   294  		Index:      txIndex,
   295  	}
   296  	bc.txLookupCache.Add(hash, txLookup{
   297  		lookup:      lookup,
   298  		transaction: tx,
   299  	})
   300  	return lookup, tx, nil
   301  }
   302  
   303  // GetTd retrieves a block's total difficulty in the canonical chain from the
   304  // database by hash and number, caching it if found.
   305  func (bc *BlockChain) GetTd(hash common.Hash, number uint64) *big.Int {
   306  	return bc.hc.GetTd(hash, number)
   307  }
   308  
   309  // HasState checks if state trie is fully present in the database or not.
   310  func (bc *BlockChain) HasState(hash common.Hash) bool {
   311  	_, err := bc.stateCache.OpenTrie(hash)
   312  	return err == nil
   313  }
   314  
   315  // HasBlockAndState checks if a block and associated state trie is fully present
   316  // in the database or not, caching it if present.
   317  func (bc *BlockChain) HasBlockAndState(hash common.Hash, number uint64) bool {
   318  	// Check first that the block itself is known
   319  	block := bc.GetBlock(hash, number)
   320  	if block == nil {
   321  		return false
   322  	}
   323  	return bc.HasState(block.Root())
   324  }
   325  
   326  // stateRecoverable checks if the specified state is recoverable.
   327  // Note, this function assumes the state is not present, because
   328  // state is not treated as recoverable if it's available, thus
   329  // false will be returned in this case.
   330  func (bc *BlockChain) stateRecoverable(root common.Hash) bool {
   331  	if bc.triedb.Scheme() == rawdb.HashScheme {
   332  		return false
   333  	}
   334  	result, _ := bc.triedb.Recoverable(root)
   335  	return result
   336  }
   337  
   338  // ContractCodeWithPrefix retrieves a blob of data associated with a contract
   339  // hash either from ephemeral in-memory cache, or from persistent storage.
   340  //
   341  // If the code doesn't exist in the in-memory cache, check the storage with
   342  // new code scheme.
   343  func (bc *BlockChain) ContractCodeWithPrefix(hash common.Hash) ([]byte, error) {
   344  	type codeReader interface {
   345  		ContractCodeWithPrefix(address common.Address, codeHash common.Hash) ([]byte, error)
   346  	}
   347  	// TODO(rjl493456442) The associated account address is also required
   348  	// in Verkle scheme. Fix it once snap-sync is supported for Verkle.
   349  	return bc.stateCache.(codeReader).ContractCodeWithPrefix(common.Address{}, hash)
   350  }
   351  
   352  // State returns a new mutable state based on the current HEAD block.
   353  func (bc *BlockChain) State() (*state.StateDB, error) {
   354  	return bc.StateAt(bc.CurrentBlock().Root)
   355  }
   356  
   357  // StateAt returns a new mutable state based on a particular point in time.
   358  func (bc *BlockChain) StateAt(root common.Hash) (*state.StateDB, error) {
   359  	return state.New(root, bc.stateCache, bc.snaps)
   360  }
   361  
   362  // Config retrieves the chain's fork configuration.
   363  func (bc *BlockChain) Config() *params.ChainConfig { return bc.chainConfig }
   364  
   365  // Engine retrieves the blockchain's consensus engine.
   366  func (bc *BlockChain) Engine() consensus.Engine { return bc.engine }
   367  
   368  // Snapshots returns the blockchain snapshot tree.
   369  func (bc *BlockChain) Snapshots() *snapshot.Tree {
   370  	return bc.snaps
   371  }
   372  
   373  // Validator returns the current validator.
   374  func (bc *BlockChain) Validator() Validator {
   375  	return bc.validator
   376  }
   377  
   378  // Processor returns the current processor.
   379  func (bc *BlockChain) Processor() Processor {
   380  	return bc.processor
   381  }
   382  
   383  // StateCache returns the caching database underpinning the blockchain instance.
   384  func (bc *BlockChain) StateCache() state.Database {
   385  	return bc.stateCache
   386  }
   387  
   388  // GasLimit returns the gas limit of the current HEAD block.
   389  func (bc *BlockChain) GasLimit() uint64 {
   390  	return bc.CurrentBlock().GasLimit
   391  }
   392  
   393  // Genesis retrieves the chain's genesis block.
   394  func (bc *BlockChain) Genesis() *types.Block {
   395  	return bc.genesisBlock
   396  }
   397  
   398  // GetVMConfig returns the block chain VM config.
   399  func (bc *BlockChain) GetVMConfig() *vm.Config {
   400  	return &bc.vmConfig
   401  }
   402  
   403  // TxIndexProgress returns the transaction indexing progress.
   404  func (bc *BlockChain) TxIndexProgress() (TxIndexProgress, error) {
   405  	if bc.txIndexer == nil {
   406  		return TxIndexProgress{}, errors.New("tx indexer is not enabled")
   407  	}
   408  	return bc.txIndexer.txIndexProgress()
   409  }
   410  
   411  // TrieDB retrieves the low level trie database used for data storage.
   412  func (bc *BlockChain) TrieDB() *triedb.Database {
   413  	return bc.triedb
   414  }
   415  
   416  // HeaderChain returns the underlying header chain.
   417  func (bc *BlockChain) HeaderChain() *HeaderChain {
   418  	return bc.hc
   419  }
   420  
   421  // SubscribeRemovedLogsEvent registers a subscription of RemovedLogsEvent.
   422  func (bc *BlockChain) SubscribeRemovedLogsEvent(ch chan<- RemovedLogsEvent) event.Subscription {
   423  	return bc.scope.Track(bc.rmLogsFeed.Subscribe(ch))
   424  }
   425  
   426  // SubscribeChainEvent registers a subscription of ChainEvent.
   427  func (bc *BlockChain) SubscribeChainEvent(ch chan<- ChainEvent) event.Subscription {
   428  	return bc.scope.Track(bc.chainFeed.Subscribe(ch))
   429  }
   430  
   431  // SubscribeChainHeadEvent registers a subscription of ChainHeadEvent.
   432  func (bc *BlockChain) SubscribeChainHeadEvent(ch chan<- ChainHeadEvent) event.Subscription {
   433  	return bc.scope.Track(bc.chainHeadFeed.Subscribe(ch))
   434  }
   435  
   436  // SubscribeChainSideEvent registers a subscription of ChainSideEvent.
   437  func (bc *BlockChain) SubscribeChainSideEvent(ch chan<- ChainSideEvent) event.Subscription {
   438  	return bc.scope.Track(bc.chainSideFeed.Subscribe(ch))
   439  }
   440  
   441  // SubscribeLogsEvent registers a subscription of []*types.Log.
   442  func (bc *BlockChain) SubscribeLogsEvent(ch chan<- []*types.Log) event.Subscription {
   443  	return bc.scope.Track(bc.logsFeed.Subscribe(ch))
   444  }
   445  
   446  // SubscribeBlockProcessingEvent registers a subscription of bool where true means
   447  // block processing has started while false means it has stopped.
   448  func (bc *BlockChain) SubscribeBlockProcessingEvent(ch chan<- bool) event.Subscription {
   449  	return bc.scope.Track(bc.blockProcFeed.Subscribe(ch))
   450  }