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