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