Skip to content
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

feat(entropy): Add callback failure states to the contract #2546

Merged
merged 10 commits into from
Apr 4, 2025

Conversation

jayantk
Copy link
Contributor

@jayantk jayantk commented Apr 2, 2025

Summary

Currently, the Entropy keeper cannot invoke a callback if the underlying callback fails. This creates confusion for users, who can't distinguish between "the keeper is offline" and "my callback code reverts".

This change creates a failure flow for callbacks that allows the keeper's transaction to succeed while explicitly reporting a failure of the underlying callback. Requests with failing callbacks remain on the blockchain and can be re-invoked by users. This feature allows users to gracefully recover in cases where the callback fails for transient reasons. (In the future, it will also allow recovery in the case where the callback uses too much gas.)

Note that this PR doesn't cover the case where the callback uses too much gas. I will send a follow-up PR for that.

How has this been tested?

  • Current tests cover my changes
  • Added new tests
  • Manually tested the code

@jayantk jayantk requested a review from a team as a code owner April 2, 2025 16:59
Copy link

vercel bot commented Apr 2, 2025

The latest updates on your projects. Learn more about Vercel for Git ↗︎

Name Status Preview Comments Updated (UTC)
proposals ✅ Ready (Inspect) Visit Preview 💬 Add feedback Apr 3, 2025 6:52pm
staking ✅ Ready (Inspect) Visit Preview 💬 Add feedback Apr 3, 2025 6:52pm
4 Skipped Deployments
Name Status Preview Comments Updated (UTC)
api-reference ⬜️ Ignored (Inspect) Visit Preview Apr 3, 2025 6:52pm
component-library ⬜️ Ignored (Inspect) Visit Preview Apr 3, 2025 6:52pm
entropy-debugger ⬜️ Ignored (Inspect) Visit Preview Apr 3, 2025 6:52pm
insights ⬜️ Ignored (Inspect) Visit Preview Apr 3, 2025 6:52pm

// any reverts will be reported as an event. Any failing requests move to a failure state
// at which point they can be recovered. The recovery flow invokes the callback directly
// (no catching errors) which allows callers to easily see the revert reason.
if (req.status == EntropyConstants.STATUS_CALLBACK_NOT_STARTED) {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note that this is a behavior change at the moment. This means that we won't be able to upgrade the contracts without upgrading the keeper.

However, in the next PR I will additionally condition this on the request having a gas limit, which means that the contract will be 100% backward compatible. (i.e., you don't get the failure flow until the provider explicitly sets a gas limit for callbacks)

@@ -938,12 +939,13 @@ contract EntropyTest is Test, EntropyTestUtils, EntropyEvents {
);
}

// TODO: restore this test once providers have custom gas limits, which allow us to toggle between
// the old and new failure behavior.
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(restoring this test will ensure backward compatibility of the flow, per the comment above)

bool isRequestWithCallback;
// There are 2 remaining bytes of free space in this slot.
// Status flag for requests with callbacks. See EntropyConstants for the possible values of this flag.
uint8 status;
Copy link
Contributor Author

@jayantk jayantk Apr 2, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(bools are internally represented as uint8 so this is a compatible change. I'm reusing this flag because I want the remaining 2 bytes for the gas limit)

library EntropyConstants {
// Status values for Request.status //
// not a request with callback
uint8 public constant STATUS_NO_CALLBACK = 0;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

how about naming the library EntropyStatusConstants and remove the STATUS_ prefix here?

library EntropyConstants {
// Status values for Request.status //
// not a request with callback
uint8 public constant STATUS_NO_CALLBACK = 0;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the name of this variant is a bit confusing. Maybe something like uninitialized?

bool isRequestWithCallback;
// There are 2 remaining bytes of free space in this slot.
// Status flag for requests with callbacks. See EntropyConstants for the possible values of this flag.
uint8 status;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe name this callback_status?

bool success;
bytes memory ret;
(success, ret) = callAddress.excessivelySafeCall(
gasleft(), // TODO: providers need to be able to configure this in the future.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this actually needs to be exactly what the requester asked for and not what provider specifyes

);
req.status = EntropyConstants.STATUS_CALLBACK_FAILED;
} else {
// The callback ran out of gas
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think there are other failure scenarios where ret.length is 0.

@jayantk jayantk merged commit f841dfc into main Apr 4, 2025
10 checks passed
@jayantk jayantk deleted the entropy_error2 branch April 4, 2025 14:15
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants