-
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
feat: ADR 038 plugin system #11691
feat: ADR 038 plugin system #11691
Changes from all commits
885b45a
00756c7
daed581
fdb450d
5d33e23
a6678a1
bdbeaab
f2306ff
72f213b
3879ae0
283f2c4
6d1944c
98240f5
2421b33
07aaf16
70b3a08
d79f52a
be4bb2a
f21ff7e
222394b
7fd7806
2680478
d86ce53
7f6173a
cdfe1b0
8ed57c4
a20a6f9
0ad44b7
9570199
3c19fdb
6c0530f
63ea30b
7f4ed75
e08fbf7
603dca4
08d6de9
1f2ed49
2bfc803
2625529
af1f9fc
ad670f2
11bc48b
331aa94
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -45,6 +45,8 @@ vagrant | |
# IDE | ||
.idea | ||
*.iml | ||
*.ipr | ||
*.iws | ||
.dir-locals.el | ||
.vscode | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -18,6 +18,13 @@ type ABCIListener interface { | |
ListenEndBlock(ctx types.Context, req abci.RequestEndBlock, res abci.ResponseEndBlock) error | ||
// ListenDeliverTx updates the steaming service with the latest DeliverTx messages | ||
ListenDeliverTx(ctx types.Context, req abci.RequestDeliverTx, res abci.ResponseDeliverTx) error | ||
// HaltAppOnDeliveryError returns true if the application has been configured to halt when | ||
// ListenBeginBlock, ListenEndBlock, ListenDeliverTx fail to process messages and false when | ||
// the application has been configured to send messages to ListenBeginBlock, ListenEndBlock, ListenDeliverTx | ||
// in fire-and-forget fashion. | ||
// | ||
// This behavior is controlled by a corresponding app config setting. | ||
HaltAppOnDeliveryError() bool | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If I understand correctly, implementations of There was a problem hiding this comment. Choose a reason for hiding this commentThe 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 commentThe reason will be displayed to describe this comment to others. Learn more. It seems that There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. :) very true but it's an unclean way of exiting. Also, it will bypass error reporting in the listener methods. We should have the the broader team chime in on this a bit and provide feedback as to how we want plugins to behave in regards to this.
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Sure! Halting an app is (AFAIK) an unclean exit, by definition. I don't think there's any way to reliably issue a "halt" from within the SDK that (a) actually terminates the process, and (b) unwinds the call stack, and captures/logs errors, in a clean and predictable way. Happy to be corrected.
Is the current behavior not correct? What would be more correct? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. my 2 cents is this is a secondary system that should have no effect on the app and consensus. If the indexer is halting the app to not lose data then a different approach needs to be thought of in which it doesn't affect the app. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @marbar3778 - @i-norden and I have had discussions about how a secondary system would work that does not effect the app. However, we agreed to move forward with the current design to allow for time to be able to work through a secondary system design. |
||
} | ||
|
||
// StreamingService interface for registering WriteListeners with the BaseApp and updating the service with the ABCI messages using the hooks | ||
|
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.
Because this goroutine is spawned and executed asynchronously, it's possible that it's scheduled when
app.deliverState
has one value, and executes whenapp.deliverState
has a different value, e.g. representing the next block. This would mean thatListenBeginBlock
will be called with actx
that doesn't correspond to its siblingreq
andres
parameters.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've been debugging an
AppHash
mismatch error when I test the plugins on our provenance blockchain. This is most likely the cause.Our initial thinking here was that we wanted to make calls to multiple listeners asynchronous. I'll test this out with synchronized listeners and report my findings.
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 primary consequence of making listeners synchronous is that slow listeners can impact node liveness. If HaltAppOnDeliveryError is true, then users are explicitly opting in to this risk, so it's (arguably) OK there. But if that setting is false, then I think it would be a mistake to make delivery synchronous.
The solution here is to produce the complete event when this method is called, and emit that event value to listeners. The event value would need to contain only plain-old-data, i.e. no pointers or references to anything else in the node or app or etc.
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 tested this and it is not the cause of the
AppHash
error I see on a two node localnet. I disabled all the listeners in abci.go (thinking this was the cause) and I was able to narrow it down to either the Inject() or Start() as the cause. When you turn on the plugin system and enable any plugin it will result in anAppHash
error. I also used the iaveiwer tool but didn't see any differences in the iAVL tree. This leads me to think the state change is happening at runtime before it's persisted.Something like.
@i-norden ^^^ perhaps you can take a look at the plugin system and maybe find what is changing the app state.
I agree ^^^. I was testing to see if asynchronous vs synchronous listeners was the cause for my
AppHash
error above. We'll also need to pass in any addition info required to keep track of what block is being emitted etc.so the new listener interface could look like this?
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.
An ABCIListener interface should
context.Context
as a first parameter, and respect context cancellationlog.Logger
it needs, and therefore not take a logger as a parametera. Halt the app directly via os.Exit or panic or whatever, or
b. Signal that information via return error from each method, detected by the caller via errors.Is/As