github.com/MetalBlockchain/subnet-evm@v0.6.3/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  	"math/big"
    34  
    35  	"github.com/MetalBlockchain/subnet-evm/consensus/misc/eip4844"
    36  	"github.com/MetalBlockchain/subnet-evm/core/types"
    37  	"github.com/MetalBlockchain/subnet-evm/params"
    38  	"github.com/ethereum/go-ethereum/common"
    39  	"github.com/ethereum/go-ethereum/ethdb"
    40  	"github.com/ethereum/go-ethereum/log"
    41  	"github.com/ethereum/go-ethereum/rlp"
    42  )
    43  
    44  // ReadCanonicalHash retrieves the hash assigned to a canonical block number.
    45  func ReadCanonicalHash(db ethdb.Reader, number uint64) common.Hash {
    46  	data, _ := db.Get(headerHashKey(number))
    47  	if len(data) == 0 {
    48  		return common.Hash{}
    49  	}
    50  	return common.BytesToHash(data)
    51  }
    52  
    53  // WriteCanonicalHash stores the hash assigned to a canonical block number.
    54  func WriteCanonicalHash(db ethdb.KeyValueWriter, hash common.Hash, number uint64) {
    55  	if err := db.Put(headerHashKey(number), hash.Bytes()); err != nil {
    56  		log.Crit("Failed to store number to hash mapping", "err", err)
    57  	}
    58  }
    59  
    60  // DeleteCanonicalHash removes the number to hash canonical mapping.
    61  func DeleteCanonicalHash(db ethdb.KeyValueWriter, number uint64) {
    62  	if err := db.Delete(headerHashKey(number)); err != nil {
    63  		log.Crit("Failed to delete number to hash mapping", "err", err)
    64  	}
    65  }
    66  
    67  // ReadAllHashes retrieves all the hashes assigned to blocks at a certain heights,
    68  // both canonical and reorged forks included.
    69  func ReadAllHashes(db ethdb.Iteratee, number uint64) []common.Hash {
    70  	prefix := headerKeyPrefix(number)
    71  
    72  	hashes := make([]common.Hash, 0, 1)
    73  	it := db.NewIterator(prefix, nil)
    74  	defer it.Release()
    75  
    76  	for it.Next() {
    77  		if key := it.Key(); len(key) == len(prefix)+32 {
    78  			hashes = append(hashes, common.BytesToHash(key[len(key)-32:]))
    79  		}
    80  	}
    81  	return hashes
    82  }
    83  
    84  type NumberHash struct {
    85  	Number uint64
    86  	Hash   common.Hash
    87  }
    88  
    89  // ReadAllHashesInRange retrieves all the hashes assigned to blocks at certain
    90  // heights, both canonical and reorged forks included.
    91  // This method considers both limits to be _inclusive_.
    92  func ReadAllHashesInRange(db ethdb.Iteratee, first, last uint64) []*NumberHash {
    93  	var (
    94  		start     = encodeBlockNumber(first)
    95  		keyLength = len(headerPrefix) + 8 + 32
    96  		hashes    = make([]*NumberHash, 0, 1+last-first)
    97  		it        = db.NewIterator(headerPrefix, start)
    98  	)
    99  	defer it.Release()
   100  	for it.Next() {
   101  		key := it.Key()
   102  		if len(key) != keyLength {
   103  			continue
   104  		}
   105  		num := binary.BigEndian.Uint64(key[len(headerPrefix) : len(headerPrefix)+8])
   106  		if num > last {
   107  			break
   108  		}
   109  		hash := common.BytesToHash(key[len(key)-32:])
   110  		hashes = append(hashes, &NumberHash{num, hash})
   111  	}
   112  	return hashes
   113  }
   114  
   115  // ReadAllCanonicalHashes retrieves all canonical number and hash mappings at the
   116  // certain chain range. If the accumulated entries reaches the given threshold,
   117  // abort the iteration and return the semi-finish result.
   118  func ReadAllCanonicalHashes(db ethdb.Iteratee, from uint64, to uint64, limit int) ([]uint64, []common.Hash) {
   119  	// Short circuit if the limit is 0.
   120  	if limit == 0 {
   121  		return nil, nil
   122  	}
   123  	var (
   124  		numbers []uint64
   125  		hashes  []common.Hash
   126  	)
   127  	// Construct the key prefix of start point.
   128  	start, end := headerHashKey(from), headerHashKey(to)
   129  	it := db.NewIterator(nil, start)
   130  	defer it.Release()
   131  
   132  	for it.Next() {
   133  		if bytes.Compare(it.Key(), end) >= 0 {
   134  			break
   135  		}
   136  		if key := it.Key(); len(key) == len(headerPrefix)+8+1 && bytes.Equal(key[len(key)-1:], headerHashSuffix) {
   137  			numbers = append(numbers, binary.BigEndian.Uint64(key[len(headerPrefix):len(headerPrefix)+8]))
   138  			hashes = append(hashes, common.BytesToHash(it.Value()))
   139  			// If the accumulated entries reaches the limit threshold, return.
   140  			if len(numbers) >= limit {
   141  				break
   142  			}
   143  		}
   144  	}
   145  	return numbers, hashes
   146  }
   147  
   148  // ReadHeaderNumber returns the header number assigned to a hash.
   149  func ReadHeaderNumber(db ethdb.KeyValueReader, hash common.Hash) *uint64 {
   150  	data, _ := db.Get(headerNumberKey(hash))
   151  	if len(data) != 8 {
   152  		return nil
   153  	}
   154  	number := binary.BigEndian.Uint64(data)
   155  	return &number
   156  }
   157  
   158  // WriteHeaderNumber stores the hash->number mapping.
   159  func WriteHeaderNumber(db ethdb.KeyValueWriter, hash common.Hash, number uint64) {
   160  	key := headerNumberKey(hash)
   161  	enc := encodeBlockNumber(number)
   162  	if err := db.Put(key, enc); err != nil {
   163  		log.Crit("Failed to store hash to number mapping", "err", err)
   164  	}
   165  }
   166  
   167  // DeleteHeaderNumber removes hash->number mapping.
   168  func DeleteHeaderNumber(db ethdb.KeyValueWriter, hash common.Hash) {
   169  	if err := db.Delete(headerNumberKey(hash)); err != nil {
   170  		log.Crit("Failed to delete hash to number mapping", "err", err)
   171  	}
   172  }
   173  
   174  // ReadHeadHeaderHash retrieves the hash of the current canonical head header.
   175  func ReadHeadHeaderHash(db ethdb.KeyValueReader) common.Hash {
   176  	data, _ := db.Get(headHeaderKey)
   177  	if len(data) == 0 {
   178  		return common.Hash{}
   179  	}
   180  	return common.BytesToHash(data)
   181  }
   182  
   183  // WriteHeadHeaderHash stores the hash of the current canonical head header.
   184  func WriteHeadHeaderHash(db ethdb.KeyValueWriter, hash common.Hash) {
   185  	if err := db.Put(headHeaderKey, hash.Bytes()); err != nil {
   186  		log.Crit("Failed to store last header's hash", "err", err)
   187  	}
   188  }
   189  
   190  // ReadHeadBlockHash retrieves the hash of the current canonical head block.
   191  func ReadHeadBlockHash(db ethdb.KeyValueReader) common.Hash {
   192  	data, _ := db.Get(headBlockKey)
   193  	if len(data) == 0 {
   194  		return common.Hash{}
   195  	}
   196  	return common.BytesToHash(data)
   197  }
   198  
   199  // WriteHeadBlockHash stores the head block's hash.
   200  func WriteHeadBlockHash(db ethdb.KeyValueWriter, hash common.Hash) {
   201  	if err := db.Put(headBlockKey, hash.Bytes()); err != nil {
   202  		log.Crit("Failed to store last block's hash", "err", err)
   203  	}
   204  }
   205  
   206  // ReadHeaderRLP retrieves a block header in its raw RLP database encoding.
   207  func ReadHeaderRLP(db ethdb.Reader, hash common.Hash, number uint64) rlp.RawValue {
   208  	data, _ := db.Get(headerKey(number, hash))
   209  	if len(data) > 0 {
   210  		return data
   211  	}
   212  	return nil
   213  }
   214  
   215  // HasHeader verifies the existence of a block header corresponding to the hash.
   216  func HasHeader(db ethdb.Reader, hash common.Hash, number uint64) bool {
   217  	if has, err := db.Has(headerKey(number, hash)); !has || err != nil {
   218  		return false
   219  	}
   220  	return true
   221  }
   222  
   223  // ReadHeader retrieves the block header corresponding to the hash.
   224  func ReadHeader(db ethdb.Reader, hash common.Hash, number uint64) *types.Header {
   225  	data := ReadHeaderRLP(db, hash, number)
   226  	if len(data) == 0 {
   227  		return nil
   228  	}
   229  	header := new(types.Header)
   230  	if err := rlp.Decode(bytes.NewReader(data), header); err != nil {
   231  		log.Error("Invalid block header RLP", "hash", hash, "err", err)
   232  		return nil
   233  	}
   234  	return header
   235  }
   236  
   237  // WriteHeader stores a block header into the database and also stores the hash-
   238  // to-number mapping.
   239  func WriteHeader(db ethdb.KeyValueWriter, header *types.Header) {
   240  	var (
   241  		hash   = header.Hash()
   242  		number = header.Number.Uint64()
   243  	)
   244  	// Write the hash -> number mapping
   245  	WriteHeaderNumber(db, hash, number)
   246  
   247  	// Write the encoded header
   248  	data, err := rlp.EncodeToBytes(header)
   249  	if err != nil {
   250  		log.Crit("Failed to RLP encode header", "err", err)
   251  	}
   252  	key := headerKey(number, hash)
   253  	if err := db.Put(key, data); err != nil {
   254  		log.Crit("Failed to store header", "err", err)
   255  	}
   256  }
   257  
   258  // DeleteHeader removes all block header data associated with a hash.
   259  func DeleteHeader(db ethdb.KeyValueWriter, hash common.Hash, number uint64) {
   260  	deleteHeaderWithoutNumber(db, hash, number)
   261  	if err := db.Delete(headerNumberKey(hash)); err != nil {
   262  		log.Crit("Failed to delete hash to number mapping", "err", err)
   263  	}
   264  }
   265  
   266  // deleteHeaderWithoutNumber removes only the block header but does not remove
   267  // the hash to number mapping.
   268  func deleteHeaderWithoutNumber(db ethdb.KeyValueWriter, hash common.Hash, number uint64) {
   269  	if err := db.Delete(headerKey(number, hash)); err != nil {
   270  		log.Crit("Failed to delete header", "err", err)
   271  	}
   272  }
   273  
   274  // ReadBodyRLP retrieves the block body (transactions and uncles) in RLP encoding.
   275  func ReadBodyRLP(db ethdb.Reader, hash common.Hash, number uint64) rlp.RawValue {
   276  	data, _ := db.Get(blockBodyKey(number, hash))
   277  	if len(data) > 0 {
   278  		return data
   279  	}
   280  	return nil
   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  	data, _ := db.Get(blockReceiptsKey(number, hash))
   351  	if len(data) > 0 {
   352  		return data
   353  	}
   354  	return nil
   355  }
   356  
   357  // ReadRawReceipts retrieves all the transaction receipts belonging to a block.
   358  // The receipt metadata fields are not guaranteed to be populated, so they
   359  // should not be used. Use ReadReceipts instead if the metadata is needed.
   360  func ReadRawReceipts(db ethdb.Reader, hash common.Hash, number uint64) types.Receipts {
   361  	// Retrieve the flattened receipt slice
   362  	data := ReadReceiptsRLP(db, hash, number)
   363  	if len(data) == 0 {
   364  		return nil
   365  	}
   366  	// Convert the receipts from their storage form to their internal representation
   367  	storageReceipts := []*types.ReceiptForStorage{}
   368  	if err := rlp.DecodeBytes(data, &storageReceipts); err != nil {
   369  		log.Error("Invalid receipt array RLP", "hash", hash, "err", err)
   370  		return nil
   371  	}
   372  	receipts := make(types.Receipts, len(storageReceipts))
   373  	for i, storageReceipt := range storageReceipts {
   374  		receipts[i] = (*types.Receipt)(storageReceipt)
   375  	}
   376  	return receipts
   377  }
   378  
   379  // ReadReceipts retrieves all the transaction receipts belonging to a block, including
   380  // its corresponding metadata fields. If it is unable to populate these metadata
   381  // fields then nil is returned.
   382  //
   383  // The current implementation populates these metadata fields by reading the receipts'
   384  // corresponding block body, so if the block body is not found it will return nil even
   385  // if the receipt itself is stored.
   386  func ReadReceipts(db ethdb.Reader, hash common.Hash, number uint64, time uint64, config *params.ChainConfig) types.Receipts {
   387  	// We're deriving many fields from the block body, retrieve beside the receipt
   388  	receipts := ReadRawReceipts(db, hash, number)
   389  	if receipts == nil {
   390  		return nil
   391  	}
   392  	body := ReadBody(db, hash, number)
   393  	if body == nil {
   394  		log.Error("Missing body but have receipt", "hash", hash, "number", number)
   395  		return nil
   396  	}
   397  	header := ReadHeader(db, hash, number)
   398  
   399  	var baseFee *big.Int
   400  	if header == nil {
   401  		baseFee = big.NewInt(0)
   402  	} else {
   403  		baseFee = header.BaseFee
   404  	}
   405  	// Compute effective blob gas price.
   406  	var blobGasPrice *big.Int
   407  	if header != nil && header.ExcessBlobGas != nil {
   408  		blobGasPrice = eip4844.CalcBlobFee(*header.ExcessBlobGas)
   409  	}
   410  	if err := receipts.DeriveFields(config, hash, number, time, baseFee, blobGasPrice, body.Transactions); err != nil {
   411  		log.Error("Failed to derive block receipts fields", "hash", hash, "number", number, "err", err)
   412  		return nil
   413  	}
   414  	return receipts
   415  }
   416  
   417  // WriteReceipts stores all the transaction receipts belonging to a block.
   418  func WriteReceipts(db ethdb.KeyValueWriter, hash common.Hash, number uint64, receipts types.Receipts) {
   419  	// Convert the receipts into their storage form and serialize them
   420  	storageReceipts := make([]*types.ReceiptForStorage, len(receipts))
   421  	for i, receipt := range receipts {
   422  		storageReceipts[i] = (*types.ReceiptForStorage)(receipt)
   423  	}
   424  	bytes, err := rlp.EncodeToBytes(storageReceipts)
   425  	if err != nil {
   426  		log.Crit("Failed to encode block receipts", "err", err)
   427  	}
   428  	// Store the flattened receipt slice
   429  	if err := db.Put(blockReceiptsKey(number, hash), bytes); err != nil {
   430  		log.Crit("Failed to store block receipts", "err", err)
   431  	}
   432  }
   433  
   434  // DeleteReceipts removes all receipt data associated with a block hash.
   435  func DeleteReceipts(db ethdb.KeyValueWriter, hash common.Hash, number uint64) {
   436  	if err := db.Delete(blockReceiptsKey(number, hash)); err != nil {
   437  		log.Crit("Failed to delete block receipts", "err", err)
   438  	}
   439  }
   440  
   441  // storedReceiptRLP is the storage encoding of a receipt.
   442  // Re-definition in core/types/receipt.go.
   443  // TODO: Re-use the existing definition.
   444  type storedReceiptRLP struct {
   445  	PostStateOrStatus []byte
   446  	CumulativeGasUsed uint64
   447  	Logs              []*types.Log
   448  }
   449  
   450  // ReceiptLogs is a barebone version of ReceiptForStorage which only keeps
   451  // the list of logs. When decoding a stored receipt into this object we
   452  // avoid creating the bloom filter.
   453  type receiptLogs struct {
   454  	Logs []*types.Log
   455  }
   456  
   457  // DecodeRLP implements rlp.Decoder.
   458  func (r *receiptLogs) DecodeRLP(s *rlp.Stream) error {
   459  	var stored storedReceiptRLP
   460  	if err := s.Decode(&stored); err != nil {
   461  		return err
   462  	}
   463  	r.Logs = stored.Logs
   464  	return nil
   465  }
   466  
   467  // DeriveLogFields fills the logs in receiptLogs with information such as block number, txhash, etc.
   468  func deriveLogFields(receipts []*receiptLogs, hash common.Hash, number uint64, txs types.Transactions) error {
   469  	logIndex := uint(0)
   470  	if len(txs) != len(receipts) {
   471  		return errors.New("transaction and receipt count mismatch")
   472  	}
   473  	for i := 0; i < len(receipts); i++ {
   474  		txHash := txs[i].Hash()
   475  		// The derived log fields can simply be set from the block and transaction
   476  		for j := 0; j < len(receipts[i].Logs); j++ {
   477  			receipts[i].Logs[j].BlockNumber = number
   478  			receipts[i].Logs[j].BlockHash = hash
   479  			receipts[i].Logs[j].TxHash = txHash
   480  			receipts[i].Logs[j].TxIndex = uint(i)
   481  			receipts[i].Logs[j].Index = logIndex
   482  			logIndex++
   483  		}
   484  	}
   485  	return nil
   486  }
   487  
   488  // ReadLogs retrieves the logs for all transactions in a block. In case
   489  // receipts is not found, a nil is returned.
   490  // Note: ReadLogs does not derive unstored log fields.
   491  func ReadLogs(db ethdb.Reader, hash common.Hash, number uint64) [][]*types.Log {
   492  	// Retrieve the flattened receipt slice
   493  	data := ReadReceiptsRLP(db, hash, number)
   494  	if len(data) == 0 {
   495  		return nil
   496  	}
   497  	receipts := []*receiptLogs{}
   498  	if err := rlp.DecodeBytes(data, &receipts); err != nil {
   499  		log.Error("Invalid receipt array RLP", "hash", hash, "err", err)
   500  		return nil
   501  	}
   502  
   503  	logs := make([][]*types.Log, len(receipts))
   504  	for i, receipt := range receipts {
   505  		logs[i] = receipt.Logs
   506  	}
   507  	return logs
   508  }
   509  
   510  // ReadBlock retrieves an entire block corresponding to the hash, assembling it
   511  // back from the stored header and body. If either the header or body could not
   512  // be retrieved nil is returned.
   513  //
   514  // Note, due to concurrent download of header and block body the header and thus
   515  // canonical hash can be stored in the database but the body data not (yet).
   516  func ReadBlock(db ethdb.Reader, hash common.Hash, number uint64) *types.Block {
   517  	header := ReadHeader(db, hash, number)
   518  	if header == nil {
   519  		return nil
   520  	}
   521  	body := ReadBody(db, hash, number)
   522  	if body == nil {
   523  		return nil
   524  	}
   525  	return types.NewBlockWithHeader(header).WithBody(body.Transactions, body.Uncles)
   526  }
   527  
   528  // WriteBlock serializes a block into the database, header and body separately.
   529  func WriteBlock(db ethdb.KeyValueWriter, block *types.Block) {
   530  	WriteBody(db, block.Hash(), block.NumberU64(), block.Body())
   531  	WriteHeader(db, block.Header())
   532  }
   533  
   534  // DeleteBlock removes all block data associated with a hash.
   535  func DeleteBlock(db ethdb.KeyValueWriter, hash common.Hash, number uint64) {
   536  	DeleteReceipts(db, hash, number)
   537  	DeleteHeader(db, hash, number)
   538  	DeleteBody(db, hash, number)
   539  }
   540  
   541  // DeleteBlockWithoutNumber removes all block data associated with a hash, except
   542  // the hash to number mapping.
   543  func DeleteBlockWithoutNumber(db ethdb.KeyValueWriter, hash common.Hash, number uint64) {
   544  	DeleteReceipts(db, hash, number)
   545  	deleteHeaderWithoutNumber(db, hash, number)
   546  	DeleteBody(db, hash, number)
   547  }
   548  
   549  // FindCommonAncestor returns the last common ancestor of two block headers
   550  func FindCommonAncestor(db ethdb.Reader, a, b *types.Header) *types.Header {
   551  	for bn := b.Number.Uint64(); a.Number.Uint64() > bn; {
   552  		a = ReadHeader(db, a.ParentHash, a.Number.Uint64()-1)
   553  		if a == nil {
   554  			return nil
   555  		}
   556  	}
   557  	for an := a.Number.Uint64(); an < b.Number.Uint64(); {
   558  		b = ReadHeader(db, b.ParentHash, b.Number.Uint64()-1)
   559  		if b == nil {
   560  			return nil
   561  		}
   562  	}
   563  	for a.Hash() != b.Hash() {
   564  		a = ReadHeader(db, a.ParentHash, a.Number.Uint64()-1)
   565  		if a == nil {
   566  			return nil
   567  		}
   568  		b = ReadHeader(db, b.ParentHash, b.Number.Uint64()-1)
   569  		if b == nil {
   570  			return nil
   571  		}
   572  	}
   573  	return a
   574  }
   575  
   576  // ReadHeadBlock returns the current canonical head block.
   577  func ReadHeadBlock(db ethdb.Reader) *types.Block {
   578  	headBlockHash := ReadHeadBlockHash(db)
   579  	if headBlockHash == (common.Hash{}) {
   580  		return nil
   581  	}
   582  	headBlockNumber := ReadHeaderNumber(db, headBlockHash)
   583  	if headBlockNumber == nil {
   584  		return nil
   585  	}
   586  	return ReadBlock(db, headBlockHash, *headBlockNumber)
   587  }
   588  
   589  // ReadTxIndexTail retrieves the number of oldest indexed block
   590  // whose transaction indices has been indexed.
   591  func ReadTxIndexTail(db ethdb.KeyValueReader) *uint64 {
   592  	data, _ := db.Get(txIndexTailKey)
   593  	if len(data) != 8 {
   594  		return nil
   595  	}
   596  	number := binary.BigEndian.Uint64(data)
   597  	return &number
   598  }
   599  
   600  // WriteTxIndexTail stores the number of oldest indexed block
   601  // into database.
   602  func WriteTxIndexTail(db ethdb.KeyValueWriter, number uint64) {
   603  	if err := db.Put(txIndexTailKey, encodeBlockNumber(number)); err != nil {
   604  		log.Crit("Failed to store the transaction index tail", "err", err)
   605  	}
   606  }