Skip to content
Draft
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
35 changes: 34 additions & 1 deletion README_ESPRESSO.md
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,39 @@ To run a subset of the tests above (fast):
kurtosis clean -a
```

### Migration from Celo's kurtosis devnet to Celo-Espesso devnet

To do the migration, you need to start Celo's kurtosis devnet first.

```console
git checkout Kourin1996/celo-rebase-13-devnet
cd kurtosis-devnet && just celo-isthmus-devnet
```

Then get back to the original branch.
```console
git checkout -
```

Deploy Espresso's contracts to the devnet.
```console
./espresso/scripts/deploy-espresso-contracts.sh
```

Stop the old batcher.
```console
kurtosis service stop celo-isthmus-devnet op-batcher-op-kurtosis
```

<!-- Sishan TODO: some other preparations like starting espresso dev node is needed here -->

Start the new batcher.
```console
cd op-batcher/ && just && cd -
cd kurtosis-devnet && just external-batcher-celo
```

<!-- Sishan TODO: some other migrations like op-node's and caff-node's will be added here later -->

### Misc commands

Expand Down Expand Up @@ -338,7 +371,7 @@ docker compose down -v
docker volume prune -a
```

* If you have changed OP contracts, you will have to start the devnet fresh and re-generate
* If you have changed OP contracts, you will have to start the devnet fresh and re-generate
the genesis allocations by running `prepare-allocs.sh`


Expand Down
206 changes: 206 additions & 0 deletions espresso/scripts/deploy-espresso-contracts.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,206 @@
#!/usr/bin/env bash
set -euo pipefail

# This script deploys Espresso contracts to a kurtosis devnet `celo-isthmus-devnet`

# Function to get L1 RPC port from kurtosis
get_l1_rpc_port() {
kurtosis enclave inspect celo-isthmus-devnet | grep -A 10 "el-1-geth-teku" | grep "rpc: " | grep -v "engine-rpc" | sed -n 's/.*127.0.0.1:\([0-9]*\).*/\1/p'
}

# Function to get user key from devnet descriptor
get_user_key() {
# Clean up any existing directory
rm -rf devnet-descriptor-0

# Download the devnet descriptor
kurtosis files download celo-isthmus-devnet devnet-descriptor-0 >/dev/null 2>&1
if [ $? -ne 0 ]; then
echo "Error: Failed to download devnet descriptor" >&2
return 1
fi

# Fix line endings and validate JSON
dos2unix devnet-descriptor-0/env.json >/dev/null 2>&1
if ! jq empty devnet-descriptor-0/env.json >/dev/null 2>&1; then
echo "Error: Invalid JSON file" >&2
rm -rf devnet-descriptor-0
return 1
fi

# Extract the user key from env.json
local user_key
user_key=$(jq -r '.l1.wallets."user-key-12".private_key' devnet-descriptor-0/env.json)
if [ -z "$user_key" ] || [ "$user_key" = "null" ]; then
echo "Error: Could not find user key in devnet descriptor" >&2
rm -rf devnet-descriptor-0
return 1
fi

# Clean up the downloaded files
rm -rf devnet-descriptor-0

# Return the user key
echo "$user_key"
return 0
}

# Default L1 RPC URL for kurtosis devnet
L1_RPC_PORT=$(get_l1_rpc_port)
if [ -z "$L1_RPC_PORT" ]; then
echo "Error: Could not get L1 RPC port from kurtosis. Please ensure the devnet is running."
exit 1
fi
echo "Using L1 RPC Port: $L1_RPC_PORT"
L1_RPC_URL=${L1_RPC_URL:-"http://localhost:$L1_RPC_PORT"}

# Get the project root directory
PROJECT_ROOT=$(realpath "$(dirname "${BASH_SOURCE[0]}")/../..")
ENV_FILE="$PROJECT_ROOT/espresso/.env"

# Load environment variables if .env exists
if [ -f "$ENV_FILE" ]; then
source "$ENV_FILE"
fi

# Function to get balance in ETH
get_balance() {
local address=$1
cast balance --rpc-url "$L1_RPC_URL" "$address" | cast --from-wei
}

# Function to transfer ETH
transfer_eth() {
local from_key=$1
local to_address=$2
local amount=$3
cast send --rpc-url "$L1_RPC_URL" --private-key "$from_key" "$to_address" --value "${amount}eth"
echo "✓ Transferred $amount ETH to $to_address"
}

