diff --git a/app/app.go b/app/app.go index 7cd77b35e4..e9018efa04 100644 --- a/app/app.go +++ b/app/app.go @@ -1,16 +1,18 @@ package app import ( + "fmt" "io" "net/http" "os" "path/filepath" - "sync" + "github.com/crypto-org-chain/cronos/x/cronos" "github.com/crypto-org-chain/cronos/x/cronos/middleware" "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/codec/types" + "github.com/cosmos/cosmos-sdk/server" "github.com/gorilla/mux" "github.com/rakyll/statik/fs" "github.com/spf13/cast" @@ -20,13 +22,12 @@ import ( dbm "github.com/tendermint/tm-db" "github.com/cosmos/cosmos-sdk/baseapp" - "github.com/cosmos/cosmos-sdk/client/flags" "github.com/cosmos/cosmos-sdk/client/grpc/tmservice" "github.com/cosmos/cosmos-sdk/codec" "github.com/cosmos/cosmos-sdk/server/api" "github.com/cosmos/cosmos-sdk/server/config" servertypes "github.com/cosmos/cosmos-sdk/server/types" - "github.com/cosmos/cosmos-sdk/store/streaming/file" + "github.com/cosmos/cosmos-sdk/store/streaming" storetypes "github.com/cosmos/cosmos-sdk/store/types" "github.com/cosmos/cosmos-sdk/testutil/testdata" sdk "github.com/cosmos/cosmos-sdk/types" @@ -121,8 +122,9 @@ import ( gravitytypes "github.com/peggyjv/gravity-bridge/module/v2/x/gravity/types" // this line is used by starport scaffolding # stargate/app/moduleImport - cronosappclient "github.com/crypto-org-chain/cronos/client" - "github.com/crypto-org-chain/cronos/x/cronos" + + "github.com/crypto-org-chain/cronos/versiondb" + "github.com/crypto-org-chain/cronos/versiondb/tmdb" cronosclient "github.com/crypto-org-chain/cronos/x/cronos/client" cronoskeeper "github.com/crypto-org-chain/cronos/x/cronos/keeper" evmhandlers "github.com/crypto-org-chain/cronos/x/cronos/keeper/evmhandlers" @@ -146,8 +148,6 @@ const ( // // NOTE: In the SDK, the default value is 255. AddrLen = 20 - - FileStreamerDirectory = "file_streamer" ) // this line is used by starport scaffolding # stargate/wasm/app/enabledProposals @@ -347,29 +347,48 @@ func New( tkeys := sdk.NewTransientStoreKeys(paramstypes.TStoreKey, evmtypes.TransientKey, feemarkettypes.TransientKey) memKeys := sdk.NewMemoryStoreKeys(capabilitytypes.MemStoreKey) + // load state streaming if enabled + if _, _, err := streaming.LoadStreamingServices(bApp, appOpts, appCodec, keys); err != nil { + fmt.Printf("failed to load state streaming: %s", err) + os.Exit(1) + } + // configure state listening capabilities using AppOptions // we are doing nothing with the returned streamingServices and waitGroup in this case - // Only support file streamer right now. - if cast.ToString(appOpts.Get(cronosappclient.FlagStreamers)) == "file" { - streamingDir := filepath.Join(cast.ToString(appOpts.Get(flags.FlagHome)), "data", FileStreamerDirectory) - if err := os.MkdirAll(streamingDir, os.ModePerm); err != nil { - panic(err) - } - - // default to exposing all - exposeStoreKeys := make([]storetypes.StoreKey, 0, len(keys)) - for _, storeKey := range keys { - exposeStoreKeys = append(exposeStoreKeys, storeKey) - } - service, err := file.NewStreamingService(streamingDir, "", exposeStoreKeys, appCodec) - if err != nil { - panic(err) - } - bApp.SetStreamingService(service) - - wg := new(sync.WaitGroup) - if err := service.Stream(wg); err != nil { - panic(err) + streamers := cast.ToStringSlice(appOpts.Get("store.streamers")) + for _, streamerName := range streamers { + if streamerName == "versiondb" { + dataDir := filepath.Join(homePath, "data", "versiondb") + if err := os.MkdirAll(dataDir, os.ModePerm); err != nil { + panic(err) + } + backendType := server.GetAppDBBackend(appOpts) + plainDB, err := dbm.NewDB("plain", backendType, dataDir) + if err != nil { + panic(err) + } + historyDB, err := dbm.NewDB("history", backendType, dataDir) + if err != nil { + panic(err) + } + changesetDB, err := dbm.NewDB("changeset", backendType, dataDir) + if err != nil { + panic(err) + } + versionDB := tmdb.NewStore(plainDB, historyDB, changesetDB) + + // default to exposing all + exposeStoreKeys := make([]storetypes.StoreKey, 0, len(keys)) + for _, storeKey := range keys { + exposeStoreKeys = append(exposeStoreKeys, storeKey) + } + service := versiondb.NewStreamingService(versionDB, exposeStoreKeys) + bApp.SetStreamingService(service) + qms := versiondb.NewMultiStore(versionDB, exposeStoreKeys) + qms.MountTransientStores(tkeys) + qms.MountMemoryStores(memKeys) + bApp.SetQueryMultiStore(qms) + break } } diff --git a/client/flags.go b/client/flags.go deleted file mode 100644 index 96926045f6..0000000000 --- a/client/flags.go +++ /dev/null @@ -1,3 +0,0 @@ -package client - -const FlagStreamers = "streamers" diff --git a/cmd/cronosd/cmd/root.go b/cmd/cronosd/cmd/root.go index 3349481928..dded42544f 100644 --- a/cmd/cronosd/cmd/root.go +++ b/cmd/cronosd/cmd/root.go @@ -46,7 +46,6 @@ import ( ethermint "github.com/evmos/ethermint/types" "github.com/crypto-org-chain/cronos/app" - cronosclient "github.com/crypto-org-chain/cronos/client" // this line is used by starport scaffolding # stargate/root/import ) @@ -150,7 +149,6 @@ func initRootCmd(rootCmd *cobra.Command, encodingConfig params.EncodingConfig) { func addModuleInitFlags(startCmd *cobra.Command) { crisis.AddModuleInitFlags(startCmd) cronos.AddModuleInitFlags(startCmd) - startCmd.Flags().String(cronosclient.FlagStreamers, "", "Enable streamers, only file streamer is supported right now") // this line is used by starport scaffolding # stargate/root/initFlags } @@ -271,7 +269,7 @@ func (a appCreator) newApp(logger log.Logger, db dbm.DB, traceStore io.Writer, a baseapp.SetIndexEvents(cast.ToStringSlice(appOpts.Get(server.FlagIndexEvents))), baseapp.SetSnapshot(snapshotStore, snapshotOptions), baseapp.SetIAVLCacheSize(cast.ToInt(appOpts.Get(server.FlagIAVLCacheSize))), - baseapp.SetIAVLDisableFastNode(cast.ToBool(appOpts.Get(server.FlagIAVLFastNode))), + baseapp.SetIAVLDisableFastNode(cast.ToBool(appOpts.Get(server.FlagDisableIAVLFastNode))), ) } diff --git a/default.nix b/default.nix index fcbab2154a..0dd65d1259 100644 --- a/default.nix +++ b/default.nix @@ -27,6 +27,7 @@ buildGoApplication rec { "!/app/" "!/cmd/" "!/client/" + "!/versiondb/" "!go.mod" "!go.sum" "!gomod2nix.toml" diff --git a/go.mod b/go.mod index 17476fe929..3048a6be54 100644 --- a/go.mod +++ b/go.mod @@ -4,8 +4,10 @@ go 1.18 require ( cosmossdk.io/math v1.0.0-beta.3 + github.com/RoaringBitmap/roaring v1.2.1 github.com/armon/go-metrics v0.4.1 github.com/cosmos/cosmos-sdk v0.46.3 + github.com/cosmos/gogoproto v1.4.3 github.com/cosmos/ibc-go/v5 v5.0.0 github.com/ethereum/go-ethereum v1.10.19 github.com/evmos/ethermint v0.6.1-0.20221003153722-491c3da7ebd7 @@ -16,14 +18,14 @@ require ( github.com/peggyjv/gravity-bridge/module/v2 v2.0.0-20220420162017-838c0d25e974 github.com/rakyll/statik v0.1.7 github.com/spf13/cast v1.5.0 - github.com/spf13/cobra v1.5.0 + github.com/spf13/cobra v1.6.0 github.com/spf13/pflag v1.0.5 github.com/stretchr/testify v1.8.0 - github.com/tendermint/tendermint v0.34.22 + github.com/tendermint/tendermint v0.34.24 github.com/tendermint/tm-db v0.6.7 - google.golang.org/genproto v0.0.0-20220822174746-9e6da59bd2fc - google.golang.org/grpc v1.50.0 - google.golang.org/protobuf v1.28.1 + google.golang.org/genproto v0.0.0-20221014213838-99cd37c6964a + google.golang.org/grpc v1.50.1 + google.golang.org/protobuf v1.28.2-0.20220831092852-f930b1dc76e8 gopkg.in/yaml.v2 v2.4.0 ) @@ -45,6 +47,7 @@ require ( github.com/beorn7/perks v1.0.1 // indirect github.com/bgentry/go-netrc v0.0.0-20140422174119-9fd32a8b3d3d // indirect github.com/bgentry/speakeasy v0.1.0 // indirect + github.com/bits-and-blooms/bitset v1.2.0 // indirect github.com/btcsuite/btcd v0.22.1 // indirect github.com/btcsuite/btcd/btcec/v2 v2.2.0 // indirect github.com/btcsuite/btcd/chaincfg/chainhash v1.0.1 // indirect @@ -60,7 +63,7 @@ require ( github.com/cosmos/cosmos-proto v1.0.0-alpha7 // indirect github.com/cosmos/go-bip39 v1.0.0 // indirect github.com/cosmos/gorocksdb v1.2.0 // indirect - github.com/cosmos/iavl v0.19.3 // indirect + github.com/cosmos/iavl v0.19.4 // indirect github.com/cosmos/ledger-cosmos-go v0.11.1 // indirect github.com/cosmos/ledger-go v0.9.2 // indirect github.com/creachadair/taskgroup v0.3.2 // indirect @@ -91,8 +94,8 @@ require ( github.com/golang/glog v1.0.0 // indirect github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect github.com/golang/snappy v0.0.4 // indirect - github.com/google/btree v1.0.1 // indirect - github.com/google/go-cmp v0.5.8 // indirect + github.com/google/btree v1.1.2 // indirect + github.com/google/go-cmp v0.5.9 // indirect github.com/google/orderedcode v0.0.1 // indirect github.com/google/uuid v1.3.0 // indirect github.com/googleapis/enterprise-certificate-proxy v0.1.0 // indirect @@ -121,7 +124,7 @@ require ( github.com/jackpal/go-nat-pmp v1.0.2 // indirect github.com/jmespath/go-jmespath v0.4.0 // indirect github.com/jmhodges/levigo v1.0.0 // indirect - github.com/klauspost/compress v1.15.9 // indirect + github.com/klauspost/compress v1.15.11 // indirect github.com/lib/pq v1.10.6 // indirect github.com/libp2p/go-buffer-pool v0.1.0 // indirect github.com/magiconair/properties v1.8.6 // indirect @@ -135,6 +138,7 @@ require ( github.com/mitchellh/go-homedir v1.1.0 // indirect github.com/mitchellh/go-testing-interface v1.0.0 // indirect github.com/mitchellh/mapstructure v1.5.0 // indirect + github.com/mschoch/smat v0.2.0 // indirect github.com/mtibben/percent v0.2.1 // indirect github.com/olekukonko/tablewriter v0.0.5 // indirect github.com/pelletier/go-toml v1.9.5 // indirect @@ -145,7 +149,7 @@ require ( github.com/prometheus/client_golang v1.12.2 // indirect github.com/prometheus/client_model v0.2.0 // indirect github.com/prometheus/common v0.34.0 // indirect - github.com/prometheus/procfs v0.7.3 // indirect + github.com/prometheus/procfs v0.8.0 // indirect github.com/prometheus/tsdb v0.7.1 // indirect github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475 // indirect github.com/regen-network/cosmos-proto v0.3.1 // indirect @@ -170,14 +174,14 @@ require ( github.com/zondax/hid v0.9.1-0.20220302062450-5552068d2266 // indirect go.etcd.io/bbolt v1.3.6 // indirect go.opencensus.io v0.23.0 // indirect - golang.org/x/crypto v0.0.0-20220824171710-5757bc0c5503 // indirect + golang.org/x/crypto v0.1.0 // indirect golang.org/x/exp v0.0.0-20220722155223-a9213eeb770e // indirect - golang.org/x/net v0.0.0-20220812174116-3211cb980234 // indirect + golang.org/x/net v0.1.0 // indirect golang.org/x/oauth2 v0.0.0-20220622183110-fd043fe589d2 // indirect - golang.org/x/sync v0.0.0-20220819030929-7fc1605a5dde // indirect - golang.org/x/sys v0.0.0-20220818161305-2296e01440c6 // indirect - golang.org/x/term v0.0.0-20220722155259-a9ba230a4035 // indirect - golang.org/x/text v0.3.7 // indirect + golang.org/x/sync v0.0.0-20220929204114-8fcdb60fdcc0 // indirect + golang.org/x/sys v0.1.0 // indirect + golang.org/x/term v0.1.0 // indirect + golang.org/x/text v0.4.0 // indirect golang.org/x/xerrors v0.0.0-20220609144429-65e65417b02f // indirect google.golang.org/api v0.93.0 // indirect google.golang.org/appengine v1.6.7 // indirect @@ -189,7 +193,7 @@ require ( ) replace ( - github.com/cosmos/cosmos-sdk => github.com/cosmos/cosmos-sdk v0.46.2 + github.com/cosmos/cosmos-sdk => github.com/cosmos/cosmos-sdk v0.46.7-0.20221206163158-45d2f08e0e1d github.com/ethereum/go-ethereum => github.com/ethereum/go-ethereum v1.10.19 // Fix upstream GHSA-h395-qcrw-5vmq vulnerability. diff --git a/go.sum b/go.sum index 1e5eb4568d..3be31013c8 100644 --- a/go.sum +++ b/go.sum @@ -91,10 +91,12 @@ github.com/DATA-DOG/go-sqlmock v1.3.3/go.mod h1:f/Ixk793poVmq4qj/V1dPUg2JEAKC73Q github.com/DataDog/datadog-go v3.2.0+incompatible/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ= github.com/DataDog/zstd v1.5.0/go.mod h1:g4AWEaM3yOg3HYfnJ3YIawPnVdXJh9QME85blwSAmyw= github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8Leh48TZaKVeNIfJntJ2wa0= -github.com/Microsoft/go-winio v0.5.2 h1:a9IhgEQBCUEk6QCdml9CiJGhAws+YwffDHEMp1VMrpA= +github.com/Microsoft/go-winio v0.6.0 h1:slsWYD/zyx7lCXoZVlvQrj0hPTM1HI4+v1sIda2yDvg= github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5 h1:TngWCqHvy9oXAN6lEVMRuU21PR1EtLVZJmdB18Gu3Rw= github.com/OneOfOne/xxhash v1.2.2 h1:KMrpdQIwFcEqXDklaen+P1axHaj9BSKzvpUUfnHldSE= github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= +github.com/RoaringBitmap/roaring v1.2.1 h1:58/LJlg/81wfEHd5L9qsHduznOIhyv4qb1yWcSvVq9A= +github.com/RoaringBitmap/roaring v1.2.1/go.mod h1:icnadbWcNyfEHlYdr+tDlOTih1Bf/h+rzPpv4sbomAA= github.com/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWXgklEdEo= github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMxUHB2q5Ap20/P/eIdh4G0pI= github.com/StackExchange/wmi v0.0.0-20180116203802-5d049714c4a6/go.mod h1:3eOhrUMpNV+6aFIbp5/iudMxNCF27Vw2OZgy4xEx0Fg= @@ -154,6 +156,8 @@ github.com/bgentry/go-netrc v0.0.0-20140422174119-9fd32a8b3d3d h1:xDfNPAt8lFiC1U github.com/bgentry/go-netrc v0.0.0-20140422174119-9fd32a8b3d3d/go.mod h1:6QX/PXZ00z/TKoufEY6K/a0k6AhaJrQKdFe6OfVXsa4= github.com/bgentry/speakeasy v0.1.0 h1:ByYyxL9InA1OWqxJqqp2A5pYHUrCiAL6K3J+LKSsQkY= github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= +github.com/bits-and-blooms/bitset v1.2.0 h1:Kn4yilvwNtMACtf1eYDlG8H77R07mZSPbMjLyS07ChA= +github.com/bits-and-blooms/bitset v1.2.0/go.mod h1:gIdJ4wp64HaoK2YrL1Q5/N7Y16edYb8uY+O0FJTyyDA= github.com/bmizerany/pat v0.0.0-20170815010413-6226ea591a40/go.mod h1:8rLXio+WjiTceGBHIoTvn60HIbs7Hm7bcHjyrSqYB9c= github.com/boltdb/bolt v1.3.1/go.mod h1:clJnj/oiGkjum5o1McbSZDSLxVThjynRyGBgiAx27Ps= github.com/btcsuite/btcd v0.0.0-20190115013929-ed77733ec07d/go.mod h1:d3C0AkH6BRcvO8T0UEPu53cnw4IbV63x1bEjildYhO0= @@ -241,15 +245,17 @@ github.com/cosmos/btcutil v1.0.4 h1:n7C2ngKXo7UC9gNyMNLbzqz7Asuf+7Qv4gnX/rOdQ44= github.com/cosmos/btcutil v1.0.4/go.mod h1:Ffqc8Hn6TJUdDgHBwIZLtrLQC1KdJ9jGJl/TvgUaxbU= github.com/cosmos/cosmos-proto v1.0.0-alpha7 h1:yqYUOHF2jopwZh4dVQp3xgqwftE5/2hkrwIV6vkUbO0= github.com/cosmos/cosmos-proto v1.0.0-alpha7/go.mod h1:dosO4pSAbJF8zWCzCoTWP7nNsjcvSUBQmniFxDg5daw= -github.com/cosmos/cosmos-sdk v0.46.2 h1:3dUNqbLas94ud5aTcJKCwxVOmNXpuGBtVQTMrYczTwY= -github.com/cosmos/cosmos-sdk v0.46.2/go.mod h1:0aUPGPU6PWaDEaHNjtgrpNhgxo9bAUrQ7BO7XCvFOfs= +github.com/cosmos/cosmos-sdk v0.46.7-0.20221206163158-45d2f08e0e1d h1:Np+fiB2/FUV/lPhFVecebV+nO9qsQgILx/hWcVeKfiI= +github.com/cosmos/cosmos-sdk v0.46.7-0.20221206163158-45d2f08e0e1d/go.mod h1:B2j/SQkKvs/hUbXTmKxGwBnShJHvlxtVEbvTYNPwfrU= github.com/cosmos/go-bip39 v0.0.0-20180819234021-555e2067c45d/go.mod h1:tSxLoYXyBmiFeKpvmq4dzayMdCjCnu8uqmCysIGBT2Y= github.com/cosmos/go-bip39 v1.0.0 h1:pcomnQdrdH22njcAatO0yWojsUnCO3y2tNoV1cb6hHY= github.com/cosmos/go-bip39 v1.0.0/go.mod h1:RNJv0H/pOIVgxw6KS7QeX2a0Uo0aKUlfhZ4xuwvCdJw= +github.com/cosmos/gogoproto v1.4.3 h1:RP3yyVREh9snv/lsOvmsAPQt8f44LgL281X0IOIhhcI= +github.com/cosmos/gogoproto v1.4.3/go.mod h1:0hLIG5TR7IvV1fme1HCFKjfzW9X2x0Mo+RooWXCnOWU= github.com/cosmos/gorocksdb v1.2.0 h1:d0l3jJG8M4hBouIZq0mDUHZ+zjOx044J3nGRskwTb4Y= github.com/cosmos/gorocksdb v1.2.0/go.mod h1:aaKvKItm514hKfNJpUJXnnOWeBnk2GL4+Qw9NHizILw= -github.com/cosmos/iavl v0.19.3 h1:cESO0OwTTxQm5rmyESKW+zESheDUYI7CcZDWWDwnuxg= -github.com/cosmos/iavl v0.19.3/go.mod h1:X9PKD3J0iFxdmgNLa7b2LYWdsGd90ToV5cAONApkEPw= +github.com/cosmos/iavl v0.19.4 h1:t82sN+Y0WeqxDLJRSpNd8YFX5URIrT+p8n6oJbJ2Dok= +github.com/cosmos/iavl v0.19.4/go.mod h1:X9PKD3J0iFxdmgNLa7b2LYWdsGd90ToV5cAONApkEPw= github.com/cosmos/ibc-go/v5 v5.0.0 h1:MkObdarpoICPHXoRg/Ne9NRix4j7eQlJZq74/uzH3Zc= github.com/cosmos/ibc-go/v5 v5.0.0/go.mod h1:Wqsguq98Iuns8tgTv8+xaGYbC+Q8zJfbpjzT6IgMJbs= github.com/cosmos/ledger-cosmos-go v0.11.1 h1:9JIYsGnXP613pb2vPjFeMMjBI5lEDsEaF6oYorTy6J4= @@ -302,7 +308,7 @@ github.com/dnaeon/go-vcr v1.1.0/go.mod h1:M7tiix8f0r6mKKJ3Yq/kqU1OYf3MnfmBWVbPx/ github.com/dnaeon/go-vcr v1.2.0/go.mod h1:R4UdLID7HZT3taECzJs4YgbbH6PIGXB6W/sc5OLb6RQ= github.com/docker/docker v1.6.2/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= github.com/docker/go-connections v0.4.0 h1:El9xVISelRB7BuFusrZozjnkIM5YnzCViNKohAFqRJQ= -github.com/docker/go-units v0.4.0 h1:3uh0PgVws3nIA0Q+MwDC8yjEPf9zjRfZZWXZYDct3Tw= +github.com/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4= github.com/dop251/goja v0.0.0-20220405120441-9037c2b61cbf h1:Yt+4K30SdjOkRoRRm3vYNQgR+/ZIy0RmeUDZo7Y8zeQ= github.com/dop251/goja v0.0.0-20220405120441-9037c2b61cbf/go.mod h1:R9ET47fwRVRPZnOGvHxxhuZcbrMCuiqOz3Rlrh4KSnk= github.com/dop251/goja_nodejs v0.0.0-20210225215109-d91c329300e7/go.mod h1:hn7BA7c8pLvoGndExHudxTDKZ84Pyvv+90pbBjbTz0Y= @@ -463,8 +469,8 @@ github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEW github.com/golangci/lint-1 v0.0.0-20181222135242-d2cdd8c08219/go.mod h1:/X8TswGSh1pIozq4ZwCfxS0WA5JGXguxk94ar/4c87Y= github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= -github.com/google/btree v1.0.1 h1:gK4Kx5IaGY9CD5sPJ36FHiBJ6ZXl0kilRiiCj+jdYp4= -github.com/google/btree v1.0.1/go.mod h1:xXMiIv4Fb/0kKde4SpL7qlzvu5cMJDRkFDxJfI9uaxA= +github.com/google/btree v1.1.2 h1:xf4v41cLI2Z6FxbKm+8Bu+m8ifhj15JuZ9sa0jZCMUU= +github.com/google/btree v1.1.2/go.mod h1:qOPhT0dTNdNzV6Z/lhRX0YXUafgPLFUh+gZMl761Gm4= github.com/google/flatbuffers v1.11.0/go.mod h1:1AeVuKshWv4vARoZatz6mlQ0JxURH0Kv5+zNeJKJCa8= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= @@ -479,8 +485,9 @@ github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/ github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8/DtOE= -github.com/google/go-cmp v0.5.8 h1:e6P7q2lk1O+qJJb4BtCQXlK8vWEO8V1ZeuEdJNOqZyg= github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= +github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/gofuzz v0.0.0-20170612174753-24818f796faf/go.mod h1:HP5RmnzzSNb993RKQDq4+1A4ia9nllfqcQFTQJedwGI= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/gofuzz v1.1.1-0.20200604201612-c04b05f3adfa h1:Q75Upo5UN4JbPFURXZ8nLKYUvF85dyFRop/vQ0Rv+64= @@ -673,8 +680,8 @@ github.com/klauspost/compress v1.10.3/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYs github.com/klauspost/compress v1.11.2/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= github.com/klauspost/compress v1.11.7/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= github.com/klauspost/compress v1.12.3/go.mod h1:8dP1Hq4DHOhN9w426knH3Rhby4rFm6D8eO+e+Dq5Gzg= -github.com/klauspost/compress v1.15.9 h1:wKRjX6JRtDdrE9qwa4b/Cip7ACOshUI4smpCQanqjSY= -github.com/klauspost/compress v1.15.9/go.mod h1:PhcZ0MbTNciWF3rruxRgKxI5NkcHHrHUDtV4Yw2GlzU= +github.com/klauspost/compress v1.15.11 h1:Lcadnb3RKGin4FYM/orgq0qde+nc15E5Cbqg4B9Sx9c= +github.com/klauspost/compress v1.15.11/go.mod h1:QPwzmACJjUTFsnSHH934V6woptycfrDDJnH7hvFVbGM= github.com/klauspost/cpuid v0.0.0-20170728055534-ae7887de9fa5/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek= github.com/klauspost/crc32 v0.0.0-20161016154125-cb6bfca970f6/go.mod h1:+ZoRqAPRLkC4NPOvfYeR5KNOrY6TD+/sAC3HXPZgDYg= github.com/klauspost/pgzip v1.0.2-0.20170402124221-0bf5dcad4ada/go.mod h1:Ch1tH69qFZu15pkjo5kYi6mth2Zzwzt50oCQKQE9RUs= @@ -771,6 +778,8 @@ github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9G github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= github.com/modocache/gover v0.0.0-20171022184752-b58185e213c5/go.mod h1:caMODM3PzxT8aQXRPkAt8xlV/e7d7w8GM5g0fa5F0D8= github.com/mschoch/smat v0.0.0-20160514031455-90eadee771ae/go.mod h1:qAyveg+e4CE+eKJXWVjKXM4ck2QobLqTDytGJbLLhJg= +github.com/mschoch/smat v0.2.0 h1:8imxQsjDm8yFEAVBe7azKmKSgzSkZXDuKkSq9374khM= +github.com/mschoch/smat v0.2.0/go.mod h1:kc9mz7DoBKqDyiRL7VZN8KvXQMWeTaVnttLRXOlotKw= github.com/mtibben/percent v0.2.1 h1:5gssi8Nqo8QU/r2pynCm+hBQHpkB/uNK7BJCFogWdzs= github.com/mtibben/percent v0.2.1/go.mod h1:KG9uO+SZkUp+VkRHsCdYQV3XSZrrSpR3O9ibNBTZrns= github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= @@ -810,7 +819,7 @@ github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1y github.com/onsi/gomega v1.20.2 h1:8uQq0zMgLEfa0vRrrBgaJF2gyW9Da9BmfGV+OyUzfkY= github.com/op/go-logging v0.0.0-20160315200505-970db520ece7/go.mod h1:HzydrMdWErDVzsI23lYNej1Htcns9BCg93Dk0bBINWk= github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U= -github.com/opencontainers/image-spec v1.0.3-0.20211202183452-c5a74bcca799 h1:rc3tiVYb5z54aKaDfakKn0dDjIyPpTtszkjuMzyt7ec= +github.com/opencontainers/image-spec v1.1.0-rc2 h1:2zx/Stx4Wc5pIPDvIxHXvXtQFW/7XWJGmnM7r3wg034= github.com/opencontainers/runc v1.1.3 h1:vIXrkId+0/J2Ymu2m7VjGvbSlAId9XNRPhn2p4b+d8w= github.com/opentracing-contrib/go-observer v0.0.0-20170622124052-a52f23424492/go.mod h1:Ngi6UdF0k5OKD5t5wlmGhe/EDKPoUM3BXZSSfIuJbis= github.com/opentracing/basictracer-go v1.0.0/go.mod h1:QfBfYuafItcjQuMwinw9GhYKwFXS9KnPs5lxoYwgW74= @@ -888,8 +897,9 @@ github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+Gx github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= github.com/prometheus/procfs v0.3.0/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= -github.com/prometheus/procfs v0.7.3 h1:4jVXhlkAyzOScmCkXBTOLRLTz8EeU+eyjrwB/EPq0VU= github.com/prometheus/procfs v0.7.3/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= +github.com/prometheus/procfs v0.8.0 h1:ODq8ZFEaYeCaZOJlZZdJA2AbQR98dSHSM1KW/You5mo= +github.com/prometheus/procfs v0.8.0/go.mod h1:z7EfXMXOkbkqb9IINtpCn86r/to3BnA0uaxHdg830/4= github.com/prometheus/tsdb v0.7.1 h1:YZcsG11NqnK4czYLrWd9mpEuAJIHVQLwdrleYfszMAA= github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU= github.com/rakyll/statik v0.1.7 h1:OF3QCZUuyPxuGEP7B4ypUa7sB/iHtqOTDYZXGM8KOdQ= @@ -949,8 +959,8 @@ github.com/spf13/cast v1.5.0 h1:rj3WzYc11XZaIZMPKmwP96zkFEnnAmV8s6XbB2aY32w= github.com/spf13/cast v1.5.0/go.mod h1:SpXXQ5YoyJw6s3/6cMTQuxvgRl3PCJiyaX9p6b155UU= github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ= github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU= -github.com/spf13/cobra v1.5.0 h1:X+jTBEBqF0bHN+9cSMgmfuvv2VHJ9ezmFNf9Y/XstYU= -github.com/spf13/cobra v1.5.0/go.mod h1:dWXEIy2H428czQCjInthrTRUg7yKbok+2Qi/yBIJoUM= +github.com/spf13/cobra v1.6.0 h1:42a0n6jwCot1pUmomAp4T7DeMD+20LFv4Q54pxLf2LI= +github.com/spf13/cobra v1.6.0/go.mod h1:IOw/AERYS7UzyrGinqmz6HLUo219MORXGxhbaJUqzrY= github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= github.com/spf13/jwalterweatherman v1.1.0 h1:ue6voC5bR5F8YxI5S67j9i582FU4Qvo2bmqnqMYADFk= github.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0EXowPYD95IqWIGo= @@ -992,8 +1002,8 @@ github.com/tendermint/crypto v0.0.0-20191022145703-50d29ede1e15 h1:hqAk8riJvK4RM github.com/tendermint/crypto v0.0.0-20191022145703-50d29ede1e15/go.mod h1:z4YtwM70uOnk8h0pjJYlj3zdYwi9l03By6iAIF5j/Pk= github.com/tendermint/go-amino v0.16.0 h1:GyhmgQKvqF82e2oZeuMSp9JTN0N09emoSZlb2lyGa2E= github.com/tendermint/go-amino v0.16.0/go.mod h1:TQU0M1i/ImAo+tYpZi73AU3V/dKeCoMC9Sphe2ZwGME= -github.com/tendermint/tendermint v0.34.22 h1:XMhtC8s8QqJO4l/dn+TkQvevTRSow3Vixjclr41o+2Q= -github.com/tendermint/tendermint v0.34.22/go.mod h1:YpP5vBEAKUT4g6oyfjKgFeZmdB/GjkJAxfF+cgmJg6Y= +github.com/tendermint/tendermint v0.34.24 h1:879MKKJWYYPJEMMKME+DWUTY4V9f/FBpnZDI82ky+4k= +github.com/tendermint/tendermint v0.34.24/go.mod h1:rXVrl4OYzmIa1I91av3iLv2HS0fGSiucyW9J4aMTpKI= github.com/tendermint/tm-db v0.6.7 h1:fE00Cbl0jayAoqlExN6oyQJ7fR/ZtoVOmvPJ//+shu8= github.com/tendermint/tm-db v0.6.7/go.mod h1:byQDzFkZV1syXr/ReXS808NxA2xvyuuVgXOJ/088L6I= github.com/tidwall/gjson v1.12.1/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk= @@ -1091,8 +1101,8 @@ golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20211108221036-ceb1ce70b4fa/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/crypto v0.0.0-20220824171710-5757bc0c5503 h1:vJ2V3lFLg+bBhgroYuRfyN583UzVveQmIXjc8T/y3to= -golang.org/x/crypto v0.0.0-20220824171710-5757bc0c5503/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= +golang.org/x/crypto v0.1.0 h1:MDRAIl0xIo9Io2xV565hzXHw3zVseKrJKodhohM5CjU= +golang.org/x/crypto v0.1.0/go.mod h1:RecgLatLF4+eUMCP1PoPZQb+cVrJcOPbHkTkbkB9sbw= golang.org/x/exp v0.0.0-20180321215751-8460e604b9de/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20180807140117-3d87b88a115f/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= @@ -1138,6 +1148,7 @@ golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.5.1/go.mod h1:5OXOZSfqPIIbmVBIIKWRFfZjPR0E5r58TLhUjH0a2Ro= golang.org/x/mod v0.6.0-dev.0.20211013180041-c96bc1413d57/go.mod h1:3p9vT2HGsQu2K1YbXdKPJLVgG5VJdoTa1poYQBtP1AY= +golang.org/x/mod v0.6.0 h1:b9gGHsz9/HhJ3HF5DHQytPpuwocVTChQJK3AvoLRD5I= golang.org/x/net v0.0.0-20180719180050-a680a1efc54d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -1200,8 +1211,8 @@ golang.org/x/net v0.0.0-20220412020605-290c469a71a5/go.mod h1:CfG3xpIq0wQ8r1q4Su golang.org/x/net v0.0.0-20220425223048-2871e0cb64e4/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.0.0-20220607020251-c690dde0001d/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.0.0-20220624214902-1bab6f366d9e/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= -golang.org/x/net v0.0.0-20220812174116-3211cb980234 h1:RDqmgfe7SvlMWoqC3xwQ2blLO3fcWcxMa3eBLRdRW7E= -golang.org/x/net v0.0.0-20220812174116-3211cb980234/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk= +golang.org/x/net v0.1.0 h1:hZ/3BUoy5aId7sCpA/Tc5lt8DkFgdVS2onTpJsZ/fl0= +golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -1236,8 +1247,8 @@ golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220601150217-0de741cfad7f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20220819030929-7fc1605a5dde h1:ejfdSekXMDxDLbRrJMwUk6KnSLZ2McaUCVcIKM+N6jc= -golang.org/x/sync v0.0.0-20220819030929-7fc1605a5dde/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20220929204114-8fcdb60fdcc0 h1:cu5kTvlzcw1Q5S9f5ip1/cpiB4nXvw1XYzFPGgzLUOY= +golang.org/x/sync v0.0.0-20220929204114-8fcdb60fdcc0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -1341,13 +1352,13 @@ golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220610221304-9f5ed59c137d/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220624220833-87e55d714810/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220818161305-2296e01440c6 h1:Sx/u41w+OwrInGdEckYmEuU5gHoGSL4QbDz3S9s6j4U= -golang.org/x/sys v0.0.0-20220818161305-2296e01440c6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.1.0 h1:kunALQeHf1/185U1i0GOB/fy1IPRDDpuoOOqRReG57U= +golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= -golang.org/x/term v0.0.0-20220722155259-a9ba230a4035 h1:Q5284mrmYTpACcm+eAKjKJH48BBwSyfJqmmGDTtT8Vc= -golang.org/x/term v0.0.0-20220722155259-a9ba230a4035/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= +golang.org/x/term v0.1.0 h1:g6Z6vPFA9dYBAF7DWcH6sCcOntplXsDKcliusYijMlw= +golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -1356,8 +1367,9 @@ golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= +golang.org/x/text v0.4.0 h1:BrVqGRd7+k1DiOgtnFvAkoQEWQvBc25ouMJM6429SFg= +golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= @@ -1430,6 +1442,7 @@ golang.org/x/tools v0.1.3/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.4/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.8-0.20211029000441-d6a9af8af023/go.mod h1:nABZi5QlRsZVlzPpHl034qft6wpY4eDcsTt5AaioBiU= +golang.org/x/tools v0.2.0 h1:G6AHpWxTMGY1KyEYoAQ5WTtIekUUvDNjan3ugu60JvE= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= @@ -1584,8 +1597,8 @@ google.golang.org/genproto v0.0.0-20220608133413-ed9918b62aac/go.mod h1:KEWEmljW google.golang.org/genproto v0.0.0-20220616135557-88e70c0c3a90/go.mod h1:KEWEmljWE5zPzLBa/oHl6DaEt9LmfH6WtH1OHIvleBA= google.golang.org/genproto v0.0.0-20220617124728-180714bec0ad/go.mod h1:KEWEmljWE5zPzLBa/oHl6DaEt9LmfH6WtH1OHIvleBA= google.golang.org/genproto v0.0.0-20220624142145-8cd45d7dbd1f/go.mod h1:KEWEmljWE5zPzLBa/oHl6DaEt9LmfH6WtH1OHIvleBA= -google.golang.org/genproto v0.0.0-20220822174746-9e6da59bd2fc h1:Nf+EdcTLHR8qDNN/KfkQL0u0ssxt9OhbaWCl5C0ucEI= -google.golang.org/genproto v0.0.0-20220822174746-9e6da59bd2fc/go.mod h1:dbqgFATTzChvnt+ujMdZwITVAJHFtfyN1qUhDqEiIlk= +google.golang.org/genproto v0.0.0-20221014213838-99cd37c6964a h1:GH6UPn3ixhWcKDhpnEC55S75cerLPdpp3hrhfKYjZgw= +google.golang.org/genproto v0.0.0-20221014213838-99cd37c6964a/go.mod h1:1vXfmgAz9N9Jx0QA82PqRVauvCz1SGSz739p0f183jM= google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.19.1/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= @@ -1624,8 +1637,8 @@ google.golang.org/grpc v1.45.0/go.mod h1:lN7owxKUQEqMfSyQikvvk5tf/6zMPsrK+ONuO11 google.golang.org/grpc v1.46.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk= google.golang.org/grpc v1.46.2/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk= google.golang.org/grpc v1.47.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk= -google.golang.org/grpc v1.50.0 h1:fPVVDxY9w++VjTZsYvXWqEf9Rqar/e+9zYfxKK+W+YU= -google.golang.org/grpc v1.50.0/go.mod h1:ZgQEeidpAuNRZ8iRrlBKXZQP1ghovWIVhdJRyCDK+GI= +google.golang.org/grpc v1.50.1 h1:DS/BukOZWp8s6p4Dt/tOaJaTQyPyOoCcrjroHuCeLzY= +google.golang.org/grpc v1.50.1/go.mod h1:ZgQEeidpAuNRZ8iRrlBKXZQP1ghovWIVhdJRyCDK+GI= google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0/go.mod h1:6Kw0yEErY5E/yWrBtf03jp27GLLJujG4z/JK95pnjjw= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= @@ -1641,8 +1654,8 @@ google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp0 google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= -google.golang.org/protobuf v1.28.1 h1:d0NfwRgPtno5B1Wa6L2DAG+KivqkdutMf1UhdNx175w= -google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= +google.golang.org/protobuf v1.28.2-0.20220831092852-f930b1dc76e8 h1:KR8+MyP7/qOlV+8Af01LtjL04bu7on42eVsxT4EyBQk= +google.golang.org/protobuf v1.28.2-0.20220831092852-f930b1dc76e8/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= diff --git a/gomod2nix.toml b/gomod2nix.toml index a05555ba67..408f0be0d3 100644 --- a/gomod2nix.toml +++ b/gomod2nix.toml @@ -31,6 +31,9 @@ schema = 3 [mod."github.com/ChainSafe/go-schnorrkel"] version = "v0.0.0-20200405005733-88cbf1b4c40d" hash = "sha256-i8RXZemJGlSjBT35oPm0SawFiBoIU5Pkq5xp4n/rzCY=" + [mod."github.com/RoaringBitmap/roaring"] + version = "v1.2.1" + hash = "sha256-0/R956wrCW71eOE36CbxGJJRuQjKwvvIQ/D8QTn2A6w=" [mod."github.com/StackExchange/wmi"] version = "v1.2.1" hash = "sha256-1BoEeWAWyebH+1mMuyPhWZut8nWHb6r73MgcqlGuUEY=" @@ -58,6 +61,9 @@ schema = 3 [mod."github.com/bgentry/speakeasy"] version = "v0.1.0" hash = "sha256-Gt1vj6CFovLnO6wX5u2O4UfecY9V2J9WGw1ez4HMrgk=" + [mod."github.com/bits-and-blooms/bitset"] + version = "v1.2.0" + hash = "sha256-IxNmtELycM+XVzg4qBv04hAJUT3nSWuyP9R+8zc9LmU=" [mod."github.com/btcsuite/btcd"] version = "v0.22.1" hash = "sha256-hBU+roIELcmbW2Gz7eGZzL9qNA1bakq5wNxqCgs4TKc=" @@ -98,18 +104,21 @@ schema = 3 version = "v1.0.0-alpha7" hash = "sha256-2wCH+toTF2A6MfFjOa13muEH5oBCcxAhZEqirNOrBA0=" [mod."github.com/cosmos/cosmos-sdk"] - version = "v0.46.2" - hash = "sha256-Lgn4+Vd5PUUkfHc+lTdK2G6/nymZekFVTe1FxWRqh2w=" + version = "v0.46.7-0.20221206163158-45d2f08e0e1d" + hash = "sha256-4j5nR0VxlxhBeCQS4RvWngQZfZIy2NVNxyTFwmmwGTk=" replaced = "github.com/cosmos/cosmos-sdk" [mod."github.com/cosmos/go-bip39"] version = "v1.0.0" hash = "sha256-Qm2aC2vaS8tjtMUbHmlBSagOSqbduEEDwc51qvQaBmA=" + [mod."github.com/cosmos/gogoproto"] + version = "v1.4.3" + hash = "sha256-Y/NL76ay/oAl8mS3skkK5ula0/xudqbwW1o22lZjKRg=" [mod."github.com/cosmos/gorocksdb"] version = "v1.2.0" hash = "sha256-209TcVuXc5s/TcOvNlaQ1HEJAUDTEK3nxPhs+d8TEcY=" [mod."github.com/cosmos/iavl"] - version = "v0.19.3" - hash = "sha256-rmW2KoKmm4YXmYIYE1vXMOCaDyP1ym0qsW224PYc9rg=" + version = "v0.19.4" + hash = "sha256-EmpRZ48pjPFq/fIHneut9Vyo5QJATfb3ZO7KzWnqs9g=" [mod."github.com/cosmos/ibc-go/v5"] version = "v5.0.0" hash = "sha256-sDZdmuGohaaBF7bxrjo9PWJnmoF+VOkjySYhsFixPz4=" @@ -164,6 +173,7 @@ schema = 3 [mod."github.com/ethereum/go-ethereum"] version = "v1.10.19" hash = "sha256-7FPnTGcCb8Xd1QVR+6PmGTaHdTY1mm/8osFTW1JLuG8=" + replaced = "github.com/ethereum/go-ethereum" [mod."github.com/evmos/ethermint"] version = "v0.6.1-0.20221003153722-491c3da7ebd7" hash = "sha256-vnfjk57gYa+F8nn0LByX/B1LV8PY2Jvm8vXV6be4ufc=" @@ -217,11 +227,11 @@ schema = 3 version = "v0.0.4" hash = "sha256-Umx+5xHAQCN/Gi4HbtMhnDCSPFAXSsjVbXd8n5LhjAA=" [mod."github.com/google/btree"] - version = "v1.0.1" - hash = "sha256-1PIeFGgUL4BK/StL/D12pg9bEQ5HfMT/fMLdus4pZTs=" + version = "v1.1.2" + hash = "sha256-K7V2obq3pLM71Mg0vhhHtZ+gtaubwXPQx3xcIyZDCjM=" [mod."github.com/google/go-cmp"] - version = "v0.5.8" - hash = "sha256-8zkIo+Sr1NXMnj3PNmvjX2sZKnAKWXOFvmnX7D9bwxQ=" + version = "v0.5.9" + hash = "sha256-lQc4O00R3QSMGs9LP8Sy7A9kj0cqV5rrUdpnGeipIyg=" [mod."github.com/google/orderedcode"] version = "v0.0.1" hash = "sha256-KrExYovtUQrHGI1mPQf57jGw8soz7eWOC2xqEaV0uGk=" @@ -313,8 +323,8 @@ schema = 3 version = "v1.0.0" hash = "sha256-xEd0mDBeq3eR/GYeXjoTVb2sPs8sTCosn5ayWkcgENI=" [mod."github.com/klauspost/compress"] - version = "v1.15.9" - hash = "sha256-ctPxlVq0c/SoNPVsP66RjxUjTHys3diW2Apxjyc9WdE=" + version = "v1.15.11" + hash = "sha256-9MXm0TObg6DyqnYMIw3IChrorHc2ILf5djZYoM0e1J0=" [mod."github.com/lib/pq"] version = "v1.10.6" hash = "sha256-8EhFwY/9YH5L/fd6l2beOnC3VvpegRAmCCsnDVJBqBM=" @@ -354,6 +364,9 @@ schema = 3 [mod."github.com/mitchellh/mapstructure"] version = "v1.5.0" hash = "sha256-ztVhGQXs67MF8UadVvG72G3ly0ypQW0IRDdOOkjYwoE=" + [mod."github.com/mschoch/smat"] + version = "v0.2.0" + hash = "sha256-DZvUJXjIcta3U+zxzgU3wpoGn/V4lpBY7Xme8aQUi+E=" [mod."github.com/mtibben/percent"] version = "v0.2.1" hash = "sha256-Zj1lpCP6mKQ0UUTMs2By4LC414ou+iJzKkK+eBHfEcc=" @@ -389,8 +402,8 @@ schema = 3 version = "v0.34.0" hash = "sha256-M+v+7DntUBmiQNzfNmG3aLLufbl0XBQOubtYoNTzJDA=" [mod."github.com/prometheus/procfs"] - version = "v0.7.3" - hash = "sha256-ik0WpnpSjMwifPYfQTfu/eb5ilNj+eLJF0d5Dftp8A8=" + version = "v0.8.0" + hash = "sha256-hgrilokQsXCOCCvwgOSfuErxoFAQpXM/+zNJKcMVHyM=" [mod."github.com/prometheus/tsdb"] version = "v0.7.1" hash = "sha256-BPz7YJbfMZgeR+u9YaeWeipVzHIS73EdgXD7VSJSLbA=" @@ -425,8 +438,8 @@ schema = 3 version = "v1.5.0" hash = "sha256-Pdp+wC5FWqyJKzyYHb7JCcV9BoJk/sxQw6nLyuLJvuQ=" [mod."github.com/spf13/cobra"] - version = "v1.5.0" - hash = "sha256-rcyHWrxshA5DVpxrSba5X4NjppqOGrJ64QkUKKnfW2E=" + version = "v1.6.0" + hash = "sha256-BidkXU9dFuU3Ah8Hl0PbuDe/EHrTr0B1JLSsdFgCXyI=" [mod."github.com/spf13/jwalterweatherman"] version = "v1.1.0" hash = "sha256-62BQtqTLF/eVrTOr7pUXE7AiHRjOVC8jQs3/Ehmflfs=" @@ -458,8 +471,8 @@ schema = 3 version = "v0.16.0" hash = "sha256-JW4zO/0vMzf1dXLePOqaMtiLUZgNbuIseh9GV+jQlf0=" [mod."github.com/tendermint/tendermint"] - version = "v0.34.22" - hash = "sha256-4p4cpyCWjBbNQUpYN2gDJvnyj+Pov9hw5uRjHrrO++Y=" + version = "v0.34.24" + hash = "sha256-3HFTv4XgN535RDaJ5OwUS+fnJHgkmLTwU7CNU2ilxEQ=" [mod."github.com/tendermint/tm-db"] version = "v0.6.7" hash = "sha256-hl/3RrBrpkk2zA6dmrNlIYKs1/GfqegSscDSkA5Pjlo=" @@ -478,6 +491,7 @@ schema = 3 [mod."github.com/zondax/hid"] version = "v0.9.0" hash = "sha256-PvXtxXo/3C+DS9ZeGBlr4zXbIpaYNtMqLzxYhusFXNY=" + replaced = "github.com/zondax/hid" [mod."go.etcd.io/bbolt"] version = "v1.3.6" hash = "sha256-DenVAmyN22xUiivk6fdJp4C9ZnUJXCMDUf8E0goRRV4=" @@ -485,29 +499,29 @@ schema = 3 version = "v0.23.0" hash = "sha256-R3O9GyNtv6j0ic7s+2xkLLaLzbJEop0Otj1nJDFBjsg=" [mod."golang.org/x/crypto"] - version = "v0.0.0-20220824171710-5757bc0c5503" - hash = "sha256-eGAblX40HAKw5jayFnN0SueZut7uQr7bHTzbv9YrR2g=" + version = "v0.1.0" + hash = "sha256-0oZWBSiW5Pd/2a1p2beuoelDe0CpfXZhrg/qPduJlYs=" [mod."golang.org/x/exp"] version = "v0.0.0-20220722155223-a9213eeb770e" hash = "sha256-kNgzydWRpjm0sZl4uXEs3LX5L0xjJtJRAFf/CTlYUN4=" [mod."golang.org/x/net"] - version = "v0.0.0-20220812174116-3211cb980234" - hash = "sha256-v/Qep/W6lw6IurR+R2V0AN/MlQUROLnEaWeeuwY8sg8=" + version = "v0.1.0" + hash = "sha256-SrThFBg6sqGYpiN1E3d1SilJxbKkQhSZXPmAFoMAA/I=" [mod."golang.org/x/oauth2"] version = "v0.0.0-20220622183110-fd043fe589d2" hash = "sha256-VLffpTpx3DlUzXB8mKiJfFzm4ZmgnLSUuLB5Ir0WQUg=" [mod."golang.org/x/sync"] - version = "v0.0.0-20220819030929-7fc1605a5dde" - hash = "sha256-5EOxO8FRdaLW9v/DhwBmWiT2G34A2ofxSCaC7ovvpb0=" + version = "v0.0.0-20220929204114-8fcdb60fdcc0" + hash = "sha256-Hygjq9euZ0qz6TvHYQwOZEjNiTbTh1nSLRAWZ6KFGR8=" [mod."golang.org/x/sys"] - version = "v0.0.0-20220818161305-2296e01440c6" - hash = "sha256-gCzekaAZ7aPg4EUAwL3USir4BNp/Etv5OWGekAGVZ8w=" + version = "v0.1.0" + hash = "sha256-nZbEJ/2PuWrDLD4ujeVvcFGoIsfVoIH/Lcp4FjD7hpU=" [mod."golang.org/x/term"] - version = "v0.0.0-20220722155259-a9ba230a4035" - hash = "sha256-9uM1OONzbsa6bz2iKk767hAaCuafi58bdTF7at03fWY=" + version = "v0.1.0" + hash = "sha256-UWnNsJIj5nXsuzlPWQ1NyHQuHStaDacMVkFbJ4pnxXk=" [mod."golang.org/x/text"] - version = "v0.3.7" - hash = "sha256-XH2pUzzQx95O0rak00grQvfACfL+EmZiV7ZzJBkX+XY=" + version = "v0.4.0" + hash = "sha256-JvyMygdmTvWg7xhbnUB9MMk6WcYXJt8DAj4DYl82Pys=" [mod."golang.org/x/xerrors"] version = "v0.0.0-20220609144429-65e65417b02f" hash = "sha256-tl8pv3oddbz2+KoIp7PFDKsxjQF8ocjPF8XPsY3sw38=" @@ -518,14 +532,14 @@ schema = 3 version = "v1.6.7" hash = "sha256-zIxGRHiq4QBvRqkrhMGMGCaVL4iM4TtlYpAi/hrivS4=" [mod."google.golang.org/genproto"] - version = "v0.0.0-20220822174746-9e6da59bd2fc" - hash = "sha256-yqs8RLNZJOaeT2QVhVpZdokXaapQa841VEBkh9xd/yU=" + version = "v0.0.0-20221014213838-99cd37c6964a" + hash = "sha256-zSdk2kbcfWaaJfHxLULI9v38lvEaJb8koC5c59aVZZI=" [mod."google.golang.org/grpc"] - version = "v1.50.0" - hash = "sha256-ep8UAToLpWoc0VLRGNQFzwzsuL+Yjd7emncmIOc2t8o=" + version = "v1.50.1" + hash = "sha256-38nk4qIme+fE57SsCqNxtCZnc8fyzzi4Sb60uDTT2KE=" [mod."google.golang.org/protobuf"] - version = "v1.28.1" - hash = "sha256-sTJYgvlv5is7vHNxcuigF2lNASp0QonhUgnrguhfHSU=" + version = "v1.28.2-0.20220831092852-f930b1dc76e8" + hash = "sha256-li5hXlXwTJ5LIZ8bVki1AZ6UFI2gXHl33JwdX1dOrtM=" [mod."gopkg.in/ini.v1"] version = "v1.67.0" hash = "sha256-V10ahGNGT+NLRdKUyRg1dos5RxLBXBk1xutcnquc/+4=" diff --git a/integration_tests/configs/cosmovisor.jsonnet b/integration_tests/configs/cosmovisor.jsonnet index 053e557720..208cf4e834 100644 --- a/integration_tests/configs/cosmovisor.jsonnet +++ b/integration_tests/configs/cosmovisor.jsonnet @@ -4,6 +4,7 @@ config { 'cronos_777-1'+: { 'app-config'+: { 'minimum-gas-prices': '100000000000basetcro', + store:: super.store, }, genesis+: { app_state+: { diff --git a/integration_tests/configs/cosmovisor_gravity.jsonnet b/integration_tests/configs/cosmovisor_gravity.jsonnet index 25ef6beb3c..86d4b300af 100644 --- a/integration_tests/configs/cosmovisor_gravity.jsonnet +++ b/integration_tests/configs/cosmovisor_gravity.jsonnet @@ -5,6 +5,7 @@ config { 'cmd-flags': '--unsafe-experimental', 'app-config'+: { 'minimum-gas-prices': '100000000000basetcro', + store:: super.store, }, genesis+: { app_state+: { diff --git a/integration_tests/configs/default.jsonnet b/integration_tests/configs/default.jsonnet index 12ca83f47d..a0351d612c 100644 --- a/integration_tests/configs/default.jsonnet +++ b/integration_tests/configs/default.jsonnet @@ -2,7 +2,7 @@ dotenv: '../../scripts/.env', 'cronos_777-1': { cmd: 'cronosd', - 'start-flags': '--trace --streamers file', + 'start-flags': '--trace', config: { mempool: { version: 'v1', @@ -20,6 +20,9 @@ 'block-range-cap': 10000, 'logs-cap': 10000, }, + store: { + streamers: ['file', 'versiondb'], + }, }, validators: [{ coins: '1000000000000000000stake,10000000000000000000000basetcro', diff --git a/integration_tests/configs/pruned-node.jsonnet b/integration_tests/configs/pruned-node.jsonnet index 2a3edd147f..3c9cdc4cdc 100644 --- a/integration_tests/configs/pruned-node.jsonnet +++ b/integration_tests/configs/pruned-node.jsonnet @@ -2,11 +2,17 @@ local config = import 'default.jsonnet'; config { 'cronos_777-1'+: { + 'start-flags': '--trace', 'app-config'+: { pruning: 'everything', 'state-sync'+: { 'snapshot-interval': 0, }, + store+: { + // don't enable versiondb, since it don't do pruning right now + streamers: ['file'], + }, + }, genesis+: { app_state+: { diff --git a/integration_tests/configs/state_benchmark.jsonnet b/integration_tests/configs/state_benchmark.jsonnet new file mode 100644 index 0000000000..8ae37bdbca --- /dev/null +++ b/integration_tests/configs/state_benchmark.jsonnet @@ -0,0 +1,36 @@ +local config = import 'default.jsonnet'; + +config { + 'cronos_777-1'+: { + 'start-flags': '--trace', + 'app-config'+: { + 'app-db-backend': 'rocksdb', + 'state-sync'+: { + 'snapshot-interval': 0, + }, + }, + validators: [ + super.validators[0], + super.validators[1] { + 'app-config'+: { + pruning: 'everything', + }, + }, + ] + super.validators[2:], + genesis+: { + consensus_params+: { + block+: { + max_gas: '163000000', + }, + }, + app_state+: { + feemarket+: { + params+: { + no_base_fee: true, + min_gas_multiplier: '0', + }, + }, + }, + }, + }, +} diff --git a/integration_tests/conftest.py b/integration_tests/conftest.py index 980d4a9627..a496fe7a12 100644 --- a/integration_tests/conftest.py +++ b/integration_tests/conftest.py @@ -13,6 +13,28 @@ def pytest_configure(config): config.addinivalue_line("markers", "slow: marks tests as slow") config.addinivalue_line("markers", "gravity: gravity bridge test cases") + config.addinivalue_line( + "markers", "benchmark: benchmarks, only run if '--run-benchmark' is passed" + ) + + +def pytest_addoption(parser): + parser.addoption( + "--run-benchmark", + action="store_true", + default=False, + help="include benchmark cases", + ) + + +def pytest_collection_modifyitems(config, items): + if config.getoption("--run-benchmark"): + # run benchmarks + return + skip = pytest.mark.skip(reason="need --run-benchmark option to run") + for item in items: + if "benchmark" in item.keywords: + item.add_marker(skip) @pytest.fixture(scope="session") diff --git a/integration_tests/contracts/contracts/BenchmarkStorage.sol b/integration_tests/contracts/contracts/BenchmarkStorage.sol new file mode 100644 index 0000000000..69dcfde451 --- /dev/null +++ b/integration_tests/contracts/contracts/BenchmarkStorage.sol @@ -0,0 +1,15 @@ +pragma solidity 0.8.10; + +contract BenchmarkStorage { + uint seed; + mapping(uint => uint) state; + function random(uint i) private view returns (uint) { + return uint(keccak256(abi.encodePacked(i, seed))); + } + function batch_set(uint _seed, uint n, uint range) public { + seed = _seed; + for (uint i=0; i< n; i++) { + state[random(i) % range] = random(i+i); + } + } +} diff --git a/integration_tests/poetry.lock b/integration_tests/poetry.lock index 81c27ee182..c1e906d137 100644 --- a/integration_tests/poetry.lock +++ b/integration_tests/poetry.lock @@ -100,7 +100,6 @@ mypy-extensions = ">=0.4.3" pathspec = ">=0.9.0" platformdirs = ">=2" tomli = {version = ">=1.1.0", markers = "python_full_version < \"3.11.0a7\""} -typing-extensions = {version = ">=3.10.0.0", markers = "python_version < \"3.10\""} [package.extras] colorama = ["colorama (>=0.4.3)"] @@ -473,21 +472,6 @@ category = "main" optional = false python-versions = ">=3.5" -[[package]] -name = "importlib-resources" -version = "5.7.1" -description = "Read resources from Python packages" -category = "main" -optional = false -python-versions = ">=3.7" - -[package.dependencies] -zipp = {version = ">=3.1.0", markers = "python_version < \"3.10\""} - -[package.extras] -docs = ["jaraco.packaging (>=9)", "rst.linker (>=1.9)", "sphinx"] -testing = ["pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=1.0.1)", "pytest-flake8", "pytest-mypy (>=0.9.1)"] - [[package]] name = "iniconfig" version = "1.1.1" @@ -551,7 +535,6 @@ python-versions = ">=3.7" [package.dependencies] attrs = ">=17.4.0" -importlib-resources = {version = ">=1.4.0", markers = "python_version < \"3.9\""} pyrsistent = ">=0.14.0,<0.17.0 || >0.17.0,<0.17.1 || >0.17.1,<0.17.2 || >0.17.2" [package.extras] @@ -739,6 +722,14 @@ python-versions = ">=3.6.8" [package.extras] diagrams = ["jinja2", "railroad-diagrams"] +[[package]] +name = "pyroaring" +version = "0.3.4" +description = "Fast and lightweight set for unsigned 32 bits integers." +category = "main" +optional = false +python-versions = "*" + [[package]] name = "pyrsistent" version = "0.18.1" @@ -783,7 +774,7 @@ tomlkit = "^0.7.0" type = "git" url = "https://github.com/crypto-com/pystarport.git" reference = "main" -resolved_reference = "c3028081386e8489171607e0aed6e68d1ff87d43" +resolved_reference = "ff645505d5052e11ecc56b6933af8f5f2a6b4373" [[package]] name = "pytest" @@ -906,6 +897,46 @@ lint = ["flake8 (==3.4.1)"] rust-backend = ["rusty-rlp (>=0.2.1,<0.3)"] test = ["hypothesis (==5.19.0)", "pytest (>=6.2.5,<7)", "tox (>=2.9.1,<3)"] +[[package]] +name = "roaring64" +version = "0.1.0" +description = "roaring64 wrapper of pyroaring implemented in pure python" +category = "main" +optional = false +python-versions = "^3.10" +develop = false + +[package.dependencies] +pyroaring = "^0.3.3" + +[package.source] +type = "git" +url = "https://github.com/yihuang/python-roaring64.git" +reference = "main" +resolved_reference = "7ceafa7beef9a0a078f2f511358f86d55550b958" + +[[package]] +name = "rocksdb" +version = "0.9.1" +description = "" +category = "main" +optional = false +python-versions = "*" +develop = false + +[package.dependencies] +setuptools = ">=25" + +[package.extras] +doc = ["sphinx", "sphinx_rtd_theme"] +test = ["pytest"] + +[package.source] +type = "git" +url = "https://github.com/HathorNetwork/python-rocksdb.git" +reference = "master" +resolved_reference = "947f68a80d97c4a5621ee681ae01602ebd883f3a" + [[package]] name = "setuptools" version = "65.5.0" @@ -994,14 +1025,6 @@ category = "main" optional = false python-versions = ">=3.5" -[[package]] -name = "typing-extensions" -version = "4.2.0" -description = "Backported and Experimental Type Hints for Python 3.7+" -category = "main" -optional = false -python-versions = ">=3.7" - [[package]] name = "urllib3" version = "1.26.9" @@ -1086,22 +1109,10 @@ python-versions = ">=3.6" idna = ">=2.0" multidict = ">=4.0" -[[package]] -name = "zipp" -version = "3.8.0" -description = "Backport of pathlib-compatible object wrapper for zip files" -category = "main" -optional = false -python-versions = ">=3.7" - -[package.extras] -docs = ["jaraco.packaging (>=9)", "rst.linker (>=1.9)", "sphinx"] -testing = ["func-timeout", "jaraco.itertools", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=1.0.1)", "pytest-flake8", "pytest-mypy (>=0.9.1)"] - [metadata] lock-version = "1.1" -python-versions = "^3.8" -content-hash = "e40ace5d601ae1cbdcfa816c195b32eaed7c3267fc988a4e0219b4a5b549100b" +python-versions = "^3.10" +content-hash = "9fe9a7aecc2e2597e0e03623b64c541aebe70034638a47456967626b6a8a3398" [metadata.files] aiohttp = [ @@ -1510,10 +1521,6 @@ idna = [ {file = "idna-3.3-py3-none-any.whl", hash = "sha256:84d9dd047ffa80596e0f246e2eab0b391788b0503584e8945f2368256d2735ff"}, {file = "idna-3.3.tar.gz", hash = "sha256:9d643ff0a55b762d5cdb124b8eaa99c66322e2157b69160bc32796e824360e6d"}, ] -importlib-resources = [ - {file = "importlib_resources-5.7.1-py3-none-any.whl", hash = "sha256:e447dc01619b1e951286f3929be820029d48c75eb25d265c28b92a16548212b8"}, - {file = "importlib_resources-5.7.1.tar.gz", hash = "sha256:b6062987dfc51f0fcb809187cffbd60f35df7acb4589091f154214af6d0d49d3"}, -] iniconfig = [ {file = "iniconfig-1.1.1-py2.py3-none-any.whl", hash = "sha256:011e24c64b7f47f6ebd835bb12a743f2fbe9a26d4cecaa7f53bc4f35ee9da8b3"}, {file = "iniconfig-1.1.1.tar.gz", hash = "sha256:bc3af051d7d14b2ee5ef9969666def0cd1a000e121eaea580d4a313df4b37f32"}, @@ -1716,6 +1723,52 @@ pyparsing = [ {file = "pyparsing-3.0.8-py3-none-any.whl", hash = "sha256:ef7b523f6356f763771559412c0d7134753f037822dad1b16945b7b846f7ad06"}, {file = "pyparsing-3.0.8.tar.gz", hash = "sha256:7bf433498c016c4314268d95df76c81b842a4cb2b276fa3312cfb1e1d85f6954"}, ] +pyroaring = [ + {file = "pyroaring-0.3.4-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:c752689fb1af66bc62380b3101426c6a357a85d73492acc5a56fbfe9dd85f571"}, + {file = "pyroaring-0.3.4-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:fa2d254b20ef2e8a094fd2c84317ad2e133e5ec40089fbbf1f798cc255dfd467"}, + {file = "pyroaring-0.3.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:cf7e4b01a62ffc8ab15d443e90afa29226f7cc7a6814e60cca1be7e4ff20c4fc"}, + {file = "pyroaring-0.3.4-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:20b7a8d445ad974ba8d17239d1729478930de8f2dae980566b55383f55280256"}, + {file = "pyroaring-0.3.4-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a10bb61c6d0128d0e92f4e16c5d995e23cbf7a1641a3ada59676d5e5ca004f39"}, + {file = "pyroaring-0.3.4-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:782f453e5a9fb1bea0e108c1d2b3e9920e41c97590b528e359a6203df3fe3bfd"}, + {file = "pyroaring-0.3.4-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:6932a4eb7fbd2673e22f4251a643ed997ec86d90f16644fbb833493e35ad19ac"}, + {file = "pyroaring-0.3.4-cp310-cp310-win32.whl", hash = "sha256:25b3bc512069777fbf05f533c248cab23f91dc99bd9f9f2cd72260a9fca525a4"}, + {file = "pyroaring-0.3.4-cp310-cp310-win_amd64.whl", hash = "sha256:1b7b8bcfd4011c13f38ffb3a96553201cb44675f16d9cc5d9a8d4560dc40c89d"}, + {file = "pyroaring-0.3.4-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:b522eba5140631e892c5727590b18cd4b93f849e5ae5fbe9e5498c94563ac3d3"}, + {file = "pyroaring-0.3.4-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:40af83423015c46f0ec29201fa3a855d216fc241b6148cbc2479b4180cf558e9"}, + {file = "pyroaring-0.3.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:7c5c0f79b1202564e8131d1e9dcd1efb7cca026562007de5a0bd6948cdcacb90"}, + {file = "pyroaring-0.3.4-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5a595aafbfa541431b61a740d51c3a6d5d579650e95cd6854526a692fb32df7a"}, + {file = "pyroaring-0.3.4-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0c2451e2c534c4df53a1df7afdb994f2387da0cf7f48df3059d332d085a79bb8"}, + {file = "pyroaring-0.3.4-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:9c37613e3916860f344bb475883b2b8f2832ac8c816836e2c81ae131d987a9b3"}, + {file = "pyroaring-0.3.4-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:a7c6ac7cbd0e799aeaea69e686160a7cb2c3d1b4804d5bf28e1816b37575cb21"}, + {file = "pyroaring-0.3.4-cp311-cp311-win32.whl", hash = "sha256:c3de6d36002a8561738baacc3e64b77102d597bcec536f82a9d20ec1b5e2d2db"}, + {file = "pyroaring-0.3.4-cp311-cp311-win_amd64.whl", hash = "sha256:5064a8fd58937e942bad5c797348dcf2c539796bbbf1e9ed24b9dc55c249d577"}, + {file = "pyroaring-0.3.4-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:ed54e3394cb762bda5846d58407aa2fb371ff8eb6e518bb3703802660aef86b1"}, + {file = "pyroaring-0.3.4-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0b0b7b4b407b178cf0076832ec1eba1a38ea88e869a410f09d3748a2f9816aa6"}, + {file = "pyroaring-0.3.4-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4f503303333ef58333f04acf63b8b6ff80ded2064d840bd4e96fda570c9b6c52"}, + {file = "pyroaring-0.3.4-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:c9d0ac2e47d201299d579e570114ae7b46f4fb49e292c796ad74e80211c48f89"}, + {file = "pyroaring-0.3.4-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:a047cb76fd8d46f7fcac9d67566885a2920ec65a9ddf090e7e29e3496d9ab849"}, + {file = "pyroaring-0.3.4-cp37-cp37m-win32.whl", hash = "sha256:5f446a2817c540ddac125f69a161c56349cbd43981cea303370cdcd76a35660e"}, + {file = "pyroaring-0.3.4-cp37-cp37m-win_amd64.whl", hash = "sha256:1037b5408699acafb5d49868f9dbc43239df385a3d6fe945f9ed4429e8adf440"}, + {file = "pyroaring-0.3.4-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:6e217c983ae6f24728f36bb2ec95464fb2a74d65e8a1e866a7eb2f412c61d00a"}, + {file = "pyroaring-0.3.4-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:fcfc7c9fd0d2f33d0297434bfb76a2bf6bc951fb0cbe86e1824451cb75a787e9"}, + {file = "pyroaring-0.3.4-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:8a22e3d3d24e0daf640a2aad5b8fe86e99ad1a0c49ca0605130b19cf8df934a0"}, + {file = "pyroaring-0.3.4-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7ac83a7f486631c111897a13de1d4ddd166c071980f794cd2ef7f12e96c41f95"}, + {file = "pyroaring-0.3.4-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9046804a12b4337c0320a02f78a73e3c5a9f2e2390bd4b5a59fefccec27d1626"}, + {file = "pyroaring-0.3.4-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:41ec889b0474838237e0f2edcb3aeeb12bf478fcaab6a7e9fc541b1e45e790cf"}, + {file = "pyroaring-0.3.4-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:8088c458bcf8fa8fdf7e174f6d1d3f5c46ef14183ecfdd07dd9741eb6a931a99"}, + {file = "pyroaring-0.3.4-cp38-cp38-win32.whl", hash = "sha256:bbcbf5956a29135dd206398e61c2a0434e8e7d13c77e0a2fafa897b0ae020e97"}, + {file = "pyroaring-0.3.4-cp38-cp38-win_amd64.whl", hash = "sha256:9f38871aff1660af2c043ab16faca61ef8bd1a0079ca31ac8a0088ee5b81b1f9"}, + {file = "pyroaring-0.3.4-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:b05d72e239628eea6cf4e757b284169b470cfa83c24ce3b31ab8b374ce2f2b5e"}, + {file = "pyroaring-0.3.4-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:3567563493f9b609df0d46b34a3d4dab7c8f43cad34bbfb22202f63f688fe627"}, + {file = "pyroaring-0.3.4-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:1f42dd009cbdf5aec8743e9b00cf8e23e83afef38f6d75ab51a2512c578fda79"}, + {file = "pyroaring-0.3.4-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bf32c2b62eeb69f76afea290c1b59b432eab7766751c0d53a2ad957c14f707f2"}, + {file = "pyroaring-0.3.4-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:060c1459c74dc1abd93303e7396d0d4682d0bbefa5c1f1d44c8d19814ce2dd31"}, + {file = "pyroaring-0.3.4-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:4d82a7f03e60f5b2404b917f91b7792a0c03207809ddb8ef16fa36679fa1923b"}, + {file = "pyroaring-0.3.4-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:3a7484ed3fe76acf34b1bfb51b8fd2a153acea6f7270d64fd4be637ae51ebe90"}, + {file = "pyroaring-0.3.4-cp39-cp39-win32.whl", hash = "sha256:c0880fe9f0155cd028662838cde8799aabca588842727fb9495487174bb2477d"}, + {file = "pyroaring-0.3.4-cp39-cp39-win_amd64.whl", hash = "sha256:b68c169b169d90c4e58610e4a352db9530e6de951ee0ac422a7501fcc1e10b0f"}, + {file = "pyroaring-0.3.4.tar.gz", hash = "sha256:0ef2fabf2808b93eb1d884fd637ea96f2c1bfb877797295b5331fd572794e2ce"}, +] pyrsistent = [ {file = "pyrsistent-0.18.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:df46c854f490f81210870e509818b729db4488e1f30f2a1ce1698b2295a878d1"}, {file = "pyrsistent-0.18.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5d45866ececf4a5fff8742c25722da6d4c9e180daa7b405dc0a2a2790d668c26"}, @@ -1836,6 +1889,8 @@ rlp = [ {file = "rlp-3.0.0-py2.py3-none-any.whl", hash = "sha256:d2a963225b3f26795c5b52310e0871df9824af56823d739511583ef459895a7d"}, {file = "rlp-3.0.0.tar.gz", hash = "sha256:63b0465d2948cd9f01de449d7adfb92d207c1aef3982f20310f8009be4a507e8"}, ] +roaring64 = [] +rocksdb = [] setuptools = [ {file = "setuptools-65.5.0-py3-none-any.whl", hash = "sha256:f62ea9da9ed6289bfe868cd6845968a2c854d1427f8548d52cae02a42b4f0356"}, {file = "setuptools-65.5.0.tar.gz", hash = "sha256:512e5536220e38146176efb833d4a62aa726b7bbff82cfbc8ba9eaa3996e0b17"}, @@ -1871,10 +1926,6 @@ toolz = [ {file = "toolz-0.11.2-py3-none-any.whl", hash = "sha256:a5700ce83414c64514d82d60bcda8aabfde092d1c1a8663f9200c07fdcc6da8f"}, {file = "toolz-0.11.2.tar.gz", hash = "sha256:6b312d5e15138552f1bda8a4e66c30e236c831b612b2bf0005f8a1df10a4bc33"}, ] -typing-extensions = [ - {file = "typing_extensions-4.2.0-py3-none-any.whl", hash = "sha256:6657594ee297170d19f67d55c05852a874e7eb634f4f753dbd667855e07c1708"}, - {file = "typing_extensions-4.2.0.tar.gz", hash = "sha256:f1c24655a0da0d1b67f07e17a5e6b2a105894e6824b92096378bb3668ef02376"}, -] urllib3 = [ {file = "urllib3-1.26.9-py2.py3-none-any.whl", hash = "sha256:44ece4d53fb1706f667c9bd1c648f5469a2ec925fcf3a776667042d645472c14"}, {file = "urllib3-1.26.9.tar.gz", hash = "sha256:aabaf16477806a5e1dd19aa41f8c2b7950dd3c746362d7e3223dbe6de6ac448e"}, @@ -2014,7 +2065,3 @@ yarl = [ {file = "yarl-1.7.2-cp39-cp39-win_amd64.whl", hash = "sha256:797c2c412b04403d2da075fb93c123df35239cd7b4cc4e0cd9e5839b73f52c58"}, {file = "yarl-1.7.2.tar.gz", hash = "sha256:45399b46d60c253327a460e99856752009fcee5f5d3c80b2f7c0cae1c38d56dd"}, ] -zipp = [ - {file = "zipp-3.8.0-py3-none-any.whl", hash = "sha256:c4f6e5bbf48e74f7a38e7cc5b0480ff42b0ae5178957d564d18932525d5cf099"}, - {file = "zipp-3.8.0.tar.gz", hash = "sha256:56bf8aadb83c24db6c4b577e13de374ccfb67da2078beba1d037c17980bf43ad"}, -] diff --git a/integration_tests/pyproject.toml b/integration_tests/pyproject.toml index 65ca14c207..54fb3b3f60 100644 --- a/integration_tests/pyproject.toml +++ b/integration_tests/pyproject.toml @@ -5,7 +5,7 @@ description = "" authors = ["chain-dev "] [tool.poetry.dependencies] -python = "^3.8" +python = "^3.10" pytest = "^7.0.1" pytest-github-actions-annotate-failures = "^0.1.1" flake8 = "^4.0.1" @@ -28,6 +28,9 @@ jsonnet = "^0.18.0" eth-account = "^0.7.0" cprotobuf = "^0.1.11" pathspec = "^0.10.1" +rocksdb = { git = "https://github.com/HathorNetwork/python-rocksdb.git", branch = "master" } +click = "^8.1.2" +roaring64 = { git = "https://github.com/yihuang/python-roaring64.git", branch = "main" } [tool.poetry.dev-dependencies] diff --git a/integration_tests/test_benchmark_storage.py b/integration_tests/test_benchmark_storage.py new file mode 100644 index 0000000000..e1782c4b11 --- /dev/null +++ b/integration_tests/test_benchmark_storage.py @@ -0,0 +1,53 @@ +from concurrent.futures import ThreadPoolExecutor +from pathlib import Path + +import pytest +from web3 import Web3 + +from .network import setup_custom_cronos +from .utils import ( + ACCOUNTS, + CONTRACTS, + deploy_contract, + send_transaction, + w3_wait_for_block, +) + + +@pytest.fixture(scope="module") +def custom_cronos(tmp_path_factory): + path = tmp_path_factory.mktemp("benchmark") + yield from setup_custom_cronos( + path, 26200, Path(__file__).parent / "configs/state_benchmark.jsonnet" + ) + + +@pytest.mark.benchmark +def test_benchmark_storage(custom_cronos): + w3: Web3 = custom_cronos.w3 + w3_wait_for_block(w3, 1) + contract = deploy_contract(w3, CONTRACTS["BenchmarkStorage"]) + + n = 3000 + gas = 81500000 + iterations = 200 + parity = 100 + + def task(acct, acct_i): + for i in range(iterations): + seed = i * 10 + acct_i + tx = contract.functions.batch_set(seed, n, n * parity).build_transaction( + {"from": acct.address, "gas": gas} + ) + print(send_transaction(w3, tx, acct.key)) + + accounts = [ + ACCOUNTS["validator"], + ACCOUNTS["community"], + ACCOUNTS["signer1"], + ACCOUNTS["signer2"], + ] + with ThreadPoolExecutor(len(accounts)) as exec: + tasks = [exec.submit(task, acct, i) for i, acct in enumerate(accounts)] + for t in tasks: + t.result() diff --git a/integration_tests/test_streamer.py b/integration_tests/test_streamer.py index 249aa346f2..d003e4c0ed 100644 --- a/integration_tests/test_streamer.py +++ b/integration_tests/test_streamer.py @@ -13,40 +13,22 @@ class StoreKVPairs(ProtoEntity): value = Field("bytes", 4) -def decode_stream_file(data, body_cls=StoreKVPairs, header_cls=None, footer_cls=None): +def decode_stream_file(data, entry_cls=StoreKVPairs): """ - header, body*, footer + StoreKVPairs, StoreKVPairs, ... """ - header = footer = None - body = [] - offset = 0 - size, n = decode_primitive(data, "uint64") - offset += n + assert int.from_bytes(data[:8], "big") + 8 == len(data), "incomplete file" - # header - if header_cls is not None: - header = header_cls() - header.ParseFromString(data[offset : offset + size]) - offset += size - - while True: + items = [] + offset = 8 + while offset < len(data): size, n = decode_primitive(data[offset:], "uint64") offset += n - if offset + size == len(data): - # footer - if footer_cls is not None: - footer = footer_cls() - footer.ParseFromString(data[offset : offset + size]) - offset += size - break - else: - # body - if body_cls is not None: - item = body_cls() - item.ParseFromString(data[offset : offset + size]) - body.append(item) - offset += size - return header, body, footer + item = entry_cls() + item.ParseFromString(data[offset : offset + size]) + items.append(item) + offset += size + return items def test_streamers(cronos): @@ -55,23 +37,22 @@ def test_streamers(cronos): - try to parse the state change sets """ # inspect the first state change of the first tx in genesis - path = cronos.node_home(0) / "data/file_streamer/block-0-tx-0" - _, body, _ = decode_stream_file(open(path, "rb").read()) + # the InitChainer is committed together with the first block. + path = cronos.node_home(0) / "data/file_streamer/block-1-data" + items = decode_stream_file(open(path, "rb").read()) # creation of the validator account - assert body[0].store_key == "acc" - # the order in gen_txs is undeterministic, could be either one. - assert body[0].key in ( - b"\x01" + HexBytes(ADDRS["validator"]), - b"\x01" + HexBytes(ADDRS["validator2"]), - ) + assert items[0].store_key == "acc" + # the writes are sorted by key, find the minimal address + min_addr = min(ADDRS.values()) + assert items[0].key == b"\x01" + HexBytes(min_addr) if __name__ == "__main__": import binascii import sys - _, body, _ = decode_stream_file(open(sys.argv[1], "rb").read()) - for item in body: + items = decode_stream_file(open(sys.argv[1], "rb").read()) + for item in items: print( item.store_key, item.delete, diff --git a/integration_tests/utils.py b/integration_tests/utils.py index 462d472bfa..a714ff3b89 100644 --- a/integration_tests/utils.py +++ b/integration_tests/utils.py @@ -47,6 +47,7 @@ "TestBlackListERC20": "TestBlackListERC20.sol", "CroBridge": "CroBridge.sol", "CronosGravityCancellation": "CronosGravityCancellation.sol", + "BenchmarkStorage": "BenchmarkStorage.sol", } diff --git a/integration_tests/versiondb.py b/integration_tests/versiondb.py new file mode 100644 index 0000000000..40c0c672e0 --- /dev/null +++ b/integration_tests/versiondb.py @@ -0,0 +1,86 @@ +""" +cli utilities for versiondb +""" +import binascii +from pathlib import Path + +import click +import rocksdb +from cprotobuf import decode_primitive +from roaring64 import BitMap64 + + +def rocksdb_stats(path): + db = rocksdb.DB(str(path), rocksdb.Options()) + for field in ["rocksdb.stats", "rocksdb.sstables"]: + print(f"############# {field}") + print(db.get_property(field.encode()).decode()) + + # space amplification + it = db.iteritems() + it.seek_to_first() + count = 0 + size = 0 + for k, v in it: + count += 1 + size += len(k) + len(v) + # directory size + fsize = sum(f.stat().st_size for f in path.glob("**/*") if f.is_file()) + print( + f"space_amplification: {fsize / size:.2f}, kv pairs: {count}, " + f"data size: {size}, file size: {fsize}" + ) + + +@click.group() +def cli(): + pass + + +@cli.command() +@click.option("--dbpath", help="path of plain db") +def latest_version(dbpath): + db = rocksdb.DB(dbpath, rocksdb.Options()) + bz = db.get(b"s/latest") + # gogoproto std int64, the first byte is field tag + print(decode_primitive(bz[1:], "int64")[0]) + + +@cli.command() +@click.option("--dbpath", help="path of version db") +@click.option("--version", help="version of the value, optional") +@click.argument("store-key") +@click.argument("hex-key") +def get(dbpath, version, store_key, hex_key): + """ + get a value at version + """ + key = f"s/k:{store_key}/".decode() + binascii.unhexlify(hex_key) + plain_db = rocksdb.DB(dbpath + "plain.db", rocksdb.Options()) + if version is None: + v = plain_db.get(key) + else: + version = int(version) + print(binascii.hexlify(v)) + + history_db = rocksdb.DB(dbpath + "history.db", rocksdb.Options()) + bz = history_db.get(key) + bm = BitMap64.deserialize(bz) + + # seek in bitmap + bm.Rank(version) + + +@cli.command() +def sync(path): + pass + + +@cli.command() +@click.option("--dbpath", help="path of rocksdb") +def rocksdbstats(dbpath): + rocksdb_stats(Path(dbpath)) + + +if __name__ == "__main__": + cli() diff --git a/nix/testenv.nix b/nix/testenv.nix index e951eccb7f..2e2298d50b 100644 --- a/nix/testenv.nix +++ b/nix/testenv.nix @@ -1,4 +1,4 @@ -{ poetry2nix, lib, python310 }: +{ poetry2nix, lib, python310, rocksdb }: poetry2nix.mkPoetryEnv { projectDir = ../integration_tests; python = python310; @@ -14,6 +14,9 @@ poetry2nix.mkPoetryEnv { pytest-github-actions-annotate-failures = [ "setuptools" ]; flake8-black = [ "setuptools" ]; multiaddr = [ "setuptools" ]; + rocksdb = [ "setuptools" "cython" "pkgconfig" ]; + pyroaring = [ "setuptools" "cython" ]; + roaring64 = [ "poetry" ]; }; in lib.mapAttrs @@ -34,6 +37,11 @@ poetry2nix.mkPoetryEnv { substituteInPlace setup.py --replace "setup()" "setup(version=\"1.3\")" ''; }; + rocksdb = super.rocksdb.overridePythonAttrs ( + old: { + buildInputs = (old.buildInputs or [ ]) ++ [ rocksdb ]; + } + ); }) ]); } diff --git a/scripts/cronos-devnet.yaml b/scripts/cronos-devnet.yaml index 0b9b865e1a..ec2f3c9fe0 100644 --- a/scripts/cronos-devnet.yaml +++ b/scripts/cronos-devnet.yaml @@ -1,7 +1,7 @@ dotenv: .env cronos_777-1: cmd: cronosd - start-flags: "--trace" + start-flags: "--trace --streamers versiondb,file" app-config: minimum-gas-prices: 0basetcro index-events: diff --git a/versiondb/backend_test_utils.go b/versiondb/backend_test_utils.go new file mode 100644 index 0000000000..507ab87ec8 --- /dev/null +++ b/versiondb/backend_test_utils.go @@ -0,0 +1,275 @@ +package versiondb + +import ( + "fmt" + "testing" + + "github.com/stretchr/testify/require" + dbm "github.com/tendermint/tm-db" + + "github.com/cosmos/cosmos-sdk/store/types" +) + +var ( + key1 = []byte("key1") + value1 = []byte("value1") + key1Subkey = []byte("key1/subkey") +) + +func SetupTestDB(t *testing.T, store VersionStore) { + changeSets := [][]types.StoreKVPair{ + { + {StoreKey: "evm", Key: []byte("delete-in-block2"), Value: []byte("1")}, + {StoreKey: "evm", Key: []byte("re-add-in-block3"), Value: []byte("1")}, + {StoreKey: "evm", Key: []byte("z-genesis-only"), Value: []byte("2")}, + {StoreKey: "evm", Key: []byte("modify-in-block2"), Value: []byte("1")}, + {StoreKey: "staking", Key: []byte("key1"), Value: []byte("value1")}, + {StoreKey: "staking", Key: []byte("key1/subkey"), Value: []byte("value1")}, + }, + { + {StoreKey: "evm", Key: []byte("re-add-in-block3"), Delete: true}, + {StoreKey: "evm", Key: []byte("add-in-block1"), Value: []byte("1")}, + {StoreKey: "staking", Key: []byte("key1"), Delete: true}, + }, + { + {StoreKey: "evm", Key: []byte("add-in-block2"), Value: []byte("1")}, + {StoreKey: "evm", Key: []byte("delete-in-block2"), Delete: true}, + {StoreKey: "evm", Key: []byte("modify-in-block2"), Value: []byte("2")}, + {StoreKey: "evm", Key: []byte("key2"), Delete: true}, + {StoreKey: "staking", Key: []byte("key1"), Value: []byte("value2")}, + }, + { + {StoreKey: "evm", Key: []byte("re-add-in-block3"), Value: []byte("2")}, + }, + { + {StoreKey: "evm", Key: []byte("re-add-in-block3"), Delete: true}, + }, + } + for i, changeSet := range changeSets { + require.NoError(t, store.PutAtVersion(int64(i), changeSet)) + } +} + +func Run(t *testing.T, storeCreator func() VersionStore) { + testBasics(t, storeCreator()) + testIterator(t, storeCreator()) + testHeightInFuture(t, storeCreator()) + + // test delete in genesis + store := storeCreator() + err := store.PutAtVersion(0, []types.StoreKVPair{ + {StoreKey: "evm", Key: []byte{1}, Delete: true}, + }) + require.Error(t, err) +} + +func testBasics(t *testing.T, store VersionStore) { + var v int64 + + SetupTestDB(t, store) + + value, err := store.GetAtVersion("evm", []byte("z-genesis-only"), nil) + require.NoError(t, err) + require.Equal(t, value, []byte("2")) + + v = 4 + ok, err := store.HasAtVersion("evm", []byte("z-genesis-only"), &v) + require.NoError(t, err) + require.True(t, ok) + value, err = store.GetAtVersion("evm", []byte("z-genesis-only"), &v) + require.NoError(t, err) + require.Equal(t, value, []byte("2")) + + value, err = store.GetAtVersion("evm", []byte("re-add-in-block3"), nil) + require.NoError(t, err) + require.Empty(t, value) + + ok, err = store.HasAtVersion("staking", key1, nil) + require.NoError(t, err) + require.True(t, ok) + + value, err = store.GetAtVersion("staking", key1, nil) + require.NoError(t, err) + require.Equal(t, value, []byte("value2")) + + v = 2 + value, err = store.GetAtVersion("staking", key1, &v) + require.NoError(t, err) + require.Equal(t, value, []byte("value2")) + + ok, err = store.HasAtVersion("staking", key1, &v) + require.NoError(t, err) + require.True(t, ok) + + v = 0 + value, err = store.GetAtVersion("staking", key1, &v) + require.NoError(t, err) + require.Equal(t, value, []byte("value1")) + + v = 1 + value, err = store.GetAtVersion("staking", key1, &v) + require.NoError(t, err) + require.Empty(t, value) + + ok, err = store.HasAtVersion("staking", key1, &v) + require.NoError(t, err) + require.False(t, ok) + + v = 0 + value, err = store.GetAtVersion("staking", key1, &v) + require.NoError(t, err) + require.Equal(t, value1, value) + value, err = store.GetAtVersion("staking", key1Subkey, &v) + require.NoError(t, err) + require.Equal(t, value1, value) +} + +type KVPair struct { + Key []byte + Value []byte +} + +func testIterator(t *testing.T, store VersionStore) { + SetupTestDB(t, store) + + expItems := [][]KVPair{ + { + KVPair{[]byte("delete-in-block2"), []byte("1")}, + KVPair{[]byte("modify-in-block2"), []byte("1")}, + KVPair{[]byte("re-add-in-block3"), []byte("1")}, + KVPair{[]byte("z-genesis-only"), []byte("2")}, + }, + { + KVPair{[]byte("add-in-block1"), []byte("1")}, + KVPair{[]byte("delete-in-block2"), []byte("1")}, + KVPair{[]byte("modify-in-block2"), []byte("1")}, + KVPair{[]byte("z-genesis-only"), []byte("2")}, + }, + { + KVPair{[]byte("add-in-block1"), []byte("1")}, + KVPair{[]byte("add-in-block2"), []byte("1")}, + KVPair{[]byte("modify-in-block2"), []byte("2")}, + KVPair{[]byte("z-genesis-only"), []byte("2")}, + }, + { + KVPair{[]byte("add-in-block1"), []byte("1")}, + KVPair{[]byte("add-in-block2"), []byte("1")}, + KVPair{[]byte("modify-in-block2"), []byte("2")}, + KVPair{[]byte("re-add-in-block3"), []byte("2")}, + KVPair{[]byte("z-genesis-only"), []byte("2")}, + }, + { + KVPair{[]byte("add-in-block1"), []byte("1")}, + KVPair{[]byte("add-in-block2"), []byte("1")}, + KVPair{[]byte("modify-in-block2"), []byte("2")}, + KVPair{[]byte("z-genesis-only"), []byte("2")}, + }, + } + for i, exp := range expItems { + t.Run(fmt.Sprintf("block-%d", i), func(t *testing.T) { + v := int64(i) + it, err := store.IteratorAtVersion("evm", nil, nil, &v) + require.NoError(t, err) + require.Equal(t, exp, consumeIterator(it)) + + it, err = store.ReverseIteratorAtVersion("evm", nil, nil, &v) + require.NoError(t, err) + actual := consumeIterator(it) + require.Equal(t, len(exp), len(actual)) + require.Equal(t, reversed(exp), actual) + }) + } + + it, err := store.IteratorAtVersion("evm", nil, nil, nil) + require.NoError(t, err) + require.Equal(t, expItems[len(expItems)-1], consumeIterator(it)) + + it, err = store.ReverseIteratorAtVersion("evm", nil, nil, nil) + require.NoError(t, err) + require.Equal(t, reversed(expItems[len(expItems)-1]), consumeIterator(it)) + + // with start parameter + v := int64(2) + it, err = store.IteratorAtVersion("evm", []byte("\xff"), nil, &v) + require.NoError(t, err) + require.Empty(t, consumeIterator(it)) + it, err = store.ReverseIteratorAtVersion("evm", nil, []byte("\x00"), &v) + require.NoError(t, err) + require.Empty(t, consumeIterator(it)) + + it, err = store.IteratorAtVersion("evm", []byte("modify-in-block2"), nil, &v) + require.NoError(t, err) + require.Equal(t, expItems[2][len(expItems[2])-2:], consumeIterator(it)) + + it, err = store.ReverseIteratorAtVersion("evm", nil, []byte("mp"), &v) + require.NoError(t, err) + require.Equal(t, + reversed(expItems[2][:len(expItems[2])-1]), + consumeIterator(it), + ) + + it, err = store.ReverseIteratorAtVersion("evm", nil, []byte("modify-in-block3"), &v) + require.NoError(t, err) + require.Equal(t, + reversed(expItems[2][:len(expItems[2])-1]), + consumeIterator(it), + ) + + // delete the last key, cover some edge cases + v = int64(len(expItems)) + err = store.PutAtVersion( + v, + []types.StoreKVPair{ + {StoreKey: "evm", Key: []byte("z-genesis-only"), Delete: true}, + }, + ) + require.NoError(t, err) + it, err = store.IteratorAtVersion("evm", nil, nil, &v) + require.NoError(t, err) + require.Equal(t, + expItems[v-1][:len(expItems[v-1])-1], + consumeIterator(it), + ) + v-- + it, err = store.IteratorAtVersion("evm", nil, nil, &v) + require.NoError(t, err) + require.Equal(t, + expItems[v], + consumeIterator(it), + ) +} + +func testHeightInFuture(t *testing.T, store VersionStore) { + SetupTestDB(t, store) + + latest, err := store.GetLatestVersion() + require.NoError(t, err) + + v := latest + 1 + _, err = store.GetAtVersion("staking", key1, &v) + require.Error(t, err) + _, err = store.HasAtVersion("staking", key1, &v) + require.Error(t, err) + _, err = store.IteratorAtVersion("staking", nil, nil, &v) + require.Error(t, err) + _, err = store.ReverseIteratorAtVersion("staking", nil, nil, &v) + require.Error(t, err) +} + +func consumeIterator(it dbm.Iterator) []KVPair { + var result []KVPair + for ; it.Valid(); it.Next() { + result = append(result, KVPair{it.Key(), it.Value()}) + } + it.Close() + return result +} + +// reversed clone and reverse the slice +func reversed[S ~[]E, E any](s S) []E { + r := make([]E, len(s)) + for i, j := 0, len(s)-1; i <= j; i, j = i+1, j-1 { + r[i], r[j] = s[j], s[i] + } + return r +} diff --git a/versiondb/multistore.go b/versiondb/multistore.go new file mode 100644 index 0000000000..4871558fd9 --- /dev/null +++ b/versiondb/multistore.go @@ -0,0 +1,135 @@ +package versiondb + +import ( + "io" + "sync" + + "github.com/cosmos/cosmos-sdk/store/cachemulti" + "github.com/cosmos/cosmos-sdk/store/mem" + "github.com/cosmos/cosmos-sdk/store/transient" + "github.com/cosmos/cosmos-sdk/store/types" + sdk "github.com/cosmos/cosmos-sdk/types" +) + +var _ sdk.MultiStore = (*MultiStore)(nil) + +type MultiStore struct { + versionDB VersionStore + storeKeys []types.StoreKey + + // transient or memory stores + transientStores map[types.StoreKey]types.KVStore + + traceWriter io.Writer + traceContext types.TraceContext + traceContextMutex sync.Mutex +} + +func NewMultiStore(versionDB VersionStore, storeKeys []types.StoreKey) *MultiStore { + return &MultiStore{versionDB: versionDB, storeKeys: storeKeys, transientStores: make(map[types.StoreKey]types.KVStore)} +} + +func (s *MultiStore) GetStoreType() types.StoreType { + return types.StoreTypeMulti +} + +func (s *MultiStore) cacheMultiStore(version *int64) sdk.CacheMultiStore { + stores := make(map[types.StoreKey]types.CacheWrapper, len(s.transientStores)+len(s.storeKeys)) + for k, v := range s.transientStores { + stores[k] = v + } + for _, k := range s.storeKeys { + stores[k] = NewKVStore(s.versionDB, k, version) + } + return cachemulti.NewStore(nil, stores, nil, s.traceWriter, s.getTracingContext()) +} + +func (s *MultiStore) CacheMultiStore() sdk.CacheMultiStore { + return s.cacheMultiStore(nil) +} + +func (s *MultiStore) CacheMultiStoreWithVersion(version int64) (sdk.CacheMultiStore, error) { + return s.cacheMultiStore(&version), nil +} + +// CacheWrap implements CacheWrapper/MultiStore/CommitStore. +func (s *MultiStore) CacheWrap() types.CacheWrap { + return s.CacheMultiStore().(types.CacheWrap) +} + +// CacheWrapWithTrace implements the CacheWrapper interface. +func (s *MultiStore) CacheWrapWithTrace(_ io.Writer, _ types.TraceContext) types.CacheWrap { + return s.CacheWrap() +} + +func (s *MultiStore) GetStore(storeKey types.StoreKey) sdk.Store { + return s.GetKVStore(storeKey) +} + +func (s *MultiStore) GetKVStore(storeKey types.StoreKey) sdk.KVStore { + store, ok := s.transientStores[storeKey] + if ok { + return store + } + return NewKVStore(s.versionDB, storeKey, nil) +} + +func (s *MultiStore) MountTransientStores(keys map[string]*types.TransientStoreKey) { + for _, key := range keys { + s.transientStores[key] = transient.NewStore() + } +} + +func (s *MultiStore) MountMemoryStores(keys map[string]*types.MemoryStoreKey) { + for _, key := range keys { + s.transientStores[key] = mem.NewStore() + } +} + +// SetTracer sets the tracer for the MultiStore that the underlying +// stores will utilize to trace operations. A MultiStore is returned. +func (s *MultiStore) SetTracer(w io.Writer) types.MultiStore { + s.traceWriter = w + return s +} + +// SetTracingContext updates the tracing context for the MultiStore by merging +// the given context with the existing context by key. Any existing keys will +// be overwritten. It is implied that the caller should update the context when +// necessary between tracing operations. It returns a modified MultiStore. +func (s *MultiStore) SetTracingContext(tc types.TraceContext) types.MultiStore { + s.traceContextMutex.Lock() + defer s.traceContextMutex.Unlock() + s.traceContext = s.traceContext.Merge(tc) + + return s +} + +func (s *MultiStore) getTracingContext() types.TraceContext { + s.traceContextMutex.Lock() + defer s.traceContextMutex.Unlock() + + if s.traceContext == nil { + return nil + } + + ctx := types.TraceContext{} + for k, v := range s.traceContext { + ctx[k] = v + } + + return ctx +} + +// TracingEnabled returns if tracing is enabled for the MultiStore. +func (s *MultiStore) TracingEnabled() bool { + return s.traceWriter != nil +} + +func (s *MultiStore) LatestVersion() int64 { + version, err := s.versionDB.GetLatestVersion() + if err != nil { + panic(err) + } + return version +} diff --git a/versiondb/store.go b/versiondb/store.go new file mode 100644 index 0000000000..283e846496 --- /dev/null +++ b/versiondb/store.go @@ -0,0 +1,96 @@ +package versiondb + +import ( + "io" + "time" + + "github.com/cosmos/cosmos-sdk/store/cachekv" + "github.com/cosmos/cosmos-sdk/store/listenkv" + "github.com/cosmos/cosmos-sdk/store/tracekv" + "github.com/cosmos/cosmos-sdk/store/types" + "github.com/cosmos/cosmos-sdk/telemetry" +) + +const StoreTypeVersionDB = 100 + +var _ types.KVStore = (*Store)(nil) + +// Store Implements types.KVStore +type Store struct { + store VersionStore + storeKey types.StoreKey + version *int64 +} + +func NewKVStore(store VersionStore, storeKey types.StoreKey, version *int64) *Store { + return &Store{store, storeKey, version} +} + +// Implements Store. +func (st *Store) GetStoreType() types.StoreType { + // should have effect, just define an unique indentifier, don't be conflicts with cosmos-sdk's builtin ones. + return StoreTypeVersionDB +} + +// Implements Store. +func (st *Store) CacheWrap() types.CacheWrap { + return cachekv.NewStore(st) +} + +// CacheWrapWithTrace implements the Store interface. +func (st *Store) CacheWrapWithTrace(w io.Writer, tc types.TraceContext) types.CacheWrap { + return cachekv.NewStore(tracekv.NewStore(st, w, tc)) +} + +// CacheWrapWithListeners implements the CacheWrapper interface. +func (st *Store) CacheWrapWithListeners(storeKey types.StoreKey, listeners []types.WriteListener) types.CacheWrap { + return cachekv.NewStore(listenkv.NewStore(st, storeKey, listeners)) +} + +// Implements types.KVStore. +func (st *Store) Get(key []byte) []byte { + defer telemetry.MeasureSince(time.Now(), "store", "iavl", "get") + value, err := st.store.GetAtVersion(st.storeKey.Name(), key, st.version) + if err != nil { + panic(err) + } + return value +} + +// Implements types.KVStore. +func (st *Store) Has(key []byte) (exists bool) { + defer telemetry.MeasureSince(time.Now(), "store", "iavl", "has") + has, err := st.store.HasAtVersion(st.storeKey.Name(), key, st.version) + if err != nil { + panic(err) + } + return has +} + +// Implements types.KVStore. +func (st *Store) Iterator(start, end []byte) types.Iterator { + itr, err := st.store.IteratorAtVersion(st.storeKey.Name(), start, end, st.version) + if err != nil { + panic(err) + } + return itr +} + +// Implements types.KVStore. +func (st *Store) ReverseIterator(start, end []byte) types.Iterator { + itr, err := st.store.ReverseIteratorAtVersion(st.storeKey.Name(), start, end, st.version) + if err != nil { + panic(err) + } + return itr +} + +// Implements types.KVStore. +func (st *Store) Set(key, value []byte) { + panic("write operation is not supported") +} + +// Implements types.KVStore. +func (st *Store) Delete(key []byte) { + panic("write operation is not supported") +} diff --git a/versiondb/streaming_service.go b/versiondb/streaming_service.go new file mode 100644 index 0000000000..f61732333d --- /dev/null +++ b/versiondb/streaming_service.go @@ -0,0 +1,84 @@ +package versiondb + +import ( + "context" + "sort" + "strings" + "sync" + + abci "github.com/tendermint/tendermint/abci/types" + + "github.com/cosmos/cosmos-sdk/baseapp" + "github.com/cosmos/cosmos-sdk/store/types" +) + +var _ baseapp.StreamingService = &StreamingService{} + +// StreamingService is a concrete implementation of StreamingService that accumulate the state changes in current block, +// writes the ordered changeset out to version storage. +type StreamingService struct { + listeners []*types.MemoryListener // the listeners that will be initialized with BaseApp + versionStore VersionStore + currentBlockNumber int64 // the current block number +} + +// NewStreamingService creates a new StreamingService for the provided writeDir, (optional) filePrefix, and storeKeys +func NewStreamingService(versionStore VersionStore, storeKeys []types.StoreKey) *StreamingService { + // sort by the storeKeys first + sort.SliceStable(storeKeys, func(i, j int) bool { + return strings.Compare(storeKeys[i].Name(), storeKeys[j].Name()) < 0 + }) + + listeners := make([]*types.MemoryListener, len(storeKeys)) + for i, key := range storeKeys { + listeners[i] = types.NewMemoryListener(key) + } + return &StreamingService{listeners, versionStore, 0} +} + +// Listeners satisfies the baseapp.StreamingService interface +func (fss *StreamingService) Listeners() map[types.StoreKey][]types.WriteListener { + listeners := make(map[types.StoreKey][]types.WriteListener, len(fss.listeners)) + for _, listener := range fss.listeners { + listeners[listener.StoreKey()] = []types.WriteListener{listener} + } + return listeners +} + +// ListenBeginBlock satisfies the baseapp.ABCIListener interface +// It sets the currentBlockNumber. +func (fss *StreamingService) ListenBeginBlock(ctx context.Context, req abci.RequestBeginBlock, res abci.ResponseBeginBlock) error { + fss.currentBlockNumber = req.GetHeader().Height + return nil +} + +// ListenDeliverTx satisfies the baseapp.ABCIListener interface +func (fss *StreamingService) ListenDeliverTx(ctx context.Context, req abci.RequestDeliverTx, res abci.ResponseDeliverTx) error { + return nil +} + +// ListenEndBlock satisfies the baseapp.ABCIListener interface +// It merge the state caches of all the listeners together, and write out to the versionStore. +func (fss *StreamingService) ListenEndBlock(ctx context.Context, req abci.RequestEndBlock, res abci.ResponseEndBlock) error { + return nil +} + +func (fss *StreamingService) ListenCommit(ctx context.Context, res abci.ResponseCommit) error { + // concat the state caches + var changeSet []types.StoreKVPair + for _, listener := range fss.listeners { + changeSet = append(changeSet, listener.PopStateCache()...) + } + + return fss.versionStore.PutAtVersion(fss.currentBlockNumber, changeSet) +} + +// Stream satisfies the baseapp.StreamingService interface +func (fss *StreamingService) Stream(wg *sync.WaitGroup) error { + return nil +} + +// Close satisfies the io.Closer interface, which satisfies the baseapp.StreamingService interface +func (fss *StreamingService) Close() error { + return nil +} diff --git a/versiondb/sync.go b/versiondb/sync.go new file mode 100644 index 0000000000..4c89590e4c --- /dev/null +++ b/versiondb/sync.go @@ -0,0 +1,31 @@ +package versiondb + +import ( + "bufio" + "io" + + protoio "github.com/gogo/protobuf/io" + + "github.com/cosmos/cosmos-sdk/store/types" +) + +const maxItemSize = 64000000 // SDK has no key/value size limit, so we set an arbitrary limit + +// ReadFileStreamer parse a binary stream dumped by file streamer to changeset, +// which can be feeded to version store. +func ReadFileStreamer(input *bufio.Reader) ([]types.StoreKVPair, error) { + var changeSet []types.StoreKVPair + reader := protoio.NewDelimitedReader(input, maxItemSize) + for { + var msg types.StoreKVPair + err := reader.ReadMsg(&msg) + if err != nil { + if err == io.EOF { + break + } + return nil, err + } + changeSet = append(changeSet, msg) + } + return changeSet, nil +} diff --git a/versiondb/sync_test.go b/versiondb/sync_test.go new file mode 100644 index 0000000000..23b86e58d4 --- /dev/null +++ b/versiondb/sync_test.go @@ -0,0 +1,30 @@ +package versiondb + +import ( + "bufio" + "bytes" + "encoding/hex" + "strings" + "testing" + + "github.com/cosmos/cosmos-sdk/store/types" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/stretchr/testify/require" +) + +const data = "0000000000000873230a0462616e6b1a06007374616b65221332303030303030303832333839303139353230300a0462616e6b1a1b021493354845030274cd4bf1686abd60ab28ec52e1a77374616b65220b3832333839303139353230250a0462616e6b10011a1b0214dc6f17bbec824fff8f86587966b2047db6ab73677374616b65250a0462616e6b10011a1b0214f1829676db577682e944fc3493d451b67ff3e29f7374616b65270a0462616e6b1a1c037374616b65001493354845030274cd4bf1686abd60ab28ec52e1a7220100260a0462616e6b10011a1c037374616b650014dc6f17bbec824fff8f86587966b2047db6ab7367260a0462616e6b10011a1c037374616b650014f1829676db577682e944fc3493d451b67ff3e29f3a0a0c646973747269627574696f6e1a010022270a250a057374616b65121c31363437373830333930343030303030303030303030303030303030290a0c646973747269627574696f6e1a010122160a14c352ad46450b10f1763ab28ade60aeecf4a276e7500a0c646973747269627574696f6e1a16021438b4089f7762e0c20e9bed8e991e074550ef5a5222280a260a057374616b65121d3432343330333435303532383030303030303030303030303030303030500a0c646973747269627574696f6e1a16021457f96e6b86cdefdb3d412547816a82e3e0ebf9d222280a260a057374616b65121d3338333130383934303736383030303030303030303030303030303030520a0c646973747269627574696f6e1a16061438b4089f7762e0c20e9bed8e991e074550ef5a52222a0a260a057374616b65121d33383138373331303534373532303030303030303030303030303030301002520a0c646973747269627574696f6e1a16061457f96e6b86cdefdb3d412547816a82e3e0ebf9d2222a0a260a057374616b65121d333434373938303436363931323030303030303030303030303030303010024f0a0c646973747269627574696f6e1a16071438b4089f7762e0c20e9bed8e991e074550ef5a5222270a250a057374616b65121c343234333033343530353238303030303030303030303030303030304f0a0c646973747269627574696f6e1a16071457f96e6b86cdefdb3d412547816a82e3e0ebf9d222270a250a057374616b65121c33383331303839343037363830303030303030303030303030303030180a096665656d61726b65741a010122080000000000000000450a046d696e741a0100223a0a1231323939393939373937313031363533303112243235393939393936343737353631363138383736303138323436303338333338383834332a0a06706172616d731a116665656d61726b65742f42617365466565220d223736363136313830393832225b0a08736c617368696e671a1601145c0f70af16fa6e056d5a722651c586b24f10908322370a3163726376616c636f6e7331747338687074636b6c666871326d323677676e39723376786b663833707979726c7067616832180122005b0a08736c617368696e671a160114c352ad46450b10f1763ab28ade60aeecf4a276e722370a3163726376616c636f6e73316364663236336a39707667307a6133366b32396475633977616e363279616838736b71686d7418012200cb070a077374616b696e671a02503222bb070a92030a02080b120c63726f6e6f735f3737372d311802220c08ebdc919c0610f89ce7db022a480a204f4280f40de2dea51618996576a960ee849cf8c605af6ea7912b7d462dfbf21c1224080112207b8624266881e12487a887ec8b2a5744d496422c245f33925f2b33ecd0c0ce8b3220b17b7bc6e2317e48eeab99202baf538fee726ac57f81d8f99e1cd94fa8ac48e03a20e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855422095e4fff352417c37f09c26c5c89e1939fb995f1d477b272d0f450ed1e6b779d34a2095e4fff352417c37f09c26c5c89e1939fb995f1d477b272d0f450ed1e6b779d35220252fe7cf36dd1bb85dafc47a08961df0cfd8c027defa5e01e958be121599db9d5a20a911dcd4c68befef4cf9798ee12c94da9ee2d60b5c43f620814d1e59ef3ad0316220e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b8556a20e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b8557214c352ad46450b10f1763ab28ade60aeecf4a276e71290020a3163726376616c6f70657231387a367133386d68767473767972356d616b38666a38733867346777376b6a6a70306530646812430a1d2f636f736d6f732e63727970746f2e656432353531392e5075624b657912220a20cdc66f7519ba5a3101c5b62a65bd4a7a767e9cadb22504e25bf1fdf78433109220032a13313030303030303030303030303030303030303225313030303030303030303030303030303030303030303030303030303030303030303030303a070a056e6f6465314a00524a0a3b0a1231303030303030303030303030303030303012123230303030303030303030303030303030301a113130303030303030303030303030303030120b08e4dc919c0610f0b180535a01311290020a3163726376616c6f70657231326c756b75367578656868616b303270793472637a36357a753073776837776a36756c726c6712430a1d2f636f736d6f732e63727970746f2e656432353531392e5075624b657912220a20b7eda2d527f8ecf441ad339841632bfe87b289de17d95d309fc091f7065ff75520032a13313030303030303030303030303030303030303225313030303030303030303030303030303030303030303030303030303030303030303030303a070a056e6f6465304a00524a0a3b0a1231303030303030303030303030303030303012123230303030303030303030303030303030301a113130303030303030303030303030303030120b08e4dc919c0610f0b180535a0131" + +func TestReadFileStreamer(t *testing.T) { + buf, err := hex.DecodeString(strings.Replace(data, "\n", "", -1)) + require.NoError(t, err) + + size := sdk.BigEndianToUint64(buf[:8]) + require.Equal(t, size+8, uint64(len(buf))) + + changeSet, err := ReadFileStreamer(bufio.NewReader(bytes.NewReader(buf[8:]))) + require.NoError(t, err) + + require.Equal(t, 21, len(changeSet)) + expItem := types.StoreKVPair{StoreKey: "bank", Delete: false, Key: []uint8{0x0, 0x73, 0x74, 0x61, 0x6b, 0x65}, Value: []uint8{0x32, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x38, 0x32, 0x33, 0x38, 0x39, 0x30, 0x31, 0x39, 0x35, 0x32, 0x30}} + require.Equal(t, expItem, changeSet[0]) +} diff --git a/versiondb/tmdb/history.go b/versiondb/tmdb/history.go new file mode 100644 index 0000000000..0b0438b3ec --- /dev/null +++ b/versiondb/tmdb/history.go @@ -0,0 +1,67 @@ +package tmdb + +import ( + "bytes" + + "github.com/RoaringBitmap/roaring/roaring64" + + "github.com/crypto-org-chain/cronos/versiondb" + dbm "github.com/tendermint/tm-db" +) + +// GetHistoryIndex returns the history index bitmap. +func GetHistoryIndex(db dbm.DB, key []byte) (*roaring64.Bitmap, error) { + // try to seek the first chunk whose maximum is bigger or equal to the target height. + bz, err := db.Get(key) + if err != nil { + return nil, err + } + if len(bz) == 0 { + return nil, nil + } + m := roaring64.New() + _, err = m.ReadFrom(bytes.NewReader(bz)) + if err != nil { + return nil, err + } + return m, nil +} + +// SeekHistoryIndex locate the minimal version that changed the key and is larger than the target version, +// using the returned version can find the value for the target version in changeset table. +// If not found, return -1 +func SeekHistoryIndex(db dbm.DB, key []byte, version uint64) (int64, error) { + m, err := GetHistoryIndex(db, key) + if err != nil { + return -1, err + } + found, ok := versiondb.SeekInBitmap64(m, version+1) + if !ok { + return -1, nil + } + return int64(found), nil +} + +// WriteHistoryIndex set the block height to the history bitmap. +// it try to set to the last chunk, if the last chunk exceeds chunk limit, split it. +func WriteHistoryIndex(db dbm.DB, batch dbm.Batch, key []byte, height uint64) error { + bz, err := db.Get(key) + if err != nil { + return err + } + + m := roaring64.New() + if len(bz) > 0 { + _, err = m.ReadFrom(bytes.NewReader(bz)) + if err != nil { + return err + } + } + m.Add(height) + m.RunOptimize() + bz, err = m.ToBytes() + if err != nil { + return err + } + return batch.Set(key, bz) +} diff --git a/versiondb/tmdb/iterator.go b/versiondb/tmdb/iterator.go new file mode 100644 index 0000000000..bdbc9a6e6d --- /dev/null +++ b/versiondb/tmdb/iterator.go @@ -0,0 +1,183 @@ +package tmdb + +import ( + "bytes" + + "github.com/RoaringBitmap/roaring/roaring64" + "github.com/cosmos/cosmos-sdk/store/types" + "github.com/crypto-org-chain/cronos/versiondb" + dbm "github.com/tendermint/tm-db" +) + +type Iterator struct { + storeKey string + version int64 + + start, end []byte + + plain, history types.Iterator + changesetDB dbm.DB + + key, value []byte + + reverse bool + status int + err error +} + +var _ types.Iterator = (*Iterator)(nil) + +func NewIterator(storeKey string, version int64, plainDB, historyDB types.KVStore, changesetDB dbm.DB, start, end []byte, reverse bool) (types.Iterator, error) { + var plain, history types.Iterator + + if reverse { + plain = plainDB.ReverseIterator(start, end) + } else { + plain = plainDB.Iterator(start, end) + } + + if reverse { + history = historyDB.ReverseIterator(start, end) + } else { + history = historyDB.Iterator(start, end) + } + iter := &Iterator{ + storeKey: storeKey, version: version, + reverse: reverse, + start: start, end: end, + plain: plain, history: history, + changesetDB: changesetDB, + } + iter.err = iter.resolve() + return iter, nil +} + +// Domain implements types.Iterator. +func (iter *Iterator) Domain() ([]byte, []byte) { + return iter.start, iter.end +} + +func (iter *Iterator) Valid() bool { + return iter.err == nil && len(iter.key) > 0 +} + +func (iter *Iterator) Next() { + switch iter.status { + case -2: + return + case 0: + iter.plain.Next() + iter.history.Next() + case 1: + iter.history.Next() + case -1: + iter.plain.Next() + } + iter.err = iter.resolve() +} + +func (iter *Iterator) Key() []byte { + return iter.key +} + +func (iter *Iterator) Value() []byte { + return iter.value +} + +func (iter *Iterator) Close() error { + err1 := iter.plain.Close() + err2 := iter.history.Close() + if err1 != nil { + return err1 + } + if err2 != nil { + return err2 + } + return nil +} + +func (iter *Iterator) Error() error { + return iter.err +} + +func (iter *Iterator) getFromHistory(key []byte, bz []byte, getLatestValue func() []byte) ([]byte, error) { + m := roaring64.New() + _, err := m.ReadFrom(bytes.NewReader(bz)) + if err != nil { + return nil, err + } + found, ok := versiondb.SeekInBitmap64(m, uint64(iter.version)+1) + if !ok { + // not changed, use the latest one + return getLatestValue(), nil + } + changesetKey := ChangesetKey(found, prependStoreKey(iter.storeKey, key)) + return iter.changesetDB.Get(changesetKey) +} + +func (iter *Iterator) resolve() (err error) { + for { + var pkey, hkey []byte + if iter.plain.Valid() { + pkey = iter.plain.Key() + } + if iter.history.Valid() { + hkey = iter.history.Key() + } + + iter.status = compareKey(pkey, hkey, iter.reverse) + switch iter.status { + case -2: + // end of iteration + iter.key = nil + iter.value = nil + return nil + case 0: + // find the historial value, or fallback to latest one. + iter.key = hkey + iter.value, err = iter.getFromHistory(hkey, iter.history.Value(), func() []byte { + return iter.plain.Value() + }) + if len(iter.value) > 0 { + return + } + iter.plain.Next() + iter.history.Next() + case 1: + // plain state exhausted or history cursor lag behind + // the key is deleted in plain state, use the history state. + iter.key = hkey + iter.value, err = iter.getFromHistory(hkey, iter.history.Value(), func() []byte { + return nil + }) + if len(iter.value) > 0 { + return + } + iter.history.Next() + case -1: + // history state exhausted or plain cursor lag behind + // the key don't exist in history state, use the plain state value. + iter.key = pkey + iter.value = iter.plain.Value() + return + } + } +} + +// compareKey is similar to bytes.Compare, but it treat empty slice as biggest value. +func compareKey(k1, k2 []byte, reverse bool) int { + switch { + case len(k1) == 0 && len(k2) == 0: + return -2 + case len(k1) == 0: + return 1 + case len(k2) == 0: + return -1 + default: + result := bytes.Compare(k1, k2) + if reverse { + result = -result + } + return result + } +} diff --git a/versiondb/tmdb/store.go b/versiondb/tmdb/store.go new file mode 100644 index 0000000000..e59914827a --- /dev/null +++ b/versiondb/tmdb/store.go @@ -0,0 +1,265 @@ +package tmdb + +import ( + "bytes" + "errors" + "fmt" + + "github.com/cosmos/cosmos-sdk/store/dbadapter" + "github.com/cosmos/cosmos-sdk/store/prefix" + "github.com/cosmos/cosmos-sdk/store/types" + sdk "github.com/cosmos/cosmos-sdk/types" + gogotypes "github.com/cosmos/gogoproto/types" + "github.com/crypto-org-chain/cronos/versiondb" + dbm "github.com/tendermint/tm-db" +) + +const latestVersionKey = "s/latest" + +var _ versiondb.VersionStore = (*Store)(nil) + +// Store implements `VersionStore`. +type Store struct { + // latest key-value pairs + plainDB dbm.DB + // history bitmap index of keys + historyDB dbm.DB + // changesets of each blocks + changesetDB dbm.DB +} + +func NewStore(plainDB, historyDB, changesetDB dbm.DB) *Store { + return &Store{plainDB, historyDB, changesetDB} +} + +// PutAtVersion implements VersionStore interface +func (s *Store) PutAtVersion(version int64, changeSet []types.StoreKVPair) error { + plainBatch := s.plainDB.NewBatch() + defer plainBatch.Close() + historyBatch := s.historyDB.NewBatch() + defer historyBatch.Close() + changesetBatch := s.changesetDB.NewBatch() + defer changesetBatch.Close() + + for _, pair := range changeSet { + key := prependStoreKey(pair.StoreKey, pair.Key) + + if version == 0 { + // genesis state is written into plain state directly + if pair.Delete { + return errors.New("can't delete at genesis") + } + if err := plainBatch.Set(key, pair.Value); err != nil { + return err + } + continue + } + + original, err := s.plainDB.Get(key) + if err != nil { + return err + } + if bytes.Equal(original, pair.Value) { + // do nothing if the value is not changed + continue + } + + // write history index + if err := WriteHistoryIndex(s.historyDB, historyBatch, key, uint64(version)); err != nil { + return err + } + + // write the old value to changeset + if len(original) > 0 { + changesetKey := append(sdk.Uint64ToBigEndian(uint64(version)), key...) + if err := changesetBatch.Set(changesetKey, original); err != nil { + return err + } + } + + // write the new value to plain state + if pair.Delete { + if err := plainBatch.Delete(key); err != nil { + return err + } + } else { + if err := plainBatch.Set(key, pair.Value); err != nil { + return err + } + } + } + + // write latest version to plain state + if err := s.setLatestVersion(plainBatch, version); err != nil { + return err + } + + if err := changesetBatch.WriteSync(); err != nil { + return err + } + if err := historyBatch.WriteSync(); err != nil { + return err + } + return plainBatch.WriteSync() +} + +// GetAtVersion implements VersionStore interface +func (s *Store) GetAtVersion(storeKey string, key []byte, version *int64) ([]byte, error) { + rawKey := prependStoreKey(storeKey, key) + if version == nil { + return s.plainDB.Get(rawKey) + } + + height := *version + + // optimize for latest version + latest, err := s.GetLatestVersion() + if err != nil { + return nil, err + } + if height > latest { + return nil, fmt.Errorf("height %d is in the future", height) + } + if latest == height { + return s.plainDB.Get(rawKey) + } + + found, err := SeekHistoryIndex(s.historyDB, rawKey, uint64(height)) + if err != nil { + return nil, err + } + if found < 0 { + // there's no change records found after the target version, query the latest state. + return s.plainDB.Get(rawKey) + } + // get from changeset + changesetKey := ChangesetKey(uint64(found), rawKey) + return s.changesetDB.Get(changesetKey) +} + +// HasAtVersion implements VersionStore interface +func (s *Store) HasAtVersion(storeKey string, key []byte, version *int64) (bool, error) { + rawKey := prependStoreKey(storeKey, key) + if version == nil { + return s.plainDB.Has(rawKey) + } + + height := *version + + // optimize for latest version + latest, err := s.GetLatestVersion() + if err != nil { + return false, err + } + if height > latest { + return false, fmt.Errorf("height %d is in the future", height) + } + if latest == height { + return s.plainDB.Has(rawKey) + } + + found, err := SeekHistoryIndex(s.historyDB, rawKey, uint64(height)) + if err != nil { + return false, err + } + if found < 0 { + // there's no change records after the target version, query the latest state. + return s.plainDB.Has(rawKey) + } + // get from changeset + changesetKey := ChangesetKey(uint64(found), rawKey) + return s.changesetDB.Has(changesetKey) +} + +// IteratorAtVersion implements VersionStore interface +func (s *Store) IteratorAtVersion(storeKey string, start, end []byte, version *int64) (types.Iterator, error) { + storePrefix := StoreKeyPrefix(storeKey) + prefixPlain := prefix.NewStore(dbadapter.Store{DB: s.plainDB}, storePrefix) + if version == nil { + return prefixPlain.Iterator(start, end), nil + } + + // optimize for latest version + height := *version + latest, err := s.GetLatestVersion() + if err != nil { + return nil, err + } + if height > latest { + return nil, fmt.Errorf("height %d is in the future", height) + } + if latest == height { + return prefixPlain.Iterator(start, end), nil + } + + prefixHistory := prefix.NewStore(dbadapter.Store{DB: s.historyDB}, storePrefix) + return NewIterator(storeKey, height, prefixPlain, prefixHistory, s.changesetDB, start, end, false) +} + +// ReverseIteratorAtVersion implements VersionStore interface +func (s *Store) ReverseIteratorAtVersion(storeKey string, start, end []byte, version *int64) (types.Iterator, error) { + storePrefix := StoreKeyPrefix(storeKey) + prefixPlain := prefix.NewStore(dbadapter.Store{DB: s.plainDB}, storePrefix) + if version == nil { + return prefixPlain.ReverseIterator(start, end), nil + } + + // optimize for latest version + height := *version + latest, err := s.GetLatestVersion() + if err != nil { + return nil, err + } + if height > latest { + return nil, fmt.Errorf("height %d is in the future", height) + } + if latest == height { + return prefixPlain.ReverseIterator(start, end), nil + } + + prefixHistory := prefix.NewStore(dbadapter.Store{DB: s.historyDB}, storePrefix) + return NewIterator(storeKey, height, prefixPlain, prefixHistory, s.changesetDB, start, end, true) +} + +// GetLatestVersion returns the latest version stored in plain state, +// it's committed after the changesets, so the data for this version is guaranteed to be persisted. +// returns -1 if the key don't exists. +func (s *Store) GetLatestVersion() (int64, error) { + bz, err := s.plainDB.Get([]byte(latestVersionKey)) + if err != nil { + return -1, err + } else if bz == nil { + return -1, nil + } + + var latestVersion int64 + + if err := gogotypes.StdInt64Unmarshal(&latestVersion, bz); err != nil { + return -1, err + } + + return latestVersion, nil +} + +func (s *Store) setLatestVersion(plainBatch dbm.Batch, version int64) error { + // write latest version to plain state + bz, err := gogotypes.StdInt64Marshal(version) + if err != nil { + return err + } + return plainBatch.Set([]byte(latestVersionKey), bz) +} + +// ChangesetKey build key changeset db +func ChangesetKey(version uint64, key []byte) []byte { + return append(sdk.Uint64ToBigEndian(version), key...) +} + +func StoreKeyPrefix(storeKey string) []byte { + return []byte("s/k:" + storeKey + "/") +} + +// prependStoreKey prepends storeKey to the key +func prependStoreKey(storeKey string, key []byte) []byte { + return append(StoreKeyPrefix(storeKey), key...) +} diff --git a/versiondb/tmdb/store_test.go b/versiondb/tmdb/store_test.go new file mode 100644 index 0000000000..24453198ff --- /dev/null +++ b/versiondb/tmdb/store_test.go @@ -0,0 +1,14 @@ +package tmdb + +import ( + "testing" + + "github.com/crypto-org-chain/cronos/versiondb" + dbm "github.com/tendermint/tm-db" +) + +func TestTMDB(t *testing.T) { + versiondb.Run(t, func() versiondb.VersionStore { + return NewStore(dbm.NewMemDB(), dbm.NewMemDB(), dbm.NewMemDB()) + }) +} diff --git a/versiondb/types.go b/versiondb/types.go new file mode 100644 index 0000000000..fab4a6a21d --- /dev/null +++ b/versiondb/types.go @@ -0,0 +1,21 @@ +package versiondb + +import ( + "github.com/cosmos/cosmos-sdk/store/types" +) + +// VersionStore is a versioned storage of a flat key-value pairs. +// it don't need to support merkle proof, so could be implemented in a much more efficient way. +// `nil` version means the latest version. +type VersionStore interface { + GetAtVersion(storeKey string, key []byte, version *int64) ([]byte, error) + HasAtVersion(storeKey string, key []byte, version *int64) (bool, error) + IteratorAtVersion(storeKey string, start, end []byte, version *int64) (types.Iterator, error) + ReverseIteratorAtVersion(storeKey string, start, end []byte, version *int64) (types.Iterator, error) + GetLatestVersion() (int64, error) + + // Persist the change set of a block, + // the `changeSet` should be ordered by (storeKey, key), + // the version should be latest version plus one. + PutAtVersion(version int64, changeSet []types.StoreKVPair) error +} diff --git a/versiondb/utils.go b/versiondb/utils.go new file mode 100644 index 0000000000..c6200caf94 --- /dev/null +++ b/versiondb/utils.go @@ -0,0 +1,19 @@ +package versiondb + +import "github.com/RoaringBitmap/roaring/roaring64" + +// SeekInBitmap64 - returns value in bitmap which is >= n +func SeekInBitmap64(m *roaring64.Bitmap, n uint64) (found uint64, ok bool) { + if m == nil || m.IsEmpty() { + return 0, false + } + if n == 0 { + return m.Minimum(), true + } + searchRank := m.Rank(n - 1) + if searchRank >= m.GetCardinality() { + return 0, false + } + found, _ = m.Select(searchRank) + return found, true +}