From 3a27baeeef4544e24dcb8890fd1efd236fabfeab Mon Sep 17 00:00:00 2001 From: panos-xyz Date: Thu, 7 May 2026 14:41:54 +0800 Subject: [PATCH 01/10] fix devnet docker submitter config --- ops/docker/docker-compose-4nodes.yml | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/ops/docker/docker-compose-4nodes.yml b/ops/docker/docker-compose-4nodes.yml index 32ea8b79b..39febd04a 100644 --- a/ops/docker/docker-compose-4nodes.yml +++ b/ops/docker/docker-compose-4nodes.yml @@ -403,7 +403,7 @@ services: - "7546:8546" - "7551:8551" healthcheck: - test: curl -f http://localhost:8545 + test: ["CMD-SHELL", "wget -qO- --header='Content-Type: application/json' --post-data='{\"jsonrpc\":\"2.0\",\"method\":\"eth_chainId\",\"params\":[],\"id\":1}' http://localhost:8545 | grep -q '\"result\"'"] interval: 30s timeout: 5s retries: 3 @@ -483,6 +483,7 @@ services: - TX_SUBMITTER_FINALIZE=true - TX_SUBMITTER_MAX_FINALIZE_NUM=100 - TX_SUBMITTER_PRIORITY_ROLLUP=false + - TX_SUBMITTER_SEAL_BATCH=true - TX_SUBMITTER_METRICS_SERVER_ENABLE=false - TX_SUBMITTER_METRICS_HOSTNAME=0.0.0.0 - TX_SUBMITTER_METRICS_PORT=6060 @@ -525,6 +526,7 @@ services: - TX_SUBMITTER_FINALIZE=false - TX_SUBMITTER_MAX_FINALIZE_NUM=100 - TX_SUBMITTER_PRIORITY_ROLLUP=false + - TX_SUBMITTER_SEAL_BATCH=true - TX_SUBMITTER_METRICS_SERVER_ENABLE=false - TX_SUBMITTER_METRICS_HOSTNAME=0.0.0.0 - TX_SUBMITTER_METRICS_PORT=6060 @@ -567,6 +569,7 @@ services: - TX_SUBMITTER_FINALIZE=false - TX_SUBMITTER_MAX_FINALIZE_NUM=100 - TX_SUBMITTER_PRIORITY_ROLLUP=false + - TX_SUBMITTER_SEAL_BATCH=true - TX_SUBMITTER_METRICS_SERVER_ENABLE=false - TX_SUBMITTER_METRICS_HOSTNAME=0.0.0.0 - TX_SUBMITTER_METRICS_PORT=6060 @@ -609,6 +612,7 @@ services: - TX_SUBMITTER_FINALIZE=false - TX_SUBMITTER_MAX_FINALIZE_NUM=100 - TX_SUBMITTER_PRIORITY_ROLLUP=false + - TX_SUBMITTER_SEAL_BATCH=true - TX_SUBMITTER_METRICS_SERVER_ENABLE=false - TX_SUBMITTER_METRICS_HOSTNAME=0.0.0.0 - TX_SUBMITTER_METRICS_PORT=6060 From b793c64ea3468f631eaea6d545613069ce2e3e20 Mon Sep 17 00:00:00 2001 From: panos-xyz Date: Thu, 7 May 2026 15:56:52 +0800 Subject: [PATCH 02/10] support reth execution client in devnet --- Makefile | 46 +++++++++-- node/ops-morph/docker-compose.yml | 16 ++-- node/ops-morph/testnet/docker-compose.yml | 48 ++++++------ node/ops-morph/testnet/static-nodes.json | 2 +- ops/devnet-morph/devnet/__init__.py | 14 +++- .../test_devnet_execution_client.py | 21 +++++ .../docker-compose.override.yml | 20 ++--- ops/docker-sequencer-test/run-test.sh | 20 ++--- .../scripts/tx-generator.sh | 2 +- ops/docker/docker-compose-4nodes.yml | 76 +++++++++---------- ops/docker/docker-compose-reth.yml | 69 +++++++++++++++++ ops/docker/static-nodes.json | 8 +- oracle/docker-compose.yml | 2 +- 13 files changed, 237 insertions(+), 107 deletions(-) create mode 100644 ops/devnet-morph/test_devnet_execution_client.py create mode 100644 ops/docker/docker-compose-reth.yml diff --git a/Makefile b/Makefile index c8a72db59..2ff3a00b5 100644 --- a/Makefile +++ b/Makefile @@ -137,25 +137,52 @@ go-ubuntu-builder: ################## devnet 4 nodes #################### -devnet-up: submodules go-ubuntu-builder - python3 ops/devnet-morph/main.py --polyrepo-dir=. +EXECUTION_CLIENT ?= geth +MORPH_RETH_DIR ?= ../morph-reth +MORPH_RETH_BUILD_PROFILE ?= release +MORPH_RETH_RUSTFLAGS ?= +MORPH_RETH_DOCKER_TARGET ?= builder +MORPH_RETH_ENTRYPOINT ?= /app/morph-reth +export MORPH_RETH_DIR +export MORPH_RETH_BUILD_PROFILE +export MORPH_RETH_RUSTFLAGS +export MORPH_RETH_DOCKER_TARGET +export MORPH_RETH_ENTRYPOINT +DEVNET_COMPOSE_FILES := -f docker-compose-4nodes.yml + +ifeq ($(EXECUTION_CLIENT),geth) +DEVNET_EXECUTION_DEPS := submodules +else ifeq ($(EXECUTION_CLIENT),reth) +DEVNET_EXECUTION_DEPS := reth +DEVNET_COMPOSE_FILES += -f docker-compose-reth.yml +else +$(error unsupported EXECUTION_CLIENT "$(EXECUTION_CLIENT)", expected "geth" or "reth") +endif + +devnet-up: $(DEVNET_EXECUTION_DEPS) go-ubuntu-builder + python3 ops/devnet-morph/main.py --polyrepo-dir=. --execution-client=$(EXECUTION_CLIENT) .PHONY: devnet-up -devnet-up-debugccc: - python3 ops/devnet-morph/main.py --polyrepo-dir=. --debugccc +devnet-up-reth: + $(MAKE) devnet-up EXECUTION_CLIENT=reth +.PHONY: devnet-up-reth + +devnet-up-debugccc: $(DEVNET_EXECUTION_DEPS) go-ubuntu-builder + python3 ops/devnet-morph/main.py --polyrepo-dir=. --execution-client=$(EXECUTION_CLIENT) --debugccc .PHONY: devnet-up-debugccc devnet-down: - cd ops/docker && docker compose -f docker-compose-4nodes.yml down + cd ops/docker && docker compose $(DEVNET_COMPOSE_FILES) down .PHONY: devnet-down devnet-clean-build: devnet-l1-clean - cd ops/docker && docker compose -f docker-compose-4nodes.yml down --volumes --remove-orphans + cd ops/docker && docker compose $(DEVNET_COMPOSE_FILES) down --volumes --remove-orphans docker volume ls --filter name=docker_ --format='{{.Name}}' | xargs docker volume rm 2>/dev/null || true rm -rf ops/l2-genesis/.devnet rm -rf ops/docker/.devnet rm -rf ops/docker/consensus/beacondata ops/docker/consensus/validatordata ops/docker/consensus/genesis.ssz rm -rf ops/docker/execution/geth + rm -rf ops/docker/execution/reth .PHONY: devnet-clean-build devnet-clean: devnet-clean-build @@ -171,9 +198,14 @@ devnet-l1-clean: .PHONY: devnet-l1-clean devnet-logs: - @(cd ops/docker && docker-compose logs -f) + @(cd ops/docker && docker compose $(DEVNET_COMPOSE_FILES) logs -f) .PHONY: devnet-logs +reth: + @test -d "$(MORPH_RETH_DIR)" || (echo "morph-reth directory not found: $(MORPH_RETH_DIR)" && exit 1) + docker build -t morph-reth:latest --target "$(MORPH_RETH_DOCKER_TARGET)" --build-arg BUILD_PROFILE="$(MORPH_RETH_BUILD_PROFILE)" --build-arg RUSTFLAGS="$(MORPH_RETH_RUSTFLAGS)" "$(MORPH_RETH_DIR)" +.PHONY: reth + # tx-submitter SUBMITTERS := $(shell grep -o 'tx-submitter-[0-9]*[^:]' ops/docker/docker-compose-4nodes.yml | sort | uniq) rebuild-all-tx-submitter: diff --git a/node/ops-morph/docker-compose.yml b/node/ops-morph/docker-compose.yml index 6557ba900..4f9106aad 100644 --- a/node/ops-morph/docker-compose.yml +++ b/node/ops-morph/docker-compose.yml @@ -1,11 +1,11 @@ version: '3.8' volumes: - sequencer_geth_data: + sequencer_el_data: sequencer_node_data: services: - sequencer_geth: + morph-el-0: image: morph/l2geth:latest ports: - "8545:8545" @@ -18,7 +18,7 @@ services: timeout: 5s retries: 3 volumes: - - "sequencer_geth_data:${GETH_DATA_DIR}" + - "sequencer_el_data:${GETH_DATA_DIR}" - "${PWD}/jwt-secret.txt:${JWT_SECRET_PATH}" - "${PWD}/genesis_geth.json:${GENESIS_FILE_PATH}" entrypoint: # pass the L2 specific flags by overriding the entry-point and adding extra arguments @@ -27,7 +27,7 @@ services: sequencer_node: depends_on: - sequencer_geth: + morph-el-0: condition: service_started build: context: .. @@ -37,8 +37,8 @@ services: - "26656:26656" environment: - EMPTY_BLOCK_DELAY=true - - MORPH_NODE_L2_ETH_RPC=http://sequencer_geth:8545 - - MORPH_NODE_L2_ENGINE_RPC=http://sequencer_geth:8551 + - MORPH_NODE_L2_ETH_RPC=http://morph-el-0:8545 + - MORPH_NODE_L2_ENGINE_RPC=http://morph-el-0:8551 - MORPH_NODE_L2_ENGINE_AUTH=jwt-secret.txt ## todo need to replace it to a public network - MORPH_NODE_L1_ETH_RPC=${L1_ETH_RPC} @@ -54,7 +54,7 @@ services: tx-submitter: depends_on: - sequencer_geth: + morph-el-0: condition: service_started sequencer_node: condition: service_started @@ -62,7 +62,7 @@ services: command: rollup environment: - TX_SUBMITTER_L1_PRIVATE_KEY=ac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80 - - TX_SUBMITTER_L2_RPC_URL=http://sequencer_geth:8545 + - TX_SUBMITTER_L2_RPC_URL=http://morph-el-0:8545 - TX_SUBMITTER_L1_RPC_URL=${L1_ETH_RPC} - TX_SUBMITTER_ROLLUP_CONTRACT_ADDRESS=0x6900000000000000000000000000000000000010 - TX_SUBMITTER_EVENT_NAME=SubmitBatches diff --git a/node/ops-morph/testnet/docker-compose.yml b/node/ops-morph/testnet/docker-compose.yml index 95330c83e..d0322fb09 100644 --- a/node/ops-morph/testnet/docker-compose.yml +++ b/node/ops-morph/testnet/docker-compose.yml @@ -32,7 +32,7 @@ volumes: o: bind services: - morph-geth-0: + morph-el-0: image: morph/l2geth:latest ports: - "8545:8545" @@ -48,9 +48,9 @@ services: - "/bin/bash" - "/entrypoint.sh" - morph-geth-1: + morph-el-1: depends_on: - - morph-geth-0 + - morph-el-0 image: morph/l2geth:latest ports: - "8645:8545" @@ -63,14 +63,14 @@ services: - "${PWD}/../genesis_geth.json:/genesis.json" - "${PWD}/static-nodes.json:/db/geth/static-nodes.json" environment: - - BOOT_NODES=enode://58e698ea2dd8a76e0cb185d13c1faabf223b60c89fef988c8b89496571056d6c2922109537bb291cd87f2ec09a23ac37d59bde2c7a4885d07b7b641cadff2921@morph-geth-0:30303 + - BOOT_NODES=enode://58e698ea2dd8a76e0cb185d13c1faabf223b60c89fef988c8b89496571056d6c2922109537bb291cd87f2ec09a23ac37d59bde2c7a4885d07b7b641cadff2921@morph-el-0:30303 entrypoint: # pass the L2 specific flags by overriding the entry-point and adding extra arguments - "/bin/bash" - "/entrypoint.sh" - morph-geth-2: + morph-el-2: depends_on: - - morph-geth-0 + - morph-el-0 image: morph/l2geth:latest ports: - "8745:8545" @@ -83,14 +83,14 @@ services: - "${PWD}/../genesis_geth.json:/genesis.json" - "${PWD}/static-nodes.json:/db/geth/static-nodes.json" environment: - - BOOT_NODES=enode://58e698ea2dd8a76e0cb185d13c1faabf223b60c89fef988c8b89496571056d6c2922109537bb291cd87f2ec09a23ac37d59bde2c7a4885d07b7b641cadff2921@morph-geth-0:30303 + - BOOT_NODES=enode://58e698ea2dd8a76e0cb185d13c1faabf223b60c89fef988c8b89496571056d6c2922109537bb291cd87f2ec09a23ac37d59bde2c7a4885d07b7b641cadff2921@morph-el-0:30303 entrypoint: # pass the L2 specific flags by overriding the entry-point and adding extra arguments - "/bin/bash" - "/entrypoint.sh" - morph-geth-3: + morph-el-3: depends_on: - - morph-geth-0 + - morph-el-0 image: morph/l2geth:latest ports: - "8845:8545" @@ -103,14 +103,14 @@ services: - "${PWD}/../genesis_geth.json:/genesis.json" - "${PWD}/static-nodes.json:/db/geth/static-nodes.json" environment: - - BOOT_NODES=enode://58e698ea2dd8a76e0cb185d13c1faabf223b60c89fef988c8b89496571056d6c2922109537bb291cd87f2ec09a23ac37d59bde2c7a4885d07b7b641cadff2921@morph-geth-0:30303 + - BOOT_NODES=enode://58e698ea2dd8a76e0cb185d13c1faabf223b60c89fef988c8b89496571056d6c2922109537bb291cd87f2ec09a23ac37d59bde2c7a4885d07b7b641cadff2921@morph-el-0:30303 entrypoint: # pass the L2 specific flags by overriding the entry-point and adding extra arguments - "/bin/bash" - "/entrypoint.sh" node-0: depends_on: - morph-geth-0: + morph-el-0: condition: service_started image: morph-node:latest ports: @@ -119,8 +119,8 @@ services: - "26658" environment: - EMPTY_BLOCK_DELAY=true - - MORPH_NODE_L2_ETH_RPC=http://morph-geth-0:8545 - - MORPH_NODE_L2_ENGINE_RPC=http://morph-geth-0:8551 + - MORPH_NODE_L2_ETH_RPC=http://morph-el-0:8545 + - MORPH_NODE_L2_ENGINE_RPC=http://morph-el-0:8551 - MORPH_NODE_L2_ENGINE_AUTH=jwt-secret.txt - MORPH_NODE_L1_ETH_RPC=${L1_ETH_RPC} - MORPH_NODE_SYNC_DEPOSIT_CONTRACT_ADDRESS=0x6900000000000000000000000000000000000001 @@ -134,7 +134,7 @@ services: node-1: depends_on: - morph-geth-1: + morph-el-1: condition: service_started image: morph-node:latest ports: @@ -143,8 +143,8 @@ services: - "26658" environment: - EMPTY_BLOCK_DELAY=true - - MORPH_NODE_L2_ETH_RPC=http://morph-geth-1:8545 - - MORPH_NODE_L2_ENGINE_RPC=http://morph-geth-1:8551 + - MORPH_NODE_L2_ETH_RPC=http://morph-el-1:8545 + - MORPH_NODE_L2_ENGINE_RPC=http://morph-el-1:8551 - MORPH_NODE_L2_ENGINE_AUTH=jwt-secret.txt - MORPH_NODE_L1_ETH_RPC=${L1_ETH_RPC} - MORPH_NODE_SYNC_DEPOSIT_CONTRACT_ADDRESS=0x6900000000000000000000000000000000000001 @@ -158,7 +158,7 @@ services: node-2: depends_on: - morph-geth-2: + morph-el-2: condition: service_started image: morph-node:latest ports: @@ -167,8 +167,8 @@ services: - "26658" environment: - EMPTY_BLOCK_DELAY=true - - MORPH_NODE_L2_ETH_RPC=http://morph-geth-2:8545 - - MORPH_NODE_L2_ENGINE_RPC=http://morph-geth-2:8551 + - MORPH_NODE_L2_ETH_RPC=http://morph-el-2:8545 + - MORPH_NODE_L2_ENGINE_RPC=http://morph-el-2:8551 - MORPH_NODE_L2_ENGINE_AUTH=jwt-secret.txt - MORPH_NODE_L1_ETH_RPC=${L1_ETH_RPC} - MORPH_NODE_SYNC_DEPOSIT_CONTRACT_ADDRESS=0x6900000000000000000000000000000000000001 @@ -182,17 +182,17 @@ services: node-3: depends_on: - morph-geth-3: + morph-el-3: condition: service_started - image: -node:latest + image: morph-node:latest ports: - "26656" - "26657" - "26658" environment: - EMPTY_BLOCK_DELAY=true - - MORPH_NODE_L2_ETH_RPC=http://morph-geth-3:8545 - - MORPH_NODE_L2_ENGINE_RPC=http://morph-geth-3:8551 + - MORPH_NODE_L2_ETH_RPC=http://morph-el-3:8545 + - MORPH_NODE_L2_ENGINE_RPC=http://morph-el-3:8551 - MORPH_NODE_L2_ENGINE_AUTH=jwt-secret.txt - MORPH_NODE_L1_ETH_RPC=${L1_ETH_RPC} - MORPH_NODE_SYNC_DEPOSIT_CONTRACT_ADDRESS=0x6900000000000000000000000000000000000001 @@ -202,4 +202,4 @@ services: command: > morphnode --dev-sequencer - --home $NODE_DATA_DIR \ No newline at end of file + --home $NODE_DATA_DIR diff --git a/node/ops-morph/testnet/static-nodes.json b/node/ops-morph/testnet/static-nodes.json index a8876e3dd..e3b48b8d5 100644 --- a/node/ops-morph/testnet/static-nodes.json +++ b/node/ops-morph/testnet/static-nodes.json @@ -1 +1 @@ -["enode://58e698ea2dd8a76e0cb185d13c1faabf223b60c89fef988c8b89496571056d6c2922109537bb291cd87f2ec09a23ac37d59bde2c7a4885d07b7b641cadff2921@morph-geth-0:30303"] \ No newline at end of file +["enode://58e698ea2dd8a76e0cb185d13c1faabf223b60c89fef988c8b89496571056d6c2922109537bb291cd87f2ec09a23ac37d59bde2c7a4885d07b7b641cadff2921@morph-el-0:30303"] \ No newline at end of file diff --git a/ops/devnet-morph/devnet/__init__.py b/ops/devnet-morph/devnet/__init__.py index 385a7a2a3..3fc3bff79 100644 --- a/ops/devnet-morph/devnet/__init__.py +++ b/ops/devnet-morph/devnet/__init__.py @@ -21,6 +21,8 @@ parser = argparse.ArgumentParser(description='devnet launcher') parser.add_argument('--polyrepo-dir', help='Directory of the polyrepo', default=os.getcwd()) parser.add_argument('--only-l1', help='Only bootstrap l1 geth', action="store_true") +parser.add_argument('--execution-client', choices=('geth', 'reth'), default='geth', + help='L2 execution client implementation to run') # parser.add_argument('--deploy', help='Whether the contracts should be predeployed or deployed', action="store_true") parser.add_argument('--debugccc', help='Whether set the debug log level for ccc', action="store_true") @@ -30,6 +32,13 @@ ETH = GWEI * GWEI +def compose_file_args(execution_client): + args = ['-f', 'docker-compose-4nodes.yml'] + if execution_client == 'reth': + args.extend(['-f', 'docker-compose-reth.yml']) + return args + + class Bunch: def __init__(self, **kwds): self.__dict__.update(kwds) @@ -255,12 +264,11 @@ def devnet_deploy(paths, args): envfile.truncate() envfile.close() - log.info('Bringing up L2.') + log.info(f'Bringing up L2 with {args.execution_client}.') - run_command(['docker', 'compose', '-f', 'docker-compose-4nodes.yml', 'up', - '--no-recreate','-d'], check=False, cwd=paths.ops_dir, + run_command(['docker', 'compose', *compose_file_args(args.execution_client), 'up', '-d'], check=False, cwd=paths.ops_dir, env={ 'MORPH_PORTAL': addresses['Proxy__L1MessageQueueWithGasPriceOracle'], 'MORPH_ROLLUP': addresses['Proxy__Rollup'], diff --git a/ops/devnet-morph/test_devnet_execution_client.py b/ops/devnet-morph/test_devnet_execution_client.py new file mode 100644 index 000000000..167a15bb0 --- /dev/null +++ b/ops/devnet-morph/test_devnet_execution_client.py @@ -0,0 +1,21 @@ +import unittest +from pathlib import Path +import sys + +sys.path.insert(0, str(Path(__file__).resolve().parent)) +from devnet import compose_file_args + + +class ExecutionClientComposeArgsTest(unittest.TestCase): + def test_geth_uses_base_compose_file(self): + self.assertEqual(compose_file_args("geth"), ["-f", "docker-compose-4nodes.yml"]) + + def test_reth_adds_reth_override_file(self): + self.assertEqual( + compose_file_args("reth"), + ["-f", "docker-compose-4nodes.yml", "-f", "docker-compose-reth.yml"], + ) + + +if __name__ == "__main__": + unittest.main() diff --git a/ops/docker-sequencer-test/docker-compose.override.yml b/ops/docker-sequencer-test/docker-compose.override.yml index 9cc69cae8..44aa1c3f7 100644 --- a/ops/docker-sequencer-test/docker-compose.override.yml +++ b/ops/docker-sequencer-test/docker-compose.override.yml @@ -3,20 +3,20 @@ version: '3.8' services: - morph-geth-0: - image: morph-geth-test:latest + morph-el-0: + image: morph-el-test:latest build: context: ../.. dockerfile: ops/docker-sequencer-test/Dockerfile.l2-geth-test - morph-geth-1: - image: morph-geth-test:latest + morph-el-1: + image: morph-el-test:latest - morph-geth-2: - image: morph-geth-test:latest + morph-el-2: + image: morph-el-test:latest - morph-geth-3: - image: morph-geth-test:latest + morph-el-3: + image: morph-el-test:latest node-0: image: morph-node-test:latest @@ -55,8 +55,8 @@ services: - MORPH_NODE_CONSENSUS_SWITCH_HEIGHT=${CONSENSUS_SWITCH_HEIGHT:-10} - sentry-geth-0: - image: morph-geth-test:latest + sentry-el-0: + image: morph-el-test:latest sentry-node-0: image: morph-node-test:latest diff --git a/ops/docker-sequencer-test/run-test.sh b/ops/docker-sequencer-test/run-test.sh index 81361fefa..9b0f0a553 100755 --- a/ops/docker-sequencer-test/run-test.sh +++ b/ops/docker-sequencer-test/run-test.sh @@ -109,9 +109,9 @@ build_test_images() { # log_warn "Build may fail due to network issues" # fi - # Build test geth image - log_info "Building morph-geth-test (using local go-ethereum)..." - docker build -t morph-geth-test:latest \ + # Build test execution image + log_info "Building morph-el-test (using local go-ethereum)..." + docker build -t morph-el-test:latest \ -f morph/ops/docker-sequencer-test/Dockerfile.l2-geth-test . # Build test node image @@ -275,17 +275,17 @@ start_l2_test() { # Stop any existing L2 containers $COMPOSE_CMD stop \ - morph-geth-0 morph-geth-1 morph-geth-2 morph-geth-3 \ + morph-el-0 morph-el-1 morph-el-2 morph-el-3 \ node-0 node-1 node-2 node-3 2>/dev/null || true # Note: Test images should already be built by build_test_images() # Uncomment below if you need to rebuild during start # log_info "Building L2 containers with test images..." - # $COMPOSE_CMD build morph-geth-0 node-0 + # $COMPOSE_CMD build morph-el-0 node-0 - # Start L2 geth nodes - log_info "Starting L2 geth nodes..." - $COMPOSE_CMD up -d morph-geth-0 morph-geth-1 morph-geth-2 morph-geth-3 + # Start L2 execution nodes + log_info "Starting L2 execution nodes..." + $COMPOSE_CMD up -d morph-el-0 morph-el-1 morph-el-2 morph-el-3 sleep 5 @@ -364,7 +364,7 @@ test_fullnode_sync() { # Start sentry node (fullnode) log_info "Starting fullnode (sentry-node-0)..." - $COMPOSE_CMD up -d sentry-geth-0 sentry-node-0 + $COMPOSE_CMD up -d sentry-el-0 sentry-node-0 sleep 10 wait_for_rpc "http://127.0.0.1:8945" @@ -522,7 +522,7 @@ case "${1:-}" in echo "Usage: $0 {build|setup|start|stop|clean|logs|test|tx|status|upgrade-height}" echo "" echo "Commands:" - echo " build - Build test Docker images (morph-geth-test, morph-node-test)" + echo " build - Build test Docker images (morph-el-test, morph-node-test)" echo " setup - Run full devnet setup (L1 + contracts + L2 genesis)" echo " start - Start L2 nodes with test images" echo " stop - Stop all containers" diff --git a/ops/docker-sequencer-test/scripts/tx-generator.sh b/ops/docker-sequencer-test/scripts/tx-generator.sh index 2311a64d5..d6ee40cdf 100644 --- a/ops/docker-sequencer-test/scripts/tx-generator.sh +++ b/ops/docker-sequencer-test/scripts/tx-generator.sh @@ -4,7 +4,7 @@ set -e -L2_RPC="${L2_RPC:-http://morph-geth-0:8545}" +L2_RPC="${L2_RPC:-http://morph-el-0:8545}" INTERVAL="${TX_INTERVAL:-5}" # seconds between txs PRIVATE_KEY="${PRIVATE_KEY:-0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80}" diff --git a/ops/docker/docker-compose-4nodes.yml b/ops/docker/docker-compose-4nodes.yml index 39febd04a..83d4f8b9e 100644 --- a/ops/docker/docker-compose-4nodes.yml +++ b/ops/docker/docker-compose-4nodes.yml @@ -8,13 +8,13 @@ volumes: morph_data_1: morph_data_2: morph_data_3: - sentry_geth_data: + sentry_el_data: node_data_0: node_data_1: node_data_2: node_data_3: sentry_node_data: - validator_geth_data: + validator_el_data: validator_node_data: layer1-el-data: layer1-cl-data: @@ -116,8 +116,8 @@ services: restart: unless-stopped # ========== L2 Services ========== - morph-geth-0: - container_name: morph-geth-0 + morph-el-0: + container_name: morph-el-0 depends_on: layer1-el: condition: service_started @@ -143,10 +143,10 @@ services: - "/bin/bash" - "/entrypoint.sh" - morph-geth-1: - container_name: morph-geth-1 + morph-el-1: + container_name: morph-el-1 depends_on: - - morph-geth-0 + - morph-el-0 image: morph-geth:latest restart: unless-stopped ports: @@ -167,10 +167,10 @@ services: - "/bin/bash" - "/entrypoint.sh" - morph-geth-2: - container_name: morph-geth-2 + morph-el-2: + container_name: morph-el-2 depends_on: - - morph-geth-0 + - morph-el-0 image: morph-geth:latest restart: unless-stopped ports: @@ -191,10 +191,10 @@ services: - "/bin/bash" - "/entrypoint.sh" - morph-geth-3: - container_name: morph-geth-3 + morph-el-3: + container_name: morph-el-3 depends_on: - - morph-geth-0 + - morph-el-0 image: morph-geth:latest restart: unless-stopped ports: @@ -219,7 +219,7 @@ services: node-0: container_name: node-0 depends_on: - morph-geth-0: + morph-el-0: condition: service_started image: morph-node:latest build: @@ -232,8 +232,8 @@ services: - "26658" - "26660" environment: - - MORPH_NODE_L2_ETH_RPC=http://morph-geth-0:8545 - - MORPH_NODE_L2_ENGINE_RPC=http://morph-geth-0:8551 + - MORPH_NODE_L2_ETH_RPC=http://morph-el-0:8545 + - MORPH_NODE_L2_ENGINE_RPC=http://morph-el-0:8551 - MORPH_NODE_L2_ENGINE_AUTH=${JWT_SECRET_PATH} - MORPH_NODE_L1_ETH_RPC=${L1_ETH_RPC} - MORPH_NODE_SYNC_DEPOSIT_CONTRACT_ADDRESS=${MORPH_PORTAL:-0x6900000000000000000000000000000000000001} @@ -261,8 +261,8 @@ services: - "26658" - "26660" environment: - - MORPH_NODE_L2_ETH_RPC=http://morph-geth-1:8545 - - MORPH_NODE_L2_ENGINE_RPC=http://morph-geth-1:8551 + - MORPH_NODE_L2_ETH_RPC=http://morph-el-1:8545 + - MORPH_NODE_L2_ENGINE_RPC=http://morph-el-1:8551 - MORPH_NODE_L2_ENGINE_AUTH=${JWT_SECRET_PATH} - MORPH_NODE_L1_ETH_RPC=${L1_ETH_RPC} - MORPH_NODE_SYNC_DEPOSIT_CONTRACT_ADDRESS=${MORPH_PORTAL:-0x6900000000000000000000000000000000000001} @@ -291,8 +291,8 @@ services: - "26660" environment: - EMPTY_BLOCK_DELAY=true - - MORPH_NODE_L2_ETH_RPC=http://morph-geth-2:8545 - - MORPH_NODE_L2_ENGINE_RPC=http://morph-geth-2:8551 + - MORPH_NODE_L2_ETH_RPC=http://morph-el-2:8545 + - MORPH_NODE_L2_ENGINE_RPC=http://morph-el-2:8551 - MORPH_NODE_L2_ENGINE_AUTH=${JWT_SECRET_PATH} - MORPH_NODE_L1_ETH_RPC=${L1_ETH_RPC} - MORPH_NODE_SYNC_DEPOSIT_CONTRACT_ADDRESS=${MORPH_PORTAL:-0x6900000000000000000000000000000000000001} @@ -321,8 +321,8 @@ services: - "26660" environment: - EMPTY_BLOCK_DELAY=true - - MORPH_NODE_L2_ETH_RPC=http://morph-geth-3:8545 - - MORPH_NODE_L2_ENGINE_RPC=http://morph-geth-3:8551 + - MORPH_NODE_L2_ETH_RPC=http://morph-el-3:8545 + - MORPH_NODE_L2_ENGINE_RPC=http://morph-el-3:8551 - MORPH_NODE_L2_ENGINE_AUTH=${JWT_SECRET_PATH} - MORPH_NODE_L1_ETH_RPC=${L1_ETH_RPC} - MORPH_NODE_SYNC_DEPOSIT_CONTRACT_ADDRESS=${MORPH_PORTAL:-0x6900000000000000000000000000000000000001} @@ -337,8 +337,8 @@ services: morphnode --home $NODE_DATA_DIR - sentry-geth-0: - container_name: sentry-geth-0 + sentry-el-0: + container_name: sentry-el-0 depends_on: node-3: condition: service_started @@ -354,7 +354,7 @@ services: - "6060" - "30303" volumes: - - "sentry_geth_data:/db" + - "sentry_el_data:/db" - "${PWD}/jwt-secret.txt:/jwt-secret.txt" - "${PWD}/../l2-genesis/.devnet/genesis-l2.json:/genesis.json" - "${PWD}/static-nodes.json:/db/geth/static-nodes.json" @@ -376,8 +376,8 @@ services: - "26660" environment: - EMPTY_BLOCK_DELAY=true - - MORPH_NODE_L2_ETH_RPC=http://sentry-geth-0:8545 - - MORPH_NODE_L2_ENGINE_RPC=http://sentry-geth-0:8551 + - MORPH_NODE_L2_ETH_RPC=http://sentry-el-0:8545 + - MORPH_NODE_L2_ENGINE_RPC=http://sentry-el-0:8551 - MORPH_NODE_L2_ENGINE_AUTH=${JWT_SECRET_PATH} - MORPH_NODE_L1_ETH_RPC=${L1_ETH_RPC} - MORPH_NODE_SYNC_DEPOSIT_CONTRACT_ADDRESS=${MORPH_PORTAL:-0x6900000000000000000000000000000000000001} @@ -392,8 +392,8 @@ services: --home $NODE_DATA_DIR - validator_geth: - container_name: validator_geth + validator-el: + container_name: validator-el image: morph-geth:latest depends_on: tx-submitter-0: @@ -408,7 +408,7 @@ services: timeout: 5s retries: 3 volumes: - - "validator_geth_data:${GETH_DATA_DIR}" + - "validator_el_data:${GETH_DATA_DIR}" - "${PWD}/jwt-secret.txt:${JWT_SECRET_PATH}" - "${PWD}/../l2-genesis/.devnet/genesis-l2.json:/genesis.json" entrypoint: # pass the L2 specific flags by overriding the entry-point and adding extra arguments @@ -418,7 +418,7 @@ services: validator_node: container_name: validator_node depends_on: - validator_geth: + validator-el: condition: service_started node-0: condition: service_started @@ -426,8 +426,8 @@ services: ports: - "26660" environment: - - MORPH_NODE_L2_ETH_RPC=http://validator_geth:8545 - - MORPH_NODE_L2_ENGINE_RPC=http://validator_geth:8551 + - MORPH_NODE_L2_ETH_RPC=http://validator-el:8545 + - MORPH_NODE_L2_ENGINE_RPC=http://validator-el:8551 - MORPH_NODE_L2_ENGINE_AUTH=${JWT_SECRET_PATH} ## todo need to replace it to a public network - MORPH_NODE_L1_ETH_RPC=${L1_ETH_RPC} @@ -470,7 +470,7 @@ services: - TX_SUBMITTER_BUILD_ENV=dev - TX_SUBMITTER_L1_ETH_RPC=${L1_ETH_RPC} - TX_SUBMITTER_L1_PRIVATE_KEY=0xd99870855d97327d20c666abc78588f1449b1fac76ed0c86c1afb9ce2db85f32 - - TX_SUBMITTER_L2_ETH_RPCS=http://morph-geth-0:8545,http://morph-geth-1:8545 + - TX_SUBMITTER_L2_ETH_RPCS=http://morph-el-0:8545,http://morph-el-1:8545 - TX_SUBMITTER_MAX_BATCH_BUILD_TIME=60s - TX_SUBMITTER_MAX_TX_SIZE=125952 - TX_SUBMITTER_POLL_INTERVAL=3s @@ -513,7 +513,7 @@ services: - TX_SUBMITTER_BUILD_ENV=dev - TX_SUBMITTER_L1_ETH_RPC=${L1_ETH_RPC} - TX_SUBMITTER_L1_PRIVATE_KEY=0x0890c388c3bf5e04fee1d8f3c117e5f44f435ced7baf7bfd66c10e1f3a3f4b10 - - TX_SUBMITTER_L2_ETH_RPCS=http://morph-geth-0:8545,http://morph-geth-1:8545 + - TX_SUBMITTER_L2_ETH_RPCS=http://morph-el-0:8545,http://morph-el-1:8545 - TX_SUBMITTER_MAX_BATCH_BUILD_TIME=60s - TX_SUBMITTER_MAX_TX_SIZE=125952 - TX_SUBMITTER_POLL_INTERVAL=3s @@ -556,7 +556,7 @@ services: - TX_SUBMITTER_BUILD_ENV=dev - TX_SUBMITTER_L1_ETH_RPC=${L1_ETH_RPC} - TX_SUBMITTER_L1_PRIVATE_KEY=0x6fd437eef7a83c486bd2e0a802ae071b3912d125ac31ac08f60841fd891559ae - - TX_SUBMITTER_L2_ETH_RPCS=http://morph-geth-2:8545,http://morph-geth-3:8545 + - TX_SUBMITTER_L2_ETH_RPCS=http://morph-el-2:8545,http://morph-el-3:8545 - TX_SUBMITTER_MAX_BATCH_BUILD_TIME=60s - TX_SUBMITTER_MAX_TX_SIZE=125952 - TX_SUBMITTER_POLL_INTERVAL=3s @@ -599,7 +599,7 @@ services: - TX_SUBMITTER_BUILD_ENV=dev - TX_SUBMITTER_L1_ETH_RPC=${L1_ETH_RPC} - TX_SUBMITTER_L1_PRIVATE_KEY=0x9ae53aecdaebe4dcbfec96f3123a2a8c53f9596bf4b3d5adc9a388ccb361b4c0 - - TX_SUBMITTER_L2_ETH_RPCS=http://morph-geth-2:8545,http://morph-geth-3:8545 + - TX_SUBMITTER_L2_ETH_RPCS=http://morph-el-2:8545,http://morph-el-3:8545 - TX_SUBMITTER_MAX_BATCH_BUILD_TIME=60s - TX_SUBMITTER_MAX_TX_SIZE=125952 - TX_SUBMITTER_POLL_INTERVAL=3s @@ -641,7 +641,7 @@ services: environment: - GAS_ORACLE_L1_RPC=${L1_ETH_RPC} - GAS_ORACLE_L1_BEACON_RPC=${L1_BEACON_CHAIN_RPC} - - GAS_ORACLE_L2_RPC=http://morph-geth-0:8545 + - GAS_ORACLE_L2_RPC=http://morph-el-0:8545 - GAS_THRESHOLD=5 - INTERVAL=28000 - L2_GAS_PRICE_ORACLE=0x530000000000000000000000000000000000000F diff --git a/ops/docker/docker-compose-reth.yml b/ops/docker/docker-compose-reth.yml new file mode 100644 index 000000000..7a9d0420c --- /dev/null +++ b/ops/docker/docker-compose-reth.yml @@ -0,0 +1,69 @@ +x-reth-command: &reth-command + - node + - --chain + - /genesis.json + - --datadir + - /db + - --http + - --http.addr + - 0.0.0.0 + - --http.port + - "8545" + - --http.api + - web3,debug,eth,txpool,net,trace,admin,reth + - --ws + - --ws.addr + - 0.0.0.0 + - --ws.port + - "8546" + - --ws.api + - web3,debug,eth,txpool,net,trace,admin,reth + - --authrpc.addr + - 0.0.0.0 + - --authrpc.port + - "8551" + - --authrpc.jwtsecret + - /jwt-secret.txt + - --disable-nat + - --disable-discovery + - --engine.persistence-threshold + - "256" + - --engine.memory-block-buffer-target + - "16" + - --engine.persistence-backpressure-threshold + - "512" + +x-reth-service: &reth-service + image: morph-reth:latest + user: "0:0" + entrypoint: + - ${MORPH_RETH_ENTRYPOINT:-/app/morph-reth} + command: *reth-command + +services: + morph-el-0: + <<: *reth-service + build: + context: ${MORPH_RETH_DIR:-../../../morph-reth} + dockerfile: Dockerfile + target: ${MORPH_RETH_DOCKER_TARGET:-builder} + args: + BUILD_PROFILE: ${MORPH_RETH_BUILD_PROFILE:-release} + RUSTFLAGS: ${MORPH_RETH_RUSTFLAGS:-} + + morph-el-1: + <<: *reth-service + + morph-el-2: + <<: *reth-service + + morph-el-3: + <<: *reth-service + + sentry-el-0: + <<: *reth-service + + validator-el: + <<: *reth-service + healthcheck: + disable: true diff --git a/ops/docker/static-nodes.json b/ops/docker/static-nodes.json index 2142637e3..7502f805e 100644 --- a/ops/docker/static-nodes.json +++ b/ops/docker/static-nodes.json @@ -1,5 +1,5 @@ -["enode://58e698ea2dd8a76e0cb185d13c1faabf223b60c89fef988c8b89496571056d6c2922109537bb291cd87f2ec09a23ac37d59bde2c7a4885d07b7b641cadff2921@morph-geth-0:30303", - "enode://bd755ce0bc8c06b4444b9013e8d1215a02e2b53f39f746f060c292ba2f6877d7b702374f006a49a7b1506bf1bc027b43824859d081283e6bac97c8600cdf3fee@morph-geth-1:30303", - "enode://c91a993ace50749c89d37d554f12b2f4937d2ecca0232695bb33772d95a01f53564ad9dd71465c229be21e231e5c46929c2adaa78bea9d5f0966c46fca327c46@morph-geth-2:30303", - "enode://7211a9f1d896d6fef69154b97a868f1ac59e178eadfa54c3fc9644fa0f25ba2a0771927acdc08bb1d6ae2ea7a64f7ed9ddd74e97472e7d2e0df66dae5608fb10@morph-geth-3:30303" +["enode://58e698ea2dd8a76e0cb185d13c1faabf223b60c89fef988c8b89496571056d6c2922109537bb291cd87f2ec09a23ac37d59bde2c7a4885d07b7b641cadff2921@morph-el-0:30303", + "enode://bd755ce0bc8c06b4444b9013e8d1215a02e2b53f39f746f060c292ba2f6877d7b702374f006a49a7b1506bf1bc027b43824859d081283e6bac97c8600cdf3fee@morph-el-1:30303", + "enode://c91a993ace50749c89d37d554f12b2f4937d2ecca0232695bb33772d95a01f53564ad9dd71465c229be21e231e5c46929c2adaa78bea9d5f0966c46fca327c46@morph-el-2:30303", + "enode://7211a9f1d896d6fef69154b97a868f1ac59e178eadfa54c3fc9644fa0f25ba2a0771927acdc08bb1d6ae2ea7a64f7ed9ddd74e97472e7d2e0df66dae5608fb10@morph-el-3:30303" ] \ No newline at end of file diff --git a/oracle/docker-compose.yml b/oracle/docker-compose.yml index 18e6e8b2c..6612f321f 100644 --- a/oracle/docker-compose.yml +++ b/oracle/docker-compose.yml @@ -13,7 +13,7 @@ services: - STAKING_ORACLE_BUILD_ENV=dev - STAKING_ORACLE_L1_ETH_RPC=${L1_ETH_RPC} - STAKING_ORACLE_RECORD_PRIVATE_KEY=${RECORD_PRIVATE_KEY} - - STAKING_ORACLE_L2_ETH_RPC=http://morph-geth-0:8545 + - STAKING_ORACLE_L2_ETH_RPC=http://morph-el-0:8545 - STAKING_ORACLE_L2_TENDERMINT_RPC=http://node-0:26657 - STAKING_ORACLE_L2_WS_ENDPOINT=http://node-0:26656 - STAKING_ORACLE_ROLLUP=${MORPH_ROLLUP:-0x6900000000000000000000000000000000000010} From 67128c8795762544f768397aa3bd9261394519f7 Mon Sep 17 00:00:00 2001 From: panos-xyz Date: Thu, 7 May 2026 22:09:41 +0800 Subject: [PATCH 03/10] use published reth image by default --- Makefile | 26 +++++++++++++-- ops/docker/docker-compose-reth.yml | 52 ++++++++---------------------- 2 files changed, 37 insertions(+), 41 deletions(-) diff --git a/Makefile b/Makefile index 2ff3a00b5..c26c638dd 100644 --- a/Makefile +++ b/Makefile @@ -138,11 +138,19 @@ go-ubuntu-builder: ################## devnet 4 nodes #################### EXECUTION_CLIENT ?= geth +MORPH_RETH_BUILD_FROM_SOURCE ?= false +ifeq ($(MORPH_RETH_BUILD_FROM_SOURCE),true) +MORPH_RETH_IMAGE ?= morph-reth:latest +MORPH_RETH_ENTRYPOINT ?= /app/morph-reth +else +MORPH_RETH_IMAGE ?= ghcr.io/morph-l2/morph-reth:latest +MORPH_RETH_ENTRYPOINT ?= /usr/local/bin/morph-reth +endif MORPH_RETH_DIR ?= ../morph-reth MORPH_RETH_BUILD_PROFILE ?= release MORPH_RETH_RUSTFLAGS ?= MORPH_RETH_DOCKER_TARGET ?= builder -MORPH_RETH_ENTRYPOINT ?= /app/morph-reth +export MORPH_RETH_IMAGE export MORPH_RETH_DIR export MORPH_RETH_BUILD_PROFILE export MORPH_RETH_RUSTFLAGS @@ -153,8 +161,12 @@ DEVNET_COMPOSE_FILES := -f docker-compose-4nodes.yml ifeq ($(EXECUTION_CLIENT),geth) DEVNET_EXECUTION_DEPS := submodules else ifeq ($(EXECUTION_CLIENT),reth) -DEVNET_EXECUTION_DEPS := reth DEVNET_COMPOSE_FILES += -f docker-compose-reth.yml +ifeq ($(MORPH_RETH_BUILD_FROM_SOURCE),true) +DEVNET_EXECUTION_DEPS := reth +else +DEVNET_EXECUTION_DEPS := reth-image +endif else $(error unsupported EXECUTION_CLIENT "$(EXECUTION_CLIENT)", expected "geth" or "reth") endif @@ -185,6 +197,10 @@ devnet-clean-build: devnet-l1-clean rm -rf ops/docker/execution/reth .PHONY: devnet-clean-build +devnet-clean-build-reth: + $(MAKE) devnet-clean-build EXECUTION_CLIENT=reth +.PHONY: devnet-clean-build-reth + devnet-clean: devnet-clean-build docker image ls '*morph*' --format='{{.Repository}}' | xargs -r docker rmi docker image ls '*sentry-*' --format='{{.Repository}}' | xargs -r docker rmi @@ -201,9 +217,13 @@ devnet-logs: @(cd ops/docker && docker compose $(DEVNET_COMPOSE_FILES) logs -f) .PHONY: devnet-logs +reth-image: + docker pull "$(MORPH_RETH_IMAGE)" +.PHONY: reth-image + reth: @test -d "$(MORPH_RETH_DIR)" || (echo "morph-reth directory not found: $(MORPH_RETH_DIR)" && exit 1) - docker build -t morph-reth:latest --target "$(MORPH_RETH_DOCKER_TARGET)" --build-arg BUILD_PROFILE="$(MORPH_RETH_BUILD_PROFILE)" --build-arg RUSTFLAGS="$(MORPH_RETH_RUSTFLAGS)" "$(MORPH_RETH_DIR)" + docker build -t "$(MORPH_RETH_IMAGE)" --target "$(MORPH_RETH_DOCKER_TARGET)" --build-arg BUILD_PROFILE="$(MORPH_RETH_BUILD_PROFILE)" --build-arg RUSTFLAGS="$(MORPH_RETH_RUSTFLAGS)" "$(MORPH_RETH_DIR)" .PHONY: reth # tx-submitter diff --git a/ops/docker/docker-compose-reth.yml b/ops/docker/docker-compose-reth.yml index 7a9d0420c..920c8af98 100644 --- a/ops/docker/docker-compose-reth.yml +++ b/ops/docker/docker-compose-reth.yml @@ -1,55 +1,31 @@ x-reth-command: &reth-command - node - - --chain - - /genesis.json - - --datadir - - /db + - --chain=/genesis.json + - --datadir=/db - --http - - --http.addr - - 0.0.0.0 - - --http.port - - "8545" - - --http.api - - web3,debug,eth,txpool,net,trace,admin,reth + - --http.addr=0.0.0.0 + - --http.port=8545 + - --http.api=web3,debug,eth,txpool,net,trace,admin,reth - --ws - - --ws.addr - - 0.0.0.0 - - --ws.port - - "8546" - - --ws.api - - web3,debug,eth,txpool,net,trace,admin,reth - - --authrpc.addr - - 0.0.0.0 - - --authrpc.port - - "8551" - - --authrpc.jwtsecret - - /jwt-secret.txt - - --disable-nat + - --ws.addr=0.0.0.0 + - --ws.port=8546 + - --ws.api=web3,debug,eth,txpool,net,trace,admin,reth + - --authrpc.addr=0.0.0.0 + - --authrpc.port=8551 + - --authrpc.jwtsecret=/jwt-secret.txt + - --nat=none - --disable-discovery - - --engine.persistence-threshold - - "256" - - --engine.memory-block-buffer-target - - "16" - - --engine.persistence-backpressure-threshold - - "512" x-reth-service: &reth-service - image: morph-reth:latest + image: ${MORPH_RETH_IMAGE:-ghcr.io/morph-l2/morph-reth:latest} user: "0:0" entrypoint: - - ${MORPH_RETH_ENTRYPOINT:-/app/morph-reth} + - ${MORPH_RETH_ENTRYPOINT:-/usr/local/bin/morph-reth} command: *reth-command services: morph-el-0: <<: *reth-service - build: - context: ${MORPH_RETH_DIR:-../../../morph-reth} - dockerfile: Dockerfile - target: ${MORPH_RETH_DOCKER_TARGET:-builder} - args: - BUILD_PROFILE: ${MORPH_RETH_BUILD_PROFILE:-release} - RUSTFLAGS: ${MORPH_RETH_RUSTFLAGS:-} morph-el-1: <<: *reth-service From 74eed9eb5da8bbfe60bb04ae22dd6d71cb76a891 Mon Sep 17 00:00:00 2001 From: panos-xyz Date: Thu, 7 May 2026 22:24:53 +0800 Subject: [PATCH 04/10] remove devnet execution client test --- .../test_devnet_execution_client.py | 21 ------------------- 1 file changed, 21 deletions(-) delete mode 100644 ops/devnet-morph/test_devnet_execution_client.py diff --git a/ops/devnet-morph/test_devnet_execution_client.py b/ops/devnet-morph/test_devnet_execution_client.py deleted file mode 100644 index 167a15bb0..000000000 --- a/ops/devnet-morph/test_devnet_execution_client.py +++ /dev/null @@ -1,21 +0,0 @@ -import unittest -from pathlib import Path -import sys - -sys.path.insert(0, str(Path(__file__).resolve().parent)) -from devnet import compose_file_args - - -class ExecutionClientComposeArgsTest(unittest.TestCase): - def test_geth_uses_base_compose_file(self): - self.assertEqual(compose_file_args("geth"), ["-f", "docker-compose-4nodes.yml"]) - - def test_reth_adds_reth_override_file(self): - self.assertEqual( - compose_file_args("reth"), - ["-f", "docker-compose-4nodes.yml", "-f", "docker-compose-reth.yml"], - ) - - -if __name__ == "__main__": - unittest.main() From d2bb14ec16bf7ce1b0fc0cf9182cd81164b94504 Mon Sep 17 00:00:00 2001 From: panos Date: Fri, 8 May 2026 10:55:58 +0800 Subject: [PATCH 05/10] chore(docker-sequencer-test): rename bitget to polyrepo Replace the internal codename "bitget" with the neutral term "polyrepo" in build context references, variable names, and container paths. --- .../Dockerfile.l2-geth-test | 2 +- .../Dockerfile.l2-node-test | 36 +++++++++---------- ops/docker-sequencer-test/run-test.sh | 14 ++++---- 3 files changed, 26 insertions(+), 26 deletions(-) diff --git a/ops/docker-sequencer-test/Dockerfile.l2-geth-test b/ops/docker-sequencer-test/Dockerfile.l2-geth-test index 1c053f44b..17de81dd1 100644 --- a/ops/docker-sequencer-test/Dockerfile.l2-geth-test +++ b/ops/docker-sequencer-test/Dockerfile.l2-geth-test @@ -1,5 +1,5 @@ # Build Geth for Sequencer Test -# Build context should be bitget/ (parent of morph) +# Build context should be the polyrepo root (parent of morph) FROM ghcr.io/morph-l2/go-ubuntu-builder:go-1.24-ubuntu AS builder # Copy local go-ethereum (not submodule) diff --git a/ops/docker-sequencer-test/Dockerfile.l2-node-test b/ops/docker-sequencer-test/Dockerfile.l2-node-test index 1ece1eb81..c7ce80847 100644 --- a/ops/docker-sequencer-test/Dockerfile.l2-node-test +++ b/ops/docker-sequencer-test/Dockerfile.l2-node-test @@ -5,33 +5,33 @@ FROM ghcr.io/morph-l2/go-ubuntu-builder:go-1.24-ubuntu AS builder # Order matters for cache efficiency # Copy go-ethereum dependency files -COPY ./go-ethereum/go.mod ./go-ethereum/go.sum /bitget/go-ethereum/ +COPY ./go-ethereum/go.mod ./go-ethereum/go.sum /polyrepo/go-ethereum/ # Copy tendermint dependency files -COPY ./tendermint/go.mod ./tendermint/go.sum /bitget/tendermint/ +COPY ./tendermint/go.mod ./tendermint/go.sum /polyrepo/tendermint/ # Copy morph go.work and all module dependency files -COPY ./morph/go.work ./morph/go.work.sum /bitget/morph/ -COPY ./morph/node/go.mod ./morph/node/go.sum /bitget/morph/node/ -COPY ./morph/bindings/go.mod ./morph/bindings/go.sum /bitget/morph/bindings/ -COPY ./morph/contracts/go.mod ./morph/contracts/go.sum /bitget/morph/contracts/ -COPY ./morph/oracle/go.mod ./morph/oracle/go.sum /bitget/morph/oracle/ -COPY ./morph/tx-submitter/go.mod ./morph/tx-submitter/go.sum /bitget/morph/tx-submitter/ -COPY ./morph/ops/l2-genesis/go.mod ./morph/ops/l2-genesis/go.sum /bitget/morph/ops/l2-genesis/ -COPY ./morph/ops/tools/go.mod ./morph/ops/tools/go.sum /bitget/morph/ops/tools/ -COPY ./morph/token-price-oracle/go.mod ./morph/token-price-oracle/go.sum /bitget/morph/token-price-oracle/ +COPY ./morph/go.work ./morph/go.work.sum /polyrepo/morph/ +COPY ./morph/node/go.mod ./morph/node/go.sum /polyrepo/morph/node/ +COPY ./morph/bindings/go.mod ./morph/bindings/go.sum /polyrepo/morph/bindings/ +COPY ./morph/contracts/go.mod ./morph/contracts/go.sum /polyrepo/morph/contracts/ +COPY ./morph/oracle/go.mod ./morph/oracle/go.sum /polyrepo/morph/oracle/ +COPY ./morph/tx-submitter/go.mod ./morph/tx-submitter/go.sum /polyrepo/morph/tx-submitter/ +COPY ./morph/ops/l2-genesis/go.mod ./morph/ops/l2-genesis/go.sum /polyrepo/morph/ops/l2-genesis/ +COPY ./morph/ops/tools/go.mod ./morph/ops/tools/go.sum /polyrepo/morph/ops/tools/ +COPY ./morph/token-price-oracle/go.mod ./morph/token-price-oracle/go.sum /polyrepo/morph/token-price-oracle/ # Download dependencies (this layer is cached if go.mod/go.sum don't change) -WORKDIR /bitget/morph/node +WORKDIR /polyrepo/morph/node RUN go mod download -x # Now copy all source code -COPY ./go-ethereum /bitget/go-ethereum -COPY ./tendermint /bitget/tendermint -COPY ./morph /bitget/morph +COPY ./go-ethereum /polyrepo/go-ethereum +COPY ./tendermint /polyrepo/tendermint +COPY ./morph /polyrepo/morph # Build (no need to download again, just compile) -WORKDIR /bitget/morph/node +WORKDIR /polyrepo/morph/node RUN make build # Final Stage @@ -41,7 +41,7 @@ RUN apt-get -qq update \ && apt-get -qq install -y --no-install-recommends ca-certificates \ && rm -rf /var/lib/apt/lists/* -COPY --from=builder /bitget/morph/node/build/bin/tendermint /usr/local/bin/ -COPY --from=builder /bitget/morph/node/build/bin/morphnode /usr/local/bin/ +COPY --from=builder /polyrepo/morph/node/build/bin/tendermint /usr/local/bin/ +COPY --from=builder /polyrepo/morph/node/build/bin/morphnode /usr/local/bin/ CMD ["morphnode", "--home", "/data"] diff --git a/ops/docker-sequencer-test/run-test.sh b/ops/docker-sequencer-test/run-test.sh index 9b0f0a553..d1928de7e 100755 --- a/ops/docker-sequencer-test/run-test.sh +++ b/ops/docker-sequencer-test/run-test.sh @@ -6,7 +6,7 @@ set -e SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" MORPH_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)" -BITGET_ROOT="$(cd "$MORPH_ROOT/.." && pwd)" +POLYREPO_ROOT="$(cd "$MORPH_ROOT/.." && pwd)" OPS_DIR="$MORPH_ROOT/ops" DOCKER_DIR="$OPS_DIR/docker" DEVNET_DIR="$OPS_DIR/devnet-morph" @@ -87,17 +87,17 @@ set_upgrade_height() { } # Build test images (with -test suffix) -# Uses bitget/ as build context to access local go-ethereum and tendermint +# Uses the polyrepo root as build context to access local go-ethereum and tendermint build_test_images() { log_info "Building test Docker images..." - log_info "Using build context: $BITGET_ROOT" - + log_info "Using build context: $POLYREPO_ROOT" + # Build go-ubuntu-builder if needed cd "$MORPH_ROOT" make go-ubuntu-builder - - # Build from bitget/ directory to access all repos - cd "$BITGET_ROOT" + + # Build from the polyrepo root to access all repos + cd "$POLYREPO_ROOT" # # Copy go module cache to avoid network downloads # if [ -d "$HOME/go/pkg/mod" ]; then From 1672b69a1c4228f31203623d6c0434895c0b8c13 Mon Sep 17 00:00:00 2001 From: panos Date: Fri, 8 May 2026 10:56:58 +0800 Subject: [PATCH 06/10] docs(devnet): add docstring to compose_file_args --- ops/devnet-morph/devnet/__init__.py | 1 + 1 file changed, 1 insertion(+) diff --git a/ops/devnet-morph/devnet/__init__.py b/ops/devnet-morph/devnet/__init__.py index 3fc3bff79..92b92f8cb 100644 --- a/ops/devnet-morph/devnet/__init__.py +++ b/ops/devnet-morph/devnet/__init__.py @@ -33,6 +33,7 @@ def compose_file_args(execution_client): + """Return docker-compose -f flags for the chosen L2 execution client.""" args = ['-f', 'docker-compose-4nodes.yml'] if execution_client == 'reth': args.extend(['-f', 'docker-compose-reth.yml']) From 4a2e1f3f809cf5ef3e66b8536430b7425e37e0e2 Mon Sep 17 00:00:00 2001 From: panos Date: Fri, 8 May 2026 11:22:19 +0800 Subject: [PATCH 07/10] docs(devnet): add docstring to devnet_deploy --- ops/devnet-morph/devnet/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ops/devnet-morph/devnet/__init__.py b/ops/devnet-morph/devnet/__init__.py index 92b92f8cb..ebc73e2b7 100644 --- a/ops/devnet-morph/devnet/__init__.py +++ b/ops/devnet-morph/devnet/__init__.py @@ -154,8 +154,8 @@ def devnet_build(paths): }) -# Bring up the devnet where the contracts are deployed to L1 def devnet_deploy(paths, args): + """Bring up the devnet where the contracts are deployed to L1.""" if not test_port(9545): devnet_l1(paths) done_file = pjoin(paths.devnet_dir, 'done') From f9327506c49074ba2291721e98e0e478746372d9 Mon Sep 17 00:00:00 2001 From: panos Date: Fri, 8 May 2026 11:32:05 +0800 Subject: [PATCH 08/10] docs(devnet): add docstrings to remaining functions Cover the rest of the file with one-line docstrings to satisfy CodeRabbit's docstring coverage threshold. --- ops/devnet-morph/devnet/__init__.py | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/ops/devnet-morph/devnet/__init__.py b/ops/devnet-morph/devnet/__init__.py index ebc73e2b7..d7b5b8f01 100644 --- a/ops/devnet-morph/devnet/__init__.py +++ b/ops/devnet-morph/devnet/__init__.py @@ -41,11 +41,15 @@ def compose_file_args(execution_client): class Bunch: + """Lightweight attribute container constructed from keyword arguments.""" + def __init__(self, **kwds): + """Store all keyword arguments as attributes on the instance.""" self.__dict__.update(kwds) def main(): + """Entry point: parse CLI arguments and bring up the L1-only or full devnet.""" args = parser.parse_args() polyrepo_dir = os.path.abspath(args.polyrepo_dir) @@ -82,6 +86,7 @@ def main(): def devnet_l1(paths, result=None): + """Start the L1 execution/consensus/validator stack and fund sequencer accounts.""" log.info('Starting L1.') layer1_dir = pjoin(paths.ops_dir, 'layer1') @@ -147,6 +152,7 @@ def devnet_l1(paths, result=None): def devnet_build(paths): + """Build the docker images declared in docker-compose-4nodes.yml.""" run_command(['docker', 'compose', '-f', 'docker-compose-4nodes.yml', 'build'], cwd=paths.ops_dir, env={ 'PWD': paths.ops_dir, 'DOCKER_BUILDKIT': '1', # (should be available by default in later versions, but explicitly enable it anyway) @@ -286,6 +292,7 @@ def devnet_deploy(paths, args): def wait_for_rpc_server(url): + """Block until the JSON-RPC server at url answers an eth_chainId call successfully.""" log.info(f'Waiting for RPC server at {url}') conn = http.client.HTTPConnection(url) @@ -306,6 +313,7 @@ def wait_for_rpc_server(url): def run_command(args, check=True, shell=False, cwd=None, env=None, output=None): + """Run a subprocess with the parent environment merged with the supplied env dict.""" env = env if env else {} return subprocess.run( args, @@ -323,6 +331,7 @@ def run_command(args, check=True, shell=False, cwd=None, env=None, output=None): def run_command_capture_output(args, check=True, shell=False, cwd=None, env=None): + """Run a subprocess and return its CompletedProcess with stdout/stderr captured.""" env = env if env else {} return subprocess.run( args, @@ -339,6 +348,7 @@ def run_command_capture_output(args, check=True, shell=False, cwd=None, env=None def wait_up(port, retries=10, wait_secs=1): + """Poll a TCP port on 127.0.0.1 until it accepts a connection or retries are exhausted.""" for i in range(0, retries): log.info(f'Trying 127.0.0.1:{port}') s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) @@ -354,6 +364,7 @@ def wait_up(port, retries=10, wait_secs=1): def test_port(port): + """Return True if a TCP connection to 127.0.0.1:port succeeds, False otherwise.""" log.info(f'Testing 127.0.0.1:{port}') s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) try: @@ -366,16 +377,19 @@ def test_port(port): def write_json(path, data): + """Serialize data to path as indented JSON.""" with open(path, 'w+') as f: json.dump(data, f, indent=' ') def read_json(path): + """Load and return the JSON document stored at path.""" with open(path, 'r') as f: return json.load(f) def eth_accounts(url): + """Call eth_accounts on url and return the raw JSON-RPC response body.""" log.info(f'Fetch eth_accounts {url}') conn = http.client.HTTPConnection(url) headers = {'Content-type': 'application/json'} From 6d8d745d955b8b3a23de7c8667fe0fa73d9ad646 Mon Sep 17 00:00:00 2001 From: panos Date: Fri, 8 May 2026 14:40:48 +0800 Subject: [PATCH 09/10] fix(devnet): isolate geth build config to prevent reth from inheriting Dockerfile.l2-geth Move the morph-el-0 build: section from docker-compose-4nodes.yml into a dedicated docker-compose-geth-build.yml, included only when EXECUTION_CLIENT=geth. The reth overlay now sees no build: on morph-el-0, eliminating the risk of docker compose up building geth code and tagging it as the reth image when the reth image is absent. --- Makefile | 1 + ops/devnet-morph/devnet/__init__.py | 2 ++ ops/docker/docker-compose-4nodes.yml | 3 --- ops/docker/docker-compose-geth-build.yml | 5 +++++ 4 files changed, 8 insertions(+), 3 deletions(-) create mode 100644 ops/docker/docker-compose-geth-build.yml diff --git a/Makefile b/Makefile index c26c638dd..39b0eab6b 100644 --- a/Makefile +++ b/Makefile @@ -160,6 +160,7 @@ DEVNET_COMPOSE_FILES := -f docker-compose-4nodes.yml ifeq ($(EXECUTION_CLIENT),geth) DEVNET_EXECUTION_DEPS := submodules +DEVNET_COMPOSE_FILES += -f docker-compose-geth-build.yml else ifeq ($(EXECUTION_CLIENT),reth) DEVNET_COMPOSE_FILES += -f docker-compose-reth.yml ifeq ($(MORPH_RETH_BUILD_FROM_SOURCE),true) diff --git a/ops/devnet-morph/devnet/__init__.py b/ops/devnet-morph/devnet/__init__.py index d7b5b8f01..ce4f789a5 100644 --- a/ops/devnet-morph/devnet/__init__.py +++ b/ops/devnet-morph/devnet/__init__.py @@ -37,6 +37,8 @@ def compose_file_args(execution_client): args = ['-f', 'docker-compose-4nodes.yml'] if execution_client == 'reth': args.extend(['-f', 'docker-compose-reth.yml']) + elif execution_client == 'geth': + args.extend(['-f', 'docker-compose-geth-build.yml']) return args diff --git a/ops/docker/docker-compose-4nodes.yml b/ops/docker/docker-compose-4nodes.yml index 83d4f8b9e..180199ceb 100644 --- a/ops/docker/docker-compose-4nodes.yml +++ b/ops/docker/docker-compose-4nodes.yml @@ -122,9 +122,6 @@ services: layer1-el: condition: service_started image: morph-geth:latest - build: - context: ../.. - dockerfile: ops/docker/Dockerfile.l2-geth restart: unless-stopped ports: - "8545:8545" diff --git a/ops/docker/docker-compose-geth-build.yml b/ops/docker/docker-compose-geth-build.yml new file mode 100644 index 000000000..f8a3070ad --- /dev/null +++ b/ops/docker/docker-compose-geth-build.yml @@ -0,0 +1,5 @@ +services: + morph-el-0: + build: + context: ../.. + dockerfile: ops/docker/Dockerfile.l2-geth From 8a5fc0af223d75383b8446ab04904f1180c02665 Mon Sep 17 00:00:00 2001 From: panos Date: Fri, 8 May 2026 15:44:04 +0800 Subject: [PATCH 10/10] fix(devnet): reset reth inherited geth builds Keep the base devnet compose file self-contained for geth while using the reth overlay to explicitly reset inherited geth build definitions. Constraint: Do not include the devnet execution-client test file in this commit Rejected: Keep a separate geth build compose file | changes direct base compose usage Confidence: high Scope-risk: narrow --- Makefile | 1 - ops/devnet-morph/devnet/__init__.py | 2 -- ops/docker/docker-compose-4nodes.yml | 3 +++ ops/docker/docker-compose-geth-build.yml | 5 ----- ops/docker/docker-compose-reth.yml | 2 ++ 5 files changed, 5 insertions(+), 8 deletions(-) delete mode 100644 ops/docker/docker-compose-geth-build.yml diff --git a/Makefile b/Makefile index 39b0eab6b..c26c638dd 100644 --- a/Makefile +++ b/Makefile @@ -160,7 +160,6 @@ DEVNET_COMPOSE_FILES := -f docker-compose-4nodes.yml ifeq ($(EXECUTION_CLIENT),geth) DEVNET_EXECUTION_DEPS := submodules -DEVNET_COMPOSE_FILES += -f docker-compose-geth-build.yml else ifeq ($(EXECUTION_CLIENT),reth) DEVNET_COMPOSE_FILES += -f docker-compose-reth.yml ifeq ($(MORPH_RETH_BUILD_FROM_SOURCE),true) diff --git a/ops/devnet-morph/devnet/__init__.py b/ops/devnet-morph/devnet/__init__.py index ce4f789a5..d7b5b8f01 100644 --- a/ops/devnet-morph/devnet/__init__.py +++ b/ops/devnet-morph/devnet/__init__.py @@ -37,8 +37,6 @@ def compose_file_args(execution_client): args = ['-f', 'docker-compose-4nodes.yml'] if execution_client == 'reth': args.extend(['-f', 'docker-compose-reth.yml']) - elif execution_client == 'geth': - args.extend(['-f', 'docker-compose-geth-build.yml']) return args diff --git a/ops/docker/docker-compose-4nodes.yml b/ops/docker/docker-compose-4nodes.yml index 180199ceb..83d4f8b9e 100644 --- a/ops/docker/docker-compose-4nodes.yml +++ b/ops/docker/docker-compose-4nodes.yml @@ -122,6 +122,9 @@ services: layer1-el: condition: service_started image: morph-geth:latest + build: + context: ../.. + dockerfile: ops/docker/Dockerfile.l2-geth restart: unless-stopped ports: - "8545:8545" diff --git a/ops/docker/docker-compose-geth-build.yml b/ops/docker/docker-compose-geth-build.yml deleted file mode 100644 index f8a3070ad..000000000 --- a/ops/docker/docker-compose-geth-build.yml +++ /dev/null @@ -1,5 +0,0 @@ -services: - morph-el-0: - build: - context: ../.. - dockerfile: ops/docker/Dockerfile.l2-geth diff --git a/ops/docker/docker-compose-reth.yml b/ops/docker/docker-compose-reth.yml index 920c8af98..fecc42f89 100644 --- a/ops/docker/docker-compose-reth.yml +++ b/ops/docker/docker-compose-reth.yml @@ -26,6 +26,7 @@ x-reth-service: &reth-service services: morph-el-0: <<: *reth-service + build: !reset null morph-el-1: <<: *reth-service @@ -38,6 +39,7 @@ services: sentry-el-0: <<: *reth-service + build: !reset null validator-el: <<: *reth-service