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  }