Skip to content

Commit

Permalink
read move function, module and struct RPC endpoints (#3852)
Browse files Browse the repository at this point in the history
  • Loading branch information
gegaowp authored Aug 10, 2022
1 parent daafc43 commit b5c3d5c
Show file tree
Hide file tree
Showing 9 changed files with 1,413 additions and 630 deletions.
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions crates/sui-json-rpc-types/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ either = "1.7.0"
itertools = "0.10.3"
tracing = "0.1.36"

move-binary-format = { git = "https://github.com/move-language/move", rev = "79071528524f08b12e9abb84c1094d8e976aa17a" }
move-core-types = { git = "https://github.com/move-language/move", rev = "79071528524f08b12e9abb84c1094d8e976aa17a", features = ["address20"] }
move-bytecode-utils = { git = "https://github.com/move-language/move", rev = "79071528524f08b12e9abb84c1094d8e976aa17a" }

Expand Down
237 changes: 237 additions & 0 deletions crates/sui-json-rpc-types/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,11 @@ use std::fmt::{Display, Formatter};
use colored::Colorize;
use either::Either;
use itertools::Itertools;
use move_binary_format::file_format::{Ability, AbilitySet, StructTypeParameter, Visibility};
use move_binary_format::normalized::{
Field as NormalizedField, Function as SuiNormalizedFunction, Module as NormalizedModule,
Struct as NormalizedStruct, Type as NormalizedType,
};
use move_bytecode_utils::module_cache::GetModule;
use move_core_types::identifier::Identifier;
use move_core_types::language_storage::{StructTag, TypeTag};
Expand Down Expand Up @@ -51,6 +56,238 @@ use sui_types::sui_serde::{Base64, Encoding};
mod rpc_types_tests;

pub type GatewayTxSeqNumber = u64;
pub type SuiMoveTypeParameterIndex = u16;

#[derive(Serialize, Deserialize, Debug, JsonSchema)]
pub enum SuiMoveAbility {
Copy,
Drop,
Store,
Key,
}

#[derive(Serialize, Deserialize, Debug, JsonSchema)]
pub struct SuiMoveAbilitySet {
pub abilities: Vec<SuiMoveAbility>,
}

#[derive(Serialize, Deserialize, Debug, JsonSchema)]
pub enum SuiMoveVisibility {
Private,
Public,
Friend,
}

#[derive(Serialize, Deserialize, Debug, JsonSchema)]
pub struct SuiMoveStructTypeParameter {
pub constraints: SuiMoveAbilitySet,
pub is_phantom: bool,
}

#[derive(Serialize, Deserialize, Debug, JsonSchema)]
pub struct SuiMoveNormalizedField {
pub name: String,
pub type_: SuiMoveNormalizedType,
}

#[derive(Serialize, Deserialize, Debug, JsonSchema)]
pub struct SuiMoveNormalizedStruct {
pub abilities: SuiMoveAbilitySet,
pub type_parameters: Vec<SuiMoveStructTypeParameter>,
pub fields: Vec<SuiMoveNormalizedField>,
}

#[derive(Serialize, Deserialize, Debug, JsonSchema)]
pub enum SuiMoveNormalizedType {
Bool,
U8,
U64,
U128,
Address,
Signer,
Struct {
address: String,
module: String,
name: String,
type_arguments: Vec<SuiMoveNormalizedType>,
},
Vector(Box<SuiMoveNormalizedType>),
TypeParameter(SuiMoveTypeParameterIndex),
Reference(Box<SuiMoveNormalizedType>),
MutableReference(Box<SuiMoveNormalizedType>),
}

#[derive(Serialize, Deserialize, Debug, JsonSchema)]
pub struct SuiMoveNormalizedFunction {
pub visibility: SuiMoveVisibility,
pub is_entry: bool,
pub type_parameters: Vec<SuiMoveAbilitySet>,
pub parameters: Vec<SuiMoveNormalizedType>,
pub return_: Vec<SuiMoveNormalizedType>,
}

#[derive(Serialize, Deserialize, Debug, JsonSchema)]
pub struct SuiMoveModuleId {
address: String,
name: String,
}

#[derive(Serialize, Deserialize, Debug, JsonSchema)]
pub struct SuiMoveNormalizedModule {
pub file_format_version: u32,
pub address: String,
pub name: String,
pub friends: Vec<SuiMoveModuleId>,
pub structs: BTreeMap<String, SuiMoveNormalizedStruct>,
pub exposed_functions: BTreeMap<String, SuiMoveNormalizedFunction>,
}

impl From<NormalizedModule> for SuiMoveNormalizedModule {
fn from(module: NormalizedModule) -> Self {
Self {
file_format_version: module.file_format_version,
address: module.address.to_hex_literal(),
name: module.name.to_string(),
friends: module
.friends
.into_iter()
.map(|module_id| SuiMoveModuleId {
address: module_id.address().to_hex_literal(),
name: module_id.name().to_string(),
})
.collect::<Vec<SuiMoveModuleId>>(),
structs: module
.structs
.into_iter()
.map(|(name, struct_)| (name.to_string(), SuiMoveNormalizedStruct::from(struct_)))
.collect::<BTreeMap<String, SuiMoveNormalizedStruct>>(),
exposed_functions: module
.exposed_functions
.into_iter()
.map(|(name, function)| {
(name.to_string(), SuiMoveNormalizedFunction::from(function))
})
.collect::<BTreeMap<String, SuiMoveNormalizedFunction>>(),
}
}
}

impl From<SuiNormalizedFunction> for SuiMoveNormalizedFunction {
fn from(function: SuiNormalizedFunction) -> Self {
Self {
visibility: match function.visibility {
Visibility::Private => SuiMoveVisibility::Private,
Visibility::Public => SuiMoveVisibility::Public,
Visibility::Friend => SuiMoveVisibility::Friend,
},
is_entry: function.is_entry,
type_parameters: function
.type_parameters
.into_iter()
.map(|a| a.into())
.collect::<Vec<SuiMoveAbilitySet>>(),
parameters: function
.parameters
.into_iter()
.map(SuiMoveNormalizedType::from)
.collect::<Vec<SuiMoveNormalizedType>>(),
return_: function
.return_
.into_iter()
.map(SuiMoveNormalizedType::from)
.collect::<Vec<SuiMoveNormalizedType>>(),
}
}
}

impl From<NormalizedStruct> for SuiMoveNormalizedStruct {
fn from(struct_: NormalizedStruct) -> Self {
Self {
abilities: struct_.abilities.into(),
type_parameters: struct_
.type_parameters
.into_iter()
.map(SuiMoveStructTypeParameter::from)
.collect::<Vec<SuiMoveStructTypeParameter>>(),
fields: struct_
.fields
.into_iter()
.map(SuiMoveNormalizedField::from)
.collect::<Vec<SuiMoveNormalizedField>>(),
}
}
}

impl From<StructTypeParameter> for SuiMoveStructTypeParameter {
fn from(type_parameter: StructTypeParameter) -> Self {
Self {
constraints: type_parameter.constraints.into(),
is_phantom: type_parameter.is_phantom,
}
}
}

impl From<NormalizedField> for SuiMoveNormalizedField {
fn from(normalized_field: NormalizedField) -> Self {
Self {
name: normalized_field.name.to_string(),
type_: SuiMoveNormalizedType::from(normalized_field.type_),
}
}
}

impl From<NormalizedType> for SuiMoveNormalizedType {
fn from(type_: NormalizedType) -> Self {
match type_ {
NormalizedType::Bool => SuiMoveNormalizedType::Bool,
NormalizedType::U8 => SuiMoveNormalizedType::U8,
NormalizedType::U64 => SuiMoveNormalizedType::U64,
NormalizedType::U128 => SuiMoveNormalizedType::U128,
NormalizedType::Address => SuiMoveNormalizedType::Address,
NormalizedType::Signer => SuiMoveNormalizedType::Signer,
NormalizedType::Struct {
address,
module,
name,
type_arguments,
} => SuiMoveNormalizedType::Struct {
address: address.to_hex_literal(),
module: module.to_string(),
name: name.to_string(),
type_arguments: type_arguments
.into_iter()
.map(SuiMoveNormalizedType::from)
.collect::<Vec<SuiMoveNormalizedType>>(),
},
NormalizedType::Vector(v) => {
SuiMoveNormalizedType::Vector(Box::new(SuiMoveNormalizedType::from(*v)))
}
NormalizedType::TypeParameter(t) => SuiMoveNormalizedType::TypeParameter(t),
NormalizedType::Reference(r) => {
SuiMoveNormalizedType::Reference(Box::new(SuiMoveNormalizedType::from(*r)))
}
NormalizedType::MutableReference(mr) => {
SuiMoveNormalizedType::MutableReference(Box::new(SuiMoveNormalizedType::from(*mr)))
}
}
}
}

impl From<AbilitySet> for SuiMoveAbilitySet {
fn from(set: AbilitySet) -> SuiMoveAbilitySet {
Self {
abilities: set
.into_iter()
.map(|a| match a {
Ability::Copy => SuiMoveAbility::Copy,
Ability::Drop => SuiMoveAbility::Drop,
Ability::Key => SuiMoveAbility::Key,
Ability::Store => SuiMoveAbility::Store,
})
.collect::<Vec<SuiMoveAbility>>(),
}
}
}

#[derive(Serialize, Deserialize, Debug, JsonSchema)]
pub enum ObjectValueKind {
Expand Down
42 changes: 39 additions & 3 deletions crates/sui-json-rpc/src/api.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,16 @@
// Copyright (c) 2022, Mysten Labs, Inc.
// SPDX-License-Identifier: Apache-2.0

use std::collections::BTreeMap;

use jsonrpsee::core::RpcResult;
use jsonrpsee_proc_macros::rpc;
use sui_json::SuiJsonValue;
use sui_json_rpc_types::{
GatewayTxSeqNumber, GetObjectDataResponse, GetRawObjectDataResponse, MoveFunctionArgType,
RPCTransactionRequestParams, SuiEventEnvelope, SuiEventFilter, SuiObjectInfo, SuiTypeTag,
TransactionBytes, TransactionEffectsResponse, TransactionResponse,
RPCTransactionRequestParams, SuiEventEnvelope, SuiEventFilter, SuiMoveNormalizedFunction,
SuiMoveNormalizedModule, SuiMoveNormalizedStruct, SuiObjectInfo, SuiTypeTag, TransactionBytes,
TransactionEffectsResponse, TransactionResponse,
};
use sui_open_rpc_macros::open_rpc;
use sui_types::base_types::{ObjectID, SuiAddress, TransactionDigest};
Expand Down Expand Up @@ -110,11 +113,44 @@ pub trait RpcFullNodeReadApi {
#[method(name = "getMoveFunctionArgTypes")]
async fn get_move_function_arg_types(
&self,
object_id: ObjectID,
package: ObjectID,
module: String,
function: String,
) -> RpcResult<Vec<MoveFunctionArgType>>;

/// Return structured representations of all modules in the given package
#[method(name = "getNormalizedMoveModulesByPackage")]
async fn get_normalized_move_modules_by_package(
&self,
package: ObjectID,
) -> RpcResult<BTreeMap<String, SuiMoveNormalizedModule>>;

/// Return a structured representation of Move module
#[method(name = "getNormalizedMoveModule")]
async fn get_normalized_move_module(
&self,
package: ObjectID,
module_name: String,
) -> RpcResult<SuiMoveNormalizedModule>;

/// Return a structured representation of Move struct
#[method(name = "getNormalizedMoveStruct")]
async fn get_normalized_move_struct(
&self,
package: ObjectID,
module_name: String,
struct_name: String,
) -> RpcResult<SuiMoveNormalizedStruct>;

/// Return a structured representation of Move function
#[method(name = "getNormalizedMoveFunction")]
async fn get_normalized_move_function(
&self,
package: ObjectID,
module_name: String,
function_name: String,
) -> RpcResult<SuiMoveNormalizedFunction>;

/// Return list of transactions for a specified input object.
#[method(name = "getTransactionsByInputObject")]
async fn get_transactions_by_input_object(
Expand Down
Loading

1 comment on commit b5c3d5c

@github-actions
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bench results

�[0m�[0m�[1m�[32m Finished�[0m release [optimized] target(s) in 0.84s
�[0m�[0m�[1m�[32m Running�[0m target/release/bench microbench throughput
Default Jemalloc conf:
�[2m2022-08-10T01:58:04.669419Z�[0m �[32m INFO�[0m �[2msui_benchmark::benchmark�[0m�[2m:�[0m benchmark �[3mbenchmark�[0m�[2m=�[0mBenchmark { committee_size: 1, send_timeout_us: 400000000, recv_timeout_us: 400000000, buffer_size: 65000, tcp_connections: 0, db_cpus: 1, use_native: false, batch_size: 2000, running_mode: SingleValidatorThread, working_dir: None, bench_type: MicroBenchmark { host: "127.0.0.1", port: 9555, type_: Throughput { num_transactions: 100000 } } }
Jemalloc: 1 MB allocated / 9 MB resident
�[2m2022-08-10T01:58:04.671189Z�[0m �[32m INFO�[0m �[2msui_config::genesis_config�[0m�[2m:�[0m Creating accounts and gas objects...
�[2m2022-08-10T01:58:04.689785Z�[0m �[32m INFO�[0m �[2msui_benchmark::benchmark::validator_preparer�[0m�[2m:�[0m authority address hex: 0x963a8fa52f5a33b4080cc4fa003e0d71ac11d245
�[2m2022-08-10T01:58:04.689888Z�[0m �[32m INFO�[0m �[2msui_benchmark::benchmark::validator_preparer�[0m�[2m:�[0m Open database on path: "/tmp/DB_0x7bfe8fbb7c10f29c5c10db99d51402689b91ce99"
�[2m2022-08-10T01:58:04.946990Z�[0m �[32m INFO�[0m �[2msui_storage::lock_service�[0m�[2m:�[0m LockService command processing loop started
�[2m2022-08-10T01:58:04.947057Z�[0m �[32m INFO�[0m �[2msui_storage::lock_service�[0m�[2m:�[0m LockService queries processing loop started
Jemalloc: 103 MB allocated / 152 MB resident
�[2m2022-08-10T01:58:05.699036Z�[0m �[32m INFO�[0m �[2msui_benchmark::benchmark::validator_preparer�[0m�[2m:�[0m Spawning a validator thread...
�[2m2022-08-10T01:58:05.700464Z�[0m �[32m INFO�[0m �[2msui_core::authority_server�[0m�[2m:�[0m Listening to traffic on /dns/127.0.0.1/tcp/9555/http
Jemalloc: 68 MB allocated / 134 MB resident
�[2m2022-08-10T01:58:08.701119Z�[0m �[31mERROR�[0m �[2msui_benchmark::benchmark�[0m�[2m:�[0m Listener error: RpcError("Service was not ready: transport error")
Jemalloc: 69 MB allocated / 131 MB resident
Jemalloc: 690 MB allocated / 2190 MB resident
Throughout: 66207.14494266792 tps

Please sign in to comment.