Last active
December 7, 2019 23:45
-
-
Save aguycalled/13f362c29ea9c38624e8dd4593bc37f8 to your computer and use it in GitHub Desktop.
NavCoin devnet stresser using staking
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/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