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

chore: switch to using subaccounts & deprecate tla creation #337

Closed
wants to merge 12 commits into from
7 changes: 4 additions & 3 deletions workspaces/src/network/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,14 @@ pub mod testnet;

pub(crate) use variants::DEV_ACCOUNT_SEED;

#[allow(deprecated)]
pub use self::variants::TopLevelAccountCreator;

pub use self::betanet::Betanet;
pub use self::custom::Custom;
pub use self::info::Info;
pub use self::mainnet::Mainnet;
pub use self::sandbox::Sandbox;
pub use self::server::{pick_unused_port, ValidatorKey};
pub use self::testnet::Testnet;
pub use self::variants::{
AllowDevAccountCreation, NetworkClient, NetworkInfo, TopLevelAccountCreator,
};
pub use self::variants::{AllowDevAccountCreation, NetworkClient, NetworkInfo};
10 changes: 6 additions & 4 deletions workspaces/src/network/sandbox.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,19 +7,20 @@ use near_jsonrpc_client::methods::sandbox_patch_state::RpcSandboxPatchStateReque
use near_primitives::state_record::StateRecord;
use near_sandbox_utils as sandbox;

#[allow(deprecated)]
use super::TopLevelAccountCreator;

use super::builder::{FromNetworkBuilder, NetworkBuilder};
use super::server::ValidatorKey;
use super::{AllowDevAccountCreation, NetworkClient, NetworkInfo, TopLevelAccountCreator};
use super::{AllowDevAccountCreation, NetworkClient, NetworkInfo};
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::types::{AccountId, InMemorySigner, SecretKey, DEFAULT_DEPOSIT};
use crate::{Account, Contract, Network, Worker};

