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