From b07347e602775aed96cec392cc736ab8438f52f0 Mon Sep 17 00:00:00 2001 From: Roman Khimov Date: Mon, 30 Aug 2021 23:43:17 +0300 Subject: [PATCH] core: reuse PushItem for interops Probably less critical here, but still let's push things faster. --- pkg/core/interop/contract/call.go | 4 ++-- pkg/core/interop/crypto/ecdsa.go | 5 +++-- pkg/core/interop/iterator/interop.go | 4 ++-- pkg/core/interop/runtime/engine.go | 9 +++++---- pkg/core/interop/runtime/util.go | 13 +++++++------ pkg/core/interop/runtime/witness.go | 3 ++- pkg/core/interop_system.go | 19 ++++++++++--------- pkg/core/native/interop.go | 2 +- 8 files changed, 32 insertions(+), 27 deletions(-) diff --git a/pkg/core/interop/contract/call.go b/pkg/core/interop/contract/call.go index 3829ea290..c6f7c59c2 100644 --- a/pkg/core/interop/contract/call.go +++ b/pkg/core/interop/contract/call.go @@ -70,7 +70,7 @@ func Call(ic *interop.Context) error { } hasReturn := md.ReturnType != smartcontract.VoidType if !hasReturn { - ic.VM.Estack().PushVal(stackitem.Null{}) + ic.VM.Estack().PushItem(stackitem.Null{}) } return callInternal(ic, cs, method, fs, hasReturn, args) } @@ -116,7 +116,7 @@ func callExFromNative(ic *interop.Context, caller util.Uint160, cs *state.Contra ic.VM.LoadScriptWithCallingHash(caller, cs.NEF.Script, cs.Hash, ic.VM.Context().GetCallFlags()&f, hasReturn, uint16(len(args))) ic.VM.Context().NEF = &cs.NEF for i := len(args) - 1; i >= 0; i-- { - ic.VM.Estack().PushVal(args[i]) + ic.VM.Estack().PushItem(args[i]) } // use Jump not Call here because context was loaded in LoadScript above. ic.VM.Jump(ic.VM.Context(), md.Offset) diff --git a/pkg/core/interop/crypto/ecdsa.go b/pkg/core/interop/crypto/ecdsa.go index 14c93aed4..668bda363 100644 --- a/pkg/core/interop/crypto/ecdsa.go +++ b/pkg/core/interop/crypto/ecdsa.go @@ -10,6 +10,7 @@ import ( "github.com/nspcc-dev/neo-go/pkg/crypto/hash" "github.com/nspcc-dev/neo-go/pkg/crypto/keys" "github.com/nspcc-dev/neo-go/pkg/vm" + "github.com/nspcc-dev/neo-go/pkg/vm/stackitem" ) // ECDSASecp256r1CheckMultisig checks multiple ECDSA signatures at once using @@ -32,7 +33,7 @@ func ECDSASecp256r1CheckMultisig(ic *interop.Context) error { return errors.New("more signatures than there are keys") } sigok := vm.CheckMultisigPar(ic.VM, elliptic.P256(), hash.NetSha256(ic.Network, ic.Container).BytesBE(), pkeys, sigs) - ic.VM.Estack().PushVal(sigok) + ic.VM.Estack().PushItem(stackitem.Bool(sigok)) return nil } @@ -45,6 +46,6 @@ func ECDSASecp256r1CheckSig(ic *interop.Context) error { return err } res := pkey.VerifyHashable(signature, ic.Network, ic.Container) - ic.VM.Estack().PushVal(res) + ic.VM.Estack().PushItem(stackitem.Bool(res)) return nil } diff --git a/pkg/core/interop/iterator/interop.go b/pkg/core/interop/iterator/interop.go index 6a72e8cf9..681d147a7 100644 --- a/pkg/core/interop/iterator/interop.go +++ b/pkg/core/interop/iterator/interop.go @@ -14,7 +14,7 @@ type iterator interface { func Next(ic *interop.Context) error { iop := ic.VM.Estack().Pop().Interop() arr := iop.Value().(iterator) - ic.VM.Estack().PushVal(arr.Next()) + ic.VM.Estack().PushItem(stackitem.Bool(arr.Next())) return nil } @@ -25,7 +25,7 @@ func Next(ic *interop.Context) error { func Value(ic *interop.Context) error { iop := ic.VM.Estack().Pop().Interop() arr := iop.Value().(iterator) - ic.VM.Estack().PushVal(arr.Value()) + ic.VM.Estack().PushItem(arr.Value()) return nil } diff --git a/pkg/core/interop/runtime/engine.go b/pkg/core/interop/runtime/engine.go index fe25c8b77..b80bb8a98 100644 --- a/pkg/core/interop/runtime/engine.go +++ b/pkg/core/interop/runtime/engine.go @@ -3,6 +3,7 @@ package runtime import ( "errors" "fmt" + "math/big" "github.com/nspcc-dev/neo-go/pkg/core/interop" "github.com/nspcc-dev/neo-go/pkg/core/state" @@ -28,7 +29,7 @@ func GetExecutingScriptHash(ic *interop.Context) error { // one native to another, no operations are performed on invocation stack. func GetCallingScriptHash(ic *interop.Context) error { h := ic.VM.GetCallingScriptHash() - ic.VM.Estack().PushVal(h.BytesBE()) + ic.VM.Estack().PushItem(stackitem.NewByteArray(h.BytesBE())) return nil } @@ -39,13 +40,13 @@ func GetEntryScriptHash(ic *interop.Context) error { // Platform returns the name of the platform. func Platform(ic *interop.Context) error { - ic.VM.Estack().PushVal([]byte("NEO")) + ic.VM.Estack().PushItem(stackitem.NewByteArray([]byte("NEO"))) return nil } // GetTrigger returns the script trigger. func GetTrigger(ic *interop.Context) error { - ic.VM.Estack().PushVal(byte(ic.Trigger)) + ic.VM.Estack().PushItem(stackitem.NewBigInteger(big.NewInt(int64(ic.Trigger)))) return nil } @@ -97,7 +98,7 @@ func Log(ic *interop.Context) error { // GetTime returns timestamp of the block being verified, or the latest // one in the blockchain if no block is given to Context. func GetTime(ic *interop.Context) error { - ic.VM.Estack().PushVal(ic.Block.Timestamp) + ic.VM.Estack().PushItem(stackitem.NewBigInteger(new(big.Int).SetUint64(ic.Block.Timestamp))) return nil } diff --git a/pkg/core/interop/runtime/util.go b/pkg/core/interop/runtime/util.go index 77f311061..d14684e66 100644 --- a/pkg/core/interop/runtime/util.go +++ b/pkg/core/interop/runtime/util.go @@ -3,6 +3,7 @@ package runtime import ( "encoding/binary" "errors" + "math/big" "github.com/nspcc-dev/neo-go/pkg/core/interop" "github.com/nspcc-dev/neo-go/pkg/core/state" @@ -16,9 +17,9 @@ import ( // GasLeft returns remaining amount of GAS. func GasLeft(ic *interop.Context) error { if ic.VM.GasLimit == -1 { - ic.VM.Estack().PushVal(ic.VM.GasLimit) + ic.VM.Estack().PushItem(stackitem.NewBigInteger(big.NewInt(ic.VM.GasLimit))) } else { - ic.VM.Estack().PushVal(ic.VM.GasLimit - ic.VM.GasConsumed()) + ic.VM.Estack().PushItem(stackitem.NewBigInteger(big.NewInt(ic.VM.GasLimit - ic.VM.GasConsumed()))) } return nil } @@ -55,7 +56,7 @@ func GetNotifications(ic *interop.Context) error { }) arr.Append(ev) } - ic.VM.Estack().PushVal(arr) + ic.VM.Estack().PushItem(arr) return nil } @@ -67,21 +68,21 @@ func GetInvocationCounter(ic *interop.Context) error { count = 1 ic.VM.Invocations[currentScriptHash] = count } - ic.VM.Estack().PushVal(count) + ic.VM.Estack().PushItem(stackitem.NewBigInteger(big.NewInt(int64(count)))) return nil } // GetNetwork returns chain network number. func GetNetwork(ic *interop.Context) error { m := ic.Chain.GetConfig().Magic - ic.VM.Estack().PushVal(uint32(m)) + ic.VM.Estack().PushItem(stackitem.NewBigInteger(big.NewInt(int64(m)))) return nil } // GetRandom returns pseudo-random number which depends on block nonce and transaction hash. func GetRandom(ic *interop.Context) error { res := murmur128(ic.NonceData[:], ic.Network) - ic.VM.Estack().PushVal(bigint.FromBytesUnsigned(res)) + ic.VM.Estack().PushItem(stackitem.NewBigInteger(bigint.FromBytesUnsigned(res))) copy(ic.NonceData[:], res) return nil } diff --git a/pkg/core/interop/runtime/witness.go b/pkg/core/interop/runtime/witness.go index 2eb5766af..e9e456d0f 100644 --- a/pkg/core/interop/runtime/witness.go +++ b/pkg/core/interop/runtime/witness.go @@ -11,6 +11,7 @@ import ( "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" + "github.com/nspcc-dev/neo-go/pkg/vm/stackitem" ) // CheckHashedWitness checks given hash against current list of script hashes @@ -97,6 +98,6 @@ func CheckWitness(ic *interop.Context) error { if err != nil { return fmt.Errorf("failed to check witness: %w", err) } - ic.VM.Estack().PushVal(res) + ic.VM.Estack().PushItem(stackitem.Bool(res)) return nil } diff --git a/pkg/core/interop_system.go b/pkg/core/interop_system.go index e83e3880f..a56ef18cd 100644 --- a/pkg/core/interop_system.go +++ b/pkg/core/interop_system.go @@ -6,6 +6,7 @@ import ( "errors" "fmt" "math" + "math/big" "sort" "github.com/nspcc-dev/neo-go/pkg/core/block" @@ -44,7 +45,7 @@ func engineGetScriptContainer(ic *interop.Context) error { default: return errors.New("unknown script container") } - ic.VM.Estack().PushVal(item) + ic.VM.Estack().PushItem(item) return nil } @@ -72,9 +73,9 @@ func storageGet(ic *interop.Context) error { key := ic.VM.Estack().Pop().Bytes() si := ic.DAO.GetStorageItem(stc.ID, key) if si != nil { - ic.VM.Estack().PushVal([]byte(si)) + ic.VM.Estack().PushItem(stackitem.NewByteArray([]byte(si))) } else { - ic.VM.Estack().PushVal(stackitem.Null{}) + ic.VM.Estack().PushItem(stackitem.Null{}) } return nil } @@ -100,7 +101,7 @@ func storageGetContextInternal(ic *interop.Context, isReadOnly bool) error { ID: contract.ID, ReadOnly: isReadOnly, } - ic.VM.Estack().PushVal(stackitem.NewInterop(sc)) + ic.VM.Estack().PushItem(stackitem.NewInterop(sc)) return nil } @@ -157,7 +158,7 @@ func storageContextAsReadOnly(ic *interop.Context) error { } stc = stx } - ic.VM.Estack().PushVal(stackitem.NewInterop(stc)) + ic.VM.Estack().PushItem(stackitem.NewInterop(stc)) return nil } @@ -210,7 +211,7 @@ func storageFind(ic *interop.Context) error { filteredMap := stackitem.NewMapWithValue(arr) item := istorage.NewIterator(filteredMap, len(prefix), opts) - ic.VM.Estack().PushVal(stackitem.NewInterop(item)) + ic.VM.Estack().PushItem(stackitem.NewInterop(item)) return nil } @@ -236,7 +237,7 @@ func contractCreateMultisigAccount(ic *interop.Context) error { if err != nil { return err } - ic.VM.Estack().PushVal(hash.Hash160(script).BytesBE()) + ic.VM.Estack().PushItem(stackitem.NewByteArray(hash.Hash160(script).BytesBE())) return nil } @@ -247,12 +248,12 @@ func contractCreateStandardAccount(ic *interop.Context) error { if err != nil { return err } - ic.VM.Estack().PushVal(p.GetScriptHash().BytesBE()) + ic.VM.Estack().PushItem(stackitem.NewByteArray(p.GetScriptHash().BytesBE())) return nil } // contractGetCallFlags returns current context calling flags. func contractGetCallFlags(ic *interop.Context) error { - ic.VM.Estack().PushVal(ic.VM.Context().GetCallFlags()) + ic.VM.Estack().PushItem(stackitem.NewBigInteger(big.NewInt(int64(ic.VM.Context().GetCallFlags())))) return nil } diff --git a/pkg/core/native/interop.go b/pkg/core/native/interop.go index c112ba539..cf12a419b 100644 --- a/pkg/core/native/interop.go +++ b/pkg/core/native/interop.go @@ -53,7 +53,7 @@ func Call(ic *interop.Context) error { } result := m.Func(ic, args) if m.MD.ReturnType != smartcontract.VoidType { - ctx.Estack().PushVal(result) + ctx.Estack().PushItem(result) } return nil }