Skip to content

Commit a2f6848

Browse files
committed
shellcheck for the miner.sh bitcoin mining script
1 parent 1efa987 commit a2f6848

1 file changed

Lines changed: 81 additions & 65 deletions

File tree

docker/bitcoin/miner.sh

Lines changed: 81 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -1,46 +1,46 @@
1+
#!/bin/env bash
2+
13
set -e
24
trap "exit" INT TERM
35
trap "kill 0" EXIT
46

5-
6-
DEFAULT_TIMEOUT=$(($(date +%s) + 30)) ## set the default mining timeout to the current epoch +30s
7-
DEFINED_ADDRESSES=$(compgen -A variable | grep "STACKS.*.BTC_ADDR") ## retrieve env vars matching STACKS*BTC_ADDRESS
8-
DEFINED_WALLETS=$(compgen -A variable | grep "STACKS.*.BTC_WALLET") ## retrieve env vars matching STACKS*BTC_WALLET
9-
mapfile -t ADDRESSES < <(printf '%s\n' "$DEFINED_ADDRESSES" | tr ' ' '\n') ## convert the compgen output to an array
10-
mapfile -t WALLETS < <(printf '%s\n' "$DEFINED_WALLETS" | tr ' ' '\n') ## convert the compgen output to an array
11-
NUM_MINERS=${#ADDRESSES[@]} ## use the same value for total miners throughout script
12-
RESERVED_BLOCKS=100 ## during initial block mining, reserve 100 blocks to mine at the end so the earlier blocks have received rewards by the epoch 2.0 block
7+
DEFAULT_TIMEOUT=$(($(date +%s) + 30)) # set the default mining timeout to the current epoch +30s
8+
DEFINED_ADDRESSES=$(compgen -A variable | grep "STACKS.*.BTC_ADDR") # retrieve env vars matching STACKS*BTC_ADDRESS
9+
DEFINED_WALLETS=$(compgen -A variable | grep "STACKS.*.BTC_WALLET") # retrieve env vars matching STACKS*BTC_WALLET
10+
mapfile -t ADDRESSES < <(printf '%s\n' "$DEFINED_ADDRESSES" | tr ' ' '\n') # convert the compgen output to an array
11+
mapfile -t WALLETS < <(printf '%s\n' "$DEFINED_WALLETS" | tr ' ' '\n') # convert the compgen output to an array
12+
NUM_MINERS=${#ADDRESSES[@]} # use the same value for total miners throughout script
13+
RESERVED_BLOCKS=100 # during initial block mining, reserve 100 blocks to mine at the end so the earlier blocks have received rewards by the epoch 2.0 block
1314

1415

1516
function get_height(){
16-
## return the current block height, or -1 in case of error
17-
echo $(bitcoin-cli -rpcconnect=bitcoin getblockcount 2>/dev/null || echo "-1")
17+
# return the current block height, or -1 in case of error
18+
bitcoin-cli -rpcconnect=bitcoin getblockcount 2>/dev/null || echo "-1"
1819
true
1920
}
2021

2122
function get_mining_info(){
22-
## canary check for getmininginfo if `chain` == `regtest`. else return a failure
23+
# canary check for getmininginfo if `chain` == `regtest`. else return a failure
2324
local mining_info=""
25+
local chain=""
2426
mining_info=$(bitcoin-cli -rpcconnect=bitcoin -rpcwait getmininginfo 2> /dev/null)
25-
local ret="$?"
26-
local chain=$(echo "${mining_info}" | awk '/chain/ { gsub(/[",]/,""); print $2}')
27+
chain=$(echo "${mining_info}" | awk '/chain/ { gsub(/[",]/,""); print $2}')
2728
if [ "$chain" == "regtest" ];then
2829
return 0
2930
fi
3031
return 1
3132
}
3233

3334
function get_wallet_info(){
34-
## returns if a wallet exists
35-
## if wallet db exists, but wallet is not loaded: this will lead to failure of the script since the wallet cannot be created since it is on disk but not loaded in memory
36-
## note: the health check in the docker compose file should avoid this scenario, since stacks-miner services will wait until the epoch 2.05 block before starting
35+
# returns if a wallet exists
36+
# if wallet db exists, but wallet is not loaded: this will lead to failure of the script since the wallet cannot be created since it is on disk but not loaded in memory
37+
# note: the health check in the docker compose file should avoid this scenario, since stacks-miner services will wait until the epoch 2.05 block before starting
3738
echo "[func] Get wallet info"
3839
local wallet=${1}
3940
echo " - checking for wallet (${wallet})"
40-
local getwallet=""
4141
local ret=""
42-
getwallet=$(bitcoin-cli -rpcconnect=bitcoin -rpcwait -rpcwallet=${wallet} getwalletinfo 2>&1 > /dev/null) # || return $?
43-
local ret=$?
42+
bitcoin-cli -rpcconnect=bitcoin -rpcwait -rpcwallet="${wallet}" getwalletinfo > /dev/null 2>&1
43+
ret="$?"
4444
if [ "$ret" -eq "0" ]; then
4545
echo " - successfully retrieved named wallet"
4646
true
@@ -49,13 +49,13 @@ function get_wallet_info(){
4949
}
5050

5151
function create_wallet(){
52-
## Create a named bitcoin wallet
52+
# Create a named bitcoin wallet
5353
echo " [func] Create Wallet"
5454
local wallet=${1}
5555
local descriptors=${2:-false}
5656
local load_on_startup=${3:-true}
5757
echo " - Creating named wallet ${wallet} (desciptors: ${descriptors}, load_on_startup=${load_on_startup})"
58-
local createwallet=$(bitcoin-cli -rpcconnect=bitcoin -named createwallet wallet_name=${wallet} descriptors=${descriptors} load_on_startup=${load_on_startup} 2>&1 > /dev/null)
58+
bitcoin-cli -rpcconnect=bitcoin -named createwallet wallet_name="${wallet}" descriptors="${descriptors}" load_on_startup="${load_on_startup}" > /dev/null 2>&1
5959
ret=$?
6060
if [ "$ret" -eq "0" ]; then
6161
echo " - successfully created named wallet (${wallet})"
@@ -64,37 +64,39 @@ function create_wallet(){
6464
}
6565

6666
function get_address_info(){
67-
## Check if a provided address was imported
67+
# Check if a provided address was imported
6868
local wallet=${1}
6969
local address=${2}
70-
local getaddressinfo=""
70+
local getaddressinfo
71+
local is_found
7172
echo " [func] Get address info"
7273
echo " - Checking (${wallet}) for address (${address})"
73-
getaddressinfo=$(bitcoin-cli -rpcconnect=bitcoin -rpcwait -rpcwallet=${wallet} getaddressinfo ${address} 2> /dev/null)
74+
getaddressinfo=$(bitcoin-cli -rpcconnect=bitcoin -rpcwait -rpcwallet="${wallet}" getaddressinfo "${address}" 2> /dev/null)
7475
local ret="$?"
75-
local is_found=$(echo "${getaddressinfo}" | awk '/iswatchonly/ { gsub(/[",]/,""); print $2}') ## check if the address iswatchonly: true
76+
is_found=$(echo "${getaddressinfo}" | awk '/iswatchonly/ { gsub(/[",]/,""); print $2}') # check if the address iswatchonly: true
7677
if [ "$is_found" == "true" ]; then
7778
echo " - Address ${address} already imported ($is_found)"
7879
else
7980
echo " - Address ${address} is not imported ($is_found)"
80-
ret=1 # force a return since the above command *was* successful, just not the data we want
81+
# force a non-zero return since the above command (is_found) *was* successful, just not the data we want
82+
ret=1
8183
fi
8284
return $ret
8385
}
8486

8587
function mine_blocks(){
86-
## Mine regtest blocks to a specified wallet address
88+
# Mine regtest blocks to a specified wallet address
8789
echo "[func] Mine blocks"
8890
local wallet=${1}
8991
local address=${2}
9092
local blocks=${3}
9193
echo " - Mining ${blocks} blocks to address ${address} in wallet ${wallet}"
92-
bitcoin-cli -rpcwallet=${wallet} -rpcconnect=bitcoin generatetoaddress ${blocks} ${address} 2>&1 > /dev/null || false
94+
bitcoin-cli -rpcwallet="${wallet}" -rpcconnect=bitcoin generatetoaddress "${blocks}" "${address}" > /dev/null 2>&1 || false
9395
true
9496
}
9597

9698
function import_address(){
97-
## Import an addresss into a named wallet
99+
# Import an addresss into a named wallet
98100
echo " [func] import_address"
99101
local wallet=${1}
100102
local address=${2}
@@ -103,7 +105,7 @@ function import_address(){
103105
echo " - address: $address"
104106
echo " - wallet: $wallet"
105107
echo " - Importing address ${btc_address} with label ${label} to wallet ${btc_wallet} (rescan: ${rescan})"
106-
bitcoin-cli -rpcwallet=${btc_wallet} -rpcconnect=bitcoin importaddress ${btc_address} ${label} ${rescan} 2>&1 > /dev/null || false
108+
bitcoin-cli -rpcwallet="${btc_wallet}" -rpcconnect=bitcoin importaddress "${btc_address}" "${label}" "${rescan}" > /dev/null 2>&1 || false
107109
true
108110
}
109111

@@ -113,59 +115,60 @@ function mining_loop(){
113115
echo "**** Mining forever ****"
114116
echo "******************************************"
115117
echo
116-
local mined_block_counter=0 ## set the counter before the loop starts
117-
local block_height=$(get_height) ## get the block height
118+
local mined_block_counter
119+
local block_height
120+
mined_block_counter=0 # set the counter before the loop starts
121+
block_height=$(get_height) # get the block height
118122
while true; do
119123
echo "******************************************"
120124
local conf_counter=0
121-
local random_wallet=""
122125
local confs=""
123-
local random="" ## for tracking which array element we're using
126+
local random="" # for tracking which array element we're using
124127
local sleep_duration=${MINE_INTERVAL}
125-
## loop through addresses and see if there are any mining txs in the list
128+
# loop through addresses and see if there are any mining txs in the list
126129
for i in $(seq 0 $((NUM_MINERS - 1)));do
127130
local btc_address=${!ADDRESSES[$i]}
128131
local btc_wallet=${!WALLETS[$i]}
129-
confs=$(bitcoin-cli -rpcwallet=${btc_wallet} -rpcconnect=bitcoin listtransactions '*' 1 0 true | grep -oP '"confirmations": \K\d+' | awk '{print $1}' 2>/dev/null || echo "")
132+
confs=$(bitcoin-cli -rpcwallet="${btc_wallet}" -rpcconnect=bitcoin listtransactions '*' 1 0 true | grep -oP '"confirmations": \K\d+' | awk '{print $1}' 2>/dev/null || echo "")
130133
conf_counter=$(( conf_counter + confs ))
131134
echo " - conf_counter: ${conf_counter}"
132135
done
133-
if [ "${conf_counter}" = "0" ] || [ $(date +%s) -gt $DEFAULT_TIMEOUT ]; then
134-
if [ $(date +%s) -gt $DEFAULT_TIMEOUT ]; then
136+
if [ "${conf_counter}" = "0" ] || [ "$(date +%s)" -gt "$DEFAULT_TIMEOUT" ]; then
137+
if [ "$(date +%s)" -gt "$DEFAULT_TIMEOUT" ]; then
135138
echo "Timed out waiting for a mempool tx, mining a btc block..."
136139
else
137140
echo "Detected Stacks mining mempool tx, mining btc block..."
138141
fi
139-
random=$((0 + $RANDOM % NUM_MINERS )) # random int with a range based on how many miners are defined
142+
random=$((0 + RANDOM % NUM_MINERS )) # random int with a range based on how many miners are defined. start from 0 since we're using an array
140143
echo "Mining block to:"
141144
echo " - wallet: ${!WALLETS[$random]}"
142145
echo " - address: ${!ADDRESSES[$random]}"
143-
echo " - block hash: $(bitcoin-cli -rpcwallet=${!WALLETS[$random]} -rpcconnect=bitcoin generatetoaddress 1 "${!ADDRESSES[$random]}" | awk -F, 'NR==2{ gsub(/[",]/,"");gsub (" ", "", $0);print $1}')"
146+
echo " - block hash: $(bitcoin-cli -rpcwallet="${!WALLETS[$random]}" -rpcconnect=bitcoin generatetoaddress 1 "${!ADDRESSES[$random]}" | awk -F, 'NR==2{ gsub(/[",]/,"");gsub (" ", "", $0);print $1}')"
144147
mined_block_counter=$((mined_block_counter + 1 )) # increment the mined block counter (used when restarting from a chainstate snapshot)
145-
block_height=$((block_height + 1)) # increment the already retrieved block_height, incrementing in the loop
148+
block_height=$((block_height + 1)) # increment the already retrieved block_height, incrementing in the loop
146149
DEFAULT_TIMEOUT=$(($(date +%s) + 30))
147150
else
148151
echo "No Stacks mining tx detected"
149152
fi
150153

