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