2020-07-27 08:06:06 +00:00
|
|
|
package callback
|
|
|
|
|
|
|
|
import (
|
|
|
|
"errors"
|
|
|
|
|
|
|
|
"github.com/nspcc-dev/neo-go/pkg/core/interop"
|
2020-08-13 07:41:33 +00:00
|
|
|
"github.com/nspcc-dev/neo-go/pkg/core/interop/interopnames"
|
2020-07-27 08:06:06 +00:00
|
|
|
"github.com/nspcc-dev/neo-go/pkg/vm"
|
|
|
|
"github.com/nspcc-dev/neo-go/pkg/vm/stackitem"
|
|
|
|
)
|
|
|
|
|
|
|
|
// Callback is an interface for arbitrary callbacks.
|
|
|
|
type Callback interface {
|
|
|
|
// ArgCount returns expected number of arguments.
|
|
|
|
ArgCount() int
|
|
|
|
// LoadContext loads context and arguments on stack.
|
|
|
|
LoadContext(*vm.VM, []stackitem.Item)
|
|
|
|
}
|
|
|
|
|
|
|
|
// Invoke invokes provided callback.
|
2020-08-07 11:37:49 +00:00
|
|
|
func Invoke(ic *interop.Context) error {
|
|
|
|
cb := ic.VM.Estack().Pop().Interop().Value().(Callback)
|
|
|
|
args := ic.VM.Estack().Pop().Array()
|
2020-07-27 08:06:06 +00:00
|
|
|
if cb.ArgCount() != len(args) {
|
|
|
|
return errors.New("invalid argument count")
|
|
|
|
}
|
2020-08-07 11:37:49 +00:00
|
|
|
cb.LoadContext(ic.VM, args)
|
2020-07-28 10:17:38 +00:00
|
|
|
switch t := cb.(type) {
|
2020-07-27 09:23:48 +00:00
|
|
|
case *MethodCallback:
|
2020-08-13 07:41:33 +00:00
|
|
|
id := interopnames.ToID([]byte("System.Contract.Call"))
|
2020-08-07 11:37:49 +00:00
|
|
|
return ic.SyscallHandler(ic.VM, id)
|
2020-07-28 10:17:38 +00:00
|
|
|
case *SyscallCallback:
|
2020-08-07 11:37:49 +00:00
|
|
|
return ic.SyscallHandler(ic.VM, t.desc.ID)
|
2020-07-27 09:23:48 +00:00
|
|
|
default:
|
|
|
|
return nil
|
|
|
|
}
|
2020-07-27 08:06:06 +00:00
|
|
|
}
|