mirror of
https://github.com/alexgo-io/stacks-subnets.git
synced 2026-04-30 20:52:16 +08:00
add rudimentary network testing tools, which helped reproduce and diagnose several networking bugs that have been plaguing production krypton
This commit is contained in:
15
net-test/README.md
Normal file
15
net-test/README.md
Normal file
@@ -0,0 +1,15 @@
|
||||
# Stacks Network Testing
|
||||
|
||||
A rudimentary set of tools for testing multiple Stacks nodes at once, locally.
|
||||
Relevant files:
|
||||
|
||||
* `bin/start.sh` -- start up a master node, a miner node, or a follower node, as
|
||||
well as ancilliary processes.
|
||||
* `bin/faucet.sh` -- a rudimentary Bitcoin faucet.
|
||||
* `bin/txload.sh` -- a rudimentary Stacks transaction generator and load-tester.
|
||||
* `etc/*.in` -- templates that `bin/start.sh` uses to create configuration
|
||||
files.
|
||||
|
||||
To use, you will need to install `stacks-node`, `blockstack-cli`,
|
||||
`bitcoin-neon-controller`, and `bin/faucet.sh` to somewhere in your `$PATH`.
|
||||
You will also need a recent `bitcoind` and `bitcoin-cli`.
|
||||
26
net-test/bin/config.sh
Normal file
26
net-test/bin/config.sh
Normal file
@@ -0,0 +1,26 @@
|
||||
# local config
|
||||
__ROOT="$(realpath "$(pwd)"/..)"
|
||||
__ETC="$_ROOT/etc"
|
||||
__MNT="$_ROOT/mnt"
|
||||
|
||||
BITCOIN_CONF="$__ETC/bitcoin.conf"
|
||||
BITCOIN_CONTROLLER_CONF="$__ETC/bitcoin-neon-controller.toml"
|
||||
STACKS_MASTER_CONF="$__ETC/stacks-master.toml"
|
||||
STACKS_MINER_CONF="$__ETC/stacks-miner.toml"
|
||||
STACKS_FOLLOWER_CONF="$__ETC/stacks-follower.toml"
|
||||
|
||||
BITCOIN_LOGFILE="$__MNT/bitcoin.log"
|
||||
BITCOIN_NEON_CONTROLLER_LOGFILE="$__MNT/bitcoin-neon-controller.log"
|
||||
|
||||
STACKS_MASTER_LOGFILE="$__MNT/stacks-node-master.log"
|
||||
STACKS_MINER_LOGFILE="$__MNT/stacks-node-miner.log"
|
||||
STACKS_FOLLOWER_LOGFILE="$__MNT/stacks-node-follower.log"
|
||||
FAUCET_LOGFILE="$__MNT/faucet.log"
|
||||
|
||||
STACKS_MASTER_PUBLIC_IP="127.0.0.1"
|
||||
|
||||
__NOW="$(date +%s)"
|
||||
STACKS_CHAINSTATE_DIR="$__MNT/stacks-chainstate-$__NOW"
|
||||
BITCOIN_DATA_DIR="$__MNT/bitcoin-$__NOW"
|
||||
|
||||
echo >&2 "Loaded external config"
|
||||
294
net-test/bin/faucet.sh
Executable file
294
net-test/bin/faucet.sh
Executable file
@@ -0,0 +1,294 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Yup, it's a faucet HTTP server written in bash. This is what my life has come to.
|
||||
|
||||
MAX_BODY_LENGTH=65536
|
||||
FAUCET_AMOUNT="1.0"
|
||||
|
||||
MODE="$1"
|
||||
BITCOIN_CONF="$2"
|
||||
|
||||
set -uo pipefail
|
||||
|
||||
exit_error() {
|
||||
printf >&2 "$1"
|
||||
exit 1
|
||||
}
|
||||
|
||||
log() {
|
||||
printf >&2 "%s\n" "$1"
|
||||
}
|
||||
|
||||
http_ok() {
|
||||
local CONTENT_LENGTH
|
||||
local CONTENT_TYPE
|
||||
|
||||
CONTENT_LENGTH=$1
|
||||
CONTENT_TYPE=$2
|
||||
printf "HTTP/1.0 200 OK\r\nContent-Length: $CONTENT_LENGTH\r\nContent-Type: $CONTENT_TYPE\r\n\r\n"
|
||||
}
|
||||
|
||||
http_401() {
|
||||
printf "HTTP/1.0 401 Unsupported Method\r\n\r\n"
|
||||
}
|
||||
|
||||
http_500() {
|
||||
local ERR="$1"
|
||||
local ERR_LEN=${#ERR}
|
||||
printf "HTTP/1.0 500 Internal Server error\r\nContent-Length: $ERR_LEN\r\nContent-Type: text/plain\r\n\r\n$ERR"
|
||||
}
|
||||
|
||||
http_404() {
|
||||
printf "HTTP/1.0 404 Not Found\r\n\r\n"
|
||||
}
|
||||
|
||||
get_ping() {
|
||||
http_ok 5 "text/plain"
|
||||
printf "alive"
|
||||
return 0
|
||||
}
|
||||
|
||||
get_bitcoin_ping() {
|
||||
bitcoin-cli -conf="$BITCOIN_CONF" ping >/dev/null 2>&1
|
||||
if [ $? -eq 0 ]; then
|
||||
local MSG="Bitcoind appears to be running"
|
||||
http_ok ${#MSG} "text/plain"
|
||||
echo "$MSG"
|
||||
return 0
|
||||
else
|
||||
http_500 "Bitcoind appears to be stopped"
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
get_balance() {
|
||||
BALANCE="$(bitcoin-cli -conf="$BITCOIN_CONF" getbalance 2>&1)"
|
||||
if [ $? -eq 0 ]; then
|
||||
http_ok "${#BALANCE}" "text/plain"
|
||||
echo "$BALANCE"
|
||||
return 0
|
||||
else
|
||||
http_500 "$BALANCE"
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
get_utxos() {
|
||||
local ADDR="$1"
|
||||
UTXOS="$(bitcoin-cli -conf="$BITCOIN_CONF" listunspent 1 1000000 "[\"$ADDR\"]" 2>&1)"
|
||||
if [ $? -eq 0 ]; then
|
||||
http_ok ${#UTXOS} "application/json"
|
||||
echo "$UTXOS"
|
||||
return 0
|
||||
else
|
||||
http_500 "$UTXOS"
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
get_confirmations() {
|
||||
local TXID="$1"
|
||||
CONFIRMATIONS="$(bitcoin-cli -conf="$BITCOIN_CONF" gettransaction "$TXID" | jq -r '.confirmations')"
|
||||
RC=$?
|
||||
if [ $RC -eq 0 ]; then
|
||||
http_ok ${#CONFIRMATIONS} "text/plain"
|
||||
echo "$CONFIRMATIONS"
|
||||
return 0
|
||||
elif [ $RC -eq 1 ]; then
|
||||
http_500 "$CONFIRMATIONS"
|
||||
return 1
|
||||
else
|
||||
http_404
|
||||
return 2
|
||||
fi
|
||||
}
|
||||
|
||||
post_sendbtc() {
|
||||
local ADDR
|
||||
|
||||
# format: address\n
|
||||
read ADDR
|
||||
TXID="$(bitcoin-cli -conf="$BITCOIN_CONF" sendtoaddress "$ADDR" "$FAUCET_AMOUNT" 2>&1)"
|
||||
if [ $? -ne 0 ]; then
|
||||
http_500 "$TXID"
|
||||
return 1
|
||||
fi
|
||||
|
||||
ERR="$(bitcoin-cli -conf="$BITCOIN_CONF" importaddress "$ADDR" 2>&1)"
|
||||
if [ $? -ne 0 ]; then
|
||||
http_500 "$ERR"
|
||||
return 1
|
||||
fi
|
||||
|
||||
http_ok ${#TXID} "text/plain"
|
||||
echo "$TXID"
|
||||
return 0
|
||||
}
|
||||
|
||||
parse_request() {
|
||||
local REQLINE
|
||||
local VERB=""
|
||||
local REQPATH=""
|
||||
local CONTENT_TYPE=""
|
||||
local CONTENT_LENGTH=0
|
||||
|
||||
while read REQLINE; do
|
||||
# trim trailing whitespace
|
||||
REQLINE="${REQLINE%"${REQLINE##*[![:space:]]}"}"
|
||||
if [ -z "$REQLINE" ]; then
|
||||
break
|
||||
fi
|
||||
|
||||
# log " reqline = '$REQLINE'"
|
||||
|
||||
TOK="$(echo "$REQLINE" | egrep "GET|POST" | sed -r 's/^(GET|POST)[ ]+([^ ]+)[ ]+HTTP\/1.(0|1)$/\1 \2/g')"
|
||||
if [ -n "$TOK" ] && [ -z "$VERB" ] && [ -z "$REQPATH" ]; then
|
||||
set -- $TOK
|
||||
VERB="$1"
|
||||
REQPATH="$2"
|
||||
continue
|
||||
fi
|
||||
|
||||
TOK="$(echo "$REQLINE" | grep -i "content-type" | cut -d ' ' -f 2)"
|
||||
if [ -n "$TOK" ] && [ -z "$CONTENT_TYPE" ]; then
|
||||
CONTENT_TYPE="${TOK,,}"
|
||||
continue
|
||||
fi
|
||||
|
||||
TOK="$(echo "$REQLINE" | grep -i "content-length" | cut -d ' ' -f 2)"
|
||||
if [ -n "$TOK" ] && [ $CONTENT_LENGTH -eq 0 ]; then
|
||||
if [[ "$TOK" =~ ^[0-9]+$ ]]; then
|
||||
CONTENT_LENGTH="$TOK"
|
||||
continue
|
||||
fi
|
||||
fi
|
||||
done
|
||||
|
||||
if [ $CONTENT_LENGTH -gt $MAX_BODY_LENGTH ]; then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ -z "$VERB" ] || [ -z "$REQPATH" ]; then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# log " verb = '$VERB', reqpath = '$REQPATH', content-type = '$CONTENT_TYPE', content-length = '$CONTENT_LENGTH'"
|
||||
|
||||
printf "$VERB\n$REQPATH\n$CONTENT_TYPE\n$CONTENT_LENGTH\n"
|
||||
dd bs=$CONTENT_LENGTH 2>/dev/null
|
||||
return 0
|
||||
}
|
||||
|
||||
handle_request() {
|
||||
local VERB
|
||||
local REQPATH
|
||||
local CONTENT_TYPE
|
||||
local CONTENT_LENGTH
|
||||
local STATUS=200
|
||||
|
||||
read VERB
|
||||
read REQPATH
|
||||
read CONTENT_TYPE
|
||||
read CONTENT_LENGTH
|
||||
|
||||
case "$VERB" in
|
||||
GET)
|
||||
case "$REQPATH" in
|
||||
/ping)
|
||||
get_ping
|
||||
if [ $? -ne 0 ]; then
|
||||
STATUS=500
|
||||
fi
|
||||
;;
|
||||
|
||||
/bitcoin)
|
||||
get_bitcoin_ping
|
||||
if [ $? -ne 0 ]; then
|
||||
STATUS=500
|
||||
fi
|
||||
;;
|
||||
|
||||
/balance)
|
||||
get_balance
|
||||
if [ $? -ne 0 ]; then
|
||||
STATUS=500
|
||||
fi
|
||||
;;
|
||||
|
||||
/confirmations/*)
|
||||
TXID="${REQPATH#/confirmations/}"
|
||||
get_confirmations "$TXID"
|
||||
if [ $? -eq 1 ]; then
|
||||
STATUS=500
|
||||
elif [ $? -eq 2 ]; then
|
||||
STATUS=404
|
||||
fi
|
||||
;;
|
||||
|
||||
/utxos/*)
|
||||
ADDR="${REQPATH#/utxos/}"
|
||||
get_utxos "$ADDR"
|
||||
if [ $? -ne 0 ]; then
|
||||
STATUS=500
|
||||
fi
|
||||
;;
|
||||
*)
|
||||
http_404
|
||||
STATUS=404
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
POST)
|
||||
case "$REQPATH" in
|
||||
/fund)
|
||||
if [ "$CONTENT_TYPE" != "text/plain" ]; then
|
||||
http_401
|
||||
STATUS=401
|
||||
else
|
||||
post_sendbtc
|
||||
if [ $? -ne 0 ]; then
|
||||
STATUS=500
|
||||
fi
|
||||
fi
|
||||
;;
|
||||
*)
|
||||
http_404
|
||||
STATUS=404
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
*)
|
||||
http_401
|
||||
STATUS=404
|
||||
;;
|
||||
esac
|
||||
|
||||
log "[$(date +%s)] $VERB $REQPATH ($CONTENT_LENGTH bytes) - $STATUS"
|
||||
}
|
||||
|
||||
usage() {
|
||||
exit_error "Usage:\n $0 serve </path/to/bitcoin.conf>\n $0 <port> </path/to/bitcoin.conf>\n"
|
||||
}
|
||||
|
||||
if [ -z "$MODE" ] || [ -z "$BITCOIN_CONF" ]; then
|
||||
usage
|
||||
fi
|
||||
|
||||
if [ "$MODE" = "serve" ]; then
|
||||
parse_request | handle_request
|
||||
exit 0
|
||||
elif [ "$MODE" = "parse" ]; then
|
||||
# undocumented test mode
|
||||
parse_request
|
||||
exit 0
|
||||
fi
|
||||
|
||||
if ! [[ $MODE =~ ^[0-9]+$ ]]; then
|
||||
usage
|
||||
fi
|
||||
|
||||
for cmd in ncat bitcoin-cli egrep grep tr dd sed cut date; do
|
||||
which $cmd >/dev/null 2>&1 || exit_error "Missing command: $cmd"
|
||||
done
|
||||
|
||||
exec ncat -k -l -p $MODE -c "bash $0 serve \"$BITCOIN_CONF\""
|
||||
363
net-test/bin/start.sh
Executable file
363
net-test/bin/start.sh
Executable file
@@ -0,0 +1,363 @@
|
||||
#!/bin/bash
|
||||
|
||||
MODE="$1"
|
||||
set -uo pipefail
|
||||
|
||||
BITCOIN_LOGFILE="/mnt/bitcoin.log"
|
||||
BITCOIN_NEON_CONTROLLER_LOGFILE="/mnt/bitcoin-neon-controller.log"
|
||||
STACKS_MASTER_LOGFILE="/mnt/stacks-node-master.log"
|
||||
STACKS_MINER_LOGFILE="/mnt/stacks-node-miner.log"
|
||||
STACKS_FOLLOWER_LOGFILE="/mnt/stacks-node-follower.log"
|
||||
FAUCET_LOGFILE="/mnt/faucet.log"
|
||||
|
||||
BITCOIN_CONF="/etc/bitcoin.conf"
|
||||
BITCOIN_CONTROLLER_CONF="/etc/bitcoin-neon-controller.toml"
|
||||
STACKS_MASTER_CONF="/etc/stacks-master.toml"
|
||||
STACKS_MINER_CONF="/etc/stacks-miner.toml"
|
||||
STACKS_FOLLOWER_CONF="/etc/stacks-follower.toml"
|
||||
|
||||
STACKS_CHAINSTATE_DIR="/mnt/stacks-chainstate"
|
||||
BITCOIN_DATA_DIR="/mnt/bitcoin"
|
||||
|
||||
STACKS_MASTER_PUBLIC_IP="127.0.0.1"
|
||||
|
||||
FAUCET_PORT=8080
|
||||
|
||||
if [ -f "./config.sh" ]; then
|
||||
source ./config.sh
|
||||
fi
|
||||
|
||||
function exit_error() {
|
||||
printf "$1" >&2
|
||||
exit 1
|
||||
}
|
||||
|
||||
function log() {
|
||||
printf "%s" "$1" >&2
|
||||
}
|
||||
|
||||
function logln() {
|
||||
printf "%s\n" "$1" >&2
|
||||
}
|
||||
|
||||
start_bitcoind() {
|
||||
logln "Setting up Bitcoind..."
|
||||
test -f "$BITCOIN_CONF".in || exit_error "No such file or directory: $BITCOIN_CONF"
|
||||
mkdir -p "$BITCOIN_DATA_DIR" || exit_error "Failed to create Bitcoin data directory $BITCOIN_DATA_DIR"
|
||||
|
||||
log " Generating Bitcoind config file..."
|
||||
sed -r \
|
||||
-e "s!@@BITCOIN_DATA_DIR@@!$BITCOIN_DATA_DIR!g" \
|
||||
"$BITCOIN_CONF".in \
|
||||
> "$BITCOIN_CONF"
|
||||
logln "ok"
|
||||
|
||||
log "Starting bitcoind..."
|
||||
bitcoind -conf="$BITCOIN_CONF" >"$BITCOIN_LOGFILE" 2>&1 &
|
||||
local BITCOIN_PID=$!
|
||||
logln "PID $BITCOIN_PID"
|
||||
|
||||
while true; do
|
||||
bitcoin-cli -regtest -conf="$BITCOIN_CONF" ping >/dev/null 2>&1
|
||||
if [ $? -eq 0 ]; then
|
||||
break
|
||||
fi
|
||||
sleep 1
|
||||
done
|
||||
|
||||
echo "$BITCOIN_PID"
|
||||
return 0
|
||||
}
|
||||
|
||||
start_bitcoind_controller() {
|
||||
logln "Setting up Bitcoind controller..."
|
||||
test -f "$BITCOIN_CONTROLLER_CONF".in || exit_error "No such file or directory: $BITCOIN_CONTROLLER_CONF.in"
|
||||
|
||||
log " Generating Bitcoind controller config file..."
|
||||
local NOW="$(date +%s)"
|
||||
sed -r \
|
||||
-e "s/@@BITCOIN_NEON_CONTROLLER_GENESIS_TIMESTAMP@@/$NOW/g" \
|
||||
"$BITCOIN_CONTROLLER_CONF".in \
|
||||
> "$BITCOIN_CONTROLLER_CONF"
|
||||
logln "ok"
|
||||
|
||||
log "Starting bitcoind controller..."
|
||||
bitcoin-neon-controller "$BITCOIN_CONTROLLER_CONF" >"$BITCOIN_NEON_CONTROLLER_LOGFILE" 2>&1 &
|
||||
local RC=$?
|
||||
local BITCOIN_NEON_CONTROLLER_PID=$!
|
||||
|
||||
if [ $RC -ne 0 ]; then
|
||||
logln "FAILED"
|
||||
return 1
|
||||
fi
|
||||
|
||||
logln "PID $BITCOIN_NEON_CONTROLLER_PID"
|
||||
|
||||
echo "$BITCOIN_NEON_CONTROLLER_PID"
|
||||
return 0
|
||||
}
|
||||
|
||||
start_faucet() {
|
||||
logln "Setting up Bitcoin faucet..."
|
||||
test -f "$BITCOIN_CONTROLLER_CONF" || exit_error "No such file or directory: $BITCOIN_CONTROLLER_CONF"
|
||||
test -f "$BITCOIN_CONF" || exit_error "No such file or directory: $BITCOIN_CONF"
|
||||
|
||||
local PRIVKEY="$(cat "$BITCOIN_CONTROLLER_CONF" | grep "# WIF" | cut -d ' ' -f 3)"
|
||||
|
||||
log " Importing faucet private key..."
|
||||
bitcoin-cli -conf="$BITCOIN_CONF" importprivkey "$PRIVKEY" >"$FAUCET_LOGFILE" 2>&1
|
||||
local RC=$?
|
||||
if [ $RC -ne 0 ]; then
|
||||
logln "FAILED!"
|
||||
return 1
|
||||
fi
|
||||
logln "ok"
|
||||
|
||||
local MINER_ADDR="$(cat "$BITCOIN_CONTROLLER_CONF" | grep "miner_address =" | cut -d ' ' -f 3 | sed -r 's/"//g')"
|
||||
|
||||
log " Importing miner address $MINER_ADDR..."
|
||||
|
||||
echo "Try importing miner address $MINER_ADDR" >>"$FAUCET_LOGFILE"
|
||||
bitcoin-cli -conf="$BITCOIN_CONF" importaddress "$MINER_ADDR" >>"$FAUCET_LOGFILE" 2>&1
|
||||
RC=$?
|
||||
if [ $RC -ne 0 ]; then
|
||||
logln "FAILED!"
|
||||
return 1
|
||||
fi
|
||||
|
||||
logln "ok"
|
||||
|
||||
log "Starting Bitcoin faucet..."
|
||||
faucet.sh "$FAUCET_PORT" "$BITCOIN_CONF" >"$FAUCET_LOGFILE" 2>&1 &
|
||||
local FAUCET_PID=$!
|
||||
logln "PID $FAUCET_PID"
|
||||
|
||||
echo "$FAUCET_PID"
|
||||
return 0
|
||||
}
|
||||
|
||||
start_stacks_master_node() {
|
||||
logln "Setting up Stacks master node..."
|
||||
test -f "$STACKS_MASTER_CONF".in || exit_error "No such file or directory: $STACKS_MASTER_CONF.in"
|
||||
|
||||
log " Generating Stacks master config file..."
|
||||
sed -r \
|
||||
-e "s!@@STACKS_CHAINSTATE_DIR@@!$STACKS_CHAINSTATE_DIR!g" \
|
||||
-e "s!@@STACKS_PUBLIC_IP@@!$STACKS_MASTER_PUBLIC_IP!g" \
|
||||
"$STACKS_MASTER_CONF".in \
|
||||
> "$STACKS_MASTER_CONF"
|
||||
logln "ok"
|
||||
|
||||
log "Starting Stacks master node..."
|
||||
BLOCKSTACK_DEBUG=1 RUST_BACKTRACE=full stacks-node start --config="$STACKS_MASTER_CONF" >"$STACKS_MASTER_LOGFILE" 2>&1 &
|
||||
local STACKS_PID=$!
|
||||
logln "PID $STACKS_PID"
|
||||
|
||||
echo "$STACKS_PID"
|
||||
return 0
|
||||
}
|
||||
|
||||
start_stacks_miner_node() {
|
||||
logln "Setting up Stacks miner node..."
|
||||
test -f "$STACKS_MINER_CONF".in || exit_error "No such file or directory: $STACKS_MINER_CONF.in"
|
||||
|
||||
log " Generating Stacks miner config file..."
|
||||
local STACKS_MASTER_IP="$1"
|
||||
local BITCOIN_IP="$2"
|
||||
local FAUCET_URL="$3"
|
||||
local STACKS_MINER_SEED="$(blockstack-cli generate-sk | jq -r '.secretKey')"
|
||||
|
||||
sed -r \
|
||||
-e "s/@@STACKS_MASTER_IP@@/$STACKS_MASTER_IP/g" \
|
||||
-e "s/@@BITCOIN_IP@@/$BITCOIN_IP/g" \
|
||||
-e "s/@@STACKS_MINER_SEED@@/$STACKS_MINER_SEED/g" \
|
||||
-e "s!@@STACKS_CHAINSTATE_DIR@@!$STACKS_CHAINSTATE_DIR!g" \
|
||||
"$STACKS_MINER_CONF".in \
|
||||
> "$STACKS_MINER_CONF"
|
||||
logln "ok"
|
||||
|
||||
local BTCADDR="$(blockstack-cli --testnet addresses "$STACKS_MINER_SEED" | jq -r '.BTC')"
|
||||
local TIMEOUT=2
|
||||
local TXID=""
|
||||
local CONFIRMATIONS=0
|
||||
|
||||
log " Fetching BTC from the faucet for this miner ($BTCADDR)..."
|
||||
for i in $(seq 1 10); do
|
||||
TXID="$(curl -sf -X POST -d $BTCADDR$'\n' -H "content-type: text/plain" "$FAUCET_URL"/fund)"
|
||||
local RC=$?
|
||||
if [ $RC -ne 0 ]; then
|
||||
# curl failed, or we didn't get 200. Try again
|
||||
logln "FAILED! Try again in $TIMEOUT seconds..."
|
||||
sleep $TIMEOUT
|
||||
|
||||
TIMEOUT=$((TIMEOUT + $RANDOM % TIMEOUT))
|
||||
continue
|
||||
fi
|
||||
break
|
||||
done
|
||||
logln "txid $TXID"
|
||||
|
||||
log " Waiting for BTC to get confirmed..."
|
||||
for i in $(seq 1 5); do
|
||||
sleep 60
|
||||
local CONFIRMATIONS="$(curl -sf "$FAUCET_URL"/confirmations/"$TXID")"
|
||||
local RC=$?
|
||||
if [ $RC -ne 0 ]; then
|
||||
logln "FAILED! Try again (attempt $i)..."
|
||||
continue
|
||||
fi
|
||||
if [ $CONFIRMATIONS -gt 0 ]; then
|
||||
break
|
||||
fi
|
||||
done
|
||||
|
||||
if [ $CONFIRMATIONS -eq 0 ]; then
|
||||
logln "FAILED"
|
||||
return 1
|
||||
fi
|
||||
logln "ok"
|
||||
|
||||
log "Starting Stacks miner node..."
|
||||
BLOCKSTACK_DEBUG=1 RUST_BACKTRACE=full stacks-node start --config="$STACKS_MINER_CONF" >"$STACKS_MINER_LOGFILE" 2>&1 &
|
||||
local STACKS_PID=$!
|
||||
logln "PID $STACKS_PID"
|
||||
|
||||
echo "$STACKS_PID"
|
||||
return 0
|
||||
}
|
||||
|
||||
start_stacks_follower_node() {
|
||||
logln "Setting up Stacks follower node..."
|
||||
test -f "$STACKS_FOLLOWER_CONF".in || exit_error "No such file or directory: $STACKS_FOLLOWER_CONF.in"
|
||||
|
||||
log " Generating Stacks follower config file..."
|
||||
local STACKS_MASTER_IP="$1"
|
||||
local BITCOIN_IP="$2"
|
||||
sed -r \
|
||||
-e "s/@@STACKS_MASTER_IP@@/$STACKS_MASTER_IP/g" \
|
||||
-e "s/@@BITCOIN_IP@@/$BITCOIN_IP/g" \
|
||||
-e "s!@@STACKS_CHAINSTATE_DIR@@!$STACKS_CHAINSTATE_DIR!g" \
|
||||
"$STACKS_FOLLOWER_CONF".in \
|
||||
> "$STACKS_FOLLOWER_CONF"
|
||||
logln "ok"
|
||||
|
||||
log "Starting Stacks follower node..."
|
||||
BLOCKSTACK_DEBUG=1 RUST_BACKTRACE=full stacks-node start --config="$STACKS_FOLLOWER_CONF" >"$STACKS_FOLLOWER_LOGFILE" 2>&1 &
|
||||
local STACKS_PID=$!
|
||||
logln "PID $STACKS_PID"
|
||||
|
||||
echo "$STACKS_PID"
|
||||
return 0
|
||||
}
|
||||
|
||||
check_if_running() {
|
||||
local PID=$1
|
||||
if [ $PID -gt 0 ]; then
|
||||
kill -s 0 "$PID" 2>/dev/null
|
||||
return $?
|
||||
else
|
||||
return 0
|
||||
fi
|
||||
}
|
||||
|
||||
kill_if_running() {
|
||||
local SIG="$1"
|
||||
local PID=$2
|
||||
|
||||
if [ $PID -gt 0 ]; then
|
||||
check_if_running $PID
|
||||
if [ $? -eq 0 ]; then
|
||||
logln "Send $SIG to PID $PID"
|
||||
kill -s "$SIG" "$PID" 2>/dev/null || true
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
usage() {
|
||||
exit_error "Usage:\n $0 master\n $0 miner STACKS_MASTER_IP BITCOIN_IP FAUCET_URL\n $0 follower STACKS_MASTER_IP BITCOIN_IP\n\n"
|
||||
}
|
||||
|
||||
if [ -z "$MODE" ]; then
|
||||
usage
|
||||
fi
|
||||
|
||||
for cmd in bitcoind bitcoin-cli bitcoin-neon-controller stacks-node blockstack-cli date jq grep sed kill cat curl faucet.sh seq; do
|
||||
which $cmd 2>&1 >/dev/null || exit_error "Missing \"$cmd\""
|
||||
done
|
||||
|
||||
BITCOIN_PID=0
|
||||
BITCOIN_NEON_CONTROLLER_PID=0
|
||||
STACKS_NODE_PID=0
|
||||
FAUCET_PID=0
|
||||
|
||||
shutdown() {
|
||||
echo "Sending SIGTERM to all processes"
|
||||
for PID in $BITCOIN_PID $BITCOIN_NEON_CONTROLLER_PID $STACKS_NODE_PID $FAUCET_PID; do
|
||||
kill_if_running SIGTERM $PID
|
||||
done
|
||||
|
||||
sleep 5
|
||||
echo "Sending SIGKILL to all processes"
|
||||
for PID in $BITCOIN_PID $BITCOIN_NEON_CONTROLLER_PID $STACKS_NODE_PID $FAUCET_PID; do
|
||||
kill_if_running SIGKILL $PID
|
||||
done
|
||||
|
||||
exit 0
|
||||
}
|
||||
|
||||
trap 'shutdown' INT
|
||||
|
||||
case "$MODE" in
|
||||
master)
|
||||
BITCOIN_PID="$(start_bitcoind)"
|
||||
|
||||
sleep 5
|
||||
BITCOIN_NEON_CONTROLLER_PID="$(start_bitcoind_controller)"
|
||||
|
||||
sleep 5
|
||||
FAUCET_PID="$(start_faucet)"
|
||||
|
||||
sleep 5
|
||||
STACKS_NODE_PID="$(start_stacks_master_node)"
|
||||
;;
|
||||
|
||||
miner)
|
||||
test -n "$2" || usage
|
||||
test -n "$3" || usage
|
||||
test -n "$4" || usage
|
||||
STACKS_NODE_PID="$(start_stacks_miner_node "$2" "$3" "$4")"
|
||||
;;
|
||||
|
||||
follower)
|
||||
test -n "$2" || usage
|
||||
test -n "$3" || usage
|
||||
STACKS_NODE_PID="$(start_stacks_follower_node "$2" "$3")"
|
||||
;;
|
||||
*)
|
||||
usage
|
||||
;;
|
||||
esac
|
||||
|
||||
echo "Running!"
|
||||
|
||||
# reap children
|
||||
while true; do
|
||||
wait
|
||||
sleep 5
|
||||
|
||||
ALL_GOOD=0
|
||||
for PID in $BITCOIN_PID $BITCOIN_NEON_CONTROLLER_PID $STACKS_NODE_PID $FAUCET_PID; do
|
||||
check_if_running $PID
|
||||
if [ $? -ne 0 ]; then
|
||||
ALL_GOOD=1
|
||||
break
|
||||
fi
|
||||
done
|
||||
|
||||
if [ $ALL_GOOD -ne 0 ]; then
|
||||
break
|
||||
fi
|
||||
done
|
||||
|
||||
echo "Some process exited unexpectedly"
|
||||
shutdown
|
||||
320
net-test/bin/txload.sh
Executable file
320
net-test/bin/txload.sh
Executable file
@@ -0,0 +1,320 @@
|
||||
#!/bin/bash
|
||||
|
||||
FEE_RATE=300
|
||||
MAX_CHAINING=5
|
||||
CONFIRMATIONS=1
|
||||
|
||||
# grab fd 3 for curl
|
||||
exec 3>&1
|
||||
|
||||
exit_error() {
|
||||
printf "$1"
|
||||
exit 1
|
||||
}
|
||||
|
||||
usage() {
|
||||
exit_error "$0 <private-key-hex> <stacks-url> <num-txs>\n"
|
||||
}
|
||||
|
||||
MAIN_PRIVATE_KEY="$1"
|
||||
STACKS_NODE_URL="$2"
|
||||
NUM_TXS="$3"
|
||||
|
||||
if [ -z "$MAIN_PRIVATE_KEY" ] || [ -z "$STACKS_NODE_URL" ] || [ -z "$NUM_TXS" ]; then
|
||||
usage
|
||||
fi
|
||||
|
||||
set -uo pipefail
|
||||
|
||||
function log() {
|
||||
printf "%s" "$1" >&2
|
||||
}
|
||||
|
||||
function logln() {
|
||||
printf "%s\n" "$1" >&2
|
||||
}
|
||||
|
||||
make_token_transfer() {
|
||||
local PRIVKEY="$1"
|
||||
local NONCE="$2"
|
||||
local DEST="$3"
|
||||
local AMOUNT="$4"
|
||||
local MEMO="load test $NONCE"
|
||||
local TX="$(blockstack-cli --testnet token-transfer "$PRIVKEY" "$FEE_RATE" "$NONCE" "$DEST" "$AMOUNT" "$MEMO" 2>&1)"
|
||||
local RC=$?
|
||||
if [ $RC -ne 0 ]; then
|
||||
logln "Failed to generate tx: blockstack-cli --testnet token-transfer $PRIVKEY $FEE_RATE $NONCE $DEST $AMOUNT \"$MEMO\""
|
||||
return 1
|
||||
fi
|
||||
|
||||
printf "$TX"
|
||||
return 0
|
||||
}
|
||||
|
||||
send_tx() {
|
||||
local STACKS_NODE_URL="$1"
|
||||
|
||||
read TX
|
||||
TXID="$(printf "$TX" | \
|
||||
xxd -r -p | \
|
||||
curl -s -X POST --data-binary @- -w "%{http_code}" -o >(cat >&3) -H "content-type: application/octet-stream" "$STACKS_NODE_URL"/v2/transactions 2>&1 | ( \
|
||||
read HTTP_CODE
|
||||
read BODY
|
||||
if [ $HTTP_CODE -ne 200 ]; then
|
||||
logln "Failed to send to node $STACKS_NODE_URL: server replied $HTTP_CODE. Tx was $TX"
|
||||
logln "Error text: $BODY"
|
||||
return 1
|
||||
fi
|
||||
echo "$BODY"
|
||||
))"
|
||||
|
||||
local RC=$?
|
||||
if [ $RC -ne 0 ]; then
|
||||
return 1
|
||||
fi
|
||||
|
||||
echo "$TXID"
|
||||
return 0
|
||||
}
|
||||
|
||||
get_chain_tip() {
|
||||
local STACKS_NODE_URL="$1"
|
||||
local TIP="$(curl -sf "$STACKS_NODE_URL"/v2/info | jq -r '.stacks_tip' 2>&1)"
|
||||
local RC=$?
|
||||
|
||||
if [ $RC -ne 0 ]; then
|
||||
logln "Failed to query chain tip on node $STACKS_NODE_URL: curl exited with code $RC"
|
||||
return 1
|
||||
fi
|
||||
|
||||
echo "$TIP"
|
||||
return 0
|
||||
}
|
||||
|
||||
get_account_nonce() {
|
||||
local STACKS_NODE_URL="$1"
|
||||
local ADDR="$2"
|
||||
local NONCE="$(curl -sf "$STACKS_NODE_URL"/v2/accounts/"$ADDR""?proof=0" | jq -r '.nonce')"
|
||||
local RC=$?
|
||||
|
||||
if [ $RC -ne 0 ]; then
|
||||
logln "Failed to query account $ADDR on node $STACKS_NODE_URL: curl exited with code $RC"
|
||||
return 1
|
||||
fi
|
||||
|
||||
echo "$NONCE"
|
||||
return 0
|
||||
}
|
||||
|
||||
wait_for_new_stacks_block() {
|
||||
local TIP="$1"
|
||||
local STACKS_NODE_URL="$2"
|
||||
while true; do
|
||||
local CUR_TIP="$(get_chain_tip "$STACKS_NODE_URL")"
|
||||
local RC=$?
|
||||
if [ $RC -ne 0 ]; then
|
||||
return 1
|
||||
fi
|
||||
|
||||
if [[ "$CUR_TIP" != "$TIP" ]]; then
|
||||
echo "$CUR_TIP"
|
||||
return 0
|
||||
fi
|
||||
|
||||
sleep 5
|
||||
done
|
||||
}
|
||||
|
||||
wait_for_confirmations() {
|
||||
local CONFS=$1
|
||||
local STACKS_NODE_URL="$2"
|
||||
local TIP="$(get_chain_tip "$STACKS_NODE_URL")"
|
||||
|
||||
local CONF=0
|
||||
for CONF in $(seq 0 $CONFS); do
|
||||
TIP="$(wait_for_new_stacks_block "$TIP" "$STACKS_NODE_URL")"
|
||||
RC=$?
|
||||
|
||||
if [ $RC -ne 0 ]; then
|
||||
return 1
|
||||
fi
|
||||
done
|
||||
|
||||
echo "$TIP"
|
||||
return 0
|
||||
}
|
||||
|
||||
fund_keys() {
|
||||
local MAIN_PRIVKEY="$1"
|
||||
local AMOUNT="$2"
|
||||
local STACKS_NODE_URL="$3"
|
||||
|
||||
local MAIN_ADDR="$(blockstack-cli --testnet addresses "$MAIN_PRIVKEY" | jq -r '.STX')"
|
||||
local RC=$?
|
||||
if [ $RC -ne 0 ]; then
|
||||
logln "Failed to generate address for \"$MAIN_PRIVKEY\""
|
||||
return 1
|
||||
fi
|
||||
|
||||
local MAIN_NONCE="$(get_account_nonce "$STACKS_NODE_URL" "$MAIN_ADDR")"
|
||||
RC=$?
|
||||
if [ $RC -ne 0 ]; then
|
||||
return 1
|
||||
fi
|
||||
|
||||
local NEXT_PRIVKEY=""
|
||||
local CHAIN_TIP="$(get_chain_tip "$STACKS_NODE_URL")"
|
||||
local TX_COUNT=0
|
||||
|
||||
while read NEXT_PRIVKEY; do
|
||||
local ADDR="$(blockstack-cli --testnet addresses "$NEXT_PRIVKEY" | jq -r '.STX')"
|
||||
RC=$?
|
||||
|
||||
if [ $RC -ne 0 ]; then
|
||||
logln "Failed to generate address for \"$NEXT_PRIVKEY\""
|
||||
return 1
|
||||
fi
|
||||
|
||||
log "Funding $NEXT_PRIVKEY ($ADDR) with $AMOUNT uSTX as tx #$MAIN_NONCE..."
|
||||
TXID="$(make_token_transfer "$MAIN_PRIVKEY" "$MAIN_NONCE" "$ADDR" "$AMOUNT" | send_tx "$STACKS_NODE_URL")"
|
||||
RC=$?
|
||||
|
||||
if [ $RC -ne 0 ]; then
|
||||
logln "FAILED!"
|
||||
logln "Failed to send fund-load token-transfer to $NEXT_PRIVKEY ($ADDR)"
|
||||
return 1
|
||||
fi
|
||||
logln " ok"
|
||||
echo "$NEXT_PRIVKEY"
|
||||
|
||||
MAIN_NONCE=$((MAIN_NONCE + 1))
|
||||
TX_COUNT=$((TX_COUNT + 1))
|
||||
if (( $TX_COUNT >= $MAX_CHAINING )); then
|
||||
while true; do
|
||||
log "Wait for at least $CONFIRMATIONS new Stacks blocks after $CHAIN_TIP..."
|
||||
CHAIN_TIP="$(wait_for_confirmations $CONFIRMATIONS "$STACKS_NODE_URL")"
|
||||
RC=$?
|
||||
|
||||
if [ $RC -ne 0 ]; then
|
||||
logln "FAILED"
|
||||
return 1
|
||||
fi
|
||||
logln "ok"
|
||||
|
||||
TX_COUNT=0
|
||||
|
||||
# wait for blockchain to catch up with us
|
||||
local CUR_NONCE="$(get_account_nonce "$STACKS_NODE_URL" "$MAIN_ADDR")"
|
||||
if [ $RC -ne 0 ]; then
|
||||
return 1
|
||||
fi
|
||||
if (( $CUR_NONCE >= $MAIN_NONCE )); then
|
||||
MAIN_NONCE=$CUR_NONCE
|
||||
break
|
||||
else
|
||||
logln "Current nonce of fund key is $CUR_NONCE; need to wait until it is $MAIN_NONCE"
|
||||
fi
|
||||
done
|
||||
fi
|
||||
done
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
get_addrs_and_nonces() {
|
||||
local NEXT_PRIVKEY=""
|
||||
local STACKS_NODE_URL="$1"
|
||||
while read NEXT_PRIVKEY; do
|
||||
local ADDR="$(blockstack-cli --testnet addresses "$NEXT_PRIVKEY" | jq -r '.STX')"
|
||||
RC=$?
|
||||
|
||||
if [ $RC -ne 0 ]; then
|
||||
logln "Failed to generate address for \"$NEXT_PRIVKEY\""
|
||||
return 1
|
||||
fi
|
||||
|
||||
NONCE="$(get_account_nonce "$STACKS_NODE_URL" "$ADDR")"
|
||||
if [ $RC -ne 0 ]; then
|
||||
return 1
|
||||
fi
|
||||
|
||||
echo "$NEXT_PRIVKEY $ADDR $NONCE"
|
||||
done
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
tx_load() {
|
||||
local DEST="$1"
|
||||
local AMOUNT="$2"
|
||||
local STACKS_NODE_URL="$3"
|
||||
|
||||
local NEXT_PRIVKEY=""
|
||||
local RC=0
|
||||
local NONCE=0
|
||||
|
||||
while read NEXT_PRIVKEY_ADDR_NONCE; do
|
||||
set -- $NEXT_PRIVKEY_ADDR_NONCE
|
||||
NEXT_PRIVKEY="$1"
|
||||
ADDR="$2"
|
||||
NONCE="$3"
|
||||
|
||||
log "Send $AMOUNT uSTX from $NEXT_PRIVKEY ($ADDR) to $DEST as tx #$NONCE..."
|
||||
TXID="$(make_token_transfer "$NEXT_PRIVKEY" "$NONCE" "$DEST" "$AMOUNT" | send_tx "$STACKS_NODE_URL")"
|
||||
RC=$?
|
||||
|
||||
if [ $RC -ne 0 ]; then
|
||||
logln "FAILED!"
|
||||
logln "Failed to send tx-load token-transfer from $NEXT_PRIVKEY ($ADDR) to $DEST"
|
||||
return 1
|
||||
fi
|
||||
logln " ok"
|
||||
done
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
generate_keys() {
|
||||
local NUM_KEYS="$1"
|
||||
local CNT=0
|
||||
for CNT in $(seq 1 $NUM_KEYS); do
|
||||
local PRIVKEY="$(blockstack-cli --testnet generate-sk | jq -r '.secretKey')"
|
||||
RC=$?
|
||||
|
||||
if [ $RC -ne 0 ]; then
|
||||
logln "Failed to generate private key"
|
||||
return 1
|
||||
fi
|
||||
|
||||
echo "$PRIVKEY"
|
||||
done
|
||||
return 0
|
||||
}
|
||||
|
||||
DEST_ADDR="$(blockstack-cli --testnet generate-sk | jq -r '.secretKey,.stacksAddress' | ( \
|
||||
read DEST_PRIVKEY
|
||||
read DEST_ADDR
|
||||
logln "Destination private key: $DEST_PRIVKEY ($DEST_ADDR)"
|
||||
echo "$DEST_ADDR"
|
||||
))"
|
||||
|
||||
AMOUNT=1
|
||||
|
||||
generate_keys "$NUM_TXS" | \
|
||||
fund_keys "$MAIN_PRIVATE_KEY" "$((AMOUNT + FEE_RATE))" "$STACKS_NODE_URL" \
|
||||
> /tmp/tx-load.keys
|
||||
|
||||
logln "Waiting for $CONFIRMATIONS confirmations before beginning"
|
||||
TIP="$(wait_for_confirmations $CONFIRMATIONS "$STACKS_NODE_URL")"
|
||||
RC=$?
|
||||
|
||||
if [ $RC -ne 0 ]; then
|
||||
logln "FAILED"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
cat /tmp/tx-load.keys | \
|
||||
get_addrs_and_nonces "$STACKS_NODE_URL" | \
|
||||
tx_load "$DEST_ADDR" "$AMOUNT" "$STACKS_NODE_URL"
|
||||
|
||||
exit $?
|
||||
30
net-test/etc/bitcoin-neon-controller.toml.in
Normal file
30
net-test/etc/bitcoin-neon-controller.toml.in
Normal file
@@ -0,0 +1,30 @@
|
||||
[neon]
|
||||
rpc_bind = "0.0.0.0:28443"
|
||||
block_time = 30000
|
||||
miner_address = "mmNe3BjtYa8ZWtpQxfpsE8aWKgHh77LYTT"
|
||||
faucet_address = "n3k15aVS4rEWhVYn4YfAFjD8Em5mmsducg"
|
||||
bitcoind_rpc_host = "127.0.0.1:18443"
|
||||
bitcoind_rpc_user = "blockstack"
|
||||
bitcoind_rpc_pass = "blockstacksystem"
|
||||
genesis_timestamp = @@BITCOIN_NEON_CONTROLLER_GENESIS_TIMESTAMP@@
|
||||
whitelisted_rpc_calls = [
|
||||
"listunspent",
|
||||
"importaddress",
|
||||
"sendrawtransaction",
|
||||
"getrawtransaction",
|
||||
"scantxoutset",
|
||||
"getrawmempool",
|
||||
]
|
||||
|
||||
# Faucet:
|
||||
# Private Key b20fea233f7718d956d2c5ed71889836ec872fec7d1de2068f19f40faf297f3001
|
||||
# Public Key 02327e09dc18fee1d51fe2b19b487e01eba4e6adcb325bf102213fce7bbdcde6bd
|
||||
# Address n3k15aVS4rEWhVYn4YfAFjD8Em5mmsducg
|
||||
# Format p2pkh
|
||||
# Network testnet
|
||||
# Compressed true
|
||||
|
||||
# NOTE: the miner_address is the address of the Stacks master node's mining private key ("seed")
|
||||
|
||||
# NOTE: the following lines are meant to be grep'ed by the node runner:
|
||||
# WIF cTYqAVPS7uJTAcxyzkXWjmRGoCjkPcb38wZVRjyXov1RiRDWPQj3
|
||||
15
net-test/etc/bitcoin.conf.in
Normal file
15
net-test/etc/bitcoin.conf.in
Normal file
@@ -0,0 +1,15 @@
|
||||
server=1
|
||||
regtest=1
|
||||
rpcallowip=0.0.0.0/0
|
||||
rpcallowip=::/0
|
||||
rpcuser=blockstack
|
||||
rpcpassword=blockstacksystem
|
||||
txindex=1
|
||||
listen=1
|
||||
debug=1
|
||||
rpcserialversion=0
|
||||
datadir=@@BITCOIN_DATA_DIR@@
|
||||
|
||||
[regtest]
|
||||
bind=0.0.0.0:18444
|
||||
rpcbind=0.0.0.0:18443
|
||||
30
net-test/etc/stacks-follower.toml.in
Normal file
30
net-test/etc/stacks-follower.toml.in
Normal file
@@ -0,0 +1,30 @@
|
||||
[node]
|
||||
rpc_bind = "0.0.0.0:20443"
|
||||
p2p_bind = "0.0.0.0:20444"
|
||||
bootstrap_node = "04ee0b1602eb18fef7986887a7e8769a30c9df981d33c8380d255edef003abdcd243a0eb74afdf6740e6c423e62aec631519a24cf5b1d62bf8a3e06ddc695dcb77@@@STACKS_MASTER_IP:20444@@"
|
||||
working_dir = "@@STACKS_CHAINSTATE_DIR@@"
|
||||
|
||||
[burnchain]
|
||||
chain = "bitcoin"
|
||||
mode = "krypton"
|
||||
peer_host = "@@BITCOIN_IP@@"
|
||||
rpc_port = 28443
|
||||
peer_port = 18444
|
||||
|
||||
[[mstx_balance]]
|
||||
# Private key: b8d99fd45da58038d630d9855d3ca2466e8e0f89d3894c4724f0efc9ff4b51f001
|
||||
address = "ST2ZRX0K27GW0SP3GJCEMHD95TQGJMKB7G9Y0X1MH"
|
||||
amount = 10000000000000000
|
||||
[[mstx_balance]]
|
||||
# Private key: 3a4e84abb8abe0c1ba37cef4b604e73c82b1fe8d99015cb36b029a65099d373601
|
||||
address = "ST26FVX16539KKXZKJN098Q08HRX3XBAP541MFS0P"
|
||||
amount = 10000000000000000
|
||||
[[mstx_balance]]
|
||||
# Private key: 052cc5b8f25b1e44a65329244066f76c8057accd5316c889f476d0ea0329632c01
|
||||
address = "ST3CECAKJ4BH08JYY7W53MC81BYDT4YDA5M7S5F53"
|
||||
amount = 10000000000000000
|
||||
[[mstx_balance]]
|
||||
# Private key: 9aef533e754663a453984b69d36f109be817e9940519cc84979419e2be00864801
|
||||
address = "ST31HHVBKYCYQQJ5AQ25ZHA6W2A548ZADDQ6S16GP"
|
||||
amount = 10000000000000000
|
||||
|
||||
35
net-test/etc/stacks-master.toml.in
Normal file
35
net-test/etc/stacks-master.toml.in
Normal file
@@ -0,0 +1,35 @@
|
||||
[node]
|
||||
rpc_bind = "0.0.0.0:20443"
|
||||
p2p_bind = "0.0.0.0:20444"
|
||||
seed = "bbd40688849e9d0f3bc3132a576835df11bb84b307a5a0588d8fecc4d6ba32d201"
|
||||
miner = true
|
||||
working_dir = "@@STACKS_CHAINSTATE_DIR@@"
|
||||
pox_sync_sample_secs = 10
|
||||
wait_time_for_microblocks = 0
|
||||
p2p_address = "@@STACKS_PUBLIC_IP@@:20444"
|
||||
|
||||
[burnchain]
|
||||
chain = "bitcoin"
|
||||
mode = "krypton"
|
||||
peer_host = "0.0.0.0"
|
||||
rpc_port = 28443
|
||||
peer_port = 18444
|
||||
poll_time_secs = 5
|
||||
|
||||
[[mstx_balance]]
|
||||
# Private key: b8d99fd45da58038d630d9855d3ca2466e8e0f89d3894c4724f0efc9ff4b51f001
|
||||
address = "ST2ZRX0K27GW0SP3GJCEMHD95TQGJMKB7G9Y0X1MH"
|
||||
amount = 10000000000000000
|
||||
[[mstx_balance]]
|
||||
# Private key: 3a4e84abb8abe0c1ba37cef4b604e73c82b1fe8d99015cb36b029a65099d373601
|
||||
address = "ST26FVX16539KKXZKJN098Q08HRX3XBAP541MFS0P"
|
||||
amount = 10000000000000000
|
||||
[[mstx_balance]]
|
||||
# Private key: 052cc5b8f25b1e44a65329244066f76c8057accd5316c889f476d0ea0329632c01
|
||||
address = "ST3CECAKJ4BH08JYY7W53MC81BYDT4YDA5M7S5F53"
|
||||
amount = 10000000000000000
|
||||
[[mstx_balance]]
|
||||
# Private key: 9aef533e754663a453984b69d36f109be817e9940519cc84979419e2be00864801
|
||||
address = "ST31HHVBKYCYQQJ5AQ25ZHA6W2A548ZADDQ6S16GP"
|
||||
amount = 10000000000000000
|
||||
|
||||
36
net-test/etc/stacks-miner.toml.in
Normal file
36
net-test/etc/stacks-miner.toml.in
Normal file
@@ -0,0 +1,36 @@
|
||||
[node]
|
||||
rpc_bind = "0.0.0.0:21443"
|
||||
p2p_bind = "0.0.0.0:21444"
|
||||
bootstrap_node = "04ee0b1602eb18fef7986887a7e8769a30c9df981d33c8380d255edef003abdcd243a0eb74afdf6740e6c423e62aec631519a24cf5b1d62bf8a3e06ddc695dcb77@@@STACKS_MASTER_IP@@:20444"
|
||||
# bootstrap_node = "03ee0b1602eb18fef7986887a7e8769a30c9df981d33c8380d255edef003abdcd2@@@STACKS_MASTER_IP@@:20444"
|
||||
seed = "@@STACKS_MINER_SEED@@"
|
||||
miner = true
|
||||
working_dir = "@@STACKS_CHAINSTATE_DIR@@"
|
||||
pox_sync_sample_secs = 10
|
||||
wait_time_for_microblocks = 0
|
||||
|
||||
[burnchain]
|
||||
chain = "bitcoin"
|
||||
mode = "krypton"
|
||||
peer_host = "@@BITCOIN_IP@@"
|
||||
rpc_port = 28443
|
||||
peer_port = 18444
|
||||
poll_time_secs = 5
|
||||
|
||||
[[mstx_balance]]
|
||||
# Private key: b8d99fd45da58038d630d9855d3ca2466e8e0f89d3894c4724f0efc9ff4b51f001
|
||||
address = "ST2ZRX0K27GW0SP3GJCEMHD95TQGJMKB7G9Y0X1MH"
|
||||
amount = 10000000000000000
|
||||
[[mstx_balance]]
|
||||
# Private key: 3a4e84abb8abe0c1ba37cef4b604e73c82b1fe8d99015cb36b029a65099d373601
|
||||
address = "ST26FVX16539KKXZKJN098Q08HRX3XBAP541MFS0P"
|
||||
amount = 10000000000000000
|
||||
[[mstx_balance]]
|
||||
# Private key: 052cc5b8f25b1e44a65329244066f76c8057accd5316c889f476d0ea0329632c01
|
||||
address = "ST3CECAKJ4BH08JYY7W53MC81BYDT4YDA5M7S5F53"
|
||||
amount = 10000000000000000
|
||||
[[mstx_balance]]
|
||||
# Private key: 9aef533e754663a453984b69d36f109be817e9940519cc84979419e2be00864801
|
||||
address = "ST31HHVBKYCYQQJ5AQ25ZHA6W2A548ZADDQ6S16GP"
|
||||
amount = 10000000000000000
|
||||
|
||||
4
net-test/mnt/cleanup.sh
Executable file
4
net-test/mnt/cleanup.sh
Executable file
@@ -0,0 +1,4 @@
|
||||
#!/bin/bash
|
||||
|
||||
mkdir -p archive
|
||||
mv bitcoin-1* stacks-chainstate-* archive
|
||||
Reference in New Issue
Block a user