Skip to content

Commit

Permalink
chore: Fix zkforge script support (#211)
Browse files Browse the repository at this point in the history
  • Loading branch information
MexicanAce authored Jan 18, 2024
1 parent 880ffdd commit 2ddfbb2
Show file tree
Hide file tree
Showing 13 changed files with 149 additions and 106 deletions.
18 changes: 10 additions & 8 deletions crates/cheatcodes/src/inspector.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ use std::{
io::BufReader,
ops::Range,
path::PathBuf,
sync::Arc,
sync::{Arc, RwLock},
};

macro_rules! try_or_continue {
Expand Down Expand Up @@ -176,7 +176,7 @@ pub struct Cheatcodes {
pub corrected_nonce: bool,

/// Scripting based transactions
pub broadcastable_transactions: BroadcastableTransactions,
pub broadcastable_transactions: Arc<RwLock<BroadcastableTransactions>>,

/// Additional, user configurable context this Inspector has access to when inspecting a call
pub config: Arc<CheatsConfig>,
Expand Down Expand Up @@ -781,7 +781,7 @@ impl<DB: DatabaseExt> Inspector<DB> for Cheatcodes {
let account =
data.journaled_state.state().get_mut(&broadcast.new_origin).unwrap();

self.broadcastable_transactions.push_back(BroadcastableTransaction {
let tx = BroadcastableTransaction {
rpc: data.db.active_fork_url(),
transaction: TypedTransaction::Legacy(TransactionRequest {
from: Some(broadcast.new_origin.to_ethers()),
Expand All @@ -796,8 +796,9 @@ impl<DB: DatabaseExt> Inspector<DB> for Cheatcodes {
},
..Default::default()
}),
});
debug!(target: "cheatcodes", tx=?self.broadcastable_transactions.back().unwrap(), "broadcastable call");
};
debug!(target: "cheatcodes", ?tx, "broadcastable call");
self.broadcastable_transactions.write().unwrap().push_back(tx);

let prev = account.info.nonce;
account.info.nonce += 1;
Expand Down Expand Up @@ -1144,7 +1145,7 @@ impl<DB: DatabaseExt> Inspector<DB> for Cheatcodes {

let is_fixed_gas_limit = check_if_fixed_gas_limit(data, call.gas_limit);

self.broadcastable_transactions.push_back(BroadcastableTransaction {
let tx = BroadcastableTransaction {
rpc: data.db.active_fork_url(),
transaction: TypedTransaction::Legacy(TransactionRequest {
from: Some(broadcast.new_origin.to_ethers()),
Expand All @@ -1159,12 +1160,13 @@ impl<DB: DatabaseExt> Inspector<DB> for Cheatcodes {
},
..Default::default()
}),
});
};
let kind = match call.scheme {
CreateScheme::Create => "create",
CreateScheme::Create2 { .. } => "create2",
};
debug!(target: "cheatcodes", tx=?self.broadcastable_transactions.back().unwrap(), "broadcastable {kind}");
debug!(target: "cheatcodes", ?tx, "broadcastable {kind}");
self.broadcastable_transactions.write().unwrap().push_back(tx);
}
}
}
Expand Down
11 changes: 7 additions & 4 deletions crates/common/src/zk_compile.rs
Original file line number Diff line number Diff line change
Expand Up @@ -181,13 +181,16 @@ impl fmt::Display for ZkSolc {
///
/// The function returns `Ok(())` if the compilation process completes successfully, or an error
/// if it fails.
pub fn compile_smart_contracts(zksolc_cfg: ZkSolcConfig, project: Project) -> eyre::Result<()> {
pub fn compile_smart_contracts(
zksolc_cfg: ZkSolcConfig,
project: Project,
) -> eyre::Result<(ProjectCompileOutput, ContractBytecodes)> {
//TODO: use remappings
let mut zksolc = ZkSolc::new(zksolc_cfg, project);

match zksolc.compile() {
Ok(_) => {
Ok(output) => {
info!("Compiled Successfully");
Ok(())
Ok(output)
}
Err(err) => {
eyre::bail!("Failed to compile smart contracts with zksolc: {}", err);
Expand Down
23 changes: 16 additions & 7 deletions crates/common/src/zksolc_manager.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,10 @@
/// for managing and interacting with zkSync contracts.
use anyhow::{anyhow, Context, Error, Result};
use dirs;
use reqwest::blocking::Client;
use reqwest::Client;
use serde::Serialize;
use std::{fmt, fs, fs::File, io::copy, os::unix::prelude::PermissionsExt, path::PathBuf};
use std::{fmt, fs, os::unix::prelude::PermissionsExt, path::PathBuf};
use tokio::{fs::File, io::copy};
use url::Url;

const ZKSOLC_DOWNLOAD_BASE_URL: &str =
Expand Down Expand Up @@ -434,7 +435,7 @@ impl fmt::Display for ZkSolcManager {
///
/// The function returns the `ZkSolcManager` if all steps are successful, or an error if any
/// step fails.
pub fn setup_zksolc_manager(zksolc_version: String) -> eyre::Result<PathBuf> {
pub async fn setup_zksolc_manager(zksolc_version: String) -> eyre::Result<PathBuf> {
let zksolc_manager_opts = ZkSolcManagerOpts::new(zksolc_version.clone());
let zksolc_manager_builder = ZkSolcManagerBuilder::new(zksolc_manager_opts);
let zksolc_manager = zksolc_manager_builder.build().map_err(|e| {
Expand All @@ -455,7 +456,7 @@ pub fn setup_zksolc_manager(zksolc_version: String) -> eyre::Result<PathBuf> {
"zksolc not found in `.zksync` directory. Downloading zksolc compiler from {}",
download_url
);
zksolc_manager.download().map_err(|err| {
zksolc_manager.download().await.map_err(|err| {
eyre::eyre!(
"Failed to download zksolc version '{}' from {}: {}",
zksolc_version,
Expand Down Expand Up @@ -620,7 +621,7 @@ impl ZkSolcManager {
/// * If the HTTP GET request to the download URL fails.
/// * If the output file cannot be created or written to.
/// * If the permissions for the downloaded compiler binary cannot be set.
pub fn download(&self) -> Result<()> {
pub async fn download(&self) -> Result<()> {
if self.exists() {
// TODO: figure out better don't download if compiler is downloaded
return Ok(())
Expand All @@ -631,16 +632,24 @@ impl ZkSolcManager {
.map_err(|e| Error::msg(format!("Could not get full download url: {}", e)))?;

let client = Client::new();
let mut response = client
let response = client
.get(url)
.send()
.await
.map_err(|e| Error::msg(format!("Failed to download file: {}", e)))?;

if response.status().is_success() {
let mut output_file = File::create(self.get_full_compiler_path())
.await
.map_err(|e| Error::msg(format!("Failed to create output file: {}", e)))?;

copy(&mut response, &mut output_file)
let content = response
.bytes()
.await
.map_err(|e| Error::msg(format!("failed to download file: {}", e)))?;

copy(&mut content.as_ref(), &mut output_file)
.await
.map_err(|e| Error::msg(format!("Failed to write the downloaded file: {}", e)))?;

let compiler_path = self.compilers_path.join(self.get_full_compiler());
Expand Down
16 changes: 11 additions & 5 deletions crates/era-cheatcodes/src/cheatcodes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use crate::{
use alloy_sol_types::{SolInterface, SolValue};
use era_test_node::utils::bytecode_to_factory_dep;
use ethers::{signers::Signer, types::TransactionRequest, utils::to_checksum};
use foundry_cheatcodes::{BroadcastableTransaction, CheatsConfig};
use foundry_cheatcodes::{BroadcastableTransaction, BroadcastableTransactions, CheatsConfig};
use foundry_cheatcodes_spec::Vm;
use foundry_common::{conversion_utils::h160_to_address, StorageModifications};
use foundry_evm_core::{
Expand Down Expand Up @@ -45,7 +45,7 @@ use std::{
ops::BitAnd,
process::Command,
str::FromStr,
sync::Arc,
sync::{Arc, RwLock},
};
use zksync_basic_types::{AccountTreeId, H160, H256, U256};
use zksync_state::{ReadStorage, StoragePtr, WriteStorage};
Expand Down Expand Up @@ -131,7 +131,7 @@ pub struct CheatcodeTracer {
test_status: FoundryTestState,
emit_config: EmitConfig,
saved_snapshots: HashMap<U256, SavedSnapshot>,
broadcastable_transactions: Vec<BroadcastableTransaction>,
broadcastable_transactions: Arc<RwLock<BroadcastableTransactions>>,
}

#[derive(Debug, Clone)]
Expand Down Expand Up @@ -508,7 +508,7 @@ impl<S: DatabaseExt + Send, H: HistoryMode> DynTracer<EraDb<S>, SimpleMemory<H>>
};
tracing::debug!(?tx, "storing for broadcast");

self.broadcastable_transactions.push(tx);
self.broadcastable_transactions.write().unwrap().push_back(tx);
//FIXME: detect if this is a deployment and increase the other nonce too
self.set_nonce(new_origin, (Some(nonce + 1), None), handle);
}
Expand Down Expand Up @@ -954,8 +954,14 @@ impl CheatcodeTracer {
pub fn new(
cheatcodes_config: Arc<CheatsConfig>,
storage_modifications: StorageModifications,
broadcastable_transactions: Arc<RwLock<BroadcastableTransactions>>,
) -> Self {
Self { config: cheatcodes_config, storage_modifications, ..Default::default() }
Self {
config: cheatcodes_config,
storage_modifications,
broadcastable_transactions,
..Default::default()
}
}

/// Resets the test state to [TestStatus::NotStarted]
Expand Down
2 changes: 1 addition & 1 deletion crates/evm/core/src/era_revm/transactions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -205,7 +205,7 @@ where
};
revm::primitives::ExecutionResult::Success {
reason: Eval::Return,
gas_used: env.tx.gas_limit - tx_result.refunds.gas_refunded as u64,
gas_used: tx_result.statistics.gas_used as u64,
gas_refunded: tx_result.refunds.gas_refunded as u64,
logs,
output: revm::primitives::Output::Create(
Expand Down
8 changes: 5 additions & 3 deletions crates/evm/evm/src/executors/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -367,7 +367,7 @@ impl Executor {
let mut cheatcodes = result.cheatcodes.take();
if let Some(cheats) = cheatcodes.as_mut() {
// Clear broadcastable transactions
cheats.broadcastable_transactions.clear();
cheats.broadcastable_transactions.write().unwrap().clear();
debug!(target: "evm::executors", "cleared broadcastable transactions");

// corrected_nonce value is needed outside of this context (setUp), so we don't
Expand Down Expand Up @@ -839,8 +839,10 @@ fn convert_executed_result(
} = inspector.collect();

let transactions = match cheatcodes.as_ref() {
Some(cheats) if !cheats.broadcastable_transactions.is_empty() => {
Some(cheats.broadcastable_transactions.clone())
Some(cheats) => {
let broadcastable_transactions =
cheats.broadcastable_transactions.read().unwrap().clone();
Some(broadcastable_transactions)
}
_ => None,
};
Expand Down
4 changes: 4 additions & 0 deletions crates/evm/evm/src/inspectors/stack.rs
Original file line number Diff line number Diff line change
Expand Up @@ -588,6 +588,10 @@ impl<DB: DatabaseExt + Send> AsTracerPointer<StorageView<RevmDatabaseForEra<DB>>
CheatcodeTracer::new(
self.cheatcodes.as_ref().map(|c| c.config.clone()).unwrap_or_default(),
self.storage_modifications.clone(),
self.cheatcodes
.as_ref()
.map(|c| c.broadcastable_transactions.clone())
.unwrap_or_default(),
)
.into_tracer_pointer()
}
Expand Down
Loading

0 comments on commit 2ddfbb2

Please sign in to comment.