core: reuse PushItem for interops
Probably less critical here, but still let's push things faster.
This commit is contained in:
parent
a3892aa662
commit
b07347e602
8 changed files with 32 additions and 27 deletions
|
@ -70,7 +70,7 @@ func Call(ic *interop.Context) error {
|
||||||
}
|
}
|
||||||
hasReturn := md.ReturnType != smartcontract.VoidType
|
hasReturn := md.ReturnType != smartcontract.VoidType
|
||||||
if !hasReturn {
|
if !hasReturn {
|
||||||
ic.VM.Estack().PushVal(stackitem.Null{})
|
ic.VM.Estack().PushItem(stackitem.Null{})
|
||||||
}
|
}
|
||||||
return callInternal(ic, cs, method, fs, hasReturn, args)
|
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.LoadScriptWithCallingHash(caller, cs.NEF.Script, cs.Hash, ic.VM.Context().GetCallFlags()&f, hasReturn, uint16(len(args)))
|
||||||
ic.VM.Context().NEF = &cs.NEF
|
ic.VM.Context().NEF = &cs.NEF
|
||||||
for i := len(args) - 1; i >= 0; i-- {
|
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.
|
// use Jump not Call here because context was loaded in LoadScript above.
|
||||||
ic.VM.Jump(ic.VM.Context(), md.Offset)
|
ic.VM.Jump(ic.VM.Context(), md.Offset)
|
||||||
|
|
|
@ -10,6 +10,7 @@ import (
|
||||||
"github.com/nspcc-dev/neo-go/pkg/crypto/hash"
|
"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/crypto/keys"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/vm"
|
"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
|
// 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")
|
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)
|
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
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -45,6 +46,6 @@ func ECDSASecp256r1CheckSig(ic *interop.Context) error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
res := pkey.VerifyHashable(signature, ic.Network, ic.Container)
|
res := pkey.VerifyHashable(signature, ic.Network, ic.Container)
|
||||||
ic.VM.Estack().PushVal(res)
|
ic.VM.Estack().PushItem(stackitem.Bool(res))
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,7 +14,7 @@ type iterator interface {
|
||||||
func Next(ic *interop.Context) error {
|
func Next(ic *interop.Context) error {
|
||||||
iop := ic.VM.Estack().Pop().Interop()
|
iop := ic.VM.Estack().Pop().Interop()
|
||||||
arr := iop.Value().(iterator)
|
arr := iop.Value().(iterator)
|
||||||
ic.VM.Estack().PushVal(arr.Next())
|
ic.VM.Estack().PushItem(stackitem.Bool(arr.Next()))
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -25,7 +25,7 @@ func Next(ic *interop.Context) error {
|
||||||
func Value(ic *interop.Context) error {
|
func Value(ic *interop.Context) error {
|
||||||
iop := ic.VM.Estack().Pop().Interop()
|
iop := ic.VM.Estack().Pop().Interop()
|
||||||
arr := iop.Value().(iterator)
|
arr := iop.Value().(iterator)
|
||||||
ic.VM.Estack().PushVal(arr.Value())
|
ic.VM.Estack().PushItem(arr.Value())
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,6 +3,7 @@ package runtime
|
||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"math/big"
|
||||||
|
|
||||||
"github.com/nspcc-dev/neo-go/pkg/core/interop"
|
"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/core/state"
|
||||||
|
@ -28,7 +29,7 @@ func GetExecutingScriptHash(ic *interop.Context) error {
|
||||||
// one native to another, no operations are performed on invocation stack.
|
// one native to another, no operations are performed on invocation stack.
|
||||||
func GetCallingScriptHash(ic *interop.Context) error {
|
func GetCallingScriptHash(ic *interop.Context) error {
|
||||||
h := ic.VM.GetCallingScriptHash()
|
h := ic.VM.GetCallingScriptHash()
|
||||||
ic.VM.Estack().PushVal(h.BytesBE())
|
ic.VM.Estack().PushItem(stackitem.NewByteArray(h.BytesBE()))
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -39,13 +40,13 @@ func GetEntryScriptHash(ic *interop.Context) error {
|
||||||
|
|
||||||
// Platform returns the name of the platform.
|
// Platform returns the name of the platform.
|
||||||
func Platform(ic *interop.Context) error {
|
func Platform(ic *interop.Context) error {
|
||||||
ic.VM.Estack().PushVal([]byte("NEO"))
|
ic.VM.Estack().PushItem(stackitem.NewByteArray([]byte("NEO")))
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetTrigger returns the script trigger.
|
// GetTrigger returns the script trigger.
|
||||||
func GetTrigger(ic *interop.Context) error {
|
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
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -97,7 +98,7 @@ func Log(ic *interop.Context) error {
|
||||||
// GetTime returns timestamp of the block being verified, or the latest
|
// GetTime returns timestamp of the block being verified, or the latest
|
||||||
// one in the blockchain if no block is given to Context.
|
// one in the blockchain if no block is given to Context.
|
||||||
func GetTime(ic *interop.Context) error {
|
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
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3,6 +3,7 @@ package runtime
|
||||||
import (
|
import (
|
||||||
"encoding/binary"
|
"encoding/binary"
|
||||||
"errors"
|
"errors"
|
||||||
|
"math/big"
|
||||||
|
|
||||||
"github.com/nspcc-dev/neo-go/pkg/core/interop"
|
"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/core/state"
|
||||||
|
@ -16,9 +17,9 @@ import (
|
||||||
// GasLeft returns remaining amount of GAS.
|
// GasLeft returns remaining amount of GAS.
|
||||||
func GasLeft(ic *interop.Context) error {
|
func GasLeft(ic *interop.Context) error {
|
||||||
if ic.VM.GasLimit == -1 {
|
if ic.VM.GasLimit == -1 {
|
||||||
ic.VM.Estack().PushVal(ic.VM.GasLimit)
|
ic.VM.Estack().PushItem(stackitem.NewBigInteger(big.NewInt(ic.VM.GasLimit)))
|
||||||
} else {
|
} 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
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -55,7 +56,7 @@ func GetNotifications(ic *interop.Context) error {
|
||||||
})
|
})
|
||||||
arr.Append(ev)
|
arr.Append(ev)
|
||||||
}
|
}
|
||||||
ic.VM.Estack().PushVal(arr)
|
ic.VM.Estack().PushItem(arr)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -67,21 +68,21 @@ func GetInvocationCounter(ic *interop.Context) error {
|
||||||
count = 1
|
count = 1
|
||||||
ic.VM.Invocations[currentScriptHash] = count
|
ic.VM.Invocations[currentScriptHash] = count
|
||||||
}
|
}
|
||||||
ic.VM.Estack().PushVal(count)
|
ic.VM.Estack().PushItem(stackitem.NewBigInteger(big.NewInt(int64(count))))
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetNetwork returns chain network number.
|
// GetNetwork returns chain network number.
|
||||||
func GetNetwork(ic *interop.Context) error {
|
func GetNetwork(ic *interop.Context) error {
|
||||||
m := ic.Chain.GetConfig().Magic
|
m := ic.Chain.GetConfig().Magic
|
||||||
ic.VM.Estack().PushVal(uint32(m))
|
ic.VM.Estack().PushItem(stackitem.NewBigInteger(big.NewInt(int64(m))))
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetRandom returns pseudo-random number which depends on block nonce and transaction hash.
|
// GetRandom returns pseudo-random number which depends on block nonce and transaction hash.
|
||||||
func GetRandom(ic *interop.Context) error {
|
func GetRandom(ic *interop.Context) error {
|
||||||
res := murmur128(ic.NonceData[:], ic.Network)
|
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)
|
copy(ic.NonceData[:], res)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,6 +11,7 @@ import (
|
||||||
"github.com/nspcc-dev/neo-go/pkg/smartcontract/callflag"
|
"github.com/nspcc-dev/neo-go/pkg/smartcontract/callflag"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/util"
|
"github.com/nspcc-dev/neo-go/pkg/util"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/vm"
|
"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
|
// CheckHashedWitness checks given hash against current list of script hashes
|
||||||
|
@ -97,6 +98,6 @@ func CheckWitness(ic *interop.Context) error {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to check witness: %w", err)
|
return fmt.Errorf("failed to check witness: %w", err)
|
||||||
}
|
}
|
||||||
ic.VM.Estack().PushVal(res)
|
ic.VM.Estack().PushItem(stackitem.Bool(res))
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,6 +6,7 @@ import (
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"math"
|
"math"
|
||||||
|
"math/big"
|
||||||
"sort"
|
"sort"
|
||||||
|
|
||||||
"github.com/nspcc-dev/neo-go/pkg/core/block"
|
"github.com/nspcc-dev/neo-go/pkg/core/block"
|
||||||
|
@ -44,7 +45,7 @@ func engineGetScriptContainer(ic *interop.Context) error {
|
||||||
default:
|
default:
|
||||||
return errors.New("unknown script container")
|
return errors.New("unknown script container")
|
||||||
}
|
}
|
||||||
ic.VM.Estack().PushVal(item)
|
ic.VM.Estack().PushItem(item)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -72,9 +73,9 @@ func storageGet(ic *interop.Context) error {
|
||||||
key := ic.VM.Estack().Pop().Bytes()
|
key := ic.VM.Estack().Pop().Bytes()
|
||||||
si := ic.DAO.GetStorageItem(stc.ID, key)
|
si := ic.DAO.GetStorageItem(stc.ID, key)
|
||||||
if si != nil {
|
if si != nil {
|
||||||
ic.VM.Estack().PushVal([]byte(si))
|
ic.VM.Estack().PushItem(stackitem.NewByteArray([]byte(si)))
|
||||||
} else {
|
} else {
|
||||||
ic.VM.Estack().PushVal(stackitem.Null{})
|
ic.VM.Estack().PushItem(stackitem.Null{})
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -100,7 +101,7 @@ func storageGetContextInternal(ic *interop.Context, isReadOnly bool) error {
|
||||||
ID: contract.ID,
|
ID: contract.ID,
|
||||||
ReadOnly: isReadOnly,
|
ReadOnly: isReadOnly,
|
||||||
}
|
}
|
||||||
ic.VM.Estack().PushVal(stackitem.NewInterop(sc))
|
ic.VM.Estack().PushItem(stackitem.NewInterop(sc))
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -157,7 +158,7 @@ func storageContextAsReadOnly(ic *interop.Context) error {
|
||||||
}
|
}
|
||||||
stc = stx
|
stc = stx
|
||||||
}
|
}
|
||||||
ic.VM.Estack().PushVal(stackitem.NewInterop(stc))
|
ic.VM.Estack().PushItem(stackitem.NewInterop(stc))
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -210,7 +211,7 @@ func storageFind(ic *interop.Context) error {
|
||||||
|
|
||||||
filteredMap := stackitem.NewMapWithValue(arr)
|
filteredMap := stackitem.NewMapWithValue(arr)
|
||||||
item := istorage.NewIterator(filteredMap, len(prefix), opts)
|
item := istorage.NewIterator(filteredMap, len(prefix), opts)
|
||||||
ic.VM.Estack().PushVal(stackitem.NewInterop(item))
|
ic.VM.Estack().PushItem(stackitem.NewInterop(item))
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -236,7 +237,7 @@ func contractCreateMultisigAccount(ic *interop.Context) error {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
ic.VM.Estack().PushVal(hash.Hash160(script).BytesBE())
|
ic.VM.Estack().PushItem(stackitem.NewByteArray(hash.Hash160(script).BytesBE()))
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -247,12 +248,12 @@ func contractCreateStandardAccount(ic *interop.Context) error {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
ic.VM.Estack().PushVal(p.GetScriptHash().BytesBE())
|
ic.VM.Estack().PushItem(stackitem.NewByteArray(p.GetScriptHash().BytesBE()))
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// contractGetCallFlags returns current context calling flags.
|
// contractGetCallFlags returns current context calling flags.
|
||||||
func contractGetCallFlags(ic *interop.Context) error {
|
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
|
return nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -53,7 +53,7 @@ func Call(ic *interop.Context) error {
|
||||||
}
|
}
|
||||||
result := m.Func(ic, args)
|
result := m.Func(ic, args)
|
||||||
if m.MD.ReturnType != smartcontract.VoidType {
|
if m.MD.ReturnType != smartcontract.VoidType {
|
||||||
ctx.Estack().PushVal(result)
|
ctx.Estack().PushItem(result)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue