github.com/nitinawathare/ethereumassignment3@v0.0.0-20211021213010-f07344c2b868/go-ethereum/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  	"math/big"
    23  
    24  	"github.com/ethereum/go-ethereum/common"
    25  	"github.com/ethereum/go-ethereum/core/types"
    26  	"github.com/ethereum/go-ethereum/ethdb"
    27  	"github.com/ethereum/go-ethereum/log"
    28  	"github.com/ethereum/go-ethereum/params"
    29  	"github.com/ethereum/go-ethereum/rlp"
    30  )
    31  
    32  // ReadCanonicalHash retrieves the hash assigned to a canonical block number.
    33  func ReadCanonicalHash(db ethdb.Reader, number uint64) common.Hash {
    34  	data, _ := db.Get(headerHashKey(number))
    35  	if len(data) == 0 {
    36  		return common.Hash{}
    37  	}
    38  	return common.BytesToHash(data)
    39  }
    40  
    41  // WriteCanonicalHash stores the hash assigned to a canonical block number.
    42  func WriteCanonicalHash(db ethdb.Writer, hash common.Hash, number uint64) {
    43  	if err := db.Put(headerHashKey(number), hash.Bytes()); err != nil {
    44  		log.Crit("Failed to store number to hash mapping", "err", err)
    45  	}
    46  }
    47  
    48  // DeleteCanonicalHash removes the number to hash canonical mapping.
    49  func DeleteCanonicalHash(db ethdb.Writer, number uint64) {
    50  	if err := db.Delete(headerHashKey(number)); err != nil {
    51  		log.Crit("Failed to delete number to hash mapping", "err", err)
    52  	}
    53  }
    54  
    55  // ReadHeaderNumber returns the header number assigned to a hash.
    56  func ReadHeaderNumber(db ethdb.Reader, hash common.Hash) *uint64 {
    57  	data, _ := db.Get(headerNumberKey(hash))
    58  	if len(data) != 8 {
    59  		return nil
    60  	}
    61  	number := binary.BigEndian.Uint64(data)
    62  	return &number
    63  }
    64  
    65  // ReadHeadHeaderHash retrieves the hash of the current canonical head header.
    66  func ReadHeadHeaderHash(db ethdb.Reader) common.Hash {
    67  	data, _ := db.Get(headHeaderKey)
    68  	if len(data) == 0 {
    69  		return common.Hash{}
    70  	}
    71  	return common.BytesToHash(data)
    72  }
    73  
    74  // WriteHeadHeaderHash stores the hash of the current canonical head header.
    75  func WriteHeadHeaderHash(db ethdb.Writer, hash common.Hash) {
    76  	if err := db.Put(headHeaderKey, hash.Bytes()); err != nil {
    77  		log.Crit("Failed to store last header's hash", "err", err)
    78  	}
    79  }
    80  
    81  // ReadHeadBlockHash retrieves the hash of the current canonical head block.
    82  func ReadHeadBlockHash(db ethdb.Reader) common.Hash {
    83  	data, _ := db.Get(headBlockKey)
    84  	if len(data) == 0 {
    85  		return common.Hash{}
    86  	}
    87  	return common.BytesToHash(data)
    88  }
    89  
    90  // WriteHeadBlockHash stores the head block's hash.
    91  func WriteHeadBlockHash(db ethdb.Writer, hash common.Hash) {
    92  	if err := db.Put(headBlockKey, hash.Bytes()); err != nil {
    93  		log.Crit("Failed to store last block's hash", "err", err)
    94  	}
    95  }
    96  
    97  // ReadHeadFastBlockHash retrieves the hash of the current fast-sync head block.
    98  func ReadHeadFastBlockHash(db ethdb.Reader) common.Hash {
    99  	data, _ := db.Get(headFastBlockKey)
   100  	if len(data) == 0 {
   101  		return common.Hash{}
   102  	}
   103  	return common.BytesToHash(data)
   104  }
   105  
   106  // WriteHeadFastBlockHash stores the hash of the current fast-sync head block.
   107  func WriteHeadFastBlockHash(db ethdb.Writer, hash common.Hash) {
   108  	if err := db.Put(headFastBlockKey, hash.Bytes()); err != nil {
   109  		log.Crit("Failed to store last fast block's hash", "err", err)
   110  	}
   111  }
   112  
   113  // ReadFastTrieProgress retrieves the number of tries nodes fast synced to allow
   114  // reporting correct numbers across restarts.
   115  func ReadFastTrieProgress(db ethdb.Reader) uint64 {
   116  	data, _ := db.Get(fastTrieProgressKey)
   117  	if len(data) == 0 {
   118  		return 0
   119  	}
   120  	return new(big.Int).SetBytes(data).Uint64()
   121  }
   122  
   123  // WriteFastTrieProgress stores the fast sync trie process counter to support
   124  // retrieving it across restarts.
   125  func WriteFastTrieProgress(db ethdb.Writer, count uint64) {
   126  	if err := db.Put(fastTrieProgressKey, new(big.Int).SetUint64(count).Bytes()); err != nil {
   127  		log.Crit("Failed to store fast sync trie progress", "err", err)
   128  	}
   129  }
   130  
   131  // ReadHeaderRLP retrieves a block header in its raw RLP database encoding.
   132  func ReadHeaderRLP(db ethdb.Reader, hash common.Hash, number uint64) rlp.RawValue {
   133  	data, _ := db.Get(headerKey(number, hash))
   134  	return data
   135  }
   136  
   137  // HasHeader verifies the existence of a block header corresponding to the hash.
   138  func HasHeader(db ethdb.Reader, hash common.Hash, number uint64) bool {
   139  	if has, err := db.Has(headerKey(number, hash)); !has || err != nil {
   140  		return false
   141  	}
   142  	return true
   143  }
   144  
   145  // ReadHeader retrieves the block header corresponding to the hash.
   146  func ReadHeader(db ethdb.Reader, hash common.Hash, number uint64) *types.Header {
   147  	data := ReadHeaderRLP(db, hash, number)
   148  	if len(data) == 0 {
   149  		return nil
   150  	}
   151  	header := new(types.Header)
   152  	if err := rlp.Decode(bytes.NewReader(data), header); err != nil {
   153  		log.Error("Invalid block header RLP", "hash", hash, "err", err)
   154  		return nil
   155  	}
   156  	return header
   157  }
   158  
   159  // WriteHeader stores a block header into the database and also stores the hash-
   160  // to-number mapping.
   161  func WriteHeader(db ethdb.Writer, header *types.Header) {
   162  	// Write the hash -> number mapping
   163  	var (
   164  		hash    = header.Hash()
   165  		number  = header.Number.Uint64()
   166  		encoded = encodeBlockNumber(number)
   167  	)
   168  	key := headerNumberKey(hash)
   169  	if err := db.Put(key, encoded); err != nil {
   170  		log.Crit("Failed to store hash to number mapping", "err", err)
   171  	}
   172  	// Write the encoded header
   173  	data, err := rlp.EncodeToBytes(header)
   174  	if err != nil {
   175  		log.Crit("Failed to RLP encode header", "err", err)
   176  	}
   177  	key = headerKey(number, hash)
   178  	if err := db.Put(key, data); err != nil {
   179  		log.Crit("Failed to store header", "err", err)
   180  	}
   181  }
   182  
   183  // DeleteHeader removes all block header data associated with a hash.
   184  func DeleteHeader(db ethdb.Writer, hash common.Hash, number uint64) {
   185  	deleteHeaderWithoutNumber(db, hash, number)
   186  	if err := db.Delete(headerNumberKey(hash)); err != nil {
   187  		log.Crit("Failed to delete hash to number mapping", "err", err)
   188  	}
   189  }
   190  
   191  // deleteHeaderWithoutNumber removes only the block header but does not remove
   192  // the hash to number mapping.
   193  func deleteHeaderWithoutNumber(db ethdb.Writer, hash common.Hash, number uint64) {
   194  	if err := db.Delete(headerKey(number, hash)); err != nil {
   195  		log.Crit("Failed to delete header", "err", err)
   196  	}
   197  }
   198  
   199  // ReadBodyRLP retrieves the block body (transactions and uncles) in RLP encoding.
   200  func ReadBodyRLP(db ethdb.Reader, hash common.Hash, number uint64) rlp.RawValue {
   201  	data, _ := db.Get(blockBodyKey(number, hash))
   202  	return data
   203  }
   204  
   205  // WriteBodyRLP stores an RLP encoded block body into the database.
   206  func WriteBodyRLP(db ethdb.Writer, hash common.Hash, number uint64, rlp rlp.RawValue) {
   207  	if err := db.Put(blockBodyKey(number, hash), rlp); err != nil {
   208  		log.Crit("Failed to store block body", "err", err)
   209  	}
   210  }
   211  
   212  // HasBody verifies the existence of a block body corresponding to the hash.
   213  func HasBody(db ethdb.Reader, hash common.Hash, number uint64) bool {
   214  	if has, err := db.Has(blockBodyKey(number, hash)); !has || err != nil {
   215  		return false
   216  	}
   217  	return true
   218  }
   219  
   220  // ReadBody retrieves the block body corresponding to the hash.
   221  func ReadBody(db ethdb.Reader, hash common.Hash, number uint64) *types.Body {
   222  	data := ReadBodyRLP(db, hash, number)
   223  	if len(data) == 0 {
   224  		return nil
   225  	}
   226  	body := new(types.Body)
   227  	if err := rlp.Decode(bytes.NewReader(data), body); err != nil {
   228  		log.Error("Invalid block body RLP", "hash", hash, "err", err)
   229  		return nil
   230  	}
   231  	return body
   232  }
   233  
   234  // WriteBody storea a block body into the database.
   235  func WriteBody(db ethdb.Writer, hash common.Hash, number uint64, body *types.Body) {
   236  	data, err := rlp.EncodeToBytes(body)
   237  	if err != nil {
   238  		log.Crit("Failed to RLP encode body", "err", err)
   239  	}
   240  	WriteBodyRLP(db, hash, number, data)
   241  }
   242  
   243  // DeleteBody removes all block body data associated with a hash.
   244  func DeleteBody(db ethdb.Writer, hash common.Hash, number uint64) {
   245  	if err := db.Delete(blockBodyKey(number, hash)); err != nil {
   246  		log.Crit("Failed to delete block body", "err", err)
   247  	}
   248  }
   249  
   250  // ReadTdRLP retrieves a block's total difficulty corresponding to the hash in RLP encoding.
   251  func ReadTdRLP(db ethdb.Reader, hash common.Hash, number uint64) rlp.RawValue {
   252  	data, _ := db.Get(headerTDKey(number, hash))
   253  	return data
   254  }
   255  
   256  // ReadTd retrieves a block's total difficulty corresponding to the hash.
   257  func ReadTd(db ethdb.Reader, hash common.Hash, number uint64) *big.Int {
   258  	data := ReadTdRLP(db, hash, number)
   259  	if len(data) == 0 {
   260  		return nil
   261  	}
   262  	td := new(big.Int)
   263  	if err := rlp.Decode(bytes.NewReader(data), td); err != nil {
   264  		log.Error("Invalid block total difficulty RLP", "hash", hash, "err", err)
   265  		return nil
   266  	}
   267  	return td
   268  }
   269  
   270  // WriteTd stores the total difficulty of a block into the database.
   271  func WriteTd(db ethdb.Writer, hash common.Hash, number uint64, td *big.Int) {
   272  	data, err := rlp.EncodeToBytes(td)
   273  	if err != nil {
   274  		log.Crit("Failed to RLP encode block total difficulty", "err", err)
   275  	}
   276  	if err := db.Put(headerTDKey(number, hash), data); err != nil {
   277  		log.Crit("Failed to store block total difficulty", "err", err)
   278  	}
   279  }
   280  
   281  // DeleteTd removes all block total difficulty data associated with a hash.
   282  func DeleteTd(db ethdb.Writer, hash common.Hash, number uint64) {
   283  	if err := db.Delete(headerTDKey(number, hash)); err != nil {
   284  		log.Crit("Failed to delete block total difficulty", "err", err)
   285  	}
   286  }
   287  
   288  // HasReceipts verifies the existence of all the transaction receipts belonging
   289  // to a block.
   290  func HasReceipts(db ethdb.Reader, hash common.Hash, number uint64) bool {
   291  	if has, err := db.Has(blockReceiptsKey(number, hash)); !has || err != nil {
   292  		return false
   293  	}
   294  	return true
   295  }
   296  
   297  // ReadReceiptsRLP retrieves all the transaction receipts belonging to a block in RLP encoding.
   298  func ReadReceiptsRLP(db ethdb.Reader, hash common.Hash, number uint64) rlp.RawValue {
   299  	data, _ := db.Get(blockReceiptsKey(number, hash))
   300  	return data
   301  }
   302  
   303  // ReadRawReceipts retrieves all the transaction receipts belonging to a block.
   304  // The receipt metadata fields are not guaranteed to be populated, so they
   305  // should not be used. Use ReadReceipts instead if the metadata is needed.
   306  func ReadRawReceipts(db ethdb.Reader, hash common.Hash, number uint64) types.Receipts {
   307  	// Retrieve the flattened receipt slice
   308  	data := ReadReceiptsRLP(db, hash, number)
   309  	if len(data) == 0 {
   310  		return nil
   311  	}
   312  	// Convert the receipts from their storage form to their internal representation
   313  	storageReceipts := []*types.ReceiptForStorage{}
   314  	if err := rlp.DecodeBytes(data, &storageReceipts); err != nil {
   315  		log.Error("Invalid receipt array RLP", "hash", hash, "err", err)
   316  		return nil
   317  	}
   318  	receipts := make(types.Receipts, len(storageReceipts))
   319  	for i, storageReceipt := range storageReceipts {
   320  		receipts[i] = (*types.Receipt)(storageReceipt)
   321  	}
   322  	return receipts
   323  }
   324  
   325  // ReadReceipts retrieves all the transaction receipts belonging to a block, including
   326  // its correspoinding metadata fields. If it is unable to populate these metadata
   327  // fields then nil is returned.
   328  //
   329  // The current implementation populates these metadata fields by reading the receipts'
   330  // corresponding block body, so if the block body is not found it will return nil even
   331  // if the receipt itself is stored.
   332  func ReadReceipts(db ethdb.Reader, hash common.Hash, number uint64, config *params.ChainConfig) types.Receipts {
   333  	// We're deriving many fields from the block body, retrieve beside the receipt
   334  	receipts := ReadRawReceipts(db, hash, number)
   335  	if receipts == nil {
   336  		return nil
   337  	}
   338  	body := ReadBody(db, hash, number)
   339  	if body == nil {
   340  		log.Error("Missing body but have receipt", "hash", hash, "number", number)
   341  		return nil
   342  	}
   343  	if err := receipts.DeriveFields(config, hash, number, body.Transactions); err != nil {
   344  		log.Error("Failed to derive block receipts fields", "hash", hash, "number", number, "err", err)
   345  		return nil
   346  	}
   347  	return receipts
   348  }
   349  
   350  // WriteReceipts stores all the transaction receipts belonging to a block.
   351  func WriteReceipts(db ethdb.Writer, hash common.Hash, number uint64, receipts types.Receipts) {
   352  	// Convert the receipts into their storage form and serialize them
   353  	storageReceipts := make([]*types.ReceiptForStorage, len(receipts))
   354  	for i, receipt := range receipts {
   355  		storageReceipts[i] = (*types.ReceiptForStorage)(receipt)
   356  	}
   357  	bytes, err := rlp.EncodeToBytes(storageReceipts)
   358  	if err != nil {
   359  		log.Crit("Failed to encode block receipts", "err", err)
   360  	}
   361  	// Store the flattened receipt slice
   362  	if err := db.Put(blockReceiptsKey(number, hash), bytes); err != nil {
   363  		log.Crit("Failed to store block receipts", "err", err)
   364  	}
   365  }
   366  
   367  // DeleteReceipts removes all receipt data associated with a block hash.
   368  func DeleteReceipts(db ethdb.Writer, hash common.Hash, number uint64) {
   369  	if err := db.Delete(blockReceiptsKey(number, hash)); err != nil {
   370  		log.Crit("Failed to delete block receipts", "err", err)
   371  	}
   372  }
   373  
   374  // ReadBlock retrieves an entire block corresponding to the hash, assembling it
   375  // back from the stored header and body. If either the header or body could not
   376  // be retrieved nil is returned.
   377  //
   378  // Note, due to concurrent download of header and block body the header and thus
   379  // canonical hash can be stored in the database but the body data not (yet).
   380  func ReadBlock(db ethdb.Reader, hash common.Hash, number uint64) *types.Block {
   381  	header := ReadHeader(db, hash, number)
   382  	if header == nil {
   383  		return nil
   384  	}
   385  	body := ReadBody(db, hash, number)
   386  	if body == nil {
   387  		return nil
   388  	}
   389  	return types.NewBlockWithHeader(header).WithBody(body.Transactions, body.Uncles)
   390  }
   391  
   392  // WriteBlock serializes a block into the database, header and body separately.
   393  func WriteBlock(db ethdb.Writer, block *types.Block) {
   394  	WriteBody(db, block.Hash(), block.NumberU64(), block.Body())
   395  	WriteHeader(db, block.Header())
   396  }
   397  
   398  // DeleteBlock removes all block data associated with a hash.
   399  func DeleteBlock(db ethdb.Writer, hash common.Hash, number uint64) {
   400  	DeleteReceipts(db, hash, number)
   401  	DeleteHeader(db, hash, number)
   402  	DeleteBody(db, hash, number)
   403  	DeleteTd(db, hash, number)
   404  }
   405  
   406  // deleteBlockWithoutNumber removes all block data associated with a hash, except
   407  // the hash to number mapping.
   408  func deleteBlockWithoutNumber(db ethdb.Writer, hash common.Hash, number uint64) {
   409  	DeleteReceipts(db, hash, number)
   410  	deleteHeaderWithoutNumber(db, hash, number)
   411  	DeleteBody(db, hash, number)
   412  	DeleteTd(db, hash, number)
   413  }
   414  
   415  // FindCommonAncestor returns the last common ancestor of two block headers
   416  func FindCommonAncestor(db ethdb.Reader, a, b *types.Header) *types.Header {
   417  	for bn := b.Number.Uint64(); a.Number.Uint64() > bn; {
   418  		a = ReadHeader(db, a.ParentHash, a.Number.Uint64()-1)
   419  		if a == nil {
   420  			return nil
   421  		}
   422  	}
   423  	for an := a.Number.Uint64(); an < b.Number.Uint64(); {
   424  		b = ReadHeader(db, b.ParentHash, b.Number.Uint64()-1)
   425  		if b == nil {
   426  			return nil
   427  		}
   428  	}
   429  	for a.Hash() != b.Hash() {
   430  		a = ReadHeader(db, a.ParentHash, a.Number.Uint64()-1)
   431  		if a == nil {
   432  			return nil
   433  		}
   434  		b = ReadHeader(db, b.ParentHash, b.Number.Uint64()-1)
   435  		if b == nil {
   436  			return nil
   437  		}
   438  	}
   439  	return a
   440  }