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

Use token bridge creator to deploy token bridges #17

Merged
merged 28 commits into from
Jan 9, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
7b9566d
Update Dockerfile to use token bridge repo instead of SDK
gvladika Oct 31, 2023
5d69cf9
Add option to deploy L2-L3 token bridge
gvladika Oct 31, 2023
e173aee
Deploy L1-L2 token bridge using token bridge creator
gvladika Oct 31, 2023
e7e95b0
Provide rollup owner
gvladika Oct 31, 2023
f2fd0bd
Add delay for services to be ready
gvladika Nov 2, 2023
1d7ba35
Delay before the L1-L2 token bridge deployment
gvladika Nov 2, 2023
e432e19
Add support for native L2-L3 bridging of the fee token
gvladika Nov 3, 2023
b157fac
Provide deployer keys as env var
gvladika Nov 3, 2023
1b9010c
Merge branch 'use-tokenbridge-creator' into fee-token-bridging
gvladika Nov 3, 2023
b3f40ee
Fix native bridging
gvladika Nov 3, 2023
26d2b22
Approve token before bridging
gvladika Nov 3, 2023
5e0b8f2
Use correct providers
gvladika Nov 3, 2023
5f6a418
Fetch native token address from config file
gvladika Nov 6, 2023
12d9bed
Use latest token-bridge-contracts tag
gvladika Nov 28, 2023
9062881
Merge pull request #18 from OffchainLabs/fee-token-bridging
gzeoneth Dec 8, 2023
dfdc759
Merge branch 'master' into use-tokenbridge-creator
gzeoneth Dec 8, 2023
a59d41c
Update test-node.bash
gzeoneth Dec 8, 2023
e93fba1
chore: use v1.1.2
gzeoneth Dec 8, 2023
6888036
Merge branch 'master' into use-tokenbridge-creator
gvladika Dec 21, 2023
1366df6
Use 'docker compose' CLI instead of 'docker-compose' when --wait flag…
gvladika Dec 21, 2023
7ca15aa
update docker compose command
spsjvc Dec 21, 2023
c554d0a
Merge pull request #23 from OffchainLabs/use-tokenbridge-creator-dock…
spsjvc Dec 21, 2023
937af32
Check not needed anymore
gvladika Dec 22, 2023
683f887
Remove unnecessary sleep
gvladika Dec 22, 2023
d77154d
Use latest token bridge design
gvladika Dec 22, 2023
8bb39c2
Read native token address from l3deployment.json
gvladika Dec 22, 2023
7c5d3e6
Bump nitro
gvladika Jan 8, 2024
d109d0f
Use the working nitro version
gvladika Jan 8, 2024
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
70 changes: 68 additions & 2 deletions scripts/ethcommands.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { ContractFactory, ethers, Wallet } from "ethers";
import * as consts from "./consts";
import { namedAccount, namedAddress } from "./accounts";
import * as ERC20PresetFixedSupplyArtifact from "@openzeppelin/contracts/build/contracts/ERC20PresetFixedSupply.json";
import * as ERC20 from "@openzeppelin/contracts/build/contracts/ERC20.json";
import * as fs from "fs";
const path = require("path");

Expand Down Expand Up @@ -52,6 +53,38 @@ async function bridgeFunds(argv: any, parentChainUrl: string, chainUrl: string,
}
}

