Skip to content

Commit

Permalink
Merge pull request #94 from tokamak-network/OR-1440-resolved-devnet-i…
Browse files Browse the repository at this point in the history
…ssue

Or 1440 resolved devnet issue
  • Loading branch information
ohbyeongmin authored Mar 18, 2024
2 parents 5158072 + 1d9c390 commit 2b68be3
Show file tree
Hide file tree
Showing 2 changed files with 113 additions and 20 deletions.
2 changes: 1 addition & 1 deletion .gethrc
Original file line number Diff line number Diff line change
@@ -1 +1 @@
v1.13.4
v1.13.14
131 changes: 112 additions & 19 deletions bedrock-devnet/devnet/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,15 @@
import time
import shutil
import http.client
import codecs
import ecdsa
import glob
import shutil
from Crypto.Hash import keccak
from multiprocessing import Process, Queue
import concurrent.futures
from collections import namedtuple


import devnet.log_setup

pjoin = os.path.join
Expand All @@ -23,6 +27,7 @@
parser.add_argument('--allocs', help='Only create the allocs and exit', type=bool, action=argparse.BooleanOptionalAction)
parser.add_argument('--test', help='Tests the deployment, must already be deployed', type=bool, action=argparse.BooleanOptionalAction)
parser.add_argument('--legacy', help='Legacy(using eth) or not(apply native token)', type=bool, action=argparse.BooleanOptionalAction)
parser.add_argument('--admin-key', help='The admin private key for upgrade contracts', type=str, default=os.environ.get('DEVNET_ADMIN_PRIVATE_KEY'))

log = logging.getLogger()

Expand Down Expand Up @@ -65,6 +70,7 @@ def main():
devnet_config_template_path = pjoin(deploy_config_dir, 'devnetL1-template.json')
ops_chain_ops = pjoin(monorepo_dir, 'op-chain-ops')
sdk_dir = pjoin(monorepo_dir, 'packages', 'tokamak', 'sdk') if not args.legacy else pjoin(monorepo_dir, 'packages', 'sdk')
bedrock_devnet_dir = pjoin(monorepo_dir, 'bedrock-devnet')

paths = Bunch(
mono_repo_dir=monorepo_dir,
Expand All @@ -84,9 +90,16 @@ def main():
allocs_path=pjoin(devnet_dir, 'allocs-l1.json'),
addresses_json_path=pjoin(devnet_dir, 'addresses.json'),
sdk_addresses_json_path=pjoin(devnet_dir, 'sdk-addresses.json'),
rollup_config_path=pjoin(devnet_dir, 'rollup.json')
rollup_config_path=pjoin(devnet_dir, 'rollup.json'),
bedrock_devnet_path=bedrock_devnet_dir,
admin_key=args.admin_key
)

if paths.admin_key is not None :
verify_admin_key(paths)
if not os.path.exists(pjoin(paths.bedrock_devnet_path, 'data')):
init_admin_geth(paths)

if args.test:
log.info('Testing deployed devnet')
devnet_test(paths)
Expand All @@ -95,8 +108,8 @@ def main():
os.makedirs(devnet_dir, exist_ok=True)

if args.allocs:
devnet_l1_genesis(paths)
return
devnet_l1_genesis(paths)
return

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()
Expand All @@ -117,22 +130,23 @@ def main():
log.info('Devnet starting')
devnet_deploy(paths)


def deploy_contracts(paths):
wait_up(8545)
wait_for_rpc_server('127.0.0.1:8545')
res = eth_accounts('127.0.0.1:8545')

response = json.loads(res)
account = response['result'][0]
account = response['result'][0 if paths.admin_key is None else 1]
log.info(f'Deploying with {account}')

# send some ether to the create2 deployer account
run_command([
'cast', 'send', '--from', account,
cmd = [
'cast', 'send',
'--rpc-url', 'http://127.0.0.1:8545',
'--unlocked', '--value', '1ether', '0x3fAB184622Dc19b6109349B94811493BF2a45362'
], env={}, cwd=paths.contracts_bedrock_dir)
'--value', '1ether', '0x3fAB184622Dc19b6109349B94811493BF2a45362'
]
cmd.extend(['--from', account, '--unlocked']) if paths.admin_key is None else cmd.extend(['--password', '1234'])
run_command(cmd, env={}, cwd=paths.contracts_bedrock_dir)

# deploy the create2 deployer
run_command([
Expand All @@ -141,11 +155,12 @@ def deploy_contracts(paths):
], env={}, cwd=paths.contracts_bedrock_dir)

fqn = 'scripts/Deploy.s.sol:Deploy'
run_command([
'forge', 'script', fqn, '--sender', account,
'--rpc-url', 'http://127.0.0.1:8545', '--broadcast',
'--unlocked'
], env={}, cwd=paths.contracts_bedrock_dir)
cmd = [
'forge', 'script', fqn,
'--rpc-url', 'http://127.0.0.1:8545', '--broadcast'
]
cmd.extend(['--sender', account, '--unlocked']) if paths.admin_key is None else cmd.extend(['--private-key', paths.admin_key])
run_command(cmd, env={}, cwd=paths.contracts_bedrock_dir)

