diff --git a/.gitignore b/.gitignore index 383b2e0..b7aa064 100644 --- a/.gitignore +++ b/.gitignore @@ -4,4 +4,6 @@ CLAUDE.md -.worktrees/ \ No newline at end of file +.worktrees/ +.claude/ +.omc/ \ No newline at end of file diff --git a/Cargo.toml b/Cargo.toml index c44c5b2..910611d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -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" diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..8cf29ef --- /dev/null +++ b/Makefile @@ -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\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) diff --git a/MakefileEc2.mk b/MakefileEc2.mk new file mode 100644 index 0000000..6259f22 --- /dev/null +++ b/MakefileEc2.mk @@ -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) diff --git a/README.md b/README.md index 70667d2..b0a216f 100644 --- a/README.md +++ b/README.md @@ -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 @@ -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 @@ -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 | |----------|------------|-------------| @@ -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