Skip to content
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
19 changes: 19 additions & 0 deletions docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,25 @@ services:
volumes:
- ./docker/shared/volume:/volume/shared

op-challenger:
image: ghcr.io/uminetwork/op-challenger:${UMI_TAG:-latest}
build:
cache_from:
- type=registry,ref=ghcr.io/uminetwork/op-challenger:latest-cache
dockerfile: docker/shared/Dockerfile
target: op-challenger
env_file:
- .env
environment:
L1_RPC_URL: "http://geth:58138"
depends_on:
- geth
- op-proposer
networks:
- localnet
volumes:
- ./docker/shared/volume:/volume/shared

op-move:
image: ghcr.io/uminetwork/op-move-rep:${UMI_TAG:-latest}
build:
Expand Down
87 changes: 48 additions & 39 deletions docker/geth/deploy-optimism.sh
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,15 @@
# -x Print out command arguments during execution
# -a Export all variables
set -euxa
WORKDIR="/volume/packages/contracts-bedrock"
DEPLOY_CONFIG="${WORKDIR}/deploy-config/umi.json"
L1_DEPLOYMENT="${WORKDIR}/deployments/1337-deploy.json"
L2_ALLOCS="${WORKDIR}/state-dump-42069.json"
GENESIS_FILE="${WORKDIR}/deployments/genesis.json"
ROLLUP_FILE="${WORKDIR}/deployments/rollup.json"
WORKDIR="/volume"
GENESIS_FILE="${WORKDIR}/genesis.json"
ROLLUP_FILE="${WORKDIR}/rollup.json"
L1_GENESIS_FILE="${WORKDIR}/l1_genesis.json"
L1_DEPLOYMENT="${WORKDIR}/l1.json"
SHARED="/volume/shared"

# Remove existing output files in the shared volume
rm -f "${SHARED}/umi.json" "${SHARED}/1337-deploy.json" "${SHARED}/state-dump-42069.json" "${SHARED}/genesis.json" "${SHARED}/rollup.json"
rm -f "${SHARED}/l1.json" "${SHARED}/genesis.json" "${SHARED}/rollup.json" "${SHARED}/l1_genesis.json"

# Create datadir for geth
mkdir -p "${L1_DATADIR}"
Expand All @@ -35,39 +34,49 @@ cast publish --rpc-url "${L1_RPC_URL}" "${SIGNED_L1_CONTRACT_TX}"
# Wait for a finalized block with a positive timestamp
while [ "$(cast block finalized --rpc-url "${L1_RPC_URL}" | awk '/^timestamp/ { print $2 }')" -le 0 ]; do sleep 3; done

# Generate L2 genesis deploy config file
DEPLOY_CONFIG_PATH="${DEPLOY_CONFIG}" \
./config.sh
# Generate L1 genesis (trying it directly on datadir throws an error)
cp -r "${L1_DATADIR}" /tmp/geth-copy
geth dumpgenesis --datadir /tmp/geth-copy >"${L1_GENESIS_FILE}"

# Deploy Optimism L1 contracts
DEPLOYMENT_CONTEXT=umi \
DEPLOY_CONFIG_PATH="${DEPLOY_CONFIG}" \
IMPL_SALT=0000000000000000000000000000000000000000000000000000000000000000 \
forge script ${WORKDIR}/scripts/Deploy.s.sol:Deploy \
--root "${WORKDIR}" \
--private-key "${ADMIN_PRIVATE_KEY}" \
--broadcast \
--rpc-url "${L1_RPC_URL}" \
--slow \
--legacy \
--non-interactive

# Generate L2 genesis state dump
CONTRACT_ADDRESSES_PATH="${L1_DEPLOYMENT}" \
DEPLOY_CONFIG_PATH="${DEPLOY_CONFIG}" \
forge script ${WORKDIR}/scripts/L2Genesis.s.sol:L2Genesis \
--root "${WORKDIR}" \
--sig "runWithAllUpgrades()" \
--non-interactive

