github.com/Finschia/finschia-sdk@v0.48.1/store/iavl/store_test.go (about)

     1  package iavl
     2  
     3  import (
     4  	crand "crypto/rand"
     5  	"fmt"
     6  	"testing"
     7  
     8  	"github.com/cosmos/iavl"
     9  	"github.com/stretchr/testify/require"
    10  	dbm "github.com/tendermint/tm-db"
    11  
    12  	"github.com/Finschia/ostracon/libs/log"
    13  	abci "github.com/tendermint/tendermint/abci/types"
    14  
    15  	"github.com/Finschia/finschia-sdk/store/cachekv"
    16  	"github.com/Finschia/finschia-sdk/store/types"
    17  	"github.com/Finschia/finschia-sdk/types/kv"
    18  )
    19  
    20  var (
    21  	cacheSize = 100
    22  	treeData  = map[string]string{
    23  		"hello": "goodbye",
    24  		"aloha": "shalom",
    25  	}
    26  	nMoreData = 0
    27  )
    28  
    29  func randBytes(numBytes int) []byte {
    30  	b := make([]byte, numBytes)
    31  	_, _ = crand.Read(b)
    32  	return b
    33  }
    34  
    35  // make a tree with data from above and save it
    36  func newAlohaTree(t *testing.T, db dbm.DB) (*iavl.MutableTree, types.CommitID) {
    37  	tree, err := iavl.NewMutableTree(db, cacheSize, false)
    38  	require.NoError(t, err)
    39  
    40  	for k, v := range treeData {
    41  		tree.Set([]byte(k), []byte(v))
    42  	}
    43  
    44  	for i := 0; i < nMoreData; i++ {
    45  		key := randBytes(12)
    46  		value := randBytes(50)
    47  		tree.Set(key, value)
    48  	}
    49  
    50  	hash, ver, err := tree.SaveVersion()
    51  	require.Nil(t, err)
    52  
    53  	return tree, types.CommitID{Version: ver, Hash: hash}
    54  }
    55  
    56  func TestLoadStore(t *testing.T) {
    57  	db := dbm.NewMemDB()
    58  	tree, _ := newAlohaTree(t, db)
    59  	store := UnsafeNewStore(tree)
    60  
    61  	// Create non-pruned height H
    62  	updated, err := tree.Set([]byte("hello"), []byte("hallo"))
    63  	require.NoError(t, err)
    64  	require.True(t, updated)
    65  	hash, verH, err := tree.SaveVersion()
    66  	cIDH := types.CommitID{Version: verH, Hash: hash}
    67  	require.Nil(t, err)
    68  
    69  	// Create pruned height Hp
    70  	updated, err = tree.Set([]byte("hello"), []byte("hola"))
    71  	require.NoError(t, err)
    72  	require.True(t, updated)
    73  	hash, verHp, err := tree.SaveVersion()
    74  	cIDHp := types.CommitID{Version: verHp, Hash: hash}
    75  	require.Nil(t, err)
    76  
    77  	// TODO: Prune this height
    78  
    79  	// Create current height Hc
    80  	updated, err = tree.Set([]byte("hello"), []byte("ciao"))
    81  	require.NoError(t, err)
    82  	require.True(t, updated)
    83  	hash, verHc, err := tree.SaveVersion()
    84  	cIDHc := types.CommitID{Version: verHc, Hash: hash}
    85  	require.Nil(t, err)
    86  
    87  	// Querying an existing store at some previous non-pruned height H
    88  	hStore, err := store.GetImmutable(verH)
    89  	require.NoError(t, err)
    90  	require.Equal(t, string(hStore.Get([]byte("hello"))), "hallo")
    91  
    92  	// Querying an existing store at some previous pruned height Hp
    93  	hpStore, err := store.GetImmutable(verHp)
    94  	require.NoError(t, err)
    95  	require.Equal(t, string(hpStore.Get([]byte("hello"))), "hola")
    96  
    97  	// Querying an existing store at current height Hc
    98  	hcStore, err := store.GetImmutable(verHc)
    99  	require.NoError(t, err)
   100  	require.Equal(t, string(hcStore.Get([]byte("hello"))), "ciao")
   101  
   102  	// Querying a new store at some previous non-pruned height H
   103  	newHStore, err := LoadStore(db, log.NewNopLogger(), types.NewKVStoreKey("test"), cIDH, false, DefaultIAVLCacheSize, false)
   104  	require.NoError(t, err)
   105  	require.Equal(t, string(newHStore.Get([]byte("hello"))), "hallo")
   106  
   107  	// Querying a new store at some previous pruned height Hp
   108  	newHpStore, err := LoadStore(db, log.NewNopLogger(), types.NewKVStoreKey("test"), cIDHp, false, DefaultIAVLCacheSize, false)
   109  	require.NoError(t, err)
   110  	require.Equal(t, string(newHpStore.Get([]byte("hello"))), "hola")
   111  
   112  	// Querying a new store at current height H
   113  	newHcStore, err := LoadStore(db, log.NewNopLogger(), types.NewKVStoreKey("test"), cIDHc, false, DefaultIAVLCacheSize, false)
   114  	require.NoError(t, err)
   115  	require.Equal(t, string(newHcStore.Get([]byte("hello"))), "ciao")
   116  }
   117  
   118  func TestGetImmutable(t *testing.T) {
   119  	db := dbm.NewMemDB()
   120  	tree, cID := newAlohaTree(t, db)
   121  	store := UnsafeNewStore(tree)
   122  
   123  	updated, err := tree.Set([]byte("hello"), []byte("adios"))
   124  	require.True(t, updated)
   125  	hash, ver, err := tree.SaveVersion()
   126  	cID = types.CommitID{Version: ver, Hash: hash}
   127  	require.Nil(t, err)
   128  
   129  	_, err = store.GetImmutable(cID.Version + 1)
   130  	require.NoError(t, err)
   131  
   132  	newStore, err := store.GetImmutable(cID.Version - 1)
   133  	require.NoError(t, err)
   134  	require.Equal(t, newStore.Get([]byte("hello")), []byte("goodbye"))
   135  
   136  	newStore, err = store.GetImmutable(cID.Version)
   137  	require.NoError(t, err)
   138  	require.Equal(t, newStore.Get([]byte("hello")), []byte("adios"))
   139  
   140  	res := newStore.Query(abci.RequestQuery{Data: []byte("hello"), Height: cID.Version, Path: "/key", Prove: true})
   141  	require.Equal(t, res.Value, []byte("adios"))
   142  	require.NotNil(t, res.ProofOps)
   143  
   144  	require.Panics(t, func() { newStore.Set(nil, nil) })
   145  	require.Panics(t, func() { newStore.Delete(nil) })
   146  	require.Panics(t, func() { newStore.Commit() })
   147  }
   148  
   149  func TestTestGetImmutableIterator(t *testing.T) {
   150  	db := dbm.NewMemDB()
   151  	tree, cID := newAlohaTree(t, db)
   152  	store := UnsafeNewStore(tree)
   153  
   154  	newStore, err := store.GetImmutable(cID.Version)
   155  	require.NoError(t, err)
   156  
   157  	iter := newStore.Iterator([]byte("aloha"), []byte("hellz"))
   158  	expected := []string{"aloha", "hello"}
   159  	var i int
   160  
   161  	for i = 0; iter.Valid(); iter.Next() {
   162  		expectedKey := expected[i]
   163  		key, value := iter.Key(), iter.Value()
   164  		require.EqualValues(t, key, expectedKey)
   165  		require.EqualValues(t, value, treeData[expectedKey])
   166  		i++
   167  	}
   168  
   169  	require.Equal(t, len(expected), i)
   170  }
   171  
   172  func TestIAVLStoreGetSetHasDelete(t *testing.T) {
   173  	db := dbm.NewMemDB()
   174  	tree, _ := newAlohaTree(t, db)
   175  	iavlStore := UnsafeNewStore(tree)
   176  
   177  	key := "hello"
   178  
   179  	exists := iavlStore.Has([]byte(key))
   180  	require.True(t, exists)
   181  
   182  	value := iavlStore.Get([]byte(key))
   183  	require.EqualValues(t, value, treeData[key])
   184  
   185  	value2 := "notgoodbye"
   186  	iavlStore.Set([]byte(key), []byte(value2))
   187  
   188  	value = iavlStore.Get([]byte(key))
   189  	require.EqualValues(t, value, value2)
   190  
   191  	iavlStore.Delete([]byte(key))
   192  
   193  	exists = iavlStore.Has([]byte(key))
   194  	require.False(t, exists)
   195  }
   196  
   197  func TestIAVLStoreNoNilSet(t *testing.T) {
   198  	db := dbm.NewMemDB()
   199  	tree, _ := newAlohaTree(t, db)
   200  	iavlStore := UnsafeNewStore(tree)
   201  
   202  	require.Panics(t, func() { iavlStore.Set(nil, []byte("value")) }, "setting a nil key should panic")
   203  	require.Panics(t, func() { iavlStore.Set([]byte(""), []byte("value")) }, "setting an empty key should panic")
   204  
   205  	require.Panics(t, func() { iavlStore.Set([]byte("key"), nil) }, "setting a nil value should panic")
   206  }
   207  
   208  func TestIAVLIterator(t *testing.T) {
   209  	db := dbm.NewMemDB()
   210  	tree, _ := newAlohaTree(t, db)
   211  	iavlStore := UnsafeNewStore(tree)
   212  	iter := iavlStore.Iterator([]byte("aloha"), []byte("hellz"))
   213  	expected := []string{"aloha", "hello"}
   214  	var i int
   215  
   216  	for i = 0; iter.Valid(); iter.Next() {
   217  		expectedKey := expected[i]
   218  		key, value := iter.Key(), iter.Value()
   219  		require.EqualValues(t, key, expectedKey)
   220  		require.EqualValues(t, value, treeData[expectedKey])
   221  		i++
   222  	}
   223  	require.Equal(t, len(expected), i)
   224  
   225  	iter = iavlStore.Iterator([]byte("golang"), []byte("rocks"))
   226  	expected = []string{"hello"}
   227  	for i = 0; iter.Valid(); iter.Next() {
   228  		expectedKey := expected[i]
   229  		key, value := iter.Key(), iter.Value()
   230  		require.EqualValues(t, key, expectedKey)
   231  		require.EqualValues(t, value, treeData[expectedKey])
   232  		i++
   233  	}
   234  	require.Equal(t, len(expected), i)
   235  
   236  	iter = iavlStore.Iterator(nil, []byte("golang"))
   237  	expected = []string{"aloha"}
   238  	for i = 0; iter.Valid(); iter.Next() {
   239  		expectedKey := expected[i]
   240  		key, value := iter.Key(), iter.Value()
   241  		require.EqualValues(t, key, expectedKey)
   242  		require.EqualValues(t, value, treeData[expectedKey])
   243  		i++
   244  	}
   245  	require.Equal(t, len(expected), i)
   246  
   247  	iter = iavlStore.Iterator(nil, []byte("shalom"))
   248  	expected = []string{"aloha", "hello"}
   249  	for i = 0; iter.Valid(); iter.Next() {
   250  		expectedKey := expected[i]
   251  		key, value := iter.Key(), iter.Value()
   252  		require.EqualValues(t, key, expectedKey)
   253  		require.EqualValues(t, value, treeData[expectedKey])
   254  		i++
   255  	}
   256  	require.Equal(t, len(expected), i)
   257  
   258  	iter = iavlStore.Iterator(nil, nil)
   259  	expected = []string{"aloha", "hello"}
   260  	for i = 0; iter.Valid(); iter.Next() {
   261  		expectedKey := expected[i]
   262  		key, value := iter.Key(), iter.Value()
   263  		require.EqualValues(t, key, expectedKey)
   264  		require.EqualValues(t, value, treeData[expectedKey])
   265  		i++
   266  	}
   267  	require.Equal(t, len(expected), i)
   268  
   269  	iter = iavlStore.Iterator([]byte("golang"), nil)
   270  	expected = []string{"hello"}
   271  	for i = 0; iter.Valid(); iter.Next() {
   272  		expectedKey := expected[i]
   273  		key, value := iter.Key(), iter.Value()
   274  		require.EqualValues(t, key, expectedKey)
   275  		require.EqualValues(t, value, treeData[expectedKey])
   276  		i++
   277  	}
   278  	require.Equal(t, len(expected), i)
   279  }
   280  
   281  func TestIAVLReverseIterator(t *testing.T) {
   282  	db := dbm.NewMemDB()
   283  
   284  	tree, err := iavl.NewMutableTree(db, cacheSize, false)
   285  	require.NoError(t, err)
   286  
   287  	iavlStore := UnsafeNewStore(tree)
   288  
   289  	iavlStore.Set([]byte{0x00}, []byte("0"))
   290  	iavlStore.Set([]byte{0x00, 0x00}, []byte("0 0"))
   291  	iavlStore.Set([]byte{0x00, 0x01}, []byte("0 1"))
   292  	iavlStore.Set([]byte{0x00, 0x02}, []byte("0 2"))
   293  	iavlStore.Set([]byte{0x01}, []byte("1"))
   294  
   295  	testReverseIterator := func(t *testing.T, start []byte, end []byte, expected []string) {
   296  		iter := iavlStore.ReverseIterator(start, end)
   297  		var i int
   298  		for i = 0; iter.Valid(); iter.Next() {
   299  			expectedValue := expected[i]
   300  			value := iter.Value()
   301  			require.EqualValues(t, string(value), expectedValue)
   302  			i++
   303  		}
   304  		require.Equal(t, len(expected), i)
   305  	}
   306  
   307  	testReverseIterator(t, nil, nil, []string{"1", "0 2", "0 1", "0 0", "0"})
   308  	testReverseIterator(t, []byte{0x00}, nil, []string{"1", "0 2", "0 1", "0 0", "0"})
   309  	testReverseIterator(t, []byte{0x00}, []byte{0x00, 0x01}, []string{"0 0", "0"})
   310  	testReverseIterator(t, []byte{0x00}, []byte{0x01}, []string{"0 2", "0 1", "0 0", "0"})
   311  	testReverseIterator(t, []byte{0x00, 0x01}, []byte{0x01}, []string{"0 2", "0 1"})
   312  	testReverseIterator(t, nil, []byte{0x01}, []string{"0 2", "0 1", "0 0", "0"})
   313  }
   314  
   315  func TestIAVLPrefixIterator(t *testing.T) {
   316  	db := dbm.NewMemDB()
   317  	tree, err := iavl.NewMutableTree(db, cacheSize, false)
   318  	require.NoError(t, err)
   319  
   320  	iavlStore := UnsafeNewStore(tree)
   321  
   322  	iavlStore.Set([]byte("test1"), []byte("test1"))
   323  	iavlStore.Set([]byte("test2"), []byte("test2"))
   324  	iavlStore.Set([]byte("test3"), []byte("test3"))
   325  	iavlStore.Set([]byte{byte(55), byte(255), byte(255), byte(0)}, []byte("test4"))
   326  	iavlStore.Set([]byte{byte(55), byte(255), byte(255), byte(1)}, []byte("test4"))
   327  	iavlStore.Set([]byte{byte(55), byte(255), byte(255), byte(255)}, []byte("test4"))
   328  	iavlStore.Set([]byte{byte(255), byte(255), byte(0)}, []byte("test4"))
   329  	iavlStore.Set([]byte{byte(255), byte(255), byte(1)}, []byte("test4"))
   330  	iavlStore.Set([]byte{byte(255), byte(255), byte(255)}, []byte("test4"))
   331  
   332  	var i int
   333  
   334  	iter := types.KVStorePrefixIterator(iavlStore, []byte("test"))
   335  	expected := []string{"test1", "test2", "test3"}
   336  	for i = 0; iter.Valid(); iter.Next() {
   337  		expectedKey := expected[i]
   338  		key, value := iter.Key(), iter.Value()
   339  		require.EqualValues(t, key, expectedKey)
   340  		require.EqualValues(t, value, expectedKey)
   341  		i++
   342  	}
   343  	iter.Close()
   344  	require.Equal(t, len(expected), i)
   345  
   346  	iter = types.KVStorePrefixIterator(iavlStore, []byte{byte(55), byte(255), byte(255)})
   347  	expected2 := [][]byte{
   348  		{byte(55), byte(255), byte(255), byte(0)},
   349  		{byte(55), byte(255), byte(255), byte(1)},
   350  		{byte(55), byte(255), byte(255), byte(255)},
   351  	}
   352  	for i = 0; iter.Valid(); iter.Next() {
   353  		expectedKey := expected2[i]
   354  		key, value := iter.Key(), iter.Value()
   355  		require.EqualValues(t, key, expectedKey)
   356  		require.EqualValues(t, value, []byte("test4"))
   357  		i++
   358  	}
   359  	iter.Close()
   360  	require.Equal(t, len(expected), i)
   361  
   362  	iter = types.KVStorePrefixIterator(iavlStore, []byte{byte(255), byte(255)})
   363  	expected2 = [][]byte{
   364  		{byte(255), byte(255), byte(0)},
   365  		{byte(255), byte(255), byte(1)},
   366  		{byte(255), byte(255), byte(255)},
   367  	}
   368  	for i = 0; iter.Valid(); iter.Next() {
   369  		expectedKey := expected2[i]
   370  		key, value := iter.Key(), iter.Value()
   371  		require.EqualValues(t, key, expectedKey)
   372  		require.EqualValues(t, value, []byte("test4"))
   373  		i++
   374  	}
   375  	iter.Close()
   376  	require.Equal(t, len(expected), i)
   377  }
   378  
   379  func TestIAVLReversePrefixIterator(t *testing.T) {
   380  	db := dbm.NewMemDB()
   381  	tree, err := iavl.NewMutableTree(db, cacheSize, false)
   382  	require.NoError(t, err)
   383  
   384  	iavlStore := UnsafeNewStore(tree)
   385  
   386  	iavlStore.Set([]byte("test1"), []byte("test1"))
   387  	iavlStore.Set([]byte("test2"), []byte("test2"))
   388  	iavlStore.Set([]byte("test3"), []byte("test3"))
   389  	iavlStore.Set([]byte{byte(55), byte(255), byte(255), byte(0)}, []byte("test4"))
   390  	iavlStore.Set([]byte{byte(55), byte(255), byte(255), byte(1)}, []byte("test4"))
   391  	iavlStore.Set([]byte{byte(55), byte(255), byte(255), byte(255)}, []byte("test4"))
   392  	iavlStore.Set([]byte{byte(255), byte(255), byte(0)}, []byte("test4"))
   393  	iavlStore.Set([]byte{byte(255), byte(255), byte(1)}, []byte("test4"))
   394  	iavlStore.Set([]byte{byte(255), byte(255), byte(255)}, []byte("test4"))
   395  
   396  	var i int
   397  
   398  	iter := types.KVStoreReversePrefixIterator(iavlStore, []byte("test"))
   399  	expected := []string{"test3", "test2", "test1"}
   400  	for i = 0; iter.Valid(); iter.Next() {
   401  		expectedKey := expected[i]
   402  		key, value := iter.Key(), iter.Value()
   403  		require.EqualValues(t, key, expectedKey)
   404  		require.EqualValues(t, value, expectedKey)
   405  		i++
   406  	}
   407  	require.Equal(t, len(expected), i)
   408  
   409  	iter = types.KVStoreReversePrefixIterator(iavlStore, []byte{byte(55), byte(255), byte(255)})
   410  	expected2 := [][]byte{
   411  		{byte(55), byte(255), byte(255), byte(255)},
   412  		{byte(55), byte(255), byte(255), byte(1)},
   413  		{byte(55), byte(255), byte(255), byte(0)},
   414  	}
   415  	for i = 0; iter.Valid(); iter.Next() {
   416  		expectedKey := expected2[i]
   417  		key, value := iter.Key(), iter.Value()
   418  		require.EqualValues(t, key, expectedKey)
   419  		require.EqualValues(t, value, []byte("test4"))
   420  		i++
   421  	}
   422  	require.Equal(t, len(expected), i)
   423  
   424  	iter = types.KVStoreReversePrefixIterator(iavlStore, []byte{byte(255), byte(255)})
   425  	expected2 = [][]byte{
   426  		{byte(255), byte(255), byte(255)},
   427  		{byte(255), byte(255), byte(1)},
   428  		{byte(255), byte(255), byte(0)},
   429  	}
   430  	for i = 0; iter.Valid(); iter.Next() {
   431  		expectedKey := expected2[i]
   432  		key, value := iter.Key(), iter.Value()
   433  		require.EqualValues(t, key, expectedKey)
   434  		require.EqualValues(t, value, []byte("test4"))
   435  		i++
   436  	}
   437  	require.Equal(t, len(expected), i)
   438  }
   439  
   440  func nextVersion(iavl *Store) {
   441  	key := []byte(fmt.Sprintf("Key for tree: %d", iavl.LastCommitID().Version))
   442  	value := []byte(fmt.Sprintf("Value for tree: %d", iavl.LastCommitID().Version))
   443  	iavl.Set(key, value)
   444  	iavl.Commit()
   445  }
   446  
   447  func TestIAVLNoPrune(t *testing.T) {
   448  	db := dbm.NewMemDB()
   449  	tree, err := iavl.NewMutableTree(db, cacheSize, false)
   450  	require.NoError(t, err)
   451  
   452  	iavlStore := UnsafeNewStore(tree)
   453  	nextVersion(iavlStore)
   454  
   455  	for i := 1; i < 100; i++ {
   456  		for j := 1; j <= i; j++ {
   457  			require.True(t, iavlStore.VersionExists(int64(j)),
   458  				"Missing version %d with latest version %d. Should be storing all versions",
   459  				j, i)
   460  		}
   461  
   462  		nextVersion(iavlStore)
   463  	}
   464  }
   465  
   466  func TestIAVLGetAllVersions(t *testing.T) {
   467  	db := dbm.NewMemDB()
   468  	tree, err := iavl.NewMutableTree(db, cacheSize, false)
   469  	require.NoError(t, err)
   470  
   471  	iavlStore := UnsafeNewStore(tree)
   472  	nextVersion(iavlStore)
   473  
   474  	for i := 1; i < 100; i++ {
   475  		for _, ver := range iavlStore.GetAllVersions() {
   476  			require.True(t, iavlStore.VersionExists(int64(ver)),
   477  				"Missing version %d with latest version %d. Should be storing all versions",
   478  				ver, i)
   479  
   480  		}
   481  
   482  		nextVersion(iavlStore)
   483  	}
   484  }
   485  
   486  func TestIAVLStoreQuery(t *testing.T) {
   487  	db := dbm.NewMemDB()
   488  	tree, err := iavl.NewMutableTree(db, cacheSize, false)
   489  	require.NoError(t, err)
   490  
   491  	iavlStore := UnsafeNewStore(tree)
   492  
   493  	k1, v1 := []byte("key1"), []byte("val1")
   494  	k2, v2 := []byte("key2"), []byte("val2")
   495  	v3 := []byte("val3")
   496  
   497  	ksub := []byte("key")
   498  	KVs0 := kv.Pairs{}
   499  	KVs1 := kv.Pairs{
   500  		Pairs: []kv.Pair{
   501  			{Key: k1, Value: v1},
   502  			{Key: k2, Value: v2},
   503  		},
   504  	}
   505  	KVs2 := kv.Pairs{
   506  		Pairs: []kv.Pair{
   507  			{Key: k1, Value: v3},
   508  			{Key: k2, Value: v2},
   509  		},
   510  	}
   511  
   512  	valExpSubEmpty, err := KVs0.Marshal()
   513  	require.NoError(t, err)
   514  
   515  	valExpSub1, err := KVs1.Marshal()
   516  	require.NoError(t, err)
   517  
   518  	valExpSub2, err := KVs2.Marshal()
   519  	require.NoError(t, err)
   520  
   521  	cid := iavlStore.Commit()
   522  	ver := cid.Version
   523  	query := abci.RequestQuery{Path: "/key", Data: k1, Height: ver}
   524  	querySub := abci.RequestQuery{Path: "/subspace", Data: ksub, Height: ver}
   525  
   526  	// query subspace before anything set
   527  	qres := iavlStore.Query(querySub)
   528  	require.Equal(t, uint32(0), qres.Code)
   529  	require.Equal(t, valExpSubEmpty, qres.Value)
   530  
   531  	// set data
   532  	iavlStore.Set(k1, v1)
   533  	iavlStore.Set(k2, v2)
   534  
   535  	// set data without commit, doesn't show up
   536  	qres = iavlStore.Query(query)
   537  	require.Equal(t, uint32(0), qres.Code)
   538  	require.Nil(t, qres.Value)
   539  
   540  	// commit it, but still don't see on old version
   541  	cid = iavlStore.Commit()
   542  	qres = iavlStore.Query(query)
   543  	require.Equal(t, uint32(0), qres.Code)
   544  	require.Nil(t, qres.Value)
   545  
   546  	// but yes on the new version
   547  	query.Height = cid.Version
   548  	qres = iavlStore.Query(query)
   549  	require.Equal(t, uint32(0), qres.Code)
   550  	require.Equal(t, v1, qres.Value)
   551  
   552  	// and for the subspace
   553  	qres = iavlStore.Query(querySub)
   554  	require.Equal(t, uint32(0), qres.Code)
   555  	require.Equal(t, valExpSub1, qres.Value)
   556  
   557  	// modify
   558  	iavlStore.Set(k1, v3)
   559  	cid = iavlStore.Commit()
   560  
   561  	// query will return old values, as height is fixed
   562  	qres = iavlStore.Query(query)
   563  	require.Equal(t, uint32(0), qres.Code)
   564  	require.Equal(t, v1, qres.Value)
   565  
   566  	// update to latest in the query and we are happy
   567  	query.Height = cid.Version
   568  	qres = iavlStore.Query(query)
   569  	require.Equal(t, uint32(0), qres.Code)
   570  	require.Equal(t, v3, qres.Value)
   571  	query2 := abci.RequestQuery{Path: "/key", Data: k2, Height: cid.Version}
   572  
   573  	qres = iavlStore.Query(query2)
   574  	require.Equal(t, uint32(0), qres.Code)
   575  	require.Equal(t, v2, qres.Value)
   576  	// and for the subspace
   577  	qres = iavlStore.Query(querySub)
   578  	require.Equal(t, uint32(0), qres.Code)
   579  	require.Equal(t, valExpSub2, qres.Value)
   580  
   581  	// default (height 0) will show latest -1
   582  	query0 := abci.RequestQuery{Path: "/key", Data: k1}
   583  	qres = iavlStore.Query(query0)
   584  	require.Equal(t, uint32(0), qres.Code)
   585  	require.Equal(t, v1, qres.Value)
   586  }
   587  
   588  func BenchmarkIAVLIteratorNext(b *testing.B) {
   589  	b.ReportAllocs()
   590  	db := dbm.NewMemDB()
   591  	treeSize := 1000
   592  	tree, err := iavl.NewMutableTree(db, cacheSize, false)
   593  	require.NoError(b, err)
   594  
   595  	for i := 0; i < treeSize; i++ {
   596  		key := randBytes(4)
   597  		value := randBytes(50)
   598  		tree.Set(key, value)
   599  	}
   600  
   601  	iavlStore := UnsafeNewStore(tree)
   602  	iterators := make([]types.Iterator, b.N/treeSize)
   603  
   604  	for i := 0; i < len(iterators); i++ {
   605  		iterators[i] = iavlStore.Iterator([]byte{0}, []byte{255, 255, 255, 255, 255})
   606  	}
   607  
   608  	b.ResetTimer()
   609  	for i := 0; i < len(iterators); i++ {
   610  		iter := iterators[i]
   611  		for j := 0; j < treeSize; j++ {
   612  			iter.Next()
   613  		}
   614  	}
   615  }
   616  
   617  func TestSetInitialVersion(t *testing.T) {
   618  	testCases := []struct {
   619  		name     string
   620  		storeFn  func(db *dbm.MemDB) *Store
   621  		expPanic bool
   622  	}{
   623  		{
   624  			"works with a mutable tree",
   625  			func(db *dbm.MemDB) *Store {
   626  				tree, err := iavl.NewMutableTree(db, cacheSize, false)
   627  				require.NoError(t, err)
   628  				store := UnsafeNewStore(tree)
   629  
   630  				return store
   631  			}, false,
   632  		},
   633  		{
   634  			"throws error on immutable tree",
   635  			func(db *dbm.MemDB) *Store {
   636  				tree, err := iavl.NewMutableTree(db, cacheSize, false)
   637  				require.NoError(t, err)
   638  				store := UnsafeNewStore(tree)
   639  				_, version, err := store.tree.SaveVersion()
   640  				require.NoError(t, err)
   641  				require.Equal(t, int64(1), version)
   642  				store, err = store.GetImmutable(1)
   643  				require.NoError(t, err)
   644  
   645  				return store
   646  			}, true,
   647  		},
   648  	}
   649  
   650  	for _, tc := range testCases {
   651  		tc := tc
   652  
   653  		t.Run(tc.name, func(t *testing.T) {
   654  			db := dbm.NewMemDB()
   655  			store := tc.storeFn(db)
   656  
   657  			if tc.expPanic {
   658  				require.Panics(t, func() { store.SetInitialVersion(5) })
   659  			} else {
   660  				store.SetInitialVersion(5)
   661  				cid := store.Commit()
   662  				require.Equal(t, int64(5), cid.GetVersion())
   663  			}
   664  		})
   665  	}
   666  }
   667  
   668  func TestCacheWraps(t *testing.T) {
   669  	db := dbm.NewMemDB()
   670  	tree, _ := newAlohaTree(t, db)
   671  	store := UnsafeNewStore(tree)
   672  
   673  	cacheWrapper := store.CacheWrap()
   674  	require.IsType(t, &cachekv.Store{}, cacheWrapper)
   675  
   676  	cacheWrappedWithTrace := store.CacheWrapWithTrace(nil, nil)
   677  	require.IsType(t, &cachekv.Store{}, cacheWrappedWithTrace)
   678  
   679  	cacheWrappedWithListeners := store.CacheWrapWithListeners(nil, nil)
   680  	require.IsType(t, &cachekv.Store{}, cacheWrappedWithListeners)
   681  }