cosmos-sdk/types/gas.go

167 lines
3.5 KiB
Go
Raw Normal View History

2018-05-07 10:48:12 -07:00
package types
// Gas consumption descriptors.
const (
GasIterNextCostFlatDesc = "IterNextFlat"
GasValuePerByteDesc = "ValuePerByte"
GasWritePerByteDesc = "WritePerByte"
GasReadPerByteDesc = "ReadPerByte"
GasWriteCostFlatDesc = "WriteFlat"
GasReadCostFlatDesc = "ReadFlat"
GasHasDesc = "Has"
GasDeleteDesc = "Delete"
)
var (
cachedKVGasConfig = KVGasConfig()
cachedTransientGasConfig = TransientGasConfig()
)
2018-05-07 12:49:11 -07:00
// Gas measured by the SDK
type Gas = uint64
2018-05-07 10:48:12 -07:00
// ErrorOutOfGas defines an error thrown when an action results in out of gas.
2018-05-08 08:34:09 -07:00
type ErrorOutOfGas struct {
Descriptor string
}
// ErrorGasOverflow defines an error thrown when an action results gas consumption
// unsigned integer overflow.
type ErrorGasOverflow struct {
Descriptor string
}
2018-05-07 12:49:11 -07:00
// GasMeter interface to track gas consumption
2018-05-07 10:48:12 -07:00
type GasMeter interface {
GasConsumed() Gas
GasConsumedToLimit() Gas
Limit() Gas
2018-05-08 08:34:09 -07:00
ConsumeGas(amount Gas, descriptor string)
IsPastLimit() bool
IsOutOfGas() bool
2018-05-07 10:48:12 -07:00
}
type basicGasMeter struct {
limit Gas
consumed Gas
}
// NewGasMeter returns a reference to a new basicGasMeter.
2018-05-07 10:48:12 -07:00
func NewGasMeter(limit Gas) GasMeter {
return &basicGasMeter{
limit: limit,
consumed: 0,
}
}
func (g *basicGasMeter) GasConsumed() Gas {
return g.consumed
}
func (g *basicGasMeter) Limit() Gas {
return g.limit
}
func (g *basicGasMeter) GasConsumedToLimit() Gas {
if g.consumed > g.limit {
return g.limit
} else {
return g.consumed
}
}
2018-05-08 08:34:09 -07:00
func (g *basicGasMeter) ConsumeGas(amount Gas, descriptor string) {
var overflow bool
// TODO: Should we set the consumed field after overflow checking?
g.consumed, overflow = AddUint64Overflow(g.consumed, amount)
if overflow {
panic(ErrorGasOverflow{descriptor})
}
2018-05-08 08:34:09 -07:00
if g.consumed > g.limit {
panic(ErrorOutOfGas{descriptor})
}
2018-05-07 10:48:12 -07:00
}
2018-05-15 17:31:52 -07:00
func (g *basicGasMeter) IsPastLimit() bool {
2018-11-13 08:30:06 -08:00
return g.consumed > g.limit
}
func (g *basicGasMeter) IsOutOfGas() bool {
return g.consumed >= g.limit
}
2018-05-15 17:31:52 -07:00
type infiniteGasMeter struct {
consumed Gas
}
// NewInfiniteGasMeter returns a reference to a new infiniteGasMeter.
2018-05-15 17:31:52 -07:00
func NewInfiniteGasMeter() GasMeter {
return &infiniteGasMeter{
consumed: 0,
}
}
func (g *infiniteGasMeter) GasConsumed() Gas {
return g.consumed
}
func (g *infiniteGasMeter) GasConsumedToLimit() Gas {
return g.consumed
}
func (g *infiniteGasMeter) Limit() Gas {
return 0
}
2018-05-15 17:31:52 -07:00
func (g *infiniteGasMeter) ConsumeGas(amount Gas, descriptor string) {
var overflow bool
// TODO: Should we set the consumed field after overflow checking?
g.consumed, overflow = AddUint64Overflow(g.consumed, amount)
if overflow {
panic(ErrorGasOverflow{descriptor})
}
2018-05-15 17:31:52 -07:00
}
2018-07-26 18:24:18 -07:00
func (g *infiniteGasMeter) IsPastLimit() bool {
return false
}
func (g *infiniteGasMeter) IsOutOfGas() bool {
2018-11-13 08:30:06 -08:00
return false
}
2018-07-26 18:24:18 -07:00
// GasConfig defines gas cost for each operation on KVStores
type GasConfig struct {
HasCost Gas
DeleteCost Gas
2018-07-26 18:24:18 -07:00
ReadCostFlat Gas
ReadCostPerByte Gas
WriteCostFlat Gas
WriteCostPerByte Gas
ValueCostPerByte Gas
IterNextCostFlat Gas
2018-07-26 18:24:18 -07:00
}
// KVGasConfig returns a default gas config for KVStores.
func KVGasConfig() GasConfig {
2018-07-26 18:24:18 -07:00
return GasConfig{
HasCost: 10,
DeleteCost: 10,
2018-07-26 18:24:18 -07:00
ReadCostFlat: 10,
ReadCostPerByte: 1,
WriteCostFlat: 10,
WriteCostPerByte: 10,
ValueCostPerByte: 1,
IterNextCostFlat: 15,
2018-07-26 18:24:18 -07:00
}
}
// TransientGasConfig returns a default gas config for TransientStores.
2018-07-26 18:24:18 -07:00
func TransientGasConfig() GasConfig {
// TODO: define gasconfig for transient stores
return KVGasConfig()
2018-07-26 18:24:18 -07:00
}