Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/main' into upstream-da77402
Browse files Browse the repository at this point in the history
  • Loading branch information
Karrq committed Oct 7, 2024
2 parents 49019a3 + dbb13e7 commit baf3004
Show file tree
Hide file tree
Showing 27 changed files with 615 additions and 99 deletions.
13 changes: 8 additions & 5 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -231,7 +231,7 @@ op-alloy-rpc-types = "0.2.9"

## zksync
era_test_node = { git="https://github.com/matter-labs/era-test-node.git" , rev = "2041018903aa7e00e74c450f8c0baf799c056d86" }
zksync-web3-rs = {git = "https://github.com/lambdaclass/zksync-web3-rs.git", rev = "2da644f5b8fc48a129e80fe0653e5334701c059b"}
zksync-web3-rs = {git = "https://github.com/jrigada/zksync-web3-rs.git", rev = "bc3e6d3e75b7ff3747ff2dccefa9fb74d770931b"}
zksync_basic_types = { git = "https://github.com/Moonsong-Labs/zksync-era.git", branch = "foundry-zksync" }
zksync_types = { git = "https://github.com/Moonsong-Labs/zksync-era.git", branch = "foundry-zksync" }
zksync_state = { git = "https://github.com/Moonsong-Labs/zksync-era.git", branch = "foundry-zksync" }
Expand Down
1 change: 1 addition & 0 deletions crates/cheatcodes/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ foundry-wallets.workspace = true
foundry-zksync-core.workspace = true
foundry-zksync-compiler.workspace = true
foundry-zksync-inspectors.workspace = true
zksync-web3-rs.workspace = true

zksync_types.workspace = true

Expand Down
4 changes: 4 additions & 0 deletions crates/cheatcodes/spec/src/vm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -693,6 +693,10 @@ interface Vm {
#[cheatcode(group = Testing, safety = Safe)]
function zkVmSkip() external pure;

/// Enables/Disables use of a paymaster for ZK transactions.
#[cheatcode(group = Testing, safety = Safe)]
function zkUsePaymaster(address paymaster_address, bytes calldata paymaster_input) external pure;

/// Registers bytecodes for ZK-VM for transact/call and create instructions.
#[cheatcode(group = Testing, safety = Safe)]
function zkRegisterContract(string calldata name, bytes32 evmBytecodeHash, bytes calldata evmDeployedBytecode, bytes calldata evmBytecode, bytes32 zkBytecodeHash, bytes calldata zkDeployedBytecode) external pure;
Expand Down
168 changes: 110 additions & 58 deletions crates/cheatcodes/src/inspector.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,9 +40,9 @@ use foundry_evm_core::{
};
use foundry_zksync_compiler::{DualCompiledContract, DualCompiledContracts};
use foundry_zksync_core::{
convert::{ConvertH160, ConvertH256, ConvertRU256, ConvertU256},
get_account_code_key, get_balance_key, get_nonce_key, Call, ZkTransactionMetadata,
DEFAULT_CREATE2_DEPLOYER_ZKSYNC,
convert::{ConvertAddress, ConvertH160, ConvertH256, ConvertRU256, ConvertU256},
get_account_code_key, get_balance_key, get_nonce_key, Call, ZkPaymasterData,
ZkTransactionMetadata, DEFAULT_CREATE2_DEPLOYER_ZKSYNC,
};
use foundry_zksync_inspectors::TraceCollector;
use itertools::Itertools;
Expand Down Expand Up @@ -76,6 +76,7 @@ use zksync_types::{
H256, KNOWN_CODES_STORAGE_ADDRESS, L2_BASE_TOKEN_ADDRESS, NONCE_HOLDER_ADDRESS,
SYSTEM_CONTEXT_ADDRESS,
};
use zksync_web3_rs::eip712::PaymasterParams;

mod utils;

Expand Down Expand Up @@ -495,6 +496,9 @@ pub struct Cheatcodes {
/// Records the next create address for `skip_zk_vm_addresses`.
pub record_next_create_address: bool,

/// Paymaster params
pub paymaster_params: Option<ZkPaymasterData>,

/// Dual compiled contracts
pub dual_compiled_contracts: DualCompiledContracts,

Expand Down Expand Up @@ -590,14 +594,15 @@ impl Cheatcodes {
mapping_slots: Default::default(),
pc: Default::default(),
breakpoints: Default::default(),
rng: Default::default(),
ignored_traces: Default::default(),
arbitrary_storage: Default::default(),
use_zk_vm: Default::default(),
skip_zk_vm: Default::default(),
skip_zk_vm_addresses: Default::default(),
record_next_create_address: Default::default(),
persisted_factory_deps: Default::default(),
rng: Default::default(),
ignored_traces: Default::default(),
arbitrary_storage: Default::default(),
paymaster_params: None,
}
}

Expand Down Expand Up @@ -972,6 +977,11 @@ impl Cheatcodes {
None
};
let rpc = ecx_inner.db.active_fork_url();
let paymaster_params =
self.paymaster_params.clone().map(|paymaster_data| PaymasterParams {
paymaster: paymaster_data.address.to_h160(),
paymaster_input: paymaster_data.input.to_vec(),
});
if let Some(factory_deps) = zk_tx {
let mut batched =
foundry_zksync_core::vm::batch_factory_dependencies(factory_deps);
Expand All @@ -990,7 +1000,10 @@ impl Cheatcodes {
..Default::default()
}
.into(),
zk_tx: Some(ZkTransactionMetadata { factory_deps }),
zk_tx: Some(ZkTransactionMetadata {
factory_deps,
paymaster_data: paymaster_params.clone(),
}),
});

