Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: allow seamless switching between evm and zk-vm #271

Merged
merged 30 commits into from
Mar 5, 2024

Conversation

nbaztec
Copy link
Collaborator

@nbaztec nbaztec commented Feb 22, 2024

What πŸ’»

  • Allows switching between evm and zk-vm seamlessly
  • Entire execution happens on the ZK-VM, with specific FarCalls being executed in the EVM.
  • Switch is made on vm.selectFork with the check if the target chain supports zks_L1ChainId rpc method or not
  • All transactions happening within "EVM scope" are recorded in the CheatcodeTracer and executed on the EVM with the current backend.
  • Any Non-FarCalls happening in the "EVM scope" that target block.number, or address(...).balance are handled to correctly return the values from the AccountInfo instead of the system contracts.
  • Any pre-deployed contracts are replaced with EVM bytecode on fork selection
  • Any contract deployments in EVM mode are replaced with EVM bytecodes.

Why βœ‹

  • Needed for bridging operations

Evidence πŸ“·

image

Notes πŸ“

  • Uses @Karrq's implementation idea of executing single transactions on EVM feat: MultiVM executionΒ #256
  • There are errors happening with code_by_hash when the switch is made that need to be investigated. These don't cause any issues and happen during storage_modification recording.
    image
  • Not switching back to ZK-EVM on test end causes some errors during success() check. These don't cause any issues and can be fixed by simply reverting to zk fork at the end.
    image

TODO

@nbaztec nbaztec changed the title feat: allow switching between evm and zk-vm seamlessly feat: allow seamless switching between evm and zk-vm Feb 22, 2024
@nbaztec nbaztec changed the title feat: allow seamless switching between evm and zk-vm feat: allow seamless switching between evm and zk-evm Feb 22, 2024
@nbaztec nbaztec changed the title feat: allow seamless switching between evm and zk-evm feat: allow seamless switching between evm and zk-vm Feb 22, 2024
@nbaztec nbaztec marked this pull request as ready for review February 23, 2024 13:35
Copy link
Collaborator

@Deniallugo Deniallugo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good! Some minor suggestions

crates/era-cheatcodes/src/cheatcodes.rs Outdated Show resolved Hide resolved
crates/zkforge/src/multi_runner.rs Outdated Show resolved Hide resolved
crates/zkforge/src/multi_runner.rs Outdated Show resolved Hide resolved
fn call_with_evm(&mut self, mut env: Env) -> eyre::Result<ResultAndState> {
let mut db = self.clone();
db.initialize(&env);
let result = match revm::evm_inner::<Self>(&mut env, &mut db, None).transact() {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

do you think that having inspector is valuable here?

Copy link
Collaborator Author

@nbaztec nbaztec Feb 23, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think any deployed code (or that we call) will have cheatcodes or anything else for that matter, so it seems like a safe bet.

Comment on lines +36 to +48
let is_zk_url = foundry_common::try_get_http_provider(fork_url)
.map(|provider| {
let is_zk_url = tokio::runtime::Builder::new_multi_thread()
.enable_all()
.build()
.unwrap()
.block_on(provider.request("zks_L1ChainId", ()))
.map(|_: String| true)
.unwrap_or_default();

is_zk_url
})
.unwrap_or_default();
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what if rpc is not available or just a network lag?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There's a retry mechanism, so that would take care at least of this partially. If the RPC is really not available then we wouldn't even be able to obtain the information for the fork to actually happen

crates/evm/core/src/backend/fuzz.rs Outdated Show resolved Hide resolved
@nbaztec nbaztec mentioned this pull request Feb 26, 2024
@@ -58,4 +58,4 @@ command -v git &>/dev/null || {
build_zkforge "${REPO_ROOT}"

echo "Running tests..."
RUST_LOG=debug "${BINARY_PATH}" test --use "./${SOLC}"
RUST_LOG=warn "${BINARY_PATH}" test --use "./${SOLC}"
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changing the default level to warn as the log output is too verbose currently, and we usually only want the reasons for failure to investigate.

Copy link
Collaborator

@Deniallugo Deniallugo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Overall looks good.
I'm still afraid about complexity and the fact that we have to implement cheatcodes twice, we do check was it evm or not multiple times.

Please consider remove maybe_* functions and handle only evm option there

crates/era-cheatcodes/src/cheatcodes.rs Outdated Show resolved Hide resolved
crates/era-cheatcodes/src/cheatcodes.rs Show resolved Hide resolved
Comment on lines 2712 to 2717
fn maybe_switch_vm<S: DatabaseExt + DatabaseCommit + Send>(
&mut self,
mut db: MutexGuard<'_, Box<S>>,
fork_id: LocalForkId,
force_initialized: bool,
) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd love to change the target of this function and name it switch_to_evm and check everything outside.

It's always difficut to understand what is going on, when you check one main condition at the top of the function and do almost the whole logic under the bracket.

Please consider separate this functionality

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Replaced maybe_switch_vm with select_fork_vm as this better conveys the relationship between selecting a fork (select_fork) and immediately selecting a vm for it.

crates/era-cheatcodes/src/cheatcodes.rs Outdated Show resolved Hide resolved
crates/era-cheatcodes/src/cheatcodes.rs Outdated Show resolved Hide resolved
@nbaztec nbaztec requested a review from Deniallugo March 1, 2024 11:19
@nbaztec nbaztec merged commit 224e5ae into main Mar 5, 2024
10 checks passed
@nbaztec nbaztec deleted the nish-multivm-try-3 branch March 5, 2024 13:46
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants