mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-05-24 08:49:29 +00:00
triedb/pathdb: rename history to state history (#32498)
This is a internal refactoring PR, renaming the history to stateHistory. It's a pre-requisite PR for merging trienode history, avoid the name conflict.
This commit is contained in:
parent
16bd164f3b
commit
8c58f4920d
11 changed files with 105 additions and 103 deletions
|
|
@ -219,12 +219,14 @@ type Database struct {
|
||||||
isVerkle bool // Flag if database is used for verkle tree
|
isVerkle bool // Flag if database is used for verkle tree
|
||||||
hasher nodeHasher // Trie node hasher
|
hasher nodeHasher // Trie node hasher
|
||||||
|
|
||||||
config *Config // Configuration for database
|
config *Config // Configuration for database
|
||||||
diskdb ethdb.Database // Persistent storage for matured trie nodes
|
diskdb ethdb.Database // Persistent storage for matured trie nodes
|
||||||
tree *layerTree // The group for all known layers
|
tree *layerTree // The group for all known layers
|
||||||
freezer ethdb.ResettableAncientStore // Freezer for storing trie histories, nil possible in tests
|
|
||||||
lock sync.RWMutex // Lock to prevent mutations from happening at the same time
|
stateFreezer ethdb.ResettableAncientStore // Freezer for storing state histories, nil possible in tests
|
||||||
indexer *historyIndexer // History indexer
|
stateIndexer *historyIndexer // History indexer historical state data, nil possible
|
||||||
|
|
||||||
|
lock sync.RWMutex // Lock to prevent mutations from happening at the same time
|
||||||
}
|
}
|
||||||
|
|
||||||
// New attempts to load an already existing layer from a persistent key-value
|
// New attempts to load an already existing layer from a persistent key-value
|
||||||
|
|
@ -275,8 +277,8 @@ func New(diskdb ethdb.Database, config *Config, isVerkle bool) *Database {
|
||||||
log.Crit("Failed to setup the generator", "err", err)
|
log.Crit("Failed to setup the generator", "err", err)
|
||||||
}
|
}
|
||||||
// TODO (rjl493456442) disable the background indexing in read-only mode
|
// TODO (rjl493456442) disable the background indexing in read-only mode
|
||||||
if db.freezer != nil && db.config.EnableStateIndexing {
|
if db.stateFreezer != nil && db.config.EnableStateIndexing {
|
||||||
db.indexer = newHistoryIndexer(db.diskdb, db.freezer, db.tree.bottom().stateID())
|
db.stateIndexer = newHistoryIndexer(db.diskdb, db.stateFreezer, db.tree.bottom().stateID())
|
||||||
log.Info("Enabled state history indexing")
|
log.Info("Enabled state history indexing")
|
||||||
}
|
}
|
||||||
fields := config.fields()
|
fields := config.fields()
|
||||||
|
|
@ -304,14 +306,14 @@ func (db *Database) repairHistory() error {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Crit("Failed to open state history freezer", "err", err)
|
log.Crit("Failed to open state history freezer", "err", err)
|
||||||
}
|
}
|
||||||
db.freezer = freezer
|
db.stateFreezer = freezer
|
||||||
|
|
||||||
// Reset the entire state histories if the trie database is not initialized
|
// Reset the entire state histories if the trie database is not initialized
|
||||||
// yet. This action is necessary because these state histories are not
|
// yet. This action is necessary because these state histories are not
|
||||||
// expected to exist without an initialized trie database.
|
// expected to exist without an initialized trie database.
|
||||||
id := db.tree.bottom().stateID()
|
id := db.tree.bottom().stateID()
|
||||||
if id == 0 {
|
if id == 0 {
|
||||||
frozen, err := db.freezer.Ancients()
|
frozen, err := db.stateFreezer.Ancients()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Crit("Failed to retrieve head of state history", "err", err)
|
log.Crit("Failed to retrieve head of state history", "err", err)
|
||||||
}
|
}
|
||||||
|
|
@ -321,7 +323,7 @@ func (db *Database) repairHistory() error {
|
||||||
// Purge all state history indexing data first
|
// Purge all state history indexing data first
|
||||||
rawdb.DeleteStateHistoryIndexMetadata(db.diskdb)
|
rawdb.DeleteStateHistoryIndexMetadata(db.diskdb)
|
||||||
rawdb.DeleteStateHistoryIndex(db.diskdb)
|
rawdb.DeleteStateHistoryIndex(db.diskdb)
|
||||||
err := db.freezer.Reset()
|
err := db.stateFreezer.Reset()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Crit("Failed to reset state histories", "err", err)
|
log.Crit("Failed to reset state histories", "err", err)
|
||||||
}
|
}
|
||||||
|
|
@ -331,7 +333,7 @@ func (db *Database) repairHistory() error {
|
||||||
}
|
}
|
||||||
// Truncate the extra state histories above in freezer in case it's not
|
// Truncate the extra state histories above in freezer in case it's not
|
||||||
// aligned with the disk layer. It might happen after a unclean shutdown.
|
// aligned with the disk layer. It might happen after a unclean shutdown.
|
||||||
pruned, err := truncateFromHead(db.diskdb, db.freezer, id)
|
pruned, err := truncateFromHead(db.diskdb, db.stateFreezer, id)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Crit("Failed to truncate extra state histories", "err", err)
|
log.Crit("Failed to truncate extra state histories", "err", err)
|
||||||
}
|
}
|
||||||
|
|
@ -507,13 +509,13 @@ func (db *Database) Enable(root common.Hash) error {
|
||||||
// all root->id mappings should be removed as well. Since
|
// all root->id mappings should be removed as well. Since
|
||||||
// mappings can be huge and might take a while to clear
|
// mappings can be huge and might take a while to clear
|
||||||
// them, just leave them in disk and wait for overwriting.
|
// them, just leave them in disk and wait for overwriting.
|
||||||
if db.freezer != nil {
|
if db.stateFreezer != nil {
|
||||||
// TODO(rjl493456442) would be better to group them into a batch.
|
// TODO(rjl493456442) would be better to group them into a batch.
|
||||||
//
|
//
|
||||||
// Purge all state history indexing data first
|
// Purge all state history indexing data first
|
||||||
rawdb.DeleteStateHistoryIndexMetadata(db.diskdb)
|
rawdb.DeleteStateHistoryIndexMetadata(db.diskdb)
|
||||||
rawdb.DeleteStateHistoryIndex(db.diskdb)
|
rawdb.DeleteStateHistoryIndex(db.diskdb)
|
||||||
if err := db.freezer.Reset(); err != nil {
|
if err := db.stateFreezer.Reset(); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -529,9 +531,9 @@ func (db *Database) Enable(root common.Hash) error {
|
||||||
// To ensure the history indexer always matches the current state, we must:
|
// To ensure the history indexer always matches the current state, we must:
|
||||||
// 1. Close any existing indexer
|
// 1. Close any existing indexer
|
||||||
// 2. Re-initialize the indexer so it starts indexing from the new state root.
|
// 2. Re-initialize the indexer so it starts indexing from the new state root.
|
||||||
if db.indexer != nil && db.freezer != nil && db.config.EnableStateIndexing {
|
if db.stateIndexer != nil && db.stateFreezer != nil && db.config.EnableStateIndexing {
|
||||||
db.indexer.close()
|
db.stateIndexer.close()
|
||||||
db.indexer = newHistoryIndexer(db.diskdb, db.freezer, db.tree.bottom().stateID())
|
db.stateIndexer = newHistoryIndexer(db.diskdb, db.stateFreezer, db.tree.bottom().stateID())
|
||||||
log.Info("Re-enabled state history indexing")
|
log.Info("Re-enabled state history indexing")
|
||||||
}
|
}
|
||||||
log.Info("Rebuilt trie database", "root", root)
|
log.Info("Rebuilt trie database", "root", root)
|
||||||
|
|
@ -551,7 +553,7 @@ func (db *Database) Recover(root common.Hash) error {
|
||||||
if err := db.modifyAllowed(); err != nil {
|
if err := db.modifyAllowed(); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if db.freezer == nil {
|
if db.stateFreezer == nil {
|
||||||
return errors.New("state rollback is non-supported")
|
return errors.New("state rollback is non-supported")
|
||||||
}
|
}
|
||||||
// Short circuit if the target state is not recoverable
|
// Short circuit if the target state is not recoverable
|
||||||
|
|
@ -564,7 +566,7 @@ func (db *Database) Recover(root common.Hash) error {
|
||||||
dl = db.tree.bottom()
|
dl = db.tree.bottom()
|
||||||
)
|
)
|
||||||
for dl.rootHash() != root {
|
for dl.rootHash() != root {
|
||||||
h, err := readHistory(db.freezer, dl.stateID())
|
h, err := readStateHistory(db.stateFreezer, dl.stateID())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
@ -585,7 +587,7 @@ func (db *Database) Recover(root common.Hash) error {
|
||||||
if err := db.diskdb.SyncKeyValue(); err != nil {
|
if err := db.diskdb.SyncKeyValue(); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
_, err := truncateFromHead(db.diskdb, db.freezer, dl.stateID())
|
_, err := truncateFromHead(db.diskdb, db.stateFreezer, dl.stateID())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
@ -613,12 +615,12 @@ func (db *Database) Recoverable(root common.Hash) bool {
|
||||||
// dev mode. As a consequence, the Pathdb loses the ability for deep reorg
|
// dev mode. As a consequence, the Pathdb loses the ability for deep reorg
|
||||||
// in certain cases.
|
// in certain cases.
|
||||||
// TODO(rjl493456442): Implement the in-memory ancient store.
|
// TODO(rjl493456442): Implement the in-memory ancient store.
|
||||||
if db.freezer == nil {
|
if db.stateFreezer == nil {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
// Ensure the requested state is a canonical state and all state
|
// Ensure the requested state is a canonical state and all state
|
||||||
// histories in range [id+1, disklayer.ID] are present and complete.
|
// histories in range [id+1, disklayer.ID] are present and complete.
|
||||||
return checkHistories(db.freezer, *id+1, dl.stateID()-*id, func(m *meta) error {
|
return checkStateHistories(db.stateFreezer, *id+1, dl.stateID()-*id, func(m *meta) error {
|
||||||
if m.parent != root {
|
if m.parent != root {
|
||||||
return errors.New("unexpected state history")
|
return errors.New("unexpected state history")
|
||||||
}
|
}
|
||||||
|
|
@ -646,14 +648,14 @@ func (db *Database) Close() error {
|
||||||
dl.resetCache() // release the memory held by clean cache
|
dl.resetCache() // release the memory held by clean cache
|
||||||
|
|
||||||
// Terminate the background state history indexer
|
// Terminate the background state history indexer
|
||||||
if db.indexer != nil {
|
if db.stateIndexer != nil {
|
||||||
db.indexer.close()
|
db.stateIndexer.close()
|
||||||
}
|
}
|
||||||
// Close the attached state history freezer.
|
// Close the attached state history freezer.
|
||||||
if db.freezer == nil {
|
if db.stateFreezer == nil {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
return db.freezer.Close()
|
return db.stateFreezer.Close()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Size returns the current storage size of the memory cache in front of the
|
// Size returns the current storage size of the memory cache in front of the
|
||||||
|
|
@ -704,7 +706,7 @@ func (db *Database) journalPath() string {
|
||||||
// End: State ID of the last history for the query. 0 implies the last available
|
// End: State ID of the last history for the query. 0 implies the last available
|
||||||
// object is selected as the ending point. Note end is included in the query.
|
// object is selected as the ending point. Note end is included in the query.
|
||||||
func (db *Database) AccountHistory(address common.Address, start, end uint64) (*HistoryStats, error) {
|
func (db *Database) AccountHistory(address common.Address, start, end uint64) (*HistoryStats, error) {
|
||||||
return accountHistory(db.freezer, address, start, end)
|
return accountHistory(db.stateFreezer, address, start, end)
|
||||||
}
|
}
|
||||||
|
|
||||||
// StorageHistory inspects the storage history within the specified range.
|
// StorageHistory inspects the storage history within the specified range.
|
||||||
|
|
@ -717,22 +719,22 @@ func (db *Database) AccountHistory(address common.Address, start, end uint64) (*
|
||||||
//
|
//
|
||||||
// Note, slot refers to the hash of the raw slot key.
|
// Note, slot refers to the hash of the raw slot key.
|
||||||
func (db *Database) StorageHistory(address common.Address, slot common.Hash, start uint64, end uint64) (*HistoryStats, error) {
|
func (db *Database) StorageHistory(address common.Address, slot common.Hash, start uint64, end uint64) (*HistoryStats, error) {
|
||||||
return storageHistory(db.freezer, address, slot, start, end)
|
return storageHistory(db.stateFreezer, address, slot, start, end)
|
||||||
}
|
}
|
||||||
|
|
||||||
// HistoryRange returns the block numbers associated with earliest and latest
|
// HistoryRange returns the block numbers associated with earliest and latest
|
||||||
// state history in the local store.
|
// state history in the local store.
|
||||||
func (db *Database) HistoryRange() (uint64, uint64, error) {
|
func (db *Database) HistoryRange() (uint64, uint64, error) {
|
||||||
return historyRange(db.freezer)
|
return historyRange(db.stateFreezer)
|
||||||
}
|
}
|
||||||
|
|
||||||
// IndexProgress returns the indexing progress made so far. It provides the
|
// IndexProgress returns the indexing progress made so far. It provides the
|
||||||
// number of states that remain unindexed.
|
// number of states that remain unindexed.
|
||||||
func (db *Database) IndexProgress() (uint64, error) {
|
func (db *Database) IndexProgress() (uint64, error) {
|
||||||
if db.indexer == nil {
|
if db.stateIndexer == nil {
|
||||||
return 0, nil
|
return 0, nil
|
||||||
}
|
}
|
||||||
return db.indexer.progress()
|
return db.stateIndexer.progress()
|
||||||
}
|
}
|
||||||
|
|
||||||
// AccountIterator creates a new account iterator for the specified root hash and
|
// AccountIterator creates a new account iterator for the specified root hash and
|
||||||
|
|
|
||||||
|
|
@ -426,7 +426,7 @@ func (t *tester) verifyHistory() error {
|
||||||
for i, root := range t.roots {
|
for i, root := range t.roots {
|
||||||
// The state history related to the state above disk layer should not exist.
|
// The state history related to the state above disk layer should not exist.
|
||||||
if i > bottom {
|
if i > bottom {
|
||||||
_, err := readHistory(t.db.freezer, uint64(i+1))
|
_, err := readStateHistory(t.db.stateFreezer, uint64(i+1))
|
||||||
if err == nil {
|
if err == nil {
|
||||||
return errors.New("unexpected state history")
|
return errors.New("unexpected state history")
|
||||||
}
|
}
|
||||||
|
|
@ -434,7 +434,7 @@ func (t *tester) verifyHistory() error {
|
||||||
}
|
}
|
||||||
// The state history related to the state below or equal to the disk layer
|
// The state history related to the state below or equal to the disk layer
|
||||||
// should exist.
|
// should exist.
|
||||||
obj, err := readHistory(t.db.freezer, uint64(i+1))
|
obj, err := readStateHistory(t.db.stateFreezer, uint64(i+1))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
@ -568,7 +568,7 @@ func TestDisable(t *testing.T) {
|
||||||
t.Fatal("Failed to clean journal")
|
t.Fatal("Failed to clean journal")
|
||||||
}
|
}
|
||||||
// Ensure all trie histories are removed
|
// Ensure all trie histories are removed
|
||||||
n, err := tester.db.freezer.Ancients()
|
n, err := tester.db.stateFreezer.Ancients()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal("Failed to clean state history")
|
t.Fatal("Failed to clean state history")
|
||||||
}
|
}
|
||||||
|
|
@ -724,7 +724,7 @@ func TestTailTruncateHistory(t *testing.T) {
|
||||||
tester.db.Close()
|
tester.db.Close()
|
||||||
tester.db = New(tester.db.diskdb, &Config{StateHistory: 10}, false)
|
tester.db = New(tester.db.diskdb, &Config{StateHistory: 10}, false)
|
||||||
|
|
||||||
head, err := tester.db.freezer.Ancients()
|
head, err := tester.db.stateFreezer.Ancients()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("Failed to obtain freezer head")
|
t.Fatalf("Failed to obtain freezer head")
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -337,16 +337,16 @@ func (dl *diskLayer) commit(bottom *diffLayer, force bool) (*diskLayer, error) {
|
||||||
overflow bool
|
overflow bool
|
||||||
oldest uint64
|
oldest uint64
|
||||||
)
|
)
|
||||||
if dl.db.freezer != nil {
|
if dl.db.stateFreezer != nil {
|
||||||
// Bail out with an error if writing the state history fails.
|
// Bail out with an error if writing the state history fails.
|
||||||
// This can happen, for example, if the device is full.
|
// This can happen, for example, if the device is full.
|
||||||
err := writeHistory(dl.db.freezer, bottom)
|
err := writeStateHistory(dl.db.stateFreezer, bottom)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
// Determine if the persisted history object has exceeded the configured
|
// Determine if the persisted history object has exceeded the configured
|
||||||
// limitation, set the overflow as true if so.
|
// limitation, set the overflow as true if so.
|
||||||
tail, err := dl.db.freezer.Tail()
|
tail, err := dl.db.stateFreezer.Tail()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
@ -356,8 +356,8 @@ func (dl *diskLayer) commit(bottom *diffLayer, force bool) (*diskLayer, error) {
|
||||||
oldest = bottom.stateID() - limit + 1 // track the id of history **after truncation**
|
oldest = bottom.stateID() - limit + 1 // track the id of history **after truncation**
|
||||||
}
|
}
|
||||||
// Notify the state history indexer for newly created history
|
// Notify the state history indexer for newly created history
|
||||||
if dl.db.indexer != nil {
|
if dl.db.stateIndexer != nil {
|
||||||
if err := dl.db.indexer.extend(bottom.stateID()); err != nil {
|
if err := dl.db.stateIndexer.extend(bottom.stateID()); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -418,7 +418,7 @@ func (dl *diskLayer) commit(bottom *diffLayer, force bool) (*diskLayer, error) {
|
||||||
|
|
||||||
// Freeze the live buffer and schedule background flushing
|
// Freeze the live buffer and schedule background flushing
|
||||||
dl.frozen = combined
|
dl.frozen = combined
|
||||||
dl.frozen.flush(bottom.root, dl.db.diskdb, dl.db.freezer, progress, dl.nodes, dl.states, bottom.stateID(), func() {
|
dl.frozen.flush(bottom.root, dl.db.diskdb, dl.db.stateFreezer, progress, dl.nodes, dl.states, bottom.stateID(), func() {
|
||||||
// Resume the background generation if it's not completed yet.
|
// Resume the background generation if it's not completed yet.
|
||||||
// The generator is assumed to be available if the progress is
|
// The generator is assumed to be available if the progress is
|
||||||
// not nil.
|
// not nil.
|
||||||
|
|
@ -448,7 +448,7 @@ func (dl *diskLayer) commit(bottom *diffLayer, force bool) (*diskLayer, error) {
|
||||||
// To remove outdated history objects from the end, we set the 'tail' parameter
|
// To remove outdated history objects from the end, we set the 'tail' parameter
|
||||||
// to 'oldest-1' due to the offset between the freezer index and the history ID.
|
// to 'oldest-1' due to the offset between the freezer index and the history ID.
|
||||||
if overflow {
|
if overflow {
|
||||||
pruned, err := truncateFromTail(ndl.db.diskdb, ndl.db.freezer, oldest-1)
|
pruned, err := truncateFromTail(ndl.db.diskdb, ndl.db.stateFreezer, oldest-1)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
@ -458,7 +458,7 @@ func (dl *diskLayer) commit(bottom *diffLayer, force bool) (*diskLayer, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// revert applies the given state history and return a reverted disk layer.
|
// revert applies the given state history and return a reverted disk layer.
|
||||||
func (dl *diskLayer) revert(h *history) (*diskLayer, error) {
|
func (dl *diskLayer) revert(h *stateHistory) (*diskLayer, error) {
|
||||||
start := time.Now()
|
start := time.Now()
|
||||||
if h.meta.root != dl.rootHash() {
|
if h.meta.root != dl.rootHash() {
|
||||||
return nil, errUnexpectedHistory
|
return nil, errUnexpectedHistory
|
||||||
|
|
@ -484,8 +484,8 @@ func (dl *diskLayer) revert(h *history) (*diskLayer, error) {
|
||||||
dl.stale = true
|
dl.stale = true
|
||||||
|
|
||||||
// Unindex the corresponding state history
|
// Unindex the corresponding state history
|
||||||
if dl.db.indexer != nil {
|
if dl.db.stateIndexer != nil {
|
||||||
if err := dl.db.indexer.shorten(dl.id); err != nil {
|
if err := dl.db.stateIndexer.shorten(dl.id); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -180,7 +180,7 @@ func TestBatchIndexerWrite(t *testing.T) {
|
||||||
var (
|
var (
|
||||||
db = rawdb.NewMemoryDatabase()
|
db = rawdb.NewMemoryDatabase()
|
||||||
batch = newBatchIndexer(db, false)
|
batch = newBatchIndexer(db, false)
|
||||||
histories = makeHistories(10)
|
histories = makeStateHistories(10)
|
||||||
)
|
)
|
||||||
for i, h := range histories {
|
for i, h := range histories {
|
||||||
if err := batch.process(h, uint64(i+1)); err != nil {
|
if err := batch.process(h, uint64(i+1)); err != nil {
|
||||||
|
|
@ -257,7 +257,7 @@ func TestBatchIndexerDelete(t *testing.T) {
|
||||||
var (
|
var (
|
||||||
db = rawdb.NewMemoryDatabase()
|
db = rawdb.NewMemoryDatabase()
|
||||||
bw = newBatchIndexer(db, false)
|
bw = newBatchIndexer(db, false)
|
||||||
histories = makeHistories(10)
|
histories = makeStateHistories(10)
|
||||||
)
|
)
|
||||||
// Index histories
|
// Index histories
|
||||||
for i, h := range histories {
|
for i, h := range histories {
|
||||||
|
|
|
||||||
|
|
@ -93,7 +93,7 @@ func newBatchIndexer(db ethdb.KeyValueStore, delete bool) *batchIndexer {
|
||||||
|
|
||||||
// process iterates through the accounts and their associated storage slots in the
|
// process iterates through the accounts and their associated storage slots in the
|
||||||
// state history, tracking the mapping between state and history IDs.
|
// state history, tracking the mapping between state and history IDs.
|
||||||
func (b *batchIndexer) process(h *history, historyID uint64) error {
|
func (b *batchIndexer) process(h *stateHistory, historyID uint64) error {
|
||||||
for _, address := range h.accountList {
|
for _, address := range h.accountList {
|
||||||
addrHash := crypto.Keccak256Hash(address.Bytes())
|
addrHash := crypto.Keccak256Hash(address.Bytes())
|
||||||
b.counter += 1
|
b.counter += 1
|
||||||
|
|
@ -241,7 +241,7 @@ func indexSingle(historyID uint64, db ethdb.KeyValueStore, freezer ethdb.Ancient
|
||||||
}
|
}
|
||||||
return fmt.Errorf("history indexing is out of order, last: %s, requested: %d", last, historyID)
|
return fmt.Errorf("history indexing is out of order, last: %s, requested: %d", last, historyID)
|
||||||
}
|
}
|
||||||
h, err := readHistory(freezer, historyID)
|
h, err := readStateHistory(freezer, historyID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
@ -271,7 +271,7 @@ func unindexSingle(historyID uint64, db ethdb.KeyValueStore, freezer ethdb.Ancie
|
||||||
}
|
}
|
||||||
return fmt.Errorf("history unindexing is out of order, last: %s, requested: %d", last, historyID)
|
return fmt.Errorf("history unindexing is out of order, last: %s, requested: %d", last, historyID)
|
||||||
}
|
}
|
||||||
h, err := readHistory(freezer, historyID)
|
h, err := readStateHistory(freezer, historyID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
@ -524,7 +524,7 @@ func (i *indexIniter) index(done chan struct{}, interrupt *atomic.Int32, lastID
|
||||||
if count > historyReadBatch {
|
if count > historyReadBatch {
|
||||||
count = historyReadBatch
|
count = historyReadBatch
|
||||||
}
|
}
|
||||||
histories, err := readHistories(i.freezer, current, count)
|
histories, err := readStateHistories(i.freezer, current, count)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
// The history read might fall if the history is truncated from
|
// The history read might fall if the history is truncated from
|
||||||
// head due to revert operation.
|
// head due to revert operation.
|
||||||
|
|
|
||||||
|
|
@ -32,7 +32,7 @@ func TestHistoryIndexerShortenDeadlock(t *testing.T) {
|
||||||
freezer, _ := rawdb.NewStateFreezer(t.TempDir(), false, false)
|
freezer, _ := rawdb.NewStateFreezer(t.TempDir(), false, false)
|
||||||
defer freezer.Close()
|
defer freezer.Close()
|
||||||
|
|
||||||
histories := makeHistories(100)
|
histories := makeStateHistories(100)
|
||||||
for i, h := range histories {
|
for i, h := range histories {
|
||||||
accountData, storageData, accountIndex, storageIndex := h.encode()
|
accountData, storageData, accountIndex, storageIndex := h.encode()
|
||||||
rawdb.WriteStateHistory(freezer, uint64(i+1), h.meta.encode(), accountIndex, storageIndex, accountData, storageData)
|
rawdb.WriteStateHistory(freezer, uint64(i+1), h.meta.encode(), accountIndex, storageIndex, accountData, storageData)
|
||||||
|
|
|
||||||
|
|
@ -61,7 +61,7 @@ func sanitizeRange(start, end uint64, freezer ethdb.AncientReader) (uint64, uint
|
||||||
return first, last, nil
|
return first, last, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func inspectHistory(freezer ethdb.AncientReader, start, end uint64, onHistory func(*history, *HistoryStats)) (*HistoryStats, error) {
|
func inspectHistory(freezer ethdb.AncientReader, start, end uint64, onHistory func(*stateHistory, *HistoryStats)) (*HistoryStats, error) {
|
||||||
var (
|
var (
|
||||||
stats = &HistoryStats{}
|
stats = &HistoryStats{}
|
||||||
init = time.Now()
|
init = time.Now()
|
||||||
|
|
@ -74,7 +74,7 @@ func inspectHistory(freezer ethdb.AncientReader, start, end uint64, onHistory fu
|
||||||
for id := start; id <= end; id += 1 {
|
for id := start; id <= end; id += 1 {
|
||||||
// The entire history object is decoded, although it's unnecessary for
|
// The entire history object is decoded, although it's unnecessary for
|
||||||
// account inspection. TODO(rjl493456442) optimization is worthwhile.
|
// account inspection. TODO(rjl493456442) optimization is worthwhile.
|
||||||
h, err := readHistory(freezer, id)
|
h, err := readStateHistory(freezer, id)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
@ -98,7 +98,7 @@ func inspectHistory(freezer ethdb.AncientReader, start, end uint64, onHistory fu
|
||||||
|
|
||||||
// accountHistory inspects the account history within the range.
|
// accountHistory inspects the account history within the range.
|
||||||
func accountHistory(freezer ethdb.AncientReader, address common.Address, start, end uint64) (*HistoryStats, error) {
|
func accountHistory(freezer ethdb.AncientReader, address common.Address, start, end uint64) (*HistoryStats, error) {
|
||||||
return inspectHistory(freezer, start, end, func(h *history, stats *HistoryStats) {
|
return inspectHistory(freezer, start, end, func(h *stateHistory, stats *HistoryStats) {
|
||||||
blob, exists := h.accounts[address]
|
blob, exists := h.accounts[address]
|
||||||
if !exists {
|
if !exists {
|
||||||
return
|
return
|
||||||
|
|
@ -111,7 +111,7 @@ func accountHistory(freezer ethdb.AncientReader, address common.Address, start,
|
||||||
// storageHistory inspects the storage history within the range.
|
// storageHistory inspects the storage history within the range.
|
||||||
func storageHistory(freezer ethdb.AncientReader, address common.Address, slot common.Hash, start uint64, end uint64) (*HistoryStats, error) {
|
func storageHistory(freezer ethdb.AncientReader, address common.Address, slot common.Hash, start uint64, end uint64) (*HistoryStats, error) {
|
||||||
slotHash := crypto.Keccak256Hash(slot.Bytes())
|
slotHash := crypto.Keccak256Hash(slot.Bytes())
|
||||||
return inspectHistory(freezer, start, end, func(h *history, stats *HistoryStats) {
|
return inspectHistory(freezer, start, end, func(h *stateHistory, stats *HistoryStats) {
|
||||||
slots, exists := h.storages[address]
|
slots, exists := h.storages[address]
|
||||||
if !exists {
|
if !exists {
|
||||||
return
|
return
|
||||||
|
|
@ -145,11 +145,11 @@ func historyRange(freezer ethdb.AncientReader) (uint64, uint64, error) {
|
||||||
}
|
}
|
||||||
last := head - 1
|
last := head - 1
|
||||||
|
|
||||||
fh, err := readHistory(freezer, first)
|
fh, err := readStateHistory(freezer, first)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, 0, err
|
return 0, 0, err
|
||||||
}
|
}
|
||||||
lh, err := readHistory(freezer, last)
|
lh, err := readStateHistory(freezer, last)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, 0, err
|
return 0, 0, err
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -133,7 +133,7 @@ func testHistoryReader(t *testing.T, historyLimit uint64) {
|
||||||
var (
|
var (
|
||||||
roots = env.roots
|
roots = env.roots
|
||||||
dRoot = env.db.tree.bottom().rootHash()
|
dRoot = env.db.tree.bottom().rootHash()
|
||||||
hr = newHistoryReader(env.db.diskdb, env.db.freezer)
|
hr = newHistoryReader(env.db.diskdb, env.db.stateFreezer)
|
||||||
)
|
)
|
||||||
for _, root := range roots {
|
for _, root := range roots {
|
||||||
if root == dRoot {
|
if root == dRoot {
|
||||||
|
|
|
||||||
|
|
@ -234,12 +234,13 @@ func (m *meta) decode(blob []byte) error {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// history represents a set of state changes belong to a block along with
|
// stateHistory represents a set of state changes belong to a block along with
|
||||||
// the metadata including the state roots involved in the state transition.
|
// the metadata including the state roots involved in the state transition.
|
||||||
|
//
|
||||||
// State history objects in disk are linked with each other by a unique id
|
// State history objects in disk are linked with each other by a unique id
|
||||||
// (8-bytes integer), the oldest state history object can be pruned on demand
|
// (8-bytes integer), the oldest state history object can be pruned on demand
|
||||||
// in order to control the storage size.
|
// in order to control the storage size.
|
||||||
type history struct {
|
type stateHistory struct {
|
||||||
meta *meta // Meta data of history
|
meta *meta // Meta data of history
|
||||||
accounts map[common.Address][]byte // Account data keyed by its address hash
|
accounts map[common.Address][]byte // Account data keyed by its address hash
|
||||||
accountList []common.Address // Sorted account hash list
|
accountList []common.Address // Sorted account hash list
|
||||||
|
|
@ -247,8 +248,8 @@ type history struct {
|
||||||
storageList map[common.Address][]common.Hash // Sorted slot hash list
|
storageList map[common.Address][]common.Hash // Sorted slot hash list
|
||||||
}
|
}
|
||||||
|
|
||||||
// newHistory constructs the state history object with provided state change set.
|
// newStateHistory constructs the state history object with provided states.
|
||||||
func newHistory(root common.Hash, parent common.Hash, block uint64, accounts map[common.Address][]byte, storages map[common.Address]map[common.Hash][]byte, rawStorageKey bool) *history {
|
func newStateHistory(root common.Hash, parent common.Hash, block uint64, accounts map[common.Address][]byte, storages map[common.Address]map[common.Hash][]byte, rawStorageKey bool) *stateHistory {
|
||||||
var (
|
var (
|
||||||
accountList = slices.SortedFunc(maps.Keys(accounts), common.Address.Cmp)
|
accountList = slices.SortedFunc(maps.Keys(accounts), common.Address.Cmp)
|
||||||
storageList = make(map[common.Address][]common.Hash)
|
storageList = make(map[common.Address][]common.Hash)
|
||||||
|
|
@ -260,7 +261,7 @@ func newHistory(root common.Hash, parent common.Hash, block uint64, accounts map
|
||||||
if !rawStorageKey {
|
if !rawStorageKey {
|
||||||
version = stateHistoryV0
|
version = stateHistoryV0
|
||||||
}
|
}
|
||||||
return &history{
|
return &stateHistory{
|
||||||
meta: &meta{
|
meta: &meta{
|
||||||
version: version,
|
version: version,
|
||||||
parent: parent,
|
parent: parent,
|
||||||
|
|
@ -276,7 +277,7 @@ func newHistory(root common.Hash, parent common.Hash, block uint64, accounts map
|
||||||
|
|
||||||
// stateSet returns the state set, keyed by the hash of the account address
|
// stateSet returns the state set, keyed by the hash of the account address
|
||||||
// and the hash of the storage slot key.
|
// and the hash of the storage slot key.
|
||||||
func (h *history) stateSet() (map[common.Hash][]byte, map[common.Hash]map[common.Hash][]byte) {
|
func (h *stateHistory) stateSet() (map[common.Hash][]byte, map[common.Hash]map[common.Hash][]byte) {
|
||||||
var (
|
var (
|
||||||
accounts = make(map[common.Hash][]byte)
|
accounts = make(map[common.Hash][]byte)
|
||||||
storages = make(map[common.Hash]map[common.Hash][]byte)
|
storages = make(map[common.Hash]map[common.Hash][]byte)
|
||||||
|
|
@ -304,7 +305,7 @@ func (h *history) stateSet() (map[common.Hash][]byte, map[common.Hash]map[common
|
||||||
|
|
||||||
// encode serializes the state history and returns four byte streams represent
|
// encode serializes the state history and returns four byte streams represent
|
||||||
// concatenated account/storage data, account/storage indexes respectively.
|
// concatenated account/storage data, account/storage indexes respectively.
|
||||||
func (h *history) encode() ([]byte, []byte, []byte, []byte) {
|
func (h *stateHistory) encode() ([]byte, []byte, []byte, []byte) {
|
||||||
var (
|
var (
|
||||||
slotNumber uint32 // the number of processed slots
|
slotNumber uint32 // the number of processed slots
|
||||||
accountData []byte // the buffer for concatenated account data
|
accountData []byte // the buffer for concatenated account data
|
||||||
|
|
@ -459,7 +460,7 @@ func (r *decoder) readStorage(accIndex accountIndex) ([]common.Hash, map[common.
|
||||||
}
|
}
|
||||||
|
|
||||||
// decode deserializes the account and storage data from the provided byte stream.
|
// decode deserializes the account and storage data from the provided byte stream.
|
||||||
func (h *history) decode(accountData, storageData, accountIndexes, storageIndexes []byte) error {
|
func (h *stateHistory) decode(accountData, storageData, accountIndexes, storageIndexes []byte) error {
|
||||||
var (
|
var (
|
||||||
count = len(accountIndexes) / accountIndexSize
|
count = len(accountIndexes) / accountIndexSize
|
||||||
accounts = make(map[common.Address][]byte, count)
|
accounts = make(map[common.Address][]byte, count)
|
||||||
|
|
@ -503,8 +504,8 @@ func (h *history) decode(accountData, storageData, accountIndexes, storageIndexe
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// readHistory reads and decodes the state history object by the given id.
|
// readStateHistory reads a single state history records with the specified id.
|
||||||
func readHistory(reader ethdb.AncientReader, id uint64) (*history, error) {
|
func readStateHistory(reader ethdb.AncientReader, id uint64) (*stateHistory, error) {
|
||||||
mData, accountIndexes, storageIndexes, accountData, storageData, err := rawdb.ReadStateHistory(reader, id)
|
mData, accountIndexes, storageIndexes, accountData, storageData, err := rawdb.ReadStateHistory(reader, id)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
|
@ -513,17 +514,16 @@ func readHistory(reader ethdb.AncientReader, id uint64) (*history, error) {
|
||||||
if err := m.decode(mData); err != nil {
|
if err := m.decode(mData); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
h := history{meta: &m}
|
h := stateHistory{meta: &m}
|
||||||
if err := h.decode(accountData, storageData, accountIndexes, storageIndexes); err != nil {
|
if err := h.decode(accountData, storageData, accountIndexes, storageIndexes); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return &h, nil
|
return &h, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// readHistories reads and decodes a list of state histories with the specific
|
// readStateHistories reads a list of state history records within the specified range.
|
||||||
// history range.
|
func readStateHistories(freezer ethdb.AncientReader, start uint64, count uint64) ([]*stateHistory, error) {
|
||||||
func readHistories(freezer ethdb.AncientReader, start uint64, count uint64) ([]*history, error) {
|
var histories []*stateHistory
|
||||||
var histories []*history
|
|
||||||
metaList, aIndexList, sIndexList, aDataList, sDataList, err := rawdb.ReadStateHistoryList(freezer, start, count)
|
metaList, aIndexList, sIndexList, aDataList, sDataList, err := rawdb.ReadStateHistoryList(freezer, start, count)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
|
@ -533,7 +533,7 @@ func readHistories(freezer ethdb.AncientReader, start uint64, count uint64) ([]*
|
||||||
if err := m.decode(metaList[i]); err != nil {
|
if err := m.decode(metaList[i]); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
h := history{meta: &m}
|
h := stateHistory{meta: &m}
|
||||||
if err := h.decode(aDataList[i], sDataList[i], aIndexList[i], sIndexList[i]); err != nil {
|
if err := h.decode(aDataList[i], sDataList[i], aIndexList[i], sIndexList[i]); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
@ -542,15 +542,15 @@ func readHistories(freezer ethdb.AncientReader, start uint64, count uint64) ([]*
|
||||||
return histories, nil
|
return histories, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// writeHistory persists the state history with the provided state set.
|
// writeStateHistory persists the state history associated with the given diff layer.
|
||||||
func writeHistory(writer ethdb.AncientWriter, dl *diffLayer) error {
|
func writeStateHistory(writer ethdb.AncientWriter, dl *diffLayer) error {
|
||||||
// Short circuit if state set is not available.
|
// Short circuit if state set is not available.
|
||||||
if dl.states == nil {
|
if dl.states == nil {
|
||||||
return errors.New("state change set is not available")
|
return errors.New("state change set is not available")
|
||||||
}
|
}
|
||||||
var (
|
var (
|
||||||
start = time.Now()
|
start = time.Now()
|
||||||
history = newHistory(dl.rootHash(), dl.parentLayer().rootHash(), dl.block, dl.states.accountOrigin, dl.states.storageOrigin, dl.states.rawStorageKey)
|
history = newStateHistory(dl.rootHash(), dl.parentLayer().rootHash(), dl.block, dl.states.accountOrigin, dl.states.storageOrigin, dl.states.rawStorageKey)
|
||||||
)
|
)
|
||||||
accountData, storageData, accountIndex, storageIndex := history.encode()
|
accountData, storageData, accountIndex, storageIndex := history.encode()
|
||||||
dataSize := common.StorageSize(len(accountData) + len(storageData))
|
dataSize := common.StorageSize(len(accountData) + len(storageData))
|
||||||
|
|
@ -568,9 +568,9 @@ func writeHistory(writer ethdb.AncientWriter, dl *diffLayer) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// checkHistories retrieves a batch of meta objects with the specified range
|
// checkStateHistories retrieves a batch of meta objects with the specified range
|
||||||
// and performs the callback on each item.
|
// and performs the callback on each item.
|
||||||
func checkHistories(reader ethdb.AncientReader, start, count uint64, check func(*meta) error) error {
|
func checkStateHistories(reader ethdb.AncientReader, start, count uint64, check func(*meta) error) error {
|
||||||
for count > 0 {
|
for count > 0 {
|
||||||
number := count
|
number := count
|
||||||
if number > 10000 {
|
if number > 10000 {
|
||||||
|
|
@ -49,36 +49,36 @@ func randomStateSet(n int) (map[common.Address][]byte, map[common.Address]map[co
|
||||||
return accounts, storages
|
return accounts, storages
|
||||||
}
|
}
|
||||||
|
|
||||||
func makeHistory(rawStorageKey bool) *history {
|
func makeStateHistory(rawStorageKey bool) *stateHistory {
|
||||||
accounts, storages := randomStateSet(3)
|
accounts, storages := randomStateSet(3)
|
||||||
return newHistory(testrand.Hash(), types.EmptyRootHash, 0, accounts, storages, rawStorageKey)
|
return newStateHistory(testrand.Hash(), types.EmptyRootHash, 0, accounts, storages, rawStorageKey)
|
||||||
}
|
}
|
||||||
|
|
||||||
func makeHistories(n int) []*history {
|
func makeStateHistories(n int) []*stateHistory {
|
||||||
var (
|
var (
|
||||||
parent = types.EmptyRootHash
|
parent = types.EmptyRootHash
|
||||||
result []*history
|
result []*stateHistory
|
||||||
)
|
)
|
||||||
for i := 0; i < n; i++ {
|
for i := 0; i < n; i++ {
|
||||||
root := testrand.Hash()
|
root := testrand.Hash()
|
||||||
accounts, storages := randomStateSet(3)
|
accounts, storages := randomStateSet(3)
|
||||||
h := newHistory(root, parent, uint64(i), accounts, storages, false)
|
h := newStateHistory(root, parent, uint64(i), accounts, storages, false)
|
||||||
parent = root
|
parent = root
|
||||||
result = append(result, h)
|
result = append(result, h)
|
||||||
}
|
}
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestEncodeDecodeHistory(t *testing.T) {
|
func TestEncodeDecodeStateHistory(t *testing.T) {
|
||||||
testEncodeDecodeHistory(t, false)
|
testEncodeDecodeStateHistory(t, false)
|
||||||
testEncodeDecodeHistory(t, true)
|
testEncodeDecodeStateHistory(t, true)
|
||||||
}
|
}
|
||||||
|
|
||||||
func testEncodeDecodeHistory(t *testing.T, rawStorageKey bool) {
|
func testEncodeDecodeStateHistory(t *testing.T, rawStorageKey bool) {
|
||||||
var (
|
var (
|
||||||
m meta
|
m meta
|
||||||
dec history
|
dec stateHistory
|
||||||
obj = makeHistory(rawStorageKey)
|
obj = makeStateHistory(rawStorageKey)
|
||||||
)
|
)
|
||||||
// check if meta data can be correctly encode/decode
|
// check if meta data can be correctly encode/decode
|
||||||
blob := obj.meta.encode()
|
blob := obj.meta.encode()
|
||||||
|
|
@ -108,7 +108,7 @@ func testEncodeDecodeHistory(t *testing.T, rawStorageKey bool) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func checkHistory(t *testing.T, db ethdb.KeyValueReader, freezer ethdb.AncientReader, id uint64, root common.Hash, exist bool) {
|
func checkStateHistory(t *testing.T, db ethdb.KeyValueReader, freezer ethdb.AncientReader, id uint64, root common.Hash, exist bool) {
|
||||||
blob := rawdb.ReadStateHistoryMeta(freezer, id)
|
blob := rawdb.ReadStateHistoryMeta(freezer, id)
|
||||||
if exist && len(blob) == 0 {
|
if exist && len(blob) == 0 {
|
||||||
t.Fatalf("Failed to load trie history, %d", id)
|
t.Fatalf("Failed to load trie history, %d", id)
|
||||||
|
|
@ -126,14 +126,14 @@ func checkHistory(t *testing.T, db ethdb.KeyValueReader, freezer ethdb.AncientRe
|
||||||
|
|
||||||
func checkHistoriesInRange(t *testing.T, db ethdb.KeyValueReader, freezer ethdb.AncientReader, from, to uint64, roots []common.Hash, exist bool) {
|
func checkHistoriesInRange(t *testing.T, db ethdb.KeyValueReader, freezer ethdb.AncientReader, from, to uint64, roots []common.Hash, exist bool) {
|
||||||
for i, j := from, 0; i <= to; i, j = i+1, j+1 {
|
for i, j := from, 0; i <= to; i, j = i+1, j+1 {
|
||||||
checkHistory(t, db, freezer, i, roots[j], exist)
|
checkStateHistory(t, db, freezer, i, roots[j], exist)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestTruncateHeadHistory(t *testing.T) {
|
func TestTruncateHeadStateHistory(t *testing.T) {
|
||||||
var (
|
var (
|
||||||
roots []common.Hash
|
roots []common.Hash
|
||||||
hs = makeHistories(10)
|
hs = makeStateHistories(10)
|
||||||
db = rawdb.NewMemoryDatabase()
|
db = rawdb.NewMemoryDatabase()
|
||||||
freezer, _ = rawdb.NewStateFreezer(t.TempDir(), false, false)
|
freezer, _ = rawdb.NewStateFreezer(t.TempDir(), false, false)
|
||||||
)
|
)
|
||||||
|
|
@ -158,10 +158,10 @@ func TestTruncateHeadHistory(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestTruncateTailHistory(t *testing.T) {
|
func TestTruncateTailStateHistory(t *testing.T) {
|
||||||
var (
|
var (
|
||||||
roots []common.Hash
|
roots []common.Hash
|
||||||
hs = makeHistories(10)
|
hs = makeStateHistories(10)
|
||||||
db = rawdb.NewMemoryDatabase()
|
db = rawdb.NewMemoryDatabase()
|
||||||
freezer, _ = rawdb.NewStateFreezer(t.TempDir(), false, false)
|
freezer, _ = rawdb.NewStateFreezer(t.TempDir(), false, false)
|
||||||
)
|
)
|
||||||
|
|
@ -183,7 +183,7 @@ func TestTruncateTailHistory(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestTruncateTailHistories(t *testing.T) {
|
func TestTruncateTailStateHistories(t *testing.T) {
|
||||||
var cases = []struct {
|
var cases = []struct {
|
||||||
limit uint64
|
limit uint64
|
||||||
expPruned int
|
expPruned int
|
||||||
|
|
@ -204,7 +204,7 @@ func TestTruncateTailHistories(t *testing.T) {
|
||||||
for i, c := range cases {
|
for i, c := range cases {
|
||||||
var (
|
var (
|
||||||
roots []common.Hash
|
roots []common.Hash
|
||||||
hs = makeHistories(10)
|
hs = makeStateHistories(10)
|
||||||
db = rawdb.NewMemoryDatabase()
|
db = rawdb.NewMemoryDatabase()
|
||||||
freezer, _ = rawdb.NewStateFreezer(t.TempDir()+fmt.Sprintf("%d", i), false, false)
|
freezer, _ = rawdb.NewStateFreezer(t.TempDir()+fmt.Sprintf("%d", i), false, false)
|
||||||
)
|
)
|
||||||
|
|
@ -232,7 +232,7 @@ func TestTruncateTailHistories(t *testing.T) {
|
||||||
|
|
||||||
func TestTruncateOutOfRange(t *testing.T) {
|
func TestTruncateOutOfRange(t *testing.T) {
|
||||||
var (
|
var (
|
||||||
hs = makeHistories(10)
|
hs = makeStateHistories(10)
|
||||||
db = rawdb.NewMemoryDatabase()
|
db = rawdb.NewMemoryDatabase()
|
||||||
freezer, _ = rawdb.NewStateFreezer(t.TempDir(), false, false)
|
freezer, _ = rawdb.NewStateFreezer(t.TempDir(), false, false)
|
||||||
)
|
)
|
||||||
|
|
@ -207,10 +207,10 @@ type HistoricalStateReader struct {
|
||||||
// HistoricReader constructs a reader for accessing the requested historic state.
|
// HistoricReader constructs a reader for accessing the requested historic state.
|
||||||
func (db *Database) HistoricReader(root common.Hash) (*HistoricalStateReader, error) {
|
func (db *Database) HistoricReader(root common.Hash) (*HistoricalStateReader, error) {
|
||||||
// Bail out if the state history hasn't been fully indexed
|
// Bail out if the state history hasn't been fully indexed
|
||||||
if db.indexer == nil || db.freezer == nil {
|
if db.stateIndexer == nil || db.stateFreezer == nil {
|
||||||
return nil, fmt.Errorf("historical state %x is not available", root)
|
return nil, fmt.Errorf("historical state %x is not available", root)
|
||||||
}
|
}
|
||||||
if !db.indexer.inited() {
|
if !db.stateIndexer.inited() {
|
||||||
return nil, errors.New("state histories haven't been fully indexed yet")
|
return nil, errors.New("state histories haven't been fully indexed yet")
|
||||||
}
|
}
|
||||||
// States at the current disk layer or above are directly accessible via
|
// States at the current disk layer or above are directly accessible via
|
||||||
|
|
@ -230,7 +230,7 @@ func (db *Database) HistoricReader(root common.Hash) (*HistoricalStateReader, er
|
||||||
return &HistoricalStateReader{
|
return &HistoricalStateReader{
|
||||||
id: *id,
|
id: *id,
|
||||||
db: db,
|
db: db,
|
||||||
reader: newHistoryReader(db.diskdb, db.freezer),
|
reader: newHistoryReader(db.diskdb, db.stateFreezer),
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue