Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ Changelog for NeoFS Node

### Fixed
- Policer removes redundant local shard copies that could remain on disk forever (#3908)
- Treat only HALTed main transactions as successfully executed, retry the rest (#3868)

### Changed

Expand Down
2 changes: 1 addition & 1 deletion pkg/morph/client/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -317,7 +317,7 @@ func (c *Client) Invoke(ctx context.Context, contract util.Uint160, await, payBy

txHash, vub, err := act.SendTunedCall(contract, method, nil, addFeeCheckerModifier(int64(fee)), args...)
if await {
_, err = conn.rpcActor.Wait(ctx, txHash, vub, err)
_, err = conn.rpcActor.WaitSuccess(ctx, txHash, vub, err)
}
if err != nil {
return fmt.Errorf("could not invoke %s: %w", method, err)
Expand Down
21 changes: 3 additions & 18 deletions pkg/morph/client/notary.go
Original file line number Diff line number Diff line change
Expand Up @@ -366,7 +366,7 @@ func (c *Client) CallWithAlphabetWitness(ctx context.Context, contract util.Uint

c.logNotaryCall(method, vub, mainTx, fbTx)

aer, err := notaryActor.WaitAny(ctx, vub, mainTx, mainTx)
aer, err := notaryActor.WaitAny(ctx, vub, mainTx, fbTx)
if err != nil {
if errors.Is(err, waiter.ErrContextDone) {
return ErrTxAwaitTimeout
Expand All @@ -379,7 +379,7 @@ func (c *Client) CallWithAlphabetWitness(ctx context.Context, contract util.Uint
}

if !aer.VMState.HasFlag(vmstate.Halt) {
return fmt.Errorf("%w: %s", actor.ErrExecFailed, aer.FaultException)
return &neorpc.FaultException{Message: aer.FaultException}
}

return nil
Expand Down Expand Up @@ -484,7 +484,7 @@ func (c *Client) NotarySignAndInvokeTX(mainTx *transaction.Transaction, await bo
retries++
mainH, fbH, untilActual, err = nAct.Notarize(mainTx, nil)
if await {
_, err = nAct.Wait(mainH, fbH, untilActual, err)
_, err = nAct.WaitSuccess(mainH, fbH, untilActual, err)
}
if err != nil {
if alreadyOnChainError(err) {
Expand Down Expand Up @@ -836,21 +836,6 @@ func alreadyOnChainError(err error) bool {
return strings.Contains(err.Error(), alreadyOnChainErrorMessage)
}

// Neo-Go VM (as of v0.117.0) can return different variations of GAS problem
// depending on instruction throwing expeception.
// See https://github.com/nspcc-dev/neo-go/issues/4170.
func insufficientAmountOfGasErr(err error) bool {
if err == nil {
return false
}
msg := err.Error()
return strings.Contains(msg, "insufficient amount of gas") ||
strings.Contains(msg, "gas limit exceeded") ||
strings.Contains(msg, "GAS limit exceeded") ||
strings.Contains(msg, "insufficient gas") ||
strings.Contains(msg, "gas limit is exceeded")
}

// CalculateNotaryDepositAmount calculates notary deposit amount
// using the rule:
//
Expand Down
9 changes: 8 additions & 1 deletion pkg/morph/client/static.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,13 @@ import (
"context"
"errors"
"fmt"
"strings"
"time"

"github.com/cenkalti/backoff/v4"
"github.com/nspcc-dev/neo-go/pkg/encoding/fixedn"
"github.com/nspcc-dev/neo-go/pkg/neorpc"
"github.com/nspcc-dev/neo-go/pkg/rpcclient/actor"
"github.com/nspcc-dev/neo-go/pkg/util"
"github.com/nspcc-dev/neo-go/pkg/vm/stackitem"
"go.uber.org/zap"
Expand Down Expand Up @@ -198,11 +200,16 @@ func (s StaticClient) Invoke(prm InvokePrm) error {
return s.execWithBackoff(invokeFunc)
}

// execWithBackoff retries invokeFunc until it succeeds or until it fails with
// neorpc.ErrMempoolCapReached or neorpc.GASLimitExceededException. Note that if
// invocation fails with the "GAS limit exceeded" error, but the error is not
// wrapped in the corresponding neorpc.FaultException, further attempts will be
// taken.
func (s StaticClient) execWithBackoff(invokeFunc func() error) error {
return backoff.RetryNotify(func() error {
err := invokeFunc()
if err != nil {
if errors.Is(err, neorpc.ErrMempoolCapReached) || insufficientAmountOfGasErr(err) {
if errors.Is(err, neorpc.ErrMempoolCapReached) || errors.Is(err, neorpc.GASLimitExceededException) || (errors.Is(err, actor.ErrExecFailed) && strings.Contains(err.Error(), neorpc.GASLimitExceededException.Message)) {
Comment thread
roman-khimov marked this conversation as resolved.
return err
}
return backoff.Permanent(err)
Expand Down
Loading