NethermindEth / blockifier-tester

A testing utility to run juno with our version of the blockifier that uses cairo native, and compare it to results from mainnet or from juno using the unmodified blockifier
1 stars 1 forks source link

Blockifier Tester

⚠️ NOTE: This project goal is to test software which has not yet reached production stage which means setting it up might not be as easy as it should. Please follow the README thoroughly since we tried to add every possible shortcomming to it. If you see there is something missing here that might help with anything please open an issue and we will fix it asap.

This is a tool created for testing the Blockifier integrated with Cairo Native. It is still a work in progress and currenty it is meant to be used only to assert that natively compiled contracts behaves the same way as casm compiled contract.

Terminology

Native Juno: Juno instance running with Native Blockifier, that is, executing Cairo transactions natively by compiling them first with Cairo Native.

Base Juno: Juno instance running using the "normal" Blockifier or executing Cairo transactions the same way as always, with the VM.

What it does

The tool takes either a single block or a block range* (see Usage). For each block it will:

  1. attempt to trace the block with Native Juno
  2. if the trace had no failures** then
  3. the block will be traced with Base Juno and
  4. a comparison between the two results will be written in ./results-<network>/trace-<block_number>.

Otherwise, if there was a failure, the block will be scanned (using binary search) until the faulty transaction is found. The report will be written in ./results-<network>/block-<block_number>.

Please note that everything in ./results-<network>/ is being tracked using Git LFS to remove noise from the codebase.

*Blocks are sorted in ascending order of how many transactions they have to avoid having to run many long RPC calls before we can get any results.

**A failure in this case is defined as any of the following:

  1. Juno crashing
  2. The block is not found (this likely means your Juno database did not have the block)

Setup

Dependencies (Juno: base and native)

To get your base version of Juno you need to first clone the repo and build it via make juno. Be sure to install all needed dependencies first, which are specified in the that same repository.

Then, to obtain the native version, clone the project again, switch to native2.x.x-blockifier branch and recompile. If you haven't compiled Cairo Native before you may face many compilation issues. We suggest you clone Cairo Native and compile it separately first (be sure to be using the same version as in native2.x.x-blockifier). After both projects are compiled, make sure you have Cairo Native runtime library in your environment which is essential for running Ahead of Time Compiled Cairo.

export CAIRO_NATIVE_RUNTIME_LIBRARY=/<absolute_path_to>/cairo_native/target/release/libcairo_native_runtime.a

Getting network

Finally, Juno must be in sync with the latest blockchain history for whichever network you're using. To achieve this you can either:

  1. (recommended) Manually download a snapshot from here (direct links: Starknet, Sepolia). Be sure that the snapshot you are downloading is recent enough.

  2. Sync Juno manually (for Starknet this will take around 4 to 5 days in optimal conditions)

Config

In the config.toml located at the project root set the following variables*:

juno_path = "<path to base Juno executable>"
juno_native_path = "<path to native Juno executable>"
juno_mainnet_database_path = "<path to Juno's database for the mainnet network>" # correlates to `--db-path` argument passed to Juno
juno_sepolia_database_path = "<path to Juno's database for the sepolia network>" # correlates to `--db-path` argument passed to Juno

It is recommended that you use absolute paths and avoid $HOME and ~

Example config.toml:

juno_path = "/home/pwhite/repos/juno/build/juno"
juno_native_path = "/home/pwhite/repos/native_juno/build/juno"
juno_mainnet_database_path = "/home/pwhite/snapshots/juno_mainnet"
juno_sepolia_database_path = "/home/pwhite/snapshots/juno_sepolia"

Git LFS

To mantain all results in the same repo and use github as a synced db we used Git LFS. It is used to keep track of all files in the ./results-<network>/ directory. Follow install instructions here.

Usage

Once setup is complete, build the project with cargo build. The tool presents two commands:

target/cprof/juno_compare_traces block 610508

or

target/cprof/juno_compare_traces range 610508 611000

Once the tester has traced a block, it will store the output in ./results-<network>/<name>.json and it won't re-do it again unless explicetly told with the redo-comp flag. The tool has many other options like this, please run the CLI with --help to get detailed information of all the commands and options.

target/cprof/juno_compare_traces --help

cprof stands for compilation profile. It is usually debug or release

There are some issues with pathing currently. It's advised to run the binary from the project root.

Logging

The tool will log it's execution. Currently it defaults to debug, but you can set any of the other logging profiles (i.e. info, warn and error) setting the LOG_LEVEL variable.

LOG_LEVEL=info juno_compare_traces range 610508 611000

Troubleshooting

Problem: A block fails on Juno Native when I don't expect it to.

Suggestion: Check juno_out.log to see what the actual failure was. If the failure was that the block was not found, check juno_database_path in your Config.toml and make sure it's pointing to a database path that has that block.