# Generate L2 genesis
op-node genesis l2 \
--deploy-config "${DEPLOY_CONFIG}" \
--l1-deployments "${L1_DEPLOYMENT}" \
--l2-allocs "${L2_ALLOCS}" \
--outfile.l2 "${GENESIS_FILE}" \
--outfile.rollup "${ROLLUP_FILE}" \
--l1-rpc "${L1_RPC_URL}"
op-deployer init --l2-chain-ids=42069 --l1-chain-id=1337 --intent-type custom

cp filled_intent.toml ./intent.toml

op-deployer bootstrap superchain \
--l1-rpc-url="${L1_RPC_URL}" \
--private-key="${ADMIN_PRIVATE_KEY}" \
--superchain-proxy-admin-owner "${ADMIN_ADDRESS}" \
--protocol-versions-owner "${ADMIN_ADDRESS}" \
--guardian "${ADMIN_ADDRESS}" \
--outfile superchain-output.json

SUPERCHAIN_PROXY_ADMIN=$(jq -r '.proxyAdminAddress' superchain-output.json)
SUPERCHAIN_CONFIG_PROXY=$(jq -r '.superchainConfigProxyAddress' superchain-output.json)
PROTOCOL_VERSIONS_PROXY=$(jq -r '.protocolVersionsProxyAddress' superchain-output.json)

op-deployer bootstrap implementations \
--l1-rpc-url="${L1_RPC_URL}" \
--private-key="${ADMIN_PRIVATE_KEY}" \
--upgrade-controller "${ADMIN_ADDRESS}" \
--challenger "${ADMIN_ADDRESS}" \
--superchain-config-proxy "${SUPERCHAIN_CONFIG_PROXY}" \
--protocol-versions-proxy "${PROTOCOL_VERSIONS_PROXY}" \
--superchain-proxy-admin "${SUPERCHAIN_PROXY_ADMIN}"

# Fill L2 genesis state dump
op-deployer apply \
--l1-rpc-url="${L1_RPC_URL}" \
--private-key="${ADMIN_PRIVATE_KEY}"

# Generate L2 genesis file
op-deployer inspect genesis 42069 >genesis.json

# Generate rollup file
op-deployer inspect rollup 42069 >rollup.json

# TODO: DGF address
op-deployer inspect l1 42069 >l1.json

# Copy output files in the shared volume
cp -f "${DEPLOY_CONFIG}" "${L2_ALLOCS}" "${L1_DEPLOYMENT}" "${GENESIS_FILE}" "${ROLLUP_FILE}" "${SHARED}/"
cp -f "${L1_DEPLOYMENT}" "${GENESIS_FILE}" "${ROLLUP_FILE}" "${L1_GENESIS_FILE}" "${SHARED}/"
6 changes: 3 additions & 3 deletions docker/geth/prefund.sh
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,13 @@ FROM_WALLET=$(ls l1_datadir/keystore | grep -o '.\{40\}$')
FACTORY_DEPLOYER_ADDRESS="0x3fAB184622Dc19b6109349B94811493BF2a45362"
NONCE=0

for _ in $(seq 10) ; do
for _ in $(seq 30); do
sleep 0.1
TX_HASH=$(curl "${L1_RPC_URL}" \
-s \
-X POST \
-H "Content-Type: application/json" \
--data "{\"method\":\"eth_sendTransaction\",\"params\":[{\"from\":\"0x${FROM_WALLET}\",\"to\":\"${ADMIN_ADDRESS}\",\"value\":\"0x8ac7230489e80000\",\"type\":\"0x2\",\"nonce\":\"$(printf "0x%x" ${NONCE})\"}],\"id\":1,\"jsonrpc\":\"2.0\"}" | jq .result)
--data "{\"method\":\"eth_sendTransaction\",\"params\":[{\"from\":\"0x${FROM_WALLET}\",\"to\":\"${ADMIN_ADDRESS}\",\"value\":\"0x8ac7230489e80000\",\"type\":\"0x2\",\"nonce\":\"$(printf "0x%x" ${NONCE})\"}],\"id\":1,\"jsonrpc\":\"2.0\"}" | jq .result)
echo "${TX_HASH}"
NONCE=$((NONCE + 1))

