Skip to content

Commit

Permalink
test: generate devnet for local testing
Browse files Browse the repository at this point in the history
  • Loading branch information
marcelstanley committed Dec 5, 2023
1 parent b4c1f2d commit ea122fe
Show file tree
Hide file tree
Showing 5 changed files with 619 additions and 0 deletions.
356 changes: 356 additions & 0 deletions scripts/devnet/gen-devnet.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,356 @@
#!/usr/bin/env bash
# (c) Cartesi and individual authors (see AUTHORS)
# SPDX-License-Identifier: Apache-2.0 (see LICENSE)
set -euo pipefail
if [[ "${TRACE-0}" == "1" ]]; then set -o xtrace; fi

script_dir="$( cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
readonly script_dir

. "$script_dir/lib/util.sh"
. "$script_dir/lib/anvil.sh"
. "$script_dir/lib/contracts.sh"

################################################################################
# Configuration
ROLLUPS_CONTRACTS_VERSION="1.1.0"
DEVNET_RPC_URL="http://localhost:8545"
DEVNET_FOUNDRY_ACCOUNT_0_ADDRESS="0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266"
DEVNET_FOUNDRY_ACCOUNT_0_PRIVATE_KEY="0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80"
# keccak256("salt")
DEVNET_DEFAULT_SALT="0xa05e334153147e75f3f416139b5109d1179cb56fef6a4ecb4c4cbc92a7c37b70"
readonly ROLLUPS_CONTRACTS_VERSION \
DEVNET_RPC_URL \
DEVNET_FOUNDRY_ACCOUNT_0_ADDRESS \
DEVNET_FOUNDRY_ACCOUNT_0_PRIVATE_KEY \
DEVNET_DEFAULT_SALT

# Defaults
devnet_anvil_state_file=$(realpath "./anvil_state.json")
devnet_deployment_file=$(realpath "./deployment.json")
readonly forge_remappings_file="$script_dir/remappings.txt"

# Deployment info, which will be gathered during processing
declare -A deployment_info

################################################################################
# Utility functions
################################################################################
usage()
{
echo "Generate devnet for testing the Cartesi Rollups Node"
echo
echo "Usage: $0 [options]"
echo
echo "OPTIONS:"
echo
echo " -m machine-template-hash"
echo " Mandatory Cartesi Machine template hash (example: 0xdeadbeef)"
echo " -a"
echo " Path for output anvil state file (default: $DEVNET_DEFAULT_ANVIL_STATE_FILE)"
echo " -d"
echo " Path for deployment information file (default: $DEVNET_DEFAULT_DEPLOYMENT_FILE)"
echo " -v"
echo " Verbose mode"
echo " -h"
echo " Show this message"
echo

exit 0
}

################################################################################
# Finish processing and clean up environment
finish() {
verbose "finishing up"

if [ -n "$work_dir" ]; then
rm -rf "$work_dir"
check_error $? "failed to remove $work_dir"
verbose "removing $work_dir"
fi

if [[ -n "$anvil_pid" ]]; then
anvil_down "$anvil_pid"
fi
}

################################################################################
# Print deployment report
print_report() {
log "Deployment report:"
log "rollups-contracts version: $ROLLUPS_CONTRACTS_VERSION"
log "anvil state file location: $devnet_anvil_state_file"
log "deployment file location : $devnet_deployment_file"
}

################################################################################
# Generate deployment file
generate_deployment_file() {
local deployment_file="$1"

echo "{" > "$deployment_file"
for key in "${!deployment_info[@]}"; do
echo " \"${key}\": \"${deployment_info[${key}]}\"," >> "$deployment_file"
done
echo "}" >> "$deployment_file"
verbose "Deployment information saved to $deployment_file"
}

################################################################################
# Deploy rollups libraries
deploy_libraries() {
local contract="lib/@cartesi/util/contracts/CartesiMathV2.sol"
local name="CartesiMathV2"
local lib_address=""
contract_deploy \
lib_address \
"$contract" \
"$name"
mathv2_lib="$contract:$name:$lib_address"
verbose "deployed $mathv2_lib"

contract="lib/@cartesi/util/contracts/MerkleV2.sol"
name="MerkleV2"
contract_deploy \
lib_address \
"$contract" \
"$name" \
--libraries \
"$mathv2_lib"
merklev2_lib="$contract:$name:$lib_address"
verbose "deployed $merklev2_lib"

contract="lib/@cartesi/util/contracts/Bitmask.sol"
name="Bitmask"
contract_deploy \
lib_address \
"$contract" \
"$name"
bitmask_lib="$contract:$name:$lib_address"
verbose "deployed $bitmask_lib"
}

################################################################################
# Deploy portals
deploy_portals() {
local name="InputBox"
local contract="src/inputs/InputBox.sol"
local portal_address=""
contract_deploy \
portal_address \
"$contract" \
"$name"
deployment_info["CARTESI_CONTRACTS_INPUT_BOX_ADDRESS"]="$portal_address"
verbose "deployed $contract:$name:$portal_address"

declare -A portals
portals["ERC1155BatchPortal"]="src/portals/ERC1155BatchPortal.sol"
portals["ERC1155SinglePortal"]="src/portals/ERC1155SinglePortal.sol"
portals["ERC20Portal"]="src/portals/ERC20Portal.sol"
portals["ERC721Portal"]="src/portals/ERC721Portal.sol"
portals["EtherPortal"]="src/portals/EtherPortal.sol"

local inputbox_address="$portal_address"
for key in "${!portals[@]}"; do
name="${key}"
contract="${portals[${key}]}"
contract_deploy \
portal_address \
"$contract" \
"$name" \
--constructor-args \
"$inputbox_address"
verbose "deployed $contract:$name:$portal_address"
done
}

