1//! `zebra_scan::service::ScanService` request types.
23use std::collections::HashSet;
45use crate::BoxError;
67/// The maximum number of keys that may be included in a request to the scan service
8const MAX_REQUEST_KEYS: usize = 1000;
910#[derive(Debug)]
11/// Request types for `zebra_scan::service::ScanService`
12pub enum Request {
13/// Requests general info about the scanner
14Info,
1516/// Submits viewing keys with their optional birth-heights for scanning.
17RegisterKeys(Vec<(String, Option<u32>)>),
1819/// Deletes viewing keys and their results from the database.
20DeleteKeys(Vec<String>),
2122/// Accept keys and return transaction data
23Results(Vec<String>),
2425/// Accept keys and return a channel receiver for transaction data
26SubscribeResults(HashSet<String>),
2728/// Clear the results for a set of viewing keys
29ClearResults(Vec<String>),
30}
3132impl Request {
33/// Check that the request data is valid for the request variant
34pub fn check(&self) -> Result<(), BoxError> {
35self.check_num_keys()?;
3637Ok(())
38 }
3940/// Checks that requests which include keys have a valid number of keys.
41fn check_num_keys(&self) -> Result<(), BoxError> {
42match self {
43 Request::DeleteKeys(keys) | Request::ClearResults(keys)
44if keys.is_empty() || keys.len() > MAX_REQUEST_KEYS =>
45 {
46Err(format!("request must include between 1 and {MAX_REQUEST_KEYS} keys").into())
47 }
4849_ => Ok(()),
50 }
51 }
52}
5354#[test]
55fn test_check_num_keys() {
56let fake_keys: Vec<_> = std::iter::repeat_n(String::new(), MAX_REQUEST_KEYS + 1).collect();
5758let bad_requests = [
59 Request::DeleteKeys(vec![]),
60 Request::DeleteKeys(fake_keys.clone()),
61 Request::ClearResults(vec![]),
62 Request::ClearResults(fake_keys),
63 ];
6465let valid_requests = [
66 Request::DeleteKeys(vec![String::new()]),
67 Request::ClearResults(vec![String::new()]),
68 ];
6970for request in bad_requests {
71let error = request.check().expect_err("check should return an error");
7273assert_eq!(
74format!("request must include between 1 and {MAX_REQUEST_KEYS} keys"),
75 error.to_string(),
76"check_num_keys should return an error because there are too many keys"
77);
78 }
7980for request in valid_requests {
81 request.check().expect("check should return Ok(())");
82 }
83}