Expand All @@ -21,7 +21,7 @@ for _ in $(seq 10) ; do
-s \
-X POST \
-H "Content-Type: application/json" \
--data "{\"method\":\"eth_sendTransaction\",\"params\":[{\"from\":\"0x${FROM_WALLET}\",\"to\":\"${BATCHER_ADDRESS}\",\"value\":\"0x8ac7230489e80000\",\"type\":\"0x2\",\"nonce\":\"$(printf "0x%x" ${NONCE})\"}],\"id\":1,\"jsonrpc\":\"2.0\"}"
--data "{\"method\":\"eth_sendTransaction\",\"params\":[{\"from\":\"0x${FROM_WALLET}\",\"to\":\"${BATCHER_ADDRESS}\",\"value\":\"0x8ac7230489e80000\",\"type\":\"0x2\",\"nonce\":\"$(printf "0x%x" ${NONCE})\"}],\"id\":1,\"jsonrpc\":\"2.0\"}"
NONCE=$((NONCE + 1))

sleep 0.1
Expand Down
27 changes: 14 additions & 13 deletions docker/op-batcher/entrypoint.sh
Original file line number Diff line number Diff line change
Expand Up @@ -9,19 +9,20 @@ wait-for-it -t "${TIMEOUT_SECS}" "$(echo "${L2_RPC_URL}" | cut -c 8-)"
wait-for-it -t "${TIMEOUT_SECS}" "$(echo "${ROLLUP_RPC_URL}" | cut -c 8-)"

op-batcher \
--l2-eth-rpc "${L2_RPC_URL}" \
--rollup-rpc "${ROLLUP_RPC_URL}" \
--poll-interval 1s \
--sub-safety-margin 6 \
--num-confirmations 1 \
--safe-abort-nonce-too-low-count 3 \
--resubmission-timeout 30s \
--rpc.addr 0.0.0.0 \
--rpc.port 8548 \
--rpc.enable-admin \
--max-channel-duration 1 \
--private-key "${BATCHER_PRIVATE_KEY}" \
--l1-eth-rpc "${L1_RPC_URL}" &
--l2-eth-rpc "${L2_RPC_URL}" \
--rollup-rpc "${ROLLUP_RPC_URL}" \
--poll-interval 1s \
--sub-safety-margin 6 \
--num-confirmations 1 \
--safe-abort-nonce-too-low-count 3 \
--resubmission-timeout 30s \
--rpc.addr 0.0.0.0 \
--rpc.port 8548 \
--rpc.enable-admin \
--max-channel-duration 1 \
--private-key "${BATCHER_PRIVATE_KEY}" \
--l1-eth-rpc "${L1_RPC_URL}" \
--throttle.unsafe-da-bytes-lower-threshold 0 &

# Get the PID of the process launched in the background
PID="$!"
Expand Down
98 changes: 98 additions & 0 deletions docker/op-challenger/entrypoint.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
#!/bin/sh
# Lightweight challenger loop to mirror the integration test behaviour.
# Resolves claims for newly created games and finalizes them once ready.

set -eux

SHARED="/volume/shared"
L1_DEPLOYMENT="${SHARED}/l1.json"
RESOLVE_INTERVAL="${RESOLVE_INTERVAL:-30}"
CLAIM_RETRIES="${CLAIM_RETRIES:-6}"
CLAIM_RETRY_DELAY="${CLAIM_RETRY_DELAY:-10}"
TIMEOUT_SECS=1500

# Wait until geth is accepting connections
wait-for-it -t "${TIMEOUT_SECS}" "$(echo "${L1_RPC_URL}" | cut -c 8-)"

# DisputeGameFactoryProxy lives in the L1 deployment manifest produced by op-deployer
GAME_FACTORY_ADDRESS="$(jq -r '.DisputeGameFactoryProxy' "${L1_DEPLOYMENT}")"
if [ -z "${GAME_FACTORY_ADDRESS}" ] || [ "${GAME_FACTORY_ADDRESS}" = "null" ]; then
echo "Unable to read DisputeGameFactoryProxy from ${L1_DEPLOYMENT}" >&2
exit 1
fi

game_count() {
cast call "${GAME_FACTORY_ADDRESS}" "gameCount()(uint256)" --rpc-url "${L1_RPC_URL}" | tail -n1 | awk 'END{print $NF}' || return 1
}

