Repository: matter-labs/era-test-node
Pull request #393 (2024-11-20 16:23:09)

fix: fix issue with balance usage
# What :computer: 
* Fixes issue with `--balance` not being used correctly

# Why :hand:
* Users should be able to specify balance (e.g. `./target/release/era_test_node --accounts 15 --balance 300 run`

# Evidence :camera:
Include screenshots, screen recordings, or `console` output here demonstrating that your changes work as intended

<!-- All sections below are optional. You can uncomment any section applicable to your Pull Request. -->

<!-- # Notes :memo:
* Any notes/thoughts that the reviewers should know prior to reviewing the code? -->



Patch:
diff --git a/src/config/cli.rs b/src/config/cli.rs
index 7329fe4..b72e32b 100644
--- a/src/config/cli.rs
+++ b/src/config/cli.rs
@@ -245,7 +245,7 @@ impl Cli {
     }
     /// Converts the CLI arguments to a `TestNodeConfig`.
     pub fn into_test_node_config(self) -> eyre::Result<TestNodeConfig> {
-        let genesis_balance = U256::from(100u128 * 10u128.pow(18));
+        let genesis_balance = U256::from(self.balance as u128 * 10u128.pow(18));
 
         let vm_log_detail = if let Some(output) = self.show_outputs {
             if output {
diff --git a/src/config/constants.rs b/src/config/constants.rs
index 8244302..9ff4fad 100644
--- a/src/config/constants.rs
+++ b/src/config/constants.rs
@@ -20,6 +20,9 @@ pub const DERIVATION_PATH: &str = "m/44'/60'/0'/0/0";
 pub const DEFAULT_LOG_FILE_PATH: &str = "era_test_node.log";
 /// Default mnemonic phrase for the test node
 pub const DEFAULT_MNEMONIC: &str = "test test test test test test test test test test test junk";
+/// Default account balance for the dev accounts
+#[cfg(test)]
+pub const DEFAULT_ACCOUNT_BALANCE: u128 = 1_000 * 10u128.pow(18);
 // List of wallets (address, private key, mnemonic) that we seed with tokens at start.
 pub const RICH_WALLETS: [(&str, &str, &str); 10] = [
     (
diff --git a/src/main.rs b/src/main.rs
index 43f27e7..c9ad8c1 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -278,15 +278,15 @@ async fn main() -> anyhow::Result<()> {
 
     for signer in config.genesis_accounts.iter() {
         let address = H160::from_slice(signer.address().as_ref());
-        node.set_rich_account(address);
+        node.set_rich_account(address, config.genesis_balance);
     }
     for signer in config.signer_accounts.iter() {
         let address = H160::from_slice(signer.address().as_ref());
-        node.set_rich_account(address);
+        node.set_rich_account(address, config.genesis_balance);
     }
     for wallet in LEGACY_RICH_WALLETS.iter() {
         let address = wallet.0;
-        node.set_rich_account(H160::from_str(address).unwrap());
+        node.set_rich_account(H160::from_str(address).unwrap(), config.genesis_balance);
     }
 
     let threads = build_json_http(
diff --git a/src/node/debug.rs b/src/node/debug.rs
index 4a527c0..0e2ff81 100644
--- a/src/node/debug.rs
+++ b/src/node/debug.rs
@@ -243,6 +243,7 @@ mod tests {
 
     use super::*;
     use crate::{
+        config::constants::DEFAULT_ACCOUNT_BALANCE,
         deps::system_contracts::bytecode_from_slice,
         http_fork_source::HttpForkSource,
         node::{InMemoryNode, TransactionResult},
@@ -252,7 +253,7 @@ mod tests {
     fn deploy_test_contracts(node: &InMemoryNode<HttpForkSource>) -> (Address, Address) {
         let private_key = K256PrivateKey::from_bytes(H256::repeat_byte(0xee)).unwrap();
         let from_account = private_key.address();
-        node.set_rich_account(from_account);
+        node.set_rich_account(from_account, U256::from(DEFAULT_ACCOUNT_BALANCE));
 
         // first, deploy secondary contract
         let secondary_bytecode = bytecode_from_slice(
diff --git a/src/node/eth.rs b/src/node/eth.rs
index 65ef02e..51c05ba 100644
--- a/src/node/eth.rs
+++ b/src/node/eth.rs
@@ -1467,7 +1467,10 @@ mod tests {
     use super::*;
     use crate::node::NON_FORK_FIRST_BLOCK_TIMESTAMP;
     use crate::{
-        config::{cache::CacheConfig, constants::DEFAULT_L2_GAS_PRICE},
+        config::{
+            cache::CacheConfig,
+            constants::{DEFAULT_ACCOUNT_BALANCE, DEFAULT_L2_GAS_PRICE},
+        },
         fork::ForkDetails,
         http_fork_source::HttpForkSource,
         node::{compute_hash, InMemoryNode, Snapshot},
@@ -2656,7 +2659,7 @@ mod tests {
 
         let private_key = K256PrivateKey::from_bytes(H256::repeat_byte(0xef)).unwrap();
         let from_account = private_key.address();
-        node.set_rich_account(from_account);
+        node.set_rich_account(from_account, U256::from(DEFAULT_ACCOUNT_BALANCE));
 
         let deployed_address = deployed_address_create(from_account, U256::zero());
 
@@ -2688,7 +2691,7 @@ mod tests {
 
         let private_key = K256PrivateKey::from_bytes(H256::repeat_byte(0xef)).unwrap();
         let from_account = private_key.address();
-        node.set_rich_account(from_account);
+        node.set_rich_account(from_account, U256::from(DEFAULT_ACCOUNT_BALANCE));
 
         let deployed_address = deployed_address_create(from_account, U256::zero());
 
@@ -2902,7 +2905,7 @@ mod tests {
 
         let private_key = H256::repeat_byte(0x01);
         let from_account = K256PrivateKey::from_bytes(private_key).unwrap().address();
-        node.set_rich_account(from_account);
+        node.set_rich_account(from_account, U256::from(DEFAULT_ACCOUNT_BALANCE));
 
         let account_result = node.accounts().await;
         let expected_accounts: Vec<H160> = vec![from_account];
diff --git a/src/node/in_memory.rs b/src/node/in_memory.rs
index 0530e60..d19d823 100644
--- a/src/node/in_memory.rs
+++ b/src/node/in_memory.rs
@@ -973,11 +973,17 @@ impl<S: ForkSource + std::fmt::Debug + Clone> InMemoryNode<S> {
 
         for wallet in LEGACY_RICH_WALLETS.iter() {
             let address = wallet.0;
-            self.set_rich_account(H160::from_str(address).unwrap());
+            self.set_rich_account(
+                H160::from_str(address).unwrap(),
+                U256::from(100u128 * 10u128.pow(18)),
+            );
         }
         for wallet in RICH_WALLETS.iter() {
             let address = wallet.0;
-            self.set_rich_account(H160::from_str(address).unwrap());
+            self.set_rich_account(
+                H160::from_str(address).unwrap(),
+                U256::from(100u128 * 10u128.pow(18)),
+            );
         }
         Ok(())
     }
@@ -996,8 +1002,8 @@ impl<S: ForkSource + std::fmt::Debug + Clone> InMemoryNode<S> {
         Ok(())
     }
 
-    /// Adds a lot of tokens to a given account.
-    pub fn set_rich_account(&self, address: H160) {
+    /// Adds a lot of tokens to a given account with a specified balance.
+    pub fn set_rich_account(&self, address: H160, balance: U256) {
         let key = storage_key_for_eth_balance(&address);
 
         let mut inner = match self.inner.write() {
@@ -1010,9 +1016,8 @@ impl<S: ForkSource + std::fmt::Debug + Clone> InMemoryNode<S> {
 
         let keys = {
             let mut storage_view = StorageView::new(&inner.fork_storage);
-            // Set balance to 100 ETH (in Wei)
-            let balance_in_wei = U256::from(100u128 * 10u128.pow(18));
-            storage_view.set_value(key, u256_to_h256(balance_in_wei));
+            // Set balance to the specified amount
+            storage_view.set_value(key, u256_to_h256(balance));
             storage_view.modified_storage_keys().clone()
         };
 
@@ -1865,8 +1870,9 @@ mod tests {
     use crate::{
         config::{
             constants::{
-                DEFAULT_ESTIMATE_GAS_PRICE_SCALE_FACTOR, DEFAULT_ESTIMATE_GAS_SCALE_FACTOR,
-                DEFAULT_FAIR_PUBDATA_PRICE, DEFAULT_L2_GAS_PRICE, TEST_NODE_NETWORK_ID,
+                DEFAULT_ACCOUNT_BALANCE, DEFAULT_ESTIMATE_GAS_PRICE_SCALE_FACTOR,
+                DEFAULT_ESTIMATE_GAS_SCALE_FACTOR, DEFAULT_FAIR_PUBDATA_PRICE,
+                DEFAULT_L2_GAS_PRICE, TEST_NODE_NETWORK_ID,
             },
             TestNodeConfig,
         },
@@ -1899,7 +1905,10 @@ mod tests {
         let tx = testing::TransactionBuilder::new()
             .set_gas_limit(U256::from(u64::MAX) + 1)
             .build();
-        node.set_rich_account(tx.common_data.initiator_address);
+        node.set_rich_account(
+            tx.common_data.initiator_address,
+            U256::from(100u128 * 10u128.pow(18)),
+        );
 
         let system_contracts = node
             .system_contracts_for_tx(tx.initiator_account())
@@ -1917,7 +1926,10 @@ mod tests {
         let tx = testing::TransactionBuilder::new()
             .set_max_fee_per_gas(U256::from(DEFAULT_L2_GAS_PRICE - 1))
             .build();
-        node.set_rich_account(tx.common_data.initiator_address);
+        node.set_rich_account(
+            tx.common_data.initiator_address,
+            U256::from(100u128 * 10u128.pow(18)),
+        );
 
         let system_contracts = node
             .system_contracts_for_tx(tx.initiator_account())
@@ -1939,7 +1951,10 @@ mod tests {
         let tx = testing::TransactionBuilder::new()
             .set_max_priority_fee_per_gas(U256::from(250_000_000 + 1))
             .build();
-        node.set_rich_account(tx.common_data.initiator_address);
+        node.set_rich_account(
+            tx.common_data.initiator_address,
+            U256::from(100u128 * 10u128.pow(18)),
+        );
 
         let system_contracts = node
             .system_contracts_for_tx(tx.initiator_account())
@@ -1968,7 +1983,10 @@ mod tests {
         // Perform a transaction to get storage to an intermediate state
         let node = InMemoryNode::<HttpForkSource>::default();
         let tx = testing::TransactionBuilder::new().build();
-        node.set_rich_account(tx.common_data.initiator_address);
+        node.set_rich_account(
+            tx.common_data.initiator_address,
+            U256::from(100u128 * 10u128.pow(18)),
+        );
         let system_contracts = node
             .system_contracts_for_tx(tx.initiator_account())
             .unwrap();
@@ -2023,7 +2041,7 @@ mod tests {
 
         let private_key = K256PrivateKey::from_bytes(H256::repeat_byte(0xef)).unwrap();
         let from_account = private_key.address();
-        node.set_rich_account(from_account);
+        node.set_rich_account(from_account, U256::from(DEFAULT_ACCOUNT_BALANCE));
 
         let deployed_address = deployed_address_create(from_account, U256::zero());
         testing::deploy_contract(


Test patch:
diff --git a/e2e-tests/test/eth-apis.test.ts b/e2e-tests/test/eth-apis.test.ts
index 4544074..02c3ee8 100644
--- a/e2e-tests/test/eth-apis.test.ts
+++ b/e2e-tests/test/eth-apis.test.ts
@@ -33,7 +33,7 @@ describe("eth_accounts", function () {
       "0x23618e81E3f5cdF7f54C3d65f7FBc0aBf5B21E8f",
       "0xa0Ee7A142d267C1f36714E4a8F75612F20a79720",
     ];
-    const expectedBalance = ethers.utils.parseEther("100");
+    const expectedBalance = ethers.utils.parseEther("10000");
 
     // Act
     const response: string[] = await provider.send("eth_accounts", []);
diff --git a/src/testing.rs b/src/testing.rs
index 7bcfaa4..ce1be04 100644
--- a/src/testing.rs
+++ b/src/testing.rs
@@ -487,7 +487,10 @@ pub fn apply_tx<T: ForkSource + std::fmt::Debug + Clone>(
 
     let tx = TransactionBuilder::new().set_hash(tx_hash).build();
 
-    node.set_rich_account(tx.common_data.initiator_address);
+    node.set_rich_account(
+        tx.common_data.initiator_address,
+        U256::from(100u128 * 10u128.pow(18)),
+    );
     node.apply_txs(vec![tx.clone()])
         .expect("failed applying tx");