1use serde::Deserialize;
5use serde::Serialize;
6use sui_protocol_config::ProtocolConfig;
7use sui_types::base_types::ObjectID;
8use sui_types::base_types::SuiAddress;
9
10pub use sui_name_service::NameServiceConfig;
11
12#[derive(Debug)]
13pub struct RpcConfig {
14 pub objects: ObjectsConfig,
16
17 pub dynamic_fields: DynamicFieldsConfig,
19
20 pub transactions: TransactionsConfig,
22
23 pub name_service: NameServiceConfig,
25
26 pub coins: CoinsConfig,
28
29 pub node: NodeConfig,
32
33 pub package_resolver: sui_package_resolver::Limits,
35}
36
37#[derive(Clone, Default, Debug, Deserialize, Serialize)]
38#[serde(default, rename_all = "kebab-case", deny_unknown_fields)]
39pub struct RpcLayer {
40 pub objects: ObjectsLayer,
41 pub dynamic_fields: DynamicFieldsLayer,
42 pub transactions: TransactionsLayer,
43 pub name_service: NameServiceLayer,
44 pub coins: CoinsLayer,
45 pub node: NodeLayer,
46 pub package_resolver: PackageResolverLayer,
47}
48
49#[derive(Debug, Clone)]
50pub struct ObjectsConfig {
51 pub max_multi_get_objects: usize,
53
54 pub default_page_size: usize,
56
57 pub max_page_size: usize,
60
61 pub max_display_field_depth: usize,
63
64 pub max_display_format_nodes: usize,
66
67 pub max_display_object_loads: usize,
69
70 pub max_display_output_size: usize,
72
73 pub max_filter_depth: usize,
75
76 pub max_type_filters: usize,
78
79 pub filter_scan_size: usize,
82
83 pub obj_retry_count: usize,
86
87 pub obj_retry_interval_ms: u64,
89}
90
91#[derive(Clone, Default, Debug, Deserialize, Serialize)]
92#[serde(default, rename_all = "kebab-case", deny_unknown_fields)]
93pub struct ObjectsLayer {
94 pub max_multi_get_objects: Option<usize>,
95 pub default_page_size: Option<usize>,
96 pub max_page_size: Option<usize>,
97 pub max_display_field_depth: Option<usize>,
98 pub max_display_format_nodes: Option<usize>,
99 pub max_display_object_loads: Option<usize>,
100 pub max_display_output_size: Option<usize>,
101 pub max_filter_depth: Option<usize>,
102 pub max_type_filters: Option<usize>,
103 pub filter_scan_size: Option<usize>,
104 pub obj_retry_count: Option<usize>,
105 pub obj_retry_interval_ms: Option<u64>,
106}
107
108#[derive(Debug, Clone)]
109pub struct DynamicFieldsConfig {
110 pub default_page_size: usize,
112
113 pub max_page_size: usize,
116}
117
118#[derive(Clone, Default, Debug, Deserialize, Serialize)]
119#[serde(default, rename_all = "kebab-case", deny_unknown_fields)]
120pub struct DynamicFieldsLayer {
121 pub default_page_size: Option<usize>,
122 pub max_page_size: Option<usize>,
123}
124
125#[derive(Debug, Clone)]
126pub struct TransactionsConfig {
127 pub default_page_size: usize,
129
130 pub max_page_size: usize,
133
134 pub tx_retry_count: usize,
137
138 pub tx_retry_interval_ms: u64,
140}
141
142#[derive(Clone, Default, Debug, Deserialize, Serialize)]
143#[serde(default, rename_all = "kebab-case", deny_unknown_fields)]
144pub struct TransactionsLayer {
145 pub default_page_size: Option<usize>,
146 pub max_page_size: Option<usize>,
147 pub tx_retry_count: Option<usize>,
148 pub tx_retry_interval_ms: Option<u64>,
149}
150
151#[derive(Clone, Default, Debug, Deserialize, Serialize)]
152#[serde(default, rename_all = "kebab-case", deny_unknown_fields)]
153pub struct NameServiceLayer {
154 pub package_address: Option<SuiAddress>,
155 pub registry_id: Option<ObjectID>,
156 pub reverse_registry_id: Option<ObjectID>,
157}
158
159#[derive(Debug, Clone)]
160pub struct CoinsConfig {
161 pub default_page_size: usize,
163
164 pub max_page_size: usize,
167}
168
169#[derive(Clone, Default, Debug, Deserialize, Serialize)]
170#[serde(default, rename_all = "kebab-case", deny_unknown_fields)]
171pub struct CoinsLayer {
172 pub default_page_size: Option<usize>,
173 pub max_page_size: Option<usize>,
174}
175
176#[derive(Clone, Debug)]
177pub struct NodeConfig {
178 pub header_value: String,
180 pub max_request_size: u32,
182}
183
184#[derive(Clone, Default, Debug, Deserialize, Serialize)]
185#[serde(default, rename_all = "kebab-case", deny_unknown_fields)]
186pub struct NodeLayer {
187 pub header_value: Option<String>,
188 pub max_request_size: Option<u32>,
189}
190
191#[derive(Clone, Debug, Deserialize, Serialize)]
192#[serde(default, rename_all = "kebab-case", deny_unknown_fields)]
193pub struct PackageResolverLayer {
194 pub max_type_argument_depth: usize,
195 pub max_type_argument_width: usize,
196 pub max_type_nodes: usize,
197 pub max_move_value_depth: usize,
198}
199
200impl RpcLayer {
201 pub fn example() -> Self {
204 Self {
205 objects: ObjectsConfig::default().into(),
206 dynamic_fields: DynamicFieldsConfig::default().into(),
207 transactions: TransactionsConfig::default().into(),
208 name_service: NameServiceConfig::default().into(),
209 coins: CoinsConfig::default().into(),
210 package_resolver: PackageResolverLayer::default(),
211 node: NodeConfig::default().into(),
212 }
213 }
214
215 pub fn finish(self) -> RpcConfig {
216 RpcConfig {
217 objects: self.objects.finish(ObjectsConfig::default()),
218 dynamic_fields: self.dynamic_fields.finish(DynamicFieldsConfig::default()),
219 transactions: self.transactions.finish(TransactionsConfig::default()),
220 name_service: self.name_service.finish(NameServiceConfig::default()),
221 coins: self.coins.finish(CoinsConfig::default()),
222 node: self.node.finish(NodeConfig::default()),
223 package_resolver: self.package_resolver.finish(),
224 }
225 }
226}
227
228impl ObjectsLayer {
229 pub fn finish(self, base: ObjectsConfig) -> ObjectsConfig {
230 ObjectsConfig {
231 max_multi_get_objects: self
232 .max_multi_get_objects
233 .unwrap_or(base.max_multi_get_objects),
234 default_page_size: self.default_page_size.unwrap_or(base.default_page_size),
235 max_page_size: self.max_page_size.unwrap_or(base.max_page_size),
236 max_display_field_depth: self
237 .max_display_field_depth
238 .unwrap_or(base.max_display_field_depth),
239 max_display_format_nodes: self
240 .max_display_format_nodes
241 .unwrap_or(base.max_display_format_nodes),
242 max_display_object_loads: self
243 .max_display_object_loads
244 .unwrap_or(base.max_display_object_loads),
245 max_display_output_size: self
246 .max_display_output_size
247 .unwrap_or(base.max_display_output_size),
248 max_filter_depth: self.max_filter_depth.unwrap_or(base.max_filter_depth),
249 max_type_filters: self.max_type_filters.unwrap_or(base.max_type_filters),
250 filter_scan_size: self.filter_scan_size.unwrap_or(base.filter_scan_size),
251 obj_retry_count: self.obj_retry_count.unwrap_or(base.obj_retry_count),
252 obj_retry_interval_ms: self
253 .obj_retry_interval_ms
254 .unwrap_or(base.obj_retry_interval_ms),
255 }
256 }
257}
258
259impl DynamicFieldsLayer {
260 pub fn finish(self, base: DynamicFieldsConfig) -> DynamicFieldsConfig {
261 DynamicFieldsConfig {
262 default_page_size: self.default_page_size.unwrap_or(base.default_page_size),
263 max_page_size: self.max_page_size.unwrap_or(base.max_page_size),
264 }
265 }
266}
267
268impl TransactionsLayer {
269 pub fn finish(self, base: TransactionsConfig) -> TransactionsConfig {
270 TransactionsConfig {
271 default_page_size: self.default_page_size.unwrap_or(base.default_page_size),
272 max_page_size: self.max_page_size.unwrap_or(base.max_page_size),
273 tx_retry_count: self.tx_retry_count.unwrap_or(base.tx_retry_count),
274 tx_retry_interval_ms: self
275 .tx_retry_interval_ms
276 .unwrap_or(base.tx_retry_interval_ms),
277 }
278 }
279}
280
281impl NameServiceLayer {
282 pub fn finish(self, base: NameServiceConfig) -> NameServiceConfig {
283 NameServiceConfig {
284 package_address: self.package_address.unwrap_or(base.package_address),
285 registry_id: self.registry_id.unwrap_or(base.registry_id),
286 reverse_registry_id: self.reverse_registry_id.unwrap_or(base.reverse_registry_id),
287 }
288 }
289}
290
291impl CoinsLayer {
292 pub fn finish(self, base: CoinsConfig) -> CoinsConfig {
293 CoinsConfig {
294 default_page_size: self.default_page_size.unwrap_or(base.default_page_size),
295 max_page_size: self.max_page_size.unwrap_or(base.max_page_size),
296 }
297 }
298}
299
300impl NodeLayer {
301 pub fn finish(self, base: NodeConfig) -> NodeConfig {
302 NodeConfig {
303 header_value: self.header_value.unwrap_or(base.header_value),
304 max_request_size: self.max_request_size.unwrap_or(base.max_request_size),
305 }
306 }
307}
308
309impl PackageResolverLayer {
310 pub fn finish(self) -> sui_package_resolver::Limits {
311 sui_package_resolver::Limits {
312 max_type_argument_depth: self.max_type_argument_depth,
313 max_type_argument_width: self.max_type_argument_width,
314 max_type_nodes: self.max_type_nodes,
315 max_move_value_depth: self.max_move_value_depth,
316 }
317 }
318}
319
320impl Default for RpcConfig {
321 fn default() -> Self {
322 Self {
323 objects: ObjectsConfig::default(),
324 dynamic_fields: DynamicFieldsConfig::default(),
325 transactions: TransactionsConfig::default(),
326 name_service: NameServiceConfig::default(),
327 coins: CoinsConfig::default(),
328 node: NodeConfig::default(),
329 package_resolver: PackageResolverLayer::default().finish(),
330 }
331 }
332}
333
334impl Default for ObjectsConfig {
335 fn default() -> Self {
336 let display_limits = sui_display::v2::Limits::default();
337
338 Self {
339 max_multi_get_objects: 50,
340 default_page_size: 50,
341 max_page_size: 100,
342 max_display_field_depth: display_limits.max_depth,
343 max_display_format_nodes: display_limits.max_nodes,
344 max_display_object_loads: display_limits.max_loads,
345 max_display_output_size: 1024 * 1024,
346 max_filter_depth: 3,
347 max_type_filters: 10,
348 filter_scan_size: 200,
349 obj_retry_count: 5,
350 obj_retry_interval_ms: 100,
351 }
352 }
353}
354
355impl Default for DynamicFieldsConfig {
356 fn default() -> Self {
357 Self {
358 default_page_size: 50,
359 max_page_size: 100,
360 }
361 }
362}
363
364impl Default for TransactionsConfig {
365 fn default() -> Self {
366 Self {
367 default_page_size: 50,
368 max_page_size: 100,
369 tx_retry_count: 5,
370 tx_retry_interval_ms: 100,
371 }
372 }
373}
374
375impl Default for CoinsConfig {
376 fn default() -> Self {
377 Self {
378 default_page_size: 50,
379 max_page_size: 100,
380 }
381 }
382}
383
384impl Default for NodeConfig {
385 fn default() -> Self {
386 Self {
387 header_value: "sui-indexer-alt-jsonrpc".to_string(),
388 max_request_size: (10 * 2) << 20, }
390 }
391}
392
393impl Default for PackageResolverLayer {
394 fn default() -> Self {
395 let config = ProtocolConfig::get_for_max_version_UNSAFE();
399
400 Self {
401 max_type_argument_depth: config.max_type_argument_depth() as usize,
402 max_type_argument_width: config.max_generic_instantiation_length() as usize,
403 max_type_nodes: config.max_type_nodes() as usize,
404 max_move_value_depth: config.max_move_value_depth() as usize,
405 }
406 }
407}
408
409impl From<ObjectsConfig> for ObjectsLayer {
410 fn from(config: ObjectsConfig) -> Self {
411 Self {
412 max_multi_get_objects: Some(config.max_multi_get_objects),
413 default_page_size: Some(config.default_page_size),
414 max_page_size: Some(config.max_page_size),
415 max_display_field_depth: Some(config.max_display_field_depth),
416 max_display_format_nodes: Some(config.max_display_format_nodes),
417 max_display_object_loads: Some(config.max_display_object_loads),
418 max_display_output_size: Some(config.max_display_output_size),
419 max_filter_depth: Some(config.max_filter_depth),
420 max_type_filters: Some(config.max_type_filters),
421 filter_scan_size: Some(config.filter_scan_size),
422 obj_retry_count: Some(config.obj_retry_count),
423 obj_retry_interval_ms: Some(config.obj_retry_interval_ms),
424 }
425 }
426}
427
428impl ObjectsConfig {
429 pub(crate) fn display(&self) -> sui_display::v2::Limits {
430 sui_display::v2::Limits {
431 max_depth: self.max_display_field_depth,
432 max_nodes: self.max_display_format_nodes,
433 max_loads: self.max_display_object_loads,
434 }
435 }
436}
437
438impl From<DynamicFieldsConfig> for DynamicFieldsLayer {
439 fn from(config: DynamicFieldsConfig) -> Self {
440 Self {
441 default_page_size: Some(config.default_page_size),
442 max_page_size: Some(config.max_page_size),
443 }
444 }
445}
446
447impl From<TransactionsConfig> for TransactionsLayer {
448 fn from(config: TransactionsConfig) -> Self {
449 Self {
450 default_page_size: Some(config.default_page_size),
451 max_page_size: Some(config.max_page_size),
452 tx_retry_count: Some(config.tx_retry_count),
453 tx_retry_interval_ms: Some(config.tx_retry_interval_ms),
454 }
455 }
456}
457
458impl From<NameServiceConfig> for NameServiceLayer {
459 fn from(config: NameServiceConfig) -> Self {
460 Self {
461 package_address: Some(config.package_address),
462 registry_id: Some(config.registry_id),
463 reverse_registry_id: Some(config.reverse_registry_id),
464 }
465 }
466}
467
468impl From<CoinsConfig> for CoinsLayer {
469 fn from(config: CoinsConfig) -> Self {
470 Self {
471 default_page_size: Some(config.default_page_size),
472 max_page_size: Some(config.max_page_size),
473 }
474 }
475}
476
477impl From<NodeConfig> for NodeLayer {
478 fn from(config: NodeConfig) -> Self {
479 Self {
480 header_value: Some(config.header_value),
481 max_request_size: Some(config.max_request_size),
482 }
483 }
484}