Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,6 @@

CLAUDE.md

.worktrees/
.worktrees/
.claude/
.omc/
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
[workspace.package]
version = "0.1.0"
version = "0.2.0"
edition = "2024"
rust-version = "1.88"
license = "MIT OR Apache-2.0"
Expand Down
131 changes: 131 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
# Heavily inspired by Lighthouse: https://github.com/sigp/lighthouse/blob/stable/Makefile
.DEFAULT_GOAL := help

GIT_SHA ?= $(shell git rev-parse HEAD)
GIT_TAG ?= $(shell git describe --tags --abbrev=0 2>/dev/null || git rev-parse --short HEAD)
BIN_DIR = "dist/bin"

CARGO_TARGET_DIR ?= target

# Cargo profile for builds. Default is release; CI can override.
PROFILE ?= release

# Extra flags for Cargo
CARGO_INSTALL_EXTRA_FLAGS ?=

# The docker image name
DOCKER_IMAGE_NAME ?= ghcr.io/morph-l2/morph-reth

##@ Help

.PHONY: help
help: ## Display this help.
@awk 'BEGIN {FS = ":.*##"; printf "Usage:\n make \033[36m<target>\033[0m\n"} /^[a-zA-Z_0-9-]+:.*?##/ { printf " \033[36m%-30s\033[0m %s\n", $$1, $$2 } /^##@/ { printf "\n\033[1m%s\033[0m\n", substr($$0, 5) } ' $(MAKEFILE_LIST)

##@ Build

.PHONY: build
build: ## Build the morph-reth binary into the `target` directory.
cargo build --bin morph-reth --profile "$(PROFILE)"

.PHONY: build-debug
build-debug: ## Build the morph-reth binary into `target/debug`.
cargo build --bin morph-reth

.PHONY: install
install: ## Build and install the morph-reth binary under `$(CARGO_HOME)/bin`.
cargo install --path bin/morph-reth --bin morph-reth --force --locked \
--profile "$(PROFILE)" \
$(CARGO_INSTALL_EXTRA_FLAGS)

# Create a `.tar.gz` containing the morph-reth binary for a specific target.
define tarball_release_binary
cp $(CARGO_TARGET_DIR)/$(PROFILE)/morph-reth $(BIN_DIR)/morph-reth
cd $(BIN_DIR) && \
tar -czf morph-reth-$(GIT_TAG).tar.gz morph-reth && \
rm morph-reth
endef

.PHONY: build-release-tarballs
build-release-tarballs: ## Build and package morph-reth into a `.tar.gz` in the `dist/bin` directory.
[ -d $(BIN_DIR) ] || mkdir -p $(BIN_DIR)
$(MAKE) build
$(call tarball_release_binary)

##@ Test

.PHONY: test
test: ## Run all tests (unit only, fast).
cargo test --all

.PHONY: test-unit
test-unit: ## Run unit tests with cargo-nextest (install with: cargo install cargo-nextest).
cargo nextest run --locked --workspace -E 'kind(lib)' -E 'kind(bin)' -E 'kind(proc-macro)'

.PHONY: test-e2e
test-e2e: ## Run e2e integration tests (spawns full nodes, slower).
cargo nextest run --locked -p morph-node --features test-utils -E 'binary(it)'

.PHONY: test-all
test-all: test test-e2e ## Run all tests including e2e.

##@ Lint

.PHONY: fmt
fmt: ## Check code formatting.
cargo fmt --all -- --check

.PHONY: fmt-fix
fmt-fix: ## Auto-fix code formatting.
cargo fmt --all

.PHONY: clippy
clippy: ## Run clippy lints.
cargo clippy --all --all-targets -- -D warnings

.PHONY: clippy-e2e
clippy-e2e: ## Run clippy on morph-node with e2e test-utils feature.
cargo clippy -p morph-node --all-targets --features test-utils -- -D warnings

.PHONY: clippy-fix
clippy-fix: ## Run clippy and auto-fix warnings.
cargo clippy --all --all-targets --fix --allow-staged --allow-dirty -- -D warnings

.PHONY: lint
lint: fmt clippy ## Run all lints (fmt + clippy).

.PHONY: fix-lint
fix-lint: clippy-fix fmt-fix ## Auto-fix all lint issues.

##@ Docker

# Note: Requires Docker with buildx support.
# Setup example:
# docker buildx create --use --driver docker-container --name cross-builder
.PHONY: docker-build-push
docker-build-push: ## Build and push a Docker image tagged with the latest git tag.
$(call docker_build_push,$(GIT_TAG),$(GIT_TAG))

.PHONY: docker-build-push-latest
docker-build-push-latest: ## Build and push a Docker image tagged with the latest git tag and `latest`.
$(call docker_build_push,$(GIT_TAG),latest)

