github.com/ubiq/go-ubiq/v6@v6.0.0/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  	"errors"
    23  	"fmt"
    24  	"math/big"
    25  	"sort"
    26  
    27  	"github.com/ubiq/go-ubiq/v6/common"
    28  	"github.com/ubiq/go-ubiq/v6/core/types"
    29  	"github.com/ubiq/go-ubiq/v6/crypto"
    30  	"github.com/ubiq/go-ubiq/v6/ethdb"
    31  	"github.com/ubiq/go-ubiq/v6/log"
    32  	"github.com/ubiq/go-ubiq/v6/params"
    33  	"github.com/ubiq/go-ubiq/v6/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.AncientReader) error {
    40  		data, _ = reader.Ancient(freezerHashTable, 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  // ReadAllHashes retrieves all the hashes assigned to blocks at a certain heights,
    87  // 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  // ReadLastPivotNumber retrieves the number of the last pivot block. If the node
   220  // full synced, the last pivot will always be nil.
   221  func ReadLastPivotNumber(db ethdb.KeyValueReader) *uint64 {
   222  	data, _ := db.Get(lastPivotKey)
   223  	if len(data) == 0 {
   224  		return nil
   225  	}
   226  	var pivot uint64
   227  	if err := rlp.DecodeBytes(data, &pivot); err != nil {
   228  		log.Error("Invalid pivot block number in database", "err", err)
   229  		return nil
   230  	}
   231  	return &pivot
   232  }
   233  
   234  // WriteLastPivotNumber stores the number of the last pivot block.
   235  func WriteLastPivotNumber(db ethdb.KeyValueWriter, pivot uint64) {
   236  	enc, err := rlp.EncodeToBytes(pivot)
   237  	if err != nil {
   238  		log.Crit("Failed to encode pivot block number", "err", err)
   239  	}
   240  	if err := db.Put(lastPivotKey, enc); err != nil {
   241  		log.Crit("Failed to store pivot block number", "err", err)
   242  	}
   243  }
   244  
   245  // ReadFastTrieProgress retrieves the number of tries nodes fast synced to allow
   246  // reporting correct numbers across restarts.
   247  func ReadFastTrieProgress(db ethdb.KeyValueReader) uint64 {
   248  	data, _ := db.Get(fastTrieProgressKey)
   249  	if len(data) == 0 {
   250  		return 0
   251  	}
   252  	return new(big.Int).SetBytes(data).Uint64()
   253  }
   254  
   255  // WriteFastTrieProgress stores the fast sync trie process counter to support
   256  // retrieving it across restarts.
   257  func WriteFastTrieProgress(db ethdb.KeyValueWriter, count uint64) {
   258  	if err := db.Put(fastTrieProgressKey, new(big.Int).SetUint64(count).Bytes()); err != nil {
   259  		log.Crit("Failed to store fast sync trie progress", "err", err)
   260  	}
   261  }
   262  
   263  // ReadTxIndexTail retrieves the number of oldest indexed block
   264  // whose transaction indices has been indexed. If the corresponding entry
   265  // is non-existent in database it means the indexing has been finished.
   266  func ReadTxIndexTail(db ethdb.KeyValueReader) *uint64 {
   267  	data, _ := db.Get(txIndexTailKey)
   268  	if len(data) != 8 {
   269  		return nil
   270  	}
   271  	number := binary.BigEndian.Uint64(data)
   272  	return &number
   273  }
   274  
   275  // WriteTxIndexTail stores the number of oldest indexed block
   276  // into database.
   277  func WriteTxIndexTail(db ethdb.KeyValueWriter, number uint64) {
   278  	if err := db.Put(txIndexTailKey, encodeBlockNumber(number)); err != nil {
   279  		log.Crit("Failed to store the transaction index tail", "err", err)
   280  	}
   281  }
   282  
   283  // ReadFastTxLookupLimit retrieves the tx lookup limit used in fast sync.
   284  func ReadFastTxLookupLimit(db ethdb.KeyValueReader) *uint64 {
   285  	data, _ := db.Get(fastTxLookupLimitKey)
   286  	if len(data) != 8 {
   287  		return nil
   288  	}
   289  	number := binary.BigEndian.Uint64(data)
   290  	return &number
   291  }
   292  
   293  // WriteFastTxLookupLimit stores the txlookup limit used in fast sync into database.
   294  func WriteFastTxLookupLimit(db ethdb.KeyValueWriter, number uint64) {
   295  	if err := db.Put(fastTxLookupLimitKey, encodeBlockNumber(number)); err != nil {
   296  		log.Crit("Failed to store transaction lookup limit for fast sync", "err", err)
   297  	}
   298  }
   299  
   300  // ReadHeaderRLP retrieves a block header in its raw RLP database encoding.
   301  func ReadHeaderRLP(db ethdb.Reader, hash common.Hash, number uint64) rlp.RawValue {
   302  	var data []byte
   303  	db.ReadAncients(func(reader ethdb.AncientReader) error {
   304  		// First try to look up the data in ancient database. Extra hash
   305  		// comparison is necessary since ancient database only maintains
   306  		// the canonical data.
   307  		data, _ = reader.Ancient(freezerHeaderTable, number)
   308  		if len(data) > 0 && crypto.Keccak256Hash(data) == hash {
   309  			return nil
   310  		}
   311  		// If not, try reading from leveldb
   312  		data, _ = db.Get(headerKey(number, hash))
   313  		return nil
   314  	})
   315  	return data
   316  }
   317  
   318  // HasHeader verifies the existence of a block header corresponding to the hash.
   319  func HasHeader(db ethdb.Reader, hash common.Hash, number uint64) bool {
   320  	if isCanon(db, number, hash) {
   321  		return true
   322  	}
   323  	if has, err := db.Has(headerKey(number, hash)); !has || err != nil {
   324  		return false
   325  	}
   326  	return true
   327  }
   328  
   329  // ReadHeader retrieves the block header corresponding to the hash.
   330  func ReadHeader(db ethdb.Reader, hash common.Hash, number uint64) *types.Header {
   331  	data := ReadHeaderRLP(db, hash, number)
   332  	if len(data) == 0 {
   333  		return nil
   334  	}
   335  	header := new(types.Header)
   336  	if err := rlp.Decode(bytes.NewReader(data), header); err != nil {
   337  		log.Error("Invalid block header RLP", "hash", hash, "err", err)
   338  		return nil
   339  	}
   340  	return header
   341  }
   342  
   343  // WriteHeader stores a block header into the database and also stores the hash-
   344  // to-number mapping.
   345  func WriteHeader(db ethdb.KeyValueWriter, header *types.Header) {
   346  	var (
   347  		hash   = header.Hash()
   348  		number = header.Number.Uint64()
   349  	)
   350  	// Write the hash -> number mapping
   351  	WriteHeaderNumber(db, hash, number)
   352  
   353  	// Write the encoded header
   354  	data, err := rlp.EncodeToBytes(header)
   355  	if err != nil {
   356  		log.Crit("Failed to RLP encode header", "err", err)
   357  	}
   358  	key := headerKey(number, hash)
   359  	if err := db.Put(key, data); err != nil {
   360  		log.Crit("Failed to store header", "err", err)
   361  	}
   362  }
   363  
   364  // DeleteHeader removes all block header data associated with a hash.
   365  func DeleteHeader(db ethdb.KeyValueWriter, hash common.Hash, number uint64) {
   366  	deleteHeaderWithoutNumber(db, hash, number)
   367  	if err := db.Delete(headerNumberKey(hash)); err != nil {
   368  		log.Crit("Failed to delete hash to number mapping", "err", err)
   369  	}
   370  }
   371  
   372  // deleteHeaderWithoutNumber removes only the block header but does not remove
   373  // the hash to number mapping.
   374  func deleteHeaderWithoutNumber(db ethdb.KeyValueWriter, hash common.Hash, number uint64) {
   375  	if err := db.Delete(headerKey(number, hash)); err != nil {
   376  		log.Crit("Failed to delete header", "err", err)
   377  	}
   378  }
   379  
   380  // isCanon is an internal utility method, to check whether the given number/hash
   381  // is part of the ancient (canon) set.
   382  func isCanon(reader ethdb.AncientReader, number uint64, hash common.Hash) bool {
   383  	h, err := reader.Ancient(freezerHashTable, number)
   384  	if err != nil {
   385  		return false
   386  	}
   387  	return bytes.Equal(h, hash[:])
   388  }
   389  
   390  // ReadBodyRLP retrieves the block body (transactions and uncles) in RLP encoding.
   391  func ReadBodyRLP(db ethdb.Reader, hash common.Hash, number uint64) rlp.RawValue {
   392  	// First try to look up the data in ancient database. Extra hash
   393  	// comparison is necessary since ancient database only maintains
   394  	// the canonical data.
   395  	var data []byte
   396  	db.ReadAncients(func(reader ethdb.AncientReader) error {
   397  		// Check if the data is in ancients
   398  		if isCanon(reader, number, hash) {
   399  			data, _ = reader.Ancient(freezerBodiesTable, number)
   400  			return nil
   401  		}
   402  		// If not, try reading from leveldb
   403  		data, _ = db.Get(blockBodyKey(number, hash))
   404  		return nil
   405  	})
   406  	return data
   407  }
   408  
   409  // ReadCanonicalBodyRLP retrieves the block body (transactions and uncles) for the canonical
   410  // block at number, in RLP encoding.
   411  func ReadCanonicalBodyRLP(db ethdb.Reader, number uint64) rlp.RawValue {
   412  	var data []byte
   413  	db.ReadAncients(func(reader ethdb.AncientReader) error {
   414  		data, _ = reader.Ancient(freezerBodiesTable, number)
   415  		if len(data) > 0 {
   416  			return nil
   417  		}
   418  		// Get it by hash from leveldb
   419  		data, _ = db.Get(blockBodyKey(number, ReadCanonicalHash(db, number)))
   420  		return nil
   421  	})
   422  	return data
   423  }
   424  
   425  // WriteBodyRLP stores an RLP encoded block body into the database.
   426  func WriteBodyRLP(db ethdb.KeyValueWriter, hash common.Hash, number uint64, rlp rlp.RawValue) {
   427  	if err := db.Put(blockBodyKey(number, hash), rlp); err != nil {
   428  		log.Crit("Failed to store block body", "err", err)
   429  	}
   430  }
   431  
   432  // HasBody verifies the existence of a block body corresponding to the hash.
   433  func HasBody(db ethdb.Reader, hash common.Hash, number uint64) bool {
   434  	if isCanon(db, number, hash) {
   435  		return true
   436  	}
   437  	if has, err := db.Has(blockBodyKey(number, hash)); !has || err != nil {
   438  		return false
   439  	}
   440  	return true
   441  }
   442  
   443  // ReadBody retrieves the block body corresponding to the hash.
   444  func ReadBody(db ethdb.Reader, hash common.Hash, number uint64) *types.Body {
   445  	data := ReadBodyRLP(db, hash, number)
   446  	if len(data) == 0 {
   447  		return nil
   448  	}
   449  	body := new(types.Body)
   450  	if err := rlp.Decode(bytes.NewReader(data), body); err != nil {
   451  		log.Error("Invalid block body RLP", "hash", hash, "err", err)
   452  		return nil
   453  	}
   454  	return body
   455  }
   456  
   457  // WriteBody stores a block body into the database.
   458  func WriteBody(db ethdb.KeyValueWriter, hash common.Hash, number uint64, body *types.Body) {
   459  	data, err := rlp.EncodeToBytes(body)
   460  	if err != nil {
   461  		log.Crit("Failed to RLP encode body", "err", err)
   462  	}
   463  	WriteBodyRLP(db, hash, number, data)
   464  }
   465  
   466  // DeleteBody removes all block body data associated with a hash.
   467  func DeleteBody(db ethdb.KeyValueWriter, hash common.Hash, number uint64) {
   468  	if err := db.Delete(blockBodyKey(number, hash)); err != nil {
   469  		log.Crit("Failed to delete block body", "err", err)
   470  	}
   471  }
   472  
   473  // ReadTdRLP retrieves a block's total difficulty corresponding to the hash in RLP encoding.
   474  func ReadTdRLP(db ethdb.Reader, hash common.Hash, number uint64) rlp.RawValue {
   475  	var data []byte
   476  	db.ReadAncients(func(reader ethdb.AncientReader) error {
   477  		// Check if the data is in ancients
   478  		if isCanon(reader, number, hash) {
   479  			data, _ = reader.Ancient(freezerDifficultyTable, number)
   480  			return nil
   481  		}
   482  		// If not, try reading from leveldb
   483  		data, _ = db.Get(headerTDKey(number, hash))
   484  		return nil
   485  	})
   486  	return data
   487  }
   488  
   489  // ReadTd retrieves a block's total difficulty corresponding to the hash.
   490  func ReadTd(db ethdb.Reader, hash common.Hash, number uint64) *big.Int {
   491  	data := ReadTdRLP(db, hash, number)
   492  	if len(data) == 0 {
   493  		return nil
   494  	}
   495  	td := new(big.Int)
   496  	if err := rlp.Decode(bytes.NewReader(data), td); err != nil {
   497  		log.Error("Invalid block total difficulty RLP", "hash", hash, "err", err)
   498  		return nil
   499  	}
   500  	return td
   501  }
   502  
   503  // WriteTd stores the total difficulty of a block into the database.
   504  func WriteTd(db ethdb.KeyValueWriter, hash common.Hash, number uint64, td *big.Int) {
   505  	data, err := rlp.EncodeToBytes(td)
   506  	if err != nil {
   507  		log.Crit("Failed to RLP encode block total difficulty", "err", err)
   508  	}
   509  	if err := db.Put(headerTDKey(number, hash), data); err != nil {
   510  		log.Crit("Failed to store block total difficulty", "err", err)
   511  	}
   512  }
   513  
   514  // DeleteTd removes all block total difficulty data associated with a hash.
   515  func DeleteTd(db ethdb.KeyValueWriter, hash common.Hash, number uint64) {
   516  	if err := db.Delete(headerTDKey(number, hash)); err != nil {
   517  		log.Crit("Failed to delete block total difficulty", "err", err)
   518  	}
   519  }
   520  
   521  // HasReceipts verifies the existence of all the transaction receipts belonging
   522  // to a block.
   523  func HasReceipts(db ethdb.Reader, hash common.Hash, number uint64) bool {
   524  	if isCanon(db, number, hash) {
   525  		return true
   526  	}
   527  	if has, err := db.Has(blockReceiptsKey(number, hash)); !has || err != nil {
   528  		return false
   529  	}
   530  	return true
   531  }
   532  
   533  // ReadReceiptsRLP retrieves all the transaction receipts belonging to a block in RLP encoding.
   534  func ReadReceiptsRLP(db ethdb.Reader, hash common.Hash, number uint64) rlp.RawValue {
   535  	var data []byte
   536  	db.ReadAncients(func(reader ethdb.AncientReader) error {
   537  		// Check if the data is in ancients
   538  		if isCanon(reader, number, hash) {
   539  			data, _ = reader.Ancient(freezerReceiptTable, number)
   540  			return nil
   541  		}
   542  		// If not, try reading from leveldb
   543  		data, _ = db.Get(blockReceiptsKey(number, hash))
   544  		return nil
   545  	})
   546  	return data
   547  }
   548  
   549  // ReadRawReceipts retrieves all the transaction receipts belonging to a block.
   550  // The receipt metadata fields are not guaranteed to be populated, so they
   551  // should not be used. Use ReadReceipts instead if the metadata is needed.
   552  func ReadRawReceipts(db ethdb.Reader, hash common.Hash, number uint64) types.Receipts {
   553  	// Retrieve the flattened receipt slice
   554  	data := ReadReceiptsRLP(db, hash, number)
   555  	if len(data) == 0 {
   556  		return nil
   557  	}
   558  	// Convert the receipts from their storage form to their internal representation
   559  	storageReceipts := []*types.ReceiptForStorage{}
   560  	if err := rlp.DecodeBytes(data, &storageReceipts); err != nil {
   561  		log.Error("Invalid receipt array RLP", "hash", hash, "err", err)
   562  		return nil
   563  	}
   564  	receipts := make(types.Receipts, len(storageReceipts))
   565  	for i, storageReceipt := range storageReceipts {
   566  		receipts[i] = (*types.Receipt)(storageReceipt)
   567  	}
   568  	return receipts
   569  }
   570  
   571  // ReadReceipts retrieves all the transaction receipts belonging to a block, including
   572  // its correspoinding metadata fields. If it is unable to populate these metadata
   573  // fields then nil is returned.
   574  //
   575  // The current implementation populates these metadata fields by reading the receipts'
   576  // corresponding block body, so if the block body is not found it will return nil even
   577  // if the receipt itself is stored.
   578  func ReadReceipts(db ethdb.Reader, hash common.Hash, number uint64, config *params.ChainConfig) types.Receipts {
   579  	// We're deriving many fields from the block body, retrieve beside the receipt
   580  	receipts := ReadRawReceipts(db, hash, number)
   581  	if receipts == nil {
   582  		return nil
   583  	}
   584  	body := ReadBody(db, hash, number)
   585  	if body == nil {
   586  		log.Error("Missing body but have receipt", "hash", hash, "number", number)
   587  		return nil
   588  	}
   589  	if err := receipts.DeriveFields(config, hash, number, body.Transactions); err != nil {
   590  		log.Error("Failed to derive block receipts fields", "hash", hash, "number", number, "err", err)
   591  		return nil
   592  	}
   593  	return receipts
   594  }
   595  
   596  // WriteReceipts stores all the transaction receipts belonging to a block.
   597  func WriteReceipts(db ethdb.KeyValueWriter, hash common.Hash, number uint64, receipts types.Receipts) {
   598  	// Convert the receipts into their storage form and serialize them
   599  	storageReceipts := make([]*types.ReceiptForStorage, len(receipts))
   600  	for i, receipt := range receipts {
   601  		storageReceipts[i] = (*types.ReceiptForStorage)(receipt)
   602  	}
   603  	bytes, err := rlp.EncodeToBytes(storageReceipts)
   604  	if err != nil {
   605  		log.Crit("Failed to encode block receipts", "err", err)
   606  	}
   607  	// Store the flattened receipt slice
   608  	if err := db.Put(blockReceiptsKey(number, hash), bytes); err != nil {
   609  		log.Crit("Failed to store block receipts", "err", err)
   610  	}
   611  }
   612  
   613  // DeleteReceipts removes all receipt data associated with a block hash.
   614  func DeleteReceipts(db ethdb.KeyValueWriter, hash common.Hash, number uint64) {
   615  	if err := db.Delete(blockReceiptsKey(number, hash)); err != nil {
   616  		log.Crit("Failed to delete block receipts", "err", err)
   617  	}
   618  }
   619  
   620  // storedReceiptRLP is the storage encoding of a receipt.
   621  // Re-definition in core/types/receipt.go.
   622  type storedReceiptRLP struct {
   623  	PostStateOrStatus []byte
   624  	CumulativeGasUsed uint64
   625  	Logs              []*types.LogForStorage
   626  }
   627  
   628  // ReceiptLogs is a barebone version of ReceiptForStorage which only keeps
   629  // the list of logs. When decoding a stored receipt into this object we
   630  // avoid creating the bloom filter.
   631  type receiptLogs struct {
   632  	Logs []*types.Log
   633  }
   634  
   635  // DecodeRLP implements rlp.Decoder.
   636  func (r *receiptLogs) DecodeRLP(s *rlp.Stream) error {
   637  	var stored storedReceiptRLP
   638  	if err := s.Decode(&stored); err != nil {
   639  		return err
   640  	}
   641  	r.Logs = make([]*types.Log, len(stored.Logs))
   642  	for i, log := range stored.Logs {
   643  		r.Logs[i] = (*types.Log)(log)
   644  	}
   645  	return nil
   646  }
   647  
   648  // DeriveLogFields fills the logs in receiptLogs with information such as block number, txhash, etc.
   649  func deriveLogFields(receipts []*receiptLogs, hash common.Hash, number uint64, txs types.Transactions) error {
   650  	logIndex := uint(0)
   651  	if len(txs) != len(receipts) {
   652  		return errors.New("transaction and receipt count mismatch")
   653  	}
   654  	for i := 0; i < len(receipts); i++ {
   655  		txHash := txs[i].Hash()
   656  		// The derived log fields can simply be set from the block and transaction
   657  		for j := 0; j < len(receipts[i].Logs); j++ {
   658  			receipts[i].Logs[j].BlockNumber = number
   659  			receipts[i].Logs[j].BlockHash = hash
   660  			receipts[i].Logs[j].TxHash = txHash
   661  			receipts[i].Logs[j].TxIndex = uint(i)
   662  			receipts[i].Logs[j].Index = logIndex
   663  			logIndex++
   664  		}
   665  	}
   666  	return nil
   667  }
   668  
   669  // ReadLogs retrieves the logs for all transactions in a block. The log fields
   670  // are populated with metadata. In case the receipts or the block body
   671  // are not found, a nil is returned.
   672  func ReadLogs(db ethdb.Reader, hash common.Hash, number uint64, config *params.ChainConfig) [][]*types.Log {
   673  	// Retrieve the flattened receipt slice
   674  	data := ReadReceiptsRLP(db, hash, number)
   675  	if len(data) == 0 {
   676  		return nil
   677  	}
   678  	receipts := []*receiptLogs{}
   679  	if err := rlp.DecodeBytes(data, &receipts); err != nil {
   680  		// Receipts might be in the legacy format, try decoding that.
   681  		// TODO: to be removed after users migrated
   682  		if logs := readLegacyLogs(db, hash, number, config); logs != nil {
   683  			return logs
   684  		}
   685  		log.Error("Invalid receipt array RLP", "hash", "err", err)
   686  		return nil
   687  	}
   688  
   689  	body := ReadBody(db, hash, number)
   690  	if body == nil {
   691  		log.Error("Missing body but have receipt", "hash", hash, "number", number)
   692  		return nil
   693  	}
   694  	if err := deriveLogFields(receipts, hash, number, body.Transactions); err != nil {
   695  		log.Error("Failed to derive block receipts fields", "hash", hash, "number", number, "err", err)
   696  		return nil
   697  	}
   698  	logs := make([][]*types.Log, len(receipts))
   699  	for i, receipt := range receipts {
   700  		logs[i] = receipt.Logs
   701  	}
   702  	return logs
   703  }
   704  
   705  // readLegacyLogs is a temporary workaround for when trying to read logs
   706  // from a block which has its receipt stored in the legacy format. It'll
   707  // be removed after users have migrated their freezer databases.
   708  func readLegacyLogs(db ethdb.Reader, hash common.Hash, number uint64, config *params.ChainConfig) [][]*types.Log {
   709  	receipts := ReadReceipts(db, hash, number, config)
   710  	if receipts == nil {
   711  		return nil
   712  	}
   713  	logs := make([][]*types.Log, len(receipts))
   714  	for i, receipt := range receipts {
   715  		logs[i] = receipt.Logs
   716  	}
   717  	return logs
   718  }
   719  
   720  // ReadBlock retrieves an entire block corresponding to the hash, assembling it
   721  // back from the stored header and body. If either the header or body could not
   722  // be retrieved nil is returned.
   723  //
   724  // Note, due to concurrent download of header and block body the header and thus
   725  // canonical hash can be stored in the database but the body data not (yet).
   726  func ReadBlock(db ethdb.Reader, hash common.Hash, number uint64) *types.Block {
   727  	header := ReadHeader(db, hash, number)
   728  	if header == nil {
   729  		return nil
   730  	}
   731  	body := ReadBody(db, hash, number)
   732  	if body == nil {
   733  		return nil
   734  	}
   735  	return types.NewBlockWithHeader(header).WithBody(body.Transactions, body.Uncles)
   736  }
   737  
   738  // WriteBlock serializes a block into the database, header and body separately.
   739  func WriteBlock(db ethdb.KeyValueWriter, block *types.Block) {
   740  	WriteBody(db, block.Hash(), block.NumberU64(), block.Body())
   741  	WriteHeader(db, block.Header())
   742  }
   743  
   744  // WriteAncientBlock writes entire block data into ancient store and returns the total written size.
   745  func WriteAncientBlocks(db ethdb.AncientWriter, blocks []*types.Block, receipts []types.Receipts, td *big.Int) (int64, error) {
   746  	var (
   747  		tdSum      = new(big.Int).Set(td)
   748  		stReceipts []*types.ReceiptForStorage
   749  	)
   750  	return db.ModifyAncients(func(op ethdb.AncientWriteOp) error {
   751  		for i, block := range blocks {
   752  			// Convert receipts to storage format and sum up total difficulty.
   753  			stReceipts = stReceipts[:0]
   754  			for _, receipt := range receipts[i] {
   755  				stReceipts = append(stReceipts, (*types.ReceiptForStorage)(receipt))
   756  			}
   757  			header := block.Header()
   758  			if i > 0 {
   759  				tdSum.Add(tdSum, header.Difficulty)
   760  			}
   761  			if err := writeAncientBlock(op, block, header, stReceipts, tdSum); err != nil {
   762  				return err
   763  			}
   764  		}
   765  		return nil
   766  	})
   767  }
   768  
   769  func writeAncientBlock(op ethdb.AncientWriteOp, block *types.Block, header *types.Header, receipts []*types.ReceiptForStorage, td *big.Int) error {
   770  	num := block.NumberU64()
   771  	if err := op.AppendRaw(freezerHashTable, num, block.Hash().Bytes()); err != nil {
   772  		return fmt.Errorf("can't add block %d hash: %v", num, err)
   773  	}
   774  	if err := op.Append(freezerHeaderTable, num, header); err != nil {
   775  		return fmt.Errorf("can't append block header %d: %v", num, err)
   776  	}
   777  	if err := op.Append(freezerBodiesTable, num, block.Body()); err != nil {
   778  		return fmt.Errorf("can't append block body %d: %v", num, err)
   779  	}
   780  	if err := op.Append(freezerReceiptTable, num, receipts); err != nil {
   781  		return fmt.Errorf("can't append block %d receipts: %v", num, err)
   782  	}
   783  	if err := op.Append(freezerDifficultyTable, num, td); err != nil {
   784  		return fmt.Errorf("can't append block %d total difficulty: %v", num, err)
   785  	}
   786  	return nil
   787  }
   788  
   789  // DeleteBlock removes all block data associated with a hash.
   790  func DeleteBlock(db ethdb.KeyValueWriter, hash common.Hash, number uint64) {
   791  	DeleteReceipts(db, hash, number)
   792  	DeleteHeader(db, hash, number)
   793  	DeleteBody(db, hash, number)
   794  	DeleteTd(db, hash, number)
   795  }
   796  
   797  // DeleteBlockWithoutNumber removes all block data associated with a hash, except
   798  // the hash to number mapping.
   799  func DeleteBlockWithoutNumber(db ethdb.KeyValueWriter, hash common.Hash, number uint64) {
   800  	DeleteReceipts(db, hash, number)
   801  	deleteHeaderWithoutNumber(db, hash, number)
   802  	DeleteBody(db, hash, number)
   803  	DeleteTd(db, hash, number)
   804  }
   805  
   806  const badBlockToKeep = 10
   807  
   808  type badBlock struct {
   809  	Header *types.Header
   810  	Body   *types.Body
   811  }
   812  
   813  // badBlockList implements the sort interface to allow sorting a list of
   814  // bad blocks by their number in the reverse order.
   815  type badBlockList []*badBlock
   816  
   817  func (s badBlockList) Len() int { return len(s) }
   818  func (s badBlockList) Less(i, j int) bool {
   819  	return s[i].Header.Number.Uint64() < s[j].Header.Number.Uint64()
   820  }
   821  func (s badBlockList) Swap(i, j int) { s[i], s[j] = s[j], s[i] }
   822  
   823  // ReadBadBlock retrieves the bad block with the corresponding block hash.
   824  func ReadBadBlock(db ethdb.Reader, hash common.Hash) *types.Block {
   825  	blob, err := db.Get(badBlockKey)
   826  	if err != nil {
   827  		return nil
   828  	}
   829  	var badBlocks badBlockList
   830  	if err := rlp.DecodeBytes(blob, &badBlocks); err != nil {
   831  		return nil
   832  	}
   833  	for _, bad := range badBlocks {
   834  		if bad.Header.Hash() == hash {
   835  			return types.NewBlockWithHeader(bad.Header).WithBody(bad.Body.Transactions, bad.Body.Uncles)
   836  		}
   837  	}
   838  	return nil
   839  }
   840  
   841  // ReadAllBadBlocks retrieves all the bad blocks in the database.
   842  // All returned blocks are sorted in reverse order by number.
   843  func ReadAllBadBlocks(db ethdb.Reader) []*types.Block {
   844  	blob, err := db.Get(badBlockKey)
   845  	if err != nil {
   846  		return nil
   847  	}
   848  	var badBlocks badBlockList
   849  	if err := rlp.DecodeBytes(blob, &badBlocks); err != nil {
   850  		return nil
   851  	}
   852  	var blocks []*types.Block
   853  	for _, bad := range badBlocks {
   854  		blocks = append(blocks, types.NewBlockWithHeader(bad.Header).WithBody(bad.Body.Transactions, bad.Body.Uncles))
   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 badBlockList
   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  	sort.Sort(sort.Reverse(badBlocks))
   883  	if len(badBlocks) > badBlockToKeep {
   884  		badBlocks = badBlocks[:badBlockToKeep]
   885  	}
   886  	data, err := rlp.EncodeToBytes(badBlocks)
   887  	if err != nil {
   888  		log.Crit("Failed to encode bad blocks", "err", err)
   889  	}
   890  	if err := db.Put(badBlockKey, data); err != nil {
   891  		log.Crit("Failed to write bad blocks", "err", err)
   892  	}
   893  }
   894  
   895  // DeleteBadBlocks deletes all the bad blocks from the database
   896  func DeleteBadBlocks(db ethdb.KeyValueWriter) {
   897  	if err := db.Delete(badBlockKey); err != nil {
   898  		log.Crit("Failed to delete bad blocks", "err", err)
   899  	}
   900  }
   901  
   902  // FindCommonAncestor returns the last common ancestor of two block headers
   903  func FindCommonAncestor(db ethdb.Reader, a, b *types.Header) *types.Header {
   904  	for bn := b.Number.Uint64(); a.Number.Uint64() > bn; {
   905  		a = ReadHeader(db, a.ParentHash, a.Number.Uint64()-1)
   906  		if a == nil {
   907  			return nil
   908  		}
   909  	}
   910  	for an := a.Number.Uint64(); an < b.Number.Uint64(); {
   911  		b = ReadHeader(db, b.ParentHash, b.Number.Uint64()-1)
   912  		if b == nil {
   913  			return nil
   914  		}
   915  	}
   916  	for a.Hash() != b.Hash() {
   917  		a = ReadHeader(db, a.ParentHash, a.Number.Uint64()-1)
   918  		if a == nil {
   919  			return nil
   920  		}
   921  		b = ReadHeader(db, b.ParentHash, b.Number.Uint64()-1)
   922  		if b == nil {
   923  			return nil
   924  		}
   925  	}
   926  	return a
   927  }
   928  
   929  // ReadHeadHeader returns the current canonical head header.
   930  func ReadHeadHeader(db ethdb.Reader) *types.Header {
   931  	headHeaderHash := ReadHeadHeaderHash(db)
   932  	if headHeaderHash == (common.Hash{}) {
   933  		return nil
   934  	}
   935  	headHeaderNumber := ReadHeaderNumber(db, headHeaderHash)
   936  	if headHeaderNumber == nil {
   937  		return nil
   938  	}
   939  	return ReadHeader(db, headHeaderHash, *headHeaderNumber)
   940  }
   941  
   942  // ReadHeadBlock returns the current canonical head block.
   943  func ReadHeadBlock(db ethdb.Reader) *types.Block {
   944  	headBlockHash := ReadHeadBlockHash(db)
   945  	if headBlockHash == (common.Hash{}) {
   946  		return nil
   947  	}
   948  	headBlockNumber := ReadHeaderNumber(db, headBlockHash)
   949  	if headBlockNumber == nil {
   950  		return nil
   951  	}
   952  	return ReadBlock(db, headBlockHash, *headBlockNumber)
   953  }