Skip to content

Commit

Permalink
add(grpc): get_results (#8255)
Browse files Browse the repository at this point in the history
* add `get_results` grpc call

* nitpick
  • Loading branch information
oxarbitrage authored Feb 9, 2024
1 parent 6b8cbf9 commit d59c730
Show file tree
Hide file tree
Showing 3 changed files with 85 additions and 4 deletions.
4 changes: 3 additions & 1 deletion zebra-grpc/build.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
//! Compile proto files

fn main() -> Result<(), Box<dyn std::error::Error>> {
tonic_build::compile_protos("proto/scanner.proto")?;
tonic_build::configure()
.btree_map(["."])
.compile(&["proto/scanner.proto"], &[""])?;
Ok(())
}
29 changes: 28 additions & 1 deletion zebra-grpc/proto/scanner.proto
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@ service Scanner {
// 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);

// Get all data we have stored for the given keys.
rpc GetResults(GetResultsRequest) returns (GetResultsResponse);
}

// A response to a GetInfo call.
Expand All @@ -34,4 +37,28 @@ message ClearResultsRequest {
message DeleteKeysRequest {
// Keys to delete from scanner.
repeated string keys = 1;
}
}

// A request for getting results for a set of keys.
message GetResultsRequest {
// Keys for which to get results.
repeated string keys = 1;
}

// A set of responses for each provided key of a GetResults call.
message GetResultsResponse {
// Results for each key.
map<string, Results> results = 1;
}

// A result for a single key.
message Results {
// A height, transaction id map
map<uint32, TransactionHash> transactions = 1;
}

// A vector of transaction hashes
message TransactionHash {
// A transaction id hash
repeated string hash = 1;
}
56 changes: 54 additions & 2 deletions zebra-grpc/src/server.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
//! The gRPC server implementation

use std::net::SocketAddr;
use std::{collections::BTreeMap, net::SocketAddr};

use futures_util::future::TryFutureExt;
use tonic::{transport::Server, Response, Status};
Expand All @@ -12,7 +12,8 @@ use zebra_node_services::scan_service::{

use crate::scanner::{
scanner_server::{Scanner, ScannerServer},
ClearResultsRequest, DeleteKeysRequest, Empty, InfoReply,
ClearResultsRequest, DeleteKeysRequest, Empty, GetResultsRequest, GetResultsResponse,
InfoReply, Results, TransactionHash,
};

type BoxError = Box<dyn std::error::Error + Send + Sync + 'static>;
Expand Down Expand Up @@ -120,6 +121,57 @@ where

Ok(Response::new(Empty {}))
}

async fn get_results(
&self,
request: tonic::Request<GetResultsRequest>,
) -> Result<Response<GetResultsResponse>, Status> {
let keys = request.into_inner().keys;

if keys.is_empty() {
let msg = "must provide at least 1 key to get results";
return Err(Status::invalid_argument(msg));
}

let ScanServiceResponse::Results(response) = self
.scan_service
.clone()
.ready()
.and_then(|service| service.call(ScanServiceRequest::Results(keys.clone())))
.await
.map_err(|err| Status::unknown(format!("scan service returned error: {err}")))?
else {
return Err(Status::unknown(
"scan service returned an unexpected response",
));
};

// If there are no results for a key, we still want to return it with empty results.
let empty_map = BTreeMap::new();

let results = keys
.into_iter()
.map(|key| {
let values = response.get(&key).unwrap_or(&empty_map);

// Skip heights with no transactions, they are scanner markers and should not be returned.
let transactions = Results {
transactions: values
.iter()
.filter(|(_, transactions)| !transactions.is_empty())
.map(|(height, transactions)| {
let txs = transactions.iter().map(ToString::to_string).collect();
(height.0, TransactionHash { hash: txs })
})
.collect(),
};

(key, transactions)
})
.collect::<BTreeMap<_, _>>();

Ok(Response::new(GetResultsResponse { results }))
}
}

/// Initializes the zebra-scan gRPC server
Expand Down

0 comments on commit d59c730

Please sign in to comment.