diff options
Diffstat (limited to 'core')
-rw-r--r-- | core/state/state_object.go | 34 | ||||
-rw-r--r-- | core/state/statedb.go | 9 |
2 files changed, 42 insertions, 1 deletions
diff --git a/core/state/state_object.go b/core/state/state_object.go index 852c340b8..45ae95a2a 100644 --- a/core/state/state_object.go +++ b/core/state/state_object.go @@ -81,6 +81,7 @@ type stateObject struct { originStorage Storage // Storage cache of original entries to dedup rewrites dirtyStorage Storage // Storage entries that need to be flushed to disk + fakeStorage Storage // Fake storage which constructed by caller for debugging purpose. // Cache flags. // When an object is marked suicided it will be delete from the trie @@ -163,6 +164,10 @@ func (s *stateObject) getTrie(db Database) Trie { // GetState retrieves a value from the account storage trie. func (s *stateObject) GetState(db Database, key common.Hash) common.Hash { + // If the fake storage is set, only lookup the state here(in the debugging mode) + if s.fakeStorage != nil { + return s.fakeStorage[key] + } // If we have a dirty value for this state entry, return it value, dirty := s.dirtyStorage[key] if dirty { @@ -174,12 +179,16 @@ func (s *stateObject) GetState(db Database, key common.Hash) common.Hash { // GetCommittedState retrieves a value from the committed account storage trie. func (s *stateObject) GetCommittedState(db Database, key common.Hash) common.Hash { + // If the fake storage is set, only lookup the state here(in the debugging mode) + if s.fakeStorage != nil { + return s.fakeStorage[key] + } // If we have the original value cached, return that value, cached := s.originStorage[key] if cached { return value } - // Track the amount of time wasted on reading the storge trie + // Track the amount of time wasted on reading the storage trie if metrics.EnabledExpensive { defer func(start time.Time) { s.db.StorageReads += time.Since(start) }(time.Now()) } @@ -202,6 +211,11 @@ func (s *stateObject) GetCommittedState(db Database, key common.Hash) common.Has // SetState updates a value in account storage. func (s *stateObject) SetState(db Database, key, value common.Hash) { + // If the fake storage is set, put the temporary state update here. + if s.fakeStorage != nil { + s.fakeStorage[key] = value + return + } // If the new value is the same as old, don't set prev := s.GetState(db, key) if prev == value { @@ -216,6 +230,24 @@ func (s *stateObject) SetState(db Database, key, value common.Hash) { s.setState(key, value) } +// SetStorage replaces the entire state storage with the given one. +// +// After this function is called, all original state will be ignored and state +// lookup only happens in the fake state storage. +// +// Note this function should only be used for debugging purpose. +func (s *stateObject) SetStorage(storage map[common.Hash]common.Hash) { + // Allocate fake storage if it's nil. + if s.fakeStorage == nil { + s.fakeStorage = make(Storage) + } + for key, value := range storage { + s.fakeStorage[key] = value + } + // Don't bother journal since this function should only be used for + // debugging and the `fake` storage won't be committed to database. +} + func (s *stateObject) setState(key, value common.Hash) { s.dirtyStorage[key] = value } diff --git a/core/state/statedb.go b/core/state/statedb.go index 3bb9862ed..b07f08fd2 100644 --- a/core/state/statedb.go +++ b/core/state/statedb.go @@ -386,6 +386,15 @@ func (self *StateDB) SetState(addr common.Address, key, value common.Hash) { } } +// SetStorage replaces the entire storage for the specified account with given +// storage. This function should only be used for debugging. +func (self *StateDB) SetStorage(addr common.Address, storage map[common.Hash]common.Hash) { + stateObject := self.GetOrNewStateObject(addr) + if stateObject != nil { + stateObject.SetStorage(storage) + } +} + // Suicide marks the given account as suicided. // This clears the account balance. // |