Skip to content

Commit

Permalink
feat: create dev account with deposit on sandbox
Browse files Browse the repository at this point in the history
  • Loading branch information
VladasZ committed Feb 12, 2024
1 parent 97d6449 commit bbfc339
Show file tree
Hide file tree
Showing 3 changed files with 107 additions and 76 deletions.
94 changes: 44 additions & 50 deletions workspaces/src/network/sandbox.rs
Original file line number Diff line number Diff line change
@@ -1,22 +1,25 @@
use std::path::PathBuf;
use std::str::FromStr;
use std::{path::PathBuf, str::FromStr};

use async_trait::async_trait;
use near_jsonrpc_client::methods::sandbox_fast_forward::RpcSandboxFastForwardRequest;
use near_jsonrpc_client::methods::sandbox_patch_state::RpcSandboxPatchStateRequest;
use near_jsonrpc_client::methods::{
sandbox_fast_forward::RpcSandboxFastForwardRequest, sandbox_patch_state::RpcSandboxPatchStateRequest,
};
use near_primitives::state_record::StateRecord;
use near_sandbox_utils as sandbox;

use super::builder::{FromNetworkBuilder, NetworkBuilder};
use super::server::ValidatorKey;
use super::{AllowDevAccountCreation, NetworkClient, NetworkInfo, TopLevelAccountCreator};
use crate::error::SandboxErrorCode;
use crate::network::server::SandboxServer;
use crate::network::Info;
use crate::result::{Execution, ExecutionFinalResult, Result};
use crate::rpc::client::Client;
use crate::types::{AccountId, InMemorySigner, NearToken, SecretKey};
use crate::{Account, Contract, Network, Worker};
use super::{
builder::{FromNetworkBuilder, NetworkBuilder},
server::ValidatorKey,
AllowDevAccountCreation, NetworkClient, NetworkInfo, TopLevelAccountCreator,
};
use crate::{
error::SandboxErrorCode,
network::{server::SandboxServer, Info},
result::{Execution, ExecutionFinalResult, Result},
rpc::client::Client,
types::{AccountId, InMemorySigner, NearToken, SecretKey},
Account, Contract, Network, Worker,
};

