Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

devnet: devnet-test and CI improvements #7788

Merged
merged 4 commits into from
Oct 26, 2023
Merged
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
1 change: 1 addition & 0 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -1031,6 +1031,7 @@ jobs:
image: ubuntu-2204:2022.10.2
environment:
DOCKER_BUILDKIT: 1
DEVNET_NO_BUILD: 'true'
steps:
- checkout
- check-changed:
Expand Down
87 changes: 69 additions & 18 deletions bedrock-devnet/devnet/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@
import shutil
import http.client
from multiprocessing import Process, Queue
import concurrent.futures
from collections import namedtuple


import devnet.log_setup

Expand Down Expand Up @@ -97,14 +100,18 @@ def main():
git_commit = subprocess.run(['git', 'rev-parse', 'HEAD'], capture_output=True, text=True).stdout.strip()
git_date = subprocess.run(['git', 'show', '-s', "--format=%ct"], capture_output=True, text=True).stdout.strip()

log.info(f'Building docker images for git commit {git_commit} ({git_date})')
run_command(['docker', 'compose', 'build', '--progress', 'plain',
'--build-arg', f'GIT_COMMIT={git_commit}', '--build-arg', f'GIT_DATE={git_date}'],
cwd=paths.ops_bedrock_dir, env={
'PWD': paths.ops_bedrock_dir,
'DOCKER_BUILDKIT': '1', # (should be available by default in later versions, but explicitly enable it anyway)
'COMPOSE_DOCKER_CLI_BUILD': '1' # use the docker cache
})
# CI loads the images from workspace, and does not otherwise know the images are good as-is
if os.getenv('DEVNET_NO_BUILD') == "true":
log.info('Skipping docker images build')
else:
log.info(f'Building docker images for git commit {git_commit} ({git_date})')
run_command(['docker', 'compose', 'build', '--progress', 'plain',
'--build-arg', f'GIT_COMMIT={git_commit}', '--build-arg', f'GIT_DATE={git_date}'],
cwd=paths.ops_bedrock_dir, env={
'PWD': paths.ops_bedrock_dir,
'DOCKER_BUILDKIT': '1', # (should be available by default in later versions, but explicitly enable it anyway)
'COMPOSE_DOCKER_CLI_BUILD': '1' # use the docker cache
})

log.info('Devnet starting')
devnet_deploy(paths)
Expand Down Expand Up @@ -297,24 +304,68 @@ def wait_for_rpc_server(url):
log.info(f'Waiting for RPC server at {url}')
time.sleep(1)


CommandPreset = namedtuple('Command', ['name', 'args', 'cwd', 'timeout'])


def devnet_test(paths):
# Check the L2 config
run_command(
['go', 'run', 'cmd/check-l2/main.go', '--l2-rpc-url', 'http://localhost:9545', '--l1-rpc-url', 'http://localhost:8545'],
cwd=paths.ops_chain_ops,
)

run_command(
['npx', 'hardhat', 'deposit-erc20', '--network', 'devnetL1', '--l1-contracts-json-path', paths.addresses_json_path],
cwd=paths.sdk_dir,
timeout=8*60,
)
# Run the two commands with different signers, so the ethereum nonce management does not conflict
# And do not use devnet system addresses, to avoid breaking fee-estimation or nonce values.
run_commands([
CommandPreset('erc20-test',
['npx', 'hardhat', 'deposit-erc20', '--network', 'devnetL1',
'--l1-contracts-json-path', paths.addresses_json_path, '--signer-index', '14'],
cwd=paths.sdk_dir, timeout=8*60),
CommandPreset('eth-test',
['npx', 'hardhat', 'deposit-eth', '--network', 'devnetL1',
'--l1-contracts-json-path', paths.addresses_json_path, '--signer-index', '15'],
cwd=paths.sdk_dir, timeout=8*60)
], max_workers=2)


def run_commands(commands: list[CommandPreset], max_workers=2):
with concurrent.futures.ThreadPoolExecutor(max_workers=max_workers) as executor:
futures = [executor.submit(run_command_preset, cmd) for cmd in commands]

for future in concurrent.futures.as_completed(futures):
result = future.result()
if result:
print(result.stdout)


