From 4f537d523126b820c415c9015deebf6dec7a252d Mon Sep 17 00:00:00 2001 From: Matt Kocubinski Date: Fri, 3 Jan 2025 04:41:47 -0600 Subject: [PATCH] feat(store/v2): full iavl/v2 support (#23131) Co-authored-by: marbar3778 Co-authored-by: auricom <27022259+auricom@users.noreply.github.com> --- .github/workflows/build.yml | 9 +- runtime/v2/module.go | 1 - scripts/build/build.mk | 15 +++- scripts/init-simapp-v2.sh | 15 ++++ server/v2/cometbft/go.mod | 4 + server/v2/cometbft/go.sum | 10 +++ server/v2/commands.go | 5 +- simapp/v2/app.go | 10 ++- simapp/v2/benchmark.go | 7 +- simapp/v2/go.mod | 13 ++- simapp/v2/go.sum | 18 +++- store/v2/commitment/iavl/tree.go | 4 + store/v2/commitment/iavlv2/snapshot.go | 59 +++++++++++++ store/v2/commitment/iavlv2/tree.go | 112 ++++++++++++++++++------ store/v2/commitment/iavlv2/tree_test.go | 3 +- store/v2/commitment/mem/tree.go | 4 + store/v2/commitment/store.go | 112 ++++++++++++++++++------ store/v2/commitment/store_test_suite.go | 3 - store/v2/commitment/tree.go | 2 + store/v2/database.go | 7 ++ store/v2/go.mod | 2 +- store/v2/go.sum | 4 +- store/v2/proof/commit_info.go | 27 +++--- store/v2/proof/commit_info_test.go | 42 ++++----- store/v2/root/factory.go | 9 +- store/v2/root/factory_test.go | 4 +- store/v2/root/store.go | 37 ++++---- store/v2/store.go | 2 + tests/go.mod | 4 + tests/go.sum | 10 +++ tools/benchmark/client/cli/tx.go | 4 +- 31 files changed, 417 insertions(+), 141 deletions(-) create mode 100644 store/v2/commitment/iavlv2/snapshot.go diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index f5df2fa95f53..9aa733f48343 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -25,9 +25,14 @@ jobs: with: go-version: "1.23" check-latest: true + - name: install aarch64-gcc + if: matrix.go-arch == 'arm64' + run: sudo apt-get install gcc-aarch64-linux-gnu binutils-aarch64-linux-gnu - name: Get rocksdb version + if: matrix.go-arch == 'amd64' run: ./.github/scripts/get-rocksdb-version.sh - name: Fix permissions for cache + if: matrix.go-arch == 'amd64' run: sudo chown $(whoami) /usr/local/lib /usr/local/include - name: Restore rocksdb libraries cache id: cache-rocksdb @@ -47,8 +52,8 @@ jobs: ################### #### Build App #### ################### - - name: Build v2 - run: GOARCH=${{ matrix.go-arch }} COSMOS_BUILD_OPTIONS=v2 make build + - name: Build with sqlite backend + run: GOARCH=${{ matrix.go-arch }} COSMOS_BUILD_OPTIONS=v2,sqlite make build - name: Build with rocksdb backend if: matrix.go-arch == 'amd64' run: GOARCH=${{ matrix.go-arch }} COSMOS_BUILD_OPTIONS=v2,rocksdb make build diff --git a/runtime/v2/module.go b/runtime/v2/module.go index fcbb671bcecb..9f638bb9c07c 100644 --- a/runtime/v2/module.go +++ b/runtime/v2/module.go @@ -148,7 +148,6 @@ func ProvideAppBuilder[T transaction.Tx]( type AppInputs struct { depinject.In - StoreConfig *root.Config Config *runtimev2.Module AppBuilder *AppBuilder[transaction.Tx] ModuleManager *MM[transaction.Tx] diff --git a/scripts/build/build.mk b/scripts/build/build.mk index e05e253ac7c2..5bf479d98933 100644 --- a/scripts/build/build.mk +++ b/scripts/build/build.mk @@ -71,6 +71,14 @@ ifeq (bls12381,$(findstring bls12381,$(COSMOS_BUILD_OPTIONS))) build_tags += bls12381 endif +# handle sqlite +ifeq (sqlite,$(findstring sqlite,$(COSMOS_BUILD_OPTIONS))) + CGO_ENABLED=1 + ifeq (arm64,$(shell go env GOARCH)) + CC=aarch64-linux-gnu-gcc + endif +endif + # benchmark module ifeq (benchmark,$(findstring benchmark,$(COSMOS_BUILD_OPTIONS))) build_tags += benchmark @@ -109,7 +117,7 @@ ifeq (debug,$(findstring debug,$(COSMOS_BUILD_OPTIONS))) BUILD_FLAGS += -gcflags "all=-N -l" endif -#? all: Run tools build +#? all: Run tools build all: build @@ -127,7 +135,10 @@ build-linux-arm64: GOOS=linux GOARCH=arm64 LEDGER_ENABLED=false $(MAKE) build $(BUILD_TARGETS): go.sum $(BUILDDIR)/ - cd ${CURRENT_DIR}/${SIMAPP} && go $@ -mod=readonly $(BUILD_FLAGS) $(BUILD_ARGS) ./... + cd ${CURRENT_DIR}/${SIMAPP} && \ + $(if $(CGO_ENABLED),CGO_ENABLED=$(CGO_ENABLED)) \ + $(if $(CC),CC=$(CC)) \ + go $@ -mod=readonly $(BUILD_FLAGS) $(BUILD_ARGS) ./... $(BUILDDIR)/: mkdir -p $(BUILDDIR)/ diff --git a/scripts/init-simapp-v2.sh b/scripts/init-simapp-v2.sh index 02fb379f8e2c..3ad1eedc41b1 100755 --- a/scripts/init-simapp-v2.sh +++ b/scripts/init-simapp-v2.sh @@ -11,8 +11,20 @@ $SIMD_BIN config set client keyring-backend test $SIMD_BIN config set client keyring-default-keyname alice $SIMD_BIN config set app rest.enable true $SIMD_BIN config set app telemetry.prometheus-retention-time 600 +$SIMD_BIN config set app store.options.sc-type iavl-v2 +sed -i '' 's/timeout_commit = "5s"/timeout_commit = "1s"/' "$SIMD_HOME"/config/config.toml +sed -i '' 's/prometheus = false/prometheus = true/' "$SIMD_HOME"/config/config.toml + $SIMD_BIN keys add alice --indiscreet $SIMD_BIN keys add bob --indiscreet +aliases="" +for i in $(seq 10); do + alias=$(dd if=/dev/urandom bs=16 count=24 2> /dev/null | base32 | head -c 32) + $SIMD_BIN keys add "$alias" --indiscreet + aliases="$aliases $alias" +done +echo "Generated aliases: $aliases" + $SIMD_BIN init simapp-v2-node --chain-id simapp-v2-chain # to change the voting_period jq '.app_state.gov.params.voting_period = "600s"' $SIMD_HOME/config/genesis.json > temp.json && mv temp.json $SIMD_HOME/config/genesis.json @@ -20,5 +32,8 @@ jq '.app_state.gov.params.expedited_voting_period = "300s"' $SIMD_HOME/config/ge jq '.app_state.mint.minter.inflation = "0.300000000000000000"' $SIMD_HOME/config/genesis.json > temp.json && mv temp.json $SIMD_HOME/config/genesis.json # to change the inflation $SIMD_BIN genesis add-genesis-account alice 5000000000stake --keyring-backend test $SIMD_BIN genesis add-genesis-account bob 5000000000stake --keyring-backend test +for a in $aliases; do + $SIMD_BIN genesis add-genesis-account "$a" 100000000stake --keyring-backend test +done $SIMD_BIN genesis gentx alice 1000000stake --chain-id simapp-v2-chain $SIMD_BIN genesis collect-gentxs \ No newline at end of file diff --git a/server/v2/cometbft/go.mod b/server/v2/cometbft/go.mod index f2c10ff6a939..76600ee6ee33 100644 --- a/server/v2/cometbft/go.mod +++ b/server/v2/cometbft/go.mod @@ -54,8 +54,10 @@ require ( github.com/DataDog/datadog-go v4.8.3+incompatible // indirect github.com/DataDog/zstd v1.5.6 // indirect github.com/Microsoft/go-winio v0.6.1 // indirect + github.com/aybabtme/uniplot v0.0.0-20151203143629-039c559e5e7e // indirect github.com/beorn7/perks v1.0.1 // indirect github.com/bgentry/speakeasy v0.2.0 // indirect + github.com/bvinc/go-sqlite-lite v0.6.1 // indirect github.com/bytedance/sonic v1.12.6 // indirect github.com/bytedance/sonic/loader v0.2.1 // indirect github.com/cespare/xxhash/v2 v2.3.0 // indirect @@ -72,6 +74,7 @@ require ( github.com/cosmos/cosmos-proto v1.0.0-beta.5 // indirect github.com/cosmos/go-bip39 v1.0.0 // indirect github.com/cosmos/iavl v1.3.4 // indirect + github.com/cosmos/iavl/v2 v2.0.0-alpha.4 // indirect github.com/cosmos/ics23/go v0.11.0 // indirect github.com/cosmos/ledger-cosmos-go v0.14.0 // indirect github.com/danieljoos/wincred v1.2.1 // indirect @@ -116,6 +119,7 @@ require ( github.com/jmhodges/levigo v1.0.0 // indirect github.com/klauspost/compress v1.17.11 // indirect github.com/klauspost/cpuid/v2 v2.2.9 // indirect + github.com/kocubinski/costor-api v1.1.1 // indirect github.com/kr/pretty v0.3.1 // indirect github.com/kr/text v0.2.0 // indirect github.com/lib/pq v1.10.9 // indirect diff --git a/server/v2/cometbft/go.sum b/server/v2/cometbft/go.sum index ff38dd975ee4..0baa3c2c5201 100644 --- a/server/v2/cometbft/go.sum +++ b/server/v2/cometbft/go.sum @@ -53,6 +53,8 @@ github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuy github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= +github.com/aybabtme/uniplot v0.0.0-20151203143629-039c559e5e7e h1:dSeuFcs4WAJJnswS8vXy7YY1+fdlbVPuEVmDAfqvFOQ= +github.com/aybabtme/uniplot v0.0.0-20151203143629-039c559e5e7e/go.mod h1:uh71c5Vc3VNIplXOFXsnDy21T1BepgT32c5X/YPrOyc= github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= @@ -66,6 +68,8 @@ github.com/btcsuite/btcd/btcutil v1.1.6 h1:zFL2+c3Lb9gEgqKNzowKUPQNb8jV7v5Oaodi/ github.com/btcsuite/btcd/btcutil v1.1.6/go.mod h1:9dFymx8HpuLqBnsPELrImQeTQfKBQqzqGbbV3jK55aE= github.com/bufbuild/protocompile v0.4.0 h1:LbFKd2XowZvQ/kajzguUp2DC9UEIQhIq77fZZlaQsNA= github.com/bufbuild/protocompile v0.4.0/go.mod h1:3v93+mbWn/v3xzN+31nwkJfrEpAUwp+BagBSZWx+TP8= +github.com/bvinc/go-sqlite-lite v0.6.1 h1:JU8Rz5YAOZQiU3WEulKF084wfXpytRiqD2IaW2QjPz4= +github.com/bvinc/go-sqlite-lite v0.6.1/go.mod h1:2GiE60NUdb0aNhDdY+LXgrqAVDpi2Ijc6dB6ZMp9x6s= github.com/bytedance/sonic v1.12.6 h1:/isNmCUF2x3Sh8RAp/4mh4ZGkcFAX/hLrzrK3AvpRzk= github.com/bytedance/sonic v1.12.6/go.mod h1:B8Gt/XvtZ3Fqj+iSKMypzymZxw/FVwgIGKzMzT9r/rk= github.com/bytedance/sonic/loader v0.1.1/go.mod h1:ncP89zfokxS5LZrJxl5z0UJcsk4M4yY2JpfqGeCtNLU= @@ -123,6 +127,10 @@ github.com/cosmos/gogoproto v1.7.0 h1:79USr0oyXAbxg3rspGh/m4SWNyoz/GLaAh0QlCe2fr github.com/cosmos/gogoproto v1.7.0/go.mod h1:yWChEv5IUEYURQasfyBW5ffkMHR/90hiHgbNgrtp4j0= github.com/cosmos/iavl v1.3.4 h1:A0RUAms7TZ0L6EFrrBIPg4Dy7qD9vvD5lJKUxEXURLM= github.com/cosmos/iavl v1.3.4/go.mod h1:T6SfBcyhulVIY2G/ZtAtQm/QiJvsuhIos52V4dWYk88= +github.com/cosmos/iavl-bench/bench v0.0.4 h1:J6zQPiBqF4CXMM3QBsLqZgQEBGY0taX85vLIZMhmAfQ= +github.com/cosmos/iavl-bench/bench v0.0.4/go.mod h1:j2rLae77EffacWcp7mmj3Uaa4AOAmZA7ymvhsuBQKKI= +github.com/cosmos/iavl/v2 v2.0.0-alpha.4 h1:PfpQt7xl4hojw2UFS2JdJppJnx8sjlmcxRQ7Hxk7Cl0= +github.com/cosmos/iavl/v2 v2.0.0-alpha.4/go.mod h1:7RSm0aeApe3S1x4TrLffvUL6pjOtMYV4glYnpAhr2lw= github.com/cosmos/ics23/go v0.11.0 h1:jk5skjT0TqX5e5QJbEnwXIS2yI2vnmLOgpQPeM5RtnU= github.com/cosmos/ics23/go v0.11.0/go.mod h1:A8OjxPE67hHST4Icw94hOxxFEJMBG031xIGF/JHNIY0= github.com/cosmos/ledger-cosmos-go v0.14.0 h1:WfCHricT3rPbkPSVKRH+L4fQGKYHuGOK9Edpel8TYpE= @@ -302,6 +310,8 @@ github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa02 github.com/klauspost/cpuid/v2 v2.2.9 h1:66ze0taIn2H33fBvCkXuv9BmCwDfafmiIVpKV9kKGuY= github.com/klauspost/cpuid/v2 v2.2.9/go.mod h1:rqkxqrZ1EhYM9G+hXH7YdowN5R5RGN6NK4QwQ3WMXF8= github.com/knz/go-libedit v1.10.1/go.mod h1:MZTVkCWyz0oBc7JOWP3wNAzd002ZbM/5hgShxwh4x8M= +github.com/kocubinski/costor-api v1.1.1 h1:sgfJA7T/8IfZ59zxiMrED0xdjerAFuPNBTqyO90GiEE= +github.com/kocubinski/costor-api v1.1.1/go.mod h1:ESMBMDkKfN+9vvvhhNVdKLhbOmzI3O/i16iXvRM9Tuc= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= diff --git a/server/v2/commands.go b/server/v2/commands.go index b0cf632138b1..082e78243f33 100644 --- a/server/v2/commands.go +++ b/server/v2/commands.go @@ -117,8 +117,9 @@ func createStartCommand[T transaction.Tx]( // wrapCPUProfile starts CPU profiling, if enabled, and executes the provided // callbackFn, then waits for it to return. func wrapCPUProfile(logger log.Logger, cfg server.ConfigMap, callbackFn func() error) error { - cpuProfileFile, ok := cfg[FlagCPUProfiling] - if !ok { + serverCfg := cfg[serverName].(map[string]any) + cpuProfileFile, ok := serverCfg["cpu-profile"] + if !ok || cpuProfileFile == "" { // if cpu profiling is not enabled, just run the callback return callbackFn() } diff --git a/simapp/v2/app.go b/simapp/v2/app.go index 601d641ad060..d32c76f9a687 100644 --- a/simapp/v2/app.go +++ b/simapp/v2/app.go @@ -16,7 +16,9 @@ import ( "cosmossdk.io/runtime/v2" serverstore "cosmossdk.io/server/v2/store" "cosmossdk.io/store/v2" + "cosmossdk.io/store/v2/commitment/iavlv2" "cosmossdk.io/store/v2/root" + _ "cosmossdk.io/tools/benchmark" basedepinject "cosmossdk.io/x/accounts/defaults/base/depinject" lockupdepinject "cosmossdk.io/x/accounts/defaults/lockup/depinject" multisigdepinject "cosmossdk.io/x/accounts/defaults/multisig/depinject" @@ -220,5 +222,11 @@ func (app *SimApp[T]) Close() error { } func ProvideRootStoreConfig(config runtime.GlobalConfig) (*root.Config, error) { - return serverstore.UnmarshalConfig(config) + cfg, err := serverstore.UnmarshalConfig(config) + if err != nil { + return nil, err + } + cfg.Options.IavlV2Config = iavlv2.DefaultOptions(int64(cfg.Options.SCPruningOption.KeepRecent)) + iavlv2.SetGlobalPruneLimit(1) + return cfg, err } diff --git a/simapp/v2/benchmark.go b/simapp/v2/benchmark.go index 85376b02cb83..bccc212b7629 100644 --- a/simapp/v2/benchmark.go +++ b/simapp/v2/benchmark.go @@ -3,12 +3,13 @@ package simapp import ( + "fmt" + runtimev2 "cosmossdk.io/api/cosmos/app/runtime/v2" appv1alpha1 "cosmossdk.io/api/cosmos/app/v1alpha1" benchmarkmodulev1 "cosmossdk.io/api/cosmos/benchmark/module/v1" "cosmossdk.io/depinject/appconfig" benchmark "cosmossdk.io/tools/benchmark/module" - "fmt" ) func init() { @@ -20,8 +21,8 @@ func init() { Config: appconfig.WrapAny(&benchmarkmodulev1.Module{ GenesisParams: &benchmarkmodulev1.GeneratorParams{ Seed: 34, - BucketCount: 3, - GenesisCount: 3_000_000, + BucketCount: 5, + GenesisCount: 20_000_000, KeyMean: 64, KeyStdDev: 12, ValueMean: 1024, diff --git a/simapp/v2/go.mod b/simapp/v2/go.mod index 8b952d2f1cec..1c4541aef289 100644 --- a/simapp/v2/go.mod +++ b/simapp/v2/go.mod @@ -1,6 +1,6 @@ module cosmossdk.io/simapp/v2 -go 1.23.3 +go 1.23.4 require ( cosmossdk.io/api v0.8.0-rc.3 @@ -14,7 +14,7 @@ require ( cosmossdk.io/server/v2 v2.0.0-beta.1 cosmossdk.io/server/v2/cometbft v0.0.0-20241015140036-ee3d320eaa55 cosmossdk.io/store/v2 v2.0.0 - cosmossdk.io/tools/benchmark v0.0.0-00010101000000-000000000000 + cosmossdk.io/tools/benchmark v0.2.0-rc.1 cosmossdk.io/tools/confix v0.0.0-00010101000000-000000000000 cosmossdk.io/x/accounts v0.0.0-20240913065641-0064ccbce64e cosmossdk.io/x/accounts/defaults/base v0.0.0-00010101000000-000000000000 @@ -48,6 +48,8 @@ require ( google.golang.org/protobuf v1.36.0 ) +require github.com/cosmos/iavl/v2 v2.0.0-alpha.4 // indirect + require ( buf.build/gen/go/cometbft/cometbft/protocolbuffers/go v1.36.0-20241120201313-68e42a58b301.1 // indirect buf.build/gen/go/cosmos/gogo-proto/protocolbuffers/go v1.36.0-20240130113600-88ef6483f90f.1 // indirect @@ -64,7 +66,7 @@ require ( cosmossdk.io/schema v1.0.0 // indirect cosmossdk.io/server/v2/appmanager v1.0.0-beta.1 // indirect cosmossdk.io/server/v2/stf v1.0.0-beta.1 // indirect - cosmossdk.io/store v1.10.0-rc.1 // indirect + cosmossdk.io/store v1.10.0-rc.1.0.20241218084712-ca559989da43 // indirect cosmossdk.io/x/tx v1.0.0-alpha.3 // indirect filippo.io/edwards25519 v1.1.0 // indirect github.com/99designs/go-keychain v0.0.0-20191008050251-8e49817e8af4 // indirect @@ -73,11 +75,13 @@ require ( github.com/DataDog/zstd v1.5.6 // indirect github.com/Microsoft/go-winio v0.6.1 // indirect github.com/aws/aws-sdk-go v1.55.5 // indirect + github.com/aybabtme/uniplot v0.0.0-20151203143629-039c559e5e7e // indirect github.com/aymanbagabas/go-osc52/v2 v2.0.1 // indirect github.com/beorn7/perks v1.0.1 // indirect github.com/bgentry/go-netrc v0.0.0-20140422174119-9fd32a8b3d3d // indirect github.com/bgentry/speakeasy v0.2.0 // indirect github.com/bits-and-blooms/bitset v1.10.0 // indirect + github.com/bvinc/go-sqlite-lite v0.6.1 // indirect github.com/bytedance/sonic v1.12.6 // indirect github.com/bytedance/sonic/loader v0.2.1 // indirect github.com/cespare/xxhash/v2 v2.3.0 // indirect @@ -161,6 +165,7 @@ require ( github.com/jmhodges/levigo v1.0.0 // indirect github.com/klauspost/compress v1.17.11 // indirect github.com/klauspost/cpuid/v2 v2.2.9 // indirect + github.com/kocubinski/costor-api v1.1.1 // indirect github.com/kr/pretty v0.3.1 // indirect github.com/kr/text v0.2.0 // indirect github.com/lib/pq v1.10.9 // indirect @@ -210,7 +215,7 @@ require ( github.com/zondax/ledger-go v0.14.3 // indirect gitlab.com/yawning/secp256k1-voi v0.0.0-20230925100816-f2616030848b // indirect gitlab.com/yawning/tuplehash v0.0.0-20230713102510-df83abbf9a02 // indirect - go.etcd.io/bbolt v1.4.0-alpha.0.0.20240404170359-43604f3112c5 // indirect + go.etcd.io/bbolt v1.4.0-alpha.1 // indirect go.opencensus.io v0.24.0 // indirect go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.53.0 // indirect go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.53.0 // indirect diff --git a/simapp/v2/go.sum b/simapp/v2/go.sum index 5054e85c93a9..e144deb31898 100644 --- a/simapp/v2/go.sum +++ b/simapp/v2/go.sum @@ -212,8 +212,8 @@ cosmossdk.io/math v1.4.0 h1:XbgExXFnXmF/CccPPEto40gOO7FpWu9yWNAZPN3nkNQ= cosmossdk.io/math v1.4.0/go.mod h1:O5PkD4apz2jZs4zqFdTr16e1dcaQCc5z6lkEnrrppuk= cosmossdk.io/schema v1.0.0 h1:/diH4XJjpV1JQwuIozwr+A4uFuuwanFdnw2kKeiXwwQ= cosmossdk.io/schema v1.0.0/go.mod h1:RDAhxIeNB4bYqAlF4NBJwRrgtnciMcyyg0DOKnhNZQQ= -cosmossdk.io/store v1.10.0-rc.1 h1:/YVPJLre7lt/QDbl90k95TLt+IvafF1sHaU6WHd/rpc= -cosmossdk.io/store v1.10.0-rc.1/go.mod h1:eZNgZKvZRlDUk8CE3LTDVMAcSM7zLOet2S8fByQkF3s= +cosmossdk.io/store v1.10.0-rc.1.0.20241218084712-ca559989da43 h1:glZ6MpmD+5AhwJYV4jzx+rn7cgUB2owHgk9o+93luz0= +cosmossdk.io/store v1.10.0-rc.1.0.20241218084712-ca559989da43/go.mod h1:XCWpgfueHSBY+B7Cf2Aq/CcsU+6XoFH+EmseCKglFrU= cosmossdk.io/x/tx v1.0.0-alpha.3 h1:+55/JFH5QRqnFhOI2heH3DKsaNL0RpXcJOQNzUvHiaQ= cosmossdk.io/x/tx v1.0.0-alpha.3/go.mod h1:h4pQ/j6Gfu8goB1R3Jbl4qY4RjYVNAsoylcleTXdSRg= dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= @@ -245,6 +245,8 @@ github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kd github.com/aws/aws-sdk-go v1.44.122/go.mod h1:y4AeaBuwd2Lk+GepC1E9v0qOiTws0MIWAX4oIKwKHZo= github.com/aws/aws-sdk-go v1.55.5 h1:KKUZBfBoyqy5d3swXyiC7Q76ic40rYcbqH7qjh59kzU= github.com/aws/aws-sdk-go v1.55.5/go.mod h1:eRwEWoyTWFMVYVQzKMNHWP5/RV4xIUGMQfXQHfHkpNU= +github.com/aybabtme/uniplot v0.0.0-20151203143629-039c559e5e7e h1:dSeuFcs4WAJJnswS8vXy7YY1+fdlbVPuEVmDAfqvFOQ= +github.com/aybabtme/uniplot v0.0.0-20151203143629-039c559e5e7e/go.mod h1:uh71c5Vc3VNIplXOFXsnDy21T1BepgT32c5X/YPrOyc= github.com/aymanbagabas/go-osc52/v2 v2.0.1 h1:HwpRHbFMcZLEVr42D4p7XBqjyuxQH5SMiErDT4WkJ2k= github.com/aymanbagabas/go-osc52/v2 v2.0.1/go.mod h1:uYgXzlJ7ZpABp8OJ+exZzJJhRNQ2ASbcXHWsFqH8hp8= github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= @@ -264,6 +266,8 @@ github.com/btcsuite/btcd/btcutil v1.1.6 h1:zFL2+c3Lb9gEgqKNzowKUPQNb8jV7v5Oaodi/ github.com/btcsuite/btcd/btcutil v1.1.6/go.mod h1:9dFymx8HpuLqBnsPELrImQeTQfKBQqzqGbbV3jK55aE= github.com/bufbuild/protocompile v0.4.0 h1:LbFKd2XowZvQ/kajzguUp2DC9UEIQhIq77fZZlaQsNA= github.com/bufbuild/protocompile v0.4.0/go.mod h1:3v93+mbWn/v3xzN+31nwkJfrEpAUwp+BagBSZWx+TP8= +github.com/bvinc/go-sqlite-lite v0.6.1 h1:JU8Rz5YAOZQiU3WEulKF084wfXpytRiqD2IaW2QjPz4= +github.com/bvinc/go-sqlite-lite v0.6.1/go.mod h1:2GiE60NUdb0aNhDdY+LXgrqAVDpi2Ijc6dB6ZMp9x6s= github.com/bytedance/sonic v1.12.6 h1:/isNmCUF2x3Sh8RAp/4mh4ZGkcFAX/hLrzrK3AvpRzk= github.com/bytedance/sonic v1.12.6/go.mod h1:B8Gt/XvtZ3Fqj+iSKMypzymZxw/FVwgIGKzMzT9r/rk= github.com/bytedance/sonic/loader v0.1.1/go.mod h1:ncP89zfokxS5LZrJxl5z0UJcsk4M4yY2JpfqGeCtNLU= @@ -342,6 +346,10 @@ github.com/cosmos/gogoproto v1.7.0 h1:79USr0oyXAbxg3rspGh/m4SWNyoz/GLaAh0QlCe2fr github.com/cosmos/gogoproto v1.7.0/go.mod h1:yWChEv5IUEYURQasfyBW5ffkMHR/90hiHgbNgrtp4j0= github.com/cosmos/iavl v1.3.4 h1:A0RUAms7TZ0L6EFrrBIPg4Dy7qD9vvD5lJKUxEXURLM= github.com/cosmos/iavl v1.3.4/go.mod h1:T6SfBcyhulVIY2G/ZtAtQm/QiJvsuhIos52V4dWYk88= +github.com/cosmos/iavl-bench/bench v0.0.4 h1:J6zQPiBqF4CXMM3QBsLqZgQEBGY0taX85vLIZMhmAfQ= +github.com/cosmos/iavl-bench/bench v0.0.4/go.mod h1:j2rLae77EffacWcp7mmj3Uaa4AOAmZA7ymvhsuBQKKI= +github.com/cosmos/iavl/v2 v2.0.0-alpha.4 h1:PfpQt7xl4hojw2UFS2JdJppJnx8sjlmcxRQ7Hxk7Cl0= +github.com/cosmos/iavl/v2 v2.0.0-alpha.4/go.mod h1:7RSm0aeApe3S1x4TrLffvUL6pjOtMYV4glYnpAhr2lw= github.com/cosmos/ics23/go v0.11.0 h1:jk5skjT0TqX5e5QJbEnwXIS2yI2vnmLOgpQPeM5RtnU= github.com/cosmos/ics23/go v0.11.0/go.mod h1:A8OjxPE67hHST4Icw94hOxxFEJMBG031xIGF/JHNIY0= github.com/cosmos/keyring v1.2.0 h1:8C1lBP9xhImmIabyXW4c3vFjjLiBdGCmfLUfeZlV1Yo= @@ -638,6 +646,8 @@ github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa02 github.com/klauspost/cpuid/v2 v2.2.9 h1:66ze0taIn2H33fBvCkXuv9BmCwDfafmiIVpKV9kKGuY= github.com/klauspost/cpuid/v2 v2.2.9/go.mod h1:rqkxqrZ1EhYM9G+hXH7YdowN5R5RGN6NK4QwQ3WMXF8= github.com/knz/go-libedit v1.10.1/go.mod h1:MZTVkCWyz0oBc7JOWP3wNAzd002ZbM/5hgShxwh4x8M= +github.com/kocubinski/costor-api v1.1.1 h1:sgfJA7T/8IfZ59zxiMrED0xdjerAFuPNBTqyO90GiEE= +github.com/kocubinski/costor-api v1.1.1/go.mod h1:ESMBMDkKfN+9vvvhhNVdKLhbOmzI3O/i16iXvRM9Tuc= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= @@ -843,8 +853,8 @@ gitlab.com/yawning/secp256k1-voi v0.0.0-20230925100816-f2616030848b h1:CzigHMRyS gitlab.com/yawning/secp256k1-voi v0.0.0-20230925100816-f2616030848b/go.mod h1:/y/V339mxv2sZmYYR64O07VuCpdNZqCTwO8ZcouTMI8= gitlab.com/yawning/tuplehash v0.0.0-20230713102510-df83abbf9a02 h1:qwDnMxjkyLmAFgcfgTnfJrmYKWhHnci3GjDqcZp1M3Q= gitlab.com/yawning/tuplehash v0.0.0-20230713102510-df83abbf9a02/go.mod h1:JTnUj0mpYiAsuZLmKjTx/ex3AtMowcCgnE7YNyCEP0I= -go.etcd.io/bbolt v1.4.0-alpha.0.0.20240404170359-43604f3112c5 h1:qxen9oVGzDdIRP6ejyAJc760RwW4SnVDiTYTzwnXuxo= -go.etcd.io/bbolt v1.4.0-alpha.0.0.20240404170359-43604f3112c5/go.mod h1:eW0HG9/oHQhvRCvb1/pIXW4cOvtDqeQK+XSi3TnwaXY= +go.etcd.io/bbolt v1.4.0-alpha.1 h1:3yrqQzbRRPFPdOMWS/QQIVxVnzSkAZQYeWlZFv1kbj4= +go.etcd.io/bbolt v1.4.0-alpha.1/go.mod h1:S/Z/Nm3iuOnyO1W4XuFfPci51Gj6F1Hv0z8hisyYYOw= go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= diff --git a/store/v2/commitment/iavl/tree.go b/store/v2/commitment/iavl/tree.go index 4aaac08ab8bf..1769bc45126e 100644 --- a/store/v2/commitment/iavl/tree.go +++ b/store/v2/commitment/iavl/tree.go @@ -199,3 +199,7 @@ func (t *IavlTree) Import(version uint64) (commitment.Importer, error) { func (t *IavlTree) Close() error { return t.tree.Close() } + +func (t *IavlTree) IsConcurrentSafe() bool { + return false +} diff --git a/store/v2/commitment/iavlv2/snapshot.go b/store/v2/commitment/iavlv2/snapshot.go new file mode 100644 index 000000000000..ad3a8bada0d9 --- /dev/null +++ b/store/v2/commitment/iavlv2/snapshot.go @@ -0,0 +1,59 @@ +package iavlv2 + +import ( + "errors" + + "github.com/cosmos/iavl/v2" + + "cosmossdk.io/store/v2/commitment" + snapshotstypes "cosmossdk.io/store/v2/snapshots/types" +) + +// Exporter is a wrapper around iavl.Exporter. +type Exporter struct { + exporter *iavl.Exporter +} + +// Next returns the next item in the exporter. +func (e *Exporter) Next() (*snapshotstypes.SnapshotIAVLItem, error) { + item, err := e.exporter.Next() + if err != nil { + if errors.Is(err, iavl.ErrorExportDone) { + return nil, commitment.ErrorExportDone + } + return nil, err + } + + return &snapshotstypes.SnapshotIAVLItem{ + Key: item.Key(), + Value: item.Value(), + Version: item.Version(), + Height: int32(item.Height()), + }, nil +} + +// Close closes the exporter. +func (e *Exporter) Close() error { + return e.exporter.Close() +} + +type Importer struct { + importer *iavl.Importer +} + +// Add adds the given item to the importer. +func (i *Importer) Add(item *snapshotstypes.SnapshotIAVLItem) error { + return i.importer.Add(iavl.NewImportNode(item.Key, item.Value, item.Version, int8(item.Height))) +} + +// Commit commits the importer. +func (i *Importer) Commit() error { + return i.importer.Commit() +} + +// Close closes the importer. +func (i *Importer) Close() error { + i.importer.Close() + + return nil +} diff --git a/store/v2/commitment/iavlv2/tree.go b/store/v2/commitment/iavlv2/tree.go index 43c25a23a2c8..e4ea00858167 100644 --- a/store/v2/commitment/iavlv2/tree.go +++ b/store/v2/commitment/iavlv2/tree.go @@ -1,12 +1,12 @@ package iavlv2 import ( - "errors" "fmt" "github.com/cosmos/iavl/v2" ics23 "github.com/cosmos/ics23/go" + "cosmossdk.io/core/log" corestore "cosmossdk.io/core/store" "cosmossdk.io/store/v2" "cosmossdk.io/store/v2/commitment" @@ -20,15 +20,22 @@ var ( type Tree struct { tree *iavl.Tree + log log.Logger + path string } -func NewTree(treeOptions iavl.TreeOptions, dbOptions iavl.SqliteDbOptions, pool *iavl.NodePool) (*Tree, error) { +func NewTree( + treeOptions iavl.TreeOptions, + dbOptions iavl.SqliteDbOptions, + log log.Logger, +) (*Tree, error) { + pool := iavl.NewNodePool() sql, err := iavl.NewSqliteDb(pool, dbOptions) if err != nil { return nil, err } tree := iavl.NewTree(sql, pool, treeOptions) - return &Tree{tree: tree}, nil + return &Tree{tree: tree, log: log, path: dbOptions.Path}, nil } func (t *Tree) Set(key, value []byte) error { @@ -58,14 +65,11 @@ func (t *Tree) LoadVersion(version uint64) error { return err } - if version == 0 { - return nil - } return t.tree.LoadVersion(int64(version)) } func (t *Tree) LoadVersionForOverwriting(version uint64) error { - return t.LoadVersion(version) // TODO: implement overwriting + return t.LoadVersion(version) } func (t *Tree) Commit() ([]byte, uint64, error) { @@ -92,28 +96,53 @@ func (t *Tree) Get(version uint64, key []byte) ([]byte, error) { if err := isHighBitSet(version); err != nil { return nil, err } - if int64(version) != t.tree.Version() { - cloned, err := t.tree.ReadonlyClone() - if err != nil { - return nil, err - } - if err = cloned.LoadVersion(int64(version)); err != nil { - return nil, err - } - return cloned.Get(key) - } else { - return t.tree.Get(key) + v := int64(version) + h := t.tree.Version() + if v > h { + return nil, fmt.Errorf("get: cannot read future version %d; h: %d path=%s", v, h, t.path) + } + versionFound, val, err := t.tree.GetRecent(v, key) + if versionFound { + return val, err + } + cloned, err := t.tree.ReadonlyClone() + if err != nil { + return nil, err + } + if err = cloned.LoadVersion(int64(version)); err != nil { + return nil, err } + return cloned.Get(key) +} + +func (t *Tree) Has(version uint64, key []byte) (bool, error) { + res, err := t.Get(version, key) + return res != nil, err } func (t *Tree) Iterator(version uint64, start, end []byte, ascending bool) (corestore.Iterator, error) { if err := isHighBitSet(version); err != nil { return nil, err } - if int64(version) != t.tree.Version() { - return nil, fmt.Errorf("loading past version not yet supported") + h := t.tree.Version() + v := int64(version) + if v > h { + return nil, fmt.Errorf("iterator: cannot read future version %d; h: %d", v, h) + } + ok, itr := t.tree.IterateRecent(v, start, end, ascending) + if ok { + return itr, nil + } + cloned, err := t.tree.ReadonlyClone() + if err != nil { + return nil, err + } + if err = cloned.LoadVersion(int64(version)); err != nil { + return nil, err } if ascending { + // inclusive = false is IAVL v1's default behavior. + // the read expectations of certain modules (like x/staking) will cause a panic if this is changed. return t.tree.Iterator(start, end, false) } else { return t.tree.ReverseIterator(start, end) @@ -121,11 +150,25 @@ func (t *Tree) Iterator(version uint64, start, end []byte, ascending bool) (core } func (t *Tree) Export(version uint64) (commitment.Exporter, error) { - return nil, errors.New("snapshot import/export not yet supported") + if err := isHighBitSet(version); err != nil { + return nil, err + } + e, err := t.tree.Export(int64(version), iavl.PostOrder) + if err != nil { + return nil, err + } + return &Exporter{e}, nil } func (t *Tree) Import(version uint64) (commitment.Importer, error) { - return nil, errors.New("snapshot import/export not yet supported") + if err := isHighBitSet(version); err != nil { + return nil, err + } + importer, err := t.tree.Import(int64(version)) + if err != nil { + return nil, err + } + return &Importer{importer}, nil } func (t *Tree) Close() error { @@ -133,16 +176,17 @@ func (t *Tree) Close() error { } func (t *Tree) Prune(version uint64) error { - if err := isHighBitSet(version); err != nil { - return err - } - - return t.tree.DeleteVersionsTo(int64(version)) + // do nothing, IAVL v2 has its own advanced pruning mechanism + return nil } // PausePruning is unnecessary in IAVL v2 due to the advanced pruning mechanism func (t *Tree) PausePruning(bool) {} +func (t *Tree) IsConcurrentSafe() bool { + return true +} + func (t *Tree) WorkingHash() []byte { return t.tree.Hash() } @@ -153,3 +197,17 @@ func isHighBitSet(version uint64) error { } return nil } + +func DefaultOptions(keepVersions int64) iavl.TreeOptions { + opts := iavl.DefaultTreeOptions() + opts.MinimumKeepVersions = keepVersions + opts.CheckpointInterval = 200 + opts.PruneRatio = 1 + opts.HeightFilter = 1 + opts.EvictionDepth = 22 + return opts +} + +func SetGlobalPruneLimit(limit int) { + iavl.SetGlobalPruneLimit(limit) +} diff --git a/store/v2/commitment/iavlv2/tree_test.go b/store/v2/commitment/iavlv2/tree_test.go index a173c453c976..77822615871c 100644 --- a/store/v2/commitment/iavlv2/tree_test.go +++ b/store/v2/commitment/iavlv2/tree_test.go @@ -14,7 +14,6 @@ import ( ) func TestCommitterSuite(t *testing.T) { - nodePool := iavl.NewNodePool() s := &commitment.CommitStoreTestSuite{ TreeType: "iavlv2", NewStore: func( @@ -26,7 +25,7 @@ func TestCommitterSuite(t *testing.T) { multiTrees := make(map[string]commitment.Tree) mountTreeFn := func(storeKey string) (commitment.Tree, error) { path := fmt.Sprintf("%s/%s", dbDir, storeKey) - tree, err := NewTree(iavl.DefaultTreeOptions(), iavl.SqliteDbOptions{Path: path}, nodePool) + tree, err := NewTree(iavl.DefaultTreeOptions(), iavl.SqliteDbOptions{Path: path}, logger) require.NoError(t, err) return tree, nil } diff --git a/store/v2/commitment/mem/tree.go b/store/v2/commitment/mem/tree.go index bf0e95bfa9c1..15e2d1083909 100644 --- a/store/v2/commitment/mem/tree.go +++ b/store/v2/commitment/mem/tree.go @@ -69,3 +69,7 @@ func (t *Tree) Import(version uint64) (commitment.Importer, error) { func New() *Tree { return &Tree{MemDB: db.NewMemDB()} } + +func (t *Tree) IsConcurrentSafe() bool { + return false +} diff --git a/store/v2/commitment/store.go b/store/v2/commitment/store.go index aa383b57ae56..757fb45851c1 100644 --- a/store/v2/commitment/store.go +++ b/store/v2/commitment/store.go @@ -9,6 +9,7 @@ import ( "slices" protoio "github.com/cosmos/gogoproto/io" + "golang.org/x/sync/errgroup" corelog "cosmossdk.io/core/log" corestore "cosmossdk.io/core/store" @@ -61,6 +62,8 @@ func NewCommitStore(trees, oldTrees map[string]Tree, db corestore.KVStoreWithBat } func (c *CommitStore) WriteChangeset(cs *corestore.Changeset) error { + eg := new(errgroup.Group) + eg.SetLimit(store.MaxWriteParallelism) for _, pairs := range cs.Changes { key := conv.UnsafeBytesToStr(pairs.Actor) @@ -68,17 +71,30 @@ func (c *CommitStore) WriteChangeset(cs *corestore.Changeset) error { if !ok { return fmt.Errorf("store key %s not found in multiTrees", key) } - for _, kv := range pairs.StateChanges { - if kv.Remove { - if err := tree.Remove(kv.Key); err != nil { - return err - } - } else if err := tree.Set(kv.Key, kv.Value); err != nil { + if tree.IsConcurrentSafe() { + eg.Go(func() error { + return writeChangeset(tree, pairs) + }) + } else { + if err := writeChangeset(tree, pairs); err != nil { return err } } } + return eg.Wait() +} + +func writeChangeset(tree Tree, changes corestore.StateChanges) error { + for _, kv := range changes.StateChanges { + if kv.Remove { + if err := tree.Remove(kv.Key); err != nil { + return err + } + } else if err := tree.Set(kv.Key, kv.Value); err != nil { + return err + } + } return nil } @@ -162,18 +178,35 @@ func (c *CommitStore) loadVersion(targetVersion uint64, storeKeys []string, over } } + eg := errgroup.Group{} + eg.SetLimit(store.MaxWriteParallelism) for _, storeKey := range storeKeys { + tree := c.multiTrees[storeKey] if overrideAfter { - if err := c.multiTrees[storeKey].LoadVersionForOverwriting(targetVersion); err != nil { - return err + if tree.IsConcurrentSafe() { + eg.Go(func() error { + return c.multiTrees[storeKey].LoadVersionForOverwriting(targetVersion) + }) + } else { + if err := c.multiTrees[storeKey].LoadVersionForOverwriting(targetVersion); err != nil { + return err + } } } else { - if err := c.multiTrees[storeKey].LoadVersion(targetVersion); err != nil { - return err + if tree.IsConcurrentSafe() { + eg.Go(func() error { return c.multiTrees[storeKey].LoadVersion(targetVersion) }) + } else { + if err := c.multiTrees[storeKey].LoadVersion(targetVersion); err != nil { + return err + } } } } + if err := eg.Wait(); err != nil { + return err + } + // If the target version is greater than the latest version, it is the snapshot // restore case, we should create a new commit info for the target version. if targetVersion > latestVersion { @@ -188,27 +221,31 @@ func (c *CommitStore) loadVersion(targetVersion uint64, storeKeys []string, over } func (c *CommitStore) Commit(version uint64) (*proof.CommitInfo, error) { - storeInfos := make([]proof.StoreInfo, 0, len(c.multiTrees)) + storeInfos := make([]*proof.StoreInfo, 0, len(c.multiTrees)) + eg := new(errgroup.Group) + eg.SetLimit(store.MaxWriteParallelism) for storeKey, tree := range c.multiTrees { if internal.IsMemoryStoreKey(storeKey) { continue } - hash, cversion, err := tree.Commit() - if err != nil { - return nil, err - } - if cversion != version { - return nil, fmt.Errorf("commit version %d does not match the target version %d", cversion, version) - } - commitID := proof.CommitID{ - Version: version, - Hash: hash, + si := &proof.StoreInfo{Name: []byte(storeKey)} + storeInfos = append(storeInfos, si) + + if tree.IsConcurrentSafe() { + eg.Go(func() error { + err := c.commit(tree, si, version) + if err != nil { + return fmt.Errorf("commit fail: %s: %w", si.Name, err) + } + return nil + }) + } else { + err := c.commit(tree, si, version) + if err != nil { + return nil, err + } } - storeInfos = append(storeInfos, proof.StoreInfo{ - Name: []byte(storeKey), - CommitID: commitID, - }) } cInfo := &proof.CommitInfo{ @@ -216,6 +253,10 @@ func (c *CommitStore) Commit(version uint64) (*proof.CommitInfo, error) { StoreInfos: storeInfos, } + if err := eg.Wait(); err != nil { + return nil, err + } + if err := c.metadata.flushCommitInfo(version, cInfo); err != nil { return nil, err } @@ -223,6 +264,21 @@ func (c *CommitStore) Commit(version uint64) (*proof.CommitInfo, error) { return cInfo, nil } +func (c *CommitStore) commit(tree Tree, si *proof.StoreInfo, expected uint64) error { + h, v, err := tree.Commit() + if err != nil { + return err + } + if v != expected { + return fmt.Errorf("commit version %d does not match the target version %d", v, expected) + } + si.CommitID = &proof.CommitID{ + Version: v, + Hash: h, + } + return nil +} + func (c *CommitStore) SetInitialVersion(version uint64) error { for _, tree := range c.multiTrees { if err := tree.SetInitialVersion(version); err != nil { @@ -531,7 +587,7 @@ func (c *CommitStore) GetCommitInfo(version uint64) (*proof.CommitInfo, error) { return ci, nil } // otherwise built the commit info from the trees - storeInfos := make([]proof.StoreInfo, 0, len(c.multiTrees)) + storeInfos := make([]*proof.StoreInfo, 0, len(c.multiTrees)) for storeKey, tree := range c.multiTrees { if internal.IsMemoryStoreKey(storeKey) { continue @@ -541,9 +597,9 @@ func (c *CommitStore) GetCommitInfo(version uint64) (*proof.CommitInfo, error) { return nil, fmt.Errorf("tree version %d does not match the target version %d", v, version) } bz := []byte(storeKey) - storeInfos = append(storeInfos, proof.StoreInfo{ + storeInfos = append(storeInfos, &proof.StoreInfo{ Name: bz, - CommitID: proof.CommitID{ + CommitID: &proof.CommitID{ Version: v, Hash: tree.Hash(), }, diff --git a/store/v2/commitment/store_test_suite.go b/store/v2/commitment/store_test_suite.go index b91119301c1e..76d1029a74a9 100644 --- a/store/v2/commitment/store_test_suite.go +++ b/store/v2/commitment/store_test_suite.go @@ -66,9 +66,6 @@ type CommitStoreTestSuite struct { // - Checks that the restored store's Merkle tree hashes match the original // - Ensures store integrity by comparing CommitInfo hashes func (s *CommitStoreTestSuite) TestStore_Snapshotter() { - if s.TreeType == "iavlv2" { - s.T().Skip("FIXME: iavlv2 does not yet support snapshots") - } storeKeys := []string{storeKey1, storeKey2} commitStore, err := s.NewStore(dbm.NewMemDB(), s.T().TempDir(), storeKeys, nil, coretesting.NewNopLogger()) s.Require().NoError(err) diff --git a/store/v2/commitment/tree.go b/store/v2/commitment/tree.go index 58a8b20beff2..03f1f3c80a72 100644 --- a/store/v2/commitment/tree.go +++ b/store/v2/commitment/tree.go @@ -34,6 +34,8 @@ type Tree interface { Export(version uint64) (Exporter, error) Import(version uint64) (Importer, error) + IsConcurrentSafe() bool + io.Closer } diff --git a/store/v2/database.go b/store/v2/database.go index 0e0697de57bb..7c6b242e257b 100644 --- a/store/v2/database.go +++ b/store/v2/database.go @@ -18,6 +18,13 @@ type VersionedReader interface { ReverseIterator(storeKey []byte, version uint64, start, end []byte) (corestore.Iterator, error) } +type LatestReader interface { + Has(storeKey, key []byte) (bool, error) + Get(storeKey, key []byte) ([]byte, error) + Iterator(storeKey, start, end []byte) (corestore.Iterator, error) + ReverseIterator(storeKey, start, end []byte) (corestore.Iterator, error) +} + // UpgradableDatabase defines an API for a versioned database that allows pruning // deleted storeKeys type UpgradableDatabase interface { diff --git a/store/v2/go.mod b/store/v2/go.mod index 6223bfc08e4e..27cddd3f37e8 100644 --- a/store/v2/go.mod +++ b/store/v2/go.mod @@ -11,7 +11,7 @@ require ( github.com/cosmos/cosmos-proto v1.0.0-beta.5 github.com/cosmos/gogoproto v1.7.0 github.com/cosmos/iavl v1.3.4 - github.com/cosmos/iavl/v2 v2.0.0-20241128205019-1b18c0edbbd9 + github.com/cosmos/iavl/v2 v2.0.0-alpha.4 github.com/cosmos/ics23/go v0.11.0 github.com/google/btree v1.1.3 github.com/hashicorp/go-metrics v0.5.3 diff --git a/store/v2/go.sum b/store/v2/go.sum index 45aa36096be2..83c4e676f6d3 100644 --- a/store/v2/go.sum +++ b/store/v2/go.sum @@ -61,8 +61,8 @@ github.com/cosmos/iavl v1.3.4 h1:A0RUAms7TZ0L6EFrrBIPg4Dy7qD9vvD5lJKUxEXURLM= github.com/cosmos/iavl v1.3.4/go.mod h1:T6SfBcyhulVIY2G/ZtAtQm/QiJvsuhIos52V4dWYk88= github.com/cosmos/iavl-bench/bench v0.0.4 h1:J6zQPiBqF4CXMM3QBsLqZgQEBGY0taX85vLIZMhmAfQ= github.com/cosmos/iavl-bench/bench v0.0.4/go.mod h1:j2rLae77EffacWcp7mmj3Uaa4AOAmZA7ymvhsuBQKKI= -github.com/cosmos/iavl/v2 v2.0.0-20241128205019-1b18c0edbbd9 h1:H+ttW6HTzezz2l3Fp/hFNNHWA+a+7qZgNDE5OFySTiY= -github.com/cosmos/iavl/v2 v2.0.0-20241128205019-1b18c0edbbd9/go.mod h1:7RSm0aeApe3S1x4TrLffvUL6pjOtMYV4glYnpAhr2lw= +github.com/cosmos/iavl/v2 v2.0.0-alpha.4 h1:PfpQt7xl4hojw2UFS2JdJppJnx8sjlmcxRQ7Hxk7Cl0= +github.com/cosmos/iavl/v2 v2.0.0-alpha.4/go.mod h1:7RSm0aeApe3S1x4TrLffvUL6pjOtMYV4glYnpAhr2lw= github.com/cosmos/ics23/go v0.11.0 h1:jk5skjT0TqX5e5QJbEnwXIS2yI2vnmLOgpQPeM5RtnU= github.com/cosmos/ics23/go v0.11.0/go.mod h1:A8OjxPE67hHST4Icw94hOxxFEJMBG031xIGF/JHNIY0= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= diff --git a/store/v2/proof/commit_info.go b/store/v2/proof/commit_info.go index b784676a8d34..0ca52bd8dd87 100644 --- a/store/v2/proof/commit_info.go +++ b/store/v2/proof/commit_info.go @@ -14,7 +14,7 @@ type ( // a version/height. CommitInfo struct { Version uint64 - StoreInfos []StoreInfo + StoreInfos []*StoreInfo Timestamp time.Time CommitHash []byte } @@ -23,7 +23,7 @@ type ( // between a store name/key and the commit ID. StoreInfo struct { Name []byte - CommitID CommitID + CommitID *CommitID Structure string } @@ -55,13 +55,13 @@ func (ci *CommitInfo) Hash() []byte { } // GetStoreCommitID returns the CommitID for the given store key. -func (ci *CommitInfo) GetStoreCommitID(storeKey []byte) CommitID { +func (ci *CommitInfo) GetStoreCommitID(storeKey []byte) *CommitID { for _, si := range ci.StoreInfos { if bytes.Equal(si.Name, storeKey) { return si.CommitID } } - return CommitID{} + return &CommitID{} } // GetStoreProof takes in a storeKey and returns a proof of the store key in addition @@ -171,8 +171,9 @@ func (ci *CommitInfo) Unmarshal(buf []byte) error { return err } buf = buf[n:] - ci.StoreInfos = make([]StoreInfo, storeInfosLen) + ci.StoreInfos = make([]*StoreInfo, storeInfosLen) for i := 0; i < int(storeInfosLen); i++ { + ci.StoreInfos[i] = &StoreInfo{} // Name name, n, err := encoding.DecodeBytes(buf) if err != nil { @@ -194,7 +195,7 @@ func (ci *CommitInfo) Unmarshal(buf []byte) error { buf = buf[n:] ci.StoreInfos[i].Structure = string(structure) - ci.StoreInfos[i].CommitID = CommitID{ + ci.StoreInfos[i].CommitID = &CommitID{ Hash: hash, Version: ci.Version, } @@ -203,24 +204,24 @@ func (ci *CommitInfo) Unmarshal(buf []byte) error { return nil } -func (ci *CommitInfo) CommitID() CommitID { - return CommitID{ +func (ci *CommitInfo) CommitID() *CommitID { + return &CommitID{ Version: ci.Version, Hash: ci.Hash(), } } -func (m *CommitInfo) GetVersion() uint64 { - if m != nil { - return m.Version +func (ci *CommitInfo) GetVersion() uint64 { + if ci != nil { + return ci.Version } return 0 } -func (cid CommitID) String() string { +func (cid *CommitID) String() string { return fmt.Sprintf("CommitID{%v:%X}", cid.Hash, cid.Version) } -func (cid CommitID) IsZero() bool { +func (cid *CommitID) IsZero() bool { return cid.Version == 0 && len(cid.Hash) == 0 } diff --git a/store/v2/proof/commit_info_test.go b/store/v2/proof/commit_info_test.go index e09449c51963..1c0221fe6360 100644 --- a/store/v2/proof/commit_info_test.go +++ b/store/v2/proof/commit_info_test.go @@ -10,37 +10,37 @@ import ( func TestGetStoreProof(t *testing.T) { tests := []struct { - storeInfos []StoreInfo + storeInfos []*StoreInfo }{ - {[]StoreInfo{ - {[]byte("key1"), CommitID{1, []byte("value1")}, "iavl"}, + {[]*StoreInfo{ + {[]byte("key1"), &CommitID{1, []byte("value1")}, "iavl"}, }}, - {[]StoreInfo{ - {[]byte("key2"), CommitID{1, []byte("value2")}, "iavl"}, - {[]byte("key1"), CommitID{1, []byte("value1")}, "iavl"}, + {[]*StoreInfo{ + {[]byte("key2"), &CommitID{1, []byte("value2")}, "iavl"}, + {[]byte("key1"), &CommitID{1, []byte("value1")}, "iavl"}, }}, - {[]StoreInfo{ - {[]byte("key3"), CommitID{1, []byte("value3")}, "iavl"}, - {[]byte("key2"), CommitID{1, []byte("value2")}, "iavl"}, - {[]byte("key1"), CommitID{1, []byte("value1")}, "iavl"}, + {[]*StoreInfo{ + {[]byte("key3"), &CommitID{1, []byte("value3")}, "iavl"}, + {[]byte("key2"), &CommitID{1, []byte("value2")}, "iavl"}, + {[]byte("key1"), &CommitID{1, []byte("value1")}, "iavl"}, }}, - {[]StoreInfo{ - {[]byte("key2"), CommitID{1, []byte("value2")}, "iavl"}, - {[]byte("key1"), CommitID{1, []byte("value1")}, "iavl"}, - {[]byte("key3"), CommitID{1, []byte("value3")}, "iavl"}, + {[]*StoreInfo{ + {[]byte("key2"), &CommitID{1, []byte("value2")}, "iavl"}, + {[]byte("key1"), &CommitID{1, []byte("value1")}, "iavl"}, + {[]byte("key3"), &CommitID{1, []byte("value3")}, "iavl"}, }}, - {[]StoreInfo{ - {[]byte("key4"), CommitID{1, []byte("value4")}, "iavl"}, - {[]byte("key1"), CommitID{1, []byte("value1")}, "iavl"}, - {[]byte("key3"), CommitID{1, []byte("value3")}, "iavl"}, - {[]byte("key2"), CommitID{1, []byte("value2")}, "iavl"}, + {[]*StoreInfo{ + {[]byte("key4"), &CommitID{1, []byte("value4")}, "iavl"}, + {[]byte("key1"), &CommitID{1, []byte("value1")}, "iavl"}, + {[]byte("key3"), &CommitID{1, []byte("value3")}, "iavl"}, + {[]byte("key2"), &CommitID{1, []byte("value2")}, "iavl"}, }}, } for i, tc := range tests { t.Run(fmt.Sprintf("%d", i), func(t *testing.T) { // create a commit info - ci := CommitInfo{ + ci := &CommitInfo{ Version: 1, Timestamp: time.Now(), StoreInfos: tc.storeInfos, @@ -59,7 +59,7 @@ func TestGetStoreProof(t *testing.T) { bz, err := ci.Marshal() require.NoError(t, err) - var ci2 CommitInfo + ci2 := &CommitInfo{} err = ci2.Unmarshal(bz) require.NoError(t, err) require.True(t, ci.Timestamp.Equal(ci2.Timestamp)) diff --git a/store/v2/root/factory.go b/store/v2/root/factory.go index c908432c9a29..b568792641ad 100644 --- a/store/v2/root/factory.go +++ b/store/v2/root/factory.go @@ -4,11 +4,14 @@ import ( "errors" "fmt" + iavl_v2 "github.com/cosmos/iavl/v2" + "cosmossdk.io/core/log" corestore "cosmossdk.io/core/store" "cosmossdk.io/store/v2" "cosmossdk.io/store/v2/commitment" "cosmossdk.io/store/v2/commitment/iavl" + "cosmossdk.io/store/v2/commitment/iavlv2" "cosmossdk.io/store/v2/commitment/mem" "cosmossdk.io/store/v2/db" "cosmossdk.io/store/v2/internal" @@ -30,6 +33,7 @@ type Options struct { SCType SCType `mapstructure:"sc-type" toml:"sc-type" comment:"State commitment database type. Currently we support: \"iavl\" and \"iavl-v2\""` SCPruningOption *store.PruningOption `mapstructure:"sc-pruning-option" toml:"sc-pruning-option" comment:"Pruning options for state commitment"` IavlConfig *iavl.Config `mapstructure:"iavl-config" toml:"iavl-config"` + IavlV2Config iavl_v2.TreeOptions } // FactoryOptions are the options for creating a root store. @@ -50,7 +54,7 @@ func DefaultStoreOptions() Options { Interval: 100, }, IavlConfig: &iavl.Config{ - CacheSize: 100_000, + CacheSize: 500_000, SkipFastStorageUpgrade: true, }, } @@ -98,7 +102,8 @@ func CreateRootStore(opts *FactoryOptions) (store.RootStore, error) { case SCTypeIavl: return iavl.NewIavlTree(db.NewPrefixDB(opts.SCRawDB, []byte(key)), opts.Logger, storeOpts.IavlConfig), nil case SCTypeIavlV2: - return nil, errors.New("iavl v2 not supported") + dir := fmt.Sprintf("%s/data/iavl-v2/%s", opts.RootDir, key) + return iavlv2.NewTree(opts.Options.IavlV2Config, iavl_v2.SqliteDbOptions{Path: dir}, opts.Logger) default: return nil, errors.New("unsupported commitment store type") } diff --git a/store/v2/root/factory_test.go b/store/v2/root/factory_test.go index 45fd34699bf7..1da5e4309ab8 100644 --- a/store/v2/root/factory_test.go +++ b/store/v2/root/factory_test.go @@ -24,6 +24,6 @@ func TestFactory(t *testing.T) { fop.Options.SCType = SCTypeIavlV2 f, err = CreateRootStore(&fop) - require.Error(t, err) - require.Nil(t, f) + require.NoError(t, err) + require.NotNil(t, f) } diff --git a/store/v2/root/store.go b/store/v2/root/store.go index ab22d3f90117..3104260d11b3 100644 --- a/store/v2/root/store.go +++ b/store/v2/root/store.go @@ -114,6 +114,12 @@ func (s *Store) getVersionedReader(version uint64) (store.VersionedReader, error return nil, fmt.Errorf("version %d does not exist", version) } +// StateAt returns a read-only view of the state at a given version. +func (s *Store) StateAt(v uint64) (corestore.ReaderMap, error) { + vReader, err := s.getVersionedReader(v) + return NewReaderMap(v, vReader), err +} + func (s *Store) StateLatest() (uint64, corestore.ReaderMap, error) { v, err := s.GetLatestVersion() if err != nil { @@ -127,12 +133,6 @@ func (s *Store) StateLatest() (uint64, corestore.ReaderMap, error) { return v, NewReaderMap(v, vReader), nil } -// StateAt returns a read-only view of the state at a given version. -func (s *Store) StateAt(v uint64) (corestore.ReaderMap, error) { - vReader, err := s.getVersionedReader(v) - return NewReaderMap(v, vReader), err -} - func (s *Store) GetStateCommitment() store.Committer { return s.stateCommitment } @@ -142,7 +142,7 @@ func (s *Store) GetStateCommitment() store.Committer { // latest version set, which is based off of the SC view. func (s *Store) LastCommitID() (proof.CommitID, error) { if s.lastCommitInfo != nil { - return s.lastCommitInfo.CommitID(), nil + return *s.lastCommitInfo.CommitID(), nil } latestVersion, err := s.stateCommitment.GetLatestVersion() @@ -169,8 +169,7 @@ func (s *Store) GetLatestVersion() (uint64, error) { func (s *Store) Query(storeKey []byte, version uint64, key []byte, prove bool) (store.QueryResult, error) { if s.telemetry != nil { - now := time.Now() - defer s.telemetry.MeasureSince(now, "root_store", "query") + defer s.telemetry.MeasureSince(time.Now(), "root_store", "query") } val, err := s.stateCommitment.Get(storeKey, version, key) @@ -196,8 +195,7 @@ func (s *Store) Query(storeKey []byte, version uint64, key []byte, prove bool) ( func (s *Store) LoadLatestVersion() error { if s.telemetry != nil { - now := time.Now() - defer s.telemetry.MeasureSince(now, "root_store", "load_latest_version") + defer s.telemetry.MeasureSince(time.Now(), "root_store", "load_latest_version") } lv, err := s.GetLatestVersion() @@ -210,8 +208,7 @@ func (s *Store) LoadLatestVersion() error { func (s *Store) LoadVersion(version uint64) error { if s.telemetry != nil { - now := time.Now() - defer s.telemetry.MeasureSince(now, "root_store", "load_version") + defer s.telemetry.MeasureSince(time.Now(), "root_store", "load_version") } return s.loadVersion(version, nil, false) @@ -219,8 +216,7 @@ func (s *Store) LoadVersion(version uint64) error { func (s *Store) LoadVersionForOverwriting(version uint64) error { if s.telemetry != nil { - now := time.Now() - defer s.telemetry.MeasureSince(now, "root_store", "load_version_for_overwriting") + defer s.telemetry.MeasureSince(time.Now(), "root_store", "load_version_for_overwriting") } return s.loadVersion(version, nil, true) @@ -233,7 +229,6 @@ func (s *Store) LoadVersionAndUpgrade(version uint64, upgrades *corestore.StoreU if upgrades == nil { return errors.New("upgrades cannot be nil") } - if s.telemetry != nil { defer s.telemetry.MeasureSince(time.Now(), "root_store", "load_version_and_upgrade") } @@ -291,7 +286,9 @@ func (s *Store) loadVersion(v uint64, upgrades *corestore.StoreUpgrades, overrid func (s *Store) Commit(cs *corestore.Changeset) ([]byte, error) { if s.telemetry != nil { now := time.Now() - defer s.telemetry.MeasureSince(now, "root_store", "commit") + defer func() { + s.telemetry.MeasureSince(now, "root_store", "commit") + }() } if err := s.handleMigration(cs); err != nil { @@ -303,15 +300,17 @@ func (s *Store) Commit(cs *corestore.Changeset) ([]byte, error) { // background pruning process (iavl v1 for example) which must be paused during the commit s.pruningManager.PausePruning() - var cInfo *proof.CommitInfo + st := time.Now() if err := s.stateCommitment.WriteChangeset(cs); err != nil { return nil, fmt.Errorf("failed to write batch to SC store: %w", err) } - + writeDur := time.Since(st) + st = time.Now() cInfo, err := s.stateCommitment.Commit(cs.Version) if err != nil { return nil, fmt.Errorf("failed to commit SC store: %w", err) } + s.logger.Warn(fmt.Sprintf("commit version %d write=%s commit=%s", cs.Version, writeDur, time.Since(st))) if cInfo.Version != cs.Version { return nil, fmt.Errorf("commit version mismatch: got %d, expected %d", cInfo.Version, cs.Version) diff --git a/store/v2/store.go b/store/v2/store.go index 20c6ab3c8ef2..df91caca6180 100644 --- a/store/v2/store.go +++ b/store/v2/store.go @@ -8,6 +8,8 @@ import ( "cosmossdk.io/store/v2/proof" ) +var MaxWriteParallelism = 8 + // RootStore defines an abstraction layer containing a State Storage (SS) engine // and one or more State Commitment (SC) engines. type RootStore interface { diff --git a/tests/go.mod b/tests/go.mod index 7e72d7179461..baa60b91bddd 100644 --- a/tests/go.mod +++ b/tests/go.mod @@ -78,11 +78,13 @@ require ( github.com/DataDog/zstd v1.5.6 // indirect github.com/Microsoft/go-winio v0.6.1 // indirect github.com/aws/aws-sdk-go v1.55.5 // indirect + github.com/aybabtme/uniplot v0.0.0-20151203143629-039c559e5e7e // indirect github.com/beorn7/perks v1.0.1 // indirect github.com/bgentry/go-netrc v0.0.0-20140422174119-9fd32a8b3d3d // indirect github.com/bgentry/speakeasy v0.2.0 // indirect github.com/bits-and-blooms/bitset v1.10.0 // indirect github.com/bufbuild/protocompile v0.14.1 // indirect + github.com/bvinc/go-sqlite-lite v0.6.1 // indirect github.com/bytedance/sonic v1.12.6 // indirect github.com/bytedance/sonic/loader v0.2.1 // indirect github.com/cespare/xxhash/v2 v2.3.0 // indirect @@ -100,6 +102,7 @@ require ( github.com/cosmos/btcutil v1.0.5 // indirect github.com/cosmos/go-bip39 v1.0.0 // indirect github.com/cosmos/iavl v1.3.4 // indirect + github.com/cosmos/iavl/v2 v2.0.0-alpha.4 // indirect github.com/cosmos/ics23/go v0.11.0 // indirect github.com/cosmos/ledger-cosmos-go v0.14.0 // indirect github.com/danieljoos/wincred v1.2.1 // indirect @@ -153,6 +156,7 @@ require ( github.com/jmhodges/levigo v1.0.0 // indirect github.com/klauspost/compress v1.17.11 // indirect github.com/klauspost/cpuid/v2 v2.2.9 // indirect + github.com/kocubinski/costor-api v1.1.1 // indirect github.com/kr/pretty v0.3.1 // indirect github.com/kr/text v0.2.0 // indirect github.com/linxGnu/grocksdb v1.9.7 // indirect diff --git a/tests/go.sum b/tests/go.sum index 57e1f562bfa4..c5ab40323142 100644 --- a/tests/go.sum +++ b/tests/go.sum @@ -239,6 +239,8 @@ github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kd github.com/aws/aws-sdk-go v1.44.122/go.mod h1:y4AeaBuwd2Lk+GepC1E9v0qOiTws0MIWAX4oIKwKHZo= github.com/aws/aws-sdk-go v1.55.5 h1:KKUZBfBoyqy5d3swXyiC7Q76ic40rYcbqH7qjh59kzU= github.com/aws/aws-sdk-go v1.55.5/go.mod h1:eRwEWoyTWFMVYVQzKMNHWP5/RV4xIUGMQfXQHfHkpNU= +github.com/aybabtme/uniplot v0.0.0-20151203143629-039c559e5e7e h1:dSeuFcs4WAJJnswS8vXy7YY1+fdlbVPuEVmDAfqvFOQ= +github.com/aybabtme/uniplot v0.0.0-20151203143629-039c559e5e7e/go.mod h1:uh71c5Vc3VNIplXOFXsnDy21T1BepgT32c5X/YPrOyc= github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= @@ -256,6 +258,8 @@ github.com/btcsuite/btcd/btcutil v1.1.6 h1:zFL2+c3Lb9gEgqKNzowKUPQNb8jV7v5Oaodi/ github.com/btcsuite/btcd/btcutil v1.1.6/go.mod h1:9dFymx8HpuLqBnsPELrImQeTQfKBQqzqGbbV3jK55aE= github.com/bufbuild/protocompile v0.14.1 h1:iA73zAf/fyljNjQKwYzUHD6AD4R8KMasmwa/FBatYVw= github.com/bufbuild/protocompile v0.14.1/go.mod h1:ppVdAIhbr2H8asPk6k4pY7t9zB1OU5DoEw9xY/FUi1c= +github.com/bvinc/go-sqlite-lite v0.6.1 h1:JU8Rz5YAOZQiU3WEulKF084wfXpytRiqD2IaW2QjPz4= +github.com/bvinc/go-sqlite-lite v0.6.1/go.mod h1:2GiE60NUdb0aNhDdY+LXgrqAVDpi2Ijc6dB6ZMp9x6s= github.com/bytedance/sonic v1.12.6 h1:/isNmCUF2x3Sh8RAp/4mh4ZGkcFAX/hLrzrK3AvpRzk= github.com/bytedance/sonic v1.12.6/go.mod h1:B8Gt/XvtZ3Fqj+iSKMypzymZxw/FVwgIGKzMzT9r/rk= github.com/bytedance/sonic/loader v0.1.1/go.mod h1:ncP89zfokxS5LZrJxl5z0UJcsk4M4yY2JpfqGeCtNLU= @@ -327,6 +331,10 @@ github.com/cosmos/gogoproto v1.7.0 h1:79USr0oyXAbxg3rspGh/m4SWNyoz/GLaAh0QlCe2fr github.com/cosmos/gogoproto v1.7.0/go.mod h1:yWChEv5IUEYURQasfyBW5ffkMHR/90hiHgbNgrtp4j0= github.com/cosmos/iavl v1.3.4 h1:A0RUAms7TZ0L6EFrrBIPg4Dy7qD9vvD5lJKUxEXURLM= github.com/cosmos/iavl v1.3.4/go.mod h1:T6SfBcyhulVIY2G/ZtAtQm/QiJvsuhIos52V4dWYk88= +github.com/cosmos/iavl-bench/bench v0.0.4 h1:J6zQPiBqF4CXMM3QBsLqZgQEBGY0taX85vLIZMhmAfQ= +github.com/cosmos/iavl-bench/bench v0.0.4/go.mod h1:j2rLae77EffacWcp7mmj3Uaa4AOAmZA7ymvhsuBQKKI= +github.com/cosmos/iavl/v2 v2.0.0-alpha.4 h1:PfpQt7xl4hojw2UFS2JdJppJnx8sjlmcxRQ7Hxk7Cl0= +github.com/cosmos/iavl/v2 v2.0.0-alpha.4/go.mod h1:7RSm0aeApe3S1x4TrLffvUL6pjOtMYV4glYnpAhr2lw= github.com/cosmos/ics23/go v0.11.0 h1:jk5skjT0TqX5e5QJbEnwXIS2yI2vnmLOgpQPeM5RtnU= github.com/cosmos/ics23/go v0.11.0/go.mod h1:A8OjxPE67hHST4Icw94hOxxFEJMBG031xIGF/JHNIY0= github.com/cosmos/keyring v1.2.0 h1:8C1lBP9xhImmIabyXW4c3vFjjLiBdGCmfLUfeZlV1Yo= @@ -603,6 +611,8 @@ github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa02 github.com/klauspost/cpuid/v2 v2.2.9 h1:66ze0taIn2H33fBvCkXuv9BmCwDfafmiIVpKV9kKGuY= github.com/klauspost/cpuid/v2 v2.2.9/go.mod h1:rqkxqrZ1EhYM9G+hXH7YdowN5R5RGN6NK4QwQ3WMXF8= github.com/knz/go-libedit v1.10.1/go.mod h1:MZTVkCWyz0oBc7JOWP3wNAzd002ZbM/5hgShxwh4x8M= +github.com/kocubinski/costor-api v1.1.1 h1:sgfJA7T/8IfZ59zxiMrED0xdjerAFuPNBTqyO90GiEE= +github.com/kocubinski/costor-api v1.1.1/go.mod h1:ESMBMDkKfN+9vvvhhNVdKLhbOmzI3O/i16iXvRM9Tuc= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= diff --git a/tools/benchmark/client/cli/tx.go b/tools/benchmark/client/cli/tx.go index 55e46d305795..d9b5543d54fd 100644 --- a/tools/benchmark/client/cli/tx.go +++ b/tools/benchmark/client/cli/tx.go @@ -171,7 +171,7 @@ func NewLoadTestCmd(params *modulev1.GeneratorParams) *cobra.Command { successCount++ } if pause > 0 { - time.Sleep(time.Duration(pause) * time.Millisecond) + time.Sleep(time.Duration(pause) * time.Microsecond) } } }, @@ -180,7 +180,7 @@ func NewLoadTestCmd(params *modulev1.GeneratorParams) *cobra.Command { flags.AddTxFlagsToCmd(cmd) cmd.Flags().BoolVarP(&verbose, "verbose", "v", false, "print the response") cmd.Flags().Uint64Var(&numOps, "ops", 1, "number of operations per transaction") - cmd.Flags().Int64Var(&pause, "pause", 0, "pause between transactions in milliseconds") + cmd.Flags().Int64Var(&pause, "pause", 0, "pause between transactions in microseconds") return cmd }