game_address() {
addr="$(cast call "${GAME_FACTORY_ADDRESS}" "gameAtIndex(uint256)(uint32,uint64,address)" "$1" --rpc-url "${L1_RPC_URL}" | tail -n1 | awk '{print $NF}' || true)"
if [ -z "${addr}" ] || [ "${addr}" = "null" ]; then
echo "Failed to read game address at index $1" >&2
return 1
fi
echo "${addr}"
}

echo "Waiting for the first game to be created..."
until [ "$(game_count || echo 0)" -gt 0 ]; do
sleep 5
done

current_idx="${START_INDEX:-0}"
existing="$(game_count || true)"
if [ -n "${existing}" ] && [ "${existing}" -gt 0 ] && [ -z "${START_INDEX:-}" ]; then
current_idx=$((existing - 1))
fi

echo "Starting challenger from index ${current_idx} using factory ${GAME_FACTORY_ADDRESS}"

while true; do
total_games="$(game_count || echo 0)"
if [ "${current_idx}" -ge "${total_games}" ]; then
sleep "${RESOLVE_INTERVAL}"
continue
fi

address="$(game_address "${current_idx}")" || {
sleep "${RESOLVE_INTERVAL}"
continue
}
echo "Processing game ${current_idx} at ${address}"

attempt=0
claim_ok=0
until [ "${attempt}" -ge "${CLAIM_RETRIES}" ]; do
if op-challenger resolve-claim \
--l1-eth-rpc "${L1_RPC_URL}" \
--game-address "${address}" \
--claim 0 \
--private-key "${ADMIN_PRIVATE_KEY}"; then
echo "Resolved claim 0 for ${address}"
claim_ok=1
break
fi

attempt=$((attempt + 1))
echo "Game not ready yet, retrying (${attempt}/${CLAIM_RETRIES})..."
sleep "${CLAIM_RETRY_DELAY}"
done

if [ "${claim_ok}" -ne 1 ]; then
echo "Could not resolve claim for ${address} after retries, will retry later"
sleep "${CLAIM_RETRY_DELAY}"
continue
fi

if ! op-challenger resolve \
--l1-eth-rpc "${L1_RPC_URL}" \
--game-address "${address}" \
--private-key "${ADMIN_PRIVATE_KEY}"; then
echo "Resolve failed for ${address}, will retry later"
sleep "${CLAIM_RETRY_DELAY}"
continue
fi

current_idx=$((current_idx + 1))
sleep "${RESOLVE_INTERVAL}"
done
2 changes: 1 addition & 1 deletion docker/op-move/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ RUN --mount=type=cache,target=/usr/local/cargo/git \
# RocksDB breaks the build with libclang.so not found https://github.com/apache/skywalking/issues/10439
# Aptos-core breaks the build with `disable_lifo_slot` not found https://github.com/aptos-labs/aptos-core/issues/5655 \
RUSTFLAGS="-C target-feature=-crt-static --cfg tokio_unstable" \
cargo build --bin op-move --release --features storage \
cargo build --bin op-move --release --features storage,op-upgrade \
# Copy binary out of target directory, else it's removed by the cache mount
&& mv target/release/op-move /volume/op-move

Expand Down
11 changes: 10 additions & 1 deletion docker/op-move/entrypoint.sh
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
set -eux
SHARED="/volume/shared"
GENESIS_FILE="${SHARED}/genesis.json"
STATE_ROOT_FILE="${SHARED}/genesis_root.txt"
TIMEOUT_SECS=1500

# Wait for geth to become online
Expand All @@ -12,7 +13,15 @@ wait-for-it -t "${TIMEOUT_SECS}" "$(echo "${L1_RPC_URL}" | cut -c 8-)"
# Wait for geth to deploy Optimism
while [ ! -f "${GENESIS_FILE}" ]; do sleep 1; done

/volume/op-move --genesis.l2-contract-genesis "${GENESIS_FILE}" &
# Compute genesis state root
/volume/op-move \
--genesis.l2-contract-genesis "${GENESIS_FILE}" \
--genesis.print-initial-state-root true | head -n2 | tail -n1 > $STATE_ROOT_FILE

