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: improve queryClient #52

Merged
merged 5 commits into from
Dec 21, 2022
Merged

feat: improve queryClient #52

merged 5 commits into from
Dec 21, 2022

Conversation

gyuguen
Copy link
Contributor

@gyuguen gyuguen commented Dec 20, 2022

close #47

I improve like below:

Improved queryClient

  • The height used by queryClient is fixed.
    • When oracle receives an event as a subscription, it gets the height from the event.
    • When oracle receives a request from client, it gets the last block height from lightClient.
      • However, the height decreases by one.
      • The reason is for quick response.

@gyuguen gyuguen added this to the v2.1.0-beta milestone Dec 20, 2022
@gyuguen gyuguen self-assigned this Dec 20, 2022
ctypes "github.com/tendermint/tendermint/rpc/core/types"
)

type Event interface {
Name() string
GetEventQuery() string
EventHandler(event ctypes.ResultEvent) error
EventHandler(context.Context, ctypes.ResultEvent) error
Copy link
Contributor Author

Choose a reason for hiding this comment

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

All event handlers added context. Because it uses shared query height.


height, err := strconv.ParseInt(tx.Events["tx.height"][0], 10, 64)
// If an error occurs, the context does not set the height.
if err == nil {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Event if an error occurs, the following logic is performed.

@@ -38,14 +38,15 @@ import (

type QueryClient interface {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Context is added to every call query in the blockchain.

@@ -306,6 +296,13 @@ func (q verifiedQueryClient) GetStoreData(ctx context.Context, storeKey string,
return result.Response.Value, nil
}

func (q verifiedQueryClient) getQueryBlockHeight(ctx context.Context) (int64, error) {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Gets the height from the context, if the height exists in the context.
If notm get last block height from lightClient.

Copy link
Contributor

@youngjoon-lee youngjoon-lee Dec 20, 2022

Choose a reason for hiding this comment

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

It would be greater if we can do this without using context, since many practices are saying it's better to minimize the use of context (for clarity of source code).
If we can pass a targetHeight parameter to the GetStoreData() function, it would be enough.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

OK. That would be good too.
If so, I will remove all contexts and modify it to specify the height only where it is needed.

I simply developed the function to be commonly applicable.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I would like to be able to set the height selectively for each logic.

Copy link
Contributor Author

@gyuguen gyuguen Dec 20, 2022

Choose a reason for hiding this comment

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

However, I have a part that worries me.

The height to be used in the event and the height to be used in the client are currently implemented differently.
To speed up the client's response, the previous height of the last block was set.
The event uses the height passed from the event.

To support both of these, the following changes must be made.

type QueryClient interface {
	Close() error
	GetAccount(queryHeight int64, address string) (authtypes.AccountI, error)
	GetOracleRegistration(queryHeight int64,  uniqueID string, address string) (*oracletypes.OracleRegistration, error)
	GetLightBlock(height int64) (*tmtypes.LightBlock, error)
	GetCdc() *codec.ProtoCodec
	GetChainID() string
	GetOracleParamsPublicKey(queryHeight int64) (*btcec.PublicKey, error)
	GetDeal(queryHeight int64, dealID uint64) (*datadealtypes.Deal, error)
	GetCertificate(queryHeight int64, dealID uint64, dataHash string) (*datadealtypes.Certificate, error)
	GetLastBlockHeight() (int64, error)
}

Copy link
Contributor

Choose a reason for hiding this comment

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

Hmm. If you think we need to change many source codes for using queryHeight, you can just use context as you did. I read this PR again, and it looks reasonable. Sorry for bothering you. So, the decision is up to you.

Copy link
Contributor Author

@gyuguen gyuguen Dec 21, 2022

Choose a reason for hiding this comment

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

I have been thinking about this part, and the conclusion will be modified so that the height is input as @youngjoon-lee initially suggested.
Using Middleware is convenient, but because it is hidden code, someone else brings confusion.

Copy link
Contributor

Choose a reason for hiding this comment

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

Ah. I also forgot that jwtAuthMiddleware also uses verifiedQueryClient.
https://github.com/medibloc/panacea-oracle/pull/52/files#diff-6f125263042ee6bd63bdbbe9ea792e6d409132c4e91fc0e4553c668e9b9d99edR74

Then, it's more reasonable to use context to pass the query height to the jwtAuthMiddleware. Anyway, I'd like to say that the decision is up to you :)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Ok, I'll decide to leave the code as is.

If I think this code is wrong, I'll fix it later. :)

panacea/tx.go Outdated
@@ -56,7 +58,7 @@ func (tb TxBuilder) GenerateSignedTxBytes(
return nil, err
}

signerAccount, err := tb.client.GetAccount(signerAddress)
signerAccount, err := tb.client.GetAccount(context.Background(), signerAddress)
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Maybe it will be change to grpcClient.

if err == nil {
log.Debugf("Set the previous value of the last block heignt. LastHeight: %v, SetHeight: %v", height, height-1)
r = r.WithContext(
panacea.SetQueryBlockHeightToContext(r.Context(), height-1),
Copy link
Contributor Author

Choose a reason for hiding this comment

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

I used the previous height of the last block

Copy link
Contributor

Choose a reason for hiding this comment

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

Could you explain why do you use the previous height of the latest block here?
Is it for (almost) immediate response?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes that's the biggest reason.
And it doesn't seem to be a query that is sensitive to block height.

Copy link
Contributor

Choose a reason for hiding this comment

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

I think it is very rare case, but what if there is no data in the previous block? since the data is set in the latest block.
In other words, it's the case that a transaction (to store data) is executed and somebody query the data at the same time. We don't have to care this edge case?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes, that case can happen enough.
But I think we should put more importance on quick response.
I think a late response will cause more problems.

Copy link
Contributor

@youngjoon-lee youngjoon-lee Dec 21, 2022

Choose a reason for hiding this comment

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

Ah. I haven't thought about using the previous height of the latest block. Umm... it's a trade-off as you and Hansol said..... Accuracy vs Latency..
Let me think about it..


dealRouter := router.PathPrefix("/v0/data-deal").Subrouter()
dealRouter.Use(jwtAuthMiddleware.Middleware)
dealRouter.Use(
queryMiddleware.Middleware,
Copy link
Contributor Author

Choose a reason for hiding this comment

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

This order is important.
You must first set the height before using the query.

Copy link
Contributor

@0xHansLee 0xHansLee left a comment

Choose a reason for hiding this comment

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

I tested and confirmed that it is improved very well. Good work!

Copy link
Contributor

@audtlr24 audtlr24 left a comment

Choose a reason for hiding this comment

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

Thanks, lgtm!

Copy link
Contributor

@youngjoon-lee youngjoon-lee left a comment

Choose a reason for hiding this comment

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

lgtm

@gyuguen gyuguen merged commit f4e07b3 into main Dec 21, 2022
@gyuguen gyuguen deleted the ft/47/improve_query_client branch December 21, 2022 05:36
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.

Consider making verifiedQueryClient.GetStoreData() accept a queryHeight
4 participants