forked from TrueCloudLab/neoneo-go
Merge pull request #1874 from nspcc-dev/fix-states-diff
vm: minor C# compatibility fixes
This commit is contained in:
commit
218fa70eb9
3 changed files with 28 additions and 4 deletions
|
@ -52,11 +52,11 @@ func GetTrigger(ic *interop.Context) error {
|
||||||
// in neo-go the only meaningful thing to do here is to log.
|
// in neo-go the only meaningful thing to do here is to log.
|
||||||
func Notify(ic *interop.Context) error {
|
func Notify(ic *interop.Context) error {
|
||||||
name := ic.VM.Estack().Pop().String()
|
name := ic.VM.Estack().Pop().String()
|
||||||
|
elem := ic.VM.Estack().Pop()
|
||||||
|
args := elem.Array()
|
||||||
if len(name) > MaxEventNameLen {
|
if len(name) > MaxEventNameLen {
|
||||||
return fmt.Errorf("event name must be less than %d", MaxEventNameLen)
|
return fmt.Errorf("event name must be less than %d", MaxEventNameLen)
|
||||||
}
|
}
|
||||||
elem := ic.VM.Estack().Pop()
|
|
||||||
args := elem.Array()
|
|
||||||
// But it has to be serializable, otherwise we either have some broken
|
// But it has to be serializable, otherwise we either have some broken
|
||||||
// (recursive) structure inside or an interop item that can't be used
|
// (recursive) structure inside or an interop item that can't be used
|
||||||
// outside of the interop subsystem anyway.
|
// outside of the interop subsystem anyway.
|
||||||
|
|
|
@ -142,7 +142,7 @@ func TestNotify(t *testing.T) {
|
||||||
return ic
|
return ic
|
||||||
}
|
}
|
||||||
t.Run("big name", func(t *testing.T) {
|
t.Run("big name", func(t *testing.T) {
|
||||||
ic := newIC(string(make([]byte, MaxEventNameLen+1)), []byte{42})
|
ic := newIC(string(make([]byte, MaxEventNameLen+1)), stackitem.NewArray([]stackitem.Item{stackitem.Null{}}))
|
||||||
require.Error(t, Notify(ic))
|
require.Error(t, Notify(ic))
|
||||||
})
|
})
|
||||||
t.Run("recursive struct", func(t *testing.T) {
|
t.Run("recursive struct", func(t *testing.T) {
|
||||||
|
|
26
pkg/vm/vm.go
26
pkg/vm/vm.go
|
@ -1304,7 +1304,7 @@ func (v *VM) execute(ctx *Context, op opcode.Opcode, parameter []byte) (err erro
|
||||||
interopID := GetInteropID(parameter)
|
interopID := GetInteropID(parameter)
|
||||||
err := v.SyscallHandler(v, interopID)
|
err := v.SyscallHandler(v, interopID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(fmt.Sprintf("failed to invoke syscall: %s", err))
|
panic(fmt.Sprintf("failed to invoke syscall %d: %s", interopID, err))
|
||||||
}
|
}
|
||||||
|
|
||||||
case opcode.RET:
|
case opcode.RET:
|
||||||
|
@ -1602,8 +1602,32 @@ func (v *VM) handleException() {
|
||||||
}
|
}
|
||||||
pop++
|
pop++
|
||||||
ictxv = ictxv.Next()
|
ictxv = ictxv.Next()
|
||||||
|
if ictxv == nil {
|
||||||
|
break
|
||||||
|
}
|
||||||
ictx = ictxv.Value().(*Context)
|
ictx = ictxv.Value().(*Context)
|
||||||
}
|
}
|
||||||
|
throwUnhandledException(v.uncaughtException)
|
||||||
|
}
|
||||||
|
|
||||||
|
// throwUnhandledException gets exception message from the provided stackitem and panics.
|
||||||
|
func throwUnhandledException(item stackitem.Item) {
|
||||||
|
msg := "unhandled exception"
|
||||||
|
switch item.Type() {
|
||||||
|
case stackitem.ArrayT:
|
||||||
|
if arr := item.Value().([]stackitem.Item); len(arr) > 0 {
|
||||||
|
data, err := arr[0].TryBytes()
|
||||||
|
if err == nil {
|
||||||
|
msg = fmt.Sprintf("%s: %q", msg, string(data))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
data, err := item.TryBytes()
|
||||||
|
if err == nil {
|
||||||
|
msg = fmt.Sprintf("%s: %q", msg, string(data))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
panic(msg)
|
||||||
}
|
}
|
||||||
|
|
||||||
// CheckMultisigPar checks if sigs contains sufficient valid signatures.
|
// CheckMultisigPar checks if sigs contains sufficient valid signatures.
|
||||||
|
|
Loading…
Reference in a new issue