diff --git a/README.md b/README.md index 6018ee19..a636db5f 100644 --- a/README.md +++ b/README.md @@ -124,6 +124,12 @@ Here's a list of the available rich wallets: | `0xa61464658AfeAf65CccaaFD3a512b69A83B77618` | `0xac1e735be8536c6534bb4f17f06f6afc73b2b5ba84ac2cfb12f7461b20c0bbe3` | | `0x0D43eB5B8a47bA8900d84AA36656c92024e9772e` | `0xd293c684d884d56f8d6abd64fc76757d3664904e309a0645baf8522ab6366d9e` | | `0xA13c10C0D5bd6f79041B9835c63f91de35A15883` | `0x850683b40d4a740aa6e745f889a6fdc8327be76e122f5aba645a5b02d0248db8` | +| `0x8002cD98Cfb563492A6fB3E7C8243b7B9Ad4cc92` | `0xf12e28c0eb1ef4ff90478f6805b68d63737b7f33abfa091601140805da450d93` | +| `0x4F9133D1d3F50011A6859807C837bdCB31Aaab13` | `0xe667e57a9b8aaa6709e51ff7d093f1c5b73b63f9987e4ab4aa9a5c699e024ee8` | +| `0xbd29A1B981925B94eEc5c4F1125AF02a2Ec4d1cA` | `0x28a574ab2de8a00364d5dd4b07c4f2f574ef7fcc2a86a197f65abaec836d1959` | +| `0xedB6F5B4aab3dD95C7806Af42881FF12BE7e9daa` | `0x74d8b3a188f7260f67698eb44da07397a298df5427df681ef68c45b34b61f998` | +| `0xe706e60ab5Dc512C36A4646D719b889F398cbBcB` | `0xbe79721778b48bcc679b78edac0ce48306a8578186ffcb9f2ee455ae6efeace1` | +| `0xE90E12261CCb0F3F7976Ae611A29e84a6A85f424` | `0x3eb15da85647edd9a1159a4a13b9e7c56877c4eb33f614546d4db06a51868b1c` | Feel free to use these wallets in your tests, but remember, they are for development purposes only and should not be used in production or with real assets. diff --git a/src/main.rs b/src/main.rs index ffbd4e3e..476d4a7c 100644 --- a/src/main.rs +++ b/src/main.rs @@ -84,7 +84,7 @@ use zksync_core::api_server::web3::backend_jsonrpc::namespaces::{ }; /// List of wallets (address, private key) that we seed with tokens at start. -pub const RICH_WALLETS: [(&str, &str); 4] = [ +pub const RICH_WALLETS: [(&str, &str); 10] = [ ( "0x36615Cf349d7F6344891B1e7CA7C72883F5dc049", "0x7726827caac94a7f9e1b160f7ea819f172f7b6f9d2a97f992c38edeab82d4110", @@ -101,6 +101,30 @@ pub const RICH_WALLETS: [(&str, &str); 4] = [ "0xA13c10C0D5bd6f79041B9835c63f91de35A15883", "0x850683b40d4a740aa6e745f889a6fdc8327be76e122f5aba645a5b02d0248db8", ), + ( + "0x8002cD98Cfb563492A6fB3E7C8243b7B9Ad4cc92", + "0xf12e28c0eb1ef4ff90478f6805b68d63737b7f33abfa091601140805da450d93", + ), + ( + "0x4F9133D1d3F50011A6859807C837bdCB31Aaab13", + "0xe667e57a9b8aaa6709e51ff7d093f1c5b73b63f9987e4ab4aa9a5c699e024ee8", + ), + ( + "0xbd29A1B981925B94eEc5c4F1125AF02a2Ec4d1cA", + "0x28a574ab2de8a00364d5dd4b07c4f2f574ef7fcc2a86a197f65abaec836d1959", + ), + ( + "0xedB6F5B4aab3dD95C7806Af42881FF12BE7e9daa", + "0x74d8b3a188f7260f67698eb44da07397a298df5427df681ef68c45b34b61f998", + ), + ( + "0xe706e60ab5Dc512C36A4646D719b889F398cbBcB", + "0xbe79721778b48bcc679b78edac0ce48306a8578186ffcb9f2ee455ae6efeace1", + ), + ( + "0xE90E12261CCb0F3F7976Ae611A29e84a6A85f424", + "0x3eb15da85647edd9a1159a4a13b9e7c56877c4eb33f614546d4db06a51868b1c", + ), ]; async fn build_json_http( @@ -288,7 +312,7 @@ async fn main() -> anyhow::Result<()> { let address = wallet.0; let private_key = wallet.1; node.set_rich_account(H160::from_str(address).unwrap()); - println!("Account #{}: {} (10000 ETH)", index, address); + println!("Account #{}: {} (1_000_000_000_000 ETH)", index, address); println!("Private Key: {}\n", private_key); } diff --git a/src/node.rs b/src/node.rs index e55f9d9d..7fc839bc 100644 --- a/src/node.rs +++ b/src/node.rs @@ -284,7 +284,7 @@ impl InMemoryNodeInner { ); match estimate_gas_result { - Err(_) => { + Err(tx_revert_reason) => { println!("{}", format!("Unable to estimate gas for the request with our suggested gas limit of {}. The transaction is most likely unexecutable. Breakdown of estimation:", suggested_gas_limit + overhead).to_string().red()); println!( "{}", @@ -302,9 +302,19 @@ impl InMemoryNodeInner { .red() ); println!("{}", format!("\tOverhead: {}", overhead).to_string().red()); + let message = tx_revert_reason.to_string(); + let data = match tx_revert_reason { + TxRevertReason::EthCall(vm_revert_reason) => vm_revert_reason.encoded_data(), + TxRevertReason::TxReverted(vm_revert_reason) => vm_revert_reason.encoded_data(), + _ => vec![], + }; Err(into_jsrpc_error(Web3Error::SubmitTransactionError( - "Transaction is unexecutable".into(), - Default::default(), + format!( + "execution reverted{}{}", + if message.is_empty() { "" } else { ": " }, + message + ), + data, ))) } Ok(_) => { @@ -590,7 +600,7 @@ impl InMemoryNode { let keys = { let mut storage_view = StorageView::new(&inner.fork_storage); - storage_view.set_value(key, u256_to_h256(U256::from(10u128.pow(22)))); + storage_view.set_value(key, u256_to_h256(U256::from(10u128.pow(30)))); storage_view.modified_storage_keys().clone() }; @@ -600,7 +610,7 @@ impl InMemoryNode { } /// Runs L2 'eth call' method - that doesn't commit to a block. - fn run_l2_call(&self, l2_tx: L2Tx) -> Result, String> { + fn run_l2_call(&self, l2_tx: L2Tx) -> Result { let execution_mode = TxExecutionMode::EthCall { missed_storage_invocation_limit: 1000000, }; @@ -653,18 +663,7 @@ impl InMemoryNode { } } - match vm_block_result.full_result.revert_reason { - Some(result) => Ok(result.original_data), - None => Ok(vm_block_result - .full_result - .return_data - .into_iter() - .flat_map(|val| { - let bytes: [u8; 32] = val.into(); - bytes.to_vec() - }) - .collect::>()), - } + Ok(vm_block_result) } fn run_l2_tx_inner( @@ -848,7 +847,40 @@ impl EthNamespaceT for InMemoryNode { let result = self.run_l2_call(tx); match result { - Ok(vec) => Ok(vec.into()).into_boxed_future(), + Ok(vm_block_result) => match vm_block_result.full_result.revert_reason { + Some(revert) => { + let message = revert.revert_reason.to_string(); + let data = match revert.revert_reason { + TxRevertReason::EthCall(vm_revert_reason) => { + vm_revert_reason.encoded_data() + } + TxRevertReason::TxReverted(vm_revert_reason) => { + vm_revert_reason.encoded_data() + } + _ => vec![], + }; + Err(into_jsrpc_error(Web3Error::SubmitTransactionError( + format!( + "execution reverted{}{}", + if message.is_empty() { "" } else { ": " }, + message + ), + data, + ))) + .into_boxed_future() + } + None => Ok(vm_block_result + .full_result + .return_data + .into_iter() + .flat_map(|val| { + let bytes: [u8; 32] = val.into(); + bytes.to_vec() + }) + .collect::>() + .into()) + .into_boxed_future(), + }, Err(e) => { let error = Web3Error::InvalidTransactionData(ethabi::Error::InvalidName(e)); @@ -984,7 +1016,13 @@ impl EthNamespaceT for InMemoryNode { match inner.write() { Ok(mut guard) => { let code_hash = guard.fork_storage.read_value(&code_key); - Ok(Bytes::from(code_hash.as_bytes())) + + let code = guard + .fork_storage + .load_factory_dep_internal(code_hash) + .unwrap_or_default(); + + Ok(Bytes::from(code)) } Err(_) => Err(into_jsrpc_error(Web3Error::InternalError)), } @@ -1083,7 +1121,7 @@ impl EthNamespaceT for InMemoryNode { } else { U64::from(0) }), - effective_gas_price: Some(500.into()), + effective_gas_price: Some(L2_GAS_PRICE.into()), ..Default::default() });