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
25b16085
Unverified
Commit
25b16085
authored
Sep 23, 2020
by
gary rong
Committed by
GitHub
Sep 23, 2020
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
trie: support empty range proof (#21199)
parent
e1365b24
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
50 additions
and
4 deletions
+50
-4
proof.go
trie/proof.go
+17
-4
proof_test.go
trie/proof_test.go
+33
-0
No files found.
trie/proof.go
View file @
25b16085
...
@@ -393,7 +393,7 @@ func hasRightElement(node node, key []byte) bool {
...
@@ -393,7 +393,7 @@ func hasRightElement(node node, key []byte) bool {
// (unless firstProof is an existent proof).
// (unless firstProof is an existent proof).
//
//
// Expect the normal case, this function can also be used to verify the following
// Expect the normal case, this function can also be used to verify the following
// range proofs
(note this function doesn't accept zero element proof)
:
// range proofs:
//
//
// - All elements proof. In this case the left and right proof can be nil, but the
// - All elements proof. In this case the left and right proof can be nil, but the
// range should be all the leaves in the trie.
// range should be all the leaves in the trie.
...
@@ -401,15 +401,16 @@ func hasRightElement(node node, key []byte) bool {
...
@@ -401,15 +401,16 @@ func hasRightElement(node node, key []byte) bool {
// - One element proof. In this case no matter the left edge proof is a non-existent
// - One element proof. In this case no matter the left edge proof is a non-existent
// proof or not, we can always verify the correctness of the proof.
// proof or not, we can always verify the correctness of the proof.
//
//
// - Zero element proof(left edge proof should be a non-existent proof). In this
// case if there are still some other leaves available on the right side, then
// an error will be returned.
//
// Except returning the error to indicate the proof is valid or not, the function will
// Except returning the error to indicate the proof is valid or not, the function will
// also return a flag to indicate whether there exists more accounts/slots in the trie.
// also return a flag to indicate whether there exists more accounts/slots in the trie.
func
VerifyRangeProof
(
rootHash
common
.
Hash
,
firstKey
[]
byte
,
keys
[][]
byte
,
values
[][]
byte
,
firstProof
ethdb
.
KeyValueReader
,
lastProof
ethdb
.
KeyValueReader
)
(
error
,
bool
)
{
func
VerifyRangeProof
(
rootHash
common
.
Hash
,
firstKey
[]
byte
,
keys
[][]
byte
,
values
[][]
byte
,
firstProof
ethdb
.
KeyValueReader
,
lastProof
ethdb
.
KeyValueReader
)
(
error
,
bool
)
{
if
len
(
keys
)
!=
len
(
values
)
{
if
len
(
keys
)
!=
len
(
values
)
{
return
fmt
.
Errorf
(
"inconsistent proof data, keys: %d, values: %d"
,
len
(
keys
),
len
(
values
)),
false
return
fmt
.
Errorf
(
"inconsistent proof data, keys: %d, values: %d"
,
len
(
keys
),
len
(
values
)),
false
}
}
if
len
(
keys
)
==
0
{
return
errors
.
New
(
"empty proof"
),
false
}
// Ensure the received batch is monotonic increasing.
// Ensure the received batch is monotonic increasing.
for
i
:=
0
;
i
<
len
(
keys
)
-
1
;
i
++
{
for
i
:=
0
;
i
<
len
(
keys
)
-
1
;
i
++
{
if
bytes
.
Compare
(
keys
[
i
],
keys
[
i
+
1
])
>=
0
{
if
bytes
.
Compare
(
keys
[
i
],
keys
[
i
+
1
])
>=
0
{
...
@@ -431,6 +432,18 @@ func VerifyRangeProof(rootHash common.Hash, firstKey []byte, keys [][]byte, valu
...
@@ -431,6 +432,18 @@ func VerifyRangeProof(rootHash common.Hash, firstKey []byte, keys [][]byte, valu
}
}
return
nil
,
false
// no more element.
return
nil
,
false
// no more element.
}
}
// Special case, there is a provided left edge proof and zero key/value
// pairs, ensure there are no more accounts / slots in the trie.
if
len
(
keys
)
==
0
{
root
,
val
,
err
:=
proofToPath
(
rootHash
,
nil
,
firstKey
,
firstProof
,
true
)
if
err
!=
nil
{
return
err
,
false
}
if
val
!=
nil
||
hasRightElement
(
root
,
firstKey
)
{
return
errors
.
New
(
"more entries available"
),
false
}
return
nil
,
false
}
// Special case, there is only one element and left edge
// Special case, there is only one element and left edge
// proof is an existent one.
// proof is an existent one.
if
len
(
keys
)
==
1
&&
bytes
.
Equal
(
keys
[
0
],
firstKey
)
{
if
len
(
keys
)
==
1
&&
bytes
.
Equal
(
keys
[
0
],
firstKey
)
{
...
...
trie/proof_test.go
View file @
25b16085
...
@@ -571,6 +571,39 @@ func TestHasRightElement(t *testing.T) {
...
@@ -571,6 +571,39 @@ func TestHasRightElement(t *testing.T) {
}
}
}
}
// TestEmptyRangeProof tests the range proof with "no" element.
// The first edge proof must be a non-existent proof.
func
TestEmptyRangeProof
(
t
*
testing
.
T
)
{
trie
,
vals
:=
randomTrie
(
4096
)
var
entries
entrySlice
for
_
,
kv
:=
range
vals
{
entries
=
append
(
entries
,
kv
)
}
sort
.
Sort
(
entries
)
var
cases
=
[]
struct
{
pos
int
err
bool
}{
{
len
(
entries
)
-
1
,
false
},
{
500
,
true
},
}
for
_
,
c
:=
range
cases
{
firstProof
:=
memorydb
.
New
()
first
:=
increseKey
(
common
.
CopyBytes
(
entries
[
c
.
pos
]
.
k
))
if
err
:=
trie
.
Prove
(
first
,
0
,
firstProof
);
err
!=
nil
{
t
.
Fatalf
(
"Failed to prove the first node %v"
,
err
)
}
err
,
_
:=
VerifyRangeProof
(
trie
.
Hash
(),
first
,
nil
,
nil
,
firstProof
,
nil
)
if
c
.
err
&&
err
==
nil
{
t
.
Fatalf
(
"Expected error, got nil"
)
}
if
!
c
.
err
&&
err
!=
nil
{
t
.
Fatalf
(
"Expected no error, got %v"
,
err
)
}
}
}
// mutateByte changes one byte in b.
// mutateByte changes one byte in b.
func
mutateByte
(
b
[]
byte
)
{
func
mutateByte
(
b
[]
byte
)
{
for
r
:=
mrand
.
Intn
(
len
(
b
));
;
{
for
r
:=
mrand
.
Intn
(
len
(
b
));
;
{
...
...
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