-
Notifications
You must be signed in to change notification settings - Fork 5
/
setup
executable file
·479 lines (401 loc) · 14.6 KB
/
setup
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
#!/usr/bin/env bash
# set -u
abort() {
printf "%s" "$@"
exit 1
}
lookingfor() {
printf "Looking for %s\t... " "$@"
}
greentext() {
for var in "$@"
do
printf "\x1B[32m%b\e[0m" "$@"
done
printf "\n"
}
redtext() {
for var in "$@"
do
printf "\x1B[31m%b\e[0m " "$var"
done
printf "\n"
}
successOrFail() {
if [[ $1 == 0 ]]; then
greentext $2
else
redtext $3
echo $4
exit 1
fi
}
if [[ -z "${BASH_VERSION:-}" ]]; then
abort "Bash is required to interpret this script."
fi
# First check OS.
OS="$(uname)"
if [[ "$OS" == "Linux" ]]; then
BCH_TOOLKIT_ON_LINUX=1
elif [[ "$OS" != "Darwin" ]]; then
abort "bch-toolkit is only supported on macOS and Linux."
fi
# Ensure working directory is clean before setup
if [[ -f ".lock" || -f "config.json" ]]; then
printf "It appears you've already run this setup script before.\n"
printf "Please run the ./clean script before trying to setup again.\n"
abort
fi
# This default address makes it easy to generate funds to
# an address you have access to.
BTK_GENERATE_ADDRESS=bchreg:qzerfrqkvsclmrlx3hzl0j2ac2eh0k88wqa0efygtm
BTK_WIF=cUDjy47QLpAUyv1beivDPoYCHjCRVqwRMwCuSnkdF4teVFBDD1ip
BTK_REGTEST=0
BTK_TESTNET=0
BTK_MAINNET=0
BTK_SLEEP_TIME=${sleep:-6}
BTK_BLOCKS=${blocks:-200}
BTK_ENV=$(uname)
BTK_UNLIMITED=0 # Default incl ElectrsCash
BTK_CASHNODE=0 # Default incl Fulcrum
BTK_BCHREST=0
BTK_BCHAPI=0 # Default incl NGINX
BTK_SLP=0 # Default incl SLPDB, slpserve
BTK_DOCKER_NETWORK=${BTK_DOCKER_NETWORK:-"bch-toolkit-network"}
ENV_FILE=./configs/env.env
EXPOSE_PORTS=0
# Process user arguments, or display usage message
if [[ ! -z "${1:-}" ]]; then
for var in "$@"
do
if [[ $var == "bcnh" ]]; then
abort "No command 'bcnh'. Did you mean 'bchn' ?"
fi
[[ $var == "regtest" ]] && BTK_REGTEST=1
[[ $var == "testnet" ]] && BTK_TESTNET=1
[[ $var == "mainnet" ]] && BTK_MAINNET=1
[[ $var == "expose-ports" ]] && EXPOSE_PORTS=1
[[ $var == "bu" ]] && BTK_UNLIMITED=1
[[ $var == "bchn" ]] && BTK_CASHNODE=1
[[ $var == "bchrest" ]] && BTK_BCHREST=1
[[ $var == "bchapi" ]] && BTK_BCHAPI=1
[[ $var == "slp" ]] && BTK_SLP=1
if [[ $var == "wallet" ]]; then
abort "Deprecated: Electron Cash SLP wallet no longer part of bch-toolkit"
fi
if [[ $var == "all" ]]; then
BTK_CASHNODE=1 # Default to BitcoinCashNode
BTK_BCHREST=1
BTK_BCHAPI=1
BTK_SLP=1
fi
done
else
TAB="\t"
normal() {
printf "$1\n"
}
option() {
if [[ ${#1} -lt 3 ]]; then
T="\t\t"
else
T="\t"
fi
printf " $1 $T- $2\n"
}
normal "usage: setup [options]"
normal "options:"
option "dev" "Use the latest cutting edge version of each component"
option "bu" "Bitcoin Unlimited node"
option "bchn" "Bitcoin Cash Node"
option "bchrest" "A rest.bitcoin.com-compatible REST service"
option "bchapi" "Bch-API REST service from Fullstack.cash"
option "slp" "SLP services (SLPDB, slpserve)"
option "all" "all of the above"
exit 0
fi
### Catch exceptions
#Only one network may be selected
if [[ $BTK_REGTEST == 1 && $BTK_TESTNET == 1 ]]; then
echo "Only one network may be selected at a time."
echo "Please select only one."
abort
fi
if [[ $BTK_REGTEST == 1 && $BTK_MAINNET == 1 ]]; then
echo "Only one network may be selected at a time."
echo "Please select only one."
abort
fi
if [[ $BTK_MAINNET == 1 && $BTK_TESTNET == 1 ]]; then
echo "Only one network may be selected at a time."
echo "Please select only one."
abort
fi
# User cannot have more than one node
if [[ $BTK_UNLIMITED == 1 && $BTK_CASHNODE == 1 ]]; then
echo "bch-toolkit cannot run both Bitcoin Unlimited and BitcoinCashNode at the same time."
echo "Please select only one."
abort
fi
# User must have at least one node
if [[ $BTK_UNLIMITED == 0 && $BTK_CASHNODE == 0 ]]; then
echo "Please select at least 1 node (bu or bchn) to set up."
abort
fi
### End exception catching
# Check that Python3 is installed
lookingfor "Python 3"
[[ -x "$(command -v python3)" ]]
successOrFail $? 'found' 'not found' 'Python 3 not found. Please install Python 3.'
# Check that openssl is installed and available
if [[ $BTK_BCHAPI == 1 ]]; then
lookingfor "OpenSSL"
[[ -x "$(command -v openssl)" ]]
successOrFail $? 'found' 'not found' 'OpenSSL not found. Please install OpenSSL.'
fi
# Check that Docker and docker-compose are installed
lookingfor "Docker"
[[ -x "$(command -v docker)" ]];
successOrFail $? 'found' 'not found' 'Docker not found. Please install docker.'
# Note: The following line may seem useless,
# however it causes the scirpt to error if
# A) Docker is not currently running, or
# B) permissions are not set correctly on Linux
printf "Checking that Docker is running\t... "
BTK_DOCKER_STATUS=`docker ps`
successOrFail $? 'done' 'error' ''
lookingfor "docker-compose"
[[ -x "$(command -v docker-compose)" ]]
successOrFail $? 'found' 'not found' 'Docker-compose not found. Please install docker-compose.'
# Create Docker network if it doesn't exist
if [[ -z $(docker network ls --filter name=^${BTK_DOCKER_NETWORK}$ --format="{{ .Name }}") ]]; then
eval "docker network create ${BTK_DOCKER_NETWORK} &> /dev/null"
fi
# Create new SSL certificate/key pair to be used on nginx server
if [[ $BTK_BCHAPI == 1 ]]; then
if [[ -d "./configs/cert" ]]; then
if [[ -f "./configs/cert/cert.key" && -f "./configs/cert/cert.crt" ]]; then
printf "OpenSSL certificates already exist.\n"
else
printf "Removing previous certs directory\t... "
rm -rf ./configs/cert
successOrFail $? 'done' 'error' 'Could not delete certificate directory.'
fi
fi
if [[ ! -d "./configs/cert" ]]; then
printf "Creating SSL certificate directory\t... "
mkdir ./configs/cert
successOrFail $? 'done' 'error' 'Could not create certificate directory.'
printf "Creating SSL certificate\t... "
eval "openssl req -x509 -nodes -days 365 -newkey rsa:2048 \
-keyout ./configs/cert/cert.key \
-out ./configs/cert/cert.crt \
-subj \"/C=no/ST=no/L=no/O=no/OU=no/CN=no/emailAddress=no\"" &> /dev/null
successOrFail $? 'done' 'error' 'Could not create SSL certificate.'
fi
fi
source ./configs/pass.conf
if [[ $BTK_UNLIMITED == 1 ]]; then
cp ./configs/default_bu.conf ./configs/bitcoin-unlimited.conf
NODE_CONFIG_FILE=./configs/bitcoin-unlimited.conf
else
cp ./configs/default_bitcoincashnode.conf ./configs/bitcoincashnode.conf
NODE_CONFIG_FILE=./configs/bitcoincashnode.conf
cp ./configs/fulcrum-config.conf ./configs/temp-fulcrum-config.conf
FULCRUM_CONFIG_FILE=./configs/temp-fulcrum-config.conf
fi
if [[ $BTK_SLP == 1 ]]; then
if [[ -z ${MONGO_USER} ]]; then
printf "SLPDB uses mongodb, a username and password is recommended."
printf "\n Please enter a username for mongodb:\n"
read MONGO_USER
echo "export MONGO_USER=$MONGO_USER">>./configs/pass.conf
fi
if [[ -z ${MONGO_PASS} ]]; then
printf "\n Please enter a password for mongodb:"
read MONGO_PASS
echo "export MONGO_PASS=$MONGO_PASS">>./configs/pass.conf
fi
fi
if [[ $BTK_MAINNET == 1 ]]; then
# Check if password already set
if [[ -z ${RPC_PASSWORD} ]]; then
printf "\n Please enter a username for the node RPC connection:\n"
read NEW_RPC_USERNAME
printf "\n Please enter a password for the RPC connection on the node.\n This will be stored in the pass.conf file in the configs directory.\n"
read NEW_RPC_PASSWORD
printf $NEW_RPC_PASSWORD
echo "rpcuser=$NEW_RPC_USERNAME">>$NODE_CONFIG_FILE
echo "rpcpassword=$NEW_RPC_PASSWORD">>$NODE_CONFIG_FILE
# Add to pass.conf
echo "export RPC_USERNAME=$NEW_RPC_USERNAME">>./configs/pass.conf
echo "export RPC_PASSWORD=$NEW_RPC_PASSWORD">>./configs/pass.conf
else
printf "Password found\n"
echo "rpcuser=$RPC_USERNAME">>$NODE_CONFIG_FILE
echo "rpcpassword=$RPC_PASSWORD">>$NODE_CONFIG_FILE
fi
if [[ $BTK_CASHNODE == 1 ]]; then
echo "bitcoind = bch-node:8332">>$FULCRUM_CONFIG_FILE
echo "rpcuser = $RPC_USERNAME">>$FULCRUM_CONFIG_FILE
echo "rpcpassword = $RPC_PASSWORD">>$FULCRUM_CONFIG_FILE
fi
echo "rpcport=8332">>$NODE_CONFIG_FILE
echo "rpcbind=0.0.0.0:8332">>$NODE_CONFIG_FILE
echo "maxconnections=10">>$NODE_CONFIG_FILE
# Config env file for ./services
echo "export RPC_PORTS=8332">>$ENV_FILE
echo "export NETWORK=mainnet">>$ENV_FILE
echo "export DB_NAME=slpdb">>$ENV_FILE
fi
if [[ $BTK_TESTNET == 1 ]]; then
if [[ -z ${RPC_PASSWORD} ]];then
printf "\n Please enter a username for the node RPC connection:\n"
read NEW_RPC_USERNAME
printf "\n Please enter a password for the RPC connection on the node.\n This will be stored in the pass.conf file in the configs directory.\n"
read NEW_RPC_PASSWORD
printf $NEW_RPC_PASSWORD
echo "rpcuser=$NEW_RPC_USERNAME">>$NODE_CONFIG_FILE
echo "rpcpassword=$NEW_RPC_PASSWORD">>$NODE_CONFIG_FILE
# Add to pass.conf
echo "export RPC_USERNAME=$NEW_RPC_USERNAME">>./configs/pass.conf
echo "export RPC_PASSWORD=$NEW_RPC_PASSWORD">>./configs/pass.conf
else
printf "Password found\n"
echo "rpcuser=$RPC_USERNAME">>$NODE_CONFIG_FILE
echo "rpcpassword=$RPC_PASSWORD">>$NODE_CONFIG_FILE
fi
if [[ $BTK_CASHNODE == 1 ]]; then
echo "bitcoind = bch-node:18332">>$FULCRUM_CONFIG_FILE
echo "rpcuser = $RPC_USERNAME">>$FULCRUM_CONFIG_FILE
echo "rpcpassword = $RPC_PASSWORD">>$FULCRUM_CONFIG_FILE
fi
echo "testnet=1">>$NODE_CONFIG_FILE
echo "maxconnections=10">>$NODE_CONFIG_FILE
echo "rpcport=18332">>$NODE_CONFIG_FILE
echo "rpcbind=0.0.0.0:18332">>$NODE_CONFIG_FILE
# Config env file for ./services
echo "export RPC_PORTS=18332">>$ENV_FILE
echo "export NETWORK=testnet">>$ENV_FILE
echo "export DB_NAME=slpdb_test">>$ENV_FILE
fi
if [[ $BTK_REGTEST == 1 ]]; then
if [[ -z "${RPC_PASSWORD}" ]]; then
printf "\n Please enter a username for the node RPC connection:\n"
read NEW_RPC_USERNAME
printf "\n Please enter a password for the RPC connection on the node.\n This will be stored in the pass.conf file in the configs directory.\n"
read NEW_RPC_PASSWORD
echo "rpcuser=$NEW_RPC_USERNAME">>$NODE_CONFIG_FILE
echo "rpcpassword=$NEW_RPC_PASSWORD">>$NODE_CONFIG_FILE
# Add to pass.conf
echo "export RPC_USERNAME=$NEW_RPC_USERNAME">>./configs/pass.conf
echo "export RPC_PASSWORD=$NEW_RPC_PASSWORD">>./configs/pass.conf
else
echo "rpcuser=$RPC_USERNAME">>$NODE_CONFIG_FILE
echo "rpcpassword=$RPC_PASSWORD">>$NODE_CONFIG_FILE
fi
if [[ $BTK_UNLIMITED == 1 ]]; then
echo "regtest=1">>$NODE_CONFIG_FILE
echo "export ELECTRUM_INDEXER=bch-node">>$ENV_FILE
else
echo "regtest = 1" >>$NODE_CONFIG_FILE
echo "[regtest]">>$NODE_CONFIG_FILE
echo "bitcoind = bch-node:18443">>$FULCRUM_CONFIG_FILE
echo "rpcuser = $RPC_USERNAME">>$FULCRUM_CONFIG_FILE
echo "rpcpassword = $RPC_PASSWORD">>$FULCRUM_CONFIG_FILE
fi
echo "rpcport=18443">>$NODE_CONFIG_FILE
echo "rpcbind=0.0.0.0:18443">>$NODE_CONFIG_FILE
echo "maxconnections=0">>$NODE_CONFIG_FILE
# Config env file for ./services
echo "export RPC_PORTS=18443">>$ENV_FILE
echo "export NETWORK=regtest">>$ENV_FILE
echo "export DB_NAME=slpdb_test">>$ENV_FILE
fi
# Here we need to copy the conf and append based on network and values before
# echo "RPC_PASSWORD=$NEW_RPC_PASSWORD">>./configs/pass.conf
source ./configs/pass.conf
source ./configs/env.env
# Set up the config file based on user input
printf "Creating config files ... "
python3 - << EOF
import json, os
PREFIX = "./compose_files/"
config = {
"node": [],
"indexer": [],
"rest": [],
"slp": [],
"network": ""
}
if ${BTK_UNLIMITED}:
if ${EXPOSE_PORTS}:
config["node"] += ["bitcoinunlimited_ports"]
config["node"] += ["bitcoinunlimited"]
if ${BTK_CASHNODE}:
if ${EXPOSE_PORTS}:
config["node"] += ["bitcoincashnode_ports"]
config["indexer"] += ["fulcrum_ports"]
config["node"] += ["bitcoincashnode"]
config["indexer"] += ["fulcrum"]
if ${BTK_BCHREST}:
if ${EXPOSE_PORTS}:
config["rest"] += ["opensight_ports"]
config["rest"] += ["bchrest_ports"]
config["rest"] += ["opensight"]
config["rest"] += ["bchrest"]
if ${BTK_BCHAPI}:
if ${EXPOSE_PORTS}:
config["rest"] += ["nginx_ports"]
config["rest"] += ["bchapi_ports"]
config["rest"] += ["nginx"]
config["rest"] += ["bchapi"]
if ${BTK_SLP}:
if ${EXPOSE_PORTS}:
config["slp"] += ["mongodb_ports"]
config["slp"] += ["slpdb"]
config["slp"] += ["slpserve_ports"]
config["slp"] += ["mongodb"]
config["slp"] += ["slpdb"]
config["slp"] += ["slpserve"]
config["network"] = "network"
def iterdict(d):
s = "DOCKER_ARGS=\""
for k,v in d.items():
if isinstance(v, dict):
iterdict(v)
elif isinstance(v, list):
for item in v:
if item:
s += "-f {}{}.yml ".format(PREFIX,item)
else:
if v:
s += "-f {}{}.yml ".format(PREFIX, v)
return "{}\"\n".format(s.strip())
docker_compose_args = iterdict(config)
with open('config.json', 'w') as config_file:
json.dump(config, config_file)
with open('.lock', 'w') as lock_file:
lock_file.write(docker_compose_args)
EOF
successOrFail $? 'done' 'error' 'Could not create config files.'
# Pull the Docker images
source .lock
eval "docker-compose -p bch-toolkit $DOCKER_ARGS pull"
#TODO: Find a way to only run this if the images
# aren't already pulled.
# Initailze regtest node
eval "docker-compose $DOCKER_ARGS up -d bch-node"
sleep $BTK_SLEEP_TIME
if [[ $BTK_REGTEST == 1 ]]; then
# Generate N blocks
printf "Generating $BTK_BLOCKS initial blocks for regtest\t... "
eval "docker-compose $DOCKER_ARGS exec -T bch-node bitcoin-cli -conf=/bitcoin.conf generate $BTK_BLOCKS > /dev/null"
successOrFail $? 'done' 'error' 'Could not create blocks.'
fi
printf "Stopping local node\t... "
sleep $BTK_SLEEP_TIME
eval "docker-compose $DOCKER_ARGS exec -T bch-node bitcoin-cli -conf=/bitcoin.conf stop > /dev/null"
successOrFail $? 'done' 'error' 'Could not stop local node.'
printf "\nFinished. Please use './services start' to run your new regtest node."
# End of file