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
//! The base data that appear in many RPC request/responses.
//!
//! These are the common "headers" or "base" types that are
//! [`flattened`](https://serde.rs/field-attrs.html#flatten)
//! into many of Monero's RPC types.
//!
//! The `Access*` structs (e.g. [`AccessResponseBase`]
//! are pseudo-deprecated structs for the RPC payment system, see:
//!
//! - <https://github.com/monero-project/monero/commit/2899379791b7542e4eb920b5d9d58cf232806937>
//! - <https://github.com/monero-project/monero/issues/8722>
//! - <https://github.com/monero-project/monero/pull/8843>

//---------------------------------------------------------------------------------------------------- Import
use serde::{Deserialize, Serialize};

use cuprate_epee_encoding::epee_object;

use crate::Status;

//---------------------------------------------------------------------------------------------------- Macro
/// Link the original `monerod` definition for RPC base types.
macro_rules! monero_rpc_base_link {
    ($start:literal..=$end:literal) => {
        concat!(
            "[Definition](https://github.com/monero-project/monero/blob/cc73fe71162d564ffda8e549b79a350bca53c454/src/rpc/core_rpc_server_commands_defs.h#L",
            stringify!($start),
            "-L",
            stringify!($end),
            ")."
        )
    };
}

//---------------------------------------------------------------------------------------------------- Requests
/// The most common base for responses (nothing).
///
#[doc = monero_rpc_base_link!(95..=99)]
#[derive(
    Copy, Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize,
)]
pub struct EmptyRequestBase;

cuprate_epee_encoding::epee_object! {
    EmptyRequestBase,
}

/// A base for RPC request types that support RPC payment.
///
#[doc = monero_rpc_base_link!(114..=122)]
#[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)]
pub struct AccessRequestBase {
    /// The RPC payment client.
    pub client: String,
}

cuprate_epee_encoding::epee_object! {
    AccessRequestBase,
    client: String,
}

//---------------------------------------------------------------------------------------------------- Responses
/// An empty response base.
///
/// This is for response types that do not contain
/// any extra fields, e.g. TODO.
// [`CalcPowResponse`](crate::json::CalcPowResponse).
#[derive(
    Copy, Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize,
)]
pub struct EmptyResponseBase;

cuprate_epee_encoding::epee_object! {
    EmptyResponseBase,
}

/// The most common base for responses.
///
#[doc = monero_rpc_base_link!(101..=112)]
#[derive(
    Copy, Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize,
)]
pub struct ResponseBase {
    /// General RPC error code. [`Status::Ok`] means everything looks good.
    pub status: Status,
    /// States if the result is obtained using the bootstrap mode,
    /// and is therefore not trusted (`true`), or when the daemon
    /// is fully synced and thus handles the RPC locally (`false`).
    pub untrusted: bool,
}

epee_object! {
    ResponseBase,
    status: Status,
    untrusted: bool,
}

/// A base for RPC response types that support RPC payment.
///
#[doc = monero_rpc_base_link!(124..=136)]
#[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)]
pub struct AccessResponseBase {
    /// A flattened [`ResponseBase`].
    #[serde(flatten)]
    pub response_base: ResponseBase,
    /// If payment for RPC is enabled, the number of credits
    /// available to the requesting client. Otherwise, `0`.
    pub credits: u64,
    /// If payment for RPC is enabled, the hash of the
    /// highest block in the chain. Otherwise, empty.
    pub top_hash: String,
}

epee_object! {
    AccessResponseBase,
    credits: u64,
    top_hash: String,
    !flatten: response_base: ResponseBase,
}

//---------------------------------------------------------------------------------------------------- Tests
#[cfg(test)]
mod test {
    // use super::*;
}