vm: set GAS limit
Make it possible to set maximum amount of GAS which can be spent during execution.
This commit is contained in:
parent
0662a7e3c2
commit
c22d09adad
2 changed files with 25 additions and 1 deletions
10
pkg/vm/vm.go
10
pkg/vm/vm.go
|
@ -80,6 +80,7 @@ type VM struct {
|
||||||
size int
|
size int
|
||||||
|
|
||||||
gasConsumed util.Fixed8
|
gasConsumed util.Fixed8
|
||||||
|
gasLimit util.Fixed8
|
||||||
|
|
||||||
// Public keys cache.
|
// Public keys cache.
|
||||||
keys map[string]*keys.PublicKey
|
keys map[string]*keys.PublicKey
|
||||||
|
@ -130,6 +131,12 @@ func (v *VM) GasConsumed() util.Fixed8 {
|
||||||
return v.gasConsumed
|
return v.gasConsumed
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SetGasLimit sets maximum amount of gas which v can spent.
|
||||||
|
// If max <= 0, no limit is imposed.
|
||||||
|
func (v *VM) SetGasLimit(max util.Fixed8) {
|
||||||
|
v.gasLimit = max
|
||||||
|
}
|
||||||
|
|
||||||
// Estack returns the evaluation stack so interop hooks can utilize this.
|
// Estack returns the evaluation stack so interop hooks can utilize this.
|
||||||
func (v *VM) Estack() *Stack {
|
func (v *VM) Estack() *Stack {
|
||||||
return v.estack
|
return v.estack
|
||||||
|
@ -483,6 +490,9 @@ func (v *VM) execute(ctx *Context, op opcode.Opcode, parameter []byte) (err erro
|
||||||
|
|
||||||
if v.getPrice != nil && ctx.ip < len(ctx.prog) {
|
if v.getPrice != nil && ctx.ip < len(ctx.prog) {
|
||||||
v.gasConsumed += v.getPrice(v, op, parameter)
|
v.gasConsumed += v.getPrice(v, op, parameter)
|
||||||
|
if v.gasLimit > 0 && v.gasConsumed > v.gasLimit {
|
||||||
|
panic("gas limit is exceeded")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if op >= opcode.PUSHBYTES1 && op <= opcode.PUSHBYTES75 {
|
if op >= opcode.PUSHBYTES1 && op <= opcode.PUSHBYTES75 {
|
||||||
|
|
|
@ -92,7 +92,21 @@ func TestVM_SetPriceGetter(t *testing.T) {
|
||||||
v.Load(prog)
|
v.Load(prog)
|
||||||
runVM(t, v)
|
runVM(t, v)
|
||||||
|
|
||||||
require.EqualValues(t, 9, v.gasConsumed)
|
require.EqualValues(t, 9, v.GasConsumed())
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("with sufficient gas limit", func(t *testing.T) {
|
||||||
|
v.Load(prog)
|
||||||
|
v.SetGasLimit(9)
|
||||||
|
runVM(t, v)
|
||||||
|
|
||||||
|
require.EqualValues(t, 9, v.GasConsumed())
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("with small gas limit", func(t *testing.T) {
|
||||||
|
v.Load(prog)
|
||||||
|
v.SetGasLimit(8)
|
||||||
|
checkVMFailed(t, v)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue