From 587ae588ac57b2d0b737ed927ee90b6e3d2897f5 Mon Sep 17 00:00:00 2001 From: oxade <93547199+oxade@users.noreply.github.com> Date: Tue, 15 Aug 2023 12:47:09 +0200 Subject: [PATCH] [graphql/rpc] Protocol config impl (#13402) --- .../schema/draft_schema.graphql | 13 ++- .../src/server/data_provider.rs | 38 +++++++++ crates/sui-graphql-rpc/src/types/display.rs | 10 +++ crates/sui-graphql-rpc/src/types/gas.rs | 29 +++++++ crates/sui-graphql-rpc/src/types/mod.rs | 3 + crates/sui-graphql-rpc/src/types/object.rs | 1 + .../src/types/protocol_config.rs | 83 +++++++++++++++++++ crates/sui-graphql-rpc/src/types/query.rs | 14 +++- ...apshot_tests__test__schema_sdl_export.snap | 19 +++++ 9 files changed, 206 insertions(+), 4 deletions(-) create mode 100644 crates/sui-graphql-rpc/src/types/display.rs create mode 100644 crates/sui-graphql-rpc/src/types/gas.rs create mode 100644 crates/sui-graphql-rpc/src/types/protocol_config.rs diff --git a/crates/sui-graphql-rpc/schema/draft_schema.graphql b/crates/sui-graphql-rpc/schema/draft_schema.graphql index 09f0c96be1ebe..560811f848784 100644 --- a/crates/sui-graphql-rpc/schema/draft_schema.graphql +++ b/crates/sui-graphql-rpc/schema/draft_schema.graphql @@ -421,15 +421,22 @@ type Epoch { type ProtocolConfigs { protocolVersion: Int! - configs: [ProtocolConfig] - config(key: String!): ProtocolConfig + featureFlags: [ProtocolConfigFeatureFlag] + configs: [ProtocolConfigAttr] + config(key: String!): ProtocolConfigAttr + featureFlag(key: String!): ProtocolConfigFeatureFlag } -type ProtocolConfig { +type ProtocolConfigAttr { key: String! value: String! } +type ProtocolConfigFeatureFlag { + key: String! + value: Boolean! +} + type SystemParameters { durationMs: BigInt stakeSubsidyStartEpoch: Int diff --git a/crates/sui-graphql-rpc/src/server/data_provider.rs b/crates/sui-graphql-rpc/src/server/data_provider.rs index 727a738e23167..80cae43271f47 100644 --- a/crates/sui-graphql-rpc/src/server/data_provider.rs +++ b/crates/sui-graphql-rpc/src/server/data_provider.rs @@ -9,6 +9,9 @@ use crate::types::base64::Base64; use crate::types::big_int::BigInt; use crate::types::object::ObjectFilter; use crate::types::object::ObjectKind; +use crate::types::protocol_config::ProtocolConfigAttr; +use crate::types::protocol_config::ProtocolConfigFeatureFlag; +use crate::types::protocol_config::ProtocolConfigs; use crate::types::transaction_block::TransactionBlock; use crate::types::{object::Object, sui_address::SuiAddress}; use async_graphql::connection::{Connection, Edge}; @@ -172,6 +175,41 @@ pub(crate) async fn fetch_chain_id(cl: &SuiClient) -> Result { Ok(cl.read_api().get_chain_identifier().await?) } +pub(crate) async fn fetch_protocol_config( + cl: &SuiClient, + version: Option, +) -> Result { + let cfg = cl + .read_api() + .get_protocol_config(version.map(|x| x.into())) + .await?; + + Ok(ProtocolConfigs { + configs: cfg + .attributes + .into_iter() + .map(|(k, v)| ProtocolConfigAttr { + key: k, + // TODO: what to return when value is None? nothing? + // TODO: do we want to return type info separately? + value: match v { + Some(q) => format!("{:?}", q), + None => "".to_string(), + }, + }) + .collect(), + feature_flags: cfg + .feature_flags + .into_iter() + .map(|x| ProtocolConfigFeatureFlag { + key: x.0, + value: x.1, + }) + .collect(), + protocol_version: cfg.protocol_version.as_u64(), + }) +} + fn convert_bal(b: sui_json_rpc_types::Balance) -> Balance { Balance { coin_object_count: b.coin_object_count as u64, diff --git a/crates/sui-graphql-rpc/src/types/display.rs b/crates/sui-graphql-rpc/src/types/display.rs new file mode 100644 index 0000000000000..b0ed320cb4494 --- /dev/null +++ b/crates/sui-graphql-rpc/src/types/display.rs @@ -0,0 +1,10 @@ +// Copyright (c) Mysten Labs, Inc. +// SPDX-License-Identifier: Apache-2.0 + +use async_graphql::*; + +#[derive(Clone, Debug, PartialEq, Eq, SimpleObject)] +pub(crate) struct DisplayEntry { + pub key: String, + pub value: String, +} diff --git a/crates/sui-graphql-rpc/src/types/gas.rs b/crates/sui-graphql-rpc/src/types/gas.rs new file mode 100644 index 0000000000000..729801b3cff93 --- /dev/null +++ b/crates/sui-graphql-rpc/src/types/gas.rs @@ -0,0 +1,29 @@ +// Copyright (c) Mysten Labs, Inc. +// SPDX-License-Identifier: Apache-2.0 + +use crate::types::object::Object; +use async_graphql::*; + +use super::{address::Address, big_int::BigInt}; + +#[derive(Clone, Debug, PartialEq, Eq, SimpleObject)] +pub(crate) struct GasInput { + pub gas_sponsor: Option
, + pub gas_payment: Option>, + pub gas_price: Option, + pub gas_budget: Option, +} + +#[derive(Clone, Debug, PartialEq, Eq, SimpleObject)] +pub(crate) struct GasCostSummary { + pub computation_cost: Option, + pub storage_cost: Option, + pub storage_rebate: Option, + pub non_refundable_storage_fee: Option, +} + +#[derive(Clone, Debug, PartialEq, Eq, SimpleObject)] +pub(crate) struct GasEffects { + pub gas_object: Option, + pub gas_summary: Option, +} diff --git a/crates/sui-graphql-rpc/src/types/mod.rs b/crates/sui-graphql-rpc/src/types/mod.rs index 1fc3497a10cfc..a3a57d8ae3eae 100644 --- a/crates/sui-graphql-rpc/src/types/mod.rs +++ b/crates/sui-graphql-rpc/src/types/mod.rs @@ -7,9 +7,12 @@ pub(crate) mod base64; pub(crate) mod big_int; pub(crate) mod coin; pub(crate) mod date_time; +pub(crate) mod display; +pub(crate) mod gas; pub(crate) mod name_service; pub(crate) mod object; pub(crate) mod owner; +pub(crate) mod protocol_config; pub(crate) mod query; pub(crate) mod stake; pub(crate) mod sui_address; diff --git a/crates/sui-graphql-rpc/src/types/object.rs b/crates/sui-graphql-rpc/src/types/object.rs index 7b82742c8e2cd..60e5b7479abed 100644 --- a/crates/sui-graphql-rpc/src/types/object.rs +++ b/crates/sui-graphql-rpc/src/types/object.rs @@ -17,6 +17,7 @@ use crate::{ types::base64::Base64, }; +#[derive(Clone, Eq, PartialEq, Debug)] pub(crate) struct Object { pub address: SuiAddress, pub version: u64, diff --git a/crates/sui-graphql-rpc/src/types/protocol_config.rs b/crates/sui-graphql-rpc/src/types/protocol_config.rs new file mode 100644 index 0000000000000..0da7ad9fa1fa2 --- /dev/null +++ b/crates/sui-graphql-rpc/src/types/protocol_config.rs @@ -0,0 +1,83 @@ +// Copyright (c) Mysten Labs, Inc. +// SPDX-License-Identifier: Apache-2.0 + +use async_graphql::*; + +use crate::server::data_provider::fetch_protocol_config; + +#[derive(Clone, Debug, PartialEq, Eq, SimpleObject)] +pub(crate) struct ProtocolConfigAttr { + pub key: String, + pub value: String, +} + +#[derive(Clone, Debug, PartialEq, Eq, SimpleObject)] +pub(crate) struct ProtocolConfigFeatureFlag { + pub key: String, + pub value: bool, +} + +#[derive(Clone, Debug, PartialEq, Eq)] +pub(crate) struct ProtocolConfigs { + pub configs: Vec, + pub feature_flags: Vec, + pub protocol_version: u64, +} + +#[allow(unreachable_code)] +#[allow(unused_variables)] +#[Object] +impl ProtocolConfigs { + async fn configs(&self, ctx: &Context<'_>) -> Result>> { + Ok(Some( + fetch_protocol_config(ctx.data_unchecked::(), None) + .await? + .configs, + )) + } + + async fn feature_flags( + &self, + ctx: &Context<'_>, + ) -> Result>> { + Ok(Some( + fetch_protocol_config(ctx.data_unchecked::(), None) + .await? + .feature_flags, + )) + } + + async fn protocol_version(&self, ctx: &Context<'_>) -> Result { + Ok( + fetch_protocol_config(ctx.data_unchecked::(), None) + .await? + .protocol_version, + ) + } + + async fn config(&self, ctx: &Context<'_>, key: String) -> Result> { + match self + .configs(ctx) + .await? + .map(|configs| configs.into_iter().find(|config| config.key == key)) + { + Some(config) => Ok(config), + None => Ok(None), + } + } + + async fn feature_flag( + &self, + ctx: &Context<'_>, + key: String, + ) -> Result> { + match self + .feature_flags(ctx) + .await? + .map(|flags| flags.into_iter().find(|config| config.key == key)) + { + Some(config) => Ok(config), + None => Ok(None), + } + } +} diff --git a/crates/sui-graphql-rpc/src/types/query.rs b/crates/sui-graphql-rpc/src/types/query.rs index 91a3a8b4168b8..f6b41b8bb0e76 100644 --- a/crates/sui-graphql-rpc/src/types/query.rs +++ b/crates/sui-graphql-rpc/src/types/query.rs @@ -3,7 +3,10 @@ use async_graphql::*; -use super::{address::Address, object::Object, owner::ObjectOwner, sui_address::SuiAddress}; +use super::{ + address::Address, object::Object, owner::ObjectOwner, protocol_config::ProtocolConfigs, + sui_address::SuiAddress, +}; use crate::server::data_provider::fetch_chain_id; pub(crate) struct Query; @@ -38,4 +41,13 @@ impl Query { async fn address(&self, address: SuiAddress) -> Option
{ Some(Address { address }) } + + async fn protocol_config( + &self, + ctx: &Context<'_>, + protocol_version: Option, + ) -> Result { + let cl = ctx.data_unchecked::(); + crate::server::data_provider::fetch_protocol_config(cl, protocol_version).await + } } diff --git a/crates/sui-graphql-rpc/tests/snapshots/snapshot_tests__test__schema_sdl_export.snap b/crates/sui-graphql-rpc/tests/snapshots/snapshot_tests__test__schema_sdl_export.snap index 76065e789f342..6b989b6fa5880 100644 --- a/crates/sui-graphql-rpc/tests/snapshots/snapshot_tests__test__schema_sdl_export.snap +++ b/crates/sui-graphql-rpc/tests/snapshots/snapshot_tests__test__schema_sdl_export.snap @@ -155,11 +155,30 @@ type PageInfo { endCursor: String } +type ProtocolConfigAttr { + key: String! + value: String! +} + +type ProtocolConfigFeatureFlag { + key: String! + value: Boolean! +} + +type ProtocolConfigs { + configs: [ProtocolConfigAttr!] + featureFlags: [ProtocolConfigFeatureFlag!] + protocolVersion: Int! + config(key: String!): ProtocolConfigAttr + featureFlag(key: String!): ProtocolConfigFeatureFlag +} + type Query { chainIdentifier: String! owner(address: SuiAddress!): ObjectOwner object(address: SuiAddress!, version: Int): Object address(address: SuiAddress!): Address + protocolConfig(protocolVersion: Int): ProtocolConfigs! } type StakeConnection {