github.com/fibonacci-chain/fbc@v0.0.0-20231124064014-c7636198c1e9/libs/cosmos-sdk/store/iavl/store_test.go (about)

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