forked from cosmos/iavl
-
Notifications
You must be signed in to change notification settings - Fork 3
/
proof_test.go
128 lines (105 loc) · 2.72 KB
/
proof_test.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
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
// nolint: errcheck
package iavl
import (
"bytes"
"sort"
"testing"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
iavlrand "github.com/cosmos/iavl/internal/rand"
)
func TestTreeGetProof(t *testing.T) {
require := require.New(t)
tree := getTestTree(0)
for _, ikey := range []byte{0x11, 0x32, 0x50, 0x72, 0x99} {
key := []byte{ikey}
tree.Set(key, []byte(iavlrand.RandStr(8)))
}
key := []byte{0x32}
proof, err := tree.GetMembershipProof(key)
require.NoError(err)
require.NotNil(proof)
res, err := tree.VerifyMembership(proof, key)
require.NoError(err, "%+v", err)
require.True(res)
key = []byte{0x1}
proof, err = tree.GetNonMembershipProof(key)
require.NoError(err)
require.NotNil(proof)
res, err = tree.VerifyNonMembership(proof, key)
require.NoError(err, "%+v", err)
require.True(res)
}
func TestTreeKeyExistsProof(t *testing.T) {
tree := getTestTree(0)
// should get error
_, err := tree.GetProof([]byte("foo"))
assert.Error(t, err)
// insert lots of info and store the bytes
allkeys := make([][]byte, 200)
for i := 0; i < 200; i++ {
key := iavlrand.RandStr(20)
value := "value_for_" + key
tree.Set([]byte(key), []byte(value))
allkeys[i] = []byte(key)
}
sortByteSlices(allkeys) // Sort all keys
// query random key fails
_, err = tree.GetMembershipProof([]byte("foo"))
require.Error(t, err)
// valid proof for real keys
for _, key := range allkeys {
proof, err := tree.GetMembershipProof(key)
require.NoError(t, err)
require.Equal(t,
append([]byte("value_for_"), key...),
proof.GetExist().Value,
)
res, err := tree.VerifyMembership(proof, key)
require.NoError(t, err)
require.True(t, res)
}
}
//----------------------------------------
// Contract: !bytes.Equal(input, output) && len(input) >= len(output)
func MutateByteSlice(bytez []byte) []byte {
// If bytez is empty, panic
if len(bytez) == 0 {
panic("Cannot mutate an empty bytez")
}
// Copy bytez
mBytez := make([]byte, len(bytez))
copy(mBytez, bytez)
bytez = mBytez
// Try a random mutation
switch iavlrand.RandInt() % 2 {
case 0: // Mutate a single byte
bytez[iavlrand.RandInt()%len(bytez)] += byte(iavlrand.RandInt()%255 + 1)
case 1: // Remove an arbitrary byte
pos := iavlrand.RandInt() % len(bytez)
bytez = append(bytez[:pos], bytez[pos+1:]...)
}
return bytez
}
func sortByteSlices(src [][]byte) [][]byte {
bzz := byteslices(src)
sort.Sort(bzz)
return bzz
}
type byteslices [][]byte
func (bz byteslices) Len() int {
return len(bz)
}
func (bz byteslices) Less(i, j int) bool {
switch bytes.Compare(bz[i], bz[j]) {
case -1:
return true
case 0, 1:
return false
default:
panic("should not happen")
}
}
func (bz byteslices) Swap(i, j int) {
bz[j], bz[i] = bz[i], bz[j]
}