sui_config/rpc_config.rs
1// Copyright (c) Mysten Labs, Inc.
2// SPDX-License-Identifier: Apache-2.0
3
4use std::net::SocketAddr;
5
6#[derive(Clone, Debug, Default, serde::Deserialize, serde::Serialize)]
7#[serde(rename_all = "kebab-case")]
8pub struct RpcConfig {
9 /// Enable indexing of transactions and objects
10 ///
11 /// This enables indexing of transactions and objects which allows for a slightly richer rpc
12 /// api. There are some APIs which will be disabled/enabled based on this config while others
13 /// (eg GetTransaction) will still be enabled regardless of this config but may return slight
14 /// less data (eg GetTransaction won't return the checkpoint that includes the requested
15 /// transaction).
16 ///
17 /// Defaults to `false`, with indexing and APIs which require indexes being disabled
18 #[serde(skip_serializing_if = "Option::is_none")]
19 pub enable_indexing: Option<bool>,
20
21 /// Configure the address to listen on for https
22 ///
23 /// Defaults to `0.0.0.0:9443` if not specified.
24 #[serde(skip_serializing_if = "Option::is_none")]
25 pub https_address: Option<SocketAddr>,
26
27 /// TLS configuration to use for https.
28 ///
29 /// If not provided then the node will not create an https service.
30 #[serde(skip_serializing_if = "Option::is_none")]
31 pub tls: Option<RpcTlsConfig>,
32
33 /// Maxumum budget for rendering a Move value into JSON.
34 ///
35 /// This sets the numbers of bytes that we are willing to spend on rendering field names and
36 /// values when rendering a Move value into a JSON value.
37 ///
38 /// Defaults to `1MiB` if not specified.
39 #[serde(skip_serializing_if = "Option::is_none")]
40 pub max_json_move_value_size: Option<usize>,
41
42 /// Configuration for RPC index initialization and bulk loading
43 #[serde(skip_serializing_if = "Option::is_none")]
44 pub index_initialization: Option<RpcIndexInitConfig>,
45
46 /// Enable indexing of authenticated events
47 ///
48 /// This controls whether authenticated events are indexed and whether the authenticated
49 /// events API endpoints are available. When disabled, authenticated events are not indexed
50 /// and API calls will return an unsupported error.
51 ///
52 /// Defaults to `false`, with authenticated events indexing and API disabled
53 #[serde(skip_serializing_if = "Option::is_none")]
54 pub authenticated_events_indexing: Option<bool>,
55
56 /// Configuration for rendering Objects based on the Display standard
57 #[serde(skip_serializing_if = "Option::is_none")]
58 pub display: Option<DisplayConfig>,
59}
60
61impl RpcConfig {
62 pub fn enable_indexing(&self) -> bool {
63 self.enable_indexing.unwrap_or(false)
64 }
65
66 pub fn https_address(&self) -> SocketAddr {
67 self.https_address
68 .unwrap_or_else(|| SocketAddr::from(([0, 0, 0, 0], 9443)))
69 }
70
71 pub fn tls_config(&self) -> Option<&RpcTlsConfig> {
72 self.tls.as_ref()
73 }
74
75 pub fn max_json_move_value_size(&self) -> usize {
76 self.max_json_move_value_size.unwrap_or(1024 * 1024)
77 }
78
79 pub fn index_initialization_config(&self) -> Option<&RpcIndexInitConfig> {
80 self.index_initialization.as_ref()
81 }
82
83 pub fn authenticated_events_indexing(&self) -> bool {
84 self.authenticated_events_indexing.unwrap_or(false)
85 }
86
87 pub fn display(&self) -> &DisplayConfig {
88 const DEFAULT_DISPLAY_CONFIG: DisplayConfig = DisplayConfig {
89 max_field_depth: None,
90 max_format_nodes: None,
91 max_object_loads: None,
92 max_move_value_depth: None,
93 max_output_size: None,
94 };
95
96 self.display.as_ref().unwrap_or(&DEFAULT_DISPLAY_CONFIG)
97 }
98}
99
100#[derive(Clone, Debug, Default, serde::Deserialize, serde::Serialize)]
101#[serde(rename_all = "kebab-case")]
102pub struct RpcTlsConfig {
103 /// File path to a PEM formatted TLS certificate chain
104 cert: String,
105 /// File path to a PEM formatted TLS private key
106 key: String,
107}
108
109impl RpcTlsConfig {
110 pub fn cert(&self) -> &str {
111 &self.cert
112 }
113
114 pub fn key(&self) -> &str {
115 &self.key
116 }
117}
118
119/// Configuration for RPC index initialization and bulk loading
120#[derive(Clone, Debug, Default, serde::Deserialize, serde::Serialize)]
121#[serde(rename_all = "kebab-case")]
122pub struct RpcIndexInitConfig {
123 /// Override for RocksDB's set_db_write_buffer_size during bulk indexing.
124 /// This is the total memory budget for all column families' memtables.
125 ///
126 /// Defaults to 90% of system RAM if not specified.
127 #[serde(skip_serializing_if = "Option::is_none")]
128 pub db_write_buffer_size: Option<usize>,
129
130 /// Override for each column family's write buffer size during bulk indexing.
131 ///
132 /// Defaults to 25% of system RAM divided by max_write_buffer_number if not specified.
133 #[serde(skip_serializing_if = "Option::is_none")]
134 pub cf_write_buffer_size: Option<usize>,
135
136 /// Override for the maximum number of write buffers per column family during bulk indexing.
137 /// This value is capped at 32 as an upper bound.
138 ///
139 /// Defaults to a dynamic value based on system RAM if not specified.
140 #[serde(skip_serializing_if = "Option::is_none")]
141 pub cf_max_write_buffer_number: Option<i32>,
142
143 /// Override for the number of background jobs during bulk indexing.
144 ///
145 /// Defaults to the number of CPU cores if not specified.
146 #[serde(skip_serializing_if = "Option::is_none")]
147 pub max_background_jobs: Option<i32>,
148
149 /// Override for the batch size limit during bulk indexing.
150 /// This controls how much data is accumulated in memory before flushing to disk.
151 ///
152 /// Defaults to half the write buffer size or 128MB, whichever is smaller.
153 #[serde(skip_serializing_if = "Option::is_none")]
154 pub batch_size_limit: Option<usize>,
155}
156
157#[derive(Clone, Debug, Default, serde::Deserialize, serde::Serialize)]
158#[serde(rename_all = "kebab-case")]
159pub struct DisplayConfig {
160 /// Maximum number of times the parser can recurse into nested structures. Depth does not
161 /// account for all nodes, only nodes that can be contained within themselves.
162 ///
163 /// Defaults to `32` if not specified.
164 #[serde(skip_serializing_if = "Option::is_none")]
165 max_field_depth: Option<usize>,
166
167 /// Maximum number of AST nodes that can be allocated during parsing. This counts all values
168 /// that are instances of AST types (but not, for example, `Vec<T>`).
169 ///
170 /// Defaults to `32768` if not specified.
171 #[serde(skip_serializing_if = "Option::is_none")]
172 max_format_nodes: Option<usize>,
173
174 /// Maximum number of objects that can be loaded during formatting.
175 ///
176 /// Defaults to `8` if not specified.
177 #[serde(skip_serializing_if = "Option::is_none")]
178 max_object_loads: Option<usize>,
179
180 /// Maximum depth to use when converting a rendered Display value to JSON.
181 ///
182 /// Defaults to `32` if not specified.
183 #[serde(skip_serializing_if = "Option::is_none")]
184 max_move_value_depth: Option<usize>,
185
186 /// Maxumum budget for rendering an object based on its Display template.
187 ///
188 /// This sets the numbers of bytes that we are willing to spend on rendering field names and
189 /// values when rendering an object based on its Display template.
190 ///
191 /// Defaults to `1MiB` if not specified.
192 #[serde(skip_serializing_if = "Option::is_none")]
193 max_output_size: Option<usize>,
194}
195
196impl DisplayConfig {
197 pub fn max_field_depth(&self) -> usize {
198 self.max_field_depth.unwrap_or(32)
199 }
200
201 pub fn max_format_nodes(&self) -> usize {
202 self.max_format_nodes.unwrap_or(32768)
203 }
204
205 pub fn max_object_loads(&self) -> usize {
206 self.max_object_loads.unwrap_or(8)
207 }
208
209 pub fn max_move_value_depth(&self) -> usize {
210 self.max_move_value_depth.unwrap_or(32)
211 }
212
213 pub fn max_output_size(&self) -> usize {
214 self.max_output_size.unwrap_or(1024 * 1024)
215 }
216}