[go: up one dir, main page]

Executing revm (rust evm) on a kernel

What

A rather large MR forming a starting point for the revm benchmark. The only two key files are revm/src/main.rs and revm/inbox-gen/main.rs. Towards a more realistic benchmark for riscv kernels. The main use of smart rollup is currently etherlink. Executing ethereum bytecode using the revm EVM implementation, is closer etherlink. Like Jstz and Etherlink, the kernel found in the revm directory reads the kernel inbox parses them into revm transactions and runs them using the revm library.

Unlike Jstz and Etherlink, there is not yet signing of messages entered into the inbox and verification of these messages from the kernel side. This is future work.

Reads external messages from the kernel inbox

Why

Intended as a more accurate benchmark of riscv kernels running realistic loads. Also experimenting with the usage of the faster modern revm library instead of sputnikvm. Enables faster iteration on experiments such as JIT compiling Ethereum bytecode of deployed contracts to RISC-V, and evaluating performance gains on a semi-realistic benchmark.

How

An ERC20 contract revm/inbox-gen/GLDToken.sol is compiled using the solidity compiler and the bytecode can be found in revm/inbox-gen/contract.bin. inbox-gen defines an executable which at the moment, creates an inbox-file with 4 transactions: Deploy said contract, mint 100 coins to alice, alice sends 40 to bob, query alice's balance. Note contract.bin doesn't contain the abi for calling the contract, and a type-safe rust interface is generated from the solidity source code (snippets contained directly in the source code of revm/inbox-gen/main.rs) using the sol! macro from the alloy crate.

revm uses the TxEnv data structure for encoding transactions in ethereum. I've chosen to serialize that structure into the inbox file as an external message (using the "external message frame" protocol). The inbox file is then read by the kernel deserialising back to a list of TxEnvs, and each transaction is executed.

I have already confirmed that these are actually executing without any revm errors. Including some debug messages while executing the kernel would force me to assume a certain order and certain type of transactions which is why all that's shown now is a generic "transaction successful". I can include something more if that's helpful.

Some things I find problematic about the current state of this

  • When generating transactions which deploy a contract. The ethereum address this contract will live in needs to be known beforehand to subsequently generate transaction which call this ethereum contract. This can apparently be done and a helper function needs to be included for this in inbox-gen
  • The abi for calling contract functions is as can be seen manually provided in inbox-gen. Some kind of better integration/automation with the solidity code compilation (which I haven't yet included) would be nice. However this is not particularly important for making a single benchmark.
  • I don't really have any profiling at this point, and from investigation of jstz, I'm not to clear on how this is done. Is it just a simple timing of the amount of time taken to execute. Is there more fancy profiling using eg. intel vtune, and checking micro-architectural usage?

Manually testing the MR

From the riscv directory, run:

make build-revm
make run-revm

Expected outcome is:

ignore internal message 
ignore internal message 
Successful transaction
Successful transaction
Successful transaction
Successful transaction
ignore internal message 

This will run the inbox-gen binary, copy the generated inbox file as an asset, compile the revm kernel and copy the elf file as well as an asset, and run it appropriately in the riscv-sandbox.

Benchmarking

Not applicable as this merge request introduces something to benchmark not the benchmarking itself.

Tasks for the Author

  • Link all Linear issues related to this MR using magic words (e.g. part of, relates to, closes). (N/A)
  • Eliminate dead code and other spurious artefacts introduced in your changes.
  • Document new public functions, methods and types.
  • Make sure the documentation for updated functions, methods, and types is correct. (no updates)
  • Add tests for bugs that have been fixed. (no bug fix)
  • Put in reasonable effort to ensure that CI will pass.
    • make -C src/riscv
    • dune build src/lib_riscv
    • dune build src/rust_deps
  • Benchmark performance and populate the table above if needed. (N/A)
  • Explain changes to regression test captures when applicable. (N/A)
  • Write commit messages to reflect the changes they're about.
  • Self-review your changes to ensure they are high-quality.
  • Complete all of the above before assigning this MR to reviewers.

Merge request reports

Loading