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
fc8ad1b7
Unverified
Commit
fc8ad1b7
authored
Feb 15, 2022
by
Péter Szilágyi
Committed by
GitHub
Feb 15, 2022
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #24391 from rjl493456442/trie-iterator
trie: implement NodeBlob API for trie iterator
parents
4d086430
55430b6e
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
93 additions
and
0 deletions
+93
-0
iterator.go
trie/iterator.go
+33
-0
iterator_test.go
trie/iterator_test.go
+51
-0
trie.go
trie/trie.go
+9
-0
No files found.
trie/iterator.go
View file @
fc8ad1b7
...
@@ -86,6 +86,10 @@ type NodeIterator interface {
...
@@ -86,6 +86,10 @@ type NodeIterator interface {
// For leaf nodes, the last element of the path is the 'terminator symbol' 0x10.
// For leaf nodes, the last element of the path is the 'terminator symbol' 0x10.
Path
()
[]
byte
Path
()
[]
byte
// NodeBlob returns the rlp-encoded value of the current iterated node.
// If the node is an embedded node in its parent, nil is returned then.
NodeBlob
()
[]
byte
// Leaf returns true iff the current node is a leaf node.
// Leaf returns true iff the current node is a leaf node.
Leaf
()
bool
Leaf
()
bool
...
@@ -224,6 +228,18 @@ func (it *nodeIterator) Path() []byte {
...
@@ -224,6 +228,18 @@ func (it *nodeIterator) Path() []byte {
return
it
.
path
return
it
.
path
}
}
func
(
it
*
nodeIterator
)
NodeBlob
()
[]
byte
{
if
it
.
Hash
()
==
(
common
.
Hash
{})
{
return
nil
// skip the non-standalone node
}
blob
,
err
:=
it
.
resolveBlob
(
it
.
Hash
()
.
Bytes
(),
it
.
Path
())
if
err
!=
nil
{
it
.
err
=
err
return
nil
}
return
blob
}
func
(
it
*
nodeIterator
)
Error
()
error
{
func
(
it
*
nodeIterator
)
Error
()
error
{
if
it
.
err
==
errIteratorEnd
{
if
it
.
err
==
errIteratorEnd
{
return
nil
return
nil
...
@@ -362,6 +378,15 @@ func (it *nodeIterator) resolveHash(hash hashNode, path []byte) (node, error) {
...
@@ -362,6 +378,15 @@ func (it *nodeIterator) resolveHash(hash hashNode, path []byte) (node, error) {
return
resolved
,
err
return
resolved
,
err
}
}
func
(
it
*
nodeIterator
)
resolveBlob
(
hash
hashNode
,
path
[]
byte
)
([]
byte
,
error
)
{
if
it
.
resolver
!=
nil
{
if
blob
,
err
:=
it
.
resolver
.
Get
(
hash
);
err
==
nil
&&
len
(
blob
)
>
0
{
return
blob
,
nil
}
}
return
it
.
trie
.
resolveBlob
(
hash
,
path
)
}
func
(
st
*
nodeIteratorState
)
resolve
(
it
*
nodeIterator
,
path
[]
byte
)
error
{
func
(
st
*
nodeIteratorState
)
resolve
(
it
*
nodeIterator
,
path
[]
byte
)
error
{
if
hash
,
ok
:=
st
.
node
.
(
hashNode
);
ok
{
if
hash
,
ok
:=
st
.
node
.
(
hashNode
);
ok
{
resolved
,
err
:=
it
.
resolveHash
(
hash
,
path
)
resolved
,
err
:=
it
.
resolveHash
(
hash
,
path
)
...
@@ -549,6 +574,10 @@ func (it *differenceIterator) Path() []byte {
...
@@ -549,6 +574,10 @@ func (it *differenceIterator) Path() []byte {
return
it
.
b
.
Path
()
return
it
.
b
.
Path
()
}
}
func
(
it
*
differenceIterator
)
NodeBlob
()
[]
byte
{
return
it
.
b
.
NodeBlob
()
}
func
(
it
*
differenceIterator
)
AddResolver
(
resolver
ethdb
.
KeyValueReader
)
{
func
(
it
*
differenceIterator
)
AddResolver
(
resolver
ethdb
.
KeyValueReader
)
{
panic
(
"not implemented"
)
panic
(
"not implemented"
)
}
}
...
@@ -660,6 +689,10 @@ func (it *unionIterator) Path() []byte {
...
@@ -660,6 +689,10 @@ func (it *unionIterator) Path() []byte {
return
(
*
it
.
items
)[
0
]
.
Path
()
return
(
*
it
.
items
)[
0
]
.
Path
()
}
}
func
(
it
*
unionIterator
)
NodeBlob
()
[]
byte
{
return
(
*
it
.
items
)[
0
]
.
NodeBlob
()
}
func
(
it
*
unionIterator
)
AddResolver
(
resolver
ethdb
.
KeyValueReader
)
{
func
(
it
*
unionIterator
)
AddResolver
(
resolver
ethdb
.
KeyValueReader
)
{
panic
(
"not implemented"
)
panic
(
"not implemented"
)
}
}
...
...
trie/iterator_test.go
View file @
fc8ad1b7
...
@@ -525,3 +525,54 @@ func TestNodeIteratorLargeTrie(t *testing.T) {
...
@@ -525,3 +525,54 @@ func TestNodeIteratorLargeTrie(t *testing.T) {
t
.
Fatalf
(
"Too many lookups during seek, have %d want %d"
,
have
,
want
)
t
.
Fatalf
(
"Too many lookups during seek, have %d want %d"
,
have
,
want
)
}
}
}
}
func
TestIteratorNodeBlob
(
t
*
testing
.
T
)
{
var
(
db
=
memorydb
.
New
()
triedb
=
NewDatabase
(
db
)
trie
,
_
=
New
(
common
.
Hash
{},
triedb
)
)
vals
:=
[]
struct
{
k
,
v
string
}{
{
"do"
,
"verb"
},
{
"ether"
,
"wookiedoo"
},
{
"horse"
,
"stallion"
},
{
"shaman"
,
"horse"
},
{
"doge"
,
"coin"
},
{
"dog"
,
"puppy"
},
{
"somethingveryoddindeedthis is"
,
"myothernodedata"
},
}
all
:=
make
(
map
[
string
]
string
)
for
_
,
val
:=
range
vals
{
all
[
val
.
k
]
=
val
.
v
trie
.
Update
([]
byte
(
val
.
k
),
[]
byte
(
val
.
v
))
}
trie
.
Commit
(
nil
)
triedb
.
Cap
(
0
)
found
:=
make
(
map
[
common
.
Hash
][]
byte
)
it
:=
trie
.
NodeIterator
(
nil
)
for
it
.
Next
(
true
)
{
if
it
.
Hash
()
==
(
common
.
Hash
{})
{
continue
}
found
[
it
.
Hash
()]
=
it
.
NodeBlob
()
}
dbIter
:=
db
.
NewIterator
(
nil
,
nil
)
defer
dbIter
.
Release
()
var
count
int
for
dbIter
.
Next
()
{
got
,
present
:=
found
[
common
.
BytesToHash
(
dbIter
.
Key
())]
if
!
present
{
t
.
Fatalf
(
"Miss trie node %v"
,
dbIter
.
Key
())
}
if
!
bytes
.
Equal
(
got
,
dbIter
.
Value
())
{
t
.
Fatalf
(
"Unexpected trie node want %v got %v"
,
dbIter
.
Value
(),
got
)
}
count
+=
1
}
if
count
!=
len
(
found
)
{
t
.
Fatal
(
"Find extra trie node via iterator"
)
}
}
trie/trie.go
View file @
fc8ad1b7
...
@@ -514,6 +514,15 @@ func (t *Trie) resolveHash(n hashNode, prefix []byte) (node, error) {
...
@@ -514,6 +514,15 @@ func (t *Trie) resolveHash(n hashNode, prefix []byte) (node, error) {
return
nil
,
&
MissingNodeError
{
NodeHash
:
hash
,
Path
:
prefix
}
return
nil
,
&
MissingNodeError
{
NodeHash
:
hash
,
Path
:
prefix
}
}
}
func
(
t
*
Trie
)
resolveBlob
(
n
hashNode
,
prefix
[]
byte
)
([]
byte
,
error
)
{
hash
:=
common
.
BytesToHash
(
n
)
blob
,
_
:=
t
.
db
.
Node
(
hash
)
if
len
(
blob
)
!=
0
{
return
blob
,
nil
}
return
nil
,
&
MissingNodeError
{
NodeHash
:
hash
,
Path
:
prefix
}
}
// Hash returns the root hash of the trie. It does not write to the
// Hash returns the root hash of the trie. It does not write to the
// database and can be used even if the trie doesn't have one.
// database and can be used even if the trie doesn't have one.
func
(
t
*
Trie
)
Hash
()
common
.
Hash
{
func
(
t
*
Trie
)
Hash
()
common
.
Hash
{
...
...
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