shutil.copy(paths.l1_deployments_path, paths.addresses_json_path)

Expand All @@ -162,6 +177,56 @@ def init_devnet_l1_deploy_config(paths, update_timestamp=False):
deploy_config['l1GenesisBlockTimestamp'] = '{:#x}'.format(int(time.time()))
write_json(paths.devnet_config_path, deploy_config)

def init_admin_geth(paths):
deploy_config = read_json(paths.devnet_config_template_path)
admin_address = deploy_config['finalSystemOwner']

f = open(pjoin(paths.bedrock_devnet_path, 'genesis.json'), "w+")
run_command([
'geth', '--dev', 'dumpgenesis'
], cwd=paths.bedrock_devnet_path, stdout=f)
f.close()

genesis = read_json(pjoin(paths.bedrock_devnet_path, 'genesis.json'))

genesis["config"]["chainId"] = 900

alloc = genesis['alloc']
alloc[admin_address] = {
"balance": "10000000000000000000"
}
genesis['alloc'] = alloc

write_file(pjoin(paths.bedrock_devnet_path, 'keystore'), paths.admin_key[2:])
write_file(pjoin(paths.bedrock_devnet_path, 'password'), '1234')

write_json(pjoin(paths.bedrock_devnet_path, 'genesis.json'), genesis)
geth_init(paths)
os.environ.setdefault(
key = 'GETH_DATADIR',
value = 'data',
)

key_store = pjoin(paths.bedrock_devnet_path, 'data', 'keystore')
key_file = glob.glob(f"{key_store}/*{admin_address[2:].lower()}*")
os.environ.setdefault(
key = 'ETH_KEYSTORE',
value = pjoin(paths.bedrock_devnet_path, 'data', 'keystore', key_file[0])
)


def geth_init(paths):
run_command([
'geth', '--dev', '--datadir', 'data', 'init', 'genesis.json'
], cwd=paths.bedrock_devnet_path)

run_command([
'geth', '--datadir', 'data', '--password', 'password', 'account', 'import', 'keystore'
], cwd=paths.bedrock_devnet_path)
delete_file(pjoin(paths.bedrock_devnet_path, 'keystore'))
delete_file(pjoin(paths.bedrock_devnet_path, 'password'))
delete_file(pjoin(paths.bedrock_devnet_path, 'genesis.json'))

def devnet_l1_genesis(paths):
log.info('Generating L1 genesis state')
init_devnet_l1_deploy_config(paths)
Expand All @@ -170,7 +235,7 @@ def devnet_l1_genesis(paths):
'geth', '--dev', '--dev.period', '2', '--http', '--http.api', 'eth,debug',
'--verbosity', '4', '--gcmode', 'archive', '--dev.gaslimit', '30000000',
'--rpc.allow-unprotected-txs'
])
], cwd=pjoin(paths.mono_repo_dir, 'bedrock-devnet'))

try:
forge = ChildProcess(deploy_contracts, paths)
Expand Down Expand Up @@ -260,6 +325,8 @@ def devnet_deploy(paths):
'PWD': paths.ops_bedrock_dir
})

shutil.rmtree(pjoin(paths.bedrock_devnet_path, 'data'), ignore_errors=True)

log.info('Devnet ready.')


Expand All @@ -274,7 +341,6 @@ def eth_accounts(url):
conn.close()
return data


def debug_dumpBlock(url):
log.info(f'Fetch debug_dumpBlock {url}')
conn = http.client.HTTPConnection(url)
Expand Down Expand Up @@ -369,7 +435,7 @@ def run_command_preset(command: CommandPreset):
return proc.returncode


def run_command(args, check=True, shell=False, cwd=None, env=None, timeout=None):
def run_command(args, check=True, shell=False, cwd=None, env=None, timeout=None, stdout=None):
env = env if env else {}
return subprocess.run(
args,
Expand All @@ -380,7 +446,8 @@ def run_command(args, check=True, shell=False, cwd=None, env=None, timeout=None)
**env
},
cwd=cwd,
timeout=timeout
timeout=timeout,
stdout=stdout
)


Expand All @@ -407,3 +474,29 @@ def write_json(path, data):
def read_json(path):
with open(path, 'r') as f:
return json.load(f)

def write_file(path, data):
f = open(path, 'w+')
f.write(data)
f.close()

def delete_file(path):
os.remove(path)

def verify_admin_key(paths):
admin_key=paths.admin_key

private_key_bytes = codecs.decode(admin_key[2:], 'hex')
pulbic_key = ecdsa.SigningKey.from_string(private_key_bytes, curve=ecdsa.SECP256k1).verifying_key
public_key_bytes = pulbic_key.to_string()
keccak_hash = keccak.new(digest_bits=256)
keccak_hash.update(public_key_bytes)
keccak_digest = keccak_hash.hexdigest()
admin_len = 40
admin = '0x' + keccak_digest[-admin_len:]

deploy_config = read_json(paths.devnet_config_template_path)
finalSystemOwner = deploy_config['finalSystemOwner']

if admin.lower() != finalSystemOwner.lower():
raise Exception("the admin key is invalid.")

0 comments on commit 2b68be3

Please sign in to comment.