github.com/ethereum/go-ethereum@v1.16.1/core/rawdb/accessors_chain.go (about)

     1  // Copyright 2018 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 rawdb
    18  
    19  import (
    20  	"bytes"
    21  	"encoding/binary"
    22  	"fmt"
    23  	"math/big"
    24  	"slices"
    25  
    26  	"github.com/ethereum/go-ethereum/common"
    27  	"github.com/ethereum/go-ethereum/consensus/misc/eip4844"
    28  	"github.com/ethereum/go-ethereum/core/types"
    29  	"github.com/ethereum/go-ethereum/crypto"
    30  	"github.com/ethereum/go-ethereum/ethdb"
    31  	"github.com/ethereum/go-ethereum/log"
    32  	"github.com/ethereum/go-ethereum/params"
    33  	"github.com/ethereum/go-ethereum/rlp"
    34  )
    35  
    36  // ReadCanonicalHash retrieves the hash assigned to a canonical block number.
    37  func ReadCanonicalHash(db ethdb.Reader, number uint64) common.Hash {
    38  	var data []byte
    39  	db.ReadAncients(func(reader ethdb.AncientReaderOp) error {
    40  		data, _ = reader.Ancient(ChainFreezerHashTable, number)
    41  		if len(data) == 0 {
    42  			// Get it by hash from leveldb
    43  			data, _ = db.Get(headerHashKey(number))
    44  		}
    45  		return nil
    46  	})
    47  	return common.BytesToHash(data)
    48  }
    49  
    50  // WriteCanonicalHash stores the hash assigned to a canonical block number.
    51  func WriteCanonicalHash(db ethdb.KeyValueWriter, hash common.Hash, number uint64) {
    52  	if err := db.Put(headerHashKey(number), hash.Bytes()); err != nil {
    53  		log.Crit("Failed to store number to hash mapping", "err", err)
    54  	}
    55  }
    56  
    57  // DeleteCanonicalHash removes the number to hash canonical mapping.
    58  func DeleteCanonicalHash(db ethdb.KeyValueWriter, number uint64) {
    59  	if err := db.Delete(headerHashKey(number)); err != nil {
    60  		log.Crit("Failed to delete number to hash mapping", "err", err)
    61  	}
    62  }
    63  
    64  // ReadAllHashes retrieves all the hashes assigned to blocks at a certain heights,
    65  // both canonical and reorged forks included.
    66  func ReadAllHashes(db ethdb.Iteratee, number uint64) []common.Hash {
    67  	prefix := headerKeyPrefix(number)
    68  
    69  	hashes := make([]common.Hash, 0, 1)
    70  	it := db.NewIterator(prefix, nil)
    71  	defer it.Release()
    72  
    73  	for it.Next() {
    74  		if key := it.Key(); len(key) == len(prefix)+32 {
    75  			hashes = append(hashes, common.BytesToHash(key[len(key)-32:]))
    76  		}
    77  	}
    78  	return hashes
    79  }
    80  
    81  type NumberHash struct {
    82  	Number uint64
    83  	Hash   common.Hash
    84  }
    85  
    86  // ReadAllHashesInRange retrieves all the hashes assigned to blocks at certain
    87  // heights, both canonical and reorged forks included.
    88  // This method considers both limits to be _inclusive_.
    89  func ReadAllHashesInRange(db ethdb.Iteratee, first, last uint64) []*NumberHash {
    90  	var (
    91  		start     = encodeBlockNumber(first)
    92  		keyLength = len(headerPrefix) + 8 + 32
    93  		hashes    = make([]*NumberHash, 0, 1+last-first)
    94  		it        = db.NewIterator(headerPrefix, start)
    95  	)
    96  	defer it.Release()
    97  	for it.Next() {
    98  		key := it.Key()
    99  		if len(key) != keyLength {
   100  			continue
   101  		}
   102  		num := binary.BigEndian.Uint64(key[len(headerPrefix) : len(headerPrefix)+8])
   103  		if num > last {
   104  			break
   105  		}
   106  		hash := common.BytesToHash(key[len(key)-32:])
   107  		hashes = append(hashes, &NumberHash{num, hash})
   108  	}
   109  	return hashes
   110  }
   111  
   112  // ReadAllCanonicalHashes retrieves all canonical number and hash mappings at the
   113  // certain chain range. If the accumulated entries reaches the given threshold,
   114  // abort the iteration and return the semi-finish result.
   115  func ReadAllCanonicalHashes(db ethdb.Iteratee, from uint64, to uint64, limit int) ([]uint64, []common.Hash) {
   116  	// Short circuit if the limit is 0.
   117  	if limit == 0 {
   118  		return nil, nil
   119  	}
   120  	var (
   121  		numbers []uint64
   122  		hashes  []common.Hash
   123  	)
   124  	// Construct the key prefix of start point.
   125  	start, end := headerHashKey(from), headerHashKey(to)
   126  	it := db.NewIterator(nil, start)
   127  	defer it.Release()
   128  
   129  	for it.Next() {
   130  		if bytes.Compare(it.Key(), end) >= 0 {
   131  			break
   132  		}
   133  		if key := it.Key(); len(key) == len(headerPrefix)+8+1 && bytes.Equal(key[len(key)-1:], headerHashSuffix) {
   134  			numbers = append(numbers, binary.BigEndian.Uint64(key[len(headerPrefix):len(headerPrefix)+8]))
   135  			hashes = append(hashes, common.BytesToHash(it.Value()))
   136  			// If the accumulated entries reaches the limit threshold, return.
   137  			if len(numbers) >= limit {
   138  				break
   139  			}
   140  		}
   141  	}
   142  	return numbers, hashes
   143  }
   144  
   145  // ReadHeaderNumber returns the header number assigned to a hash.
   146  func ReadHeaderNumber(db ethdb.KeyValueReader, hash common.Hash) *uint64 {
   147  	data, _ := db.Get(headerNumberKey(hash))
   148  	if len(data) != 8 {
   149  		return nil
   150  	}
   151  	number := binary.BigEndian.Uint64(data)
   152  	return &number
   153  }
   154  
   155  // WriteHeaderNumber stores the hash->number mapping.
   156  func WriteHeaderNumber(db ethdb.KeyValueWriter, hash common.Hash, number uint64) {
   157  	key := headerNumberKey(hash)
   158  	enc := encodeBlockNumber(number)
   159  	if err := db.Put(key, enc); err != nil {
   160  		log.Crit("Failed to store hash to number mapping", "err", err)
   161  	}
   162  }
   163  
   164  // DeleteHeaderNumber removes hash->number mapping.
   165  func DeleteHeaderNumber(db ethdb.KeyValueWriter, hash common.Hash) {
   166  	if err := db.Delete(headerNumberKey(hash)); err != nil {
   167  		log.Crit("Failed to delete hash to number mapping", "err", err)
   168  	}
   169  }
   170  
   171  // ReadHeadHeaderHash retrieves the hash of the current canonical head header.
   172  func ReadHeadHeaderHash(db ethdb.KeyValueReader) common.Hash {
   173  	data, _ := db.Get(headHeaderKey)
   174  	if len(data) == 0 {
   175  		return common.Hash{}
   176  	}
   177  	return common.BytesToHash(data)
   178  }
   179  
   180  // WriteHeadHeaderHash stores the hash of the current canonical head header.
   181  func WriteHeadHeaderHash(db ethdb.KeyValueWriter, hash common.Hash) {
   182  	if err := db.Put(headHeaderKey, hash.Bytes()); err != nil {
   183  		log.Crit("Failed to store last header's hash", "err", err)
   184  	}
   185  }
   186  
   187  // ReadHeadBlockHash retrieves the hash of the current canonical head block.
   188  func ReadHeadBlockHash(db ethdb.KeyValueReader) common.Hash {
   189  	data, _ := db.Get(headBlockKey)
   190  	if len(data) == 0 {
   191  		return common.Hash{}
   192  	}
   193  	return common.BytesToHash(data)
   194  }
   195  
   196  // WriteHeadBlockHash stores the head block's hash.
   197  func WriteHeadBlockHash(db ethdb.KeyValueWriter, hash common.Hash) {
   198  	if err := db.Put(headBlockKey, hash.Bytes()); err != nil {
   199  		log.Crit("Failed to store last block's hash", "err", err)
   200  	}
   201  }
   202  
   203  // ReadHeadFastBlockHash retrieves the hash of the current fast-sync head block.
   204  func ReadHeadFastBlockHash(db ethdb.KeyValueReader) common.Hash {
   205  	data, _ := db.Get(headFastBlockKey)
   206  	if len(data) == 0 {
   207  		return common.Hash{}
   208  	}
   209  	return common.BytesToHash(data)
   210  }
   211  
   212  // WriteHeadFastBlockHash stores the hash of the current fast-sync head block.
   213  func WriteHeadFastBlockHash(db ethdb.KeyValueWriter, hash common.Hash) {
   214  	if err := db.Put(headFastBlockKey, hash.Bytes()); err != nil {
   215  		log.Crit("Failed to store last fast block's hash", "err", err)
   216  	}
   217  }
   218  
   219  // ReadFinalizedBlockHash retrieves the hash of the finalized block.
   220  func ReadFinalizedBlockHash(db ethdb.KeyValueReader) common.Hash {
   221  	data, _ := db.Get(headFinalizedBlockKey)
   222  	if len(data) == 0 {
   223  		return common.Hash{}
   224  	}
   225  	return common.BytesToHash(data)
   226  }
   227  
   228  // WriteFinalizedBlockHash stores the hash of the finalized block.
   229  func WriteFinalizedBlockHash(db ethdb.KeyValueWriter, hash common.Hash) {
   230  	if err := db.Put(headFinalizedBlockKey, hash.Bytes()); err != nil {
   231  		log.Crit("Failed to store last finalized block's hash", "err", err)
   232  	}
   233  }
   234  
   235  // ReadLastPivotNumber retrieves the number of the last pivot block. If the node
   236  // full synced, the last pivot will always be nil.
   237  func ReadLastPivotNumber(db ethdb.KeyValueReader) *uint64 {
   238  	data, _ := db.Get(lastPivotKey)
   239  	if len(data) == 0 {
   240  		return nil
   241  	}
   242  	var pivot uint64
   243  	if err := rlp.DecodeBytes(data, &pivot); err != nil {
   244  		log.Error("Invalid pivot block number in database", "err", err)
   245  		return nil
   246  	}
   247  	return &pivot
   248  }
   249  
   250  // WriteLastPivotNumber stores the number of the last pivot block.
   251  func WriteLastPivotNumber(db ethdb.KeyValueWriter, pivot uint64) {
   252  	enc, err := rlp.EncodeToBytes(pivot)
   253  	if err != nil {
   254  		log.Crit("Failed to encode pivot block number", "err", err)
   255  	}
   256  	if err := db.Put(lastPivotKey, enc); err != nil {
   257  		log.Crit("Failed to store pivot block number", "err", err)
   258  	}
   259  }
   260  
   261  // ReadTxIndexTail retrieves the number of oldest indexed block
   262  // whose transaction indices has been indexed.
   263  func ReadTxIndexTail(db ethdb.KeyValueReader) *uint64 {
   264  	data, _ := db.Get(txIndexTailKey)
   265  	if len(data) != 8 {
   266  		return nil
   267  	}
   268  	number := binary.BigEndian.Uint64(data)
   269  	return &number
   270  }
   271  
   272  // WriteTxIndexTail stores the number of oldest indexed block
   273  // into database.
   274  func WriteTxIndexTail(db ethdb.KeyValueWriter, number uint64) {
   275  	if err := db.Put(txIndexTailKey, encodeBlockNumber(number)); err != nil {
   276  		log.Crit("Failed to store the transaction index tail", "err", err)
   277  	}
   278  }
   279  
   280  // DeleteTxIndexTail deletes the number of oldest indexed block
   281  // from database.
   282  func DeleteTxIndexTail(db ethdb.KeyValueWriter) {
   283  	if err := db.Delete(txIndexTailKey); err != nil {
   284  		log.Crit("Failed to delete the transaction index tail", "err", err)
   285  	}
   286  }
   287  
   288  // ReadHeaderRange returns the rlp-encoded headers, starting at 'number', and going
   289  // backwards towards genesis. This method assumes that the caller already has
   290  // placed a cap on count, to prevent DoS issues.
   291  // Since this method operates in head-towards-genesis mode, it will return an empty
   292  // slice in case the head ('number') is missing. Hence, the caller must ensure that
   293  // the head ('number') argument is actually an existing header.
   294  //
   295  // N.B: Since the input is a number, as opposed to a hash, it's implicit that
   296  // this method only operates on canon headers.
   297  func ReadHeaderRange(db ethdb.Reader, number uint64, count uint64) []rlp.RawValue {
   298  	var rlpHeaders []rlp.RawValue
   299  	if count == 0 {
   300  		return rlpHeaders
   301  	}
   302  	i := number
   303  	if count-1 > number {
   304  		// It's ok to request block 0, 1 item
   305  		count = number + 1
   306  	}
   307  	limit, _ := db.Ancients()
   308  	// First read live blocks
   309  	if i >= limit {
   310  		// If we need to read live blocks, we need to figure out the hash first
   311  		hash := ReadCanonicalHash(db, number)
   312  		for ; i >= limit && count > 0; i-- {
   313  			if data, _ := db.Get(headerKey(i, hash)); len(data) > 0 {
   314  				rlpHeaders = append(rlpHeaders, data)
   315  				// Get the parent hash for next query
   316  				hash = types.HeaderParentHashFromRLP(data)
   317  			} else {
   318  				break // Maybe got moved to ancients
   319  			}
   320  			count--
   321  		}
   322  	}
   323  	if count == 0 {
   324  		return rlpHeaders
   325  	}
   326  	// read remaining from ancients, cap at 2M
   327  	data, err := db.AncientRange(ChainFreezerHeaderTable, i+1-count, count, 2*1024*1024)
   328  	if err != nil {
   329  		log.Error("Failed to read headers from freezer", "err", err)
   330  		return rlpHeaders
   331  	}
   332  	if uint64(len(data)) != count {
   333  		log.Warn("Incomplete read of headers from freezer", "wanted", count, "read", len(data))
   334  		return rlpHeaders
   335  	}
   336  	// The data is on the order [h, h+1, .., n] -- reordering needed
   337  	for i := range data {
   338  		rlpHeaders = append(rlpHeaders, data[len(data)-1-i])
   339  	}
   340  	return rlpHeaders
   341  }
   342  
   343  // ReadHeaderRLP retrieves a block header in its raw RLP database encoding.
   344  func ReadHeaderRLP(db ethdb.Reader, hash common.Hash, number uint64) rlp.RawValue {
   345  	var data []byte
   346  	db.ReadAncients(func(reader ethdb.AncientReaderOp) error {
   347  		// First try to look up the data in ancient database. Extra hash
   348  		// comparison is necessary since ancient database only maintains
   349  		// the canonical data.
   350  		data, _ = reader.Ancient(ChainFreezerHeaderTable, number)
   351  		if len(data) > 0 && crypto.Keccak256Hash(data) == hash {
   352  			return nil
   353  		}
   354  		// If not, try reading from leveldb
   355  		data, _ = db.Get(headerKey(number, hash))
   356  		return nil
   357  	})
   358  	return data
   359  }
   360  
   361  // HasHeader verifies the existence of a block header corresponding to the hash.
   362  func HasHeader(db ethdb.Reader, hash common.Hash, number uint64) bool {
   363  	if isCanon(db, number, hash) {
   364  		return true
   365  	}
   366  	if has, err := db.Has(headerKey(number, hash)); !has || err != nil {
   367  		return false
   368  	}
   369  	return true
   370  }
   371  
   372  // ReadHeader retrieves the block header corresponding to the hash.
   373  func ReadHeader(db ethdb.Reader, hash common.Hash, number uint64) *types.Header {
   374  	data := ReadHeaderRLP(db, hash, number)
   375  	if len(data) == 0 {
   376  		return nil
   377  	}
   378  	header := new(types.Header)
   379  	if err := rlp.DecodeBytes(data, header); err != nil {
   380  		log.Error("Invalid block header RLP", "hash", hash, "err", err)
   381  		return nil
   382  	}
   383  	return header
   384  }
   385  
   386  // WriteHeader stores a block header into the database and also stores the hash-
   387  // to-number mapping.
   388  func WriteHeader(db ethdb.KeyValueWriter, header *types.Header) {
   389  	var (
   390  		hash   = header.Hash()
   391  		number = header.Number.Uint64()
   392  	)
   393  	// Write the hash -> number mapping
   394  	WriteHeaderNumber(db, hash, number)
   395  
   396  	// Write the encoded header
   397  	data, err := rlp.EncodeToBytes(header)
   398  	if err != nil {
   399  		log.Crit("Failed to RLP encode header", "err", err)
   400  	}
   401  	key := headerKey(number, hash)
   402  	if err := db.Put(key, data); err != nil {
   403  		log.Crit("Failed to store header", "err", err)
   404  	}
   405  }
   406  
   407  // DeleteHeader removes all block header data associated with a hash.
   408  func DeleteHeader(db ethdb.KeyValueWriter, hash common.Hash, number uint64) {
   409  	deleteHeaderWithoutNumber(db, hash, number)
   410  	if err := db.Delete(headerNumberKey(hash)); err != nil {
   411  		log.Crit("Failed to delete hash to number mapping", "err", err)
   412  	}
   413  }
   414  
   415  // deleteHeaderWithoutNumber removes only the block header but does not remove
   416  // the hash to number mapping.
   417  func deleteHeaderWithoutNumber(db ethdb.KeyValueWriter, hash common.Hash, number uint64) {
   418  	if err := db.Delete(headerKey(number, hash)); err != nil {
   419  		log.Crit("Failed to delete header", "err", err)
   420  	}
   421  }
   422  
   423  // isCanon is an internal utility method, to check whether the given number/hash
   424  // is part of the ancient (canon) set.
   425  func isCanon(reader ethdb.AncientReaderOp, number uint64, hash common.Hash) bool {
   426  	h, err := reader.Ancient(ChainFreezerHashTable, number)
   427  	if err != nil {
   428  		return false
   429  	}
   430  	return bytes.Equal(h, hash[:])
   431  }
   432  
   433  // ReadBodyRLP retrieves the block body (transactions and uncles) in RLP encoding.
   434  func ReadBodyRLP(db ethdb.Reader, hash common.Hash, number uint64) rlp.RawValue {
   435  	// First try to look up the data in ancient database. Extra hash
   436  	// comparison is necessary since ancient database only maintains
   437  	// the canonical data.
   438  	var data []byte
   439  	db.ReadAncients(func(reader ethdb.AncientReaderOp) error {
   440  		// Check if the data is in ancients
   441  		if isCanon(reader, number, hash) {
   442  			data, _ = reader.Ancient(ChainFreezerBodiesTable, number)
   443  			return nil
   444  		}
   445  		// If not, try reading from leveldb
   446  		data, _ = db.Get(blockBodyKey(number, hash))
   447  		return nil
   448  	})
   449  	return data
   450  }
   451  
   452  // ReadCanonicalBodyRLP retrieves the block body (transactions and uncles) for the
   453  // canonical block at number, in RLP encoding. Optionally it takes the block hash
   454  // to avoid looking it up
   455  func ReadCanonicalBodyRLP(db ethdb.Reader, number uint64, hash *common.Hash) rlp.RawValue {
   456  	var data []byte
   457  	db.ReadAncients(func(reader ethdb.AncientReaderOp) error {
   458  		data, _ = reader.Ancient(ChainFreezerBodiesTable, number)
   459  		if len(data) > 0 {
   460  			return nil
   461  		}
   462  		// Block is not in ancients, read from leveldb by hash and number.
   463  		if hash != nil {
   464  			data, _ = db.Get(blockBodyKey(number, *hash))
   465  		} else {
   466  			// Note: ReadCanonicalHash cannot be used here because it also
   467  			// calls ReadAncients internally.
   468  			hashBytes, _ := db.Get(headerHashKey(number))
   469  			data, _ = db.Get(blockBodyKey(number, common.BytesToHash(hashBytes)))
   470  		}
   471  		return nil
   472  	})
   473  	return data
   474  }
   475  
   476  // WriteBodyRLP stores an RLP encoded block body into the database.
   477  func WriteBodyRLP(db ethdb.KeyValueWriter, hash common.Hash, number uint64, rlp rlp.RawValue) {
   478  	if err := db.Put(blockBodyKey(number, hash), rlp); err != nil {
   479  		log.Crit("Failed to store block body", "err", err)
   480  	}
   481  }
   482  
   483  // HasBody verifies the existence of a block body corresponding to the hash.
   484  func HasBody(db ethdb.Reader, hash common.Hash, number uint64) bool {
   485  	if isCanon(db, number, hash) {
   486  		return true
   487  	}
   488  	if has, err := db.Has(blockBodyKey(number, hash)); !has || err != nil {
   489  		return false
   490  	}
   491  	return true
   492  }
   493  
   494  // ReadBody retrieves the block body corresponding to the hash.
   495  func ReadBody(db ethdb.Reader, hash common.Hash, number uint64) *types.Body {
   496  	data := ReadBodyRLP(db, hash, number)
   497  	if len(data) == 0 {
   498  		return nil
   499  	}
   500  	body := new(types.Body)
   501  	if err := rlp.DecodeBytes(data, body); err != nil {
   502  		log.Error("Invalid block body RLP", "hash", hash, "err", err)
   503  		return nil
   504  	}
   505  	return body
   506  }
   507  
   508  // WriteBody stores a block body into the database.
   509  func WriteBody(db ethdb.KeyValueWriter, hash common.Hash, number uint64, body *types.Body) {
   510  	data, err := rlp.EncodeToBytes(body)
   511  	if err != nil {
   512  		log.Crit("Failed to RLP encode body", "err", err)
   513  	}
   514  	WriteBodyRLP(db, hash, number, data)
   515  }
   516  
   517  // DeleteBody removes all block body data associated with a hash.
   518  func DeleteBody(db ethdb.KeyValueWriter, hash common.Hash, number uint64) {
   519  	if err := db.Delete(blockBodyKey(number, hash)); err != nil {
   520  		log.Crit("Failed to delete block body", "err", err)
   521  	}
   522  }
   523  
   524  // HasReceipts verifies the existence of all the transaction receipts belonging
   525  // to a block.
   526  func HasReceipts(db ethdb.Reader, hash common.Hash, number uint64) bool {
   527  	if isCanon(db, number, hash) {
   528  		return true
   529  	}
   530  	if has, err := db.Has(blockReceiptsKey(number, hash)); !has || err != nil {
   531  		return false
   532  	}
   533  	return true
   534  }
   535  
   536  // ReadReceiptsRLP retrieves all the transaction receipts belonging to a block in RLP encoding.
   537  func ReadReceiptsRLP(db ethdb.Reader, hash common.Hash, number uint64) rlp.RawValue {
   538  	var data []byte
   539  	db.ReadAncients(func(reader ethdb.AncientReaderOp) error {
   540  		// Check if the data is in ancients
   541  		if isCanon(reader, number, hash) {
   542  			data, _ = reader.Ancient(ChainFreezerReceiptTable, number)
   543  			return nil
   544  		}
   545  		// If not, try reading from leveldb
   546  		data, _ = db.Get(blockReceiptsKey(number, hash))
   547  		return nil
   548  	})
   549  	return data
   550  }
   551  
   552  // ReadCanonicalReceiptsRLP retrieves the receipts RLP for the canonical block at
   553  // number, in RLP encoding. Optionally it takes the block hash to avoid looking it up.
   554  func ReadCanonicalReceiptsRLP(db ethdb.Reader, number uint64, hash *common.Hash) rlp.RawValue {
   555  	var data []byte
   556  	db.ReadAncients(func(reader ethdb.AncientReaderOp) error {
   557  		data, _ = reader.Ancient(ChainFreezerReceiptTable, number)
   558  		if len(data) > 0 {
   559  			return nil
   560  		}
   561  		// Block is not in ancients, read from leveldb by hash and number.
   562  		if hash != nil {
   563  			data, _ = db.Get(blockReceiptsKey(number, *hash))
   564  		} else {
   565  			// Note: ReadCanonicalHash cannot be used here because it also
   566  			// calls ReadAncients internally.
   567  			hashBytes, _ := db.Get(headerHashKey(number))
   568  			data, _ = db.Get(blockReceiptsKey(number, common.BytesToHash(hashBytes)))
   569  		}
   570  		return nil
   571  	})
   572  	return data
   573  }
   574  
   575  // ReadRawReceipts retrieves all the transaction receipts belonging to a block.
   576  // The receipt metadata fields and the Bloom are not guaranteed to be populated,
   577  // so they should not be used. Use ReadReceipts instead if the metadata is needed.
   578  func ReadRawReceipts(db ethdb.Reader, hash common.Hash, number uint64) types.Receipts {
   579  	// Retrieve the flattened receipt slice
   580  	data := ReadReceiptsRLP(db, hash, number)
   581  	if len(data) == 0 {
   582  		return nil
   583  	}
   584  	// Convert the receipts from their storage form to their internal representation
   585  	storageReceipts := []*types.ReceiptForStorage{}
   586  	if err := rlp.DecodeBytes(data, &storageReceipts); err != nil {
   587  		log.Error("Invalid receipt array RLP", "hash", hash, "err", err)
   588  		return nil
   589  	}
   590  	receipts := make(types.Receipts, len(storageReceipts))
   591  	for i, storageReceipt := range storageReceipts {
   592  		receipts[i] = (*types.Receipt)(storageReceipt)
   593  	}
   594  	return receipts
   595  }
   596  
   597  // ReadReceipts retrieves all the transaction receipts belonging to a block, including
   598  // its corresponding metadata fields. If it is unable to populate these metadata
   599  // fields then nil is returned.
   600  //
   601  // The current implementation populates these metadata fields by reading the receipts'
   602  // corresponding block body, so if the block body is not found it will return nil even
   603  // if the receipt itself is stored.
   604  func ReadReceipts(db ethdb.Reader, hash common.Hash, number uint64, time uint64, config *params.ChainConfig) types.Receipts {
   605  	// We're deriving many fields from the block body, retrieve beside the receipt
   606  	receipts := ReadRawReceipts(db, hash, number)
   607  	if receipts == nil {
   608  		return nil
   609  	}
   610  	body := ReadBody(db, hash, number)
   611  	if body == nil {
   612  		log.Error("Missing body but have receipt", "hash", hash, "number", number)
   613  		return nil
   614  	}
   615  	header := ReadHeader(db, hash, number)
   616  
   617  	var baseFee *big.Int
   618  	if header == nil {
   619  		baseFee = big.NewInt(0)
   620  	} else {
   621  		baseFee = header.BaseFee
   622  	}
   623  	// Compute effective blob gas price.
   624  	var blobGasPrice *big.Int
   625  	if header != nil && header.ExcessBlobGas != nil {
   626  		blobGasPrice = eip4844.CalcBlobFee(config, header)
   627  	}
   628  	if err := receipts.DeriveFields(config, hash, number, time, baseFee, blobGasPrice, body.Transactions); err != nil {
   629  		log.Error("Failed to derive block receipts fields", "hash", hash, "number", number, "err", err)
   630  		return nil
   631  	}
   632  	return receipts
   633  }
   634  
   635  // WriteReceipts stores all the transaction receipts belonging to a block.
   636  func WriteReceipts(db ethdb.KeyValueWriter, hash common.Hash, number uint64, receipts types.Receipts) {
   637  	// Convert the receipts into their storage form and serialize them
   638  	storageReceipts := make([]*types.ReceiptForStorage, len(receipts))
   639  	for i, receipt := range receipts {
   640  		storageReceipts[i] = (*types.ReceiptForStorage)(receipt)
   641  	}
   642  	bytes, err := rlp.EncodeToBytes(storageReceipts)
   643  	if err != nil {
   644  		log.Crit("Failed to encode block receipts", "err", err)
   645  	}
   646  	// Store the flattened receipt slice
   647  	if err := db.Put(blockReceiptsKey(number, hash), bytes); err != nil {
   648  		log.Crit("Failed to store block receipts", "err", err)
   649  	}
   650  }
   651  
   652  // WriteRawReceipts stores all the transaction receipts belonging to a block.
   653  func WriteRawReceipts(db ethdb.KeyValueWriter, hash common.Hash, number uint64, receipts rlp.RawValue) {
   654  	// Store the flattened receipt slice
   655  	if err := db.Put(blockReceiptsKey(number, hash), receipts); err != nil {
   656  		log.Crit("Failed to store block receipts", "err", err)
   657  	}
   658  }
   659  
   660  // DeleteReceipts removes all receipt data associated with a block hash.
   661  func DeleteReceipts(db ethdb.KeyValueWriter, hash common.Hash, number uint64) {
   662  	if err := db.Delete(blockReceiptsKey(number, hash)); err != nil {
   663  		log.Crit("Failed to delete block receipts", "err", err)
   664  	}
   665  }
   666  
   667  // storedReceiptRLP is the storage encoding of a receipt.
   668  // Re-definition in core/types/receipt.go.
   669  // TODO: Re-use the existing definition.
   670  type storedReceiptRLP struct {
   671  	PostStateOrStatus []byte
   672  	CumulativeGasUsed uint64
   673  	Logs              []*types.Log
   674  }
   675  
   676  // ReceiptLogs is a barebone version of ReceiptForStorage which only keeps
   677  // the list of logs. When decoding a stored receipt into this object we
   678  // avoid creating the bloom filter.
   679  type receiptLogs struct {
   680  	Logs []*types.Log
   681  }
   682  
   683  // DecodeRLP implements rlp.Decoder.
   684  func (r *receiptLogs) DecodeRLP(s *rlp.Stream) error {
   685  	var stored storedReceiptRLP
   686  	if err := s.Decode(&stored); err != nil {
   687  		return err
   688  	}
   689  	r.Logs = stored.Logs
   690  	return nil
   691  }
   692  
   693  // ReadLogs retrieves the logs for all transactions in a block. In case
   694  // receipts is not found, a nil is returned.
   695  // Note: ReadLogs does not derive unstored log fields.
   696  func ReadLogs(db ethdb.Reader, hash common.Hash, number uint64) [][]*types.Log {
   697  	// Retrieve the flattened receipt slice
   698  	data := ReadReceiptsRLP(db, hash, number)
   699  	if len(data) == 0 {
   700  		return nil
   701  	}
   702  	receipts := []*receiptLogs{}
   703  	if err := rlp.DecodeBytes(data, &receipts); err != nil {
   704  		log.Error("Invalid receipt array RLP", "hash", hash, "err", err)
   705  		return nil
   706  	}
   707  
   708  	logs := make([][]*types.Log, len(receipts))
   709  	for i, receipt := range receipts {
   710  		logs[i] = receipt.Logs
   711  	}
   712  	return logs
   713  }
   714  
   715  // ReadBlock retrieves an entire block corresponding to the hash, assembling it
   716  // back from the stored header and body. If either the header or body could not
   717  // be retrieved nil is returned.
   718  //
   719  // Note, due to concurrent download of header and block body the header and thus
   720  // canonical hash can be stored in the database but the body data not (yet).
   721  func ReadBlock(db ethdb.Reader, hash common.Hash, number uint64) *types.Block {
   722  	header := ReadHeader(db, hash, number)
   723  	if header == nil {
   724  		return nil
   725  	}
   726  	body := ReadBody(db, hash, number)
   727  	if body == nil {
   728  		return nil
   729  	}
   730  	return types.NewBlockWithHeader(header).WithBody(*body)
   731  }
   732  
   733  // WriteBlock serializes a block into the database, header and body separately.
   734  func WriteBlock(db ethdb.KeyValueWriter, block *types.Block) {
   735  	WriteBody(db, block.Hash(), block.NumberU64(), block.Body())
   736  	WriteHeader(db, block.Header())
   737  }
   738  
   739  // WriteAncientBlocks writes entire block data into ancient store and returns the total written size.
   740  func WriteAncientBlocks(db ethdb.AncientWriter, blocks []*types.Block, receipts []rlp.RawValue) (int64, error) {
   741  	return db.ModifyAncients(func(op ethdb.AncientWriteOp) error {
   742  		for i, block := range blocks {
   743  			header := block.Header()
   744  			if err := writeAncientBlock(op, block, header, receipts[i]); err != nil {
   745  				return err
   746  			}
   747  		}
   748  		return nil
   749  	})
   750  }
   751  
   752  func writeAncientBlock(op ethdb.AncientWriteOp, block *types.Block, header *types.Header, receipts rlp.RawValue) error {
   753  	num := block.NumberU64()
   754  	if err := op.AppendRaw(ChainFreezerHashTable, num, block.Hash().Bytes()); err != nil {
   755  		return fmt.Errorf("can't add block %d hash: %v", num, err)
   756  	}
   757  	if err := op.Append(ChainFreezerHeaderTable, num, header); err != nil {
   758  		return fmt.Errorf("can't append block header %d: %v", num, err)
   759  	}
   760  	if err := op.Append(ChainFreezerBodiesTable, num, block.Body()); err != nil {
   761  		return fmt.Errorf("can't append block body %d: %v", num, err)
   762  	}
   763  	if err := op.Append(ChainFreezerReceiptTable, num, receipts); err != nil {
   764  		return fmt.Errorf("can't append block %d receipts: %v", num, err)
   765  	}
   766  	return nil
   767  }
   768  
   769  // WriteAncientHeaderChain writes the supplied headers along with nil block
   770  // bodies and receipts into the ancient store. It's supposed to be used for
   771  // storing chain segment before the chain cutoff.
   772  func WriteAncientHeaderChain(db ethdb.AncientWriter, headers []*types.Header) (int64, error) {
   773  	return db.ModifyAncients(func(op ethdb.AncientWriteOp) error {
   774  		for _, header := range headers {
   775  			num := header.Number.Uint64()
   776  			if err := op.AppendRaw(ChainFreezerHashTable, num, header.Hash().Bytes()); err != nil {
   777  				return fmt.Errorf("can't add block %d hash: %v", num, err)
   778  			}
   779  			if err := op.Append(ChainFreezerHeaderTable, num, header); err != nil {
   780  				return fmt.Errorf("can't append block header %d: %v", num, err)
   781  			}
   782  			if err := op.AppendRaw(ChainFreezerBodiesTable, num, nil); err != nil {
   783  				return fmt.Errorf("can't append block body %d: %v", num, err)
   784  			}
   785  			if err := op.AppendRaw(ChainFreezerReceiptTable, num, nil); err != nil {
   786  				return fmt.Errorf("can't append block %d receipts: %v", num, err)
   787  			}
   788  		}
   789  		return nil
   790  	})
   791  }
   792  
   793  // DeleteBlock removes all block data associated with a hash.
   794  func DeleteBlock(db ethdb.KeyValueWriter, hash common.Hash, number uint64) {
   795  	DeleteReceipts(db, hash, number)
   796  	DeleteHeader(db, hash, number)
   797  	DeleteBody(db, hash, number)
   798  }
   799  
   800  // DeleteBlockWithoutNumber removes all block data associated with a hash, except
   801  // the hash to number mapping.
   802  func DeleteBlockWithoutNumber(db ethdb.KeyValueWriter, hash common.Hash, number uint64) {
   803  	DeleteReceipts(db, hash, number)
   804  	deleteHeaderWithoutNumber(db, hash, number)
   805  	DeleteBody(db, hash, number)
   806  }
   807  
   808  const badBlockToKeep = 10
   809  
   810  type badBlock struct {
   811  	Header *types.Header
   812  	Body   *types.Body
   813  }
   814  
   815  // ReadBadBlock retrieves the bad block with the corresponding block hash.
   816  func ReadBadBlock(db ethdb.Reader, hash common.Hash) *types.Block {
   817  	blob, err := db.Get(badBlockKey)
   818  	if err != nil {
   819  		return nil
   820  	}
   821  	var badBlocks []*badBlock
   822  	if err := rlp.DecodeBytes(blob, &badBlocks); err != nil {
   823  		return nil
   824  	}
   825  	for _, bad := range badBlocks {
   826  		if bad.Header.Hash() == hash {
   827  			block := types.NewBlockWithHeader(bad.Header)
   828  			if bad.Body != nil {
   829  				block = block.WithBody(*bad.Body)
   830  			}
   831  			return block
   832  		}
   833  	}
   834  	return nil
   835  }
   836  
   837  // ReadAllBadBlocks retrieves all the bad blocks in the database.
   838  // All returned blocks are sorted in reverse order by number.
   839  func ReadAllBadBlocks(db ethdb.Reader) []*types.Block {
   840  	blob, err := db.Get(badBlockKey)
   841  	if err != nil {
   842  		return nil
   843  	}
   844  	var badBlocks []*badBlock
   845  	if err := rlp.DecodeBytes(blob, &badBlocks); err != nil {
   846  		return nil
   847  	}
   848  	var blocks []*types.Block
   849  	for _, bad := range badBlocks {
   850  		block := types.NewBlockWithHeader(bad.Header)
   851  		if bad.Body != nil {
   852  			block = block.WithBody(*bad.Body)
   853  		}
   854  		blocks = append(blocks, block)
   855  	}
   856  	return blocks
   857  }
   858  
   859  // WriteBadBlock serializes the bad block into the database. If the cumulated
   860  // bad blocks exceeds the limitation, the oldest will be dropped.
   861  func WriteBadBlock(db ethdb.KeyValueStore, block *types.Block) {
   862  	blob, err := db.Get(badBlockKey)
   863  	if err != nil {
   864  		log.Warn("Failed to load old bad blocks", "error", err)
   865  	}
   866  	var badBlocks []*badBlock
   867  	if len(blob) > 0 {
   868  		if err := rlp.DecodeBytes(blob, &badBlocks); err != nil {
   869  			log.Crit("Failed to decode old bad blocks", "error", err)
   870  		}
   871  	}
   872  	for _, b := range badBlocks {
   873  		if b.Header.Number.Uint64() == block.NumberU64() && b.Header.Hash() == block.Hash() {
   874  			log.Info("Skip duplicated bad block", "number", block.NumberU64(), "hash", block.Hash())
   875  			return
   876  		}
   877  	}
   878  	badBlocks = append(badBlocks, &badBlock{
   879  		Header: block.Header(),
   880  		Body:   block.Body(),
   881  	})
   882  	slices.SortFunc(badBlocks, func(a, b *badBlock) int {
   883  		// Note: sorting in descending number order.
   884  		return -a.Header.Number.Cmp(b.Header.Number)
   885  	})
   886  	if len(badBlocks) > badBlockToKeep {
   887  		badBlocks = badBlocks[:badBlockToKeep]
   888  	}
   889  	data, err := rlp.EncodeToBytes(badBlocks)
   890  	if err != nil {
   891  		log.Crit("Failed to encode bad blocks", "err", err)
   892  	}
   893  	if err := db.Put(badBlockKey, data); err != nil {
   894  		log.Crit("Failed to write bad blocks", "err", err)
   895  	}
   896  }
   897  
   898  // DeleteBadBlocks deletes all the bad blocks from the database
   899  func DeleteBadBlocks(db ethdb.KeyValueWriter) {
   900  	if err := db.Delete(badBlockKey); err != nil {
   901  		log.Crit("Failed to delete bad blocks", "err", err)
   902  	}
   903  }
   904  
   905  // FindCommonAncestor returns the last common ancestor of two block headers
   906  func FindCommonAncestor(db ethdb.Reader, a, b *types.Header) *types.Header {
   907  	for bn := b.Number.Uint64(); a.Number.Uint64() > bn; {
   908  		a = ReadHeader(db, a.ParentHash, a.Number.Uint64()-1)
   909  		if a == nil {
   910  			return nil
   911  		}
   912  	}
   913  	for an := a.Number.Uint64(); an < b.Number.Uint64(); {
   914  		b = ReadHeader(db, b.ParentHash, b.Number.Uint64()-1)
   915  		if b == nil {
   916  			return nil
   917  		}
   918  	}
   919  	for a.Hash() != b.Hash() {
   920  		a = ReadHeader(db, a.ParentHash, a.Number.Uint64()-1)
   921  		if a == nil {
   922  			return nil
   923  		}
   924  		b = ReadHeader(db, b.ParentHash, b.Number.Uint64()-1)
   925  		if b == nil {
   926  			return nil
   927  		}
   928  	}
   929  	return a
   930  }
   931  
   932  // ReadHeadHeader returns the current canonical head header.
   933  func ReadHeadHeader(db ethdb.Reader) *types.Header {
   934  	headHeaderHash := ReadHeadHeaderHash(db)
   935  	if headHeaderHash == (common.Hash{}) {
   936  		return nil
   937  	}
   938  	headHeaderNumber := ReadHeaderNumber(db, headHeaderHash)
   939  	if headHeaderNumber == nil {
   940  		return nil
   941  	}
   942  	return ReadHeader(db, headHeaderHash, *headHeaderNumber)
   943  }
   944  
   945  // ReadHeadBlock returns the current canonical head block.
   946  func ReadHeadBlock(db ethdb.Reader) *types.Block {
   947  	headBlockHash := ReadHeadBlockHash(db)
   948  	if headBlockHash == (common.Hash{}) {
   949  		return nil
   950  	}
   951  	headBlockNumber := ReadHeaderNumber(db, headBlockHash)
   952  	if headBlockNumber == nil {
   953  		return nil
   954  	}
   955  	return ReadBlock(db, headBlockHash, *headBlockNumber)
   956  }