Skip to content

Instantly share code, notes, and snippets.

@aguycalled
Last active December 7, 2019 23:45
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save aguycalled/13f362c29ea9c38624e8dd4593bc37f8 to your computer and use it in GitHub Desktop.
Save aguycalled/13f362c29ea9c38624e8dd4593bc37f8 to your computer and use it in GitHub Desktop.
NavCoin devnet stresser using staking
#!/bin/bash
### Need to configure this!!
### Path to binaries
navpath=/Users/alex/navcoin-core/src
### How many voting cycles to run the stresser
cycles=20
### Each verifychain thread is spread in groups of n blocks. N == number of nodes for checking every block
increment_verifychain=2
### How many extra blocks should be staked when the stresser is done
extra_blocks_to_stake=500
extra_blocks_to_stake_randomness=500
### Length in blocks of a voting cycles_left
voting_cycle_length=30
### Length in seconds for a stress round
seconds_round=120
p2p_port_one=10001
p2p_port_two=10002
rpc_port_one=30001
rpc_port_two=30002
data_one=$(mktemp -d)
data_two=$(mktemp -d)
user_one=$(env LC_CTYPE=C tr -dc "a-zA-Z0-9-_\$\?" < /dev/urandom | head -c 10)
user_two=$(env LC_CTYPE=C tr -dc "a-zA-Z0-9-_\$\?" < /dev/urandom | head -c 10)
pwd_one=$(env LC_CTYPE=C tr -dc "a-zA-Z0-9-_\$\?" < /dev/urandom | head -c 10)
pwd_two=$(env LC_CTYPE=C tr -dc "a-zA-Z0-9-_\$\?" < /dev/urandom | head -c 10)
killall -9 navcoind
echo DATADIR_NODE1 = $data_one
echo DATADIR_NODE2 = $data_two
$(echo $navpath)/navcoind -datadir=$data_one -port=$p2p_port_one -rpcport=$rpc_port_one -rpcuser=$user_one -rpcpassword=$pwd_one -devnet -daemon -debug=dao -ntpminmeasures=0 -staking=0 2> /dev/null
$(echo $navpath)/navcoind -datadir=$data_two -port=$p2p_port_two -rpcport=$rpc_port_two -rpcuser=$user_two -rpcpassword=$pwd_two -connect=127.0.0.1:10001 -devnet -daemon -debug=dao -ntpminmeasures=0 -staking=0 2> /dev/null
trap ctrl_c INT
function ctrl_c() {
kill -9 $check_node_one_pid 2> /dev/null
kill -9 $check_node_two_pid 2> /dev/null
terminate 1
}
function nav_cli_one {
echo $($(echo $navpath)/navcoin-cli -datadir=$data_one -rpcport=$rpc_port_one -devnet -rpcuser=$user_one -rpcpassword=$pwd_one $1 2> /dev/null)
}
function nav_cli_two {
echo $($(echo $navpath)/navcoin-cli -datadir=$data_two -rpcport=$rpc_port_two -devnet -rpcuser=$user_two -rpcpassword=$pwd_two $1 2> /dev/null)
}
function terminate {
killall -9 navcoind
exit $1
}
function wait_until_sync {
sleep 2
besthash_one=$(nav_cli_one getbestblockhash)
besthash_two=$(nav_cli_two getbestblockhash)
if [ "$besthash_one" != "$besthash_two" ];
then
sleep 1
dice=$(bc <<< "$RANDOM % 5")
if [ $dice -eq 1 ];
then
node=$(bc <<< "$RANDOM % 2")
if [ $node -eq 0 ];
then
$(nav_cli_one "generate 1")
else
$(nav_cli_two "generate 1")
fi
sleep 2
fi
wait_until_sync
fi
}
function assert_state {
sleep 2
statehash_one=$(nav_cli_one getcfunddbstatehash)
statehash_two=$(nav_cli_two getcfunddbstatehash)
if [ "$statehash_one" != "$statehash_two" ];
then
echo STATE HASH MISMATCH! $statehash_one vs $statehash_two
echo I wrote listproposals output to $data_one/devnet/listproposals.out and $data_two/devnet/listproposals.out
nav_cli_one listproposals > $data_one/devnet/listproposals.out
nav_cli_two listproposals > $data_two/devnet/listproposals.out
terminate 1
fi
}
function dice {
dice=$(bc <<< "$RANDOM % 100")
node=$(bc <<< "$RANDOM % 2")
if [ $dice -lt 75 ];
then
randomSentence=$(env LC_CTYPE=C tr -dc "a-zA-Z0-9-_\$\?" < /dev/urandom | head -c 10)
amount=$(bc <<< "$RANDOM % 1000")
deadline=$(bc <<< "$RANDOM % 1000000")
if [ $node -eq 0 ];
then
address=$(nav_cli_one getnewaddress)
out=$(nav_cli_one "createproposal $address $amount $deadline \"$randomSentence\"")
else
address=$(nav_cli_two getnewaddress)
out=$(nav_cli_two "createproposal $address $amount $deadline \"$randomSentence\"")
fi
fi
if [ $dice -gt 25 ];
then
if [ $node -eq 0 ];
then
proposals=$(nav_cli_one "listproposals mine"|jq -r ".[]|.hash"|tr "\n" " ")
else
proposals=$(nav_cli_two "listproposals mine"|jq -r ".[]|.hash"|tr "\n" " ")
fi
arrayproposals=($proposals)
for p in "${arrayproposals[@]}"
do
if [ $node -eq 0 ];
then
proposal=$(nav_cli_one "getproposal $p")
else
proposal=$(nav_cli_two "getproposal $p")
fi
address=$(echo $proposal|jq -r .paymentAddress)
status=$(echo $proposal|jq -r .status)
if [[ "$status" == "accepted" ]];
then
dice=$(bc <<< "$RANDOM % 10")
if [ $dice -eq 1 ];
then
randomSentence=$(env LC_CTYPE=C tr -dc "a-zA-Z0-9-_\$\?" < /dev/urandom | head -c 10)
maxAmount=$(echo $proposal|jq -r .notRequestedYet)
if (( $(echo "$maxAmount > 0"|bc -l) ));
then
hash=$(echo $proposal|jq -r .hash)
requestAmount=$(bc <<< "$RANDOM % $maxAmount")
if [ $node -eq 0 ];
then
out=$(nav_cli_one "createpaymentrequest $hash $requestAmount \"$randomSentence\"")
else
out=$(nav_cli_two "createpaymentrequest $hash $requestAmount \"$randomSentence\"")
fi
fi
fi
fi
done
fi
}
function voter_dice {
node=$(bc <<< "$RANDOM % 2")
if [ $node -eq 0 ];
then
proposals=$(nav_cli_one proposalvotelist|jq -r ".null[]|.hash")
else
proposals=$(nav_cli_two proposalvotelist|jq -r ".null[]|.hash")
fi
for i in $proposals;
do
dice=$(bc <<< "$RANDOM % 2")
if [ $dice -eq 1 ];
then
if [ $node -eq 0 ];
then
out=$(nav_cli_one "proposalvote $i yes")
else
out=$(nav_cli_two "proposalvote $i yes")
fi
else
if [ $node -eq 0 ];
then
out=$(nav_cli_one "proposalvote $i no")
else
out=$(nav_cli_two "proposalvote $i no")
fi
fi
done
if [ $node -eq 0 ];
then
prequests=$(nav_cli_one paymentrequestvotelist|jq -r ".null[]|.hash?")
else
prequests=$(nav_cli_two paymentrequestvotelist|jq -r ".null[]|.hash?")
fi
for i in $prequests;
do
dice=$(bc <<< "$RANDOM % 2")
if [ $dice -eq 1 ];
then
if [ $node -eq 0 ];
then
out=$(nav_cli_one "paymentrequestvote $i yes")
else
out=$(nav_cli_two "paymentrequestvote $i yes")
fi
else
if [ $node -eq 0 ];
then
out=$(nav_cli_one "paymentrequestvote $i no")
else
out=$(nav_cli_two "paymentrequestvote $i no")
fi
fi
done
}
function stress {
out=$(nav_cli_one "staking true")
out=$(nav_cli_two "staking true")
time=$(bc <<< $(date +%s)+$1)
while [ $time -gt $(date +%s) ]
do
dice
sleep 0.1
done
voter_dice
donation=$(bc <<< "$RANDOM % 10000")
out=$(nav_cli_one "donatefund $donation")
out=$(nav_cli_one "staking false")
out=$(nav_cli_two "staking false")
}
echo ''
echo Waiting 25 seconds for navcoind...
sleep 25
out=$(nav_cli_one "generate 10")
address_two=$(nav_cli_two getnewaddress)
for i in {1..50}; do
out=$(nav_cli_one "sendtoaddress $address_two 100000")
out=$(nav_cli_one "generate 10")
done
sleep 25
donation=$(bc <<< "$RANDOM % 10000")
out=$(nav_cli_one "donatefund $donation")
echo ''
echo Waiting until both nodes are synced
wait_until_sync
echo ''
echo Checking state hashes match
assert_state
blocks=$(nav_cli_one getinfo|jq .blocks)
initial_cycle=$(bc <<< $blocks/$voting_cycle_length)
wait_until_cycle=$(bc <<< "$initial_cycle + $cycles + 1")
this_cycle=0
current_block=$(nav_cli_one getinfo|jq .blocks)
while [ $wait_until_cycle -gt $this_cycle ]; do
echo ''
echo Stressing for $seconds_round seconds
stress $seconds_round
echo Waiting until both nodes are synced
wait_until_sync
echo Checking state hashes match
assert_state
blocks=$(nav_cli_one getinfo|jq .blocks)
this_cycle=$(bc <<< $blocks/$voting_cycle_length)
cycles_left=$(bc <<< "$wait_until_cycle - $this_cycle")
previous_block=$current_block
current_block=$blocks
echo Ok!
echo Current block: $current_block
echo Current cycle: $this_cycle - $cycles_left cycle\(s\) left to finish.
echo Proposals: $(nav_cli_one listproposals|jq -c "map({status:.status})|group_by(.status)|map({status:.[0].status,count:length})|.[]")
echo Payment Requests: $(nav_cli_one listproposals|jq -c "[.[].paymentRequests|map({status:.status})]|flatten|group_by(.status)|map({status:.[0].status,count:length})|.[]")
echo Reorganizations Node 1: $(prev=0;for i in $(grep height= $data_one/devnet/debug.log|sed -n -e '/height\='$previous_block'/,$p'|sed -n 's/.*height\=\([0-9]*\) .*/\1/p'); do if [ $i -lt $prev ]; then echo $i; fi; prev=$i; done)
echo Reorganizations Node 2: $(prev=0;for i in $(grep height= $data_two/devnet/debug.log|sed -n -e '/height\='$previous_block'/,$p'|sed -n 's/.*height\=\([0-9]*\) .*/\1/p'); do if [ $i -lt $prev ]; then echo $i; fi; prev=$i; done)
done
extra_blocks=$(bc <<< "($RANDOM%$extra_blocks_to_stake_randomness)+$extra_blocks_to_stake")
blocks=`nav_cli_one getinfo|jq .blocks`
wait_until=$(bc <<< "$blocks+$extra_blocks")
echo ''
echo Stopping stresser. Waiting until $extra_blocks blocks are staked
out=$(nav_cli_one "staking true")
out=$(nav_cli_two "staking true")
while [ $blocks -lt $wait_until ];
do
sleep 60
blocks=`nav_cli_one getinfo|jq .blocks`
echo $(bc <<< "$wait_until-$blocks") blocks left...
done
out=$(nav_cli_one "staking false")
out=$(nav_cli_two "staking false")
echo ''
echo Waiting until both nodes are synced
wait_until_sync
echo Ok! Block: $(nav_cli_one getinfo|jq .blocks) Cycle: $(bc <<< $(nav_cli_one getinfo|jq .blocks)/$voting_cycle_length).
echo Proposals: $(nav_cli_one listproposals|jq -c "map({status:.status})|group_by(.status)|map({status:.[0].status,count:length})|.[]")
echo Payment Requests: $(nav_cli_one listproposals|jq -c "[.[].paymentRequests|map({status:.status})]|flatten|group_by(.status)|map({status:.[0].status,count:length})|.[]")
node_one_check_ready=0
function check_node_one {
node_one_check_ready=0
blocks=`nav_cli_one getinfo|jq .blocks`
for i in $(seq 1 $increment_verifychain $blocks);
do
verifyoutput=`nav_cli_one verifychain 4 $i`
if [[ "$verifyoutput" == "false" ]];
then
verifyoutput+=`echo ' - ' && echo failed at $(grep 'ERROR: VerifyDB()' $data_one/devnet/debug.log |tail -1|sed 's/.*block at \(\d*\)/\1/')`
fi
echo Node 1 - Rewinding to \
$(bc <<< $blocks-$i) \
- reconnecting up to $blocks \
- verifychain 4 $i -\> $verifyoutput;
done
node_one_check_ready=1
}
node_two_check_ready=0
function check_node_two {
node_two_check_ready=0
blocks=`nav_cli_two getinfo|jq .blocks`
for i in $(seq 2 $increment_verifychain $blocks);
do
verifyoutput=`nav_cli_two verifychain 4 $i`
if [[ "$verifyoutput" == "false" ]];
then
verifyoutput+=`echo ' - ' && echo failed at $(grep 'ERROR: VerifyDB()' $data_two/devnet/debug.log |tail -1|sed 's/.*block at \(\d*\)/\1/')`
fi
echo Node 2 - Rewinding to \
$(bc <<< $blocks-$i) \
- reconnecting up to $blocks \
- verifychain 4 $i -\> $verifyoutput;
done
node_two_check_ready=1
}
echo ''
echo Running verifychain test in node1...
echo ''
echo Running verifychain test in node2...
echo ''
check_node_one &
check_node_one_pid=$!
check_node_two &
check_node_two_pid=$!
while [[ $node_one_check_ready != "1" ]] && [[ $node_two_check_ready != "1" ]];
do
sleep 1
done
terminate 0
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment