vm: do not increment invocation counter in Call

Everywhere it matters (and that's callExFromNative() now) it's incremented
already, so when we're doing Call() at the same time (and it's done to invoke
`_initialize` method) we're effectively double-incrementing it.
This commit is contained in:
Roman Khimov 2021-11-19 17:02:53 +03:00
parent a577d40de9
commit 7b713762be
2 changed files with 22 additions and 6 deletions

View file

@ -229,21 +229,31 @@ func TestRuntimeGetNotifications(t *testing.T) {
}
func TestRuntimeGetInvocationCounter(t *testing.T) {
v, ic, _ := createVM(t)
v, ic, bc := createVM(t)
cs, _ := getTestContractState(bc)
require.NoError(t, bc.contracts.Management.PutContractState(ic.DAO, cs))
ic.VM.Invocations[hash.Hash160([]byte{2})] = 42
t.Run("No invocations", func(t *testing.T) {
v.LoadScript([]byte{1})
v.Load([]byte{1})
// do not return an error in this case.
require.NoError(t, runtime.GetInvocationCounter(ic))
require.EqualValues(t, 1, v.Estack().Pop().BigInt().Int64())
})
t.Run("NonZero", func(t *testing.T) {
v.LoadScript([]byte{2})
v.Load([]byte{2})
require.NoError(t, runtime.GetInvocationCounter(ic))
require.EqualValues(t, 42, v.Estack().Pop().BigInt().Int64())
})
t.Run("Contract", func(t *testing.T) {
w := io.NewBufBinWriter()
emit.AppCall(w.BinWriter, cs.Hash, "invocCounter", callflag.All)
v.LoadWithFlags(w.Bytes(), callflag.All)
require.NoError(t, v.Run())
require.EqualValues(t, 1, v.Estack().Pop().BigInt().Int64())
})
}
func TestStoragePut(t *testing.T) {
@ -756,6 +766,9 @@ func getTestContractState(bc *Blockchain) (*state.Contract, *state.Contract) {
burnGasOff := w.Len()
emit.Syscall(w.BinWriter, interopnames.SystemRuntimeBurnGas)
emit.Opcodes(w.BinWriter, opcode.RET)
invocCounterOff := w.Len()
emit.Syscall(w.BinWriter, interopnames.SystemRuntimeGetInvocationCounter)
emit.Opcodes(w.BinWriter, opcode.RET)
script := w.Bytes()
h := hash.Hash160(script)
@ -925,6 +938,11 @@ func getTestContractState(bc *Blockchain) (*state.Contract, *state.Contract) {
},
ReturnType: smartcontract.VoidType,
},
{
Name: "invocCounter",
Offset: invocCounterOff,
ReturnType: smartcontract.IntegerType,
},
}
m.Permissions = make([]manifest.Permission, 2)
m.Permissions[0].Contract.Type = manifest.PermissionHash

View file

@ -1556,11 +1556,9 @@ func (v *VM) throw(item stackitem.Item) {
v.handleException()
}
// Call calls method by offset. It pushes new context to the invocation stack
// and increments invocation counter for the corresponding context script hash.
// Call calls method by offset using new execution context.
func (v *VM) Call(ctx *Context, offset int) {
v.call(ctx, offset)
v.Invocations[ctx.ScriptHash()]++
}
// call is an internal representation of Call, which does not