diff --git a/orm/go.mod b/orm/go.mod index 1ab217ce7b..ccba0f44ae 100644 --- a/orm/go.mod +++ b/orm/go.mod @@ -4,8 +4,10 @@ go 1.19 require ( cosmossdk.io/api v0.2.6 + cosmossdk.io/core v0.5.1 + cosmossdk.io/depinject v1.0.0-alpha.3 cosmossdk.io/errors v1.0.0-beta.7 - github.com/cosmos/cosmos-db v0.0.0-20221224071843-97e1443c3226 + github.com/cosmos/cosmos-db v0.0.0-20221226095112-f3c38ecb5e32 github.com/cosmos/cosmos-proto v1.0.0-beta.1 github.com/golang/mock v1.6.0 github.com/google/go-cmp v0.5.9 @@ -56,6 +58,5 @@ require ( golang.org/x/sys v0.4.0 // indirect golang.org/x/text v0.6.0 // indirect google.golang.org/genproto v0.0.0-20230125152338-dcaf20b6aeaa // indirect - gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/orm/go.sum b/orm/go.sum index 2168e183a1..ef5c874081 100644 --- a/orm/go.sum +++ b/orm/go.sum @@ -1,6 +1,10 @@ cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cosmossdk.io/api v0.2.6 h1:AoNwaLLapcLsphhMK6+o0kZl+D6MMUaHVqSdwinASGU= cosmossdk.io/api v0.2.6/go.mod h1:u/d+GAxil0nWpl1XnQL8nkziQDIWuBDhv8VnDm/s6dI= +cosmossdk.io/core v0.5.1 h1:vQVtFrIYOQJDV3f7rw4pjjVqc1id4+mE0L9hHP66pyI= +cosmossdk.io/core v0.5.1/go.mod h1:KZtwHCLjcFuo0nmDc24Xy6CRNEL9Vl/MeimQ2aC7NLE= +cosmossdk.io/depinject v1.0.0-alpha.3 h1:6evFIgj//Y3w09bqOUOzEpFj5tsxBqdc5CfkO7z+zfw= +cosmossdk.io/depinject v1.0.0-alpha.3/go.mod h1:eRbcdQ7MRpIPEM5YUJh8k97nxHpYbc3sMUnEtt8HPWU= cosmossdk.io/errors v1.0.0-beta.7 h1:gypHW76pTQGVnHKo6QBkb4yFOJjC+sUGRc5Al3Odj1w= cosmossdk.io/errors v1.0.0-beta.7/go.mod h1:mz6FQMJRku4bY7aqS/Gwfcmr/ue91roMEKAmDUDpBfE= dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= @@ -55,8 +59,8 @@ github.com/codegangsta/inject v0.0.0-20150114235600-33e0aa1cb7c0/go.mod h1:4Zcju github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk= github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= -github.com/cosmos/cosmos-db v0.0.0-20221224071843-97e1443c3226 h1:mb2FmhiCYEL5sz4DOpz4RoUgghwmtyr7V+TBVrGPUFY= -github.com/cosmos/cosmos-db v0.0.0-20221224071843-97e1443c3226/go.mod h1:kwMlEC4wWvB48zAShGKVqboJL6w4zCLesaNQ3YLU2BQ= +github.com/cosmos/cosmos-db v0.0.0-20221226095112-f3c38ecb5e32 h1:zlCp9n3uwQieELltZWHRmwPmPaZ8+XoL2Sj+A2YJlr8= +github.com/cosmos/cosmos-db v0.0.0-20221226095112-f3c38ecb5e32/go.mod h1:kwMlEC4wWvB48zAShGKVqboJL6w4zCLesaNQ3YLU2BQ= github.com/cosmos/cosmos-proto v1.0.0-beta.1 h1:iDL5qh++NoXxG8hSy93FdYJut4XfgbShIocllGaXx/0= github.com/cosmos/cosmos-proto v1.0.0-beta.1/go.mod h1:8k2GNZghi5sDRFw/scPL8gMSowT1vDA+5ouxL8GjaUE= github.com/cosmos/gogoproto v1.4.3 h1:RP3yyVREh9snv/lsOvmsAPQt8f44LgL281X0IOIhhcI= @@ -202,7 +206,6 @@ github.com/klauspost/compress v1.15.12 h1:YClS/PImqYbn+UILDnqxQCZ3RehC9N318SU3kE github.com/klauspost/compress v1.15.12/go.mod h1:QPwzmACJjUTFsnSHH934V6woptycfrDDJnH7hvFVbGM= github.com/klauspost/cpuid v1.2.1/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= -github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= @@ -501,7 +504,6 @@ gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8 gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= -gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= gopkg.in/go-playground/assert.v1 v1.2.1/go.mod h1:9RXL0bg/zibRAgZUYszZSwO/z8Y/a8bDuhia5mkpMnE= diff --git a/orm/internal/testutil/testutil.go b/orm/internal/testutil/testutil.go index 13556fdd0d..6ea248e83b 100644 --- a/orm/internal/testutil/testutil.go +++ b/orm/internal/testutil/testutil.go @@ -101,7 +101,7 @@ var TestFieldSpecs = []TestFieldSpec{ }, { "e", - rapid.Transform(rapid.Int32(), func(x int32) protoreflect.EnumNumber { + rapid.Map(rapid.Int32(), func(x int32) protoreflect.EnumNumber { return protoreflect.EnumNumber(x) }).AsAny(), }, diff --git a/orm/model/ormdb/module.go b/orm/model/ormdb/module.go index 71d3ef4765..5879f1b55c 100644 --- a/orm/model/ormdb/module.go +++ b/orm/model/ormdb/module.go @@ -4,8 +4,10 @@ import ( "bytes" "context" "encoding/binary" + "fmt" "math" + "cosmossdk.io/core/store" "google.golang.org/protobuf/reflect/protoregistry" ormv1alpha1 "cosmossdk.io/api/cosmos/orm/v1alpha1" @@ -66,9 +68,14 @@ type ModuleDBOptions struct { // will be used JSONValidator func(proto.Message) error - // GetBackendResolver returns a backend resolver for the requested storage - // type or an error if this type of storage isn't supported. - GetBackendResolver func(ormv1alpha1.StorageType) (ormtable.BackendResolver, error) + // KVStoreService is the storage service to use for the DB if default KV-store storage is used. + KVStoreService store.KVStoreService + + // KVStoreService is the storage service to use for the DB if memory storage is used. + MemoryStoreService store.MemoryStoreService + + // KVStoreService is the storage service to use for the DB if transient storage is used. + TransientStoreService store.TransientStoreService } // NewModuleDB constructs a ModuleDB instance from the provided schema and options. @@ -87,12 +94,49 @@ func NewModuleDB(schema *ormv1alpha1.ModuleSchemaDescriptor, options ModuleDBOpt for _, entry := range schema.SchemaFile { var backendResolver ormtable.BackendResolver - var err error - if options.GetBackendResolver != nil { - backendResolver, err = options.GetBackendResolver(entry.StorageType) - if err != nil { - return nil, err + + switch entry.StorageType { + case ormv1alpha1.StorageType_STORAGE_TYPE_DEFAULT_UNSPECIFIED: + service := options.KVStoreService + if service == nil { + return nil, fmt.Errorf("missing KVStoreService") } + + backendResolver = func(ctx context.Context) (ormtable.ReadBackend, error) { + kvStore := service.OpenKVStore(ctx) + return ormtable.NewBackend(ormtable.BackendOptions{ + CommitmentStore: kvStore, + IndexStore: kvStore, + }), nil + } + case ormv1alpha1.StorageType_STORAGE_TYPE_MEMORY: + service := options.MemoryStoreService + if service == nil { + return nil, fmt.Errorf("missing MemoryStoreService") + } + + backendResolver = func(ctx context.Context) (ormtable.ReadBackend, error) { + kvStore := service.OpenMemoryStore(ctx) + return ormtable.NewBackend(ormtable.BackendOptions{ + CommitmentStore: kvStore, + IndexStore: kvStore, + }), nil + } + case ormv1alpha1.StorageType_STORAGE_TYPE_TRANSIENT: + service := options.TransientStoreService + if service == nil { + return nil, fmt.Errorf("missing TransientStoreService") + } + + backendResolver = func(ctx context.Context) (ormtable.ReadBackend, error) { + kvStore := service.OpenTransientStore(ctx) + return ormtable.NewBackend(ormtable.BackendOptions{ + CommitmentStore: kvStore, + IndexStore: kvStore, + }), nil + } + default: + return nil, fmt.Errorf("unsupported storage type %s", entry.StorageType) } id := entry.Id diff --git a/orm/model/ormdb/module_test.go b/orm/model/ormdb/module_test.go index 0bd160995d..c558de88aa 100644 --- a/orm/model/ormdb/module_test.go +++ b/orm/model/ormdb/module_test.go @@ -9,6 +9,8 @@ import ( "testing" ormv1alpha1 "cosmossdk.io/api/cosmos/orm/v1alpha1" + "cosmossdk.io/core/store" + dbm "github.com/cosmos/cosmos-db" "github.com/golang/mock/gomock" @@ -43,8 +45,8 @@ type keeper struct { } func NewKeeper(db ormdb.ModuleDB) (Keeper, error) { - store, err := testpb.NewBankStore(db) - return keeper{store}, err + bankStore, err := testpb.NewBankStore(db) + return keeper{bankStore}, err } type Keeper interface { @@ -338,22 +340,17 @@ func TestHooks(t *testing.T) { assert.NilError(t, k.Burn(ctx, acct1, denom, 5)) } +type testStoreService struct { + db dbm.DB +} + +func (t testStoreService) OpenMemoryStore(context.Context) store.KVStore { + return t.db +} + func TestGetBackendResolver(t *testing.T) { - backend := ormtest.NewMemoryBackend() - getResolver := func(storageType ormv1alpha1.StorageType) (ormtable.BackendResolver, error) { - switch storageType { - case ormv1alpha1.StorageType_STORAGE_TYPE_MEMORY: - return func(ctx context.Context) (ormtable.ReadBackend, error) { - return backend, nil - }, nil - default: - return nil, fmt.Errorf("storage type %s unsupported", storageType) - } - } - _, err := ormdb.NewModuleDB(TestBankSchema, ormdb.ModuleDBOptions{ - GetBackendResolver: getResolver, - }) - assert.ErrorContains(t, err, "unsupported") + _, err := ormdb.NewModuleDB(TestBankSchema, ormdb.ModuleDBOptions{}) + assert.ErrorContains(t, err, "missing KVStoreService") _, err = ormdb.NewModuleDB(&ormv1alpha1.ModuleSchemaDescriptor{ SchemaFile: []*ormv1alpha1.ModuleSchemaDescriptor_FileEntry{ @@ -364,7 +361,7 @@ func TestGetBackendResolver(t *testing.T) { }, }, }, ormdb.ModuleDBOptions{ - GetBackendResolver: getResolver, + MemoryStoreService: testStoreService{db: dbm.NewMemDB()}, }) assert.NilError(t, err) } diff --git a/proto/cosmos/orm/v1alpha1/schema.proto b/proto/cosmos/orm/v1alpha1/schema.proto index ab713340e3..cbe90de3d3 100644 --- a/proto/cosmos/orm/v1alpha1/schema.proto +++ b/proto/cosmos/orm/v1alpha1/schema.proto @@ -40,11 +40,8 @@ message ModuleSchemaDescriptor { // StorageType enum StorageType { - // STORAGE_TYPE_DEFAULT_UNSPECIFIED indicates the persistent - // KV-storage where primary key entries are stored in merkle-tree - // backed commitment storage and indexes and seqs are stored in - // fast index storage. Note that the Cosmos SDK before store/v2alpha1 - // does not support this. + // STORAGE_TYPE_DEFAULT_UNSPECIFIED indicates the persistent storage where all + // data is stored in the regular Merkle-tree backed KV-store. STORAGE_TYPE_DEFAULT_UNSPECIFIED = 0; // STORAGE_TYPE_MEMORY indicates in-memory storage that will be @@ -58,19 +55,4 @@ enum StorageType { // will by default be ignored when importing and exporting a module's // state from JSON. STORAGE_TYPE_TRANSIENT = 2; - - // STORAGE_TYPE_INDEX indicates persistent storage which is not backed - // by a merkle-tree and won't affect the app hash. Note that the Cosmos SDK - // before store/v2alpha1 does not support this. - STORAGE_TYPE_INDEX = 3; - - // STORAGE_TYPE_INDEX indicates persistent storage which is backed by - // a merkle-tree. With this type of storage, both primary and index keys - // will affect the app hash and this is generally less efficient - // than using STORAGE_TYPE_DEFAULT_UNSPECIFIED which separates index - // keys into index storage. Note that modules built with the - // Cosmos SDK before store/v2alpha1 must specify STORAGE_TYPE_COMMITMENT - // instead of STORAGE_TYPE_DEFAULT_UNSPECIFIED or STORAGE_TYPE_INDEX - // because this is the only type of persistent storage available. - STORAGE_TYPE_COMMITMENT = 4; }