refactor(orm)!: support core store API (#14796)

This commit is contained in:
Aaron Craelius 2023-01-27 02:50:16 -05:00 committed by GitHub
parent be9bd7a8c1
commit de466b9f8b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 79 additions and 53 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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