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 --recursive
after 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, andscripts/ubuntu-build/install-boost.shinstall all required system packages. On an Ubuntu host, first runsudo apt-get update, then run these scripts with elevated privileges (for example, viasudo, or as root).
- gcc-15 or clang-19
- CMake 3.27
- Even when using clang, the only standard library supported is libstdc++; libc++ may work but it is not a tested platform
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=haswellfor C, C++, and assembly sources. -
Run CMake, and generate a ninja build system in the
<path-to-execution-repo>/builddirectory with theCMAKE_BUILD_TYPEset toRelWithDebInfoby default -
Build the CMake
alltarget, 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) ctest
To 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.