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

feat(zk_toolbox): Minting base token #2571

Merged
merged 5 commits into from
Aug 13, 2024
Merged
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
28 changes: 0 additions & 28 deletions core/tests/ts-integration/src/env.ts
Original file line number Diff line number Diff line change
@@ -97,7 +97,6 @@ async function loadTestEnvironmentFromFile(chain: string): Promise<TestEnvironme
token = Object.values(tokens.tokens)[1];
}
}
const weth = tokens.tokens['WETH'];
let baseToken;

for (const key in tokens.tokens) {
@@ -114,12 +113,6 @@ async function loadTestEnvironmentFromFile(chain: string): Promise<TestEnvironme
ethers.getDefaultProvider(l1NodeUrl)
).l2TokenAddress(token.address);

const l2WethAddress = await new zksync.Wallet(
mainWalletPK,
l2Provider,
ethers.getDefaultProvider(l1NodeUrl)
).l2TokenAddress(weth.address);

const baseTokenAddressL2 = L2_BASE_TOKEN_ADDRESS;
const l2ChainId = BigInt(genesisConfig.l2_chain_id);
const l1BatchCommitDataGeneratorMode = genesisConfig.l1_batch_commit_data_generator_mode as DataAvailabityMode;
@@ -152,13 +145,6 @@ async function loadTestEnvironmentFromFile(chain: string): Promise<TestEnvironme
l1Address: token.address,
l2Address: l2TokenAddress
},
wethToken: {
name: weth.name,
symbol: weth.symbol,
decimals: weth.decimals,
l1Address: weth.address,
l2Address: l2WethAddress
},
baseToken: {
name: baseToken?.name || token.name,
symbol: baseToken?.symbol || token.symbol,
@@ -213,7 +199,6 @@ export async function loadTestEnvironmentFromEnv(): Promise<TestEnvironment> {
if (!token) {
token = tokens[0];
}
const weth = tokens.find((token: { symbol: string }) => token.symbol == 'WETH')!;
const baseToken = tokens.find((token: { address: string }) =>
zksync.utils.isAddressEq(token.address, baseTokenAddress)
)!;
@@ -225,12 +210,6 @@ export async function loadTestEnvironmentFromEnv(): Promise<TestEnvironment> {
ethers.getDefaultProvider(l1NodeUrl)
).l2TokenAddress(token.address);

const l2WethAddress = await new zksync.Wallet(
mainWalletPK,
l2Provider,
ethers.getDefaultProvider(l1NodeUrl)
).l2TokenAddress(weth.address);

const baseTokenAddressL2 = L2_BASE_TOKEN_ADDRESS;
const l2ChainId = BigInt(process.env.CHAIN_ETH_ZKSYNC_NETWORK_ID!);
// If the `CHAIN_STATE_KEEPER_L1_BATCH_COMMIT_DATA_GENERATOR_MODE` is not set, the default value is `Rollup`.
@@ -280,13 +259,6 @@ export async function loadTestEnvironmentFromEnv(): Promise<TestEnvironment> {
l1Address: token.address,
l2Address: l2TokenAddress
},
wethToken: {
name: weth.name,
symbol: weth.symbol,
decimals: weth.decimals,
l1Address: weth.address,
l2Address: l2WethAddress
},
baseToken: {
name: baseToken?.name || token.name,
symbol: baseToken?.symbol || token.symbol,
4 changes: 0 additions & 4 deletions core/tests/ts-integration/src/types.ts
Original file line number Diff line number Diff line change
@@ -85,10 +85,6 @@ export interface TestEnvironment {
* Description of the "main" ERC20 token used in the tests.
*/
erc20Token: Token;
/**
* Description of the WETH token used in the tests.
*/
wethToken: Token;
/**
* Description of the "base" ERC20 token used in the tests.
*/
40 changes: 39 additions & 1 deletion zk_toolbox/crates/common/src/ethereum.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use std::{ops::Add, time::Duration};
use std::{ops::Add, sync::Arc, time::Duration};

use ethers::{
contract::abigen,
core::k256::ecdsa::SigningKey,
middleware::MiddlewareBuilder,
prelude::{Http, LocalWallet, Provider, Signer, SignerMiddleware},
@@ -53,3 +54,40 @@ pub async fn distribute_eth(
futures::future::join_all(pending_txs).await;
Ok(())
}

abigen!(
TokenContract,
r"[
function mint(address to, uint256 amount)
]"
);

pub async fn mint_token(
main_wallet: Wallet,
token_address: Address,
addresses: Vec<Address>,
l1_rpc: String,
chain_id: u64,
amount: u128,
) -> anyhow::Result<()> {
let client = Arc::new(create_ethers_client(
main_wallet.private_key.unwrap(),
l1_rpc,
Some(chain_id),
)?);

let contract = TokenContract::new(token_address, client);
// contract
for address in addresses {
contract
.mint(address, amount.into())
.send()
.await?
// It's safe to set such low number of confirmations and low interval for localhost
.confirmations(1)
.interval(Duration::from_millis(30))
.await?;
}

Ok(())
}
14 changes: 11 additions & 3 deletions zk_toolbox/crates/config/src/ecosystem.rs
Original file line number Diff line number Diff line change
@@ -13,11 +13,14 @@ use zksync_basic_types::L2ChainId;
use crate::{
consts::{
CONFIGS_PATH, CONFIG_NAME, CONTRACTS_FILE, ECOSYSTEM_PATH, ERA_CHAIN_ID,
ERC20_DEPLOYMENT_FILE, INITIAL_DEPLOYMENT_FILE, L1_CONTRACTS_FOUNDRY, LOCAL_DB_PATH,
WALLETS_FILE,
ERC20_CONFIGS_FILE, ERC20_DEPLOYMENT_FILE, INITIAL_DEPLOYMENT_FILE, L1_CONTRACTS_FOUNDRY,
LOCAL_DB_PATH, WALLETS_FILE,
},
create_localhost_wallets,
forge_interface::deploy_ecosystem::input::{Erc20DeploymentConfig, InitialDeploymentConfig},
forge_interface::deploy_ecosystem::{
input::{Erc20DeploymentConfig, InitialDeploymentConfig},
output::{ERC20Tokens, Erc20Token},
},
traits::{FileConfigWithDefaultName, ReadConfig, SaveConfig, ZkToolboxConfig},
ChainConfig, ChainConfigInternal, ContractsConfig, WalletsConfig,
};
@@ -169,6 +172,11 @@ impl EcosystemConfig {
pub fn get_erc20_deployment_config(&self) -> anyhow::Result<Erc20DeploymentConfig> {
Erc20DeploymentConfig::read(self.get_shell(), self.config.join(ERC20_DEPLOYMENT_FILE))
}
pub fn get_erc20_tokens(&self) -> Vec<Erc20Token> {
ERC20Tokens::read(self.get_shell(), self.config.join(ERC20_CONFIGS_FILE))
.map(|tokens| tokens.tokens.values().cloned().collect())
.unwrap_or_default()
}

pub fn get_wallets(&self) -> anyhow::Result<WalletsConfig> {
let path = self.config.join(WALLETS_FILE);
Original file line number Diff line number Diff line change
@@ -92,13 +92,6 @@ impl Default for Erc20DeploymentConfig {
implementation: String::from("TestnetERC20Token.sol"),
mint: U256::from_str("9000000000000000000000").unwrap(),
},
Erc20DeploymentTokensConfig {
name: String::from("Wrapped Ether"),
symbol: String::from("WETH"),
decimals: 18,
implementation: String::from("WETH9.sol"),
mint: U256::zero(),
},
],
}
}
Original file line number Diff line number Diff line change
@@ -79,7 +79,7 @@ pub struct L1StateTransitionOutput {
}

#[derive(Debug, Deserialize, Serialize, Clone)]
pub struct TokenDeployErc20Output {
pub struct Erc20Token {
pub address: Address,
pub name: String,
pub symbol: String,
@@ -89,12 +89,12 @@ pub struct TokenDeployErc20Output {
}

#[derive(Debug, Deserialize, Serialize, Clone)]
pub struct DeployErc20Output {
pub tokens: HashMap<String, TokenDeployErc20Output>,
pub struct ERC20Tokens {
pub tokens: HashMap<String, Erc20Token>,
}

impl FileConfigWithDefaultName for DeployErc20Output {
impl FileConfigWithDefaultName for ERC20Tokens {
const FILE_NAME: &'static str = ERC20_CONFIGS_FILE;
}

impl ZkToolboxConfig for DeployErc20Output {}
impl ZkToolboxConfig for ERC20Tokens {}
6 changes: 6 additions & 0 deletions zk_toolbox/crates/config/src/general.rs
Original file line number Diff line number Diff line change
@@ -14,6 +14,7 @@ use crate::{
pub struct RocksDbs {
pub state_keeper: PathBuf,
pub merkle_tree: PathBuf,
pub protective_reads: PathBuf,
}

pub fn set_rocks_db_config(config: &mut GeneralConfig, rocks_dbs: RocksDbs) -> anyhow::Result<()> {
@@ -28,6 +29,11 @@ pub fn set_rocks_db_config(config: &mut GeneralConfig, rocks_dbs: RocksDbs) -> a
.context("DB config is not presented")?
.merkle_tree
.path = rocks_dbs.merkle_tree.to_str().unwrap().to_string();
config
.protective_reads_writer_config
.as_mut()
.context("Protective reads config is not presented")?
.db_path = rocks_dbs.protective_reads.to_str().unwrap().to_string();
Ok(())
}

2 changes: 1 addition & 1 deletion zk_toolbox/crates/types/src/base_token.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use ethers::types::Address;
use serde::{Deserialize, Serialize};

#[derive(Debug, Serialize, Deserialize, Clone)]
#[derive(Debug, Serialize, Deserialize, Clone, PartialEq)]
pub struct BaseToken {
pub address: Address,
pub nominator: u64,
26 changes: 19 additions & 7 deletions zk_toolbox/crates/zk_inception/src/commands/chain/args/create.rs
Original file line number Diff line number Diff line change
@@ -3,6 +3,7 @@ use std::{path::PathBuf, str::FromStr};
use anyhow::{bail, Context};
use clap::{Parser, ValueEnum};
use common::{Prompt, PromptConfirm, PromptSelect};
use config::forge_interface::deploy_ecosystem::output::Erc20Token;
use serde::{Deserialize, Serialize};
use slugify_rs::slugify;
use strum::{Display, EnumIter, IntoEnumIterator};
@@ -71,6 +72,7 @@ impl ChainCreateArgs {
self,
number_of_chains: u32,
l1_network: &L1Network,
possible_erc20: Vec<Erc20Token>,
) -> anyhow::Result<ChainCreateArgsFinal> {
let mut chain_name = self
.chain_name
@@ -151,14 +153,24 @@ impl ChainCreateArgs {
&& self.base_token_price_denominator.is_none()
&& self.base_token_price_nominator.is_none()
{
let base_token_selection =
PromptSelect::new(MSG_BASE_TOKEN_SELECTION_PROMPT, BaseTokenSelection::iter())
.ask();
let mut token_selection: Vec<_> =
BaseTokenSelection::iter().map(|a| a.to_string()).collect();

match base_token_selection {
BaseTokenSelection::Eth => BaseToken::eth(),
BaseTokenSelection::Custom => {
let address = Prompt::new(MSG_BASE_TOKEN_ADDRESS_PROMPT).ask();
let erc20_tokens = &mut (possible_erc20
.iter()
.map(|t| format!("{:?}", t.address))
.collect());
token_selection.append(erc20_tokens);
let base_token_selection =
PromptSelect::new(MSG_BASE_TOKEN_SELECTION_PROMPT, token_selection).ask();
match base_token_selection.as_str() {
"Eth" => BaseToken::eth(),
other => {
let address = if other == "Custom" {
Prompt::new(MSG_BASE_TOKEN_ADDRESS_PROMPT).ask()
} else {
H160::from_str(other)?
};
let nominator = Prompt::new(MSG_BASE_TOKEN_PRICE_NOMINATOR_PROMPT)
.validate_with(number_validator)
.ask();
2 changes: 2 additions & 0 deletions zk_toolbox/crates/zk_inception/src/commands/chain/create.rs
Original file line number Diff line number Diff line change
@@ -27,10 +27,12 @@ fn create(
ecosystem_config: &mut EcosystemConfig,
shell: &Shell,
) -> anyhow::Result<()> {
let tokens = ecosystem_config.get_erc20_tokens();
let args = args
.fill_values_with_prompt(
ecosystem_config.list_of_chains().len() as u32,
&ecosystem_config.l1_network,
tokens,
)
.context(MSG_ARGS_VALIDATOR_ERR)?;

78 changes: 70 additions & 8 deletions zk_toolbox/crates/zk_inception/src/commands/chain/init.rs
Original file line number Diff line number Diff line change
@@ -15,6 +15,7 @@ use config::{
traits::{ReadConfig, SaveConfig, SaveConfigWithBasePath},
update_from_chain_config, ChainConfig, ContractsConfig, EcosystemConfig,
};
use types::{BaseToken, L1Network, WalletCreation};
use xshell::Shell;

use crate::{
@@ -24,10 +25,11 @@ use crate::{
deploy_l2_contracts, deploy_paymaster,
genesis::genesis,
},
consts::AMOUNT_FOR_DISTRIBUTION_TO_WALLETS,
messages::{
msg_initializing_chain, MSG_ACCEPTING_ADMIN_SPINNER, MSG_CHAIN_INITIALIZED,
MSG_CHAIN_NOT_FOUND_ERR, MSG_GENESIS_DATABASE_ERR, MSG_REGISTERING_CHAIN_SPINNER,
MSG_SELECTED_CONFIG,
MSG_CHAIN_NOT_FOUND_ERR, MSG_DISTRIBUTING_ETH_SPINNER, MSG_GENESIS_DATABASE_ERR,
MSG_MINT_BASE_TOKEN_SPINNER, MSG_REGISTERING_CHAIN_SPINNER, MSG_SELECTED_CONFIG,
},
utils::forge::{check_the_balance, fill_forge_private_key},
};
@@ -67,12 +69,9 @@ pub async fn init(
contracts_config.l1.base_token_addr = chain_config.base_token.address;
contracts_config.save_with_base_path(shell, &chain_config.configs)?;

crate::commands::ecosystem::init::distribute_eth(
ecosystem_config,
chain_config,
init_args.l1_rpc_url.clone(),
)
.await?;
distribute_eth(ecosystem_config, chain_config, init_args.l1_rpc_url.clone()).await?;
mint_base_token(ecosystem_config, chain_config, init_args.l1_rpc_url.clone()).await?;

let mut secrets = chain_config.get_secrets_config()?;
set_l1_rpc_url(&mut secrets, init_args.l1_rpc_url.clone())?;
secrets.save_with_base_path(shell, &chain_config.configs)?;
@@ -160,3 +159,66 @@ async fn register_chain(
contracts.set_chain_contracts(&register_chain_output);
Ok(())
}

// Distribute eth to the chain wallets for localhost environment
pub async fn distribute_eth(
ecosystem_config: &EcosystemConfig,
chain_config: &ChainConfig,
l1_rpc_url: String,
) -> anyhow::Result<()> {
if chain_config.wallet_creation == WalletCreation::Localhost
&& ecosystem_config.l1_network == L1Network::Localhost
{
let spinner = Spinner::new(MSG_DISTRIBUTING_ETH_SPINNER);
let wallets = ecosystem_config.get_wallets()?;
let chain_wallets = chain_config.get_wallets_config()?;
let mut addresses = vec![
chain_wallets.operator.address,
chain_wallets.blob_operator.address,
chain_wallets.governor.address,
];
if let Some(deployer) = chain_wallets.deployer {
addresses.push(deployer.address)
}
common::ethereum::distribute_eth(
wallets.operator,
addresses,
l1_rpc_url,
ecosystem_config.l1_network.chain_id(),
AMOUNT_FOR_DISTRIBUTION_TO_WALLETS,
)
.await?;
spinner.finish();
}
Ok(())
}

pub async fn mint_base_token(
ecosystem_config: &EcosystemConfig,
chain_config: &ChainConfig,
l1_rpc_url: String,
) -> anyhow::Result<()> {
if chain_config.wallet_creation == WalletCreation::Localhost
&& ecosystem_config.l1_network == L1Network::Localhost
&& chain_config.base_token != BaseToken::eth()
{
let spinner = Spinner::new(MSG_MINT_BASE_TOKEN_SPINNER);
let wallets = ecosystem_config.get_wallets()?;
let chain_wallets = chain_config.get_wallets_config()?;
let base_token = &chain_config.base_token;
let addresses = vec![wallets.governor.address, chain_wallets.governor.address];
let amount = AMOUNT_FOR_DISTRIBUTION_TO_WALLETS * base_token.nominator as u128
/ base_token.denominator as u128;
common::ethereum::mint_token(
wallets.operator,
base_token.address,
addresses,
l1_rpc_url,
ecosystem_config.l1_network.chain_id(),
amount,
)
.await?;
spinner.finish();
}
Ok(())
}
Original file line number Diff line number Diff line change
@@ -71,7 +71,7 @@ impl EcosystemCreateArgs {
// Make the only chain as a default one
self.chain.set_as_default = Some(true);

let chain = self.chain.fill_values_with_prompt(0, &l1_network)?;
let chain = self.chain.fill_values_with_prompt(0, &l1_network, vec![])?;

let start_containers = self.start_containers.unwrap_or_else(|| {
PromptConfirm::new(MSG_START_CONTAINERS_PROMPT)
50 changes: 8 additions & 42 deletions zk_toolbox/crates/zk_inception/src/commands/ecosystem/init.rs
Original file line number Diff line number Diff line change
@@ -18,17 +18,17 @@ use config::{
input::{
DeployErc20Config, DeployL1Config, Erc20DeploymentConfig, InitialDeploymentConfig,
},
output::{DeployErc20Output, DeployL1Output},
output::{DeployL1Output, ERC20Tokens},
},
script_params::{DEPLOY_ECOSYSTEM_SCRIPT_PARAMS, DEPLOY_ERC20_SCRIPT_PARAMS},
},
traits::{
FileConfigWithDefaultName, ReadConfig, ReadConfigWithBasePath, SaveConfig,
SaveConfigWithBasePath,
},
ChainConfig, ContractsConfig, EcosystemConfig, GenesisConfig,
ContractsConfig, EcosystemConfig, GenesisConfig,
};
use types::{L1Network, ProverMode, WalletCreation};
use types::{L1Network, ProverMode};
use xshell::{cmd, Shell};

use super::{
@@ -43,13 +43,12 @@ use crate::{
create_erc20_deployment_config, create_initial_deployments_config,
},
},
consts::AMOUNT_FOR_DISTRIBUTION_TO_WALLETS,
messages::{
msg_ecosystem_initialized, msg_initializing_chain, MSG_CHAIN_NOT_INITIALIZED,
MSG_DEPLOYING_ECOSYSTEM_CONTRACTS_SPINNER, MSG_DEPLOYING_ERC20,
MSG_DEPLOYING_ERC20_SPINNER, MSG_DISTRIBUTING_ETH_SPINNER,
MSG_ECOSYSTEM_CONTRACTS_PATH_INVALID_ERR, MSG_ECOSYSTEM_CONTRACTS_PATH_PROMPT,
MSG_INITIALIZING_ECOSYSTEM, MSG_INTALLING_DEPS_SPINNER,
MSG_DEPLOYING_ERC20_SPINNER, MSG_ECOSYSTEM_CONTRACTS_PATH_INVALID_ERR,
MSG_ECOSYSTEM_CONTRACTS_PATH_PROMPT, MSG_INITIALIZING_ECOSYSTEM,
MSG_INTALLING_DEPS_SPINNER,
},
utils::forge::{check_the_balance, fill_forge_private_key},
};
@@ -135,39 +134,6 @@ pub async fn run(args: EcosystemInitArgs, shell: &Shell) -> anyhow::Result<()> {
Ok(())
}

// Distribute eth to the chain wallets for localhost environment
pub async fn distribute_eth(
ecosystem_config: &EcosystemConfig,
chain_config: &ChainConfig,
l1_rpc_url: String,
) -> anyhow::Result<()> {
if chain_config.wallet_creation == WalletCreation::Localhost
&& ecosystem_config.l1_network == L1Network::Localhost
{
let spinner = Spinner::new(MSG_DISTRIBUTING_ETH_SPINNER);
let wallets = ecosystem_config.get_wallets()?;
let chain_wallets = chain_config.get_wallets_config()?;
let mut addresses = vec![
chain_wallets.operator.address,
chain_wallets.blob_operator.address,
chain_wallets.governor.address,
];
if let Some(deployer) = chain_wallets.deployer {
addresses.push(deployer.address)
}
common::ethereum::distribute_eth(
wallets.operator,
addresses,
l1_rpc_url,
ecosystem_config.l1_network.chain_id(),
AMOUNT_FOR_DISTRIBUTION_TO_WALLETS,
)
.await?;
spinner.finish();
}
Ok(())
}

async fn init(
init_args: &mut EcosystemInitArgsFinal,
shell: &Shell,
@@ -198,7 +164,7 @@ async fn deploy_erc20(
contracts_config: &ContractsConfig,
forge_args: ForgeScriptArgs,
l1_rpc_url: String,
) -> anyhow::Result<DeployErc20Output> {
) -> anyhow::Result<ERC20Tokens> {
let deploy_config_path = DEPLOY_ERC20_SCRIPT_PARAMS.input(&ecosystem_config.link_to_code);
let wallets = ecosystem_config.get_wallets()?;
DeployErc20Config::new(
@@ -228,7 +194,7 @@ async fn deploy_erc20(
forge.run(shell)?;
spinner.finish();

let result = DeployErc20Output::read(
let result = ERC20Tokens::read(
shell,
DEPLOY_ERC20_SCRIPT_PARAMS.output(&ecosystem_config.link_to_code),
)?;
1 change: 1 addition & 0 deletions zk_toolbox/crates/zk_inception/src/defaults.rs
Original file line number Diff line number Diff line change
@@ -11,6 +11,7 @@ lazy_static! {

pub const ROCKS_DB_STATE_KEEPER: &str = "state_keeper";
pub const ROCKS_DB_TREE: &str = "tree";
pub const ROCKS_DB_PROTECTIVE_READS: &str = "protective_reads";
pub const EN_ROCKS_DB_PREFIX: &str = "en";
pub const MAIN_ROCKS_DB_PREFIX: &str = "main";

2 changes: 2 additions & 0 deletions zk_toolbox/crates/zk_inception/src/messages.rs
Original file line number Diff line number Diff line change
@@ -67,6 +67,8 @@ pub(super) const MSG_INITIALIZING_ECOSYSTEM: &str = "Initializing ecosystem";
pub(super) const MSG_DEPLOYING_ERC20: &str = "Deploying ERC20 contracts";
pub(super) const MSG_CHAIN_INITIALIZED: &str = "Chain initialized successfully";
pub(super) const MSG_DISTRIBUTING_ETH_SPINNER: &str = "Distributing eth...";
pub(super) const MSG_MINT_BASE_TOKEN_SPINNER: &str =
"Minting base token to the governance addresses...";
pub(super) const MSG_INTALLING_DEPS_SPINNER: &str = "Installing and building dependencies...";
pub(super) const MSG_DEPLOYING_ERC20_SPINNER: &str = "Deploying ERC20 contracts...";
pub(super) const MSG_DEPLOYING_ECOSYSTEM_CONTRACTS_SPINNER: &str =
8 changes: 7 additions & 1 deletion zk_toolbox/crates/zk_inception/src/utils/rocks_db.rs
Original file line number Diff line number Diff line change
@@ -4,7 +4,8 @@ use config::RocksDbs;
use xshell::Shell;

use crate::defaults::{
EN_ROCKS_DB_PREFIX, MAIN_ROCKS_DB_PREFIX, ROCKS_DB_STATE_KEEPER, ROCKS_DB_TREE,
EN_ROCKS_DB_PREFIX, MAIN_ROCKS_DB_PREFIX, ROCKS_DB_PROTECTIVE_READS, ROCKS_DB_STATE_KEEPER,
ROCKS_DB_TREE,
};

pub enum RocksDBDirOption {
@@ -32,8 +33,13 @@ pub fn recreate_rocksdb_dirs(
shell.remove_path(&state_keeper)?;
let merkle_tree = rocks_db_path.join(option.prefix()).join(ROCKS_DB_TREE);
shell.remove_path(&merkle_tree)?;
let protective_reads = rocks_db_path
.join(option.prefix())
.join(ROCKS_DB_PROTECTIVE_READS);
shell.remove_path(&protective_reads)?;
Ok(RocksDbs {
state_keeper: shell.create_dir(state_keeper)?,
merkle_tree: shell.create_dir(merkle_tree)?,
protective_reads: shell.create_dir(protective_reads)?,
})
}