.PHONY: docker-build-push-git-sha
docker-build-push-git-sha: ## Build and push a Docker image tagged with the latest git sha.
$(call docker_build_push,$(GIT_SHA),$(GIT_SHA))

define docker_build_push
docker buildx build --file ./Dockerfile . \
--platform linux/amd64 \
--tag $(DOCKER_IMAGE_NAME):$(1) \
--tag $(DOCKER_IMAGE_NAME):$(2) \
--provenance=false \
--push
endef

##@ Other

.PHONY: clean
clean: ## Clean build artifacts and the dist directory.
cargo clean
rm -rf $(BIN_DIR)
31 changes: 31 additions & 0 deletions MakefileEc2.mk
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
# Internal Makefile for building and deploying morph-reth binaries to AWS S3.
# Mirrors the target naming convention from go-ethereum/MakefileEc2.mk.

DIST_DIR = dist
BINARY = morph-reth
TARBALL = morph-reth.tar.gz
CARGO_TARGET_DIR ?= target
PROFILE ?= release

define cargo_build_and_upload
if [ ! -d $(DIST_DIR) ]; then mkdir -p $(DIST_DIR); fi
cargo build --bin $(BINARY) --profile "$(PROFILE)" --target-dir "$(CARGO_TARGET_DIR)"
cp "$(CARGO_TARGET_DIR)/$(PROFILE)/$(BINARY)" "$(DIST_DIR)/"
tar -czvf $(TARBALL) $(DIST_DIR)
aws s3 cp $(TARBALL) $(1)
endef

# ─── Mainnet ─────────────────────────────────────────────────────────────────

build-bk-prod-morph-prod-mainnet-to-morph-reth:
$(call cargo_build_and_upload,s3://morph-0582-morph-technical-department-mainnet-data/morph-setup/morph-reth.tar.gz)

# ─── Testnet (Hoodi) ────────────────────────────────────────────────────────

build-bk-prod-morph-prod-testnet-to-morph-reth-hoodi:
$(call cargo_build_and_upload,s3://morph-0582-morph-technical-department-testnet-data/testnet/hoodi/morph-setup/morph-reth.tar.gz)

# ─── QA Net ──────────────────────────────────────────────────────────────────

build-bk-test-morph-test-qanet-to-morph-reth-qanet:
$(call cargo_build_and_upload,s3://morph-7637-morph-technical-department-qanet-data/morph-setup/morph-reth.tar.gz)
7 changes: 4 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ Morph Reth is the next-generation execution client for [Morph](https://www.morph

- **L1 Message Support**: Seamless bridging of assets and messages from Ethereum L1 to Morph L2
- **Morph Transaction**: Versioned Morph EVM+ transaction with alternative fee-token support and Jade-era reference/memo fields
- **Morph Hardforks**: Implements Morph hardfork logic through Jade, with bundled Mainnet and Hoodi chainspecs currently scheduled through Emerald
- **Morph Hardforks**: Implements Morph hardfork logic through Jade, with bundled Mainnet and Hoodi chainspecs scheduled through Jade
- **Custom Engine API**: L2-specific Engine API for sequencer block building and validation
- **L1 Fee Validation**: Transaction pool with L1 data fee affordability checks

Expand Down Expand Up @@ -114,6 +114,7 @@ openssl rand -hex 32 > jwt.hex
|------|---------|-------------|
| `--morph.max-tx-payload-bytes` | 122880 (120KB) | Maximum transaction payload bytes per block |
| `--morph.max-tx-per-block` | None (unlimited) | Maximum number of transactions per block |
| `--rpc.eth-proof-window` | 0 (disabled) | Max historical blocks for `eth_getProof` (up to 1209600) |

### Running Tests

Expand Down Expand Up @@ -175,7 +176,7 @@ Morph Transaction (`0x7f`) is a versioned custom transaction type that extends E

Bernoulli and Curie use block-based activation; Morph203, Viridian, Emerald, and Jade use timestamp-based activation.

The codebase implements hardfork logic through Jade, but the bundled Mainnet and Hoodi chainspecs currently schedule through Emerald.
The codebase implements hardfork logic through Jade, and the bundled Mainnet and Hoodi chainspecs include activation timestamps through Jade.

| Hardfork | Activation | Description |
|----------|------------|-------------|
Expand All @@ -186,7 +187,7 @@ The codebase implements hardfork logic through Jade, but the bundled Mainnet and
| Emerald | Timestamp | BLS12-381 and P256verify precompiles |
| Jade | Timestamp | MPT state root validation, MorphTx V1 with reference and memo fields |

Before Jade, Morph uses ZK-trie state roots, so morph-reth intentionally skips state-root equality checks and only enables MPT state-root validation at Jade.
Before Jade, Morph uses ZK-trie (Poseidon hash) state roots. morph-reth skips ZK-trie state-root validation pre-Jade and enables MPT state-root validation from Jade onward.

### Engine API

Expand Down
Loading