diff --git a/Cargo.lock b/Cargo.lock index e09137ea..a294e1f3 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -489,6 +489,7 @@ dependencies = [ "flate2", "futures 0.3.31", "hex", + "itertools 0.13.0", "rand 0.8.5", "serde", "serde_json", diff --git a/crates/cli/Cargo.toml b/crates/cli/Cargo.toml index 484b6bb2..9b3a7873 100644 --- a/crates/cli/Cargo.toml +++ b/crates/cli/Cargo.toml @@ -23,6 +23,7 @@ anyhow.workspace = true clap.workspace = true eyre.workspace = true hex.workspace = true +itertools.workspace = true futures.workspace = true rand.workspace = true serde.workspace = true diff --git a/crates/cli/src/main.rs b/crates/cli/src/main.rs index 499566a5..2166d8bf 100644 --- a/crates/cli/src/main.rs +++ b/crates/cli/src/main.rs @@ -266,26 +266,27 @@ async fn main() -> anyhow::Result<()> { .await?; } - for signer in config.genesis_accounts.iter() { - let address = H160::from_slice(signer.address().as_ref()); + // TODO: Consider moving to `InMemoryNodeInner::init` + let rich_addresses = itertools::chain!( + config + .genesis_accounts + .iter() + .map(|acc| H160::from_slice(acc.address().as_ref())), + config + .signer_accounts + .iter() + .map(|acc| H160::from_slice(acc.address().as_ref())), + LEGACY_RICH_WALLETS + .iter() + .map(|(address, _)| H160::from_str(address).unwrap()), + RICH_WALLETS + .iter() + .map(|(address, _, _)| H160::from_str(address).unwrap()), + ) + .collect::>(); + for address in rich_addresses { node.set_rich_account(address, config.genesis_balance).await; } - for signer in config.signer_accounts.iter() { - let address = H160::from_slice(signer.address().as_ref()); - node.set_rich_account(address, config.genesis_balance).await; - } - // sets legacy rich wallets - for wallet in LEGACY_RICH_WALLETS.iter() { - let address = wallet.0; - node.set_rich_account(H160::from_str(address).unwrap(), config.genesis_balance) - .await; - } - // sets additional legacy rich wallets - for wallet in RICH_WALLETS.iter() { - let address = wallet.0; - node.set_rich_account(H160::from_str(address).unwrap(), config.genesis_balance) - .await; - } let mut server_builder = NodeServerBuilder::new( node.clone(), diff --git a/crates/core/src/node/in_memory_ext.rs b/crates/core/src/node/in_memory_ext.rs index 79ecc1de..3090a261 100644 --- a/crates/core/src/node/in_memory_ext.rs +++ b/crates/core/src/node/in_memory_ext.rs @@ -1,7 +1,6 @@ use super::pool::TxBatch; use super::sealer::BlockSealerMode; use super::InMemoryNode; -use anvil_zksync_config::constants::{LEGACY_RICH_WALLETS, RICH_WALLETS}; use anvil_zksync_types::api::{DetailedTransaction, ResetRequest}; use anyhow::{anyhow, Context}; use std::str::FromStr; @@ -10,7 +9,7 @@ use url::Url; use zksync_types::api::{Block, TransactionVariant}; use zksync_types::bytecode::BytecodeHash; use zksync_types::u256_to_h256; -use zksync_types::{AccountTreeId, Address, L2BlockNumber, StorageKey, H160, H256, U256, U64}; +use zksync_types::{AccountTreeId, Address, L2BlockNumber, StorageKey, H256, U256, U64}; type Result = anyhow::Result; @@ -247,22 +246,6 @@ impl InMemoryNode { self.snapshots.write().await.clear(); - for wallet in LEGACY_RICH_WALLETS.iter() { - let address = wallet.0; - self.set_rich_account( - H160::from_str(address).unwrap(), - U256::from(100u128 * 10u128.pow(18)), - ) - .await; - } - for wallet in RICH_WALLETS.iter() { - let address = wallet.0; - self.set_rich_account( - H160::from_str(address).unwrap(), - U256::from(100u128 * 10u128.pow(18)), - ) - .await; - } tracing::info!("👷 Network reset"); Ok(true) diff --git a/crates/core/src/node/inner/in_memory_inner.rs b/crates/core/src/node/inner/in_memory_inner.rs index ae61b6e6..6d20182b 100644 --- a/crates/core/src/node/inner/in_memory_inner.rs +++ b/crates/core/src/node/inner/in_memory_inner.rs @@ -22,7 +22,9 @@ use crate::node::{ use crate::system_contracts::SystemContracts; use crate::utils::create_debug_output; use crate::{delegate_vm, formatter, utils}; -use anvil_zksync_config::constants::NON_FORK_FIRST_BLOCK_TIMESTAMP; +use anvil_zksync_config::constants::{ + LEGACY_RICH_WALLETS, NON_FORK_FIRST_BLOCK_TIMESTAMP, RICH_WALLETS, +}; use anvil_zksync_config::TestNodeConfig; use anvil_zksync_types::{ShowCalls, ShowGasDetails, ShowStorageLogs, ShowVMDetails}; use anyhow::Context; @@ -30,6 +32,7 @@ use colored::Colorize; use indexmap::IndexMap; use once_cell::sync::OnceCell; use std::collections::{HashMap, HashSet}; +use std::str::FromStr; use std::sync::Arc; use tokio::sync::RwLock; use zksync_contracts::BaseSystemContracts; @@ -1308,6 +1311,27 @@ impl InMemoryNodeInner { self.rich_accounts.clear(); self.previous_states.clear(); + + let rich_addresses = itertools::chain!( + self.config + .genesis_accounts + .iter() + .map(|acc| H160::from_slice(acc.address().as_ref())), + self.config + .signer_accounts + .iter() + .map(|acc| H160::from_slice(acc.address().as_ref())), + LEGACY_RICH_WALLETS + .iter() + .map(|(address, _)| H160::from_str(address).unwrap()), + RICH_WALLETS + .iter() + .map(|(address, _, _)| H160::from_str(address).unwrap()), + ) + .collect::>(); + for address in rich_addresses { + self.set_rich_account(address, self.config.genesis_balance); + } } /// Adds a lot of tokens to a given account with a specified balance. diff --git a/e2e-tests/helpers/constants.ts b/e2e-tests/helpers/constants.ts index 8adca28d..01163137 100644 --- a/e2e-tests/helpers/constants.ts +++ b/e2e-tests/helpers/constants.ts @@ -40,3 +40,16 @@ export const RichAccounts = [ PrivateKey: "0x3eb15da85647edd9a1159a4a13b9e7c56877c4eb33f614546d4db06a51868b1c", }, ] as const; + +export const GenesisAccounts = [ + "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", + "0x70997970C51812dc3A010C7d01b50e0d17dc79C8", + "0x3C44CdDdB6a900fa2b585dd299e03d12FA4293BC", + "0x90F79bf6EB2c4f870365E785982E1f101E93b906", + "0x15d34AAf54267DB7D7c367839AAf71A00a2C6A65", + "0x9965507D1a55bcC2695C58ba16FB37d819B0A4dc", + "0x976EA74026E726554dB657fA54763abd0C3a0aa9", + "0x14dC79964da2C08b23698B3D3cc7Ca32193d9955", + "0x23618e81E3f5cdF7f54C3d65f7FBc0aBf5B21E8f", + "0xa0Ee7A142d267C1f36714E4a8F75612F20a79720", +] as const; diff --git a/e2e-tests/test/eth-apis.test.ts b/e2e-tests/test/eth-apis.test.ts index 2da606ec..ed898470 100644 --- a/e2e-tests/test/eth-apis.test.ts +++ b/e2e-tests/test/eth-apis.test.ts @@ -1,7 +1,7 @@ import { expect } from "chai"; import { Wallet } from "zksync-ethers"; import { expectThrowsAsync, getTestProvider } from "../helpers/utils"; -import { RichAccounts } from "../helpers/constants"; +import { GenesisAccounts, RichAccounts } from "../helpers/constants"; import { ethers } from "ethers"; import { TransactionResponse } from "zksync-ethers/build/types"; @@ -22,18 +22,6 @@ describe("eth_accounts", function () { it("Should return genesis accounts with sufficient balances", async function () { // Arrange - const genesisAccounts = [ - "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", - "0x70997970C51812dc3A010C7d01b50e0d17dc79C8", - "0x3C44CdDdB6a900fa2b585dd299e03d12FA4293BC", - "0x90F79bf6EB2c4f870365E785982E1f101E93b906", - "0x15d34AAf54267DB7D7c367839AAf71A00a2C6A65", - "0x9965507D1a55bcC2695C58ba16FB37d819B0A4dc", - "0x976EA74026E726554dB657fA54763abd0C3a0aa9", - "0x14dC79964da2C08b23698B3D3cc7Ca32193d9955", - "0x23618e81E3f5cdF7f54C3d65f7FBc0aBf5B21E8f", - "0xa0Ee7A142d267C1f36714E4a8F75612F20a79720", - ]; const expectedBalance = ethers.parseEther("10000"); // Act @@ -41,10 +29,10 @@ describe("eth_accounts", function () { const accounts = response.map((addr) => ethers.getAddress(addr)); // Assert - expect(accounts).to.include.members(genesisAccounts); + expect(accounts).to.include.members(GenesisAccounts); // Assert - for (const account of genesisAccounts) { + for (const account of GenesisAccounts) { const balance = await provider.getBalance(account); expect(balance.toString()).to.equal(expectedBalance.toString()); } diff --git a/e2e-tests/test/hardhat-apis.test.ts b/e2e-tests/test/hardhat-apis.test.ts index 12f5ac25..953bcdce 100644 --- a/e2e-tests/test/hardhat-apis.test.ts +++ b/e2e-tests/test/hardhat-apis.test.ts @@ -1,7 +1,7 @@ import { expect } from "chai"; import { Wallet } from "zksync-ethers"; import { deployContract, expectThrowsAsync, getTestProvider } from "../helpers/utils"; -import { RichAccounts } from "../helpers/constants"; +import { GenesisAccounts, RichAccounts } from "../helpers/constants"; import { ethers } from "hardhat"; import { Deployer } from "@matterlabs/hardhat-zksync-deploy"; import * as hre from "hardhat"; @@ -175,6 +175,13 @@ describe("hardhat_reset", function () { await provider.send("hardhat_reset", []); const newBlockNumber = await provider.send("eth_blockNumber", []); expect(BigInt(newBlockNumber)).to.eq(0n); + + // Assert that both rich accounts and genesis accounts are still managed by the node + const response: string[] = await provider.send("eth_accounts", []); + const accounts = response.map((addr) => ethers.getAddress(addr)).sort(); + const richAccounts = RichAccounts.map((ra) => ra.Account); + expect(accounts).to.include.members(GenesisAccounts); + expect(accounts).to.include.members(richAccounts); }); });