# Check if OPERATOR_PRIVATE_KEY is set in .env
if [ -z "${OPERATOR_PRIVATE_KEY:-}" ]; then
echo "Error: OPERATOR_PRIVATE_KEY not found in .env file"
exit 1
fi

# Use the operator's private key from .env
PRIVATE_KEY=$OPERATOR_PRIVATE_KEY

# Get operator's address
OPERATOR_ADDRESS=$(cast wallet address --private-key "$PRIVATE_KEY")
echo "Using operator address: $OPERATOR_ADDRESS"

# Check operator balance and transfer funds if needed
OPERATOR_BALANCE=$(get_balance "$OPERATOR_ADDRESS")
echo "Operator balance: $OPERATOR_BALANCE ETH"

# Convert balance to a number that can be compared
OPERATOR_BALANCE_NUM=$(echo "$OPERATOR_BALANCE" | bc)
if (( $(echo "$OPERATOR_BALANCE_NUM < 5" | bc -l) )); then
echo "Operator balance is less than 5 ETH. Transferring funds..."
# Get user key from devnet descriptor
USER_KEY=$(get_user_key)
if [ $? -ne 0 ]; then
echo "Error: Failed to get user key from devnet descriptor" >&2
exit 1
fi
# Remove 0x prefix if present
USER_KEY=${USER_KEY#0x}
cast send --private-key "$USER_KEY" --rpc-url "$L1_RPC_URL" "$OPERATOR_ADDRESS" --value 2ether
if [ $? -ne 0 ]; then
echo "Error: Failed to transfer funds to operator" >&2
exit 1
fi
echo "Successfully transferred 2 ETH to operator"
fi

# Function to validate contract deployment
validate_contract() {
local address=$1
local name=$2
echo "Validating $name at $address..."
# Check if address exists on chain
if ! cast code "$address" --rpc-url "$L1_RPC_URL" > /dev/null 2>&1; then
echo "Error: $name contract not found at $address"
exit 1
fi
echo "✓ $name contract validated"
}

# Function to update .env file
update_env() {
local name=$1
local address=$2
# Remove existing line if it exists
sed -i "/$name=/d" "$ENV_FILE"
# Add new line
echo "$name=$address" >> "$ENV_FILE"
echo "✓ Updated $name in .env"
}

# Ensure we're in the contracts directory
cd "$PROJECT_ROOT/packages/contracts-bedrock"

# First, deploy the EspressoTEEVerifier
echo "Deploying EspressoTEEVerifier..."
TEE_VERIFIER_RESULT=$(forge create \
--rpc-url "$L1_RPC_URL" \
--private-key "$PRIVATE_KEY" \
--broadcast \
lib/espresso-tee-contracts/src/EspressoTEEVerifier.sol:EspressoTEEVerifier \
--constructor-args "$ESPRESSO_SEQUENCER_PLONK_VERIFIER_ADDRESS" "$ESPRESSO_SEQUENCER_PLONK_VERIFIER_V2_ADDRESS")

# Extract EspressoTEEVerifier address
TEE_VERIFIER_ADDRESS=$(echo "$TEE_VERIFIER_RESULT" | grep "Deployed to:" | awk '{print $3}')
echo "EspressoTEEVerifier deployed to: $TEE_VERIFIER_ADDRESS"

# Validate EspressoTEEVerifier deployment
validate_contract "$TEE_VERIFIER_ADDRESS" "EspressoTEEVerifier"

# Deploy BatchAuthenticator with TEE verifier
echo "Deploying BatchAuthenticator..."
AUTHENTICATOR_RESULT=$(forge create \
--rpc-url "$L1_RPC_URL" \
--private-key "$PRIVATE_KEY" \
--broadcast \
src/L1/BatchAuthenticator.sol:BatchAuthenticator \
--constructor-args "$TEE_VERIFIER_ADDRESS" "$OPERATOR_ADDRESS")

# Extract BatchAuthenticator address
AUTHENTICATOR_ADDRESS=$(echo "$AUTHENTICATOR_RESULT" | grep "Deployed to:" | awk '{print $3}')
echo "BatchAuthenticator deployed to: $AUTHENTICATOR_ADDRESS"

# Validate BatchAuthenticator deployment
validate_contract "$AUTHENTICATOR_ADDRESS" "BatchAuthenticator"

# Deploy BatchInbox with BatchAuthenticator address
echo "Deploying BatchInbox..."
INBOX_RESULT=$(forge create \
--rpc-url "$L1_RPC_URL" \
--private-key "$PRIVATE_KEY" \
--broadcast \
src/L1/BatchInbox.sol:BatchInbox \
--constructor-args "$AUTHENTICATOR_ADDRESS")

# Extract BatchInbox address
INBOX_ADDRESS=$(echo "$INBOX_RESULT" | grep "Deployed to:" | awk '{print $3}')
echo "BatchInbox deployed to: $INBOX_ADDRESS"

# Validate BatchInbox deployment
validate_contract "$INBOX_ADDRESS" "BatchInbox"

# Update .env file with new contract addresses
echo "Updating .env file with contract addresses..."
update_env "ESPRESSO_TEE_VERIFIER_ADDRESS" "$TEE_VERIFIER_ADDRESS"
update_env "BATCH_AUTHENTICATOR_ADDRESS" "$AUTHENTICATOR_ADDRESS"
update_env "BATCH_INBOX_ADDRESS" "$INBOX_ADDRESS"

echo "Deployment complete! Contract addresses have been added to $ENV_FILE"

# Output addresses in a format suitable for environment variables
echo ""
echo "Added these to your .env file:"
echo "ESPRESSO_TEE_VERIFIER_ADDRESS=$TEE_VERIFIER_ADDRESS"
echo "BATCH_AUTHENTICATOR_ADDRESS=$AUTHENTICATOR_ADDRESS"
echo "BATCH_INBOX_ADDRESS=$INBOX_ADDRESS"
2 changes: 1 addition & 1 deletion espresso/scripts/prepare-allocs.sh
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ kill $ANVIL_PID

sleep 1

"${OP_ROOT}/espresso/scripts/reshape-allocs.jq" \
jq -S -f "${OP_ROOT}/espresso/scripts/reshape-allocs.jq" \
<(jq .accounts "${ANVIL_STATE_FILE}") \
| jq '{ "alloc": map_values(.state) }' \
> "${DEPLOYMENT_DIR}/deployer_allocs.json"
Expand Down
1 change: 0 additions & 1 deletion espresso/scripts/reshape-allocs.jq
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
#!/usr/bin/env jq -S -f
# Converts output of espresso-dev-node launched with
# 'ESPRESSO_DEV_NODE_L1_DEPLOYMENT=dump' to form suitable
# for e2e testing harness.
Expand Down
22 changes: 22 additions & 0 deletions kurtosis-devnet/justfile
Original file line number Diff line number Diff line change
Expand Up @@ -144,3 +144,25 @@ external-batcher-parameters:
echo "$parameter2"
echo "$parameter3"
echo "$parameter4"

external-batcher-celo:
#!/usr/bin/env sh
function external_url () {
kurtosis service inspect celo-isthmus-devnet "${1}" | yq .Ports."${2}" | sed -E 's#.*->\s+(.*\/)?#http://#'
}
batcher="$(pwd)/../op-batcher/bin/op-batcher"
command="${batcher} "\
"--l2-eth-rpc=$(external_url 'op-el-1-op-geth-op-node-op-kurtosis' 'rpc') "\
"--rollup-rpc=$(external_url 'op-cl-1-op-node-op-geth-op-kurtosis' 'http') "\
"--l1-eth-rpc=$(external_url 'el-1-geth-teku' 'rpc') "\
"--espresso-url=http://localhost:24000,http://localhost:24000 "\
"--espresso-light-client-addr=0x703848f4c85f18e3acd8196c8ec91eb0b7bd0797 "\
"--testing-espresso-batcher-private-key=0xb3d2d558e3491a3709b7c451100a0366b5872520c7aa020c17a0e7fa35b6a8df "\
"--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=0xb3d2d558e3491a3709b7c451100a0366b5872520c7aa020c17a0e7fa35b6a8df "\
"--data-availability-type=calldata --metrics.enabled --metrics.addr=0.0.0.0 --metrics.port=9001 "\
"--log.level=debug"
echo "Running batcher:"
echo "$command"
$command