Move GasKVStore to /store
This commit is contained in:
parent
702ffafa06
commit
147cf9f897
|
@ -50,6 +50,10 @@ 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 {
|
||||
panic("not implemented")
|
||||
}
|
||||
|
||||
func (ms multiStore) GetStore(key sdk.StoreKey) sdk.Store {
|
||||
panic("not implemented")
|
||||
}
|
||||
|
|
|
@ -72,3 +72,8 @@ func (cms cacheMultiStore) GetStore(key StoreKey) Store {
|
|||
func (cms cacheMultiStore) GetKVStore(key StoreKey) KVStore {
|
||||
return cms.stores[key].(KVStore)
|
||||
}
|
||||
|
||||
// Implements MultiStore.
|
||||
func (cms cacheMultiStore) GetKVStoreWithGas(meter sdk.GasMeter, key StoreKey) KVStore {
|
||||
return NewGasKVStore(meter, cms.GetKVStore(key))
|
||||
}
|
||||
|
|
|
@ -1,4 +1,8 @@
|
|||
package types
|
||||
package store
|
||||
|
||||
import (
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
)
|
||||
|
||||
// nolint
|
||||
const (
|
||||
|
@ -14,12 +18,12 @@ const (
|
|||
|
||||
// gasKVStore applies gas tracking to an underlying kvstore
|
||||
type gasKVStore struct {
|
||||
gasMeter GasMeter
|
||||
parent KVStore
|
||||
gasMeter sdk.GasMeter
|
||||
parent sdk.KVStore
|
||||
}
|
||||
|
||||
// nolint
|
||||
func NewGasKVStore(gasMeter GasMeter, parent KVStore) *gasKVStore {
|
||||
func NewGasKVStore(gasMeter sdk.GasMeter, parent sdk.KVStore) *gasKVStore {
|
||||
kvs := &gasKVStore{
|
||||
gasMeter: gasMeter,
|
||||
parent: parent,
|
||||
|
@ -28,7 +32,7 @@ func NewGasKVStore(gasMeter GasMeter, parent KVStore) *gasKVStore {
|
|||
}
|
||||
|
||||
// Implements Store.
|
||||
func (gi *gasKVStore) GetStoreType() StoreType {
|
||||
func (gi *gasKVStore) GetStoreType() sdk.StoreType {
|
||||
return gi.parent.GetStoreType()
|
||||
}
|
||||
|
||||
|
@ -37,7 +41,7 @@ func (gi *gasKVStore) Get(key []byte) (value []byte) {
|
|||
gi.gasMeter.ConsumeGas(ReadCostFlat, "GetFlat")
|
||||
value = gi.parent.Get(key)
|
||||
// TODO overflow-safe math?
|
||||
gi.gasMeter.ConsumeGas(ReadCostPerByte*Gas(len(value)), "ReadPerByte")
|
||||
gi.gasMeter.ConsumeGas(ReadCostPerByte*sdk.Gas(len(value)), "ReadPerByte")
|
||||
return value
|
||||
}
|
||||
|
||||
|
@ -45,7 +49,7 @@ func (gi *gasKVStore) Get(key []byte) (value []byte) {
|
|||
func (gi *gasKVStore) Set(key []byte, value []byte) {
|
||||
gi.gasMeter.ConsumeGas(WriteCostFlat, "SetFlat")
|
||||
// TODO overflow-safe math?
|
||||
gi.gasMeter.ConsumeGas(WriteCostPerByte*Gas(len(value)), "SetPerByte")
|
||||
gi.gasMeter.ConsumeGas(WriteCostPerByte*sdk.Gas(len(value)), "SetPerByte")
|
||||
gi.parent.Set(key, value)
|
||||
}
|
||||
|
||||
|
@ -62,32 +66,32 @@ func (gi *gasKVStore) Delete(key []byte) {
|
|||
}
|
||||
|
||||
// Implements KVStore.
|
||||
func (gi *gasKVStore) Iterator(start, end []byte) Iterator {
|
||||
func (gi *gasKVStore) Iterator(start, end []byte) sdk.Iterator {
|
||||
return gi.iterator(start, end, true)
|
||||
}
|
||||
|
||||
// Implements KVStore.
|
||||
func (gi *gasKVStore) ReverseIterator(start, end []byte) Iterator {
|
||||
func (gi *gasKVStore) ReverseIterator(start, end []byte) sdk.Iterator {
|
||||
return gi.iterator(start, end, false)
|
||||
}
|
||||
|
||||
// Implements KVStore.
|
||||
func (gi *gasKVStore) SubspaceIterator(prefix []byte) Iterator {
|
||||
return gi.iterator(prefix, PrefixEndBytes(prefix), true)
|
||||
func (gi *gasKVStore) SubspaceIterator(prefix []byte) sdk.Iterator {
|
||||
return gi.iterator(prefix, sdk.PrefixEndBytes(prefix), true)
|
||||
}
|
||||
|
||||
// Implements KVStore.
|
||||
func (gi *gasKVStore) ReverseSubspaceIterator(prefix []byte) Iterator {
|
||||
return gi.iterator(prefix, PrefixEndBytes(prefix), false)
|
||||
func (gi *gasKVStore) ReverseSubspaceIterator(prefix []byte) sdk.Iterator {
|
||||
return gi.iterator(prefix, sdk.PrefixEndBytes(prefix), false)
|
||||
}
|
||||
|
||||
// Implements KVStore.
|
||||
func (gi *gasKVStore) CacheWrap() CacheWrap {
|
||||
func (gi *gasKVStore) CacheWrap() sdk.CacheWrap {
|
||||
panic("you cannot CacheWrap a GasKVStore")
|
||||
}
|
||||
|
||||
func (gi *gasKVStore) iterator(start, end []byte, ascending bool) Iterator {
|
||||
var parent Iterator
|
||||
func (gi *gasKVStore) iterator(start, end []byte, ascending bool) sdk.Iterator {
|
||||
var parent sdk.Iterator
|
||||
if ascending {
|
||||
parent = gi.parent.Iterator(start, end)
|
||||
} else {
|
||||
|
@ -97,11 +101,11 @@ func (gi *gasKVStore) iterator(start, end []byte, ascending bool) Iterator {
|
|||
}
|
||||
|
||||
type gasIterator struct {
|
||||
gasMeter GasMeter
|
||||
parent Iterator
|
||||
gasMeter sdk.GasMeter
|
||||
parent sdk.Iterator
|
||||
}
|
||||
|
||||
func newGasIterator(gasMeter GasMeter, parent Iterator) Iterator {
|
||||
func newGasIterator(gasMeter sdk.GasMeter, parent sdk.Iterator) sdk.Iterator {
|
||||
return &gasIterator{
|
||||
gasMeter: gasMeter,
|
||||
parent: parent,
|
||||
|
@ -134,7 +138,7 @@ func (g *gasIterator) Key() (key []byte) {
|
|||
func (g *gasIterator) Value() (value []byte) {
|
||||
value = g.parent.Value()
|
||||
g.gasMeter.ConsumeGas(ValueCostFlat, "ValueFlat")
|
||||
g.gasMeter.ConsumeGas(ValueCostPerByte*Gas(len(value)), "ValuePerByte")
|
||||
g.gasMeter.ConsumeGas(ValueCostPerByte*sdk.Gas(len(value)), "ValuePerByte")
|
||||
return value
|
||||
}
|
||||
|
|
@ -0,0 +1,34 @@
|
|||
package store
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
"github.com/stretchr/testify/require"
|
||||
dbm "github.com/tendermint/tmlibs/db"
|
||||
)
|
||||
|
||||
func newGasKVStore() KVStore {
|
||||
meter := sdk.NewGasMeter(1000)
|
||||
mem := dbStoreAdapter{dbm.NewMemDB()}
|
||||
return NewGasKVStore(meter, mem)
|
||||
}
|
||||
|
||||
func TestGasKVStoreBasic(t *testing.T) {
|
||||
mem := dbStoreAdapter{dbm.NewMemDB()}
|
||||
meter := sdk.NewGasMeter(1000)
|
||||
st := NewGasKVStore(meter, mem)
|
||||
|
||||
require.Empty(t, st.Get(keyFmt(1)), "Expected `key1` to be empty")
|
||||
|
||||
mem.Set(keyFmt(1), valFmt(1))
|
||||
st.Set(keyFmt(1), valFmt(1))
|
||||
require.Equal(t, valFmt(1), st.Get(keyFmt(1)))
|
||||
}
|
||||
|
||||
func TestGasKVStoreOutOfGas(t *testing.T) {
|
||||
mem := dbStoreAdapter{dbm.NewMemDB()}
|
||||
meter := sdk.NewGasMeter(0)
|
||||
st := NewGasKVStore(meter, mem)
|
||||
require.Panics(t, func() { st.Set(keyFmt(1), valFmt(1)) }, "Expected out-of-gas")
|
||||
}
|
|
@ -183,6 +183,11 @@ func (rs *rootMultiStore) GetKVStore(key StoreKey) KVStore {
|
|||
return rs.stores[key].(KVStore)
|
||||
}
|
||||
|
||||
// Implements MultiStore.
|
||||
func (rs *rootMultiStore) GetKVStoreWithGas(meter sdk.GasMeter, key StoreKey) KVStore {
|
||||
return NewGasKVStore(meter, rs.GetKVStore(key))
|
||||
}
|
||||
|
||||
// getStoreByName will first convert the original name to
|
||||
// a special key, before looking up the CommitStore.
|
||||
// This is not exposed to the extensions (which will need the
|
||||
|
|
|
@ -69,7 +69,7 @@ func (c Context) Value(key interface{}) interface{} {
|
|||
|
||||
// KVStore fetches a KVStore from the MultiStore.
|
||||
func (c Context) KVStore(key StoreKey) KVStore {
|
||||
return NewGasKVStore(c.GasMeter(), c.multiStore().GetKVStore(key))
|
||||
return c.multiStore().GetKVStoreWithGas(c.GasMeter(), key)
|
||||
}
|
||||
|
||||
//----------------------------------------
|
||||
|
|
|
@ -1,63 +0,0 @@
|
|||
package types
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
cmn "github.com/tendermint/tmlibs/common"
|
||||
dbm "github.com/tendermint/tmlibs/db"
|
||||
)
|
||||
|
||||
func newGasKVStore() KVStore {
|
||||
meter := NewGasMeter(1000)
|
||||
mem := dbStoreAdapter{dbm.NewMemDB()}
|
||||
return NewGasKVStore(meter, mem)
|
||||
}
|
||||
|
||||
func TestGasKVStoreBasic(t *testing.T) {
|
||||
mem := dbStoreAdapter{dbm.NewMemDB()}
|
||||
meter := NewGasMeter(1000)
|
||||
st := NewGasKVStore(meter, mem)
|
||||
|
||||
require.Empty(t, st.Get(keyFmt(1)), "Expected `key1` to be empty")
|
||||
|
||||
mem.Set(keyFmt(1), valFmt(1))
|
||||
st.Set(keyFmt(1), valFmt(1))
|
||||
require.Equal(t, valFmt(1), st.Get(keyFmt(1)))
|
||||
}
|
||||
|
||||
func TestGasKVStoreOutOfGas(t *testing.T) {
|
||||
mem := dbStoreAdapter{dbm.NewMemDB()}
|
||||
meter := NewGasMeter(0)
|
||||
st := NewGasKVStore(meter, mem)
|
||||
require.Panics(t, func() { st.Set(keyFmt(1), valFmt(1)) }, "Expected out-of-gas")
|
||||
}
|
||||
|
||||
func keyFmt(i int) []byte { return bz(cmn.Fmt("key%0.8d", i)) }
|
||||
func valFmt(i int) []byte { return bz(cmn.Fmt("value%0.8d", i)) }
|
||||
func bz(s string) []byte { return []byte(s) }
|
||||
|
||||
type dbStoreAdapter struct {
|
||||
dbm.DB
|
||||
}
|
||||
|
||||
// Implements Store.
|
||||
func (dbStoreAdapter) GetStoreType() StoreType {
|
||||
return StoreTypeDB
|
||||
}
|
||||
|
||||
// Implements KVStore.
|
||||
func (dsa dbStoreAdapter) CacheWrap() CacheWrap {
|
||||
panic("unsupported")
|
||||
}
|
||||
|
||||
func (dsa dbStoreAdapter) SubspaceIterator(prefix []byte) Iterator {
|
||||
return dsa.Iterator(prefix, PrefixEndBytes(prefix))
|
||||
}
|
||||
|
||||
func (dsa dbStoreAdapter) ReverseSubspaceIterator(prefix []byte) Iterator {
|
||||
return dsa.ReverseIterator(prefix, PrefixEndBytes(prefix))
|
||||
}
|
||||
|
||||
// dbm.DB implements KVStore so we can CacheKVStore it.
|
||||
var _ KVStore = dbStoreAdapter{dbm.DB(nil)}
|
|
@ -49,6 +49,7 @@ type MultiStore interface { //nolint
|
|||
// Convenience for fetching substores.
|
||||
GetStore(StoreKey) Store
|
||||
GetKVStore(StoreKey) KVStore
|
||||
GetKVStoreWithGas(GasMeter, StoreKey) KVStore
|
||||
}
|
||||
|
||||
// From MultiStore.CacheMultiStore()....
|
||||
|
|
Loading…
Reference in New Issue