duniter_getnode.sh 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119
  1. #!/bin/bash
  2. ################################################################################
  3. # Authors: @jytou (https://git.duniter.org/jytou)
  4. # Modified by Fred (support@qo-op.com)
  5. # Version: 0.1
  6. # License: AGPL-3.0 (https://choosealicense.com/licenses/agpl-3.0/)
  7. ################################################################################
  8. # Checks the current block number of $DIR/duniter_nodes.txt (is run in parallel)
  9. # and output random (from last synchronized) node
  10. checkonenode()
  11. {
  12. # Timeout in seconds for https nodes
  13. httpsTimeout=1
  14. # Timeout in seconds for http nodes
  15. httpTimeout=1
  16. node=$1
  17. watched=$2
  18. outfile=$3
  19. # Curl: -m timeout, -k ignore SSL certificate errors
  20. cur=`echo "$( { curl -m $httpsTimeout -k https://$node/blockchain/current; } 2>&1 )"`
  21. n=$node
  22. if [[ "$cur" != *issuersFrameVar* ]]
  23. then
  24. # It failed in https, maybe try http?
  25. cur=`echo "$( { curl -m $httpTimeout http://$node/blockchain/current; } 2>&1 )"`
  26. if [[ "$cur" == *issuersFrameVar* ]]
  27. then
  28. # Indicate that the node is http
  29. n="$n-(http)"
  30. fi
  31. fi
  32. if [[ "$cur" != *issuersFrameVar* ]]
  33. then
  34. # The node didn't respond on time
  35. cur="ERROR"
  36. else
  37. # The node did respond - grab the block number and hash of the block as key
  38. 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)}'`"
  39. fi
  40. if [[ $watched =~ .*#$node#.* ]]
  41. then
  42. # The node is a watched node, add some bold
  43. n="\e[1m$n\e[0m"
  44. fi
  45. # Put the result into the file
  46. echo "$cur $n">$outfile
  47. # Notify that we're done here
  48. touch $outfile.done
  49. }
  50. # Temp dir where results are stored
  51. rm -Rf /tmp/zen/gnodewatch
  52. DIR=/tmp/zen/gnodewatch
  53. export DIR
  54. mkdir -p $DIR/chains
  55. # TODO: REMOVE 777 PATCH, ACTIVATE ramdisk
  56. # sudo mkdir /mnt/ramdisk
  57. # sudo mount -t tmpfs -o size=50m tmpfs /mnt/ramdisk
  58. chmod -R 777 /tmp/zen/
  59. # KEEP /tmp/zen/current.duniter for 15 mn
  60. find /tmp/zen/ -cmin +15 -type f -name "current.duniter" -exec rm -f '{}' \;
  61. [[ -f /tmp/zen/current.duniter ]] && cat /tmp/zen/current.duniter && exit 0
  62. ##### $DIR/duniter_nodes.txt REFRESH after 20 minutes #####
  63. find $DIR/ -cmin +20 -type f -name "duniter_*" -exec rm -f '{}' \;
  64. if [[ ! -f $DIR/duniter_nodes.txt ]]; then
  65. # Get New BMAS known Nodes list from shuffle one $DIR/good.nodes.txt
  66. [[ -f $DIR/good.nodes.txt ]] && DUNITER=$(shuf -n 1 $DIR/good.nodes.txt) || DUNITER="duniter-g1.p2p.legal:443"
  67. curl -s https://$DUNITER/network/peers | jq '.peers[] | .endpoints' | grep BMAS | awk '{print $2,$3}' | sed s/\"//g | sed s/\,//g | sed s/\ /:/g | sort -u > $DIR/duniter_nodes.txt
  68. fi
  69. # Grab the nodes we are actively watching - they will be in bold in the final output
  70. watched=`grep -v "#" $DIR/duniter_nodes.txt|egrep "\!$"|awk '{print "#" $1 "#"}'`
  71. # All nodes we are watching
  72. nodes=`grep -v "#" $DIR/duniter_nodes.txt|awk '{print $1}'`
  73. # The index to generate separate file names
  74. index=0
  75. # Wipe out the output directory
  76. rm $DIR/*out $DIR/*done $DIR/chains/* $DIR/NODE.* 2>/dev/null
  77. # Query all nodes in parallel
  78. for node in $nodes
  79. do
  80. checkonenode $node "$watched" $DIR/$index.out &
  81. ((index++))
  82. done
  83. # Wait a little for the first files to be created
  84. sleep 1s
  85. # Wait for all the threads to report they are done
  86. while [ `ls $DIR/*done|wc -l` -lt $index ]
  87. do
  88. sleep 1s
  89. done
  90. # Grab all results
  91. curs=`cat $DIR/*out|sort`
  92. # Extract all forks, excluding all errors
  93. chains="`echo "$curs"|grep -v ERROR|awk '{print $1}'|sort -r|uniq`"
  94. # Count the number of chains and output most recent consensus to "good.nodes.txt"
  95. nb=0
  96. for chain in $chains
  97. do
  98. echo "$curs" | egrep "^$chain " | awk '{print $2}' >> $DIR/chains/$nb;
  99. ((nb++))
  100. done
  101. longchain=$(ls -S $DIR/chains/ | head -n 1)
  102. cp $DIR/chains/$longchain $DIR/good.nodes.txt
  103. # WRITE OUT shuffle Duniter Node Sync with longest chain
  104. result=$(shuf -n 1 $DIR/good.nodes.txt)
  105. [[ ! $result ]] && result="duniter-g1.p2p.legal:443"
  106. echo "$result" > /tmp/zen/current.duniter
  107. echo $result