github.com/ethereum/go-ethereum@v1.14.3/core/rawdb/accessors_state.go (about)

     1  // Copyright 2020 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  	"encoding/binary"
    21  
    22  	"github.com/ethereum/go-ethereum/common"
    23  	"github.com/ethereum/go-ethereum/ethdb"
    24  	"github.com/ethereum/go-ethereum/log"
    25  )
    26  
    27  // ReadPreimage retrieves a single preimage of the provided hash.
    28  func ReadPreimage(db ethdb.KeyValueReader, hash common.Hash) []byte {
    29  	data, _ := db.Get(preimageKey(hash))
    30  	return data
    31  }
    32  
    33  // WritePreimages writes the provided set of preimages to the database.
    34  func WritePreimages(db ethdb.KeyValueWriter, preimages map[common.Hash][]byte) {
    35  	for hash, preimage := range preimages {
    36  		if err := db.Put(preimageKey(hash), preimage); err != nil {
    37  			log.Crit("Failed to store trie preimage", "err", err)
    38  		}
    39  	}
    40  	preimageCounter.Inc(int64(len(preimages)))
    41  	preimageHitCounter.Inc(int64(len(preimages)))
    42  }
    43  
    44  // ReadCode retrieves the contract code of the provided code hash.
    45  func ReadCode(db ethdb.KeyValueReader, hash common.Hash) []byte {
    46  	// Try with the prefixed code scheme first, if not then try with legacy
    47  	// scheme.
    48  	data := ReadCodeWithPrefix(db, hash)
    49  	if len(data) != 0 {
    50  		return data
    51  	}
    52  	data, _ = db.Get(hash.Bytes())
    53  	return data
    54  }
    55  
    56  // ReadCodeWithPrefix retrieves the contract code of the provided code hash.
    57  // The main difference between this function and ReadCode is this function
    58  // will only check the existence with latest scheme(with prefix).
    59  func ReadCodeWithPrefix(db ethdb.KeyValueReader, hash common.Hash) []byte {
    60  	data, _ := db.Get(codeKey(hash))
    61  	return data
    62  }
    63  
    64  // HasCode checks if the contract code corresponding to the
    65  // provided code hash is present in the db.
    66  func HasCode(db ethdb.KeyValueReader, hash common.Hash) bool {
    67  	// Try with the prefixed code scheme first, if not then try with legacy
    68  	// scheme.
    69  	if ok := HasCodeWithPrefix(db, hash); ok {
    70  		return true
    71  	}
    72  	ok, _ := db.Has(hash.Bytes())
    73  	return ok
    74  }
    75  
    76  // HasCodeWithPrefix checks if the contract code corresponding to the
    77  // provided code hash is present in the db. This function will only check
    78  // presence using the prefix-scheme.
    79  func HasCodeWithPrefix(db ethdb.KeyValueReader, hash common.Hash) bool {
    80  	ok, _ := db.Has(codeKey(hash))
    81  	return ok
    82  }
    83  
    84  // WriteCode writes the provided contract code database.
    85  func WriteCode(db ethdb.KeyValueWriter, hash common.Hash, code []byte) {
    86  	if err := db.Put(codeKey(hash), code); err != nil {
    87  		log.Crit("Failed to store contract code", "err", err)
    88  	}
    89  }
    90  
    91  // DeleteCode deletes the specified contract code from the database.
    92  func DeleteCode(db ethdb.KeyValueWriter, hash common.Hash) {
    93  	if err := db.Delete(codeKey(hash)); err != nil {
    94  		log.Crit("Failed to delete contract code", "err", err)
    95  	}
    96  }
    97  
    98  // ReadStateID retrieves the state id with the provided state root.
    99  func ReadStateID(db ethdb.KeyValueReader, root common.Hash) *uint64 {
   100  	data, err := db.Get(stateIDKey(root))
   101  	if err != nil || len(data) == 0 {
   102  		return nil
   103  	}
   104  	number := binary.BigEndian.Uint64(data)
   105  	return &number
   106  }
   107  
   108  // WriteStateID writes the provided state lookup to database.
   109  func WriteStateID(db ethdb.KeyValueWriter, root common.Hash, id uint64) {
   110  	var buff [8]byte
   111  	binary.BigEndian.PutUint64(buff[:], id)
   112  	if err := db.Put(stateIDKey(root), buff[:]); err != nil {
   113  		log.Crit("Failed to store state ID", "err", err)
   114  	}
   115  }
   116  
   117  // DeleteStateID deletes the specified state lookup from the database.
   118  func DeleteStateID(db ethdb.KeyValueWriter, root common.Hash) {
   119  	if err := db.Delete(stateIDKey(root)); err != nil {
   120  		log.Crit("Failed to delete state ID", "err", err)
   121  	}
   122  }
   123  
   124  // ReadPersistentStateID retrieves the id of the persistent state from the database.
   125  func ReadPersistentStateID(db ethdb.KeyValueReader) uint64 {
   126  	data, _ := db.Get(persistentStateIDKey)
   127  	if len(data) != 8 {
   128  		return 0
   129  	}
   130  	return binary.BigEndian.Uint64(data)
   131  }
   132  
   133  // WritePersistentStateID stores the id of the persistent state into database.
   134  func WritePersistentStateID(db ethdb.KeyValueWriter, number uint64) {
   135  	if err := db.Put(persistentStateIDKey, encodeBlockNumber(number)); err != nil {
   136  		log.Crit("Failed to store the persistent state ID", "err", err)
   137  	}
   138  }
   139  
   140  // ReadTrieJournal retrieves the serialized in-memory trie nodes of layers saved at
   141  // the last shutdown.
   142  func ReadTrieJournal(db ethdb.KeyValueReader) []byte {
   143  	data, _ := db.Get(trieJournalKey)
   144  	return data
   145  }
   146  
   147  // WriteTrieJournal stores the serialized in-memory trie nodes of layers to save at
   148  // shutdown.
   149  func WriteTrieJournal(db ethdb.KeyValueWriter, journal []byte) {
   150  	if err := db.Put(trieJournalKey, journal); err != nil {
   151  		log.Crit("Failed to store tries journal", "err", err)
   152  	}
   153  }
   154  
   155  // DeleteTrieJournal deletes the serialized in-memory trie nodes of layers saved at
   156  // the last shutdown.
   157  func DeleteTrieJournal(db ethdb.KeyValueWriter) {
   158  	if err := db.Delete(trieJournalKey); err != nil {
   159  		log.Crit("Failed to remove tries journal", "err", err)
   160  	}
   161  }
   162  
   163  // ReadStateHistoryMeta retrieves the metadata corresponding to the specified
   164  // state history. Compute the position of state history in freezer by minus
   165  // one since the id of first state history starts from one(zero for initial
   166  // state).
   167  func ReadStateHistoryMeta(db ethdb.AncientReaderOp, id uint64) []byte {
   168  	blob, err := db.Ancient(stateHistoryMeta, id-1)
   169  	if err != nil {
   170  		return nil
   171  	}
   172  	return blob
   173  }
   174  
   175  // ReadStateHistoryMetaList retrieves a batch of meta objects with the specified
   176  // start position and count. Compute the position of state history in freezer by
   177  // minus one since the id of first state history starts from one(zero for initial
   178  // state).
   179  func ReadStateHistoryMetaList(db ethdb.AncientReaderOp, start uint64, count uint64) ([][]byte, error) {
   180  	return db.AncientRange(stateHistoryMeta, start-1, count, 0)
   181  }
   182  
   183  // ReadStateAccountIndex retrieves the state root corresponding to the specified
   184  // state history. Compute the position of state history in freezer by minus one
   185  // since the id of first state history starts from one(zero for initial state).
   186  func ReadStateAccountIndex(db ethdb.AncientReaderOp, id uint64) []byte {
   187  	blob, err := db.Ancient(stateHistoryAccountIndex, id-1)
   188  	if err != nil {
   189  		return nil
   190  	}
   191  	return blob
   192  }
   193  
   194  // ReadStateStorageIndex retrieves the state root corresponding to the specified
   195  // state history. Compute the position of state history in freezer by minus one
   196  // since the id of first state history starts from one(zero for initial state).
   197  func ReadStateStorageIndex(db ethdb.AncientReaderOp, id uint64) []byte {
   198  	blob, err := db.Ancient(stateHistoryStorageIndex, id-1)
   199  	if err != nil {
   200  		return nil
   201  	}
   202  	return blob
   203  }
   204  
   205  // ReadStateAccountHistory retrieves the state root corresponding to the specified
   206  // state history. Compute the position of state history in freezer by minus one
   207  // since the id of first state history starts from one(zero for initial state).
   208  func ReadStateAccountHistory(db ethdb.AncientReaderOp, id uint64) []byte {
   209  	blob, err := db.Ancient(stateHistoryAccountData, id-1)
   210  	if err != nil {
   211  		return nil
   212  	}
   213  	return blob
   214  }
   215  
   216  // ReadStateStorageHistory retrieves the state root corresponding to the specified
   217  // state history. Compute the position of state history in freezer by minus one
   218  // since the id of first state history starts from one(zero for initial state).
   219  func ReadStateStorageHistory(db ethdb.AncientReaderOp, id uint64) []byte {
   220  	blob, err := db.Ancient(stateHistoryStorageData, id-1)
   221  	if err != nil {
   222  		return nil
   223  	}
   224  	return blob
   225  }
   226  
   227  // ReadStateHistory retrieves the state history from database with provided id.
   228  // Compute the position of state history in freezer by minus one since the id
   229  // of first state history starts from one(zero for initial state).
   230  func ReadStateHistory(db ethdb.AncientReaderOp, id uint64) ([]byte, []byte, []byte, []byte, []byte, error) {
   231  	meta, err := db.Ancient(stateHistoryMeta, id-1)
   232  	if err != nil {
   233  		return nil, nil, nil, nil, nil, err
   234  	}
   235  	accountIndex, err := db.Ancient(stateHistoryAccountIndex, id-1)
   236  	if err != nil {
   237  		return nil, nil, nil, nil, nil, err
   238  	}
   239  	storageIndex, err := db.Ancient(stateHistoryStorageIndex, id-1)
   240  	if err != nil {
   241  		return nil, nil, nil, nil, nil, err
   242  	}
   243  	accountData, err := db.Ancient(stateHistoryAccountData, id-1)
   244  	if err != nil {
   245  		return nil, nil, nil, nil, nil, err
   246  	}
   247  	storageData, err := db.Ancient(stateHistoryStorageData, id-1)
   248  	if err != nil {
   249  		return nil, nil, nil, nil, nil, err
   250  	}
   251  	return meta, accountIndex, storageIndex, accountData, storageData, nil
   252  }
   253  
   254  // WriteStateHistory writes the provided state history to database. Compute the
   255  // position of state history in freezer by minus one since the id of first state
   256  // history starts from one(zero for initial state).
   257  func WriteStateHistory(db ethdb.AncientWriter, id uint64, meta []byte, accountIndex []byte, storageIndex []byte, accounts []byte, storages []byte) {
   258  	db.ModifyAncients(func(op ethdb.AncientWriteOp) error {
   259  		op.AppendRaw(stateHistoryMeta, id-1, meta)
   260  		op.AppendRaw(stateHistoryAccountIndex, id-1, accountIndex)
   261  		op.AppendRaw(stateHistoryStorageIndex, id-1, storageIndex)
   262  		op.AppendRaw(stateHistoryAccountData, id-1, accounts)
   263  		op.AppendRaw(stateHistoryStorageData, id-1, storages)
   264  		return nil
   265  	})
   266  }