diff --git a/pkg/core/interop/context.go b/pkg/core/interop/context.go index dd252d5a0..6768c5324 100644 --- a/pkg/core/interop/context.go +++ b/pkg/core/interop/context.go @@ -91,6 +91,7 @@ type MethodAndPrice struct { Func Method MD *manifest.Method CPUFee int64 + StorageFee int64 SyscallOffset int RequiredFlags callflag.CallFlag } diff --git a/pkg/core/native/interop.go b/pkg/core/native/interop.go index 72a2fca92..084a3f2de 100644 --- a/pkg/core/native/interop.go +++ b/pkg/core/native/interop.go @@ -34,7 +34,9 @@ func Call(ic *interop.Context) error { return fmt.Errorf("missing call flags for native %d `%s` operation call: %05b vs %05b", version, m.MD.Name, ic.VM.Context().GetCallFlags(), m.RequiredFlags) } - if !ic.VM.AddGas(m.CPUFee * ic.Chain.GetPolicer().GetBaseExecFee()) { + invokeFee := m.CPUFee*ic.Chain.GetPolicer().GetBaseExecFee() + + m.StorageFee*ic.Chain.GetPolicer().GetStoragePrice() + if !ic.VM.AddGas(invokeFee) { return errors.New("gas limit exceeded") } ctx := ic.VM.Context() diff --git a/pkg/core/native/name_service.go b/pkg/core/native/name_service.go index 40707836a..4edb45155 100644 --- a/pkg/core/native/name_service.go +++ b/pkg/core/native/name_service.go @@ -136,6 +136,7 @@ func newNameService() *NameService { manifest.NewParameter("name", smartcontract.StringType), manifest.NewParameter("admin", smartcontract.Hash160Type)) md = newMethodAndPrice(n.setAdmin, 1<<15, callflag.States) + md.StorageFee = 20 n.AddMethod(md, desc) desc = newDescriptor("setRecord", smartcontract.VoidType, @@ -143,6 +144,7 @@ func newNameService() *NameService { manifest.NewParameter("type", smartcontract.IntegerType), manifest.NewParameter("data", smartcontract.StringType)) md = newMethodAndPrice(n.setRecord, 1<<15, callflag.States) + md.StorageFee = 200 n.AddMethod(md, desc) desc = newDescriptor("getRecord", smartcontract.StringType, diff --git a/pkg/core/native/native_nep17.go b/pkg/core/native/native_nep17.go index 93e75a654..2d3cde642 100644 --- a/pkg/core/native/native_nep17.go +++ b/pkg/core/native/native_nep17.go @@ -72,6 +72,7 @@ func newNEP17Native(name string, id int32) *nep17TokenNative { append(transferParams, manifest.NewParameter("data", smartcontract.AnyType))..., ) md = newMethodAndPrice(n.Transfer, 1<<17, callflag.States|callflag.AllowCall|callflag.AllowNotify) + md.StorageFee = 50 n.AddMethod(md, desc) n.AddEvent("Transfer", transferParams...) diff --git a/pkg/core/native/nonfungible.go b/pkg/core/native/nonfungible.go index ccf012c6f..49846e313 100644 --- a/pkg/core/native/nonfungible.go +++ b/pkg/core/native/nonfungible.go @@ -108,6 +108,7 @@ func newNonFungible(name string, id int32, symbol string, decimals byte) *nonfun manifest.NewParameter("to", smartcontract.Hash160Type), manifest.NewParameter("tokenId", smartcontract.ByteArrayType)) md = newMethodAndPrice(n.transfer, 1<<17, callflag.States|callflag.AllowNotify) + md.StorageFee = 50 n.AddMethod(md, desc) n.AddEvent("Transfer", diff --git a/pkg/core/native_contract_test.go b/pkg/core/native_contract_test.go index 77e5b01eb..358641c52 100644 --- a/pkg/core/native_contract_test.go +++ b/pkg/core/native_contract_test.go @@ -56,7 +56,10 @@ func (bc *Blockchain) registerNative(c interop.Contract) { bc.contracts.Contracts = append(bc.contracts.Contracts, c) } -const testSumCPUFee = 1 << 15 // same as contract.Call +const ( + testSumCPUFee = 1 << 15 // same as contract.Call + testSumStorageFee = 200 +) func newTestNative() *testNative { tn := &testNative{ @@ -77,6 +80,7 @@ func newTestNative() *testNative { md := &interop.MethodAndPrice{ Func: tn.sum, CPUFee: testSumCPUFee, + StorageFee: testSumStorageFee, RequiredFlags: callflag.NoneFlag, } tn.meta.AddMethod(md, desc) @@ -183,6 +187,7 @@ func TestNativeContract_Invoke(t *testing.T) { // System.Contract.Call + "sum" itself + opcodes for pushing arguments. price := int64(testSumCPUFee * chain.GetBaseExecFee() * 2) + price += testSumStorageFee * chain.GetStoragePrice() price += 3 * fee.Opcode(chain.GetBaseExecFee(), opcode.PUSHINT8) price += 2 * fee.Opcode(chain.GetBaseExecFee(), opcode.SYSCALL, opcode.PUSHDATA1, opcode.PUSHINT8) price += fee.Opcode(chain.GetBaseExecFee(), opcode.PACK)