@@ -757,7 +757,7 @@ func (s *StateDB) GetRefund() uint64 {
757757 return s .refund
758758}
759759
760- // Finalise finalises the state by removing the self destructed objects and clears
760+ // Finalise finalises the state by removing the destructed objects and clears
761761// the journal as well as the refunds. Finalise, however, will not push any updates
762762// into the tries just yet. Only IntermediateRoot or Commit will do that.
763763func (s * StateDB ) Finalise (deleteEmptyObjects bool ) {
@@ -839,7 +839,11 @@ func (s *StateDB) Commit(deleteEmptyObjects bool) (common.Hash, error) {
839839 s .stateObjectsDirty [addr ] = struct {}{}
840840 }
841841 // Commit objects to the trie, measuring the elapsed time
842- var storageCommitted int
842+ var (
843+ accountTrieNodes int
844+ storageTrieNodes int
845+ nodes = trie .NewMergedNodeSet ()
846+ )
843847 codeWriter := s .db .TrieDB ().DiskDB ().NewBatch ()
844848 for addr := range s .stateObjectsDirty {
845849 if obj := s .stateObjects [addr ]; ! obj .deleted {
@@ -848,12 +852,18 @@ func (s *StateDB) Commit(deleteEmptyObjects bool) (common.Hash, error) {
848852 rawdb .WriteCode (codeWriter , common .BytesToHash (obj .CodeHash ()), obj .code )
849853 obj .dirtyCode = false
850854 }
851- // Write any storage changes in the state object to its storage trie.
852- committed , err := obj .commitTrie (s .db )
855+ // Write any storage changes in the state object to its storage trie
856+ set , err := obj .commitTrie (s .db )
853857 if err != nil {
854858 return common.Hash {}, err
855859 }
856- storageCommitted += committed
860+ // Merge the dirty nodes of storage trie into global set
861+ if set != nil {
862+ if err := nodes .Merge (set ); err != nil {
863+ return common.Hash {}, err
864+ }
865+ storageTrieNodes += set .Len ()
866+ }
857867 }
858868 // If the contract is destructed, the storage is still left in the
859869 // database as dangling data. Theoretically it's should be wiped from
@@ -873,34 +883,35 @@ func (s *StateDB) Commit(deleteEmptyObjects bool) (common.Hash, error) {
873883 // Write the account trie changes, measuring the amount of wasted time
874884 start := time .Now ()
875885
876- root , accountCommitted , err := s .trie .Commit (func (_ [][]byte , _ []byte , leaf []byte , parent common.Hash , _ []byte ) error {
877- var account types.StateAccount
878- if err := rlp .DecodeBytes (leaf , & account ); err != nil {
879- return nil
880- }
881- if account .Root != types .EmptyRootHash {
882- s .db .TrieDB ().Reference (account .Root , parent )
883- }
884- return nil
885- })
886+ root , set , err := s .trie .Commit (true )
886887 if err != nil {
887888 return common.Hash {}, err
888889 }
890+ // Merge the dirty nodes of account trie into global set
891+ if set != nil {
892+ if err := nodes .Merge (set ); err != nil {
893+ return common.Hash {}, err
894+ }
895+ accountTrieNodes = set .Len ()
896+ }
889897 // Report the commit metrics
890898 s .AccountCommits += time .Since (start )
891899
892900 accountUpdatedMeter .Mark (int64 (s .AccountUpdated ))
893901 storageUpdatedMeter .Mark (int64 (s .StorageUpdated ))
894902 accountDeletedMeter .Mark (int64 (s .AccountDeleted ))
895903 storageDeletedMeter .Mark (int64 (s .StorageDeleted ))
896- accountCommittedMeter .Mark (int64 (accountCommitted ))
897- storageCommittedMeter .Mark (int64 (storageCommitted ))
904+ accountTrieCommittedMeter .Mark (int64 (accountTrieNodes ))
905+ storageTriesCommittedMeter .Mark (int64 (storageTrieNodes ))
898906 s .AccountUpdated , s .AccountDeleted = 0 , 0
899907 s .StorageUpdated , s .StorageDeleted = 0 , 0
900908
901909 if len (s .stateObjectsDestruct ) > 0 {
902910 s .stateObjectsDestruct = make (map [common.Address ]struct {})
903911 }
912+ if err := s .db .TrieDB ().Update (nodes ); err != nil {
913+ return common.Hash {}, err
914+ }
904915 return root , err
905916}
906917
0 commit comments