diff --git a/zebra-grpc/proto/scanner.proto b/zebra-grpc/proto/scanner.proto index 9eed480f..cc6e0b73 100644 --- a/zebra-grpc/proto/scanner.proto +++ b/zebra-grpc/proto/scanner.proto @@ -19,6 +19,9 @@ service Scanner { // Get all data we have stored for the given keys. rpc GetResults(GetResultsRequest) returns (GetResultsResponse); + + // Submits scanning keys to the scanner. + rpc RegisterKeys(RegisterKeysRequest) returns (RegisterKeysResponse); } // A response to a GetInfo call. @@ -45,12 +48,24 @@ message GetResultsRequest { repeated string keys = 1; } +// A request to register scanning keys +message RegisterKeysRequest { + // Keys to register + repeated KeyWithHeight keys = 1; +} + // A set of responses for each provided key of a GetResults call. message GetResultsResponse { // Results for each key. map results = 1; } +// A response to `RegisterKeysRequest` containing registered keys +message RegisterKeysResponse { + // Keys that were registered + repeated string keys = 1; +} + // A result for a single key. message Results { // A height, transaction id map @@ -62,3 +77,11 @@ message TransactionHash { // A transaction id hash repeated string hash = 1; } + +// A scanning key with an optional birth height +message KeyWithHeight { + // Scanning key + string key = 1; + // Birth height of the key + optional uint32 height = 2; +} diff --git a/zebra-grpc/src/server.rs b/zebra-grpc/src/server.rs index 65e2b8a9..0e358e43 100644 --- a/zebra-grpc/src/server.rs +++ b/zebra-grpc/src/server.rs @@ -3,7 +3,7 @@ use std::{collections::BTreeMap, net::SocketAddr}; use futures_util::future::TryFutureExt; -use tonic::{transport::Server, Response, Status}; +use tonic::{transport::Server, Request, Response, Status}; use tower::ServiceExt; use zebra_node_services::scan_service::{ @@ -13,7 +13,7 @@ use zebra_node_services::scan_service::{ use crate::scanner::{ scanner_server::{Scanner, ScannerServer}, ClearResultsRequest, DeleteKeysRequest, Empty, GetResultsRequest, GetResultsResponse, - InfoReply, Results, TransactionHash, + InfoReply, RegisterKeysRequest, RegisterKeysResponse, Results, TransactionHash, }; type BoxError = Box; @@ -42,10 +42,7 @@ where + 'static, >::Future: Send, { - async fn get_info( - &self, - _request: tonic::Request, - ) -> Result, Status> { + async fn get_info(&self, _request: Request) -> Result, Status> { let ScanServiceResponse::Info { min_sapling_birthday_height, } = self @@ -68,9 +65,36 @@ where Ok(Response::new(reply)) } + async fn register_keys( + &self, + request: Request, + ) -> Result, Status> { + let keys = request + .into_inner() + .keys + .into_iter() + .map(|key_with_height| (key_with_height.key, key_with_height.height)) + .collect(); + + let ScanServiceResponse::RegisteredKeys(keys) = self + .scan_service + .clone() + .ready() + .and_then(|service| service.call(ScanServiceRequest::RegisterKeys(keys))) + .await + .map_err(|_| Status::unknown("scan service was unavailable"))? + else { + return Err(Status::unknown( + "scan service returned an unexpected response", + )); + }; + + Ok(Response::new(RegisterKeysResponse { keys })) + } + async fn clear_results( &self, - request: tonic::Request, + request: Request, ) -> Result, Status> { let keys = request.into_inner().keys; @@ -97,7 +121,7 @@ where async fn delete_keys( &self, - request: tonic::Request, + request: Request, ) -> Result, Status> { let keys = request.into_inner().keys; @@ -124,7 +148,7 @@ where async fn get_results( &self, - request: tonic::Request, + request: Request, ) -> Result, Status> { let keys = request.into_inner().keys;