forked from TrueCloudLab/neoneo-go
vm: wrap cross-contract exceptions
This commit is contained in:
parent
a39b7cc3fd
commit
a79c80cb8d
2 changed files with 11 additions and 4 deletions
|
@ -85,12 +85,12 @@ func callInternal(ic *interop.Context, cs *state.Contract, name string, f callfl
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return callExFromNative(ic, ic.VM.GetCurrentScriptHash(), cs, name, args, f, hasReturn, pushNullOnUnloading)
|
return callExFromNative(ic, ic.VM.GetCurrentScriptHash(), cs, name, args, f, hasReturn, pushNullOnUnloading, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
// callExFromNative calls a contract with flags using the provided calling hash.
|
// callExFromNative calls a contract with flags using the provided calling hash.
|
||||||
func callExFromNative(ic *interop.Context, caller util.Uint160, cs *state.Contract,
|
func callExFromNative(ic *interop.Context, caller util.Uint160, cs *state.Contract,
|
||||||
name string, args []stackitem.Item, f callflag.CallFlag, hasReturn bool, pushNullOnUnloading bool) error {
|
name string, args []stackitem.Item, f callflag.CallFlag, hasReturn bool, pushNullOnUnloading bool, callFromNative bool) error {
|
||||||
for _, nc := range ic.Natives {
|
for _, nc := range ic.Natives {
|
||||||
if nc.Metadata().Name == nativenames.Policy {
|
if nc.Metadata().Name == nativenames.Policy {
|
||||||
var pch = nc.(policyChecker)
|
var pch = nc.(policyChecker)
|
||||||
|
@ -140,6 +140,9 @@ func callExFromNative(ic *interop.Context, caller util.Uint160, cs *state.Contra
|
||||||
if pushNullOnUnloading && commit {
|
if pushNullOnUnloading && commit {
|
||||||
ic.VM.Context().Estack().PushItem(stackitem.Null{}) // Must use current context stack.
|
ic.VM.Context().Estack().PushItem(stackitem.Null{}) // Must use current context stack.
|
||||||
}
|
}
|
||||||
|
if callFromNative && !commit {
|
||||||
|
return fmt.Errorf("unhandled exception")
|
||||||
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
ic.VM.LoadNEFMethod(&cs.NEF, caller, cs.Hash, f,
|
ic.VM.LoadNEFMethod(&cs.NEF, caller, cs.Hash, f,
|
||||||
|
@ -157,7 +160,7 @@ var ErrNativeCall = errors.New("failed native call")
|
||||||
// CallFromNative performs synchronous call from native contract.
|
// CallFromNative performs synchronous call from native contract.
|
||||||
func CallFromNative(ic *interop.Context, caller util.Uint160, cs *state.Contract, method string, args []stackitem.Item, hasReturn bool) error {
|
func CallFromNative(ic *interop.Context, caller util.Uint160, cs *state.Contract, method string, args []stackitem.Item, hasReturn bool) error {
|
||||||
startSize := ic.VM.Istack().Len()
|
startSize := ic.VM.Istack().Len()
|
||||||
if err := callExFromNative(ic, caller, cs, method, args, callflag.All, hasReturn, false); err != nil {
|
if err := callExFromNative(ic, caller, cs, method, args, callflag.All, hasReturn, false, true); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1595,7 +1595,11 @@ func (v *VM) unloadContext(ctx *Context) {
|
||||||
if ctx.onUnload != nil {
|
if ctx.onUnload != nil {
|
||||||
err := ctx.onUnload(v.uncaughtException == nil)
|
err := ctx.onUnload(v.uncaughtException == nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(fmt.Errorf("context unload callback failed: %w", err))
|
errMessage := fmt.Sprintf("context unload callback failed: %s", err)
|
||||||
|
if v.uncaughtException != nil {
|
||||||
|
errMessage = fmt.Sprintf("%s, uncaught exception: %s", errMessage, v.uncaughtException)
|
||||||
|
}
|
||||||
|
panic(errors.New(errMessage))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue