Skip to content

Commit

Permalink
introduce a sandbox-multi feature that controls which sandbox strateg…
Browse files Browse the repository at this point in the history
…y is used
  • Loading branch information
itegulov committed Feb 9, 2022
1 parent 8262636 commit 70e76e3
Show file tree
Hide file tree
Showing 8 changed files with 171 additions and 97 deletions.
3 changes: 3 additions & 0 deletions workspaces/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -45,3 +45,6 @@ libc = "0.2"
borsh = "0.9"
test-log = { version = "0.2.8", default-features = false, features = ["trace"] }
tracing-subscriber = { version = "0.3.5", features = ["env-filter"] }

[features]
sandbox-multi = []
3 changes: 1 addition & 2 deletions workspaces/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,5 @@ pub mod prelude;
pub use network::{Account, Contract, DevNetwork, Network};
pub use types::{AccountId, BlockHeight, CryptoHash, InMemorySigner};
pub use worker::{
mainnet, mainnet_archival, sandbox, sandbox_shared, testnet, with_mainnet, with_sandbox,
with_testnet, Worker,
mainnet, mainnet_archival, sandbox, testnet, with_mainnet, with_sandbox, with_testnet, Worker,
};
9 changes: 8 additions & 1 deletion workspaces/src/network/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@ mod info;
mod mainnet;
mod result;
mod sandbox;
#[cfg(feature = "sandbox-multi")]
mod sandbox_multi;
#[cfg(not(feature = "sandbox-multi"))]
mod sandbox_shared;
mod server;
mod testnet;
Expand All @@ -13,6 +16,11 @@ use near_jsonrpc_client::methods::sandbox_patch_state::RpcSandboxPatchStateReque
use near_primitives::state_record::StateRecord;

pub(crate) use crate::network::info::Info;
pub(crate) use crate::network::sandbox::HasRpcPort;
#[cfg(feature = "sandbox-multi")]
pub(crate) use crate::network::sandbox_multi::SandboxMulti;
#[cfg(not(feature = "sandbox-multi"))]
pub(crate) use crate::network::sandbox_shared::SandboxShared;
use crate::rpc::client::Client;
use crate::rpc::patch::ImportContractBuilder;
use crate::types::{AccountId, KeyType, SecretKey};
Expand All @@ -22,7 +30,6 @@ pub use crate::network::account::{Account, Contract};
pub use crate::network::mainnet::Mainnet;
pub use crate::network::result::{CallExecution, CallExecutionDetails, ViewResultDetails};
pub use crate::network::sandbox::Sandbox;
pub use crate::network::sandbox_shared::SandboxShared;
pub use crate::network::testnet::Testnet;

pub(crate) const DEV_ACCOUNT_SEED: &str = "testificate";
Expand Down
92 changes: 31 additions & 61 deletions workspaces/src/network/sandbox.rs
Original file line number Diff line number Diff line change
@@ -1,28 +1,23 @@
use std::path::PathBuf;
use std::str::FromStr;

use async_trait::async_trait;

use super::{
Account, AllowDevAccountCreation, AllowStatePatching, CallExecution, Contract, NetworkClient,
NetworkInfo, TopLevelAccountCreator,
};

use crate::network::server::SandboxServer;
use crate::network::Info;
use crate::rpc::client::Client;
use crate::types::{AccountId, Balance, InMemorySigner, SecretKey};
use async_trait::async_trait;
use std::path::PathBuf;

// Constant taken from nearcore crate to avoid dependency
pub(crate) const NEAR_BASE: Balance = 1_000_000_000_000_000_000_000_000;

const DEFAULT_DEPOSIT: Balance = 100 * NEAR_BASE;
pub(crate) const DEFAULT_DEPOSIT: Balance = 100 * NEAR_BASE;

pub struct Sandbox {
server: SandboxServer,
client: Client,
info: Info,
}
#[cfg(not(feature = "sandbox-multi"))]
pub struct Sandbox(crate::network::SandboxShared);

#[cfg(feature = "sandbox-multi")]
pub struct Sandbox(crate::network::SandboxMulti);

