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

fix: Make call consistent with worker::view #245

Merged
merged 2 commits into from
Nov 30, 2022
Merged
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
8 changes: 4 additions & 4 deletions workspaces/src/network/sandbox.rs
Original file line number Diff line number Diff line change
Expand Up @@ -98,9 +98,9 @@ impl TopLevelAccountCreator for Sandbox {
.create_account(&root_signer, &id, sk.public_key(), DEFAULT_DEPOSIT)
.await?;

let signer = InMemorySigner::from_secret_key(id.clone(), sk);
let signer = InMemorySigner::from_secret_key(id, sk);
Ok(Execution {
result: Account::new(id, signer, worker),
result: Account::new(signer, worker),
details: ExecutionFinalResult::from_view(outcome),
})
}
Expand All @@ -124,9 +124,9 @@ impl TopLevelAccountCreator for Sandbox {
)
.await?;

let signer = InMemorySigner::from_secret_key(id.clone(), sk);
let signer = InMemorySigner::from_secret_key(id, sk);
Ok(Execution {
result: Contract::new(id, signer, worker),
result: Contract::new(signer, worker),
details: ExecutionFinalResult::from_view(outcome),
})
}
Expand Down
4 changes: 2 additions & 2 deletions workspaces/src/network/testnet.rs
Original file line number Diff line number Diff line change
Expand Up @@ -83,10 +83,10 @@ impl TopLevelAccountCreator for Testnet {
) -> Result<Execution<Account>> {
let url = Url::parse(HELPER_URL).unwrap();
tool::url_create_account(url, id.clone(), sk.public_key()).await?;
let signer = InMemorySigner::from_secret_key(id.clone(), sk);
let signer = InMemorySigner::from_secret_key(id, sk);

Ok(Execution {
result: Account::new(id, signer, worker),
result: Account::new(signer, worker),
details: ExecutionFinalResult {
// We technically have not burnt any gas ourselves since someone else paid to
// create the account for us in testnet when we used the Helper contract.
Expand Down
27 changes: 16 additions & 11 deletions workspaces/src/operations.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ use crate::rpc::client::{
send_batch_tx_and_retry, send_batch_tx_async_and_retry, Client, 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 Down Expand Up @@ -256,21 +257,21 @@ impl<'a> Transaction<'a> {
/// 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> {
worker: &'a Worker<dyn Network>,
client: &'a Client,
signer: InMemorySigner,
contract_id: AccountId,
function: Function,
}

impl<'a> CallTransaction<'a> {
pub(crate) fn new(
worker: &'a Worker<dyn Network>,
client: &'a Client,
contract_id: AccountId,
signer: InMemorySigner,
function: &str,
) -> Self {
Self {
worker,
client,
signer,
contract_id,
function: Function::new(function),
Expand Down Expand Up @@ -322,8 +323,7 @@ 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.worker
.client()
self.client
.call(
&self.signer,
&self.contract_id,
Expand All @@ -346,7 +346,7 @@ impl<'a> CallTransaction<'a> {
/// [`status`]: TransactionStatus::status
pub async fn transact_async(self) -> Result<TransactionStatus<'a>> {
send_batch_tx_async_and_retry(
self.worker.client(),
self.client,
&self.signer,
&self.contract_id,
vec![FunctionCallAction {
Expand All @@ -362,9 +362,14 @@ impl<'a> CallTransaction<'a> {

/// Instead of transacting the transaction, call into the specified view function.
pub async fn view(self) -> Result<ViewResultDetails> {
self.worker
.view_by_function(&self.contract_id, self.function)
.await
Query::new(
self.client,
ViewFunction {
account_id: self.contract_id.clone(),
function: self.function,
},
)
.await
}
}

Expand Down Expand Up @@ -426,8 +431,8 @@ impl<'a, 'b> CreateAccountTransaction<'a, 'b> {
.create_account(&self.signer, &id, sk.public_key(), self.initial_balance)
.await?;

let signer = InMemorySigner::from_secret_key(id.clone(), sk);
let account = Account::new(id, signer, self.worker.clone());
let signer = InMemorySigner::from_secret_key(id, sk);
let account = Account::new(signer, self.worker.clone());

Ok(Execution {
result: account,
Expand Down
2 changes: 1 addition & 1 deletion workspaces/src/rpc/patch.rs
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,6 @@ impl<'a, 'b> ImportContractTransaction<'a> {
.await
.map_err(|err| SandboxErrorCode::PatchStateFailure.custom(err))?;

Ok(Contract::new(account_id, signer, self.into_network))
Ok(Contract::new(signer, self.into_network))
}
}
57 changes: 26 additions & 31 deletions workspaces/src/types/account.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,14 +18,15 @@ use crate::result::{Execution, ExecutionFinalResult, Result};
/// network, such as creating transactions and calling into contract functions.
#[derive(Clone)]
pub struct Account {
pub(crate) id: AccountId,
pub(crate) signer: InMemorySigner,
signer: InMemorySigner,
worker: Worker<dyn Network>,
}

impl fmt::Debug for Account {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
f.debug_struct("Account").field("id", &self.id).finish()
f.debug_struct("Account")
.field("id", &self.signer.account_id)
.finish()
}
}

Expand All @@ -36,8 +37,7 @@ impl Account {
worker: &Worker<impl Network + 'static>,
) -> Result<Self> {
let signer = InMemorySigner::from_file(path.as_ref())?;
let id = signer.account_id.clone();
Ok(Self::new(id, signer, worker.clone().coerce()))
Ok(Self::new(signer, worker.clone().coerce()))
}

/// Create an [`Account`] object from an [`AccountId`] and [`SecretKey`].
Expand All @@ -47,36 +47,33 @@ impl Account {
worker: &Worker<impl Network + 'static>,
) -> Self {
Self {
id: id.clone(),
signer: InMemorySigner::from_secret_key(id, sk),
worker: worker.clone().coerce(),
}
}

pub(crate) fn new(id: AccountId, signer: InMemorySigner, worker: Worker<dyn Network>) -> Self {
Self { id, signer, worker }
pub(crate) fn new(signer: InMemorySigner, worker: Worker<dyn Network>) -> Self {
Self { signer, worker }
}

/// Grab the current account identifier
pub fn id(&self) -> &AccountId {
&self.id
&self.signer.account_id
}

pub(crate) fn signer(&self) -> &InMemorySigner {
/// Grab the signer of the account. This signer is used to sign all transactions
/// sent to the network.
pub fn signer(&self) -> &InMemorySigner {
&self.signer
}

/// Call a contract on the network specified within `worker`, and return
/// 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<'a, 'b>(
&'a self,
contract_id: &AccountId,
function: &'b str,
) -> CallTransaction<'a> {
pub fn call(&self, contract_id: &AccountId, function: &str) -> CallTransaction<'_> {
CallTransaction::new(
&self.worker,
self.worker.client(),
contract_id.to_owned(),
self.signer.clone(),
function,
Expand Down Expand Up @@ -105,13 +102,13 @@ impl Account {
/// transaction. The beneficiary will receive the funds of the account deleted
pub async fn delete_account(self, beneficiary_id: &AccountId) -> Result<ExecutionFinalResult> {
self.worker
.delete_account(&self.id, &self.signer, beneficiary_id)
.delete_account(self.id(), &self.signer, beneficiary_id)
.await
}

/// Views the current account's details such as balance and storage usage.
pub fn view_account(&self) -> Query<'_, ViewAccount> {
self.worker.view_account(&self.id)
self.worker.view_account(self.id())
}

/// Views the current accounts's access key, given the [`PublicKey`] associated to it.
Expand All @@ -133,7 +130,7 @@ impl Account {
Query::new(
self.worker.client(),
ViewAccessKeyList {
account_id: self.id.clone(),
account_id: self.id().clone(),
},
)
}
Expand Down Expand Up @@ -163,11 +160,7 @@ impl Account {
.await?;

Ok(Execution {
result: Contract::new(
self.id().clone(),
self.signer().clone(),
self.worker.clone(),
),
result: Contract::new(self.signer().clone(), self.worker.clone()),
details: ExecutionFinalResult::from_view(outcome),
})
}
Expand All @@ -190,10 +183,10 @@ impl Account {
let savepath = save_dir.as_ref().to_path_buf();
std::fs::create_dir_all(save_dir).map_err(|e| ErrorKind::Io.custom(e))?;

let mut savepath = savepath.join(self.id.to_string());
let mut savepath = savepath.join(self.id().to_string());
savepath.set_extension("json");

crate::rpc::tool::write_cred_to_file(&savepath, &self.id, &self.secret_key().0);
crate::rpc::tool::write_cred_to_file(&savepath, self.id(), &self.secret_key().0);

Ok(())
}
Expand Down Expand Up @@ -221,7 +214,7 @@ pub struct Contract {
impl fmt::Debug for Contract {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
f.debug_struct("Contract")
.field("id", &self.account.id)
.field("id", self.account.id())
.finish()
}
}
Expand All @@ -236,9 +229,9 @@ impl Contract {
Self::account(Account::from_secret_key(id, sk, worker))
}

pub(crate) fn new(id: AccountId, signer: InMemorySigner, worker: Worker<dyn Network>) -> Self {
pub(crate) fn new(signer: InMemorySigner, worker: Worker<dyn Network>) -> Self {
Self {
account: Account::new(id, signer, worker),
account: Account::new(signer, worker),
}
}

Expand All @@ -248,7 +241,7 @@ impl Contract {

/// Grab the current contract's account identifier
pub fn id(&self) -> &AccountId {
&self.account.id
self.account.id()
}

/// Treat this [`Contract`] object as an [`Account`] type. This does nothing
Expand All @@ -265,7 +258,9 @@ impl Contract {
&mut self.account
}

pub(crate) fn signer(&self) -> &InMemorySigner {
/// Grab the signer of the account. This signer is used to sign all transactions
/// sent to the network.
pub fn signer(&self) -> &InMemorySigner {
self.account.signer()
}

Expand Down
54 changes: 25 additions & 29 deletions workspaces/src/worker/impls.rs
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
use crate::network::{AllowDevAccountCreation, NetworkClient, NetworkInfo};
use crate::network::{Info, Sandbox};
use crate::operations::Function;
use crate::operations::{CallTransaction, Function};
use crate::result::{ExecutionFinalResult, Result};
use crate::rpc::client::{Client, DEFAULT_CALL_DEPOSIT, DEFAULT_CALL_FN_GAS};
use crate::rpc::client::Client;
use crate::rpc::patch::ImportContractTransaction;
use crate::rpc::query::{
GasPrice, Query, QueryChunk, ViewAccessKey, ViewAccessKeyList, ViewAccount, ViewBlock,
ViewCode, ViewFunction, ViewState,
};
use crate::types::{AccountId, Gas, InMemorySigner, PublicKey};
use crate::types::{AccountId, InMemorySigner, PublicKey};
use crate::worker::Worker;
use crate::{Account, Contract, Network};
use crate::{Account, Network};

use near_primitives::types::Balance;

Expand Down Expand Up @@ -41,31 +41,28 @@ where
self.workspace.client()
}

/// Call into a contract's change function.
pub async fn call(
/// 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,
contract: &Contract,
signer: &InMemorySigner,
contract_id: &AccountId,
function: &str,
args: Vec<u8>,
gas: Option<Gas>,
deposit: Option<Balance>,
) -> Result<ExecutionFinalResult> {
let outcome = self
.client()
.call(
contract.signer(),
contract.id(),
function.into(),
args,
gas.unwrap_or(DEFAULT_CALL_FN_GAS),
deposit.unwrap_or(DEFAULT_CALL_DEPOSIT),
)
.await?;

Ok(ExecutionFinalResult::from_view(outcome))
}

/// Call into a contract's view function.
) -> 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.
pub fn view(&self, contract_id: &AccountId, function: &str) -> Query<'_, ViewFunction> {
self.view_by_function(contract_id, Function::new(function))
}
Expand Down Expand Up @@ -197,9 +194,8 @@ where

impl Worker<Sandbox> {
pub fn root_account(&self) -> Result<Account> {
let account_id = self.info().root_id.clone();
let signer = self.workspace.root_signer()?;
Ok(Account::new(account_id, signer, self.clone().coerce()))
Ok(Account::new(signer, self.clone().coerce()))
}

/// Import a contract from the the given network, and return us a [`ImportContractTransaction`]
Expand Down