Monad Execution Overview This repository contains the execution component of a Monad node. It handles the transaction processing for new bl…
Monad Execution Overview This repository contains the execution component of a Monad node. It handles the transaction processing for new bl…
This repository contains the execution component of a Monad node. It handles the transaction processing for new blocks, and keeps track of the state of the blockchain. Consequently, this repository contains the source code for Category Labs' custom EVM implementation, its database implementation, and the high-level transaction scheduling. The other main repository is monad-bft, which contains the source code for the consensus component.
Execution has two kinds of dependencies on third-party libraries:
Self-managed: execution's CMake build system will checkout most of its third-party dependencies as git submodules, and build them as part of its own build process, as CMake subprojects; this will happen automatically during the build, but you must run:
git submodule update --init --recursiveafter checking out this repository.
System: some dependencies are expected to already be part of the
system in a default location, i.e., they are expected to come from the
system's package manager. The primary development platform is Ubuntu.
The scripts scripts/ubuntu-build/install-tools.sh,
scripts/ubuntu-build/install-deps.sh, and
scripts/ubuntu-build/install-boost.sh install all required system
packages. On an Ubuntu host, first run sudo apt-get update, then run
these scripts with elevated privileges (for example, via sudo, or as
root).
As explained in the hardware requirements, a Monad node requires a relatively recent CPU. Execution explicitly requires this to compile: it needs to emit machine code that is only supported on recent CPU models, for fast cryptographic operations.
The minimum ISA support corresponds to the x86-64-v3
feature level. Consequently, the minimum flag you must pass to the compiler
is -march=x86-64-v3, or alternatively -march=haswell ("Haswell" was
the codename of the first Intel CPU to support all of these features).
You may also pass any higher architecture level if you wish, although
the compiled binary may not work on older CPUs. The execution docker
files use -march=haswell because it tries to maximize the number of
systems the resulting binary can run on. If you are only running locally
(i.e., the binary does not need to run anywhere else) use -march=native.
First, change your working directory to the root directory of the execution git repository root and then run:
CC=gcc-15 CXX=g++-15 CMAKE_TOOLCHAIN_FILE=category/core/toolchains/gcc-avx2.cmake \
./scripts/configure.sh && ./scripts/build.shThe above command will do several things:
Use gcc-15 instead of the system's default compiler
Emit machine code using Haswell-era CPU extensions, via the toolchain
file category/core/toolchains/gcc-avx2.cmake; the toolchain file sets
-march=haswell for C, C++, and assembly sources.
Run CMake, and generate a ninja build
system in the /build directory with
the CMAKE_BUILD_TYPE
set to RelWithDebInfo by default
Build the CMake all target, which builds everything
The compiler is selected via the CC/CXX environment variables, which
CMake reads at configuration time. The CPU target is set via the toolchain
file, passed through the CMAKE_TOOLCHAIN_FILE environment variable. If
you want debug binaries instead, you can also pass CMAKE_BUILD_TYPE=Debug
via the environment.
When finished, this will build all of the execution binaries. The main one is
the execution daemon, build/cmd/monad. This binary can provide block
execution services for different EVM-compatible blockchains:
When used as part of a Monad blockchain node, it behaves as the block execution service for the Category Labs consensus daemon (for details, see here); when running in this mode, Monad EVM extensions (e.g., Monad-style staking) are enabled
It can also replay the history of other EVM-compatible blockchains, by executing their historical blocks as inputs; a common developer workflow (and a good full system test) is to replay the history of the original Ethereum mainnet and verify that the computed Merkle roots match after each block
You can also run the full test suite in parallel with:
CTEST_PARALLEL_LEVEL=$(nproc) ctestTo compile monad as a guest program for various zkVMs, such as ZisK or SP1, we need to use a riscv64 cross-compiler that includes newlib. The cmake build extracts only the needed libc objects (setjmp/longjmp) from the unmodified newlib; malloc and syscalls are weakly linked by the zkVM frameworks.
The toolchain is provided by nix, which is what CI uses. Flakes must be enabled; see nix/README.md.
nix build ./nix#toolchainEnvA riscv-gnu-toolchain build also works if you already have one; pass whichever prefix you have as RISCV_TOOLCHAIN_DIR.
cmake -B build-zkvm -S zkvm/guest \
-DCMAKE_TOOLCHAIN_FILE=$PWD/category/core/toolchains/riscv64-elf.cmake \
-DRISCV_TOOLCHAIN_DIR="path/to/riscv_gcc" \
-DCMAKE_BUILD_TYPE=Release -GNinjaWe can then build the static library:
cmake --build build-zkvm --target monad-zkvm --parallelTo understand how the source code is organized, you should start by reading the execution developer overview, which explains how execution and consensus fit together, and where in the source tree you can find different pieces of functionality.
No open issues yet, or sync has not completed.