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

Removed the lifetime in transact_async #249

Merged
merged 7 commits into from
Jan 9, 2023
Merged
Show file tree
Hide file tree
Changes from 5 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
68 changes: 40 additions & 28 deletions workspaces/src/operations.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,10 @@
use crate::error::{ErrorKind, RpcErrorCode};
use crate::result::{Execution, ExecutionFinalResult, Result, ViewResultDetails};
use crate::rpc::client::{
send_batch_tx_and_retry, send_batch_tx_async_and_retry, Client, DEFAULT_CALL_DEPOSIT,
send_batch_tx_and_retry, send_batch_tx_async_and_retry, DEFAULT_CALL_DEPOSIT,
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,
};
Expand All @@ -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;
Expand Down Expand Up @@ -112,18 +112,22 @@ impl Function {
/// is used by default for `Contract::batch`.
///
/// [`Contract::batch`]: crate::Contract::batch
pub struct Transaction<'a> {
client: &'a Client,
pub struct Transaction {
worker: Worker<dyn Network>,
signer: InMemorySigner,
receiver_id: AccountId,
// Result used to defer errors in argument parsing to later when calling into transact
actions: Result<Vec<Action>>,
}

impl<'a> Transaction<'a> {
pub(crate) fn new(client: &'a Client, signer: InMemorySigner, receiver_id: AccountId) -> Self {
impl Transaction {
pub(crate) fn new(
worker: Worker<dyn Network>,
signer: InMemorySigner,
receiver_id: AccountId,
) -> Self {
Self {
client,
worker,
signer,
receiver_id,
actions: Ok(Vec::new()),
Expand Down Expand Up @@ -230,7 +234,13 @@ impl<'a> Transaction<'a> {
}

async fn transact_raw(self) -> Result<FinalExecutionOutcomeView> {
send_batch_tx_and_retry(self.client, &self.signer, &self.receiver_id, self.actions?).await
send_batch_tx_and_retry(
self.worker.client(),
&self.signer,
&self.receiver_id,
self.actions?,
)
.await
}

/// Process the transaction, and return the result of the execution.
Expand All @@ -248,30 +258,30 @@ impl<'a> Transaction<'a> {
/// of the transaction.
///
/// [`status`]: TransactionStatus::status
pub async fn transact_async(self) -> Result<TransactionStatus<'a>> {
send_batch_tx_async_and_retry(self.client, &self.signer, &self.receiver_id, self.actions?)
pub async fn transact_async(self) -> Result<TransactionStatus> {
send_batch_tx_async_and_retry(self.worker, &self.signer, &self.receiver_id, self.actions?)
.await
}
}

/// Similiar to a [`Transaction`], but more specific to making a call into a contract.
/// Note, only one call can be made per `CallTransaction`.
pub struct CallTransaction<'a> {
client: &'a Client,
pub struct CallTransaction {
worker: Worker<dyn Network>,
signer: InMemorySigner,
contract_id: AccountId,
function: Function,
}

impl<'a> CallTransaction<'a> {
impl CallTransaction {
pub(crate) fn new(
client: &'a Client,
worker: Worker<dyn Network>,
contract_id: AccountId,
signer: InMemorySigner,
function: &str,
) -> Self {
Self {
client,
worker,
signer,
contract_id,
function: Function::new(function),
Expand Down Expand Up @@ -323,7 +333,8 @@ impl<'a> CallTransaction<'a> {
/// object and return us the execution details, along with any errors if the transaction
/// failed in any process along the way.
pub async fn transact(self) -> Result<ExecutionFinalResult> {
self.client
self.worker
.client()
.call(
&self.signer,
&self.contract_id,
Expand All @@ -344,9 +355,9 @@ impl<'a> CallTransaction<'a> {
/// of the transaction.
///
/// [`status`]: TransactionStatus::status
pub async fn transact_async(self) -> Result<TransactionStatus<'a>> {
pub async fn transact_async(self) -> Result<TransactionStatus> {
send_batch_tx_async_and_retry(
self.client,
self.worker,
&self.signer,
&self.contract_id,
vec![FunctionCallAction {
Expand All @@ -363,7 +374,7 @@ impl<'a> CallTransaction<'a> {
/// Instead of transacting the transaction, call into the specified view function.
pub async fn view(self) -> Result<ViewResultDetails> {
Query::new(
self.client,
self.worker.client(),
ViewFunction {
account_id: self.contract_id.clone(),
function: self.function,
Expand Down Expand Up @@ -446,20 +457,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 {
worker: Worker<dyn Network>,
sender_id: AccountId,
hash: CryptoHash,
}

impl<'a> TransactionStatus<'a> {
impl TransactionStatus {
pub(crate) fn new(
client: &'a Client,
worker: Worker<dyn Network>,
id: AccountId,
hash: near_primitives::hash::CryptoHash,
) -> Self {
Self {
client,
worker,
sender_id: id,
hash: CryptoHash(hash.0),
}
Expand All @@ -470,7 +481,8 @@ impl<'a> TransactionStatus<'a> {
/// `Ok` value with [`Poll::Pending`] is returned, then the transaction has not finished.
pub async fn status(&self) -> Result<Poll<ExecutionFinalResult>> {
let result = self
.client
.worker
.client()
.tx_async_status(
&self.sender_id,
near_primitives::hash::CryptoHash(self.hash.0),
Expand Down Expand Up @@ -512,7 +524,7 @@ impl<'a> TransactionStatus<'a> {
}
}

impl<'a> fmt::Debug for TransactionStatus<'a> {
impl fmt::Debug for TransactionStatus {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("TransactionStatus")
.field("sender_id", &self.sender_id)
Expand All @@ -521,9 +533,9 @@ impl<'a> fmt::Debug for TransactionStatus<'a> {
}
}

impl<'a> IntoFuture for TransactionStatus<'a> {
impl IntoFuture for TransactionStatus {
type Output = Result<ExecutionFinalResult>;
type IntoFuture = BoxFuture<'a, Self::Output>;
type IntoFuture = Pin<Box<dyn std::future::Future<Output = Self::Output>>>;

fn into_future(self) -> Self::IntoFuture {
Box::pin(async { self.wait().await })
Expand Down
14 changes: 8 additions & 6 deletions workspaces/src/rpc/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ use crate::error::{Error, ErrorKind, RpcErrorCode};
use crate::operations::TransactionStatus;
use crate::result::Result;
use crate::types::{AccountId, InMemorySigner, Nonce, PublicKey};
use crate::{Network, Worker};

pub(crate) const DEFAULT_CALL_FN_GAS: Gas = 10_000_000_000_000;
pub(crate) const DEFAULT_CALL_DEPOSIT: Balance = 0;
Expand Down Expand Up @@ -464,18 +465,19 @@ 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(
worker: Worker<dyn Network>,
signer: &InMemorySigner,
receiver_id: &AccountId,
actions: Vec<Action>,
) -> Result<TransactionStatus<'a>> {
) -> Result<TransactionStatus> {
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(worker.client(), &cache_key).await?;
let hash = worker
.client()
.query(&methods::broadcast_tx_async::RpcBroadcastTxAsyncRequest {
signed_transaction: SignedTransaction::from_actions(
nonce,
Expand All @@ -490,7 +492,7 @@ pub(crate) async fn send_batch_tx_async_and_retry<'a>(
.map_err(|e| RpcErrorCode::BroadcastTxFailure.custom(e))?;

Ok(TransactionStatus::new(
client,
worker.clone(),
signer.account_id.clone(),
hash,
))
Expand Down
8 changes: 4 additions & 4 deletions workspaces/src/types/account.rs
Original file line number Diff line number Diff line change
Expand Up @@ -71,9 +71,9 @@ impl Account {
/// a [`CallTransaction`] object that we will make use to populate the
/// rest of the call details. Note that the current [`Account`]'s secret
/// key is used as the signer of the transaction.
pub fn call(&self, contract_id: &AccountId, function: &str) -> CallTransaction<'_> {
pub fn call(&self, contract_id: &AccountId, function: &str) -> CallTransaction {
CallTransaction::new(
self.worker.client(),
self.worker.clone(),
contract_id.to_owned(),
self.signer.clone(),
function,
Expand Down Expand Up @@ -172,7 +172,7 @@ impl Account {
/// network.
pub fn batch(&self, contract_id: &AccountId) -> Transaction {
Transaction::new(
self.worker.client(),
self.worker.clone(),
self.signer().clone(),
contract_id.clone(),
)
Expand Down Expand Up @@ -270,7 +270,7 @@ impl Contract {
///
/// If we want to make use of the contract's secret key as a signer to call
/// into another contract, use `contract.as_account().call` instead.
pub fn call(&self, function: &str) -> CallTransaction<'_> {
pub fn call(&self, function: &str) -> CallTransaction {
self.account.call(self.id(), function)
}

Expand Down
43 changes: 24 additions & 19 deletions workspaces/src/worker/impls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,25 +41,6 @@ where
self.workspace.client()
}

/// Call into a contract's change function. Returns a [`CallTransaction`] object
/// that we will make use to populate the rest of the call details. The [`signer`]
/// will be used to sign the transaction.
///
/// [`signer`]: crate::types::InMemorySigner
pub fn call(
&self,
signer: &InMemorySigner,
contract_id: &AccountId,
function: &str,
) -> CallTransaction<'_> {
CallTransaction::new(
self.client(),
contract_id.to_owned(),
signer.clone(),
function,
)
}

/// Call into a contract's view function. Returns a [`Query`] which allows us
/// to specify further details like the arguments of the view call, or at what
/// point in the chain we want to view.
Expand Down Expand Up @@ -192,6 +173,30 @@ where
}
}

impl<T> Worker<T>
where
T: Network + 'static,
{
/// Call into a contract's change function. Returns a [`CallTransaction`] object
/// that we will make use to populate the rest of the call details. The [`signer`]
/// will be used to sign the transaction.
///
/// [`signer`]: crate::types::InMemorySigner
pub fn call(
&self,
signer: &InMemorySigner,
contract_id: &AccountId,
function: &str,
) -> CallTransaction {
CallTransaction::new(
self.clone().coerce(),
contract_id.to_owned(),
signer.clone(),
function,
)
}
}

impl Worker<Sandbox> {
pub fn root_account(&self) -> Result<Account> {
let signer = self.workspace.root_signer()?;
Expand Down