Skip to content
Snippets Groups Projects
Commit e695b721 authored by Robert Martin-Legene's avatar Robert Martin-Legene
Browse files

Introducing command: bfa

parent 193e2c36
No related branches found
No related tags found
No related merge requests found
bin/bfa 0 → 100755
#!/bin/bash
# Robert Martin-Legene <robert@nic.ar>
if [ -z "${BFAHOME}" ]; then echo "\$BFAHOME not set. Did you source bfa/bin/env ?" >&2; exit 1; fi
source ${BFAHOME}/bin/libbfa.sh || exit 1
declare -A commands help
function register_subcommand
{
declare -g commands help
commands[$1]=$2
help[$1]=$3
}
function _usage()
{
local after=''
for c in $( echo ${!commands[*]} | sort )
do
after="${after}|$c"
done
echo "Usage: $(basename $0) {${after:1}}" >&2
for c in $( echo ${!commands[*]} | sort )
do
printf '%-15s %s\n' "$c" "${help[$c]}" >&2
done
trap - ERR
exit 1
}
function _max
{
test "$1" -lt "$2" && echo "$2"
echo "$1"
}
function pidsfromsigfiles
{
local pids=
local file
for file in \
${BFANETWORKDIR}/bootnode.pid \
${BFANETWORKDIR}/start-bootnode-loop.pid \
${BFANODEDIR}/monitor.pid \
${BFANODEDIR}/start-monitor-loop.pid \
${BFANODEDIR}/geth.pid \
${BFANODEDIR}/start-geth-loop.pid
do
test -r "$file" || continue
local pid=$(< "$file")
if ! [[ "$pid" =~ ^[0-9]+$ ]]
then
rm -f "$file"
continue
fi
if ! kill -0 "$pid" >/dev/null 2>/dev/null
then
rm -f "$file"
continue
fi
pids="$pids $pid"
done
echo "${pids# }"
}
function sendsig
{
local signal=$1
shift
local pids="$*"
test -n "$pids" || return
ps -p ${pids// /,}
echo "Sending ${signal} signal to pid $pids."
kill "$signal" $pids || true
}
register_subcommand 'kill' 'killbfastuff' 'Kill BFA background processes (no questions asked).'
function killbfastuff
{
local pids=$(pidsfromsigfiles)
if [ -z "$pids" ]
then
echo "Nothing to send signals to." >&2
exit 2
fi
sendsig -KILL $pids
}
register_subcommand 'stop' 'graceful' 'Ask the BFA background processes to end gracefully.'
function graceful
{
local max=10
local pids=$(pidsfromsigfiles)
while :
do
max=$((max - 1))
test "$max" -eq 0 && break
if [ -z "$pids" ]
then
echo "Nothing to send signals to." >&2
break
fi
sendsig -TERM $pids
sleep 0.4
pids=$(pidsfromsigfiles)
done
test -z "$pids" || echo "This/these pids is/are still running: $f"
}
register_subcommand 'initdb' 'initdb' 'Stop geth and reset the node to block zero (genesis).'
function initdb
{
killbfastuff
yes | geth --cache 0 --datadir ${BFANODEDIR} removedb
geth --networkid ${BFANETWORKID} --cache 0 --datadir ${BFANODEDIR} init ${BFANETWORKDIR}/genesis.json
}
register_subcommand 'exportdb' 'exportdb' 'Export blockchain in chunks of 1 million blocks per file.'
function exportdb
{
local delta=1000000
graceful
local maxblocks=$(bfageth --exec 'eth.blockNumber' console 2> /dev/null)
# 0 is genesis.. shouldn't dump that
local toblock
local blockstart=1
while [ "$blockstart" -lt "$maxblocks" ]
do
toblock=$(( blockstart + delta - 1 ))
test "$toblock" -gt "$maxblocks" &&
toblock=$maxblocks
local filename
printf -v filename 'bfa2018.blocks.%09d-%09d.export.gz' "$blockstart" "$toblock"
if [ ! -e "$filename" ]
then
echo "Dumping blocks# $blockstart to $toblock to the file named $filename"
bfageth export "$filename" "$blockstart" "$toblock"
fi
blockstart=$(( toblock + 1 ))
done
}
register_subcommand 'importdb' 'importdb' 'Import blocks safely from previous block exports.'
function importdb
{
local dumpurl="https://s3.wasabisys.com/bfa/blockdumps"
local delta=1000000
graceful
local toblock
local blockstart=1
while :
do
toblock=$(( blockstart + delta - 1 ))
printf -v filename 'bfa2018.blocks.%09d-%09d.export.gz' "$blockstart" "$toblock"
curl --fail "${dumpurl}/${filename}" || break
blockstart=$(( toblock + 1 ))
done
geth --networkid ${BFANETWORKID} --datadir "${BFANODEDIR}" --syncmode "full" --gcmode "archive" import <(
n=1
while gzip -dc "bfa2018-1Mblocksstartingat${n}.block.export.gz" 2>/dev/null
do
n=$(( n + 1000000 ))
done
true
)
}
register_subcommand 'syncmode' 'admin_syncmode' 'Set initial synchronization mode.'
function admin_syncmode
{
echo "Synchronization modes can only be set for the initial "
echo "synchronization. Later follow-up block synchronization "
echo "operations will always be \"full\" and can not be changed."
echo "Available synchronization modes:"
echo " full : verify all blocks and all transactions (most secure)"
echo " fast : verify all blocks but not all transactions (faster than full, but less certain)"
echo " light: Makes this node into a light node which downloads almost"
echo " nothing, but relies on fast and full nodes in the network"
echo " to answer it's requests. This is the fastest and uses least"
echo " local resources, but outsources all trust to another node."
echo " Possibly still an untested-by-BFA feature."
echo "Default mode is fast, because for many, it is a healthy compromise"
echo "between speed and paranoia. You can change the setting, according to"
echo "your needs."
mode=$( cat ${BFANODEDIR}/syncmode 2>/dev/null || true )
mode=${mode:-fast}
echo "Your current mode is set to ${mode}"
killed=0
orgmode=$mode
mode=
echo
while [ -z "${mode}" ]
do
read -p "Which mode do you wish? : " mode
modefilter "$mode"
if [[ "$mode" =~ ^full$|^fast$|^light$ ]]
then
:
else
echo "Unsupported synchronization mode." >&2
exit 1
fi
done
echo "Remembering your choice."
echo $mode > ${BFANODEDIR}/syncmode
if [ "$orgmode" = "fast" ] && [ "$mode" = "full" ]
then
echo "You increased your paranoia level. The proper thing to do now,"
echo "would be to delete your version of what you synchronized with"
echo "fast mode, and revalidate everything in the entire blockchain."
echo "This probably takes quite a long time and also requires downloading"
echo "all blocks from the entire blockchain again."
yesno n "Do you wish to delete all downloaded blocks and resynchronize?"
if [ "$REPLY" = "y" ]
then
if [ -r "${BFANODEDIR}/geth.pid" ]
then
pid=$( cat ${BFANODEDIR}/geth.pid )
kill -0 $pid 2>/dev/null &&
echo "Killing running geth." &&
killed=1
while ! kill $pid 2>/dev/null
do
sleep 1
done
fi
initdb
test $killed -eq 1 &&
echo &&
echo "The startup.sh should restart your geth shortly."
fi
else
echo "No further action taken."
fi
}
register_subcommand 'bootnode' 'admin_bootnode' 'Enable/disable the local bootnode.'
function admin_bootnode
{
keyfile=${BFANETWORKDIR}/bootnode/key
echo "Only very few wants to actually run a boot node."
echo "If you have a keyfile for a bootnode, then you will"
echo "automatically start one, when restarting your system."
if [ -f $keyfile ]
then
echo "You are set up to run a boot node."
echo "Deleting your bootnode keyfile disables your bootnode."
yesno n "Do you want to delete your bootnode keyfile?"
if [ "$REPLY" = "y" ]
then
rm $keyfile
fi
pidfile=${BFANETWORKDIR}/bootnode/pid
if [ -r $pidfile ]
then
pid=`cat $pidfile`
kill -0 $pid &&
echo "Terminating your bootnode." &&
kill `cat $pidfile` ||
true
fi
else
echo "You are not set up to run a boot node."
yesno n "Do you want to create a keyfile for a bootnode?"
if [ "$REPLY" = "y" ]
then
bootnode -genkey $keyfile
fi
echo "You can now start your bootnode by running start.sh"
fi
}
register_subcommand 'account' 'bfaaccount' 'Account manipulation.'
function bfaaccount
{
case "$1" in
'create')
exec create_account
;;
*)
echo "Usage: $0 account create" >&2
echo ' create' 'Create an extra account locally on the node.' >&2
exit 1
;;
esac
}
function create_account
{
local num=0
local filename
for filename in ${BFANODEDIR}/keystore/*
do
test -f "$filename" &&
num=$(( num + 1 ))
done
if [ "$num" -gt 0 ]
then
local plural=""
if [ "$num" -ne 1 ]
then
plural="s"
fi
yesno n "You already have ${num} account${plural}. Do you wish to create an extra?"
if [ "$REPLY" = "n" ]
then
return
fi
fi
geth --cache 0 --datadir ${BFANODEDIR} --password /dev/null account new
}
register_subcommand 'truncatelog' 'truncatelog' \
'Truncate the log file. You may want to stop the background processes first.'
function truncatelog
{
true > ${BFANODEDIR}/log
}
register_subcommand 'bfageth' 'bfageth' 'Start geth for BFA.'
function bfageth
{
exec geth --config ${BFANETWORKDIR}/conf.bfa2018.local+full+archive "$@"
}
function bfaadmin
{
case "$1" in
'bootnode')
admin_bootnode
;;
'syncmode')
admin_syncmode
;;
'account')
create_account
;;
*)
echo Usage: `basename $0` "{bootnode|syncmode|account}"
trap '' ERR
exit 1
esac
}
register_subcommand 'tail' 'bfatail' 'tail -f on the logfile.'
function bfatail
{
exec tail -n 100 -F ${BFANODEDIR}/log
exit 1
}
register_subcommand 'log' 'bfalog' 'Open the logfile with less(1).'
function bfalog
{
exec less ${BFANODEDIR}/log
exit 1
}
function main
{
case "$(basename $0)" in
'bfa')
local cmd
cmd=$1
shift || _usage
test -n "$cmd" && test -n "${commands[$cmd]}" || _usage
eval ${commands[$cmd]} "$*"
;;
'admin.sh')
bfaadmin "$*"
;;
'bfalog.sh')
bfatail
;;
'bfageth')
bfageth "$*"
exit 1
esac
}
main "$*"
#!/bin/bash
# Robert Martin-Legene <robert@nic.ar>
if [ -z "${BFAHOME}" ]; then echo "\$BFAHOME not set. Did you source bfa/bin/env ?" >&2; exit 1; fi
source ${BFAHOME}/bin/libbfa.sh || exit 1
exec tail -n 100 -F ${BFANODEDIR}/log
bfa
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment