diff --git a/workspaces/src/operations.rs b/workspaces/src/operations.rs index 1083f3c7..7dac54a9 100644 --- a/workspaces/src/operations.rs +++ b/workspaces/src/operations.rs @@ -7,7 +7,6 @@ use crate::rpc::client::{ DEFAULT_CALL_FN_GAS, }; use crate::rpc::query::{Query, ViewFunction}; -use crate::rpc::BoxFuture; use crate::types::{ AccessKey, AccountId, Balance, Gas, InMemorySigner, KeyType, PublicKey, SecretKey, }; @@ -25,6 +24,7 @@ use near_primitives::views::FinalExecutionOutcomeView; use std::convert::TryInto; use std::fmt; use std::future::IntoFuture; +use std::pin::Pin; use std::task::Poll; const MAX_GAS: Gas = 300_000_000_000_000; @@ -248,7 +248,7 @@ impl<'a> Transaction<'a> { /// of the transaction. /// /// [`status`]: TransactionStatus::status - pub async fn transact_async(self) -> Result> { + pub async fn transact_async(self) -> Result { send_batch_tx_async_and_retry(self.client, &self.signer, &self.receiver_id, self.actions?) .await } @@ -344,7 +344,7 @@ impl<'a> CallTransaction<'a> { /// of the transaction. /// /// [`status`]: TransactionStatus::status - pub async fn transact_async(self) -> Result> { + pub async fn transact_async(self) -> Result { send_batch_tx_async_and_retry( self.client, &self.signer, @@ -446,20 +446,20 @@ impl<'a, 'b> CreateAccountTransaction<'a, 'b> { /// /// [`asynchronous transaction`]: https://docs.near.org/api/rpc/transactions#send-transaction-async #[must_use] -pub struct TransactionStatus<'a> { - client: &'a Client, +pub struct TransactionStatus { + client: Client, sender_id: AccountId, hash: CryptoHash, } -impl<'a> TransactionStatus<'a> { +impl TransactionStatus { pub(crate) fn new( - client: &'a Client, + client: &Client, id: AccountId, hash: near_primitives::hash::CryptoHash, ) -> Self { Self { - client, + client: client.clone(), sender_id: id, hash: CryptoHash(hash.0), } @@ -512,7 +512,7 @@ impl<'a> TransactionStatus<'a> { } } -impl<'a> fmt::Debug for TransactionStatus<'a> { +impl<'a> fmt::Debug for TransactionStatus { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_struct("TransactionStatus") .field("sender_id", &self.sender_id) @@ -521,9 +521,9 @@ impl<'a> fmt::Debug for TransactionStatus<'a> { } } -impl<'a> IntoFuture for TransactionStatus<'a> { +impl IntoFuture for TransactionStatus { type Output = Result; - type IntoFuture = BoxFuture<'a, Self::Output>; + type IntoFuture = Pin>>; fn into_future(self) -> Self::IntoFuture { Box::pin(async { self.wait().await }) diff --git a/workspaces/src/rpc/client.rs b/workspaces/src/rpc/client.rs index b2c8e5d0..434e5c4b 100644 --- a/workspaces/src/rpc/client.rs +++ b/workspaces/src/rpc/client.rs @@ -2,6 +2,7 @@ use std::collections::hash_map::Entry; use std::collections::HashMap; use std::fmt::Debug; use std::sync::atomic::{AtomicU64, Ordering}; +use std::sync::Arc; use std::time::Duration; use tokio::sync::RwLock; @@ -36,11 +37,13 @@ pub(crate) const DEFAULT_CALL_DEPOSIT: Balance = 0; /// A client that wraps around [`JsonRpcClient`], and provides more capabilities such /// as retry w/ exponential backoff and utility functions for sending transactions. +#[derive(Clone)] pub struct Client { rpc_addr: String, rpc_client: JsonRpcClient, /// AccessKey nonces to reference when sending transactions. - pub(crate) access_key_nonces: RwLock>, + pub(crate) access_key_nonces: + Arc>>, } impl Client { @@ -51,7 +54,7 @@ impl Client { Self { rpc_client, rpc_addr: rpc_addr.into(), - access_key_nonces: RwLock::new(HashMap::new()), + access_key_nonces: Arc::new(RwLock::new(HashMap::new())), } } @@ -446,9 +449,9 @@ pub(crate) async fn send_batch_tx_and_retry( let cache_key = (signer.account_id.clone(), signer.public_key()); retry(|| async { - let (block_hash, nonce) = fetch_tx_nonce(client, &cache_key).await?; + let (block_hash, nonce) = fetch_tx_nonce(&client, &cache_key).await?; send_tx( - client, + &*client, &cache_key, SignedTransaction::from_actions( nonce, @@ -464,18 +467,18 @@ pub(crate) async fn send_batch_tx_and_retry( .await } -pub(crate) async fn send_batch_tx_async_and_retry<'a>( - client: &'a Client, +pub(crate) async fn send_batch_tx_async_and_retry( + client: &Client, signer: &InMemorySigner, receiver_id: &AccountId, actions: Vec, -) -> Result> { +) -> Result { let signer = signer.inner(); let cache_key = (signer.account_id.clone(), signer.public_key()); retry(|| async { - let (block_hash, nonce) = fetch_tx_nonce(client, &cache_key).await?; - let hash = client + let (block_hash, nonce) = fetch_tx_nonce(&client, &cache_key).await?; + let hash = &client .query(&methods::broadcast_tx_async::RpcBroadcastTxAsyncRequest { signed_transaction: SignedTransaction::from_actions( nonce, @@ -490,9 +493,9 @@ pub(crate) async fn send_batch_tx_async_and_retry<'a>( .map_err(|e| RpcErrorCode::BroadcastTxFailure.custom(e))?; Ok(TransactionStatus::new( - client, + &client.clone(), signer.account_id.clone(), - hash, + *hash, )) }) .await