async function bridgeNativeToken(argv: any, parentChainUrl: string, chainUrl: string, inboxAddr: string, token: string) {
argv.provider = new ethers.providers.WebSocketProvider(parentChainUrl);

argv.to = "address_" + inboxAddr;

/// approve inbox to use fee token
const bridgerParentChain = namedAccount(argv.from, argv.threadId).connect(argv.provider)
const nativeTokenContract = new ethers.Contract(token, ERC20.abi, bridgerParentChain)
await nativeTokenContract.approve(inboxAddr, ethers.utils.parseEther(argv.amount))

/// deposit fee token
const iface = new ethers.utils.Interface(["function depositERC20(uint256 amount)"])
argv.data = iface.encodeFunctionData("depositERC20", [ethers.utils.parseEther(argv.amount)]);

await runStress(argv, sendTransaction);

argv.provider.destroy();
if (argv.wait) {
const childProvider = new ethers.providers.WebSocketProvider(chainUrl);
const bridger = namedAccount(argv.from, argv.threadId).connect(childProvider)
const sleep = (ms: number) => new Promise(r => setTimeout(r, ms));
while (true) {
const balance = await bridger.getBalance()
if (balance.gte(ethers.utils.parseEther(argv.amount))) {
return
}
await sleep(100)
}
}
}


export const bridgeFundsCommand = {
command: "bridge-funds",
describe: "sends funds from l1 to l2",
Expand Down Expand Up @@ -84,7 +117,6 @@ export const bridgeFundsCommand = {
},
};


export const bridgeToL3Command = {
command: "bridge-to-l3",
describe: "sends funds from l2 to l3",
Expand Down Expand Up @@ -117,6 +149,40 @@ export const bridgeToL3Command = {
},
};

export const bridgeNativeTokenToL3Command = {
command: "bridge-native-token-to-l3",
describe: "bridge native token from l2 to l3",
builder: {
amount: {
string: true,
describe: "amount to transfer",
default: "10",
},
from: {
string: true,
describe: "account (see general help)",
default: "funnel",
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

in my tests funnel doesn't have l3tokens initially, so it shouldn't be the default
set the default to bridge-native-token-to-l3.

},
wait: {
boolean: true,
describe: "wait till l3 has balance of amount",
default: false,
},
},
handler: async (argv: any) => {
const deploydata = JSON.parse(
fs
.readFileSync(path.join(consts.configpath, "l3deployment.json"))
.toString()
);
const inboxAddr = ethers.utils.hexlify(deploydata.inbox);
const nativeTokenAddr = ethers.utils.hexlify(deploydata["native-token"]);

argv.ethamount = "0"
await bridgeNativeToken(argv, argv.l2url, argv.l3url, inboxAddr, nativeTokenAddr)
},
};

