Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
G
Geth-Modification
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
张蕾
Geth-Modification
Commits
a5a52371
Unverified
Commit
a5a52371
authored
Aug 24, 2021
by
gary rong
Committed by
GitHub
Aug 24, 2021
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
core, light, tests, trie: add state metrics (#23433)
parent
a789dcc9
Changes
15
Hide whitespace changes
Inline
Side-by-side
Showing
15 changed files
with
131 additions
and
75 deletions
+131
-75
database.go
core/state/database.go
+1
-1
metrics.go
core/state/metrics.go
+28
-0
generate.go
core/state/snapshot/generate.go
+1
-1
generate_test.go
core/state/snapshot/generate_test.go
+8
-8
state_object.go
core/state/state_object.go
+9
-7
statedb.go
core/state/statedb.go
+24
-2
postprocess.go
light/postprocess.go
+2
-2
trie.go
light/trie.go
+2
-2
trie_fuzzer.go
tests/fuzzers/stacktrie/trie_fuzzer.go
+1
-1
trie-fuzzer.go
tests/fuzzers/trie/trie-fuzzer.go
+2
-2
committer.go
trie/committer.go
+34
-29
iterator_test.go
trie/iterator_test.go
+1
-1
secure_trie.go
trie/secure_trie.go
+1
-1
trie.go
trie/trie.go
+6
-7
trie_test.go
trie/trie_test.go
+11
-11
No files found.
core/state/database.go
View file @
a5a52371
...
...
@@ -86,7 +86,7 @@ type Trie interface {
// Commit writes all nodes to the trie's memory database, tracking the internal
// and external (for account tries) references.
Commit
(
onleaf
trie
.
LeafCallback
)
(
common
.
Hash
,
error
)
Commit
(
onleaf
trie
.
LeafCallback
)
(
common
.
Hash
,
int
,
error
)
// NodeIterator returns an iterator that returns nodes of the trie. Iteration
// starts at the key after the given start key.
...
...
core/state/metrics.go
0 → 100644
View file @
a5a52371
// Copyright 2021 The go-ethereum Authors
// This file is part of the go-ethereum library.
//
// The go-ethereum library is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// The go-ethereum library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
package
state
import
"github.com/ethereum/go-ethereum/metrics"
var
(
accountUpdatedMeter
=
metrics
.
NewRegisteredMeter
(
"state/update/account"
,
nil
)
storageUpdatedMeter
=
metrics
.
NewRegisteredMeter
(
"state/update/storage"
,
nil
)
accountDeletedMeter
=
metrics
.
NewRegisteredMeter
(
"state/delete/account"
,
nil
)
storageDeletedMeter
=
metrics
.
NewRegisteredMeter
(
"state/delete/storage"
,
nil
)
accountCommittedMeter
=
metrics
.
NewRegisteredMeter
(
"state/commit/account"
,
nil
)
storageCommittedMeter
=
metrics
.
NewRegisteredMeter
(
"state/commit/storage"
,
nil
)
)
core/state/snapshot/generate.go
View file @
a5a52371
...
...
@@ -436,7 +436,7 @@ func (dl *diskLayer) generateRange(root common.Hash, prefix []byte, kind string,
for
i
,
key
:=
range
result
.
keys
{
snapTrie
.
Update
(
key
,
result
.
vals
[
i
])
}
root
,
_
:=
snapTrie
.
Commit
(
nil
)
root
,
_
,
_
:=
snapTrie
.
Commit
(
nil
)
snapTrieDb
.
Commit
(
root
,
false
,
nil
)
}
tr
:=
result
.
tr
...
...
core/state/snapshot/generate_test.go
View file @
a5a52371
...
...
@@ -60,7 +60,7 @@ func TestGeneration(t *testing.T) {
acc
=
&
Account
{
Balance
:
big
.
NewInt
(
3
),
Root
:
stTrie
.
Hash
()
.
Bytes
(),
CodeHash
:
emptyCode
.
Bytes
()}
val
,
_
=
rlp
.
EncodeToBytes
(
acc
)
accTrie
.
Update
([]
byte
(
"acc-3"
),
val
)
// 0x50815097425d000edfc8b3a4a13e175fc2bdcfee8bdfbf2d1ff61041d3c235b2
root
,
_
:=
accTrie
.
Commit
(
nil
)
// Root: 0xe3712f1a226f3782caca78ca770ccc19ee000552813a9f59d479f8611db9b1fd
root
,
_
,
_
:=
accTrie
.
Commit
(
nil
)
// Root: 0xe3712f1a226f3782caca78ca770ccc19ee000552813a9f59d479f8611db9b1fd
triedb
.
Commit
(
root
,
false
,
nil
)
if
have
,
want
:=
root
,
common
.
HexToHash
(
"0xe3712f1a226f3782caca78ca770ccc19ee000552813a9f59d479f8611db9b1fd"
);
have
!=
want
{
...
...
@@ -128,7 +128,7 @@ func TestGenerateExistentState(t *testing.T) {
rawdb
.
WriteStorageSnapshot
(
diskdb
,
hashData
([]
byte
(
"acc-3"
)),
hashData
([]
byte
(
"key-2"
)),
[]
byte
(
"val-2"
))
rawdb
.
WriteStorageSnapshot
(
diskdb
,
hashData
([]
byte
(
"acc-3"
)),
hashData
([]
byte
(
"key-3"
)),
[]
byte
(
"val-3"
))
root
,
_
:=
accTrie
.
Commit
(
nil
)
// Root: 0xe3712f1a226f3782caca78ca770ccc19ee000552813a9f59d479f8611db9b1fd
root
,
_
,
_
:=
accTrie
.
Commit
(
nil
)
// Root: 0xe3712f1a226f3782caca78ca770ccc19ee000552813a9f59d479f8611db9b1fd
triedb
.
Commit
(
root
,
false
,
nil
)
snap
:=
generateSnapshot
(
diskdb
,
triedb
,
16
,
root
)
...
...
@@ -215,12 +215,12 @@ func (t *testHelper) makeStorageTrie(keys []string, vals []string) []byte {
for
i
,
k
:=
range
keys
{
stTrie
.
Update
([]
byte
(
k
),
[]
byte
(
vals
[
i
]))
}
root
,
_
:=
stTrie
.
Commit
(
nil
)
root
,
_
,
_
:=
stTrie
.
Commit
(
nil
)
return
root
.
Bytes
()
}
func
(
t
*
testHelper
)
Generate
()
(
common
.
Hash
,
*
diskLayer
)
{
root
,
_
:=
t
.
accTrie
.
Commit
(
nil
)
root
,
_
,
_
:=
t
.
accTrie
.
Commit
(
nil
)
t
.
triedb
.
Commit
(
root
,
false
,
nil
)
snap
:=
generateSnapshot
(
t
.
diskdb
,
t
.
triedb
,
16
,
root
)
return
root
,
snap
...
...
@@ -575,7 +575,7 @@ func TestGenerateWithExtraAccounts(t *testing.T) {
rawdb
.
WriteStorageSnapshot
(
diskdb
,
key
,
hashData
([]
byte
(
"b-key-2"
)),
[]
byte
(
"b-val-2"
))
rawdb
.
WriteStorageSnapshot
(
diskdb
,
key
,
hashData
([]
byte
(
"b-key-3"
)),
[]
byte
(
"b-val-3"
))
}
root
,
_
:=
accTrie
.
Commit
(
nil
)
root
,
_
,
_
:=
accTrie
.
Commit
(
nil
)
t
.
Logf
(
"root: %x"
,
root
)
triedb
.
Commit
(
root
,
false
,
nil
)
// To verify the test: If we now inspect the snap db, there should exist extraneous storage items
...
...
@@ -637,7 +637,7 @@ func TestGenerateWithManyExtraAccounts(t *testing.T) {
rawdb
.
WriteAccountSnapshot
(
diskdb
,
key
,
val
)
}
}
root
,
_
:=
accTrie
.
Commit
(
nil
)
root
,
_
,
_
:=
accTrie
.
Commit
(
nil
)
t
.
Logf
(
"root: %x"
,
root
)
triedb
.
Commit
(
root
,
false
,
nil
)
...
...
@@ -690,7 +690,7 @@ func TestGenerateWithExtraBeforeAndAfter(t *testing.T) {
rawdb
.
WriteAccountSnapshot
(
diskdb
,
common
.
HexToHash
(
"0x07"
),
val
)
}
root
,
_
:=
accTrie
.
Commit
(
nil
)
root
,
_
,
_
:=
accTrie
.
Commit
(
nil
)
t
.
Logf
(
"root: %x"
,
root
)
triedb
.
Commit
(
root
,
false
,
nil
)
...
...
@@ -734,7 +734,7 @@ func TestGenerateWithMalformedSnapdata(t *testing.T) {
rawdb
.
WriteAccountSnapshot
(
diskdb
,
common
.
HexToHash
(
"0x05"
),
junk
)
}
root
,
_
:=
accTrie
.
Commit
(
nil
)
root
,
_
,
_
:=
accTrie
.
Commit
(
nil
)
t
.
Logf
(
"root: %x"
,
root
)
triedb
.
Commit
(
root
,
false
,
nil
)
...
...
core/state/state_object.go
View file @
a5a52371
...
...
@@ -329,7 +329,7 @@ func (s *stateObject) finalise(prefetch bool) {
// It will return nil if the trie has not been loaded and no changes have been made
func
(
s
*
stateObject
)
updateTrie
(
db
Database
)
Trie
{
// Make sure all dirty slots are finalized into the pending storage area
s
.
finalise
(
false
)
// Don't prefetch any
more, pull directly if need be
s
.
finalise
(
false
)
// Don't prefetch anymore, pull directly if need be
if
len
(
s
.
pendingStorage
)
==
0
{
return
s
.
trie
}
...
...
@@ -354,10 +354,12 @@ func (s *stateObject) updateTrie(db Database) Trie {
var
v
[]
byte
if
(
value
==
common
.
Hash
{})
{
s
.
setError
(
tr
.
TryDelete
(
key
[
:
]))
s
.
db
.
StorageDeleted
+=
1
}
else
{
// Encoding []byte cannot fail, ok to ignore the error.
v
,
_
=
rlp
.
EncodeToBytes
(
common
.
TrimLeftZeroes
(
value
[
:
]))
s
.
setError
(
tr
.
TryUpdate
(
key
[
:
],
v
))
s
.
db
.
StorageUpdated
+=
1
}
// If state snapshotting is active, cache the data til commit
if
s
.
db
.
snap
!=
nil
{
...
...
@@ -368,7 +370,7 @@ func (s *stateObject) updateTrie(db Database) Trie {
s
.
db
.
snapStorage
[
s
.
addrHash
]
=
storage
}
}
storage
[
crypto
.
HashData
(
hasher
,
key
[
:
])]
=
v
// v will be nil if
value is 0x00
storage
[
crypto
.
HashData
(
hasher
,
key
[
:
])]
=
v
// v will be nil if
it's deleted
}
usedStorage
=
append
(
usedStorage
,
common
.
CopyBytes
(
key
[
:
]))
// Copy needed for closure
}
...
...
@@ -396,23 +398,23 @@ func (s *stateObject) updateRoot(db Database) {
// CommitTrie the storage trie of the object to db.
// This updates the trie root.
func
(
s
*
stateObject
)
CommitTrie
(
db
Database
)
error
{
func
(
s
*
stateObject
)
CommitTrie
(
db
Database
)
(
int
,
error
)
{
// If nothing changed, don't bother with hashing anything
if
s
.
updateTrie
(
db
)
==
nil
{
return
nil
return
0
,
nil
}
if
s
.
dbErr
!=
nil
{
return
s
.
dbErr
return
0
,
s
.
dbErr
}
// Track the amount of time wasted on committing the storage trie
if
metrics
.
EnabledExpensive
{
defer
func
(
start
time
.
Time
)
{
s
.
db
.
StorageCommits
+=
time
.
Since
(
start
)
}(
time
.
Now
())
}
root
,
err
:=
s
.
trie
.
Commit
(
nil
)
root
,
committed
,
err
:=
s
.
trie
.
Commit
(
nil
)
if
err
==
nil
{
s
.
data
.
Root
=
root
}
return
err
return
committed
,
err
}
// AddBalance adds amount to s's balance.
...
...
core/state/statedb.go
View file @
a5a52371
...
...
@@ -117,6 +117,11 @@ type StateDB struct {
SnapshotAccountReads
time
.
Duration
SnapshotStorageReads
time
.
Duration
SnapshotCommits
time
.
Duration
AccountUpdated
int
StorageUpdated
int
AccountDeleted
int
StorageDeleted
int
}
// New creates a new state from a given trie.
...
...
@@ -860,8 +865,10 @@ func (s *StateDB) IntermediateRoot(deleteEmptyObjects bool) common.Hash {
for
addr
:=
range
s
.
stateObjectsPending
{
if
obj
:=
s
.
stateObjects
[
addr
];
obj
.
deleted
{
s
.
deleteStateObject
(
obj
)
s
.
AccountDeleted
+=
1
}
else
{
s
.
updateStateObject
(
obj
)
s
.
AccountUpdated
+=
1
}
usedAddrs
=
append
(
usedAddrs
,
common
.
CopyBytes
(
addr
[
:
]))
// Copy needed for closure
}
...
...
@@ -903,6 +910,7 @@ func (s *StateDB) Commit(deleteEmptyObjects bool) (common.Hash, error) {
s
.
IntermediateRoot
(
deleteEmptyObjects
)
// Commit objects to the trie, measuring the elapsed time
var
storageCommitted
int
codeWriter
:=
s
.
db
.
TrieDB
()
.
DiskDB
()
.
NewBatch
()
for
addr
:=
range
s
.
stateObjectsDirty
{
if
obj
:=
s
.
stateObjects
[
addr
];
!
obj
.
deleted
{
...
...
@@ -912,9 +920,11 @@ func (s *StateDB) Commit(deleteEmptyObjects bool) (common.Hash, error) {
obj
.
dirtyCode
=
false
}
// Write any storage changes in the state object to its storage trie
if
err
:=
obj
.
CommitTrie
(
s
.
db
);
err
!=
nil
{
committed
,
err
:=
obj
.
CommitTrie
(
s
.
db
)
if
err
!=
nil
{
return
common
.
Hash
{},
err
}
storageCommitted
+=
committed
}
}
if
len
(
s
.
stateObjectsDirty
)
>
0
{
...
...
@@ -933,7 +943,7 @@ func (s *StateDB) Commit(deleteEmptyObjects bool) (common.Hash, error) {
// The onleaf func is called _serially_, so we can reuse the same account
// for unmarshalling every time.
var
account
Account
root
,
err
:=
s
.
trie
.
Commit
(
func
(
_
[][]
byte
,
_
[]
byte
,
leaf
[]
byte
,
parent
common
.
Hash
)
error
{
root
,
accountCommitted
,
err
:=
s
.
trie
.
Commit
(
func
(
_
[][]
byte
,
_
[]
byte
,
leaf
[]
byte
,
parent
common
.
Hash
)
error
{
if
err
:=
rlp
.
DecodeBytes
(
leaf
,
&
account
);
err
!=
nil
{
return
nil
}
...
...
@@ -942,8 +952,20 @@ func (s *StateDB) Commit(deleteEmptyObjects bool) (common.Hash, error) {
}
return
nil
})
if
err
!=
nil
{
return
common
.
Hash
{},
err
}
if
metrics
.
EnabledExpensive
{
s
.
AccountCommits
+=
time
.
Since
(
start
)
accountUpdatedMeter
.
Mark
(
int64
(
s
.
AccountUpdated
))
storageUpdatedMeter
.
Mark
(
int64
(
s
.
StorageUpdated
))
accountDeletedMeter
.
Mark
(
int64
(
s
.
AccountDeleted
))
storageDeletedMeter
.
Mark
(
int64
(
s
.
StorageDeleted
))
accountCommittedMeter
.
Mark
(
int64
(
accountCommitted
))
storageCommittedMeter
.
Mark
(
int64
(
storageCommitted
))
s
.
AccountUpdated
,
s
.
AccountDeleted
=
0
,
0
s
.
StorageUpdated
,
s
.
StorageDeleted
=
0
,
0
}
// If snapshotting is enabled, update the snapshot tree with this new version
if
s
.
snap
!=
nil
{
...
...
light/postprocess.go
View file @
a5a52371
...
...
@@ -217,7 +217,7 @@ func (c *ChtIndexerBackend) Process(ctx context.Context, header *types.Header) e
// Commit implements core.ChainIndexerBackend
func
(
c
*
ChtIndexerBackend
)
Commit
()
error
{
root
,
err
:=
c
.
trie
.
Commit
(
nil
)
root
,
_
,
err
:=
c
.
trie
.
Commit
(
nil
)
if
err
!=
nil
{
return
err
}
...
...
@@ -454,7 +454,7 @@ func (b *BloomTrieIndexerBackend) Commit() error {
b
.
trie
.
Delete
(
encKey
[
:
])
}
}
root
,
err
:=
b
.
trie
.
Commit
(
nil
)
root
,
_
,
err
:=
b
.
trie
.
Commit
(
nil
)
if
err
!=
nil
{
return
err
}
...
...
light/trie.go
View file @
a5a52371
...
...
@@ -125,9 +125,9 @@ func (t *odrTrie) TryDelete(key []byte) error {
})
}
func
(
t
*
odrTrie
)
Commit
(
onleaf
trie
.
LeafCallback
)
(
common
.
Hash
,
error
)
{
func
(
t
*
odrTrie
)
Commit
(
onleaf
trie
.
LeafCallback
)
(
common
.
Hash
,
int
,
error
)
{
if
t
.
trie
==
nil
{
return
t
.
id
.
Root
,
nil
return
t
.
id
.
Root
,
0
,
nil
}
return
t
.
trie
.
Commit
(
onleaf
)
}
...
...
tests/fuzzers/stacktrie/trie_fuzzer.go
View file @
a5a52371
...
...
@@ -173,7 +173,7 @@ func (f *fuzzer) fuzz() int {
return
0
}
// Flush trie -> database
rootA
,
err
:=
trieA
.
Commit
(
nil
)
rootA
,
_
,
err
:=
trieA
.
Commit
(
nil
)
if
err
!=
nil
{
panic
(
err
)
}
...
...
tests/fuzzers/trie/trie-fuzzer.go
View file @
a5a52371
...
...
@@ -162,11 +162,11 @@ func runRandTest(rt randTest) error {
rt
[
i
]
.
err
=
fmt
.
Errorf
(
"mismatch for key 0x%x, got 0x%x want 0x%x"
,
step
.
key
,
v
,
want
)
}
case
opCommit
:
_
,
rt
[
i
]
.
err
=
tr
.
Commit
(
nil
)
_
,
_
,
rt
[
i
]
.
err
=
tr
.
Commit
(
nil
)
case
opHash
:
tr
.
Hash
()
case
opReset
:
hash
,
err
:=
tr
.
Commit
(
nil
)
hash
,
_
,
err
:=
tr
.
Commit
(
nil
)
if
err
!=
nil
{
return
err
}
...
...
trie/committer.go
View file @
a5a52371
...
...
@@ -72,24 +72,24 @@ func returnCommitterToPool(h *committer) {
committerPool
.
Put
(
h
)
}
//
c
ommit collapses a node down into a hash node and inserts it into the database
func
(
c
*
committer
)
Commit
(
n
node
,
db
*
Database
)
(
hashNode
,
error
)
{
//
C
ommit collapses a node down into a hash node and inserts it into the database
func
(
c
*
committer
)
Commit
(
n
node
,
db
*
Database
)
(
hashNode
,
int
,
error
)
{
if
db
==
nil
{
return
nil
,
errors
.
New
(
"no db provided"
)
return
nil
,
0
,
errors
.
New
(
"no db provided"
)
}
h
,
err
:=
c
.
commit
(
n
,
db
)
h
,
committed
,
err
:=
c
.
commit
(
n
,
db
)
if
err
!=
nil
{
return
nil
,
err
return
nil
,
0
,
err
}
return
h
.
(
hashNode
),
nil
return
h
.
(
hashNode
),
committed
,
nil
}
// commit collapses a node down into a hash node and inserts it into the database
func
(
c
*
committer
)
commit
(
n
node
,
db
*
Database
)
(
node
,
error
)
{
func
(
c
*
committer
)
commit
(
n
node
,
db
*
Database
)
(
node
,
int
,
error
)
{
// if this path is clean, use available cached data
hash
,
dirty
:=
n
.
cache
()
if
hash
!=
nil
&&
!
dirty
{
return
hash
,
nil
return
hash
,
0
,
nil
}
// Commit children, then parent, and remove remove the dirty flag.
switch
cn
:=
n
.
(
type
)
{
...
...
@@ -97,37 +97,38 @@ func (c *committer) commit(n node, db *Database) (node, error) {
// Commit child
collapsed
:=
cn
.
copy
()
// If the child is fullnode, recursively commit.
// Otherwise it can only be hashNode or valueNode.
// If the child is fullNode, recursively commit,
// otherwise it can only be hashNode or valueNode.
var
childCommitted
int
if
_
,
ok
:=
cn
.
Val
.
(
*
fullNode
);
ok
{
childV
,
err
:=
c
.
commit
(
cn
.
Val
,
db
)
childV
,
committed
,
err
:=
c
.
commit
(
cn
.
Val
,
db
)
if
err
!=
nil
{
return
nil
,
err
return
nil
,
0
,
err
}
collapsed
.
Val
=
childV
collapsed
.
Val
,
childCommitted
=
childV
,
committed
}
// The key needs to be copied, since we're delivering it to database
collapsed
.
Key
=
hexToCompact
(
cn
.
Key
)
hashedNode
:=
c
.
store
(
collapsed
,
db
)
if
hn
,
ok
:=
hashedNode
.
(
hashNode
);
ok
{
return
hn
,
nil
return
hn
,
childCommitted
+
1
,
nil
}
return
collapsed
,
nil
return
collapsed
,
childCommitted
,
nil
case
*
fullNode
:
hashedKids
,
err
:=
c
.
commitChildren
(
cn
,
db
)
hashedKids
,
childCommitted
,
err
:=
c
.
commitChildren
(
cn
,
db
)
if
err
!=
nil
{
return
nil
,
err
return
nil
,
0
,
err
}
collapsed
:=
cn
.
copy
()
collapsed
.
Children
=
hashedKids
hashedNode
:=
c
.
store
(
collapsed
,
db
)
if
hn
,
ok
:=
hashedNode
.
(
hashNode
);
ok
{
return
hn
,
nil
return
hn
,
childCommitted
+
1
,
nil
}
return
collapsed
,
nil
return
collapsed
,
childCommitted
,
nil
case
hashNode
:
return
cn
,
nil
return
cn
,
0
,
nil
default
:
// nil, valuenode shouldn't be committed
panic
(
fmt
.
Sprintf
(
"%T: invalid node: %v"
,
n
,
n
))
...
...
@@ -135,8 +136,11 @@ func (c *committer) commit(n node, db *Database) (node, error) {
}
// commitChildren commits the children of the given fullnode
func
(
c
*
committer
)
commitChildren
(
n
*
fullNode
,
db
*
Database
)
([
17
]
node
,
error
)
{
var
children
[
17
]
node
func
(
c
*
committer
)
commitChildren
(
n
*
fullNode
,
db
*
Database
)
([
17
]
node
,
int
,
error
)
{
var
(
committed
int
children
[
17
]
node
)
for
i
:=
0
;
i
<
16
;
i
++
{
child
:=
n
.
Children
[
i
]
if
child
==
nil
{
...
...
@@ -144,25 +148,26 @@ func (c *committer) commitChildren(n *fullNode, db *Database) ([17]node, error)
}
// If it's the hashed child, save the hash value directly.
// Note: it's impossible that the child in range [0, 15]
// is a value
n
ode.
// is a value
N
ode.
if
hn
,
ok
:=
child
.
(
hashNode
);
ok
{
children
[
i
]
=
hn
continue
}
// Commit the child recursively and store the "hashed" value.
// Note the returned node can be some embedded nodes, so it's
// possible the type is not hash
n
ode.
hashed
,
err
:=
c
.
commit
(
child
,
db
)
// possible the type is not hash
N
ode.
hashed
,
childCommitted
,
err
:=
c
.
commit
(
child
,
db
)
if
err
!=
nil
{
return
children
,
err
return
children
,
0
,
err
}
children
[
i
]
=
hashed
committed
+=
childCommitted
}
// For the 17th child, it's possible the type is valuenode.
if
n
.
Children
[
16
]
!=
nil
{
children
[
16
]
=
n
.
Children
[
16
]
}
return
children
,
nil
return
children
,
committed
,
nil
}
// store hashes the node n and if we have a storage layer specified, it writes
...
...
@@ -176,7 +181,7 @@ func (c *committer) store(n node, db *Database) node {
)
if
hash
==
nil
{
// This was not generated - must be a small node stored in the parent.
// In theory we should apply the leafCall here if it's not nil(embedded
// In theory
,
we should apply the leafCall here if it's not nil(embedded
// node usually contains value). But small value(less than 32bytes) is
// not our target.
return
n
...
...
@@ -224,7 +229,7 @@ func (c *committer) commitLoop(db *Database) {
}
case
*
fullNode
:
// For children in range [0, 15], it's impossible
// to contain value
n
ode. Only check the 17th child.
// to contain value
N
ode. Only check the 17th child.
if
n
.
Children
[
16
]
!=
nil
{
c
.
onleaf
(
nil
,
nil
,
n
.
Children
[
16
]
.
(
valueNode
),
hash
)
}
...
...
trie/iterator_test.go
View file @
a5a52371
...
...
@@ -393,7 +393,7 @@ func testIteratorContinueAfterSeekError(t *testing.T, memonly bool) {
for
_
,
val
:=
range
testdata1
{
ctr
.
Update
([]
byte
(
val
.
k
),
[]
byte
(
val
.
v
))
}
root
,
_
:=
ctr
.
Commit
(
nil
)
root
,
_
,
_
:=
ctr
.
Commit
(
nil
)
if
!
memonly
{
triedb
.
Commit
(
root
,
true
,
nil
)
}
...
...
trie/secure_trie.go
View file @
a5a52371
...
...
@@ -144,7 +144,7 @@ func (t *SecureTrie) GetKey(shaKey []byte) []byte {
//
// Committing flushes nodes from memory. Subsequent Get calls will load nodes
// from the database.
func
(
t
*
SecureTrie
)
Commit
(
onleaf
LeafCallback
)
(
root
common
.
Hash
,
err
error
)
{
func
(
t
*
SecureTrie
)
Commit
(
onleaf
LeafCallback
)
(
common
.
Hash
,
int
,
error
)
{
// Write all the pre-images to the actual disk database
if
len
(
t
.
getSecKeyCache
())
>
0
{
if
t
.
trie
.
db
.
preimages
!=
nil
{
// Ugly direct check but avoids the below write lock
...
...
trie/trie.go
View file @
a5a52371
...
...
@@ -514,12 +514,12 @@ func (t *Trie) Hash() common.Hash {
// Commit writes all nodes to the trie's memory database, tracking the internal
// and external (for account tries) references.
func
(
t
*
Trie
)
Commit
(
onleaf
LeafCallback
)
(
root
common
.
Hash
,
err
error
)
{
func
(
t
*
Trie
)
Commit
(
onleaf
LeafCallback
)
(
common
.
Hash
,
int
,
error
)
{
if
t
.
db
==
nil
{
panic
(
"commit called on trie with nil database"
)
}
if
t
.
root
==
nil
{
return
emptyRoot
,
nil
return
emptyRoot
,
0
,
nil
}
// Derive the hash for all dirty nodes first. We hold the assumption
// in the following procedure that all nodes are hashed.
...
...
@@ -531,7 +531,7 @@ func (t *Trie) Commit(onleaf LeafCallback) (root common.Hash, err error) {
// up goroutines. This can happen e.g. if we load a trie for reading storage
// values, but don't write to it.
if
_
,
dirty
:=
t
.
root
.
cache
();
!
dirty
{
return
rootHash
,
nil
return
rootHash
,
0
,
nil
}
var
wg
sync
.
WaitGroup
if
onleaf
!=
nil
{
...
...
@@ -543,8 +543,7 @@ func (t *Trie) Commit(onleaf LeafCallback) (root common.Hash, err error) {
h
.
commitLoop
(
t
.
db
)
}()
}
var
newRoot
hashNode
newRoot
,
err
=
h
.
Commit
(
t
.
root
,
t
.
db
)
newRoot
,
committed
,
err
:=
h
.
Commit
(
t
.
root
,
t
.
db
)
if
onleaf
!=
nil
{
// The leafch is created in newCommitter if there was an onleaf callback
// provided. The commitLoop only _reads_ from it, and the commit
...
...
@@ -554,10 +553,10 @@ func (t *Trie) Commit(onleaf LeafCallback) (root common.Hash, err error) {
wg
.
Wait
()
}
if
err
!=
nil
{
return
common
.
Hash
{},
err
return
common
.
Hash
{},
0
,
err
}
t
.
root
=
newRoot
return
rootHash
,
nil
return
rootHash
,
committed
,
nil
}
// hashRoot calculates the root hash of the given trie
...
...
trie/trie_test.go
View file @
a5a52371
...
...
@@ -90,7 +90,7 @@ func testMissingNode(t *testing.T, memonly bool) {
trie
,
_
:=
New
(
common
.
Hash
{},
triedb
)
updateString
(
trie
,
"120000"
,
"qwerqwerqwerqwerqwerqwerqwerqwer"
)
updateString
(
trie
,
"123456"
,
"asdfasdfasdfasdfasdfasdfasdfasdf"
)
root
,
_
:=
trie
.
Commit
(
nil
)
root
,
_
,
_
:=
trie
.
Commit
(
nil
)
if
!
memonly
{
triedb
.
Commit
(
root
,
true
,
nil
)
}
...
...
@@ -172,7 +172,7 @@ func TestInsert(t *testing.T) {
updateString
(
trie
,
"A"
,
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
)
exp
=
common
.
HexToHash
(
"d23786fb4a010da3ce639d66d5e904a11dbc02746d1ce25029e53290cabf28ab"
)
root
,
err
:=
trie
.
Commit
(
nil
)
root
,
_
,
err
:=
trie
.
Commit
(
nil
)
if
err
!=
nil
{
t
.
Fatalf
(
"commit error: %v"
,
err
)
}
...
...
@@ -270,7 +270,7 @@ func TestReplication(t *testing.T) {
for
_
,
val
:=
range
vals
{
updateString
(
trie
,
val
.
k
,
val
.
v
)
}
exp
,
err
:=
trie
.
Commit
(
nil
)
exp
,
_
,
err
:=
trie
.
Commit
(
nil
)
if
err
!=
nil
{
t
.
Fatalf
(
"commit error: %v"
,
err
)
}
...
...
@@ -285,7 +285,7 @@ func TestReplication(t *testing.T) {
t
.
Errorf
(
"trie2 doesn't have %q => %q"
,
kv
.
k
,
kv
.
v
)
}
}
hash
,
err
:=
trie2
.
Commit
(
nil
)
hash
,
_
,
err
:=
trie2
.
Commit
(
nil
)
if
err
!=
nil
{
t
.
Fatalf
(
"commit error: %v"
,
err
)
}
...
...
@@ -429,11 +429,11 @@ func runRandTest(rt randTest) bool {
rt
[
i
]
.
err
=
fmt
.
Errorf
(
"mismatch for key 0x%x, got 0x%x want 0x%x"
,
step
.
key
,
v
,
want
)
}
case
opCommit
:
_
,
rt
[
i
]
.
err
=
tr
.
Commit
(
nil
)
_
,
_
,
rt
[
i
]
.
err
=
tr
.
Commit
(
nil
)
case
opHash
:
tr
.
Hash
()
case
opReset
:
hash
,
err
:=
tr
.
Commit
(
nil
)
hash
,
_
,
err
:=
tr
.
Commit
(
nil
)
if
err
!=
nil
{
rt
[
i
]
.
err
=
err
return
false
...
...
@@ -633,7 +633,7 @@ func TestCommitAfterHash(t *testing.T) {
if
exp
!=
root
{
t
.
Errorf
(
"got %x, exp %x"
,
root
,
exp
)
}
root
,
_
=
trie
.
Commit
(
nil
)
root
,
_
,
_
=
trie
.
Commit
(
nil
)
if
exp
!=
root
{
t
.
Errorf
(
"got %x, exp %x"
,
root
,
exp
)
}
...
...
@@ -740,7 +740,7 @@ func TestCommitSequence(t *testing.T) {
trie
.
Update
(
crypto
.
Keccak256
(
addresses
[
i
][
:
]),
accounts
[
i
])
}
// Flush trie -> database
root
,
_
:=
trie
.
Commit
(
nil
)
root
,
_
,
_
:=
trie
.
Commit
(
nil
)
// Flush memdb -> disk (sponge)
db
.
Commit
(
root
,
false
,
func
(
c
common
.
Hash
)
{
// And spongify the callback-order
...
...
@@ -792,7 +792,7 @@ func TestCommitSequenceRandomBlobs(t *testing.T) {
trie
.
Update
(
key
,
val
)
}
// Flush trie -> database
root
,
_
:=
trie
.
Commit
(
nil
)
root
,
_
,
_
:=
trie
.
Commit
(
nil
)
// Flush memdb -> disk (sponge)
db
.
Commit
(
root
,
false
,
func
(
c
common
.
Hash
)
{
// And spongify the callback-order
...
...
@@ -834,7 +834,7 @@ func TestCommitSequenceStackTrie(t *testing.T) {
stTrie
.
TryUpdate
(
key
,
val
)
}
// Flush trie -> database
root
,
_
:=
trie
.
Commit
(
nil
)
root
,
_
,
_
:=
trie
.
Commit
(
nil
)
// Flush memdb -> disk (sponge)
db
.
Commit
(
root
,
false
,
nil
)
// And flush stacktrie -> disk
...
...
@@ -879,7 +879,7 @@ func TestCommitSequenceSmallRoot(t *testing.T) {
trie
.
TryUpdate
(
key
,
[]
byte
{
0x1
})
stTrie
.
TryUpdate
(
key
,
[]
byte
{
0x1
})
// Flush trie -> database
root
,
_
:=
trie
.
Commit
(
nil
)
root
,
_
,
_
:=
trie
.
Commit
(
nil
)
// Flush memdb -> disk (sponge)
db
.
Commit
(
root
,
false
,
nil
)
// And flush stacktrie -> disk
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment