2018-05-07 10:48:12 -07:00
|
|
|
package types
|
|
|
|
|
2018-09-26 07:02:56 -07:00
|
|
|
// Gas consumption descriptors.
|
|
|
|
const (
|
|
|
|
GasIterNextCostFlatDesc = "IterNextFlat"
|
|
|
|
GasValuePerByteDesc = "ValuePerByte"
|
|
|
|
GasWritePerByteDesc = "WritePerByte"
|
|
|
|
GasReadPerByteDesc = "ReadPerByte"
|
|
|
|
GasWriteCostFlatDesc = "WriteFlat"
|
|
|
|
GasReadCostFlatDesc = "ReadFlat"
|
|
|
|
GasHasDesc = "Has"
|
|
|
|
GasDeleteDesc = "Delete"
|
|
|
|
)
|
|
|
|
|
|
|
|
var (
|
2018-08-31 02:03:43 -07:00
|
|
|
cachedKVGasConfig = KVGasConfig()
|
2018-09-26 07:02:56 -07:00
|
|
|
cachedTransientGasConfig = TransientGasConfig()
|
|
|
|
)
|
|
|
|
|
2018-05-07 12:49:11 -07:00
|
|
|
// Gas measured by the SDK
|
2018-05-07 11:49:34 -07:00
|
|
|
type Gas = int64
|
2018-05-07 10:48:12 -07:00
|
|
|
|
2018-09-26 07:02:56 -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
|
|
|
|
}
|
|
|
|
|
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 {
|
2018-05-07 11:49:34 -07:00
|
|
|
GasConsumed() Gas
|
2018-05-08 08:34:09 -07:00
|
|
|
ConsumeGas(amount Gas, descriptor string)
|
2018-05-07 10:48:12 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
type basicGasMeter struct {
|
|
|
|
limit Gas
|
|
|
|
consumed Gas
|
|
|
|
}
|
|
|
|
|
2018-09-26 07:02:56 -07:00
|
|
|
// 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,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-05-07 11:49:34 -07:00
|
|
|
func (g *basicGasMeter) GasConsumed() Gas {
|
|
|
|
return g.consumed
|
|
|
|
}
|
|
|
|
|
2018-05-08 08:34:09 -07:00
|
|
|
func (g *basicGasMeter) ConsumeGas(amount Gas, descriptor string) {
|
2018-05-07 10:48:12 -07:00
|
|
|
g.consumed += amount
|
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
|
|
|
|
|
|
|
type infiniteGasMeter struct {
|
|
|
|
consumed Gas
|
|
|
|
}
|
|
|
|
|
2018-09-26 07:02:56 -07:00
|
|
|
// 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) ConsumeGas(amount Gas, descriptor string) {
|
|
|
|
g.consumed += amount
|
|
|
|
}
|
2018-07-26 18:24:18 -07:00
|
|
|
|
|
|
|
// GasConfig defines gas cost for each operation on KVStores
|
|
|
|
type GasConfig struct {
|
|
|
|
HasCost Gas
|
2018-09-26 07:02:56 -07:00
|
|
|
DeleteCost Gas
|
2018-07-26 18:24:18 -07:00
|
|
|
ReadCostFlat Gas
|
|
|
|
ReadCostPerByte Gas
|
|
|
|
WriteCostFlat Gas
|
|
|
|
WriteCostPerByte Gas
|
|
|
|
ValueCostPerByte Gas
|
2018-09-26 07:02:56 -07:00
|
|
|
IterNextCostFlat Gas
|
2018-07-26 18:24:18 -07:00
|
|
|
}
|
|
|
|
|
2018-08-31 02:03:43 -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,
|
2018-09-26 07:02:56 -07:00
|
|
|
DeleteCost: 10,
|
2018-07-26 18:24:18 -07:00
|
|
|
ReadCostFlat: 10,
|
|
|
|
ReadCostPerByte: 1,
|
|
|
|
WriteCostFlat: 10,
|
|
|
|
WriteCostPerByte: 10,
|
|
|
|
ValueCostPerByte: 1,
|
2018-09-26 07:02:56 -07:00
|
|
|
IterNextCostFlat: 15,
|
2018-07-26 18:24:18 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-09-26 07:02:56 -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
|
2018-08-31 02:03:43 -07:00
|
|
|
return KVGasConfig()
|
2018-07-26 18:24:18 -07:00
|
|
|
}
|