explorerd/rpc/
statistics.rs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
/* This file is part of DarkFi (https://dark.fi)
 *
 * Copyright (C) 2020-2025 Dyne.org foundation
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as
 * published by the Free Software Foundation, either version 3 of the
 * License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program.  If not, see <https://www.gnu.org/licenses/>.
 */

use std::vec::Vec;

use tinyjson::JsonValue;

use darkfi::{rpc::jsonrpc::validate_empty_params, Result};

use crate::Explorerd;

impl Explorerd {
    // RPCAPI:
    // Queries the database to retrieve current basic statistics.
    // Returns the readable transaction upon success.
    //
    // **Params:**
    // * `None`
    //
    // **Returns:**
    // * `BaseStatistics` encoded into a JSON.
    //
    // **Example API Usage:**
    // --> {"jsonrpc": "2.0", "method": "statistics.get_basic_statistics", "params": [], "id": 1}
    // <-- {"jsonrpc": "2.0", "result": {...}, "id": 1}
    pub async fn statistics_get_basic_statistics(&self, params: &JsonValue) -> Result<JsonValue> {
        // Validate that no parameters are provided
        validate_empty_params(params)?;

        // Attempt to retrieve base statistics; if found, convert to a JSON array,
        // otherwise return an empty JSON array
        match self.service.get_base_statistics()? {
            Some(statistics) => Ok(statistics.to_json_array()),
            None => Ok(JsonValue::Array(vec![])),
        }
    }

    // RPCAPI:
    // Queries the database to retrieve all metrics statistics.
    // Returns a collection of metric statistics upon success.
    //
    // **Params:**
    // * `None`
    //
    // **Returns:**
    // * `MetricsStatistics` array encoded into a JSON.
    //
    // **Example API Usage:**
    // --> {"jsonrpc": "2.0", "method": "statistics.get_metric_statistics", "params": [], "id": 1}
    // <-- {"jsonrpc": "2.0", "result": {...}, "id": 1}
    pub async fn statistics_get_metric_statistics(&self, params: &JsonValue) -> Result<JsonValue> {
        // Validate that no parameters are provided
        validate_empty_params(params)?;

        // Retrieve metric statistics
        let statistics = self.service.get_metrics_statistics().await?;

        // Convert each metric statistic into a JSON array, returning the collected array
        let statistics_json: Vec<JsonValue> =
            statistics.iter().map(|m| m.to_json_array()).collect();
        Ok(JsonValue::Array(statistics_json))
    }

    // RPCAPI:
    // Queries the database to retrieve latest metric statistics.
    // Returns the readable metric statistics upon success.
    //
    // **Params:**
    // * `None`
    //
    // **Returns:**
    // * `MetricsStatistics` encoded into a JSON.
    //
    // **Example API Usage:**
    // --> {"jsonrpc": "2.0", "method": "statistics.get_latest_metric_statistics", "params": [], "id": 1}
    // <-- {"jsonrpc": "2.0", "result": {...}, "id": 1}
    pub async fn statistics_get_latest_metric_statistics(
        &self,
        params: &JsonValue,
    ) -> Result<JsonValue> {
        // Validate that no parameters are provided
        validate_empty_params(params)?;

        // Retrieve the latest statistics
        let statistics = self.service.get_latest_metrics_statistics().await?;

        // Convert the retrieved metrics into a JSON array and return it
        Ok(statistics.to_json_array())
    }
}

#[cfg(test)]
/// Test module for validating the functionality of RPC methods related to explorer statistics.
/// Focuses on ensuring proper error handling for invalid parameters across several use cases.
mod tests {

    use crate::test_utils::{setup, validate_empty_rpc_parameters};

    /// Tests all RPC-related statistics calls when provided with empty parameters, ensuring they
    /// handle the input correctly and return appropriate validation responses.
    #[test]
    fn test_statistics_rpc_calls_for_empty_parameters() {
        smol::block_on(async {
            let explorerd = setup();

            let rpc_methods = [
                "statistics.get_latest_metric_statistics",
                "statistics.get_metric_statistics",
                "statistics.get_basic_statistics",
            ];

            for rpc_method in rpc_methods.iter() {
                validate_empty_rpc_parameters(&explorerd, rpc_method).await;
            }
        });
    }
}