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

add(scan): Implement scan gRPC method #8268

Merged
merged 8 commits into from
Feb 20, 2024
Merged

add(scan): Implement scan gRPC method #8268

merged 8 commits into from
Feb 20, 2024

Conversation

arya2
Copy link
Contributor

@arya2 arya2 commented Feb 13, 2024

Motivation

We want to provide a streaming method for registering keys, getting cached scan results, and listening for any new scan results.

Closes #8256.

PR Author Checklist

Check before marking the PR as ready for review:

  • Will the PR name make sense to users?
  • Does the PR have a priority label?
  • Have you added or updated tests?
  • Is the documentation up to date?
For significant changes:
  • Is there a summary in the CHANGELOG?
  • Can these changes be split into multiple PRs?

If a checkbox isn't relevant to the PR, mark it as done.

Solution

  • Calls ScanService with RegisterKeys, Results and SubscribeResults requests
  • Creates a response channel
  • Creates a new ReceiverStream wrapper around the response receiver
  • Spawns a tokio task
    • Transposes the Results response and sends them to the response channel
    • Waits for results from the results_receiver returned by the call to SubscribeResults and sends them to the response channel
  • Returns the response stream

Review

Anyone can review.

Reviewer Checklist

Check before approving the PR:

  • Does the PR scope match the ticket?
  • Are there enough tests to make sure it works? Do the tests cover the PR motivation?
  • Are all the PR blockers dealt with?
    PR blockers can be dealt with in new tickets or PRs.

And check the PR Author checklist is complete.

@arya2 arya2 added A-rpc Area: Remote Procedure Call interfaces A-concurrency Area: Async code, needs extra work to make it work properly. A-blockchain-scanner Area: Blockchain scanner of shielded transactions P-Medium ⚡ labels Feb 13, 2024
@arya2 arya2 self-assigned this Feb 13, 2024
@arya2 arya2 added E-help-wanted Call for participation: Help is requested to fix this issue. and removed E-help-wanted Call for participation: Help is requested to fix this issue. labels Feb 13, 2024
@arya2
Copy link
Contributor Author

arya2 commented Feb 14, 2024

Manual test output with cached results:

