Skip to content

trie: no need to store preimage if not enabled #32012

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Jun 13, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions trie/database_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,10 @@ func (db *testDb) InsertPreimage(preimages map[common.Hash][]byte) {
rawdb.WritePreimages(db.disk, preimages)
}

func (db *testDb) PreimageEnabled() bool {
return true
}

func (db *testDb) Scheme() string { return db.scheme }

func (db *testDb) Update(root common.Hash, parent common.Hash, nodes *trienode.MergedNodeSet) error {
Expand Down
36 changes: 25 additions & 11 deletions trie/secure_trie.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,9 @@ type preimageStore interface {

// InsertPreimage commits a set of preimages along with their hashes.
InsertPreimage(preimages map[common.Hash][]byte)

// PreimageEnabled returns true if the preimage store is enabled.
PreimageEnabled() bool
}

// SecureTrie is the old name of StateTrie.
Expand Down Expand Up @@ -84,8 +87,7 @@ func NewStateTrie(id *ID, db database.NodeDatabase) (*StateTrie, error) {
tr := &StateTrie{trie: *trie, db: db}

// link the preimage store if it's supported
preimages, ok := db.(preimageStore)
if ok {
if preimages, ok := db.(preimageStore); ok && preimages.PreimageEnabled() {
tr.preimages = preimages
}
return tr, nil
Expand Down Expand Up @@ -159,7 +161,9 @@ func (t *StateTrie) GetNode(path []byte) ([]byte, int, error) {
func (t *StateTrie) MustUpdate(key, value []byte) {
hk := crypto.Keccak256(key)
t.trie.MustUpdate(hk, value)
t.getSecKeyCache()[common.Hash(hk)] = common.CopyBytes(key)
if t.preimages != nil {
t.getSecKeyCache()[common.Hash(hk)] = common.CopyBytes(key)
}
}

// UpdateStorage associates key with value in the trie. Subsequent calls to
Expand All @@ -177,7 +181,9 @@ func (t *StateTrie) UpdateStorage(_ common.Address, key, value []byte) error {
if err != nil {
return err
}
t.getSecKeyCache()[common.Hash(hk)] = common.CopyBytes(key)
if t.preimages != nil {
t.getSecKeyCache()[common.Hash(hk)] = common.CopyBytes(key)
}
return nil
}

Expand All @@ -191,7 +197,9 @@ func (t *StateTrie) UpdateAccount(address common.Address, acc *types.StateAccoun
if err := t.trie.Update(hk, data); err != nil {
return err
}
t.getSecKeyCache()[common.Hash(hk)] = address.Bytes()
if t.preimages != nil {
t.getSecKeyCache()[common.Hash(hk)] = address.Bytes()
}
return nil
}

Expand All @@ -203,7 +211,9 @@ func (t *StateTrie) UpdateContractCode(_ common.Address, _ common.Hash, _ []byte
// will omit any encountered error but just print out an error message.
func (t *StateTrie) MustDelete(key []byte) {
hk := crypto.Keccak256(key)
delete(t.getSecKeyCache(), common.Hash(hk))
if t.preimages != nil {
delete(t.getSecKeyCache(), common.Hash(hk))
}
t.trie.MustDelete(hk)
}

Expand All @@ -212,26 +222,30 @@ func (t *StateTrie) MustDelete(key []byte) {
// If a node is not found in the database, a MissingNodeError is returned.
func (t *StateTrie) DeleteStorage(_ common.Address, key []byte) error {
hk := crypto.Keccak256(key)
delete(t.getSecKeyCache(), common.Hash(hk))
if t.preimages != nil {
delete(t.getSecKeyCache(), common.Hash(hk))
}
return t.trie.Delete(hk)
}

// DeleteAccount abstracts an account deletion from the trie.
func (t *StateTrie) DeleteAccount(address common.Address) error {
hk := crypto.Keccak256(address.Bytes())
delete(t.getSecKeyCache(), common.Hash(hk))
if t.preimages != nil {
delete(t.getSecKeyCache(), common.Hash(hk))
}
return t.trie.Delete(hk)
}

// GetKey returns the sha3 preimage of a hashed key that was
// previously used to store a value.
func (t *StateTrie) GetKey(shaKey []byte) []byte {
if key, ok := t.getSecKeyCache()[common.BytesToHash(shaKey)]; ok {
return key
}
if t.preimages == nil {
return nil
}
if key, ok := t.getSecKeyCache()[common.BytesToHash(shaKey)]; ok {
return key
}
return t.preimages.Preimage(common.BytesToHash(shaKey))
}

Expand Down
5 changes: 5 additions & 0 deletions triedb/database.go
Original file line number Diff line number Diff line change
Expand Up @@ -213,6 +213,11 @@ func (db *Database) InsertPreimage(preimages map[common.Hash][]byte) {
db.preimages.insertPreimage(preimages)
}

// PreimageEnabled returns the indicator if the pre-image store is enabled.
func (db *Database) PreimageEnabled() bool {
return db.preimages != nil
}

// Cap iteratively flushes old but still referenced trie nodes until the total
// memory usage goes below the given threshold. The held pre-images accumulated
// up to this point will be flushed in case the size exceeds the threshold.
Expand Down