impl Sandbox {
pub(crate) fn home_dir(port: u16) -> PathBuf {
Expand All @@ -31,30 +26,21 @@ impl Sandbox {
path
}

pub(crate) fn root_signer(&self) -> InMemorySigner {
let mut path = Self::home_dir(self.server.rpc_port);
pub(crate) fn root_signer(port: u16) -> InMemorySigner {
let mut path = Self::home_dir(port);
path.push("validator_key.json");

InMemorySigner::from_file(&path)
}

#[cfg(not(feature = "sandbox-multi"))]
pub(crate) fn new() -> Self {
let mut server = SandboxServer::default();
server.start().unwrap();

let client = Client::new(server.rpc_addr());
let info = Info {
name: "sandbox".to_string(),
root_id: AccountId::from_str("test.near").unwrap(),
keystore_path: PathBuf::from(".near-credentials/sandbox/"),
rpc_url: server.rpc_addr(),
};

Self {
server,
client,
info,
}
Self(crate::network::SandboxShared::new())
}

#[cfg(feature = "sandbox-multi")]
pub(crate) fn new() -> Self {
Self(crate::network::SandboxMulti::new())
}
}

Expand All @@ -69,17 +55,7 @@ impl TopLevelAccountCreator for Sandbox {
id: AccountId,
sk: SecretKey,
) -> anyhow::Result<CallExecution<Account>> {
let root_signer = self.root_signer();
let outcome = self
.client
.create_account(&root_signer, &id, sk.public_key(), DEFAULT_DEPOSIT)
.await?;

let signer = InMemorySigner::from_secret_key(id.clone(), sk);
Ok(CallExecution {
result: Account::new(id, signer),
details: outcome.into(),
})
self.0.create_tla(id, sk).await
}

async fn create_tla_and_deploy(
Expand All @@ -88,34 +64,28 @@ impl TopLevelAccountCreator for Sandbox {
sk: SecretKey,
wasm: &[u8],
) -> anyhow::Result<CallExecution<Contract>> {
let root_signer = self.root_signer();
let outcome = self
.client
.create_account_and_deploy(
&root_signer,
&id,
sk.public_key(),
DEFAULT_DEPOSIT,
wasm.into(),
)
.await?;

let signer = InMemorySigner::from_secret_key(id.clone(), sk);
Ok(CallExecution {
result: Contract::new(id, signer),
details: outcome.into(),
})
self.0.create_tla_and_deploy(id, sk, wasm).await
}
}

impl NetworkClient for Sandbox {
fn client(&self) -> &Client {
&self.client
&self.0.client()
}
}

impl NetworkInfo for Sandbox {
fn info(&self) -> &Info {
&self.info
&self.0.info()
}
}

pub(crate) trait HasRpcPort {
fn rpc_port(&self) -> u16;
}

impl HasRpcPort for Sandbox {
fn rpc_port(&self) -> u16 {
self.0.rpc_port()
}
}
110 changes: 110 additions & 0 deletions workspaces/src/network/sandbox_multi.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
use std::path::PathBuf;
use std::str::FromStr;

use async_trait::async_trait;

use super::{
Account, AllowDevAccountCreation, AllowStatePatching, CallExecution, Contract, NetworkClient,
NetworkInfo, TopLevelAccountCreator,
};

use crate::network::sandbox::{HasRpcPort, DEFAULT_DEPOSIT};
use crate::network::server::SandboxServer;
use crate::network::{Info, Sandbox};
use crate::rpc::client::Client;
use crate::types::{AccountId, InMemorySigner, SecretKey};

pub struct SandboxMulti {
server: SandboxServer,
client: Client,
info: Info,
}

impl SandboxMulti {
pub(crate) fn new() -> Self {
let mut server = SandboxServer::default();
server.start().unwrap();

let client = Client::new(server.rpc_addr());
let info = Info {
name: "sandbox".to_string(),
root_id: AccountId::from_str("test.near").unwrap(),
keystore_path: PathBuf::from(".near-credentials/sandbox/"),
rpc_url: server.rpc_addr(),
};

Self {
server,
client,
info,
}
}
}

impl AllowStatePatching for SandboxMulti {}

impl AllowDevAccountCreation for SandboxMulti {}

#[async_trait]
impl TopLevelAccountCreator for SandboxMulti {
async fn create_tla(
&self,
id: AccountId,
sk: SecretKey,
) -> anyhow::Result<CallExecution<Account>> {
let root_signer = Sandbox::root_signer(self.rpc_port());
let outcome = self
.client
.create_account(&root_signer, &id, sk.public_key(), DEFAULT_DEPOSIT)
.await?;

let signer = InMemorySigner::from_secret_key(id.clone(), sk);
Ok(CallExecution {
result: Account::new(id, signer),
details: outcome.into(),
})
}

async fn create_tla_and_deploy(
&self,
id: AccountId,
sk: SecretKey,
wasm: &[u8],
) -> anyhow::Result<CallExecution<Contract>> {
let root_signer = Sandbox::root_signer(self.rpc_port());
let outcome = self
.client
.create_account_and_deploy(
&root_signer,
&id,
sk.public_key(),
DEFAULT_DEPOSIT,
wasm.into(),
)
.await?;

let signer = InMemorySigner::from_secret_key(id.clone(), sk);
Ok(CallExecution {
result: Contract::new(id, signer),
details: outcome.into(),
})
}
}

impl NetworkClient for SandboxMulti {
fn client(&self) -> &Client {
&self.client
}
}

impl NetworkInfo for SandboxMulti {
fn info(&self) -> &Info {
&self.info
}
}

impl HasRpcPort for SandboxMulti {
fn rpc_port(&self) -> u16 {
self.server.rpc_port
}
}
31 changes: 11 additions & 20 deletions workspaces/src/network/sandbox_shared.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@ use super::{
Account, AllowDevAccountCreation, AllowStatePatching, CallExecution, Contract, NetworkClient,
NetworkInfo, TopLevelAccountCreator,
};
use crate::network::sandbox::NEAR_BASE;
use crate::network::sandbox::{HasRpcPort, DEFAULT_DEPOSIT};
use crate::network::server::SandboxServer;
use crate::network::Info;
use crate::network::{Info, Sandbox};
use crate::rpc::client::Client;
use crate::types::{AccountId, Balance, InMemorySigner, SecretKey};
use crate::types::{AccountId, InMemorySigner, SecretKey};
use async_mutex::Mutex;
use async_trait::async_trait;
use once_cell::sync::Lazy;
Expand All @@ -24,27 +24,12 @@ static SHARED_SERVER: Lazy<SandboxServer> = Lazy::new(|| {
// order to avoid duplicated nonces.
static TLA_ACCOUNT_MUTEX: Lazy<Mutex<()>> = Lazy::new(|| Mutex::new(()));

const DEFAULT_DEPOSIT: Balance = 100 * NEAR_BASE;

pub struct SandboxShared {
client: Client,
info: Info,
}

impl SandboxShared {
pub(crate) fn home_dir(port: u16) -> PathBuf {
let mut path = std::env::temp_dir();
path.push(format!("sandbox-{}", port));
path
}

pub(crate) fn root_signer(&self) -> InMemorySigner {
let mut path = Self::home_dir(SHARED_SERVER.rpc_port);
path.push("validator_key.json");

InMemorySigner::from_file(&path)
}

pub(crate) fn new() -> Self {
let client = Client::new(SHARED_SERVER.rpc_addr());
let info = Info {
Expand All @@ -69,7 +54,7 @@ impl TopLevelAccountCreator for SandboxShared {
id: AccountId,
sk: SecretKey,
) -> anyhow::Result<CallExecution<Account>> {
let root_signer = self.root_signer();
let root_signer = Sandbox::root_signer(self.rpc_port());
let guard = TLA_ACCOUNT_MUTEX.lock().await;
let outcome = self
.client
Expand All @@ -90,7 +75,7 @@ impl TopLevelAccountCreator for SandboxShared {
sk: SecretKey,
wasm: &[u8],
) -> anyhow::Result<CallExecution<Contract>> {
let root_signer = self.root_signer();
let root_signer = Sandbox::root_signer(self.rpc_port());
let guard = TLA_ACCOUNT_MUTEX.lock().await;
let outcome = self
.client
Expand Down Expand Up @@ -123,3 +108,9 @@ impl NetworkInfo for SandboxShared {
&self.info
}
}

impl HasRpcPort for SandboxShared {
fn rpc_port(&self) -> u16 {
SHARED_SERVER.rpc_port
}
}
Loading

0 comments on commit 70e76e3

Please sign in to comment.