Skip to content

Commit d926bf2

Browse files
karalabefjl
authored andcommitted
trie: cache collapsed tries node, not rlp blobs (ethereum#16876)
The current trie memory database/cache that we do pruning on stores trie nodes as binary rlp encoded blobs, and also stores the node relationships/references for GC purposes. However, most of the trie nodes (everything apart from a value node) is in essence just a collection of references. This PR switches out the RLP encoded trie blobs with the collapsed-but-not-serialized trie nodes. This permits most of the references to be recovered from within the node data structure, avoiding the need to track them a second time (expensive memory wise).
1 parent 8db8d07 commit d926bf2

File tree

8 files changed

+268
-75
lines changed

8 files changed

+268
-75
lines changed

core/blockchain.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -672,7 +672,7 @@ func (bc *BlockChain) Stop() {
672672
}
673673
}
674674
for !bc.triegc.Empty() {
675-
triedb.Dereference(bc.triegc.PopItem().(common.Hash), common.Hash{})
675+
triedb.Dereference(bc.triegc.PopItem().(common.Hash))
676676
}
677677
if size, _ := triedb.Size(); size != 0 {
678678
log.Error("Dangling trie nodes after full cleanup")
@@ -947,7 +947,7 @@ func (bc *BlockChain) WriteBlockWithState(block *types.Block, receipts []*types.
947947
bc.triegc.Push(root, number)
948948
break
949949
}
950-
triedb.Dereference(root.(common.Hash), common.Hash{})
950+
triedb.Dereference(root.(common.Hash))
951951
}
952952
}
953953
}

core/blockchain_test.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -1313,8 +1313,8 @@ func TestTrieForkGC(t *testing.T) {
13131313
}
13141314
// Dereference all the recent tries and ensure no past trie is left in
13151315
for i := 0; i < triesInMemory; i++ {
1316-
chain.stateCache.TrieDB().Dereference(blocks[len(blocks)-1-i].Root(), common.Hash{})
1317-
chain.stateCache.TrieDB().Dereference(forks[len(blocks)-1-i].Root(), common.Hash{})
1316+
chain.stateCache.TrieDB().Dereference(blocks[len(blocks)-1-i].Root())
1317+
chain.stateCache.TrieDB().Dereference(forks[len(blocks)-1-i].Root())
13181318
}
13191319
if len(chain.stateCache.TrieDB().Nodes()) > 0 {
13201320
t.Fatalf("stale tries still alive after garbase collection")

core/state/statedb.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -596,7 +596,7 @@ func (s *StateDB) Commit(deleteEmptyObjects bool) (root common.Hash, err error)
596596
case isDirty:
597597
// Write any contract code associated with the state object
598598
if stateObject.code != nil && stateObject.dirtyCode {
599-
s.db.TrieDB().Insert(common.BytesToHash(stateObject.CodeHash()), stateObject.code)
599+
s.db.TrieDB().InsertBlob(common.BytesToHash(stateObject.CodeHash()), stateObject.code)
600600
stateObject.dirtyCode = false
601601
}
602602
// Write any storage changes in the state object to its storage trie.

eth/api_tracer.go

+3-3
Original file line numberDiff line numberDiff line change
@@ -297,7 +297,7 @@ func (api *PrivateDebugAPI) traceChain(ctx context.Context, start, end *types.Bl
297297
database.TrieDB().Reference(root, common.Hash{})
298298
}
299299
// Dereference all past tries we ourselves are done working with
300-
database.TrieDB().Dereference(proot, common.Hash{})
300+
database.TrieDB().Dereference(proot)
301301
proot = root
302302

303303
// TODO(karalabe): Do we need the preimages? Won't they accumulate too much?
@@ -320,7 +320,7 @@ func (api *PrivateDebugAPI) traceChain(ctx context.Context, start, end *types.Bl
320320
done[uint64(result.Block)] = result
321321

322322
// Dereference any paret tries held in memory by this task
323-
database.TrieDB().Dereference(res.rootref, common.Hash{})
323+
database.TrieDB().Dereference(res.rootref)
324324

325325
// Stream completed traces to the user, aborting on the first error
326326
for result, ok := done[next]; ok; result, ok = done[next] {
@@ -526,7 +526,7 @@ func (api *PrivateDebugAPI) computeStateDB(block *types.Block, reexec uint64) (*
526526
return nil, err
527527
}
528528
database.TrieDB().Reference(root, common.Hash{})
529-
database.TrieDB().Dereference(proot, common.Hash{})
529+
database.TrieDB().Dereference(proot)
530530
proot = root
531531
}
532532
nodes, imgs := database.TrieDB().Size()

0 commit comments

Comments
 (0)