forked from rzmahmood/ethereum-pos-testnet
-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathtestnet.sh
executable file
·233 lines (197 loc) · 8.57 KB
/
testnet.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
#!/bin/bash
set -exu
set -o pipefail
# Check if jq is installed
if ! command -v jq &> /dev/null; then
echo "Error: jq is not installed. Please install jq first."
exit 1
fi
# Check if curl is installed
if ! command -v curl &> /dev/null; then
echo "Error: curl is not installed. Please install curl first."
exit 1
fi
# NETWORK_DIR is where all files for the testnet will be stored,
# including logs and storage
NETWORK_DIR=./network
# Change this number for your desired number of nodes
NUM_NODES=4
# Port information. All ports will be incremented upon
# with more validators to prevent port conflicts on a single machine
GETH_BOOTNODE_PORT=30301
GETH_HTTP_PORT=8000
GETH_WS_PORT=8100
GETH_AUTH_RPC_PORT=8200
GETH_METRICS_PORT=8300
GETH_NETWORK_PORT=8400
PRYSM_BEACON_RPC_PORT=4000
PRYSM_BEACON_GRPC_GATEWAY_PORT=4100
PRYSM_BEACON_P2P_TCP_PORT=4200
PRYSM_BEACON_P2P_UDP_PORT=4300
PRYSM_BEACON_MONITORING_PORT=4400
PRYSM_VALIDATOR_RPC_PORT=7000
PRYSM_VALIDATOR_GRPC_GATEWAY_PORT=7100
PRYSM_VALIDATOR_MONITORING_PORT=7200
trap 'echo "Error on line $LINENO"; exit 1' ERR
# Function to handle the cleanup
cleanup() {
echo "Caught Ctrl+C. Killing active background processes and exiting."
kill $(jobs -p) # Kills all background processes started in this script
exit
}
# Trap the SIGINT signal and call the cleanup function when it's caught
trap 'cleanup' SIGINT
# Reset the data from any previous runs and kill any hanging runtimes
rm -rf "$NETWORK_DIR" || echo "no network directory"
mkdir -p $NETWORK_DIR
pkill geth || echo "No existing geth processes"
pkill beacon-chain || echo "No existing beacon-chain processes"
pkill validator || echo "No existing validator processes"
pkill bootnode || echo "No existing bootnode processes"
# Set Paths for your binaries. Configure as you wish, particularly
# if you're developing on a local fork of geth/prysm
GETH_BINARY=./dependencies/agora-el/build/bin/geth
GETH_BOOTNODE_BINARY=./dependencies/agora-el/build/bin/bootnode
PRYSM_CTL_BINARY=./dependencies/agora-cl/bazel-bin/cmd/prysmctl/prysmctl_/prysmctl
PRYSM_BEACON_BINARY=./dependencies/agora-cl/bazel-bin/cmd/beacon-chain/beacon-chain_/beacon-chain
PRYSM_VALIDATOR_BINARY=./dependencies/agora-cl/bazel-bin/cmd/validator/validator_/validator
# Create the bootnode for execution client peer discovery.
# Not a production grade bootnode. Does not do peer discovery for consensus client
mkdir -p $NETWORK_DIR/bootnode
$GETH_BOOTNODE_BINARY -genkey $NETWORK_DIR/bootnode/nodekey
$GETH_BOOTNODE_BINARY \
-nodekey $NETWORK_DIR/bootnode/nodekey \
-addr=:$GETH_BOOTNODE_PORT \
-verbosity=5 > "$NETWORK_DIR/bootnode/bootnode.log" 2>&1 &
sleep 2
# Get the ENODE from the first line of the logs for the bootnode
bootnode_enode=$(head -n 1 $NETWORK_DIR/bootnode/bootnode.log)
# Check if the line begins with "enode"
if [[ "$bootnode_enode" == enode* ]]; then
echo "bootnode enode is: $bootnode_enode"
else
echo "The bootnode enode was not found. Exiting."
exit 1
fi
# Generate the genesis. This will generate validators based
# on https://github.com/ethereum/eth2.0-pm/blob/a085c9870f3956d6228ed2a40cd37f0c6580ecd7/interop/mocked_start/README.md
$PRYSM_CTL_BINARY testnet generate-genesis \
--fork=capella \
--num-validators=$NUM_NODES \
--chain-config-file=./config.yml \
--geth-genesis-json-in=./genesis.json \
--output-ssz=$NETWORK_DIR/genesis.ssz \
--geth-genesis-json-out=$NETWORK_DIR/genesis.json
python3 add-bosagora.py
# The prysm bootstrap node is set after the first loop, as the first
# node is the bootstrap node. This is used for consensus client discovery
PRYSM_BOOTSTRAP_NODE=
# Calculate how many nodes to wait for to be in sync with. Not a hard rule
MIN_SYNC_PEERS=$((NUM_NODES/2))
echo $MIN_SYNC_PEERS is minimum number of synced peers required
MINER_LIST=(0x123463a4b065722e99115d6c222f267d9cabb524 0xdF18f7A5880291b50B0d9d3a0feC1e0d2BFf1B74 0xd921B4F2251cF8d08aa4A00892839C0a365E3cd4 0x3cB007d10f3980092E2c9f2b0038050c84d4C1c3)
# Create the validators in a loop
for (( i=0; i<$NUM_NODES; i++ )); do
NODE_DIR=$NETWORK_DIR/node-$i
mkdir -p $NODE_DIR/execution
mkdir -p $NODE_DIR/consensus
mkdir -p $NODE_DIR/logs
echo "TTTTTTTTTTTTTTTTTTTTTTTTTTT------"
echo ${MINER_LIST[i]}
# We use an empty password. Do not do this in production
geth_pw_file="$NODE_DIR/geth_password.txt"
echo "" > "$geth_pw_file"
# Copy the same genesis and inital config the node's directories
# All nodes must have the same genesis otherwise they will reject eachother
cp ./config.yml $NODE_DIR/consensus/config.yml
cp $NETWORK_DIR/genesis.ssz $NODE_DIR/consensus/genesis.ssz
cp $NETWORK_DIR/genesis.json $NODE_DIR/execution/genesis.json
# Create the secret keys for this node and other account details
$GETH_BINARY account new --datadir "$NODE_DIR/execution" --password "$geth_pw_file"
# Initialize geth for this node. Geth uses the genesis.json to write some initial state
$GETH_BINARY init \
--datadir=$NODE_DIR/execution \
$NODE_DIR/execution/genesis.json
# Start geth execution client for this node
$GETH_BINARY \
--networkid=${CHAIN_ID:-2151} \
--http \
--http.api=eth,net,web3 \
--http.addr=127.0.0.1 \
--http.corsdomain="*" \
--http.port=$((GETH_HTTP_PORT + i)) \
--port=$((GETH_NETWORK_PORT + i)) \
--metrics.port=$((GETH_METRICS_PORT + i)) \
--ws \
--ws.api=eth,net,web3 \
--ws.addr=127.0.0.1 \
--ws.origins="*" \
--ws.port=$((GETH_WS_PORT + i)) \
--authrpc.vhosts="*" \
--authrpc.addr=127.0.0.1 \
--authrpc.jwtsecret=$NODE_DIR/execution/jwtsecret \
--authrpc.port=$((GETH_AUTH_RPC_PORT + i)) \
--datadir=$NODE_DIR/execution \
--password=$geth_pw_file \
--bootnodes=$bootnode_enode \
--identity=node-$i \
--maxpendpeers=$NUM_NODES \
--verbosity=3 \
--syncmode=full > "$NODE_DIR/logs/geth.log" 2>&1 &
sleep 5
# Start prysm consensus client for this node
$PRYSM_BEACON_BINARY \
--datadir=$NODE_DIR/consensus/beacondata \
--min-sync-peers=$MIN_SYNC_PEERS \
--genesis-state=$NODE_DIR/consensus/genesis.ssz \
--bootstrap-node=$PRYSM_BOOTSTRAP_NODE \
--interop-eth1data-votes \
--chain-config-file=$NODE_DIR/consensus/config.yml \
--contract-deployment-block=0 \
--chain-id=${CHAIN_ID:-2151} \
--rpc-host=127.0.0.1 \
--rpc-port=$((PRYSM_BEACON_RPC_PORT + i)) \
--grpc-gateway-host=127.0.0.1 \
--grpc-gateway-port=$((PRYSM_BEACON_GRPC_GATEWAY_PORT + i)) \
--execution-endpoint=http://localhost:$((GETH_AUTH_RPC_PORT + i)) \
--accept-terms-of-use \
--jwt-secret=$NODE_DIR/execution/jwtsecret \
--suggested-fee-recipient=${MINER_LIST[i]} \
--minimum-peers-per-subnet=0 \
--p2p-tcp-port=$((PRYSM_BEACON_P2P_TCP_PORT + i)) \
--p2p-udp-port=$((PRYSM_BEACON_P2P_UDP_PORT + i)) \
--monitoring-port=$((PRYSM_BEACON_MONITORING_PORT + i)) \
--verbosity=info \
--slasher \
--enable-debug-rpc-endpoints > "$NODE_DIR/logs/beacon.log" 2>&1 &
# Start prysm validator for this node. Each validator node will
# manage 1 validator
$PRYSM_VALIDATOR_BINARY \
--beacon-rpc-provider=localhost:$((PRYSM_BEACON_RPC_PORT + i)) \
--datadir=$NODE_DIR/consensus/validatordata \
--accept-terms-of-use \
--interop-num-validators=1 \
--interop-start-index=$i \
--rpc-port=$((PRYSM_VALIDATOR_RPC_PORT + i)) \
--grpc-gateway-port=$((PRYSM_VALIDATOR_GRPC_GATEWAY_PORT + i)) \
--monitoring-port=$((PRYSM_VALIDATOR_MONITORING_PORT + i)) \
--graffiti="node-$i" \
--chain-config-file=$NODE_DIR/consensus/config.yml > "$NODE_DIR/logs/validator.log" 2>&1 &
# Check if the PRYSM_BOOTSTRAP_NODE variable is already set
if [[ -z "${PRYSM_BOOTSTRAP_NODE}" ]]; then
sleep 5 # sleep to let the prysm node set up
# If PRYSM_BOOTSTRAP_NODE is not set, execute the command and capture the result into the variable
# This allows subsequent nodes to discover the first node, treating it as the bootnode
PRYSM_BOOTSTRAP_NODE=$(curl -s localhost:4100/eth/v1/node/identity | jq -r '.data.enr')
# Check if the result starts with enr
if [[ $PRYSM_BOOTSTRAP_NODE == enr* ]]; then
echo "PRYSM_BOOTSTRAP_NODE is valid: $PRYSM_BOOTSTRAP_NODE"
else
echo "PRYSM_BOOTSTRAP_NODE does NOT start with enr"
exit 1
fi
fi
done
# You might want to change this if you want to tail logs for other nodes
# Logs for all nodes can be found in `./network/node-*/logs`
tail -f "$NETWORK_DIR/node-0/logs/geth.log"