From 567b0eb5ac89885a6632f9c2e4e4fd0f41184548 Mon Sep 17 00:00:00 2001 From: CPerezz Date: Mon, 16 Mar 2026 23:55:47 +0100 Subject: [PATCH] core/state: skip redundant trie Commit for Verkle in stateObject.commit In Verkle mode, all state objects share a single unified trie (OpenStorageTrie returns self). During stateDB.commit(), the main account trie is committed via s.trie.Commit(true), which calls CollectNodes to traverse and serialize the entire tree. However, each dirty account's obj.commit() also calls s.trie.Commit(false) on the same trie object, redundantly traversing the full tree once per dirty account (N+1 traversals instead of 1). This also fixes a latent data race where N+1 goroutines concurrently call CollectNodes on the same BinaryTrie/InternalNode objects. --- core/state/state_object.go | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/core/state/state_object.go b/core/state/state_object.go index dd30bb64a5..b7d56ce1ba 100644 --- a/core/state/state_object.go +++ b/core/state/state_object.go @@ -474,6 +474,14 @@ func (s *stateObject) commit() (*accountUpdate, *trienode.NodeSet, error) { s.origin = s.data.Copy() return op, nil, nil } + // In Verkle/binary trie mode, all state objects share one unified trie. + // The main account trie commit in stateDB.commit() already calls + // CollectNodes on this trie, so calling Commit here again would + // redundantly traverse and serialize the entire tree per dirty account. + if s.db.db.TrieDB().IsVerkle() { + s.origin = s.data.Copy() + return op, nil, nil + } root, nodes := s.trie.Commit(false) s.data.Root = root s.origin = s.data.Copy()