#!/bin/bash ################################################################################ # Authors: @jytou (https://git.duniter.org/jytou) # Modified by Fred (support@qo-op.com) to modifiy silkaj constant with best server # Version: 0.1 # License: AGPL-3.0 (https://choosealicense.com/licenses/agpl-3.0/) ################################################################################ # Checks the current block number of nodes.txt (is run in parallel) and output random (from last synchronized) node # pip3 install duniterpy # pip3 install silkaj --user checkonenode() { # Timeout in seconds for https nodes httpsTimeout=1 # Timeout in seconds for http nodes httpTimeout=1 node=$1 watched=$2 outfile=$3 # Curl: -m timeout, -k ignore SSL certificate errors cur=`echo "$( { curl -m $httpsTimeout -k https://$node/blockchain/current; } 2>&1 )"` n=$node if [[ "$cur" != *issuersFrameVar* ]] then # It failed in https, maybe try http? cur=`echo "$( { curl -m $httpTimeout http://$node/blockchain/current; } 2>&1 )"` if [[ "$cur" == *issuersFrameVar* ]] then # Indicate that the node is http n="$n-(http)" fi fi if [[ "$cur" != *issuersFrameVar* ]] then # The node didn't respond on time cur="ERROR" else # The node did respond - grab the block number and hash of the block as key cur="`echo "$cur"|grep '^ "number": '|awk '{print $2}'|awk -F, '{print $1}'`-`echo "$cur"|grep '^ "hash": '|awk '{print $2}'|awk '{print substr($1,2,13)}'`" fi if [[ $watched =~ .*#$node#.* ]] then # The node is a watched node, add some bold n="\e[1m$n\e[0m" fi # Put the result into the file echo "$cur $n">$outfile # Notify that we're done here touch $outfile.done } # Temp dir where results are stored DIR=/tmp/gnodewatch export DIR mkdir -p $DIR/chains ########### # BANNISH DUNITER NODE? # TODO: silkaj evolution!! Better CLI integration to make! # Duniter Node is too slow or behave badly, remove it from nodes.txt list BAN=$1 if [[ "$BAN" == "BAN" ]]; then # Get actual Duniter node used by silkaj SERVER=$(cat ./silkaj/src/constants.py | grep G1_DEFAULT_ENDPOINT | awk '{print $3}' | sed s/\"\,//g | sed s/\"//g) [[ ! $(grep $SERVER:443 shell/bad.nodes.txt) ]] && echo $SERVER:443 >> shell/bad.nodes.txt sed -i "/$SERVER:443/d" ./shell/good.nodes.txt echo "$SERVER:443 IS NOW in ./shell/bad.nodes.txt" fi ### nodes.txt EMPTYNESS CARE NBgood=$(cat ./shell/good.nodes.txt | wc -l) NBbad=$(cat ./shell/bad.nodes.txt | wc -l) if [[ $NBgood -le $NBbad ]]; then echo "" > ./shell/good.nodes.txt echo "" > ./shell/bad.nodes.txt # TODO: Each decentralized App must have a source for its confidence to be UP and running and publishing latest code for our concensus behaviour! echo "___ REFRESH ./shell/nodes.txt from g1.duniter.org:443 ___" curl -s https://g1.duniter.org/network/peers | jq '.peers[] | .endpoints' | grep BMAS | awk '{print $2,$3}' | sed s/\"//g | sed s/\,//g | sed s/\ /:/g > "./shell/nodes.txt" echo $(cat "./shell/nodes.txt") fi ########### # CONTINUE # Grab the nodes we are actively watching - they will be in bold in the final output watched=`grep -v "#" ./shell/nodes.txt|egrep "\!$"|awk '{print "#" $1 "#"}'` # All nodes we are watching nodes=`grep -v "#" ./shell/nodes.txt|awk '{print $1}'` # The index to generate separate file names index=0 # Wipe out the output directory rm $DIR/*out $DIR/*done $DIR/chains/* $DIR/NODE.* 2>/dev/null # Query all nodes in parallel for node in $nodes do checkonenode $node "$watched" $DIR/$index.out & ((index++)) done # Wait a little for the first files to be created sleep 1s # Wait for all the threads to report they are done while [ `ls $DIR/*done|wc -l` -lt $index ] do sleep 1s done # Grab all results curs=`cat $DIR/*out|sort` # Extract all forks, excluding all errors chains="`echo "$curs"|grep -v ERROR|awk '{print $1}'|sort -r|uniq`" # Count the number of chains and output most recent consensus to "good.nodes.txt" nb=0 for chain in $chains do echo "$curs" | egrep "^$chain " | awk '{print $2}' >> $DIR/chains/$nb; ((nb++)) done longchain=$(ls -S /tmp/gnodewatch/chains/ | head -n 1) cp /tmp/gnodewatch/chains/$longchain "./shell/good.nodes.txt" ##################################################################################### # ASK peers to all good.nodes.txt #for node in $(cat ./shell/good.nodes.txt); do # NANODATE=$(date +%s%N); # DUN="https://$(echo $node| cut -d ":" -f 1)"; # curl -s -o $DIR/NODE.$NANODATE.$node ${DUN}/network/peers; #done # REFRESH from all known peers NEW nodes.txt #cat /tmp/gnodewatch/NODE.* | jq '.peers[] | .endpoints' | grep BMAS | awk '{print $2,$3}' | sed s/\"//g | sed s/\,//g | sed s/\ /:/g | sort | uniq > "./shell/nodes.txt" ##################################################################################### # Output Random actual best node # Compare with ./shell/bad.nodes.txt while [[ "$BAD" == "$DUNITER" ]]; do DUNITER=$(shuf "./shell/good.nodes.txt" | head -n 1) BAD=$(grep -Rw "$DUNITER" ./shell/bad.nodes.txt) done ################# MODIFY silkaj constants.py silkaj=$(echo $DUNITER | cut -d ":" -f 1) if [[ "$silkaj" != "" && "$silkaj" != "https" ]]; then #echo "PUT $silkaj SILKAJ PARAM" cat ./silkaj/src/constants.default.py | sed s/duniter-g1.p2p.legal/$silkaj/g > ./silkaj/src/constants.py else echo "RESTORE DEFAULT SILKAJ PARAM" cp -f ./silkaj/src/constants.default.py ./silkaj/src/constants.py fi echo $DUNITER