sui_json_rpc_types/
sui_protocol.rs

1// Copyright (c) Mysten Labs, Inc.
2// SPDX-License-Identifier: Apache-2.0
3
4use std::collections::BTreeMap;
5
6use schemars::JsonSchema;
7use serde::{Deserialize, Serialize};
8use serde_with::DisplayFromStr;
9use serde_with::serde_as;
10use sui_protocol_config::{ProtocolConfig, ProtocolConfigValue, ProtocolVersion};
11use sui_types::sui_serde::Readable;
12use sui_types::sui_serde::{AsProtocolVersion, BigInt};
13
14#[serde_as]
15#[derive(Debug, Clone, Deserialize, Serialize, JsonSchema, PartialEq)]
16#[serde(rename_all = "camelCase", rename = "ProtocolConfigValue")]
17pub enum SuiProtocolConfigValue {
18    U16(
19        #[schemars(with = "BigInt<u16>")]
20        #[serde_as(as = "BigInt<u16>")]
21        u16,
22    ),
23    U32(
24        #[schemars(with = "BigInt<u32>")]
25        #[serde_as(as = "BigInt<u32>")]
26        u32,
27    ),
28    U64(
29        #[schemars(with = "BigInt<u64>")]
30        #[serde_as(as = "BigInt<u64>")]
31        u64,
32    ),
33    F64(
34        #[schemars(with = "String")]
35        #[serde_as(as = "DisplayFromStr")]
36        f64,
37    ),
38    Bool(
39        #[schemars(with = "String")]
40        #[serde_as(as = "DisplayFromStr")]
41        bool,
42    ),
43}
44
45impl From<ProtocolConfigValue> for SuiProtocolConfigValue {
46    fn from(value: ProtocolConfigValue) -> Self {
47        match value {
48            ProtocolConfigValue::u16(y) => SuiProtocolConfigValue::U16(y),
49            ProtocolConfigValue::u32(y) => SuiProtocolConfigValue::U32(y),
50            ProtocolConfigValue::u64(x) => SuiProtocolConfigValue::U64(x),
51            ProtocolConfigValue::bool(z) => SuiProtocolConfigValue::Bool(z),
52        }
53    }
54}
55
56#[serde_as]
57#[derive(Debug, Clone, Deserialize, Serialize, JsonSchema, PartialEq)]
58#[serde(rename_all = "camelCase", rename = "ProtocolConfig")]
59pub struct ProtocolConfigResponse {
60    #[schemars(with = "AsProtocolVersion")]
61    #[serde_as(as = "Readable<AsProtocolVersion, _>")]
62    pub min_supported_protocol_version: ProtocolVersion,
63    #[schemars(with = "AsProtocolVersion")]
64    #[serde_as(as = "Readable<AsProtocolVersion, _>")]
65    pub max_supported_protocol_version: ProtocolVersion,
66    #[schemars(with = "AsProtocolVersion")]
67    #[serde_as(as = "Readable<AsProtocolVersion, _>")]
68    pub protocol_version: ProtocolVersion,
69    pub feature_flags: BTreeMap<String, bool>,
70    pub attributes: BTreeMap<String, Option<SuiProtocolConfigValue>>,
71    /// Lossless view of every protocol-config attribute and feature flag, rendered to
72    /// JSON. Unlike `attributes`, this includes non-scalar fields (e.g. lists) and is the
73    /// preferred surface for clients that need to read complex values.
74    #[serde(default)]
75    #[schemars(with = "BTreeMap<String, serde_json::Value>")]
76    pub configs: BTreeMap<String, serde_json::Value>,
77}
78
79impl From<ProtocolConfig> for ProtocolConfigResponse {
80    fn from(config: ProtocolConfig) -> Self {
81        // Render emits explicit `Null`s for fields unset at this protocol version; filter them
82        // out so the public `configs` map only carries values that are actually configured.
83        let mut configs = config
84            .render::<serde_json::Value>(&mut mysten_common::rpc_format::Unmetered)
85            .expect("render to serde_json::Value should succeed")
86            .into_iter()
87            .filter(|(_, v)| !v.is_null())
88            .collect::<BTreeMap<String, serde_json::Value>>();
89
90        // Merge feature flags into `configs` so it stands alone as a complete view.
91        for (k, v) in config.feature_map() {
92            let old = configs.insert(k, serde_json::Value::Bool(v));
93            debug_assert!(
94                old.is_none(),
95                "feature flags and attributes can't have keys which are the same"
96            );
97        }
98
99        ProtocolConfigResponse {
100            protocol_version: config.version,
101            attributes: config
102                .attr_map()
103                .into_iter()
104                .map(|(k, v)| (k, v.map(SuiProtocolConfigValue::from)))
105                .collect(),
106            min_supported_protocol_version: ProtocolVersion::MIN,
107            max_supported_protocol_version: ProtocolVersion::MAX,
108            feature_flags: config.feature_map(),
109            configs,
110        }
111    }
112}