Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(dev-tools): Clean up excess Arc usage in sdk #2217

Open
wants to merge 17 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions crates/iota-core/src/authority.rs
Original file line number Diff line number Diff line change
Expand Up @@ -802,6 +802,16 @@ pub struct AuthorityState {
pub validator_tx_finalizer: Option<Arc<ValidatorTxFinalizer<NetworkAuthorityClient>>>,
}

impl core::fmt::Debug for AuthorityState {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("AuthorityState")
.field("name", &self.name)
.field("db_checkpoint_config", &self.db_checkpoint_config)
.field("config", &self.config)
.finish()
}
}

/// The authority state encapsulates all state, drives execution, and ensures
/// safety.
///
Expand Down
21 changes: 18 additions & 3 deletions crates/iota-indexer/src/apis/transaction_builder_api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,25 @@ pub(crate) struct TransactionBuilderApi<T: R2D2Connection + 'static> {
inner: IndexerReader<T>,
}

impl<T: R2D2Connection> Clone for TransactionBuilderApi<T> {
fn clone(&self) -> Self {
Self {
inner: self.inner.clone(),
}
}
}

impl<T: R2D2Connection> core::fmt::Debug for TransactionBuilderApi<T> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("TransactionBuilderApi")
.field("inner", &self.inner)
.finish()
}
}

impl<T: R2D2Connection> TransactionBuilderApi<T> {
#[expect(clippy::new_ret_no_self)]
pub fn new(inner: IndexerReader<T>) -> IotaTransactionBuilderApi {
IotaTransactionBuilderApi::new_with_data_reader(std::sync::Arc::new(Self { inner }))
pub fn new(inner: IndexerReader<T>) -> IotaTransactionBuilderApi<TransactionBuilderApi<T>> {
IotaTransactionBuilderApi::new_with_data_reader(Self { inner })
}
}

Expand Down
14 changes: 10 additions & 4 deletions crates/iota-indexer/src/indexer_reader.rs
Original file line number Diff line number Diff line change
Expand Up @@ -82,10 +82,7 @@ where
package_obj_type_cache: Arc<Mutex<SizedCache<String, Option<ObjectID>>>>,
}

impl<T> Clone for IndexerReader<T>
where
T: R2D2Connection,
{
impl<T: R2D2Connection> Clone for IndexerReader<T> {
fn clone(&self) -> IndexerReader<T> {
IndexerReader {
pool: self.pool.clone(),
Expand All @@ -95,6 +92,15 @@ where
}
}

impl<U: R2D2Connection> core::fmt::Debug for IndexerReader<U> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("IndexerReader")
.field("pool", &self.pool)
.field("package_obj_type_cache", &self.package_obj_type_cache)
.finish()
}
}

pub type PackageResolver<T> =
Arc<Resolver<PackageStoreWithLruCache<IndexerStorePackageResolver<T>>>>;

Expand Down
39 changes: 23 additions & 16 deletions crates/iota-json-rpc/src/transaction_builder_api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,20 +25,25 @@ use move_core_types::language_storage::StructTag;

use crate::{IotaRpcModule, authority_state::StateRead};

pub struct TransactionBuilderApi(TransactionBuilder);
#[derive(Clone, Debug)]
pub struct TransactionBuilderApi<R>(TransactionBuilder<R>);