export const createERC20Command = {
command: "create-erc20",
describe: "creates simple ERC20 on L2",
Expand Down Expand Up @@ -228,7 +294,7 @@ export const sendL2Command = {

export const sendL3Command = {
command: "send-l3",
describe: "sends funds between l2 accounts",
describe: "sends funds between l3 accounts",
builder: {
ethamount: {
string: true,
Expand Down
2 changes: 2 additions & 0 deletions scripts/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import {
} from "./accounts";
import {
bridgeFundsCommand,
bridgeNativeTokenToL3Command,
bridgeToL3Command,
createERC20Command,
sendL1Command,
Expand All @@ -31,6 +32,7 @@ async function main() {
.options(stressOptions)
.command(bridgeFundsCommand)
.command(bridgeToL3Command)
.command(bridgeNativeTokenToL3Command)
.command(createERC20Command)
.command(sendL1Command)
.command(sendL2Command)
Expand Down
144 changes: 81 additions & 63 deletions test-node.bash
Original file line number Diff line number Diff line change
Expand Up @@ -2,22 +2,15 @@

set -e

NITRO_NODE_VERSION=offchainlabs/nitro-node:v2.2.0-alpha.1-fdd098e-dev
NITRO_NODE_VERSION=offchainlabs/nitro-node:v2.2.2-8f33fea-dev
BLOCKSCOUT_VERSION=offchainlabs/blockscout:v1.0.0-c8db5b1

mydir=`dirname $0`
cd "$mydir"

if ! which docker-compose > /dev/null; then
echo == Error! docker-compose not installed
echo please install docker-compose and have it in PATH
echo see https://docs.docker.com/compose/install/
exit 1
fi

if [[ $# -gt 0 ]] && [[ $1 == "script" ]]; then
shift
docker-compose run scripts "$@"
docker compose run scripts "$@"
exit $?
fi

Expand All @@ -40,7 +33,8 @@ consensusclient=false
redundantsequencers=0
dev_build_nitro=false
dev_build_blockscout=false
l3CustomFeeToken=false
l3_custom_fee_token=false
l3_token_bridge=false
batchposters=1
devprivkey=b6b15c8cb491557369f3c7d2c287b053eb229daa9c22138887752191c9520659
l1chainid=1337
Expand Down Expand Up @@ -131,7 +125,15 @@ while [[ $# -gt 0 ]]; do
echo "Error: --l3-fee-token requires --l3node to be provided."
exit 1
fi
l3CustomFeeToken=true
l3_custom_fee_token=true
shift
;;
--l3-token-bridge)
if ! $l3node; then
echo "Error: --l3-token-bridge requires --l3node to be provided."
exit 1
fi
l3_token_bridge=true
shift
;;
--redundantsequencers)
Expand Down Expand Up @@ -163,6 +165,7 @@ while [[ $# -gt 0 ]]; do
echo --pos l1 is a proof-of-stake chain \(using prysm for consensus\)
echo --validate heavy computation, validating all blocks in WASM
echo --l3-fee-token L3 chain is set up to use custom fee token. Only valid if also '--l3node' is provided
echo --l3-token-bridge Deploy L2-L3 token bridge. Only valid if also '--l3node' is provided
echo --batchposters batch posters [0-3]
echo --redundantsequencers redundant sequencers [0-3]
echo --detach detach from nodes after running them
Expand Down Expand Up @@ -251,10 +254,10 @@ if $force_build; then
fi
fi
LOCAL_BUILD_NODES=scripts
if $tokenbridge; then
if $tokenbridge || $l3_token_bridge; then
LOCAL_BUILD_NODES="$LOCAL_BUILD_NODES tokenbridge"
fi
docker-compose build --no-rm $LOCAL_BUILD_NODES
docker compose build --no-rm $LOCAL_BUILD_NODES
fi

if $dev_build_nitro; then
Expand All @@ -276,12 +279,12 @@ else
fi

if $force_build; then
docker-compose build --no-rm $NODES scripts
docker compose build --no-rm $NODES scripts
fi

if $force_init; then
echo == Removing old data..
docker-compose down
docker compose down
leftoverContainers=`docker container ls -a --filter label=com.docker.compose.project=nitro-testnode -q | xargs echo`
if [ `echo $leftoverContainers | wc -w` -gt 0 ]; then
docker rm $leftoverContainers
Expand All @@ -293,108 +296,123 @@ if $force_init; then
fi

echo == Generating l1 keys
docker-compose run scripts write-accounts
docker-compose run --entrypoint sh geth -c "echo passphrase > /datadir/passphrase"
docker-compose run --entrypoint sh geth -c "chown -R 1000:1000 /keystore"
docker-compose run --entrypoint sh geth -c "chown -R 1000:1000 /config"
docker compose run scripts write-accounts
docker compose run --entrypoint sh geth -c "echo passphrase > /datadir/passphrase"
docker compose run --entrypoint sh geth -c "chown -R 1000:1000 /keystore"
docker compose run --entrypoint sh geth -c "chown -R 1000:1000 /config"

if $consensusclient; then
echo == Writing configs
docker-compose run scripts write-geth-genesis-config
docker compose run scripts write-geth-genesis-config

echo == Writing configs
docker-compose run scripts write-prysm-config
docker compose run scripts write-prysm-config

echo == Initializing go-ethereum genesis configuration
docker-compose run geth init --datadir /datadir/ /config/geth_genesis.json
docker compose run geth init --datadir /datadir/ /config/geth_genesis.json

echo == Starting geth
docker-compose up --wait geth
docker compose up --wait geth

echo == Creating prysm genesis
docker-compose up create_beacon_chain_genesis
docker compose up create_beacon_chain_genesis

echo == Running prysm
docker-compose up --wait prysm_beacon_chain
docker-compose up --wait prysm_validator
docker compose up --wait prysm_beacon_chain
docker compose up --wait prysm_validator
else
docker-compose up --wait geth
docker compose up --wait geth
fi

echo == Funding validator and sequencer
docker-compose run scripts send-l1 --ethamount 1000 --to validator --wait
docker-compose run scripts send-l1 --ethamount 1000 --to sequencer --wait
docker compose run scripts send-l1 --ethamount 1000 --to validator --wait
docker compose run scripts send-l1 --ethamount 1000 --to sequencer --wait

echo == create l1 traffic
docker-compose run scripts send-l1 --ethamount 1000 --to user_l1user --wait
docker-compose run scripts send-l1 --ethamount 0.0001 --from user_l1user --to user_l1user_b --wait --delay 500 --times 1000000 > /dev/null &
docker compose run scripts send-l1 --ethamount 1000 --to user_l1user --wait
docker compose run scripts send-l1 --ethamount 0.0001 --from user_l1user --to user_l1user_b --wait --delay 500 --times 1000000 > /dev/null &

echo == Writing l2 chain config
docker-compose run scripts write-l2-chain-config
docker compose run scripts write-l2-chain-config

sequenceraddress=`docker-compose run scripts print-address --account sequencer | tail -n 1 | tr -d '\r\n'`
sequenceraddress=`docker compose run scripts print-address --account sequencer | tail -n 1 | tr -d '\r\n'`

docker-compose run --entrypoint /usr/local/bin/deploy sequencer --l1conn ws://geth:8546 --l1keystore /home/user/l1keystore --sequencerAddress $sequenceraddress --ownerAddress $sequenceraddress --l1DeployAccount $sequenceraddress --l1deployment /config/deployment.json --authorizevalidators 10 --wasmrootpath /home/user/target/machines --l1chainid=$l1chainid --l2chainconfig /config/l2_chain_config.json --l2chainname arb-dev-test --l2chaininfo /config/deployed_chain_info.json
docker-compose run --entrypoint sh sequencer -c "jq [.[]] /config/deployed_chain_info.json > /config/l2_chain_info.json"
docker compose run --entrypoint /usr/local/bin/deploy sequencer --l1conn ws://geth:8546 --l1keystore /home/user/l1keystore --sequencerAddress $sequenceraddress --ownerAddress $sequenceraddress --l1DeployAccount $sequenceraddress --l1deployment /config/deployment.json --authorizevalidators 10 --wasmrootpath /home/user/target/machines --l1chainid=$l1chainid --l2chainconfig /config/l2_chain_config.json --l2chainname arb-dev-test --l2chaininfo /config/deployed_chain_info.json
docker compose run --entrypoint sh sequencer -c "jq [.[]] /config/deployed_chain_info.json > /config/l2_chain_info.json"

if $simple; then
echo == Writing configs
docker-compose run scripts write-config --simple
docker compose run scripts write-config --simple
else
echo == Writing configs
docker-compose run scripts write-config
docker compose run scripts write-config

echo == Initializing redis
docker-compose up --wait redis
docker-compose run scripts redis-init --redundancy $redundantsequencers
docker compose up --wait redis
docker compose run scripts redis-init --redundancy $redundantsequencers
fi

echo == Funding l2 funnel and dev key
docker-compose up --wait $INITIAL_SEQ_NODES
docker-compose run scripts bridge-funds --ethamount 100000 --wait
docker-compose run scripts bridge-funds --ethamount 1000 --wait --from "key_0x$devprivkey"
docker compose up --wait $INITIAL_SEQ_NODES
docker compose run scripts bridge-funds --ethamount 100000 --wait
docker compose run scripts bridge-funds --ethamount 1000 --wait --from "key_0x$devprivkey"

if $tokenbridge; then
echo == Deploying token bridge
docker-compose run -e ARB_KEY=$devprivkey -e ETH_KEY=$devprivkey tokenbridge gen:network
docker-compose run --entrypoint sh tokenbridge -c "cat localNetwork.json"
echo == Deploying L1-L2 token bridge
rollupAddress=`docker compose run --entrypoint sh poster -c "jq -r '.[0].rollup.rollup' /config/deployed_chain_info.json | tail -n 1 | tr -d '\r\n'"`
docker compose run -e ROLLUP_OWNER=$sequenceraddress -e ROLLUP_ADDRESS=$rollupAddress -e PARENT_KEY=$devprivkey -e PARENT_RPC=http://geth:8545 -e CHILD_KEY=$devprivkey -e CHILD_RPC=http://sequencer:8547 tokenbridge deploy:local:token-bridge
docker compose run --entrypoint sh tokenbridge -c "cat network.json"
echo
fi

if $l3node; then
echo == Funding l3 users
docker-compose run scripts send-l2 --ethamount 1000 --to l3owner --wait
docker-compose run scripts send-l2 --ethamount 1000 --to l3sequencer --wait
docker compose run scripts send-l2 --ethamount 1000 --to l3owner --wait
docker compose run scripts send-l2 --ethamount 1000 --to l3sequencer --wait

echo == Funding l2 deployers
docker-compose run scripts send-l2 --ethamount 100 --to user_token_bridge_deployer --wait
docker-compose run scripts send-l2 --ethamount 100 --to user_fee_token_deployer --wait
docker compose run scripts send-l2 --ethamount 100 --to user_token_bridge_deployer --wait
docker compose run scripts send-l2 --ethamount 100 --to user_fee_token_deployer --wait
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

let's add to scripts/accounts.ts, under "Valid account names" - a description of:

  • user_token_bridge_deployer
  • user_fee_token_deployer
  • l3owner
  • l3sequencer


echo == create l2 traffic
docker-compose run scripts send-l2 --ethamount 100 --to user_traffic_generator --wait
docker-compose run scripts send-l2 --ethamount 0.0001 --from user_traffic_generator --to user_fee_token_deployer --wait --delay 500 --times 1000000 > /dev/null &
docker compose run scripts send-l2 --ethamount 100 --to user_traffic_generator --wait
docker compose run scripts send-l2 --ethamount 0.0001 --from user_traffic_generator --to user_fee_token_deployer --wait --delay 500 --times 1000000 > /dev/null &

echo == Writing l3 chain config
docker-compose run scripts write-l3-chain-config
docker compose run scripts write-l3-chain-config

if $l3CustomFeeToken; then
if $l3_custom_fee_token; then
echo == Deploying custom fee token
nativeTokenAddress=`docker-compose run scripts create-erc20 --deployer user_fee_token_deployer --mintTo user_token_bridge_deployer | tail -n 1 | awk '{ print $NF }'`
nativeTokenAddress=`docker compose run scripts create-erc20 --deployer user_fee_token_deployer --mintTo user_token_bridge_deployer | tail -n 1 | awk '{ print $NF }'`
EXTRA_L3_DEPLOY_FLAG="--nativeTokenAddress $nativeTokenAddress"
fi

echo == Deploying L3
l3owneraddress=`docker-compose run scripts print-address --account l3owner | tail -n 1 | tr -d '\r\n'`
l3sequenceraddress=`docker-compose run scripts print-address --account l3sequencer | tail -n 1 | tr -d '\r\n'`
docker-compose run --entrypoint /usr/local/bin/deploy sequencer --l1conn ws://sequencer:8548 --l1keystore /home/user/l1keystore --sequencerAddress $l3sequenceraddress --ownerAddress $l3owneraddress --l1DeployAccount $l3owneraddress --l1deployment /config/l3deployment.json --authorizevalidators 10 --wasmrootpath /home/user/target/machines --l1chainid=412346 --l2chainconfig /config/l3_chain_config.json --l2chainname orbit-dev-test --l2chaininfo /config/deployed_l3_chain_info.json --maxDataSize 104857 $EXTRA_L3_DEPLOY_FLAG
docker-compose run --entrypoint sh sequencer -c "jq [.[]] /config/deployed_l3_chain_info.json > /config/l3_chain_info.json"
l3owneraddress=`docker compose run scripts print-address --account l3owner | tail -n 1 | tr -d '\r\n'`
l3sequenceraddress=`docker compose run scripts print-address --account l3sequencer | tail -n 1 | tr -d '\r\n'`
docker compose run --entrypoint /usr/local/bin/deploy sequencer --l1conn ws://sequencer:8548 --l1keystore /home/user/l1keystore --sequencerAddress $l3sequenceraddress --ownerAddress $l3owneraddress --l1DeployAccount $l3owneraddress --l1deployment /config/l3deployment.json --authorizevalidators 10 --wasmrootpath /home/user/target/machines --l1chainid=412346 --l2chainconfig /config/l3_chain_config.json --l2chainname orbit-dev-test --l2chaininfo /config/deployed_l3_chain_info.json --maxDataSize 104857 $EXTRA_L3_DEPLOY_FLAG
docker compose run --entrypoint sh sequencer -c "jq [.[]] /config/deployed_l3_chain_info.json > /config/l3_chain_info.json"

echo == Funding l3 funnel and dev key
docker-compose up --wait l3node sequencer
docker compose up --wait l3node sequencer

if $l3_token_bridge; then
echo == Deploying L2-L3 token bridge
deployer_key=`printf "%s" "user_token_bridge_deployer" | openssl dgst -sha256 | sed 's/^.*= //'`
rollupAddress=`docker compose run --entrypoint sh poster -c "jq -r '.[0].rollup.rollup' /config/deployed_l3_chain_info.json | tail -n 1 | tr -d '\r\n'"`
docker compose run -e ROLLUP_OWNER=$l3owneraddress -e ROLLUP_ADDRESS=$rollupAddress -e PARENT_RPC=http://sequencer:8547 -e PARENT_KEY=$deployer_key -e CHILD_RPC=http://l3node:3347 -e CHILD_KEY=$deployer_key tokenbridge deploy:local:token-bridge
docker compose run --entrypoint sh tokenbridge -c "cat network.json"
echo
fi

if ! $l3CustomFeeToken; then
docker-compose run scripts bridge-to-l3 --ethamount 50000 --wait
docker-compose run scripts bridge-to-l3 --ethamount 500 --wait --from "key_0x$devprivkey"
echo == Fund L3 accounts
if $l3_custom_fee_token; then
docker compose run scripts bridge-native-token-to-l3 --amount 50000 --from user_token_bridge_deployer --wait
docker compose run scripts send-l3 --ethamount 500 --from user_token_bridge_deployer --wait
docker compose run scripts send-l3 --ethamount 500 --from user_token_bridge_deployer --to "key_0x$devprivkey" --wait
else
docker compose run scripts bridge-to-l3 --ethamount 50000 --wait
docker compose run scripts bridge-to-l3 --ethamount 500 --wait --from "key_0x$devprivkey"
fi

fi
Expand All @@ -410,5 +428,5 @@ if $run; then
echo if things go wrong - use --init to create a new chain
echo

docker-compose up $UP_FLAG $NODES
docker compose up $UP_FLAG $NODES
fi
5 changes: 3 additions & 2 deletions tokenbridge/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
FROM node:16-bullseye-slim
RUN apt-get update && \
apt-get install -y git docker.io
apt-get install -y git docker.io python3 chromium build-essential
WORKDIR /workspace
RUN git clone --depth 1 -b v3.1.4 https://github.com/OffchainLabs/arbitrum-sdk.git ./
RUN git clone -b feat-registry https://github.com/OffchainLabs/token-bridge-contracts.git ./
RUN yarn install
RUN yarn build
ENTRYPOINT ["yarn"]