@@ -77,9 +77,9 @@ type stateObject struct {
7777 trie Trie // storage trie, which becomes non-nil on first access
7878 code Code // contract bytecode, which gets set when code is loaded
7979
80- cachedStorage Storage // Storage entry cache to avoid duplicate reads
80+ originStorage Storage // Storage cache of original entries to dedup rewrites
8181 dirtyStorage Storage // Storage entries that need to be flushed to disk
82- originalValue Storage // Map of original storage values, at the beginning of current call context
82+
8383 // Cache flags.
8484 // When an object is marked suicided it will be delete from the trie
8585 // during the "update" phase of the state transition.
@@ -115,9 +115,8 @@ func newObject(db *StateDB, address common.Address, data Account) *stateObject {
115115 address : address ,
116116 addrHash : crypto .Keccak256Hash (address [:]),
117117 data : data ,
118- cachedStorage : make (Storage ),
118+ originStorage : make (Storage ),
119119 dirtyStorage : make (Storage ),
120- originalValue : make (Storage ),
121120 }
122121}
123122
@@ -160,13 +159,25 @@ func (c *stateObject) getTrie(db Database) Trie {
160159 return c .trie
161160}
162161
163- // GetState returns a value in account storage.
162+ // GetState retrieves a value from the account storage trie .
164163func (self * stateObject ) GetState (db Database , key common.Hash ) common.Hash {
165- value , exists := self .cachedStorage [key ]
166- if exists {
164+ // If we have a dirty value for this state entry, return it
165+ value , dirty := self .dirtyStorage [key ]
166+ if dirty {
167+ return value
168+ }
169+ // Otherwise return the entry's original value
170+ return self .GetCommittedState (db , key )
171+ }
172+
173+ // GetCommittedState retrieves a value from the committed account storage trie.
174+ func (self * stateObject ) GetCommittedState (db Database , key common.Hash ) common.Hash {
175+ // If we have the original value cached, return that
176+ value , cached := self .originStorage [key ]
177+ if cached {
167178 return value
168179 }
169- // Load from DB in case it is missing.
180+ // Otherwise load the value from the database
170181 enc , err := self .getTrie (db ).TryGet (key [:])
171182 if err != nil {
172183 self .setError (err )
@@ -179,37 +190,27 @@ func (self *stateObject) GetState(db Database, key common.Hash) common.Hash {
179190 }
180191 value .SetBytes (content )
181192 }
182- self .cachedStorage [key ] = value
193+ self .originStorage [key ] = value
183194 return value
184195}
185196
186- // GetOriginalStateValue returns the state value that is currently in the Trie, that is, ignoring any
187- // changes that have been made but not yet written to trie.
188- func (self * stateObject ) GetOriginalStateValue (db Database , key common.Hash ) common.Hash {
189- if original , exist := self .originalValue [key ]; exist {
190- // original value has been set, return it
191- return original
192- }
193- return self .GetState (db , key )
194- }
195-
196197// SetState updates a value in account storage.
197198func (self * stateObject ) SetState (db Database , key , value common.Hash ) {
199+ // If the new value is the same as old, don't set
198200 prev := self .GetState (db , key )
201+ if prev == value {
202+ return
203+ }
204+ // New value is different, update and journal the change
199205 self .db .journal .append (storageChange {
200206 account : & self .address ,
201207 key : key ,
202208 prevalue : prev ,
203209 })
204- if _ , isSet := self .originalValue [key ]; ! isSet {
205- // original value has not been set, so set it now
206- self .originalValue [key ] = prev
207- }
208210 self .setState (key , value )
209211}
210212
211213func (self * stateObject ) setState (key , value common.Hash ) {
212- self .cachedStorage [key ] = value
213214 self .dirtyStorage [key ] = value
214215}
215216
@@ -218,6 +219,13 @@ func (self *stateObject) updateTrie(db Database) Trie {
218219 tr := self .getTrie (db )
219220 for key , value := range self .dirtyStorage {
220221 delete (self .dirtyStorage , key )
222+
223+ // Skip noop changes, persist actual changes
224+ if value == self .originStorage [key ] {
225+ continue
226+ }
227+ self .originStorage [key ] = value
228+
221229 if (value == common.Hash {}) {
222230 self .setError (tr .TryDelete (key [:]))
223231 continue
@@ -226,10 +234,6 @@ func (self *stateObject) updateTrie(db Database) Trie {
226234 v , _ := rlp .EncodeToBytes (bytes .TrimLeft (value [:], "\x00 " ))
227235 self .setError (tr .TryUpdate (key [:], v ))
228236 }
229- // Clean the map containing 'original' value of storage entries
230- for k , _ := range self .originalValue {
231- delete (self .originalValue , k )
232- }
233237 return tr
234238}
235239
@@ -299,8 +303,7 @@ func (self *stateObject) deepCopy(db *StateDB) *stateObject {
299303 }
300304 stateObject .code = self .code
301305 stateObject .dirtyStorage = self .dirtyStorage .Copy ()
302- stateObject .cachedStorage = self .dirtyStorage .Copy ()
303- stateObject .originalValue = self .originalValue .Copy ()
306+ stateObject .originStorage = self .originStorage .Copy ()
304307 stateObject .suicided = self .suicided
305308 stateObject .dirtyCode = self .dirtyCode
306309 stateObject .deleted = self .deleted
0 commit comments