forked from MystenLabs/sui
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[RPC API] - split api into GatewayAPI, ReadApi, FullNodeApi, and Tran…
…sactionBuilder (MystenLabs#2093) * split api into GatewayAPI, ReadApi, FullNodeApi, and TransactionBuilder * add module support to json rpc doc generation * revert rpc response sample changes * remove unnecessary dep and commented out code
- Loading branch information
1 parent
cf86d29
commit dd08d69
Showing
14 changed files
with
1,056 additions
and
732 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2,6 +2,7 @@ | |
// SPDX-License-Identifier: Apache-2.0 | ||
|
||
use jsonrpsee::core::RpcResult; | ||
use jsonrpsee_core::server::rpc_module::RpcModule; | ||
use jsonrpsee_proc_macros::rpc; | ||
use schemars::JsonSchema; | ||
use serde::{Deserialize, Serialize}; | ||
|
@@ -11,6 +12,7 @@ use sui_core::gateway_state::GatewayTxSeqNumber; | |
use sui_core::gateway_types::{GetObjectInfoResponse, SuiInputObjectKind, SuiObjectRef}; | ||
use sui_core::gateway_types::{TransactionEffectsResponse, TransactionResponse}; | ||
use sui_json::SuiJsonValue; | ||
use sui_open_rpc::Module; | ||
use sui_open_rpc_macros::open_rpc; | ||
use sui_types::sui_serde::Base64; | ||
use sui_types::{ | ||
|
@@ -22,73 +24,9 @@ use sui_types::{ | |
use crate::rpc_gateway::responses::ObjectResponse; | ||
use crate::rpc_gateway::responses::SuiTypeTag; | ||
|
||
#[open_rpc( | ||
name = "Sui JSON-RPC", | ||
namespace = "sui", | ||
contact_name = "Mysten Labs", | ||
contact_url = "https://mystenlabs.com", | ||
contact_email = "[email protected]", | ||
license = "Apache-2.0", | ||
license_url = "https://raw.githubusercontent.com/MystenLabs/sui/main/LICENSE", | ||
description = "Sui JSON-RPC API for interaction with the Sui network gateway." | ||
)] | ||
#[open_rpc(namespace = "sui", tag = "Gateway API")] | ||
#[rpc(server, client, namespace = "sui")] | ||
pub trait RpcGateway { | ||
/// Create a transaction to transfer a Sui coin from one address to another. | ||
#[method(name = "transferCoin")] | ||
async fn transfer_coin( | ||
&self, | ||
signer: SuiAddress, | ||
object_id: ObjectID, | ||
gas: Option<ObjectID>, | ||
gas_budget: u64, | ||
recipient: SuiAddress, | ||
) -> RpcResult<TransactionBytes>; | ||
|
||
/// Execute a Move call transaction by calling the specified function in the module of a given package. | ||
#[method(name = "moveCall")] | ||
async fn move_call( | ||
&self, | ||
signer: SuiAddress, | ||
package_object_id: ObjectID, | ||
module: String, | ||
function: String, | ||
type_arguments: Vec<SuiTypeTag>, | ||
arguments: Vec<SuiJsonValue>, | ||
gas: Option<ObjectID>, | ||
gas_budget: u64, | ||
) -> RpcResult<TransactionBytes>; | ||
|
||
/// Publish Move module. | ||
#[method(name = "publish")] | ||
async fn publish( | ||
&self, | ||
sender: SuiAddress, | ||
compiled_modules: Vec<Base64>, | ||
gas: Option<ObjectID>, | ||
gas_budget: u64, | ||
) -> RpcResult<TransactionBytes>; | ||
|
||
#[method(name = "splitCoin")] | ||
async fn split_coin( | ||
&self, | ||
signer: SuiAddress, | ||
coin_object_id: ObjectID, | ||
split_amounts: Vec<u64>, | ||
gas: Option<ObjectID>, | ||
gas_budget: u64, | ||
) -> RpcResult<TransactionBytes>; | ||
|
||
#[method(name = "mergeCoins")] | ||
async fn merge_coin( | ||
&self, | ||
signer: SuiAddress, | ||
primary_coin: ObjectID, | ||
coin_to_merge: ObjectID, | ||
gas: Option<ObjectID>, | ||
gas_budget: u64, | ||
) -> RpcResult<TransactionBytes>; | ||
|
||
pub trait RpcGatewayApi { | ||
/// Execute the transaction using the transaction data, signature and public key. | ||
#[method(name = "executeTransaction")] | ||
async fn execute_transaction( | ||
|
@@ -101,7 +39,11 @@ pub trait RpcGateway { | |
/// Synchronize client state with validators. | ||
#[method(name = "syncAccountState")] | ||
async fn sync_account_state(&self, address: SuiAddress) -> RpcResult<()>; | ||
} | ||
|
||
#[open_rpc(namespace = "sui", tag = "Read API")] | ||
#[rpc(server, client, namespace = "sui")] | ||
pub trait RpcReadApi { | ||
/// Return the list of objects owned by an address. | ||
#[method(name = "getOwnedObjects")] | ||
async fn get_owned_objects(&self, owner: SuiAddress) -> RpcResult<ObjectResponse>; | ||
|
@@ -128,6 +70,14 @@ pub trait RpcGateway { | |
digest: TransactionDigest, | ||
) -> RpcResult<TransactionEffectsResponse>; | ||
|
||
/// Return the object information for a specified object | ||
#[method(name = "getObjectInfo")] | ||
async fn get_object_info(&self, object_id: ObjectID) -> RpcResult<GetObjectInfoResponse>; | ||
} | ||
|
||
#[open_rpc(namespace = "sui", tag = "Full Node API")] | ||
#[rpc(server, client, namespace = "sui")] | ||
pub trait RpcFullNodeReadApi { | ||
#[method(name = "getTransactionsByInputObject")] | ||
async fn get_transactions_by_input_object( | ||
&self, | ||
|
@@ -151,10 +101,65 @@ pub trait RpcGateway { | |
&self, | ||
addr: SuiAddress, | ||
) -> RpcResult<Vec<(GatewayTxSeqNumber, TransactionDigest)>>; | ||
} | ||
|
||
/// Return the object information for a specified object | ||
#[method(name = "getObjectInfo")] | ||
async fn get_object_info(&self, object_id: ObjectID) -> RpcResult<GetObjectInfoResponse>; | ||
#[open_rpc(namespace = "sui", tag = "Transaction Builder API")] | ||
#[rpc(server, client, namespace = "sui")] | ||
pub trait RpcTransactionBuilder { | ||
/// Create a transaction to transfer a Sui coin from one address to another. | ||
#[method(name = "transferCoin")] | ||
async fn transfer_coin( | ||
&self, | ||
signer: SuiAddress, | ||
object_id: ObjectID, | ||
gas: Option<ObjectID>, | ||
gas_budget: u64, | ||
recipient: SuiAddress, | ||
) -> RpcResult<TransactionBytes>; | ||
|
||
/// Execute a Move call transaction by calling the specified function in the module of a given package. | ||
#[method(name = "moveCall")] | ||
async fn move_call( | ||
&self, | ||
signer: SuiAddress, | ||
package_object_id: ObjectID, | ||
module: String, | ||
function: String, | ||
type_arguments: Vec<SuiTypeTag>, | ||
arguments: Vec<SuiJsonValue>, | ||
gas: Option<ObjectID>, | ||
gas_budget: u64, | ||
) -> RpcResult<TransactionBytes>; | ||
|
||
/// Publish Move module. | ||
#[method(name = "publish")] | ||
async fn publish( | ||
&self, | ||
sender: SuiAddress, | ||
compiled_modules: Vec<Base64>, | ||
gas: Option<ObjectID>, | ||
gas_budget: u64, | ||
) -> RpcResult<TransactionBytes>; | ||
|
||
#[method(name = "splitCoin")] | ||
async fn split_coin( | ||
&self, | ||
signer: SuiAddress, | ||
coin_object_id: ObjectID, | ||
split_amounts: Vec<u64>, | ||
gas: Option<ObjectID>, | ||
gas_budget: u64, | ||
) -> RpcResult<TransactionBytes>; | ||
|
||
#[method(name = "mergeCoins")] | ||
async fn merge_coin( | ||
&self, | ||
signer: SuiAddress, | ||
primary_coin: ObjectID, | ||
coin_to_merge: ObjectID, | ||
gas: Option<ObjectID>, | ||
gas_budget: u64, | ||
) -> RpcResult<TransactionBytes>; | ||
} | ||
|
||
#[serde_as] | ||
|
@@ -183,3 +188,11 @@ impl TransactionBytes { | |
TransactionData::from_signable_bytes(&self.tx_bytes.to_vec()?) | ||
} | ||
} | ||
|
||
pub trait SuiRpcModule | ||
where | ||
Self: Sized, | ||
{ | ||
fn rpc(self) -> RpcModule<Self>; | ||
fn rpc_doc_module() -> Module; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,22 +1,39 @@ | ||
// Copyright (c) 2022, Mysten Labs, Inc. | ||
// SPDX-License-Identifier: Apache-2.0 | ||
|
||
use std::{env, net::SocketAddr, time::Instant}; | ||
|
||
use anyhow::Result; | ||
use jsonrpsee::{ | ||
http_server::{AccessControlBuilder, HttpServerBuilder, HttpServerHandle}, | ||
RpcModule, | ||
}; | ||
use jsonrpsee_core::{middleware::Middleware, server::rpc_module::Methods}; | ||
use jsonrpsee_core::middleware::Middleware; | ||
use prometheus_exporter::prometheus::{ | ||
register_histogram_vec, register_int_counter_vec, HistogramVec, IntCounterVec, | ||
}; | ||
use serde::Serialize; | ||
use std::{env, net::SocketAddr, time::Instant}; | ||
use tracing::info; | ||
|
||
use sui_open_rpc::Project; | ||
|
||
use crate::api::SuiRpcModule; | ||
|
||
pub struct JsonRpcServerBuilder { | ||
module: RpcModule<()>, | ||
server_builder: HttpServerBuilder<JsonRpcMetrics>, | ||
rpc_doc: Project, | ||
} | ||
|
||
pub fn sui_rpc_doc() -> Project { | ||
Project::new( | ||
"Sui JSON-RPC", | ||
"Sui JSON-RPC API for interaction with the Sui network gateway.", | ||
"Mysten Labs", | ||
"https://mystenlabs.com", | ||
"[email protected]", | ||
"Apache-2.0", | ||
"https://raw.githubusercontent.com/MystenLabs/sui/main/LICENSE", | ||
) | ||
} | ||
|
||
impl JsonRpcServerBuilder { | ||
|
@@ -41,23 +58,19 @@ impl JsonRpcServerBuilder { | |
Ok(Self { | ||
module, | ||
server_builder, | ||
rpc_doc: sui_rpc_doc(), | ||
}) | ||
} | ||
|
||
pub fn register_methods(&mut self, methods: impl Into<Methods>) -> Result<()> { | ||
self.module.merge(methods).map_err(Into::into) | ||
pub fn register_module<T: SuiRpcModule>(&mut self, module: T) -> Result<()> { | ||
self.rpc_doc.add_module(T::rpc_doc_module()); | ||
self.module.merge(module.rpc()).map_err(Into::into) | ||
} | ||
|
||
pub fn register_open_rpc<T>(&mut self, spec: T) -> Result<()> | ||
where | ||
T: Clone + Serialize + Send + Sync + 'static, | ||
{ | ||
pub async fn start(mut self, listen_address: SocketAddr) -> Result<HttpServerHandle> { | ||
self.module | ||
.register_method("rpc.discover", move |_, _| Ok(spec.clone()))?; | ||
Ok(()) | ||
} | ||
.register_method("rpc.discover", move |_, _| Ok(self.rpc_doc.clone()))?; | ||
|
||
pub async fn start(self, listen_address: SocketAddr) -> Result<HttpServerHandle> { | ||
let server = self.server_builder.build(listen_address).await?; | ||
|
||
let addr = server.local_addr()?; | ||
|
Oops, something went wrong.