impl TransactionBuilderApi {
impl TransactionBuilderApi<AuthorityStateDataReader> {
pub fn new(state: Arc<AuthorityState>) -> Self {
let reader = Arc::new(AuthorityStateDataReader::new(state));
Self(TransactionBuilder::new(reader))
Self(TransactionBuilder::new(AuthorityStateDataReader::new(
state,
)))
}
}

pub fn new_with_data_reader(data_reader: Arc<dyn DataReader + Sync + Send>) -> Self {
impl<R: DataReader + core::fmt::Debug + Clone + Send + Sync> TransactionBuilderApi<R> {
pub fn new_with_data_reader(data_reader: R) -> Self {
Self(TransactionBuilder::new(data_reader))
}
}

pub struct AuthorityStateDataReader(Arc<dyn StateRead>);
#[derive(Clone, Debug)]
pub struct AuthorityStateDataReader(Arc<AuthorityState>);

impl AuthorityStateDataReader {
pub fn new(state: Arc<AuthorityState>) -> Self {
Expand All @@ -53,14 +58,12 @@ impl DataReader for AuthorityStateDataReader {
address: IotaAddress,
object_type: StructTag,
) -> Result<Vec<ObjectInfo>, anyhow::Error> {
Ok(self
.0
// DataReader is used internally, don't need a limit
.get_owner_objects(
address,
None,
Some(IotaObjectDataFilter::StructType(object_type)),
)?)
Ok(StateRead::get_owner_objects(
self.0.as_ref(),
address,
None,
Some(IotaObjectDataFilter::StructType(object_type)),
)?)
}

async fn get_object_with_options(
Expand All @@ -79,7 +82,9 @@ impl DataReader for AuthorityStateDataReader {
}

#[async_trait]
impl TransactionBuilderServer for TransactionBuilderApi {
impl<R: DataReader + core::fmt::Debug + Clone + Send + Sync + 'static> TransactionBuilderServer
for TransactionBuilderApi<R>
{
async fn transfer_object(
&self,
signer: IotaAddress,
Expand Down Expand Up @@ -366,7 +371,9 @@ impl TransactionBuilderServer for TransactionBuilderApi {
}
}

impl IotaRpcModule for TransactionBuilderApi {
impl<R: DataReader + core::fmt::Debug + Clone + Send + Sync + 'static> IotaRpcModule
for TransactionBuilderApi<R>
{
fn rpc(self) -> RpcModule<Self> {
self.into_rpc()
}
Expand Down
13 changes: 7 additions & 6 deletions crates/iota-open-rpc/src/generate_json_rpc_spec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,13 @@
use std::{fs::File, io::Write};

use clap::{Parser, ValueEnum};
// temporarily remove api ref content for indexer methods
// use iota_json_rpc::api::ExtendedApiOpenRpc;
use iota_json_rpc::coin_api::CoinReadApi;
use iota_json_rpc::{
IotaRpcModule, governance_api::GovernanceReadApi, iota_rpc_doc, read_api::ReadApi,
transaction_builder_api::TransactionBuilderApi,
IotaRpcModule,
coin_api::CoinReadApi,
governance_api::GovernanceReadApi,
iota_rpc_doc,
read_api::ReadApi,
transaction_builder_api::{AuthorityStateDataReader, TransactionBuilderApi},
transaction_execution_api::TransactionExecutionApi,
};
use iota_json_rpc_api::{ExtendedApiOpenRpc, IndexerApiOpenRpc, MoveUtilsOpenRpc};
Expand Down Expand Up @@ -51,7 +52,7 @@ async fn main() {
open_rpc.add_module(CoinReadApi::rpc_doc_module());
open_rpc.add_module(IndexerApiOpenRpc::module_doc());
open_rpc.add_module(TransactionExecutionApi::rpc_doc_module());
open_rpc.add_module(TransactionBuilderApi::rpc_doc_module());
open_rpc.add_module(TransactionBuilderApi::<AuthorityStateDataReader>::rpc_doc_module());
open_rpc.add_module(GovernanceReadApi::rpc_doc_module());
open_rpc.add_module(ExtendedApiOpenRpc::module_doc());
open_rpc.add_module(MoveUtilsOpenRpc::module_doc());
Expand Down
2 changes: 1 addition & 1 deletion crates/iota-sdk/src/apis/event.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ use crate::{
};

/// Defines methods to fetch, query, or subscribe to events on the Iota network.
#[derive(Clone)]
#[derive(Clone, Debug)]
pub struct EventApi {
api: Arc<RpcClient>,
}
Expand Down
2 changes: 1 addition & 1 deletion crates/iota-sdk/src/apis/quorum_driver.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ const WAIT_FOR_LOCAL_EXECUTION_DELAY: Duration = Duration::from_millis(200);
const WAIT_FOR_LOCAL_EXECUTION_INTERVAL: Duration = Duration::from_secs(2);

/// Defines methods to execute transaction blocks and submit them to fullnodes.
#[derive(Clone)]
#[derive(Clone, Debug)]
pub struct QuorumDriverApi {
api: Arc<RpcClient>,
}
Expand Down
2 changes: 1 addition & 1 deletion crates/iota-sdk/src/apis/read.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ use crate::{
};

/// Defines methods for retrieving data about objects and transactions.
#[derive(Debug)]
#[derive(Clone, Debug)]
pub struct ReadApi {
api: Arc<RpcClient>,
}
Expand Down
41 changes: 18 additions & 23 deletions crates/iota-sdk/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -79,11 +79,7 @@ pub mod iota_client_config;
pub mod json_rpc_error;
pub mod wallet_context;

use std::{
fmt::{Debug, Formatter},
sync::Arc,
time::Duration,
};
use std::{fmt::Debug, sync::Arc, time::Duration};

use async_trait::async_trait;
use base64::Engine;
Expand Down Expand Up @@ -265,11 +261,10 @@ impl IotaClientBuilder {
.request_timeout(self.request_timeout)
.build(http)?;

let info = Self::get_server_info(&http, &ws).await?;
let info = Self::get_server_info(&http, ws.as_ref()).await?;

let rpc = RpcClient { http, ws, info };
let api = Arc::new(rpc);
let read_api = Arc::new(ReadApi::new(api.clone()));
let api = Arc::new(RpcClient { http, ws, info });
let read_api = ReadApi::new(api.clone());
let quorum_driver_api = QuorumDriverApi::new(api.clone());
let event_api = EventApi::new(api.clone());
let transaction_builder = TransactionBuilder::new(read_api.clone());
Expand Down Expand Up @@ -359,7 +354,7 @@ impl IotaClientBuilder {
/// Fails with an error if it cannot call the RPC discover.
async fn get_server_info(
http: &HttpClient,
ws: &Option<WsClient>,
ws: Option<&WsClient>,
) -> Result<ServerInfo, Error> {
let rpc_spec: Value = http.request("rpc.discover", rpc_params![]).await?;
let version = rpc_spec
Expand Down Expand Up @@ -439,32 +434,32 @@ impl IotaClientBuilder {
#[derive(Clone)]
pub struct IotaClient {
api: Arc<RpcClient>,
transaction_builder: TransactionBuilder,
read_api: Arc<ReadApi>,
transaction_builder: TransactionBuilder<ReadApi>,
read_api: ReadApi,
coin_read_api: CoinReadApi,
event_api: EventApi,
quorum_driver_api: QuorumDriverApi,
governance_api: GovernanceApi,
}

impl core::fmt::Debug for IotaClient {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("IotaClient")
.field("api", &self.api)
.finish()
}
}

#[derive(Debug)]
pub(crate) struct RpcClient {
http: HttpClient,
ws: Option<WsClient>,
info: ServerInfo,
}

impl Debug for RpcClient {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
write!(
f,
"RPC client. Http: {:?}, Websocket: {:?}",
self.http, self.ws
)
}
}

/// Contains all the useful information regarding the API version, the available
/// RPC calls, and subscriptions.
#[derive(Clone, Debug)]
struct ServerInfo {
rpc_methods: Vec<String>,
subscriptions: Vec<String>,
Expand Down Expand Up @@ -533,7 +528,7 @@ impl IotaClient {
}

/// Return a reference to the transaction builder API.
pub fn transaction_builder(&self) -> &TransactionBuilder {
pub fn transaction_builder(&self) -> &TransactionBuilder<ReadApi> {
&self.transaction_builder
}

Expand Down
33 changes: 29 additions & 4 deletions crates/iota-transaction-builder/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,11 +43,36 @@ pub trait DataReader {
async fn get_reference_gas_price(&self) -> Result<u64, anyhow::Error>;
}

#[derive(Clone)]
pub struct TransactionBuilder(Arc<dyn DataReader + Sync + Send>);
#[async_trait]
impl<T: DataReader + Send + Sync + 'static> DataReader for Arc<T> {
async fn get_owned_objects(
Copy link
Contributor

Choose a reason for hiding this comment

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

Is this change somehow related to the Arc cleanup?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes, it was necessary because of the cleanup of one of the methods

&self,
address: IotaAddress,
object_type: StructTag,
) -> Result<Vec<ObjectInfo>, anyhow::Error> {
self.as_ref().get_owned_objects(address, object_type).await
}

async fn get_object_with_options(
&self,
object_id: ObjectID,
options: IotaObjectDataOptions,
) -> Result<IotaObjectResponse, anyhow::Error> {
self.as_ref()
.get_object_with_options(object_id, options)
.await
}

async fn get_reference_gas_price(&self) -> Result<u64, anyhow::Error> {
self.as_ref().get_reference_gas_price().await
}
}

#[derive(Clone, Debug)]
pub struct TransactionBuilder<R>(R);

impl TransactionBuilder {
pub fn new(data_reader: Arc<dyn DataReader + Sync + Send>) -> Self {
impl<R: DataReader + core::fmt::Debug + Clone + Send + Sync> TransactionBuilder<R> {
pub fn new(data_reader: R) -> Self {
Self(data_reader)
}

Expand Down
4 changes: 2 additions & 2 deletions crates/iota-transaction-builder/src/package.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,9 @@ use iota_types::{
};
use move_core_types::ident_str;

use crate::TransactionBuilder;
use crate::{DataReader, TransactionBuilder};

impl TransactionBuilder {
impl<R: DataReader + core::fmt::Debug + Clone + Send + Sync> TransactionBuilder<R> {
/// Build a [`TransactionKind::ProgrammableTransaction`] that contains
/// [`iota_types::transaction::Command::Publish`] for the provided package.
pub async fn publish_tx_kind(
Expand Down
4 changes: 2 additions & 2 deletions crates/iota-transaction-builder/src/stake.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,9 @@ use iota_types::{
transaction::{CallArg, Command, ObjectArg, TransactionData},
};

use crate::TransactionBuilder;
use crate::{DataReader, TransactionBuilder};

impl TransactionBuilder {
impl<R: DataReader + core::fmt::Debug + Clone + Send + Sync> TransactionBuilder<R> {
/// Add stake to a validator's staking pool using multiple IOTA coins.
pub async fn request_add_stake(
&self,
Expand Down
4 changes: 2 additions & 2 deletions crates/iota-transaction-builder/src/utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,9 @@ use move_binary_format::{
};
use move_core_types::{identifier::Identifier, language_storage::TypeTag};

use crate::TransactionBuilder;
use crate::{DataReader, TransactionBuilder};

impl TransactionBuilder {
impl<R: DataReader + core::fmt::Debug + Clone + Send + Sync> TransactionBuilder<R> {
/// Select a gas coin for the provided gas budget.
pub(crate) async fn select_gas(
&self,
Expand Down