//update nonce for each tx
Expand All @@ -1014,7 +1027,9 @@ impl Cheatcodes {
..Default::default()
}
.into(),
zk_tx: zk_tx.map(ZkTransactionMetadata::new),
zk_tx: zk_tx.map(|factory_deps| {
ZkTransactionMetadata::new(factory_deps, paymaster_params)
}),
});

input.log_debug(self, &input.scheme().unwrap_or(CreateScheme::Create));
Expand Down Expand Up @@ -1076,6 +1091,22 @@ impl Cheatcodes {
return None
}

if let Some(CreateScheme::Create) = input.scheme() {
let caller = input.caller();
let nonce = ecx
.inner
.journaled_state
.load_account(input.caller(), &mut ecx.inner.db)
.expect("to load caller account")
.info
.nonce;
let address = caller.create(nonce);
if ecx.db.get_test_contract_address().map(|addr| address == addr).unwrap_or_default() {
info!("running create in EVM, instead of zkEVM (Test Contract) {:#?}", address);
return None
}
}

if input.init_code().0 == DEFAULT_CREATE2_DEPLOYER_CODE {
info!("running create in EVM, instead of zkEVM (DEFAULT_CREATE2_DEPLOYER_CODE)");
return None
Expand All @@ -1096,6 +1127,7 @@ impl Cheatcodes {
expected_calls: Some(&mut self.expected_calls),
accesses: self.accesses.as_mut(),
persisted_factory_deps: Some(&mut self.persisted_factory_deps),
paymaster_data: self.paymaster_params.take(),
};
let create_inputs = CreateInputs {
scheme: input.scheme().unwrap_or(CreateScheme::Create),
Expand All @@ -1105,9 +1137,7 @@ impl Cheatcodes {
gas_limit: input.gas_limit(),
};

// We currently exhaust the entire gas for the call as zkEVM returns a very high
// amount of gas that OOGs revm.
let gas = Gas::new(input.gas_limit());
let mut gas = Gas::new(input.gas_limit());
match foundry_zksync_core::vm::create::<_, DatabaseError>(
&create_inputs,
zk_contract,
Expand Down Expand Up @@ -1149,32 +1179,38 @@ impl Cheatcodes {
}

match result.execution_result {
ExecutionResult::Success { output, .. } => match output {
Output::Create(bytes, address) => Some(CreateOutcome {
result: InterpreterResult {
result: InstructionResult::Return,
output: bytes,
gas,
},
address,
}),
_ => Some(CreateOutcome {
ExecutionResult::Success { output, gas_used, .. } => {
let _ = gas.record_cost(gas_used);
match output {
Output::Create(bytes, address) => Some(CreateOutcome {
result: InterpreterResult {
result: InstructionResult::Return,
output: bytes,
gas,
},
address,
}),
_ => Some(CreateOutcome {
result: InterpreterResult {
result: InstructionResult::Revert,
output: Bytes::new(),
gas,
},
address: None,
}),
}
}
ExecutionResult::Revert { output, gas_used, .. } => {
let _ = gas.record_cost(gas_used);
Some(CreateOutcome {
result: InterpreterResult {
result: InstructionResult::Revert,
output: Bytes::new(),
output,
gas,
},
address: None,
}),
},
ExecutionResult::Revert { output, .. } => Some(CreateOutcome {
result: InterpreterResult {
result: InstructionResult::Revert,
output,
gas,
},
address: None,
}),
})
}
ExecutionResult::Halt { .. } => Some(CreateOutcome {
result: InterpreterResult {
result: InstructionResult::Revert,
Expand Down Expand Up @@ -1541,11 +1577,22 @@ impl Cheatcodes {
ecx_inner.journaled_state.state().get_mut(&broadcast.new_origin).unwrap();

let zk_tx = if self.use_zk_vm {
let paymaster_params =
self.paymaster_params.clone().map(|paymaster_data| PaymasterParams {
paymaster: paymaster_data.address.to_h160(),
paymaster_input: paymaster_data.input.to_vec(),
});
// We shouldn't need factory_deps for CALLs
if call.target_address == DEFAULT_CREATE2_DEPLOYER_ZKSYNC {
Some(ZkTransactionMetadata { factory_deps: factory_deps.clone() })
Some(ZkTransactionMetadata {
factory_deps: factory_deps.clone(),
paymaster_data: paymaster_params,
})
} else {
Some(ZkTransactionMetadata { factory_deps: Default::default() })
Some(ZkTransactionMetadata {
factory_deps: Default::default(),
paymaster_data: paymaster_params,
})
}
} else {
None
Expand Down Expand Up @@ -1690,11 +1737,10 @@ impl Cheatcodes {
expected_calls: Some(&mut self.expected_calls),
accesses: self.accesses.as_mut(),
persisted_factory_deps: Some(&mut self.persisted_factory_deps),
paymaster_data: self.paymaster_params.take(),
};

// We currently exhaust the entire gas for the call as zkEVM returns a very high amount
// of gas that OOGs revm.
let gas = Gas::new(call.gas_limit);
let mut gas = Gas::new(call.gas_limit);
match foundry_zksync_core::vm::call::<_, DatabaseError>(call, factory_deps, ecx, ccx) {
Ok(result) => {
// append console logs from zkEVM to the current executor's LogTracer
Expand Down Expand Up @@ -1733,32 +1779,38 @@ impl Cheatcodes {
}

match result.execution_result {
ExecutionResult::Success { output, .. } => match output {
Output::Call(bytes) => Some(CallOutcome {
result: InterpreterResult {
result: InstructionResult::Return,
output: bytes,
gas,
},
memory_offset: call.return_memory_offset.clone(),
}),
_ => Some(CallOutcome {
ExecutionResult::Success { output, gas_used, .. } => {
let _ = gas.record_cost(gas_used);
match output {
Output::Call(bytes) => Some(CallOutcome {
result: InterpreterResult {
result: InstructionResult::Return,
output: bytes,
gas,
},
memory_offset: call.return_memory_offset.clone(),
}),
_ => Some(CallOutcome {
result: InterpreterResult {
result: InstructionResult::Revert,
output: Bytes::new(),
gas,
},
memory_offset: call.return_memory_offset.clone(),
}),
}
}
ExecutionResult::Revert { output, gas_used, .. } => {
let _ = gas.record_cost(gas_used);
Some(CallOutcome {
result: InterpreterResult {
result: InstructionResult::Revert,
output: Bytes::new(),
output,
gas,
},
memory_offset: call.return_memory_offset.clone(),
}),
},
ExecutionResult::Revert { output, .. } => Some(CallOutcome {
result: InterpreterResult {
result: InstructionResult::Revert,
output,
gas,
},
memory_offset: call.return_memory_offset.clone(),
}),
})
}
ExecutionResult::Halt { .. } => Some(CallOutcome {
result: InterpreterResult {
result: InstructionResult::Revert,
Expand Down
10 changes: 10 additions & 0 deletions crates/cheatcodes/src/test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ use alloy_primitives::Address;
use alloy_sol_types::SolValue;
use foundry_evm_core::constants::MAGIC_SKIP;
use foundry_zksync_compiler::DualCompiledContract;
use foundry_zksync_core::ZkPaymasterData;

pub(crate) mod assert;
pub(crate) mod assume;
Expand Down Expand Up @@ -35,6 +36,15 @@ impl Cheatcode for zkVmSkipCall {
}
}

impl Cheatcode for zkUsePaymasterCall {
fn apply_stateful<DB: DatabaseExt>(&self, ccx: &mut CheatsCtxt<DB>) -> Result {
let Self { paymaster_address, paymaster_input } = self;
ccx.state.paymaster_params =
Some(ZkPaymasterData { address: *paymaster_address, input: paymaster_input.clone() });
Ok(Default::default())
}
}

impl Cheatcode for zkRegisterContractCall {
fn apply_stateful<DB: DatabaseExt>(&self, ccx: &mut CheatsCtxt<DB>) -> Result {
let Self {
Expand Down
1 change: 1 addition & 0 deletions crates/evm/traces/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ foundry-compilers.workspace = true
foundry-linking.workspace = true
foundry-config.workspace = true
foundry-evm-core.workspace = true
foundry-zksync-compiler.workspace = true

alloy-dyn-abi = { workspace = true, features = ["arbitrary", "eip712"] }
alloy-json-abi.workspace = true
Expand Down
Loading

0 comments on commit baf3004

Please sign in to comment.