cosmos-sdk/store/gaskvstore.go

156 lines
3.7 KiB
Go
Raw Normal View History

2018-05-11 08:46:50 -07:00
package store
import (
"io"
2018-05-11 08:46:50 -07:00
sdk "github.com/cosmos/cosmos-sdk/types"
)
2018-05-08 13:03:42 -07:00
2018-07-26 18:24:18 -07:00
var _ KVStore = &gasKVStore{}
2018-05-08 15:27:41 -07:00
2018-05-08 13:03:42 -07:00
// gasKVStore applies gas tracking to an underlying kvstore
type gasKVStore struct {
2018-07-26 18:24:18 -07:00
gasMeter sdk.GasMeter
gasConfig sdk.GasConfig
parent sdk.KVStore
2018-05-08 13:03:42 -07:00
}
// nolint
2018-07-26 18:24:18 -07:00
func NewGasKVStore(gasMeter sdk.GasMeter, gasConfig sdk.GasConfig, parent sdk.KVStore) *gasKVStore {
2018-05-08 13:03:42 -07:00
kvs := &gasKVStore{
2018-07-26 18:24:18 -07:00
gasMeter: gasMeter,
gasConfig: gasConfig,
parent: parent,
2018-05-08 13:03:42 -07:00
}
return kvs
}
// Implements Store.
2018-05-11 08:46:50 -07:00
func (gi *gasKVStore) GetStoreType() sdk.StoreType {
2018-05-08 13:03:42 -07:00
return gi.parent.GetStoreType()
}
// Implements KVStore.
func (gi *gasKVStore) Get(key []byte) (value []byte) {
2018-07-26 18:24:18 -07:00
gi.gasMeter.ConsumeGas(gi.gasConfig.ReadCostFlat, "ReadFlat")
2018-05-08 15:27:41 -07:00
value = gi.parent.Get(key)
// TODO overflow-safe math?
2018-07-26 18:24:18 -07:00
gi.gasMeter.ConsumeGas(gi.gasConfig.ReadCostPerByte*sdk.Gas(len(value)), "ReadPerByte")
2018-05-08 15:27:41 -07:00
return value
2018-05-08 13:03:42 -07:00
}
// Implements KVStore.
func (gi *gasKVStore) Set(key []byte, value []byte) {
2018-07-26 18:24:18 -07:00
gi.gasMeter.ConsumeGas(gi.gasConfig.WriteCostFlat, "WriteFlat")
2018-05-08 15:27:41 -07:00
// TODO overflow-safe math?
2018-07-26 18:24:18 -07:00
gi.gasMeter.ConsumeGas(gi.gasConfig.WriteCostPerByte*sdk.Gas(len(value)), "WritePerByte")
2018-05-08 13:03:42 -07:00
gi.parent.Set(key, value)
}
// Implements KVStore.
func (gi *gasKVStore) Has(key []byte) bool {
2018-07-26 18:24:18 -07:00
gi.gasMeter.ConsumeGas(gi.gasConfig.HasCost, "Has")
2018-05-08 13:03:42 -07:00
return gi.parent.Has(key)
}
// Implements KVStore.
func (gi *gasKVStore) Delete(key []byte) {
2018-05-08 15:27:41 -07:00
// No gas costs for deletion
2018-05-08 13:03:42 -07:00
gi.parent.Delete(key)
}
// Implements KVStore
func (gi *gasKVStore) Prefix(prefix []byte) KVStore {
2018-07-26 18:24:18 -07:00
// Keep gasstore layer at the top
return &gasKVStore{
gasMeter: gi.gasMeter,
gasConfig: gi.gasConfig,
parent: prefixStore{gi.parent, prefix},
}
}
// Implements KVStore
func (gi *gasKVStore) Gas(meter GasMeter, config GasConfig) KVStore {
return NewGasKVStore(meter, config, gi)
}
2018-05-08 13:03:42 -07:00
// Implements KVStore.
2018-05-11 08:46:50 -07:00
func (gi *gasKVStore) Iterator(start, end []byte) sdk.Iterator {
2018-05-08 13:03:42 -07:00
return gi.iterator(start, end, true)
}
// Implements KVStore.
2018-05-11 08:46:50 -07:00
func (gi *gasKVStore) ReverseIterator(start, end []byte) sdk.Iterator {
2018-05-08 13:03:42 -07:00
return gi.iterator(start, end, false)
}
// Implements KVStore.
2018-05-11 08:46:50 -07:00
func (gi *gasKVStore) CacheWrap() sdk.CacheWrap {
panic("cannot CacheWrap a GasKVStore")
}
// CacheWrapWithTrace implements the KVStore interface.
func (gi *gasKVStore) CacheWrapWithTrace(_ io.Writer, _ TraceContext) CacheWrap {
panic("cannot CacheWrapWithTrace a GasKVStore")
2018-05-08 13:03:42 -07:00
}
2018-05-11 08:46:50 -07:00
func (gi *gasKVStore) iterator(start, end []byte, ascending bool) sdk.Iterator {
var parent sdk.Iterator
2018-05-08 13:03:42 -07:00
if ascending {
parent = gi.parent.Iterator(start, end)
} else {
parent = gi.parent.ReverseIterator(start, end)
}
2018-07-26 18:24:18 -07:00
return newGasIterator(gi.gasMeter, gi.gasConfig, parent)
2018-05-08 15:27:41 -07:00
}
type gasIterator struct {
2018-07-26 18:24:18 -07:00
gasMeter sdk.GasMeter
gasConfig sdk.GasConfig
parent sdk.Iterator
2018-05-08 15:27:41 -07:00
}
2018-07-26 18:24:18 -07:00
func newGasIterator(gasMeter sdk.GasMeter, gasConfig sdk.GasConfig, parent sdk.Iterator) sdk.Iterator {
2018-05-08 15:27:41 -07:00
return &gasIterator{
2018-07-26 18:24:18 -07:00
gasMeter: gasMeter,
gasConfig: gasConfig,
parent: parent,
2018-05-08 15:27:41 -07:00
}
}
// Implements Iterator.
func (g *gasIterator) Domain() (start []byte, end []byte) {
return g.parent.Domain()
}
// Implements Iterator.
func (g *gasIterator) Valid() bool {
return g.parent.Valid()
}
// Implements Iterator.
func (g *gasIterator) Next() {
g.parent.Next()
}
// Implements Iterator.
func (g *gasIterator) Key() (key []byte) {
2018-07-26 18:24:18 -07:00
g.gasMeter.ConsumeGas(g.gasConfig.KeyCostFlat, "KeyFlat")
2018-05-08 16:11:22 -07:00
key = g.parent.Key()
return key
2018-05-08 15:27:41 -07:00
}
// Implements Iterator.
func (g *gasIterator) Value() (value []byte) {
value = g.parent.Value()
2018-07-26 18:24:18 -07:00
g.gasMeter.ConsumeGas(g.gasConfig.ValueCostFlat, "ValueFlat")
g.gasMeter.ConsumeGas(g.gasConfig.ValueCostPerByte*sdk.Gas(len(value)), "ValuePerByte")
2018-05-08 15:27:41 -07:00
return value
}
// Implements Iterator.
func (g *gasIterator) Close() {
g.parent.Close()
2018-05-08 13:03:42 -07:00
}