native: take into account native contract method prices

Burn gas right before function invoke.
This commit is contained in:
Evgenii Stratonikov 2020-06-17 16:50:37 +03:00
parent 031fd93172
commit 3894b6db9f
2 changed files with 9 additions and 4 deletions

View file

@ -77,7 +77,6 @@ func (cs *Contracts) GetNativeInterop(ic *interop.Context) func(uint32) *vm.Inte
if c := cs.ByID(id); c != nil { if c := cs.ByID(id); c != nil {
return &vm.InteropFuncPrice{ return &vm.InteropFuncPrice{
Func: getNativeInterop(ic, c), Func: getNativeInterop(ic, c),
Price: 0, // TODO price func
} }
} }
return nil return nil
@ -100,6 +99,9 @@ func getNativeInterop(ic *interop.Context, c interop.Contract) func(v *vm.VM) er
if !v.Context().GetCallFlags().Has(m.RequiredFlags) { if !v.Context().GetCallFlags().Has(m.RequiredFlags) {
return errors.New("missing call flags") return errors.New("missing call flags")
} }
if !v.AddGas(util.Fixed8(m.Price)) {
return errors.New("gas limit exceeded")
}
result := m.Func(ic, args) result := m.Func(ic, args)
v.Estack().PushVal(result) v.Estack().PushVal(result)
return nil return nil

View file

@ -47,6 +47,8 @@ func (bc *Blockchain) registerNative(c interop.Contract) {
bc.contracts.Contracts = append(bc.contracts.Contracts, c) bc.contracts.Contracts = append(bc.contracts.Contracts, c)
} }
const testSumPrice = 1000000
func newTestNative() *testNative { func newTestNative() *testNative {
tn := &testNative{ tn := &testNative{
meta: *interop.NewContractMD("Test.Native.Sum"), meta: *interop.NewContractMD("Test.Native.Sum"),
@ -62,7 +64,7 @@ func newTestNative() *testNative {
} }
md := &interop.MethodAndPrice{ md := &interop.MethodAndPrice{
Func: tn.sum, Func: tn.sum,
Price: 1, Price: testSumPrice,
RequiredFlags: smartcontract.NoneFlag, RequiredFlags: smartcontract.NoneFlag,
} }
tn.meta.AddMethod(md, desc, true) tn.meta.AddMethod(md, desc, true)
@ -99,7 +101,8 @@ func TestNativeContract_Invoke(t *testing.T) {
w := io.NewBufBinWriter() w := io.NewBufBinWriter()
emit.AppCallWithOperationAndArgs(w.BinWriter, tn.Metadata().Hash, "sum", int64(14), int64(28)) emit.AppCallWithOperationAndArgs(w.BinWriter, tn.Metadata().Hash, "sum", int64(14), int64(28))
script := w.Bytes() script := w.Bytes()
tx := transaction.New(chain.GetConfig().Magic, script, 0) // System.Contract.Call + "sum" itself + opcodes for pushing arguments (PACK is 7000)
tx := transaction.New(chain.GetConfig().Magic, script, testSumPrice*2+10000)
validUntil := chain.blockHeight + 1 validUntil := chain.blockHeight + 1
tx.ValidUntilBlock = validUntil tx.ValidUntilBlock = validUntil
require.NoError(t, addSender(tx)) require.NoError(t, addSender(tx))