Skip to content

Commit c1883c0

Browse files
committed
Merge branch 'master' of github.com:cosmos/ics23 into carlos/return-error-getPosition
2 parents 0016a6b + 315aa71 commit c1883c0

16 files changed

+129
-1066
lines changed

README.md

+2
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,8 @@ Anyone interested in adding support for Solidity could pick up where [#58](https
7070
* [cometbft/crypto/merkle](https://github.com/cometbft/cometbft/tree/main/crypto/merkle)
7171
* [penumbra-zone/jmt](https://github.com/penumbra-zone/jmt)
7272

73+
Supported merkle stores must be lexicographically ordered to maintain soundness.
74+
7375
### Unsupported
7476

7577
* [turbofish-org/merk](https://github.com/turbofish-org/merk)

go/CHANGELOG.md

+3
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,9 @@
55
- deps: bump golang to v1.22 ([#363](https://github.com/cosmos/ics23/pull/363)).
66
- fix: guarantee that `spec.InnerSpec.MaxPrefixLength` < `spec.InnerSpec.MinPrefixLength` + `spec.InnerSpec.ChildSize` ([#369](https://github.com/cosmos/ics23/pull/369))
77
- fix: return error instead of panic in `getPosition` which results in error returns from `IsLeftMost`, `IsRightMost`, `IsLeftNeighbor`, `leftBranchesAreEmpty`, `rightBranchesAreEmpty`, and `getPadding`
8+
- refactor: support for `BatchProof` and `CompressedBatchProof` is being dropped.
9+
* The API's `BatchVerifyMembership`, `BatchVerifyNonMembership`, and `CombineProofs` have been removed. ([#390](https://github.com/cosmos/ics23/pull/390))
10+
* The API's `IsCompressed`, `Compress`, and `Decompress` have been removed. ([#392](https://github.com/cosmos/ics23/pull/392))
811

912
# v0.11.0
1013

go/compress.go

-159
This file was deleted.

go/fuzz_test.go

-34
Original file line numberDiff line numberDiff line change
@@ -172,37 +172,3 @@ func FuzzVerifyMembership(f *testing.F) {
172172
_ = VerifyMembership(spec, ref.RootHash, proof, ref.Key, ref.Value)
173173
})
174174
}
175-
176-
func FuzzCombineProofs(f *testing.F) {
177-
// 1. Load in the CommitmentProofs
178-
baseDirs := []string{"iavl", "tendermint", "smt"}
179-
filenames := []string{
180-
"exist_left.json",
181-
"exist_right.json",
182-
"exist_middle.json",
183-
"nonexist_left.json",
184-
"nonexist_right.json",
185-
"nonexist_middle.json",
186-
}
187-
188-
for _, baseDir := range baseDirs {
189-
dir := filepath.Join("..", "testdata", baseDir)
190-
for _, filename := range filenames {
191-
proofs, _ := LoadFile(new(testing.T), dir, filename)
192-
blob, err := json.Marshal(proofs)
193-
if err != nil {
194-
f.Fatal(err)
195-
}
196-
f.Add(blob)
197-
}
198-
}
199-
200-
// 2. Now let's run the fuzzer.
201-
f.Fuzz(func(t *testing.T, proofsJSON []byte) {
202-
var proofs []*CommitmentProof
203-
if err := json.Unmarshal(proofsJSON, &proofs); err != nil {
204-
return
205-
}
206-
_, _ = CombineProofs(proofs)
207-
})
208-
}

go/ics23.go

+14-132
Original file line numberDiff line numberDiff line change
@@ -23,26 +23,23 @@ and determine neighbors
2323
*/
2424
package ics23
2525

26-
import (
27-
"bytes"
28-
"fmt"
29-
)
30-
3126
// CommitmentRoot is a byte slice that represents the merkle root of a tree that can be used to validate proofs
3227
type CommitmentRoot []byte
3328

3429
// VerifyMembership returns true iff
35-
// proof is (contains) an ExistenceProof for the given key and value AND
36-
// calculating the root for the ExistenceProof matches the provided CommitmentRoot
30+
// proof is an ExistenceProof for the given key and value AND
31+
// calculating the root for the ExistenceProof matches the provided CommitmentRoot.
3732
func VerifyMembership(spec *ProofSpec, root CommitmentRoot, proof *CommitmentProof, key []byte, value []byte) bool {
38-
// decompress it before running code (no-op if not compressed)
39-
proof = Decompress(proof)
40-
ep := getExistProofForKey(proof, key)
33+
if proof == nil {
34+
return false
35+
}
36+
37+
ep := proof.GetExist()
4138
if ep == nil {
4239
return false
4340
}
44-
err := ep.Verify(spec, root, key, value)
45-
return err == nil
41+
42+
return ep.Verify(spec, root, key, value) == nil
4643
}
4744

4845
// VerifyNonMembership returns true iff
@@ -51,129 +48,14 @@ func VerifyMembership(spec *ProofSpec, root CommitmentRoot, proof *CommitmentPro
5148
// left and right proofs are neighbors (or left/right most if one is nil)
5249
// provided key is between the keys of the two proofs
5350
func VerifyNonMembership(spec *ProofSpec, root CommitmentRoot, proof *CommitmentProof, key []byte) bool {
54-
// decompress it before running code (no-op if not compressed)
55-
proof = Decompress(proof)
56-
np := getNonExistProofForKey(spec, proof, key)
57-
if np == nil {
58-
return false
59-
}
60-
err := np.Verify(spec, root, key)
61-
return err == nil
62-
}
63-
64-
// BatchVerifyMembership will ensure all items are also proven by the CommitmentProof (which should be a BatchProof,
65-
// unless there is one item, when a ExistenceProof may work)
66-
func BatchVerifyMembership(spec *ProofSpec, root CommitmentRoot, proof *CommitmentProof, items map[string][]byte) bool {
67-
// decompress it before running code (no-op if not compressed) - once for batch
68-
proof = Decompress(proof)
69-
for k, v := range items {
70-
valid := VerifyMembership(spec, root, proof, []byte(k), v)
71-
if !valid {
72-
return false
73-
}
74-
}
75-
return true
76-
}
77-
78-
// BatchVerifyNonMembership will ensure all items are also proven to not be in the Commitment by the CommitmentProof
79-
// (which should be a BatchProof, unless there is one item, when a NonExistenceProof may work)
80-
func BatchVerifyNonMembership(spec *ProofSpec, root CommitmentRoot, proof *CommitmentProof, keys [][]byte) bool {
81-
// decompress it before running code (no-op if not compressed) - once for batch
82-
proof = Decompress(proof)
83-
for _, k := range keys {
84-
valid := VerifyNonMembership(spec, root, proof, k)
85-
if !valid {
86-
return false
87-
}
88-
}
89-
return true
90-
}
91-
92-
// CombineProofs takes a number of commitment proofs (simple or batch) and
93-
// converts them into a batch and compresses them.
94-
//
95-
// This is designed for proof generation libraries to create efficient batches
96-
func CombineProofs(proofs []*CommitmentProof) (*CommitmentProof, error) {
97-
var entries []*BatchEntry
98-
99-
for _, proof := range proofs {
100-
if ex := proof.GetExist(); ex != nil {
101-
entry := &BatchEntry{
102-
Proof: &BatchEntry_Exist{
103-
Exist: ex,
104-
},
105-
}
106-
entries = append(entries, entry)
107-
} else if non := proof.GetNonexist(); non != nil {
108-
entry := &BatchEntry{
109-
Proof: &BatchEntry_Nonexist{
110-
Nonexist: non,
111-
},
112-
}
113-
entries = append(entries, entry)
114-
} else if batch := proof.GetBatch(); batch != nil {
115-
entries = append(entries, batch.Entries...)
116-
} else if comp := proof.GetCompressed(); comp != nil {
117-
decomp := Decompress(proof)
118-
entries = append(entries, decomp.GetBatch().Entries...)
119-
} else {
120-
return nil, fmt.Errorf("proof neither exist or nonexist: %#v", proof.GetProof())
121-
}
122-
}
123-
124-
batch := &CommitmentProof{
125-
Proof: &CommitmentProof_Batch{
126-
Batch: &BatchProof{
127-
Entries: entries,
128-
},
129-
},
130-
}
131-
132-
return Compress(batch), nil
133-
}
134-
135-
func getExistProofForKey(proof *CommitmentProof, key []byte) *ExistenceProof {
13651
if proof == nil {
137-
return nil
138-
}
139-
140-
switch p := proof.Proof.(type) {
141-
case *CommitmentProof_Exist:
142-
ep := p.Exist
143-
if bytes.Equal(ep.Key, key) {
144-
return ep
145-
}
146-
case *CommitmentProof_Batch:
147-
for _, sub := range p.Batch.Entries {
148-
if ep := sub.GetExist(); ep != nil && bytes.Equal(ep.Key, key) {
149-
return ep
150-
}
151-
}
52+
return false
15253
}
153-
return nil
154-
}
15554

156-
func getNonExistProofForKey(spec *ProofSpec, proof *CommitmentProof, key []byte) *NonExistenceProof {
157-
switch p := proof.Proof.(type) {
158-
case *CommitmentProof_Nonexist:
159-
np := p.Nonexist
160-
if isLeft(spec, np.Left, key) && isRight(spec, np.Right, key) {
161-
return np
162-
}
163-
case *CommitmentProof_Batch:
164-
for _, sub := range p.Batch.Entries {
165-
if np := sub.GetNonexist(); np != nil && isLeft(spec, np.Left, key) && isRight(spec, np.Right, key) {
166-
return np
167-
}
168-
}
55+
np := proof.GetNonexist()
56+
if np == nil {
57+
return false
16958
}
170-
return nil
171-
}
172-
173-
func isLeft(spec *ProofSpec, left *ExistenceProof, key []byte) bool {
174-
return left == nil || bytes.Compare(keyForComparison(spec, left.Key), keyForComparison(spec, key)) < 0
175-
}
17659

177-
func isRight(spec *ProofSpec, right *ExistenceProof, key []byte) bool {
178-
return right == nil || bytes.Compare(keyForComparison(spec, right.Key), keyForComparison(spec, key)) > 0
60+
return np.Verify(spec, root, key) == nil
17961
}

0 commit comments

Comments
 (0)