aboutsummaryrefslogtreecommitdiffstats
path: root/core/state
diff options
context:
space:
mode:
authorPéter Szilágyi <peterke@gmail.com>2019-03-25 16:01:18 +0800
committerGitHub <noreply@github.com>2019-03-25 16:01:18 +0800
commit86989e3fcd93ac319dfbced226b3902520a5a4a9 (patch)
tree12cd70f812c25be27c9fd391190e3b09e8335322 /core/state
parente852505acedf6d3728330852b2d816ebf12a2cfb (diff)
downloadgo-tangerine-86989e3fcd93ac319dfbced226b3902520a5a4a9.tar
go-tangerine-86989e3fcd93ac319dfbced226b3902520a5a4a9.tar.gz
go-tangerine-86989e3fcd93ac319dfbced226b3902520a5a4a9.tar.bz2
go-tangerine-86989e3fcd93ac319dfbced226b3902520a5a4a9.tar.lz
go-tangerine-86989e3fcd93ac319dfbced226b3902520a5a4a9.tar.xz
go-tangerine-86989e3fcd93ac319dfbced226b3902520a5a4a9.tar.zst
go-tangerine-86989e3fcd93ac319dfbced226b3902520a5a4a9.zip
core: split out detailed trie access metrics from insertion time (#19316)
* core: split out detailed trie access metrics from insertion time * cmd, core, metrics: support expensive optional metrics
Diffstat (limited to 'core/state')
-rw-r--r--core/state/state_object.go20
-rw-r--r--core/state/statedb.go67
2 files changed, 71 insertions, 16 deletions
diff --git a/core/state/state_object.go b/core/state/state_object.go
index f41ab0409..7fbb45b3d 100644
--- a/core/state/state_object.go
+++ b/core/state/state_object.go
@@ -21,9 +21,11 @@ import (
"fmt"
"io"
"math/big"
+ "time"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/crypto"
+ "github.com/ethereum/go-ethereum/metrics"
"github.com/ethereum/go-ethereum/rlp"
)
@@ -177,6 +179,10 @@ func (self *stateObject) GetCommittedState(db Database, key common.Hash) common.
if cached {
return value
}
+ // Track the amount of time wasted on reading the storge trie
+ if metrics.EnabledExpensive {
+ defer func(start time.Time) { self.db.StorageReads += time.Since(start) }(time.Now())
+ }
// Otherwise load the value from the database
enc, err := self.getTrie(db).TryGet(key[:])
if err != nil {
@@ -216,6 +222,11 @@ func (self *stateObject) setState(key, value common.Hash) {
// updateTrie writes cached storage modifications into the object's storage trie.
func (self *stateObject) updateTrie(db Database) Trie {
+ // Track the amount of time wasted on updating the storge trie
+ if metrics.EnabledExpensive {
+ defer func(start time.Time) { self.db.StorageUpdates += time.Since(start) }(time.Now())
+ }
+ // Update all the dirty slots in the trie
tr := self.getTrie(db)
for key, value := range self.dirtyStorage {
delete(self.dirtyStorage, key)
@@ -240,6 +251,11 @@ func (self *stateObject) updateTrie(db Database) Trie {
// UpdateRoot sets the trie root to the current root hash of
func (self *stateObject) updateRoot(db Database) {
self.updateTrie(db)
+
+ // Track the amount of time wasted on hashing the storge trie
+ if metrics.EnabledExpensive {
+ defer func(start time.Time) { self.db.StorageHashes += time.Since(start) }(time.Now())
+ }
self.data.Root = self.trie.Hash()
}
@@ -250,6 +266,10 @@ func (self *stateObject) CommitTrie(db Database) error {
if self.dbErr != nil {
return self.dbErr
}
+ // Track the amount of time wasted on committing the storge trie
+ if metrics.EnabledExpensive {
+ defer func(start time.Time) { self.db.StorageCommits += time.Since(start) }(time.Now())
+ }
root, err := self.trie.Commit(nil)
if err == nil {
self.data.Root = root
diff --git a/core/state/statedb.go b/core/state/statedb.go
index 4c00092f4..0673de543 100644
--- a/core/state/statedb.go
+++ b/core/state/statedb.go
@@ -22,11 +22,13 @@ import (
"fmt"
"math/big"
"sort"
+ "time"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/log"
+ "github.com/ethereum/go-ethereum/metrics"
"github.com/ethereum/go-ethereum/rlp"
"github.com/ethereum/go-ethereum/trie"
)
@@ -86,6 +88,16 @@ type StateDB struct {
journal *journal
validRevisions []revision
nextRevisionId int
+
+ // Measurements gathered during execution for debugging purposes
+ AccountReads time.Duration
+ AccountHashes time.Duration
+ AccountUpdates time.Duration
+ AccountCommits time.Duration
+ StorageReads time.Duration
+ StorageHashes time.Duration
+ StorageUpdates time.Duration
+ StorageCommits time.Duration
}
// Create a new state from a given trie.
@@ -386,36 +398,51 @@ func (self *StateDB) Suicide(addr common.Address) bool {
//
// updateStateObject writes the given object to the trie.
-func (self *StateDB) updateStateObject(stateObject *stateObject) {
+func (s *StateDB) updateStateObject(stateObject *stateObject) {
+ // Track the amount of time wasted on updating the account from the trie
+ if metrics.EnabledExpensive {
+ defer func(start time.Time) { s.AccountUpdates += time.Since(start) }(time.Now())
+ }
+ // Encode the account and update the account trie
addr := stateObject.Address()
+
data, err := rlp.EncodeToBytes(stateObject)
if err != nil {
panic(fmt.Errorf("can't encode object at %x: %v", addr[:], err))
}
- self.setError(self.trie.TryUpdate(addr[:], data))
+ s.setError(s.trie.TryUpdate(addr[:], data))
}
// deleteStateObject removes the given object from the state trie.
-func (self *StateDB) deleteStateObject(stateObject *stateObject) {
+func (s *StateDB) deleteStateObject(stateObject *stateObject) {
+ // Track the amount of time wasted on deleting the account from the trie
+ if metrics.EnabledExpensive {
+ defer func(start time.Time) { s.AccountUpdates += time.Since(start) }(time.Now())
+ }
+ // Delete the account from the trie
stateObject.deleted = true
+
addr := stateObject.Address()
- self.setError(self.trie.TryDelete(addr[:]))
+ s.setError(s.trie.TryDelete(addr[:]))
}
// Retrieve a state object given by the address. Returns nil if not found.
-func (self *StateDB) getStateObject(addr common.Address) (stateObject *stateObject) {
- // Prefer 'live' objects.
- if obj := self.stateObjects[addr]; obj != nil {
+func (s *StateDB) getStateObject(addr common.Address) (stateObject *stateObject) {
+ // Prefer live objects
+ if obj := s.stateObjects[addr]; obj != nil {
if obj.deleted {
return nil
}
return obj
}
-
- // Load the object from the database.
- enc, err := self.trie.TryGet(addr[:])
+ // Track the amount of time wasted on loading the object from the database
+ if metrics.EnabledExpensive {
+ defer func(start time.Time) { s.AccountReads += time.Since(start) }(time.Now())
+ }
+ // Load the object from the database
+ enc, err := s.trie.TryGet(addr[:])
if len(enc) == 0 {
- self.setError(err)
+ s.setError(err)
return nil
}
var data Account
@@ -423,9 +450,9 @@ func (self *StateDB) getStateObject(addr common.Address) (stateObject *stateObje
log.Error("Failed to decode state object", "addr", addr, "err", err)
return nil
}
- // Insert into the live set.
- obj := newObject(self, addr, data)
- self.setStateObject(obj)
+ // Insert into the live set
+ obj := newObject(s, addr, data)
+ s.setStateObject(obj)
return obj
}
@@ -600,6 +627,11 @@ func (s *StateDB) Finalise(deleteEmptyObjects bool) {
// goes into transaction receipts.
func (s *StateDB) IntermediateRoot(deleteEmptyObjects bool) common.Hash {
s.Finalise(deleteEmptyObjects)
+
+ // Track the amount of time wasted on hashing the account trie
+ if metrics.EnabledExpensive {
+ defer func(start time.Time) { s.AccountHashes += time.Since(start) }(time.Now())
+ }
return s.trie.Hash()
}
@@ -624,7 +656,7 @@ func (s *StateDB) Commit(deleteEmptyObjects bool) (root common.Hash, err error)
for addr := range s.journal.dirties {
s.stateObjectsDirty[addr] = struct{}{}
}
- // Commit objects to the trie.
+ // Commit objects to the trie, measuring the elapsed time
for addr, stateObject := range s.stateObjects {
_, isDirty := s.stateObjectsDirty[addr]
switch {
@@ -647,7 +679,10 @@ func (s *StateDB) Commit(deleteEmptyObjects bool) (root common.Hash, err error)
}
delete(s.stateObjectsDirty, addr)
}
- // Write trie changes.
+ // Write the account trie changes, measuing the amount of wasted time
+ if metrics.EnabledExpensive {
+ defer func(start time.Time) { s.AccountCommits += time.Since(start) }(time.Now())
+ }
root, err = s.trie.Commit(func(leaf []byte, parent common.Hash) error {
var account Account
if err := rlp.DecodeBytes(leaf, &account); err != nil {