github.com/ethereum/go-ethereum@v1.16.1/core/rawdb/accessors_history.go (about) 1 // Copyright 2025 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 "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 // ReadStateHistoryIndexMetadata retrieves the metadata of state history index. 29 func ReadStateHistoryIndexMetadata(db ethdb.KeyValueReader) []byte { 30 data, _ := db.Get(headStateHistoryIndexKey) 31 return data 32 } 33 34 // WriteStateHistoryIndexMetadata stores the metadata of state history index 35 // into database. 36 func WriteStateHistoryIndexMetadata(db ethdb.KeyValueWriter, blob []byte) { 37 if err := db.Put(headStateHistoryIndexKey, blob); err != nil { 38 log.Crit("Failed to store the metadata of state history index", "err", err) 39 } 40 } 41 42 // DeleteStateHistoryIndexMetadata removes the metadata of state history index. 43 func DeleteStateHistoryIndexMetadata(db ethdb.KeyValueWriter) { 44 if err := db.Delete(headStateHistoryIndexKey); err != nil { 45 log.Crit("Failed to delete the metadata of state history index", "err", err) 46 } 47 } 48 49 // ReadAccountHistoryIndex retrieves the account history index with the provided 50 // account address. 51 func ReadAccountHistoryIndex(db ethdb.KeyValueReader, addressHash common.Hash) []byte { 52 data, err := db.Get(accountHistoryIndexKey(addressHash)) 53 if err != nil || len(data) == 0 { 54 return nil 55 } 56 return data 57 } 58 59 // WriteAccountHistoryIndex writes the provided account history index into database. 60 func WriteAccountHistoryIndex(db ethdb.KeyValueWriter, addressHash common.Hash, data []byte) { 61 if err := db.Put(accountHistoryIndexKey(addressHash), data); err != nil { 62 log.Crit("Failed to store account history index", "err", err) 63 } 64 } 65 66 // DeleteAccountHistoryIndex deletes the specified account history index from 67 // the database. 68 func DeleteAccountHistoryIndex(db ethdb.KeyValueWriter, addressHash common.Hash) { 69 if err := db.Delete(accountHistoryIndexKey(addressHash)); err != nil { 70 log.Crit("Failed to delete account history index", "err", err) 71 } 72 } 73 74 // ReadStorageHistoryIndex retrieves the storage history index with the provided 75 // account address and storage key hash. 76 func ReadStorageHistoryIndex(db ethdb.KeyValueReader, addressHash common.Hash, storageHash common.Hash) []byte { 77 data, err := db.Get(storageHistoryIndexKey(addressHash, storageHash)) 78 if err != nil || len(data) == 0 { 79 return nil 80 } 81 return data 82 } 83 84 // WriteStorageHistoryIndex writes the provided storage history index into database. 85 func WriteStorageHistoryIndex(db ethdb.KeyValueWriter, addressHash common.Hash, storageHash common.Hash, data []byte) { 86 if err := db.Put(storageHistoryIndexKey(addressHash, storageHash), data); err != nil { 87 log.Crit("Failed to store storage history index", "err", err) 88 } 89 } 90 91 // DeleteStorageHistoryIndex deletes the specified state index from the database. 92 func DeleteStorageHistoryIndex(db ethdb.KeyValueWriter, addressHash common.Hash, storageHash common.Hash) { 93 if err := db.Delete(storageHistoryIndexKey(addressHash, storageHash)); err != nil { 94 log.Crit("Failed to delete storage history index", "err", err) 95 } 96 } 97 98 // ReadAccountHistoryIndexBlock retrieves the index block with the provided 99 // account address along with the block id. 100 func ReadAccountHistoryIndexBlock(db ethdb.KeyValueReader, addressHash common.Hash, blockID uint32) []byte { 101 data, err := db.Get(accountHistoryIndexBlockKey(addressHash, blockID)) 102 if err != nil || len(data) == 0 { 103 return nil 104 } 105 return data 106 } 107 108 // WriteAccountHistoryIndexBlock writes the provided index block into database. 109 func WriteAccountHistoryIndexBlock(db ethdb.KeyValueWriter, addressHash common.Hash, blockID uint32, data []byte) { 110 if err := db.Put(accountHistoryIndexBlockKey(addressHash, blockID), data); err != nil { 111 log.Crit("Failed to store account index block", "err", err) 112 } 113 } 114 115 // DeleteAccountHistoryIndexBlock deletes the specified index block from the database. 116 func DeleteAccountHistoryIndexBlock(db ethdb.KeyValueWriter, addressHash common.Hash, blockID uint32) { 117 if err := db.Delete(accountHistoryIndexBlockKey(addressHash, blockID)); err != nil { 118 log.Crit("Failed to delete account index block", "err", err) 119 } 120 } 121 122 // ReadStorageHistoryIndexBlock retrieves the index block with the provided state 123 // identifier along with the block id. 124 func ReadStorageHistoryIndexBlock(db ethdb.KeyValueReader, addressHash common.Hash, storageHash common.Hash, blockID uint32) []byte { 125 data, err := db.Get(storageHistoryIndexBlockKey(addressHash, storageHash, blockID)) 126 if err != nil || len(data) == 0 { 127 return nil 128 } 129 return data 130 } 131 132 // WriteStorageHistoryIndexBlock writes the provided index block into database. 133 func WriteStorageHistoryIndexBlock(db ethdb.KeyValueWriter, addressHash common.Hash, storageHash common.Hash, id uint32, data []byte) { 134 if err := db.Put(storageHistoryIndexBlockKey(addressHash, storageHash, id), data); err != nil { 135 log.Crit("Failed to store storage index block", "err", err) 136 } 137 } 138 139 // DeleteStorageHistoryIndexBlock deletes the specified index block from the database. 140 func DeleteStorageHistoryIndexBlock(db ethdb.KeyValueWriter, addressHash common.Hash, storageHash common.Hash, id uint32) { 141 if err := db.Delete(storageHistoryIndexBlockKey(addressHash, storageHash, id)); err != nil { 142 log.Crit("Failed to delete storage index block", "err", err) 143 } 144 } 145 146 // increaseKey increase the input key by one bit. Return nil if the entire 147 // addition operation overflows. 148 func increaseKey(key []byte) []byte { 149 for i := len(key) - 1; i >= 0; i-- { 150 key[i]++ 151 if key[i] != 0x0 { 152 return key 153 } 154 } 155 return nil 156 } 157 158 // DeleteStateHistoryIndex completely removes all history indexing data, including 159 // indexes for accounts and storages. 160 // 161 // Note, this method assumes the storage space with prefix `StateHistoryIndexPrefix` 162 // is exclusively occupied by the history indexing data! 163 func DeleteStateHistoryIndex(db ethdb.KeyValueRangeDeleter) { 164 start := StateHistoryIndexPrefix 165 limit := increaseKey(bytes.Clone(StateHistoryIndexPrefix)) 166 167 // Try to remove the data in the range by a loop, as the leveldb 168 // doesn't support the native range deletion. 169 for { 170 err := db.DeleteRange(start, limit) 171 if err == nil { 172 return 173 } 174 if errors.Is(err, ethdb.ErrTooManyKeys) { 175 continue 176 } 177 log.Crit("Failed to delete history index range", "err", err) 178 } 179 }