(There's a duplicate result here, that should be fixed now that the SubscribeResults request comes after the Results request.)

~/github/zebra$ grpcurl -plaintext -import-path ./zebra-grpc/proto -proto zebra-grpc/proto/scanner.proto -d '{"keys": [{ "key": "zxviews1q0duytgcqqqqpqre26wkl45gvwwwd706xw608hucmvfalr759ejwf7qshjf5r9aa7323zulvz6plhttp5mltqcgs9t039cx2d09mgq05ts63n8u35hyv6h9nc9ctqqtue2u7cer2mqegunuulq2luhq3ywjcz35yyljewa4mgkgjzyfwh6fr6jd0dzd44ghk0nxdv2hnv4j5nxfwv24rwdmgllhe0p8568sgqt9ckt02v2kxf5ahtql6s0ltjpkckw8gtymxtxuu9gcr0swvz", "height": 736000 }]}' '127.0.0.1:8231' scanner.Scanner/Scan
{
  "height": 780532,
  "results": {
    "zxviews1q0duytgcqqqqpqre26wkl45gvwwwd706xw608hucmvfalr759ejwf7qshjf5r9aa7323zulvz6plhttp5mltqcgs9t039cx2d09mgq05ts63n8u35hyv6h9nc9ctqqtue2u7cer2mqegunuulq2luhq3ywjcz35yyljewa4mgkgjzyfwh6fr6jd0dzd44ghk0nxdv2hnv4j5nxfwv24rwdmgllhe0p8568sgqt9ckt02v2kxf5ahtql6s0ltjpkckw8gtymxtxuu9gcr0swvz": {
      "txIds": [
        "HFGctyvCDQJPnAlUF4QD0W+sfOjbWUrGDbdiE+bIgms="
      ]
    }
  }
}
{
  "height": 780532,
  "results": {
    "zxviews1q0duytgcqqqqpqre26wkl45gvwwwd706xw608hucmvfalr759ejwf7qshjf5r9aa7323zulvz6plhttp5mltqcgs9t039cx2d09mgq05ts63n8u35hyv6h9nc9ctqqtue2u7cer2mqegunuulq2luhq3ywjcz35yyljewa4mgkgjzyfwh6fr6jd0dzd44ghk0nxdv2hnv4j5nxfwv24rwdmgllhe0p8568sgqt9ckt02v2kxf5ahtql6s0ltjpkckw8gtymxtxuu9gcr0swvz": {
      "txIds": [
        "HFGctyvCDQJPnAlUF4QD0W+sfOjbWUrGDbdiE+bIgms="
      ]
    }
  }
}
{
  "height": 780616,
  "results": {
    "zxviews1q0duytgcqqqqpqre26wkl45gvwwwd706xw608hucmvfalr759ejwf7qshjf5r9aa7323zulvz6plhttp5mltqcgs9t039cx2d09mgq05ts63n8u35hyv6h9nc9ctqqtue2u7cer2mqegunuulq2luhq3ywjcz35yyljewa4mgkgjzyfwh6fr6jd0dzd44ghk0nxdv2hnv4j5nxfwv24rwdmgllhe0p8568sgqt9ckt02v2kxf5ahtql6s0ltjpkckw8gtymxtxuu9gcr0swvz": {
      "txIds": [
        "nvIywWt5HlwTwGcRV3bc+hVEsYMEAa8cKCiGymOVZ54="
      ]
    }
  }
}
..
^C

Output without cached results:

~/github/zebra$ grpcurl -plaintext -import-path ./zebra-grpc/proto -proto zebra-grpc/proto/scanner.proto -d '{"keys": [{ "key": "zxviews1q0duytgcqqqqpqre26wkl45gvwwwd706xw608hucmvfalr759ejwf7qshjf5r9aa7323zulvz6plhttp5mltqcgs9t039cx2d09mgq05ts63n8u35hyv6h9nc9ctqqtue2u7cer2mqegunuulq2luhq3ywjcz35yyljewa4mgkgjzyfwh6fr6jd0dzd44ghk0nxdv2hnv4j5nxfwv24rwdmgllhe0p8568sgqt9ckt02v2kxf5ahtql6s0ltjpkckw8gtymxtxuu9gcr0swvz", "height": 736000 }]}' '127.0.0.1:8231' scanner.Scanner/Scan
{
  "height": 780532,
  "results": {
    "zxviews1q0duytgcqqqqpqre26wkl45gvwwwd706xw608hucmvfalr759ejwf7qshjf5r9aa7323zulvz6plhttp5mltqcgs9t039cx2d09mgq05ts63n8u35hyv6h9nc9ctqqtue2u7cer2mqegunuulq2luhq3ywjcz35yyljewa4mgkgjzyfwh6fr6jd0dzd44ghk0nxdv2hnv4j5nxfwv24rwdmgllhe0p8568sgqt9ckt02v2kxf5ahtql6s0ltjpkckw8gtymxtxuu9gcr0swvz": {
      "txIds": [
        "HFGctyvCDQJPnAlUF4QD0W+sfOjbWUrGDbdiE+bIgms="
      ]
    }
  }
}
{
  "height": 780616,
  "results": {
    "zxviews1q0duytgcqqqqpqre26wkl45gvwwwd706xw608hucmvfalr759ejwf7qshjf5r9aa7323zulvz6plhttp5mltqcgs9t039cx2d09mgq05ts63n8u35hyv6h9nc9ctqqtue2u7cer2mqegunuulq2luhq3ywjcz35yyljewa4mgkgjzyfwh6fr6jd0dzd44ghk0nxdv2hnv4j5nxfwv24rwdmgllhe0p8568sgqt9ckt02v2kxf5ahtql6s0ltjpkckw8gtymxtxuu9gcr0swvz": {
      "txIds": [
        "nvIywWt5HlwTwGcRV3bc+hVEsYMEAa8cKCiGymOVZ54="
      ]
    }
  }
}
{
  "height": 780773,
  "results": {
    "zxviews1q0duytgcqqqqpqre26wkl45gvwwwd706xw608hucmvfalr759ejwf7qshjf5r9aa7323zulvz6plhttp5mltqcgs9t039cx2d09mgq05ts63n8u35hyv6h9nc9ctqqtue2u7cer2mqegunuulq2luhq3ywjcz35yyljewa4mgkgjzyfwh6fr6jd0dzd44ghk0nxdv2hnv4j5nxfwv24rwdmgllhe0p8568sgqt9ckt02v2kxf5ahtql6s0ltjpkckw8gtymxtxuu9gcr0swvz": {
      "txIds": [
        "uTuqs07MXG4huksWBwWB1ccrGzjX4SG+UWZPPPBCVxM="
      ]
    }
  }
}
..

@arya2 arya2 marked this pull request as ready for review February 14, 2024 22:17
@arya2 arya2 requested a review from a team as a code owner February 14, 2024 22:17
@arya2 arya2 changed the base branch from main to reg-keys-grpc February 15, 2024 17:49
Base automatically changed from reg-keys-grpc to main February 15, 2024 18:02
@oxarbitrage
Copy link
Contributor

For the manual test i think it will be nice if we can show that we are listening and that a new transaction gets in.

Copy link
Contributor

@oxarbitrage oxarbitrage left a comment

Choose a reason for hiding this comment

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

I was expecting a method subscribe that will subscribe to an already registered key but i think this method is even better as it kind of do everything.

I am wondering if we should also have a subscribe method that just subscribe to the stream of an already registered key.

Added:
It feels the method covers too much so it kind of leave obsolete other methods that we need to maintain if we keep.

zebra-grpc/proto/scanner.proto Outdated Show resolved Hide resolved
@arya2
Copy link
Contributor Author

arya2 commented Feb 16, 2024

For the manual test i think it will be nice if we can show that we are listening and that a new transaction gets in.

I did, that's the second console output, I deleted the key, added it back, waited a bit, and hit ctrl-C after seeing a few results.

I am wondering if we should also have a subscribe method that just subscribe to the stream of an already registered key.

Do you have a use case or motivation in mind? I'm thinking clients probably want the results whether their key is registered or not, so it feels redundant.

Added: It feels the method covers too much so it kind of leave obsolete other methods that we need to maintain if we keep.

This method is a push interface, the pull interface is useful for clients that are calling the RPC methods from a browser environment, or for usability if some clients find it simpler to use the pull interface.

The RPC methods are only thin wrappers around the service requests, so there shouldn't be much of a maintenance burden to supporting both.

@oxarbitrage
Copy link
Contributor

I did, that's the second console output, I deleted the key, added it back, waited a bit, and hit ctrl-C after seeing a few results.

Ok, thanks for the clarification.

Do you have a use case or motivation in mind? I'm thinking clients probably want the results whether their key is registered or not, so it feels redundant.

  • I was expecting that the users will register a key and start scanning with registerkey.
  • Then to get all the cached results with getresults.
  • Subscribe to future results with subscribe.

This makes all that in one step, which i think it can be fine but i don't remember it was planned this way.

This method is a push interface, the pull interface is useful for clients that are calling the RPC methods from a browser environment, or for usability if some clients find it simpler to use the pull interface.

I don't remember that we planned to have 2 different interfaces (with overlapping functionality).

The RPC methods are only thin wrappers around the service requests, so there shouldn't be much of a maintenance burden to supporting both.

It is more easy to add than to remove. Once you support an api call you make a commit to support it (otherwise applications will break). You can have deprecation policies, etc but in general you need to keep them.

I don't mind adding this call, i just think it do a lot more than needed.

@arya2
Copy link
Contributor Author

arya2 commented Feb 16, 2024

I'll wait for #8277 to merge then rebase and update/add the snapshots.

oxarbitrage
oxarbitrage previously approved these changes Feb 16, 2024
Copy link
Contributor

@oxarbitrage oxarbitrage left a comment

Choose a reason for hiding this comment

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

Looks great, thank you for the changes. Can you update the manual tests to show the new output format ? The other option is to add the snapshots, whatever is easier for you.

zebra-grpc/src/server.rs Outdated Show resolved Hide resolved
zebra-grpc/src/server.rs Show resolved Hide resolved
@arya2
Copy link
Contributor Author

arya2 commented Feb 16, 2024

Can you update the manual tests to show the new output format ? The other option is to add the snapshots, whatever is easier for you.

I'll try adding the snapshots, since we need to do that anyways.

Copy link
Contributor

@oxarbitrage oxarbitrage left a comment

Choose a reason for hiding this comment

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

Looks good, thank for adding the snapshots here.

mergify bot added a commit that referenced this pull request Feb 20, 2024
@mergify mergify bot merged commit a7de137 into main Feb 20, 2024
186 checks passed
@mergify mergify bot deleted the scan-grpc-method branch February 20, 2024 19:16
idky137 pushed a commit to idky137/zebra that referenced this pull request Feb 28, 2024
* Adds scan method

* fix clippy warning

* Skip empty results and don't panic if the gRPC client disconnects

* moves `Results` request above `SubscribeResults` request to avoid duplicate results.

* returns early if there's a send error when sending initial results and updates response type

* move responder buffer size to const

* Adds a snapshot test for the `scan` method

* updates snapshots
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-blockchain-scanner Area: Blockchain scanner of shielded transactions A-concurrency Area: Async code, needs extra work to make it work properly. A-rpc Area: Remote Procedure Call interfaces P-Medium ⚡
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Implement scan grpc method
2 participants