# Run op-move with correct root
/volume/op-move \
--genesis.l2-contract-genesis "${GENESIS_FILE}" \
--genesis.initial-state-root $(cat $STATE_ROOT_FILE) &

# Get the PID of the geth process launched in the background
PID="$!"
Expand Down
19 changes: 12 additions & 7 deletions docker/op-node-rep/entrypoint.sh
Original file line number Diff line number Diff line change
Expand Up @@ -6,18 +6,22 @@ WORKDIR="/volume"
SHARED="${WORKDIR}/shared"
P2P_DIR="${WORKDIR}/host/p2p"
ROLLUP_FILE="${SHARED}/rollup.json"
L1_GENESIS_FILE="${SHARED}/l1_genesis.json"
JWT_FILE="${WORKDIR}/jwt.txt"
TIMEOUT_SECS=1500
PEER_RPC="http://${PEER_ADDR}:${PEER_RPC_PORT}"

# Dump JWT secret token to a file that gets passed as op-node CLI argument
echo "${JWT_SECRET}" > "${JWT_FILE}"
echo "${JWT_SECRET}" >"${JWT_FILE}"

# Make dir for persistent P2P data
mkdir -p ${P2P_DIR}

# Wait for op-move to serve the genesis block
while [ "$(cast block 0 --rpc-url "${L2_RPC_HTTP_URL}" >/dev/null 2>&1 ; echo $?)" -ne 0 ]; do sleep 1; done
while [ "$(
cast block 0 --rpc-url "${L2_RPC_HTTP_URL}" >/dev/null 2>&1
echo $?
)" -ne 0 ]; do sleep 1; done

# Wait for geth to deploy Optimism
while [ ! -f "${ROLLUP_FILE}" ]; do sleep 1; done
Expand All @@ -27,13 +31,13 @@ wait-for-it -t "${TIMEOUT_SECS}" "${PEER_ADDR}:${PEER_RPC_PORT}"

# Parse peer P2P parameters, wait for PEER_ENR to contain IP (test by length)
while
PEER_P2P=$(curl -X POST -H "Content-Type: application/json" --data '{"jsonrpc":"2.0","method":"opp2p_self","params":[],"id":1}' "${PEER_RPC}");
PEER_ENR=$(echo "${PEER_P2P}" | sed -e 's/.*\"ENR\"\:\"//g' | sed -e 's/\".*//g');
[ ${#PEER_ENR} -lt 220 ];
PEER_P2P=$(curl -X POST -H "Content-Type: application/json" --data '{"jsonrpc":"2.0","method":"opp2p_self","params":[],"id":1}' "${PEER_RPC}")
PEER_ENR=$(echo "${PEER_P2P}" | sed -e 's/.*\"ENR\"\:\"//g' | sed -e 's/\".*//g')
[ ${#PEER_ENR} -lt 220 ]
do sleep 5; done

# Set peer manually
PEER_ID=$(echo "${PEER_P2P}" | sed -e 's/.*\"peerID\"\:\"//g' | sed -e 's/\".*//g');
PEER_ID=$(echo "${PEER_P2P}" | sed -e 's/.*\"peerID\"\:\"//g' | sed -e 's/\".*//g')
PEER_IP=$(nc -vz "${PEER_ADDR}" "${PEER_P2P_PORT}" 2>&1 | cut -d '(' -f2 | cut -d ':' -f1)
P2P_STATIC="/ip4/${PEER_IP}/tcp/${PEER_P2P_PORT}/p2p/${PEER_ID}"
P2P_BOOTNODES="${PEER_ENR}"
Expand All @@ -59,7 +63,8 @@ op-node \
--p2p.static "${P2P_STATIC}" \
--p2p.priv.path "${P2P_DIR}/priv.txt" \
--p2p.peerstore.path "${P2P_DIR}/peerstore_db" \
--p2p.discovery.path "${P2P_DIR}/discovery_db" &
--p2p.discovery.path "${P2P_DIR}/discovery_db" \
--rollup.l1-chain-config "${L1_GENESIS_FILE}" &

# Get the PID of the process launched in the background
PID="$!"
Expand Down
Loading