151154
if [ "${block_height}" -eq "${PAUSE_HEIGHT}" ]; then
152155
echo "At boundary ( ${PAUSE_HEIGHT} ) - sleeping for ${PAUSE_TIMER}"
153-
sleep ${PAUSE_TIMER}
156+
sleep "${PAUSE_TIMER}"
154157
# if we use the default snapshot, mine the next blocks quickly based on the counter position
155158
elif ! [[ "${CHAINSTATE_DIR}" =~ "genesis" ]] && [[ "${mined_block_counter}" -le "2" ]]; then
156159
echo "Network resumed. sleeping for 5s for next 2 mined blocks"
157160
sleep_duration=5
158-
elif [ "${block_height}" -gt $(( ${STACKS_30_HEIGHT} + 1 )) ]; then
161+
elif [ "${block_height}" -gt $(( STACKS_30_HEIGHT + 1 )) ]; then
159162
echo "In Epoch3, sleeping for ${MINE_INTERVAL_EPOCH3} ... "
160163
sleep_duration=${MINE_INTERVAL_EPOCH3}
161-
elif [ "${block_height}" -gt $(( ${STACKS_25_HEIGHT} + 1 )) ]; then
164+
elif [ "${block_height}" -gt $(( STACKS_25_HEIGHT + 1 )) ]; then
162165
echo "In Epoch2.5, sleeping for ${MINE_INTERVAL_EPOCH25} ... "
163166
sleep_duration=${MINE_INTERVAL_EPOCH25}
164167
fi
165168
echo "Current btc height: ${block_height}"
166169
echo "total mined blocks: ${mined_block_counter}"
167170
echo "sleeping for ${sleep_duration}s"
168-
sleep ${sleep_duration} &
171+
sleep "${sleep_duration}" &
169172
wait || exit 0
170173
done
171174
true
@@ -178,11 +181,9 @@ function init(){
178181
echo "Waiting indefinitely for a return from 'bitcoin-cli getmininginfo'"
179182
sleep 1
180183
done
181-
182184
local mineable_blocks=$(( (STACKS_2_05_HEIGHT - 1) - RESERVED_BLOCKS )) # calculate the total number of blocks to allocate to the defined stacks-miner wallets
183185
local remainder_blocks=0 # set the initial remainder as zero before calculating if there is a modulus
184186
local mined_counter=0 # keep track of initial mined blocks
185-
local address_count=0 # keep track of how many addresses have an initial balance
186187
blocks_per_miner=$(( mineable_blocks / NUM_MINERS )) # how many blocks per miner address
187188
remainder_blocks=$(( (STACKS_2_05_HEIGHT - 1) - (blocks_per_miner * NUM_MINERS + RESERVED_BLOCKS) )) # if there is a modulus, we need to mine them to the last miner address
188189
for i in $(seq 0 $((NUM_MINERS - 1)));do
@@ -195,40 +196,54 @@ function init(){
195196
if [ "$i" -eq $((NUM_MINERS - 1)) ];then
196197
blocks_per_miner=$((blocks_per_miner + remainder_blocks)) # this is the last miner address. add the modulus to the defined number of blocks for all miner
197198
fi
198-
if ! get_wallet_info ${btc_wallet}; then ## Check if a wallet is loaded in memory
199-
if ! create_wallet ${btc_wallet}; then ## Create a wallet if one is not loaded in memory (if not in memory, but on disk...this will break the script)
199+
# Check if a wallet is loaded in memory
200+
if ! get_wallet_info "${btc_wallet}"; then
201+
# Create a wallet if one is not loaded in memory (if not in memory, but on disk...this will break the script)
202+
if ! create_wallet "${btc_wallet}"; then
200203
echo "ERROR creating wallet (${btc_wallet})"
201-
exit 1 ## Exit if wallet creation returns a failure
204+
# Exit if wallet creation returns a failure
205+
exit 1
202206
fi
203207
fi
204-
if ! get_address_info ${btc_wallet} ${btc_address}; then ## Check if a specified address is loaded in a specific wallet
205-
if ! import_address ${btc_wallet} ${btc_address}; then ## Import an address into a wallet
208+
# Check if a specified address is loaded in a specific wallet
209+
if ! get_address_info "${btc_wallet}" "${btc_address}"; then
210+
# Import an address into a wallet
211+
if ! import_address "${btc_wallet}" "${btc_address}"; then
206212
echo "ERROR importing address (${btc_address}) into wallet (${btc_wallet})"
207-
exit 1 ## Exit if address import returns a failure
213+
# Exit if address import returns a failure
214+
exit 1
208215
fi
209216
fi
210-
mine_blocks ${btc_wallet} ${btc_address} ${blocks_per_miner} ## mined the initial balance per address (102 blocks / number of miners) per address
211-
mined_counter=$((mined_counter + blocks_per_miner)) ## keep track of how many blocks were mined in this stage
217+
mine_blocks "${btc_wallet}" "${btc_address}" "${blocks_per_miner}" # mined the initial balance per address (102 blocks / number of miners) per address
218+
mined_counter=$((mined_counter + blocks_per_miner)) # keep track of how many blocks were mined in this stage
212219
done
213220
echo ""
214221
echo "******************************************"
215-
local depositor_blocks=$(((STACKS_2_05_HEIGHT - 1) - mined_counter)) ## this should be equal to reserved_blocks (100). this is needed for the stacks-miner wallet address to have mature rewards
222+
local depositor_blocks=$(((STACKS_2_05_HEIGHT - 1) - mined_counter)) # this should be equal to reserved_blocks (100). this is needed for the stacks-miner wallet address to have mature rewards
216223
echo "btc_wallet: depositor"
217224
echo "btc_address: tbd"
218-
if ! get_wallet_info depositor; then ## Check if depositor wallet is loaded in memory
219-
if ! create_wallet depositor; then ## Create depositor wallet if one is not loaded in memory (if not in memory, but on disk...this will break the script)
225+
local depositor_addr
226+
# Check if depositor wallet is loaded in memory
227+
if ! get_wallet_info depositor; then
228+
# Create depositor wallet if one is not loaded in memory (if not in memory, but on disk...this will break the script)
229+
if ! create_wallet depositor; then
220230
echo "Error creating depositor wallet"
221-
exit 1 ## Exit if depositor wallet creation returns a failure
231+
# Exit if depositor wallet creation returns a failure
232+
exit 1
222233
fi
223-
local depositor_addr=$(bitcoin-cli -rpcwallet=depositor -rpcconnect=bitcoin getnewaddress label="" bech32)
234+
depositor_addr=$(bitcoin-cli -rpcwallet=depositor -rpcconnect=bitcoin getnewaddress label="" bech32)
224235
fi
225-
if ! get_address_info depositor ${depositor_addr}; then ## Check if depositor address is loaded in a specific wallet
226-
if ! import_address depositor ${depositor_addr}; then ## Import depositor address into the depositor wallet
236+
# Check if depositor address is loaded in a specific wallet
237+
if ! get_address_info depositor "${depositor_addr}"; then
238+
# Import depositor address into the depositor wallet
239+
if ! import_address depositor "${depositor_addr}"; then
227240
echo "ERROR importing address (depositor) into wallet (${depositor_addr})"
228-
exit 1 ## Exit if depositor address import returns a failure
241+
# Exit if depositor address import returns a failure
242+
exit 1
229243
fi
230244
fi
231-
mine_blocks "depositor" ${depositor_addr} ${depositor_blocks} ## mine blocks to the depositor address (should be 100 blocks so stacks-miner blocks are mature for epoch 2.0)
245+
# mine blocks to the depositor address (should be 100 blocks so stacks-miner blocks are mature for epoch 2.0)
246+
mine_blocks "depositor" "${depositor_addr}" "${depositor_blocks}"
232247
echo ""
233248
echo "******************************************"
234249
echo "Mined ${mined_counter} btc to (${NUM_MINERS}) stacks-miner wallets"
@@ -237,7 +252,8 @@ function init(){
237252
true
238253
}
239254

240-
if [ $(get_height) -eq "0" ]; then ## if the btc height is > 0, we don't need to create the wallets or import address. assume they already exist.
255+
# if the btc height is > 0, we don't need to create the wallets or import address. assume they already exist.
256+
if [ "$(get_height)" -eq "0" ]; then
241257
init
242258
else
243259
echo "Skipping genesis functions"

0 commit comments

Comments
 (0)