def run_command_preset(command: CommandPreset):
with subprocess.Popen(command.args, cwd=command.cwd,
stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True) as proc:
try:
# Live output processing
for line in proc.stdout:
# Annotate and print the line with timestamp and command name
timestamp = datetime.datetime.utcnow().strftime('%H:%M:%S.%f')
# Annotate and print the line with the timestamp
print(f"[{timestamp}][{command.name}] {line}", end='')

stdout, stderr = proc.communicate(timeout=command.timeout)

if proc.returncode != 0:
raise RuntimeError(f"Command '{' '.join(command.args)}' failed with return code {proc.returncode}: {stderr}")

except subprocess.TimeoutExpired:
raise RuntimeError(f"Command '{' '.join(command.args)}' timed out!")

except Exception as e:
raise RuntimeError(f"Error executing '{' '.join(command.args)}': {e}")

finally:
# Ensure process is terminated
proc.kill()
return proc.returncode

run_command(
['npx', 'hardhat', 'deposit-eth', '--network', 'devnetL1', '--l1-contracts-json-path', paths.addresses_json_path],
cwd=paths.sdk_dir,
timeout=8*60,
)

def run_command(args, check=True, shell=False, cwd=None, env=None, timeout=None):
env = env if env else {}
Expand Down
4 changes: 4 additions & 0 deletions ops-bedrock/docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@ services:
- "l1_data:/db"
- "${PWD}/../.devnet/genesis-l1.json:/genesis.json"
- "${PWD}/test-jwt-secret.txt:/config/test-jwt-secret.txt"
environment:
GETH_MINER_RECOMMIT: 100ms

l2:
build:
Expand All @@ -49,6 +51,8 @@ services:
- "/bin/sh"
- "/entrypoint.sh"
- "--authrpc.jwtsecret=/config/test-jwt-secret.txt"
environment:
GETH_MINER_RECOMMIT: 100ms

