-
Notifications
You must be signed in to change notification settings - Fork 0
/
btc-net.sh
executable file
·251 lines (215 loc) · 5.45 KB
/
btc-net.sh
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
#!/bin/bash
### ENVIRONMENT ###
BTC_NET="testnet"
BTC_NET_SUBNET="10.1.0"
NUM_NODES=10
NUM_MINERS=1
BASE_NAME="btc"
LOCALNET=$BASE_NAME"net"
TEST="test"
# DNS_NAME=$BASE_NAME"dns"
# DNS_DOCK="fedfranz/btcnet-dns"
# DNS_IP="10.1.1.2"
# NODE_DOCK="fedfranz/bitcoinlocal:0.12.0-testnet"
NODE_NAME=$BASE_NAME"node"
NODE_DOCK="fedfranz/btcnet-node"
MINER_DOCK="fedfranz/bitcoinlocal:0.12.0-testnet-miner"
RUN_OPTIONS=""
#RUNTIME COMMANDS OPTIONS
NODE=""
### UTILS ###
function check_exit () {
# "$@"
local status=$?
if [ $status -ne 0 ]; then
echo "ERROR: $1 failed ($status)" >&2
exit $status
fi
}
# Include DNS functions
DIR="${BASH_SOURCE%/*}"
if [[ ! -d "$DIR" ]]; then DIR="$PWD"; fi
. "$DIR/btc-dns.sh"
### FUNCTIONS ###
# Run nodes
function run_nodes () {
ctype=$1
n=$2
net=$3
options=$4
basename=""
imagename=""
case $ctype in
"node")
basename="btcnode"
imagename=$NODE_DOCK
;;
"miner")
basename="btcminer"
imagename=$MINER_DOCK
;;
*)
echo "$ctype is not a valid container type. Aborting..."
exit 1
esac
if (( $n > 0 )); then
#Check if other nodes of the same type are running
running=$(docker ps | grep $basename)
if [ -z "$running" ]; then
first=1
last=$n
else
#Get highest container ID number
lastrunning=$(docker ps | grep $basename | sed -e 's/.*[^0-9]\([0-9]\+\)[^0-9]*$/\1/' | sort -n | tail -1)
first=$(expr 1 + $lastrunning)
last=$(expr $first + $n - 1)
fi
#Run containers
echo "Starting $ctype containers ($n)"
for i in $(seq $first $last)
do
runcmd="docker run -d --network=$net --dns=$DNS_IP $options --name=$basename$i $imagename $BTC_NET"
echo $runcmd && $runcmd
check_exit "docker run $imagename"
done
fi
}
# Run new nodes
# Args:
# $1 : container type (node|miner|dns)
# $2 : number of containers to start
function run () {
#TODO get network as parameter - check if no $3, set net=$LOCALNET
ctype=$1
n=$2
run_nodes $ctype $n $LOCALNET
# update_dns -n=$n
}
# Start simulation
function start () {
#Create network
if docker network list | grep -q $LOCALNET
then
echo "$LOCALNET already exists; skipping..."
else
#TODO Create multiple networks
#TODO Take num of subnets as a parameter
echo "Creating $LOCALNET network"
docker network create --internal --subnet $BTC_NET_SUBNET.0/16 $LOCALNET
check_exit "docker network create"
fi
#TODO Start fixed nodes with specific IPs (those returned by the DNS?)
#TODO Get options to choose if to run DNS dynamic (-d) or not OR get number of addresses to add to DNS (-n=N)
tot_nodes=$(($NUM_NODES + $NUM_MINERS))
run_dns -d -n=$tot_nodes
run_nodes "node" $NUM_NODES $LOCALNET
run_nodes "miner" $NUM_MINERS $LOCALNET
#TODO node join/leave script
# ./btc-net-nodes.sh $NODE_NAME &
}
# Stop simulation (stop all containers)
function stop () {
running_nodes=$(docker ps | grep $BASE_NAME | awk '{print $1}')
if [ ! -z "$running_nodes" ]; then
docker stop $running_nodes
fi
}
# Reset simulation (stop and remove all containers)
function reset () {
stop
all_nodes=$(docker ps -a | grep $BASE_NAME | awk '{print $1}')
if [ ! -z "$all_nodes" ]; then
docker rm $all_nodes
fi
}
# Prints node's IP address
function getnodeaddr () {
nodenum=$1
nodeaddr=$(docker exec -it $NODE_NAME$nodenum /bin/bash -ic "ifconfig eth0" | grep "inet " | cut -d: -f2 | awk '{print $1}')
echo $nodeaddr
}
# ParsePeers
function parsepeers () {
if [ -z "$1" ]; then
echo "ERR: nodename expected"; exit 1
fi
nodename=$1 #NODE_NAME
getpeers=$(docker exec -it $nodename /bin/bash -ic "getpeersaddr")
# Check for errors (error output means node's offline)
err=$(echo "$getpeers" | grep error | wc -l)
if (( $err > 0 )); then
echo "Node offline"
else
peers=$(echo "$getpeers" | sed 's/^ *//' | cut -d' ' -f2 | sed -e 's/,//' -e 's/^"//' -e 's/"//' | tr -d '\015')
IFS=$'\n' array=($peers)
index=0
declare -A LIST
for (( i = 0; i < ${#array[@]}; i=i+2 )); do
LIST[$index,0]=${array[$i]}
LIST[$index,1]=${array[$((i+1))]}
index=$((index+1))
done
index=$((index-1))
for i in $(seq 0 $(($index))); do
echo "${LIST[$i,0]} ($([[ ${LIST[$i,1]} = true ]] && echo "inbound" || echo "outbound"))"
done
fi
}
# Prints current peers connections
function getpeers () {
if [ ! -z "$1" ]; then
parsepeers $NODE_NAME$1
else
numnodes=$(docker ps -a | grep $NODE_NAME | wc -l)
for i in $(seq 1 $numnodes)
do
echo "$NODE_NAME$i ($(getnodeaddr $i))"
parsepeers $NODE_NAME$i
done
fi
}
### BEGINNING OF PROGRAM ###
#Parse arguments
#TODO: dns IP, subnets
for i in "$@"
do
case $i in
-n=*|--num-nodes=*)
NUM_NODES="${i#*=}"
NODE="${i#*=}" #Used for runtime commands
shift
;;
-m=*|--num-miners=*)
NUM_MINERS="${i#*=}"
shift
;;
-dns=*|--dns_image=*)
DNS_DOCK="${i#*=}"
shift
;;
-btc=*|--btc_image=*)
NODE_DOCK="${i#*=}"
shift
;;
-net=*|--btc_network=*)
BTC_NET="${i#*=}"
shift
;;
-o=*)
RUN_OPTIONS+=" $i" #TODO Currently unused
shift
;;
*) # Execute commands
cmd=$i
shift
$cmd $@
exit 0
;;
esac
done
#TODO Update docker images ? - Take as option
#TODO Take list of images as a parameter - or just use one image with different tags (take tags list)
# docker pull $NODE_DOCK
# docker pull $MINER_DOCK
# docker pull $DNS_DOCK
start