feat(store/v2): full iavl/v2 support (#23131)

Co-authored-by: marbar3778 <marbar3778@yahoo.com>
Co-authored-by: auricom <27022259+auricom@users.noreply.github.com>
This commit is contained in:
Matt Kocubinski 2025-01-03 04:41:47 -06:00 committed by GitHub
parent 3d544c1ef3
commit 4f537d5231
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
31 changed files with 417 additions and 141 deletions

View File

@ -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

View File

@ -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]

View File

@ -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)/

View File

@ -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

View File

@ -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

View File

@ -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=

View File

@ -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()
}

View File

@ -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
}

View File

@ -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,

View File

@ -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

View File

@ -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=

View File

@ -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
}

View File

@ -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
}

View File

@ -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)
}

View File

@ -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
}

View File

@ -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
}

View File

@ -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
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
}
}
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,
}
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(),
},

View File

@ -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)

View File

@ -34,6 +34,8 @@ type Tree interface {
Export(version uint64) (Exporter, error)
Import(version uint64) (Importer, error)
IsConcurrentSafe() bool
io.Closer
}

View File

@ -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 {

View File

@ -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

View File

@ -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=

View File

@ -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
}

View File

@ -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))

View File

@ -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")
}

View File

@ -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)
}

View File

@ -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)

View File

@ -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 {

View File

@ -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

View File

@ -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=

View File

@ -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
}