// Constant taken from nearcore crate to avoid dependency
const DEFAULT_DEPOSIT: NearToken = NearToken::from_near(100);
/// Local sandboxed environment/network, which can be used to test without interacting with
/// networks that are online such as mainnet and testnet. Look at [`workspaces::sandbox`]
/// for how to spin up a sandboxed network and interact with it.
Expand Down Expand Up @@ -118,6 +119,7 @@ impl FromNetworkBuilder for Sandbox {

impl AllowDevAccountCreation for Sandbox {}

#[allow(deprecated)]
#[async_trait]
impl TopLevelAccountCreator for Sandbox {
async fn create_tla(
Expand Down
6 changes: 5 additions & 1 deletion workspaces/src/network/testnet.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,12 @@ use url::Url;

use near_primitives::views::ExecutionStatusView;

#[allow(deprecated)]
use crate::network::TopLevelAccountCreator;

use crate::network::builder::{FromNetworkBuilder, NetworkBuilder};
use crate::network::Info;
use crate::network::{AllowDevAccountCreation, NetworkClient, NetworkInfo, TopLevelAccountCreator};
use crate::network::{AllowDevAccountCreation, NetworkClient, NetworkInfo};
use crate::result::{Execution, ExecutionDetails, ExecutionFinalResult, ExecutionOutcome, Result};
use crate::rpc::{client::Client, tool};
use crate::types::{AccountId, InMemorySigner, NearToken, SecretKey};
Expand Down Expand Up @@ -66,6 +69,7 @@ impl std::fmt::Debug for Testnet {

impl AllowDevAccountCreation for Testnet {}

#[allow(deprecated)]
#[async_trait]
impl TopLevelAccountCreator for Testnet {
async fn create_tla(
Expand Down
8 changes: 6 additions & 2 deletions workspaces/src/network/variants.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ pub trait NetworkInfo {
fn info(&self) -> &Info;
}

#[deprecated = "only the registrar can create top level accounts as of Protocol >=64"]
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Top-level accounts creation is not deprecated, so I am not completely convinced that we should mark this trait as deprecated

Copy link
Author

@ghost ghost Nov 29, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I added that as an attempt to discourage usage maybe we use warn?

#[async_trait]
pub trait TopLevelAccountCreator {
async fn create_tla(
Expand All @@ -37,9 +38,10 @@ pub trait TopLevelAccountCreator {
// This trait acts as segmented boundary for only specific networks such as sandbox and testnet.
pub trait AllowDevAccountCreation {}

#[allow(deprecated)]
impl<T> Worker<T>
where
T: DevNetwork + TopLevelAccountCreator + 'static,
T: DevNetwork + TopLevelAccountCreator + 'static + NetworkInfo,
{
pub async fn create_tla(&self, id: AccountId, sk: SecretKey) -> Result<Execution<Account>> {
let res = self
Expand Down Expand Up @@ -73,7 +75,7 @@ where
}

pub async fn dev_generate(&self) -> (AccountId, SecretKey) {
let id = crate::rpc::tool::random_account_id();
let id = crate::rpc::tool::random_account_id(self.info().root_id.clone());
let sk = SecretKey::from_seed(KeyType::ED25519, DEV_ACCOUNT_SEED);
(id, sk)
}
Expand All @@ -98,8 +100,10 @@ pub trait Network: NetworkInfo + NetworkClient + Send + Sync {}
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.
#[allow(deprecated)]
pub trait DevNetwork: TopLevelAccountCreator + AllowDevAccountCreation + Network + 'static {}

#[allow(deprecated)]
impl<T> DevNetwork for T where
T: TopLevelAccountCreator + AllowDevAccountCreation + Network + 'static
{
Expand Down
3 changes: 2 additions & 1 deletion workspaces/src/operations.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ use crate::rpc::client::{
use crate::rpc::query::{Query, ViewFunction};
use crate::types::{
AccessKey, AccountId, Gas, InMemorySigner, KeyType, NearToken, PublicKey, SecretKey,
DEFAULT_DEPOSIT,
};
use crate::worker::Worker;
use crate::{Account, CryptoHash, Network};
Expand Down Expand Up @@ -435,7 +436,7 @@ impl<'a, 'b> CreateAccountTransaction<'a, 'b> {
signer,
parent_id,
new_account_id,
initial_balance: NearToken::from_yoctonear(100000000000000000000000u128),
initial_balance: DEFAULT_DEPOSIT,
secret_key: None,
}
}
Expand Down
1 change: 1 addition & 0 deletions workspaces/src/prelude.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
//! All traits that are essential to the ease of use of workspaces.

#[allow(deprecated)]
pub use crate::network::TopLevelAccountCreator;
9 changes: 7 additions & 2 deletions workspaces/src/rpc/tool.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,15 @@ pub(crate) fn into_state_map(state_items: Vec<StateItem>) -> HashMap<Vec<u8>, Ve
.collect()
}

pub(crate) fn random_account_id() -> AccountId {
pub(crate) fn random_account_id(parent_id: AccountId) -> AccountId {
let mut rng = rand::thread_rng();
let random_num = rng.gen_range(10000000000000usize..99999999999999);
let account_id = format!("dev-{}-{}", Utc::now().format("%Y%m%d%H%M%S"), random_num);
let account_id = format!(
"dev-{}-{}.{}",
Utc::now().format("%Y%m%d%H%M%S"),
random_num,
parent_id
);
let account_id: AccountId = account_id
.try_into()
.expect("could not convert dev account into AccountId");
Expand Down
3 changes: 3 additions & 0 deletions workspaces/src/types/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,9 @@ pub type BlockHeight = u64;
/// Shard index, from 0 to NUM_SHARDS - 1.
pub type ShardId = u64;

// Constant taken from nearcore crate to avoid dependency
pub const DEFAULT_DEPOSIT: NearToken = NearToken::from_near(100);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is no sense in such a public constant. There is no such a thing like "default deposit" in NEAR protocol.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I moved this over to types crate:

const DEFAULT_DEPOSIT: NearToken = NearToken::from_near(100);

Copy link
Author

@ghost ghost Jan 3, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is no sense in such a public constant. There is no such a thing like "default deposit" in NEAR protocol.

Updated the docs and renamed the constant to reflect that. 9abfd8b


fn from_base58(s: &str) -> Result<Vec<u8>, Box<dyn std::error::Error + Send + Sync>> {
bs58::decode(s).into_vec().map_err(|err| err.into())
}
Expand Down
2 changes: 1 addition & 1 deletion workspaces/tests/account.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ use std::path::Path;
#[test(tokio::test)]
async fn test_subaccount_creation() -> anyhow::Result<()> {
let worker = near_workspaces::sandbox().await?;
let account = worker.dev_create_account().await?;
let account = worker.root_account()?;

let sub = account
.create_subaccount("subaccount")
Expand Down
35 changes: 20 additions & 15 deletions workspaces/tests/cross_contract.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,25 +29,29 @@ async fn test_cross_contract_create_contract() -> anyhow::Result<()> {
let contract = worker.dev_deploy(FACTORY_CONTRACT).await?;
let status_amt = NearToken::from_near(35);

// Expect to fail for trying to create a new contract account with too short of a
// top level account name, such as purely just "status"
let status_id: AccountId = "status".parse().unwrap();
let outcome = cross_contract_create_contract(&status_id, &status_amt, &contract).await?;
let failures = outcome.failures();
assert!(
failures.len() == 1,
"Expected one receipt failure for creating too short of a TLA, but got {} failures",
failures.len()
);
#[cfg(feature = "experimental")]
if let Ok(conf) = worker.genesis_config().await {
if conf.protocol_version >= 64 {
// Expect the creation of a top level account to fail.
let status_id: AccountId = "status-top-level-account-long-name".parse().unwrap();
let outcome =
cross_contract_create_contract(&status_id, &status_amt, &contract).await?;
let failures = outcome.failures();
assert!(
failures.len() == 1,
"Expected one receipt failure for creating a top level account, but got {} failures",
failures.len()
);
}
}

// Expect to succeed after calling into the contract with expected length for a
// top level account.
let status_id: AccountId = "status-top-level-account-long-name".parse().unwrap();
// Expect the creation of a subaccount like "status.{contract_id}" to pass.
let status_id: AccountId = format!("status.{}", contract.id()).parse().unwrap();
let outcome = cross_contract_create_contract(&status_id, &status_amt, &contract).await?;
let failures = outcome.failures();
assert!(
failures.is_empty(),
"Expected no failures for creating a TLA, but got {} failures",
"Expected no failures for creating a subaccount, but got {} failures",
failures.len(),
);

Expand All @@ -60,7 +64,8 @@ async fn test_cross_contract_calls() -> anyhow::Result<()> {
let contract = worker.dev_deploy(FACTORY_CONTRACT).await?;
let status_amt = NearToken::from_near(35);

let status_id: AccountId = "status-top-level-account-long-name".parse().unwrap();
// "status.{contract_id}" is the account that will be created by the factory contract.
let status_id: AccountId = format!("status.{}", contract.id()).parse().unwrap();
cross_contract_create_contract(&status_id, &status_amt, &contract)
.await?
.into_result()?;
Expand Down
Loading
Loading