2020-06-16 09:04:08 +00:00
|
|
|
package runtime
|
|
|
|
|
|
|
|
import (
|
|
|
|
"github.com/nspcc-dev/neo-go/pkg/core/interop"
|
2020-06-16 09:30:25 +00:00
|
|
|
"github.com/nspcc-dev/neo-go/pkg/core/state"
|
|
|
|
"github.com/nspcc-dev/neo-go/pkg/util"
|
2020-06-16 09:04:08 +00:00
|
|
|
"github.com/nspcc-dev/neo-go/pkg/vm"
|
2020-06-16 09:30:25 +00:00
|
|
|
"github.com/nspcc-dev/neo-go/pkg/vm/stackitem"
|
|
|
|
"github.com/pkg/errors"
|
2020-06-16 09:04:08 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
// GasLeft returns remaining amount of GAS.
|
|
|
|
func GasLeft(_ *interop.Context, v *vm.VM) error {
|
2020-06-23 14:15:35 +00:00
|
|
|
v.Estack().PushVal(v.GasLimit - v.GasConsumed())
|
2020-06-16 09:04:08 +00:00
|
|
|
return nil
|
|
|
|
}
|
2020-06-16 09:30:25 +00:00
|
|
|
|
|
|
|
// GetNotifications returns notifications emitted by current contract execution.
|
|
|
|
func GetNotifications(ic *interop.Context, v *vm.VM) error {
|
|
|
|
item := v.Estack().Pop().Item()
|
|
|
|
notifications := ic.Notifications
|
|
|
|
if _, ok := item.(stackitem.Null); !ok {
|
|
|
|
b, err := item.TryBytes()
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
u, err := util.Uint160DecodeBytesBE(b)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
notifications = []state.NotificationEvent{}
|
|
|
|
for i := range ic.Notifications {
|
|
|
|
if ic.Notifications[i].ScriptHash.Equals(u) {
|
|
|
|
notifications = append(notifications, ic.Notifications[i])
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if len(notifications) > vm.MaxStackSize {
|
|
|
|
return errors.New("too many notifications")
|
|
|
|
}
|
|
|
|
arr := stackitem.NewArray(make([]stackitem.Item, 0, len(notifications)))
|
|
|
|
for i := range notifications {
|
|
|
|
ev := stackitem.NewArray([]stackitem.Item{
|
|
|
|
stackitem.NewByteArray(notifications[i].ScriptHash.BytesBE()),
|
|
|
|
notifications[i].Item,
|
|
|
|
})
|
|
|
|
arr.Append(ev)
|
|
|
|
}
|
|
|
|
v.Estack().PushVal(arr)
|
|
|
|
return nil
|
|
|
|
}
|
2020-06-16 09:47:42 +00:00
|
|
|
|
|
|
|
// GetInvocationCounter returns how many times current contract was invoked during current tx execution.
|
|
|
|
func GetInvocationCounter(ic *interop.Context, v *vm.VM) error {
|
|
|
|
count, ok := ic.Invocations[v.GetCurrentScriptHash()]
|
|
|
|
if !ok {
|
|
|
|
return errors.New("current contract wasn't invoked from others")
|
|
|
|
}
|
|
|
|
v.Estack().PushVal(count)
|
|
|
|
return nil
|
|
|
|
}
|