aboutsummaryrefslogtreecommitdiffstats
path: root/core
diff options
context:
space:
mode:
Diffstat (limited to 'core')
-rw-r--r--core/state/state_object.go34
-rw-r--r--core/state/statedb.go9
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.
//