-
Notifications
You must be signed in to change notification settings - Fork 302
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
fix(contract-client): timeout & retry logic #919
Conversation
f072c51
to
ac5545b
Compare
@Shaptic thanks! I'm not sure how exactly to clean up the retry logic, actually. Maybe you could help give some pointers? About a month ago, I learned from Tyler van der Hoeven that the rebuild/resign/resend logic is not so great, but I forget what the ideas were for improving it. Here's the current
Or, as a flow chart: graph TD;
A[Start: Attempt sendTransaction] --> B{Status == PENDING?};
B -- No --> C[Rebuild transaction, increment sequenceNumber & request new signature];
C --> D[Retry with exponential backoff];
D --> B;
B -- Yes --> E[Save as sendTransactionResponseAll];
E --> F{Did final sendTransaction have status == PENDING?};
F -- No --> G[🛑 oh no];
F -- Yes --> H[Attempt getTransaction using hash from sendTransactionResult];
H --> I{Status == NOT_FOUND?};
I -- Yes --> J[Retry with exponential backoff];
J --> I;
I -- No --> K[Continue];
K --> L{Final attempt status == NOT_FOUND?};
L -- Yes --> M[🛑 oh no];
L -- No --> N[Return SentTransaction];
If GitHub refuses to render that, you can view it at https://www.mermaidchart.com/raw/10719cfd-0a10-45c4-b58b-5fe2e3cbdd38?theme=dark&version=v0.1&format=svg |
If you want to merge this one as-is, I can clean up the retry logic in a follow-up |
Thank you for the breakdown!! Both explanations are super helpful. As a prerequisite, I hope you've read the error-handling guide which covers a lot of nuances. With that in mind, here are some thoughts:
Do you differentiate between recoverable and non-recoverable errors? For example, fees vs. seqnum issues. Also let's try to keep the whole "signer-agnostic" thing in mind in the "request new signature" bit (like the generic
Is the amount of time or retries user-controlled?
For
Does this include the also cc @kalepail for his thoughts! |
/** | ||
* The maximum amount of time to wait for the transaction to complete. Default: {@link DEFAULT_TIMEOUT} | ||
*/ | ||
timeoutInSeconds?: number; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can we make this required rather than have a default?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would way rather have a default! That way you don't need to include a second options object on every call. If we make it required, every function call from the generated Contract Clients would look like this:
await myContract.myMethod(
{ args: 'for', my: 'method', ... },
{ timeoutInSeconds: 10 }
)
Do you think this is important enough to bring to people's attention that we should uglify every method call in this way, or do you think there's a good-enough default?
no more
TimeoutInfinite