-
Notifications
You must be signed in to change notification settings - Fork 0
/
create.go
94 lines (84 loc) · 2.37 KB
/
create.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
package iavlproofs
import (
"fmt"
ics23 "github.com/confio/ics23/go"
"github.com/cosmos/iavl"
)
// IavlSpec constrains the format from ics23-iavl (iavl merkle ics23)
var IavlSpec = &ics23.ProofSpec{
LeafSpec: &ics23.LeafOp{
Prefix: []byte{0},
Hash: ics23.HashOp_SHA256,
PrehashValue: ics23.HashOp_SHA256,
Length: ics23.LengthOp_VAR_PROTO,
},
InnerSpec: &ics23.InnerSpec{
ChildOrder: []int32{0, 1},
MinPrefixLength: 4,
MaxPrefixLength: 12,
ChildSize: 33, // (with length byte)
Hash: ics23.HashOp_SHA256,
},
}
/*
CreateMembershipProof will produce a CommitmentProof that the given key (and queries value) exists in the iavl tree.
If the key doesn't exist in the tree, this will return an error.
*/
func CreateMembershipProof(tree *iavl.MutableTree, key []byte) (*ics23.CommitmentProof, error) {
exist, err := createExistenceProof(tree, key)
if err != nil {
return nil, err
}
proof := &ics23.CommitmentProof{
Proof: &ics23.CommitmentProof_Exist{
Exist: exist,
},
}
return proof, nil
}
/*
CreateNonMembershipProof will produce a CommitmentProof that the given key doesn't exist in the iavl tree.
If the key exists in the tree, this will return an error.
*/
func CreateNonMembershipProof(tree *iavl.MutableTree, key []byte) (*ics23.CommitmentProof, error) {
// idx is one node right of what we want....
idx, val := tree.Get(key)
if val != nil {
return nil, fmt.Errorf("Cannot create NonExistanceProof when Key in State")
}
var err error
nonexist := &ics23.NonExistenceProof{
Key: key,
}
if idx >= 1 {
leftkey, _ := tree.GetByIndex(idx - 1)
nonexist.Left, err = createExistenceProof(tree, leftkey)
if err != nil {
return nil, err
}
}
// this will be nil if nothing right of the queried key
rightkey, _ := tree.GetByIndex(idx)
if rightkey != nil {
nonexist.Right, err = createExistenceProof(tree, rightkey)
if err != nil {
return nil, err
}
}
proof := &ics23.CommitmentProof{
Proof: &ics23.CommitmentProof_Nonexist{
Nonexist: nonexist,
},
}
return proof, nil
}
func createExistenceProof(tree *iavl.MutableTree, key []byte) (*ics23.ExistenceProof, error) {
value, proof, err := tree.GetWithProof(key)
if err != nil {
return nil, err
}
if value == nil {
return nil, fmt.Errorf("Cannot create ExistanceProof when Key not in State")
}
return convertExistenceProof(proof, key, value)
}