cuprated/config/
rpc.rs

1use std::{
2    net::{Ipv4Addr, SocketAddr, SocketAddrV4},
3    time::Duration,
4};
5
6use serde::{Deserialize, Serialize};
7
8use crate::config::macros::config_struct;
9
10config_struct! {
11    /// RPC config.
12    #[derive(Clone, Debug, Default, Deserialize, Serialize, PartialEq, Eq)]
13    #[serde(deny_unknown_fields, default)]
14    pub struct RpcConfig {
15        #[child = true]
16        /// Configuration for the unrestricted RPC server.
17        pub unrestricted: UnrestrictedRpcConfig,
18
19        #[child = true]
20        /// Configuration for the restricted RPC server.
21        pub restricted: RestrictedRpcConfig,
22    }
23}
24
25config_struct! {
26    Shared {
27        /// The address and port the RPC server will listen on.
28        ///
29        /// Type     | IPv4/IPv6 address + port
30        /// Examples | "", "127.0.0.1:18081", "192.168.1.50:18085"
31        pub address: SocketAddr,
32
33        /// Toggle the RPC server.
34        ///
35        /// If `true` the RPC server will be enabled.
36        /// If `false` the RPC server will be disabled.
37        ///
38        /// Type     | boolean
39        /// Examples | true, false
40        pub enable: bool,
41
42        #[comment_out = true]
43        /// If a request is above this byte limit, it will be rejected.
44        ///
45        /// Setting this to `0` will disable the limit.
46        ///
47        /// Type         | Number
48        /// Valid values | >= 0
49        /// Examples     | 0 (no limit), 5242880 (5MB), 10485760 (10MB)
50        pub request_byte_limit: usize,
51
52        // TODO: <https://github.com/Cuprate/cuprate/issues/445>
53    }
54
55    #[derive(Clone, Debug, Deserialize, Serialize, PartialEq, Eq)]
56    #[serde(deny_unknown_fields, default)]
57    pub struct UnrestrictedRpcConfig {
58        /// Allow the unrestricted RPC server to be public.
59        ///
60        /// ⚠️ WARNING ⚠️
61        /// -------------
62        /// Unrestricted RPC should almost never be made available
63        /// to the wider internet. If the unrestricted address
64        /// is a non-local address, `cuprated` will crash,
65        /// unless this setting is set to `true`.
66        ///
67        /// Type         | boolean
68        /// Valid values | true, false
69        pub i_know_what_im_doing_allow_public_unrestricted_rpc: bool,
70    }
71
72    #[derive(Clone, Debug, Deserialize, Serialize, PartialEq, Eq)]
73    #[serde(deny_unknown_fields, default)]
74    pub struct RestrictedRpcConfig {
75        /// Advertise the restricted RPC port.
76        ///
77        /// Setting this to `true` will make `cuprated`
78        /// share the restricted RPC server's port
79        /// publicly to the P2P network.
80        ///
81        /// Type         | boolean
82        /// Valid values | true, false
83        pub advertise: bool,
84    }
85}
86
87impl Default for UnrestrictedRpcConfig {
88    fn default() -> Self {
89        Self {
90            i_know_what_im_doing_allow_public_unrestricted_rpc: false,
91            address: SocketAddr::V4(SocketAddrV4::new(Ipv4Addr::LOCALHOST, 18081)),
92            enable: true,
93            request_byte_limit: 0,
94        }
95    }
96}
97
98impl Default for RestrictedRpcConfig {
99    fn default() -> Self {
100        Self {
101            advertise: false,
102            address: SocketAddr::V4(SocketAddrV4::new(Ipv4Addr::UNSPECIFIED, 18089)),
103            enable: false,
104            // 1 megabyte.
105            // <https://github.com/monero-project/monero/blob/3b01c490953fe92f3c6628fa31d280a4f0490d28/src/cryptonote_config.h#L134>
106            request_byte_limit: 1024 * 1024,
107        }
108    }
109}
110
111impl RestrictedRpcConfig {
112    /// Return the restricted RPC port for P2P if available and public.
113    pub const fn port_for_p2p(&self) -> u16 {
114        if self.advertise && self.enable {
115            self.address.port()
116        } else {
117            0
118        }
119    }
120}