From 8d1a1ac48609c927e6e428850757e0e3bc18ba9b Mon Sep 17 00:00:00 2001 From: Arya Date: Tue, 6 Feb 2024 16:08:56 -0500 Subject: [PATCH] add(scan): Add `ClearResults` and `DeleteKeys` gRPC methods (#8237) * adds clear_results RPC method for zebra-scan * adds delete_keys rpc method * adds docs * Update zebra-grpc/proto/scanner.proto Co-authored-by: Alfredo Garcia * Apply suggestions from code review --------- Co-authored-by: Alfredo Garcia --- zebra-grpc/proto/scanner.proto | 21 +++++++++++++ zebra-grpc/src/server.rs | 56 +++++++++++++++++++++++++++++++++- 2 files changed, 76 insertions(+), 1 deletion(-) diff --git a/zebra-grpc/proto/scanner.proto b/zebra-grpc/proto/scanner.proto index 8974a2530..72ff40882 100644 --- a/zebra-grpc/proto/scanner.proto +++ b/zebra-grpc/proto/scanner.proto @@ -7,10 +7,31 @@ message Empty {} service Scanner { // Get information about the scanner service. rpc GetInfo (Empty) returns (InfoReply); + + // Clear results for a set of keys without removing the keys from the scanner. + // This request does not stop the scanner from scanning blocks for these keys, it + // only clears past results. + rpc ClearResults(ClearResultsRequest) returns (Empty); + + // Deletes a set of keys and their results from the scanner. + // This request stop the scanner from scanning blocks for the these keys. + rpc DeleteKeys(DeleteKeysRequest) returns (Empty); } // A response to a GetInfo call. message InfoReply { // The minimum sapling height allowed. uint32 min_sapling_birthday_height = 1; +} + +// A request for clearing past results from the scanner cache. +message ClearResultsRequest { + // Keys for which to clear results. + repeated string keys = 1; +} + +// A request to delete keys, delete their results, and stop scanning for their results. +message DeleteKeysRequest { + // Keys to delete from scanner. + repeated string keys = 1; } \ No newline at end of file diff --git a/zebra-grpc/src/server.rs b/zebra-grpc/src/server.rs index 808ebba8f..39f2d02ff 100644 --- a/zebra-grpc/src/server.rs +++ b/zebra-grpc/src/server.rs @@ -5,7 +5,7 @@ use tonic::{transport::Server, Response, Status}; use tower::ServiceExt; use scanner::scanner_server::{Scanner, ScannerServer}; -use scanner::{Empty, InfoReply}; +use scanner::{ClearResultsRequest, DeleteKeysRequest, Empty, InfoReply}; use zebra_node_services::scan_service::{ request::Request as ScanServiceRequest, response::Response as ScanServiceResponse, @@ -67,6 +67,60 @@ where Ok(Response::new(reply)) } + + async fn clear_results( + &self, + request: tonic::Request, + ) -> Result, Status> { + let keys = request.into_inner().keys; + + if keys.is_empty() { + let msg = "must provide at least 1 key for which to clear results"; + return Err(Status::invalid_argument(msg)); + } + + let ScanServiceResponse::ClearedResults = self + .scan_service + .clone() + .ready() + .and_then(|service| service.call(ScanServiceRequest::ClearResults(keys))) + .await + .map_err(|err| Status::unknown(format!("scan service returned error: {err}")))? + else { + return Err(Status::unknown( + "scan service returned an unexpected response", + )); + }; + + Ok(Response::new(Empty {})) + } + + async fn delete_keys( + &self, + request: tonic::Request, + ) -> Result, Status> { + let keys = request.into_inner().keys; + + if keys.is_empty() { + let msg = "must provide at least 1 key to delete"; + return Err(Status::invalid_argument(msg)); + } + + let ScanServiceResponse::DeletedKeys = self + .scan_service + .clone() + .ready() + .and_then(|service| service.call(ScanServiceRequest::DeleteKeys(keys))) + .await + .map_err(|err| Status::unknown(format!("scan service returned error: {err}")))? + else { + return Err(Status::unknown( + "scan service returned an unexpected response", + )); + }; + + Ok(Response::new(Empty {})) + } } /// Initializes the zebra-scan gRPC server