Merge pull request #290 from CosmWasm/check-iavl-range-bounds
Check iavl range bounds
This commit is contained in:
1
go.mod
1
go.mod
@@ -21,6 +21,7 @@ require (
|
||||
github.com/spf13/viper v1.6.3
|
||||
github.com/stretchr/testify v1.6.1
|
||||
github.com/tendermint/go-amino v0.15.1
|
||||
github.com/tendermint/iavl v0.14.0
|
||||
github.com/tendermint/tendermint v0.33.6
|
||||
github.com/tendermint/tm-db v0.5.1
|
||||
go.etcd.io/bbolt v1.3.4 // indirect
|
||||
|
||||
83
x/wasm/internal/types/iavl_range_test.go
Normal file
83
x/wasm/internal/types/iavl_range_test.go
Normal file
@@ -0,0 +1,83 @@
|
||||
package types
|
||||
|
||||
import (
|
||||
"github.com/cosmos/cosmos-sdk/store"
|
||||
"github.com/cosmos/cosmos-sdk/store/iavl"
|
||||
"github.com/stretchr/testify/require"
|
||||
iavl2 "github.com/tendermint/iavl"
|
||||
dbm "github.com/tendermint/tm-db"
|
||||
"testing"
|
||||
)
|
||||
|
||||
// This is modeled close to
|
||||
// https://github.com/CosmWasm/cosmwasm-plus/blob/f97a7de44b6a930fd1d5179ee6f95b786a532f32/packages/storage-plus/src/prefix.rs#L183
|
||||
// and designed to ensure the IAVL store handles bounds the same way as the mock storage we use in Rust contract tests
|
||||
func TestIavlRangeBounds(t *testing.T) {
|
||||
memdb := dbm.NewMemDB()
|
||||
tree, err := iavl2.NewMutableTree(memdb, 50)
|
||||
require.NoError(t, err)
|
||||
kvstore := iavl.UnsafeNewStore(tree)
|
||||
|
||||
// values to compare with
|
||||
expected := []KV{
|
||||
{[]byte("bar"), []byte("1")},
|
||||
{[]byte("ra"), []byte("2")},
|
||||
{[]byte("zi"), []byte("3")},
|
||||
}
|
||||
reversed := []KV{
|
||||
{[]byte("zi"), []byte("3")},
|
||||
{[]byte("ra"), []byte("2")},
|
||||
{[]byte("bar"), []byte("1")},
|
||||
}
|
||||
|
||||
// set up test cases, like `ensure_proper_range_bounds` in `cw-storage-plus`
|
||||
for _, kv := range expected {
|
||||
kvstore.Set(kv.Key, kv.Value)
|
||||
}
|
||||
|
||||
cases := map[string]struct {
|
||||
start []byte
|
||||
end []byte
|
||||
reverse bool
|
||||
expected []KV
|
||||
}{
|
||||
"all ascending": {nil, nil, false, expected},
|
||||
"ascending start inclusive": {[]byte("ra"), nil, false, expected[1:]},
|
||||
"ascending end exclusive": {nil, []byte("ra"), false, expected[:1]},
|
||||
"ascending both points": {[]byte("bar"), []byte("zi"), false, expected[:2]},
|
||||
|
||||
"all descending": {nil, nil, true, reversed},
|
||||
"descending start inclusive": {[]byte("ra"), nil, true, reversed[:2]}, // "zi", "ra"
|
||||
"descending end inclusive": {nil, []byte("ra"), true, reversed[2:]}, // "bar"
|
||||
"descending both points": {[]byte("bar"), []byte("zi"), true, reversed[1:]}, // "ra", "bar"
|
||||
}
|
||||
|
||||
for name, tc := range cases {
|
||||
t.Run(name, func(t *testing.T) {
|
||||
var iter store.Iterator
|
||||
if tc.reverse {
|
||||
iter = kvstore.ReverseIterator(tc.start, tc.end)
|
||||
} else {
|
||||
iter = kvstore.Iterator(tc.start, tc.end)
|
||||
}
|
||||
items := consume(iter)
|
||||
require.Equal(t, tc.expected, items)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
type KV struct {
|
||||
Key []byte
|
||||
Value []byte
|
||||
}
|
||||
|
||||
func consume(itr store.Iterator) []KV {
|
||||
defer itr.Close()
|
||||
|
||||
var res []KV
|
||||
for ; itr.Valid(); itr.Next() {
|
||||
k, v := itr.Key(), itr.Value()
|
||||
res = append(res, KV{k, v})
|
||||
}
|
||||
return res
|
||||
}
|
||||
Reference in New Issue
Block a user