diff --git a/Cargo.lock b/Cargo.lock index 1758cfb76d417..381e6fa39604c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5211,6 +5211,7 @@ dependencies = [ "scopeguard", "serde 1.0.137", "serde-reflection", + "serde_json", "serde_yaml", "signature", "sui-adapter", diff --git a/doc/src/build/json-rpc.md b/doc/src/build/json-rpc.md index a8a0d913c830f..a3a9827c7b450 100644 --- a/doc/src/build/json-rpc.md +++ b/doc/src/build/json-rpc.md @@ -197,17 +197,19 @@ the [Move](move.md#move) language): ```shell curl --location --request POST $SUI_RPC_HOST \ --header 'Content-Type: application/json' \ ---data-raw '{ "jsonrpc":"2.0", - "method":"sui_moveCall", - "params":["{{owner_address}}", - "0x2", - "GAS", - "transfer", - [], - ["Pure": "{{coin_object_id_base64}}", "Pure": "{{to_address_base64}}"}], - "{{gas_object_id}}", - 2000], - "id":1}' | json_pp +--data-raw '{ "jsonrpc": "2.0", + "method": "sui_moveCall", + "params": [ + "{{owner_address}}", + "0000000000000000000000000000000000000002", + "Coin", + "transfer_", + ["0x2::SUI::SUI"], + ["0x{{coin_object_id}}",10000, "0x{{recipient_address}}"], + "{{gas_object_id}}", + 2000 + ], + "id": 1 }' | json_pp ``` #### 2, Sign the transaction @@ -221,13 +223,13 @@ signature. Gas usage is capped by the gas_budget. The `transfer` function is described in more detail in the [Sui Wallet](wallet.md#calling-move-code) documentation. -Calling the `transfer` function in the `GAS` module serves the same +Calling the `transfer_` function in the `Coin` module serves the same purpose as the native coin transfer ([`sui_transferCoin`](#sui_transfercoin)), and is mostly used for illustration purposes as native transfer is more efficient when it's applicable (i.e., we are transferring coins rather than non-coin objects). Consequently, you should fill out argument placeholders (`{{owner_address}}`, `{{coin_object_id}`, etc.) the same way you -would for [`sui_transferCoin`](#sui_transfercoin) - please not additional +would for [`sui_transferCoin`](#sui_transfercoin) - please note additional `0x` prepended to function arguments. To learn more about what `args` are accepted in a Move call, refer to the [SuiJSON](sui-json.md) documentation. diff --git a/sui/open_rpc/spec/openrpc.json b/sui/open_rpc/spec/openrpc.json index eaab090abf0bf..0e25e5e9f0325 100644 --- a/sui/open_rpc/spec/openrpc.json +++ b/sui/open_rpc/spec/openrpc.json @@ -145,10 +145,11 @@ "name": "type_arguments", "summary": "", "description": "", + "required": true, "schema": { "type": "array", "items": { - "$ref": "#/components/schemas/TypeTag" + "$ref": "#/components/schemas/TypeTagString" } } }, @@ -160,7 +161,7 @@ "schema": { "type": "array", "items": { - "$ref": "#/components/schemas/RpcCallArg" + "$ref": "#/components/schemas/SuiJsonValue" } } }, @@ -1456,46 +1457,6 @@ } } }, - "RpcCallArg": { - "oneOf": [ - { - "type": "object", - "required": [ - "Pure" - ], - "properties": { - "Pure": { - "$ref": "#/components/schemas/Base64" - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "ImmOrOwnedObject" - ], - "properties": { - "ImmOrOwnedObject": { - "$ref": "#/components/schemas/ObjectID" - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "SharedObject" - ], - "properties": { - "SharedObject": { - "$ref": "#/components/schemas/ObjectID" - } - }, - "additionalProperties": false - } - ] - }, "SequenceNumber": { "type": "integer", "format": "uint64", @@ -1637,6 +1598,7 @@ "SuiAddress": { "$ref": "#/components/schemas/Hex" }, + "SuiJsonValue": {}, "TransactionBytes": { "type": "object", "required": [ @@ -2099,6 +2061,9 @@ "additionalProperties": false } ] + }, + "TypeTagString": { + "type": "string" } } } diff --git a/sui/src/lib.rs b/sui/src/lib.rs index affc675c11f7c..e392f576baa05 100644 --- a/sui/src/lib.rs +++ b/sui/src/lib.rs @@ -9,5 +9,4 @@ pub mod rpc_gateway; pub mod rpc_gateway_client; pub mod shell; pub mod sui_commands; -pub mod sui_json; pub mod wallet_commands; diff --git a/sui/src/rpc_gateway.rs b/sui/src/rpc_gateway.rs index 547eef826bad9..0f4526d1698ca 100644 --- a/sui/src/rpc_gateway.rs +++ b/sui/src/rpc_gateway.rs @@ -1,6 +1,7 @@ // Copyright (c) 2022, Mysten Labs, Inc. // SPDX-License-Identifier: Apache-2.0 +use crate::rpc_gateway::responses::SuiTypeTag; use crate::{ config::{GatewayConfig, PersistedConfig}, rpc_gateway::responses::{GetObjectInfoResponse, NamedObjectRef, ObjectResponse}, @@ -10,7 +11,7 @@ use async_trait::async_trait; use ed25519_dalek::ed25519::signature::Signature; use jsonrpsee::core::RpcResult; use jsonrpsee_proc_macros::rpc; -use move_core_types::{identifier::Identifier, language_storage::TypeTag}; +use move_core_types::identifier::Identifier; use schemars::JsonSchema; use serde::{Deserialize, Serialize}; use serde_with::{base64, serde_as}; @@ -19,6 +20,7 @@ use sui_core::gateway_state::{ gateway_responses::{TransactionEffectsResponse, TransactionResponse}, GatewayClient, GatewayState, GatewayTxSeqNumber, }; +use sui_core::sui_json::SuiJsonValue; use sui_open_rpc_macros::open_rpc; use sui_types::{ base_types::{ObjectID, SuiAddress, TransactionDigest}, @@ -26,7 +28,7 @@ use sui_types::{ crypto::SignableBytes, json_schema, json_schema::Base64, - messages::{CallArg, Transaction, TransactionData}, + messages::{Transaction, TransactionData}, object::ObjectRead, }; use tracing::debug; @@ -75,10 +77,8 @@ pub trait RpcGateway { package_object_id: ObjectID, #[schemars(with = "json_schema::Identifier")] module: Identifier, #[schemars(with = "json_schema::Identifier")] function: Identifier, - #[schemars(with = "Option>")] type_arguments: Option< - Vec, - >, - arguments: Vec, + type_arguments: Vec, + arguments: Vec, gas_object_id: ObjectID, gas_budget: u64, ) -> RpcResult; @@ -313,8 +313,8 @@ impl RpcGatewayServer for RpcGatewayImpl { package_object_id: ObjectID, module: Identifier, function: Identifier, - type_arguments: Option>, - rpc_arguments: Vec, + type_arguments: Vec, + rpc_arguments: Vec, gas_object_id: ObjectID, gas_budget: u64, ) -> RpcResult { @@ -331,28 +331,18 @@ impl RpcGatewayServer for RpcGatewayImpl { .await? .reference()?; - // Fetch the objects for the object args - let mut arguments = Vec::with_capacity(rpc_arguments.len()); - for rpc_arg in rpc_arguments { - arguments.push(match rpc_arg { - RpcCallArg::Pure(arg) => CallArg::Pure(arg.to_vec()), - RpcCallArg::SharedObject(id) => CallArg::SharedObject(id), - RpcCallArg::ImmOrOwnedObject(id) => { - let object_ref = self.gateway.get_object_info(id).await?.reference()?; - CallArg::ImmOrOwnedObject(object_ref) - } - }) - } - self.gateway .move_call( signer, package_object_ref, module, function, - type_arguments.unwrap_or_default(), + type_arguments + .into_iter() + .map(|tag| tag.try_into()) + .collect::, _>>()?, + rpc_arguments, gas_obj_ref, - arguments, gas_budget, ) .await diff --git a/sui/src/rpc_gateway/responses.rs b/sui/src/rpc_gateway/responses.rs index e9c2e6cc0175e..4cd84653a22d9 100644 --- a/sui/src/rpc_gateway/responses.rs +++ b/sui/src/rpc_gateway/responses.rs @@ -3,7 +3,8 @@ use anyhow::anyhow; use base64ct::{Base64, Encoding}; - +use move_core_types::language_storage::TypeTag; +use move_core_types::parser::parse_type_tag; use schemars::JsonSchema; use serde::Deserialize; use serde::Serialize; @@ -110,3 +111,20 @@ impl MoveObjectType { } } } + +#[derive(Serialize, Deserialize, JsonSchema)] +#[serde(rename = "TypeTagString")] +pub struct SuiTypeTag(String); + +impl TryInto for SuiTypeTag { + type Error = anyhow::Error; + fn try_into(self) -> Result { + parse_type_tag(&self.0) + } +} + +impl From for SuiTypeTag { + fn from(tag: TypeTag) -> Self { + Self(format!("{}", tag)) + } +} diff --git a/sui/src/rpc_gateway_client.rs b/sui/src/rpc_gateway_client.rs index 1215c7e17dba6..db4ffa8bcd50a 100644 --- a/sui/src/rpc_gateway_client.rs +++ b/sui/src/rpc_gateway_client.rs @@ -1,22 +1,23 @@ // Copyright (c) 2022, Mysten Labs, Inc. // SPDX-License-Identifier: Apache-2.0 -use crate::rpc_gateway::responses::ObjectResponse; -use crate::rpc_gateway::{ - RpcCallArg, RpcGatewayClient as RpcGateway, SignedTransaction, TransactionBytes, -}; use anyhow::Error; use async_trait::async_trait; use jsonrpsee::http_client::{HttpClient, HttpClientBuilder}; use move_core_types::identifier::Identifier; use move_core_types::language_storage::TypeTag; +use tokio::runtime::Handle; + use sui_core::gateway_state::gateway_responses::{TransactionEffectsResponse, TransactionResponse}; use sui_core::gateway_state::{GatewayAPI, GatewayTxSeqNumber}; +use sui_core::sui_json::SuiJsonValue; use sui_types::base_types::{ObjectID, ObjectRef, SuiAddress, TransactionDigest}; use sui_types::json_schema::Base64; -use sui_types::messages::{CallArg, Transaction, TransactionData}; +use sui_types::messages::{Transaction, TransactionData}; use sui_types::object::ObjectRead; -use tokio::runtime::Handle; + +use crate::rpc_gateway::responses::ObjectResponse; +use crate::rpc_gateway::{RpcGatewayClient as RpcGateway, SignedTransaction, TransactionBytes}; pub struct RpcGatewayClient { client: HttpClient, @@ -69,19 +70,10 @@ impl GatewayAPI for RpcGatewayClient { module: Identifier, function: Identifier, type_arguments: Vec, + arguments: Vec, gas_object_ref: ObjectRef, - arguments: Vec, gas_budget: u64, ) -> Result { - let arguments = arguments - .into_iter() - .map(|arg| match arg { - CallArg::Pure(bytes) => RpcCallArg::Pure(Base64(bytes)), - CallArg::ImmOrOwnedObject((id, _, _)) => RpcCallArg::ImmOrOwnedObject(id), - CallArg::SharedObject(id) => RpcCallArg::SharedObject(id), - }) - .collect(); - let bytes: TransactionBytes = self .client .move_call( @@ -89,7 +81,10 @@ impl GatewayAPI for RpcGatewayClient { package_object_ref.0, module, function, - Some(type_arguments), + type_arguments + .into_iter() + .map(|tag| tag.try_into()) + .collect::, _>>()?, arguments, gas_object_ref.0, gas_budget, diff --git a/sui/src/unit_tests/cli_tests.rs b/sui/src/unit_tests/cli_tests.rs index 77e3a5526e78b..42fdcfd5e7f62 100644 --- a/sui/src/unit_tests/cli_tests.rs +++ b/sui/src/unit_tests/cli_tests.rs @@ -1,13 +1,15 @@ // Copyright (c) 2022, Mysten Labs, Inc. // SPDX-License-Identifier: Apache-2.0 -use crate::cli_tests::sui_network::start_test_network; -use anyhow::anyhow; -use move_core_types::identifier::Identifier; -use serde_json::{json, Value}; use std::{ collections::BTreeSet, fmt::Write, fs::read_dir, ops::Add, path::PathBuf, str, time::Duration, }; + +use anyhow::anyhow; +use move_core_types::identifier::Identifier; +use serde_json::{json, Value}; +use tracing_test::traced_test; + use sui::{ config::{ AccountConfig, Config, GatewayConfig, GatewayType, GenesisConfig, NetworkConfig, @@ -16,10 +18,10 @@ use sui::{ }, keystore::KeystoreType, sui_commands::{SuiCommand, SuiNetwork, SUI_AUTHORITY_KEYS}, - sui_json::SuiJsonValue, wallet_commands::{WalletCommandResult, WalletCommands, WalletContext}, }; use sui_core::gateway_state::gateway_responses::SwitchResponse; +use sui_core::sui_json::SuiJsonValue; use sui_types::{ base_types::{ObjectID, SequenceNumber, SuiAddress}, crypto::{get_key_pair, random_key_pairs}, @@ -27,7 +29,8 @@ use sui_types::{ messages::TransactionEffects, object::{Object, ObjectRead, GAS_VALUE_FOR_TESTING}, }; -use tracing_test::traced_test; + +use crate::cli_tests::sui_network::start_test_network; const TEST_DATA_DIR: &str = "src/unit_tests/data/"; const AIRDROP_SOURCE_CONTRACT_ADDRESS: &str = "bc4ca0eda7647a8ab7c2061c2e118a18a936f13d"; diff --git a/sui/src/unit_tests/rpc_server_tests.rs b/sui/src/unit_tests/rpc_server_tests.rs index 0cdee8c70713e..0346bbe6e33f1 100644 --- a/sui/src/unit_tests/rpc_server_tests.rs +++ b/sui/src/unit_tests/rpc_server_tests.rs @@ -16,18 +16,17 @@ use sui::{ config::{PersistedConfig, WalletConfig, SUI_GATEWAY_CONFIG, SUI_WALLET_CONFIG}, keystore::{Keystore, SuiKeystore}, rpc_gateway::{ - responses::ObjectResponse, RpcCallArg, RpcGatewayClient, RpcGatewayImpl, RpcGatewayServer, + responses::ObjectResponse, RpcGatewayClient, RpcGatewayImpl, RpcGatewayServer, SignedTransaction, TransactionBytes, }, sui_commands::SuiNetwork, - sui_json::{resolve_move_function_args, SuiJsonCallArg, SuiJsonValue}, }; use sui_core::gateway_state::gateway_responses::TransactionResponse; +use sui_core::sui_json::SuiJsonValue; use sui_framework::build_move_package_to_bytes; use sui_types::{ base_types::{ObjectID, SuiAddress}, json_schema::Base64, - object::ObjectRead, SUI_FRAMEWORK_ADDRESS, }; @@ -142,34 +141,24 @@ async fn test_move_call() -> Result<(), anyhow::Error> { let gas = objects.first().unwrap(); let package_id = ObjectID::new(SUI_FRAMEWORK_ADDRESS.into_bytes()); - let package: ObjectRead = http_client.get_object_info(package_id).await?; - let package = package.into_object()?; let module = Identifier::new("ObjectBasics")?; let function = Identifier::new("create")?; - let json_args = resolve_move_function_args( - &package, - module.clone(), - function.clone(), - vec![ - SuiJsonValue::from_str("10000")?, - SuiJsonValue::from_str(&format!("\"0x{}\"", address))?, - ], - )?; - let mut args = Vec::with_capacity(json_args.len()); - for json_arg in json_args { - args.push(match json_arg { - SuiJsonCallArg::Pure(bytes) => RpcCallArg::Pure(Base64(bytes)), - SuiJsonCallArg::Object(id) => match http_client.get_object_info(id).await? { - ObjectRead::Exists(_, obj, _) if obj.is_shared() => RpcCallArg::SharedObject(id), - _ => RpcCallArg::ImmOrOwnedObject(id), - }, - }) - } + let json_args = vec![ + SuiJsonValue::from_str("10000")?, + SuiJsonValue::from_str(&format!("\"0x{}\"", address))?, + ]; let tx_data: TransactionBytes = http_client .move_call( - *address, package_id, module, function, None, args, gas.0, 1000, + *address, + package_id, + module, + function, + vec![], + json_args, + gas.0, + 1000, ) .await?; diff --git a/sui/src/wallet_commands.rs b/sui/src/wallet_commands.rs index 1925addccafe8..ada6115bde4ec 100644 --- a/sui/src/wallet_commands.rs +++ b/sui/src/wallet_commands.rs @@ -1,18 +1,7 @@ // Copyright (c) 2022, Mysten Labs, Inc. // SPDX-License-Identifier: Apache-2.0 -use crate::{ - config::{Config, GatewayType, PersistedConfig, WalletConfig}, - keystore::Keystore, - sui_json::{resolve_move_function_args, SuiJsonCallArg, SuiJsonValue}, -}; -use anyhow::anyhow; -use clap::*; -use colored::Colorize; use core::fmt; -use move_core_types::{identifier::Identifier, language_storage::TypeTag, parser::parse_type_tag}; -use serde::Serialize; -use serde_json::json; use std::{ collections::{BTreeMap, BTreeSet}, fmt::{Debug, Display, Formatter, Write}, @@ -20,20 +9,33 @@ use std::{ sync::{Arc, RwLock}, time::Instant, }; -use sui_adapter::adapter::resolve_and_type_check; + +use anyhow::anyhow; +use clap::*; +use colored::Colorize; +use move_core_types::{identifier::Identifier, language_storage::TypeTag, parser::parse_type_tag}; +use serde::Serialize; +use serde_json::json; +use tracing::info; + use sui_core::gateway_state::{ gateway_responses::{MergeCoinResponse, PublishResponse, SplitCoinResponse, SwitchResponse}, GatewayClient, }; +use sui_core::sui_json::{resolve_move_function_args, SuiJsonCallArg, SuiJsonValue}; use sui_framework::build_move_package_to_bytes; use sui_types::{ base_types::{decode_bytes_hex, ObjectID, ObjectRef, SuiAddress}, gas_coin::GasCoin, - messages::{CallArg, CertifiedTransaction, ExecutionStatus, Transaction, TransactionEffects}, + messages::{CertifiedTransaction, ExecutionStatus, Transaction, TransactionEffects}, object::{Object, ObjectRead, ObjectRead::Exists}, SUI_FRAMEWORK_ADDRESS, }; -use tracing::info; + +use crate::{ + config::{Config, GatewayType, PersistedConfig, WalletConfig}, + keystore::Keystore, +}; const EXAMPLE_NFT_NAME: &str = "Example NFT"; const EXAMPLE_NFT_DESCRIPTION: &str = "An NFT created by the wallet Command Line Tool"; @@ -108,10 +110,10 @@ pub enum WalletCommands { function: Identifier, /// Function name in module #[clap( - long, - parse(try_from_str = parse_type_tag), - multiple_occurrences = false, - multiple_values = true + long, + parse(try_from_str = parse_type_tag), + multiple_occurrences = false, + multiple_values = true )] type_args: Vec, /// Simplified ordered args like in the function syntax @@ -745,52 +747,25 @@ async fn call_move( context: &mut WalletContext, ) -> Result<(CertifiedTransaction, TransactionEffects), anyhow::Error> { let package_obj_info = context.gateway.get_object_info(*package).await?; - let package_obj = package_obj_info.object().clone()?; + let package_obj = package_obj_info.object()?; let package_obj_ref = package_obj_info.reference().unwrap(); - // These steps can potentially be condensed and moved into the client/manager level - // Extract the input args + // Resolving the args in client side to identify forbidden_gas_objects let json_args = resolve_move_function_args(package_obj, module.clone(), function.clone(), args.to_vec())?; - // Fetch all the objects needed for this call let mut objects = BTreeMap::new(); - let mut args = Vec::with_capacity(json_args.len()); for json_arg in json_args { - args.push(match json_arg { - SuiJsonCallArg::Object(id) => { - let obj = context.gateway.get_object_info(id).await?.into_object()?; - let arg = if obj.is_shared() { - CallArg::SharedObject(id) - } else { - CallArg::ImmOrOwnedObject(obj.compute_object_reference()) - }; - objects.insert(id, obj); - arg - } - SuiJsonCallArg::Pure(bytes) => CallArg::Pure(bytes), - }) + if let SuiJsonCallArg::Object(id) = json_arg { + let obj = context.gateway.get_object_info(id).await?.into_object()?; + objects.insert(id, obj); + } } let forbidden_gas_objects = objects.keys().copied().collect(); let gas_object = context .choose_gas_for_wallet(*gas, *gas_budget, forbidden_gas_objects) .await?; let sender = gas_object.owner.get_owner_address()?; - - // Pass in the objects for a deeper check - let compiled_module = package_obj - .data - .try_as_package() - .ok_or_else(|| anyhow!("Cannot get package from object"))? - .deserialize_module(module)?; - resolve_and_type_check( - &objects, - &compiled_module, - function, - type_args, - args.clone(), - )?; - // Fetch the object info for the gas obj let gas_obj_ref = gas_object.compute_object_reference(); @@ -802,8 +777,8 @@ async fn call_move( module.to_owned(), function.to_owned(), type_args.to_owned(), + args.to_vec(), gas_obj_ref, - args, *gas_budget, ) .await?; diff --git a/sui_core/Cargo.toml b/sui_core/Cargo.toml index e16999737de6f..b45926c7718c4 100644 --- a/sui_core/Cargo.toml +++ b/sui_core/Cargo.toml @@ -14,6 +14,8 @@ futures = "0.3.21" rand = "0.7.3" bytes = "1.1.0" serde = { version = "1.0.137", features = ["derive"] } +serde_json = "1.0.79" +hex = "0.4.3" tokio = { version = "1.17.0", features = ["full", "tracing"] } tokio-stream = { version = "0.1.8", features = ["sync", "net"] } tokio-util = { version = "0.7.1", features = ["codec"] } diff --git a/sui_core/src/gateway_state.rs b/sui_core/src/gateway_state.rs index 0624e7246c517..20214232e2bbf 100644 --- a/sui_core/src/gateway_state.rs +++ b/sui_core/src/gateway_state.rs @@ -13,6 +13,7 @@ use async_trait::async_trait; use futures::future; use move_core_types::identifier::Identifier; use move_core_types::language_storage::TypeTag; +use sui_adapter::adapter::resolve_and_type_check; use tracing::{error, Instrument}; use sui_types::gas::{self, SuiGasStatus}; @@ -27,6 +28,7 @@ use sui_types::{ SUI_FRAMEWORK_ADDRESS, }; +use crate::sui_json::{resolve_move_function_args, SuiJsonCallArg, SuiJsonValue}; use crate::transaction_input_checker; use crate::{ authority::GatewayStore, authority_aggregator::AuthorityAggregator, @@ -136,8 +138,8 @@ pub trait GatewayAPI { module: Identifier, function: Identifier, type_arguments: Vec, + arguments: Vec, gas_object_ref: ObjectRef, - arguments: Vec, gas_budget: u64, ) -> Result; @@ -652,10 +654,48 @@ where module: Identifier, function: Identifier, type_arguments: Vec, + arguments: Vec, gas_object_ref: ObjectRef, - arguments: Vec, gas_budget: u64, ) -> Result { + let package_obj = self.get_object(&package_object_ref.0).await?; + let json_args = + resolve_move_function_args(&package_obj, module.clone(), function.clone(), arguments)?; + + // Fetch all the objects needed for this call + let mut objects = BTreeMap::new(); + let mut args = Vec::with_capacity(json_args.len()); + + for json_arg in json_args { + args.push(match json_arg { + SuiJsonCallArg::Object(id) => { + let obj = self.get_object(&id).await?; + let arg = if obj.is_shared() { + CallArg::SharedObject(id) + } else { + CallArg::ImmOrOwnedObject(obj.compute_object_reference()) + }; + objects.insert(id, obj); + arg + } + SuiJsonCallArg::Pure(bytes) => CallArg::Pure(bytes), + }) + } + + // Pass in the objects for a deeper check + let compiled_module = package_obj + .data + .try_as_package() + .ok_or_else(|| anyhow!("Cannot get package from object"))? + .deserialize_module(&module)?; + resolve_and_type_check( + &objects, + &compiled_module, + &function, + &type_arguments, + args.clone(), + )?; + let data = TransactionData::new_move_call( signer, package_object_ref, @@ -663,7 +703,7 @@ where function, type_arguments, gas_object_ref, - arguments, + args, gas_budget, ); Ok(data) diff --git a/sui_core/src/lib.rs b/sui_core/src/lib.rs index 4e8f5ee70e098..bead970be8189 100644 --- a/sui_core/src/lib.rs +++ b/sui_core/src/lib.rs @@ -12,4 +12,5 @@ pub mod consensus_adapter; pub mod execution_engine; pub mod gateway_state; pub mod safe_client; +pub mod sui_json; pub mod transaction_input_checker; diff --git a/sui/src/sui_json.rs b/sui_core/src/sui_json.rs similarity index 96% rename from sui/src/sui_json.rs rename to sui_core/src/sui_json.rs index 215ddb15338c2..6c9cf90ccc032 100644 --- a/sui/src/sui_json.rs +++ b/sui_core/src/sui_json.rs @@ -1,26 +1,25 @@ // Copyright (c) 2022, Mysten Labs, Inc. // SPDX-License-Identifier: Apache-2.0 -use anyhow::{anyhow, bail}; -use move_core_types::{ - identifier::Identifier, - value::{MoveTypeLayout, MoveValue}, -}; -use schemars::JsonSchema; -use serde::{Deserialize, Serialize}; use std::collections::VecDeque; -use sui_types::{ - base_types::{decode_bytes_hex, ObjectID, SuiAddress}, - object::Object, -}; +use anyhow::{anyhow, bail}; // Alias the type names for clarity use move_binary_format::{ access::ModuleAccess, file_format::{SignatureToken, Visibility}, }; +use move_core_types::{ + identifier::Identifier, + value::{MoveTypeLayout, MoveValue}, +}; +use schemars::JsonSchema; +use serde::{Deserialize, Serialize}; use serde_json::Value as JsonValue; +use sui_types::base_types::{decode_bytes_hex, ObjectID, SuiAddress}; +use sui_types::object::Object; + const HEX_PREFIX: &str = "0x"; #[cfg(test)] @@ -279,12 +278,12 @@ fn resolve_call_arg( SignatureToken::Struct(_) | SignatureToken::StructInstantiation(_, _) + | SignatureToken::TypeParameter(_) | SignatureToken::Reference(_) | SignatureToken::MutableReference(_) => { SuiJsonCallArg::Object(resolve_object_arg(idx, arg)?) } - SignatureToken::TypeParameter(_) => unreachable!("Not yet supported and already gated"), SignatureToken::Signer => unreachable!(), }) } @@ -339,13 +338,6 @@ pub fn resolve_move_function_args( function, ) } - if !function_signature.type_parameters.is_empty() { - bail!( - "{}::{} has type arguments, which are not yet supported in sui_json", - module.self_id(), - function, - ) - } // Lengths have to match, less one, due to TxContext let expected_len = parameters.len() - 1; diff --git a/sui/src/unit_tests/sui_json.rs b/sui_core/src/unit_tests/sui_json.rs similarity index 98% rename from sui/src/unit_tests/sui_json.rs rename to sui_core/src/unit_tests/sui_json.rs index fb0e8838bf76d..c6d614a17dc12 100644 --- a/sui/src/unit_tests/sui_json.rs +++ b/sui_core/src/unit_tests/sui_json.rs @@ -7,12 +7,9 @@ use move_core_types::{ account_address::AccountAddress, identifier::Identifier, value::MoveTypeLayout, }; use serde_json::{json, Value}; -use sui_adapter::{self, genesis::clone_genesis_packages}; -use sui_types::{ - base_types::{ObjectID, SuiAddress, TransactionDigest}, - object::Object, - SUI_FRAMEWORK_ADDRESS, -}; +use sui_types::base_types::{ObjectID, SuiAddress, TransactionDigest}; +use sui_types::object::Object; +use sui_types::SUI_FRAMEWORK_ADDRESS; use crate::sui_json::{resolve_move_function_args, SuiJsonCallArg, SuiJsonValue}; @@ -394,7 +391,7 @@ fn test_basic_args_linter_top_level() { assert!(resolve_move_function_args(&example_package, module, function, args).is_err()); // Test with vecu8 as address - let genesis_objs = clone_genesis_packages(); + let genesis_objs = sui_adapter::genesis::clone_genesis_packages(); let framework_pkg = genesis_objs .iter() .find(|q| q.id() == ObjectID::from(SUI_FRAMEWORK_ADDRESS)) diff --git a/sui_programmability/adapter/src/adapter.rs b/sui_programmability/adapter/src/adapter.rs index 03571f81fed7d..b422fd6f6a75d 100644 --- a/sui_programmability/adapter/src/adapter.rs +++ b/sui_programmability/adapter/src/adapter.rs @@ -902,6 +902,10 @@ fn struct_tag_equals_sig_token( SignatureToken::StructInstantiation(idx, args) => { struct_tag_equals_struct_inst(module, function_type_arguments, arg_type, *idx, args) } + SignatureToken::TypeParameter(idx) => match &function_type_arguments[*idx as usize] { + TypeTag::Struct(s) => arg_type == s, + _ => false, + }, _ => false, } }