Skip to content

Commit

Permalink
Merge pull request #1481: Transient Stores
Browse files Browse the repository at this point in the history
move gasconfig to types, make GetKVStoreWithGas take GasConfig

fix lint

modify transientstore

in progress

add test for transientstore

fix errors

fix test

fix errors and lint

last fix
  • Loading branch information
mossid committed Jun 30, 2018
1 parent 2f508f5 commit daed85e
Show file tree
Hide file tree
Showing 27 changed files with 333 additions and 134 deletions.
17 changes: 12 additions & 5 deletions baseapp/baseapp.go
Original file line number Diff line number Diff line change
Expand Up @@ -102,18 +102,25 @@ func (app *BaseApp) RegisterCodespace(codespace sdk.CodespaceType) sdk.Codespace
// Mount a store to the provided key in the BaseApp multistore
func (app *BaseApp) MountStoresIAVL(keys ...*sdk.KVStoreKey) {
for _, key := range keys {
app.MountStore(key, sdk.StoreTypeIAVL)
app.MountStore(key, sdk.NoTransient, sdk.StoreTypeIAVL)
}
}

// Mount stores to the provided keys with transient support
func (app *BaseApp) MountStoresIAVLUsingTransient(keys ...*sdk.KVStoreKey) {
for _, key := range keys {
app.MountStore(key, sdk.UsingTransient, sdk.StoreTypeIAVL)
}
}

