Skip to content

Instantly share code, notes, and snippets.

@philsaxton
Last active January 16, 2024 20:46
Show Gist options
  • Save philsaxton/806b56d33de4451d9d16f05d5c7b6cbe to your computer and use it in GitHub Desktop.
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.
#!/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