Skip to content

Commit 415ca28

Browse files
FletcherManfletcher.fan
andauthored
ops: refactor layer1 for devnet tools (#802)
Co-authored-by: fletcher.fan <[email protected]>
1 parent 3e02ce8 commit 415ca28

File tree

82 files changed

+908
-147
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

82 files changed

+908
-147
lines changed

Makefile

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -147,7 +147,7 @@ devnet-down:
147147
cd ops/docker && docker compose -f docker-compose-4nodes.yml down
148148
.PHONY: devnet-down
149149

150-
devnet-clean-build: devnet-down
150+
devnet-clean-build: devnet-down devnet-l1-clean
151151
docker volume ls --filter name=docker-* --format='{{.Name}}' | xargs -r docker volume rm
152152
rm -rf ops/l2-genesis/.devnet
153153
rm -rf ops/docker/.devnet
@@ -163,6 +163,10 @@ devnet-clean: devnet-clean-build
163163
devnet-l1:
164164
python3 ops/devnet-morph/main.py --polyrepo-dir=. --only-l1
165165

166+
devnet-l1-clean:
167+
@cd ops/docker && ./layer1/scripts/clean.sh
168+
.PHONY: devnet-l1-clean
169+
166170
devnet-logs:
167171
@(cd ops/docker && docker-compose logs -f)
168172
.PHONY: devnet-logs

ops/devnet-morph/devnet/__init__.py

Lines changed: 69 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -73,21 +73,51 @@ def main():
7373

7474
def devnet_l1(paths, result=None):
7575
log.info('Starting L1.')
76-
run_command(['docker', 'compose', '-f', 'docker-compose-4nodes.yml', 'build', '--no-cache', 'l1'], check=False,
77-
cwd=paths.ops_dir, env={
76+
77+
layer1_dir = pjoin(paths.ops_dir, 'layer1')
78+
genesis_dir = pjoin(layer1_dir, 'genesis')
79+
jwt_dir = pjoin(layer1_dir, 'jwt')
80+
81+
# Check if genesis files exist, if not generate them
82+
genesis_json = pjoin(genesis_dir, 'genesis.json')
83+
genesis_ssz = pjoin(genesis_dir, 'genesis.ssz')
84+
jwt_secret = pjoin(jwt_dir, 'jwtsecret')
85+
86+
if not os.path.exists(genesis_json) or not os.path.exists(genesis_ssz) or not os.path.exists(jwt_secret):
87+
log.info('Genesis files not found, generating...')
88+
generate_script = pjoin(layer1_dir, 'scripts', 'generate-genesis.sh')
89+
if os.path.exists(generate_script):
90+
run_command(['bash', generate_script], check=True, cwd=layer1_dir)
91+
else:
92+
log.error(f'Genesis generation script not found at {generate_script}')
93+
raise FileNotFoundError(f'Genesis generation script not found')
94+
95+
# Start layer1 services
96+
log.info('Starting layer1 services (layer1-el, layer1-cl, layer1-vc)...')
97+
run_command(['docker', 'compose', '-f', 'docker-compose-4nodes.yml', 'up', '-d',
98+
'layer1-el', 'layer1-cl', 'layer1-vc'], check=False, cwd=paths.ops_dir, env={
7899
'PWD': paths.ops_dir
79100
})
80-
run_command(['docker', 'compose', '-f', 'docker-compose-4nodes.yml', 'up', '-d', 'l1'], check=False,
81-
cwd=paths.ops_dir, env={
82-
'PWD': paths.ops_dir
83-
})
84-
wait_up(9545)
101+
102+
# Wait for EL node to be ready
103+
log.info('Waiting for layer1-el to be ready...')
104+
wait_up(9545, retries=60, wait_secs=2)
85105
wait_for_rpc_server('127.0.0.1:9545')
86-
log.info('Sleep another 10s...')
87-
time.sleep(10)
88-
res = eth_accounts('127.0.0.1:9545')
89-
response = json.loads(res)
90-
account = response['result'][0]
106+
107+
# Wait for first block to be mined
108+
log.info('Waiting for first block to be mined...')
109+
max_retries = 60
110+
retry_count = 0
111+
while retry_count < max_retries:
112+
block_number = eth_blockNumber('127.0.0.1:9545')
113+
if block_number is not None and block_number >= 1:
114+
log.info(f'First block mined! Current block number: {block_number}')
115+
break
116+
retry_count += 1
117+
log.info(f'Waiting for first block (current: {block_number if block_number is not None else "N/A"})...')
118+
time.sleep(3)
119+
else:
120+
log.warning('Timeout waiting for first block to be mined')
91121

92122
devnet_cfg_orig = pjoin(paths.deploy_config_dir, 'devnet-deploy-config.json')
93123
deploy_config = read_json(devnet_cfg_orig)
@@ -97,7 +127,7 @@ def devnet_l1(paths, result=None):
97127
log.info(f"Account {sequencer}, Balance: {result.stdout}", )
98128

99129
if int(result.stdout) < 5 * ETH:
100-
log.info(f'Insufficient Sequencer: {sequencer}, Founding with account: {account}')
130+
log.info(f'Insufficient Sequencer: {sequencer}, Founding')
101131
run_command([
102132
'cast', 'send', '--private-key', deploy_config['BLOCK_SIGNER_PRIVATE_KEY'],
103133
'--rpc-url', 'http://127.0.0.1:9545',
@@ -238,8 +268,8 @@ def devnet_deploy(paths, args):
238268
'NODE_DATA_DIR': '/data',
239269
'GETH_DATA_DIR': '/db',
240270
'GENESIS_FILE_PATH': '/genesis.json',
241-
'L1_ETH_RPC': 'http://l1:8545',
242-
'L1_BEACON_CHAIN_RPC': 'http://beacon-chain:3500',
271+
'L1_ETH_RPC': 'http://layer1-el:8545',
272+
'L1_BEACON_CHAIN_RPC': 'http://layer1-cl:4000',
243273
})
244274
wait_up(8545)
245275
wait_for_rpc_server('127.0.0.1:8545')
@@ -345,3 +375,27 @@ def eth_accounts(url):
345375
data = response.read().decode()
346376
conn.close()
347377
return data
378+
379+
380+
def eth_blockNumber(url):
381+
"""
382+
Call eth_blockNumber JSON-RPC method to get the current block number.
383+
Returns the block number as an integer, or None on error.
384+
"""
385+
try:
386+
conn = http.client.HTTPConnection(url)
387+
headers = {'Content-type': 'application/json'}
388+
body = '{"id":1, "jsonrpc":"2.0", "method": "eth_blockNumber", "params":[]}'
389+
conn.request('POST', '/', body, headers)
390+
response = conn.getresponse()
391+
data = response.read().decode()
392+
conn.close()
393+
result = json.loads(data)
394+
if 'result' in result:
395+
# Convert hex string (e.g., "0x1") to integer
396+
block_number_hex = result['result']
397+
return int(block_number_hex, 16)
398+
return None
399+
except Exception as e:
400+
log.debug(f'Error calling eth_blockNumber: {e}')
401+
return None

ops/docker/.env

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@ GETH_DATA_DIR=/db
22
GENESIS_FILE_PATH=/genesis.json
33
JWT_SECRET_PATH=/jwt-secret.txt
44
NODE_DATA_DIR=/data
5-
L1_ETH_RPC=http://l1:8545
6-
L1_BEACON_CHAIN_RPC=http://beacon-chain:3500
5+
L1_ETH_RPC=http://layer1-el:8545
6+
L1_BEACON_CHAIN_RPC=http://layer1-cl:4000
77
L1_CROSS_DOMAIN_MESSENGER=0xcf7ed3acca5a467e9e704c703e8d87f634fb0fc9
88
MORPH_PORTAL=0xdc64a140aa3e981100a9beca4e685f962f0cf6c9
99
MORPH_ROLLUP=0x0165878a594ca255338adfa4d48449f69242eb8f

ops/docker/Makefile.layer1

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
.PHONY: help generate start stop restart logs clean
2+
3+
help:
4+
@echo "Available commands:"
5+
@echo " make generate - Generate genesis data and keystores"
6+
@echo " make start - Start network"
7+
@echo " make stop - Stop network"
8+
@echo " make restart - Restart network"
9+
@echo " make logs - View logs"
10+
@echo " make clean - Clean all generated data and reset to initial state"
11+
12+
generate:
13+
@./layer1/scripts/generate-genesis.sh
14+
15+
start:
16+
@./layer1/scripts/start.sh
17+
18+
stop:
19+
@docker compose -f docker-compose-4nodes.yml down
20+
21+
restart: stop start
22+
23+
logs:
24+
@docker compose -f docker-compose-4nodes.yml logs -f layer1-el layer1-cl layer1-vc
25+
26+
clean:
27+
@./layer1/scripts/clean.sh

0 commit comments

Comments
 (0)