Last active
January 16, 2024 20:46
-
-
Save philsaxton/806b56d33de4451d9d16f05d5c7b6cbe to your computer and use it in GitHub Desktop.
Script for finding and executing an outbox message from the flextesa smart-rollup sandbox running in a docker container.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
# This script will execute the outbox message of a smart rollup contract. | |
# It's intended to be used with a Flextesa sandbox within a Docker container. | |
set -e | |
set -o pipefail | |
container=${container_name:-"my-sandbox"} # Name of the Docker container | |
time_bb=${block_time:-2} # Time between blocks in seconds | |
proto=${protocol:-"Proxford"} # Tezos protocol hash | |
export TEZOS_CLIENT_UNSAFE_DISABLE_DISCLAIMER="YES" # Remove the "Test Net" warning. | |
say() { printf "[Withdrawal:] $@" >&2; } | |
# Execute octez-client commands within the container. | |
cli () { | |
docker exec "$container" octez-client --protocol "$proto" "$@" | |
} | |
# RPC calls pointed at the octez-smart-rollup-node. | |
soru_rpc () { | |
cli -E "http://localhost:20002" rpc get "$@" | |
} | |
# Get the smart-rollup address. | |
get_sr_addr() { | |
sr_addr="$(cli list known smart rollups | grep 'evm:' | awk '{print $2}')" | |
if [ -z "$sr_addr" ]; then | |
say 'Error: Empty output from octez-client list known smart rollups.\n' | |
else | |
echo "$sr_addr" | |
fi | |
} | |
SR_ADDR="$(get_sr_addr)" | |
export SR_ADDR | |
# Find a message starting from the current block and searching back a specified number of levels. | |
# This assumes that the first message found is the one you want to execute. | |
find_message() { | |
# Get the current level of the chain. | |
level="$(cli rpc get "/chains/main/blocks/head/metadata" | jq .level_info.level)" | |
if [ -z "$level" ]; then | |
say 'Error: No "level_info" found from octez-client rpc get "/chains/main/blocks/head/metadata".\n' | |
return 1 # Failure | |
fi | |
found=false | |
counter=0 | |
max="$1" | |
# Search back a $max number of levels for a non-empty rollup outbox message. | |
while [ "$found" = "false" ] && [ "$counter" -lt "$max" ]; do | |
msg="$(soru_rpc "/global/block/head/outbox/${level}/messages")" | |
case "$msg" in | |
*'[]'*) | |
level=$((level - 1)) | |
;; | |
*) | |
found=true | |
;; | |
esac | |
counter=$((counter + 1)) | |
done | |
if [ "$found" = "true" ]; then | |
echo "$level" # The block level at which a message was found. | |
else | |
say "No messages in the last %s levels.\n" "$1" | |
return 1 | |
fi | |
} | |
# Wait for the commitment at `level` to be cemented allowing the outbox message to become available for execution. | |
cemented_message() { | |
level="$1" # The level containing the outbox message. | |
cemented=false | |
counter=0 | |
max=90 # max nuber of tries. There is some buffer incase the blocks are slow | |
# Query cemented outbox until the message arrives or $max reached. | |
while [ "$cemented" = "false" ] && [ "$counter" -lt "$max" ]; do | |
msg="$(soru_rpc "/global/block/cemented/outbox/${level}/messages")" | |
case "$msg" in | |
*'[]'*) | |
;; | |
*) | |
say "The commitment at level %s is cemented.\n" "$level" | |
return 0 # Success | |
;; | |
esac | |
sleep "$time_bb" | |
counter=$((counter + 1)) | |
done | |
say "Message never cemented at level %s.\n" "$level" | |
return 1 # Failure | |
} | |
# Execute the outbox at a specified level. | |
execute_outbox() { | |
level="$1" | |
json="$(soru_rpc "/global/block/head/helpers/proofs/outbox/${level}/messages?index=0")" | |
proof="$(echo "$json" | jq -r '.proof' | sed 's/^/0x/')" # Prepend "0x" because the octez-client expects a hexadecimal value. | |
commit="$(echo "$json" | jq -r '.commitment')" | |
cli execute outbox message of smart rollup "$SR_ADDR" \ | |
from alice for commitment hash "$commit" \ | |
and output proof "$proof" --burn-cap 1 | |
} | |
# Run the entire sequence of operations in order. | |
run () { | |
say "Alice's starting balance: $(cli get balance for alice)\n" | |
SEARCH_DEPTH=300 | |
say "Searching for the outbox message in the last %s levels...\n" "$SEARCH_DEPTH" | |
MESSAGE_LEVEL=$(find_message "$SEARCH_DEPTH") | |
say "The evm-rollup outbox message was found in the commit at level %s.\n" "$MESSAGE_LEVEL" | |
say "Waiting for the commitment to cement...\n" | |
cemented_message "$MESSAGE_LEVEL" | |
say "Executing the outbox message...\n" | |
execute_outbox "$MESSAGE_LEVEL" | |
say "Alice's ending balance $(cli get balance for alice)\n" | |
} | |
{ if [ "$1" = "" ]; then run; else "$@"; fi; } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment