github.com/ethereum/go-ethereum@v1.16.1/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  	"fmt"
    22  	"math/big"
    23  
    24  	"github.com/ethereum/go-ethereum/common"
    25  	"github.com/ethereum/go-ethereum/consensus"
    26  	"github.com/ethereum/go-ethereum/consensus/misc/eip4844"
    27  	"github.com/ethereum/go-ethereum/core/rawdb"
    28  	"github.com/ethereum/go-ethereum/core/state"
    29  	"github.com/ethereum/go-ethereum/core/state/snapshot"
    30  	"github.com/ethereum/go-ethereum/core/types"
    31  	"github.com/ethereum/go-ethereum/core/vm"
    32  	"github.com/ethereum/go-ethereum/event"
    33  	"github.com/ethereum/go-ethereum/params"
    34  	"github.com/ethereum/go-ethereum/rlp"
    35  	"github.com/ethereum/go-ethereum/triedb"
    36  )
    37  
    38  // CurrentHeader retrieves the current head header of the canonical chain. The
    39  // header is retrieved from the HeaderChain's internal cache.
    40  func (bc *BlockChain) CurrentHeader() *types.Header {
    41  	return bc.hc.CurrentHeader()
    42  }
    43  
    44  // CurrentBlock retrieves the current head block of the canonical chain. The
    45  // block is retrieved from the blockchain's internal cache.
    46  func (bc *BlockChain) CurrentBlock() *types.Header {
    47  	return bc.currentBlock.Load()
    48  }
    49  
    50  // CurrentSnapBlock retrieves the current snap-sync head block of the canonical
    51  // chain. The block is retrieved from the blockchain's internal cache.
    52  func (bc *BlockChain) CurrentSnapBlock() *types.Header {
    53  	return bc.currentSnapBlock.Load()
    54  }
    55  
    56  // CurrentFinalBlock retrieves the current finalized block of the canonical
    57  // chain. The block is retrieved from the blockchain's internal cache.
    58  func (bc *BlockChain) CurrentFinalBlock() *types.Header {
    59  	return bc.currentFinalBlock.Load()
    60  }
    61  
    62  // CurrentSafeBlock retrieves the current safe block of the canonical
    63  // chain. The block is retrieved from the blockchain's internal cache.
    64  func (bc *BlockChain) CurrentSafeBlock() *types.Header {
    65  	return bc.currentSafeBlock.Load()
    66  }
    67  
    68  // HasHeader checks if a block header is present in the database or not, caching
    69  // it if present.
    70  func (bc *BlockChain) HasHeader(hash common.Hash, number uint64) bool {
    71  	return bc.hc.HasHeader(hash, number)
    72  }
    73  
    74  // GetHeader retrieves a block header from the database by hash and number,
    75  // caching it if found.
    76  func (bc *BlockChain) GetHeader(hash common.Hash, number uint64) *types.Header {
    77  	return bc.hc.GetHeader(hash, number)
    78  }
    79  
    80  // GetHeaderByHash retrieves a block header from the database by hash, caching it if
    81  // found.
    82  func (bc *BlockChain) GetHeaderByHash(hash common.Hash) *types.Header {
    83  	return bc.hc.GetHeaderByHash(hash)
    84  }
    85  
    86  // GetHeaderByNumber retrieves a block header from the database by number,
    87  // caching it (associated with its hash) if found.
    88  func (bc *BlockChain) GetHeaderByNumber(number uint64) *types.Header {
    89  	return bc.hc.GetHeaderByNumber(number)
    90  }
    91  
    92  // GetBlockNumber retrieves the block number associated with a block hash.
    93  func (bc *BlockChain) GetBlockNumber(hash common.Hash) *uint64 {
    94  	return bc.hc.GetBlockNumber(hash)
    95  }
    96  
    97  // GetHeadersFrom returns a contiguous segment of headers, in rlp-form, going
    98  // backwards from the given number.
    99  func (bc *BlockChain) GetHeadersFrom(number, count uint64) []rlp.RawValue {
   100  	return bc.hc.GetHeadersFrom(number, count)
   101  }
   102  
   103  // GetBody retrieves a block body (transactions and uncles) from the database by
   104  // hash, caching it if found.
   105  func (bc *BlockChain) GetBody(hash common.Hash) *types.Body {
   106  	// Short circuit if the body's already in the cache, retrieve otherwise
   107  	if cached, ok := bc.bodyCache.Get(hash); ok {
   108  		return cached
   109  	}
   110  	number := bc.hc.GetBlockNumber(hash)
   111  	if number == nil {
   112  		return nil
   113  	}
   114  	body := rawdb.ReadBody(bc.db, hash, *number)
   115  	if body == nil {
   116  		return nil
   117  	}
   118  	// Cache the found body for next time and return
   119  	bc.bodyCache.Add(hash, body)
   120  	return body
   121  }
   122  
   123  // GetBodyRLP retrieves a block body in RLP encoding from the database by hash,
   124  // caching it if found.
   125  func (bc *BlockChain) GetBodyRLP(hash common.Hash) rlp.RawValue {
   126  	// Short circuit if the body's already in the cache, retrieve otherwise
   127  	if cached, ok := bc.bodyRLPCache.Get(hash); ok {
   128  		return cached
   129  	}
   130  	number := bc.hc.GetBlockNumber(hash)
   131  	if number == nil {
   132  		return nil
   133  	}
   134  	body := rawdb.ReadBodyRLP(bc.db, hash, *number)
   135  	if len(body) == 0 {
   136  		return nil
   137  	}
   138  	// Cache the found body for next time and return
   139  	bc.bodyRLPCache.Add(hash, body)
   140  	return body
   141  }
   142  
   143  // HasBlock checks if a block is fully present in the database or not.
   144  func (bc *BlockChain) HasBlock(hash common.Hash, number uint64) bool {
   145  	if bc.blockCache.Contains(hash) {
   146  		return true
   147  	}
   148  	if !bc.HasHeader(hash, number) {
   149  		return false
   150  	}
   151  	return rawdb.HasBody(bc.db, hash, number)
   152  }
   153  
   154  // HasFastBlock checks if a fast block is fully present in the database or not.
   155  func (bc *BlockChain) HasFastBlock(hash common.Hash, number uint64) bool {
   156  	if !bc.HasBlock(hash, number) {
   157  		return false
   158  	}
   159  	if bc.receiptsCache.Contains(hash) {
   160  		return true
   161  	}
   162  	return rawdb.HasReceipts(bc.db, hash, number)
   163  }
   164  
   165  // GetBlock retrieves a block from the database by hash and number,
   166  // caching it if found.
   167  func (bc *BlockChain) GetBlock(hash common.Hash, number uint64) *types.Block {
   168  	// Short circuit if the block's already in the cache, retrieve otherwise
   169  	if block, ok := bc.blockCache.Get(hash); ok {
   170  		return block
   171  	}
   172  	block := rawdb.ReadBlock(bc.db, hash, number)
   173  	if block == nil {
   174  		return nil
   175  	}
   176  	// Cache the found block for next time and return
   177  	bc.blockCache.Add(block.Hash(), block)
   178  	return block
   179  }
   180  
   181  // GetBlockByHash retrieves a block from the database by hash, caching it if found.
   182  func (bc *BlockChain) GetBlockByHash(hash common.Hash) *types.Block {
   183  	number := bc.hc.GetBlockNumber(hash)
   184  	if number == nil {
   185  		return nil
   186  	}
   187  	return bc.GetBlock(hash, *number)
   188  }
   189  
   190  // GetBlockByNumber retrieves a block from the database by number, caching it
   191  // (associated with its hash) if found.
   192  func (bc *BlockChain) GetBlockByNumber(number uint64) *types.Block {
   193  	hash := rawdb.ReadCanonicalHash(bc.db, number)
   194  	if hash == (common.Hash{}) {
   195  		return nil
   196  	}
   197  	return bc.GetBlock(hash, number)
   198  }
   199  
   200  // GetBlocksFromHash returns the block corresponding to hash and up to n-1 ancestors.
   201  // [deprecated by eth/62]
   202  func (bc *BlockChain) GetBlocksFromHash(hash common.Hash, n int) (blocks []*types.Block) {
   203  	number := bc.hc.GetBlockNumber(hash)
   204  	if number == nil {
   205  		return nil
   206  	}
   207  	for i := 0; i < n; i++ {
   208  		block := bc.GetBlock(hash, *number)
   209  		if block == nil {
   210  			break
   211  		}
   212  		blocks = append(blocks, block)
   213  		hash = block.ParentHash()
   214  		*number--
   215  	}
   216  	return
   217  }
   218  
   219  // GetCanonicalReceipt allows fetching a receipt for a transaction that was
   220  // already looked up on the index. Notably, only receipt in canonical chain
   221  // is visible.
   222  func (bc *BlockChain) GetCanonicalReceipt(tx *types.Transaction, blockHash common.Hash, blockNumber, txIndex uint64) (*types.Receipt, error) {
   223  	// The receipt retrieved from the cache contains all previously derived fields
   224  	if receipts, ok := bc.receiptsCache.Get(blockHash); ok {
   225  		if int(txIndex) >= len(receipts) {
   226  			return nil, fmt.Errorf("receipt out of index, length: %d, index: %d", len(receipts), txIndex)
   227  		}
   228  		return receipts[int(txIndex)], nil
   229  	}
   230  	header := bc.GetHeader(blockHash, blockNumber)
   231  	if header == nil {
   232  		return nil, fmt.Errorf("block header is not found, %d, %x", blockNumber, blockHash)
   233  	}
   234  	var blobGasPrice *big.Int
   235  	if header.ExcessBlobGas != nil {
   236  		blobGasPrice = eip4844.CalcBlobFee(bc.chainConfig, header)
   237  	}
   238  	receipt, ctx, err := rawdb.ReadCanonicalRawReceipt(bc.db, blockHash, blockNumber, txIndex)
   239  	if err != nil {
   240  		return nil, err
   241  	}
   242  	signer := types.MakeSigner(bc.chainConfig, new(big.Int).SetUint64(blockNumber), header.Time)
   243  	receipt.DeriveFields(signer, types.DeriveReceiptContext{
   244  		BlockHash:    blockHash,
   245  		BlockNumber:  blockNumber,
   246  		BlockTime:    header.Time,
   247  		BaseFee:      header.BaseFee,
   248  		BlobGasPrice: blobGasPrice,
   249  		GasUsed:      ctx.GasUsed,
   250  		LogIndex:     ctx.LogIndex,
   251  		Tx:           tx,
   252  		TxIndex:      uint(txIndex),
   253  	})
   254  	return receipt, nil
   255  }
   256  
   257  // GetReceiptsByHash retrieves the receipts for all transactions in a given block.
   258  func (bc *BlockChain) GetReceiptsByHash(hash common.Hash) types.Receipts {
   259  	if receipts, ok := bc.receiptsCache.Get(hash); ok {
   260  		return receipts
   261  	}
   262  	number := rawdb.ReadHeaderNumber(bc.db, hash)
   263  	if number == nil {
   264  		return nil
   265  	}
   266  	header := bc.GetHeader(hash, *number)
   267  	if header == nil {
   268  		return nil
   269  	}
   270  	receipts := rawdb.ReadReceipts(bc.db, hash, *number, header.Time, bc.chainConfig)
   271  	if receipts == nil {
   272  		return nil
   273  	}
   274  	bc.receiptsCache.Add(hash, receipts)
   275  	return receipts
   276  }
   277  
   278  // GetRawReceipts retrieves the receipts for all transactions in a given block
   279  // without deriving the internal fields and the Bloom.
   280  func (bc *BlockChain) GetRawReceipts(hash common.Hash, number uint64) types.Receipts {
   281  	if receipts, ok := bc.receiptsCache.Get(hash); ok {
   282  		return receipts
   283  	}
   284  	return rawdb.ReadRawReceipts(bc.db, hash, number)
   285  }
   286  
   287  // GetReceiptsRLP retrieves the receipts of a block.
   288  func (bc *BlockChain) GetReceiptsRLP(hash common.Hash) rlp.RawValue {
   289  	number := rawdb.ReadHeaderNumber(bc.db, hash)
   290  	if number == nil {
   291  		return nil
   292  	}
   293  	return rawdb.ReadReceiptsRLP(bc.db, hash, *number)
   294  }
   295  
   296  // GetUnclesInChain retrieves all the uncles from a given block backwards until
   297  // a specific distance is reached.
   298  func (bc *BlockChain) GetUnclesInChain(block *types.Block, length int) []*types.Header {
   299  	uncles := []*types.Header{}
   300  	for i := 0; block != nil && i < length; i++ {
   301  		uncles = append(uncles, block.Uncles()...)
   302  		block = bc.GetBlock(block.ParentHash(), block.NumberU64()-1)
   303  	}
   304  	return uncles
   305  }
   306  
   307  // GetCanonicalHash returns the canonical hash for a given block number
   308  func (bc *BlockChain) GetCanonicalHash(number uint64) common.Hash {
   309  	return bc.hc.GetCanonicalHash(number)
   310  }
   311  
   312  // GetAncestor retrieves the Nth ancestor of a given block. It assumes that either the given block or
   313  // a close ancestor of it is canonical. maxNonCanonical points to a downwards counter limiting the
   314  // number of blocks to be individually checked before we reach the canonical chain.
   315  //
   316  // Note: ancestor == 0 returns the same block, 1 returns its parent and so on.
   317  func (bc *BlockChain) GetAncestor(hash common.Hash, number, ancestor uint64, maxNonCanonical *uint64) (common.Hash, uint64) {
   318  	return bc.hc.GetAncestor(hash, number, ancestor, maxNonCanonical)
   319  }
   320  
   321  // GetCanonicalTransaction retrieves the lookup along with the transaction
   322  // itself associate with the given transaction hash.
   323  //
   324  // A null will be returned if the transaction is not found. This can be due to
   325  // the transaction indexer not being finished. The caller must explicitly check
   326  // the indexer progress.
   327  //
   328  // Notably, only the transaction in the canonical chain is visible.
   329  func (bc *BlockChain) GetCanonicalTransaction(hash common.Hash) (*rawdb.LegacyTxLookupEntry, *types.Transaction) {
   330  	bc.txLookupLock.RLock()
   331  	defer bc.txLookupLock.RUnlock()
   332  
   333  	// Short circuit if the txlookup already in the cache, retrieve otherwise
   334  	if item, exist := bc.txLookupCache.Get(hash); exist {
   335  		return item.lookup, item.transaction
   336  	}
   337  	tx, blockHash, blockNumber, txIndex := rawdb.ReadCanonicalTransaction(bc.db, hash)
   338  	if tx == nil {
   339  		return nil, nil
   340  	}
   341  	lookup := &rawdb.LegacyTxLookupEntry{
   342  		BlockHash:  blockHash,
   343  		BlockIndex: blockNumber,
   344  		Index:      txIndex,
   345  	}
   346  	bc.txLookupCache.Add(hash, txLookup{
   347  		lookup:      lookup,
   348  		transaction: tx,
   349  	})
   350  	return lookup, tx
   351  }
   352  
   353  // TxIndexDone returns true if the transaction indexer has finished indexing.
   354  func (bc *BlockChain) TxIndexDone() bool {
   355  	progress, err := bc.TxIndexProgress()
   356  	if err != nil {
   357  		// No error is returned if the transaction indexing progress is unreachable
   358  		// due to unexpected internal errors. In such cases, it is impossible to
   359  		// determine whether the transaction does not exist or has simply not been
   360  		// indexed yet without a progress marker.
   361  		//
   362  		// In such scenarios, the transaction is treated as unreachable, though
   363  		// this is clearly an unintended and unexpected situation.
   364  		return true
   365  	}
   366  	return progress.Done()
   367  }
   368  
   369  // HasState checks if state trie is fully present in the database or not.
   370  func (bc *BlockChain) HasState(hash common.Hash) bool {
   371  	_, err := bc.statedb.OpenTrie(hash)
   372  	return err == nil
   373  }
   374  
   375  // HasBlockAndState checks if a block and associated state trie is fully present
   376  // in the database or not, caching it if present.
   377  func (bc *BlockChain) HasBlockAndState(hash common.Hash, number uint64) bool {
   378  	// Check first that the block itself is known
   379  	block := bc.GetBlock(hash, number)
   380  	if block == nil {
   381  		return false
   382  	}
   383  	return bc.HasState(block.Root())
   384  }
   385  
   386  // stateRecoverable checks if the specified state is recoverable.
   387  // Note, this function assumes the state is not present, because
   388  // state is not treated as recoverable if it's available, thus
   389  // false will be returned in this case.
   390  func (bc *BlockChain) stateRecoverable(root common.Hash) bool {
   391  	if bc.triedb.Scheme() == rawdb.HashScheme {
   392  		return false
   393  	}
   394  	result, _ := bc.triedb.Recoverable(root)
   395  	return result
   396  }
   397  
   398  // ContractCodeWithPrefix retrieves a blob of data associated with a contract
   399  // hash either from ephemeral in-memory cache, or from persistent storage.
   400  func (bc *BlockChain) ContractCodeWithPrefix(hash common.Hash) []byte {
   401  	// TODO(rjl493456442) The associated account address is also required
   402  	// in Verkle scheme. Fix it once snap-sync is supported for Verkle.
   403  	return bc.statedb.ContractCodeWithPrefix(common.Address{}, hash)
   404  }
   405  
   406  // State returns a new mutable state based on the current HEAD block.
   407  func (bc *BlockChain) State() (*state.StateDB, error) {
   408  	return bc.StateAt(bc.CurrentBlock().Root)
   409  }
   410  
   411  // StateAt returns a new mutable state based on a particular point in time.
   412  func (bc *BlockChain) StateAt(root common.Hash) (*state.StateDB, error) {
   413  	return state.New(root, bc.statedb)
   414  }
   415  
   416  // HistoricState returns a historic state specified by the given root.
   417  // Live states are not available and won't be served, please use `State`
   418  // or `StateAt` instead.
   419  func (bc *BlockChain) HistoricState(root common.Hash) (*state.StateDB, error) {
   420  	return state.New(root, state.NewHistoricDatabase(bc.db, bc.triedb))
   421  }
   422  
   423  // Config retrieves the chain's fork configuration.
   424  func (bc *BlockChain) Config() *params.ChainConfig { return bc.chainConfig }
   425  
   426  // Engine retrieves the blockchain's consensus engine.
   427  func (bc *BlockChain) Engine() consensus.Engine { return bc.engine }
   428  
   429  // Snapshots returns the blockchain snapshot tree.
   430  func (bc *BlockChain) Snapshots() *snapshot.Tree {
   431  	return bc.snaps
   432  }
   433  
   434  // Validator returns the current validator.
   435  func (bc *BlockChain) Validator() Validator {
   436  	return bc.validator
   437  }
   438  
   439  // Processor returns the current processor.
   440  func (bc *BlockChain) Processor() Processor {
   441  	return bc.processor
   442  }
   443  
   444  // StateCache returns the caching database underpinning the blockchain instance.
   445  func (bc *BlockChain) StateCache() state.Database {
   446  	return bc.statedb
   447  }
   448  
   449  // GasLimit returns the gas limit of the current HEAD block.
   450  func (bc *BlockChain) GasLimit() uint64 {
   451  	return bc.CurrentBlock().GasLimit
   452  }
   453  
   454  // Genesis retrieves the chain's genesis block.
   455  func (bc *BlockChain) Genesis() *types.Block {
   456  	return bc.genesisBlock
   457  }
   458  
   459  // GetVMConfig returns the block chain VM config.
   460  func (bc *BlockChain) GetVMConfig() *vm.Config {
   461  	return &bc.cfg.VmConfig
   462  }
   463  
   464  // TxIndexProgress returns the transaction indexing progress.
   465  func (bc *BlockChain) TxIndexProgress() (TxIndexProgress, error) {
   466  	if bc.txIndexer == nil {
   467  		return TxIndexProgress{}, errors.New("tx indexer is not enabled")
   468  	}
   469  	return bc.txIndexer.txIndexProgress(), nil
   470  }
   471  
   472  // StateIndexProgress returns the historical state indexing progress.
   473  func (bc *BlockChain) StateIndexProgress() (uint64, error) {
   474  	return bc.triedb.IndexProgress()
   475  }
   476  
   477  // HistoryPruningCutoff returns the configured history pruning point.
   478  // Blocks before this might not be available in the database.
   479  func (bc *BlockChain) HistoryPruningCutoff() (uint64, common.Hash) {
   480  	pt := bc.historyPrunePoint.Load()
   481  	if pt == nil {
   482  		return 0, bc.genesisBlock.Hash()
   483  	}
   484  	return pt.BlockNumber, pt.BlockHash
   485  }
   486  
   487  // TrieDB retrieves the low level trie database used for data storage.
   488  func (bc *BlockChain) TrieDB() *triedb.Database {
   489  	return bc.triedb
   490  }
   491  
   492  // HeaderChain returns the underlying header chain.
   493  func (bc *BlockChain) HeaderChain() *HeaderChain {
   494  	return bc.hc
   495  }
   496  
   497  // SubscribeRemovedLogsEvent registers a subscription of RemovedLogsEvent.
   498  func (bc *BlockChain) SubscribeRemovedLogsEvent(ch chan<- RemovedLogsEvent) event.Subscription {
   499  	return bc.scope.Track(bc.rmLogsFeed.Subscribe(ch))
   500  }
   501  
   502  // SubscribeChainEvent registers a subscription of ChainEvent.
   503  func (bc *BlockChain) SubscribeChainEvent(ch chan<- ChainEvent) event.Subscription {
   504  	return bc.scope.Track(bc.chainFeed.Subscribe(ch))
   505  }
   506  
   507  // SubscribeChainHeadEvent registers a subscription of ChainHeadEvent.
   508  func (bc *BlockChain) SubscribeChainHeadEvent(ch chan<- ChainHeadEvent) event.Subscription {
   509  	return bc.scope.Track(bc.chainHeadFeed.Subscribe(ch))
   510  }
   511  
   512  // SubscribeLogsEvent registers a subscription of []*types.Log.
   513  func (bc *BlockChain) SubscribeLogsEvent(ch chan<- []*types.Log) event.Subscription {
   514  	return bc.scope.Track(bc.logsFeed.Subscribe(ch))
   515  }
   516  
   517  // SubscribeBlockProcessingEvent registers a subscription of bool where true means
   518  // block processing has started while false means it has stopped.
   519  func (bc *BlockChain) SubscribeBlockProcessingEvent(ch chan<- bool) event.Subscription {
   520  	return bc.scope.Track(bc.blockProcFeed.Subscribe(ch))
   521  }