Skip to content
This repository was archived by the owner on Nov 15, 2023. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
0dfafb2
Add check_bootnode script and github action
s3krit Mar 14, 2023
5bb0a9e
fix mktemp for linux machines
s3krit Mar 14, 2023
2350fb5
Update check_bootnodes.sh
s3krit Mar 14, 2023
7470da0
fix ephemeral ports and fetch polkadot
s3krit Mar 15, 2023
2d31104
Merge branch 'mp-bootnode-checker' of github.com:paritytech/polkadot …
s3krit Mar 15, 2023
134127c
fix check-bootnodes.yml
s3krit Mar 15, 2023
1af8d0b
increase node spawn holdoff
s3krit Mar 15, 2023
c668286
disable fail-fast
s3krit Mar 15, 2023
1cebfd8
refactor, separate out check_bootnodes and make it posix-compliant
s3krit Mar 15, 2023
1170e84
add new job for detecting new bootnodes
s3krit Mar 15, 2023
feec2e4
fix check-bootnodes.yml
s3krit Mar 15, 2023
da4da9a
only check all bootnodes on release
s3krit Mar 15, 2023
540dd97
Add test bad bootnode
s3krit Mar 15, 2023
5ee885a
fix paths
s3krit Mar 15, 2023
5b465ab
fix paths and git... hopefully
s3krit Mar 15, 2023
9d1a4be
this better work...
s3krit Mar 15, 2023
1e106e7
fix
s3krit Mar 15, 2023
db27961
test
s3krit Mar 15, 2023
fc9a45e
last test
s3krit Mar 15, 2023
db701fb
Revert "Add test bad bootnode"
s3krit Mar 15, 2023
c815413
Merge remote-tracking branch 'origin' into mp-bootnode-checker
s3krit Mar 16, 2023
1733e63
Update check_bootnodes.sh
s3krit Mar 16, 2023
9f76d0e
optimisations
s3krit Mar 16, 2023
9dc9a6a
Merge branch 'mp-bootnode-checker' of github.com:paritytech/polkadot …
s3krit Mar 16, 2023
3f9d31b
increase holdoff to 5 seconds
s3krit Mar 16, 2023
ea5f71c
dont delete chainspec til we kill the node
s3krit Mar 16, 2023
45a94cc
Update check-bootnodes.yml
s3krit Mar 20, 2023
cce201e
Remove checking bootnodes on pushing of this branch
s3krit Mar 20, 2023
90c3faa
Merge remote-tracking branch 'origin/master' into mp-bootnode-checker
Mar 21, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
refactor, separate out check_bootnodes and make it posix-compliant
  • Loading branch information
s3krit committed Mar 15, 2023
commit 1cebfd8e7abd8fe5f6719a1157d027056dfa1be0
47 changes: 47 additions & 0 deletions scripts/ci/common/lib.sh
Original file line number Diff line number Diff line change
Expand Up @@ -139,3 +139,50 @@ has_runtime_changes() {
return 1
fi
}

# given a bootnode and the path to a chainspec file, this function will create a new chainspec file
# with only the bootnode specified and test whether that bootnode provides peers
# The optional third argument is the index of the bootnode in the list of bootnodes, this is just used to pick an ephemeral
# port for the node to run on. If you're only testing one, it'll just use the first ephemeral port
# BOOTNODE: /dns/polkadot-connect-0.parity.io/tcp/443/wss/p2p/12D3KooWEPmjoRpDSUuiTjvyNDd8fejZ9eNWH5bE965nyBMDrB4o
# CHAINSPEC_FILE: /path/to/polkadot.json
check_bootnode(){
BOOTNODE=$1
BASE_CHAINSPEC=$2
RUNTIME=$(basename "$BASE_CHAINSPEC" | cut -d '.' -f 1)

# Generate a temporary chainspec file containing only the bootnode we care about
TMP_CHAINSPEC_FILE="$RUNTIME.$(echo "$BOOTNODE" | tr '/' '_').tmp.json"
jq ".bootNodes = [\"$BOOTNODE\"] " < "$CHAINSPEC_FILE" > "$TMP_CHAINSPEC_FILE"

# Grab an unused port by binding to port 0 and then immediately closing the socket
# This is a bit of a hack, but it's the only way to do it in the shell
RPC_PORT=$(python -c "import socket; s=socket.socket(); s.bind(('', 0)); print(s.getsockname()[1]); s.close()")

echo "[+] Checking bootnode $BOOTNODE"
polkadot --chain "$TMP_CHAINSPEC_FILE" --no-mdns --rpc-port="$RPC_PORT" --tmp > /dev/null 2>&1 &
POLKADOT_PID=$!
# Wait a little while for the node to start up and attempt to start peering
sleep 60
# Delete the temporary chainspec file now we're done running the node
rm "$TMP_CHAINSPEC_FILE"

# Check the health endpoint of the RPC node
PEERS="$(curl -s -X POST -H "Content-Type: application/json" --data '{"jsonrpc":"2.0","method":"system_health","params":[],"id":1}' http://localhost:"$RPC_PORT" | jq -r '.result.peers')"
# Clean up the node
kill -9 $POLKADOT_PID
# Sometimes due to machine load or other reasons, we don't get a response from the RPC node
# If $PEERS is an empty variable, mark the node as unreachable
if [ -z "$PEERS" ]; then
PEERS=0
fi
if [ "$PEERS" -gt 0 ]; then
echo "[+] $PEERS peers found for $BOOTNODE"
echo " Bootnode appears contactable"
return 0
else
echo "[!] $PEERS peers found for $BOOTNODE"
echo " Bootnode appears unreachable"
return 1
fi
}
54 changes: 5 additions & 49 deletions scripts/ci/github/check_bootnodes.sh
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@

# Root of the polkadot dir
ROOT="$(dirname "${0}")/../../.."
# shellcheck source=scripts/ci/common/lib.sh
source "$ROOT/scripts/ci/common/lib.sh"
RUNTIME="$1"

trap cleanup EXIT INT TERM
Expand All @@ -19,67 +21,21 @@ cleanup(){
killall polkadot > /dev/null 2>&1
}

check_bootnode(){
BOOTNODE_INDEX=$1
TMP_CHAINSPEC_FILE="$RUNTIME.$BOOTNODE_INDEX.tmp.json"
FINAL_CHAINSPEC_FILE="$RUNTIME.$BOOTNODE_INDEX.final.json"
# Copy the chainspec file to a temporary location to avoid weird race conditions when running in parallel
cp "$CHAINSPEC_FILE" "$CHAINSPEC_TMPDIR/$TMP_CHAINSPEC_FILE"
pushd "$CHAINSPEC_TMPDIR" > /dev/null || exit 1
jq ".bootNodes |= [.[$BOOTNODE_INDEX]] " < "$TMP_CHAINSPEC_FILE" > "$FINAL_CHAINSPEC_FILE"
BOOTNODE=$( jq -r '.bootNodes[0]' < "$FINAL_CHAINSPEC_FILE" )
# Get the first ephemeral port
if [[ "$OSTYPE" == "darwin"* ]]; then
BASE_PORT=$(sysctl net.inet.ip.portrange.first | awk '{print $2}')
else
BASE_PORT=$(sysctl net.ipv4.ip_local_port_range | awk '{print $3}')
fi
# If we're on a mac, use this instead
# BASE_PORT=$(sysctl net.inet.ip.portrange.first | awk '{print $2}')
RPC_PORT=$((BASE_PORT + BOOTNODE_INDEX))
echo "[+] Checking bootnode $BOOTNODE"
polkadot --chain "$FINAL_CHAINSPEC_FILE" --no-mdns --rpc-port=$RPC_PORT --tmp > /dev/null 2>&1 &
POLKADOT_PID=$!
# We just spun up a bunch of nodes... probably want to wait a bit.
sleep 60
popd > /dev/null || exit 1
# Check the health endpoint of the RPC node
PEERS="$(curl -s -X POST -H "Content-Type: application/json" --data '{"jsonrpc":"2.0","method":"system_health","params":[],"id":1}' http://localhost:$RPC_PORT | jq -r '.result.peers')"
# Clean up the node
kill -9 $POLKADOT_PID
# Sometimes due to machine load or other reasons, we don't get a response from the RPC node
# If $PEERS is an empty variable, mark the node as unreachable
if [ -z "$PEERS" ]; then
PEERS=0
fi
if [ "$PEERS" -gt 0 ]; then
echo "[+] $PEERS peers found for $BOOTNODE"
echo " Bootnode appears contactable"
GOOD_BOOTNODES+=("$BOOTNODE")
return 0
else
echo "[!] $PEERS peers found for $BOOTNODE"
echo " Bootnode appears unreachable"
BAD_BOOTNODES+=("$BOOTNODE")
return 1
fi
}

# For each runtime
CHAINSPEC_FILE="$ROOT/node/service/chain-specs/$RUNTIME.json"
# count the number of bootnodes
BOOTNODES=$( jq -r '.bootNodes | length' "$CHAINSPEC_FILE" )
# Make a temporary dir for chainspec files
CHAINSPEC_TMPDIR="$(mktemp -d -t "${RUNTIME}_chainspecs_XXXXXX")"
echo "[+] Using $CHAINSPEC_TMPDIR as temporary chainspec dir"
# Store an array of the bad bootnodes
BAD_BOOTNODES=()
GOOD_BOOTNODES=()
PIDS=()

echo "[+] Checking $BOOTNODES bootnodes for $RUNTIME"
for i in $(seq 0 $((BOOTNODES-1))); do
BOOTNODE=$( jq -r .bootNodes["$i"] < "$CHAINSPEC_FILE" )
# Check each bootnode in parallel
check_bootnode "$i" &
check_bootnode "$BOOTNODE" "$CHAINSPEC_FILE" &
PIDS+=($!)
# Hold off 10 seconds between attempting to spawn nodes to stop the machine from getting overloaded
sleep 10
Expand Down