Git Product home page Git Product logo

Comments (10)

peterbroadhurst avatar peterbroadhurst commented on July 24, 2024 2

ok - thanks all.

I'm happy to stick with proposal 1:

  • We spend the idempotencyKey
  • Operation goes to Failed status

Given great input from @awrichar and @Chengxuan above, I propose returning retryable: false as an explicit JSON payload in the body of the error that flows back.

Note that the default will be true if retryable is omitted from the JSON, or is null.

I will begin by implementing this in FFTM, and the ethereum plugin in Core.

I observe that the HTTP transport is actually one-level detached from the code contract between core and connectors, as the plugin code in Go is responsible for the mapping. So the above expresses a convention, rather than a hard requirement.

I did read the suggestion on a HTTP Header, but I believe currently got a contract being in the body of the response payload (for propagating error codes) and I think it makes sense to extend that with another parameter.

from firefly.

peterbroadhurst avatar peterbroadhurst commented on July 24, 2024

Proposal 1

I believe it is a more obvious and explainable behavior, if these situations were to instead immediately transition an operation to Failed status - re-instating the behavior before #1406.

However, that the connector must be responsible for reporting that the nature of the failure to accept the transaction is a Reject of the transaction, rather than a temporary condition.

That will be a complex per-connector decision.
In this specific case in EVMConnect:

  • The eth_estimateGas operation returned an error from the blockchain node JSON/RPC interface
  • The "Revert reason" was successfully extracted from the response, so we are confident the issue is not transient (if it were transient, it would be retryable and we would want the app to be able to re-submit with the idempotencyKey)

image

sequence diagram source

from firefly.

nguyer avatar nguyer commented on July 24, 2024

I like the general idea of the "Proposed" solution. One question would be whether it should return 500 or 400 after it updates the status to Failed, indicating that it is not a retryable error.

from firefly.

peterbroadhurst avatar peterbroadhurst commented on July 24, 2024

I like the idea of the spelling of "Reject" being returning HTTP Status code 400 👍

from firefly.

peterbroadhurst avatar peterbroadhurst commented on July 24, 2024

Actually, I wonder if there is a tweak here @nguyer - to your great point. That we should propagate the 400 all the way back to the application, and instead of leaving the transaction in Initializing status, we should remove the record before returning the 400. I'll do a tweaked sequence diagram for this, for us to consider.

from firefly.

peterbroadhurst avatar peterbroadhurst commented on July 24, 2024

Counter proposal (2)

NOTE: Eliminated in favor of proposal 1 - see below

image

sequence diagram source

from firefly.

Chengxuan avatar Chengxuan commented on July 24, 2024

Greate diagrams @peterbroadhurst 🎉

I like the spelling of "Reject" being returning HTTP Status code 400, may want to make the HTTP status code a list.

Below is my reasoning:

Regarding the logic to decide whether an error from a connector is retry-able, I see the following options:

  • introduce a new mechanism that requires code changes in connectors to explicitly opt-in for all situations (delegate the decision-making to the connectors)
  • introduce an implicit contract/assumption/convention in Firefly to do the decision-making itself and optionally connectors can update their code to embrace this convention

For the first option, one solution is introducing an HTTP response header for connectors to include when the error is non-retryable.

For the second option:

the spelling of "Reject" being returning HTTP Status code 400

This is an example of implicit contract/assumption/convention

For this specific error case ((EVM reverted due to "bad" input param), treat 400 (one of the HTTP client error codes) as non-retryable error does solve it nicely.

I'm not so sure about other error cases. As we are putting a constraint on which HTTP error code (400) can be returned for initialization failure, this forces connectors to use 400 for all the non-retryable errors that might be better represented using other HTTP error codes. (e.g. 409, 413). Also, an error code like 413 can be a tricky one to override as it's often handled by HTTP middleware.

But it has a big advantage of less code change in the connectors and it can co-exist with solutions for the first option in the future (if we ever need one). 👍

from firefly.

awrichar avatar awrichar commented on July 24, 2024

I would lean toward the first proposal, where we move the operation to "failed" state if the gas estimation fails. As you said, this was the previous behavior, and I think it makes sense.

The second proposal, where we actually delete the operation and all evidence of it, seems to be a pretty significant change to FireFly's behavior. I think it would be odd for the operation to exist for a few seconds and then not exist later.

On the choice of error codes... it seems like it should be HTTP 400 or 500. I think 400 makes sense if we can reasonably deduce that the request was invalid for some reason, which I do think is the general case being considered here.

from firefly.

peterbroadhurst avatar peterbroadhurst commented on July 24, 2024

The default-true semantics felt error-prone, so I have actually gone for submissionRejected: true as the API spelling in the FFTM layer.

from firefly.

peterbroadhurst avatar peterbroadhurst commented on July 24, 2024

All of the changes, including the new E2E test in core, and releases of FFTM and EVMConnect, have been individually reviewed and are in mainline.

from firefly.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.