Gas-wrap ctx.KVStore

This commit is contained in:
Christopher Goes 2018-05-09 01:38:32 +02:00
parent 9dfccb1cfd
commit 1c4ed7b833
No known key found for this signature in database
GPG Key ID: E828D98232D328D3
16 changed files with 92 additions and 60 deletions

View File

@ -51,7 +51,7 @@ func NewGaiaApp(logger log.Logger, db dbm.DB) *GaiaApp {
// create your application object
var app = &GaiaApp{
BaseApp: bam.NewBaseApp(appName, cdc, logger, db, 10000),
BaseApp: bam.NewBaseApp(appName, cdc, logger, db, 1000000),
cdc: cdc,
keyMain: sdk.NewKVStoreKey("main"),
keyAccount: sdk.NewKVStoreKey("acc"),

View File

@ -48,7 +48,7 @@ func NewBasecoinApp(logger log.Logger, db dbm.DB) *BasecoinApp {
// Create your application object.
var app = &BasecoinApp{
BaseApp: bam.NewBaseApp(appName, cdc, logger, db, 10000),
BaseApp: bam.NewBaseApp(appName, cdc, logger, db, 1000000),
cdc: cdc,
keyMain: sdk.NewKVStoreKey("main"),
keyAccount: sdk.NewKVStoreKey("acc"),

View File

@ -56,7 +56,7 @@ func NewDemocoinApp(logger log.Logger, db dbm.DB) *DemocoinApp {
// Create your application object.
var app = &DemocoinApp{
BaseApp: bam.NewBaseApp(appName, cdc, logger, db, 10000),
BaseApp: bam.NewBaseApp(appName, cdc, logger, db, 1000000),
cdc: cdc,
capKeyMainStore: sdk.NewKVStoreKey("main"),
capKeyAccountStore: sdk.NewKVStoreKey("acc"),

View File

@ -30,7 +30,7 @@ func TestCoolKeeper(t *testing.T) {
auth.RegisterBaseAccount(cdc)
am := auth.NewAccountMapper(cdc, capKey, &auth.BaseAccount{})
ctx := sdk.NewContext(ms, abci.Header{}, false, nil, nil, 0)
ctx := sdk.NewContext(ms, abci.Header{}, false, nil, nil, 100000)
ck := bank.NewKeeper(am)
keeper := NewKeeper(capKey, ck, DefaultCodespace)

View File

@ -33,7 +33,7 @@ func TestPowKeeperGetSet(t *testing.T) {
auth.RegisterBaseAccount(cdc)
am := auth.NewAccountMapper(cdc, capKey, &auth.BaseAccount{})
ctx := sdk.NewContext(ms, abci.Header{}, false, nil, log.NewNopLogger(), 0)
ctx := sdk.NewContext(ms, abci.Header{}, false, nil, log.NewNopLogger(), 10000)
config := NewConfig("pow", int64(1))
ck := bank.NewKeeper(am)
keeper := NewKeeper(capKey, config, ck, DefaultCodespace)

View File

@ -33,7 +33,7 @@ func setupMultiStore() (sdk.MultiStore, *sdk.KVStoreKey, *sdk.KVStoreKey) {
func TestKeeperGetSet(t *testing.T) {
ms, _, capKey := setupMultiStore()
ctx := sdk.NewContext(ms, abci.Header{}, false, nil, log.NewNopLogger(), 0)
ctx := sdk.NewContext(ms, abci.Header{}, false, nil, log.NewNopLogger(), 100000)
stakeKeeper := NewKeeper(capKey, bank.NewKeeper(nil), DefaultCodespace)
addr := sdk.Address([]byte("some-address"))
@ -60,7 +60,7 @@ func TestBonding(t *testing.T) {
cdc := wire.NewCodec()
auth.RegisterBaseAccount(cdc)
ctx := sdk.NewContext(ms, abci.Header{}, false, nil, log.NewNopLogger(), 0)
ctx := sdk.NewContext(ms, abci.Header{}, false, nil, log.NewNopLogger(), 100000)
accountMapper := auth.NewAccountMapper(cdc, authKey, &auth.BaseAccount{})
coinKeeper := bank.NewKeeper(accountMapper)

View File

@ -1,27 +0,0 @@
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 TestGasKVStore(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)))
}

View File

@ -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 c.multiStore().GetKVStore(key)
return NewGasKVStore(c.GasMeter(), c.multiStore().GetKVStore(key))
}
//----------------------------------------

View File

@ -43,7 +43,7 @@ func (l MockLogger) With(kvs ...interface{}) log.Logger {
func TestContextGetOpShouldNeverPanic(t *testing.T) {
var ms types.MultiStore
ctx := types.NewContext(ms, abci.Header{}, false, nil, log.NewNopLogger(), 0)
ctx := types.NewContext(ms, abci.Header{}, false, nil, log.NewNopLogger(), 10000)
indices := []int64{
-10, 1, 0, 10, 20,
}
@ -58,7 +58,7 @@ func defaultContext(key types.StoreKey) types.Context {
cms := store.NewCommitMultiStore(db)
cms.MountStoreWithDB(key, types.StoreTypeIAVL, db)
cms.LoadLatestVersion()
ctx := types.NewContext(cms, abci.Header{}, false, nil, log.NewNopLogger(), 0)
ctx := types.NewContext(cms, abci.Header{}, false, nil, log.NewNopLogger(), 10000)
return ctx
}

View File

@ -1,8 +1,4 @@
package store
import (
sdk "github.com/cosmos/cosmos-sdk/types"
)
package types
// nolint
const (
@ -18,12 +14,12 @@ const (
// gasKVStore applies gas tracking to an underlying kvstore
type gasKVStore struct {
gasMeter sdk.GasMeter
gasMeter GasMeter
parent KVStore
}
// nolint
func NewGasKVStore(gasMeter sdk.GasMeter, parent KVStore) *gasKVStore {
func NewGasKVStore(gasMeter GasMeter, parent KVStore) *gasKVStore {
kvs := &gasKVStore{
gasMeter: gasMeter,
parent: parent,
@ -41,7 +37,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*sdk.Gas(len(value)), "ReadPerByte")
gi.gasMeter.ConsumeGas(ReadCostPerByte*Gas(len(value)), "ReadPerByte")
return value
}
@ -49,7 +45,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*sdk.Gas(len(value)), "SetPerByte")
gi.gasMeter.ConsumeGas(WriteCostPerByte*Gas(len(value)), "SetPerByte")
gi.parent.Set(key, value)
}
@ -77,12 +73,12 @@ func (gi *gasKVStore) ReverseIterator(start, end []byte) Iterator {
// Implements KVStore.
func (gi *gasKVStore) SubspaceIterator(prefix []byte) Iterator {
return gi.iterator(prefix, sdk.PrefixEndBytes(prefix), true)
return gi.iterator(prefix, PrefixEndBytes(prefix), true)
}
// Implements KVStore.
func (gi *gasKVStore) ReverseSubspaceIterator(prefix []byte) Iterator {
return gi.iterator(prefix, sdk.PrefixEndBytes(prefix), false)
return gi.iterator(prefix, PrefixEndBytes(prefix), false)
}
// Implements KVStore.
@ -101,11 +97,11 @@ func (gi *gasKVStore) iterator(start, end []byte, ascending bool) Iterator {
}
type gasIterator struct {
gasMeter sdk.GasMeter
gasMeter GasMeter
parent Iterator
}
func newGasIterator(gasMeter sdk.GasMeter, parent Iterator) Iterator {
func newGasIterator(gasMeter GasMeter, parent Iterator) Iterator {
return &gasIterator{
gasMeter: gasMeter,
parent: parent,
@ -138,7 +134,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*sdk.Gas(len(value)), "ValuePerByte")
g.gasMeter.ConsumeGas(ValueCostPerByte*Gas(len(value)), "ValuePerByte")
return value
}

63
types/gaskvstore_test.go Normal file
View File

@ -0,0 +1,63 @@
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)}

View File

@ -25,7 +25,7 @@ func defaultComponents(key sdk.StoreKey) (sdk.Context, *wire.Codec) {
cms := store.NewCommitMultiStore(db)
cms.MountStoreWithDB(key, sdk.StoreTypeIAVL, db)
cms.LoadLatestVersion()
ctx := sdk.NewContext(cms, abci.Header{}, false, nil, log.NewNopLogger(), 0)
ctx := sdk.NewContext(cms, abci.Header{}, false, nil, log.NewNopLogger(), 10000)
cdc := wire.NewCodec()
return ctx, cdc
}

View File

@ -74,7 +74,7 @@ func TestAnteHandlerSigErrors(t *testing.T) {
RegisterBaseAccount(cdc)
mapper := NewAccountMapper(cdc, capKey, &BaseAccount{})
anteHandler := NewAnteHandler(mapper, BurnFeeHandler)
ctx := sdk.NewContext(ms, abci.Header{ChainID: "mychainid"}, false, nil, log.NewNopLogger(), 0)
ctx := sdk.NewContext(ms, abci.Header{ChainID: "mychainid"}, false, nil, log.NewNopLogger(), 100000)
// keys and addresses
priv1, addr1 := privAndAddr()
@ -115,7 +115,7 @@ func TestAnteHandlerSequences(t *testing.T) {
RegisterBaseAccount(cdc)
mapper := NewAccountMapper(cdc, capKey, &BaseAccount{})
anteHandler := NewAnteHandler(mapper, BurnFeeHandler)
ctx := sdk.NewContext(ms, abci.Header{ChainID: "mychainid"}, false, nil, log.NewNopLogger(), 0)
ctx := sdk.NewContext(ms, abci.Header{ChainID: "mychainid"}, false, nil, log.NewNopLogger(), 1000000)
// keys and addresses
priv1, addr1 := privAndAddr()
@ -181,7 +181,7 @@ func TestAnteHandlerFees(t *testing.T) {
RegisterBaseAccount(cdc)
mapper := NewAccountMapper(cdc, capKey, &BaseAccount{})
anteHandler := NewAnteHandler(mapper, BurnFeeHandler)
ctx := sdk.NewContext(ms, abci.Header{ChainID: "mychainid"}, false, nil, log.NewNopLogger(), 0)
ctx := sdk.NewContext(ms, abci.Header{ChainID: "mychainid"}, false, nil, log.NewNopLogger(), 10000)
// keys and addresses
priv1, addr1 := privAndAddr()
@ -218,7 +218,7 @@ func TestAnteHandlerBadSignBytes(t *testing.T) {
RegisterBaseAccount(cdc)
mapper := NewAccountMapper(cdc, capKey, &BaseAccount{})
anteHandler := NewAnteHandler(mapper, BurnFeeHandler)
ctx := sdk.NewContext(ms, abci.Header{ChainID: "mychainid"}, false, nil, log.NewNopLogger(), 0)
ctx := sdk.NewContext(ms, abci.Header{ChainID: "mychainid"}, false, nil, log.NewNopLogger(), 10000)
// keys and addresses
priv1, addr1 := privAndAddr()
@ -293,7 +293,7 @@ func TestAnteHandlerSetPubKey(t *testing.T) {
RegisterBaseAccount(cdc)
mapper := NewAccountMapper(cdc, capKey, &BaseAccount{})
anteHandler := NewAnteHandler(mapper, BurnFeeHandler)
ctx := sdk.NewContext(ms, abci.Header{ChainID: "mychainid"}, false, nil, log.NewNopLogger(), 0)
ctx := sdk.NewContext(ms, abci.Header{ChainID: "mychainid"}, false, nil, log.NewNopLogger(), 100000)
// keys and addresses
priv1, addr1 := privAndAddr()

View File

@ -13,7 +13,7 @@ import (
func TestContextWithSigners(t *testing.T) {
ms, _ := setupMultiStore()
ctx := sdk.NewContext(ms, abci.Header{ChainID: "mychainid"}, false, nil, log.NewNopLogger(), 0)
ctx := sdk.NewContext(ms, abci.Header{ChainID: "mychainid"}, false, nil, log.NewNopLogger(), 1000000)
_, _, addr1 := keyPubAddr()
_, _, addr2 := keyPubAddr()

View File

@ -29,7 +29,7 @@ func TestAccountMapperGetSet(t *testing.T) {
RegisterBaseAccount(cdc)
// make context and mapper
ctx := sdk.NewContext(ms, abci.Header{}, false, nil, log.NewNopLogger(), 0)
ctx := sdk.NewContext(ms, abci.Header{}, false, nil, log.NewNopLogger(), 1000000)
mapper := NewAccountMapper(cdc, capKey, &BaseAccount{})
addr := sdk.Address([]byte("some-address"))

View File

@ -158,7 +158,7 @@ func createTestInput(t *testing.T, isCheckTx bool, initCoins int64) (sdk.Context
err := ms.LoadLatestVersion()
require.Nil(t, err)
ctx := sdk.NewContext(ms, abci.Header{ChainID: "foochainid"}, isCheckTx, nil, log.NewNopLogger(), 10000)
ctx := sdk.NewContext(ms, abci.Header{ChainID: "foochainid"}, isCheckTx, nil, log.NewNopLogger(), 100000000)
cdc := makeTestCodec()
accountMapper := auth.NewAccountMapper(
cdc, // amino codec