explorerd/rpc/
statistics.rs

1/* This file is part of DarkFi (https://dark.fi)
2 *
3 * Copyright (C) 2020-2025 Dyne.org foundation
4 *
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU Affero General Public License as
7 * published by the Free Software Foundation, either version 3 of the
8 * License, or (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 * GNU Affero General Public License for more details.
14 *
15 * You should have received a copy of the GNU Affero General Public License
16 * along with this program.  If not, see <https://www.gnu.org/licenses/>.
17 */
18
19use std::vec::Vec;
20
21use tinyjson::JsonValue;
22
23use darkfi::{rpc::jsonrpc::validate_empty_params, Result};
24
25use crate::Explorerd;
26
27impl Explorerd {
28    // RPCAPI:
29    // Queries the database to retrieve current basic statistics.
30    // Returns the readable transaction upon success.
31    //
32    // **Params:**
33    // * `None`
34    //
35    // **Returns:**
36    // * `BaseStatistics` encoded into a JSON.
37    //
38    // **Example API Usage:**
39    // --> {"jsonrpc": "2.0", "method": "statistics.get_basic_statistics", "params": [], "id": 1}
40    // <-- {"jsonrpc": "2.0", "result": {...}, "id": 1}
41    pub async fn statistics_get_basic_statistics(&self, params: &JsonValue) -> Result<JsonValue> {
42        // Validate that no parameters are provided
43        validate_empty_params(params)?;
44
45        // Attempt to retrieve base statistics; if found, convert to a JSON array,
46        // otherwise return an empty JSON array
47        match self.service.get_base_statistics()? {
48            Some(statistics) => Ok(statistics.to_json_array()),
49            None => Ok(JsonValue::Array(vec![])),
50        }
51    }
52
53    // RPCAPI:
54    // Queries the database to retrieve all metrics statistics.
55    // Returns a collection of metric statistics upon success.
56    //
57    // **Params:**
58    // * `None`
59    //
60    // **Returns:**
61    // * `MetricsStatistics` array encoded into a JSON.
62    //
63    // **Example API Usage:**
64    // --> {"jsonrpc": "2.0", "method": "statistics.get_metric_statistics", "params": [], "id": 1}
65    // <-- {"jsonrpc": "2.0", "result": {...}, "id": 1}
66    pub async fn statistics_get_metric_statistics(&self, params: &JsonValue) -> Result<JsonValue> {
67        // Validate that no parameters are provided
68        validate_empty_params(params)?;
69
70        // Retrieve metric statistics
71        let statistics = self.service.get_metrics_statistics().await?;
72
73        // Convert each metric statistic into a JSON array, returning the collected array
74        let statistics_json: Vec<JsonValue> =
75            statistics.iter().map(|m| m.to_json_array()).collect();
76        Ok(JsonValue::Array(statistics_json))
77    }
78
79    // RPCAPI:
80    // Queries the database to retrieve latest metric statistics.
81    // Returns the readable metric statistics upon success.
82    //
83    // **Params:**
84    // * `None`
85    //
86    // **Returns:**
87    // * `MetricsStatistics` encoded into a JSON.
88    //
89    // **Example API Usage:**
90    // --> {"jsonrpc": "2.0", "method": "statistics.get_latest_metric_statistics", "params": [], "id": 1}
91    // <-- {"jsonrpc": "2.0", "result": {...}, "id": 1}
92    pub async fn statistics_get_latest_metric_statistics(
93        &self,
94        params: &JsonValue,
95    ) -> Result<JsonValue> {
96        // Validate that no parameters are provided
97        validate_empty_params(params)?;
98
99        // Retrieve the latest statistics
100        let statistics = self.service.get_latest_metrics_statistics().await?;
101
102        // Convert the retrieved metrics into a JSON array and return it
103        Ok(statistics.to_json_array())
104    }
105}
106
107#[cfg(test)]
108/// Test module for validating the functionality of RPC methods related to explorer statistics.
109/// Focuses on ensuring proper error handling for invalid parameters across several use cases.
110mod tests {
111
112    use crate::test_utils::{setup, validate_empty_rpc_parameters};
113
114    /// Tests all RPC-related statistics calls when provided with empty parameters, ensuring they
115    /// handle the input correctly and return appropriate validation responses.
116    #[test]
117    fn test_statistics_rpc_calls_for_empty_parameters() {
118        smol::block_on(async {
119            let explorerd = setup();
120
121            let rpc_methods = [
122                "statistics.get_latest_metric_statistics",
123                "statistics.get_metric_statistics",
124                "statistics.get_basic_statistics",
125            ];
126
127            for rpc_method in rpc_methods.iter() {
128                validate_empty_rpc_parameters(&explorerd, rpc_method).await;
129            }
130        });
131    }
132}