################################################################################
# Deploy DAppRelay
deploy_relay() {
local contract="src/relays/DAppAddressRelay.sol"
local name="DAppAddressRelay"
local relay_address=""
contract_deploy \
relay_address \
"$contract" \
"$name" \
--constructor-args \
"$DEVNET_FOUNDRY_ACCOUNT_0_ADDRESS"
verbose "deployed $contract:$name:$relay_address"
}

################################################################################
# Create DApp factories
create_factories() {
local -n dapp_factory_addr="$1"
shift
local -n auth_hist_factory_addr="$1"
shift

local contract="src/dapp/CartesiDAppFactory.sol"
local name="CartesiDAppFactory"
local factory_address=""
contract_deploy \
factory_address \
"$contract" \
"$name" \
--libraries "$mathv2_lib" \
--libraries "$merklev2_lib" \
--libraries "$bitmask_lib"
dapp_factory_addr="$factory_address"
verbose "deployed $contract:$name:$factory_address"

contract="src/consensus/authority/AuthorityFactory.sol"
name="AuthorityFactory"
contract_deploy \
factory_address \
"$contract" \
"$name" \
--constructor-args \
"$DEVNET_FOUNDRY_ACCOUNT_0_ADDRESS"
verbose "deployed $contract:$name:$factory_address"
authority_factory_address="$factory_address"

contract="src/history/HistoryFactory.sol"
name="HistoryFactory"
contract_deploy \
factory_address \
"$contract" \
"$name" \
--constructor-args \
"$DEVNET_FOUNDRY_ACCOUNT_0_ADDRESS"
verbose "deployed $contract:$name:$factory_address"
history_factory_address="$factory_address"

contract="src/consensus/authority/AuthorityHistoryPairFactory.sol"
name="AuthorityHistoryPairFactory"
contract_deploy \
factory_address \
"$contract" \
"$name" \
--constructor-args \
"$authority_factory_address" \
"$history_factory_address"
auth_hist_factory_addr="$factory_address"
verbose "deployed $contract:$name:$factory_address"
}

################################################################################
# create DApp contracts
create_dapp() {
local -n ret="$1"
shift
factory_addr="$1"
shift
dapp_factory_addr="$1"
shift

local addresses
contract_create \
addresses \
block_number \
"$factory_addr" \
"newAuthorityHistoryPair(address,bytes32)(address,address)" \
"$DEVNET_FOUNDRY_ACCOUNT_0_ADDRESS" \
"$DEVNET_DEFAULT_SALT"
authority_address="${addresses[0]}"
history_address="${addresses[1]}"
deployment_info["CARTESI_CONTRACTS_AUTHORITY_ADDRESS"]="$authority_address"
deployment_info["CARTESI_CONTRACTS_HISTORY_ADDRESS"]="$history_address"
verbose "deployed authority_address=$authority_address"
verbose "deployed history_address=$history_address"

contract_create \
addresses \
block_number \
"$dapp_factory_addr" \
"newApplication(address,address,bytes32,bytes32)(address)" \
"$authority_address" \
"$DEVNET_FOUNDRY_ACCOUNT_0_ADDRESS" \
"$template_hash" \
"$DEVNET_DEFAULT_SALT"
ret="${addresses[0]}"
deployment_info["CARTESI_CONTRACTS_DAPP_ADDRESS"]="$ret"
deployment_info["CARTESI_CONTRACTS_DAPP_DEPLOYMENT_BLOCK_NUMBER"]="$block_number"
verbose "deployed dapp_address=$ret"
}

################################################################################
# Main workflow
################################################################################

# Process script options
while getopts ":a:d:m:hv" option; do
case $option in
a)
devnet_anvil_state_file=$(realpath "$OPTARG")
;;
d)
devnet_deployment_file=$(realpath "$OPTARG")
;;
m)
template_hash="$OPTARG"
;;
h)
usage
;;
v)
VERBOSE=1
;;
\?)
err "$OPTARG is not a valid option"
usage
;;
esac
done

if [[ -z $template_hash ]]; then
err "missing machine-template-hash"
usage
fi

readonly devnet_anvil_state_file devnet_deployment_file template_hash

# From here on, any exit deserves a clean up
trap finish EXIT ERR

log "starting devnet creation"
work_dir=$(mktemp -d)
readonly work_dir
check_error $? "create temp dir"
verbose "created $work_dir"

anvil_pid=""
anvil_up \
anvil_pid\
"$devnet_anvil_state_file"
check_error $? "start anvil"
log "started anvil (pid=$anvil_pid)"

forge_prepare \
"$work_dir" \
"$forge_remappings_file"
log "prepared forge environment"

deploy_libraries
deploy_portals
deploy_relay
log "deployed contracts"

create_factories \
dapp_factory_address \
auth_hist_factory_address
log "created factories"

create_dapp \
dapp_address \
"$auth_hist_factory_address" \
"$dapp_factory_address"
log "created CartesiDApp"

generate_deployment_file \
"$devnet_deployment_file"

print_report
log "done creating devnet"
Loading

0 comments on commit ea122fe

Please sign in to comment.