// Constant taken from nearcore crate to avoid dependency
const DEFAULT_DEPOSIT: NearToken = NearToken::from_near(100);
Expand All @@ -39,36 +42,28 @@ impl Sandbox {
let path = home_dir.join("validator_key.json");
InMemorySigner::from_file(&path)
}
ValidatorKey::Known(account_id, secret_key) => Ok(InMemorySigner::from_secret_key(
account_id.clone(),
secret_key.clone(),
)),
ValidatorKey::Known(account_id, secret_key) => {
Ok(InMemorySigner::from_secret_key(account_id.clone(), secret_key.clone()))
}
}
}
pub(crate) async fn from_builder_with_version<'a>(
build: NetworkBuilder<'a, Self>,
version: &str,
) -> Result<Self> {
pub(crate) async fn from_builder_with_version<'a>(build: NetworkBuilder<'a, Self>, version: &str) -> Result<Self> {
// Check the conditions of the provided rpc_url and validator_key
let mut server = match (build.rpc_addr, build.validator_key) {
// Connect to a provided sandbox:
(Some(rpc_url), Some(validator_key)) => {
SandboxServer::connect(rpc_url, validator_key).await?
}
(Some(rpc_url), Some(validator_key)) => SandboxServer::connect(rpc_url, validator_key).await?,

// Spawn a new sandbox since rpc_url and home_dir weren't specified:
(None, None) => SandboxServer::run_new_with_version(version).await?,

// Missing inputted parameters for sandbox:
(Some(rpc_url), None) => {
return Err(SandboxErrorCode::InitFailure.message(format!(
"Custom rpc_url={rpc_url} requires validator_key set."
)));
return Err(SandboxErrorCode::InitFailure
.message(format!("Custom rpc_url={rpc_url} requires validator_key set.")));
}
(None, Some(validator_key)) => {
return Err(SandboxErrorCode::InitFailure.message(format!(
"Custom validator_key={validator_key:?} requires rpc_url set."
)));
return Err(SandboxErrorCode::InitFailure
.message(format!("Custom validator_key={validator_key:?} requires rpc_url set.")));
}
};

Expand Down Expand Up @@ -126,41 +121,45 @@ impl TopLevelAccountCreator for Sandbox {
id: AccountId,
sk: SecretKey,
) -> Result<Execution<Account>> {
self.create_tla_with_deposit(worker, id, sk, DEFAULT_DEPOSIT).await
}

async fn create_tla_and_deploy(
&self,
worker: Worker<dyn Network>,
id: AccountId,
sk: SecretKey,
wasm: &[u8],
) -> Result<Execution<Contract>> {
let root_signer = self.root_signer()?;
let outcome = self
.client()
.create_account(&root_signer, &id, sk.public_key(), DEFAULT_DEPOSIT)
.create_account_and_deploy(&root_signer, &id, sk.public_key(), DEFAULT_DEPOSIT, wasm.into())
.await?;

let signer = InMemorySigner::from_secret_key(id, sk);
Ok(Execution {
result: Account::new(signer, worker),
result: Contract::new(signer, worker),
details: ExecutionFinalResult::from_view(outcome),
})
}

async fn create_tla_and_deploy(
async fn create_tla_with_deposit(
&self,
worker: Worker<dyn Network>,
id: AccountId,
sk: SecretKey,
wasm: &[u8],
) -> Result<Execution<Contract>> {
deposit: NearToken,
) -> Result<Execution<Account>> {
let root_signer = self.root_signer()?;
let outcome = self
.client()
.create_account_and_deploy(
&root_signer,
&id,
sk.public_key(),
DEFAULT_DEPOSIT,
wasm.into(),
)
.create_account(&root_signer, &id, sk.public_key(), deposit)
.await?;

let signer = InMemorySigner::from_secret_key(id, sk);
Ok(Execution {
result: Contract::new(signer, worker),
result: Account::new(signer, worker),
details: ExecutionFinalResult::from_view(outcome),
})
}
Expand All @@ -179,12 +178,7 @@ impl NetworkInfo for Sandbox {
}

impl Sandbox {
pub(crate) async fn patch_state(
&self,
contract_id: &AccountId,
key: &[u8],
value: &[u8],
) -> Result<()> {
pub(crate) async fn patch_state(&self, contract_id: &AccountId, key: &[u8], value: &[u8]) -> Result<()> {
let state = StateRecord::Data {
account_id: contract_id.to_owned(),
data_key: key.to_vec().into(),
Expand Down
33 changes: 22 additions & 11 deletions workspaces/src/network/testnet.rs
Original file line number Diff line number Diff line change
@@ -1,19 +1,20 @@
use std::path::PathBuf;
use std::str::FromStr;
use std::{path::PathBuf, str::FromStr};

use async_trait::async_trait;
use near_gas::NearGas;
use url::Url;

use near_primitives::views::ExecutionStatusView;
use url::Url;

use crate::network::builder::{FromNetworkBuilder, NetworkBuilder};
use crate::network::Info;
use crate::network::{AllowDevAccountCreation, NetworkClient, NetworkInfo, TopLevelAccountCreator};
use crate::result::{Execution, ExecutionDetails, ExecutionFinalResult, ExecutionOutcome, Result};
use crate::rpc::{client::Client, tool};
use crate::types::{AccountId, InMemorySigner, NearToken, SecretKey};
use crate::{Account, Contract, CryptoHash, Network, Worker};
use crate::{
network::{
builder::{FromNetworkBuilder, NetworkBuilder},
AllowDevAccountCreation, Info, NetworkClient, NetworkInfo, TopLevelAccountCreator,
},
result::{Execution, ExecutionDetails, ExecutionFinalResult, ExecutionOutcome, Result},
rpc::{client::Client, tool},
types::{AccountId, InMemorySigner, NearToken, SecretKey},
Account, Contract, CryptoHash, Network, Worker,
};

/// URL to the testnet RPC node provided by near.org.
pub const RPC_URL: &str = "https://rpc.testnet.near.org";
Expand Down Expand Up @@ -121,6 +122,16 @@ impl TopLevelAccountCreator for Testnet {
details: ExecutionFinalResult::from_view(outcome),
})
}

async fn create_tla_with_deposit(
&self,
_worker: Worker<dyn Network>,
_id: AccountId,
_sk: SecretKey,
_deposit: NearToken,
) -> Result<Execution<Account>> {
unimplemented!("Creating accounts with deposin is not supported on Testnet")
}
}

impl NetworkClient for Testnet {
Expand Down
56 changes: 41 additions & 15 deletions workspaces/src/network/variants.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
use crate::network::Info;
use crate::result::{Execution, Result};
use crate::rpc::client::Client;
use crate::types::{AccountId, KeyType, SecretKey};
use crate::{Account, Contract, Worker};
use async_trait::async_trait;
use near_token::NearToken;

use crate::{
network::Info,
result::{Execution, Result},
rpc::client::Client,
types::{AccountId, KeyType, SecretKey},
Account, Contract, Worker,
};

pub(crate) const DEV_ACCOUNT_SEED: &str = "testificate";

Expand All @@ -17,20 +21,24 @@ pub trait NetworkInfo {

#[async_trait]
pub trait TopLevelAccountCreator {
async fn create_tla(
async fn create_tla(&self, worker: Worker<dyn Network>, id: AccountId, sk: SecretKey)
-> Result<Execution<Account>>;

async fn create_tla_and_deploy(
&self,
worker: Worker<dyn Network>,
id: AccountId,
sk: SecretKey,
) -> Result<Execution<Account>>;
wasm: &[u8],
) -> Result<Execution<Contract>>;

async fn create_tla_and_deploy(
async fn create_tla_with_deposit(
&self,
worker: Worker<dyn Network>,
id: AccountId,
sk: SecretKey,
wasm: &[u8],
) -> Result<Execution<Contract>>;
deposit: NearToken,
) -> Result<Execution<Account>>;
}

// NOTE: Not all networks/runtimes will have the ability to be able to do dev_deploy.
Expand All @@ -42,9 +50,24 @@ where
T: DevNetwork + TopLevelAccountCreator + 'static,
{
pub async fn create_tla(&self, id: AccountId, sk: SecretKey) -> Result<Execution<Account>> {
let res = self.workspace.create_tla(self.clone().coerce(), id, sk).await?;

for callback in self.tx_callbacks.iter() {
callback(res.details.total_gas_burnt)?;
}

Ok(res)
}

pub async fn create_tla_with_deposit(
&self,
id: AccountId,
sk: SecretKey,
deposit: NearToken,
) -> Result<Execution<Account>> {
let res = self
.workspace
.create_tla(self.clone().coerce(), id, sk)
.create_tla_with_deposit(self.clone().coerce(), id, sk, deposit)
.await?;

for callback in self.tx_callbacks.iter() {
Expand Down Expand Up @@ -84,6 +107,12 @@ where
Ok(account.into_result()?)
}

pub async fn dev_create_account_with_deposit(&self, deposit: NearToken) -> Result<Account> {
let (id, sk) = self.dev_generate().await;
let account = self.create_tla_with_deposit(id.clone(), sk, deposit).await?;
Ok(account.into_result()?)
}

pub async fn dev_deploy(&self, wasm: &[u8]) -> Result<Contract> {
let (id, sk) = self.dev_generate().await;
let contract = self.create_tla_and_deploy(id.clone(), sk, wasm).await?;
Expand All @@ -100,7 +129,4 @@ impl<T> Network for T where T: NetworkInfo + NetworkClient + Send + Sync {}
/// DevNetwork is a Network that can call into `dev_create` and `dev_deploy` to create developer accounts.
pub trait DevNetwork: TopLevelAccountCreator + AllowDevAccountCreation + Network + 'static {}

impl<T> DevNetwork for T where
T: TopLevelAccountCreator + AllowDevAccountCreation + Network + 'static
{
}
impl<T> DevNetwork for T where T: TopLevelAccountCreator + AllowDevAccountCreation + Network + 'static {}

0 comments on commit bbfc339

Please sign in to comment.