provisioning/taskservs/polkadot/validator/default/validator-keys.sh.j2

266 lines
8.5 KiB
Plaintext
Raw Permalink Normal View History

#!/bin/bash
# Info: Polkadot Validator Key Management Script
# Author: Provisioning System
set -e
POLKADOT_BIN="{{ polkadot_validator.bin_path }}"
BASE_PATH="{{ polkadot_validator.base_path }}"
KEYSTORE_PATH="{{ polkadot_validator.keystore_path }}"
CONFIG_PATH="{{ polkadot_validator.config_path }}"
CHAIN="{{ polkadot_validator.network.chain }}"
RUN_USER="{{ polkadot_validator.run_user.name }}"
# Session keys file
SESSION_KEYS_FILE="{{ polkadot_validator.session_keys.keys_file | default('/var/lib/polkadot/session-keys') }}"
BACKUP_PATH="{{ polkadot_validator.security.backup_path | default('/var/backups/polkadot') }}"
echo "Polkadot Validator Key Management"
echo "================================="
# Function to generate session keys
generate_session_keys() {
echo "Generating session keys..."
# Call RPC to rotate keys
RESULT=$(curl -H "Content-Type: application/json" -d '{"id":1, "jsonrpc":"2.0", "method": "author_rotateKeys", "params":[]}' http://localhost:9933 2>/dev/null | jq -r '.result' 2>/dev/null || echo "")
if [ -n "$RESULT" ] && [ "$RESULT" != "null" ]; then
echo "$RESULT" > "$SESSION_KEYS_FILE"
echo "Session keys generated and saved to: $SESSION_KEYS_FILE"
echo "Session keys: $RESULT"
# Backup keys if enabled
if [ "{{ polkadot_validator.security.backup_keys | lower }}" = "true" ]; then
backup_keys
fi
return 0
else
echo "Failed to generate session keys via RPC. Is the node running?"
return 1
fi
}
# Function to backup keys
backup_keys() {
echo "Backing up validator keys..."
# Create backup directory
mkdir -p "$BACKUP_PATH"
BACKUP_DATE=$(date +%Y%m%d_%H%M%S)
BACKUP_DIR="$BACKUP_PATH/keys_backup_$BACKUP_DATE"
mkdir -p "$BACKUP_DIR"
# Backup session keys
if [ -f "$SESSION_KEYS_FILE" ]; then
cp "$SESSION_KEYS_FILE" "$BACKUP_DIR/"
echo "Session keys backed up"
fi
# Backup keystore (encrypted)
if [ -d "$KEYSTORE_PATH" ]; then
tar -czf "$BACKUP_DIR/keystore_backup.tar.gz" -C "$(dirname "$KEYSTORE_PATH")" "$(basename "$KEYSTORE_PATH")"
echo "Keystore backed up"
fi
# Backup node key
NODE_KEY_FILE="{{ polkadot_validator.network.node_key_file | default('/var/lib/polkadot/node-key') }}"
if [ -f "$NODE_KEY_FILE" ]; then
cp "$NODE_KEY_FILE" "$BACKUP_DIR/"
echo "Node key backed up"
fi
# Set proper permissions
chown -R "$RUN_USER:$RUN_USER" "$BACKUP_DIR"
chmod -R 600 "$BACKUP_DIR"/*
chmod 700 "$BACKUP_DIR"
echo "Keys backed up to: $BACKUP_DIR"
}
# Function to restore keys from backup
restore_keys() {
BACKUP_DIR="$1"
if [ -z "$BACKUP_DIR" ] || [ ! -d "$BACKUP_DIR" ]; then
echo "Usage: $0 restore <backup_directory>"
echo "Available backups:"
ls -la "$BACKUP_PATH"/keys_backup_* 2>/dev/null || echo "No backups found"
return 1
fi
echo "Restoring keys from: $BACKUP_DIR"
# Stop validator service for safety
systemctl stop polkadot-validator 2>/dev/null || true
# Restore session keys
if [ -f "$BACKUP_DIR/session-keys" ]; then
cp "$BACKUP_DIR/session-keys" "$SESSION_KEYS_FILE"
echo "Session keys restored"
fi
# Restore keystore
if [ -f "$BACKUP_DIR/keystore_backup.tar.gz" ]; then
rm -rf "$KEYSTORE_PATH.old" 2>/dev/null || true
mv "$KEYSTORE_PATH" "$KEYSTORE_PATH.old" 2>/dev/null || true
tar -xzf "$BACKUP_DIR/keystore_backup.tar.gz" -C "$(dirname "$KEYSTORE_PATH")"
echo "Keystore restored"
fi
# Restore node key
NODE_KEY_FILE="{{ polkadot_validator.network.node_key_file | default('/var/lib/polkadot/node-key') }}"
if [ -f "$BACKUP_DIR/node-key" ]; then
cp "$BACKUP_DIR/node-key" "$NODE_KEY_FILE"
echo "Node key restored"
fi
# Set proper permissions
chown -R "$RUN_USER:$RUN_USER" "$KEYSTORE_PATH" "$SESSION_KEYS_FILE" "$NODE_KEY_FILE"
chmod -R 600 "$KEYSTORE_PATH"/* "$SESSION_KEYS_FILE" "$NODE_KEY_FILE"
echo "Keys restored successfully"
echo "Starting validator service..."
systemctl start polkadot-validator
}
# Function to verify session keys
verify_session_keys() {
echo "Verifying session keys..."
if [ ! -f "$SESSION_KEYS_FILE" ]; then
echo "Session keys file not found: $SESSION_KEYS_FILE"
return 1
fi
SESSION_KEYS=$(cat "$SESSION_KEYS_FILE")
echo "Current session keys: $SESSION_KEYS"
# Verify via RPC
RESULT=$(curl -H "Content-Type: application/json" -d "{\"id\":1, \"jsonrpc\":\"2.0\", \"method\": \"author_hasSessionKeys\", \"params\":[\"$SESSION_KEYS\"]}" http://localhost:9933 2>/dev/null | jq -r '.result' 2>/dev/null || echo "false")
if [ "$RESULT" = "true" ]; then
echo "✅ Session keys are valid and loaded in the node"
else
echo "❌ Session keys are not loaded in the node"
return 1
fi
}
# Function to show current keys
show_keys() {
echo "Current Validator Keys:"
echo "======================"
# Session keys
if [ -f "$SESSION_KEYS_FILE" ]; then
echo "Session keys: $(cat "$SESSION_KEYS_FILE")"
else
echo "Session keys: Not generated"
fi
# Node key (show public part only)
NODE_KEY_FILE="{{ polkadot_validator.network.node_key_file | default('/var/lib/polkadot/node-key') }}"
if [ -f "$NODE_KEY_FILE" ]; then
if command -v "$POLKADOT_BIN" >/dev/null 2>&1; then
PEER_ID=$("$POLKADOT_BIN" key inspect-node-key --file "$NODE_KEY_FILE" 2>/dev/null || echo "Unable to extract peer ID")
echo "Node Peer ID: $PEER_ID"
else
echo "Node key: Present (run 'polkadot key inspect-node-key --file $NODE_KEY_FILE' to view peer ID)"
fi
else
echo "Node key: Not generated"
fi
# Keystore info
if [ -d "$KEYSTORE_PATH" ]; then
KEY_COUNT=$(find "$KEYSTORE_PATH" -type f | wc -l)
echo "Keystore keys: $KEY_COUNT files"
echo "Keystore path: $KEYSTORE_PATH"
else
echo "Keystore: Not initialized"
fi
}
# Function to set session keys on-chain
set_session_keys() {
if [ ! -f "$SESSION_KEYS_FILE" ]; then
echo "Session keys not found. Generate them first with: $0 generate"
return 1
fi
SESSION_KEYS=$(cat "$SESSION_KEYS_FILE")
echo "Setting session keys on-chain..."
echo "Session keys: $SESSION_KEYS"
echo ""
echo "To set these keys on-chain:"
echo "1. Go to https://polkadot.js.org/apps/#/staking/actions"
echo "2. Click 'Set Session Key' for your stash account"
echo "3. Paste the session keys: $SESSION_KEYS"
echo "4. Submit the transaction"
echo ""
echo "Or use the Polkadot JS API:"
echo "api.tx.session.setKeys('$SESSION_KEYS', '0x').signAndSend(account)"
}
# Function to rotate session keys
rotate_session_keys() {
echo "Rotating session keys..."
# Backup current keys
if [ -f "$SESSION_KEYS_FILE" ]; then
cp "$SESSION_KEYS_FILE" "$SESSION_KEYS_FILE.backup.$(date +%Y%m%d_%H%M%S)"
echo "Current keys backed up"
fi
# Generate new keys
generate_session_keys
echo "Session keys rotated successfully"
echo "Remember to update the keys on-chain!"
}
# Main command handling
case "${1:-help}" in
"generate")
generate_session_keys
;;
"backup")
backup_keys
;;
"restore")
restore_keys "$2"
;;
"verify")
verify_session_keys
;;
"show")
show_keys
;;
"set")
set_session_keys
;;
"rotate")
rotate_session_keys
;;
"help"|*)
echo "Usage: $0 [command]"
echo ""
echo "Commands:"
echo " generate Generate new session keys"
echo " backup Backup all validator keys"
echo " restore DIR Restore keys from backup directory"
echo " verify Verify current session keys"
echo " show Show current keys information"
echo " set Show instructions for setting keys on-chain"
echo " rotate Rotate session keys (backup old, generate new)"
echo " help Show this help message"
echo ""
echo "Examples:"
echo " $0 generate # Generate new session keys"
echo " $0 verify # Check if keys are loaded"
echo " $0 backup # Backup all keys"
echo " $0 show # Display key information"
;;
esac