|
set export |
|
set shell := ["zsh", "-cu"] |
|
|
|
NETWORKS := `echo $HOME` + "/networks" |
|
# NAME := "indexerboxes" |
|
NAME := "niftynetwork" |
|
TEMP_NETWORK := NETWORKS + "/" + NAME |
|
# GO_ALGORAND := "../../.." |
|
GO_ALGORAND := ".." |
|
NODE_TEMPLATE := GO_ALGORAND + "/test/testdata/nettemplates/OneNodeFuture.json" |
|
ALGORAND_DATA := TEMP_NETWORK + "/Primary" |
|
BOXES_TEAL := "boxes.teal" |
|
|
|
# --- SUMMARY --- # |
|
|
|
# list all available commands |
|
default: |
|
just --list |
|
|
|
# echo all variables |
|
@echo: |
|
echo NETWORKS: $NETWORKS |
|
echo NAME: $NAME |
|
echo TEMP_NETWORK: $TEMP_NETWORK |
|
echo GO_ALGORAND: $GO_ALGORAND |
|
echo NODE_TEMPLATE: $NODE_TEMPLATE |
|
echo ALGORAND_DATA: $ALGORAND_DATA |
|
echo BOXES_TEAL: $BOXES_TEAL |
|
|
|
# --- GENERATOR SCRIPT COMMANDS --- # |
|
|
|
# generate an arbitrary number of app and box scenarios, each with up to BOXES_PER_APP boxes |
|
gen-mult-app-boxes NUM_APPS="10" BOXES_PER_APP="2048": |
|
#!/usr/bin/env python3 |
|
import subprocess |
|
from subprocess import CalledProcessError |
|
|
|
num_apps = int({{NUM_APPS}}) |
|
print(f"{num_apps=}") |
|
for i in range(num_apps): |
|
print("\n", "\n", "\n", f"gen-app-and-box-scenarios #{i+1}" ) |
|
subprocess.run(["just", "gen-app-and-box-scenarios", "{{BOXES_PER_APP}}"]).check_returncode() |
|
|
|
|
|
# create an app and add up to BOXES_PER_APP random boxes to it in a multi-threaded fashion |
|
gen-app-and-box-scenarios BOXES_PER_APP="10": |
|
#!/usr/bin/env python3 |
|
from concurrent.futures import ThreadPoolExecutor |
|
import json |
|
import logging |
|
import random |
|
import string |
|
import subprocess |
|
from subprocess import CalledProcessError |
|
import time |
|
|
|
CHARS = string.digits + string.ascii_letters |
|
VAL_SIZE = 24 |
|
BOXES_PER_APP = int({{BOXES_PER_APP}}) |
|
NLS = "\n" * 3 |
|
|
|
subprocess.run(["just", "app-create_fund"]).check_returncode() |
|
|
|
def worker(thread_number): |
|
logging.info(f"HELLO from {thread_number}!") |
|
|
|
create_cpe = set_cpe = test_cpe = del_cpe = None |
|
|
|
rand_key_size = random.randint(4, 64) |
|
rand_key = "".join(random.choice(CHARS) for _ in range(rand_key_size)) |
|
print(f"{NLS}{thread_number}: {rand_key=}") |
|
try: |
|
subprocess.run(["just", "box-create", rand_key]).check_returncode() |
|
except CalledProcessError as cpe: |
|
create_cpe = str(cpe) |
|
|
|
rand_val = "".join(random.choice(CHARS) for _ in range(VAL_SIZE)) |
|
print(f"{NLS}{thread_number}: {rand_val=}") |
|
try: |
|
subprocess.run(["just", "box-set", rand_key, rand_val]).check_returncode() |
|
except CalledProcessError as cpe: |
|
set_cpe = str(cpe) |
|
|
|
print(f"{NLS}{thread_number}: checking {rand_val=}") |
|
try: |
|
subprocess.run(["just", "box-test", rand_key, rand_val]).check_returncode() |
|
except CalledProcessError as cpe: |
|
test_cpe = str(cpe) |
|
|
|
delete = random.choice([True, False]) |
|
if delete: |
|
print(f"{NLS}{thread_number}: deleting") |
|
try: |
|
subprocess.run(["just", "box-delete", rand_key]).check_returncode() |
|
except CalledProcessError as cpe: |
|
del_cpe = str(cpe) |
|
|
|
return { |
|
"thread_number": thread_number, |
|
"key_size": rand_key_size, |
|
"key": rand_key, |
|
"val": rand_val, |
|
"deleted": delete, |
|
"called_process_errors": { |
|
"create_cpe": create_cpe, |
|
"set_cpe": set_cpe, |
|
"test_cpe": test_cpe, |
|
"del_cpe": del_cpe, |
|
}, |
|
} |
|
|
|
format = "%(asctime)s: %(message)s" |
|
logging.basicConfig(format=format, level=logging.INFO, |
|
datefmt="%H:%M:%S") |
|
|
|
results = [] |
|
with ThreadPoolExecutor() as executor: |
|
for r in executor.map(worker, range(BOXES_PER_APP)): |
|
results.append(r) |
|
|
|
print(json.dumps(results, indent=2)) |
|
|
|
for result in results: |
|
for err in result["called_process_errors"].values(): |
|
if err: |
|
raise err |
|
|
|
# --- HIGHER LEVEL --- # |
|
|
|
# create and then start (error if already created) |
|
@create_and_start: create start status |
|
sleep 5 |
|
just status |
|
|
|
# create an app and then fund it |
|
@app-create_fund: app-create last-app-fund |
|
|
|
|
|
# --- BOX PUT: HIGHER LEVEL --- # |
|
|
|
# create box[BOX] for last app with provided key variable BOX |
|
@box-create $BOX: |
|
just app-call-last '\"create\", \"{{BOX}}\"' |
|
|
|
# set box[BOX]=VAL for last app with key BOX and val VAL |
|
@box-set $BOX $VAL: |
|
just app-call-last '\"set\", \"{{BOX}}\", \"{{VAL}}\"' |
|
|
|
# set box[BOX]=VAL for last app with key BOX and val VAL |
|
@box-test $BOX $VAL: |
|
just app-call-last '\"check\", \"{{BOX}}\", \"{{VAL}}\"' |
|
|
|
# delete box[BOX] for last app |
|
@box-delete $BOX: |
|
just app-call-last '\"delete\", \"{{BOX}}\"' |
|
|
|
# stop and tear down the node network. WARNING: YOU WILL LOSE ALL YOUR NODE DATA FROM THE FILE SYSTEM. |
|
@stop_and_nuke: stop nuke |
|
|
|
# --- PRE-REQUISITES --- # |
|
|
|
# calculate an app's address using the python SDK |
|
app-address *ARGS: |
|
#!/usr/bin/env python3 |
|
from algosdk import logic |
|
print(logic.get_application_address({{ ARGS }})) |
|
|
|
# --- NETWORKS / NODE --- # |
|
|
|
# create a private network with one node (error if already created) |
|
@create: |
|
mkdir -p $NETWORKS |
|
goal network create -n $NAME -r $TEMP_NETWORK -t $NODE_TEMPLATE |
|
|
|
# start a the network (error if already running or not created) |
|
@start: |
|
goal node start |
|
|
|
# status of network node |
|
@status: |
|
goal node status && echo "RUNNING" || echo "NOT RUNNING" |
|
|
|
# stop the running node (error if not running) |
|
@stop: |
|
goal node stop |
|
|
|
# remove the node's data from the file system |
|
@nuke: |
|
echo "deleting $TEMP_NETWORK" |
|
rm -rf $TEMP_NETWORK |
|
|
|
# --- ACCOUNTS --- # |
|
|
|
# list all associated accounts |
|
@list: |
|
goal account list |
|
|
|
# create a new account without renaming it to a human friendly local alias |
|
@raw-new-account: |
|
goal account new | awk '{print $NF}' |
|
|
|
@account-alias $ACCOUNT: |
|
just list | grep {{ACCOUNT}} | awk '{print $2}' |
|
|
|
# create a new locally aliased account |
|
@new-account $ALIAS $ACCOUNT=`just raw-new-account`: |
|
goal account rename `just account-alias {{ACCOUNT}}` {{ALIAS}} |
|
|
|
# create a new multisig account with threshold 1 using provided accounts (cannot handle aliases) |
|
@raw-msig-account *ACCOUNTS: |
|
goal account multisig new -T 1 {{ACCOUNTS}} | awk '{print $NF}' |
|
|
|
# create a new multisig account with given ALIAS and threshold 1 using provided accounts (cannot handle aliases) |
|
@new-msig-account $ALIAS *ACCOUNTS: |
|
goal account rename `just account-alias $(just raw-msig-account {{ACCOUNTS}})` {{ALIAS}} |
|
|
|
# funding account's address |
|
@funder: |
|
just list | awk '{print $2}' |
|
|
|
# provide information about a given account |
|
@info $ACCOUNT=`just funder`: |
|
goal account info --address {{ACCOUNT}} |
|
|
|
# provide an account's balance |
|
@balance $ACCOUNT=`just funder`: |
|
goal account balance --address {{ACCOUNT}} |
|
|
|
# funder's most recently created app-id |
|
@last-app-id: |
|
just info | grep ID | tail -n 1 | cut -d "," -f1 | awk '{print $2}' |
|
|
|
# the account address of the funders most recently created app-id |
|
@last-app-address: |
|
just app-address `just last-app-id` |
|
|
|
# --- ASSETS --- # |
|
|
|
# create a dummy asset for the provided FUNDER. Copy pasta from: https://dappradar.com/blog/algorand-dapp-development-2-standard-asset-management |
|
@asset-create $FUNDER=`just funder`: |
|
goal asset create --creator {{FUNDER}} --total 1000000 --unitname bUSD --name "Balgorand USD" --asseturl "https://b-usd.com" --decimals 9 |
|
|
|
# --- APPLICATIONS --- # |
|
|
|
# information about an application of given id |
|
@app-info $APP_ID=`just last-app-id`: |
|
goal app info --app-id {{APP_ID}} |
|
|
|
# print out the boxes teal program |
|
@boxes_teal: |
|
cat $BOXES_TEAL |
|
|
|
# shortcut for the approval and clear program `goal app create` params |
|
@programs: |
|
echo "--approval-prog $BOXES_TEAL --clear-prog clear.teal" |
|
|
|
# shortcut for the storage params of `goal app create` |
|
@app-vars $GBS="0" $GI="0" $LBS="0" $LI="0": |
|
echo "--global-byteslices $GBS --global-ints $GI --local-byteslices $LBS --local-ints $LI" |
|
|
|
# shortcut for creating the arguments of an app call |
|
box-app-args *ARGS: |
|
#!/usr/bin/env python3 |
|
args = [] |
|
box_arg = "" |
|
i = 0 |
|
for arg in {{ARGS}}: |
|
try: |
|
int(arg) |
|
arg = f"int:{arg}" |
|
except Exception: |
|
arg = f"str:{arg}" |
|
args.extend(["--app-arg", arg]) |
|
if i == 1: |
|
box_arg = f"--box {arg}" |
|
i += 1 |
|
if box_arg: |
|
args = [box_arg] + args |
|
print(*args) |
|
|
|
# create an app funded by funder account |
|
@app-create $GBS="0" $GI="0" $LBS="0" $LI="0": |
|
echo "goal app create --creator `just funder` `just programs` `just app-vars $GBS $GI $LBS $LI`" |
|
goal app create --creator `just funder` `just programs` `just app-vars $GBS $GI $LBS $LI` |
|
|
|
# call the last app from the funder address using ARGS |
|
@app-call-last *ARGS='\"create\", \"mybox\"': |
|
(set -x; goal app call --app-id `just last-app-id` --from `just funder` `just box-app-args {{ARGS}}`) |
|
|
|
# --- BOX INFO --- # |
|
|
|
# get all the boxes associated a given app-id |
|
app-box-list $APP_ID=`just last-app-id`: |
|
goal app box list --app-id {{APP_ID}} --max 0 |
|
|
|
# get box information for agiven app-id and box anme |
|
app-box-info $APP_ID=`just last-app-id` $BOX="str:mybox": |
|
goal app box info --app-id {{APP_ID}} --name {{BOX}} |
|
|
|
|
|
# --- CLERK --- # |
|
|
|
# send from one account to another a given amount |
|
@send $FROM $TO $AMOUNT: |
|
goal clerk send --from {{FROM}} --to {{TO}} --amount {{AMOUNT}} |
|
|
|
# fund the most recently created app |
|
@last-app-fund $AMOUNT=`echo 133713371337`: |
|
just send `just funder` `just last-app-address` {{AMOUNT}} |
|
|
|
# --- CONSENSUS PARAMS --- # |
|
|
|
# list all consensus param declarations |
|
@consensus-params-list: |
|
cat ${GO_ALGORAND}/config/consensus.go | egrep " (bool|byte|int$|uint|map\[|Duration|PaysetCommitType)" | egrep -v "type|=|func|,|//" |
|
|
|
# print out the value history of a consensus param |
|
@consensus-param $CP="MaximumMinimumBalance": |
|
cat ${GO_ALGORAND}/config/consensus.go | grep {{CP}} || echo "{{CP}} not found in consensus.go" |
|
|
|
# consensus params for program size |
|
consensus-prog-size: |
|
just consensus-param LogicSigMaxSize |
|
just consensus-param MaxAppProgramLen |
|
|
|
# consensus param for LogicSigMaxCost |
|
consensus-prog-cost: |
|
just consensus-param MaxCost |
|
just consensus-param MaxAppProgramCost |
|
|
|
# consensus params for program pages |
|
@consensus-prog-pages: |
|
just consensus-param MaxExtraAppProgramPages |
|
|
|
# consnsus params for foreign refs: |
|
consensus-foreign-refs: |
|
just consensus-param MaxAppTxnAccounts |
|
just consensus-param MaxAppTxnForeignApps |
|
just consensus-param MaxAppTxnForeignAssets |
|
just consensus-param MaxAppTotalTxnReferences |
|
just consensus-param MaxAppBoxReferences |
|
|
|
# consensus params for local/global storage: |
|
consensus-storage: |
|
just consensus-param MaxAppKeyLen |
|
just consensus-param MaxAppBytesValueLen |
|
just consensus-param MaxAppSumKeyValueLens |
|
just consensus-param MaxLocalSchemaEntries |
|
just consensus-param MaxGlobalSchemaEntries |
|
|
|
# consensus params for min-balance calc: |
|
consensus-minbal: |
|
just consensus-param SchemaMinBalancePerEntry |
|
just consensus-param SchemaUintMinBalance |
|
just consensus-param SchemaBytesMinBalance |
|
just consensus-param BoxFlatMinBalance |
|
just consensus-param BoxByteMinBalance |
|
|
|
# consensus params for boxes: |
|
consensus-boxes: |
|
just consensus-param MaxAppKeyLen |
|
just consensus-param MaxBoxSize |
|
just consensus-param BoxFlatMinBalance |
|
just consensus-param BoxByteMinBalance |
|
just consensus-param MaxAppBoxReferences |
|
just consensus-param BytesPerBoxReference |
|
|
|
# --- MISCELLANEOUS --- # |
|
|
|
# print out the network's algod & kmd token and network/process info |
|
@client-info: |
|
echo "algod.token: "$(cat ${ALGORAND_DATA}/algod.token) |
|
echo "algod.net: "$(cat ${ALGORAND_DATA}/algod.net) |
|
echo "algod.pid: "$(cat ${ALGORAND_DATA}/algod.pid) |
|
echo "kmd.token: "$(cat ${ALGORAND_DATA}/kmd-v0.5/kmd.token) |
|
echo "kmd.net---->" |
|
cat ${ALGORAND_DATA}/kmd-v0.5/kmd.log | grep 127.0.0.1 | head -n 1 | cut -d '"' -f4 |
|
|
|
# print out broadcastQueueBulk's channel size ... the default is 100 which is too small for the example |
|
@broadcast-queue-size: |
|
echo "default is 100. What is it actually in network/wsNetwork.go ?" |
|
cat {{GO_ALGORAND}}/network/wsNetwork.go | grep "wn.broadcastQueueBulk = make(chan broadcastRequest" | cut -d "," -f2 | cut -d ")" -f1 | awk '{print $1}' |