diff --git a/internal/blockchain/ethereum/ethereum.go b/internal/blockchain/ethereum/ethereum.go index afa3c2c06..5ece3a219 100644 --- a/internal/blockchain/ethereum/ethereum.go +++ b/internal/blockchain/ethereum/ethereum.go @@ -77,6 +77,7 @@ type Ethereum struct { ethconnectConf config.Section subs common.FireflySubscriptions cache cache.CInterface + count int } type eventStreamWebsocket struct { @@ -147,6 +148,7 @@ func (e *Ethereum) Init(ctx context.Context, cancelCtx context.CancelFunc, conf e.capabilities = &blockchain.Capabilities{} e.callbacks = common.NewBlockchainCallbacks() e.subs = common.NewFireflySubscriptions() + e.count = 0 if addressResolverConf.GetString(AddressResolverURLTemplate) != "" { // Check if we need to invoke the address resolver (without caching) on every call @@ -623,8 +625,12 @@ func (e *Ethereum) invokeContractMethod(ctx context.Context, address, signingKey SetBody(body). SetError(&resErr). Post("/") - if err != nil || !res.IsSuccess() { - return resErr.SubmissionRejected, common.WrapRESTError(ctx, &resErr, res, err, coremsgs.MsgEthConnectorRESTErr) + log.L(ctx).Infof("count %d", e.count) + if err != nil || !res.IsSuccess() || e.count == 0 { + e.count = 1 + wrapErr := common.WrapRESTError(ctx, &resErr, res, err, coremsgs.MsgEthConnectorRESTErr) + log.L(ctx).Errorf("forced ethereum invokeContractMethod: %s", wrapErr) + return resErr.SubmissionRejected, wrapErr } return false, nil } diff --git a/internal/operations/manager.go b/internal/operations/manager.go index 27e67c5dc..ccd4b6ec2 100644 --- a/internal/operations/manager.go +++ b/internal/operations/manager.go @@ -182,6 +182,8 @@ func (om *operationsManager) RunOperation(ctx context.Context, op *core.Prepared // So this is safe failState = core.OpStatusPending log.L(ctx).Infof("Setting operation %s operation %s status to %s after conflict", op.Type, op.ID, failState) + // clear error so we're not infinitely retrying + err = nil case phase == core.OpPhaseInitializing && idempotentSubmit: // We haven't submitted the operation yet - so we will reuse the operation if the user retires with the same idempotency key failState = core.OpStatusInitialized @@ -193,13 +195,17 @@ func (om *operationsManager) RunOperation(ctx context.Context, op *core.Prepared // Ok, we're failed failState = core.OpStatusFailed } - om.SubmitOperationUpdate(&core.OperationUpdate{ + opUpdate := &core.OperationUpdate{ NamespacedOpID: op.NamespacedIDString(), Plugin: op.Plugin, Status: failState, - ErrorMessage: err.Error(), Output: outputs, - }) + } + if err != nil { + opUpdate.ErrorMessage = err.Error() + } + + om.SubmitOperationUpdate(opUpdate) } else { // No error so move us from "Initialized" to "Pending" newState := core.OpStatusPending