-
Notifications
You must be signed in to change notification settings - Fork 2
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
Espresso migration #46
Changes from 47 commits
631874a
26ac754
73735d4
66f137b
2591c33
853a470
03cfd37
4d7f7d4
dc9f43b
1a12259
1d62c1f
8faf6d4
8d890c3
8fc2fb1
8572963
015cc1a
00490b2
5c576f6
804b034
7a1d231
f95942e
359b895
2fdf356
8e68bc8
f75e6bc
f7d2e02
ffd396e
d8322f3
90e12dd
4210058
64c026c
9d55ff3
78244ef
4037501
ee6519c
5813618
74222a3
c719f27
eec62f3
3721574
bbb8757
6b9cda3
775dbd3
60a1d61
1a43eaa
32c8a2f
aea5b46
b459a47
8b5d7f3
4d1068b
39e8496
71d78a1
c8fe3c5
46dbb2f
fd55f28
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,7 @@ | ||
[submodule "blockscout"] | ||
path = blockscout | ||
url = https://github.com/OffchainLabs/blockscout.git | ||
[submodule "orbit-actions"] | ||
path = orbit-actions | ||
url = [email protected]:EspressoSystems/orbit-actions.git | ||
branch = espresso-migration |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
# Environment variables for chain name and rpc_url | ||
# These are essential for the upgrade | ||
PARENT_CHAIN_CHAIN_ID="1337" | ||
CHILD_CHAIN_CHAIN_NAME="412346" | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I there a reason to call this "name"? It's also the chain ID. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. No, we can rename this. In my head chain name and chain id are interchangeable which is not the case for Arbitrum or Ethereum. |
||
PARENT_CHAIN_RPC_URL="http://localhost:8545" | ||
CHILD_CHAIN_RPC_URL="http://localhost:8547" | ||
# Environment variables for new OSP deployment | ||
# These are essential for the upgrade | ||
HOTSHOT_ADDRESS="0xb6eb235fa509e3206f959761d11e3777e16d0e98" | ||
PARENT_CHAIN_UPGRADE_EXECUTOR="0x513D9F96d4D0563DEbae8a0DC307ea0E46b10ed7" | ||
CHILD_CHAIN_UPGRADE_EXUCTOR_ADDRESS="0xD59870177729b1Fa7CCdA1d2E245C57C6ad5F9F6" | ||
# Environment variables for osp migration action contract | ||
CURRENT_OSP_ENTRY="0x9C2eD9F57D053FDfAEcBF1B6Dfd7C97e2e340B84" | ||
ROLLUP_ADDRESS="0x0DFDF1473B14D2330A40F6a42bb6d601DD121E6b" | ||
PROXY_ADMIN="0x2A1f38c9097e7883570e0b02BFBE6869Cc25d8a3" | ||
# Environment variables for ArbOS upgrade action. | ||
UPGRADE_TIMESTAMP="1723664126" | ||
|
||
NEW_WASM_MODULE_ROOT="0x2422802a7cda99737209430b103689205bc8e56eab8b08c6ad409e65e45c3145" | ||
CURRENT_WASM_MODULE_ROOT="0xbc1026ff45c20ea97e9e6057224a5668ea78d8f885c9b14fc849238e8ef5c5dc" | ||
|
||
#Environment variables used in test assertions | ||
CHALLENGE_MANAGER_ADDRESS="0x784FC11476F3d06801A76b944795E6367391b12e" |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
# Espresso Migration | ||
|
||
This document contains details surrounding the test migrating an exsisting Arbitrum Orbit chain to use the nitro-espresso-integration, and be compatible with the Espresso network. | ||
|
||
## Running the test | ||
|
||
Run the test by navigating to nitro-testnode/espresso-tests and run ./migration-test.bash | ||
|
||
|
||
## Steps related to upgrade in production | ||
|
||
Many of the steps in the test are nearly identical to the steps needed to upgrade an orbit network to be compatible with the espresso network. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think the instructions on how to carry out the upgrade should go into a new README in Let's link to this test from the new README in orbit-actions for the curious. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I agree and I'm actively working on a README in that repo. |
||
|
||
Any commands in the migration-test.bash file that have comments above them prefixed with the string `** Essential migration step **` are core parts of the migration. | ||
|
||
E.g. | ||
``` | ||
# ** Essential migration step ** Forge script to deploy new OSP entry. We do this to later point the rollups challenge manager to the espresso integrated OSP. | ||
forge script --chain $PARENT_CHAIN_CHAIN_ID contracts/parent-chain/contract-upgrades/DeployEspressoOsp.s.sol:DeployEspressoOsp --rpc-url $PARENT_CHAIN_RPC_URL --broadcast -vvvv | ||
``` | ||
|
||
Other steps, such as noting contract addresses, are technically part of these essential core steps. However, these steps are not marked with " ** Essential migration step ** ". In a real migration, these steps will likely not occur in a single bash script, or necessarily have the same process. | ||
|
||
These steps can be done manually while preparing the `** Essential migration step **` steps in whichever manner makes sense to the operators of the network doing their migration. Therefore they are marked with `* Essential migration sub step * `, and specific context is given as to how these steps may be different for operators. | ||
|
||
## Non upgrade related steps | ||
|
||
Steps that are not directly related to a real world example of this upgrade will be unmarked. That is comments about these steps will contain neither `** Essential migration step **` or `* Essential migration sub step *` |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
#!/usr/bin/env bash | ||
set -euo pipefail | ||
|
||
ESPRESSO_VERSION=ghcr.io/espressosystems/nitro-espresso-integration/nitro-node-dev:migration-test | ||
lightClientAddr=0xb6eb235fa509e3206f959761d11e3777e16d0e98 | ||
espresso=true | ||
|
||
# docker pull and tag the espresso integration nitro node. | ||
docker pull $ESPRESSO_VERSION | ||
|
||
docker tag $ESPRESSO_VERSION espresso-integration-testnode | ||
|
||
# write the espresso configs to the config volume | ||
echo == Writing configs | ||
docker compose run scripts-espresso write-config --simple --espresso $espresso --lightClientAddress $lightClientAddr | ||
|
||
# do whatever other espresso setup is needed. | ||
|
||
# run esprsso-integrated nitro node for sequencing. | ||
docker compose up sequencer-on-espresso --detach |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,182 @@ | ||
#!/usr/bin/env bash | ||
# This is a utility function for creating assertions at the end of this test. | ||
fail(){ | ||
echo "$*" 1>&2; exit 1; | ||
} | ||
|
||
set -euo pipefail | ||
set -a # automatically export all variables | ||
set -x # print each command before executing it, for debugging | ||
|
||
|
||
|
||
# Find directory of this script, the project, and the orbit-actions submodule | ||
TEST_DIR="$(dirname $(readlink -f $0))" | ||
TESTNODE_DIR="$(dirname "$TEST_DIR")" | ||
ORBIT_ACTIONS_DIR="$TESTNODE_DIR/orbit-actions" | ||
|
||
# Change to orbit actions directory, update the submodule, and install any dependencies for the purposes of the test. | ||
cd "$ORBIT_ACTIONS_DIR" | ||
|
||
git submodule update --init | ||
yarn | ||
|
||
# Change to the top level directory for the purposes of the test. | ||
cd "$TESTNODE_DIR" | ||
|
||
# Initialize a standard network not compatible with espresso to simulate a pre-upgrade orbit network e.g. not needed for the real migration | ||
./test-node.bash --simple --init-force --tokenbridge --detach | ||
|
||
# Start espresso sequencer node for the purposes of the test e.g. not needed for the real migration. | ||
docker compose up espresso-dev-node --detach | ||
|
||
# Export environment variables in .env file | ||
# A similar env file should be supplied for whatever | ||
. "$TEST_DIR/.env" | ||
|
||
# Overwrite the ROLLUP_ADDRESS for this test, it might not be the same as the one in the .env file | ||
#* Essential migration sub step * This address (the rollup proxy address) is likely a known address to operators. | ||
ROLLUP_ADDRESS=$(docker compose run --entrypoint cat scripts /config/deployed_chain_info.json | jq -r '.[0].rollup.rollup' | tail -n 1 | tr -d '\r\n') | ||
|
||
# A convoluted way to get the address of the child chain upgrade executor, maybe there's a better way? | ||
# These steps below are just for the purposes of the test. In a real deployment operators will likely already know their child-chain's upgrade executor address, and it should be included in a .env file for the migration run. | ||
INBOX_ADDRESS=$(docker compose run --entrypoint cat scripts /config/deployed_chain_info.json | jq -r '.[0].rollup.inbox' | tail -n 1 | tr -d '\r\n') | ||
L1_TOKEN_BRIDGE_CREATOR_ADDRESS=$(docker compose run --entrypoint cat scripts /tokenbridge-data/network.json | jq -r '.l1TokenBridgeCreator' | tail -n 1 | tr -d '\r\n') | ||
CHILD_CHAIN_UPGRADE_EXECUTOR_ADDRESS=$(cast call $L1_TOKEN_BRIDGE_CREATOR_ADDRESS 'inboxToL2Deployment(address)(address,address,address,address,address,address,address,address,address)' $INBOX_ADDRESS | tail -n 2 | head -n 1 | tr -d '\r\n') | ||
|
||
# Export l2 owner private key and address | ||
# These commands are exclusive to the test. | ||
# * Essential migration sub step * These addresses are likely known addresses to operators in the event of a real migration | ||
PRIVATE_KEY="$(docker compose run scripts print-private-key --account l2owner | tail -n 1 | tr -d '\r\n')" | ||
OWNER_ADDRESS="$(docker compose run scripts print-address --account l2owner | tail -n 1 | tr -d '\r\n')" | ||
|
||
# Echo for debug | ||
echo "Deploying Espresso Osp" | ||
# Change directory to orbit actions dir for the following commands. | ||
cd $ORBIT_ACTIONS_DIR | ||
# ** Essential migration step ** Forge script to deploy new OSP entry. We do this to later point the rollups challenge manager to the espresso integrated OSP. | ||
forge script --chain $PARENT_CHAIN_CHAIN_ID contracts/parent-chain/contract-upgrades/DeployEspressoOsp.s.sol:DeployEspressoOsp --rpc-url $PARENT_CHAIN_RPC_URL --broadcast -vvvv | ||
|
||
# Extract new_osp_entry address from run-latest.json | ||
# * Essential migration sub step * These addresses are likely known addresses to operators in the event of a real migration after they have deployed the new OSP contracts, however, if operators create a script for the migration, this command is useful. | ||
NEW_OSP_ENTRY=$(cat broadcast/DeployEspressoOsp.s.sol/1337/run-latest.json | jq -r '.transactions[4].contractAddress'| cast to-checksum) | ||
|
||
# Echo for debugging. | ||
echo "Deployed new OspEntry at $NEW_OSP_ENTRY" | ||
|
||
# Echo for debug | ||
echo "Deploying Espresso Osp migration action" | ||
|
||
# ** Essential migration step ** Forge script to deploy Espresso OSP migration action | ||
forge script --chain $PARENT_CHAIN_CHAIN_ID contracts/parent-chain/contract-upgrades/DeployEspressoOspMigrationAction.s.sol --rpc-url $PARENT_CHAIN_RPC_URL --broadcast -vvvv | ||
|
||
# Capture new OSP address | ||
# * Essential migration sub step ** Essential migration sub step * operators will be able to manually determine this address while running the upgrade, but this can be useful if they wish to make a script. | ||
OSP_MIGRATION_ACTION=$(cat broadcast/DeployEspressoOspMigrationAction.s.sol/1337/run-latest.json | jq -r '.transactions[0].contractAddress') | ||
|
||
echo "Deployed new OspMigrationAction at $OSP_MIGRATION_ACTION" | ||
|
||
# Use cast to call the upgradeExecutor and execute the L1 upgrade actions.This will point the challenge manager at the new OSP entry, as well as update the wasmModuleRoot for the rollup. | ||
# ** Essential migration step ** | ||
|
||
cast send $PARENT_CHAIN_UPGRADE_EXECUTOR "execute(address, bytes)" $OSP_MIGRATION_ACTION $(cast calldata "perform()") --rpc-url $PARENT_CHAIN_RPC_URL --private-key $PRIVATE_KEY | ||
|
||
echo "Executed OspMigrationAction via UpgradeExecutor" | ||
|
||
# Get the number of confirmed nodes before the upgrade to ensure the staker is still working. | ||
NUM_CONFIRMED_NODES_BEFORE_UPGRADE=$(cast call --rpc-url $PARENT_CHAIN_RPC_URL $ROLLUP_ADDRESS 'latestConfirmed()(uint256)') | ||
# Shutdown nitro node | ||
|
||
# This is part of the migration but the mechanics of this can be left up to operators. | ||
# ** Essential migration step ** The previous sequencer that is not compatible with espresso must be shut down so that we can start a new sequencer node that can have it's ArbOS version updated to signify the upgrade has occurred. | ||
docker stop nitro-testnode-sequencer-1 | ||
|
||
# Change directories to start nitro node in new docker container with espresso image | ||
cd $TESTNODE_DIR | ||
# Start nitro node in new docker container with espresso image | ||
./espresso-tests/create-espresso-integrated-nitro-node.bash | ||
|
||
# Wait for CHILD_CHAIN_RPC_URL to be available | ||
# * Essential migration sub step * This is technically essential to the migration, but doesn't usually take long and shouldn't need to be programatically determined during a live migration. | ||
while ! curl -s $CHILD_CHAIN_RPC_URL > /dev/null; do | ||
echo "Waiting for $CHILD_CHAIN_RPC_URL to be available..." | ||
sleep 5 | ||
done | ||
|
||
# Echo for debugging | ||
echo "Adding child chain upgrade executor as an L2 chain owner" | ||
# This step is done for the purposes of the test, as there should already be an upgrade executor on the child chain that is a chain owner | ||
cast send 0x0000000000000000000000000000000000000070 'addChainOwner(address)' $CHILD_CHAIN_UPGRADE_EXECUTOR_ADDRESS --rpc-url $CHILD_CHAIN_RPC_URL --private-key $PRIVATE_KEY | ||
|
||
echo "Deploying ArbOS Upgrade action" | ||
|
||
cd $ORBIT_ACTIONS_DIR | ||
# Forge script to deploy the Espresso ArbOS upgrade action. | ||
# ** Essential migration step ** the ArbOS upgrade signifies that the chain is now espresso compatible. | ||
forge script --chain $CHILD_CHAIN_CHAIN_NAME contracts/child-chain/arbos-upgrade/DeployArbOSUpgradeAction.s.sol:DeployArbOSUpgradeAction --rpc-url $CHILD_CHAIN_RPC_URL --broadcast -vvvv | ||
|
||
# Get the address of the newly deployed upgrade action. | ||
ARBOS_UPGRADE_ACTION=$(cat broadcast/DeployArbOSUpgradeAction.s.sol/412346/run-latest.json | jq -r '.transactions[0].contractAddress') | ||
|
||
# Echo information for debugging. | ||
echo "Deployed ArbOSUpgradeAction at $ARBOS_UPGRADE_ACTION" | ||
|
||
# Grab the pre-upgrade ArbOS version for testing. | ||
ARBOS_VERSION_BEFORE_UPGRADE=$(cast call "0x0000000000000000000000000000000000000064" "arbOSVersion()(uint64)" --rpc-url $CHILD_CHAIN_RPC_URL) | ||
|
||
# Use the Upgrde executor on the child chain to execute the ArbOS upgrade to signify that the node is now operating in espresso mode. This is essential for the migration. | ||
# ** Essential migration step ** This step can technically be done before all of the others as it is just scheduling the ArbOS upgrade. The unix timestamp at which the upgrade occurrs can be determined by operators, but for the purposes of the test we use 0 to upgrade immediately. | ||
cast send $CHILD_CHAIN_UPGRADE_EXECUTOR_ADDRESS "execute(address, bytes)" $ARBOS_UPGRADE_ACTION $(cast calldata "perform()") --rpc-url $CHILD_CHAIN_RPC_URL --private-key $PRIVATE_KEY | ||
|
||
# Check the upgrade happened | ||
|
||
# Grab the post upgrade ArbOS version. | ||
ARBOS_VERSION_AFTER_UPGRADE=$(cast call "0x0000000000000000000000000000000000000064" "arbOSVersion()(uint64)" --rpc-url $CHILD_CHAIN_RPC_URL) | ||
# Wait to observe the ArbOS version update. (potentially add a timeout or max retry number before failing) | ||
while [ $ARBOS_VERSION_BEFORE_UPGRADE == $ARBOS_VERSION_AFTER_UPGRADE ] | ||
do | ||
sleep 5 | ||
ARBOS_VERSION_AFTER_UPGRADE=$(cast call "0x0000000000000000000000000000000000000064" "arbOSVersion()(uint64)" --rpc-url $CHILD_CHAIN_RPC_URL) | ||
done | ||
|
||
# We are upgrading the ArbOS version to 35 so the expect the return value to be 55 + 35 = 90 | ||
if [ $ARBOS_VERSION_AFTER_UPGRADE != "90" ]; then | ||
fail "ArbOS version not updated: Expected 90, Actual $ARBOS_VERSION_AFTER_UPGRADE" | ||
fi | ||
|
||
# Test for new OSP address | ||
CHALLENGE_MANAGER_OSP_ADDRESS=$(cast call $CHALLENGE_MANAGER_ADDRESS "osp()(address)" --rpc-url $PARENT_CHAIN_RPC_URL) | ||
if [ $NEW_OSP_ENTRY != $CHALLENGE_MANAGER_OSP_ADDRESS ]; then | ||
sveitser marked this conversation as resolved.
Show resolved
Hide resolved
|
||
fail "OSP has not been set to newly deployed OSP: \n Newly deployed: $NEW_OSP_ENTRY \n Currently set OSP: $CHALLENGE_MANAGER_OSP_ADDRESS" | ||
fi | ||
# Check for balance before transfer. | ||
# The following sequence is to check that transactions are still successfully being sequenced on the L2 | ||
ORIGINAL_OWNER_BALANCE=$(cast balance $OWNER_ADDRESS -e --rpc-url $CHILD_CHAIN_RPC_URL) | ||
|
||
# Send 1 eth as the owner | ||
RECIPIENT_ADDRESS=0xAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA | ||
BALANCE_ORIG=$(cast balance $RECIPIENT_ADDRESS -e --rpc-url $CHILD_CHAIN_RPC_URL) | ||
cast send $RECIPIENT_ADDRESS --value 1ether --rpc-url $CHILD_CHAIN_RPC_URL --private-key $PRIVATE_KEY | ||
|
||
# Get the new balance after the transfer. | ||
BALANCE_NEW=$(cast balance $RECIPIENT_ADDRESS -e --rpc-url $CHILD_CHAIN_RPC_URL) | ||
|
||
# Assertion that balance should have changed. | ||
if [ $BALANCE_NEW == $BALANCE_ORIG ]; then | ||
fail "Balance of $RECIPIENT_ADDRESS should have changed but remained: $BALANCE_ORIG" | ||
fi | ||
# Echo successful balance update | ||
echo "Balance of $RECIPIENT_ADDRESS changed from $BALANCE_ORIG to $BALANCE_NEW" | ||
|
||
# Check that the staker is making progress after the upgrade | ||
while [ "$NUM_CONFIRMED_NODES_BEFORE_UPGRADE" == "$(cast call --rpc-url $PARENT_CHAIN_RPC_URL $ROLLUP_ADDRESS 'latestConfirmed()(uint256)')" ]; do | ||
echo "Waiting for confirmed nodes ..." | ||
sleep 5 | ||
done | ||
# Echo to confirm that stakers are behaving normally. | ||
echo "Confirmed nodes have progressed" | ||
|
||
# Echo to signal that test has been successful | ||
echo "Migration successfully completed!" | ||
|
||
docker compose down |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -3,5 +3,8 @@ WORKDIR /workspace | |
COPY ./package.json ./yarn.lock ./ | ||
RUN yarn | ||
COPY ./*.ts ./tsconfig.json ./ | ||
RUN mkdir /config | ||
# populate this file with valid json that will later be overwritten. If we don't do this the docker image won't build because of typescript looking for this file before the volume that contains it is mounted (I assume) | ||
RUN cp ./tsconfig.json /config/l2_chain_info.json | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is this still an issue? A bit strange I think |
||
RUN yarn build | ||
ENTRYPOINT ["node", "index.js"] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
what's the difference between this and
nitro-node-dev-testnode
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this should be
ghcr.io/espressosystems/nitro-espresso-integration/nitro-node-dev:integration
eventually but it's currently necessary to use a local docker image for testing because we haven't merged @zacshowa's E2E changes in nitro and they will be needed for this upgrade test. So I guess it's a locally tagged image.