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