diff --git a/CHANGELOG.md b/CHANGELOG.md index e1ffe15b25..2174caa93c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,7 @@ Changelog for NeoFS Node - Resending the header after chunks have already been sent in object service `Get` handler (#3833) - GC deadlock on local object storage shutdown (#3837) - `owner mismatches signature` for stored objects (#3836) +- SN does not retry resending failed transaction because of insufficient GAS in some cases (#3839) ### Changed - SN returns unsigned responses to requests with API >= `v2.22` (#3785) diff --git a/pkg/morph/client/notary.go b/pkg/morph/client/notary.go index 0cc9e5827d..abde51cde1 100644 --- a/pkg/morph/client/notary.go +++ b/pkg/morph/client/notary.go @@ -836,6 +836,21 @@ 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: // diff --git a/pkg/morph/client/static.go b/pkg/morph/client/static.go index d4806186ab..33452d9fe1 100644 --- a/pkg/morph/client/static.go +++ b/pkg/morph/client/static.go @@ -4,7 +4,6 @@ import ( "context" "errors" "fmt" - "strings" "time" "github.com/cenkalti/backoff/v4" @@ -203,8 +202,7 @@ func (s StaticClient) execWithBackoff(invokeFunc func() error) error { return backoff.RetryNotify(func() error { err := invokeFunc() if err != nil { - if errors.Is(err, neorpc.ErrMempoolCapReached) || - strings.Contains(err.Error(), "insufficient amount of gas") { + if errors.Is(err, neorpc.ErrMempoolCapReached) || insufficientAmountOfGasErr(err) { return err } return backoff.Permanent(err)