Skip to content

Commit

Permalink
Problem: no object kvStore service for runtime
Browse files Browse the repository at this point in the history
  • Loading branch information
mmsqe committed Jan 15, 2025
1 parent d9bb1b6 commit 68790ee
Show file tree
Hide file tree
Showing 20 changed files with 190 additions and 53 deletions.
5 changes: 5 additions & 0 deletions core/store/service.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,11 @@ type KVStoreService interface {
OpenKVStore(context.Context) KVStore
}

type ObjKVStoreService interface {
// OpenObjKVStore retrieves the ObjKVStore from the context.
OpenObjKVStore(context.Context) ObjKVStore
}

// MemoryStoreService represents a unique, non-forgeable handle to a memory-backed
// KVStore. It should be provided as a module-scoped dependency by the runtime
// module being used to build the app.
Expand Down
58 changes: 58 additions & 0 deletions core/store/store.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,3 +34,61 @@ type KVStore interface {

// Iterator is an alias db's Iterator for convenience.
type Iterator = dbm.Iterator

type ObjKVStore interface {
// Get returns nil if key doesn't exist. Errors on nil key.
Get(key []byte) (any, error)

// Has checks if a key exists. Errors on nil key.
Has(key []byte) (bool, error)

// Set sets the key. Errors on nil key or value.
Set(key []byte, value any) error

// Delete deletes the key. Errors on nil key.
Delete(key []byte) error

// Iterator over a domain of keys in ascending order. End is exclusive.
// Start must be less than end, or the Iterator is invalid.
// Iterator must be closed by caller.
// To iterate over entire domain, use store.Iterator(nil, nil)
// CONTRACT: No writes may happen within a domain while an iterator exists over it.
// Exceptionally allowed for cachekv.Store, safe to write in the modules.
Iterator(start, end []byte) (GIterator[any], error)

// Iterator over a domain of keys in descending order. End is exclusive.
// Start must be less than end, or the Iterator is invalid.
// Iterator must be closed by caller.
// CONTRACT: No writes may happen within a domain while an iterator exists over it.
// Exceptionally allowed for cachekv.Store, safe to write in the modules.
ReverseIterator(start, end []byte) (GIterator[any], error)
}

// GIterator is the generic version of dbm's Iterator
type GIterator[V any] interface {
// Domain returns the start (inclusive) and end (exclusive) limits of the iterator.
// CONTRACT: start, end readonly []byte
Domain() (start, end []byte)

// Valid returns whether the current iterator is valid. Once invalid, the Iterator remains
// invalid forever.
Valid() bool

// Next moves the iterator to the next key in the database, as defined by order of iteration.
// If Valid returns false, this method will panic.
Next()

// Key returns the key at the current position. Panics if the iterator is invalid.
// CONTRACT: key readonly []byte
Key() (key []byte)

// Value returns the value at the current position. Panics if the iterator is invalid.
// CONTRACT: value readonly []byte
Value() (value V)

// Error returns the last error encountered by the iterator, if any.
Error() error

// Close closes the iterator, relasing any allocated resources.
Close() error
}
17 changes: 11 additions & 6 deletions runtime/module.go
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ func init() {
ProvideKVStoreService,
ProvideMemoryStoreService,
ProvideTransientStoreService,
ProvideObjKVStoreService,
ProvideEventService,
ProvideHeaderInfoService,
ProvideCometInfoService,
Expand Down Expand Up @@ -214,20 +215,20 @@ func ProvideKVStoreKey(config *runtimev1alpha1.Module, key depinject.ModuleKey,
return storeKey
}

func ProvideTransientStoreKey(key depinject.ModuleKey, app *AppBuilder) *storetypes.TransientStoreKey {
storeKey := storetypes.NewTransientStoreKey(fmt.Sprintf("transient:%s", key.Name()))
func ProvideObjectStoreKey(key depinject.ModuleKey, app *AppBuilder) *storetypes.ObjectStoreKey {
storeKey := storetypes.NewObjectStoreKey(fmt.Sprintf("object:%s", key.Name()))
registerStoreKey(app, storeKey)
return storeKey
}

func ProvideMemoryStoreKey(key depinject.ModuleKey, app *AppBuilder) *storetypes.MemoryStoreKey {
storeKey := storetypes.NewMemoryStoreKey(fmt.Sprintf("memory:%s", key.Name()))
func ProvideTransientStoreKey(key depinject.ModuleKey, app *AppBuilder) *storetypes.TransientStoreKey {
storeKey := storetypes.NewTransientStoreKey(fmt.Sprintf("transient:%s", key.Name()))
registerStoreKey(app, storeKey)
return storeKey
}

func ProvideObjectStoreKey(key depinject.ModuleKey, app *AppBuilder) *storetypes.ObjectStoreKey {
storeKey := storetypes.NewObjectStoreKey(fmt.Sprintf("object:%s", key.Name()))
func ProvideMemoryStoreKey(key depinject.ModuleKey, app *AppBuilder) *storetypes.MemoryStoreKey {
storeKey := storetypes.NewMemoryStoreKey(fmt.Sprintf("memory:%s", key.Name()))
registerStoreKey(app, storeKey)
return storeKey
}
Expand All @@ -251,6 +252,10 @@ func ProvideTransientStoreService(key depinject.ModuleKey, app *AppBuilder) stor
return transientStoreService{key: storeKey}
}

func ProvideObjKVStoreService(config *runtimev1alpha1.Module, key depinject.ModuleKey, app *AppBuilder) store.ObjKVStoreService {
storeKey := ProvideObjectStoreKey(key, app)
return objectStoreService{key: storeKey}
}
func ProvideEventService() event.Service {
return EventService{}
}
Expand Down
63 changes: 63 additions & 0 deletions runtime/store.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,18 @@ func (t transientStoreService) OpenTransientStore(ctx context.Context) store.KVS
return newKVStore(sdk.UnwrapSDKContext(ctx).KVStore(t.key))
}

func NewObjKVStoreService(key *storetypes.ObjectStoreKey) store.ObjKVStoreService {
return &objectStoreService{key}
}

type objectStoreService struct {
key *storetypes.ObjectStoreKey
}

func (k objectStoreService) OpenObjKVStore(ctx context.Context) store.ObjKVStore {
return newObjectStore(sdk.UnwrapSDKContext(ctx).ObjectStore(k.key))
}

// CoreKVStore is a wrapper of Core/Store kvstore interface
// Remove after https://github.com/cosmos/cosmos-sdk/issues/14714 is closed
type coreKVStore struct {
Expand Down Expand Up @@ -98,6 +110,57 @@ func (store coreKVStore) ReverseIterator(start, end []byte) (store.Iterator, err
return store.kvStore.ReverseIterator(start, end), nil
}

type coreObjKVStore struct {
objKVStore storetypes.ObjKVStore
}

// NewObjectStore returns a wrapper of Core/Store objKVstore interface
// Remove once store migrates to core/store objKVstore interface
func newObjectStore(objKVStore storetypes.ObjKVStore) store.ObjKVStore {
return coreObjKVStore{objKVStore}
}

// Get returns nil iff key doesn't exist. Errors on nil key.
func (store coreObjKVStore) Get(key []byte) (any, error) {
return store.objKVStore.Get(key), nil
}

// Has checks if a key exists. Errors on nil key.
func (store coreObjKVStore) Has(key []byte) (bool, error) {
return store.objKVStore.Has(key), nil
}

// Set sets the key. Errors on nil key or value.
func (store coreObjKVStore) Set(key []byte, value any) error {
store.objKVStore.Set(key, value)
return nil
}

// Delete deletes the key. Errors on nil key.
func (store coreObjKVStore) Delete(key []byte) error {
store.objKVStore.Delete(key)
return nil
}

// Iterator iterates over a domain of keys in ascending order. End is exclusive.
// Start must be less than end, or the Iterator is invalid.
// Iterator must be closed by caller.
// To iterate over entire domain, use store.Iterator(nil, nil)
// CONTRACT: No writes may happen within a domain while an iterator exists over it.
// Exceptionally allowed for cachekv.Store, safe to write in the modules.
func (store coreObjKVStore) Iterator(start, end []byte) (store.GIterator[any], error) {
return store.objKVStore.Iterator(start, end), nil
}

// ReverseIterator iterates over a domain of keys in descending order. End is exclusive.
// Start must be less than end, or the Iterator is invalid.
// Iterator must be closed by caller.
// CONTRACT: No writes may happen within a domain while an iterator exists over it.
// Exceptionally allowed for cachekv.Store, safe to write in the modules.
func (store coreObjKVStore) ReverseIterator(start, end []byte) (store.GIterator[any], error) {
return store.objKVStore.ReverseIterator(start, end), nil
}

// Adapter
var _ storetypes.KVStore = kvStoreAdapter{}

Expand Down
2 changes: 1 addition & 1 deletion simapp/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -294,7 +294,7 @@ func NewSimApp(
app.BankKeeper = bankkeeper.NewBaseKeeper(
appCodec,
runtime.NewKVStoreService(keys[banktypes.StoreKey]),
okeys[banktypes.ObjectStoreKey],
runtime.NewObjKVStoreService(okeys[banktypes.ObjectStoreKey]),
app.AccountKeeper,
BlockedAddresses(),
authtypes.NewModuleAddress(govtypes.ModuleName).String(),
Expand Down
3 changes: 2 additions & 1 deletion tests/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -205,14 +205,15 @@ require (

// Below are the long-lived replace for tests.
replace (
cosmossdk.io/core => ../core
// We always want to test against the latest version of the simapp.
cosmossdk.io/simapp => ../simapp
cosmossdk.io/store => ../store
cosmossdk.io/x/tx => ../x/tx
github.com/99designs/keyring => github.com/cosmos/keyring v1.2.0
// We always want to test against the latest version of the SDK.
github.com/cosmos/cosmos-sdk => ../.
// Fix upstream GHSA-h395-qcrw-5vmq and GHSA-3vp4-m3rf-835h vulnerabilities.
// TODO Remove it: https://github.com/cosmos/cosmos-sdk/issues/10409
github.com/gin-gonic/gin => github.com/gin-gonic/gin v1.9.1
cosmossdk.io/x/tx => ../x/tx
)
4 changes: 0 additions & 4 deletions tests/go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -188,8 +188,6 @@ cosmossdk.io/client/v2 v2.0.0-beta.5 h1:0LVv3nEByn//hFDIrYLs2WvsEU3HodOelh4SDHnA
cosmossdk.io/client/v2 v2.0.0-beta.5/go.mod h1:4p0P6o0ro+FizakJUYS9SeM94RNbv0thLmkHRw5o5as=
cosmossdk.io/collections v0.4.0 h1:PFmwj2W8szgpD5nOd8GWH6AbYNi1f2J6akWXJ7P5t9s=
cosmossdk.io/collections v0.4.0/go.mod h1:oa5lUING2dP+gdDquow+QjlF45eL1t4TJDypgGd+tv0=
cosmossdk.io/core v0.11.1 h1:h9WfBey7NAiFfIcUhDVNS503I2P2HdZLebJlUIs8LPA=
cosmossdk.io/core v0.11.1/go.mod h1:OJzxcdC+RPrgGF8NJZR2uoQr56tc7gfBKhiKeDO7hH0=
cosmossdk.io/depinject v1.0.0 h1:dQaTu6+O6askNXO06+jyeUAnF2/ssKwrrszP9t5q050=
cosmossdk.io/depinject v1.0.0/go.mod h1:zxK/h3HgHoA/eJVtiSsoaRaRA2D5U4cJ5thIG4ssbB8=
cosmossdk.io/errors v1.0.1 h1:bzu+Kcr0kS/1DuPBtUFdWjzLqyUuCiyHjyJB6srBV/0=
Expand All @@ -206,8 +204,6 @@ cosmossdk.io/x/feegrant v0.1.1 h1:EKFWOeo/pup0yF0svDisWWKAA9Zags6Zd0P3nRvVvw8=
cosmossdk.io/x/feegrant v0.1.1/go.mod h1:2GjVVxX6G2fta8LWj7pC/ytHjryA6MHAJroBWHFNiEQ=
cosmossdk.io/x/nft v0.1.1 h1:pslAVS8P5NkW080+LWOamInjDcq+v2GSCo+BjN9sxZ8=
cosmossdk.io/x/nft v0.1.1/go.mod h1:Kac6F6y2gsKvoxU+fy8uvxRTi4BIhLOor2zgCNQwVgY=
cosmossdk.io/x/tx v0.13.6-0.20241003112805-ff8789a02871 h1:+lRwWQRVvB3jgRgdqrgeFUJ45BoXZh/UeeAV5f/m2Gk=
cosmossdk.io/x/tx v0.13.6-0.20241003112805-ff8789a02871/go.mod h1:V6DImnwJMTq5qFjeGWpXNiT/fjgE4HtmclRmTqRVM3w=
cosmossdk.io/x/upgrade v0.1.4 h1:/BWJim24QHoXde8Bc64/2BSEB6W4eTydq0X/2f8+g38=
cosmossdk.io/x/upgrade v0.1.4/go.mod h1:9v0Aj+fs97O+Ztw+tG3/tp5JSlrmT7IcFhAebQHmOPo=
dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
Expand Down
2 changes: 1 addition & 1 deletion tests/integration/bank/keeper/deterministic_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ func initDeterministicFixture(t *testing.T) *deterministicFixture {
bankKeeper := keeper.NewBaseKeeper(
cdc,
runtime.NewKVStoreService(keys[banktypes.StoreKey]),
okeys[banktypes.ObjectStoreKey],
runtime.NewObjKVStoreService(okeys[banktypes.ObjectStoreKey]),
accountKeeper,
blockedAddresses,
authority.String(),
Expand Down
2 changes: 1 addition & 1 deletion tests/integration/distribution/keeper/msg_server_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ func initFixture(t testing.TB) *fixture {
bankKeeper := bankkeeper.NewBaseKeeper(
cdc,
runtime.NewKVStoreService(keys[banktypes.StoreKey]),
okeys[banktypes.ObjectStoreKey],
runtime.NewObjKVStoreService(okeys[banktypes.ObjectStoreKey]),
accountKeeper,
blockedAddresses,
authority.String(),
Expand Down
2 changes: 1 addition & 1 deletion tests/integration/evidence/keeper/infraction_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ func initFixture(t testing.TB) *fixture {
bankKeeper := bankkeeper.NewBaseKeeper(
cdc,
runtime.NewKVStoreService(keys[banktypes.StoreKey]),
okeys[banktypes.ObjectStoreKey],
runtime.NewObjKVStoreService(okeys[banktypes.ObjectStoreKey]),
accountKeeper,
blockedAddresses,
authority.String(),
Expand Down
2 changes: 1 addition & 1 deletion tests/integration/gov/keeper/keeper_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ func initFixture(t testing.TB) *fixture {
bankKeeper := bankkeeper.NewBaseKeeper(
cdc,
runtime.NewKVStoreService(keys[banktypes.StoreKey]),
okeys[banktypes.ObjectStoreKey],
runtime.NewObjKVStoreService(okeys[banktypes.ObjectStoreKey]),
accountKeeper,
blockedAddresses,
authority.String(),
Expand Down
2 changes: 1 addition & 1 deletion tests/integration/slashing/keeper/keeper_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ func initFixture(t testing.TB) *fixture {
bankKeeper := bankkeeper.NewBaseKeeper(
cdc,
runtime.NewKVStoreService(keys[banktypes.StoreKey]),
okeys[banktypes.ObjectStoreKey],
runtime.NewObjKVStoreService(okeys[banktypes.ObjectStoreKey]),
accountKeeper,
blockedAddresses,
authority.String(),
Expand Down
2 changes: 1 addition & 1 deletion tests/integration/staking/keeper/common_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@ func initFixture(t testing.TB) *fixture {
bankKeeper := bankkeeper.NewBaseKeeper(
cdc,
runtime.NewKVStoreService(keys[banktypes.StoreKey]),
okeys[banktypes.ObjectStoreKey],
runtime.NewObjKVStoreService(okeys[banktypes.ObjectStoreKey]),
accountKeeper,
blockedAddresses,
authority.String(),
Expand Down
2 changes: 1 addition & 1 deletion tests/integration/staking/keeper/determinstic_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ func initDeterministicFixture(t *testing.T) *deterministicFixture {
bankKeeper := bankkeeper.NewBaseKeeper(
cdc,
runtime.NewKVStoreService(keys[banktypes.StoreKey]),
okeys[banktypes.ObjectStoreKey],
runtime.NewObjKVStoreService(okeys[banktypes.ObjectStoreKey]),
accountKeeper,
blockedAddresses,
authority.String(),
Expand Down
3 changes: 2 additions & 1 deletion x/bank/keeper/collections_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ func TestBankStateCompatibility(t *testing.T) {
encCfg := moduletestutil.MakeTestEncodingConfig()

storeService := runtime.NewKVStoreService(key)
objStoreService := runtime.NewObjKVStoreService(okey)

// gomock initializations
ctrl := gomock.NewController(t)
Expand All @@ -41,7 +42,7 @@ func TestBankStateCompatibility(t *testing.T) {
k := keeper.NewBaseKeeper(
encCfg.Codec,
storeService,
okey,
objStoreService,
authKeeper,
map[string]bool{accAddrs[4].String(): true},
authtypes.NewModuleAddress("gov").String(),
Expand Down
5 changes: 2 additions & 3 deletions x/bank/keeper/keeper.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ import (
errorsmod "cosmossdk.io/errors"
"cosmossdk.io/log"
"cosmossdk.io/math"
storetypes "cosmossdk.io/store/types"

"github.com/cosmos/cosmos-sdk/codec"
sdk "github.com/cosmos/cosmos-sdk/types"
Expand Down Expand Up @@ -90,7 +89,7 @@ func (k BaseKeeper) GetPaginatedTotalSupply(ctx context.Context, pagination *que
func NewBaseKeeper(
cdc codec.BinaryCodec,
storeService store.KVStoreService,
objStoreKey storetypes.StoreKey,
objStoreService store.ObjKVStoreService,
ak types.AccountKeeper,
blockedAddrs map[string]bool,
authority string,
Expand All @@ -104,7 +103,7 @@ func NewBaseKeeper(
logger = logger.With(log.ModuleKey, "x/"+types.ModuleName)

return BaseKeeper{
BaseSendKeeper: NewBaseSendKeeper(cdc, storeService, objStoreKey, ak, blockedAddrs, authority, logger),
BaseSendKeeper: NewBaseSendKeeper(cdc, storeService, objStoreService, ak, blockedAddrs, authority, logger),
ak: ak,
cdc: cdc,
storeService: storeService,
Expand Down
6 changes: 4 additions & 2 deletions x/bank/keeper/keeper_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,7 @@ func (suite *KeeperTestSuite) SetupTest() {
encCfg := moduletestutil.MakeTestEncodingConfig()

storeService := runtime.NewKVStoreService(key)
objStoreService := runtime.NewObjKVStoreService(okey)

// gomock initializations
ctrl := gomock.NewController(suite.T())
Expand All @@ -146,7 +147,7 @@ func (suite *KeeperTestSuite) SetupTest() {
suite.bankKeeper = keeper.NewBaseKeeper(
encCfg.Codec,
storeService,
okey,
objStoreService,
suite.authKeeper,
map[string]bool{accAddrs[4].String(): true},
authtypes.NewModuleAddress(govtypes.ModuleName).String(),
Expand Down Expand Up @@ -324,11 +325,12 @@ func (suite *KeeperTestSuite) TestPrependSendRestriction() {

func (suite *KeeperTestSuite) TestGetAuthority() {
storeService := runtime.NewKVStoreService(storetypes.NewKVStoreKey(banktypes.StoreKey))
objStoreService := runtime.NewObjKVStoreService(storetypes.NewObjectStoreKey(banktypes.ObjectStoreKey))
NewKeeperWithAuthority := func(authority string) keeper.BaseKeeper {
return keeper.NewBaseKeeper(
moduletestutil.MakeTestEncodingConfig().Codec,
storeService,
nil,
objStoreService,
suite.authKeeper,
nil,
authority,
Expand Down
Loading

0 comments on commit 68790ee

Please sign in to comment.