github.com/gnolang/gno@v0.0.0-20240520182011-228e9d0192ce/tm2/pkg/store/iavl/store_test.go (about) 1 package iavl 2 3 import ( 4 "fmt" 5 "testing" 6 7 "github.com/stretchr/testify/require" 8 9 "github.com/gnolang/gno/tm2/pkg/amino" 10 abci "github.com/gnolang/gno/tm2/pkg/bft/abci/types" 11 dbm "github.com/gnolang/gno/tm2/pkg/db" 12 "github.com/gnolang/gno/tm2/pkg/db/memdb" 13 "github.com/gnolang/gno/tm2/pkg/iavl" 14 "github.com/gnolang/gno/tm2/pkg/random" 15 16 // "github.com/gnolang/gno/tm2/pkg/store/errors" 17 "github.com/gnolang/gno/tm2/pkg/store/types" 18 ) 19 20 var ( 21 cacheSize = 100 22 numRecent int64 = 5 23 storeEvery int64 = 3 24 ) 25 26 var ( 27 treeData = map[string]string{ 28 "hello": "goodbye", 29 "aloha": "shalom", 30 } 31 nMoreData = 0 32 ) 33 34 // make a tree with data from above and save it 35 func newAlohaTree(t *testing.T, db dbm.DB) (*iavl.MutableTree, types.CommitID) { 36 t.Helper() 37 38 tree := iavl.NewMutableTree(db, cacheSize) 39 for k, v := range treeData { 40 tree.Set([]byte(k), []byte(v)) 41 } 42 for i := 0; i < nMoreData; i++ { 43 key := random.RandBytes(12) 44 value := random.RandBytes(50) 45 tree.Set(key, value) 46 } 47 hash, ver, err := tree.SaveVersion() 48 require.Nil(t, err) 49 return tree, types.CommitID{ver, hash} 50 } 51 52 func TestGetImmutable(t *testing.T) { 53 t.Parallel() 54 55 db := memdb.NewMemDB() 56 tree, cID := newAlohaTree(t, db) 57 store := UnsafeNewStore(tree, storeOptions(10, 10)) 58 59 require.True(t, tree.Set([]byte("hello"), []byte("adios"))) 60 hash, ver, err := tree.SaveVersion() 61 cID = types.CommitID{ver, hash} 62 require.Nil(t, err) 63 64 _, err = store.GetImmutable(cID.Version + 1) 65 require.Error(t, err) 66 67 newStore, err := store.GetImmutable(cID.Version - 1) 68 require.NoError(t, err) 69 require.Equal(t, newStore.Get([]byte("hello")), []byte("goodbye")) 70 71 newStore, err = store.GetImmutable(cID.Version) 72 require.NoError(t, err) 73 require.Equal(t, newStore.Get([]byte("hello")), []byte("adios")) 74 75 res := newStore.Query(abci.RequestQuery{Data: []byte("hello"), Height: cID.Version, Path: "/key", Prove: true}) 76 require.Equal(t, res.Value, []byte("adios")) 77 require.NotNil(t, res.Proof) 78 79 require.Panics(t, func() { newStore.Set(nil, nil) }) 80 require.Panics(t, func() { newStore.Delete(nil) }) 81 require.Panics(t, func() { newStore.Commit() }) 82 } 83 84 func TestTestGetImmutableIterator(t *testing.T) { 85 t.Parallel() 86 87 db := memdb.NewMemDB() 88 tree, cID := newAlohaTree(t, db) 89 store := UnsafeNewStore(tree, storeOptions(10, 10)) 90 91 newStore, err := store.GetImmutable(cID.Version) 92 require.NoError(t, err) 93 94 iter := newStore.Iterator([]byte("aloha"), []byte("hellz")) 95 expected := []string{"aloha", "hello"} 96 var i int 97 98 for i = 0; iter.Valid(); iter.Next() { 99 expectedKey := expected[i] 100 key, value := iter.Key(), iter.Value() 101 require.EqualValues(t, key, expectedKey) 102 require.EqualValues(t, value, treeData[expectedKey]) 103 i++ 104 } 105 106 require.Equal(t, len(expected), i) 107 } 108 109 func TestIAVLStoreGetSetHasDelete(t *testing.T) { 110 t.Parallel() 111 112 db := memdb.NewMemDB() 113 tree, _ := newAlohaTree(t, db) 114 iavlStore := UnsafeNewStore(tree, storeOptions(numRecent, storeEvery)) 115 116 key := "hello" 117 118 exists := iavlStore.Has([]byte(key)) 119 require.True(t, exists) 120 121 value := iavlStore.Get([]byte(key)) 122 require.EqualValues(t, value, treeData[key]) 123 124 value2 := "notgoodbye" 125 iavlStore.Set([]byte(key), []byte(value2)) 126 127 value = iavlStore.Get([]byte(key)) 128 require.EqualValues(t, value, value2) 129 130 iavlStore.Delete([]byte(key)) 131 132 exists = iavlStore.Has([]byte(key)) 133 require.False(t, exists) 134 } 135 136 func TestIAVLStoreNoNilSet(t *testing.T) { 137 t.Parallel() 138 139 db := memdb.NewMemDB() 140 tree, _ := newAlohaTree(t, db) 141 iavlStore := UnsafeNewStore(tree, storeOptions(numRecent, storeEvery)) 142 require.Panics(t, func() { iavlStore.Set([]byte("key"), nil) }, "setting a nil value should panic") 143 } 144 145 func TestIAVLIterator(t *testing.T) { 146 t.Parallel() 147 148 db := memdb.NewMemDB() 149 tree, _ := newAlohaTree(t, db) 150 iavlStore := UnsafeNewStore(tree, storeOptions(numRecent, storeEvery)) 151 iter := iavlStore.Iterator([]byte("aloha"), []byte("hellz")) 152 expected := []string{"aloha", "hello"} 153 var i int 154 155 for i = 0; iter.Valid(); iter.Next() { 156 expectedKey := expected[i] 157 key, value := iter.Key(), iter.Value() 158 require.EqualValues(t, key, expectedKey) 159 require.EqualValues(t, value, treeData[expectedKey]) 160 i++ 161 } 162 require.Equal(t, len(expected), i) 163 164 iter = iavlStore.Iterator([]byte("golang"), []byte("rocks")) 165 expected = []string{"hello"} 166 for i = 0; iter.Valid(); iter.Next() { 167 expectedKey := expected[i] 168 key, value := iter.Key(), iter.Value() 169 require.EqualValues(t, key, expectedKey) 170 require.EqualValues(t, value, treeData[expectedKey]) 171 i++ 172 } 173 require.Equal(t, len(expected), i) 174 175 iter = iavlStore.Iterator(nil, []byte("golang")) 176 expected = []string{"aloha"} 177 for i = 0; iter.Valid(); iter.Next() { 178 expectedKey := expected[i] 179 key, value := iter.Key(), iter.Value() 180 require.EqualValues(t, key, expectedKey) 181 require.EqualValues(t, value, treeData[expectedKey]) 182 i++ 183 } 184 require.Equal(t, len(expected), i) 185 186 iter = iavlStore.Iterator(nil, []byte("shalom")) 187 expected = []string{"aloha", "hello"} 188 for i = 0; iter.Valid(); iter.Next() { 189 expectedKey := expected[i] 190 key, value := iter.Key(), iter.Value() 191 require.EqualValues(t, key, expectedKey) 192 require.EqualValues(t, value, treeData[expectedKey]) 193 i++ 194 } 195 require.Equal(t, len(expected), i) 196 197 iter = iavlStore.Iterator(nil, nil) 198 expected = []string{"aloha", "hello"} 199 for i = 0; iter.Valid(); iter.Next() { 200 expectedKey := expected[i] 201 key, value := iter.Key(), iter.Value() 202 require.EqualValues(t, key, expectedKey) 203 require.EqualValues(t, value, treeData[expectedKey]) 204 i++ 205 } 206 require.Equal(t, len(expected), i) 207 208 iter = iavlStore.Iterator([]byte("golang"), nil) 209 expected = []string{"hello"} 210 for i = 0; iter.Valid(); iter.Next() { 211 expectedKey := expected[i] 212 key, value := iter.Key(), iter.Value() 213 require.EqualValues(t, key, expectedKey) 214 require.EqualValues(t, value, treeData[expectedKey]) 215 i++ 216 } 217 require.Equal(t, len(expected), i) 218 } 219 220 func TestIAVLReverseIterator(t *testing.T) { 221 t.Parallel() 222 223 db := memdb.NewMemDB() 224 tree := iavl.NewMutableTree(db, cacheSize) 225 iavlStore := UnsafeNewStore(tree, storeOptions(numRecent, storeEvery)) 226 227 iavlStore.Set([]byte{0x00}, []byte("0")) 228 iavlStore.Set([]byte{0x00, 0x00}, []byte("0 0")) 229 iavlStore.Set([]byte{0x00, 0x01}, []byte("0 1")) 230 iavlStore.Set([]byte{0x00, 0x02}, []byte("0 2")) 231 iavlStore.Set([]byte{0x01}, []byte("1")) 232 233 testReverseIterator := func(t *testing.T, start []byte, end []byte, expected []string) { 234 t.Helper() 235 236 iter := iavlStore.ReverseIterator(start, end) 237 var i int 238 for i = 0; iter.Valid(); iter.Next() { 239 expectedValue := expected[i] 240 value := iter.Value() 241 require.EqualValues(t, string(value), expectedValue) 242 i++ 243 } 244 require.Equal(t, len(expected), i) 245 } 246 247 testReverseIterator(t, nil, nil, []string{"1", "0 2", "0 1", "0 0", "0"}) 248 testReverseIterator(t, []byte{0x00}, nil, []string{"1", "0 2", "0 1", "0 0", "0"}) 249 testReverseIterator(t, []byte{0x00}, []byte{0x00, 0x01}, []string{"0 0", "0"}) 250 testReverseIterator(t, []byte{0x00}, []byte{0x01}, []string{"0 2", "0 1", "0 0", "0"}) 251 testReverseIterator(t, []byte{0x00, 0x01}, []byte{0x01}, []string{"0 2", "0 1"}) 252 testReverseIterator(t, nil, []byte{0x01}, []string{"0 2", "0 1", "0 0", "0"}) 253 } 254 255 func TestIAVLPrefixIterator(t *testing.T) { 256 t.Parallel() 257 258 db := memdb.NewMemDB() 259 tree := iavl.NewMutableTree(db, cacheSize) 260 iavlStore := UnsafeNewStore(tree, storeOptions(numRecent, storeEvery)) 261 262 iavlStore.Set([]byte("test1"), []byte("test1")) 263 iavlStore.Set([]byte("test2"), []byte("test2")) 264 iavlStore.Set([]byte("test3"), []byte("test3")) 265 iavlStore.Set([]byte{byte(55), byte(255), byte(255), byte(0)}, []byte("test4")) 266 iavlStore.Set([]byte{byte(55), byte(255), byte(255), byte(1)}, []byte("test4")) 267 iavlStore.Set([]byte{byte(55), byte(255), byte(255), byte(255)}, []byte("test4")) 268 iavlStore.Set([]byte{byte(255), byte(255), byte(0)}, []byte("test4")) 269 iavlStore.Set([]byte{byte(255), byte(255), byte(1)}, []byte("test4")) 270 iavlStore.Set([]byte{byte(255), byte(255), byte(255)}, []byte("test4")) 271 272 var i int 273 274 iter := types.PrefixIterator(iavlStore, []byte("test")) 275 expected := []string{"test1", "test2", "test3"} 276 for i = 0; iter.Valid(); iter.Next() { 277 expectedKey := expected[i] 278 key, value := iter.Key(), iter.Value() 279 require.EqualValues(t, key, expectedKey) 280 require.EqualValues(t, value, expectedKey) 281 i++ 282 } 283 iter.Close() 284 require.Equal(t, len(expected), i) 285 286 iter = types.PrefixIterator(iavlStore, []byte{byte(55), byte(255), byte(255)}) 287 expected2 := [][]byte{ 288 {byte(55), byte(255), byte(255), byte(0)}, 289 {byte(55), byte(255), byte(255), byte(1)}, 290 {byte(55), byte(255), byte(255), byte(255)}, 291 } 292 for i = 0; iter.Valid(); iter.Next() { 293 expectedKey := expected2[i] 294 key, value := iter.Key(), iter.Value() 295 require.EqualValues(t, key, expectedKey) 296 require.EqualValues(t, value, []byte("test4")) 297 i++ 298 } 299 iter.Close() 300 require.Equal(t, len(expected), i) 301 302 iter = types.PrefixIterator(iavlStore, []byte{byte(255), byte(255)}) 303 expected2 = [][]byte{ 304 {byte(255), byte(255), byte(0)}, 305 {byte(255), byte(255), byte(1)}, 306 {byte(255), byte(255), byte(255)}, 307 } 308 for i = 0; iter.Valid(); iter.Next() { 309 expectedKey := expected2[i] 310 key, value := iter.Key(), iter.Value() 311 require.EqualValues(t, key, expectedKey) 312 require.EqualValues(t, value, []byte("test4")) 313 i++ 314 } 315 iter.Close() 316 require.Equal(t, len(expected), i) 317 } 318 319 func TestIAVLReversePrefixIterator(t *testing.T) { 320 t.Parallel() 321 322 db := memdb.NewMemDB() 323 tree := iavl.NewMutableTree(db, cacheSize) 324 iavlStore := UnsafeNewStore(tree, storeOptions(numRecent, storeEvery)) 325 326 iavlStore.Set([]byte("test1"), []byte("test1")) 327 iavlStore.Set([]byte("test2"), []byte("test2")) 328 iavlStore.Set([]byte("test3"), []byte("test3")) 329 iavlStore.Set([]byte{byte(55), byte(255), byte(255), byte(0)}, []byte("test4")) 330 iavlStore.Set([]byte{byte(55), byte(255), byte(255), byte(1)}, []byte("test4")) 331 iavlStore.Set([]byte{byte(55), byte(255), byte(255), byte(255)}, []byte("test4")) 332 iavlStore.Set([]byte{byte(255), byte(255), byte(0)}, []byte("test4")) 333 iavlStore.Set([]byte{byte(255), byte(255), byte(1)}, []byte("test4")) 334 iavlStore.Set([]byte{byte(255), byte(255), byte(255)}, []byte("test4")) 335 336 var i int 337 338 iter := types.ReversePrefixIterator(iavlStore, []byte("test")) 339 expected := []string{"test3", "test2", "test1"} 340 for i = 0; iter.Valid(); iter.Next() { 341 expectedKey := expected[i] 342 key, value := iter.Key(), iter.Value() 343 require.EqualValues(t, key, expectedKey) 344 require.EqualValues(t, value, expectedKey) 345 i++ 346 } 347 require.Equal(t, len(expected), i) 348 349 iter = types.ReversePrefixIterator(iavlStore, []byte{byte(55), byte(255), byte(255)}) 350 expected2 := [][]byte{ 351 {byte(55), byte(255), byte(255), byte(255)}, 352 {byte(55), byte(255), byte(255), byte(1)}, 353 {byte(55), byte(255), byte(255), byte(0)}, 354 } 355 for i = 0; iter.Valid(); iter.Next() { 356 expectedKey := expected2[i] 357 key, value := iter.Key(), iter.Value() 358 require.EqualValues(t, key, expectedKey) 359 require.EqualValues(t, value, []byte("test4")) 360 i++ 361 } 362 require.Equal(t, len(expected), i) 363 364 iter = types.ReversePrefixIterator(iavlStore, []byte{byte(255), byte(255)}) 365 expected2 = [][]byte{ 366 {byte(255), byte(255), byte(255)}, 367 {byte(255), byte(255), byte(1)}, 368 {byte(255), byte(255), byte(0)}, 369 } 370 for i = 0; iter.Valid(); iter.Next() { 371 expectedKey := expected2[i] 372 key, value := iter.Key(), iter.Value() 373 require.EqualValues(t, key, expectedKey) 374 require.EqualValues(t, value, []byte("test4")) 375 i++ 376 } 377 require.Equal(t, len(expected), i) 378 } 379 380 func nextVersion(iavl *Store) { 381 key := []byte(fmt.Sprintf("Key for tree: %d", iavl.LastCommitID().Version)) 382 value := []byte(fmt.Sprintf("Value for tree: %d", iavl.LastCommitID().Version)) 383 iavl.Set(key, value) 384 iavl.Commit() 385 } 386 387 func TestIAVLDefaultPruning(t *testing.T) { 388 t.Parallel() 389 390 // Expected stored / deleted version numbers for: 391 // numRecent = 5, storeEvery = 3 392 states := []pruneState{ 393 {[]int64{}, []int64{}}, 394 {[]int64{1}, []int64{}}, 395 {[]int64{1, 2}, []int64{}}, 396 {[]int64{1, 2, 3}, []int64{}}, 397 {[]int64{1, 2, 3, 4}, []int64{}}, 398 {[]int64{1, 2, 3, 4, 5}, []int64{}}, 399 {[]int64{1, 2, 3, 4, 5, 6}, []int64{}}, 400 {[]int64{2, 3, 4, 5, 6, 7}, []int64{1}}, 401 {[]int64{3, 4, 5, 6, 7, 8}, []int64{1, 2}}, 402 {[]int64{3, 4, 5, 6, 7, 8, 9}, []int64{1, 2}}, 403 {[]int64{3, 5, 6, 7, 8, 9, 10}, []int64{1, 2, 4}}, 404 {[]int64{3, 6, 7, 8, 9, 10, 11}, []int64{1, 2, 4, 5}}, 405 {[]int64{3, 6, 7, 8, 9, 10, 11, 12}, []int64{1, 2, 4, 5}}, 406 {[]int64{3, 6, 8, 9, 10, 11, 12, 13}, []int64{1, 2, 4, 5, 7}}, 407 {[]int64{3, 6, 9, 10, 11, 12, 13, 14}, []int64{1, 2, 4, 5, 7, 8}}, 408 {[]int64{3, 6, 9, 10, 11, 12, 13, 14, 15}, []int64{1, 2, 4, 5, 7, 8}}, 409 } 410 testPruning(t, int64(5), int64(3), states) 411 } 412 413 func TestIAVLAlternativePruning(t *testing.T) { 414 t.Parallel() 415 416 // Expected stored / deleted version numbers for: 417 // numRecent = 3, storeEvery = 5 418 states := []pruneState{ 419 {[]int64{}, []int64{}}, 420 {[]int64{1}, []int64{}}, 421 {[]int64{1, 2}, []int64{}}, 422 {[]int64{1, 2, 3}, []int64{}}, 423 {[]int64{1, 2, 3, 4}, []int64{}}, 424 {[]int64{2, 3, 4, 5}, []int64{1}}, 425 {[]int64{3, 4, 5, 6}, []int64{1, 2}}, 426 {[]int64{4, 5, 6, 7}, []int64{1, 2, 3}}, 427 {[]int64{5, 6, 7, 8}, []int64{1, 2, 3, 4}}, 428 {[]int64{5, 6, 7, 8, 9}, []int64{1, 2, 3, 4}}, 429 {[]int64{5, 7, 8, 9, 10}, []int64{1, 2, 3, 4, 6}}, 430 {[]int64{5, 8, 9, 10, 11}, []int64{1, 2, 3, 4, 6, 7}}, 431 {[]int64{5, 9, 10, 11, 12}, []int64{1, 2, 3, 4, 6, 7, 8}}, 432 {[]int64{5, 10, 11, 12, 13}, []int64{1, 2, 3, 4, 6, 7, 8, 9}}, 433 {[]int64{5, 10, 11, 12, 13, 14}, []int64{1, 2, 3, 4, 6, 7, 8, 9}}, 434 {[]int64{5, 10, 12, 13, 14, 15}, []int64{1, 2, 3, 4, 6, 7, 8, 9, 11}}, 435 } 436 testPruning(t, int64(3), int64(5), states) 437 } 438 439 type pruneState struct { 440 stored []int64 441 deleted []int64 442 } 443 444 func testPruning(t *testing.T, numRecent int64, storeEvery int64, states []pruneState) { 445 t.Helper() 446 447 db := memdb.NewMemDB() 448 tree := iavl.NewMutableTree(db, cacheSize) 449 iavlStore := UnsafeNewStore(tree, storeOptions(numRecent, storeEvery)) 450 for step, state := range states { 451 for _, ver := range state.stored { 452 require.True(t, iavlStore.VersionExists(ver), 453 "Missing version %d with latest version %d. Should save last %d and every %d", 454 ver, step, numRecent, storeEvery) 455 } 456 for _, ver := range state.deleted { 457 require.False(t, iavlStore.VersionExists(ver), 458 "Unpruned version %d with latest version %d. Should prune all but last %d and every %d", 459 ver, step, numRecent, storeEvery) 460 } 461 nextVersion(iavlStore) 462 } 463 } 464 465 func TestIAVLNoPrune(t *testing.T) { 466 t.Parallel() 467 468 db := memdb.NewMemDB() 469 tree := iavl.NewMutableTree(db, cacheSize) 470 iavlStore := UnsafeNewStore(tree, storeOptions(numRecent, int64(1))) 471 nextVersion(iavlStore) 472 for i := 1; i < 100; i++ { 473 for j := 1; j <= i; j++ { 474 require.True(t, iavlStore.VersionExists(int64(j)), 475 "Missing version %d with latest version %d. Should be storing all versions", 476 j, i) 477 } 478 nextVersion(iavlStore) 479 } 480 } 481 482 func TestIAVLPruneEverything(t *testing.T) { 483 t.Parallel() 484 485 db := memdb.NewMemDB() 486 tree := iavl.NewMutableTree(db, cacheSize) 487 iavlStore := UnsafeNewStore(tree, storeOptions(int64(0), int64(0))) 488 nextVersion(iavlStore) 489 for i := 1; i < 100; i++ { 490 for j := 1; j < i; j++ { 491 require.False(t, iavlStore.VersionExists(int64(j)), 492 "Unpruned version %d with latest version %d. Should prune all old versions", 493 j, i) 494 } 495 require.True(t, iavlStore.VersionExists(int64(i)), 496 "Missing current version on step %d, should not prune current state tree", 497 i) 498 nextVersion(iavlStore) 499 } 500 } 501 502 func TestIAVLStoreQuery(t *testing.T) { 503 t.Parallel() 504 505 db := memdb.NewMemDB() 506 tree := iavl.NewMutableTree(db, cacheSize) 507 iavlStore := UnsafeNewStore(tree, storeOptions(numRecent, storeEvery)) 508 509 k1, v1 := []byte("key1"), []byte("val1") 510 k2, v2 := []byte("key2"), []byte("val2") 511 v3 := []byte("val3") 512 513 ksub := []byte("key") 514 KVs0 := []types.KVPair{} 515 KVs1 := []types.KVPair{ 516 {Key: k1, Value: v1}, 517 {Key: k2, Value: v2}, 518 } 519 KVs2 := []types.KVPair{ 520 {Key: k1, Value: v3}, 521 {Key: k2, Value: v2}, 522 } 523 valExpSubEmpty := amino.MustMarshalSized(KVs0) 524 valExpSub1 := amino.MustMarshalSized(KVs1) 525 valExpSub2 := amino.MustMarshalSized(KVs2) 526 527 cid := iavlStore.Commit() 528 ver := cid.Version 529 query := abci.RequestQuery{Path: "/key", Data: k1, Height: ver} 530 querySub := abci.RequestQuery{Path: "/subspace", Data: ksub, Height: ver} 531 532 // query subspace before anything set 533 qres := iavlStore.Query(querySub) 534 require.Nil(t, qres.Error) 535 require.Equal(t, valExpSubEmpty, qres.Value) 536 537 // set data 538 iavlStore.Set(k1, v1) 539 iavlStore.Set(k2, v2) 540 541 // set data without commit, doesn't show up 542 qres = iavlStore.Query(query) 543 require.Nil(t, qres.Error) 544 require.Nil(t, qres.Value) 545 546 // commit it, but still don't see on old version 547 cid = iavlStore.Commit() 548 qres = iavlStore.Query(query) 549 require.Nil(t, qres.Error) 550 require.Nil(t, qres.Value) 551 552 // but yes on the new version 553 query.Height = cid.Version 554 qres = iavlStore.Query(query) 555 require.Nil(t, qres.Error) 556 require.Equal(t, v1, qres.Value) 557 558 // and for the subspace 559 qres = iavlStore.Query(querySub) 560 require.Nil(t, qres.Error) 561 require.Equal(t, valExpSub1, qres.Value) 562 563 // modify 564 iavlStore.Set(k1, v3) 565 cid = iavlStore.Commit() 566 567 // query will return old values, as height is fixed 568 qres = iavlStore.Query(query) 569 require.Nil(t, qres.Error) 570 require.Equal(t, v1, qres.Value) 571 572 // update to latest in the query and we are happy 573 query.Height = cid.Version 574 qres = iavlStore.Query(query) 575 require.Nil(t, qres.Error) 576 require.Equal(t, v3, qres.Value) 577 query2 := abci.RequestQuery{Path: "/key", Data: k2, Height: cid.Version} 578 579 qres = iavlStore.Query(query2) 580 require.Nil(t, qres.Error) 581 require.Equal(t, v2, qres.Value) 582 // and for the subspace 583 qres = iavlStore.Query(querySub) 584 require.Nil(t, qres.Error) 585 require.Equal(t, valExpSub2, qres.Value) 586 587 // default (height 0) will show latest -1 588 query0 := abci.RequestQuery{Path: "/key", Data: k1} 589 qres = iavlStore.Query(query0) 590 require.Nil(t, qres.Error) 591 require.Equal(t, v1, qres.Value) 592 } 593 594 func BenchmarkIAVLIteratorNext(b *testing.B) { 595 db := memdb.NewMemDB() 596 treeSize := 1000 597 tree := iavl.NewMutableTree(db, cacheSize) 598 for i := 0; i < treeSize; i++ { 599 key := random.RandBytes(4) 600 value := random.RandBytes(50) 601 tree.Set(key, value) 602 } 603 iavlStore := UnsafeNewStore(tree, storeOptions(numRecent, storeEvery)) 604 iterators := make([]types.Iterator, b.N/treeSize) 605 for i := 0; i < len(iterators); i++ { 606 iterators[i] = iavlStore.Iterator([]byte{0}, []byte{255, 255, 255, 255, 255}) 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 storeOptions(recent, every int64) types.StoreOptions { 618 return types.StoreOptions{ 619 PruningOptions: types.PruningOptions{ 620 KeepRecent: recent, 621 KeepEvery: every, 622 }, 623 } 624 }