forked from TrueCloudLab/neoneo-go
vm: implement (*VM).AddGas
Calculating interop prices can be tricky. It is more convenitent to burn gas inside interops where necessary parameters are popped.
This commit is contained in:
parent
df958caf93
commit
7256efd1ed
4 changed files with 21 additions and 0 deletions
|
@ -11,6 +11,9 @@ import (
|
|||
// of 0.001 GAS = Fixed8(10^5).
|
||||
const interopGasRatio = 100000
|
||||
|
||||
// StoragePrice is a price for storing 1 byte of storage.
|
||||
const StoragePrice = 100000
|
||||
|
||||
// getPrice returns a price for executing op with the provided parameter.
|
||||
// Some SYSCALLs have variable price depending on their arguments.
|
||||
func getPrice(v *vm.VM, op opcode.Opcode, parameter []byte) util.Fixed8 {
|
||||
|
|
|
@ -11,6 +11,7 @@ import (
|
|||
"github.com/nspcc-dev/neo-go/pkg/io"
|
||||
"github.com/nspcc-dev/neo-go/pkg/smartcontract/manifest"
|
||||
"github.com/nspcc-dev/neo-go/pkg/smartcontract/trigger"
|
||||
"github.com/nspcc-dev/neo-go/pkg/util"
|
||||
"github.com/nspcc-dev/neo-go/pkg/vm"
|
||||
"github.com/nspcc-dev/neo-go/pkg/vm/stackitem"
|
||||
)
|
||||
|
@ -73,6 +74,9 @@ func createContractStateFromVM(ic *interop.Context, v *vm.VM) (*state.Contract,
|
|||
if len(manifestBytes) > manifest.MaxManifestSize {
|
||||
return nil, errors.New("manifest is too big")
|
||||
}
|
||||
if !v.AddGas(util.Fixed8(StoragePrice * (len(script) + len(manifestBytes)))) {
|
||||
return nil, errors.New("gas limit exceeded")
|
||||
}
|
||||
var m manifest.Manifest
|
||||
r := io.NewBinReaderFromBuf(manifestBytes)
|
||||
m.DecodeBinary(r)
|
||||
|
|
|
@ -136,6 +136,12 @@ func (v *VM) SetGasLimit(max util.Fixed8) {
|
|||
v.gasLimit = max
|
||||
}
|
||||
|
||||
// AddGas consumes specified amount of gas. It returns true iff gas limit wasn't exceeded.
|
||||
func (v *VM) AddGas(gas util.Fixed8) bool {
|
||||
v.gasConsumed += gas
|
||||
return v.gasLimit == 0 || v.gasConsumed <= v.gasLimit
|
||||
}
|
||||
|
||||
// Estack returns the evaluation stack so interop hooks can utilize this.
|
||||
func (v *VM) Estack() *Stack {
|
||||
return v.estack
|
||||
|
|
|
@ -98,6 +98,14 @@ func TestVM_SetPriceGetter(t *testing.T) {
|
|||
})
|
||||
}
|
||||
|
||||
func TestAddGas(t *testing.T) {
|
||||
v := New()
|
||||
v.SetGasLimit(10)
|
||||
require.True(t, v.AddGas(5))
|
||||
require.True(t, v.AddGas(5))
|
||||
require.False(t, v.AddGas(5))
|
||||
}
|
||||
|
||||
func TestBytesToPublicKey(t *testing.T) {
|
||||
v := New()
|
||||
cache := v.GetPublicKeys()
|
||||
|
|
Loading…
Reference in a new issue