From 4a4aee82e0e23712f81c0e69c4dfa0c5864fb7fd Mon Sep 17 00:00:00 2001 From: Pavel Karpy Date: Fri, 9 Apr 2021 23:10:59 +0300 Subject: [PATCH] [#474] morph/client: Add FaultException to error msg If non-"HALT" `State` occurs after calling `InvokeFunction` NeoGo client method, add `FaultException` information to returning error. Add returning state check to `NotaryInvoke` method of the morph/client. Signed-off-by: Pavel Karpy --- pkg/morph/client/client.go | 15 ++++++++++++++- pkg/morph/client/notary.go | 5 +++++ 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/pkg/morph/client/client.go b/pkg/morph/client/client.go index 6587d5dec..4e7978470 100644 --- a/pkg/morph/client/client.go +++ b/pkg/morph/client/client.go @@ -2,6 +2,7 @@ package client import ( "context" + "fmt" "time" "github.com/nspcc-dev/neo-go/pkg/core/native/noderoles" @@ -48,6 +49,18 @@ var ErrNilClient = errors.New("client is nil") // HaltState returned if TestInvoke function processed without panic. const HaltState = "HALT" +type NotHaltStateError struct { + state, exception string +} + +func (e *NotHaltStateError) Error() string { + return fmt.Sprintf( + "chain/client: contract execution finished with state %s; exception: %s", + e.state, + e.exception, + ) +} + var errEmptyInvocationScript = errors.New("got empty invocation script from neo node") var errScriptDecode = errors.New("could not decode invocation script from neo node") @@ -132,7 +145,7 @@ func (c *Client) TestInvoke(contract util.Uint160, method string, args ...interf } if val.State != HaltState { - return nil, errors.Errorf("chain/client: contract execution finished with state %s", val.State) + return nil, &NotHaltStateError{state: val.State, exception: val.FaultException} } return val.Stack, nil diff --git a/pkg/morph/client/notary.go b/pkg/morph/client/notary.go index b55f8cae0..65e3b1f45 100644 --- a/pkg/morph/client/notary.go +++ b/pkg/morph/client/notary.go @@ -222,6 +222,11 @@ func (c *Client) notaryInvoke(committee bool, contract util.Uint160, method stri return err } + // check invocation state + if test.State != HaltState { + return &NotHaltStateError{state: test.State, exception: test.FaultException} + } + // if test invocation failed, then return error if len(test.Script) == 0 { return errEmptyInvocationScript