-
Notifications
You must be signed in to change notification settings - Fork 298
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: support gRPC endpoints in core #1513
Conversation
Just found out that once we enable the app grpc, these endpoints get overridden, I'll be looking into it |
This reverts commit 072b5eb.
// SubscriptionCapacity the maximum number of pending blocks in the subscription. | ||
const SubscriptionCapacity = 500 | ||
|
||
func (blockAPI *BlockAPI) retryNewBlocksSubscription(ctx context.Context) (bool, error) { |
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.
[question][nit] what does the bool return argument indicate? It seems like (isSuccess bool, err error)
IMO the bool argument is unnecessary b/c either this function returns:
- true, no error
- false, an error
So the bool argument could be removed and this could just return an error if the retry failed or nil if the retry succeeded
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.
it also returns false, no error
when the context is done. This avoids reporting a context done error unnecessarily and just stops quietly
if blockAPI.heightListeners == nil { | ||
// if this is nil, then there is no need to close anything | ||
return | ||
} |
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.
This check is unnecessary because heightListeners is always non-nil due to:
func NewBlockAPI() *BlockAPI {
return &BlockAPI{
heightListeners: make(map[chan NewHeightEvent]struct{}, 1000),
subscriptionID: fmt.Sprintf("block-api-subscription-%s", rand.Str(6)),
subscriptionQuery: eventstypes.EventQueryNewBlock,
}
}
and it's never explicitly set to nil so this check will never evaluate to true. Proposal to remove it
if blockAPI.heightListeners == nil { | |
// if this is nil, then there is no need to close anything | |
return | |
} |
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.
this is just a foolproof check because the BlockAPI is exported and anyone can instantiate it and mess up initialising the fields
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.
IMO it's unecessary to safe-guard against this b/c the default NewBlockAPI
initializes fields correctly but if you want to inform developers of a code error then this should throw an error instead of silently 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.
aah sorry, meant when closing, if the field hasn't been initialized correctly or was set to nil at some level, there is no need to close anything as there is nothing to close
var err error | ||
// stop the events subscription | ||
if blockAPI.newBlockSubscription != nil { | ||
err = core.GetEnvironment().EventBus.Unsubscribe(ctx, blockAPI.subscriptionID, blockAPI.subscriptionQuery) |
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.
this error isn't explicitly handled, is that intentional? I would expect
err = core.GetEnvironment().EventBus.Unsubscribe(ctx, blockAPI.subscriptionID, blockAPI.subscriptionQuery) | |
err = core.GetEnvironment().EventBus.Unsubscribe(ctx, blockAPI.subscriptionID, blockAPI.subscriptionQuery) | |
if err != nil { | |
// handle the error | |
} | |
blockAPI.newBlockSubscription = 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.
yes, it's returned at the end of the function. If you prefer the error handling to be done in place, I can change
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 think it's safer to do error handling immediately after the error b/c in this case the code would log
"gRPC streaming API has been stopped"
even though there may have been an error during the unsubscribe.
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.
yes, and would return the error that happened during the unsubscribe to be handled separately, which if I am not missing something, is also logged at a higher level.
opts = append(opts, grpc.WithTransportCredentials(insecure.NewCredentials())) | ||
} | ||
opts = append(opts, grpc.WithContextDialer(dialerFunc)) | ||
conn, err := grpc.Dial( //nolint:staticcheck |
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.
This can be refactored to eliminate the nolint directive
conn, err := grpc.Dial( //nolint:staticcheck | |
conn, err := grpc.NewClient( |
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 problem with this is that it uses an address from the config which has a tcp prefix and when used with NewClient it fails to connect.
So, changing this would mean reparsing the provided address and separating it to host:port
.
We can create an issue to do it along with the other gRPC endpoint for consistency instead of touching both in here
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.
Co-authored-by: Rootul P <[email protected]>
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.
Feedback is optional not blocking
"github.com/tendermint/tendermint/libs/pubsub" | ||
|
||
"github.com/tendermint/tendermint/crypto/encoding" | ||
|
||
"github.com/tendermint/tendermint/proto/tendermint/crypto" | ||
|
||
"github.com/tendermint/tendermint/libs/rand" | ||
|
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.
nit: these newlines seem unintentional
"github.com/tendermint/tendermint/libs/pubsub" | |
"github.com/tendermint/tendermint/crypto/encoding" | |
"github.com/tendermint/tendermint/proto/tendermint/crypto" | |
"github.com/tendermint/tendermint/libs/rand" | |
"github.com/tendermint/tendermint/libs/pubsub" | |
"github.com/tendermint/tendermint/crypto/encoding" | |
"github.com/tendermint/tendermint/proto/tendermint/crypto" | |
"github.com/tendermint/tendermint/libs/rand" |
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.
if blockAPI.heightListeners == nil { | ||
// if this is nil, then there is no need to close anything | ||
return | ||
} |
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.
IMO it's unecessary to safe-guard against this b/c the default NewBlockAPI
initializes fields correctly but if you want to inform developers of a code error then this should throw an error instead of silently returning.
var err error | ||
// stop the events subscription | ||
if blockAPI.newBlockSubscription != nil { | ||
err = core.GetEnvironment().EventBus.Unsubscribe(ctx, blockAPI.subscriptionID, blockAPI.subscriptionQuery) |
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 think it's safer to do error handling immediately after the error b/c in this case the code would log
"gRPC streaming API has been stopped"
even though there may have been an error during the unsubscribe.
@@ -1,9 +1,19 @@ | |||
//nolint:dupl |
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 disable this linter?
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 didn't spend time refactoring the testing suite so it has multiple duplicates. I'll open a good first issue for it
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.
## Description Addresses this #1513 (comment)
This is an implementation of a streaming API for blocks in core.
Helps close celestiaorg/celestia-app#3421 but not sure it entirely closes it.
It can easily be used:
Ps: I didn't add the tests because I didn't find a direct way of mocking the environment without polluting the rest of the repo (exporting some methods, adding new helpers, etc). And I think since the implementation is simple, just querying the block/state stores for results, it's fine to leave it untested.