Skip to content
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
5 changes: 5 additions & 0 deletions graft/coreth/core/txpool/legacypool/legacypool.go
Original file line number Diff line number Diff line change
Expand Up @@ -446,6 +446,11 @@ func (pool *LegacyPool) Close() error {
if pool.journal != nil {
pool.journal.close()
}

// remove all references to state to allow GC to reclaim memory
pool.pendingNonces = nil
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These keep around a StateDB, which holds onto the *firewood.accountTrie, so the database closure will hang unless we remove these references. Another (worse) option is that on state.Trie.Copy(), we don't copy the Reader, and instead use GetFromRoot then. This seems too messy, so I have this small line change instead.

Copy link
Contributor

@RodrigoVillar RodrigoVillar Dec 17, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wonder if it's possible to remove *state.StateDB from the noncer - doing so could allow us to remove the pool.pendingNonces = nil statement (which seems odd to me IMO). After all, the noncer is only used by the legacy pool which itself already has a reference to *state.StateDB.

This is out of scope for the PR though, so approving nonetheless.

pool.currentState = nil

log.Info("Transaction pool stopped")
return nil
}
Expand Down
10 changes: 5 additions & 5 deletions graft/evm/firewood/triedb.go
Original file line number Diff line number Diff line change
Expand Up @@ -486,16 +486,16 @@ func (t *TrieDB) removeProposalFromMap(pCtx *ProposalContext) {
// Reader retrieves a node reader belonging to the given state root.
// An error will be returned if the requested state is not available.
func (t *TrieDB) Reader(root common.Hash) (database.Reader, error) {
if _, err := t.fwDisk.GetFromRoot(ffi.Hash(root), []byte{}); err != nil {
revision, err := t.fwDisk.Revision(ffi.Hash(root))
if err != nil {
return nil, fmt.Errorf("firewood: unable to retrieve from root %s: %w", root.Hex(), err)
}
return &reader{db: t, root: ffi.Hash(root)}, nil
return &reader{revision: revision}, nil
}

// reader is a state reader of Database which implements the Reader interface.
type reader struct {
db *TrieDB
root ffi.Hash // The root of the state this reader is reading.
revision *ffi.Revision
}

// Node retrieves the trie node with the given node hash. No error will be
Expand All @@ -504,7 +504,7 @@ func (reader *reader) Node(_ common.Hash, path []byte, _ common.Hash) ([]byte, e
// This function relies on Firewood's internal locking to ensure concurrent reads are safe.
// This is safe even if a proposal is being committed concurrently.
start := time.Now()
result, err := reader.db.fwDisk.GetFromRoot(reader.root, path)
result, err := reader.revision.Get(path)
if metrics.EnabledExpensive {
ffiReadCount.Inc(1)
ffiReadTimer.Inc(time.Since(start).Milliseconds())
Expand Down
5 changes: 5 additions & 0 deletions graft/subnet-evm/core/txpool/legacypool/legacypool.go
Original file line number Diff line number Diff line change
Expand Up @@ -449,6 +449,11 @@ func (pool *LegacyPool) Close() error {
if pool.journal != nil {
pool.journal.close()
}

// remove all references to state to allow GC to reclaim memory
pool.pendingNonces = nil
pool.currentState = nil

log.Info("Transaction pool stopped")
return nil
}
Expand Down