diff --git a/baseapp/abci_test.go b/baseapp/abci_test.go index 698b12212f5b..c225cab2db22 100644 --- a/baseapp/abci_test.go +++ b/baseapp/abci_test.go @@ -609,7 +609,8 @@ func TestABCI_CheckTx(t *testing.T) { require.Empty(t, r.GetEvents()) } - checkStateStore := getCheckStateCtx(suite.baseApp).KVStore(capKey1) + ctx := getCheckStateCtx(suite.baseApp) + checkStateStore := ctx.KVStore(capKey1) storedCounter := getIntFromStore(t, checkStateStore, counterKey) // ensure AnteHandler ran @@ -625,7 +626,8 @@ func TestABCI_CheckTx(t *testing.T) { suite.baseApp.EndBlock(abci.RequestEndBlock{}) suite.baseApp.Commit() - checkStateStore = getCheckStateCtx(suite.baseApp).KVStore(capKey1) + ctx = getCheckStateCtx(suite.baseApp) + checkStateStore = ctx.KVStore(capKey1) storedBytes := checkStateStore.Get(counterKey) require.Nil(t, storedBytes) } @@ -697,7 +699,8 @@ func TestABCI_DeliverTx_MultiMsg(t *testing.T) { res := suite.baseApp.DeliverTx(abci.RequestDeliverTx{Tx: txBytes}) require.True(t, res.IsOK(), fmt.Sprintf("%v", res)) - store := getDeliverStateCtx(suite.baseApp).KVStore(capKey1) + ctx := getDeliverStateCtx(suite.baseApp) + store := ctx.KVStore(capKey1) // tx counter only incremented once txCounter := getIntFromStore(t, store, anteKey) @@ -725,7 +728,8 @@ func TestABCI_DeliverTx_MultiMsg(t *testing.T) { res = suite.baseApp.DeliverTx(abci.RequestDeliverTx{Tx: txBytes}) require.True(t, res.IsOK(), fmt.Sprintf("%v", res)) - store = getDeliverStateCtx(suite.baseApp).KVStore(capKey1) + ctx = getDeliverStateCtx(suite.baseApp) + store = ctx.KVStore(capKey1) // tx counter only incremented once txCounter = getIntFromStore(t, store, anteKey) diff --git a/store/gaskv/store.go b/store/gaskv/store.go index 85bf598d0626..01aa16dafdfc 100644 --- a/store/gaskv/store.go +++ b/store/gaskv/store.go @@ -12,12 +12,12 @@ var _ types.KVStore = &Store{} // KVStore interface. type Store struct { gasMeter types.GasMeter - gasConfig types.GasConfig + gasConfig *types.GasConfig parent types.KVStore } // NewStore returns a reference to a new GasKVStore. -func NewStore(parent types.KVStore, gasMeter types.GasMeter, gasConfig types.GasConfig) *Store { +func NewStore(parent types.KVStore, gasMeter types.GasMeter, gasConfig *types.GasConfig) *Store { kvs := &Store{ gasMeter: gasMeter, gasConfig: gasConfig, @@ -108,11 +108,11 @@ func (gs *Store) iterator(start, end []byte, ascending bool) types.Iterator { type gasIterator struct { gasMeter types.GasMeter - gasConfig types.GasConfig + gasConfig *types.GasConfig parent types.Iterator } -func newGasIterator(gasMeter types.GasMeter, gasConfig types.GasConfig, parent types.Iterator) types.Iterator { +func newGasIterator(gasMeter types.GasMeter, gasConfig *types.GasConfig, parent types.Iterator) types.Iterator { return &gasIterator{ gasMeter: gasMeter, gasConfig: gasConfig, diff --git a/store/types/gas.go b/store/types/gas.go index 84ca542550b7..1dcf4483a434 100644 --- a/store/types/gas.go +++ b/store/types/gas.go @@ -228,8 +228,8 @@ type GasConfig struct { } // KVGasConfig returns a default gas config for KVStores. -func KVGasConfig() GasConfig { - return GasConfig{ +func KVGasConfig() *GasConfig { + return &GasConfig{ HasCost: 1000, DeleteCost: 1000, ReadCostFlat: 1000, @@ -241,8 +241,8 @@ func KVGasConfig() GasConfig { } // TransientGasConfig returns a default gas config for TransientStores. -func TransientGasConfig() GasConfig { - return GasConfig{ +func TransientGasConfig() *GasConfig { + return &GasConfig{ HasCost: 100, DeleteCost: 100, ReadCostFlat: 100, diff --git a/store/types/gas_test.go b/store/types/gas_test.go index f4b5a6abe5ba..11f943396dd1 100644 --- a/store/types/gas_test.go +++ b/store/types/gas_test.go @@ -111,7 +111,7 @@ func TestAddUint64Overflow(t *testing.T) { func TestTransientGasConfig(t *testing.T) { t.Parallel() config := TransientGasConfig() - require.Equal(t, config, GasConfig{ + require.Equal(t, config, &GasConfig{ HasCost: 100, DeleteCost: 100, ReadCostFlat: 100, diff --git a/types/context.go b/types/context.go index fac8ed981b0d..c9d6f6fb2991 100644 --- a/types/context.go +++ b/types/context.go @@ -39,8 +39,8 @@ type Context struct { consParams *tmproto.ConsensusParams eventManager *EventManager priority int64 // The tx priority, only relevant in CheckTx - kvGasConfig storetypes.GasConfig - transientKVGasConfig storetypes.GasConfig + kvGasConfig *storetypes.GasConfig + transientKVGasConfig *storetypes.GasConfig } // Proposed rename, not done to avoid API breakage @@ -62,8 +62,8 @@ func (c Context) IsReCheckTx() bool { return c.recheckT func (c Context) MinGasPrices() DecCoins { return c.minGasPrice } func (c Context) EventManager() *EventManager { return c.eventManager } func (c Context) Priority() int64 { return c.priority } -func (c Context) KVGasConfig() storetypes.GasConfig { return c.kvGasConfig } -func (c Context) TransientKVGasConfig() storetypes.GasConfig { return c.transientKVGasConfig } +func (c Context) KVGasConfig() storetypes.GasConfig { return *c.kvGasConfig } +func (c Context) TransientKVGasConfig() storetypes.GasConfig { return *c.transientKVGasConfig } // clone the header before returning func (c Context) BlockHeader() tmproto.Header { @@ -203,14 +203,14 @@ func (c Context) WithBlockGasMeter(meter GasMeter) Context { // WithKVGasConfig returns a Context with an updated gas configuration for // the KVStore func (c Context) WithKVGasConfig(gasConfig storetypes.GasConfig) Context { - c.kvGasConfig = gasConfig + c.kvGasConfig = &gasConfig return c } // WithTransientKVGasConfig returns a Context with an updated gas configuration for // the transient KVStore func (c Context) WithTransientKVGasConfig(gasConfig storetypes.GasConfig) Context { - c.transientKVGasConfig = gasConfig + c.transientKVGasConfig = &gasConfig return c } @@ -277,13 +277,16 @@ func (c Context) Value(key interface{}) interface{} { // ---------------------------------------------------------------------------- // KVStore fetches a KVStore from the MultiStore. -func (c Context) KVStore(key storetypes.StoreKey) KVStore { - return gaskv.NewStore(c.MultiStore().GetKVStore(key), c.GasMeter(), c.kvGasConfig) +// NOTE: Uses pointer receiver to save on execution time. +func (c *Context) KVStore(key storetypes.StoreKey) KVStore { + kv := c.ms.GetKVStore(key) + return gaskv.NewStore(kv, c.gasMeter, c.kvGasConfig) } // TransientStore fetches a TransientStore from the MultiStore. -func (c Context) TransientStore(key storetypes.StoreKey) KVStore { - return gaskv.NewStore(c.MultiStore().GetKVStore(key), c.GasMeter(), c.transientKVGasConfig) +// NOTE: Uses pointer receiver to save on execution time. +func (c *Context) TransientStore(key storetypes.StoreKey) KVStore { + return gaskv.NewStore(c.ms.GetKVStore(key), c.gasMeter, c.transientKVGasConfig) } // CacheContext returns a new Context with the multi-store cached and a new @@ -291,7 +294,7 @@ func (c Context) TransientStore(key storetypes.StoreKey) KVStore { // is called. Note, events are automatically emitted on the parent context's // EventManager when the caller executes the write. func (c Context) CacheContext() (cc Context, writeCache func()) { - cms := c.MultiStore().CacheMultiStore() + cms := c.ms.CacheMultiStore() cc = c.WithMultiStore(cms).WithEventManager(NewEventManager()) writeCache = func() { diff --git a/types/context_bench_test.go b/types/context_bench_test.go new file mode 100644 index 000000000000..9e114a0d5716 --- /dev/null +++ b/types/context_bench_test.go @@ -0,0 +1,18 @@ +package types_test + +import ( + "github.com/cosmos/cosmos-sdk/store/types" + "github.com/cosmos/cosmos-sdk/testutil" + "testing" +) + +func BenchmarkContext_KVStore(b *testing.B) { + key := types.NewKVStoreKey(b.Name() + "_TestCacheContext") + + ctx := testutil.DefaultContext(key, types.NewTransientStoreKey("transient_"+b.Name())) + + b.ResetTimer() + for i := 0; i < b.N; i++ { + _ = ctx.KVStore(key) + } +}