-
Notifications
You must be signed in to change notification settings - Fork 3.6k
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
ADR 022 - Custom baseapp panic handling #6072
Conversation
Codecov Report
@@ Coverage Diff @@
## master #6072 +/- ##
==========================================
- Coverage 54.64% 54.39% -0.25%
==========================================
Files 426 430 +4
Lines 25890 26106 +216
==========================================
+ Hits 14148 14201 +53
- Misses 10763 10922 +159
- Partials 979 983 +4 |
I think we should allow more customizability of these sorts of things in general. The approach in #6053 handles one such case and I don't think we should block it. But I do think we should reconsider a composable middleware approach to BaseApp, rather than handling each edge case one by one. |
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.
Thanks @iTiky! Left some minor feedback.
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.
Well written ADR. Left a few suggestions. Thanks @iTiky! 👍
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 took another pass through over this ADR and things started to make more sense to me. I think certain sections can be either clarified or omitted entirely. But overall, the premise looks solid and I see no reason why we can't support this.
One thing I would like note (I've mentioned this in a comment), is that we should guarantee or assert that the last handler in the decorator/middleware stack is guaranteed to return an error -- a fail-safe/terminator.
Co-Authored-By: Alexander Bezobchuk <alexanderbez@users.noreply.github.com>
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.
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.
Concept ACK but I would like to see more clearly explained examples
might be handled in a "standard" way (middleware) alongside the others. | ||
|
||
We propose middleware-solution, which could help developers implement the following cases: | ||
* add external logging (let's say sending reports to external services like [Sentry](https://sentry.io)); |
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 do not understand how this would work. Would every node make an HTTP call to Sentry?
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.
Those are examples of how developers can use those middlewares. They can send panic logs to Sentry if they need to or do other struf needed.
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 still don't understand how Sentry would be used in a replicated state machine.
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.
Those are just examples of what developers of Cosmos SDK based project could use those handlers for. May be they want to get notifications on every panic()
event (Sentry), that doesn't collide with state machine ideology.
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.
The issue is that (in a production blockchain) the state machine is replicated, so many copies of every error would be sent to Sentry, and you would need to be careful to ensure that making HTTP requests doesn't introduce non-determinism. It's an alright example, but these points need to be clarified.
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.
Actually Sentry can aggregate multiple similar event into one issue with some meta and statistics. As for non-deterministic behavior: developers can do that in so many ways including the proposed middlewares =)
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.
That's nice. The determinism bit is more important. I think it would be sufficient if we add a warning that middlewares must be deterministic, or consensus safety will be lost.
// ... | ||
defer func() { | ||
if r := recover(); r != nil { | ||
recoveryMW := newOutOfGasRecoveryMiddleware(gasWanted, ctx, app.runTxRecoveryMiddleware) |
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.
Why are we hard-coding newOutOfGasRecoveryMiddleware
into BaseApp
? I thought the idea was to defer to app.runTxRecoveryMiddleware
?
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.
That is because OutOfGas
error handling needs some extra context and can't be statically created.
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.
Generally I'm in favor of well-reasoned customizability. As I noted before, I would like us to think of a more general framework for BaseApp
being composed of middleware in the future.
But, this seems like a good starting point with a concrete use case and I'd like to see it move forward.
Co-Authored-By: Federico Kunze <31522760+fedekunze@users.noreply.github.com>
Co-Authored-By: Federico Kunze <31522760+fedekunze@users.noreply.github.com>
Co-Authored-By: Federico Kunze <31522760+fedekunze@users.noreply.github.com>
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.
ACK
func newOutOfGasRecoveryMiddleware(gasWanted uint64, ctx sdk.Context, next recoveryMiddleware) recoveryMiddleware { | ||
handler := func(recoveryObj interface{}) error { | ||
err, ok := recoveryObj.(sdk.ErrorOutOfGas) | ||
if !ok { return nil } |
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.
Should middleware decorators simply pass recoveryObj
along to the next middleware if it isn't an error they handle instead of returning?
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.
Actually they do. The example above creates a handler
and passes it to func newRecoveryMiddleware
which creates a middleware. That way developer only needs to create a RecoveryHandler
(which only return an error
/ nil
). The rest is done with helper functions automatically.
@alexanderbez ADR's PR is approved, what are the next steps? I can update the implementation PR (add link to the ADR, make some minor improvements proposed in the discussion). |
@iTiky, yes let's update this PR so we can merge it and then we can proceed with reviewing the implementation 👍 Thank you for all the hard work :) |
Looks like the main thing needed to move this forward is merging master into this branch. @iTiky can you do that and then we'll merge. |
@alexanderbez Can we merge this ADR as it breaks the markdown analyser for PR (invalid link to the ADR file). |
Yes, we just need to rebase 👍 |
Something did not go right in the rebase @iTiky |
@alexanderbez Yes, you're right. Can I just close this PR and make a new cleaner one preserving all changes? I'm not sure I can do the force push right. |
I don't think that is necessary. Revert back to 35fc451, checkout and pull latest |
@alexanderbez Thanks! I did the rollback and merged the latest master. |
/cc @alexanderbez
For contributor use:
docs/
) or specification (x/<module>/spec/
)godoc
comments.Unreleased
section inCHANGELOG.md
Files changed
in the Github PR explorerFor admin use:
WIP
,R4R
,docs
, etc)