// Mount a store to the provided key in the BaseApp multistore, using a specified DB
func (app *BaseApp) MountStoreWithDB(key sdk.StoreKey, typ sdk.StoreType, db dbm.DB) {
app.cms.MountStoreWithDB(key, typ, db)
func (app *BaseApp) MountStoreWithDB(key sdk.StoreKey, typ sdk.StoreType, transient sdk.TransientUsage, db dbm.DB) {
app.cms.MountStoreWithDB(key, typ, transient, db)
}

// Mount a store to the provided key in the BaseApp multistore, using the default DB
func (app *BaseApp) MountStore(key sdk.StoreKey, typ sdk.StoreType) {
app.cms.MountStoreWithDB(key, typ, nil)
func (app *BaseApp) MountStore(key sdk.StoreKey, transient sdk.TransientUsage, typ sdk.StoreType) {
app.cms.MountStoreWithDB(key, typ, transient, nil)
}

// Set the txDecoder function
Expand Down
2 changes: 1 addition & 1 deletion examples/democoin/x/assoc/validator_set_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ import (
func defaultContext(key sdk.StoreKey) sdk.Context {
db := dbm.NewMemDB()
cms := store.NewCommitMultiStore(db)
cms.MountStoreWithDB(key, sdk.StoreTypeIAVL, db)
cms.MountStoreWithDB(key, sdk.StoreTypeIAVL, sdk.NoTransient, db)
cms.LoadLatestVersion()
ctx := sdk.NewContext(cms, abci.Header{}, false, nil)
return ctx
Expand Down
2 changes: 1 addition & 1 deletion examples/democoin/x/cool/keeper_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ func setupMultiStore() (sdk.MultiStore, *sdk.KVStoreKey) {
db := dbm.NewMemDB()
capKey := sdk.NewKVStoreKey("capkey")
ms := store.NewCommitMultiStore(db)
ms.MountStoreWithDB(capKey, sdk.StoreTypeIAVL, db)
ms.MountStoreWithDB(capKey, sdk.StoreTypeIAVL, sdk.NoTransient, db)
ms.LoadLatestVersion()
return ms, capKey
}
Expand Down
2 changes: 1 addition & 1 deletion examples/democoin/x/oracle/oracle_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ func defaultContext(keys ...sdk.StoreKey) sdk.Context {
db := dbm.NewMemDB()
cms := store.NewCommitMultiStore(db)
for _, key := range keys {
cms.MountStoreWithDB(key, sdk.StoreTypeIAVL, db)
cms.MountStoreWithDB(key, sdk.StoreTypeIAVL, sdk.NoTransient, db)
}
cms.LoadLatestVersion()
ctx := sdk.NewContext(cms, abci.Header{}, false, nil)
Expand Down
2 changes: 1 addition & 1 deletion examples/democoin/x/pow/keeper_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ func setupMultiStore() (sdk.MultiStore, *sdk.KVStoreKey) {
db := dbm.NewMemDB()
capKey := sdk.NewKVStoreKey("capkey")
ms := store.NewCommitMultiStore(db)
ms.MountStoreWithDB(capKey, sdk.StoreTypeIAVL, db)
ms.MountStoreWithDB(capKey, sdk.StoreTypeIAVL, sdk.NoTransient, db)
ms.LoadLatestVersion()

return ms, capKey
Expand Down
4 changes: 2 additions & 2 deletions examples/democoin/x/simplestake/keeper_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,8 @@ func setupMultiStore() (sdk.MultiStore, *sdk.KVStoreKey, *sdk.KVStoreKey) {
authKey := sdk.NewKVStoreKey("authkey")
capKey := sdk.NewKVStoreKey("capkey")
ms := store.NewCommitMultiStore(db)
ms.MountStoreWithDB(capKey, sdk.StoreTypeIAVL, db)
ms.MountStoreWithDB(authKey, sdk.StoreTypeIAVL, db)
ms.MountStoreWithDB(capKey, sdk.StoreTypeIAVL, sdk.NoTransient, db)
ms.MountStoreWithDB(authKey, sdk.StoreTypeIAVL, sdk.NoTransient, db)
ms.LoadLatestVersion()
return ms, authKey, capKey
}
Expand Down
6 changes: 4 additions & 2 deletions server/mock/store.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ import (
sdk "github.com/cosmos/cosmos-sdk/types"
)

var _ sdk.CommitMultiStore = multiStore{}

type multiStore struct {
kv map[sdk.StoreKey]kvStore
}
Expand Down Expand Up @@ -34,7 +36,7 @@ func (ms multiStore) GetCommitStore(key sdk.StoreKey) sdk.CommitStore {
panic("not implemented")
}

func (ms multiStore) MountStoreWithDB(key sdk.StoreKey, typ sdk.StoreType, db dbm.DB) {
func (ms multiStore) MountStoreWithDB(key sdk.StoreKey, typ sdk.StoreType, transient sdk.TransientUsage, db dbm.DB) {
ms.kv[key] = kvStore{store: make(map[string][]byte)}
}

Expand All @@ -50,7 +52,7 @@ func (ms multiStore) GetKVStore(key sdk.StoreKey) sdk.KVStore {
return ms.kv[key]
}

func (ms multiStore) GetKVStoreWithGas(meter sdk.GasMeter, key sdk.StoreKey) sdk.KVStore {
func (ms multiStore) GetKVStoreWithGas(meter sdk.GasMeter, config sdk.GasConfig, key sdk.StoreKey) sdk.KVStore {
panic("not implemented")
}

Expand Down
2 changes: 1 addition & 1 deletion server/mock/store_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ func TestStore(t *testing.T) {
cms := NewCommitMultiStore()

key := sdk.NewKVStoreKey("test")
cms.MountStoreWithDB(key, sdk.StoreTypeIAVL, db)
cms.MountStoreWithDB(key, sdk.StoreTypeIAVL, sdk.NoTransient, db)
err := cms.LoadLatestVersion()
require.Nil(t, err)

Expand Down
4 changes: 2 additions & 2 deletions store/cachemultistore.go
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,6 @@ func (cms cacheMultiStore) GetKVStore(key StoreKey) KVStore {
}

// Implements MultiStore.
func (cms cacheMultiStore) GetKVStoreWithGas(meter sdk.GasMeter, key StoreKey) KVStore {
return NewGasKVStore(meter, cms.GetKVStore(key))
func (cms cacheMultiStore) GetKVStoreWithGas(meter sdk.GasMeter, config sdk.GasConfig, key StoreKey) KVStore {
return NewGasKVStore(meter, config, cms.GetKVStore(key))
}
55 changes: 24 additions & 31 deletions store/gaskvstore.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,29 +4,19 @@ import (
sdk "github.com/cosmos/cosmos-sdk/types"
)

// nolint
const (
HasCost = 10
ReadCostFlat = 10
ReadCostPerByte = 1
WriteCostFlat = 10
WriteCostPerByte = 10
KeyCostFlat = 5
ValueCostFlat = 10
ValueCostPerByte = 1
)

// gasKVStore applies gas tracking to an underlying kvstore
type gasKVStore struct {
gasMeter sdk.GasMeter
parent sdk.KVStore
gasMeter sdk.GasMeter
gasConfig sdk.GasConfig
parent sdk.KVStore
}

// nolint
func NewGasKVStore(gasMeter sdk.GasMeter, parent sdk.KVStore) *gasKVStore {
func NewGasKVStore(gasMeter sdk.GasMeter, gasConfig sdk.GasConfig, parent sdk.KVStore) *gasKVStore {
kvs := &gasKVStore{
gasMeter: gasMeter,
parent: parent,
gasMeter: gasMeter,
gasConfig: gasConfig,
parent: parent,
}
return kvs
}
Expand All @@ -38,24 +28,25 @@ func (gi *gasKVStore) GetStoreType() sdk.StoreType {

// Implements KVStore.
func (gi *gasKVStore) Get(key []byte) (value []byte) {
gi.gasMeter.ConsumeGas(ReadCostFlat, "GetFlat")
gi.gasMeter.ConsumeGas(gi.gasConfig.ReadCostFlat, "ReadFlat")
value = gi.parent.Get(key)
// TODO overflow-safe math?
gi.gasMeter.ConsumeGas(ReadCostPerByte*sdk.Gas(len(value)), "ReadPerByte")
gi.gasMeter.ConsumeGas(gi.gasConfig.ReadCostPerByte*sdk.Gas(len(value)), "ReadPerByte")

return value
}

// Implements KVStore.
func (gi *gasKVStore) Set(key []byte, value []byte) {
gi.gasMeter.ConsumeGas(WriteCostFlat, "SetFlat")
gi.gasMeter.ConsumeGas(gi.gasConfig.WriteCostFlat, "WriteFlat")
// TODO overflow-safe math?
gi.gasMeter.ConsumeGas(WriteCostPerByte*sdk.Gas(len(value)), "SetPerByte")
gi.gasMeter.ConsumeGas(gi.gasConfig.WriteCostPerByte*sdk.Gas(len(value)), "WritePerByte")
gi.parent.Set(key, value)
}

// Implements KVStore.
func (gi *gasKVStore) Has(key []byte) bool {
gi.gasMeter.ConsumeGas(HasCost, "Has")
gi.gasMeter.ConsumeGas(gi.gasConfig.HasCost, "Has")
return gi.parent.Has(key)
}

Expand Down Expand Up @@ -92,18 +83,20 @@ func (gi *gasKVStore) iterator(start, end []byte, ascending bool) sdk.Iterator {
} else {
parent = gi.parent.ReverseIterator(start, end)
}
return newGasIterator(gi.gasMeter, parent)
return newGasIterator(gi.gasMeter, gi.gasConfig, parent)
}

type gasIterator struct {
gasMeter sdk.GasMeter
parent sdk.Iterator
gasMeter sdk.GasMeter
gasConfig sdk.GasConfig
parent sdk.Iterator
}

func newGasIterator(gasMeter sdk.GasMeter, parent sdk.Iterator) sdk.Iterator {
func newGasIterator(gasMeter sdk.GasMeter, gasConfig sdk.GasConfig, parent sdk.Iterator) sdk.Iterator {
return &gasIterator{
gasMeter: gasMeter,
parent: parent,
gasMeter: gasMeter,
gasConfig: gasConfig,
parent: parent,
}
}

Expand All @@ -124,16 +117,16 @@ func (g *gasIterator) Next() {

// Implements Iterator.
func (g *gasIterator) Key() (key []byte) {
g.gasMeter.ConsumeGas(KeyCostFlat, "KeyFlat")
g.gasMeter.ConsumeGas(g.gasConfig.KeyCostFlat, "KeyFlat")
key = g.parent.Key()
return key
}

// Implements Iterator.
func (g *gasIterator) Value() (value []byte) {
value = g.parent.Value()
g.gasMeter.ConsumeGas(ValueCostFlat, "ValueFlat")
g.gasMeter.ConsumeGas(ValueCostPerByte*sdk.Gas(len(value)), "ValuePerByte")
g.gasMeter.ConsumeGas(g.gasConfig.ValueCostFlat, "ValueFlat")
g.gasMeter.ConsumeGas(g.gasConfig.ValueCostPerByte*sdk.Gas(len(value)), "ValuePerByte")
return value
}

Expand Down
10 changes: 5 additions & 5 deletions store/gaskvstore_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,13 @@ import (
func newGasKVStore() KVStore {
meter := sdk.NewGasMeter(1000)
mem := dbStoreAdapter{dbm.NewMemDB()}
return NewGasKVStore(meter, mem)
return NewGasKVStore(meter, sdk.DefaultGasConfig(), mem)
}

func TestGasKVStoreBasic(t *testing.T) {
mem := dbStoreAdapter{dbm.NewMemDB()}
meter := sdk.NewGasMeter(1000)
st := NewGasKVStore(meter, mem)
st := NewGasKVStore(meter, sdk.DefaultGasConfig(), mem)
require.Empty(t, st.Get(keyFmt(1)), "Expected `key1` to be empty")
st.Set(keyFmt(1), valFmt(1))
require.Equal(t, valFmt(1), st.Get(keyFmt(1)))
Expand All @@ -29,7 +29,7 @@ func TestGasKVStoreBasic(t *testing.T) {
func TestGasKVStoreIterator(t *testing.T) {
mem := dbStoreAdapter{dbm.NewMemDB()}
meter := sdk.NewGasMeter(1000)
st := NewGasKVStore(meter, mem)
st := NewGasKVStore(meter, sdk.DefaultGasConfig(), mem)
require.Empty(t, st.Get(keyFmt(1)), "Expected `key1` to be empty")
require.Empty(t, st.Get(keyFmt(2)), "Expected `key2` to be empty")
st.Set(keyFmt(1), valFmt(1))
Expand All @@ -53,14 +53,14 @@ func TestGasKVStoreIterator(t *testing.T) {
func TestGasKVStoreOutOfGasSet(t *testing.T) {
mem := dbStoreAdapter{dbm.NewMemDB()}
meter := sdk.NewGasMeter(0)
st := NewGasKVStore(meter, mem)
st := NewGasKVStore(meter, sdk.DefaultGasConfig(), mem)
require.Panics(t, func() { st.Set(keyFmt(1), valFmt(1)) }, "Expected out-of-gas")
}

func TestGasKVStoreOutOfGasIterator(t *testing.T) {
mem := dbStoreAdapter{dbm.NewMemDB()}
meter := sdk.NewGasMeter(200)
st := NewGasKVStore(meter, mem)
st := NewGasKVStore(meter, sdk.DefaultGasConfig(), mem)
st.Set(keyFmt(1), valFmt(1))
iterator := st.Iterator(nil, nil)
iterator.Next()
Expand Down
2 changes: 1 addition & 1 deletion store/prefixstore_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ func TestCacheKVStorePrefix(t *testing.T) {
func TestGasKVStorePrefix(t *testing.T) {
meter := sdk.NewGasMeter(100000000)
mem := dbStoreAdapter{dbm.NewMemDB()}
gasStore := NewGasKVStore(meter, mem)
gasStore := NewGasKVStore(meter, sdk.DefaultGasConfig(), mem)

testPrefixStore(t, gasStore, []byte("test"))
}
Expand Down
Loading

0 comments on commit daed85e

Please sign in to comment.