From 1c0c331e25d25b978e6f548ff9df2345b2d4fcf7 Mon Sep 17 00:00:00 2001 From: Evgenii Stratonikov Date: Tue, 29 Dec 2020 13:44:07 +0300 Subject: [PATCH] core: update `System.Contract.Call` syscall 1. Remove `System.Contract.CallEx`. 2. Extend number of parameters. 3. Add return value count to `VM.Context`. --- cli/smartcontract/smart_contract.go | 5 ++- cli/testdata/chain50x2.acc | Bin 45775 -> 45874 bytes cli/testdata/deploy/main.go | 2 +- cli/wallet/validator.go | 5 ++- examples/timer/timer.go | 6 +-- internal/testchain/transaction.go | 5 ++- pkg/compiler/codegen.go | 9 +---- pkg/compiler/interop_test.go | 14 +++---- pkg/compiler/syscall.go | 1 - pkg/consensus/consensus_test.go | 9 +++-- pkg/core/blockchain.go | 2 - pkg/core/blockchain_test.go | 7 ++-- pkg/core/helper_test.go | 11 +++--- pkg/core/interop/contract/call.go | 50 +++++++++++-------------- pkg/core/interop/interopnames/names.go | 2 - pkg/core/interop_system_test.go | 18 +++++---- pkg/core/interops.go | 2 - pkg/core/native/interop.go | 6 ++- pkg/core/native/management.go | 11 +++--- pkg/core/native/native_nep17.go | 3 +- pkg/core/native/notary.go | 3 +- pkg/core/native/oracle.go | 4 +- pkg/core/native_contract_test.go | 16 +++++--- pkg/core/native_designate_test.go | 4 +- pkg/core/native_neo_test.go | 7 ++-- pkg/core/native_notary_test.go | 4 +- pkg/core/native_oracle_test.go | 2 + pkg/interop/contract/contract.go | 12 +----- pkg/rpc/client/nep17.go | 5 ++- pkg/rpc/request/txBuilder.go | 5 ++- pkg/rpc/request/tx_builder_test.go | 30 +++++++-------- pkg/rpc/server/server.go | 13 ++----- pkg/rpc/server/server_test.go | 4 +- pkg/rpc/server/testdata/testblocks.acc | Bin 7656 -> 7665 bytes pkg/vm/context.go | 15 +++++++- pkg/vm/emit/emit.go | 14 ++++--- pkg/vm/vm.go | 32 ++++++++-------- scripts/gendump/main.go | 3 +- 38 files changed, 170 insertions(+), 171 deletions(-) diff --git a/cli/smartcontract/smart_contract.go b/cli/smartcontract/smart_contract.go index c18bdb40b..681949158 100644 --- a/cli/smartcontract/smart_contract.go +++ b/cli/smartcontract/smart_contract.go @@ -24,6 +24,7 @@ import ( "github.com/nspcc-dev/neo-go/pkg/io" "github.com/nspcc-dev/neo-go/pkg/rpc/response/result" "github.com/nspcc-dev/neo-go/pkg/smartcontract" + "github.com/nspcc-dev/neo-go/pkg/smartcontract/callflag" "github.com/nspcc-dev/neo-go/pkg/smartcontract/manifest" "github.com/nspcc-dev/neo-go/pkg/smartcontract/nef" "github.com/nspcc-dev/neo-go/pkg/util" @@ -821,7 +822,9 @@ func contractDeploy(ctx *cli.Context) error { return cli.NewExitError(fmt.Errorf("failed to get management contract's hash: %w", err), 1) } buf := io.NewBufBinWriter() - emit.AppCallWithOperationAndArgs(buf.BinWriter, mgmtHash, "deploy", f, manifestBytes) + emit.AppCall(buf.BinWriter, mgmtHash, "deploy", + callflag.ReadStates|callflag.WriteStates|callflag.AllowNotify, + f, manifestBytes) if buf.Err != nil { return cli.NewExitError(fmt.Errorf("failed to create deployment script: %w", buf.Err), 1) } diff --git a/cli/testdata/chain50x2.acc b/cli/testdata/chain50x2.acc index 21277914ffd155b123105788d40cfffa42e6e3f9..3c320249034f91fad7254b088a263a702973e234 100644 GIT binary patch literal 45874 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 R!x7&&payVOvwwk}?0=SKr=I`- literal 45775 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 L_;BfuSbFgv(9p7r diff --git a/cli/testdata/deploy/main.go b/cli/testdata/deploy/main.go index 525d932d9..dcadc30ea 100644 --- a/cli/testdata/deploy/main.go +++ b/cli/testdata/deploy/main.go @@ -36,7 +36,7 @@ func Fail() { func Update(script, manifest []byte) { ctx := storage.GetReadOnlyContext() mgmt := storage.Get(ctx, mgmtKey).(interop.Hash160) - contract.Call(mgmt, "update", script, manifest) + contract.Call(mgmt, "update", contract.All, script, manifest) } // GetValue returns stored value. diff --git a/cli/wallet/validator.go b/cli/wallet/validator.go index 3d8a337a0..dbc5f1d33 100644 --- a/cli/wallet/validator.go +++ b/cli/wallet/validator.go @@ -11,6 +11,7 @@ import ( "github.com/nspcc-dev/neo-go/pkg/crypto/keys" "github.com/nspcc-dev/neo-go/pkg/encoding/address" "github.com/nspcc-dev/neo-go/pkg/io" + "github.com/nspcc-dev/neo-go/pkg/smartcontract/callflag" "github.com/nspcc-dev/neo-go/pkg/util" "github.com/nspcc-dev/neo-go/pkg/vm/emit" "github.com/nspcc-dev/neo-go/pkg/vm/opcode" @@ -105,7 +106,7 @@ func handleCandidate(ctx *cli.Context, method string) error { return err } w := io.NewBufBinWriter() - emit.AppCallWithOperationAndArgs(w.BinWriter, neoContractHash, method, acc.PrivateKey().PublicKey().Bytes()) + emit.AppCall(w.BinWriter, neoContractHash, method, callflag.WriteStates, acc.PrivateKey().PublicKey().Bytes()) emit.Opcodes(w.BinWriter, opcode.ASSERT) tx, err := c.CreateTxFromScript(w.Bytes(), acc, -1, int64(gas), transaction.Signer{ Account: acc.Contract.ScriptHash(), @@ -167,7 +168,7 @@ func handleVote(ctx *cli.Context) error { return cli.NewExitError(err, 1) } w := io.NewBufBinWriter() - emit.AppCallWithOperationAndArgs(w.BinWriter, neoContractHash, "vote", addr.BytesBE(), pubArg) + emit.AppCall(w.BinWriter, neoContractHash, "vote", callflag.WriteStates, addr.BytesBE(), pubArg) emit.Opcodes(w.BinWriter, opcode.ASSERT) tx, err := c.CreateTxFromScript(w.Bytes(), acc, -1, int64(gas), transaction.Signer{ diff --git a/examples/timer/timer.go b/examples/timer/timer.go index 1d58a20fe..91f52a3ef 100644 --- a/examples/timer/timer.go +++ b/examples/timer/timer.go @@ -46,7 +46,7 @@ func Migrate(script []byte, manifest []byte) bool { return false } mgmt := storage.Get(ctx, mgmtKey).(interop.Hash160) - contract.Call(mgmt, "update", script, manifest) + contract.Call(mgmt, "update", contract.All, script, manifest) runtime.Log("Contract updated.") return true } @@ -58,7 +58,7 @@ func Tick() bool { ticksLeft = ticksLeft.(int) - 1 if ticksLeft == 0 { runtime.Log("Fired!") - return contract.Call(runtime.GetExecutingScriptHash(), "selfDestroy").(bool) + return contract.Call(runtime.GetExecutingScriptHash(), "selfDestroy", contract.All).(bool) } storage.Put(ctx, ticksKey, ticksLeft) i := binary.Itoa(ticksLeft.(int), 10) @@ -73,7 +73,7 @@ func SelfDestroy() bool { return false } mgmt := storage.Get(ctx, mgmtKey).(interop.Hash160) - contract.Call(mgmt, "destroy") + contract.Call(mgmt, "destroy", contract.All) runtime.Log("Destroyed.") return true } diff --git a/internal/testchain/transaction.go b/internal/testchain/transaction.go index 302cbb694..e4400e74e 100644 --- a/internal/testchain/transaction.go +++ b/internal/testchain/transaction.go @@ -13,6 +13,7 @@ import ( "github.com/nspcc-dev/neo-go/pkg/core/state" "github.com/nspcc-dev/neo-go/pkg/core/transaction" "github.com/nspcc-dev/neo-go/pkg/io" + "github.com/nspcc-dev/neo-go/pkg/smartcontract/callflag" "github.com/nspcc-dev/neo-go/pkg/smartcontract/nef" "github.com/nspcc-dev/neo-go/pkg/util" "github.com/nspcc-dev/neo-go/pkg/vm/emit" @@ -28,7 +29,7 @@ var ( func NewTransferFromOwner(bc blockchainer.Blockchainer, contractHash, to util.Uint160, amount int64, nonce, validUntil uint32) (*transaction.Transaction, error) { w := io.NewBufBinWriter() - emit.AppCallWithOperationAndArgs(w.BinWriter, contractHash, "transfer", ownerHash, to, amount, nil) + emit.AppCall(w.BinWriter, contractHash, "transfer", callflag.All, ownerHash, to, amount, nil) emit.Opcodes(w.BinWriter, opcode.ASSERT) if w.Err != nil { return nil, w.Err @@ -76,7 +77,7 @@ func NewDeployTx(bc blockchainer.Blockchainer, name string, sender util.Uint160, return nil, util.Uint160{}, err } buf := io.NewBufBinWriter() - emit.AppCallWithOperationAndArgs(buf.BinWriter, bc.ManagementContractHash(), "deploy", neb, rawManifest) + emit.AppCall(buf.BinWriter, bc.ManagementContractHash(), "deploy", callflag.All, neb, rawManifest) if buf.Err != nil { return nil, util.Uint160{}, buf.Err } diff --git a/pkg/compiler/codegen.go b/pkg/compiler/codegen.go index f10e5e440..d62474aef 100644 --- a/pkg/compiler/codegen.go +++ b/pkg/compiler/codegen.go @@ -866,14 +866,7 @@ func (c *codegen) Visit(node ast.Node) ast.Visitor { emit.Opcodes(c.prog.BinWriter, opcode.PACK) numArgs -= varSize - 1 } - // CallFlag in CallEx interop should be the last argument - // but this can't be reflected in signature due to varargs. - // It is first in compiler interop though, thus we just need to reverse 1 values less. - if f != nil && isSyscall(f) && f.pkg.Name() == "contract" && f.name == "CallEx" { - c.emitReverse(numArgs - 1) - } else { - c.emitReverse(numArgs) - } + c.emitReverse(numArgs) } // Check builtin first to avoid nil pointer on funcScope! diff --git a/pkg/compiler/interop_test.go b/pkg/compiler/interop_test.go index 0cd5cac5c..cb0504e07 100644 --- a/pkg/compiler/interop_test.go +++ b/pkg/compiler/interop_test.go @@ -150,7 +150,7 @@ func TestAppCall(t *testing.T) { return a + n } func CallInner() int { - return contract.Call(%s, "get42").(int) + return contract.Call(%s, "get42", contract.All).(int) }` srcInner = fmt.Sprintf(srcInner, fmt.Sprintf("%#v", cinterop.Hash160(barH.BytesBE()))) @@ -222,7 +222,7 @@ func TestAppCall(t *testing.T) { func Main() []byte { x := []byte{1, 2} y := []byte{3, 4} - result := contract.Call([]byte(scriptHash), "append", x, y) + result := contract.Call([]byte(scriptHash), "append", contract.All, x, y) return result.([]byte) } ` @@ -241,7 +241,7 @@ func TestAppCall(t *testing.T) { x := []byte{1, 2} y := []byte{3, 4} var addr = []byte(` + fmt.Sprintf("%#v", string(ih.BytesBE())) + `) - result := contract.Call(addr, "append", x, y) + result := contract.Call(addr, "append", contract.All, x, y) return result.([]byte) } ` @@ -257,7 +257,7 @@ func TestAppCall(t *testing.T) { import "github.com/nspcc-dev/neo-go/pkg/interop/contract" func Main() int { var addr = []byte(` + fmt.Sprintf("%#v", string(ih.BytesBE())) + `) - result := contract.Call(addr, "add3", 39) + result := contract.Call(addr, "add3", contract.All, 39) return result.(int) }` @@ -272,7 +272,7 @@ func TestAppCall(t *testing.T) { import ee "github.com/nspcc-dev/neo-go/pkg/interop/contract" func Main() int { var addr = []byte(` + fmt.Sprintf("%#v", string(ih.BytesBE())) + `) - result := ee.Call(addr, "add3", 39) + result := ee.Call(addr, "add3", ee.All, 39) return result.(int) }` v := spawnVM(t, ic, src) @@ -288,7 +288,7 @@ func getAppCallScript(h string) string { func Main() []byte { x := []byte{1, 2} y := []byte{3, 4} - result := contract.Call(` + h + `, "append", x, y) + result := contract.Call(` + h + `, "append", contract.All, x, y) return result.([]byte) } ` @@ -298,7 +298,7 @@ func getCallExScript(h string, flags string) string { return `package foo import "github.com/nspcc-dev/neo-go/pkg/interop/contract" func Main() int { - result := contract.CallEx(` + flags + `, ` + h + `, "callInner") + result := contract.Call(` + h + `, "callInner", ` + flags + `) return result.(int) }` } diff --git a/pkg/compiler/syscall.go b/pkg/compiler/syscall.go index abc5bebe0..c30617ab3 100644 --- a/pkg/compiler/syscall.go +++ b/pkg/compiler/syscall.go @@ -23,7 +23,6 @@ var syscalls = map[string]map[string]string{ }, "contract": { "Call": interopnames.SystemContractCall, - "CallEx": interopnames.SystemContractCallEx, "CreateStandardAccount": interopnames.SystemContractCreateStandardAccount, "IsStandard": interopnames.SystemContractIsStandard, "GetCallFlags": interopnames.SystemContractGetCallFlags, diff --git a/pkg/consensus/consensus_test.go b/pkg/consensus/consensus_test.go index 99ae07bb0..f67ef00e8 100644 --- a/pkg/consensus/consensus_test.go +++ b/pkg/consensus/consensus_test.go @@ -20,6 +20,7 @@ import ( "github.com/nspcc-dev/neo-go/pkg/crypto/keys" "github.com/nspcc-dev/neo-go/pkg/io" "github.com/nspcc-dev/neo-go/pkg/smartcontract" + "github.com/nspcc-dev/neo-go/pkg/smartcontract/callflag" "github.com/nspcc-dev/neo-go/pkg/util" "github.com/nspcc-dev/neo-go/pkg/vm/emit" "github.com/nspcc-dev/neo-go/pkg/vm/opcode" @@ -54,10 +55,10 @@ func initServiceNextConsensus(t *testing.T, newAcc *wallet.Account, offset uint3 // Transfer funds to new validator. w := io.NewBufBinWriter() - emit.AppCallWithOperationAndArgs(w.BinWriter, bc.GoverningTokenHash(), "transfer", + emit.AppCall(w.BinWriter, bc.GoverningTokenHash(), "transfer", callflag.All, acc.Contract.ScriptHash().BytesBE(), newPriv.GetScriptHash().BytesBE(), int64(native.NEOTotalSupply), nil) emit.Opcodes(w.BinWriter, opcode.ASSERT) - emit.AppCallWithOperationAndArgs(w.BinWriter, bc.UtilityTokenHash(), "transfer", + emit.AppCall(w.BinWriter, bc.UtilityTokenHash(), "transfer", callflag.All, acc.Contract.ScriptHash().BytesBE(), newPriv.GetScriptHash().BytesBE(), int64(1_000_000_000), nil) emit.Opcodes(w.BinWriter, opcode.ASSERT) require.NoError(t, w.Err) @@ -74,7 +75,7 @@ func initServiceNextConsensus(t *testing.T, newAcc *wallet.Account, offset uint3 // Register new candidate. w.Reset() - emit.AppCallWithOperationAndArgs(w.BinWriter, bc.GoverningTokenHash(), "registerCandidate", newPriv.PublicKey().Bytes()) + emit.AppCall(w.BinWriter, bc.GoverningTokenHash(), "registerCandidate", callflag.All, newPriv.PublicKey().Bytes()) require.NoError(t, w.Err) tx = transaction.New(netmode.UnitTestNet, w.Bytes(), 20_000_000) @@ -92,7 +93,7 @@ func initServiceNextConsensus(t *testing.T, newAcc *wallet.Account, offset uint3 // Vote for new candidate. w.Reset() - emit.AppCallWithOperationAndArgs(w.BinWriter, bc.GoverningTokenHash(), "vote", + emit.AppCall(w.BinWriter, bc.GoverningTokenHash(), "vote", callflag.All, newPriv.GetScriptHash(), newPriv.PublicKey().Bytes()) emit.Opcodes(w.BinWriter, opcode.ASSERT) require.NoError(t, w.Err) diff --git a/pkg/core/blockchain.go b/pkg/core/blockchain.go index 30b3a1a4a..e4fa6b0f2 100644 --- a/pkg/core/blockchain.go +++ b/pkg/core/blockchain.go @@ -33,7 +33,6 @@ import ( "github.com/nspcc-dev/neo-go/pkg/util" "github.com/nspcc-dev/neo-go/pkg/vm" "github.com/nspcc-dev/neo-go/pkg/vm/emit" - "github.com/nspcc-dev/neo-go/pkg/vm/opcode" "github.com/nspcc-dev/neo-go/pkg/vm/stackitem" "go.uber.org/zap" ) @@ -1675,7 +1674,6 @@ func (bc *Blockchain) initVerificationVM(ic *interop.Context, hash util.Uint160, if cs.ID <= 0 { w := io.NewBufBinWriter() - emit.Opcodes(w.BinWriter, opcode.DEPTH, opcode.PACK) emit.String(w.BinWriter, manifest.MethodVerify) if w.Err != nil { return w.Err diff --git a/pkg/core/blockchain_test.go b/pkg/core/blockchain_test.go index a7e40b18b..a3a09c7a7 100644 --- a/pkg/core/blockchain_test.go +++ b/pkg/core/blockchain_test.go @@ -28,6 +28,7 @@ import ( "github.com/nspcc-dev/neo-go/pkg/crypto/keys" "github.com/nspcc-dev/neo-go/pkg/io" "github.com/nspcc-dev/neo-go/pkg/smartcontract" + "github.com/nspcc-dev/neo-go/pkg/smartcontract/callflag" "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" @@ -272,12 +273,12 @@ func TestVerifyTx(t *testing.T) { if sc.Equals(gasHash) { amount = 1_000_000_000 } - emit.AppCallWithOperationAndArgs(w.BinWriter, sc, "transfer", + emit.AppCall(w.BinWriter, sc, "transfer", callflag.All, neoOwner, a.Contract.ScriptHash(), amount, nil) emit.Opcodes(w.BinWriter, opcode.ASSERT) } } - emit.AppCallWithOperationAndArgs(w.BinWriter, gasHash, "transfer", + emit.AppCall(w.BinWriter, gasHash, "transfer", callflag.All, neoOwner, testchain.CommitteeScriptHash(), int64(1_000_000_000), nil) emit.Opcodes(w.BinWriter, opcode.ASSERT) require.NoError(t, w.Err) @@ -973,7 +974,7 @@ func TestVerifyTx(t *testing.T) { transaction.NotaryServiceFeePerKey + // fee for Notary attribute fee.Opcode(bc.GetBaseExecFee(), // Notary verification script opcode.PUSHDATA1, opcode.RET, // invocation script - opcode.DEPTH, opcode.PACK, opcode.PUSHDATA1, opcode.RET, // arguments for native verification call + opcode.PUSHDATA1, opcode.RET, // arguments for native verification call opcode.PUSHDATA1, opcode.SYSCALL, opcode.RET) + // Neo.Native.Call native.NotaryVerificationPrice // Notary witness verification price tx.Scripts = []transaction.Witness{ diff --git a/pkg/core/helper_test.go b/pkg/core/helper_test.go index dca80e2c0..9cb78bb74 100644 --- a/pkg/core/helper_test.go +++ b/pkg/core/helper_test.go @@ -25,6 +25,7 @@ import ( "github.com/nspcc-dev/neo-go/pkg/encoding/fixedn" "github.com/nspcc-dev/neo-go/pkg/io" "github.com/nspcc-dev/neo-go/pkg/smartcontract" + "github.com/nspcc-dev/neo-go/pkg/smartcontract/callflag" "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" @@ -298,7 +299,7 @@ func initBasicChain(t *testing.T, bc *Blockchain) { // Now invoke this contract. script := io.NewBufBinWriter() - emit.AppCallWithOperationAndArgs(script.BinWriter, cHash, "putValue", "testkey", "testvalue") + emit.AppCall(script.BinWriter, cHash, "putValue", callflag.All, "testkey", "testvalue") txInv := transaction.New(testchain.Network(), script.Bytes(), 1*native.GASFactor) txInv.Nonce = getNextNonce() @@ -328,7 +329,7 @@ func initBasicChain(t *testing.T, bc *Blockchain) { require.NoError(t, bc.AddBlock(b)) w := io.NewBufBinWriter() - emit.AppCallWithOperationAndArgs(w.BinWriter, cHash, "init") + emit.AppCall(w.BinWriter, cHash, "init", callflag.All) initTx := transaction.New(testchain.Network(), w.Bytes(), 1*native.GASFactor) initTx.Nonce = getNextNonce() initTx.ValidUntilBlock = validUntilBlock @@ -383,7 +384,7 @@ func initBasicChain(t *testing.T, bc *Blockchain) { func newNEP17Transfer(sc, from, to util.Uint160, amount int64, additionalArgs ...interface{}) *transaction.Transaction { w := io.NewBufBinWriter() - emit.AppCallWithOperationAndArgs(w.BinWriter, sc, "transfer", from, to, amount, additionalArgs) + emit.AppCall(w.BinWriter, sc, "transfer", callflag.All, from, to, amount, additionalArgs) emit.Opcodes(w.BinWriter, opcode.ASSERT) script := w.Bytes() @@ -430,7 +431,7 @@ func addNetworkFee(bc *Blockchain, tx *transaction.Transaction, sender *wallet.A func prepareContractMethodInvoke(chain *Blockchain, sysfee int64, hash util.Uint160, method string, args ...interface{}) (*transaction.Transaction, error) { w := io.NewBufBinWriter() - emit.AppCallWithOperationAndArgs(w.BinWriter, hash, method, args...) + emit.AppCall(w.BinWriter, hash, method, callflag.All, args...) if w.Err != nil { return nil, w.Err } @@ -487,7 +488,7 @@ func invokeContractMethodBy(t *testing.T, chain *Blockchain, signer *wallet.Acco require.Equal(t, 0, len(res[0].Stack)) w := io.NewBufBinWriter() - emit.AppCallWithOperationAndArgs(w.BinWriter, hash, method, args...) + emit.AppCall(w.BinWriter, hash, method, callflag.All, args...) if w.Err != nil { return nil, w.Err } diff --git a/pkg/core/interop/contract/call.go b/pkg/core/interop/contract/call.go index 66eb9a028..d0b155544 100644 --- a/pkg/core/interop/contract/call.go +++ b/pkg/core/interop/contract/call.go @@ -7,6 +7,7 @@ import ( "github.com/nspcc-dev/neo-go/pkg/core/interop" "github.com/nspcc-dev/neo-go/pkg/core/state" + "github.com/nspcc-dev/neo-go/pkg/smartcontract" "github.com/nspcc-dev/neo-go/pkg/smartcontract/callflag" "github.com/nspcc-dev/neo-go/pkg/smartcontract/manifest" "github.com/nspcc-dev/neo-go/pkg/util" @@ -14,27 +15,19 @@ import ( "github.com/nspcc-dev/neo-go/pkg/vm/stackitem" ) -// Call calls a contract. +// Call calls a contract with flags. func Call(ic *interop.Context) error { h := ic.VM.Estack().Pop().Bytes() method := ic.VM.Estack().Pop().String() - args := ic.VM.Estack().Pop().Array() - return callExInternal(ic, h, method, args, callflag.All) -} - -// CallEx calls a contract with flags. -func CallEx(ic *interop.Context) error { - h := ic.VM.Estack().Pop().Bytes() - method := ic.VM.Estack().Pop().String() - args := ic.VM.Estack().Pop().Array() fs := callflag.CallFlag(int32(ic.VM.Estack().Pop().BigInt().Int64())) if fs&^callflag.All != 0 { return errors.New("call flags out of range") } - return callExInternal(ic, h, method, args, fs) + args := ic.VM.Estack().Pop().Array() + return callInternal(ic, h, method, fs, args) } -func callExInternal(ic *interop.Context, h []byte, name string, args []stackitem.Item, f callflag.CallFlag) error { +func callInternal(ic *interop.Context, h []byte, name string, f callflag.CallFlag, args []stackitem.Item) error { u, err := util.Uint160DecodeBytesBE(h) if err != nil { return errors.New("invalid contract hash") @@ -50,6 +43,10 @@ func callExInternal(ic *interop.Context, h []byte, name string, args []stackitem if md == nil { return errors.New("method not found") } + hasReturn := md.ReturnType != smartcontract.VoidType + if !hasReturn { + ic.VM.Estack().PushVal(stackitem.Null{}) + } if md.Safe { f &^= callflag.WriteStates } else if ctx := ic.VM.Context(); ctx != nil && ctx.IsDeployed() { @@ -60,18 +57,12 @@ func callExInternal(ic *interop.Context, h []byte, name string, args []stackitem } } } - return CallExInternal(ic, cs, name, args, f, vm.EnsureNotEmpty) -} - -// CallExInternal calls a contract with flags and can't be invoked directly by user. -func CallExInternal(ic *interop.Context, cs *state.Contract, - name string, args []stackitem.Item, f callflag.CallFlag, checkReturn vm.CheckReturnState) error { - return callExFromNative(ic, ic.VM.GetCurrentScriptHash(), cs, name, args, f, checkReturn) + return callExFromNative(ic, ic.VM.GetCurrentScriptHash(), cs, name, args, f, hasReturn) } // callExFromNative calls a contract with flags using provided calling hash. func callExFromNative(ic *interop.Context, caller util.Uint160, cs *state.Contract, - name string, args []stackitem.Item, f callflag.CallFlag, checkReturn vm.CheckReturnState) error { + name string, args []stackitem.Item, f callflag.CallFlag, hasReturn bool) error { md := cs.Manifest.ABI.GetMethod(name) if md == nil { return fmt.Errorf("method '%s' not found", name) @@ -82,7 +73,7 @@ func callExFromNative(ic *interop.Context, caller util.Uint160, cs *state.Contra } ic.VM.Invocations[cs.Hash]++ - ic.VM.LoadScriptWithCallingHash(caller, cs.NEF.Script, cs.Hash, ic.VM.Context().GetCallFlags()&f) + ic.VM.LoadScriptWithCallingHash(caller, cs.NEF.Script, cs.Hash, ic.VM.Context().GetCallFlags()&f, true, uint16(len(args))) var isNative bool for i := range ic.Natives { if ic.Natives[i].Metadata().Hash.Equals(cs.Hash) { @@ -90,17 +81,20 @@ func callExFromNative(ic *interop.Context, caller util.Uint160, cs *state.Contra break } } + for i := len(args) - 1; i >= 0; i-- { + ic.VM.Estack().PushVal(args[i]) + } if isNative { - ic.VM.Estack().PushVal(args) ic.VM.Estack().PushVal(name) } else { - for i := len(args) - 1; i >= 0; i-- { - ic.VM.Estack().PushVal(args[i]) - } // use Jump not Call here because context was loaded in LoadScript above. ic.VM.Jump(ic.VM.Context(), md.Offset) } - ic.VM.Context().CheckReturn = checkReturn + if hasReturn { + ic.VM.Context().RetCount = 1 + } else { + ic.VM.Context().RetCount = 0 + } md = cs.Manifest.ABI.GetMethod(manifest.MethodInit) if md != nil { @@ -114,9 +108,9 @@ func callExFromNative(ic *interop.Context, caller util.Uint160, cs *state.Contra var ErrNativeCall = errors.New("error during call from native") // CallFromNative performs synchronous call from native contract. -func CallFromNative(ic *interop.Context, caller util.Uint160, cs *state.Contract, method string, args []stackitem.Item, checkReturn vm.CheckReturnState) error { +func CallFromNative(ic *interop.Context, caller util.Uint160, cs *state.Contract, method string, args []stackitem.Item, hasReturn bool) error { startSize := ic.VM.Istack().Len() - if err := callExFromNative(ic, caller, cs, method, args, callflag.All, checkReturn); err != nil { + if err := callExFromNative(ic, caller, cs, method, args, callflag.All, hasReturn); err != nil { return err } diff --git a/pkg/core/interop/interopnames/names.go b/pkg/core/interop/interopnames/names.go index a96b8dee1..1d642cc9b 100644 --- a/pkg/core/interop/interopnames/names.go +++ b/pkg/core/interop/interopnames/names.go @@ -20,7 +20,6 @@ const ( SystemCallbackCreateFromSyscall = "System.Callback.CreateFromSyscall" SystemCallbackInvoke = "System.Callback.Invoke" SystemContractCall = "System.Contract.Call" - SystemContractCallEx = "System.Contract.CallEx" SystemContractCallNative = "System.Contract.CallNative" SystemContractCreateStandardAccount = "System.Contract.CreateStandardAccount" SystemContractIsStandard = "System.Contract.IsStandard" @@ -86,7 +85,6 @@ var names = []string{ SystemCallbackCreateFromSyscall, SystemCallbackInvoke, SystemContractCall, - SystemContractCallEx, SystemContractCallNative, SystemContractCreateStandardAccount, SystemContractIsStandard, diff --git a/pkg/core/interop_system_test.go b/pkg/core/interop_system_test.go index 19b3650f5..d4a333f58 100644 --- a/pkg/core/interop_system_test.go +++ b/pkg/core/interop_system_test.go @@ -502,13 +502,12 @@ func getTestContractState(bc *Blockchain) (*state.Contract, *state.Contract) { updateOff := w.Len() emit.Int(w.BinWriter, 2) emit.Opcodes(w.BinWriter, opcode.PACK) - emit.String(w.BinWriter, "update") - emit.AppCall(w.BinWriter, mgmtHash) + emit.AppCallNoArgs(w.BinWriter, mgmtHash, "update", callflag.All) + emit.Opcodes(w.BinWriter, opcode.DROP) emit.Opcodes(w.BinWriter, opcode.RET) destroyOff := w.Len() - emit.Opcodes(w.BinWriter, opcode.NEWARRAY0) - emit.String(w.BinWriter, "destroy") - emit.AppCall(w.BinWriter, mgmtHash) + emit.AppCall(w.BinWriter, mgmtHash, "destroy", callflag.All) + emit.Opcodes(w.BinWriter, opcode.DROP) emit.Opcodes(w.BinWriter, opcode.RET) invalidStackOff := w.Len() emit.Opcodes(w.BinWriter, opcode.NEWARRAY0, opcode.DUP, opcode.DUP, opcode.APPEND, opcode.NEWMAP) @@ -685,6 +684,7 @@ func TestContractCall(t *testing.T) { t.Run("Good", func(t *testing.T) { loadScript(ic, currScript, 42) ic.VM.Estack().PushVal(addArgs) + ic.VM.Estack().PushVal(callflag.All) ic.VM.Estack().PushVal("add") ic.VM.Estack().PushVal(h.BytesBE()) require.NoError(t, contract.Call(ic)) @@ -696,11 +696,11 @@ func TestContractCall(t *testing.T) { t.Run("CallExInvalidFlag", func(t *testing.T) { loadScript(ic, currScript, 42) - ic.VM.Estack().PushVal(byte(0xFF)) ic.VM.Estack().PushVal(addArgs) + ic.VM.Estack().PushVal(byte(0xFF)) ic.VM.Estack().PushVal("add") ic.VM.Estack().PushVal(h.BytesBE()) - require.Error(t, contract.CallEx(ic)) + require.Error(t, contract.Call(ic)) }) runInvalid := func(args ...interface{}) func(t *testing.T) { @@ -735,6 +735,7 @@ func TestContractCall(t *testing.T) { t.Run("Many", func(t *testing.T) { loadScript(ic, currScript, 42) ic.VM.Estack().PushVal(stackitem.NewArray(nil)) + ic.VM.Estack().PushVal(callflag.All) ic.VM.Estack().PushVal("invalidReturn") ic.VM.Estack().PushVal(h.BytesBE()) require.NoError(t, contract.Call(ic)) @@ -743,6 +744,7 @@ func TestContractCall(t *testing.T) { t.Run("Void", func(t *testing.T) { loadScript(ic, currScript, 42) ic.VM.Estack().PushVal(stackitem.NewArray(nil)) + ic.VM.Estack().PushVal(callflag.All) ic.VM.Estack().PushVal("justReturn") ic.VM.Estack().PushVal(h.BytesBE()) require.NoError(t, contract.Call(ic)) @@ -756,6 +758,7 @@ func TestContractCall(t *testing.T) { t.Run("IsolatedStack", func(t *testing.T) { loadScript(ic, currScript, 42) ic.VM.Estack().PushVal(stackitem.NewArray(nil)) + ic.VM.Estack().PushVal(callflag.All) ic.VM.Estack().PushVal("drop") ic.VM.Estack().PushVal(h.BytesBE()) require.NoError(t, contract.Call(ic)) @@ -767,6 +770,7 @@ func TestContractCall(t *testing.T) { loadScript(ic, currScript, 42) ic.VM.Estack().PushVal(stackitem.NewArray([]stackitem.Item{stackitem.Make(5)})) + ic.VM.Estack().PushVal(callflag.All) ic.VM.Estack().PushVal("add3") ic.VM.Estack().PushVal(h.BytesBE()) require.NoError(t, contract.Call(ic)) diff --git a/pkg/core/interops.go b/pkg/core/interops.go index 113a98af5..41cbb1f25 100644 --- a/pkg/core/interops.go +++ b/pkg/core/interops.go @@ -51,8 +51,6 @@ var systemInterops = []interop.Function{ {Name: interopnames.SystemBlockchainGetTransactionHeight, Func: bcGetTransactionHeight, Price: 1 << 15, RequiredFlags: callflag.ReadStates, ParamCount: 1}, {Name: interopnames.SystemContractCall, Func: contract.Call, Price: 1 << 15, - RequiredFlags: callflag.AllowCall, ParamCount: 3}, - {Name: interopnames.SystemContractCallEx, Func: contract.CallEx, Price: 1 << 15, RequiredFlags: callflag.AllowCall, ParamCount: 4}, {Name: interopnames.SystemContractCallNative, Func: native.Call, Price: 0, ParamCount: 1}, {Name: interopnames.SystemContractCreateStandardAccount, Func: contractCreateStandardAccount, Price: 1 << 8, ParamCount: 1}, diff --git a/pkg/core/native/interop.go b/pkg/core/native/interop.go index ef5e434de..ba4a613a1 100644 --- a/pkg/core/native/interop.go +++ b/pkg/core/native/interop.go @@ -7,6 +7,7 @@ import ( "github.com/nspcc-dev/neo-go/pkg/core/interop" "github.com/nspcc-dev/neo-go/pkg/smartcontract" "github.com/nspcc-dev/neo-go/pkg/smartcontract/trigger" + "github.com/nspcc-dev/neo-go/pkg/vm/stackitem" ) // Call calls specified native contract method. @@ -27,7 +28,6 @@ func Call(ic *interop.Context) error { return errors.New("it is not allowed to use Neo.Native.Call directly to call native contracts. System.Contract.Call should be used") } operation := ic.VM.Estack().Pop().String() - args := ic.VM.Estack().Pop().Array() m, ok := c.Metadata().Methods[operation] if !ok { return fmt.Errorf("method %s not found", operation) @@ -40,6 +40,10 @@ func Call(ic *interop.Context) error { return errors.New("gas limit exceeded") } ctx := ic.VM.Context() + args := make([]stackitem.Item, len(m.MD.Parameters)) + for i := range args { + args[i] = ic.VM.Estack().Pop().Item() + } result := m.Func(ic, args) if m.MD.ReturnType != smartcontract.VoidType { ctx.Estack().PushVal(result) diff --git a/pkg/core/native/management.go b/pkg/core/native/management.go index 2bacf4037..df9d7eaed 100644 --- a/pkg/core/native/management.go +++ b/pkg/core/native/management.go @@ -21,7 +21,6 @@ import ( "github.com/nspcc-dev/neo-go/pkg/smartcontract/manifest" "github.com/nspcc-dev/neo-go/pkg/smartcontract/nef" "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" ) @@ -222,7 +221,7 @@ func (m *Management) deploy(ic *interop.Context, args []stackitem.Item) stackite if err != nil { panic(err) } - callDeploy(ic, newcontract, false) + m.callDeploy(ic, newcontract, false) m.emitNotification(ic, contractDeployNotificationName, newcontract.Hash) return contractToStack(newcontract) } @@ -278,7 +277,7 @@ func (m *Management) update(ic *interop.Context, args []stackitem.Item) stackite if err != nil { panic(err) } - callDeploy(ic, contract, true) + m.callDeploy(ic, contract, true) m.emitNotification(ic, contractUpdateNotificationName, contract.Hash) return stackitem.Null{} } @@ -380,11 +379,11 @@ func (m *Management) setMinimumDeploymentFee(ic *interop.Context, args []stackit return stackitem.NewBool(true) } -func callDeploy(ic *interop.Context, cs *state.Contract, isUpdate bool) { +func (m *Management) callDeploy(ic *interop.Context, cs *state.Contract, isUpdate bool) { md := cs.Manifest.ABI.GetMethod(manifest.MethodDeploy) if md != nil { - err := contract.CallExInternal(ic, cs, manifest.MethodDeploy, - []stackitem.Item{stackitem.NewBool(isUpdate)}, callflag.All, vm.EnsureIsEmpty) + err := contract.CallFromNative(ic, m.Hash, cs, manifest.MethodDeploy, + []stackitem.Item{stackitem.NewBool(isUpdate)}, false) if err != nil { panic(err) } diff --git a/pkg/core/native/native_nep17.go b/pkg/core/native/native_nep17.go index 563b10ced..81dfa6493 100644 --- a/pkg/core/native/native_nep17.go +++ b/pkg/core/native/native_nep17.go @@ -15,7 +15,6 @@ import ( "github.com/nspcc-dev/neo-go/pkg/smartcontract/callflag" "github.com/nspcc-dev/neo-go/pkg/smartcontract/manifest" "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" ) @@ -144,7 +143,7 @@ func (c *nep17TokenNative) postTransfer(ic *interop.Context, from, to *util.Uint stackitem.NewBigInteger(amount), data, } - if err := contract.CallFromNative(ic, c.Hash, cs, manifest.MethodOnPayment, args, vm.EnsureIsEmpty); err != nil { + if err := contract.CallFromNative(ic, c.Hash, cs, manifest.MethodOnPayment, args, false); err != nil { panic(err) } } diff --git a/pkg/core/native/notary.go b/pkg/core/native/notary.go index 855413a4e..215169c44 100644 --- a/pkg/core/native/notary.go +++ b/pkg/core/native/notary.go @@ -20,7 +20,6 @@ import ( "github.com/nspcc-dev/neo-go/pkg/smartcontract/callflag" "github.com/nspcc-dev/neo-go/pkg/smartcontract/manifest" "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" ) @@ -277,7 +276,7 @@ func (n *Notary) withdraw(ic *interop.Context, args []stackitem.Item) stackitem. panic(fmt.Errorf("failed to get GAS contract state: %w", err)) } transferArgs := []stackitem.Item{stackitem.NewByteArray(n.Hash.BytesBE()), stackitem.NewByteArray(to.BytesBE()), stackitem.NewBigInteger(deposit.Amount), stackitem.Null{}} - err = contract.CallFromNative(ic, n.Hash, cs, "transfer", transferArgs, vm.EnsureNotEmpty) + err = contract.CallFromNative(ic, n.Hash, cs, "transfer", transferArgs, true) if err != nil { panic(fmt.Errorf("failed to transfer GAS from Notary account: %w", err)) } diff --git a/pkg/core/native/oracle.go b/pkg/core/native/oracle.go index dfb204ae8..ff6548088 100644 --- a/pkg/core/native/oracle.go +++ b/pkg/core/native/oracle.go @@ -23,7 +23,6 @@ import ( "github.com/nspcc-dev/neo-go/pkg/smartcontract/callflag" "github.com/nspcc-dev/neo-go/pkg/smartcontract/manifest" "github.com/nspcc-dev/neo-go/pkg/util" - "github.com/nspcc-dev/neo-go/pkg/vm" "github.com/nspcc-dev/neo-go/pkg/vm/emit" "github.com/nspcc-dev/neo-go/pkg/vm/opcode" "github.com/nspcc-dev/neo-go/pkg/vm/stackitem" @@ -57,6 +56,7 @@ func init() { w := io.NewBufBinWriter() emit.Int(w.BinWriter, 0) emit.Opcodes(w.BinWriter, opcode.NEWARRAY) + emit.Int(w.BinWriter, int64(callflag.All)) emit.String(w.BinWriter, "finish") emit.Bytes(w.BinWriter, h.BytesBE()) emit.Syscall(w.BinWriter, interopnames.SystemContractCall) @@ -239,7 +239,7 @@ func (o *Oracle) FinishInternal(ic *interop.Context) error { if err != nil { return err } - return contract.CallFromNative(ic, o.Hash, cs, req.CallbackMethod, args, vm.EnsureIsEmpty) + return contract.CallFromNative(ic, o.Hash, cs, req.CallbackMethod, args, false) } func (o *Oracle) request(ic *interop.Context, args []stackitem.Item) stackitem.Item { diff --git a/pkg/core/native_contract_test.go b/pkg/core/native_contract_test.go index 09d4bfc4f..865b48021 100644 --- a/pkg/core/native_contract_test.go +++ b/pkg/core/native_contract_test.go @@ -138,7 +138,7 @@ func toUint160(item stackitem.Item) util.Uint160 { return u } -func (tn *testNative) call(ic *interop.Context, args []stackitem.Item, checkReturn vm.CheckReturnState) { +func (tn *testNative) call(ic *interop.Context, args []stackitem.Item, hasReturn bool) { cs, err := ic.GetContract(toUint160(args[0])) if err != nil { panic(err) @@ -147,19 +147,19 @@ func (tn *testNative) call(ic *interop.Context, args []stackitem.Item, checkRetu if err != nil { panic(err) } - err = contract.CallFromNative(ic, tn.meta.Hash, cs, string(bs), args[2].Value().([]stackitem.Item), checkReturn) + err = contract.CallFromNative(ic, tn.meta.Hash, cs, string(bs), args[2].Value().([]stackitem.Item), hasReturn) if err != nil { panic(err) } } func (tn *testNative) callOtherContractNoReturn(ic *interop.Context, args []stackitem.Item) stackitem.Item { - tn.call(ic, args, vm.EnsureIsEmpty) + tn.call(ic, args, false) return stackitem.Null{} } func (tn *testNative) callOtherContractWithReturn(ic *interop.Context, args []stackitem.Item) stackitem.Item { - tn.call(ic, args, vm.EnsureNotEmpty) + tn.call(ic, args, true) bi := ic.VM.Estack().Pop().BigInt() return stackitem.Make(bi.Add(bi, big.NewInt(1))) } @@ -184,6 +184,7 @@ func TestNativeContract_Invoke(t *testing.T) { price += 3 * fee.Opcode(chain.GetBaseExecFee(), opcode.PUSHINT8, opcode.PUSHDATA1) price += 2 * fee.Opcode(chain.GetBaseExecFee(), opcode.SYSCALL) price += fee.Opcode(chain.GetBaseExecFee(), opcode.PACK) + price += fee.Opcode(chain.GetBaseExecFee(), opcode.PUSHINT8) res, err := invokeContractMethod(chain, price, tn.Metadata().Hash, "sum", int64(14), int64(28)) require.NoError(t, err) checkResult(t, res, stackitem.Make(42)) @@ -222,7 +223,8 @@ func TestNativeContract_InvokeInternal(t *testing.T) { t.Run("fail, bad current script hash", func(t *testing.T) { v.LoadScriptWithHash([]byte{1}, util.Uint160{1, 2, 3}, callflag.All) - v.Estack().PushVal(stackitem.NewArray([]stackitem.Item{stackitem.NewBigInteger(big.NewInt(14)), stackitem.NewBigInteger(big.NewInt(28))})) + v.Estack().PushVal(14) + v.Estack().PushVal(28) v.Estack().PushVal("sum") v.Estack().PushVal(tn.Metadata().Name) @@ -232,7 +234,8 @@ func TestNativeContract_InvokeInternal(t *testing.T) { t.Run("success", func(t *testing.T) { v.LoadScriptWithHash([]byte{1}, tn.Metadata().Hash, callflag.All) - v.Estack().PushVal(stackitem.NewArray([]stackitem.Item{stackitem.NewBigInteger(big.NewInt(14)), stackitem.NewBigInteger(big.NewInt(28))})) + v.Estack().PushVal(14) + v.Estack().PushVal(28) v.Estack().PushVal("sum") v.Estack().PushVal(tn.Metadata().Name) @@ -273,6 +276,7 @@ func TestNativeContract_InvokeOtherContract(t *testing.T) { res, err := invokeContractMethod(chain, testSumPrice*4+10000, tn.Metadata().Hash, "callOtherContractNoReturn", cs.Hash, "justReturn", []interface{}{}) require.NoError(t, err) drainTN(t) + require.Equal(t, vm.HaltState, res.VMState, res.FaultException) checkResult(t, res, stackitem.Null{}) // simple call is done with EnsureNotEmpty }) t.Run("non-native, with return", func(t *testing.T) { diff --git a/pkg/core/native_designate_test.go b/pkg/core/native_designate_test.go index b381a923f..7b0c0b6c1 100644 --- a/pkg/core/native_designate_test.go +++ b/pkg/core/native_designate_test.go @@ -11,6 +11,7 @@ import ( "github.com/nspcc-dev/neo-go/pkg/core/transaction" "github.com/nspcc-dev/neo-go/pkg/crypto/keys" "github.com/nspcc-dev/neo-go/pkg/io" + "github.com/nspcc-dev/neo-go/pkg/smartcontract/callflag" "github.com/nspcc-dev/neo-go/pkg/smartcontract/trigger" "github.com/nspcc-dev/neo-go/pkg/vm" "github.com/nspcc-dev/neo-go/pkg/vm/emit" @@ -29,8 +30,7 @@ func (bc *Blockchain) setNodesByRole(t *testing.T, ok bool, r native.Role, nodes emit.Int(w.BinWriter, int64(r)) emit.Int(w.BinWriter, 2) emit.Opcodes(w.BinWriter, opcode.PACK) - emit.String(w.BinWriter, "designateAsRole") - emit.AppCall(w.BinWriter, bc.contracts.Designate.Hash) + emit.AppCallNoArgs(w.BinWriter, bc.contracts.Designate.Hash, "designateAsRole", callflag.All) require.NoError(t, w.Err) tx := transaction.New(netmode.UnitTestNet, w.Bytes(), 0) tx.NetworkFee = 10_000_000 diff --git a/pkg/core/native_neo_test.go b/pkg/core/native_neo_test.go index a88fecea5..9d7d87ea5 100644 --- a/pkg/core/native_neo_test.go +++ b/pkg/core/native_neo_test.go @@ -11,6 +11,7 @@ import ( "github.com/nspcc-dev/neo-go/pkg/core/transaction" "github.com/nspcc-dev/neo-go/pkg/crypto/keys" "github.com/nspcc-dev/neo-go/pkg/io" + "github.com/nspcc-dev/neo-go/pkg/smartcontract/callflag" "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" @@ -75,11 +76,11 @@ func TestNEO_Vote(t *testing.T) { to := accs[i].Contract.ScriptHash() w := io.NewBufBinWriter() - emit.AppCallWithOperationAndArgs(w.BinWriter, bc.contracts.NEO.Hash, "transfer", + emit.AppCall(w.BinWriter, bc.contracts.NEO.Hash, "transfer", callflag.All, neoOwner.BytesBE(), to.BytesBE(), big.NewInt(int64(sz-i)*1000000).Int64(), nil) emit.Opcodes(w.BinWriter, opcode.ASSERT) - emit.AppCallWithOperationAndArgs(w.BinWriter, bc.contracts.GAS.Hash, "transfer", + emit.AppCall(w.BinWriter, bc.contracts.GAS.Hash, "transfer", callflag.All, neoOwner.BytesBE(), to.BytesBE(), int64(1_000_000_000), nil) emit.Opcodes(w.BinWriter, opcode.ASSERT) @@ -141,7 +142,7 @@ func TestNEO_Vote(t *testing.T) { h := accs[i].PrivateKey().GetScriptHash() gasBalance[i] = bc.GetUtilityTokenBalance(h) neoBalance[i], _ = bc.GetGoverningTokenBalance(h) - emit.AppCallWithOperationAndArgs(w.BinWriter, bc.contracts.NEO.Hash, "transfer", + emit.AppCall(w.BinWriter, bc.contracts.NEO.Hash, "transfer", callflag.All, h.BytesBE(), h.BytesBE(), int64(1), nil) emit.Opcodes(w.BinWriter, opcode.ASSERT) require.NoError(t, w.Err) diff --git a/pkg/core/native_notary_test.go b/pkg/core/native_notary_test.go index a9d2ff614..75f6fd3e9 100644 --- a/pkg/core/native_notary_test.go +++ b/pkg/core/native_notary_test.go @@ -11,6 +11,7 @@ import ( "github.com/nspcc-dev/neo-go/pkg/crypto/keys" "github.com/nspcc-dev/neo-go/pkg/encoding/bigint" "github.com/nspcc-dev/neo-go/pkg/io" + "github.com/nspcc-dev/neo-go/pkg/smartcontract/callflag" "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" @@ -174,7 +175,8 @@ func TestNotaryContractPipeline(t *testing.T) { // `withdraw`: bad witness w := io.NewBufBinWriter() - emit.AppCallWithOperationAndArgs(w.BinWriter, notaryHash, "withdraw", testchain.MultisigScriptHash(), acc.PrivateKey().PublicKey().GetScriptHash()) + emit.AppCall(w.BinWriter, notaryHash, "withdraw", callflag.All, + testchain.MultisigScriptHash(), acc.PrivateKey().PublicKey().GetScriptHash()) require.NoError(t, w.Err) script := w.Bytes() withdrawTx := transaction.New(chain.GetConfig().Magic, script, 10000000) diff --git a/pkg/core/native_oracle_test.go b/pkg/core/native_oracle_test.go index 7dfcb860e..b316bc3e5 100644 --- a/pkg/core/native_oracle_test.go +++ b/pkg/core/native_oracle_test.go @@ -33,9 +33,11 @@ func getOracleContractState(h util.Uint160) *state.Contract { w := io.NewBufBinWriter() emit.Int(w.BinWriter, 5) emit.Opcodes(w.BinWriter, opcode.PACK) + emit.Int(w.BinWriter, int64(callflag.All)) emit.String(w.BinWriter, "request") emit.Bytes(w.BinWriter, h.BytesBE()) emit.Syscall(w.BinWriter, interopnames.SystemContractCall) + emit.Opcodes(w.BinWriter, opcode.DROP) emit.Opcodes(w.BinWriter, opcode.RET) // `handle` method aborts if len(userData) == 2 diff --git a/pkg/interop/contract/contract.go b/pkg/interop/contract/contract.go index a42be36c5..4e628b0d1 100644 --- a/pkg/interop/contract/contract.go +++ b/pkg/interop/contract/contract.go @@ -40,17 +40,9 @@ func GetCallFlags() int64 { } // Call executes previously deployed blockchain contract with specified hash -// (20 bytes in BE form) using provided arguments. -// It returns whatever this contract returns. This function uses -// `System.Contract.Call` syscall. -func Call(scriptHash interop.Hash160, method string, args ...interface{}) interface{} { - return nil -} - -// CallEx executes previously deployed blockchain contract with specified hash // (20 bytes in BE form) using provided arguments and call flags. // It returns whatever this contract returns. This function uses -// `System.Contract.CallEx` syscall. -func CallEx(f CallFlag, scriptHash interop.Hash160, method string, args ...interface{}) interface{} { +// `System.Contract.Call` syscall. +func Call(scriptHash interop.Hash160, method string, f CallFlag, args ...interface{}) interface{} { return nil } diff --git a/pkg/rpc/client/nep17.go b/pkg/rpc/client/nep17.go index 941cd908f..250432ef1 100644 --- a/pkg/rpc/client/nep17.go +++ b/pkg/rpc/client/nep17.go @@ -9,6 +9,7 @@ import ( "github.com/nspcc-dev/neo-go/pkg/io" "github.com/nspcc-dev/neo-go/pkg/rpc/response/result" "github.com/nspcc-dev/neo-go/pkg/smartcontract" + "github.com/nspcc-dev/neo-go/pkg/smartcontract/callflag" "github.com/nspcc-dev/neo-go/pkg/util" "github.com/nspcc-dev/neo-go/pkg/vm/emit" "github.com/nspcc-dev/neo-go/pkg/vm/opcode" @@ -120,8 +121,8 @@ func (c *Client) CreateNEP17MultiTransferTx(acc *wallet.Account, gas int64, reci } w := io.NewBufBinWriter() for i := range recipients { - emit.AppCallWithOperationAndArgs(w.BinWriter, recipients[i].Token, "transfer", from, - recipients[i].Address, recipients[i].Amount, nil) + emit.AppCall(w.BinWriter, recipients[i].Token, "transfer", + callflag.WriteStates|callflag.AllowCall|callflag.AllowNotify, from, recipients[i].Address, recipients[i].Amount, nil) emit.Opcodes(w.BinWriter, opcode.ASSERT) } accAddr, err := address.StringToUint160(acc.Address) diff --git a/pkg/rpc/request/txBuilder.go b/pkg/rpc/request/txBuilder.go index 0c5f58336..e43e8b1bd 100644 --- a/pkg/rpc/request/txBuilder.go +++ b/pkg/rpc/request/txBuilder.go @@ -8,6 +8,7 @@ import ( "github.com/nspcc-dev/neo-go/pkg/crypto/keys" "github.com/nspcc-dev/neo-go/pkg/io" "github.com/nspcc-dev/neo-go/pkg/smartcontract" + "github.com/nspcc-dev/neo-go/pkg/smartcontract/callflag" "github.com/nspcc-dev/neo-go/pkg/util" "github.com/nspcc-dev/neo-go/pkg/vm/emit" "github.com/nspcc-dev/neo-go/pkg/vm/opcode" @@ -101,7 +102,7 @@ func expandArrayIntoScript(script *io.BinWriter, slice []Param) error { // CreateFunctionInvocationScript creates a script to invoke given contract with // given parameters. -func CreateFunctionInvocationScript(contract util.Uint160, params Params) ([]byte, error) { +func CreateFunctionInvocationScript(contract util.Uint160, method string, params Params) ([]byte, error) { script := io.NewBufBinWriter() for i := len(params) - 1; i >= 0; i-- { switch params[i].Type { @@ -127,6 +128,6 @@ func CreateFunctionInvocationScript(contract util.Uint160, params Params) ([]byt } } - emit.AppCall(script.BinWriter, contract) + emit.AppCallNoArgs(script.BinWriter, contract, method, callflag.All) return script.Bytes(), nil } diff --git a/pkg/rpc/request/tx_builder_test.go b/pkg/rpc/request/tx_builder_test.go index 6c1f1587e..af0fcbaa7 100644 --- a/pkg/rpc/request/tx_builder_test.go +++ b/pkg/rpc/request/tx_builder_test.go @@ -21,46 +21,44 @@ func TestInvocationScriptCreationGood(t *testing.T) { ps Params script string }{{ - script: "0c146f459162ceeb248b071ec157d9e4f6fd26fdbe5041627d5b52", - }, { ps: Params{{Type: StringT, Value: "transfer"}}, - script: "0c087472616e736665720c146f459162ceeb248b071ec157d9e4f6fd26fdbe5041627d5b52", + script: "1f0c087472616e736665720c146f459162ceeb248b071ec157d9e4f6fd26fdbe5041627d5b52", }, { ps: Params{{Type: NumberT, Value: 42}}, - script: "0c0234320c146f459162ceeb248b071ec157d9e4f6fd26fdbe5041627d5b52", + script: "1f0c0234320c146f459162ceeb248b071ec157d9e4f6fd26fdbe5041627d5b52", }, { ps: Params{{Type: StringT, Value: "a"}, {Type: ArrayT, Value: []Param{}}}, - script: "10c00c01610c146f459162ceeb248b071ec157d9e4f6fd26fdbe5041627d5b52", + script: "10c01f0c01610c146f459162ceeb248b071ec157d9e4f6fd26fdbe5041627d5b52", }, { ps: Params{{Type: StringT, Value: "a"}, {Type: ArrayT, Value: []Param{{Type: FuncParamT, Value: FuncParam{Type: smartcontract.ByteArrayType, Value: Param{Type: StringT, Value: "AwEtR+diEK7HO+Oas9GG4KQP6Nhr+j1Pq/2le6E7iPlq"}}}}}}, - script: "0c2103012d47e76210aec73be39ab3d186e0a40fe8d86bfa3d4fabfda57ba13b88f96a11c00c01610c146f459162ceeb248b071ec157d9e4f6fd26fdbe5041627d5b52", + script: "0c2103012d47e76210aec73be39ab3d186e0a40fe8d86bfa3d4fabfda57ba13b88f96a11c01f0c01610c146f459162ceeb248b071ec157d9e4f6fd26fdbe5041627d5b52", }, { ps: Params{{Type: StringT, Value: "a"}, {Type: ArrayT, Value: []Param{{Type: FuncParamT, Value: FuncParam{Type: smartcontract.SignatureType, Value: Param{Type: StringT, Value: "4edf5005771de04619235d5a4c7a9a11bb78e008541f1da7725f654c33380a3c87e2959a025da706d7255cb3a3fa07ebe9c6559d0d9e6213c68049168eb1056f"}}}}}}, - script: "0c404edf5005771de04619235d5a4c7a9a11bb78e008541f1da7725f654c33380a3c87e2959a025da706d7255cb3a3fa07ebe9c6559d0d9e6213c68049168eb1056f11c00c01610c146f459162ceeb248b071ec157d9e4f6fd26fdbe5041627d5b52", + script: "0c404edf5005771de04619235d5a4c7a9a11bb78e008541f1da7725f654c33380a3c87e2959a025da706d7255cb3a3fa07ebe9c6559d0d9e6213c68049168eb1056f11c01f0c01610c146f459162ceeb248b071ec157d9e4f6fd26fdbe5041627d5b52", }, { ps: Params{{Type: StringT, Value: "a"}, {Type: ArrayT, Value: []Param{{Type: FuncParamT, Value: FuncParam{Type: smartcontract.StringType, Value: Param{Type: StringT, Value: "50befd26fdf6e4d957c11e078b24ebce6291456f"}}}}}}, - script: "0c283530626566643236666466366534643935376331316530373862323465626365363239313435366611c00c01610c146f459162ceeb248b071ec157d9e4f6fd26fdbe5041627d5b52", + script: "0c283530626566643236666466366534643935376331316530373862323465626365363239313435366611c01f0c01610c146f459162ceeb248b071ec157d9e4f6fd26fdbe5041627d5b52", }, { ps: Params{{Type: StringT, Value: "a"}, {Type: ArrayT, Value: []Param{{Type: FuncParamT, Value: FuncParam{Type: smartcontract.Hash160Type, Value: Param{Type: StringT, Value: "50befd26fdf6e4d957c11e078b24ebce6291456f"}}}}}}, - script: "0c146f459162ceeb248b071ec157d9e4f6fd26fdbe5011c00c01610c146f459162ceeb248b071ec157d9e4f6fd26fdbe5041627d5b52", + script: "0c146f459162ceeb248b071ec157d9e4f6fd26fdbe5011c01f0c01610c146f459162ceeb248b071ec157d9e4f6fd26fdbe5041627d5b52", }, { ps: Params{{Type: StringT, Value: "a"}, {Type: ArrayT, Value: []Param{{Type: FuncParamT, Value: FuncParam{Type: smartcontract.Hash256Type, Value: Param{Type: StringT, Value: "602c79718b16e442de58778e148d0b1084e3b2dffd5de6b7b16cee7969282de7"}}}}}}, - script: "0c20e72d286979ee6cb1b7e65dfddfb2e384100b8d148e7758de42e4168b71792c6011c00c01610c146f459162ceeb248b071ec157d9e4f6fd26fdbe5041627d5b52", + script: "0c20e72d286979ee6cb1b7e65dfddfb2e384100b8d148e7758de42e4168b71792c6011c01f0c01610c146f459162ceeb248b071ec157d9e4f6fd26fdbe5041627d5b52", }, { ps: Params{{Type: StringT, Value: "a"}, {Type: ArrayT, Value: []Param{{Type: FuncParamT, Value: FuncParam{Type: smartcontract.PublicKeyType, Value: Param{Type: StringT, Value: "03c089d7122b840a4935234e82e26ae5efd0c2acb627239dc9f207311337b6f2c1"}}}}}}, - script: "0c2103c089d7122b840a4935234e82e26ae5efd0c2acb627239dc9f207311337b6f2c111c00c01610c146f459162ceeb248b071ec157d9e4f6fd26fdbe5041627d5b52", + script: "0c2103c089d7122b840a4935234e82e26ae5efd0c2acb627239dc9f207311337b6f2c111c01f0c01610c146f459162ceeb248b071ec157d9e4f6fd26fdbe5041627d5b52", }, { ps: Params{{Type: StringT, Value: "a"}, {Type: ArrayT, Value: []Param{{Type: FuncParamT, Value: FuncParam{Type: smartcontract.IntegerType, Value: Param{Type: NumberT, Value: 42}}}}}}, - script: "002a11c00c01610c146f459162ceeb248b071ec157d9e4f6fd26fdbe5041627d5b52", + script: "002a11c01f0c01610c146f459162ceeb248b071ec157d9e4f6fd26fdbe5041627d5b52", }, { ps: Params{{Type: StringT, Value: "a"}, {Type: ArrayT, Value: []Param{{Type: FuncParamT, Value: FuncParam{Type: smartcontract.BoolType, Value: Param{Type: StringT, Value: "true"}}}}}}, - script: "1111c00c01610c146f459162ceeb248b071ec157d9e4f6fd26fdbe5041627d5b52", + script: "1111c01f0c01610c146f459162ceeb248b071ec157d9e4f6fd26fdbe5041627d5b52", }, { ps: Params{{Type: StringT, Value: "a"}, {Type: ArrayT, Value: []Param{{Type: FuncParamT, Value: FuncParam{Type: smartcontract.BoolType, Value: Param{Type: StringT, Value: "false"}}}}}}, - script: "1011c00c01610c146f459162ceeb248b071ec157d9e4f6fd26fdbe5041627d5b52", + script: "1011c01f0c01610c146f459162ceeb248b071ec157d9e4f6fd26fdbe5041627d5b52", }} for _, ps := range paramScripts { - script, err := CreateFunctionInvocationScript(contract, ps.ps) + script, err := CreateFunctionInvocationScript(contract, ps.ps[0].String(), ps.ps[1:]) assert.Nil(t, err) assert.Equal(t, ps.script, hex.EncodeToString(script)) } @@ -86,7 +84,7 @@ func TestInvocationScriptCreationBad(t *testing.T) { {{Type: ArrayT, Value: []Param{{Type: FuncParamT, Value: FuncParam{Type: smartcontract.UnknownType, Value: Param{}}}}}}, } for _, ps := range testParams { - _, err := CreateFunctionInvocationScript(contract, ps) + _, err := CreateFunctionInvocationScript(contract, "", ps) assert.NotNil(t, err) } } diff --git a/pkg/rpc/server/server.go b/pkg/rpc/server/server.go index 01a15412b..8edafd530 100644 --- a/pkg/rpc/server/server.go +++ b/pkg/rpc/server/server.go @@ -1097,7 +1097,7 @@ func (s *Server) invokeFunction(reqParams request.Params) (interface{}, *respons if len(tx.Signers) == 0 { tx.Signers = []transaction.Signer{{Account: util.Uint160{}, Scopes: transaction.None}} } - script, err := request.CreateFunctionInvocationScript(scriptHash, reqParams[1:checkWitnessHashesIndex]) + script, err := request.CreateFunctionInvocationScript(scriptHash, reqParams[1].String(), reqParams[2:checkWitnessHashesIndex]) if err != nil { return nil, response.NewInternalServerError("can't create invocation script", err) } @@ -1138,14 +1138,7 @@ func (s *Server) invokeContractVerify(reqParams request.Params) (interface{}, *r return nil, responseErr } - args := make(request.Params, 1) - args[0] = request.Param{ - Type: request.StringT, - Value: manifest.MethodVerify, - } - if len(reqParams) > 1 { - args = append(args, reqParams[1]) - } + args := reqParams[1:2] var tx *transaction.Transaction if len(reqParams) > 2 { signers, witnesses, err := reqParams[2].GetSignersWithWitnesses() @@ -1162,7 +1155,7 @@ func (s *Server) invokeContractVerify(reqParams request.Params) (interface{}, *r if cs == nil { return nil, response.NewRPCError("unknown contract", scriptHash.StringBE(), nil) } - script, err := request.CreateFunctionInvocationScript(cs.Hash, args) + script, err := request.CreateFunctionInvocationScript(cs.Hash, manifest.MethodVerify, args) if err != nil { return nil, response.NewInternalServerError("can't create invocation script", err) } diff --git a/pkg/rpc/server/server_test.go b/pkg/rpc/server/server_test.go index 9037cc7a3..4a532f983 100644 --- a/pkg/rpc/server/server_test.go +++ b/pkg/rpc/server/server_test.go @@ -57,7 +57,7 @@ type rpcTestCase struct { } const testContractHash = "743ed26f78e29ecd595535b74a943b1f9ccbc444" -const deploymentTxHash = "a4644e08389ced59e875a8d5bdcb8fdded7507ed7dc3915a37e5be71736ac7b4" +const deploymentTxHash = "2aef5684c6cf60884cc00400b78c65c5105ed4261a4f614bce74c74927a66bf3" const genesisBlockHash = "0542f4350c6e236d0509bcd98188b0034bfbecc1a0c7fcdb8e4295310d468b70" const verifyContractHash = "a2eb22340979804cb10cc1add0b8822c201f4d8a" @@ -1408,7 +1408,7 @@ func checkNep17Balances(t *testing.T, e *executor, acc interface{}) { }, { Asset: e.chain.UtilityTokenHash(), - Amount: "80006564770", + Amount: "80006675650", LastUpdated: 7, }}, Address: testchain.PrivateKeyByID(0).GetScriptHash().StringLE(), diff --git a/pkg/rpc/server/testdata/testblocks.acc b/pkg/rpc/server/testdata/testblocks.acc index 4bed865540d2e8ae6fb9f8488db88e077423921f..21aa35b50c40d5ef3d4e42450db540b2bf0e697c 100644 GIT binary patch delta 3172 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 0 && oldEstack.Len() != oldCtx.RetCount { + panic(fmt.Errorf("invalid return values count: expected %d, got %d", + oldCtx.RetCount, oldEstack.Len())) + } rvcount := oldEstack.Len() for i := rvcount; i > 0; i-- { elem := oldEstack.RemoveAt(i - 1) @@ -1425,19 +1436,6 @@ func (v *VM) unloadContext(ctx *Context) { if ctx.static != nil && currCtx != nil && ctx.static != currCtx.static { ctx.static.Clear() } - switch ctx.CheckReturn { - case NoCheck: - case EnsureIsEmpty: - if currCtx != nil && ctx.estack.len != 0 { - panic("return value amount is > 0") - } - case EnsureNotEmpty: - if currCtx != nil && ctx.estack.len == 0 { - currCtx.estack.PushVal(stackitem.Null{}) - } else if ctx.estack.len > 1 { - panic("return value amount is > 1") - } - } } // getTryParams splits TRY(L) instruction parameter into offsets for catch and finally blocks. @@ -1494,7 +1492,7 @@ func (v *VM) Call(ctx *Context, offset int) { func (v *VM) call(ctx *Context, offset int) { v.checkInvocationStackSize() newCtx := ctx.Copy() - newCtx.CheckReturn = NoCheck + newCtx.RetCount = -1 newCtx.local = nil newCtx.arguments = nil newCtx.tryStack = NewStack("exception") diff --git a/scripts/gendump/main.go b/scripts/gendump/main.go index 3a8cfc35b..8b93aea5a 100644 --- a/scripts/gendump/main.go +++ b/scripts/gendump/main.go @@ -20,6 +20,7 @@ import ( "github.com/nspcc-dev/neo-go/pkg/core/transaction" "github.com/nspcc-dev/neo-go/pkg/io" "github.com/nspcc-dev/neo-go/pkg/smartcontract" + "github.com/nspcc-dev/neo-go/pkg/smartcontract/callflag" "github.com/nspcc-dev/neo-go/pkg/vm/emit" "github.com/nspcc-dev/neo-go/pkg/wallet" "go.uber.org/zap" @@ -95,7 +96,7 @@ func main() { rand.Read(value) w := io.NewBufBinWriter() - emit.AppCallWithOperationAndArgs(w.BinWriter, contractHash, "put", key, value) + emit.AppCall(w.BinWriter, contractHash, "put", callflag.All, key, value) handleError("can't create transaction", w.Err) tx := transaction.New(netmode.UnitTestNet, w.Bytes(), 4_000_000)