github.com/MetalBlockchain/subnet-evm@v0.4.9/core/rawdb/accessors_chain.go (about)

     1  // (c) 2019-2020, Ava Labs, Inc.
     2  //
     3  // This file is a derived work, based on the go-ethereum library whose original
     4  // notices appear below.
     5  //
     6  // It is distributed under a license compatible with the licensing terms of the
     7  // original code from which it is derived.
     8  //
     9  // Much love to the original authors for their work.
    10  // **********
    11  // Copyright 2018 The go-ethereum Authors
    12  // This file is part of the go-ethereum library.
    13  //
    14  // The go-ethereum library is free software: you can redistribute it and/or modify
    15  // it under the terms of the GNU Lesser General Public License as published by
    16  // the Free Software Foundation, either version 3 of the License, or
    17  // (at your option) any later version.
    18  //
    19  // The go-ethereum library is distributed in the hope that it will be useful,
    20  // but WITHOUT ANY WARRANTY; without even the implied warranty of
    21  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    22  // GNU Lesser General Public License for more details.
    23  //
    24  // You should have received a copy of the GNU Lesser General Public License
    25  // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
    26  
    27  package rawdb
    28  
    29  import (
    30  	"bytes"
    31  	"encoding/binary"
    32  	"errors"
    33  
    34  	"github.com/MetalBlockchain/subnet-evm/core/types"
    35  	"github.com/MetalBlockchain/subnet-evm/ethdb"
    36  	"github.com/MetalBlockchain/subnet-evm/params"
    37  	"github.com/ethereum/go-ethereum/common"
    38  	"github.com/ethereum/go-ethereum/log"
    39  	"github.com/ethereum/go-ethereum/rlp"
    40  )
    41  
    42  // ReadCanonicalHash retrieves the hash assigned to a canonical block number.
    43  func ReadCanonicalHash(db ethdb.Reader, number uint64) common.Hash {
    44  	data, _ := db.Get(headerHashKey(number))
    45  	if len(data) == 0 {
    46  		return common.Hash{}
    47  	}
    48  	return common.BytesToHash(data)
    49  }
    50  
    51  // WriteCanonicalHash stores the hash assigned to a canonical block number.
    52  func WriteCanonicalHash(db ethdb.KeyValueWriter, hash common.Hash, number uint64) {
    53  	if err := db.Put(headerHashKey(number), hash.Bytes()); err != nil {
    54  		log.Crit("Failed to store number to hash mapping", "err", err)
    55  	}
    56  }
    57  
    58  // DeleteCanonicalHash removes the number to hash canonical mapping.
    59  func DeleteCanonicalHash(db ethdb.KeyValueWriter, number uint64) {
    60  	if err := db.Delete(headerHashKey(number)); err != nil {
    61  		log.Crit("Failed to delete number to hash mapping", "err", err)
    62  	}
    63  }
    64  
    65  // ReadAllHashes retrieves all the hashes assigned to blocks at a certain heights,
    66  // both canonical and reorged forks included.
    67  func ReadAllHashes(db ethdb.Iteratee, number uint64) []common.Hash {
    68  	prefix := headerKeyPrefix(number)
    69  
    70  	hashes := make([]common.Hash, 0, 1)
    71  	it := db.NewIterator(prefix, nil)
    72  	defer it.Release()
    73  
    74  	for it.Next() {
    75  		if key := it.Key(); len(key) == len(prefix)+32 {
    76  			hashes = append(hashes, common.BytesToHash(key[len(key)-32:]))
    77  		}
    78  	}
    79  	return hashes
    80  }
    81  
    82  type NumberHash struct {
    83  	Number uint64
    84  	Hash   common.Hash
    85  }
    86  
    87  // ReadAllHashesInRange retrieves all the hashes assigned to blocks at a certain
    88  // heights, both canonical and reorged forks included.
    89  // This method considers both limits to be _inclusive_.
    90  func ReadAllHashesInRange(db ethdb.Iteratee, first, last uint64) []*NumberHash {
    91  	var (
    92  		start     = encodeBlockNumber(first)
    93  		keyLength = len(headerPrefix) + 8 + 32
    94  		hashes    = make([]*NumberHash, 0, 1+last-first)
    95  		it        = db.NewIterator(headerPrefix, start)
    96  	)
    97  	defer it.Release()
    98  	for it.Next() {
    99  		key := it.Key()
   100  		if len(key) != keyLength {
   101  			continue
   102  		}
   103  		num := binary.BigEndian.Uint64(key[len(headerPrefix) : len(headerPrefix)+8])
   104  		if num > last {
   105  			break
   106  		}
   107  		hash := common.BytesToHash(key[len(key)-32:])
   108  		hashes = append(hashes, &NumberHash{num, hash})
   109  	}
   110  	return hashes
   111  }
   112  
   113  // ReadAllCanonicalHashes retrieves all canonical number and hash mappings at the
   114  // certain chain range. If the accumulated entries reaches the given threshold,
   115  // abort the iteration and return the semi-finish result.
   116  func ReadAllCanonicalHashes(db ethdb.Iteratee, from uint64, to uint64, limit int) ([]uint64, []common.Hash) {
   117  	// Short circuit if the limit is 0.
   118  	if limit == 0 {
   119  		return nil, nil
   120  	}
   121  	var (
   122  		numbers []uint64
   123  		hashes  []common.Hash
   124  	)
   125  	// Construct the key prefix of start point.
   126  	start, end := headerHashKey(from), headerHashKey(to)
   127  	it := db.NewIterator(nil, start)
   128  	defer it.Release()
   129  
   130  	for it.Next() {
   131  		if bytes.Compare(it.Key(), end) >= 0 {
   132  			break
   133  		}
   134  		if key := it.Key(); len(key) == len(headerPrefix)+8+1 && bytes.Equal(key[len(key)-1:], headerHashSuffix) {
   135  			numbers = append(numbers, binary.BigEndian.Uint64(key[len(headerPrefix):len(headerPrefix)+8]))
   136  			hashes = append(hashes, common.BytesToHash(it.Value()))
   137  			// If the accumulated entries reaches the limit threshold, return.
   138  			if len(numbers) >= limit {
   139  				break
   140  			}
   141  		}
   142  	}
   143  	return numbers, hashes
   144  }
   145  
   146  // ReadHeaderNumber returns the header number assigned to a hash.
   147  func ReadHeaderNumber(db ethdb.KeyValueReader, hash common.Hash) *uint64 {
   148  	data, _ := db.Get(headerNumberKey(hash))
   149  	if len(data) != 8 {
   150  		return nil
   151  	}
   152  	number := binary.BigEndian.Uint64(data)
   153  	return &number
   154  }
   155  
   156  // WriteHeaderNumber stores the hash->number mapping.
   157  func WriteHeaderNumber(db ethdb.KeyValueWriter, hash common.Hash, number uint64) {
   158  	key := headerNumberKey(hash)
   159  	enc := encodeBlockNumber(number)
   160  	if err := db.Put(key, enc); err != nil {
   161  		log.Crit("Failed to store hash to number mapping", "err", err)
   162  	}
   163  }
   164  
   165  // DeleteHeaderNumber removes hash->number mapping.
   166  func DeleteHeaderNumber(db ethdb.KeyValueWriter, hash common.Hash) {
   167  	if err := db.Delete(headerNumberKey(hash)); err != nil {
   168  		log.Crit("Failed to delete hash to number mapping", "err", err)
   169  	}
   170  }
   171  
   172  // ReadHeadHeaderHash retrieves the hash of the current canonical head header.
   173  func ReadHeadHeaderHash(db ethdb.KeyValueReader) common.Hash {
   174  	data, _ := db.Get(headHeaderKey)
   175  	if len(data) == 0 {
   176  		return common.Hash{}
   177  	}
   178  	return common.BytesToHash(data)
   179  }
   180  
   181  // WriteHeadHeaderHash stores the hash of the current canonical head header.
   182  func WriteHeadHeaderHash(db ethdb.KeyValueWriter, hash common.Hash) {
   183  	if err := db.Put(headHeaderKey, hash.Bytes()); err != nil {
   184  		log.Crit("Failed to store last header's hash", "err", err)
   185  	}
   186  }
   187  
   188  // ReadHeadBlockHash retrieves the hash of the current canonical head block.
   189  func ReadHeadBlockHash(db ethdb.KeyValueReader) common.Hash {
   190  	data, _ := db.Get(headBlockKey)
   191  	if len(data) == 0 {
   192  		return common.Hash{}
   193  	}
   194  	return common.BytesToHash(data)
   195  }
   196  
   197  // WriteHeadBlockHash stores the head block's hash.
   198  func WriteHeadBlockHash(db ethdb.KeyValueWriter, hash common.Hash) {
   199  	if err := db.Put(headBlockKey, hash.Bytes()); err != nil {
   200  		log.Crit("Failed to store last block's hash", "err", err)
   201  	}
   202  }
   203  
   204  // ReadHeaderRLP retrieves a block header in its raw RLP database encoding.
   205  func ReadHeaderRLP(db ethdb.Reader, hash common.Hash, number uint64) rlp.RawValue {
   206  	// Then try to look up the data in leveldb.
   207  	data, _ := db.Get(headerKey(number, hash))
   208  	if len(data) > 0 {
   209  		return data
   210  	}
   211  	return nil // Can't find the data anywhere.
   212  }
   213  
   214  // HasHeader verifies the existence of a block header corresponding to the hash.
   215  func HasHeader(db ethdb.Reader, hash common.Hash, number uint64) bool {
   216  	if has, err := db.Has(headerKey(number, hash)); !has || err != nil {
   217  		return false
   218  	}
   219  	return true
   220  }
   221  
   222  // ReadHeader retrieves the block header corresponding to the hash.
   223  func ReadHeader(db ethdb.Reader, hash common.Hash, number uint64) *types.Header {
   224  	data := ReadHeaderRLP(db, hash, number)
   225  	if len(data) == 0 {
   226  		return nil
   227  	}
   228  	header := new(types.Header)
   229  	if err := rlp.Decode(bytes.NewReader(data), header); err != nil {
   230  		log.Error("Invalid block header RLP", "hash", hash, "err", err)
   231  		return nil
   232  	}
   233  	return header
   234  }
   235  
   236  // WriteHeader stores a block header into the database and also stores the hash-
   237  // to-number mapping.
   238  func WriteHeader(db ethdb.KeyValueWriter, header *types.Header) {
   239  	var (
   240  		hash   = header.Hash()
   241  		number = header.Number.Uint64()
   242  	)
   243  	// Write the hash -> number mapping
   244  	WriteHeaderNumber(db, hash, number)
   245  
   246  	// Write the encoded header
   247  	data, err := rlp.EncodeToBytes(header)
   248  	if err != nil {
   249  		log.Crit("Failed to RLP encode header", "err", err)
   250  	}
   251  	key := headerKey(number, hash)
   252  	if err := db.Put(key, data); err != nil {
   253  		log.Crit("Failed to store header", "err", err)
   254  	}
   255  }
   256  
   257  // DeleteHeader removes all block header data associated with a hash.
   258  func DeleteHeader(db ethdb.KeyValueWriter, hash common.Hash, number uint64) {
   259  	deleteHeaderWithoutNumber(db, hash, number)
   260  	if err := db.Delete(headerNumberKey(hash)); err != nil {
   261  		log.Crit("Failed to delete hash to number mapping", "err", err)
   262  	}
   263  }
   264  
   265  // deleteHeaderWithoutNumber removes only the block header but does not remove
   266  // the hash to number mapping.
   267  func deleteHeaderWithoutNumber(db ethdb.KeyValueWriter, hash common.Hash, number uint64) {
   268  	if err := db.Delete(headerKey(number, hash)); err != nil {
   269  		log.Crit("Failed to delete header", "err", err)
   270  	}
   271  }
   272  
   273  // ReadBodyRLP retrieves the block body (transactions and uncles) in RLP encoding.
   274  func ReadBodyRLP(db ethdb.Reader, hash common.Hash, number uint64) rlp.RawValue {
   275  	// Then try to look up the data in leveldb.
   276  	data, _ := db.Get(blockBodyKey(number, hash))
   277  	if len(data) > 0 {
   278  		return data
   279  	}
   280  	return nil // Can't find the data anywhere.
   281  }
   282  
   283  // ReadCanonicalBodyRLP retrieves the block body (transactions and uncles) for the canonical
   284  // block at number, in RLP encoding.
   285  func ReadCanonicalBodyRLP(db ethdb.Reader, number uint64) rlp.RawValue {
   286  	// Need to get the hash
   287  	data, _ := db.Get(blockBodyKey(number, ReadCanonicalHash(db, number)))
   288  	if len(data) > 0 {
   289  		return data
   290  	}
   291  	return nil
   292  }
   293  
   294  // WriteBodyRLP stores an RLP encoded block body into the database.
   295  func WriteBodyRLP(db ethdb.KeyValueWriter, hash common.Hash, number uint64, rlp rlp.RawValue) {
   296  	if err := db.Put(blockBodyKey(number, hash), rlp); err != nil {
   297  		log.Crit("Failed to store block body", "err", err)
   298  	}
   299  }
   300  
   301  // HasBody verifies the existence of a block body corresponding to the hash.
   302  func HasBody(db ethdb.Reader, hash common.Hash, number uint64) bool {
   303  	if has, err := db.Has(blockBodyKey(number, hash)); !has || err != nil {
   304  		return false
   305  	}
   306  	return true
   307  }
   308  
   309  // ReadBody retrieves the block body corresponding to the hash.
   310  func ReadBody(db ethdb.Reader, hash common.Hash, number uint64) *types.Body {
   311  	data := ReadBodyRLP(db, hash, number)
   312  	if len(data) == 0 {
   313  		return nil
   314  	}
   315  	body := new(types.Body)
   316  	if err := rlp.Decode(bytes.NewReader(data), body); err != nil {
   317  		log.Error("Invalid block body RLP", "hash", hash, "err", err)
   318  		return nil
   319  	}
   320  	return body
   321  }
   322  
   323  // WriteBody stores a block body into the database.
   324  func WriteBody(db ethdb.KeyValueWriter, hash common.Hash, number uint64, body *types.Body) {
   325  	data, err := rlp.EncodeToBytes(body)
   326  	if err != nil {
   327  		log.Crit("Failed to RLP encode body", "err", err)
   328  	}
   329  	WriteBodyRLP(db, hash, number, data)
   330  }
   331  
   332  // DeleteBody removes all block body data associated with a hash.
   333  func DeleteBody(db ethdb.KeyValueWriter, hash common.Hash, number uint64) {
   334  	if err := db.Delete(blockBodyKey(number, hash)); err != nil {
   335  		log.Crit("Failed to delete block body", "err", err)
   336  	}
   337  }
   338  
   339  // HasReceipts verifies the existence of all the transaction receipts belonging
   340  // to a block.
   341  func HasReceipts(db ethdb.Reader, hash common.Hash, number uint64) bool {
   342  	if has, err := db.Has(blockReceiptsKey(number, hash)); !has || err != nil {
   343  		return false
   344  	}
   345  	return true
   346  }
   347  
   348  // ReadReceiptsRLP retrieves all the transaction receipts belonging to a block in RLP encoding.
   349  func ReadReceiptsRLP(db ethdb.Reader, hash common.Hash, number uint64) rlp.RawValue {
   350  	// Then try to look up the data in leveldb.
   351  	data, _ := db.Get(blockReceiptsKey(number, hash))
   352  	if len(data) > 0 {
   353  		return data
   354  	}
   355  	return nil // Can't find the data anywhere.
   356  }
   357  
   358  // ReadRawReceipts retrieves all the transaction receipts belonging to a block.
   359  // The receipt metadata fields are not guaranteed to be populated, so they
   360  // should not be used. Use ReadReceipts instead if the metadata is needed.
   361  func ReadRawReceipts(db ethdb.Reader, hash common.Hash, number uint64) types.Receipts {
   362  	// Retrieve the flattened receipt slice
   363  	data := ReadReceiptsRLP(db, hash, number)
   364  	if len(data) == 0 {
   365  		return nil
   366  	}
   367  	// Convert the receipts from their storage form to their internal representation
   368  	storageReceipts := []*types.ReceiptForStorage{}
   369  	if err := rlp.DecodeBytes(data, &storageReceipts); err != nil {
   370  		log.Error("Invalid receipt array RLP", "hash", hash, "err", err)
   371  		return nil
   372  	}
   373  	receipts := make(types.Receipts, len(storageReceipts))
   374  	for i, storageReceipt := range storageReceipts {
   375  		receipts[i] = (*types.Receipt)(storageReceipt)
   376  	}
   377  	return receipts
   378  }
   379  
   380  // ReadReceipts retrieves all the transaction receipts belonging to a block, including
   381  // its corresponding metadata fields. If it is unable to populate these metadata
   382  // fields then nil is returned.
   383  //
   384  // The current implementation populates these metadata fields by reading the receipts'
   385  // corresponding block body, so if the block body is not found it will return nil even
   386  // if the receipt itself is stored.
   387  func ReadReceipts(db ethdb.Reader, hash common.Hash, number uint64, config *params.ChainConfig) types.Receipts {
   388  	// We're deriving many fields from the block body, retrieve beside the receipt
   389  	receipts := ReadRawReceipts(db, hash, number)
   390  	if receipts == nil {
   391  		return nil
   392  	}
   393  	header := ReadHeader(db, hash, number)
   394  	if header == nil {
   395  		return nil
   396  	}
   397  	body := ReadBody(db, hash, number)
   398  	if body == nil {
   399  		log.Error("Missing body but have receipt", "hash", hash, "number", number)
   400  		return nil
   401  	}
   402  	if err := receipts.DeriveFields(config, hash, number, header.Time, body.Transactions); err != nil {
   403  		log.Error("Failed to derive block receipts fields", "hash", hash, "number", number, "err", err)
   404  		return nil
   405  	}
   406  	return receipts
   407  }
   408  
   409  // WriteReceipts stores all the transaction receipts belonging to a block.
   410  func WriteReceipts(db ethdb.KeyValueWriter, hash common.Hash, number uint64, receipts types.Receipts) {
   411  	// Convert the receipts into their storage form and serialize them
   412  	storageReceipts := make([]*types.ReceiptForStorage, len(receipts))
   413  	for i, receipt := range receipts {
   414  		storageReceipts[i] = (*types.ReceiptForStorage)(receipt)
   415  	}
   416  	bytes, err := rlp.EncodeToBytes(storageReceipts)
   417  	if err != nil {
   418  		log.Crit("Failed to encode block receipts", "err", err)
   419  	}
   420  	// Store the flattened receipt slice
   421  	if err := db.Put(blockReceiptsKey(number, hash), bytes); err != nil {
   422  		log.Crit("Failed to store block receipts", "err", err)
   423  	}
   424  }
   425  
   426  // DeleteReceipts removes all receipt data associated with a block hash.
   427  func DeleteReceipts(db ethdb.KeyValueWriter, hash common.Hash, number uint64) {
   428  	if err := db.Delete(blockReceiptsKey(number, hash)); err != nil {
   429  		log.Crit("Failed to delete block receipts", "err", err)
   430  	}
   431  }
   432  
   433  // storedReceiptRLP is the storage encoding of a receipt.
   434  // Re-definition in core/types/receipt.go.
   435  type storedReceiptRLP struct {
   436  	PostStateOrStatus []byte
   437  	CumulativeGasUsed uint64
   438  	Logs              []*types.LogForStorage
   439  }
   440  
   441  // ReceiptLogs is a barebone version of ReceiptForStorage which only keeps
   442  // the list of logs. When decoding a stored receipt into this object we
   443  // avoid creating the bloom filter.
   444  type receiptLogs struct {
   445  	Logs []*types.Log
   446  }
   447  
   448  // DecodeRLP implements rlp.Decoder.
   449  func (r *receiptLogs) DecodeRLP(s *rlp.Stream) error {
   450  	var stored storedReceiptRLP
   451  	if err := s.Decode(&stored); err != nil {
   452  		return err
   453  	}
   454  	r.Logs = make([]*types.Log, len(stored.Logs))
   455  	for i, log := range stored.Logs {
   456  		r.Logs[i] = (*types.Log)(log)
   457  	}
   458  	return nil
   459  }
   460  
   461  // DeriveLogFields fills the logs in receiptLogs with information such as block number, txhash, etc.
   462  func deriveLogFields(receipts []*receiptLogs, hash common.Hash, number uint64, txs types.Transactions) error {
   463  	logIndex := uint(0)
   464  	if len(txs) != len(receipts) {
   465  		return errors.New("transaction and receipt count mismatch")
   466  	}
   467  	for i := 0; i < len(receipts); i++ {
   468  		txHash := txs[i].Hash()
   469  		// The derived log fields can simply be set from the block and transaction
   470  		for j := 0; j < len(receipts[i].Logs); j++ {
   471  			receipts[i].Logs[j].BlockNumber = number
   472  			receipts[i].Logs[j].BlockHash = hash
   473  			receipts[i].Logs[j].TxHash = txHash
   474  			receipts[i].Logs[j].TxIndex = uint(i)
   475  			receipts[i].Logs[j].Index = logIndex
   476  			logIndex++
   477  		}
   478  	}
   479  	return nil
   480  }
   481  
   482  // ReadLogs retrieves the logs for all transactions in a block. The log fields
   483  // are populated with metadata. In case the receipts or the block body
   484  // are not found, a nil is returned.
   485  func ReadLogs(db ethdb.Reader, hash common.Hash, number uint64) [][]*types.Log {
   486  	// Retrieve the flattened receipt slice
   487  	data := ReadReceiptsRLP(db, hash, number)
   488  	if len(data) == 0 {
   489  		return nil
   490  	}
   491  	receipts := []*receiptLogs{}
   492  	if err := rlp.DecodeBytes(data, &receipts); err != nil {
   493  		log.Error("Invalid receipt array RLP", "hash", hash, "err", err)
   494  		return nil
   495  	}
   496  
   497  	body := ReadBody(db, hash, number)
   498  	if body == nil {
   499  		log.Error("Missing body but have receipt", "hash", hash, "number", number)
   500  		return nil
   501  	}
   502  	if err := deriveLogFields(receipts, hash, number, body.Transactions); err != nil {
   503  		log.Error("Failed to derive block receipts fields", "hash", hash, "number", number, "err", err)
   504  		return nil
   505  	}
   506  	logs := make([][]*types.Log, len(receipts))
   507  	for i, receipt := range receipts {
   508  		logs[i] = receipt.Logs
   509  	}
   510  	return logs
   511  }
   512  
   513  // ReadBlock retrieves an entire block corresponding to the hash, assembling it
   514  // back from the stored header and body. If either the header or body could not
   515  // be retrieved nil is returned.
   516  //
   517  // Note, due to concurrent download of header and block body the header and thus
   518  // canonical hash can be stored in the database but the body data not (yet).
   519  func ReadBlock(db ethdb.Reader, hash common.Hash, number uint64) *types.Block {
   520  	header := ReadHeader(db, hash, number)
   521  	if header == nil {
   522  		return nil
   523  	}
   524  	body := ReadBody(db, hash, number)
   525  	if body == nil {
   526  		return nil
   527  	}
   528  	return types.NewBlockWithHeader(header).WithBody(body.Transactions, body.Uncles)
   529  }
   530  
   531  // WriteBlock serializes a block into the database, header and body separately.
   532  func WriteBlock(db ethdb.KeyValueWriter, block *types.Block) {
   533  	WriteBody(db, block.Hash(), block.NumberU64(), block.Body())
   534  	WriteHeader(db, block.Header())
   535  }
   536  
   537  // DeleteBlock removes all block data associated with a hash.
   538  func DeleteBlock(db ethdb.KeyValueWriter, hash common.Hash, number uint64) {
   539  	DeleteReceipts(db, hash, number)
   540  	DeleteHeader(db, hash, number)
   541  	DeleteBody(db, hash, number)
   542  }
   543  
   544  // DeleteBlockWithoutNumber removes all block data associated with a hash, except
   545  // the hash to number mapping.
   546  func DeleteBlockWithoutNumber(db ethdb.KeyValueWriter, hash common.Hash, number uint64) {
   547  	DeleteReceipts(db, hash, number)
   548  	deleteHeaderWithoutNumber(db, hash, number)
   549  	DeleteBody(db, hash, number)
   550  }
   551  
   552  // FindCommonAncestor returns the last common ancestor of two block headers
   553  func FindCommonAncestor(db ethdb.Reader, a, b *types.Header) *types.Header {
   554  	for bn := b.Number.Uint64(); a.Number.Uint64() > bn; {
   555  		a = ReadHeader(db, a.ParentHash, a.Number.Uint64()-1)
   556  		if a == nil {
   557  			return nil
   558  		}
   559  	}
   560  	for an := a.Number.Uint64(); an < b.Number.Uint64(); {
   561  		b = ReadHeader(db, b.ParentHash, b.Number.Uint64()-1)
   562  		if b == nil {
   563  			return nil
   564  		}
   565  	}
   566  	for a.Hash() != b.Hash() {
   567  		a = ReadHeader(db, a.ParentHash, a.Number.Uint64()-1)
   568  		if a == nil {
   569  			return nil
   570  		}
   571  		b = ReadHeader(db, b.ParentHash, b.Number.Uint64()-1)
   572  		if b == nil {
   573  			return nil
   574  		}
   575  	}
   576  	return a
   577  }
   578  
   579  // ReadHeadBlock returns the current canonical head block.
   580  func ReadHeadBlock(db ethdb.Reader) *types.Block {
   581  	headBlockHash := ReadHeadBlockHash(db)
   582  	if headBlockHash == (common.Hash{}) {
   583  		return nil
   584  	}
   585  	headBlockNumber := ReadHeaderNumber(db, headBlockHash)
   586  	if headBlockNumber == nil {
   587  		return nil
   588  	}
   589  	return ReadBlock(db, headBlockHash, *headBlockNumber)
   590  }
   591  
   592  // ReadTxIndexTail retrieves the number of oldest indexed block
   593  // whose transaction indices has been indexed. If the corresponding entry
   594  // is non-existent in database it means the indexing has been finished.
   595  func ReadTxIndexTail(db ethdb.KeyValueReader) *uint64 {
   596  	data, _ := db.Get(txIndexTailKey)
   597  	if len(data) != 8 {
   598  		return nil
   599  	}
   600  	number := binary.BigEndian.Uint64(data)
   601  	return &number
   602  }
   603  
   604  // WriteTxIndexTail stores the number of oldest indexed block
   605  // into database.
   606  func WriteTxIndexTail(db ethdb.KeyValueWriter, number uint64) {
   607  	if err := db.Put(txIndexTailKey, encodeBlockNumber(number)); err != nil {
   608  		log.Crit("Failed to store the transaction index tail", "err", err)
   609  	}
   610  }