-
Notifications
You must be signed in to change notification settings - Fork 1.8k
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(compatibility): add zkSync
support
#7624
Comments
zkSync
support
@nbaztec we're supportive in adding such and rolling it in post v1, reviewed https://gist.github.com/nbaztec/205ac47e8e68bbb3264402965816a413 and would like to continue discussion here on impl. |
My preference goes to strategy |
Yup, that's our plan. We're currently analyzing the areas where the implementation paths diverge, and want to initially build a PoC that would at least demonstrate the required abstractions. For that PoC we may probably use dynamic dispatch, as it's easier to implement, and then it will be rewritten to use static typing. |
We have an example PR that I made in the making of the abstraction doc using dynamic dispatch (as it involved the least amount of code changes) here https://github.com/matter-labs/foundry-zksync/pull/692/files It's currently not tracking the latest |
I gave the process a go with generics and encountered the issues/limitations that there were extensive code changes across the foundry code due to the introduction of strategy objects As a result, in the interest of simply demonstrating the approach, and focusing instead on abstractions and moving things around to avoid cyclic dependencies, we'd like to propose that we proceed with the trait object approach. This would not only be a smaller code footprint but also help the reviewers focus on the proposed abstraction boundaries without additional noise generated due to generic and trait propagation. |
@nbaztec is it possible to prepare a benchmark that would show whether trait objects involve any kind of performance penalty? E.g. with your PR above, you can write a benchmark and run it against upstream code and trait-based implementation. |
@popzxc Yes I believe the foundry team also has a benchmarking which I saw being done on certain PRs. We'd definitely be running the dynamic dispatch approach with native foundry to figure out the performance hit. |
Component
Forge
Describe the feature you would like
Foundry zkSync Support
To enable Foundry compatibility with zkSync, we created the fork https://github.com/matter-labs/foundry-zksync. This fork introduces changes to support smart contract compilation, deployment, testing, and interaction on zkSync Era.
This feature request is a proposal to integrate zkSync support into Foundry. It details an approach designed to be minimally invasive, complemented by a subsequent request for
zksolc
support in foundry-compilers. For more info related tozksolc
please refer to here, and here.Objective
The goal is to integrate zkSync support into Foundry, facilitating community and maintainer dialogue on how best to have these changes accepted.
Below is a brief outline on the differences that are accounted for in the proposed approach.
Differences
zkSync VM
The zkSync VM is fundamentally different from the EVM, in it, it uses an entirely different register-based architecture.
Storage
The Storage is as well different from the EVM's account based trie. In the zkSync VM there's a single global trie. Account balances, nonces, etc. are stored under the hashes slots for special system contracts.
Bytecode
Owing to a different VM, the corresponding bytecode is as well different than what is compiled with solc. In comparison, the zkSync VM is compiled with
zksolc
, which supports all opcodes, with a few exceptions.Proposed Approach
1. Compilation
The foundry-identified files are passed through
zksolc
to generate zkSync VM bytecode. This was then matched using the contract's name with its respective EVM/solc counterpart - finally giving us aDualCompiledContract
containing both evm and zk bytecodes and their respective hashes (which also differ in how they are computed). This "registry" of compiled contracts was propagated down to theExecutors
and to the tracers to perform specialized operations in the context of interoperability between the two scopes, namely EVM and ZK.We're currently in the process of migrating the compilation logic to
foundry-compilers
, but the concept of compiling the same contract for both environments and passing it down to the internals would probably remain.2.
forge
The proposed approach leverages the
CheatcodeTracer
and an early implementation can be reviewed on thedev
branch of foundry-zksync.Consider the following contract:
We assume the test contract is being tested for deployment on zkSync.
solc
and thenzksolc
. Both bytecodes are bundled asDualCompiledContract
and passed down to theExecutor
, till theCheatcodeTracer
.CALLER
account to the deployed test contract (includingensure_success
calls) are handled as normal EVM calls. Except,address.balance
, which are intercepted as opcodes and retrieve the data from ZK-storageblock.timestamp
,block.number
, which are updated with the ZK-specific context on theEnv
directly.CALL
orCREATE
is intercepted in the tracer (withcall
andcreate
hooks) and translated into a ZK transactions. This includesjournaled_state
, and the result returned back.console.log()
in the ZK-VM execution is translated back for foundry to pick upThis forms the basic premise of our implementation that foundry gets to do foundry-specific operations, and only at the necessary stage with invoke the zkSync VM when passing the
--zksync
flag.Challenges
forge test
case. A similar strategy would be required inforge script
.set_balance
andset_nonce
on the correct form of storage - EVM or ZKwarp
,deal
, etc. must be context aware to set correct storage - EVM or ZKexpectCall
must be supported by the ZK tracer to return the appropriate data back to foundry'sCheatcodeTracer
to evaluate their success.Plan
Feature Flag
It is proposed to put all zkSync related features behind a
zksync
feature flag. Rust nightly would be required to compile with this flag, as the zksync libraries currently depend on nightly rust.Foundry zkSync
A single
foundry-zksync
module will contain all zkSync specific logic, and translations. Other parts of foundry source will simply use this module.Foundry Compilers
zksolc
compilation would initially be added tofoundry-compilers
that would later be used in foundry.Forge Commands
Forge commands like
test
,create
,build
,script
would be incrementally supported as pull requests.Conclusion
This is obviously the result of work and testing over several months, and is offered as the best case from our current perspective to integrate foundry into the zkSync ecosystem, while maintaining the same level of foundry's user experience. On that front, we'd like to get the thoughts of foundry developers on anything we may have missed, misunderstood, or vaguely underestimated, in our proposed implementation.
Contributors
@aon, @Deniallugo, @dutterbutter, @HermanObst, @Jrigada, @Karrq, @nbaztec
Additional context
No response
The text was updated successfully, but these errors were encountered: