zebra_node_services/scan_service/
request.rs

1//! `zebra_scan::service::ScanService` request types.
2
3use std::collections::HashSet;
4
5use crate::BoxError;
6
7/// The maximum number of keys that may be included in a request to the scan service
8const MAX_REQUEST_KEYS: usize = 1000;
9
10#[derive(Debug)]
11/// Request types for `zebra_scan::service::ScanService`
12pub enum Request {
13    /// Requests general info about the scanner
14    Info,
15
16    /// Submits viewing keys with their optional birth-heights for scanning.
17    RegisterKeys(Vec<(String, Option<u32>)>),
18
19    /// Deletes viewing keys and their results from the database.
20    DeleteKeys(Vec<String>),
21
22    /// Accept keys and return transaction data
23    Results(Vec<String>),
24
25    /// Accept keys and return a channel receiver for transaction data
26    SubscribeResults(HashSet<String>),
27
28    /// Clear the results for a set of viewing keys
29    ClearResults(Vec<String>),
30}
31
32impl Request {
33    /// Check that the request data is valid for the request variant
34    pub fn check(&self) -> Result<(), BoxError> {
35        self.check_num_keys()?;
36
37        Ok(())
38    }
39
40    /// Checks that requests which include keys have a valid number of keys.
41    fn check_num_keys(&self) -> Result<(), BoxError> {
42        match self {
43            Request::DeleteKeys(keys) | Request::ClearResults(keys)
44                if keys.is_empty() || keys.len() > MAX_REQUEST_KEYS =>
45            {
46                Err(format!("request must include between 1 and {MAX_REQUEST_KEYS} keys").into())
47            }
48
49            _ => Ok(()),
50        }
51    }
52}
53
54#[test]
55fn test_check_num_keys() {
56    let fake_keys: Vec<_> = std::iter::repeat_n(String::new(), MAX_REQUEST_KEYS + 1).collect();
57
58    let bad_requests = [
59        Request::DeleteKeys(vec![]),
60        Request::DeleteKeys(fake_keys.clone()),
61        Request::ClearResults(vec![]),
62        Request::ClearResults(fake_keys),
63    ];
64
65    let valid_requests = [
66        Request::DeleteKeys(vec![String::new()]),
67        Request::ClearResults(vec![String::new()]),
68    ];
69
70    for request in bad_requests {
71        let error = request.check().expect_err("check should return an error");
72
73        assert_eq!(
74            format!("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    }
79
80    for request in valid_requests {
81        request.check().expect("check should return Ok(())");
82    }
83}