op-node:
depends_on:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
"cliqueSignerAddress": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266",
"l1UseClique": true,
"l1StartingBlockTag": "earliest",
"l2OutputOracleSubmissionInterval": 6,
"l2OutputOracleSubmissionInterval": 10,
"l2OutputOracleStartingTimestamp": 0,
"l2OutputOracleStartingBlockNumber": 0,
"l2OutputOracleProposer": "0x70997970C51812dc3A010C7d01b50e0d17dc79C8",
Expand Down
22 changes: 21 additions & 1 deletion packages/sdk/hardhat.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,27 @@ const config: HardhatUserConfig = {
devnetL1: {
url: 'http://localhost:8545',
accounts: [
'ac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80',
// warning: keys 0 - 12 (incl) are used by the system
'ac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80', // 0
'59c6995e998f97a5a0044966f0945389dc9e86dae88c7a8412f4603b6b78690d', // 1
'5de4111afa1a4b94908f83103eb1f1706367c2e68ca870fc3fb9a804cdab365a', // 2
'7c852118294e51e653712a81e05800f419141751be58f605c371e15141b007a6', // 3
'47e179ec197488593b187f80a00eb0da91f1b9d0b13f8733639f19c30a34926a', // 4
'8b3a350cf5c34c9194ca85829a2df0ec3153be0318b5e2d3348e872092edffba', // 5
'92db14e403b83dfe3df233f83dfa3a0d7096f21ca9b0d6d6b8d88b2b4ec1564e', // 6
'4bbbf85ce3377467afe5d46f804f221813b2bb87f24d81f60f1fcdbf7cbf4356', // 7
'dbda1821b80551c9d65939329250298aa3472ba22feea921c0cf5d620ea67b97', // 8
'2a871d0798f97d79848a013d4936a73bf4cc922c825d33c1cf7073dff6d409c6', // 9
'f214f2b2cd398c806f84e317254e0f0b801d0643303237d97a22a48e01628897', // 10
'701b615bbdfb9de65240bc28bd21bbc0d996645a3dd57e7b12bc2bdf6f192c82', // 11
'a267530f49f8280200edf313ee7af6b827f2a8bce2897751d06a843f644967b1', // 12
'47c99abed3324a2707c28affff1267e45918ec8c3f20b8aa892e8b065d2942dd', // 13
'c526ee95bf44d8fc405a158bb884d9d1238d99f0612e9f33d006bb0789009aaa', // 14
'8166f546bab6da521a8369cab06c5d2b9e46670292d85c875ee9ec20e84ffb61', // 15
'ea6c44ac03bff858b476bba40716402b03e41b8e97e276d1baec7c37d42484a0', // 16
'689af8efa8c651a91ad287602527f3af2fe9f6501a7ac4b061667b5a93e037fd', // 17
'de9be858da4a475276426320d5e9262ecfc3ba460bfac56360bfa6c4c28b4ee0', // 18
'df57089febbacf7ba0bc227dafbffa9fc08a93fdc68e1e42411a14efcf23656e', // 19
],
},
hivenet: {
Expand Down
16 changes: 9 additions & 7 deletions packages/sdk/tasks/deposit-erc20.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { promises as fs } from 'fs'

import { task, types } from 'hardhat/config'
import { HardhatRuntimeEnvironment } from 'hardhat/types'
import { SignerWithAddress } from '@nomiclabs/hardhat-ethers/signers'
import '@nomiclabs/hardhat-ethers'
import 'hardhat-deploy'
import { Event, Contract, Wallet, providers, utils, ethers } from 'ethers'
Expand All @@ -27,11 +28,9 @@ import {

const deployWETH9 = async (
hre: HardhatRuntimeEnvironment,
signer: SignerWithAddress,
wrap: boolean
): Promise<Contract> => {
const signers = await hre.ethers.getSigners()
const signer = signers[0]

const Factory__WETH9 = new hre.ethers.ContractFactory(
Artifact__WETH9.abi,
Artifact__WETH9.bytecode.object,
Expand Down Expand Up @@ -117,13 +116,16 @@ task('deposit-erc20', 'Deposits WETH9 onto L2.')
'',
types.string
)
.addOptionalParam('signerIndex', 'Index of signer to use', 0, types.int)
.setAction(async (args, hre) => {
const signers = await hre.ethers.getSigners()
if (signers.length === 0) {
throw new Error('No configured signers')
}
// Use the first configured signer for simplicity
const signer = signers[0]
if (args.signerIndex < 0 || signers.length <= args.signerIndex) {
throw new Error('Invalid signer index')
}
const signer = signers[args.signerIndex]
const address = await signer.getAddress()
console.log(`Using signer ${address}`)

Expand All @@ -137,7 +139,7 @@ task('deposit-erc20', 'Deposits WETH9 onto L2.')
const l2Provider = new providers.StaticJsonRpcProvider(args.l2ProviderUrl)

const l2Signer = new hre.ethers.Wallet(
hre.network.config.accounts[0],
hre.network.config.accounts[args.signerIndex],
l2Provider
)

Expand Down Expand Up @@ -219,7 +221,7 @@ task('deposit-erc20', 'Deposits WETH9 onto L2.')
console.log(params)

console.log('Deploying WETH9 to L1')
const WETH9 = await deployWETH9(hre, true)
const WETH9 = await deployWETH9(hre, signer, true)
console.log(`Deployed to ${WETH9.address}`)

console.log('Creating L2 WETH9')
Expand Down
9 changes: 6 additions & 3 deletions packages/sdk/tasks/deposit-eth.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,14 +50,17 @@ task('deposit-eth', 'Deposits ether to L2.')
'',
types.string
)
.addOptionalParam('signerIndex', 'Index of signer to use', 0, types.int)
.addOptionalParam('withdrawAmount', 'Amount to withdraw', '', types.string)
.setAction(async (args, hre) => {
const signers = await hre.ethers.getSigners()
if (signers.length === 0) {
throw new Error('No configured signers')
}
// Use the first configured signer for simplicity
const signer = signers[0]
if (args.signerIndex < 0 || signers.length <= args.signerIndex) {
throw new Error('Invalid signer index')
}
const signer = signers[args.signerIndex]
const address = await signer.getAddress()
console.log(`Using signer ${address}`)

Expand All @@ -81,7 +84,7 @@ task('deposit-eth', 'Deposits ether to L2.')
: amount.div(2)

const l2Signer = new hre.ethers.Wallet(
hre.network.config.accounts[0],
hre.network.config.accounts[args.signerIndex],
l2Provider
)

Expand Down