From 21d5e0175dcab714f59c2a22543de13970954e09 Mon Sep 17 00:00:00 2001 From: Bruno Galvao Date: Tue, 18 Nov 2025 12:45:31 +0700 Subject: [PATCH 01/39] Add system parachain RPC guide and enhance documentation - Add comprehensive guide for running system parachain RPC nodes - Covers People Chain, Bridge Hub, and Coretime Chain - Provides both Docker and systemd deployment options - Includes snapshot setup, monitoring, and security best practices - Add conclusion sections to RPC and collator guides - polkadot-hub-rpc.md: summarize benefits and next steps - system-parachain-rpc.md: highlight adaptability across system parachains - collator.md: emphasize operator role and responsibilities - Restructure documentation from nodes-and-validators to node-infrastructure --- ...-infrastructure-run-a-collator-collator.md | 560 ++++++++++++++ ...rastructure-run-a-node-polkadot-hub-rpc.md | 622 +++++++++++++++ ...ructure-run-a-node-relay-chain-bootnode.md | 130 ++++ ...ucture-run-a-node-relay-chain-full-node.md | 338 ++++++++ ...cture-run-a-node-relay-chain-secure-wss.md | 125 +++ ...ructure-run-a-node-system-parachain-rpc.md | 652 ++++++++++++++++ ...boarding-and-offboarding-key-management.md | 155 ++++ ...arding-and-offboarding-set-up-validator.md | 213 ++++++ ...arding-and-offboarding-start-validating.md | 255 +++++++ ...oarding-and-offboarding-stop-validating.md | 45 ++ ...or-operational-tasks-general-management.md | 722 ++++++++++++++++++ ...ator-operational-tasks-pause-validating.md | 46 ++ ...tor-operational-tasks-upgrade-your-node.md | 75 ++ ...astructure-run-a-validator-requirements.md | 85 +++ ...-staking-mechanics-offenses-and-slashes.md | 171 +++++ ...n-a-validator-staking-mechanics-rewards.md | 204 +++++ .nav.yml | 2 +- .../.nav.yml | 1 + node-infrastructure/run-a-collator/.nav.yml | 2 + .../run-a-collator/collator.md | 557 ++++++++++++++ node-infrastructure/run-a-node/.nav.yml | 4 + .../run-a-node/polkadot-hub-rpc.md | 619 +++++++++++++++ .../run-a-node/relay-chain}/.nav.yml | 0 .../run-a-node/relay-chain}/bootnode.md | 0 .../run-a-node/relay-chain}/full-node.md | 0 .../run-a-node/relay-chain}/secure-wss.md | 0 .../run-a-node/system-parachain-rpc.md | 649 ++++++++++++++++ .../run-a-validator/.nav.yml | 0 .../onboarding-and-offboarding/.nav.yml | 0 .../key-management.md | 0 .../set-up-validator.md | 0 .../start-validating.md | 0 .../stop-validating.md | 0 .../operational-tasks/.nav.yml | 0 .../operational-tasks/general-management.md | 0 .../operational-tasks/pause-validating.md | 0 .../operational-tasks/upgrade-your-node.md | 0 .../run-a-validator/requirements.md | 0 .../staking-mechanics/.nav.yml | 0 .../staking-mechanics/offenses-and-slashes.md | 0 .../staking-mechanics/rewards.md | 0 41 files changed, 6231 insertions(+), 1 deletion(-) create mode 100644 .ai/pages/node-infrastructure-run-a-collator-collator.md create mode 100644 .ai/pages/node-infrastructure-run-a-node-polkadot-hub-rpc.md create mode 100644 .ai/pages/node-infrastructure-run-a-node-relay-chain-bootnode.md create mode 100644 .ai/pages/node-infrastructure-run-a-node-relay-chain-full-node.md create mode 100644 .ai/pages/node-infrastructure-run-a-node-relay-chain-secure-wss.md create mode 100644 .ai/pages/node-infrastructure-run-a-node-system-parachain-rpc.md create mode 100644 .ai/pages/node-infrastructure-run-a-validator-onboarding-and-offboarding-key-management.md create mode 100644 .ai/pages/node-infrastructure-run-a-validator-onboarding-and-offboarding-set-up-validator.md create mode 100644 .ai/pages/node-infrastructure-run-a-validator-onboarding-and-offboarding-start-validating.md create mode 100644 .ai/pages/node-infrastructure-run-a-validator-onboarding-and-offboarding-stop-validating.md create mode 100644 .ai/pages/node-infrastructure-run-a-validator-operational-tasks-general-management.md create mode 100644 .ai/pages/node-infrastructure-run-a-validator-operational-tasks-pause-validating.md create mode 100644 .ai/pages/node-infrastructure-run-a-validator-operational-tasks-upgrade-your-node.md create mode 100644 .ai/pages/node-infrastructure-run-a-validator-requirements.md create mode 100644 .ai/pages/node-infrastructure-run-a-validator-staking-mechanics-offenses-and-slashes.md create mode 100644 .ai/pages/node-infrastructure-run-a-validator-staking-mechanics-rewards.md rename {nodes-and-validators => node-infrastructure}/.nav.yml (66%) create mode 100644 node-infrastructure/run-a-collator/.nav.yml create mode 100644 node-infrastructure/run-a-collator/collator.md create mode 100644 node-infrastructure/run-a-node/.nav.yml create mode 100644 node-infrastructure/run-a-node/polkadot-hub-rpc.md rename {nodes-and-validators/run-a-node => node-infrastructure/run-a-node/relay-chain}/.nav.yml (100%) rename {nodes-and-validators/run-a-node => node-infrastructure/run-a-node/relay-chain}/bootnode.md (100%) rename {nodes-and-validators/run-a-node => node-infrastructure/run-a-node/relay-chain}/full-node.md (100%) rename {nodes-and-validators/run-a-node => node-infrastructure/run-a-node/relay-chain}/secure-wss.md (100%) create mode 100644 node-infrastructure/run-a-node/system-parachain-rpc.md rename {nodes-and-validators => node-infrastructure}/run-a-validator/.nav.yml (100%) rename {nodes-and-validators => node-infrastructure}/run-a-validator/onboarding-and-offboarding/.nav.yml (100%) rename {nodes-and-validators => node-infrastructure}/run-a-validator/onboarding-and-offboarding/key-management.md (100%) rename {nodes-and-validators => node-infrastructure}/run-a-validator/onboarding-and-offboarding/set-up-validator.md (100%) rename {nodes-and-validators => node-infrastructure}/run-a-validator/onboarding-and-offboarding/start-validating.md (100%) rename {nodes-and-validators => node-infrastructure}/run-a-validator/onboarding-and-offboarding/stop-validating.md (100%) rename {nodes-and-validators => node-infrastructure}/run-a-validator/operational-tasks/.nav.yml (100%) rename {nodes-and-validators => node-infrastructure}/run-a-validator/operational-tasks/general-management.md (100%) rename {nodes-and-validators => node-infrastructure}/run-a-validator/operational-tasks/pause-validating.md (100%) rename {nodes-and-validators => node-infrastructure}/run-a-validator/operational-tasks/upgrade-your-node.md (100%) rename {nodes-and-validators => node-infrastructure}/run-a-validator/requirements.md (100%) rename {nodes-and-validators => node-infrastructure}/run-a-validator/staking-mechanics/.nav.yml (100%) rename {nodes-and-validators => node-infrastructure}/run-a-validator/staking-mechanics/offenses-and-slashes.md (100%) rename {nodes-and-validators => node-infrastructure}/run-a-validator/staking-mechanics/rewards.md (100%) diff --git a/.ai/pages/node-infrastructure-run-a-collator-collator.md b/.ai/pages/node-infrastructure-run-a-collator-collator.md new file mode 100644 index 000000000..18babcfa8 --- /dev/null +++ b/.ai/pages/node-infrastructure-run-a-collator-collator.md @@ -0,0 +1,560 @@ +--- +title: Run a Block-Producing Collator +description: Learn how to set up and run a block-producing collator for Polkadot system parachains, including registration and session key management. +categories: Infrastructure +url: https://docs.polkadot.com/node-infrastructure/run-a-collator/collator/ +--- + +# Run a Block-Producing Collator + +## Overview + +Block-producing collators are the backbone of system parachain operations. Unlike RPC nodes or archive nodes that simply maintain state, collators actively produce blocks and submit them to relay chain validators for inclusion. + +This guide covers setting up a **block-producing collator** for Polkadot system parachains. Running a collator requires: + +- Meeting hardware requirements for reliable block production +- Setting up and registering session keys +- Obtaining governance approval or meeting selection criteria +- Maintaining high uptime and performance + +**Important**: System parachain collators typically require governance approval or being added to the invulnerables list. This is different from non-system parachains where collator selection may be more permissionless. + +## Collator Responsibilities + +Block-producing collators perform critical functions: + +- **Maintain full nodes**: Both relay chain and parachain +- **Collect transactions**: Aggregate user transactions into blocks +- **Produce blocks**: Create parachain block candidates +- **Generate proofs**: Produce state transition proofs (Proof-of-Validity) +- **Submit to validators**: Send block candidates to relay chain validators +- **Facilitate XCM**: Enable cross-chain message passing + +Unlike relay chain validators, collators do not provide security guarantees—that responsibility lies with relay chain validators through the ELVES protocol. However, collators are essential for network liveness and censorship resistance. + +## Prerequisites + +### Hardware Requirements + +Block-producing collators require robust hardware for reliable operation: + +- **CPU**: 4+ cores (8+ cores recommended for optimal performance) +- **Memory**: 32 GB RAM minimum (64 GB recommended) +- **Storage**: + - 500 GB+ NVMe SSD for parachain data + - Additional 200+ GB for relay chain pruned database + - Fast disk I/O is critical for block production performance +- **Network**: + - Public IP address (required) + - 100+ Mbps connection (stable connection critical) + - Open ports: + - 30333 (parachain P2P) + - 30334 (relay chain P2P) + - 9944 (WebSocket RPC - for management) + +**Note**: Uptime is critical. Consider redundancy and monitoring to maintain block production reliability. + +### Software Requirements + +Collators use the **Polkadot Omni Node**, a universal binary that runs any parachain using a chain specification file. + +Required software: + +- **Operating System**: Ubuntu 22.04 LTS (recommended) or similar Linux distribution +- **Docker**: For running subkey utility +- **Rust Toolchain**: Version 1.86 or as specified by the runtime +- **Dependencies**: + ```bash + sudo apt update + sudo apt install -y build-essential git clang curl libssl-dev llvm libudev-dev make protobuf-compiler + ``` + +### Account Requirements + +You'll need: +- **Funded account**: For on-chain transactions and potential bonding +- **Session keys**: For collator identification (generated after node setup) +- **Node key**: For stable P2P peer ID (recommended) + +## Installation + +### Step 1: Install Rust and Required Toolchain + +```bash +# Install Rust +curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh +source $HOME/.cargo/env + +# Install specific Rust version +rustup install 1.86 +rustup default 1.86 +rustup target add wasm32-unknown-unknown --toolchain 1.86 +rustup component add rust-src --toolchain 1.86 +``` + +### Step 2: Install the Polkadot Omni Node + +```bash +# Install polkadot-omni-node +cargo install --locked polkadot-omni-node@0.5.0 + +# Verify installation +polkadot-omni-node --version +``` + +### Step 3: Generate Node Key + +Generate a stable node key for consistent peer ID: + +```bash +# Create directory for node data +sudo mkdir -p /var/lib/polkadot-collator + +# Generate node key using Docker +docker run -it parity/subkey:latest generate-node-key > /var/lib/polkadot-collator/node.key + +# The output displays your peer ID +# Example: 12D3KooWExcVYu7Mvjd4kxPVLwN2ZPnZ5NyLZ5ft477wqzfP2q6E +``` + +Save the peer ID for future reference. + +### Step 4: Generate Account Key + +Generate an account for on-chain transactions: + +```bash +# Generate account key with sr25519 scheme +docker run -it parity/subkey:latest generate --scheme sr25519 +``` + +Save the output containing: +- Secret phrase (seed) - Keep this secure! +- Public key (hex) +- Account ID +- SS58 Address + +**Security**: Store the secret phrase securely. Never share it. Consider using a hardware wallet for production collators. + +### Step 5: Obtain Chain Specification + +Download the chain specification for your target system parachain: + +**Option 1: Download from Chainspec Collection (Recommended)** + +1. Visit the [Chainspec Collection website](https://paritytech.github.io/chainspecs/) +2. Find your target system parachain +3. Download the chain specification JSON file +4. Save it as `chain-spec.json` + +**Option 2: Build from Runtime** + +```bash +# Clone the runtimes repository +git clone https://github.com/polkadot-fellows/runtimes.git +cd runtimes + +# Build the desired runtime (example for Polkadot Hub) +cargo build --release -p asset-hub-polkadot-runtime + +# Install chain-spec-builder +cargo install --locked staging-chain-spec-builder@10.0.0 + +# Generate chain spec +chain-spec-builder create \ + --relay-chain polkadot \ + --para-id 1000 \ + --runtime target/release/wbuild/asset-hub-polkadot-runtime/asset_hub_polkadot_runtime.compact.compressed.wasm \ + named-preset production > chain-spec.json +``` + +**System Parachain Para IDs:** +- Polkadot Hub: 1000 +- Bridge Hub: 1002 +- People Chain: 1004 +- Coretime Chain: 1005 + +### Step 6: Create User and Directory Structure + +```bash +# Create dedicated user +sudo useradd -r -s /bin/bash polkadot + +# Copy chain spec to directory +sudo cp chain-spec.json /var/lib/polkadot-collator/ + +# Set permissions +sudo chown -R polkadot:polkadot /var/lib/polkadot-collator +``` + +## Configuration + +### Create Systemd Service File + +Create a service file for your collator: + +```bash +sudo nano /etc/systemd/system/polkadot-collator.service +``` + +Add the following configuration: + +```ini +[Unit] +Description=Polkadot System Parachain Collator +After=network.target + +[Service] +Type=simple +User=polkadot +Group=polkadot +WorkingDirectory=/var/lib/polkadot-collator + +# Block-Producing Collator Configuration +ExecStart=/usr/local/bin/polkadot-omni-node \ + --collator \ + --chain=/var/lib/polkadot-collator/chain-spec.json \ + --base-path=/var/lib/polkadot-collator \ + --port=30333 \ + --rpc-port=9944 \ + --prometheus-port=9615 \ + --node-key-file=/var/lib/polkadot-collator/node.key \ + --name="YourCollatorName" \ + -- \ + --execution=wasm \ + --chain=polkadot \ + --port=30334 \ + --sync=warp + +Restart=always +RestartSec=10 +LimitNOFILE=65536 + +[Install] +WantedBy=multi-user.target +``` + +**Configuration Notes**: +- `--collator`: Enables block production mode +- `--node-key-file`: Uses the generated node key for stable peer ID +- `--name`: Your collator name (visible in telemetry) +- Relay chain uses `--sync=warp` for faster initial sync + +## Running the Collator + +### Step 1: Start the Service + +```bash +# Reload systemd +sudo systemctl daemon-reload + +# Enable service to start on boot +sudo systemctl enable polkadot-collator + +# Start the service +sudo systemctl start polkadot-collator + +# Check status +sudo systemctl status polkadot-collator + +# View logs +sudo journalctl -u polkadot-collator -f +``` + +### Step 2: Initial Sync + +Your collator must sync both the relay chain and parachain before producing blocks. + +Sync time depends on: +- Network bandwidth +- Disk I/O speed +- Current chain size + +The relay chain uses warp sync for faster synchronization. + +Monitor sync progress: +```bash +# Check logs for sync status +sudo journalctl -u polkadot-collator -f | grep "Syncing" + +# Wait for messages indicating full sync +# Example: "Idle" or "Imported" messages for both chains +``` + +**Important**: Do not proceed with registration until both chains are fully synced. + +### Step 3: Generate Session Keys + +Once your node is fully synced, generate session keys: + +```bash +# Generate session keys via RPC +curl -H "Content-Type: application/json" \ + -d '{"id":1, "jsonrpc":"2.0", "method": "author_rotateKeys", "params":[]}' \ + http://localhost:9944 + +# Returns session keys as a hex string +# Example: "0x1234567890abcdef..." +``` + +**Save the session keys** - you'll need them for on-chain registration. + +**Note**: Session keys are stored in the node's database. If you wipe the database, you'll need to generate new keys. + +## Registration and Governance + +### Understanding Collator Selection + +System parachains use different collator selection mechanisms: + +**Invulnerables List**: +- Fixed list of collators approved through governance +- Most common for system parachains +- Requires governance proposal and approval + +**On-chain Selection**: +- Some parachains use pallet-collator-selection +- May require bonding tokens +- Automatic selection based on criteria + +**Fellowship Decisions**: +- Technical Fellowship may manage some system parachain collators +- Requires Fellowship membership or approval + +### Registration Process + +The registration process varies by system parachain. General steps: + +#### 1. Check Current Collators + +Check the existing collators for your target parachain: + +```bash +# Using Polkadot.js Apps +# Connect to your target system parachain +# Go to Developer > Chain State +# Query: collatorSelection.invulnerables() or similar +``` + +#### 2. Prepare Governance Proposal + +For invulnerables-based selection: + +1. **Draft proposal**: Explain why you should be added as a collator +2. **Technical details**: Provide your session keys and account ID +3. **Infrastructure**: Describe your hardware and monitoring setup +4. **Experience**: Detail your relevant experience + +Submit to: +- Polkadot Forum: https://forum.polkadot.network +- Relevant governance channels + +#### 3. Set Session Keys On-Chain + +Once approved (or if using on-chain selection), set your session keys: + +**Using Polkadot.js Apps:** + +1. Navigate to Polkadot.js Apps and connect to your system parachain +2. Go to **Developer > Extrinsics** +3. Select your account +4. Choose `session.setKeys` extrinsic +5. Enter: + - `keys`: Your session keys (from `author_rotateKeys`) + - `proof`: 0x00 (typically) +6. Submit and sign the transaction + +**Using CLI (alternative):** + +```bash +# This varies by parachain - consult specific documentation +``` + +#### 4. Bond Tokens (if required) + +Some parachains require bonding tokens: + +1. Go to **Developer > Extrinsics** +2. Select `collatorSelection.registerAsCandidate` (if available) +3. Submit with required bond amount +4. Sign transaction + +#### 5. Await Governance Approval + +If using invulnerables: +- Wait for governance vote +- Monitor forum and announcements +- Once approved, you'll be added to the invulnerables list +- Your collator will begin producing blocks in the next session/era + +### Verify Collator Status + +Check if your collator is active: + +```bash +# Monitor logs for block production +sudo journalctl -u polkadot-collator -f | grep -i "imported" + +# Look for messages like: +# "Prepared block for proposing" +# "Imported #123" +``` + +## Monitoring and Maintenance + +### Essential Monitoring + +**Block Production**: +```bash +# Monitor block production +sudo journalctl -u polkadot-collator | grep -i "prepared block" +``` + +**Peer Connections**: +- Maintain 30+ peers for good connectivity +- Check peer count in logs + +**Resource Usage**: +- Monitor CPU, RAM, and disk I/O +- Set up alerts for high usage + +**Sync Status**: +- Ensure both chains stay synced +- Alert on sync issues + +### Prometheus Metrics + +Metrics available at `http://localhost:9615/metrics` + +Example Prometheus configuration: +{% raw %} +```yaml +scrape_configs: + - job_name: 'polkadot-collator' + static_configs: + - targets: ['localhost:9615'] +``` +{% endraw %} + +Key metrics to monitor: +- `substrate_block_height`: Current block height +- `substrate_finalized_height`: Finalized block height +- `substrate_peers_count`: Peer connections +- `substrate_ready_transactions_number`: Transaction queue + +### Setting Up Alerts + +Configure alerts for: +- Service failures +- Sync issues +- Low peer count (< 10 peers) +- Block production gaps +- High resource usage +- Disk space low + +### Log Management + +```bash +# View recent logs +sudo journalctl -u polkadot-collator -n 100 + +# Follow logs in real-time +sudo journalctl -u polkadot-collator -f + +# Filter for errors +sudo journalctl -u polkadot-collator | grep -i error + +# Filter for block production +sudo journalctl -u polkadot-collator | grep -i "imported" +``` + +### Database Maintenance + +Check database size: +```bash +# Check database size +du -sh /var/lib/polkadot-collator +``` + +The node handles pruning automatically. + +### Updates and Upgrades + +**Runtime Upgrades**: +- Automatic via on-chain governance +- No manual action required +- Monitor announcements for breaking changes + +**Client Upgrades**: +- Require manual binary update +- Subscribe to announcements: + - Polkadot Forum + - Fellowship GitHub + - Matrix channels + +**Upgrade Procedure**: + +```bash +# Stop the service +sudo systemctl stop polkadot-collator + +# Backup data (recommended) +sudo cp -r /var/lib/polkadot-collator /var/lib/polkadot-collator.backup + +# Update polkadot-omni-node +cargo install --locked --force polkadot-omni-node@ + +# Verify version +polkadot-omni-node --version + +# Restart service +sudo systemctl start polkadot-collator + +# Monitor logs +sudo journalctl -u polkadot-collator -f +``` + +## Security Best Practices + +### Key Management + +- **Secure storage**: Store session keys and account keys securely +- **Never share**: Never share private keys or secret phrases +- **Hardware wallets**: Consider HSM for production +- **Backup**: Keep encrypted backups of keys +- **Rotation**: Plan for key rotation procedures + +### Network Security + +- **Firewall**: Restrict access to necessary ports only +- **SSH**: Use SSH keys, disable password auth +- **VPN**: Consider VPN for administrative access +- **DDoS protection**: Implement if running in cloud + +### System Security + +- **Updates**: Keep OS and software updated +- **Dedicated user**: Never run as root +- **Fail2ban**: Enable for SSH protection +- **Audits**: Regular security audits +- **Minimal services**: Disable unnecessary services + +### Operational Security + +- **Monitoring**: 24/7 monitoring with alerts +- **Backups**: Regular configuration backups +- **Documentation**: Document procedures +- **Incident response**: Have incident response plan +- **Redundancy**: Consider backup collator (standby) + +## Conclusion + +Running a collator node is essential for parachain operation and network security. By following this guide, you have set up a production-ready collator that: + +- Produces blocks for your parachain and maintains network consensus +- Implements comprehensive security measures to protect keys and operations +- Supports robust monitoring and alerting for reliable performance +- Follows best practices for both Docker and systemd deployments + +As a collator operator, you play a vital role in your parachain's infrastructure. Regular maintenance, security updates, and monitoring will ensure your collator continues to perform reliably. Stay engaged with your parachain community and keep up with updates to maintain optimal performance and security. diff --git a/.ai/pages/node-infrastructure-run-a-node-polkadot-hub-rpc.md b/.ai/pages/node-infrastructure-run-a-node-polkadot-hub-rpc.md new file mode 100644 index 000000000..7282f2ef0 --- /dev/null +++ b/.ai/pages/node-infrastructure-run-a-node-polkadot-hub-rpc.md @@ -0,0 +1,622 @@ +--- +title: Run an RPC Node for Polkadot Hub +description: Complete guide to set up and run an RPC node for Polkadot Hub with Polkadot SDK RPC endpoints. +categories: Infrastructure +url: https://docs.polkadot.com/node-infrastructure/run-a-node/polkadot-hub-rpc/ +--- + +# Run an RPC Node for Polkadot Hub + +## Overview + +[Polkadot Hub](/reference/polkadot-hub/){target=\_blank} is the entry point to Polkadot for all users and application developers. It provides access to essential Web3 services, including: + +- **Asset Management**: Native support for fungible and non-fungible assets +- **Governance, Staking, and Treasury**: Core protocol operations +- **Cross-chain Communication**: XCM message handling + +Running an RPC node for Polkadot Hub enables applications, wallets, and users to interact with the parachain through: +- **Polkadot SDK Node RPC** (Port 9944): Native Polkadot API (WebSocket and HTTP) + +This setup enables block explorer indexing and provides full compatibility with Polkadot SDK development tools. + +**Important Note**: The parameters and configurations in this guide are provided as illustrative examples. You may need to modify them according to your specific environment, hardware capabilities, and network conditions. + +## Prerequisites + +### Hardware Requirements + +RPC nodes serving production traffic require robust hardware: + +- **CPU**: 8+ cores (16+ cores for high traffic) +- **Memory**: 64 GB RAM minimum (128 GB recommended for high traffic) +- **Storage**: + - 500 GB+ NVMe SSD for parachain state (archive nodes require 2-4 TB+) + - Additional 200+ GB for relay chain pruned database + - Fast disk I/O is critical for query performance +- **Network**: + - Public IP address + - 1 Gbps connection (for high traffic scenarios) + - Stable internet connection with sufficient bandwidth + - Open ports: + - 30333 (parachain P2P) + - 30334 (relay chain P2P) + - 9944 (Polkadot SDK WebSocket RPC) + - 9933 (Polkadot SDK HTTP RPC) + - 9615 (Prometheus metrics - optional) + - Consider DDoS protection and rate limiting for production deployments + +**Note**: For development or low-traffic scenarios, you can reduce these requirements proportionally. Consider using a reverse proxy (nginx, Caddy) for production deployments. + +### Software Requirements + +Required software: + +- **Operating System**: Ubuntu 22.04 LTS (recommended) or similar Linux distribution +- **Docker**: Latest version installed and running (for Docker-based setup) +- **rclone**: (Optional but recommended) Command-line program for managing files on cloud storage (https://rclone.org/downloads/) +- **Rust Toolchain**: Version 1.86 or as specified by runtime (for manual build) + +## Setup Options + +This guide provides two deployment options: + +1. **Docker-based Setup**: Simpler to set up and maintain +2. **Manual/Systemd Setup**: For production environments requiring more control + +Choose the option that best fits your needs. + +--- + +## Option 1: Docker-Based Setup + +This option uses Docker containers for the Polkadot SDK node, making it easy to set up and manage. + +### Step 1: Download Chain Specification + +Download the official Polkadot Hub (formerly known as Asset Hub) chain specification: + +```bash +curl -L https://raw.githubusercontent.com/paritytech/polkadot-sdk/master/cumulus/parachains/chain-specs/asset-hub-polkadot.json -o asset-hub-polkadot.json +``` + +**Note**: This chain specification is the official configuration file that defines the network parameters for Polkadot Hub. + +### Step 2: Download Database Snapshots (Optional but Recommended) + +Using pre-synchronized snapshots significantly reduces initial sync time from several days to just a few hours. You need to download both parachain and relay chain data. + +**Snapshot Provider**: https://snapshots.polkadot.io/ + +#### Create Directories + +```bash +mkdir -p my-node-data/chains/asset-hub-polkadot/db +mkdir -p my-node-data/chains/polkadot/db +``` + +#### Download Polkadot Hub Parachain Snapshot + +Choose between archive (complete history) or pruned (recent state) snapshots: + +**Archive Snapshot** (recommended for RPC with historical data): + +```bash +# Check https://snapshots.polkadot.io/ for the latest snapshot URL +export SNAPSHOT_URL_ASSET_HUB="https://snapshots.polkadot.io/polkadot-asset-hub-rocksdb-archive/LATEST" + +rclone copyurl $SNAPSHOT_URL_ASSET_HUB/files.txt files.txt +rclone copy --progress --transfers 20 \ + --http-url $SNAPSHOT_URL_ASSET_HUB \ + --no-traverse --http-no-head --disable-http2 \ + --inplace --no-gzip-encoding --size-only \ + --retries 6 --retries-sleep 10s \ + --files-from files.txt :http: my-node-data/chains/asset-hub-polkadot/db/ + +rm files.txt +``` + +**Parameter Explanation**: +- `--transfers 20`: Uses 20 parallel transfers for faster download +- `--retries 6`: Automatically retries failed transfers up to 6 times +- `--retries-sleep 10s`: Waits 10 seconds between retry attempts +- `--size-only`: Only transfers if sizes differ (prevents unnecessary re-downloads) + +#### Download Polkadot Relay Chain Snapshot + +**Pruned Snapshot** (recommended for RPC nodes): + +```bash +# Check https://snapshots.polkadot.io/ for the latest snapshot URL +export SNAPSHOT_URL_RELAY="https://snapshots.polkadot.io/polkadot-rocksdb-prune/LATEST" + +rclone copyurl $SNAPSHOT_URL_RELAY/files.txt files.txt +rclone copy --progress --transfers 20 \ + --http-url $SNAPSHOT_URL_RELAY \ + --no-traverse --http-no-head --disable-http2 \ + --inplace --no-gzip-encoding --size-only \ + --retries 6 --retries-sleep 10s \ + --files-from files.txt :http: my-node-data/chains/polkadot/db/ + +rm files.txt +``` + +**Alternative Options**: +- Pruned snapshot: `polkadot-rocksdb-prune` (smaller size, recent state) +- Archive snapshot: `polkadot-rocksdb-archive` (complete history, larger size) + +### Step 3: Start Polkadot Hub Node + +Launch the node using the official Parity Docker image: + +**Docker Image**: https://hub.docker.com/r/parity/polkadot-omni-node + +```bash +docker run -d --name polkadot-hub-rpc --restart unless-stopped \ + -p 9944:9944 \ + -p 9933:9933 \ + -p 9615:9615 \ + -p 30334:30334 \ + -p 30333:30333 \ + -v $(pwd)/asset-hub-polkadot.json:/asset-hub-polkadot.json \ + -v $(pwd)/my-node-data:/data \ + parity/polkadot-omni-node:stable2506-4 \ + --name=PolkadotHubRPC \ + --base-path=/data \ + --chain=/asset-hub-polkadot.json \ + --prometheus-external \ + --prometheus-port 9615 \ + --unsafe-rpc-external \ + --rpc-port=9944 \ + --rpc-cors=all \ + --rpc-methods=safe \ + --rpc-max-connections=1000 \ + --state-pruning=archive \ + --blocks-pruning=archive \ + -- \ + --base-path=/data \ + --chain=polkadot \ + --state-pruning=256 \ + --blocks-pruning=archive-canonical +``` + +**Critical Configuration Parameters**: + +**Port Mappings**: +- `9944`: Polkadot SDK RPC endpoint (WebSocket/HTTP) +- `9933`: Polkadot SDK HTTP RPC endpoint +- `9615`: Prometheus metrics endpoint +- `30333/30334`: P2P networking ports + +**Node Parameters**: +- `--unsafe-rpc-external`: Enables external RPC access +- `--rpc-cors=all`: Allows all origins for CORS +- `--rpc-methods=safe`: Only allows safe RPC methods +- `--state-pruning=archive`: Keeps complete state history +- `--blocks-pruning=archive`: Keeps all block data +- `--prometheus-external`: Exposes metrics externally + +**Security Warning**: The `--unsafe-rpc-external` flag should only be used in development or properly secured environments. For production, use a reverse proxy with authentication. + +### Step 4: Monitor Synchronization + +Monitor the node synchronization status: + +```bash +# Check sync status +curl -H "Content-Type: application/json" \ + -d '{"id":1, "jsonrpc":"2.0", "method": "system_syncState", "params":[]}' \ + http://localhost:9944 +``` + +**Expected Response Format**: + +```json +{ + "jsonrpc":"2.0", + "id":1, + "result":{ + "startingBlock":0, + "currentBlock":3394816, + "highestBlock":3394816 + } +} +``` + +**Synchronization Status**: +- **In Progress**: `currentBlock` < `highestBlock` +- **Complete**: `currentBlock` = `highestBlock` + +**Monitor logs**: + +```bash +# View node logs +docker logs -f polkadot-hub-rpc + +# Filter for sync messages +docker logs polkadot-hub-rpc 2>&1 | grep -i "syncing" +``` + +### Step 5: Verify Setup + +Let's verify the Polkadot SDK RPC endpoint is working correctly. + +#### API Endpoint + +**Polkadot SDK RPC (Port 9944)**: +- WebSocket: `ws://your-server:9944` +- HTTP: `http://your-server:9944` +- Purpose: Full Polkadot SDK API access for parachain data +- Use Cases: Polkadot SDK applications, parachain-specific operations + +#### Polkadot SDK RPC Tests + +**Get Chain Information**: + +```bash +curl -H "Content-Type: application/json" \ + -d '{"id":1, "jsonrpc":"2.0", "method": "system_chain", "params":[]}' \ + http://localhost:9944 +``` + +**Get Latest Block**: + +```bash +curl -H "Content-Type: application/json" \ + -d '{"id":1, "jsonrpc":"2.0", "method": "chain_getHeader", "params":[]}' \ + http://localhost:9944 +``` + +**Get Node Health**: + +```bash +curl -H "Content-Type: application/json" \ + -d '{"id":1, "jsonrpc":"2.0", "method": "system_health", "params":[]}' \ + http://localhost:9944 +``` + +### Managing Docker Containers + +**View logs**: + +```bash +# View node logs +docker logs -f polkadot-hub-rpc +``` + +**Stop container**: + +```bash +docker stop polkadot-hub-rpc +``` + +**Start container**: + +```bash +docker start polkadot-hub-rpc +``` + +**Remove container**: + +```bash +docker rm polkadot-hub-rpc +``` + +**Update container**: + +```bash +# Pull latest image +docker pull parity/polkadot-omni-node:stable2506-4 + +# Stop and remove old container +docker stop polkadot-hub-rpc +docker rm polkadot-hub-rpc + +# Start new container with same command as above +``` + +--- + +## Option 2: Manual/Systemd Setup + +This option provides more control and is recommended for production environments requiring custom configurations. + +### Step 1: Install Rust and Required Toolchain + +```bash +# Install Rust +curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh +source $HOME/.cargo/env + +# Install specific Rust version +rustup install 1.86 +rustup default 1.86 +rustup target add wasm32-unknown-unknown --toolchain 1.86 +rustup component add rust-src --toolchain 1.86 +``` + +### Step 2: Install the Polkadot Omni Node + +```bash +# Install polkadot-omni-node +cargo install --locked polkadot-omni-node@0.7.0 + +# Verify installation +polkadot-omni-node --version +``` + +### Step 3: Obtain Chain Specification + +Download the Polkadot Hub chain specification: + +```bash +curl -L https://raw.githubusercontent.com/paritytech/polkadot-sdk/master/cumulus/parachains/chain-specs/asset-hub-polkadot.json -o asset-hub-polkadot.json +``` + +### Step 4: Create User and Directory Structure + +```bash +# Create dedicated user +sudo useradd -r -s /bin/bash polkadot + +# Create data directory +sudo mkdir -p /var/lib/polkadot-hub-rpc + +# Copy chain spec to the directory +sudo cp asset-hub-polkadot.json /var/lib/polkadot-hub-rpc/ + +# Set permissions +sudo chown -R polkadot:polkadot /var/lib/polkadot-hub-rpc +``` + +### Step 5: Create Systemd Service for Polkadot SDK Node + +Create a service file for the Polkadot SDK RPC node: + +```bash +sudo nano /etc/systemd/system/polkadot-hub-rpc.service +``` + +Add the following configuration: + +```ini +[Unit] +Description=Polkadot Hub RPC Node +After=network.target + +[Service] +Type=simple +User=polkadot +Group=polkadot +WorkingDirectory=/var/lib/polkadot-hub-rpc + +ExecStart=/usr/local/bin/polkadot-omni-node \ + --name=PolkadotHubRPC \ + --chain=/var/lib/polkadot-hub-rpc/asset-hub-polkadot.json \ + --base-path=/var/lib/polkadot-hub-rpc \ + --port=30333 \ + --rpc-port=9944 \ + --rpc-external \ + --rpc-cors=all \ + --rpc-methods=safe \ + --rpc-max-connections=1000 \ + --prometheus-port=9615 \ + --prometheus-external \ + --state-pruning=archive \ + --blocks-pruning=archive \ + -- \ + --chain=polkadot \ + --base-path=/var/lib/polkadot-hub-rpc \ + --port=30334 \ + --state-pruning=256 \ + --blocks-pruning=archive-canonical + +Restart=always +RestartSec=10 +LimitNOFILE=65536 + +[Install] +WantedBy=multi-user.target +``` + +### Step 6: Start Service + +```bash +# Reload systemd +sudo systemctl daemon-reload + +# Enable service to start on boot +sudo systemctl enable polkadot-hub-rpc + +# Start the Polkadot SDK node +sudo systemctl start polkadot-hub-rpc + +# Check status and wait for sync +sudo systemctl status polkadot-hub-rpc +sudo journalctl -u polkadot-hub-rpc -f +``` + +### Step 7: Verify Setup + +Use the same verification tests as in the Docker setup (see Step 5 above). + +--- + +## Monitoring and Maintenance + +### Log Management + +**Docker Setup**: + +```bash +# View node logs +docker logs -f polkadot-hub-rpc +``` + +**Systemd Setup**: + +```bash +# View node logs +sudo journalctl -u polkadot-hub-rpc -f + +# View recent logs +sudo journalctl -u polkadot-hub-rpc -n 100 + +# Filter for errors +sudo journalctl -u polkadot-hub-rpc | grep -i error +``` + +### Performance Monitoring + +Monitor key metrics: +- **Sync status**: Ensure node stays fully synced +- **Peer connections**: Maintain 30+ peers for good connectivity +- **Resource usage**: Monitor CPU, RAM, and disk I/O +- **RPC request latency**: Track response times for the Polkadot SDK API +- **Connection count**: Monitor active RPC connections + +**Prometheus Metrics**: + +Metrics are available at `http://localhost:9615/metrics` + +Example Prometheus scrape configuration: + +{% raw %} +```yaml +scrape_configs: + - job_name: 'polkadot-hub-rpc' + static_configs: + - targets: ['localhost:9615'] +``` +{% endraw %} + +**Key Metrics to Monitor**: +- `substrate_block_height`: Current block height +- `substrate_finalized_height`: Finalized block height +- `substrate_peers_count`: Number of connected peers +- `substrate_ready_transactions_number`: Transaction queue size + +### Database Maintenance + +Check database size periodically: + +```bash +# Docker setup +du -sh my-node-data + +# Systemd setup +du -sh /var/lib/polkadot-hub-rpc +``` + +The node handles pruning automatically based on configuration unless running in archive mode. + +### Updates and Upgrades + +**Docker Setup**: + +```bash +# Pull latest image +docker pull parity/polkadot-omni-node:stable2506-4 + +# Restart container +docker stop polkadot-hub-rpc +docker rm polkadot-hub-rpc + +# Start new container (use same command from setup) +``` + +**Systemd Setup**: + +```bash +# Stop service +sudo systemctl stop polkadot-hub-rpc + +# Backup data +sudo cp -r /var/lib/polkadot-hub-rpc /var/lib/polkadot-hub-rpc.backup + +# Update binary +cargo install --locked --force polkadot-omni-node@ + +# Restart service +sudo systemctl start polkadot-hub-rpc +``` + +## Security Best Practices + +### Network Security + +1. **Firewall Configuration**: + - Only expose necessary ports + - Use UFW or iptables to restrict access + - Consider IP whitelisting for RPC endpoints + +2. **Reverse Proxy** (Recommended for Production): + - Use nginx or Caddy as reverse proxy + - Enable SSL/TLS (HTTPS/WSS) + - Implement authentication + - Add rate limiting + +Example nginx configuration: + +```nginx +upstream polkadot_sdk_rpc { + server 127.0.0.1:9944; +} + +server { + listen 443 ssl http2; + server_name your-domain.com; + + ssl_certificate /path/to/cert.pem; + ssl_certificate_key /path/to/key.pem; + + # Polkadot SDK RPC + location /polkadot { + proxy_pass http://polkadot_sdk_rpc; + proxy_http_version 1.1; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection "upgrade"; + + # Rate limiting + limit_req zone=rpc_limit burst=10; + } +} +``` + +### RPC Security + +- **Always use `--rpc-methods=safe`**: Prevents dangerous RPC calls +- **Restrict CORS**: Use specific domains instead of `all` in production +- **Set connection limits**: Prevent resource exhaustion +- **Monitor for abuse**: Track unusual patterns +- **Authentication**: Implement API keys or OAuth for production + +### System Security + +- Keep operating system updated +- Use dedicated user accounts (never root) +- Enable fail2ban for SSH protection +- Regular security audits +- Disable unnecessary services +- Use AppArmor or SELinux for additional isolation + +### Monitoring and Alerting + +Set up alerts for: +- Service failures +- Sync issues +- Low peer count (< 10 peers) +- High resource usage +- Unusual RPC traffic patterns +- Database errors + +## Conclusion + +Running an RPC node for Polkadot Hub provides essential infrastructure for applications and users to interact with the network. By following this guide, you have set up a production-ready RPC node that: + +- Provides reliable access to Polkadot Hub's asset management, governance, and cross-chain communication features +- Supports both Docker and systemd deployment options for flexibility +- Implements proper monitoring, security, and maintenance practices +- Serves as a foundation for building and operating Polkadot SDK applications + +Regular maintenance, security updates, and monitoring will ensure your RPC node continues to serve your users reliably. As the Polkadot network evolves, stay informed about updates and best practices through the official channels and community resources listed in this guide. diff --git a/.ai/pages/node-infrastructure-run-a-node-relay-chain-bootnode.md b/.ai/pages/node-infrastructure-run-a-node-relay-chain-bootnode.md new file mode 100644 index 000000000..8b91741f0 --- /dev/null +++ b/.ai/pages/node-infrastructure-run-a-node-relay-chain-bootnode.md @@ -0,0 +1,130 @@ +--- +title: Set Up a Bootnode +description: Learn how to configure and run a bootnode for Polkadot, including P2P, WS, and secure WSS connections with network key management and proxies. +categories: Infrastructure +url: https://docs.polkadot.com/node-infrastructure/run-a-node/relay-chain/bootnode/ +--- + +# Set Up a Bootnode + +## Introduction + +Bootnodes are essential for helping blockchain nodes discover peers and join the network. When a node starts, it needs to find other nodes, and bootnodes provide an initial point of contact. Once connected, a node can expand its peer connections and play its role in the network, like participating as a validator. + +This guide will walk you through setting up a Polkadot bootnode, configuring P2P, WebSocket (WS), secure WSS connections, and managing network keys. You'll also learn how to test your bootnode to ensure it is running correctly and accessible to other nodes. + +## Prerequisites + +Before you start, you need to have the following prerequisites: + +- Verify a working Polkadot (`polkadot`) binary is available on your machine. +- Ensure you have nginx installed. Please refer to the [Installation Guide](https://nginx.org/en/docs/install.html){target=\_blank} for help with installation if needed. +- A VPS or other dedicated server setup. + +## Accessing the Bootnode + +Bootnodes must be accessible through three key channels to connect with other nodes in the network: + +- **P2P**: A direct peer-to-peer connection, set by. + + ```bash + + --listen-addr /ip4/0.0.0.0/tcp/INSERT_PORT + + ``` + + This is not enabled by default on non-validator nodes like archive RPC nodes. + +- **P2P/WS**: A WebSocket (WS) connection, also configured via `--listen-addr`. +- **P2P/WSS**: A secure WebSocket (WSS) connection using SSL, often required for light clients. An SSL proxy is needed, as the node itself cannot handle certificates. + +## Node Key + +A node key is the ED25519 key used by `libp2p` to assign your node an identity or peer ID. Generating a known node key for a bootnode is crucial, as it gives you a consistent key that can be placed in chain specifications as a known, reliable bootnode. + +Starting a node creates its node key in the `chains/INSERT_CHAIN/network/secret_ed25519` file. + +You can create a node key using: + + ``` bash + polkadot key generate-node-key + ``` + +This key can be used in the startup command line. + +It is imperative that you backup the node key. If it is included in the `polkadot` binary, it is hardcoded into the binary, which must be recompiled to change the key. + +## Running the Bootnode + +A bootnode can be run as follows: + + ``` bash + polkadot --chain polkadot \ + --name dot-bootnode \ + --listen-addr /ip4/0.0.0.0/tcp/30310 \ + --listen-addr /ip4/0.0.0.0/tcp/30311/ws + ``` + +This assigns the p2p to port 30310 and p2p/ws to port 30311. For the p2p/wss port, a proxy must be set up with a DNS name and a corresponding certificate. The following example is for the popular nginx server and enables p2p/wss on port 30312 by adding a proxy to the p2p/ws port 30311: + +``` conf title="/etc/nginx/sites-enabled/dot-bootnode" +server { + listen 30312 ssl http2 default_server; + server_name dot-bootnode.stakeworld.io; + root /var/www/html; + + ssl_certificate "INSERT_YOUR_CERT"; + ssl_certificate_key "INSERT_YOUR_KEY"; + + location / { + proxy_buffers 16 4k; + proxy_buffer_size 2k; + proxy_pass http://localhost:30311; + proxy_http_version 1.1; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection "Upgrade"; + proxy_set_header Host $host; + } + +} +``` + +## Testing Bootnode Connection + +If the preceding node is running with DNS name `dot-bootnode.stakeworld.io`, which contains a proxy with a valid certificate and node-id `12D3KooWAb5MyC1UJiEQJk4Hg4B2Vi3AJdqSUhTGYUqSnEqCFMFg` then the following commands should output `syncing 1 peers`. + +!!!tip + You can add `-lsub-libp2p=trace` on the end to get libp2p trace logging for debugging purposes. + +### P2P + +```bash +polkadot --chain polkadot \ +--base-path /tmp/node \ +--name "Bootnode testnode" \ +--reserved-only \ +--reserved-nodes "/dns/dot-bootnode.stakeworld.io/tcp/30310/p2p/12D3KooWAb5MyC1UJiEQJk4Hg4B2Vi3AJdqSUhTGYUqSnEqCFMFg" \ +--no-hardware-benchmarks +``` + +### P2P/WS + +```bash +polkadot --chain polkadot \ +--base-path /tmp/node \ +--name "Bootnode testnode" \ +--reserved-only \ +--reserved-nodes "/dns/dot-bootnode.stakeworld.io/tcp/30311/ws/p2p/12D3KooWAb5MyC1UJiEQJk4Hg4B2Vi3AJdqSUhTGYUqSnEqCFMFg" \ +--no-hardware-benchmarks +``` + +### P2P/WSS + +```bash +polkadot --chain polkadot \ +--base-path /tmp/node \ +--name "Bootnode testnode" \ +--reserved-only \ +--reserved-nodes "/dns/dot-bootnode.stakeworld.io/tcp/30312/wss/p2p/12D3KooWAb5MyC1UJiEQJk4Hg4B2Vi3AJdqSUhTGYUqSnEqCFMFg" \ +--no-hardware-benchmarks +``` diff --git a/.ai/pages/node-infrastructure-run-a-node-relay-chain-full-node.md b/.ai/pages/node-infrastructure-run-a-node-relay-chain-full-node.md new file mode 100644 index 000000000..17f93a8f1 --- /dev/null +++ b/.ai/pages/node-infrastructure-run-a-node-relay-chain-full-node.md @@ -0,0 +1,338 @@ +--- +title: Set Up a Node +description: Learn how to install, configure, and run Polkadot nodes, including setting up different node types and connecting to the network. +categories: Infrastructure +url: https://docs.polkadot.com/node-infrastructure/run-a-node/relay-chain/full-node/ +--- + +# Set Up a Node + +## Introduction + +Running a node on Polkadot provides direct interaction with the network, enhanced privacy, and full control over RPC requests, transactions, and data queries. As the backbone of the network, nodes ensure decentralized data propagation, transaction validation, and seamless communication across the ecosystem. + +Polkadot supports multiple node types, including pruned, archive, and light nodes, each suited to specific use cases. During setup, you can use configuration flags to choose the node type you wish to run. + +This guide walks you through configuring, securing, and maintaining a node on Polkadot or any Polkadot SDK-based chain. It covers instructions for the different node types and how to safely expose your node's RPC server for external access. Whether you're building a local development environment, powering dApps, or supporting network decentralization, this guide provides all the essentials. + +## Set Up a Node + +Now that you're familiar with the different types of nodes, this section will walk you through configuring, securing, and maintaining a node on Polkadot or any Polkadot SDK-based chain. + +### Prerequisites + +Before getting started, ensure the following prerequisites are met: + +- Ensure [Rust](https://www.rust-lang.org/tools/install){target=\_blank} is installed on your operating system. +- [Install the necessary dependencies for the Polkadot SDK](/parachains/install-polkadot-sdk/){target=\_blank}. + +!!! warning + This setup is not recommended for validators. If you plan to run a validator, refer to the [Running a Validator](/nodes-and-validators/run-a-validator/onboarding-and-offboarding/set-up-validator/){target=\_blank} guide for proper instructions. + +### Install and Build the Polkadot Binary + +This section will walk you through installing and building the Polkadot binary for different operating systems and methods. + +??? interface "macOS" + + To get started, update and configure the Rust toolchain by running the following commands: + + ```bash + source ~/.cargo/env + + rustup default stable + rustup update + + rustup update nightly + rustup target add wasm32-unknown-unknown --toolchain nightly + rustup component add rust-src --toolchain stable-aarch64-apple-darwin + ``` + + You can verify your installation by running: + + ```bash + rustup show + rustup +nightly show + ``` + + You should see output similar to the following: + +
+ rustup show
+ rustup +nightly show
+ active toolchain + ---------------- + + stable-aarch64-apple-darwin (default) + rustc 1.82.0 (f6e511eec 2024-10-15) + + active toolchain + ---------------- + + nightly-aarch64-apple-darwin (overridden by +toolchain on the command line) + rustc 1.84.0-nightly (03ee48451 2024-11-18) + +
+ + Then, run the following commands to clone and build the Polkadot binary: + + ```bash + git clone https://github.com/paritytech/polkadot-sdk polkadot-sdk + cd polkadot-sdk + cargo build --release + ``` + + Depending upon the specs of your machine, compiling the binary may take an hour or more. After building the Polkadot node from source, the executable binary will be located in the `./target/release/polkadot` directory. + +??? interface "Windows" + + To get started, make sure that you have [WSL and Ubuntu](https://learn.microsoft.com/en-us/windows/wsl/install){target=\_blank} installed on your Windows machine. + + Once installed, you have a couple options for installing the Polkadot binary: + + - If Rust is installed, then `cargo` can be used similar to the macOS instructions. + - Or, the instructions in the Linux section can be used. + +??? interface "Linux (pre-built binary)" + + To grab the [latest release of the Polkadot binary](https://github.com/paritytech/polkadot-sdk/releases){target=\_blank}, you can use `wget`: + + ```bash + wget https://github.com/paritytech/polkadot-sdk/releases/download/polkadot-INSERT_VERSION/polkadot + ``` + + Ensure you note the executable binary's location, as you'll need to use it when running the start-up command. If you prefer, you can specify the output location of the executable binary with the `-O` flag, for example: + + ```bash + wget https://github.com/paritytech/polkadot-sdk/releases/download/polkadot-INSERT_VERSION/polkadot \ + - O /var/lib/polkadot-data/polkadot + ``` + + !!!tip + The nature of pre-built binaries means that they may not work on your particular architecture or Linux distribution. If you see an error like `cannot execute binary file: Exec format error` it likely means the binary is incompatible with your system. You will either need to compile the binary or use [Docker](#use-docker). + + Ensure that you properly configure the permissions to make the Polkadot release binary executable: + + ```bash + sudo chmod +x polkadot + ``` + +??? interface "Linux (compile binary)" + + The most reliable (although perhaps not the fastest) way of launching a full node is to compile the binary yourself. Depending on your machine's specs, this may take an hour or more. + + To get started, run the following commands to configure the Rust toolchain: + + ```bash + rustup default stable + rustup update + rustup update nightly + rustup target add wasm32-unknown-unknown --toolchain nightly + rustup target add wasm32-unknown-unknown --toolchain stable-x86_64-unknown-linux-gnu + rustup component add rust-src --toolchain stable-x86_64-unknown-linux-gnu + ``` + + You can verify your installation by running: + + ```bash + rustup show + ``` + + You should see output similar to the following: + +
+ rustup show
+ rustup +nightly show
+ active toolchain + ---------------- + + stable-x86_64-unknown-linux-gnu (default) + rustc 1.82.0 (f6e511eec 2024-10-15) +
+ + Once Rust is configured, run the following commands to clone and build Polkadot: + + ```bash + git clone https://github.com/paritytech/polkadot-sdk polkadot-sdk + cd polkadot-sdk + cargo build --release + ``` + + Compiling the binary may take an hour or more, depending on your machine's specs. After building the Polkadot node from the source, the executable binary will be located in the `./target/release/polkadot` directory. + +??? interface "Linux (snap package)" + + Polkadot can be installed as a [snap package](https://snapcraft.io/polkadot){target=\_blank}. If you don't already have Snap installed, take the following steps to install it: + + ```bash + sudo apt update + sudo apt install snapd + ``` + + Install the Polkadot snap package: + + ```bash + sudo snap install polkadot + ``` + + Before continuing on with the following instructions, check out the [Configure and Run Your Node](#configure-and-run-your-node) section to learn more about the configuration options. + + To configure your Polkadot node with your desired options, you'll run a command similar to the following: + + ```bash + sudo snap set polkadot service-args="--name=MyName --chain=polkadot" + ``` + + Then to start the node service, run: + + ```bash + sudo snap start polkadot + ``` + + You can review the logs to check on the status of the node: + + ```bash + snap logs polkadot -f + ``` + + And at any time, you can stop the node service: + + ```bash + sudo snap stop polkadot + ``` + + You can optionally prevent the service from stopping when snap is updated with the following command: + + ```bash + sudo snap set polkadot endure=true + ``` + +### Use Docker + +As an additional option, you can use Docker to run your node in a container. Doing this is more advanced, so it's best left up to those already familiar with Docker or who have completed the other set-up instructions in this guide. You can review the latest versions on [DockerHub](https://hub.docker.com/r/parity/polkadot/tags){target=\_blank}. + +Be aware that when you run Polkadot in Docker, the process only listens on `localhost` by default. If you would like to connect to your node's services (RPC and Prometheus) you need to ensure that you run the node with the `--rpc-external`, and `--prometheus-external` commands. + +```bash +docker run -p 9944:9944 -p 9615:9615 parity/polkadot:v1.16.2 --name "my-polkadot-node-calling-home" --rpc-external --prometheus-external +``` + +If you're running Docker on an Apple Silicon machine (e.g. M4), you'll need to adapt the command slightly: + +```bash +docker run --platform linux/amd64 -p 9944:9944 -p 9615:9615 parity/polkadot:v1.16.2 --name "kearsarge-calling-home" --rpc-external --prometheus-external +``` + +## Configure and Run Your Node + +Now that you've installed and built the Polkadot binary, the next step is to configure the start-up command depending on the type of node that you want to run. You'll need to modify the start-up command accordingly based on the location of the binary. In some cases, it may be located within the `./target/release/` folder, so you'll need to replace polkadot with `./target/release/polkadot` in the following commands. + +Also, note that you can use the same binary for Polkadot as you would for Kusama or any other relay chain. You'll need to use the `--chain` flag to differentiate between chains. + +The base commands for running a Polkadot node are as follows: + +=== "Default pruned node" + + This uses the default pruning value of the last 256 blocks: + + ```bash + polkadot --chain polkadot \ + --name "INSERT_NODE_NAME" + ``` + +=== "Custom pruned node" + + You can customize the pruning value, for example, to the last 1000 finalized blocks: + + ```bash + polkadot --chain polkadot \ + --name INSERT_YOUR_NODE_NAME \ + --state-pruning 1000 \ + --blocks-pruning archive \ + --rpc-cors all \ + --rpc-methods safe + ``` + +=== "Archive node" + + To support the full state, use the `archive` option: + + ```bash + polkadot --chain polkadot \ + --name INSERT_YOUR_NODE_NAME \ + --state-pruning archive \ + --blocks-pruning archive \ + ``` + +If you want to run an RPC node, please refer to the following [RPC Configurations](#rpc-configurations) section. + +To review a complete list of the available commands, flags, and options, you can use the `--help` flag: + +```bash +polkadot --help +``` + +Once you've fully configured your start-up command, you can execute it in your terminal and your node will start [syncing](#sync-your-node). + +### RPC Configurations + +The node startup settings allow you to choose what to expose, how many connections to expose, and which systems should be granted access through the RPC server. + +- You can limit the methods to use with `--rpc-methods`; an easy way to set this to a safe mode is `--rpc-methods safe`. +- You can set your maximum connections through `--rpc-max-connections`, for example, `--rpc-max-connections 200`. +- By default, localhost and Polkadot.js can access the RPC server. You can change this by setting `--rpc-cors`. To allow access from everywhere, you can use `--rpc-cors all`. + +For a list of important flags when running RPC nodes, refer to the Parity DevOps documentation: [Important Flags for Running an RPC Node](https://paritytech.github.io/devops-guide/guides/rpc_index.html?#important-flags-for-running-an-rpc-node){target=\_blank}. + +## Sync Your Node + +The syncing process will take a while, depending on your capacity, processing power, disk speed, and RAM. The process may be completed on a $10 DigitalOcean droplet in about ~36 hours. While syncing, your node name should be visible in gray on Polkadot Telemetry, and once it is fully synced, your node name will appear in white on [Polkadot Telemetry](https://telemetry.polkadot.io/#list/Polkadot){target=_blank}. + +A healthy node syncing blocks will output logs like the following: + +
+ 2024-11-19 23:49:57 Parity Polkadot + 2024-11-19 23:49:57 ✌️ version 1.14.1-7c4cd60da6d + 2024-11-19 23:49:57 ❤️ by Parity Technologies <admin@parity.io>, 2017-2024 + 2024-11-19 23:49:57 📋 Chain specification: Polkadot + 2024-11-19 23:49:57 🏷 Node name: myPolkadotNode + 2024-11-19 23:49:57 👤 Role: FULL + 2024-11-19 23:49:57 💾 Database: RocksDb at /home/ubuntu/.local/share/polkadot/chains/polkadot/db/full + 2024-11-19 23:50:00 🏷 Local node identity is: 12D3KooWDmhHEgPRJUJnUpJ4TFWn28EENqvKWH4dZGCN9TS51y9h + 2024-11-19 23:50:00 Running libp2p network backend + 2024-11-19 23:50:00 💻 Operating system: linux + 2024-11-19 23:50:00 💻 CPU architecture: x86_64 + 2024-11-19 23:50:00 💻 Target environment: gnu + 2024-11-19 23:50:00 💻 CPU: Intel(R) Xeon(R) CPU E3-1245 V2 @ 3.40GHz + 2024-11-19 23:50:00 💻 CPU cores: 4 + 2024-11-19 23:50:00 💻 Memory: 32001MB + 2024-11-19 23:50:00 💻 Kernel: 5.15.0-113-generic + 2024-11-19 23:50:00 💻 Linux distribution: Ubuntu 22.04.5 LTS + 2024-11-19 23:50:00 💻 Virtual machine: no + 2024-11-19 23:50:00 📦 Highest known block at #9319 + 2024-11-19 23:50:00 〽️ Prometheus exporter started at 127.0.0.1:9615 + 2024-11-19 23:50:00 Running JSON-RPC server: addr=127.0.0.1:9944, allowed origins=["http://localhost:*", "http://127.0.0.1:*", "https://localhost:*", "https://127.0.0.1:*", "https://polkadot.js.org"] + 2024-11-19 23:50:00 🏁 CPU score: 671.67 MiBs + 2024-11-19 23:50:00 🏁 Memory score: 7.96 GiBs + 2024-11-19 23:50:00 🏁 Disk score (seq. writes): 377.87 MiBs + 2024-11-19 23:50:00 🏁 Disk score (rand. writes): 147.92 MiBs + 2024-11-19 23:50:00 🥩 BEEFY gadget waiting for BEEFY pallet to become available... + 2024-11-19 23:50:00 🔍 Discovered new external address for our node: /ip4/37.187.93.17/tcp/30333/ws/p2p/12D3KooWDmhHEgPRJUJnUpJ4TFWn28EENqvKWH4dZGCN9TS51y9h + 2024-11-19 23:50:01 🔍 Discovered new external address for our node: /ip6/2001:41d0:a:3511::1/tcp/30333/ws/p2p/12D3KooWDmhHEgPRJUJnUpJ4TFWn28EENqvKWH4dZGCN9TS51y9h + 2024-11-19 23:50:05 ⚙️ Syncing, target=#23486325 (5 peers), best: #12262 (0x8fb5…f310), finalized #11776 (0x9de1…32fb), ⬇ 430.5kiB/s ⬆ 17.8kiB/s + 2024-11-19 23:50:10 ⚙️ Syncing 628.8 bps, target=#23486326 (6 peers), best: #15406 (0x9ce1…2d76), finalized #15360 (0x0e41…a064), ⬇ 255.0kiB/s ⬆ 1.8kiB/s +
+ +Congratulations, you're now syncing a Polkadot full node! Remember that the process is identical when using any other Polkadot SDK-based chain, although individual chains may have chain-specific flag requirements. + +### Connect to Your Node + +Open [Polkadot.js Apps](https://polkadot.js.org/apps/?rpc=ws%3A%2F%2F127.0.0.1%3A9944#/explorer){target=\_blank} and click the logo in the top left to switch the node. Activate the **Development** toggle and input your node's domain or IP address. The default WSS endpoint for a local node is: + +```bash +ws://127.0.0.1:9944 +``` diff --git a/.ai/pages/node-infrastructure-run-a-node-relay-chain-secure-wss.md b/.ai/pages/node-infrastructure-run-a-node-relay-chain-secure-wss.md new file mode 100644 index 000000000..c39c29993 --- /dev/null +++ b/.ai/pages/node-infrastructure-run-a-node-relay-chain-secure-wss.md @@ -0,0 +1,125 @@ +--- +title: Set Up Secure WebSocket +description: Instructions on enabling SSL for your node and setting up a secure WebSocket proxy server using nginx for remote connections. +categories: Infrastructure +url: https://docs.polkadot.com/node-infrastructure/run-a-node/relay-chain/secure-wss/ +--- + +# Set Up Secure WebSocket + +## Introduction + +Ensuring secure WebSocket communication is crucial for maintaining the integrity and security of a Polkadot or Kusama node when interacting with remote clients. This guide walks you through setting up a secure WebSocket (WSS) connection for your node by leveraging SSL encryption with popular web server proxies like nginx or Apache. + +By the end of this guide, you'll be able to secure your node's WebSocket port, enabling safe remote connections without exposing your node to unnecessary risks. The instructions in this guide are for UNIX-based systems. + +## Secure a WebSocket Port + +You can convert a non-secured WebSocket port to a secure WSS port by placing it behind an SSL-enabled proxy. This approach can be used to secure a bootnode or RPC server. The SSL-enabled apache2/nginx/other proxy server redirects requests to the internal WebSocket and converts it to a secure (WSS) connection. You can use a service like [LetsEncrypt](https://letsencrypt.org/){target=\_blank} to obtain an SSL certificate. + +### Obtain an SSL Certificate + +LetsEncrypt suggests using the [Certbot ACME client](https://letsencrypt.org/getting-started/#with-shell-access/){target=\_blank} for your respective web server implementation to get a free SSL certificate: + +- [nginx](https://certbot.eff.org/instructions?ws=nginx&os=ubuntufocal){target=\_blank} +- [apache2](https://certbot.eff.org/instructions?ws=apache&os=ubuntufocal){target=\_blank} + +LetsEncrypt will auto-generate an SSL certificate and include it in your configuration. + +When connecting, you can generate a self-signed certificate and rely on your node's raw IP address. However, self-signed certificates aren't optimal because you must include the certificate in an allowlist to access it from a browser. + +Use the following command to generate a self-signed certificate using OpenSSL: + +```bash +sudo openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout /etc/ssl/private/selfsigned.key -out /etc/ssl/certs/selfsigned.crt +sudo openssl dhparam -out /etc/ssl/certs/dhparam.pem 2048 +``` +## Install a Proxy Server + +There are a lot of different implementations of a WebSocket proxy; some of the more widely used are [nginx](https://www.f5.com/go/product/welcome-to-nginx){target=\_blank} and [apache2](https://httpd.apache.org/){target=\_blank}, both of which are commonly used web server implementations. See the following section for configuration examples for both implementations. + +### Use nginx + +1. Install the `nginx` web server: + ```bash + apt install nginx + ``` + +2. In an SSL-enabled virtual host, add: + ```conf + server { + (...) + location / { + proxy_buffers 16 4k; + proxy_buffer_size 2k; + proxy_pass http://localhost:9944; + proxy_http_version 1.1; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection "Upgrade"; + proxy_set_header Host $host; + } + } + ``` +3. Optionally, you can introduce some form of rate limiting: + ```conf + http { + limit_req_zone "$http_x_forwarded_for" zone=zone:10m rate=2r/s; + (...) + } + location / { + limit_req zone=zone burst=5; + (...) + } + ``` +### Use Apache2 + +Apache2 can run in various modes, including `prefork`, `worker`, and `event`. In this example, the [`event`](https://httpd.apache.org/docs/2.4/mod/event.html){target=\_blank} mode is recommended for handling higher traffic loads, as it is optimized for performance in such environments. However, depending on the specific requirements of your setup, other modes like `prefork` or `worker` may also be appropriate. + +1. Install the `apache2` web server: + ```bash + apt install apache2 + a2dismod mpm_prefork + a2enmod mpm_event proxy proxy_html proxy_http proxy_wstunnel rewrite ssl + ``` +2. The [`mod_proxy_wstunnel`](https://httpd.apache.org/docs/2.4/mod/mod_proxy_wstunnel.html){target=\_blank} provides support for the tunneling of WebSocket connections to a backend WebSocket server. The connection is automatically upgraded to a WebSocket connection. In an SSL-enabled virtual host add: + + ```apacheconf + # (...) + SSLProxyEngine on + ProxyRequests off + ProxyPass / ws://localhost:9944 + ProxyPassReverse / ws://localhost:9944 + ``` + !!!warning + Older versions of `mod_proxy_wstunnel` don't upgrade the connection automatically and will need the following config added: + ```apacheconf + RewriteEngine on + RewriteCond %{HTTP:Upgrade} websocket [NC] + RewriteRule /(.*) ws://localhost:9944/$1 [P,L] + RewriteRule /(.*) http://localhost:9944/$1 [P,L] + ``` + +3. Optionally, some form of rate limiting can be introduced by first running the following command: + + ```bash + apt install libapache2-mod-qos + a2enmod qos + ``` + + Then edit `/etc/apache2/mods-available/qos.conf` as follows: + + ```conf + # allows max 50 connections from a single IP address: + QS_SrvMaxConnPerIP 50 + ``` + +## Connect to the Node + +1. Open [Polkadot.js Apps interface](https://polkadot.js.org/apps){target=\_blank} and click the logo in the top left to switch the node. +2. Activate the **Development** toggle and input either your node's domain or IP address. Remember to prefix with `wss://` and, if you're using the 443 port, append `:443` as follows: + + ```bash + wss://example.com:443 + ``` + +![A sync-in-progress chain connected to Polkadot.js UI](/images/nodes-and-validators/run-a-node/secure-wss/secure-wss-01.webp) diff --git a/.ai/pages/node-infrastructure-run-a-node-system-parachain-rpc.md b/.ai/pages/node-infrastructure-run-a-node-system-parachain-rpc.md new file mode 100644 index 000000000..c5d5b13cc --- /dev/null +++ b/.ai/pages/node-infrastructure-run-a-node-system-parachain-rpc.md @@ -0,0 +1,652 @@ +--- +title: Run an RPC Node for System Parachains +description: Complete guide to set up and run an RPC node for Polkadot system parachains including Bridge Hub, People Chain, and Coretime Chain. +categories: Infrastructure +url: https://docs.polkadot.com/node-infrastructure/run-a-node/system-parachain-rpc/ +--- + +# Run an RPC Node for System Parachains + +## Overview + +System parachains are core infrastructure parachains that provide essential services to the Polkadot network. Running an RPC node for these parachains enables applications, wallets, and users to interact with their specialized functionality: + +- **Bridge Hub**: Cross-chain asset transfers via trustless bridges +- **People Chain**: Identity and social credential management +- **Coretime Chain**: Blockspace allocation and core time management + +Each system parachain RPC node provides access through: +- **Polkadot SDK Node RPC** (Port 9944): Native Polkadot API (WebSocket and HTTP) + +This setup enables block explorer indexing and provides full compatibility with Polkadot SDK development tools. + +**Important Note**: The parameters and configurations in this guide are provided as illustrative examples. You may need to modify them according to your specific environment, hardware capabilities, and network conditions. + +## Choosing a System Parachain + +This guide uses **People Chain** as the example, but the same principles and setup procedures apply to all system parachains. Simply substitute the appropriate values from the table below for your chosen parachain: + +| Parachain | Para ID | Chain Spec File | Snapshot Path | Chain Name | +|-----------|---------|-----------------|---------------|------------| +| **Bridge Hub** | 1002 | `bridge-hub-polkadot.json` | `polkadot-bridge-hub-rocksdb-archive` | `bridge-hub-polkadot` | +| **People Chain** | 1004 | `people-polkadot.json` | `polkadot-people-rocksdb-archive` | `people-polkadot` | +| **Coretime Chain** | 1005 | `coretime-polkadot.json` | `polkadot-coretime-rocksdb-archive` | `coretime-polkadot` | + +**Note**: Throughout this guide, we use People Chain values. To set up a different system parachain, replace the chain spec file, snapshot path, and chain name with the corresponding values from the table above. + +## Prerequisites + +### Hardware Requirements + +RPC nodes serving production traffic require robust hardware: + +- **CPU**: 8+ cores (16+ cores for high traffic) +- **Memory**: 64 GB RAM minimum (128 GB recommended for high traffic) +- **Storage**: + - 500 GB+ NVMe SSD for parachain state (archive nodes require 2-4 TB+) + - Additional 200+ GB for relay chain pruned database + - Fast disk I/O is critical for query performance +- **Network**: + - Public IP address + - 1 Gbps connection (for high traffic scenarios) + - Stable internet connection with sufficient bandwidth + - Open ports: + - 30333 (parachain P2P) + - 30334 (relay chain P2P) + - 9944 (Polkadot SDK WebSocket RPC) + - 9933 (Polkadot SDK HTTP RPC) + - 9615 (Prometheus metrics - optional) + - Consider DDoS protection and rate limiting for production deployments + +**Note**: For development or low-traffic scenarios, you can reduce these requirements proportionally. Consider using a reverse proxy (nginx, Caddy) for production deployments. + +### Software Requirements + +Required software: + +- **Operating System**: Ubuntu 22.04 LTS (recommended) or similar Linux distribution +- **Docker**: Latest version installed and running (for Docker-based setup) +- **rclone**: (Optional but recommended) Command-line program for managing files on cloud storage (https://rclone.org/downloads/) +- **Rust Toolchain**: Version 1.86 or as specified by runtime (for manual build) + +## Setup Options + +This guide provides two deployment options: + +1. **Docker-based Setup**: Simpler to set up and maintain +2. **Manual/Systemd Setup**: For production environments requiring more control + +Choose the option that best fits your needs. + +--- + +## Option 1: Docker-Based Setup + +This option uses Docker containers for the Polkadot SDK node, making it easy to set up and manage. + +### Step 1: Download Chain Specification + +Download the official chain specification for People Chain: + +```bash +curl -L https://raw.githubusercontent.com/paritytech/polkadot-sdk/master/cumulus/parachains/chain-specs/people-polkadot.json -o people-polkadot.json +``` + +**Note**: This chain specification is the official configuration file that defines the network parameters for People Chain. + +### Step 2: Download Database Snapshots (Optional but Recommended) + +Using pre-synchronized snapshots significantly reduces initial sync time from several days to just a few hours. You need to download both parachain and relay chain data. + +**Snapshot Provider**: https://snapshots.polkadot.io/ + +#### Create Directories + +```bash +mkdir -p my-node-data/chains/people-polkadot/db +mkdir -p my-node-data/chains/polkadot/db +``` + +#### Download People Chain Snapshot + +Choose between archive (complete history) or pruned (recent state) snapshots. + +**Archive Snapshot** (recommended for RPC with historical data): + +```bash +# Check https://snapshots.polkadot.io/ for the latest snapshot URL +export SNAPSHOT_URL_PARACHAIN="https://snapshots.polkadot.io/polkadot-people-rocksdb-archive/LATEST" + +rclone copyurl $SNAPSHOT_URL_PARACHAIN/files.txt files.txt +rclone copy --progress --transfers 20 \ + --http-url $SNAPSHOT_URL_PARACHAIN \ + --no-traverse --http-no-head --disable-http2 \ + --inplace --no-gzip-encoding --size-only \ + --retries 6 --retries-sleep 10s \ + --files-from files.txt :http: my-node-data/chains/people-polkadot/db/ + +rm files.txt +``` + +**Parameter Explanation**: +- `--transfers 20`: Uses 20 parallel transfers for faster download +- `--retries 6`: Automatically retries failed transfers up to 6 times +- `--retries-sleep 10s`: Waits 10 seconds between retry attempts +- `--size-only`: Only transfers if sizes differ (prevents unnecessary re-downloads) + +**Note**: If a snapshot is not available, you can sync from scratch (which will take longer) or check https://snapshots.polkadot.io/ for alternative snapshot providers. + +#### Download Polkadot Relay Chain Snapshot + +**Pruned Snapshot** (recommended for RPC nodes): + +```bash +# Check https://snapshots.polkadot.io/ for the latest snapshot URL +export SNAPSHOT_URL_RELAY="https://snapshots.polkadot.io/polkadot-rocksdb-prune/LATEST" + +rclone copyurl $SNAPSHOT_URL_RELAY/files.txt files.txt +rclone copy --progress --transfers 20 \ + --http-url $SNAPSHOT_URL_RELAY \ + --no-traverse --http-no-head --disable-http2 \ + --inplace --no-gzip-encoding --size-only \ + --retries 6 --retries-sleep 10s \ + --files-from files.txt :http: my-node-data/chains/polkadot/db/ + +rm files.txt +``` + +**Alternative Options**: +- Pruned snapshot: `polkadot-rocksdb-prune` (smaller size, recent state) +- Archive snapshot: `polkadot-rocksdb-archive` (complete history, larger size) + +### Step 3: Start People Chain Node + +Launch the node using the official Parity Docker image. + +**Docker Image**: https://hub.docker.com/r/parity/polkadot-omni-node + +```bash +docker run -d --name people-chain-rpc --restart unless-stopped \ + -p 9944:9944 \ + -p 9933:9933 \ + -p 9615:9615 \ + -p 30334:30334 \ + -p 30333:30333 \ + -v $(pwd)/people-polkadot.json:/people-polkadot.json \ + -v $(pwd)/my-node-data:/data \ + parity/polkadot-omni-node:stable2506-4 \ + --name=PeopleChainRPC \ + --base-path=/data \ + --chain=/people-polkadot.json \ + --prometheus-external \ + --prometheus-port 9615 \ + --unsafe-rpc-external \ + --rpc-port=9944 \ + --rpc-cors=all \ + --rpc-methods=safe \ + --rpc-max-connections=1000 \ + --state-pruning=archive \ + --blocks-pruning=archive \ + -- \ + --base-path=/data \ + --chain=polkadot \ + --state-pruning=256 \ + --blocks-pruning=archive-canonical +``` + +**Critical Configuration Parameters**: + +**Port Mappings**: +- `9944`: Polkadot SDK RPC endpoint (WebSocket/HTTP) +- `9933`: Polkadot SDK HTTP RPC endpoint +- `9615`: Prometheus metrics endpoint +- `30333/30334`: P2P networking ports + +**Node Parameters**: +- `--unsafe-rpc-external`: Enables external RPC access +- `--rpc-cors=all`: Allows all origins for CORS +- `--rpc-methods=safe`: Only allows safe RPC methods +- `--state-pruning=archive`: Keeps complete state history +- `--blocks-pruning=archive`: Keeps all block data +- `--prometheus-external`: Exposes metrics externally + +**Security Warning**: The `--unsafe-rpc-external` flag should only be used in development or properly secured environments. For production, use a reverse proxy with authentication. + +### Step 4: Monitor Synchronization + +Monitor the node synchronization status: + +```bash +# Check sync status +curl -H "Content-Type: application/json" \ + -d '{"id":1, "jsonrpc":"2.0", "method": "system_syncState", "params":[]}' \ + http://localhost:9944 +``` + +**Expected Response Format**: + +```json +{ + "jsonrpc":"2.0", + "id":1, + "result":{ + "startingBlock":0, + "currentBlock":3394816, + "highestBlock":3394816 + } +} +``` + +**Synchronization Status**: +- **In Progress**: `currentBlock` < `highestBlock` +- **Complete**: `currentBlock` = `highestBlock` + +**Monitor logs**: + +```bash +# View node logs +docker logs -f people-chain-rpc + +# Filter for sync messages +docker logs people-chain-rpc 2>&1 | grep -i "syncing" +``` + +### Step 5: Verify Setup + +Let's verify the Polkadot SDK RPC endpoint is working correctly. + +#### API Endpoint + +**Polkadot SDK RPC (Port 9944)**: +- WebSocket: `ws://your-server:9944` +- HTTP: `http://your-server:9944` +- Purpose: Full Polkadot SDK API access for parachain data +- Use Cases: Polkadot SDK applications, parachain-specific operations + +#### Polkadot SDK RPC Tests + +**Get Chain Information**: + +```bash +curl -H "Content-Type: application/json" \ + -d '{"id":1, "jsonrpc":"2.0", "method": "system_chain", "params":[]}' \ + http://localhost:9944 +``` + +**Expected Response**: +```json +{ + "jsonrpc":"2.0", + "id":1, + "result":"Polkadot People" +} +``` + +**Get Latest Block**: + +```bash +curl -H "Content-Type: application/json" \ + -d '{"id":1, "jsonrpc":"2.0", "method": "chain_getHeader", "params":[]}' \ + http://localhost:9944 +``` + +**Get Node Health**: + +```bash +curl -H "Content-Type: application/json" \ + -d '{"id":1, "jsonrpc":"2.0", "method": "system_health", "params":[]}' \ + http://localhost:9944 +``` + +**Get Peer Count**: + +```bash +curl -H "Content-Type: application/json" \ + -d '{"id":1, "jsonrpc":"2.0", "method": "system_peers", "params":[]}' \ + http://localhost:9944 +``` + +### Managing Docker Containers + +**View logs**: + +```bash +docker logs -f people-chain-rpc +``` + +**Stop container**: + +```bash +docker stop people-chain-rpc +``` + +**Start container**: + +```bash +docker start people-chain-rpc +``` + +**Remove container**: + +```bash +docker rm people-chain-rpc +``` + +**Update container**: + +```bash +# Pull latest image +docker pull parity/polkadot-omni-node:stable2506-4 + +# Stop and remove old container +docker stop people-chain-rpc +docker rm people-chain-rpc + +# Start new container with same command as above +``` + +--- + +## Option 2: Manual/Systemd Setup + +This option provides more control and is recommended for production environments requiring custom configurations. + +### Step 1: Install Rust and Required Toolchain + +```bash +# Install Rust +curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh +source $HOME/.cargo/env + +# Install specific Rust version +rustup install 1.86 +rustup default 1.86 +rustup target add wasm32-unknown-unknown --toolchain 1.86 +rustup component add rust-src --toolchain 1.86 +``` + +### Step 2: Install the Polkadot Omni Node + +```bash +# Install polkadot-omni-node +cargo install --locked polkadot-omni-node@0.7.0 + +# Verify installation +polkadot-omni-node --version +``` + +### Step 3: Obtain Chain Specification + +Download the People Chain specification: + +```bash +curl -L https://raw.githubusercontent.com/paritytech/polkadot-sdk/master/cumulus/parachains/chain-specs/people-polkadot.json -o people-polkadot.json +``` + +### Step 4: Create User and Directory Structure + +```bash +# Create dedicated user (skip if already exists) +sudo useradd -r -s /bin/bash polkadot + +# Create data directory +sudo mkdir -p /var/lib/people-chain-rpc + +# Copy chain spec to the directory +sudo cp people-polkadot.json /var/lib/people-chain-rpc/ + +# Set permissions +sudo chown -R polkadot:polkadot /var/lib/people-chain-rpc +``` + +### Step 5: Create Systemd Service + +Create a service file for the People Chain RPC node: + +```bash +sudo nano /etc/systemd/system/people-chain-rpc.service +``` + +Add the following configuration: + +```ini +[Unit] +Description=People Chain RPC Node +After=network.target + +[Service] +Type=simple +User=polkadot +Group=polkadot +WorkingDirectory=/var/lib/people-chain-rpc + +ExecStart=/usr/local/bin/polkadot-omni-node \ + --name=PeopleChainRPC \ + --chain=/var/lib/people-chain-rpc/people-polkadot.json \ + --base-path=/var/lib/people-chain-rpc \ + --port=30333 \ + --rpc-port=9944 \ + --rpc-external \ + --rpc-cors=all \ + --rpc-methods=safe \ + --rpc-max-connections=1000 \ + --prometheus-port=9615 \ + --prometheus-external \ + --state-pruning=archive \ + --blocks-pruning=archive \ + -- \ + --chain=polkadot \ + --base-path=/var/lib/people-chain-rpc \ + --port=30334 \ + --state-pruning=256 \ + --blocks-pruning=archive-canonical + +Restart=always +RestartSec=10 +LimitNOFILE=65536 + +[Install] +WantedBy=multi-user.target +``` + +### Step 6: Start Service + +```bash +# Reload systemd +sudo systemctl daemon-reload + +# Enable service to start on boot +sudo systemctl enable people-chain-rpc + +# Start the node +sudo systemctl start people-chain-rpc + +# Check status and wait for sync +sudo systemctl status people-chain-rpc +sudo journalctl -u people-chain-rpc -f +``` + +### Step 7: Verify Setup + +Use the same verification tests as in the Docker setup (see Step 5 above). + +--- + +## Monitoring and Maintenance + +### Log Management + +**Docker Setup**: + +```bash +# View node logs +docker logs -f people-chain-rpc +``` + +**Systemd Setup**: + +```bash +# View node logs +sudo journalctl -u people-chain-rpc -f + +# View recent logs +sudo journalctl -u people-chain-rpc -n 100 + +# Filter for errors +sudo journalctl -u people-chain-rpc | grep -i error +``` + +### Performance Monitoring + +Monitor key metrics: +- **Sync status**: Ensure node stays fully synced +- **Peer connections**: Maintain 30+ peers for good connectivity +- **Resource usage**: Monitor CPU, RAM, and disk I/O +- **RPC request latency**: Track response times for the Polkadot SDK API +- **Connection count**: Monitor active RPC connections + +**Prometheus Metrics**: + +Metrics are available at `http://localhost:9615/metrics` + +Example Prometheus scrape configuration: + +{% raw %} +```yaml +scrape_configs: + - job_name: 'people-chain-rpc' + static_configs: + - targets: ['localhost:9615'] +``` +{% endraw %} + +**Key Metrics to Monitor**: +- `substrate_block_height`: Current block height +- `substrate_finalized_height`: Finalized block height +- `substrate_peers_count`: Number of connected peers +- `substrate_ready_transactions_number`: Transaction queue size + +### Database Maintenance + +Check database size periodically: + +```bash +# Docker setup +du -sh my-node-data + +# Systemd setup +du -sh /var/lib/people-chain-rpc +``` + +The node handles pruning automatically based on configuration unless running in archive mode. + +### Updates and Upgrades + +**Docker Setup**: + +```bash +# Pull latest image +docker pull parity/polkadot-omni-node:stable2506-4 + +# Restart container +docker stop people-chain-rpc +docker rm people-chain-rpc + +# Start new container (use same command from setup) +``` + +**Systemd Setup**: + +```bash +# Stop service +sudo systemctl stop people-chain-rpc + +# Backup data +sudo cp -r /var/lib/people-chain-rpc /var/lib/people-chain-rpc.backup + +# Update binary +cargo install --locked --force polkadot-omni-node@ + +# Restart service +sudo systemctl start people-chain-rpc +``` + +## Security Best Practices + +### Network Security + +1. **Firewall Configuration**: + - Only expose necessary ports + - Use UFW or iptables to restrict access + - Consider IP whitelisting for RPC endpoints + +2. **Reverse Proxy** (Recommended for Production): + - Use nginx or Caddy as reverse proxy + - Enable SSL/TLS (HTTPS/WSS) + - Implement authentication + - Add rate limiting + +Example nginx configuration: + +```nginx +upstream polkadot_sdk_rpc { + server 127.0.0.1:9944; +} + +server { + listen 443 ssl http2; + server_name your-domain.com; + + ssl_certificate /path/to/cert.pem; + ssl_certificate_key /path/to/key.pem; + + # Polkadot SDK RPC + location /polkadot { + proxy_pass http://polkadot_sdk_rpc; + proxy_http_version 1.1; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection "upgrade"; + + # Rate limiting + limit_req zone=rpc_limit burst=10; + } +} +``` + +### RPC Security + +- **Always use `--rpc-methods=safe`**: Prevents dangerous RPC calls +- **Restrict CORS**: Use specific domains instead of `all` in production +- **Set connection limits**: Prevent resource exhaustion +- **Monitor for abuse**: Track unusual patterns +- **Authentication**: Implement API keys or OAuth for production + +### System Security + +- Keep operating system updated +- Use dedicated user accounts (never root) +- Enable fail2ban for SSH protection +- Regular security audits +- Disable unnecessary services +- Use AppArmor or SELinux for additional isolation + +### Monitoring and Alerting + +Set up alerts for: +- Service failures +- Sync issues +- Low peer count (< 10 peers) +- High resource usage +- Unusual RPC traffic patterns +- Database errors + +## Conclusion + +Running an RPC node for system parachains provides critical infrastructure for accessing specialized Polkadot network services. By following this guide, you have set up a production-ready RPC node that: + +- Enables applications and users to interact with essential system parachain features (identity management, cross-chain bridges, or coretime allocation) +- Supports flexible deployment with both Docker and systemd options +- Implements comprehensive monitoring, security, and maintenance practices +- Can be easily adapted for any system parachain by substituting the appropriate chain specification + +Whether you're running a node for People Chain, Bridge Hub, or Coretime Chain, regular maintenance and monitoring will ensure your RPC node continues to provide reliable service. Stay updated with the latest releases and best practices to keep your infrastructure secure and performant. diff --git a/.ai/pages/node-infrastructure-run-a-validator-onboarding-and-offboarding-key-management.md b/.ai/pages/node-infrastructure-run-a-validator-onboarding-and-offboarding-key-management.md new file mode 100644 index 000000000..1f688736e --- /dev/null +++ b/.ai/pages/node-infrastructure-run-a-validator-onboarding-and-offboarding-key-management.md @@ -0,0 +1,155 @@ +--- +title: Validator Key Management +description: Learn how to generate and manage validator keys, including session keys for consensus participation and node keys for maintaining a stable network identity. +categories: Infrastructure +url: https://docs.polkadot.com/node-infrastructure/run-a-validator/onboarding-and-offboarding/key-management/ +--- + +# Key Management + +## Introduction + +After setting up your node environment as shown in the [Setup](/nodes-and-validators/run-a-validator/onboarding-and-offboarding/set-up-validator/){target=\_blank} section, you'll need to configure multiple keys for your validator to operate properly. This includes setting up session keys, which are essential for participating in the consensus process, and configuring a node key that maintains a stable network identity. This guide walks you through the key management process, showing you how to generate, store, and register these keys. + +## Set Session Keys + +Setting up your validator's session keys is essential to associate your node with your stash account on the Polkadot network. Validators use session keys to participate in the consensus process. Your validator can only perform its role in the network by properly setting session keys which consist of several key pairs for different parts of the protocol (e.g., GRANDPA, BABE). These keys must be registered on-chain and associated with your validator node to ensure it can participate in validating blocks. + +### Generate Session Keys + +There are multiple ways to create the session keys. It can be done by interacting with the [Polkadot.js Apps UI](https://polkadot.js.org/apps/#/explorer){target=\_blank}, using the curl command or by using [Subkey](https://paritytech.github.io/polkadot-sdk/master/subkey/index.html){target=\_blank}. + +=== "Polkadot.js Apps UI" + + 1. In Polkadot.js Apps, connect to your local node, navigate to the **Developer** dropdown, and select the **RPC Calls** option. + + 2. Construct an `author_rotateKeys` RPC call and execute it: + + 1. Select the **author** endpoint. + 2. Choose the **rotateKeys()** call. + 3. Click the **Submit RPC Call** button. + 4. Copy the hex-encoded public key from the response. + + ![](/images/nodes-and-validators/run-a-validator/onboarding-and-offboarding/key-management/key-management-01.webp) + +=== "Curl" + + Generate session keys by running the following command on your validator node: + + ``` bash + curl -H "Content-Type: application/json" \ + -d '{"id":1, "jsonrpc":"2.0", "method": "author_rotateKeys", "params":[]}' \ + http://localhost:9944 + ``` + + This command will return a JSON object. The `result` key is the hex-encoded public part of the newly created session key. Save this for later use. + + ```json + {"jsonrpc":"2.0","result":"0xda3861a45e0197f3ca145c2c209f9126e5053fas503e459af4255cf8011d51010","id":1} + ``` + +=== "Subkey" + + To create a keypair for your node's session keys, use the `subkey generate` command. This generates a set of cryptographic keys that must be stored in your node's keystore directory. + + When you run the command, it produces output similar to this example: + +
+ subkey generate +
+    Secret phrase:       twist buffalo mixture excess device drastic vague mammal fitness punch match hammer
+      Network ID:        substrate
+      Secret seed:       0x5faa9e5defe42b201388d5c2b8202d6625a344abc9aa52943a71f12cb90b88a9
+      Public key (hex):  0x28cc2fdb6e28835e2bbac9a16feb65c23d448c9314ef12fe083b61bab8fc2755
+      Account ID:        0x28cc2fdb6e28835e2bbac9a16feb65c23d448c9314ef12fe083b61bab8fc2755
+      Public key (SS58): 5CzCRpXzHYhuo6G3gYFR3cgV6X3qCNwVt51m8q14ZcChsSXQ
+      SS58 Address:      5CzCRpXzHYhuo6G3gYFR3cgV6X3qCNwVt51m8q14ZcChsSXQ
+      
+
+ + To properly store these keys, create a file in your keystore directory with a specific naming convention. The filename must consist of the hex string `61757261` (which represents "aura" in hex) followed by the public key without its `0x` prefix. + + Using the example above, you would create a file named: + + ``` + ./keystores/6175726128cc2fdb6e28835e2bbac9a16feb65c23d448c9314ef12fe083b61bab8fc2755 + ``` + + And store only the secret phrase in the file: + + ``` + "twist buffalo mixture excess device drastic vague mammal fitness punch match hammer" + ``` + +### Submit Transaction to Set Keys + +Now that you have generated your session keys, you must submit them to the chain. Follow these steps: + +1. Go to the **Network > Staking > Accounts** section on Polkadot.js Apps. +2. Select **Set Session Key** on the bonding account you generated earlier. +3. Paste the hex-encoded session key string you generated (from either the UI or CLI) into the input field and submit the transaction. + +![](/images/nodes-and-validators/run-a-validator/onboarding-and-offboarding/key-management/key-management-02.webp) + +Once the transaction is signed and submitted, your session keys will be registered on-chain. + +### Verify Session Key Setup + +To verify that your session keys are properly set, you can use one of two RPC calls: + +- **`hasKey`**: Checks if the node has a specific key by public key and key type. +- **`hasSessionKeys`**: Verifies if your node has the full session key string associated with the validator. + +For example, you can [check session keys on the Polkadot.js Apps](https://polkadot.js.org/apps/#/rpc){target=\_blank} interface or by running an RPC query against your node. Once this is done, your validator node is ready for its role. + +## Set the Node Key + +Validators on Polkadot need a static network key (also known as the node key) to maintain a stable node identity. This key ensures that your validator can maintain a consistent peer ID, even across restarts, which is crucial for maintaining reliable network connections. + +Starting with Polkadot version 1.11, validators without a stable network key may encounter the following error on startup: + +
+ polkadot --validator --name "INSERT_NAME_FROM_TELEMETRY" + Error: + 0: Starting an authority without network key + This is not a safe operation because other authorities in the network may depend on your node having a stable identity. + Otherwise these other authorities may not being able to reach you. + If it is the first time running your node you could use one of the following methods: + 1. [Preferred] Separately generate the key with: INSERT_NODE_BINARY key generate-node-key --base-path INSERT_YOUR_BASE_PATH + 2. [Preferred] Separately generate the key with: INSERT_NODE_BINARY key generate-node-key --file INSERT_YOUR_PATH_TO_NODE_KEY + 3. [Preferred] Separately generate the key with: INSERT_NODE_BINARY key generate-node-key --default-base-path + 4. [Unsafe] Pass --unsafe-force-node-key-generation and make sure you remove it for subsequent node restarts + +
+ +### Generate the Node Key + +Use one of the following methods to generate your node key: + +=== "Save to file" + + The recommended solution is to generate a node key and save it to a file using the following command: + + ``` bash + polkadot key generate-node-key --file INSERT_PATH_TO_NODE_KEY + ``` + +=== "Use default path" + + You can also generate the node key with the following command, which will automatically save the key to the base path of your node: + + ``` bash + polkadot key generate-node-key --default-base-path + ``` + +Save the file path for reference. You will need it in the next step to configure your node with a static identity. + +### Set Node Key + +After generating the node key, configure your node to use it by specifying the path to the key file when launching your node. Add the following flag to your validator node's startup command: + +``` bash +polkadot --node-key-file INSERT_PATH_TO_NODE_KEY +``` + +Following these steps ensures that your node retains its identity, making it discoverable by peers without the risk of conflicting identities across sessions. For further technical background, see Polkadot SDK [Pull Request #3852](https://github.com/paritytech/polkadot-sdk/pull/3852){target=\_blank} for the rationale behind requiring static keys. diff --git a/.ai/pages/node-infrastructure-run-a-validator-onboarding-and-offboarding-set-up-validator.md b/.ai/pages/node-infrastructure-run-a-validator-onboarding-and-offboarding-set-up-validator.md new file mode 100644 index 000000000..4fd33b1ef --- /dev/null +++ b/.ai/pages/node-infrastructure-run-a-validator-onboarding-and-offboarding-set-up-validator.md @@ -0,0 +1,213 @@ +--- +title: Set Up a Validator +description: Set up a Polkadot validator node to secure the network and earn staking rewards. Follow this step-by-step guide to install, configure, and manage your node. +categories: Infrastructure +url: https://docs.polkadot.com/node-infrastructure/run-a-validator/onboarding-and-offboarding/set-up-validator/ +--- + +# Set Up a Validator + +## Introduction + +Setting up a Polkadot validator node is essential for securing the network and earning staking rewards. This guide walks you through the technical steps to set up a validator, from installing the necessary software to managing keys and synchronizing your node with the chain. + +Running a validator requires a commitment to maintaining a stable, secure infrastructure. Validators are responsible for their own stakes and those of nominators who trust them with their tokens. Proper setup and ongoing management are critical to ensuring smooth operation and avoiding potential penalties such as slashing. + +## Prerequisites + +To get the most from this guide, ensure you've done the following before going forward: + +- Read [Validator Requirements](/nodes-and-validators/run-a-validator/requirements/){target=\_blank} and understand the recommended minimum skill level and hardware needs. +- Read [General Management](/nodes-and-validators/run-a-validator/operational-tasks/general-management/){target=\_blank}, [Upgrade Your Node](/nodes-and-validators/run-a-validator/operational-tasks/upgrade-your-node/){target=\_blank}, and [Pause Validating](/nodes-and-validators/run-a-validator/operational-tasks/pause-validating/){target=\_blank} and understand the tasks required to keep your validator operational. +- Read [Rewards Payout](/nodes-and-validators/run-a-validator/staking-mechanics/rewards/){target=\_blank} and understand how validator rewards are determined and paid out. +- Read [Offenses and Slashes](/nodes-and-validators/run-a-validator/staking-mechanics/offenses-and-slashes/){target=\_blank} and understand how validator performance and security can affect tokens staked by you or your nominators. + +## Initial Setup + +Before running your validator, you must configure your server environment to meet the operational and security standards required for validating. + +You must use a Linux-based operating system with Kernel 5.16 or later. Configuration includes setting up time synchronization, ensuring critical security features are active, and installing the necessary binaries. Proper setup at this stage is essential to prevent issues like block production errors or being penalized for downtime. Below are the essential steps to get your system ready. + +### Install Network Time Protocol Client + +Accurate timekeeping is critical to ensure your validator is synchronized with the network. Validators need local clocks in sync with the blockchain to avoid missing block authorship opportunities. Using [Network Time Protocol (NTP)](https://en.wikipedia.org/wiki/Network_Time_Protocol){target=\_blank} is the standard solution to keep your system's clock accurate. + +If you are using Ubuntu version 18.04 or newer, the NTP Client should be installed by default. You can check whether you have the NTP client by running: + +```sh +timedatectl +``` + +If NTP is running, you should see a message like the following: + +``` sh +System clock synchronized: yes +``` + +If NTP is not installed or running, you can install it using: + +```sh +sudo apt-get install ntp +``` + +After installation, NTP will automatically start. To check its status: + +```sh +sudo ntpq -p +``` + +This command will return a message with the status of the NTP synchronization. Skipping this step could result in your validator node missing blocks due to minor clock drift, potentially affecting its network performance. + +### Verify Landlock is Activated + +[Landlock](https://docs.kernel.org/userspace-api/landlock.html){target=\_blank} is an important security feature integrated into Linux kernels starting with version 5.13. It allows processes, even those without special privileges, to limit their access to the system to reduce the machine's attack surface. This feature is crucial for validators, as it helps ensure the security and stability of the node by preventing unauthorized access or malicious behavior. + +To use Landlock, ensure you use the reference kernel or newer versions. Most Linux distributions should already have Landlock activated. You can check if Landlock is activated on your machine by running the following command as root: + +```sh +dmesg | grep landlock || journalctl -kg landlock +``` + +If Landlock is not activated, your system logs won't show any related output. In this case, you will need to activate it manually or ensure that your Linux distribution supports it. Most modern distributions with the required kernel version should have Landlock activated by default. However, if your system lacks support, you may need to build the kernel with Landlock activated. For more information on doing so, refer to the [official kernel documentation](https://docs.kernel.org/userspace-api/landlock.html#kernel-support){target=\_blank}. + +Implementing Landlock ensures your node operates in a restricted, self-imposed sandbox, limiting potential damage from security breaches or bugs. While not a mandatory requirement, enabling this feature greatly improves the security of your validator setup. + +## Install the Polkadot Binaries + +You must install the Polkadot binaries required to run your validator node. These binaries include the main `polkadot`, `polkadot-prepare-worker`, and `polkadot-execute-worker` binaries. All three are needed to run a fully functioning validator node. + +Depending on your preference and operating system setup, there are multiple methods to install these binaries. Below are the main options: + +### Install from Official Releases + +The preferred, most straightforward method to install the required binaries is downloading the latest versions from the official releases. You can visit the [Github Releases](https://github.com/paritytech/polkadot-sdk/releases){target=\_blank} page for the most current versions of the `polkadot`, `polkadot-prepare-worker`, and `polkadot-execute-worker` binaries. + +You can also download the binaries by using the following direct links: + +=== "`polkadot`" + + ``` bash + # Download the binary + curl -LO https://github.com/paritytech/polkadot-sdk/releases/download/polkadot-stable2506-2/polkadot + + # Verify signature + curl -LO https://github.com/paritytech/polkadot-sdk/releases/download/polkadot-stable2506-2/polkadot.asc + + gpg --keyserver hkps://keyserver.ubuntu.com --receive-keys 90BD75EBBB8E95CB3DA6078F94A4029AB4B35DAE + + gpg --verify polkadot.asc + ``` + +=== "`polkadot-prepare-worker`" + + ``` bash + # Download the binary + curl -LO https://github.com/paritytech/polkadot-sdk/releases/download/polkadot-stable2506-2/polkadot-prepare-worker + + # Verify signature + curl -LO https://github.com/paritytech/polkadot-sdk/releases/download/polkadot-stable2506-2/polkadot-prepare-worker.asc + + gpg --keyserver hkps://keyserver.ubuntu.com --receive-keys 90BD75EBBB8E95CB3DA6078F94A4029AB4B35DAE + + gpg --verify polkadot-prepare-worker.asc + ``` + +=== "`polkadot-execute-worker`" + + ``` bash + # Download the binary + curl -LO https://github.com/paritytech/polkadot-sdk/releases/download/polkadot-stable2506-2/polkadot-execute-worker + + # Verify signature + curl -LO https://github.com/paritytech/polkadot-sdk/releases/download/polkadot-stable2506-2/polkadot-execute-worker.asc + + gpg --keyserver hkps://keyserver.ubuntu.com --receive-keys 90BD75EBBB8E95CB3DA6078F94A4029AB4B35DAE + + gpg --verify polkadot-execute-worker.asc + ``` + + +Signature verification cryptographically ensures the downloaded binaries are authentic and have not been tampered with by using GPG signing keys. Polkadot releases use two different signing keys: + +- ParityReleases (release-team@parity.io) with key [`90BD75EBBB8E95CB3DA6078F94A4029AB4B35DAE`](https://keyserver.ubuntu.com/pks/lookup?search=90BD75EBBB8E95CB3DA6078F94A4029AB4B35DAE&fingerprint=on&op=index){target=\_blank} for current and new releases. +- Parity Security Team (security@parity.io) with key [`9D4B2B6EB8F97156D19669A9FF0812D491B96798`](https://keyserver.ubuntu.com/pks/lookup?search=9D4B2B6EB8F97156D19669A9FF0812D491B96798&fingerprint=on&op=index){target=\_blank} for old releases. + + !!!warning + When verifying a signature, a "Good signature" message indicates successful verification, while any other output signals a potential security risk. + +### Install with Package Managers + +Users running Debian-based distributions like Ubuntu can install the binaries using the [APT](https://wiki.debian.org/Apt){target=\_blank} package manager. + +Execute the following commands as root to add the official repository and install the binaries: + +```bash +# Import the release-team@parity.io GPG key +gpg --keyserver hkps://keyserver.ubuntu.com --receive-keys 90BD75EBBB8E95CB3DA6078F94A4029AB4B35DAE +gpg --export 90BD75EBBB8E95CB3DA6078F94A4029AB4B35DAE > /usr/share/keyrings/parity.gpg + +# Add the Parity repository and update the package index +echo 'deb [signed-by=/usr/share/keyrings/parity.gpg] https://releases.parity.io/deb release main' > /etc/apt/sources.list.d/parity.list +apt update + +# Install the `parity-keyring` package - This will ensure the GPG key +# used by APT remains up-to-date +apt install parity-keyring + +# Install polkadot +apt install polkadot +``` + +Once installation completes, verify the binaries are correctly installed by following the steps in the [verify installation](#verify-installation) section. + +### Install with Ansible + +You can also manage Polkadot installations using Ansible. This approach can be beneficial for users managing multiple validator nodes or requiring automated deployment. The [Parity chain operations Ansible collection](https://github.com/paritytech/ansible-galaxy/){target=\_blank} provides a Substrate node role for this purpose. + +### Install with Docker + +If you prefer using Docker or an OCI-compatible container runtime, the official Polkadot Docker image can be pulled directly from Docker Hub. + +To pull the latest stable image, run the following command: + +```bash +docker pull parity/polkadot:stable2506-2 +``` + +### Build from Sources + +You may build the binaries from source by following the instructions on the [Polkadot SDK repository](https://github.com/paritytech/polkadot-sdk/tree/polkadot-stable2506-2/polkadot#building){target=\_blank}. + +## Verify Installation + +Once the Polkadot binaries are installed, it's essential to verify that everything is set up correctly and that all the necessary components are in place. Follow these steps to ensure the binaries are installed and functioning as expected. + +1. **Check the versions**: Run the following commands to verify the versions of the installed binaries. + + ```bash + polkadot --version + polkadot-execute-worker --version + polkadot-prepare-worker --version + ``` + + The output should show the version numbers for each of the binaries. Ensure that the versions match and are consistent, similar to the following example (the specific version may vary): + +
+ polkadot --version polkadot-execute-worker --version polkadot-prepare-worker --version + 1.16.1-36264cb36db + 1.16.1-36264cb36db + 1.16.1-36264cb36db + +
+ + If the versions do not match or if there is an error, double-check that all the binaries were correctly installed and are accessible within your `$PATH`. + +2. **Ensure all binaries are in the same directory**: All the binaries must be in the same directory for the Polkadot validator node to function properly. If the binaries are not in the same location, move them to a unified directory and ensure this directory is added to your system's `$PATH`. + + To verify the `$PATH`, run the following command: + + ```bash + echo $PATH + ``` + + If necessary, you can move the binaries to a shared location, such as `/usr/local/bin/`, and add it to your `$PATH`. diff --git a/.ai/pages/node-infrastructure-run-a-validator-onboarding-and-offboarding-start-validating.md b/.ai/pages/node-infrastructure-run-a-validator-onboarding-and-offboarding-start-validating.md new file mode 100644 index 000000000..3065d19f1 --- /dev/null +++ b/.ai/pages/node-infrastructure-run-a-validator-onboarding-and-offboarding-start-validating.md @@ -0,0 +1,255 @@ +--- +title: Start Validating +description: Learn how to start validating on Polkadot by choosing a network, syncing your node, bonding DOT tokens, and activating your validator. +categories: Infrastructure +url: https://docs.polkadot.com/node-infrastructure/run-a-validator/onboarding-and-offboarding/start-validating/ +--- + +# Start Validating + +## Introduction + +After configuring your node keys as shown in the [Key Management](/nodes-and-validators/run-a-validator/onboarding-and-offboarding/key-management/){target=\_blank} section and ensuring your system is set up, you're ready to begin the validator setup process. This guide will walk you through choosing a network, synchronizing your node with the blockchain, bonding your DOT tokens, and starting your validator. + +## Choose a Network + +Running your validator on a test network like Westend or Kusama is a smart way to familiarize yourself with the process and identify any setup issues in a lower-stakes environment before joining the Polkadot MainNet. + +- **Westend**: Polkadot's primary TestNet is open to anyone for testing purposes. Validator slots are intentionally limited to keep the network stable for the Polkadot release process, so it may not support as many validators at any given time. +- **Kusama**: Often called Polkadot's "canary network," Kusama has real economic value but operates with a faster and more experimental approach. Running a validator here provides an experience closer to MainNet with the benefit of more frequent validation opportunities with an era time of 6 hours vs 24 hours for Polkadot. +- **Polkadot**: The main network, where validators secure the Polkadot relay chain. It has a slower era time of 24 hours and requires a higher minimum bond amount to participate. + +## Synchronize Chain Data + +The next step is to sync your node with the chosen blockchain network. Synchronization is necessary to download and validate the blockchain data, ensuring your node is ready to participate as a validator. Follow these steps to sync your node: + +1. **Start syncing**: You can run a full or warp sync. + + === "Full sync" + + Polkadot defaults to using a full sync, which downloads and validates the entire blockchain history from the genesis block. Start the syncing process by running the following command: + + ```sh + polkadot + ``` + + This command starts your Polkadot node in non-validator mode, allowing you to synchronize the chain data. + + === "Warp sync" + + You can opt to use warp sync which initially downloads only GRANDPA finality proofs and the latest finalized block's state. Use the following command to start a warp sync: + + ``` bash + polkadot --sync warp + ``` + + Warp sync ensures that your node quickly updates to the latest finalized state. The historical blocks are downloaded in the background as the node continues to operate. + + If you're planning to run a validator on a TestNet, you can specify the chain using the `--chain` flag. For example, the following will run a validator on Kusama: + + ```sh + polkadot --chain=kusama + ``` + +2. **Monitor sync progress**: Once the sync starts, you will see a stream of logs providing information about the node's status and progress. Here's an example of what the output might look like: + +
+ polkadot + 2021-06-17 03:07:07 Parity Polkadot + 2021-06-17 03:07:07 ✌️ version 0.9.5-95f6aa201-x86_64-linux-gnu + 2021-06-17 03:07:07 ❤️ by Parity Technologies <admin@parity.io>, 2017-2021 + 2021-06-17 03:07:07 📋 Chain specification: Polkadot + 2021-06-17 03:07:07 🏷 Node name: boiling-pet-7554 + 2021-06-17 03:07:07 👤 Role: FULL + 2021-06-17 03:07:07 💾 Database: RocksDb at /root/.local/share/polkadot/chains/polkadot/db + 2021-06-17 03:07:07 ⛓ Native runtime: polkadot-9050 (parity-polkadot-0.tx7.au0) + 2021-06-17 03:07:10 🏷 Local node identity is: 12D3KooWLtXFWf1oGrnxMGmPKPW54xWCHAXHbFh4Eap6KXmxoi9u + 2021-06-17 03:07:10 📦 Highest known block at #17914 + 2021-06-17 03:07:10 〽️ Prometheus server started at 127.0.0.1:9615 + 2021-06-17 03:07:10 Listening for new connections on 127.0.0.1:9944 + ... +
+ + The output logs provide information such as the current block number, node name, and network connections. Monitor the sync progress and any errors that might occur during the process. Look for information about the latest processed block and compare it with the current highest block using tools like [Telemetry](https://telemetry.polkadot.io/#list/Polkadot%20CC1){target=\_blank} or [Polkadot.js Apps Explorer](https://polkadot.js.org/apps/#/explorer){target=\_blank}. + +### Database Snapshot Services + +If you'd like to speed up the process further, you can use a database snapshot. Snapshots are compressed backups of the blockchain's database directory and can significantly reduce the time required to sync a new node. Here are a few public snapshot providers: + +- [Stakeworld](https://stakeworld.io/snapshot){target=\_blank} +- [Polkachu](https://polkachu.com/substrate_snapshots){target=\_blank} +- [Polkashots](https://polkashots.io/){target=\_blank} +- [ITRocket](https://itrocket.net/services/mainnet/polkadot/#snapshot){target=\_blank} + +!!!warning + Although snapshots are convenient, syncing from scratch is recommended for security purposes. If snapshots become corrupted and most nodes rely on them, the network could inadvertently run on a non-canonical chain. + +
+ polkadot + 2021-06-17 03:07:07 Idle (0 peers), best: #0 (0x3fd7...5baf), finalized #0 (0x3fd7...5baf), ⬇ 2.9kiB/s ⬆ 3.7kiB/s + 2021-06-17 03:07:12 Idle (0 peers), best: #0 (0x3fd7...5baf), finalized #0 (0x3fd7...5baf), ⬇ 1.7kiB/s ⬆ 2.0kiB/s + 2021-06-17 03:07:17 Idle (0 peers), best: #0 (0x3fd7...5baf), finalized #0 (0x3fd7...5baf), ⬇ 0.9kiB/s ⬆ 1.2kiB/s + 2021-06-17 03:07:19 Libp2p => Random Kademlia query has yielded empty results + 2021-06-17 03:08:00 Idle (0 peers), best: #0 (0x3fd7...5baf), finalized #0 (0x3fd7...5baf), ⬇ 1.6kiB/s ⬆ 1.9kiB/s + 2021-06-17 03:08:05 Idle (0 peers), best: #0 (0x3fd7...5baf), finalized #0 (0x3fd7...5baf), ⬇ 0.6kiB/s ⬆ 0.9kiB/s + ... +
+ +If you see terminal output similar to the preceding, and you are unable to synchronize the chain due to having zero peers, make sure you have libp2p port `30333` activated. It will take some time to discover other peers over the network. + +## Bond DOT + +Once your validator node is synced, the next step is bonding DOT. A bonded account, or stash, holds your staked tokens (DOT) that back your validator node. Bonding your DOT means locking it for a period, during which it cannot be transferred or spent but is used to secure your validator's role in the network. Visit the [Minimum Bond Requirement](/nodes-and-validators/run-a-validator/requirements/#minimum-bond-requirement) section for details on how much DOT is required. + +The following sections will guide you through bonding DOT for your validator. + +### Bonding DOT on Polkadot.js Apps + +Once you're ready to bond your DOT, head over to the [Polkadot.js Apps](https://polkadot.js.org/apps/){target=\_blank} staking page by clicking the **Network** dropdown at the top of the page and selecting [**Staking**](https://polkadot.js.org/apps/#/staking/actions){target=\_blank}. + +To get started with the bond submission, click on the **Accounts** tab, then the **+ Stash** button, and then enter the following information: + +1. **Stash account**: Select your stash account (which is the account with the DOT/KSM balance). +2. **Value bonded**: Enter how much DOT from the stash account you want to bond/stake. You are not required to bond all of the DOT in that account and you may bond more DOT at a later time. Be aware, withdrawing any bonded amount requires waiting for the unbonding period. The unbonding period is seven days for Kusama and 28 days for Polkadot. +3. **Payment destination**: Add the recipient account for validator rewards. If you'd like to redirect payments to an account that is not the stash account, you can do it by entering the address here. Note that it is extremely unsafe to set an exchange address as the recipient of the staking rewards. + +Once everything is filled in properly, select **Bond** and sign the transaction with your stash account. If successful, you should see an `ExtrinsicSuccess` message. + +Your bonded account will be available under **Stashes**. After refreshing the screen, you should now see a card with all your accounts. The bonded amount on the right corresponds to the funds bonded by the stash account. + +## Validate + +Once your validator node is fully synced and ready, the next step is to ensure it's visible on the network and performing as expected. Below are steps for monitoring and managing your node on the Polkadot network. + +### Verify Sync via Telemetry + +To confirm that your validator is live and synchronized with the Polkadot network, visit the [Telemetry](https://telemetry.polkadot.io/#list/Polkadot%20CC1){target=\_blank} page. Telemetry provides real-time information on node performance and can help you check if your validator is connected properly. Search for your node by name. You can search all nodes currently active on the network, which is why you should use a unique name for easy recognition. Now, confirm that your node is fully synced by comparing the block height of your node with the network's latest block. Nodes that are fully synced will appear white in the list, while nodes that are not yet fully synced will appear gray. + +### Activate using Polkadot.js Apps + +Follow these steps to use Polkadot.js Apps to activate your validator: + +1. In Polkadot.js Apps, navigate to **Network** and select **Staking**: + + ![](/images/nodes-and-validators/run-a-validator/onboarding-and-offboarding/start-validating/start-validating-01.webp) + +2. Open the **Accounts** tab and click on **+ Validator**: + + ![](/images/nodes-and-validators/run-a-validator/onboarding-and-offboarding/start-validating/start-validating-02.webp) + +3. Set a bond amount in the **value bonded** field and then click **next**: + + ![](/images/nodes-and-validators/run-a-validator/onboarding-and-offboarding/start-validating/start-validating-03.webp) + +4. Paste the hex output from `author_rotateKeys`, set the commission, allow or block new nominations, then click **Bond & Validate** to link your validator with its session keys. + + ![](/images/nodes-and-validators/run-a-validator/onboarding-and-offboarding/start-validating/start-validating-04.webp) + + You can also set the **commission** and **blocked** nominations option via `staking.validate` extrinsic. By default, the blocked option is set to FALSE (i.e., the validator accepts nominations). + + ![](/images/nodes-and-validators/run-a-validator/onboarding-and-offboarding/start-validating/start-validating-05.webp) + + +### Monitor Validation Status and Slots + +On the [**Staking**](https://polkadot.js.org/apps/#/staking){target=\_blank} tab in Polkadot.js Apps, you can see your validator's status, the number of available validator slots, and the nodes that have signaled their intent to validate. Your node may initially appear in the waiting queue, especially if the validator slots are full. The following is an example view of the **Staking** tab: + +![staking queue](/images/nodes-and-validators/run-a-validator/onboarding-and-offboarding/start-validating/start-validating-06.webp) + +The validator set refreshes each era. If there's an available slot in the next era, your node may be selected to move from the waiting queue to the active validator set, allowing it to start validating blocks. If your validator is not selected, it remains in the waiting queue. Increasing your stake or gaining more nominators may improve your chance of being selected in future eras. + +## Run a Validator Using Systemd + +Running your Polkadot validator as a [systemd](https://en.wikipedia.org/wiki/Systemd){target=\_blank} service is an effective way to ensure its high uptime and reliability. Using systemd allows your validator to automatically restart after server reboots or unexpected crashes, significantly reducing the risk of slashing due to downtime. + +This following sections will walk you through creating and managing a systemd service for your validator, allowing you to seamlessly monitor and control it as part of your Linux system. + +Ensure the following requirements are met before proceeding with the systemd setup: + +- Confirm your system meets the [requirements](/nodes-and-validators/run-a-validator/requirements/){target=\_blank} for running a validator. +- Ensure you meet the [minimum bond requirements](https://wiki.polkadot.com/general/chain-state-values/#minimum-validator-bond){target=\_blank} for validating. +- Verify the Polkadot binary is [installed](#install-the-polkadot-binaries). + +### Create the Systemd Service File + +First create a new unit file called `polkadot-validator.service` in `/etc/systemd/system/`: + +```bash +touch /etc/systemd/system/polkadot-validator.service +``` + +In this unit file, you will write the commands that you want to run on server boot/restart: + +```systemd title="/etc/systemd/system/polkadot-validator.service" +[Unit] +Description=Polkadot Node +After=network.target +Documentation=https://github.com/paritytech/polkadot-sdk + +[Service] +EnvironmentFile=-/etc/default/polkadot +ExecStart=/usr/bin/polkadot $POLKADOT_CLI_ARGS +User=polkadot +Group=polkadot +Restart=always +RestartSec=120 +CapabilityBoundingSet= +LockPersonality=true +NoNewPrivileges=true +PrivateDevices=true +PrivateMounts=true +PrivateTmp=true +PrivateUsers=true +ProtectClock=true +ProtectControlGroups=true +ProtectHostname=true +ProtectKernelModules=true +ProtectKernelTunables=true +ProtectSystem=strict +RemoveIPC=true +RestrictAddressFamilies=AF_INET AF_INET6 AF_NETLINK AF_UNIX +RestrictNamespaces=false +RestrictSUIDSGID=true +SystemCallArchitectures=native +SystemCallFilter=@system-service +SystemCallFilter=landlock_add_rule landlock_create_ruleset landlock_restrict_self seccomp mount umount2 +SystemCallFilter=~@clock @module @reboot @swap @privileged +SystemCallFilter=pivot_root +UMask=0027 + +[Install] +WantedBy=multi-user.target +``` + +!!! warning "Restart delay and equivocation risk" + It is recommended that a node's restart be delayed with `RestartSec` in the case of a crash. It's possible that when a node crashes, consensus votes in GRANDPA aren't persisted to disk. In this case, there is potential to equivocate when immediately restarting. Delaying the restart will allow the network to progress past potentially conflicting votes. + +### Run the Service + +Activate the systemd service to start on system boot by running: + +```bash +systemctl enable polkadot-validator.service +``` + +To start the service manually, use: + +```bash +systemctl start polkadot-validator.service +``` + +Check the service's status to confirm it is running: + +```bash +systemctl status polkadot-validator.service +``` + +To view the logs in real-time, use [journalctl](https://www.freedesktop.org/software/systemd/man/latest/journalctl.html){target=\_blank} like so: + +```bash +journalctl -f -u polkadot-validator +``` + +With these steps, you can effectively manage and monitor your validator as a systemd service. + +Once your validator is active, it's officially part of Polkadot's security infrastructure. For questions or further support, you can reach out to the [Polkadot Validator chat](https://matrix.to/#/!NZrbtteFeqYKCUGQtr:matrix.parity.io?via=matrix.parity.io&via=matrix.org&via=web3.foundation){target=\_blank} for tips and troubleshooting. diff --git a/.ai/pages/node-infrastructure-run-a-validator-onboarding-and-offboarding-stop-validating.md b/.ai/pages/node-infrastructure-run-a-validator-onboarding-and-offboarding-stop-validating.md new file mode 100644 index 000000000..5cff77ad4 --- /dev/null +++ b/.ai/pages/node-infrastructure-run-a-validator-onboarding-and-offboarding-stop-validating.md @@ -0,0 +1,45 @@ +--- +title: Stop Validating +description: Learn to safely stop validating on Polkadot, including chilling, unbonding tokens, and purging validator keys. +categories: Infrastructure +url: https://docs.polkadot.com/node-infrastructure/run-a-validator/onboarding-and-offboarding/stop-validating/ +--- + +# Stop Validating + +## Introduction + +If you're ready to stop validating on Polkadot, there are essential steps to ensure a smooth transition while protecting your funds and account integrity. Whether you're taking a break for maintenance or unbonding entirely, you'll need to chill your validator, purge session keys, and unbond your tokens. This guide explains how to use Polkadot's tools and extrinsics to safely withdraw from validation activities, safeguarding your account's future usability. + +## Pause Versus Stop + +If you wish to remain a validator or nominator (for example, stopping for planned downtime or server maintenance), submitting the `chill` extrinsic in the `staking` pallet should suffice. Additional steps are only needed to unbond funds or reap an account. + +The following are steps to ensure a smooth stop to validation: + +- Chill the validator. +- Purge validator session keys. +- Unbond your tokens. + +## Chill Validator + +When stepping back from validating, the first step is to chill your validator status. This action stops your validator from being considered for the next era without fully unbonding your tokens, which can be useful for temporary pauses like maintenance or planned downtime. + +Use the `staking.chill` extrinsic to initiate this. For more guidance on chilling your node, refer to the [Pause Validating](/nodes-and-validators/run-a-validator/operational-tasks/pause-validating/){target=\_blank} guide. You may also claim any pending staking rewards at this point. + +## Purge Validator Session Keys + +Purging validator session keys is a critical step in removing the association between your validator account and its session keys, which ensures that your account is fully disassociated from validator activities. The `session.purgeKeys` extrinsic removes the reference to your session keys from the stash or staking proxy account that originally set them. + +Here are a couple of important things to know about purging keys: + +- **Account used to purge keys**: Always use the same account to purge keys you originally used to set them, usually your stash or staking proxy account. Using a different account may leave an unremovable reference to the session keys on the original account, preventing its reaping. +- **Account reaping issue**: Failing to purge keys will prevent you from reaping (fully deleting) your stash account. If you attempt to transfer tokens without purging, you'll need to rebond, purge the session keys, unbond again, and wait through the unbonding period before any transfer. + +## Unbond Your Tokens + +After chilling your node and purging session keys, the final step is to unbond your staked tokens. This action removes them from staking and begins the unbonding period (usually 28 days for Polkadot and seven days for Kusama), after which the tokens will be transferable. + +To unbond tokens, go to **Network > Staking > Account Actions** on Polkadot.js Apps. Select your stash account, click on the dropdown menu, and choose **Unbond Funds**. Alternatively, you can use the `staking.unbond` extrinsic if you handle this via a staking proxy account. + +Once the unbonding period is complete, your tokens will be available for use in transactions or transfers outside of staking. diff --git a/.ai/pages/node-infrastructure-run-a-validator-operational-tasks-general-management.md b/.ai/pages/node-infrastructure-run-a-validator-operational-tasks-general-management.md new file mode 100644 index 000000000..9c8ac6502 --- /dev/null +++ b/.ai/pages/node-infrastructure-run-a-validator-operational-tasks-general-management.md @@ -0,0 +1,722 @@ +--- +title: General Management +description: Optimize your Polkadot validator setup with advanced configuration techniques. Learn how to boost performance, enhance security, and ensure seamless operations. +categories: Infrastructure +url: https://docs.polkadot.com/node-infrastructure/run-a-validator/operational-tasks/general-management/ +--- + +# General Management + +## Introduction + +Validator performance is pivotal in maintaining the security and stability of the Polkadot network. As a validator, optimizing your setup ensures efficient transaction processing, minimizes latency, and maintains system reliability during high-demand periods. Proper configuration and proactive monitoring also help mitigate risks like slashing and service interruptions. + +This guide covers essential practices for managing a validator, including performance tuning techniques, security hardening, and tools for real-time monitoring. Whether you're fine-tuning CPU settings, configuring NUMA balancing, or setting up a robust alert system, these steps will help you build a resilient and efficient validator operation. + +## Configuration Optimization + +For those seeking to optimize their validator's performance, the following configurations can improve responsiveness, reduce latency, and ensure consistent performance during high-demand periods. + +### Deactivate Simultaneous Multithreading + +Polkadot validators operate primarily in single-threaded mode for critical tasks, so optimizing single-core CPU performance can reduce latency and improve stability. Deactivating simultaneous multithreading (SMT) can prevent virtual cores from affecting performance. SMT is called Hyper-Threading on Intel and 2-way SMT on AMD Zen. + +Take the following steps to deactivate every other (vCPU) core: + +1. Loop though all the CPU cores and deactivate the virtual cores associated with them: + + ```bash + for cpunum in $(cat /sys/devices/system/cpu/cpu*/topology/thread_siblings_list | \ + cut -s -d, -f2- | tr ',' '\n' | sort -un) + do + echo 0 > /sys/devices/system/cpu/cpu$cpunum/online + done + ``` + +2. To permanently save the changes, add `nosmt=force` to the `GRUB_CMDLINE_LINUX_DEFAULT` variable in `/etc/default/grub`: + + ```bash + sudo nano /etc/default/grub + # Add to GRUB_CMDLINE_LINUX_DEFAULT + ``` + + ```config title="/etc/default/grub" + GRUB_DEFAULT = 0; + GRUB_HIDDEN_TIMEOUT = 0; + GRUB_HIDDEN_TIMEOUT_QUIET = true; + GRUB_TIMEOUT = 10; + GRUB_DISTRIBUTOR = `lsb_release -i -s 2> /dev/null || echo Debian`; + GRUB_CMDLINE_LINUX_DEFAULT = 'nosmt=force'; + GRUB_CMDLINE_LINUX = ''; + ``` + +3. Update GRUB to apply changes: + + ```bash + sudo update-grub + ``` + +4. After the reboot, you should see that half of the cores are offline. To confirm, run: + + ```bash + lscpu --extended + ``` + +### Deactivate Automatic NUMA Balancing + +Deactivating NUMA (Non-Uniform Memory Access) balancing for multi-CPU setups helps keep processes on the same CPU node, minimizing latency. + +Follow these stpes: + +1. Deactivate NUMA balancing in runtime: + + ```bash + sysctl kernel.numa_balancing=0 + ``` + +2. Deactivate NUMA balancing permanently by adding `numa_balancing=disable` to the GRUB settings: + + ```bash + sudo nano /etc/default/grub + # Add to GRUB_CMDLINE_LINUX_DEFAULT + ``` + + ```config title="/etc/default/grub" + GRUB_DEFAULT = 0; + GRUB_HIDDEN_TIMEOUT = 0; + GRUB_HIDDEN_TIMEOUT_QUIET = true; + GRUB_TIMEOUT = 10; + GRUB_DISTRIBUTOR = `lsb_release -i -s 2> /dev/null || echo Debian`; + GRUB_CMDLINE_LINUX_DEFAULT = 'numa_balancing=disable'; + GRUB_CMDLINE_LINUX = ''; + ``` + +3. Update GRUB to apply changes: + + ```bash + sudo update-grub + ``` + +4. Confirm the deactivation: + + ```bash + sysctl -a | grep 'kernel.numa_balancing' + ``` + +If you successfully deactivated NUMA balancing, the preceding command should return `0`. + +### Spectre and Meltdown Mitigations + +[Spectre](https://en.wikipedia.org/wiki/Spectre_(security_vulnerability)){target=\_blank} and [Meltdown](https://en.wikipedia.org/wiki/Meltdown_(security_vulnerability)){target=\_blank} are well-known CPU vulnerabilities that exploit speculative execution to access sensitive data. These vulnerabilities have been patched in recent Linux kernels, but the mitigations can slightly impact performance, especially in high-throughput or containerized environments. + +If your security requirements allow it, you can deactivate specific mitigations, such as Spectre V2 and Speculative Store Bypass Disable (SSBD), to improve performance. + +To selectively deactivate the Spectre mitigations, take these steps: + +1. Update the `GRUB_CMDLINE_LINUX_DEFAULT` variable in your `/etc/default/grub` configuration: + + ```bash + sudo nano /etc/default/grub + # Add to GRUB_CMDLINE_LINUX_DEFAULT + ``` + + ```config title="/etc/default/grub" + GRUB_DEFAULT = 0; + GRUB_HIDDEN_TIMEOUT = 0; + GRUB_HIDDEN_TIMEOUT_QUIET = true; + GRUB_TIMEOUT = 10; + GRUB_DISTRIBUTOR = `lsb_release -i -s 2> /dev/null || echo Debian`; + GRUB_CMDLINE_LINUX_DEFAULT = + 'spec_store_bypass_disable=prctl spectre_v2_user=prctl'; + ``` + +2. Update GRUB to apply changes and then reboot: + + ```bash + sudo update-grub + sudo reboot + ``` + +This approach selectively deactivates the Spectre V2 and Spectre V4 mitigations, leaving other protections intact. For full security, keep mitigations activated unless there's a significant performance need, as disabling them could expose the system to potential attacks on affected CPUs. + +## Monitor Your Node + +Monitoring your node's performance is critical for network reliability and security. Tools like the following provide valuable insights: + +- **[Prometheus](https://prometheus.io/){target=\_blank}**: An open-source monitoring toolkit for collecting and querying time-series data. +- **[Grafana](https://grafana.com/){target=\_blank}**: A visualization tool for real-time metrics, providing interactive dashboards. +- **[Alertmanager](https://prometheus.io/docs/alerting/latest/alertmanager/){target=\_blank}**: A tool for managing and routing alerts based on Prometheus data. + +This section covers setting up these tools and configuring alerts to notify you of potential issues. + +### Environment Setup + +Before installing Prometheus, ensure the environment is set up securely by running Prometheus with restricted user privileges. + +Follow these steps: + +1. Create a Prometheus user to ensure Prometheus runs with minimal permissions: + + ```bash + sudo useradd --no-create-home --shell /usr/sbin/nologin prometheus + ``` + +2. Create directories for configuration and data storage: + + ```bash + sudo mkdir /etc/prometheus + sudo mkdir /var/lib/prometheus + ``` + +3. Change directory ownership to ensure Prometheus has access: + + ```bash + sudo chown -R prometheus:prometheus /etc/prometheus + sudo chown -R prometheus:prometheus /var/lib/prometheus + ``` + +### Install and Configure Prometheus + +After setting up the environment, install and configure the latest version of Prometheus as follows: + +1. Download Prometheus for your system architecture from the [releases page](https://github.com/prometheus/prometheus/releases/){target=\_blank}. Replace `INSERT_RELEASE_DOWNLOAD` with the release binary URL (e.g., `https://github.com/prometheus/prometheus/releases/download/v3.0.0/prometheus-3.0.0.linux-amd64.tar.gz`): + + ```bash + sudo apt-get update && sudo apt-get upgrade + wget INSERT_RELEASE_DOWNLOAD_LINK + tar xfz prometheus-*.tar.gz + cd prometheus-3.0.0.linux-amd64 + ``` + +2. Set up Prometheus: + + 1. Copy binaries: + + ```bash + sudo cp ./prometheus /usr/local/bin/ + sudo cp ./promtool /usr/local/bin/ + sudo cp ./prometheus /usr/local/bin/ + ``` + + 2. Copy directories and assign ownership of these files to the `prometheus` user: + + ```bash + sudo cp -r ./consoles /etc/prometheus + sudo cp -r ./console_libraries /etc/prometheus + sudo chown -R prometheus:prometheus /etc/prometheus/consoles + sudo chown -R prometheus:prometheus /etc/prometheus/console_libraries + ``` + + 3. Clean up the download directory: + + ```bash + cd .. && rm -r prometheus* + ``` + +3. Create `prometheus.yml` to define global settings, rule files, and scrape targets: + + ```bash + sudo nano /etc/prometheus/prometheus.yml + ``` + + {% raw %} + ```yaml title="prometheus-config.yml" + global: + scrape_interval: 15s + evaluation_interval: 15s + + rule_files: + # - "first.rules" + # - "second.rules" + + scrape_configs: + - job_name: 'prometheus' + scrape_interval: 5s + static_configs: + - targets: ['localhost:9090'] + - job_name: 'substrate_node' + scrape_interval: 5s + static_configs: + - targets: ['localhost:9615'] + ``` + {% endraw %} + + Prometheus is scraped every 5 seconds in this example configuration file, ensuring detailed internal metrics. Node metrics with customizable intervals are scraped from port `9615` by default. + +4. Verify the configuration with `promtool`, an open source monitoring tool: + + ```bash + promtool check config /etc/prometheus/prometheus.yml + ``` + +5. Save the configuration and change the ownership of the file to `prometheus` user: + + ```bash + sudo chown prometheus:prometheus /etc/prometheus/prometheus.yml + ``` + +### Start Prometheus + +1. Launch Prometheus with the appropriate configuration file, storage location, and necessary web resources, running it with restricted privileges for security: + + ```bash + sudo -u prometheus /usr/local/bin/prometheus --config.file /etc/prometheus/prometheus.yml \ + --storage.tsdb.path /var/lib/prometheus/ \ + --web.console.templates=/etc/prometheus/consoles \ + --web.console.libraries=/etc/prometheus/console_libraries + ``` + + If you set the server up properly, you should see terminal output similar to the following: + + +2. Verify you can access the Prometheus interface by navigating to: + + ```text + http://SERVER_IP_ADDRESS:9090/graph + ``` + + If the interface appears to work as expected, exit the process using `Control + C`. + +3. Create a systemd service file to ensure Prometheus starts on boot: + + ```bash + sudo nano /etc/systemd/system/prometheus.service + ``` + + ```bash title="prometheus.service" + [Unit] + Description=Prometheus Monitoring + Wants=network-online.target + After=network-online.target + + [Service] + User=prometheus + Group=prometheus + Type=simple + ExecStart=/usr/local/bin/prometheus \ + --config.file /etc/prometheus/prometheus.yml \ + --storage.tsdb.path /var/lib/prometheus/ \ + --web.console.templates=/etc/prometheus/consoles \ + --web.console.libraries=/etc/prometheus/console_libraries + ExecReload=/bin/kill -HUP $MAINPID + + [Install] + WantedBy=multi-user.target + + ``` + +4. Reload systemd and enable the service to start on boot: + + ```bash + sudo systemctl daemon-reload && sudo systemctl enable prometheus && sudo systemctl start prometheus + ``` + +5. Verify the service is running by visiting the Prometheus interface again at: + + ```text + http://SERVER_IP_ADDRESS:9090/ + ``` + +### Install and Configure Grafana + +This guide follows [Grafana's canonical installation instructions](https://grafana.com/docs/grafana/latest/setup-grafana/installation/debian/#install-from-apt-repository){target=\_blank}. + +To install and configure Grafana, follow these steps: + +1. Install Grafana prerequisites: + + ```bash + sudo apt-get install -y apt-transport-https software-properties-common wget + ``` + +2. Import the [GPG key](https://gnupg.org/){target=\_blank}: + + ```bash + sudo mkdir -p /etc/apt/keyrings/ + wget -q -O - https://apt.grafana.com/gpg.key | gpg --dearmor | sudo tee /etc/apt/keyrings/grafana.gpg > /dev/null + ``` + +3. Configure the stable release repo and update packages: + + ```bash + echo "deb [signed-by=/etc/apt/keyrings/grafana.gpg] https://apt.grafana.com stable main" | sudo tee -a /etc/apt/sources.list.d/grafana.list + sudo apt-get update + ``` + +4. Install the latest stable version of Grafana: + + ```bash + sudo apt-get install grafana + ``` + +To configure Grafana, take these steps: + +1. Configure Grafana to start automatically on boot and start the service: + + ```bash + sudo systemctl daemon-reload + sudo systemctl enable grafana-server.service + sudo systemctl start grafana-server + ``` + +2. Check if Grafana is running: + + ```bash + sudo systemctl status grafana-server + ``` + + If necessary, you can stop or restart the service with the following commands: + + ```bash + sudo systemctl stop grafana-server + sudo systemctl restart grafana-server + ``` + +3. Access Grafana by navigating to the following URL and logging in with the default username and password (`admin`): + + ```text + http://SERVER_IP_ADDRESS:3000/login + ``` + + !!! tip "Change default port" + To change Grafana's port, edit `/usr/share/grafana/conf/defaults.ini`: + + ```bash + sudo vim /usr/share/grafana/conf/defaults.ini + ``` + + Modify the `http_port` value, then restart Grafana: + + ```bash + sudo systemctl restart grafana-server + ``` + +![Grafana login screen](/images/nodes-and-validators/run-a-validator/operational-tasks/general-management/general-management-01.webp) + +To visualize node metrics, follow these steps: + +1. Select the gear icon to access **Data Sources** settings. +2. Select **Add data source** to define the data source. + + ![Select Prometheus](/images/nodes-and-validators/run-a-validator/operational-tasks/general-management/general-management-02.webp) + +3. Select **Prometheus**. + + ![Save and test](/images/nodes-and-validators/run-a-validator/operational-tasks/general-management/general-management-03.webp) + +4. Enter `http://localhost:9090` in the **URL** field and click **Save & Test**. If **"Data source is working"** appears, your connection is configured correctly. + + ![Import dashboard](/images/nodes-and-validators/run-a-validator/operational-tasks/general-management/general-management-04.webp) + +5. Select **Import** from the left menu, choose **Prometheus** from the dropdown, and click **Import**. + +6. Start your Polkadot node by running `./polkadot`. You should now be able to monitor node performance, block height, network traffic, and tasks tasks on the Grafana dashboard. + + ![Live dashboard](/images/nodes-and-validators/run-a-validator/operational-tasks/general-management/general-management-05.webp) + +The [Grafana dashboards](https://grafana.com/grafana/dashboards){target=\_blank} page features user created dashboards made available for public use. For an example, see the [Substrate Node Metrics](https://grafana.com/grafana/dashboards/21715-substrate-node-metrics/){target=\_blank} dashboard. + +### Install and Configure Alertmanager + +[Alertmanager](https://prometheus.io/docs/alerting/latest/alertmanager/){target=\_blank} is an optional component that complements Prometheus by managing alerts and notifying users about potential issues. + +Follow these steps to install and configure Alertmanager: + +1. Download Alertmanager for your system architecture from the [releases page](https://github.com/prometheus/alertmanager/releases){target=\_blank}. Replace `INSERT_RELEASE_DOWNLOAD` with the release binary URL (e.g., `https://github.com/prometheus/alertmanager/releases/download/v0.28.0-rc.0/alertmanager-0.28.0-rc.0.linux-amd64.tar.gz`): + + ```bash + wget INSERT_RELEASE_DOWNLOAD_LINK + tar -xvzf alertmanager* + ``` + +2. Copy the binaries to the system directory and set permissions: + + ```bash + cd alertmanager-0.28.0-rc.0.linux-amd64 + sudo cp ./alertmanager /usr/local/bin/ + sudo cp ./amtool /usr/local/bin/ + sudo chown prometheus:prometheus /usr/local/bin/alertmanager + sudo chown prometheus:prometheus /usr/local/bin/amtool + ``` + +3. Create the `alertmanager.yml` configuration file under `/etc/alertmanager`: + + ```bash + sudo mkdir /etc/alertmanager + sudo nano /etc/alertmanager/alertmanager.yml + ``` + + Generate an [app password in your Google account](https://support.google.com/accounts/answer/185833?hl=en){target=\_blank} to enable email notifications from Alertmanager. Then, add the following code to the configuration file to define email notifications using your email and app password: + + {% raw %} + ```yml title="alertmanager.yml" + global: + resolve_timeout: 1m + + route: + receiver: 'gmail-notifications' + + receivers: + - name: 'gmail-notifications' + email_configs: + - to: INSERT_YOUR_EMAIL + from: INSERT_YOUR_EMAIL + smarthost: smtp.gmail.com:587 + auth_username: INSERT_YOUR_EMAIL + auth_identity: INSERT_YOUR_EMAIL + auth_password: INSERT_YOUR_APP_PASSWORD + send_resolved: true + + ``` + {% endraw %} + + + ```bash + sudo chown -R prometheus:prometheus /etc/alertmanager + ``` + +4. Configure Alertmanager as a service by creating a systemd service file: + + ```bash + sudo nano /etc/systemd/system/alertmanager.service + ``` + + {% raw %} + ```yml title="alertmanager.service" + [Unit] + Description=AlertManager Server Service + Wants=network-online.target + After=network-online.target + + [Service] + User=root + Group=root + Type=simple + ExecStart=/usr/local/bin/alertmanager --config.file /etc/alertmanager/alertmanager.yml --web.external-url=http://SERVER_IP:9093 --cluster.advertise-address='0.0.0.0:9093' + + [Install] + WantedBy=multi-user.target + + ``` + {% endraw %} + +5. Reload and enable the service: + + ```bash + sudo systemctl daemon-reload + sudo systemctl enable alertmanager + sudo systemctl start alertmanager + ``` + +6. Verify the service status: + + ```bash + sudo systemctl status alertmanager + ``` + + If you have configured Alertmanager properly, the **Active** field should display **active (running)** similar to below: + +
+ sudo systemctl status alertmanager + alertmanager.service - AlertManager Server Service + Loaded: loaded (/etc/systemd/system/alertmanager.service; enabled; vendor preset: enabled) + Active: active (running) since Thu 2020-08-20 22:01:21 CEST; 3 days ago + Main PID: 20592 (alertmanager) + Tasks: 70 (limit: 9830) + CGroup: /system.slice/alertmanager.service + +
+ +#### Grafana Plugin + +There is an [Alertmanager plugin in Grafana](https://grafana.com/grafana/plugins/alertmanager/){target=\_blank} that can help you monitor alert information. + +Follow these steps to use the plugin: + +1. Install the plugin: + + ```bash + sudo grafana-cli plugins install camptocamp-prometheus-alertmanager-datasource + ``` + +2. Restart Grafana: + + ```bash + sudo systemctl restart grafana-server + ``` + +3. Configure Alertmanager as a data source in your Grafana dashboard (`SERVER_IP:3000`): + + 1. Go to **Configuration** > **Data Sources** and search for **Prometheus Alertmanager**. + 2. Enter the server URL and port for the Alertmanager service, and select **Save & Test** to verify the connection. + +4. Import the [8010](https://grafana.com/grafana/dashboards/8010-prometheus-alertmanager/){target=\_blank} dashboard for Alertmanager, selecting **Prometheus Alertmanager** in the last column, then select **Import**. + +#### Integrate Alertmanager + +Complete the integration by following these steps to enable communication between Prometheus and Alertmanager and configure detection and alert rules: + +1. Update the `etc/prometheus/prometheus.yml` configuration file to include the following code: + + {% raw %} + ```yml title="prometheus.yml" + rule_files: + - 'rules.yml' + + alerting: + alertmanagers: + - static_configs: + - targets: + - localhost:9093 + ``` + {% endraw %} + + Expand the following item to view the complete `prometheus.yml` file. + + ??? code "prometheus.yml" + + {% raw %} + ```yml title="prometheus.yml" + global: + scrape_interval: 15s + evaluation_interval: 15s + + rule_files: + - 'rules.yml' + + alerting: + alertmanagers: + - static_configs: + - targets: + - localhost:9093 + + scrape_configs: + - job_name: 'prometheus' + scrape_interval: 5s + static_configs: + - targets: ['localhost:9090'] + - job_name: 'substrate_node' + scrape_interval: 5s + static_configs: + - targets: ['localhost:9615'] + + ``` + {% endraw %} + +2. Create the rules file for detection and alerts: + + ```bash + sudo nano /etc/prometheus/rules.yml + ``` + + Add a sample rule to trigger email notifications for node downtime over five minutes: + + {% raw %} + ```yml title="rules.yml" + groups: + - name: alert_rules + rules: + - alert: InstanceDown + expr: up == 0 + for: 5m + labels: + severity: critical + annotations: + summary: 'Instance [{{ $labels.instance }}] down' + description: '[{{ $labels.instance }}] of job [{{ $labels.job }}] has been down for more than 5 minutes.' + + ``` + {% endraw %} + + If any of the conditions defined in the rules file are met, an alert will be triggered. For more on alert rules, refer to [Alerting Rules](https://prometheus.io/docs/prometheus/latest/configuration/alerting_rules/){target=\_blank} and [additional alerts](https://samber.github.io/awesome-prometheus-alerts/rules.html){target=\_blank}. + +3. Update the file ownership to `prometheus`: + + ```bash + sudo chown prometheus:prometheus rules.yml + ``` + +4. Validate the rules syntax: + + ```bash + sudo -u prometheus promtool check rules rules.yml + ``` + +5. Restart Prometheus and Alertmanager: + + ```bash + sudo systemctl restart prometheus && sudo systemctl restart alertmanager + ``` + +Now you will receive an email alert if one of your rule triggering conditions is met. + +## Secure Your Validator + +Validators in Polkadot's Proof of Stake (PoS) network play a critical role in maintaining network integrity and security by keeping the network in consensus and verifying state transitions. To ensure optimal performance and minimize risks, validators must adhere to strict guidelines around security and reliable operations. + +### Key Management + +Though they don't transfer funds, session keys are essential for validators as they sign messages related to consensus and parachains. Securing session keys is crucial as allowing them to be exploited or used across multiple nodes can lead to a loss of staked funds via [slashing](/nodes-and-validators/run-a-validator/staking-mechanics/offenses-and-slashes/){target=\_blank}. + +Given the current limitations in high-availability setups and the risks associated with double-signing, it’s recommended to run only a single validator instance. Keys should be securely managed, and processes automated to minimize human error. + +There are two approaches for generating session keys: + +- **Generate and store in node**: Using the `author.rotateKeys` RPC call. For most users, generating keys directly within the client is recommended. You must submit a session certificate from your staking proxy to register new keys. See the [How to Validate](/nodes-and-validators/run-a-validator/onboarding-and-offboarding/set-up-validator/){target=\_blank} guide for instructions on setting keys. + +- **Generate outside node and insert**: Using the `author.setKeys` RPC call. This flexibility accommodates advanced security setups and should only be used by experienced validator operators. + +### Signing Outside the Client + +Polkadot plans to support external signing, allowing session keys to reside in secure environments like Hardware Security Modules (HSMs). However, these modules can sign any payload they receive, potentially enabling an attacker to perform slashable actions. + +### Secure-Validator Mode + +Polkadot's Secure-Validator mode offers an extra layer of protection through strict filesystem, networking, and process sandboxing. This secure mode is activated by default if the machine meets the following requirements: + +- **Linux (x86-64 architecture)**: Usually Intel or AMD. +- **Enabled `seccomp`**: This kernel feature facilitates a more secure approach for process management on Linux. Verify by running. + + ```bash + cat /boot/config-`uname -r` | grep CONFIG_SECCOMP= + ``` + + If `seccomp` is enabled, you should see output similar to the following: + + ```bash + CONFIG_SECCOMP=y + ``` + +!!! tip + Optionally, **Linux 5.13** may also be used, as it provides access to even more strict filesystem protections. + +### Linux Best Practices + +Follow these best practices to keep your validator secure: + +- Use a non-root user for all operations. +- Regularly apply OS security patches. +- Enable and configure a firewall. +- Use key-based SSH authentication; deactivate password-based login. +- Regularly back up data and harden your SSH configuration. Visit this [SSH guide](https://blog.stribik.technology/2015/01/04/secure-secure-shell.html){target=\_blank} for more details. + +### Validator Best Practices + +Additional best practices can add an additional layer of security and operational reliability: + +- Only run the Polkadot binary, and only listen on the configured p2p port. +- Run on bare-metal machines, as opposed to virtual machines. +- Provisioning of the validator machine should be automated and defined in code which is kept in private version control, reviewed, audited, and tested. +- Generate and provide session keys in a secure way. +- Start Polkadot at boot and restart if stopped for any reason. +- Run Polkadot as a non-root user. +- Establish and maintain an on-call rotation for managing alerts. +- Establish and maintain a clear protocol with actions to perform for each level of each alert with an escalation policy. + +## Additional Resources + +- [Certus One's Knowledge Base](https://knowledgebase.certus.com/FAQ/){target=\_blank} +- [EOS Block Producer Security List](https://github.com/slowmist/eos-bp-nodes-security-checklist){target=\_blank} +- [HSM Policies and the Importance of Validator Security](https://medium.com/loom-network/hsm-policies-and-the-importance-of-validator-security-ec8a4cc1b6f){target=\_blank} + +For additional guidance, connect with other validators and the Polkadot engineering team in the [Polkadot Validator Lounge](https://matrix.to/#/#polkadotvalidatorlounge:web3.foundation){target=\_blank} on Element. diff --git a/.ai/pages/node-infrastructure-run-a-validator-operational-tasks-pause-validating.md b/.ai/pages/node-infrastructure-run-a-validator-operational-tasks-pause-validating.md new file mode 100644 index 000000000..154270d5e --- /dev/null +++ b/.ai/pages/node-infrastructure-run-a-validator-operational-tasks-pause-validating.md @@ -0,0 +1,46 @@ +--- +title: Pause Validating +description: Learn how to temporarily pause staking activity in Polkadot using the chill extrinsic, with guidance for validators and nominators. +categories: Infrastructure +url: https://docs.polkadot.com/node-infrastructure/run-a-validator/operational-tasks/pause-validating/ +--- + +# Pause Validating + +## Introduction + +If you need to temporarily stop participating in Polkadot staking activities without fully unbonding your funds, chilling your account allows you to do so efficiently. Chilling removes your node from active validation or nomination in the next era while keeping your funds bonded, making it ideal for planned downtimes or temporary pauses. + +This guide covers the steps for chilling as a validator or nominator, using the `chill` and `chillOther` extrinsics, and how these affect your staking status and nominations. + +## Chilling Your Node + +If you need to temporarily step back from staking without unbonding your funds, you can "chill" your account. Chilling pauses your active staking participation, setting your account to inactive in the next era while keeping your funds bonded. + +To chill your account, go to the **Network > Staking > Account Actions** page on [Polkadot.js Apps](https://polkadot.js.org/apps){target=\_blank}, and select **Stop**. Alternatively, you can call the [`chill`](https://paritytech.github.io/polkadot-sdk/master/pallet_staking/enum.Call.html#variant.chill){target=\_blank} extrinsic in the Staking pallet. + +## Staking Election Timing Considerations + +When a node actively participates in staking but then chills, it will continue contributing for the remainder of the current era. However, its eligibility for the next election depends on the chill status at the start of the new era: + +- **Chilled during previous era**: Will not participate in the current era election and will remain inactive until reactivated. +- **Chilled during current era**: Will not be selected for the next era's election. +- **Chilled after current era**: May be selected if it was active during the previous era and is now chilled. + +## Chilling as a Nominator + +When you choose to chill as a nominator, your active nominations are reset. Upon re-entering the nominating process, you must reselect validators to support manually. Depending on preferences, these can be the same validators as before or a new set. Remember that your previous nominations won’t be saved or automatically reactivated after chilling. + +While chilled, your nominator account remains bonded, preserving your staked funds without requiring a full unbonding process. When you’re ready to start nominating again, you can issue a new nomination call to activate your bond with a fresh set of validators. This process bypasses the need for re-bonding, allowing you to maintain your stake while adjusting your involvement in active staking. + +## Chilling as a Validator + +When you chill as a validator, your active validator status is paused. Although your nominators remain bonded to you, the validator bond will no longer appear as an active choice for new or revised nominations until reactivated. Any existing nominators who take no action will still have their stake linked to the validator, meaning they don’t need to reselect the validator upon reactivation. However, if nominators adjust their stakes while the validator is chilled, they will not be able to nominate the chilled validator until it resumes activity. + +Upon reactivating as a validator, you must also reconfigure your validator preferences, such as commission rate and other parameters. These can be set to match your previous configuration or updated as desired. This step is essential for rejoining the active validator set and regaining eligibility for nominations. + +## Chill Other + +Historical constraints in the runtime prevented unlimited nominators and validators from being supported. These constraints created a need for checks to keep the size of the staking system manageable. One of these checks is the `chillOther` extrinsic, allowing users to chill accounts that no longer met standards such as minimum staking requirements set through on-chain governance. + +This control mechanism included a `ChillThreshold`, which was structured to define how close to the maximum number of nominators or validators the staking system would be allowed to get before users could start chilling one another. With the passage of [Referendum #90](https://polkadot-old.polkassembly.io/referendum/90){target=\_blank}, the value for `maxNominatorCount` on Polkadot was set to `None`, effectively removing the limit on how many nominators and validators can participate. This means the `ChillThreshold` will never be met; thus, `chillOther` no longer has any effect. diff --git a/.ai/pages/node-infrastructure-run-a-validator-operational-tasks-upgrade-your-node.md b/.ai/pages/node-infrastructure-run-a-validator-operational-tasks-upgrade-your-node.md new file mode 100644 index 000000000..d3bf39683 --- /dev/null +++ b/.ai/pages/node-infrastructure-run-a-validator-operational-tasks-upgrade-your-node.md @@ -0,0 +1,75 @@ +--- +title: Upgrade a Validator Node +description: Guide to seamlessly upgrading your Polkadot validator node, managing session keys, and executing server maintenance while avoiding downtime and slashing risks. +categories: Infrastructure +url: https://docs.polkadot.com/node-infrastructure/run-a-validator/operational-tasks/upgrade-your-node/ +--- + +# Upgrade a Validator Node + +## Introduction + +Upgrading a Polkadot validator node is essential for staying current with network updates and maintaining optimal performance. This guide covers routine and extended maintenance scenarios, including software upgrades and major server changes. Following these steps, you can manage session keys and transition smoothly between servers without risking downtime, slashing, or network disruptions. The process requires strategic planning, especially if you need to perform long-lead maintenance, ensuring your validator remains active and compliant. + +This guide will allow validators to seamlessly substitute an active validator server to allow for maintenance operations. The process can take several hours, so ensure you understand the instructions first and plan accordingly. + +## Prerequisites + +Before beginning the upgrade process for your validator node, ensure the following: + +- You have a fully functional validator setup with all required binaries installed. See [Set Up a Validator](/nodes-and-validators/run-a-validator/onboarding-and-offboarding/set-up-validator/){target=\_blank} and [Validator Requirements](/nodes-and-validators/run-a-validator/requirements/){target=\_blank} for additional guidance. +- Your VPS infrastructure has enough capacity to run a secondary validator instance temporarily for the upgrade process. + +## Session Keys + +Session keys are used to sign validator operations and establish a connection between your validator node and your staking proxy account. These keys are stored in the client, and any change to them requires a waiting period. Specifically, if you modify your session keys, the change will take effect only after the current session is completed and two additional sessions have passed. + +Remembering this delayed effect when planning upgrades is crucial to ensure that your validator continues to function correctly and avoids interruptions. To learn more about session keys and their importance, visit the [Keys section](https://wiki.polkadot.com/learn/learn-cryptography/#keys){target=\_blank}. + +## Keystore + +Your validator server's `keystore` folder holds the private keys needed for signing network-level transactions. It is important not to duplicate or transfer this folder between validator instances. Doing so could result in multiple validators signing with the duplicate keys, leading to severe consequences such as [equivocation slashing](/nodes-and-validators/run-a-validator/staking-mechanics/offenses-and-slashes/#equivocation-slash){target=\_blank}. Instead, always generate new session keys for each validator instance. + +The default path to the `keystore` is as follows: + +```bash +/home/polkadot/.local/share/polkadot/chains//keystore +``` + +Taking care to manage your keys securely ensures that your validator operates safely and without the risk of slashing penalties. + +## Upgrade Using Backup Validator + +The following instructions outline how to temporarily switch between two validator nodes. The original active validator is referred to as Validator A and the backup node used for maintenance purposes as Validator B. + +### Session `N` + +1. **Start Validator B**: Launch a secondary node and wait until it is fully synced with the network. Once synced, start it with the `--validator` flag. This node will now act as Validator B. +2. **Generate session keys**: Create new session keys specifically for Validator B. +3. **Submit the `set_key` extrinsic**: Use your staking proxy account to submit a `set_key` extrinsic, linking the session keys for Validator B to your staking setup. +4. **Record the session**: Make a note of the session in which you executed this extrinsic. +5. **Wait for session changes**: Allow the current session to end and then wait for two additional full sessions for the new keys to take effect. + +!!! warning "Keep Validator A running" + + It is crucial to keep Validator A operational during this entire waiting period. Since `set_key` does not take effect immediately, turning off Validator A too early may result in chilling or even slashing. + +### Session `N+3` + +At this stage, Validator B becomes your active validator. You can now safely perform any maintenance tasks on Validator A. + +Complete the following steps when you are ready to bring Validator A back online: + +1. **Start Validator A**: Launch Validator A, sync the blockchain database, and ensure it is running with the `--validator` flag. +2. **Generate new session keys for Validator A**: Create fresh session keys for Validator A. +3. **Submit the `set_key` extrinsic**: Using your staking proxy account, submit a `set_key` extrinsic with the new Validator A session keys. +4. **Record the session**: Again, make a note of the session in which you executed this extrinsic. + +Keep Validator B active until the session during which you executed the `set-key` extrinsic completes plus two additional full sessions have passed. Once Validator A has successfully taken over, you can safely stop Validator B. This process helps ensure a smooth handoff between nodes and minimizes the risk of downtime or penalties. Verify the transition by checking for finalized blocks in the new session. The logs should indicate the successful change, similar to the example below: + +
+ INSERT_COMMAND + 2019-10-28 21:44:13 Applying authority set change scheduled at block #450092 + 2019-10-28 21:44:13 Applying GRANDPA set change to new set with 20 authorities + +
diff --git a/.ai/pages/node-infrastructure-run-a-validator-requirements.md b/.ai/pages/node-infrastructure-run-a-validator-requirements.md new file mode 100644 index 000000000..2997baeb9 --- /dev/null +++ b/.ai/pages/node-infrastructure-run-a-validator-requirements.md @@ -0,0 +1,85 @@ +--- +title: Validator Requirements +description: Explore the technical and system requirements for running a Polkadot validator, including setup, hardware, staking prerequisites, and security best practices. +categories: Infrastructure +url: https://docs.polkadot.com/node-infrastructure/run-a-validator/requirements/ +--- + +# Validator Requirements + +## Introduction + +Running a validator in the Polkadot ecosystem is essential for maintaining network security and decentralization. Validators are responsible for validating transactions and adding new blocks to the chain, ensuring the system operates smoothly. In return for their services, validators earn rewards. However, the role comes with inherent risks, such as slashing penalties for misbehavior or technical failures. If you’re new to validation, starting on Kusama provides a lower-stakes environment to gain valuable experience before progressing to the Polkadot network. + +This guide covers everything you need to know about becoming a validator, including system requirements, staking prerequisites, and infrastructure setup. Whether you’re deploying on a VPS or running your node on custom hardware, you’ll learn how to optimize your validator for performance and security, ensuring compliance with network standards while minimizing risks. + +## Prerequisites + +Running a validator requires solid system administration skills and a secure, well-maintained infrastructure. Below are the primary requirements you need to be aware of before getting started: + +- **System administration expertise**: Handling technical anomalies and maintaining node infrastructure is critical. Validators must be able to troubleshoot and optimize their setup. +- **Security**: Ensure your setup follows best practices for securing your node. Refer to the [Secure Your Validator](/nodes-and-validators/run-a-validator/operational-tasks/general-management/#secure-your-validator){target=\_blank} section to learn about important security measures. +- **Network choice**: Start with [Kusama](/nodes-and-validators/run-a-validator/onboarding-and-offboarding/set-up-validator/#run-a-kusama-validator){target=\_blank} to gain experience. Look for "Adjustments for Kusama" throughout these guides for tips on adapting the provided instructions for the Kusama network. +- **Staking requirements**: A minimum amount of native token (KSM or DOT) is required to be elected into the validator set. The required stake can come from your own holdings or from nominators. +- **Risk of slashing**: Any DOT you stake is at risk if your setup fails or your validator misbehaves. If you’re unsure of your ability to maintain a reliable validator, consider nominating your DOT to a trusted validator. + +## Minimum Hardware Requirements + +Polkadot validators rely on high-performance hardware to process blocks efficiently. The recommended minimum hardware requirements to ensure a fully functional and performant validator are as follows: + +- CPU: + + - x86-64 compatible. + - Eight physical cores @ 3.4 GHz. + - Processor: + - **Intel**: Ice Lake or newer (Xeon or Core series) + - **AMD**: Zen3 or newer (EPYC or Ryzen) + - Simultaneous multithreading disabled: + - **Intel**: Hyper-Threading + - **AMD**: SMT + - [Single-threaded performance](https://www.cpubenchmark.net/singleThread.html){target=\_blank} is prioritized over higher cores count. + +- Storage: + + - **NVMe SSD**: At least 2 TB for blockchain data recommended (prioritize latency rather than throughput). + - Storage requirements will increase as the chain grows. For current estimates, see the [current chain snapshot](https://stakeworld.io/docs/dbsize){target=\_blank}. + +- Memory: + + - 32 GB DDR4 ECC + +- Network: + + - Symmetric networking speed of 500 Mbit/s is required to handle large numbers of parachains and ensure congestion control during peak times. + +## VPS Provider List + +When selecting a VPS provider for your validator node, prioritize reliability, consistent performance, and adherence to the specific hardware requirements set for Polkadot validators. The following server types have been tested and showed acceptable performance in benchmark tests. However, this is not an endorsement and actual performance may vary depending on your workload and VPS provider. + +Be aware that some providers may overprovision the underlying host and use shared storage such as NVMe over TCP, which appears as local storage. These setups might result in poor or inconsistent performance. Benchmark your infrastructure before deploying. + +- **[Google Cloud Platform (GCP)](https://cloud.google.com/){target=\_blank}**: `c2` and `c2d` machine families offer high-performance configurations suitable for validators. +- **[Amazon Web Services (AWS)](https://aws.amazon.com/){target=\_blank}**: `c6id` machine family provides strong performance, particularly for I/O-intensive workloads. +- **[OVH](https://www.ovhcloud.com/en-au/){target=\_blank}**: Can be a budget-friendly solution if it meets your minimum hardware specifications. +- **[Digital Ocean](https://www.digitalocean.com/){target=\_blank}**: Popular among developers, Digital Ocean's premium droplets offer configurations suitable for medium to high-intensity workloads. +- **[Vultr](https://www.vultr.com/){target=\_blank}**: Offers flexibility with plans that may meet validator requirements, especially for high-bandwidth needs. +- **[Linode](https://www.linode.com/){target=\_blank}**: Provides detailed documentation, which can be helpful for setup. +- **[Scaleway](https://www.scaleway.com/en/){target=\_blank}**: Offers high-performance cloud instances that can be suitable for validator nodes. +- **[OnFinality](https://onfinality.io/en){target=\_blank}**: Specialized in blockchain infrastructure, OnFinality provides validator-specific support and configurations. + +!!! warning "Acceptable use policies" + Different VPS providers have varying acceptable use policies, and not all allow cryptocurrency-related activities. + + For example, Digital Ocean, requires explicit permission to use servers for cryptocurrency mining and defines unauthorized mining as [network abuse](https://www.digitalocean.com/legal/acceptable-use-policy#network-abuse){target=\_blank} in their acceptable use policy. + + Review the terms for your VPS provider to avoid account suspension or server shutdown due to policy violations. + +## Minimum Bond Requirement + +Before bonding DOT, ensure you meet the minimum bond requirement to start a validator instance. The minimum bond is the least DOT you need to stake to enter the validator set. To become eligible for rewards, your validator node must be nominated by enough staked tokens. + +For example, on November 19, 2024, the minimum stake backing a validator in Polkadot's era 1632 was 1,159,434.248 DOT. You can check the current minimum stake required using these tools: + +- [**Chain State Values**](https://wiki.polkadot.com/general/chain-state-values/){target=\_blank} +- [**Subscan**](https://polkadot.subscan.io/validator_list?status=validator){target=\_blank} +- [**Staking Dashboard**](https://staking.polkadot.cloud/#/overview){target=\_blank} diff --git a/.ai/pages/node-infrastructure-run-a-validator-staking-mechanics-offenses-and-slashes.md b/.ai/pages/node-infrastructure-run-a-validator-staking-mechanics-offenses-and-slashes.md new file mode 100644 index 000000000..6014711bd --- /dev/null +++ b/.ai/pages/node-infrastructure-run-a-validator-staking-mechanics-offenses-and-slashes.md @@ -0,0 +1,171 @@ +--- +title: Offenses and Slashes +description: Learn about how Polkadot discourages validator misconduct via an offenses and slashing system, including details on offenses and their consequences. +categories: Infrastructure +url: https://docs.polkadot.com/node-infrastructure/run-a-validator/staking-mechanics/offenses-and-slashes/ +--- + +# Offenses and Slashes + +## Introduction + +In Polkadot's Nominated Proof of Stake (NPoS) system, validator misconduct is deterred through a combination of slashing, disabling, and reputation penalties. Validators and nominators who stake tokens face consequences for validator misbehavior, which range from token slashes to restrictions on network participation. + +This page outlines the types of offenses recognized by Polkadot, including block equivocations and invalid votes, as well as the corresponding penalties. While some parachains may implement additional custom slashing mechanisms, this guide focuses on the offenses tied to staking within the Polkadot ecosystem. + +## Offenses + +Polkadot is a public permissionless network. As such, it has a mechanism to disincentivize offenses and incentivize good behavior. You can review the [parachain protocol](https://wiki.polkadot.com/learn/learn-parachains-protocol/#parachain-protocol){target=\_blank} to understand better the terminology used to describe offenses. Polkadot validator offenses fall into two categories: invalid votes and equivocations. + +### Invalid Votes + +A validator will be penalized for inappropriate voting activity during the block inclusion and approval processes. The invalid voting related offenses are as follows: + +- **Backing an invalid block**: A para-validator backs an invalid block for inclusion in a fork of the relay chain. +- **`ForInvalid` vote**: When acting as a secondary checker, the validator votes in favor of an invalid block. +- **`AgainstValid` vote**: When acting as a secondary checker, the validator votes against a valid block. This type of vote wastes network resources required to resolve the disparate votes and resulting dispute. + +### Equivocations + +Equivocation occurs when a validator produces statements that conflict with each other when producing blocks or voting. Unintentional equivocations usually occur when duplicate signing keys reside on the validator host. If keys are never duplicated, the probability of an honest equivocation slash decreases to near zero. The equivocation related offenses are as follows: + +- **Equivocation**: The validator produces two or more of the same block or vote. + - **GRANDPA and BEEFY equivocation**: The validator signs two or more votes in the same round on different chains. + - **BABE equivocation**: The validator produces two or more blocks on the relay chain in the same time slot. +- **Double seconded equivocation**: The validator attempts to second, or back, more than one block in the same round. +- **Seconded and valid equivocation**: The validator seconds, or backs, a block and then attempts to hide their role as the responsible backer by later placing a standard validation vote. + +## Penalties + +On Polkadot, offenses to the network incur different penalties depending on severity. There are three main penalties: slashing, disabling, and reputation changes. + +### Slashing + +Validators engaging in bad actor behavior in the network may be subject to slashing if they commit a qualifying offense. When a validator is slashed, they and their nominators lose a percentage of their staked DOT or KSM, from as little as 0.01% up to 100% based on the severity of the offense. Nominators are evaluated for slashing against their active validations at any given time. Validator nodes are evaluated as discrete entities, meaning an operator can't attempt to mitigate the offense on another node they operate in order to avoid a slash. + +Any slashed DOT or KSM will be added to the [Treasury](https://wiki.polkadot.com/learn/learn-polkadot-opengov-treasury/){target=\_blank} rather than burned or distributed as rewards. Moving slashed funds to the Treasury allows tokens to be quickly moved away from malicious validators while maintaining the ability to revert faulty slashes when needed. + +A nominator with a very large bond may nominate several validators in a single era. In this case, a slash is proportionate to the amount staked to the offending validator. Stake allocation and validator activation is controlled by the [Phragmén algorithm](https://wiki.polkadot.com/learn/learn-phragmen/#algorithm){target=\_blank}. + +A validator slash creates an `unapplied` state transition. You can view pending slashes on [Polkadot.js Apps](https://polkadot.js.org/apps/?rpc=wss%3A%2F%2Frpc.polkadot.io#/staking/slashes){target=\_blank}. The UI will display the slash per validator, the affected nominators, and the slash amounts. The unapplied state includes a 27-day grace period during which a governance proposal can be made to reverse the slash. Once this grace period expires, the slash is applied. + +#### Equivocation Slash + +The Web3 Foundation's [Slashing mechanisms](https://research.web3.foundation/Polkadot/security/slashing/amounts){target=\_blank} page provides guidelines for evaluating the security threat level of different offenses and determining penalties proportionate to the threat level of the offense. Offenses requiring coordination between validators or extensive computational costs to the system will typically call for harsher penalties than those more likely to be unintentional than malicious. A description of potential offenses for each threat level and the corresponding penalties is as follows: + +- **Level 1**: Honest misconduct such as isolated cases of unresponsiveness. + - **Penalty**: Validator can be kicked out or slashed up to 0.1% of stake in the validator slot. +- **Level 2**: Misconduct that can occur honestly but is a sign of bad practices. Examples include repeated cases of unresponsiveness and isolated cases of equivocation. + - **Penalty**: Slash of up to 1% of stake in the validator slot. +- **Level 3**: Misconduct that is likely intentional but of limited effect on the performance or security of the network. This level will typically include signs of coordination between validators. Examples include repeated cases of equivocation or isolated cases of unjustified voting on GRANDPA. + - **Penalty**: Reduction in networking reputation metrics, slash of up to 10% of stake in the validator slot. +- **Level 4**: Misconduct that poses severe security or monetary risk to the system or mass collusion. Examples include signs of extensive coordination, creating a serious security risk to the system, or forcing the system to use extensive resources to counter the misconduct. + - **Penalty**: Slash of up to 100% of stake in the validator slot. + +See the next section to understand how slash amounts for equivocations are calculated. If you want to know more details about slashing, please look at the research page on [Slashing mechanisms](https://research.web3.foundation/Polkadot/security/slashing/amounts){target=\_blank}. + +#### Slash Calculation for Equivocation + +The slashing penalty for GRANDPA, BABE, and BEEFY equivocations is calculated using the formula below, where `x` represents the number of offenders and `n` is the total number of validators in the active set: + +```text +min((3 * x / n )^2, 1) +``` + +The following scenarios demonstrate how this formula means slash percentages can increase exponentially based on the number of offenders involved compared to the size of the validator pool: + +- **Minor offense**: Assume 1 validator out of a 100 validator active set equivocates in a slot. A single validator committing an isolated offense is most likely a mistake rather than malicious attack on the network. This offense results in a 0.09% slash to the stake in the validator slot. + + ``` mermaid + flowchart LR + N["Total Validators = 100"] + X["Offenders = 1"] + F["min((3 * 1 / 100)^2, 1) = 0.0009"] + G["0.09% slash of stake"] + + N --> F + X --> F + F --> G + ``` + +- **Moderate offense**: Assume 5 validators out a 100 validator active set equivocate in a slot. This is a slightly more serious event as there may be some element of coordination involved. This offense results in a 2.25% slash to the stake in the validator slot. + + ``` mermaid + flowchart LR + N["Total Validators = 100"] + X["Offenders = 5"] + F["min((3 * 5 / 100)^2, 1) = 0.0225"] + G["2.25% slash of stake"] + + N --> F + X --> F + F --> G + ``` + +- **Major offense**: Assume 20 validators out a 100 validator active set equivocate in a slot. This is a major security threat as it possible represents a coordinated attack on the network. This offense results in a 36% slash and all slashed validators will also be chilled. + ``` mermaid + flowchart LR + N["Total Validators = 100"] + X["Offenders = 20"] + F["min((3 * 20 / 100)^2, 1) = 0.36"] + G["36% slash of stake"] + + N --> F + X --> F + F --> G + ``` + +The examples above show the risk of nominating or running many validators in the active set. While rewards grow linearly (two validators will get you approximately twice as many staking rewards as one), slashing grows exponentially. Going from a single validator equivocating to two validators equivocating causes a slash four time as much as the single validator. + +Validators may run their nodes on multiple machines to ensure they can still perform validation work if one of their nodes goes down. Still, validator operators should be cautious when setting these up. Equivocation is possible if they don't coordinate well in managing signing machines. + +#### Best Practices to Avoid Slashing + +The following are advised to node operators to ensure that they obtain pristine binaries or source code and to ensure the security of their node: + +- Always download either source files or binaries from the official Parity repository. +- Verify the hash of downloaded files. +- Use the W3F secure validator setup or adhere to its principles. +- Ensure essential security items are checked, use a firewall, manage user access, use SSH certificates. +- Avoid using your server as a general-purpose system. Hosting a validator on your workstation or one that hosts other services increases the risk of maleficence. +- Avoid cloning servers (copying all contents) when migrating to new hardware. If an image is needed, create it before generating keys. +- High Availability (HA) systems are generally not recommended as equivocation may occur if concurrent operations happen—such as when a failed server restarts or two servers are falsely online simultaneously. +- Copying the keystore folder when moving a database between instances can cause equivocation. Even brief use of duplicated keystores can result in slashing. + +Below are some examples of small equivocations that happened in the past: + +| Network | Era | Event Type | Details | Action Taken | +|----------|------|--------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------| +| Polkadot | 774 | Small Equivocation | [The validator](https://matrix.to/#/!NZrbtteFeqYKCUGQtr:matrix.parity.io/$165562246360408hKCfC:matrix.org?via=matrix.parity.io&via=corepaper.org&via=matrix.org){target=\_blank} migrated servers and cloned the keystore folder. The on-chain event can be viewed on [Subscan](https://polkadot.subscan.io/extrinsic/11190109-0?event=11190109-5){target=\_blank}. | The validator didn't submit a request for the slash to be canceled. | +| Kusama | 3329 | Small Equivocation | The validator operated a test machine with cloned keys. The test machine was online simultaneously as the primary, which resulted in a slash. | The validator requested a slash cancellation, but the council declined. | +| Kusama | 3995 | Small Equivocation | The validator noticed several errors, after which the client crashed, and a slash was applied. The validator recorded all events and opened GitHub issues to allow for technical opinions to be shared. | The validator requested to cancel the slash. The council approved the request as they believed the error wasn't operator-related. | + +#### Slashing Across Eras + +There are three main difficulties to account for with slashing in NPoS: + +- A nominator can nominate multiple validators and be slashed as a result of actions taken by any of them. +- Until slashed, the stake is reused from era to era. +- Slashable offenses can be found after the fact and out of order. + +To balance this, the system applies only the maximum slash a participant can receive in a given time period rather than the sum. This ensures protection from excessive slashing. + +### Disabling + +The disabling mechanism is triggered when validators commit serious infractions, such as backing invalid blocks or engaging in equivocations. Disabling stops validators from performing specific actions after they have committed an offense. Disabling is further divided into: + +- **On-chain disabling**: Lasts for a whole era and stops validators from authoring blocks, backing, and initiating a dispute. +- **Off-chain disabling**: Lasts for a session, is caused by losing a dispute, and stops validators from initiating a dispute. + +Off-chain disabling is always a lower priority than on-chain disabling. Off-chain disabling prioritizes disabling first backers and then approval checkers. + +The material in this guide reflects the changes introduced in Stage 4. For more details, see the [State of Disabling issue](https://github.com/paritytech/polkadot-sdk/issues/4359){target=\_blank} on GitHub. + + +### Reputation Changes + +Some minor offenses, such as spamming, are only punished by networking reputation changes. Validators use a reputation metric when choosing which peers to connect with. The system adds reputation if a peer provides valuable data and behaves appropriately. If they provide faulty or spam data, the system reduces their reputation. If a validator loses enough reputation, their peers will temporarily close their channels to them. This helps in fighting against Denial of Service (DoS) attacks. Performing validator tasks under reduced reputation will be harder, resulting in lower validator rewards. + +### Penalties by Offense + +Refer to the Polkadot Wiki's [offenses page](https://wiki.polkadot.com/learn/learn-offenses/){target=\_blank} for a summary of penalties for specific offenses. diff --git a/.ai/pages/node-infrastructure-run-a-validator-staking-mechanics-rewards.md b/.ai/pages/node-infrastructure-run-a-validator-staking-mechanics-rewards.md new file mode 100644 index 000000000..557244eed --- /dev/null +++ b/.ai/pages/node-infrastructure-run-a-validator-staking-mechanics-rewards.md @@ -0,0 +1,204 @@ +--- +title: Rewards Payout +description: Learn how validator rewards work on the network, including era points, payout distribution, running multiple validators, and nominator payments. +categories: Infrastructure +url: https://docs.polkadot.com/node-infrastructure/run-a-validator/staking-mechanics/rewards/ +--- + +# Rewards Payout + +## Introduction + +Understanding how rewards are distributed to validators and nominators is essential for network participants. In Polkadot and Kusama, validators earn rewards based on their era points, which are accrued through actions like block production and parachain validation. + +This guide explains the payout scheme, factors influencing rewards, and how multiple validators affect returns. Validators can also share rewards with nominators, who contribute by staking behind them. By following the payout mechanics, validators can optimize their earnings and better engage with their nominators. + +## Era Points + +The Polkadot ecosystem measures its reward cycles in a unit called an era. Kusama eras are approximately 6 hours long, and Polkadot eras are 24 hours long. At the end of each era, validators are paid proportionally to the amount of era points they have collected. Era points are reward points earned for payable actions like: + +- Issuing validity statements for [parachain blocks](/reference/parachains/blocks-transactions-fees/blocks/){target=\_blank}. +- Producing a non-uncle block in the relay chain. +- Producing a reference to a previously unreferenced uncle block. +- Producing a referenced uncle block. + +An uncle block is a relay chain block that is valid in every regard but has failed to become canonical. This can happen when two or more validators are block producers in a single slot, and the block produced by one validator reaches the next block producer before the others. The lagging blocks are called uncle blocks. + +## Reward Variance + +Rewards in Polkadot and Kusama staking systems can fluctuate due to differences in era points earned by para-validators and non-para-validators. Para-validators generally contribute more to the overall reward distribution due to their role in validating parachain blocks, thus influencing the variance in staking rewards. + +To illustrate this relationship: + +- Para-validator era points tend to have a higher impact on the expected value of staking rewards compared to non-para-validator points. +- The variance in staking rewards increases as the total number of validators grows relative to the number of para-validators. +- In simpler terms, when more validators are added to the active set without increasing the para-validator pool, the disparity in rewards between validators becomes more pronounced. + +However, despite this increased variance, rewards tend to even out over time due to the continuous rotation of para-validators across eras. The network's design ensures that over multiple eras, each validator has an equal opportunity to participate in para-validation, eventually leading to a balanced distribution of rewards. + +??? interface "Probability in Staking Rewards" + + This should only serve as a high-level overview of the probabilistic nature for staking rewards. + + Let: + + - `pe` = para-validator era points + - `ne` = non-para-validator era points + - `EV` = expected value of staking rewards + + Then, `EV(pe)` has more influence on the `EV` than `EV(ne)`. + + Since `EV(pe)` has a more weighted probability on the `EV`, the increase in variance against the `EV` becomes apparent between the different validator pools (aka. validators in the active set and the ones chosen to para-validate). + + Also, let: + + - `v` = the variance of staking rewards + - `p` = number of para-validators + - `w` = number validators in the active set + - `e` = era + + Then, `v` ↑ if `w` ↑, as this reduces `p` : `w`, with respect to `e`. + + Increased `v` is expected, and initially keeping `p` ↓ using the same para-validator set for all parachains ensures [availability](https://spec.polkadot.network/chapter-anv){target=\_blank} and [voting](https://wiki.polkadot.com/learn/learn-polkadot-opengov/){target=\_blank}. In addition, despite `v` ↑ on an `e` to `e` basis, over time, the amount of rewards each validator receives will equal out based on the continuous selection of para-validators. + + There are plans to scale the active para-validation set in the future. + +## Payout Scheme + +Validator rewards are distributed equally among all validators in the active set, regardless of the total stake behind each validator. However, individual payouts may differ based on the number of era points a validator has earned. Although factors like network connectivity can affect era points, well-performing validators should accumulate similar totals over time. + +Validators can also receive tips from users, which incentivize them to include certain transactions in their blocks. Validators retain 100% of these tips. + +Rewards are paid out in the network's native token (DOT for Polkadot and KSM for Kusama). + +The following example illustrates a four member validator set with their names, amount they have staked, and how payout of rewards is divided. This scenario assumes all validators earned the same amount of era points and no one received tips: + +``` mermaid +flowchart TD + A["Alice (18 DOT)"] + B["Bob (9 DOT)"] + C["Carol (8 DOT)"] + D["Dave (7 DOT)"] + E["Payout (8 DOT total)"] + E --"2 DOT"--> A + E --"2 DOT"--> B + E --"2 DOT"--> C + E --"2 DOT"--> D +``` + +Note that this is different than most other Proof of Stake (PoS) systems. As long as a validator is in the validator set, it will receive the same block reward as every other validator. Validator Alice, who had 18 DOT staked, received the same 2 DOT reward in this era as Dave, who had only 7 DOT staked. + +## Running Multiple Validators + +Running multiple validators can offer a more favorable risk/reward ratio compared to running a single one. If you have sufficient DOT or nominators staking on your validators, maintaining multiple validators within the active set can yield higher rewards. + +In the preceding section, with 18 DOT staked and no nominators, Alice earned 2 DOT in one era. This example uses DOT, but the same principles apply for KSM on the Kusama network. By managing stake across multiple validators, you can potentially increase overall returns. Recall the set of validators from the preceding section: + +``` mermaid +flowchart TD + A["Alice (18 DOT)"] + B["Bob (9 DOT)"] + C["Carol (8 DOT)"] + D["Dave (7 DOT)"] + E["Payout (8 DOT total)"] + E --"2 DOT"--> A + E --"2 DOT"--> B + E --"2 DOT"--> C + E --"2 DOT"--> D +``` + +Now, assume Alice decides to split their stake and run two validators, each with a nine DOT stake. This validator set only has four spots and priority is given to validators with a larger stake. In this example, Dave has the smallest stake and loses his spot in the validator set. Now, Alice will earn two shares of the total payout each era as illustrated below: + +``` mermaid +flowchart TD + A["Alice (9 DOT)"] + F["Alice (9 DOT)"] + B["Bob (9 DOT)"] + C["Carol (8 DOT)"] + E["Payout (8 DOT total)"] + E --"2 DOT"--> A + E --"2 DOT"--> B + E --"2 DOT"--> C + E --"2 DOT"--> F +``` + +With enough stake, you could run more than two validators. However, each validator must have enough stake behind it to maintain a spot in the validator set. + +## Nominators and Validator Payments + +A nominator's stake allows them to vote for validators and earn a share of the rewards without managing a validator node. Although staking rewards depend on validator activity during an era, validators themselves never control or own nominator rewards. To trigger payouts, anyone can call the `staking.payoutStakers` or `staking.payoutStakerByPage` methods, which mint and distribute rewards directly to the recipients. This trustless process ensures nominators receive their earned rewards. + +Validators set a commission rate as a percentage of the block reward, affecting how rewards are shared with nominators. A 0% commission means the validator keeps only rewards from their self-stake, while a 100% commission means they retain all rewards, leaving none for nominators. + +The following examples model splitting validator payments between nominator and validator using various commission percentages. For simplicity, these examples assume a Polkadot-SDK based relay chain that uses DOT as a native token and a single nominator per validator. Calculations of KSM reward payouts for Kusama follow the same formula. + +Start with the original validator set from the previous section: + +``` mermaid +flowchart TD + A["Alice (18 DOT)"] + B["Bob (9 DOT)"] + C["Carol (8 DOT)"] + D["Dave (7 DOT)"] + E["Payout (8 DOT total)"] + E --"2 DOT"--> A + E --"2 DOT"--> B + E --"2 DOT"--> C + E --"2 DOT"--> D +``` + +The preceding diagram shows each validator receiving a 2 DOT payout, but doesn't account for sharing rewards with nominators. The following diagram shows what nominator payout might look like for validator Alice. Alice has a 20% commission rate and holds 50% of the stake for their validator: + +``` mermaid + +flowchart TD + A["Gross Rewards = 2 DOT"] + E["Commission = 20%"] + F["Alice Validator Payment = 0.4 DOT"] + G["Total Stake Rewards = 1.6 DOT"] + B["Alice Validator Stake = 18 DOT"] + C["9 DOT Alice (50%)"] + H["Alice Stake Reward = 0.8 DOT"] + I["Total Alice Validator Reward = 1.2 DOT"] + D["9 DOT Nominator (50%)"] + J["Total Nominator Reward = 0.8 DOT"] + + A --> E + E --(2 x 0.20)--> F + F --(2 - 0.4)--> G + B --> C + B --> D + C --(1.6 x 0.50)--> H + H --(0.4 + 0.8)--> I + D --(1.60 x 0.50)--> J +``` + +Notice the validator commission rate is applied against the gross amount of rewards for the era. The validator commission is subtracted from the total rewards. After the commission is paid to the validator, the remaining amount is split among stake owners according to their percentage of the total stake. A validator's total rewards for an era include their commission plus their piece of the stake rewards. + +Now, consider a different scenario for validator Bob where the commission rate is 40%, and Bob holds 33% of the stake for their validator: + +``` mermaid + +flowchart TD + A["Gross Rewards = 2 DOT"] + E["Commission = 40%"] + F["Bob Validator Payment = 0.8 DOT"] + G["Total Stake Rewards = 1.2 DOT"] + B["Bob Validator Stake = 9 DOT"] + C["3 DOT Bob (33%)"] + H["Bob Stake Reward = 0.4 DOT"] + I["Total Bob Validator Reward = 1.2 DOT"] + D["6 DOT Nominator (67%)"] + J["Total Nominator Reward = 0.8 DOT"] + + A --> E + E --(2 x 0.4)--> F + F --(2 - 0.8)--> G + B --> C + B --> D + C --(1.2 x 0.33)--> H + H --(0.8 + 0.4)--> I + D --(1.2 x 0.67)--> J +``` + +Bob holds a smaller percentage of their node's total stake, making their stake reward smaller than Alice's. In this scenario, Bob makes up the difference by charging a 40% commission rate and ultimately ends up with the same total payment as Alice. Each validator will need to find their ideal balance between the amount of stake and commission rate to attract nominators while still making running a validator worthwhile. diff --git a/.nav.yml b/.nav.yml index 0bb75ad17..88871fcb5 100644 --- a/.nav.yml +++ b/.nav.yml @@ -4,4 +4,4 @@ nav: - 'Parachains': parachains - 'Chain Interactions': chain-interactions # 'Get Support': get-support - - 'Nodes and Validators': nodes-and-validators + - 'Node Infrastructure': node-infrastructure diff --git a/nodes-and-validators/.nav.yml b/node-infrastructure/.nav.yml similarity index 66% rename from nodes-and-validators/.nav.yml rename to node-infrastructure/.nav.yml index 17b62067c..a14f33cae 100644 --- a/nodes-and-validators/.nav.yml +++ b/node-infrastructure/.nav.yml @@ -1,3 +1,4 @@ nav: - 'Run a Node': run-a-node + - 'Run a Collator': run-a-collator - 'Run a Validator': run-a-validator diff --git a/node-infrastructure/run-a-collator/.nav.yml b/node-infrastructure/run-a-collator/.nav.yml new file mode 100644 index 000000000..a18175837 --- /dev/null +++ b/node-infrastructure/run-a-collator/.nav.yml @@ -0,0 +1,2 @@ +nav: + - 'Run a Block-Producing Collator': collator.md diff --git a/node-infrastructure/run-a-collator/collator.md b/node-infrastructure/run-a-collator/collator.md new file mode 100644 index 000000000..57ba15e1c --- /dev/null +++ b/node-infrastructure/run-a-collator/collator.md @@ -0,0 +1,557 @@ +--- +title: Run a Block-Producing Collator +description: Learn how to set up and run a block-producing collator for Polkadot system parachains, including registration and session key management. +categories: Infrastructure +--- + +# Run a Block-Producing Collator + +## Overview + +Block-producing collators are the backbone of system parachain operations. Unlike RPC nodes or archive nodes that simply maintain state, collators actively produce blocks and submit them to relay chain validators for inclusion. + +This guide covers setting up a **block-producing collator** for Polkadot system parachains. Running a collator requires: + +- Meeting hardware requirements for reliable block production +- Setting up and registering session keys +- Obtaining governance approval or meeting selection criteria +- Maintaining high uptime and performance + +**Important**: System parachain collators typically require governance approval or being added to the invulnerables list. This is different from non-system parachains where collator selection may be more permissionless. + +## Collator Responsibilities + +Block-producing collators perform critical functions: + +- **Maintain full nodes**: Both relay chain and parachain +- **Collect transactions**: Aggregate user transactions into blocks +- **Produce blocks**: Create parachain block candidates +- **Generate proofs**: Produce state transition proofs (Proof-of-Validity) +- **Submit to validators**: Send block candidates to relay chain validators +- **Facilitate XCM**: Enable cross-chain message passing + +Unlike relay chain validators, collators do not provide security guarantees—that responsibility lies with relay chain validators through the ELVES protocol. However, collators are essential for network liveness and censorship resistance. + +## Prerequisites + +### Hardware Requirements + +Block-producing collators require robust hardware for reliable operation: + +- **CPU**: 4+ cores (8+ cores recommended for optimal performance) +- **Memory**: 32 GB RAM minimum (64 GB recommended) +- **Storage**: + - 500 GB+ NVMe SSD for parachain data + - Additional 200+ GB for relay chain pruned database + - Fast disk I/O is critical for block production performance +- **Network**: + - Public IP address (required) + - 100+ Mbps connection (stable connection critical) + - Open ports: + - 30333 (parachain P2P) + - 30334 (relay chain P2P) + - 9944 (WebSocket RPC - for management) + +**Note**: Uptime is critical. Consider redundancy and monitoring to maintain block production reliability. + +### Software Requirements + +Collators use the **Polkadot Omni Node**, a universal binary that runs any parachain using a chain specification file. + +Required software: + +- **Operating System**: Ubuntu 22.04 LTS (recommended) or similar Linux distribution +- **Docker**: For running subkey utility +- **Rust Toolchain**: Version 1.86 or as specified by the runtime +- **Dependencies**: + ```bash + sudo apt update + sudo apt install -y build-essential git clang curl libssl-dev llvm libudev-dev make protobuf-compiler + ``` + +### Account Requirements + +You'll need: +- **Funded account**: For on-chain transactions and potential bonding +- **Session keys**: For collator identification (generated after node setup) +- **Node key**: For stable P2P peer ID (recommended) + +## Installation + +### Step 1: Install Rust and Required Toolchain + +```bash +# Install Rust +curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh +source $HOME/.cargo/env + +# Install specific Rust version +rustup install 1.86 +rustup default 1.86 +rustup target add wasm32-unknown-unknown --toolchain 1.86 +rustup component add rust-src --toolchain 1.86 +``` + +### Step 2: Install the Polkadot Omni Node + +```bash +# Install polkadot-omni-node +cargo install --locked polkadot-omni-node@0.5.0 + +# Verify installation +polkadot-omni-node --version +``` + +### Step 3: Generate Node Key + +Generate a stable node key for consistent peer ID: + +```bash +# Create directory for node data +sudo mkdir -p /var/lib/polkadot-collator + +# Generate node key using Docker +docker run -it parity/subkey:latest generate-node-key > /var/lib/polkadot-collator/node.key + +# The output displays your peer ID +# Example: 12D3KooWExcVYu7Mvjd4kxPVLwN2ZPnZ5NyLZ5ft477wqzfP2q6E +``` + +Save the peer ID for future reference. + +### Step 4: Generate Account Key + +Generate an account for on-chain transactions: + +```bash +# Generate account key with sr25519 scheme +docker run -it parity/subkey:latest generate --scheme sr25519 +``` + +Save the output containing: +- Secret phrase (seed) - Keep this secure! +- Public key (hex) +- Account ID +- SS58 Address + +**Security**: Store the secret phrase securely. Never share it. Consider using a hardware wallet for production collators. + +### Step 5: Obtain Chain Specification + +Download the chain specification for your target system parachain: + +**Option 1: Download from Chainspec Collection (Recommended)** + +1. Visit the [Chainspec Collection website](https://paritytech.github.io/chainspecs/) +2. Find your target system parachain +3. Download the chain specification JSON file +4. Save it as `chain-spec.json` + +**Option 2: Build from Runtime** + +```bash +# Clone the runtimes repository +git clone https://github.com/polkadot-fellows/runtimes.git +cd runtimes + +# Build the desired runtime (example for Polkadot Hub) +cargo build --release -p asset-hub-polkadot-runtime + +# Install chain-spec-builder +cargo install --locked staging-chain-spec-builder@10.0.0 + +# Generate chain spec +chain-spec-builder create \ + --relay-chain polkadot \ + --para-id 1000 \ + --runtime target/release/wbuild/asset-hub-polkadot-runtime/asset_hub_polkadot_runtime.compact.compressed.wasm \ + named-preset production > chain-spec.json +``` + +**System Parachain Para IDs:** +- Polkadot Hub: 1000 +- Bridge Hub: 1002 +- People Chain: 1004 +- Coretime Chain: 1005 + +### Step 6: Create User and Directory Structure + +```bash +# Create dedicated user +sudo useradd -r -s /bin/bash polkadot + +# Copy chain spec to directory +sudo cp chain-spec.json /var/lib/polkadot-collator/ + +# Set permissions +sudo chown -R polkadot:polkadot /var/lib/polkadot-collator +``` + +## Configuration + +### Create Systemd Service File + +Create a service file for your collator: + +```bash +sudo nano /etc/systemd/system/polkadot-collator.service +``` + +Add the following configuration: + +```ini +[Unit] +Description=Polkadot System Parachain Collator +After=network.target + +[Service] +Type=simple +User=polkadot +Group=polkadot +WorkingDirectory=/var/lib/polkadot-collator + +# Block-Producing Collator Configuration +ExecStart=/usr/local/bin/polkadot-omni-node \ + --collator \ + --chain=/var/lib/polkadot-collator/chain-spec.json \ + --base-path=/var/lib/polkadot-collator \ + --port=30333 \ + --rpc-port=9944 \ + --prometheus-port=9615 \ + --node-key-file=/var/lib/polkadot-collator/node.key \ + --name="YourCollatorName" \ + -- \ + --execution=wasm \ + --chain=polkadot \ + --port=30334 \ + --sync=warp + +Restart=always +RestartSec=10 +LimitNOFILE=65536 + +[Install] +WantedBy=multi-user.target +``` + +**Configuration Notes**: +- `--collator`: Enables block production mode +- `--node-key-file`: Uses the generated node key for stable peer ID +- `--name`: Your collator name (visible in telemetry) +- Relay chain uses `--sync=warp` for faster initial sync + +## Running the Collator + +### Step 1: Start the Service + +```bash +# Reload systemd +sudo systemctl daemon-reload + +# Enable service to start on boot +sudo systemctl enable polkadot-collator + +# Start the service +sudo systemctl start polkadot-collator + +# Check status +sudo systemctl status polkadot-collator + +# View logs +sudo journalctl -u polkadot-collator -f +``` + +### Step 2: Initial Sync + +Your collator must sync both the relay chain and parachain before producing blocks. + +Sync time depends on: +- Network bandwidth +- Disk I/O speed +- Current chain size + +The relay chain uses warp sync for faster synchronization. + +Monitor sync progress: +```bash +# Check logs for sync status +sudo journalctl -u polkadot-collator -f | grep "Syncing" + +# Wait for messages indicating full sync +# Example: "Idle" or "Imported" messages for both chains +``` + +**Important**: Do not proceed with registration until both chains are fully synced. + +### Step 3: Generate Session Keys + +Once your node is fully synced, generate session keys: + +```bash +# Generate session keys via RPC +curl -H "Content-Type: application/json" \ + -d '{"id":1, "jsonrpc":"2.0", "method": "author_rotateKeys", "params":[]}' \ + http://localhost:9944 + +# Returns session keys as a hex string +# Example: "0x1234567890abcdef..." +``` + +**Save the session keys** - you'll need them for on-chain registration. + +**Note**: Session keys are stored in the node's database. If you wipe the database, you'll need to generate new keys. + +## Registration and Governance + +### Understanding Collator Selection + +System parachains use different collator selection mechanisms: + +**Invulnerables List**: +- Fixed list of collators approved through governance +- Most common for system parachains +- Requires governance proposal and approval + +**On-chain Selection**: +- Some parachains use pallet-collator-selection +- May require bonding tokens +- Automatic selection based on criteria + +**Fellowship Decisions**: +- Technical Fellowship may manage some system parachain collators +- Requires Fellowship membership or approval + +### Registration Process + +The registration process varies by system parachain. General steps: + +#### 1. Check Current Collators + +Check the existing collators for your target parachain: + +```bash +# Using Polkadot.js Apps +# Connect to your target system parachain +# Go to Developer > Chain State +# Query: collatorSelection.invulnerables() or similar +``` + +#### 2. Prepare Governance Proposal + +For invulnerables-based selection: + +1. **Draft proposal**: Explain why you should be added as a collator +2. **Technical details**: Provide your session keys and account ID +3. **Infrastructure**: Describe your hardware and monitoring setup +4. **Experience**: Detail your relevant experience + +Submit to: +- Polkadot Forum: https://forum.polkadot.network +- Relevant governance channels + +#### 3. Set Session Keys On-Chain + +Once approved (or if using on-chain selection), set your session keys: + +**Using Polkadot.js Apps:** + +1. Navigate to Polkadot.js Apps and connect to your system parachain +2. Go to **Developer > Extrinsics** +3. Select your account +4. Choose `session.setKeys` extrinsic +5. Enter: + - `keys`: Your session keys (from `author_rotateKeys`) + - `proof`: 0x00 (typically) +6. Submit and sign the transaction + +**Using CLI (alternative):** + +```bash +# This varies by parachain - consult specific documentation +``` + +#### 4. Bond Tokens (if required) + +Some parachains require bonding tokens: + +1. Go to **Developer > Extrinsics** +2. Select `collatorSelection.registerAsCandidate` (if available) +3. Submit with required bond amount +4. Sign transaction + +#### 5. Await Governance Approval + +If using invulnerables: +- Wait for governance vote +- Monitor forum and announcements +- Once approved, you'll be added to the invulnerables list +- Your collator will begin producing blocks in the next session/era + +### Verify Collator Status + +Check if your collator is active: + +```bash +# Monitor logs for block production +sudo journalctl -u polkadot-collator -f | grep -i "imported" + +# Look for messages like: +# "Prepared block for proposing" +# "Imported #123" +``` + +## Monitoring and Maintenance + +### Essential Monitoring + +**Block Production**: +```bash +# Monitor block production +sudo journalctl -u polkadot-collator | grep -i "prepared block" +``` + +**Peer Connections**: +- Maintain 30+ peers for good connectivity +- Check peer count in logs + +**Resource Usage**: +- Monitor CPU, RAM, and disk I/O +- Set up alerts for high usage + +**Sync Status**: +- Ensure both chains stay synced +- Alert on sync issues + +### Prometheus Metrics + +Metrics available at `http://localhost:9615/metrics` + +Example Prometheus configuration: +```yaml +scrape_configs: + - job_name: 'polkadot-collator' + static_configs: + - targets: ['localhost:9615'] +``` + +Key metrics to monitor: +- `substrate_block_height`: Current block height +- `substrate_finalized_height`: Finalized block height +- `substrate_peers_count`: Peer connections +- `substrate_ready_transactions_number`: Transaction queue + +### Setting Up Alerts + +Configure alerts for: +- Service failures +- Sync issues +- Low peer count (< 10 peers) +- Block production gaps +- High resource usage +- Disk space low + +### Log Management + +```bash +# View recent logs +sudo journalctl -u polkadot-collator -n 100 + +# Follow logs in real-time +sudo journalctl -u polkadot-collator -f + +# Filter for errors +sudo journalctl -u polkadot-collator | grep -i error + +# Filter for block production +sudo journalctl -u polkadot-collator | grep -i "imported" +``` + +### Database Maintenance + +Check database size: +```bash +# Check database size +du -sh /var/lib/polkadot-collator +``` + +The node handles pruning automatically. + +### Updates and Upgrades + +**Runtime Upgrades**: +- Automatic via on-chain governance +- No manual action required +- Monitor announcements for breaking changes + +**Client Upgrades**: +- Require manual binary update +- Subscribe to announcements: + - Polkadot Forum + - Fellowship GitHub + - Matrix channels + +**Upgrade Procedure**: + +```bash +# Stop the service +sudo systemctl stop polkadot-collator + +# Backup data (recommended) +sudo cp -r /var/lib/polkadot-collator /var/lib/polkadot-collator.backup + +# Update polkadot-omni-node +cargo install --locked --force polkadot-omni-node@ + +# Verify version +polkadot-omni-node --version + +# Restart service +sudo systemctl start polkadot-collator + +# Monitor logs +sudo journalctl -u polkadot-collator -f +``` + +## Security Best Practices + +### Key Management + +- **Secure storage**: Store session keys and account keys securely +- **Never share**: Never share private keys or secret phrases +- **Hardware wallets**: Consider HSM for production +- **Backup**: Keep encrypted backups of keys +- **Rotation**: Plan for key rotation procedures + +### Network Security + +- **Firewall**: Restrict access to necessary ports only +- **SSH**: Use SSH keys, disable password auth +- **VPN**: Consider VPN for administrative access +- **DDoS protection**: Implement if running in cloud + +### System Security + +- **Updates**: Keep OS and software updated +- **Dedicated user**: Never run as root +- **Fail2ban**: Enable for SSH protection +- **Audits**: Regular security audits +- **Minimal services**: Disable unnecessary services + +### Operational Security + +- **Monitoring**: 24/7 monitoring with alerts +- **Backups**: Regular configuration backups +- **Documentation**: Document procedures +- **Incident response**: Have incident response plan +- **Redundancy**: Consider backup collator (standby) + +## Conclusion + +Running a collator node is essential for parachain operation and network security. By following this guide, you have set up a production-ready collator that: + +- Produces blocks for your parachain and maintains network consensus +- Implements comprehensive security measures to protect keys and operations +- Supports robust monitoring and alerting for reliable performance +- Follows best practices for both Docker and systemd deployments + +As a collator operator, you play a vital role in your parachain's infrastructure. Regular maintenance, security updates, and monitoring will ensure your collator continues to perform reliably. Stay engaged with your parachain community and keep up with updates to maintain optimal performance and security. diff --git a/node-infrastructure/run-a-node/.nav.yml b/node-infrastructure/run-a-node/.nav.yml new file mode 100644 index 000000000..f4e014c43 --- /dev/null +++ b/node-infrastructure/run-a-node/.nav.yml @@ -0,0 +1,4 @@ +nav: + - 'Polkadot Hub RPC Node': polkadot-hub-rpc.md + - 'System Parachain RPC Nodes': system-parachain-rpc.md + - 'Relay Chain Nodes': relay-chain diff --git a/node-infrastructure/run-a-node/polkadot-hub-rpc.md b/node-infrastructure/run-a-node/polkadot-hub-rpc.md new file mode 100644 index 000000000..92e5b2528 --- /dev/null +++ b/node-infrastructure/run-a-node/polkadot-hub-rpc.md @@ -0,0 +1,619 @@ +--- +title: Run an RPC Node for Polkadot Hub +description: Complete guide to set up and run an RPC node for Polkadot Hub with Polkadot SDK RPC endpoints. +categories: Infrastructure +--- + +# Run an RPC Node for Polkadot Hub + +## Overview + +[Polkadot Hub](/reference/polkadot-hub/){target=\_blank} is the entry point to Polkadot for all users and application developers. It provides access to essential Web3 services, including: + +- **Asset Management**: Native support for fungible and non-fungible assets +- **Governance, Staking, and Treasury**: Core protocol operations +- **Cross-chain Communication**: XCM message handling + +Running an RPC node for Polkadot Hub enables applications, wallets, and users to interact with the parachain through: +- **Polkadot SDK Node RPC** (Port 9944): Native Polkadot API (WebSocket and HTTP) + +This setup enables block explorer indexing and provides full compatibility with Polkadot SDK development tools. + +**Important Note**: The parameters and configurations in this guide are provided as illustrative examples. You may need to modify them according to your specific environment, hardware capabilities, and network conditions. + +## Prerequisites + +### Hardware Requirements + +RPC nodes serving production traffic require robust hardware: + +- **CPU**: 8+ cores (16+ cores for high traffic) +- **Memory**: 64 GB RAM minimum (128 GB recommended for high traffic) +- **Storage**: + - 500 GB+ NVMe SSD for parachain state (archive nodes require 2-4 TB+) + - Additional 200+ GB for relay chain pruned database + - Fast disk I/O is critical for query performance +- **Network**: + - Public IP address + - 1 Gbps connection (for high traffic scenarios) + - Stable internet connection with sufficient bandwidth + - Open ports: + - 30333 (parachain P2P) + - 30334 (relay chain P2P) + - 9944 (Polkadot SDK WebSocket RPC) + - 9933 (Polkadot SDK HTTP RPC) + - 9615 (Prometheus metrics - optional) + - Consider DDoS protection and rate limiting for production deployments + +**Note**: For development or low-traffic scenarios, you can reduce these requirements proportionally. Consider using a reverse proxy (nginx, Caddy) for production deployments. + +### Software Requirements + +Required software: + +- **Operating System**: Ubuntu 22.04 LTS (recommended) or similar Linux distribution +- **Docker**: Latest version installed and running (for Docker-based setup) +- **rclone**: (Optional but recommended) Command-line program for managing files on cloud storage (https://rclone.org/downloads/) +- **Rust Toolchain**: Version 1.86 or as specified by runtime (for manual build) + +## Setup Options + +This guide provides two deployment options: + +1. **Docker-based Setup**: Simpler to set up and maintain +2. **Manual/Systemd Setup**: For production environments requiring more control + +Choose the option that best fits your needs. + +--- + +## Option 1: Docker-Based Setup + +This option uses Docker containers for the Polkadot SDK node, making it easy to set up and manage. + +### Step 1: Download Chain Specification + +Download the official Polkadot Hub (formerly known as Asset Hub) chain specification: + +```bash +curl -L https://raw.githubusercontent.com/paritytech/polkadot-sdk/master/cumulus/parachains/chain-specs/asset-hub-polkadot.json -o asset-hub-polkadot.json +``` + +**Note**: This chain specification is the official configuration file that defines the network parameters for Polkadot Hub. + +### Step 2: Download Database Snapshots (Optional but Recommended) + +Using pre-synchronized snapshots significantly reduces initial sync time from several days to just a few hours. You need to download both parachain and relay chain data. + +**Snapshot Provider**: https://snapshots.polkadot.io/ + +#### Create Directories + +```bash +mkdir -p my-node-data/chains/asset-hub-polkadot/db +mkdir -p my-node-data/chains/polkadot/db +``` + +#### Download Polkadot Hub Parachain Snapshot + +Choose between archive (complete history) or pruned (recent state) snapshots: + +**Archive Snapshot** (recommended for RPC with historical data): + +```bash +# Check https://snapshots.polkadot.io/ for the latest snapshot URL +export SNAPSHOT_URL_ASSET_HUB="https://snapshots.polkadot.io/polkadot-asset-hub-rocksdb-archive/LATEST" + +rclone copyurl $SNAPSHOT_URL_ASSET_HUB/files.txt files.txt +rclone copy --progress --transfers 20 \ + --http-url $SNAPSHOT_URL_ASSET_HUB \ + --no-traverse --http-no-head --disable-http2 \ + --inplace --no-gzip-encoding --size-only \ + --retries 6 --retries-sleep 10s \ + --files-from files.txt :http: my-node-data/chains/asset-hub-polkadot/db/ + +rm files.txt +``` + +**Parameter Explanation**: +- `--transfers 20`: Uses 20 parallel transfers for faster download +- `--retries 6`: Automatically retries failed transfers up to 6 times +- `--retries-sleep 10s`: Waits 10 seconds between retry attempts +- `--size-only`: Only transfers if sizes differ (prevents unnecessary re-downloads) + +#### Download Polkadot Relay Chain Snapshot + +**Pruned Snapshot** (recommended for RPC nodes): + +```bash +# Check https://snapshots.polkadot.io/ for the latest snapshot URL +export SNAPSHOT_URL_RELAY="https://snapshots.polkadot.io/polkadot-rocksdb-prune/LATEST" + +rclone copyurl $SNAPSHOT_URL_RELAY/files.txt files.txt +rclone copy --progress --transfers 20 \ + --http-url $SNAPSHOT_URL_RELAY \ + --no-traverse --http-no-head --disable-http2 \ + --inplace --no-gzip-encoding --size-only \ + --retries 6 --retries-sleep 10s \ + --files-from files.txt :http: my-node-data/chains/polkadot/db/ + +rm files.txt +``` + +**Alternative Options**: +- Pruned snapshot: `polkadot-rocksdb-prune` (smaller size, recent state) +- Archive snapshot: `polkadot-rocksdb-archive` (complete history, larger size) + +### Step 3: Start Polkadot Hub Node + +Launch the node using the official Parity Docker image: + +**Docker Image**: https://hub.docker.com/r/parity/polkadot-omni-node + +```bash +docker run -d --name polkadot-hub-rpc --restart unless-stopped \ + -p 9944:9944 \ + -p 9933:9933 \ + -p 9615:9615 \ + -p 30334:30334 \ + -p 30333:30333 \ + -v $(pwd)/asset-hub-polkadot.json:/asset-hub-polkadot.json \ + -v $(pwd)/my-node-data:/data \ + parity/polkadot-omni-node:stable2506-4 \ + --name=PolkadotHubRPC \ + --base-path=/data \ + --chain=/asset-hub-polkadot.json \ + --prometheus-external \ + --prometheus-port 9615 \ + --unsafe-rpc-external \ + --rpc-port=9944 \ + --rpc-cors=all \ + --rpc-methods=safe \ + --rpc-max-connections=1000 \ + --state-pruning=archive \ + --blocks-pruning=archive \ + -- \ + --base-path=/data \ + --chain=polkadot \ + --state-pruning=256 \ + --blocks-pruning=archive-canonical +``` + +**Critical Configuration Parameters**: + +**Port Mappings**: +- `9944`: Polkadot SDK RPC endpoint (WebSocket/HTTP) +- `9933`: Polkadot SDK HTTP RPC endpoint +- `9615`: Prometheus metrics endpoint +- `30333/30334`: P2P networking ports + +**Node Parameters**: +- `--unsafe-rpc-external`: Enables external RPC access +- `--rpc-cors=all`: Allows all origins for CORS +- `--rpc-methods=safe`: Only allows safe RPC methods +- `--state-pruning=archive`: Keeps complete state history +- `--blocks-pruning=archive`: Keeps all block data +- `--prometheus-external`: Exposes metrics externally + +**Security Warning**: The `--unsafe-rpc-external` flag should only be used in development or properly secured environments. For production, use a reverse proxy with authentication. + +### Step 4: Monitor Synchronization + +Monitor the node synchronization status: + +```bash +# Check sync status +curl -H "Content-Type: application/json" \ + -d '{"id":1, "jsonrpc":"2.0", "method": "system_syncState", "params":[]}' \ + http://localhost:9944 +``` + +**Expected Response Format**: + +```json +{ + "jsonrpc":"2.0", + "id":1, + "result":{ + "startingBlock":0, + "currentBlock":3394816, + "highestBlock":3394816 + } +} +``` + +**Synchronization Status**: +- **In Progress**: `currentBlock` < `highestBlock` +- **Complete**: `currentBlock` = `highestBlock` + +**Monitor logs**: + +```bash +# View node logs +docker logs -f polkadot-hub-rpc + +# Filter for sync messages +docker logs polkadot-hub-rpc 2>&1 | grep -i "syncing" +``` + +### Step 5: Verify Setup + +Let's verify the Polkadot SDK RPC endpoint is working correctly. + +#### API Endpoint + +**Polkadot SDK RPC (Port 9944)**: +- WebSocket: `ws://your-server:9944` +- HTTP: `http://your-server:9944` +- Purpose: Full Polkadot SDK API access for parachain data +- Use Cases: Polkadot SDK applications, parachain-specific operations + +#### Polkadot SDK RPC Tests + +**Get Chain Information**: + +```bash +curl -H "Content-Type: application/json" \ + -d '{"id":1, "jsonrpc":"2.0", "method": "system_chain", "params":[]}' \ + http://localhost:9944 +``` + +**Get Latest Block**: + +```bash +curl -H "Content-Type: application/json" \ + -d '{"id":1, "jsonrpc":"2.0", "method": "chain_getHeader", "params":[]}' \ + http://localhost:9944 +``` + +**Get Node Health**: + +```bash +curl -H "Content-Type: application/json" \ + -d '{"id":1, "jsonrpc":"2.0", "method": "system_health", "params":[]}' \ + http://localhost:9944 +``` + +### Managing Docker Containers + +**View logs**: + +```bash +# View node logs +docker logs -f polkadot-hub-rpc +``` + +**Stop container**: + +```bash +docker stop polkadot-hub-rpc +``` + +**Start container**: + +```bash +docker start polkadot-hub-rpc +``` + +**Remove container**: + +```bash +docker rm polkadot-hub-rpc +``` + +**Update container**: + +```bash +# Pull latest image +docker pull parity/polkadot-omni-node:stable2506-4 + +# Stop and remove old container +docker stop polkadot-hub-rpc +docker rm polkadot-hub-rpc + +# Start new container with same command as above +``` + +--- + +## Option 2: Manual/Systemd Setup + +This option provides more control and is recommended for production environments requiring custom configurations. + +### Step 1: Install Rust and Required Toolchain + +```bash +# Install Rust +curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh +source $HOME/.cargo/env + +# Install specific Rust version +rustup install 1.86 +rustup default 1.86 +rustup target add wasm32-unknown-unknown --toolchain 1.86 +rustup component add rust-src --toolchain 1.86 +``` + +### Step 2: Install the Polkadot Omni Node + +```bash +# Install polkadot-omni-node +cargo install --locked polkadot-omni-node@0.7.0 + +# Verify installation +polkadot-omni-node --version +``` + +### Step 3: Obtain Chain Specification + +Download the Polkadot Hub chain specification: + +```bash +curl -L https://raw.githubusercontent.com/paritytech/polkadot-sdk/master/cumulus/parachains/chain-specs/asset-hub-polkadot.json -o asset-hub-polkadot.json +``` + +### Step 4: Create User and Directory Structure + +```bash +# Create dedicated user +sudo useradd -r -s /bin/bash polkadot + +# Create data directory +sudo mkdir -p /var/lib/polkadot-hub-rpc + +# Copy chain spec to the directory +sudo cp asset-hub-polkadot.json /var/lib/polkadot-hub-rpc/ + +# Set permissions +sudo chown -R polkadot:polkadot /var/lib/polkadot-hub-rpc +``` + +### Step 5: Create Systemd Service for Polkadot SDK Node + +Create a service file for the Polkadot SDK RPC node: + +```bash +sudo nano /etc/systemd/system/polkadot-hub-rpc.service +``` + +Add the following configuration: + +```ini +[Unit] +Description=Polkadot Hub RPC Node +After=network.target + +[Service] +Type=simple +User=polkadot +Group=polkadot +WorkingDirectory=/var/lib/polkadot-hub-rpc + +ExecStart=/usr/local/bin/polkadot-omni-node \ + --name=PolkadotHubRPC \ + --chain=/var/lib/polkadot-hub-rpc/asset-hub-polkadot.json \ + --base-path=/var/lib/polkadot-hub-rpc \ + --port=30333 \ + --rpc-port=9944 \ + --rpc-external \ + --rpc-cors=all \ + --rpc-methods=safe \ + --rpc-max-connections=1000 \ + --prometheus-port=9615 \ + --prometheus-external \ + --state-pruning=archive \ + --blocks-pruning=archive \ + -- \ + --chain=polkadot \ + --base-path=/var/lib/polkadot-hub-rpc \ + --port=30334 \ + --state-pruning=256 \ + --blocks-pruning=archive-canonical + +Restart=always +RestartSec=10 +LimitNOFILE=65536 + +[Install] +WantedBy=multi-user.target +``` + +### Step 6: Start Service + +```bash +# Reload systemd +sudo systemctl daemon-reload + +# Enable service to start on boot +sudo systemctl enable polkadot-hub-rpc + +# Start the Polkadot SDK node +sudo systemctl start polkadot-hub-rpc + +# Check status and wait for sync +sudo systemctl status polkadot-hub-rpc +sudo journalctl -u polkadot-hub-rpc -f +``` + +### Step 7: Verify Setup + +Use the same verification tests as in the Docker setup (see Step 5 above). + +--- + +## Monitoring and Maintenance + +### Log Management + +**Docker Setup**: + +```bash +# View node logs +docker logs -f polkadot-hub-rpc +``` + +**Systemd Setup**: + +```bash +# View node logs +sudo journalctl -u polkadot-hub-rpc -f + +# View recent logs +sudo journalctl -u polkadot-hub-rpc -n 100 + +# Filter for errors +sudo journalctl -u polkadot-hub-rpc | grep -i error +``` + +### Performance Monitoring + +Monitor key metrics: +- **Sync status**: Ensure node stays fully synced +- **Peer connections**: Maintain 30+ peers for good connectivity +- **Resource usage**: Monitor CPU, RAM, and disk I/O +- **RPC request latency**: Track response times for the Polkadot SDK API +- **Connection count**: Monitor active RPC connections + +**Prometheus Metrics**: + +Metrics are available at `http://localhost:9615/metrics` + +Example Prometheus scrape configuration: + +```yaml +scrape_configs: + - job_name: 'polkadot-hub-rpc' + static_configs: + - targets: ['localhost:9615'] +``` + +**Key Metrics to Monitor**: +- `substrate_block_height`: Current block height +- `substrate_finalized_height`: Finalized block height +- `substrate_peers_count`: Number of connected peers +- `substrate_ready_transactions_number`: Transaction queue size + +### Database Maintenance + +Check database size periodically: + +```bash +# Docker setup +du -sh my-node-data + +# Systemd setup +du -sh /var/lib/polkadot-hub-rpc +``` + +The node handles pruning automatically based on configuration unless running in archive mode. + +### Updates and Upgrades + +**Docker Setup**: + +```bash +# Pull latest image +docker pull parity/polkadot-omni-node:stable2506-4 + +# Restart container +docker stop polkadot-hub-rpc +docker rm polkadot-hub-rpc + +# Start new container (use same command from setup) +``` + +**Systemd Setup**: + +```bash +# Stop service +sudo systemctl stop polkadot-hub-rpc + +# Backup data +sudo cp -r /var/lib/polkadot-hub-rpc /var/lib/polkadot-hub-rpc.backup + +# Update binary +cargo install --locked --force polkadot-omni-node@ + +# Restart service +sudo systemctl start polkadot-hub-rpc +``` + +## Security Best Practices + +### Network Security + +1. **Firewall Configuration**: + - Only expose necessary ports + - Use UFW or iptables to restrict access + - Consider IP whitelisting for RPC endpoints + +2. **Reverse Proxy** (Recommended for Production): + - Use nginx or Caddy as reverse proxy + - Enable SSL/TLS (HTTPS/WSS) + - Implement authentication + - Add rate limiting + +Example nginx configuration: + +```nginx +upstream polkadot_sdk_rpc { + server 127.0.0.1:9944; +} + +server { + listen 443 ssl http2; + server_name your-domain.com; + + ssl_certificate /path/to/cert.pem; + ssl_certificate_key /path/to/key.pem; + + # Polkadot SDK RPC + location /polkadot { + proxy_pass http://polkadot_sdk_rpc; + proxy_http_version 1.1; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection "upgrade"; + + # Rate limiting + limit_req zone=rpc_limit burst=10; + } +} +``` + +### RPC Security + +- **Always use `--rpc-methods=safe`**: Prevents dangerous RPC calls +- **Restrict CORS**: Use specific domains instead of `all` in production +- **Set connection limits**: Prevent resource exhaustion +- **Monitor for abuse**: Track unusual patterns +- **Authentication**: Implement API keys or OAuth for production + +### System Security + +- Keep operating system updated +- Use dedicated user accounts (never root) +- Enable fail2ban for SSH protection +- Regular security audits +- Disable unnecessary services +- Use AppArmor or SELinux for additional isolation + +### Monitoring and Alerting + +Set up alerts for: +- Service failures +- Sync issues +- Low peer count (< 10 peers) +- High resource usage +- Unusual RPC traffic patterns +- Database errors + +## Conclusion + +Running an RPC node for Polkadot Hub provides essential infrastructure for applications and users to interact with the network. By following this guide, you have set up a production-ready RPC node that: + +- Provides reliable access to Polkadot Hub's asset management, governance, and cross-chain communication features +- Supports both Docker and systemd deployment options for flexibility +- Implements proper monitoring, security, and maintenance practices +- Serves as a foundation for building and operating Polkadot SDK applications + +Regular maintenance, security updates, and monitoring will ensure your RPC node continues to serve your users reliably. As the Polkadot network evolves, stay informed about updates and best practices through the official channels and community resources listed in this guide. diff --git a/nodes-and-validators/run-a-node/.nav.yml b/node-infrastructure/run-a-node/relay-chain/.nav.yml similarity index 100% rename from nodes-and-validators/run-a-node/.nav.yml rename to node-infrastructure/run-a-node/relay-chain/.nav.yml diff --git a/nodes-and-validators/run-a-node/bootnode.md b/node-infrastructure/run-a-node/relay-chain/bootnode.md similarity index 100% rename from nodes-and-validators/run-a-node/bootnode.md rename to node-infrastructure/run-a-node/relay-chain/bootnode.md diff --git a/nodes-and-validators/run-a-node/full-node.md b/node-infrastructure/run-a-node/relay-chain/full-node.md similarity index 100% rename from nodes-and-validators/run-a-node/full-node.md rename to node-infrastructure/run-a-node/relay-chain/full-node.md diff --git a/nodes-and-validators/run-a-node/secure-wss.md b/node-infrastructure/run-a-node/relay-chain/secure-wss.md similarity index 100% rename from nodes-and-validators/run-a-node/secure-wss.md rename to node-infrastructure/run-a-node/relay-chain/secure-wss.md diff --git a/node-infrastructure/run-a-node/system-parachain-rpc.md b/node-infrastructure/run-a-node/system-parachain-rpc.md new file mode 100644 index 000000000..82823a719 --- /dev/null +++ b/node-infrastructure/run-a-node/system-parachain-rpc.md @@ -0,0 +1,649 @@ +--- +title: Run an RPC Node for System Parachains +description: Complete guide to set up and run an RPC node for Polkadot system parachains including Bridge Hub, People Chain, and Coretime Chain. +categories: Infrastructure +--- + +# Run an RPC Node for System Parachains + +## Overview + +System parachains are core infrastructure parachains that provide essential services to the Polkadot network. Running an RPC node for these parachains enables applications, wallets, and users to interact with their specialized functionality: + +- **Bridge Hub**: Cross-chain asset transfers via trustless bridges +- **People Chain**: Identity and social credential management +- **Coretime Chain**: Blockspace allocation and core time management + +Each system parachain RPC node provides access through: +- **Polkadot SDK Node RPC** (Port 9944): Native Polkadot API (WebSocket and HTTP) + +This setup enables block explorer indexing and provides full compatibility with Polkadot SDK development tools. + +**Important Note**: The parameters and configurations in this guide are provided as illustrative examples. You may need to modify them according to your specific environment, hardware capabilities, and network conditions. + +## Choosing a System Parachain + +This guide uses **People Chain** as the example, but the same principles and setup procedures apply to all system parachains. Simply substitute the appropriate values from the table below for your chosen parachain: + +| Parachain | Para ID | Chain Spec File | Snapshot Path | Chain Name | +|-----------|---------|-----------------|---------------|------------| +| **Bridge Hub** | 1002 | `bridge-hub-polkadot.json` | `polkadot-bridge-hub-rocksdb-archive` | `bridge-hub-polkadot` | +| **People Chain** | 1004 | `people-polkadot.json` | `polkadot-people-rocksdb-archive` | `people-polkadot` | +| **Coretime Chain** | 1005 | `coretime-polkadot.json` | `polkadot-coretime-rocksdb-archive` | `coretime-polkadot` | + +**Note**: Throughout this guide, we use People Chain values. To set up a different system parachain, replace the chain spec file, snapshot path, and chain name with the corresponding values from the table above. + +## Prerequisites + +### Hardware Requirements + +RPC nodes serving production traffic require robust hardware: + +- **CPU**: 8+ cores (16+ cores for high traffic) +- **Memory**: 64 GB RAM minimum (128 GB recommended for high traffic) +- **Storage**: + - 500 GB+ NVMe SSD for parachain state (archive nodes require 2-4 TB+) + - Additional 200+ GB for relay chain pruned database + - Fast disk I/O is critical for query performance +- **Network**: + - Public IP address + - 1 Gbps connection (for high traffic scenarios) + - Stable internet connection with sufficient bandwidth + - Open ports: + - 30333 (parachain P2P) + - 30334 (relay chain P2P) + - 9944 (Polkadot SDK WebSocket RPC) + - 9933 (Polkadot SDK HTTP RPC) + - 9615 (Prometheus metrics - optional) + - Consider DDoS protection and rate limiting for production deployments + +**Note**: For development or low-traffic scenarios, you can reduce these requirements proportionally. Consider using a reverse proxy (nginx, Caddy) for production deployments. + +### Software Requirements + +Required software: + +- **Operating System**: Ubuntu 22.04 LTS (recommended) or similar Linux distribution +- **Docker**: Latest version installed and running (for Docker-based setup) +- **rclone**: (Optional but recommended) Command-line program for managing files on cloud storage (https://rclone.org/downloads/) +- **Rust Toolchain**: Version 1.86 or as specified by runtime (for manual build) + +## Setup Options + +This guide provides two deployment options: + +1. **Docker-based Setup**: Simpler to set up and maintain +2. **Manual/Systemd Setup**: For production environments requiring more control + +Choose the option that best fits your needs. + +--- + +## Option 1: Docker-Based Setup + +This option uses Docker containers for the Polkadot SDK node, making it easy to set up and manage. + +### Step 1: Download Chain Specification + +Download the official chain specification for People Chain: + +```bash +curl -L https://raw.githubusercontent.com/paritytech/polkadot-sdk/master/cumulus/parachains/chain-specs/people-polkadot.json -o people-polkadot.json +``` + +**Note**: This chain specification is the official configuration file that defines the network parameters for People Chain. + +### Step 2: Download Database Snapshots (Optional but Recommended) + +Using pre-synchronized snapshots significantly reduces initial sync time from several days to just a few hours. You need to download both parachain and relay chain data. + +**Snapshot Provider**: https://snapshots.polkadot.io/ + +#### Create Directories + +```bash +mkdir -p my-node-data/chains/people-polkadot/db +mkdir -p my-node-data/chains/polkadot/db +``` + +#### Download People Chain Snapshot + +Choose between archive (complete history) or pruned (recent state) snapshots. + +**Archive Snapshot** (recommended for RPC with historical data): + +```bash +# Check https://snapshots.polkadot.io/ for the latest snapshot URL +export SNAPSHOT_URL_PARACHAIN="https://snapshots.polkadot.io/polkadot-people-rocksdb-archive/LATEST" + +rclone copyurl $SNAPSHOT_URL_PARACHAIN/files.txt files.txt +rclone copy --progress --transfers 20 \ + --http-url $SNAPSHOT_URL_PARACHAIN \ + --no-traverse --http-no-head --disable-http2 \ + --inplace --no-gzip-encoding --size-only \ + --retries 6 --retries-sleep 10s \ + --files-from files.txt :http: my-node-data/chains/people-polkadot/db/ + +rm files.txt +``` + +**Parameter Explanation**: +- `--transfers 20`: Uses 20 parallel transfers for faster download +- `--retries 6`: Automatically retries failed transfers up to 6 times +- `--retries-sleep 10s`: Waits 10 seconds between retry attempts +- `--size-only`: Only transfers if sizes differ (prevents unnecessary re-downloads) + +**Note**: If a snapshot is not available, you can sync from scratch (which will take longer) or check https://snapshots.polkadot.io/ for alternative snapshot providers. + +#### Download Polkadot Relay Chain Snapshot + +**Pruned Snapshot** (recommended for RPC nodes): + +```bash +# Check https://snapshots.polkadot.io/ for the latest snapshot URL +export SNAPSHOT_URL_RELAY="https://snapshots.polkadot.io/polkadot-rocksdb-prune/LATEST" + +rclone copyurl $SNAPSHOT_URL_RELAY/files.txt files.txt +rclone copy --progress --transfers 20 \ + --http-url $SNAPSHOT_URL_RELAY \ + --no-traverse --http-no-head --disable-http2 \ + --inplace --no-gzip-encoding --size-only \ + --retries 6 --retries-sleep 10s \ + --files-from files.txt :http: my-node-data/chains/polkadot/db/ + +rm files.txt +``` + +**Alternative Options**: +- Pruned snapshot: `polkadot-rocksdb-prune` (smaller size, recent state) +- Archive snapshot: `polkadot-rocksdb-archive` (complete history, larger size) + +### Step 3: Start People Chain Node + +Launch the node using the official Parity Docker image. + +**Docker Image**: https://hub.docker.com/r/parity/polkadot-omni-node + +```bash +docker run -d --name people-chain-rpc --restart unless-stopped \ + -p 9944:9944 \ + -p 9933:9933 \ + -p 9615:9615 \ + -p 30334:30334 \ + -p 30333:30333 \ + -v $(pwd)/people-polkadot.json:/people-polkadot.json \ + -v $(pwd)/my-node-data:/data \ + parity/polkadot-omni-node:stable2506-4 \ + --name=PeopleChainRPC \ + --base-path=/data \ + --chain=/people-polkadot.json \ + --prometheus-external \ + --prometheus-port 9615 \ + --unsafe-rpc-external \ + --rpc-port=9944 \ + --rpc-cors=all \ + --rpc-methods=safe \ + --rpc-max-connections=1000 \ + --state-pruning=archive \ + --blocks-pruning=archive \ + -- \ + --base-path=/data \ + --chain=polkadot \ + --state-pruning=256 \ + --blocks-pruning=archive-canonical +``` + +**Critical Configuration Parameters**: + +**Port Mappings**: +- `9944`: Polkadot SDK RPC endpoint (WebSocket/HTTP) +- `9933`: Polkadot SDK HTTP RPC endpoint +- `9615`: Prometheus metrics endpoint +- `30333/30334`: P2P networking ports + +**Node Parameters**: +- `--unsafe-rpc-external`: Enables external RPC access +- `--rpc-cors=all`: Allows all origins for CORS +- `--rpc-methods=safe`: Only allows safe RPC methods +- `--state-pruning=archive`: Keeps complete state history +- `--blocks-pruning=archive`: Keeps all block data +- `--prometheus-external`: Exposes metrics externally + +**Security Warning**: The `--unsafe-rpc-external` flag should only be used in development or properly secured environments. For production, use a reverse proxy with authentication. + +### Step 4: Monitor Synchronization + +Monitor the node synchronization status: + +```bash +# Check sync status +curl -H "Content-Type: application/json" \ + -d '{"id":1, "jsonrpc":"2.0", "method": "system_syncState", "params":[]}' \ + http://localhost:9944 +``` + +**Expected Response Format**: + +```json +{ + "jsonrpc":"2.0", + "id":1, + "result":{ + "startingBlock":0, + "currentBlock":3394816, + "highestBlock":3394816 + } +} +``` + +**Synchronization Status**: +- **In Progress**: `currentBlock` < `highestBlock` +- **Complete**: `currentBlock` = `highestBlock` + +**Monitor logs**: + +```bash +# View node logs +docker logs -f people-chain-rpc + +# Filter for sync messages +docker logs people-chain-rpc 2>&1 | grep -i "syncing" +``` + +### Step 5: Verify Setup + +Let's verify the Polkadot SDK RPC endpoint is working correctly. + +#### API Endpoint + +**Polkadot SDK RPC (Port 9944)**: +- WebSocket: `ws://your-server:9944` +- HTTP: `http://your-server:9944` +- Purpose: Full Polkadot SDK API access for parachain data +- Use Cases: Polkadot SDK applications, parachain-specific operations + +#### Polkadot SDK RPC Tests + +**Get Chain Information**: + +```bash +curl -H "Content-Type: application/json" \ + -d '{"id":1, "jsonrpc":"2.0", "method": "system_chain", "params":[]}' \ + http://localhost:9944 +``` + +**Expected Response**: +```json +{ + "jsonrpc":"2.0", + "id":1, + "result":"Polkadot People" +} +``` + +**Get Latest Block**: + +```bash +curl -H "Content-Type: application/json" \ + -d '{"id":1, "jsonrpc":"2.0", "method": "chain_getHeader", "params":[]}' \ + http://localhost:9944 +``` + +**Get Node Health**: + +```bash +curl -H "Content-Type: application/json" \ + -d '{"id":1, "jsonrpc":"2.0", "method": "system_health", "params":[]}' \ + http://localhost:9944 +``` + +**Get Peer Count**: + +```bash +curl -H "Content-Type: application/json" \ + -d '{"id":1, "jsonrpc":"2.0", "method": "system_peers", "params":[]}' \ + http://localhost:9944 +``` + +### Managing Docker Containers + +**View logs**: + +```bash +docker logs -f people-chain-rpc +``` + +**Stop container**: + +```bash +docker stop people-chain-rpc +``` + +**Start container**: + +```bash +docker start people-chain-rpc +``` + +**Remove container**: + +```bash +docker rm people-chain-rpc +``` + +**Update container**: + +```bash +# Pull latest image +docker pull parity/polkadot-omni-node:stable2506-4 + +# Stop and remove old container +docker stop people-chain-rpc +docker rm people-chain-rpc + +# Start new container with same command as above +``` + +--- + +## Option 2: Manual/Systemd Setup + +This option provides more control and is recommended for production environments requiring custom configurations. + +### Step 1: Install Rust and Required Toolchain + +```bash +# Install Rust +curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh +source $HOME/.cargo/env + +# Install specific Rust version +rustup install 1.86 +rustup default 1.86 +rustup target add wasm32-unknown-unknown --toolchain 1.86 +rustup component add rust-src --toolchain 1.86 +``` + +### Step 2: Install the Polkadot Omni Node + +```bash +# Install polkadot-omni-node +cargo install --locked polkadot-omni-node@0.7.0 + +# Verify installation +polkadot-omni-node --version +``` + +### Step 3: Obtain Chain Specification + +Download the People Chain specification: + +```bash +curl -L https://raw.githubusercontent.com/paritytech/polkadot-sdk/master/cumulus/parachains/chain-specs/people-polkadot.json -o people-polkadot.json +``` + +### Step 4: Create User and Directory Structure + +```bash +# Create dedicated user (skip if already exists) +sudo useradd -r -s /bin/bash polkadot + +# Create data directory +sudo mkdir -p /var/lib/people-chain-rpc + +# Copy chain spec to the directory +sudo cp people-polkadot.json /var/lib/people-chain-rpc/ + +# Set permissions +sudo chown -R polkadot:polkadot /var/lib/people-chain-rpc +``` + +### Step 5: Create Systemd Service + +Create a service file for the People Chain RPC node: + +```bash +sudo nano /etc/systemd/system/people-chain-rpc.service +``` + +Add the following configuration: + +```ini +[Unit] +Description=People Chain RPC Node +After=network.target + +[Service] +Type=simple +User=polkadot +Group=polkadot +WorkingDirectory=/var/lib/people-chain-rpc + +ExecStart=/usr/local/bin/polkadot-omni-node \ + --name=PeopleChainRPC \ + --chain=/var/lib/people-chain-rpc/people-polkadot.json \ + --base-path=/var/lib/people-chain-rpc \ + --port=30333 \ + --rpc-port=9944 \ + --rpc-external \ + --rpc-cors=all \ + --rpc-methods=safe \ + --rpc-max-connections=1000 \ + --prometheus-port=9615 \ + --prometheus-external \ + --state-pruning=archive \ + --blocks-pruning=archive \ + -- \ + --chain=polkadot \ + --base-path=/var/lib/people-chain-rpc \ + --port=30334 \ + --state-pruning=256 \ + --blocks-pruning=archive-canonical + +Restart=always +RestartSec=10 +LimitNOFILE=65536 + +[Install] +WantedBy=multi-user.target +``` + +### Step 6: Start Service + +```bash +# Reload systemd +sudo systemctl daemon-reload + +# Enable service to start on boot +sudo systemctl enable people-chain-rpc + +# Start the node +sudo systemctl start people-chain-rpc + +# Check status and wait for sync +sudo systemctl status people-chain-rpc +sudo journalctl -u people-chain-rpc -f +``` + +### Step 7: Verify Setup + +Use the same verification tests as in the Docker setup (see Step 5 above). + +--- + +## Monitoring and Maintenance + +### Log Management + +**Docker Setup**: + +```bash +# View node logs +docker logs -f people-chain-rpc +``` + +**Systemd Setup**: + +```bash +# View node logs +sudo journalctl -u people-chain-rpc -f + +# View recent logs +sudo journalctl -u people-chain-rpc -n 100 + +# Filter for errors +sudo journalctl -u people-chain-rpc | grep -i error +``` + +### Performance Monitoring + +Monitor key metrics: +- **Sync status**: Ensure node stays fully synced +- **Peer connections**: Maintain 30+ peers for good connectivity +- **Resource usage**: Monitor CPU, RAM, and disk I/O +- **RPC request latency**: Track response times for the Polkadot SDK API +- **Connection count**: Monitor active RPC connections + +**Prometheus Metrics**: + +Metrics are available at `http://localhost:9615/metrics` + +Example Prometheus scrape configuration: + +```yaml +scrape_configs: + - job_name: 'people-chain-rpc' + static_configs: + - targets: ['localhost:9615'] +``` + +**Key Metrics to Monitor**: +- `substrate_block_height`: Current block height +- `substrate_finalized_height`: Finalized block height +- `substrate_peers_count`: Number of connected peers +- `substrate_ready_transactions_number`: Transaction queue size + +### Database Maintenance + +Check database size periodically: + +```bash +# Docker setup +du -sh my-node-data + +# Systemd setup +du -sh /var/lib/people-chain-rpc +``` + +The node handles pruning automatically based on configuration unless running in archive mode. + +### Updates and Upgrades + +**Docker Setup**: + +```bash +# Pull latest image +docker pull parity/polkadot-omni-node:stable2506-4 + +# Restart container +docker stop people-chain-rpc +docker rm people-chain-rpc + +# Start new container (use same command from setup) +``` + +**Systemd Setup**: + +```bash +# Stop service +sudo systemctl stop people-chain-rpc + +# Backup data +sudo cp -r /var/lib/people-chain-rpc /var/lib/people-chain-rpc.backup + +# Update binary +cargo install --locked --force polkadot-omni-node@ + +# Restart service +sudo systemctl start people-chain-rpc +``` + +## Security Best Practices + +### Network Security + +1. **Firewall Configuration**: + - Only expose necessary ports + - Use UFW or iptables to restrict access + - Consider IP whitelisting for RPC endpoints + +2. **Reverse Proxy** (Recommended for Production): + - Use nginx or Caddy as reverse proxy + - Enable SSL/TLS (HTTPS/WSS) + - Implement authentication + - Add rate limiting + +Example nginx configuration: + +```nginx +upstream polkadot_sdk_rpc { + server 127.0.0.1:9944; +} + +server { + listen 443 ssl http2; + server_name your-domain.com; + + ssl_certificate /path/to/cert.pem; + ssl_certificate_key /path/to/key.pem; + + # Polkadot SDK RPC + location /polkadot { + proxy_pass http://polkadot_sdk_rpc; + proxy_http_version 1.1; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection "upgrade"; + + # Rate limiting + limit_req zone=rpc_limit burst=10; + } +} +``` + +### RPC Security + +- **Always use `--rpc-methods=safe`**: Prevents dangerous RPC calls +- **Restrict CORS**: Use specific domains instead of `all` in production +- **Set connection limits**: Prevent resource exhaustion +- **Monitor for abuse**: Track unusual patterns +- **Authentication**: Implement API keys or OAuth for production + +### System Security + +- Keep operating system updated +- Use dedicated user accounts (never root) +- Enable fail2ban for SSH protection +- Regular security audits +- Disable unnecessary services +- Use AppArmor or SELinux for additional isolation + +### Monitoring and Alerting + +Set up alerts for: +- Service failures +- Sync issues +- Low peer count (< 10 peers) +- High resource usage +- Unusual RPC traffic patterns +- Database errors + +## Conclusion + +Running an RPC node for system parachains provides critical infrastructure for accessing specialized Polkadot network services. By following this guide, you have set up a production-ready RPC node that: + +- Enables applications and users to interact with essential system parachain features (identity management, cross-chain bridges, or coretime allocation) +- Supports flexible deployment with both Docker and systemd options +- Implements comprehensive monitoring, security, and maintenance practices +- Can be easily adapted for any system parachain by substituting the appropriate chain specification + +Whether you're running a node for People Chain, Bridge Hub, or Coretime Chain, regular maintenance and monitoring will ensure your RPC node continues to provide reliable service. Stay updated with the latest releases and best practices to keep your infrastructure secure and performant. diff --git a/nodes-and-validators/run-a-validator/.nav.yml b/node-infrastructure/run-a-validator/.nav.yml similarity index 100% rename from nodes-and-validators/run-a-validator/.nav.yml rename to node-infrastructure/run-a-validator/.nav.yml diff --git a/nodes-and-validators/run-a-validator/onboarding-and-offboarding/.nav.yml b/node-infrastructure/run-a-validator/onboarding-and-offboarding/.nav.yml similarity index 100% rename from nodes-and-validators/run-a-validator/onboarding-and-offboarding/.nav.yml rename to node-infrastructure/run-a-validator/onboarding-and-offboarding/.nav.yml diff --git a/nodes-and-validators/run-a-validator/onboarding-and-offboarding/key-management.md b/node-infrastructure/run-a-validator/onboarding-and-offboarding/key-management.md similarity index 100% rename from nodes-and-validators/run-a-validator/onboarding-and-offboarding/key-management.md rename to node-infrastructure/run-a-validator/onboarding-and-offboarding/key-management.md diff --git a/nodes-and-validators/run-a-validator/onboarding-and-offboarding/set-up-validator.md b/node-infrastructure/run-a-validator/onboarding-and-offboarding/set-up-validator.md similarity index 100% rename from nodes-and-validators/run-a-validator/onboarding-and-offboarding/set-up-validator.md rename to node-infrastructure/run-a-validator/onboarding-and-offboarding/set-up-validator.md diff --git a/nodes-and-validators/run-a-validator/onboarding-and-offboarding/start-validating.md b/node-infrastructure/run-a-validator/onboarding-and-offboarding/start-validating.md similarity index 100% rename from nodes-and-validators/run-a-validator/onboarding-and-offboarding/start-validating.md rename to node-infrastructure/run-a-validator/onboarding-and-offboarding/start-validating.md diff --git a/nodes-and-validators/run-a-validator/onboarding-and-offboarding/stop-validating.md b/node-infrastructure/run-a-validator/onboarding-and-offboarding/stop-validating.md similarity index 100% rename from nodes-and-validators/run-a-validator/onboarding-and-offboarding/stop-validating.md rename to node-infrastructure/run-a-validator/onboarding-and-offboarding/stop-validating.md diff --git a/nodes-and-validators/run-a-validator/operational-tasks/.nav.yml b/node-infrastructure/run-a-validator/operational-tasks/.nav.yml similarity index 100% rename from nodes-and-validators/run-a-validator/operational-tasks/.nav.yml rename to node-infrastructure/run-a-validator/operational-tasks/.nav.yml diff --git a/nodes-and-validators/run-a-validator/operational-tasks/general-management.md b/node-infrastructure/run-a-validator/operational-tasks/general-management.md similarity index 100% rename from nodes-and-validators/run-a-validator/operational-tasks/general-management.md rename to node-infrastructure/run-a-validator/operational-tasks/general-management.md diff --git a/nodes-and-validators/run-a-validator/operational-tasks/pause-validating.md b/node-infrastructure/run-a-validator/operational-tasks/pause-validating.md similarity index 100% rename from nodes-and-validators/run-a-validator/operational-tasks/pause-validating.md rename to node-infrastructure/run-a-validator/operational-tasks/pause-validating.md diff --git a/nodes-and-validators/run-a-validator/operational-tasks/upgrade-your-node.md b/node-infrastructure/run-a-validator/operational-tasks/upgrade-your-node.md similarity index 100% rename from nodes-and-validators/run-a-validator/operational-tasks/upgrade-your-node.md rename to node-infrastructure/run-a-validator/operational-tasks/upgrade-your-node.md diff --git a/nodes-and-validators/run-a-validator/requirements.md b/node-infrastructure/run-a-validator/requirements.md similarity index 100% rename from nodes-and-validators/run-a-validator/requirements.md rename to node-infrastructure/run-a-validator/requirements.md diff --git a/nodes-and-validators/run-a-validator/staking-mechanics/.nav.yml b/node-infrastructure/run-a-validator/staking-mechanics/.nav.yml similarity index 100% rename from nodes-and-validators/run-a-validator/staking-mechanics/.nav.yml rename to node-infrastructure/run-a-validator/staking-mechanics/.nav.yml diff --git a/nodes-and-validators/run-a-validator/staking-mechanics/offenses-and-slashes.md b/node-infrastructure/run-a-validator/staking-mechanics/offenses-and-slashes.md similarity index 100% rename from nodes-and-validators/run-a-validator/staking-mechanics/offenses-and-slashes.md rename to node-infrastructure/run-a-validator/staking-mechanics/offenses-and-slashes.md diff --git a/nodes-and-validators/run-a-validator/staking-mechanics/rewards.md b/node-infrastructure/run-a-validator/staking-mechanics/rewards.md similarity index 100% rename from nodes-and-validators/run-a-validator/staking-mechanics/rewards.md rename to node-infrastructure/run-a-validator/staking-mechanics/rewards.md From cb3ac550933a2317744099cbda8be0d5327b776f Mon Sep 17 00:00:00 2001 From: Bruno Galvao Date: Wed, 19 Nov 2025 14:39:18 +0700 Subject: [PATCH 02/39] Update system parachain RPC guide to latest versions Update polkadot-omni-node from stable2506-4 to v1.20.2 and Rust from 1.86 to 1.91.1 in the system parachain RPC documentation. This ensures users are working with the latest stable releases. Changes: - Docker image: parity/polkadot-omni-node:v1.20.2 - Cargo package: polkadot-omni-node@0.11.0 - Rust toolchain: 1.91.1 All versions have been tested and verified to work correctly. --- .../run-a-node/system-parachain-rpc.md | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/node-infrastructure/run-a-node/system-parachain-rpc.md b/node-infrastructure/run-a-node/system-parachain-rpc.md index 82823a719..4cfb4b741 100644 --- a/node-infrastructure/run-a-node/system-parachain-rpc.md +++ b/node-infrastructure/run-a-node/system-parachain-rpc.md @@ -66,7 +66,7 @@ Required software: - **Operating System**: Ubuntu 22.04 LTS (recommended) or similar Linux distribution - **Docker**: Latest version installed and running (for Docker-based setup) - **rclone**: (Optional but recommended) Command-line program for managing files on cloud storage (https://rclone.org/downloads/) -- **Rust Toolchain**: Version 1.86 or as specified by runtime (for manual build) +- **Rust Toolchain**: Version 1.91.1 or as specified by runtime (for manual build) ## Setup Options @@ -173,7 +173,7 @@ docker run -d --name people-chain-rpc --restart unless-stopped \ -p 30333:30333 \ -v $(pwd)/people-polkadot.json:/people-polkadot.json \ -v $(pwd)/my-node-data:/data \ - parity/polkadot-omni-node:stable2506-4 \ + parity/polkadot-omni-node:v1.20.2 \ --name=PeopleChainRPC \ --base-path=/data \ --chain=/people-polkadot.json \ @@ -335,7 +335,7 @@ docker rm people-chain-rpc ```bash # Pull latest image -docker pull parity/polkadot-omni-node:stable2506-4 +docker pull parity/polkadot-omni-node:v1.20.2 # Stop and remove old container docker stop people-chain-rpc @@ -358,17 +358,17 @@ curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh source $HOME/.cargo/env # Install specific Rust version -rustup install 1.86 -rustup default 1.86 -rustup target add wasm32-unknown-unknown --toolchain 1.86 -rustup component add rust-src --toolchain 1.86 +rustup install 1.91.1 +rustup default 1.91.1 +rustup target add wasm32-unknown-unknown --toolchain 1.91.1 +rustup component add rust-src --toolchain 1.91.1 ``` ### Step 2: Install the Polkadot Omni Node ```bash # Install polkadot-omni-node -cargo install --locked polkadot-omni-node@0.7.0 +cargo install --locked polkadot-omni-node@0.11.0 # Verify installation polkadot-omni-node --version @@ -543,7 +543,7 @@ The node handles pruning automatically based on configuration unless running in ```bash # Pull latest image -docker pull parity/polkadot-omni-node:stable2506-4 +docker pull parity/polkadot-omni-node:v1.20.2 # Restart container docker stop people-chain-rpc From 9105f65d9c323275dcf3687909d219d8a713af43 Mon Sep 17 00:00:00 2001 From: Bruno Galvao Date: Wed, 19 Nov 2025 17:06:56 +0700 Subject: [PATCH 03/39] Update software versions and dependencies - Update Rust toolchain to 1.91.1 (from 1.86) - Update polkadot-omni-node to v0.11.0 for collator (from v0.5.0) - Update Docker image to v1.20.2 for RPC nodes (from stable2506-4) - Update chain-spec-builder to v14.0.0 (from v10.0.0) - Update AI-generated page files to reflect latest changes - Clean up old nodes-and-validators AI page files --- ...-infrastructure-run-a-collator-collator.md | 14 +- ...rastructure-run-a-node-polkadot-hub-rpc.md | 40 +- ...ucture-run-a-node-relay-chain-full-node.md | 2 +- ...ructure-run-a-node-system-parachain-rpc.md | 18 +- ...arding-and-offboarding-start-validating.md | 1 - ...odes-and-validators-run-a-node-bootnode.md | 130 ---- ...des-and-validators-run-a-node-full-node.md | 338 -------- ...es-and-validators-run-a-node-secure-wss.md | 125 --- ...boarding-and-offboarding-key-management.md | 155 ---- ...arding-and-offboarding-set-up-validator.md | 213 ------ ...arding-and-offboarding-start-validating.md | 254 ------ ...oarding-and-offboarding-stop-validating.md | 45 -- ...or-operational-tasks-general-management.md | 722 ------------------ ...ator-operational-tasks-pause-validating.md | 46 -- ...tor-operational-tasks-upgrade-your-node.md | 75 -- ...validators-run-a-validator-requirements.md | 85 --- ...-staking-mechanics-offenses-and-slashes.md | 171 ----- ...n-a-validator-staking-mechanics-rewards.md | 204 ----- .../run-a-collator/collator.md | 14 +- .../run-a-node/polkadot-hub-rpc.md | 40 +- 20 files changed, 74 insertions(+), 2618 deletions(-) delete mode 100644 .ai/pages/nodes-and-validators-run-a-node-bootnode.md delete mode 100644 .ai/pages/nodes-and-validators-run-a-node-full-node.md delete mode 100644 .ai/pages/nodes-and-validators-run-a-node-secure-wss.md delete mode 100644 .ai/pages/nodes-and-validators-run-a-validator-onboarding-and-offboarding-key-management.md delete mode 100644 .ai/pages/nodes-and-validators-run-a-validator-onboarding-and-offboarding-set-up-validator.md delete mode 100644 .ai/pages/nodes-and-validators-run-a-validator-onboarding-and-offboarding-start-validating.md delete mode 100644 .ai/pages/nodes-and-validators-run-a-validator-onboarding-and-offboarding-stop-validating.md delete mode 100644 .ai/pages/nodes-and-validators-run-a-validator-operational-tasks-general-management.md delete mode 100644 .ai/pages/nodes-and-validators-run-a-validator-operational-tasks-pause-validating.md delete mode 100644 .ai/pages/nodes-and-validators-run-a-validator-operational-tasks-upgrade-your-node.md delete mode 100644 .ai/pages/nodes-and-validators-run-a-validator-requirements.md delete mode 100644 .ai/pages/nodes-and-validators-run-a-validator-staking-mechanics-offenses-and-slashes.md delete mode 100644 .ai/pages/nodes-and-validators-run-a-validator-staking-mechanics-rewards.md diff --git a/.ai/pages/node-infrastructure-run-a-collator-collator.md b/.ai/pages/node-infrastructure-run-a-collator-collator.md index 18babcfa8..1f6f96cc6 100644 --- a/.ai/pages/node-infrastructure-run-a-collator-collator.md +++ b/.ai/pages/node-infrastructure-run-a-collator-collator.md @@ -63,7 +63,7 @@ Required software: - **Operating System**: Ubuntu 22.04 LTS (recommended) or similar Linux distribution - **Docker**: For running subkey utility -- **Rust Toolchain**: Version 1.86 or as specified by the runtime +- **Rust Toolchain**: Version 1.91.1 or as specified by the runtime - **Dependencies**: ```bash sudo apt update @@ -87,17 +87,17 @@ curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh source $HOME/.cargo/env # Install specific Rust version -rustup install 1.86 -rustup default 1.86 -rustup target add wasm32-unknown-unknown --toolchain 1.86 -rustup component add rust-src --toolchain 1.86 +rustup install 1.91.1 +rustup default 1.91.1 +rustup target add wasm32-unknown-unknown --toolchain 1.91.1 +rustup component add rust-src --toolchain 1.91.1 ``` ### Step 2: Install the Polkadot Omni Node ```bash # Install polkadot-omni-node -cargo install --locked polkadot-omni-node@0.5.0 +cargo install --locked polkadot-omni-node@0.11.0 # Verify installation polkadot-omni-node --version @@ -159,7 +159,7 @@ cd runtimes cargo build --release -p asset-hub-polkadot-runtime # Install chain-spec-builder -cargo install --locked staging-chain-spec-builder@10.0.0 +cargo install --locked staging-chain-spec-builder@14.0.0 # Generate chain spec chain-spec-builder create \ diff --git a/.ai/pages/node-infrastructure-run-a-node-polkadot-hub-rpc.md b/.ai/pages/node-infrastructure-run-a-node-polkadot-hub-rpc.md index 7282f2ef0..ed95abd5d 100644 --- a/.ai/pages/node-infrastructure-run-a-node-polkadot-hub-rpc.md +++ b/.ai/pages/node-infrastructure-run-a-node-polkadot-hub-rpc.md @@ -55,7 +55,7 @@ Required software: - **Operating System**: Ubuntu 22.04 LTS (recommended) or similar Linux distribution - **Docker**: Latest version installed and running (for Docker-based setup) - **rclone**: (Optional but recommended) Command-line program for managing files on cloud storage (https://rclone.org/downloads/) -- **Rust Toolchain**: Version 1.86 or as specified by runtime (for manual build) +- **Rust Toolchain**: Version 1.91.1 or later (for manual build) ## Setup Options @@ -160,7 +160,7 @@ docker run -d --name polkadot-hub-rpc --restart unless-stopped \ -p 30333:30333 \ -v $(pwd)/asset-hub-polkadot.json:/asset-hub-polkadot.json \ -v $(pwd)/my-node-data:/data \ - parity/polkadot-omni-node:stable2506-4 \ + parity/polkadot-omni-node:v1.20.2 \ --name=PolkadotHubRPC \ --base-path=/data \ --chain=/asset-hub-polkadot.json \ @@ -306,7 +306,7 @@ docker rm polkadot-hub-rpc ```bash # Pull latest image -docker pull parity/polkadot-omni-node:stable2506-4 +docker pull parity/polkadot-omni-node:v1.20.2 # Stop and remove old container docker stop polkadot-hub-rpc @@ -329,23 +329,33 @@ curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh source $HOME/.cargo/env # Install specific Rust version -rustup install 1.86 -rustup default 1.86 -rustup target add wasm32-unknown-unknown --toolchain 1.86 -rustup component add rust-src --toolchain 1.86 +rustup install 1.91.1 +rustup default 1.91.1 +rustup target add wasm32-unknown-unknown --toolchain 1.91.1 +rustup component add rust-src --toolchain 1.91.1 ``` -### Step 2: Install the Polkadot Omni Node +### Step 2: Install Required Dependencies + +```bash +# Install system dependencies +sudo apt update +sudo apt install -y build-essential git clang curl libssl-dev llvm libudev-dev make protobuf-compiler +``` + +### Step 3: Install the Polkadot Omni Node ```bash # Install polkadot-omni-node -cargo install --locked polkadot-omni-node@0.7.0 +cargo install --locked polkadot-omni-node@0.11.0 # Verify installation polkadot-omni-node --version ``` -### Step 3: Obtain Chain Specification +**Note**: Compiling polkadot-omni-node from source requires significant RAM (minimum 24GB recommended). The compilation may take 10-15 minutes on systems with adequate resources. + +### Step 4: Obtain Chain Specification Download the Polkadot Hub chain specification: @@ -353,7 +363,7 @@ Download the Polkadot Hub chain specification: curl -L https://raw.githubusercontent.com/paritytech/polkadot-sdk/master/cumulus/parachains/chain-specs/asset-hub-polkadot.json -o asset-hub-polkadot.json ``` -### Step 4: Create User and Directory Structure +### Step 5: Create User and Directory Structure ```bash # Create dedicated user @@ -369,7 +379,7 @@ sudo cp asset-hub-polkadot.json /var/lib/polkadot-hub-rpc/ sudo chown -R polkadot:polkadot /var/lib/polkadot-hub-rpc ``` -### Step 5: Create Systemd Service for Polkadot SDK Node +### Step 6: Create Systemd Service for Polkadot SDK Node Create a service file for the Polkadot SDK RPC node: @@ -419,7 +429,7 @@ LimitNOFILE=65536 WantedBy=multi-user.target ``` -### Step 6: Start Service +### Step 7: Start Service ```bash # Reload systemd @@ -436,7 +446,7 @@ sudo systemctl status polkadot-hub-rpc sudo journalctl -u polkadot-hub-rpc -f ``` -### Step 7: Verify Setup +### Step 8: Verify Setup Use the same verification tests as in the Docker setup (see Step 5 above). @@ -516,7 +526,7 @@ The node handles pruning automatically based on configuration unless running in ```bash # Pull latest image -docker pull parity/polkadot-omni-node:stable2506-4 +docker pull parity/polkadot-omni-node:v1.20.2 # Restart container docker stop polkadot-hub-rpc diff --git a/.ai/pages/node-infrastructure-run-a-node-relay-chain-full-node.md b/.ai/pages/node-infrastructure-run-a-node-relay-chain-full-node.md index 17f93a8f1..05c3394fc 100644 --- a/.ai/pages/node-infrastructure-run-a-node-relay-chain-full-node.md +++ b/.ai/pages/node-infrastructure-run-a-node-relay-chain-full-node.md @@ -23,7 +23,7 @@ Now that you're familiar with the different types of nodes, this section will wa Before getting started, ensure the following prerequisites are met: -- Ensure [Rust](https://www.rust-lang.org/tools/install){target=\_blank} is installed on your operating system. +- Ensure [Rust](https://rust-lang.org/tools/install/){target=\_blank} is installed on your operating system. - [Install the necessary dependencies for the Polkadot SDK](/parachains/install-polkadot-sdk/){target=\_blank}. !!! warning diff --git a/.ai/pages/node-infrastructure-run-a-node-system-parachain-rpc.md b/.ai/pages/node-infrastructure-run-a-node-system-parachain-rpc.md index c5d5b13cc..9d3fc5735 100644 --- a/.ai/pages/node-infrastructure-run-a-node-system-parachain-rpc.md +++ b/.ai/pages/node-infrastructure-run-a-node-system-parachain-rpc.md @@ -67,7 +67,7 @@ Required software: - **Operating System**: Ubuntu 22.04 LTS (recommended) or similar Linux distribution - **Docker**: Latest version installed and running (for Docker-based setup) - **rclone**: (Optional but recommended) Command-line program for managing files on cloud storage (https://rclone.org/downloads/) -- **Rust Toolchain**: Version 1.86 or as specified by runtime (for manual build) +- **Rust Toolchain**: Version 1.91.1 or as specified by runtime (for manual build) ## Setup Options @@ -174,7 +174,7 @@ docker run -d --name people-chain-rpc --restart unless-stopped \ -p 30333:30333 \ -v $(pwd)/people-polkadot.json:/people-polkadot.json \ -v $(pwd)/my-node-data:/data \ - parity/polkadot-omni-node:stable2506-4 \ + parity/polkadot-omni-node:v1.20.2 \ --name=PeopleChainRPC \ --base-path=/data \ --chain=/people-polkadot.json \ @@ -336,7 +336,7 @@ docker rm people-chain-rpc ```bash # Pull latest image -docker pull parity/polkadot-omni-node:stable2506-4 +docker pull parity/polkadot-omni-node:v1.20.2 # Stop and remove old container docker stop people-chain-rpc @@ -359,17 +359,17 @@ curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh source $HOME/.cargo/env # Install specific Rust version -rustup install 1.86 -rustup default 1.86 -rustup target add wasm32-unknown-unknown --toolchain 1.86 -rustup component add rust-src --toolchain 1.86 +rustup install 1.91.1 +rustup default 1.91.1 +rustup target add wasm32-unknown-unknown --toolchain 1.91.1 +rustup component add rust-src --toolchain 1.91.1 ``` ### Step 2: Install the Polkadot Omni Node ```bash # Install polkadot-omni-node -cargo install --locked polkadot-omni-node@0.7.0 +cargo install --locked polkadot-omni-node@0.11.0 # Verify installation polkadot-omni-node --version @@ -546,7 +546,7 @@ The node handles pruning automatically based on configuration unless running in ```bash # Pull latest image -docker pull parity/polkadot-omni-node:stable2506-4 +docker pull parity/polkadot-omni-node:v1.20.2 # Restart container docker stop people-chain-rpc diff --git a/.ai/pages/node-infrastructure-run-a-validator-onboarding-and-offboarding-start-validating.md b/.ai/pages/node-infrastructure-run-a-validator-onboarding-and-offboarding-start-validating.md index 3065d19f1..0ca3cc0fc 100644 --- a/.ai/pages/node-infrastructure-run-a-validator-onboarding-and-offboarding-start-validating.md +++ b/.ai/pages/node-infrastructure-run-a-validator-onboarding-and-offboarding-start-validating.md @@ -149,7 +149,6 @@ Follow these steps to use Polkadot.js Apps to activate your validator: ![](/images/nodes-and-validators/run-a-validator/onboarding-and-offboarding/start-validating/start-validating-05.webp) - ### Monitor Validation Status and Slots On the [**Staking**](https://polkadot.js.org/apps/#/staking){target=\_blank} tab in Polkadot.js Apps, you can see your validator's status, the number of available validator slots, and the nodes that have signaled their intent to validate. Your node may initially appear in the waiting queue, especially if the validator slots are full. The following is an example view of the **Staking** tab: diff --git a/.ai/pages/nodes-and-validators-run-a-node-bootnode.md b/.ai/pages/nodes-and-validators-run-a-node-bootnode.md deleted file mode 100644 index 33f135611..000000000 --- a/.ai/pages/nodes-and-validators-run-a-node-bootnode.md +++ /dev/null @@ -1,130 +0,0 @@ ---- -title: Set Up a Bootnode -description: Learn how to configure and run a bootnode for Polkadot, including P2P, WS, and secure WSS connections with network key management and proxies. -categories: Infrastructure -url: https://docs.polkadot.com/nodes-and-validators/run-a-node/bootnode/ ---- - -# Set Up a Bootnode - -## Introduction - -Bootnodes are essential for helping blockchain nodes discover peers and join the network. When a node starts, it needs to find other nodes, and bootnodes provide an initial point of contact. Once connected, a node can expand its peer connections and play its role in the network, like participating as a validator. - -This guide will walk you through setting up a Polkadot bootnode, configuring P2P, WebSocket (WS), secure WSS connections, and managing network keys. You'll also learn how to test your bootnode to ensure it is running correctly and accessible to other nodes. - -## Prerequisites - -Before you start, you need to have the following prerequisites: - -- Verify a working Polkadot (`polkadot`) binary is available on your machine. -- Ensure you have nginx installed. Please refer to the [Installation Guide](https://nginx.org/en/docs/install.html){target=\_blank} for help with installation if needed. -- A VPS or other dedicated server setup. - -## Accessing the Bootnode - -Bootnodes must be accessible through three key channels to connect with other nodes in the network: - -- **P2P**: A direct peer-to-peer connection, set by. - - ```bash - - --listen-addr /ip4/0.0.0.0/tcp/INSERT_PORT - - ``` - - This is not enabled by default on non-validator nodes like archive RPC nodes. - -- **P2P/WS**: A WebSocket (WS) connection, also configured via `--listen-addr`. -- **P2P/WSS**: A secure WebSocket (WSS) connection using SSL, often required for light clients. An SSL proxy is needed, as the node itself cannot handle certificates. - -## Node Key - -A node key is the ED25519 key used by `libp2p` to assign your node an identity or peer ID. Generating a known node key for a bootnode is crucial, as it gives you a consistent key that can be placed in chain specifications as a known, reliable bootnode. - -Starting a node creates its node key in the `chains/INSERT_CHAIN/network/secret_ed25519` file. - -You can create a node key using: - - ``` bash - polkadot key generate-node-key - ``` - -This key can be used in the startup command line. - -It is imperative that you backup the node key. If it is included in the `polkadot` binary, it is hardcoded into the binary, which must be recompiled to change the key. - -## Running the Bootnode - -A bootnode can be run as follows: - - ``` bash - polkadot --chain polkadot \ - --name dot-bootnode \ - --listen-addr /ip4/0.0.0.0/tcp/30310 \ - --listen-addr /ip4/0.0.0.0/tcp/30311/ws - ``` - -This assigns the p2p to port 30310 and p2p/ws to port 30311. For the p2p/wss port, a proxy must be set up with a DNS name and a corresponding certificate. The following example is for the popular nginx server and enables p2p/wss on port 30312 by adding a proxy to the p2p/ws port 30311: - -``` conf title="/etc/nginx/sites-enabled/dot-bootnode" -server { - listen 30312 ssl http2 default_server; - server_name dot-bootnode.stakeworld.io; - root /var/www/html; - - ssl_certificate "INSERT_YOUR_CERT"; - ssl_certificate_key "INSERT_YOUR_KEY"; - - location / { - proxy_buffers 16 4k; - proxy_buffer_size 2k; - proxy_pass http://localhost:30311; - proxy_http_version 1.1; - proxy_set_header Upgrade $http_upgrade; - proxy_set_header Connection "Upgrade"; - proxy_set_header Host $host; - } - -} -``` - -## Testing Bootnode Connection - -If the preceding node is running with DNS name `dot-bootnode.stakeworld.io`, which contains a proxy with a valid certificate and node-id `12D3KooWAb5MyC1UJiEQJk4Hg4B2Vi3AJdqSUhTGYUqSnEqCFMFg` then the following commands should output `syncing 1 peers`. - -!!!tip - You can add `-lsub-libp2p=trace` on the end to get libp2p trace logging for debugging purposes. - -### P2P - -```bash -polkadot --chain polkadot \ ---base-path /tmp/node \ ---name "Bootnode testnode" \ ---reserved-only \ ---reserved-nodes "/dns/dot-bootnode.stakeworld.io/tcp/30310/p2p/12D3KooWAb5MyC1UJiEQJk4Hg4B2Vi3AJdqSUhTGYUqSnEqCFMFg" \ ---no-hardware-benchmarks -``` - -### P2P/WS - -```bash -polkadot --chain polkadot \ ---base-path /tmp/node \ ---name "Bootnode testnode" \ ---reserved-only \ ---reserved-nodes "/dns/dot-bootnode.stakeworld.io/tcp/30311/ws/p2p/12D3KooWAb5MyC1UJiEQJk4Hg4B2Vi3AJdqSUhTGYUqSnEqCFMFg" \ ---no-hardware-benchmarks -``` - -### P2P/WSS - -```bash -polkadot --chain polkadot \ ---base-path /tmp/node \ ---name "Bootnode testnode" \ ---reserved-only \ ---reserved-nodes "/dns/dot-bootnode.stakeworld.io/tcp/30312/wss/p2p/12D3KooWAb5MyC1UJiEQJk4Hg4B2Vi3AJdqSUhTGYUqSnEqCFMFg" \ ---no-hardware-benchmarks -``` diff --git a/.ai/pages/nodes-and-validators-run-a-node-full-node.md b/.ai/pages/nodes-and-validators-run-a-node-full-node.md deleted file mode 100644 index 8ba35da3c..000000000 --- a/.ai/pages/nodes-and-validators-run-a-node-full-node.md +++ /dev/null @@ -1,338 +0,0 @@ ---- -title: Set Up a Node -description: Learn how to install, configure, and run Polkadot nodes, including setting up different node types and connecting to the network. -categories: Infrastructure -url: https://docs.polkadot.com/nodes-and-validators/run-a-node/full-node/ ---- - -# Set Up a Node - -## Introduction - -Running a node on Polkadot provides direct interaction with the network, enhanced privacy, and full control over RPC requests, transactions, and data queries. As the backbone of the network, nodes ensure decentralized data propagation, transaction validation, and seamless communication across the ecosystem. - -Polkadot supports multiple node types, including pruned, archive, and light nodes, each suited to specific use cases. During setup, you can use configuration flags to choose the node type you wish to run. - -This guide walks you through configuring, securing, and maintaining a node on Polkadot or any Polkadot SDK-based chain. It covers instructions for the different node types and how to safely expose your node's RPC server for external access. Whether you're building a local development environment, powering dApps, or supporting network decentralization, this guide provides all the essentials. - -## Set Up a Node - -Now that you're familiar with the different types of nodes, this section will walk you through configuring, securing, and maintaining a node on Polkadot or any Polkadot SDK-based chain. - -### Prerequisites - -Before getting started, ensure the following prerequisites are met: - -- Ensure [Rust](https://rust-lang.org/tools/install/){target=\_blank} is installed on your operating system. -- [Install the necessary dependencies for the Polkadot SDK](/parachains/install-polkadot-sdk/){target=\_blank}. - -!!! warning - This setup is not recommended for validators. If you plan to run a validator, refer to the [Running a Validator](/nodes-and-validators/run-a-validator/onboarding-and-offboarding/set-up-validator/){target=\_blank} guide for proper instructions. - -### Install and Build the Polkadot Binary - -This section will walk you through installing and building the Polkadot binary for different operating systems and methods. - -??? interface "macOS" - - To get started, update and configure the Rust toolchain by running the following commands: - - ```bash - source ~/.cargo/env - - rustup default stable - rustup update - - rustup update nightly - rustup target add wasm32-unknown-unknown --toolchain nightly - rustup component add rust-src --toolchain stable-aarch64-apple-darwin - ``` - - You can verify your installation by running: - - ```bash - rustup show - rustup +nightly show - ``` - - You should see output similar to the following: - -
- rustup show
- rustup +nightly show
- active toolchain - ---------------- - - stable-aarch64-apple-darwin (default) - rustc 1.82.0 (f6e511eec 2024-10-15) - - active toolchain - ---------------- - - nightly-aarch64-apple-darwin (overridden by +toolchain on the command line) - rustc 1.84.0-nightly (03ee48451 2024-11-18) - -
- - Then, run the following commands to clone and build the Polkadot binary: - - ```bash - git clone https://github.com/paritytech/polkadot-sdk polkadot-sdk - cd polkadot-sdk - cargo build --release - ``` - - Depending upon the specs of your machine, compiling the binary may take an hour or more. After building the Polkadot node from source, the executable binary will be located in the `./target/release/polkadot` directory. - -??? interface "Windows" - - To get started, make sure that you have [WSL and Ubuntu](https://learn.microsoft.com/en-us/windows/wsl/install){target=\_blank} installed on your Windows machine. - - Once installed, you have a couple options for installing the Polkadot binary: - - - If Rust is installed, then `cargo` can be used similar to the macOS instructions. - - Or, the instructions in the Linux section can be used. - -??? interface "Linux (pre-built binary)" - - To grab the [latest release of the Polkadot binary](https://github.com/paritytech/polkadot-sdk/releases){target=\_blank}, you can use `wget`: - - ```bash - wget https://github.com/paritytech/polkadot-sdk/releases/download/polkadot-INSERT_VERSION/polkadot - ``` - - Ensure you note the executable binary's location, as you'll need to use it when running the start-up command. If you prefer, you can specify the output location of the executable binary with the `-O` flag, for example: - - ```bash - wget https://github.com/paritytech/polkadot-sdk/releases/download/polkadot-INSERT_VERSION/polkadot \ - - O /var/lib/polkadot-data/polkadot - ``` - - !!!tip - The nature of pre-built binaries means that they may not work on your particular architecture or Linux distribution. If you see an error like `cannot execute binary file: Exec format error` it likely means the binary is incompatible with your system. You will either need to compile the binary or use [Docker](#use-docker). - - Ensure that you properly configure the permissions to make the Polkadot release binary executable: - - ```bash - sudo chmod +x polkadot - ``` - -??? interface "Linux (compile binary)" - - The most reliable (although perhaps not the fastest) way of launching a full node is to compile the binary yourself. Depending on your machine's specs, this may take an hour or more. - - To get started, run the following commands to configure the Rust toolchain: - - ```bash - rustup default stable - rustup update - rustup update nightly - rustup target add wasm32-unknown-unknown --toolchain nightly - rustup target add wasm32-unknown-unknown --toolchain stable-x86_64-unknown-linux-gnu - rustup component add rust-src --toolchain stable-x86_64-unknown-linux-gnu - ``` - - You can verify your installation by running: - - ```bash - rustup show - ``` - - You should see output similar to the following: - -
- rustup show
- rustup +nightly show
- active toolchain - ---------------- - - stable-x86_64-unknown-linux-gnu (default) - rustc 1.82.0 (f6e511eec 2024-10-15) -
- - Once Rust is configured, run the following commands to clone and build Polkadot: - - ```bash - git clone https://github.com/paritytech/polkadot-sdk polkadot-sdk - cd polkadot-sdk - cargo build --release - ``` - - Compiling the binary may take an hour or more, depending on your machine's specs. After building the Polkadot node from the source, the executable binary will be located in the `./target/release/polkadot` directory. - -??? interface "Linux (snap package)" - - Polkadot can be installed as a [snap package](https://snapcraft.io/polkadot){target=\_blank}. If you don't already have Snap installed, take the following steps to install it: - - ```bash - sudo apt update - sudo apt install snapd - ``` - - Install the Polkadot snap package: - - ```bash - sudo snap install polkadot - ``` - - Before continuing on with the following instructions, check out the [Configure and Run Your Node](#configure-and-run-your-node) section to learn more about the configuration options. - - To configure your Polkadot node with your desired options, you'll run a command similar to the following: - - ```bash - sudo snap set polkadot service-args="--name=MyName --chain=polkadot" - ``` - - Then to start the node service, run: - - ```bash - sudo snap start polkadot - ``` - - You can review the logs to check on the status of the node: - - ```bash - snap logs polkadot -f - ``` - - And at any time, you can stop the node service: - - ```bash - sudo snap stop polkadot - ``` - - You can optionally prevent the service from stopping when snap is updated with the following command: - - ```bash - sudo snap set polkadot endure=true - ``` - -### Use Docker - -As an additional option, you can use Docker to run your node in a container. Doing this is more advanced, so it's best left up to those already familiar with Docker or who have completed the other set-up instructions in this guide. You can review the latest versions on [DockerHub](https://hub.docker.com/r/parity/polkadot/tags){target=\_blank}. - -Be aware that when you run Polkadot in Docker, the process only listens on `localhost` by default. If you would like to connect to your node's services (RPC and Prometheus) you need to ensure that you run the node with the `--rpc-external`, and `--prometheus-external` commands. - -```bash -docker run -p 9944:9944 -p 9615:9615 parity/polkadot:v1.16.2 --name "my-polkadot-node-calling-home" --rpc-external --prometheus-external -``` - -If you're running Docker on an Apple Silicon machine (e.g. M4), you'll need to adapt the command slightly: - -```bash -docker run --platform linux/amd64 -p 9944:9944 -p 9615:9615 parity/polkadot:v1.16.2 --name "kearsarge-calling-home" --rpc-external --prometheus-external -``` - -## Configure and Run Your Node - -Now that you've installed and built the Polkadot binary, the next step is to configure the start-up command depending on the type of node that you want to run. You'll need to modify the start-up command accordingly based on the location of the binary. In some cases, it may be located within the `./target/release/` folder, so you'll need to replace polkadot with `./target/release/polkadot` in the following commands. - -Also, note that you can use the same binary for Polkadot as you would for Kusama or any other relay chain. You'll need to use the `--chain` flag to differentiate between chains. - -The base commands for running a Polkadot node are as follows: - -=== "Default pruned node" - - This uses the default pruning value of the last 256 blocks: - - ```bash - polkadot --chain polkadot \ - --name "INSERT_NODE_NAME" - ``` - -=== "Custom pruned node" - - You can customize the pruning value, for example, to the last 1000 finalized blocks: - - ```bash - polkadot --chain polkadot \ - --name INSERT_YOUR_NODE_NAME \ - --state-pruning 1000 \ - --blocks-pruning archive \ - --rpc-cors all \ - --rpc-methods safe - ``` - -=== "Archive node" - - To support the full state, use the `archive` option: - - ```bash - polkadot --chain polkadot \ - --name INSERT_YOUR_NODE_NAME \ - --state-pruning archive \ - --blocks-pruning archive \ - ``` - -If you want to run an RPC node, please refer to the following [RPC Configurations](#rpc-configurations) section. - -To review a complete list of the available commands, flags, and options, you can use the `--help` flag: - -```bash -polkadot --help -``` - -Once you've fully configured your start-up command, you can execute it in your terminal and your node will start [syncing](#sync-your-node). - -### RPC Configurations - -The node startup settings allow you to choose what to expose, how many connections to expose, and which systems should be granted access through the RPC server. - -- You can limit the methods to use with `--rpc-methods`; an easy way to set this to a safe mode is `--rpc-methods safe`. -- You can set your maximum connections through `--rpc-max-connections`, for example, `--rpc-max-connections 200`. -- By default, localhost and Polkadot.js can access the RPC server. You can change this by setting `--rpc-cors`. To allow access from everywhere, you can use `--rpc-cors all`. - -For a list of important flags when running RPC nodes, refer to the Parity DevOps documentation: [Important Flags for Running an RPC Node](https://paritytech.github.io/devops-guide/guides/rpc_index.html?#important-flags-for-running-an-rpc-node){target=\_blank}. - -## Sync Your Node - -The syncing process will take a while, depending on your capacity, processing power, disk speed, and RAM. The process may be completed on a $10 DigitalOcean droplet in about ~36 hours. While syncing, your node name should be visible in gray on Polkadot Telemetry, and once it is fully synced, your node name will appear in white on [Polkadot Telemetry](https://telemetry.polkadot.io/#list/Polkadot){target=_blank}. - -A healthy node syncing blocks will output logs like the following: - -
- 2024-11-19 23:49:57 Parity Polkadot - 2024-11-19 23:49:57 ✌️ version 1.14.1-7c4cd60da6d - 2024-11-19 23:49:57 ❤️ by Parity Technologies <admin@parity.io>, 2017-2024 - 2024-11-19 23:49:57 📋 Chain specification: Polkadot - 2024-11-19 23:49:57 🏷 Node name: myPolkadotNode - 2024-11-19 23:49:57 👤 Role: FULL - 2024-11-19 23:49:57 💾 Database: RocksDb at /home/ubuntu/.local/share/polkadot/chains/polkadot/db/full - 2024-11-19 23:50:00 🏷 Local node identity is: 12D3KooWDmhHEgPRJUJnUpJ4TFWn28EENqvKWH4dZGCN9TS51y9h - 2024-11-19 23:50:00 Running libp2p network backend - 2024-11-19 23:50:00 💻 Operating system: linux - 2024-11-19 23:50:00 💻 CPU architecture: x86_64 - 2024-11-19 23:50:00 💻 Target environment: gnu - 2024-11-19 23:50:00 💻 CPU: Intel(R) Xeon(R) CPU E3-1245 V2 @ 3.40GHz - 2024-11-19 23:50:00 💻 CPU cores: 4 - 2024-11-19 23:50:00 💻 Memory: 32001MB - 2024-11-19 23:50:00 💻 Kernel: 5.15.0-113-generic - 2024-11-19 23:50:00 💻 Linux distribution: Ubuntu 22.04.5 LTS - 2024-11-19 23:50:00 💻 Virtual machine: no - 2024-11-19 23:50:00 📦 Highest known block at #9319 - 2024-11-19 23:50:00 〽️ Prometheus exporter started at 127.0.0.1:9615 - 2024-11-19 23:50:00 Running JSON-RPC server: addr=127.0.0.1:9944, allowed origins=["http://localhost:*", "http://127.0.0.1:*", "https://localhost:*", "https://127.0.0.1:*", "https://polkadot.js.org"] - 2024-11-19 23:50:00 🏁 CPU score: 671.67 MiBs - 2024-11-19 23:50:00 🏁 Memory score: 7.96 GiBs - 2024-11-19 23:50:00 🏁 Disk score (seq. writes): 377.87 MiBs - 2024-11-19 23:50:00 🏁 Disk score (rand. writes): 147.92 MiBs - 2024-11-19 23:50:00 🥩 BEEFY gadget waiting for BEEFY pallet to become available... - 2024-11-19 23:50:00 🔍 Discovered new external address for our node: /ip4/37.187.93.17/tcp/30333/ws/p2p/12D3KooWDmhHEgPRJUJnUpJ4TFWn28EENqvKWH4dZGCN9TS51y9h - 2024-11-19 23:50:01 🔍 Discovered new external address for our node: /ip6/2001:41d0:a:3511::1/tcp/30333/ws/p2p/12D3KooWDmhHEgPRJUJnUpJ4TFWn28EENqvKWH4dZGCN9TS51y9h - 2024-11-19 23:50:05 ⚙️ Syncing, target=#23486325 (5 peers), best: #12262 (0x8fb5…f310), finalized #11776 (0x9de1…32fb), ⬇ 430.5kiB/s ⬆ 17.8kiB/s - 2024-11-19 23:50:10 ⚙️ Syncing 628.8 bps, target=#23486326 (6 peers), best: #15406 (0x9ce1…2d76), finalized #15360 (0x0e41…a064), ⬇ 255.0kiB/s ⬆ 1.8kiB/s -
- -Congratulations, you're now syncing a Polkadot full node! Remember that the process is identical when using any other Polkadot SDK-based chain, although individual chains may have chain-specific flag requirements. - -### Connect to Your Node - -Open [Polkadot.js Apps](https://polkadot.js.org/apps/?rpc=ws%3A%2F%2F127.0.0.1%3A9944#/explorer){target=\_blank} and click the logo in the top left to switch the node. Activate the **Development** toggle and input your node's domain or IP address. The default WSS endpoint for a local node is: - -```bash -ws://127.0.0.1:9944 -``` diff --git a/.ai/pages/nodes-and-validators-run-a-node-secure-wss.md b/.ai/pages/nodes-and-validators-run-a-node-secure-wss.md deleted file mode 100644 index 27810abc3..000000000 --- a/.ai/pages/nodes-and-validators-run-a-node-secure-wss.md +++ /dev/null @@ -1,125 +0,0 @@ ---- -title: Set Up Secure WebSocket -description: Instructions on enabling SSL for your node and setting up a secure WebSocket proxy server using nginx for remote connections. -categories: Infrastructure -url: https://docs.polkadot.com/nodes-and-validators/run-a-node/secure-wss/ ---- - -# Set Up Secure WebSocket - -## Introduction - -Ensuring secure WebSocket communication is crucial for maintaining the integrity and security of a Polkadot or Kusama node when interacting with remote clients. This guide walks you through setting up a secure WebSocket (WSS) connection for your node by leveraging SSL encryption with popular web server proxies like nginx or Apache. - -By the end of this guide, you'll be able to secure your node's WebSocket port, enabling safe remote connections without exposing your node to unnecessary risks. The instructions in this guide are for UNIX-based systems. - -## Secure a WebSocket Port - -You can convert a non-secured WebSocket port to a secure WSS port by placing it behind an SSL-enabled proxy. This approach can be used to secure a bootnode or RPC server. The SSL-enabled apache2/nginx/other proxy server redirects requests to the internal WebSocket and converts it to a secure (WSS) connection. You can use a service like [LetsEncrypt](https://letsencrypt.org/){target=\_blank} to obtain an SSL certificate. - -### Obtain an SSL Certificate - -LetsEncrypt suggests using the [Certbot ACME client](https://letsencrypt.org/getting-started/#with-shell-access/){target=\_blank} for your respective web server implementation to get a free SSL certificate: - -- [nginx](https://certbot.eff.org/instructions?ws=nginx&os=ubuntufocal){target=\_blank} -- [apache2](https://certbot.eff.org/instructions?ws=apache&os=ubuntufocal){target=\_blank} - -LetsEncrypt will auto-generate an SSL certificate and include it in your configuration. - -When connecting, you can generate a self-signed certificate and rely on your node's raw IP address. However, self-signed certificates aren't optimal because you must include the certificate in an allowlist to access it from a browser. - -Use the following command to generate a self-signed certificate using OpenSSL: - -```bash -sudo openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout /etc/ssl/private/selfsigned.key -out /etc/ssl/certs/selfsigned.crt -sudo openssl dhparam -out /etc/ssl/certs/dhparam.pem 2048 -``` -## Install a Proxy Server - -There are a lot of different implementations of a WebSocket proxy; some of the more widely used are [nginx](https://www.f5.com/go/product/welcome-to-nginx){target=\_blank} and [apache2](https://httpd.apache.org/){target=\_blank}, both of which are commonly used web server implementations. See the following section for configuration examples for both implementations. - -### Use nginx - -1. Install the `nginx` web server: - ```bash - apt install nginx - ``` - -2. In an SSL-enabled virtual host, add: - ```conf - server { - (...) - location / { - proxy_buffers 16 4k; - proxy_buffer_size 2k; - proxy_pass http://localhost:9944; - proxy_http_version 1.1; - proxy_set_header Upgrade $http_upgrade; - proxy_set_header Connection "Upgrade"; - proxy_set_header Host $host; - } - } - ``` -3. Optionally, you can introduce some form of rate limiting: - ```conf - http { - limit_req_zone "$http_x_forwarded_for" zone=zone:10m rate=2r/s; - (...) - } - location / { - limit_req zone=zone burst=5; - (...) - } - ``` -### Use Apache2 - -Apache2 can run in various modes, including `prefork`, `worker`, and `event`. In this example, the [`event`](https://httpd.apache.org/docs/2.4/mod/event.html){target=\_blank} mode is recommended for handling higher traffic loads, as it is optimized for performance in such environments. However, depending on the specific requirements of your setup, other modes like `prefork` or `worker` may also be appropriate. - -1. Install the `apache2` web server: - ```bash - apt install apache2 - a2dismod mpm_prefork - a2enmod mpm_event proxy proxy_html proxy_http proxy_wstunnel rewrite ssl - ``` -2. The [`mod_proxy_wstunnel`](https://httpd.apache.org/docs/2.4/mod/mod_proxy_wstunnel.html){target=\_blank} provides support for the tunneling of WebSocket connections to a backend WebSocket server. The connection is automatically upgraded to a WebSocket connection. In an SSL-enabled virtual host add: - - ```apacheconf - # (...) - SSLProxyEngine on - ProxyRequests off - ProxyPass / ws://localhost:9944 - ProxyPassReverse / ws://localhost:9944 - ``` - !!!warning - Older versions of `mod_proxy_wstunnel` don't upgrade the connection automatically and will need the following config added: - ```apacheconf - RewriteEngine on - RewriteCond %{HTTP:Upgrade} websocket [NC] - RewriteRule /(.*) ws://localhost:9944/$1 [P,L] - RewriteRule /(.*) http://localhost:9944/$1 [P,L] - ``` - -3. Optionally, some form of rate limiting can be introduced by first running the following command: - - ```bash - apt install libapache2-mod-qos - a2enmod qos - ``` - - Then edit `/etc/apache2/mods-available/qos.conf` as follows: - - ```conf - # allows max 50 connections from a single IP address: - QS_SrvMaxConnPerIP 50 - ``` - -## Connect to the Node - -1. Open [Polkadot.js Apps interface](https://polkadot.js.org/apps){target=\_blank} and click the logo in the top left to switch the node. -2. Activate the **Development** toggle and input either your node's domain or IP address. Remember to prefix with `wss://` and, if you're using the 443 port, append `:443` as follows: - - ```bash - wss://example.com:443 - ``` - -![A sync-in-progress chain connected to Polkadot.js UI](/images/nodes-and-validators/run-a-node/secure-wss/secure-wss-01.webp) diff --git a/.ai/pages/nodes-and-validators-run-a-validator-onboarding-and-offboarding-key-management.md b/.ai/pages/nodes-and-validators-run-a-validator-onboarding-and-offboarding-key-management.md deleted file mode 100644 index 25c74598c..000000000 --- a/.ai/pages/nodes-and-validators-run-a-validator-onboarding-and-offboarding-key-management.md +++ /dev/null @@ -1,155 +0,0 @@ ---- -title: Validator Key Management -description: Learn how to generate and manage validator keys, including session keys for consensus participation and node keys for maintaining a stable network identity. -categories: Infrastructure -url: https://docs.polkadot.com/nodes-and-validators/run-a-validator/onboarding-and-offboarding/key-management/ ---- - -# Key Management - -## Introduction - -After setting up your node environment as shown in the [Setup](/nodes-and-validators/run-a-validator/onboarding-and-offboarding/set-up-validator/){target=\_blank} section, you'll need to configure multiple keys for your validator to operate properly. This includes setting up session keys, which are essential for participating in the consensus process, and configuring a node key that maintains a stable network identity. This guide walks you through the key management process, showing you how to generate, store, and register these keys. - -## Set Session Keys - -Setting up your validator's session keys is essential to associate your node with your stash account on the Polkadot network. Validators use session keys to participate in the consensus process. Your validator can only perform its role in the network by properly setting session keys which consist of several key pairs for different parts of the protocol (e.g., GRANDPA, BABE). These keys must be registered on-chain and associated with your validator node to ensure it can participate in validating blocks. - -### Generate Session Keys - -There are multiple ways to create the session keys. It can be done by interacting with the [Polkadot.js Apps UI](https://polkadot.js.org/apps/#/explorer){target=\_blank}, using the curl command or by using [Subkey](https://paritytech.github.io/polkadot-sdk/master/subkey/index.html){target=\_blank}. - -=== "Polkadot.js Apps UI" - - 1. In Polkadot.js Apps, connect to your local node, navigate to the **Developer** dropdown, and select the **RPC Calls** option. - - 2. Construct an `author_rotateKeys` RPC call and execute it: - - 1. Select the **author** endpoint. - 2. Choose the **rotateKeys()** call. - 3. Click the **Submit RPC Call** button. - 4. Copy the hex-encoded public key from the response. - - ![](/images/nodes-and-validators/run-a-validator/onboarding-and-offboarding/key-management/key-management-01.webp) - -=== "Curl" - - Generate session keys by running the following command on your validator node: - - ``` bash - curl -H "Content-Type: application/json" \ - -d '{"id":1, "jsonrpc":"2.0", "method": "author_rotateKeys", "params":[]}' \ - http://localhost:9944 - ``` - - This command will return a JSON object. The `result` key is the hex-encoded public part of the newly created session key. Save this for later use. - - ```json - {"jsonrpc":"2.0","result":"0xda3861a45e0197f3ca145c2c209f9126e5053fas503e459af4255cf8011d51010","id":1} - ``` - -=== "Subkey" - - To create a keypair for your node's session keys, use the `subkey generate` command. This generates a set of cryptographic keys that must be stored in your node's keystore directory. - - When you run the command, it produces output similar to this example: - -
- subkey generate -
-    Secret phrase:       twist buffalo mixture excess device drastic vague mammal fitness punch match hammer
-      Network ID:        substrate
-      Secret seed:       0x5faa9e5defe42b201388d5c2b8202d6625a344abc9aa52943a71f12cb90b88a9
-      Public key (hex):  0x28cc2fdb6e28835e2bbac9a16feb65c23d448c9314ef12fe083b61bab8fc2755
-      Account ID:        0x28cc2fdb6e28835e2bbac9a16feb65c23d448c9314ef12fe083b61bab8fc2755
-      Public key (SS58): 5CzCRpXzHYhuo6G3gYFR3cgV6X3qCNwVt51m8q14ZcChsSXQ
-      SS58 Address:      5CzCRpXzHYhuo6G3gYFR3cgV6X3qCNwVt51m8q14ZcChsSXQ
-      
-
- - To properly store these keys, create a file in your keystore directory with a specific naming convention. The filename must consist of the hex string `61757261` (which represents "aura" in hex) followed by the public key without its `0x` prefix. - - Using the example above, you would create a file named: - - ``` - ./keystores/6175726128cc2fdb6e28835e2bbac9a16feb65c23d448c9314ef12fe083b61bab8fc2755 - ``` - - And store only the secret phrase in the file: - - ``` - "twist buffalo mixture excess device drastic vague mammal fitness punch match hammer" - ``` - -### Submit Transaction to Set Keys - -Now that you have generated your session keys, you must submit them to the chain. Follow these steps: - -1. Go to the **Network > Staking > Accounts** section on Polkadot.js Apps. -2. Select **Set Session Key** on the bonding account you generated earlier. -3. Paste the hex-encoded session key string you generated (from either the UI or CLI) into the input field and submit the transaction. - -![](/images/nodes-and-validators/run-a-validator/onboarding-and-offboarding/key-management/key-management-02.webp) - -Once the transaction is signed and submitted, your session keys will be registered on-chain. - -### Verify Session Key Setup - -To verify that your session keys are properly set, you can use one of two RPC calls: - -- **`hasKey`**: Checks if the node has a specific key by public key and key type. -- **`hasSessionKeys`**: Verifies if your node has the full session key string associated with the validator. - -For example, you can [check session keys on the Polkadot.js Apps](https://polkadot.js.org/apps/#/rpc){target=\_blank} interface or by running an RPC query against your node. Once this is done, your validator node is ready for its role. - -## Set the Node Key - -Validators on Polkadot need a static network key (also known as the node key) to maintain a stable node identity. This key ensures that your validator can maintain a consistent peer ID, even across restarts, which is crucial for maintaining reliable network connections. - -Starting with Polkadot version 1.11, validators without a stable network key may encounter the following error on startup: - -
- polkadot --validator --name "INSERT_NAME_FROM_TELEMETRY" - Error: - 0: Starting an authority without network key - This is not a safe operation because other authorities in the network may depend on your node having a stable identity. - Otherwise these other authorities may not being able to reach you. - If it is the first time running your node you could use one of the following methods: - 1. [Preferred] Separately generate the key with: INSERT_NODE_BINARY key generate-node-key --base-path INSERT_YOUR_BASE_PATH - 2. [Preferred] Separately generate the key with: INSERT_NODE_BINARY key generate-node-key --file INSERT_YOUR_PATH_TO_NODE_KEY - 3. [Preferred] Separately generate the key with: INSERT_NODE_BINARY key generate-node-key --default-base-path - 4. [Unsafe] Pass --unsafe-force-node-key-generation and make sure you remove it for subsequent node restarts - -
- -### Generate the Node Key - -Use one of the following methods to generate your node key: - -=== "Save to file" - - The recommended solution is to generate a node key and save it to a file using the following command: - - ``` bash - polkadot key generate-node-key --file INSERT_PATH_TO_NODE_KEY - ``` - -=== "Use default path" - - You can also generate the node key with the following command, which will automatically save the key to the base path of your node: - - ``` bash - polkadot key generate-node-key --default-base-path - ``` - -Save the file path for reference. You will need it in the next step to configure your node with a static identity. - -### Set Node Key - -After generating the node key, configure your node to use it by specifying the path to the key file when launching your node. Add the following flag to your validator node's startup command: - -``` bash -polkadot --node-key-file INSERT_PATH_TO_NODE_KEY -``` - -Following these steps ensures that your node retains its identity, making it discoverable by peers without the risk of conflicting identities across sessions. For further technical background, see Polkadot SDK [Pull Request #3852](https://github.com/paritytech/polkadot-sdk/pull/3852){target=\_blank} for the rationale behind requiring static keys. diff --git a/.ai/pages/nodes-and-validators-run-a-validator-onboarding-and-offboarding-set-up-validator.md b/.ai/pages/nodes-and-validators-run-a-validator-onboarding-and-offboarding-set-up-validator.md deleted file mode 100644 index 2f7566b64..000000000 --- a/.ai/pages/nodes-and-validators-run-a-validator-onboarding-and-offboarding-set-up-validator.md +++ /dev/null @@ -1,213 +0,0 @@ ---- -title: Set Up a Validator -description: Set up a Polkadot validator node to secure the network and earn staking rewards. Follow this step-by-step guide to install, configure, and manage your node. -categories: Infrastructure -url: https://docs.polkadot.com/nodes-and-validators/run-a-validator/onboarding-and-offboarding/set-up-validator/ ---- - -# Set Up a Validator - -## Introduction - -Setting up a Polkadot validator node is essential for securing the network and earning staking rewards. This guide walks you through the technical steps to set up a validator, from installing the necessary software to managing keys and synchronizing your node with the chain. - -Running a validator requires a commitment to maintaining a stable, secure infrastructure. Validators are responsible for their own stakes and those of nominators who trust them with their tokens. Proper setup and ongoing management are critical to ensuring smooth operation and avoiding potential penalties such as slashing. - -## Prerequisites - -To get the most from this guide, ensure you've done the following before going forward: - -- Read [Validator Requirements](/nodes-and-validators/run-a-validator/requirements/){target=\_blank} and understand the recommended minimum skill level and hardware needs. -- Read [General Management](/nodes-and-validators/run-a-validator/operational-tasks/general-management/){target=\_blank}, [Upgrade Your Node](/nodes-and-validators/run-a-validator/operational-tasks/upgrade-your-node/){target=\_blank}, and [Pause Validating](/nodes-and-validators/run-a-validator/operational-tasks/pause-validating/){target=\_blank} and understand the tasks required to keep your validator operational. -- Read [Rewards Payout](/nodes-and-validators/run-a-validator/staking-mechanics/rewards/){target=\_blank} and understand how validator rewards are determined and paid out. -- Read [Offenses and Slashes](/nodes-and-validators/run-a-validator/staking-mechanics/offenses-and-slashes/){target=\_blank} and understand how validator performance and security can affect tokens staked by you or your nominators. - -## Initial Setup - -Before running your validator, you must configure your server environment to meet the operational and security standards required for validating. - -You must use a Linux-based operating system with Kernel 5.16 or later. Configuration includes setting up time synchronization, ensuring critical security features are active, and installing the necessary binaries. Proper setup at this stage is essential to prevent issues like block production errors or being penalized for downtime. Below are the essential steps to get your system ready. - -### Install Network Time Protocol Client - -Accurate timekeeping is critical to ensure your validator is synchronized with the network. Validators need local clocks in sync with the blockchain to avoid missing block authorship opportunities. Using [Network Time Protocol (NTP)](https://en.wikipedia.org/wiki/Network_Time_Protocol){target=\_blank} is the standard solution to keep your system's clock accurate. - -If you are using Ubuntu version 18.04 or newer, the NTP Client should be installed by default. You can check whether you have the NTP client by running: - -```sh -timedatectl -``` - -If NTP is running, you should see a message like the following: - -``` sh -System clock synchronized: yes -``` - -If NTP is not installed or running, you can install it using: - -```sh -sudo apt-get install ntp -``` - -After installation, NTP will automatically start. To check its status: - -```sh -sudo ntpq -p -``` - -This command will return a message with the status of the NTP synchronization. Skipping this step could result in your validator node missing blocks due to minor clock drift, potentially affecting its network performance. - -### Verify Landlock is Activated - -[Landlock](https://docs.kernel.org/userspace-api/landlock.html){target=\_blank} is an important security feature integrated into Linux kernels starting with version 5.13. It allows processes, even those without special privileges, to limit their access to the system to reduce the machine's attack surface. This feature is crucial for validators, as it helps ensure the security and stability of the node by preventing unauthorized access or malicious behavior. - -To use Landlock, ensure you use the reference kernel or newer versions. Most Linux distributions should already have Landlock activated. You can check if Landlock is activated on your machine by running the following command as root: - -```sh -dmesg | grep landlock || journalctl -kg landlock -``` - -If Landlock is not activated, your system logs won't show any related output. In this case, you will need to activate it manually or ensure that your Linux distribution supports it. Most modern distributions with the required kernel version should have Landlock activated by default. However, if your system lacks support, you may need to build the kernel with Landlock activated. For more information on doing so, refer to the [official kernel documentation](https://docs.kernel.org/userspace-api/landlock.html#kernel-support){target=\_blank}. - -Implementing Landlock ensures your node operates in a restricted, self-imposed sandbox, limiting potential damage from security breaches or bugs. While not a mandatory requirement, enabling this feature greatly improves the security of your validator setup. - -## Install the Polkadot Binaries - -You must install the Polkadot binaries required to run your validator node. These binaries include the main `polkadot`, `polkadot-prepare-worker`, and `polkadot-execute-worker` binaries. All three are needed to run a fully functioning validator node. - -Depending on your preference and operating system setup, there are multiple methods to install these binaries. Below are the main options: - -### Install from Official Releases - -The preferred, most straightforward method to install the required binaries is downloading the latest versions from the official releases. You can visit the [Github Releases](https://github.com/paritytech/polkadot-sdk/releases){target=\_blank} page for the most current versions of the `polkadot`, `polkadot-prepare-worker`, and `polkadot-execute-worker` binaries. - -You can also download the binaries by using the following direct links: - -=== "`polkadot`" - - ``` bash - # Download the binary - curl -LO https://github.com/paritytech/polkadot-sdk/releases/download/polkadot-stable2506-2/polkadot - - # Verify signature - curl -LO https://github.com/paritytech/polkadot-sdk/releases/download/polkadot-stable2506-2/polkadot.asc - - gpg --keyserver hkps://keyserver.ubuntu.com --receive-keys 90BD75EBBB8E95CB3DA6078F94A4029AB4B35DAE - - gpg --verify polkadot.asc - ``` - -=== "`polkadot-prepare-worker`" - - ``` bash - # Download the binary - curl -LO https://github.com/paritytech/polkadot-sdk/releases/download/polkadot-stable2506-2/polkadot-prepare-worker - - # Verify signature - curl -LO https://github.com/paritytech/polkadot-sdk/releases/download/polkadot-stable2506-2/polkadot-prepare-worker.asc - - gpg --keyserver hkps://keyserver.ubuntu.com --receive-keys 90BD75EBBB8E95CB3DA6078F94A4029AB4B35DAE - - gpg --verify polkadot-prepare-worker.asc - ``` - -=== "`polkadot-execute-worker`" - - ``` bash - # Download the binary - curl -LO https://github.com/paritytech/polkadot-sdk/releases/download/polkadot-stable2506-2/polkadot-execute-worker - - # Verify signature - curl -LO https://github.com/paritytech/polkadot-sdk/releases/download/polkadot-stable2506-2/polkadot-execute-worker.asc - - gpg --keyserver hkps://keyserver.ubuntu.com --receive-keys 90BD75EBBB8E95CB3DA6078F94A4029AB4B35DAE - - gpg --verify polkadot-execute-worker.asc - ``` - - -Signature verification cryptographically ensures the downloaded binaries are authentic and have not been tampered with by using GPG signing keys. Polkadot releases use two different signing keys: - -- ParityReleases (release-team@parity.io) with key [`90BD75EBBB8E95CB3DA6078F94A4029AB4B35DAE`](https://keyserver.ubuntu.com/pks/lookup?search=90BD75EBBB8E95CB3DA6078F94A4029AB4B35DAE&fingerprint=on&op=index){target=\_blank} for current and new releases. -- Parity Security Team (security@parity.io) with key [`9D4B2B6EB8F97156D19669A9FF0812D491B96798`](https://keyserver.ubuntu.com/pks/lookup?search=9D4B2B6EB8F97156D19669A9FF0812D491B96798&fingerprint=on&op=index){target=\_blank} for old releases. - - !!!warning - When verifying a signature, a "Good signature" message indicates successful verification, while any other output signals a potential security risk. - -### Install with Package Managers - -Users running Debian-based distributions like Ubuntu can install the binaries using the [APT](https://wiki.debian.org/Apt){target=\_blank} package manager. - -Execute the following commands as root to add the official repository and install the binaries: - -```bash -# Import the release-team@parity.io GPG key -gpg --keyserver hkps://keyserver.ubuntu.com --receive-keys 90BD75EBBB8E95CB3DA6078F94A4029AB4B35DAE -gpg --export 90BD75EBBB8E95CB3DA6078F94A4029AB4B35DAE > /usr/share/keyrings/parity.gpg - -# Add the Parity repository and update the package index -echo 'deb [signed-by=/usr/share/keyrings/parity.gpg] https://releases.parity.io/deb release main' > /etc/apt/sources.list.d/parity.list -apt update - -# Install the `parity-keyring` package - This will ensure the GPG key -# used by APT remains up-to-date -apt install parity-keyring - -# Install polkadot -apt install polkadot -``` - -Once installation completes, verify the binaries are correctly installed by following the steps in the [verify installation](#verify-installation) section. - -### Install with Ansible - -You can also manage Polkadot installations using Ansible. This approach can be beneficial for users managing multiple validator nodes or requiring automated deployment. The [Parity chain operations Ansible collection](https://github.com/paritytech/ansible-galaxy/){target=\_blank} provides a Substrate node role for this purpose. - -### Install with Docker - -If you prefer using Docker or an OCI-compatible container runtime, the official Polkadot Docker image can be pulled directly from Docker Hub. - -To pull the latest stable image, run the following command: - -```bash -docker pull parity/polkadot:stable2506-2 -``` - -### Build from Sources - -You may build the binaries from source by following the instructions on the [Polkadot SDK repository](https://github.com/paritytech/polkadot-sdk/tree/polkadot-stable2506-2/polkadot#building){target=\_blank}. - -## Verify Installation - -Once the Polkadot binaries are installed, it's essential to verify that everything is set up correctly and that all the necessary components are in place. Follow these steps to ensure the binaries are installed and functioning as expected. - -1. **Check the versions**: Run the following commands to verify the versions of the installed binaries. - - ```bash - polkadot --version - polkadot-execute-worker --version - polkadot-prepare-worker --version - ``` - - The output should show the version numbers for each of the binaries. Ensure that the versions match and are consistent, similar to the following example (the specific version may vary): - -
- polkadot --version polkadot-execute-worker --version polkadot-prepare-worker --version - 1.16.1-36264cb36db - 1.16.1-36264cb36db - 1.16.1-36264cb36db - -
- - If the versions do not match or if there is an error, double-check that all the binaries were correctly installed and are accessible within your `$PATH`. - -2. **Ensure all binaries are in the same directory**: All the binaries must be in the same directory for the Polkadot validator node to function properly. If the binaries are not in the same location, move them to a unified directory and ensure this directory is added to your system's `$PATH`. - - To verify the `$PATH`, run the following command: - - ```bash - echo $PATH - ``` - - If necessary, you can move the binaries to a shared location, such as `/usr/local/bin/`, and add it to your `$PATH`. diff --git a/.ai/pages/nodes-and-validators-run-a-validator-onboarding-and-offboarding-start-validating.md b/.ai/pages/nodes-and-validators-run-a-validator-onboarding-and-offboarding-start-validating.md deleted file mode 100644 index fdec84d1d..000000000 --- a/.ai/pages/nodes-and-validators-run-a-validator-onboarding-and-offboarding-start-validating.md +++ /dev/null @@ -1,254 +0,0 @@ ---- -title: Start Validating -description: Learn how to start validating on Polkadot by choosing a network, syncing your node, bonding DOT tokens, and activating your validator. -categories: Infrastructure -url: https://docs.polkadot.com/nodes-and-validators/run-a-validator/onboarding-and-offboarding/start-validating/ ---- - -# Start Validating - -## Introduction - -After configuring your node keys as shown in the [Key Management](/nodes-and-validators/run-a-validator/onboarding-and-offboarding/key-management/){target=\_blank} section and ensuring your system is set up, you're ready to begin the validator setup process. This guide will walk you through choosing a network, synchronizing your node with the blockchain, bonding your DOT tokens, and starting your validator. - -## Choose a Network - -Running your validator on a test network like Westend or Kusama is a smart way to familiarize yourself with the process and identify any setup issues in a lower-stakes environment before joining the Polkadot MainNet. - -- **Westend**: Polkadot's primary TestNet is open to anyone for testing purposes. Validator slots are intentionally limited to keep the network stable for the Polkadot release process, so it may not support as many validators at any given time. -- **Kusama**: Often called Polkadot's "canary network," Kusama has real economic value but operates with a faster and more experimental approach. Running a validator here provides an experience closer to MainNet with the benefit of more frequent validation opportunities with an era time of 6 hours vs 24 hours for Polkadot. -- **Polkadot**: The main network, where validators secure the Polkadot relay chain. It has a slower era time of 24 hours and requires a higher minimum bond amount to participate. - -## Synchronize Chain Data - -The next step is to sync your node with the chosen blockchain network. Synchronization is necessary to download and validate the blockchain data, ensuring your node is ready to participate as a validator. Follow these steps to sync your node: - -1. **Start syncing**: You can run a full or warp sync. - - === "Full sync" - - Polkadot defaults to using a full sync, which downloads and validates the entire blockchain history from the genesis block. Start the syncing process by running the following command: - - ```sh - polkadot - ``` - - This command starts your Polkadot node in non-validator mode, allowing you to synchronize the chain data. - - === "Warp sync" - - You can opt to use warp sync which initially downloads only GRANDPA finality proofs and the latest finalized block's state. Use the following command to start a warp sync: - - ``` bash - polkadot --sync warp - ``` - - Warp sync ensures that your node quickly updates to the latest finalized state. The historical blocks are downloaded in the background as the node continues to operate. - - If you're planning to run a validator on a TestNet, you can specify the chain using the `--chain` flag. For example, the following will run a validator on Kusama: - - ```sh - polkadot --chain=kusama - ``` - -2. **Monitor sync progress**: Once the sync starts, you will see a stream of logs providing information about the node's status and progress. Here's an example of what the output might look like: - -
- polkadot - 2021-06-17 03:07:07 Parity Polkadot - 2021-06-17 03:07:07 ✌️ version 0.9.5-95f6aa201-x86_64-linux-gnu - 2021-06-17 03:07:07 ❤️ by Parity Technologies <admin@parity.io>, 2017-2021 - 2021-06-17 03:07:07 📋 Chain specification: Polkadot - 2021-06-17 03:07:07 🏷 Node name: boiling-pet-7554 - 2021-06-17 03:07:07 👤 Role: FULL - 2021-06-17 03:07:07 💾 Database: RocksDb at /root/.local/share/polkadot/chains/polkadot/db - 2021-06-17 03:07:07 ⛓ Native runtime: polkadot-9050 (parity-polkadot-0.tx7.au0) - 2021-06-17 03:07:10 🏷 Local node identity is: 12D3KooWLtXFWf1oGrnxMGmPKPW54xWCHAXHbFh4Eap6KXmxoi9u - 2021-06-17 03:07:10 📦 Highest known block at #17914 - 2021-06-17 03:07:10 〽️ Prometheus server started at 127.0.0.1:9615 - 2021-06-17 03:07:10 Listening for new connections on 127.0.0.1:9944 - ... -
- - The output logs provide information such as the current block number, node name, and network connections. Monitor the sync progress and any errors that might occur during the process. Look for information about the latest processed block and compare it with the current highest block using tools like [Telemetry](https://telemetry.polkadot.io/#list/Polkadot%20CC1){target=\_blank} or [Polkadot.js Apps Explorer](https://polkadot.js.org/apps/#/explorer){target=\_blank}. - -### Database Snapshot Services - -If you'd like to speed up the process further, you can use a database snapshot. Snapshots are compressed backups of the blockchain's database directory and can significantly reduce the time required to sync a new node. Here are a few public snapshot providers: - -- [Stakeworld](https://stakeworld.io/snapshot){target=\_blank} -- [Polkachu](https://polkachu.com/substrate_snapshots){target=\_blank} -- [Polkashots](https://polkashots.io/){target=\_blank} -- [ITRocket](https://itrocket.net/services/mainnet/polkadot/#snapshot){target=\_blank} - -!!!warning - Although snapshots are convenient, syncing from scratch is recommended for security purposes. If snapshots become corrupted and most nodes rely on them, the network could inadvertently run on a non-canonical chain. - -
- polkadot - 2021-06-17 03:07:07 Idle (0 peers), best: #0 (0x3fd7...5baf), finalized #0 (0x3fd7...5baf), ⬇ 2.9kiB/s ⬆ 3.7kiB/s - 2021-06-17 03:07:12 Idle (0 peers), best: #0 (0x3fd7...5baf), finalized #0 (0x3fd7...5baf), ⬇ 1.7kiB/s ⬆ 2.0kiB/s - 2021-06-17 03:07:17 Idle (0 peers), best: #0 (0x3fd7...5baf), finalized #0 (0x3fd7...5baf), ⬇ 0.9kiB/s ⬆ 1.2kiB/s - 2021-06-17 03:07:19 Libp2p => Random Kademlia query has yielded empty results - 2021-06-17 03:08:00 Idle (0 peers), best: #0 (0x3fd7...5baf), finalized #0 (0x3fd7...5baf), ⬇ 1.6kiB/s ⬆ 1.9kiB/s - 2021-06-17 03:08:05 Idle (0 peers), best: #0 (0x3fd7...5baf), finalized #0 (0x3fd7...5baf), ⬇ 0.6kiB/s ⬆ 0.9kiB/s - ... -
- -If you see terminal output similar to the preceding, and you are unable to synchronize the chain due to having zero peers, make sure you have libp2p port `30333` activated. It will take some time to discover other peers over the network. - -## Bond DOT - -Once your validator node is synced, the next step is bonding DOT. A bonded account, or stash, holds your staked tokens (DOT) that back your validator node. Bonding your DOT means locking it for a period, during which it cannot be transferred or spent but is used to secure your validator's role in the network. Visit the [Minimum Bond Requirement](/nodes-and-validators/run-a-validator/requirements/#minimum-bond-requirement) section for details on how much DOT is required. - -The following sections will guide you through bonding DOT for your validator. - -### Bonding DOT on Polkadot.js Apps - -Once you're ready to bond your DOT, head over to the [Polkadot.js Apps](https://polkadot.js.org/apps/){target=\_blank} staking page by clicking the **Network** dropdown at the top of the page and selecting [**Staking**](https://polkadot.js.org/apps/#/staking/actions){target=\_blank}. - -To get started with the bond submission, click on the **Accounts** tab, then the **+ Stash** button, and then enter the following information: - -1. **Stash account**: Select your stash account (which is the account with the DOT/KSM balance). -2. **Value bonded**: Enter how much DOT from the stash account you want to bond/stake. You are not required to bond all of the DOT in that account and you may bond more DOT at a later time. Be aware, withdrawing any bonded amount requires waiting for the unbonding period. The unbonding period is seven days for Kusama and 28 days for Polkadot. -3. **Payment destination**: Add the recipient account for validator rewards. If you'd like to redirect payments to an account that is not the stash account, you can do it by entering the address here. Note that it is extremely unsafe to set an exchange address as the recipient of the staking rewards. - -Once everything is filled in properly, select **Bond** and sign the transaction with your stash account. If successful, you should see an `ExtrinsicSuccess` message. - -Your bonded account will be available under **Stashes**. After refreshing the screen, you should now see a card with all your accounts. The bonded amount on the right corresponds to the funds bonded by the stash account. - -## Validate - -Once your validator node is fully synced and ready, the next step is to ensure it's visible on the network and performing as expected. Below are steps for monitoring and managing your node on the Polkadot network. - -### Verify Sync via Telemetry - -To confirm that your validator is live and synchronized with the Polkadot network, visit the [Telemetry](https://telemetry.polkadot.io/#list/Polkadot%20CC1){target=\_blank} page. Telemetry provides real-time information on node performance and can help you check if your validator is connected properly. Search for your node by name. You can search all nodes currently active on the network, which is why you should use a unique name for easy recognition. Now, confirm that your node is fully synced by comparing the block height of your node with the network's latest block. Nodes that are fully synced will appear white in the list, while nodes that are not yet fully synced will appear gray. - -### Activate using Polkadot.js Apps - -Follow these steps to use Polkadot.js Apps to activate your validator: - -1. In Polkadot.js Apps, navigate to **Network** and select **Staking**: - - ![](/images/nodes-and-validators/run-a-validator/onboarding-and-offboarding/start-validating/start-validating-01.webp) - -2. Open the **Accounts** tab and click on **+ Validator**: - - ![](/images/nodes-and-validators/run-a-validator/onboarding-and-offboarding/start-validating/start-validating-02.webp) - -3. Set a bond amount in the **value bonded** field and then click **next**: - - ![](/images/nodes-and-validators/run-a-validator/onboarding-and-offboarding/start-validating/start-validating-03.webp) - -4. Paste the hex output from `author_rotateKeys`, set the commission, allow or block new nominations, then click **Bond & Validate** to link your validator with its session keys. - - ![](/images/nodes-and-validators/run-a-validator/onboarding-and-offboarding/start-validating/start-validating-04.webp) - - You can also set the **commission** and **blocked** nominations option via `staking.validate` extrinsic. By default, the blocked option is set to FALSE (i.e., the validator accepts nominations). - - ![](/images/nodes-and-validators/run-a-validator/onboarding-and-offboarding/start-validating/start-validating-05.webp) - -### Monitor Validation Status and Slots - -On the [**Staking**](https://polkadot.js.org/apps/#/staking){target=\_blank} tab in Polkadot.js Apps, you can see your validator's status, the number of available validator slots, and the nodes that have signaled their intent to validate. Your node may initially appear in the waiting queue, especially if the validator slots are full. The following is an example view of the **Staking** tab: - -![staking queue](/images/nodes-and-validators/run-a-validator/onboarding-and-offboarding/start-validating/start-validating-06.webp) - -The validator set refreshes each era. If there's an available slot in the next era, your node may be selected to move from the waiting queue to the active validator set, allowing it to start validating blocks. If your validator is not selected, it remains in the waiting queue. Increasing your stake or gaining more nominators may improve your chance of being selected in future eras. - -## Run a Validator Using Systemd - -Running your Polkadot validator as a [systemd](https://en.wikipedia.org/wiki/Systemd){target=\_blank} service is an effective way to ensure its high uptime and reliability. Using systemd allows your validator to automatically restart after server reboots or unexpected crashes, significantly reducing the risk of slashing due to downtime. - -This following sections will walk you through creating and managing a systemd service for your validator, allowing you to seamlessly monitor and control it as part of your Linux system. - -Ensure the following requirements are met before proceeding with the systemd setup: - -- Confirm your system meets the [requirements](/nodes-and-validators/run-a-validator/requirements/){target=\_blank} for running a validator. -- Ensure you meet the [minimum bond requirements](https://wiki.polkadot.com/general/chain-state-values/#minimum-validator-bond){target=\_blank} for validating. -- Verify the Polkadot binary is [installed](#install-the-polkadot-binaries). - -### Create the Systemd Service File - -First create a new unit file called `polkadot-validator.service` in `/etc/systemd/system/`: - -```bash -touch /etc/systemd/system/polkadot-validator.service -``` - -In this unit file, you will write the commands that you want to run on server boot/restart: - -```systemd title="/etc/systemd/system/polkadot-validator.service" -[Unit] -Description=Polkadot Node -After=network.target -Documentation=https://github.com/paritytech/polkadot-sdk - -[Service] -EnvironmentFile=-/etc/default/polkadot -ExecStart=/usr/bin/polkadot $POLKADOT_CLI_ARGS -User=polkadot -Group=polkadot -Restart=always -RestartSec=120 -CapabilityBoundingSet= -LockPersonality=true -NoNewPrivileges=true -PrivateDevices=true -PrivateMounts=true -PrivateTmp=true -PrivateUsers=true -ProtectClock=true -ProtectControlGroups=true -ProtectHostname=true -ProtectKernelModules=true -ProtectKernelTunables=true -ProtectSystem=strict -RemoveIPC=true -RestrictAddressFamilies=AF_INET AF_INET6 AF_NETLINK AF_UNIX -RestrictNamespaces=false -RestrictSUIDSGID=true -SystemCallArchitectures=native -SystemCallFilter=@system-service -SystemCallFilter=landlock_add_rule landlock_create_ruleset landlock_restrict_self seccomp mount umount2 -SystemCallFilter=~@clock @module @reboot @swap @privileged -SystemCallFilter=pivot_root -UMask=0027 - -[Install] -WantedBy=multi-user.target -``` - -!!! warning "Restart delay and equivocation risk" - It is recommended that a node's restart be delayed with `RestartSec` in the case of a crash. It's possible that when a node crashes, consensus votes in GRANDPA aren't persisted to disk. In this case, there is potential to equivocate when immediately restarting. Delaying the restart will allow the network to progress past potentially conflicting votes. - -### Run the Service - -Activate the systemd service to start on system boot by running: - -```bash -systemctl enable polkadot-validator.service -``` - -To start the service manually, use: - -```bash -systemctl start polkadot-validator.service -``` - -Check the service's status to confirm it is running: - -```bash -systemctl status polkadot-validator.service -``` - -To view the logs in real-time, use [journalctl](https://www.freedesktop.org/software/systemd/man/latest/journalctl.html){target=\_blank} like so: - -```bash -journalctl -f -u polkadot-validator -``` - -With these steps, you can effectively manage and monitor your validator as a systemd service. - -Once your validator is active, it's officially part of Polkadot's security infrastructure. For questions or further support, you can reach out to the [Polkadot Validator chat](https://matrix.to/#/!NZrbtteFeqYKCUGQtr:matrix.parity.io?via=matrix.parity.io&via=matrix.org&via=web3.foundation){target=\_blank} for tips and troubleshooting. diff --git a/.ai/pages/nodes-and-validators-run-a-validator-onboarding-and-offboarding-stop-validating.md b/.ai/pages/nodes-and-validators-run-a-validator-onboarding-and-offboarding-stop-validating.md deleted file mode 100644 index 922e9784b..000000000 --- a/.ai/pages/nodes-and-validators-run-a-validator-onboarding-and-offboarding-stop-validating.md +++ /dev/null @@ -1,45 +0,0 @@ ---- -title: Stop Validating -description: Learn to safely stop validating on Polkadot, including chilling, unbonding tokens, and purging validator keys. -categories: Infrastructure -url: https://docs.polkadot.com/nodes-and-validators/run-a-validator/onboarding-and-offboarding/stop-validating/ ---- - -# Stop Validating - -## Introduction - -If you're ready to stop validating on Polkadot, there are essential steps to ensure a smooth transition while protecting your funds and account integrity. Whether you're taking a break for maintenance or unbonding entirely, you'll need to chill your validator, purge session keys, and unbond your tokens. This guide explains how to use Polkadot's tools and extrinsics to safely withdraw from validation activities, safeguarding your account's future usability. - -## Pause Versus Stop - -If you wish to remain a validator or nominator (for example, stopping for planned downtime or server maintenance), submitting the `chill` extrinsic in the `staking` pallet should suffice. Additional steps are only needed to unbond funds or reap an account. - -The following are steps to ensure a smooth stop to validation: - -- Chill the validator. -- Purge validator session keys. -- Unbond your tokens. - -## Chill Validator - -When stepping back from validating, the first step is to chill your validator status. This action stops your validator from being considered for the next era without fully unbonding your tokens, which can be useful for temporary pauses like maintenance or planned downtime. - -Use the `staking.chill` extrinsic to initiate this. For more guidance on chilling your node, refer to the [Pause Validating](/nodes-and-validators/run-a-validator/operational-tasks/pause-validating/){target=\_blank} guide. You may also claim any pending staking rewards at this point. - -## Purge Validator Session Keys - -Purging validator session keys is a critical step in removing the association between your validator account and its session keys, which ensures that your account is fully disassociated from validator activities. The `session.purgeKeys` extrinsic removes the reference to your session keys from the stash or staking proxy account that originally set them. - -Here are a couple of important things to know about purging keys: - -- **Account used to purge keys**: Always use the same account to purge keys you originally used to set them, usually your stash or staking proxy account. Using a different account may leave an unremovable reference to the session keys on the original account, preventing its reaping. -- **Account reaping issue**: Failing to purge keys will prevent you from reaping (fully deleting) your stash account. If you attempt to transfer tokens without purging, you'll need to rebond, purge the session keys, unbond again, and wait through the unbonding period before any transfer. - -## Unbond Your Tokens - -After chilling your node and purging session keys, the final step is to unbond your staked tokens. This action removes them from staking and begins the unbonding period (usually 28 days for Polkadot and seven days for Kusama), after which the tokens will be transferable. - -To unbond tokens, go to **Network > Staking > Account Actions** on Polkadot.js Apps. Select your stash account, click on the dropdown menu, and choose **Unbond Funds**. Alternatively, you can use the `staking.unbond` extrinsic if you handle this via a staking proxy account. - -Once the unbonding period is complete, your tokens will be available for use in transactions or transfers outside of staking. diff --git a/.ai/pages/nodes-and-validators-run-a-validator-operational-tasks-general-management.md b/.ai/pages/nodes-and-validators-run-a-validator-operational-tasks-general-management.md deleted file mode 100644 index 8bceb81b8..000000000 --- a/.ai/pages/nodes-and-validators-run-a-validator-operational-tasks-general-management.md +++ /dev/null @@ -1,722 +0,0 @@ ---- -title: General Management -description: Optimize your Polkadot validator setup with advanced configuration techniques. Learn how to boost performance, enhance security, and ensure seamless operations. -categories: Infrastructure -url: https://docs.polkadot.com/nodes-and-validators/run-a-validator/operational-tasks/general-management/ ---- - -# General Management - -## Introduction - -Validator performance is pivotal in maintaining the security and stability of the Polkadot network. As a validator, optimizing your setup ensures efficient transaction processing, minimizes latency, and maintains system reliability during high-demand periods. Proper configuration and proactive monitoring also help mitigate risks like slashing and service interruptions. - -This guide covers essential practices for managing a validator, including performance tuning techniques, security hardening, and tools for real-time monitoring. Whether you're fine-tuning CPU settings, configuring NUMA balancing, or setting up a robust alert system, these steps will help you build a resilient and efficient validator operation. - -## Configuration Optimization - -For those seeking to optimize their validator's performance, the following configurations can improve responsiveness, reduce latency, and ensure consistent performance during high-demand periods. - -### Deactivate Simultaneous Multithreading - -Polkadot validators operate primarily in single-threaded mode for critical tasks, so optimizing single-core CPU performance can reduce latency and improve stability. Deactivating simultaneous multithreading (SMT) can prevent virtual cores from affecting performance. SMT is called Hyper-Threading on Intel and 2-way SMT on AMD Zen. - -Take the following steps to deactivate every other (vCPU) core: - -1. Loop though all the CPU cores and deactivate the virtual cores associated with them: - - ```bash - for cpunum in $(cat /sys/devices/system/cpu/cpu*/topology/thread_siblings_list | \ - cut -s -d, -f2- | tr ',' '\n' | sort -un) - do - echo 0 > /sys/devices/system/cpu/cpu$cpunum/online - done - ``` - -2. To permanently save the changes, add `nosmt=force` to the `GRUB_CMDLINE_LINUX_DEFAULT` variable in `/etc/default/grub`: - - ```bash - sudo nano /etc/default/grub - # Add to GRUB_CMDLINE_LINUX_DEFAULT - ``` - - ```config title="/etc/default/grub" - GRUB_DEFAULT = 0; - GRUB_HIDDEN_TIMEOUT = 0; - GRUB_HIDDEN_TIMEOUT_QUIET = true; - GRUB_TIMEOUT = 10; - GRUB_DISTRIBUTOR = `lsb_release -i -s 2> /dev/null || echo Debian`; - GRUB_CMDLINE_LINUX_DEFAULT = 'nosmt=force'; - GRUB_CMDLINE_LINUX = ''; - ``` - -3. Update GRUB to apply changes: - - ```bash - sudo update-grub - ``` - -4. After the reboot, you should see that half of the cores are offline. To confirm, run: - - ```bash - lscpu --extended - ``` - -### Deactivate Automatic NUMA Balancing - -Deactivating NUMA (Non-Uniform Memory Access) balancing for multi-CPU setups helps keep processes on the same CPU node, minimizing latency. - -Follow these stpes: - -1. Deactivate NUMA balancing in runtime: - - ```bash - sysctl kernel.numa_balancing=0 - ``` - -2. Deactivate NUMA balancing permanently by adding `numa_balancing=disable` to the GRUB settings: - - ```bash - sudo nano /etc/default/grub - # Add to GRUB_CMDLINE_LINUX_DEFAULT - ``` - - ```config title="/etc/default/grub" - GRUB_DEFAULT = 0; - GRUB_HIDDEN_TIMEOUT = 0; - GRUB_HIDDEN_TIMEOUT_QUIET = true; - GRUB_TIMEOUT = 10; - GRUB_DISTRIBUTOR = `lsb_release -i -s 2> /dev/null || echo Debian`; - GRUB_CMDLINE_LINUX_DEFAULT = 'numa_balancing=disable'; - GRUB_CMDLINE_LINUX = ''; - ``` - -3. Update GRUB to apply changes: - - ```bash - sudo update-grub - ``` - -4. Confirm the deactivation: - - ```bash - sysctl -a | grep 'kernel.numa_balancing' - ``` - -If you successfully deactivated NUMA balancing, the preceding command should return `0`. - -### Spectre and Meltdown Mitigations - -[Spectre](https://en.wikipedia.org/wiki/Spectre_(security_vulnerability)){target=\_blank} and [Meltdown](https://en.wikipedia.org/wiki/Meltdown_(security_vulnerability)){target=\_blank} are well-known CPU vulnerabilities that exploit speculative execution to access sensitive data. These vulnerabilities have been patched in recent Linux kernels, but the mitigations can slightly impact performance, especially in high-throughput or containerized environments. - -If your security requirements allow it, you can deactivate specific mitigations, such as Spectre V2 and Speculative Store Bypass Disable (SSBD), to improve performance. - -To selectively deactivate the Spectre mitigations, take these steps: - -1. Update the `GRUB_CMDLINE_LINUX_DEFAULT` variable in your `/etc/default/grub` configuration: - - ```bash - sudo nano /etc/default/grub - # Add to GRUB_CMDLINE_LINUX_DEFAULT - ``` - - ```config title="/etc/default/grub" - GRUB_DEFAULT = 0; - GRUB_HIDDEN_TIMEOUT = 0; - GRUB_HIDDEN_TIMEOUT_QUIET = true; - GRUB_TIMEOUT = 10; - GRUB_DISTRIBUTOR = `lsb_release -i -s 2> /dev/null || echo Debian`; - GRUB_CMDLINE_LINUX_DEFAULT = - 'spec_store_bypass_disable=prctl spectre_v2_user=prctl'; - ``` - -2. Update GRUB to apply changes and then reboot: - - ```bash - sudo update-grub - sudo reboot - ``` - -This approach selectively deactivates the Spectre V2 and Spectre V4 mitigations, leaving other protections intact. For full security, keep mitigations activated unless there's a significant performance need, as disabling them could expose the system to potential attacks on affected CPUs. - -## Monitor Your Node - -Monitoring your node's performance is critical for network reliability and security. Tools like the following provide valuable insights: - -- **[Prometheus](https://prometheus.io/){target=\_blank}**: An open-source monitoring toolkit for collecting and querying time-series data. -- **[Grafana](https://grafana.com/){target=\_blank}**: A visualization tool for real-time metrics, providing interactive dashboards. -- **[Alertmanager](https://prometheus.io/docs/alerting/latest/alertmanager/){target=\_blank}**: A tool for managing and routing alerts based on Prometheus data. - -This section covers setting up these tools and configuring alerts to notify you of potential issues. - -### Environment Setup - -Before installing Prometheus, ensure the environment is set up securely by running Prometheus with restricted user privileges. - -Follow these steps: - -1. Create a Prometheus user to ensure Prometheus runs with minimal permissions: - - ```bash - sudo useradd --no-create-home --shell /usr/sbin/nologin prometheus - ``` - -2. Create directories for configuration and data storage: - - ```bash - sudo mkdir /etc/prometheus - sudo mkdir /var/lib/prometheus - ``` - -3. Change directory ownership to ensure Prometheus has access: - - ```bash - sudo chown -R prometheus:prometheus /etc/prometheus - sudo chown -R prometheus:prometheus /var/lib/prometheus - ``` - -### Install and Configure Prometheus - -After setting up the environment, install and configure the latest version of Prometheus as follows: - -1. Download Prometheus for your system architecture from the [releases page](https://github.com/prometheus/prometheus/releases/){target=\_blank}. Replace `INSERT_RELEASE_DOWNLOAD` with the release binary URL (e.g., `https://github.com/prometheus/prometheus/releases/download/v3.0.0/prometheus-3.0.0.linux-amd64.tar.gz`): - - ```bash - sudo apt-get update && sudo apt-get upgrade - wget INSERT_RELEASE_DOWNLOAD_LINK - tar xfz prometheus-*.tar.gz - cd prometheus-3.0.0.linux-amd64 - ``` - -2. Set up Prometheus: - - 1. Copy binaries: - - ```bash - sudo cp ./prometheus /usr/local/bin/ - sudo cp ./promtool /usr/local/bin/ - sudo cp ./prometheus /usr/local/bin/ - ``` - - 2. Copy directories and assign ownership of these files to the `prometheus` user: - - ```bash - sudo cp -r ./consoles /etc/prometheus - sudo cp -r ./console_libraries /etc/prometheus - sudo chown -R prometheus:prometheus /etc/prometheus/consoles - sudo chown -R prometheus:prometheus /etc/prometheus/console_libraries - ``` - - 3. Clean up the download directory: - - ```bash - cd .. && rm -r prometheus* - ``` - -3. Create `prometheus.yml` to define global settings, rule files, and scrape targets: - - ```bash - sudo nano /etc/prometheus/prometheus.yml - ``` - - {% raw %} - ```yaml title="prometheus-config.yml" - global: - scrape_interval: 15s - evaluation_interval: 15s - - rule_files: - # - "first.rules" - # - "second.rules" - - scrape_configs: - - job_name: 'prometheus' - scrape_interval: 5s - static_configs: - - targets: ['localhost:9090'] - - job_name: 'substrate_node' - scrape_interval: 5s - static_configs: - - targets: ['localhost:9615'] - ``` - {% endraw %} - - Prometheus is scraped every 5 seconds in this example configuration file, ensuring detailed internal metrics. Node metrics with customizable intervals are scraped from port `9615` by default. - -4. Verify the configuration with `promtool`, an open source monitoring tool: - - ```bash - promtool check config /etc/prometheus/prometheus.yml - ``` - -5. Save the configuration and change the ownership of the file to `prometheus` user: - - ```bash - sudo chown prometheus:prometheus /etc/prometheus/prometheus.yml - ``` - -### Start Prometheus - -1. Launch Prometheus with the appropriate configuration file, storage location, and necessary web resources, running it with restricted privileges for security: - - ```bash - sudo -u prometheus /usr/local/bin/prometheus --config.file /etc/prometheus/prometheus.yml \ - --storage.tsdb.path /var/lib/prometheus/ \ - --web.console.templates=/etc/prometheus/consoles \ - --web.console.libraries=/etc/prometheus/console_libraries - ``` - - If you set the server up properly, you should see terminal output similar to the following: - - -2. Verify you can access the Prometheus interface by navigating to: - - ```text - http://SERVER_IP_ADDRESS:9090/graph - ``` - - If the interface appears to work as expected, exit the process using `Control + C`. - -3. Create a systemd service file to ensure Prometheus starts on boot: - - ```bash - sudo nano /etc/systemd/system/prometheus.service - ``` - - ```bash title="prometheus.service" - [Unit] - Description=Prometheus Monitoring - Wants=network-online.target - After=network-online.target - - [Service] - User=prometheus - Group=prometheus - Type=simple - ExecStart=/usr/local/bin/prometheus \ - --config.file /etc/prometheus/prometheus.yml \ - --storage.tsdb.path /var/lib/prometheus/ \ - --web.console.templates=/etc/prometheus/consoles \ - --web.console.libraries=/etc/prometheus/console_libraries - ExecReload=/bin/kill -HUP $MAINPID - - [Install] - WantedBy=multi-user.target - - ``` - -4. Reload systemd and enable the service to start on boot: - - ```bash - sudo systemctl daemon-reload && sudo systemctl enable prometheus && sudo systemctl start prometheus - ``` - -5. Verify the service is running by visiting the Prometheus interface again at: - - ```text - http://SERVER_IP_ADDRESS:9090/ - ``` - -### Install and Configure Grafana - -This guide follows [Grafana's canonical installation instructions](https://grafana.com/docs/grafana/latest/setup-grafana/installation/debian/#install-from-apt-repository){target=\_blank}. - -To install and configure Grafana, follow these steps: - -1. Install Grafana prerequisites: - - ```bash - sudo apt-get install -y apt-transport-https software-properties-common wget - ``` - -2. Import the [GPG key](https://gnupg.org/){target=\_blank}: - - ```bash - sudo mkdir -p /etc/apt/keyrings/ - wget -q -O - https://apt.grafana.com/gpg.key | gpg --dearmor | sudo tee /etc/apt/keyrings/grafana.gpg > /dev/null - ``` - -3. Configure the stable release repo and update packages: - - ```bash - echo "deb [signed-by=/etc/apt/keyrings/grafana.gpg] https://apt.grafana.com stable main" | sudo tee -a /etc/apt/sources.list.d/grafana.list - sudo apt-get update - ``` - -4. Install the latest stable version of Grafana: - - ```bash - sudo apt-get install grafana - ``` - -To configure Grafana, take these steps: - -1. Configure Grafana to start automatically on boot and start the service: - - ```bash - sudo systemctl daemon-reload - sudo systemctl enable grafana-server.service - sudo systemctl start grafana-server - ``` - -2. Check if Grafana is running: - - ```bash - sudo systemctl status grafana-server - ``` - - If necessary, you can stop or restart the service with the following commands: - - ```bash - sudo systemctl stop grafana-server - sudo systemctl restart grafana-server - ``` - -3. Access Grafana by navigating to the following URL and logging in with the default username and password (`admin`): - - ```text - http://SERVER_IP_ADDRESS:3000/login - ``` - - !!! tip "Change default port" - To change Grafana's port, edit `/usr/share/grafana/conf/defaults.ini`: - - ```bash - sudo vim /usr/share/grafana/conf/defaults.ini - ``` - - Modify the `http_port` value, then restart Grafana: - - ```bash - sudo systemctl restart grafana-server - ``` - -![Grafana login screen](/images/nodes-and-validators/run-a-validator/operational-tasks/general-management/general-management-01.webp) - -To visualize node metrics, follow these steps: - -1. Select the gear icon to access **Data Sources** settings. -2. Select **Add data source** to define the data source. - - ![Select Prometheus](/images/nodes-and-validators/run-a-validator/operational-tasks/general-management/general-management-02.webp) - -3. Select **Prometheus**. - - ![Save and test](/images/nodes-and-validators/run-a-validator/operational-tasks/general-management/general-management-03.webp) - -4. Enter `http://localhost:9090` in the **URL** field and click **Save & Test**. If **"Data source is working"** appears, your connection is configured correctly. - - ![Import dashboard](/images/nodes-and-validators/run-a-validator/operational-tasks/general-management/general-management-04.webp) - -5. Select **Import** from the left menu, choose **Prometheus** from the dropdown, and click **Import**. - -6. Start your Polkadot node by running `./polkadot`. You should now be able to monitor node performance, block height, network traffic, and tasks tasks on the Grafana dashboard. - - ![Live dashboard](/images/nodes-and-validators/run-a-validator/operational-tasks/general-management/general-management-05.webp) - -The [Grafana dashboards](https://grafana.com/grafana/dashboards){target=\_blank} page features user created dashboards made available for public use. For an example, see the [Substrate Node Metrics](https://grafana.com/grafana/dashboards/21715-substrate-node-metrics/){target=\_blank} dashboard. - -### Install and Configure Alertmanager - -[Alertmanager](https://prometheus.io/docs/alerting/latest/alertmanager/){target=\_blank} is an optional component that complements Prometheus by managing alerts and notifying users about potential issues. - -Follow these steps to install and configure Alertmanager: - -1. Download Alertmanager for your system architecture from the [releases page](https://github.com/prometheus/alertmanager/releases){target=\_blank}. Replace `INSERT_RELEASE_DOWNLOAD` with the release binary URL (e.g., `https://github.com/prometheus/alertmanager/releases/download/v0.28.0-rc.0/alertmanager-0.28.0-rc.0.linux-amd64.tar.gz`): - - ```bash - wget INSERT_RELEASE_DOWNLOAD_LINK - tar -xvzf alertmanager* - ``` - -2. Copy the binaries to the system directory and set permissions: - - ```bash - cd alertmanager-0.28.0-rc.0.linux-amd64 - sudo cp ./alertmanager /usr/local/bin/ - sudo cp ./amtool /usr/local/bin/ - sudo chown prometheus:prometheus /usr/local/bin/alertmanager - sudo chown prometheus:prometheus /usr/local/bin/amtool - ``` - -3. Create the `alertmanager.yml` configuration file under `/etc/alertmanager`: - - ```bash - sudo mkdir /etc/alertmanager - sudo nano /etc/alertmanager/alertmanager.yml - ``` - - Generate an [app password in your Google account](https://support.google.com/accounts/answer/185833?hl=en){target=\_blank} to enable email notifications from Alertmanager. Then, add the following code to the configuration file to define email notifications using your email and app password: - - {% raw %} - ```yml title="alertmanager.yml" - global: - resolve_timeout: 1m - - route: - receiver: 'gmail-notifications' - - receivers: - - name: 'gmail-notifications' - email_configs: - - to: INSERT_YOUR_EMAIL - from: INSERT_YOUR_EMAIL - smarthost: smtp.gmail.com:587 - auth_username: INSERT_YOUR_EMAIL - auth_identity: INSERT_YOUR_EMAIL - auth_password: INSERT_YOUR_APP_PASSWORD - send_resolved: true - - ``` - {% endraw %} - - - ```bash - sudo chown -R prometheus:prometheus /etc/alertmanager - ``` - -4. Configure Alertmanager as a service by creating a systemd service file: - - ```bash - sudo nano /etc/systemd/system/alertmanager.service - ``` - - {% raw %} - ```yml title="alertmanager.service" - [Unit] - Description=AlertManager Server Service - Wants=network-online.target - After=network-online.target - - [Service] - User=root - Group=root - Type=simple - ExecStart=/usr/local/bin/alertmanager --config.file /etc/alertmanager/alertmanager.yml --web.external-url=http://SERVER_IP:9093 --cluster.advertise-address='0.0.0.0:9093' - - [Install] - WantedBy=multi-user.target - - ``` - {% endraw %} - -5. Reload and enable the service: - - ```bash - sudo systemctl daemon-reload - sudo systemctl enable alertmanager - sudo systemctl start alertmanager - ``` - -6. Verify the service status: - - ```bash - sudo systemctl status alertmanager - ``` - - If you have configured Alertmanager properly, the **Active** field should display **active (running)** similar to below: - -
- sudo systemctl status alertmanager - alertmanager.service - AlertManager Server Service - Loaded: loaded (/etc/systemd/system/alertmanager.service; enabled; vendor preset: enabled) - Active: active (running) since Thu 2020-08-20 22:01:21 CEST; 3 days ago - Main PID: 20592 (alertmanager) - Tasks: 70 (limit: 9830) - CGroup: /system.slice/alertmanager.service - -
- -#### Grafana Plugin - -There is an [Alertmanager plugin in Grafana](https://grafana.com/grafana/plugins/alertmanager/){target=\_blank} that can help you monitor alert information. - -Follow these steps to use the plugin: - -1. Install the plugin: - - ```bash - sudo grafana-cli plugins install camptocamp-prometheus-alertmanager-datasource - ``` - -2. Restart Grafana: - - ```bash - sudo systemctl restart grafana-server - ``` - -3. Configure Alertmanager as a data source in your Grafana dashboard (`SERVER_IP:3000`): - - 1. Go to **Configuration** > **Data Sources** and search for **Prometheus Alertmanager**. - 2. Enter the server URL and port for the Alertmanager service, and select **Save & Test** to verify the connection. - -4. Import the [8010](https://grafana.com/grafana/dashboards/8010-prometheus-alertmanager/){target=\_blank} dashboard for Alertmanager, selecting **Prometheus Alertmanager** in the last column, then select **Import**. - -#### Integrate Alertmanager - -Complete the integration by following these steps to enable communication between Prometheus and Alertmanager and configure detection and alert rules: - -1. Update the `etc/prometheus/prometheus.yml` configuration file to include the following code: - - {% raw %} - ```yml title="prometheus.yml" - rule_files: - - 'rules.yml' - - alerting: - alertmanagers: - - static_configs: - - targets: - - localhost:9093 - ``` - {% endraw %} - - Expand the following item to view the complete `prometheus.yml` file. - - ??? code "prometheus.yml" - - {% raw %} - ```yml title="prometheus.yml" - global: - scrape_interval: 15s - evaluation_interval: 15s - - rule_files: - - 'rules.yml' - - alerting: - alertmanagers: - - static_configs: - - targets: - - localhost:9093 - - scrape_configs: - - job_name: 'prometheus' - scrape_interval: 5s - static_configs: - - targets: ['localhost:9090'] - - job_name: 'substrate_node' - scrape_interval: 5s - static_configs: - - targets: ['localhost:9615'] - - ``` - {% endraw %} - -2. Create the rules file for detection and alerts: - - ```bash - sudo nano /etc/prometheus/rules.yml - ``` - - Add a sample rule to trigger email notifications for node downtime over five minutes: - - {% raw %} - ```yml title="rules.yml" - groups: - - name: alert_rules - rules: - - alert: InstanceDown - expr: up == 0 - for: 5m - labels: - severity: critical - annotations: - summary: 'Instance [{{ $labels.instance }}] down' - description: '[{{ $labels.instance }}] of job [{{ $labels.job }}] has been down for more than 5 minutes.' - - ``` - {% endraw %} - - If any of the conditions defined in the rules file are met, an alert will be triggered. For more on alert rules, refer to [Alerting Rules](https://prometheus.io/docs/prometheus/latest/configuration/alerting_rules/){target=\_blank} and [additional alerts](https://samber.github.io/awesome-prometheus-alerts/rules.html){target=\_blank}. - -3. Update the file ownership to `prometheus`: - - ```bash - sudo chown prometheus:prometheus rules.yml - ``` - -4. Validate the rules syntax: - - ```bash - sudo -u prometheus promtool check rules rules.yml - ``` - -5. Restart Prometheus and Alertmanager: - - ```bash - sudo systemctl restart prometheus && sudo systemctl restart alertmanager - ``` - -Now you will receive an email alert if one of your rule triggering conditions is met. - -## Secure Your Validator - -Validators in Polkadot's Proof of Stake (PoS) network play a critical role in maintaining network integrity and security by keeping the network in consensus and verifying state transitions. To ensure optimal performance and minimize risks, validators must adhere to strict guidelines around security and reliable operations. - -### Key Management - -Though they don't transfer funds, session keys are essential for validators as they sign messages related to consensus and parachains. Securing session keys is crucial as allowing them to be exploited or used across multiple nodes can lead to a loss of staked funds via [slashing](/nodes-and-validators/run-a-validator/staking-mechanics/offenses-and-slashes/){target=\_blank}. - -Given the current limitations in high-availability setups and the risks associated with double-signing, it’s recommended to run only a single validator instance. Keys should be securely managed, and processes automated to minimize human error. - -There are two approaches for generating session keys: - -- **Generate and store in node**: Using the `author.rotateKeys` RPC call. For most users, generating keys directly within the client is recommended. You must submit a session certificate from your staking proxy to register new keys. See the [How to Validate](/nodes-and-validators/run-a-validator/onboarding-and-offboarding/set-up-validator/){target=\_blank} guide for instructions on setting keys. - -- **Generate outside node and insert**: Using the `author.setKeys` RPC call. This flexibility accommodates advanced security setups and should only be used by experienced validator operators. - -### Signing Outside the Client - -Polkadot plans to support external signing, allowing session keys to reside in secure environments like Hardware Security Modules (HSMs). However, these modules can sign any payload they receive, potentially enabling an attacker to perform slashable actions. - -### Secure-Validator Mode - -Polkadot's Secure-Validator mode offers an extra layer of protection through strict filesystem, networking, and process sandboxing. This secure mode is activated by default if the machine meets the following requirements: - -- **Linux (x86-64 architecture)**: Usually Intel or AMD. -- **Enabled `seccomp`**: This kernel feature facilitates a more secure approach for process management on Linux. Verify by running. - - ```bash - cat /boot/config-`uname -r` | grep CONFIG_SECCOMP= - ``` - - If `seccomp` is enabled, you should see output similar to the following: - - ```bash - CONFIG_SECCOMP=y - ``` - -!!! tip - Optionally, **Linux 5.13** may also be used, as it provides access to even more strict filesystem protections. - -### Linux Best Practices - -Follow these best practices to keep your validator secure: - -- Use a non-root user for all operations. -- Regularly apply OS security patches. -- Enable and configure a firewall. -- Use key-based SSH authentication; deactivate password-based login. -- Regularly back up data and harden your SSH configuration. Visit this [SSH guide](https://blog.stribik.technology/2015/01/04/secure-secure-shell.html){target=\_blank} for more details. - -### Validator Best Practices - -Additional best practices can add an additional layer of security and operational reliability: - -- Only run the Polkadot binary, and only listen on the configured p2p port. -- Run on bare-metal machines, as opposed to virtual machines. -- Provisioning of the validator machine should be automated and defined in code which is kept in private version control, reviewed, audited, and tested. -- Generate and provide session keys in a secure way. -- Start Polkadot at boot and restart if stopped for any reason. -- Run Polkadot as a non-root user. -- Establish and maintain an on-call rotation for managing alerts. -- Establish and maintain a clear protocol with actions to perform for each level of each alert with an escalation policy. - -## Additional Resources - -- [Certus One's Knowledge Base](https://knowledgebase.certus.com/FAQ/){target=\_blank} -- [EOS Block Producer Security List](https://github.com/slowmist/eos-bp-nodes-security-checklist){target=\_blank} -- [HSM Policies and the Importance of Validator Security](https://medium.com/loom-network/hsm-policies-and-the-importance-of-validator-security-ec8a4cc1b6f){target=\_blank} - -For additional guidance, connect with other validators and the Polkadot engineering team in the [Polkadot Validator Lounge](https://matrix.to/#/#polkadotvalidatorlounge:web3.foundation){target=\_blank} on Element. diff --git a/.ai/pages/nodes-and-validators-run-a-validator-operational-tasks-pause-validating.md b/.ai/pages/nodes-and-validators-run-a-validator-operational-tasks-pause-validating.md deleted file mode 100644 index f29841b3e..000000000 --- a/.ai/pages/nodes-and-validators-run-a-validator-operational-tasks-pause-validating.md +++ /dev/null @@ -1,46 +0,0 @@ ---- -title: Pause Validating -description: Learn how to temporarily pause staking activity in Polkadot using the chill extrinsic, with guidance for validators and nominators. -categories: Infrastructure -url: https://docs.polkadot.com/nodes-and-validators/run-a-validator/operational-tasks/pause-validating/ ---- - -# Pause Validating - -## Introduction - -If you need to temporarily stop participating in Polkadot staking activities without fully unbonding your funds, chilling your account allows you to do so efficiently. Chilling removes your node from active validation or nomination in the next era while keeping your funds bonded, making it ideal for planned downtimes or temporary pauses. - -This guide covers the steps for chilling as a validator or nominator, using the `chill` and `chillOther` extrinsics, and how these affect your staking status and nominations. - -## Chilling Your Node - -If you need to temporarily step back from staking without unbonding your funds, you can "chill" your account. Chilling pauses your active staking participation, setting your account to inactive in the next era while keeping your funds bonded. - -To chill your account, go to the **Network > Staking > Account Actions** page on [Polkadot.js Apps](https://polkadot.js.org/apps){target=\_blank}, and select **Stop**. Alternatively, you can call the [`chill`](https://paritytech.github.io/polkadot-sdk/master/pallet_staking/enum.Call.html#variant.chill){target=\_blank} extrinsic in the Staking pallet. - -## Staking Election Timing Considerations - -When a node actively participates in staking but then chills, it will continue contributing for the remainder of the current era. However, its eligibility for the next election depends on the chill status at the start of the new era: - -- **Chilled during previous era**: Will not participate in the current era election and will remain inactive until reactivated. -- **Chilled during current era**: Will not be selected for the next era's election. -- **Chilled after current era**: May be selected if it was active during the previous era and is now chilled. - -## Chilling as a Nominator - -When you choose to chill as a nominator, your active nominations are reset. Upon re-entering the nominating process, you must reselect validators to support manually. Depending on preferences, these can be the same validators as before or a new set. Remember that your previous nominations won’t be saved or automatically reactivated after chilling. - -While chilled, your nominator account remains bonded, preserving your staked funds without requiring a full unbonding process. When you’re ready to start nominating again, you can issue a new nomination call to activate your bond with a fresh set of validators. This process bypasses the need for re-bonding, allowing you to maintain your stake while adjusting your involvement in active staking. - -## Chilling as a Validator - -When you chill as a validator, your active validator status is paused. Although your nominators remain bonded to you, the validator bond will no longer appear as an active choice for new or revised nominations until reactivated. Any existing nominators who take no action will still have their stake linked to the validator, meaning they don’t need to reselect the validator upon reactivation. However, if nominators adjust their stakes while the validator is chilled, they will not be able to nominate the chilled validator until it resumes activity. - -Upon reactivating as a validator, you must also reconfigure your validator preferences, such as commission rate and other parameters. These can be set to match your previous configuration or updated as desired. This step is essential for rejoining the active validator set and regaining eligibility for nominations. - -## Chill Other - -Historical constraints in the runtime prevented unlimited nominators and validators from being supported. These constraints created a need for checks to keep the size of the staking system manageable. One of these checks is the `chillOther` extrinsic, allowing users to chill accounts that no longer met standards such as minimum staking requirements set through on-chain governance. - -This control mechanism included a `ChillThreshold`, which was structured to define how close to the maximum number of nominators or validators the staking system would be allowed to get before users could start chilling one another. With the passage of [Referendum #90](https://polkadot-old.polkassembly.io/referendum/90){target=\_blank}, the value for `maxNominatorCount` on Polkadot was set to `None`, effectively removing the limit on how many nominators and validators can participate. This means the `ChillThreshold` will never be met; thus, `chillOther` no longer has any effect. diff --git a/.ai/pages/nodes-and-validators-run-a-validator-operational-tasks-upgrade-your-node.md b/.ai/pages/nodes-and-validators-run-a-validator-operational-tasks-upgrade-your-node.md deleted file mode 100644 index 5e26ac7a4..000000000 --- a/.ai/pages/nodes-and-validators-run-a-validator-operational-tasks-upgrade-your-node.md +++ /dev/null @@ -1,75 +0,0 @@ ---- -title: Upgrade a Validator Node -description: Guide to seamlessly upgrading your Polkadot validator node, managing session keys, and executing server maintenance while avoiding downtime and slashing risks. -categories: Infrastructure -url: https://docs.polkadot.com/nodes-and-validators/run-a-validator/operational-tasks/upgrade-your-node/ ---- - -# Upgrade a Validator Node - -## Introduction - -Upgrading a Polkadot validator node is essential for staying current with network updates and maintaining optimal performance. This guide covers routine and extended maintenance scenarios, including software upgrades and major server changes. Following these steps, you can manage session keys and transition smoothly between servers without risking downtime, slashing, or network disruptions. The process requires strategic planning, especially if you need to perform long-lead maintenance, ensuring your validator remains active and compliant. - -This guide will allow validators to seamlessly substitute an active validator server to allow for maintenance operations. The process can take several hours, so ensure you understand the instructions first and plan accordingly. - -## Prerequisites - -Before beginning the upgrade process for your validator node, ensure the following: - -- You have a fully functional validator setup with all required binaries installed. See [Set Up a Validator](/nodes-and-validators/run-a-validator/onboarding-and-offboarding/set-up-validator/){target=\_blank} and [Validator Requirements](/nodes-and-validators/run-a-validator/requirements/){target=\_blank} for additional guidance. -- Your VPS infrastructure has enough capacity to run a secondary validator instance temporarily for the upgrade process. - -## Session Keys - -Session keys are used to sign validator operations and establish a connection between your validator node and your staking proxy account. These keys are stored in the client, and any change to them requires a waiting period. Specifically, if you modify your session keys, the change will take effect only after the current session is completed and two additional sessions have passed. - -Remembering this delayed effect when planning upgrades is crucial to ensure that your validator continues to function correctly and avoids interruptions. To learn more about session keys and their importance, visit the [Keys section](https://wiki.polkadot.com/learn/learn-cryptography/#keys){target=\_blank}. - -## Keystore - -Your validator server's `keystore` folder holds the private keys needed for signing network-level transactions. It is important not to duplicate or transfer this folder between validator instances. Doing so could result in multiple validators signing with the duplicate keys, leading to severe consequences such as [equivocation slashing](/nodes-and-validators/run-a-validator/staking-mechanics/offenses-and-slashes/#equivocation-slash){target=\_blank}. Instead, always generate new session keys for each validator instance. - -The default path to the `keystore` is as follows: - -```bash -/home/polkadot/.local/share/polkadot/chains//keystore -``` - -Taking care to manage your keys securely ensures that your validator operates safely and without the risk of slashing penalties. - -## Upgrade Using Backup Validator - -The following instructions outline how to temporarily switch between two validator nodes. The original active validator is referred to as Validator A and the backup node used for maintenance purposes as Validator B. - -### Session `N` - -1. **Start Validator B**: Launch a secondary node and wait until it is fully synced with the network. Once synced, start it with the `--validator` flag. This node will now act as Validator B. -2. **Generate session keys**: Create new session keys specifically for Validator B. -3. **Submit the `set_key` extrinsic**: Use your staking proxy account to submit a `set_key` extrinsic, linking the session keys for Validator B to your staking setup. -4. **Record the session**: Make a note of the session in which you executed this extrinsic. -5. **Wait for session changes**: Allow the current session to end and then wait for two additional full sessions for the new keys to take effect. - -!!! warning "Keep Validator A running" - - It is crucial to keep Validator A operational during this entire waiting period. Since `set_key` does not take effect immediately, turning off Validator A too early may result in chilling or even slashing. - -### Session `N+3` - -At this stage, Validator B becomes your active validator. You can now safely perform any maintenance tasks on Validator A. - -Complete the following steps when you are ready to bring Validator A back online: - -1. **Start Validator A**: Launch Validator A, sync the blockchain database, and ensure it is running with the `--validator` flag. -2. **Generate new session keys for Validator A**: Create fresh session keys for Validator A. -3. **Submit the `set_key` extrinsic**: Using your staking proxy account, submit a `set_key` extrinsic with the new Validator A session keys. -4. **Record the session**: Again, make a note of the session in which you executed this extrinsic. - -Keep Validator B active until the session during which you executed the `set-key` extrinsic completes plus two additional full sessions have passed. Once Validator A has successfully taken over, you can safely stop Validator B. This process helps ensure a smooth handoff between nodes and minimizes the risk of downtime or penalties. Verify the transition by checking for finalized blocks in the new session. The logs should indicate the successful change, similar to the example below: - -
- INSERT_COMMAND - 2019-10-28 21:44:13 Applying authority set change scheduled at block #450092 - 2019-10-28 21:44:13 Applying GRANDPA set change to new set with 20 authorities - -
diff --git a/.ai/pages/nodes-and-validators-run-a-validator-requirements.md b/.ai/pages/nodes-and-validators-run-a-validator-requirements.md deleted file mode 100644 index cf6fad411..000000000 --- a/.ai/pages/nodes-and-validators-run-a-validator-requirements.md +++ /dev/null @@ -1,85 +0,0 @@ ---- -title: Validator Requirements -description: Explore the technical and system requirements for running a Polkadot validator, including setup, hardware, staking prerequisites, and security best practices. -categories: Infrastructure -url: https://docs.polkadot.com/nodes-and-validators/run-a-validator/requirements/ ---- - -# Validator Requirements - -## Introduction - -Running a validator in the Polkadot ecosystem is essential for maintaining network security and decentralization. Validators are responsible for validating transactions and adding new blocks to the chain, ensuring the system operates smoothly. In return for their services, validators earn rewards. However, the role comes with inherent risks, such as slashing penalties for misbehavior or technical failures. If you’re new to validation, starting on Kusama provides a lower-stakes environment to gain valuable experience before progressing to the Polkadot network. - -This guide covers everything you need to know about becoming a validator, including system requirements, staking prerequisites, and infrastructure setup. Whether you’re deploying on a VPS or running your node on custom hardware, you’ll learn how to optimize your validator for performance and security, ensuring compliance with network standards while minimizing risks. - -## Prerequisites - -Running a validator requires solid system administration skills and a secure, well-maintained infrastructure. Below are the primary requirements you need to be aware of before getting started: - -- **System administration expertise**: Handling technical anomalies and maintaining node infrastructure is critical. Validators must be able to troubleshoot and optimize their setup. -- **Security**: Ensure your setup follows best practices for securing your node. Refer to the [Secure Your Validator](/nodes-and-validators/run-a-validator/operational-tasks/general-management/#secure-your-validator){target=\_blank} section to learn about important security measures. -- **Network choice**: Start with [Kusama](/nodes-and-validators/run-a-validator/onboarding-and-offboarding/set-up-validator/#run-a-kusama-validator){target=\_blank} to gain experience. Look for "Adjustments for Kusama" throughout these guides for tips on adapting the provided instructions for the Kusama network. -- **Staking requirements**: A minimum amount of native token (KSM or DOT) is required to be elected into the validator set. The required stake can come from your own holdings or from nominators. -- **Risk of slashing**: Any DOT you stake is at risk if your setup fails or your validator misbehaves. If you’re unsure of your ability to maintain a reliable validator, consider nominating your DOT to a trusted validator. - -## Minimum Hardware Requirements - -Polkadot validators rely on high-performance hardware to process blocks efficiently. The recommended minimum hardware requirements to ensure a fully functional and performant validator are as follows: - -- CPU: - - - x86-64 compatible. - - Eight physical cores @ 3.4 GHz. - - Processor: - - **Intel**: Ice Lake or newer (Xeon or Core series) - - **AMD**: Zen3 or newer (EPYC or Ryzen) - - Simultaneous multithreading disabled: - - **Intel**: Hyper-Threading - - **AMD**: SMT - - [Single-threaded performance](https://www.cpubenchmark.net/singleThread.html){target=\_blank} is prioritized over higher cores count. - -- Storage: - - - **NVMe SSD**: At least 2 TB for blockchain data recommended (prioritize latency rather than throughput). - - Storage requirements will increase as the chain grows. For current estimates, see the [current chain snapshot](https://stakeworld.io/docs/dbsize){target=\_blank}. - -- Memory: - - - 32 GB DDR4 ECC - -- Network: - - - Symmetric networking speed of 500 Mbit/s is required to handle large numbers of parachains and ensure congestion control during peak times. - -## VPS Provider List - -When selecting a VPS provider for your validator node, prioritize reliability, consistent performance, and adherence to the specific hardware requirements set for Polkadot validators. The following server types have been tested and showed acceptable performance in benchmark tests. However, this is not an endorsement and actual performance may vary depending on your workload and VPS provider. - -Be aware that some providers may overprovision the underlying host and use shared storage such as NVMe over TCP, which appears as local storage. These setups might result in poor or inconsistent performance. Benchmark your infrastructure before deploying. - -- **[Google Cloud Platform (GCP)](https://cloud.google.com/){target=\_blank}**: `c2` and `c2d` machine families offer high-performance configurations suitable for validators. -- **[Amazon Web Services (AWS)](https://aws.amazon.com/){target=\_blank}**: `c6id` machine family provides strong performance, particularly for I/O-intensive workloads. -- **[OVH](https://www.ovhcloud.com/en-au/){target=\_blank}**: Can be a budget-friendly solution if it meets your minimum hardware specifications. -- **[Digital Ocean](https://www.digitalocean.com/){target=\_blank}**: Popular among developers, Digital Ocean's premium droplets offer configurations suitable for medium to high-intensity workloads. -- **[Vultr](https://www.vultr.com/){target=\_blank}**: Offers flexibility with plans that may meet validator requirements, especially for high-bandwidth needs. -- **[Linode](https://www.linode.com/){target=\_blank}**: Provides detailed documentation, which can be helpful for setup. -- **[Scaleway](https://www.scaleway.com/en/){target=\_blank}**: Offers high-performance cloud instances that can be suitable for validator nodes. -- **[OnFinality](https://onfinality.io/en){target=\_blank}**: Specialized in blockchain infrastructure, OnFinality provides validator-specific support and configurations. - -!!! warning "Acceptable use policies" - Different VPS providers have varying acceptable use policies, and not all allow cryptocurrency-related activities. - - For example, Digital Ocean, requires explicit permission to use servers for cryptocurrency mining and defines unauthorized mining as [network abuse](https://www.digitalocean.com/legal/acceptable-use-policy#network-abuse){target=\_blank} in their acceptable use policy. - - Review the terms for your VPS provider to avoid account suspension or server shutdown due to policy violations. - -## Minimum Bond Requirement - -Before bonding DOT, ensure you meet the minimum bond requirement to start a validator instance. The minimum bond is the least DOT you need to stake to enter the validator set. To become eligible for rewards, your validator node must be nominated by enough staked tokens. - -For example, on November 19, 2024, the minimum stake backing a validator in Polkadot's era 1632 was 1,159,434.248 DOT. You can check the current minimum stake required using these tools: - -- [**Chain State Values**](https://wiki.polkadot.com/general/chain-state-values/){target=\_blank} -- [**Subscan**](https://polkadot.subscan.io/validator_list?status=validator){target=\_blank} -- [**Staking Dashboard**](https://staking.polkadot.cloud/#/overview){target=\_blank} diff --git a/.ai/pages/nodes-and-validators-run-a-validator-staking-mechanics-offenses-and-slashes.md b/.ai/pages/nodes-and-validators-run-a-validator-staking-mechanics-offenses-and-slashes.md deleted file mode 100644 index 48e739f9e..000000000 --- a/.ai/pages/nodes-and-validators-run-a-validator-staking-mechanics-offenses-and-slashes.md +++ /dev/null @@ -1,171 +0,0 @@ ---- -title: Offenses and Slashes -description: Learn about how Polkadot discourages validator misconduct via an offenses and slashing system, including details on offenses and their consequences. -categories: Infrastructure -url: https://docs.polkadot.com/nodes-and-validators/run-a-validator/staking-mechanics/offenses-and-slashes/ ---- - -# Offenses and Slashes - -## Introduction - -In Polkadot's Nominated Proof of Stake (NPoS) system, validator misconduct is deterred through a combination of slashing, disabling, and reputation penalties. Validators and nominators who stake tokens face consequences for validator misbehavior, which range from token slashes to restrictions on network participation. - -This page outlines the types of offenses recognized by Polkadot, including block equivocations and invalid votes, as well as the corresponding penalties. While some parachains may implement additional custom slashing mechanisms, this guide focuses on the offenses tied to staking within the Polkadot ecosystem. - -## Offenses - -Polkadot is a public permissionless network. As such, it has a mechanism to disincentivize offenses and incentivize good behavior. You can review the [parachain protocol](https://wiki.polkadot.com/learn/learn-parachains-protocol/#parachain-protocol){target=\_blank} to understand better the terminology used to describe offenses. Polkadot validator offenses fall into two categories: invalid votes and equivocations. - -### Invalid Votes - -A validator will be penalized for inappropriate voting activity during the block inclusion and approval processes. The invalid voting related offenses are as follows: - -- **Backing an invalid block**: A para-validator backs an invalid block for inclusion in a fork of the relay chain. -- **`ForInvalid` vote**: When acting as a secondary checker, the validator votes in favor of an invalid block. -- **`AgainstValid` vote**: When acting as a secondary checker, the validator votes against a valid block. This type of vote wastes network resources required to resolve the disparate votes and resulting dispute. - -### Equivocations - -Equivocation occurs when a validator produces statements that conflict with each other when producing blocks or voting. Unintentional equivocations usually occur when duplicate signing keys reside on the validator host. If keys are never duplicated, the probability of an honest equivocation slash decreases to near zero. The equivocation related offenses are as follows: - -- **Equivocation**: The validator produces two or more of the same block or vote. - - **GRANDPA and BEEFY equivocation**: The validator signs two or more votes in the same round on different chains. - - **BABE equivocation**: The validator produces two or more blocks on the relay chain in the same time slot. -- **Double seconded equivocation**: The validator attempts to second, or back, more than one block in the same round. -- **Seconded and valid equivocation**: The validator seconds, or backs, a block and then attempts to hide their role as the responsible backer by later placing a standard validation vote. - -## Penalties - -On Polkadot, offenses to the network incur different penalties depending on severity. There are three main penalties: slashing, disabling, and reputation changes. - -### Slashing - -Validators engaging in bad actor behavior in the network may be subject to slashing if they commit a qualifying offense. When a validator is slashed, they and their nominators lose a percentage of their staked DOT or KSM, from as little as 0.01% up to 100% based on the severity of the offense. Nominators are evaluated for slashing against their active validations at any given time. Validator nodes are evaluated as discrete entities, meaning an operator can't attempt to mitigate the offense on another node they operate in order to avoid a slash. - -Any slashed DOT or KSM will be added to the [Treasury](https://wiki.polkadot.com/learn/learn-polkadot-opengov-treasury/){target=\_blank} rather than burned or distributed as rewards. Moving slashed funds to the Treasury allows tokens to be quickly moved away from malicious validators while maintaining the ability to revert faulty slashes when needed. - -A nominator with a very large bond may nominate several validators in a single era. In this case, a slash is proportionate to the amount staked to the offending validator. Stake allocation and validator activation is controlled by the [Phragmén algorithm](https://wiki.polkadot.com/learn/learn-phragmen/#algorithm){target=\_blank}. - -A validator slash creates an `unapplied` state transition. You can view pending slashes on [Polkadot.js Apps](https://polkadot.js.org/apps/?rpc=wss%3A%2F%2Frpc.polkadot.io#/staking/slashes){target=\_blank}. The UI will display the slash per validator, the affected nominators, and the slash amounts. The unapplied state includes a 27-day grace period during which a governance proposal can be made to reverse the slash. Once this grace period expires, the slash is applied. - -#### Equivocation Slash - -The Web3 Foundation's [Slashing mechanisms](https://research.web3.foundation/Polkadot/security/slashing/amounts){target=\_blank} page provides guidelines for evaluating the security threat level of different offenses and determining penalties proportionate to the threat level of the offense. Offenses requiring coordination between validators or extensive computational costs to the system will typically call for harsher penalties than those more likely to be unintentional than malicious. A description of potential offenses for each threat level and the corresponding penalties is as follows: - -- **Level 1**: Honest misconduct such as isolated cases of unresponsiveness. - - **Penalty**: Validator can be kicked out or slashed up to 0.1% of stake in the validator slot. -- **Level 2**: Misconduct that can occur honestly but is a sign of bad practices. Examples include repeated cases of unresponsiveness and isolated cases of equivocation. - - **Penalty**: Slash of up to 1% of stake in the validator slot. -- **Level 3**: Misconduct that is likely intentional but of limited effect on the performance or security of the network. This level will typically include signs of coordination between validators. Examples include repeated cases of equivocation or isolated cases of unjustified voting on GRANDPA. - - **Penalty**: Reduction in networking reputation metrics, slash of up to 10% of stake in the validator slot. -- **Level 4**: Misconduct that poses severe security or monetary risk to the system or mass collusion. Examples include signs of extensive coordination, creating a serious security risk to the system, or forcing the system to use extensive resources to counter the misconduct. - - **Penalty**: Slash of up to 100% of stake in the validator slot. - -See the next section to understand how slash amounts for equivocations are calculated. If you want to know more details about slashing, please look at the research page on [Slashing mechanisms](https://research.web3.foundation/Polkadot/security/slashing/amounts){target=\_blank}. - -#### Slash Calculation for Equivocation - -The slashing penalty for GRANDPA, BABE, and BEEFY equivocations is calculated using the formula below, where `x` represents the number of offenders and `n` is the total number of validators in the active set: - -```text -min((3 * x / n )^2, 1) -``` - -The following scenarios demonstrate how this formula means slash percentages can increase exponentially based on the number of offenders involved compared to the size of the validator pool: - -- **Minor offense**: Assume 1 validator out of a 100 validator active set equivocates in a slot. A single validator committing an isolated offense is most likely a mistake rather than malicious attack on the network. This offense results in a 0.09% slash to the stake in the validator slot. - - ``` mermaid - flowchart LR - N["Total Validators = 100"] - X["Offenders = 1"] - F["min((3 * 1 / 100)^2, 1) = 0.0009"] - G["0.09% slash of stake"] - - N --> F - X --> F - F --> G - ``` - -- **Moderate offense**: Assume 5 validators out a 100 validator active set equivocate in a slot. This is a slightly more serious event as there may be some element of coordination involved. This offense results in a 2.25% slash to the stake in the validator slot. - - ``` mermaid - flowchart LR - N["Total Validators = 100"] - X["Offenders = 5"] - F["min((3 * 5 / 100)^2, 1) = 0.0225"] - G["2.25% slash of stake"] - - N --> F - X --> F - F --> G - ``` - -- **Major offense**: Assume 20 validators out a 100 validator active set equivocate in a slot. This is a major security threat as it possible represents a coordinated attack on the network. This offense results in a 36% slash and all slashed validators will also be chilled. - ``` mermaid - flowchart LR - N["Total Validators = 100"] - X["Offenders = 20"] - F["min((3 * 20 / 100)^2, 1) = 0.36"] - G["36% slash of stake"] - - N --> F - X --> F - F --> G - ``` - -The examples above show the risk of nominating or running many validators in the active set. While rewards grow linearly (two validators will get you approximately twice as many staking rewards as one), slashing grows exponentially. Going from a single validator equivocating to two validators equivocating causes a slash four time as much as the single validator. - -Validators may run their nodes on multiple machines to ensure they can still perform validation work if one of their nodes goes down. Still, validator operators should be cautious when setting these up. Equivocation is possible if they don't coordinate well in managing signing machines. - -#### Best Practices to Avoid Slashing - -The following are advised to node operators to ensure that they obtain pristine binaries or source code and to ensure the security of their node: - -- Always download either source files or binaries from the official Parity repository. -- Verify the hash of downloaded files. -- Use the W3F secure validator setup or adhere to its principles. -- Ensure essential security items are checked, use a firewall, manage user access, use SSH certificates. -- Avoid using your server as a general-purpose system. Hosting a validator on your workstation or one that hosts other services increases the risk of maleficence. -- Avoid cloning servers (copying all contents) when migrating to new hardware. If an image is needed, create it before generating keys. -- High Availability (HA) systems are generally not recommended as equivocation may occur if concurrent operations happen—such as when a failed server restarts or two servers are falsely online simultaneously. -- Copying the keystore folder when moving a database between instances can cause equivocation. Even brief use of duplicated keystores can result in slashing. - -Below are some examples of small equivocations that happened in the past: - -| Network | Era | Event Type | Details | Action Taken | -|----------|------|--------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------| -| Polkadot | 774 | Small Equivocation | [The validator](https://matrix.to/#/!NZrbtteFeqYKCUGQtr:matrix.parity.io/$165562246360408hKCfC:matrix.org?via=matrix.parity.io&via=corepaper.org&via=matrix.org){target=\_blank} migrated servers and cloned the keystore folder. The on-chain event can be viewed on [Subscan](https://polkadot.subscan.io/extrinsic/11190109-0?event=11190109-5){target=\_blank}. | The validator didn't submit a request for the slash to be canceled. | -| Kusama | 3329 | Small Equivocation | The validator operated a test machine with cloned keys. The test machine was online simultaneously as the primary, which resulted in a slash. | The validator requested a slash cancellation, but the council declined. | -| Kusama | 3995 | Small Equivocation | The validator noticed several errors, after which the client crashed, and a slash was applied. The validator recorded all events and opened GitHub issues to allow for technical opinions to be shared. | The validator requested to cancel the slash. The council approved the request as they believed the error wasn't operator-related. | - -#### Slashing Across Eras - -There are three main difficulties to account for with slashing in NPoS: - -- A nominator can nominate multiple validators and be slashed as a result of actions taken by any of them. -- Until slashed, the stake is reused from era to era. -- Slashable offenses can be found after the fact and out of order. - -To balance this, the system applies only the maximum slash a participant can receive in a given time period rather than the sum. This ensures protection from excessive slashing. - -### Disabling - -The disabling mechanism is triggered when validators commit serious infractions, such as backing invalid blocks or engaging in equivocations. Disabling stops validators from performing specific actions after they have committed an offense. Disabling is further divided into: - -- **On-chain disabling**: Lasts for a whole era and stops validators from authoring blocks, backing, and initiating a dispute. -- **Off-chain disabling**: Lasts for a session, is caused by losing a dispute, and stops validators from initiating a dispute. - -Off-chain disabling is always a lower priority than on-chain disabling. Off-chain disabling prioritizes disabling first backers and then approval checkers. - -The material in this guide reflects the changes introduced in Stage 4. For more details, see the [State of Disabling issue](https://github.com/paritytech/polkadot-sdk/issues/4359){target=\_blank} on GitHub. - - -### Reputation Changes - -Some minor offenses, such as spamming, are only punished by networking reputation changes. Validators use a reputation metric when choosing which peers to connect with. The system adds reputation if a peer provides valuable data and behaves appropriately. If they provide faulty or spam data, the system reduces their reputation. If a validator loses enough reputation, their peers will temporarily close their channels to them. This helps in fighting against Denial of Service (DoS) attacks. Performing validator tasks under reduced reputation will be harder, resulting in lower validator rewards. - -### Penalties by Offense - -Refer to the Polkadot Wiki's [offenses page](https://wiki.polkadot.com/learn/learn-offenses/){target=\_blank} for a summary of penalties for specific offenses. diff --git a/.ai/pages/nodes-and-validators-run-a-validator-staking-mechanics-rewards.md b/.ai/pages/nodes-and-validators-run-a-validator-staking-mechanics-rewards.md deleted file mode 100644 index d301d24c4..000000000 --- a/.ai/pages/nodes-and-validators-run-a-validator-staking-mechanics-rewards.md +++ /dev/null @@ -1,204 +0,0 @@ ---- -title: Rewards Payout -description: Learn how validator rewards work on the network, including era points, payout distribution, running multiple validators, and nominator payments. -categories: Infrastructure -url: https://docs.polkadot.com/nodes-and-validators/run-a-validator/staking-mechanics/rewards/ ---- - -# Rewards Payout - -## Introduction - -Understanding how rewards are distributed to validators and nominators is essential for network participants. In Polkadot and Kusama, validators earn rewards based on their era points, which are accrued through actions like block production and parachain validation. - -This guide explains the payout scheme, factors influencing rewards, and how multiple validators affect returns. Validators can also share rewards with nominators, who contribute by staking behind them. By following the payout mechanics, validators can optimize their earnings and better engage with their nominators. - -## Era Points - -The Polkadot ecosystem measures its reward cycles in a unit called an era. Kusama eras are approximately 6 hours long, and Polkadot eras are 24 hours long. At the end of each era, validators are paid proportionally to the amount of era points they have collected. Era points are reward points earned for payable actions like: - -- Issuing validity statements for [parachain blocks](/reference/parachains/blocks-transactions-fees/blocks/){target=\_blank}. -- Producing a non-uncle block in the relay chain. -- Producing a reference to a previously unreferenced uncle block. -- Producing a referenced uncle block. - -An uncle block is a relay chain block that is valid in every regard but has failed to become canonical. This can happen when two or more validators are block producers in a single slot, and the block produced by one validator reaches the next block producer before the others. The lagging blocks are called uncle blocks. - -## Reward Variance - -Rewards in Polkadot and Kusama staking systems can fluctuate due to differences in era points earned by para-validators and non-para-validators. Para-validators generally contribute more to the overall reward distribution due to their role in validating parachain blocks, thus influencing the variance in staking rewards. - -To illustrate this relationship: - -- Para-validator era points tend to have a higher impact on the expected value of staking rewards compared to non-para-validator points. -- The variance in staking rewards increases as the total number of validators grows relative to the number of para-validators. -- In simpler terms, when more validators are added to the active set without increasing the para-validator pool, the disparity in rewards between validators becomes more pronounced. - -However, despite this increased variance, rewards tend to even out over time due to the continuous rotation of para-validators across eras. The network's design ensures that over multiple eras, each validator has an equal opportunity to participate in para-validation, eventually leading to a balanced distribution of rewards. - -??? interface "Probability in Staking Rewards" - - This should only serve as a high-level overview of the probabilistic nature for staking rewards. - - Let: - - - `pe` = para-validator era points - - `ne` = non-para-validator era points - - `EV` = expected value of staking rewards - - Then, `EV(pe)` has more influence on the `EV` than `EV(ne)`. - - Since `EV(pe)` has a more weighted probability on the `EV`, the increase in variance against the `EV` becomes apparent between the different validator pools (aka. validators in the active set and the ones chosen to para-validate). - - Also, let: - - - `v` = the variance of staking rewards - - `p` = number of para-validators - - `w` = number validators in the active set - - `e` = era - - Then, `v` ↑ if `w` ↑, as this reduces `p` : `w`, with respect to `e`. - - Increased `v` is expected, and initially keeping `p` ↓ using the same para-validator set for all parachains ensures [availability](https://spec.polkadot.network/chapter-anv){target=\_blank} and [voting](https://wiki.polkadot.com/learn/learn-polkadot-opengov/){target=\_blank}. In addition, despite `v` ↑ on an `e` to `e` basis, over time, the amount of rewards each validator receives will equal out based on the continuous selection of para-validators. - - There are plans to scale the active para-validation set in the future. - -## Payout Scheme - -Validator rewards are distributed equally among all validators in the active set, regardless of the total stake behind each validator. However, individual payouts may differ based on the number of era points a validator has earned. Although factors like network connectivity can affect era points, well-performing validators should accumulate similar totals over time. - -Validators can also receive tips from users, which incentivize them to include certain transactions in their blocks. Validators retain 100% of these tips. - -Rewards are paid out in the network's native token (DOT for Polkadot and KSM for Kusama). - -The following example illustrates a four member validator set with their names, amount they have staked, and how payout of rewards is divided. This scenario assumes all validators earned the same amount of era points and no one received tips: - -``` mermaid -flowchart TD - A["Alice (18 DOT)"] - B["Bob (9 DOT)"] - C["Carol (8 DOT)"] - D["Dave (7 DOT)"] - E["Payout (8 DOT total)"] - E --"2 DOT"--> A - E --"2 DOT"--> B - E --"2 DOT"--> C - E --"2 DOT"--> D -``` - -Note that this is different than most other Proof of Stake (PoS) systems. As long as a validator is in the validator set, it will receive the same block reward as every other validator. Validator Alice, who had 18 DOT staked, received the same 2 DOT reward in this era as Dave, who had only 7 DOT staked. - -## Running Multiple Validators - -Running multiple validators can offer a more favorable risk/reward ratio compared to running a single one. If you have sufficient DOT or nominators staking on your validators, maintaining multiple validators within the active set can yield higher rewards. - -In the preceding section, with 18 DOT staked and no nominators, Alice earned 2 DOT in one era. This example uses DOT, but the same principles apply for KSM on the Kusama network. By managing stake across multiple validators, you can potentially increase overall returns. Recall the set of validators from the preceding section: - -``` mermaid -flowchart TD - A["Alice (18 DOT)"] - B["Bob (9 DOT)"] - C["Carol (8 DOT)"] - D["Dave (7 DOT)"] - E["Payout (8 DOT total)"] - E --"2 DOT"--> A - E --"2 DOT"--> B - E --"2 DOT"--> C - E --"2 DOT"--> D -``` - -Now, assume Alice decides to split their stake and run two validators, each with a nine DOT stake. This validator set only has four spots and priority is given to validators with a larger stake. In this example, Dave has the smallest stake and loses his spot in the validator set. Now, Alice will earn two shares of the total payout each era as illustrated below: - -``` mermaid -flowchart TD - A["Alice (9 DOT)"] - F["Alice (9 DOT)"] - B["Bob (9 DOT)"] - C["Carol (8 DOT)"] - E["Payout (8 DOT total)"] - E --"2 DOT"--> A - E --"2 DOT"--> B - E --"2 DOT"--> C - E --"2 DOT"--> F -``` - -With enough stake, you could run more than two validators. However, each validator must have enough stake behind it to maintain a spot in the validator set. - -## Nominators and Validator Payments - -A nominator's stake allows them to vote for validators and earn a share of the rewards without managing a validator node. Although staking rewards depend on validator activity during an era, validators themselves never control or own nominator rewards. To trigger payouts, anyone can call the `staking.payoutStakers` or `staking.payoutStakerByPage` methods, which mint and distribute rewards directly to the recipients. This trustless process ensures nominators receive their earned rewards. - -Validators set a commission rate as a percentage of the block reward, affecting how rewards are shared with nominators. A 0% commission means the validator keeps only rewards from their self-stake, while a 100% commission means they retain all rewards, leaving none for nominators. - -The following examples model splitting validator payments between nominator and validator using various commission percentages. For simplicity, these examples assume a Polkadot-SDK based relay chain that uses DOT as a native token and a single nominator per validator. Calculations of KSM reward payouts for Kusama follow the same formula. - -Start with the original validator set from the previous section: - -``` mermaid -flowchart TD - A["Alice (18 DOT)"] - B["Bob (9 DOT)"] - C["Carol (8 DOT)"] - D["Dave (7 DOT)"] - E["Payout (8 DOT total)"] - E --"2 DOT"--> A - E --"2 DOT"--> B - E --"2 DOT"--> C - E --"2 DOT"--> D -``` - -The preceding diagram shows each validator receiving a 2 DOT payout, but doesn't account for sharing rewards with nominators. The following diagram shows what nominator payout might look like for validator Alice. Alice has a 20% commission rate and holds 50% of the stake for their validator: - -``` mermaid - -flowchart TD - A["Gross Rewards = 2 DOT"] - E["Commission = 20%"] - F["Alice Validator Payment = 0.4 DOT"] - G["Total Stake Rewards = 1.6 DOT"] - B["Alice Validator Stake = 18 DOT"] - C["9 DOT Alice (50%)"] - H["Alice Stake Reward = 0.8 DOT"] - I["Total Alice Validator Reward = 1.2 DOT"] - D["9 DOT Nominator (50%)"] - J["Total Nominator Reward = 0.8 DOT"] - - A --> E - E --(2 x 0.20)--> F - F --(2 - 0.4)--> G - B --> C - B --> D - C --(1.6 x 0.50)--> H - H --(0.4 + 0.8)--> I - D --(1.60 x 0.50)--> J -``` - -Notice the validator commission rate is applied against the gross amount of rewards for the era. The validator commission is subtracted from the total rewards. After the commission is paid to the validator, the remaining amount is split among stake owners according to their percentage of the total stake. A validator's total rewards for an era include their commission plus their piece of the stake rewards. - -Now, consider a different scenario for validator Bob where the commission rate is 40%, and Bob holds 33% of the stake for their validator: - -``` mermaid - -flowchart TD - A["Gross Rewards = 2 DOT"] - E["Commission = 40%"] - F["Bob Validator Payment = 0.8 DOT"] - G["Total Stake Rewards = 1.2 DOT"] - B["Bob Validator Stake = 9 DOT"] - C["3 DOT Bob (33%)"] - H["Bob Stake Reward = 0.4 DOT"] - I["Total Bob Validator Reward = 1.2 DOT"] - D["6 DOT Nominator (67%)"] - J["Total Nominator Reward = 0.8 DOT"] - - A --> E - E --(2 x 0.4)--> F - F --(2 - 0.8)--> G - B --> C - B --> D - C --(1.2 x 0.33)--> H - H --(0.8 + 0.4)--> I - D --(1.2 x 0.67)--> J -``` - -Bob holds a smaller percentage of their node's total stake, making their stake reward smaller than Alice's. In this scenario, Bob makes up the difference by charging a 40% commission rate and ultimately ends up with the same total payment as Alice. Each validator will need to find their ideal balance between the amount of stake and commission rate to attract nominators while still making running a validator worthwhile. diff --git a/node-infrastructure/run-a-collator/collator.md b/node-infrastructure/run-a-collator/collator.md index 57ba15e1c..805e0a4ca 100644 --- a/node-infrastructure/run-a-collator/collator.md +++ b/node-infrastructure/run-a-collator/collator.md @@ -62,7 +62,7 @@ Required software: - **Operating System**: Ubuntu 22.04 LTS (recommended) or similar Linux distribution - **Docker**: For running subkey utility -- **Rust Toolchain**: Version 1.86 or as specified by the runtime +- **Rust Toolchain**: Version 1.91.1 or as specified by the runtime - **Dependencies**: ```bash sudo apt update @@ -86,17 +86,17 @@ curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh source $HOME/.cargo/env # Install specific Rust version -rustup install 1.86 -rustup default 1.86 -rustup target add wasm32-unknown-unknown --toolchain 1.86 -rustup component add rust-src --toolchain 1.86 +rustup install 1.91.1 +rustup default 1.91.1 +rustup target add wasm32-unknown-unknown --toolchain 1.91.1 +rustup component add rust-src --toolchain 1.91.1 ``` ### Step 2: Install the Polkadot Omni Node ```bash # Install polkadot-omni-node -cargo install --locked polkadot-omni-node@0.5.0 +cargo install --locked polkadot-omni-node@0.11.0 # Verify installation polkadot-omni-node --version @@ -158,7 +158,7 @@ cd runtimes cargo build --release -p asset-hub-polkadot-runtime # Install chain-spec-builder -cargo install --locked staging-chain-spec-builder@10.0.0 +cargo install --locked staging-chain-spec-builder@14.0.0 # Generate chain spec chain-spec-builder create \ diff --git a/node-infrastructure/run-a-node/polkadot-hub-rpc.md b/node-infrastructure/run-a-node/polkadot-hub-rpc.md index 92e5b2528..ee619b4a6 100644 --- a/node-infrastructure/run-a-node/polkadot-hub-rpc.md +++ b/node-infrastructure/run-a-node/polkadot-hub-rpc.md @@ -54,7 +54,7 @@ Required software: - **Operating System**: Ubuntu 22.04 LTS (recommended) or similar Linux distribution - **Docker**: Latest version installed and running (for Docker-based setup) - **rclone**: (Optional but recommended) Command-line program for managing files on cloud storage (https://rclone.org/downloads/) -- **Rust Toolchain**: Version 1.86 or as specified by runtime (for manual build) +- **Rust Toolchain**: Version 1.91.1 or later (for manual build) ## Setup Options @@ -159,7 +159,7 @@ docker run -d --name polkadot-hub-rpc --restart unless-stopped \ -p 30333:30333 \ -v $(pwd)/asset-hub-polkadot.json:/asset-hub-polkadot.json \ -v $(pwd)/my-node-data:/data \ - parity/polkadot-omni-node:stable2506-4 \ + parity/polkadot-omni-node:v1.20.2 \ --name=PolkadotHubRPC \ --base-path=/data \ --chain=/asset-hub-polkadot.json \ @@ -305,7 +305,7 @@ docker rm polkadot-hub-rpc ```bash # Pull latest image -docker pull parity/polkadot-omni-node:stable2506-4 +docker pull parity/polkadot-omni-node:v1.20.2 # Stop and remove old container docker stop polkadot-hub-rpc @@ -328,23 +328,33 @@ curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh source $HOME/.cargo/env # Install specific Rust version -rustup install 1.86 -rustup default 1.86 -rustup target add wasm32-unknown-unknown --toolchain 1.86 -rustup component add rust-src --toolchain 1.86 +rustup install 1.91.1 +rustup default 1.91.1 +rustup target add wasm32-unknown-unknown --toolchain 1.91.1 +rustup component add rust-src --toolchain 1.91.1 ``` -### Step 2: Install the Polkadot Omni Node +### Step 2: Install Required Dependencies + +```bash +# Install system dependencies +sudo apt update +sudo apt install -y build-essential git clang curl libssl-dev llvm libudev-dev make protobuf-compiler +``` + +### Step 3: Install the Polkadot Omni Node ```bash # Install polkadot-omni-node -cargo install --locked polkadot-omni-node@0.7.0 +cargo install --locked polkadot-omni-node@0.11.0 # Verify installation polkadot-omni-node --version ``` -### Step 3: Obtain Chain Specification +**Note**: Compiling polkadot-omni-node from source requires significant RAM (minimum 24GB recommended). The compilation may take 10-15 minutes on systems with adequate resources. + +### Step 4: Obtain Chain Specification Download the Polkadot Hub chain specification: @@ -352,7 +362,7 @@ Download the Polkadot Hub chain specification: curl -L https://raw.githubusercontent.com/paritytech/polkadot-sdk/master/cumulus/parachains/chain-specs/asset-hub-polkadot.json -o asset-hub-polkadot.json ``` -### Step 4: Create User and Directory Structure +### Step 5: Create User and Directory Structure ```bash # Create dedicated user @@ -368,7 +378,7 @@ sudo cp asset-hub-polkadot.json /var/lib/polkadot-hub-rpc/ sudo chown -R polkadot:polkadot /var/lib/polkadot-hub-rpc ``` -### Step 5: Create Systemd Service for Polkadot SDK Node +### Step 6: Create Systemd Service for Polkadot SDK Node Create a service file for the Polkadot SDK RPC node: @@ -418,7 +428,7 @@ LimitNOFILE=65536 WantedBy=multi-user.target ``` -### Step 6: Start Service +### Step 7: Start Service ```bash # Reload systemd @@ -435,7 +445,7 @@ sudo systemctl status polkadot-hub-rpc sudo journalctl -u polkadot-hub-rpc -f ``` -### Step 7: Verify Setup +### Step 8: Verify Setup Use the same verification tests as in the Docker setup (see Step 5 above). @@ -513,7 +523,7 @@ The node handles pruning automatically based on configuration unless running in ```bash # Pull latest image -docker pull parity/polkadot-omni-node:stable2506-4 +docker pull parity/polkadot-omni-node:v1.20.2 # Restart container docker stop polkadot-hub-rpc From ed97e71107b0ebc96599959ea974ffe4ba8571e0 Mon Sep 17 00:00:00 2001 From: Bruno Galvao Date: Thu, 20 Nov 2025 18:01:41 +0700 Subject: [PATCH 04/39] Update content --- ...-infrastructure-run-a-collator-collator.md | 105 +++++---------- ...rastructure-run-a-node-polkadot-hub-rpc.md | 126 +++--------------- ...ructure-run-a-node-system-parachain-rpc.md | 126 +++--------------- .../run-a-collator/collator.md | 105 +++++---------- .../run-a-node/polkadot-hub-rpc.md | 126 +++--------------- .../run-a-node/system-parachain-rpc.md | 126 +++--------------- 6 files changed, 160 insertions(+), 554 deletions(-) diff --git a/.ai/pages/node-infrastructure-run-a-collator-collator.md b/.ai/pages/node-infrastructure-run-a-collator-collator.md index 1f6f96cc6..cb2adbf48 100644 --- a/.ai/pages/node-infrastructure-run-a-collator-collator.md +++ b/.ai/pages/node-infrastructure-run-a-collator-collator.md @@ -42,16 +42,16 @@ Block-producing collators require robust hardware for reliable operation: - **CPU**: 4+ cores (8+ cores recommended for optimal performance) - **Memory**: 32 GB RAM minimum (64 GB recommended) - **Storage**: - - 500 GB+ NVMe SSD for parachain data - - Additional 200+ GB for relay chain pruned database - - Fast disk I/O is critical for block production performance + - 500 GB+ NVMe SSD for parachain data + - Additional 200+ GB for relay chain pruned database + - Fast disk I/O is critical for block production performance - **Network**: - - Public IP address (required) - - 100+ Mbps connection (stable connection critical) - - Open ports: - - 30333 (parachain P2P) - - 30334 (relay chain P2P) - - 9944 (WebSocket RPC - for management) + - Public IP address (required) + - 100+ Mbps connection (stable connection critical) + - Open ports: + - 30333 (parachain P2P) + - 30334 (relay chain P2P) + - 9944 (WebSocket RPC - for management) **Note**: Uptime is critical. Consider redundancy and monitoring to maintain block production reliability. @@ -73,6 +73,7 @@ Required software: ### Account Requirements You'll need: + - **Funded account**: For on-chain transactions and potential bonding - **Session keys**: For collator identification (generated after node setup) - **Node key**: For stable P2P peer ID (recommended) @@ -130,6 +131,7 @@ docker run -it parity/subkey:latest generate --scheme sr25519 ``` Save the output containing: + - Secret phrase (seed) - Keep this secure! - Public key (hex) - Account ID @@ -170,6 +172,7 @@ chain-spec-builder create \ ``` **System Parachain Para IDs:** + - Polkadot Hub: 1000 - Bridge Hub: 1002 - People Chain: 1004 @@ -236,6 +239,7 @@ WantedBy=multi-user.target ``` **Configuration Notes**: + - `--collator`: Enables block production mode - `--node-key-file`: Uses the generated node key for stable peer ID - `--name`: Your collator name (visible in telemetry) @@ -267,22 +271,14 @@ sudo journalctl -u polkadot-collator -f Your collator must sync both the relay chain and parachain before producing blocks. Sync time depends on: + - Network bandwidth - Disk I/O speed - Current chain size The relay chain uses warp sync for faster synchronization. -Monitor sync progress: -```bash -# Check logs for sync status -sudo journalctl -u polkadot-collator -f | grep "Syncing" - -# Wait for messages indicating full sync -# Example: "Idle" or "Imported" messages for both chains -``` - -**Important**: Do not proceed with registration until both chains are fully synced. +**Important**: Do not proceed with registration until both chains are fully synced. Monitor sync progress using the log viewing commands in the [Log Management](#log-management) section. ### Step 3: Generate Session Keys @@ -309,16 +305,19 @@ curl -H "Content-Type: application/json" \ System parachains use different collator selection mechanisms: **Invulnerables List**: + - Fixed list of collators approved through governance - Most common for system parachains - Requires governance proposal and approval **On-chain Selection**: + - Some parachains use pallet-collator-selection - May require bonding tokens - Automatic selection based on criteria **Fellowship Decisions**: + - Technical Fellowship may manage some system parachain collators - Requires Fellowship membership or approval @@ -361,8 +360,8 @@ Once approved (or if using on-chain selection), set your session keys: 3. Select your account 4. Choose `session.setKeys` extrinsic 5. Enter: - - `keys`: Your session keys (from `author_rotateKeys`) - - `proof`: 0x00 (typically) + - `keys`: Your session keys (from `author_rotateKeys`) + - `proof`: 0x00 (typically) 6. Submit and sign the transaction **Using CLI (alternative):** @@ -383,6 +382,7 @@ Some parachains require bonding tokens: #### 5. Await Governance Approval If using invulnerables: + - Wait for governance vote - Monitor forum and announcements - Once approved, you'll be added to the invulnerables list @@ -390,16 +390,7 @@ If using invulnerables: ### Verify Collator Status -Check if your collator is active: - -```bash -# Monitor logs for block production -sudo journalctl -u polkadot-collator -f | grep -i "imported" - -# Look for messages like: -# "Prepared block for proposing" -# "Imported #123" -``` +Check if your collator is active by monitoring logs for block production messages like "Prepared block for proposing" and "Imported #123". See the [Log Management](#log-management) section for log viewing commands. ## Monitoring and Maintenance @@ -412,14 +403,17 @@ sudo journalctl -u polkadot-collator | grep -i "prepared block" ``` **Peer Connections**: -- Maintain 30+ peers for good connectivity + +- Maintain a sufficient amount of peers for good connectivity - Check peer count in logs **Resource Usage**: + - Monitor CPU, RAM, and disk I/O - Set up alerts for high usage **Sync Status**: + - Ensure both chains stay synced - Alert on sync issues @@ -438,6 +432,7 @@ scrape_configs: {% endraw %} Key metrics to monitor: + - `substrate_block_height`: Current block height - `substrate_finalized_height`: Finalized block height - `substrate_peers_count`: Peer connections @@ -446,6 +441,7 @@ Key metrics to monitor: ### Setting Up Alerts Configure alerts for: + - Service failures - Sync issues - Low peer count (< 10 peers) @@ -482,16 +478,18 @@ The node handles pruning automatically. ### Updates and Upgrades **Runtime Upgrades**: + - Automatic via on-chain governance - No manual action required - Monitor announcements for breaking changes **Client Upgrades**: + - Require manual binary update - Subscribe to announcements: - - Polkadot Forum - - Fellowship GitHub - - Matrix channels + - Polkadot Forum + - Fellowship GitHub + - Matrix channels **Upgrade Procedure**: @@ -511,42 +509,11 @@ polkadot-omni-node --version # Restart service sudo systemctl start polkadot-collator -# Monitor logs -sudo journalctl -u polkadot-collator -f +# Verify service is running +sudo systemctl status polkadot-collator ``` -## Security Best Practices - -### Key Management - -- **Secure storage**: Store session keys and account keys securely -- **Never share**: Never share private keys or secret phrases -- **Hardware wallets**: Consider HSM for production -- **Backup**: Keep encrypted backups of keys -- **Rotation**: Plan for key rotation procedures - -### Network Security - -- **Firewall**: Restrict access to necessary ports only -- **SSH**: Use SSH keys, disable password auth -- **VPN**: Consider VPN for administrative access -- **DDoS protection**: Implement if running in cloud - -### System Security - -- **Updates**: Keep OS and software updated -- **Dedicated user**: Never run as root -- **Fail2ban**: Enable for SSH protection -- **Audits**: Regular security audits -- **Minimal services**: Disable unnecessary services - -### Operational Security - -- **Monitoring**: 24/7 monitoring with alerts -- **Backups**: Regular configuration backups -- **Documentation**: Document procedures -- **Incident response**: Have incident response plan -- **Redundancy**: Consider backup collator (standby) +**Note**: For log monitoring, see the [Log Management](#log-management) section. ## Conclusion diff --git a/.ai/pages/node-infrastructure-run-a-node-polkadot-hub-rpc.md b/.ai/pages/node-infrastructure-run-a-node-polkadot-hub-rpc.md index ed95abd5d..80f5ce475 100644 --- a/.ai/pages/node-infrastructure-run-a-node-polkadot-hub-rpc.md +++ b/.ai/pages/node-infrastructure-run-a-node-polkadot-hub-rpc.md @@ -31,20 +31,20 @@ RPC nodes serving production traffic require robust hardware: - **CPU**: 8+ cores (16+ cores for high traffic) - **Memory**: 64 GB RAM minimum (128 GB recommended for high traffic) - **Storage**: - - 500 GB+ NVMe SSD for parachain state (archive nodes require 2-4 TB+) - - Additional 200+ GB for relay chain pruned database - - Fast disk I/O is critical for query performance + - 500 GB+ NVMe SSD for parachain state (archive nodes require 2-4 TB+) + - Additional 200+ GB for relay chain pruned database + - Fast disk I/O is critical for query performance - **Network**: - - Public IP address - - 1 Gbps connection (for high traffic scenarios) - - Stable internet connection with sufficient bandwidth - - Open ports: - - 30333 (parachain P2P) - - 30334 (relay chain P2P) - - 9944 (Polkadot SDK WebSocket RPC) - - 9933 (Polkadot SDK HTTP RPC) - - 9615 (Prometheus metrics - optional) - - Consider DDoS protection and rate limiting for production deployments + - Public IP address + - 1 Gbps connection (for high traffic scenarios) + - Stable internet connection with sufficient bandwidth + - Open ports: + - 30333 (parachain P2P) + - 30334 (relay chain P2P) + - 9944 (Polkadot SDK WebSocket RPC) + - 9933 (Polkadot SDK HTTP RPC) + - 9615 (Prometheus metrics - optional) + - Consider DDoS protection and rate limiting for production deployments **Note**: For development or low-traffic scenarios, you can reduce these requirements proportionally. Consider using a reverse proxy (nginx, Caddy) for production deployments. @@ -117,6 +117,7 @@ rm files.txt ``` **Parameter Explanation**: + - `--transfers 20`: Uses 20 parallel transfers for faster download - `--retries 6`: Automatically retries failed transfers up to 6 times - `--retries-sleep 10s`: Waits 10 seconds between retry attempts @@ -142,6 +143,7 @@ rm files.txt ``` **Alternative Options**: + - Pruned snapshot: `polkadot-rocksdb-prune` (smaller size, recent state) - Archive snapshot: `polkadot-rocksdb-archive` (complete history, larger size) @@ -183,12 +185,14 @@ docker run -d --name polkadot-hub-rpc --restart unless-stopped \ **Critical Configuration Parameters**: **Port Mappings**: + - `9944`: Polkadot SDK RPC endpoint (WebSocket/HTTP) - `9933`: Polkadot SDK HTTP RPC endpoint - `9615`: Prometheus metrics endpoint - `30333/30334`: P2P networking ports **Node Parameters**: + - `--unsafe-rpc-external`: Enables external RPC access - `--rpc-cors=all`: Allows all origins for CORS - `--rpc-methods=safe`: Only allows safe RPC methods @@ -224,19 +228,10 @@ curl -H "Content-Type: application/json" \ ``` **Synchronization Status**: + - **In Progress**: `currentBlock` < `highestBlock` - **Complete**: `currentBlock` = `highestBlock` -**Monitor logs**: - -```bash -# View node logs -docker logs -f polkadot-hub-rpc - -# Filter for sync messages -docker logs polkadot-hub-rpc 2>&1 | grep -i "syncing" -``` - ### Step 5: Verify Setup Let's verify the Polkadot SDK RPC endpoint is working correctly. @@ -244,6 +239,7 @@ Let's verify the Polkadot SDK RPC endpoint is working correctly. #### API Endpoint **Polkadot SDK RPC (Port 9944)**: + - WebSocket: `ws://your-server:9944` - HTTP: `http://your-server:9944` - Purpose: Full Polkadot SDK API access for parachain data @@ -302,18 +298,7 @@ docker start polkadot-hub-rpc docker rm polkadot-hub-rpc ``` -**Update container**: - -```bash -# Pull latest image -docker pull parity/polkadot-omni-node:v1.20.2 - -# Stop and remove old container -docker stop polkadot-hub-rpc -docker rm polkadot-hub-rpc - -# Start new container with same command as above -``` +**Note**: For update procedures, see the [Updates and Upgrades](#updates-and-upgrades) section. --- @@ -479,6 +464,7 @@ sudo journalctl -u polkadot-hub-rpc | grep -i error ### Performance Monitoring Monitor key metrics: + - **Sync status**: Ensure node stays fully synced - **Peer connections**: Maintain 30+ peers for good connectivity - **Resource usage**: Monitor CPU, RAM, and disk I/O @@ -501,6 +487,7 @@ scrape_configs: {% endraw %} **Key Metrics to Monitor**: + - `substrate_block_height`: Current block height - `substrate_finalized_height`: Finalized block height - `substrate_peers_count`: Number of connected peers @@ -551,75 +538,6 @@ cargo install --locked --force polkadot-omni-node@ sudo systemctl start polkadot-hub-rpc ``` -## Security Best Practices - -### Network Security - -1. **Firewall Configuration**: - - Only expose necessary ports - - Use UFW or iptables to restrict access - - Consider IP whitelisting for RPC endpoints - -2. **Reverse Proxy** (Recommended for Production): - - Use nginx or Caddy as reverse proxy - - Enable SSL/TLS (HTTPS/WSS) - - Implement authentication - - Add rate limiting - -Example nginx configuration: - -```nginx -upstream polkadot_sdk_rpc { - server 127.0.0.1:9944; -} - -server { - listen 443 ssl http2; - server_name your-domain.com; - - ssl_certificate /path/to/cert.pem; - ssl_certificate_key /path/to/key.pem; - - # Polkadot SDK RPC - location /polkadot { - proxy_pass http://polkadot_sdk_rpc; - proxy_http_version 1.1; - proxy_set_header Upgrade $http_upgrade; - proxy_set_header Connection "upgrade"; - - # Rate limiting - limit_req zone=rpc_limit burst=10; - } -} -``` - -### RPC Security - -- **Always use `--rpc-methods=safe`**: Prevents dangerous RPC calls -- **Restrict CORS**: Use specific domains instead of `all` in production -- **Set connection limits**: Prevent resource exhaustion -- **Monitor for abuse**: Track unusual patterns -- **Authentication**: Implement API keys or OAuth for production - -### System Security - -- Keep operating system updated -- Use dedicated user accounts (never root) -- Enable fail2ban for SSH protection -- Regular security audits -- Disable unnecessary services -- Use AppArmor or SELinux for additional isolation - -### Monitoring and Alerting - -Set up alerts for: -- Service failures -- Sync issues -- Low peer count (< 10 peers) -- High resource usage -- Unusual RPC traffic patterns -- Database errors - ## Conclusion Running an RPC node for Polkadot Hub provides essential infrastructure for applications and users to interact with the network. By following this guide, you have set up a production-ready RPC node that: diff --git a/.ai/pages/node-infrastructure-run-a-node-system-parachain-rpc.md b/.ai/pages/node-infrastructure-run-a-node-system-parachain-rpc.md index 9d3fc5735..63f5aa7ed 100644 --- a/.ai/pages/node-infrastructure-run-a-node-system-parachain-rpc.md +++ b/.ai/pages/node-infrastructure-run-a-node-system-parachain-rpc.md @@ -43,20 +43,20 @@ RPC nodes serving production traffic require robust hardware: - **CPU**: 8+ cores (16+ cores for high traffic) - **Memory**: 64 GB RAM minimum (128 GB recommended for high traffic) - **Storage**: - - 500 GB+ NVMe SSD for parachain state (archive nodes require 2-4 TB+) - - Additional 200+ GB for relay chain pruned database - - Fast disk I/O is critical for query performance + - 500 GB+ NVMe SSD for parachain state (archive nodes require 2-4 TB+) + - Additional 200+ GB for relay chain pruned database + - Fast disk I/O is critical for query performance - **Network**: - - Public IP address - - 1 Gbps connection (for high traffic scenarios) - - Stable internet connection with sufficient bandwidth - - Open ports: - - 30333 (parachain P2P) - - 30334 (relay chain P2P) - - 9944 (Polkadot SDK WebSocket RPC) - - 9933 (Polkadot SDK HTTP RPC) - - 9615 (Prometheus metrics - optional) - - Consider DDoS protection and rate limiting for production deployments + - Public IP address + - 1 Gbps connection (for high traffic scenarios) + - Stable internet connection with sufficient bandwidth + - Open ports: + - 30333 (parachain P2P) + - 30334 (relay chain P2P) + - 9944 (Polkadot SDK WebSocket RPC) + - 9933 (Polkadot SDK HTTP RPC) + - 9615 (Prometheus metrics - optional) + - Consider DDoS protection and rate limiting for production deployments **Note**: For development or low-traffic scenarios, you can reduce these requirements proportionally. Consider using a reverse proxy (nginx, Caddy) for production deployments. @@ -129,6 +129,7 @@ rm files.txt ``` **Parameter Explanation**: + - `--transfers 20`: Uses 20 parallel transfers for faster download - `--retries 6`: Automatically retries failed transfers up to 6 times - `--retries-sleep 10s`: Waits 10 seconds between retry attempts @@ -156,6 +157,7 @@ rm files.txt ``` **Alternative Options**: + - Pruned snapshot: `polkadot-rocksdb-prune` (smaller size, recent state) - Archive snapshot: `polkadot-rocksdb-archive` (complete history, larger size) @@ -197,12 +199,14 @@ docker run -d --name people-chain-rpc --restart unless-stopped \ **Critical Configuration Parameters**: **Port Mappings**: + - `9944`: Polkadot SDK RPC endpoint (WebSocket/HTTP) - `9933`: Polkadot SDK HTTP RPC endpoint - `9615`: Prometheus metrics endpoint - `30333/30334`: P2P networking ports **Node Parameters**: + - `--unsafe-rpc-external`: Enables external RPC access - `--rpc-cors=all`: Allows all origins for CORS - `--rpc-methods=safe`: Only allows safe RPC methods @@ -238,19 +242,10 @@ curl -H "Content-Type: application/json" \ ``` **Synchronization Status**: + - **In Progress**: `currentBlock` < `highestBlock` - **Complete**: `currentBlock` = `highestBlock` -**Monitor logs**: - -```bash -# View node logs -docker logs -f people-chain-rpc - -# Filter for sync messages -docker logs people-chain-rpc 2>&1 | grep -i "syncing" -``` - ### Step 5: Verify Setup Let's verify the Polkadot SDK RPC endpoint is working correctly. @@ -258,6 +253,7 @@ Let's verify the Polkadot SDK RPC endpoint is working correctly. #### API Endpoint **Polkadot SDK RPC (Port 9944)**: + - WebSocket: `ws://your-server:9944` - HTTP: `http://your-server:9944` - Purpose: Full Polkadot SDK API access for parachain data @@ -332,18 +328,7 @@ docker start people-chain-rpc docker rm people-chain-rpc ``` -**Update container**: - -```bash -# Pull latest image -docker pull parity/polkadot-omni-node:v1.20.2 - -# Stop and remove old container -docker stop people-chain-rpc -docker rm people-chain-rpc - -# Start new container with same command as above -``` +**Note**: For update procedures, see the [Updates and Upgrades](#updates-and-upgrades) section. --- @@ -499,6 +484,7 @@ sudo journalctl -u people-chain-rpc | grep -i error ### Performance Monitoring Monitor key metrics: + - **Sync status**: Ensure node stays fully synced - **Peer connections**: Maintain 30+ peers for good connectivity - **Resource usage**: Monitor CPU, RAM, and disk I/O @@ -521,6 +507,7 @@ scrape_configs: {% endraw %} **Key Metrics to Monitor**: + - `substrate_block_height`: Current block height - `substrate_finalized_height`: Finalized block height - `substrate_peers_count`: Number of connected peers @@ -571,75 +558,6 @@ cargo install --locked --force polkadot-omni-node@ sudo systemctl start people-chain-rpc ``` -## Security Best Practices - -### Network Security - -1. **Firewall Configuration**: - - Only expose necessary ports - - Use UFW or iptables to restrict access - - Consider IP whitelisting for RPC endpoints - -2. **Reverse Proxy** (Recommended for Production): - - Use nginx or Caddy as reverse proxy - - Enable SSL/TLS (HTTPS/WSS) - - Implement authentication - - Add rate limiting - -Example nginx configuration: - -```nginx -upstream polkadot_sdk_rpc { - server 127.0.0.1:9944; -} - -server { - listen 443 ssl http2; - server_name your-domain.com; - - ssl_certificate /path/to/cert.pem; - ssl_certificate_key /path/to/key.pem; - - # Polkadot SDK RPC - location /polkadot { - proxy_pass http://polkadot_sdk_rpc; - proxy_http_version 1.1; - proxy_set_header Upgrade $http_upgrade; - proxy_set_header Connection "upgrade"; - - # Rate limiting - limit_req zone=rpc_limit burst=10; - } -} -``` - -### RPC Security - -- **Always use `--rpc-methods=safe`**: Prevents dangerous RPC calls -- **Restrict CORS**: Use specific domains instead of `all` in production -- **Set connection limits**: Prevent resource exhaustion -- **Monitor for abuse**: Track unusual patterns -- **Authentication**: Implement API keys or OAuth for production - -### System Security - -- Keep operating system updated -- Use dedicated user accounts (never root) -- Enable fail2ban for SSH protection -- Regular security audits -- Disable unnecessary services -- Use AppArmor or SELinux for additional isolation - -### Monitoring and Alerting - -Set up alerts for: -- Service failures -- Sync issues -- Low peer count (< 10 peers) -- High resource usage -- Unusual RPC traffic patterns -- Database errors - ## Conclusion Running an RPC node for system parachains provides critical infrastructure for accessing specialized Polkadot network services. By following this guide, you have set up a production-ready RPC node that: diff --git a/node-infrastructure/run-a-collator/collator.md b/node-infrastructure/run-a-collator/collator.md index 805e0a4ca..8230cbb44 100644 --- a/node-infrastructure/run-a-collator/collator.md +++ b/node-infrastructure/run-a-collator/collator.md @@ -41,16 +41,16 @@ Block-producing collators require robust hardware for reliable operation: - **CPU**: 4+ cores (8+ cores recommended for optimal performance) - **Memory**: 32 GB RAM minimum (64 GB recommended) - **Storage**: - - 500 GB+ NVMe SSD for parachain data - - Additional 200+ GB for relay chain pruned database - - Fast disk I/O is critical for block production performance + - 500 GB+ NVMe SSD for parachain data + - Additional 200+ GB for relay chain pruned database + - Fast disk I/O is critical for block production performance - **Network**: - - Public IP address (required) - - 100+ Mbps connection (stable connection critical) - - Open ports: - - 30333 (parachain P2P) - - 30334 (relay chain P2P) - - 9944 (WebSocket RPC - for management) + - Public IP address (required) + - 100+ Mbps connection (stable connection critical) + - Open ports: + - 30333 (parachain P2P) + - 30334 (relay chain P2P) + - 9944 (WebSocket RPC - for management) **Note**: Uptime is critical. Consider redundancy and monitoring to maintain block production reliability. @@ -72,6 +72,7 @@ Required software: ### Account Requirements You'll need: + - **Funded account**: For on-chain transactions and potential bonding - **Session keys**: For collator identification (generated after node setup) - **Node key**: For stable P2P peer ID (recommended) @@ -129,6 +130,7 @@ docker run -it parity/subkey:latest generate --scheme sr25519 ``` Save the output containing: + - Secret phrase (seed) - Keep this secure! - Public key (hex) - Account ID @@ -169,6 +171,7 @@ chain-spec-builder create \ ``` **System Parachain Para IDs:** + - Polkadot Hub: 1000 - Bridge Hub: 1002 - People Chain: 1004 @@ -235,6 +238,7 @@ WantedBy=multi-user.target ``` **Configuration Notes**: + - `--collator`: Enables block production mode - `--node-key-file`: Uses the generated node key for stable peer ID - `--name`: Your collator name (visible in telemetry) @@ -266,22 +270,14 @@ sudo journalctl -u polkadot-collator -f Your collator must sync both the relay chain and parachain before producing blocks. Sync time depends on: + - Network bandwidth - Disk I/O speed - Current chain size The relay chain uses warp sync for faster synchronization. -Monitor sync progress: -```bash -# Check logs for sync status -sudo journalctl -u polkadot-collator -f | grep "Syncing" - -# Wait for messages indicating full sync -# Example: "Idle" or "Imported" messages for both chains -``` - -**Important**: Do not proceed with registration until both chains are fully synced. +**Important**: Do not proceed with registration until both chains are fully synced. Monitor sync progress using the log viewing commands in the [Log Management](#log-management) section. ### Step 3: Generate Session Keys @@ -308,16 +304,19 @@ curl -H "Content-Type: application/json" \ System parachains use different collator selection mechanisms: **Invulnerables List**: + - Fixed list of collators approved through governance - Most common for system parachains - Requires governance proposal and approval **On-chain Selection**: + - Some parachains use pallet-collator-selection - May require bonding tokens - Automatic selection based on criteria **Fellowship Decisions**: + - Technical Fellowship may manage some system parachain collators - Requires Fellowship membership or approval @@ -360,8 +359,8 @@ Once approved (or if using on-chain selection), set your session keys: 3. Select your account 4. Choose `session.setKeys` extrinsic 5. Enter: - - `keys`: Your session keys (from `author_rotateKeys`) - - `proof`: 0x00 (typically) + - `keys`: Your session keys (from `author_rotateKeys`) + - `proof`: 0x00 (typically) 6. Submit and sign the transaction **Using CLI (alternative):** @@ -382,6 +381,7 @@ Some parachains require bonding tokens: #### 5. Await Governance Approval If using invulnerables: + - Wait for governance vote - Monitor forum and announcements - Once approved, you'll be added to the invulnerables list @@ -389,16 +389,7 @@ If using invulnerables: ### Verify Collator Status -Check if your collator is active: - -```bash -# Monitor logs for block production -sudo journalctl -u polkadot-collator -f | grep -i "imported" - -# Look for messages like: -# "Prepared block for proposing" -# "Imported #123" -``` +Check if your collator is active by monitoring logs for block production messages like "Prepared block for proposing" and "Imported #123". See the [Log Management](#log-management) section for log viewing commands. ## Monitoring and Maintenance @@ -411,14 +402,17 @@ sudo journalctl -u polkadot-collator | grep -i "prepared block" ``` **Peer Connections**: -- Maintain 30+ peers for good connectivity + +- Maintain a sufficient amount of peers for good connectivity - Check peer count in logs **Resource Usage**: + - Monitor CPU, RAM, and disk I/O - Set up alerts for high usage **Sync Status**: + - Ensure both chains stay synced - Alert on sync issues @@ -435,6 +429,7 @@ scrape_configs: ``` Key metrics to monitor: + - `substrate_block_height`: Current block height - `substrate_finalized_height`: Finalized block height - `substrate_peers_count`: Peer connections @@ -443,6 +438,7 @@ Key metrics to monitor: ### Setting Up Alerts Configure alerts for: + - Service failures - Sync issues - Low peer count (< 10 peers) @@ -479,16 +475,18 @@ The node handles pruning automatically. ### Updates and Upgrades **Runtime Upgrades**: + - Automatic via on-chain governance - No manual action required - Monitor announcements for breaking changes **Client Upgrades**: + - Require manual binary update - Subscribe to announcements: - - Polkadot Forum - - Fellowship GitHub - - Matrix channels + - Polkadot Forum + - Fellowship GitHub + - Matrix channels **Upgrade Procedure**: @@ -508,42 +506,11 @@ polkadot-omni-node --version # Restart service sudo systemctl start polkadot-collator -# Monitor logs -sudo journalctl -u polkadot-collator -f +# Verify service is running +sudo systemctl status polkadot-collator ``` -## Security Best Practices - -### Key Management - -- **Secure storage**: Store session keys and account keys securely -- **Never share**: Never share private keys or secret phrases -- **Hardware wallets**: Consider HSM for production -- **Backup**: Keep encrypted backups of keys -- **Rotation**: Plan for key rotation procedures - -### Network Security - -- **Firewall**: Restrict access to necessary ports only -- **SSH**: Use SSH keys, disable password auth -- **VPN**: Consider VPN for administrative access -- **DDoS protection**: Implement if running in cloud - -### System Security - -- **Updates**: Keep OS and software updated -- **Dedicated user**: Never run as root -- **Fail2ban**: Enable for SSH protection -- **Audits**: Regular security audits -- **Minimal services**: Disable unnecessary services - -### Operational Security - -- **Monitoring**: 24/7 monitoring with alerts -- **Backups**: Regular configuration backups -- **Documentation**: Document procedures -- **Incident response**: Have incident response plan -- **Redundancy**: Consider backup collator (standby) +**Note**: For log monitoring, see the [Log Management](#log-management) section. ## Conclusion diff --git a/node-infrastructure/run-a-node/polkadot-hub-rpc.md b/node-infrastructure/run-a-node/polkadot-hub-rpc.md index ee619b4a6..f8e653222 100644 --- a/node-infrastructure/run-a-node/polkadot-hub-rpc.md +++ b/node-infrastructure/run-a-node/polkadot-hub-rpc.md @@ -30,20 +30,20 @@ RPC nodes serving production traffic require robust hardware: - **CPU**: 8+ cores (16+ cores for high traffic) - **Memory**: 64 GB RAM minimum (128 GB recommended for high traffic) - **Storage**: - - 500 GB+ NVMe SSD for parachain state (archive nodes require 2-4 TB+) - - Additional 200+ GB for relay chain pruned database - - Fast disk I/O is critical for query performance + - 500 GB+ NVMe SSD for parachain state (archive nodes require 2-4 TB+) + - Additional 200+ GB for relay chain pruned database + - Fast disk I/O is critical for query performance - **Network**: - - Public IP address - - 1 Gbps connection (for high traffic scenarios) - - Stable internet connection with sufficient bandwidth - - Open ports: - - 30333 (parachain P2P) - - 30334 (relay chain P2P) - - 9944 (Polkadot SDK WebSocket RPC) - - 9933 (Polkadot SDK HTTP RPC) - - 9615 (Prometheus metrics - optional) - - Consider DDoS protection and rate limiting for production deployments + - Public IP address + - 1 Gbps connection (for high traffic scenarios) + - Stable internet connection with sufficient bandwidth + - Open ports: + - 30333 (parachain P2P) + - 30334 (relay chain P2P) + - 9944 (Polkadot SDK WebSocket RPC) + - 9933 (Polkadot SDK HTTP RPC) + - 9615 (Prometheus metrics - optional) + - Consider DDoS protection and rate limiting for production deployments **Note**: For development or low-traffic scenarios, you can reduce these requirements proportionally. Consider using a reverse proxy (nginx, Caddy) for production deployments. @@ -116,6 +116,7 @@ rm files.txt ``` **Parameter Explanation**: + - `--transfers 20`: Uses 20 parallel transfers for faster download - `--retries 6`: Automatically retries failed transfers up to 6 times - `--retries-sleep 10s`: Waits 10 seconds between retry attempts @@ -141,6 +142,7 @@ rm files.txt ``` **Alternative Options**: + - Pruned snapshot: `polkadot-rocksdb-prune` (smaller size, recent state) - Archive snapshot: `polkadot-rocksdb-archive` (complete history, larger size) @@ -182,12 +184,14 @@ docker run -d --name polkadot-hub-rpc --restart unless-stopped \ **Critical Configuration Parameters**: **Port Mappings**: + - `9944`: Polkadot SDK RPC endpoint (WebSocket/HTTP) - `9933`: Polkadot SDK HTTP RPC endpoint - `9615`: Prometheus metrics endpoint - `30333/30334`: P2P networking ports **Node Parameters**: + - `--unsafe-rpc-external`: Enables external RPC access - `--rpc-cors=all`: Allows all origins for CORS - `--rpc-methods=safe`: Only allows safe RPC methods @@ -223,19 +227,10 @@ curl -H "Content-Type: application/json" \ ``` **Synchronization Status**: + - **In Progress**: `currentBlock` < `highestBlock` - **Complete**: `currentBlock` = `highestBlock` -**Monitor logs**: - -```bash -# View node logs -docker logs -f polkadot-hub-rpc - -# Filter for sync messages -docker logs polkadot-hub-rpc 2>&1 | grep -i "syncing" -``` - ### Step 5: Verify Setup Let's verify the Polkadot SDK RPC endpoint is working correctly. @@ -243,6 +238,7 @@ Let's verify the Polkadot SDK RPC endpoint is working correctly. #### API Endpoint **Polkadot SDK RPC (Port 9944)**: + - WebSocket: `ws://your-server:9944` - HTTP: `http://your-server:9944` - Purpose: Full Polkadot SDK API access for parachain data @@ -301,18 +297,7 @@ docker start polkadot-hub-rpc docker rm polkadot-hub-rpc ``` -**Update container**: - -```bash -# Pull latest image -docker pull parity/polkadot-omni-node:v1.20.2 - -# Stop and remove old container -docker stop polkadot-hub-rpc -docker rm polkadot-hub-rpc - -# Start new container with same command as above -``` +**Note**: For update procedures, see the [Updates and Upgrades](#updates-and-upgrades) section. --- @@ -478,6 +463,7 @@ sudo journalctl -u polkadot-hub-rpc | grep -i error ### Performance Monitoring Monitor key metrics: + - **Sync status**: Ensure node stays fully synced - **Peer connections**: Maintain 30+ peers for good connectivity - **Resource usage**: Monitor CPU, RAM, and disk I/O @@ -498,6 +484,7 @@ scrape_configs: ``` **Key Metrics to Monitor**: + - `substrate_block_height`: Current block height - `substrate_finalized_height`: Finalized block height - `substrate_peers_count`: Number of connected peers @@ -548,75 +535,6 @@ cargo install --locked --force polkadot-omni-node@ sudo systemctl start polkadot-hub-rpc ``` -## Security Best Practices - -### Network Security - -1. **Firewall Configuration**: - - Only expose necessary ports - - Use UFW or iptables to restrict access - - Consider IP whitelisting for RPC endpoints - -2. **Reverse Proxy** (Recommended for Production): - - Use nginx or Caddy as reverse proxy - - Enable SSL/TLS (HTTPS/WSS) - - Implement authentication - - Add rate limiting - -Example nginx configuration: - -```nginx -upstream polkadot_sdk_rpc { - server 127.0.0.1:9944; -} - -server { - listen 443 ssl http2; - server_name your-domain.com; - - ssl_certificate /path/to/cert.pem; - ssl_certificate_key /path/to/key.pem; - - # Polkadot SDK RPC - location /polkadot { - proxy_pass http://polkadot_sdk_rpc; - proxy_http_version 1.1; - proxy_set_header Upgrade $http_upgrade; - proxy_set_header Connection "upgrade"; - - # Rate limiting - limit_req zone=rpc_limit burst=10; - } -} -``` - -### RPC Security - -- **Always use `--rpc-methods=safe`**: Prevents dangerous RPC calls -- **Restrict CORS**: Use specific domains instead of `all` in production -- **Set connection limits**: Prevent resource exhaustion -- **Monitor for abuse**: Track unusual patterns -- **Authentication**: Implement API keys or OAuth for production - -### System Security - -- Keep operating system updated -- Use dedicated user accounts (never root) -- Enable fail2ban for SSH protection -- Regular security audits -- Disable unnecessary services -- Use AppArmor or SELinux for additional isolation - -### Monitoring and Alerting - -Set up alerts for: -- Service failures -- Sync issues -- Low peer count (< 10 peers) -- High resource usage -- Unusual RPC traffic patterns -- Database errors - ## Conclusion Running an RPC node for Polkadot Hub provides essential infrastructure for applications and users to interact with the network. By following this guide, you have set up a production-ready RPC node that: diff --git a/node-infrastructure/run-a-node/system-parachain-rpc.md b/node-infrastructure/run-a-node/system-parachain-rpc.md index 4cfb4b741..47440b93c 100644 --- a/node-infrastructure/run-a-node/system-parachain-rpc.md +++ b/node-infrastructure/run-a-node/system-parachain-rpc.md @@ -42,20 +42,20 @@ RPC nodes serving production traffic require robust hardware: - **CPU**: 8+ cores (16+ cores for high traffic) - **Memory**: 64 GB RAM minimum (128 GB recommended for high traffic) - **Storage**: - - 500 GB+ NVMe SSD for parachain state (archive nodes require 2-4 TB+) - - Additional 200+ GB for relay chain pruned database - - Fast disk I/O is critical for query performance + - 500 GB+ NVMe SSD for parachain state (archive nodes require 2-4 TB+) + - Additional 200+ GB for relay chain pruned database + - Fast disk I/O is critical for query performance - **Network**: - - Public IP address - - 1 Gbps connection (for high traffic scenarios) - - Stable internet connection with sufficient bandwidth - - Open ports: - - 30333 (parachain P2P) - - 30334 (relay chain P2P) - - 9944 (Polkadot SDK WebSocket RPC) - - 9933 (Polkadot SDK HTTP RPC) - - 9615 (Prometheus metrics - optional) - - Consider DDoS protection and rate limiting for production deployments + - Public IP address + - 1 Gbps connection (for high traffic scenarios) + - Stable internet connection with sufficient bandwidth + - Open ports: + - 30333 (parachain P2P) + - 30334 (relay chain P2P) + - 9944 (Polkadot SDK WebSocket RPC) + - 9933 (Polkadot SDK HTTP RPC) + - 9615 (Prometheus metrics - optional) + - Consider DDoS protection and rate limiting for production deployments **Note**: For development or low-traffic scenarios, you can reduce these requirements proportionally. Consider using a reverse proxy (nginx, Caddy) for production deployments. @@ -128,6 +128,7 @@ rm files.txt ``` **Parameter Explanation**: + - `--transfers 20`: Uses 20 parallel transfers for faster download - `--retries 6`: Automatically retries failed transfers up to 6 times - `--retries-sleep 10s`: Waits 10 seconds between retry attempts @@ -155,6 +156,7 @@ rm files.txt ``` **Alternative Options**: + - Pruned snapshot: `polkadot-rocksdb-prune` (smaller size, recent state) - Archive snapshot: `polkadot-rocksdb-archive` (complete history, larger size) @@ -196,12 +198,14 @@ docker run -d --name people-chain-rpc --restart unless-stopped \ **Critical Configuration Parameters**: **Port Mappings**: + - `9944`: Polkadot SDK RPC endpoint (WebSocket/HTTP) - `9933`: Polkadot SDK HTTP RPC endpoint - `9615`: Prometheus metrics endpoint - `30333/30334`: P2P networking ports **Node Parameters**: + - `--unsafe-rpc-external`: Enables external RPC access - `--rpc-cors=all`: Allows all origins for CORS - `--rpc-methods=safe`: Only allows safe RPC methods @@ -237,19 +241,10 @@ curl -H "Content-Type: application/json" \ ``` **Synchronization Status**: + - **In Progress**: `currentBlock` < `highestBlock` - **Complete**: `currentBlock` = `highestBlock` -**Monitor logs**: - -```bash -# View node logs -docker logs -f people-chain-rpc - -# Filter for sync messages -docker logs people-chain-rpc 2>&1 | grep -i "syncing" -``` - ### Step 5: Verify Setup Let's verify the Polkadot SDK RPC endpoint is working correctly. @@ -257,6 +252,7 @@ Let's verify the Polkadot SDK RPC endpoint is working correctly. #### API Endpoint **Polkadot SDK RPC (Port 9944)**: + - WebSocket: `ws://your-server:9944` - HTTP: `http://your-server:9944` - Purpose: Full Polkadot SDK API access for parachain data @@ -331,18 +327,7 @@ docker start people-chain-rpc docker rm people-chain-rpc ``` -**Update container**: - -```bash -# Pull latest image -docker pull parity/polkadot-omni-node:v1.20.2 - -# Stop and remove old container -docker stop people-chain-rpc -docker rm people-chain-rpc - -# Start new container with same command as above -``` +**Note**: For update procedures, see the [Updates and Upgrades](#updates-and-upgrades) section. --- @@ -498,6 +483,7 @@ sudo journalctl -u people-chain-rpc | grep -i error ### Performance Monitoring Monitor key metrics: + - **Sync status**: Ensure node stays fully synced - **Peer connections**: Maintain 30+ peers for good connectivity - **Resource usage**: Monitor CPU, RAM, and disk I/O @@ -518,6 +504,7 @@ scrape_configs: ``` **Key Metrics to Monitor**: + - `substrate_block_height`: Current block height - `substrate_finalized_height`: Finalized block height - `substrate_peers_count`: Number of connected peers @@ -568,75 +555,6 @@ cargo install --locked --force polkadot-omni-node@ sudo systemctl start people-chain-rpc ``` -## Security Best Practices - -### Network Security - -1. **Firewall Configuration**: - - Only expose necessary ports - - Use UFW or iptables to restrict access - - Consider IP whitelisting for RPC endpoints - -2. **Reverse Proxy** (Recommended for Production): - - Use nginx or Caddy as reverse proxy - - Enable SSL/TLS (HTTPS/WSS) - - Implement authentication - - Add rate limiting - -Example nginx configuration: - -```nginx -upstream polkadot_sdk_rpc { - server 127.0.0.1:9944; -} - -server { - listen 443 ssl http2; - server_name your-domain.com; - - ssl_certificate /path/to/cert.pem; - ssl_certificate_key /path/to/key.pem; - - # Polkadot SDK RPC - location /polkadot { - proxy_pass http://polkadot_sdk_rpc; - proxy_http_version 1.1; - proxy_set_header Upgrade $http_upgrade; - proxy_set_header Connection "upgrade"; - - # Rate limiting - limit_req zone=rpc_limit burst=10; - } -} -``` - -### RPC Security - -- **Always use `--rpc-methods=safe`**: Prevents dangerous RPC calls -- **Restrict CORS**: Use specific domains instead of `all` in production -- **Set connection limits**: Prevent resource exhaustion -- **Monitor for abuse**: Track unusual patterns -- **Authentication**: Implement API keys or OAuth for production - -### System Security - -- Keep operating system updated -- Use dedicated user accounts (never root) -- Enable fail2ban for SSH protection -- Regular security audits -- Disable unnecessary services -- Use AppArmor or SELinux for additional isolation - -### Monitoring and Alerting - -Set up alerts for: -- Service failures -- Sync issues -- Low peer count (< 10 peers) -- High resource usage -- Unusual RPC traffic patterns -- Database errors - ## Conclusion Running an RPC node for system parachains provides critical infrastructure for accessing specialized Polkadot network services. By following this guide, you have set up a production-ready RPC node that: From 656920e92734429a3d1cc4e5a4b94905569ceffb Mon Sep 17 00:00:00 2001 From: DAWN KELLY Date: Thu, 20 Nov 2025 16:26:49 -0500 Subject: [PATCH 05/39] initial look at collator.md --- .../run-a-collator/collator.md | 303 +++++++++--------- 1 file changed, 158 insertions(+), 145 deletions(-) diff --git a/node-infrastructure/run-a-collator/collator.md b/node-infrastructure/run-a-collator/collator.md index 8230cbb44..f4b7b4937 100644 --- a/node-infrastructure/run-a-collator/collator.md +++ b/node-infrastructure/run-a-collator/collator.md @@ -8,35 +8,35 @@ categories: Infrastructure ## Overview -Block-producing collators are the backbone of system parachain operations. Unlike RPC nodes or archive nodes that simply maintain state, collators actively produce blocks and submit them to relay chain validators for inclusion. +Block-producing collators are the backbone of system parachain operations. Unlike RPC or archive nodes, which maintain state, collators actively produce blocks and submit them to relay chain validators for inclusion. -This guide covers setting up a **block-producing collator** for Polkadot system parachains. Running a collator requires: +This guide covers setting up a block-producing collator for Polkadot system parachains. Running a collator requires: - Meeting hardware requirements for reliable block production - Setting up and registering session keys - Obtaining governance approval or meeting selection criteria - Maintaining high uptime and performance -**Important**: System parachain collators typically require governance approval or being added to the invulnerables list. This is different from non-system parachains where collator selection may be more permissionless. +System parachain collators typically require governance approval or being added to the invulnerables list. This is different from non-system parachains where collator selection may be more permissionless. ## Collator Responsibilities Block-producing collators perform critical functions: -- **Maintain full nodes**: Both relay chain and parachain -- **Collect transactions**: Aggregate user transactions into blocks -- **Produce blocks**: Create parachain block candidates -- **Generate proofs**: Produce state transition proofs (Proof-of-Validity) -- **Submit to validators**: Send block candidates to relay chain validators -- **Facilitate XCM**: Enable cross-chain message passing +- Maintain full nodes for relay chain and parachain. +- Aggregate user transactions into blocks. +- Create parachain block candidates. +- Produce state transition proofs (Proof-of-Validity). +- Send block candidates to relay chain validators. +- Enable cross-chain message passing using XCM -Unlike relay chain validators, collators do not provide security guarantees—that responsibility lies with relay chain validators through the ELVES protocol. However, collators are essential for network liveness and censorship resistance. +Unlike relay chain validators, collators do not provide security guarantees—that responsibility lies with relay chain validators through the ELVES protocol. Rather, collators are essential for network liveness and censorship resistance. ## Prerequisites ### Hardware Requirements -Block-producing collators require robust hardware for reliable operation: +Block-producing collators require robust hardware for reliable operation including the following: - **CPU**: 4+ cores (8+ cores recommended for optimal performance) - **Memory**: 32 GB RAM minimum (64 GB recommended) @@ -52,13 +52,13 @@ Block-producing collators require robust hardware for reliable operation: - 30334 (relay chain P2P) - 9944 (WebSocket RPC - for management) -**Note**: Uptime is critical. Consider redundancy and monitoring to maintain block production reliability. +Uptime is critical. Consider redundancy and monitoring to maintain block production reliability. ### Software Requirements Collators use the **Polkadot Omni Node**, a universal binary that runs any parachain using a chain specification file. -Required software: +Required software includes the following: - **Operating System**: Ubuntu 22.04 LTS (recommended) or similar Linux distribution - **Docker**: For running subkey utility @@ -71,182 +71,195 @@ Required software: ### Account Requirements -You'll need: +Your account must meet the following requirements: - **Funded account**: For on-chain transactions and potential bonding - **Session keys**: For collator identification (generated after node setup) - **Node key**: For stable P2P peer ID (recommended) -## Installation +## Install Dependencies -### Step 1: Install Rust and Required Toolchain - -```bash -# Install Rust -curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -source $HOME/.cargo/env - -# Install specific Rust version -rustup install 1.91.1 -rustup default 1.91.1 -rustup target add wasm32-unknown-unknown --toolchain 1.91.1 -rustup component add rust-src --toolchain 1.91.1 -``` - -### Step 2: Install the Polkadot Omni Node +1. Install Rust using the following commands: + ```bash + # Install Rust + curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh + source $HOME/.cargo/env + + # Install specific Rust version + rustup install 1.91.1 + rustup default 1.91.1 + rustup target add wasm32-unknown-unknown --toolchain 1.91.1 + rustup component add rust-src --toolchain 1.91.1 + ``` -```bash -# Install polkadot-omni-node -cargo install --locked polkadot-omni-node@0.11.0 +2. Install the Polkadot Omni Node using the following command: + ```bash + cargo install --locked polkadot-omni-node@0.11.0 + ``` -# Verify installation -polkadot-omni-node --version -``` +3. Verify a successful installation using the `--version` flag: + ```bash + polkadot-omni-node --version + ``` -### Step 3: Generate Node Key +## Generate Node Key -Generate a stable node key for consistent peer ID: +Generating a stable node key enables a consistent peer ID across the network. Follow these steps to generate a node key: -```bash -# Create directory for node data -sudo mkdir -p /var/lib/polkadot-collator +1. Create a directory for node data using the following command: + ```bash + sudo mkdir -p /var/lib/polkadot-collator + ``` -# Generate node key using Docker -docker run -it parity/subkey:latest generate-node-key > /var/lib/polkadot-collator/node.key +2. Generate your node key using Docker with the following command: + ```bash + docker run -it parity/subkey:latest generate-node-key > /var/lib/polkadot-collator/node.key + ``` -# The output displays your peer ID -# Example: 12D3KooWExcVYu7Mvjd4kxPVLwN2ZPnZ5NyLZ5ft477wqzfP2q6E -``` +3. Locate your peer ID in the displayed output. It will be similar to the following example: + ```bash + 12D3KooWExcVYu7Mvjd4kxPVLwN2ZPnZ5NyLZ5ft477wqzfP2q6E + ``` -Save the peer ID for future reference. +Be sure to save the peer ID for future reference. -### Step 4: Generate Account Key +## Generate Account Key -Generate an account for on-chain transactions: +Generate an account for on-chain transactions as follows: -```bash -# Generate account key with sr25519 scheme -docker run -it parity/subkey:latest generate --scheme sr25519 -``` +1. Generate an account key with `sr25519` scheme using the following command: + ```bash + docker run -it parity/subkey:latest generate --scheme sr25519 + ``` -Save the output containing: +2. Save the following items displayed in the output: + - Secret phrase (seed) - Keep this secure! + - Public key (hex) + - Account ID + - SS58 Address -- Secret phrase (seed) - Keep this secure! -- Public key (hex) -- Account ID -- SS58 Address + !!! warning + Store the secret phrase securely. Never share it. Consider using a hardware wallet for production collators. -**Security**: Store the secret phrase securely. Never share it. Consider using a hardware wallet for production collators. +## Obtain Chain Specification -### Step 5: Obtain Chain Specification +Download the chain specification for your target system parachain using one of the following options: -Download the chain specification for your target system parachain: +### Download from Chainspec Collection (Recommended) -**Option 1: Download from Chainspec Collection (Recommended)** +Follow these steps to download your specification from the Chainspec Collection: 1. Visit the [Chainspec Collection website](https://paritytech.github.io/chainspecs/) 2. Find your target system parachain 3. Download the chain specification JSON file 4. Save it as `chain-spec.json` -**Option 2: Build from Runtime** +### Build Chainspec from Runtime -```bash -# Clone the runtimes repository -git clone https://github.com/polkadot-fellows/runtimes.git -cd runtimes - -# Build the desired runtime (example for Polkadot Hub) -cargo build --release -p asset-hub-polkadot-runtime - -# Install chain-spec-builder -cargo install --locked staging-chain-spec-builder@14.0.0 - -# Generate chain spec -chain-spec-builder create \ - --relay-chain polkadot \ - --para-id 1000 \ - --runtime target/release/wbuild/asset-hub-polkadot-runtime/asset_hub_polkadot_runtime.compact.compressed.wasm \ - named-preset production > chain-spec.json -``` +Follow these steps to build a chainspec from the runtime: -**System Parachain Para IDs:** +1. Clone the runtimes repository and navigate into it using the following commands: + ```bash + git clone https://github.com/polkadot-fellows/runtimes.git + cd runtimes + ``` -- Polkadot Hub: 1000 -- Bridge Hub: 1002 -- People Chain: 1004 -- Coretime Chain: 1005 +2. Build the desired runtime. Use the following command for Polkadot Hub: + ```bash + cargo build --release -p asset-hub-polkadot-runtime + ``` -### Step 6: Create User and Directory Structure +3. Install the `chain-spec-builder` dependency using the following command: + ```bash + cargo install --locked staging-chain-spec-builder@14.0.0 + ``` -```bash -# Create dedicated user -sudo useradd -r -s /bin/bash polkadot +4. Finally, generate the chain spec using the following commands: + ```bash + chain-spec-builder create \ + --relay-chain polkadot \ + --para-id 1000 \ + --runtime target/release/wbuild/asset-hub-polkadot-runtime/asset_hub_polkadot_runtime.compact.compressed.wasm \ + named-preset production > chain-spec.json + ``` -# Copy chain spec to directory -sudo cp chain-spec.json /var/lib/polkadot-collator/ +??? tip "System Parachain Para IDs" -# Set permissions -sudo chown -R polkadot:polkadot /var/lib/polkadot-collator -``` + - Polkadot Hub: 1000 + - Bridge Hub: 1002 + - People Chain: 1004 + - Coretime Chain: 1005 -## Configuration +## Create User and Directory Structure -### Create Systemd Service File +1. Create a dedicated user with the following command: + ```bash + sudo useradd -r -s /bin/bash polkadot + ``` -Create a service file for your collator: +2. Use the following command to copy your chain spec to the directory: + ```bash + sudo cp chain-spec.json /var/lib/polkadot-collator/ + ``` -```bash -sudo nano /etc/systemd/system/polkadot-collator.service -``` +3. Set permissions using the following command: + ```bash + sudo chown -R polkadot:polkadot /var/lib/polkadot-collator + ``` -Add the following configuration: - -```ini -[Unit] -Description=Polkadot System Parachain Collator -After=network.target - -[Service] -Type=simple -User=polkadot -Group=polkadot -WorkingDirectory=/var/lib/polkadot-collator - -# Block-Producing Collator Configuration -ExecStart=/usr/local/bin/polkadot-omni-node \ - --collator \ - --chain=/var/lib/polkadot-collator/chain-spec.json \ - --base-path=/var/lib/polkadot-collator \ - --port=30333 \ - --rpc-port=9944 \ - --prometheus-port=9615 \ - --node-key-file=/var/lib/polkadot-collator/node.key \ - --name="YourCollatorName" \ - -- \ - --execution=wasm \ - --chain=polkadot \ - --port=30334 \ - --sync=warp - -Restart=always -RestartSec=10 -LimitNOFILE=65536 - -[Install] -WantedBy=multi-user.target -``` +## Create Systemd Service File + +1. Create a service file to hold the configuration for your collator: + ```bash + sudo nano /etc/systemd/system/polkadot-collator.service + ``` + +2. Open the new file and add the following configuration code: + ```ini title="systemd/system/polkadot-collator.service" + [Unit] + Description=Polkadot System Parachain Collator + After=network.target + + [Service] + Type=simple + User=polkadot + Group=polkadot + WorkingDirectory=/var/lib/polkadot-collator + + # Block-Producing Collator Configuration + ExecStart=/usr/local/bin/polkadot-omni-node \ + --collator \ + --chain=/var/lib/polkadot-collator/chain-spec.json \ + --base-path=/var/lib/polkadot-collator \ + --port=30333 \ + --rpc-port=9944 \ + --prometheus-port=9615 \ + --node-key-file=/var/lib/polkadot-collator/node.key \ + --name="YourCollatorName" \ + -- \ + --execution=wasm \ + --chain=polkadot \ + --port=30334 \ + --sync=warp + + Restart=always + RestartSec=10 + LimitNOFILE=65536 + + [Install] + WantedBy=multi-user.target + ``` -**Configuration Notes**: +??? tip -- `--collator`: Enables block production mode -- `--node-key-file`: Uses the generated node key for stable peer ID -- `--name`: Your collator name (visible in telemetry) -- Relay chain uses `--sync=warp` for faster initial sync + - `--collator`: Enables block production mode + - `--node-key-file`: Uses the generated node key for stable peer ID + - `--name`: Your collator name (visible in telemetry) + - Relay chain uses `--sync=warp` for faster initial sync ## Running the Collator -### Step 1: Start the Service +### Start the Service ```bash # Reload systemd @@ -265,7 +278,7 @@ sudo systemctl status polkadot-collator sudo journalctl -u polkadot-collator -f ``` -### Step 2: Initial Sync +### Initial Sync Your collator must sync both the relay chain and parachain before producing blocks. @@ -279,7 +292,7 @@ The relay chain uses warp sync for faster synchronization. **Important**: Do not proceed with registration until both chains are fully synced. Monitor sync progress using the log viewing commands in the [Log Management](#log-management) section. -### Step 3: Generate Session Keys +### Generate Session Keys Once your node is fully synced, generate session keys: From b04156ae9cb6ea43b5a19dcee297d057450c12b4 Mon Sep 17 00:00:00 2001 From: DAWN KELLY Date: Thu, 20 Nov 2025 16:28:53 -0500 Subject: [PATCH 06/39] tweak admo --- node-infrastructure/run-a-collator/collator.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/node-infrastructure/run-a-collator/collator.md b/node-infrastructure/run-a-collator/collator.md index f4b7b4937..b0b9699f0 100644 --- a/node-infrastructure/run-a-collator/collator.md +++ b/node-infrastructure/run-a-collator/collator.md @@ -250,7 +250,7 @@ Follow these steps to build a chainspec from the runtime: WantedBy=multi-user.target ``` -??? tip +??? note "Configuration notes" - `--collator`: Enables block production mode - `--node-key-file`: Uses the generated node key for stable peer ID From dbd2d9805e7274080a60fdc822ea11f3d0f5cca7 Mon Sep 17 00:00:00 2001 From: DAWN KELLY Date: Fri, 21 Nov 2025 10:39:10 -0500 Subject: [PATCH 07/39] wip - collator page --- .../run-a-collator/collator.md | 35 +++++++++++-------- 1 file changed, 21 insertions(+), 14 deletions(-) diff --git a/node-infrastructure/run-a-collator/collator.md b/node-infrastructure/run-a-collator/collator.md index b0b9699f0..645024cd4 100644 --- a/node-infrastructure/run-a-collator/collator.md +++ b/node-infrastructure/run-a-collator/collator.md @@ -257,28 +257,35 @@ Follow these steps to build a chainspec from the runtime: - `--name`: Your collator name (visible in telemetry) - Relay chain uses `--sync=warp` for faster initial sync -## Running the Collator +## Run the Collator -### Start the Service +Follow these steps to run your collator node: -```bash -# Reload systemd -sudo systemctl daemon-reload - -# Enable service to start on boot -sudo systemctl enable polkadot-collator +1. Reload systemd using the following command: + ```bash + sudo systemctl daemon-reload + ``` -# Start the service -sudo systemctl start polkadot-collator +2. Next, enable the service to start on boot using the command: + ```bash + sudo systemctl enable polkadot-collator + ``` +3. Now, start the service with the following command: + ```bash + sudo systemctl start polkadot-collator + ``` -# Check status -sudo systemctl status polkadot-collator +4. Finally, you can check the status of the service using the command: + ```bash + sudo systemctl status polkadot-collator + ``` -# View logs +To view collator service logs, use the command: +```bash sudo journalctl -u polkadot-collator -f ``` -### Initial Sync +## Complete Initial Sync Your collator must sync both the relay chain and parachain before producing blocks. From fc25788bd1fc39d7bdfee79d3795dff7cc2653f9 Mon Sep 17 00:00:00 2001 From: DAWN KELLY Date: Fri, 21 Nov 2025 12:39:10 -0500 Subject: [PATCH 08/39] finish collator pre-tech review pass --- .../run-a-collator/collator.md | 336 +++++++----------- 1 file changed, 136 insertions(+), 200 deletions(-) diff --git a/node-infrastructure/run-a-collator/collator.md b/node-infrastructure/run-a-collator/collator.md index 645024cd4..a72c1e5a6 100644 --- a/node-infrastructure/run-a-collator/collator.md +++ b/node-infrastructure/run-a-collator/collator.md @@ -133,13 +133,14 @@ Generate an account for on-chain transactions as follows: ``` 2. Save the following items displayed in the output: - - Secret phrase (seed) - Keep this secure! - - Public key (hex) - - Account ID - - SS58 Address + - Secret phrase (seed) - Keep this secure! + - Public key (hex) + - Account ID + - SS58 Address - !!! warning - Store the secret phrase securely. Never share it. Consider using a hardware wallet for production collators. + !!! warning + + Store the secret phrase securely. Never share it. Consider using a hardware wallet for production collators. ## Obtain Chain Specification @@ -149,10 +150,10 @@ Download the chain specification for your target system parachain using one of t Follow these steps to download your specification from the Chainspec Collection: -1. Visit the [Chainspec Collection website](https://paritytech.github.io/chainspecs/) -2. Find your target system parachain -3. Download the chain specification JSON file -4. Save it as `chain-spec.json` +1. Visit the [Chainspec Collection](https://paritytech.github.io/chainspecs/) website. +2. Find your target system parachain. +3. Download the chain specification JSON file. +4. Save it as `chain-spec.json`. ### Build Chainspec from Runtime @@ -299,246 +300,181 @@ The relay chain uses warp sync for faster synchronization. **Important**: Do not proceed with registration until both chains are fully synced. Monitor sync progress using the log viewing commands in the [Log Management](#log-management) section. -### Generate Session Keys +## Generate Session Keys -Once your node is fully synced, generate session keys: +Once your node is fully synced, use the following command to generate session keys via RPC: ```bash -# Generate session keys via RPC curl -H "Content-Type: application/json" \ -d '{"id":1, "jsonrpc":"2.0", "method": "author_rotateKeys", "params":[]}' \ http://localhost:9944 - -# Returns session keys as a hex string -# Example: "0x1234567890abcdef..." ``` -**Save the session keys** - you'll need them for on-chain registration. - -**Note**: Session keys are stored in the node's database. If you wipe the database, you'll need to generate new keys. +This command returns session keys as a hexstring in the terminal. You must save these session keys as you'll need them for on-chain registration. As session keys are stored in the node's database, if you wipe the database, you'll also need to generate new keys. -## Registration and Governance +## Register Collator for Selection -### Understanding Collator Selection +System parachains use different collator selection mechanisms. Explore the following tabs to see how mechanisms compare and determine the most suitable mechanism for registering your collator. -System parachains use different collator selection mechanisms: +=== "Invulnerables List" -**Invulnerables List**: + - Fixed list of collators approved through governance. + - Most common for system parachains. + - Requires governance proposal and approval. -- Fixed list of collators approved through governance -- Most common for system parachains -- Requires governance proposal and approval -**On-chain Selection**: +=== "On-chain Selection" -- Some parachains use pallet-collator-selection -- May require bonding tokens -- Automatic selection based on criteria + - Some parachains use pallet-collator-selection. + - May require bonding tokens. + - Automatic selection based on criteria. -**Fellowship Decisions**: +=== "Fellowship Decisions" -- Technical Fellowship may manage some system parachain collators -- Requires Fellowship membership or approval + - Technical Fellowship may manage some system parachain collators. + - Requires Fellowship membership or approval. ### Registration Process -The registration process varies by system parachain. General steps: - -#### 1. Check Current Collators - -Check the existing collators for your target parachain: - -```bash -# Using Polkadot.js Apps -# Connect to your target system parachain -# Go to Developer > Chain State -# Query: collatorSelection.invulnerables() or similar -``` - -#### 2. Prepare Governance Proposal - -For invulnerables-based selection: - -1. **Draft proposal**: Explain why you should be added as a collator -2. **Technical details**: Provide your session keys and account ID -3. **Infrastructure**: Describe your hardware and monitoring setup -4. **Experience**: Detail your relevant experience - -Submit to: -- Polkadot Forum: https://forum.polkadot.network -- Relevant governance channels - -#### 3. Set Session Keys On-Chain - -Once approved (or if using on-chain selection), set your session keys: - -**Using Polkadot.js Apps:** - -1. Navigate to Polkadot.js Apps and connect to your system parachain -2. Go to **Developer > Extrinsics** -3. Select your account -4. Choose `session.setKeys` extrinsic -5. Enter: - - `keys`: Your session keys (from `author_rotateKeys`) - - `proof`: 0x00 (typically) -6. Submit and sign the transaction - -**Using CLI (alternative):** - -```bash -# This varies by parachain - consult specific documentation -``` - -#### 4. Bond Tokens (if required) - -Some parachains require bonding tokens: - -1. Go to **Developer > Extrinsics** -2. Select `collatorSelection.registerAsCandidate` (if available) -3. Submit with required bond amount -4. Sign transaction - -#### 5. Await Governance Approval - -If using invulnerables: - -- Wait for governance vote -- Monitor forum and announcements -- Once approved, you'll be added to the invulnerables list -- Your collator will begin producing blocks in the next session/era - -### Verify Collator Status - -Check if your collator is active by monitoring logs for block production messages like "Prepared block for proposing" and "Imported #123". See the [Log Management](#log-management) section for log viewing commands. - -## Monitoring and Maintenance - -### Essential Monitoring - -**Block Production**: -```bash -# Monitor block production -sudo journalctl -u polkadot-collator | grep -i "prepared block" -``` - -**Peer Connections**: - -- Maintain a sufficient amount of peers for good connectivity -- Check peer count in logs - -**Resource Usage**: - -- Monitor CPU, RAM, and disk I/O -- Set up alerts for high usage - -**Sync Status**: - -- Ensure both chains stay synced -- Alert on sync issues +The registration process varies by system parachain. General steps include the following: + +1. Check the existing collators for your target parachain: + + 1. Navigate to Polkadot.js Apps and connect to your system parachain. + 2. Locate **Developer > Chain State**. + 3. Query `collatorSelection.invulnerables()` + +2. Prepare a governance proposal for invulnerables-based selection including the following information: + - **Draft proposal**: Explain why you should be added as a collator + - **Technical details**: Provide your session keys and account ID + - **Infrastructure**: Describe your hardware and monitoring setup + - **Experience**: Detail your relevant experience + + Submit the proposal to the relevant governance channels on the [Polkadot Forum](https://forum.polkadot.network){target=\_blank}. + +3. Once approved (or if using on-chain selection), follow these steps to register session keys using Polkadot.js Apps: + 1. Navigate to Polkadot.js Apps and connect to your system parachain. + 2. Locate **Developer > Extrinsics**. + 3. Select your account. + 4. Choose the `session.setKeys` extrinsic. + 5. Enter the following information: + - `keys`: Your session keys (from `author_rotateKeys`) + - `proof`: 0x00 (typically) + 6. Submit and sign the transaction. + +4. If the parachain requires bonding tokens, use the follow these steps to submit them using Polkadot.js Apps: + 1. Locate **Developer > Extrinsics**. + 2. Select `collatorSelection.registerAsCandidate`. + 3. Submit the transaction with the required bond amount. + 4. Sign the transaction. + +5. If applying to join the invulnerables list, you must now await governance approval for your proposal. Monitor the [Polkadot Forum](https://forum.polkadot.network){target=\_blank} governance channels and announcements. Once approved, your collator is added to the invulnerables list and will begin producing blocks in the next session or era. + +6. Verify your collator is active by monitoring logs for block production messages like "Prepared block for proposing" and "Imported #123". See the [Log Management](#log-management) section for log viewing commands. + +## Monitor and Maintain Your Collator + +Monitoring the following items will help ensure your collator runs efficiently to avoid service interruptions or down time: + +- **Block Production**: monitor for block production using the following command: + ```bash + sudo journalctl -u polkadot-collator | grep -i "prepared block" + ``` +- **Peer Connections**: Maintain a sufficient amount of peers for good connectivity and set up alerts to notify if peer connections falls below ten. +- **Resource Usage**: Monitor CPU, RAM, and disk I/O and set up alerts for unusual or high usage. +- **Sync Status**: Ensure both chains stay synced and set up alerts for sync issues. ### Prometheus Metrics -Metrics available at `http://localhost:9615/metrics` +You can use the following information to configure [Prometheus](https://prometheus.io/docs/introduction/first_steps/){target=\_blank} to monitor, collect, and store your collator node metrics: -Example Prometheus configuration: -```yaml -scrape_configs: - - job_name: 'polkadot-collator' - static_configs: - - targets: ['localhost:9615'] -``` +- **URL**: Metrics are available to view at `http://localhost:9615/metrics` +- **Example Prometheus configuration**: Update your `prometheus.yml` to add the following code: + ```yaml + scrape_configs: + - job_name: 'polkadot-collator' + static_configs: + - targets: ['localhost:9615'] + ``` -Key metrics to monitor: +Key metrics to monitor via Prometheus include the following: - `substrate_block_height`: Current block height - `substrate_finalized_height`: Finalized block height - `substrate_peers_count`: Peer connections - `substrate_ready_transactions_number`: Transaction queue -### Setting Up Alerts -Configure alerts for: +## Log Management -- Service failures -- Sync issues -- Low peer count (< 10 peers) -- Block production gaps -- High resource usage -- Disk space low +Effecient log management is essential to ensure collator performance and uptime. Use the following commands to help you manage logs to monitor and maintain your collator: -### Log Management +- View recent logs: + ```bash + sudo journalctl -u polkadot-collator -n 100 + ``` +- Follow logs in real-time: + ```bash + sudo journalctl -u polkadot-collator -f + ``` +- Filter for errors: + ```bash + sudo journalctl -u polkadot-collator | grep -i error + ``` +- Filter for block production: + ```bash + sudo journalctl -u polkadot-collator | grep -i "imported" + ``` -```bash -# View recent logs -sudo journalctl -u polkadot-collator -n 100 +## Database Maintenance -# Follow logs in real-time -sudo journalctl -u polkadot-collator -f - -# Filter for errors -sudo journalctl -u polkadot-collator | grep -i error - -# Filter for block production -sudo journalctl -u polkadot-collator | grep -i "imported" -``` - -### Database Maintenance - -Check database size: +You can check database size using the following command: ```bash -# Check database size du -sh /var/lib/polkadot-collator ``` +The collator node handles pruning automatically. -The node handles pruning automatically. - -### Updates and Upgrades +## Updates and Upgrades -**Runtime Upgrades**: +Updates or upgrades can happen on either the runtime or client. Runtime upgrades happen automatically via on-chain governance and do not require manual action on your part. Client upgrades do require a manual binary update process performed via terminal commands as follows: -- Automatic via on-chain governance -- No manual action required -- Monitor announcements for breaking changes +1. Stop the service: + ```bash + sudo systemctl stop polkadot-collator + ``` -**Client Upgrades**: +2. Backup data (recommended): + ```bash + sudo cp -r /var/lib/polkadot-collator /var/lib/polkadot-collator.backup + ``` -- Require manual binary update -- Subscribe to announcements: - - Polkadot Forum - - Fellowship GitHub - - Matrix channels +3. Update `polkadot-omni-node`: + ```bash + cargo install --locked --force polkadot-omni-node@ + ``` -**Upgrade Procedure**: +4. Verify `polkadot-omni-node` version to confirm successful update: + ```bash + polkadot-omni-node --version + ``` -```bash -# Stop the service -sudo systemctl stop polkadot-collator - -# Backup data (recommended) -sudo cp -r /var/lib/polkadot-collator /var/lib/polkadot-collator.backup - -# Update polkadot-omni-node -cargo install --locked --force polkadot-omni-node@ - -# Verify version -polkadot-omni-node --version - -# Restart service -sudo systemctl start polkadot-collator - -# Verify service is running -sudo systemctl status polkadot-collator -``` +5. Restart the service: + ```bash + sudo systemctl start polkadot-collator + ``` -**Note**: For log monitoring, see the [Log Management](#log-management) section. +6. Verify the service is running: + ```bash + sudo systemctl status polkadot-collator + ``` ## Conclusion Running a collator node is essential for parachain operation and network security. By following this guide, you have set up a production-ready collator that: -- Produces blocks for your parachain and maintains network consensus -- Implements comprehensive security measures to protect keys and operations -- Supports robust monitoring and alerting for reliable performance -- Follows best practices for both Docker and systemd deployments +- Produces blocks for your parachain and maintains network consensus. +- Implements comprehensive security measures to protect keys and operations. +- Supports robust monitoring and alerting for reliable performance. +- Follows best practices for both Docker and systemd deployments. -As a collator operator, you play a vital role in your parachain's infrastructure. Regular maintenance, security updates, and monitoring will ensure your collator continues to perform reliably. Stay engaged with your parachain community and keep up with updates to maintain optimal performance and security. +As a collator operator, you play a vital role in your parachain's infrastructure. Regular maintenance, security updates, and monitoring will ensure your collator continues to perform reliably. Stay engaged with your parachain community and keep up with updates to maintain optimal performance and security. \ No newline at end of file From 2de9f460f4229471a42d11dbccb0f297c13a97d7 Mon Sep 17 00:00:00 2001 From: DAWN KELLY Date: Fri, 21 Nov 2025 15:56:33 -0500 Subject: [PATCH 09/39] clean up formatting for RPC node page --- .../run-a-node/polkadot-hub-rpc.md | 903 +++++++++--------- 1 file changed, 431 insertions(+), 472 deletions(-) diff --git a/node-infrastructure/run-a-node/polkadot-hub-rpc.md b/node-infrastructure/run-a-node/polkadot-hub-rpc.md index f8e653222..247651263 100644 --- a/node-infrastructure/run-a-node/polkadot-hub-rpc.md +++ b/node-infrastructure/run-a-node/polkadot-hub-rpc.md @@ -1,6 +1,6 @@ --- title: Run an RPC Node for Polkadot Hub -description: Complete guide to set up and run an RPC node for Polkadot Hub with Polkadot SDK RPC endpoints. +description: Follow this guide to understand hardware and software requirements and how to set up and run an RPC node for Polkadot Hub with Polkadot SDK RPC endpoints. categories: Infrastructure --- @@ -19,13 +19,15 @@ Running an RPC node for Polkadot Hub enables applications, wallets, and users to This setup enables block explorer indexing and provides full compatibility with Polkadot SDK development tools. -**Important Note**: The parameters and configurations in this guide are provided as illustrative examples. You may need to modify them according to your specific environment, hardware capabilities, and network conditions. +!!! note + + The parameters and configurations in this guide are provided as illustrative examples. You may need to modify them according to your specific environment, hardware capabilities, and network conditions. ## Prerequisites ### Hardware Requirements -RPC nodes serving production traffic require robust hardware: +RPC nodes serving production traffic require robust hardware. The following should be considered the minimum standard to effectively operate an RPC node: - **CPU**: 8+ cores (16+ cores for high traffic) - **Memory**: 64 GB RAM minimum (128 GB recommended for high traffic) @@ -58,490 +60,447 @@ Required software: ## Setup Options -This guide provides two deployment options: +This guide provides two options for deployment: + +- **Docker-based Setup**: Best for simpler set up and maintainance +- **Manual/systemd Setup**: Best for production environments requiring more control + +Select the best option for your project, then use the steps in the following tabs to complete set up. + + +=== "Docker-Based Setup" + + This option uses Docker containers for the Polkadot SDK node, making it easy to set up and manage. Follow these steps to set your RPC node using Docker: + + 1. Download the official Polkadot Hub (formerly known as Asset Hub) chain specification: + ```bash + curl -L https://raw.githubusercontent.com/paritytech/polkadot-sdk/master/cumulus/parachains/chain-specs/asset-hub-polkadot.json -o asset-hub-polkadot.json + ``` + + !!! note + + This chain specification is the official configuration file that defines the network parameters for Polkadot Hub. + + 2. (Optional but recommended) Download database snapshots + - Using pre-synchronized snapshots significantly reduces initial sync time from several days to just a few hours. You need to download both parachain and relay chain data. + - You can obtain the lastest snapshot from the [Snapshot Provider](https://snapshots.polkadot.io/){target=\_blank}. Follow these steps to download and use snapshots: + 1. Create new directories with the following commands: + ```bash + mkdir -p my-node-data/chains/asset-hub-polkadot/db + mkdir -p my-node-data/chains/polkadot/db + ``` + 2. Download the appropriate snapshot using the following commands: + + === "Archive snapshot" + + Contains complete history, recommended for RPC with historical data. + ```bash + # Check https://snapshots.polkadot.io/ for the latest snapshot URL + export SNAPSHOT_URL_ASSET_HUB="https://snapshots.polkadot.io/polkadot-asset-hub-rocksdb-archive/LATEST" + + rclone copyurl $SNAPSHOT_URL_ASSET_HUB/files.txt files.txt + rclone copy --progress --transfers 20 \ + --http-url $SNAPSHOT_URL_ASSET_HUB \ + --no-traverse --http-no-head --disable-http2 \ + --inplace --no-gzip-encoding --size-only \ + --retries 6 --retries-sleep 10s \ + --files-from files.txt :http: my-node-data/chains/asset-hub-polkadot/db/ + + rm files.txt + ``` + + - `--transfers 20`: Uses 20 parallel transfers for faster download. + - `--retries 6`: Automatically retries failed transfers up to 6 times. + - `--retries-sleep 10s`: Waits 10 seconds between retry attempts. + - `--size-only`: Only transfers if sizes differ (prevents unnecessary re-downloads). + + === "Pruned snapshot" + + Contains recent state for a smaller package size, recommended for RPC nodes. + ```bash + # Check https://snapshots.polkadot.io/ for the latest snapshot URL + export SNAPSHOT_URL_RELAY="https://snapshots.polkadot.io/polkadot-rocksdb-prune/LATEST" + + rclone copyurl $SNAPSHOT_URL_RELAY/files.txt files.txt + rclone copy --progress --transfers 20 \ + --http-url $SNAPSHOT_URL_RELAY \ + --no-traverse --http-no-head --disable-http2 \ + --inplace --no-gzip-encoding --size-only \ + --retries 6 --retries-sleep 10s \ + --files-from files.txt :http: my-node-data/chains/polkadot/db/ + + rm files.txt + ``` + 3. Launch Polkadot Hub Node using the official [Parity Docker image](https://hub.docker.com/r/parity/polkadot-omni-node){target=\_blank} with the following command: + ```bash + docker run -d --name polkadot-hub-rpc --restart unless-stopped \ + -p 9944:9944 \ + -p 9933:9933 \ + -p 9615:9615 \ + -p 30334:30334 \ + -p 30333:30333 \ + -v $(pwd)/asset-hub-polkadot.json:/asset-hub-polkadot.json \ + -v $(pwd)/my-node-data:/data \ + parity/polkadot-omni-node:v1.20.2 \ + --name=PolkadotHubRPC \ + --base-path=/data \ + --chain=/asset-hub-polkadot.json \ + --prometheus-external \ + --prometheus-port 9615 \ + --unsafe-rpc-external \ + --rpc-port=9944 \ + --rpc-cors=all \ + --rpc-methods=safe \ + --rpc-max-connections=1000 \ + --state-pruning=archive \ + --blocks-pruning=archive \ + -- \ + --base-path=/data \ + --chain=polkadot \ + --state-pruning=256 \ + --blocks-pruning=archive-canonical + ``` + + Critical configuration parameters include port mappings and node parameters: + + === "Port mappings" + + - `9944`: Polkadot SDK RPC endpoint (WebSocket/HTTP) + - `9933`: Polkadot SDK HTTP RPC endpoint + - `9615`: Prometheus metrics endpoint + - `30333/30334`: P2P networking ports + + === "Node parameters" + + - `--unsafe-rpc-external`: Enables external RPC access + - `--rpc-cors=all`: Allows all origins for CORS + - `--rpc-methods=safe`: Only allows safe RPC methods + - `--state-pruning=archive`: Keeps complete state history + - `--blocks-pruning=archive`: Keeps all block data + - `--prometheus-external`: Exposes metrics externally + + !!! warning + + The `--unsafe-rpc-external` flag should only be used in development or properly secured environments. For production, use a reverse proxy with authentication. + + 4. Monitor the node synchronization status using the following command: + ```bash + curl -H "Content-Type: application/json" \ + -d '{"id":1, "jsonrpc":"2.0", "method": "system_syncState", "params":[]}' \ + http://localhost:9944 + ``` + + You should see a response similar to the following: + + ```json + { + "jsonrpc":"2.0", + "id":1, + "result":{ + "startingBlock":0, + "currentBlock":3394816, + "highestBlock":3394816 + } + } + ``` + + When synchronization is complete, `currentBlock` will be equal to `highestBlock`. + + 5. You can use a few different commands to verify your node is running properly: + + - Get chain information: + ```bash + curl -H "Content-Type: application/json" \ + -d '{"id":1, "jsonrpc":"2.0", "method": "system_chain", "params":[]}' \ + http://localhost:9944 + ``` + - Get the latest block: + ```bash + curl -H "Content-Type: application/json" \ + -d '{"id":1, "jsonrpc":"2.0", "method": "chain_getHeader", "params":[]}' \ + http://localhost:9944 + ``` + - Query node health: + ```bash + curl -H "Content-Type: application/json" \ + -d '{"id":1, "jsonrpc":"2.0", "method": "system_health", "params":[]}' \ + http://localhost:9944 + ``` + + 6. Use the following commands to manage your Docker containers: + + - View node logs: + ```bash + docker logs -f polkadot-hub-rpc + ``` + - Stop container: + ```bash + docker stop polkadot-hub-rpc + ``` + - Start container: + ```bash + docker start polkadot-hub-rpc + ``` + - Remove container: + ```bash + docker rm polkadot-hub-rpc + ``` +=== "Manual systemd Setup" + + This option provides more control and is recommended for production environments requiring custom configurations. + + 1. Install Rust and required toolchain using the following command: + ```bash + # Install Rust + curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh + source $HOME/.cargo/env + + # Install specific Rust version + rustup install 1.91.1 + rustup default 1.91.1 + rustup target add wasm32-unknown-unknown --toolchain 1.91.1 + rustup component add rust-src --toolchain 1.91.1 + ``` + + 2. Install required dependencies using the following commands: + - System dependencies: + ```bash + sudo apt update + sudo apt install -y build-essential git clang curl libssl-dev llvm libudev-dev make protobuf-compiler + ``` + - Polkadot Omni node: + ```bash + cargo install --locked polkadot-omni-node@0.11.0 + ``` + You can verify successful installation of Polkadot Omni node using the version command: + ```bash + polkadot-omni-node --version + ``` + + !!! tip + + Compiling polkadot-omni-node from source requires significant RAM (minimum 24GB recommended). The compilation may take 10-15 minutes on systems with adequate resources. + + 3. Download the Polkadot Hub chain specification: + ```bash + curl -L https://raw.githubusercontent.com/paritytech/polkadot-sdk/master/cumulus/parachains/chain-specs/asset-hub-polkadot.json -o asset-hub-polkadot.json + ``` + + 4. Create user and directory structures using the following commands: + - Create a dedicated user: + ```bash + sudo useradd -r -s /bin/bash polkadot + ``` + - Create data directory: + ```bash + sudo mkdir -p /var/lib/polkadot-hub-rpc + ``` + - Copy the chain spec to the directory: + ```bash + sudo cp asset-hub-polkadot.json /var/lib/polkadot-hub-rpc/ + ``` + - Set permissions: + ```bash + sudo chown -R polkadot:polkadot /var/lib/polkadot-hub-rpc + ``` + + 5. Create a systemd service file for the Polkadot SDK RPC node: + ```bash + sudo nano /etc/systemd/system/polkadot-hub-rpc.service + ``` + + 6. Open the new service file and add the following configuration: + ```ini + [Unit] + Description=Polkadot Hub RPC Node + After=network.target + + [Service] + Type=simple + User=polkadot + Group=polkadot + WorkingDirectory=/var/lib/polkadot-hub-rpc + + ExecStart=/usr/local/bin/polkadot-omni-node \ + --name=PolkadotHubRPC \ + --chain=/var/lib/polkadot-hub-rpc/asset-hub-polkadot.json \ + --base-path=/var/lib/polkadot-hub-rpc \ + --port=30333 \ + --rpc-port=9944 \ + --rpc-external \ + --rpc-cors=all \ + --rpc-methods=safe \ + --rpc-max-connections=1000 \ + --prometheus-port=9615 \ + --prometheus-external \ + --state-pruning=archive \ + --blocks-pruning=archive \ + -- \ + --chain=polkadot \ + --base-path=/var/lib/polkadot-hub-rpc \ + --port=30334 \ + --state-pruning=256 \ + --blocks-pruning=archive-canonical + + Restart=always + RestartSec=10 + LimitNOFILE=65536 + + [Install] + WantedBy=multi-user.target + ``` + + 7. Start the service using the following commands: + - Reload systemd: + ```bash + sudo systemctl daemon-reload + ``` + - Enable service to start on boot: + ```bash + sudo systemctl enable polkadot-hub-rpc + ``` + - Start the Polkadot SDK node: + ```bash + sudo systemctl start polkadot-hub-rpc + ``` + - Check status and wait for sync: + ```bash + sudo systemctl status polkadot-hub-rpc + sudo journalctl -u polkadot-hub-rpc -f + ``` + + 8. You can use a few different commands to verify your node is running properly: + - Get chain information: + ```bash + curl -H "Content-Type: application/json" \ + -d '{"id":1, "jsonrpc":"2.0", "method": "system_chain", "params":[]}' \ + http://localhost:9944 + ``` + - Get the latest block: + ```bash + curl -H "Content-Type: application/json" \ + -d '{"id":1, "jsonrpc":"2.0", "method": "chain_getHeader", "params":[]}' \ + http://localhost:9944 + ``` + - Query node health: + ```bash + curl -H "Content-Type: application/json" \ + -d '{"id":1, "jsonrpc":"2.0", "method": "system_health", "params":[]}' \ + http://localhost:9944 + ``` + +## Monitor and Maintain RPC Node + +There are a few key monitoring and maintenance commands that can help you ensure RPC node uptime and performance including log monitoring and metrics. + +To view node logs, use the appropriate command for your setup: + +=== "Docker Setup" + + ```bash + docker logs -f polkadot-hub-rpc + ``` + +=== "systemd Setup" + + - View node logs: + ```bash + sudo journalctl -u polkadot-hub-rpc -f + ``` + - View recent logs: + ```bash + sudo journalctl -u polkadot-hub-rpc -n 100 + ``` + - Filter for errors: + ```bash + sudo journalctl -u polkadot-hub-rpc | grep -i error + ``` + +Monitoring key metrics like the following items can help you stay up to date on the performance and health of your node and allow you to intervene at the first sign of issues: + +- **Sync status**: Ensure node stays fully synced. +- **Peer connections**: Maintain 30+ peers for good connectivity. +- **Resource usage**: Monitor CPU, RAM, and disk I/O. +- **RPC request latency**: Track response times for the Polkadot SDK API. +- **Connection count**: Monitor active RPC connections. + +You can use the following information to configure [Prometheus](https://prometheus.io/docs/introduction/first_steps/){target=\_blank} to monitor, collect, and store your collator node metrics: + +- **URL**: Metrics are available to view at `http://localhost:9615/metrics` +- **Example Prometheus configuration**: Update your `prometheus.yml` to add the following code: + ```yaml + scrape_configs: + - job_name: 'polkadot-hub-rpc' + static_configs: + - targets: ['localhost:9615'] + ``` + +Key metric to monitor via Prometheus include: + - `substrate_block_height`: Current block height + - `substrate_finalized_height`: Finalized block height + - `substrate_peers_count`: Number of connected peers + - `substrate_ready_transactions_number`: Transaction queue size -1. **Docker-based Setup**: Simpler to set up and maintain -2. **Manual/Systemd Setup**: For production environments requiring more control - -Choose the option that best fits your needs. - ---- - -## Option 1: Docker-Based Setup - -This option uses Docker containers for the Polkadot SDK node, making it easy to set up and manage. - -### Step 1: Download Chain Specification - -Download the official Polkadot Hub (formerly known as Asset Hub) chain specification: - -```bash -curl -L https://raw.githubusercontent.com/paritytech/polkadot-sdk/master/cumulus/parachains/chain-specs/asset-hub-polkadot.json -o asset-hub-polkadot.json -``` - -**Note**: This chain specification is the official configuration file that defines the network parameters for Polkadot Hub. - -### Step 2: Download Database Snapshots (Optional but Recommended) - -Using pre-synchronized snapshots significantly reduces initial sync time from several days to just a few hours. You need to download both parachain and relay chain data. - -**Snapshot Provider**: https://snapshots.polkadot.io/ - -#### Create Directories - -```bash -mkdir -p my-node-data/chains/asset-hub-polkadot/db -mkdir -p my-node-data/chains/polkadot/db -``` - -#### Download Polkadot Hub Parachain Snapshot - -Choose between archive (complete history) or pruned (recent state) snapshots: - -**Archive Snapshot** (recommended for RPC with historical data): - -```bash -# Check https://snapshots.polkadot.io/ for the latest snapshot URL -export SNAPSHOT_URL_ASSET_HUB="https://snapshots.polkadot.io/polkadot-asset-hub-rocksdb-archive/LATEST" - -rclone copyurl $SNAPSHOT_URL_ASSET_HUB/files.txt files.txt -rclone copy --progress --transfers 20 \ - --http-url $SNAPSHOT_URL_ASSET_HUB \ - --no-traverse --http-no-head --disable-http2 \ - --inplace --no-gzip-encoding --size-only \ - --retries 6 --retries-sleep 10s \ - --files-from files.txt :http: my-node-data/chains/asset-hub-polkadot/db/ - -rm files.txt -``` - -**Parameter Explanation**: - -- `--transfers 20`: Uses 20 parallel transfers for faster download -- `--retries 6`: Automatically retries failed transfers up to 6 times -- `--retries-sleep 10s`: Waits 10 seconds between retry attempts -- `--size-only`: Only transfers if sizes differ (prevents unnecessary re-downloads) - -#### Download Polkadot Relay Chain Snapshot - -**Pruned Snapshot** (recommended for RPC nodes): - -```bash -# Check https://snapshots.polkadot.io/ for the latest snapshot URL -export SNAPSHOT_URL_RELAY="https://snapshots.polkadot.io/polkadot-rocksdb-prune/LATEST" - -rclone copyurl $SNAPSHOT_URL_RELAY/files.txt files.txt -rclone copy --progress --transfers 20 \ - --http-url $SNAPSHOT_URL_RELAY \ - --no-traverse --http-no-head --disable-http2 \ - --inplace --no-gzip-encoding --size-only \ - --retries 6 --retries-sleep 10s \ - --files-from files.txt :http: my-node-data/chains/polkadot/db/ - -rm files.txt -``` - -**Alternative Options**: - -- Pruned snapshot: `polkadot-rocksdb-prune` (smaller size, recent state) -- Archive snapshot: `polkadot-rocksdb-archive` (complete history, larger size) - -### Step 3: Start Polkadot Hub Node - -Launch the node using the official Parity Docker image: - -**Docker Image**: https://hub.docker.com/r/parity/polkadot-omni-node - -```bash -docker run -d --name polkadot-hub-rpc --restart unless-stopped \ - -p 9944:9944 \ - -p 9933:9933 \ - -p 9615:9615 \ - -p 30334:30334 \ - -p 30333:30333 \ - -v $(pwd)/asset-hub-polkadot.json:/asset-hub-polkadot.json \ - -v $(pwd)/my-node-data:/data \ - parity/polkadot-omni-node:v1.20.2 \ - --name=PolkadotHubRPC \ - --base-path=/data \ - --chain=/asset-hub-polkadot.json \ - --prometheus-external \ - --prometheus-port 9615 \ - --unsafe-rpc-external \ - --rpc-port=9944 \ - --rpc-cors=all \ - --rpc-methods=safe \ - --rpc-max-connections=1000 \ - --state-pruning=archive \ - --blocks-pruning=archive \ - -- \ - --base-path=/data \ - --chain=polkadot \ - --state-pruning=256 \ - --blocks-pruning=archive-canonical -``` - -**Critical Configuration Parameters**: - -**Port Mappings**: - -- `9944`: Polkadot SDK RPC endpoint (WebSocket/HTTP) -- `9933`: Polkadot SDK HTTP RPC endpoint -- `9615`: Prometheus metrics endpoint -- `30333/30334`: P2P networking ports - -**Node Parameters**: - -- `--unsafe-rpc-external`: Enables external RPC access -- `--rpc-cors=all`: Allows all origins for CORS -- `--rpc-methods=safe`: Only allows safe RPC methods -- `--state-pruning=archive`: Keeps complete state history -- `--blocks-pruning=archive`: Keeps all block data -- `--prometheus-external`: Exposes metrics externally - -**Security Warning**: The `--unsafe-rpc-external` flag should only be used in development or properly secured environments. For production, use a reverse proxy with authentication. - -### Step 4: Monitor Synchronization - -Monitor the node synchronization status: - -```bash -# Check sync status -curl -H "Content-Type: application/json" \ - -d '{"id":1, "jsonrpc":"2.0", "method": "system_syncState", "params":[]}' \ - http://localhost:9944 -``` - -**Expected Response Format**: - -```json -{ - "jsonrpc":"2.0", - "id":1, - "result":{ - "startingBlock":0, - "currentBlock":3394816, - "highestBlock":3394816 - } -} -``` - -**Synchronization Status**: - -- **In Progress**: `currentBlock` < `highestBlock` -- **Complete**: `currentBlock` = `highestBlock` - -### Step 5: Verify Setup - -Let's verify the Polkadot SDK RPC endpoint is working correctly. - -#### API Endpoint - -**Polkadot SDK RPC (Port 9944)**: - -- WebSocket: `ws://your-server:9944` -- HTTP: `http://your-server:9944` -- Purpose: Full Polkadot SDK API access for parachain data -- Use Cases: Polkadot SDK applications, parachain-specific operations - -#### Polkadot SDK RPC Tests - -**Get Chain Information**: - -```bash -curl -H "Content-Type: application/json" \ - -d '{"id":1, "jsonrpc":"2.0", "method": "system_chain", "params":[]}' \ - http://localhost:9944 -``` - -**Get Latest Block**: - -```bash -curl -H "Content-Type: application/json" \ - -d '{"id":1, "jsonrpc":"2.0", "method": "chain_getHeader", "params":[]}' \ - http://localhost:9944 -``` - -**Get Node Health**: - -```bash -curl -H "Content-Type: application/json" \ - -d '{"id":1, "jsonrpc":"2.0", "method": "system_health", "params":[]}' \ - http://localhost:9944 -``` - -### Managing Docker Containers - -**View logs**: - -```bash -# View node logs -docker logs -f polkadot-hub-rpc -``` - -**Stop container**: - -```bash -docker stop polkadot-hub-rpc -``` - -**Start container**: - -```bash -docker start polkadot-hub-rpc -``` - -**Remove container**: - -```bash -docker rm polkadot-hub-rpc -``` - -**Note**: For update procedures, see the [Updates and Upgrades](#updates-and-upgrades) section. - ---- - -## Option 2: Manual/Systemd Setup - -This option provides more control and is recommended for production environments requiring custom configurations. - -### Step 1: Install Rust and Required Toolchain - -```bash -# Install Rust -curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -source $HOME/.cargo/env - -# Install specific Rust version -rustup install 1.91.1 -rustup default 1.91.1 -rustup target add wasm32-unknown-unknown --toolchain 1.91.1 -rustup component add rust-src --toolchain 1.91.1 -``` - -### Step 2: Install Required Dependencies - -```bash -# Install system dependencies -sudo apt update -sudo apt install -y build-essential git clang curl libssl-dev llvm libudev-dev make protobuf-compiler -``` - -### Step 3: Install the Polkadot Omni Node - -```bash -# Install polkadot-omni-node -cargo install --locked polkadot-omni-node@0.11.0 - -# Verify installation -polkadot-omni-node --version -``` - -**Note**: Compiling polkadot-omni-node from source requires significant RAM (minimum 24GB recommended). The compilation may take 10-15 minutes on systems with adequate resources. - -### Step 4: Obtain Chain Specification - -Download the Polkadot Hub chain specification: - -```bash -curl -L https://raw.githubusercontent.com/paritytech/polkadot-sdk/master/cumulus/parachains/chain-specs/asset-hub-polkadot.json -o asset-hub-polkadot.json -``` - -### Step 5: Create User and Directory Structure - -```bash -# Create dedicated user -sudo useradd -r -s /bin/bash polkadot - -# Create data directory -sudo mkdir -p /var/lib/polkadot-hub-rpc - -# Copy chain spec to the directory -sudo cp asset-hub-polkadot.json /var/lib/polkadot-hub-rpc/ - -# Set permissions -sudo chown -R polkadot:polkadot /var/lib/polkadot-hub-rpc -``` - -### Step 6: Create Systemd Service for Polkadot SDK Node - -Create a service file for the Polkadot SDK RPC node: - -```bash -sudo nano /etc/systemd/system/polkadot-hub-rpc.service -``` - -Add the following configuration: - -```ini -[Unit] -Description=Polkadot Hub RPC Node -After=network.target - -[Service] -Type=simple -User=polkadot -Group=polkadot -WorkingDirectory=/var/lib/polkadot-hub-rpc - -ExecStart=/usr/local/bin/polkadot-omni-node \ - --name=PolkadotHubRPC \ - --chain=/var/lib/polkadot-hub-rpc/asset-hub-polkadot.json \ - --base-path=/var/lib/polkadot-hub-rpc \ - --port=30333 \ - --rpc-port=9944 \ - --rpc-external \ - --rpc-cors=all \ - --rpc-methods=safe \ - --rpc-max-connections=1000 \ - --prometheus-port=9615 \ - --prometheus-external \ - --state-pruning=archive \ - --blocks-pruning=archive \ - -- \ - --chain=polkadot \ - --base-path=/var/lib/polkadot-hub-rpc \ - --port=30334 \ - --state-pruning=256 \ - --blocks-pruning=archive-canonical - -Restart=always -RestartSec=10 -LimitNOFILE=65536 - -[Install] -WantedBy=multi-user.target -``` - -### Step 7: Start Service - -```bash -# Reload systemd -sudo systemctl daemon-reload - -# Enable service to start on boot -sudo systemctl enable polkadot-hub-rpc - -# Start the Polkadot SDK node -sudo systemctl start polkadot-hub-rpc - -# Check status and wait for sync -sudo systemctl status polkadot-hub-rpc -sudo journalctl -u polkadot-hub-rpc -f -``` - -### Step 8: Verify Setup - -Use the same verification tests as in the Docker setup (see Step 5 above). - ---- - -## Monitoring and Maintenance - -### Log Management - -**Docker Setup**: - -```bash -# View node logs -docker logs -f polkadot-hub-rpc -``` - -**Systemd Setup**: - -```bash -# View node logs -sudo journalctl -u polkadot-hub-rpc -f - -# View recent logs -sudo journalctl -u polkadot-hub-rpc -n 100 - -# Filter for errors -sudo journalctl -u polkadot-hub-rpc | grep -i error -``` - -### Performance Monitoring - -Monitor key metrics: - -- **Sync status**: Ensure node stays fully synced -- **Peer connections**: Maintain 30+ peers for good connectivity -- **Resource usage**: Monitor CPU, RAM, and disk I/O -- **RPC request latency**: Track response times for the Polkadot SDK API -- **Connection count**: Monitor active RPC connections - -**Prometheus Metrics**: - -Metrics are available at `http://localhost:9615/metrics` - -Example Prometheus scrape configuration: - -```yaml -scrape_configs: - - job_name: 'polkadot-hub-rpc' - static_configs: - - targets: ['localhost:9615'] -``` - -**Key Metrics to Monitor**: +### Database Maintenance -- `substrate_block_height`: Current block height -- `substrate_finalized_height`: Finalized block height -- `substrate_peers_count`: Number of connected peers -- `substrate_ready_transactions_number`: Transaction queue size +Check database size periodically using the commands for your selected setup: -### Database Maintenance +=== "Docker Setup" -Check database size periodically: + ```bash + du -sh my-node-data + ``` -```bash -# Docker setup -du -sh my-node-data +=== "systemd Setup" -# Systemd setup -du -sh /var/lib/polkadot-hub-rpc -``` + ```bash + du -sh /var/lib/polkadot-hub-rpc + ``` The node handles pruning automatically based on configuration unless running in archive mode. ### Updates and Upgrades -**Docker Setup**: - -```bash -# Pull latest image -docker pull parity/polkadot-omni-node:v1.20.2 - -# Restart container -docker stop polkadot-hub-rpc -docker rm polkadot-hub-rpc - -# Start new container (use same command from setup) -``` - -**Systemd Setup**: - -```bash -# Stop service -sudo systemctl stop polkadot-hub-rpc - -# Backup data -sudo cp -r /var/lib/polkadot-hub-rpc /var/lib/polkadot-hub-rpc.backup - -# Update binary -cargo install --locked --force polkadot-omni-node@ - -# Restart service -sudo systemctl start polkadot-hub-rpc -``` +Use the following commands for updating or upgrading your RPC node according to your setup: + +=== "Docker Setup" + + 1. Pull the latest image: + ```bash + docker pull parity/polkadot-omni-node:v1.20.2 + ``` + 2. Restart the container: + ```bash + docker stop polkadot-hub-rpc + docker rm polkadot-hub-rpc + ``` + +=== "systemd Setup" + + 1. Stop the service: + ```bash + sudo systemctl stop polkadot-hub-rpc + ``` + 2. Backup data: + ```bash + sudo cp -r /var/lib/polkadot-hub-rpc /var/lib/polkadot-hub-rpc.backup + ``` + 3. Update the binary: + ```bash + cargo install --locked --force polkadot-omni-node@ + ``` + 4. Restart the service: + ```bash + sudo systemctl start polkadot-hub-rpc + ``` ## Conclusion Running an RPC node for Polkadot Hub provides essential infrastructure for applications and users to interact with the network. By following this guide, you have set up a production-ready RPC node that: -- Provides reliable access to Polkadot Hub's asset management, governance, and cross-chain communication features -- Supports both Docker and systemd deployment options for flexibility -- Implements proper monitoring, security, and maintenance practices -- Serves as a foundation for building and operating Polkadot SDK applications +- Provides reliable access to Polkadot Hub's asset management, governance, and cross-chain communication features. +- Supports both Docker and systemd deployment options for flexibility. +- Implements proper monitoring, security, and maintenance practices. +- Serves as a foundation for building and operating Polkadot SDK applications. Regular maintenance, security updates, and monitoring will ensure your RPC node continues to serve your users reliably. As the Polkadot network evolves, stay informed about updates and best practices through the official channels and community resources listed in this guide. From 3b791ace30a33bb0c469f1263aeb182b41f271a3 Mon Sep 17 00:00:00 2001 From: DAWN KELLY Date: Fri, 21 Nov 2025 16:00:44 -0500 Subject: [PATCH 10/39] formatting edits --- node-infrastructure/run-a-node/polkadot-hub-rpc.md | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/node-infrastructure/run-a-node/polkadot-hub-rpc.md b/node-infrastructure/run-a-node/polkadot-hub-rpc.md index 247651263..7af6e5ddc 100644 --- a/node-infrastructure/run-a-node/polkadot-hub-rpc.md +++ b/node-infrastructure/run-a-node/polkadot-hub-rpc.md @@ -247,7 +247,7 @@ Select the best option for your project, then use the steps in the following tab ``` === "Manual systemd Setup" - This option provides more control and is recommended for production environments requiring custom configurations. + This option uses systemd to provide more control and is recommended for production environments requiring custom configurations. 1. Install Rust and required toolchain using the following command: ```bash @@ -435,11 +435,12 @@ You can use the following information to configure [Prometheus](https://promethe - targets: ['localhost:9615'] ``` -Key metric to monitor via Prometheus include: - - `substrate_block_height`: Current block height - - `substrate_finalized_height`: Finalized block height - - `substrate_peers_count`: Number of connected peers - - `substrate_ready_transactions_number`: Transaction queue size +Key metrics to monitor via Prometheus include: + +- `substrate_block_height`: Current block height +- `substrate_finalized_height`: Finalized block height +- `substrate_peers_count`: Number of connected peers +- `substrate_ready_transactions_number`: Transaction queue size ### Database Maintenance From b84d71de716ce49299d8fafdf3c9155f08f4855c Mon Sep 17 00:00:00 2001 From: Bruno Galvao Date: Mon, 24 Nov 2025 16:24:55 +0700 Subject: [PATCH 11/39] Update guides --- .ai/pages/node-infrastructure-overview.md | 81 +++++++++ ...-infrastructure-run-a-collator-collator.md | 169 ++++++++++++++---- ...infrastructure-run-a-node-parachain-rpc.md | 158 ++++++++-------- ...rastructure-run-a-node-polkadot-hub-rpc.md | 65 +++---- node-infrastructure/.nav.yml | 1 + node-infrastructure/overview.md | 80 +++++++++ .../run-a-collator/collator.md | 169 ++++++++++++++---- node-infrastructure/run-a-node/.nav.yml | 2 +- .../run-a-node/parachain-rpc.md | 158 ++++++++-------- .../run-a-node/polkadot-hub-rpc.md | 65 +++---- 10 files changed, 640 insertions(+), 308 deletions(-) create mode 100644 .ai/pages/node-infrastructure-overview.md rename node-infrastructure/run-a-node/system-parachain-rpc.md => .ai/pages/node-infrastructure-run-a-node-parachain-rpc.md (70%) create mode 100644 node-infrastructure/overview.md rename .ai/pages/node-infrastructure-run-a-node-system-parachain-rpc.md => node-infrastructure/run-a-node/parachain-rpc.md (71%) diff --git a/.ai/pages/node-infrastructure-overview.md b/.ai/pages/node-infrastructure-overview.md new file mode 100644 index 000000000..fe7e4f507 --- /dev/null +++ b/.ai/pages/node-infrastructure-overview.md @@ -0,0 +1,81 @@ +--- +title: Node Infrastructure +description: Overview of running nodes in the Polkadot ecosystem, including RPC nodes, collators, and validators. +categories: Infrastructure +url: https://docs.polkadot.com/node-infrastructure/overview/ +--- + +# Node Infrastructure Overview + +## Introduction + +The Polkadot network relies on various types of nodes to maintain security, provide data access, and produce blocks. This section covers everything you need to know about running infrastructure for the Polkadot ecosystem. + +Whether you want to provide RPC endpoints for applications, produce blocks for a parachain, or secure the relay chain as a validator, this guide will help you understand your options and get started. + +## Node Types + +### RPC Nodes + +RPC nodes provide API access to blockchain data without participating in consensus. They are essential infrastructure for: + +- **Applications and dApps**: Query blockchain state and submit transactions +- **Block explorers**: Index and display blockchain data +- **Wallets**: Check balances and broadcast transactions +- **Development**: Test and debug applications + +RPC nodes can be run for both the relay chain and parachains, with varying levels of data retention (pruned vs archive). + +### Collators + +Collators are block producers for parachains. They perform critical functions: + +- **Collect transactions**: Aggregate user transactions into blocks +- **Produce blocks**: Create parachain block candidates +- **Generate proofs**: Produce state transition proofs (Proof-of-Validity) +- **Submit to validators**: Send block candidates to relay chain validators + +Unlike validators, collators do not provide security guarantees—that responsibility lies with relay chain validators. However, collators are essential for parachain liveness and censorship resistance. + +### Validators + +Validators secure the Polkadot relay chain through Nominated Proof of Stake (NPoS). They: + +- **Validate blocks**: Verify parachain blocks and relay chain transactions +- **Participate in consensus**: Run BABE and GRANDPA protocols +- **Earn rewards**: Receive staking rewards for honest behavior +- **Risk slashing**: Face penalties for misbehavior or downtime + +Running a validator requires significant technical expertise, reliable infrastructure, and a stake of DOT tokens. + +## Next Steps + +Choose your path based on your goals: + +
+ +- :material-api:{ .lg .middle } **Run RPC Nodes** + + --- + + Provide API access for applications, explorers, and wallets + + [:octicons-arrow-right-24: Run a Node](/node-infrastructure/run-a-node/parachain-rpc/) + +- :material-cube-outline:{ .lg .middle } **Run a Collator** + + --- + + Produce blocks for system parachains or your own parachain + + [:octicons-arrow-right-24: Run a Collator](/node-infrastructure/run-a-collator/collator/) + +- :material-shield-check:{ .lg .middle } **Run a Validator** + + --- + + Secure the relay chain and earn staking rewards + + [:octicons-arrow-right-24: Run a Validator](/node-infrastructure/run-a-validator/requirements/) + +
diff --git a/.ai/pages/node-infrastructure-run-a-collator-collator.md b/.ai/pages/node-infrastructure-run-a-collator-collator.md index cb2adbf48..e1bed1380 100644 --- a/.ai/pages/node-infrastructure-run-a-collator-collator.md +++ b/.ai/pages/node-infrastructure-run-a-collator-collator.md @@ -57,18 +57,12 @@ Block-producing collators require robust hardware for reliable operation: ### Software Requirements -Collators use the **Polkadot Omni Node**, a universal binary that runs any parachain using a chain specification file. +Collators use the **Polkadot Parachain** binary, the standard client for running Polkadot system parachains. Required software: - **Operating System**: Ubuntu 22.04 LTS (recommended) or similar Linux distribution -- **Docker**: For running subkey utility -- **Rust Toolchain**: Version 1.91.1 or as specified by the runtime -- **Dependencies**: - ```bash - sudo apt update - sudo apt install -y build-essential git clang curl libssl-dev llvm libudev-dev make protobuf-compiler - ``` +- **Docker**: Required for obtaining binaries and running containers ### Account Requirements @@ -80,54 +74,81 @@ You'll need: ## Installation -### Step 1: Install Rust and Required Toolchain +### Step 1: Install the Polkadot Parachain Binary + +**For Docker deployment:** ```bash -# Install Rust -curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -source $HOME/.cargo/env - -# Install specific Rust version -rustup install 1.91.1 -rustup default 1.91.1 -rustup target add wasm32-unknown-unknown --toolchain 1.91.1 -rustup component add rust-src --toolchain 1.91.1 +# Pull the polkadot-parachain image +docker pull parity/polkadot-parachain:stable2509-2 + +# Verify installation +docker run --rm parity/polkadot-parachain:stable2509-2 --version ``` -### Step 2: Install the Polkadot Omni Node +**For bare-metal deployment:** + +Extract the binary from the Docker image: ```bash -# Install polkadot-omni-node -cargo install --locked polkadot-omni-node@0.11.0 +# Create a temporary container and copy the binary +docker create --name temp-parachain parity/polkadot-parachain:stable2509-2 +sudo docker cp temp-parachain:/usr/local/bin/polkadot-parachain /usr/local/bin/ +docker rm temp-parachain # Verify installation -polkadot-omni-node --version +polkadot-parachain --version ``` -### Step 3: Generate Node Key +Check [Docker Hub](https://hub.docker.com/r/parity/polkadot-parachain/tags) for the latest stable tags. + +### Step 2: Generate Node Key Generate a stable node key for consistent peer ID: ```bash # Create directory for node data sudo mkdir -p /var/lib/polkadot-collator +``` + +**Using Docker:** -# Generate node key using Docker -docker run -it parity/subkey:latest generate-node-key > /var/lib/polkadot-collator/node.key +```bash +# Generate node key (outputs peer ID to console, saves key to file) +docker run --rm -v /var/lib/polkadot-collator:/data \ + parity/polkadot-parachain:stable2509-2 \ + key generate-node-key --file /data/node.key -# The output displays your peer ID -# Example: 12D3KooWExcVYu7Mvjd4kxPVLwN2ZPnZ5NyLZ5ft477wqzfP2q6E +# Example output: 12D3KooWExcVYu7Mvjd4kxPVLwN2ZPnZ5NyLZ5ft477wqzfP2q6E +``` + +**Using native binary:** + +```bash +# Generate node key +polkadot-parachain key generate-node-key --file /var/lib/polkadot-collator/node.key + +# Example output: 12D3KooWExcVYu7Mvjd4kxPVLwN2ZPnZ5NyLZ5ft477wqzfP2q6E ``` Save the peer ID for future reference. -### Step 4: Generate Account Key +### Step 3: Generate Account Key Generate an account for on-chain transactions: +**Using Docker:** + +```bash +# Generate account key with sr25519 scheme +docker run --rm parity/polkadot-parachain:stable2509-2 key generate --scheme sr25519 +``` + +**Using native binary:** + ```bash # Generate account key with sr25519 scheme -docker run -it parity/subkey:latest generate --scheme sr25519 +polkadot-parachain key generate --scheme sr25519 ``` Save the output containing: @@ -139,7 +160,7 @@ Save the output containing: **Security**: Store the secret phrase securely. Never share it. Consider using a hardware wallet for production collators. -### Step 5: Obtain Chain Specification +### Step 4: Obtain Chain Specification Download the chain specification for your target system parachain: @@ -178,7 +199,7 @@ chain-spec-builder create \ - People Chain: 1004 - Coretime Chain: 1005 -### Step 6: Create User and Directory Structure +### Step 5: Create User and Directory Structure ```bash # Create dedicated user @@ -193,7 +214,7 @@ sudo chown -R polkadot:polkadot /var/lib/polkadot-collator ## Configuration -### Create Systemd Service File +### Native Binary Systemd Service Create a service file for your collator: @@ -215,7 +236,7 @@ Group=polkadot WorkingDirectory=/var/lib/polkadot-collator # Block-Producing Collator Configuration -ExecStart=/usr/local/bin/polkadot-omni-node \ +ExecStart=/usr/local/bin/polkadot-parachain \ --collator \ --chain=/var/lib/polkadot-collator/chain-spec.json \ --base-path=/var/lib/polkadot-collator \ @@ -245,6 +266,55 @@ WantedBy=multi-user.target - `--name`: Your collator name (visible in telemetry) - Relay chain uses `--sync=warp` for faster initial sync +### Docker Systemd Service + +If using Docker, create a service file with Docker configuration: + +```bash +sudo nano /etc/systemd/system/polkadot-collator.service +``` + +Add the following configuration: + +```ini +[Unit] +Description=Polkadot System Parachain Collator (Docker) +After=network.target docker.service +Requires=docker.service + +[Service] +Type=simple +Restart=always +RestartSec=10 +TimeoutStartSec=0 + +ExecStartPre=-/usr/bin/docker stop polkadot-collator +ExecStartPre=-/usr/bin/docker rm polkadot-collator + +ExecStart=/usr/bin/docker run --rm \ + --name polkadot-collator \ + --network host \ + -v /var/lib/polkadot-collator:/data \ + parity/polkadot-parachain:stable2509-2 \ + --collator \ + --chain=/data/chain-spec.json \ + --base-path=/data \ + --port=30333 \ + --rpc-port=9944 \ + --prometheus-port=9615 \ + --node-key-file=/data/node.key \ + --name="YourCollatorName" \ + -- \ + --chain=polkadot \ + --port=30334 \ + --sync=warp + +ExecStop=/usr/bin/docker stop polkadot-collator + +[Install] +WantedBy=multi-user.target +``` + ## Running the Collator ### Step 1: Start the Service @@ -491,7 +561,7 @@ The node handles pruning automatically. - Fellowship GitHub - Matrix channels -**Upgrade Procedure**: +**Upgrade Procedure (Bare-Metal)**: ```bash # Stop the service @@ -500,11 +570,14 @@ sudo systemctl stop polkadot-collator # Backup data (recommended) sudo cp -r /var/lib/polkadot-collator /var/lib/polkadot-collator.backup -# Update polkadot-omni-node -cargo install --locked --force polkadot-omni-node@ +# Pull new image and extract binary +docker pull parity/polkadot-parachain: +docker create --name temp-parachain parity/polkadot-parachain: +sudo docker cp temp-parachain:/usr/local/bin/polkadot-parachain /usr/local/bin/ +docker rm temp-parachain # Verify version -polkadot-omni-node --version +polkadot-parachain --version # Restart service sudo systemctl start polkadot-collator @@ -513,6 +586,28 @@ sudo systemctl start polkadot-collator sudo systemctl status polkadot-collator ``` +**Upgrade Procedure (Docker)**: + +```bash +# Stop the service +sudo systemctl stop polkadot-collator + +# Backup data (recommended) +sudo cp -r /var/lib/polkadot-collator /var/lib/polkadot-collator.backup + +# Pull new image +docker pull parity/polkadot-parachain: + +# Update the image tag in /etc/systemd/system/polkadot-collator.service + +# Reload systemd and restart +sudo systemctl daemon-reload +sudo systemctl start polkadot-collator + +# Verify service is running +sudo systemctl status polkadot-collator +``` + **Note**: For log monitoring, see the [Log Management](#log-management) section. ## Conclusion diff --git a/node-infrastructure/run-a-node/system-parachain-rpc.md b/.ai/pages/node-infrastructure-run-a-node-parachain-rpc.md similarity index 70% rename from node-infrastructure/run-a-node/system-parachain-rpc.md rename to .ai/pages/node-infrastructure-run-a-node-parachain-rpc.md index 47440b93c..e38c1a1fd 100644 --- a/node-infrastructure/run-a-node/system-parachain-rpc.md +++ b/.ai/pages/node-infrastructure-run-a-node-parachain-rpc.md @@ -1,37 +1,60 @@ --- -title: Run an RPC Node for System Parachains -description: Complete guide to set up and run an RPC node for Polkadot system parachains including Bridge Hub, People Chain, and Coretime Chain. +title: Run a Parachain RPC Node +description: Complete guide to set up and run an RPC node for any Polkadot parachain, with system parachains as examples. categories: Infrastructure +url: https://docs.polkadot.com/node-infrastructure/run-a-node/parachain-rpc/ --- -# Run an RPC Node for System Parachains +# Run a Parachain RPC Node ## Overview -System parachains are core infrastructure parachains that provide essential services to the Polkadot network. Running an RPC node for these parachains enables applications, wallets, and users to interact with their specialized functionality: +Running an RPC node for a parachain enables applications, wallets, and users to interact with the parachain's functionality. This guide applies to **any parachain** in the Polkadot ecosystem, including: -- **Bridge Hub**: Cross-chain asset transfers via trustless bridges -- **People Chain**: Identity and social credential management -- **Coretime Chain**: Blockspace allocation and core time management +- **System parachains**: Bridge Hub, People Chain, Coretime Chain +- **Common good parachains**: Collectives, Encointer +- **Commercial parachains**: Any parachain with a publicly available chain specification -Each system parachain RPC node provides access through: -- **Polkadot SDK Node RPC** (Port 9944): Native Polkadot API (WebSocket and HTTP) - -This setup enables block explorer indexing and provides full compatibility with Polkadot SDK development tools. +Each parachain RPC node provides access through the Polkadot SDK Node RPC (Port 9944), offering native Polkadot API access via WebSocket and HTTP. This setup enables block explorer indexing and provides full compatibility with Polkadot SDK development tools. **Important Note**: The parameters and configurations in this guide are provided as illustrative examples. You may need to modify them according to your specific environment, hardware capabilities, and network conditions. -## Choosing a System Parachain +## Obtaining a Chain Specification + +To run an RPC node for any parachain, you need its **chain specification file**. This JSON file defines the network parameters, genesis state, and bootnodes. + +### System Parachains + +System parachain chain specs are available from multiple sources: -This guide uses **People Chain** as the example, but the same principles and setup procedures apply to all system parachains. Simply substitute the appropriate values from the table below for your chosen parachain: +**Option 1: Chainspec Collection (Recommended)** -| Parachain | Para ID | Chain Spec File | Snapshot Path | Chain Name | -|-----------|---------|-----------------|---------------|------------| -| **Bridge Hub** | 1002 | `bridge-hub-polkadot.json` | `polkadot-bridge-hub-rocksdb-archive` | `bridge-hub-polkadot` | -| **People Chain** | 1004 | `people-polkadot.json` | `polkadot-people-rocksdb-archive` | `people-polkadot` | -| **Coretime Chain** | 1005 | `coretime-polkadot.json` | `polkadot-coretime-rocksdb-archive` | `coretime-polkadot` | +Visit the [Chainspec Collection](https://paritytech.github.io/chainspecs/) to download official chain specifications. -**Note**: Throughout this guide, we use People Chain values. To set up a different system parachain, replace the chain spec file, snapshot path, and chain name with the corresponding values from the table above. +**Option 2: Polkadot SDK Repository** + +Download directly from the Polkadot SDK repository: + +```bash +# Example for People Chain +curl -L https://raw.githubusercontent.com/paritytech/polkadot-sdk/master/cumulus/parachains/chain-specs/people-polkadot.json -o chain-spec.json +``` + +| System Parachain | Para ID | Chain Spec File | Snapshot Path | +|------------------|---------|-----------------|---------------| +| **Bridge Hub** | 1002 | `bridge-hub-polkadot.json` | `polkadot-bridge-hub-rocksdb-archive` | +| **People Chain** | 1004 | `people-polkadot.json` | `polkadot-people-rocksdb-archive` | +| **Coretime Chain** | 1005 | `coretime-polkadot.json` | `polkadot-coretime-rocksdb-archive` | + +### Other Parachains + +For non-system parachains: + +- **Check the parachain's documentation** for official chain specification files +- **Contact the parachain team** if no public chain spec is available +- **Export from a running node** using `system_chainSpec` RPC method if you have access to an existing node + +**Note**: Throughout this guide, we use **People Chain** as the example. To set up a different parachain, substitute the chain spec file, snapshot path, and chain name with values for your target parachain. ## Prerequisites @@ -64,9 +87,8 @@ RPC nodes serving production traffic require robust hardware: Required software: - **Operating System**: Ubuntu 22.04 LTS (recommended) or similar Linux distribution -- **Docker**: Latest version installed and running (for Docker-based setup) +- **Docker**: Required for obtaining binaries and running containers - **rclone**: (Optional but recommended) Command-line program for managing files on cloud storage (https://rclone.org/downloads/) -- **Rust Toolchain**: Version 1.91.1 or as specified by runtime (for manual build) ## Setup Options @@ -83,22 +105,14 @@ Choose the option that best fits your needs. This option uses Docker containers for the Polkadot SDK node, making it easy to set up and manage. -### Step 1: Download Chain Specification - -Download the official chain specification for People Chain: - -```bash -curl -L https://raw.githubusercontent.com/paritytech/polkadot-sdk/master/cumulus/parachains/chain-specs/people-polkadot.json -o people-polkadot.json -``` - -**Note**: This chain specification is the official configuration file that defines the network parameters for People Chain. - -### Step 2: Download Database Snapshots (Optional but Recommended) +### Step 1: Download Database Snapshots (Optional but Recommended) Using pre-synchronized snapshots significantly reduces initial sync time from several days to just a few hours. You need to download both parachain and relay chain data. **Snapshot Provider**: https://snapshots.polkadot.io/ +**Note**: Snapshots are available for system parachains and the Polkadot relay chain. For other parachains, check with the parachain team for snapshot availability or sync from genesis. + #### Create Directories ```bash @@ -160,11 +174,13 @@ rm files.txt - Pruned snapshot: `polkadot-rocksdb-prune` (smaller size, recent state) - Archive snapshot: `polkadot-rocksdb-archive` (complete history, larger size) -### Step 3: Start People Chain Node +### Step 2: Start the Parachain Node Launch the node using the official Parity Docker image. -**Docker Image**: https://hub.docker.com/r/parity/polkadot-omni-node +**Docker Image**: https://hub.docker.com/r/parity/polkadot-parachain + +**Note**: The `parity/polkadot-parachain` image works for system parachains and parachains built with standard Cumulus templates. For parachains with custom runtimes, check the parachain's documentation for their specific Docker image or binary. ```bash docker run -d --name people-chain-rpc --restart unless-stopped \ @@ -175,7 +191,7 @@ docker run -d --name people-chain-rpc --restart unless-stopped \ -p 30333:30333 \ -v $(pwd)/people-polkadot.json:/people-polkadot.json \ -v $(pwd)/my-node-data:/data \ - parity/polkadot-omni-node:v1.20.2 \ + parity/polkadot-parachain:stable2509-2 \ --name=PeopleChainRPC \ --base-path=/data \ --chain=/people-polkadot.json \ @@ -215,7 +231,7 @@ docker run -d --name people-chain-rpc --restart unless-stopped \ **Security Warning**: The `--unsafe-rpc-external` flag should only be used in development or properly secured environments. For production, use a reverse proxy with authentication. -### Step 4: Monitor Synchronization +### Step 3: Monitor Synchronization Monitor the node synchronization status: @@ -245,7 +261,7 @@ curl -H "Content-Type: application/json" \ - **In Progress**: `currentBlock` < `highestBlock` - **Complete**: `currentBlock` = `highestBlock` -### Step 5: Verify Setup +### Step 4: Verify Setup Let's verify the Polkadot SDK RPC endpoint is working correctly. @@ -335,39 +351,26 @@ docker rm people-chain-rpc This option provides more control and is recommended for production environments requiring custom configurations. -### Step 1: Install Rust and Required Toolchain +### Step 1: Install the Polkadot Parachain Binary -```bash -# Install Rust -curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -source $HOME/.cargo/env - -# Install specific Rust version -rustup install 1.91.1 -rustup default 1.91.1 -rustup target add wasm32-unknown-unknown --toolchain 1.91.1 -rustup component add rust-src --toolchain 1.91.1 -``` - -### Step 2: Install the Polkadot Omni Node +Extract the binary from the official Docker image: ```bash -# Install polkadot-omni-node -cargo install --locked polkadot-omni-node@0.11.0 +# Pull the image and extract binary +docker pull parity/polkadot-parachain:stable2509-2 +docker create --name temp-parachain parity/polkadot-parachain:stable2509-2 +sudo docker cp temp-parachain:/usr/local/bin/polkadot-parachain /usr/local/bin/ +docker rm temp-parachain # Verify installation -polkadot-omni-node --version +polkadot-parachain --version ``` -### Step 3: Obtain Chain Specification +Check [Docker Hub](https://hub.docker.com/r/parity/polkadot-parachain/tags) for the latest stable tags. -Download the People Chain specification: +### Step 2: Create User and Directory Structure -```bash -curl -L https://raw.githubusercontent.com/paritytech/polkadot-sdk/master/cumulus/parachains/chain-specs/people-polkadot.json -o people-polkadot.json -``` - -### Step 4: Create User and Directory Structure +Ensure you have downloaded your parachain's chain specification as described in [Obtaining a Chain Specification](#obtaining-a-chain-specification). ```bash # Create dedicated user (skip if already exists) @@ -383,9 +386,9 @@ sudo cp people-polkadot.json /var/lib/people-chain-rpc/ sudo chown -R polkadot:polkadot /var/lib/people-chain-rpc ``` -### Step 5: Create Systemd Service +### Step 3: Create Systemd Service -Create a service file for the People Chain RPC node: +Create a service file for your parachain RPC node: ```bash sudo nano /etc/systemd/system/people-chain-rpc.service @@ -404,7 +407,7 @@ User=polkadot Group=polkadot WorkingDirectory=/var/lib/people-chain-rpc -ExecStart=/usr/local/bin/polkadot-omni-node \ +ExecStart=/usr/local/bin/polkadot-parachain \ --name=PeopleChainRPC \ --chain=/var/lib/people-chain-rpc/people-polkadot.json \ --base-path=/var/lib/people-chain-rpc \ @@ -433,7 +436,7 @@ LimitNOFILE=65536 WantedBy=multi-user.target ``` -### Step 6: Start Service +### Step 4: Start Service ```bash # Reload systemd @@ -450,9 +453,9 @@ sudo systemctl status people-chain-rpc sudo journalctl -u people-chain-rpc -f ``` -### Step 7: Verify Setup +### Step 5: Verify Setup -Use the same verification tests as in the Docker setup (see Step 5 above). +Use the same verification tests as in the Docker setup (see Step 4 above). --- @@ -496,12 +499,14 @@ Metrics are available at `http://localhost:9615/metrics` Example Prometheus scrape configuration: +{% raw %} ```yaml scrape_configs: - job_name: 'people-chain-rpc' static_configs: - targets: ['localhost:9615'] ``` +{% endraw %} **Key Metrics to Monitor**: @@ -530,13 +535,13 @@ The node handles pruning automatically based on configuration unless running in ```bash # Pull latest image -docker pull parity/polkadot-omni-node:v1.20.2 +docker pull parity/polkadot-parachain: # Restart container docker stop people-chain-rpc docker rm people-chain-rpc -# Start new container (use same command from setup) +# Start new container (use same command from setup with updated image tag) ``` **Systemd Setup**: @@ -548,8 +553,11 @@ sudo systemctl stop people-chain-rpc # Backup data sudo cp -r /var/lib/people-chain-rpc /var/lib/people-chain-rpc.backup -# Update binary -cargo install --locked --force polkadot-omni-node@ +# Pull new image and extract binary +docker pull parity/polkadot-parachain: +docker create --name temp-parachain parity/polkadot-parachain: +sudo docker cp temp-parachain:/usr/local/bin/polkadot-parachain /usr/local/bin/ +docker rm temp-parachain # Restart service sudo systemctl start people-chain-rpc @@ -557,11 +565,11 @@ sudo systemctl start people-chain-rpc ## Conclusion -Running an RPC node for system parachains provides critical infrastructure for accessing specialized Polkadot network services. By following this guide, you have set up a production-ready RPC node that: +Running a parachain RPC node provides critical infrastructure for accessing Polkadot network services. By following this guide, you have set up a production-ready RPC node that: -- Enables applications and users to interact with essential system parachain features (identity management, cross-chain bridges, or coretime allocation) +- Provides reliable access to parachain functionality for applications and users - Supports flexible deployment with both Docker and systemd options - Implements comprehensive monitoring, security, and maintenance practices -- Can be easily adapted for any system parachain by substituting the appropriate chain specification +- Can be adapted for any parachain by substituting the appropriate chain specification -Whether you're running a node for People Chain, Bridge Hub, or Coretime Chain, regular maintenance and monitoring will ensure your RPC node continues to provide reliable service. Stay updated with the latest releases and best practices to keep your infrastructure secure and performant. +Whether you're running a node for system parachains (People Chain, Bridge Hub, Coretime Chain) or other parachains in the ecosystem, regular maintenance and monitoring will ensure your RPC node continues to provide reliable service. Stay updated with the latest releases and best practices to keep your infrastructure secure and performant. diff --git a/.ai/pages/node-infrastructure-run-a-node-polkadot-hub-rpc.md b/.ai/pages/node-infrastructure-run-a-node-polkadot-hub-rpc.md index 80f5ce475..7a8368545 100644 --- a/.ai/pages/node-infrastructure-run-a-node-polkadot-hub-rpc.md +++ b/.ai/pages/node-infrastructure-run-a-node-polkadot-hub-rpc.md @@ -53,9 +53,8 @@ RPC nodes serving production traffic require robust hardware: Required software: - **Operating System**: Ubuntu 22.04 LTS (recommended) or similar Linux distribution -- **Docker**: Latest version installed and running (for Docker-based setup) +- **Docker**: Required for obtaining binaries and running containers - **rclone**: (Optional but recommended) Command-line program for managing files on cloud storage (https://rclone.org/downloads/) -- **Rust Toolchain**: Version 1.91.1 or later (for manual build) ## Setup Options @@ -151,7 +150,7 @@ rm files.txt Launch the node using the official Parity Docker image: -**Docker Image**: https://hub.docker.com/r/parity/polkadot-omni-node +**Docker Image**: https://hub.docker.com/r/parity/polkadot-parachain ```bash docker run -d --name polkadot-hub-rpc --restart unless-stopped \ @@ -162,7 +161,7 @@ docker run -d --name polkadot-hub-rpc --restart unless-stopped \ -p 30333:30333 \ -v $(pwd)/asset-hub-polkadot.json:/asset-hub-polkadot.json \ -v $(pwd)/my-node-data:/data \ - parity/polkadot-omni-node:v1.20.2 \ + parity/polkadot-parachain:stable2509-2 \ --name=PolkadotHubRPC \ --base-path=/data \ --chain=/asset-hub-polkadot.json \ @@ -306,41 +305,24 @@ docker rm polkadot-hub-rpc This option provides more control and is recommended for production environments requiring custom configurations. -### Step 1: Install Rust and Required Toolchain +### Step 1: Install the Polkadot Parachain Binary -```bash -# Install Rust -curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -source $HOME/.cargo/env - -# Install specific Rust version -rustup install 1.91.1 -rustup default 1.91.1 -rustup target add wasm32-unknown-unknown --toolchain 1.91.1 -rustup component add rust-src --toolchain 1.91.1 -``` - -### Step 2: Install Required Dependencies - -```bash -# Install system dependencies -sudo apt update -sudo apt install -y build-essential git clang curl libssl-dev llvm libudev-dev make protobuf-compiler -``` - -### Step 3: Install the Polkadot Omni Node +Extract the binary from the official Docker image: ```bash -# Install polkadot-omni-node -cargo install --locked polkadot-omni-node@0.11.0 +# Pull the image and extract binary +docker pull parity/polkadot-parachain:stable2509-2 +docker create --name temp-parachain parity/polkadot-parachain:stable2509-2 +sudo docker cp temp-parachain:/usr/local/bin/polkadot-parachain /usr/local/bin/ +docker rm temp-parachain # Verify installation -polkadot-omni-node --version +polkadot-parachain --version ``` -**Note**: Compiling polkadot-omni-node from source requires significant RAM (minimum 24GB recommended). The compilation may take 10-15 minutes on systems with adequate resources. +Check [Docker Hub](https://hub.docker.com/r/parity/polkadot-parachain/tags) for the latest stable tags. -### Step 4: Obtain Chain Specification +### Step 2: Obtain Chain Specification Download the Polkadot Hub chain specification: @@ -348,7 +330,7 @@ Download the Polkadot Hub chain specification: curl -L https://raw.githubusercontent.com/paritytech/polkadot-sdk/master/cumulus/parachains/chain-specs/asset-hub-polkadot.json -o asset-hub-polkadot.json ``` -### Step 5: Create User and Directory Structure +### Step 3: Create User and Directory Structure ```bash # Create dedicated user @@ -364,7 +346,7 @@ sudo cp asset-hub-polkadot.json /var/lib/polkadot-hub-rpc/ sudo chown -R polkadot:polkadot /var/lib/polkadot-hub-rpc ``` -### Step 6: Create Systemd Service for Polkadot SDK Node +### Step 4: Create Systemd Service Create a service file for the Polkadot SDK RPC node: @@ -385,7 +367,7 @@ User=polkadot Group=polkadot WorkingDirectory=/var/lib/polkadot-hub-rpc -ExecStart=/usr/local/bin/polkadot-omni-node \ +ExecStart=/usr/local/bin/polkadot-parachain \ --name=PolkadotHubRPC \ --chain=/var/lib/polkadot-hub-rpc/asset-hub-polkadot.json \ --base-path=/var/lib/polkadot-hub-rpc \ @@ -414,7 +396,7 @@ LimitNOFILE=65536 WantedBy=multi-user.target ``` -### Step 7: Start Service +### Step 5: Start Service ```bash # Reload systemd @@ -431,7 +413,7 @@ sudo systemctl status polkadot-hub-rpc sudo journalctl -u polkadot-hub-rpc -f ``` -### Step 8: Verify Setup +### Step 6: Verify Setup Use the same verification tests as in the Docker setup (see Step 5 above). @@ -513,13 +495,13 @@ The node handles pruning automatically based on configuration unless running in ```bash # Pull latest image -docker pull parity/polkadot-omni-node:v1.20.2 +docker pull parity/polkadot-parachain: # Restart container docker stop polkadot-hub-rpc docker rm polkadot-hub-rpc -# Start new container (use same command from setup) +# Start new container (use same command from setup with updated image tag) ``` **Systemd Setup**: @@ -531,8 +513,11 @@ sudo systemctl stop polkadot-hub-rpc # Backup data sudo cp -r /var/lib/polkadot-hub-rpc /var/lib/polkadot-hub-rpc.backup -# Update binary -cargo install --locked --force polkadot-omni-node@ +# Pull new image and extract binary +docker pull parity/polkadot-parachain: +docker create --name temp-parachain parity/polkadot-parachain: +sudo docker cp temp-parachain:/usr/local/bin/polkadot-parachain /usr/local/bin/ +docker rm temp-parachain # Restart service sudo systemctl start polkadot-hub-rpc diff --git a/node-infrastructure/.nav.yml b/node-infrastructure/.nav.yml index a14f33cae..d907a96bb 100644 --- a/node-infrastructure/.nav.yml +++ b/node-infrastructure/.nav.yml @@ -1,4 +1,5 @@ nav: + - 'Overview': overview.md - 'Run a Node': run-a-node - 'Run a Collator': run-a-collator - 'Run a Validator': run-a-validator diff --git a/node-infrastructure/overview.md b/node-infrastructure/overview.md new file mode 100644 index 000000000..13098d5ad --- /dev/null +++ b/node-infrastructure/overview.md @@ -0,0 +1,80 @@ +--- +title: Node Infrastructure +description: Overview of running nodes in the Polkadot ecosystem, including RPC nodes, collators, and validators. +categories: Infrastructure +--- + +# Node Infrastructure Overview + +## Introduction + +The Polkadot network relies on various types of nodes to maintain security, provide data access, and produce blocks. This section covers everything you need to know about running infrastructure for the Polkadot ecosystem. + +Whether you want to provide RPC endpoints for applications, produce blocks for a parachain, or secure the relay chain as a validator, this guide will help you understand your options and get started. + +## Node Types + +### RPC Nodes + +RPC nodes provide API access to blockchain data without participating in consensus. They are essential infrastructure for: + +- **Applications and dApps**: Query blockchain state and submit transactions +- **Block explorers**: Index and display blockchain data +- **Wallets**: Check balances and broadcast transactions +- **Development**: Test and debug applications + +RPC nodes can be run for both the relay chain and parachains, with varying levels of data retention (pruned vs archive). + +### Collators + +Collators are block producers for parachains. They perform critical functions: + +- **Collect transactions**: Aggregate user transactions into blocks +- **Produce blocks**: Create parachain block candidates +- **Generate proofs**: Produce state transition proofs (Proof-of-Validity) +- **Submit to validators**: Send block candidates to relay chain validators + +Unlike validators, collators do not provide security guarantees—that responsibility lies with relay chain validators. However, collators are essential for parachain liveness and censorship resistance. + +### Validators + +Validators secure the Polkadot relay chain through Nominated Proof of Stake (NPoS). They: + +- **Validate blocks**: Verify parachain blocks and relay chain transactions +- **Participate in consensus**: Run BABE and GRANDPA protocols +- **Earn rewards**: Receive staking rewards for honest behavior +- **Risk slashing**: Face penalties for misbehavior or downtime + +Running a validator requires significant technical expertise, reliable infrastructure, and a stake of DOT tokens. + +## Next Steps + +Choose your path based on your goals: + +
+ +- :material-api:{ .lg .middle } **Run RPC Nodes** + + --- + + Provide API access for applications, explorers, and wallets + + [:octicons-arrow-right-24: Run a Node](/node-infrastructure/run-a-node/parachain-rpc/) + +- :material-cube-outline:{ .lg .middle } **Run a Collator** + + --- + + Produce blocks for system parachains or your own parachain + + [:octicons-arrow-right-24: Run a Collator](/node-infrastructure/run-a-collator/collator/) + +- :material-shield-check:{ .lg .middle } **Run a Validator** + + --- + + Secure the relay chain and earn staking rewards + + [:octicons-arrow-right-24: Run a Validator](/node-infrastructure/run-a-validator/requirements/) + +
diff --git a/node-infrastructure/run-a-collator/collator.md b/node-infrastructure/run-a-collator/collator.md index 8230cbb44..18ec9445b 100644 --- a/node-infrastructure/run-a-collator/collator.md +++ b/node-infrastructure/run-a-collator/collator.md @@ -56,18 +56,12 @@ Block-producing collators require robust hardware for reliable operation: ### Software Requirements -Collators use the **Polkadot Omni Node**, a universal binary that runs any parachain using a chain specification file. +Collators use the **Polkadot Parachain** binary, the standard client for running Polkadot system parachains. Required software: - **Operating System**: Ubuntu 22.04 LTS (recommended) or similar Linux distribution -- **Docker**: For running subkey utility -- **Rust Toolchain**: Version 1.91.1 or as specified by the runtime -- **Dependencies**: - ```bash - sudo apt update - sudo apt install -y build-essential git clang curl libssl-dev llvm libudev-dev make protobuf-compiler - ``` +- **Docker**: Required for obtaining binaries and running containers ### Account Requirements @@ -79,54 +73,81 @@ You'll need: ## Installation -### Step 1: Install Rust and Required Toolchain +### Step 1: Install the Polkadot Parachain Binary + +**For Docker deployment:** ```bash -# Install Rust -curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -source $HOME/.cargo/env - -# Install specific Rust version -rustup install 1.91.1 -rustup default 1.91.1 -rustup target add wasm32-unknown-unknown --toolchain 1.91.1 -rustup component add rust-src --toolchain 1.91.1 +# Pull the polkadot-parachain image +docker pull parity/polkadot-parachain:stable2509-2 + +# Verify installation +docker run --rm parity/polkadot-parachain:stable2509-2 --version ``` -### Step 2: Install the Polkadot Omni Node +**For bare-metal deployment:** + +Extract the binary from the Docker image: ```bash -# Install polkadot-omni-node -cargo install --locked polkadot-omni-node@0.11.0 +# Create a temporary container and copy the binary +docker create --name temp-parachain parity/polkadot-parachain:stable2509-2 +sudo docker cp temp-parachain:/usr/local/bin/polkadot-parachain /usr/local/bin/ +docker rm temp-parachain # Verify installation -polkadot-omni-node --version +polkadot-parachain --version ``` -### Step 3: Generate Node Key +Check [Docker Hub](https://hub.docker.com/r/parity/polkadot-parachain/tags) for the latest stable tags. + +### Step 2: Generate Node Key Generate a stable node key for consistent peer ID: ```bash # Create directory for node data sudo mkdir -p /var/lib/polkadot-collator +``` + +**Using Docker:** -# Generate node key using Docker -docker run -it parity/subkey:latest generate-node-key > /var/lib/polkadot-collator/node.key +```bash +# Generate node key (outputs peer ID to console, saves key to file) +docker run --rm -v /var/lib/polkadot-collator:/data \ + parity/polkadot-parachain:stable2509-2 \ + key generate-node-key --file /data/node.key -# The output displays your peer ID -# Example: 12D3KooWExcVYu7Mvjd4kxPVLwN2ZPnZ5NyLZ5ft477wqzfP2q6E +# Example output: 12D3KooWExcVYu7Mvjd4kxPVLwN2ZPnZ5NyLZ5ft477wqzfP2q6E +``` + +**Using native binary:** + +```bash +# Generate node key +polkadot-parachain key generate-node-key --file /var/lib/polkadot-collator/node.key + +# Example output: 12D3KooWExcVYu7Mvjd4kxPVLwN2ZPnZ5NyLZ5ft477wqzfP2q6E ``` Save the peer ID for future reference. -### Step 4: Generate Account Key +### Step 3: Generate Account Key Generate an account for on-chain transactions: +**Using Docker:** + +```bash +# Generate account key with sr25519 scheme +docker run --rm parity/polkadot-parachain:stable2509-2 key generate --scheme sr25519 +``` + +**Using native binary:** + ```bash # Generate account key with sr25519 scheme -docker run -it parity/subkey:latest generate --scheme sr25519 +polkadot-parachain key generate --scheme sr25519 ``` Save the output containing: @@ -138,7 +159,7 @@ Save the output containing: **Security**: Store the secret phrase securely. Never share it. Consider using a hardware wallet for production collators. -### Step 5: Obtain Chain Specification +### Step 4: Obtain Chain Specification Download the chain specification for your target system parachain: @@ -177,7 +198,7 @@ chain-spec-builder create \ - People Chain: 1004 - Coretime Chain: 1005 -### Step 6: Create User and Directory Structure +### Step 5: Create User and Directory Structure ```bash # Create dedicated user @@ -192,7 +213,7 @@ sudo chown -R polkadot:polkadot /var/lib/polkadot-collator ## Configuration -### Create Systemd Service File +### Native Binary Systemd Service Create a service file for your collator: @@ -214,7 +235,7 @@ Group=polkadot WorkingDirectory=/var/lib/polkadot-collator # Block-Producing Collator Configuration -ExecStart=/usr/local/bin/polkadot-omni-node \ +ExecStart=/usr/local/bin/polkadot-parachain \ --collator \ --chain=/var/lib/polkadot-collator/chain-spec.json \ --base-path=/var/lib/polkadot-collator \ @@ -244,6 +265,55 @@ WantedBy=multi-user.target - `--name`: Your collator name (visible in telemetry) - Relay chain uses `--sync=warp` for faster initial sync +### Docker Systemd Service + +If using Docker, create a service file with Docker configuration: + +```bash +sudo nano /etc/systemd/system/polkadot-collator.service +``` + +Add the following configuration: + +```ini +[Unit] +Description=Polkadot System Parachain Collator (Docker) +After=network.target docker.service +Requires=docker.service + +[Service] +Type=simple +Restart=always +RestartSec=10 +TimeoutStartSec=0 + +ExecStartPre=-/usr/bin/docker stop polkadot-collator +ExecStartPre=-/usr/bin/docker rm polkadot-collator + +ExecStart=/usr/bin/docker run --rm \ + --name polkadot-collator \ + --network host \ + -v /var/lib/polkadot-collator:/data \ + parity/polkadot-parachain:stable2509-2 \ + --collator \ + --chain=/data/chain-spec.json \ + --base-path=/data \ + --port=30333 \ + --rpc-port=9944 \ + --prometheus-port=9615 \ + --node-key-file=/data/node.key \ + --name="YourCollatorName" \ + -- \ + --chain=polkadot \ + --port=30334 \ + --sync=warp + +ExecStop=/usr/bin/docker stop polkadot-collator + +[Install] +WantedBy=multi-user.target +``` + ## Running the Collator ### Step 1: Start the Service @@ -488,7 +558,7 @@ The node handles pruning automatically. - Fellowship GitHub - Matrix channels -**Upgrade Procedure**: +**Upgrade Procedure (Bare-Metal)**: ```bash # Stop the service @@ -497,11 +567,14 @@ sudo systemctl stop polkadot-collator # Backup data (recommended) sudo cp -r /var/lib/polkadot-collator /var/lib/polkadot-collator.backup -# Update polkadot-omni-node -cargo install --locked --force polkadot-omni-node@ +# Pull new image and extract binary +docker pull parity/polkadot-parachain: +docker create --name temp-parachain parity/polkadot-parachain: +sudo docker cp temp-parachain:/usr/local/bin/polkadot-parachain /usr/local/bin/ +docker rm temp-parachain # Verify version -polkadot-omni-node --version +polkadot-parachain --version # Restart service sudo systemctl start polkadot-collator @@ -510,6 +583,28 @@ sudo systemctl start polkadot-collator sudo systemctl status polkadot-collator ``` +**Upgrade Procedure (Docker)**: + +```bash +# Stop the service +sudo systemctl stop polkadot-collator + +# Backup data (recommended) +sudo cp -r /var/lib/polkadot-collator /var/lib/polkadot-collator.backup + +# Pull new image +docker pull parity/polkadot-parachain: + +# Update the image tag in /etc/systemd/system/polkadot-collator.service + +# Reload systemd and restart +sudo systemctl daemon-reload +sudo systemctl start polkadot-collator + +# Verify service is running +sudo systemctl status polkadot-collator +``` + **Note**: For log monitoring, see the [Log Management](#log-management) section. ## Conclusion diff --git a/node-infrastructure/run-a-node/.nav.yml b/node-infrastructure/run-a-node/.nav.yml index f4e014c43..747174907 100644 --- a/node-infrastructure/run-a-node/.nav.yml +++ b/node-infrastructure/run-a-node/.nav.yml @@ -1,4 +1,4 @@ nav: - 'Polkadot Hub RPC Node': polkadot-hub-rpc.md - - 'System Parachain RPC Nodes': system-parachain-rpc.md + - 'Parachain RPC Nodes': parachain-rpc.md - 'Relay Chain Nodes': relay-chain diff --git a/.ai/pages/node-infrastructure-run-a-node-system-parachain-rpc.md b/node-infrastructure/run-a-node/parachain-rpc.md similarity index 71% rename from .ai/pages/node-infrastructure-run-a-node-system-parachain-rpc.md rename to node-infrastructure/run-a-node/parachain-rpc.md index 63f5aa7ed..b5a0fec82 100644 --- a/.ai/pages/node-infrastructure-run-a-node-system-parachain-rpc.md +++ b/node-infrastructure/run-a-node/parachain-rpc.md @@ -1,38 +1,59 @@ --- -title: Run an RPC Node for System Parachains -description: Complete guide to set up and run an RPC node for Polkadot system parachains including Bridge Hub, People Chain, and Coretime Chain. +title: Run a Parachain RPC Node +description: Complete guide to set up and run an RPC node for any Polkadot parachain, with system parachains as examples. categories: Infrastructure -url: https://docs.polkadot.com/node-infrastructure/run-a-node/system-parachain-rpc/ --- -# Run an RPC Node for System Parachains +# Run a Parachain RPC Node ## Overview -System parachains are core infrastructure parachains that provide essential services to the Polkadot network. Running an RPC node for these parachains enables applications, wallets, and users to interact with their specialized functionality: +Running an RPC node for a parachain enables applications, wallets, and users to interact with the parachain's functionality. This guide applies to **any parachain** in the Polkadot ecosystem, including: -- **Bridge Hub**: Cross-chain asset transfers via trustless bridges -- **People Chain**: Identity and social credential management -- **Coretime Chain**: Blockspace allocation and core time management +- **System parachains**: Bridge Hub, People Chain, Coretime Chain +- **Common good parachains**: Collectives, Encointer +- **Commercial parachains**: Any parachain with a publicly available chain specification -Each system parachain RPC node provides access through: -- **Polkadot SDK Node RPC** (Port 9944): Native Polkadot API (WebSocket and HTTP) - -This setup enables block explorer indexing and provides full compatibility with Polkadot SDK development tools. +Each parachain RPC node provides access through the Polkadot SDK Node RPC (Port 9944), offering native Polkadot API access via WebSocket and HTTP. This setup enables block explorer indexing and provides full compatibility with Polkadot SDK development tools. **Important Note**: The parameters and configurations in this guide are provided as illustrative examples. You may need to modify them according to your specific environment, hardware capabilities, and network conditions. -## Choosing a System Parachain +## Obtaining a Chain Specification + +To run an RPC node for any parachain, you need its **chain specification file**. This JSON file defines the network parameters, genesis state, and bootnodes. + +### System Parachains + +System parachain chain specs are available from multiple sources: -This guide uses **People Chain** as the example, but the same principles and setup procedures apply to all system parachains. Simply substitute the appropriate values from the table below for your chosen parachain: +**Option 1: Chainspec Collection (Recommended)** -| Parachain | Para ID | Chain Spec File | Snapshot Path | Chain Name | -|-----------|---------|-----------------|---------------|------------| -| **Bridge Hub** | 1002 | `bridge-hub-polkadot.json` | `polkadot-bridge-hub-rocksdb-archive` | `bridge-hub-polkadot` | -| **People Chain** | 1004 | `people-polkadot.json` | `polkadot-people-rocksdb-archive` | `people-polkadot` | -| **Coretime Chain** | 1005 | `coretime-polkadot.json` | `polkadot-coretime-rocksdb-archive` | `coretime-polkadot` | +Visit the [Chainspec Collection](https://paritytech.github.io/chainspecs/) to download official chain specifications. -**Note**: Throughout this guide, we use People Chain values. To set up a different system parachain, replace the chain spec file, snapshot path, and chain name with the corresponding values from the table above. +**Option 2: Polkadot SDK Repository** + +Download directly from the Polkadot SDK repository: + +```bash +# Example for People Chain +curl -L https://raw.githubusercontent.com/paritytech/polkadot-sdk/master/cumulus/parachains/chain-specs/people-polkadot.json -o chain-spec.json +``` + +| System Parachain | Para ID | Chain Spec File | Snapshot Path | +|------------------|---------|-----------------|---------------| +| **Bridge Hub** | 1002 | `bridge-hub-polkadot.json` | `polkadot-bridge-hub-rocksdb-archive` | +| **People Chain** | 1004 | `people-polkadot.json` | `polkadot-people-rocksdb-archive` | +| **Coretime Chain** | 1005 | `coretime-polkadot.json` | `polkadot-coretime-rocksdb-archive` | + +### Other Parachains + +For non-system parachains: + +- **Check the parachain's documentation** for official chain specification files +- **Contact the parachain team** if no public chain spec is available +- **Export from a running node** using `system_chainSpec` RPC method if you have access to an existing node + +**Note**: Throughout this guide, we use **People Chain** as the example. To set up a different parachain, substitute the chain spec file, snapshot path, and chain name with values for your target parachain. ## Prerequisites @@ -65,9 +86,8 @@ RPC nodes serving production traffic require robust hardware: Required software: - **Operating System**: Ubuntu 22.04 LTS (recommended) or similar Linux distribution -- **Docker**: Latest version installed and running (for Docker-based setup) +- **Docker**: Required for obtaining binaries and running containers - **rclone**: (Optional but recommended) Command-line program for managing files on cloud storage (https://rclone.org/downloads/) -- **Rust Toolchain**: Version 1.91.1 or as specified by runtime (for manual build) ## Setup Options @@ -84,22 +104,14 @@ Choose the option that best fits your needs. This option uses Docker containers for the Polkadot SDK node, making it easy to set up and manage. -### Step 1: Download Chain Specification - -Download the official chain specification for People Chain: - -```bash -curl -L https://raw.githubusercontent.com/paritytech/polkadot-sdk/master/cumulus/parachains/chain-specs/people-polkadot.json -o people-polkadot.json -``` - -**Note**: This chain specification is the official configuration file that defines the network parameters for People Chain. - -### Step 2: Download Database Snapshots (Optional but Recommended) +### Step 1: Download Database Snapshots (Optional but Recommended) Using pre-synchronized snapshots significantly reduces initial sync time from several days to just a few hours. You need to download both parachain and relay chain data. **Snapshot Provider**: https://snapshots.polkadot.io/ +**Note**: Snapshots are available for system parachains and the Polkadot relay chain. For other parachains, check with the parachain team for snapshot availability or sync from genesis. + #### Create Directories ```bash @@ -161,11 +173,13 @@ rm files.txt - Pruned snapshot: `polkadot-rocksdb-prune` (smaller size, recent state) - Archive snapshot: `polkadot-rocksdb-archive` (complete history, larger size) -### Step 3: Start People Chain Node +### Step 2: Start the Parachain Node Launch the node using the official Parity Docker image. -**Docker Image**: https://hub.docker.com/r/parity/polkadot-omni-node +**Docker Image**: https://hub.docker.com/r/parity/polkadot-parachain + +**Note**: The `parity/polkadot-parachain` image works for system parachains and parachains built with standard Cumulus templates. For parachains with custom runtimes, check the parachain's documentation for their specific Docker image or binary. ```bash docker run -d --name people-chain-rpc --restart unless-stopped \ @@ -176,7 +190,7 @@ docker run -d --name people-chain-rpc --restart unless-stopped \ -p 30333:30333 \ -v $(pwd)/people-polkadot.json:/people-polkadot.json \ -v $(pwd)/my-node-data:/data \ - parity/polkadot-omni-node:v1.20.2 \ + parity/polkadot-parachain:stable2509-2 \ --name=PeopleChainRPC \ --base-path=/data \ --chain=/people-polkadot.json \ @@ -216,7 +230,7 @@ docker run -d --name people-chain-rpc --restart unless-stopped \ **Security Warning**: The `--unsafe-rpc-external` flag should only be used in development or properly secured environments. For production, use a reverse proxy with authentication. -### Step 4: Monitor Synchronization +### Step 3: Monitor Synchronization Monitor the node synchronization status: @@ -246,7 +260,7 @@ curl -H "Content-Type: application/json" \ - **In Progress**: `currentBlock` < `highestBlock` - **Complete**: `currentBlock` = `highestBlock` -### Step 5: Verify Setup +### Step 4: Verify Setup Let's verify the Polkadot SDK RPC endpoint is working correctly. @@ -336,39 +350,26 @@ docker rm people-chain-rpc This option provides more control and is recommended for production environments requiring custom configurations. -### Step 1: Install Rust and Required Toolchain +### Step 1: Install the Polkadot Parachain Binary -```bash -# Install Rust -curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -source $HOME/.cargo/env - -# Install specific Rust version -rustup install 1.91.1 -rustup default 1.91.1 -rustup target add wasm32-unknown-unknown --toolchain 1.91.1 -rustup component add rust-src --toolchain 1.91.1 -``` - -### Step 2: Install the Polkadot Omni Node +Extract the binary from the official Docker image: ```bash -# Install polkadot-omni-node -cargo install --locked polkadot-omni-node@0.11.0 +# Pull the image and extract binary +docker pull parity/polkadot-parachain:stable2509-2 +docker create --name temp-parachain parity/polkadot-parachain:stable2509-2 +sudo docker cp temp-parachain:/usr/local/bin/polkadot-parachain /usr/local/bin/ +docker rm temp-parachain # Verify installation -polkadot-omni-node --version +polkadot-parachain --version ``` -### Step 3: Obtain Chain Specification +Check [Docker Hub](https://hub.docker.com/r/parity/polkadot-parachain/tags) for the latest stable tags. -Download the People Chain specification: +### Step 2: Create User and Directory Structure -```bash -curl -L https://raw.githubusercontent.com/paritytech/polkadot-sdk/master/cumulus/parachains/chain-specs/people-polkadot.json -o people-polkadot.json -``` - -### Step 4: Create User and Directory Structure +Ensure you have downloaded your parachain's chain specification as described in [Obtaining a Chain Specification](#obtaining-a-chain-specification). ```bash # Create dedicated user (skip if already exists) @@ -384,9 +385,9 @@ sudo cp people-polkadot.json /var/lib/people-chain-rpc/ sudo chown -R polkadot:polkadot /var/lib/people-chain-rpc ``` -### Step 5: Create Systemd Service +### Step 3: Create Systemd Service -Create a service file for the People Chain RPC node: +Create a service file for your parachain RPC node: ```bash sudo nano /etc/systemd/system/people-chain-rpc.service @@ -405,7 +406,7 @@ User=polkadot Group=polkadot WorkingDirectory=/var/lib/people-chain-rpc -ExecStart=/usr/local/bin/polkadot-omni-node \ +ExecStart=/usr/local/bin/polkadot-parachain \ --name=PeopleChainRPC \ --chain=/var/lib/people-chain-rpc/people-polkadot.json \ --base-path=/var/lib/people-chain-rpc \ @@ -434,7 +435,7 @@ LimitNOFILE=65536 WantedBy=multi-user.target ``` -### Step 6: Start Service +### Step 4: Start Service ```bash # Reload systemd @@ -451,9 +452,9 @@ sudo systemctl status people-chain-rpc sudo journalctl -u people-chain-rpc -f ``` -### Step 7: Verify Setup +### Step 5: Verify Setup -Use the same verification tests as in the Docker setup (see Step 5 above). +Use the same verification tests as in the Docker setup (see Step 4 above). --- @@ -497,14 +498,12 @@ Metrics are available at `http://localhost:9615/metrics` Example Prometheus scrape configuration: -{% raw %} ```yaml scrape_configs: - job_name: 'people-chain-rpc' static_configs: - targets: ['localhost:9615'] ``` -{% endraw %} **Key Metrics to Monitor**: @@ -533,13 +532,13 @@ The node handles pruning automatically based on configuration unless running in ```bash # Pull latest image -docker pull parity/polkadot-omni-node:v1.20.2 +docker pull parity/polkadot-parachain: # Restart container docker stop people-chain-rpc docker rm people-chain-rpc -# Start new container (use same command from setup) +# Start new container (use same command from setup with updated image tag) ``` **Systemd Setup**: @@ -551,8 +550,11 @@ sudo systemctl stop people-chain-rpc # Backup data sudo cp -r /var/lib/people-chain-rpc /var/lib/people-chain-rpc.backup -# Update binary -cargo install --locked --force polkadot-omni-node@ +# Pull new image and extract binary +docker pull parity/polkadot-parachain: +docker create --name temp-parachain parity/polkadot-parachain: +sudo docker cp temp-parachain:/usr/local/bin/polkadot-parachain /usr/local/bin/ +docker rm temp-parachain # Restart service sudo systemctl start people-chain-rpc @@ -560,11 +562,11 @@ sudo systemctl start people-chain-rpc ## Conclusion -Running an RPC node for system parachains provides critical infrastructure for accessing specialized Polkadot network services. By following this guide, you have set up a production-ready RPC node that: +Running a parachain RPC node provides critical infrastructure for accessing Polkadot network services. By following this guide, you have set up a production-ready RPC node that: -- Enables applications and users to interact with essential system parachain features (identity management, cross-chain bridges, or coretime allocation) +- Provides reliable access to parachain functionality for applications and users - Supports flexible deployment with both Docker and systemd options - Implements comprehensive monitoring, security, and maintenance practices -- Can be easily adapted for any system parachain by substituting the appropriate chain specification +- Can be adapted for any parachain by substituting the appropriate chain specification -Whether you're running a node for People Chain, Bridge Hub, or Coretime Chain, regular maintenance and monitoring will ensure your RPC node continues to provide reliable service. Stay updated with the latest releases and best practices to keep your infrastructure secure and performant. +Whether you're running a node for system parachains (People Chain, Bridge Hub, Coretime Chain) or other parachains in the ecosystem, regular maintenance and monitoring will ensure your RPC node continues to provide reliable service. Stay updated with the latest releases and best practices to keep your infrastructure secure and performant. diff --git a/node-infrastructure/run-a-node/polkadot-hub-rpc.md b/node-infrastructure/run-a-node/polkadot-hub-rpc.md index f8e653222..c08af26c3 100644 --- a/node-infrastructure/run-a-node/polkadot-hub-rpc.md +++ b/node-infrastructure/run-a-node/polkadot-hub-rpc.md @@ -52,9 +52,8 @@ RPC nodes serving production traffic require robust hardware: Required software: - **Operating System**: Ubuntu 22.04 LTS (recommended) or similar Linux distribution -- **Docker**: Latest version installed and running (for Docker-based setup) +- **Docker**: Required for obtaining binaries and running containers - **rclone**: (Optional but recommended) Command-line program for managing files on cloud storage (https://rclone.org/downloads/) -- **Rust Toolchain**: Version 1.91.1 or later (for manual build) ## Setup Options @@ -150,7 +149,7 @@ rm files.txt Launch the node using the official Parity Docker image: -**Docker Image**: https://hub.docker.com/r/parity/polkadot-omni-node +**Docker Image**: https://hub.docker.com/r/parity/polkadot-parachain ```bash docker run -d --name polkadot-hub-rpc --restart unless-stopped \ @@ -161,7 +160,7 @@ docker run -d --name polkadot-hub-rpc --restart unless-stopped \ -p 30333:30333 \ -v $(pwd)/asset-hub-polkadot.json:/asset-hub-polkadot.json \ -v $(pwd)/my-node-data:/data \ - parity/polkadot-omni-node:v1.20.2 \ + parity/polkadot-parachain:stable2509-2 \ --name=PolkadotHubRPC \ --base-path=/data \ --chain=/asset-hub-polkadot.json \ @@ -305,41 +304,24 @@ docker rm polkadot-hub-rpc This option provides more control and is recommended for production environments requiring custom configurations. -### Step 1: Install Rust and Required Toolchain +### Step 1: Install the Polkadot Parachain Binary -```bash -# Install Rust -curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -source $HOME/.cargo/env - -# Install specific Rust version -rustup install 1.91.1 -rustup default 1.91.1 -rustup target add wasm32-unknown-unknown --toolchain 1.91.1 -rustup component add rust-src --toolchain 1.91.1 -``` - -### Step 2: Install Required Dependencies - -```bash -# Install system dependencies -sudo apt update -sudo apt install -y build-essential git clang curl libssl-dev llvm libudev-dev make protobuf-compiler -``` - -### Step 3: Install the Polkadot Omni Node +Extract the binary from the official Docker image: ```bash -# Install polkadot-omni-node -cargo install --locked polkadot-omni-node@0.11.0 +# Pull the image and extract binary +docker pull parity/polkadot-parachain:stable2509-2 +docker create --name temp-parachain parity/polkadot-parachain:stable2509-2 +sudo docker cp temp-parachain:/usr/local/bin/polkadot-parachain /usr/local/bin/ +docker rm temp-parachain # Verify installation -polkadot-omni-node --version +polkadot-parachain --version ``` -**Note**: Compiling polkadot-omni-node from source requires significant RAM (minimum 24GB recommended). The compilation may take 10-15 minutes on systems with adequate resources. +Check [Docker Hub](https://hub.docker.com/r/parity/polkadot-parachain/tags) for the latest stable tags. -### Step 4: Obtain Chain Specification +### Step 2: Obtain Chain Specification Download the Polkadot Hub chain specification: @@ -347,7 +329,7 @@ Download the Polkadot Hub chain specification: curl -L https://raw.githubusercontent.com/paritytech/polkadot-sdk/master/cumulus/parachains/chain-specs/asset-hub-polkadot.json -o asset-hub-polkadot.json ``` -### Step 5: Create User and Directory Structure +### Step 3: Create User and Directory Structure ```bash # Create dedicated user @@ -363,7 +345,7 @@ sudo cp asset-hub-polkadot.json /var/lib/polkadot-hub-rpc/ sudo chown -R polkadot:polkadot /var/lib/polkadot-hub-rpc ``` -### Step 6: Create Systemd Service for Polkadot SDK Node +### Step 4: Create Systemd Service Create a service file for the Polkadot SDK RPC node: @@ -384,7 +366,7 @@ User=polkadot Group=polkadot WorkingDirectory=/var/lib/polkadot-hub-rpc -ExecStart=/usr/local/bin/polkadot-omni-node \ +ExecStart=/usr/local/bin/polkadot-parachain \ --name=PolkadotHubRPC \ --chain=/var/lib/polkadot-hub-rpc/asset-hub-polkadot.json \ --base-path=/var/lib/polkadot-hub-rpc \ @@ -413,7 +395,7 @@ LimitNOFILE=65536 WantedBy=multi-user.target ``` -### Step 7: Start Service +### Step 5: Start Service ```bash # Reload systemd @@ -430,7 +412,7 @@ sudo systemctl status polkadot-hub-rpc sudo journalctl -u polkadot-hub-rpc -f ``` -### Step 8: Verify Setup +### Step 6: Verify Setup Use the same verification tests as in the Docker setup (see Step 5 above). @@ -510,13 +492,13 @@ The node handles pruning automatically based on configuration unless running in ```bash # Pull latest image -docker pull parity/polkadot-omni-node:v1.20.2 +docker pull parity/polkadot-parachain: # Restart container docker stop polkadot-hub-rpc docker rm polkadot-hub-rpc -# Start new container (use same command from setup) +# Start new container (use same command from setup with updated image tag) ``` **Systemd Setup**: @@ -528,8 +510,11 @@ sudo systemctl stop polkadot-hub-rpc # Backup data sudo cp -r /var/lib/polkadot-hub-rpc /var/lib/polkadot-hub-rpc.backup -# Update binary -cargo install --locked --force polkadot-omni-node@ +# Pull new image and extract binary +docker pull parity/polkadot-parachain: +docker create --name temp-parachain parity/polkadot-parachain: +sudo docker cp temp-parachain:/usr/local/bin/polkadot-parachain /usr/local/bin/ +docker rm temp-parachain # Restart service sudo systemctl start polkadot-hub-rpc From a9f83404d7476d5dcb5f25a02bf0705c4332cda5 Mon Sep 17 00:00:00 2001 From: Bruno Galvao Date: Mon, 24 Nov 2025 16:34:47 +0700 Subject: [PATCH 12/39] Use polkadot-parachain binary instead of polkadot-omni-node --- .../run-a-collator/collator.md | 42 +++++------- .../run-a-node/polkadot-hub-rpc.md | 67 +++++++------------ 2 files changed, 43 insertions(+), 66 deletions(-) diff --git a/node-infrastructure/run-a-collator/collator.md b/node-infrastructure/run-a-collator/collator.md index 843a5f863..745d37dac 100644 --- a/node-infrastructure/run-a-collator/collator.md +++ b/node-infrastructure/run-a-collator/collator.md @@ -96,28 +96,17 @@ This guide provides two deployment options. Select the option that best fits you === "Manual Setup" - 1. Install Rust using the following commands: - ```bash - # Install Rust - curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh - source $HOME/.cargo/env - - # Install specific Rust version - rustup install 1.91.1 - rustup default 1.91.1 - rustup target add wasm32-unknown-unknown --toolchain 1.91.1 - rustup component add rust-src --toolchain 1.91.1 - ``` + Extract the binary from the official Docker image: - 2. Install the Polkadot Omni Node using the following command: - ```bash - cargo install --locked polkadot-omni-node@0.11.0 - ``` + ```bash + # Create a temporary container and copy the binary + docker create --name temp-parachain parity/polkadot-parachain:stable2509-2 + sudo docker cp temp-parachain:/usr/local/bin/polkadot-parachain /usr/local/bin/ + docker rm temp-parachain - 3. Verify a successful installation using the `--version` flag: - ```bash - polkadot-omni-node --version - ``` + # Verify installation + polkadot-parachain --version + ``` ## Generate Node Key @@ -245,7 +234,7 @@ Follow these steps to build a chainspec from the runtime: WorkingDirectory=/var/lib/polkadot-collator # Block-Producing Collator Configuration - ExecStart=/usr/local/bin/polkadot-omni-node \ + ExecStart=/usr/local/bin/polkadot-parachain \ --collator \ --chain=/var/lib/polkadot-collator/chain-spec.json \ --base-path=/var/lib/polkadot-collator \ @@ -500,14 +489,17 @@ Updates or upgrades can happen on either the runtime or client. Runtime upgrades sudo cp -r /var/lib/polkadot-collator /var/lib/polkadot-collator.backup ``` - 3. Update `polkadot-omni-node`: + 3. Pull the new image and extract the binary: ```bash - cargo install --locked --force polkadot-omni-node@ + docker pull parity/polkadot-parachain: + docker create --name temp-parachain parity/polkadot-parachain: + sudo docker cp temp-parachain:/usr/local/bin/polkadot-parachain /usr/local/bin/ + docker rm temp-parachain ``` - 4. Verify `polkadot-omni-node` version to confirm successful update: + 4. Verify `polkadot-parachain` version to confirm successful update: ```bash - polkadot-omni-node --version + polkadot-parachain --version ``` 5. Restart the service: diff --git a/node-infrastructure/run-a-node/polkadot-hub-rpc.md b/node-infrastructure/run-a-node/polkadot-hub-rpc.md index 7ef0bad0c..e33f65eca 100644 --- a/node-infrastructure/run-a-node/polkadot-hub-rpc.md +++ b/node-infrastructure/run-a-node/polkadot-hub-rpc.md @@ -129,7 +129,7 @@ Select the best option for your project, then use the steps in the following tab rm files.txt ``` - 3. Launch Polkadot Hub Node using the official [Parity Docker image](https://hub.docker.com/r/parity/polkadot-omni-node){target=\_blank} with the following command: + 3. Launch Polkadot Hub Node using the official [Parity Docker image](https://hub.docker.com/r/parity/polkadot-parachain){target=\_blank} with the following command: ```bash docker run -d --name polkadot-hub-rpc --restart unless-stopped \ -p 9944:9944 \ @@ -139,7 +139,7 @@ Select the best option for your project, then use the steps in the following tab -p 30333:30333 \ -v $(pwd)/asset-hub-polkadot.json:/asset-hub-polkadot.json \ -v $(pwd)/my-node-data:/data \ - parity/polkadot-omni-node:v1.20.2 \ + parity/polkadot-parachain:stable2509-2 \ --name=PolkadotHubRPC \ --base-path=/data \ --chain=/asset-hub-polkadot.json \ @@ -246,46 +246,28 @@ Select the best option for your project, then use the steps in the following tab === "Manual systemd Setup" - This option uses systemd to provide more control and is recommended for production environments requiring custom configurations. + This option provides more control and is recommended for production environments requiring custom configurations. - 1. Install Rust and required toolchain using the following command: + 1. Install the Polkadot Parachain binary by extracting it from the official Docker image: ```bash - # Install Rust - curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh - source $HOME/.cargo/env - - # Install specific Rust version - rustup install 1.91.1 - rustup default 1.91.1 - rustup target add wasm32-unknown-unknown --toolchain 1.91.1 - rustup component add rust-src --toolchain 1.91.1 + # Pull the image and extract binary + docker pull parity/polkadot-parachain:stable2509-2 + docker create --name temp-parachain parity/polkadot-parachain:stable2509-2 + sudo docker cp temp-parachain:/usr/local/bin/polkadot-parachain /usr/local/bin/ + docker rm temp-parachain + + # Verify installation + polkadot-parachain --version ``` - 2. Install required dependencies using the following commands: - - System dependencies: - ```bash - sudo apt update - sudo apt install -y build-essential git clang curl libssl-dev llvm libudev-dev make protobuf-compiler - ``` - - Polkadot Omni node: - ```bash - cargo install --locked polkadot-omni-node@0.11.0 - ``` - You can verify successful installation of Polkadot Omni node using the version command: - ```bash - polkadot-omni-node --version - ``` - - !!! tip - - Compiling polkadot-omni-node from source requires significant RAM (minimum 24GB recommended). The compilation may take 10-15 minutes on systems with adequate resources. + Check [Docker Hub](https://hub.docker.com/r/parity/polkadot-parachain/tags){target=\_blank} for the latest stable tags. - 3. Download the Polkadot Hub chain specification: + 2. Download the Polkadot Hub chain specification: ```bash curl -L https://raw.githubusercontent.com/paritytech/polkadot-sdk/master/cumulus/parachains/chain-specs/asset-hub-polkadot.json -o asset-hub-polkadot.json ``` - 4. Create user and directory structures using the following commands: + 3. Create user and directory structures using the following commands: - Create a dedicated user: ```bash sudo useradd -r -s /bin/bash polkadot @@ -303,12 +285,12 @@ Select the best option for your project, then use the steps in the following tab sudo chown -R polkadot:polkadot /var/lib/polkadot-hub-rpc ``` - 5. Create a systemd service file for the Polkadot SDK RPC node: + 4. Create a systemd service file for the Polkadot SDK RPC node: ```bash sudo nano /etc/systemd/system/polkadot-hub-rpc.service ``` - 6. Open the new service file and add the following configuration: + 5. Open the new service file and add the following configuration: ```ini [Unit] Description=Polkadot Hub RPC Node @@ -320,7 +302,7 @@ Select the best option for your project, then use the steps in the following tab Group=polkadot WorkingDirectory=/var/lib/polkadot-hub-rpc - ExecStart=/usr/local/bin/polkadot-omni-node \ + ExecStart=/usr/local/bin/polkadot-parachain \ --name=PolkadotHubRPC \ --chain=/var/lib/polkadot-hub-rpc/asset-hub-polkadot.json \ --base-path=/var/lib/polkadot-hub-rpc \ @@ -349,7 +331,7 @@ Select the best option for your project, then use the steps in the following tab WantedBy=multi-user.target ``` - 7. Start the service using the following commands: + 6. Start the service using the following commands: - Reload systemd: ```bash sudo systemctl daemon-reload @@ -368,7 +350,7 @@ Select the best option for your project, then use the steps in the following tab sudo journalctl -u polkadot-hub-rpc -f ``` - 8. You can use a few different commands to verify your node is running properly: + 7. You can use a few different commands to verify your node is running properly: - Get chain information: ```bash curl -H "Content-Type: application/json" \ @@ -472,7 +454,7 @@ Use the following commands for updating or upgrading your RPC node according to ``` 2. Pull the latest image: ```bash - docker pull parity/polkadot-omni-node: + docker pull parity/polkadot-parachain: ``` 3. Start the new container using the same command from the setup section with the updated image tag. @@ -486,9 +468,12 @@ Use the following commands for updating or upgrading your RPC node according to ```bash sudo cp -r /var/lib/polkadot-hub-rpc /var/lib/polkadot-hub-rpc.backup ``` - 3. Update the binary: + 3. Pull the new image and extract the binary: ```bash - cargo install --locked --force polkadot-omni-node@ + docker pull parity/polkadot-parachain: + docker create --name temp-parachain parity/polkadot-parachain: + sudo docker cp temp-parachain:/usr/local/bin/polkadot-parachain /usr/local/bin/ + docker rm temp-parachain ``` 4. Restart the service: ```bash From 35d51a0b3951c6b9b11bc0d3195817bb5b682ed2 Mon Sep 17 00:00:00 2001 From: Bruno Galvao Date: Mon, 24 Nov 2025 16:35:34 +0700 Subject: [PATCH 13/39] Update llms --- ...-infrastructure-run-a-collator-collator.md | 837 ++++++++--------- ...rastructure-run-a-node-polkadot-hub-rpc.md | 872 +++++++++--------- 2 files changed, 787 insertions(+), 922 deletions(-) diff --git a/.ai/pages/node-infrastructure-run-a-collator-collator.md b/.ai/pages/node-infrastructure-run-a-collator-collator.md index e1bed1380..bb8fd588e 100644 --- a/.ai/pages/node-infrastructure-run-a-collator-collator.md +++ b/.ai/pages/node-infrastructure-run-a-collator-collator.md @@ -9,35 +9,35 @@ url: https://docs.polkadot.com/node-infrastructure/run-a-collator/collator/ ## Overview -Block-producing collators are the backbone of system parachain operations. Unlike RPC nodes or archive nodes that simply maintain state, collators actively produce blocks and submit them to relay chain validators for inclusion. +Block-producing collators are the backbone of system parachain operations. Unlike RPC or archive nodes, which maintain state, collators actively produce blocks and submit them to relay chain validators for inclusion. -This guide covers setting up a **block-producing collator** for Polkadot system parachains. Running a collator requires: +This guide covers setting up a block-producing collator for Polkadot system parachains. Running a collator requires: - Meeting hardware requirements for reliable block production - Setting up and registering session keys - Obtaining governance approval or meeting selection criteria - Maintaining high uptime and performance -**Important**: System parachain collators typically require governance approval or being added to the invulnerables list. This is different from non-system parachains where collator selection may be more permissionless. +System parachain collators typically require governance approval or being added to the invulnerables list. This is different from non-system parachains where collator selection may be more permissionless. ## Collator Responsibilities Block-producing collators perform critical functions: -- **Maintain full nodes**: Both relay chain and parachain -- **Collect transactions**: Aggregate user transactions into blocks -- **Produce blocks**: Create parachain block candidates -- **Generate proofs**: Produce state transition proofs (Proof-of-Validity) -- **Submit to validators**: Send block candidates to relay chain validators -- **Facilitate XCM**: Enable cross-chain message passing +- Maintain full nodes for relay chain and parachain. +- Aggregate user transactions into blocks. +- Create parachain block candidates. +- Produce state transition proofs (Proof-of-Validity). +- Send block candidates to relay chain validators. +- Enable cross-chain message passing using XCM -Unlike relay chain validators, collators do not provide security guarantees—that responsibility lies with relay chain validators through the ELVES protocol. However, collators are essential for network liveness and censorship resistance. +Unlike relay chain validators, collators do not provide security guarantees—that responsibility lies with relay chain validators through the ELVES protocol. Rather, collators are essential for network liveness and censorship resistance. ## Prerequisites ### Hardware Requirements -Block-producing collators require robust hardware for reliable operation: +Block-producing collators require robust hardware for reliable operation including the following: - **CPU**: 4+ cores (8+ cores recommended for optimal performance) - **Memory**: 32 GB RAM minimum (64 GB recommended) @@ -53,290 +53,247 @@ Block-producing collators require robust hardware for reliable operation: - 30334 (relay chain P2P) - 9944 (WebSocket RPC - for management) -**Note**: Uptime is critical. Consider redundancy and monitoring to maintain block production reliability. +Uptime is critical. Consider redundancy and monitoring to maintain block production reliability. ### Software Requirements Collators use the **Polkadot Parachain** binary, the standard client for running Polkadot system parachains. -Required software: +Required software includes the following: - **Operating System**: Ubuntu 22.04 LTS (recommended) or similar Linux distribution - **Docker**: Required for obtaining binaries and running containers ### Account Requirements -You'll need: +Your account must meet the following requirements: - **Funded account**: For on-chain transactions and potential bonding - **Session keys**: For collator identification (generated after node setup) - **Node key**: For stable P2P peer ID (recommended) -## Installation +## Install Dependencies -### Step 1: Install the Polkadot Parachain Binary +This guide provides two deployment options. Select the option that best fits your needs: -**For Docker deployment:** +- **Docker-based Setup**: Best for simpler setup and maintenance +- **Manual/systemd Setup**: Best for production environments requiring more control -```bash -# Pull the polkadot-parachain image -docker pull parity/polkadot-parachain:stable2509-2 - -# Verify installation -docker run --rm parity/polkadot-parachain:stable2509-2 --version -``` - -**For bare-metal deployment:** - -Extract the binary from the Docker image: - -```bash -# Create a temporary container and copy the binary -docker create --name temp-parachain parity/polkadot-parachain:stable2509-2 -sudo docker cp temp-parachain:/usr/local/bin/polkadot-parachain /usr/local/bin/ -docker rm temp-parachain - -# Verify installation -polkadot-parachain --version -``` - -Check [Docker Hub](https://hub.docker.com/r/parity/polkadot-parachain/tags) for the latest stable tags. - -### Step 2: Generate Node Key - -Generate a stable node key for consistent peer ID: - -```bash -# Create directory for node data -sudo mkdir -p /var/lib/polkadot-collator -``` - -**Using Docker:** - -```bash -# Generate node key (outputs peer ID to console, saves key to file) -docker run --rm -v /var/lib/polkadot-collator:/data \ - parity/polkadot-parachain:stable2509-2 \ - key generate-node-key --file /data/node.key - -# Example output: 12D3KooWExcVYu7Mvjd4kxPVLwN2ZPnZ5NyLZ5ft477wqzfP2q6E -``` - -**Using native binary:** - -```bash -# Generate node key -polkadot-parachain key generate-node-key --file /var/lib/polkadot-collator/node.key - -# Example output: 12D3KooWExcVYu7Mvjd4kxPVLwN2ZPnZ5NyLZ5ft477wqzfP2q6E -``` - -Save the peer ID for future reference. - -### Step 3: Generate Account Key - -Generate an account for on-chain transactions: - -**Using Docker:** - -```bash -# Generate account key with sr25519 scheme -docker run --rm parity/polkadot-parachain:stable2509-2 key generate --scheme sr25519 -``` +=== "Docker Setup" -**Using native binary:** + Pull the Polkadot Parachain Docker image: -```bash -# Generate account key with sr25519 scheme -polkadot-parachain key generate --scheme sr25519 -``` + ```bash + docker pull parity/polkadot-parachain:stable2509-2 + ``` -Save the output containing: + Verify the installation: -- Secret phrase (seed) - Keep this secure! -- Public key (hex) -- Account ID -- SS58 Address + ```bash + docker run --rm parity/polkadot-parachain:stable2509-2 --version + ``` -**Security**: Store the secret phrase securely. Never share it. Consider using a hardware wallet for production collators. + Check [Docker Hub](https://hub.docker.com/r/parity/polkadot-parachain/tags){target=\_blank} for the latest stable tags. -### Step 4: Obtain Chain Specification +=== "Manual Setup" -Download the chain specification for your target system parachain: + Extract the binary from the official Docker image: -**Option 1: Download from Chainspec Collection (Recommended)** + ```bash + # Create a temporary container and copy the binary + docker create --name temp-parachain parity/polkadot-parachain:stable2509-2 + sudo docker cp temp-parachain:/usr/local/bin/polkadot-parachain /usr/local/bin/ + docker rm temp-parachain -1. Visit the [Chainspec Collection website](https://paritytech.github.io/chainspecs/) -2. Find your target system parachain -3. Download the chain specification JSON file -4. Save it as `chain-spec.json` + # Verify installation + polkadot-parachain --version + ``` -**Option 2: Build from Runtime** +## Generate Node Key -```bash -# Clone the runtimes repository -git clone https://github.com/polkadot-fellows/runtimes.git -cd runtimes - -# Build the desired runtime (example for Polkadot Hub) -cargo build --release -p asset-hub-polkadot-runtime - -# Install chain-spec-builder -cargo install --locked staging-chain-spec-builder@14.0.0 - -# Generate chain spec -chain-spec-builder create \ - --relay-chain polkadot \ - --para-id 1000 \ - --runtime target/release/wbuild/asset-hub-polkadot-runtime/asset_hub_polkadot_runtime.compact.compressed.wasm \ - named-preset production > chain-spec.json -``` +Generating a stable node key enables a consistent peer ID across the network. Follow these steps to generate a node key: -**System Parachain Para IDs:** +1. Create a directory for node data using the following command: + ```bash + sudo mkdir -p /var/lib/polkadot-collator + ``` -- Polkadot Hub: 1000 -- Bridge Hub: 1002 -- People Chain: 1004 -- Coretime Chain: 1005 +2. Generate your node key using Docker with the following command: + ```bash + docker run -it parity/subkey:latest generate-node-key > /var/lib/polkadot-collator/node.key + ``` -### Step 5: Create User and Directory Structure +3. Locate your peer ID in the displayed output. It will be similar to the following example: + ```bash + 12D3KooWExcVYu7Mvjd4kxPVLwN2ZPnZ5NyLZ5ft477wqzfP2q6E + ``` -```bash -# Create dedicated user -sudo useradd -r -s /bin/bash polkadot +Be sure to save the peer ID for future reference. -# Copy chain spec to directory -sudo cp chain-spec.json /var/lib/polkadot-collator/ +## Generate Account Key -# Set permissions -sudo chown -R polkadot:polkadot /var/lib/polkadot-collator -``` +Generate an account for on-chain transactions as follows: -## Configuration +1. Generate an account key with `sr25519` scheme using the following command: + ```bash + docker run -it parity/subkey:latest generate --scheme sr25519 + ``` -### Native Binary Systemd Service +2. Save the following items displayed in the output: + - Secret phrase (seed) - Keep this secure! + - Public key (hex) + - Account ID + - SS58 Address -Create a service file for your collator: + !!! warning + + Store the secret phrase securely. Never share it. Consider using a hardware wallet for production collators. -```bash -sudo nano /etc/systemd/system/polkadot-collator.service -``` +## Obtain Chain Specification -Add the following configuration: - -```ini -[Unit] -Description=Polkadot System Parachain Collator -After=network.target - -[Service] -Type=simple -User=polkadot -Group=polkadot -WorkingDirectory=/var/lib/polkadot-collator - -# Block-Producing Collator Configuration -ExecStart=/usr/local/bin/polkadot-parachain \ - --collator \ - --chain=/var/lib/polkadot-collator/chain-spec.json \ - --base-path=/var/lib/polkadot-collator \ - --port=30333 \ - --rpc-port=9944 \ - --prometheus-port=9615 \ - --node-key-file=/var/lib/polkadot-collator/node.key \ - --name="YourCollatorName" \ - -- \ - --execution=wasm \ - --chain=polkadot \ - --port=30334 \ - --sync=warp - -Restart=always -RestartSec=10 -LimitNOFILE=65536 - -[Install] -WantedBy=multi-user.target -``` +Download the chain specification for your target system parachain using one of the following options: -**Configuration Notes**: +### Download from Chainspec Collection (Recommended) -- `--collator`: Enables block production mode -- `--node-key-file`: Uses the generated node key for stable peer ID -- `--name`: Your collator name (visible in telemetry) -- Relay chain uses `--sync=warp` for faster initial sync +Follow these steps to download your specification from the Chainspec Collection: -### Docker Systemd Service +1. Visit the [Chainspec Collection](https://paritytech.github.io/chainspecs/) website. +2. Find your target system parachain. +3. Download the chain specification JSON file. +4. Save it as `chain-spec.json`. -If using Docker, create a service file with Docker configuration: +### Build Chainspec from Runtime -```bash -sudo nano /etc/systemd/system/polkadot-collator.service -``` - -Add the following configuration: - -```ini -[Unit] -Description=Polkadot System Parachain Collator (Docker) -After=network.target docker.service -Requires=docker.service - -[Service] -Type=simple -Restart=always -RestartSec=10 -TimeoutStartSec=0 - -ExecStartPre=-/usr/bin/docker stop polkadot-collator -ExecStartPre=-/usr/bin/docker rm polkadot-collator - -ExecStart=/usr/bin/docker run --rm \ - --name polkadot-collator \ - --network host \ - -v /var/lib/polkadot-collator:/data \ - parity/polkadot-parachain:stable2509-2 \ - --collator \ - --chain=/data/chain-spec.json \ - --base-path=/data \ - --port=30333 \ - --rpc-port=9944 \ - --prometheus-port=9615 \ - --node-key-file=/data/node.key \ - --name="YourCollatorName" \ - -- \ - --chain=polkadot \ - --port=30334 \ - --sync=warp - -ExecStop=/usr/bin/docker stop polkadot-collator - -[Install] -WantedBy=multi-user.target -``` +Follow these steps to build a chainspec from the runtime: -## Running the Collator +1. Clone the runtimes repository and navigate into it using the following commands: + ```bash + git clone https://github.com/polkadot-fellows/runtimes.git + cd runtimes + ``` -### Step 1: Start the Service +2. Build the desired runtime. Use the following command for Polkadot Hub: + ```bash + cargo build --release -p asset-hub-polkadot-runtime + ``` +3. Install the `chain-spec-builder` dependency using the following command: + ```bash + cargo install --locked staging-chain-spec-builder@14.0.0 + ``` + +4. Finally, generate the chain spec using the following commands: + ```bash + chain-spec-builder create \ + --relay-chain polkadot \ + --para-id 1000 \ + --runtime target/release/wbuild/asset-hub-polkadot-runtime/asset_hub_polkadot_runtime.compact.compressed.wasm \ + named-preset production > chain-spec.json + ``` + +??? tip "System Parachain Para IDs" + + - Polkadot Hub: 1000 + - Bridge Hub: 1002 + - People Chain: 1004 + - Coretime Chain: 1005 + +## Create User and Directory Structure + +1. Create a dedicated user with the following command: + ```bash + sudo useradd -r -s /bin/bash polkadot + ``` + +2. Use the following command to copy your chain spec to the directory: + ```bash + sudo cp chain-spec.json /var/lib/polkadot-collator/ + ``` + +3. Set permissions using the following command: + ```bash + sudo chown -R polkadot:polkadot /var/lib/polkadot-collator + ``` + +## Create Systemd Service File + +1. Create a service file to hold the configuration for your collator: + ```bash + sudo nano /etc/systemd/system/polkadot-collator.service + ``` + +2. Open the new file and add the following configuration code: + ```ini title="systemd/system/polkadot-collator.service" + [Unit] + Description=Polkadot System Parachain Collator + After=network.target + + [Service] + Type=simple + User=polkadot + Group=polkadot + WorkingDirectory=/var/lib/polkadot-collator + + # Block-Producing Collator Configuration + ExecStart=/usr/local/bin/polkadot-parachain \ + --collator \ + --chain=/var/lib/polkadot-collator/chain-spec.json \ + --base-path=/var/lib/polkadot-collator \ + --port=30333 \ + --rpc-port=9944 \ + --prometheus-port=9615 \ + --node-key-file=/var/lib/polkadot-collator/node.key \ + --name="YourCollatorName" \ + -- \ + --execution=wasm \ + --chain=polkadot \ + --port=30334 \ + --sync=warp + + Restart=always + RestartSec=10 + LimitNOFILE=65536 + + [Install] + WantedBy=multi-user.target + ``` + +??? note "Configuration notes" + + - `--collator`: Enables block production mode + - `--node-key-file`: Uses the generated node key for stable peer ID + - `--name`: Your collator name (visible in telemetry) + - Relay chain uses `--sync=warp` for faster initial sync + +## Run the Collator + +Follow these steps to run your collator node: + +1. Reload systemd using the following command: + ```bash + sudo systemctl daemon-reload + ``` + +2. Next, enable the service to start on boot using the command: + ```bash + sudo systemctl enable polkadot-collator + ``` +3. Now, start the service with the following command: + ```bash + sudo systemctl start polkadot-collator + ``` + +4. Finally, you can check the status of the service using the command: + ```bash + sudo systemctl status polkadot-collator + ``` + +To view collator service logs, use the command: ```bash -# Reload systemd -sudo systemctl daemon-reload - -# Enable service to start on boot -sudo systemctl enable polkadot-collator - -# Start the service -sudo systemctl start polkadot-collator - -# Check status -sudo systemctl status polkadot-collator - -# View logs sudo journalctl -u polkadot-collator -f ``` -### Step 2: Initial Sync +## Complete Initial Sync Your collator must sync both the relay chain and parachain before producing blocks. @@ -350,273 +307,221 @@ The relay chain uses warp sync for faster synchronization. **Important**: Do not proceed with registration until both chains are fully synced. Monitor sync progress using the log viewing commands in the [Log Management](#log-management) section. -### Step 3: Generate Session Keys +## Generate Session Keys -Once your node is fully synced, generate session keys: +Once your node is fully synced, use the following command to generate session keys via RPC: ```bash -# Generate session keys via RPC curl -H "Content-Type: application/json" \ -d '{"id":1, "jsonrpc":"2.0", "method": "author_rotateKeys", "params":[]}' \ http://localhost:9944 - -# Returns session keys as a hex string -# Example: "0x1234567890abcdef..." ``` -**Save the session keys** - you'll need them for on-chain registration. - -**Note**: Session keys are stored in the node's database. If you wipe the database, you'll need to generate new keys. +This command returns session keys as a hexstring in the terminal. You must save these session keys as you'll need them for on-chain registration. As session keys are stored in the node's database, if you wipe the database, you'll also need to generate new keys. -## Registration and Governance +## Register Collator for Selection -### Understanding Collator Selection +System parachains use different collator selection mechanisms. Explore the following tabs to see how mechanisms compare and determine the most suitable mechanism for registering your collator. -System parachains use different collator selection mechanisms: +=== "Invulnerables List" -**Invulnerables List**: + - Fixed list of collators approved through governance. + - Most common for system parachains. + - Requires governance proposal and approval. -- Fixed list of collators approved through governance -- Most common for system parachains -- Requires governance proposal and approval -**On-chain Selection**: +=== "On-chain Selection" -- Some parachains use pallet-collator-selection -- May require bonding tokens -- Automatic selection based on criteria + - Some parachains use pallet-collator-selection. + - May require bonding tokens. + - Automatic selection based on criteria. -**Fellowship Decisions**: +=== "Fellowship Decisions" -- Technical Fellowship may manage some system parachain collators -- Requires Fellowship membership or approval + - Technical Fellowship may manage some system parachain collators. + - Requires Fellowship membership or approval. ### Registration Process -The registration process varies by system parachain. General steps: - -#### 1. Check Current Collators - -Check the existing collators for your target parachain: - -```bash -# Using Polkadot.js Apps -# Connect to your target system parachain -# Go to Developer > Chain State -# Query: collatorSelection.invulnerables() or similar -``` - -#### 2. Prepare Governance Proposal - -For invulnerables-based selection: - -1. **Draft proposal**: Explain why you should be added as a collator -2. **Technical details**: Provide your session keys and account ID -3. **Infrastructure**: Describe your hardware and monitoring setup -4. **Experience**: Detail your relevant experience - -Submit to: -- Polkadot Forum: https://forum.polkadot.network -- Relevant governance channels - -#### 3. Set Session Keys On-Chain - -Once approved (or if using on-chain selection), set your session keys: - -**Using Polkadot.js Apps:** - -1. Navigate to Polkadot.js Apps and connect to your system parachain -2. Go to **Developer > Extrinsics** -3. Select your account -4. Choose `session.setKeys` extrinsic -5. Enter: - - `keys`: Your session keys (from `author_rotateKeys`) - - `proof`: 0x00 (typically) -6. Submit and sign the transaction - -**Using CLI (alternative):** - -```bash -# This varies by parachain - consult specific documentation -``` - -#### 4. Bond Tokens (if required) - -Some parachains require bonding tokens: - -1. Go to **Developer > Extrinsics** -2. Select `collatorSelection.registerAsCandidate` (if available) -3. Submit with required bond amount -4. Sign transaction - -#### 5. Await Governance Approval - -If using invulnerables: - -- Wait for governance vote -- Monitor forum and announcements -- Once approved, you'll be added to the invulnerables list -- Your collator will begin producing blocks in the next session/era - -### Verify Collator Status - -Check if your collator is active by monitoring logs for block production messages like "Prepared block for proposing" and "Imported #123". See the [Log Management](#log-management) section for log viewing commands. - -## Monitoring and Maintenance - -### Essential Monitoring - -**Block Production**: -```bash -# Monitor block production -sudo journalctl -u polkadot-collator | grep -i "prepared block" -``` - -**Peer Connections**: - -- Maintain a sufficient amount of peers for good connectivity -- Check peer count in logs - -**Resource Usage**: - -- Monitor CPU, RAM, and disk I/O -- Set up alerts for high usage - -**Sync Status**: - -- Ensure both chains stay synced -- Alert on sync issues +The registration process varies by system parachain. General steps include the following: + +1. Check the existing collators for your target parachain: + + 1. Navigate to Polkadot.js Apps and connect to your system parachain. + 2. Locate **Developer > Chain State**. + 3. Query `collatorSelection.invulnerables()` + +2. Prepare a governance proposal for invulnerables-based selection including the following information: + - **Draft proposal**: Explain why you should be added as a collator + - **Technical details**: Provide your session keys and account ID + - **Infrastructure**: Describe your hardware and monitoring setup + - **Experience**: Detail your relevant experience + + Submit the proposal to the relevant governance channels on the [Polkadot Forum](https://forum.polkadot.network){target=\_blank}. + +3. Once approved (or if using on-chain selection), follow these steps to register session keys using Polkadot.js Apps: + 1. Navigate to Polkadot.js Apps and connect to your system parachain. + 2. Locate **Developer > Extrinsics**. + 3. Select your account. + 4. Choose the `session.setKeys` extrinsic. + 5. Enter the following information: + - `keys`: Your session keys (from `author_rotateKeys`) + - `proof`: 0x00 (typically) + 6. Submit and sign the transaction. + +4. If the parachain requires bonding tokens, use the follow these steps to submit them using Polkadot.js Apps: + 1. Locate **Developer > Extrinsics**. + 2. Select `collatorSelection.registerAsCandidate`. + 3. Submit the transaction with the required bond amount. + 4. Sign the transaction. + +5. If applying to join the invulnerables list, you must now await governance approval for your proposal. Monitor the [Polkadot Forum](https://forum.polkadot.network){target=\_blank} governance channels and announcements. Once approved, your collator is added to the invulnerables list and will begin producing blocks in the next session or era. + +6. Verify your collator is active by monitoring logs for block production messages like "Prepared block for proposing" and "Imported #123". See the [Log Management](#log-management) section for log viewing commands. + +## Monitor and Maintain Your Collator + +Monitoring the following items will help ensure your collator runs efficiently to avoid service interruptions or down time: + +- **Block Production**: monitor for block production using the following command: + ```bash + sudo journalctl -u polkadot-collator | grep -i "prepared block" + ``` +- **Peer Connections**: Maintain a sufficient amount of peers for good connectivity and set up alerts to notify if peer connections falls below ten. +- **Resource Usage**: Monitor CPU, RAM, and disk I/O and set up alerts for unusual or high usage. +- **Sync Status**: Ensure both chains stay synced and set up alerts for sync issues. ### Prometheus Metrics -Metrics available at `http://localhost:9615/metrics` +You can use the following information to configure [Prometheus](https://prometheus.io/docs/introduction/first_steps/){target=\_blank} to monitor, collect, and store your collator node metrics: -Example Prometheus configuration: -{% raw %} -```yaml -scrape_configs: - - job_name: 'polkadot-collator' - static_configs: - - targets: ['localhost:9615'] -``` -{% endraw %} +- **URL**: Metrics are available to view at `http://localhost:9615/metrics` +- **Example Prometheus configuration**: Update your `prometheus.yml` to add the following code: + {% raw %} + ```yaml + scrape_configs: + - job_name: 'polkadot-collator' + static_configs: + - targets: ['localhost:9615'] + ``` + {% endraw %} -Key metrics to monitor: +Key metrics to monitor via Prometheus include the following: - `substrate_block_height`: Current block height - `substrate_finalized_height`: Finalized block height - `substrate_peers_count`: Peer connections - `substrate_ready_transactions_number`: Transaction queue -### Setting Up Alerts - -Configure alerts for: - -- Service failures -- Sync issues -- Low peer count (< 10 peers) -- Block production gaps -- High resource usage -- Disk space low -### Log Management +## Log Management -```bash -# View recent logs -sudo journalctl -u polkadot-collator -n 100 - -# Follow logs in real-time -sudo journalctl -u polkadot-collator -f - -# Filter for errors -sudo journalctl -u polkadot-collator | grep -i error +Effecient log management is essential to ensure collator performance and uptime. Use the following commands to help you manage logs to monitor and maintain your collator: -# Filter for block production -sudo journalctl -u polkadot-collator | grep -i "imported" -``` +- View recent logs: + ```bash + sudo journalctl -u polkadot-collator -n 100 + ``` +- Follow logs in real-time: + ```bash + sudo journalctl -u polkadot-collator -f + ``` +- Filter for errors: + ```bash + sudo journalctl -u polkadot-collator | grep -i error + ``` +- Filter for block production: + ```bash + sudo journalctl -u polkadot-collator | grep -i "imported" + ``` -### Database Maintenance +## Database Maintenance -Check database size: +You can check database size using the following command: ```bash -# Check database size du -sh /var/lib/polkadot-collator ``` - -The node handles pruning automatically. - -### Updates and Upgrades - -**Runtime Upgrades**: - -- Automatic via on-chain governance -- No manual action required -- Monitor announcements for breaking changes - -**Client Upgrades**: - -- Require manual binary update -- Subscribe to announcements: - - Polkadot Forum - - Fellowship GitHub - - Matrix channels - -**Upgrade Procedure (Bare-Metal)**: - -```bash -# Stop the service -sudo systemctl stop polkadot-collator - -# Backup data (recommended) -sudo cp -r /var/lib/polkadot-collator /var/lib/polkadot-collator.backup - -# Pull new image and extract binary -docker pull parity/polkadot-parachain: -docker create --name temp-parachain parity/polkadot-parachain: -sudo docker cp temp-parachain:/usr/local/bin/polkadot-parachain /usr/local/bin/ -docker rm temp-parachain - -# Verify version -polkadot-parachain --version - -# Restart service -sudo systemctl start polkadot-collator - -# Verify service is running -sudo systemctl status polkadot-collator -``` - -**Upgrade Procedure (Docker)**: - -```bash -# Stop the service -sudo systemctl stop polkadot-collator - -# Backup data (recommended) -sudo cp -r /var/lib/polkadot-collator /var/lib/polkadot-collator.backup - -# Pull new image -docker pull parity/polkadot-parachain: - -# Update the image tag in /etc/systemd/system/polkadot-collator.service - -# Reload systemd and restart -sudo systemctl daemon-reload -sudo systemctl start polkadot-collator - -# Verify service is running -sudo systemctl status polkadot-collator -``` - -**Note**: For log monitoring, see the [Log Management](#log-management) section. +The collator node handles pruning automatically. + +## Updates and Upgrades + +Updates or upgrades can happen on either the runtime or client. Runtime upgrades happen automatically via on-chain governance and do not require manual action on your part. Client upgrades do require a manual binary update process performed via terminal commands as follows: + +=== "Docker Setup" + + 1. Stop the service: + ```bash + sudo systemctl stop polkadot-collator + ``` + + 2. Backup data (recommended): + ```bash + sudo cp -r /var/lib/polkadot-collator /var/lib/polkadot-collator.backup + ``` + + 3. Pull the new Docker image: + ```bash + docker pull parity/polkadot-parachain: + ``` + + 4. Update the image tag in your systemd service file: + ```bash + sudo nano /etc/systemd/system/polkadot-collator.service + ``` + + 5. Reload systemd and restart the service: + ```bash + sudo systemctl daemon-reload + sudo systemctl start polkadot-collator + ``` + + 6. Verify the service is running: + ```bash + sudo systemctl status polkadot-collator + ``` + +=== "Manual Setup" + + 1. Stop the service: + ```bash + sudo systemctl stop polkadot-collator + ``` + + 2. Backup data (recommended): + ```bash + sudo cp -r /var/lib/polkadot-collator /var/lib/polkadot-collator.backup + ``` + + 3. Pull the new image and extract the binary: + ```bash + docker pull parity/polkadot-parachain: + docker create --name temp-parachain parity/polkadot-parachain: + sudo docker cp temp-parachain:/usr/local/bin/polkadot-parachain /usr/local/bin/ + docker rm temp-parachain + ``` + + 4. Verify `polkadot-parachain` version to confirm successful update: + ```bash + polkadot-parachain --version + ``` + + 5. Restart the service: + ```bash + sudo systemctl start polkadot-collator + ``` + + 6. Verify the service is running: + ```bash + sudo systemctl status polkadot-collator + ``` ## Conclusion Running a collator node is essential for parachain operation and network security. By following this guide, you have set up a production-ready collator that: -- Produces blocks for your parachain and maintains network consensus -- Implements comprehensive security measures to protect keys and operations -- Supports robust monitoring and alerting for reliable performance -- Follows best practices for both Docker and systemd deployments +- Produces blocks for your parachain and maintains network consensus. +- Implements comprehensive security measures to protect keys and operations. +- Supports robust monitoring and alerting for reliable performance. +- Follows best practices for both Docker and systemd deployments. As a collator operator, you play a vital role in your parachain's infrastructure. Regular maintenance, security updates, and monitoring will ensure your collator continues to perform reliably. Stay engaged with your parachain community and keep up with updates to maintain optimal performance and security. diff --git a/.ai/pages/node-infrastructure-run-a-node-polkadot-hub-rpc.md b/.ai/pages/node-infrastructure-run-a-node-polkadot-hub-rpc.md index 7a8368545..e1dab7997 100644 --- a/.ai/pages/node-infrastructure-run-a-node-polkadot-hub-rpc.md +++ b/.ai/pages/node-infrastructure-run-a-node-polkadot-hub-rpc.md @@ -1,6 +1,6 @@ --- title: Run an RPC Node for Polkadot Hub -description: Complete guide to set up and run an RPC node for Polkadot Hub with Polkadot SDK RPC endpoints. +description: Follow this guide to understand hardware and software requirements and how to set up and run an RPC node for Polkadot Hub with Polkadot SDK RPC endpoints. categories: Infrastructure url: https://docs.polkadot.com/node-infrastructure/run-a-node/polkadot-hub-rpc/ --- @@ -20,13 +20,15 @@ Running an RPC node for Polkadot Hub enables applications, wallets, and users to This setup enables block explorer indexing and provides full compatibility with Polkadot SDK development tools. -**Important Note**: The parameters and configurations in this guide are provided as illustrative examples. You may need to modify them according to your specific environment, hardware capabilities, and network conditions. +!!! note + + The parameters and configurations in this guide are provided as illustrative examples. You may need to modify them according to your specific environment, hardware capabilities, and network conditions. ## Prerequisites ### Hardware Requirements -RPC nodes serving production traffic require robust hardware: +RPC nodes serving production traffic require robust hardware. The following should be considered the minimum standard to effectively operate an RPC node: - **CPU**: 8+ cores (16+ cores for high traffic) - **Memory**: 64 GB RAM minimum (128 GB recommended for high traffic) @@ -58,417 +60,366 @@ Required software: ## Setup Options -This guide provides two deployment options: - -1. **Docker-based Setup**: Simpler to set up and maintain -2. **Manual/Systemd Setup**: For production environments requiring more control - -Choose the option that best fits your needs. - ---- - -## Option 1: Docker-Based Setup - -This option uses Docker containers for the Polkadot SDK node, making it easy to set up and manage. - -### Step 1: Download Chain Specification - -Download the official Polkadot Hub (formerly known as Asset Hub) chain specification: - -```bash -curl -L https://raw.githubusercontent.com/paritytech/polkadot-sdk/master/cumulus/parachains/chain-specs/asset-hub-polkadot.json -o asset-hub-polkadot.json -``` - -**Note**: This chain specification is the official configuration file that defines the network parameters for Polkadot Hub. - -### Step 2: Download Database Snapshots (Optional but Recommended) - -Using pre-synchronized snapshots significantly reduces initial sync time from several days to just a few hours. You need to download both parachain and relay chain data. - -**Snapshot Provider**: https://snapshots.polkadot.io/ - -#### Create Directories - -```bash -mkdir -p my-node-data/chains/asset-hub-polkadot/db -mkdir -p my-node-data/chains/polkadot/db -``` - -#### Download Polkadot Hub Parachain Snapshot - -Choose between archive (complete history) or pruned (recent state) snapshots: - -**Archive Snapshot** (recommended for RPC with historical data): - -```bash -# Check https://snapshots.polkadot.io/ for the latest snapshot URL -export SNAPSHOT_URL_ASSET_HUB="https://snapshots.polkadot.io/polkadot-asset-hub-rocksdb-archive/LATEST" - -rclone copyurl $SNAPSHOT_URL_ASSET_HUB/files.txt files.txt -rclone copy --progress --transfers 20 \ - --http-url $SNAPSHOT_URL_ASSET_HUB \ - --no-traverse --http-no-head --disable-http2 \ - --inplace --no-gzip-encoding --size-only \ - --retries 6 --retries-sleep 10s \ - --files-from files.txt :http: my-node-data/chains/asset-hub-polkadot/db/ - -rm files.txt -``` - -**Parameter Explanation**: - -- `--transfers 20`: Uses 20 parallel transfers for faster download -- `--retries 6`: Automatically retries failed transfers up to 6 times -- `--retries-sleep 10s`: Waits 10 seconds between retry attempts -- `--size-only`: Only transfers if sizes differ (prevents unnecessary re-downloads) - -#### Download Polkadot Relay Chain Snapshot - -**Pruned Snapshot** (recommended for RPC nodes): - -```bash -# Check https://snapshots.polkadot.io/ for the latest snapshot URL -export SNAPSHOT_URL_RELAY="https://snapshots.polkadot.io/polkadot-rocksdb-prune/LATEST" - -rclone copyurl $SNAPSHOT_URL_RELAY/files.txt files.txt -rclone copy --progress --transfers 20 \ - --http-url $SNAPSHOT_URL_RELAY \ - --no-traverse --http-no-head --disable-http2 \ - --inplace --no-gzip-encoding --size-only \ - --retries 6 --retries-sleep 10s \ - --files-from files.txt :http: my-node-data/chains/polkadot/db/ - -rm files.txt -``` - -**Alternative Options**: - -- Pruned snapshot: `polkadot-rocksdb-prune` (smaller size, recent state) -- Archive snapshot: `polkadot-rocksdb-archive` (complete history, larger size) - -### Step 3: Start Polkadot Hub Node - -Launch the node using the official Parity Docker image: - -**Docker Image**: https://hub.docker.com/r/parity/polkadot-parachain - -```bash -docker run -d --name polkadot-hub-rpc --restart unless-stopped \ - -p 9944:9944 \ - -p 9933:9933 \ - -p 9615:9615 \ - -p 30334:30334 \ - -p 30333:30333 \ - -v $(pwd)/asset-hub-polkadot.json:/asset-hub-polkadot.json \ - -v $(pwd)/my-node-data:/data \ - parity/polkadot-parachain:stable2509-2 \ - --name=PolkadotHubRPC \ - --base-path=/data \ - --chain=/asset-hub-polkadot.json \ - --prometheus-external \ - --prometheus-port 9615 \ - --unsafe-rpc-external \ - --rpc-port=9944 \ - --rpc-cors=all \ - --rpc-methods=safe \ - --rpc-max-connections=1000 \ - --state-pruning=archive \ - --blocks-pruning=archive \ - -- \ - --base-path=/data \ - --chain=polkadot \ - --state-pruning=256 \ - --blocks-pruning=archive-canonical -``` - -**Critical Configuration Parameters**: - -**Port Mappings**: - -- `9944`: Polkadot SDK RPC endpoint (WebSocket/HTTP) -- `9933`: Polkadot SDK HTTP RPC endpoint -- `9615`: Prometheus metrics endpoint -- `30333/30334`: P2P networking ports - -**Node Parameters**: - -- `--unsafe-rpc-external`: Enables external RPC access -- `--rpc-cors=all`: Allows all origins for CORS -- `--rpc-methods=safe`: Only allows safe RPC methods -- `--state-pruning=archive`: Keeps complete state history -- `--blocks-pruning=archive`: Keeps all block data -- `--prometheus-external`: Exposes metrics externally - -**Security Warning**: The `--unsafe-rpc-external` flag should only be used in development or properly secured environments. For production, use a reverse proxy with authentication. - -### Step 4: Monitor Synchronization - -Monitor the node synchronization status: - -```bash -# Check sync status -curl -H "Content-Type: application/json" \ - -d '{"id":1, "jsonrpc":"2.0", "method": "system_syncState", "params":[]}' \ - http://localhost:9944 -``` - -**Expected Response Format**: - -```json -{ - "jsonrpc":"2.0", - "id":1, - "result":{ - "startingBlock":0, - "currentBlock":3394816, - "highestBlock":3394816 - } -} -``` - -**Synchronization Status**: - -- **In Progress**: `currentBlock` < `highestBlock` -- **Complete**: `currentBlock` = `highestBlock` - -### Step 5: Verify Setup - -Let's verify the Polkadot SDK RPC endpoint is working correctly. - -#### API Endpoint - -**Polkadot SDK RPC (Port 9944)**: - -- WebSocket: `ws://your-server:9944` -- HTTP: `http://your-server:9944` -- Purpose: Full Polkadot SDK API access for parachain data -- Use Cases: Polkadot SDK applications, parachain-specific operations - -#### Polkadot SDK RPC Tests - -**Get Chain Information**: - -```bash -curl -H "Content-Type: application/json" \ - -d '{"id":1, "jsonrpc":"2.0", "method": "system_chain", "params":[]}' \ - http://localhost:9944 -``` - -**Get Latest Block**: - -```bash -curl -H "Content-Type: application/json" \ - -d '{"id":1, "jsonrpc":"2.0", "method": "chain_getHeader", "params":[]}' \ - http://localhost:9944 -``` - -**Get Node Health**: - -```bash -curl -H "Content-Type: application/json" \ - -d '{"id":1, "jsonrpc":"2.0", "method": "system_health", "params":[]}' \ - http://localhost:9944 -``` - -### Managing Docker Containers - -**View logs**: - -```bash -# View node logs -docker logs -f polkadot-hub-rpc -``` - -**Stop container**: - -```bash -docker stop polkadot-hub-rpc -``` - -**Start container**: - -```bash -docker start polkadot-hub-rpc -``` - -**Remove container**: - -```bash -docker rm polkadot-hub-rpc -``` - -**Note**: For update procedures, see the [Updates and Upgrades](#updates-and-upgrades) section. - ---- - -## Option 2: Manual/Systemd Setup - -This option provides more control and is recommended for production environments requiring custom configurations. - -### Step 1: Install the Polkadot Parachain Binary - -Extract the binary from the official Docker image: - -```bash -# Pull the image and extract binary -docker pull parity/polkadot-parachain:stable2509-2 -docker create --name temp-parachain parity/polkadot-parachain:stable2509-2 -sudo docker cp temp-parachain:/usr/local/bin/polkadot-parachain /usr/local/bin/ -docker rm temp-parachain - -# Verify installation -polkadot-parachain --version -``` - -Check [Docker Hub](https://hub.docker.com/r/parity/polkadot-parachain/tags) for the latest stable tags. - -### Step 2: Obtain Chain Specification - -Download the Polkadot Hub chain specification: - -```bash -curl -L https://raw.githubusercontent.com/paritytech/polkadot-sdk/master/cumulus/parachains/chain-specs/asset-hub-polkadot.json -o asset-hub-polkadot.json -``` - -### Step 3: Create User and Directory Structure - -```bash -# Create dedicated user -sudo useradd -r -s /bin/bash polkadot - -# Create data directory -sudo mkdir -p /var/lib/polkadot-hub-rpc - -# Copy chain spec to the directory -sudo cp asset-hub-polkadot.json /var/lib/polkadot-hub-rpc/ - -# Set permissions -sudo chown -R polkadot:polkadot /var/lib/polkadot-hub-rpc -``` - -### Step 4: Create Systemd Service - -Create a service file for the Polkadot SDK RPC node: - -```bash -sudo nano /etc/systemd/system/polkadot-hub-rpc.service -``` - -Add the following configuration: - -```ini -[Unit] -Description=Polkadot Hub RPC Node -After=network.target - -[Service] -Type=simple -User=polkadot -Group=polkadot -WorkingDirectory=/var/lib/polkadot-hub-rpc - -ExecStart=/usr/local/bin/polkadot-parachain \ - --name=PolkadotHubRPC \ - --chain=/var/lib/polkadot-hub-rpc/asset-hub-polkadot.json \ - --base-path=/var/lib/polkadot-hub-rpc \ - --port=30333 \ - --rpc-port=9944 \ - --rpc-external \ - --rpc-cors=all \ - --rpc-methods=safe \ - --rpc-max-connections=1000 \ - --prometheus-port=9615 \ - --prometheus-external \ - --state-pruning=archive \ - --blocks-pruning=archive \ - -- \ - --chain=polkadot \ - --base-path=/var/lib/polkadot-hub-rpc \ - --port=30334 \ - --state-pruning=256 \ - --blocks-pruning=archive-canonical - -Restart=always -RestartSec=10 -LimitNOFILE=65536 - -[Install] -WantedBy=multi-user.target -``` - -### Step 5: Start Service - -```bash -# Reload systemd -sudo systemctl daemon-reload - -# Enable service to start on boot -sudo systemctl enable polkadot-hub-rpc - -# Start the Polkadot SDK node -sudo systemctl start polkadot-hub-rpc - -# Check status and wait for sync -sudo systemctl status polkadot-hub-rpc -sudo journalctl -u polkadot-hub-rpc -f -``` - -### Step 6: Verify Setup - -Use the same verification tests as in the Docker setup (see Step 5 above). - ---- - -## Monitoring and Maintenance - -### Log Management - -**Docker Setup**: - -```bash -# View node logs -docker logs -f polkadot-hub-rpc -``` - -**Systemd Setup**: - -```bash -# View node logs -sudo journalctl -u polkadot-hub-rpc -f - -# View recent logs -sudo journalctl -u polkadot-hub-rpc -n 100 - -# Filter for errors -sudo journalctl -u polkadot-hub-rpc | grep -i error -``` - -### Performance Monitoring - -Monitor key metrics: - -- **Sync status**: Ensure node stays fully synced -- **Peer connections**: Maintain 30+ peers for good connectivity -- **Resource usage**: Monitor CPU, RAM, and disk I/O -- **RPC request latency**: Track response times for the Polkadot SDK API -- **Connection count**: Monitor active RPC connections - -**Prometheus Metrics**: - -Metrics are available at `http://localhost:9615/metrics` - -Example Prometheus scrape configuration: - -{% raw %} -```yaml -scrape_configs: - - job_name: 'polkadot-hub-rpc' - static_configs: - - targets: ['localhost:9615'] -``` -{% endraw %} - -**Key Metrics to Monitor**: +This guide provides two options for deployment: + +- **Docker-based Setup**: Best for simpler set up and maintenance +- **Manual/systemd Setup**: Best for production environments requiring more control + +Select the best option for your project, then use the steps in the following tabs to complete set up. + +=== "Docker-Based Setup" + + This option uses Docker containers for the Polkadot SDK node, making it easy to set up and manage. Follow these steps to set your RPC node using Docker: + + 1. Download the official Polkadot Hub (formerly known as Asset Hub) chain specification: + ```bash + curl -L https://raw.githubusercontent.com/paritytech/polkadot-sdk/master/cumulus/parachains/chain-specs/asset-hub-polkadot.json -o asset-hub-polkadot.json + ``` + + !!! note + + This chain specification is the official configuration file that defines the network parameters for Polkadot Hub. + + 2. (Optional but recommended) Download database snapshots + - Using pre-synchronized snapshots significantly reduces initial sync time from several days to just a few hours. You need to download both parachain and relay chain data. + - You can obtain the latest snapshot from the [Snapshot Provider](https://snapshots.polkadot.io/){target=\_blank}. Follow these steps to download and use snapshots: + 1. Create new directories with the following commands: + ```bash + mkdir -p my-node-data/chains/asset-hub-polkadot/db + mkdir -p my-node-data/chains/polkadot/db + ``` + 2. Download the appropriate snapshot using the following commands: + + === "Archive snapshot" + + Contains complete history, recommended for RPC with historical data. + ```bash + # Check https://snapshots.polkadot.io/ for the latest snapshot URL + export SNAPSHOT_URL_ASSET_HUB="https://snapshots.polkadot.io/polkadot-asset-hub-rocksdb-archive/LATEST" + + rclone copyurl $SNAPSHOT_URL_ASSET_HUB/files.txt files.txt + rclone copy --progress --transfers 20 \ + --http-url $SNAPSHOT_URL_ASSET_HUB \ + --no-traverse --http-no-head --disable-http2 \ + --inplace --no-gzip-encoding --size-only \ + --retries 6 --retries-sleep 10s \ + --files-from files.txt :http: my-node-data/chains/asset-hub-polkadot/db/ + + rm files.txt + ``` + + - `--transfers 20`: Uses 20 parallel transfers for faster download. + - `--retries 6`: Automatically retries failed transfers up to 6 times. + - `--retries-sleep 10s`: Waits 10 seconds between retry attempts. + - `--size-only`: Only transfers if sizes differ (prevents unnecessary re-downloads). + + === "Pruned snapshot" + + Contains recent state for a smaller package size, recommended for RPC nodes. + ```bash + # Check https://snapshots.polkadot.io/ for the latest snapshot URL + export SNAPSHOT_URL_RELAY="https://snapshots.polkadot.io/polkadot-rocksdb-prune/LATEST" + + rclone copyurl $SNAPSHOT_URL_RELAY/files.txt files.txt + rclone copy --progress --transfers 20 \ + --http-url $SNAPSHOT_URL_RELAY \ + --no-traverse --http-no-head --disable-http2 \ + --inplace --no-gzip-encoding --size-only \ + --retries 6 --retries-sleep 10s \ + --files-from files.txt :http: my-node-data/chains/polkadot/db/ + + rm files.txt + ``` + 3. Launch Polkadot Hub Node using the official [Parity Docker image](https://hub.docker.com/r/parity/polkadot-parachain){target=\_blank} with the following command: + ```bash + docker run -d --name polkadot-hub-rpc --restart unless-stopped \ + -p 9944:9944 \ + -p 9933:9933 \ + -p 9615:9615 \ + -p 30334:30334 \ + -p 30333:30333 \ + -v $(pwd)/asset-hub-polkadot.json:/asset-hub-polkadot.json \ + -v $(pwd)/my-node-data:/data \ + parity/polkadot-parachain:stable2509-2 \ + --name=PolkadotHubRPC \ + --base-path=/data \ + --chain=/asset-hub-polkadot.json \ + --prometheus-external \ + --prometheus-port 9615 \ + --unsafe-rpc-external \ + --rpc-port=9944 \ + --rpc-cors=all \ + --rpc-methods=safe \ + --rpc-max-connections=1000 \ + --state-pruning=archive \ + --blocks-pruning=archive \ + -- \ + --base-path=/data \ + --chain=polkadot \ + --state-pruning=256 \ + --blocks-pruning=archive-canonical + ``` + + Critical configuration parameters include port mappings and node parameters: + + === "Port mappings" + + - `9944`: Polkadot SDK RPC endpoint (WebSocket/HTTP) + - `9933`: Polkadot SDK HTTP RPC endpoint + - `9615`: Prometheus metrics endpoint + - `30333/30334`: P2P networking ports + + === "Node parameters" + + - `--unsafe-rpc-external`: Enables external RPC access + - `--rpc-cors=all`: Allows all origins for CORS + - `--rpc-methods=safe`: Only allows safe RPC methods + - `--state-pruning=archive`: Keeps complete state history + - `--blocks-pruning=archive`: Keeps all block data + - `--prometheus-external`: Exposes metrics externally + + !!! warning + + The `--unsafe-rpc-external` flag should only be used in development or properly secured environments. For production, use a reverse proxy with authentication. + + 4. Monitor the node synchronization status using the following command: + ```bash + curl -H "Content-Type: application/json" \ + -d '{"id":1, "jsonrpc":"2.0", "method": "system_syncState", "params":[]}' \ + http://localhost:9944 + ``` + + You should see a response similar to the following: + + ```json + { + "jsonrpc":"2.0", + "id":1, + "result":{ + "startingBlock":0, + "currentBlock":3394816, + "highestBlock":3394816 + } + } + ``` + + When synchronization is complete, `currentBlock` will be equal to `highestBlock`. + + 5. You can use a few different commands to verify your node is running properly: + + - Get chain information: + ```bash + curl -H "Content-Type: application/json" \ + -d '{"id":1, "jsonrpc":"2.0", "method": "system_chain", "params":[]}' \ + http://localhost:9944 + ``` + - Get the latest block: + ```bash + curl -H "Content-Type: application/json" \ + -d '{"id":1, "jsonrpc":"2.0", "method": "chain_getHeader", "params":[]}' \ + http://localhost:9944 + ``` + - Query node health: + ```bash + curl -H "Content-Type: application/json" \ + -d '{"id":1, "jsonrpc":"2.0", "method": "system_health", "params":[]}' \ + http://localhost:9944 + ``` + + 6. Use the following commands to manage your Docker containers: + + - View node logs: + ```bash + docker logs -f polkadot-hub-rpc + ``` + - Stop container: + ```bash + docker stop polkadot-hub-rpc + ``` + - Start container: + ```bash + docker start polkadot-hub-rpc + ``` + - Remove container: + ```bash + docker rm polkadot-hub-rpc + ``` + +=== "Manual systemd Setup" + + This option provides more control and is recommended for production environments requiring custom configurations. + + 1. Install the Polkadot Parachain binary by extracting it from the official Docker image: + ```bash + # Pull the image and extract binary + docker pull parity/polkadot-parachain:stable2509-2 + docker create --name temp-parachain parity/polkadot-parachain:stable2509-2 + sudo docker cp temp-parachain:/usr/local/bin/polkadot-parachain /usr/local/bin/ + docker rm temp-parachain + + # Verify installation + polkadot-parachain --version + ``` + + Check [Docker Hub](https://hub.docker.com/r/parity/polkadot-parachain/tags){target=\_blank} for the latest stable tags. + + 2. Download the Polkadot Hub chain specification: + ```bash + curl -L https://raw.githubusercontent.com/paritytech/polkadot-sdk/master/cumulus/parachains/chain-specs/asset-hub-polkadot.json -o asset-hub-polkadot.json + ``` + + 3. Create user and directory structures using the following commands: + - Create a dedicated user: + ```bash + sudo useradd -r -s /bin/bash polkadot + ``` + - Create data directory: + ```bash + sudo mkdir -p /var/lib/polkadot-hub-rpc + ``` + - Copy the chain spec to the directory: + ```bash + sudo cp asset-hub-polkadot.json /var/lib/polkadot-hub-rpc/ + ``` + - Set permissions: + ```bash + sudo chown -R polkadot:polkadot /var/lib/polkadot-hub-rpc + ``` + + 4. Create a systemd service file for the Polkadot SDK RPC node: + ```bash + sudo nano /etc/systemd/system/polkadot-hub-rpc.service + ``` + + 5. Open the new service file and add the following configuration: + ```ini + [Unit] + Description=Polkadot Hub RPC Node + After=network.target + + [Service] + Type=simple + User=polkadot + Group=polkadot + WorkingDirectory=/var/lib/polkadot-hub-rpc + + ExecStart=/usr/local/bin/polkadot-parachain \ + --name=PolkadotHubRPC \ + --chain=/var/lib/polkadot-hub-rpc/asset-hub-polkadot.json \ + --base-path=/var/lib/polkadot-hub-rpc \ + --port=30333 \ + --rpc-port=9944 \ + --rpc-external \ + --rpc-cors=all \ + --rpc-methods=safe \ + --rpc-max-connections=1000 \ + --prometheus-port=9615 \ + --prometheus-external \ + --state-pruning=archive \ + --blocks-pruning=archive \ + -- \ + --chain=polkadot \ + --base-path=/var/lib/polkadot-hub-rpc \ + --port=30334 \ + --state-pruning=256 \ + --blocks-pruning=archive-canonical + + Restart=always + RestartSec=10 + LimitNOFILE=65536 + + [Install] + WantedBy=multi-user.target + ``` + + 6. Start the service using the following commands: + - Reload systemd: + ```bash + sudo systemctl daemon-reload + ``` + - Enable service to start on boot: + ```bash + sudo systemctl enable polkadot-hub-rpc + ``` + - Start the Polkadot SDK node: + ```bash + sudo systemctl start polkadot-hub-rpc + ``` + - Check status and wait for sync: + ```bash + sudo systemctl status polkadot-hub-rpc + sudo journalctl -u polkadot-hub-rpc -f + ``` + + 7. You can use a few different commands to verify your node is running properly: + - Get chain information: + ```bash + curl -H "Content-Type: application/json" \ + -d '{"id":1, "jsonrpc":"2.0", "method": "system_chain", "params":[]}' \ + http://localhost:9944 + ``` + - Get the latest block: + ```bash + curl -H "Content-Type: application/json" \ + -d '{"id":1, "jsonrpc":"2.0", "method": "chain_getHeader", "params":[]}' \ + http://localhost:9944 + ``` + - Query node health: + ```bash + curl -H "Content-Type: application/json" \ + -d '{"id":1, "jsonrpc":"2.0", "method": "system_health", "params":[]}' \ + http://localhost:9944 + ``` + +## Monitor and Maintain RPC Node + +There are a few key monitoring and maintenance commands that can help you ensure RPC node uptime and performance including log monitoring and metrics. + +To view node logs, use the appropriate command for your setup: + +=== "Docker Setup" + + ```bash + docker logs -f polkadot-hub-rpc + ``` + +=== "systemd Setup" + + - View node logs: + ```bash + sudo journalctl -u polkadot-hub-rpc -f + ``` + - View recent logs: + ```bash + sudo journalctl -u polkadot-hub-rpc -n 100 + ``` + - Filter for errors: + ```bash + sudo journalctl -u polkadot-hub-rpc | grep -i error + ``` + +Monitoring key metrics like the following items can help you stay up to date on the performance and health of your node and allow you to intervene at the first sign of issues: + +- **Sync status**: Ensure node stays fully synced. +- **Peer connections**: Maintain 30+ peers for good connectivity. +- **Resource usage**: Monitor CPU, RAM, and disk I/O. +- **RPC request latency**: Track response times for the Polkadot SDK API. +- **Connection count**: Monitor active RPC connections. + +You can use the following information to configure [Prometheus](https://prometheus.io/docs/introduction/first_steps/){target=\_blank} to monitor, collect, and store your RPC node metrics: + +- **URL**: Metrics are available to view at `http://localhost:9615/metrics` +- **Example Prometheus configuration**: Update your `prometheus.yml` to add the following code: + {% raw %} + ```yaml + scrape_configs: + - job_name: 'polkadot-hub-rpc' + static_configs: + - targets: ['localhost:9615'] + ``` + {% endraw %} + +Key metrics to monitor via Prometheus include: - `substrate_block_height`: Current block height - `substrate_finalized_height`: Finalized block height @@ -477,59 +428,68 @@ scrape_configs: ### Database Maintenance -Check database size periodically: - -```bash -# Docker setup -du -sh my-node-data - -# Systemd setup -du -sh /var/lib/polkadot-hub-rpc -``` +Check database size periodically using the commands for your selected setup: -The node handles pruning automatically based on configuration unless running in archive mode. - -### Updates and Upgrades - -**Docker Setup**: +=== "Docker Setup" -```bash -# Pull latest image -docker pull parity/polkadot-parachain: + ```bash + du -sh my-node-data + ``` -# Restart container -docker stop polkadot-hub-rpc -docker rm polkadot-hub-rpc +=== "systemd Setup" -# Start new container (use same command from setup with updated image tag) -``` + ```bash + du -sh /var/lib/polkadot-hub-rpc + ``` -**Systemd Setup**: - -```bash -# Stop service -sudo systemctl stop polkadot-hub-rpc - -# Backup data -sudo cp -r /var/lib/polkadot-hub-rpc /var/lib/polkadot-hub-rpc.backup +The node handles pruning automatically based on configuration unless running in archive mode. -# Pull new image and extract binary -docker pull parity/polkadot-parachain: -docker create --name temp-parachain parity/polkadot-parachain: -sudo docker cp temp-parachain:/usr/local/bin/polkadot-parachain /usr/local/bin/ -docker rm temp-parachain +### Updates and Upgrades -# Restart service -sudo systemctl start polkadot-hub-rpc -``` +Use the following commands for updating or upgrading your RPC node according to your setup: + +=== "Docker Setup" + + 1. Stop and remove the existing container: + ```bash + docker stop polkadot-hub-rpc + docker rm polkadot-hub-rpc + ``` + 2. Pull the latest image: + ```bash + docker pull parity/polkadot-parachain: + ``` + 3. Start the new container using the same command from the setup section with the updated image tag. + +=== "systemd Setup" + + 1. Stop the service: + ```bash + sudo systemctl stop polkadot-hub-rpc + ``` + 2. Backup data: + ```bash + sudo cp -r /var/lib/polkadot-hub-rpc /var/lib/polkadot-hub-rpc.backup + ``` + 3. Pull the new image and extract the binary: + ```bash + docker pull parity/polkadot-parachain: + docker create --name temp-parachain parity/polkadot-parachain: + sudo docker cp temp-parachain:/usr/local/bin/polkadot-parachain /usr/local/bin/ + docker rm temp-parachain + ``` + 4. Restart the service: + ```bash + sudo systemctl start polkadot-hub-rpc + ``` ## Conclusion Running an RPC node for Polkadot Hub provides essential infrastructure for applications and users to interact with the network. By following this guide, you have set up a production-ready RPC node that: -- Provides reliable access to Polkadot Hub's asset management, governance, and cross-chain communication features -- Supports both Docker and systemd deployment options for flexibility -- Implements proper monitoring, security, and maintenance practices -- Serves as a foundation for building and operating Polkadot SDK applications +- Provides reliable access to Polkadot Hub's asset management, governance, and cross-chain communication features. +- Supports both Docker and systemd deployment options for flexibility. +- Implements proper monitoring, security, and maintenance practices. +- Serves as a foundation for building and operating Polkadot SDK applications. Regular maintenance, security updates, and monitoring will ensure your RPC node continues to serve your users reliably. As the Polkadot network evolves, stay informed about updates and best practices through the official channels and community resources listed in this guide. From fda3e1ce0b607fbc9a448d08f922449c684bf7ba Mon Sep 17 00:00:00 2001 From: Bruno Galvao Date: Mon, 24 Nov 2025 16:51:55 +0700 Subject: [PATCH 14/39] Download polkadot-parachain binary from GitHub releases instead of Docker --- .../run-a-collator/collator.md | 23 ++++++------ .../run-a-node/parachain-rpc.md | 36 ++++++++----------- .../run-a-node/polkadot-hub-rpc.md | 24 ++++++------- 3 files changed, 39 insertions(+), 44 deletions(-) diff --git a/node-infrastructure/run-a-collator/collator.md b/node-infrastructure/run-a-collator/collator.md index 745d37dac..31e6c60bc 100644 --- a/node-infrastructure/run-a-collator/collator.md +++ b/node-infrastructure/run-a-collator/collator.md @@ -96,18 +96,22 @@ This guide provides two deployment options. Select the option that best fits you === "Manual Setup" - Extract the binary from the official Docker image: + Download the `polkadot-parachain` binary from the latest stable [Polkadot SDK release](https://github.com/paritytech/polkadot-sdk/releases){target=\_blank}: ```bash - # Create a temporary container and copy the binary - docker create --name temp-parachain parity/polkadot-parachain:stable2509-2 - sudo docker cp temp-parachain:/usr/local/bin/polkadot-parachain /usr/local/bin/ - docker rm temp-parachain + # Download the latest stable release (check releases page for current version) + wget https://github.com/paritytech/polkadot-sdk/releases/download/stable2409-2/polkadot-parachain + + # Make it executable and move to system path + chmod +x polkadot-parachain + sudo mv polkadot-parachain /usr/local/bin/ # Verify installation polkadot-parachain --version ``` + Check the [Polkadot SDK releases](https://github.com/paritytech/polkadot-sdk/releases){target=\_blank} page for the latest stable version. + ## Generate Node Key Generating a stable node key enables a consistent peer ID across the network. Follow these steps to generate a node key: @@ -489,12 +493,11 @@ Updates or upgrades can happen on either the runtime or client. Runtime upgrades sudo cp -r /var/lib/polkadot-collator /var/lib/polkadot-collator.backup ``` - 3. Pull the new image and extract the binary: + 3. Download the new binary from [GitHub releases](https://github.com/paritytech/polkadot-sdk/releases){target=\_blank}: ```bash - docker pull parity/polkadot-parachain: - docker create --name temp-parachain parity/polkadot-parachain: - sudo docker cp temp-parachain:/usr/local/bin/polkadot-parachain /usr/local/bin/ - docker rm temp-parachain + wget https://github.com/paritytech/polkadot-sdk/releases/download//polkadot-parachain + chmod +x polkadot-parachain + sudo mv polkadot-parachain /usr/local/bin/ ``` 4. Verify `polkadot-parachain` version to confirm successful update: diff --git a/node-infrastructure/run-a-node/parachain-rpc.md b/node-infrastructure/run-a-node/parachain-rpc.md index b5a0fec82..3feb1c941 100644 --- a/node-infrastructure/run-a-node/parachain-rpc.md +++ b/node-infrastructure/run-a-node/parachain-rpc.md @@ -8,11 +8,7 @@ categories: Infrastructure ## Overview -Running an RPC node for a parachain enables applications, wallets, and users to interact with the parachain's functionality. This guide applies to **any parachain** in the Polkadot ecosystem, including: - -- **System parachains**: Bridge Hub, People Chain, Coretime Chain -- **Common good parachains**: Collectives, Encointer -- **Commercial parachains**: Any parachain with a publicly available chain specification +Running an RPC node for a parachain enables applications, wallets, and users to interact with the parachain's functionality. Each parachain RPC node provides access through the Polkadot SDK Node RPC (Port 9944), offering native Polkadot API access via WebSocket and HTTP. This setup enables block explorer indexing and provides full compatibility with Polkadot SDK development tools. @@ -47,11 +43,7 @@ curl -L https://raw.githubusercontent.com/paritytech/polkadot-sdk/master/cumulus ### Other Parachains -For non-system parachains: - -- **Check the parachain's documentation** for official chain specification files -- **Contact the parachain team** if no public chain spec is available -- **Export from a running node** using `system_chainSpec` RPC method if you have access to an existing node +For non-system parachains, check the parachain's documentation for official chain specification files. **Note**: Throughout this guide, we use **People Chain** as the example. To set up a different parachain, substitute the chain spec file, snapshot path, and chain name with values for your target parachain. @@ -352,20 +344,21 @@ This option provides more control and is recommended for production environments ### Step 1: Install the Polkadot Parachain Binary -Extract the binary from the official Docker image: +Download the `polkadot-parachain` binary from the latest stable [Polkadot SDK release](https://github.com/paritytech/polkadot-sdk/releases){target=\_blank}: ```bash -# Pull the image and extract binary -docker pull parity/polkadot-parachain:stable2509-2 -docker create --name temp-parachain parity/polkadot-parachain:stable2509-2 -sudo docker cp temp-parachain:/usr/local/bin/polkadot-parachain /usr/local/bin/ -docker rm temp-parachain +# Download the latest stable release (check releases page for current version) +wget https://github.com/paritytech/polkadot-sdk/releases/download/stable2409-2/polkadot-parachain + +# Make it executable and move to system path +chmod +x polkadot-parachain +sudo mv polkadot-parachain /usr/local/bin/ # Verify installation polkadot-parachain --version ``` -Check [Docker Hub](https://hub.docker.com/r/parity/polkadot-parachain/tags) for the latest stable tags. +Check the [Polkadot SDK releases](https://github.com/paritytech/polkadot-sdk/releases){target=\_blank} page for the latest stable version. ### Step 2: Create User and Directory Structure @@ -550,11 +543,10 @@ sudo systemctl stop people-chain-rpc # Backup data sudo cp -r /var/lib/people-chain-rpc /var/lib/people-chain-rpc.backup -# Pull new image and extract binary -docker pull parity/polkadot-parachain: -docker create --name temp-parachain parity/polkadot-parachain: -sudo docker cp temp-parachain:/usr/local/bin/polkadot-parachain /usr/local/bin/ -docker rm temp-parachain +# Download new binary from GitHub releases +wget https://github.com/paritytech/polkadot-sdk/releases/download//polkadot-parachain +chmod +x polkadot-parachain +sudo mv polkadot-parachain /usr/local/bin/ # Restart service sudo systemctl start people-chain-rpc diff --git a/node-infrastructure/run-a-node/polkadot-hub-rpc.md b/node-infrastructure/run-a-node/polkadot-hub-rpc.md index e33f65eca..ad4a6656f 100644 --- a/node-infrastructure/run-a-node/polkadot-hub-rpc.md +++ b/node-infrastructure/run-a-node/polkadot-hub-rpc.md @@ -248,19 +248,20 @@ Select the best option for your project, then use the steps in the following tab This option provides more control and is recommended for production environments requiring custom configurations. - 1. Install the Polkadot Parachain binary by extracting it from the official Docker image: + 1. Download the `polkadot-parachain` binary from the latest stable [Polkadot SDK release](https://github.com/paritytech/polkadot-sdk/releases){target=\_blank}: ```bash - # Pull the image and extract binary - docker pull parity/polkadot-parachain:stable2509-2 - docker create --name temp-parachain parity/polkadot-parachain:stable2509-2 - sudo docker cp temp-parachain:/usr/local/bin/polkadot-parachain /usr/local/bin/ - docker rm temp-parachain + # Download the latest stable release (check releases page for current version) + wget https://github.com/paritytech/polkadot-sdk/releases/download/stable2409-2/polkadot-parachain + + # Make it executable and move to system path + chmod +x polkadot-parachain + sudo mv polkadot-parachain /usr/local/bin/ # Verify installation polkadot-parachain --version ``` - Check [Docker Hub](https://hub.docker.com/r/parity/polkadot-parachain/tags){target=\_blank} for the latest stable tags. + Check the [Polkadot SDK releases](https://github.com/paritytech/polkadot-sdk/releases){target=\_blank} page for the latest stable version. 2. Download the Polkadot Hub chain specification: ```bash @@ -468,12 +469,11 @@ Use the following commands for updating or upgrading your RPC node according to ```bash sudo cp -r /var/lib/polkadot-hub-rpc /var/lib/polkadot-hub-rpc.backup ``` - 3. Pull the new image and extract the binary: + 3. Download the new binary from [GitHub releases](https://github.com/paritytech/polkadot-sdk/releases){target=\_blank}: ```bash - docker pull parity/polkadot-parachain: - docker create --name temp-parachain parity/polkadot-parachain: - sudo docker cp temp-parachain:/usr/local/bin/polkadot-parachain /usr/local/bin/ - docker rm temp-parachain + wget https://github.com/paritytech/polkadot-sdk/releases/download//polkadot-parachain + chmod +x polkadot-parachain + sudo mv polkadot-parachain /usr/local/bin/ ``` 4. Restart the service: ```bash From e5175947d98a207e0f495a19daa0cf8627061d5d Mon Sep 17 00:00:00 2001 From: Bruno Galvao Date: Mon, 24 Nov 2025 16:57:09 +0700 Subject: [PATCH 15/39] Use MkDocs admonition syntax for notes and warnings --- .../run-a-collator/collator.md | 4 +++- .../run-a-node/parachain-rpc.md | 24 ++++++++++++++----- 2 files changed, 21 insertions(+), 7 deletions(-) diff --git a/node-infrastructure/run-a-collator/collator.md b/node-infrastructure/run-a-collator/collator.md index 31e6c60bc..6414709ac 100644 --- a/node-infrastructure/run-a-collator/collator.md +++ b/node-infrastructure/run-a-collator/collator.md @@ -308,7 +308,9 @@ Sync time depends on: The relay chain uses warp sync for faster synchronization. -**Important**: Do not proceed with registration until both chains are fully synced. Monitor sync progress using the log viewing commands in the [Log Management](#log-management) section. +!!! warning + + Do not proceed with registration until both chains are fully synced. Monitor sync progress using the log viewing commands in the [Log Management](#log-management) section. ## Generate Session Keys diff --git a/node-infrastructure/run-a-node/parachain-rpc.md b/node-infrastructure/run-a-node/parachain-rpc.md index 3feb1c941..960a22535 100644 --- a/node-infrastructure/run-a-node/parachain-rpc.md +++ b/node-infrastructure/run-a-node/parachain-rpc.md @@ -45,7 +45,9 @@ curl -L https://raw.githubusercontent.com/paritytech/polkadot-sdk/master/cumulus For non-system parachains, check the parachain's documentation for official chain specification files. -**Note**: Throughout this guide, we use **People Chain** as the example. To set up a different parachain, substitute the chain spec file, snapshot path, and chain name with values for your target parachain. +!!! note + + Throughout this guide, we use **People Chain** as the example. To set up a different parachain, substitute the chain spec file, snapshot path, and chain name with values for your target parachain. ## Prerequisites @@ -71,7 +73,9 @@ RPC nodes serving production traffic require robust hardware: - 9615 (Prometheus metrics - optional) - Consider DDoS protection and rate limiting for production deployments -**Note**: For development or low-traffic scenarios, you can reduce these requirements proportionally. Consider using a reverse proxy (nginx, Caddy) for production deployments. +!!! note + + For development or low-traffic scenarios, you can reduce these requirements proportionally. Consider using a reverse proxy (nginx, Caddy) for production deployments. ### Software Requirements @@ -102,7 +106,9 @@ Using pre-synchronized snapshots significantly reduces initial sync time from se **Snapshot Provider**: https://snapshots.polkadot.io/ -**Note**: Snapshots are available for system parachains and the Polkadot relay chain. For other parachains, check with the parachain team for snapshot availability or sync from genesis. +!!! note + + Snapshots are available for system parachains and the Polkadot relay chain. For other parachains, check with the parachain team for snapshot availability or sync from genesis. #### Create Directories @@ -139,7 +145,9 @@ rm files.txt - `--retries-sleep 10s`: Waits 10 seconds between retry attempts - `--size-only`: Only transfers if sizes differ (prevents unnecessary re-downloads) -**Note**: If a snapshot is not available, you can sync from scratch (which will take longer) or check https://snapshots.polkadot.io/ for alternative snapshot providers. +!!! note + + If a snapshot is not available, you can sync from scratch (which will take longer) or check https://snapshots.polkadot.io/ for alternative snapshot providers. #### Download Polkadot Relay Chain Snapshot @@ -171,7 +179,9 @@ Launch the node using the official Parity Docker image. **Docker Image**: https://hub.docker.com/r/parity/polkadot-parachain -**Note**: The `parity/polkadot-parachain` image works for system parachains and parachains built with standard Cumulus templates. For parachains with custom runtimes, check the parachain's documentation for their specific Docker image or binary. +!!! note + + The `parity/polkadot-parachain` image works for system parachains and parachains built with standard Cumulus templates. For parachains with custom runtimes, check the parachain's documentation for their specific Docker image or binary. ```bash docker run -d --name people-chain-rpc --restart unless-stopped \ @@ -334,7 +344,9 @@ docker start people-chain-rpc docker rm people-chain-rpc ``` -**Note**: For update procedures, see the [Updates and Upgrades](#updates-and-upgrades) section. +!!! note + + For update procedures, see the [Updates and Upgrades](#updates-and-upgrades) section. --- From 1c3288fdb24bb606ea143a91bb1f1c01c4d3bb4f Mon Sep 17 00:00:00 2001 From: Bruno Galvao Date: Mon, 24 Nov 2025 16:59:35 +0700 Subject: [PATCH 16/39] Fix GitHub release tag to polkadot-stable2509-2 --- node-infrastructure/run-a-collator/collator.md | 2 +- node-infrastructure/run-a-node/parachain-rpc.md | 2 +- node-infrastructure/run-a-node/polkadot-hub-rpc.md | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/node-infrastructure/run-a-collator/collator.md b/node-infrastructure/run-a-collator/collator.md index 6414709ac..e4f645733 100644 --- a/node-infrastructure/run-a-collator/collator.md +++ b/node-infrastructure/run-a-collator/collator.md @@ -100,7 +100,7 @@ This guide provides two deployment options. Select the option that best fits you ```bash # Download the latest stable release (check releases page for current version) - wget https://github.com/paritytech/polkadot-sdk/releases/download/stable2409-2/polkadot-parachain + wget https://github.com/paritytech/polkadot-sdk/releases/download/polkadot-stable2509-2/polkadot-parachain # Make it executable and move to system path chmod +x polkadot-parachain diff --git a/node-infrastructure/run-a-node/parachain-rpc.md b/node-infrastructure/run-a-node/parachain-rpc.md index 960a22535..ba58c5a7c 100644 --- a/node-infrastructure/run-a-node/parachain-rpc.md +++ b/node-infrastructure/run-a-node/parachain-rpc.md @@ -360,7 +360,7 @@ Download the `polkadot-parachain` binary from the latest stable [Polkadot SDK re ```bash # Download the latest stable release (check releases page for current version) -wget https://github.com/paritytech/polkadot-sdk/releases/download/stable2409-2/polkadot-parachain +wget https://github.com/paritytech/polkadot-sdk/releases/download/polkadot-stable2509-2/polkadot-parachain # Make it executable and move to system path chmod +x polkadot-parachain diff --git a/node-infrastructure/run-a-node/polkadot-hub-rpc.md b/node-infrastructure/run-a-node/polkadot-hub-rpc.md index ad4a6656f..8104bff42 100644 --- a/node-infrastructure/run-a-node/polkadot-hub-rpc.md +++ b/node-infrastructure/run-a-node/polkadot-hub-rpc.md @@ -251,7 +251,7 @@ Select the best option for your project, then use the steps in the following tab 1. Download the `polkadot-parachain` binary from the latest stable [Polkadot SDK release](https://github.com/paritytech/polkadot-sdk/releases){target=\_blank}: ```bash # Download the latest stable release (check releases page for current version) - wget https://github.com/paritytech/polkadot-sdk/releases/download/stable2409-2/polkadot-parachain + wget https://github.com/paritytech/polkadot-sdk/releases/download/polkadot-stable2509-2/polkadot-parachain # Make it executable and move to system path chmod +x polkadot-parachain From 18599158d02a1f0442cbe9f94037e85180a8bae2 Mon Sep 17 00:00:00 2001 From: Bruno Galvao Date: Mon, 24 Nov 2025 17:05:36 +0700 Subject: [PATCH 17/39] Restructure parachain-rpc.md to use tabbed content layout --- .../run-a-node/parachain-rpc.md | 878 ++++++++---------- 1 file changed, 412 insertions(+), 466 deletions(-) diff --git a/node-infrastructure/run-a-node/parachain-rpc.md b/node-infrastructure/run-a-node/parachain-rpc.md index ba58c5a7c..e857f6ec6 100644 --- a/node-infrastructure/run-a-node/parachain-rpc.md +++ b/node-infrastructure/run-a-node/parachain-rpc.md @@ -12,7 +12,9 @@ Running an RPC node for a parachain enables applications, wallets, and users to Each parachain RPC node provides access through the Polkadot SDK Node RPC (Port 9944), offering native Polkadot API access via WebSocket and HTTP. This setup enables block explorer indexing and provides full compatibility with Polkadot SDK development tools. -**Important Note**: The parameters and configurations in this guide are provided as illustrative examples. You may need to modify them according to your specific environment, hardware capabilities, and network conditions. +!!! note + + The parameters and configurations in this guide are provided as illustrative examples. You may need to modify them according to your specific environment, hardware capabilities, and network conditions. ## Obtaining a Chain Specification @@ -87,430 +89,365 @@ Required software: ## Setup Options -This guide provides two deployment options: - -1. **Docker-based Setup**: Simpler to set up and maintain -2. **Manual/Systemd Setup**: For production environments requiring more control - -Choose the option that best fits your needs. - ---- - -## Option 1: Docker-Based Setup - -This option uses Docker containers for the Polkadot SDK node, making it easy to set up and manage. - -### Step 1: Download Database Snapshots (Optional but Recommended) - -Using pre-synchronized snapshots significantly reduces initial sync time from several days to just a few hours. You need to download both parachain and relay chain data. - -**Snapshot Provider**: https://snapshots.polkadot.io/ - -!!! note - - Snapshots are available for system parachains and the Polkadot relay chain. For other parachains, check with the parachain team for snapshot availability or sync from genesis. - -#### Create Directories - -```bash -mkdir -p my-node-data/chains/people-polkadot/db -mkdir -p my-node-data/chains/polkadot/db -``` - -#### Download People Chain Snapshot - -Choose between archive (complete history) or pruned (recent state) snapshots. - -**Archive Snapshot** (recommended for RPC with historical data): - -```bash -# Check https://snapshots.polkadot.io/ for the latest snapshot URL -export SNAPSHOT_URL_PARACHAIN="https://snapshots.polkadot.io/polkadot-people-rocksdb-archive/LATEST" - -rclone copyurl $SNAPSHOT_URL_PARACHAIN/files.txt files.txt -rclone copy --progress --transfers 20 \ - --http-url $SNAPSHOT_URL_PARACHAIN \ - --no-traverse --http-no-head --disable-http2 \ - --inplace --no-gzip-encoding --size-only \ - --retries 6 --retries-sleep 10s \ - --files-from files.txt :http: my-node-data/chains/people-polkadot/db/ - -rm files.txt -``` - -**Parameter Explanation**: - -- `--transfers 20`: Uses 20 parallel transfers for faster download -- `--retries 6`: Automatically retries failed transfers up to 6 times -- `--retries-sleep 10s`: Waits 10 seconds between retry attempts -- `--size-only`: Only transfers if sizes differ (prevents unnecessary re-downloads) - -!!! note - - If a snapshot is not available, you can sync from scratch (which will take longer) or check https://snapshots.polkadot.io/ for alternative snapshot providers. - -#### Download Polkadot Relay Chain Snapshot - -**Pruned Snapshot** (recommended for RPC nodes): - -```bash -# Check https://snapshots.polkadot.io/ for the latest snapshot URL -export SNAPSHOT_URL_RELAY="https://snapshots.polkadot.io/polkadot-rocksdb-prune/LATEST" - -rclone copyurl $SNAPSHOT_URL_RELAY/files.txt files.txt -rclone copy --progress --transfers 20 \ - --http-url $SNAPSHOT_URL_RELAY \ - --no-traverse --http-no-head --disable-http2 \ - --inplace --no-gzip-encoding --size-only \ - --retries 6 --retries-sleep 10s \ - --files-from files.txt :http: my-node-data/chains/polkadot/db/ - -rm files.txt -``` - -**Alternative Options**: - -- Pruned snapshot: `polkadot-rocksdb-prune` (smaller size, recent state) -- Archive snapshot: `polkadot-rocksdb-archive` (complete history, larger size) - -### Step 2: Start the Parachain Node - -Launch the node using the official Parity Docker image. - -**Docker Image**: https://hub.docker.com/r/parity/polkadot-parachain - -!!! note - - The `parity/polkadot-parachain` image works for system parachains and parachains built with standard Cumulus templates. For parachains with custom runtimes, check the parachain's documentation for their specific Docker image or binary. - -```bash -docker run -d --name people-chain-rpc --restart unless-stopped \ - -p 9944:9944 \ - -p 9933:9933 \ - -p 9615:9615 \ - -p 30334:30334 \ - -p 30333:30333 \ - -v $(pwd)/people-polkadot.json:/people-polkadot.json \ - -v $(pwd)/my-node-data:/data \ - parity/polkadot-parachain:stable2509-2 \ - --name=PeopleChainRPC \ - --base-path=/data \ - --chain=/people-polkadot.json \ - --prometheus-external \ - --prometheus-port 9615 \ - --unsafe-rpc-external \ - --rpc-port=9944 \ - --rpc-cors=all \ - --rpc-methods=safe \ - --rpc-max-connections=1000 \ - --state-pruning=archive \ - --blocks-pruning=archive \ - -- \ - --base-path=/data \ - --chain=polkadot \ - --state-pruning=256 \ - --blocks-pruning=archive-canonical -``` - -**Critical Configuration Parameters**: - -**Port Mappings**: - -- `9944`: Polkadot SDK RPC endpoint (WebSocket/HTTP) -- `9933`: Polkadot SDK HTTP RPC endpoint -- `9615`: Prometheus metrics endpoint -- `30333/30334`: P2P networking ports - -**Node Parameters**: - -- `--unsafe-rpc-external`: Enables external RPC access -- `--rpc-cors=all`: Allows all origins for CORS -- `--rpc-methods=safe`: Only allows safe RPC methods -- `--state-pruning=archive`: Keeps complete state history -- `--blocks-pruning=archive`: Keeps all block data -- `--prometheus-external`: Exposes metrics externally - -**Security Warning**: The `--unsafe-rpc-external` flag should only be used in development or properly secured environments. For production, use a reverse proxy with authentication. - -### Step 3: Monitor Synchronization - -Monitor the node synchronization status: - -```bash -# Check sync status -curl -H "Content-Type: application/json" \ - -d '{"id":1, "jsonrpc":"2.0", "method": "system_syncState", "params":[]}' \ - http://localhost:9944 -``` - -**Expected Response Format**: - -```json -{ - "jsonrpc":"2.0", - "id":1, - "result":{ - "startingBlock":0, - "currentBlock":3394816, - "highestBlock":3394816 - } -} -``` - -**Synchronization Status**: - -- **In Progress**: `currentBlock` < `highestBlock` -- **Complete**: `currentBlock` = `highestBlock` - -### Step 4: Verify Setup - -Let's verify the Polkadot SDK RPC endpoint is working correctly. - -#### API Endpoint - -**Polkadot SDK RPC (Port 9944)**: - -- WebSocket: `ws://your-server:9944` -- HTTP: `http://your-server:9944` -- Purpose: Full Polkadot SDK API access for parachain data -- Use Cases: Polkadot SDK applications, parachain-specific operations - -#### Polkadot SDK RPC Tests - -**Get Chain Information**: - -```bash -curl -H "Content-Type: application/json" \ - -d '{"id":1, "jsonrpc":"2.0", "method": "system_chain", "params":[]}' \ - http://localhost:9944 -``` - -**Expected Response**: -```json -{ - "jsonrpc":"2.0", - "id":1, - "result":"Polkadot People" -} -``` - -**Get Latest Block**: - -```bash -curl -H "Content-Type: application/json" \ - -d '{"id":1, "jsonrpc":"2.0", "method": "chain_getHeader", "params":[]}' \ - http://localhost:9944 -``` - -**Get Node Health**: - -```bash -curl -H "Content-Type: application/json" \ - -d '{"id":1, "jsonrpc":"2.0", "method": "system_health", "params":[]}' \ - http://localhost:9944 -``` - -**Get Peer Count**: - -```bash -curl -H "Content-Type: application/json" \ - -d '{"id":1, "jsonrpc":"2.0", "method": "system_peers", "params":[]}' \ - http://localhost:9944 -``` - -### Managing Docker Containers - -**View logs**: - -```bash -docker logs -f people-chain-rpc -``` - -**Stop container**: - -```bash -docker stop people-chain-rpc -``` - -**Start container**: - -```bash -docker start people-chain-rpc -``` - -**Remove container**: - -```bash -docker rm people-chain-rpc -``` - -!!! note - - For update procedures, see the [Updates and Upgrades](#updates-and-upgrades) section. - ---- - -## Option 2: Manual/Systemd Setup - -This option provides more control and is recommended for production environments requiring custom configurations. - -### Step 1: Install the Polkadot Parachain Binary - -Download the `polkadot-parachain` binary from the latest stable [Polkadot SDK release](https://github.com/paritytech/polkadot-sdk/releases){target=\_blank}: - -```bash -# Download the latest stable release (check releases page for current version) -wget https://github.com/paritytech/polkadot-sdk/releases/download/polkadot-stable2509-2/polkadot-parachain - -# Make it executable and move to system path -chmod +x polkadot-parachain -sudo mv polkadot-parachain /usr/local/bin/ - -# Verify installation -polkadot-parachain --version -``` - -Check the [Polkadot SDK releases](https://github.com/paritytech/polkadot-sdk/releases){target=\_blank} page for the latest stable version. - -### Step 2: Create User and Directory Structure - -Ensure you have downloaded your parachain's chain specification as described in [Obtaining a Chain Specification](#obtaining-a-chain-specification). - -```bash -# Create dedicated user (skip if already exists) -sudo useradd -r -s /bin/bash polkadot - -# Create data directory -sudo mkdir -p /var/lib/people-chain-rpc - -# Copy chain spec to the directory -sudo cp people-polkadot.json /var/lib/people-chain-rpc/ - -# Set permissions -sudo chown -R polkadot:polkadot /var/lib/people-chain-rpc -``` - -### Step 3: Create Systemd Service - -Create a service file for your parachain RPC node: - -```bash -sudo nano /etc/systemd/system/people-chain-rpc.service -``` - -Add the following configuration: - -```ini -[Unit] -Description=People Chain RPC Node -After=network.target - -[Service] -Type=simple -User=polkadot -Group=polkadot -WorkingDirectory=/var/lib/people-chain-rpc - -ExecStart=/usr/local/bin/polkadot-parachain \ - --name=PeopleChainRPC \ - --chain=/var/lib/people-chain-rpc/people-polkadot.json \ - --base-path=/var/lib/people-chain-rpc \ - --port=30333 \ - --rpc-port=9944 \ - --rpc-external \ - --rpc-cors=all \ - --rpc-methods=safe \ - --rpc-max-connections=1000 \ - --prometheus-port=9615 \ - --prometheus-external \ - --state-pruning=archive \ - --blocks-pruning=archive \ - -- \ - --chain=polkadot \ - --base-path=/var/lib/people-chain-rpc \ - --port=30334 \ - --state-pruning=256 \ - --blocks-pruning=archive-canonical - -Restart=always -RestartSec=10 -LimitNOFILE=65536 - -[Install] -WantedBy=multi-user.target -``` - -### Step 4: Start Service - -```bash -# Reload systemd -sudo systemctl daemon-reload - -# Enable service to start on boot -sudo systemctl enable people-chain-rpc - -# Start the node -sudo systemctl start people-chain-rpc - -# Check status and wait for sync -sudo systemctl status people-chain-rpc -sudo journalctl -u people-chain-rpc -f -``` - -### Step 5: Verify Setup - -Use the same verification tests as in the Docker setup (see Step 4 above). - ---- - -## Monitoring and Maintenance - -### Log Management - -**Docker Setup**: - -```bash -# View node logs -docker logs -f people-chain-rpc -``` - -**Systemd Setup**: - -```bash -# View node logs -sudo journalctl -u people-chain-rpc -f - -# View recent logs -sudo journalctl -u people-chain-rpc -n 100 - -# Filter for errors -sudo journalctl -u people-chain-rpc | grep -i error -``` - -### Performance Monitoring - -Monitor key metrics: - -- **Sync status**: Ensure node stays fully synced -- **Peer connections**: Maintain 30+ peers for good connectivity -- **Resource usage**: Monitor CPU, RAM, and disk I/O -- **RPC request latency**: Track response times for the Polkadot SDK API -- **Connection count**: Monitor active RPC connections - -**Prometheus Metrics**: - -Metrics are available at `http://localhost:9615/metrics` - -Example Prometheus scrape configuration: - -```yaml -scrape_configs: - - job_name: 'people-chain-rpc' - static_configs: - - targets: ['localhost:9615'] -``` - -**Key Metrics to Monitor**: +This guide provides two options for deployment: + +- **Docker-based Setup**: Best for simpler set up and maintenance +- **Manual/systemd Setup**: Best for production environments requiring more control + +Select the best option for your project, then use the steps in the following tabs to complete set up. + +=== "Docker-Based Setup" + + This option uses Docker containers for the Polkadot SDK node, making it easy to set up and manage. Follow these steps to set your RPC node using Docker: + + 1. Download your parachain's chain specification as described in [Obtaining a Chain Specification](#obtaining-a-chain-specification). + + 2. (Optional but recommended) Download database snapshots: + - Using pre-synchronized snapshots significantly reduces initial sync time from several days to just a few hours. You need to download both parachain and relay chain data. + - You can obtain the latest snapshot from the [Snapshot Provider](https://snapshots.polkadot.io/){target=\_blank}. Follow these steps to download and use snapshots: + + !!! note + + Snapshots are available for system parachains and the Polkadot relay chain. For other parachains, check with the parachain team for snapshot availability or sync from genesis. + + 1. Create new directories with the following commands: + ```bash + mkdir -p my-node-data/chains/people-polkadot/db + mkdir -p my-node-data/chains/polkadot/db + ``` + 2. Download the appropriate snapshot using the following commands: + + === "Archive snapshot" + + Contains complete history, recommended for RPC with historical data. + ```bash + # Check https://snapshots.polkadot.io/ for the latest snapshot URL + export SNAPSHOT_URL_PARACHAIN="https://snapshots.polkadot.io/polkadot-people-rocksdb-archive/LATEST" + + rclone copyurl $SNAPSHOT_URL_PARACHAIN/files.txt files.txt + rclone copy --progress --transfers 20 \ + --http-url $SNAPSHOT_URL_PARACHAIN \ + --no-traverse --http-no-head --disable-http2 \ + --inplace --no-gzip-encoding --size-only \ + --retries 6 --retries-sleep 10s \ + --files-from files.txt :http: my-node-data/chains/people-polkadot/db/ + + rm files.txt + ``` + + - `--transfers 20`: Uses 20 parallel transfers for faster download. + - `--retries 6`: Automatically retries failed transfers up to 6 times. + - `--retries-sleep 10s`: Waits 10 seconds between retry attempts. + - `--size-only`: Only transfers if sizes differ (prevents unnecessary re-downloads). + + === "Pruned snapshot" + + Contains recent state for a smaller package size, recommended for RPC nodes. + ```bash + # Check https://snapshots.polkadot.io/ for the latest snapshot URL + export SNAPSHOT_URL_RELAY="https://snapshots.polkadot.io/polkadot-rocksdb-prune/LATEST" + + rclone copyurl $SNAPSHOT_URL_RELAY/files.txt files.txt + rclone copy --progress --transfers 20 \ + --http-url $SNAPSHOT_URL_RELAY \ + --no-traverse --http-no-head --disable-http2 \ + --inplace --no-gzip-encoding --size-only \ + --retries 6 --retries-sleep 10s \ + --files-from files.txt :http: my-node-data/chains/polkadot/db/ + + rm files.txt + ``` + + 3. Launch the parachain node using the official [Parity Docker image](https://hub.docker.com/r/parity/polkadot-parachain){target=\_blank} with the following command: + ```bash + docker run -d --name people-chain-rpc --restart unless-stopped \ + -p 9944:9944 \ + -p 9933:9933 \ + -p 9615:9615 \ + -p 30334:30334 \ + -p 30333:30333 \ + -v $(pwd)/people-polkadot.json:/people-polkadot.json \ + -v $(pwd)/my-node-data:/data \ + parity/polkadot-parachain:stable2509-2 \ + --name=PeopleChainRPC \ + --base-path=/data \ + --chain=/people-polkadot.json \ + --prometheus-external \ + --prometheus-port 9615 \ + --unsafe-rpc-external \ + --rpc-port=9944 \ + --rpc-cors=all \ + --rpc-methods=safe \ + --rpc-max-connections=1000 \ + --state-pruning=archive \ + --blocks-pruning=archive \ + -- \ + --base-path=/data \ + --chain=polkadot \ + --state-pruning=256 \ + --blocks-pruning=archive-canonical + ``` + + !!! note + + The `parity/polkadot-parachain` image works for system parachains and parachains built with standard Cumulus templates. For parachains with custom runtimes, check the parachain's documentation for their specific Docker image or binary. + + Critical configuration parameters include port mappings and node parameters: + + === "Port mappings" + + - `9944`: Polkadot SDK RPC endpoint (WebSocket/HTTP) + - `9933`: Polkadot SDK HTTP RPC endpoint + - `9615`: Prometheus metrics endpoint + - `30333/30334`: P2P networking ports + + === "Node parameters" + + - `--unsafe-rpc-external`: Enables external RPC access + - `--rpc-cors=all`: Allows all origins for CORS + - `--rpc-methods=safe`: Only allows safe RPC methods + - `--state-pruning=archive`: Keeps complete state history + - `--blocks-pruning=archive`: Keeps all block data + - `--prometheus-external`: Exposes metrics externally + + !!! warning + + The `--unsafe-rpc-external` flag should only be used in development or properly secured environments. For production, use a reverse proxy with authentication. + + 4. Monitor the node synchronization status using the following command: + ```bash + curl -H "Content-Type: application/json" \ + -d '{"id":1, "jsonrpc":"2.0", "method": "system_syncState", "params":[]}' \ + http://localhost:9944 + ``` + + You should see a response similar to the following: + + ```json + { + "jsonrpc":"2.0", + "id":1, + "result":{ + "startingBlock":0, + "currentBlock":3394816, + "highestBlock":3394816 + } + } + ``` + + When synchronization is complete, `currentBlock` will be equal to `highestBlock`. + + 5. You can use a few different commands to verify your node is running properly: + + - Get chain information: + ```bash + curl -H "Content-Type: application/json" \ + -d '{"id":1, "jsonrpc":"2.0", "method": "system_chain", "params":[]}' \ + http://localhost:9944 + ``` + - Get the latest block: + ```bash + curl -H "Content-Type: application/json" \ + -d '{"id":1, "jsonrpc":"2.0", "method": "chain_getHeader", "params":[]}' \ + http://localhost:9944 + ``` + - Query node health: + ```bash + curl -H "Content-Type: application/json" \ + -d '{"id":1, "jsonrpc":"2.0", "method": "system_health", "params":[]}' \ + http://localhost:9944 + ``` + + 6. Use the following commands to manage your Docker containers: + + - View node logs: + ```bash + docker logs -f people-chain-rpc + ``` + - Stop container: + ```bash + docker stop people-chain-rpc + ``` + - Start container: + ```bash + docker start people-chain-rpc + ``` + - Remove container: + ```bash + docker rm people-chain-rpc + ``` + +=== "Manual systemd Setup" + + This option provides more control and is recommended for production environments requiring custom configurations. + + 1. Download the `polkadot-parachain` binary from the latest stable [Polkadot SDK release](https://github.com/paritytech/polkadot-sdk/releases){target=\_blank}: + ```bash + # Download the latest stable release (check releases page for current version) + wget https://github.com/paritytech/polkadot-sdk/releases/download/polkadot-stable2509-2/polkadot-parachain + + # Make it executable and move to system path + chmod +x polkadot-parachain + sudo mv polkadot-parachain /usr/local/bin/ + + # Verify installation + polkadot-parachain --version + ``` + + Check the [Polkadot SDK releases](https://github.com/paritytech/polkadot-sdk/releases){target=\_blank} page for the latest stable version. + + 2. Download your parachain's chain specification as described in [Obtaining a Chain Specification](#obtaining-a-chain-specification). + + 3. Create user and directory structures using the following commands: + - Create a dedicated user: + ```bash + sudo useradd -r -s /bin/bash polkadot + ``` + - Create data directory: + ```bash + sudo mkdir -p /var/lib/people-chain-rpc + ``` + - Copy the chain spec to the directory: + ```bash + sudo cp people-polkadot.json /var/lib/people-chain-rpc/ + ``` + - Set permissions: + ```bash + sudo chown -R polkadot:polkadot /var/lib/people-chain-rpc + ``` + + 4. Create a systemd service file for the Polkadot SDK RPC node: + ```bash + sudo nano /etc/systemd/system/people-chain-rpc.service + ``` + + 5. Open the new service file and add the following configuration: + ```ini + [Unit] + Description=People Chain RPC Node + After=network.target + + [Service] + Type=simple + User=polkadot + Group=polkadot + WorkingDirectory=/var/lib/people-chain-rpc + + ExecStart=/usr/local/bin/polkadot-parachain \ + --name=PeopleChainRPC \ + --chain=/var/lib/people-chain-rpc/people-polkadot.json \ + --base-path=/var/lib/people-chain-rpc \ + --port=30333 \ + --rpc-port=9944 \ + --rpc-external \ + --rpc-cors=all \ + --rpc-methods=safe \ + --rpc-max-connections=1000 \ + --prometheus-port=9615 \ + --prometheus-external \ + --state-pruning=archive \ + --blocks-pruning=archive \ + -- \ + --chain=polkadot \ + --base-path=/var/lib/people-chain-rpc \ + --port=30334 \ + --state-pruning=256 \ + --blocks-pruning=archive-canonical + + Restart=always + RestartSec=10 + LimitNOFILE=65536 + + [Install] + WantedBy=multi-user.target + ``` + + 6. Start the service using the following commands: + - Reload systemd: + ```bash + sudo systemctl daemon-reload + ``` + - Enable service to start on boot: + ```bash + sudo systemctl enable people-chain-rpc + ``` + - Start the Polkadot SDK node: + ```bash + sudo systemctl start people-chain-rpc + ``` + - Check status and wait for sync: + ```bash + sudo systemctl status people-chain-rpc + sudo journalctl -u people-chain-rpc -f + ``` + + 7. You can use a few different commands to verify your node is running properly: + - Get chain information: + ```bash + curl -H "Content-Type: application/json" \ + -d '{"id":1, "jsonrpc":"2.0", "method": "system_chain", "params":[]}' \ + http://localhost:9944 + ``` + - Get the latest block: + ```bash + curl -H "Content-Type: application/json" \ + -d '{"id":1, "jsonrpc":"2.0", "method": "chain_getHeader", "params":[]}' \ + http://localhost:9944 + ``` + - Query node health: + ```bash + curl -H "Content-Type: application/json" \ + -d '{"id":1, "jsonrpc":"2.0", "method": "system_health", "params":[]}' \ + http://localhost:9944 + ``` + +## Monitor and Maintain RPC Node + +There are a few key monitoring and maintenance commands that can help you ensure RPC node uptime and performance including log monitoring and metrics. + +To view node logs, use the appropriate command for your setup: + +=== "Docker Setup" + + ```bash + docker logs -f people-chain-rpc + ``` + +=== "systemd Setup" + + - View node logs: + ```bash + sudo journalctl -u people-chain-rpc -f + ``` + - View recent logs: + ```bash + sudo journalctl -u people-chain-rpc -n 100 + ``` + - Filter for errors: + ```bash + sudo journalctl -u people-chain-rpc | grep -i error + ``` + +Monitoring key metrics like the following items can help you stay up to date on the performance and health of your node and allow you to intervene at the first sign of issues: + +- **Sync status**: Ensure node stays fully synced. +- **Peer connections**: Maintain 30+ peers for good connectivity. +- **Resource usage**: Monitor CPU, RAM, and disk I/O. +- **RPC request latency**: Track response times for the Polkadot SDK API. +- **Connection count**: Monitor active RPC connections. + +You can use the following information to configure [Prometheus](https://prometheus.io/docs/introduction/first_steps/){target=\_blank} to monitor, collect, and store your RPC node metrics: + +- **URL**: Metrics are available to view at `http://localhost:9615/metrics` +- **Example Prometheus configuration**: Update your `prometheus.yml` to add the following code: + ```yaml + scrape_configs: + - job_name: 'people-chain-rpc' + static_configs: + - targets: ['localhost:9615'] + ``` + +Key metrics to monitor via Prometheus include: - `substrate_block_height`: Current block height - `substrate_finalized_height`: Finalized block height @@ -519,58 +456,67 @@ scrape_configs: ### Database Maintenance -Check database size periodically: - -```bash -# Docker setup -du -sh my-node-data - -# Systemd setup -du -sh /var/lib/people-chain-rpc -``` - -The node handles pruning automatically based on configuration unless running in archive mode. - -### Updates and Upgrades +Check database size periodically using the commands for your selected setup: -**Docker Setup**: +=== "Docker Setup" -```bash -# Pull latest image -docker pull parity/polkadot-parachain: - -# Restart container -docker stop people-chain-rpc -docker rm people-chain-rpc + ```bash + du -sh my-node-data + ``` -# Start new container (use same command from setup with updated image tag) -``` +=== "systemd Setup" -**Systemd Setup**: + ```bash + du -sh /var/lib/people-chain-rpc + ``` -```bash -# Stop service -sudo systemctl stop people-chain-rpc - -# Backup data -sudo cp -r /var/lib/people-chain-rpc /var/lib/people-chain-rpc.backup +The node handles pruning automatically based on configuration unless running in archive mode. -# Download new binary from GitHub releases -wget https://github.com/paritytech/polkadot-sdk/releases/download//polkadot-parachain -chmod +x polkadot-parachain -sudo mv polkadot-parachain /usr/local/bin/ +### Updates and Upgrades -# Restart service -sudo systemctl start people-chain-rpc -``` +Use the following commands for updating or upgrading your RPC node according to your setup: + +=== "Docker Setup" + + 1. Stop and remove the existing container: + ```bash + docker stop people-chain-rpc + docker rm people-chain-rpc + ``` + 2. Pull the latest image: + ```bash + docker pull parity/polkadot-parachain: + ``` + 3. Start the new container using the same command from the setup section with the updated image tag. + +=== "systemd Setup" + + 1. Stop the service: + ```bash + sudo systemctl stop people-chain-rpc + ``` + 2. Backup data: + ```bash + sudo cp -r /var/lib/people-chain-rpc /var/lib/people-chain-rpc.backup + ``` + 3. Download the new binary from [GitHub releases](https://github.com/paritytech/polkadot-sdk/releases){target=\_blank}: + ```bash + wget https://github.com/paritytech/polkadot-sdk/releases/download//polkadot-parachain + chmod +x polkadot-parachain + sudo mv polkadot-parachain /usr/local/bin/ + ``` + 4. Restart the service: + ```bash + sudo systemctl start people-chain-rpc + ``` ## Conclusion Running a parachain RPC node provides critical infrastructure for accessing Polkadot network services. By following this guide, you have set up a production-ready RPC node that: -- Provides reliable access to parachain functionality for applications and users -- Supports flexible deployment with both Docker and systemd options -- Implements comprehensive monitoring, security, and maintenance practices -- Can be adapted for any parachain by substituting the appropriate chain specification +- Provides reliable access to parachain functionality for applications and users. +- Supports flexible deployment with both Docker and systemd options. +- Implements comprehensive monitoring, security, and maintenance practices. +- Can be adapted for any parachain by substituting the appropriate chain specification. Whether you're running a node for system parachains (People Chain, Bridge Hub, Coretime Chain) or other parachains in the ecosystem, regular maintenance and monitoring will ensure your RPC node continues to provide reliable service. Stay updated with the latest releases and best practices to keep your infrastructure secure and performant. From f645cca760feed0517ddd83f1beb09295571485f Mon Sep 17 00:00:00 2001 From: Bruno Galvao Date: Mon, 24 Nov 2025 17:08:28 +0700 Subject: [PATCH 18/39] Add Docker commands to collator.md monitoring and maintenance sections --- .../run-a-collator/collator.md | 90 ++++++++++++++----- 1 file changed, 66 insertions(+), 24 deletions(-) diff --git a/node-infrastructure/run-a-collator/collator.md b/node-infrastructure/run-a-collator/collator.md index e4f645733..2560584d1 100644 --- a/node-infrastructure/run-a-collator/collator.md +++ b/node-infrastructure/run-a-collator/collator.md @@ -388,10 +388,20 @@ The registration process varies by system parachain. General steps include the f Monitoring the following items will help ensure your collator runs efficiently to avoid service interruptions or down time: -- **Block Production**: monitor for block production using the following command: - ```bash - sudo journalctl -u polkadot-collator | grep -i "prepared block" - ``` +- **Block Production**: Monitor for block production using the appropriate command for your setup: + + === "Docker Setup" + + ```bash + docker logs polkadot-collator 2>&1 | grep -i "prepared block" + ``` + + === "systemd Setup" + + ```bash + sudo journalctl -u polkadot-collator | grep -i "prepared block" + ``` + - **Peer Connections**: Maintain a sufficient amount of peers for good connectivity and set up alerts to notify if peer connections falls below ten. - **Resource Usage**: Monitor CPU, RAM, and disk I/O and set up alerts for unusual or high usage. - **Sync Status**: Ensure both chains stay synced and set up alerts for sync issues. @@ -419,32 +429,64 @@ Key metrics to monitor via Prometheus include the following: ## Log Management -Effecient log management is essential to ensure collator performance and uptime. Use the following commands to help you manage logs to monitor and maintain your collator: +Efficient log management is essential to ensure collator performance and uptime. Use the following commands to help you manage logs to monitor and maintain your collator: + +=== "Docker Setup" + + - View logs: + ```bash + docker logs -f polkadot-collator + ``` + - View recent logs (last 100 lines): + ```bash + docker logs --tail 100 polkadot-collator + ``` + - Filter for errors: + ```bash + docker logs polkadot-collator 2>&1 | grep -i error + ``` + - Filter for block production: + ```bash + docker logs polkadot-collator 2>&1 | grep -i "imported" + ``` + +=== "systemd Setup" + + - View recent logs: + ```bash + sudo journalctl -u polkadot-collator -n 100 + ``` + - Follow logs in real-time: + ```bash + sudo journalctl -u polkadot-collator -f + ``` + - Filter for errors: + ```bash + sudo journalctl -u polkadot-collator | grep -i error + ``` + - Filter for block production: + ```bash + sudo journalctl -u polkadot-collator | grep -i "imported" + ``` + +## Database Maintenance + +Check database size periodically using the commands for your selected setup: + +=== "Docker Setup" -- View recent logs: - ```bash - sudo journalctl -u polkadot-collator -n 100 - ``` -- Follow logs in real-time: - ```bash - sudo journalctl -u polkadot-collator -f - ``` -- Filter for errors: ```bash - sudo journalctl -u polkadot-collator | grep -i error + # Replace with your mounted data directory path + du -sh ./collator-data ``` -- Filter for block production: + +=== "systemd Setup" + ```bash - sudo journalctl -u polkadot-collator | grep -i "imported" + du -sh /var/lib/polkadot-collator ``` -## Database Maintenance - -You can check database size using the following command: -```bash -du -sh /var/lib/polkadot-collator -``` -The collator node handles pruning automatically. +The collator node handles pruning automatically based on configuration. ## Updates and Upgrades From 1a74bf48cc04492ef462510ce139979bdc5243ee Mon Sep 17 00:00:00 2001 From: Bruno Galvao Date: Mon, 24 Nov 2025 17:09:49 +0700 Subject: [PATCH 19/39] Update content --- ...-infrastructure-run-a-collator-collator.md | 117 ++- ...infrastructure-run-a-node-parachain-rpc.md | 892 +++++++++--------- ...rastructure-run-a-node-polkadot-hub-rpc.md | 24 +- .../run-a-node/polkadot-hub-rpc.md | 2 - 4 files changed, 514 insertions(+), 521 deletions(-) diff --git a/.ai/pages/node-infrastructure-run-a-collator-collator.md b/.ai/pages/node-infrastructure-run-a-collator-collator.md index bb8fd588e..cf706b94e 100644 --- a/.ai/pages/node-infrastructure-run-a-collator-collator.md +++ b/.ai/pages/node-infrastructure-run-a-collator-collator.md @@ -97,18 +97,22 @@ This guide provides two deployment options. Select the option that best fits you === "Manual Setup" - Extract the binary from the official Docker image: + Download the `polkadot-parachain` binary from the latest stable [Polkadot SDK release](https://github.com/paritytech/polkadot-sdk/releases){target=\_blank}: ```bash - # Create a temporary container and copy the binary - docker create --name temp-parachain parity/polkadot-parachain:stable2509-2 - sudo docker cp temp-parachain:/usr/local/bin/polkadot-parachain /usr/local/bin/ - docker rm temp-parachain + # Download the latest stable release (check releases page for current version) + wget https://github.com/paritytech/polkadot-sdk/releases/download/polkadot-stable2509-2/polkadot-parachain + + # Make it executable and move to system path + chmod +x polkadot-parachain + sudo mv polkadot-parachain /usr/local/bin/ # Verify installation polkadot-parachain --version ``` + Check the [Polkadot SDK releases](https://github.com/paritytech/polkadot-sdk/releases){target=\_blank} page for the latest stable version. + ## Generate Node Key Generating a stable node key enables a consistent peer ID across the network. Follow these steps to generate a node key: @@ -305,7 +309,9 @@ Sync time depends on: The relay chain uses warp sync for faster synchronization. -**Important**: Do not proceed with registration until both chains are fully synced. Monitor sync progress using the log viewing commands in the [Log Management](#log-management) section. +!!! warning + + Do not proceed with registration until both chains are fully synced. Monitor sync progress using the log viewing commands in the [Log Management](#log-management) section. ## Generate Session Keys @@ -383,10 +389,20 @@ The registration process varies by system parachain. General steps include the f Monitoring the following items will help ensure your collator runs efficiently to avoid service interruptions or down time: -- **Block Production**: monitor for block production using the following command: - ```bash - sudo journalctl -u polkadot-collator | grep -i "prepared block" - ``` +- **Block Production**: Monitor for block production using the appropriate command for your setup: + + === "Docker Setup" + + ```bash + docker logs polkadot-collator 2>&1 | grep -i "prepared block" + ``` + + === "systemd Setup" + + ```bash + sudo journalctl -u polkadot-collator | grep -i "prepared block" + ``` + - **Peer Connections**: Maintain a sufficient amount of peers for good connectivity and set up alerts to notify if peer connections falls below ten. - **Resource Usage**: Monitor CPU, RAM, and disk I/O and set up alerts for unusual or high usage. - **Sync Status**: Ensure both chains stay synced and set up alerts for sync issues. @@ -416,32 +432,64 @@ Key metrics to monitor via Prometheus include the following: ## Log Management -Effecient log management is essential to ensure collator performance and uptime. Use the following commands to help you manage logs to monitor and maintain your collator: +Efficient log management is essential to ensure collator performance and uptime. Use the following commands to help you manage logs to monitor and maintain your collator: + +=== "Docker Setup" + + - View logs: + ```bash + docker logs -f polkadot-collator + ``` + - View recent logs (last 100 lines): + ```bash + docker logs --tail 100 polkadot-collator + ``` + - Filter for errors: + ```bash + docker logs polkadot-collator 2>&1 | grep -i error + ``` + - Filter for block production: + ```bash + docker logs polkadot-collator 2>&1 | grep -i "imported" + ``` + +=== "systemd Setup" + + - View recent logs: + ```bash + sudo journalctl -u polkadot-collator -n 100 + ``` + - Follow logs in real-time: + ```bash + sudo journalctl -u polkadot-collator -f + ``` + - Filter for errors: + ```bash + sudo journalctl -u polkadot-collator | grep -i error + ``` + - Filter for block production: + ```bash + sudo journalctl -u polkadot-collator | grep -i "imported" + ``` + +## Database Maintenance + +Check database size periodically using the commands for your selected setup: + +=== "Docker Setup" -- View recent logs: - ```bash - sudo journalctl -u polkadot-collator -n 100 - ``` -- Follow logs in real-time: - ```bash - sudo journalctl -u polkadot-collator -f - ``` -- Filter for errors: ```bash - sudo journalctl -u polkadot-collator | grep -i error + # Replace with your mounted data directory path + du -sh ./collator-data ``` -- Filter for block production: + +=== "systemd Setup" + ```bash - sudo journalctl -u polkadot-collator | grep -i "imported" + du -sh /var/lib/polkadot-collator ``` -## Database Maintenance - -You can check database size using the following command: -```bash -du -sh /var/lib/polkadot-collator -``` -The collator node handles pruning automatically. +The collator node handles pruning automatically based on configuration. ## Updates and Upgrades @@ -492,12 +540,11 @@ Updates or upgrades can happen on either the runtime or client. Runtime upgrades sudo cp -r /var/lib/polkadot-collator /var/lib/polkadot-collator.backup ``` - 3. Pull the new image and extract the binary: + 3. Download the new binary from [GitHub releases](https://github.com/paritytech/polkadot-sdk/releases){target=\_blank}: ```bash - docker pull parity/polkadot-parachain: - docker create --name temp-parachain parity/polkadot-parachain: - sudo docker cp temp-parachain:/usr/local/bin/polkadot-parachain /usr/local/bin/ - docker rm temp-parachain + wget https://github.com/paritytech/polkadot-sdk/releases/download//polkadot-parachain + chmod +x polkadot-parachain + sudo mv polkadot-parachain /usr/local/bin/ ``` 4. Verify `polkadot-parachain` version to confirm successful update: diff --git a/.ai/pages/node-infrastructure-run-a-node-parachain-rpc.md b/.ai/pages/node-infrastructure-run-a-node-parachain-rpc.md index e38c1a1fd..3d39db163 100644 --- a/.ai/pages/node-infrastructure-run-a-node-parachain-rpc.md +++ b/.ai/pages/node-infrastructure-run-a-node-parachain-rpc.md @@ -9,15 +9,13 @@ url: https://docs.polkadot.com/node-infrastructure/run-a-node/parachain-rpc/ ## Overview -Running an RPC node for a parachain enables applications, wallets, and users to interact with the parachain's functionality. This guide applies to **any parachain** in the Polkadot ecosystem, including: - -- **System parachains**: Bridge Hub, People Chain, Coretime Chain -- **Common good parachains**: Collectives, Encointer -- **Commercial parachains**: Any parachain with a publicly available chain specification +Running an RPC node for a parachain enables applications, wallets, and users to interact with the parachain's functionality. Each parachain RPC node provides access through the Polkadot SDK Node RPC (Port 9944), offering native Polkadot API access via WebSocket and HTTP. This setup enables block explorer indexing and provides full compatibility with Polkadot SDK development tools. -**Important Note**: The parameters and configurations in this guide are provided as illustrative examples. You may need to modify them according to your specific environment, hardware capabilities, and network conditions. +!!! note + + The parameters and configurations in this guide are provided as illustrative examples. You may need to modify them according to your specific environment, hardware capabilities, and network conditions. ## Obtaining a Chain Specification @@ -48,13 +46,11 @@ curl -L https://raw.githubusercontent.com/paritytech/polkadot-sdk/master/cumulus ### Other Parachains -For non-system parachains: +For non-system parachains, check the parachain's documentation for official chain specification files. -- **Check the parachain's documentation** for official chain specification files -- **Contact the parachain team** if no public chain spec is available -- **Export from a running node** using `system_chainSpec` RPC method if you have access to an existing node +!!! note -**Note**: Throughout this guide, we use **People Chain** as the example. To set up a different parachain, substitute the chain spec file, snapshot path, and chain name with values for your target parachain. + Throughout this guide, we use **People Chain** as the example. To set up a different parachain, substitute the chain spec file, snapshot path, and chain name with values for your target parachain. ## Prerequisites @@ -80,7 +76,9 @@ RPC nodes serving production traffic require robust hardware: - 9615 (Prometheus metrics - optional) - Consider DDoS protection and rate limiting for production deployments -**Note**: For development or low-traffic scenarios, you can reduce these requirements proportionally. Consider using a reverse proxy (nginx, Caddy) for production deployments. +!!! note + + For development or low-traffic scenarios, you can reduce these requirements proportionally. Consider using a reverse proxy (nginx, Caddy) for production deployments. ### Software Requirements @@ -92,423 +90,367 @@ Required software: ## Setup Options -This guide provides two deployment options: - -1. **Docker-based Setup**: Simpler to set up and maintain -2. **Manual/Systemd Setup**: For production environments requiring more control - -Choose the option that best fits your needs. - ---- - -## Option 1: Docker-Based Setup - -This option uses Docker containers for the Polkadot SDK node, making it easy to set up and manage. - -### Step 1: Download Database Snapshots (Optional but Recommended) - -Using pre-synchronized snapshots significantly reduces initial sync time from several days to just a few hours. You need to download both parachain and relay chain data. - -**Snapshot Provider**: https://snapshots.polkadot.io/ - -**Note**: Snapshots are available for system parachains and the Polkadot relay chain. For other parachains, check with the parachain team for snapshot availability or sync from genesis. - -#### Create Directories - -```bash -mkdir -p my-node-data/chains/people-polkadot/db -mkdir -p my-node-data/chains/polkadot/db -``` - -#### Download People Chain Snapshot - -Choose between archive (complete history) or pruned (recent state) snapshots. - -**Archive Snapshot** (recommended for RPC with historical data): - -```bash -# Check https://snapshots.polkadot.io/ for the latest snapshot URL -export SNAPSHOT_URL_PARACHAIN="https://snapshots.polkadot.io/polkadot-people-rocksdb-archive/LATEST" - -rclone copyurl $SNAPSHOT_URL_PARACHAIN/files.txt files.txt -rclone copy --progress --transfers 20 \ - --http-url $SNAPSHOT_URL_PARACHAIN \ - --no-traverse --http-no-head --disable-http2 \ - --inplace --no-gzip-encoding --size-only \ - --retries 6 --retries-sleep 10s \ - --files-from files.txt :http: my-node-data/chains/people-polkadot/db/ - -rm files.txt -``` - -**Parameter Explanation**: - -- `--transfers 20`: Uses 20 parallel transfers for faster download -- `--retries 6`: Automatically retries failed transfers up to 6 times -- `--retries-sleep 10s`: Waits 10 seconds between retry attempts -- `--size-only`: Only transfers if sizes differ (prevents unnecessary re-downloads) - -**Note**: If a snapshot is not available, you can sync from scratch (which will take longer) or check https://snapshots.polkadot.io/ for alternative snapshot providers. - -#### Download Polkadot Relay Chain Snapshot - -**Pruned Snapshot** (recommended for RPC nodes): - -```bash -# Check https://snapshots.polkadot.io/ for the latest snapshot URL -export SNAPSHOT_URL_RELAY="https://snapshots.polkadot.io/polkadot-rocksdb-prune/LATEST" - -rclone copyurl $SNAPSHOT_URL_RELAY/files.txt files.txt -rclone copy --progress --transfers 20 \ - --http-url $SNAPSHOT_URL_RELAY \ - --no-traverse --http-no-head --disable-http2 \ - --inplace --no-gzip-encoding --size-only \ - --retries 6 --retries-sleep 10s \ - --files-from files.txt :http: my-node-data/chains/polkadot/db/ - -rm files.txt -``` - -**Alternative Options**: - -- Pruned snapshot: `polkadot-rocksdb-prune` (smaller size, recent state) -- Archive snapshot: `polkadot-rocksdb-archive` (complete history, larger size) - -### Step 2: Start the Parachain Node - -Launch the node using the official Parity Docker image. - -**Docker Image**: https://hub.docker.com/r/parity/polkadot-parachain - -**Note**: The `parity/polkadot-parachain` image works for system parachains and parachains built with standard Cumulus templates. For parachains with custom runtimes, check the parachain's documentation for their specific Docker image or binary. - -```bash -docker run -d --name people-chain-rpc --restart unless-stopped \ - -p 9944:9944 \ - -p 9933:9933 \ - -p 9615:9615 \ - -p 30334:30334 \ - -p 30333:30333 \ - -v $(pwd)/people-polkadot.json:/people-polkadot.json \ - -v $(pwd)/my-node-data:/data \ - parity/polkadot-parachain:stable2509-2 \ - --name=PeopleChainRPC \ - --base-path=/data \ - --chain=/people-polkadot.json \ - --prometheus-external \ - --prometheus-port 9615 \ - --unsafe-rpc-external \ - --rpc-port=9944 \ - --rpc-cors=all \ - --rpc-methods=safe \ - --rpc-max-connections=1000 \ - --state-pruning=archive \ - --blocks-pruning=archive \ - -- \ - --base-path=/data \ - --chain=polkadot \ - --state-pruning=256 \ - --blocks-pruning=archive-canonical -``` - -**Critical Configuration Parameters**: - -**Port Mappings**: - -- `9944`: Polkadot SDK RPC endpoint (WebSocket/HTTP) -- `9933`: Polkadot SDK HTTP RPC endpoint -- `9615`: Prometheus metrics endpoint -- `30333/30334`: P2P networking ports - -**Node Parameters**: - -- `--unsafe-rpc-external`: Enables external RPC access -- `--rpc-cors=all`: Allows all origins for CORS -- `--rpc-methods=safe`: Only allows safe RPC methods -- `--state-pruning=archive`: Keeps complete state history -- `--blocks-pruning=archive`: Keeps all block data -- `--prometheus-external`: Exposes metrics externally - -**Security Warning**: The `--unsafe-rpc-external` flag should only be used in development or properly secured environments. For production, use a reverse proxy with authentication. - -### Step 3: Monitor Synchronization - -Monitor the node synchronization status: - -```bash -# Check sync status -curl -H "Content-Type: application/json" \ - -d '{"id":1, "jsonrpc":"2.0", "method": "system_syncState", "params":[]}' \ - http://localhost:9944 -``` - -**Expected Response Format**: - -```json -{ - "jsonrpc":"2.0", - "id":1, - "result":{ - "startingBlock":0, - "currentBlock":3394816, - "highestBlock":3394816 - } -} -``` - -**Synchronization Status**: - -- **In Progress**: `currentBlock` < `highestBlock` -- **Complete**: `currentBlock` = `highestBlock` - -### Step 4: Verify Setup - -Let's verify the Polkadot SDK RPC endpoint is working correctly. - -#### API Endpoint - -**Polkadot SDK RPC (Port 9944)**: - -- WebSocket: `ws://your-server:9944` -- HTTP: `http://your-server:9944` -- Purpose: Full Polkadot SDK API access for parachain data -- Use Cases: Polkadot SDK applications, parachain-specific operations - -#### Polkadot SDK RPC Tests - -**Get Chain Information**: - -```bash -curl -H "Content-Type: application/json" \ - -d '{"id":1, "jsonrpc":"2.0", "method": "system_chain", "params":[]}' \ - http://localhost:9944 -``` - -**Expected Response**: -```json -{ - "jsonrpc":"2.0", - "id":1, - "result":"Polkadot People" -} -``` - -**Get Latest Block**: - -```bash -curl -H "Content-Type: application/json" \ - -d '{"id":1, "jsonrpc":"2.0", "method": "chain_getHeader", "params":[]}' \ - http://localhost:9944 -``` - -**Get Node Health**: - -```bash -curl -H "Content-Type: application/json" \ - -d '{"id":1, "jsonrpc":"2.0", "method": "system_health", "params":[]}' \ - http://localhost:9944 -``` - -**Get Peer Count**: - -```bash -curl -H "Content-Type: application/json" \ - -d '{"id":1, "jsonrpc":"2.0", "method": "system_peers", "params":[]}' \ - http://localhost:9944 -``` - -### Managing Docker Containers - -**View logs**: - -```bash -docker logs -f people-chain-rpc -``` - -**Stop container**: - -```bash -docker stop people-chain-rpc -``` - -**Start container**: - -```bash -docker start people-chain-rpc -``` - -**Remove container**: - -```bash -docker rm people-chain-rpc -``` - -**Note**: For update procedures, see the [Updates and Upgrades](#updates-and-upgrades) section. - ---- - -## Option 2: Manual/Systemd Setup - -This option provides more control and is recommended for production environments requiring custom configurations. - -### Step 1: Install the Polkadot Parachain Binary - -Extract the binary from the official Docker image: - -```bash -# Pull the image and extract binary -docker pull parity/polkadot-parachain:stable2509-2 -docker create --name temp-parachain parity/polkadot-parachain:stable2509-2 -sudo docker cp temp-parachain:/usr/local/bin/polkadot-parachain /usr/local/bin/ -docker rm temp-parachain - -# Verify installation -polkadot-parachain --version -``` - -Check [Docker Hub](https://hub.docker.com/r/parity/polkadot-parachain/tags) for the latest stable tags. - -### Step 2: Create User and Directory Structure - -Ensure you have downloaded your parachain's chain specification as described in [Obtaining a Chain Specification](#obtaining-a-chain-specification). - -```bash -# Create dedicated user (skip if already exists) -sudo useradd -r -s /bin/bash polkadot - -# Create data directory -sudo mkdir -p /var/lib/people-chain-rpc - -# Copy chain spec to the directory -sudo cp people-polkadot.json /var/lib/people-chain-rpc/ - -# Set permissions -sudo chown -R polkadot:polkadot /var/lib/people-chain-rpc -``` - -### Step 3: Create Systemd Service - -Create a service file for your parachain RPC node: - -```bash -sudo nano /etc/systemd/system/people-chain-rpc.service -``` - -Add the following configuration: - -```ini -[Unit] -Description=People Chain RPC Node -After=network.target - -[Service] -Type=simple -User=polkadot -Group=polkadot -WorkingDirectory=/var/lib/people-chain-rpc - -ExecStart=/usr/local/bin/polkadot-parachain \ - --name=PeopleChainRPC \ - --chain=/var/lib/people-chain-rpc/people-polkadot.json \ - --base-path=/var/lib/people-chain-rpc \ - --port=30333 \ - --rpc-port=9944 \ - --rpc-external \ - --rpc-cors=all \ - --rpc-methods=safe \ - --rpc-max-connections=1000 \ - --prometheus-port=9615 \ - --prometheus-external \ - --state-pruning=archive \ - --blocks-pruning=archive \ - -- \ - --chain=polkadot \ - --base-path=/var/lib/people-chain-rpc \ - --port=30334 \ - --state-pruning=256 \ - --blocks-pruning=archive-canonical - -Restart=always -RestartSec=10 -LimitNOFILE=65536 - -[Install] -WantedBy=multi-user.target -``` - -### Step 4: Start Service - -```bash -# Reload systemd -sudo systemctl daemon-reload - -# Enable service to start on boot -sudo systemctl enable people-chain-rpc - -# Start the node -sudo systemctl start people-chain-rpc - -# Check status and wait for sync -sudo systemctl status people-chain-rpc -sudo journalctl -u people-chain-rpc -f -``` - -### Step 5: Verify Setup - -Use the same verification tests as in the Docker setup (see Step 4 above). - ---- - -## Monitoring and Maintenance - -### Log Management - -**Docker Setup**: - -```bash -# View node logs -docker logs -f people-chain-rpc -``` - -**Systemd Setup**: - -```bash -# View node logs -sudo journalctl -u people-chain-rpc -f - -# View recent logs -sudo journalctl -u people-chain-rpc -n 100 - -# Filter for errors -sudo journalctl -u people-chain-rpc | grep -i error -``` - -### Performance Monitoring - -Monitor key metrics: - -- **Sync status**: Ensure node stays fully synced -- **Peer connections**: Maintain 30+ peers for good connectivity -- **Resource usage**: Monitor CPU, RAM, and disk I/O -- **RPC request latency**: Track response times for the Polkadot SDK API -- **Connection count**: Monitor active RPC connections - -**Prometheus Metrics**: - -Metrics are available at `http://localhost:9615/metrics` - -Example Prometheus scrape configuration: - -{% raw %} -```yaml -scrape_configs: - - job_name: 'people-chain-rpc' - static_configs: - - targets: ['localhost:9615'] -``` -{% endraw %} - -**Key Metrics to Monitor**: +This guide provides two options for deployment: + +- **Docker-based Setup**: Best for simpler set up and maintenance +- **Manual/systemd Setup**: Best for production environments requiring more control + +Select the best option for your project, then use the steps in the following tabs to complete set up. + +=== "Docker-Based Setup" + + This option uses Docker containers for the Polkadot SDK node, making it easy to set up and manage. Follow these steps to set your RPC node using Docker: + + 1. Download your parachain's chain specification as described in [Obtaining a Chain Specification](#obtaining-a-chain-specification). + + 2. (Optional but recommended) Download database snapshots: + - Using pre-synchronized snapshots significantly reduces initial sync time from several days to just a few hours. You need to download both parachain and relay chain data. + - You can obtain the latest snapshot from the [Snapshot Provider](https://snapshots.polkadot.io/){target=\_blank}. Follow these steps to download and use snapshots: + + !!! note + + Snapshots are available for system parachains and the Polkadot relay chain. For other parachains, check with the parachain team for snapshot availability or sync from genesis. + + 1. Create new directories with the following commands: + ```bash + mkdir -p my-node-data/chains/people-polkadot/db + mkdir -p my-node-data/chains/polkadot/db + ``` + 2. Download the appropriate snapshot using the following commands: + + === "Archive snapshot" + + Contains complete history, recommended for RPC with historical data. + ```bash + # Check https://snapshots.polkadot.io/ for the latest snapshot URL + export SNAPSHOT_URL_PARACHAIN="https://snapshots.polkadot.io/polkadot-people-rocksdb-archive/LATEST" + + rclone copyurl $SNAPSHOT_URL_PARACHAIN/files.txt files.txt + rclone copy --progress --transfers 20 \ + --http-url $SNAPSHOT_URL_PARACHAIN \ + --no-traverse --http-no-head --disable-http2 \ + --inplace --no-gzip-encoding --size-only \ + --retries 6 --retries-sleep 10s \ + --files-from files.txt :http: my-node-data/chains/people-polkadot/db/ + + rm files.txt + ``` + + - `--transfers 20`: Uses 20 parallel transfers for faster download. + - `--retries 6`: Automatically retries failed transfers up to 6 times. + - `--retries-sleep 10s`: Waits 10 seconds between retry attempts. + - `--size-only`: Only transfers if sizes differ (prevents unnecessary re-downloads). + + === "Pruned snapshot" + + Contains recent state for a smaller package size, recommended for RPC nodes. + ```bash + # Check https://snapshots.polkadot.io/ for the latest snapshot URL + export SNAPSHOT_URL_RELAY="https://snapshots.polkadot.io/polkadot-rocksdb-prune/LATEST" + + rclone copyurl $SNAPSHOT_URL_RELAY/files.txt files.txt + rclone copy --progress --transfers 20 \ + --http-url $SNAPSHOT_URL_RELAY \ + --no-traverse --http-no-head --disable-http2 \ + --inplace --no-gzip-encoding --size-only \ + --retries 6 --retries-sleep 10s \ + --files-from files.txt :http: my-node-data/chains/polkadot/db/ + + rm files.txt + ``` + + 3. Launch the parachain node using the official [Parity Docker image](https://hub.docker.com/r/parity/polkadot-parachain){target=\_blank} with the following command: + ```bash + docker run -d --name people-chain-rpc --restart unless-stopped \ + -p 9944:9944 \ + -p 9933:9933 \ + -p 9615:9615 \ + -p 30334:30334 \ + -p 30333:30333 \ + -v $(pwd)/people-polkadot.json:/people-polkadot.json \ + -v $(pwd)/my-node-data:/data \ + parity/polkadot-parachain:stable2509-2 \ + --name=PeopleChainRPC \ + --base-path=/data \ + --chain=/people-polkadot.json \ + --prometheus-external \ + --prometheus-port 9615 \ + --unsafe-rpc-external \ + --rpc-port=9944 \ + --rpc-cors=all \ + --rpc-methods=safe \ + --rpc-max-connections=1000 \ + --state-pruning=archive \ + --blocks-pruning=archive \ + -- \ + --base-path=/data \ + --chain=polkadot \ + --state-pruning=256 \ + --blocks-pruning=archive-canonical + ``` + + !!! note + + The `parity/polkadot-parachain` image works for system parachains and parachains built with standard Cumulus templates. For parachains with custom runtimes, check the parachain's documentation for their specific Docker image or binary. + + Critical configuration parameters include port mappings and node parameters: + + === "Port mappings" + + - `9944`: Polkadot SDK RPC endpoint (WebSocket/HTTP) + - `9933`: Polkadot SDK HTTP RPC endpoint + - `9615`: Prometheus metrics endpoint + - `30333/30334`: P2P networking ports + + === "Node parameters" + + - `--unsafe-rpc-external`: Enables external RPC access + - `--rpc-cors=all`: Allows all origins for CORS + - `--rpc-methods=safe`: Only allows safe RPC methods + - `--state-pruning=archive`: Keeps complete state history + - `--blocks-pruning=archive`: Keeps all block data + - `--prometheus-external`: Exposes metrics externally + + !!! warning + + The `--unsafe-rpc-external` flag should only be used in development or properly secured environments. For production, use a reverse proxy with authentication. + + 4. Monitor the node synchronization status using the following command: + ```bash + curl -H "Content-Type: application/json" \ + -d '{"id":1, "jsonrpc":"2.0", "method": "system_syncState", "params":[]}' \ + http://localhost:9944 + ``` + + You should see a response similar to the following: + + ```json + { + "jsonrpc":"2.0", + "id":1, + "result":{ + "startingBlock":0, + "currentBlock":3394816, + "highestBlock":3394816 + } + } + ``` + + When synchronization is complete, `currentBlock` will be equal to `highestBlock`. + + 5. You can use a few different commands to verify your node is running properly: + + - Get chain information: + ```bash + curl -H "Content-Type: application/json" \ + -d '{"id":1, "jsonrpc":"2.0", "method": "system_chain", "params":[]}' \ + http://localhost:9944 + ``` + - Get the latest block: + ```bash + curl -H "Content-Type: application/json" \ + -d '{"id":1, "jsonrpc":"2.0", "method": "chain_getHeader", "params":[]}' \ + http://localhost:9944 + ``` + - Query node health: + ```bash + curl -H "Content-Type: application/json" \ + -d '{"id":1, "jsonrpc":"2.0", "method": "system_health", "params":[]}' \ + http://localhost:9944 + ``` + + 6. Use the following commands to manage your Docker containers: + + - View node logs: + ```bash + docker logs -f people-chain-rpc + ``` + - Stop container: + ```bash + docker stop people-chain-rpc + ``` + - Start container: + ```bash + docker start people-chain-rpc + ``` + - Remove container: + ```bash + docker rm people-chain-rpc + ``` + +=== "Manual systemd Setup" + + This option provides more control and is recommended for production environments requiring custom configurations. + + 1. Download the `polkadot-parachain` binary from the latest stable [Polkadot SDK release](https://github.com/paritytech/polkadot-sdk/releases){target=\_blank}: + ```bash + # Download the latest stable release (check releases page for current version) + wget https://github.com/paritytech/polkadot-sdk/releases/download/polkadot-stable2509-2/polkadot-parachain + + # Make it executable and move to system path + chmod +x polkadot-parachain + sudo mv polkadot-parachain /usr/local/bin/ + + # Verify installation + polkadot-parachain --version + ``` + + Check the [Polkadot SDK releases](https://github.com/paritytech/polkadot-sdk/releases){target=\_blank} page for the latest stable version. + + 2. Download your parachain's chain specification as described in [Obtaining a Chain Specification](#obtaining-a-chain-specification). + + 3. Create user and directory structures using the following commands: + - Create a dedicated user: + ```bash + sudo useradd -r -s /bin/bash polkadot + ``` + - Create data directory: + ```bash + sudo mkdir -p /var/lib/people-chain-rpc + ``` + - Copy the chain spec to the directory: + ```bash + sudo cp people-polkadot.json /var/lib/people-chain-rpc/ + ``` + - Set permissions: + ```bash + sudo chown -R polkadot:polkadot /var/lib/people-chain-rpc + ``` + + 4. Create a systemd service file for the Polkadot SDK RPC node: + ```bash + sudo nano /etc/systemd/system/people-chain-rpc.service + ``` + + 5. Open the new service file and add the following configuration: + ```ini + [Unit] + Description=People Chain RPC Node + After=network.target + + [Service] + Type=simple + User=polkadot + Group=polkadot + WorkingDirectory=/var/lib/people-chain-rpc + + ExecStart=/usr/local/bin/polkadot-parachain \ + --name=PeopleChainRPC \ + --chain=/var/lib/people-chain-rpc/people-polkadot.json \ + --base-path=/var/lib/people-chain-rpc \ + --port=30333 \ + --rpc-port=9944 \ + --rpc-external \ + --rpc-cors=all \ + --rpc-methods=safe \ + --rpc-max-connections=1000 \ + --prometheus-port=9615 \ + --prometheus-external \ + --state-pruning=archive \ + --blocks-pruning=archive \ + -- \ + --chain=polkadot \ + --base-path=/var/lib/people-chain-rpc \ + --port=30334 \ + --state-pruning=256 \ + --blocks-pruning=archive-canonical + + Restart=always + RestartSec=10 + LimitNOFILE=65536 + + [Install] + WantedBy=multi-user.target + ``` + + 6. Start the service using the following commands: + - Reload systemd: + ```bash + sudo systemctl daemon-reload + ``` + - Enable service to start on boot: + ```bash + sudo systemctl enable people-chain-rpc + ``` + - Start the Polkadot SDK node: + ```bash + sudo systemctl start people-chain-rpc + ``` + - Check status and wait for sync: + ```bash + sudo systemctl status people-chain-rpc + sudo journalctl -u people-chain-rpc -f + ``` + + 7. You can use a few different commands to verify your node is running properly: + - Get chain information: + ```bash + curl -H "Content-Type: application/json" \ + -d '{"id":1, "jsonrpc":"2.0", "method": "system_chain", "params":[]}' \ + http://localhost:9944 + ``` + - Get the latest block: + ```bash + curl -H "Content-Type: application/json" \ + -d '{"id":1, "jsonrpc":"2.0", "method": "chain_getHeader", "params":[]}' \ + http://localhost:9944 + ``` + - Query node health: + ```bash + curl -H "Content-Type: application/json" \ + -d '{"id":1, "jsonrpc":"2.0", "method": "system_health", "params":[]}' \ + http://localhost:9944 + ``` + +## Monitor and Maintain RPC Node + +There are a few key monitoring and maintenance commands that can help you ensure RPC node uptime and performance including log monitoring and metrics. + +To view node logs, use the appropriate command for your setup: + +=== "Docker Setup" + + ```bash + docker logs -f people-chain-rpc + ``` + +=== "systemd Setup" + + - View node logs: + ```bash + sudo journalctl -u people-chain-rpc -f + ``` + - View recent logs: + ```bash + sudo journalctl -u people-chain-rpc -n 100 + ``` + - Filter for errors: + ```bash + sudo journalctl -u people-chain-rpc | grep -i error + ``` + +Monitoring key metrics like the following items can help you stay up to date on the performance and health of your node and allow you to intervene at the first sign of issues: + +- **Sync status**: Ensure node stays fully synced. +- **Peer connections**: Maintain 30+ peers for good connectivity. +- **Resource usage**: Monitor CPU, RAM, and disk I/O. +- **RPC request latency**: Track response times for the Polkadot SDK API. +- **Connection count**: Monitor active RPC connections. + +You can use the following information to configure [Prometheus](https://prometheus.io/docs/introduction/first_steps/){target=\_blank} to monitor, collect, and store your RPC node metrics: + +- **URL**: Metrics are available to view at `http://localhost:9615/metrics` +- **Example Prometheus configuration**: Update your `prometheus.yml` to add the following code: + {% raw %} + ```yaml + scrape_configs: + - job_name: 'people-chain-rpc' + static_configs: + - targets: ['localhost:9615'] + ``` + {% endraw %} + +Key metrics to monitor via Prometheus include: - `substrate_block_height`: Current block height - `substrate_finalized_height`: Finalized block height @@ -517,59 +459,67 @@ scrape_configs: ### Database Maintenance -Check database size periodically: +Check database size periodically using the commands for your selected setup: -```bash -# Docker setup -du -sh my-node-data +=== "Docker Setup" -# Systemd setup -du -sh /var/lib/people-chain-rpc -``` + ```bash + du -sh my-node-data + ``` -The node handles pruning automatically based on configuration unless running in archive mode. +=== "systemd Setup" -### Updates and Upgrades + ```bash + du -sh /var/lib/people-chain-rpc + ``` -**Docker Setup**: - -```bash -# Pull latest image -docker pull parity/polkadot-parachain: - -# Restart container -docker stop people-chain-rpc -docker rm people-chain-rpc - -# Start new container (use same command from setup with updated image tag) -``` - -**Systemd Setup**: - -```bash -# Stop service -sudo systemctl stop people-chain-rpc - -# Backup data -sudo cp -r /var/lib/people-chain-rpc /var/lib/people-chain-rpc.backup +The node handles pruning automatically based on configuration unless running in archive mode. -# Pull new image and extract binary -docker pull parity/polkadot-parachain: -docker create --name temp-parachain parity/polkadot-parachain: -sudo docker cp temp-parachain:/usr/local/bin/polkadot-parachain /usr/local/bin/ -docker rm temp-parachain +### Updates and Upgrades -# Restart service -sudo systemctl start people-chain-rpc -``` +Use the following commands for updating or upgrading your RPC node according to your setup: + +=== "Docker Setup" + + 1. Stop and remove the existing container: + ```bash + docker stop people-chain-rpc + docker rm people-chain-rpc + ``` + 2. Pull the latest image: + ```bash + docker pull parity/polkadot-parachain: + ``` + 3. Start the new container using the same command from the setup section with the updated image tag. + +=== "systemd Setup" + + 1. Stop the service: + ```bash + sudo systemctl stop people-chain-rpc + ``` + 2. Backup data: + ```bash + sudo cp -r /var/lib/people-chain-rpc /var/lib/people-chain-rpc.backup + ``` + 3. Download the new binary from [GitHub releases](https://github.com/paritytech/polkadot-sdk/releases){target=\_blank}: + ```bash + wget https://github.com/paritytech/polkadot-sdk/releases/download//polkadot-parachain + chmod +x polkadot-parachain + sudo mv polkadot-parachain /usr/local/bin/ + ``` + 4. Restart the service: + ```bash + sudo systemctl start people-chain-rpc + ``` ## Conclusion Running a parachain RPC node provides critical infrastructure for accessing Polkadot network services. By following this guide, you have set up a production-ready RPC node that: -- Provides reliable access to parachain functionality for applications and users -- Supports flexible deployment with both Docker and systemd options -- Implements comprehensive monitoring, security, and maintenance practices -- Can be adapted for any parachain by substituting the appropriate chain specification +- Provides reliable access to parachain functionality for applications and users. +- Supports flexible deployment with both Docker and systemd options. +- Implements comprehensive monitoring, security, and maintenance practices. +- Can be adapted for any parachain by substituting the appropriate chain specification. Whether you're running a node for system parachains (People Chain, Bridge Hub, Coretime Chain) or other parachains in the ecosystem, regular maintenance and monitoring will ensure your RPC node continues to provide reliable service. Stay updated with the latest releases and best practices to keep your infrastructure secure and performant. diff --git a/.ai/pages/node-infrastructure-run-a-node-polkadot-hub-rpc.md b/.ai/pages/node-infrastructure-run-a-node-polkadot-hub-rpc.md index e1dab7997..6c5880316 100644 --- a/.ai/pages/node-infrastructure-run-a-node-polkadot-hub-rpc.md +++ b/.ai/pages/node-infrastructure-run-a-node-polkadot-hub-rpc.md @@ -249,20 +249,19 @@ Select the best option for your project, then use the steps in the following tab This option provides more control and is recommended for production environments requiring custom configurations. - 1. Install the Polkadot Parachain binary by extracting it from the official Docker image: + 1. Download the `polkadot-parachain` binary from the latest stable [Polkadot SDK release](https://github.com/paritytech/polkadot-sdk/releases){target=\_blank}: ```bash - # Pull the image and extract binary - docker pull parity/polkadot-parachain:stable2509-2 - docker create --name temp-parachain parity/polkadot-parachain:stable2509-2 - sudo docker cp temp-parachain:/usr/local/bin/polkadot-parachain /usr/local/bin/ - docker rm temp-parachain + # Download the latest stable release (check releases page for current version) + wget https://github.com/paritytech/polkadot-sdk/releases/download/polkadot-stable2509-2/polkadot-parachain + + # Make it executable and move to system path + chmod +x polkadot-parachain + sudo mv polkadot-parachain /usr/local/bin/ # Verify installation polkadot-parachain --version ``` - Check [Docker Hub](https://hub.docker.com/r/parity/polkadot-parachain/tags){target=\_blank} for the latest stable tags. - 2. Download the Polkadot Hub chain specification: ```bash curl -L https://raw.githubusercontent.com/paritytech/polkadot-sdk/master/cumulus/parachains/chain-specs/asset-hub-polkadot.json -o asset-hub-polkadot.json @@ -471,12 +470,11 @@ Use the following commands for updating or upgrading your RPC node according to ```bash sudo cp -r /var/lib/polkadot-hub-rpc /var/lib/polkadot-hub-rpc.backup ``` - 3. Pull the new image and extract the binary: + 3. Download the new binary from [GitHub releases](https://github.com/paritytech/polkadot-sdk/releases){target=\_blank}: ```bash - docker pull parity/polkadot-parachain: - docker create --name temp-parachain parity/polkadot-parachain: - sudo docker cp temp-parachain:/usr/local/bin/polkadot-parachain /usr/local/bin/ - docker rm temp-parachain + wget https://github.com/paritytech/polkadot-sdk/releases/download//polkadot-parachain + chmod +x polkadot-parachain + sudo mv polkadot-parachain /usr/local/bin/ ``` 4. Restart the service: ```bash diff --git a/node-infrastructure/run-a-node/polkadot-hub-rpc.md b/node-infrastructure/run-a-node/polkadot-hub-rpc.md index 8104bff42..a7dd6388a 100644 --- a/node-infrastructure/run-a-node/polkadot-hub-rpc.md +++ b/node-infrastructure/run-a-node/polkadot-hub-rpc.md @@ -261,8 +261,6 @@ Select the best option for your project, then use the steps in the following tab polkadot-parachain --version ``` - Check the [Polkadot SDK releases](https://github.com/paritytech/polkadot-sdk/releases){target=\_blank} page for the latest stable version. - 2. Download the Polkadot Hub chain specification: ```bash curl -L https://raw.githubusercontent.com/paritytech/polkadot-sdk/master/cumulus/parachains/chain-specs/asset-hub-polkadot.json -o asset-hub-polkadot.json From 6822d5717b00fcd843c4445a90bc96a43634caa2 Mon Sep 17 00:00:00 2001 From: DAWN KELLY Date: Mon, 24 Nov 2025 11:11:11 -0500 Subject: [PATCH 20/39] wip rpc page cleanup --- node-infrastructure/run-a-node/polkadot-hub-rpc.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/node-infrastructure/run-a-node/polkadot-hub-rpc.md b/node-infrastructure/run-a-node/polkadot-hub-rpc.md index a7dd6388a..9b956861c 100644 --- a/node-infrastructure/run-a-node/polkadot-hub-rpc.md +++ b/node-infrastructure/run-a-node/polkadot-hub-rpc.md @@ -79,7 +79,7 @@ Select the best option for your project, then use the steps in the following tab This chain specification is the official configuration file that defines the network parameters for Polkadot Hub. - 2. (Optional but recommended) Download database snapshots + 2. (Optional but recommended) Download database snapshots: - Using pre-synchronized snapshots significantly reduces initial sync time from several days to just a few hours. You need to download both parachain and relay chain data. - You can obtain the latest snapshot from the [Snapshot Provider](https://snapshots.polkadot.io/){target=\_blank}. Follow these steps to download and use snapshots: 1. Create new directories with the following commands: @@ -189,7 +189,7 @@ Select the best option for your project, then use the steps in the following tab ``` You should see a response similar to the following: - + ```json { "jsonrpc":"2.0", From 65132eda66d751a2cf8aa97db4010b57a435d877 Mon Sep 17 00:00:00 2001 From: Bruno Galvao Date: Wed, 26 Nov 2025 12:39:43 +0700 Subject: [PATCH 21/39] Update content --- .ai/pages/node-infrastructure-overview.md | 15 +- ...-infrastructure-run-a-collator-collator.md | 79 ++-- ...infrastructure-run-a-node-parachain-rpc.md | 405 ++++++++-------- ...rastructure-run-a-node-polkadot-hub-rpc.md | 437 +++++++++--------- node-infrastructure/overview.md | 15 +- .../run-a-collator/collator.md | 77 ++- .../run-a-node/parachain-rpc.md | 403 ++++++++-------- .../run-a-node/polkadot-hub-rpc.md | 433 ++++++++--------- 8 files changed, 945 insertions(+), 919 deletions(-) diff --git a/.ai/pages/node-infrastructure-overview.md b/.ai/pages/node-infrastructure-overview.md index fe7e4f507..15da08c89 100644 --- a/.ai/pages/node-infrastructure-overview.md +++ b/.ai/pages/node-infrastructure-overview.md @@ -24,7 +24,12 @@ RPC nodes provide API access to blockchain data without participating in consens - **Wallets**: Check balances and broadcast transactions - **Development**: Test and debug applications -RPC nodes can be run for both the relay chain and parachains, with varying levels of data retention (pruned vs archive). +RPC nodes can be run for both the relay chain and parachains, with varying levels of data retention: + +- **Pruned Nodes**: Keep recent state and a limited number of finalized blocks. Suitable for most applications that only need current state and recent history. More efficient in terms of storage and sync time. +- **Archive Nodes**: Maintain complete historical state and all blocks since genesis. Required for block explorers, analytics platforms, or applications that need to query historical data at any point in time. + +**Transaction Broadcasting**: RPC nodes play a crucial role in transaction submission and propagation. When a client submits a transaction via RPC methods like `author_submitExtrinsic`, the node validates the transaction format, adds it to its local transaction pool, and broadcasts it across the P2P network. Block producers (collators or validators) then pick up these transactions from their pools for inclusion in blocks. This makes RPC nodes the primary gateway for users and applications to interact with the blockchain. ### Collators @@ -32,17 +37,17 @@ Collators are block producers for parachains. They perform critical functions: - **Collect transactions**: Aggregate user transactions into blocks - **Produce blocks**: Create parachain block candidates -- **Generate proofs**: Produce state transition proofs (Proof-of-Validity) -- **Submit to validators**: Send block candidates to relay chain validators +- **Generate and package PoV**: Generate the Proof-of-Validity containing the state transition proof and necessary witness data for validation +- **Submit to validators**: Send block candidates and PoVs to relay chain validators Unlike validators, collators do not provide security guarantees—that responsibility lies with relay chain validators. However, collators are essential for parachain liveness and censorship resistance. ### Validators -Validators secure the Polkadot relay chain through Nominated Proof of Stake (NPoS). They: +Validators secure the Polkadot relay chain through [Nominated Proof of Stake (NPoS)](https://wiki.polkadot.network/docs/learn-staking){target=\_blank}. They: - **Validate blocks**: Verify parachain blocks and relay chain transactions -- **Participate in consensus**: Run BABE and GRANDPA protocols +- **Participate in consensus**: Run [BABE](https://wiki.polkadot.network/docs/learn-consensus#babe-block-production){target=\_blank} and [GRANDPA](https://wiki.polkadot.network/docs/learn-consensus#grandpa-finality-gadget){target=\_blank} protocols - **Earn rewards**: Receive staking rewards for honest behavior - **Risk slashing**: Face penalties for misbehavior or downtime diff --git a/.ai/pages/node-infrastructure-run-a-collator-collator.md b/.ai/pages/node-infrastructure-run-a-collator-collator.md index cf706b94e..8525e7ee4 100644 --- a/.ai/pages/node-infrastructure-run-a-collator-collator.md +++ b/.ai/pages/node-infrastructure-run-a-collator-collator.md @@ -31,7 +31,7 @@ Block-producing collators perform critical functions: - Send block candidates to relay chain validators. - Enable cross-chain message passing using XCM -Unlike relay chain validators, collators do not provide security guarantees—that responsibility lies with relay chain validators through the ELVES protocol. Rather, collators are essential for network liveness and censorship resistance. +Unlike relay chain validators, collators do not provide security guarantees—that responsibility lies with relay chain validators through the [ELVES protocol](https://wiki.polkadot.com/learn/learn-parachains-protocol/){target=\_blank}. Rather, collators are essential for network liveness and censorship resistance. ## Prerequisites @@ -57,7 +57,7 @@ Uptime is critical. Consider redundancy and monitoring to maintain block product ### Software Requirements -Collators use the **Polkadot Parachain** binary, the standard client for running Polkadot system parachains. +Collators use the Polkadot Parachain binary, the standard client for running Polkadot system parachains. Required software includes the following: @@ -143,6 +143,17 @@ Generate an account for on-chain transactions as follows: docker run -it parity/subkey:latest generate --scheme sr25519 ``` + The output will be similar to the following: + ```bash + Secret phrase: embody rail hour peanut .... badge syrup luggage canvas + Network ID: substrate + Secret seed: 0x6498dd3416c491406e2c8283c76760ce4ca018478888b42315e7718778f2c2e1 + Public key (hex): 0x2202210357e49390d4f8d868da983940fe220a0a0e00bc6feaeda462aa031810 + Account ID: 0x2202210357e49390d4f8d868da983940fe220a0a0e00bc6feaeda462aa031810 + Public key (SS58): 5CqJ7n72GvvF5ZzUT2HMj83KyDje4n8sXR8kuiK8HWtfDktF + SS58 Address: 5CqJ7n72GvvF5ZzUT2HMj83KyDje4n8sXR8kuiK8HWtfDktF + ``` + 2. Save the following items displayed in the output: - Secret phrase (seed) - Keep this secure! - Public key (hex) @@ -161,7 +172,7 @@ Download the chain specification for your target system parachain using one of t Follow these steps to download your specification from the Chainspec Collection: -1. Visit the [Chainspec Collection](https://paritytech.github.io/chainspecs/) website. +1. Visit the [Chainspec Collection](https://paritytech.github.io/chainspecs/){target=\_blank} website. 2. Find your target system parachain. 3. Download the chain specification JSON file. 4. Save it as `chain-spec.json`. @@ -315,6 +326,8 @@ The relay chain uses warp sync for faster synchronization. ## Generate Session Keys +Session keys are cryptographic keys used by your collator node to sign authorship information when producing blocks. They uniquely identify your collator on the network and must be registered on-chain before your collator can participate in block production. + Once your node is fully synced, use the following command to generate session keys via RPC: ```bash @@ -338,7 +351,7 @@ System parachains use different collator selection mechanisms. Explore the follo === "On-chain Selection" - - Some parachains use pallet-collator-selection. + - Some parachains use [pallet-collator-selection](https://paritytech.github.io/polkadot-sdk/master/pallet_collator_selection/index.html){target=\_blank}. - May require bonding tokens. - Automatic selection based on criteria. @@ -349,6 +362,8 @@ System parachains use different collator selection mechanisms. Explore the follo ### Registration Process +Collator registration authorizes your node to produce blocks on the network. The parachain's collator selection mechanism uses this on-chain registration to determine which nodes are eligible to author blocks. + The registration process varies by system parachain. General steps include the following: 1. Check the existing collators for your target parachain: @@ -375,61 +390,19 @@ The registration process varies by system parachain. General steps include the f - `proof`: 0x00 (typically) 6. Submit and sign the transaction. -4. If the parachain requires bonding tokens, use the follow these steps to submit them using Polkadot.js Apps: +4. (Optional - primarily for non-system parachains) If the parachain uses on-chain bonding for collator selection, register as a candidate using Polkadot.js Apps: + + !!! note + Most system parachains use invulnerables lists exclusively and do not require this step. Skip to step 5 if you're running a collator for a system parachain. + 1. Locate **Developer > Extrinsics**. 2. Select `collatorSelection.registerAsCandidate`. - 3. Submit the transaction with the required bond amount. - 4. Sign the transaction. + 3. Submit and sign the transaction. The required bond amount will be automatically reserved from your account based on the pallet's configured `CandidacyBond`. -5. If applying to join the invulnerables list, you must now await governance approval for your proposal. Monitor the [Polkadot Forum](https://forum.polkadot.network){target=\_blank} governance channels and announcements. Once approved, your collator is added to the invulnerables list and will begin producing blocks in the next session or era. +5. For system parachains using invulnerables lists, await governance approval for your proposal. Monitor the [Polkadot Forum](https://forum.polkadot.network){target=\_blank} governance channels and announcements. Once approved, your collator is added to the invulnerables list and will begin producing blocks in the next session or era. 6. Verify your collator is active by monitoring logs for block production messages like "Prepared block for proposing" and "Imported #123". See the [Log Management](#log-management) section for log viewing commands. -## Monitor and Maintain Your Collator - -Monitoring the following items will help ensure your collator runs efficiently to avoid service interruptions or down time: - -- **Block Production**: Monitor for block production using the appropriate command for your setup: - - === "Docker Setup" - - ```bash - docker logs polkadot-collator 2>&1 | grep -i "prepared block" - ``` - - === "systemd Setup" - - ```bash - sudo journalctl -u polkadot-collator | grep -i "prepared block" - ``` - -- **Peer Connections**: Maintain a sufficient amount of peers for good connectivity and set up alerts to notify if peer connections falls below ten. -- **Resource Usage**: Monitor CPU, RAM, and disk I/O and set up alerts for unusual or high usage. -- **Sync Status**: Ensure both chains stay synced and set up alerts for sync issues. - -### Prometheus Metrics - -You can use the following information to configure [Prometheus](https://prometheus.io/docs/introduction/first_steps/){target=\_blank} to monitor, collect, and store your collator node metrics: - -- **URL**: Metrics are available to view at `http://localhost:9615/metrics` -- **Example Prometheus configuration**: Update your `prometheus.yml` to add the following code: - {% raw %} - ```yaml - scrape_configs: - - job_name: 'polkadot-collator' - static_configs: - - targets: ['localhost:9615'] - ``` - {% endraw %} - -Key metrics to monitor via Prometheus include the following: - -- `substrate_block_height`: Current block height -- `substrate_finalized_height`: Finalized block height -- `substrate_peers_count`: Peer connections -- `substrate_ready_transactions_number`: Transaction queue - - ## Log Management Efficient log management is essential to ensure collator performance and uptime. Use the following commands to help you manage logs to monitor and maintain your collator: diff --git a/.ai/pages/node-infrastructure-run-a-node-parachain-rpc.md b/.ai/pages/node-infrastructure-run-a-node-parachain-rpc.md index 3d39db163..b5b394b3a 100644 --- a/.ai/pages/node-infrastructure-run-a-node-parachain-rpc.md +++ b/.ai/pages/node-infrastructure-run-a-node-parachain-rpc.md @@ -61,7 +61,7 @@ RPC nodes serving production traffic require robust hardware: - **CPU**: 8+ cores (16+ cores for high traffic) - **Memory**: 64 GB RAM minimum (128 GB recommended for high traffic) - **Storage**: - - 500 GB+ NVMe SSD for parachain state (archive nodes require 2-4 TB+) + - Storage requirements vary by parachain. System parachains: Asset Hub (~600-800 GB), Bridge Hub (~500-600 GB), Collectives (~400-500 GB), People Chain (~300-400 GB), Coretime (~300-400 GB). For non-system parachains, check the [snapshot sizes](https://snapshots.polkadot.io/){target=\_blank} if available. - Additional 200+ GB for relay chain pruned database - Fast disk I/O is critical for query performance - **Network**: @@ -116,11 +116,13 @@ Select the best option for your project, then use the steps in the following tab mkdir -p my-node-data/chains/people-polkadot/db mkdir -p my-node-data/chains/polkadot/db ``` - 2. Download the appropriate snapshot using the following commands: + 2. Download the appropriate snapshots using the following commands: - === "Archive snapshot" + === "Archive Node" - Contains complete history, recommended for RPC with historical data. + Archive node setup maintains complete parachain history. Download both parachain archive and relay chain pruned snapshots: + + **Parachain archive snapshot** (People Chain example): ```bash # Check https://snapshots.polkadot.io/ for the latest snapshot URL export SNAPSHOT_URL_PARACHAIN="https://snapshots.polkadot.io/polkadot-people-rocksdb-archive/LATEST" @@ -136,14 +138,50 @@ Select the best option for your project, then use the steps in the following tab rm files.txt ``` - - `--transfers 20`: Uses 20 parallel transfers for faster download. - - `--retries 6`: Automatically retries failed transfers up to 6 times. - - `--retries-sleep 10s`: Waits 10 seconds between retry attempts. - - `--size-only`: Only transfers if sizes differ (prevents unnecessary re-downloads). + **Relay chain pruned snapshot** (~200 GB): + ```bash + # Check https://snapshots.polkadot.io/ for the latest snapshot URL + export SNAPSHOT_URL_RELAY="https://snapshots.polkadot.io/polkadot-rocksdb-prune/LATEST" + + rclone copyurl $SNAPSHOT_URL_RELAY/files.txt files.txt + rclone copy --progress --transfers 20 \ + --http-url $SNAPSHOT_URL_RELAY \ + --no-traverse --http-no-head --disable-http2 \ + --inplace --no-gzip-encoding --size-only \ + --retries 6 --retries-sleep 10s \ + --files-from files.txt :http: my-node-data/chains/polkadot/db/ + + rm files.txt + ``` + + **rclone parameters:** + + - `--transfers 20`: Uses 20 parallel transfers for faster download + - `--retries 6`: Automatically retries failed transfers up to 6 times + - `--retries-sleep 10s`: Waits 10 seconds between retry attempts + - `--size-only`: Only transfers if sizes differ (prevents unnecessary re-downloads) + + === "Pruned Node" + + Pruned node setup keeps recent state for smaller storage. Download both parachain pruned and relay chain pruned snapshots: + + **Parachain pruned snapshot** (People Chain example): + ```bash + # Check https://snapshots.polkadot.io/ for the latest snapshot URL + export SNAPSHOT_URL_PARACHAIN="https://snapshots.polkadot.io/polkadot-people-rocksdb-prune/LATEST" + + rclone copyurl $SNAPSHOT_URL_PARACHAIN/files.txt files.txt + rclone copy --progress --transfers 20 \ + --http-url $SNAPSHOT_URL_PARACHAIN \ + --no-traverse --http-no-head --disable-http2 \ + --inplace --no-gzip-encoding --size-only \ + --retries 6 --retries-sleep 10s \ + --files-from files.txt :http: my-node-data/chains/people-polkadot/db/ - === "Pruned snapshot" + rm files.txt + ``` - Contains recent state for a smaller package size, recommended for RPC nodes. + **Relay chain pruned snapshot** (~200 GB): ```bash # Check https://snapshots.polkadot.io/ for the latest snapshot URL export SNAPSHOT_URL_RELAY="https://snapshots.polkadot.io/polkadot-rocksdb-prune/LATEST" @@ -159,35 +197,80 @@ Select the best option for your project, then use the steps in the following tab rm files.txt ``` - 3. Launch the parachain node using the official [Parity Docker image](https://hub.docker.com/r/parity/polkadot-parachain){target=\_blank} with the following command: - ```bash - docker run -d --name people-chain-rpc --restart unless-stopped \ - -p 9944:9944 \ - -p 9933:9933 \ - -p 9615:9615 \ - -p 30334:30334 \ - -p 30333:30333 \ - -v $(pwd)/people-polkadot.json:/people-polkadot.json \ - -v $(pwd)/my-node-data:/data \ - parity/polkadot-parachain:stable2509-2 \ - --name=PeopleChainRPC \ - --base-path=/data \ - --chain=/people-polkadot.json \ - --prometheus-external \ - --prometheus-port 9615 \ - --unsafe-rpc-external \ - --rpc-port=9944 \ - --rpc-cors=all \ - --rpc-methods=safe \ - --rpc-max-connections=1000 \ - --state-pruning=archive \ - --blocks-pruning=archive \ - -- \ - --base-path=/data \ - --chain=polkadot \ - --state-pruning=256 \ - --blocks-pruning=archive-canonical - ``` + **rclone parameters:** + + - `--transfers 20`: Uses 20 parallel transfers for faster download + - `--retries 6`: Automatically retries failed transfers up to 6 times + - `--retries-sleep 10s`: Waits 10 seconds between retry attempts + - `--size-only`: Only transfers if sizes differ (prevents unnecessary re-downloads) + + 3. Launch the parachain node using the official [Parity Docker image](https://hub.docker.com/r/parity/polkadot-parachain){target=\_blank}: + + === "Archive Node" + + Archive node configuration maintains complete parachain history for historical queries: + + ```bash + docker run -d --name people-chain-rpc --restart unless-stopped \ + -p 9944:9944 \ + -p 9933:9933 \ + -p 9615:9615 \ + -p 30334:30334 \ + -p 30333:30333 \ + -v $(pwd)/people-polkadot.json:/people-polkadot.json \ + -v $(pwd)/my-node-data:/data \ + parity/polkadot-parachain:stable2509-2 \ + --name=PeopleChainRPC \ + --base-path=/data \ + --chain=/people-polkadot.json \ + --prometheus-external \ + --prometheus-port 9615 \ + --unsafe-rpc-external \ + --rpc-port=9944 \ + --rpc-cors=all \ + --rpc-methods=safe \ + --rpc-max-connections=1000 \ + --state-pruning=archive \ + --blocks-pruning=archive \ + -- \ + --base-path=/data \ + --chain=polkadot \ + --state-pruning=256 \ + --blocks-pruning=archive-canonical + ``` + + === "Pruned Node" + + Pruned node configuration keeps recent state for smaller storage requirements: + + ```bash + docker run -d --name people-chain-rpc --restart unless-stopped \ + -p 9944:9944 \ + -p 9933:9933 \ + -p 9615:9615 \ + -p 30334:30334 \ + -p 30333:30333 \ + -v $(pwd)/people-polkadot.json:/people-polkadot.json \ + -v $(pwd)/my-node-data:/data \ + parity/polkadot-parachain:stable2509-2 \ + --name=PeopleChainRPC \ + --base-path=/data \ + --chain=/people-polkadot.json \ + --prometheus-external \ + --prometheus-port 9615 \ + --unsafe-rpc-external \ + --rpc-port=9944 \ + --rpc-cors=all \ + --rpc-methods=safe \ + --rpc-max-connections=1000 \ + --state-pruning=1000 \ + --blocks-pruning=256 \ + -- \ + --base-path=/data \ + --chain=polkadot \ + --state-pruning=256 \ + --blocks-pruning=archive-canonical + ``` !!! note @@ -207,8 +290,8 @@ Select the best option for your project, then use the steps in the following tab - `--unsafe-rpc-external`: Enables external RPC access - `--rpc-cors=all`: Allows all origins for CORS - `--rpc-methods=safe`: Only allows safe RPC methods - - `--state-pruning=archive`: Keeps complete state history - - `--blocks-pruning=archive`: Keeps all block data + - `--state-pruning=archive` or `--state-pruning=1000`: Archive keeps complete state history, pruned keeps last 1000 blocks + - `--blocks-pruning=archive` or `--blocks-pruning=256`: Archive keeps all blocks, pruned keeps last 256 finalized blocks - `--prometheus-external`: Exposes metrics externally !!! warning @@ -322,46 +405,95 @@ Select the best option for your project, then use the steps in the following tab sudo nano /etc/systemd/system/people-chain-rpc.service ``` - 5. Open the new service file and add the following configuration: - ```ini - [Unit] - Description=People Chain RPC Node - After=network.target - - [Service] - Type=simple - User=polkadot - Group=polkadot - WorkingDirectory=/var/lib/people-chain-rpc - - ExecStart=/usr/local/bin/polkadot-parachain \ - --name=PeopleChainRPC \ - --chain=/var/lib/people-chain-rpc/people-polkadot.json \ - --base-path=/var/lib/people-chain-rpc \ - --port=30333 \ - --rpc-port=9944 \ - --rpc-external \ - --rpc-cors=all \ - --rpc-methods=safe \ - --rpc-max-connections=1000 \ - --prometheus-port=9615 \ - --prometheus-external \ - --state-pruning=archive \ - --blocks-pruning=archive \ - -- \ - --chain=polkadot \ - --base-path=/var/lib/people-chain-rpc \ - --port=30334 \ - --state-pruning=256 \ - --blocks-pruning=archive-canonical - - Restart=always - RestartSec=10 - LimitNOFILE=65536 - - [Install] - WantedBy=multi-user.target - ``` + 5. Open the new service file and add the configuration for your chosen node type: + + === "Archive Node" + + Archive node configuration maintains complete parachain history for historical queries: + + ```ini + [Unit] + Description=People Chain RPC Node + After=network.target + + [Service] + Type=simple + User=polkadot + Group=polkadot + WorkingDirectory=/var/lib/people-chain-rpc + + ExecStart=/usr/local/bin/polkadot-parachain \ + --name=PeopleChainRPC \ + --chain=/var/lib/people-chain-rpc/people-polkadot.json \ + --base-path=/var/lib/people-chain-rpc \ + --port=30333 \ + --rpc-port=9944 \ + --rpc-external \ + --rpc-cors=all \ + --rpc-methods=safe \ + --rpc-max-connections=1000 \ + --prometheus-port=9615 \ + --prometheus-external \ + --state-pruning=archive \ + --blocks-pruning=archive \ + -- \ + --chain=polkadot \ + --base-path=/var/lib/people-chain-rpc \ + --port=30334 \ + --state-pruning=256 \ + --blocks-pruning=archive-canonical + + Restart=always + RestartSec=10 + LimitNOFILE=65536 + + [Install] + WantedBy=multi-user.target + ``` + + === "Pruned Node" + + Pruned node configuration keeps recent state for smaller storage requirements: + + ```ini + [Unit] + Description=People Chain RPC Node + After=network.target + + [Service] + Type=simple + User=polkadot + Group=polkadot + WorkingDirectory=/var/lib/people-chain-rpc + + ExecStart=/usr/local/bin/polkadot-parachain \ + --name=PeopleChainRPC \ + --chain=/var/lib/people-chain-rpc/people-polkadot.json \ + --base-path=/var/lib/people-chain-rpc \ + --port=30333 \ + --rpc-port=9944 \ + --rpc-external \ + --rpc-cors=all \ + --rpc-methods=safe \ + --rpc-max-connections=1000 \ + --prometheus-port=9615 \ + --prometheus-external \ + --state-pruning=1000 \ + --blocks-pruning=256 \ + -- \ + --chain=polkadot \ + --base-path=/var/lib/people-chain-rpc \ + --port=30334 \ + --state-pruning=256 \ + --blocks-pruning=archive-canonical + + Restart=always + RestartSec=10 + LimitNOFILE=65536 + + [Install] + WantedBy=multi-user.target + ``` 6. Start the service using the following commands: - Reload systemd: @@ -402,117 +534,6 @@ Select the best option for your project, then use the steps in the following tab http://localhost:9944 ``` -## Monitor and Maintain RPC Node - -There are a few key monitoring and maintenance commands that can help you ensure RPC node uptime and performance including log monitoring and metrics. - -To view node logs, use the appropriate command for your setup: - -=== "Docker Setup" - - ```bash - docker logs -f people-chain-rpc - ``` - -=== "systemd Setup" - - - View node logs: - ```bash - sudo journalctl -u people-chain-rpc -f - ``` - - View recent logs: - ```bash - sudo journalctl -u people-chain-rpc -n 100 - ``` - - Filter for errors: - ```bash - sudo journalctl -u people-chain-rpc | grep -i error - ``` - -Monitoring key metrics like the following items can help you stay up to date on the performance and health of your node and allow you to intervene at the first sign of issues: - -- **Sync status**: Ensure node stays fully synced. -- **Peer connections**: Maintain 30+ peers for good connectivity. -- **Resource usage**: Monitor CPU, RAM, and disk I/O. -- **RPC request latency**: Track response times for the Polkadot SDK API. -- **Connection count**: Monitor active RPC connections. - -You can use the following information to configure [Prometheus](https://prometheus.io/docs/introduction/first_steps/){target=\_blank} to monitor, collect, and store your RPC node metrics: - -- **URL**: Metrics are available to view at `http://localhost:9615/metrics` -- **Example Prometheus configuration**: Update your `prometheus.yml` to add the following code: - {% raw %} - ```yaml - scrape_configs: - - job_name: 'people-chain-rpc' - static_configs: - - targets: ['localhost:9615'] - ``` - {% endraw %} - -Key metrics to monitor via Prometheus include: - -- `substrate_block_height`: Current block height -- `substrate_finalized_height`: Finalized block height -- `substrate_peers_count`: Number of connected peers -- `substrate_ready_transactions_number`: Transaction queue size - -### Database Maintenance - -Check database size periodically using the commands for your selected setup: - -=== "Docker Setup" - - ```bash - du -sh my-node-data - ``` - -=== "systemd Setup" - - ```bash - du -sh /var/lib/people-chain-rpc - ``` - -The node handles pruning automatically based on configuration unless running in archive mode. - -### Updates and Upgrades - -Use the following commands for updating or upgrading your RPC node according to your setup: - -=== "Docker Setup" - - 1. Stop and remove the existing container: - ```bash - docker stop people-chain-rpc - docker rm people-chain-rpc - ``` - 2. Pull the latest image: - ```bash - docker pull parity/polkadot-parachain: - ``` - 3. Start the new container using the same command from the setup section with the updated image tag. - -=== "systemd Setup" - - 1. Stop the service: - ```bash - sudo systemctl stop people-chain-rpc - ``` - 2. Backup data: - ```bash - sudo cp -r /var/lib/people-chain-rpc /var/lib/people-chain-rpc.backup - ``` - 3. Download the new binary from [GitHub releases](https://github.com/paritytech/polkadot-sdk/releases){target=\_blank}: - ```bash - wget https://github.com/paritytech/polkadot-sdk/releases/download//polkadot-parachain - chmod +x polkadot-parachain - sudo mv polkadot-parachain /usr/local/bin/ - ``` - 4. Restart the service: - ```bash - sudo systemctl start people-chain-rpc - ``` - ## Conclusion Running a parachain RPC node provides critical infrastructure for accessing Polkadot network services. By following this guide, you have set up a production-ready RPC node that: diff --git a/.ai/pages/node-infrastructure-run-a-node-polkadot-hub-rpc.md b/.ai/pages/node-infrastructure-run-a-node-polkadot-hub-rpc.md index 6c5880316..70fdd2192 100644 --- a/.ai/pages/node-infrastructure-run-a-node-polkadot-hub-rpc.md +++ b/.ai/pages/node-infrastructure-run-a-node-polkadot-hub-rpc.md @@ -16,6 +16,7 @@ url: https://docs.polkadot.com/node-infrastructure/run-a-node/polkadot-hub-rpc/ - **Cross-chain Communication**: XCM message handling Running an RPC node for Polkadot Hub enables applications, wallets, and users to interact with the parachain through: + - **Polkadot SDK Node RPC** (Port 9944): Native Polkadot API (WebSocket and HTTP) This setup enables block explorer indexing and provides full compatibility with Polkadot SDK development tools. @@ -33,7 +34,7 @@ RPC nodes serving production traffic require robust hardware. The following shou - **CPU**: 8+ cores (16+ cores for high traffic) - **Memory**: 64 GB RAM minimum (128 GB recommended for high traffic) - **Storage**: - - 500 GB+ NVMe SSD for parachain state (archive nodes require 2-4 TB+) + - 500 GB+ NVMe SSD for parachain state (archive nodes require 600-800 GB+) - Additional 200+ GB for relay chain pruned database - Fast disk I/O is critical for query performance - **Network**: @@ -80,7 +81,7 @@ Select the best option for your project, then use the steps in the following tab This chain specification is the official configuration file that defines the network parameters for Polkadot Hub. - 2. (Optional but recommended) Download database snapshots + 2. (Optional but recommended) Download database snapshots: - Using pre-synchronized snapshots significantly reduces initial sync time from several days to just a few hours. You need to download both parachain and relay chain data. - You can obtain the latest snapshot from the [Snapshot Provider](https://snapshots.polkadot.io/){target=\_blank}. Follow these steps to download and use snapshots: 1. Create new directories with the following commands: @@ -88,34 +89,72 @@ Select the best option for your project, then use the steps in the following tab mkdir -p my-node-data/chains/asset-hub-polkadot/db mkdir -p my-node-data/chains/polkadot/db ``` - 2. Download the appropriate snapshot using the following commands: + 2. Download the appropriate snapshots using the following commands: + + === "Archive Node" - === "Archive snapshot" + Archive node setup maintains complete parachain history (~600-800 GB total). Download both Asset Hub archive and Relay chain pruned snapshots: - Contains complete history, recommended for RPC with historical data. + **Asset Hub archive snapshot** (~400 GB): ```bash # Check https://snapshots.polkadot.io/ for the latest snapshot URL export SNAPSHOT_URL_ASSET_HUB="https://snapshots.polkadot.io/polkadot-asset-hub-rocksdb-archive/LATEST" rclone copyurl $SNAPSHOT_URL_ASSET_HUB/files.txt files.txt rclone copy --progress --transfers 20 \ - --http-url $SNAPSHOT_URL_ASSET_HUB \ - --no-traverse --http-no-head --disable-http2 \ - --inplace --no-gzip-encoding --size-only \ - --retries 6 --retries-sleep 10s \ - --files-from files.txt :http: my-node-data/chains/asset-hub-polkadot/db/ + --http-url $SNAPSHOT_URL_ASSET_HUB \ + --no-traverse --http-no-head --disable-http2 \ + --inplace --no-gzip-encoding --size-only \ + --retries 6 --retries-sleep 10s \ + --files-from files.txt :http: my-node-data/chains/asset-hub-polkadot/db/ rm files.txt ``` - - `--transfers 20`: Uses 20 parallel transfers for faster download. - - `--retries 6`: Automatically retries failed transfers up to 6 times. - - `--retries-sleep 10s`: Waits 10 seconds between retry attempts. - - `--size-only`: Only transfers if sizes differ (prevents unnecessary re-downloads). + **Relay chain pruned snapshot** (~200 GB): + ```bash + # Check https://snapshots.polkadot.io/ for the latest snapshot URL + export SNAPSHOT_URL_RELAY="https://snapshots.polkadot.io/polkadot-rocksdb-prune/LATEST" - === "Pruned snapshot" + rclone copyurl $SNAPSHOT_URL_RELAY/files.txt files.txt + rclone copy --progress --transfers 20 \ + --http-url $SNAPSHOT_URL_RELAY \ + --no-traverse --http-no-head --disable-http2 \ + --inplace --no-gzip-encoding --size-only \ + --retries 6 --retries-sleep 10s \ + --files-from files.txt :http: my-node-data/chains/polkadot/db/ - Contains recent state for a smaller package size, recommended for RPC nodes. + rm files.txt + ``` + + **rclone parameters:** + + - `--transfers 20`: Uses 20 parallel transfers for faster download + - `--retries 6`: Automatically retries failed transfers up to 6 times + - `--retries-sleep 10s`: Waits 10 seconds between retry attempts + - `--size-only`: Only transfers if sizes differ (prevents unnecessary re-downloads) + + === "Pruned Node" + + Pruned node setup keeps recent state for smaller storage (~500 GB total). Download both Asset Hub pruned and Relay chain pruned snapshots: + + **Asset Hub pruned snapshot**: + ```bash + # Check https://snapshots.polkadot.io/ for the latest snapshot URL + export SNAPSHOT_URL_ASSET_HUB="https://snapshots.polkadot.io/polkadot-asset-hub-rocksdb-prune/LATEST" + + rclone copyurl $SNAPSHOT_URL_ASSET_HUB/files.txt files.txt + rclone copy --progress --transfers 20 \ + --http-url $SNAPSHOT_URL_ASSET_HUB \ + --no-traverse --http-no-head --disable-http2 \ + --inplace --no-gzip-encoding --size-only \ + --retries 6 --retries-sleep 10s \ + --files-from files.txt :http: my-node-data/chains/asset-hub-polkadot/db/ + + rm files.txt + ``` + + **Relay chain pruned snapshot** (~200 GB): ```bash # Check https://snapshots.polkadot.io/ for the latest snapshot URL export SNAPSHOT_URL_RELAY="https://snapshots.polkadot.io/polkadot-rocksdb-prune/LATEST" @@ -128,37 +167,82 @@ Select the best option for your project, then use the steps in the following tab --retries 6 --retries-sleep 10s \ --files-from files.txt :http: my-node-data/chains/polkadot/db/ - rm files.txt + rm files.txt ``` - 3. Launch Polkadot Hub Node using the official [Parity Docker image](https://hub.docker.com/r/parity/polkadot-parachain){target=\_blank} with the following command: - ```bash - docker run -d --name polkadot-hub-rpc --restart unless-stopped \ - -p 9944:9944 \ - -p 9933:9933 \ - -p 9615:9615 \ - -p 30334:30334 \ - -p 30333:30333 \ - -v $(pwd)/asset-hub-polkadot.json:/asset-hub-polkadot.json \ - -v $(pwd)/my-node-data:/data \ - parity/polkadot-parachain:stable2509-2 \ - --name=PolkadotHubRPC \ - --base-path=/data \ - --chain=/asset-hub-polkadot.json \ - --prometheus-external \ - --prometheus-port 9615 \ - --unsafe-rpc-external \ - --rpc-port=9944 \ - --rpc-cors=all \ - --rpc-methods=safe \ - --rpc-max-connections=1000 \ - --state-pruning=archive \ - --blocks-pruning=archive \ - -- \ - --base-path=/data \ - --chain=polkadot \ - --state-pruning=256 \ - --blocks-pruning=archive-canonical - ``` + + **rclone parameters:** + + - `--transfers 20`: Uses 20 parallel transfers for faster download + - `--retries 6`: Automatically retries failed transfers up to 6 times + - `--retries-sleep 10s`: Waits 10 seconds between retry attempts + - `--size-only`: Only transfers if sizes differ (prevents unnecessary re-downloads) + 3. Launch Polkadot Hub Node using the official [Parity Docker image](https://hub.docker.com/r/parity/polkadot-parachain){target=\_blank}: + + === "Archive Node" + + Archive node configuration maintains complete parachain history for historical queries: + + ```bash + docker run -d --name polkadot-hub-rpc --restart unless-stopped \ + -p 9944:9944 \ + -p 9933:9933 \ + -p 9615:9615 \ + -p 30334:30334 \ + -p 30333:30333 \ + -v $(pwd)/asset-hub-polkadot.json:/asset-hub-polkadot.json \ + -v $(pwd)/my-node-data:/data \ + parity/polkadot-parachain:stable2509-2 \ + --name=PolkadotHubRPC \ + --base-path=/data \ + --chain=/asset-hub-polkadot.json \ + --prometheus-external \ + --prometheus-port 9615 \ + --unsafe-rpc-external \ + --rpc-port=9944 \ + --rpc-cors=all \ + --rpc-methods=safe \ + --rpc-max-connections=1000 \ + --state-pruning=archive \ + --blocks-pruning=archive \ + -- \ + --base-path=/data \ + --chain=polkadot \ + --state-pruning=256 \ + --blocks-pruning=archive-canonical + ``` + + === "Pruned Node" + + Pruned node configuration keeps recent state for smaller storage requirements: + + ```bash + docker run -d --name polkadot-hub-rpc --restart unless-stopped \ + -p 9944:9944 \ + -p 9933:9933 \ + -p 9615:9615 \ + -p 30334:30334 \ + -p 30333:30333 \ + -v $(pwd)/asset-hub-polkadot.json:/asset-hub-polkadot.json \ + -v $(pwd)/my-node-data:/data \ + parity/polkadot-parachain:stable2509-2 \ + --name=PolkadotHubRPC \ + --base-path=/data \ + --chain=/asset-hub-polkadot.json \ + --prometheus-external \ + --prometheus-port 9615 \ + --unsafe-rpc-external \ + --rpc-port=9944 \ + --rpc-cors=all \ + --rpc-methods=safe \ + --rpc-max-connections=1000 \ + --state-pruning=1000 \ + --blocks-pruning=256 \ + -- \ + --base-path=/data \ + --chain=polkadot \ + --state-pruning=256 \ + --blocks-pruning=archive-canonical + ``` Critical configuration parameters include port mappings and node parameters: @@ -174,8 +258,8 @@ Select the best option for your project, then use the steps in the following tab - `--unsafe-rpc-external`: Enables external RPC access - `--rpc-cors=all`: Allows all origins for CORS - `--rpc-methods=safe`: Only allows safe RPC methods - - `--state-pruning=archive`: Keeps complete state history - - `--blocks-pruning=archive`: Keeps all block data + - `--state-pruning=archive` or `--state-pruning=1000`: Archive keeps complete state history, pruned keeps last 1000 blocks + - `--blocks-pruning=archive` or `--blocks-pruning=256`: Archive keeps all blocks, pruned keeps last 256 finalized blocks - `--prometheus-external`: Exposes metrics externally !!! warning @@ -183,6 +267,7 @@ Select the best option for your project, then use the steps in the following tab The `--unsafe-rpc-external` flag should only be used in development or properly secured environments. For production, use a reverse proxy with authentication. 4. Monitor the node synchronization status using the following command: + ```bash curl -H "Content-Type: application/json" \ -d '{"id":1, "jsonrpc":"2.0", "method": "system_syncState", "params":[]}' \ @@ -190,7 +275,7 @@ Select the best option for your project, then use the steps in the following tab ``` You should see a response similar to the following: - + ```json { "jsonrpc":"2.0", @@ -205,20 +290,8 @@ Select the best option for your project, then use the steps in the following tab When synchronization is complete, `currentBlock` will be equal to `highestBlock`. - 5. You can use a few different commands to verify your node is running properly: + 5. You can use the `system_health` command to verify your node is running properly: - - Get chain information: - ```bash - curl -H "Content-Type: application/json" \ - -d '{"id":1, "jsonrpc":"2.0", "method": "system_chain", "params":[]}' \ - http://localhost:9944 - ``` - - Get the latest block: - ```bash - curl -H "Content-Type: application/json" \ - -d '{"id":1, "jsonrpc":"2.0", "method": "chain_getHeader", "params":[]}' \ - http://localhost:9944 - ``` - Query node health: ```bash curl -H "Content-Type: application/json" \ @@ -290,46 +363,95 @@ Select the best option for your project, then use the steps in the following tab sudo nano /etc/systemd/system/polkadot-hub-rpc.service ``` - 5. Open the new service file and add the following configuration: - ```ini - [Unit] - Description=Polkadot Hub RPC Node - After=network.target - - [Service] - Type=simple - User=polkadot - Group=polkadot - WorkingDirectory=/var/lib/polkadot-hub-rpc - - ExecStart=/usr/local/bin/polkadot-parachain \ - --name=PolkadotHubRPC \ - --chain=/var/lib/polkadot-hub-rpc/asset-hub-polkadot.json \ - --base-path=/var/lib/polkadot-hub-rpc \ - --port=30333 \ - --rpc-port=9944 \ - --rpc-external \ - --rpc-cors=all \ - --rpc-methods=safe \ - --rpc-max-connections=1000 \ - --prometheus-port=9615 \ - --prometheus-external \ - --state-pruning=archive \ - --blocks-pruning=archive \ - -- \ - --chain=polkadot \ - --base-path=/var/lib/polkadot-hub-rpc \ - --port=30334 \ - --state-pruning=256 \ - --blocks-pruning=archive-canonical - - Restart=always - RestartSec=10 - LimitNOFILE=65536 - - [Install] - WantedBy=multi-user.target - ``` + 5. Open the new service file and add the configuration for your chosen node type: + + === "Archive Node" + + Archive node configuration maintains complete parachain history for historical queries: + + ```ini + [Unit] + Description=Polkadot Hub RPC Node + After=network.target + + [Service] + Type=simple + User=polkadot + Group=polkadot + WorkingDirectory=/var/lib/polkadot-hub-rpc + + ExecStart=/usr/local/bin/polkadot-parachain \ + --name=PolkadotHubRPC \ + --chain=/var/lib/polkadot-hub-rpc/asset-hub-polkadot.json \ + --base-path=/var/lib/polkadot-hub-rpc \ + --port=30333 \ + --rpc-port=9944 \ + --rpc-external \ + --rpc-cors=all \ + --rpc-methods=safe \ + --rpc-max-connections=1000 \ + --prometheus-port=9615 \ + --prometheus-external \ + --state-pruning=archive \ + --blocks-pruning=archive \ + -- \ + --chain=polkadot \ + --base-path=/var/lib/polkadot-hub-rpc \ + --port=30334 \ + --state-pruning=256 \ + --blocks-pruning=archive-canonical + + Restart=always + RestartSec=10 + LimitNOFILE=65536 + + [Install] + WantedBy=multi-user.target + ``` + + === "Pruned Node" + + Pruned node configuration keeps recent state for smaller storage requirements: + + ```ini + [Unit] + Description=Polkadot Hub RPC Node + After=network.target + + [Service] + Type=simple + User=polkadot + Group=polkadot + WorkingDirectory=/var/lib/polkadot-hub-rpc + + ExecStart=/usr/local/bin/polkadot-parachain \ + --name=PolkadotHubRPC \ + --chain=/var/lib/polkadot-hub-rpc/asset-hub-polkadot.json \ + --base-path=/var/lib/polkadot-hub-rpc \ + --port=30333 \ + --rpc-port=9944 \ + --rpc-external \ + --rpc-cors=all \ + --rpc-methods=safe \ + --rpc-max-connections=1000 \ + --prometheus-port=9615 \ + --prometheus-external \ + --state-pruning=1000 \ + --blocks-pruning=256 \ + -- \ + --chain=polkadot \ + --base-path=/var/lib/polkadot-hub-rpc \ + --port=30334 \ + --state-pruning=256 \ + --blocks-pruning=archive-canonical + + Restart=always + RestartSec=10 + LimitNOFILE=65536 + + [Install] + WantedBy=multi-user.target + ``` 6. Start the service using the following commands: - Reload systemd: @@ -370,117 +492,6 @@ Select the best option for your project, then use the steps in the following tab http://localhost:9944 ``` -## Monitor and Maintain RPC Node - -There are a few key monitoring and maintenance commands that can help you ensure RPC node uptime and performance including log monitoring and metrics. - -To view node logs, use the appropriate command for your setup: - -=== "Docker Setup" - - ```bash - docker logs -f polkadot-hub-rpc - ``` - -=== "systemd Setup" - - - View node logs: - ```bash - sudo journalctl -u polkadot-hub-rpc -f - ``` - - View recent logs: - ```bash - sudo journalctl -u polkadot-hub-rpc -n 100 - ``` - - Filter for errors: - ```bash - sudo journalctl -u polkadot-hub-rpc | grep -i error - ``` - -Monitoring key metrics like the following items can help you stay up to date on the performance and health of your node and allow you to intervene at the first sign of issues: - -- **Sync status**: Ensure node stays fully synced. -- **Peer connections**: Maintain 30+ peers for good connectivity. -- **Resource usage**: Monitor CPU, RAM, and disk I/O. -- **RPC request latency**: Track response times for the Polkadot SDK API. -- **Connection count**: Monitor active RPC connections. - -You can use the following information to configure [Prometheus](https://prometheus.io/docs/introduction/first_steps/){target=\_blank} to monitor, collect, and store your RPC node metrics: - -- **URL**: Metrics are available to view at `http://localhost:9615/metrics` -- **Example Prometheus configuration**: Update your `prometheus.yml` to add the following code: - {% raw %} - ```yaml - scrape_configs: - - job_name: 'polkadot-hub-rpc' - static_configs: - - targets: ['localhost:9615'] - ``` - {% endraw %} - -Key metrics to monitor via Prometheus include: - -- `substrate_block_height`: Current block height -- `substrate_finalized_height`: Finalized block height -- `substrate_peers_count`: Number of connected peers -- `substrate_ready_transactions_number`: Transaction queue size - -### Database Maintenance - -Check database size periodically using the commands for your selected setup: - -=== "Docker Setup" - - ```bash - du -sh my-node-data - ``` - -=== "systemd Setup" - - ```bash - du -sh /var/lib/polkadot-hub-rpc - ``` - -The node handles pruning automatically based on configuration unless running in archive mode. - -### Updates and Upgrades - -Use the following commands for updating or upgrading your RPC node according to your setup: - -=== "Docker Setup" - - 1. Stop and remove the existing container: - ```bash - docker stop polkadot-hub-rpc - docker rm polkadot-hub-rpc - ``` - 2. Pull the latest image: - ```bash - docker pull parity/polkadot-parachain: - ``` - 3. Start the new container using the same command from the setup section with the updated image tag. - -=== "systemd Setup" - - 1. Stop the service: - ```bash - sudo systemctl stop polkadot-hub-rpc - ``` - 2. Backup data: - ```bash - sudo cp -r /var/lib/polkadot-hub-rpc /var/lib/polkadot-hub-rpc.backup - ``` - 3. Download the new binary from [GitHub releases](https://github.com/paritytech/polkadot-sdk/releases){target=\_blank}: - ```bash - wget https://github.com/paritytech/polkadot-sdk/releases/download//polkadot-parachain - chmod +x polkadot-parachain - sudo mv polkadot-parachain /usr/local/bin/ - ``` - 4. Restart the service: - ```bash - sudo systemctl start polkadot-hub-rpc - ``` - ## Conclusion Running an RPC node for Polkadot Hub provides essential infrastructure for applications and users to interact with the network. By following this guide, you have set up a production-ready RPC node that: diff --git a/node-infrastructure/overview.md b/node-infrastructure/overview.md index 13098d5ad..4b06c00ee 100644 --- a/node-infrastructure/overview.md +++ b/node-infrastructure/overview.md @@ -23,7 +23,12 @@ RPC nodes provide API access to blockchain data without participating in consens - **Wallets**: Check balances and broadcast transactions - **Development**: Test and debug applications -RPC nodes can be run for both the relay chain and parachains, with varying levels of data retention (pruned vs archive). +RPC nodes can be run for both the relay chain and parachains, with varying levels of data retention: + +- **Pruned Nodes**: Keep recent state and a limited number of finalized blocks. Suitable for most applications that only need current state and recent history. More efficient in terms of storage and sync time. +- **Archive Nodes**: Maintain complete historical state and all blocks since genesis. Required for block explorers, analytics platforms, or applications that need to query historical data at any point in time. + +**Transaction Broadcasting**: RPC nodes play a crucial role in transaction submission and propagation. When a client submits a transaction via RPC methods like `author_submitExtrinsic`, the node validates the transaction format, adds it to its local transaction pool, and broadcasts it across the P2P network. Block producers (collators or validators) then pick up these transactions from their pools for inclusion in blocks. This makes RPC nodes the primary gateway for users and applications to interact with the blockchain. ### Collators @@ -31,17 +36,17 @@ Collators are block producers for parachains. They perform critical functions: - **Collect transactions**: Aggregate user transactions into blocks - **Produce blocks**: Create parachain block candidates -- **Generate proofs**: Produce state transition proofs (Proof-of-Validity) -- **Submit to validators**: Send block candidates to relay chain validators +- **Generate and package PoV**: Generate the Proof-of-Validity containing the state transition proof and necessary witness data for validation +- **Submit to validators**: Send block candidates and PoVs to relay chain validators Unlike validators, collators do not provide security guarantees—that responsibility lies with relay chain validators. However, collators are essential for parachain liveness and censorship resistance. ### Validators -Validators secure the Polkadot relay chain through Nominated Proof of Stake (NPoS). They: +Validators secure the Polkadot relay chain through [Nominated Proof of Stake (NPoS)](https://wiki.polkadot.network/docs/learn-staking){target=\_blank}. They: - **Validate blocks**: Verify parachain blocks and relay chain transactions -- **Participate in consensus**: Run BABE and GRANDPA protocols +- **Participate in consensus**: Run [BABE](https://wiki.polkadot.network/docs/learn-consensus#babe-block-production){target=\_blank} and [GRANDPA](https://wiki.polkadot.network/docs/learn-consensus#grandpa-finality-gadget){target=\_blank} protocols - **Earn rewards**: Receive staking rewards for honest behavior - **Risk slashing**: Face penalties for misbehavior or downtime diff --git a/node-infrastructure/run-a-collator/collator.md b/node-infrastructure/run-a-collator/collator.md index 2560584d1..778d6aea2 100644 --- a/node-infrastructure/run-a-collator/collator.md +++ b/node-infrastructure/run-a-collator/collator.md @@ -30,7 +30,7 @@ Block-producing collators perform critical functions: - Send block candidates to relay chain validators. - Enable cross-chain message passing using XCM -Unlike relay chain validators, collators do not provide security guarantees—that responsibility lies with relay chain validators through the ELVES protocol. Rather, collators are essential for network liveness and censorship resistance. +Unlike relay chain validators, collators do not provide security guarantees—that responsibility lies with relay chain validators through the [ELVES protocol](https://wiki.polkadot.com/learn/learn-parachains-protocol/){target=\_blank}. Rather, collators are essential for network liveness and censorship resistance. ## Prerequisites @@ -56,7 +56,7 @@ Uptime is critical. Consider redundancy and monitoring to maintain block product ### Software Requirements -Collators use the **Polkadot Parachain** binary, the standard client for running Polkadot system parachains. +Collators use the Polkadot Parachain binary, the standard client for running Polkadot system parachains. Required software includes the following: @@ -142,6 +142,17 @@ Generate an account for on-chain transactions as follows: docker run -it parity/subkey:latest generate --scheme sr25519 ``` + The output will be similar to the following: + ```bash + Secret phrase: embody rail hour peanut .... badge syrup luggage canvas + Network ID: substrate + Secret seed: 0x6498dd3416c491406e2c8283c76760ce4ca018478888b42315e7718778f2c2e1 + Public key (hex): 0x2202210357e49390d4f8d868da983940fe220a0a0e00bc6feaeda462aa031810 + Account ID: 0x2202210357e49390d4f8d868da983940fe220a0a0e00bc6feaeda462aa031810 + Public key (SS58): 5CqJ7n72GvvF5ZzUT2HMj83KyDje4n8sXR8kuiK8HWtfDktF + SS58 Address: 5CqJ7n72GvvF5ZzUT2HMj83KyDje4n8sXR8kuiK8HWtfDktF + ``` + 2. Save the following items displayed in the output: - Secret phrase (seed) - Keep this secure! - Public key (hex) @@ -160,7 +171,7 @@ Download the chain specification for your target system parachain using one of t Follow these steps to download your specification from the Chainspec Collection: -1. Visit the [Chainspec Collection](https://paritytech.github.io/chainspecs/) website. +1. Visit the [Chainspec Collection](https://paritytech.github.io/chainspecs/){target=\_blank} website. 2. Find your target system parachain. 3. Download the chain specification JSON file. 4. Save it as `chain-spec.json`. @@ -314,6 +325,8 @@ The relay chain uses warp sync for faster synchronization. ## Generate Session Keys +Session keys are cryptographic keys used by your collator node to sign authorship information when producing blocks. They uniquely identify your collator on the network and must be registered on-chain before your collator can participate in block production. + Once your node is fully synced, use the following command to generate session keys via RPC: ```bash @@ -337,7 +350,7 @@ System parachains use different collator selection mechanisms. Explore the follo === "On-chain Selection" - - Some parachains use pallet-collator-selection. + - Some parachains use [pallet-collator-selection](https://paritytech.github.io/polkadot-sdk/master/pallet_collator_selection/index.html){target=\_blank}. - May require bonding tokens. - Automatic selection based on criteria. @@ -348,6 +361,8 @@ System parachains use different collator selection mechanisms. Explore the follo ### Registration Process +Collator registration authorizes your node to produce blocks on the network. The parachain's collator selection mechanism uses this on-chain registration to determine which nodes are eligible to author blocks. + The registration process varies by system parachain. General steps include the following: 1. Check the existing collators for your target parachain: @@ -374,59 +389,19 @@ The registration process varies by system parachain. General steps include the f - `proof`: 0x00 (typically) 6. Submit and sign the transaction. -4. If the parachain requires bonding tokens, use the follow these steps to submit them using Polkadot.js Apps: +4. (Optional - primarily for non-system parachains) If the parachain uses on-chain bonding for collator selection, register as a candidate using Polkadot.js Apps: + + !!! note + Most system parachains use invulnerables lists exclusively and do not require this step. Skip to step 5 if you're running a collator for a system parachain. + 1. Locate **Developer > Extrinsics**. 2. Select `collatorSelection.registerAsCandidate`. - 3. Submit the transaction with the required bond amount. - 4. Sign the transaction. + 3. Submit and sign the transaction. The required bond amount will be automatically reserved from your account based on the pallet's configured `CandidacyBond`. -5. If applying to join the invulnerables list, you must now await governance approval for your proposal. Monitor the [Polkadot Forum](https://forum.polkadot.network){target=\_blank} governance channels and announcements. Once approved, your collator is added to the invulnerables list and will begin producing blocks in the next session or era. +5. For system parachains using invulnerables lists, await governance approval for your proposal. Monitor the [Polkadot Forum](https://forum.polkadot.network){target=\_blank} governance channels and announcements. Once approved, your collator is added to the invulnerables list and will begin producing blocks in the next session or era. 6. Verify your collator is active by monitoring logs for block production messages like "Prepared block for proposing" and "Imported #123". See the [Log Management](#log-management) section for log viewing commands. -## Monitor and Maintain Your Collator - -Monitoring the following items will help ensure your collator runs efficiently to avoid service interruptions or down time: - -- **Block Production**: Monitor for block production using the appropriate command for your setup: - - === "Docker Setup" - - ```bash - docker logs polkadot-collator 2>&1 | grep -i "prepared block" - ``` - - === "systemd Setup" - - ```bash - sudo journalctl -u polkadot-collator | grep -i "prepared block" - ``` - -- **Peer Connections**: Maintain a sufficient amount of peers for good connectivity and set up alerts to notify if peer connections falls below ten. -- **Resource Usage**: Monitor CPU, RAM, and disk I/O and set up alerts for unusual or high usage. -- **Sync Status**: Ensure both chains stay synced and set up alerts for sync issues. - -### Prometheus Metrics - -You can use the following information to configure [Prometheus](https://prometheus.io/docs/introduction/first_steps/){target=\_blank} to monitor, collect, and store your collator node metrics: - -- **URL**: Metrics are available to view at `http://localhost:9615/metrics` -- **Example Prometheus configuration**: Update your `prometheus.yml` to add the following code: - ```yaml - scrape_configs: - - job_name: 'polkadot-collator' - static_configs: - - targets: ['localhost:9615'] - ``` - -Key metrics to monitor via Prometheus include the following: - -- `substrate_block_height`: Current block height -- `substrate_finalized_height`: Finalized block height -- `substrate_peers_count`: Peer connections -- `substrate_ready_transactions_number`: Transaction queue - - ## Log Management Efficient log management is essential to ensure collator performance and uptime. Use the following commands to help you manage logs to monitor and maintain your collator: diff --git a/node-infrastructure/run-a-node/parachain-rpc.md b/node-infrastructure/run-a-node/parachain-rpc.md index e857f6ec6..3dbbcf988 100644 --- a/node-infrastructure/run-a-node/parachain-rpc.md +++ b/node-infrastructure/run-a-node/parachain-rpc.md @@ -60,7 +60,7 @@ RPC nodes serving production traffic require robust hardware: - **CPU**: 8+ cores (16+ cores for high traffic) - **Memory**: 64 GB RAM minimum (128 GB recommended for high traffic) - **Storage**: - - 500 GB+ NVMe SSD for parachain state (archive nodes require 2-4 TB+) + - Storage requirements vary by parachain. System parachains: Asset Hub (~600-800 GB), Bridge Hub (~500-600 GB), Collectives (~400-500 GB), People Chain (~300-400 GB), Coretime (~300-400 GB). For non-system parachains, check the [snapshot sizes](https://snapshots.polkadot.io/){target=\_blank} if available. - Additional 200+ GB for relay chain pruned database - Fast disk I/O is critical for query performance - **Network**: @@ -115,11 +115,13 @@ Select the best option for your project, then use the steps in the following tab mkdir -p my-node-data/chains/people-polkadot/db mkdir -p my-node-data/chains/polkadot/db ``` - 2. Download the appropriate snapshot using the following commands: + 2. Download the appropriate snapshots using the following commands: - === "Archive snapshot" + === "Archive Node" - Contains complete history, recommended for RPC with historical data. + Archive node setup maintains complete parachain history. Download both parachain archive and relay chain pruned snapshots: + + **Parachain archive snapshot** (People Chain example): ```bash # Check https://snapshots.polkadot.io/ for the latest snapshot URL export SNAPSHOT_URL_PARACHAIN="https://snapshots.polkadot.io/polkadot-people-rocksdb-archive/LATEST" @@ -135,14 +137,50 @@ Select the best option for your project, then use the steps in the following tab rm files.txt ``` - - `--transfers 20`: Uses 20 parallel transfers for faster download. - - `--retries 6`: Automatically retries failed transfers up to 6 times. - - `--retries-sleep 10s`: Waits 10 seconds between retry attempts. - - `--size-only`: Only transfers if sizes differ (prevents unnecessary re-downloads). + **Relay chain pruned snapshot** (~200 GB): + ```bash + # Check https://snapshots.polkadot.io/ for the latest snapshot URL + export SNAPSHOT_URL_RELAY="https://snapshots.polkadot.io/polkadot-rocksdb-prune/LATEST" + + rclone copyurl $SNAPSHOT_URL_RELAY/files.txt files.txt + rclone copy --progress --transfers 20 \ + --http-url $SNAPSHOT_URL_RELAY \ + --no-traverse --http-no-head --disable-http2 \ + --inplace --no-gzip-encoding --size-only \ + --retries 6 --retries-sleep 10s \ + --files-from files.txt :http: my-node-data/chains/polkadot/db/ + + rm files.txt + ``` + + **rclone parameters:** + + - `--transfers 20`: Uses 20 parallel transfers for faster download + - `--retries 6`: Automatically retries failed transfers up to 6 times + - `--retries-sleep 10s`: Waits 10 seconds between retry attempts + - `--size-only`: Only transfers if sizes differ (prevents unnecessary re-downloads) + + === "Pruned Node" + + Pruned node setup keeps recent state for smaller storage. Download both parachain pruned and relay chain pruned snapshots: + + **Parachain pruned snapshot** (People Chain example): + ```bash + # Check https://snapshots.polkadot.io/ for the latest snapshot URL + export SNAPSHOT_URL_PARACHAIN="https://snapshots.polkadot.io/polkadot-people-rocksdb-prune/LATEST" + + rclone copyurl $SNAPSHOT_URL_PARACHAIN/files.txt files.txt + rclone copy --progress --transfers 20 \ + --http-url $SNAPSHOT_URL_PARACHAIN \ + --no-traverse --http-no-head --disable-http2 \ + --inplace --no-gzip-encoding --size-only \ + --retries 6 --retries-sleep 10s \ + --files-from files.txt :http: my-node-data/chains/people-polkadot/db/ - === "Pruned snapshot" + rm files.txt + ``` - Contains recent state for a smaller package size, recommended for RPC nodes. + **Relay chain pruned snapshot** (~200 GB): ```bash # Check https://snapshots.polkadot.io/ for the latest snapshot URL export SNAPSHOT_URL_RELAY="https://snapshots.polkadot.io/polkadot-rocksdb-prune/LATEST" @@ -158,35 +196,80 @@ Select the best option for your project, then use the steps in the following tab rm files.txt ``` - 3. Launch the parachain node using the official [Parity Docker image](https://hub.docker.com/r/parity/polkadot-parachain){target=\_blank} with the following command: - ```bash - docker run -d --name people-chain-rpc --restart unless-stopped \ - -p 9944:9944 \ - -p 9933:9933 \ - -p 9615:9615 \ - -p 30334:30334 \ - -p 30333:30333 \ - -v $(pwd)/people-polkadot.json:/people-polkadot.json \ - -v $(pwd)/my-node-data:/data \ - parity/polkadot-parachain:stable2509-2 \ - --name=PeopleChainRPC \ - --base-path=/data \ - --chain=/people-polkadot.json \ - --prometheus-external \ - --prometheus-port 9615 \ - --unsafe-rpc-external \ - --rpc-port=9944 \ - --rpc-cors=all \ - --rpc-methods=safe \ - --rpc-max-connections=1000 \ - --state-pruning=archive \ - --blocks-pruning=archive \ - -- \ - --base-path=/data \ - --chain=polkadot \ - --state-pruning=256 \ - --blocks-pruning=archive-canonical - ``` + **rclone parameters:** + + - `--transfers 20`: Uses 20 parallel transfers for faster download + - `--retries 6`: Automatically retries failed transfers up to 6 times + - `--retries-sleep 10s`: Waits 10 seconds between retry attempts + - `--size-only`: Only transfers if sizes differ (prevents unnecessary re-downloads) + + 3. Launch the parachain node using the official [Parity Docker image](https://hub.docker.com/r/parity/polkadot-parachain){target=\_blank}: + + === "Archive Node" + + Archive node configuration maintains complete parachain history for historical queries: + + ```bash + docker run -d --name people-chain-rpc --restart unless-stopped \ + -p 9944:9944 \ + -p 9933:9933 \ + -p 9615:9615 \ + -p 30334:30334 \ + -p 30333:30333 \ + -v $(pwd)/people-polkadot.json:/people-polkadot.json \ + -v $(pwd)/my-node-data:/data \ + parity/polkadot-parachain:stable2509-2 \ + --name=PeopleChainRPC \ + --base-path=/data \ + --chain=/people-polkadot.json \ + --prometheus-external \ + --prometheus-port 9615 \ + --unsafe-rpc-external \ + --rpc-port=9944 \ + --rpc-cors=all \ + --rpc-methods=safe \ + --rpc-max-connections=1000 \ + --state-pruning=archive \ + --blocks-pruning=archive \ + -- \ + --base-path=/data \ + --chain=polkadot \ + --state-pruning=256 \ + --blocks-pruning=archive-canonical + ``` + + === "Pruned Node" + + Pruned node configuration keeps recent state for smaller storage requirements: + + ```bash + docker run -d --name people-chain-rpc --restart unless-stopped \ + -p 9944:9944 \ + -p 9933:9933 \ + -p 9615:9615 \ + -p 30334:30334 \ + -p 30333:30333 \ + -v $(pwd)/people-polkadot.json:/people-polkadot.json \ + -v $(pwd)/my-node-data:/data \ + parity/polkadot-parachain:stable2509-2 \ + --name=PeopleChainRPC \ + --base-path=/data \ + --chain=/people-polkadot.json \ + --prometheus-external \ + --prometheus-port 9615 \ + --unsafe-rpc-external \ + --rpc-port=9944 \ + --rpc-cors=all \ + --rpc-methods=safe \ + --rpc-max-connections=1000 \ + --state-pruning=1000 \ + --blocks-pruning=256 \ + -- \ + --base-path=/data \ + --chain=polkadot \ + --state-pruning=256 \ + --blocks-pruning=archive-canonical + ``` !!! note @@ -206,8 +289,8 @@ Select the best option for your project, then use the steps in the following tab - `--unsafe-rpc-external`: Enables external RPC access - `--rpc-cors=all`: Allows all origins for CORS - `--rpc-methods=safe`: Only allows safe RPC methods - - `--state-pruning=archive`: Keeps complete state history - - `--blocks-pruning=archive`: Keeps all block data + - `--state-pruning=archive` or `--state-pruning=1000`: Archive keeps complete state history, pruned keeps last 1000 blocks + - `--blocks-pruning=archive` or `--blocks-pruning=256`: Archive keeps all blocks, pruned keeps last 256 finalized blocks - `--prometheus-external`: Exposes metrics externally !!! warning @@ -321,46 +404,95 @@ Select the best option for your project, then use the steps in the following tab sudo nano /etc/systemd/system/people-chain-rpc.service ``` - 5. Open the new service file and add the following configuration: - ```ini - [Unit] - Description=People Chain RPC Node - After=network.target - - [Service] - Type=simple - User=polkadot - Group=polkadot - WorkingDirectory=/var/lib/people-chain-rpc - - ExecStart=/usr/local/bin/polkadot-parachain \ - --name=PeopleChainRPC \ - --chain=/var/lib/people-chain-rpc/people-polkadot.json \ - --base-path=/var/lib/people-chain-rpc \ - --port=30333 \ - --rpc-port=9944 \ - --rpc-external \ - --rpc-cors=all \ - --rpc-methods=safe \ - --rpc-max-connections=1000 \ - --prometheus-port=9615 \ - --prometheus-external \ - --state-pruning=archive \ - --blocks-pruning=archive \ - -- \ - --chain=polkadot \ - --base-path=/var/lib/people-chain-rpc \ - --port=30334 \ - --state-pruning=256 \ - --blocks-pruning=archive-canonical - - Restart=always - RestartSec=10 - LimitNOFILE=65536 - - [Install] - WantedBy=multi-user.target - ``` + 5. Open the new service file and add the configuration for your chosen node type: + + === "Archive Node" + + Archive node configuration maintains complete parachain history for historical queries: + + ```ini + [Unit] + Description=People Chain RPC Node + After=network.target + + [Service] + Type=simple + User=polkadot + Group=polkadot + WorkingDirectory=/var/lib/people-chain-rpc + + ExecStart=/usr/local/bin/polkadot-parachain \ + --name=PeopleChainRPC \ + --chain=/var/lib/people-chain-rpc/people-polkadot.json \ + --base-path=/var/lib/people-chain-rpc \ + --port=30333 \ + --rpc-port=9944 \ + --rpc-external \ + --rpc-cors=all \ + --rpc-methods=safe \ + --rpc-max-connections=1000 \ + --prometheus-port=9615 \ + --prometheus-external \ + --state-pruning=archive \ + --blocks-pruning=archive \ + -- \ + --chain=polkadot \ + --base-path=/var/lib/people-chain-rpc \ + --port=30334 \ + --state-pruning=256 \ + --blocks-pruning=archive-canonical + + Restart=always + RestartSec=10 + LimitNOFILE=65536 + + [Install] + WantedBy=multi-user.target + ``` + + === "Pruned Node" + + Pruned node configuration keeps recent state for smaller storage requirements: + + ```ini + [Unit] + Description=People Chain RPC Node + After=network.target + + [Service] + Type=simple + User=polkadot + Group=polkadot + WorkingDirectory=/var/lib/people-chain-rpc + + ExecStart=/usr/local/bin/polkadot-parachain \ + --name=PeopleChainRPC \ + --chain=/var/lib/people-chain-rpc/people-polkadot.json \ + --base-path=/var/lib/people-chain-rpc \ + --port=30333 \ + --rpc-port=9944 \ + --rpc-external \ + --rpc-cors=all \ + --rpc-methods=safe \ + --rpc-max-connections=1000 \ + --prometheus-port=9615 \ + --prometheus-external \ + --state-pruning=1000 \ + --blocks-pruning=256 \ + -- \ + --chain=polkadot \ + --base-path=/var/lib/people-chain-rpc \ + --port=30334 \ + --state-pruning=256 \ + --blocks-pruning=archive-canonical + + Restart=always + RestartSec=10 + LimitNOFILE=65536 + + [Install] + WantedBy=multi-user.target + ``` 6. Start the service using the following commands: - Reload systemd: @@ -401,115 +533,6 @@ Select the best option for your project, then use the steps in the following tab http://localhost:9944 ``` -## Monitor and Maintain RPC Node - -There are a few key monitoring and maintenance commands that can help you ensure RPC node uptime and performance including log monitoring and metrics. - -To view node logs, use the appropriate command for your setup: - -=== "Docker Setup" - - ```bash - docker logs -f people-chain-rpc - ``` - -=== "systemd Setup" - - - View node logs: - ```bash - sudo journalctl -u people-chain-rpc -f - ``` - - View recent logs: - ```bash - sudo journalctl -u people-chain-rpc -n 100 - ``` - - Filter for errors: - ```bash - sudo journalctl -u people-chain-rpc | grep -i error - ``` - -Monitoring key metrics like the following items can help you stay up to date on the performance and health of your node and allow you to intervene at the first sign of issues: - -- **Sync status**: Ensure node stays fully synced. -- **Peer connections**: Maintain 30+ peers for good connectivity. -- **Resource usage**: Monitor CPU, RAM, and disk I/O. -- **RPC request latency**: Track response times for the Polkadot SDK API. -- **Connection count**: Monitor active RPC connections. - -You can use the following information to configure [Prometheus](https://prometheus.io/docs/introduction/first_steps/){target=\_blank} to monitor, collect, and store your RPC node metrics: - -- **URL**: Metrics are available to view at `http://localhost:9615/metrics` -- **Example Prometheus configuration**: Update your `prometheus.yml` to add the following code: - ```yaml - scrape_configs: - - job_name: 'people-chain-rpc' - static_configs: - - targets: ['localhost:9615'] - ``` - -Key metrics to monitor via Prometheus include: - -- `substrate_block_height`: Current block height -- `substrate_finalized_height`: Finalized block height -- `substrate_peers_count`: Number of connected peers -- `substrate_ready_transactions_number`: Transaction queue size - -### Database Maintenance - -Check database size periodically using the commands for your selected setup: - -=== "Docker Setup" - - ```bash - du -sh my-node-data - ``` - -=== "systemd Setup" - - ```bash - du -sh /var/lib/people-chain-rpc - ``` - -The node handles pruning automatically based on configuration unless running in archive mode. - -### Updates and Upgrades - -Use the following commands for updating or upgrading your RPC node according to your setup: - -=== "Docker Setup" - - 1. Stop and remove the existing container: - ```bash - docker stop people-chain-rpc - docker rm people-chain-rpc - ``` - 2. Pull the latest image: - ```bash - docker pull parity/polkadot-parachain: - ``` - 3. Start the new container using the same command from the setup section with the updated image tag. - -=== "systemd Setup" - - 1. Stop the service: - ```bash - sudo systemctl stop people-chain-rpc - ``` - 2. Backup data: - ```bash - sudo cp -r /var/lib/people-chain-rpc /var/lib/people-chain-rpc.backup - ``` - 3. Download the new binary from [GitHub releases](https://github.com/paritytech/polkadot-sdk/releases){target=\_blank}: - ```bash - wget https://github.com/paritytech/polkadot-sdk/releases/download//polkadot-parachain - chmod +x polkadot-parachain - sudo mv polkadot-parachain /usr/local/bin/ - ``` - 4. Restart the service: - ```bash - sudo systemctl start people-chain-rpc - ``` - ## Conclusion Running a parachain RPC node provides critical infrastructure for accessing Polkadot network services. By following this guide, you have set up a production-ready RPC node that: diff --git a/node-infrastructure/run-a-node/polkadot-hub-rpc.md b/node-infrastructure/run-a-node/polkadot-hub-rpc.md index 9b956861c..cb2048b23 100644 --- a/node-infrastructure/run-a-node/polkadot-hub-rpc.md +++ b/node-infrastructure/run-a-node/polkadot-hub-rpc.md @@ -15,6 +15,7 @@ categories: Infrastructure - **Cross-chain Communication**: XCM message handling Running an RPC node for Polkadot Hub enables applications, wallets, and users to interact with the parachain through: + - **Polkadot SDK Node RPC** (Port 9944): Native Polkadot API (WebSocket and HTTP) This setup enables block explorer indexing and provides full compatibility with Polkadot SDK development tools. @@ -32,7 +33,7 @@ RPC nodes serving production traffic require robust hardware. The following shou - **CPU**: 8+ cores (16+ cores for high traffic) - **Memory**: 64 GB RAM minimum (128 GB recommended for high traffic) - **Storage**: - - 500 GB+ NVMe SSD for parachain state (archive nodes require 2-4 TB+) + - 500 GB+ NVMe SSD for parachain state (archive nodes require 600-800 GB+) - Additional 200+ GB for relay chain pruned database - Fast disk I/O is critical for query performance - **Network**: @@ -87,34 +88,72 @@ Select the best option for your project, then use the steps in the following tab mkdir -p my-node-data/chains/asset-hub-polkadot/db mkdir -p my-node-data/chains/polkadot/db ``` - 2. Download the appropriate snapshot using the following commands: + 2. Download the appropriate snapshots using the following commands: + + === "Archive Node" - === "Archive snapshot" + Archive node setup maintains complete parachain history (~600-800 GB total). Download both Asset Hub archive and Relay chain pruned snapshots: - Contains complete history, recommended for RPC with historical data. + **Asset Hub archive snapshot** (~400 GB): ```bash # Check https://snapshots.polkadot.io/ for the latest snapshot URL export SNAPSHOT_URL_ASSET_HUB="https://snapshots.polkadot.io/polkadot-asset-hub-rocksdb-archive/LATEST" rclone copyurl $SNAPSHOT_URL_ASSET_HUB/files.txt files.txt rclone copy --progress --transfers 20 \ - --http-url $SNAPSHOT_URL_ASSET_HUB \ - --no-traverse --http-no-head --disable-http2 \ - --inplace --no-gzip-encoding --size-only \ - --retries 6 --retries-sleep 10s \ - --files-from files.txt :http: my-node-data/chains/asset-hub-polkadot/db/ + --http-url $SNAPSHOT_URL_ASSET_HUB \ + --no-traverse --http-no-head --disable-http2 \ + --inplace --no-gzip-encoding --size-only \ + --retries 6 --retries-sleep 10s \ + --files-from files.txt :http: my-node-data/chains/asset-hub-polkadot/db/ + + rm files.txt + ``` + + **Relay chain pruned snapshot** (~200 GB): + ```bash + # Check https://snapshots.polkadot.io/ for the latest snapshot URL + export SNAPSHOT_URL_RELAY="https://snapshots.polkadot.io/polkadot-rocksdb-prune/LATEST" + + rclone copyurl $SNAPSHOT_URL_RELAY/files.txt files.txt + rclone copy --progress --transfers 20 \ + --http-url $SNAPSHOT_URL_RELAY \ + --no-traverse --http-no-head --disable-http2 \ + --inplace --no-gzip-encoding --size-only \ + --retries 6 --retries-sleep 10s \ + --files-from files.txt :http: my-node-data/chains/polkadot/db/ rm files.txt ``` - - `--transfers 20`: Uses 20 parallel transfers for faster download. - - `--retries 6`: Automatically retries failed transfers up to 6 times. - - `--retries-sleep 10s`: Waits 10 seconds between retry attempts. - - `--size-only`: Only transfers if sizes differ (prevents unnecessary re-downloads). + **rclone parameters:** + + - `--transfers 20`: Uses 20 parallel transfers for faster download + - `--retries 6`: Automatically retries failed transfers up to 6 times + - `--retries-sleep 10s`: Waits 10 seconds between retry attempts + - `--size-only`: Only transfers if sizes differ (prevents unnecessary re-downloads) + + === "Pruned Node" + + Pruned node setup keeps recent state for smaller storage (~500 GB total). Download both Asset Hub pruned and Relay chain pruned snapshots: + + **Asset Hub pruned snapshot**: + ```bash + # Check https://snapshots.polkadot.io/ for the latest snapshot URL + export SNAPSHOT_URL_ASSET_HUB="https://snapshots.polkadot.io/polkadot-asset-hub-rocksdb-prune/LATEST" + + rclone copyurl $SNAPSHOT_URL_ASSET_HUB/files.txt files.txt + rclone copy --progress --transfers 20 \ + --http-url $SNAPSHOT_URL_ASSET_HUB \ + --no-traverse --http-no-head --disable-http2 \ + --inplace --no-gzip-encoding --size-only \ + --retries 6 --retries-sleep 10s \ + --files-from files.txt :http: my-node-data/chains/asset-hub-polkadot/db/ - === "Pruned snapshot" + rm files.txt + ``` - Contains recent state for a smaller package size, recommended for RPC nodes. + **Relay chain pruned snapshot** (~200 GB): ```bash # Check https://snapshots.polkadot.io/ for the latest snapshot URL export SNAPSHOT_URL_RELAY="https://snapshots.polkadot.io/polkadot-rocksdb-prune/LATEST" @@ -127,37 +166,82 @@ Select the best option for your project, then use the steps in the following tab --retries 6 --retries-sleep 10s \ --files-from files.txt :http: my-node-data/chains/polkadot/db/ - rm files.txt + rm files.txt ``` - 3. Launch Polkadot Hub Node using the official [Parity Docker image](https://hub.docker.com/r/parity/polkadot-parachain){target=\_blank} with the following command: - ```bash - docker run -d --name polkadot-hub-rpc --restart unless-stopped \ - -p 9944:9944 \ - -p 9933:9933 \ - -p 9615:9615 \ - -p 30334:30334 \ - -p 30333:30333 \ - -v $(pwd)/asset-hub-polkadot.json:/asset-hub-polkadot.json \ - -v $(pwd)/my-node-data:/data \ - parity/polkadot-parachain:stable2509-2 \ - --name=PolkadotHubRPC \ - --base-path=/data \ - --chain=/asset-hub-polkadot.json \ - --prometheus-external \ - --prometheus-port 9615 \ - --unsafe-rpc-external \ - --rpc-port=9944 \ - --rpc-cors=all \ - --rpc-methods=safe \ - --rpc-max-connections=1000 \ - --state-pruning=archive \ - --blocks-pruning=archive \ - -- \ - --base-path=/data \ - --chain=polkadot \ - --state-pruning=256 \ - --blocks-pruning=archive-canonical - ``` + + **rclone parameters:** + + - `--transfers 20`: Uses 20 parallel transfers for faster download + - `--retries 6`: Automatically retries failed transfers up to 6 times + - `--retries-sleep 10s`: Waits 10 seconds between retry attempts + - `--size-only`: Only transfers if sizes differ (prevents unnecessary re-downloads) + 3. Launch Polkadot Hub Node using the official [Parity Docker image](https://hub.docker.com/r/parity/polkadot-parachain){target=\_blank}: + + === "Archive Node" + + Archive node configuration maintains complete parachain history for historical queries: + + ```bash + docker run -d --name polkadot-hub-rpc --restart unless-stopped \ + -p 9944:9944 \ + -p 9933:9933 \ + -p 9615:9615 \ + -p 30334:30334 \ + -p 30333:30333 \ + -v $(pwd)/asset-hub-polkadot.json:/asset-hub-polkadot.json \ + -v $(pwd)/my-node-data:/data \ + parity/polkadot-parachain:stable2509-2 \ + --name=PolkadotHubRPC \ + --base-path=/data \ + --chain=/asset-hub-polkadot.json \ + --prometheus-external \ + --prometheus-port 9615 \ + --unsafe-rpc-external \ + --rpc-port=9944 \ + --rpc-cors=all \ + --rpc-methods=safe \ + --rpc-max-connections=1000 \ + --state-pruning=archive \ + --blocks-pruning=archive \ + -- \ + --base-path=/data \ + --chain=polkadot \ + --state-pruning=256 \ + --blocks-pruning=archive-canonical + ``` + + === "Pruned Node" + + Pruned node configuration keeps recent state for smaller storage requirements: + + ```bash + docker run -d --name polkadot-hub-rpc --restart unless-stopped \ + -p 9944:9944 \ + -p 9933:9933 \ + -p 9615:9615 \ + -p 30334:30334 \ + -p 30333:30333 \ + -v $(pwd)/asset-hub-polkadot.json:/asset-hub-polkadot.json \ + -v $(pwd)/my-node-data:/data \ + parity/polkadot-parachain:stable2509-2 \ + --name=PolkadotHubRPC \ + --base-path=/data \ + --chain=/asset-hub-polkadot.json \ + --prometheus-external \ + --prometheus-port 9615 \ + --unsafe-rpc-external \ + --rpc-port=9944 \ + --rpc-cors=all \ + --rpc-methods=safe \ + --rpc-max-connections=1000 \ + --state-pruning=1000 \ + --blocks-pruning=256 \ + -- \ + --base-path=/data \ + --chain=polkadot \ + --state-pruning=256 \ + --blocks-pruning=archive-canonical + ``` Critical configuration parameters include port mappings and node parameters: @@ -173,8 +257,8 @@ Select the best option for your project, then use the steps in the following tab - `--unsafe-rpc-external`: Enables external RPC access - `--rpc-cors=all`: Allows all origins for CORS - `--rpc-methods=safe`: Only allows safe RPC methods - - `--state-pruning=archive`: Keeps complete state history - - `--blocks-pruning=archive`: Keeps all block data + - `--state-pruning=archive` or `--state-pruning=1000`: Archive keeps complete state history, pruned keeps last 1000 blocks + - `--blocks-pruning=archive` or `--blocks-pruning=256`: Archive keeps all blocks, pruned keeps last 256 finalized blocks - `--prometheus-external`: Exposes metrics externally !!! warning @@ -182,6 +266,7 @@ Select the best option for your project, then use the steps in the following tab The `--unsafe-rpc-external` flag should only be used in development or properly secured environments. For production, use a reverse proxy with authentication. 4. Monitor the node synchronization status using the following command: + ```bash curl -H "Content-Type: application/json" \ -d '{"id":1, "jsonrpc":"2.0", "method": "system_syncState", "params":[]}' \ @@ -189,7 +274,7 @@ Select the best option for your project, then use the steps in the following tab ``` You should see a response similar to the following: - + ```json { "jsonrpc":"2.0", @@ -204,20 +289,8 @@ Select the best option for your project, then use the steps in the following tab When synchronization is complete, `currentBlock` will be equal to `highestBlock`. - 5. You can use a few different commands to verify your node is running properly: + 5. You can use the `system_health` command to verify your node is running properly: - - Get chain information: - ```bash - curl -H "Content-Type: application/json" \ - -d '{"id":1, "jsonrpc":"2.0", "method": "system_chain", "params":[]}' \ - http://localhost:9944 - ``` - - Get the latest block: - ```bash - curl -H "Content-Type: application/json" \ - -d '{"id":1, "jsonrpc":"2.0", "method": "chain_getHeader", "params":[]}' \ - http://localhost:9944 - ``` - Query node health: ```bash curl -H "Content-Type: application/json" \ @@ -289,46 +362,95 @@ Select the best option for your project, then use the steps in the following tab sudo nano /etc/systemd/system/polkadot-hub-rpc.service ``` - 5. Open the new service file and add the following configuration: - ```ini - [Unit] - Description=Polkadot Hub RPC Node - After=network.target - - [Service] - Type=simple - User=polkadot - Group=polkadot - WorkingDirectory=/var/lib/polkadot-hub-rpc - - ExecStart=/usr/local/bin/polkadot-parachain \ - --name=PolkadotHubRPC \ - --chain=/var/lib/polkadot-hub-rpc/asset-hub-polkadot.json \ - --base-path=/var/lib/polkadot-hub-rpc \ - --port=30333 \ - --rpc-port=9944 \ - --rpc-external \ - --rpc-cors=all \ - --rpc-methods=safe \ - --rpc-max-connections=1000 \ - --prometheus-port=9615 \ - --prometheus-external \ - --state-pruning=archive \ - --blocks-pruning=archive \ - -- \ - --chain=polkadot \ - --base-path=/var/lib/polkadot-hub-rpc \ - --port=30334 \ - --state-pruning=256 \ - --blocks-pruning=archive-canonical - - Restart=always - RestartSec=10 - LimitNOFILE=65536 - - [Install] - WantedBy=multi-user.target - ``` + 5. Open the new service file and add the configuration for your chosen node type: + + === "Archive Node" + + Archive node configuration maintains complete parachain history for historical queries: + + ```ini + [Unit] + Description=Polkadot Hub RPC Node + After=network.target + + [Service] + Type=simple + User=polkadot + Group=polkadot + WorkingDirectory=/var/lib/polkadot-hub-rpc + + ExecStart=/usr/local/bin/polkadot-parachain \ + --name=PolkadotHubRPC \ + --chain=/var/lib/polkadot-hub-rpc/asset-hub-polkadot.json \ + --base-path=/var/lib/polkadot-hub-rpc \ + --port=30333 \ + --rpc-port=9944 \ + --rpc-external \ + --rpc-cors=all \ + --rpc-methods=safe \ + --rpc-max-connections=1000 \ + --prometheus-port=9615 \ + --prometheus-external \ + --state-pruning=archive \ + --blocks-pruning=archive \ + -- \ + --chain=polkadot \ + --base-path=/var/lib/polkadot-hub-rpc \ + --port=30334 \ + --state-pruning=256 \ + --blocks-pruning=archive-canonical + + Restart=always + RestartSec=10 + LimitNOFILE=65536 + + [Install] + WantedBy=multi-user.target + ``` + + === "Pruned Node" + + Pruned node configuration keeps recent state for smaller storage requirements: + + ```ini + [Unit] + Description=Polkadot Hub RPC Node + After=network.target + + [Service] + Type=simple + User=polkadot + Group=polkadot + WorkingDirectory=/var/lib/polkadot-hub-rpc + + ExecStart=/usr/local/bin/polkadot-parachain \ + --name=PolkadotHubRPC \ + --chain=/var/lib/polkadot-hub-rpc/asset-hub-polkadot.json \ + --base-path=/var/lib/polkadot-hub-rpc \ + --port=30333 \ + --rpc-port=9944 \ + --rpc-external \ + --rpc-cors=all \ + --rpc-methods=safe \ + --rpc-max-connections=1000 \ + --prometheus-port=9615 \ + --prometheus-external \ + --state-pruning=1000 \ + --blocks-pruning=256 \ + -- \ + --chain=polkadot \ + --base-path=/var/lib/polkadot-hub-rpc \ + --port=30334 \ + --state-pruning=256 \ + --blocks-pruning=archive-canonical + + Restart=always + RestartSec=10 + LimitNOFILE=65536 + + [Install] + WantedBy=multi-user.target + ``` 6. Start the service using the following commands: - Reload systemd: @@ -369,115 +491,6 @@ Select the best option for your project, then use the steps in the following tab http://localhost:9944 ``` -## Monitor and Maintain RPC Node - -There are a few key monitoring and maintenance commands that can help you ensure RPC node uptime and performance including log monitoring and metrics. - -To view node logs, use the appropriate command for your setup: - -=== "Docker Setup" - - ```bash - docker logs -f polkadot-hub-rpc - ``` - -=== "systemd Setup" - - - View node logs: - ```bash - sudo journalctl -u polkadot-hub-rpc -f - ``` - - View recent logs: - ```bash - sudo journalctl -u polkadot-hub-rpc -n 100 - ``` - - Filter for errors: - ```bash - sudo journalctl -u polkadot-hub-rpc | grep -i error - ``` - -Monitoring key metrics like the following items can help you stay up to date on the performance and health of your node and allow you to intervene at the first sign of issues: - -- **Sync status**: Ensure node stays fully synced. -- **Peer connections**: Maintain 30+ peers for good connectivity. -- **Resource usage**: Monitor CPU, RAM, and disk I/O. -- **RPC request latency**: Track response times for the Polkadot SDK API. -- **Connection count**: Monitor active RPC connections. - -You can use the following information to configure [Prometheus](https://prometheus.io/docs/introduction/first_steps/){target=\_blank} to monitor, collect, and store your RPC node metrics: - -- **URL**: Metrics are available to view at `http://localhost:9615/metrics` -- **Example Prometheus configuration**: Update your `prometheus.yml` to add the following code: - ```yaml - scrape_configs: - - job_name: 'polkadot-hub-rpc' - static_configs: - - targets: ['localhost:9615'] - ``` - -Key metrics to monitor via Prometheus include: - -- `substrate_block_height`: Current block height -- `substrate_finalized_height`: Finalized block height -- `substrate_peers_count`: Number of connected peers -- `substrate_ready_transactions_number`: Transaction queue size - -### Database Maintenance - -Check database size periodically using the commands for your selected setup: - -=== "Docker Setup" - - ```bash - du -sh my-node-data - ``` - -=== "systemd Setup" - - ```bash - du -sh /var/lib/polkadot-hub-rpc - ``` - -The node handles pruning automatically based on configuration unless running in archive mode. - -### Updates and Upgrades - -Use the following commands for updating or upgrading your RPC node according to your setup: - -=== "Docker Setup" - - 1. Stop and remove the existing container: - ```bash - docker stop polkadot-hub-rpc - docker rm polkadot-hub-rpc - ``` - 2. Pull the latest image: - ```bash - docker pull parity/polkadot-parachain: - ``` - 3. Start the new container using the same command from the setup section with the updated image tag. - -=== "systemd Setup" - - 1. Stop the service: - ```bash - sudo systemctl stop polkadot-hub-rpc - ``` - 2. Backup data: - ```bash - sudo cp -r /var/lib/polkadot-hub-rpc /var/lib/polkadot-hub-rpc.backup - ``` - 3. Download the new binary from [GitHub releases](https://github.com/paritytech/polkadot-sdk/releases){target=\_blank}: - ```bash - wget https://github.com/paritytech/polkadot-sdk/releases/download//polkadot-parachain - chmod +x polkadot-parachain - sudo mv polkadot-parachain /usr/local/bin/ - ``` - 4. Restart the service: - ```bash - sudo systemctl start polkadot-hub-rpc - ``` - ## Conclusion Running an RPC node for Polkadot Hub provides essential infrastructure for applications and users to interact with the network. By following this guide, you have set up a production-ready RPC node that: From ad7ac4d73c840da7e69de7c1c2bee16b1cd64cb3 Mon Sep 17 00:00:00 2001 From: Bruno Galvao Date: Thu, 4 Dec 2025 12:46:03 +0700 Subject: [PATCH 22/39] Update node configs: optimize pruning, disable external ports - Remove 9944/9615 from external firewall ports (localhost only) - Add pruning flags for para and relay chains (--blocks-pruning=256, --state-pruning=256) - Use --database=paritydb and --sync=fast for collators - Disable relay chain RPC with --rpc-port=0 - Add --pool-limit=0 for relay chain on collators - Replace archive-canonical with pruned relay chain config - Add chown root:root for binary ownership --- .../run-a-collator/collator.md | 21 ++++++++++++++----- .../run-a-node/parachain-rpc.md | 13 +++++++----- .../run-a-node/polkadot-hub-rpc.md | 13 +++++++----- 3 files changed, 32 insertions(+), 15 deletions(-) diff --git a/node-infrastructure/run-a-collator/collator.md b/node-infrastructure/run-a-collator/collator.md index 778d6aea2..65e53571b 100644 --- a/node-infrastructure/run-a-collator/collator.md +++ b/node-infrastructure/run-a-collator/collator.md @@ -50,7 +50,6 @@ Block-producing collators require robust hardware for reliable operation includi - Open ports: - 30333 (parachain P2P) - 30334 (relay chain P2P) - - 9944 (WebSocket RPC - for management) Uptime is critical. Consider redundancy and monitoring to maintain block production reliability. @@ -105,6 +104,7 @@ This guide provides two deployment options. Select the option that best fits you # Make it executable and move to system path chmod +x polkadot-parachain sudo mv polkadot-parachain /usr/local/bin/ + sudo chown root:root /usr/local/bin/polkadot-parachain # Verify installation polkadot-parachain --version @@ -258,11 +258,18 @@ Follow these steps to build a chainspec from the runtime: --prometheus-port=9615 \ --node-key-file=/var/lib/polkadot-collator/node.key \ --name="YourCollatorName" \ + --blocks-pruning=256 \ + --state-pruning=256 \ + --database=paritydb \ -- \ - --execution=wasm \ --chain=polkadot \ --port=30334 \ - --sync=warp + --sync=fast \ + --blocks-pruning=256 \ + --state-pruning=256 \ + --database=paritydb \ + --pool-limit=0 \ + --rpc-port=0 Restart=always RestartSec=10 @@ -277,7 +284,11 @@ Follow these steps to build a chainspec from the runtime: - `--collator`: Enables block production mode - `--node-key-file`: Uses the generated node key for stable peer ID - `--name`: Your collator name (visible in telemetry) - - Relay chain uses `--sync=warp` for faster initial sync + - `--blocks-pruning=256` and `--state-pruning=256`: Keeps only recent blocks and state, reducing disk usage (collators don't need archive data) + - `--database=paritydb`: Uses ParityDB for better performance + - `--sync=fast`: Fast sync mode for the relay chain + - `--pool-limit=0`: Disables transaction pool on relay chain (collators don't need it) + - `--rpc-port=0` (relay chain): Disables RPC on the embedded relay chain node (not needed for collators) ## Run the Collator @@ -317,7 +328,7 @@ Sync time depends on: - Disk I/O speed - Current chain size -The relay chain uses warp sync for faster synchronization. +The relay chain uses fast sync for faster synchronization. !!! warning diff --git a/node-infrastructure/run-a-node/parachain-rpc.md b/node-infrastructure/run-a-node/parachain-rpc.md index 3dbbcf988..38d6e7168 100644 --- a/node-infrastructure/run-a-node/parachain-rpc.md +++ b/node-infrastructure/run-a-node/parachain-rpc.md @@ -72,7 +72,6 @@ RPC nodes serving production traffic require robust hardware: - 30334 (relay chain P2P) - 9944 (Polkadot SDK WebSocket RPC) - 9933 (Polkadot SDK HTTP RPC) - - 9615 (Prometheus metrics - optional) - Consider DDoS protection and rate limiting for production deployments !!! note @@ -235,7 +234,8 @@ Select the best option for your project, then use the steps in the following tab --base-path=/data \ --chain=polkadot \ --state-pruning=256 \ - --blocks-pruning=archive-canonical + --blocks-pruning=256 \ + --rpc-port=0 ``` === "Pruned Node" @@ -268,7 +268,8 @@ Select the best option for your project, then use the steps in the following tab --base-path=/data \ --chain=polkadot \ --state-pruning=256 \ - --blocks-pruning=archive-canonical + --blocks-pruning=256 \ + --rpc-port=0 ``` !!! note @@ -440,7 +441,8 @@ Select the best option for your project, then use the steps in the following tab --base-path=/var/lib/people-chain-rpc \ --port=30334 \ --state-pruning=256 \ - --blocks-pruning=archive-canonical + --blocks-pruning=256 \ + --rpc-port=0 Restart=always RestartSec=10 @@ -484,7 +486,8 @@ Select the best option for your project, then use the steps in the following tab --base-path=/var/lib/people-chain-rpc \ --port=30334 \ --state-pruning=256 \ - --blocks-pruning=archive-canonical + --blocks-pruning=256 \ + --rpc-port=0 Restart=always RestartSec=10 diff --git a/node-infrastructure/run-a-node/polkadot-hub-rpc.md b/node-infrastructure/run-a-node/polkadot-hub-rpc.md index cb2048b23..0656e7fa5 100644 --- a/node-infrastructure/run-a-node/polkadot-hub-rpc.md +++ b/node-infrastructure/run-a-node/polkadot-hub-rpc.md @@ -45,7 +45,6 @@ RPC nodes serving production traffic require robust hardware. The following shou - 30334 (relay chain P2P) - 9944 (Polkadot SDK WebSocket RPC) - 9933 (Polkadot SDK HTTP RPC) - - 9615 (Prometheus metrics - optional) - Consider DDoS protection and rate limiting for production deployments **Note**: For development or low-traffic scenarios, you can reduce these requirements proportionally. Consider using a reverse proxy (nginx, Caddy) for production deployments. @@ -207,7 +206,8 @@ Select the best option for your project, then use the steps in the following tab --base-path=/data \ --chain=polkadot \ --state-pruning=256 \ - --blocks-pruning=archive-canonical + --blocks-pruning=256 \ + --rpc-port=0 ``` === "Pruned Node" @@ -240,7 +240,8 @@ Select the best option for your project, then use the steps in the following tab --base-path=/data \ --chain=polkadot \ --state-pruning=256 \ - --blocks-pruning=archive-canonical + --blocks-pruning=256 \ + --rpc-port=0 ``` Critical configuration parameters include port mappings and node parameters: @@ -398,7 +399,8 @@ Select the best option for your project, then use the steps in the following tab --base-path=/var/lib/polkadot-hub-rpc \ --port=30334 \ --state-pruning=256 \ - --blocks-pruning=archive-canonical + --blocks-pruning=256 \ + --rpc-port=0 Restart=always RestartSec=10 @@ -442,7 +444,8 @@ Select the best option for your project, then use the steps in the following tab --base-path=/var/lib/polkadot-hub-rpc \ --port=30334 \ --state-pruning=256 \ - --blocks-pruning=archive-canonical + --blocks-pruning=256 \ + --rpc-port=0 Restart=always RestartSec=10 From 5569d63dd74028ae7a23a73493e33a05bb78e08d Mon Sep 17 00:00:00 2001 From: Bruno Galvao Date: Thu, 4 Dec 2025 12:46:37 +0700 Subject: [PATCH 23/39] Update AI index pages for node infrastructure docs --- ...-infrastructure-run-a-collator-collator.md | 21 ++++++++++++++----- ...infrastructure-run-a-node-parachain-rpc.md | 13 +++++++----- ...rastructure-run-a-node-polkadot-hub-rpc.md | 13 +++++++----- 3 files changed, 32 insertions(+), 15 deletions(-) diff --git a/.ai/pages/node-infrastructure-run-a-collator-collator.md b/.ai/pages/node-infrastructure-run-a-collator-collator.md index 8525e7ee4..0a7aa466c 100644 --- a/.ai/pages/node-infrastructure-run-a-collator-collator.md +++ b/.ai/pages/node-infrastructure-run-a-collator-collator.md @@ -51,7 +51,6 @@ Block-producing collators require robust hardware for reliable operation includi - Open ports: - 30333 (parachain P2P) - 30334 (relay chain P2P) - - 9944 (WebSocket RPC - for management) Uptime is critical. Consider redundancy and monitoring to maintain block production reliability. @@ -106,6 +105,7 @@ This guide provides two deployment options. Select the option that best fits you # Make it executable and move to system path chmod +x polkadot-parachain sudo mv polkadot-parachain /usr/local/bin/ + sudo chown root:root /usr/local/bin/polkadot-parachain # Verify installation polkadot-parachain --version @@ -259,11 +259,18 @@ Follow these steps to build a chainspec from the runtime: --prometheus-port=9615 \ --node-key-file=/var/lib/polkadot-collator/node.key \ --name="YourCollatorName" \ + --blocks-pruning=256 \ + --state-pruning=256 \ + --database=paritydb \ -- \ - --execution=wasm \ --chain=polkadot \ --port=30334 \ - --sync=warp + --sync=fast \ + --blocks-pruning=256 \ + --state-pruning=256 \ + --database=paritydb \ + --pool-limit=0 \ + --rpc-port=0 Restart=always RestartSec=10 @@ -278,7 +285,11 @@ Follow these steps to build a chainspec from the runtime: - `--collator`: Enables block production mode - `--node-key-file`: Uses the generated node key for stable peer ID - `--name`: Your collator name (visible in telemetry) - - Relay chain uses `--sync=warp` for faster initial sync + - `--blocks-pruning=256` and `--state-pruning=256`: Keeps only recent blocks and state, reducing disk usage (collators don't need archive data) + - `--database=paritydb`: Uses ParityDB for better performance + - `--sync=fast`: Fast sync mode for the relay chain + - `--pool-limit=0`: Disables transaction pool on relay chain (collators don't need it) + - `--rpc-port=0` (relay chain): Disables RPC on the embedded relay chain node (not needed for collators) ## Run the Collator @@ -318,7 +329,7 @@ Sync time depends on: - Disk I/O speed - Current chain size -The relay chain uses warp sync for faster synchronization. +The relay chain uses fast sync for faster synchronization. !!! warning diff --git a/.ai/pages/node-infrastructure-run-a-node-parachain-rpc.md b/.ai/pages/node-infrastructure-run-a-node-parachain-rpc.md index b5b394b3a..466892c99 100644 --- a/.ai/pages/node-infrastructure-run-a-node-parachain-rpc.md +++ b/.ai/pages/node-infrastructure-run-a-node-parachain-rpc.md @@ -73,7 +73,6 @@ RPC nodes serving production traffic require robust hardware: - 30334 (relay chain P2P) - 9944 (Polkadot SDK WebSocket RPC) - 9933 (Polkadot SDK HTTP RPC) - - 9615 (Prometheus metrics - optional) - Consider DDoS protection and rate limiting for production deployments !!! note @@ -236,7 +235,8 @@ Select the best option for your project, then use the steps in the following tab --base-path=/data \ --chain=polkadot \ --state-pruning=256 \ - --blocks-pruning=archive-canonical + --blocks-pruning=256 \ + --rpc-port=0 ``` === "Pruned Node" @@ -269,7 +269,8 @@ Select the best option for your project, then use the steps in the following tab --base-path=/data \ --chain=polkadot \ --state-pruning=256 \ - --blocks-pruning=archive-canonical + --blocks-pruning=256 \ + --rpc-port=0 ``` !!! note @@ -441,7 +442,8 @@ Select the best option for your project, then use the steps in the following tab --base-path=/var/lib/people-chain-rpc \ --port=30334 \ --state-pruning=256 \ - --blocks-pruning=archive-canonical + --blocks-pruning=256 \ + --rpc-port=0 Restart=always RestartSec=10 @@ -485,7 +487,8 @@ Select the best option for your project, then use the steps in the following tab --base-path=/var/lib/people-chain-rpc \ --port=30334 \ --state-pruning=256 \ - --blocks-pruning=archive-canonical + --blocks-pruning=256 \ + --rpc-port=0 Restart=always RestartSec=10 diff --git a/.ai/pages/node-infrastructure-run-a-node-polkadot-hub-rpc.md b/.ai/pages/node-infrastructure-run-a-node-polkadot-hub-rpc.md index 70fdd2192..419f0a1ab 100644 --- a/.ai/pages/node-infrastructure-run-a-node-polkadot-hub-rpc.md +++ b/.ai/pages/node-infrastructure-run-a-node-polkadot-hub-rpc.md @@ -46,7 +46,6 @@ RPC nodes serving production traffic require robust hardware. The following shou - 30334 (relay chain P2P) - 9944 (Polkadot SDK WebSocket RPC) - 9933 (Polkadot SDK HTTP RPC) - - 9615 (Prometheus metrics - optional) - Consider DDoS protection and rate limiting for production deployments **Note**: For development or low-traffic scenarios, you can reduce these requirements proportionally. Consider using a reverse proxy (nginx, Caddy) for production deployments. @@ -208,7 +207,8 @@ Select the best option for your project, then use the steps in the following tab --base-path=/data \ --chain=polkadot \ --state-pruning=256 \ - --blocks-pruning=archive-canonical + --blocks-pruning=256 \ + --rpc-port=0 ``` === "Pruned Node" @@ -241,7 +241,8 @@ Select the best option for your project, then use the steps in the following tab --base-path=/data \ --chain=polkadot \ --state-pruning=256 \ - --blocks-pruning=archive-canonical + --blocks-pruning=256 \ + --rpc-port=0 ``` Critical configuration parameters include port mappings and node parameters: @@ -399,7 +400,8 @@ Select the best option for your project, then use the steps in the following tab --base-path=/var/lib/polkadot-hub-rpc \ --port=30334 \ --state-pruning=256 \ - --blocks-pruning=archive-canonical + --blocks-pruning=256 \ + --rpc-port=0 Restart=always RestartSec=10 @@ -443,7 +445,8 @@ Select the best option for your project, then use the steps in the following tab --base-path=/var/lib/polkadot-hub-rpc \ --port=30334 \ --state-pruning=256 \ - --blocks-pruning=archive-canonical + --blocks-pruning=256 \ + --rpc-port=0 Restart=always RestartSec=10 From 121857186b4c82b444e3f728b1356872ff8d24f5 Mon Sep 17 00:00:00 2001 From: Bruno Galvao Date: Tue, 9 Dec 2025 16:06:18 +0700 Subject: [PATCH 24/39] Update snapshot URLs and storage requirements for node docs - Switch from rocksdb to paritydb snapshots where available - Update relay chain pruned snapshot size from ~200 GB to ~822 GB - Fix non-existent pruned snapshot URLs (Asset Hub, People Chain) - Clarify storage requirements: archive nodes (~1.2 TB) vs pruned nodes (200+ GB) - Update system parachain snapshot sizes with accurate values --- .../run-a-collator/collator.md | 3 +-- .../run-a-node/parachain-rpc.md | 20 ++++++++-------- .../run-a-node/polkadot-hub-rpc.md | 24 +++++++++---------- 3 files changed, 23 insertions(+), 24 deletions(-) diff --git a/node-infrastructure/run-a-collator/collator.md b/node-infrastructure/run-a-collator/collator.md index 65e53571b..974f7a47d 100644 --- a/node-infrastructure/run-a-collator/collator.md +++ b/node-infrastructure/run-a-collator/collator.md @@ -41,8 +41,7 @@ Block-producing collators require robust hardware for reliable operation includi - **CPU**: 4+ cores (8+ cores recommended for optimal performance) - **Memory**: 32 GB RAM minimum (64 GB recommended) - **Storage**: - - 500 GB+ NVMe SSD for parachain data - - Additional 200+ GB for relay chain pruned database + - 200+ GB NVMe SSD (with pruning enabled for both parachain and relay chain) - Fast disk I/O is critical for block production performance - **Network**: - Public IP address (required) diff --git a/node-infrastructure/run-a-node/parachain-rpc.md b/node-infrastructure/run-a-node/parachain-rpc.md index 38d6e7168..b1b445880 100644 --- a/node-infrastructure/run-a-node/parachain-rpc.md +++ b/node-infrastructure/run-a-node/parachain-rpc.md @@ -39,7 +39,7 @@ curl -L https://raw.githubusercontent.com/paritytech/polkadot-sdk/master/cumulus | System Parachain | Para ID | Chain Spec File | Snapshot Path | |------------------|---------|-----------------|---------------| -| **Bridge Hub** | 1002 | `bridge-hub-polkadot.json` | `polkadot-bridge-hub-rocksdb-archive` | +| **Bridge Hub** | 1002 | `bridge-hub-polkadot.json` | `polkadot-bridge-hub-paritydb-archive` | | **People Chain** | 1004 | `people-polkadot.json` | `polkadot-people-rocksdb-archive` | | **Coretime Chain** | 1005 | `coretime-polkadot.json` | `polkadot-coretime-rocksdb-archive` | @@ -60,8 +60,8 @@ RPC nodes serving production traffic require robust hardware: - **CPU**: 8+ cores (16+ cores for high traffic) - **Memory**: 64 GB RAM minimum (128 GB recommended for high traffic) - **Storage**: - - Storage requirements vary by parachain. System parachains: Asset Hub (~600-800 GB), Bridge Hub (~500-600 GB), Collectives (~400-500 GB), People Chain (~300-400 GB), Coretime (~300-400 GB). For non-system parachains, check the [snapshot sizes](https://snapshots.polkadot.io/){target=\_blank} if available. - - Additional 200+ GB for relay chain pruned database + - Archive node: Storage varies by parachain. Using snapshots, system parachain totals are: Asset Hub (~1.2 TB), Bridge Hub (~1.1 TB), Collectives (~1 TB), People Chain (~900 GB), Coretime (~900 GB). For non-system parachains, check the [snapshot sizes](https://snapshots.polkadot.io/){target=\_blank} and add ~822 GB for the relay chain. + - Pruned node: 200+ GB NVMe SSD (with pruning enabled for both parachain and relay chain) - Fast disk I/O is critical for query performance - **Network**: - Public IP address @@ -136,10 +136,10 @@ Select the best option for your project, then use the steps in the following tab rm files.txt ``` - **Relay chain pruned snapshot** (~200 GB): + **Relay chain pruned snapshot** (~822 GB): ```bash # Check https://snapshots.polkadot.io/ for the latest snapshot URL - export SNAPSHOT_URL_RELAY="https://snapshots.polkadot.io/polkadot-rocksdb-prune/LATEST" + export SNAPSHOT_URL_RELAY="https://snapshots.polkadot.io/polkadot-paritydb-prune/LATEST" rclone copyurl $SNAPSHOT_URL_RELAY/files.txt files.txt rclone copy --progress --transfers 20 \ @@ -161,12 +161,12 @@ Select the best option for your project, then use the steps in the following tab === "Pruned Node" - Pruned node setup keeps recent state for smaller storage. Download both parachain pruned and relay chain pruned snapshots: + Pruned node setup keeps recent state for smaller storage. Since no pruned parachain snapshots are available for most system parachains, this setup uses the parachain archive snapshot with the relay chain pruned snapshot. - **Parachain pruned snapshot** (People Chain example): + **Parachain archive snapshot** (People Chain example, ~71 GB): ```bash # Check https://snapshots.polkadot.io/ for the latest snapshot URL - export SNAPSHOT_URL_PARACHAIN="https://snapshots.polkadot.io/polkadot-people-rocksdb-prune/LATEST" + export SNAPSHOT_URL_PARACHAIN="https://snapshots.polkadot.io/polkadot-people-rocksdb-archive/LATEST" rclone copyurl $SNAPSHOT_URL_PARACHAIN/files.txt files.txt rclone copy --progress --transfers 20 \ @@ -179,10 +179,10 @@ Select the best option for your project, then use the steps in the following tab rm files.txt ``` - **Relay chain pruned snapshot** (~200 GB): + **Relay chain pruned snapshot** (~822 GB): ```bash # Check https://snapshots.polkadot.io/ for the latest snapshot URL - export SNAPSHOT_URL_RELAY="https://snapshots.polkadot.io/polkadot-rocksdb-prune/LATEST" + export SNAPSHOT_URL_RELAY="https://snapshots.polkadot.io/polkadot-paritydb-prune/LATEST" rclone copyurl $SNAPSHOT_URL_RELAY/files.txt files.txt rclone copy --progress --transfers 20 \ diff --git a/node-infrastructure/run-a-node/polkadot-hub-rpc.md b/node-infrastructure/run-a-node/polkadot-hub-rpc.md index 0656e7fa5..809b88747 100644 --- a/node-infrastructure/run-a-node/polkadot-hub-rpc.md +++ b/node-infrastructure/run-a-node/polkadot-hub-rpc.md @@ -33,8 +33,8 @@ RPC nodes serving production traffic require robust hardware. The following shou - **CPU**: 8+ cores (16+ cores for high traffic) - **Memory**: 64 GB RAM minimum (128 GB recommended for high traffic) - **Storage**: - - 500 GB+ NVMe SSD for parachain state (archive nodes require 600-800 GB+) - - Additional 200+ GB for relay chain pruned database + - Archive node: ~1.2 TB NVMe SSD total (~392 GB for Asset Hub archive + ~822 GB for relay chain pruned snapshot) + - Pruned node: 200+ GB NVMe SSD (with pruning enabled for both parachain and relay chain) - Fast disk I/O is critical for query performance - **Network**: - Public IP address @@ -91,12 +91,12 @@ Select the best option for your project, then use the steps in the following tab === "Archive Node" - Archive node setup maintains complete parachain history (~600-800 GB total). Download both Asset Hub archive and Relay chain pruned snapshots: + Archive node setup maintains complete parachain history (~1.2 TB total). Download both Asset Hub archive and Relay chain pruned snapshots: - **Asset Hub archive snapshot** (~400 GB): + **Asset Hub archive snapshot** (~392 GB): ```bash # Check https://snapshots.polkadot.io/ for the latest snapshot URL - export SNAPSHOT_URL_ASSET_HUB="https://snapshots.polkadot.io/polkadot-asset-hub-rocksdb-archive/LATEST" + export SNAPSHOT_URL_ASSET_HUB="https://snapshots.polkadot.io/polkadot-asset-hub-paritydb-archive/LATEST" rclone copyurl $SNAPSHOT_URL_ASSET_HUB/files.txt files.txt rclone copy --progress --transfers 20 \ @@ -109,10 +109,10 @@ Select the best option for your project, then use the steps in the following tab rm files.txt ``` - **Relay chain pruned snapshot** (~200 GB): + **Relay chain pruned snapshot** (~822 GB): ```bash # Check https://snapshots.polkadot.io/ for the latest snapshot URL - export SNAPSHOT_URL_RELAY="https://snapshots.polkadot.io/polkadot-rocksdb-prune/LATEST" + export SNAPSHOT_URL_RELAY="https://snapshots.polkadot.io/polkadot-paritydb-prune/LATEST" rclone copyurl $SNAPSHOT_URL_RELAY/files.txt files.txt rclone copy --progress --transfers 20 \ @@ -134,12 +134,12 @@ Select the best option for your project, then use the steps in the following tab === "Pruned Node" - Pruned node setup keeps recent state for smaller storage (~500 GB total). Download both Asset Hub pruned and Relay chain pruned snapshots: + Pruned node setup keeps recent state for smaller storage. Since no pruned Asset Hub snapshot is available, this setup uses the Asset Hub archive snapshot with the Relay chain pruned snapshot (~1.2 TB total). - **Asset Hub pruned snapshot**: + **Asset Hub archive snapshot** (~392 GB): ```bash # Check https://snapshots.polkadot.io/ for the latest snapshot URL - export SNAPSHOT_URL_ASSET_HUB="https://snapshots.polkadot.io/polkadot-asset-hub-rocksdb-prune/LATEST" + export SNAPSHOT_URL_ASSET_HUB="https://snapshots.polkadot.io/polkadot-asset-hub-paritydb-archive/LATEST" rclone copyurl $SNAPSHOT_URL_ASSET_HUB/files.txt files.txt rclone copy --progress --transfers 20 \ @@ -152,10 +152,10 @@ Select the best option for your project, then use the steps in the following tab rm files.txt ``` - **Relay chain pruned snapshot** (~200 GB): + **Relay chain pruned snapshot** (~822 GB): ```bash # Check https://snapshots.polkadot.io/ for the latest snapshot URL - export SNAPSHOT_URL_RELAY="https://snapshots.polkadot.io/polkadot-rocksdb-prune/LATEST" + export SNAPSHOT_URL_RELAY="https://snapshots.polkadot.io/polkadot-paritydb-prune/LATEST" rclone copyurl $SNAPSHOT_URL_RELAY/files.txt files.txt rclone copy --progress --transfers 20 \ From decf9d534bff6e81f1dd4f7b2efe172d6b3a7969 Mon Sep 17 00:00:00 2001 From: Bruno Galvao Date: Tue, 9 Dec 2025 16:26:47 +0700 Subject: [PATCH 25/39] Simplify snapshot sections to single archive instructions Remove duplicate tabs for archive/pruned snapshots since the same archive snapshots are used for both node types. --- .../run-a-node/parachain-rpc.md | 127 ++++++------------ .../run-a-node/polkadot-hub-rpc.md | 127 ++++++------------ 2 files changed, 80 insertions(+), 174 deletions(-) diff --git a/node-infrastructure/run-a-node/parachain-rpc.md b/node-infrastructure/run-a-node/parachain-rpc.md index b1b445880..ae71ec8b7 100644 --- a/node-infrastructure/run-a-node/parachain-rpc.md +++ b/node-infrastructure/run-a-node/parachain-rpc.md @@ -114,93 +114,46 @@ Select the best option for your project, then use the steps in the following tab mkdir -p my-node-data/chains/people-polkadot/db mkdir -p my-node-data/chains/polkadot/db ``` - 2. Download the appropriate snapshots using the following commands: - - === "Archive Node" - - Archive node setup maintains complete parachain history. Download both parachain archive and relay chain pruned snapshots: - - **Parachain archive snapshot** (People Chain example): - ```bash - # Check https://snapshots.polkadot.io/ for the latest snapshot URL - export SNAPSHOT_URL_PARACHAIN="https://snapshots.polkadot.io/polkadot-people-rocksdb-archive/LATEST" - - rclone copyurl $SNAPSHOT_URL_PARACHAIN/files.txt files.txt - rclone copy --progress --transfers 20 \ - --http-url $SNAPSHOT_URL_PARACHAIN \ - --no-traverse --http-no-head --disable-http2 \ - --inplace --no-gzip-encoding --size-only \ - --retries 6 --retries-sleep 10s \ - --files-from files.txt :http: my-node-data/chains/people-polkadot/db/ - - rm files.txt - ``` - - **Relay chain pruned snapshot** (~822 GB): - ```bash - # Check https://snapshots.polkadot.io/ for the latest snapshot URL - export SNAPSHOT_URL_RELAY="https://snapshots.polkadot.io/polkadot-paritydb-prune/LATEST" - - rclone copyurl $SNAPSHOT_URL_RELAY/files.txt files.txt - rclone copy --progress --transfers 20 \ - --http-url $SNAPSHOT_URL_RELAY \ - --no-traverse --http-no-head --disable-http2 \ - --inplace --no-gzip-encoding --size-only \ - --retries 6 --retries-sleep 10s \ - --files-from files.txt :http: my-node-data/chains/polkadot/db/ - - rm files.txt - ``` - - **rclone parameters:** - - - `--transfers 20`: Uses 20 parallel transfers for faster download - - `--retries 6`: Automatically retries failed transfers up to 6 times - - `--retries-sleep 10s`: Waits 10 seconds between retry attempts - - `--size-only`: Only transfers if sizes differ (prevents unnecessary re-downloads) - - === "Pruned Node" - - Pruned node setup keeps recent state for smaller storage. Since no pruned parachain snapshots are available for most system parachains, this setup uses the parachain archive snapshot with the relay chain pruned snapshot. - - **Parachain archive snapshot** (People Chain example, ~71 GB): - ```bash - # Check https://snapshots.polkadot.io/ for the latest snapshot URL - export SNAPSHOT_URL_PARACHAIN="https://snapshots.polkadot.io/polkadot-people-rocksdb-archive/LATEST" - - rclone copyurl $SNAPSHOT_URL_PARACHAIN/files.txt files.txt - rclone copy --progress --transfers 20 \ - --http-url $SNAPSHOT_URL_PARACHAIN \ - --no-traverse --http-no-head --disable-http2 \ - --inplace --no-gzip-encoding --size-only \ - --retries 6 --retries-sleep 10s \ - --files-from files.txt :http: my-node-data/chains/people-polkadot/db/ - - rm files.txt - ``` - - **Relay chain pruned snapshot** (~822 GB): - ```bash - # Check https://snapshots.polkadot.io/ for the latest snapshot URL - export SNAPSHOT_URL_RELAY="https://snapshots.polkadot.io/polkadot-paritydb-prune/LATEST" - - rclone copyurl $SNAPSHOT_URL_RELAY/files.txt files.txt - rclone copy --progress --transfers 20 \ - --http-url $SNAPSHOT_URL_RELAY \ - --no-traverse --http-no-head --disable-http2 \ - --inplace --no-gzip-encoding --size-only \ - --retries 6 --retries-sleep 10s \ - --files-from files.txt :http: my-node-data/chains/polkadot/db/ - - rm files.txt - ``` - - **rclone parameters:** - - - `--transfers 20`: Uses 20 parallel transfers for faster download - - `--retries 6`: Automatically retries failed transfers up to 6 times - - `--retries-sleep 10s`: Waits 10 seconds between retry attempts - - `--size-only`: Only transfers if sizes differ (prevents unnecessary re-downloads) + 2. Download the snapshots: + + **Parachain archive snapshot** (People Chain example, ~71 GB): + ```bash + # Check https://snapshots.polkadot.io/ for the latest snapshot URL + export SNAPSHOT_URL_PARACHAIN="https://snapshots.polkadot.io/polkadot-people-rocksdb-archive/LATEST" + + rclone copyurl $SNAPSHOT_URL_PARACHAIN/files.txt files.txt + rclone copy --progress --transfers 20 \ + --http-url $SNAPSHOT_URL_PARACHAIN \ + --no-traverse --http-no-head --disable-http2 \ + --inplace --no-gzip-encoding --size-only \ + --retries 6 --retries-sleep 10s \ + --files-from files.txt :http: my-node-data/chains/people-polkadot/db/ + + rm files.txt + ``` + + **Relay chain pruned snapshot** (~822 GB): + ```bash + # Check https://snapshots.polkadot.io/ for the latest snapshot URL + export SNAPSHOT_URL_RELAY="https://snapshots.polkadot.io/polkadot-paritydb-prune/LATEST" + + rclone copyurl $SNAPSHOT_URL_RELAY/files.txt files.txt + rclone copy --progress --transfers 20 \ + --http-url $SNAPSHOT_URL_RELAY \ + --no-traverse --http-no-head --disable-http2 \ + --inplace --no-gzip-encoding --size-only \ + --retries 6 --retries-sleep 10s \ + --files-from files.txt :http: my-node-data/chains/polkadot/db/ + + rm files.txt + ``` + + **rclone parameters:** + + - `--transfers 20`: Uses 20 parallel transfers for faster download + - `--retries 6`: Automatically retries failed transfers up to 6 times + - `--retries-sleep 10s`: Waits 10 seconds between retry attempts + - `--size-only`: Only transfers if sizes differ (prevents unnecessary re-downloads) 3. Launch the parachain node using the official [Parity Docker image](https://hub.docker.com/r/parity/polkadot-parachain){target=\_blank}: diff --git a/node-infrastructure/run-a-node/polkadot-hub-rpc.md b/node-infrastructure/run-a-node/polkadot-hub-rpc.md index 809b88747..5ca8207e8 100644 --- a/node-infrastructure/run-a-node/polkadot-hub-rpc.md +++ b/node-infrastructure/run-a-node/polkadot-hub-rpc.md @@ -87,93 +87,46 @@ Select the best option for your project, then use the steps in the following tab mkdir -p my-node-data/chains/asset-hub-polkadot/db mkdir -p my-node-data/chains/polkadot/db ``` - 2. Download the appropriate snapshots using the following commands: - - === "Archive Node" - - Archive node setup maintains complete parachain history (~1.2 TB total). Download both Asset Hub archive and Relay chain pruned snapshots: - - **Asset Hub archive snapshot** (~392 GB): - ```bash - # Check https://snapshots.polkadot.io/ for the latest snapshot URL - export SNAPSHOT_URL_ASSET_HUB="https://snapshots.polkadot.io/polkadot-asset-hub-paritydb-archive/LATEST" - - rclone copyurl $SNAPSHOT_URL_ASSET_HUB/files.txt files.txt - rclone copy --progress --transfers 20 \ - --http-url $SNAPSHOT_URL_ASSET_HUB \ - --no-traverse --http-no-head --disable-http2 \ - --inplace --no-gzip-encoding --size-only \ - --retries 6 --retries-sleep 10s \ - --files-from files.txt :http: my-node-data/chains/asset-hub-polkadot/db/ - - rm files.txt - ``` - - **Relay chain pruned snapshot** (~822 GB): - ```bash - # Check https://snapshots.polkadot.io/ for the latest snapshot URL - export SNAPSHOT_URL_RELAY="https://snapshots.polkadot.io/polkadot-paritydb-prune/LATEST" - - rclone copyurl $SNAPSHOT_URL_RELAY/files.txt files.txt - rclone copy --progress --transfers 20 \ - --http-url $SNAPSHOT_URL_RELAY \ - --no-traverse --http-no-head --disable-http2 \ - --inplace --no-gzip-encoding --size-only \ - --retries 6 --retries-sleep 10s \ - --files-from files.txt :http: my-node-data/chains/polkadot/db/ - - rm files.txt - ``` - - **rclone parameters:** - - - `--transfers 20`: Uses 20 parallel transfers for faster download - - `--retries 6`: Automatically retries failed transfers up to 6 times - - `--retries-sleep 10s`: Waits 10 seconds between retry attempts - - `--size-only`: Only transfers if sizes differ (prevents unnecessary re-downloads) - - === "Pruned Node" - - Pruned node setup keeps recent state for smaller storage. Since no pruned Asset Hub snapshot is available, this setup uses the Asset Hub archive snapshot with the Relay chain pruned snapshot (~1.2 TB total). - - **Asset Hub archive snapshot** (~392 GB): - ```bash - # Check https://snapshots.polkadot.io/ for the latest snapshot URL - export SNAPSHOT_URL_ASSET_HUB="https://snapshots.polkadot.io/polkadot-asset-hub-paritydb-archive/LATEST" - - rclone copyurl $SNAPSHOT_URL_ASSET_HUB/files.txt files.txt - rclone copy --progress --transfers 20 \ - --http-url $SNAPSHOT_URL_ASSET_HUB \ - --no-traverse --http-no-head --disable-http2 \ - --inplace --no-gzip-encoding --size-only \ - --retries 6 --retries-sleep 10s \ - --files-from files.txt :http: my-node-data/chains/asset-hub-polkadot/db/ - - rm files.txt - ``` - - **Relay chain pruned snapshot** (~822 GB): - ```bash - # Check https://snapshots.polkadot.io/ for the latest snapshot URL - export SNAPSHOT_URL_RELAY="https://snapshots.polkadot.io/polkadot-paritydb-prune/LATEST" - - rclone copyurl $SNAPSHOT_URL_RELAY/files.txt files.txt - rclone copy --progress --transfers 20 \ - --http-url $SNAPSHOT_URL_RELAY \ - --no-traverse --http-no-head --disable-http2 \ - --inplace --no-gzip-encoding --size-only \ - --retries 6 --retries-sleep 10s \ - --files-from files.txt :http: my-node-data/chains/polkadot/db/ - - rm files.txt - ``` - - **rclone parameters:** - - - `--transfers 20`: Uses 20 parallel transfers for faster download - - `--retries 6`: Automatically retries failed transfers up to 6 times - - `--retries-sleep 10s`: Waits 10 seconds between retry attempts - - `--size-only`: Only transfers if sizes differ (prevents unnecessary re-downloads) + 2. Download the snapshots (~1.2 TB total): + + **Asset Hub archive snapshot** (~392 GB): + ```bash + # Check https://snapshots.polkadot.io/ for the latest snapshot URL + export SNAPSHOT_URL_ASSET_HUB="https://snapshots.polkadot.io/polkadot-asset-hub-paritydb-archive/LATEST" + + rclone copyurl $SNAPSHOT_URL_ASSET_HUB/files.txt files.txt + rclone copy --progress --transfers 20 \ + --http-url $SNAPSHOT_URL_ASSET_HUB \ + --no-traverse --http-no-head --disable-http2 \ + --inplace --no-gzip-encoding --size-only \ + --retries 6 --retries-sleep 10s \ + --files-from files.txt :http: my-node-data/chains/asset-hub-polkadot/db/ + + rm files.txt + ``` + + **Relay chain pruned snapshot** (~822 GB): + ```bash + # Check https://snapshots.polkadot.io/ for the latest snapshot URL + export SNAPSHOT_URL_RELAY="https://snapshots.polkadot.io/polkadot-paritydb-prune/LATEST" + + rclone copyurl $SNAPSHOT_URL_RELAY/files.txt files.txt + rclone copy --progress --transfers 20 \ + --http-url $SNAPSHOT_URL_RELAY \ + --no-traverse --http-no-head --disable-http2 \ + --inplace --no-gzip-encoding --size-only \ + --retries 6 --retries-sleep 10s \ + --files-from files.txt :http: my-node-data/chains/polkadot/db/ + + rm files.txt + ``` + + **rclone parameters:** + + - `--transfers 20`: Uses 20 parallel transfers for faster download + - `--retries 6`: Automatically retries failed transfers up to 6 times + - `--retries-sleep 10s`: Waits 10 seconds between retry attempts + - `--size-only`: Only transfers if sizes differ (prevents unnecessary re-downloads) 3. Launch Polkadot Hub Node using the official [Parity Docker image](https://hub.docker.com/r/parity/polkadot-parachain){target=\_blank}: === "Archive Node" From 41f354860c5349eb5cdbdf04793e979f4c74c513 Mon Sep 17 00:00:00 2001 From: Bruno Galvao Date: Tue, 9 Dec 2025 16:44:28 +0700 Subject: [PATCH 26/39] Add Docker setup option for collator deployment Restructure Run the Collator section to provide both Docker and systemd setup options in tabs, consistent with other node documentation. --- .../run-a-collator/collator.md | 227 +++++++++++------- 1 file changed, 139 insertions(+), 88 deletions(-) diff --git a/node-infrastructure/run-a-collator/collator.md b/node-infrastructure/run-a-collator/collator.md index 974f7a47d..74ffd70da 100644 --- a/node-infrastructure/run-a-collator/collator.md +++ b/node-infrastructure/run-a-collator/collator.md @@ -211,72 +211,151 @@ Follow these steps to build a chainspec from the runtime: - People Chain: 1004 - Coretime Chain: 1005 -## Create User and Directory Structure +## Run the Collator -1. Create a dedicated user with the following command: - ```bash - sudo useradd -r -s /bin/bash polkadot - ``` +Select your preferred deployment method: -2. Use the following command to copy your chain spec to the directory: - ```bash - sudo cp chain-spec.json /var/lib/polkadot-collator/ - ``` +=== "Docker Setup" -3. Set permissions using the following command: - ```bash - sudo chown -R polkadot:polkadot /var/lib/polkadot-collator - ``` + 1. Create a directory for collator data and copy the chain spec: + ```bash + mkdir -p collator-data + cp chain-spec.json collator-data/ + cp /var/lib/polkadot-collator/node.key collator-data/ + ``` -## Create Systemd Service File + 2. Launch the collator using Docker: + ```bash + docker run -d --name polkadot-collator --restart unless-stopped \ + -p 30333:30333 \ + -p 30334:30334 \ + -p 9944:9944 \ + -p 9615:9615 \ + -v $(pwd)/collator-data:/data \ + -v $(pwd)/chain-spec.json:/chain-spec.json \ + parity/polkadot-parachain:stable2509-2 \ + --collator \ + --chain=/chain-spec.json \ + --base-path=/data \ + --port=30333 \ + --rpc-port=9944 \ + --prometheus-port=9615 \ + --prometheus-external \ + --node-key-file=/data/node.key \ + --name="YourCollatorName" \ + --blocks-pruning=256 \ + --state-pruning=256 \ + --database=paritydb \ + -- \ + --chain=polkadot \ + --port=30334 \ + --sync=fast \ + --blocks-pruning=256 \ + --state-pruning=256 \ + --database=paritydb \ + --pool-limit=0 \ + --rpc-port=0 + ``` -1. Create a service file to hold the configuration for your collator: - ```bash - sudo nano /etc/systemd/system/polkadot-collator.service - ``` + 3. View logs to monitor sync progress: + ```bash + docker logs -f polkadot-collator + ``` -2. Open the new file and add the following configuration code: - ```ini title="systemd/system/polkadot-collator.service" - [Unit] - Description=Polkadot System Parachain Collator - After=network.target - - [Service] - Type=simple - User=polkadot - Group=polkadot - WorkingDirectory=/var/lib/polkadot-collator - - # Block-Producing Collator Configuration - ExecStart=/usr/local/bin/polkadot-parachain \ - --collator \ - --chain=/var/lib/polkadot-collator/chain-spec.json \ - --base-path=/var/lib/polkadot-collator \ - --port=30333 \ - --rpc-port=9944 \ - --prometheus-port=9615 \ - --node-key-file=/var/lib/polkadot-collator/node.key \ - --name="YourCollatorName" \ - --blocks-pruning=256 \ - --state-pruning=256 \ - --database=paritydb \ - -- \ - --chain=polkadot \ - --port=30334 \ - --sync=fast \ - --blocks-pruning=256 \ - --state-pruning=256 \ - --database=paritydb \ - --pool-limit=0 \ - --rpc-port=0 - - Restart=always - RestartSec=10 - LimitNOFILE=65536 - - [Install] - WantedBy=multi-user.target - ``` + 4. Use the following commands to manage your Docker container: + - Stop container: + ```bash + docker stop polkadot-collator + ``` + - Start container: + ```bash + docker start polkadot-collator + ``` + - Remove container: + ```bash + docker rm polkadot-collator + ``` + +=== "systemd Setup" + + 1. Create a dedicated user: + ```bash + sudo useradd -r -s /bin/bash polkadot + ``` + + 2. Copy your chain spec to the directory: + ```bash + sudo cp chain-spec.json /var/lib/polkadot-collator/ + ``` + + 3. Set permissions: + ```bash + sudo chown -R polkadot:polkadot /var/lib/polkadot-collator + ``` + + 4. Create a systemd service file: + ```bash + sudo nano /etc/systemd/system/polkadot-collator.service + ``` + + 5. Add the following configuration: + ```ini title="systemd/system/polkadot-collator.service" + [Unit] + Description=Polkadot System Parachain Collator + After=network.target + + [Service] + Type=simple + User=polkadot + Group=polkadot + WorkingDirectory=/var/lib/polkadot-collator + + ExecStart=/usr/local/bin/polkadot-parachain \ + --collator \ + --chain=/var/lib/polkadot-collator/chain-spec.json \ + --base-path=/var/lib/polkadot-collator \ + --port=30333 \ + --rpc-port=9944 \ + --prometheus-port=9615 \ + --node-key-file=/var/lib/polkadot-collator/node.key \ + --name="YourCollatorName" \ + --blocks-pruning=256 \ + --state-pruning=256 \ + --database=paritydb \ + -- \ + --chain=polkadot \ + --port=30334 \ + --sync=fast \ + --blocks-pruning=256 \ + --state-pruning=256 \ + --database=paritydb \ + --pool-limit=0 \ + --rpc-port=0 + + Restart=always + RestartSec=10 + LimitNOFILE=65536 + + [Install] + WantedBy=multi-user.target + ``` + + 6. Start the service: + ```bash + sudo systemctl daemon-reload + sudo systemctl enable polkadot-collator + sudo systemctl start polkadot-collator + ``` + + 7. Check the status: + ```bash + sudo systemctl status polkadot-collator + ``` + + 8. View logs: + ```bash + sudo journalctl -u polkadot-collator -f + ``` ??? note "Configuration notes" @@ -289,34 +368,6 @@ Follow these steps to build a chainspec from the runtime: - `--pool-limit=0`: Disables transaction pool on relay chain (collators don't need it) - `--rpc-port=0` (relay chain): Disables RPC on the embedded relay chain node (not needed for collators) -## Run the Collator - -Follow these steps to run your collator node: - -1. Reload systemd using the following command: - ```bash - sudo systemctl daemon-reload - ``` - -2. Next, enable the service to start on boot using the command: - ```bash - sudo systemctl enable polkadot-collator - ``` -3. Now, start the service with the following command: - ```bash - sudo systemctl start polkadot-collator - ``` - -4. Finally, you can check the status of the service using the command: - ```bash - sudo systemctl status polkadot-collator - ``` - -To view collator service logs, use the command: -```bash -sudo journalctl -u polkadot-collator -f -``` - ## Complete Initial Sync Your collator must sync both the relay chain and parachain before producing blocks. From 9a200f28f6b9ac09c54c56c46a71c0096633ff6b Mon Sep 17 00:00:00 2001 From: Bruno Galvao Date: Tue, 9 Dec 2025 16:56:51 +0700 Subject: [PATCH 27/39] LLMS files --- ...-infrastructure-run-a-collator-collator.md | 230 +++++++++++------- ...infrastructure-run-a-node-parachain-rpc.md | 133 ++++------ ...rastructure-run-a-node-polkadot-hub-rpc.md | 131 ++++------ 3 files changed, 225 insertions(+), 269 deletions(-) diff --git a/.ai/pages/node-infrastructure-run-a-collator-collator.md b/.ai/pages/node-infrastructure-run-a-collator-collator.md index 0a7aa466c..2219a928d 100644 --- a/.ai/pages/node-infrastructure-run-a-collator-collator.md +++ b/.ai/pages/node-infrastructure-run-a-collator-collator.md @@ -42,8 +42,7 @@ Block-producing collators require robust hardware for reliable operation includi - **CPU**: 4+ cores (8+ cores recommended for optimal performance) - **Memory**: 32 GB RAM minimum (64 GB recommended) - **Storage**: - - 500 GB+ NVMe SSD for parachain data - - Additional 200+ GB for relay chain pruned database + - 200+ GB NVMe SSD (with pruning enabled for both parachain and relay chain) - Fast disk I/O is critical for block production performance - **Network**: - Public IP address (required) @@ -213,72 +212,151 @@ Follow these steps to build a chainspec from the runtime: - People Chain: 1004 - Coretime Chain: 1005 -## Create User and Directory Structure +## Run the Collator -1. Create a dedicated user with the following command: - ```bash - sudo useradd -r -s /bin/bash polkadot - ``` +Select your preferred deployment method: -2. Use the following command to copy your chain spec to the directory: - ```bash - sudo cp chain-spec.json /var/lib/polkadot-collator/ - ``` +=== "Docker Setup" -3. Set permissions using the following command: - ```bash - sudo chown -R polkadot:polkadot /var/lib/polkadot-collator - ``` + 1. Create a directory for collator data and copy the chain spec: + ```bash + mkdir -p collator-data + cp chain-spec.json collator-data/ + cp /var/lib/polkadot-collator/node.key collator-data/ + ``` -## Create Systemd Service File + 2. Launch the collator using Docker: + ```bash + docker run -d --name polkadot-collator --restart unless-stopped \ + -p 30333:30333 \ + -p 30334:30334 \ + -p 9944:9944 \ + -p 9615:9615 \ + -v $(pwd)/collator-data:/data \ + -v $(pwd)/chain-spec.json:/chain-spec.json \ + parity/polkadot-parachain:stable2509-2 \ + --collator \ + --chain=/chain-spec.json \ + --base-path=/data \ + --port=30333 \ + --rpc-port=9944 \ + --prometheus-port=9615 \ + --prometheus-external \ + --node-key-file=/data/node.key \ + --name="YourCollatorName" \ + --blocks-pruning=256 \ + --state-pruning=256 \ + --database=paritydb \ + -- \ + --chain=polkadot \ + --port=30334 \ + --sync=fast \ + --blocks-pruning=256 \ + --state-pruning=256 \ + --database=paritydb \ + --pool-limit=0 \ + --rpc-port=0 + ``` -1. Create a service file to hold the configuration for your collator: - ```bash - sudo nano /etc/systemd/system/polkadot-collator.service - ``` + 3. View logs to monitor sync progress: + ```bash + docker logs -f polkadot-collator + ``` -2. Open the new file and add the following configuration code: - ```ini title="systemd/system/polkadot-collator.service" - [Unit] - Description=Polkadot System Parachain Collator - After=network.target - - [Service] - Type=simple - User=polkadot - Group=polkadot - WorkingDirectory=/var/lib/polkadot-collator - - # Block-Producing Collator Configuration - ExecStart=/usr/local/bin/polkadot-parachain \ - --collator \ - --chain=/var/lib/polkadot-collator/chain-spec.json \ - --base-path=/var/lib/polkadot-collator \ - --port=30333 \ - --rpc-port=9944 \ - --prometheus-port=9615 \ - --node-key-file=/var/lib/polkadot-collator/node.key \ - --name="YourCollatorName" \ - --blocks-pruning=256 \ - --state-pruning=256 \ - --database=paritydb \ - -- \ - --chain=polkadot \ - --port=30334 \ - --sync=fast \ - --blocks-pruning=256 \ - --state-pruning=256 \ - --database=paritydb \ - --pool-limit=0 \ - --rpc-port=0 - - Restart=always - RestartSec=10 - LimitNOFILE=65536 - - [Install] - WantedBy=multi-user.target - ``` + 4. Use the following commands to manage your Docker container: + - Stop container: + ```bash + docker stop polkadot-collator + ``` + - Start container: + ```bash + docker start polkadot-collator + ``` + - Remove container: + ```bash + docker rm polkadot-collator + ``` + +=== "systemd Setup" + + 1. Create a dedicated user: + ```bash + sudo useradd -r -s /bin/bash polkadot + ``` + + 2. Copy your chain spec to the directory: + ```bash + sudo cp chain-spec.json /var/lib/polkadot-collator/ + ``` + + 3. Set permissions: + ```bash + sudo chown -R polkadot:polkadot /var/lib/polkadot-collator + ``` + + 4. Create a systemd service file: + ```bash + sudo nano /etc/systemd/system/polkadot-collator.service + ``` + + 5. Add the following configuration: + ```ini title="systemd/system/polkadot-collator.service" + [Unit] + Description=Polkadot System Parachain Collator + After=network.target + + [Service] + Type=simple + User=polkadot + Group=polkadot + WorkingDirectory=/var/lib/polkadot-collator + + ExecStart=/usr/local/bin/polkadot-parachain \ + --collator \ + --chain=/var/lib/polkadot-collator/chain-spec.json \ + --base-path=/var/lib/polkadot-collator \ + --port=30333 \ + --rpc-port=9944 \ + --prometheus-port=9615 \ + --node-key-file=/var/lib/polkadot-collator/node.key \ + --name="YourCollatorName" \ + --blocks-pruning=256 \ + --state-pruning=256 \ + --database=paritydb \ + -- \ + --chain=polkadot \ + --port=30334 \ + --sync=fast \ + --blocks-pruning=256 \ + --state-pruning=256 \ + --database=paritydb \ + --pool-limit=0 \ + --rpc-port=0 + + Restart=always + RestartSec=10 + LimitNOFILE=65536 + + [Install] + WantedBy=multi-user.target + ``` + + 6. Start the service: + ```bash + sudo systemctl daemon-reload + sudo systemctl enable polkadot-collator + sudo systemctl start polkadot-collator + ``` + + 7. Check the status: + ```bash + sudo systemctl status polkadot-collator + ``` + + 8. View logs: + ```bash + sudo journalctl -u polkadot-collator -f + ``` ??? note "Configuration notes" @@ -291,34 +369,6 @@ Follow these steps to build a chainspec from the runtime: - `--pool-limit=0`: Disables transaction pool on relay chain (collators don't need it) - `--rpc-port=0` (relay chain): Disables RPC on the embedded relay chain node (not needed for collators) -## Run the Collator - -Follow these steps to run your collator node: - -1. Reload systemd using the following command: - ```bash - sudo systemctl daemon-reload - ``` - -2. Next, enable the service to start on boot using the command: - ```bash - sudo systemctl enable polkadot-collator - ``` -3. Now, start the service with the following command: - ```bash - sudo systemctl start polkadot-collator - ``` - -4. Finally, you can check the status of the service using the command: - ```bash - sudo systemctl status polkadot-collator - ``` - -To view collator service logs, use the command: -```bash -sudo journalctl -u polkadot-collator -f -``` - ## Complete Initial Sync Your collator must sync both the relay chain and parachain before producing blocks. diff --git a/.ai/pages/node-infrastructure-run-a-node-parachain-rpc.md b/.ai/pages/node-infrastructure-run-a-node-parachain-rpc.md index 466892c99..fe0c5c578 100644 --- a/.ai/pages/node-infrastructure-run-a-node-parachain-rpc.md +++ b/.ai/pages/node-infrastructure-run-a-node-parachain-rpc.md @@ -40,7 +40,7 @@ curl -L https://raw.githubusercontent.com/paritytech/polkadot-sdk/master/cumulus | System Parachain | Para ID | Chain Spec File | Snapshot Path | |------------------|---------|-----------------|---------------| -| **Bridge Hub** | 1002 | `bridge-hub-polkadot.json` | `polkadot-bridge-hub-rocksdb-archive` | +| **Bridge Hub** | 1002 | `bridge-hub-polkadot.json` | `polkadot-bridge-hub-paritydb-archive` | | **People Chain** | 1004 | `people-polkadot.json` | `polkadot-people-rocksdb-archive` | | **Coretime Chain** | 1005 | `coretime-polkadot.json` | `polkadot-coretime-rocksdb-archive` | @@ -61,8 +61,8 @@ RPC nodes serving production traffic require robust hardware: - **CPU**: 8+ cores (16+ cores for high traffic) - **Memory**: 64 GB RAM minimum (128 GB recommended for high traffic) - **Storage**: - - Storage requirements vary by parachain. System parachains: Asset Hub (~600-800 GB), Bridge Hub (~500-600 GB), Collectives (~400-500 GB), People Chain (~300-400 GB), Coretime (~300-400 GB). For non-system parachains, check the [snapshot sizes](https://snapshots.polkadot.io/){target=\_blank} if available. - - Additional 200+ GB for relay chain pruned database + - Archive node: Storage varies by parachain. Using snapshots, system parachain totals are: Asset Hub (~1.2 TB), Bridge Hub (~1.1 TB), Collectives (~1 TB), People Chain (~900 GB), Coretime (~900 GB). For non-system parachains, check the [snapshot sizes](https://snapshots.polkadot.io/){target=\_blank} and add ~822 GB for the relay chain. + - Pruned node: 200+ GB NVMe SSD (with pruning enabled for both parachain and relay chain) - Fast disk I/O is critical for query performance - **Network**: - Public IP address @@ -115,93 +115,46 @@ Select the best option for your project, then use the steps in the following tab mkdir -p my-node-data/chains/people-polkadot/db mkdir -p my-node-data/chains/polkadot/db ``` - 2. Download the appropriate snapshots using the following commands: - - === "Archive Node" - - Archive node setup maintains complete parachain history. Download both parachain archive and relay chain pruned snapshots: - - **Parachain archive snapshot** (People Chain example): - ```bash - # Check https://snapshots.polkadot.io/ for the latest snapshot URL - export SNAPSHOT_URL_PARACHAIN="https://snapshots.polkadot.io/polkadot-people-rocksdb-archive/LATEST" - - rclone copyurl $SNAPSHOT_URL_PARACHAIN/files.txt files.txt - rclone copy --progress --transfers 20 \ - --http-url $SNAPSHOT_URL_PARACHAIN \ - --no-traverse --http-no-head --disable-http2 \ - --inplace --no-gzip-encoding --size-only \ - --retries 6 --retries-sleep 10s \ - --files-from files.txt :http: my-node-data/chains/people-polkadot/db/ - - rm files.txt - ``` - - **Relay chain pruned snapshot** (~200 GB): - ```bash - # Check https://snapshots.polkadot.io/ for the latest snapshot URL - export SNAPSHOT_URL_RELAY="https://snapshots.polkadot.io/polkadot-rocksdb-prune/LATEST" - - rclone copyurl $SNAPSHOT_URL_RELAY/files.txt files.txt - rclone copy --progress --transfers 20 \ - --http-url $SNAPSHOT_URL_RELAY \ - --no-traverse --http-no-head --disable-http2 \ - --inplace --no-gzip-encoding --size-only \ - --retries 6 --retries-sleep 10s \ - --files-from files.txt :http: my-node-data/chains/polkadot/db/ - - rm files.txt - ``` - - **rclone parameters:** - - - `--transfers 20`: Uses 20 parallel transfers for faster download - - `--retries 6`: Automatically retries failed transfers up to 6 times - - `--retries-sleep 10s`: Waits 10 seconds between retry attempts - - `--size-only`: Only transfers if sizes differ (prevents unnecessary re-downloads) - - === "Pruned Node" - - Pruned node setup keeps recent state for smaller storage. Download both parachain pruned and relay chain pruned snapshots: - - **Parachain pruned snapshot** (People Chain example): - ```bash - # Check https://snapshots.polkadot.io/ for the latest snapshot URL - export SNAPSHOT_URL_PARACHAIN="https://snapshots.polkadot.io/polkadot-people-rocksdb-prune/LATEST" - - rclone copyurl $SNAPSHOT_URL_PARACHAIN/files.txt files.txt - rclone copy --progress --transfers 20 \ - --http-url $SNAPSHOT_URL_PARACHAIN \ - --no-traverse --http-no-head --disable-http2 \ - --inplace --no-gzip-encoding --size-only \ - --retries 6 --retries-sleep 10s \ - --files-from files.txt :http: my-node-data/chains/people-polkadot/db/ - - rm files.txt - ``` - - **Relay chain pruned snapshot** (~200 GB): - ```bash - # Check https://snapshots.polkadot.io/ for the latest snapshot URL - export SNAPSHOT_URL_RELAY="https://snapshots.polkadot.io/polkadot-rocksdb-prune/LATEST" - - rclone copyurl $SNAPSHOT_URL_RELAY/files.txt files.txt - rclone copy --progress --transfers 20 \ - --http-url $SNAPSHOT_URL_RELAY \ - --no-traverse --http-no-head --disable-http2 \ - --inplace --no-gzip-encoding --size-only \ - --retries 6 --retries-sleep 10s \ - --files-from files.txt :http: my-node-data/chains/polkadot/db/ - - rm files.txt - ``` - - **rclone parameters:** - - - `--transfers 20`: Uses 20 parallel transfers for faster download - - `--retries 6`: Automatically retries failed transfers up to 6 times - - `--retries-sleep 10s`: Waits 10 seconds between retry attempts - - `--size-only`: Only transfers if sizes differ (prevents unnecessary re-downloads) + 2. Download the snapshots: + + **Parachain archive snapshot** (People Chain example, ~71 GB): + ```bash + # Check https://snapshots.polkadot.io/ for the latest snapshot URL + export SNAPSHOT_URL_PARACHAIN="https://snapshots.polkadot.io/polkadot-people-rocksdb-archive/LATEST" + + rclone copyurl $SNAPSHOT_URL_PARACHAIN/files.txt files.txt + rclone copy --progress --transfers 20 \ + --http-url $SNAPSHOT_URL_PARACHAIN \ + --no-traverse --http-no-head --disable-http2 \ + --inplace --no-gzip-encoding --size-only \ + --retries 6 --retries-sleep 10s \ + --files-from files.txt :http: my-node-data/chains/people-polkadot/db/ + + rm files.txt + ``` + + **Relay chain pruned snapshot** (~822 GB): + ```bash + # Check https://snapshots.polkadot.io/ for the latest snapshot URL + export SNAPSHOT_URL_RELAY="https://snapshots.polkadot.io/polkadot-paritydb-prune/LATEST" + + rclone copyurl $SNAPSHOT_URL_RELAY/files.txt files.txt + rclone copy --progress --transfers 20 \ + --http-url $SNAPSHOT_URL_RELAY \ + --no-traverse --http-no-head --disable-http2 \ + --inplace --no-gzip-encoding --size-only \ + --retries 6 --retries-sleep 10s \ + --files-from files.txt :http: my-node-data/chains/polkadot/db/ + + rm files.txt + ``` + + **rclone parameters:** + + - `--transfers 20`: Uses 20 parallel transfers for faster download + - `--retries 6`: Automatically retries failed transfers up to 6 times + - `--retries-sleep 10s`: Waits 10 seconds between retry attempts + - `--size-only`: Only transfers if sizes differ (prevents unnecessary re-downloads) 3. Launch the parachain node using the official [Parity Docker image](https://hub.docker.com/r/parity/polkadot-parachain){target=\_blank}: diff --git a/.ai/pages/node-infrastructure-run-a-node-polkadot-hub-rpc.md b/.ai/pages/node-infrastructure-run-a-node-polkadot-hub-rpc.md index 419f0a1ab..8c2c946d9 100644 --- a/.ai/pages/node-infrastructure-run-a-node-polkadot-hub-rpc.md +++ b/.ai/pages/node-infrastructure-run-a-node-polkadot-hub-rpc.md @@ -34,8 +34,8 @@ RPC nodes serving production traffic require robust hardware. The following shou - **CPU**: 8+ cores (16+ cores for high traffic) - **Memory**: 64 GB RAM minimum (128 GB recommended for high traffic) - **Storage**: - - 500 GB+ NVMe SSD for parachain state (archive nodes require 600-800 GB+) - - Additional 200+ GB for relay chain pruned database + - Archive node: ~1.2 TB NVMe SSD total (~392 GB for Asset Hub archive + ~822 GB for relay chain pruned snapshot) + - Pruned node: 200+ GB NVMe SSD (with pruning enabled for both parachain and relay chain) - Fast disk I/O is critical for query performance - **Network**: - Public IP address @@ -88,93 +88,46 @@ Select the best option for your project, then use the steps in the following tab mkdir -p my-node-data/chains/asset-hub-polkadot/db mkdir -p my-node-data/chains/polkadot/db ``` - 2. Download the appropriate snapshots using the following commands: - - === "Archive Node" - - Archive node setup maintains complete parachain history (~600-800 GB total). Download both Asset Hub archive and Relay chain pruned snapshots: - - **Asset Hub archive snapshot** (~400 GB): - ```bash - # Check https://snapshots.polkadot.io/ for the latest snapshot URL - export SNAPSHOT_URL_ASSET_HUB="https://snapshots.polkadot.io/polkadot-asset-hub-rocksdb-archive/LATEST" - - rclone copyurl $SNAPSHOT_URL_ASSET_HUB/files.txt files.txt - rclone copy --progress --transfers 20 \ - --http-url $SNAPSHOT_URL_ASSET_HUB \ - --no-traverse --http-no-head --disable-http2 \ - --inplace --no-gzip-encoding --size-only \ - --retries 6 --retries-sleep 10s \ - --files-from files.txt :http: my-node-data/chains/asset-hub-polkadot/db/ - - rm files.txt - ``` - - **Relay chain pruned snapshot** (~200 GB): - ```bash - # Check https://snapshots.polkadot.io/ for the latest snapshot URL - export SNAPSHOT_URL_RELAY="https://snapshots.polkadot.io/polkadot-rocksdb-prune/LATEST" - - rclone copyurl $SNAPSHOT_URL_RELAY/files.txt files.txt - rclone copy --progress --transfers 20 \ - --http-url $SNAPSHOT_URL_RELAY \ - --no-traverse --http-no-head --disable-http2 \ - --inplace --no-gzip-encoding --size-only \ - --retries 6 --retries-sleep 10s \ - --files-from files.txt :http: my-node-data/chains/polkadot/db/ - - rm files.txt - ``` - - **rclone parameters:** - - - `--transfers 20`: Uses 20 parallel transfers for faster download - - `--retries 6`: Automatically retries failed transfers up to 6 times - - `--retries-sleep 10s`: Waits 10 seconds between retry attempts - - `--size-only`: Only transfers if sizes differ (prevents unnecessary re-downloads) - - === "Pruned Node" - - Pruned node setup keeps recent state for smaller storage (~500 GB total). Download both Asset Hub pruned and Relay chain pruned snapshots: - - **Asset Hub pruned snapshot**: - ```bash - # Check https://snapshots.polkadot.io/ for the latest snapshot URL - export SNAPSHOT_URL_ASSET_HUB="https://snapshots.polkadot.io/polkadot-asset-hub-rocksdb-prune/LATEST" - - rclone copyurl $SNAPSHOT_URL_ASSET_HUB/files.txt files.txt - rclone copy --progress --transfers 20 \ - --http-url $SNAPSHOT_URL_ASSET_HUB \ - --no-traverse --http-no-head --disable-http2 \ - --inplace --no-gzip-encoding --size-only \ - --retries 6 --retries-sleep 10s \ - --files-from files.txt :http: my-node-data/chains/asset-hub-polkadot/db/ - - rm files.txt - ``` - - **Relay chain pruned snapshot** (~200 GB): - ```bash - # Check https://snapshots.polkadot.io/ for the latest snapshot URL - export SNAPSHOT_URL_RELAY="https://snapshots.polkadot.io/polkadot-rocksdb-prune/LATEST" - - rclone copyurl $SNAPSHOT_URL_RELAY/files.txt files.txt - rclone copy --progress --transfers 20 \ - --http-url $SNAPSHOT_URL_RELAY \ - --no-traverse --http-no-head --disable-http2 \ - --inplace --no-gzip-encoding --size-only \ - --retries 6 --retries-sleep 10s \ - --files-from files.txt :http: my-node-data/chains/polkadot/db/ - - rm files.txt - ``` - - **rclone parameters:** - - - `--transfers 20`: Uses 20 parallel transfers for faster download - - `--retries 6`: Automatically retries failed transfers up to 6 times - - `--retries-sleep 10s`: Waits 10 seconds between retry attempts - - `--size-only`: Only transfers if sizes differ (prevents unnecessary re-downloads) + 2. Download the snapshots (~1.2 TB total): + + **Asset Hub archive snapshot** (~392 GB): + ```bash + # Check https://snapshots.polkadot.io/ for the latest snapshot URL + export SNAPSHOT_URL_ASSET_HUB="https://snapshots.polkadot.io/polkadot-asset-hub-paritydb-archive/LATEST" + + rclone copyurl $SNAPSHOT_URL_ASSET_HUB/files.txt files.txt + rclone copy --progress --transfers 20 \ + --http-url $SNAPSHOT_URL_ASSET_HUB \ + --no-traverse --http-no-head --disable-http2 \ + --inplace --no-gzip-encoding --size-only \ + --retries 6 --retries-sleep 10s \ + --files-from files.txt :http: my-node-data/chains/asset-hub-polkadot/db/ + + rm files.txt + ``` + + **Relay chain pruned snapshot** (~822 GB): + ```bash + # Check https://snapshots.polkadot.io/ for the latest snapshot URL + export SNAPSHOT_URL_RELAY="https://snapshots.polkadot.io/polkadot-paritydb-prune/LATEST" + + rclone copyurl $SNAPSHOT_URL_RELAY/files.txt files.txt + rclone copy --progress --transfers 20 \ + --http-url $SNAPSHOT_URL_RELAY \ + --no-traverse --http-no-head --disable-http2 \ + --inplace --no-gzip-encoding --size-only \ + --retries 6 --retries-sleep 10s \ + --files-from files.txt :http: my-node-data/chains/polkadot/db/ + + rm files.txt + ``` + + **rclone parameters:** + + - `--transfers 20`: Uses 20 parallel transfers for faster download + - `--retries 6`: Automatically retries failed transfers up to 6 times + - `--retries-sleep 10s`: Waits 10 seconds between retry attempts + - `--size-only`: Only transfers if sizes differ (prevents unnecessary re-downloads) 3. Launch Polkadot Hub Node using the official [Parity Docker image](https://hub.docker.com/r/parity/polkadot-parachain){target=\_blank}: === "Archive Node" From 1993fdb46fd255dcf3000c1585adae2189198f8c Mon Sep 17 00:00:00 2001 From: Erin Shaben Date: Tue, 9 Dec 2025 15:35:28 -0500 Subject: [PATCH 28/39] cleanup docs --- .ai/categories/basics.md | 2327 +----- .ai/categories/dapps.md | 3786 +--------- .ai/categories/infrastructure.md | 2633 +------ .ai/categories/networks.md | 2625 +------ .ai/categories/parachains.md | 2235 +----- .ai/categories/polkadot-protocol.md | 3235 +-------- .ai/categories/reference.md | 493 -- .ai/categories/smart-contracts.md | 2906 +------- .ai/categories/tooling.md | 6252 +++-------------- .ai/pages/smart-contracts-libraries-wagmi.md | 18 +- .ai/site-index.json | 2871 +------- .nav.yml | 2 +- .../run-a-node/bootnode/bootnode.conf | 0 .../run-a-node/full-node/run-node.html | 0 .../full-node/setup-full-node-1.html | 0 .../full-node/setup-full-node-2.html | 0 .../run-a-node/secure-wss/apache2-config.md | 0 .../run-a-node/secure-wss/install-apache2.md | 0 .../run-a-node/secure-wss/install-openssl.md | 0 .../run-a-node/secure-wss/nginx-config.md | 0 .../run-a-node/secure-wss/nginx-rate-limit.md | 0 .../key-management/node-key-error-01.html | 0 .../key-management/subkey-generate.html | 0 .../set-up-validator/terminal-output-01.html | 0 .../start-validating/terminal-output-01.html | 0 .../start-validating/terminal-output-02.html | 0 .../alertmanager-status.html | 0 .../general-management/alertmanager.yml | 0 .../general-management/grub-config-01.js | 0 .../general-management/instance-down.yml | 0 .../general-management/prometheus-config.yml | 0 .../systemd-alert-config.md | 0 .../general-management/systemd-config.md | 0 .../terminal-output-01.html | 0 .../general-management/update-prometheus.yml | 0 .../verify-session-change.md | 0 .../libraries/wagmi/BlockchainInfo.tsx | 4 +- .../libraries/wagmi/ConnectWallet.tsx | 4 +- .../smart-contracts/libraries/wagmi/page.tsx | 4 +- .../run-a-node/secure-wss/secure-wss-01.webp | Bin .../key-management/key-management-01.webp | Bin .../key-management/key-management-02.webp | Bin .../start-validating/start-validating-01.webp | Bin .../start-validating/start-validating-02.webp | Bin .../start-validating/start-validating-03.webp | Bin .../start-validating/start-validating-04.webp | Bin .../start-validating/start-validating-05.webp | Bin .../start-validating/start-validating-06.webp | Bin .../general-management-01.webp | Bin .../general-management-02.webp | Bin .../general-management-03.webp | Bin .../general-management-04.webp | Bin .../general-management-05.webp | Bin llms-full.jsonl | 244 +- llms.txt | 79 +- node-infrastructure/.nav.yml | 4 +- node-infrastructure/{overview.md => index.md} | 46 +- .../collator.md => run-a-collator.md} | 32 +- node-infrastructure/run-a-collator/.nav.yml | 2 - .../run-a-node/parachain-rpc.md | 562 +- .../run-a-node/polkadot-hub-rpc.md | 475 +- .../run-a-node/relay-chain/bootnode.md | 2 +- .../run-a-node/relay-chain/full-node.md | 8 +- .../run-a-node/relay-chain/secure-wss.md | 12 +- .../key-management.md | 10 +- .../set-up-validator.md | 10 +- .../start-validating.md | 22 +- .../stop-validating.md | 2 +- .../operational-tasks/general-management.md | 38 +- .../operational-tasks/upgrade-your-node.md | 6 +- .../run-a-validator/requirements.md | 4 +- smart-contracts/libraries/wagmi.md | 6 +- 72 files changed, 2865 insertions(+), 28094 deletions(-) rename .snippets/code/{nodes-and-validators => node-infrastructure}/run-a-node/bootnode/bootnode.conf (100%) rename .snippets/code/{nodes-and-validators => node-infrastructure}/run-a-node/full-node/run-node.html (100%) rename .snippets/code/{nodes-and-validators => node-infrastructure}/run-a-node/full-node/setup-full-node-1.html (100%) rename .snippets/code/{nodes-and-validators => node-infrastructure}/run-a-node/full-node/setup-full-node-2.html (100%) rename .snippets/code/{nodes-and-validators => node-infrastructure}/run-a-node/secure-wss/apache2-config.md (100%) rename .snippets/code/{nodes-and-validators => node-infrastructure}/run-a-node/secure-wss/install-apache2.md (100%) rename .snippets/code/{nodes-and-validators => node-infrastructure}/run-a-node/secure-wss/install-openssl.md (100%) rename .snippets/code/{nodes-and-validators => node-infrastructure}/run-a-node/secure-wss/nginx-config.md (100%) rename .snippets/code/{nodes-and-validators => node-infrastructure}/run-a-node/secure-wss/nginx-rate-limit.md (100%) rename .snippets/code/{nodes-and-validators => node-infrastructure}/run-a-validator/onboarding-and-offboarding/key-management/node-key-error-01.html (100%) rename .snippets/code/{nodes-and-validators => node-infrastructure}/run-a-validator/onboarding-and-offboarding/key-management/subkey-generate.html (100%) rename .snippets/code/{nodes-and-validators => node-infrastructure}/run-a-validator/onboarding-and-offboarding/set-up-validator/terminal-output-01.html (100%) rename .snippets/code/{nodes-and-validators => node-infrastructure}/run-a-validator/onboarding-and-offboarding/start-validating/terminal-output-01.html (100%) rename .snippets/code/{nodes-and-validators => node-infrastructure}/run-a-validator/onboarding-and-offboarding/start-validating/terminal-output-02.html (100%) rename .snippets/code/{nodes-and-validators => node-infrastructure}/run-a-validator/operational-tasks/general-management/alertmanager-status.html (100%) rename .snippets/code/{nodes-and-validators => node-infrastructure}/run-a-validator/operational-tasks/general-management/alertmanager.yml (100%) rename .snippets/code/{nodes-and-validators => node-infrastructure}/run-a-validator/operational-tasks/general-management/grub-config-01.js (100%) rename .snippets/code/{nodes-and-validators => node-infrastructure}/run-a-validator/operational-tasks/general-management/instance-down.yml (100%) rename .snippets/code/{nodes-and-validators => node-infrastructure}/run-a-validator/operational-tasks/general-management/prometheus-config.yml (100%) rename .snippets/code/{nodes-and-validators => node-infrastructure}/run-a-validator/operational-tasks/general-management/systemd-alert-config.md (100%) rename .snippets/code/{nodes-and-validators => node-infrastructure}/run-a-validator/operational-tasks/general-management/systemd-config.md (100%) rename .snippets/code/{nodes-and-validators => node-infrastructure}/run-a-validator/operational-tasks/general-management/terminal-output-01.html (100%) rename .snippets/code/{nodes-and-validators => node-infrastructure}/run-a-validator/operational-tasks/general-management/update-prometheus.yml (100%) rename .snippets/code/{nodes-and-validators => node-infrastructure}/run-a-validator/operational-tasks/upgrade-your-node/verify-session-change.md (100%) rename images/{nodes-and-validators => node-infrastructure}/run-a-node/secure-wss/secure-wss-01.webp (100%) rename images/{nodes-and-validators => node-infrastructure}/run-a-validator/onboarding-and-offboarding/key-management/key-management-01.webp (100%) rename images/{nodes-and-validators => node-infrastructure}/run-a-validator/onboarding-and-offboarding/key-management/key-management-02.webp (100%) rename images/{nodes-and-validators => node-infrastructure}/run-a-validator/onboarding-and-offboarding/start-validating/start-validating-01.webp (100%) rename images/{nodes-and-validators => node-infrastructure}/run-a-validator/onboarding-and-offboarding/start-validating/start-validating-02.webp (100%) rename images/{nodes-and-validators => node-infrastructure}/run-a-validator/onboarding-and-offboarding/start-validating/start-validating-03.webp (100%) rename images/{nodes-and-validators => node-infrastructure}/run-a-validator/onboarding-and-offboarding/start-validating/start-validating-04.webp (100%) rename images/{nodes-and-validators => node-infrastructure}/run-a-validator/onboarding-and-offboarding/start-validating/start-validating-05.webp (100%) rename images/{nodes-and-validators => node-infrastructure}/run-a-validator/onboarding-and-offboarding/start-validating/start-validating-06.webp (100%) rename images/{nodes-and-validators => node-infrastructure}/run-a-validator/operational-tasks/general-management/general-management-01.webp (100%) rename images/{nodes-and-validators => node-infrastructure}/run-a-validator/operational-tasks/general-management/general-management-02.webp (100%) rename images/{nodes-and-validators => node-infrastructure}/run-a-validator/operational-tasks/general-management/general-management-03.webp (100%) rename images/{nodes-and-validators => node-infrastructure}/run-a-validator/operational-tasks/general-management/general-management-04.webp (100%) rename images/{nodes-and-validators => node-infrastructure}/run-a-validator/operational-tasks/general-management/general-management-05.webp (100%) rename node-infrastructure/{overview.md => index.md} (69%) rename node-infrastructure/{run-a-collator/collator.md => run-a-collator.md} (94%) delete mode 100644 node-infrastructure/run-a-collator/.nav.yml diff --git a/.ai/categories/basics.md b/.ai/categories/basics.md index e97053967..3480712c2 100644 --- a/.ai/categories/basics.md +++ b/.ai/categories/basics.md @@ -1817,368 +1817,6 @@ To stop the node, press `Control-C` in the terminal. ---- - -Page Title: Interoperability - -- Source (raw): https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/reference-parachains-interoperability.md -- Canonical (HTML): https://docs.polkadot.com/reference/parachains/interoperability/ -- Summary: Explore the importance of interoperability in the Polkadot ecosystem, covering XCM, bridges, and cross-chain communication. - -# Interoperability - -## Introduction - -Interoperability lies at the heart of the Polkadot ecosystem, enabling communication and collaboration across a diverse range of blockchains. By bridging the gaps between parachains, relay chains, and even external networks, Polkadot unlocks the potential for truly decentralized applications, efficient resource sharing, and scalable solutions. - -Polkadot’s design ensures that blockchains can transcend their individual limitations by working together as part of a unified system. This cooperative architecture is what sets Polkadot apart in the blockchain landscape. - -## Why Interoperability Matters - -The blockchain ecosystem is inherently fragmented. Different blockchains excel in specialized domains such as finance, gaming, or supply chain management, but these chains function in isolation without interoperability. This lack of connectivity stifles the broader utility of blockchain technology. - -Interoperability solves this problem by enabling blockchains to: - -- **Collaborate across networks**: Chains can interact to share assets, functionality, and data, creating synergies that amplify their individual strengths. -- **Achieve greater scalability**: Specialized chains can offload tasks to others, optimizing performance and resource utilization. -- **Expand use-case potential**: Cross-chain applications can leverage features from multiple blockchains, unlocking novel user experiences and solutions. - -In the Polkadot ecosystem, interoperability transforms a collection of isolated chains into a cohesive, efficient network, pushing the boundaries of what blockchains can achieve together. - -## Key Mechanisms for Interoperability - -At the core of Polkadot's cross-chain collaboration are foundational technologies designed to break down barriers between networks. These mechanisms empower blockchains to communicate, share resources, and operate as a cohesive ecosystem. - -### Cross-Consensus Messaging (XCM): The Backbone of Communication - -Polkadot's Cross-Consensus Messaging (XCM) is the standard framework for interaction between parachains, relay chains, and, eventually, external blockchains. XCM provides a trustless, secure messaging format for exchanging assets, sharing data, and executing cross-chain operations. - -Through XCM, decentralized applications can: - -- Transfer tokens and other assets across chains. -- Coordinate complex workflows that span multiple blockchains. -- Enable seamless user experiences where underlying blockchain differences are invisible. -- XCM exemplifies Polkadot’s commitment to creating a robust and interoperable ecosystem. - -For further information about XCM, check the [Get Started with XCM](/parachains/interoperability/get-started/){target=\_blank} article. - -### Bridges: Connecting External Networks - -While XCM enables interoperability within the Polkadot ecosystem, bridges extend this functionality to external blockchains such as Ethereum and Bitcoin. By connecting these networks, bridges allow Polkadot-based chains to access external liquidity, additional functionalities, and broader user bases. - -With bridges, developers and users gain the ability to: - -- Integrate external assets into Polkadot-based applications. -- Combine the strengths of Polkadot’s scalability with the liquidity of other networks. -- Facilitate accurate multi-chain applications that transcend ecosystem boundaries. - -For more information about bridges in the Polkadot ecosystem, see the [Bridge Hub](/reference/polkadot-hub/bridging/){target=\_blank} guide. - -## The Polkadot Advantage - -Polkadot was purpose-built for interoperability. Unlike networks that add interoperability as an afterthought, Polkadot integrates it as a fundamental design principle. This approach offers several distinct advantages: - -- **Developer empowerment**: Polkadot’s interoperability tools allow developers to build applications that leverage multiple chains’ capabilities without added complexity. -- **Enhanced ecosystem collaboration**: Chains in Polkadot can focus on their unique strengths while contributing to the ecosystem’s overall growth. -- **Future-proofing blockchain**: By enabling seamless communication, Polkadot ensures its ecosystem can adapt to evolving demands and technologies. - -## Looking Ahead - -Polkadot’s vision of interoperability extends beyond technical functionality, representing a shift towards a more collaborative blockchain landscape. By enabling chains to work together, Polkadot fosters innovation, efficiency, and accessibility, paving the way for a decentralized future where blockchains are not isolated competitors but interconnected collaborators. - - ---- - -Page Title: Networks - -- Source (raw): https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/reference-parachains-networks.md -- Canonical (HTML): https://docs.polkadot.com/reference/parachains/networks/ -- Summary: Explore Polkadot's testing and production networks, including Westend, Kusama, and Paseo, for efficient development, deployment, and testing. - -# Networks - -## Introduction - -The Polkadot ecosystem is built on a robust set of networks designed to enable secure and scalable development. Whether you are testing new features or deploying to live production, Polkadot offers several layers of networks tailored for each stage of the development process. From local environments to experimental networks like Kusama and community-run TestNets such as Paseo, developers can thoroughly test, iterate, and validate their applications. This guide will introduce you to Polkadot's various networks and explain how they fit into the development workflow. - -## Network Overview - -Polkadot's development process is structured to ensure new features and upgrades are rigorously tested before being deployed on live production networks. The progression follows a well-defined path, starting from local environments and advancing through TestNets, ultimately reaching the Polkadot MainNet. The diagram below outlines the typical progression of the Polkadot development cycle: - -``` mermaid -flowchart LR - id1[Local] --> id2[Westend] --> id4[Kusama] --> id5[Polkadot] - id1[Local] --> id3[Paseo] --> id5[Polkadot] -``` - -This flow ensures developers can thoroughly test and iterate without risking real tokens or affecting production networks. Testing tools like [Chopsticks](#chopsticks) and various TestNets make it easier to experiment safely before releasing to production. - -A typical journey through the Polkadot core protocol development process might look like this: - -1. **Local development node**: Development starts in a local environment, where developers can create, test, and iterate on upgrades or new features using a local development node. This stage allows rapid experimentation in an isolated setup without any external dependencies. - -2. **Westend**: After testing locally, upgrades are deployed to [Westend](#westend), Polkadot's primary TestNet. Westend simulates real-world conditions without using real tokens, making it the ideal place for rigorous feature testing before moving on to production networks. - -3. **Kusama**: Once features have passed extensive testing on Westend, they move to Kusama, Polkadot's experimental and fast-moving "canary" network. Kusama operates as a high-fidelity testing ground with actual economic incentives, giving developers insights into how their features will perform in a real-world environment. - -4. **Polkadot**: After passing tests on Westend and Kusama, features are considered ready for deployment to Polkadot, the live production network. - - In addition, parachain developers can leverage local TestNets like [Zombienet](#zombienet) and deploy upgrades on parachain TestNets. - -5. **Paseo**: For parachain and dApp developers, Paseo serves as a community-run TestNet that mirrors Polkadot's runtime. Like Westend for core protocol development, Paseo provides a testing ground for parachain development without affecting live networks. - -!!!note - The Rococo TestNet deprecation date was October 14, 2024. Teams should use Westend for Polkadot protocol and feature testing and Paseo for chain development-related testing. - -## Polkadot Development Networks - -Development and testing are crucial to building robust dApps and parachains and performing network upgrades within the Polkadot ecosystem. To achieve this, developers can leverage various networks and tools that provide a risk-free environment for experimentation and validation before deploying features to live networks. These networks help avoid the costs and risks associated with real tokens, enabling testing for functionalities like governance, cross-chain messaging, and runtime upgrades. - -## Kusama Network - -Kusama is the experimental version of Polkadot, designed for developers who want to move quickly and test their applications in a real-world environment with economic incentives. Kusama serves as a production-grade testing ground where developers can deploy features and upgrades with the pressure of game theory and economics in mind. It mirrors Polkadot but operates as a more flexible space for innovation. - -The native token for Kusama is KSM. For more information about KSM, visit the [Native Assets](https://wiki.polkadot.com/kusama/kusama-getting-started/){target=\_blank} page. - -## Test Networks - -The following test networks provide controlled environments for testing upgrades and new features. TestNet tokens are available from the [Polkadot faucet](https://faucet.polkadot.io/){target=\_blank}. - -### Westend - -Westend is Polkadot's primary permanent TestNet. Unlike temporary test networks, Westend is not reset to the genesis block, making it an ongoing environment for testing Polkadot core features. Managed by Parity Technologies, Westend ensures that developers can test features in a real-world simulation without using actual tokens. - -The native token for Westend is WND. More details about WND can be found on the [Native Assets](https://wiki.polkadot.com/learn/learn-dot/#__tabbed_2_2){target=\_blank} page. - -### Paseo - -[Paseo](https://github.com/paseo-network){target=\_blank} is a community-managed TestNet designed for parachain and dApp developers. It mirrors Polkadot's runtime and is maintained by Polkadot community members. Paseo provides a dedicated space for parachain developers to test their applications in a Polkadot-like environment without the risks associated with live networks. - -The native token for Paseo is PAS. Additional information on PAS is available on the [Native Assets](https://wiki.polkadot.com/learn/learn-dot/#__tabbed_2_1){target=\_blank} page. - -## Local Test Networks - -Local test networks are an essential part of the development cycle for blockchain developers using the Polkadot SDK. They allow for fast, iterative testing in controlled, private environments without connecting to public TestNets. Developers can quickly spin up local instances to experiment, debug, and validate their code before deploying to larger TestNets like Westend or Paseo. Two key tools for local network testing are Zombienet and Chopsticks. - -### Zombienet - -[Zombienet](https://github.com/paritytech/zombienet){target=\_blank} is a flexible testing framework for Polkadot SDK-based blockchains. It enables developers to create and manage ephemeral, short-lived networks. This feature makes Zombienet particularly useful for quick iterations, as it allows you to run multiple local networks concurrently, mimicking different runtime conditions. Whether you're developing a parachain or testing your custom blockchain logic, Zombienet gives you the tools to automate local testing. - -Key features of Zombienet include: - -- Creating dynamic, local networks with different configurations. -- Running parachains and relay chains in a simulated environment. -- Efficient testing of network components like cross-chain messaging and governance. - -Zombienet is ideal for developers looking to test quickly and thoroughly before moving to more resource-intensive public TestNets. - -### Chopsticks - -[Chopsticks](https://github.com/AcalaNetwork/chopsticks){target=\_blank} is a tool designed to create forks of Polkadot SDK-based blockchains, allowing developers to interact with network forks as part of their testing process. This capability makes Chopsticks a powerful option for testing upgrades, runtime changes, or cross-chain applications in a forked network environment. - -Key features of Chopsticks include: - -- Forking live Polkadot SDK-based blockchains for isolated testing. -- Simulating cross-chain messages in a private, controlled setup. -- Debugging network behavior by interacting with the fork in real-time. - -Chopsticks provides a controlled environment for developers to safely explore the effects of runtime changes. It ensures that network behavior is tested and verified before upgrades are deployed to live networks. - - ---- - -Page Title: Node and Runtime - -- Source (raw): https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/reference-parachains-node-and-runtime.md -- Canonical (HTML): https://docs.polkadot.com/reference/parachains/node-and-runtime/ -- Summary: Learn how Polkadot SDK-based nodes function, how the client and runtime are separated, and how they communicate using SCALE-encoded data. - -# Node and Runtime - -## Introduction - -Every blockchain platform relies on a decentralized network of computers, called nodes, that communicate with each other about transactions and blocks. In this context, a node refers to the software running on the connected devices rather than the physical or virtual machines in the network. - -Polkadot SDK-based nodes consist of two main components, each with distinct responsibilities: the client (also called node) and the runtime. - -If the system were a monolithic protocol, any modification would require updating the entire system. Instead, Polkadot achieves true upgradeability by defining an immutable meta-protocol (the client) and a protocol (the runtime) that can be upgraded independently. - -This separation gives the [Polkadot Relay Chain](/polkadot-protocol/architecture/polkadot-chain){target=\_blank} and all connected [parachains](/polkadot-protocol/architecture/parachains){target=\_blank} an evolutionary advantage over other blockchain platforms. - -## Architectural Principles - -The Polkadot SDK-based blockchain architecture is fundamentally built on two distinct yet interconnected components: - -- Client (Meta-protocol): - - Handles the foundational infrastructure of the blockchain. - - Manages runtime execution, networking, consensus, and other off-chain components. - - Provides an immutable base layer that ensures network stability. - - Upgradable only through hard forks. - -- Runtime (Protocol): - - Defines the blockchain's state transition logic. - - Determines the specific rules and behaviors of the blockchain. - - Compiled to WebAssembly (Wasm) for platform-independent execution. - - Capable of being upgraded without network-wide forking. - -### Advantages of this Architecture - -- **Forkless upgrades**: Runtime can be updated without disrupting the entire network. -- **Modularity**: Clear separation allows independent development of client and runtime. -- **Flexibility**: Enables rapid iteration and evolution of blockchain logic. -- **Performance**: WebAssembly compilation provides efficient, cross-platform execution. - -## Node (Client) - -The node, also known as the client, is the core component responsible for executing the Wasm runtime and orchestrating various essential blockchain components. It ensures the correct execution of the state transition function and manages multiple critical subsystems, including: - -- **Wasm execution**: Runs the blockchain runtime, which defines the state transition rules. -- **Database management**: Stores blockchain data. -- **Networking**: Facilitates peer-to-peer communication, block propagation, and transaction gossiping. -- **Transaction pool (Mempool)**: Manages pending transactions before they are included in a block. -- **Consensus mechanism**: Ensures agreement on the blockchain state across nodes. -- **RPC services**: Provides external interfaces for applications and users to interact with the node. - -## Runtime - -The runtime is more than just a set of rules. It's the fundamental logic engine that defines a blockchain's entire behavior. In Polkadot SDK-based blockchains, the runtime represents a complete, self-contained description of the blockchain's state transition function. - -### Characteristics - -The runtime is distinguished by three key characteristics: - -- **Business logic**: Defines the complete application-specific blockchain behavior. -- **WebAssembly compilation**: Ensures platform-independent, secure execution. -- **On-chain storage**: Stored within the blockchain's state, allowing dynamic updates. - -### Key Functions - -The runtime performs several critical functions, such as: - -- Define state transition rules. -- Implement blockchain-specific logic. -- Manage account interactions. -- Control transaction processing. -- Define governance mechanisms. -- Handle custom pallets and modules. - -## Communication Between Node and Runtime - -The client and runtime communicate exclusively using [SCALE-encoded](/polkadot-protocol/parachain-basics/data-encoding){target=\_blank} communication. This ensures efficient and compact data exchange between the two components. - -### Runtime APIs - -The Runtime API consists of well-defined functions and constants a client assumes are implemented in the Runtime Wasm blob. These APIs enable the client to interact with the runtime to execute blockchain operations and retrieve information. The client invokes these APIs to: - -- Build, execute, and finalize blocks. -- Access metadata. -- Access consensus related information. -- Handle transaction execution. - -### Host Functions - -During execution, the runtime can access certain external client functionalities via host functions. The specific functions the client exposes allow the runtime to perform operations outside the WebAssembly domain. Host functions enable the runtime to: - -- Perform cryptographic operations. -- Access the current blockchain state. -- Handle storage modifications. -- Allocate memory. - - ---- - -Page Title: On-Chain Governance Overview - -- Source (raw): https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/reference-governance.md -- Canonical (HTML): https://docs.polkadot.com/reference/governance/ -- Summary: Discover Polkadot’s cutting-edge OpenGov system, enabling transparent, decentralized decision-making through direct democracy and flexible governance tracks. - -# On-Chain Governance - -## Introduction - -Polkadot’s governance system exemplifies decentralized decision-making, empowering its community of stakeholders to shape the network’s future through active participation. The latest evolution, OpenGov, builds on Polkadot’s foundation by providing a more inclusive and efficient governance model. - -This guide will explain the principles and structure of OpenGov and walk you through its key components, such as Origins, Tracks, and Delegation. You will learn about improvements over earlier governance systems, including streamlined voting processes and enhanced stakeholder participation. - -With OpenGov, Polkadot achieves a flexible, scalable, and democratic governance framework that allows multiple proposals to proceed simultaneously, ensuring the network evolves in alignment with its community's needs. - -## Governance Evolution - -Polkadot’s governance journey began with [Governance V1](https://wiki.polkadot.com/learn/learn-polkadot-opengov/#governance-summary){target=\_blank}, a system that proved effective in managing treasury funds and protocol upgrades. However, it faced limitations, such as: - -- Slow voting cycles, causing delays in decision-making. -- Inflexibility in handling multiple referendums, restricting scalability. - -To address these challenges, Polkadot introduced OpenGov, a governance model designed for greater inclusivity, efficiency, and scalability. OpenGov replaces the centralized structures of Governance V1, such as the Council and Technical Committee, with a fully decentralized and dynamic framework. - -For a full comparison of the historic and current governance models, visit the [Gov1 vs. Polkadot OpenGov](https://wiki.polkadot.com/learn/learn-polkadot-opengov/#gov1-vs-polkadot-opengov){target=\_blank} section of the Polkadot Wiki. - -## OpenGov Key Features - -OpenGov transforms Polkadot’s governance into a decentralized, stakeholder-driven model, eliminating centralized decision-making bodies like the Council. Key enhancements include: - -- **Decentralization**: Shifts all decision-making power to the public, ensuring a more democratic process. -- **Enhanced delegation**: Allows users to delegate their votes to trusted experts across specific governance tracks. -- **Simultaneous referendums**: Multiple proposals can progress at once, enabling faster decision-making. -- **Polkadot Technical Fellowship**: A broad, community-driven group replacing the centralized Technical Committee. - -This new system ensures Polkadot governance remains agile and inclusive, even as the ecosystem grows. - -## Origins and Tracks - -In OpenGov, origins and tracks are central to managing proposals and votes. - -- **Origin**: Determines the authority level of a proposal (e.g., Treasury, Root) which decides the track of all referendums from that origin. -- **Track**: Define the procedural flow of a proposal, such as voting duration, approval thresholds, and enactment timelines. - -Developers must be aware that referendums from different origins and tracks will take varying amounts of time to reach approval and enactment. The [Polkadot Technical Fellowship](https://wiki.polkadot.com/learn/learn-polkadot-technical-fellowship/){target=\_blank} has the option to shorten this timeline by whitelisting a proposal and allowing it to be enacted through the [Whitelist Caller](https://wiki.polkadot.com/learn/learn-polkadot-opengov-origins/#whitelisted-caller){target=\_blank} origin. - -Visit [Origins and Tracks Info](https://wiki.polkadot.com/learn/learn-polkadot-opengov/#origins-and-tracks){target=\_blank} for details on current origins and tracks, associated terminology, and parameters. - -## Referendums - -In OpenGov, anyone can submit a referendum, fostering an open and participatory system. The timeline for a referendum depends on the privilege level of the origin with more significant changes offering more time for community voting and participation before enactment. - -The timeline for an individual referendum includes four distinct periods: - -- **Lead-in**: A minimum amount of time to allow for community participation, available room in the origin, and payment of the decision deposit. Voting is open during this period. -- **Decision**: Voting continues. -- **Confirmation**: Referendum must meet [approval and support](https://wiki.polkadot.com/learn/learn-polkadot-opengov/#approval-and-support){target=\_blank} criteria during entire period to avoid rejection. -- **Enactment**: Changes approved by the referendum are executed. - -### Vote on Referendums - -Voters can vote with their tokens on each referendum. Polkadot uses a voluntary token locking mechanism, called conviction voting, as a way for voters to increase their voting power. A token holder signals they have a stronger preference for approving a proposal based upon their willingness to lock up tokens. Longer voluntary token locks are seen as a signal of continual approval and translate to increased voting weight. - -See [Voting on a Referendum](https://wiki.polkadot.com/learn/learn-polkadot-opengov/#voting-on-a-referendum){target=\_blank} for a deeper look at conviction voting and related token locks. - -### Delegate Voting Power - -The OpenGov system also supports multi-role delegations, allowing token holders to assign their voting power on different tracks to entities with expertise in those areas. - -For example, if a token holder lacks the technical knowledge to evaluate proposals on the [Root track](https://wiki.polkadot.com/learn/learn-polkadot-opengov-origins/#root){target=\_blank}, they can delegate their voting power for that track to an expert they trust to vote in the best interest of the network. This ensures informed decision-making across tracks while maintaining flexibility for token holders. - -Visit [Multirole Delegation](https://wiki.polkadot.com/learn/learn-polkadot-opengov/#multirole-delegation){target=\_blank} for more details on delegating voting power. - -### Cancel a Referendum - -Polkadot OpenGov has two origins for rejecting ongoing referendums: - -- [**Referendum Canceller**](https://wiki.polkadot.com/learn/learn-polkadot-opengov-origins/#referendum-canceller){target=\_blank}: Cancels an active referendum when non-malicious errors occur and refunds the deposits to the originators. -- [**Referendum Killer**](https://wiki.polkadot.com/learn/learn-polkadot-opengov-origins/#referendum-killer){target=\_blank}: Used for urgent, malicious cases this origin instantly terminates an active referendum and slashes deposits. - -See [Cancelling, Killing, and Blacklisting](https://wiki.polkadot.com/learn/learn-polkadot-opengov/#cancelling-killing--blacklisting){target=\_blank} for additional information on rejecting referendums. - -## Additional Resources - -- **[Democracy pallet](https://github.com/paritytech/polkadot-sdk/tree/polkadot-stable2506-2/substrate/frame/democracy/src){target=\_blank}**: Handles administration of general stakeholder voting. -- **[Gov2: Polkadot’s Next Generation of Decentralised Governance](https://medium.com/polkadot-network/gov2-polkadots-next-generation-of-decentralised-governance-4d9ef657d11b){target=\_blank}**: Medium article by Gavin Wood. -- **[Polkadot Direction](https://matrix.to/#/#Polkadot-Direction:parity.io){target=\_blank}**: Matrix Element client. -- **[Polkassembly](https://polkadot.polkassembly.io/){target=\_blank}**: OpenGov dashboard and UI. -- **[Polkadot.js Apps Governance](https://polkadot.js.org/apps/#/referenda){target=\_blank}**: Overview of active referendums. - - --- Page Title: Overview of FRAME @@ -2317,974 +1955,152 @@ This section covers the most common customization patterns you'll encounter: --- -Page Title: Overview of the Polkadot Relay Chain +Page Title: Set Up the Polkadot SDK Parachain Template -- Source (raw): https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/reference-polkadot-hub-consensus-and-security-relay-chain.md -- Canonical (HTML): https://docs.polkadot.com/reference/polkadot-hub/consensus-and-security/relay-chain/ -- Summary: Explore Polkadot's core architecture, including its multi-chain vision, shared security, and the DOT token's governance and staking roles. +- Source (raw): https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/parachains-launch-a-parachain-set-up-the-parachain-template.md +- Canonical (HTML): https://docs.polkadot.com/parachains/launch-a-parachain/set-up-the-parachain-template/ +- Summary: Learn how to set up and run the Polkadot SDK Parachain Template locally, creating a ready-to-customize foundation for your parachain. -# Overview +# Set Up the Polkadot SDK Parachain Template ## Introduction -Polkadot is a next-generation blockchain protocol designed to support a multi-chain future by enabling secure communication and interoperability between different blockchains. Built as a Layer-0 protocol, Polkadot introduces innovations like application-specific Layer-1 chains ([parachains](/polkadot-protocol/architecture/parachains/){targe=\_blank}), shared security through [Nominated Proof of Stake (NPoS)](/reference/glossary/#nominated-proof-of-stake-npos){target=\_blank}, and cross-chain interactions via its native [Cross-Consensus Messaging Format (XCM)](/parachains/interoperability/get-started/){target=\_blank}. +The [Polkadot SDK](https://github.com/paritytech/polkadot-sdk){target=\_blank} includes several [templates](/parachains/customize-runtime/#starting-templates){target=\_blank} designed to help you quickly start building your own blockchain. Each template offers a different level of configuration, from minimal setups to feature-rich environments, allowing you to choose the foundation that best fits your project's needs. -This guide covers key aspects of Polkadot’s architecture, including its high-level protocol structure, blockspace commoditization, and the role of its native token, DOT, in governance, staking, and resource allocation. +Among these, the [Parachain Template](https://github.com/paritytech/polkadot-sdk-parachain-template){target=\_blank} provides a preconfigured runtime with commonly used pallets, making it an ideal starting point for most parachain development projects. -## Polkadot 1.0 +This guide walks you through the full process of working with this template. You will: -Polkadot 1.0 represents the state of Polkadot as of 2023, coinciding with the release of [Polkadot runtime v1.0.0](https://github.com/paritytech/polkadot/releases/tag/v1.0.0){target=\_blank}. This section will focus on Polkadot 1.0, along with philosophical insights into network resilience and blockspace. +- Set up the Polkadot SDK Parachain Template. +- Understand the project structure and key components. +- Verify your template is ready for development. +- Run the parachain template locally in development mode. -As a Layer-0 blockchain, Polkadot contributes to the multi-chain vision through several key innovations and initiatives, including: +By the end of this guide, you'll have a working template ready to customize and deploy as a parachain. -- **Application-specific Layer-1 blockchains (parachains)**: Polkadot's sharded network allows for parallel transaction processing, with shards that can have unique state transition functions, enabling custom-built L1 chains optimized for specific applications. +## Prerequisites -- **Shared security and scalability**: L1 chains connected to Polkadot benefit from its [Nominated Proof of Stake (NPoS)](/reference/polkadot-hub/consensus-and-security/pos-consensus/#nominated-proof-of-stake){target=\_blank} system, providing security out-of-the-box without the need to bootstrap their own. +Before getting started, ensure you have done the following: -- **Secure interoperability**: Polkadot's native interoperability enables seamless data and value exchange between parachains. This interoperability can also be used outside of the ecosystem for bridging with external networks. +- Completed the [Install Polkadot SDK](/parachains/install-polkadot-sdk/){target=\_blank} guide and successfully installed [Rust](https://www.rust-lang.org/){target=\_blank} and the required packages to set up your development environment. -- **Resilient infrastructure**: Decentralized and scalable, Polkadot ensures ongoing support for development and community initiatives via its on-chain [treasury](https://wiki.polkadot.com/learn/learn-polkadot-opengov-treasury/){target=\_blank} and governance. +For this tutorial series, you need to use Rust `1.86`. Newer versions of the compiler may not work with this parachain template version. -- **Rapid L1 development**: The [Polkadot SDK](/reference/parachains/){target=\_blank} allows fast, flexible creation and deployment of Layer-1 chains. +Run the following commands to set up the correct Rust version: -- **Cultivating the next generation of Web3 developers**: Polkadot supports the growth of Web3 core developers through initiatives such as. +=== "macOS" - - [Polkadot Blockchain Academy](https://polkadot.com/blockchain-academy){target=\_blank} - - [EdX courses](https://www.edx.org/school/web3x){target=\_blank} - - Rust and Substrate courses (coming soon) + ```bash + rustup install 1.86 + rustup default 1.86 + rustup target add wasm32-unknown-unknown --toolchain 1.86-aarch64-apple-darwin + rustup component add rust-src --toolchain 1.86-aarch64-apple-darwin + ``` -### High-Level Architecture +=== "Ubuntu" -Polkadot features a chain that serves as the central component of the system. This chain is depicted as a ring encircled by several parachains that are connected to it. + ```bash + rustup toolchain install 1.86.0 + rustup default 1.86.0 + rustup target add wasm32-unknown-unknown --toolchain 1.86.0 + rustup component add rust-src --toolchain 1.86.0 + ``` -According to Polkadot's design, any blockchain that can compile to WebAssembly (Wasm) and adheres to the Parachains Protocol becomes a parachain on the Polkadot network. +## Polkadot SDK Utility Tools -Here’s a high-level overview of the Polkadot protocol architecture: +This tutorial requires two essential tools: -![](/images/reference/polkadot-hub/consensus-and-security/relay-chain/relay-chain-01.webp){ style="background:white" } +- [**Chain spec builder**](https://crates.io/crates/staging-chain-spec-builder/10.0.0){target=\_blank}: A Polkadot SDK utility for generating chain specifications. Refer to the [Generate Chain Specs](/parachains/launch-a-parachain/deploy-to-polkadot/#generate-the-chain-specification){target=\_blank} documentation for detailed usage. + + Install it by executing the following command: + + ```bash + cargo install --locked staging-chain-spec-builder@10.0.0 + ``` -Parachains propose blocks to Polkadot validators, who check for availability and validity before finalizing them. With the relay chain providing security, collators—full nodes of parachains—can focus on their tasks without needing strong incentives. + This command installs the `chain-spec-builder` binary. -The [Cross-Consensus Messaging Format (XCM)](/parachains/interoperability/get-started/){target=\_blank} allows parachains to exchange messages freely, leveraging the chain's security for trust-free communication. +- [**Polkadot Omni Node**](https://crates.io/crates/polkadot-omni-node/0.5.0){target=\_blank}: A white-labeled binary, released as a part of Polkadot SDK that can act as the collator of a parachain in production, with all the related auxiliary functionalities that a normal collator node has: RPC server, archiving state, etc. Moreover, it can also run the Wasm blob of the parachain locally for testing and development. -In order to interact with chains that want to use their own finalization process (e.g., Bitcoin), Polkadot has [bridges](/reference/parachains/interoperability/#bridges-connecting-external-networks){target=\_blank} that offer two-way compatibility, meaning that transactions can be made between different parachains. + To install it, run the following command: -### Polkadot's Additional Functionalities + ```bash + cargo install --locked polkadot-omni-node@0.5.0 + ``` -Historically, obtaining core slots on Polkadot chain relied upon crowdloans and auctions. Chain cores were leased through auctions for three-month periods, up to a maximum of two years. Crowdloans enabled users to securely lend funds to teams for lease deposits in exchange for pre-sale tokens, which is the only way to access slots on Polkadot 1.0. Auctions are now deprecated in favor of [coretime](/polkadot-protocol/architecture/system-chains/coretime/){target=\_blank}. + This command installs the `polkadot-omni-node` binary. -Additionally, the chain handles [staking](https://wiki.polkadot.com/learn/learn-staking/){target=\_blank}, [accounts](/reference/parachains/accounts/){target=\_blank}, balances, and [governance](/reference/governance/){target=\_blank}. +## Clone the Template -#### Agile Coretime +The [Polkadot SDK Parachain Template](https://github.com/paritytech/polkadot-sdk-parachain-template){target=\_blank} provides a ready-to-use development environment for building with the [Polkadot SDK](https://github.com/paritytech/polkadot-sdk){target=\_blank}. Follow these steps to set up the template: -The new and more efficient way of obtaining core on Polkadot is to go through the process of purchasing coretime. +1. Clone the template repository: -[Agile coretime](/reference/polkadot-hub/consensus-and-security/agile-coretime/){target=\_blank} improves the efficient use of Polkadot's network resources and offers economic flexibility for developers, extending Polkadot's capabilities far beyond the original vision outlined in the [whitepaper](https://polkadot.com/papers/Polkadot-whitepaper.pdf){target=\_blank}. + ```bash + git clone https://github.com/paritytech/polkadot-sdk-parachain-template.git parachain-template + ``` -It enables parachains to purchase monthly "bulk" allocations of coretime (the time allocated for utilizing a core, measured in Polkadot relay chain blocks), ensuring heavy-duty parachains that can author a block every six seconds with [Asynchronous Backing](https://wiki.polkadot.com/learn/learn-async-backing/#asynchronous-backing){target=\_blank} can reliably renew their coretime each month. Although six-second block times are now the default, parachains have the option of producing blocks less frequently. +2. Navigate into the project directory: -Renewal orders are prioritized over new orders, offering stability against price fluctuations and helping parachains budget more effectively for project costs. + ```bash + cd parachain-template + ``` -### Polkadot's Resilience +## Explore the Project Structure -Decentralization is a vital component of blockchain networks, but it comes with trade-offs: +Before building the template, take a moment to familiarize yourself with its structure. Understanding this organization will help you navigate the codebase as you develop your parachain. -- An overly decentralized network may face challenges in reaching consensus and require significant energy to operate. -- Also, a network that achieves consensus quickly risks centralization, making it easier to manipulate or attack. +The template follows a standard Polkadot SDK project layout: -A network should be decentralized enough to prevent manipulative or malicious influence. In this sense, decentralization is a tool for achieving resilience. +```text +parachain-template/ +├── node/ # Node implementation and client +├── pallets/ # Custom pallets for your parachain +├── runtime/ # Runtime configuration and logic +├── Cargo.toml # Workspace configuration +└── README.md # Documentation +``` -Polkadot 1.0 currently achieves resilience through several strategies: +Key directories explained: -- **Nominated Proof of Stake (NPoS)**: Ensures that the stake per validator is maximized and evenly distributed among validators. +- **runtime/**: Contains your parachain's state transition function and pallet configuration. This is where you'll define what your blockchain can do. +- **node/**: Houses the client implementation that runs your blockchain, handles networking, and manages the database. +- **pallets/**: Where you'll create custom business logic modules (pallets) for your specific use case. +- **Cargo.toml**: The workspace configuration that ties all components together. -- **Decentralized nodes**: Designed to encourage operators to join the network. This program aims to expand and diversify the validators in the ecosystem who aim to become independent of the program during their term. Feel free to explore more about the program on the official [Decentralized Nodes](https://nodes.web3.foundation/){target=\_blank} page. +!!!note + The runtime is compiled to WebAssembly (Wasm), enabling forkless upgrades. The node binary remains constant while the runtime can be updated on-chain. -- **On-chain treasury and governance**: Known as [OpenGov](/reference/governance/){target=\_blank}, this system allows every decision to be made through public referenda, enabling any token holder to cast a vote. +## Compile the Runtime -### Polkadot's Blockspace +Now that you understand the template structure, let's compile the runtime to ensure everything is working correctly. -Polkadot 1.0’s design allows for the commoditization of blockspace. +1. Compile the runtime: -Blockspace is a blockchain's capacity to finalize and commit operations, encompassing its security, computing, and storage capabilities. Its characteristics can vary across different blockchains, affecting security, flexibility, and availability. + ```bash + cargo build --release --locked + ``` -- **Security**: Measures the robustness of blockspace in Proof of Stake (PoS) networks linked to the stake locked on validator nodes, the variance in stake among validators, and the total number of validators. It also considers social centralization (how many validators are owned by single operators) and physical centralization (how many validators run on the same service provider). + !!!tip + Initial compilation may take several minutes, depending on your machine specifications. Use the `--release` flag for improved runtime performance compared to the default `--debug` build. If you need to troubleshoot issues, the `--debug` build provides better diagnostics. + + For production deployments, consider using a dedicated `--profile production` flag - this can provide an additional 15-30% performance improvement over the standard `--release` profile. -- **Flexibility**: Reflects the functionalities and types of data that can be stored, with high-quality data essential to avoid bottlenecks in critical processes. +2. Upon successful compilation, you should see output indicating the build was successful. The compiled runtime will be located at: + + `./target/release/wbuild/parachain-template-runtime/parachain_template_runtime.compact.compressed.wasm` -- **Availability**: Indicates how easily users can access blockspace. It should be easily accessible, allowing diverse business models to thrive, ideally regulated by a marketplace based on demand and supplemented by options for "second-hand" blockspace. +## Verify the Build -Polkadot is built on core blockspace principles, but there's room for improvement. Tasks like balance transfers, staking, and governance are managed on the relay chain. +After compilation completes, verify that the runtime was created successfully by checking for the Wasm blob: -Delegating these responsibilities to [system chains](/polkadot-protocol/architecture/system-chains/){target=\_blank} could enhance flexibility and allow the relay chain to concentrate on providing shared security and interoperability. +```bash +ls -la ./target/release/wbuild/parachain-template-runtime/ +``` -For more information about blockspace, watch [Robert Habermeier’s interview](https://www.youtube.com/watch?v=e1vISppPwe4){target=\_blank} or read his [technical blog post](https://www.rob.tech/blog/polkadot-blockspace-over-blockchains/){target=\_blank}. +You should see the `parachain_template_runtime.compact.compressed.wasm` file in the output, confirming the build was successful. -## DOT Token - -DOT is the native token of the Polkadot network, much like BTC for Bitcoin and Ether for the Ethereum blockchain. DOT has 10 decimals, uses the Planck base unit, and has a balance type of `u128`. The same is true for Kusama's KSM token with the exception of having 12 decimals. - -### Redenomination of DOT - -Polkadot conducted a community poll, which ended on 27 July 2020 at block 888,888, to decide whether to redenominate the DOT token. The stakeholders chose to redenominate the token, changing the value of 1 DOT from 1e12 plancks to 1e10 plancks. - -Importantly, this did not affect the network's total number of base units (plancks); it only affects how a single DOT is represented. The redenomination became effective 72 hours after transfers were enabled, occurring at block 1,248,328 on 21 August 2020 around 16:50 UTC. - -### The Planck Unit - -The smallest unit of account balance on Polkadot SDK-based blockchains (such as Polkadot and Kusama) is called _Planck_, named after the Planck length, the smallest measurable distance in the physical universe. - -Similar to how BTC's smallest unit is the Satoshi and ETH's is the Wei, Polkadot's native token DOT equals 1e10 Planck, while Kusama's native token KSM equals 1e12 Planck. - -### Uses for DOT - -DOT serves three primary functions within the Polkadot network: - -- **Governance**: It is used to participate in the governance of the network. -- **Staking**: DOT is staked to support the network's operation and security. -- **Buying coretime**: Used to purchase coretime in-bulk or on-demand and access the chain to benefit from Polkadot's security and interoperability. - -Additionally, DOT can serve as a transferable token. For example, DOT, held in the treasury, can be allocated to teams developing projects that benefit the Polkadot ecosystem. - -## JAM and the Road Ahead - -The Join-Accumulate Machine (JAM) represents a transformative redesign of Polkadot's core architecture, envisioned as the successor to the current relay chain. Unlike traditional blockchain architectures, JAM introduces a unique computational model that processes work through two primary functions: - -- **Join**: Handles data integration. -- **Accumulate**: Folds computations into the chain's state. - -JAM removes many of the opinions and constraints of the current relay chain while maintaining its core security properties. Expected improvements include: - -- **Permissionless code execution**: JAM is designed to be more generic and flexible, allowing for permissionless code execution through services that can be deployed without governance approval. -- **More effective block time utilization**: JAM's efficient pipeline processing model places the prior state root in block headers instead of the posterior state root, enabling more effective utilization of block time for computations. - -This architectural evolution promises to enhance Polkadot's scalability and flexibility while maintaining robust security guarantees. JAM is planned to be rolled out to Polkadot as a single, complete upgrade rather than a stream of smaller updates. This approach seeks to minimize the developer overhead required to address any breaking changes. - - ---- - -Page Title: Parachains Overview - -- Source (raw): https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/reference-parachains.md -- Canonical (HTML): https://docs.polkadot.com/reference/parachains/ -- Summary: Learn about parachains, specialized blockchains on Polkadot that gain shared security and interoperability. Discover how they work and the tools to build them. - -# Parachains Overview - -## Introduction - -A parachain is a specialized blockchain that connects to the Polkadot relay chain, benefiting from shared security, interoperability, and scalability. Parachains are built using the [Polkadot SDK](https://github.com/paritytech/polkadot-sdk){target=\_blank}, a powerful toolkit written in Rust that provides everything needed to create custom blockchain logic while integrating seamlessly with the Polkadot network. - -Unlike standalone blockchains that must bootstrap their own validator sets and security, parachains leverage Polkadot's pooled security model. This allows parachain developers to focus on their application-specific functionality rather than consensus and security infrastructure. Parachains can communicate with each other through Cross-Consensus Messaging (XCM), enabling seamless interoperability across the Polkadot ecosystem. - -Key capabilities that parachains provide include: - -- **Shared security**: Inherit security from Polkadot's validator set without maintaining your own. -- **Interoperability**: Communicate trustlessly with other parachains via XCM. -- **Scalability**: Process transactions in parallel with other parachains. -- **Customization**: Build application-specific logic tailored to your use case. -- **Upgradeability**: Upgrade runtime logic without hard forks. - -## Polkadot SDK: Parachain Architecture - -Building a parachain involves understanding and utilizing several key components of the Polkadot SDK: - -![](/images/reference/parachains/index/overview-01.webp) - -- **[Substrate](https://paritytech.github.io/polkadot-sdk/master/polkadot_sdk_docs/polkadot_sdk/substrate/index.html){target=\_blank}**: The foundation providing core blockchain primitives and libraries. -- **[FRAME](https://paritytech.github.io/polkadot-sdk/master/polkadot_sdk_docs/polkadot_sdk/frame_runtime/index.html){target=\_blank}**: A modular framework for building your parachain's runtime logic. -- **[Cumulus](https://paritytech.github.io/polkadot-sdk/master/polkadot_sdk_docs/polkadot_sdk/cumulus/index.html){target=\_blank}**: Essential libraries and pallets that enable parachain functionality. -- **[XCM (Cross Consensus Messaging)](https://paritytech.github.io/polkadot-sdk/master/polkadot_sdk_docs/polkadot_sdk/xcm/index.html){target=\_blank}**: The messaging format for communicating with other parachains and the relay chain. -- **[Polkadot](https://paritytech.github.io/polkadot-sdk/master/polkadot_sdk_docs/polkadot_sdk/polkadot/index.html){target=\_blank}**: The relay chain that provides security and coordination. - -### Substrate: The Foundation - -Substrate provides the core infrastructure that every parachain is built upon. It handles the low-level blockchain functionality, allowing you to focus on your application's unique features. Substrate includes implementations for networking, database management, consensus participation, and the execution environment for your runtime. - -Every Polkadot SDK node consists of two main components: - -- **Client (Host)**: Handles infrastructure services. - - - Native binary that runs on validator and collator nodes. - - Executes the Wasm-compiled runtime. - - Manages networking, database, mempool, and block production. - - Interfaces with the relay chain for validation. - -- **Runtime (State Transition Function)**: Contains your business logic. - - - Defines how your Polkadot SDK node processes transactions. - - Compiled to [Wasm](https://webassembly.org/){target=\_blank} for deterministic execution. - - Stored on-chain and upgradeable via governance. - -```mermaid -%%{init: {'flowchart': {'padding': 5, 'nodeSpacing': 50, 'rankSpacing': 10}}}%% -graph TB - classDef title font-size:20px,font-weight:bold,stroke-width:0px - classDef clientStyle font-size:16px,font-weight:bold - classDef clientSubNodeStyle margin-top:10px - classDef runtimeCallExecutorStyle padding-top:10px - - subgraph sg1[Parachain
Node] - direction TB - - I[RuntimeCall Executor] - B[Wasm Runtime - STF] - - subgraph sg2[Client] - direction TB - C[Network and Blockchain
Infrastructure Services
+ Relay Chain Interface] - end - - I --> B - end - - class sg1 title - class sg2 clientStyle - class C clientSubNodeStyle - class I runtimeCallExecutorStyle - -``` - -### FRAME: Building Blocks for Your Runtime - -FRAME provides modular components called [pallets](/reference/glossary#pallet){target=\_blank} that you can compose to build your parachain's runtime. Each pallet provides specific functionality that you can customize and configure for your needs. This modular approach allows you to quickly assemble complex functionality without writing everything from scratch. - -```mermaid -graph LR - subgraph SP["Parachain Runtime"] - direction LR - Timestamp ~~~ Aura ~~~ ParachainSystem - Balances ~~~ TransactionPayment ~~~ Sudo - subgraph Timestamp["Timestamp"] - SS1[Custom Config] - end - subgraph Aura["Aura"] - SS2[Custom Config] - end - subgraph ParachainSystem["Parachain System"] - SS3[Custom Config] - end - subgraph Balances["Balances"] - SS4[Custom Config] - end - subgraph TransactionPayment["Transaction Payment"] - SS5[Custom Config] - end - subgraph Sudo["Sudo"] - SS6[Custom Config] - end - style Timestamp stroke:#FF69B4 - style Aura stroke:#FF69B4 - style ParachainSystem stroke:#FF69B4 - style Balances stroke:#FF69B4 - style TransactionPayment stroke:#FF69B4 - style Sudo stroke:#FF69B4 - style SS1 stroke-dasharray: 5 - style SS2 stroke-dasharray: 5 - style SS3 stroke-dasharray: 5 - style SS4 stroke-dasharray: 5 - style SS5 stroke-dasharray: 5 - style SS6 stroke-dasharray: 5 - - end - subgraph AP["Available FRAME Pallets"] - direction LR - A1[Aura]~~~A2[Parachain
System]~~~A3[Transaction
Payment]~~~A4[Sudo] - B1[Identity]~~~B2[Balances]~~~B3[Assets]~~~B4[EVM] - C1[Timestamp]~~~C2[Staking]~~~C3[Contracts]~~~C4[and more...] - end - AP --> SP -``` - -### Cumulus: Parachain-Specific Functionality - -Cumulus is what transforms a Polkadot SDK-based runtime into a parachain-capable runtime. It provides the essential components for communicating with the relay chain, participating in Polkadot's consensus, and handling parachain-specific operations like block validation and collation. - -Key Cumulus components include: - -- **Parachain system pallet**: Core parachain functionality and relay chain communication. -- **Collator consensus**: Block production logic for parachain collators. -- **Relay chain interface**: APIs for interacting with the Polkadot relay chain. -- **Validation data**: Handling proof-of-validity data required by relay chain validators. - -## Where to Go Next - -Building a parachain requires understanding the relationship between your chain and the Polkadot relay chain. The Polkadot SDK provides all the tools needed to design custom runtime logic, enable cross-chain communication, and deploy your parachain to production. - -The following sections provide detailed guidance on each aspect of parachain development, from initial design through deployment and ongoing maintenance. - -
- -- Guide __Launch a Simple Parachain__ - - --- - - Walk through the complete parachain launch flow: from setup and deployment to obtaining coretime. - - [:octicons-arrow-right-24: Deploy](/parachains/launch-a-parachain/set-up-the-parachain-template/) - - -- Guide __Customize Your Runtime__ - - --- - - Design your parachain's runtime logic and choose appropriate pallets for your use case. - - [:octicons-arrow-right-24: Get Started](/parachains/customize-runtime/) - -- Guide __Interoperability__ - - --- - - Implement XCM for trustless cross-chain communication with other parachains. - - [:octicons-arrow-right-24: Learn More](/parachains/interoperability/get-started/) - -- Guide __Runtime Upgrades__ - - --- - - Upgrade your parachain's runtime without hard forks using forkless upgrade mechanisms. - - [:octicons-arrow-right-24: Maintain](/parachains/runtime-maintenance/runtime-upgrades/) - -
- - ---- - -Page Title: Polkadot SDK Accounts - -- Source (raw): https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/reference-parachains-accounts.md -- Canonical (HTML): https://docs.polkadot.com/reference/parachains/accounts/ -- Summary: Learn about account structures, balances, and address formats in the Polkadot SDK, including how to manage lifecycle, references, and balances. - -# Accounts - -## Introduction - -Accounts are essential for managing identity, transactions, and governance on the network in the Polkadot SDK. Understanding these components is critical for seamless development and operation on the network, whether you're building or interacting with Polkadot-based chains. - -This page will guide you through the essential aspects of accounts, including their data structure, balance types, reference counters, and address formats. You’ll learn how accounts are managed within the runtime, how balances are categorized, and how addresses are encoded and validated. - -## Account Data Structure - -Accounts are foundational to any blockchain, and the Polkadot SDK provides a flexible management system. This section explains how the Polkadot SDK defines accounts and manages their lifecycle through data structures within the runtime. - -### Account - -The [`Account` data type](https://paritytech.github.io/polkadot-sdk/master/frame_system/pallet/type.Account.html){target=\_blank} is a storage map within the [System pallet](https://paritytech.github.io/polkadot-sdk/master/src/frame_system/lib.rs.html){target=\_blank} that links an account ID to its corresponding data. This structure is fundamental for mapping account-related information within the chain. - -The code snippet below shows how accounts are defined: - -```rs - /// The full account information for a particular account ID. - #[pallet::storage] - #[pallet::getter(fn account)] - pub type Account = StorageMap< - _, - Blake2_128Concat, - T::AccountId, - AccountInfo, - ValueQuery, - >; -``` - -The preceding code block defines a storage map named `Account`. The `StorageMap` is a type of on-chain storage that maps keys to values. In the `Account` map, the key is an account ID, and the value is the account's information. Here, `T` represents the generic parameter for the runtime configuration, which is defined by the pallet's configuration trait (`Config`). - -The `StorageMap` consists of the following parameters: - -- **`_`**: Used in macro expansion and acts as a placeholder for the storage prefix type. Tells the macro to insert the default prefix during expansion. -- **`Blake2_128Concat`**: The hashing function applied to keys in the storage map. -- **`T: :AccountId`**: Represents the key type, which corresponds to the account’s unique ID. -- **`AccountInfo`**: The value type stored in the map. For each account ID, the map stores an `AccountInfo` struct containing: - - - **`T::Nonce`**: A nonce for the account, which is incremented with each transaction to ensure transaction uniqueness. - - **`T: :AccountData`**: Custom account data defined by the runtime configuration, which could include balances, locked funds, or other relevant information. - -- **`ValueQuery`**: Defines how queries to the storage map behave when no value is found; returns a default value instead of `None`. - -For a detailed explanation of storage maps, see the [`StorageMap`](https://paritytech.github.io/polkadot-sdk/master/frame_support/storage/types/struct.StorageMap.html){target=\_blank} entry in the Rust docs. - -### Account Info - -The `AccountInfo` structure is another key element within the [System pallet](https://paritytech.github.io/polkadot-sdk/master/src/frame_system/lib.rs.html){target=\_blank}, providing more granular details about each account's state. This structure tracks vital data, such as the number of transactions and the account’s relationships with other modules. - -```rs -/// Information of an account. -#[derive(Clone, Eq, PartialEq, Default, RuntimeDebug, Encode, Decode, TypeInfo, MaxEncodedLen)] -pub struct AccountInfo { - /// The number of transactions this account has sent. - pub nonce: Nonce, - /// The number of other modules that currently depend on this account's existence. The account - /// cannot be reaped until this is zero. - pub consumers: RefCount, - /// The number of other modules that allow this account to exist. The account may not be reaped - /// until this and `sufficients` are both zero. - pub providers: RefCount, - /// The number of modules that allow this account to exist for their own purposes only. The - /// account may not be reaped until this and `providers` are both zero. - pub sufficients: RefCount, - /// The additional data that belongs to this account. Used to store the balance(s) in a lot of - /// chains. - pub data: AccountData, -} -``` - -The `AccountInfo` structure includes the following components: - -- **`nonce`**: Tracks the number of transactions initiated by the account, which ensures transaction uniqueness and prevents replay attacks. -- **`consumers`**: Counts how many other modules or pallets rely on this account’s existence. The account cannot be removed from the chain (reaped) until this count reaches zero. -- **`providers`**: Tracks how many modules permit this account’s existence. An account can only be reaped once both `providers` and `sufficients` are zero. -- **`sufficients`**: Represents the number of modules that allow the account to exist for internal purposes, independent of any other modules. -- **`AccountData`**: A flexible data structure that can be customized in the runtime configuration, usually containing balances or other user-specific data. - -This structure helps manage an account's state and prevents its premature removal while it is still referenced by other on-chain data or modules. The [`AccountInfo`](https://paritytech.github.io/polkadot-sdk/master/frame_system/struct.AccountInfo.html){target=\_blank} structure can vary as long as it satisfies the trait bounds defined by the `AccountData` associated type in the [`frame-system::pallet::Config`](https://paritytech.github.io/polkadot-sdk/master/frame_system/pallet/trait.Config.html){target=\_blank} trait. - -### Account Reference Counters - -Polkadot SDK uses reference counters to track an account’s dependencies across different runtime modules. These counters ensure that accounts remain active while data is associated with them. - -The reference counters include: - -- **`consumers`**: Prevents account removal while other pallets still rely on the account. -- **`providers`**: Ensures an account is active before other pallets store data related to it. -- **`sufficients`**: Indicates the account’s independence, ensuring it can exist even without a native token balance, such as when holding sufficient alternative assets. - -#### Providers Reference Counters - -The `providers` counter ensures that an account is ready to be depended upon by other runtime modules. For example, it is incremented when an account has a balance above the existential deposit, which marks the account as active. - -The system requires this reference counter to be greater than zero for the `consumers` counter to be incremented, ensuring the account is stable before any dependencies are added. - -#### Consumers Reference Counters - -The `consumers` counter ensures that the account cannot be reaped until all references to it across the runtime have been removed. This check prevents the accidental deletion of accounts that still have active on-chain data. - -It is the user’s responsibility to clear out any data from other runtime modules if they wish to remove their account and reclaim their existential deposit. - -#### Sufficients Reference Counter - -The `sufficients` counter tracks accounts that can exist independently without relying on a native account balance. This is useful for accounts holding other types of assets, like tokens, without needing a minimum balance in the native token. - -For instance, the [Assets pallet](https://paritytech.github.io/polkadot-sdk/master/pallet_assets/index.html){target=\_blank}, may increment this counter for an account holding sufficient tokens. - -#### Account Deactivation - -In Polkadot SDK-based chains, an account is deactivated when its reference counters (such as `providers`, `consumers`, and `sufficient`) reach zero. These counters ensure the account remains active as long as other runtime modules or pallets reference it. - -When all dependencies are cleared and the counters drop to zero, the account becomes deactivated and may be removed from the chain (reaped). This is particularly important in Polkadot SDK-based blockchains, where accounts with balances below the existential deposit threshold are pruned from storage to conserve state resources. - -Each pallet that references an account has cleanup functions that decrement these counters when the pallet no longer depends on the account. Once these counters reach zero, the account is marked for deactivation. - -#### Updating Counters - -The Polkadot SDK provides runtime developers with various methods to manage account lifecycle events, such as deactivation or incrementing reference counters. These methods ensure that accounts cannot be reaped while still in use. - -The following helper functions manage these counters: - -- **`inc_consumers()`**: Increments the `consumer` reference counter for an account, signaling that another pallet depends on it. -- **`dec_consumers()`**: Decrements the `consumer` reference counter, signaling that a pallet no longer relies on the account. -- **`inc_providers()`**: Increments the `provider` reference counter, ensuring the account remains active. -- **`dec_providers()`**: Decrements the `provider` reference counter, allowing for account deactivation when no longer in use. -- **`inc_sufficients()`**: Increments the `sufficient` reference counter for accounts that hold sufficient assets. -- **`dec_sufficients()`**: Decrements the `sufficient` reference counter. - -To ensure proper account cleanup and lifecycle management, a corresponding decrement should be made for each increment action. - -The `System` pallet offers three query functions to assist developers in tracking account states: - -- **[`can_inc_consumer()`](https://paritytech.github.io/polkadot-sdk/master/frame_system/pallet/struct.Pallet.html#method.can_inc_consumer){target=\_blank}**: Checks if the account can safely increment the consumer reference. -- **[`can_dec_provider()`](https://paritytech.github.io/polkadot-sdk/master/frame_system/pallet/struct.Pallet.html#method.can_dec_provider){target=\_blank}**: Ensures that no consumers exist before allowing the decrement of the provider counter. -- **[`is_provider_required()`](https://paritytech.github.io/polkadot-sdk/master/frame_system/pallet/struct.Pallet.html#method.is_provider_required){target=\_blank}**: Verifies whether the account still has any active consumer references. - -This modular and flexible system of reference counters tightly controls the lifecycle of accounts in Polkadot SDK-based blockchains, preventing the accidental removal or retention of unneeded accounts. You can refer to the [System pallet Rust docs](https://paritytech.github.io/polkadot-sdk/master/frame_system/pallet/struct.Pallet.html){target=\_blank} for more details. - - -## Account Balance Types - -In the Polkadot ecosystem, account balances are categorized into different types based on how the funds are utilized and their availability. These balance types determine the actions that can be performed, such as transferring tokens, paying transaction fees, or participating in governance activities. Understanding these balance types helps developers manage user accounts and implement balance-dependent logic. - -!!! note "A more efficient distribution of account balance types is in development" - Soon, pallets in the Polkadot SDK will implement the [`Fungible` trait](https://paritytech.github.io/polkadot-sdk/master/frame_support/traits/tokens/fungible/index.html){target=\_blank} (see the [tracking issue](https://github.com/paritytech/polkadot-sdk/issues/226){target=\_blank} for more details). For example, the [`transaction-storage`](https://paritytech.github.io/polkadot-sdk/master/pallet_transaction_storage/index.html){target=\_blank} pallet changed the implementation of the [`Currency`](https://paritytech.github.io/polkadot-sdk/master/frame_support/traits/tokens/currency/index.html){target=\_blank} trait (see the [Refactor transaction storage pallet to use fungible traits](https://github.com/paritytech/polkadot-sdk/pull/1800){target=\_blank} PR for further details): - - ```rust - type BalanceOf = <::Currency as Currency<::AccountId>>::Balance; - ``` - - To the [`Fungible`](https://paritytech.github.io/polkadot-sdk/master/frame_support/traits/tokens/fungible/index.html){target=\_blank} trait: - - ```rust - type BalanceOf = <::Currency as FnInspect<::AccountId>>::Balance; - ``` - - This update will enable more efficient use of account balances, allowing the free balance to be utilized for on-chain activities such as setting proxies and managing identities. - -### Balance Types - -The five main balance types are: - -- **Free balance**: Represents the total tokens available to the account for any on-chain activity, including staking, governance, and voting. However, it may not be fully spendable or transferrable if portions of it are locked or reserved. -- **Locked balance**: Portions of the free balance that cannot be spent or transferred because they are tied up in specific activities like [staking](https://wiki.polkadot.com/learn/learn-staking/#nominating-validators){target=\_blank}, [vesting](https://wiki.polkadot.com/learn/learn-guides-transfers/#vested-transfers-with-the-polkadot-js-ui){target=\_blank}, or participating in [governance](https://wiki.polkadot.com/learn/learn-polkadot-opengov/#voting-on-a-referendum){target=\_blank}. While the tokens remain part of the free balance, they are non-transferable for the duration of the lock. -- **Reserved balance**: Funds locked by specific system actions, such as setting up an [identity](https://wiki.polkadot.com/learn/learn-identity/){target=\_blank}, creating [proxies](https://wiki.polkadot.com/learn/learn-proxies/){target=\_blank}, or submitting [deposits for governance proposals](https://wiki.polkadot.com/learn/learn-guides-polkadot-opengov/#claiming-opengov-deposits){target=\_blank}. These tokens are not part of the free balance and cannot be spent unless they are unreserved. -- **Spendable balance**: The portion of the free balance that is available for immediate spending or transfers. It is calculated by subtracting the maximum of locked or reserved amounts from the free balance, ensuring that existential deposit limits are met. -- **Untouchable balance**: Funds that cannot be directly spent or transferred but may still be utilized for on-chain activities, such as governance participation or staking. These tokens are typically tied to certain actions or locked for a specific period. - -The spendable balance is calculated as follows: - -```text -spendable = free - max(locked - reserved, ED) -``` - -Here, `free`, `locked`, and `reserved` are defined above. The `ED` represents the [existential deposit](https://wiki.polkadot.com/learn/learn-accounts/#existential-deposit-and-reaping){target=\_blank}, the minimum balance required to keep an account active and prevent it from being reaped. You may find you can't see all balance types when looking at your account via a wallet. Wallet providers often display only spendable, locked, and reserved balances. - -### Locks - -Locks are applied to an account's free balance, preventing that portion from being spent or transferred. Locks are automatically placed when an account participates in specific on-chain activities, such as staking or governance. Although multiple locks may be applied simultaneously, they do not stack. Instead, the largest lock determines the total amount of locked tokens. - -Locks follow these basic rules: - -- If different locks apply to varying amounts, the largest lock amount takes precedence. -- If multiple locks apply to the same amount, the lock with the longest duration governs when the balance can be unlocked. - -#### Locks Example - -Consider an example where an account has 80 DOT locked for both staking and governance purposes like so: - -- 80 DOT is staked with a 28-day lock period. -- 24 DOT is locked for governance with a 1x conviction and a 7-day lock period. -- 4 DOT is locked for governance with a 6x conviction and a 224-day lock period. - -In this case, the total locked amount is 80 DOT because only the largest lock (80 DOT from staking) governs the locked balance. These 80 DOT will be released at different times based on the lock durations. In this example, the 24 DOT locked for governance will be released first since the shortest lock period is seven days. The 80 DOT stake with a 28-day lock period is released next. Now, all that remains locked is the 4 DOT for governance. After 224 days, all 80 DOT (minus the existential deposit) will be free and transferable. - -![Illustration of Lock Example](/images/reference/parachains/accounts/accounts-01.webp) - -#### Edge Cases for Locks - -In scenarios where multiple convictions and lock periods are active, the lock duration and amount are determined by the longest period and largest amount. For example, if you delegate with different convictions and attempt to undelegate during an active lock period, the lock may be extended for the full amount of tokens. For a detailed discussion on edge case lock behavior, see this [Stack Exchange post](https://substrate.stackexchange.com/questions/5067/delegating-and-undelegating-during-the-lock-period-extends-it-for-the-initial-am){target=\_blank}. - -### Balance Types on Polkadot.js - -Polkadot.js provides a user-friendly interface for managing and visualizing various account balances on Polkadot and Kusama networks. When interacting with Polkadot.js, you will encounter multiple balance types that are critical for understanding how your funds are distributed and restricted. This section explains how different balances are displayed in the Polkadot.js UI and what each type represents. - -![](/images/reference/parachains/accounts/accounts-02.webp) - -The most common balance types displayed on Polkadot.js are: - -- **Total balance**: The total number of tokens available in the account. This includes all tokens, whether they are transferable, locked, reserved, or vested. However, the total balance does not always reflect what can be spent immediately. In this example, the total balance is 0.6274 KSM. - -- **Transferable balance**: Shows how many tokens are immediately available for transfer. It is calculated by subtracting the locked and reserved balances from the total balance. For example, if an account has a total balance of 0.6274 KSM and a transferable balance of 0.0106 KSM, only the latter amount can be sent or spent freely. - -- **Vested balance**: Tokens that allocated to the account but released according to a specific schedule. Vested tokens remain locked and cannot be transferred until fully vested. For example, an account with a vested balance of 0.2500 KSM means that this amount is owned but not yet transferable. - -- **Locked balance**: Tokens that are temporarily restricted from being transferred or spent. These locks typically result from participating in staking, governance, or vested transfers. In Polkadot.js, locked balances do not stack—only the largest lock is applied. For instance, if an account has 0.5500 KSM locked for governance and staking, the locked balance would display 0.5500 KSM, not the sum of all locked amounts. - -- **Reserved balance**: Refers to tokens locked for specific on-chain actions, such as setting an identity, creating a proxy, or making governance deposits. Reserved tokens are not part of the free balance, but can be freed by performing certain actions. For example, removing an identity would unreserve those funds. - -- **Bonded balance**: The tokens locked for staking purposes. Bonded tokens are not transferable until they are unbonded after the unbonding period. - -- **Redeemable balance**: The number of tokens that have completed the unbonding period and are ready to be unlocked and transferred again. For example, if an account has a redeemable balance of 0.1000 KSM, those tokens are now available for spending. - -- **Democracy balance**: Reflects the number of tokens locked for governance activities, such as voting on referenda. These tokens are locked for the duration of the governance action and are only released after the lock period ends. - -By understanding these balance types and their implications, developers and users can better manage their funds and engage with on-chain activities more effectively. - -## Address Formats - -The SS58 address format is a core component of the Polkadot SDK that enables accounts to be uniquely identified across Polkadot-based networks. This format is a modified version of Bitcoin's Base58Check encoding, specifically designed to accommodate the multi-chain nature of the Polkadot ecosystem. SS58 encoding allows each chain to define its own set of addresses while maintaining compatibility and checksum validation for security. - -### Basic Format - -SS58 addresses consist of three main components: - -```text -base58encode(concat(,
, )) -``` - -- **Address type**: A byte or set of bytes that define the network (or chain) for which the address is intended. This ensures that addresses are unique across different Polkadot SDK-based chains. -- **Address**: The public key of the account encoded as bytes. -- **Checksum**: A hash-based checksum which ensures that addresses are valid and unaltered. The checksum is derived from the concatenated address type and address components, ensuring integrity. - -The encoding process transforms the concatenated components into a Base58 string, providing a compact and human-readable format that avoids easily confused characters (e.g., zero '0', capital 'O', lowercase 'l'). This encoding function ([`encode`](https://docs.rs/bs58/latest/bs58/fn.encode.html){target=\_blank}) is implemented exactly as defined in Bitcoin and IPFS specifications, using the same alphabet as both implementations. - -For more details about the SS58 address format implementation, see the [`Ss58Codec`](https://paritytech.github.io/polkadot-sdk/master/sp_core/crypto/trait.Ss58Codec.html){target=\_blank} trait in the Rust Docs. - -### Address Type - -The address type defines how an address is interpreted and to which network it belongs. Polkadot SDK uses different prefixes to distinguish between various chains and address formats: - -- **Address types `0-63`**: Simple addresses, commonly used for network identifiers. -- **Address types `64-127`**: Full addresses that support a wider range of network identifiers. -- **Address types `128-255`**: Reserved for future address format extensions. - -For example, Polkadot’s main network uses an address type of 0, while Kusama uses 2. This ensures that addresses can be used without confusion between networks. - -The address type is always encoded as part of the SS58 address, making it easy to quickly identify the network. Refer to the [SS58 registry](https://github.com/paritytech/ss58-registry){target=\_blank} for the canonical listing of all address type identifiers and how they map to Polkadot SDK-based networks. - -### Address Length - -SS58 addresses can have different lengths depending on the specific format. Address lengths range from as short as 3 to 35 bytes, depending on the complexity of the address and network requirements. This flexibility allows SS58 addresses to adapt to different chains while providing a secure encoding mechanism. - -| Total | Type | Raw account | Checksum | -|-------|------|-------------|----------| -| 3 | 1 | 1 | 1 | -| 4 | 1 | 2 | 1 | -| 5 | 1 | 2 | 2 | -| 6 | 1 | 4 | 1 | -| 7 | 1 | 4 | 2 | -| 8 | 1 | 4 | 3 | -| 9 | 1 | 4 | 4 | -| 10 | 1 | 8 | 1 | -| 11 | 1 | 8 | 2 | -| 12 | 1 | 8 | 3 | -| 13 | 1 | 8 | 4 | -| 14 | 1 | 8 | 5 | -| 15 | 1 | 8 | 6 | -| 16 | 1 | 8 | 7 | -| 17 | 1 | 8 | 8 | -| 35 | 1 | 32 | 2 | - -SS58 addresses also support different payload sizes, allowing a flexible range of account identifiers. - -### Checksum Types - -A checksum is applied to validate SS58 addresses. Polkadot SDK uses a Blake2b-512 hash function to calculate the checksum, which is appended to the address before encoding. The checksum length can vary depending on the address format (e.g., 1-byte, 2-byte, or longer), providing varying levels of validation strength. - -The checksum ensures that an address is not modified or corrupted, adding an extra layer of security for account management. - -### Validating Addresses - -SS58 addresses can be validated using the subkey command-line interface or the Polkadot.js API. These tools help ensure an address is correctly formatted and valid for the intended network. The following sections will provide an overview of how validation works with these tools. - -#### Using Subkey - -[Subkey](https://paritytech.github.io/polkadot-sdk/master/subkey/index.html){target=\_blank} is a CLI tool provided by Polkadot SDK for generating and managing keys. It can inspect and validate SS58 addresses. - -The `inspect` command gets a public key and an SS58 address from the provided secret URI. The basic syntax for the `subkey inspect` command is: - -```bash -subkey inspect [flags] [options] uri -``` - -For the `uri` command-line argument, you can specify the secret seed phrase, a hex-encoded private key, or an SS58 address. If the input is a valid address, the `subkey` program displays the corresponding hex-encoded public key, account identifier, and SS58 addresses. - -For example, to inspect the public keys derived from a secret seed phrase, you can run a command similar to the following: - -```bash -subkey inspect "caution juice atom organ advance problem want pledge someone senior holiday very" -``` - -The command displays output similar to the following: - -
- subkey inspect "caution juice atom organ advance problem want pledge someone senior holiday very" - Secret phrase `caution juice atom organ advance problem want pledge someone senior holiday very` is account: - Secret seed: 0xc8fa03532fb22ee1f7f6908b9c02b4e72483f0dbd66e4cd456b8f34c6230b849 - Public key (hex): 0xd6a3105d6768e956e9e5d41050ac29843f98561410d3a47f9dd5b3b227ab8746 - Public key (SS58): 5Gv8YYFu8H1btvmrJy9FjjAWfb99wrhV3uhPFoNEr918utyR - Account ID: 0xd6a3105d6768e956e9e5d41050ac29843f98561410d3a47f9dd5b3b227ab8746 - SS58 Address: 5Gv8YYFu8H1btvmrJy9FjjAWfb99wrhV3uhPFoNEr918utyR -
- -The `subkey` program assumes an address is based on a public/private key pair. If you inspect an address, the command returns the 32-byte account identifier. - -However, not all addresses in Polkadot SDK-based networks are based on keys. - -Depending on the command-line options you specify and the input you provided, the command output might also display the network for which the address has been encoded. For example: - -```bash -subkey inspect "12bzRJfh7arnnfPPUZHeJUaE62QLEwhK48QnH9LXeK2m1iZU" -``` - -The command displays output similar to the following: - -
- subkey inspect "12bzRJfh7arnnfPPUZHeJUaE62QLEwhK48QnH9LXeK2m1iZU" - Public Key URI `12bzRJfh7arnnfPPUZHeJUaE62QLEwhK48QnH9LXeK2m1iZU` is account: - Network ID/Version: polkadot - Public key (hex): 0x46ebddef8cd9bb167dc30878d7113b7e168e6f0646beffd77d69d39bad76b47a - Account ID: 0x46ebddef8cd9bb167dc30878d7113b7e168e6f0646beffd77d69d39bad76b47a - Public key (SS58): 12bzRJfh7arnnfPPUZHeJUaE62QLEwhK48QnH9LXeK2m1iZU - SS58 Address: 12bzRJfh7arnnfPPUZHeJUaE62QLEwhK48QnH9LXeK2m1iZU -
- -#### Using Polkadot.js API - -To verify an address in JavaScript or TypeScript projects, you can use the functions built into the [Polkadot.js API](https://polkadot.js.org/docs/){target=\_blank}. For example: - -```js -// Import Polkadot.js API dependencies -const { decodeAddress, encodeAddress } = require('@polkadot/keyring'); -const { hexToU8a, isHex } = require('@polkadot/util'); - -// Specify an address to test. -const address = 'INSERT_ADDRESS_TO_TEST'; - -// Check address -const isValidSubstrateAddress = () => { - try { - encodeAddress(isHex(address) ? hexToU8a(address) : decodeAddress(address)); - - return true; - } catch (error) { - return false; - } -}; - -// Query result -const isValid = isValidSubstrateAddress(); -console.log(isValid); - -``` - -If the function returns `true`, the specified address is a valid address. - -#### Other SS58 Implementations - -Support for encoding and decoding Polkadot SDK SS58 addresses has been implemented in several other languages and libraries. - -- **Crystal**: [`wyhaines/base58.cr`](https://github.com/wyhaines/base58.cr){target=\_blank} -- **Go**: [`itering/subscan-plugin`](https://github.com/itering/subscan-plugin){target=\_blank} -- **Python**: [`polkascan/py-scale-codec`](https://github.com/polkascan/py-scale-codec){target=\_blank} -- **TypeScript**: [`subsquid/squid-sdk`](https://github.com/subsquid/squid-sdk){target=\_blank} - - ---- - -Page Title: Randomness - -- Source (raw): https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/reference-parachains-randomness.md -- Canonical (HTML): https://docs.polkadot.com/reference/parachains/randomness/ -- Summary: Explore the importance of randomness in PoS blockchains, focusing on Polkadot’s VRF-based approach to ensure fairness and security in validator selection. - -# Randomness - -## Introduction - -Randomness is crucial in Proof of Stake (PoS) blockchains to ensure a fair and unpredictable distribution of validator duties. However, computers are inherently deterministic, meaning the same input always produces the same output. What we typically refer to as "random" numbers on a computer are actually pseudo-random. These numbers rely on an initial "seed," which can come from external sources like [atmospheric noise](https://www.random.org/randomness/){target=\_blank}, [heart rates](https://mdpi.altmetric.com/details/47574324){target=\_blank}, or even [lava lamps](https://en.wikipedia.org/wiki/Lavarand){target=\_blank}. While this may seem random, given the same "seed," the same sequence of numbers will always be generated. - -In a global blockchain network, relying on real-world entropy for randomness isn’t feasible because these inputs vary by time and location. If nodes use different inputs, blockchains can fork. Hence, real-world randomness isn't suitable for use as a seed in blockchain systems. - -Currently, two primary methods for generating randomness in blockchains are used: [`RANDAO`](#randao) and [`VRF`](#vrf) (Verifiable Random Function). Polkadot adopts the `VRF` approach for its randomness. - -## VRF - -A Verifiable Random Function (VRF) is a cryptographic function that generates a random number and proof that ensures the submitter produced the number. This proof allows anyone to verify the validity of the random number. - -Polkadot's VRF is similar to the one used in [**Ouroboros Praos**](https://eprint.iacr.org/2017/573.pdf){target=\_blank}, which secures randomness for block production in systems like [BABE](/reference/polkadot-hub/consensus-and-security/pos-consensus/#block-production-babe){target=\_blank} (Polkadot’s block production mechanism). - -The key difference is that Polkadot's VRF doesn’t rely on a central clock—avoiding the issue of whose clock to trust. Instead, it uses its own past results and slot numbers to simulate time and determine future outcomes. - -### How VRF Works - -Slots on Polkadot are discrete units of time, each lasting six seconds, and can potentially hold a block. Multiple slots form an epoch, with 2400 slots making up one four-hour epoch. - -In each slot, validators execute a "die roll" using a VRF. The VRF uses three inputs: - -1. A "secret key," unique to each validator, is used for the die roll. -2. An epoch randomness value, derived from the hash of VRF outputs from blocks two epochs ago (N-2), so past randomness influences the current epoch (N). -3. The current slot number. - -This process helps maintain fair randomness across the network. - -Here is a graphical representation: - -![](/images/reference/parachains/randomness/randomness-01.webp) - -The VRF produces two outputs: a result (the random number) and a proof (verifying that the number was generated correctly). - -The result is checked by the validator against a protocol threshold. If it's below the threshold, the validator becomes a candidate for block production in that slot. - -The validator then attempts to create a block, submitting it along with the `PROOF` and `RESULT`. - -So, VRF can be expressed like: - -`(RESULT, PROOF) = VRF(SECRET, EPOCH_RANDOMNESS_VALUE, CURRENT_SLOT_NUMBER)` - -Put simply, performing a "VRF roll" generates a random number along with proof that the number was genuinely produced and not arbitrarily chosen. - -After executing the VRF, the `RESULT` is compared to a protocol-defined `THRESHOLD`. If the `RESULT` is below the `THRESHOLD`, the validator becomes a valid candidate to propose a block for that slot. Otherwise, the validator skips the slot. - -As a result, there may be multiple validators eligible to propose a block for a slot. In this case, the block accepted by other nodes will prevail, provided it is on the chain with the latest finalized block as determined by the GRANDPA finality gadget. It's also possible for no block producers to be available for a slot, in which case the AURA consensus takes over. AURA is a fallback mechanism that randomly selects a validator to produce a block, running in parallel with BABE and only stepping in when no block producers exist for a slot. Otherwise, it remains inactive. - -Because validators roll independently, no block candidates may appear in some slots if all roll numbers are above the threshold. - -To verify resolution of this issue and that Polkadot block times remain near constant-time, see the [PoS Consensus](/reference/polkadot-hub/consensus-and-security/pos-consensus/){target=\_blank} page of this documentation. - -## RANDAO - -An alternative on-chain randomness method is Ethereum's RANDAO, where validators perform thousands of hashes on a seed and publish the final hash during a round. The collective input from all validators forms the random number, and as long as one honest validator participates, the randomness is secure. - -To enhance security, RANDAO can optionally be combined with a Verifiable Delay Function (VDF), ensuring that randomness can't be predicted or manipulated during computation. - -For more information about RANDAO, see the [Randomness - RANDAO](https://eth2book.info/capella/part2/building_blocks/randomness/){target=\_blank} section of the Upgrading Ethereum documentation. - -## VDFs - -Verifiable Delay Functions (VDFs) are time-bound computations that, even on parallel computers, take a set amount of time to complete. - -They produce a unique result that can be quickly verified publicly. When combined with RANDAO, feeding RANDAO's output into a VDF introduces a delay that nullifies an attacker's chance to influence the randomness. - -However, VDF likely requires specialized ASIC devices to run separately from standard nodes. - -!!!warning - While only one is needed to secure the system, and they will be open-source and inexpensive, running VDF devices involves significant costs without direct incentives, adding friction for blockchain users. - -## Additional Resources - -For more information about the reasoning for choices made along with proofs, see Polkadot's research on blockchain randomness and sortition in the [Block production](https://research.web3.foundation/Polkadot/protocols/block-production){target=\_blank} entry of the Polkadot Wiki. - -For a discussion with Web3 Foundation researchers about when and under what conditions Polkadot's randomness can be utilized, see the [Discussion on Randomness used in Polkadot](https://github.com/use-ink/ink/issues/57){target=\_blank} issue on GitHub. - - ---- - -Page Title: Set Up the Polkadot SDK Parachain Template - -- Source (raw): https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/parachains-launch-a-parachain-set-up-the-parachain-template.md -- Canonical (HTML): https://docs.polkadot.com/parachains/launch-a-parachain/set-up-the-parachain-template/ -- Summary: Learn how to set up and run the Polkadot SDK Parachain Template locally, creating a ready-to-customize foundation for your parachain. - -# Set Up the Polkadot SDK Parachain Template - -## Introduction - -The [Polkadot SDK](https://github.com/paritytech/polkadot-sdk){target=\_blank} includes several [templates](/parachains/customize-runtime/#starting-templates){target=\_blank} designed to help you quickly start building your own blockchain. Each template offers a different level of configuration, from minimal setups to feature-rich environments, allowing you to choose the foundation that best fits your project's needs. - -Among these, the [Parachain Template](https://github.com/paritytech/polkadot-sdk-parachain-template){target=\_blank} provides a preconfigured runtime with commonly used pallets, making it an ideal starting point for most parachain development projects. - -This guide walks you through the full process of working with this template. You will: - -- Set up the Polkadot SDK Parachain Template. -- Understand the project structure and key components. -- Verify your template is ready for development. -- Run the parachain template locally in development mode. - -By the end of this guide, you'll have a working template ready to customize and deploy as a parachain. - -## Prerequisites - -Before getting started, ensure you have done the following: - -- Completed the [Install Polkadot SDK](/parachains/install-polkadot-sdk/){target=\_blank} guide and successfully installed [Rust](https://www.rust-lang.org/){target=\_blank} and the required packages to set up your development environment. - -For this tutorial series, you need to use Rust `1.86`. Newer versions of the compiler may not work with this parachain template version. - -Run the following commands to set up the correct Rust version: - -=== "macOS" - - ```bash - rustup install 1.86 - rustup default 1.86 - rustup target add wasm32-unknown-unknown --toolchain 1.86-aarch64-apple-darwin - rustup component add rust-src --toolchain 1.86-aarch64-apple-darwin - ``` - -=== "Ubuntu" - - ```bash - rustup toolchain install 1.86.0 - rustup default 1.86.0 - rustup target add wasm32-unknown-unknown --toolchain 1.86.0 - rustup component add rust-src --toolchain 1.86.0 - ``` - -## Polkadot SDK Utility Tools - -This tutorial requires two essential tools: - -- [**Chain spec builder**](https://crates.io/crates/staging-chain-spec-builder/10.0.0){target=\_blank}: A Polkadot SDK utility for generating chain specifications. Refer to the [Generate Chain Specs](/parachains/launch-a-parachain/deploy-to-polkadot/#generate-the-chain-specification){target=\_blank} documentation for detailed usage. - - Install it by executing the following command: - - ```bash - cargo install --locked staging-chain-spec-builder@10.0.0 - ``` - - This command installs the `chain-spec-builder` binary. - -- [**Polkadot Omni Node**](https://crates.io/crates/polkadot-omni-node/0.5.0){target=\_blank}: A white-labeled binary, released as a part of Polkadot SDK that can act as the collator of a parachain in production, with all the related auxiliary functionalities that a normal collator node has: RPC server, archiving state, etc. Moreover, it can also run the Wasm blob of the parachain locally for testing and development. - - To install it, run the following command: - - ```bash - cargo install --locked polkadot-omni-node@0.5.0 - ``` - - This command installs the `polkadot-omni-node` binary. - -## Clone the Template - -The [Polkadot SDK Parachain Template](https://github.com/paritytech/polkadot-sdk-parachain-template){target=\_blank} provides a ready-to-use development environment for building with the [Polkadot SDK](https://github.com/paritytech/polkadot-sdk){target=\_blank}. Follow these steps to set up the template: - -1. Clone the template repository: - - ```bash - git clone https://github.com/paritytech/polkadot-sdk-parachain-template.git parachain-template - ``` - -2. Navigate into the project directory: - - ```bash - cd parachain-template - ``` - -## Explore the Project Structure - -Before building the template, take a moment to familiarize yourself with its structure. Understanding this organization will help you navigate the codebase as you develop your parachain. - -The template follows a standard Polkadot SDK project layout: - -```text -parachain-template/ -├── node/ # Node implementation and client -├── pallets/ # Custom pallets for your parachain -├── runtime/ # Runtime configuration and logic -├── Cargo.toml # Workspace configuration -└── README.md # Documentation -``` - -Key directories explained: - -- **runtime/**: Contains your parachain's state transition function and pallet configuration. This is where you'll define what your blockchain can do. -- **node/**: Houses the client implementation that runs your blockchain, handles networking, and manages the database. -- **pallets/**: Where you'll create custom business logic modules (pallets) for your specific use case. -- **Cargo.toml**: The workspace configuration that ties all components together. - -!!!note - The runtime is compiled to WebAssembly (Wasm), enabling forkless upgrades. The node binary remains constant while the runtime can be updated on-chain. - -## Compile the Runtime - -Now that you understand the template structure, let's compile the runtime to ensure everything is working correctly. - -1. Compile the runtime: - - ```bash - cargo build --release --locked - ``` - - !!!tip - Initial compilation may take several minutes, depending on your machine specifications. Use the `--release` flag for improved runtime performance compared to the default `--debug` build. If you need to troubleshoot issues, the `--debug` build provides better diagnostics. - - For production deployments, consider using a dedicated `--profile production` flag - this can provide an additional 15-30% performance improvement over the standard `--release` profile. - -2. Upon successful compilation, you should see output indicating the build was successful. The compiled runtime will be located at: - - `./target/release/wbuild/parachain-template-runtime/parachain_template_runtime.compact.compressed.wasm` - -## Verify the Build - -After compilation completes, verify that the runtime was created successfully by checking for the Wasm blob: - -```bash -ls -la ./target/release/wbuild/parachain-template-runtime/ -``` - -You should see the `parachain_template_runtime.compact.compressed.wasm` file in the output, confirming the build was successful. - -## Run the Node Locally +## Run the Node Locally After successfully compiling your runtime, you can spin up a local chain and produce blocks. This process will start your local parachain using the Polkadot Omni Node and allow you to interact with it. You'll first need to generate a chain specification that defines your network's identity, initial connections, and genesis state, providing the foundational configuration for how your nodes connect and what initial state they agree upon. @@ -3373,514 +2189,122 @@ Page Title: Smart Contracts Cookbook - Canonical (HTML): https://docs.polkadot.com/smart-contracts/cookbook/ - Summary: Explore our full collection of tutorials and guides to learn step-by-step how to build, deploy, and work with smart contracts on Polkadot. -# Smart Contracts Cookbook - -Welcome to the Polkadot smart contracts cookbook index. - -This page contains a list of all relevant tutorials and guides to help you get started coding smart contracts and dApps in Polkadot. - - - - -## Get Tokens from the Faucet - -| Title | Difficulty | Tools | Description | -|------------------------------------|:-----------:|-------|-----------------------------------------------------------------------------------------------------------------------| -| [Faucet](/smart-contracts/faucet/) | 🟢 Beginner | N/A | Learn how to obtain test tokens from Polkadot faucets for development and testing purposes across different networks. | - -## EVM Smart Contracts - -| Title | Difficulty | Tools | Description | -|---------------------------------------------------------------------------------------------------------|:-----------:|--------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------| -| [Deploy an ERC-20 to Polkadot Hub](/smart-contracts/cookbook/smart-contracts/deploy-erc20/erc20-remix/) | 🟢 Beginner | EVM Wallet, Polkadot Remix IDE | Deploy an ERC-20 token on Polkadot Hub using PolkaVM. This guide covers contract creation, compilation, deployment, and interaction via Polkadot Remix IDE. | -| [Deploy an NFT to Polkadot Hub](/smart-contracts/cookbook/smart-contracts/deploy-nft/nft-remix/) | 🟢 Beginner | EVM Wallet, Polkadot Remix IDE | Deploy an NFT on Polkadot Hub using PolkaVM and OpenZeppelin. Learn how to compile, deploy, and interact with your contract using Polkadot Remix IDE. | - -## Port Ethereum DApps - -| Title | Difficulty | Tools | Description | -|-------------------------------------------------------------------------------------|:---------------:|---------|----------------------------------------------------------------------------------------------------------------------------------| -| [Deploying Uniswap V2 on Polkadot](/smart-contracts/cookbook/eth-dapps/uniswap-v2/) | 🟡 Intermediate | Hardhat | Learn how to deploy and test Uniswap V2 on Polkadot Hub using Hardhat, bringing AMM-based token swaps to the Polkadot ecosystem. | - - ---- - -Page Title: Smart Contracts Overview - -- Source (raw): https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/smart-contracts-overview.md -- Canonical (HTML): https://docs.polkadot.com/smart-contracts/overview/ -- Summary: Learn about smart contract development on Polkadot Hub with native PolkaVM support, dual-VM execution, and seamless cross-chain capabilities. - -# Smart Contracts on Polkadot Hub - -## Introduction - -Polkadot Hub provides a production-ready smart contract platform that combines Ethereum compatibility with the performance and cross-chain capabilities of the Polkadot ecosystem. Developers can deploy smart contracts directly on Polkadot Hub while using familiar Ethereum tooling, workflows, and programming languages. - -Built with a dual-VM approach, Polkadot Hub offers two execution backends: REVM for unmodified EVM compatibility and native PolkaVM for optimized computationally expensive workloads. This dual-VM architecture enables developers to migrate existing Ethereum contracts instantly or optimize for speed and efficiency with native execution. - -## Why Build on Polkadot Hub - -### Ethereum Compatibility - -Deploy existing Ethereum contracts with zero modifications while maintaining full compatibility with your existing development stack: - -- **Complete JSON-RPC API support**: Use MetaMask, Hardhat, Remix, Foundry, and all standard Ethereum tooling. -- **Standard libraries**: Integrate Ethers.js, Web3.js, Viem, Wagmi, and Web3.py without changes. -- **Solidity development**: Write contracts in Solidity or migrate existing code directly. -- **Familiar workflows**: Maintain your existing deployment, testing, and monitoring processes. - -### Performance Options - -Choose between two execution backends: - -- **REVM**: Run unmodified Ethereum contracts with full EVM/Ethereum compatibility. -- **PolkaVM**: Compile to optimized RISC-V bytecode for enhanced performance and lower fees while keeping Ethereum-compatibility. - -Both backends share the same RPC interface and tooling support, allowing seamless transitions. In addition, smart contracts can interact with Polkadot native services via [precompile contracts](/smart-contracts/precompiles/){target=\_blank}. - -### Cross-VM & Cross-Chain Capabilities - -Smart contracts written for one VM (for example, EVM) can interact directly with other smart contracts written for the RISC-V PolkaVM, and back. This allows to use full EVM compatible contracts but extend to heavy/complex execution workloads to the PolkaVM RISC-V backend. - -Furthermore, all smart contracts in Polkadot Hub can interact with any service in the Polkadot ecosystem through [XCM](/smart-contracts/precompiles/xcm/){target=\_blank}, enabling token transfers, remote execution, and cross-chain composability without bridges or intermediaries. - -## Other Smart Contract Environments - -Beyond Polkadot Hub's native PolkaVM support, the ecosystem offers two main alternatives for smart contract development: - -- **EVM-compatible parachains**: Provide access to Ethereum's extensive developer ecosystem, smart contract portability, and established tooling like Hardhat, Remix, Foundry, and OpenZeppelin. The main options include Moonbeam (the first full Ethereum-compatible parachain serving as an interoperability hub), Astar (featuring dual VM support for both EVM and WebAssembly contracts), and Acala (DeFi-focused with enhanced Acala EVM+ offering advanced DeFi primitives). - -- **Rust (ink!)**: ink! is a Rust-based framework that can compile to PolkaVM. It uses [`#[ink(...)]`](https://use.ink/docs/v6/macros-attributes/){target=\_blank} attribute macros to create Polkadot SDK-compatible PolkaVM bytecode, offering strong memory safety from Rust, an advanced type system, high-performance PolkaVM execution, and platform independence with sandboxed security. - -## Next Steps - -
- -- Guide __Get Started__ - - --- - - Quick-start guides for connecting, deploying, and building your first smart contract. - - [:octicons-arrow-right-24: Get Started](/smart-contracts/get-started/) - -- Guide __Cookbook__ - - --- - - Step-by-step tutorials for deploying contracts, tokens, NFTs, and full dApps. - - [:octicons-arrow-right-24: View Tutorials](/smart-contracts/cookbook/) - -- Guide __Ethereum Developers__ - - --- - - Understand key differences in accounts, fees, gas model, and deployment on Polkadot Hub. - - [:octicons-arrow-right-24: Learn More](/smart-contracts/for-eth-devs/accounts/) - -- Guide __Precompiles__ - - --- - - Discover advanced functionalities including XCM for cross-chain interactions. - - [:octicons-arrow-right-24: Explore Precompiles](/smart-contracts/precompiles/) - -
- - ---- - -Page Title: Technical Reference Overview - -- Source (raw): https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/reference.md -- Canonical (HTML): https://docs.polkadot.com/reference/ -- Summary: Learn about Polkadot's technical architecture, governance framework, parachain ecosystem, and the tools you need to build and interact with the network. - -## Introduction - -The Technical Reference section provides comprehensive documentation of Polkadot's architecture, core concepts, and development tooling. Whether you're exploring how Polkadot's relay chain coordinates parachains, understanding governance mechanisms, or building applications on the network, this reference covers the technical foundations you need. - -Polkadot is a multi-chain network that enables diverse, interconnected blockchains to share security and communicate seamlessly. Understanding how these components interact from the [relay chain](/polkadot-protocol/glossary#relay-chain){target=\_blank} that validates [parachains](/polkadot-protocol/glossary#parachain){target=\_blank} to the [governance](/reference/glossary#governance){target=\_blank} mechanisms that evolve the protocol is essential for developers, validators, and network participants. - -This guide organizes technical documentation across five core areas: Polkadot Hub, Parachains, On-Chain Governance, Glossary, and Tools, each providing detailed information on different aspects of the Polkadot ecosystem. - -## Polkadot Hub - -[Polkadot Hub](/reference/polkadot-hub/){target=\_blank} is the entry point to Polkadot for all users and application developers. It provides access to essential Web3 services, including smart contracts, staking, governance, identity management, and cross-ecosystem interoperability—without requiring you to deploy or manage a parachain. - -The Hub encompasses a set of core functionality that enables developers and users to build and interact with applications on Polkadot. Key capabilities include: - -- **Smart contracts**: Deploy Ethereum-compatible smart contracts and build decentralized applications. -- **Assets and tokens**: Create, manage, and transfer fungible tokens and NFTs across the ecosystem. -- **Staking**: Participate in network security and earn rewards by staking DOT. -- **Governance**: Vote on proposals and participate in Polkadot's decentralized decision-making through OpenGov. -- **Identity services**: Register and manage on-chain identities, enabling access to governance roles and network opportunities. -- **Cross-chain interoperability**: Leverage XCM messaging to interact securely with other chains in the Polkadot ecosystem. -- **Collectives and DAOs**: Participate in governance collectives and decentralized autonomous organizations. - -## Parachains - -[Parachains](/reference/parachains/){target=\_blank} are specialized blockchains that connect to the Polkadot relay chain, inheriting its security while maintaining their own application-specific logic. The parachains documentation covers: - -- **Accounts**: Deep dive into account types, storage, and management on parachains. -- **Blocks, transactions and fees**: Understand block production, transaction inclusion, and fee mechanisms. -- **Consensus**: Learn how parachain blocks are validated and finalized through the relay chain's consensus. -- **Chain data**: Explore data structures, storage layouts, and state management. -- **Cryptography**: Study cryptographic primitives used in Polkadot SDK-based chains. -- **Data encoding**: Understand how data is encoded and decoded for blockchain compatibility. -- **Networks**: Learn about networking protocols and peer-to-peer communication. -- **Interoperability**: Discover [Cross-Consensus Messaging (XCM)](/parachains/interoperability/get-started/){target=\_blank}, the standard for cross-chain communication. -- **Randomness**: Understand how randomness is generated and used in Polkadot chains. -- **Node and runtime**: Learn about parachain nodes, runtime environments, and the [Polkadot SDK](https://github.com/paritytech/polkadot-sdk){target=\_blank}. - -## On-Chain Governance - -[On-Chain governance](/reference/governance/){target=\_blank} is the decentralized decision-making mechanism for the Polkadot network. It manages the evolution and modification of the network's runtime logic, enabling community oversight and approval for proposed changes. The governance documentation details: - -- **OpenGov framework**: Understand Polkadot's next-generation governance system with enhanced delegation, flexible tracks, and simultaneous referendums. -- **Origins and tracks**: Learn how governance proposals are categorized, prioritized, and executed based on their privilege level and complexity. -- **Voting and delegation**: Explore conviction voting, vote delegation, and how token holders participate in governance. -- **Governance evolution**: See how Polkadot's governance has evolved from Governance V1 to the current OpenGov system. - -## Glossary - -The [Glossary](/reference/glossary/){target=\_blank} provides quick-reference definitions for Polkadot-specific terminology. Essential terms include: - -- Blockchain concepts (blocks, transactions, state) -- Consensus mechanisms (validators, collators, finality) -- Polkadot-specific terms (relay chain, parachain, XCM, FRAME) -- Network components (nodes, runtimes, storage) -- Governance terminology (origins, tracks, referendums) - -## Tools - -The [Tools](/reference/tools/){target=\_blank} section documents essential development and interaction tools for the Polkadot ecosystem: - -- **Light clients**: Lightweight solutions for interacting with the network without running full nodes. -- **JavaScript/TypeScript tools**: Libraries like [Polkadot.js API](/reference/tools/polkadot-js-api/){target=\_blank} and [PAPI](/reference/tools/papi/){target=\_blank} for building applications. -- **Rust tools**: [Polkadart](/reference/tools/polkadart/){target=\_blank} and other Rust-based libraries for SDK development. -- **Python tools**: [py-substrate-interface](/reference/tools/py-substrate-interface/){target=\_blank} for Python developers. -- **Testing and development**: Tools like [Moonwall](/reference/tools/moonwall/){target=\_blank}, [Chopsticks](/reference/tools/chopsticks/){target=\_blank}, and [Omninode](/reference/tools/omninode/){target=\_blank} for smart contract and parachain testing. -- **Indexing and monitoring**: [Sidecar](/reference/tools/sidecar/){target=\_blank} for data indexing and [Dedot](/reference/tools/dedot/){target=\_blank} for substrate interaction. -- **Cross-chain tools**: [ParaSpell](/reference/tools/paraspell/){target=\_blank} for XCM integration and asset transfers. - -## Where to Go Next - -For detailed exploration of specific areas, proceed to any of the main sections: - -
- -- Learn **Polkadot Hub** - - --- - - Understand the relay chain's role in coordinating parachains, providing shared security, and enabling governance. - - [:octicons-arrow-right-24: Reference](/reference/polkadot-hub/) - -- Learn **Parachains** - - --- - - Deep dive into parachain architecture, consensus, data structures, and building application-specific blockchains. - - [:octicons-arrow-right-24: Reference](/reference/parachains/) - -- Learn **On-Chain Governance** - - --- - - Explore Polkadot's decentralized governance framework and how to participate in network decision-making. - - [:octicons-arrow-right-24: Reference](/reference/governance/) - -- Guide **Glossary** - - --- - - Quick reference for Polkadot-specific terminology and concepts used throughout the documentation. - - [:octicons-arrow-right-24: Reference](/reference/glossary/) - -- Guide **Tools** - - --- - - Discover development tools, libraries, and frameworks for building and interacting with Polkadot. - - [:octicons-arrow-right-24: Reference](/reference/tools/) - -
- - ---- - -Page Title: Transactions - -- Source (raw): https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/reference-parachains-blocks-transactions-fees-transactions.md -- Canonical (HTML): https://docs.polkadot.com/reference/parachains/blocks-transactions-fees/transactions/ -- Summary: Learn how to construct, submit, and validate transactions in the Polkadot SDK, covering signed, unsigned, and inherent types of transactions. - -# Transactions - -## Introduction - -Transactions are essential components of blockchain networks, enabling state changes and the execution of key operations. In the Polkadot SDK, transactions, often called extrinsics, come in multiple forms, including signed, unsigned, and inherent transactions. - -This guide walks you through the different transaction types and how they're formatted, validated, and processed within the Polkadot ecosystem. You'll also learn how to customize transaction formats and construct transactions for FRAME-based runtimes, ensuring a complete understanding of how transactions are built and executed in Polkadot SDK-based chains. - -## What Is a Transaction? - -In the Polkadot SDK, transactions represent operations that modify the chain's state, bundled into blocks for execution. The term extrinsic is often used to refer to any data that originates outside the runtime and is included in the chain. While other blockchain systems typically refer to these operations as "transactions," the Polkadot SDK adopts the broader term "extrinsic" to capture the wide variety of data types that can be added to a block. - -There are three primary types of transactions (extrinsics) in the Polkadot SDK: - -- **Signed transactions**: Signed by the submitting account, often carrying transaction fees. -- **Unsigned transactions**: Submitted without a signature, often requiring custom validation logic. -- **Inherent transactions**: Typically inserted directly into blocks by block authoring nodes, without gossiping between peers. - -Each type serves a distinct purpose, and understanding when and how to use each is key to efficiently working with the Polkadot SDK. - -### Signed Transactions - -Signed transactions require an account's signature and typically involve submitting a request to execute a runtime call. The signature serves as a form of cryptographic proof that the sender has authorized the action, using their private key. These transactions often involve a transaction fee to cover the cost of execution and incentivize block producers. - -Signed transactions are the most common type of transaction and are integral to user-driven actions, such as token transfers. For instance, when you transfer tokens from one account to another, the sending account must sign the transaction to authorize the operation. - -For example, the [`pallet_balances::Call::transfer_allow_death`](https://paritytech.github.io/polkadot-sdk/master/pallet_balances/pallet/struct.Pallet.html#method.transfer_allow_death){target=\_blank} extrinsic in the Balances pallet allows you to transfer tokens. Since your account initiates this transaction, your account key is used to sign it. You'll also be responsible for paying the associated transaction fee, with the option to include an additional tip to incentivize faster inclusion in the block. - -### Unsigned Transactions - -Unsigned transactions do not require a signature or account-specific data from the sender. Unlike signed transactions, they do not come with any form of economic deterrent, such as fees, which makes them susceptible to spam or replay attacks. Custom validation logic must be implemented to mitigate these risks and ensure these transactions are secure. - -Unsigned transactions typically involve scenarios where including a fee or signature is unnecessary or counterproductive. However, due to the absence of fees, they require careful validation to protect the network. For example, [`pallet_im_online::Call::heartbeat`](https://paritytech.github.io/polkadot-sdk/master/pallet_im_online/pallet/struct.Pallet.html#method.heartbeat){target=\_blank} extrinsic allows validators to send a heartbeat signal, indicating they are active. Since only validators can make this call, the logic embedded in the transaction ensures that the sender is a validator, making the need for a signature or fee redundant. - -Unsigned transactions are more resource-intensive than signed ones because custom validation is required, but they play a crucial role in certain operational scenarios, especially when regular user accounts aren't involved. - -### Inherent Transactions - -Inherent transactions are a specialized type of unsigned transaction that is used primarily for block authoring. Unlike signed or other unsigned transactions, inherent transactions are added directly by block producers and are not broadcasted to the network or stored in the transaction queue. They don't require signatures or the usual validation steps and are generally used to insert system-critical data directly into blocks. - -A key example of an inherent transaction is inserting a timestamp into each block. The [`pallet_timestamp::Call::now`](https://paritytech.github.io/polkadot-sdk/master/pallet_timestamp/pallet/struct.Pallet.html#method.now-1){target=\_blank} extrinsic allows block authors to include the current time in the block they are producing. Since the block producer adds this information, there is no need for transaction validation, like signature verification. The validation in this case is done indirectly by the validators, who check whether the timestamp is within an acceptable range before finalizing the block. - -Another example is the [`paras_inherent::Call::enter`](https://paritytech.github.io/polkadot-sdk/master/polkadot_runtime_parachains/paras_inherent/pallet/struct.Pallet.html#method.enter){target=\_blank} extrinsic, which enables parachain collator nodes to send validation data to the relay chain. This inherent transaction ensures that the necessary parachain data is included in each block without the overhead of gossiped transactions. - -Inherent transactions serve a critical role in block authoring by allowing important operational data to be added directly to the chain without needing the validation processes required for standard transactions. - -## Transaction Formats - -Understanding the structure of signed and unsigned transactions is crucial for developers building on Polkadot SDK-based chains. Whether you're optimizing transaction processing, customizing formats, or interacting with the transaction pool, knowing the format of extrinsics, Polkadot's term for transactions, is essential. - -### Types of Transaction Formats - -In Polkadot SDK-based chains, extrinsics can fall into three main categories: - -- **Unchecked extrinsics**: Typically used for signed transactions that require validation. They contain a signature and additional data, such as a nonce and information for fee calculation. Unchecked extrinsics are named as such because they require validation checks before being accepted into the transaction pool. -- **Checked extrinsics**: Typically used for inherent extrinsics (unsigned transactions); these don't require signature verification. Instead, they carry information such as where the extrinsic originates and any additional data required for the block authoring process. -- **Opaque extrinsics**: Used when the format of an extrinsic is not yet fully committed or finalized. They are still decodable, but their structure can be flexible depending on the context. - -### Signed Transaction Data Structure - -A signed transaction typically includes the following components: - -- **Signature**: Verifies the authenticity of the transaction sender. -- **Call**: The actual function or method call the transaction is requesting (for example, transferring funds). -- **Nonce**: Tracks the number of prior transactions sent from the account, helping to prevent replay attacks. -- **Tip**: An optional incentive to prioritize the transaction in block inclusion. -- **Additional data**: Includes details such as spec version, block hash, and genesis hash to ensure the transaction is valid within the correct runtime and chain context. - -Here's a simplified breakdown of how signed transactions are typically constructed in a Polkadot SDK runtime: - -``` code - + + -``` - -Each part of the signed transaction has a purpose, ensuring the transaction's authenticity and context within the blockchain. - -### Signed Extensions - -Polkadot SDK also provides the concept of [signed extensions](https://paritytech.github.io/polkadot-sdk/master/polkadot_sdk_docs/reference_docs/signed_extensions/index.html){target=\_blank}, which allow developers to extend extrinsics with additional data or validation logic before they are included in a block. The [`SignedExtension`](https://paritytech.github.io/try-runtime-cli/sp_runtime/traits/trait.SignedExtension.html){target=\_blank} set helps enforce custom rules or protections, such as ensuring the transaction's validity or calculating priority. - -The transaction queue regularly calls signed extensions to verify a transaction's validity before placing it in the ready queue. This safeguard ensures transactions won't fail in a block. Signed extensions are commonly used to enforce validation logic and protect the transaction pool from spam and replay attacks. - -In FRAME, a signed extension can hold any of the following types by default: - -- **[`AccountId`](https://paritytech.github.io/polkadot-sdk/master/polkadot_sdk_frame/runtime/types_common/type.AccountId.html){target=\_blank}**: To encode the sender's identity. -- **[`Call`](https://paritytech.github.io/polkadot-sdk/master/polkadot_sdk_frame/traits/trait.SignedExtension.html#associatedtype.Call){target=\_blank}**: To encode the pallet call to be dispatched. This data is used to calculate transaction fees. -- **[`AdditionalSigned`](https://paritytech.github.io/polkadot-sdk/master/polkadot_sdk_frame/traits/trait.SignedExtension.html#associatedtype.AdditionalSigned){target=\_blank}**: To handle any additional data to go into the signed payload allowing you to attach any custom logic prior to dispatching a transaction. -- **[`Pre`](https://paritytech.github.io/polkadot-sdk/master/polkadot_sdk_frame/traits/trait.SignedExtension.html#associatedtype.Pre){target=\_blank}**: To encode the information that can be passed from before a call is dispatched to after it gets dispatched. - -Signed extensions can enforce checks like: - -- **[`CheckSpecVersion`](https://paritytech.github.io/polkadot-sdk/master/src/frame_system/extensions/check_spec_version.rs.html){target=\_blank}**: Ensures the transaction is compatible with the runtime's current version. -- **[`CheckWeight`](https://paritytech.github.io/polkadot-sdk/master/frame_system/struct.CheckWeight.html){target=\_blank}**: Calculates the weight (or computational cost) of the transaction, ensuring the block doesn't exceed the maximum allowed weight. - -These extensions are critical in the transaction lifecycle, ensuring that only valid and prioritized transactions are processed. - -## Transaction Construction - -Building transactions in the Polkadot SDK involves constructing a payload that can be verified, signed, and submitted for inclusion in a block. Each runtime in the Polkadot SDK has its own rules for validating and executing transactions, but there are common patterns for constructing a signed transaction. - -### Construct a Signed Transaction - -A signed transaction in the Polkadot SDK includes various pieces of data to ensure security, prevent replay attacks, and prioritize processing. Here's an overview of how to construct one: - -1. **Construct the unsigned payload**: Gather the necessary information for the call, including: - - - **Pallet index**: Identifies the pallet where the runtime function resides. - - **Function index**: Specifies the particular function to call in the pallet. - - **Parameters**: Any additional arguments required by the function call. - -2. **Create a signing payload**: Once the unsigned payload is ready, additional data must be included: - - - **Transaction nonce**: Unique identifier to prevent replay attacks. - - **Era information**: Defines how long the transaction is valid before it's dropped from the pool. - - **Block hash**: Ensures the transaction doesn't execute on the wrong chain or fork. - -3. **Sign the payload**: Using the sender's private key, sign the payload to ensure that the transaction can only be executed by the account holder. -4. **Serialize the signed payload**: Once signed, the transaction must be serialized into a binary format, ensuring the data is compact and easy to transmit over the network. -5. **Submit the serialized transaction**: Finally, submit the serialized transaction to the network, where it will enter the transaction pool and wait for processing by an authoring node. - -The following is an example of how a signed transaction might look: - -``` rust -node_runtime::UncheckedExtrinsic::new_signed( - function.clone(), // some call - sp_runtime::AccountId32::from(sender.public()).into(), // some sending account - node_runtime::Signature::Sr25519(signature.clone()), // the account's signature - extra.clone(), // the signed extensions -) -``` - -### Transaction Encoding +# Smart Contracts Cookbook -Before a transaction is sent to the network, it is serialized and encoded using a structured encoding process that ensures consistency and prevents tampering: +Welcome to the Polkadot smart contracts cookbook index. -- **`[1]`**: Compact encoded length in bytes of the entire transaction. -- **`[2]`**: A u8 containing 1 byte to indicate whether the transaction is signed or unsigned (1 bit) and the encoded transaction version ID (7 bits). -- **`[3]`**: If signed, this field contains an account ID, an SR25519 signature, and some extra data. -- **`[4]`**: Encoded call data, including pallet and function indices and any required arguments. +This page contains a list of all relevant tutorials and guides to help you get started coding smart contracts and dApps in Polkadot. -This encoded format ensures consistency and efficiency in processing transactions across the network. By adhering to this format, applications can construct valid transactions and pass them to the network for execution. -To learn more about how compact encoding works using SCALE, see the [SCALE Codec](https://github.com/paritytech/parity-scale-codec){target=\_blank} README on GitHub. -### Customize Transaction Construction -Although the basic steps for constructing transactions are consistent across Polkadot SDK-based chains, developers can customize transaction formats and validation rules. For example: +## Get Tokens from the Faucet -- **Custom pallets**: You can define new pallets with custom function calls, each with its own parameters and validation logic. -- **Signed extensions**: Developers can implement custom extensions that modify how transactions are prioritized, validated, or included in blocks. +| Title | Difficulty | Tools | Description | +|------------------------------------|:-----------:|-------|-----------------------------------------------------------------------------------------------------------------------| +| [Faucet](/smart-contracts/faucet/) | 🟢 Beginner | N/A | Learn how to obtain test tokens from Polkadot faucets for development and testing purposes across different networks. | -By leveraging Polkadot SDK's modular design, developers can create highly specialized transaction logic tailored to their chain's needs. +## EVM Smart Contracts -## Lifecycle of a Transaction +| Title | Difficulty | Tools | Description | +|---------------------------------------------------------------------------------------------------------|:-----------:|--------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------| +| [Deploy an ERC-20 to Polkadot Hub](/smart-contracts/cookbook/smart-contracts/deploy-erc20/erc20-remix/) | 🟢 Beginner | EVM Wallet, Polkadot Remix IDE | Deploy an ERC-20 token on Polkadot Hub using PolkaVM. This guide covers contract creation, compilation, deployment, and interaction via Polkadot Remix IDE. | +| [Deploy an NFT to Polkadot Hub](/smart-contracts/cookbook/smart-contracts/deploy-nft/nft-remix/) | 🟢 Beginner | EVM Wallet, Polkadot Remix IDE | Deploy an NFT on Polkadot Hub using PolkaVM and OpenZeppelin. Learn how to compile, deploy, and interact with your contract using Polkadot Remix IDE. | -In the Polkadot SDK, transactions are often referred to as extrinsics because the data in transactions originates outside of the runtime. These transactions contain data that initiates changes to the chain state. The most common type of extrinsic is a signed transaction, which is cryptographically verified and typically incurs a fee. This section focuses on how signed transactions are processed, validated, and ultimately included in a block. +## Port Ethereum DApps -### Define Transaction Properties +| Title | Difficulty | Tools | Description | +|-------------------------------------------------------------------------------------|:---------------:|---------|----------------------------------------------------------------------------------------------------------------------------------| +| [Deploying Uniswap V2 on Polkadot](/smart-contracts/cookbook/eth-dapps/uniswap-v2/) | 🟡 Intermediate | Hardhat | Learn how to deploy and test Uniswap V2 on Polkadot Hub using Hardhat, bringing AMM-based token swaps to the Polkadot ecosystem. | -The Polkadot SDK runtime defines key transaction properties, such as: -- **Transaction validity**: Ensures the transaction meets all runtime requirements. -- **Signed or unsigned**: Identifies whether a transaction needs to be signed by an account. -- **State changes**: Determines how the transaction modifies the state of the chain. +--- -Pallets, which compose the runtime's logic, define the specific transactions that your chain supports. When a user submits a transaction, such as a token transfer, it becomes a signed transaction, verified by the user's account signature. If the account has enough funds to cover fees, the transaction is executed, and the chain's state is updated accordingly. +Page Title: Smart Contracts Overview -### Process on a Block Authoring Node +- Source (raw): https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/smart-contracts-overview.md +- Canonical (HTML): https://docs.polkadot.com/smart-contracts/overview/ +- Summary: Learn about smart contract development on Polkadot Hub with native PolkaVM support, dual-VM execution, and seamless cross-chain capabilities. -In Polkadot SDK-based networks, some nodes are authorized to author blocks. These nodes validate and process transactions. When a transaction is sent to a node that can produce blocks, it undergoes a lifecycle that involves several stages, including validation and execution. Non-authoring nodes gossip the transaction across the network until an authoring node receives it. The following diagram illustrates the lifecycle of a transaction that's submitted to a network and processed by an authoring node. +# Smart Contracts on Polkadot Hub -![Transaction lifecycle diagram](/images/reference/parachains/blocks-transactions-fees/transactions/transactions-01.webp){ style="background:white" } +## Introduction -### Validate and Queue +Polkadot Hub provides a production-ready smart contract platform that combines Ethereum compatibility with the performance and cross-chain capabilities of the Polkadot ecosystem. Developers can deploy smart contracts directly on Polkadot Hub while using familiar Ethereum tooling, workflows, and programming languages. -Once a transaction reaches an authoring node, it undergoes an initial validation process to ensure it meets specific conditions defined in the runtime. This validation includes checks for: +Built with a dual-VM approach, Polkadot Hub offers two execution backends: REVM for unmodified EVM compatibility and native PolkaVM for optimized computationally expensive workloads. This dual-VM architecture enables developers to migrate existing Ethereum contracts instantly or optimize for speed and efficiency with native execution. -- **Correct nonce**: Ensures the transaction is sequentially valid for the account. -- **Sufficient funds**: Confirms the account can cover any associated transaction fees. -- **Signature validity**: Verifies that the sender's signature matches the transaction data. +## Why Build on Polkadot Hub -After these checks, valid transactions are placed in the transaction pool, where they are queued for inclusion in a block. The transaction pool regularly re-validates queued transactions to ensure they remain valid before being processed. To reach consensus, two-thirds of the nodes must agree on the order of the transactions executed and the resulting state change. Transactions are validated and queued on the local node in a transaction pool to prepare for consensus. +### Ethereum Compatibility -#### Transaction Pool +Deploy existing Ethereum contracts with zero modifications while maintaining full compatibility with your existing development stack: -The transaction pool is responsible for managing valid transactions. It ensures that only transactions that pass initial validity checks are queued. Transactions that fail validation, expire, or become invalid for other reasons are removed from the pool. +- **Complete JSON-RPC API support**: Use MetaMask, Hardhat, Remix, Foundry, and all standard Ethereum tooling. +- **Standard libraries**: Integrate Ethers.js, Web3.js, Viem, Wagmi, and Web3.py without changes. +- **Solidity development**: Write contracts in Solidity or migrate existing code directly. +- **Familiar workflows**: Maintain your existing deployment, testing, and monitoring processes. -The transaction pool organizes transactions into two queues: +### Performance Options -- **Ready queue**: Transactions that are valid and ready to be included in a block. -- **Future queue**: Transactions that are not yet valid but could be in the future, such as transactions with a nonce too high for the current state. +Choose between two execution backends: -Details on how the transaction pool validates transactions, including fee and signature handling, can be found in the [`validate_transaction`](https://paritytech.github.io/polkadot-sdk/master/sp_transaction_pool/runtime_api/trait.TaggedTransactionQueue.html#method.validate_transaction){target=\_blank} method. +- **REVM**: Run unmodified Ethereum contracts with full EVM/Ethereum compatibility. +- **PolkaVM**: Compile to optimized RISC-V bytecode for enhanced performance and lower fees while keeping Ethereum-compatibility. -#### Invalid Transactions +Both backends share the same RPC interface and tooling support, allowing seamless transitions. In addition, smart contracts can interact with Polkadot native services via [precompile contracts](/smart-contracts/precompiles/){target=\_blank}. -If a transaction is invalid, for example, due to an invalid signature or insufficient funds, it is rejected and won't be added to the block. Invalid transactions might be rejected for reasons such as: +### Cross-VM & Cross-Chain Capabilities -- The transaction has already been included in a block. -- The transaction's signature does not match the sender. -- The transaction is too large to fit in the current block. +Smart contracts written for one VM (for example, EVM) can interact directly with other smart contracts written for the RISC-V PolkaVM, and back. This allows to use full EVM compatible contracts but extend to heavy/complex execution workloads to the PolkaVM RISC-V backend. -### Transaction Ordering and Priority +Furthermore, all smart contracts in Polkadot Hub can interact with any service in the Polkadot ecosystem through [XCM](/smart-contracts/precompiles/xcm/){target=\_blank}, enabling token transfers, remote execution, and cross-chain composability without bridges or intermediaries. -When a node is selected as the next block author, it prioritizes transactions based on weight, length, and tip amount. The goal is to fill the block with high-priority transactions without exceeding its maximum size or computational limits. Transactions are ordered as follows: +## Other Smart Contract Environments -- **Inherents first**: Inherent transactions, such as block timestamp updates, are always placed first. -- **Nonce-based ordering**: Transactions from the same account are ordered by their nonce. -- **Fee-based ordering**: Among transactions with the same nonce or priority level, those with higher fees are prioritized. +Beyond Polkadot Hub's native PolkaVM support, the ecosystem offers two main alternatives for smart contract development: -### Transaction Execution +- **EVM-compatible parachains**: Provide access to Ethereum's extensive developer ecosystem, smart contract portability, and established tooling like Hardhat, Remix, Foundry, and OpenZeppelin. The main options include Moonbeam (the first full Ethereum-compatible parachain serving as an interoperability hub), Astar (featuring dual VM support for both EVM and WebAssembly contracts), and Acala (DeFi-focused with enhanced Acala EVM+ offering advanced DeFi primitives). -Once a block author selects transactions from the pool, the transactions are executed in priority order. As each transaction is processed, the state changes are written directly to the chain's storage. It's important to note that these changes are not cached, meaning a failed transaction won't revert earlier state changes, which could leave the block in an inconsistent state. +- **Rust (ink!)**: ink! is a Rust-based framework that can compile to PolkaVM. It uses [`#[ink(...)]`](https://use.ink/docs/v6/macros-attributes/){target=\_blank} attribute macros to create Polkadot SDK-compatible PolkaVM bytecode, offering strong memory safety from Rust, an advanced type system, high-performance PolkaVM execution, and platform independence with sandboxed security. -Events are also written to storage. Runtime logic should not emit an event before performing the associated actions. If the associated transaction fails after the event was emitted, the event will not revert. +## Next Steps -## Transaction Mortality +
-Transactions in the network can be configured as either mortal (with expiration) or immortal (without expiration). Every transaction payload contains a block checkpoint (reference block number and hash) and an era/validity period that determines how many blocks after the checkpoint the transaction remains valid. +- Guide __Get Started__ -When a transaction is submitted, the network validates it against these parameters. If the transaction is not included in a block within the specified validity window, it is automatically removed from the transaction queue. + --- -- **Mortal transactions**: Have a finite lifespan and will expire after a specified number of blocks. For example, a transaction with a block checkpoint of 1000 and a validity period of 64 blocks will be valid from blocks 1000 to 1064. + Quick-start guides for connecting, deploying, and building your first smart contract. -- **Immortal transactions**: Never expire and remain valid indefinitely. To create an immortal transaction, set the block checkpoint to 0 (genesis block), use the genesis hash as a reference, and set the validity period to 0. + [:octicons-arrow-right-24: Get Started](/smart-contracts/get-started/) -However, immortal transactions pose significant security risks through replay attacks. If an account is reaped (balance drops to zero, account removed) and later re-funded, malicious actors can replay old immortal transactions. +- Guide __Cookbook__ -The blockchain maintains only a limited number of prior block hashes for reference validation, called `BlockHashCount`. If your validity period exceeds `BlockHashCount`, the effective validity period becomes the minimum of your specified period and the block hash count. + --- -## Unique Identifiers for Extrinsics + Step-by-step tutorials for deploying contracts, tokens, NFTs, and full dApps. -Transaction hashes are **not unique identifiers** in Polkadot SDK-based chains. + [:octicons-arrow-right-24: View Tutorials](/smart-contracts/cookbook/) -Key differences from traditional blockchains: +- Guide __Ethereum Developers__ -- Transaction hashes serve only as fingerprints of transaction information. -- Multiple valid transactions can share the same hash. -- Hash uniqueness assumptions lead to serious issues. + --- -For example, when an account is reaped (removed due to insufficient balance) and later recreated, it resets to nonce 0, allowing identical transactions to be valid at different points: + Understand key differences in accounts, fees, gas model, and deployment on Polkadot Hub. -| Block | Extrinsic Index | Hash | Origin | Nonce | Call | Result | -|-------|----------------|------|-----------|-------|---------------------|-------------------------------| -| 100 | 0 | 0x01 | Account A | 0 | Transfer 5 DOT to B | Account A reaped | -| 150 | 5 | 0x02 | Account B | 4 | Transfer 7 DOT to A | Account A created (nonce = 0) | -| 200 | 2 | 0x01 | Account A | 0 | Transfer 5 DOT to B | Successful transaction | + [:octicons-arrow-right-24: Learn More](/smart-contracts/for-eth-devs/accounts/) -Notice that blocks 100 and 200 contain transactions with identical hashes (0x01) but are completely different, valid operations occurring at different times. +- Guide __Precompiles__ -Additional complexity comes from Polkadot SDK's origin abstraction. Origins can represent collectives, governance bodies, or other non-account entities that don't maintain nonces like regular accounts and might dispatch identical calls multiple times with the same hash values. Each execution occurs in different chain states with different results. + --- -The correct way to uniquely identify an extrinsic on a Polkadot SDK-based chain is to use the block ID (height or hash) and the extrinsic index. Since the Polkadot SDK defines blocks as headers plus ordered arrays of extrinsics, the index position within a canonical block provides guaranteed uniqueness. + Discover advanced functionalities including XCM for cross-chain interactions. -## Additional Resources + [:octicons-arrow-right-24: Explore Precompiles](/smart-contracts/precompiles/) -For a video overview of the lifecycle of transactions and the types of transactions that exist, see the [Transaction lifecycle](https://www.youtube.com/watch?v=3pfM0GOp02c){target=\_blank} seminar from Parity Tech. +
--- @@ -3986,436 +2410,3 @@ The system maintains precise conversion mechanisms between: - Different resource metrics within the multi-dimensional model. This ensures accurate fee calculation while maintaining compatibility with existing Ethereum tools and workflows. - - ---- - -Page Title: Transactions Weights and Fees - -- Source (raw): https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/reference-parachains-blocks-transactions-fees-fees.md -- Canonical (HTML): https://docs.polkadot.com/reference/parachains/blocks-transactions-fees/fees/ -- Summary: Overview of transaction weights and fees in Polkadot SDK chains, detailing how fees are calculated using a defined formula and runtime specifics. - -# Transactions Weights and Fees - -## Introductions - -When transactions are executed, or data is stored on-chain, the activity changes the chain's state and consumes blockchain resources. Because the resources available to a blockchain are limited, managing how operations on-chain consume them is important. In addition to being limited in practical terms, such as storage capacity, blockchain resources represent a potential attack vector for malicious users. For example, a malicious user might attempt to overload the network with messages to stop the network from producing new blocks. To protect blockchain resources from being drained or overloaded, you need to manage how they are made available and how they are consumed. The resources to be aware of include: - -- Memory usage -- Storage input and output -- Computation -- Transaction and block size -- State database size - -The Polkadot SDK provides block authors with several ways to manage access to resources and to prevent individual components of the chain from consuming too much of any single resource. Two of the most important mechanisms available to block authors are weights and transaction fees. - -[Weights](/reference/glossary/#weight){target=\_blank} manage the time it takes to validate a block and characterize the time it takes to execute the calls in the block's body. By controlling the execution time a block can consume, weights set limits on storage input, output, and computation. - -Some of the weight allowed for a block is consumed as part of the block's initialization and finalization. The weight might also be used to execute mandatory inherent extrinsic calls. To help ensure blocks don’t consume too much execution time and prevent malicious users from overloading the system with unnecessary calls, weights are combined with transaction fees. - -[Transaction fees](/reference/parachains/blocks-transactions-fees/transactions/#transaction-fees){target=\_blank} provide an economic incentive to limit execution time, computation, and the number of calls required to perform operations. Transaction fees are also used to make the blockchain economically sustainable because they are typically applied to transactions initiated by users and deducted before a transaction request is executed. - -## How Fees are Calculated - -The final fee for a transaction is calculated using the following parameters: - -- **`base fee`**: This is the minimum amount a user pays for a transaction. It is declared a base weight in the runtime and converted to a fee using the [`WeightToFee`](https://docs.rs/pallet-transaction-payment/latest/pallet_transaction_payment/pallet/trait.Config.html#associatedtype.WeightToFee){target=\_blank} conversion. -- **`weight fee`**: A fee proportional to the execution time (input and output and computation) that a transaction consumes. -- **`length fee`**: A fee proportional to the encoded length of the transaction. -- **`tip`**: An optional tip to increase the transaction’s priority, giving it a higher chance to be included in the transaction queue. - -The base fee and proportional weight and length fees constitute the inclusion fee. The inclusion fee is the minimum fee that must be available for a transaction to be included in a block. - -```text -inclusion fee = base fee + weight fee + length fee -``` - -Transaction fees are withdrawn before the transaction is executed. After the transaction is executed, the weight can be adjusted to reflect the resources used. If a transaction uses fewer resources than expected, the transaction fee is corrected, and the adjusted transaction fee is deposited. - -## Using the Transaction Payment Pallet - -The [Transaction Payment pallet](https://github.com/paritytech/polkadot-sdk/tree/polkadot-stable2506-2/substrate/frame/transaction-payment){target=\_blank} provides the basic logic for calculating the inclusion fee. You can also use the Transaction Payment pallet to: - -- Convert a weight value into a deductible fee based on a currency type using [`Config::WeightToFee`](https://docs.rs/pallet-transaction-payment/latest/pallet_transaction_payment/pallet/trait.Config.html#associatedtype.WeightToFee){target=\_blank}. -- Update the fee for the next block by defining a multiplier based on the chain’s final state at the end of the previous block using [`Config::FeeMultiplierUpdate`](https://docs.rs/pallet-transaction-payment/latest/pallet_transaction_payment/pallet/trait.Config.html#associatedtype.FeeMultiplierUpdate){target=\_blank}. -- Manage the withdrawal, refund, and deposit of transaction fees using [`Config::OnChargeTransaction`](https://docs.rs/pallet-transaction-payment/latest/pallet_transaction_payment/pallet/trait.Config.html#associatedtype.OnChargeTransaction){target=\_blank}. - -You can learn more about these configuration traits in the [Transaction Payment documentation](https://paritytech.github.io/polkadot-sdk/master/pallet_transaction_payment/index.html){target=\_blank}. - -### Understanding the Inclusion Fee - -The formula for calculating the inclusion fee is as follows: - -```text -inclusion_fee = base_fee + length_fee + [targeted_fee_adjustment * weight_fee] -``` - -And then, for calculating the final fee: - -```text -final_fee = inclusion_fee + tip -``` - -In the first formula, the `targeted_fee_adjustment` is a multiplier that can tune the final fee based on the network’s congestion. - -- The `base_fee` derived from the base weight covers inclusion overhead like signature verification. -- The `length_fee` is a per-byte fee that is multiplied by the length of the encoded extrinsic. -- The `weight_fee` fee is calculated using two parameters: - - The `ExtrinsicBaseWeight` that is declared in the runtime and applies to all extrinsics. - - The `#[pallet::weight]` annotation that accounts for an extrinsic's complexity. - -To convert the weight to `Currency`, the runtime must define a `WeightToFee` struct that implements a conversion function, [`Convert`](https://docs.rs/pallet-transaction-payment/latest/pallet_transaction_payment/pallet/struct.Pallet.html#method.weight_to_fee){target=\_blank}. - -Note that the extrinsic sender is charged the inclusion fee before the extrinsic is invoked. The fee is deducted from the sender's balance even if the transaction fails upon execution. - -### Accounts with an Insufficient Balance - -If an account does not have a sufficient balance to pay the inclusion fee and remain alive—that is, enough to pay the inclusion fee and maintain the minimum existential deposit—then you should ensure the transaction is canceled so that no fee is deducted and the transaction does not begin execution. - -The Polkadot SDK doesn't enforce this rollback behavior. However, this scenario would be rare because the transaction queue and block-making logic perform checks to prevent it before adding an extrinsic to a block. - -### Fee Multipliers - -The inclusion fee formula always results in the same fee for the same input. However, weight can be dynamic and—based on how [`WeightToFee`](https://docs.rs/pallet-transaction-payment/latest/pallet_transaction_payment/pallet/trait.Config.html#associatedtype.WeightToFee){target=\_blank} is defined—the final fee can include some degree of variability. -The Transaction Payment pallet provides the [`FeeMultiplierUpdate`](https://docs.rs/pallet-transaction-payment/latest/pallet_transaction_payment/pallet/trait.Config.html#associatedtype.FeeMultiplierUpdate){target=\_blank} configurable parameter to account for this variability. - -The Polkadot network inspires the default update function and implements a targeted adjustment in which a target saturation level of block weight is defined. If the previous block is more saturated, the fees increase slightly. Similarly, if the last block has fewer transactions than the target, fees are decreased by a small amount. For more information about fee multiplier adjustments, see the [Web3 Research Page](https://research.web3.foundation/Polkadot/overview/token-economics#relay-chain-transaction-fees-and-per-block-transaction-limits){target=\_blank}. - -## Transactions with Special Requirements - -Inclusion fees must be computable before execution and can only represent fixed logic. Some transactions warrant limiting resources with other strategies. For example: - -- Bonds are a type of fee that might be returned or slashed after some on-chain event. For example, you might want to require users to place a bond to participate in a vote. The bond might then be returned at the end of the referendum or slashed if the voter attempted malicious behavior. -- Deposits are fees that might be returned later. For example, you might require users to pay a deposit to execute an operation that uses storage. The user’s deposit could be returned if a subsequent operation frees up storage. -- Burn operations are used to pay for a transaction based on its internal logic. For example, a transaction might burn funds from the sender if the transaction creates new storage items to pay for the increased state size. -- Limits enable you to enforce constant or configurable limits on specific operations. For example, the default [Staking pallet](https://github.com/paritytech/polkadot-sdk/tree/polkadot-stable2506-2/substrate/frame/staking){target=\_blank} only allows nominators to nominate 16 validators to limit the complexity of the validator election process. - -It is important to note that if you query the chain for a transaction fee, it only returns the inclusion fee. - -## Default Weight Annotations - -All dispatchable functions in the Polkadot SDK must specify a weight. The way of doing that is using the annotation-based system that lets you combine fixed values for database read/write weight and/or fixed values based on benchmarks. The most basic example would look like this: - -```rust -#[pallet::weight(100_000)] -fn my_dispatchable() { - // ... -} -``` - -Note that the [`ExtrinsicBaseWeight`](https://crates.parity.io/frame_support/weights/constants/struct.ExtrinsicBaseWeight.html){target=\_blank} is automatically added to the declared weight to account for the costs of simply including an empty extrinsic into a block. - -### Weights and Database Read/Write Operations - -To make weight annotations independent of the deployed database backend, they are defined as a constant and then used in the annotations when expressing database accesses performed by the dispatchable: - -```rust -#[pallet::weight(T::DbWeight::get().reads_writes(1, 2) + 20_000)] -fn my_dispatchable() { - // ... -} -``` - -This dispatchable allows one database to read and two to write, in addition to other things that add the additional 20,000. Database access is generally every time a value declared inside the [`#[pallet::storage]`](https://paritytech.github.io/polkadot-sdk/master/frame_support/pallet_macros/attr.storage.html){target=\_blank} block is accessed. However, unique accesses are counted because after a value is accessed, it is cached, and reaccessing it does not result in a database operation. That is: - -- Multiple reads of the exact value count as one read. -- Multiple writes of the exact value count as one write. -- Multiple reads of the same value, followed by a write to that value, count as one read and one write. -- A write followed by a read-only counts as one write. - -### Dispatch Classes - -Dispatches are broken into three classes: - -- Normal -- Operational -- Mandatory - -If a dispatch is not defined as `Operational` or `Mandatory` in the weight annotation, the dispatch is identified as `Normal` by default. You can specify that the dispatchable uses another class like this: - -```rust -#[pallet::dispatch((DispatchClass::Operational))] -fn my_dispatchable() { - // ... -} -``` - -This tuple notation also allows you to specify a final argument determining whether the user is charged based on the annotated weight. If you don't specify otherwise, `Pays::Yes` is assumed: - -```rust -#[pallet::dispatch(DispatchClass::Normal, Pays::No)] -fn my_dispatchable() { - // ... -} -``` - -#### Normal Dispatches - -Dispatches in this class represent normal user-triggered transactions. These types of dispatches only consume a portion of a block's total weight limit. For information about the maximum portion of a block that can be consumed for normal dispatches, see [`AvailableBlockRatio`](https://paritytech.github.io/polkadot-sdk/master/frame_system/limits/struct.BlockLength.html){target=\_blank}. Normal dispatches are sent to the transaction pool. - -#### Operational Dispatches - -Unlike normal dispatches, which represent the usage of network capabilities, operational dispatches are those that provide network capabilities. Operational dispatches can consume the entire weight limit of a block. They are not bound by the [`AvailableBlockRatio`](https://paritytech.github.io/polkadot-sdk/master/frame_system/limits/struct.BlockLength.html){target=\_blank}. Dispatches in this class are given maximum priority and are exempt from paying the [`length_fee`](https://docs.rs/pallet-transaction-payment/latest/pallet_transaction_payment/){target=\_blank}. - -#### Mandatory Dispatches - -Mandatory dispatches are included in a block even if they cause the block to surpass its weight limit. You can only use the mandatory dispatch class for inherent transactions that the block author submits. This dispatch class is intended to represent functions in the block validation process. Because these dispatches are always included in a block regardless of the function weight, the validation process must prevent malicious nodes from abusing the function to craft valid but impossibly heavy blocks. You can typically accomplish this by ensuring that: - -- The operation performed is always light. -- The operation can only be included in a block once. - -To make it more difficult for malicious nodes to abuse mandatory dispatches, they cannot be included in blocks that return errors. This dispatch class serves the assumption that it is better to allow an overweight block to be created than not to allow any block to be created at all. - -### Dynamic Weights - -In addition to purely fixed weights and constants, the weight calculation can consider the input arguments of a dispatchable. The weight should be trivially computable from the input arguments with some basic arithmetic: - -```rust -use frame_support:: { - dispatch:: { - DispatchClass::Normal, - Pays::Yes, - }, - weights::Weight, -}; - -#[pallet::weight(FunctionOf( - |args: (&Vec,)| args.0.len().saturating_mul(10_000), - ) -] -fn handle_users(origin, calls: Vec) { - // Do something per user -} -``` - -## Post Dispatch Weight Correction - -Depending on the execution logic, a dispatchable function might consume less weight than was prescribed pre-dispatch. To correct weight, the function declares a different return type and returns its actual weight: - -```rust -#[pallet::weight(10_000 + 500_000_000)] -fn expensive_or_cheap(input: u64) -> DispatchResultWithPostInfo { - let was_heavy = do_calculation(input); - - if (was_heavy) { - // None means "no correction" from the weight annotation. - Ok(None.into()) - } else { - // Return the actual weight consumed. - Ok(Some(10_000).into()) - } -} -``` - -## Custom Fees - -You can also define custom fee systems through custom weight functions or inclusion fee functions. - -### Custom Weights - -Instead of using the default weight annotations, you can create a custom weight calculation type using the weights module. The custom weight calculation type must implement the following traits: - -- [`WeighData`](https://crates.parity.io/frame_support/weights/trait.WeighData.html){target=\_blank} to determine the weight of the dispatch. -- [`ClassifyDispatch`](https://crates.parity.io/frame_support/weights/trait.ClassifyDispatch.html){target=\_blank} to determine the class of the dispatch. -- [`PaysFee`](https://crates.parity.io/frame_support/weights/trait.PaysFee.html){target=\_blank} to determine whether the sender of the dispatch pays fees. - -The Polkadot SDK then bundles the output information of the three traits into the [`DispatchInfo`](https://paritytech.github.io/polkadot-sdk/master/frame_support/dispatch/struct.DispatchInfo.html){target=\_blank} struct and provides it by implementing the [`GetDispatchInfo`](https://docs.rs/frame-support/latest/frame_support/dispatch/trait.GetDispatchInfo.html){target=\_blank} for all `Call` variants and opaque extrinsic types. This is used internally by the System and Executive modules. - -`ClassifyDispatch`, `WeighData`, and `PaysFee` are generic over T, which gets resolved into the tuple of all dispatch arguments except for the origin. The following example illustrates a struct that calculates the weight as `m * len(args)`, where `m` is a given multiplier and args is the concatenated tuple of all dispatch arguments. In this example, the dispatch class is `Operational` if the transaction has more than 100 bytes of length in arguments and will pay fees if the encoded length exceeds 10 bytes. - -```rust -struct LenWeight(u32); -impl WeighData for LenWeight { - fn weigh_data(&self, target: T) -> Weight { - let multiplier = self.0; - let encoded_len = target.encode().len() as u32; - multiplier * encoded_len - } -} - -impl ClassifyDispatch for LenWeight { - fn classify_dispatch(&self, target: T) -> DispatchClass { - let encoded_len = target.encode().len() as u32; - if encoded_len > 100 { - DispatchClass::Operational - } else { - DispatchClass::Normal - } - } -} - -impl PaysFee { - fn pays_fee(&self, target: T) -> Pays { - let encoded_len = target.encode().len() as u32; - if encoded_len > 10 { - Pays::Yes - } else { - Pays::No - } - } -} -``` - -A weight calculator function can also be coerced to the final type of the argument instead of defining it as a vague type that can be encoded. The code would roughly look like this: - -```rust -struct CustomWeight; -impl WeighData<(&u32, &u64)> for CustomWeight { - fn weigh_data(&self, target: (&u32, &u64)) -> Weight { - ... - } -} - -// given a dispatch: -#[pallet::call] -impl, I: 'static> Pallet { - #[pallet::weight(CustomWeight)] - fn foo(a: u32, b: u64) { ... } -} -``` - -In this example, the `CustomWeight` can only be used in conjunction with a dispatch with a particular signature `(u32, u64)`, as opposed to `LenWeight`, which can be used with anything because there aren't any assumptions about ``. - -#### Custom Inclusion Fee - -The following example illustrates how to customize your inclusion fee. You must configure the appropriate associated types in the respective module. - -```rust -// Assume this is the balance type -type Balance = u64; - -// Assume we want all the weights to have a `100 + 2 * w` conversion to fees -struct CustomWeightToFee; -impl WeightToFee for CustomWeightToFee { - fn convert(w: Weight) -> Balance { - let a = Balance::from(100); - let b = Balance::from(2); - let w = Balance::from(w); - a + b * w - } -} - -parameter_types! { - pub const ExtrinsicBaseWeight: Weight = 10_000_000; -} - -impl frame_system::Config for Runtime { - type ExtrinsicBaseWeight = ExtrinsicBaseWeight; -} - -parameter_types! { - pub const TransactionByteFee: Balance = 10; -} - -impl transaction_payment::Config { - type TransactionByteFee = TransactionByteFee; - type WeightToFee = CustomWeightToFee; - type FeeMultiplierUpdate = TargetedFeeAdjustment; -} - -struct TargetedFeeAdjustment(sp_std::marker::PhantomData); -impl> WeightToFee for TargetedFeeAdjustment { - fn convert(multiplier: Fixed128) -> Fixed128 { - // Don't change anything. Put any fee update info here. - multiplier - } -} -``` - -## Additional Resources - -You now know the weight system, how it affects transaction fee computation, and how to specify weights for your dispatchable calls. The next step is determining the correct weight for your dispatchable operations. You can use Substrate benchmarking functions and frame-benchmarking calls to test your functions with different parameters and empirically determine the proper weight in their worst-case scenarios. - -- [Benchmark](/parachains/customize-runtime/pallet-development/benchmark-pallet/) -- [`SignedExtension`](https://paritytech.github.io/polkadot-sdk/master/sp_runtime/traits/trait.SignedExtension.html){target=\_blank} -- [Custom weights for the Example pallet](https://github.com/paritytech/polkadot-sdk/blob/polkadot-stable2506-2/substrate/frame/examples/basic/src/weights.rs){target=\_blank} -- [Web3 Foundation Research](https://research.web3.foundation/Polkadot/overview/token-economics#relay-chain-transaction-fees-and-per-block-transaction-limits){target=\_blank} - - ---- - -Page Title: XCM Tools - -- Source (raw): https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/reference-tools-xcm-tools.md -- Canonical (HTML): https://docs.polkadot.com/reference/tools/xcm-tools/ -- Summary: Explore essential XCM tools across Polkadot, crafted to enhance cross-chain functionality and integration within the ecosystem. - -# XCM Tools - -## Introduction - -As described in the [Interoperability](/develop/interoperability){target=\_blank} section, XCM (Cross-Consensus Messaging) is a protocol used in the Polkadot and Kusama ecosystems to enable communication and interaction between chains. It facilitates cross-chain communication, allowing assets, data, and messages to flow seamlessly across the ecosystem. - -As XCM is central to enabling communication between blockchains, developers need robust tools to help interact with, build, and test XCM messages. Several XCM tools simplify working with the protocol by providing libraries, frameworks, and utilities that enhance the development process, ensuring that applications built within the Polkadot ecosystem can efficiently use cross-chain functionalities. - -## Popular XCM Tools - -### Moonsong Labs XCM Tools - -[Moonsong Labs XCM Tools](https://github.com/Moonsong-Labs/xcm-tools){target=\_blank} provides a collection of scripts for managing and testing XCM operations between Polkadot SDK-based runtimes. These tools allow performing tasks like asset registration, channel setup, and XCM initialization. Key features include: - -- **Asset registration**: Registers assets, setting units per second (up-front fees), and configuring error (revert) codes. -- **XCM initializer**: Initializes XCM, sets default XCM versions, and configures revert codes for XCM-related precompiles. -- **HRMP manipulator**: Manages HRMP channel actions, including opening, accepting, or closing channels. -- **XCM-Transactor-Info-Setter**: Configures transactor information, including extra weight and fee settings. -- **Decode XCM**: Decodes XCM messages on the relay chain or parachains to help interpret cross-chain communication. - -To get started, clone the repository and install the required dependencies: - -```bash -git clone https://github.com/Moonsong-Labs/xcm-tools && -cd xcm-tools && -yarn install -``` - -For a full overview of each script, visit the [scripts](https://github.com/Moonsong-Labs/xcm-tools/tree/main/scripts){target=\_blank} directory or refer to the [official documentation](https://github.com/Moonsong-Labs/xcm-tools/blob/main/README.md){target=\_blank} on GitHub. - -### ParaSpell - -[ParaSpell](/reference/tools/paraspell/){target=\_blank} is a collection of open-source XCM tools that streamline cross-chain asset transfers and interactions across the Polkadot and Kusama ecosystems. It provides developers with an intuitive interface to build, test, and deploy interoperable dApps, featuring message composition, decoding, and practical utilities for parachain interactions that simplify debugging and cross-chain communication optimization. - -### Astar XCM Tools - -The [Astar parachain](https://github.com/AstarNetwork/Astar/tree/master){target=\_blank} offers a crate with a set of utilities for interacting with the XCM protocol. The [xcm-tools](https://github.com/AstarNetwork/Astar/tree/master/bin/xcm-tools){target=\_blank} crate provides a straightforward method for users to locate a sovereign account or calculate an XC20 asset ID. Some commands included by the xcm-tools crate allow users to perform the following tasks: - -- **Sovereign accounts**: Obtain the sovereign account address for any parachain, either on the Relay Chain or for sibling parachains, using a simple command. -- **XC20 EVM addresses**: Generate XC20-compatible Ethereum addresses for assets by entering the asset ID, making it easy to integrate assets across Ethereum-compatible environments. -- **Remote accounts**: Retrieve remote account addresses needed for multi-location compatibility, using flexible options to specify account types and parachain IDs. - -To start using these tools, clone the [Astar repository](https://github.com/AstarNetwork/Astar){target=\_blank} and compile the xcm-tools package: - -```bash -git clone https://github.com/AstarNetwork/Astar && -cd Astar && -cargo build --release -p xcm-tools -``` - -After compiling, verify the setup with the following command: - -```bash -./target/release/xcm-tools --help -``` -For more details on using Astar xcm-tools, consult the [official documentation](https://docs.astar.network/docs/learn/interoperability/xcm/integration/tools/){target=\_blank}. - -### Chopsticks - -The Chopsticks library provides XCM functionality for testing XCM messages across networks, enabling you to fork multiple parachains along with a relay chain. For further details, see the [Chopsticks documentation](/tutorials/polkadot-sdk/testing/fork-live-chains/){target=\_blank} about XCM. - -### Moonbeam XCM SDK - -The [Moonbeam XCM SDK](https://github.com/moonbeam-foundation/xcm-sdk){target=\_blank} enables developers to easily transfer assets between chains, either between parachains or between a parachain and the relay chain, within the Polkadot/Kusama ecosystem. With the SDK, you don't need to worry about determining the [Multilocation](https://github.com/polkadot-fellows/xcm-format?tab=readme-ov-file#7-universal-consensus-location-identifiers){target=\_blank} of the origin or destination assets or which extrinsics are used on which networks. - -The SDK consists of two main packages: - -- **[XCM SDK](https://github.com/moonbeam-foundation/xcm-sdk/tree/main/packages/sdk){target=\_blank}**: Core SDK for executing XCM transfers between chains in the Polkadot/Kusama ecosystem. -- **[MRL SDK](https://github.com/moonbeam-foundation/xcm-sdk/tree/main/packages/mrl){target=\_blank}**: Extension of the XCM SDK for transferring liquidity into and across the Polkadot ecosystem from other ecosystems like Ethereum. - -Key features include: - -- **Simplified asset transfers**: Abstracts away complex multilocation determinations and extrinsic selection. -- **Cross-ecosystem support**: Enables transfers between Polkadot/Kusama chains and external ecosystems. -- **Developer-friendly API**: Provides intuitive interfaces for cross-chain functionality. -- **Comprehensive documentation**: Includes usage guides and API references for both packages. - -For detailed usage examples and API documentation, visit the [official Moonbeam XCM SDK documentation](https://moonbeam-foundation.github.io/xcm-sdk/latest/){target=\_blank}. diff --git a/.ai/categories/dapps.md b/.ai/categories/dapps.md index 77d5d6ff9..071c680ad 100644 --- a/.ai/categories/dapps.md +++ b/.ai/categories/dapps.md @@ -1624,374 +1624,6 @@ XCM revolutionizes cross-chain communication by enabling use cases such as: These functionalities empower developers to build innovative, multi-chain applications, leveraging the strengths of various blockchain networks. To stay updated on XCM’s evolving format or contribute, visit the [XCM repository](https://github.com/paritytech/xcm-docs/blob/main/examples/src/0_first_look/mod.rs){target=\_blank}. ---- - -Page Title: Glossary - -- Source (raw): https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/reference-glossary.md -- Canonical (HTML): https://docs.polkadot.com/reference/glossary/ -- Summary: Glossary of terms used within the Polkadot ecosystem, Polkadot SDK, its subsequent libraries, and other relevant Web3 terminology. - -# Glossary - -Key definitions, concepts, and terminology specific to the Polkadot ecosystem are included here. - -Additional glossaries from around the ecosystem you might find helpful: - -- [Polkadot Wiki Glossary](https://wiki.polkadot.com/general/glossary){target=\_blank} -- [Polkadot SDK Glossary](https://paritytech.github.io/polkadot-sdk/master/polkadot_sdk_docs/reference_docs/glossary/index.html){target=\_blank} - -## Authority - -The role in a blockchain that can participate in consensus mechanisms. - -- **[GRANDPA](#grandpa)**: The authorities vote on chains they consider final. -- **[Blind Assignment of Blockchain Extension](#blind-assignment-of-blockchain-extension-babe) (BABE)**: The authorities are also [block authors](#block-author). - -Authority sets can be used as a basis for consensus mechanisms such as the [Nominated Proof of Stake (NPoS)](#nominated-proof-of-stake-npos) protocol. - -## Authority Round (Aura) - -A deterministic [consensus](#consensus) protocol where block production is limited to a rotating list of [authorities](#authority) that take turns creating blocks. In authority round (Aura) consensus, most online authorities are assumed to be honest. It is often used in combination with [GRANDPA](#grandpa) as a [hybrid consensus](#hybrid-consensus) protocol. - -Learn more by reading the official [Aura consensus algorithm](https://openethereum.github.io/Aura){target=\_blank} wiki article. - -## Blind Assignment of Blockchain Extension (BABE) - -A [block authoring](#block-author) protocol similar to [Aura](#authority-round-aura), except [authorities](#authority) win [slots](#slot) based on a Verifiable Random Function (VRF) instead of the round-robin selection method. The winning authority can select a chain and submit a new block. - -Learn more by reading the official Web3 Foundation [BABE research document](https://research.web3.foundation/Polkadot/protocols/block-production/Babe){target=\_blank}. - -## Block Author - -The node responsible for the creation of a block, also called _block producers_. In a Proof of Work (PoW) blockchain, these nodes are called _miners_. - -## Byzantine Fault Tolerance (BFT) - -The ability of a distributed computer network to remain operational if a certain proportion of its nodes or [authorities](#authority) are defective or behaving maliciously. A distributed network is typically considered Byzantine fault tolerant if it can remain functional, with up to one-third of nodes assumed to be defective, offline, actively malicious, and part of a coordinated attack. - -### Byzantine Failure - -The loss of a network service due to node failures that exceed the proportion of nodes required to reach consensus. - -### Practical Byzantine Fault Tolerance (pBFT) - -An early approach to Byzantine fault tolerance (BFT), practical Byzantine fault tolerance (pBFT) systems tolerate Byzantine behavior from up to one-third of participants. - -The communication overhead for such systems is `O(n²)`, where `n` is the number of nodes (participants) in the system. - -### Preimage - -A preimage is the data that is input into a hash function to calculate a hash. Since a hash function is a [one-way function](https://en.wikipedia.org/wiki/One-way_function){target=\_blank}, the output, the hash, cannot be used to reveal the input, the preimage. - -## Call - -In the context of pallets containing functions to be dispatched to the runtime, `Call` is an enumeration data type that describes the functions that can be dispatched with one variant per pallet. A `Call` represents a [dispatch](#dispatchable) data structure object. - -## Chain Specification - -A chain specification file defines the properties required to run a node in an active or new Polkadot SDK-built network. It often contains the initial genesis runtime code, network properties (such as the network's name), the initial state for some pallets, and the boot node list. The chain specification file makes it easy to use a single Polkadot SDK codebase as the foundation for multiple independently configured chains. - -## Collator - -An [author](#block-author) of a [parachain](#parachain) network. -They aren't [authorities](#authority) in themselves, as they require a [relay chain](#relay-chain) to coordinate [consensus](#consensus). - -More details are found on the [Polkadot Collator Wiki](https://wiki.polkadot.com/learn/learn-collator/){target=\_blank}. - -## Collective - -Most often used to refer to an instance of the Collective pallet on Polkadot SDK-based networks such as [Kusama](#kusama) or [Polkadot](#polkadot) if the Collective pallet is part of the FRAME-based runtime for the network. - -## Consensus - -Consensus is the process blockchain nodes use to agree on a chain's canonical fork. It is composed of [authorship](#block-author), finality, and [fork-choice rule](#fork-choice-rulestrategy). In the Polkadot ecosystem, these three components are usually separate and the term consensus often refers specifically to authorship. - -See also [hybrid consensus](#hybrid-consensus). - -## Consensus Algorithm - -Ensures a set of [actors](#authority)—who don't necessarily trust each other—can reach an agreement about the state as the result of some computation. Most consensus algorithms assume that up to one-third of the actors or nodes can be [Byzantine fault tolerant](#byzantine-fault-tolerance-bft). - -Consensus algorithms are generally concerned with ensuring two properties: - -- **Safety**: Indicating that all honest nodes eventually agreed on the state of the chain. -- **Liveness**: Indicating the ability of the chain to keep progressing. - -## Consensus Engine - -The node subsystem responsible for consensus tasks. - -For detailed information about the consensus strategies of the [Polkadot](#polkadot) network, see the [Polkadot Consensus](/reference/polkadot-hub/consensus-and-security/pos-consensus/){target=\_blank} blog series. - -See also [hybrid consensus](#hybrid-consensus). - -## Coretime - -The time allocated for utilizing a core, measured in relay chain blocks. There are two types of coretime: *on-demand* and *bulk*. - -On-demand coretime refers to coretime acquired through bidding in near real-time for the validation of a single parachain block on one of the cores reserved specifically for on-demand orders. They are available as an on-demand coretime pool. Set of cores that are available on-demand. Cores reserved through bulk coretime could also be made available in the on-demand coretime pool, in parts or in entirety. - -Bulk coretime is a fixed duration of continuous coretime represented by an NFT that can be split, shared, or resold. It is managed by the [Broker pallet](https://paritytech.github.io/polkadot-sdk/master/pallet_broker/index.html){target=\_blank}. - -## Development Phrase - -A [mnemonic phrase](https://en.wikipedia.org/wiki/Mnemonic#For_numerical_sequences_and_mathematical_operations){target=\_blank} that is intentionally made public. - -Well-known development accounts, such as Alice, Bob, Charlie, Dave, Eve, and Ferdie, are generated from the same secret phrase: - -``` -bottom drive obey lake curtain smoke basket hold race lonely fit walk -``` - -Many tools in the Polkadot SDK ecosystem, such as [`subkey`](https://github.com/paritytech/polkadot-sdk/tree/polkadot-stable2506-2/substrate/bin/utils/subkey){target=\_blank}, allow you to implicitly specify an account using a derivation path such as `//Alice`. - -## Digest - -An extensible field of the [block header](#header) that encodes information needed by several actors in a blockchain network, including: - -- [Light clients](#light-client) for chain synchronization. -- Consensus engines for block verification. -- The runtime itself, in the case of pre-runtime digests. - -## Dispatchable - -Function objects that act as the entry points in FRAME [pallets](#pallet). Internal or external entities can call them to interact with the blockchain’s state. They are a core aspect of the runtime logic, handling [transactions](#transaction) and other state-changing operations. - -## Events - -A means of recording that some particular [state](#state) transition happened. - -In the context of [FRAME](#frame-framework-for-runtime-aggregation-of-modularized-entities), events are composable data types that each [pallet](#pallet) can individually define. Events in FRAME are implemented as a set of transient storage items inspected immediately after a block has been executed and reset during block initialization. - -## Executor - -A means of executing a function call in a given [runtime](#runtime) with a set of dependencies. -There are two orchestration engines in Polkadot SDK, _WebAssembly_ and _native_. - -- The _native executor_ uses a natively compiled runtime embedded in the node to execute calls. This is a performance optimization available to up-to-date nodes. - -- The _WebAssembly executor_ uses a [Wasm](#webassembly-wasm) binary and a Wasm interpreter to execute calls. The binary is guaranteed to be up-to-date regardless of the version of the blockchain node because it is persisted in the [state](#state) of the Polkadot SDK-based chain. - -## Existential Deposit - -The minimum balance an account is allowed to have in the [Balances pallet](https://paritytech.github.io/polkadot-sdk/master/pallet_balances/index.html){target=\_blank}. Accounts cannot be created with a balance less than the existential deposit amount. - -If an account balance drops below this amount, the Balances pallet uses [a FRAME System API](https://paritytech.github.io/substrate/master/frame_system/pallet/struct.Pallet.html#method.dec_ref){target=\_blank} to drop its references to that account. - -If the Balances pallet reference to an account is dropped, the account can be [reaped](https://paritytech.github.io/substrate/master/frame_system/pallet/struct.Pallet.html#method.allow_death){target=\_blank}. - -## Extrinsic - -A general term for data that originates outside the runtime, is included in a block, and leads to some action. This includes user-initiated transactions and inherent transactions placed into the block by the block builder. - -It is a SCALE-encoded array typically consisting of a version number, signature, and varying data types indicating the resulting runtime function to be called. Extrinsics can take two forms: [inherents](#inherent-transactions) and [transactions](#transaction). - -For more technical details, see the [Polkadot spec](https://spec.polkadot.network/id-extrinsics){target=\_blank}. - -## Fork Choice Rule/Strategy - -A fork choice rule or strategy helps determine which chain is valid when reconciling several network forks. A common fork choice rule is the [longest chain](https://paritytech.github.io/polkadot-sdk/master/sc_consensus/struct.LongestChain.html){target=\_blank}, in which the chain with the most blocks is selected. - -## FRAME (Framework for Runtime Aggregation of Modularized Entities) - -Enables developers to create blockchain [runtime](#runtime) environments from a modular set of components called [pallets](#pallet). It utilizes a set of procedural macros to construct runtimes. - -[Visit the Polkadot SDK docs for more details on FRAME.](https://paritytech.github.io/polkadot-sdk/master/polkadot_sdk_docs/polkadot_sdk/frame_runtime/index.html){target=\_blank} - -## Full Node - -A node that prunes historical states, keeping only recently finalized block states to reduce storage needs. Full nodes provide current chain state access and allow direct submission and validation of [extrinsics](#extrinsic), maintaining network decentralization. - -## Genesis Configuration - -A mechanism for specifying the initial state of a blockchain. By convention, this initial state or first block is commonly referred to as the genesis state or genesis block. The genesis configuration for Polkadot SDK-based chains is accomplished by way of a [chain specification](#chain-specification) file. - -## GRANDPA - -A deterministic finality mechanism for blockchains that is implemented in the [Rust](https://www.rust-lang.org/){target=\_blank} programming language. - -The [formal specification](https://github.com/w3f/consensus/blob/master/pdf/grandpa-old.pdf){target=\_blank} is maintained by the [Web3 Foundation](https://web3.foundation/){target=\_blank}. - -## Header - -A structure that aggregates the information used to summarize a block. Primarily, it consists of cryptographic information used by [light clients](#light-client) to get minimally secure but very efficient chain synchronization. - -## Hybrid Consensus - -A blockchain consensus protocol that consists of independent or loosely coupled mechanisms for [block production](#block-author) and finality. - -Hybrid consensus allows the chain to grow as fast as probabilistic consensus protocols, such as [Aura](#authority-round-aura), while maintaining the same level of security as deterministic finality consensus protocols, such as [GRANDPA](#grandpa). - -## Inherent Transactions - -A special type of unsigned transaction, referred to as _inherents_, that enables a block authoring node to insert information that doesn't require validation directly into a block. - -Only the block-authoring node that calls the inherent transaction function can insert data into its block. In general, validators assume the data inserted using an inherent transaction is valid and reasonable even if it can't be deterministically verified. - -## JSON-RPC - -A stateless, lightweight remote procedure call protocol encoded in JavaScript Object Notation (JSON). JSON-RPC provides a standard way to call functions on a remote system by using JSON. - -For Polkadot SDK, this protocol is implemented through the [Parity JSON-RPC](https://github.com/paritytech/jsonrpc){target=\_blank} crate. - -## Keystore - -A subsystem for managing keys for the purpose of producing new blocks. - -## Kusama - -[Kusama](https://kusama.network/){target=\_blank} is a Polkadot SDK-based blockchain that implements a design similar to the [Polkadot](#polkadot) network. - -Kusama is a [canary](https://en.wiktionary.org/wiki/canary_in_a_coal_mine){target=\_blank} network and is referred to as [Polkadot's "wild cousin."](https://wiki.polkadot.com/learn/learn-comparisons-kusama/){target=\_blank}. - -As a canary network, Kusama is expected to be more stable than a test network like [Westend](#westend) but less stable than a production network like [Polkadot](#polkadot). Kusama is controlled by its network participants and is intended to be stable enough to encourage meaningful experimentation. - -## libp2p - -A peer-to-peer networking stack that allows the use of many transport mechanisms, including WebSockets (usable in a web browser). - -Polkadot SDK uses the [Rust implementation](https://github.com/libp2p/rust-libp2p){target=\_blank} of the `libp2p` networking stack. - -## Light Client - -A type of blockchain node that doesn't store the [chain state](#state) or produce blocks. - -A light client can verify cryptographic primitives and provides a [remote procedure call (RPC)](https://en.wikipedia.org/wiki/Remote_procedure_call){target=\_blank} server, enabling blockchain users to interact with the network. - -## Metadata - -Data that provides information about one or more aspects of a system. -The metadata that exposes information about a Polkadot SDK blockchain enables you to interact with that system. - -## Nominated Proof of Stake (NPoS) - -A method for determining [validators](#validator) or _[authorities](#authority)_ based on a willingness to commit their stake to the proper functioning of one or more block-producing nodes. - -## Oracle - -An entity that connects a blockchain to a non-blockchain data source. Oracles enable the blockchain to access and act upon information from existing data sources and incorporate data from non-blockchain systems and services. - -## Origin - -A [FRAME](#frame-framework-for-runtime-aggregation-of-modularized-entities) primitive that identifies the source of a [dispatched](#dispatchable) function call into the [runtime](#runtime). The FRAME System pallet defines three built-in [origins](#origin). As a [pallet](#pallet) developer, you can also define custom origins, such as those defined by the [Collective pallet](https://paritytech.github.io/substrate/master/pallet_collective/enum.RawOrigin.html){target=\_blank}. - -## Pallet - -A module that can be used to extend the capabilities of a [FRAME](#frame-framework-for-runtime-aggregation-of-modularized-entities)-based [runtime](#runtime). -Pallets bundle domain-specific logic with runtime primitives like [events](#events) and [storage items](#storage-item). - -## Parachain - -A parachain is a blockchain that derives shared infrastructure and security from a _[relay chain](#relay-chain)_. -You can learn more about parachains on the [Polkadot Wiki](https://wiki.polkadot.com/learn/learn-parachains/){target=\_blank}. - -## Paseo - -Paseo TestNet provisions testing on Polkadot's "production" runtime, which means less chance of feature or code mismatch when developing parachain apps. Specifically, after the [Polkadot Technical fellowship](https://wiki.polkadot.com/learn/learn-polkadot-technical-fellowship/){target=\_blank} proposes a runtime upgrade for Polkadot, this TestNet is updated, giving a period where the TestNet will be ahead of Polkadot to allow for testing. - -## Polkadot - -The [Polkadot network](https://polkadot.com/){target=\_blank} is a blockchain that serves as the central hub of a heterogeneous blockchain network. It serves the role of the [relay chain](#relay-chain) and provides shared infrastructure and security to support [parachains](#parachain). - -## Polkadot Cloud - -Polkadot Cloud is a platform for deploying resilient, customizable and scalable Web3 applications through Polkadot's functionality. It encompasses the wider Polkadot network infrastructure and security layer where parachains operate. The platform enables users to launch Ethereum-compatible chains, build specialized blockchains, and flexibly manage computing resources through on-demand or bulk coretime purchases. Initially launched with basic parachain functionality, Polkadot Cloud has evolved to offer enhanced flexibility with features like coretime, elastic scaling, and async backing for improved performance. - -## Polkadot Hub - -Polkadot Hub is a Layer 1 platform that serves as the primary entry point to the Polkadot ecosystem, providing essential functionality without requiring parachain deployment. It offers core services including smart contracts, identity management, staking, governance, and interoperability with other ecosystems, making it simple and fast for both builders and users to get started in Web3. - -## PolkaVM - -PolkaVM is a custom virtual machine optimized for performance, leveraging a RISC-V-based architecture to support Solidity and any language that compiles to RISC-V. It is specifically designed for the Polkadot ecosystem, enabling smart contract deployment and execution. - -## Relay Chain - -Relay chains are blockchains that provide shared infrastructure and security to the [parachains](#parachain) in the network. In addition to providing [consensus](#consensus) capabilities, relay chains allow parachains to communicate and exchange digital assets without needing to trust one another. - -## Rococo - -A [parachain](#parachain) test network for the Polkadot network. The [Rococo](#rococo) network is a Polkadot SDK-based blockchain with an October 14, 2024 deprecation date. Development teams are encouraged to use the Paseo TestNet instead. - -## Runtime - -The runtime represents the [state transition function](#state-transition-function-stf) for a blockchain. In Polkadot SDK, the runtime is stored as a [Wasm](#webassembly-wasm) binary in the chain state. The Runtime is stored under a unique state key and can be modified during the execution of the state transition function. - -## Slot - -A fixed, equal interval of time used by consensus engines such as [Aura](#authority-round-aura) and [BABE](#blind-assignment-of-blockchain-extension-babe). In each slot, a subset of [authorities](#authority) is permitted, or obliged, to [author](#block-author) a block. - -## Sovereign Account - -The unique account identifier for each chain in the relay chain ecosystem. It is often used in cross-consensus (XCM) interactions to sign XCM messages sent to the relay chain or other chains in the ecosystem. - -The sovereign account for each chain is a root-level account that can only be accessed using the Sudo pallet or through governance. The account identifier is calculated by concatenating the Blake2 hash of a specific text string and the registered parachain identifier. - -## SS58 Address Format - -A public key address based on the Bitcoin [`Base-58-check`](https://en.bitcoin.it/wiki/Base58Check_encoding){target=\_blank} encoding. Each Polkadot SDK SS58 address uses a `base-58` encoded value to identify a specific account on a specific Polkadot SDK-based chain - -The [canonical `ss58-registry`](https://github.com/paritytech/ss58-registry){target=\_blank} provides additional details about the address format used by different Polkadot SDK-based chains, including the network prefix and website used for different networks - -## State Transition Function (STF) - -The logic of a blockchain that determines how the state changes when a block is processed. In Polkadot SDK, the state transition function is effectively equivalent to the [runtime](#runtime). - -## Storage Item - -[FRAME](#frame-framework-for-runtime-aggregation-of-modularized-entities) primitives that provide type-safe data persistence capabilities to the [runtime](#runtime). -Learn more in the [storage items](https://paritytech.github.io/polkadot-sdk/master/frame_support/storage/types/index.html){target=\_blank} reference document in the Polkadot SDK. - -## Substrate - -A flexible framework for building modular, efficient, and upgradeable blockchains. Substrate is written in the [Rust](https://www.rust-lang.org/){target=\_blank} programming language and is maintained by [Parity Technologies](https://www.parity.io/){target=\_blank}. - -## Transaction - -An [extrinsic](#extrinsic) that includes a signature that can be used to verify the account authorizing it inherently or via [signed extensions](https://paritytech.github.io/polkadot-sdk/master/polkadot_sdk_docs/reference_docs/signed_extensions/index.html){target=\_blank}. - -## Transaction Era - -A definable period expressed as a range of block numbers during which a transaction can be included in a block. -Transaction eras are used to protect against transaction replay attacks if an account is reaped and its replay-protecting nonce is reset to zero. - -## Trie (Patricia Merkle Tree) - -A data structure used to represent sets of key-value pairs and enables the items in the data set to be stored and retrieved using a cryptographic hash. Because incremental changes to the data set result in a new hash, retrieving data is efficient even if the data set is very large. With this data structure, you can also prove whether the data set includes any particular key-value pair without access to the entire data set. - -In Polkadot SDK-based blockchains, state is stored in a trie data structure that supports the efficient creation of incremental digests. This trie is exposed to the [runtime](#runtime) as [a simple key/value map](#storage-item) where both keys and values can be arbitrary byte arrays. - -## Validator - -A validator is a node that participates in the consensus mechanism of the network. Its roles include block production, transaction validation, network integrity, and security maintenance. - -## WebAssembly (Wasm) - -An execution architecture that allows for the efficient, platform-neutral expression of -deterministic, machine-executable logic. - -[Wasm](https://webassembly.org/){target=\_blank} can be compiled from many languages, including -the [Rust](https://www.rust-lang.org/){target=\_blank} programming language. Polkadot SDK-based chains use a Wasm binary to provide portable [runtimes](#runtime) that can be included as part of the chain's state. - -## Weight - -A convention used in Polkadot SDK-based blockchains to measure and manage the time it takes to validate a block. -Polkadot SDK defines one unit of weight as one picosecond of execution time on reference hardware. - -The maximum block weight should be equivalent to one-third of the target block time with an allocation of one-third each for: - -- Block construction -- Network propagation -- Import and verification - -By defining weights, you can trade-off the number of transactions per second and the hardware required to maintain the target block time appropriate for your use case. Weights are defined in the runtime, meaning you can tune them using runtime updates to keep up with hardware and software improvements. - -## Westend - -Westend is a Parity-maintained, Polkadot SDK-based blockchain that serves as a test network for the [Polkadot](#polkadot) network. - - --- Page Title: Indexers @@ -2466,76 +2098,6 @@ To stop the node, press `Control-C` in the terminal. ---- - -Page Title: Interoperability - -- Source (raw): https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/reference-parachains-interoperability.md -- Canonical (HTML): https://docs.polkadot.com/reference/parachains/interoperability/ -- Summary: Explore the importance of interoperability in the Polkadot ecosystem, covering XCM, bridges, and cross-chain communication. - -# Interoperability - -## Introduction - -Interoperability lies at the heart of the Polkadot ecosystem, enabling communication and collaboration across a diverse range of blockchains. By bridging the gaps between parachains, relay chains, and even external networks, Polkadot unlocks the potential for truly decentralized applications, efficient resource sharing, and scalable solutions. - -Polkadot’s design ensures that blockchains can transcend their individual limitations by working together as part of a unified system. This cooperative architecture is what sets Polkadot apart in the blockchain landscape. - -## Why Interoperability Matters - -The blockchain ecosystem is inherently fragmented. Different blockchains excel in specialized domains such as finance, gaming, or supply chain management, but these chains function in isolation without interoperability. This lack of connectivity stifles the broader utility of blockchain technology. - -Interoperability solves this problem by enabling blockchains to: - -- **Collaborate across networks**: Chains can interact to share assets, functionality, and data, creating synergies that amplify their individual strengths. -- **Achieve greater scalability**: Specialized chains can offload tasks to others, optimizing performance and resource utilization. -- **Expand use-case potential**: Cross-chain applications can leverage features from multiple blockchains, unlocking novel user experiences and solutions. - -In the Polkadot ecosystem, interoperability transforms a collection of isolated chains into a cohesive, efficient network, pushing the boundaries of what blockchains can achieve together. - -## Key Mechanisms for Interoperability - -At the core of Polkadot's cross-chain collaboration are foundational technologies designed to break down barriers between networks. These mechanisms empower blockchains to communicate, share resources, and operate as a cohesive ecosystem. - -### Cross-Consensus Messaging (XCM): The Backbone of Communication - -Polkadot's Cross-Consensus Messaging (XCM) is the standard framework for interaction between parachains, relay chains, and, eventually, external blockchains. XCM provides a trustless, secure messaging format for exchanging assets, sharing data, and executing cross-chain operations. - -Through XCM, decentralized applications can: - -- Transfer tokens and other assets across chains. -- Coordinate complex workflows that span multiple blockchains. -- Enable seamless user experiences where underlying blockchain differences are invisible. -- XCM exemplifies Polkadot’s commitment to creating a robust and interoperable ecosystem. - -For further information about XCM, check the [Get Started with XCM](/parachains/interoperability/get-started/){target=\_blank} article. - -### Bridges: Connecting External Networks - -While XCM enables interoperability within the Polkadot ecosystem, bridges extend this functionality to external blockchains such as Ethereum and Bitcoin. By connecting these networks, bridges allow Polkadot-based chains to access external liquidity, additional functionalities, and broader user bases. - -With bridges, developers and users gain the ability to: - -- Integrate external assets into Polkadot-based applications. -- Combine the strengths of Polkadot’s scalability with the liquidity of other networks. -- Facilitate accurate multi-chain applications that transcend ecosystem boundaries. - -For more information about bridges in the Polkadot ecosystem, see the [Bridge Hub](/reference/polkadot-hub/bridging/){target=\_blank} guide. - -## The Polkadot Advantage - -Polkadot was purpose-built for interoperability. Unlike networks that add interoperability as an afterthought, Polkadot integrates it as a fundamental design principle. This approach offers several distinct advantages: - -- **Developer empowerment**: Polkadot’s interoperability tools allow developers to build applications that leverage multiple chains’ capabilities without added complexity. -- **Enhanced ecosystem collaboration**: Chains in Polkadot can focus on their unique strengths while contributing to the ecosystem’s overall growth. -- **Future-proofing blockchain**: By enabling seamless communication, Polkadot ensures its ecosystem can adapt to evolving demands and technologies. - -## Looking Ahead - -Polkadot’s vision of interoperability extends beyond technical functionality, representing a shift towards a more collaborative blockchain landscape. By enabling chains to work together, Polkadot fosters innovation, efficiency, and accessibility, paving the way for a decentralized future where blockchains are not isolated competitors but interconnected collaborators. - - --- Page Title: JSON-RPC APIs @@ -3407,377 +2969,85 @@ If an error occurs, the response will include an error object: --- -Page Title: Networks +Page Title: Oracles -- Source (raw): https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/reference-parachains-networks.md -- Canonical (HTML): https://docs.polkadot.com/reference/parachains/networks/ -- Summary: Explore Polkadot's testing and production networks, including Westend, Kusama, and Paseo, for efficient development, deployment, and testing. +- Source (raw): https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/parachains-integrations-oracles.md +- Canonical (HTML): https://docs.polkadot.com/parachains/integrations/oracles/ +- Summary: Learn about blockchain oracles, the essential bridges connecting blockchains with real-world data for decentralized applications in the Polkadot ecosystem. -# Networks +# Oracles -## Introduction +## What is a Blockchain Oracle? -The Polkadot ecosystem is built on a robust set of networks designed to enable secure and scalable development. Whether you are testing new features or deploying to live production, Polkadot offers several layers of networks tailored for each stage of the development process. From local environments to experimental networks like Kusama and community-run TestNets such as Paseo, developers can thoroughly test, iterate, and validate their applications. This guide will introduce you to Polkadot's various networks and explain how they fit into the development workflow. +Oracles enable blockchains to access external data sources. Since blockchains operate as isolated networks, they cannot natively interact with external systems - this limitation is known as the "blockchain oracle problem." Oracles solves this by extracting data from external sources (like APIs, IoT devices, or other blockchains), validating it, and submitting it on-chain. -## Network Overview +While simple oracle implementations may rely on a single trusted provider, more sophisticated solutions use decentralized networks where multiple providers stake assets and reach consensus on data validity. Typical applications include DeFi price feeds, weather data for insurance contracts, and cross-chain asset verification. -Polkadot's development process is structured to ensure new features and upgrades are rigorously tested before being deployed on live production networks. The progression follows a well-defined path, starting from local environments and advancing through TestNets, ultimately reaching the Polkadot MainNet. The diagram below outlines the typical progression of the Polkadot development cycle: +## Oracle Implementations -``` mermaid -flowchart LR - id1[Local] --> id2[Westend] --> id4[Kusama] --> id5[Polkadot] - id1[Local] --> id3[Paseo] --> id5[Polkadot] -``` +
-This flow ensures developers can thoroughly test and iterate without risking real tokens or affecting production networks. Testing tools like [Chopsticks](#chopsticks) and various TestNets make it easier to experiment safely before releasing to production. +- __Acurast__ -A typical journey through the Polkadot core protocol development process might look like this: + --- -1. **Local development node**: Development starts in a local environment, where developers can create, test, and iterate on upgrades or new features using a local development node. This stage allows rapid experimentation in an isolated setup without any external dependencies. + Acurast is a decentralized, serverless cloud platform that uses a distributed network of mobile devices for oracle services, addressing centralized trust and data ownership issues. In the Polkadot ecosystem, it allows developers to define off-chain data and computation needs, which are processed by these devices acting as decentralized oracle nodes, delivering results to Substrate (Wasm) and EVM environments. -2. **Westend**: After testing locally, upgrades are deployed to [Westend](#westend), Polkadot's primary TestNet. Westend simulates real-world conditions without using real tokens, making it the ideal place for rigorous feature testing before moving on to production networks. + [:octicons-arrow-right-24: Reference](https://acurast.com/){target=\_blank} -3. **Kusama**: Once features have passed extensive testing on Westend, they move to Kusama, Polkadot's experimental and fast-moving "canary" network. Kusama operates as a high-fidelity testing ground with actual economic incentives, giving developers insights into how their features will perform in a real-world environment. +
-4. **Polkadot**: After passing tests on Westend and Kusama, features are considered ready for deployment to Polkadot, the live production network. - In addition, parachain developers can leverage local TestNets like [Zombienet](#zombienet) and deploy upgrades on parachain TestNets. +--- -5. **Paseo**: For parachain and dApp developers, Paseo serves as a community-run TestNet that mirrors Polkadot's runtime. Like Westend for core protocol development, Paseo provides a testing ground for parachain development without affecting live networks. +Page Title: Overview of FRAME -!!!note - The Rococo TestNet deprecation date was October 14, 2024. Teams should use Westend for Polkadot protocol and feature testing and Paseo for chain development-related testing. +- Source (raw): https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/parachains-customize-runtime.md +- Canonical (HTML): https://docs.polkadot.com/parachains/customize-runtime/ +- Summary: Learn how Polkadot SDK’s FRAME framework simplifies blockchain development with modular pallets and support libraries for efficient runtime design. -## Polkadot Development Networks +# Customize Your Runtime -Development and testing are crucial to building robust dApps and parachains and performing network upgrades within the Polkadot ecosystem. To achieve this, developers can leverage various networks and tools that provide a risk-free environment for experimentation and validation before deploying features to live networks. These networks help avoid the costs and risks associated with real tokens, enabling testing for functionalities like governance, cross-chain messaging, and runtime upgrades. +## Introduction -## Kusama Network +A blockchain runtime is more than just a fixed set of rules—it's a dynamic foundation that you can shape to match your specific needs. With Polkadot SDK's [FRAME (Framework for Runtime Aggregation of Modularized Entities)](https://paritytech.github.io/polkadot-sdk/master/polkadot_sdk_docs/polkadot_sdk/frame_runtime/index.html){target=\_blank}, customizing your runtime is straightforward and modular. Instead of building everything from scratch, you combine pre-built pallets with your own custom logic to create a runtime suited to your blockchain's purpose. -Kusama is the experimental version of Polkadot, designed for developers who want to move quickly and test their applications in a real-world environment with economic incentives. Kusama serves as a production-grade testing ground where developers can deploy features and upgrades with the pressure of game theory and economics in mind. It mirrors Polkadot but operates as a more flexible space for innovation. -The native token for Kusama is KSM. For more information about KSM, visit the [Native Assets](https://wiki.polkadot.com/kusama/kusama-getting-started/){target=\_blank} page. -## Test Networks +This overview explains how runtime customization works, introduces the building blocks you'll use, and guides you through the key patterns for extending your runtime. -The following test networks provide controlled environments for testing upgrades and new features. TestNet tokens are available from the [Polkadot faucet](https://faucet.polkadot.io/){target=\_blank}. +## Understanding Your Runtime -### Westend +The runtime is the core logic of your blockchain—it processes transactions, manages state, and enforces the rules that govern your network. When a transaction arrives at your blockchain, the [`frame_executive`](https://paritytech.github.io/polkadot-sdk/master/frame_executive/index.html){target=\_blank} pallet receives it and routes it to the appropriate pallet for execution. -Westend is Polkadot's primary permanent TestNet. Unlike temporary test networks, Westend is not reset to the genesis block, making it an ongoing environment for testing Polkadot core features. Managed by Parity Technologies, Westend ensures that developers can test features in a real-world simulation without using actual tokens. +Think of your runtime as a collection of specialized modules, each handling a different aspect of your blockchain. Need token balances? Use the Balances pallet. Want governance? Add the Governance pallets. Need something custom? Create your own pallet. By mixing and matching these modules, you build a runtime that's efficient, secure, and tailored to your use case. -The native token for Westend is WND. More details about WND can be found on the [Native Assets](https://wiki.polkadot.com/learn/learn-dot/#__tabbed_2_2){target=\_blank} page. +## Runtime Architecture -### Paseo +The following diagram shows how FRAME components work together to form your runtime: -[Paseo](https://github.com/paseo-network){target=\_blank} is a community-managed TestNet designed for parachain and dApp developers. It mirrors Polkadot's runtime and is maintained by Polkadot community members. Paseo provides a dedicated space for parachain developers to test their applications in a Polkadot-like environment without the risks associated with live networks. +![](/images/parachains/customize-runtime/index/frame-overview-01.webp) -The native token for Paseo is PAS. Additional information on PAS is available on the [Native Assets](https://wiki.polkadot.com/learn/learn-dot/#__tabbed_2_1){target=\_blank} page. +The main components are: -## Local Test Networks +- **`frame_executive`**: Routes all incoming transactions to the correct pallet for execution. +- **Pallets**: Domain-specific modules that implement your blockchain's features and business logic. +- **`frame_system`**: Provides core runtime primitives and storage. +- **`frame_support`**: Utilities and macros that simplify pallet development. -Local test networks are an essential part of the development cycle for blockchain developers using the Polkadot SDK. They allow for fast, iterative testing in controlled, private environments without connecting to public TestNets. Developers can quickly spin up local instances to experiment, debug, and validate their code before deploying to larger TestNets like Westend or Paseo. Two key tools for local network testing are Zombienet and Chopsticks. +## Building Blocks: Pallets -### Zombienet +[Pallets](https://paritytech.github.io/polkadot-sdk/master/polkadot_sdk_docs/polkadot_sdk/frame_runtime/pallet/index.html){target=\_blank} are the fundamental units of runtime customization. Each pallet encapsulates specific functionality and can be independently developed, tested, and integrated. -[Zombienet](https://github.com/paritytech/zombienet){target=\_blank} is a flexible testing framework for Polkadot SDK-based blockchains. It enables developers to create and manage ephemeral, short-lived networks. This feature makes Zombienet particularly useful for quick iterations, as it allows you to run multiple local networks concurrently, mimicking different runtime conditions. Whether you're developing a parachain or testing your custom blockchain logic, Zombienet gives you the tools to automate local testing. +A pallet can implement virtually any blockchain feature you need: -Key features of Zombienet include: +- Expose new transactions that users can submit. +- Store data on-chain. +- Enforce business rules and validation logic. +- Emit events to notify users of state changes. +- Handle errors gracefully. -- Creating dynamic, local networks with different configurations. -- Running parachains and relay chains in a simulated environment. -- Efficient testing of network components like cross-chain messaging and governance. - -Zombienet is ideal for developers looking to test quickly and thoroughly before moving to more resource-intensive public TestNets. - -### Chopsticks - -[Chopsticks](https://github.com/AcalaNetwork/chopsticks){target=\_blank} is a tool designed to create forks of Polkadot SDK-based blockchains, allowing developers to interact with network forks as part of their testing process. This capability makes Chopsticks a powerful option for testing upgrades, runtime changes, or cross-chain applications in a forked network environment. - -Key features of Chopsticks include: - -- Forking live Polkadot SDK-based blockchains for isolated testing. -- Simulating cross-chain messages in a private, controlled setup. -- Debugging network behavior by interacting with the fork in real-time. - -Chopsticks provides a controlled environment for developers to safely explore the effects of runtime changes. It ensures that network behavior is tested and verified before upgrades are deployed to live networks. - - ---- - -Page Title: Node and Runtime - -- Source (raw): https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/reference-parachains-node-and-runtime.md -- Canonical (HTML): https://docs.polkadot.com/reference/parachains/node-and-runtime/ -- Summary: Learn how Polkadot SDK-based nodes function, how the client and runtime are separated, and how they communicate using SCALE-encoded data. - -# Node and Runtime - -## Introduction - -Every blockchain platform relies on a decentralized network of computers, called nodes, that communicate with each other about transactions and blocks. In this context, a node refers to the software running on the connected devices rather than the physical or virtual machines in the network. - -Polkadot SDK-based nodes consist of two main components, each with distinct responsibilities: the client (also called node) and the runtime. - -If the system were a monolithic protocol, any modification would require updating the entire system. Instead, Polkadot achieves true upgradeability by defining an immutable meta-protocol (the client) and a protocol (the runtime) that can be upgraded independently. - -This separation gives the [Polkadot Relay Chain](/polkadot-protocol/architecture/polkadot-chain){target=\_blank} and all connected [parachains](/polkadot-protocol/architecture/parachains){target=\_blank} an evolutionary advantage over other blockchain platforms. - -## Architectural Principles - -The Polkadot SDK-based blockchain architecture is fundamentally built on two distinct yet interconnected components: - -- Client (Meta-protocol): - - Handles the foundational infrastructure of the blockchain. - - Manages runtime execution, networking, consensus, and other off-chain components. - - Provides an immutable base layer that ensures network stability. - - Upgradable only through hard forks. - -- Runtime (Protocol): - - Defines the blockchain's state transition logic. - - Determines the specific rules and behaviors of the blockchain. - - Compiled to WebAssembly (Wasm) for platform-independent execution. - - Capable of being upgraded without network-wide forking. - -### Advantages of this Architecture - -- **Forkless upgrades**: Runtime can be updated without disrupting the entire network. -- **Modularity**: Clear separation allows independent development of client and runtime. -- **Flexibility**: Enables rapid iteration and evolution of blockchain logic. -- **Performance**: WebAssembly compilation provides efficient, cross-platform execution. - -## Node (Client) - -The node, also known as the client, is the core component responsible for executing the Wasm runtime and orchestrating various essential blockchain components. It ensures the correct execution of the state transition function and manages multiple critical subsystems, including: - -- **Wasm execution**: Runs the blockchain runtime, which defines the state transition rules. -- **Database management**: Stores blockchain data. -- **Networking**: Facilitates peer-to-peer communication, block propagation, and transaction gossiping. -- **Transaction pool (Mempool)**: Manages pending transactions before they are included in a block. -- **Consensus mechanism**: Ensures agreement on the blockchain state across nodes. -- **RPC services**: Provides external interfaces for applications and users to interact with the node. - -## Runtime - -The runtime is more than just a set of rules. It's the fundamental logic engine that defines a blockchain's entire behavior. In Polkadot SDK-based blockchains, the runtime represents a complete, self-contained description of the blockchain's state transition function. - -### Characteristics - -The runtime is distinguished by three key characteristics: - -- **Business logic**: Defines the complete application-specific blockchain behavior. -- **WebAssembly compilation**: Ensures platform-independent, secure execution. -- **On-chain storage**: Stored within the blockchain's state, allowing dynamic updates. - -### Key Functions - -The runtime performs several critical functions, such as: - -- Define state transition rules. -- Implement blockchain-specific logic. -- Manage account interactions. -- Control transaction processing. -- Define governance mechanisms. -- Handle custom pallets and modules. - -## Communication Between Node and Runtime - -The client and runtime communicate exclusively using [SCALE-encoded](/polkadot-protocol/parachain-basics/data-encoding){target=\_blank} communication. This ensures efficient and compact data exchange between the two components. - -### Runtime APIs - -The Runtime API consists of well-defined functions and constants a client assumes are implemented in the Runtime Wasm blob. These APIs enable the client to interact with the runtime to execute blockchain operations and retrieve information. The client invokes these APIs to: - -- Build, execute, and finalize blocks. -- Access metadata. -- Access consensus related information. -- Handle transaction execution. - -### Host Functions - -During execution, the runtime can access certain external client functionalities via host functions. The specific functions the client exposes allow the runtime to perform operations outside the WebAssembly domain. Host functions enable the runtime to: - -- Perform cryptographic operations. -- Access the current blockchain state. -- Handle storage modifications. -- Allocate memory. - - ---- - -Page Title: On-Chain Governance Overview - -- Source (raw): https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/reference-governance.md -- Canonical (HTML): https://docs.polkadot.com/reference/governance/ -- Summary: Discover Polkadot’s cutting-edge OpenGov system, enabling transparent, decentralized decision-making through direct democracy and flexible governance tracks. - -# On-Chain Governance - -## Introduction - -Polkadot’s governance system exemplifies decentralized decision-making, empowering its community of stakeholders to shape the network’s future through active participation. The latest evolution, OpenGov, builds on Polkadot’s foundation by providing a more inclusive and efficient governance model. - -This guide will explain the principles and structure of OpenGov and walk you through its key components, such as Origins, Tracks, and Delegation. You will learn about improvements over earlier governance systems, including streamlined voting processes and enhanced stakeholder participation. - -With OpenGov, Polkadot achieves a flexible, scalable, and democratic governance framework that allows multiple proposals to proceed simultaneously, ensuring the network evolves in alignment with its community's needs. - -## Governance Evolution - -Polkadot’s governance journey began with [Governance V1](https://wiki.polkadot.com/learn/learn-polkadot-opengov/#governance-summary){target=\_blank}, a system that proved effective in managing treasury funds and protocol upgrades. However, it faced limitations, such as: - -- Slow voting cycles, causing delays in decision-making. -- Inflexibility in handling multiple referendums, restricting scalability. - -To address these challenges, Polkadot introduced OpenGov, a governance model designed for greater inclusivity, efficiency, and scalability. OpenGov replaces the centralized structures of Governance V1, such as the Council and Technical Committee, with a fully decentralized and dynamic framework. - -For a full comparison of the historic and current governance models, visit the [Gov1 vs. Polkadot OpenGov](https://wiki.polkadot.com/learn/learn-polkadot-opengov/#gov1-vs-polkadot-opengov){target=\_blank} section of the Polkadot Wiki. - -## OpenGov Key Features - -OpenGov transforms Polkadot’s governance into a decentralized, stakeholder-driven model, eliminating centralized decision-making bodies like the Council. Key enhancements include: - -- **Decentralization**: Shifts all decision-making power to the public, ensuring a more democratic process. -- **Enhanced delegation**: Allows users to delegate their votes to trusted experts across specific governance tracks. -- **Simultaneous referendums**: Multiple proposals can progress at once, enabling faster decision-making. -- **Polkadot Technical Fellowship**: A broad, community-driven group replacing the centralized Technical Committee. - -This new system ensures Polkadot governance remains agile and inclusive, even as the ecosystem grows. - -## Origins and Tracks - -In OpenGov, origins and tracks are central to managing proposals and votes. - -- **Origin**: Determines the authority level of a proposal (e.g., Treasury, Root) which decides the track of all referendums from that origin. -- **Track**: Define the procedural flow of a proposal, such as voting duration, approval thresholds, and enactment timelines. - -Developers must be aware that referendums from different origins and tracks will take varying amounts of time to reach approval and enactment. The [Polkadot Technical Fellowship](https://wiki.polkadot.com/learn/learn-polkadot-technical-fellowship/){target=\_blank} has the option to shorten this timeline by whitelisting a proposal and allowing it to be enacted through the [Whitelist Caller](https://wiki.polkadot.com/learn/learn-polkadot-opengov-origins/#whitelisted-caller){target=\_blank} origin. - -Visit [Origins and Tracks Info](https://wiki.polkadot.com/learn/learn-polkadot-opengov/#origins-and-tracks){target=\_blank} for details on current origins and tracks, associated terminology, and parameters. - -## Referendums - -In OpenGov, anyone can submit a referendum, fostering an open and participatory system. The timeline for a referendum depends on the privilege level of the origin with more significant changes offering more time for community voting and participation before enactment. - -The timeline for an individual referendum includes four distinct periods: - -- **Lead-in**: A minimum amount of time to allow for community participation, available room in the origin, and payment of the decision deposit. Voting is open during this period. -- **Decision**: Voting continues. -- **Confirmation**: Referendum must meet [approval and support](https://wiki.polkadot.com/learn/learn-polkadot-opengov/#approval-and-support){target=\_blank} criteria during entire period to avoid rejection. -- **Enactment**: Changes approved by the referendum are executed. - -### Vote on Referendums - -Voters can vote with their tokens on each referendum. Polkadot uses a voluntary token locking mechanism, called conviction voting, as a way for voters to increase their voting power. A token holder signals they have a stronger preference for approving a proposal based upon their willingness to lock up tokens. Longer voluntary token locks are seen as a signal of continual approval and translate to increased voting weight. - -See [Voting on a Referendum](https://wiki.polkadot.com/learn/learn-polkadot-opengov/#voting-on-a-referendum){target=\_blank} for a deeper look at conviction voting and related token locks. - -### Delegate Voting Power - -The OpenGov system also supports multi-role delegations, allowing token holders to assign their voting power on different tracks to entities with expertise in those areas. - -For example, if a token holder lacks the technical knowledge to evaluate proposals on the [Root track](https://wiki.polkadot.com/learn/learn-polkadot-opengov-origins/#root){target=\_blank}, they can delegate their voting power for that track to an expert they trust to vote in the best interest of the network. This ensures informed decision-making across tracks while maintaining flexibility for token holders. - -Visit [Multirole Delegation](https://wiki.polkadot.com/learn/learn-polkadot-opengov/#multirole-delegation){target=\_blank} for more details on delegating voting power. - -### Cancel a Referendum - -Polkadot OpenGov has two origins for rejecting ongoing referendums: - -- [**Referendum Canceller**](https://wiki.polkadot.com/learn/learn-polkadot-opengov-origins/#referendum-canceller){target=\_blank}: Cancels an active referendum when non-malicious errors occur and refunds the deposits to the originators. -- [**Referendum Killer**](https://wiki.polkadot.com/learn/learn-polkadot-opengov-origins/#referendum-killer){target=\_blank}: Used for urgent, malicious cases this origin instantly terminates an active referendum and slashes deposits. - -See [Cancelling, Killing, and Blacklisting](https://wiki.polkadot.com/learn/learn-polkadot-opengov/#cancelling-killing--blacklisting){target=\_blank} for additional information on rejecting referendums. - -## Additional Resources - -- **[Democracy pallet](https://github.com/paritytech/polkadot-sdk/tree/polkadot-stable2506-2/substrate/frame/democracy/src){target=\_blank}**: Handles administration of general stakeholder voting. -- **[Gov2: Polkadot’s Next Generation of Decentralised Governance](https://medium.com/polkadot-network/gov2-polkadots-next-generation-of-decentralised-governance-4d9ef657d11b){target=\_blank}**: Medium article by Gavin Wood. -- **[Polkadot Direction](https://matrix.to/#/#Polkadot-Direction:parity.io){target=\_blank}**: Matrix Element client. -- **[Polkassembly](https://polkadot.polkassembly.io/){target=\_blank}**: OpenGov dashboard and UI. -- **[Polkadot.js Apps Governance](https://polkadot.js.org/apps/#/referenda){target=\_blank}**: Overview of active referendums. - - ---- - -Page Title: Oracles - -- Source (raw): https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/parachains-integrations-oracles.md -- Canonical (HTML): https://docs.polkadot.com/parachains/integrations/oracles/ -- Summary: Learn about blockchain oracles, the essential bridges connecting blockchains with real-world data for decentralized applications in the Polkadot ecosystem. - -# Oracles - -## What is a Blockchain Oracle? - -Oracles enable blockchains to access external data sources. Since blockchains operate as isolated networks, they cannot natively interact with external systems - this limitation is known as the "blockchain oracle problem." Oracles solves this by extracting data from external sources (like APIs, IoT devices, or other blockchains), validating it, and submitting it on-chain. - -While simple oracle implementations may rely on a single trusted provider, more sophisticated solutions use decentralized networks where multiple providers stake assets and reach consensus on data validity. Typical applications include DeFi price feeds, weather data for insurance contracts, and cross-chain asset verification. - -## Oracle Implementations - -
- -- __Acurast__ - - --- - - Acurast is a decentralized, serverless cloud platform that uses a distributed network of mobile devices for oracle services, addressing centralized trust and data ownership issues. In the Polkadot ecosystem, it allows developers to define off-chain data and computation needs, which are processed by these devices acting as decentralized oracle nodes, delivering results to Substrate (Wasm) and EVM environments. - - [:octicons-arrow-right-24: Reference](https://acurast.com/){target=\_blank} - -
- - ---- - -Page Title: Overview of FRAME - -- Source (raw): https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/parachains-customize-runtime.md -- Canonical (HTML): https://docs.polkadot.com/parachains/customize-runtime/ -- Summary: Learn how Polkadot SDK’s FRAME framework simplifies blockchain development with modular pallets and support libraries for efficient runtime design. - -# Customize Your Runtime - -## Introduction - -A blockchain runtime is more than just a fixed set of rules—it's a dynamic foundation that you can shape to match your specific needs. With Polkadot SDK's [FRAME (Framework for Runtime Aggregation of Modularized Entities)](https://paritytech.github.io/polkadot-sdk/master/polkadot_sdk_docs/polkadot_sdk/frame_runtime/index.html){target=\_blank}, customizing your runtime is straightforward and modular. Instead of building everything from scratch, you combine pre-built pallets with your own custom logic to create a runtime suited to your blockchain's purpose. - - - -This overview explains how runtime customization works, introduces the building blocks you'll use, and guides you through the key patterns for extending your runtime. - -## Understanding Your Runtime - -The runtime is the core logic of your blockchain—it processes transactions, manages state, and enforces the rules that govern your network. When a transaction arrives at your blockchain, the [`frame_executive`](https://paritytech.github.io/polkadot-sdk/master/frame_executive/index.html){target=\_blank} pallet receives it and routes it to the appropriate pallet for execution. - -Think of your runtime as a collection of specialized modules, each handling a different aspect of your blockchain. Need token balances? Use the Balances pallet. Want governance? Add the Governance pallets. Need something custom? Create your own pallet. By mixing and matching these modules, you build a runtime that's efficient, secure, and tailored to your use case. - -## Runtime Architecture - -The following diagram shows how FRAME components work together to form your runtime: - -![](/images/parachains/customize-runtime/index/frame-overview-01.webp) - -The main components are: - -- **`frame_executive`**: Routes all incoming transactions to the correct pallet for execution. -- **Pallets**: Domain-specific modules that implement your blockchain's features and business logic. -- **`frame_system`**: Provides core runtime primitives and storage. -- **`frame_support`**: Utilities and macros that simplify pallet development. - -## Building Blocks: Pallets - -[Pallets](https://paritytech.github.io/polkadot-sdk/master/polkadot_sdk_docs/polkadot_sdk/frame_runtime/pallet/index.html){target=\_blank} are the fundamental units of runtime customization. Each pallet encapsulates specific functionality and can be independently developed, tested, and integrated. - -A pallet can implement virtually any blockchain feature you need: - -- Expose new transactions that users can submit. -- Store data on-chain. -- Enforce business rules and validation logic. -- Emit events to notify users of state changes. -- Handle errors gracefully. - -### Pre-Built Pallets vs. Custom Pallets +### Pre-Built Pallets vs. Custom Pallets FRAME provides a comprehensive library of [pre-built pallets](https://github.com/paritytech/polkadot-sdk/tree/polkadot-stable2506-2/substrate/frame){target=\_blank} for common blockchain features, including consensus, staking, balances, governance, and more. These pallets are battle-tested, optimized, and ready to use. @@ -3866,2485 +3136,356 @@ This section covers the most common customization patterns you'll encounter: --- -Page Title: Overview of the Polkadot Relay Chain +Page Title: Set Up the Polkadot SDK Parachain Template -- Source (raw): https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/reference-polkadot-hub-consensus-and-security-relay-chain.md -- Canonical (HTML): https://docs.polkadot.com/reference/polkadot-hub/consensus-and-security/relay-chain/ -- Summary: Explore Polkadot's core architecture, including its multi-chain vision, shared security, and the DOT token's governance and staking roles. +- Source (raw): https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/parachains-launch-a-parachain-set-up-the-parachain-template.md +- Canonical (HTML): https://docs.polkadot.com/parachains/launch-a-parachain/set-up-the-parachain-template/ +- Summary: Learn how to set up and run the Polkadot SDK Parachain Template locally, creating a ready-to-customize foundation for your parachain. -# Overview +# Set Up the Polkadot SDK Parachain Template ## Introduction -Polkadot is a next-generation blockchain protocol designed to support a multi-chain future by enabling secure communication and interoperability between different blockchains. Built as a Layer-0 protocol, Polkadot introduces innovations like application-specific Layer-1 chains ([parachains](/polkadot-protocol/architecture/parachains/){targe=\_blank}), shared security through [Nominated Proof of Stake (NPoS)](/reference/glossary/#nominated-proof-of-stake-npos){target=\_blank}, and cross-chain interactions via its native [Cross-Consensus Messaging Format (XCM)](/parachains/interoperability/get-started/){target=\_blank}. - -This guide covers key aspects of Polkadot’s architecture, including its high-level protocol structure, blockspace commoditization, and the role of its native token, DOT, in governance, staking, and resource allocation. +The [Polkadot SDK](https://github.com/paritytech/polkadot-sdk){target=\_blank} includes several [templates](/parachains/customize-runtime/#starting-templates){target=\_blank} designed to help you quickly start building your own blockchain. Each template offers a different level of configuration, from minimal setups to feature-rich environments, allowing you to choose the foundation that best fits your project's needs. -## Polkadot 1.0 +Among these, the [Parachain Template](https://github.com/paritytech/polkadot-sdk-parachain-template){target=\_blank} provides a preconfigured runtime with commonly used pallets, making it an ideal starting point for most parachain development projects. -Polkadot 1.0 represents the state of Polkadot as of 2023, coinciding with the release of [Polkadot runtime v1.0.0](https://github.com/paritytech/polkadot/releases/tag/v1.0.0){target=\_blank}. This section will focus on Polkadot 1.0, along with philosophical insights into network resilience and blockspace. +This guide walks you through the full process of working with this template. You will: -As a Layer-0 blockchain, Polkadot contributes to the multi-chain vision through several key innovations and initiatives, including: +- Set up the Polkadot SDK Parachain Template. +- Understand the project structure and key components. +- Verify your template is ready for development. +- Run the parachain template locally in development mode. -- **Application-specific Layer-1 blockchains (parachains)**: Polkadot's sharded network allows for parallel transaction processing, with shards that can have unique state transition functions, enabling custom-built L1 chains optimized for specific applications. +By the end of this guide, you'll have a working template ready to customize and deploy as a parachain. -- **Shared security and scalability**: L1 chains connected to Polkadot benefit from its [Nominated Proof of Stake (NPoS)](/reference/polkadot-hub/consensus-and-security/pos-consensus/#nominated-proof-of-stake){target=\_blank} system, providing security out-of-the-box without the need to bootstrap their own. +## Prerequisites -- **Secure interoperability**: Polkadot's native interoperability enables seamless data and value exchange between parachains. This interoperability can also be used outside of the ecosystem for bridging with external networks. +Before getting started, ensure you have done the following: -- **Resilient infrastructure**: Decentralized and scalable, Polkadot ensures ongoing support for development and community initiatives via its on-chain [treasury](https://wiki.polkadot.com/learn/learn-polkadot-opengov-treasury/){target=\_blank} and governance. +- Completed the [Install Polkadot SDK](/parachains/install-polkadot-sdk/){target=\_blank} guide and successfully installed [Rust](https://www.rust-lang.org/){target=\_blank} and the required packages to set up your development environment. -- **Rapid L1 development**: The [Polkadot SDK](/reference/parachains/){target=\_blank} allows fast, flexible creation and deployment of Layer-1 chains. +For this tutorial series, you need to use Rust `1.86`. Newer versions of the compiler may not work with this parachain template version. -- **Cultivating the next generation of Web3 developers**: Polkadot supports the growth of Web3 core developers through initiatives such as. +Run the following commands to set up the correct Rust version: - - [Polkadot Blockchain Academy](https://polkadot.com/blockchain-academy){target=\_blank} - - [EdX courses](https://www.edx.org/school/web3x){target=\_blank} - - Rust and Substrate courses (coming soon) +=== "macOS" -### High-Level Architecture + ```bash + rustup install 1.86 + rustup default 1.86 + rustup target add wasm32-unknown-unknown --toolchain 1.86-aarch64-apple-darwin + rustup component add rust-src --toolchain 1.86-aarch64-apple-darwin + ``` -Polkadot features a chain that serves as the central component of the system. This chain is depicted as a ring encircled by several parachains that are connected to it. +=== "Ubuntu" -According to Polkadot's design, any blockchain that can compile to WebAssembly (Wasm) and adheres to the Parachains Protocol becomes a parachain on the Polkadot network. + ```bash + rustup toolchain install 1.86.0 + rustup default 1.86.0 + rustup target add wasm32-unknown-unknown --toolchain 1.86.0 + rustup component add rust-src --toolchain 1.86.0 + ``` -Here’s a high-level overview of the Polkadot protocol architecture: +## Polkadot SDK Utility Tools -![](/images/reference/polkadot-hub/consensus-and-security/relay-chain/relay-chain-01.webp){ style="background:white" } +This tutorial requires two essential tools: -Parachains propose blocks to Polkadot validators, who check for availability and validity before finalizing them. With the relay chain providing security, collators—full nodes of parachains—can focus on their tasks without needing strong incentives. +- [**Chain spec builder**](https://crates.io/crates/staging-chain-spec-builder/10.0.0){target=\_blank}: A Polkadot SDK utility for generating chain specifications. Refer to the [Generate Chain Specs](/parachains/launch-a-parachain/deploy-to-polkadot/#generate-the-chain-specification){target=\_blank} documentation for detailed usage. + + Install it by executing the following command: + + ```bash + cargo install --locked staging-chain-spec-builder@10.0.0 + ``` -The [Cross-Consensus Messaging Format (XCM)](/parachains/interoperability/get-started/){target=\_blank} allows parachains to exchange messages freely, leveraging the chain's security for trust-free communication. + This command installs the `chain-spec-builder` binary. -In order to interact with chains that want to use their own finalization process (e.g., Bitcoin), Polkadot has [bridges](/reference/parachains/interoperability/#bridges-connecting-external-networks){target=\_blank} that offer two-way compatibility, meaning that transactions can be made between different parachains. +- [**Polkadot Omni Node**](https://crates.io/crates/polkadot-omni-node/0.5.0){target=\_blank}: A white-labeled binary, released as a part of Polkadot SDK that can act as the collator of a parachain in production, with all the related auxiliary functionalities that a normal collator node has: RPC server, archiving state, etc. Moreover, it can also run the Wasm blob of the parachain locally for testing and development. -### Polkadot's Additional Functionalities + To install it, run the following command: -Historically, obtaining core slots on Polkadot chain relied upon crowdloans and auctions. Chain cores were leased through auctions for three-month periods, up to a maximum of two years. Crowdloans enabled users to securely lend funds to teams for lease deposits in exchange for pre-sale tokens, which is the only way to access slots on Polkadot 1.0. Auctions are now deprecated in favor of [coretime](/polkadot-protocol/architecture/system-chains/coretime/){target=\_blank}. + ```bash + cargo install --locked polkadot-omni-node@0.5.0 + ``` -Additionally, the chain handles [staking](https://wiki.polkadot.com/learn/learn-staking/){target=\_blank}, [accounts](/reference/parachains/accounts/){target=\_blank}, balances, and [governance](/reference/governance/){target=\_blank}. + This command installs the `polkadot-omni-node` binary. -#### Agile Coretime +## Clone the Template -The new and more efficient way of obtaining core on Polkadot is to go through the process of purchasing coretime. +The [Polkadot SDK Parachain Template](https://github.com/paritytech/polkadot-sdk-parachain-template){target=\_blank} provides a ready-to-use development environment for building with the [Polkadot SDK](https://github.com/paritytech/polkadot-sdk){target=\_blank}. Follow these steps to set up the template: -[Agile coretime](/reference/polkadot-hub/consensus-and-security/agile-coretime/){target=\_blank} improves the efficient use of Polkadot's network resources and offers economic flexibility for developers, extending Polkadot's capabilities far beyond the original vision outlined in the [whitepaper](https://polkadot.com/papers/Polkadot-whitepaper.pdf){target=\_blank}. +1. Clone the template repository: -It enables parachains to purchase monthly "bulk" allocations of coretime (the time allocated for utilizing a core, measured in Polkadot relay chain blocks), ensuring heavy-duty parachains that can author a block every six seconds with [Asynchronous Backing](https://wiki.polkadot.com/learn/learn-async-backing/#asynchronous-backing){target=\_blank} can reliably renew their coretime each month. Although six-second block times are now the default, parachains have the option of producing blocks less frequently. + ```bash + git clone https://github.com/paritytech/polkadot-sdk-parachain-template.git parachain-template + ``` -Renewal orders are prioritized over new orders, offering stability against price fluctuations and helping parachains budget more effectively for project costs. +2. Navigate into the project directory: -### Polkadot's Resilience + ```bash + cd parachain-template + ``` -Decentralization is a vital component of blockchain networks, but it comes with trade-offs: +## Explore the Project Structure -- An overly decentralized network may face challenges in reaching consensus and require significant energy to operate. -- Also, a network that achieves consensus quickly risks centralization, making it easier to manipulate or attack. +Before building the template, take a moment to familiarize yourself with its structure. Understanding this organization will help you navigate the codebase as you develop your parachain. -A network should be decentralized enough to prevent manipulative or malicious influence. In this sense, decentralization is a tool for achieving resilience. +The template follows a standard Polkadot SDK project layout: -Polkadot 1.0 currently achieves resilience through several strategies: +```text +parachain-template/ +├── node/ # Node implementation and client +├── pallets/ # Custom pallets for your parachain +├── runtime/ # Runtime configuration and logic +├── Cargo.toml # Workspace configuration +└── README.md # Documentation +``` -- **Nominated Proof of Stake (NPoS)**: Ensures that the stake per validator is maximized and evenly distributed among validators. +Key directories explained: -- **Decentralized nodes**: Designed to encourage operators to join the network. This program aims to expand and diversify the validators in the ecosystem who aim to become independent of the program during their term. Feel free to explore more about the program on the official [Decentralized Nodes](https://nodes.web3.foundation/){target=\_blank} page. +- **runtime/**: Contains your parachain's state transition function and pallet configuration. This is where you'll define what your blockchain can do. +- **node/**: Houses the client implementation that runs your blockchain, handles networking, and manages the database. +- **pallets/**: Where you'll create custom business logic modules (pallets) for your specific use case. +- **Cargo.toml**: The workspace configuration that ties all components together. -- **On-chain treasury and governance**: Known as [OpenGov](/reference/governance/){target=\_blank}, this system allows every decision to be made through public referenda, enabling any token holder to cast a vote. +!!!note + The runtime is compiled to WebAssembly (Wasm), enabling forkless upgrades. The node binary remains constant while the runtime can be updated on-chain. -### Polkadot's Blockspace +## Compile the Runtime -Polkadot 1.0’s design allows for the commoditization of blockspace. +Now that you understand the template structure, let's compile the runtime to ensure everything is working correctly. -Blockspace is a blockchain's capacity to finalize and commit operations, encompassing its security, computing, and storage capabilities. Its characteristics can vary across different blockchains, affecting security, flexibility, and availability. +1. Compile the runtime: -- **Security**: Measures the robustness of blockspace in Proof of Stake (PoS) networks linked to the stake locked on validator nodes, the variance in stake among validators, and the total number of validators. It also considers social centralization (how many validators are owned by single operators) and physical centralization (how many validators run on the same service provider). + ```bash + cargo build --release --locked + ``` -- **Flexibility**: Reflects the functionalities and types of data that can be stored, with high-quality data essential to avoid bottlenecks in critical processes. - -- **Availability**: Indicates how easily users can access blockspace. It should be easily accessible, allowing diverse business models to thrive, ideally regulated by a marketplace based on demand and supplemented by options for "second-hand" blockspace. - -Polkadot is built on core blockspace principles, but there's room for improvement. Tasks like balance transfers, staking, and governance are managed on the relay chain. - -Delegating these responsibilities to [system chains](/polkadot-protocol/architecture/system-chains/){target=\_blank} could enhance flexibility and allow the relay chain to concentrate on providing shared security and interoperability. - -For more information about blockspace, watch [Robert Habermeier’s interview](https://www.youtube.com/watch?v=e1vISppPwe4){target=\_blank} or read his [technical blog post](https://www.rob.tech/blog/polkadot-blockspace-over-blockchains/){target=\_blank}. - -## DOT Token - -DOT is the native token of the Polkadot network, much like BTC for Bitcoin and Ether for the Ethereum blockchain. DOT has 10 decimals, uses the Planck base unit, and has a balance type of `u128`. The same is true for Kusama's KSM token with the exception of having 12 decimals. - -### Redenomination of DOT - -Polkadot conducted a community poll, which ended on 27 July 2020 at block 888,888, to decide whether to redenominate the DOT token. The stakeholders chose to redenominate the token, changing the value of 1 DOT from 1e12 plancks to 1e10 plancks. - -Importantly, this did not affect the network's total number of base units (plancks); it only affects how a single DOT is represented. The redenomination became effective 72 hours after transfers were enabled, occurring at block 1,248,328 on 21 August 2020 around 16:50 UTC. - -### The Planck Unit - -The smallest unit of account balance on Polkadot SDK-based blockchains (such as Polkadot and Kusama) is called _Planck_, named after the Planck length, the smallest measurable distance in the physical universe. - -Similar to how BTC's smallest unit is the Satoshi and ETH's is the Wei, Polkadot's native token DOT equals 1e10 Planck, while Kusama's native token KSM equals 1e12 Planck. - -### Uses for DOT - -DOT serves three primary functions within the Polkadot network: - -- **Governance**: It is used to participate in the governance of the network. -- **Staking**: DOT is staked to support the network's operation and security. -- **Buying coretime**: Used to purchase coretime in-bulk or on-demand and access the chain to benefit from Polkadot's security and interoperability. - -Additionally, DOT can serve as a transferable token. For example, DOT, held in the treasury, can be allocated to teams developing projects that benefit the Polkadot ecosystem. - -## JAM and the Road Ahead - -The Join-Accumulate Machine (JAM) represents a transformative redesign of Polkadot's core architecture, envisioned as the successor to the current relay chain. Unlike traditional blockchain architectures, JAM introduces a unique computational model that processes work through two primary functions: - -- **Join**: Handles data integration. -- **Accumulate**: Folds computations into the chain's state. - -JAM removes many of the opinions and constraints of the current relay chain while maintaining its core security properties. Expected improvements include: - -- **Permissionless code execution**: JAM is designed to be more generic and flexible, allowing for permissionless code execution through services that can be deployed without governance approval. -- **More effective block time utilization**: JAM's efficient pipeline processing model places the prior state root in block headers instead of the posterior state root, enabling more effective utilization of block time for computations. - -This architectural evolution promises to enhance Polkadot's scalability and flexibility while maintaining robust security guarantees. JAM is planned to be rolled out to Polkadot as a single, complete upgrade rather than a stream of smaller updates. This approach seeks to minimize the developer overhead required to address any breaking changes. - - ---- - -Page Title: Parachains Overview - -- Source (raw): https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/reference-parachains.md -- Canonical (HTML): https://docs.polkadot.com/reference/parachains/ -- Summary: Learn about parachains, specialized blockchains on Polkadot that gain shared security and interoperability. Discover how they work and the tools to build them. - -# Parachains Overview - -## Introduction - -A parachain is a specialized blockchain that connects to the Polkadot relay chain, benefiting from shared security, interoperability, and scalability. Parachains are built using the [Polkadot SDK](https://github.com/paritytech/polkadot-sdk){target=\_blank}, a powerful toolkit written in Rust that provides everything needed to create custom blockchain logic while integrating seamlessly with the Polkadot network. - -Unlike standalone blockchains that must bootstrap their own validator sets and security, parachains leverage Polkadot's pooled security model. This allows parachain developers to focus on their application-specific functionality rather than consensus and security infrastructure. Parachains can communicate with each other through Cross-Consensus Messaging (XCM), enabling seamless interoperability across the Polkadot ecosystem. - -Key capabilities that parachains provide include: - -- **Shared security**: Inherit security from Polkadot's validator set without maintaining your own. -- **Interoperability**: Communicate trustlessly with other parachains via XCM. -- **Scalability**: Process transactions in parallel with other parachains. -- **Customization**: Build application-specific logic tailored to your use case. -- **Upgradeability**: Upgrade runtime logic without hard forks. - -## Polkadot SDK: Parachain Architecture - -Building a parachain involves understanding and utilizing several key components of the Polkadot SDK: - -![](/images/reference/parachains/index/overview-01.webp) - -- **[Substrate](https://paritytech.github.io/polkadot-sdk/master/polkadot_sdk_docs/polkadot_sdk/substrate/index.html){target=\_blank}**: The foundation providing core blockchain primitives and libraries. -- **[FRAME](https://paritytech.github.io/polkadot-sdk/master/polkadot_sdk_docs/polkadot_sdk/frame_runtime/index.html){target=\_blank}**: A modular framework for building your parachain's runtime logic. -- **[Cumulus](https://paritytech.github.io/polkadot-sdk/master/polkadot_sdk_docs/polkadot_sdk/cumulus/index.html){target=\_blank}**: Essential libraries and pallets that enable parachain functionality. -- **[XCM (Cross Consensus Messaging)](https://paritytech.github.io/polkadot-sdk/master/polkadot_sdk_docs/polkadot_sdk/xcm/index.html){target=\_blank}**: The messaging format for communicating with other parachains and the relay chain. -- **[Polkadot](https://paritytech.github.io/polkadot-sdk/master/polkadot_sdk_docs/polkadot_sdk/polkadot/index.html){target=\_blank}**: The relay chain that provides security and coordination. - -### Substrate: The Foundation - -Substrate provides the core infrastructure that every parachain is built upon. It handles the low-level blockchain functionality, allowing you to focus on your application's unique features. Substrate includes implementations for networking, database management, consensus participation, and the execution environment for your runtime. - -Every Polkadot SDK node consists of two main components: - -- **Client (Host)**: Handles infrastructure services. - - - Native binary that runs on validator and collator nodes. - - Executes the Wasm-compiled runtime. - - Manages networking, database, mempool, and block production. - - Interfaces with the relay chain for validation. - -- **Runtime (State Transition Function)**: Contains your business logic. - - - Defines how your Polkadot SDK node processes transactions. - - Compiled to [Wasm](https://webassembly.org/){target=\_blank} for deterministic execution. - - Stored on-chain and upgradeable via governance. - -```mermaid -%%{init: {'flowchart': {'padding': 5, 'nodeSpacing': 50, 'rankSpacing': 10}}}%% -graph TB - classDef title font-size:20px,font-weight:bold,stroke-width:0px - classDef clientStyle font-size:16px,font-weight:bold - classDef clientSubNodeStyle margin-top:10px - classDef runtimeCallExecutorStyle padding-top:10px - - subgraph sg1[Parachain
Node] - direction TB - - I[RuntimeCall Executor] - B[Wasm Runtime - STF] - - subgraph sg2[Client] - direction TB - C[Network and Blockchain
Infrastructure Services
+ Relay Chain Interface] - end - - I --> B - end - - class sg1 title - class sg2 clientStyle - class C clientSubNodeStyle - class I runtimeCallExecutorStyle - -``` - -### FRAME: Building Blocks for Your Runtime - -FRAME provides modular components called [pallets](/reference/glossary#pallet){target=\_blank} that you can compose to build your parachain's runtime. Each pallet provides specific functionality that you can customize and configure for your needs. This modular approach allows you to quickly assemble complex functionality without writing everything from scratch. - -```mermaid -graph LR - subgraph SP["Parachain Runtime"] - direction LR - Timestamp ~~~ Aura ~~~ ParachainSystem - Balances ~~~ TransactionPayment ~~~ Sudo - subgraph Timestamp["Timestamp"] - SS1[Custom Config] - end - subgraph Aura["Aura"] - SS2[Custom Config] - end - subgraph ParachainSystem["Parachain System"] - SS3[Custom Config] - end - subgraph Balances["Balances"] - SS4[Custom Config] - end - subgraph TransactionPayment["Transaction Payment"] - SS5[Custom Config] - end - subgraph Sudo["Sudo"] - SS6[Custom Config] - end - style Timestamp stroke:#FF69B4 - style Aura stroke:#FF69B4 - style ParachainSystem stroke:#FF69B4 - style Balances stroke:#FF69B4 - style TransactionPayment stroke:#FF69B4 - style Sudo stroke:#FF69B4 - style SS1 stroke-dasharray: 5 - style SS2 stroke-dasharray: 5 - style SS3 stroke-dasharray: 5 - style SS4 stroke-dasharray: 5 - style SS5 stroke-dasharray: 5 - style SS6 stroke-dasharray: 5 - - end - subgraph AP["Available FRAME Pallets"] - direction LR - A1[Aura]~~~A2[Parachain
System]~~~A3[Transaction
Payment]~~~A4[Sudo] - B1[Identity]~~~B2[Balances]~~~B3[Assets]~~~B4[EVM] - C1[Timestamp]~~~C2[Staking]~~~C3[Contracts]~~~C4[and more...] - end - AP --> SP -``` - -### Cumulus: Parachain-Specific Functionality - -Cumulus is what transforms a Polkadot SDK-based runtime into a parachain-capable runtime. It provides the essential components for communicating with the relay chain, participating in Polkadot's consensus, and handling parachain-specific operations like block validation and collation. - -Key Cumulus components include: - -- **Parachain system pallet**: Core parachain functionality and relay chain communication. -- **Collator consensus**: Block production logic for parachain collators. -- **Relay chain interface**: APIs for interacting with the Polkadot relay chain. -- **Validation data**: Handling proof-of-validity data required by relay chain validators. - -## Where to Go Next - -Building a parachain requires understanding the relationship between your chain and the Polkadot relay chain. The Polkadot SDK provides all the tools needed to design custom runtime logic, enable cross-chain communication, and deploy your parachain to production. - -The following sections provide detailed guidance on each aspect of parachain development, from initial design through deployment and ongoing maintenance. - -
- -- Guide __Launch a Simple Parachain__ - - --- - - Walk through the complete parachain launch flow: from setup and deployment to obtaining coretime. - - [:octicons-arrow-right-24: Deploy](/parachains/launch-a-parachain/set-up-the-parachain-template/) - - -- Guide __Customize Your Runtime__ - - --- - - Design your parachain's runtime logic and choose appropriate pallets for your use case. - - [:octicons-arrow-right-24: Get Started](/parachains/customize-runtime/) - -- Guide __Interoperability__ - - --- - - Implement XCM for trustless cross-chain communication with other parachains. - - [:octicons-arrow-right-24: Learn More](/parachains/interoperability/get-started/) - -- Guide __Runtime Upgrades__ - - --- - - Upgrade your parachain's runtime without hard forks using forkless upgrade mechanisms. - - [:octicons-arrow-right-24: Maintain](/parachains/runtime-maintenance/runtime-upgrades/) - -
- - ---- - -Page Title: Polkadart - -- Source (raw): https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/reference-tools-polkadart.md -- Canonical (HTML): https://docs.polkadot.com/reference/tools/polkadart/ -- Summary: Polkadart is a type-safe, native Dart, SDK for Polkadot and any compatible Polkadot-SDK blockchain network. - -# Polkadart - -Polkadart is the most comprehensive Dart/Flutter SDK for interacting with Polkadot, Substrate, and other compatible blockchain networks. Designed with a Dart-first approach and type-safe APIs, it provides everything developers need to build powerful decentralized applications. - -This page will outline some of the core components of Polkadart. For more details, refer to the [official documentation](https://polkadart.dev){target=\_blank}. - -## Installation - -Add Polkadart to your `pubspec.yaml`: - -=== "All packages" - - ```bash - dart pub add polkadart polkadart_cli polkadart_keyring polkadart_scale_codec secp256k1_ecdsa sr25519 ss58 substrate_bip39 substrate_metadata - ``` - -=== "Core only" - - ```bash - dart pub add polkadart polkadart_cli polkadart_keyring - ``` - -For type-safe API generation, add the following to your `pubspec.yaml`: - -{% raw %} -```yaml title="pubspec.yaml" -polkadart: - output_dir: lib/generated - chains: - polkadot: wss://rpc.polkadot.io - kusama: wss://kusama-rpc.polkadot.io - custom: wss://your-node.example.com -``` -{% endraw %} - -## Get Started - -### Type Generation - -Polkadart provides a CLI tool to generate type definitions from any Polkadot-SDK compatible blockchain network. This allows you to build type-safe Dart applications without dealing with the low-level details of the blockchain. - -### Run Generator - -```bash -dart run polkadart_cli:generate -v -``` - -### Use Generated Types - -```dart -import 'package:your_app/generated/polkadot/polkadot.dart'; -import 'package:polkadart/polkadart.dart'; -import 'package:ss58/ss58.dart'; - -final provider = Provider.fromUri(Uri.parse('wss://rpc.polkadot.io')); -final polkadot = Polkadot(provider); - -// Account from SS58 address -final account = Address.decode('19t9Q2ay58hMDaeg6eeBhqmHsRnc2jDMV3cYYw9zbc59HLj'); - -// Retrieve Account Balance -final accountInfo = await polkadot.query.system.account(account.pubkey); -print('Balance: ${accountInfo.data.free}') -``` - -### Creating an API Instance - -An API instance is required to interact with the blockchain. Polkadart provides a `Provider` class that allows you to connect to any network. - -```dart -import 'package:demo/generated/polkadot/polkadot.dart'; -import 'package:polkadart/provider.dart'; - -Future main(List arguments) async { - final provider = Provider.fromUri(Uri.parse('wss://rpc.polkadot.io')); - final polkadot = Polkadot(provider); -} -``` - -### Reading Chain Data - -Besides querying the data using the `query` from the generated API, you can also use the State API for querying storage data, metadata, runtime information, and other chain information. - -```dart -final stateApi = StateApi(provider); - -// Get current runtime version -final runtimeVersion = await stateApi.getRuntimeVersion(); -print(runtimeVersion.toJson()); - -// Get metadata -final metadata = await stateApi.getMetadata(); -print('Metadata version: ${metadata.version}'); -``` - -### Subscribe to New Blocks - -You can subscribe to new blocks on the blockchain using the `subscribe` method. - -```dart -final subscription = await provider.subscribe('chain_subscribeNewHeads', []); - -subscription.stream.forEach((response) { - print('New head: ${response.result}'); -}); -``` - -### Send a Transaction - -Perhaps the most common operation done in any blockchain is transferring funds. Here you can see how that can be done using Polkadart: - -```dart -final wallet = await KeyPair.sr25519.fromUri("//Alice"); -print('Alice\' wallet: ${wallet.address}'); - -// Get information necessary to build a proper extrinsic -final runtimeVersion = await polkadot.rpc.state.getRuntimeVersion(); -final currentBlockNumber = (await polkadot.query.system.number()) - 1; -final currentBlockHash = await polkadot.query.system.blockHash(currentBlockNumber); -final genesisHash = await polkadot.query.system.blockHash(0); -final nonce = await polkadot.rpc.system.accountNextIndex(wallet.address); - -// Make the encoded call -final multiAddress = $MultiAddress().id(wallet.publicKey.bytes); -final transferCall = polkadot.tx.balances.transferKeepAlive(dest: multiAddress, value: BigInt.one).encode(); - -// Make the payload -final payload = SigningPayload( - method: transferCall, - specVersion: runtimeVersion.specVersion, - transactionVersion: runtimeVersion.transactionVersion, - genesisHash: encodeHex(genesisHash), - blockHash: encodeHex(currentBlockHash), - blockNumber: currentBlockNumber, - eraPeriod: 64, - nonce: nonce, - tip: 0, -).encode(polkadot.registry); - -// Sign the payload and build the final extrinsic -final signature = wallet.sign(payload); -final extrinsic = ExtrinsicPayload( - signer: wallet.bytes(), - method: transferCall, - signature: signature, - eraPeriod: 64, - blockNumber: currentBlockNumber, - nonce: nonce, - tip: 0, -).encode(polkadot.registry, SignatureType.sr25519); - -// Send the extrinsic to the blockchain -final author = AuthorApi(provider); -await author.submitAndWatchExtrinsic(extrinsic, (data) { - print(data); -}); -``` - -## Where to Go Next - -To dive deeper into Polkadart, refer to the [official Polkadart documentation](https://polkadart.dev/){target=\_blank}, where you can find comprehensive guides for common use cases and advanced usage. - - ---- - -Page Title: Polkadot SDK Accounts - -- Source (raw): https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/reference-parachains-accounts.md -- Canonical (HTML): https://docs.polkadot.com/reference/parachains/accounts/ -- Summary: Learn about account structures, balances, and address formats in the Polkadot SDK, including how to manage lifecycle, references, and balances. - -# Accounts - -## Introduction - -Accounts are essential for managing identity, transactions, and governance on the network in the Polkadot SDK. Understanding these components is critical for seamless development and operation on the network, whether you're building or interacting with Polkadot-based chains. - -This page will guide you through the essential aspects of accounts, including their data structure, balance types, reference counters, and address formats. You’ll learn how accounts are managed within the runtime, how balances are categorized, and how addresses are encoded and validated. - -## Account Data Structure - -Accounts are foundational to any blockchain, and the Polkadot SDK provides a flexible management system. This section explains how the Polkadot SDK defines accounts and manages their lifecycle through data structures within the runtime. - -### Account - -The [`Account` data type](https://paritytech.github.io/polkadot-sdk/master/frame_system/pallet/type.Account.html){target=\_blank} is a storage map within the [System pallet](https://paritytech.github.io/polkadot-sdk/master/src/frame_system/lib.rs.html){target=\_blank} that links an account ID to its corresponding data. This structure is fundamental for mapping account-related information within the chain. - -The code snippet below shows how accounts are defined: - -```rs - /// The full account information for a particular account ID. - #[pallet::storage] - #[pallet::getter(fn account)] - pub type Account = StorageMap< - _, - Blake2_128Concat, - T::AccountId, - AccountInfo, - ValueQuery, - >; -``` - -The preceding code block defines a storage map named `Account`. The `StorageMap` is a type of on-chain storage that maps keys to values. In the `Account` map, the key is an account ID, and the value is the account's information. Here, `T` represents the generic parameter for the runtime configuration, which is defined by the pallet's configuration trait (`Config`). - -The `StorageMap` consists of the following parameters: - -- **`_`**: Used in macro expansion and acts as a placeholder for the storage prefix type. Tells the macro to insert the default prefix during expansion. -- **`Blake2_128Concat`**: The hashing function applied to keys in the storage map. -- **`T: :AccountId`**: Represents the key type, which corresponds to the account’s unique ID. -- **`AccountInfo`**: The value type stored in the map. For each account ID, the map stores an `AccountInfo` struct containing: - - - **`T::Nonce`**: A nonce for the account, which is incremented with each transaction to ensure transaction uniqueness. - - **`T: :AccountData`**: Custom account data defined by the runtime configuration, which could include balances, locked funds, or other relevant information. - -- **`ValueQuery`**: Defines how queries to the storage map behave when no value is found; returns a default value instead of `None`. - -For a detailed explanation of storage maps, see the [`StorageMap`](https://paritytech.github.io/polkadot-sdk/master/frame_support/storage/types/struct.StorageMap.html){target=\_blank} entry in the Rust docs. - -### Account Info - -The `AccountInfo` structure is another key element within the [System pallet](https://paritytech.github.io/polkadot-sdk/master/src/frame_system/lib.rs.html){target=\_blank}, providing more granular details about each account's state. This structure tracks vital data, such as the number of transactions and the account’s relationships with other modules. - -```rs -/// Information of an account. -#[derive(Clone, Eq, PartialEq, Default, RuntimeDebug, Encode, Decode, TypeInfo, MaxEncodedLen)] -pub struct AccountInfo { - /// The number of transactions this account has sent. - pub nonce: Nonce, - /// The number of other modules that currently depend on this account's existence. The account - /// cannot be reaped until this is zero. - pub consumers: RefCount, - /// The number of other modules that allow this account to exist. The account may not be reaped - /// until this and `sufficients` are both zero. - pub providers: RefCount, - /// The number of modules that allow this account to exist for their own purposes only. The - /// account may not be reaped until this and `providers` are both zero. - pub sufficients: RefCount, - /// The additional data that belongs to this account. Used to store the balance(s) in a lot of - /// chains. - pub data: AccountData, -} -``` - -The `AccountInfo` structure includes the following components: - -- **`nonce`**: Tracks the number of transactions initiated by the account, which ensures transaction uniqueness and prevents replay attacks. -- **`consumers`**: Counts how many other modules or pallets rely on this account’s existence. The account cannot be removed from the chain (reaped) until this count reaches zero. -- **`providers`**: Tracks how many modules permit this account’s existence. An account can only be reaped once both `providers` and `sufficients` are zero. -- **`sufficients`**: Represents the number of modules that allow the account to exist for internal purposes, independent of any other modules. -- **`AccountData`**: A flexible data structure that can be customized in the runtime configuration, usually containing balances or other user-specific data. - -This structure helps manage an account's state and prevents its premature removal while it is still referenced by other on-chain data or modules. The [`AccountInfo`](https://paritytech.github.io/polkadot-sdk/master/frame_system/struct.AccountInfo.html){target=\_blank} structure can vary as long as it satisfies the trait bounds defined by the `AccountData` associated type in the [`frame-system::pallet::Config`](https://paritytech.github.io/polkadot-sdk/master/frame_system/pallet/trait.Config.html){target=\_blank} trait. - -### Account Reference Counters - -Polkadot SDK uses reference counters to track an account’s dependencies across different runtime modules. These counters ensure that accounts remain active while data is associated with them. - -The reference counters include: - -- **`consumers`**: Prevents account removal while other pallets still rely on the account. -- **`providers`**: Ensures an account is active before other pallets store data related to it. -- **`sufficients`**: Indicates the account’s independence, ensuring it can exist even without a native token balance, such as when holding sufficient alternative assets. - -#### Providers Reference Counters - -The `providers` counter ensures that an account is ready to be depended upon by other runtime modules. For example, it is incremented when an account has a balance above the existential deposit, which marks the account as active. - -The system requires this reference counter to be greater than zero for the `consumers` counter to be incremented, ensuring the account is stable before any dependencies are added. - -#### Consumers Reference Counters - -The `consumers` counter ensures that the account cannot be reaped until all references to it across the runtime have been removed. This check prevents the accidental deletion of accounts that still have active on-chain data. - -It is the user’s responsibility to clear out any data from other runtime modules if they wish to remove their account and reclaim their existential deposit. - -#### Sufficients Reference Counter - -The `sufficients` counter tracks accounts that can exist independently without relying on a native account balance. This is useful for accounts holding other types of assets, like tokens, without needing a minimum balance in the native token. - -For instance, the [Assets pallet](https://paritytech.github.io/polkadot-sdk/master/pallet_assets/index.html){target=\_blank}, may increment this counter for an account holding sufficient tokens. - -#### Account Deactivation - -In Polkadot SDK-based chains, an account is deactivated when its reference counters (such as `providers`, `consumers`, and `sufficient`) reach zero. These counters ensure the account remains active as long as other runtime modules or pallets reference it. - -When all dependencies are cleared and the counters drop to zero, the account becomes deactivated and may be removed from the chain (reaped). This is particularly important in Polkadot SDK-based blockchains, where accounts with balances below the existential deposit threshold are pruned from storage to conserve state resources. - -Each pallet that references an account has cleanup functions that decrement these counters when the pallet no longer depends on the account. Once these counters reach zero, the account is marked for deactivation. - -#### Updating Counters - -The Polkadot SDK provides runtime developers with various methods to manage account lifecycle events, such as deactivation or incrementing reference counters. These methods ensure that accounts cannot be reaped while still in use. - -The following helper functions manage these counters: - -- **`inc_consumers()`**: Increments the `consumer` reference counter for an account, signaling that another pallet depends on it. -- **`dec_consumers()`**: Decrements the `consumer` reference counter, signaling that a pallet no longer relies on the account. -- **`inc_providers()`**: Increments the `provider` reference counter, ensuring the account remains active. -- **`dec_providers()`**: Decrements the `provider` reference counter, allowing for account deactivation when no longer in use. -- **`inc_sufficients()`**: Increments the `sufficient` reference counter for accounts that hold sufficient assets. -- **`dec_sufficients()`**: Decrements the `sufficient` reference counter. - -To ensure proper account cleanup and lifecycle management, a corresponding decrement should be made for each increment action. - -The `System` pallet offers three query functions to assist developers in tracking account states: - -- **[`can_inc_consumer()`](https://paritytech.github.io/polkadot-sdk/master/frame_system/pallet/struct.Pallet.html#method.can_inc_consumer){target=\_blank}**: Checks if the account can safely increment the consumer reference. -- **[`can_dec_provider()`](https://paritytech.github.io/polkadot-sdk/master/frame_system/pallet/struct.Pallet.html#method.can_dec_provider){target=\_blank}**: Ensures that no consumers exist before allowing the decrement of the provider counter. -- **[`is_provider_required()`](https://paritytech.github.io/polkadot-sdk/master/frame_system/pallet/struct.Pallet.html#method.is_provider_required){target=\_blank}**: Verifies whether the account still has any active consumer references. - -This modular and flexible system of reference counters tightly controls the lifecycle of accounts in Polkadot SDK-based blockchains, preventing the accidental removal or retention of unneeded accounts. You can refer to the [System pallet Rust docs](https://paritytech.github.io/polkadot-sdk/master/frame_system/pallet/struct.Pallet.html){target=\_blank} for more details. - - -## Account Balance Types - -In the Polkadot ecosystem, account balances are categorized into different types based on how the funds are utilized and their availability. These balance types determine the actions that can be performed, such as transferring tokens, paying transaction fees, or participating in governance activities. Understanding these balance types helps developers manage user accounts and implement balance-dependent logic. - -!!! note "A more efficient distribution of account balance types is in development" - Soon, pallets in the Polkadot SDK will implement the [`Fungible` trait](https://paritytech.github.io/polkadot-sdk/master/frame_support/traits/tokens/fungible/index.html){target=\_blank} (see the [tracking issue](https://github.com/paritytech/polkadot-sdk/issues/226){target=\_blank} for more details). For example, the [`transaction-storage`](https://paritytech.github.io/polkadot-sdk/master/pallet_transaction_storage/index.html){target=\_blank} pallet changed the implementation of the [`Currency`](https://paritytech.github.io/polkadot-sdk/master/frame_support/traits/tokens/currency/index.html){target=\_blank} trait (see the [Refactor transaction storage pallet to use fungible traits](https://github.com/paritytech/polkadot-sdk/pull/1800){target=\_blank} PR for further details): - - ```rust - type BalanceOf = <::Currency as Currency<::AccountId>>::Balance; - ``` - - To the [`Fungible`](https://paritytech.github.io/polkadot-sdk/master/frame_support/traits/tokens/fungible/index.html){target=\_blank} trait: - - ```rust - type BalanceOf = <::Currency as FnInspect<::AccountId>>::Balance; - ``` - - This update will enable more efficient use of account balances, allowing the free balance to be utilized for on-chain activities such as setting proxies and managing identities. - -### Balance Types - -The five main balance types are: - -- **Free balance**: Represents the total tokens available to the account for any on-chain activity, including staking, governance, and voting. However, it may not be fully spendable or transferrable if portions of it are locked or reserved. -- **Locked balance**: Portions of the free balance that cannot be spent or transferred because they are tied up in specific activities like [staking](https://wiki.polkadot.com/learn/learn-staking/#nominating-validators){target=\_blank}, [vesting](https://wiki.polkadot.com/learn/learn-guides-transfers/#vested-transfers-with-the-polkadot-js-ui){target=\_blank}, or participating in [governance](https://wiki.polkadot.com/learn/learn-polkadot-opengov/#voting-on-a-referendum){target=\_blank}. While the tokens remain part of the free balance, they are non-transferable for the duration of the lock. -- **Reserved balance**: Funds locked by specific system actions, such as setting up an [identity](https://wiki.polkadot.com/learn/learn-identity/){target=\_blank}, creating [proxies](https://wiki.polkadot.com/learn/learn-proxies/){target=\_blank}, or submitting [deposits for governance proposals](https://wiki.polkadot.com/learn/learn-guides-polkadot-opengov/#claiming-opengov-deposits){target=\_blank}. These tokens are not part of the free balance and cannot be spent unless they are unreserved. -- **Spendable balance**: The portion of the free balance that is available for immediate spending or transfers. It is calculated by subtracting the maximum of locked or reserved amounts from the free balance, ensuring that existential deposit limits are met. -- **Untouchable balance**: Funds that cannot be directly spent or transferred but may still be utilized for on-chain activities, such as governance participation or staking. These tokens are typically tied to certain actions or locked for a specific period. - -The spendable balance is calculated as follows: - -```text -spendable = free - max(locked - reserved, ED) -``` - -Here, `free`, `locked`, and `reserved` are defined above. The `ED` represents the [existential deposit](https://wiki.polkadot.com/learn/learn-accounts/#existential-deposit-and-reaping){target=\_blank}, the minimum balance required to keep an account active and prevent it from being reaped. You may find you can't see all balance types when looking at your account via a wallet. Wallet providers often display only spendable, locked, and reserved balances. - -### Locks - -Locks are applied to an account's free balance, preventing that portion from being spent or transferred. Locks are automatically placed when an account participates in specific on-chain activities, such as staking or governance. Although multiple locks may be applied simultaneously, they do not stack. Instead, the largest lock determines the total amount of locked tokens. - -Locks follow these basic rules: - -- If different locks apply to varying amounts, the largest lock amount takes precedence. -- If multiple locks apply to the same amount, the lock with the longest duration governs when the balance can be unlocked. - -#### Locks Example - -Consider an example where an account has 80 DOT locked for both staking and governance purposes like so: - -- 80 DOT is staked with a 28-day lock period. -- 24 DOT is locked for governance with a 1x conviction and a 7-day lock period. -- 4 DOT is locked for governance with a 6x conviction and a 224-day lock period. - -In this case, the total locked amount is 80 DOT because only the largest lock (80 DOT from staking) governs the locked balance. These 80 DOT will be released at different times based on the lock durations. In this example, the 24 DOT locked for governance will be released first since the shortest lock period is seven days. The 80 DOT stake with a 28-day lock period is released next. Now, all that remains locked is the 4 DOT for governance. After 224 days, all 80 DOT (minus the existential deposit) will be free and transferable. - -![Illustration of Lock Example](/images/reference/parachains/accounts/accounts-01.webp) - -#### Edge Cases for Locks - -In scenarios where multiple convictions and lock periods are active, the lock duration and amount are determined by the longest period and largest amount. For example, if you delegate with different convictions and attempt to undelegate during an active lock period, the lock may be extended for the full amount of tokens. For a detailed discussion on edge case lock behavior, see this [Stack Exchange post](https://substrate.stackexchange.com/questions/5067/delegating-and-undelegating-during-the-lock-period-extends-it-for-the-initial-am){target=\_blank}. - -### Balance Types on Polkadot.js - -Polkadot.js provides a user-friendly interface for managing and visualizing various account balances on Polkadot and Kusama networks. When interacting with Polkadot.js, you will encounter multiple balance types that are critical for understanding how your funds are distributed and restricted. This section explains how different balances are displayed in the Polkadot.js UI and what each type represents. - -![](/images/reference/parachains/accounts/accounts-02.webp) - -The most common balance types displayed on Polkadot.js are: - -- **Total balance**: The total number of tokens available in the account. This includes all tokens, whether they are transferable, locked, reserved, or vested. However, the total balance does not always reflect what can be spent immediately. In this example, the total balance is 0.6274 KSM. - -- **Transferable balance**: Shows how many tokens are immediately available for transfer. It is calculated by subtracting the locked and reserved balances from the total balance. For example, if an account has a total balance of 0.6274 KSM and a transferable balance of 0.0106 KSM, only the latter amount can be sent or spent freely. - -- **Vested balance**: Tokens that allocated to the account but released according to a specific schedule. Vested tokens remain locked and cannot be transferred until fully vested. For example, an account with a vested balance of 0.2500 KSM means that this amount is owned but not yet transferable. - -- **Locked balance**: Tokens that are temporarily restricted from being transferred or spent. These locks typically result from participating in staking, governance, or vested transfers. In Polkadot.js, locked balances do not stack—only the largest lock is applied. For instance, if an account has 0.5500 KSM locked for governance and staking, the locked balance would display 0.5500 KSM, not the sum of all locked amounts. - -- **Reserved balance**: Refers to tokens locked for specific on-chain actions, such as setting an identity, creating a proxy, or making governance deposits. Reserved tokens are not part of the free balance, but can be freed by performing certain actions. For example, removing an identity would unreserve those funds. - -- **Bonded balance**: The tokens locked for staking purposes. Bonded tokens are not transferable until they are unbonded after the unbonding period. - -- **Redeemable balance**: The number of tokens that have completed the unbonding period and are ready to be unlocked and transferred again. For example, if an account has a redeemable balance of 0.1000 KSM, those tokens are now available for spending. - -- **Democracy balance**: Reflects the number of tokens locked for governance activities, such as voting on referenda. These tokens are locked for the duration of the governance action and are only released after the lock period ends. - -By understanding these balance types and their implications, developers and users can better manage their funds and engage with on-chain activities more effectively. - -## Address Formats - -The SS58 address format is a core component of the Polkadot SDK that enables accounts to be uniquely identified across Polkadot-based networks. This format is a modified version of Bitcoin's Base58Check encoding, specifically designed to accommodate the multi-chain nature of the Polkadot ecosystem. SS58 encoding allows each chain to define its own set of addresses while maintaining compatibility and checksum validation for security. - -### Basic Format - -SS58 addresses consist of three main components: - -```text -base58encode(concat(,
, )) -``` - -- **Address type**: A byte or set of bytes that define the network (or chain) for which the address is intended. This ensures that addresses are unique across different Polkadot SDK-based chains. -- **Address**: The public key of the account encoded as bytes. -- **Checksum**: A hash-based checksum which ensures that addresses are valid and unaltered. The checksum is derived from the concatenated address type and address components, ensuring integrity. - -The encoding process transforms the concatenated components into a Base58 string, providing a compact and human-readable format that avoids easily confused characters (e.g., zero '0', capital 'O', lowercase 'l'). This encoding function ([`encode`](https://docs.rs/bs58/latest/bs58/fn.encode.html){target=\_blank}) is implemented exactly as defined in Bitcoin and IPFS specifications, using the same alphabet as both implementations. - -For more details about the SS58 address format implementation, see the [`Ss58Codec`](https://paritytech.github.io/polkadot-sdk/master/sp_core/crypto/trait.Ss58Codec.html){target=\_blank} trait in the Rust Docs. - -### Address Type - -The address type defines how an address is interpreted and to which network it belongs. Polkadot SDK uses different prefixes to distinguish between various chains and address formats: - -- **Address types `0-63`**: Simple addresses, commonly used for network identifiers. -- **Address types `64-127`**: Full addresses that support a wider range of network identifiers. -- **Address types `128-255`**: Reserved for future address format extensions. - -For example, Polkadot’s main network uses an address type of 0, while Kusama uses 2. This ensures that addresses can be used without confusion between networks. - -The address type is always encoded as part of the SS58 address, making it easy to quickly identify the network. Refer to the [SS58 registry](https://github.com/paritytech/ss58-registry){target=\_blank} for the canonical listing of all address type identifiers and how they map to Polkadot SDK-based networks. - -### Address Length - -SS58 addresses can have different lengths depending on the specific format. Address lengths range from as short as 3 to 35 bytes, depending on the complexity of the address and network requirements. This flexibility allows SS58 addresses to adapt to different chains while providing a secure encoding mechanism. - -| Total | Type | Raw account | Checksum | -|-------|------|-------------|----------| -| 3 | 1 | 1 | 1 | -| 4 | 1 | 2 | 1 | -| 5 | 1 | 2 | 2 | -| 6 | 1 | 4 | 1 | -| 7 | 1 | 4 | 2 | -| 8 | 1 | 4 | 3 | -| 9 | 1 | 4 | 4 | -| 10 | 1 | 8 | 1 | -| 11 | 1 | 8 | 2 | -| 12 | 1 | 8 | 3 | -| 13 | 1 | 8 | 4 | -| 14 | 1 | 8 | 5 | -| 15 | 1 | 8 | 6 | -| 16 | 1 | 8 | 7 | -| 17 | 1 | 8 | 8 | -| 35 | 1 | 32 | 2 | - -SS58 addresses also support different payload sizes, allowing a flexible range of account identifiers. - -### Checksum Types - -A checksum is applied to validate SS58 addresses. Polkadot SDK uses a Blake2b-512 hash function to calculate the checksum, which is appended to the address before encoding. The checksum length can vary depending on the address format (e.g., 1-byte, 2-byte, or longer), providing varying levels of validation strength. - -The checksum ensures that an address is not modified or corrupted, adding an extra layer of security for account management. - -### Validating Addresses - -SS58 addresses can be validated using the subkey command-line interface or the Polkadot.js API. These tools help ensure an address is correctly formatted and valid for the intended network. The following sections will provide an overview of how validation works with these tools. - -#### Using Subkey - -[Subkey](https://paritytech.github.io/polkadot-sdk/master/subkey/index.html){target=\_blank} is a CLI tool provided by Polkadot SDK for generating and managing keys. It can inspect and validate SS58 addresses. - -The `inspect` command gets a public key and an SS58 address from the provided secret URI. The basic syntax for the `subkey inspect` command is: - -```bash -subkey inspect [flags] [options] uri -``` - -For the `uri` command-line argument, you can specify the secret seed phrase, a hex-encoded private key, or an SS58 address. If the input is a valid address, the `subkey` program displays the corresponding hex-encoded public key, account identifier, and SS58 addresses. - -For example, to inspect the public keys derived from a secret seed phrase, you can run a command similar to the following: - -```bash -subkey inspect "caution juice atom organ advance problem want pledge someone senior holiday very" -``` - -The command displays output similar to the following: - -
- subkey inspect "caution juice atom organ advance problem want pledge someone senior holiday very" - Secret phrase `caution juice atom organ advance problem want pledge someone senior holiday very` is account: - Secret seed: 0xc8fa03532fb22ee1f7f6908b9c02b4e72483f0dbd66e4cd456b8f34c6230b849 - Public key (hex): 0xd6a3105d6768e956e9e5d41050ac29843f98561410d3a47f9dd5b3b227ab8746 - Public key (SS58): 5Gv8YYFu8H1btvmrJy9FjjAWfb99wrhV3uhPFoNEr918utyR - Account ID: 0xd6a3105d6768e956e9e5d41050ac29843f98561410d3a47f9dd5b3b227ab8746 - SS58 Address: 5Gv8YYFu8H1btvmrJy9FjjAWfb99wrhV3uhPFoNEr918utyR -
- -The `subkey` program assumes an address is based on a public/private key pair. If you inspect an address, the command returns the 32-byte account identifier. - -However, not all addresses in Polkadot SDK-based networks are based on keys. - -Depending on the command-line options you specify and the input you provided, the command output might also display the network for which the address has been encoded. For example: - -```bash -subkey inspect "12bzRJfh7arnnfPPUZHeJUaE62QLEwhK48QnH9LXeK2m1iZU" -``` - -The command displays output similar to the following: - -
- subkey inspect "12bzRJfh7arnnfPPUZHeJUaE62QLEwhK48QnH9LXeK2m1iZU" - Public Key URI `12bzRJfh7arnnfPPUZHeJUaE62QLEwhK48QnH9LXeK2m1iZU` is account: - Network ID/Version: polkadot - Public key (hex): 0x46ebddef8cd9bb167dc30878d7113b7e168e6f0646beffd77d69d39bad76b47a - Account ID: 0x46ebddef8cd9bb167dc30878d7113b7e168e6f0646beffd77d69d39bad76b47a - Public key (SS58): 12bzRJfh7arnnfPPUZHeJUaE62QLEwhK48QnH9LXeK2m1iZU - SS58 Address: 12bzRJfh7arnnfPPUZHeJUaE62QLEwhK48QnH9LXeK2m1iZU -
- -#### Using Polkadot.js API - -To verify an address in JavaScript or TypeScript projects, you can use the functions built into the [Polkadot.js API](https://polkadot.js.org/docs/){target=\_blank}. For example: - -```js -// Import Polkadot.js API dependencies -const { decodeAddress, encodeAddress } = require('@polkadot/keyring'); -const { hexToU8a, isHex } = require('@polkadot/util'); - -// Specify an address to test. -const address = 'INSERT_ADDRESS_TO_TEST'; - -// Check address -const isValidSubstrateAddress = () => { - try { - encodeAddress(isHex(address) ? hexToU8a(address) : decodeAddress(address)); - - return true; - } catch (error) { - return false; - } -}; - -// Query result -const isValid = isValidSubstrateAddress(); -console.log(isValid); - -``` - -If the function returns `true`, the specified address is a valid address. - -#### Other SS58 Implementations - -Support for encoding and decoding Polkadot SDK SS58 addresses has been implemented in several other languages and libraries. - -- **Crystal**: [`wyhaines/base58.cr`](https://github.com/wyhaines/base58.cr){target=\_blank} -- **Go**: [`itering/subscan-plugin`](https://github.com/itering/subscan-plugin){target=\_blank} -- **Python**: [`polkascan/py-scale-codec`](https://github.com/polkascan/py-scale-codec){target=\_blank} -- **TypeScript**: [`subsquid/squid-sdk`](https://github.com/subsquid/squid-sdk){target=\_blank} - - ---- - -Page Title: Polkadot-API - -- Source (raw): https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/reference-tools-papi.md -- Canonical (HTML): https://docs.polkadot.com/reference/tools/papi/ -- Summary: Polkadot-API (PAPI) is a modular, composable library set designed for efficient interaction with Polkadot chains, prioritizing a "light-client first" approach. - -# Polkadot-API - -## Introduction - -[Polkadot-API](https://github.com/polkadot-api/polkadot-api){target=\_blank} (PAPI) is a set of libraries built to be modular, composable, and grounded in a “light-client first” approach. Its primary aim is to equip dApp developers with an extensive toolkit for building fully decentralized applications. - -PAPI is optimized for light-client functionality, using the new JSON-RPC spec to support decentralized interactions fully. It provides strong TypeScript support with types and documentation generated directly from on-chain metadata, and it offers seamless access to storage reads, constants, transactions, events, and runtime calls. Developers can connect to multiple chains simultaneously and prepare for runtime updates through multi-descriptor generation and compatibility checks. PAPI is lightweight and performant, leveraging native BigInt, dynamic imports, and modular subpaths to avoid bundling unnecessary assets. It supports promise-based and observable-based APIs, integrates easily with Polkadot.js extensions, and offers signing options through browser extensions or private keys. - -## Get Started - -### API Instantiation - -To instantiate the API, you can install the package by using the following command: - -=== "npm" - - ```bash - npm i polkadot-api@1.17.2 - ``` - -=== "pnpm" - - ```bash - pnpm add polkadot-api@1.17.2 - ``` - -=== "yarn" - - ```bash - yarn add polkadot-api@1.17.2 - ``` - -Then, obtain the latest metadata from the target chain and generate the necessary types: - -```bash -# Add the target chain -npx papi add dot -n polkadot -``` - -The `papi add` command initializes the library by generating the corresponding types needed for the chain used. It assigns the chain a custom name and specifies downloading metadata from the Polkadot chain. You can replace `dot` with the name you prefer or with another chain if you want to add a different one. Once the latest metadata is downloaded, generate the required types: - -```bash -# Generate the necessary types -npx papi -``` - -You can now set up a [`PolkadotClient`](https://github.com/polkadot-api/polkadot-api/blob/main/packages/client/src/types.ts#L153){target=\_blank} with your chosen provider to begin interacting with the API. Choose from Smoldot via WebWorker, Node.js, or direct usage, or connect through the WSS provider. The examples below show how to configure each option for your setup. - -=== "Smoldot (WebWorker)" - - ```typescript - // `dot` is the identifier assigned during `npx papi add` - import { dot } from '@polkadot-api/descriptors'; - import { createClient } from 'polkadot-api'; - import { getSmProvider } from 'polkadot-api/sm-provider'; - import { chainSpec } from 'polkadot-api/chains/polkadot'; - import { startFromWorker } from 'polkadot-api/smoldot/from-worker'; - import SmWorker from 'polkadot-api/smoldot/worker?worker'; - - const worker = new SmWorker(); - const smoldot = startFromWorker(worker); - const chain = await smoldot.addChain({ chainSpec }); - - // Establish connection to the Polkadot relay chain - const client = createClient(getSmProvider(chain)); - - // To interact with the chain, obtain the `TypedApi`, which provides - // the necessary types for every API call on this chain - const dotApi = client.getTypedApi(dot); - - ``` - -=== "Smoldot (Node.js)" - - ```typescript - // `dot` is the alias assigned during `npx papi add` - import { dot } from '@polkadot-api/descriptors'; - import { createClient } from 'polkadot-api'; - import { getSmProvider } from 'polkadot-api/sm-provider'; - import { chainSpec } from 'polkadot-api/chains/polkadot'; - import { startFromWorker } from 'polkadot-api/smoldot/from-node-worker'; - import { fileURLToPath } from 'url'; - import { Worker } from 'worker_threads'; - - // Get the path for the worker file in ESM - const workerPath = fileURLToPath( - import.meta.resolve('polkadot-api/smoldot/node-worker'), - ); - - const worker = new Worker(workerPath); - const smoldot = startFromWorker(worker); - const chain = await smoldot.addChain({ chainSpec }); - - // Set up a client to connect to the Polkadot relay chain - const client = createClient(getSmProvider(chain)); - - // To interact with the chain's API, use `TypedApi` for access to - // all the necessary types and calls associated with this chain - const dotApi = client.getTypedApi(dot); - - ``` - -=== "Smoldot" - - ```typescript - // `dot` is the alias assigned when running `npx papi add` - import { dot } from '@polkadot-api/descriptors'; - import { createClient } from 'polkadot-api'; - import { getSmProvider } from 'polkadot-api/sm-provider'; - import { chainSpec } from 'polkadot-api/chains/polkadot'; - import { start } from 'polkadot-api/smoldot'; - - // Initialize Smoldot client - const smoldot = start(); - const chain = await smoldot.addChain({ chainSpec }); - - // Set up a client to connect to the Polkadot relay chain - const client = createClient(getSmProvider(chain)); - - // Access the `TypedApi` to interact with all available chain calls and types - const dotApi = client.getTypedApi(dot); - - ``` - -=== "WSS" - - ```typescript - // `dot` is the identifier assigned when executing `npx papi add` - import { dot } from '@polkadot-api/descriptors'; - import { createClient } from 'polkadot-api'; - // Use this import for Node.js environments - import { getWsProvider } from 'polkadot-api/ws-provider/web'; - import { withPolkadotSdkCompat } from 'polkadot-api/polkadot-sdk-compat'; - - // Establish a connection to the Polkadot relay chain - const client = createClient( - // The Polkadot SDK nodes may have compatibility issues; using this enhancer is recommended. - // Refer to the Requirements page for additional details - withPolkadotSdkCompat(getWsProvider('wss://dot-rpc.stakeworld.io')), - ); - - // To interact with the chain, obtain the `TypedApi`, which provides - // the types for all available calls in that chain - const dotApi = client.getTypedApi(dot); - - ``` - -Now that you have set up the client, you can interact with the chain by reading and sending transactions. - -### Reading Chain Data - -The `TypedApi` provides a streamlined way to read blockchain data through three main interfaces, each designed for specific data access patterns: - -- **Constants**: Access fixed values or configurations on the blockchain using the `constants` interface. - - ```typescript - const version = await typedApi.constants.System.Version(); - ``` - -- **Storage queries**: Retrieve stored values by querying the blockchain’s storage via the `query` interface. - - ```typescript - const asset = await api.query.ForeignAssets.Asset.getValue( - token.location, - { at: 'best' }, - ); - ``` - -- **Runtime APIs**: Interact directly with runtime APIs using the `apis` interface. - - ```typescript - const metadata = await typedApi.apis.Metadata.metadata(); - ``` - -To learn more about the different actions you can perform with the `TypedApi`, refer to the [TypedApi reference](https://papi.how/typed){target=\_blank}. - -### Sending Transactions - -In PAPI, the `TypedApi` provides the `tx` and `txFromCallData` methods to send transactions. - -- The `tx` method allows you to directly send a transaction with the specified parameters by using the `typedApi.tx.Pallet.Call` pattern: - - ```typescript - const tx: Transaction = typedApi.tx.Pallet.Call({arg1, arg2, arg3}); - ``` - - For instance, to execute the `balances.transferKeepAlive` call, you can use the following snippet: - - ```typescript - import { MultiAddress } from '@polkadot-api/descriptors'; - - const tx: Transaction = typedApi.tx.Balances.transfer_keep_alive({ - dest: MultiAddress.Id('INSERT_DESTINATION_ADDRESS'), - value: BigInt(INSERT_VALUE), - }); - - ``` - - Ensure you replace `INSERT_DESTINATION_ADDRESS` and `INSERT_VALUE` with the actual destination address and value, respectively. - -- The `txFromCallData` method allows you to send a transaction using the call data. This option accepts binary call data and constructs the transaction from it. It validates the input upon creation and will throw an error if invalid data is provided. The pattern is as follows: - - ```typescript - const callData = Binary.fromHex('0x...'); - const tx: Transaction = typedApi.txFromCallData(callData); - ``` - - For instance, to execute a transaction using the call data, you can use the following snippet: - - ```typescript - const callData = Binary.fromHex('0x00002470617065726d6f6f6e'); - const tx: Transaction = typedApi.txFromCallData(callData); - ``` - -For more information about sending transactions, refer to the [Transactions](https://papi.how/typed/tx#transactions){target=\_blank} page. - -## Where to Go Next - -For an in-depth guide on how to use PAPI, refer to the official [PAPI](https://papi.how/){target=\_blank} documentation. - - ---- - -Page Title: Polkadot.js API - -- Source (raw): https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/reference-tools-polkadot-js-api.md -- Canonical (HTML): https://docs.polkadot.com/reference/tools/polkadot-js-api/ -- Summary: Interact with Polkadot SDK-based chains easily using the Polkadot.js API. Query chain data, submit transactions, and more via JavaScript or Typescript. - -# Polkadot.js API - -!!! warning "Maintenance Mode Only" - The Polkadot.js API is now in maintenance mode and is no longer actively developed. New projects should use [Dedot](/develop/toolkit/api-libraries/dedot){target=\_blank} (TypeScript-first API) or [Polkadot API](/develop/toolkit/api-libraries/papi){target=\_blank} (modern, type-safe API) as actively maintained alternatives. - -## Introduction - -The [Polkadot.js API](https://github.com/polkadot-js/api){target=\_blank} uses JavaScript/TypeScript to interact with Polkadot SDK-based chains. It allows you to query nodes, read chain state, and submit transactions through a dynamic, auto-generated API interface. - -### Dynamic API Generation - -Unlike traditional static APIs, the Polkadot.js API generates its interfaces automatically when connecting to a node. Here's what happens when you connect: - -1. The API connects to your node. -2. It retrieves the chain's metadata. -3. Based on this metadata, it creates specific endpoints in this format: `api...
`. - -### Available API Categories - -You can access three main categories of chain interactions: - -- **[Runtime constants](https://polkadot.js.org/docs/api/start/api.consts){target=\_blank}** (`api.consts`): - - - Access runtime constants directly. - - Returns values immediately without function calls. - - **Example**: `api.consts.balances.existentialDeposit` - -- **[State queries](https://polkadot.js.org/docs/api/start/api.query/){target=\_blank}** (`api.query`): - - - Read chain state. - - **Example**: `api.query.system.account(accountId)` - -- **[Transactions](https://polkadot.js.org/docs/api/start/api.tx/){target=\_blank}** (`api.tx`): - - Submit extrinsics (transactions). - - **Example**: `api.tx.balances.transfer(accountId, value)` - -The available methods and interfaces will automatically reflect what's possible on your connected chain. - -## Installation - -To add the Polkadot.js API to your project, use the following command to install the version `16.4.7` which supports any Polkadot SDK-based chain: - -=== "npm" - ```bash - npm i @polkadot/api@16.4.7 - ``` - -=== "pnpm" - ```bash - pnpm add @polkadot/api@16.4.7 - ``` - -=== "yarn" - ```bash - yarn add @polkadot/api@16.4.7 - ``` - -For more detailed information about installation, see the [Installation](https://polkadot.js.org/docs/api/start/install/){target=\_blank} section in the official Polkadot.js API documentation. - -## Get Started - -### Creating an API Instance - -To interact with a Polkadot SDK-based chain, you must establish a connection through an API instance. The API provides methods for querying chain state, sending transactions, and subscribing to updates. - -To create an API connection: - -```js -import { ApiPromise, WsProvider } from '@polkadot/api'; - -// Create a WebSocket provider -const wsProvider = new WsProvider('wss://rpc.polkadot.io'); - -// Initialize the API -const api = await ApiPromise.create({ provider: wsProvider }); - -// Verify the connection by getting the chain's genesis hash -console.log('Genesis Hash:', api.genesisHash.toHex()); - -``` - -!!!warning - All `await` operations must be wrapped in an async function or block since the API uses promises for asynchronous operations. - -### Reading Chain Data - -The API provides several ways to read data from the chain. You can access: - -- **Constants**: Values that are fixed in the runtime and don't change without a runtime upgrade. - - ```js - // Get the minimum balance required for a new account - const minBalance = api.consts.balances.existentialDeposit.toNumber(); - - ``` - -- **State**: Current chain state that updates with each block. - - ```js - // Example address - const address = '5DTestUPts3kjeXSTMyerHihn1uwMfLj8vU8sqF7qYrFabHE'; - - // Get current timestamp - const timestamp = await api.query.timestamp.now(); - - // Get account information - const { nonce, data: balance } = await api.query.system.account(address); - - console.log(` - Timestamp: ${timestamp} - Free Balance: ${balance.free} - Nonce: ${nonce} - `); - - ``` - -### Sending Transactions - -Transactions (also called extrinsics) modify the chain state. Before sending a transaction, you need: - -- A funded account with sufficient balance to pay transaction fees. -- The account's keypair for signing. - -To make a transfer: - -```js -// Assuming you have an `alice` keypair from the Keyring -const recipient = 'INSERT_RECIPIENT_ADDRESS'; -const amount = 'INSERT_VALUE'; // Amount in the smallest unit (e.g., Planck for DOT) - -// Sign and send a transfer -const txHash = await api.tx.balances - .transfer(recipient, amount) - .signAndSend(alice); - -console.log('Transaction Hash:', txHash); - -``` - -The `alice` keypair in the example comes from a `Keyring` object. For more details about managing keypairs, see the [Keyring documentation](https://polkadot.js.org/docs/keyring){target=\_blank}. - -## Where to Go Next - -For more detailed information about the Polkadot.js API, check the [official documentation](https://polkadot.js.org/docs/){target=\_blank}. - - ---- - -Page Title: Python Substrate Interface - -- Source (raw): https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/reference-tools-py-substrate-interface.md -- Canonical (HTML): https://docs.polkadot.com/reference/tools/py-substrate-interface/ -- Summary: Learn how to connect to Polkadot SDK-based nodes, query data, submit transactions, and manage blockchain interactions using the Python Substrate Interface. - -# Python Substrate Interface - -## Introduction - -The [Python Substrate Interface](https://github.com/polkascan/py-substrate-interface){target=\_blank} is a powerful library that enables interaction with Polkadot SDK-based chains. It provides essential functionality for: - -- Querying on-chain storage. -- Composing and submitting extrinsics. -- SCALE encoding/decoding. -- Interacting with Substrate runtime metadata. -- Managing blockchain interactions through convenient utility methods. - -## Installation - -Install the library using `pip`: - -```py -pip install substrate-interface -``` - -For more installation details, see the [Installation](https://jamdottech.github.io/py-polkadot-sdk/getting-started/installation/){target=\_blank} section in the official Python Substrate Interface documentation. - -## Get Started - -This guide will walk you through the basic operations with the Python Substrate Interface: connecting to a node, reading chain state, and submitting transactions. - -### Establishing Connection - -The first step is to establish a connection to a Polkadot SDK-based node. You can connect to either a local or remote node: - -```py -from substrateinterface import SubstrateInterface - -# Connect to a node using websocket -substrate = SubstrateInterface( - # For local node: "ws://127.0.0.1:9944" - # For Polkadot: "wss://rpc.polkadot.io" - # For Kusama: "wss://kusama-rpc.polkadot.io" - url="INSERT_WS_URL" -) - -# Verify connection -print(f"Connected to chain: {substrate.chain}") - -``` - -### Reading Chain State - -You can query various on-chain storage items. To retrieve data, you need to specify three key pieces of information: - -- **Pallet name**: Module or pallet that contains the storage item you want to access. -- **Storage item**: Specific storage entry you want to query within the pallet. -- **Required parameters**: Any parameters needed to retrieve the desired data. - -Here's an example of how to check an account's balance and other details: - -```py -# ... - -# Query account balance and info -account_info = substrate.query( - module="System", # The pallet name - storage_function="Account", # The storage item - params=["INSERT_ADDRESS"], # Account address in SS58 format -) - -# Access account details from the result -free_balance = account_info.value["data"]["free"] -reserved = account_info.value["data"]["reserved"] -nonce = account_info.value["nonce"] - -print( - f""" - Account Details: - - Free Balance: {free_balance} - - Reserved: {reserved} - - Nonce: {nonce} - """ -) - -``` - -### Submitting Transactions - -To modify the chain state, you need to submit transactions (extrinsics). Before proceeding, ensure you have: - -- A funded account with sufficient balance to pay transaction fees. -- Access to the account's keypair. - -Here's how to create and submit a balance transfer: - -```py -#... - -# Compose the transfer call -call = substrate.compose_call( - call_module="Balances", # The pallet name - call_function="transfer_keep_alive", # The extrinsic function - call_params={ - 'dest': 'INSERT_ADDRESS', # Recipient's address - 'value': 'INSERT_VALUE' # Amount in smallest unit (e.g., Planck for DOT) - } -) - -# Create a signed extrinsic -extrinsic = substrate.create_signed_extrinsic( - call=call, keypair=keypair # Your keypair for signing -) - -# Submit and wait for inclusion -receipt = substrate.submit_extrinsic( - extrinsic, wait_for_inclusion=True # Wait until the transaction is in a block -) - -if receipt.is_success: - print( - f""" - Transaction successful: - - Extrinsic Hash: {receipt.extrinsic_hash} - - Block Hash: {receipt.block_hash} - """ - ) -else: - print(f"Transaction failed: {receipt.error_message}") - -``` - -The `keypair` object is essential for signing transactions. See the [Keypair](https://jamdottech.github.io/py-polkadot-sdk/reference/keypair/){target=\_blank} documentation for more details. - -## Where to Go Next - -Now that you understand the basics, you can: - -- Explore more complex queries and transactions. -- Learn about batch transactions and utility functions. -- Discover how to work with custom pallets and types. - -For comprehensive reference materials and advanced features, see the [Python Substrate Interface](https://jamdottech.github.io/py-polkadot-sdk/){target=\_blank} documentation. - - ---- - -Page Title: Randomness - -- Source (raw): https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/reference-parachains-randomness.md -- Canonical (HTML): https://docs.polkadot.com/reference/parachains/randomness/ -- Summary: Explore the importance of randomness in PoS blockchains, focusing on Polkadot’s VRF-based approach to ensure fairness and security in validator selection. - -# Randomness - -## Introduction - -Randomness is crucial in Proof of Stake (PoS) blockchains to ensure a fair and unpredictable distribution of validator duties. However, computers are inherently deterministic, meaning the same input always produces the same output. What we typically refer to as "random" numbers on a computer are actually pseudo-random. These numbers rely on an initial "seed," which can come from external sources like [atmospheric noise](https://www.random.org/randomness/){target=\_blank}, [heart rates](https://mdpi.altmetric.com/details/47574324){target=\_blank}, or even [lava lamps](https://en.wikipedia.org/wiki/Lavarand){target=\_blank}. While this may seem random, given the same "seed," the same sequence of numbers will always be generated. - -In a global blockchain network, relying on real-world entropy for randomness isn’t feasible because these inputs vary by time and location. If nodes use different inputs, blockchains can fork. Hence, real-world randomness isn't suitable for use as a seed in blockchain systems. - -Currently, two primary methods for generating randomness in blockchains are used: [`RANDAO`](#randao) and [`VRF`](#vrf) (Verifiable Random Function). Polkadot adopts the `VRF` approach for its randomness. - -## VRF - -A Verifiable Random Function (VRF) is a cryptographic function that generates a random number and proof that ensures the submitter produced the number. This proof allows anyone to verify the validity of the random number. - -Polkadot's VRF is similar to the one used in [**Ouroboros Praos**](https://eprint.iacr.org/2017/573.pdf){target=\_blank}, which secures randomness for block production in systems like [BABE](/reference/polkadot-hub/consensus-and-security/pos-consensus/#block-production-babe){target=\_blank} (Polkadot’s block production mechanism). - -The key difference is that Polkadot's VRF doesn’t rely on a central clock—avoiding the issue of whose clock to trust. Instead, it uses its own past results and slot numbers to simulate time and determine future outcomes. - -### How VRF Works - -Slots on Polkadot are discrete units of time, each lasting six seconds, and can potentially hold a block. Multiple slots form an epoch, with 2400 slots making up one four-hour epoch. - -In each slot, validators execute a "die roll" using a VRF. The VRF uses three inputs: - -1. A "secret key," unique to each validator, is used for the die roll. -2. An epoch randomness value, derived from the hash of VRF outputs from blocks two epochs ago (N-2), so past randomness influences the current epoch (N). -3. The current slot number. - -This process helps maintain fair randomness across the network. - -Here is a graphical representation: - -![](/images/reference/parachains/randomness/randomness-01.webp) - -The VRF produces two outputs: a result (the random number) and a proof (verifying that the number was generated correctly). - -The result is checked by the validator against a protocol threshold. If it's below the threshold, the validator becomes a candidate for block production in that slot. - -The validator then attempts to create a block, submitting it along with the `PROOF` and `RESULT`. - -So, VRF can be expressed like: - -`(RESULT, PROOF) = VRF(SECRET, EPOCH_RANDOMNESS_VALUE, CURRENT_SLOT_NUMBER)` - -Put simply, performing a "VRF roll" generates a random number along with proof that the number was genuinely produced and not arbitrarily chosen. - -After executing the VRF, the `RESULT` is compared to a protocol-defined `THRESHOLD`. If the `RESULT` is below the `THRESHOLD`, the validator becomes a valid candidate to propose a block for that slot. Otherwise, the validator skips the slot. - -As a result, there may be multiple validators eligible to propose a block for a slot. In this case, the block accepted by other nodes will prevail, provided it is on the chain with the latest finalized block as determined by the GRANDPA finality gadget. It's also possible for no block producers to be available for a slot, in which case the AURA consensus takes over. AURA is a fallback mechanism that randomly selects a validator to produce a block, running in parallel with BABE and only stepping in when no block producers exist for a slot. Otherwise, it remains inactive. - -Because validators roll independently, no block candidates may appear in some slots if all roll numbers are above the threshold. - -To verify resolution of this issue and that Polkadot block times remain near constant-time, see the [PoS Consensus](/reference/polkadot-hub/consensus-and-security/pos-consensus/){target=\_blank} page of this documentation. - -## RANDAO - -An alternative on-chain randomness method is Ethereum's RANDAO, where validators perform thousands of hashes on a seed and publish the final hash during a round. The collective input from all validators forms the random number, and as long as one honest validator participates, the randomness is secure. - -To enhance security, RANDAO can optionally be combined with a Verifiable Delay Function (VDF), ensuring that randomness can't be predicted or manipulated during computation. - -For more information about RANDAO, see the [Randomness - RANDAO](https://eth2book.info/capella/part2/building_blocks/randomness/){target=\_blank} section of the Upgrading Ethereum documentation. - -## VDFs - -Verifiable Delay Functions (VDFs) are time-bound computations that, even on parallel computers, take a set amount of time to complete. - -They produce a unique result that can be quickly verified publicly. When combined with RANDAO, feeding RANDAO's output into a VDF introduces a delay that nullifies an attacker's chance to influence the randomness. - -However, VDF likely requires specialized ASIC devices to run separately from standard nodes. - -!!!warning - While only one is needed to secure the system, and they will be open-source and inexpensive, running VDF devices involves significant costs without direct incentives, adding friction for blockchain users. - -## Additional Resources - -For more information about the reasoning for choices made along with proofs, see Polkadot's research on blockchain randomness and sortition in the [Block production](https://research.web3.foundation/Polkadot/protocols/block-production){target=\_blank} entry of the Polkadot Wiki. - -For a discussion with Web3 Foundation researchers about when and under what conditions Polkadot's randomness can be utilized, see the [Discussion on Randomness used in Polkadot](https://github.com/use-ink/ink/issues/57){target=\_blank} issue on GitHub. - - ---- - -Page Title: Set Up the Polkadot SDK Parachain Template - -- Source (raw): https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/parachains-launch-a-parachain-set-up-the-parachain-template.md -- Canonical (HTML): https://docs.polkadot.com/parachains/launch-a-parachain/set-up-the-parachain-template/ -- Summary: Learn how to set up and run the Polkadot SDK Parachain Template locally, creating a ready-to-customize foundation for your parachain. - -# Set Up the Polkadot SDK Parachain Template - -## Introduction - -The [Polkadot SDK](https://github.com/paritytech/polkadot-sdk){target=\_blank} includes several [templates](/parachains/customize-runtime/#starting-templates){target=\_blank} designed to help you quickly start building your own blockchain. Each template offers a different level of configuration, from minimal setups to feature-rich environments, allowing you to choose the foundation that best fits your project's needs. - -Among these, the [Parachain Template](https://github.com/paritytech/polkadot-sdk-parachain-template){target=\_blank} provides a preconfigured runtime with commonly used pallets, making it an ideal starting point for most parachain development projects. - -This guide walks you through the full process of working with this template. You will: - -- Set up the Polkadot SDK Parachain Template. -- Understand the project structure and key components. -- Verify your template is ready for development. -- Run the parachain template locally in development mode. - -By the end of this guide, you'll have a working template ready to customize and deploy as a parachain. - -## Prerequisites - -Before getting started, ensure you have done the following: - -- Completed the [Install Polkadot SDK](/parachains/install-polkadot-sdk/){target=\_blank} guide and successfully installed [Rust](https://www.rust-lang.org/){target=\_blank} and the required packages to set up your development environment. - -For this tutorial series, you need to use Rust `1.86`. Newer versions of the compiler may not work with this parachain template version. - -Run the following commands to set up the correct Rust version: - -=== "macOS" - - ```bash - rustup install 1.86 - rustup default 1.86 - rustup target add wasm32-unknown-unknown --toolchain 1.86-aarch64-apple-darwin - rustup component add rust-src --toolchain 1.86-aarch64-apple-darwin - ``` - -=== "Ubuntu" - - ```bash - rustup toolchain install 1.86.0 - rustup default 1.86.0 - rustup target add wasm32-unknown-unknown --toolchain 1.86.0 - rustup component add rust-src --toolchain 1.86.0 - ``` - -## Polkadot SDK Utility Tools - -This tutorial requires two essential tools: - -- [**Chain spec builder**](https://crates.io/crates/staging-chain-spec-builder/10.0.0){target=\_blank}: A Polkadot SDK utility for generating chain specifications. Refer to the [Generate Chain Specs](/parachains/launch-a-parachain/deploy-to-polkadot/#generate-the-chain-specification){target=\_blank} documentation for detailed usage. - - Install it by executing the following command: - - ```bash - cargo install --locked staging-chain-spec-builder@10.0.0 - ``` - - This command installs the `chain-spec-builder` binary. - -- [**Polkadot Omni Node**](https://crates.io/crates/polkadot-omni-node/0.5.0){target=\_blank}: A white-labeled binary, released as a part of Polkadot SDK that can act as the collator of a parachain in production, with all the related auxiliary functionalities that a normal collator node has: RPC server, archiving state, etc. Moreover, it can also run the Wasm blob of the parachain locally for testing and development. - - To install it, run the following command: - - ```bash - cargo install --locked polkadot-omni-node@0.5.0 - ``` - - This command installs the `polkadot-omni-node` binary. - -## Clone the Template - -The [Polkadot SDK Parachain Template](https://github.com/paritytech/polkadot-sdk-parachain-template){target=\_blank} provides a ready-to-use development environment for building with the [Polkadot SDK](https://github.com/paritytech/polkadot-sdk){target=\_blank}. Follow these steps to set up the template: - -1. Clone the template repository: - - ```bash - git clone https://github.com/paritytech/polkadot-sdk-parachain-template.git parachain-template - ``` - -2. Navigate into the project directory: - - ```bash - cd parachain-template - ``` - -## Explore the Project Structure - -Before building the template, take a moment to familiarize yourself with its structure. Understanding this organization will help you navigate the codebase as you develop your parachain. - -The template follows a standard Polkadot SDK project layout: - -```text -parachain-template/ -├── node/ # Node implementation and client -├── pallets/ # Custom pallets for your parachain -├── runtime/ # Runtime configuration and logic -├── Cargo.toml # Workspace configuration -└── README.md # Documentation -``` - -Key directories explained: - -- **runtime/**: Contains your parachain's state transition function and pallet configuration. This is where you'll define what your blockchain can do. -- **node/**: Houses the client implementation that runs your blockchain, handles networking, and manages the database. -- **pallets/**: Where you'll create custom business logic modules (pallets) for your specific use case. -- **Cargo.toml**: The workspace configuration that ties all components together. - -!!!note - The runtime is compiled to WebAssembly (Wasm), enabling forkless upgrades. The node binary remains constant while the runtime can be updated on-chain. - -## Compile the Runtime - -Now that you understand the template structure, let's compile the runtime to ensure everything is working correctly. - -1. Compile the runtime: - - ```bash - cargo build --release --locked - ``` - - !!!tip - Initial compilation may take several minutes, depending on your machine specifications. Use the `--release` flag for improved runtime performance compared to the default `--debug` build. If you need to troubleshoot issues, the `--debug` build provides better diagnostics. - - For production deployments, consider using a dedicated `--profile production` flag - this can provide an additional 15-30% performance improvement over the standard `--release` profile. - -2. Upon successful compilation, you should see output indicating the build was successful. The compiled runtime will be located at: - - `./target/release/wbuild/parachain-template-runtime/parachain_template_runtime.compact.compressed.wasm` - -## Verify the Build - -After compilation completes, verify that the runtime was created successfully by checking for the Wasm blob: - -```bash -ls -la ./target/release/wbuild/parachain-template-runtime/ -``` - -You should see the `parachain_template_runtime.compact.compressed.wasm` file in the output, confirming the build was successful. - -## Run the Node Locally - -After successfully compiling your runtime, you can spin up a local chain and produce blocks. This process will start your local parachain using the Polkadot Omni Node and allow you to interact with it. You'll first need to generate a chain specification that defines your network's identity, initial connections, and genesis state, providing the foundational configuration for how your nodes connect and what initial state they agree upon. - -Follow these steps to launch your node in development mode: - -1. Generate the chain specification file of your parachain: - - ```bash - chain-spec-builder create -t development \ - --relay-chain paseo \ - --para-id 1000 \ - --runtime ./target/release/wbuild/parachain-template-runtime/parachain_template_runtime.compact.compressed.wasm \ - named-preset development - ``` - -2. Start the Omni Node with the generated chain spec. You'll start it in development mode (without a relay chain config), producing and finalizing blocks: - - ```bash - polkadot-omni-node --chain ./chain_spec.json --dev - ``` - - The `--dev` option does the following: - - - Deletes all active data (keys, blockchain database, networking information) when stopped. - - Ensures a clean working state each time you restart the node. - -3. Verify that your node is running by reviewing the terminal output. You should see log messages indicating block production and finalization. - -4. Confirm that your blockchain is producing new blocks by checking if the number after `finalized` is increasing in the output. - -The details of the log output will be explored in a later tutorial. For now, knowing that your node is running and producing blocks is sufficient. - -## Interact with the Node - -When running the template node, it's accessible by default at `ws://localhost:9944`. To interact with your node using the [Polkadot.js Apps](https://polkadot.js.org/apps/#/explorer){target=\_blank} interface, follow these steps: - -1. Open [Polkadot.js Apps](https://polkadot.js.org/apps/#/explorer){target=\_blank} in your web browser and click the network icon (which should be the Polkadot logo) in the top left corner: - - ![](/images/parachains/launch-a-parachain/set-up-the-parachain-template/parachain-template-01.webp) - -2. Connect to your local node: - - 1. Scroll to the bottom and select **Development**. - 2. Choose **Custom**. - 3. Enter `ws://localhost:9944` in the **custom endpoint** input field. - 4. Click the **Switch** button. - - ![](/images/parachains/launch-a-parachain/set-up-the-parachain-template/parachain-template-02.webp) - -3. Once connected, you should see **parachain-template-runtime** in the top left corner, with the interface displaying information about your local blockchain. - - ![](/images/parachains/launch-a-parachain/set-up-the-parachain-template/parachain-template-03.webp) - -You are now connected to your local node and can interact with it through the Polkadot.js Apps interface. This tool enables you to explore blocks, execute transactions, and interact with your blockchain's features. For in-depth guidance on using the interface effectively, refer to the [Polkadot.js Guides](https://wiki.polkadot.com/general/polkadotjs/){target=\_blank} available on the Polkadot Wiki. - -## Stop the Node - -When you're done exploring your local node, you can stop it to remove any state changes you've made. Since you started the node with the `--dev` option, stopping the node will purge all persistent block data, allowing you to start fresh the next time. - -To stop the local node: - -1. Return to the terminal window where the node output is displayed. -2. Press `Control-C` to stop the running process. -3. Verify that your terminal returns to the prompt in the `parachain-template` directory. - -## Where to Go Next - -
- -- Tutorial __Deploy to Polkadot__ - - --- - - Learn how to deploy your parachain template to a relay chain testnet. Configure your chain specification, register as a parachain, and start producing blocks. - - [:octicons-arrow-right-24: Get Started](/parachains/launch-a-parachain/deploy-to-polkadot/) - -
- - ---- - -Page Title: Smart Contracts Cookbook - -- Source (raw): https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/smart-contracts-cookbook.md -- Canonical (HTML): https://docs.polkadot.com/smart-contracts/cookbook/ -- Summary: Explore our full collection of tutorials and guides to learn step-by-step how to build, deploy, and work with smart contracts on Polkadot. - -# Smart Contracts Cookbook - -Welcome to the Polkadot smart contracts cookbook index. - -This page contains a list of all relevant tutorials and guides to help you get started coding smart contracts and dApps in Polkadot. - - - - -## Get Tokens from the Faucet - -| Title | Difficulty | Tools | Description | -|------------------------------------|:-----------:|-------|-----------------------------------------------------------------------------------------------------------------------| -| [Faucet](/smart-contracts/faucet/) | 🟢 Beginner | N/A | Learn how to obtain test tokens from Polkadot faucets for development and testing purposes across different networks. | - -## EVM Smart Contracts - -| Title | Difficulty | Tools | Description | -|---------------------------------------------------------------------------------------------------------|:-----------:|--------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------| -| [Deploy an ERC-20 to Polkadot Hub](/smart-contracts/cookbook/smart-contracts/deploy-erc20/erc20-remix/) | 🟢 Beginner | EVM Wallet, Polkadot Remix IDE | Deploy an ERC-20 token on Polkadot Hub using PolkaVM. This guide covers contract creation, compilation, deployment, and interaction via Polkadot Remix IDE. | -| [Deploy an NFT to Polkadot Hub](/smart-contracts/cookbook/smart-contracts/deploy-nft/nft-remix/) | 🟢 Beginner | EVM Wallet, Polkadot Remix IDE | Deploy an NFT on Polkadot Hub using PolkaVM and OpenZeppelin. Learn how to compile, deploy, and interact with your contract using Polkadot Remix IDE. | - -## Port Ethereum DApps - -| Title | Difficulty | Tools | Description | -|-------------------------------------------------------------------------------------|:---------------:|---------|----------------------------------------------------------------------------------------------------------------------------------| -| [Deploying Uniswap V2 on Polkadot](/smart-contracts/cookbook/eth-dapps/uniswap-v2/) | 🟡 Intermediate | Hardhat | Learn how to deploy and test Uniswap V2 on Polkadot Hub using Hardhat, bringing AMM-based token swaps to the Polkadot ecosystem. | - - ---- - -Page Title: Smart Contracts Overview - -- Source (raw): https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/smart-contracts-overview.md -- Canonical (HTML): https://docs.polkadot.com/smart-contracts/overview/ -- Summary: Learn about smart contract development on Polkadot Hub with native PolkaVM support, dual-VM execution, and seamless cross-chain capabilities. - -# Smart Contracts on Polkadot Hub - -## Introduction - -Polkadot Hub provides a production-ready smart contract platform that combines Ethereum compatibility with the performance and cross-chain capabilities of the Polkadot ecosystem. Developers can deploy smart contracts directly on Polkadot Hub while using familiar Ethereum tooling, workflows, and programming languages. - -Built with a dual-VM approach, Polkadot Hub offers two execution backends: REVM for unmodified EVM compatibility and native PolkaVM for optimized computationally expensive workloads. This dual-VM architecture enables developers to migrate existing Ethereum contracts instantly or optimize for speed and efficiency with native execution. - -## Why Build on Polkadot Hub - -### Ethereum Compatibility - -Deploy existing Ethereum contracts with zero modifications while maintaining full compatibility with your existing development stack: - -- **Complete JSON-RPC API support**: Use MetaMask, Hardhat, Remix, Foundry, and all standard Ethereum tooling. -- **Standard libraries**: Integrate Ethers.js, Web3.js, Viem, Wagmi, and Web3.py without changes. -- **Solidity development**: Write contracts in Solidity or migrate existing code directly. -- **Familiar workflows**: Maintain your existing deployment, testing, and monitoring processes. - -### Performance Options - -Choose between two execution backends: - -- **REVM**: Run unmodified Ethereum contracts with full EVM/Ethereum compatibility. -- **PolkaVM**: Compile to optimized RISC-V bytecode for enhanced performance and lower fees while keeping Ethereum-compatibility. - -Both backends share the same RPC interface and tooling support, allowing seamless transitions. In addition, smart contracts can interact with Polkadot native services via [precompile contracts](/smart-contracts/precompiles/){target=\_blank}. - -### Cross-VM & Cross-Chain Capabilities - -Smart contracts written for one VM (for example, EVM) can interact directly with other smart contracts written for the RISC-V PolkaVM, and back. This allows to use full EVM compatible contracts but extend to heavy/complex execution workloads to the PolkaVM RISC-V backend. - -Furthermore, all smart contracts in Polkadot Hub can interact with any service in the Polkadot ecosystem through [XCM](/smart-contracts/precompiles/xcm/){target=\_blank}, enabling token transfers, remote execution, and cross-chain composability without bridges or intermediaries. - -## Other Smart Contract Environments - -Beyond Polkadot Hub's native PolkaVM support, the ecosystem offers two main alternatives for smart contract development: - -- **EVM-compatible parachains**: Provide access to Ethereum's extensive developer ecosystem, smart contract portability, and established tooling like Hardhat, Remix, Foundry, and OpenZeppelin. The main options include Moonbeam (the first full Ethereum-compatible parachain serving as an interoperability hub), Astar (featuring dual VM support for both EVM and WebAssembly contracts), and Acala (DeFi-focused with enhanced Acala EVM+ offering advanced DeFi primitives). - -- **Rust (ink!)**: ink! is a Rust-based framework that can compile to PolkaVM. It uses [`#[ink(...)]`](https://use.ink/docs/v6/macros-attributes/){target=\_blank} attribute macros to create Polkadot SDK-compatible PolkaVM bytecode, offering strong memory safety from Rust, an advanced type system, high-performance PolkaVM execution, and platform independence with sandboxed security. - -## Next Steps - -
- -- Guide __Get Started__ - - --- - - Quick-start guides for connecting, deploying, and building your first smart contract. - - [:octicons-arrow-right-24: Get Started](/smart-contracts/get-started/) - -- Guide __Cookbook__ - - --- - - Step-by-step tutorials for deploying contracts, tokens, NFTs, and full dApps. - - [:octicons-arrow-right-24: View Tutorials](/smart-contracts/cookbook/) - -- Guide __Ethereum Developers__ - - --- - - Understand key differences in accounts, fees, gas model, and deployment on Polkadot Hub. - - [:octicons-arrow-right-24: Learn More](/smart-contracts/for-eth-devs/accounts/) - -- Guide __Precompiles__ - - --- - - Discover advanced functionalities including XCM for cross-chain interactions. - - [:octicons-arrow-right-24: Explore Precompiles](/smart-contracts/precompiles/) - -
+ !!!tip + Initial compilation may take several minutes, depending on your machine specifications. Use the `--release` flag for improved runtime performance compared to the default `--debug` build. If you need to troubleshoot issues, the `--debug` build provides better diagnostics. + + For production deployments, consider using a dedicated `--profile production` flag - this can provide an additional 15-30% performance improvement over the standard `--release` profile. +2. Upon successful compilation, you should see output indicating the build was successful. The compiled runtime will be located at: + + `./target/release/wbuild/parachain-template-runtime/parachain_template_runtime.compact.compressed.wasm` ---- +## Verify the Build -Page Title: Subxt Rust API +After compilation completes, verify that the runtime was created successfully by checking for the Wasm blob: -- Source (raw): https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/reference-tools-subxt.md -- Canonical (HTML): https://docs.polkadot.com/reference/tools/subxt/ -- Summary: Subxt is a Rust library for type-safe interaction with Polkadot SDK blockchains, enabling transactions, state queries, runtime API access, and more. +```bash +ls -la ./target/release/wbuild/parachain-template-runtime/ +``` -# Subxt Rust API +You should see the `parachain_template_runtime.compact.compressed.wasm` file in the output, confirming the build was successful. -## Introduction +## Run the Node Locally -Subxt is a Rust library designed to interact with Polkadot SDK-based blockchains. It provides a type-safe interface for submitting transactions, querying on-chain state, and performing other blockchain interactions. By leveraging Rust's strong type system, subxt ensures that your code is validated at compile time, reducing runtime errors and improving reliability. +After successfully compiling your runtime, you can spin up a local chain and produce blocks. This process will start your local parachain using the Polkadot Omni Node and allow you to interact with it. You'll first need to generate a chain specification that defines your network's identity, initial connections, and genesis state, providing the foundational configuration for how your nodes connect and what initial state they agree upon. -## Prerequisites +Follow these steps to launch your node in development mode: -Before using subxt, ensure you have the following requirements: +1. Generate the chain specification file of your parachain: -- Rust and Cargo installed on your system. You can install them using [Rustup](https://rustup.rs/){target=\_blank}. -- A Rust project initialized. If you don't have one, create it with: ```bash - cargo new my_project && cd my_project + chain-spec-builder create -t development \ + --relay-chain paseo \ + --para-id 1000 \ + --runtime ./target/release/wbuild/parachain-template-runtime/parachain_template_runtime.compact.compressed.wasm \ + named-preset development ``` -## Installation - -To use subxt in your project, you must install the necessary dependencies. Each plays a specific role in enabling interaction with the blockchain: - -1. **Install the subxt CLI**: [`subxt-cli`](https://crates.io/crates/subxt-cli){target=\_blank} is a command-line tool that provides utilities for working with Polkadot SDK metadata. In the context of subxt, it is essential to download chain metadata, which is required to generate type-safe Rust interfaces for interacting with the blockchain. Install it using the following: +2. Start the Omni Node with the generated chain spec. You'll start it in development mode (without a relay chain config), producing and finalizing blocks: ```bash - cargo install subxt-cli@0.44.0 - ``` - -2. **Add core dependencies**: These dependencies are essential for interacting with the blockchain. - - - **[subxt](https://crates.io/crates/subxt){target=\_blank}**: The main library for communicating with Polkadot SDK nodes. It handles RPC requests, encoding/decoding, and type generation. - - ```bash - cargo add subxt@0.44.0 - ``` - - - **[subxt-signer](https://crates.io/crates/subxt-signer){target=\_blank}**: Provides cryptographic functionality for signing transactions. Without this, you can only read data but cannot submit transactions. - - ```bash - cargo add subxt-signer@0.44.0 - ``` - - - **[tokio](https://crates.io/crates/tokio){target=\_blank}**: An asynchronous runtime for Rust. Since blockchain operations are async, Tokio enables the efficient handling of network requests. The `rt` feature enables Tokio's runtime, including the current-thread single-threaded scheduler, which is necessary for async execution. The `macros` feature provides procedural macros like `#[tokio::main]` to simplify runtime setup. - - ```bash - cargo add tokio@1.44.2 --features rt,macros - ``` - - After adding the dependencies, your `Cargo.toml` should look like this: - - ```toml - [package] - name = "my_project" - version = "0.1.0" - edition = "2021" - - [dependencies] - subxt = "0.41.0" - subxt-signer = "0.41.0" - tokio = { version = "1.44.2", features = ["rt", "macros"] } - + polkadot-omni-node --chain ./chain_spec.json --dev ``` -## Get Started - -This guide will walk you through the fundamental operations of subxt, from setting up your environment to executing transactions and querying blockchain state. - -### Download Chain Metadata - -Before interacting with a blockchain, you need to retrieve its metadata. This metadata defines storage structures, extrinsics, and other runtime details. Use the `subxt-cli` tool to download the metadata, replacing `INSERT_NODE_URL` with the URL of the node you want to interact with: - -```bash -subxt metadata --url INSERT_NODE_URL > polkadot_metadata.scale -``` - -### Generate Type-Safe Interfaces - -Use the `#[subxt::subxt]` macro to generate a type-safe Rust interface from the downloaded metadata: - -```rust -// Generate an interface that we can use from the node's metadata. -#[subxt::subxt(runtime_metadata_path = "./polkadot_metadata.scale")] -pub mod polkadot {} -``` - -Once subxt interfaces are generated, you can interact with your node in the following ways. You can use the links below to view the related subxt documentation: - -- **[Transactions](https://docs.rs/subxt/latest/subxt/book/usage/transactions/index.html){target=\_blank}**: Builds and submits transactions, monitors their inclusion in blocks, and retrieves associated events. -- **[Storage](https://docs.rs/subxt/latest/subxt/book/usage/storage/index.html){target=\_blank}**: Enables querying of node storage data. -- **[Events](https://docs.rs/subxt/latest/subxt/book/usage/events/index.html){target=\_blank}**: Retrieves events emitted from recent blocks. -- **[Constants](https://docs.rs/subxt/latest/subxt/book/usage/constants/index.html){target=\_blank}**: Accesses constant values stored in nodes that remain unchanged across a specific runtime version. -- **[Blocks](https://docs.rs/subxt/latest/subxt/book/usage/blocks/index.html){target=\_blank}**: Loads recent blocks or subscribes to new/finalized blocks, allowing examination of extrinsics, events, and storage at those blocks. -- **[Runtime APIs](https://docs.rs/subxt/latest/subxt/book/usage/runtime_apis/index.html){target=\_blank}**: Makes calls into pallet runtime APIs to fetch data. -- **[Custom values](https://docs.rs/subxt/latest/subxt/book/usage/custom_values/index.html){target=\_blank}**: Accesses "custom values" contained within metadata. -- **[Raw RPC calls](https://docs.rs/subxt/latest/subxt/book/usage/rpc/index.html){target=\_blank}**: Facilitates raw RPC requests to compatible nodes. - -### Initialize the Subxt Client - -To interact with a blockchain node using subxt, create an asynchronous main function and initialize the client. Replace `INSERT_NODE_URL` with the URL of your target node: - -```rust -use std::str::FromStr; -use subxt::utils::AccountId32; -use subxt::{OnlineClient, PolkadotConfig}; -use subxt_signer::{bip39::Mnemonic,sr25519::Keypair}; - -// Generate an interface that we can use from the node's metadata. -#[subxt::subxt(runtime_metadata_path = "./polkadot_metadata.scale")] -pub mod polkadot {} - -#[tokio::main(flavor = "current_thread")] -async fn main() -> Result<(), Box> { - // Define the node URL. - const NODE_URL: &str = "INSERT_NODE_URL"; + The `--dev` option does the following: - // Initialize the Subxt client to interact with the blockchain. - let api = OnlineClient::::from_url(NODE_URL).await?; + - Deletes all active data (keys, blockchain database, networking information) when stopped. + - Ensures a clean working state each time you restart the node. - // Your code here... +3. Verify that your node is running by reviewing the terminal output. You should see log messages indicating block production and finalization. - Ok(()) -} -``` +4. Confirm that your blockchain is producing new blocks by checking if the number after `finalized` is increasing in the output. -### Read Chain Data +The details of the log output will be explored in a later tutorial. For now, knowing that your node is running and producing blocks is sufficient. -subxt provides multiple ways to access on-chain data: +## Interact with the Node -- **Constants**: Constants are predefined values in the runtime that remain unchanged unless modified by a runtime upgrade. +When running the template node, it's accessible by default at `ws://localhost:9944`. To interact with your node using the [Polkadot.js Apps](https://polkadot.js.org/apps/#/explorer){target=\_blank} interface, follow these steps: - For example, to retrieve the existential deposit, use: +1. Open [Polkadot.js Apps](https://polkadot.js.org/apps/#/explorer){target=\_blank} in your web browser and click the network icon (which should be the Polkadot logo) in the top left corner: - ```rust - // A query to obtain some constant. - let constant_query = polkadot::constants().balances().existential_deposit(); - - // Obtain the value. - let value = api.constants().at(&constant_query)?; - - println!("Existential deposit: {:?}", value); - ``` - -- **State**: State refers to the current chain data, which updates with each block. - - To fetch account information, replace `INSERT_ADDRESS` with the address you want to fetch data from and use: - - ```rust - // Define the target account address. - const ADDRESS: &str = "INSERT_ADDRESS"; - let account = AccountId32::from_str(ADDRESS).unwrap(); - - // Build a storage query to access account information. - let storage_query = polkadot::storage().system().account(&account.into()); - - // Fetch the latest state for the account. - let result = api - .storage() - .at_latest() - .await? - .fetch(&storage_query) - .await? - .unwrap(); - - println!("Account info: {:?}", result); - ``` - -### Submit Transactions - -To submit a transaction, you must construct an extrinsic, sign it with your private key, and send it to the blockchain. Replace `INSERT_DEST_ADDRESS` with the recipient's address, `INSERT_AMOUNT` with the amount to transfer, and `INSERT_SECRET_PHRASE` with the sender's mnemonic phrase: - -```rust - // Define the recipient address and transfer amount. - const DEST_ADDRESS: &str = "INSERT_DEST_ADDRESS"; - const AMOUNT: u128 = INSERT_AMOUNT; - - // Convert the recipient address into an `AccountId32`. - let dest = AccountId32::from_str(DEST_ADDRESS).unwrap(); - - // Build the balance transfer extrinsic. - let balance_transfer_tx = polkadot::tx() - .balances() - .transfer_allow_death(dest.into(), AMOUNT); - - // Load the sender's keypair from a mnemonic phrase. - const SECRET_PHRASE: &str = "INSERT_SECRET_PHRASE"; - let mnemonic = Mnemonic::parse(SECRET_PHRASE).unwrap(); - let sender_keypair = Keypair::from_phrase(&mnemonic, None).unwrap(); - - // Sign and submit the extrinsic, then wait for it to be finalized. - let events = api - .tx() - .sign_and_submit_then_watch_default(&balance_transfer_tx, &sender_keypair) - .await? - .wait_for_finalized_success() - .await?; - - // Check for a successful transfer event. - if let Some(event) = events.find_first::()? { - println!("Balance transfer successful: {:?}", event); - } -``` - -## Where to Go Next - -Now that you've covered the basics dive into the official [subxt documentation](https://docs.rs/subxt/latest/subxt/book/index.html){target=\_blank} for comprehensive reference materials and advanced features. - - ---- - -Page Title: Technical Reference Overview - -- Source (raw): https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/reference.md -- Canonical (HTML): https://docs.polkadot.com/reference/ -- Summary: Learn about Polkadot's technical architecture, governance framework, parachain ecosystem, and the tools you need to build and interact with the network. - -## Introduction - -The Technical Reference section provides comprehensive documentation of Polkadot's architecture, core concepts, and development tooling. Whether you're exploring how Polkadot's relay chain coordinates parachains, understanding governance mechanisms, or building applications on the network, this reference covers the technical foundations you need. - -Polkadot is a multi-chain network that enables diverse, interconnected blockchains to share security and communicate seamlessly. Understanding how these components interact from the [relay chain](/polkadot-protocol/glossary#relay-chain){target=\_blank} that validates [parachains](/polkadot-protocol/glossary#parachain){target=\_blank} to the [governance](/reference/glossary#governance){target=\_blank} mechanisms that evolve the protocol is essential for developers, validators, and network participants. - -This guide organizes technical documentation across five core areas: Polkadot Hub, Parachains, On-Chain Governance, Glossary, and Tools, each providing detailed information on different aspects of the Polkadot ecosystem. - -## Polkadot Hub - -[Polkadot Hub](/reference/polkadot-hub/){target=\_blank} is the entry point to Polkadot for all users and application developers. It provides access to essential Web3 services, including smart contracts, staking, governance, identity management, and cross-ecosystem interoperability—without requiring you to deploy or manage a parachain. - -The Hub encompasses a set of core functionality that enables developers and users to build and interact with applications on Polkadot. Key capabilities include: - -- **Smart contracts**: Deploy Ethereum-compatible smart contracts and build decentralized applications. -- **Assets and tokens**: Create, manage, and transfer fungible tokens and NFTs across the ecosystem. -- **Staking**: Participate in network security and earn rewards by staking DOT. -- **Governance**: Vote on proposals and participate in Polkadot's decentralized decision-making through OpenGov. -- **Identity services**: Register and manage on-chain identities, enabling access to governance roles and network opportunities. -- **Cross-chain interoperability**: Leverage XCM messaging to interact securely with other chains in the Polkadot ecosystem. -- **Collectives and DAOs**: Participate in governance collectives and decentralized autonomous organizations. - -## Parachains - -[Parachains](/reference/parachains/){target=\_blank} are specialized blockchains that connect to the Polkadot relay chain, inheriting its security while maintaining their own application-specific logic. The parachains documentation covers: - -- **Accounts**: Deep dive into account types, storage, and management on parachains. -- **Blocks, transactions and fees**: Understand block production, transaction inclusion, and fee mechanisms. -- **Consensus**: Learn how parachain blocks are validated and finalized through the relay chain's consensus. -- **Chain data**: Explore data structures, storage layouts, and state management. -- **Cryptography**: Study cryptographic primitives used in Polkadot SDK-based chains. -- **Data encoding**: Understand how data is encoded and decoded for blockchain compatibility. -- **Networks**: Learn about networking protocols and peer-to-peer communication. -- **Interoperability**: Discover [Cross-Consensus Messaging (XCM)](/parachains/interoperability/get-started/){target=\_blank}, the standard for cross-chain communication. -- **Randomness**: Understand how randomness is generated and used in Polkadot chains. -- **Node and runtime**: Learn about parachain nodes, runtime environments, and the [Polkadot SDK](https://github.com/paritytech/polkadot-sdk){target=\_blank}. - -## On-Chain Governance + ![](/images/parachains/launch-a-parachain/set-up-the-parachain-template/parachain-template-01.webp) -[On-Chain governance](/reference/governance/){target=\_blank} is the decentralized decision-making mechanism for the Polkadot network. It manages the evolution and modification of the network's runtime logic, enabling community oversight and approval for proposed changes. The governance documentation details: +2. Connect to your local node: -- **OpenGov framework**: Understand Polkadot's next-generation governance system with enhanced delegation, flexible tracks, and simultaneous referendums. -- **Origins and tracks**: Learn how governance proposals are categorized, prioritized, and executed based on their privilege level and complexity. -- **Voting and delegation**: Explore conviction voting, vote delegation, and how token holders participate in governance. -- **Governance evolution**: See how Polkadot's governance has evolved from Governance V1 to the current OpenGov system. + 1. Scroll to the bottom and select **Development**. + 2. Choose **Custom**. + 3. Enter `ws://localhost:9944` in the **custom endpoint** input field. + 4. Click the **Switch** button. + + ![](/images/parachains/launch-a-parachain/set-up-the-parachain-template/parachain-template-02.webp) -## Glossary +3. Once connected, you should see **parachain-template-runtime** in the top left corner, with the interface displaying information about your local blockchain. + + ![](/images/parachains/launch-a-parachain/set-up-the-parachain-template/parachain-template-03.webp) -The [Glossary](/reference/glossary/){target=\_blank} provides quick-reference definitions for Polkadot-specific terminology. Essential terms include: +You are now connected to your local node and can interact with it through the Polkadot.js Apps interface. This tool enables you to explore blocks, execute transactions, and interact with your blockchain's features. For in-depth guidance on using the interface effectively, refer to the [Polkadot.js Guides](https://wiki.polkadot.com/general/polkadotjs/){target=\_blank} available on the Polkadot Wiki. -- Blockchain concepts (blocks, transactions, state) -- Consensus mechanisms (validators, collators, finality) -- Polkadot-specific terms (relay chain, parachain, XCM, FRAME) -- Network components (nodes, runtimes, storage) -- Governance terminology (origins, tracks, referendums) +## Stop the Node -## Tools +When you're done exploring your local node, you can stop it to remove any state changes you've made. Since you started the node with the `--dev` option, stopping the node will purge all persistent block data, allowing you to start fresh the next time. -The [Tools](/reference/tools/){target=\_blank} section documents essential development and interaction tools for the Polkadot ecosystem: +To stop the local node: -- **Light clients**: Lightweight solutions for interacting with the network without running full nodes. -- **JavaScript/TypeScript tools**: Libraries like [Polkadot.js API](/reference/tools/polkadot-js-api/){target=\_blank} and [PAPI](/reference/tools/papi/){target=\_blank} for building applications. -- **Rust tools**: [Polkadart](/reference/tools/polkadart/){target=\_blank} and other Rust-based libraries for SDK development. -- **Python tools**: [py-substrate-interface](/reference/tools/py-substrate-interface/){target=\_blank} for Python developers. -- **Testing and development**: Tools like [Moonwall](/reference/tools/moonwall/){target=\_blank}, [Chopsticks](/reference/tools/chopsticks/){target=\_blank}, and [Omninode](/reference/tools/omninode/){target=\_blank} for smart contract and parachain testing. -- **Indexing and monitoring**: [Sidecar](/reference/tools/sidecar/){target=\_blank} for data indexing and [Dedot](/reference/tools/dedot/){target=\_blank} for substrate interaction. -- **Cross-chain tools**: [ParaSpell](/reference/tools/paraspell/){target=\_blank} for XCM integration and asset transfers. +1. Return to the terminal window where the node output is displayed. +2. Press `Control-C` to stop the running process. +3. Verify that your terminal returns to the prompt in the `parachain-template` directory. ## Where to Go Next -For detailed exploration of specific areas, proceed to any of the main sections: -
-- Learn **Polkadot Hub** - - --- - - Understand the relay chain's role in coordinating parachains, providing shared security, and enabling governance. - - [:octicons-arrow-right-24: Reference](/reference/polkadot-hub/) - -- Learn **Parachains** - - --- - - Deep dive into parachain architecture, consensus, data structures, and building application-specific blockchains. - - [:octicons-arrow-right-24: Reference](/reference/parachains/) - -- Learn **On-Chain Governance** - - --- - - Explore Polkadot's decentralized governance framework and how to participate in network decision-making. - - [:octicons-arrow-right-24: Reference](/reference/governance/) - -- Guide **Glossary** - - --- - - Quick reference for Polkadot-specific terminology and concepts used throughout the documentation. - - [:octicons-arrow-right-24: Reference](/reference/glossary/) - -- Guide **Tools** +- Tutorial __Deploy to Polkadot__ --- - Discover development tools, libraries, and frameworks for building and interacting with Polkadot. + Learn how to deploy your parachain template to a relay chain testnet. Configure your chain specification, register as a parachain, and start producing blocks. - [:octicons-arrow-right-24: Reference](/reference/tools/) + [:octicons-arrow-right-24: Get Started](/parachains/launch-a-parachain/deploy-to-polkadot/)
--- -Page Title: Transactions - -- Source (raw): https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/reference-parachains-blocks-transactions-fees-transactions.md -- Canonical (HTML): https://docs.polkadot.com/reference/parachains/blocks-transactions-fees/transactions/ -- Summary: Learn how to construct, submit, and validate transactions in the Polkadot SDK, covering signed, unsigned, and inherent types of transactions. - -# Transactions - -## Introduction - -Transactions are essential components of blockchain networks, enabling state changes and the execution of key operations. In the Polkadot SDK, transactions, often called extrinsics, come in multiple forms, including signed, unsigned, and inherent transactions. - -This guide walks you through the different transaction types and how they're formatted, validated, and processed within the Polkadot ecosystem. You'll also learn how to customize transaction formats and construct transactions for FRAME-based runtimes, ensuring a complete understanding of how transactions are built and executed in Polkadot SDK-based chains. - -## What Is a Transaction? - -In the Polkadot SDK, transactions represent operations that modify the chain's state, bundled into blocks for execution. The term extrinsic is often used to refer to any data that originates outside the runtime and is included in the chain. While other blockchain systems typically refer to these operations as "transactions," the Polkadot SDK adopts the broader term "extrinsic" to capture the wide variety of data types that can be added to a block. - -There are three primary types of transactions (extrinsics) in the Polkadot SDK: - -- **Signed transactions**: Signed by the submitting account, often carrying transaction fees. -- **Unsigned transactions**: Submitted without a signature, often requiring custom validation logic. -- **Inherent transactions**: Typically inserted directly into blocks by block authoring nodes, without gossiping between peers. - -Each type serves a distinct purpose, and understanding when and how to use each is key to efficiently working with the Polkadot SDK. - -### Signed Transactions - -Signed transactions require an account's signature and typically involve submitting a request to execute a runtime call. The signature serves as a form of cryptographic proof that the sender has authorized the action, using their private key. These transactions often involve a transaction fee to cover the cost of execution and incentivize block producers. - -Signed transactions are the most common type of transaction and are integral to user-driven actions, such as token transfers. For instance, when you transfer tokens from one account to another, the sending account must sign the transaction to authorize the operation. - -For example, the [`pallet_balances::Call::transfer_allow_death`](https://paritytech.github.io/polkadot-sdk/master/pallet_balances/pallet/struct.Pallet.html#method.transfer_allow_death){target=\_blank} extrinsic in the Balances pallet allows you to transfer tokens. Since your account initiates this transaction, your account key is used to sign it. You'll also be responsible for paying the associated transaction fee, with the option to include an additional tip to incentivize faster inclusion in the block. - -### Unsigned Transactions - -Unsigned transactions do not require a signature or account-specific data from the sender. Unlike signed transactions, they do not come with any form of economic deterrent, such as fees, which makes them susceptible to spam or replay attacks. Custom validation logic must be implemented to mitigate these risks and ensure these transactions are secure. - -Unsigned transactions typically involve scenarios where including a fee or signature is unnecessary or counterproductive. However, due to the absence of fees, they require careful validation to protect the network. For example, [`pallet_im_online::Call::heartbeat`](https://paritytech.github.io/polkadot-sdk/master/pallet_im_online/pallet/struct.Pallet.html#method.heartbeat){target=\_blank} extrinsic allows validators to send a heartbeat signal, indicating they are active. Since only validators can make this call, the logic embedded in the transaction ensures that the sender is a validator, making the need for a signature or fee redundant. - -Unsigned transactions are more resource-intensive than signed ones because custom validation is required, but they play a crucial role in certain operational scenarios, especially when regular user accounts aren't involved. - -### Inherent Transactions - -Inherent transactions are a specialized type of unsigned transaction that is used primarily for block authoring. Unlike signed or other unsigned transactions, inherent transactions are added directly by block producers and are not broadcasted to the network or stored in the transaction queue. They don't require signatures or the usual validation steps and are generally used to insert system-critical data directly into blocks. - -A key example of an inherent transaction is inserting a timestamp into each block. The [`pallet_timestamp::Call::now`](https://paritytech.github.io/polkadot-sdk/master/pallet_timestamp/pallet/struct.Pallet.html#method.now-1){target=\_blank} extrinsic allows block authors to include the current time in the block they are producing. Since the block producer adds this information, there is no need for transaction validation, like signature verification. The validation in this case is done indirectly by the validators, who check whether the timestamp is within an acceptable range before finalizing the block. - -Another example is the [`paras_inherent::Call::enter`](https://paritytech.github.io/polkadot-sdk/master/polkadot_runtime_parachains/paras_inherent/pallet/struct.Pallet.html#method.enter){target=\_blank} extrinsic, which enables parachain collator nodes to send validation data to the relay chain. This inherent transaction ensures that the necessary parachain data is included in each block without the overhead of gossiped transactions. - -Inherent transactions serve a critical role in block authoring by allowing important operational data to be added directly to the chain without needing the validation processes required for standard transactions. - -## Transaction Formats - -Understanding the structure of signed and unsigned transactions is crucial for developers building on Polkadot SDK-based chains. Whether you're optimizing transaction processing, customizing formats, or interacting with the transaction pool, knowing the format of extrinsics, Polkadot's term for transactions, is essential. - -### Types of Transaction Formats - -In Polkadot SDK-based chains, extrinsics can fall into three main categories: - -- **Unchecked extrinsics**: Typically used for signed transactions that require validation. They contain a signature and additional data, such as a nonce and information for fee calculation. Unchecked extrinsics are named as such because they require validation checks before being accepted into the transaction pool. -- **Checked extrinsics**: Typically used for inherent extrinsics (unsigned transactions); these don't require signature verification. Instead, they carry information such as where the extrinsic originates and any additional data required for the block authoring process. -- **Opaque extrinsics**: Used when the format of an extrinsic is not yet fully committed or finalized. They are still decodable, but their structure can be flexible depending on the context. - -### Signed Transaction Data Structure - -A signed transaction typically includes the following components: - -- **Signature**: Verifies the authenticity of the transaction sender. -- **Call**: The actual function or method call the transaction is requesting (for example, transferring funds). -- **Nonce**: Tracks the number of prior transactions sent from the account, helping to prevent replay attacks. -- **Tip**: An optional incentive to prioritize the transaction in block inclusion. -- **Additional data**: Includes details such as spec version, block hash, and genesis hash to ensure the transaction is valid within the correct runtime and chain context. - -Here's a simplified breakdown of how signed transactions are typically constructed in a Polkadot SDK runtime: - -``` code - + + -``` - -Each part of the signed transaction has a purpose, ensuring the transaction's authenticity and context within the blockchain. - -### Signed Extensions - -Polkadot SDK also provides the concept of [signed extensions](https://paritytech.github.io/polkadot-sdk/master/polkadot_sdk_docs/reference_docs/signed_extensions/index.html){target=\_blank}, which allow developers to extend extrinsics with additional data or validation logic before they are included in a block. The [`SignedExtension`](https://paritytech.github.io/try-runtime-cli/sp_runtime/traits/trait.SignedExtension.html){target=\_blank} set helps enforce custom rules or protections, such as ensuring the transaction's validity or calculating priority. - -The transaction queue regularly calls signed extensions to verify a transaction's validity before placing it in the ready queue. This safeguard ensures transactions won't fail in a block. Signed extensions are commonly used to enforce validation logic and protect the transaction pool from spam and replay attacks. - -In FRAME, a signed extension can hold any of the following types by default: - -- **[`AccountId`](https://paritytech.github.io/polkadot-sdk/master/polkadot_sdk_frame/runtime/types_common/type.AccountId.html){target=\_blank}**: To encode the sender's identity. -- **[`Call`](https://paritytech.github.io/polkadot-sdk/master/polkadot_sdk_frame/traits/trait.SignedExtension.html#associatedtype.Call){target=\_blank}**: To encode the pallet call to be dispatched. This data is used to calculate transaction fees. -- **[`AdditionalSigned`](https://paritytech.github.io/polkadot-sdk/master/polkadot_sdk_frame/traits/trait.SignedExtension.html#associatedtype.AdditionalSigned){target=\_blank}**: To handle any additional data to go into the signed payload allowing you to attach any custom logic prior to dispatching a transaction. -- **[`Pre`](https://paritytech.github.io/polkadot-sdk/master/polkadot_sdk_frame/traits/trait.SignedExtension.html#associatedtype.Pre){target=\_blank}**: To encode the information that can be passed from before a call is dispatched to after it gets dispatched. - -Signed extensions can enforce checks like: - -- **[`CheckSpecVersion`](https://paritytech.github.io/polkadot-sdk/master/src/frame_system/extensions/check_spec_version.rs.html){target=\_blank}**: Ensures the transaction is compatible with the runtime's current version. -- **[`CheckWeight`](https://paritytech.github.io/polkadot-sdk/master/frame_system/struct.CheckWeight.html){target=\_blank}**: Calculates the weight (or computational cost) of the transaction, ensuring the block doesn't exceed the maximum allowed weight. - -These extensions are critical in the transaction lifecycle, ensuring that only valid and prioritized transactions are processed. - -## Transaction Construction - -Building transactions in the Polkadot SDK involves constructing a payload that can be verified, signed, and submitted for inclusion in a block. Each runtime in the Polkadot SDK has its own rules for validating and executing transactions, but there are common patterns for constructing a signed transaction. - -### Construct a Signed Transaction - -A signed transaction in the Polkadot SDK includes various pieces of data to ensure security, prevent replay attacks, and prioritize processing. Here's an overview of how to construct one: - -1. **Construct the unsigned payload**: Gather the necessary information for the call, including: - - - **Pallet index**: Identifies the pallet where the runtime function resides. - - **Function index**: Specifies the particular function to call in the pallet. - - **Parameters**: Any additional arguments required by the function call. - -2. **Create a signing payload**: Once the unsigned payload is ready, additional data must be included: - - - **Transaction nonce**: Unique identifier to prevent replay attacks. - - **Era information**: Defines how long the transaction is valid before it's dropped from the pool. - - **Block hash**: Ensures the transaction doesn't execute on the wrong chain or fork. - -3. **Sign the payload**: Using the sender's private key, sign the payload to ensure that the transaction can only be executed by the account holder. -4. **Serialize the signed payload**: Once signed, the transaction must be serialized into a binary format, ensuring the data is compact and easy to transmit over the network. -5. **Submit the serialized transaction**: Finally, submit the serialized transaction to the network, where it will enter the transaction pool and wait for processing by an authoring node. - -The following is an example of how a signed transaction might look: +Page Title: Smart Contracts Cookbook -``` rust -node_runtime::UncheckedExtrinsic::new_signed( - function.clone(), // some call - sp_runtime::AccountId32::from(sender.public()).into(), // some sending account - node_runtime::Signature::Sr25519(signature.clone()), // the account's signature - extra.clone(), // the signed extensions -) -``` +- Source (raw): https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/smart-contracts-cookbook.md +- Canonical (HTML): https://docs.polkadot.com/smart-contracts/cookbook/ +- Summary: Explore our full collection of tutorials and guides to learn step-by-step how to build, deploy, and work with smart contracts on Polkadot. -### Transaction Encoding +# Smart Contracts Cookbook -Before a transaction is sent to the network, it is serialized and encoded using a structured encoding process that ensures consistency and prevents tampering: +Welcome to the Polkadot smart contracts cookbook index. -- **`[1]`**: Compact encoded length in bytes of the entire transaction. -- **`[2]`**: A u8 containing 1 byte to indicate whether the transaction is signed or unsigned (1 bit) and the encoded transaction version ID (7 bits). -- **`[3]`**: If signed, this field contains an account ID, an SR25519 signature, and some extra data. -- **`[4]`**: Encoded call data, including pallet and function indices and any required arguments. +This page contains a list of all relevant tutorials and guides to help you get started coding smart contracts and dApps in Polkadot. -This encoded format ensures consistency and efficiency in processing transactions across the network. By adhering to this format, applications can construct valid transactions and pass them to the network for execution. -To learn more about how compact encoding works using SCALE, see the [SCALE Codec](https://github.com/paritytech/parity-scale-codec){target=\_blank} README on GitHub. -### Customize Transaction Construction -Although the basic steps for constructing transactions are consistent across Polkadot SDK-based chains, developers can customize transaction formats and validation rules. For example: +## Get Tokens from the Faucet -- **Custom pallets**: You can define new pallets with custom function calls, each with its own parameters and validation logic. -- **Signed extensions**: Developers can implement custom extensions that modify how transactions are prioritized, validated, or included in blocks. +| Title | Difficulty | Tools | Description | +|------------------------------------|:-----------:|-------|-----------------------------------------------------------------------------------------------------------------------| +| [Faucet](/smart-contracts/faucet/) | 🟢 Beginner | N/A | Learn how to obtain test tokens from Polkadot faucets for development and testing purposes across different networks. | -By leveraging Polkadot SDK's modular design, developers can create highly specialized transaction logic tailored to their chain's needs. +## EVM Smart Contracts -## Lifecycle of a Transaction +| Title | Difficulty | Tools | Description | +|---------------------------------------------------------------------------------------------------------|:-----------:|--------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------| +| [Deploy an ERC-20 to Polkadot Hub](/smart-contracts/cookbook/smart-contracts/deploy-erc20/erc20-remix/) | 🟢 Beginner | EVM Wallet, Polkadot Remix IDE | Deploy an ERC-20 token on Polkadot Hub using PolkaVM. This guide covers contract creation, compilation, deployment, and interaction via Polkadot Remix IDE. | +| [Deploy an NFT to Polkadot Hub](/smart-contracts/cookbook/smart-contracts/deploy-nft/nft-remix/) | 🟢 Beginner | EVM Wallet, Polkadot Remix IDE | Deploy an NFT on Polkadot Hub using PolkaVM and OpenZeppelin. Learn how to compile, deploy, and interact with your contract using Polkadot Remix IDE. | -In the Polkadot SDK, transactions are often referred to as extrinsics because the data in transactions originates outside of the runtime. These transactions contain data that initiates changes to the chain state. The most common type of extrinsic is a signed transaction, which is cryptographically verified and typically incurs a fee. This section focuses on how signed transactions are processed, validated, and ultimately included in a block. +## Port Ethereum DApps -### Define Transaction Properties +| Title | Difficulty | Tools | Description | +|-------------------------------------------------------------------------------------|:---------------:|---------|----------------------------------------------------------------------------------------------------------------------------------| +| [Deploying Uniswap V2 on Polkadot](/smart-contracts/cookbook/eth-dapps/uniswap-v2/) | 🟡 Intermediate | Hardhat | Learn how to deploy and test Uniswap V2 on Polkadot Hub using Hardhat, bringing AMM-based token swaps to the Polkadot ecosystem. | -The Polkadot SDK runtime defines key transaction properties, such as: -- **Transaction validity**: Ensures the transaction meets all runtime requirements. -- **Signed or unsigned**: Identifies whether a transaction needs to be signed by an account. -- **State changes**: Determines how the transaction modifies the state of the chain. +--- -Pallets, which compose the runtime's logic, define the specific transactions that your chain supports. When a user submits a transaction, such as a token transfer, it becomes a signed transaction, verified by the user's account signature. If the account has enough funds to cover fees, the transaction is executed, and the chain's state is updated accordingly. +Page Title: Smart Contracts Overview -### Process on a Block Authoring Node +- Source (raw): https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/smart-contracts-overview.md +- Canonical (HTML): https://docs.polkadot.com/smart-contracts/overview/ +- Summary: Learn about smart contract development on Polkadot Hub with native PolkaVM support, dual-VM execution, and seamless cross-chain capabilities. -In Polkadot SDK-based networks, some nodes are authorized to author blocks. These nodes validate and process transactions. When a transaction is sent to a node that can produce blocks, it undergoes a lifecycle that involves several stages, including validation and execution. Non-authoring nodes gossip the transaction across the network until an authoring node receives it. The following diagram illustrates the lifecycle of a transaction that's submitted to a network and processed by an authoring node. +# Smart Contracts on Polkadot Hub -![Transaction lifecycle diagram](/images/reference/parachains/blocks-transactions-fees/transactions/transactions-01.webp){ style="background:white" } +## Introduction -### Validate and Queue +Polkadot Hub provides a production-ready smart contract platform that combines Ethereum compatibility with the performance and cross-chain capabilities of the Polkadot ecosystem. Developers can deploy smart contracts directly on Polkadot Hub while using familiar Ethereum tooling, workflows, and programming languages. -Once a transaction reaches an authoring node, it undergoes an initial validation process to ensure it meets specific conditions defined in the runtime. This validation includes checks for: +Built with a dual-VM approach, Polkadot Hub offers two execution backends: REVM for unmodified EVM compatibility and native PolkaVM for optimized computationally expensive workloads. This dual-VM architecture enables developers to migrate existing Ethereum contracts instantly or optimize for speed and efficiency with native execution. -- **Correct nonce**: Ensures the transaction is sequentially valid for the account. -- **Sufficient funds**: Confirms the account can cover any associated transaction fees. -- **Signature validity**: Verifies that the sender's signature matches the transaction data. +## Why Build on Polkadot Hub -After these checks, valid transactions are placed in the transaction pool, where they are queued for inclusion in a block. The transaction pool regularly re-validates queued transactions to ensure they remain valid before being processed. To reach consensus, two-thirds of the nodes must agree on the order of the transactions executed and the resulting state change. Transactions are validated and queued on the local node in a transaction pool to prepare for consensus. +### Ethereum Compatibility -#### Transaction Pool +Deploy existing Ethereum contracts with zero modifications while maintaining full compatibility with your existing development stack: -The transaction pool is responsible for managing valid transactions. It ensures that only transactions that pass initial validity checks are queued. Transactions that fail validation, expire, or become invalid for other reasons are removed from the pool. +- **Complete JSON-RPC API support**: Use MetaMask, Hardhat, Remix, Foundry, and all standard Ethereum tooling. +- **Standard libraries**: Integrate Ethers.js, Web3.js, Viem, Wagmi, and Web3.py without changes. +- **Solidity development**: Write contracts in Solidity or migrate existing code directly. +- **Familiar workflows**: Maintain your existing deployment, testing, and monitoring processes. -The transaction pool organizes transactions into two queues: +### Performance Options -- **Ready queue**: Transactions that are valid and ready to be included in a block. -- **Future queue**: Transactions that are not yet valid but could be in the future, such as transactions with a nonce too high for the current state. +Choose between two execution backends: -Details on how the transaction pool validates transactions, including fee and signature handling, can be found in the [`validate_transaction`](https://paritytech.github.io/polkadot-sdk/master/sp_transaction_pool/runtime_api/trait.TaggedTransactionQueue.html#method.validate_transaction){target=\_blank} method. +- **REVM**: Run unmodified Ethereum contracts with full EVM/Ethereum compatibility. +- **PolkaVM**: Compile to optimized RISC-V bytecode for enhanced performance and lower fees while keeping Ethereum-compatibility. -#### Invalid Transactions +Both backends share the same RPC interface and tooling support, allowing seamless transitions. In addition, smart contracts can interact with Polkadot native services via [precompile contracts](/smart-contracts/precompiles/){target=\_blank}. -If a transaction is invalid, for example, due to an invalid signature or insufficient funds, it is rejected and won't be added to the block. Invalid transactions might be rejected for reasons such as: +### Cross-VM & Cross-Chain Capabilities -- The transaction has already been included in a block. -- The transaction's signature does not match the sender. -- The transaction is too large to fit in the current block. +Smart contracts written for one VM (for example, EVM) can interact directly with other smart contracts written for the RISC-V PolkaVM, and back. This allows to use full EVM compatible contracts but extend to heavy/complex execution workloads to the PolkaVM RISC-V backend. -### Transaction Ordering and Priority +Furthermore, all smart contracts in Polkadot Hub can interact with any service in the Polkadot ecosystem through [XCM](/smart-contracts/precompiles/xcm/){target=\_blank}, enabling token transfers, remote execution, and cross-chain composability without bridges or intermediaries. -When a node is selected as the next block author, it prioritizes transactions based on weight, length, and tip amount. The goal is to fill the block with high-priority transactions without exceeding its maximum size or computational limits. Transactions are ordered as follows: +## Other Smart Contract Environments -- **Inherents first**: Inherent transactions, such as block timestamp updates, are always placed first. -- **Nonce-based ordering**: Transactions from the same account are ordered by their nonce. -- **Fee-based ordering**: Among transactions with the same nonce or priority level, those with higher fees are prioritized. +Beyond Polkadot Hub's native PolkaVM support, the ecosystem offers two main alternatives for smart contract development: -### Transaction Execution +- **EVM-compatible parachains**: Provide access to Ethereum's extensive developer ecosystem, smart contract portability, and established tooling like Hardhat, Remix, Foundry, and OpenZeppelin. The main options include Moonbeam (the first full Ethereum-compatible parachain serving as an interoperability hub), Astar (featuring dual VM support for both EVM and WebAssembly contracts), and Acala (DeFi-focused with enhanced Acala EVM+ offering advanced DeFi primitives). -Once a block author selects transactions from the pool, the transactions are executed in priority order. As each transaction is processed, the state changes are written directly to the chain's storage. It's important to note that these changes are not cached, meaning a failed transaction won't revert earlier state changes, which could leave the block in an inconsistent state. +- **Rust (ink!)**: ink! is a Rust-based framework that can compile to PolkaVM. It uses [`#[ink(...)]`](https://use.ink/docs/v6/macros-attributes/){target=\_blank} attribute macros to create Polkadot SDK-compatible PolkaVM bytecode, offering strong memory safety from Rust, an advanced type system, high-performance PolkaVM execution, and platform independence with sandboxed security. -Events are also written to storage. Runtime logic should not emit an event before performing the associated actions. If the associated transaction fails after the event was emitted, the event will not revert. +## Next Steps -## Transaction Mortality +
-Transactions in the network can be configured as either mortal (with expiration) or immortal (without expiration). Every transaction payload contains a block checkpoint (reference block number and hash) and an era/validity period that determines how many blocks after the checkpoint the transaction remains valid. +- Guide __Get Started__ -When a transaction is submitted, the network validates it against these parameters. If the transaction is not included in a block within the specified validity window, it is automatically removed from the transaction queue. + --- -- **Mortal transactions**: Have a finite lifespan and will expire after a specified number of blocks. For example, a transaction with a block checkpoint of 1000 and a validity period of 64 blocks will be valid from blocks 1000 to 1064. + Quick-start guides for connecting, deploying, and building your first smart contract. -- **Immortal transactions**: Never expire and remain valid indefinitely. To create an immortal transaction, set the block checkpoint to 0 (genesis block), use the genesis hash as a reference, and set the validity period to 0. + [:octicons-arrow-right-24: Get Started](/smart-contracts/get-started/) -However, immortal transactions pose significant security risks through replay attacks. If an account is reaped (balance drops to zero, account removed) and later re-funded, malicious actors can replay old immortal transactions. +- Guide __Cookbook__ -The blockchain maintains only a limited number of prior block hashes for reference validation, called `BlockHashCount`. If your validity period exceeds `BlockHashCount`, the effective validity period becomes the minimum of your specified period and the block hash count. + --- -## Unique Identifiers for Extrinsics + Step-by-step tutorials for deploying contracts, tokens, NFTs, and full dApps. -Transaction hashes are **not unique identifiers** in Polkadot SDK-based chains. + [:octicons-arrow-right-24: View Tutorials](/smart-contracts/cookbook/) -Key differences from traditional blockchains: +- Guide __Ethereum Developers__ -- Transaction hashes serve only as fingerprints of transaction information. -- Multiple valid transactions can share the same hash. -- Hash uniqueness assumptions lead to serious issues. + --- -For example, when an account is reaped (removed due to insufficient balance) and later recreated, it resets to nonce 0, allowing identical transactions to be valid at different points: + Understand key differences in accounts, fees, gas model, and deployment on Polkadot Hub. -| Block | Extrinsic Index | Hash | Origin | Nonce | Call | Result | -|-------|----------------|------|-----------|-------|---------------------|-------------------------------| -| 100 | 0 | 0x01 | Account A | 0 | Transfer 5 DOT to B | Account A reaped | -| 150 | 5 | 0x02 | Account B | 4 | Transfer 7 DOT to A | Account A created (nonce = 0) | -| 200 | 2 | 0x01 | Account A | 0 | Transfer 5 DOT to B | Successful transaction | + [:octicons-arrow-right-24: Learn More](/smart-contracts/for-eth-devs/accounts/) -Notice that blocks 100 and 200 contain transactions with identical hashes (0x01) but are completely different, valid operations occurring at different times. +- Guide __Precompiles__ -Additional complexity comes from Polkadot SDK's origin abstraction. Origins can represent collectives, governance bodies, or other non-account entities that don't maintain nonces like regular accounts and might dispatch identical calls multiple times with the same hash values. Each execution occurs in different chain states with different results. + --- -The correct way to uniquely identify an extrinsic on a Polkadot SDK-based chain is to use the block ID (height or hash) and the extrinsic index. Since the Polkadot SDK defines blocks as headers plus ordered arrays of extrinsics, the index position within a canonical block provides guaranteed uniqueness. + Discover advanced functionalities including XCM for cross-chain interactions. -## Additional Resources + [:octicons-arrow-right-24: Explore Precompiles](/smart-contracts/precompiles/) -For a video overview of the lifecycle of transactions and the types of transactions that exist, see the [Transaction lifecycle](https://www.youtube.com/watch?v=3pfM0GOp02c){target=\_blank} seminar from Parity Tech. +
--- @@ -6452,351 +3593,6 @@ The system maintains precise conversion mechanisms between: This ensures accurate fee calculation while maintaining compatibility with existing Ethereum tools and workflows. ---- - -Page Title: Transactions Weights and Fees - -- Source (raw): https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/reference-parachains-blocks-transactions-fees-fees.md -- Canonical (HTML): https://docs.polkadot.com/reference/parachains/blocks-transactions-fees/fees/ -- Summary: Overview of transaction weights and fees in Polkadot SDK chains, detailing how fees are calculated using a defined formula and runtime specifics. - -# Transactions Weights and Fees - -## Introductions - -When transactions are executed, or data is stored on-chain, the activity changes the chain's state and consumes blockchain resources. Because the resources available to a blockchain are limited, managing how operations on-chain consume them is important. In addition to being limited in practical terms, such as storage capacity, blockchain resources represent a potential attack vector for malicious users. For example, a malicious user might attempt to overload the network with messages to stop the network from producing new blocks. To protect blockchain resources from being drained or overloaded, you need to manage how they are made available and how they are consumed. The resources to be aware of include: - -- Memory usage -- Storage input and output -- Computation -- Transaction and block size -- State database size - -The Polkadot SDK provides block authors with several ways to manage access to resources and to prevent individual components of the chain from consuming too much of any single resource. Two of the most important mechanisms available to block authors are weights and transaction fees. - -[Weights](/reference/glossary/#weight){target=\_blank} manage the time it takes to validate a block and characterize the time it takes to execute the calls in the block's body. By controlling the execution time a block can consume, weights set limits on storage input, output, and computation. - -Some of the weight allowed for a block is consumed as part of the block's initialization and finalization. The weight might also be used to execute mandatory inherent extrinsic calls. To help ensure blocks don’t consume too much execution time and prevent malicious users from overloading the system with unnecessary calls, weights are combined with transaction fees. - -[Transaction fees](/reference/parachains/blocks-transactions-fees/transactions/#transaction-fees){target=\_blank} provide an economic incentive to limit execution time, computation, and the number of calls required to perform operations. Transaction fees are also used to make the blockchain economically sustainable because they are typically applied to transactions initiated by users and deducted before a transaction request is executed. - -## How Fees are Calculated - -The final fee for a transaction is calculated using the following parameters: - -- **`base fee`**: This is the minimum amount a user pays for a transaction. It is declared a base weight in the runtime and converted to a fee using the [`WeightToFee`](https://docs.rs/pallet-transaction-payment/latest/pallet_transaction_payment/pallet/trait.Config.html#associatedtype.WeightToFee){target=\_blank} conversion. -- **`weight fee`**: A fee proportional to the execution time (input and output and computation) that a transaction consumes. -- **`length fee`**: A fee proportional to the encoded length of the transaction. -- **`tip`**: An optional tip to increase the transaction’s priority, giving it a higher chance to be included in the transaction queue. - -The base fee and proportional weight and length fees constitute the inclusion fee. The inclusion fee is the minimum fee that must be available for a transaction to be included in a block. - -```text -inclusion fee = base fee + weight fee + length fee -``` - -Transaction fees are withdrawn before the transaction is executed. After the transaction is executed, the weight can be adjusted to reflect the resources used. If a transaction uses fewer resources than expected, the transaction fee is corrected, and the adjusted transaction fee is deposited. - -## Using the Transaction Payment Pallet - -The [Transaction Payment pallet](https://github.com/paritytech/polkadot-sdk/tree/polkadot-stable2506-2/substrate/frame/transaction-payment){target=\_blank} provides the basic logic for calculating the inclusion fee. You can also use the Transaction Payment pallet to: - -- Convert a weight value into a deductible fee based on a currency type using [`Config::WeightToFee`](https://docs.rs/pallet-transaction-payment/latest/pallet_transaction_payment/pallet/trait.Config.html#associatedtype.WeightToFee){target=\_blank}. -- Update the fee for the next block by defining a multiplier based on the chain’s final state at the end of the previous block using [`Config::FeeMultiplierUpdate`](https://docs.rs/pallet-transaction-payment/latest/pallet_transaction_payment/pallet/trait.Config.html#associatedtype.FeeMultiplierUpdate){target=\_blank}. -- Manage the withdrawal, refund, and deposit of transaction fees using [`Config::OnChargeTransaction`](https://docs.rs/pallet-transaction-payment/latest/pallet_transaction_payment/pallet/trait.Config.html#associatedtype.OnChargeTransaction){target=\_blank}. - -You can learn more about these configuration traits in the [Transaction Payment documentation](https://paritytech.github.io/polkadot-sdk/master/pallet_transaction_payment/index.html){target=\_blank}. - -### Understanding the Inclusion Fee - -The formula for calculating the inclusion fee is as follows: - -```text -inclusion_fee = base_fee + length_fee + [targeted_fee_adjustment * weight_fee] -``` - -And then, for calculating the final fee: - -```text -final_fee = inclusion_fee + tip -``` - -In the first formula, the `targeted_fee_adjustment` is a multiplier that can tune the final fee based on the network’s congestion. - -- The `base_fee` derived from the base weight covers inclusion overhead like signature verification. -- The `length_fee` is a per-byte fee that is multiplied by the length of the encoded extrinsic. -- The `weight_fee` fee is calculated using two parameters: - - The `ExtrinsicBaseWeight` that is declared in the runtime and applies to all extrinsics. - - The `#[pallet::weight]` annotation that accounts for an extrinsic's complexity. - -To convert the weight to `Currency`, the runtime must define a `WeightToFee` struct that implements a conversion function, [`Convert`](https://docs.rs/pallet-transaction-payment/latest/pallet_transaction_payment/pallet/struct.Pallet.html#method.weight_to_fee){target=\_blank}. - -Note that the extrinsic sender is charged the inclusion fee before the extrinsic is invoked. The fee is deducted from the sender's balance even if the transaction fails upon execution. - -### Accounts with an Insufficient Balance - -If an account does not have a sufficient balance to pay the inclusion fee and remain alive—that is, enough to pay the inclusion fee and maintain the minimum existential deposit—then you should ensure the transaction is canceled so that no fee is deducted and the transaction does not begin execution. - -The Polkadot SDK doesn't enforce this rollback behavior. However, this scenario would be rare because the transaction queue and block-making logic perform checks to prevent it before adding an extrinsic to a block. - -### Fee Multipliers - -The inclusion fee formula always results in the same fee for the same input. However, weight can be dynamic and—based on how [`WeightToFee`](https://docs.rs/pallet-transaction-payment/latest/pallet_transaction_payment/pallet/trait.Config.html#associatedtype.WeightToFee){target=\_blank} is defined—the final fee can include some degree of variability. -The Transaction Payment pallet provides the [`FeeMultiplierUpdate`](https://docs.rs/pallet-transaction-payment/latest/pallet_transaction_payment/pallet/trait.Config.html#associatedtype.FeeMultiplierUpdate){target=\_blank} configurable parameter to account for this variability. - -The Polkadot network inspires the default update function and implements a targeted adjustment in which a target saturation level of block weight is defined. If the previous block is more saturated, the fees increase slightly. Similarly, if the last block has fewer transactions than the target, fees are decreased by a small amount. For more information about fee multiplier adjustments, see the [Web3 Research Page](https://research.web3.foundation/Polkadot/overview/token-economics#relay-chain-transaction-fees-and-per-block-transaction-limits){target=\_blank}. - -## Transactions with Special Requirements - -Inclusion fees must be computable before execution and can only represent fixed logic. Some transactions warrant limiting resources with other strategies. For example: - -- Bonds are a type of fee that might be returned or slashed after some on-chain event. For example, you might want to require users to place a bond to participate in a vote. The bond might then be returned at the end of the referendum or slashed if the voter attempted malicious behavior. -- Deposits are fees that might be returned later. For example, you might require users to pay a deposit to execute an operation that uses storage. The user’s deposit could be returned if a subsequent operation frees up storage. -- Burn operations are used to pay for a transaction based on its internal logic. For example, a transaction might burn funds from the sender if the transaction creates new storage items to pay for the increased state size. -- Limits enable you to enforce constant or configurable limits on specific operations. For example, the default [Staking pallet](https://github.com/paritytech/polkadot-sdk/tree/polkadot-stable2506-2/substrate/frame/staking){target=\_blank} only allows nominators to nominate 16 validators to limit the complexity of the validator election process. - -It is important to note that if you query the chain for a transaction fee, it only returns the inclusion fee. - -## Default Weight Annotations - -All dispatchable functions in the Polkadot SDK must specify a weight. The way of doing that is using the annotation-based system that lets you combine fixed values for database read/write weight and/or fixed values based on benchmarks. The most basic example would look like this: - -```rust -#[pallet::weight(100_000)] -fn my_dispatchable() { - // ... -} -``` - -Note that the [`ExtrinsicBaseWeight`](https://crates.parity.io/frame_support/weights/constants/struct.ExtrinsicBaseWeight.html){target=\_blank} is automatically added to the declared weight to account for the costs of simply including an empty extrinsic into a block. - -### Weights and Database Read/Write Operations - -To make weight annotations independent of the deployed database backend, they are defined as a constant and then used in the annotations when expressing database accesses performed by the dispatchable: - -```rust -#[pallet::weight(T::DbWeight::get().reads_writes(1, 2) + 20_000)] -fn my_dispatchable() { - // ... -} -``` - -This dispatchable allows one database to read and two to write, in addition to other things that add the additional 20,000. Database access is generally every time a value declared inside the [`#[pallet::storage]`](https://paritytech.github.io/polkadot-sdk/master/frame_support/pallet_macros/attr.storage.html){target=\_blank} block is accessed. However, unique accesses are counted because after a value is accessed, it is cached, and reaccessing it does not result in a database operation. That is: - -- Multiple reads of the exact value count as one read. -- Multiple writes of the exact value count as one write. -- Multiple reads of the same value, followed by a write to that value, count as one read and one write. -- A write followed by a read-only counts as one write. - -### Dispatch Classes - -Dispatches are broken into three classes: - -- Normal -- Operational -- Mandatory - -If a dispatch is not defined as `Operational` or `Mandatory` in the weight annotation, the dispatch is identified as `Normal` by default. You can specify that the dispatchable uses another class like this: - -```rust -#[pallet::dispatch((DispatchClass::Operational))] -fn my_dispatchable() { - // ... -} -``` - -This tuple notation also allows you to specify a final argument determining whether the user is charged based on the annotated weight. If you don't specify otherwise, `Pays::Yes` is assumed: - -```rust -#[pallet::dispatch(DispatchClass::Normal, Pays::No)] -fn my_dispatchable() { - // ... -} -``` - -#### Normal Dispatches - -Dispatches in this class represent normal user-triggered transactions. These types of dispatches only consume a portion of a block's total weight limit. For information about the maximum portion of a block that can be consumed for normal dispatches, see [`AvailableBlockRatio`](https://paritytech.github.io/polkadot-sdk/master/frame_system/limits/struct.BlockLength.html){target=\_blank}. Normal dispatches are sent to the transaction pool. - -#### Operational Dispatches - -Unlike normal dispatches, which represent the usage of network capabilities, operational dispatches are those that provide network capabilities. Operational dispatches can consume the entire weight limit of a block. They are not bound by the [`AvailableBlockRatio`](https://paritytech.github.io/polkadot-sdk/master/frame_system/limits/struct.BlockLength.html){target=\_blank}. Dispatches in this class are given maximum priority and are exempt from paying the [`length_fee`](https://docs.rs/pallet-transaction-payment/latest/pallet_transaction_payment/){target=\_blank}. - -#### Mandatory Dispatches - -Mandatory dispatches are included in a block even if they cause the block to surpass its weight limit. You can only use the mandatory dispatch class for inherent transactions that the block author submits. This dispatch class is intended to represent functions in the block validation process. Because these dispatches are always included in a block regardless of the function weight, the validation process must prevent malicious nodes from abusing the function to craft valid but impossibly heavy blocks. You can typically accomplish this by ensuring that: - -- The operation performed is always light. -- The operation can only be included in a block once. - -To make it more difficult for malicious nodes to abuse mandatory dispatches, they cannot be included in blocks that return errors. This dispatch class serves the assumption that it is better to allow an overweight block to be created than not to allow any block to be created at all. - -### Dynamic Weights - -In addition to purely fixed weights and constants, the weight calculation can consider the input arguments of a dispatchable. The weight should be trivially computable from the input arguments with some basic arithmetic: - -```rust -use frame_support:: { - dispatch:: { - DispatchClass::Normal, - Pays::Yes, - }, - weights::Weight, -}; - -#[pallet::weight(FunctionOf( - |args: (&Vec,)| args.0.len().saturating_mul(10_000), - ) -] -fn handle_users(origin, calls: Vec) { - // Do something per user -} -``` - -## Post Dispatch Weight Correction - -Depending on the execution logic, a dispatchable function might consume less weight than was prescribed pre-dispatch. To correct weight, the function declares a different return type and returns its actual weight: - -```rust -#[pallet::weight(10_000 + 500_000_000)] -fn expensive_or_cheap(input: u64) -> DispatchResultWithPostInfo { - let was_heavy = do_calculation(input); - - if (was_heavy) { - // None means "no correction" from the weight annotation. - Ok(None.into()) - } else { - // Return the actual weight consumed. - Ok(Some(10_000).into()) - } -} -``` - -## Custom Fees - -You can also define custom fee systems through custom weight functions or inclusion fee functions. - -### Custom Weights - -Instead of using the default weight annotations, you can create a custom weight calculation type using the weights module. The custom weight calculation type must implement the following traits: - -- [`WeighData`](https://crates.parity.io/frame_support/weights/trait.WeighData.html){target=\_blank} to determine the weight of the dispatch. -- [`ClassifyDispatch`](https://crates.parity.io/frame_support/weights/trait.ClassifyDispatch.html){target=\_blank} to determine the class of the dispatch. -- [`PaysFee`](https://crates.parity.io/frame_support/weights/trait.PaysFee.html){target=\_blank} to determine whether the sender of the dispatch pays fees. - -The Polkadot SDK then bundles the output information of the three traits into the [`DispatchInfo`](https://paritytech.github.io/polkadot-sdk/master/frame_support/dispatch/struct.DispatchInfo.html){target=\_blank} struct and provides it by implementing the [`GetDispatchInfo`](https://docs.rs/frame-support/latest/frame_support/dispatch/trait.GetDispatchInfo.html){target=\_blank} for all `Call` variants and opaque extrinsic types. This is used internally by the System and Executive modules. - -`ClassifyDispatch`, `WeighData`, and `PaysFee` are generic over T, which gets resolved into the tuple of all dispatch arguments except for the origin. The following example illustrates a struct that calculates the weight as `m * len(args)`, where `m` is a given multiplier and args is the concatenated tuple of all dispatch arguments. In this example, the dispatch class is `Operational` if the transaction has more than 100 bytes of length in arguments and will pay fees if the encoded length exceeds 10 bytes. - -```rust -struct LenWeight(u32); -impl WeighData for LenWeight { - fn weigh_data(&self, target: T) -> Weight { - let multiplier = self.0; - let encoded_len = target.encode().len() as u32; - multiplier * encoded_len - } -} - -impl ClassifyDispatch for LenWeight { - fn classify_dispatch(&self, target: T) -> DispatchClass { - let encoded_len = target.encode().len() as u32; - if encoded_len > 100 { - DispatchClass::Operational - } else { - DispatchClass::Normal - } - } -} - -impl PaysFee { - fn pays_fee(&self, target: T) -> Pays { - let encoded_len = target.encode().len() as u32; - if encoded_len > 10 { - Pays::Yes - } else { - Pays::No - } - } -} -``` - -A weight calculator function can also be coerced to the final type of the argument instead of defining it as a vague type that can be encoded. The code would roughly look like this: - -```rust -struct CustomWeight; -impl WeighData<(&u32, &u64)> for CustomWeight { - fn weigh_data(&self, target: (&u32, &u64)) -> Weight { - ... - } -} - -// given a dispatch: -#[pallet::call] -impl, I: 'static> Pallet { - #[pallet::weight(CustomWeight)] - fn foo(a: u32, b: u64) { ... } -} -``` - -In this example, the `CustomWeight` can only be used in conjunction with a dispatch with a particular signature `(u32, u64)`, as opposed to `LenWeight`, which can be used with anything because there aren't any assumptions about ``. - -#### Custom Inclusion Fee - -The following example illustrates how to customize your inclusion fee. You must configure the appropriate associated types in the respective module. - -```rust -// Assume this is the balance type -type Balance = u64; - -// Assume we want all the weights to have a `100 + 2 * w` conversion to fees -struct CustomWeightToFee; -impl WeightToFee for CustomWeightToFee { - fn convert(w: Weight) -> Balance { - let a = Balance::from(100); - let b = Balance::from(2); - let w = Balance::from(w); - a + b * w - } -} - -parameter_types! { - pub const ExtrinsicBaseWeight: Weight = 10_000_000; -} - -impl frame_system::Config for Runtime { - type ExtrinsicBaseWeight = ExtrinsicBaseWeight; -} - -parameter_types! { - pub const TransactionByteFee: Balance = 10; -} - -impl transaction_payment::Config { - type TransactionByteFee = TransactionByteFee; - type WeightToFee = CustomWeightToFee; - type FeeMultiplierUpdate = TargetedFeeAdjustment; -} - -struct TargetedFeeAdjustment(sp_std::marker::PhantomData); -impl> WeightToFee for TargetedFeeAdjustment { - fn convert(multiplier: Fixed128) -> Fixed128 { - // Don't change anything. Put any fee update info here. - multiplier - } -} -``` - -## Additional Resources - -You now know the weight system, how it affects transaction fee computation, and how to specify weights for your dispatchable calls. The next step is determining the correct weight for your dispatchable operations. You can use Substrate benchmarking functions and frame-benchmarking calls to test your functions with different parameters and empirically determine the proper weight in their worst-case scenarios. - -- [Benchmark](/parachains/customize-runtime/pallet-development/benchmark-pallet/) -- [`SignedExtension`](https://paritytech.github.io/polkadot-sdk/master/sp_runtime/traits/trait.SignedExtension.html){target=\_blank} -- [Custom weights for the Example pallet](https://github.com/paritytech/polkadot-sdk/blob/polkadot-stable2506-2/substrate/frame/examples/basic/src/weights.rs){target=\_blank} -- [Web3 Foundation Research](https://research.web3.foundation/Polkadot/overview/token-economics#relay-chain-transaction-fees-and-per-block-transaction-limits){target=\_blank} - - --- Page Title: Wallets @@ -6883,91 +3679,3 @@ Wallet types fall into two categories based on their connection to the internet: - - ---- - -Page Title: XCM Tools - -- Source (raw): https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/reference-tools-xcm-tools.md -- Canonical (HTML): https://docs.polkadot.com/reference/tools/xcm-tools/ -- Summary: Explore essential XCM tools across Polkadot, crafted to enhance cross-chain functionality and integration within the ecosystem. - -# XCM Tools - -## Introduction - -As described in the [Interoperability](/develop/interoperability){target=\_blank} section, XCM (Cross-Consensus Messaging) is a protocol used in the Polkadot and Kusama ecosystems to enable communication and interaction between chains. It facilitates cross-chain communication, allowing assets, data, and messages to flow seamlessly across the ecosystem. - -As XCM is central to enabling communication between blockchains, developers need robust tools to help interact with, build, and test XCM messages. Several XCM tools simplify working with the protocol by providing libraries, frameworks, and utilities that enhance the development process, ensuring that applications built within the Polkadot ecosystem can efficiently use cross-chain functionalities. - -## Popular XCM Tools - -### Moonsong Labs XCM Tools - -[Moonsong Labs XCM Tools](https://github.com/Moonsong-Labs/xcm-tools){target=\_blank} provides a collection of scripts for managing and testing XCM operations between Polkadot SDK-based runtimes. These tools allow performing tasks like asset registration, channel setup, and XCM initialization. Key features include: - -- **Asset registration**: Registers assets, setting units per second (up-front fees), and configuring error (revert) codes. -- **XCM initializer**: Initializes XCM, sets default XCM versions, and configures revert codes for XCM-related precompiles. -- **HRMP manipulator**: Manages HRMP channel actions, including opening, accepting, or closing channels. -- **XCM-Transactor-Info-Setter**: Configures transactor information, including extra weight and fee settings. -- **Decode XCM**: Decodes XCM messages on the relay chain or parachains to help interpret cross-chain communication. - -To get started, clone the repository and install the required dependencies: - -```bash -git clone https://github.com/Moonsong-Labs/xcm-tools && -cd xcm-tools && -yarn install -``` - -For a full overview of each script, visit the [scripts](https://github.com/Moonsong-Labs/xcm-tools/tree/main/scripts){target=\_blank} directory or refer to the [official documentation](https://github.com/Moonsong-Labs/xcm-tools/blob/main/README.md){target=\_blank} on GitHub. - -### ParaSpell - -[ParaSpell](/reference/tools/paraspell/){target=\_blank} is a collection of open-source XCM tools that streamline cross-chain asset transfers and interactions across the Polkadot and Kusama ecosystems. It provides developers with an intuitive interface to build, test, and deploy interoperable dApps, featuring message composition, decoding, and practical utilities for parachain interactions that simplify debugging and cross-chain communication optimization. - -### Astar XCM Tools - -The [Astar parachain](https://github.com/AstarNetwork/Astar/tree/master){target=\_blank} offers a crate with a set of utilities for interacting with the XCM protocol. The [xcm-tools](https://github.com/AstarNetwork/Astar/tree/master/bin/xcm-tools){target=\_blank} crate provides a straightforward method for users to locate a sovereign account or calculate an XC20 asset ID. Some commands included by the xcm-tools crate allow users to perform the following tasks: - -- **Sovereign accounts**: Obtain the sovereign account address for any parachain, either on the Relay Chain or for sibling parachains, using a simple command. -- **XC20 EVM addresses**: Generate XC20-compatible Ethereum addresses for assets by entering the asset ID, making it easy to integrate assets across Ethereum-compatible environments. -- **Remote accounts**: Retrieve remote account addresses needed for multi-location compatibility, using flexible options to specify account types and parachain IDs. - -To start using these tools, clone the [Astar repository](https://github.com/AstarNetwork/Astar){target=\_blank} and compile the xcm-tools package: - -```bash -git clone https://github.com/AstarNetwork/Astar && -cd Astar && -cargo build --release -p xcm-tools -``` - -After compiling, verify the setup with the following command: - -```bash -./target/release/xcm-tools --help -``` -For more details on using Astar xcm-tools, consult the [official documentation](https://docs.astar.network/docs/learn/interoperability/xcm/integration/tools/){target=\_blank}. - -### Chopsticks - -The Chopsticks library provides XCM functionality for testing XCM messages across networks, enabling you to fork multiple parachains along with a relay chain. For further details, see the [Chopsticks documentation](/tutorials/polkadot-sdk/testing/fork-live-chains/){target=\_blank} about XCM. - -### Moonbeam XCM SDK - -The [Moonbeam XCM SDK](https://github.com/moonbeam-foundation/xcm-sdk){target=\_blank} enables developers to easily transfer assets between chains, either between parachains or between a parachain and the relay chain, within the Polkadot/Kusama ecosystem. With the SDK, you don't need to worry about determining the [Multilocation](https://github.com/polkadot-fellows/xcm-format?tab=readme-ov-file#7-universal-consensus-location-identifiers){target=\_blank} of the origin or destination assets or which extrinsics are used on which networks. - -The SDK consists of two main packages: - -- **[XCM SDK](https://github.com/moonbeam-foundation/xcm-sdk/tree/main/packages/sdk){target=\_blank}**: Core SDK for executing XCM transfers between chains in the Polkadot/Kusama ecosystem. -- **[MRL SDK](https://github.com/moonbeam-foundation/xcm-sdk/tree/main/packages/mrl){target=\_blank}**: Extension of the XCM SDK for transferring liquidity into and across the Polkadot ecosystem from other ecosystems like Ethereum. - -Key features include: - -- **Simplified asset transfers**: Abstracts away complex multilocation determinations and extrinsic selection. -- **Cross-ecosystem support**: Enables transfers between Polkadot/Kusama chains and external ecosystems. -- **Developer-friendly API**: Provides intuitive interfaces for cross-chain functionality. -- **Comprehensive documentation**: Includes usage guides and API references for both packages. - -For detailed usage examples and API documentation, visit the [official Moonbeam XCM SDK documentation](https://moonbeam-foundation.github.io/xcm-sdk/latest/){target=\_blank}. diff --git a/.ai/categories/infrastructure.md b/.ai/categories/infrastructure.md index 745d8f24e..fb0b5c6ec 100644 --- a/.ai/categories/infrastructure.md +++ b/.ai/categories/infrastructure.md @@ -2121,374 +2121,6 @@ XCM revolutionizes cross-chain communication by enabling use cases such as: These functionalities empower developers to build innovative, multi-chain applications, leveraging the strengths of various blockchain networks. To stay updated on XCM’s evolving format or contribute, visit the [XCM repository](https://github.com/paritytech/xcm-docs/blob/main/examples/src/0_first_look/mod.rs){target=\_blank}. ---- - -Page Title: Glossary - -- Source (raw): https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/reference-glossary.md -- Canonical (HTML): https://docs.polkadot.com/reference/glossary/ -- Summary: Glossary of terms used within the Polkadot ecosystem, Polkadot SDK, its subsequent libraries, and other relevant Web3 terminology. - -# Glossary - -Key definitions, concepts, and terminology specific to the Polkadot ecosystem are included here. - -Additional glossaries from around the ecosystem you might find helpful: - -- [Polkadot Wiki Glossary](https://wiki.polkadot.com/general/glossary){target=\_blank} -- [Polkadot SDK Glossary](https://paritytech.github.io/polkadot-sdk/master/polkadot_sdk_docs/reference_docs/glossary/index.html){target=\_blank} - -## Authority - -The role in a blockchain that can participate in consensus mechanisms. - -- **[GRANDPA](#grandpa)**: The authorities vote on chains they consider final. -- **[Blind Assignment of Blockchain Extension](#blind-assignment-of-blockchain-extension-babe) (BABE)**: The authorities are also [block authors](#block-author). - -Authority sets can be used as a basis for consensus mechanisms such as the [Nominated Proof of Stake (NPoS)](#nominated-proof-of-stake-npos) protocol. - -## Authority Round (Aura) - -A deterministic [consensus](#consensus) protocol where block production is limited to a rotating list of [authorities](#authority) that take turns creating blocks. In authority round (Aura) consensus, most online authorities are assumed to be honest. It is often used in combination with [GRANDPA](#grandpa) as a [hybrid consensus](#hybrid-consensus) protocol. - -Learn more by reading the official [Aura consensus algorithm](https://openethereum.github.io/Aura){target=\_blank} wiki article. - -## Blind Assignment of Blockchain Extension (BABE) - -A [block authoring](#block-author) protocol similar to [Aura](#authority-round-aura), except [authorities](#authority) win [slots](#slot) based on a Verifiable Random Function (VRF) instead of the round-robin selection method. The winning authority can select a chain and submit a new block. - -Learn more by reading the official Web3 Foundation [BABE research document](https://research.web3.foundation/Polkadot/protocols/block-production/Babe){target=\_blank}. - -## Block Author - -The node responsible for the creation of a block, also called _block producers_. In a Proof of Work (PoW) blockchain, these nodes are called _miners_. - -## Byzantine Fault Tolerance (BFT) - -The ability of a distributed computer network to remain operational if a certain proportion of its nodes or [authorities](#authority) are defective or behaving maliciously. A distributed network is typically considered Byzantine fault tolerant if it can remain functional, with up to one-third of nodes assumed to be defective, offline, actively malicious, and part of a coordinated attack. - -### Byzantine Failure - -The loss of a network service due to node failures that exceed the proportion of nodes required to reach consensus. - -### Practical Byzantine Fault Tolerance (pBFT) - -An early approach to Byzantine fault tolerance (BFT), practical Byzantine fault tolerance (pBFT) systems tolerate Byzantine behavior from up to one-third of participants. - -The communication overhead for such systems is `O(n²)`, where `n` is the number of nodes (participants) in the system. - -### Preimage - -A preimage is the data that is input into a hash function to calculate a hash. Since a hash function is a [one-way function](https://en.wikipedia.org/wiki/One-way_function){target=\_blank}, the output, the hash, cannot be used to reveal the input, the preimage. - -## Call - -In the context of pallets containing functions to be dispatched to the runtime, `Call` is an enumeration data type that describes the functions that can be dispatched with one variant per pallet. A `Call` represents a [dispatch](#dispatchable) data structure object. - -## Chain Specification - -A chain specification file defines the properties required to run a node in an active or new Polkadot SDK-built network. It often contains the initial genesis runtime code, network properties (such as the network's name), the initial state for some pallets, and the boot node list. The chain specification file makes it easy to use a single Polkadot SDK codebase as the foundation for multiple independently configured chains. - -## Collator - -An [author](#block-author) of a [parachain](#parachain) network. -They aren't [authorities](#authority) in themselves, as they require a [relay chain](#relay-chain) to coordinate [consensus](#consensus). - -More details are found on the [Polkadot Collator Wiki](https://wiki.polkadot.com/learn/learn-collator/){target=\_blank}. - -## Collective - -Most often used to refer to an instance of the Collective pallet on Polkadot SDK-based networks such as [Kusama](#kusama) or [Polkadot](#polkadot) if the Collective pallet is part of the FRAME-based runtime for the network. - -## Consensus - -Consensus is the process blockchain nodes use to agree on a chain's canonical fork. It is composed of [authorship](#block-author), finality, and [fork-choice rule](#fork-choice-rulestrategy). In the Polkadot ecosystem, these three components are usually separate and the term consensus often refers specifically to authorship. - -See also [hybrid consensus](#hybrid-consensus). - -## Consensus Algorithm - -Ensures a set of [actors](#authority)—who don't necessarily trust each other—can reach an agreement about the state as the result of some computation. Most consensus algorithms assume that up to one-third of the actors or nodes can be [Byzantine fault tolerant](#byzantine-fault-tolerance-bft). - -Consensus algorithms are generally concerned with ensuring two properties: - -- **Safety**: Indicating that all honest nodes eventually agreed on the state of the chain. -- **Liveness**: Indicating the ability of the chain to keep progressing. - -## Consensus Engine - -The node subsystem responsible for consensus tasks. - -For detailed information about the consensus strategies of the [Polkadot](#polkadot) network, see the [Polkadot Consensus](/reference/polkadot-hub/consensus-and-security/pos-consensus/){target=\_blank} blog series. - -See also [hybrid consensus](#hybrid-consensus). - -## Coretime - -The time allocated for utilizing a core, measured in relay chain blocks. There are two types of coretime: *on-demand* and *bulk*. - -On-demand coretime refers to coretime acquired through bidding in near real-time for the validation of a single parachain block on one of the cores reserved specifically for on-demand orders. They are available as an on-demand coretime pool. Set of cores that are available on-demand. Cores reserved through bulk coretime could also be made available in the on-demand coretime pool, in parts or in entirety. - -Bulk coretime is a fixed duration of continuous coretime represented by an NFT that can be split, shared, or resold. It is managed by the [Broker pallet](https://paritytech.github.io/polkadot-sdk/master/pallet_broker/index.html){target=\_blank}. - -## Development Phrase - -A [mnemonic phrase](https://en.wikipedia.org/wiki/Mnemonic#For_numerical_sequences_and_mathematical_operations){target=\_blank} that is intentionally made public. - -Well-known development accounts, such as Alice, Bob, Charlie, Dave, Eve, and Ferdie, are generated from the same secret phrase: - -``` -bottom drive obey lake curtain smoke basket hold race lonely fit walk -``` - -Many tools in the Polkadot SDK ecosystem, such as [`subkey`](https://github.com/paritytech/polkadot-sdk/tree/polkadot-stable2506-2/substrate/bin/utils/subkey){target=\_blank}, allow you to implicitly specify an account using a derivation path such as `//Alice`. - -## Digest - -An extensible field of the [block header](#header) that encodes information needed by several actors in a blockchain network, including: - -- [Light clients](#light-client) for chain synchronization. -- Consensus engines for block verification. -- The runtime itself, in the case of pre-runtime digests. - -## Dispatchable - -Function objects that act as the entry points in FRAME [pallets](#pallet). Internal or external entities can call them to interact with the blockchain’s state. They are a core aspect of the runtime logic, handling [transactions](#transaction) and other state-changing operations. - -## Events - -A means of recording that some particular [state](#state) transition happened. - -In the context of [FRAME](#frame-framework-for-runtime-aggregation-of-modularized-entities), events are composable data types that each [pallet](#pallet) can individually define. Events in FRAME are implemented as a set of transient storage items inspected immediately after a block has been executed and reset during block initialization. - -## Executor - -A means of executing a function call in a given [runtime](#runtime) with a set of dependencies. -There are two orchestration engines in Polkadot SDK, _WebAssembly_ and _native_. - -- The _native executor_ uses a natively compiled runtime embedded in the node to execute calls. This is a performance optimization available to up-to-date nodes. - -- The _WebAssembly executor_ uses a [Wasm](#webassembly-wasm) binary and a Wasm interpreter to execute calls. The binary is guaranteed to be up-to-date regardless of the version of the blockchain node because it is persisted in the [state](#state) of the Polkadot SDK-based chain. - -## Existential Deposit - -The minimum balance an account is allowed to have in the [Balances pallet](https://paritytech.github.io/polkadot-sdk/master/pallet_balances/index.html){target=\_blank}. Accounts cannot be created with a balance less than the existential deposit amount. - -If an account balance drops below this amount, the Balances pallet uses [a FRAME System API](https://paritytech.github.io/substrate/master/frame_system/pallet/struct.Pallet.html#method.dec_ref){target=\_blank} to drop its references to that account. - -If the Balances pallet reference to an account is dropped, the account can be [reaped](https://paritytech.github.io/substrate/master/frame_system/pallet/struct.Pallet.html#method.allow_death){target=\_blank}. - -## Extrinsic - -A general term for data that originates outside the runtime, is included in a block, and leads to some action. This includes user-initiated transactions and inherent transactions placed into the block by the block builder. - -It is a SCALE-encoded array typically consisting of a version number, signature, and varying data types indicating the resulting runtime function to be called. Extrinsics can take two forms: [inherents](#inherent-transactions) and [transactions](#transaction). - -For more technical details, see the [Polkadot spec](https://spec.polkadot.network/id-extrinsics){target=\_blank}. - -## Fork Choice Rule/Strategy - -A fork choice rule or strategy helps determine which chain is valid when reconciling several network forks. A common fork choice rule is the [longest chain](https://paritytech.github.io/polkadot-sdk/master/sc_consensus/struct.LongestChain.html){target=\_blank}, in which the chain with the most blocks is selected. - -## FRAME (Framework for Runtime Aggregation of Modularized Entities) - -Enables developers to create blockchain [runtime](#runtime) environments from a modular set of components called [pallets](#pallet). It utilizes a set of procedural macros to construct runtimes. - -[Visit the Polkadot SDK docs for more details on FRAME.](https://paritytech.github.io/polkadot-sdk/master/polkadot_sdk_docs/polkadot_sdk/frame_runtime/index.html){target=\_blank} - -## Full Node - -A node that prunes historical states, keeping only recently finalized block states to reduce storage needs. Full nodes provide current chain state access and allow direct submission and validation of [extrinsics](#extrinsic), maintaining network decentralization. - -## Genesis Configuration - -A mechanism for specifying the initial state of a blockchain. By convention, this initial state or first block is commonly referred to as the genesis state or genesis block. The genesis configuration for Polkadot SDK-based chains is accomplished by way of a [chain specification](#chain-specification) file. - -## GRANDPA - -A deterministic finality mechanism for blockchains that is implemented in the [Rust](https://www.rust-lang.org/){target=\_blank} programming language. - -The [formal specification](https://github.com/w3f/consensus/blob/master/pdf/grandpa-old.pdf){target=\_blank} is maintained by the [Web3 Foundation](https://web3.foundation/){target=\_blank}. - -## Header - -A structure that aggregates the information used to summarize a block. Primarily, it consists of cryptographic information used by [light clients](#light-client) to get minimally secure but very efficient chain synchronization. - -## Hybrid Consensus - -A blockchain consensus protocol that consists of independent or loosely coupled mechanisms for [block production](#block-author) and finality. - -Hybrid consensus allows the chain to grow as fast as probabilistic consensus protocols, such as [Aura](#authority-round-aura), while maintaining the same level of security as deterministic finality consensus protocols, such as [GRANDPA](#grandpa). - -## Inherent Transactions - -A special type of unsigned transaction, referred to as _inherents_, that enables a block authoring node to insert information that doesn't require validation directly into a block. - -Only the block-authoring node that calls the inherent transaction function can insert data into its block. In general, validators assume the data inserted using an inherent transaction is valid and reasonable even if it can't be deterministically verified. - -## JSON-RPC - -A stateless, lightweight remote procedure call protocol encoded in JavaScript Object Notation (JSON). JSON-RPC provides a standard way to call functions on a remote system by using JSON. - -For Polkadot SDK, this protocol is implemented through the [Parity JSON-RPC](https://github.com/paritytech/jsonrpc){target=\_blank} crate. - -## Keystore - -A subsystem for managing keys for the purpose of producing new blocks. - -## Kusama - -[Kusama](https://kusama.network/){target=\_blank} is a Polkadot SDK-based blockchain that implements a design similar to the [Polkadot](#polkadot) network. - -Kusama is a [canary](https://en.wiktionary.org/wiki/canary_in_a_coal_mine){target=\_blank} network and is referred to as [Polkadot's "wild cousin."](https://wiki.polkadot.com/learn/learn-comparisons-kusama/){target=\_blank}. - -As a canary network, Kusama is expected to be more stable than a test network like [Westend](#westend) but less stable than a production network like [Polkadot](#polkadot). Kusama is controlled by its network participants and is intended to be stable enough to encourage meaningful experimentation. - -## libp2p - -A peer-to-peer networking stack that allows the use of many transport mechanisms, including WebSockets (usable in a web browser). - -Polkadot SDK uses the [Rust implementation](https://github.com/libp2p/rust-libp2p){target=\_blank} of the `libp2p` networking stack. - -## Light Client - -A type of blockchain node that doesn't store the [chain state](#state) or produce blocks. - -A light client can verify cryptographic primitives and provides a [remote procedure call (RPC)](https://en.wikipedia.org/wiki/Remote_procedure_call){target=\_blank} server, enabling blockchain users to interact with the network. - -## Metadata - -Data that provides information about one or more aspects of a system. -The metadata that exposes information about a Polkadot SDK blockchain enables you to interact with that system. - -## Nominated Proof of Stake (NPoS) - -A method for determining [validators](#validator) or _[authorities](#authority)_ based on a willingness to commit their stake to the proper functioning of one or more block-producing nodes. - -## Oracle - -An entity that connects a blockchain to a non-blockchain data source. Oracles enable the blockchain to access and act upon information from existing data sources and incorporate data from non-blockchain systems and services. - -## Origin - -A [FRAME](#frame-framework-for-runtime-aggregation-of-modularized-entities) primitive that identifies the source of a [dispatched](#dispatchable) function call into the [runtime](#runtime). The FRAME System pallet defines three built-in [origins](#origin). As a [pallet](#pallet) developer, you can also define custom origins, such as those defined by the [Collective pallet](https://paritytech.github.io/substrate/master/pallet_collective/enum.RawOrigin.html){target=\_blank}. - -## Pallet - -A module that can be used to extend the capabilities of a [FRAME](#frame-framework-for-runtime-aggregation-of-modularized-entities)-based [runtime](#runtime). -Pallets bundle domain-specific logic with runtime primitives like [events](#events) and [storage items](#storage-item). - -## Parachain - -A parachain is a blockchain that derives shared infrastructure and security from a _[relay chain](#relay-chain)_. -You can learn more about parachains on the [Polkadot Wiki](https://wiki.polkadot.com/learn/learn-parachains/){target=\_blank}. - -## Paseo - -Paseo TestNet provisions testing on Polkadot's "production" runtime, which means less chance of feature or code mismatch when developing parachain apps. Specifically, after the [Polkadot Technical fellowship](https://wiki.polkadot.com/learn/learn-polkadot-technical-fellowship/){target=\_blank} proposes a runtime upgrade for Polkadot, this TestNet is updated, giving a period where the TestNet will be ahead of Polkadot to allow for testing. - -## Polkadot - -The [Polkadot network](https://polkadot.com/){target=\_blank} is a blockchain that serves as the central hub of a heterogeneous blockchain network. It serves the role of the [relay chain](#relay-chain) and provides shared infrastructure and security to support [parachains](#parachain). - -## Polkadot Cloud - -Polkadot Cloud is a platform for deploying resilient, customizable and scalable Web3 applications through Polkadot's functionality. It encompasses the wider Polkadot network infrastructure and security layer where parachains operate. The platform enables users to launch Ethereum-compatible chains, build specialized blockchains, and flexibly manage computing resources through on-demand or bulk coretime purchases. Initially launched with basic parachain functionality, Polkadot Cloud has evolved to offer enhanced flexibility with features like coretime, elastic scaling, and async backing for improved performance. - -## Polkadot Hub - -Polkadot Hub is a Layer 1 platform that serves as the primary entry point to the Polkadot ecosystem, providing essential functionality without requiring parachain deployment. It offers core services including smart contracts, identity management, staking, governance, and interoperability with other ecosystems, making it simple and fast for both builders and users to get started in Web3. - -## PolkaVM - -PolkaVM is a custom virtual machine optimized for performance, leveraging a RISC-V-based architecture to support Solidity and any language that compiles to RISC-V. It is specifically designed for the Polkadot ecosystem, enabling smart contract deployment and execution. - -## Relay Chain - -Relay chains are blockchains that provide shared infrastructure and security to the [parachains](#parachain) in the network. In addition to providing [consensus](#consensus) capabilities, relay chains allow parachains to communicate and exchange digital assets without needing to trust one another. - -## Rococo - -A [parachain](#parachain) test network for the Polkadot network. The [Rococo](#rococo) network is a Polkadot SDK-based blockchain with an October 14, 2024 deprecation date. Development teams are encouraged to use the Paseo TestNet instead. - -## Runtime - -The runtime represents the [state transition function](#state-transition-function-stf) for a blockchain. In Polkadot SDK, the runtime is stored as a [Wasm](#webassembly-wasm) binary in the chain state. The Runtime is stored under a unique state key and can be modified during the execution of the state transition function. - -## Slot - -A fixed, equal interval of time used by consensus engines such as [Aura](#authority-round-aura) and [BABE](#blind-assignment-of-blockchain-extension-babe). In each slot, a subset of [authorities](#authority) is permitted, or obliged, to [author](#block-author) a block. - -## Sovereign Account - -The unique account identifier for each chain in the relay chain ecosystem. It is often used in cross-consensus (XCM) interactions to sign XCM messages sent to the relay chain or other chains in the ecosystem. - -The sovereign account for each chain is a root-level account that can only be accessed using the Sudo pallet or through governance. The account identifier is calculated by concatenating the Blake2 hash of a specific text string and the registered parachain identifier. - -## SS58 Address Format - -A public key address based on the Bitcoin [`Base-58-check`](https://en.bitcoin.it/wiki/Base58Check_encoding){target=\_blank} encoding. Each Polkadot SDK SS58 address uses a `base-58` encoded value to identify a specific account on a specific Polkadot SDK-based chain - -The [canonical `ss58-registry`](https://github.com/paritytech/ss58-registry){target=\_blank} provides additional details about the address format used by different Polkadot SDK-based chains, including the network prefix and website used for different networks - -## State Transition Function (STF) - -The logic of a blockchain that determines how the state changes when a block is processed. In Polkadot SDK, the state transition function is effectively equivalent to the [runtime](#runtime). - -## Storage Item - -[FRAME](#frame-framework-for-runtime-aggregation-of-modularized-entities) primitives that provide type-safe data persistence capabilities to the [runtime](#runtime). -Learn more in the [storage items](https://paritytech.github.io/polkadot-sdk/master/frame_support/storage/types/index.html){target=\_blank} reference document in the Polkadot SDK. - -## Substrate - -A flexible framework for building modular, efficient, and upgradeable blockchains. Substrate is written in the [Rust](https://www.rust-lang.org/){target=\_blank} programming language and is maintained by [Parity Technologies](https://www.parity.io/){target=\_blank}. - -## Transaction - -An [extrinsic](#extrinsic) that includes a signature that can be used to verify the account authorizing it inherently or via [signed extensions](https://paritytech.github.io/polkadot-sdk/master/polkadot_sdk_docs/reference_docs/signed_extensions/index.html){target=\_blank}. - -## Transaction Era - -A definable period expressed as a range of block numbers during which a transaction can be included in a block. -Transaction eras are used to protect against transaction replay attacks if an account is reaped and its replay-protecting nonce is reset to zero. - -## Trie (Patricia Merkle Tree) - -A data structure used to represent sets of key-value pairs and enables the items in the data set to be stored and retrieved using a cryptographic hash. Because incremental changes to the data set result in a new hash, retrieving data is efficient even if the data set is very large. With this data structure, you can also prove whether the data set includes any particular key-value pair without access to the entire data set. - -In Polkadot SDK-based blockchains, state is stored in a trie data structure that supports the efficient creation of incremental digests. This trie is exposed to the [runtime](#runtime) as [a simple key/value map](#storage-item) where both keys and values can be arbitrary byte arrays. - -## Validator - -A validator is a node that participates in the consensus mechanism of the network. Its roles include block production, transaction validation, network integrity, and security maintenance. - -## WebAssembly (Wasm) - -An execution architecture that allows for the efficient, platform-neutral expression of -deterministic, machine-executable logic. - -[Wasm](https://webassembly.org/){target=\_blank} can be compiled from many languages, including -the [Rust](https://www.rust-lang.org/){target=\_blank} programming language. Polkadot SDK-based chains use a Wasm binary to provide portable [runtimes](#runtime) that can be included as part of the chain's state. - -## Weight - -A convention used in Polkadot SDK-based blockchains to measure and manage the time it takes to validate a block. -Polkadot SDK defines one unit of weight as one picosecond of execution time on reference hardware. - -The maximum block weight should be equivalent to one-third of the target block time with an allocation of one-third each for: - -- Block construction -- Network propagation -- Import and verification - -By defining weights, you can trade-off the number of transactions per second and the hardware required to maintain the target block time appropriate for your use case. Weights are defined in the runtime, meaning you can tune them using runtime updates to keep up with hardware and software improvements. - -## Westend - -Westend is a Parity-maintained, Polkadot SDK-based blockchain that serves as a test network for the [Polkadot](#polkadot) network. - - --- Page Title: Install Polkadot SDK @@ -2911,76 +2543,6 @@ To stop the node, press `Control-C` in the terminal. ---- - -Page Title: Interoperability - -- Source (raw): https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/reference-parachains-interoperability.md -- Canonical (HTML): https://docs.polkadot.com/reference/parachains/interoperability/ -- Summary: Explore the importance of interoperability in the Polkadot ecosystem, covering XCM, bridges, and cross-chain communication. - -# Interoperability - -## Introduction - -Interoperability lies at the heart of the Polkadot ecosystem, enabling communication and collaboration across a diverse range of blockchains. By bridging the gaps between parachains, relay chains, and even external networks, Polkadot unlocks the potential for truly decentralized applications, efficient resource sharing, and scalable solutions. - -Polkadot’s design ensures that blockchains can transcend their individual limitations by working together as part of a unified system. This cooperative architecture is what sets Polkadot apart in the blockchain landscape. - -## Why Interoperability Matters - -The blockchain ecosystem is inherently fragmented. Different blockchains excel in specialized domains such as finance, gaming, or supply chain management, but these chains function in isolation without interoperability. This lack of connectivity stifles the broader utility of blockchain technology. - -Interoperability solves this problem by enabling blockchains to: - -- **Collaborate across networks**: Chains can interact to share assets, functionality, and data, creating synergies that amplify their individual strengths. -- **Achieve greater scalability**: Specialized chains can offload tasks to others, optimizing performance and resource utilization. -- **Expand use-case potential**: Cross-chain applications can leverage features from multiple blockchains, unlocking novel user experiences and solutions. - -In the Polkadot ecosystem, interoperability transforms a collection of isolated chains into a cohesive, efficient network, pushing the boundaries of what blockchains can achieve together. - -## Key Mechanisms for Interoperability - -At the core of Polkadot's cross-chain collaboration are foundational technologies designed to break down barriers between networks. These mechanisms empower blockchains to communicate, share resources, and operate as a cohesive ecosystem. - -### Cross-Consensus Messaging (XCM): The Backbone of Communication - -Polkadot's Cross-Consensus Messaging (XCM) is the standard framework for interaction between parachains, relay chains, and, eventually, external blockchains. XCM provides a trustless, secure messaging format for exchanging assets, sharing data, and executing cross-chain operations. - -Through XCM, decentralized applications can: - -- Transfer tokens and other assets across chains. -- Coordinate complex workflows that span multiple blockchains. -- Enable seamless user experiences where underlying blockchain differences are invisible. -- XCM exemplifies Polkadot’s commitment to creating a robust and interoperable ecosystem. - -For further information about XCM, check the [Get Started with XCM](/parachains/interoperability/get-started/){target=\_blank} article. - -### Bridges: Connecting External Networks - -While XCM enables interoperability within the Polkadot ecosystem, bridges extend this functionality to external blockchains such as Ethereum and Bitcoin. By connecting these networks, bridges allow Polkadot-based chains to access external liquidity, additional functionalities, and broader user bases. - -With bridges, developers and users gain the ability to: - -- Integrate external assets into Polkadot-based applications. -- Combine the strengths of Polkadot’s scalability with the liquidity of other networks. -- Facilitate accurate multi-chain applications that transcend ecosystem boundaries. - -For more information about bridges in the Polkadot ecosystem, see the [Bridge Hub](/reference/polkadot-hub/bridging/){target=\_blank} guide. - -## The Polkadot Advantage - -Polkadot was purpose-built for interoperability. Unlike networks that add interoperability as an afterthought, Polkadot integrates it as a fundamental design principle. This approach offers several distinct advantages: - -- **Developer empowerment**: Polkadot’s interoperability tools allow developers to build applications that leverage multiple chains’ capabilities without added complexity. -- **Enhanced ecosystem collaboration**: Chains in Polkadot can focus on their unique strengths while contributing to the ecosystem’s overall growth. -- **Future-proofing blockchain**: By enabling seamless communication, Polkadot ensures its ecosystem can adapt to evolving demands and technologies. - -## Looking Ahead - -Polkadot’s vision of interoperability extends beyond technical functionality, representing a shift towards a more collaborative blockchain landscape. By enabling chains to work together, Polkadot fosters innovation, efficiency, and accessibility, paving the way for a decentralized future where blockchains are not isolated competitors but interconnected collaborators. - - --- Page Title: JSON-RPC APIs @@ -3852,272 +3414,74 @@ If an error occurs, the response will include an error object: --- -Page Title: Networks +Page Title: Offenses and Slashes -- Source (raw): https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/reference-parachains-networks.md -- Canonical (HTML): https://docs.polkadot.com/reference/parachains/networks/ -- Summary: Explore Polkadot's testing and production networks, including Westend, Kusama, and Paseo, for efficient development, deployment, and testing. +- Source (raw): https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/nodes-and-validators-run-a-validator-staking-mechanics-offenses-and-slashes.md +- Canonical (HTML): https://docs.polkadot.com/nodes-and-validators/run-a-validator/staking-mechanics/offenses-and-slashes/ +- Summary: Learn about how Polkadot discourages validator misconduct via an offenses and slashing system, including details on offenses and their consequences. -# Networks +# Offenses and Slashes ## Introduction -The Polkadot ecosystem is built on a robust set of networks designed to enable secure and scalable development. Whether you are testing new features or deploying to live production, Polkadot offers several layers of networks tailored for each stage of the development process. From local environments to experimental networks like Kusama and community-run TestNets such as Paseo, developers can thoroughly test, iterate, and validate their applications. This guide will introduce you to Polkadot's various networks and explain how they fit into the development workflow. - -## Network Overview - -Polkadot's development process is structured to ensure new features and upgrades are rigorously tested before being deployed on live production networks. The progression follows a well-defined path, starting from local environments and advancing through TestNets, ultimately reaching the Polkadot MainNet. The diagram below outlines the typical progression of the Polkadot development cycle: +In Polkadot's Nominated Proof of Stake (NPoS) system, validator misconduct is deterred through a combination of slashing, disabling, and reputation penalties. Validators and nominators who stake tokens face consequences for validator misbehavior, which range from token slashes to restrictions on network participation. -``` mermaid -flowchart LR - id1[Local] --> id2[Westend] --> id4[Kusama] --> id5[Polkadot] - id1[Local] --> id3[Paseo] --> id5[Polkadot] -``` +This page outlines the types of offenses recognized by Polkadot, including block equivocations and invalid votes, as well as the corresponding penalties. While some parachains may implement additional custom slashing mechanisms, this guide focuses on the offenses tied to staking within the Polkadot ecosystem. -This flow ensures developers can thoroughly test and iterate without risking real tokens or affecting production networks. Testing tools like [Chopsticks](#chopsticks) and various TestNets make it easier to experiment safely before releasing to production. +## Offenses -A typical journey through the Polkadot core protocol development process might look like this: +Polkadot is a public permissionless network. As such, it has a mechanism to disincentivize offenses and incentivize good behavior. You can review the [parachain protocol](https://wiki.polkadot.com/learn/learn-parachains-protocol/#parachain-protocol){target=\_blank} to understand better the terminology used to describe offenses. Polkadot validator offenses fall into two categories: invalid votes and equivocations. -1. **Local development node**: Development starts in a local environment, where developers can create, test, and iterate on upgrades or new features using a local development node. This stage allows rapid experimentation in an isolated setup without any external dependencies. +### Invalid Votes -2. **Westend**: After testing locally, upgrades are deployed to [Westend](#westend), Polkadot's primary TestNet. Westend simulates real-world conditions without using real tokens, making it the ideal place for rigorous feature testing before moving on to production networks. +A validator will be penalized for inappropriate voting activity during the block inclusion and approval processes. The invalid voting related offenses are as follows: -3. **Kusama**: Once features have passed extensive testing on Westend, they move to Kusama, Polkadot's experimental and fast-moving "canary" network. Kusama operates as a high-fidelity testing ground with actual economic incentives, giving developers insights into how their features will perform in a real-world environment. +- **Backing an invalid block**: A para-validator backs an invalid block for inclusion in a fork of the relay chain. +- **`ForInvalid` vote**: When acting as a secondary checker, the validator votes in favor of an invalid block. +- **`AgainstValid` vote**: When acting as a secondary checker, the validator votes against a valid block. This type of vote wastes network resources required to resolve the disparate votes and resulting dispute. -4. **Polkadot**: After passing tests on Westend and Kusama, features are considered ready for deployment to Polkadot, the live production network. +### Equivocations - In addition, parachain developers can leverage local TestNets like [Zombienet](#zombienet) and deploy upgrades on parachain TestNets. +Equivocation occurs when a validator produces statements that conflict with each other when producing blocks or voting. Unintentional equivocations usually occur when duplicate signing keys reside on the validator host. If keys are never duplicated, the probability of an honest equivocation slash decreases to near zero. The equivocation related offenses are as follows: -5. **Paseo**: For parachain and dApp developers, Paseo serves as a community-run TestNet that mirrors Polkadot's runtime. Like Westend for core protocol development, Paseo provides a testing ground for parachain development without affecting live networks. +- **Equivocation**: The validator produces two or more of the same block or vote. + - **GRANDPA and BEEFY equivocation**: The validator signs two or more votes in the same round on different chains. + - **BABE equivocation**: The validator produces two or more blocks on the relay chain in the same time slot. +- **Double seconded equivocation**: The validator attempts to second, or back, more than one block in the same round. +- **Seconded and valid equivocation**: The validator seconds, or backs, a block and then attempts to hide their role as the responsible backer by later placing a standard validation vote. -!!!note - The Rococo TestNet deprecation date was October 14, 2024. Teams should use Westend for Polkadot protocol and feature testing and Paseo for chain development-related testing. +## Penalties -## Polkadot Development Networks +On Polkadot, offenses to the network incur different penalties depending on severity. There are three main penalties: slashing, disabling, and reputation changes. -Development and testing are crucial to building robust dApps and parachains and performing network upgrades within the Polkadot ecosystem. To achieve this, developers can leverage various networks and tools that provide a risk-free environment for experimentation and validation before deploying features to live networks. These networks help avoid the costs and risks associated with real tokens, enabling testing for functionalities like governance, cross-chain messaging, and runtime upgrades. +### Slashing -## Kusama Network +Validators engaging in bad actor behavior in the network may be subject to slashing if they commit a qualifying offense. When a validator is slashed, they and their nominators lose a percentage of their staked DOT or KSM, from as little as 0.01% up to 100% based on the severity of the offense. Nominators are evaluated for slashing against their active validations at any given time. Validator nodes are evaluated as discrete entities, meaning an operator can't attempt to mitigate the offense on another node they operate in order to avoid a slash. -Kusama is the experimental version of Polkadot, designed for developers who want to move quickly and test their applications in a real-world environment with economic incentives. Kusama serves as a production-grade testing ground where developers can deploy features and upgrades with the pressure of game theory and economics in mind. It mirrors Polkadot but operates as a more flexible space for innovation. +Any slashed DOT or KSM will be added to the [Treasury](https://wiki.polkadot.com/learn/learn-polkadot-opengov-treasury/){target=\_blank} rather than burned or distributed as rewards. Moving slashed funds to the Treasury allows tokens to be quickly moved away from malicious validators while maintaining the ability to revert faulty slashes when needed. -The native token for Kusama is KSM. For more information about KSM, visit the [Native Assets](https://wiki.polkadot.com/kusama/kusama-getting-started/){target=\_blank} page. +A nominator with a very large bond may nominate several validators in a single era. In this case, a slash is proportionate to the amount staked to the offending validator. Stake allocation and validator activation is controlled by the [Phragmén algorithm](https://wiki.polkadot.com/learn/learn-phragmen/#algorithm){target=\_blank}. -## Test Networks +A validator slash creates an `unapplied` state transition. You can view pending slashes on [Polkadot.js Apps](https://polkadot.js.org/apps/?rpc=wss%3A%2F%2Frpc.polkadot.io#/staking/slashes){target=\_blank}. The UI will display the slash per validator, the affected nominators, and the slash amounts. The unapplied state includes a 27-day grace period during which a governance proposal can be made to reverse the slash. Once this grace period expires, the slash is applied. -The following test networks provide controlled environments for testing upgrades and new features. TestNet tokens are available from the [Polkadot faucet](https://faucet.polkadot.io/){target=\_blank}. +#### Equivocation Slash -### Westend +The Web3 Foundation's [Slashing mechanisms](https://research.web3.foundation/Polkadot/security/slashing/amounts){target=\_blank} page provides guidelines for evaluating the security threat level of different offenses and determining penalties proportionate to the threat level of the offense. Offenses requiring coordination between validators or extensive computational costs to the system will typically call for harsher penalties than those more likely to be unintentional than malicious. A description of potential offenses for each threat level and the corresponding penalties is as follows: -Westend is Polkadot's primary permanent TestNet. Unlike temporary test networks, Westend is not reset to the genesis block, making it an ongoing environment for testing Polkadot core features. Managed by Parity Technologies, Westend ensures that developers can test features in a real-world simulation without using actual tokens. +- **Level 1**: Honest misconduct such as isolated cases of unresponsiveness. + - **Penalty**: Validator can be kicked out or slashed up to 0.1% of stake in the validator slot. +- **Level 2**: Misconduct that can occur honestly but is a sign of bad practices. Examples include repeated cases of unresponsiveness and isolated cases of equivocation. + - **Penalty**: Slash of up to 1% of stake in the validator slot. +- **Level 3**: Misconduct that is likely intentional but of limited effect on the performance or security of the network. This level will typically include signs of coordination between validators. Examples include repeated cases of equivocation or isolated cases of unjustified voting on GRANDPA. + - **Penalty**: Reduction in networking reputation metrics, slash of up to 10% of stake in the validator slot. +- **Level 4**: Misconduct that poses severe security or monetary risk to the system or mass collusion. Examples include signs of extensive coordination, creating a serious security risk to the system, or forcing the system to use extensive resources to counter the misconduct. + - **Penalty**: Slash of up to 100% of stake in the validator slot. -The native token for Westend is WND. More details about WND can be found on the [Native Assets](https://wiki.polkadot.com/learn/learn-dot/#__tabbed_2_2){target=\_blank} page. +See the next section to understand how slash amounts for equivocations are calculated. If you want to know more details about slashing, please look at the research page on [Slashing mechanisms](https://research.web3.foundation/Polkadot/security/slashing/amounts){target=\_blank}. -### Paseo +#### Slash Calculation for Equivocation -[Paseo](https://github.com/paseo-network){target=\_blank} is a community-managed TestNet designed for parachain and dApp developers. It mirrors Polkadot's runtime and is maintained by Polkadot community members. Paseo provides a dedicated space for parachain developers to test their applications in a Polkadot-like environment without the risks associated with live networks. - -The native token for Paseo is PAS. Additional information on PAS is available on the [Native Assets](https://wiki.polkadot.com/learn/learn-dot/#__tabbed_2_1){target=\_blank} page. - -## Local Test Networks - -Local test networks are an essential part of the development cycle for blockchain developers using the Polkadot SDK. They allow for fast, iterative testing in controlled, private environments without connecting to public TestNets. Developers can quickly spin up local instances to experiment, debug, and validate their code before deploying to larger TestNets like Westend or Paseo. Two key tools for local network testing are Zombienet and Chopsticks. - -### Zombienet - -[Zombienet](https://github.com/paritytech/zombienet){target=\_blank} is a flexible testing framework for Polkadot SDK-based blockchains. It enables developers to create and manage ephemeral, short-lived networks. This feature makes Zombienet particularly useful for quick iterations, as it allows you to run multiple local networks concurrently, mimicking different runtime conditions. Whether you're developing a parachain or testing your custom blockchain logic, Zombienet gives you the tools to automate local testing. - -Key features of Zombienet include: - -- Creating dynamic, local networks with different configurations. -- Running parachains and relay chains in a simulated environment. -- Efficient testing of network components like cross-chain messaging and governance. - -Zombienet is ideal for developers looking to test quickly and thoroughly before moving to more resource-intensive public TestNets. - -### Chopsticks - -[Chopsticks](https://github.com/AcalaNetwork/chopsticks){target=\_blank} is a tool designed to create forks of Polkadot SDK-based blockchains, allowing developers to interact with network forks as part of their testing process. This capability makes Chopsticks a powerful option for testing upgrades, runtime changes, or cross-chain applications in a forked network environment. - -Key features of Chopsticks include: - -- Forking live Polkadot SDK-based blockchains for isolated testing. -- Simulating cross-chain messages in a private, controlled setup. -- Debugging network behavior by interacting with the fork in real-time. - -Chopsticks provides a controlled environment for developers to safely explore the effects of runtime changes. It ensures that network behavior is tested and verified before upgrades are deployed to live networks. - - ---- - -Page Title: Node and Runtime - -- Source (raw): https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/reference-parachains-node-and-runtime.md -- Canonical (HTML): https://docs.polkadot.com/reference/parachains/node-and-runtime/ -- Summary: Learn how Polkadot SDK-based nodes function, how the client and runtime are separated, and how they communicate using SCALE-encoded data. - -# Node and Runtime - -## Introduction - -Every blockchain platform relies on a decentralized network of computers, called nodes, that communicate with each other about transactions and blocks. In this context, a node refers to the software running on the connected devices rather than the physical or virtual machines in the network. - -Polkadot SDK-based nodes consist of two main components, each with distinct responsibilities: the client (also called node) and the runtime. - -If the system were a monolithic protocol, any modification would require updating the entire system. Instead, Polkadot achieves true upgradeability by defining an immutable meta-protocol (the client) and a protocol (the runtime) that can be upgraded independently. - -This separation gives the [Polkadot Relay Chain](/polkadot-protocol/architecture/polkadot-chain){target=\_blank} and all connected [parachains](/polkadot-protocol/architecture/parachains){target=\_blank} an evolutionary advantage over other blockchain platforms. - -## Architectural Principles - -The Polkadot SDK-based blockchain architecture is fundamentally built on two distinct yet interconnected components: - -- Client (Meta-protocol): - - Handles the foundational infrastructure of the blockchain. - - Manages runtime execution, networking, consensus, and other off-chain components. - - Provides an immutable base layer that ensures network stability. - - Upgradable only through hard forks. - -- Runtime (Protocol): - - Defines the blockchain's state transition logic. - - Determines the specific rules and behaviors of the blockchain. - - Compiled to WebAssembly (Wasm) for platform-independent execution. - - Capable of being upgraded without network-wide forking. - -### Advantages of this Architecture - -- **Forkless upgrades**: Runtime can be updated without disrupting the entire network. -- **Modularity**: Clear separation allows independent development of client and runtime. -- **Flexibility**: Enables rapid iteration and evolution of blockchain logic. -- **Performance**: WebAssembly compilation provides efficient, cross-platform execution. - -## Node (Client) - -The node, also known as the client, is the core component responsible for executing the Wasm runtime and orchestrating various essential blockchain components. It ensures the correct execution of the state transition function and manages multiple critical subsystems, including: - -- **Wasm execution**: Runs the blockchain runtime, which defines the state transition rules. -- **Database management**: Stores blockchain data. -- **Networking**: Facilitates peer-to-peer communication, block propagation, and transaction gossiping. -- **Transaction pool (Mempool)**: Manages pending transactions before they are included in a block. -- **Consensus mechanism**: Ensures agreement on the blockchain state across nodes. -- **RPC services**: Provides external interfaces for applications and users to interact with the node. - -## Runtime - -The runtime is more than just a set of rules. It's the fundamental logic engine that defines a blockchain's entire behavior. In Polkadot SDK-based blockchains, the runtime represents a complete, self-contained description of the blockchain's state transition function. - -### Characteristics - -The runtime is distinguished by three key characteristics: - -- **Business logic**: Defines the complete application-specific blockchain behavior. -- **WebAssembly compilation**: Ensures platform-independent, secure execution. -- **On-chain storage**: Stored within the blockchain's state, allowing dynamic updates. - -### Key Functions - -The runtime performs several critical functions, such as: - -- Define state transition rules. -- Implement blockchain-specific logic. -- Manage account interactions. -- Control transaction processing. -- Define governance mechanisms. -- Handle custom pallets and modules. - -## Communication Between Node and Runtime - -The client and runtime communicate exclusively using [SCALE-encoded](/polkadot-protocol/parachain-basics/data-encoding){target=\_blank} communication. This ensures efficient and compact data exchange between the two components. - -### Runtime APIs - -The Runtime API consists of well-defined functions and constants a client assumes are implemented in the Runtime Wasm blob. These APIs enable the client to interact with the runtime to execute blockchain operations and retrieve information. The client invokes these APIs to: - -- Build, execute, and finalize blocks. -- Access metadata. -- Access consensus related information. -- Handle transaction execution. - -### Host Functions - -During execution, the runtime can access certain external client functionalities via host functions. The specific functions the client exposes allow the runtime to perform operations outside the WebAssembly domain. Host functions enable the runtime to: - -- Perform cryptographic operations. -- Access the current blockchain state. -- Handle storage modifications. -- Allocate memory. - - ---- - -Page Title: Offenses and Slashes - -- Source (raw): https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/nodes-and-validators-run-a-validator-staking-mechanics-offenses-and-slashes.md -- Canonical (HTML): https://docs.polkadot.com/nodes-and-validators/run-a-validator/staking-mechanics/offenses-and-slashes/ -- Summary: Learn about how Polkadot discourages validator misconduct via an offenses and slashing system, including details on offenses and their consequences. - -# Offenses and Slashes - -## Introduction - -In Polkadot's Nominated Proof of Stake (NPoS) system, validator misconduct is deterred through a combination of slashing, disabling, and reputation penalties. Validators and nominators who stake tokens face consequences for validator misbehavior, which range from token slashes to restrictions on network participation. - -This page outlines the types of offenses recognized by Polkadot, including block equivocations and invalid votes, as well as the corresponding penalties. While some parachains may implement additional custom slashing mechanisms, this guide focuses on the offenses tied to staking within the Polkadot ecosystem. - -## Offenses - -Polkadot is a public permissionless network. As such, it has a mechanism to disincentivize offenses and incentivize good behavior. You can review the [parachain protocol](https://wiki.polkadot.com/learn/learn-parachains-protocol/#parachain-protocol){target=\_blank} to understand better the terminology used to describe offenses. Polkadot validator offenses fall into two categories: invalid votes and equivocations. - -### Invalid Votes - -A validator will be penalized for inappropriate voting activity during the block inclusion and approval processes. The invalid voting related offenses are as follows: - -- **Backing an invalid block**: A para-validator backs an invalid block for inclusion in a fork of the relay chain. -- **`ForInvalid` vote**: When acting as a secondary checker, the validator votes in favor of an invalid block. -- **`AgainstValid` vote**: When acting as a secondary checker, the validator votes against a valid block. This type of vote wastes network resources required to resolve the disparate votes and resulting dispute. - -### Equivocations - -Equivocation occurs when a validator produces statements that conflict with each other when producing blocks or voting. Unintentional equivocations usually occur when duplicate signing keys reside on the validator host. If keys are never duplicated, the probability of an honest equivocation slash decreases to near zero. The equivocation related offenses are as follows: - -- **Equivocation**: The validator produces two or more of the same block or vote. - - **GRANDPA and BEEFY equivocation**: The validator signs two or more votes in the same round on different chains. - - **BABE equivocation**: The validator produces two or more blocks on the relay chain in the same time slot. -- **Double seconded equivocation**: The validator attempts to second, or back, more than one block in the same round. -- **Seconded and valid equivocation**: The validator seconds, or backs, a block and then attempts to hide their role as the responsible backer by later placing a standard validation vote. - -## Penalties - -On Polkadot, offenses to the network incur different penalties depending on severity. There are three main penalties: slashing, disabling, and reputation changes. - -### Slashing - -Validators engaging in bad actor behavior in the network may be subject to slashing if they commit a qualifying offense. When a validator is slashed, they and their nominators lose a percentage of their staked DOT or KSM, from as little as 0.01% up to 100% based on the severity of the offense. Nominators are evaluated for slashing against their active validations at any given time. Validator nodes are evaluated as discrete entities, meaning an operator can't attempt to mitigate the offense on another node they operate in order to avoid a slash. - -Any slashed DOT or KSM will be added to the [Treasury](https://wiki.polkadot.com/learn/learn-polkadot-opengov-treasury/){target=\_blank} rather than burned or distributed as rewards. Moving slashed funds to the Treasury allows tokens to be quickly moved away from malicious validators while maintaining the ability to revert faulty slashes when needed. - -A nominator with a very large bond may nominate several validators in a single era. In this case, a slash is proportionate to the amount staked to the offending validator. Stake allocation and validator activation is controlled by the [Phragmén algorithm](https://wiki.polkadot.com/learn/learn-phragmen/#algorithm){target=\_blank}. - -A validator slash creates an `unapplied` state transition. You can view pending slashes on [Polkadot.js Apps](https://polkadot.js.org/apps/?rpc=wss%3A%2F%2Frpc.polkadot.io#/staking/slashes){target=\_blank}. The UI will display the slash per validator, the affected nominators, and the slash amounts. The unapplied state includes a 27-day grace period during which a governance proposal can be made to reverse the slash. Once this grace period expires, the slash is applied. - -#### Equivocation Slash - -The Web3 Foundation's [Slashing mechanisms](https://research.web3.foundation/Polkadot/security/slashing/amounts){target=\_blank} page provides guidelines for evaluating the security threat level of different offenses and determining penalties proportionate to the threat level of the offense. Offenses requiring coordination between validators or extensive computational costs to the system will typically call for harsher penalties than those more likely to be unintentional than malicious. A description of potential offenses for each threat level and the corresponding penalties is as follows: - -- **Level 1**: Honest misconduct such as isolated cases of unresponsiveness. - - **Penalty**: Validator can be kicked out or slashed up to 0.1% of stake in the validator slot. -- **Level 2**: Misconduct that can occur honestly but is a sign of bad practices. Examples include repeated cases of unresponsiveness and isolated cases of equivocation. - - **Penalty**: Slash of up to 1% of stake in the validator slot. -- **Level 3**: Misconduct that is likely intentional but of limited effect on the performance or security of the network. This level will typically include signs of coordination between validators. Examples include repeated cases of equivocation or isolated cases of unjustified voting on GRANDPA. - - **Penalty**: Reduction in networking reputation metrics, slash of up to 10% of stake in the validator slot. -- **Level 4**: Misconduct that poses severe security or monetary risk to the system or mass collusion. Examples include signs of extensive coordination, creating a serious security risk to the system, or forcing the system to use extensive resources to counter the misconduct. - - **Penalty**: Slash of up to 100% of stake in the validator slot. - -See the next section to understand how slash amounts for equivocations are calculated. If you want to know more details about slashing, please look at the research page on [Slashing mechanisms](https://research.web3.foundation/Polkadot/security/slashing/amounts){target=\_blank}. - -#### Slash Calculation for Equivocation - -The slashing penalty for GRANDPA, BABE, and BEEFY equivocations is calculated using the formula below, where `x` represents the number of offenders and `n` is the total number of validators in the active set: +The slashing penalty for GRANDPA, BABE, and BEEFY equivocations is calculated using the formula below, where `x` represents the number of offenders and `n` is the total number of validators in the active set: ```text min((3 * x / n )^2, 1) @@ -4222,100 +3586,6 @@ Some minor offenses, such as spamming, are only punished by networking reputatio Refer to the Polkadot Wiki's [offenses page](https://wiki.polkadot.com/learn/learn-offenses/){target=\_blank} for a summary of penalties for specific offenses. ---- - -Page Title: On-Chain Governance Overview - -- Source (raw): https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/reference-governance.md -- Canonical (HTML): https://docs.polkadot.com/reference/governance/ -- Summary: Discover Polkadot’s cutting-edge OpenGov system, enabling transparent, decentralized decision-making through direct democracy and flexible governance tracks. - -# On-Chain Governance - -## Introduction - -Polkadot’s governance system exemplifies decentralized decision-making, empowering its community of stakeholders to shape the network’s future through active participation. The latest evolution, OpenGov, builds on Polkadot’s foundation by providing a more inclusive and efficient governance model. - -This guide will explain the principles and structure of OpenGov and walk you through its key components, such as Origins, Tracks, and Delegation. You will learn about improvements over earlier governance systems, including streamlined voting processes and enhanced stakeholder participation. - -With OpenGov, Polkadot achieves a flexible, scalable, and democratic governance framework that allows multiple proposals to proceed simultaneously, ensuring the network evolves in alignment with its community's needs. - -## Governance Evolution - -Polkadot’s governance journey began with [Governance V1](https://wiki.polkadot.com/learn/learn-polkadot-opengov/#governance-summary){target=\_blank}, a system that proved effective in managing treasury funds and protocol upgrades. However, it faced limitations, such as: - -- Slow voting cycles, causing delays in decision-making. -- Inflexibility in handling multiple referendums, restricting scalability. - -To address these challenges, Polkadot introduced OpenGov, a governance model designed for greater inclusivity, efficiency, and scalability. OpenGov replaces the centralized structures of Governance V1, such as the Council and Technical Committee, with a fully decentralized and dynamic framework. - -For a full comparison of the historic and current governance models, visit the [Gov1 vs. Polkadot OpenGov](https://wiki.polkadot.com/learn/learn-polkadot-opengov/#gov1-vs-polkadot-opengov){target=\_blank} section of the Polkadot Wiki. - -## OpenGov Key Features - -OpenGov transforms Polkadot’s governance into a decentralized, stakeholder-driven model, eliminating centralized decision-making bodies like the Council. Key enhancements include: - -- **Decentralization**: Shifts all decision-making power to the public, ensuring a more democratic process. -- **Enhanced delegation**: Allows users to delegate their votes to trusted experts across specific governance tracks. -- **Simultaneous referendums**: Multiple proposals can progress at once, enabling faster decision-making. -- **Polkadot Technical Fellowship**: A broad, community-driven group replacing the centralized Technical Committee. - -This new system ensures Polkadot governance remains agile and inclusive, even as the ecosystem grows. - -## Origins and Tracks - -In OpenGov, origins and tracks are central to managing proposals and votes. - -- **Origin**: Determines the authority level of a proposal (e.g., Treasury, Root) which decides the track of all referendums from that origin. -- **Track**: Define the procedural flow of a proposal, such as voting duration, approval thresholds, and enactment timelines. - -Developers must be aware that referendums from different origins and tracks will take varying amounts of time to reach approval and enactment. The [Polkadot Technical Fellowship](https://wiki.polkadot.com/learn/learn-polkadot-technical-fellowship/){target=\_blank} has the option to shorten this timeline by whitelisting a proposal and allowing it to be enacted through the [Whitelist Caller](https://wiki.polkadot.com/learn/learn-polkadot-opengov-origins/#whitelisted-caller){target=\_blank} origin. - -Visit [Origins and Tracks Info](https://wiki.polkadot.com/learn/learn-polkadot-opengov/#origins-and-tracks){target=\_blank} for details on current origins and tracks, associated terminology, and parameters. - -## Referendums - -In OpenGov, anyone can submit a referendum, fostering an open and participatory system. The timeline for a referendum depends on the privilege level of the origin with more significant changes offering more time for community voting and participation before enactment. - -The timeline for an individual referendum includes four distinct periods: - -- **Lead-in**: A minimum amount of time to allow for community participation, available room in the origin, and payment of the decision deposit. Voting is open during this period. -- **Decision**: Voting continues. -- **Confirmation**: Referendum must meet [approval and support](https://wiki.polkadot.com/learn/learn-polkadot-opengov/#approval-and-support){target=\_blank} criteria during entire period to avoid rejection. -- **Enactment**: Changes approved by the referendum are executed. - -### Vote on Referendums - -Voters can vote with their tokens on each referendum. Polkadot uses a voluntary token locking mechanism, called conviction voting, as a way for voters to increase their voting power. A token holder signals they have a stronger preference for approving a proposal based upon their willingness to lock up tokens. Longer voluntary token locks are seen as a signal of continual approval and translate to increased voting weight. - -See [Voting on a Referendum](https://wiki.polkadot.com/learn/learn-polkadot-opengov/#voting-on-a-referendum){target=\_blank} for a deeper look at conviction voting and related token locks. - -### Delegate Voting Power - -The OpenGov system also supports multi-role delegations, allowing token holders to assign their voting power on different tracks to entities with expertise in those areas. - -For example, if a token holder lacks the technical knowledge to evaluate proposals on the [Root track](https://wiki.polkadot.com/learn/learn-polkadot-opengov-origins/#root){target=\_blank}, they can delegate their voting power for that track to an expert they trust to vote in the best interest of the network. This ensures informed decision-making across tracks while maintaining flexibility for token holders. - -Visit [Multirole Delegation](https://wiki.polkadot.com/learn/learn-polkadot-opengov/#multirole-delegation){target=\_blank} for more details on delegating voting power. - -### Cancel a Referendum - -Polkadot OpenGov has two origins for rejecting ongoing referendums: - -- [**Referendum Canceller**](https://wiki.polkadot.com/learn/learn-polkadot-opengov-origins/#referendum-canceller){target=\_blank}: Cancels an active referendum when non-malicious errors occur and refunds the deposits to the originators. -- [**Referendum Killer**](https://wiki.polkadot.com/learn/learn-polkadot-opengov-origins/#referendum-killer){target=\_blank}: Used for urgent, malicious cases this origin instantly terminates an active referendum and slashes deposits. - -See [Cancelling, Killing, and Blacklisting](https://wiki.polkadot.com/learn/learn-polkadot-opengov/#cancelling-killing--blacklisting){target=\_blank} for additional information on rejecting referendums. - -## Additional Resources - -- **[Democracy pallet](https://github.com/paritytech/polkadot-sdk/tree/polkadot-stable2506-2/substrate/frame/democracy/src){target=\_blank}**: Handles administration of general stakeholder voting. -- **[Gov2: Polkadot’s Next Generation of Decentralised Governance](https://medium.com/polkadot-network/gov2-polkadots-next-generation-of-decentralised-governance-4d9ef657d11b){target=\_blank}**: Medium article by Gavin Wood. -- **[Polkadot Direction](https://matrix.to/#/#Polkadot-Direction:parity.io){target=\_blank}**: Matrix Element client. -- **[Polkassembly](https://polkadot.polkassembly.io/){target=\_blank}**: OpenGov dashboard and UI. -- **[Polkadot.js Apps Governance](https://polkadot.js.org/apps/#/referenda){target=\_blank}**: Overview of active referendums. - - --- Page Title: Overview of FRAME @@ -4454,873 +3724,51 @@ This section covers the most common customization patterns you'll encounter: --- -Page Title: Overview of the Polkadot Relay Chain - -- Source (raw): https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/reference-polkadot-hub-consensus-and-security-relay-chain.md -- Canonical (HTML): https://docs.polkadot.com/reference/polkadot-hub/consensus-and-security/relay-chain/ -- Summary: Explore Polkadot's core architecture, including its multi-chain vision, shared security, and the DOT token's governance and staking roles. - -# Overview - -## Introduction - -Polkadot is a next-generation blockchain protocol designed to support a multi-chain future by enabling secure communication and interoperability between different blockchains. Built as a Layer-0 protocol, Polkadot introduces innovations like application-specific Layer-1 chains ([parachains](/polkadot-protocol/architecture/parachains/){targe=\_blank}), shared security through [Nominated Proof of Stake (NPoS)](/reference/glossary/#nominated-proof-of-stake-npos){target=\_blank}, and cross-chain interactions via its native [Cross-Consensus Messaging Format (XCM)](/parachains/interoperability/get-started/){target=\_blank}. - -This guide covers key aspects of Polkadot’s architecture, including its high-level protocol structure, blockspace commoditization, and the role of its native token, DOT, in governance, staking, and resource allocation. - -## Polkadot 1.0 - -Polkadot 1.0 represents the state of Polkadot as of 2023, coinciding with the release of [Polkadot runtime v1.0.0](https://github.com/paritytech/polkadot/releases/tag/v1.0.0){target=\_blank}. This section will focus on Polkadot 1.0, along with philosophical insights into network resilience and blockspace. - -As a Layer-0 blockchain, Polkadot contributes to the multi-chain vision through several key innovations and initiatives, including: - -- **Application-specific Layer-1 blockchains (parachains)**: Polkadot's sharded network allows for parallel transaction processing, with shards that can have unique state transition functions, enabling custom-built L1 chains optimized for specific applications. - -- **Shared security and scalability**: L1 chains connected to Polkadot benefit from its [Nominated Proof of Stake (NPoS)](/reference/polkadot-hub/consensus-and-security/pos-consensus/#nominated-proof-of-stake){target=\_blank} system, providing security out-of-the-box without the need to bootstrap their own. - -- **Secure interoperability**: Polkadot's native interoperability enables seamless data and value exchange between parachains. This interoperability can also be used outside of the ecosystem for bridging with external networks. - -- **Resilient infrastructure**: Decentralized and scalable, Polkadot ensures ongoing support for development and community initiatives via its on-chain [treasury](https://wiki.polkadot.com/learn/learn-polkadot-opengov-treasury/){target=\_blank} and governance. - -- **Rapid L1 development**: The [Polkadot SDK](/reference/parachains/){target=\_blank} allows fast, flexible creation and deployment of Layer-1 chains. - -- **Cultivating the next generation of Web3 developers**: Polkadot supports the growth of Web3 core developers through initiatives such as. - - - [Polkadot Blockchain Academy](https://polkadot.com/blockchain-academy){target=\_blank} - - [EdX courses](https://www.edx.org/school/web3x){target=\_blank} - - Rust and Substrate courses (coming soon) - -### High-Level Architecture - -Polkadot features a chain that serves as the central component of the system. This chain is depicted as a ring encircled by several parachains that are connected to it. - -According to Polkadot's design, any blockchain that can compile to WebAssembly (Wasm) and adheres to the Parachains Protocol becomes a parachain on the Polkadot network. - -Here’s a high-level overview of the Polkadot protocol architecture: - -![](/images/reference/polkadot-hub/consensus-and-security/relay-chain/relay-chain-01.webp){ style="background:white" } - -Parachains propose blocks to Polkadot validators, who check for availability and validity before finalizing them. With the relay chain providing security, collators—full nodes of parachains—can focus on their tasks without needing strong incentives. - -The [Cross-Consensus Messaging Format (XCM)](/parachains/interoperability/get-started/){target=\_blank} allows parachains to exchange messages freely, leveraging the chain's security for trust-free communication. - -In order to interact with chains that want to use their own finalization process (e.g., Bitcoin), Polkadot has [bridges](/reference/parachains/interoperability/#bridges-connecting-external-networks){target=\_blank} that offer two-way compatibility, meaning that transactions can be made between different parachains. - -### Polkadot's Additional Functionalities - -Historically, obtaining core slots on Polkadot chain relied upon crowdloans and auctions. Chain cores were leased through auctions for three-month periods, up to a maximum of two years. Crowdloans enabled users to securely lend funds to teams for lease deposits in exchange for pre-sale tokens, which is the only way to access slots on Polkadot 1.0. Auctions are now deprecated in favor of [coretime](/polkadot-protocol/architecture/system-chains/coretime/){target=\_blank}. - -Additionally, the chain handles [staking](https://wiki.polkadot.com/learn/learn-staking/){target=\_blank}, [accounts](/reference/parachains/accounts/){target=\_blank}, balances, and [governance](/reference/governance/){target=\_blank}. - -#### Agile Coretime - -The new and more efficient way of obtaining core on Polkadot is to go through the process of purchasing coretime. - -[Agile coretime](/reference/polkadot-hub/consensus-and-security/agile-coretime/){target=\_blank} improves the efficient use of Polkadot's network resources and offers economic flexibility for developers, extending Polkadot's capabilities far beyond the original vision outlined in the [whitepaper](https://polkadot.com/papers/Polkadot-whitepaper.pdf){target=\_blank}. - -It enables parachains to purchase monthly "bulk" allocations of coretime (the time allocated for utilizing a core, measured in Polkadot relay chain blocks), ensuring heavy-duty parachains that can author a block every six seconds with [Asynchronous Backing](https://wiki.polkadot.com/learn/learn-async-backing/#asynchronous-backing){target=\_blank} can reliably renew their coretime each month. Although six-second block times are now the default, parachains have the option of producing blocks less frequently. - -Renewal orders are prioritized over new orders, offering stability against price fluctuations and helping parachains budget more effectively for project costs. - -### Polkadot's Resilience - -Decentralization is a vital component of blockchain networks, but it comes with trade-offs: - -- An overly decentralized network may face challenges in reaching consensus and require significant energy to operate. -- Also, a network that achieves consensus quickly risks centralization, making it easier to manipulate or attack. - -A network should be decentralized enough to prevent manipulative or malicious influence. In this sense, decentralization is a tool for achieving resilience. - -Polkadot 1.0 currently achieves resilience through several strategies: - -- **Nominated Proof of Stake (NPoS)**: Ensures that the stake per validator is maximized and evenly distributed among validators. - -- **Decentralized nodes**: Designed to encourage operators to join the network. This program aims to expand and diversify the validators in the ecosystem who aim to become independent of the program during their term. Feel free to explore more about the program on the official [Decentralized Nodes](https://nodes.web3.foundation/){target=\_blank} page. - -- **On-chain treasury and governance**: Known as [OpenGov](/reference/governance/){target=\_blank}, this system allows every decision to be made through public referenda, enabling any token holder to cast a vote. - -### Polkadot's Blockspace - -Polkadot 1.0’s design allows for the commoditization of blockspace. - -Blockspace is a blockchain's capacity to finalize and commit operations, encompassing its security, computing, and storage capabilities. Its characteristics can vary across different blockchains, affecting security, flexibility, and availability. - -- **Security**: Measures the robustness of blockspace in Proof of Stake (PoS) networks linked to the stake locked on validator nodes, the variance in stake among validators, and the total number of validators. It also considers social centralization (how many validators are owned by single operators) and physical centralization (how many validators run on the same service provider). - -- **Flexibility**: Reflects the functionalities and types of data that can be stored, with high-quality data essential to avoid bottlenecks in critical processes. - -- **Availability**: Indicates how easily users can access blockspace. It should be easily accessible, allowing diverse business models to thrive, ideally regulated by a marketplace based on demand and supplemented by options for "second-hand" blockspace. - -Polkadot is built on core blockspace principles, but there's room for improvement. Tasks like balance transfers, staking, and governance are managed on the relay chain. - -Delegating these responsibilities to [system chains](/polkadot-protocol/architecture/system-chains/){target=\_blank} could enhance flexibility and allow the relay chain to concentrate on providing shared security and interoperability. - -For more information about blockspace, watch [Robert Habermeier’s interview](https://www.youtube.com/watch?v=e1vISppPwe4){target=\_blank} or read his [technical blog post](https://www.rob.tech/blog/polkadot-blockspace-over-blockchains/){target=\_blank}. - -## DOT Token - -DOT is the native token of the Polkadot network, much like BTC for Bitcoin and Ether for the Ethereum blockchain. DOT has 10 decimals, uses the Planck base unit, and has a balance type of `u128`. The same is true for Kusama's KSM token with the exception of having 12 decimals. - -### Redenomination of DOT - -Polkadot conducted a community poll, which ended on 27 July 2020 at block 888,888, to decide whether to redenominate the DOT token. The stakeholders chose to redenominate the token, changing the value of 1 DOT from 1e12 plancks to 1e10 plancks. - -Importantly, this did not affect the network's total number of base units (plancks); it only affects how a single DOT is represented. The redenomination became effective 72 hours after transfers were enabled, occurring at block 1,248,328 on 21 August 2020 around 16:50 UTC. - -### The Planck Unit - -The smallest unit of account balance on Polkadot SDK-based blockchains (such as Polkadot and Kusama) is called _Planck_, named after the Planck length, the smallest measurable distance in the physical universe. - -Similar to how BTC's smallest unit is the Satoshi and ETH's is the Wei, Polkadot's native token DOT equals 1e10 Planck, while Kusama's native token KSM equals 1e12 Planck. - -### Uses for DOT - -DOT serves three primary functions within the Polkadot network: - -- **Governance**: It is used to participate in the governance of the network. -- **Staking**: DOT is staked to support the network's operation and security. -- **Buying coretime**: Used to purchase coretime in-bulk or on-demand and access the chain to benefit from Polkadot's security and interoperability. - -Additionally, DOT can serve as a transferable token. For example, DOT, held in the treasury, can be allocated to teams developing projects that benefit the Polkadot ecosystem. - -## JAM and the Road Ahead - -The Join-Accumulate Machine (JAM) represents a transformative redesign of Polkadot's core architecture, envisioned as the successor to the current relay chain. Unlike traditional blockchain architectures, JAM introduces a unique computational model that processes work through two primary functions: - -- **Join**: Handles data integration. -- **Accumulate**: Folds computations into the chain's state. - -JAM removes many of the opinions and constraints of the current relay chain while maintaining its core security properties. Expected improvements include: - -- **Permissionless code execution**: JAM is designed to be more generic and flexible, allowing for permissionless code execution through services that can be deployed without governance approval. -- **More effective block time utilization**: JAM's efficient pipeline processing model places the prior state root in block headers instead of the posterior state root, enabling more effective utilization of block time for computations. - -This architectural evolution promises to enhance Polkadot's scalability and flexibility while maintaining robust security guarantees. JAM is planned to be rolled out to Polkadot as a single, complete upgrade rather than a stream of smaller updates. This approach seeks to minimize the developer overhead required to address any breaking changes. - - ---- - -Page Title: Parachains Overview - -- Source (raw): https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/reference-parachains.md -- Canonical (HTML): https://docs.polkadot.com/reference/parachains/ -- Summary: Learn about parachains, specialized blockchains on Polkadot that gain shared security and interoperability. Discover how they work and the tools to build them. - -# Parachains Overview - -## Introduction - -A parachain is a specialized blockchain that connects to the Polkadot relay chain, benefiting from shared security, interoperability, and scalability. Parachains are built using the [Polkadot SDK](https://github.com/paritytech/polkadot-sdk){target=\_blank}, a powerful toolkit written in Rust that provides everything needed to create custom blockchain logic while integrating seamlessly with the Polkadot network. - -Unlike standalone blockchains that must bootstrap their own validator sets and security, parachains leverage Polkadot's pooled security model. This allows parachain developers to focus on their application-specific functionality rather than consensus and security infrastructure. Parachains can communicate with each other through Cross-Consensus Messaging (XCM), enabling seamless interoperability across the Polkadot ecosystem. - -Key capabilities that parachains provide include: - -- **Shared security**: Inherit security from Polkadot's validator set without maintaining your own. -- **Interoperability**: Communicate trustlessly with other parachains via XCM. -- **Scalability**: Process transactions in parallel with other parachains. -- **Customization**: Build application-specific logic tailored to your use case. -- **Upgradeability**: Upgrade runtime logic without hard forks. - -## Polkadot SDK: Parachain Architecture - -Building a parachain involves understanding and utilizing several key components of the Polkadot SDK: - -![](/images/reference/parachains/index/overview-01.webp) - -- **[Substrate](https://paritytech.github.io/polkadot-sdk/master/polkadot_sdk_docs/polkadot_sdk/substrate/index.html){target=\_blank}**: The foundation providing core blockchain primitives and libraries. -- **[FRAME](https://paritytech.github.io/polkadot-sdk/master/polkadot_sdk_docs/polkadot_sdk/frame_runtime/index.html){target=\_blank}**: A modular framework for building your parachain's runtime logic. -- **[Cumulus](https://paritytech.github.io/polkadot-sdk/master/polkadot_sdk_docs/polkadot_sdk/cumulus/index.html){target=\_blank}**: Essential libraries and pallets that enable parachain functionality. -- **[XCM (Cross Consensus Messaging)](https://paritytech.github.io/polkadot-sdk/master/polkadot_sdk_docs/polkadot_sdk/xcm/index.html){target=\_blank}**: The messaging format for communicating with other parachains and the relay chain. -- **[Polkadot](https://paritytech.github.io/polkadot-sdk/master/polkadot_sdk_docs/polkadot_sdk/polkadot/index.html){target=\_blank}**: The relay chain that provides security and coordination. - -### Substrate: The Foundation - -Substrate provides the core infrastructure that every parachain is built upon. It handles the low-level blockchain functionality, allowing you to focus on your application's unique features. Substrate includes implementations for networking, database management, consensus participation, and the execution environment for your runtime. - -Every Polkadot SDK node consists of two main components: - -- **Client (Host)**: Handles infrastructure services. +Page Title: Pause Validating - - Native binary that runs on validator and collator nodes. - - Executes the Wasm-compiled runtime. - - Manages networking, database, mempool, and block production. - - Interfaces with the relay chain for validation. - -- **Runtime (State Transition Function)**: Contains your business logic. - - - Defines how your Polkadot SDK node processes transactions. - - Compiled to [Wasm](https://webassembly.org/){target=\_blank} for deterministic execution. - - Stored on-chain and upgradeable via governance. - -```mermaid -%%{init: {'flowchart': {'padding': 5, 'nodeSpacing': 50, 'rankSpacing': 10}}}%% -graph TB - classDef title font-size:20px,font-weight:bold,stroke-width:0px - classDef clientStyle font-size:16px,font-weight:bold - classDef clientSubNodeStyle margin-top:10px - classDef runtimeCallExecutorStyle padding-top:10px - - subgraph sg1[Parachain
Node] - direction TB - - I[RuntimeCall Executor] - B[Wasm Runtime - STF] - - subgraph sg2[Client] - direction TB - C[Network and Blockchain
Infrastructure Services
+ Relay Chain Interface] - end - - I --> B - end - - class sg1 title - class sg2 clientStyle - class C clientSubNodeStyle - class I runtimeCallExecutorStyle - -``` - -### FRAME: Building Blocks for Your Runtime - -FRAME provides modular components called [pallets](/reference/glossary#pallet){target=\_blank} that you can compose to build your parachain's runtime. Each pallet provides specific functionality that you can customize and configure for your needs. This modular approach allows you to quickly assemble complex functionality without writing everything from scratch. - -```mermaid -graph LR - subgraph SP["Parachain Runtime"] - direction LR - Timestamp ~~~ Aura ~~~ ParachainSystem - Balances ~~~ TransactionPayment ~~~ Sudo - subgraph Timestamp["Timestamp"] - SS1[Custom Config] - end - subgraph Aura["Aura"] - SS2[Custom Config] - end - subgraph ParachainSystem["Parachain System"] - SS3[Custom Config] - end - subgraph Balances["Balances"] - SS4[Custom Config] - end - subgraph TransactionPayment["Transaction Payment"] - SS5[Custom Config] - end - subgraph Sudo["Sudo"] - SS6[Custom Config] - end - style Timestamp stroke:#FF69B4 - style Aura stroke:#FF69B4 - style ParachainSystem stroke:#FF69B4 - style Balances stroke:#FF69B4 - style TransactionPayment stroke:#FF69B4 - style Sudo stroke:#FF69B4 - style SS1 stroke-dasharray: 5 - style SS2 stroke-dasharray: 5 - style SS3 stroke-dasharray: 5 - style SS4 stroke-dasharray: 5 - style SS5 stroke-dasharray: 5 - style SS6 stroke-dasharray: 5 - - end - subgraph AP["Available FRAME Pallets"] - direction LR - A1[Aura]~~~A2[Parachain
System]~~~A3[Transaction
Payment]~~~A4[Sudo] - B1[Identity]~~~B2[Balances]~~~B3[Assets]~~~B4[EVM] - C1[Timestamp]~~~C2[Staking]~~~C3[Contracts]~~~C4[and more...] - end - AP --> SP -``` - -### Cumulus: Parachain-Specific Functionality - -Cumulus is what transforms a Polkadot SDK-based runtime into a parachain-capable runtime. It provides the essential components for communicating with the relay chain, participating in Polkadot's consensus, and handling parachain-specific operations like block validation and collation. - -Key Cumulus components include: - -- **Parachain system pallet**: Core parachain functionality and relay chain communication. -- **Collator consensus**: Block production logic for parachain collators. -- **Relay chain interface**: APIs for interacting with the Polkadot relay chain. -- **Validation data**: Handling proof-of-validity data required by relay chain validators. - -## Where to Go Next - -Building a parachain requires understanding the relationship between your chain and the Polkadot relay chain. The Polkadot SDK provides all the tools needed to design custom runtime logic, enable cross-chain communication, and deploy your parachain to production. - -The following sections provide detailed guidance on each aspect of parachain development, from initial design through deployment and ongoing maintenance. - -
- -- Guide __Launch a Simple Parachain__ - - --- - - Walk through the complete parachain launch flow: from setup and deployment to obtaining coretime. - - [:octicons-arrow-right-24: Deploy](/parachains/launch-a-parachain/set-up-the-parachain-template/) - - -- Guide __Customize Your Runtime__ - - --- - - Design your parachain's runtime logic and choose appropriate pallets for your use case. - - [:octicons-arrow-right-24: Get Started](/parachains/customize-runtime/) - -- Guide __Interoperability__ - - --- - - Implement XCM for trustless cross-chain communication with other parachains. - - [:octicons-arrow-right-24: Learn More](/parachains/interoperability/get-started/) - -- Guide __Runtime Upgrades__ - - --- - - Upgrade your parachain's runtime without hard forks using forkless upgrade mechanisms. - - [:octicons-arrow-right-24: Maintain](/parachains/runtime-maintenance/runtime-upgrades/) - -
- - ---- - -Page Title: Pause Validating - -- Source (raw): https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/nodes-and-validators-run-a-validator-operational-tasks-pause-validating.md -- Canonical (HTML): https://docs.polkadot.com/nodes-and-validators/run-a-validator/operational-tasks/pause-validating/ -- Summary: Learn how to temporarily pause staking activity in Polkadot using the chill extrinsic, with guidance for validators and nominators. +- Source (raw): https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/nodes-and-validators-run-a-validator-operational-tasks-pause-validating.md +- Canonical (HTML): https://docs.polkadot.com/nodes-and-validators/run-a-validator/operational-tasks/pause-validating/ +- Summary: Learn how to temporarily pause staking activity in Polkadot using the chill extrinsic, with guidance for validators and nominators. # Pause Validating -## Introduction - -If you need to temporarily stop participating in Polkadot staking activities without fully unbonding your funds, chilling your account allows you to do so efficiently. Chilling removes your node from active validation or nomination in the next era while keeping your funds bonded, making it ideal for planned downtimes or temporary pauses. - -This guide covers the steps for chilling as a validator or nominator, using the `chill` and `chillOther` extrinsics, and how these affect your staking status and nominations. - -## Chilling Your Node - -If you need to temporarily step back from staking without unbonding your funds, you can "chill" your account. Chilling pauses your active staking participation, setting your account to inactive in the next era while keeping your funds bonded. - -To chill your account, go to the **Network > Staking > Account Actions** page on [Polkadot.js Apps](https://polkadot.js.org/apps){target=\_blank}, and select **Stop**. Alternatively, you can call the [`chill`](https://paritytech.github.io/polkadot-sdk/master/pallet_staking/enum.Call.html#variant.chill){target=\_blank} extrinsic in the Staking pallet. - -## Staking Election Timing Considerations - -When a node actively participates in staking but then chills, it will continue contributing for the remainder of the current era. However, its eligibility for the next election depends on the chill status at the start of the new era: - -- **Chilled during previous era**: Will not participate in the current era election and will remain inactive until reactivated. -- **Chilled during current era**: Will not be selected for the next era's election. -- **Chilled after current era**: May be selected if it was active during the previous era and is now chilled. - -## Chilling as a Nominator - -When you choose to chill as a nominator, your active nominations are reset. Upon re-entering the nominating process, you must reselect validators to support manually. Depending on preferences, these can be the same validators as before or a new set. Remember that your previous nominations won’t be saved or automatically reactivated after chilling. - -While chilled, your nominator account remains bonded, preserving your staked funds without requiring a full unbonding process. When you’re ready to start nominating again, you can issue a new nomination call to activate your bond with a fresh set of validators. This process bypasses the need for re-bonding, allowing you to maintain your stake while adjusting your involvement in active staking. - -## Chilling as a Validator - -When you chill as a validator, your active validator status is paused. Although your nominators remain bonded to you, the validator bond will no longer appear as an active choice for new or revised nominations until reactivated. Any existing nominators who take no action will still have their stake linked to the validator, meaning they don’t need to reselect the validator upon reactivation. However, if nominators adjust their stakes while the validator is chilled, they will not be able to nominate the chilled validator until it resumes activity. - -Upon reactivating as a validator, you must also reconfigure your validator preferences, such as commission rate and other parameters. These can be set to match your previous configuration or updated as desired. This step is essential for rejoining the active validator set and regaining eligibility for nominations. - -## Chill Other - -Historical constraints in the runtime prevented unlimited nominators and validators from being supported. These constraints created a need for checks to keep the size of the staking system manageable. One of these checks is the `chillOther` extrinsic, allowing users to chill accounts that no longer met standards such as minimum staking requirements set through on-chain governance. - -This control mechanism included a `ChillThreshold`, which was structured to define how close to the maximum number of nominators or validators the staking system would be allowed to get before users could start chilling one another. With the passage of [Referendum #90](https://polkadot-old.polkassembly.io/referendum/90){target=\_blank}, the value for `maxNominatorCount` on Polkadot was set to `None`, effectively removing the limit on how many nominators and validators can participate. This means the `ChillThreshold` will never be met; thus, `chillOther` no longer has any effect. - - ---- - -Page Title: Polkadot SDK Accounts - -- Source (raw): https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/reference-parachains-accounts.md -- Canonical (HTML): https://docs.polkadot.com/reference/parachains/accounts/ -- Summary: Learn about account structures, balances, and address formats in the Polkadot SDK, including how to manage lifecycle, references, and balances. - -# Accounts - -## Introduction - -Accounts are essential for managing identity, transactions, and governance on the network in the Polkadot SDK. Understanding these components is critical for seamless development and operation on the network, whether you're building or interacting with Polkadot-based chains. - -This page will guide you through the essential aspects of accounts, including their data structure, balance types, reference counters, and address formats. You’ll learn how accounts are managed within the runtime, how balances are categorized, and how addresses are encoded and validated. - -## Account Data Structure - -Accounts are foundational to any blockchain, and the Polkadot SDK provides a flexible management system. This section explains how the Polkadot SDK defines accounts and manages their lifecycle through data structures within the runtime. - -### Account - -The [`Account` data type](https://paritytech.github.io/polkadot-sdk/master/frame_system/pallet/type.Account.html){target=\_blank} is a storage map within the [System pallet](https://paritytech.github.io/polkadot-sdk/master/src/frame_system/lib.rs.html){target=\_blank} that links an account ID to its corresponding data. This structure is fundamental for mapping account-related information within the chain. - -The code snippet below shows how accounts are defined: - -```rs - /// The full account information for a particular account ID. - #[pallet::storage] - #[pallet::getter(fn account)] - pub type Account = StorageMap< - _, - Blake2_128Concat, - T::AccountId, - AccountInfo, - ValueQuery, - >; -``` - -The preceding code block defines a storage map named `Account`. The `StorageMap` is a type of on-chain storage that maps keys to values. In the `Account` map, the key is an account ID, and the value is the account's information. Here, `T` represents the generic parameter for the runtime configuration, which is defined by the pallet's configuration trait (`Config`). - -The `StorageMap` consists of the following parameters: - -- **`_`**: Used in macro expansion and acts as a placeholder for the storage prefix type. Tells the macro to insert the default prefix during expansion. -- **`Blake2_128Concat`**: The hashing function applied to keys in the storage map. -- **`T: :AccountId`**: Represents the key type, which corresponds to the account’s unique ID. -- **`AccountInfo`**: The value type stored in the map. For each account ID, the map stores an `AccountInfo` struct containing: - - - **`T::Nonce`**: A nonce for the account, which is incremented with each transaction to ensure transaction uniqueness. - - **`T: :AccountData`**: Custom account data defined by the runtime configuration, which could include balances, locked funds, or other relevant information. - -- **`ValueQuery`**: Defines how queries to the storage map behave when no value is found; returns a default value instead of `None`. - -For a detailed explanation of storage maps, see the [`StorageMap`](https://paritytech.github.io/polkadot-sdk/master/frame_support/storage/types/struct.StorageMap.html){target=\_blank} entry in the Rust docs. - -### Account Info - -The `AccountInfo` structure is another key element within the [System pallet](https://paritytech.github.io/polkadot-sdk/master/src/frame_system/lib.rs.html){target=\_blank}, providing more granular details about each account's state. This structure tracks vital data, such as the number of transactions and the account’s relationships with other modules. - -```rs -/// Information of an account. -#[derive(Clone, Eq, PartialEq, Default, RuntimeDebug, Encode, Decode, TypeInfo, MaxEncodedLen)] -pub struct AccountInfo { - /// The number of transactions this account has sent. - pub nonce: Nonce, - /// The number of other modules that currently depend on this account's existence. The account - /// cannot be reaped until this is zero. - pub consumers: RefCount, - /// The number of other modules that allow this account to exist. The account may not be reaped - /// until this and `sufficients` are both zero. - pub providers: RefCount, - /// The number of modules that allow this account to exist for their own purposes only. The - /// account may not be reaped until this and `providers` are both zero. - pub sufficients: RefCount, - /// The additional data that belongs to this account. Used to store the balance(s) in a lot of - /// chains. - pub data: AccountData, -} -``` - -The `AccountInfo` structure includes the following components: - -- **`nonce`**: Tracks the number of transactions initiated by the account, which ensures transaction uniqueness and prevents replay attacks. -- **`consumers`**: Counts how many other modules or pallets rely on this account’s existence. The account cannot be removed from the chain (reaped) until this count reaches zero. -- **`providers`**: Tracks how many modules permit this account’s existence. An account can only be reaped once both `providers` and `sufficients` are zero. -- **`sufficients`**: Represents the number of modules that allow the account to exist for internal purposes, independent of any other modules. -- **`AccountData`**: A flexible data structure that can be customized in the runtime configuration, usually containing balances or other user-specific data. - -This structure helps manage an account's state and prevents its premature removal while it is still referenced by other on-chain data or modules. The [`AccountInfo`](https://paritytech.github.io/polkadot-sdk/master/frame_system/struct.AccountInfo.html){target=\_blank} structure can vary as long as it satisfies the trait bounds defined by the `AccountData` associated type in the [`frame-system::pallet::Config`](https://paritytech.github.io/polkadot-sdk/master/frame_system/pallet/trait.Config.html){target=\_blank} trait. - -### Account Reference Counters - -Polkadot SDK uses reference counters to track an account’s dependencies across different runtime modules. These counters ensure that accounts remain active while data is associated with them. - -The reference counters include: - -- **`consumers`**: Prevents account removal while other pallets still rely on the account. -- **`providers`**: Ensures an account is active before other pallets store data related to it. -- **`sufficients`**: Indicates the account’s independence, ensuring it can exist even without a native token balance, such as when holding sufficient alternative assets. - -#### Providers Reference Counters - -The `providers` counter ensures that an account is ready to be depended upon by other runtime modules. For example, it is incremented when an account has a balance above the existential deposit, which marks the account as active. - -The system requires this reference counter to be greater than zero for the `consumers` counter to be incremented, ensuring the account is stable before any dependencies are added. - -#### Consumers Reference Counters - -The `consumers` counter ensures that the account cannot be reaped until all references to it across the runtime have been removed. This check prevents the accidental deletion of accounts that still have active on-chain data. - -It is the user’s responsibility to clear out any data from other runtime modules if they wish to remove their account and reclaim their existential deposit. - -#### Sufficients Reference Counter - -The `sufficients` counter tracks accounts that can exist independently without relying on a native account balance. This is useful for accounts holding other types of assets, like tokens, without needing a minimum balance in the native token. - -For instance, the [Assets pallet](https://paritytech.github.io/polkadot-sdk/master/pallet_assets/index.html){target=\_blank}, may increment this counter for an account holding sufficient tokens. - -#### Account Deactivation - -In Polkadot SDK-based chains, an account is deactivated when its reference counters (such as `providers`, `consumers`, and `sufficient`) reach zero. These counters ensure the account remains active as long as other runtime modules or pallets reference it. - -When all dependencies are cleared and the counters drop to zero, the account becomes deactivated and may be removed from the chain (reaped). This is particularly important in Polkadot SDK-based blockchains, where accounts with balances below the existential deposit threshold are pruned from storage to conserve state resources. - -Each pallet that references an account has cleanup functions that decrement these counters when the pallet no longer depends on the account. Once these counters reach zero, the account is marked for deactivation. - -#### Updating Counters - -The Polkadot SDK provides runtime developers with various methods to manage account lifecycle events, such as deactivation or incrementing reference counters. These methods ensure that accounts cannot be reaped while still in use. - -The following helper functions manage these counters: - -- **`inc_consumers()`**: Increments the `consumer` reference counter for an account, signaling that another pallet depends on it. -- **`dec_consumers()`**: Decrements the `consumer` reference counter, signaling that a pallet no longer relies on the account. -- **`inc_providers()`**: Increments the `provider` reference counter, ensuring the account remains active. -- **`dec_providers()`**: Decrements the `provider` reference counter, allowing for account deactivation when no longer in use. -- **`inc_sufficients()`**: Increments the `sufficient` reference counter for accounts that hold sufficient assets. -- **`dec_sufficients()`**: Decrements the `sufficient` reference counter. - -To ensure proper account cleanup and lifecycle management, a corresponding decrement should be made for each increment action. - -The `System` pallet offers three query functions to assist developers in tracking account states: - -- **[`can_inc_consumer()`](https://paritytech.github.io/polkadot-sdk/master/frame_system/pallet/struct.Pallet.html#method.can_inc_consumer){target=\_blank}**: Checks if the account can safely increment the consumer reference. -- **[`can_dec_provider()`](https://paritytech.github.io/polkadot-sdk/master/frame_system/pallet/struct.Pallet.html#method.can_dec_provider){target=\_blank}**: Ensures that no consumers exist before allowing the decrement of the provider counter. -- **[`is_provider_required()`](https://paritytech.github.io/polkadot-sdk/master/frame_system/pallet/struct.Pallet.html#method.is_provider_required){target=\_blank}**: Verifies whether the account still has any active consumer references. - -This modular and flexible system of reference counters tightly controls the lifecycle of accounts in Polkadot SDK-based blockchains, preventing the accidental removal or retention of unneeded accounts. You can refer to the [System pallet Rust docs](https://paritytech.github.io/polkadot-sdk/master/frame_system/pallet/struct.Pallet.html){target=\_blank} for more details. - - -## Account Balance Types - -In the Polkadot ecosystem, account balances are categorized into different types based on how the funds are utilized and their availability. These balance types determine the actions that can be performed, such as transferring tokens, paying transaction fees, or participating in governance activities. Understanding these balance types helps developers manage user accounts and implement balance-dependent logic. - -!!! note "A more efficient distribution of account balance types is in development" - Soon, pallets in the Polkadot SDK will implement the [`Fungible` trait](https://paritytech.github.io/polkadot-sdk/master/frame_support/traits/tokens/fungible/index.html){target=\_blank} (see the [tracking issue](https://github.com/paritytech/polkadot-sdk/issues/226){target=\_blank} for more details). For example, the [`transaction-storage`](https://paritytech.github.io/polkadot-sdk/master/pallet_transaction_storage/index.html){target=\_blank} pallet changed the implementation of the [`Currency`](https://paritytech.github.io/polkadot-sdk/master/frame_support/traits/tokens/currency/index.html){target=\_blank} trait (see the [Refactor transaction storage pallet to use fungible traits](https://github.com/paritytech/polkadot-sdk/pull/1800){target=\_blank} PR for further details): - - ```rust - type BalanceOf = <::Currency as Currency<::AccountId>>::Balance; - ``` - - To the [`Fungible`](https://paritytech.github.io/polkadot-sdk/master/frame_support/traits/tokens/fungible/index.html){target=\_blank} trait: - - ```rust - type BalanceOf = <::Currency as FnInspect<::AccountId>>::Balance; - ``` - - This update will enable more efficient use of account balances, allowing the free balance to be utilized for on-chain activities such as setting proxies and managing identities. - -### Balance Types - -The five main balance types are: - -- **Free balance**: Represents the total tokens available to the account for any on-chain activity, including staking, governance, and voting. However, it may not be fully spendable or transferrable if portions of it are locked or reserved. -- **Locked balance**: Portions of the free balance that cannot be spent or transferred because they are tied up in specific activities like [staking](https://wiki.polkadot.com/learn/learn-staking/#nominating-validators){target=\_blank}, [vesting](https://wiki.polkadot.com/learn/learn-guides-transfers/#vested-transfers-with-the-polkadot-js-ui){target=\_blank}, or participating in [governance](https://wiki.polkadot.com/learn/learn-polkadot-opengov/#voting-on-a-referendum){target=\_blank}. While the tokens remain part of the free balance, they are non-transferable for the duration of the lock. -- **Reserved balance**: Funds locked by specific system actions, such as setting up an [identity](https://wiki.polkadot.com/learn/learn-identity/){target=\_blank}, creating [proxies](https://wiki.polkadot.com/learn/learn-proxies/){target=\_blank}, or submitting [deposits for governance proposals](https://wiki.polkadot.com/learn/learn-guides-polkadot-opengov/#claiming-opengov-deposits){target=\_blank}. These tokens are not part of the free balance and cannot be spent unless they are unreserved. -- **Spendable balance**: The portion of the free balance that is available for immediate spending or transfers. It is calculated by subtracting the maximum of locked or reserved amounts from the free balance, ensuring that existential deposit limits are met. -- **Untouchable balance**: Funds that cannot be directly spent or transferred but may still be utilized for on-chain activities, such as governance participation or staking. These tokens are typically tied to certain actions or locked for a specific period. - -The spendable balance is calculated as follows: - -```text -spendable = free - max(locked - reserved, ED) -``` - -Here, `free`, `locked`, and `reserved` are defined above. The `ED` represents the [existential deposit](https://wiki.polkadot.com/learn/learn-accounts/#existential-deposit-and-reaping){target=\_blank}, the minimum balance required to keep an account active and prevent it from being reaped. You may find you can't see all balance types when looking at your account via a wallet. Wallet providers often display only spendable, locked, and reserved balances. - -### Locks - -Locks are applied to an account's free balance, preventing that portion from being spent or transferred. Locks are automatically placed when an account participates in specific on-chain activities, such as staking or governance. Although multiple locks may be applied simultaneously, they do not stack. Instead, the largest lock determines the total amount of locked tokens. - -Locks follow these basic rules: - -- If different locks apply to varying amounts, the largest lock amount takes precedence. -- If multiple locks apply to the same amount, the lock with the longest duration governs when the balance can be unlocked. - -#### Locks Example - -Consider an example where an account has 80 DOT locked for both staking and governance purposes like so: - -- 80 DOT is staked with a 28-day lock period. -- 24 DOT is locked for governance with a 1x conviction and a 7-day lock period. -- 4 DOT is locked for governance with a 6x conviction and a 224-day lock period. - -In this case, the total locked amount is 80 DOT because only the largest lock (80 DOT from staking) governs the locked balance. These 80 DOT will be released at different times based on the lock durations. In this example, the 24 DOT locked for governance will be released first since the shortest lock period is seven days. The 80 DOT stake with a 28-day lock period is released next. Now, all that remains locked is the 4 DOT for governance. After 224 days, all 80 DOT (minus the existential deposit) will be free and transferable. - -![Illustration of Lock Example](/images/reference/parachains/accounts/accounts-01.webp) - -#### Edge Cases for Locks - -In scenarios where multiple convictions and lock periods are active, the lock duration and amount are determined by the longest period and largest amount. For example, if you delegate with different convictions and attempt to undelegate during an active lock period, the lock may be extended for the full amount of tokens. For a detailed discussion on edge case lock behavior, see this [Stack Exchange post](https://substrate.stackexchange.com/questions/5067/delegating-and-undelegating-during-the-lock-period-extends-it-for-the-initial-am){target=\_blank}. - -### Balance Types on Polkadot.js - -Polkadot.js provides a user-friendly interface for managing and visualizing various account balances on Polkadot and Kusama networks. When interacting with Polkadot.js, you will encounter multiple balance types that are critical for understanding how your funds are distributed and restricted. This section explains how different balances are displayed in the Polkadot.js UI and what each type represents. - -![](/images/reference/parachains/accounts/accounts-02.webp) - -The most common balance types displayed on Polkadot.js are: - -- **Total balance**: The total number of tokens available in the account. This includes all tokens, whether they are transferable, locked, reserved, or vested. However, the total balance does not always reflect what can be spent immediately. In this example, the total balance is 0.6274 KSM. - -- **Transferable balance**: Shows how many tokens are immediately available for transfer. It is calculated by subtracting the locked and reserved balances from the total balance. For example, if an account has a total balance of 0.6274 KSM and a transferable balance of 0.0106 KSM, only the latter amount can be sent or spent freely. - -- **Vested balance**: Tokens that allocated to the account but released according to a specific schedule. Vested tokens remain locked and cannot be transferred until fully vested. For example, an account with a vested balance of 0.2500 KSM means that this amount is owned but not yet transferable. - -- **Locked balance**: Tokens that are temporarily restricted from being transferred or spent. These locks typically result from participating in staking, governance, or vested transfers. In Polkadot.js, locked balances do not stack—only the largest lock is applied. For instance, if an account has 0.5500 KSM locked for governance and staking, the locked balance would display 0.5500 KSM, not the sum of all locked amounts. - -- **Reserved balance**: Refers to tokens locked for specific on-chain actions, such as setting an identity, creating a proxy, or making governance deposits. Reserved tokens are not part of the free balance, but can be freed by performing certain actions. For example, removing an identity would unreserve those funds. - -- **Bonded balance**: The tokens locked for staking purposes. Bonded tokens are not transferable until they are unbonded after the unbonding period. - -- **Redeemable balance**: The number of tokens that have completed the unbonding period and are ready to be unlocked and transferred again. For example, if an account has a redeemable balance of 0.1000 KSM, those tokens are now available for spending. - -- **Democracy balance**: Reflects the number of tokens locked for governance activities, such as voting on referenda. These tokens are locked for the duration of the governance action and are only released after the lock period ends. - -By understanding these balance types and their implications, developers and users can better manage their funds and engage with on-chain activities more effectively. - -## Address Formats - -The SS58 address format is a core component of the Polkadot SDK that enables accounts to be uniquely identified across Polkadot-based networks. This format is a modified version of Bitcoin's Base58Check encoding, specifically designed to accommodate the multi-chain nature of the Polkadot ecosystem. SS58 encoding allows each chain to define its own set of addresses while maintaining compatibility and checksum validation for security. - -### Basic Format - -SS58 addresses consist of three main components: - -```text -base58encode(concat(,
, )) -``` - -- **Address type**: A byte or set of bytes that define the network (or chain) for which the address is intended. This ensures that addresses are unique across different Polkadot SDK-based chains. -- **Address**: The public key of the account encoded as bytes. -- **Checksum**: A hash-based checksum which ensures that addresses are valid and unaltered. The checksum is derived from the concatenated address type and address components, ensuring integrity. - -The encoding process transforms the concatenated components into a Base58 string, providing a compact and human-readable format that avoids easily confused characters (e.g., zero '0', capital 'O', lowercase 'l'). This encoding function ([`encode`](https://docs.rs/bs58/latest/bs58/fn.encode.html){target=\_blank}) is implemented exactly as defined in Bitcoin and IPFS specifications, using the same alphabet as both implementations. - -For more details about the SS58 address format implementation, see the [`Ss58Codec`](https://paritytech.github.io/polkadot-sdk/master/sp_core/crypto/trait.Ss58Codec.html){target=\_blank} trait in the Rust Docs. - -### Address Type - -The address type defines how an address is interpreted and to which network it belongs. Polkadot SDK uses different prefixes to distinguish between various chains and address formats: - -- **Address types `0-63`**: Simple addresses, commonly used for network identifiers. -- **Address types `64-127`**: Full addresses that support a wider range of network identifiers. -- **Address types `128-255`**: Reserved for future address format extensions. - -For example, Polkadot’s main network uses an address type of 0, while Kusama uses 2. This ensures that addresses can be used without confusion between networks. - -The address type is always encoded as part of the SS58 address, making it easy to quickly identify the network. Refer to the [SS58 registry](https://github.com/paritytech/ss58-registry){target=\_blank} for the canonical listing of all address type identifiers and how they map to Polkadot SDK-based networks. - -### Address Length - -SS58 addresses can have different lengths depending on the specific format. Address lengths range from as short as 3 to 35 bytes, depending on the complexity of the address and network requirements. This flexibility allows SS58 addresses to adapt to different chains while providing a secure encoding mechanism. - -| Total | Type | Raw account | Checksum | -|-------|------|-------------|----------| -| 3 | 1 | 1 | 1 | -| 4 | 1 | 2 | 1 | -| 5 | 1 | 2 | 2 | -| 6 | 1 | 4 | 1 | -| 7 | 1 | 4 | 2 | -| 8 | 1 | 4 | 3 | -| 9 | 1 | 4 | 4 | -| 10 | 1 | 8 | 1 | -| 11 | 1 | 8 | 2 | -| 12 | 1 | 8 | 3 | -| 13 | 1 | 8 | 4 | -| 14 | 1 | 8 | 5 | -| 15 | 1 | 8 | 6 | -| 16 | 1 | 8 | 7 | -| 17 | 1 | 8 | 8 | -| 35 | 1 | 32 | 2 | - -SS58 addresses also support different payload sizes, allowing a flexible range of account identifiers. - -### Checksum Types - -A checksum is applied to validate SS58 addresses. Polkadot SDK uses a Blake2b-512 hash function to calculate the checksum, which is appended to the address before encoding. The checksum length can vary depending on the address format (e.g., 1-byte, 2-byte, or longer), providing varying levels of validation strength. - -The checksum ensures that an address is not modified or corrupted, adding an extra layer of security for account management. - -### Validating Addresses - -SS58 addresses can be validated using the subkey command-line interface or the Polkadot.js API. These tools help ensure an address is correctly formatted and valid for the intended network. The following sections will provide an overview of how validation works with these tools. - -#### Using Subkey - -[Subkey](https://paritytech.github.io/polkadot-sdk/master/subkey/index.html){target=\_blank} is a CLI tool provided by Polkadot SDK for generating and managing keys. It can inspect and validate SS58 addresses. - -The `inspect` command gets a public key and an SS58 address from the provided secret URI. The basic syntax for the `subkey inspect` command is: - -```bash -subkey inspect [flags] [options] uri -``` - -For the `uri` command-line argument, you can specify the secret seed phrase, a hex-encoded private key, or an SS58 address. If the input is a valid address, the `subkey` program displays the corresponding hex-encoded public key, account identifier, and SS58 addresses. - -For example, to inspect the public keys derived from a secret seed phrase, you can run a command similar to the following: - -```bash -subkey inspect "caution juice atom organ advance problem want pledge someone senior holiday very" -``` - -The command displays output similar to the following: - -
- subkey inspect "caution juice atom organ advance problem want pledge someone senior holiday very" - Secret phrase `caution juice atom organ advance problem want pledge someone senior holiday very` is account: - Secret seed: 0xc8fa03532fb22ee1f7f6908b9c02b4e72483f0dbd66e4cd456b8f34c6230b849 - Public key (hex): 0xd6a3105d6768e956e9e5d41050ac29843f98561410d3a47f9dd5b3b227ab8746 - Public key (SS58): 5Gv8YYFu8H1btvmrJy9FjjAWfb99wrhV3uhPFoNEr918utyR - Account ID: 0xd6a3105d6768e956e9e5d41050ac29843f98561410d3a47f9dd5b3b227ab8746 - SS58 Address: 5Gv8YYFu8H1btvmrJy9FjjAWfb99wrhV3uhPFoNEr918utyR -
- -The `subkey` program assumes an address is based on a public/private key pair. If you inspect an address, the command returns the 32-byte account identifier. - -However, not all addresses in Polkadot SDK-based networks are based on keys. - -Depending on the command-line options you specify and the input you provided, the command output might also display the network for which the address has been encoded. For example: - -```bash -subkey inspect "12bzRJfh7arnnfPPUZHeJUaE62QLEwhK48QnH9LXeK2m1iZU" -``` - -The command displays output similar to the following: - -
- subkey inspect "12bzRJfh7arnnfPPUZHeJUaE62QLEwhK48QnH9LXeK2m1iZU" - Public Key URI `12bzRJfh7arnnfPPUZHeJUaE62QLEwhK48QnH9LXeK2m1iZU` is account: - Network ID/Version: polkadot - Public key (hex): 0x46ebddef8cd9bb167dc30878d7113b7e168e6f0646beffd77d69d39bad76b47a - Account ID: 0x46ebddef8cd9bb167dc30878d7113b7e168e6f0646beffd77d69d39bad76b47a - Public key (SS58): 12bzRJfh7arnnfPPUZHeJUaE62QLEwhK48QnH9LXeK2m1iZU - SS58 Address: 12bzRJfh7arnnfPPUZHeJUaE62QLEwhK48QnH9LXeK2m1iZU -
- -#### Using Polkadot.js API - -To verify an address in JavaScript or TypeScript projects, you can use the functions built into the [Polkadot.js API](https://polkadot.js.org/docs/){target=\_blank}. For example: - -```js -// Import Polkadot.js API dependencies -const { decodeAddress, encodeAddress } = require('@polkadot/keyring'); -const { hexToU8a, isHex } = require('@polkadot/util'); - -// Specify an address to test. -const address = 'INSERT_ADDRESS_TO_TEST'; - -// Check address -const isValidSubstrateAddress = () => { - try { - encodeAddress(isHex(address) ? hexToU8a(address) : decodeAddress(address)); - - return true; - } catch (error) { - return false; - } -}; - -// Query result -const isValid = isValidSubstrateAddress(); -console.log(isValid); - -``` - -If the function returns `true`, the specified address is a valid address. - -#### Other SS58 Implementations - -Support for encoding and decoding Polkadot SDK SS58 addresses has been implemented in several other languages and libraries. - -- **Crystal**: [`wyhaines/base58.cr`](https://github.com/wyhaines/base58.cr){target=\_blank} -- **Go**: [`itering/subscan-plugin`](https://github.com/itering/subscan-plugin){target=\_blank} -- **Python**: [`polkascan/py-scale-codec`](https://github.com/polkascan/py-scale-codec){target=\_blank} -- **TypeScript**: [`subsquid/squid-sdk`](https://github.com/subsquid/squid-sdk){target=\_blank} - - ---- - -Page Title: Randomness - -- Source (raw): https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/reference-parachains-randomness.md -- Canonical (HTML): https://docs.polkadot.com/reference/parachains/randomness/ -- Summary: Explore the importance of randomness in PoS blockchains, focusing on Polkadot’s VRF-based approach to ensure fairness and security in validator selection. - -# Randomness - -## Introduction - -Randomness is crucial in Proof of Stake (PoS) blockchains to ensure a fair and unpredictable distribution of validator duties. However, computers are inherently deterministic, meaning the same input always produces the same output. What we typically refer to as "random" numbers on a computer are actually pseudo-random. These numbers rely on an initial "seed," which can come from external sources like [atmospheric noise](https://www.random.org/randomness/){target=\_blank}, [heart rates](https://mdpi.altmetric.com/details/47574324){target=\_blank}, or even [lava lamps](https://en.wikipedia.org/wiki/Lavarand){target=\_blank}. While this may seem random, given the same "seed," the same sequence of numbers will always be generated. - -In a global blockchain network, relying on real-world entropy for randomness isn’t feasible because these inputs vary by time and location. If nodes use different inputs, blockchains can fork. Hence, real-world randomness isn't suitable for use as a seed in blockchain systems. - -Currently, two primary methods for generating randomness in blockchains are used: [`RANDAO`](#randao) and [`VRF`](#vrf) (Verifiable Random Function). Polkadot adopts the `VRF` approach for its randomness. - -## VRF - -A Verifiable Random Function (VRF) is a cryptographic function that generates a random number and proof that ensures the submitter produced the number. This proof allows anyone to verify the validity of the random number. - -Polkadot's VRF is similar to the one used in [**Ouroboros Praos**](https://eprint.iacr.org/2017/573.pdf){target=\_blank}, which secures randomness for block production in systems like [BABE](/reference/polkadot-hub/consensus-and-security/pos-consensus/#block-production-babe){target=\_blank} (Polkadot’s block production mechanism). - -The key difference is that Polkadot's VRF doesn’t rely on a central clock—avoiding the issue of whose clock to trust. Instead, it uses its own past results and slot numbers to simulate time and determine future outcomes. - -### How VRF Works - -Slots on Polkadot are discrete units of time, each lasting six seconds, and can potentially hold a block. Multiple slots form an epoch, with 2400 slots making up one four-hour epoch. - -In each slot, validators execute a "die roll" using a VRF. The VRF uses three inputs: - -1. A "secret key," unique to each validator, is used for the die roll. -2. An epoch randomness value, derived from the hash of VRF outputs from blocks two epochs ago (N-2), so past randomness influences the current epoch (N). -3. The current slot number. - -This process helps maintain fair randomness across the network. - -Here is a graphical representation: - -![](/images/reference/parachains/randomness/randomness-01.webp) - -The VRF produces two outputs: a result (the random number) and a proof (verifying that the number was generated correctly). - -The result is checked by the validator against a protocol threshold. If it's below the threshold, the validator becomes a candidate for block production in that slot. - -The validator then attempts to create a block, submitting it along with the `PROOF` and `RESULT`. - -So, VRF can be expressed like: - -`(RESULT, PROOF) = VRF(SECRET, EPOCH_RANDOMNESS_VALUE, CURRENT_SLOT_NUMBER)` +## Introduction -Put simply, performing a "VRF roll" generates a random number along with proof that the number was genuinely produced and not arbitrarily chosen. +If you need to temporarily stop participating in Polkadot staking activities without fully unbonding your funds, chilling your account allows you to do so efficiently. Chilling removes your node from active validation or nomination in the next era while keeping your funds bonded, making it ideal for planned downtimes or temporary pauses. -After executing the VRF, the `RESULT` is compared to a protocol-defined `THRESHOLD`. If the `RESULT` is below the `THRESHOLD`, the validator becomes a valid candidate to propose a block for that slot. Otherwise, the validator skips the slot. +This guide covers the steps for chilling as a validator or nominator, using the `chill` and `chillOther` extrinsics, and how these affect your staking status and nominations. -As a result, there may be multiple validators eligible to propose a block for a slot. In this case, the block accepted by other nodes will prevail, provided it is on the chain with the latest finalized block as determined by the GRANDPA finality gadget. It's also possible for no block producers to be available for a slot, in which case the AURA consensus takes over. AURA is a fallback mechanism that randomly selects a validator to produce a block, running in parallel with BABE and only stepping in when no block producers exist for a slot. Otherwise, it remains inactive. +## Chilling Your Node -Because validators roll independently, no block candidates may appear in some slots if all roll numbers are above the threshold. +If you need to temporarily step back from staking without unbonding your funds, you can "chill" your account. Chilling pauses your active staking participation, setting your account to inactive in the next era while keeping your funds bonded. -To verify resolution of this issue and that Polkadot block times remain near constant-time, see the [PoS Consensus](/reference/polkadot-hub/consensus-and-security/pos-consensus/){target=\_blank} page of this documentation. +To chill your account, go to the **Network > Staking > Account Actions** page on [Polkadot.js Apps](https://polkadot.js.org/apps){target=\_blank}, and select **Stop**. Alternatively, you can call the [`chill`](https://paritytech.github.io/polkadot-sdk/master/pallet_staking/enum.Call.html#variant.chill){target=\_blank} extrinsic in the Staking pallet. -## RANDAO +## Staking Election Timing Considerations -An alternative on-chain randomness method is Ethereum's RANDAO, where validators perform thousands of hashes on a seed and publish the final hash during a round. The collective input from all validators forms the random number, and as long as one honest validator participates, the randomness is secure. +When a node actively participates in staking but then chills, it will continue contributing for the remainder of the current era. However, its eligibility for the next election depends on the chill status at the start of the new era: -To enhance security, RANDAO can optionally be combined with a Verifiable Delay Function (VDF), ensuring that randomness can't be predicted or manipulated during computation. +- **Chilled during previous era**: Will not participate in the current era election and will remain inactive until reactivated. +- **Chilled during current era**: Will not be selected for the next era's election. +- **Chilled after current era**: May be selected if it was active during the previous era and is now chilled. -For more information about RANDAO, see the [Randomness - RANDAO](https://eth2book.info/capella/part2/building_blocks/randomness/){target=\_blank} section of the Upgrading Ethereum documentation. +## Chilling as a Nominator -## VDFs +When you choose to chill as a nominator, your active nominations are reset. Upon re-entering the nominating process, you must reselect validators to support manually. Depending on preferences, these can be the same validators as before or a new set. Remember that your previous nominations won’t be saved or automatically reactivated after chilling. -Verifiable Delay Functions (VDFs) are time-bound computations that, even on parallel computers, take a set amount of time to complete. +While chilled, your nominator account remains bonded, preserving your staked funds without requiring a full unbonding process. When you’re ready to start nominating again, you can issue a new nomination call to activate your bond with a fresh set of validators. This process bypasses the need for re-bonding, allowing you to maintain your stake while adjusting your involvement in active staking. -They produce a unique result that can be quickly verified publicly. When combined with RANDAO, feeding RANDAO's output into a VDF introduces a delay that nullifies an attacker's chance to influence the randomness. +## Chilling as a Validator -However, VDF likely requires specialized ASIC devices to run separately from standard nodes. +When you chill as a validator, your active validator status is paused. Although your nominators remain bonded to you, the validator bond will no longer appear as an active choice for new or revised nominations until reactivated. Any existing nominators who take no action will still have their stake linked to the validator, meaning they don’t need to reselect the validator upon reactivation. However, if nominators adjust their stakes while the validator is chilled, they will not be able to nominate the chilled validator until it resumes activity. -!!!warning - While only one is needed to secure the system, and they will be open-source and inexpensive, running VDF devices involves significant costs without direct incentives, adding friction for blockchain users. +Upon reactivating as a validator, you must also reconfigure your validator preferences, such as commission rate and other parameters. These can be set to match your previous configuration or updated as desired. This step is essential for rejoining the active validator set and regaining eligibility for nominations. -## Additional Resources +## Chill Other -For more information about the reasoning for choices made along with proofs, see Polkadot's research on blockchain randomness and sortition in the [Block production](https://research.web3.foundation/Polkadot/protocols/block-production){target=\_blank} entry of the Polkadot Wiki. +Historical constraints in the runtime prevented unlimited nominators and validators from being supported. These constraints created a need for checks to keep the size of the staking system manageable. One of these checks is the `chillOther` extrinsic, allowing users to chill accounts that no longer met standards such as minimum staking requirements set through on-chain governance. -For a discussion with Web3 Foundation researchers about when and under what conditions Polkadot's randomness can be utilized, see the [Discussion on Randomness used in Polkadot](https://github.com/use-ink/ink/issues/57){target=\_blank} issue on GitHub. +This control mechanism included a `ChillThreshold`, which was structured to define how close to the maximum number of nominators or validators the staking system would be allowed to get before users could start chilling one another. With the passage of [Referendum #90](https://polkadot-old.polkassembly.io/referendum/90){target=\_blank}, the value for `maxNominatorCount` on Polkadot was set to `None`, effectively removing the limit on how many nominators and validators can participate. This means the `ChillThreshold` will never be met; thus, `chillOther` no longer has any effect. --- @@ -6908,496 +5356,104 @@ PrivateUsers=true ProtectClock=true ProtectControlGroups=true ProtectHostname=true -ProtectKernelModules=true -ProtectKernelTunables=true -ProtectSystem=strict -RemoveIPC=true -RestrictAddressFamilies=AF_INET AF_INET6 AF_NETLINK AF_UNIX -RestrictNamespaces=false -RestrictSUIDSGID=true -SystemCallArchitectures=native -SystemCallFilter=@system-service -SystemCallFilter=landlock_add_rule landlock_create_ruleset landlock_restrict_self seccomp mount umount2 -SystemCallFilter=~@clock @module @reboot @swap @privileged -SystemCallFilter=pivot_root -UMask=0027 - -[Install] -WantedBy=multi-user.target -``` - -!!! warning "Restart delay and equivocation risk" - It is recommended that a node's restart be delayed with `RestartSec` in the case of a crash. It's possible that when a node crashes, consensus votes in GRANDPA aren't persisted to disk. In this case, there is potential to equivocate when immediately restarting. Delaying the restart will allow the network to progress past potentially conflicting votes. - -### Run the Service - -Activate the systemd service to start on system boot by running: - -```bash -systemctl enable polkadot-validator.service -``` - -To start the service manually, use: - -```bash -systemctl start polkadot-validator.service -``` - -Check the service's status to confirm it is running: - -```bash -systemctl status polkadot-validator.service -``` - -To view the logs in real-time, use [journalctl](https://www.freedesktop.org/software/systemd/man/latest/journalctl.html){target=\_blank} like so: - -```bash -journalctl -f -u polkadot-validator -``` - -With these steps, you can effectively manage and monitor your validator as a systemd service. - -Once your validator is active, it's officially part of Polkadot's security infrastructure. For questions or further support, you can reach out to the [Polkadot Validator chat](https://matrix.to/#/!NZrbtteFeqYKCUGQtr:matrix.parity.io?via=matrix.parity.io&via=matrix.org&via=web3.foundation){target=\_blank} for tips and troubleshooting. - - ---- - -Page Title: Stop Validating - -- Source (raw): https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/nodes-and-validators-run-a-validator-onboarding-and-offboarding-stop-validating.md -- Canonical (HTML): https://docs.polkadot.com/nodes-and-validators/run-a-validator/onboarding-and-offboarding/stop-validating/ -- Summary: Learn to safely stop validating on Polkadot, including chilling, unbonding tokens, and purging validator keys. - -# Stop Validating - -## Introduction - -If you're ready to stop validating on Polkadot, there are essential steps to ensure a smooth transition while protecting your funds and account integrity. Whether you're taking a break for maintenance or unbonding entirely, you'll need to chill your validator, purge session keys, and unbond your tokens. This guide explains how to use Polkadot's tools and extrinsics to safely withdraw from validation activities, safeguarding your account's future usability. - -## Pause Versus Stop - -If you wish to remain a validator or nominator (for example, stopping for planned downtime or server maintenance), submitting the `chill` extrinsic in the `staking` pallet should suffice. Additional steps are only needed to unbond funds or reap an account. - -The following are steps to ensure a smooth stop to validation: - -- Chill the validator. -- Purge validator session keys. -- Unbond your tokens. - -## Chill Validator - -When stepping back from validating, the first step is to chill your validator status. This action stops your validator from being considered for the next era without fully unbonding your tokens, which can be useful for temporary pauses like maintenance or planned downtime. - -Use the `staking.chill` extrinsic to initiate this. For more guidance on chilling your node, refer to the [Pause Validating](/nodes-and-validators/run-a-validator/operational-tasks/pause-validating/){target=\_blank} guide. You may also claim any pending staking rewards at this point. - -## Purge Validator Session Keys - -Purging validator session keys is a critical step in removing the association between your validator account and its session keys, which ensures that your account is fully disassociated from validator activities. The `session.purgeKeys` extrinsic removes the reference to your session keys from the stash or staking proxy account that originally set them. - -Here are a couple of important things to know about purging keys: - -- **Account used to purge keys**: Always use the same account to purge keys you originally used to set them, usually your stash or staking proxy account. Using a different account may leave an unremovable reference to the session keys on the original account, preventing its reaping. -- **Account reaping issue**: Failing to purge keys will prevent you from reaping (fully deleting) your stash account. If you attempt to transfer tokens without purging, you'll need to rebond, purge the session keys, unbond again, and wait through the unbonding period before any transfer. - -## Unbond Your Tokens - -After chilling your node and purging session keys, the final step is to unbond your staked tokens. This action removes them from staking and begins the unbonding period (usually 28 days for Polkadot and seven days for Kusama), after which the tokens will be transferable. - -To unbond tokens, go to **Network > Staking > Account Actions** on Polkadot.js Apps. Select your stash account, click on the dropdown menu, and choose **Unbond Funds**. Alternatively, you can use the `staking.unbond` extrinsic if you handle this via a staking proxy account. - -Once the unbonding period is complete, your tokens will be available for use in transactions or transfers outside of staking. - - ---- - -Page Title: Technical Reference Overview - -- Source (raw): https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/reference.md -- Canonical (HTML): https://docs.polkadot.com/reference/ -- Summary: Learn about Polkadot's technical architecture, governance framework, parachain ecosystem, and the tools you need to build and interact with the network. - -## Introduction - -The Technical Reference section provides comprehensive documentation of Polkadot's architecture, core concepts, and development tooling. Whether you're exploring how Polkadot's relay chain coordinates parachains, understanding governance mechanisms, or building applications on the network, this reference covers the technical foundations you need. - -Polkadot is a multi-chain network that enables diverse, interconnected blockchains to share security and communicate seamlessly. Understanding how these components interact from the [relay chain](/polkadot-protocol/glossary#relay-chain){target=\_blank} that validates [parachains](/polkadot-protocol/glossary#parachain){target=\_blank} to the [governance](/reference/glossary#governance){target=\_blank} mechanisms that evolve the protocol is essential for developers, validators, and network participants. - -This guide organizes technical documentation across five core areas: Polkadot Hub, Parachains, On-Chain Governance, Glossary, and Tools, each providing detailed information on different aspects of the Polkadot ecosystem. - -## Polkadot Hub - -[Polkadot Hub](/reference/polkadot-hub/){target=\_blank} is the entry point to Polkadot for all users and application developers. It provides access to essential Web3 services, including smart contracts, staking, governance, identity management, and cross-ecosystem interoperability—without requiring you to deploy or manage a parachain. - -The Hub encompasses a set of core functionality that enables developers and users to build and interact with applications on Polkadot. Key capabilities include: - -- **Smart contracts**: Deploy Ethereum-compatible smart contracts and build decentralized applications. -- **Assets and tokens**: Create, manage, and transfer fungible tokens and NFTs across the ecosystem. -- **Staking**: Participate in network security and earn rewards by staking DOT. -- **Governance**: Vote on proposals and participate in Polkadot's decentralized decision-making through OpenGov. -- **Identity services**: Register and manage on-chain identities, enabling access to governance roles and network opportunities. -- **Cross-chain interoperability**: Leverage XCM messaging to interact securely with other chains in the Polkadot ecosystem. -- **Collectives and DAOs**: Participate in governance collectives and decentralized autonomous organizations. - -## Parachains - -[Parachains](/reference/parachains/){target=\_blank} are specialized blockchains that connect to the Polkadot relay chain, inheriting its security while maintaining their own application-specific logic. The parachains documentation covers: - -- **Accounts**: Deep dive into account types, storage, and management on parachains. -- **Blocks, transactions and fees**: Understand block production, transaction inclusion, and fee mechanisms. -- **Consensus**: Learn how parachain blocks are validated and finalized through the relay chain's consensus. -- **Chain data**: Explore data structures, storage layouts, and state management. -- **Cryptography**: Study cryptographic primitives used in Polkadot SDK-based chains. -- **Data encoding**: Understand how data is encoded and decoded for blockchain compatibility. -- **Networks**: Learn about networking protocols and peer-to-peer communication. -- **Interoperability**: Discover [Cross-Consensus Messaging (XCM)](/parachains/interoperability/get-started/){target=\_blank}, the standard for cross-chain communication. -- **Randomness**: Understand how randomness is generated and used in Polkadot chains. -- **Node and runtime**: Learn about parachain nodes, runtime environments, and the [Polkadot SDK](https://github.com/paritytech/polkadot-sdk){target=\_blank}. - -## On-Chain Governance - -[On-Chain governance](/reference/governance/){target=\_blank} is the decentralized decision-making mechanism for the Polkadot network. It manages the evolution and modification of the network's runtime logic, enabling community oversight and approval for proposed changes. The governance documentation details: - -- **OpenGov framework**: Understand Polkadot's next-generation governance system with enhanced delegation, flexible tracks, and simultaneous referendums. -- **Origins and tracks**: Learn how governance proposals are categorized, prioritized, and executed based on their privilege level and complexity. -- **Voting and delegation**: Explore conviction voting, vote delegation, and how token holders participate in governance. -- **Governance evolution**: See how Polkadot's governance has evolved from Governance V1 to the current OpenGov system. - -## Glossary - -The [Glossary](/reference/glossary/){target=\_blank} provides quick-reference definitions for Polkadot-specific terminology. Essential terms include: - -- Blockchain concepts (blocks, transactions, state) -- Consensus mechanisms (validators, collators, finality) -- Polkadot-specific terms (relay chain, parachain, XCM, FRAME) -- Network components (nodes, runtimes, storage) -- Governance terminology (origins, tracks, referendums) - -## Tools - -The [Tools](/reference/tools/){target=\_blank} section documents essential development and interaction tools for the Polkadot ecosystem: - -- **Light clients**: Lightweight solutions for interacting with the network without running full nodes. -- **JavaScript/TypeScript tools**: Libraries like [Polkadot.js API](/reference/tools/polkadot-js-api/){target=\_blank} and [PAPI](/reference/tools/papi/){target=\_blank} for building applications. -- **Rust tools**: [Polkadart](/reference/tools/polkadart/){target=\_blank} and other Rust-based libraries for SDK development. -- **Python tools**: [py-substrate-interface](/reference/tools/py-substrate-interface/){target=\_blank} for Python developers. -- **Testing and development**: Tools like [Moonwall](/reference/tools/moonwall/){target=\_blank}, [Chopsticks](/reference/tools/chopsticks/){target=\_blank}, and [Omninode](/reference/tools/omninode/){target=\_blank} for smart contract and parachain testing. -- **Indexing and monitoring**: [Sidecar](/reference/tools/sidecar/){target=\_blank} for data indexing and [Dedot](/reference/tools/dedot/){target=\_blank} for substrate interaction. -- **Cross-chain tools**: [ParaSpell](/reference/tools/paraspell/){target=\_blank} for XCM integration and asset transfers. - -## Where to Go Next - -For detailed exploration of specific areas, proceed to any of the main sections: - -
- -- Learn **Polkadot Hub** - - --- - - Understand the relay chain's role in coordinating parachains, providing shared security, and enabling governance. - - [:octicons-arrow-right-24: Reference](/reference/polkadot-hub/) - -- Learn **Parachains** - - --- - - Deep dive into parachain architecture, consensus, data structures, and building application-specific blockchains. - - [:octicons-arrow-right-24: Reference](/reference/parachains/) - -- Learn **On-Chain Governance** - - --- - - Explore Polkadot's decentralized governance framework and how to participate in network decision-making. - - [:octicons-arrow-right-24: Reference](/reference/governance/) - -- Guide **Glossary** - - --- - - Quick reference for Polkadot-specific terminology and concepts used throughout the documentation. - - [:octicons-arrow-right-24: Reference](/reference/glossary/) - -- Guide **Tools** - - --- - - Discover development tools, libraries, and frameworks for building and interacting with Polkadot. - - [:octicons-arrow-right-24: Reference](/reference/tools/) - -
- - ---- - -Page Title: Transactions - -- Source (raw): https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/reference-parachains-blocks-transactions-fees-transactions.md -- Canonical (HTML): https://docs.polkadot.com/reference/parachains/blocks-transactions-fees/transactions/ -- Summary: Learn how to construct, submit, and validate transactions in the Polkadot SDK, covering signed, unsigned, and inherent types of transactions. - -# Transactions - -## Introduction - -Transactions are essential components of blockchain networks, enabling state changes and the execution of key operations. In the Polkadot SDK, transactions, often called extrinsics, come in multiple forms, including signed, unsigned, and inherent transactions. - -This guide walks you through the different transaction types and how they're formatted, validated, and processed within the Polkadot ecosystem. You'll also learn how to customize transaction formats and construct transactions for FRAME-based runtimes, ensuring a complete understanding of how transactions are built and executed in Polkadot SDK-based chains. - -## What Is a Transaction? - -In the Polkadot SDK, transactions represent operations that modify the chain's state, bundled into blocks for execution. The term extrinsic is often used to refer to any data that originates outside the runtime and is included in the chain. While other blockchain systems typically refer to these operations as "transactions," the Polkadot SDK adopts the broader term "extrinsic" to capture the wide variety of data types that can be added to a block. - -There are three primary types of transactions (extrinsics) in the Polkadot SDK: - -- **Signed transactions**: Signed by the submitting account, often carrying transaction fees. -- **Unsigned transactions**: Submitted without a signature, often requiring custom validation logic. -- **Inherent transactions**: Typically inserted directly into blocks by block authoring nodes, without gossiping between peers. - -Each type serves a distinct purpose, and understanding when and how to use each is key to efficiently working with the Polkadot SDK. - -### Signed Transactions - -Signed transactions require an account's signature and typically involve submitting a request to execute a runtime call. The signature serves as a form of cryptographic proof that the sender has authorized the action, using their private key. These transactions often involve a transaction fee to cover the cost of execution and incentivize block producers. - -Signed transactions are the most common type of transaction and are integral to user-driven actions, such as token transfers. For instance, when you transfer tokens from one account to another, the sending account must sign the transaction to authorize the operation. - -For example, the [`pallet_balances::Call::transfer_allow_death`](https://paritytech.github.io/polkadot-sdk/master/pallet_balances/pallet/struct.Pallet.html#method.transfer_allow_death){target=\_blank} extrinsic in the Balances pallet allows you to transfer tokens. Since your account initiates this transaction, your account key is used to sign it. You'll also be responsible for paying the associated transaction fee, with the option to include an additional tip to incentivize faster inclusion in the block. - -### Unsigned Transactions - -Unsigned transactions do not require a signature or account-specific data from the sender. Unlike signed transactions, they do not come with any form of economic deterrent, such as fees, which makes them susceptible to spam or replay attacks. Custom validation logic must be implemented to mitigate these risks and ensure these transactions are secure. - -Unsigned transactions typically involve scenarios where including a fee or signature is unnecessary or counterproductive. However, due to the absence of fees, they require careful validation to protect the network. For example, [`pallet_im_online::Call::heartbeat`](https://paritytech.github.io/polkadot-sdk/master/pallet_im_online/pallet/struct.Pallet.html#method.heartbeat){target=\_blank} extrinsic allows validators to send a heartbeat signal, indicating they are active. Since only validators can make this call, the logic embedded in the transaction ensures that the sender is a validator, making the need for a signature or fee redundant. - -Unsigned transactions are more resource-intensive than signed ones because custom validation is required, but they play a crucial role in certain operational scenarios, especially when regular user accounts aren't involved. - -### Inherent Transactions - -Inherent transactions are a specialized type of unsigned transaction that is used primarily for block authoring. Unlike signed or other unsigned transactions, inherent transactions are added directly by block producers and are not broadcasted to the network or stored in the transaction queue. They don't require signatures or the usual validation steps and are generally used to insert system-critical data directly into blocks. - -A key example of an inherent transaction is inserting a timestamp into each block. The [`pallet_timestamp::Call::now`](https://paritytech.github.io/polkadot-sdk/master/pallet_timestamp/pallet/struct.Pallet.html#method.now-1){target=\_blank} extrinsic allows block authors to include the current time in the block they are producing. Since the block producer adds this information, there is no need for transaction validation, like signature verification. The validation in this case is done indirectly by the validators, who check whether the timestamp is within an acceptable range before finalizing the block. - -Another example is the [`paras_inherent::Call::enter`](https://paritytech.github.io/polkadot-sdk/master/polkadot_runtime_parachains/paras_inherent/pallet/struct.Pallet.html#method.enter){target=\_blank} extrinsic, which enables parachain collator nodes to send validation data to the relay chain. This inherent transaction ensures that the necessary parachain data is included in each block without the overhead of gossiped transactions. - -Inherent transactions serve a critical role in block authoring by allowing important operational data to be added directly to the chain without needing the validation processes required for standard transactions. - -## Transaction Formats - -Understanding the structure of signed and unsigned transactions is crucial for developers building on Polkadot SDK-based chains. Whether you're optimizing transaction processing, customizing formats, or interacting with the transaction pool, knowing the format of extrinsics, Polkadot's term for transactions, is essential. - -### Types of Transaction Formats - -In Polkadot SDK-based chains, extrinsics can fall into three main categories: - -- **Unchecked extrinsics**: Typically used for signed transactions that require validation. They contain a signature and additional data, such as a nonce and information for fee calculation. Unchecked extrinsics are named as such because they require validation checks before being accepted into the transaction pool. -- **Checked extrinsics**: Typically used for inherent extrinsics (unsigned transactions); these don't require signature verification. Instead, they carry information such as where the extrinsic originates and any additional data required for the block authoring process. -- **Opaque extrinsics**: Used when the format of an extrinsic is not yet fully committed or finalized. They are still decodable, but their structure can be flexible depending on the context. - -### Signed Transaction Data Structure - -A signed transaction typically includes the following components: - -- **Signature**: Verifies the authenticity of the transaction sender. -- **Call**: The actual function or method call the transaction is requesting (for example, transferring funds). -- **Nonce**: Tracks the number of prior transactions sent from the account, helping to prevent replay attacks. -- **Tip**: An optional incentive to prioritize the transaction in block inclusion. -- **Additional data**: Includes details such as spec version, block hash, and genesis hash to ensure the transaction is valid within the correct runtime and chain context. - -Here's a simplified breakdown of how signed transactions are typically constructed in a Polkadot SDK runtime: - -``` code - + + -``` - -Each part of the signed transaction has a purpose, ensuring the transaction's authenticity and context within the blockchain. - -### Signed Extensions - -Polkadot SDK also provides the concept of [signed extensions](https://paritytech.github.io/polkadot-sdk/master/polkadot_sdk_docs/reference_docs/signed_extensions/index.html){target=\_blank}, which allow developers to extend extrinsics with additional data or validation logic before they are included in a block. The [`SignedExtension`](https://paritytech.github.io/try-runtime-cli/sp_runtime/traits/trait.SignedExtension.html){target=\_blank} set helps enforce custom rules or protections, such as ensuring the transaction's validity or calculating priority. - -The transaction queue regularly calls signed extensions to verify a transaction's validity before placing it in the ready queue. This safeguard ensures transactions won't fail in a block. Signed extensions are commonly used to enforce validation logic and protect the transaction pool from spam and replay attacks. - -In FRAME, a signed extension can hold any of the following types by default: - -- **[`AccountId`](https://paritytech.github.io/polkadot-sdk/master/polkadot_sdk_frame/runtime/types_common/type.AccountId.html){target=\_blank}**: To encode the sender's identity. -- **[`Call`](https://paritytech.github.io/polkadot-sdk/master/polkadot_sdk_frame/traits/trait.SignedExtension.html#associatedtype.Call){target=\_blank}**: To encode the pallet call to be dispatched. This data is used to calculate transaction fees. -- **[`AdditionalSigned`](https://paritytech.github.io/polkadot-sdk/master/polkadot_sdk_frame/traits/trait.SignedExtension.html#associatedtype.AdditionalSigned){target=\_blank}**: To handle any additional data to go into the signed payload allowing you to attach any custom logic prior to dispatching a transaction. -- **[`Pre`](https://paritytech.github.io/polkadot-sdk/master/polkadot_sdk_frame/traits/trait.SignedExtension.html#associatedtype.Pre){target=\_blank}**: To encode the information that can be passed from before a call is dispatched to after it gets dispatched. - -Signed extensions can enforce checks like: - -- **[`CheckSpecVersion`](https://paritytech.github.io/polkadot-sdk/master/src/frame_system/extensions/check_spec_version.rs.html){target=\_blank}**: Ensures the transaction is compatible with the runtime's current version. -- **[`CheckWeight`](https://paritytech.github.io/polkadot-sdk/master/frame_system/struct.CheckWeight.html){target=\_blank}**: Calculates the weight (or computational cost) of the transaction, ensuring the block doesn't exceed the maximum allowed weight. - -These extensions are critical in the transaction lifecycle, ensuring that only valid and prioritized transactions are processed. - -## Transaction Construction - -Building transactions in the Polkadot SDK involves constructing a payload that can be verified, signed, and submitted for inclusion in a block. Each runtime in the Polkadot SDK has its own rules for validating and executing transactions, but there are common patterns for constructing a signed transaction. - -### Construct a Signed Transaction - -A signed transaction in the Polkadot SDK includes various pieces of data to ensure security, prevent replay attacks, and prioritize processing. Here's an overview of how to construct one: - -1. **Construct the unsigned payload**: Gather the necessary information for the call, including: - - - **Pallet index**: Identifies the pallet where the runtime function resides. - - **Function index**: Specifies the particular function to call in the pallet. - - **Parameters**: Any additional arguments required by the function call. - -2. **Create a signing payload**: Once the unsigned payload is ready, additional data must be included: - - - **Transaction nonce**: Unique identifier to prevent replay attacks. - - **Era information**: Defines how long the transaction is valid before it's dropped from the pool. - - **Block hash**: Ensures the transaction doesn't execute on the wrong chain or fork. - -3. **Sign the payload**: Using the sender's private key, sign the payload to ensure that the transaction can only be executed by the account holder. -4. **Serialize the signed payload**: Once signed, the transaction must be serialized into a binary format, ensuring the data is compact and easy to transmit over the network. -5. **Submit the serialized transaction**: Finally, submit the serialized transaction to the network, where it will enter the transaction pool and wait for processing by an authoring node. - -The following is an example of how a signed transaction might look: - -``` rust -node_runtime::UncheckedExtrinsic::new_signed( - function.clone(), // some call - sp_runtime::AccountId32::from(sender.public()).into(), // some sending account - node_runtime::Signature::Sr25519(signature.clone()), // the account's signature - extra.clone(), // the signed extensions -) -``` - -### Transaction Encoding - -Before a transaction is sent to the network, it is serialized and encoded using a structured encoding process that ensures consistency and prevents tampering: - -- **`[1]`**: Compact encoded length in bytes of the entire transaction. -- **`[2]`**: A u8 containing 1 byte to indicate whether the transaction is signed or unsigned (1 bit) and the encoded transaction version ID (7 bits). -- **`[3]`**: If signed, this field contains an account ID, an SR25519 signature, and some extra data. -- **`[4]`**: Encoded call data, including pallet and function indices and any required arguments. - -This encoded format ensures consistency and efficiency in processing transactions across the network. By adhering to this format, applications can construct valid transactions and pass them to the network for execution. - -To learn more about how compact encoding works using SCALE, see the [SCALE Codec](https://github.com/paritytech/parity-scale-codec){target=\_blank} README on GitHub. - -### Customize Transaction Construction - -Although the basic steps for constructing transactions are consistent across Polkadot SDK-based chains, developers can customize transaction formats and validation rules. For example: - -- **Custom pallets**: You can define new pallets with custom function calls, each with its own parameters and validation logic. -- **Signed extensions**: Developers can implement custom extensions that modify how transactions are prioritized, validated, or included in blocks. - -By leveraging Polkadot SDK's modular design, developers can create highly specialized transaction logic tailored to their chain's needs. - -## Lifecycle of a Transaction - -In the Polkadot SDK, transactions are often referred to as extrinsics because the data in transactions originates outside of the runtime. These transactions contain data that initiates changes to the chain state. The most common type of extrinsic is a signed transaction, which is cryptographically verified and typically incurs a fee. This section focuses on how signed transactions are processed, validated, and ultimately included in a block. - -### Define Transaction Properties - -The Polkadot SDK runtime defines key transaction properties, such as: - -- **Transaction validity**: Ensures the transaction meets all runtime requirements. -- **Signed or unsigned**: Identifies whether a transaction needs to be signed by an account. -- **State changes**: Determines how the transaction modifies the state of the chain. - -Pallets, which compose the runtime's logic, define the specific transactions that your chain supports. When a user submits a transaction, such as a token transfer, it becomes a signed transaction, verified by the user's account signature. If the account has enough funds to cover fees, the transaction is executed, and the chain's state is updated accordingly. - -### Process on a Block Authoring Node - -In Polkadot SDK-based networks, some nodes are authorized to author blocks. These nodes validate and process transactions. When a transaction is sent to a node that can produce blocks, it undergoes a lifecycle that involves several stages, including validation and execution. Non-authoring nodes gossip the transaction across the network until an authoring node receives it. The following diagram illustrates the lifecycle of a transaction that's submitted to a network and processed by an authoring node. - -![Transaction lifecycle diagram](/images/reference/parachains/blocks-transactions-fees/transactions/transactions-01.webp){ style="background:white" } - -### Validate and Queue +ProtectKernelModules=true +ProtectKernelTunables=true +ProtectSystem=strict +RemoveIPC=true +RestrictAddressFamilies=AF_INET AF_INET6 AF_NETLINK AF_UNIX +RestrictNamespaces=false +RestrictSUIDSGID=true +SystemCallArchitectures=native +SystemCallFilter=@system-service +SystemCallFilter=landlock_add_rule landlock_create_ruleset landlock_restrict_self seccomp mount umount2 +SystemCallFilter=~@clock @module @reboot @swap @privileged +SystemCallFilter=pivot_root +UMask=0027 -Once a transaction reaches an authoring node, it undergoes an initial validation process to ensure it meets specific conditions defined in the runtime. This validation includes checks for: +[Install] +WantedBy=multi-user.target +``` -- **Correct nonce**: Ensures the transaction is sequentially valid for the account. -- **Sufficient funds**: Confirms the account can cover any associated transaction fees. -- **Signature validity**: Verifies that the sender's signature matches the transaction data. +!!! warning "Restart delay and equivocation risk" + It is recommended that a node's restart be delayed with `RestartSec` in the case of a crash. It's possible that when a node crashes, consensus votes in GRANDPA aren't persisted to disk. In this case, there is potential to equivocate when immediately restarting. Delaying the restart will allow the network to progress past potentially conflicting votes. -After these checks, valid transactions are placed in the transaction pool, where they are queued for inclusion in a block. The transaction pool regularly re-validates queued transactions to ensure they remain valid before being processed. To reach consensus, two-thirds of the nodes must agree on the order of the transactions executed and the resulting state change. Transactions are validated and queued on the local node in a transaction pool to prepare for consensus. +### Run the Service -#### Transaction Pool +Activate the systemd service to start on system boot by running: -The transaction pool is responsible for managing valid transactions. It ensures that only transactions that pass initial validity checks are queued. Transactions that fail validation, expire, or become invalid for other reasons are removed from the pool. +```bash +systemctl enable polkadot-validator.service +``` -The transaction pool organizes transactions into two queues: +To start the service manually, use: -- **Ready queue**: Transactions that are valid and ready to be included in a block. -- **Future queue**: Transactions that are not yet valid but could be in the future, such as transactions with a nonce too high for the current state. +```bash +systemctl start polkadot-validator.service +``` -Details on how the transaction pool validates transactions, including fee and signature handling, can be found in the [`validate_transaction`](https://paritytech.github.io/polkadot-sdk/master/sp_transaction_pool/runtime_api/trait.TaggedTransactionQueue.html#method.validate_transaction){target=\_blank} method. +Check the service's status to confirm it is running: -#### Invalid Transactions +```bash +systemctl status polkadot-validator.service +``` -If a transaction is invalid, for example, due to an invalid signature or insufficient funds, it is rejected and won't be added to the block. Invalid transactions might be rejected for reasons such as: +To view the logs in real-time, use [journalctl](https://www.freedesktop.org/software/systemd/man/latest/journalctl.html){target=\_blank} like so: -- The transaction has already been included in a block. -- The transaction's signature does not match the sender. -- The transaction is too large to fit in the current block. +```bash +journalctl -f -u polkadot-validator +``` -### Transaction Ordering and Priority +With these steps, you can effectively manage and monitor your validator as a systemd service. -When a node is selected as the next block author, it prioritizes transactions based on weight, length, and tip amount. The goal is to fill the block with high-priority transactions without exceeding its maximum size or computational limits. Transactions are ordered as follows: +Once your validator is active, it's officially part of Polkadot's security infrastructure. For questions or further support, you can reach out to the [Polkadot Validator chat](https://matrix.to/#/!NZrbtteFeqYKCUGQtr:matrix.parity.io?via=matrix.parity.io&via=matrix.org&via=web3.foundation){target=\_blank} for tips and troubleshooting. -- **Inherents first**: Inherent transactions, such as block timestamp updates, are always placed first. -- **Nonce-based ordering**: Transactions from the same account are ordered by their nonce. -- **Fee-based ordering**: Among transactions with the same nonce or priority level, those with higher fees are prioritized. -### Transaction Execution +--- -Once a block author selects transactions from the pool, the transactions are executed in priority order. As each transaction is processed, the state changes are written directly to the chain's storage. It's important to note that these changes are not cached, meaning a failed transaction won't revert earlier state changes, which could leave the block in an inconsistent state. +Page Title: Stop Validating -Events are also written to storage. Runtime logic should not emit an event before performing the associated actions. If the associated transaction fails after the event was emitted, the event will not revert. +- Source (raw): https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/nodes-and-validators-run-a-validator-onboarding-and-offboarding-stop-validating.md +- Canonical (HTML): https://docs.polkadot.com/nodes-and-validators/run-a-validator/onboarding-and-offboarding/stop-validating/ +- Summary: Learn to safely stop validating on Polkadot, including chilling, unbonding tokens, and purging validator keys. -## Transaction Mortality +# Stop Validating -Transactions in the network can be configured as either mortal (with expiration) or immortal (without expiration). Every transaction payload contains a block checkpoint (reference block number and hash) and an era/validity period that determines how many blocks after the checkpoint the transaction remains valid. +## Introduction -When a transaction is submitted, the network validates it against these parameters. If the transaction is not included in a block within the specified validity window, it is automatically removed from the transaction queue. +If you're ready to stop validating on Polkadot, there are essential steps to ensure a smooth transition while protecting your funds and account integrity. Whether you're taking a break for maintenance or unbonding entirely, you'll need to chill your validator, purge session keys, and unbond your tokens. This guide explains how to use Polkadot's tools and extrinsics to safely withdraw from validation activities, safeguarding your account's future usability. -- **Mortal transactions**: Have a finite lifespan and will expire after a specified number of blocks. For example, a transaction with a block checkpoint of 1000 and a validity period of 64 blocks will be valid from blocks 1000 to 1064. +## Pause Versus Stop -- **Immortal transactions**: Never expire and remain valid indefinitely. To create an immortal transaction, set the block checkpoint to 0 (genesis block), use the genesis hash as a reference, and set the validity period to 0. +If you wish to remain a validator or nominator (for example, stopping for planned downtime or server maintenance), submitting the `chill` extrinsic in the `staking` pallet should suffice. Additional steps are only needed to unbond funds or reap an account. -However, immortal transactions pose significant security risks through replay attacks. If an account is reaped (balance drops to zero, account removed) and later re-funded, malicious actors can replay old immortal transactions. +The following are steps to ensure a smooth stop to validation: -The blockchain maintains only a limited number of prior block hashes for reference validation, called `BlockHashCount`. If your validity period exceeds `BlockHashCount`, the effective validity period becomes the minimum of your specified period and the block hash count. +- Chill the validator. +- Purge validator session keys. +- Unbond your tokens. -## Unique Identifiers for Extrinsics +## Chill Validator -Transaction hashes are **not unique identifiers** in Polkadot SDK-based chains. +When stepping back from validating, the first step is to chill your validator status. This action stops your validator from being considered for the next era without fully unbonding your tokens, which can be useful for temporary pauses like maintenance or planned downtime. -Key differences from traditional blockchains: +Use the `staking.chill` extrinsic to initiate this. For more guidance on chilling your node, refer to the [Pause Validating](/nodes-and-validators/run-a-validator/operational-tasks/pause-validating/){target=\_blank} guide. You may also claim any pending staking rewards at this point. -- Transaction hashes serve only as fingerprints of transaction information. -- Multiple valid transactions can share the same hash. -- Hash uniqueness assumptions lead to serious issues. +## Purge Validator Session Keys -For example, when an account is reaped (removed due to insufficient balance) and later recreated, it resets to nonce 0, allowing identical transactions to be valid at different points: +Purging validator session keys is a critical step in removing the association between your validator account and its session keys, which ensures that your account is fully disassociated from validator activities. The `session.purgeKeys` extrinsic removes the reference to your session keys from the stash or staking proxy account that originally set them. -| Block | Extrinsic Index | Hash | Origin | Nonce | Call | Result | -|-------|----------------|------|-----------|-------|---------------------|-------------------------------| -| 100 | 0 | 0x01 | Account A | 0 | Transfer 5 DOT to B | Account A reaped | -| 150 | 5 | 0x02 | Account B | 4 | Transfer 7 DOT to A | Account A created (nonce = 0) | -| 200 | 2 | 0x01 | Account A | 0 | Transfer 5 DOT to B | Successful transaction | +Here are a couple of important things to know about purging keys: -Notice that blocks 100 and 200 contain transactions with identical hashes (0x01) but are completely different, valid operations occurring at different times. +- **Account used to purge keys**: Always use the same account to purge keys you originally used to set them, usually your stash or staking proxy account. Using a different account may leave an unremovable reference to the session keys on the original account, preventing its reaping. +- **Account reaping issue**: Failing to purge keys will prevent you from reaping (fully deleting) your stash account. If you attempt to transfer tokens without purging, you'll need to rebond, purge the session keys, unbond again, and wait through the unbonding period before any transfer. -Additional complexity comes from Polkadot SDK's origin abstraction. Origins can represent collectives, governance bodies, or other non-account entities that don't maintain nonces like regular accounts and might dispatch identical calls multiple times with the same hash values. Each execution occurs in different chain states with different results. +## Unbond Your Tokens -The correct way to uniquely identify an extrinsic on a Polkadot SDK-based chain is to use the block ID (height or hash) and the extrinsic index. Since the Polkadot SDK defines blocks as headers plus ordered arrays of extrinsics, the index position within a canonical block provides guaranteed uniqueness. +After chilling your node and purging session keys, the final step is to unbond your staked tokens. This action removes them from staking and begins the unbonding period (usually 28 days for Polkadot and seven days for Kusama), after which the tokens will be transferable. -## Additional Resources +To unbond tokens, go to **Network > Staking > Account Actions** on Polkadot.js Apps. Select your stash account, click on the dropdown menu, and choose **Unbond Funds**. Alternatively, you can use the `staking.unbond` extrinsic if you handle this via a staking proxy account. -For a video overview of the lifecycle of transactions and the types of transactions that exist, see the [Transaction lifecycle](https://www.youtube.com/watch?v=3pfM0GOp02c){target=\_blank} seminar from Parity Tech. +Once the unbonding period is complete, your tokens will be available for use in transactions or transfers outside of staking. --- @@ -7505,351 +5561,6 @@ The system maintains precise conversion mechanisms between: This ensures accurate fee calculation while maintaining compatibility with existing Ethereum tools and workflows. ---- - -Page Title: Transactions Weights and Fees - -- Source (raw): https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/reference-parachains-blocks-transactions-fees-fees.md -- Canonical (HTML): https://docs.polkadot.com/reference/parachains/blocks-transactions-fees/fees/ -- Summary: Overview of transaction weights and fees in Polkadot SDK chains, detailing how fees are calculated using a defined formula and runtime specifics. - -# Transactions Weights and Fees - -## Introductions - -When transactions are executed, or data is stored on-chain, the activity changes the chain's state and consumes blockchain resources. Because the resources available to a blockchain are limited, managing how operations on-chain consume them is important. In addition to being limited in practical terms, such as storage capacity, blockchain resources represent a potential attack vector for malicious users. For example, a malicious user might attempt to overload the network with messages to stop the network from producing new blocks. To protect blockchain resources from being drained or overloaded, you need to manage how they are made available and how they are consumed. The resources to be aware of include: - -- Memory usage -- Storage input and output -- Computation -- Transaction and block size -- State database size - -The Polkadot SDK provides block authors with several ways to manage access to resources and to prevent individual components of the chain from consuming too much of any single resource. Two of the most important mechanisms available to block authors are weights and transaction fees. - -[Weights](/reference/glossary/#weight){target=\_blank} manage the time it takes to validate a block and characterize the time it takes to execute the calls in the block's body. By controlling the execution time a block can consume, weights set limits on storage input, output, and computation. - -Some of the weight allowed for a block is consumed as part of the block's initialization and finalization. The weight might also be used to execute mandatory inherent extrinsic calls. To help ensure blocks don’t consume too much execution time and prevent malicious users from overloading the system with unnecessary calls, weights are combined with transaction fees. - -[Transaction fees](/reference/parachains/blocks-transactions-fees/transactions/#transaction-fees){target=\_blank} provide an economic incentive to limit execution time, computation, and the number of calls required to perform operations. Transaction fees are also used to make the blockchain economically sustainable because they are typically applied to transactions initiated by users and deducted before a transaction request is executed. - -## How Fees are Calculated - -The final fee for a transaction is calculated using the following parameters: - -- **`base fee`**: This is the minimum amount a user pays for a transaction. It is declared a base weight in the runtime and converted to a fee using the [`WeightToFee`](https://docs.rs/pallet-transaction-payment/latest/pallet_transaction_payment/pallet/trait.Config.html#associatedtype.WeightToFee){target=\_blank} conversion. -- **`weight fee`**: A fee proportional to the execution time (input and output and computation) that a transaction consumes. -- **`length fee`**: A fee proportional to the encoded length of the transaction. -- **`tip`**: An optional tip to increase the transaction’s priority, giving it a higher chance to be included in the transaction queue. - -The base fee and proportional weight and length fees constitute the inclusion fee. The inclusion fee is the minimum fee that must be available for a transaction to be included in a block. - -```text -inclusion fee = base fee + weight fee + length fee -``` - -Transaction fees are withdrawn before the transaction is executed. After the transaction is executed, the weight can be adjusted to reflect the resources used. If a transaction uses fewer resources than expected, the transaction fee is corrected, and the adjusted transaction fee is deposited. - -## Using the Transaction Payment Pallet - -The [Transaction Payment pallet](https://github.com/paritytech/polkadot-sdk/tree/polkadot-stable2506-2/substrate/frame/transaction-payment){target=\_blank} provides the basic logic for calculating the inclusion fee. You can also use the Transaction Payment pallet to: - -- Convert a weight value into a deductible fee based on a currency type using [`Config::WeightToFee`](https://docs.rs/pallet-transaction-payment/latest/pallet_transaction_payment/pallet/trait.Config.html#associatedtype.WeightToFee){target=\_blank}. -- Update the fee for the next block by defining a multiplier based on the chain’s final state at the end of the previous block using [`Config::FeeMultiplierUpdate`](https://docs.rs/pallet-transaction-payment/latest/pallet_transaction_payment/pallet/trait.Config.html#associatedtype.FeeMultiplierUpdate){target=\_blank}. -- Manage the withdrawal, refund, and deposit of transaction fees using [`Config::OnChargeTransaction`](https://docs.rs/pallet-transaction-payment/latest/pallet_transaction_payment/pallet/trait.Config.html#associatedtype.OnChargeTransaction){target=\_blank}. - -You can learn more about these configuration traits in the [Transaction Payment documentation](https://paritytech.github.io/polkadot-sdk/master/pallet_transaction_payment/index.html){target=\_blank}. - -### Understanding the Inclusion Fee - -The formula for calculating the inclusion fee is as follows: - -```text -inclusion_fee = base_fee + length_fee + [targeted_fee_adjustment * weight_fee] -``` - -And then, for calculating the final fee: - -```text -final_fee = inclusion_fee + tip -``` - -In the first formula, the `targeted_fee_adjustment` is a multiplier that can tune the final fee based on the network’s congestion. - -- The `base_fee` derived from the base weight covers inclusion overhead like signature verification. -- The `length_fee` is a per-byte fee that is multiplied by the length of the encoded extrinsic. -- The `weight_fee` fee is calculated using two parameters: - - The `ExtrinsicBaseWeight` that is declared in the runtime and applies to all extrinsics. - - The `#[pallet::weight]` annotation that accounts for an extrinsic's complexity. - -To convert the weight to `Currency`, the runtime must define a `WeightToFee` struct that implements a conversion function, [`Convert`](https://docs.rs/pallet-transaction-payment/latest/pallet_transaction_payment/pallet/struct.Pallet.html#method.weight_to_fee){target=\_blank}. - -Note that the extrinsic sender is charged the inclusion fee before the extrinsic is invoked. The fee is deducted from the sender's balance even if the transaction fails upon execution. - -### Accounts with an Insufficient Balance - -If an account does not have a sufficient balance to pay the inclusion fee and remain alive—that is, enough to pay the inclusion fee and maintain the minimum existential deposit—then you should ensure the transaction is canceled so that no fee is deducted and the transaction does not begin execution. - -The Polkadot SDK doesn't enforce this rollback behavior. However, this scenario would be rare because the transaction queue and block-making logic perform checks to prevent it before adding an extrinsic to a block. - -### Fee Multipliers - -The inclusion fee formula always results in the same fee for the same input. However, weight can be dynamic and—based on how [`WeightToFee`](https://docs.rs/pallet-transaction-payment/latest/pallet_transaction_payment/pallet/trait.Config.html#associatedtype.WeightToFee){target=\_blank} is defined—the final fee can include some degree of variability. -The Transaction Payment pallet provides the [`FeeMultiplierUpdate`](https://docs.rs/pallet-transaction-payment/latest/pallet_transaction_payment/pallet/trait.Config.html#associatedtype.FeeMultiplierUpdate){target=\_blank} configurable parameter to account for this variability. - -The Polkadot network inspires the default update function and implements a targeted adjustment in which a target saturation level of block weight is defined. If the previous block is more saturated, the fees increase slightly. Similarly, if the last block has fewer transactions than the target, fees are decreased by a small amount. For more information about fee multiplier adjustments, see the [Web3 Research Page](https://research.web3.foundation/Polkadot/overview/token-economics#relay-chain-transaction-fees-and-per-block-transaction-limits){target=\_blank}. - -## Transactions with Special Requirements - -Inclusion fees must be computable before execution and can only represent fixed logic. Some transactions warrant limiting resources with other strategies. For example: - -- Bonds are a type of fee that might be returned or slashed after some on-chain event. For example, you might want to require users to place a bond to participate in a vote. The bond might then be returned at the end of the referendum or slashed if the voter attempted malicious behavior. -- Deposits are fees that might be returned later. For example, you might require users to pay a deposit to execute an operation that uses storage. The user’s deposit could be returned if a subsequent operation frees up storage. -- Burn operations are used to pay for a transaction based on its internal logic. For example, a transaction might burn funds from the sender if the transaction creates new storage items to pay for the increased state size. -- Limits enable you to enforce constant or configurable limits on specific operations. For example, the default [Staking pallet](https://github.com/paritytech/polkadot-sdk/tree/polkadot-stable2506-2/substrate/frame/staking){target=\_blank} only allows nominators to nominate 16 validators to limit the complexity of the validator election process. - -It is important to note that if you query the chain for a transaction fee, it only returns the inclusion fee. - -## Default Weight Annotations - -All dispatchable functions in the Polkadot SDK must specify a weight. The way of doing that is using the annotation-based system that lets you combine fixed values for database read/write weight and/or fixed values based on benchmarks. The most basic example would look like this: - -```rust -#[pallet::weight(100_000)] -fn my_dispatchable() { - // ... -} -``` - -Note that the [`ExtrinsicBaseWeight`](https://crates.parity.io/frame_support/weights/constants/struct.ExtrinsicBaseWeight.html){target=\_blank} is automatically added to the declared weight to account for the costs of simply including an empty extrinsic into a block. - -### Weights and Database Read/Write Operations - -To make weight annotations independent of the deployed database backend, they are defined as a constant and then used in the annotations when expressing database accesses performed by the dispatchable: - -```rust -#[pallet::weight(T::DbWeight::get().reads_writes(1, 2) + 20_000)] -fn my_dispatchable() { - // ... -} -``` - -This dispatchable allows one database to read and two to write, in addition to other things that add the additional 20,000. Database access is generally every time a value declared inside the [`#[pallet::storage]`](https://paritytech.github.io/polkadot-sdk/master/frame_support/pallet_macros/attr.storage.html){target=\_blank} block is accessed. However, unique accesses are counted because after a value is accessed, it is cached, and reaccessing it does not result in a database operation. That is: - -- Multiple reads of the exact value count as one read. -- Multiple writes of the exact value count as one write. -- Multiple reads of the same value, followed by a write to that value, count as one read and one write. -- A write followed by a read-only counts as one write. - -### Dispatch Classes - -Dispatches are broken into three classes: - -- Normal -- Operational -- Mandatory - -If a dispatch is not defined as `Operational` or `Mandatory` in the weight annotation, the dispatch is identified as `Normal` by default. You can specify that the dispatchable uses another class like this: - -```rust -#[pallet::dispatch((DispatchClass::Operational))] -fn my_dispatchable() { - // ... -} -``` - -This tuple notation also allows you to specify a final argument determining whether the user is charged based on the annotated weight. If you don't specify otherwise, `Pays::Yes` is assumed: - -```rust -#[pallet::dispatch(DispatchClass::Normal, Pays::No)] -fn my_dispatchable() { - // ... -} -``` - -#### Normal Dispatches - -Dispatches in this class represent normal user-triggered transactions. These types of dispatches only consume a portion of a block's total weight limit. For information about the maximum portion of a block that can be consumed for normal dispatches, see [`AvailableBlockRatio`](https://paritytech.github.io/polkadot-sdk/master/frame_system/limits/struct.BlockLength.html){target=\_blank}. Normal dispatches are sent to the transaction pool. - -#### Operational Dispatches - -Unlike normal dispatches, which represent the usage of network capabilities, operational dispatches are those that provide network capabilities. Operational dispatches can consume the entire weight limit of a block. They are not bound by the [`AvailableBlockRatio`](https://paritytech.github.io/polkadot-sdk/master/frame_system/limits/struct.BlockLength.html){target=\_blank}. Dispatches in this class are given maximum priority and are exempt from paying the [`length_fee`](https://docs.rs/pallet-transaction-payment/latest/pallet_transaction_payment/){target=\_blank}. - -#### Mandatory Dispatches - -Mandatory dispatches are included in a block even if they cause the block to surpass its weight limit. You can only use the mandatory dispatch class for inherent transactions that the block author submits. This dispatch class is intended to represent functions in the block validation process. Because these dispatches are always included in a block regardless of the function weight, the validation process must prevent malicious nodes from abusing the function to craft valid but impossibly heavy blocks. You can typically accomplish this by ensuring that: - -- The operation performed is always light. -- The operation can only be included in a block once. - -To make it more difficult for malicious nodes to abuse mandatory dispatches, they cannot be included in blocks that return errors. This dispatch class serves the assumption that it is better to allow an overweight block to be created than not to allow any block to be created at all. - -### Dynamic Weights - -In addition to purely fixed weights and constants, the weight calculation can consider the input arguments of a dispatchable. The weight should be trivially computable from the input arguments with some basic arithmetic: - -```rust -use frame_support:: { - dispatch:: { - DispatchClass::Normal, - Pays::Yes, - }, - weights::Weight, -}; - -#[pallet::weight(FunctionOf( - |args: (&Vec,)| args.0.len().saturating_mul(10_000), - ) -] -fn handle_users(origin, calls: Vec) { - // Do something per user -} -``` - -## Post Dispatch Weight Correction - -Depending on the execution logic, a dispatchable function might consume less weight than was prescribed pre-dispatch. To correct weight, the function declares a different return type and returns its actual weight: - -```rust -#[pallet::weight(10_000 + 500_000_000)] -fn expensive_or_cheap(input: u64) -> DispatchResultWithPostInfo { - let was_heavy = do_calculation(input); - - if (was_heavy) { - // None means "no correction" from the weight annotation. - Ok(None.into()) - } else { - // Return the actual weight consumed. - Ok(Some(10_000).into()) - } -} -``` - -## Custom Fees - -You can also define custom fee systems through custom weight functions or inclusion fee functions. - -### Custom Weights - -Instead of using the default weight annotations, you can create a custom weight calculation type using the weights module. The custom weight calculation type must implement the following traits: - -- [`WeighData`](https://crates.parity.io/frame_support/weights/trait.WeighData.html){target=\_blank} to determine the weight of the dispatch. -- [`ClassifyDispatch`](https://crates.parity.io/frame_support/weights/trait.ClassifyDispatch.html){target=\_blank} to determine the class of the dispatch. -- [`PaysFee`](https://crates.parity.io/frame_support/weights/trait.PaysFee.html){target=\_blank} to determine whether the sender of the dispatch pays fees. - -The Polkadot SDK then bundles the output information of the three traits into the [`DispatchInfo`](https://paritytech.github.io/polkadot-sdk/master/frame_support/dispatch/struct.DispatchInfo.html){target=\_blank} struct and provides it by implementing the [`GetDispatchInfo`](https://docs.rs/frame-support/latest/frame_support/dispatch/trait.GetDispatchInfo.html){target=\_blank} for all `Call` variants and opaque extrinsic types. This is used internally by the System and Executive modules. - -`ClassifyDispatch`, `WeighData`, and `PaysFee` are generic over T, which gets resolved into the tuple of all dispatch arguments except for the origin. The following example illustrates a struct that calculates the weight as `m * len(args)`, where `m` is a given multiplier and args is the concatenated tuple of all dispatch arguments. In this example, the dispatch class is `Operational` if the transaction has more than 100 bytes of length in arguments and will pay fees if the encoded length exceeds 10 bytes. - -```rust -struct LenWeight(u32); -impl WeighData for LenWeight { - fn weigh_data(&self, target: T) -> Weight { - let multiplier = self.0; - let encoded_len = target.encode().len() as u32; - multiplier * encoded_len - } -} - -impl ClassifyDispatch for LenWeight { - fn classify_dispatch(&self, target: T) -> DispatchClass { - let encoded_len = target.encode().len() as u32; - if encoded_len > 100 { - DispatchClass::Operational - } else { - DispatchClass::Normal - } - } -} - -impl PaysFee { - fn pays_fee(&self, target: T) -> Pays { - let encoded_len = target.encode().len() as u32; - if encoded_len > 10 { - Pays::Yes - } else { - Pays::No - } - } -} -``` - -A weight calculator function can also be coerced to the final type of the argument instead of defining it as a vague type that can be encoded. The code would roughly look like this: - -```rust -struct CustomWeight; -impl WeighData<(&u32, &u64)> for CustomWeight { - fn weigh_data(&self, target: (&u32, &u64)) -> Weight { - ... - } -} - -// given a dispatch: -#[pallet::call] -impl, I: 'static> Pallet { - #[pallet::weight(CustomWeight)] - fn foo(a: u32, b: u64) { ... } -} -``` - -In this example, the `CustomWeight` can only be used in conjunction with a dispatch with a particular signature `(u32, u64)`, as opposed to `LenWeight`, which can be used with anything because there aren't any assumptions about ``. - -#### Custom Inclusion Fee - -The following example illustrates how to customize your inclusion fee. You must configure the appropriate associated types in the respective module. - -```rust -// Assume this is the balance type -type Balance = u64; - -// Assume we want all the weights to have a `100 + 2 * w` conversion to fees -struct CustomWeightToFee; -impl WeightToFee for CustomWeightToFee { - fn convert(w: Weight) -> Balance { - let a = Balance::from(100); - let b = Balance::from(2); - let w = Balance::from(w); - a + b * w - } -} - -parameter_types! { - pub const ExtrinsicBaseWeight: Weight = 10_000_000; -} - -impl frame_system::Config for Runtime { - type ExtrinsicBaseWeight = ExtrinsicBaseWeight; -} - -parameter_types! { - pub const TransactionByteFee: Balance = 10; -} - -impl transaction_payment::Config { - type TransactionByteFee = TransactionByteFee; - type WeightToFee = CustomWeightToFee; - type FeeMultiplierUpdate = TargetedFeeAdjustment; -} - -struct TargetedFeeAdjustment(sp_std::marker::PhantomData); -impl> WeightToFee for TargetedFeeAdjustment { - fn convert(multiplier: Fixed128) -> Fixed128 { - // Don't change anything. Put any fee update info here. - multiplier - } -} -``` - -## Additional Resources - -You now know the weight system, how it affects transaction fee computation, and how to specify weights for your dispatchable calls. The next step is determining the correct weight for your dispatchable operations. You can use Substrate benchmarking functions and frame-benchmarking calls to test your functions with different parameters and empirically determine the proper weight in their worst-case scenarios. - -- [Benchmark](/parachains/customize-runtime/pallet-development/benchmark-pallet/) -- [`SignedExtension`](https://paritytech.github.io/polkadot-sdk/master/sp_runtime/traits/trait.SignedExtension.html){target=\_blank} -- [Custom weights for the Example pallet](https://github.com/paritytech/polkadot-sdk/blob/polkadot-stable2506-2/substrate/frame/examples/basic/src/weights.rs){target=\_blank} -- [Web3 Foundation Research](https://research.web3.foundation/Polkadot/overview/token-economics#relay-chain-transaction-fees-and-per-block-transaction-limits){target=\_blank} - - --- Page Title: Upgrade a Validator Node @@ -8172,91 +5883,3 @@ For example, on November 19, 2024, the minimum stake backing a validator in Polk - [**Chain State Values**](https://wiki.polkadot.com/general/chain-state-values/){target=\_blank} - [**Subscan**](https://polkadot.subscan.io/validator_list?status=validator){target=\_blank} - [**Staking Dashboard**](https://staking.polkadot.cloud/#/overview){target=\_blank} - - ---- - -Page Title: XCM Tools - -- Source (raw): https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/reference-tools-xcm-tools.md -- Canonical (HTML): https://docs.polkadot.com/reference/tools/xcm-tools/ -- Summary: Explore essential XCM tools across Polkadot, crafted to enhance cross-chain functionality and integration within the ecosystem. - -# XCM Tools - -## Introduction - -As described in the [Interoperability](/develop/interoperability){target=\_blank} section, XCM (Cross-Consensus Messaging) is a protocol used in the Polkadot and Kusama ecosystems to enable communication and interaction between chains. It facilitates cross-chain communication, allowing assets, data, and messages to flow seamlessly across the ecosystem. - -As XCM is central to enabling communication between blockchains, developers need robust tools to help interact with, build, and test XCM messages. Several XCM tools simplify working with the protocol by providing libraries, frameworks, and utilities that enhance the development process, ensuring that applications built within the Polkadot ecosystem can efficiently use cross-chain functionalities. - -## Popular XCM Tools - -### Moonsong Labs XCM Tools - -[Moonsong Labs XCM Tools](https://github.com/Moonsong-Labs/xcm-tools){target=\_blank} provides a collection of scripts for managing and testing XCM operations between Polkadot SDK-based runtimes. These tools allow performing tasks like asset registration, channel setup, and XCM initialization. Key features include: - -- **Asset registration**: Registers assets, setting units per second (up-front fees), and configuring error (revert) codes. -- **XCM initializer**: Initializes XCM, sets default XCM versions, and configures revert codes for XCM-related precompiles. -- **HRMP manipulator**: Manages HRMP channel actions, including opening, accepting, or closing channels. -- **XCM-Transactor-Info-Setter**: Configures transactor information, including extra weight and fee settings. -- **Decode XCM**: Decodes XCM messages on the relay chain or parachains to help interpret cross-chain communication. - -To get started, clone the repository and install the required dependencies: - -```bash -git clone https://github.com/Moonsong-Labs/xcm-tools && -cd xcm-tools && -yarn install -``` - -For a full overview of each script, visit the [scripts](https://github.com/Moonsong-Labs/xcm-tools/tree/main/scripts){target=\_blank} directory or refer to the [official documentation](https://github.com/Moonsong-Labs/xcm-tools/blob/main/README.md){target=\_blank} on GitHub. - -### ParaSpell - -[ParaSpell](/reference/tools/paraspell/){target=\_blank} is a collection of open-source XCM tools that streamline cross-chain asset transfers and interactions across the Polkadot and Kusama ecosystems. It provides developers with an intuitive interface to build, test, and deploy interoperable dApps, featuring message composition, decoding, and practical utilities for parachain interactions that simplify debugging and cross-chain communication optimization. - -### Astar XCM Tools - -The [Astar parachain](https://github.com/AstarNetwork/Astar/tree/master){target=\_blank} offers a crate with a set of utilities for interacting with the XCM protocol. The [xcm-tools](https://github.com/AstarNetwork/Astar/tree/master/bin/xcm-tools){target=\_blank} crate provides a straightforward method for users to locate a sovereign account or calculate an XC20 asset ID. Some commands included by the xcm-tools crate allow users to perform the following tasks: - -- **Sovereign accounts**: Obtain the sovereign account address for any parachain, either on the Relay Chain or for sibling parachains, using a simple command. -- **XC20 EVM addresses**: Generate XC20-compatible Ethereum addresses for assets by entering the asset ID, making it easy to integrate assets across Ethereum-compatible environments. -- **Remote accounts**: Retrieve remote account addresses needed for multi-location compatibility, using flexible options to specify account types and parachain IDs. - -To start using these tools, clone the [Astar repository](https://github.com/AstarNetwork/Astar){target=\_blank} and compile the xcm-tools package: - -```bash -git clone https://github.com/AstarNetwork/Astar && -cd Astar && -cargo build --release -p xcm-tools -``` - -After compiling, verify the setup with the following command: - -```bash -./target/release/xcm-tools --help -``` -For more details on using Astar xcm-tools, consult the [official documentation](https://docs.astar.network/docs/learn/interoperability/xcm/integration/tools/){target=\_blank}. - -### Chopsticks - -The Chopsticks library provides XCM functionality for testing XCM messages across networks, enabling you to fork multiple parachains along with a relay chain. For further details, see the [Chopsticks documentation](/tutorials/polkadot-sdk/testing/fork-live-chains/){target=\_blank} about XCM. - -### Moonbeam XCM SDK - -The [Moonbeam XCM SDK](https://github.com/moonbeam-foundation/xcm-sdk){target=\_blank} enables developers to easily transfer assets between chains, either between parachains or between a parachain and the relay chain, within the Polkadot/Kusama ecosystem. With the SDK, you don't need to worry about determining the [Multilocation](https://github.com/polkadot-fellows/xcm-format?tab=readme-ov-file#7-universal-consensus-location-identifiers){target=\_blank} of the origin or destination assets or which extrinsics are used on which networks. - -The SDK consists of two main packages: - -- **[XCM SDK](https://github.com/moonbeam-foundation/xcm-sdk/tree/main/packages/sdk){target=\_blank}**: Core SDK for executing XCM transfers between chains in the Polkadot/Kusama ecosystem. -- **[MRL SDK](https://github.com/moonbeam-foundation/xcm-sdk/tree/main/packages/mrl){target=\_blank}**: Extension of the XCM SDK for transferring liquidity into and across the Polkadot ecosystem from other ecosystems like Ethereum. - -Key features include: - -- **Simplified asset transfers**: Abstracts away complex multilocation determinations and extrinsic selection. -- **Cross-ecosystem support**: Enables transfers between Polkadot/Kusama chains and external ecosystems. -- **Developer-friendly API**: Provides intuitive interfaces for cross-chain functionality. -- **Comprehensive documentation**: Includes usage guides and API references for both packages. - -For detailed usage examples and API documentation, visit the [official Moonbeam XCM SDK documentation](https://moonbeam-foundation.github.io/xcm-sdk/latest/){target=\_blank}. diff --git a/.ai/categories/networks.md b/.ai/categories/networks.md index e2ee7b8ce..ffd58ed1c 100644 --- a/.ai/categories/networks.md +++ b/.ai/categories/networks.md @@ -1396,374 +1396,6 @@ XCM revolutionizes cross-chain communication by enabling use cases such as: These functionalities empower developers to build innovative, multi-chain applications, leveraging the strengths of various blockchain networks. To stay updated on XCM’s evolving format or contribute, visit the [XCM repository](https://github.com/paritytech/xcm-docs/blob/main/examples/src/0_first_look/mod.rs){target=\_blank}. ---- - -Page Title: Glossary - -- Source (raw): https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/reference-glossary.md -- Canonical (HTML): https://docs.polkadot.com/reference/glossary/ -- Summary: Glossary of terms used within the Polkadot ecosystem, Polkadot SDK, its subsequent libraries, and other relevant Web3 terminology. - -# Glossary - -Key definitions, concepts, and terminology specific to the Polkadot ecosystem are included here. - -Additional glossaries from around the ecosystem you might find helpful: - -- [Polkadot Wiki Glossary](https://wiki.polkadot.com/general/glossary){target=\_blank} -- [Polkadot SDK Glossary](https://paritytech.github.io/polkadot-sdk/master/polkadot_sdk_docs/reference_docs/glossary/index.html){target=\_blank} - -## Authority - -The role in a blockchain that can participate in consensus mechanisms. - -- **[GRANDPA](#grandpa)**: The authorities vote on chains they consider final. -- **[Blind Assignment of Blockchain Extension](#blind-assignment-of-blockchain-extension-babe) (BABE)**: The authorities are also [block authors](#block-author). - -Authority sets can be used as a basis for consensus mechanisms such as the [Nominated Proof of Stake (NPoS)](#nominated-proof-of-stake-npos) protocol. - -## Authority Round (Aura) - -A deterministic [consensus](#consensus) protocol where block production is limited to a rotating list of [authorities](#authority) that take turns creating blocks. In authority round (Aura) consensus, most online authorities are assumed to be honest. It is often used in combination with [GRANDPA](#grandpa) as a [hybrid consensus](#hybrid-consensus) protocol. - -Learn more by reading the official [Aura consensus algorithm](https://openethereum.github.io/Aura){target=\_blank} wiki article. - -## Blind Assignment of Blockchain Extension (BABE) - -A [block authoring](#block-author) protocol similar to [Aura](#authority-round-aura), except [authorities](#authority) win [slots](#slot) based on a Verifiable Random Function (VRF) instead of the round-robin selection method. The winning authority can select a chain and submit a new block. - -Learn more by reading the official Web3 Foundation [BABE research document](https://research.web3.foundation/Polkadot/protocols/block-production/Babe){target=\_blank}. - -## Block Author - -The node responsible for the creation of a block, also called _block producers_. In a Proof of Work (PoW) blockchain, these nodes are called _miners_. - -## Byzantine Fault Tolerance (BFT) - -The ability of a distributed computer network to remain operational if a certain proportion of its nodes or [authorities](#authority) are defective or behaving maliciously. A distributed network is typically considered Byzantine fault tolerant if it can remain functional, with up to one-third of nodes assumed to be defective, offline, actively malicious, and part of a coordinated attack. - -### Byzantine Failure - -The loss of a network service due to node failures that exceed the proportion of nodes required to reach consensus. - -### Practical Byzantine Fault Tolerance (pBFT) - -An early approach to Byzantine fault tolerance (BFT), practical Byzantine fault tolerance (pBFT) systems tolerate Byzantine behavior from up to one-third of participants. - -The communication overhead for such systems is `O(n²)`, where `n` is the number of nodes (participants) in the system. - -### Preimage - -A preimage is the data that is input into a hash function to calculate a hash. Since a hash function is a [one-way function](https://en.wikipedia.org/wiki/One-way_function){target=\_blank}, the output, the hash, cannot be used to reveal the input, the preimage. - -## Call - -In the context of pallets containing functions to be dispatched to the runtime, `Call` is an enumeration data type that describes the functions that can be dispatched with one variant per pallet. A `Call` represents a [dispatch](#dispatchable) data structure object. - -## Chain Specification - -A chain specification file defines the properties required to run a node in an active or new Polkadot SDK-built network. It often contains the initial genesis runtime code, network properties (such as the network's name), the initial state for some pallets, and the boot node list. The chain specification file makes it easy to use a single Polkadot SDK codebase as the foundation for multiple independently configured chains. - -## Collator - -An [author](#block-author) of a [parachain](#parachain) network. -They aren't [authorities](#authority) in themselves, as they require a [relay chain](#relay-chain) to coordinate [consensus](#consensus). - -More details are found on the [Polkadot Collator Wiki](https://wiki.polkadot.com/learn/learn-collator/){target=\_blank}. - -## Collective - -Most often used to refer to an instance of the Collective pallet on Polkadot SDK-based networks such as [Kusama](#kusama) or [Polkadot](#polkadot) if the Collective pallet is part of the FRAME-based runtime for the network. - -## Consensus - -Consensus is the process blockchain nodes use to agree on a chain's canonical fork. It is composed of [authorship](#block-author), finality, and [fork-choice rule](#fork-choice-rulestrategy). In the Polkadot ecosystem, these three components are usually separate and the term consensus often refers specifically to authorship. - -See also [hybrid consensus](#hybrid-consensus). - -## Consensus Algorithm - -Ensures a set of [actors](#authority)—who don't necessarily trust each other—can reach an agreement about the state as the result of some computation. Most consensus algorithms assume that up to one-third of the actors or nodes can be [Byzantine fault tolerant](#byzantine-fault-tolerance-bft). - -Consensus algorithms are generally concerned with ensuring two properties: - -- **Safety**: Indicating that all honest nodes eventually agreed on the state of the chain. -- **Liveness**: Indicating the ability of the chain to keep progressing. - -## Consensus Engine - -The node subsystem responsible for consensus tasks. - -For detailed information about the consensus strategies of the [Polkadot](#polkadot) network, see the [Polkadot Consensus](/reference/polkadot-hub/consensus-and-security/pos-consensus/){target=\_blank} blog series. - -See also [hybrid consensus](#hybrid-consensus). - -## Coretime - -The time allocated for utilizing a core, measured in relay chain blocks. There are two types of coretime: *on-demand* and *bulk*. - -On-demand coretime refers to coretime acquired through bidding in near real-time for the validation of a single parachain block on one of the cores reserved specifically for on-demand orders. They are available as an on-demand coretime pool. Set of cores that are available on-demand. Cores reserved through bulk coretime could also be made available in the on-demand coretime pool, in parts or in entirety. - -Bulk coretime is a fixed duration of continuous coretime represented by an NFT that can be split, shared, or resold. It is managed by the [Broker pallet](https://paritytech.github.io/polkadot-sdk/master/pallet_broker/index.html){target=\_blank}. - -## Development Phrase - -A [mnemonic phrase](https://en.wikipedia.org/wiki/Mnemonic#For_numerical_sequences_and_mathematical_operations){target=\_blank} that is intentionally made public. - -Well-known development accounts, such as Alice, Bob, Charlie, Dave, Eve, and Ferdie, are generated from the same secret phrase: - -``` -bottom drive obey lake curtain smoke basket hold race lonely fit walk -``` - -Many tools in the Polkadot SDK ecosystem, such as [`subkey`](https://github.com/paritytech/polkadot-sdk/tree/polkadot-stable2506-2/substrate/bin/utils/subkey){target=\_blank}, allow you to implicitly specify an account using a derivation path such as `//Alice`. - -## Digest - -An extensible field of the [block header](#header) that encodes information needed by several actors in a blockchain network, including: - -- [Light clients](#light-client) for chain synchronization. -- Consensus engines for block verification. -- The runtime itself, in the case of pre-runtime digests. - -## Dispatchable - -Function objects that act as the entry points in FRAME [pallets](#pallet). Internal or external entities can call them to interact with the blockchain’s state. They are a core aspect of the runtime logic, handling [transactions](#transaction) and other state-changing operations. - -## Events - -A means of recording that some particular [state](#state) transition happened. - -In the context of [FRAME](#frame-framework-for-runtime-aggregation-of-modularized-entities), events are composable data types that each [pallet](#pallet) can individually define. Events in FRAME are implemented as a set of transient storage items inspected immediately after a block has been executed and reset during block initialization. - -## Executor - -A means of executing a function call in a given [runtime](#runtime) with a set of dependencies. -There are two orchestration engines in Polkadot SDK, _WebAssembly_ and _native_. - -- The _native executor_ uses a natively compiled runtime embedded in the node to execute calls. This is a performance optimization available to up-to-date nodes. - -- The _WebAssembly executor_ uses a [Wasm](#webassembly-wasm) binary and a Wasm interpreter to execute calls. The binary is guaranteed to be up-to-date regardless of the version of the blockchain node because it is persisted in the [state](#state) of the Polkadot SDK-based chain. - -## Existential Deposit - -The minimum balance an account is allowed to have in the [Balances pallet](https://paritytech.github.io/polkadot-sdk/master/pallet_balances/index.html){target=\_blank}. Accounts cannot be created with a balance less than the existential deposit amount. - -If an account balance drops below this amount, the Balances pallet uses [a FRAME System API](https://paritytech.github.io/substrate/master/frame_system/pallet/struct.Pallet.html#method.dec_ref){target=\_blank} to drop its references to that account. - -If the Balances pallet reference to an account is dropped, the account can be [reaped](https://paritytech.github.io/substrate/master/frame_system/pallet/struct.Pallet.html#method.allow_death){target=\_blank}. - -## Extrinsic - -A general term for data that originates outside the runtime, is included in a block, and leads to some action. This includes user-initiated transactions and inherent transactions placed into the block by the block builder. - -It is a SCALE-encoded array typically consisting of a version number, signature, and varying data types indicating the resulting runtime function to be called. Extrinsics can take two forms: [inherents](#inherent-transactions) and [transactions](#transaction). - -For more technical details, see the [Polkadot spec](https://spec.polkadot.network/id-extrinsics){target=\_blank}. - -## Fork Choice Rule/Strategy - -A fork choice rule or strategy helps determine which chain is valid when reconciling several network forks. A common fork choice rule is the [longest chain](https://paritytech.github.io/polkadot-sdk/master/sc_consensus/struct.LongestChain.html){target=\_blank}, in which the chain with the most blocks is selected. - -## FRAME (Framework for Runtime Aggregation of Modularized Entities) - -Enables developers to create blockchain [runtime](#runtime) environments from a modular set of components called [pallets](#pallet). It utilizes a set of procedural macros to construct runtimes. - -[Visit the Polkadot SDK docs for more details on FRAME.](https://paritytech.github.io/polkadot-sdk/master/polkadot_sdk_docs/polkadot_sdk/frame_runtime/index.html){target=\_blank} - -## Full Node - -A node that prunes historical states, keeping only recently finalized block states to reduce storage needs. Full nodes provide current chain state access and allow direct submission and validation of [extrinsics](#extrinsic), maintaining network decentralization. - -## Genesis Configuration - -A mechanism for specifying the initial state of a blockchain. By convention, this initial state or first block is commonly referred to as the genesis state or genesis block. The genesis configuration for Polkadot SDK-based chains is accomplished by way of a [chain specification](#chain-specification) file. - -## GRANDPA - -A deterministic finality mechanism for blockchains that is implemented in the [Rust](https://www.rust-lang.org/){target=\_blank} programming language. - -The [formal specification](https://github.com/w3f/consensus/blob/master/pdf/grandpa-old.pdf){target=\_blank} is maintained by the [Web3 Foundation](https://web3.foundation/){target=\_blank}. - -## Header - -A structure that aggregates the information used to summarize a block. Primarily, it consists of cryptographic information used by [light clients](#light-client) to get minimally secure but very efficient chain synchronization. - -## Hybrid Consensus - -A blockchain consensus protocol that consists of independent or loosely coupled mechanisms for [block production](#block-author) and finality. - -Hybrid consensus allows the chain to grow as fast as probabilistic consensus protocols, such as [Aura](#authority-round-aura), while maintaining the same level of security as deterministic finality consensus protocols, such as [GRANDPA](#grandpa). - -## Inherent Transactions - -A special type of unsigned transaction, referred to as _inherents_, that enables a block authoring node to insert information that doesn't require validation directly into a block. - -Only the block-authoring node that calls the inherent transaction function can insert data into its block. In general, validators assume the data inserted using an inherent transaction is valid and reasonable even if it can't be deterministically verified. - -## JSON-RPC - -A stateless, lightweight remote procedure call protocol encoded in JavaScript Object Notation (JSON). JSON-RPC provides a standard way to call functions on a remote system by using JSON. - -For Polkadot SDK, this protocol is implemented through the [Parity JSON-RPC](https://github.com/paritytech/jsonrpc){target=\_blank} crate. - -## Keystore - -A subsystem for managing keys for the purpose of producing new blocks. - -## Kusama - -[Kusama](https://kusama.network/){target=\_blank} is a Polkadot SDK-based blockchain that implements a design similar to the [Polkadot](#polkadot) network. - -Kusama is a [canary](https://en.wiktionary.org/wiki/canary_in_a_coal_mine){target=\_blank} network and is referred to as [Polkadot's "wild cousin."](https://wiki.polkadot.com/learn/learn-comparisons-kusama/){target=\_blank}. - -As a canary network, Kusama is expected to be more stable than a test network like [Westend](#westend) but less stable than a production network like [Polkadot](#polkadot). Kusama is controlled by its network participants and is intended to be stable enough to encourage meaningful experimentation. - -## libp2p - -A peer-to-peer networking stack that allows the use of many transport mechanisms, including WebSockets (usable in a web browser). - -Polkadot SDK uses the [Rust implementation](https://github.com/libp2p/rust-libp2p){target=\_blank} of the `libp2p` networking stack. - -## Light Client - -A type of blockchain node that doesn't store the [chain state](#state) or produce blocks. - -A light client can verify cryptographic primitives and provides a [remote procedure call (RPC)](https://en.wikipedia.org/wiki/Remote_procedure_call){target=\_blank} server, enabling blockchain users to interact with the network. - -## Metadata - -Data that provides information about one or more aspects of a system. -The metadata that exposes information about a Polkadot SDK blockchain enables you to interact with that system. - -## Nominated Proof of Stake (NPoS) - -A method for determining [validators](#validator) or _[authorities](#authority)_ based on a willingness to commit their stake to the proper functioning of one or more block-producing nodes. - -## Oracle - -An entity that connects a blockchain to a non-blockchain data source. Oracles enable the blockchain to access and act upon information from existing data sources and incorporate data from non-blockchain systems and services. - -## Origin - -A [FRAME](#frame-framework-for-runtime-aggregation-of-modularized-entities) primitive that identifies the source of a [dispatched](#dispatchable) function call into the [runtime](#runtime). The FRAME System pallet defines three built-in [origins](#origin). As a [pallet](#pallet) developer, you can also define custom origins, such as those defined by the [Collective pallet](https://paritytech.github.io/substrate/master/pallet_collective/enum.RawOrigin.html){target=\_blank}. - -## Pallet - -A module that can be used to extend the capabilities of a [FRAME](#frame-framework-for-runtime-aggregation-of-modularized-entities)-based [runtime](#runtime). -Pallets bundle domain-specific logic with runtime primitives like [events](#events) and [storage items](#storage-item). - -## Parachain - -A parachain is a blockchain that derives shared infrastructure and security from a _[relay chain](#relay-chain)_. -You can learn more about parachains on the [Polkadot Wiki](https://wiki.polkadot.com/learn/learn-parachains/){target=\_blank}. - -## Paseo - -Paseo TestNet provisions testing on Polkadot's "production" runtime, which means less chance of feature or code mismatch when developing parachain apps. Specifically, after the [Polkadot Technical fellowship](https://wiki.polkadot.com/learn/learn-polkadot-technical-fellowship/){target=\_blank} proposes a runtime upgrade for Polkadot, this TestNet is updated, giving a period where the TestNet will be ahead of Polkadot to allow for testing. - -## Polkadot - -The [Polkadot network](https://polkadot.com/){target=\_blank} is a blockchain that serves as the central hub of a heterogeneous blockchain network. It serves the role of the [relay chain](#relay-chain) and provides shared infrastructure and security to support [parachains](#parachain). - -## Polkadot Cloud - -Polkadot Cloud is a platform for deploying resilient, customizable and scalable Web3 applications through Polkadot's functionality. It encompasses the wider Polkadot network infrastructure and security layer where parachains operate. The platform enables users to launch Ethereum-compatible chains, build specialized blockchains, and flexibly manage computing resources through on-demand or bulk coretime purchases. Initially launched with basic parachain functionality, Polkadot Cloud has evolved to offer enhanced flexibility with features like coretime, elastic scaling, and async backing for improved performance. - -## Polkadot Hub - -Polkadot Hub is a Layer 1 platform that serves as the primary entry point to the Polkadot ecosystem, providing essential functionality without requiring parachain deployment. It offers core services including smart contracts, identity management, staking, governance, and interoperability with other ecosystems, making it simple and fast for both builders and users to get started in Web3. - -## PolkaVM - -PolkaVM is a custom virtual machine optimized for performance, leveraging a RISC-V-based architecture to support Solidity and any language that compiles to RISC-V. It is specifically designed for the Polkadot ecosystem, enabling smart contract deployment and execution. - -## Relay Chain - -Relay chains are blockchains that provide shared infrastructure and security to the [parachains](#parachain) in the network. In addition to providing [consensus](#consensus) capabilities, relay chains allow parachains to communicate and exchange digital assets without needing to trust one another. - -## Rococo - -A [parachain](#parachain) test network for the Polkadot network. The [Rococo](#rococo) network is a Polkadot SDK-based blockchain with an October 14, 2024 deprecation date. Development teams are encouraged to use the Paseo TestNet instead. - -## Runtime - -The runtime represents the [state transition function](#state-transition-function-stf) for a blockchain. In Polkadot SDK, the runtime is stored as a [Wasm](#webassembly-wasm) binary in the chain state. The Runtime is stored under a unique state key and can be modified during the execution of the state transition function. - -## Slot - -A fixed, equal interval of time used by consensus engines such as [Aura](#authority-round-aura) and [BABE](#blind-assignment-of-blockchain-extension-babe). In each slot, a subset of [authorities](#authority) is permitted, or obliged, to [author](#block-author) a block. - -## Sovereign Account - -The unique account identifier for each chain in the relay chain ecosystem. It is often used in cross-consensus (XCM) interactions to sign XCM messages sent to the relay chain or other chains in the ecosystem. - -The sovereign account for each chain is a root-level account that can only be accessed using the Sudo pallet or through governance. The account identifier is calculated by concatenating the Blake2 hash of a specific text string and the registered parachain identifier. - -## SS58 Address Format - -A public key address based on the Bitcoin [`Base-58-check`](https://en.bitcoin.it/wiki/Base58Check_encoding){target=\_blank} encoding. Each Polkadot SDK SS58 address uses a `base-58` encoded value to identify a specific account on a specific Polkadot SDK-based chain - -The [canonical `ss58-registry`](https://github.com/paritytech/ss58-registry){target=\_blank} provides additional details about the address format used by different Polkadot SDK-based chains, including the network prefix and website used for different networks - -## State Transition Function (STF) - -The logic of a blockchain that determines how the state changes when a block is processed. In Polkadot SDK, the state transition function is effectively equivalent to the [runtime](#runtime). - -## Storage Item - -[FRAME](#frame-framework-for-runtime-aggregation-of-modularized-entities) primitives that provide type-safe data persistence capabilities to the [runtime](#runtime). -Learn more in the [storage items](https://paritytech.github.io/polkadot-sdk/master/frame_support/storage/types/index.html){target=\_blank} reference document in the Polkadot SDK. - -## Substrate - -A flexible framework for building modular, efficient, and upgradeable blockchains. Substrate is written in the [Rust](https://www.rust-lang.org/){target=\_blank} programming language and is maintained by [Parity Technologies](https://www.parity.io/){target=\_blank}. - -## Transaction - -An [extrinsic](#extrinsic) that includes a signature that can be used to verify the account authorizing it inherently or via [signed extensions](https://paritytech.github.io/polkadot-sdk/master/polkadot_sdk_docs/reference_docs/signed_extensions/index.html){target=\_blank}. - -## Transaction Era - -A definable period expressed as a range of block numbers during which a transaction can be included in a block. -Transaction eras are used to protect against transaction replay attacks if an account is reaped and its replay-protecting nonce is reset to zero. - -## Trie (Patricia Merkle Tree) - -A data structure used to represent sets of key-value pairs and enables the items in the data set to be stored and retrieved using a cryptographic hash. Because incremental changes to the data set result in a new hash, retrieving data is efficient even if the data set is very large. With this data structure, you can also prove whether the data set includes any particular key-value pair without access to the entire data set. - -In Polkadot SDK-based blockchains, state is stored in a trie data structure that supports the efficient creation of incremental digests. This trie is exposed to the [runtime](#runtime) as [a simple key/value map](#storage-item) where both keys and values can be arbitrary byte arrays. - -## Validator - -A validator is a node that participates in the consensus mechanism of the network. Its roles include block production, transaction validation, network integrity, and security maintenance. - -## WebAssembly (Wasm) - -An execution architecture that allows for the efficient, platform-neutral expression of -deterministic, machine-executable logic. - -[Wasm](https://webassembly.org/){target=\_blank} can be compiled from many languages, including -the [Rust](https://www.rust-lang.org/){target=\_blank} programming language. Polkadot SDK-based chains use a Wasm binary to provide portable [runtimes](#runtime) that can be included as part of the chain's state. - -## Weight - -A convention used in Polkadot SDK-based blockchains to measure and manage the time it takes to validate a block. -Polkadot SDK defines one unit of weight as one picosecond of execution time on reference hardware. - -The maximum block weight should be equivalent to one-third of the target block time with an allocation of one-third each for: - -- Block construction -- Network propagation -- Import and verification - -By defining weights, you can trade-off the number of transactions per second and the hardware required to maintain the target block time appropriate for your use case. Weights are defined in the runtime, meaning you can tune them using runtime updates to keep up with hardware and software improvements. - -## Westend - -Westend is a Parity-maintained, Polkadot SDK-based blockchain that serves as a test network for the [Polkadot](#polkadot) network. - - --- Page Title: Install Polkadot SDK @@ -2186,76 +1818,6 @@ To stop the node, press `Control-C` in the terminal. ---- - -Page Title: Interoperability - -- Source (raw): https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/reference-parachains-interoperability.md -- Canonical (HTML): https://docs.polkadot.com/reference/parachains/interoperability/ -- Summary: Explore the importance of interoperability in the Polkadot ecosystem, covering XCM, bridges, and cross-chain communication. - -# Interoperability - -## Introduction - -Interoperability lies at the heart of the Polkadot ecosystem, enabling communication and collaboration across a diverse range of blockchains. By bridging the gaps between parachains, relay chains, and even external networks, Polkadot unlocks the potential for truly decentralized applications, efficient resource sharing, and scalable solutions. - -Polkadot’s design ensures that blockchains can transcend their individual limitations by working together as part of a unified system. This cooperative architecture is what sets Polkadot apart in the blockchain landscape. - -## Why Interoperability Matters - -The blockchain ecosystem is inherently fragmented. Different blockchains excel in specialized domains such as finance, gaming, or supply chain management, but these chains function in isolation without interoperability. This lack of connectivity stifles the broader utility of blockchain technology. - -Interoperability solves this problem by enabling blockchains to: - -- **Collaborate across networks**: Chains can interact to share assets, functionality, and data, creating synergies that amplify their individual strengths. -- **Achieve greater scalability**: Specialized chains can offload tasks to others, optimizing performance and resource utilization. -- **Expand use-case potential**: Cross-chain applications can leverage features from multiple blockchains, unlocking novel user experiences and solutions. - -In the Polkadot ecosystem, interoperability transforms a collection of isolated chains into a cohesive, efficient network, pushing the boundaries of what blockchains can achieve together. - -## Key Mechanisms for Interoperability - -At the core of Polkadot's cross-chain collaboration are foundational technologies designed to break down barriers between networks. These mechanisms empower blockchains to communicate, share resources, and operate as a cohesive ecosystem. - -### Cross-Consensus Messaging (XCM): The Backbone of Communication - -Polkadot's Cross-Consensus Messaging (XCM) is the standard framework for interaction between parachains, relay chains, and, eventually, external blockchains. XCM provides a trustless, secure messaging format for exchanging assets, sharing data, and executing cross-chain operations. - -Through XCM, decentralized applications can: - -- Transfer tokens and other assets across chains. -- Coordinate complex workflows that span multiple blockchains. -- Enable seamless user experiences where underlying blockchain differences are invisible. -- XCM exemplifies Polkadot’s commitment to creating a robust and interoperable ecosystem. - -For further information about XCM, check the [Get Started with XCM](/parachains/interoperability/get-started/){target=\_blank} article. - -### Bridges: Connecting External Networks - -While XCM enables interoperability within the Polkadot ecosystem, bridges extend this functionality to external blockchains such as Ethereum and Bitcoin. By connecting these networks, bridges allow Polkadot-based chains to access external liquidity, additional functionalities, and broader user bases. - -With bridges, developers and users gain the ability to: - -- Integrate external assets into Polkadot-based applications. -- Combine the strengths of Polkadot’s scalability with the liquidity of other networks. -- Facilitate accurate multi-chain applications that transcend ecosystem boundaries. - -For more information about bridges in the Polkadot ecosystem, see the [Bridge Hub](/reference/polkadot-hub/bridging/){target=\_blank} guide. - -## The Polkadot Advantage - -Polkadot was purpose-built for interoperability. Unlike networks that add interoperability as an afterthought, Polkadot integrates it as a fundamental design principle. This approach offers several distinct advantages: - -- **Developer empowerment**: Polkadot’s interoperability tools allow developers to build applications that leverage multiple chains’ capabilities without added complexity. -- **Enhanced ecosystem collaboration**: Chains in Polkadot can focus on their unique strengths while contributing to the ecosystem’s overall growth. -- **Future-proofing blockchain**: By enabling seamless communication, Polkadot ensures its ecosystem can adapt to evolving demands and technologies. - -## Looking Ahead - -Polkadot’s vision of interoperability extends beyond technical functionality, representing a shift towards a more collaborative blockchain landscape. By enabling chains to work together, Polkadot fosters innovation, efficiency, and accessibility, paving the way for a decentralized future where blockchains are not isolated competitors but interconnected collaborators. - - --- Page Title: JSON-RPC APIs @@ -3127,368 +2689,76 @@ If an error occurs, the response will include an error object: --- -Page Title: Networks +Page Title: Overview of FRAME -- Source (raw): https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/reference-parachains-networks.md -- Canonical (HTML): https://docs.polkadot.com/reference/parachains/networks/ -- Summary: Explore Polkadot's testing and production networks, including Westend, Kusama, and Paseo, for efficient development, deployment, and testing. +- Source (raw): https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/parachains-customize-runtime.md +- Canonical (HTML): https://docs.polkadot.com/parachains/customize-runtime/ +- Summary: Learn how Polkadot SDK’s FRAME framework simplifies blockchain development with modular pallets and support libraries for efficient runtime design. -# Networks +# Customize Your Runtime ## Introduction -The Polkadot ecosystem is built on a robust set of networks designed to enable secure and scalable development. Whether you are testing new features or deploying to live production, Polkadot offers several layers of networks tailored for each stage of the development process. From local environments to experimental networks like Kusama and community-run TestNets such as Paseo, developers can thoroughly test, iterate, and validate their applications. This guide will introduce you to Polkadot's various networks and explain how they fit into the development workflow. - -## Network Overview - -Polkadot's development process is structured to ensure new features and upgrades are rigorously tested before being deployed on live production networks. The progression follows a well-defined path, starting from local environments and advancing through TestNets, ultimately reaching the Polkadot MainNet. The diagram below outlines the typical progression of the Polkadot development cycle: - -``` mermaid -flowchart LR - id1[Local] --> id2[Westend] --> id4[Kusama] --> id5[Polkadot] - id1[Local] --> id3[Paseo] --> id5[Polkadot] -``` - -This flow ensures developers can thoroughly test and iterate without risking real tokens or affecting production networks. Testing tools like [Chopsticks](#chopsticks) and various TestNets make it easier to experiment safely before releasing to production. +A blockchain runtime is more than just a fixed set of rules—it's a dynamic foundation that you can shape to match your specific needs. With Polkadot SDK's [FRAME (Framework for Runtime Aggregation of Modularized Entities)](https://paritytech.github.io/polkadot-sdk/master/polkadot_sdk_docs/polkadot_sdk/frame_runtime/index.html){target=\_blank}, customizing your runtime is straightforward and modular. Instead of building everything from scratch, you combine pre-built pallets with your own custom logic to create a runtime suited to your blockchain's purpose. -A typical journey through the Polkadot core protocol development process might look like this: -1. **Local development node**: Development starts in a local environment, where developers can create, test, and iterate on upgrades or new features using a local development node. This stage allows rapid experimentation in an isolated setup without any external dependencies. -2. **Westend**: After testing locally, upgrades are deployed to [Westend](#westend), Polkadot's primary TestNet. Westend simulates real-world conditions without using real tokens, making it the ideal place for rigorous feature testing before moving on to production networks. +This overview explains how runtime customization works, introduces the building blocks you'll use, and guides you through the key patterns for extending your runtime. -3. **Kusama**: Once features have passed extensive testing on Westend, they move to Kusama, Polkadot's experimental and fast-moving "canary" network. Kusama operates as a high-fidelity testing ground with actual economic incentives, giving developers insights into how their features will perform in a real-world environment. +## Understanding Your Runtime -4. **Polkadot**: After passing tests on Westend and Kusama, features are considered ready for deployment to Polkadot, the live production network. +The runtime is the core logic of your blockchain—it processes transactions, manages state, and enforces the rules that govern your network. When a transaction arrives at your blockchain, the [`frame_executive`](https://paritytech.github.io/polkadot-sdk/master/frame_executive/index.html){target=\_blank} pallet receives it and routes it to the appropriate pallet for execution. - In addition, parachain developers can leverage local TestNets like [Zombienet](#zombienet) and deploy upgrades on parachain TestNets. +Think of your runtime as a collection of specialized modules, each handling a different aspect of your blockchain. Need token balances? Use the Balances pallet. Want governance? Add the Governance pallets. Need something custom? Create your own pallet. By mixing and matching these modules, you build a runtime that's efficient, secure, and tailored to your use case. -5. **Paseo**: For parachain and dApp developers, Paseo serves as a community-run TestNet that mirrors Polkadot's runtime. Like Westend for core protocol development, Paseo provides a testing ground for parachain development without affecting live networks. +## Runtime Architecture -!!!note - The Rococo TestNet deprecation date was October 14, 2024. Teams should use Westend for Polkadot protocol and feature testing and Paseo for chain development-related testing. +The following diagram shows how FRAME components work together to form your runtime: -## Polkadot Development Networks +![](/images/parachains/customize-runtime/index/frame-overview-01.webp) -Development and testing are crucial to building robust dApps and parachains and performing network upgrades within the Polkadot ecosystem. To achieve this, developers can leverage various networks and tools that provide a risk-free environment for experimentation and validation before deploying features to live networks. These networks help avoid the costs and risks associated with real tokens, enabling testing for functionalities like governance, cross-chain messaging, and runtime upgrades. +The main components are: -## Kusama Network +- **`frame_executive`**: Routes all incoming transactions to the correct pallet for execution. +- **Pallets**: Domain-specific modules that implement your blockchain's features and business logic. +- **`frame_system`**: Provides core runtime primitives and storage. +- **`frame_support`**: Utilities and macros that simplify pallet development. -Kusama is the experimental version of Polkadot, designed for developers who want to move quickly and test their applications in a real-world environment with economic incentives. Kusama serves as a production-grade testing ground where developers can deploy features and upgrades with the pressure of game theory and economics in mind. It mirrors Polkadot but operates as a more flexible space for innovation. +## Building Blocks: Pallets -The native token for Kusama is KSM. For more information about KSM, visit the [Native Assets](https://wiki.polkadot.com/kusama/kusama-getting-started/){target=\_blank} page. +[Pallets](https://paritytech.github.io/polkadot-sdk/master/polkadot_sdk_docs/polkadot_sdk/frame_runtime/pallet/index.html){target=\_blank} are the fundamental units of runtime customization. Each pallet encapsulates specific functionality and can be independently developed, tested, and integrated. -## Test Networks +A pallet can implement virtually any blockchain feature you need: -The following test networks provide controlled environments for testing upgrades and new features. TestNet tokens are available from the [Polkadot faucet](https://faucet.polkadot.io/){target=\_blank}. +- Expose new transactions that users can submit. +- Store data on-chain. +- Enforce business rules and validation logic. +- Emit events to notify users of state changes. +- Handle errors gracefully. -### Westend +### Pre-Built Pallets vs. Custom Pallets -Westend is Polkadot's primary permanent TestNet. Unlike temporary test networks, Westend is not reset to the genesis block, making it an ongoing environment for testing Polkadot core features. Managed by Parity Technologies, Westend ensures that developers can test features in a real-world simulation without using actual tokens. +FRAME provides a comprehensive library of [pre-built pallets](https://github.com/paritytech/polkadot-sdk/tree/polkadot-stable2506-2/substrate/frame){target=\_blank} for common blockchain features, including consensus, staking, balances, governance, and more. These pallets are battle-tested, optimized, and ready to use. -The native token for Westend is WND. More details about WND can be found on the [Native Assets](https://wiki.polkadot.com/learn/learn-dot/#__tabbed_2_2){target=\_blank} page. +However, you're not limited to pre-built functionality. When pre-built pallets don't meet your needs, you can create custom pallets with entirely custom logic. The real power of FRAME is the flexibility to use pre-built modules for standard features while building your own for unique requirements. -### Paseo +### Pallet Structure -[Paseo](https://github.com/paseo-network){target=\_blank} is a community-managed TestNet designed for parachain and dApp developers. It mirrors Polkadot's runtime and is maintained by Polkadot community members. Paseo provides a dedicated space for parachain developers to test their applications in a Polkadot-like environment without the risks associated with live networks. +FRAME uses Rust macros extensively, allowing you to focus on your pallet's logic while the framework handles boilerplate and integration code. -The native token for Paseo is PAS. Additional information on PAS is available on the [Native Assets](https://wiki.polkadot.com/learn/learn-dot/#__tabbed_2_1){target=\_blank} page. +A typical pallet looks like this: -## Local Test Networks +```rust +pub use pallet::*; -Local test networks are an essential part of the development cycle for blockchain developers using the Polkadot SDK. They allow for fast, iterative testing in controlled, private environments without connecting to public TestNets. Developers can quickly spin up local instances to experiment, debug, and validate their code before deploying to larger TestNets like Westend or Paseo. Two key tools for local network testing are Zombienet and Chopsticks. +#[frame_support::pallet] +pub mod pallet { + use frame_support::pallet_prelude::*; + use frame_system::pallet_prelude::*; -### Zombienet - -[Zombienet](https://github.com/paritytech/zombienet){target=\_blank} is a flexible testing framework for Polkadot SDK-based blockchains. It enables developers to create and manage ephemeral, short-lived networks. This feature makes Zombienet particularly useful for quick iterations, as it allows you to run multiple local networks concurrently, mimicking different runtime conditions. Whether you're developing a parachain or testing your custom blockchain logic, Zombienet gives you the tools to automate local testing. - -Key features of Zombienet include: - -- Creating dynamic, local networks with different configurations. -- Running parachains and relay chains in a simulated environment. -- Efficient testing of network components like cross-chain messaging and governance. - -Zombienet is ideal for developers looking to test quickly and thoroughly before moving to more resource-intensive public TestNets. - -### Chopsticks - -[Chopsticks](https://github.com/AcalaNetwork/chopsticks){target=\_blank} is a tool designed to create forks of Polkadot SDK-based blockchains, allowing developers to interact with network forks as part of their testing process. This capability makes Chopsticks a powerful option for testing upgrades, runtime changes, or cross-chain applications in a forked network environment. - -Key features of Chopsticks include: - -- Forking live Polkadot SDK-based blockchains for isolated testing. -- Simulating cross-chain messages in a private, controlled setup. -- Debugging network behavior by interacting with the fork in real-time. - -Chopsticks provides a controlled environment for developers to safely explore the effects of runtime changes. It ensures that network behavior is tested and verified before upgrades are deployed to live networks. - - ---- - -Page Title: Node and Runtime - -- Source (raw): https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/reference-parachains-node-and-runtime.md -- Canonical (HTML): https://docs.polkadot.com/reference/parachains/node-and-runtime/ -- Summary: Learn how Polkadot SDK-based nodes function, how the client and runtime are separated, and how they communicate using SCALE-encoded data. - -# Node and Runtime - -## Introduction - -Every blockchain platform relies on a decentralized network of computers, called nodes, that communicate with each other about transactions and blocks. In this context, a node refers to the software running on the connected devices rather than the physical or virtual machines in the network. - -Polkadot SDK-based nodes consist of two main components, each with distinct responsibilities: the client (also called node) and the runtime. - -If the system were a monolithic protocol, any modification would require updating the entire system. Instead, Polkadot achieves true upgradeability by defining an immutable meta-protocol (the client) and a protocol (the runtime) that can be upgraded independently. - -This separation gives the [Polkadot Relay Chain](/polkadot-protocol/architecture/polkadot-chain){target=\_blank} and all connected [parachains](/polkadot-protocol/architecture/parachains){target=\_blank} an evolutionary advantage over other blockchain platforms. - -## Architectural Principles - -The Polkadot SDK-based blockchain architecture is fundamentally built on two distinct yet interconnected components: - -- Client (Meta-protocol): - - Handles the foundational infrastructure of the blockchain. - - Manages runtime execution, networking, consensus, and other off-chain components. - - Provides an immutable base layer that ensures network stability. - - Upgradable only through hard forks. - -- Runtime (Protocol): - - Defines the blockchain's state transition logic. - - Determines the specific rules and behaviors of the blockchain. - - Compiled to WebAssembly (Wasm) for platform-independent execution. - - Capable of being upgraded without network-wide forking. - -### Advantages of this Architecture - -- **Forkless upgrades**: Runtime can be updated without disrupting the entire network. -- **Modularity**: Clear separation allows independent development of client and runtime. -- **Flexibility**: Enables rapid iteration and evolution of blockchain logic. -- **Performance**: WebAssembly compilation provides efficient, cross-platform execution. - -## Node (Client) - -The node, also known as the client, is the core component responsible for executing the Wasm runtime and orchestrating various essential blockchain components. It ensures the correct execution of the state transition function and manages multiple critical subsystems, including: - -- **Wasm execution**: Runs the blockchain runtime, which defines the state transition rules. -- **Database management**: Stores blockchain data. -- **Networking**: Facilitates peer-to-peer communication, block propagation, and transaction gossiping. -- **Transaction pool (Mempool)**: Manages pending transactions before they are included in a block. -- **Consensus mechanism**: Ensures agreement on the blockchain state across nodes. -- **RPC services**: Provides external interfaces for applications and users to interact with the node. - -## Runtime - -The runtime is more than just a set of rules. It's the fundamental logic engine that defines a blockchain's entire behavior. In Polkadot SDK-based blockchains, the runtime represents a complete, self-contained description of the blockchain's state transition function. - -### Characteristics - -The runtime is distinguished by three key characteristics: - -- **Business logic**: Defines the complete application-specific blockchain behavior. -- **WebAssembly compilation**: Ensures platform-independent, secure execution. -- **On-chain storage**: Stored within the blockchain's state, allowing dynamic updates. - -### Key Functions - -The runtime performs several critical functions, such as: - -- Define state transition rules. -- Implement blockchain-specific logic. -- Manage account interactions. -- Control transaction processing. -- Define governance mechanisms. -- Handle custom pallets and modules. - -## Communication Between Node and Runtime - -The client and runtime communicate exclusively using [SCALE-encoded](/polkadot-protocol/parachain-basics/data-encoding){target=\_blank} communication. This ensures efficient and compact data exchange between the two components. - -### Runtime APIs - -The Runtime API consists of well-defined functions and constants a client assumes are implemented in the Runtime Wasm blob. These APIs enable the client to interact with the runtime to execute blockchain operations and retrieve information. The client invokes these APIs to: - -- Build, execute, and finalize blocks. -- Access metadata. -- Access consensus related information. -- Handle transaction execution. - -### Host Functions - -During execution, the runtime can access certain external client functionalities via host functions. The specific functions the client exposes allow the runtime to perform operations outside the WebAssembly domain. Host functions enable the runtime to: - -- Perform cryptographic operations. -- Access the current blockchain state. -- Handle storage modifications. -- Allocate memory. - - ---- - -Page Title: On-Chain Governance Overview - -- Source (raw): https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/reference-governance.md -- Canonical (HTML): https://docs.polkadot.com/reference/governance/ -- Summary: Discover Polkadot’s cutting-edge OpenGov system, enabling transparent, decentralized decision-making through direct democracy and flexible governance tracks. - -# On-Chain Governance - -## Introduction - -Polkadot’s governance system exemplifies decentralized decision-making, empowering its community of stakeholders to shape the network’s future through active participation. The latest evolution, OpenGov, builds on Polkadot’s foundation by providing a more inclusive and efficient governance model. - -This guide will explain the principles and structure of OpenGov and walk you through its key components, such as Origins, Tracks, and Delegation. You will learn about improvements over earlier governance systems, including streamlined voting processes and enhanced stakeholder participation. - -With OpenGov, Polkadot achieves a flexible, scalable, and democratic governance framework that allows multiple proposals to proceed simultaneously, ensuring the network evolves in alignment with its community's needs. - -## Governance Evolution - -Polkadot’s governance journey began with [Governance V1](https://wiki.polkadot.com/learn/learn-polkadot-opengov/#governance-summary){target=\_blank}, a system that proved effective in managing treasury funds and protocol upgrades. However, it faced limitations, such as: - -- Slow voting cycles, causing delays in decision-making. -- Inflexibility in handling multiple referendums, restricting scalability. - -To address these challenges, Polkadot introduced OpenGov, a governance model designed for greater inclusivity, efficiency, and scalability. OpenGov replaces the centralized structures of Governance V1, such as the Council and Technical Committee, with a fully decentralized and dynamic framework. - -For a full comparison of the historic and current governance models, visit the [Gov1 vs. Polkadot OpenGov](https://wiki.polkadot.com/learn/learn-polkadot-opengov/#gov1-vs-polkadot-opengov){target=\_blank} section of the Polkadot Wiki. - -## OpenGov Key Features - -OpenGov transforms Polkadot’s governance into a decentralized, stakeholder-driven model, eliminating centralized decision-making bodies like the Council. Key enhancements include: - -- **Decentralization**: Shifts all decision-making power to the public, ensuring a more democratic process. -- **Enhanced delegation**: Allows users to delegate their votes to trusted experts across specific governance tracks. -- **Simultaneous referendums**: Multiple proposals can progress at once, enabling faster decision-making. -- **Polkadot Technical Fellowship**: A broad, community-driven group replacing the centralized Technical Committee. - -This new system ensures Polkadot governance remains agile and inclusive, even as the ecosystem grows. - -## Origins and Tracks - -In OpenGov, origins and tracks are central to managing proposals and votes. - -- **Origin**: Determines the authority level of a proposal (e.g., Treasury, Root) which decides the track of all referendums from that origin. -- **Track**: Define the procedural flow of a proposal, such as voting duration, approval thresholds, and enactment timelines. - -Developers must be aware that referendums from different origins and tracks will take varying amounts of time to reach approval and enactment. The [Polkadot Technical Fellowship](https://wiki.polkadot.com/learn/learn-polkadot-technical-fellowship/){target=\_blank} has the option to shorten this timeline by whitelisting a proposal and allowing it to be enacted through the [Whitelist Caller](https://wiki.polkadot.com/learn/learn-polkadot-opengov-origins/#whitelisted-caller){target=\_blank} origin. - -Visit [Origins and Tracks Info](https://wiki.polkadot.com/learn/learn-polkadot-opengov/#origins-and-tracks){target=\_blank} for details on current origins and tracks, associated terminology, and parameters. - -## Referendums - -In OpenGov, anyone can submit a referendum, fostering an open and participatory system. The timeline for a referendum depends on the privilege level of the origin with more significant changes offering more time for community voting and participation before enactment. - -The timeline for an individual referendum includes four distinct periods: - -- **Lead-in**: A minimum amount of time to allow for community participation, available room in the origin, and payment of the decision deposit. Voting is open during this period. -- **Decision**: Voting continues. -- **Confirmation**: Referendum must meet [approval and support](https://wiki.polkadot.com/learn/learn-polkadot-opengov/#approval-and-support){target=\_blank} criteria during entire period to avoid rejection. -- **Enactment**: Changes approved by the referendum are executed. - -### Vote on Referendums - -Voters can vote with their tokens on each referendum. Polkadot uses a voluntary token locking mechanism, called conviction voting, as a way for voters to increase their voting power. A token holder signals they have a stronger preference for approving a proposal based upon their willingness to lock up tokens. Longer voluntary token locks are seen as a signal of continual approval and translate to increased voting weight. - -See [Voting on a Referendum](https://wiki.polkadot.com/learn/learn-polkadot-opengov/#voting-on-a-referendum){target=\_blank} for a deeper look at conviction voting and related token locks. - -### Delegate Voting Power - -The OpenGov system also supports multi-role delegations, allowing token holders to assign their voting power on different tracks to entities with expertise in those areas. - -For example, if a token holder lacks the technical knowledge to evaluate proposals on the [Root track](https://wiki.polkadot.com/learn/learn-polkadot-opengov-origins/#root){target=\_blank}, they can delegate their voting power for that track to an expert they trust to vote in the best interest of the network. This ensures informed decision-making across tracks while maintaining flexibility for token holders. - -Visit [Multirole Delegation](https://wiki.polkadot.com/learn/learn-polkadot-opengov/#multirole-delegation){target=\_blank} for more details on delegating voting power. - -### Cancel a Referendum - -Polkadot OpenGov has two origins for rejecting ongoing referendums: - -- [**Referendum Canceller**](https://wiki.polkadot.com/learn/learn-polkadot-opengov-origins/#referendum-canceller){target=\_blank}: Cancels an active referendum when non-malicious errors occur and refunds the deposits to the originators. -- [**Referendum Killer**](https://wiki.polkadot.com/learn/learn-polkadot-opengov-origins/#referendum-killer){target=\_blank}: Used for urgent, malicious cases this origin instantly terminates an active referendum and slashes deposits. - -See [Cancelling, Killing, and Blacklisting](https://wiki.polkadot.com/learn/learn-polkadot-opengov/#cancelling-killing--blacklisting){target=\_blank} for additional information on rejecting referendums. - -## Additional Resources - -- **[Democracy pallet](https://github.com/paritytech/polkadot-sdk/tree/polkadot-stable2506-2/substrate/frame/democracy/src){target=\_blank}**: Handles administration of general stakeholder voting. -- **[Gov2: Polkadot’s Next Generation of Decentralised Governance](https://medium.com/polkadot-network/gov2-polkadots-next-generation-of-decentralised-governance-4d9ef657d11b){target=\_blank}**: Medium article by Gavin Wood. -- **[Polkadot Direction](https://matrix.to/#/#Polkadot-Direction:parity.io){target=\_blank}**: Matrix Element client. -- **[Polkassembly](https://polkadot.polkassembly.io/){target=\_blank}**: OpenGov dashboard and UI. -- **[Polkadot.js Apps Governance](https://polkadot.js.org/apps/#/referenda){target=\_blank}**: Overview of active referendums. - - ---- - -Page Title: Overview of FRAME - -- Source (raw): https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/parachains-customize-runtime.md -- Canonical (HTML): https://docs.polkadot.com/parachains/customize-runtime/ -- Summary: Learn how Polkadot SDK’s FRAME framework simplifies blockchain development with modular pallets and support libraries for efficient runtime design. - -# Customize Your Runtime - -## Introduction - -A blockchain runtime is more than just a fixed set of rules—it's a dynamic foundation that you can shape to match your specific needs. With Polkadot SDK's [FRAME (Framework for Runtime Aggregation of Modularized Entities)](https://paritytech.github.io/polkadot-sdk/master/polkadot_sdk_docs/polkadot_sdk/frame_runtime/index.html){target=\_blank}, customizing your runtime is straightforward and modular. Instead of building everything from scratch, you combine pre-built pallets with your own custom logic to create a runtime suited to your blockchain's purpose. - - - -This overview explains how runtime customization works, introduces the building blocks you'll use, and guides you through the key patterns for extending your runtime. - -## Understanding Your Runtime - -The runtime is the core logic of your blockchain—it processes transactions, manages state, and enforces the rules that govern your network. When a transaction arrives at your blockchain, the [`frame_executive`](https://paritytech.github.io/polkadot-sdk/master/frame_executive/index.html){target=\_blank} pallet receives it and routes it to the appropriate pallet for execution. - -Think of your runtime as a collection of specialized modules, each handling a different aspect of your blockchain. Need token balances? Use the Balances pallet. Want governance? Add the Governance pallets. Need something custom? Create your own pallet. By mixing and matching these modules, you build a runtime that's efficient, secure, and tailored to your use case. - -## Runtime Architecture - -The following diagram shows how FRAME components work together to form your runtime: - -![](/images/parachains/customize-runtime/index/frame-overview-01.webp) - -The main components are: - -- **`frame_executive`**: Routes all incoming transactions to the correct pallet for execution. -- **Pallets**: Domain-specific modules that implement your blockchain's features and business logic. -- **`frame_system`**: Provides core runtime primitives and storage. -- **`frame_support`**: Utilities and macros that simplify pallet development. - -## Building Blocks: Pallets - -[Pallets](https://paritytech.github.io/polkadot-sdk/master/polkadot_sdk_docs/polkadot_sdk/frame_runtime/pallet/index.html){target=\_blank} are the fundamental units of runtime customization. Each pallet encapsulates specific functionality and can be independently developed, tested, and integrated. - -A pallet can implement virtually any blockchain feature you need: - -- Expose new transactions that users can submit. -- Store data on-chain. -- Enforce business rules and validation logic. -- Emit events to notify users of state changes. -- Handle errors gracefully. - -### Pre-Built Pallets vs. Custom Pallets - -FRAME provides a comprehensive library of [pre-built pallets](https://github.com/paritytech/polkadot-sdk/tree/polkadot-stable2506-2/substrate/frame){target=\_blank} for common blockchain features, including consensus, staking, balances, governance, and more. These pallets are battle-tested, optimized, and ready to use. - -However, you're not limited to pre-built functionality. When pre-built pallets don't meet your needs, you can create custom pallets with entirely custom logic. The real power of FRAME is the flexibility to use pre-built modules for standard features while building your own for unique requirements. - -### Pallet Structure - -FRAME uses Rust macros extensively, allowing you to focus on your pallet's logic while the framework handles boilerplate and integration code. - -A typical pallet looks like this: - -```rust -pub use pallet::*; - -#[frame_support::pallet] -pub mod pallet { - use frame_support::pallet_prelude::*; - use frame_system::pallet_prelude::*; - - #[pallet::pallet] - #[pallet::generate_store(pub(super) trait Store)] - pub struct Pallet(_); + #[pallet::pallet] + #[pallet::generate_store(pub(super) trait Store)] + pub struct Pallet(_); #[pallet::config] // snip #[pallet::event] // snip @@ -3512,867 +2782,45 @@ For a comprehensive reference, see the [`pallet_macros` documentation](https://p ## How Runtime Customization Works -Customizing your runtime typically follows these patterns: - -**Adding Pre-Built Pallets**: Select pallets from the FRAME library and integrate them into your runtime configuration. This is the fastest way to add functionality. - -**Creating Custom Pallets**: Write custom pallets for features that don't exist in the pre-built library. Custom pallets follow the same structure as pre-built ones and integrate seamlessly. - -**Combining Multiple Pallets**: Layer multiple pallets together to create complex behaviors. Pallets can call each other and share storage when needed. - -**Configuring Pallet Parameters**: Most pallets are configurable—you can adjust their behavior through configuration traits without modifying their code. - -The following diagram illustrates how pallets combine to form a complete runtime: - -![](/images/parachains/customize-runtime/index/frame-overview-02.webp) - -## Starting Templates - -The easiest way to begin customizing your runtime is with a starter template. These templates provide a pre-configured foundation so you can focus on customization rather than setup. - -- **[Polkadot SDK Parachain Template](https://github.com/paritytech/polkadot-sdk-parachain-template){target=\_blank}**: The recommended choice for most developers, it includes pre-configured pallets for common features (balances, block production, governance), a complete runtime setup, and built-in parachain consensus support. This template offers the best balance of features and learning opportunities. - -- **[Polkadot SDK Minimal Template](https://github.com/paritytech/polkadot-sdk-minimal-template){target=\_blank}**: Provides a bare-bones runtime with only essential components. Choose this if you want maximum flexibility and prefer building from a clean slate. - -- **[Polkadot SDK Solochain Template](https://github.com/paritytech/polkadot-sdk/tree/master/templates/solochain){target=\_blank}**: Designed for building standalone blockchains with moderate features, simple consensus, and several core pallets. Use this if you want a sovereign blockchain independent of a relay chain. - -- **[OpenZeppelin Runtime Templates](https://github.com/OpenZeppelin/polkadot-runtime-templates){target=\_blank}**: Provides security-focused configurations following industry best practices. The [generic-template](https://github.com/OpenZeppelin/polkadot-runtime-templates/tree/main/generic-template){target=\_blank} includes curated pallet selections and production-ready defaults—ideal if security is your top priority. - -## Key Customization Scenarios - -This section covers the most common customization patterns you'll encounter: - -- **[Add Existing Pallets to Your Runtime](/parachains/customize-runtime/add-existing-pallets/)**: Integrate pre-built pallets from the FRAME library with minimal configuration. - -- **[Add Multiple Instances of a Pallet](/parachains/customize-runtime/add-pallet-instances/)**: Run multiple instances of the same pallet with different configurations—useful for multi-token systems or parallel features. - -- **[Add Smart Contract Functionality](/parachains/customize-runtime/add-smart-contract-functionality/)**: Enable smart contract execution on your parachain using Contracts pallets. - -- **[Create Custom Pallets](/parachains/customize-runtime/pallet-development/create-a-pallet/)**: Build entirely custom pallets for features unique to your blockchain. - -- **[Test Your Runtime](/parachains/customize-runtime/pallet-development/pallet-testing/)**: Unit test pallets and mock complete runtimes to ensure everything works correctly. - - ---- - -Page Title: Overview of the Polkadot Relay Chain - -- Source (raw): https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/reference-polkadot-hub-consensus-and-security-relay-chain.md -- Canonical (HTML): https://docs.polkadot.com/reference/polkadot-hub/consensus-and-security/relay-chain/ -- Summary: Explore Polkadot's core architecture, including its multi-chain vision, shared security, and the DOT token's governance and staking roles. - -# Overview - -## Introduction - -Polkadot is a next-generation blockchain protocol designed to support a multi-chain future by enabling secure communication and interoperability between different blockchains. Built as a Layer-0 protocol, Polkadot introduces innovations like application-specific Layer-1 chains ([parachains](/polkadot-protocol/architecture/parachains/){targe=\_blank}), shared security through [Nominated Proof of Stake (NPoS)](/reference/glossary/#nominated-proof-of-stake-npos){target=\_blank}, and cross-chain interactions via its native [Cross-Consensus Messaging Format (XCM)](/parachains/interoperability/get-started/){target=\_blank}. - -This guide covers key aspects of Polkadot’s architecture, including its high-level protocol structure, blockspace commoditization, and the role of its native token, DOT, in governance, staking, and resource allocation. - -## Polkadot 1.0 - -Polkadot 1.0 represents the state of Polkadot as of 2023, coinciding with the release of [Polkadot runtime v1.0.0](https://github.com/paritytech/polkadot/releases/tag/v1.0.0){target=\_blank}. This section will focus on Polkadot 1.0, along with philosophical insights into network resilience and blockspace. - -As a Layer-0 blockchain, Polkadot contributes to the multi-chain vision through several key innovations and initiatives, including: - -- **Application-specific Layer-1 blockchains (parachains)**: Polkadot's sharded network allows for parallel transaction processing, with shards that can have unique state transition functions, enabling custom-built L1 chains optimized for specific applications. - -- **Shared security and scalability**: L1 chains connected to Polkadot benefit from its [Nominated Proof of Stake (NPoS)](/reference/polkadot-hub/consensus-and-security/pos-consensus/#nominated-proof-of-stake){target=\_blank} system, providing security out-of-the-box without the need to bootstrap their own. - -- **Secure interoperability**: Polkadot's native interoperability enables seamless data and value exchange between parachains. This interoperability can also be used outside of the ecosystem for bridging with external networks. - -- **Resilient infrastructure**: Decentralized and scalable, Polkadot ensures ongoing support for development and community initiatives via its on-chain [treasury](https://wiki.polkadot.com/learn/learn-polkadot-opengov-treasury/){target=\_blank} and governance. - -- **Rapid L1 development**: The [Polkadot SDK](/reference/parachains/){target=\_blank} allows fast, flexible creation and deployment of Layer-1 chains. - -- **Cultivating the next generation of Web3 developers**: Polkadot supports the growth of Web3 core developers through initiatives such as. - - - [Polkadot Blockchain Academy](https://polkadot.com/blockchain-academy){target=\_blank} - - [EdX courses](https://www.edx.org/school/web3x){target=\_blank} - - Rust and Substrate courses (coming soon) - -### High-Level Architecture - -Polkadot features a chain that serves as the central component of the system. This chain is depicted as a ring encircled by several parachains that are connected to it. - -According to Polkadot's design, any blockchain that can compile to WebAssembly (Wasm) and adheres to the Parachains Protocol becomes a parachain on the Polkadot network. - -Here’s a high-level overview of the Polkadot protocol architecture: - -![](/images/reference/polkadot-hub/consensus-and-security/relay-chain/relay-chain-01.webp){ style="background:white" } - -Parachains propose blocks to Polkadot validators, who check for availability and validity before finalizing them. With the relay chain providing security, collators—full nodes of parachains—can focus on their tasks without needing strong incentives. - -The [Cross-Consensus Messaging Format (XCM)](/parachains/interoperability/get-started/){target=\_blank} allows parachains to exchange messages freely, leveraging the chain's security for trust-free communication. - -In order to interact with chains that want to use their own finalization process (e.g., Bitcoin), Polkadot has [bridges](/reference/parachains/interoperability/#bridges-connecting-external-networks){target=\_blank} that offer two-way compatibility, meaning that transactions can be made between different parachains. - -### Polkadot's Additional Functionalities - -Historically, obtaining core slots on Polkadot chain relied upon crowdloans and auctions. Chain cores were leased through auctions for three-month periods, up to a maximum of two years. Crowdloans enabled users to securely lend funds to teams for lease deposits in exchange for pre-sale tokens, which is the only way to access slots on Polkadot 1.0. Auctions are now deprecated in favor of [coretime](/polkadot-protocol/architecture/system-chains/coretime/){target=\_blank}. - -Additionally, the chain handles [staking](https://wiki.polkadot.com/learn/learn-staking/){target=\_blank}, [accounts](/reference/parachains/accounts/){target=\_blank}, balances, and [governance](/reference/governance/){target=\_blank}. - -#### Agile Coretime - -The new and more efficient way of obtaining core on Polkadot is to go through the process of purchasing coretime. - -[Agile coretime](/reference/polkadot-hub/consensus-and-security/agile-coretime/){target=\_blank} improves the efficient use of Polkadot's network resources and offers economic flexibility for developers, extending Polkadot's capabilities far beyond the original vision outlined in the [whitepaper](https://polkadot.com/papers/Polkadot-whitepaper.pdf){target=\_blank}. - -It enables parachains to purchase monthly "bulk" allocations of coretime (the time allocated for utilizing a core, measured in Polkadot relay chain blocks), ensuring heavy-duty parachains that can author a block every six seconds with [Asynchronous Backing](https://wiki.polkadot.com/learn/learn-async-backing/#asynchronous-backing){target=\_blank} can reliably renew their coretime each month. Although six-second block times are now the default, parachains have the option of producing blocks less frequently. - -Renewal orders are prioritized over new orders, offering stability against price fluctuations and helping parachains budget more effectively for project costs. - -### Polkadot's Resilience - -Decentralization is a vital component of blockchain networks, but it comes with trade-offs: - -- An overly decentralized network may face challenges in reaching consensus and require significant energy to operate. -- Also, a network that achieves consensus quickly risks centralization, making it easier to manipulate or attack. - -A network should be decentralized enough to prevent manipulative or malicious influence. In this sense, decentralization is a tool for achieving resilience. - -Polkadot 1.0 currently achieves resilience through several strategies: - -- **Nominated Proof of Stake (NPoS)**: Ensures that the stake per validator is maximized and evenly distributed among validators. - -- **Decentralized nodes**: Designed to encourage operators to join the network. This program aims to expand and diversify the validators in the ecosystem who aim to become independent of the program during their term. Feel free to explore more about the program on the official [Decentralized Nodes](https://nodes.web3.foundation/){target=\_blank} page. - -- **On-chain treasury and governance**: Known as [OpenGov](/reference/governance/){target=\_blank}, this system allows every decision to be made through public referenda, enabling any token holder to cast a vote. - -### Polkadot's Blockspace - -Polkadot 1.0’s design allows for the commoditization of blockspace. - -Blockspace is a blockchain's capacity to finalize and commit operations, encompassing its security, computing, and storage capabilities. Its characteristics can vary across different blockchains, affecting security, flexibility, and availability. - -- **Security**: Measures the robustness of blockspace in Proof of Stake (PoS) networks linked to the stake locked on validator nodes, the variance in stake among validators, and the total number of validators. It also considers social centralization (how many validators are owned by single operators) and physical centralization (how many validators run on the same service provider). - -- **Flexibility**: Reflects the functionalities and types of data that can be stored, with high-quality data essential to avoid bottlenecks in critical processes. - -- **Availability**: Indicates how easily users can access blockspace. It should be easily accessible, allowing diverse business models to thrive, ideally regulated by a marketplace based on demand and supplemented by options for "second-hand" blockspace. - -Polkadot is built on core blockspace principles, but there's room for improvement. Tasks like balance transfers, staking, and governance are managed on the relay chain. - -Delegating these responsibilities to [system chains](/polkadot-protocol/architecture/system-chains/){target=\_blank} could enhance flexibility and allow the relay chain to concentrate on providing shared security and interoperability. - -For more information about blockspace, watch [Robert Habermeier’s interview](https://www.youtube.com/watch?v=e1vISppPwe4){target=\_blank} or read his [technical blog post](https://www.rob.tech/blog/polkadot-blockspace-over-blockchains/){target=\_blank}. - -## DOT Token - -DOT is the native token of the Polkadot network, much like BTC for Bitcoin and Ether for the Ethereum blockchain. DOT has 10 decimals, uses the Planck base unit, and has a balance type of `u128`. The same is true for Kusama's KSM token with the exception of having 12 decimals. - -### Redenomination of DOT - -Polkadot conducted a community poll, which ended on 27 July 2020 at block 888,888, to decide whether to redenominate the DOT token. The stakeholders chose to redenominate the token, changing the value of 1 DOT from 1e12 plancks to 1e10 plancks. - -Importantly, this did not affect the network's total number of base units (plancks); it only affects how a single DOT is represented. The redenomination became effective 72 hours after transfers were enabled, occurring at block 1,248,328 on 21 August 2020 around 16:50 UTC. - -### The Planck Unit - -The smallest unit of account balance on Polkadot SDK-based blockchains (such as Polkadot and Kusama) is called _Planck_, named after the Planck length, the smallest measurable distance in the physical universe. - -Similar to how BTC's smallest unit is the Satoshi and ETH's is the Wei, Polkadot's native token DOT equals 1e10 Planck, while Kusama's native token KSM equals 1e12 Planck. - -### Uses for DOT - -DOT serves three primary functions within the Polkadot network: - -- **Governance**: It is used to participate in the governance of the network. -- **Staking**: DOT is staked to support the network's operation and security. -- **Buying coretime**: Used to purchase coretime in-bulk or on-demand and access the chain to benefit from Polkadot's security and interoperability. - -Additionally, DOT can serve as a transferable token. For example, DOT, held in the treasury, can be allocated to teams developing projects that benefit the Polkadot ecosystem. - -## JAM and the Road Ahead - -The Join-Accumulate Machine (JAM) represents a transformative redesign of Polkadot's core architecture, envisioned as the successor to the current relay chain. Unlike traditional blockchain architectures, JAM introduces a unique computational model that processes work through two primary functions: - -- **Join**: Handles data integration. -- **Accumulate**: Folds computations into the chain's state. - -JAM removes many of the opinions and constraints of the current relay chain while maintaining its core security properties. Expected improvements include: - -- **Permissionless code execution**: JAM is designed to be more generic and flexible, allowing for permissionless code execution through services that can be deployed without governance approval. -- **More effective block time utilization**: JAM's efficient pipeline processing model places the prior state root in block headers instead of the posterior state root, enabling more effective utilization of block time for computations. - -This architectural evolution promises to enhance Polkadot's scalability and flexibility while maintaining robust security guarantees. JAM is planned to be rolled out to Polkadot as a single, complete upgrade rather than a stream of smaller updates. This approach seeks to minimize the developer overhead required to address any breaking changes. - - ---- - -Page Title: Parachains Overview - -- Source (raw): https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/reference-parachains.md -- Canonical (HTML): https://docs.polkadot.com/reference/parachains/ -- Summary: Learn about parachains, specialized blockchains on Polkadot that gain shared security and interoperability. Discover how they work and the tools to build them. - -# Parachains Overview - -## Introduction - -A parachain is a specialized blockchain that connects to the Polkadot relay chain, benefiting from shared security, interoperability, and scalability. Parachains are built using the [Polkadot SDK](https://github.com/paritytech/polkadot-sdk){target=\_blank}, a powerful toolkit written in Rust that provides everything needed to create custom blockchain logic while integrating seamlessly with the Polkadot network. - -Unlike standalone blockchains that must bootstrap their own validator sets and security, parachains leverage Polkadot's pooled security model. This allows parachain developers to focus on their application-specific functionality rather than consensus and security infrastructure. Parachains can communicate with each other through Cross-Consensus Messaging (XCM), enabling seamless interoperability across the Polkadot ecosystem. - -Key capabilities that parachains provide include: - -- **Shared security**: Inherit security from Polkadot's validator set without maintaining your own. -- **Interoperability**: Communicate trustlessly with other parachains via XCM. -- **Scalability**: Process transactions in parallel with other parachains. -- **Customization**: Build application-specific logic tailored to your use case. -- **Upgradeability**: Upgrade runtime logic without hard forks. - -## Polkadot SDK: Parachain Architecture - -Building a parachain involves understanding and utilizing several key components of the Polkadot SDK: - -![](/images/reference/parachains/index/overview-01.webp) - -- **[Substrate](https://paritytech.github.io/polkadot-sdk/master/polkadot_sdk_docs/polkadot_sdk/substrate/index.html){target=\_blank}**: The foundation providing core blockchain primitives and libraries. -- **[FRAME](https://paritytech.github.io/polkadot-sdk/master/polkadot_sdk_docs/polkadot_sdk/frame_runtime/index.html){target=\_blank}**: A modular framework for building your parachain's runtime logic. -- **[Cumulus](https://paritytech.github.io/polkadot-sdk/master/polkadot_sdk_docs/polkadot_sdk/cumulus/index.html){target=\_blank}**: Essential libraries and pallets that enable parachain functionality. -- **[XCM (Cross Consensus Messaging)](https://paritytech.github.io/polkadot-sdk/master/polkadot_sdk_docs/polkadot_sdk/xcm/index.html){target=\_blank}**: The messaging format for communicating with other parachains and the relay chain. -- **[Polkadot](https://paritytech.github.io/polkadot-sdk/master/polkadot_sdk_docs/polkadot_sdk/polkadot/index.html){target=\_blank}**: The relay chain that provides security and coordination. - -### Substrate: The Foundation - -Substrate provides the core infrastructure that every parachain is built upon. It handles the low-level blockchain functionality, allowing you to focus on your application's unique features. Substrate includes implementations for networking, database management, consensus participation, and the execution environment for your runtime. - -Every Polkadot SDK node consists of two main components: - -- **Client (Host)**: Handles infrastructure services. - - - Native binary that runs on validator and collator nodes. - - Executes the Wasm-compiled runtime. - - Manages networking, database, mempool, and block production. - - Interfaces with the relay chain for validation. - -- **Runtime (State Transition Function)**: Contains your business logic. - - - Defines how your Polkadot SDK node processes transactions. - - Compiled to [Wasm](https://webassembly.org/){target=\_blank} for deterministic execution. - - Stored on-chain and upgradeable via governance. - -```mermaid -%%{init: {'flowchart': {'padding': 5, 'nodeSpacing': 50, 'rankSpacing': 10}}}%% -graph TB - classDef title font-size:20px,font-weight:bold,stroke-width:0px - classDef clientStyle font-size:16px,font-weight:bold - classDef clientSubNodeStyle margin-top:10px - classDef runtimeCallExecutorStyle padding-top:10px - - subgraph sg1[Parachain
Node] - direction TB - - I[RuntimeCall Executor] - B[Wasm Runtime - STF] - - subgraph sg2[Client] - direction TB - C[Network and Blockchain
Infrastructure Services
+ Relay Chain Interface] - end - - I --> B - end - - class sg1 title - class sg2 clientStyle - class C clientSubNodeStyle - class I runtimeCallExecutorStyle - -``` - -### FRAME: Building Blocks for Your Runtime - -FRAME provides modular components called [pallets](/reference/glossary#pallet){target=\_blank} that you can compose to build your parachain's runtime. Each pallet provides specific functionality that you can customize and configure for your needs. This modular approach allows you to quickly assemble complex functionality without writing everything from scratch. - -```mermaid -graph LR - subgraph SP["Parachain Runtime"] - direction LR - Timestamp ~~~ Aura ~~~ ParachainSystem - Balances ~~~ TransactionPayment ~~~ Sudo - subgraph Timestamp["Timestamp"] - SS1[Custom Config] - end - subgraph Aura["Aura"] - SS2[Custom Config] - end - subgraph ParachainSystem["Parachain System"] - SS3[Custom Config] - end - subgraph Balances["Balances"] - SS4[Custom Config] - end - subgraph TransactionPayment["Transaction Payment"] - SS5[Custom Config] - end - subgraph Sudo["Sudo"] - SS6[Custom Config] - end - style Timestamp stroke:#FF69B4 - style Aura stroke:#FF69B4 - style ParachainSystem stroke:#FF69B4 - style Balances stroke:#FF69B4 - style TransactionPayment stroke:#FF69B4 - style Sudo stroke:#FF69B4 - style SS1 stroke-dasharray: 5 - style SS2 stroke-dasharray: 5 - style SS3 stroke-dasharray: 5 - style SS4 stroke-dasharray: 5 - style SS5 stroke-dasharray: 5 - style SS6 stroke-dasharray: 5 - - end - subgraph AP["Available FRAME Pallets"] - direction LR - A1[Aura]~~~A2[Parachain
System]~~~A3[Transaction
Payment]~~~A4[Sudo] - B1[Identity]~~~B2[Balances]~~~B3[Assets]~~~B4[EVM] - C1[Timestamp]~~~C2[Staking]~~~C3[Contracts]~~~C4[and more...] - end - AP --> SP -``` - -### Cumulus: Parachain-Specific Functionality - -Cumulus is what transforms a Polkadot SDK-based runtime into a parachain-capable runtime. It provides the essential components for communicating with the relay chain, participating in Polkadot's consensus, and handling parachain-specific operations like block validation and collation. - -Key Cumulus components include: - -- **Parachain system pallet**: Core parachain functionality and relay chain communication. -- **Collator consensus**: Block production logic for parachain collators. -- **Relay chain interface**: APIs for interacting with the Polkadot relay chain. -- **Validation data**: Handling proof-of-validity data required by relay chain validators. - -## Where to Go Next - -Building a parachain requires understanding the relationship between your chain and the Polkadot relay chain. The Polkadot SDK provides all the tools needed to design custom runtime logic, enable cross-chain communication, and deploy your parachain to production. - -The following sections provide detailed guidance on each aspect of parachain development, from initial design through deployment and ongoing maintenance. - -
- -- Guide __Launch a Simple Parachain__ - - --- - - Walk through the complete parachain launch flow: from setup and deployment to obtaining coretime. - - [:octicons-arrow-right-24: Deploy](/parachains/launch-a-parachain/set-up-the-parachain-template/) - - -- Guide __Customize Your Runtime__ - - --- - - Design your parachain's runtime logic and choose appropriate pallets for your use case. - - [:octicons-arrow-right-24: Get Started](/parachains/customize-runtime/) - -- Guide __Interoperability__ - - --- - - Implement XCM for trustless cross-chain communication with other parachains. - - [:octicons-arrow-right-24: Learn More](/parachains/interoperability/get-started/) - -- Guide __Runtime Upgrades__ - - --- - - Upgrade your parachain's runtime without hard forks using forkless upgrade mechanisms. - - [:octicons-arrow-right-24: Maintain](/parachains/runtime-maintenance/runtime-upgrades/) - -
- - ---- - -Page Title: Polkadot SDK Accounts - -- Source (raw): https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/reference-parachains-accounts.md -- Canonical (HTML): https://docs.polkadot.com/reference/parachains/accounts/ -- Summary: Learn about account structures, balances, and address formats in the Polkadot SDK, including how to manage lifecycle, references, and balances. - -# Accounts - -## Introduction - -Accounts are essential for managing identity, transactions, and governance on the network in the Polkadot SDK. Understanding these components is critical for seamless development and operation on the network, whether you're building or interacting with Polkadot-based chains. - -This page will guide you through the essential aspects of accounts, including their data structure, balance types, reference counters, and address formats. You’ll learn how accounts are managed within the runtime, how balances are categorized, and how addresses are encoded and validated. - -## Account Data Structure - -Accounts are foundational to any blockchain, and the Polkadot SDK provides a flexible management system. This section explains how the Polkadot SDK defines accounts and manages their lifecycle through data structures within the runtime. - -### Account - -The [`Account` data type](https://paritytech.github.io/polkadot-sdk/master/frame_system/pallet/type.Account.html){target=\_blank} is a storage map within the [System pallet](https://paritytech.github.io/polkadot-sdk/master/src/frame_system/lib.rs.html){target=\_blank} that links an account ID to its corresponding data. This structure is fundamental for mapping account-related information within the chain. - -The code snippet below shows how accounts are defined: - -```rs - /// The full account information for a particular account ID. - #[pallet::storage] - #[pallet::getter(fn account)] - pub type Account = StorageMap< - _, - Blake2_128Concat, - T::AccountId, - AccountInfo, - ValueQuery, - >; -``` - -The preceding code block defines a storage map named `Account`. The `StorageMap` is a type of on-chain storage that maps keys to values. In the `Account` map, the key is an account ID, and the value is the account's information. Here, `T` represents the generic parameter for the runtime configuration, which is defined by the pallet's configuration trait (`Config`). - -The `StorageMap` consists of the following parameters: - -- **`_`**: Used in macro expansion and acts as a placeholder for the storage prefix type. Tells the macro to insert the default prefix during expansion. -- **`Blake2_128Concat`**: The hashing function applied to keys in the storage map. -- **`T: :AccountId`**: Represents the key type, which corresponds to the account’s unique ID. -- **`AccountInfo`**: The value type stored in the map. For each account ID, the map stores an `AccountInfo` struct containing: - - - **`T::Nonce`**: A nonce for the account, which is incremented with each transaction to ensure transaction uniqueness. - - **`T: :AccountData`**: Custom account data defined by the runtime configuration, which could include balances, locked funds, or other relevant information. - -- **`ValueQuery`**: Defines how queries to the storage map behave when no value is found; returns a default value instead of `None`. - -For a detailed explanation of storage maps, see the [`StorageMap`](https://paritytech.github.io/polkadot-sdk/master/frame_support/storage/types/struct.StorageMap.html){target=\_blank} entry in the Rust docs. - -### Account Info - -The `AccountInfo` structure is another key element within the [System pallet](https://paritytech.github.io/polkadot-sdk/master/src/frame_system/lib.rs.html){target=\_blank}, providing more granular details about each account's state. This structure tracks vital data, such as the number of transactions and the account’s relationships with other modules. - -```rs -/// Information of an account. -#[derive(Clone, Eq, PartialEq, Default, RuntimeDebug, Encode, Decode, TypeInfo, MaxEncodedLen)] -pub struct AccountInfo { - /// The number of transactions this account has sent. - pub nonce: Nonce, - /// The number of other modules that currently depend on this account's existence. The account - /// cannot be reaped until this is zero. - pub consumers: RefCount, - /// The number of other modules that allow this account to exist. The account may not be reaped - /// until this and `sufficients` are both zero. - pub providers: RefCount, - /// The number of modules that allow this account to exist for their own purposes only. The - /// account may not be reaped until this and `providers` are both zero. - pub sufficients: RefCount, - /// The additional data that belongs to this account. Used to store the balance(s) in a lot of - /// chains. - pub data: AccountData, -} -``` - -The `AccountInfo` structure includes the following components: - -- **`nonce`**: Tracks the number of transactions initiated by the account, which ensures transaction uniqueness and prevents replay attacks. -- **`consumers`**: Counts how many other modules or pallets rely on this account’s existence. The account cannot be removed from the chain (reaped) until this count reaches zero. -- **`providers`**: Tracks how many modules permit this account’s existence. An account can only be reaped once both `providers` and `sufficients` are zero. -- **`sufficients`**: Represents the number of modules that allow the account to exist for internal purposes, independent of any other modules. -- **`AccountData`**: A flexible data structure that can be customized in the runtime configuration, usually containing balances or other user-specific data. - -This structure helps manage an account's state and prevents its premature removal while it is still referenced by other on-chain data or modules. The [`AccountInfo`](https://paritytech.github.io/polkadot-sdk/master/frame_system/struct.AccountInfo.html){target=\_blank} structure can vary as long as it satisfies the trait bounds defined by the `AccountData` associated type in the [`frame-system::pallet::Config`](https://paritytech.github.io/polkadot-sdk/master/frame_system/pallet/trait.Config.html){target=\_blank} trait. - -### Account Reference Counters - -Polkadot SDK uses reference counters to track an account’s dependencies across different runtime modules. These counters ensure that accounts remain active while data is associated with them. - -The reference counters include: - -- **`consumers`**: Prevents account removal while other pallets still rely on the account. -- **`providers`**: Ensures an account is active before other pallets store data related to it. -- **`sufficients`**: Indicates the account’s independence, ensuring it can exist even without a native token balance, such as when holding sufficient alternative assets. - -#### Providers Reference Counters - -The `providers` counter ensures that an account is ready to be depended upon by other runtime modules. For example, it is incremented when an account has a balance above the existential deposit, which marks the account as active. - -The system requires this reference counter to be greater than zero for the `consumers` counter to be incremented, ensuring the account is stable before any dependencies are added. - -#### Consumers Reference Counters - -The `consumers` counter ensures that the account cannot be reaped until all references to it across the runtime have been removed. This check prevents the accidental deletion of accounts that still have active on-chain data. - -It is the user’s responsibility to clear out any data from other runtime modules if they wish to remove their account and reclaim their existential deposit. - -#### Sufficients Reference Counter - -The `sufficients` counter tracks accounts that can exist independently without relying on a native account balance. This is useful for accounts holding other types of assets, like tokens, without needing a minimum balance in the native token. - -For instance, the [Assets pallet](https://paritytech.github.io/polkadot-sdk/master/pallet_assets/index.html){target=\_blank}, may increment this counter for an account holding sufficient tokens. - -#### Account Deactivation - -In Polkadot SDK-based chains, an account is deactivated when its reference counters (such as `providers`, `consumers`, and `sufficient`) reach zero. These counters ensure the account remains active as long as other runtime modules or pallets reference it. - -When all dependencies are cleared and the counters drop to zero, the account becomes deactivated and may be removed from the chain (reaped). This is particularly important in Polkadot SDK-based blockchains, where accounts with balances below the existential deposit threshold are pruned from storage to conserve state resources. - -Each pallet that references an account has cleanup functions that decrement these counters when the pallet no longer depends on the account. Once these counters reach zero, the account is marked for deactivation. - -#### Updating Counters - -The Polkadot SDK provides runtime developers with various methods to manage account lifecycle events, such as deactivation or incrementing reference counters. These methods ensure that accounts cannot be reaped while still in use. - -The following helper functions manage these counters: - -- **`inc_consumers()`**: Increments the `consumer` reference counter for an account, signaling that another pallet depends on it. -- **`dec_consumers()`**: Decrements the `consumer` reference counter, signaling that a pallet no longer relies on the account. -- **`inc_providers()`**: Increments the `provider` reference counter, ensuring the account remains active. -- **`dec_providers()`**: Decrements the `provider` reference counter, allowing for account deactivation when no longer in use. -- **`inc_sufficients()`**: Increments the `sufficient` reference counter for accounts that hold sufficient assets. -- **`dec_sufficients()`**: Decrements the `sufficient` reference counter. - -To ensure proper account cleanup and lifecycle management, a corresponding decrement should be made for each increment action. - -The `System` pallet offers three query functions to assist developers in tracking account states: - -- **[`can_inc_consumer()`](https://paritytech.github.io/polkadot-sdk/master/frame_system/pallet/struct.Pallet.html#method.can_inc_consumer){target=\_blank}**: Checks if the account can safely increment the consumer reference. -- **[`can_dec_provider()`](https://paritytech.github.io/polkadot-sdk/master/frame_system/pallet/struct.Pallet.html#method.can_dec_provider){target=\_blank}**: Ensures that no consumers exist before allowing the decrement of the provider counter. -- **[`is_provider_required()`](https://paritytech.github.io/polkadot-sdk/master/frame_system/pallet/struct.Pallet.html#method.is_provider_required){target=\_blank}**: Verifies whether the account still has any active consumer references. - -This modular and flexible system of reference counters tightly controls the lifecycle of accounts in Polkadot SDK-based blockchains, preventing the accidental removal or retention of unneeded accounts. You can refer to the [System pallet Rust docs](https://paritytech.github.io/polkadot-sdk/master/frame_system/pallet/struct.Pallet.html){target=\_blank} for more details. - - -## Account Balance Types - -In the Polkadot ecosystem, account balances are categorized into different types based on how the funds are utilized and their availability. These balance types determine the actions that can be performed, such as transferring tokens, paying transaction fees, or participating in governance activities. Understanding these balance types helps developers manage user accounts and implement balance-dependent logic. - -!!! note "A more efficient distribution of account balance types is in development" - Soon, pallets in the Polkadot SDK will implement the [`Fungible` trait](https://paritytech.github.io/polkadot-sdk/master/frame_support/traits/tokens/fungible/index.html){target=\_blank} (see the [tracking issue](https://github.com/paritytech/polkadot-sdk/issues/226){target=\_blank} for more details). For example, the [`transaction-storage`](https://paritytech.github.io/polkadot-sdk/master/pallet_transaction_storage/index.html){target=\_blank} pallet changed the implementation of the [`Currency`](https://paritytech.github.io/polkadot-sdk/master/frame_support/traits/tokens/currency/index.html){target=\_blank} trait (see the [Refactor transaction storage pallet to use fungible traits](https://github.com/paritytech/polkadot-sdk/pull/1800){target=\_blank} PR for further details): - - ```rust - type BalanceOf = <::Currency as Currency<::AccountId>>::Balance; - ``` - - To the [`Fungible`](https://paritytech.github.io/polkadot-sdk/master/frame_support/traits/tokens/fungible/index.html){target=\_blank} trait: - - ```rust - type BalanceOf = <::Currency as FnInspect<::AccountId>>::Balance; - ``` - - This update will enable more efficient use of account balances, allowing the free balance to be utilized for on-chain activities such as setting proxies and managing identities. - -### Balance Types - -The five main balance types are: - -- **Free balance**: Represents the total tokens available to the account for any on-chain activity, including staking, governance, and voting. However, it may not be fully spendable or transferrable if portions of it are locked or reserved. -- **Locked balance**: Portions of the free balance that cannot be spent or transferred because they are tied up in specific activities like [staking](https://wiki.polkadot.com/learn/learn-staking/#nominating-validators){target=\_blank}, [vesting](https://wiki.polkadot.com/learn/learn-guides-transfers/#vested-transfers-with-the-polkadot-js-ui){target=\_blank}, or participating in [governance](https://wiki.polkadot.com/learn/learn-polkadot-opengov/#voting-on-a-referendum){target=\_blank}. While the tokens remain part of the free balance, they are non-transferable for the duration of the lock. -- **Reserved balance**: Funds locked by specific system actions, such as setting up an [identity](https://wiki.polkadot.com/learn/learn-identity/){target=\_blank}, creating [proxies](https://wiki.polkadot.com/learn/learn-proxies/){target=\_blank}, or submitting [deposits for governance proposals](https://wiki.polkadot.com/learn/learn-guides-polkadot-opengov/#claiming-opengov-deposits){target=\_blank}. These tokens are not part of the free balance and cannot be spent unless they are unreserved. -- **Spendable balance**: The portion of the free balance that is available for immediate spending or transfers. It is calculated by subtracting the maximum of locked or reserved amounts from the free balance, ensuring that existential deposit limits are met. -- **Untouchable balance**: Funds that cannot be directly spent or transferred but may still be utilized for on-chain activities, such as governance participation or staking. These tokens are typically tied to certain actions or locked for a specific period. - -The spendable balance is calculated as follows: - -```text -spendable = free - max(locked - reserved, ED) -``` - -Here, `free`, `locked`, and `reserved` are defined above. The `ED` represents the [existential deposit](https://wiki.polkadot.com/learn/learn-accounts/#existential-deposit-and-reaping){target=\_blank}, the minimum balance required to keep an account active and prevent it from being reaped. You may find you can't see all balance types when looking at your account via a wallet. Wallet providers often display only spendable, locked, and reserved balances. - -### Locks - -Locks are applied to an account's free balance, preventing that portion from being spent or transferred. Locks are automatically placed when an account participates in specific on-chain activities, such as staking or governance. Although multiple locks may be applied simultaneously, they do not stack. Instead, the largest lock determines the total amount of locked tokens. - -Locks follow these basic rules: - -- If different locks apply to varying amounts, the largest lock amount takes precedence. -- If multiple locks apply to the same amount, the lock with the longest duration governs when the balance can be unlocked. - -#### Locks Example - -Consider an example where an account has 80 DOT locked for both staking and governance purposes like so: - -- 80 DOT is staked with a 28-day lock period. -- 24 DOT is locked for governance with a 1x conviction and a 7-day lock period. -- 4 DOT is locked for governance with a 6x conviction and a 224-day lock period. - -In this case, the total locked amount is 80 DOT because only the largest lock (80 DOT from staking) governs the locked balance. These 80 DOT will be released at different times based on the lock durations. In this example, the 24 DOT locked for governance will be released first since the shortest lock period is seven days. The 80 DOT stake with a 28-day lock period is released next. Now, all that remains locked is the 4 DOT for governance. After 224 days, all 80 DOT (minus the existential deposit) will be free and transferable. - -![Illustration of Lock Example](/images/reference/parachains/accounts/accounts-01.webp) - -#### Edge Cases for Locks - -In scenarios where multiple convictions and lock periods are active, the lock duration and amount are determined by the longest period and largest amount. For example, if you delegate with different convictions and attempt to undelegate during an active lock period, the lock may be extended for the full amount of tokens. For a detailed discussion on edge case lock behavior, see this [Stack Exchange post](https://substrate.stackexchange.com/questions/5067/delegating-and-undelegating-during-the-lock-period-extends-it-for-the-initial-am){target=\_blank}. - -### Balance Types on Polkadot.js - -Polkadot.js provides a user-friendly interface for managing and visualizing various account balances on Polkadot and Kusama networks. When interacting with Polkadot.js, you will encounter multiple balance types that are critical for understanding how your funds are distributed and restricted. This section explains how different balances are displayed in the Polkadot.js UI and what each type represents. - -![](/images/reference/parachains/accounts/accounts-02.webp) - -The most common balance types displayed on Polkadot.js are: - -- **Total balance**: The total number of tokens available in the account. This includes all tokens, whether they are transferable, locked, reserved, or vested. However, the total balance does not always reflect what can be spent immediately. In this example, the total balance is 0.6274 KSM. - -- **Transferable balance**: Shows how many tokens are immediately available for transfer. It is calculated by subtracting the locked and reserved balances from the total balance. For example, if an account has a total balance of 0.6274 KSM and a transferable balance of 0.0106 KSM, only the latter amount can be sent or spent freely. - -- **Vested balance**: Tokens that allocated to the account but released according to a specific schedule. Vested tokens remain locked and cannot be transferred until fully vested. For example, an account with a vested balance of 0.2500 KSM means that this amount is owned but not yet transferable. - -- **Locked balance**: Tokens that are temporarily restricted from being transferred or spent. These locks typically result from participating in staking, governance, or vested transfers. In Polkadot.js, locked balances do not stack—only the largest lock is applied. For instance, if an account has 0.5500 KSM locked for governance and staking, the locked balance would display 0.5500 KSM, not the sum of all locked amounts. - -- **Reserved balance**: Refers to tokens locked for specific on-chain actions, such as setting an identity, creating a proxy, or making governance deposits. Reserved tokens are not part of the free balance, but can be freed by performing certain actions. For example, removing an identity would unreserve those funds. - -- **Bonded balance**: The tokens locked for staking purposes. Bonded tokens are not transferable until they are unbonded after the unbonding period. - -- **Redeemable balance**: The number of tokens that have completed the unbonding period and are ready to be unlocked and transferred again. For example, if an account has a redeemable balance of 0.1000 KSM, those tokens are now available for spending. - -- **Democracy balance**: Reflects the number of tokens locked for governance activities, such as voting on referenda. These tokens are locked for the duration of the governance action and are only released after the lock period ends. - -By understanding these balance types and their implications, developers and users can better manage their funds and engage with on-chain activities more effectively. - -## Address Formats - -The SS58 address format is a core component of the Polkadot SDK that enables accounts to be uniquely identified across Polkadot-based networks. This format is a modified version of Bitcoin's Base58Check encoding, specifically designed to accommodate the multi-chain nature of the Polkadot ecosystem. SS58 encoding allows each chain to define its own set of addresses while maintaining compatibility and checksum validation for security. - -### Basic Format - -SS58 addresses consist of three main components: - -```text -base58encode(concat(,
, )) -``` - -- **Address type**: A byte or set of bytes that define the network (or chain) for which the address is intended. This ensures that addresses are unique across different Polkadot SDK-based chains. -- **Address**: The public key of the account encoded as bytes. -- **Checksum**: A hash-based checksum which ensures that addresses are valid and unaltered. The checksum is derived from the concatenated address type and address components, ensuring integrity. - -The encoding process transforms the concatenated components into a Base58 string, providing a compact and human-readable format that avoids easily confused characters (e.g., zero '0', capital 'O', lowercase 'l'). This encoding function ([`encode`](https://docs.rs/bs58/latest/bs58/fn.encode.html){target=\_blank}) is implemented exactly as defined in Bitcoin and IPFS specifications, using the same alphabet as both implementations. - -For more details about the SS58 address format implementation, see the [`Ss58Codec`](https://paritytech.github.io/polkadot-sdk/master/sp_core/crypto/trait.Ss58Codec.html){target=\_blank} trait in the Rust Docs. - -### Address Type - -The address type defines how an address is interpreted and to which network it belongs. Polkadot SDK uses different prefixes to distinguish between various chains and address formats: - -- **Address types `0-63`**: Simple addresses, commonly used for network identifiers. -- **Address types `64-127`**: Full addresses that support a wider range of network identifiers. -- **Address types `128-255`**: Reserved for future address format extensions. - -For example, Polkadot’s main network uses an address type of 0, while Kusama uses 2. This ensures that addresses can be used without confusion between networks. - -The address type is always encoded as part of the SS58 address, making it easy to quickly identify the network. Refer to the [SS58 registry](https://github.com/paritytech/ss58-registry){target=\_blank} for the canonical listing of all address type identifiers and how they map to Polkadot SDK-based networks. - -### Address Length - -SS58 addresses can have different lengths depending on the specific format. Address lengths range from as short as 3 to 35 bytes, depending on the complexity of the address and network requirements. This flexibility allows SS58 addresses to adapt to different chains while providing a secure encoding mechanism. - -| Total | Type | Raw account | Checksum | -|-------|------|-------------|----------| -| 3 | 1 | 1 | 1 | -| 4 | 1 | 2 | 1 | -| 5 | 1 | 2 | 2 | -| 6 | 1 | 4 | 1 | -| 7 | 1 | 4 | 2 | -| 8 | 1 | 4 | 3 | -| 9 | 1 | 4 | 4 | -| 10 | 1 | 8 | 1 | -| 11 | 1 | 8 | 2 | -| 12 | 1 | 8 | 3 | -| 13 | 1 | 8 | 4 | -| 14 | 1 | 8 | 5 | -| 15 | 1 | 8 | 6 | -| 16 | 1 | 8 | 7 | -| 17 | 1 | 8 | 8 | -| 35 | 1 | 32 | 2 | - -SS58 addresses also support different payload sizes, allowing a flexible range of account identifiers. - -### Checksum Types - -A checksum is applied to validate SS58 addresses. Polkadot SDK uses a Blake2b-512 hash function to calculate the checksum, which is appended to the address before encoding. The checksum length can vary depending on the address format (e.g., 1-byte, 2-byte, or longer), providing varying levels of validation strength. - -The checksum ensures that an address is not modified or corrupted, adding an extra layer of security for account management. - -### Validating Addresses - -SS58 addresses can be validated using the subkey command-line interface or the Polkadot.js API. These tools help ensure an address is correctly formatted and valid for the intended network. The following sections will provide an overview of how validation works with these tools. - -#### Using Subkey - -[Subkey](https://paritytech.github.io/polkadot-sdk/master/subkey/index.html){target=\_blank} is a CLI tool provided by Polkadot SDK for generating and managing keys. It can inspect and validate SS58 addresses. - -The `inspect` command gets a public key and an SS58 address from the provided secret URI. The basic syntax for the `subkey inspect` command is: - -```bash -subkey inspect [flags] [options] uri -``` - -For the `uri` command-line argument, you can specify the secret seed phrase, a hex-encoded private key, or an SS58 address. If the input is a valid address, the `subkey` program displays the corresponding hex-encoded public key, account identifier, and SS58 addresses. - -For example, to inspect the public keys derived from a secret seed phrase, you can run a command similar to the following: - -```bash -subkey inspect "caution juice atom organ advance problem want pledge someone senior holiday very" -``` - -The command displays output similar to the following: - -
- subkey inspect "caution juice atom organ advance problem want pledge someone senior holiday very" - Secret phrase `caution juice atom organ advance problem want pledge someone senior holiday very` is account: - Secret seed: 0xc8fa03532fb22ee1f7f6908b9c02b4e72483f0dbd66e4cd456b8f34c6230b849 - Public key (hex): 0xd6a3105d6768e956e9e5d41050ac29843f98561410d3a47f9dd5b3b227ab8746 - Public key (SS58): 5Gv8YYFu8H1btvmrJy9FjjAWfb99wrhV3uhPFoNEr918utyR - Account ID: 0xd6a3105d6768e956e9e5d41050ac29843f98561410d3a47f9dd5b3b227ab8746 - SS58 Address: 5Gv8YYFu8H1btvmrJy9FjjAWfb99wrhV3uhPFoNEr918utyR -
- -The `subkey` program assumes an address is based on a public/private key pair. If you inspect an address, the command returns the 32-byte account identifier. - -However, not all addresses in Polkadot SDK-based networks are based on keys. - -Depending on the command-line options you specify and the input you provided, the command output might also display the network for which the address has been encoded. For example: - -```bash -subkey inspect "12bzRJfh7arnnfPPUZHeJUaE62QLEwhK48QnH9LXeK2m1iZU" -``` - -The command displays output similar to the following: - -
- subkey inspect "12bzRJfh7arnnfPPUZHeJUaE62QLEwhK48QnH9LXeK2m1iZU" - Public Key URI `12bzRJfh7arnnfPPUZHeJUaE62QLEwhK48QnH9LXeK2m1iZU` is account: - Network ID/Version: polkadot - Public key (hex): 0x46ebddef8cd9bb167dc30878d7113b7e168e6f0646beffd77d69d39bad76b47a - Account ID: 0x46ebddef8cd9bb167dc30878d7113b7e168e6f0646beffd77d69d39bad76b47a - Public key (SS58): 12bzRJfh7arnnfPPUZHeJUaE62QLEwhK48QnH9LXeK2m1iZU - SS58 Address: 12bzRJfh7arnnfPPUZHeJUaE62QLEwhK48QnH9LXeK2m1iZU -
- -#### Using Polkadot.js API - -To verify an address in JavaScript or TypeScript projects, you can use the functions built into the [Polkadot.js API](https://polkadot.js.org/docs/){target=\_blank}. For example: - -```js -// Import Polkadot.js API dependencies -const { decodeAddress, encodeAddress } = require('@polkadot/keyring'); -const { hexToU8a, isHex } = require('@polkadot/util'); - -// Specify an address to test. -const address = 'INSERT_ADDRESS_TO_TEST'; - -// Check address -const isValidSubstrateAddress = () => { - try { - encodeAddress(isHex(address) ? hexToU8a(address) : decodeAddress(address)); - - return true; - } catch (error) { - return false; - } -}; - -// Query result -const isValid = isValidSubstrateAddress(); -console.log(isValid); - -``` - -If the function returns `true`, the specified address is a valid address. - -#### Other SS58 Implementations - -Support for encoding and decoding Polkadot SDK SS58 addresses has been implemented in several other languages and libraries. - -- **Crystal**: [`wyhaines/base58.cr`](https://github.com/wyhaines/base58.cr){target=\_blank} -- **Go**: [`itering/subscan-plugin`](https://github.com/itering/subscan-plugin){target=\_blank} -- **Python**: [`polkascan/py-scale-codec`](https://github.com/polkascan/py-scale-codec){target=\_blank} -- **TypeScript**: [`subsquid/squid-sdk`](https://github.com/subsquid/squid-sdk){target=\_blank} - - ---- - -Page Title: Randomness - -- Source (raw): https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/reference-parachains-randomness.md -- Canonical (HTML): https://docs.polkadot.com/reference/parachains/randomness/ -- Summary: Explore the importance of randomness in PoS blockchains, focusing on Polkadot’s VRF-based approach to ensure fairness and security in validator selection. - -# Randomness - -## Introduction - -Randomness is crucial in Proof of Stake (PoS) blockchains to ensure a fair and unpredictable distribution of validator duties. However, computers are inherently deterministic, meaning the same input always produces the same output. What we typically refer to as "random" numbers on a computer are actually pseudo-random. These numbers rely on an initial "seed," which can come from external sources like [atmospheric noise](https://www.random.org/randomness/){target=\_blank}, [heart rates](https://mdpi.altmetric.com/details/47574324){target=\_blank}, or even [lava lamps](https://en.wikipedia.org/wiki/Lavarand){target=\_blank}. While this may seem random, given the same "seed," the same sequence of numbers will always be generated. - -In a global blockchain network, relying on real-world entropy for randomness isn’t feasible because these inputs vary by time and location. If nodes use different inputs, blockchains can fork. Hence, real-world randomness isn't suitable for use as a seed in blockchain systems. - -Currently, two primary methods for generating randomness in blockchains are used: [`RANDAO`](#randao) and [`VRF`](#vrf) (Verifiable Random Function). Polkadot adopts the `VRF` approach for its randomness. - -## VRF - -A Verifiable Random Function (VRF) is a cryptographic function that generates a random number and proof that ensures the submitter produced the number. This proof allows anyone to verify the validity of the random number. - -Polkadot's VRF is similar to the one used in [**Ouroboros Praos**](https://eprint.iacr.org/2017/573.pdf){target=\_blank}, which secures randomness for block production in systems like [BABE](/reference/polkadot-hub/consensus-and-security/pos-consensus/#block-production-babe){target=\_blank} (Polkadot’s block production mechanism). - -The key difference is that Polkadot's VRF doesn’t rely on a central clock—avoiding the issue of whose clock to trust. Instead, it uses its own past results and slot numbers to simulate time and determine future outcomes. - -### How VRF Works - -Slots on Polkadot are discrete units of time, each lasting six seconds, and can potentially hold a block. Multiple slots form an epoch, with 2400 slots making up one four-hour epoch. - -In each slot, validators execute a "die roll" using a VRF. The VRF uses three inputs: - -1. A "secret key," unique to each validator, is used for the die roll. -2. An epoch randomness value, derived from the hash of VRF outputs from blocks two epochs ago (N-2), so past randomness influences the current epoch (N). -3. The current slot number. - -This process helps maintain fair randomness across the network. - -Here is a graphical representation: - -![](/images/reference/parachains/randomness/randomness-01.webp) - -The VRF produces two outputs: a result (the random number) and a proof (verifying that the number was generated correctly). - -The result is checked by the validator against a protocol threshold. If it's below the threshold, the validator becomes a candidate for block production in that slot. - -The validator then attempts to create a block, submitting it along with the `PROOF` and `RESULT`. +Customizing your runtime typically follows these patterns: -So, VRF can be expressed like: +**Adding Pre-Built Pallets**: Select pallets from the FRAME library and integrate them into your runtime configuration. This is the fastest way to add functionality. -`(RESULT, PROOF) = VRF(SECRET, EPOCH_RANDOMNESS_VALUE, CURRENT_SLOT_NUMBER)` +**Creating Custom Pallets**: Write custom pallets for features that don't exist in the pre-built library. Custom pallets follow the same structure as pre-built ones and integrate seamlessly. -Put simply, performing a "VRF roll" generates a random number along with proof that the number was genuinely produced and not arbitrarily chosen. +**Combining Multiple Pallets**: Layer multiple pallets together to create complex behaviors. Pallets can call each other and share storage when needed. -After executing the VRF, the `RESULT` is compared to a protocol-defined `THRESHOLD`. If the `RESULT` is below the `THRESHOLD`, the validator becomes a valid candidate to propose a block for that slot. Otherwise, the validator skips the slot. +**Configuring Pallet Parameters**: Most pallets are configurable—you can adjust their behavior through configuration traits without modifying their code. -As a result, there may be multiple validators eligible to propose a block for a slot. In this case, the block accepted by other nodes will prevail, provided it is on the chain with the latest finalized block as determined by the GRANDPA finality gadget. It's also possible for no block producers to be available for a slot, in which case the AURA consensus takes over. AURA is a fallback mechanism that randomly selects a validator to produce a block, running in parallel with BABE and only stepping in when no block producers exist for a slot. Otherwise, it remains inactive. +The following diagram illustrates how pallets combine to form a complete runtime: -Because validators roll independently, no block candidates may appear in some slots if all roll numbers are above the threshold. +![](/images/parachains/customize-runtime/index/frame-overview-02.webp) -To verify resolution of this issue and that Polkadot block times remain near constant-time, see the [PoS Consensus](/reference/polkadot-hub/consensus-and-security/pos-consensus/){target=\_blank} page of this documentation. +## Starting Templates -## RANDAO +The easiest way to begin customizing your runtime is with a starter template. These templates provide a pre-configured foundation so you can focus on customization rather than setup. -An alternative on-chain randomness method is Ethereum's RANDAO, where validators perform thousands of hashes on a seed and publish the final hash during a round. The collective input from all validators forms the random number, and as long as one honest validator participates, the randomness is secure. +- **[Polkadot SDK Parachain Template](https://github.com/paritytech/polkadot-sdk-parachain-template){target=\_blank}**: The recommended choice for most developers, it includes pre-configured pallets for common features (balances, block production, governance), a complete runtime setup, and built-in parachain consensus support. This template offers the best balance of features and learning opportunities. -To enhance security, RANDAO can optionally be combined with a Verifiable Delay Function (VDF), ensuring that randomness can't be predicted or manipulated during computation. +- **[Polkadot SDK Minimal Template](https://github.com/paritytech/polkadot-sdk-minimal-template){target=\_blank}**: Provides a bare-bones runtime with only essential components. Choose this if you want maximum flexibility and prefer building from a clean slate. -For more information about RANDAO, see the [Randomness - RANDAO](https://eth2book.info/capella/part2/building_blocks/randomness/){target=\_blank} section of the Upgrading Ethereum documentation. +- **[Polkadot SDK Solochain Template](https://github.com/paritytech/polkadot-sdk/tree/master/templates/solochain){target=\_blank}**: Designed for building standalone blockchains with moderate features, simple consensus, and several core pallets. Use this if you want a sovereign blockchain independent of a relay chain. -## VDFs +- **[OpenZeppelin Runtime Templates](https://github.com/OpenZeppelin/polkadot-runtime-templates){target=\_blank}**: Provides security-focused configurations following industry best practices. The [generic-template](https://github.com/OpenZeppelin/polkadot-runtime-templates/tree/main/generic-template){target=\_blank} includes curated pallet selections and production-ready defaults—ideal if security is your top priority. -Verifiable Delay Functions (VDFs) are time-bound computations that, even on parallel computers, take a set amount of time to complete. +## Key Customization Scenarios -They produce a unique result that can be quickly verified publicly. When combined with RANDAO, feeding RANDAO's output into a VDF introduces a delay that nullifies an attacker's chance to influence the randomness. +This section covers the most common customization patterns you'll encounter: -However, VDF likely requires specialized ASIC devices to run separately from standard nodes. +- **[Add Existing Pallets to Your Runtime](/parachains/customize-runtime/add-existing-pallets/)**: Integrate pre-built pallets from the FRAME library with minimal configuration. -!!!warning - While only one is needed to secure the system, and they will be open-source and inexpensive, running VDF devices involves significant costs without direct incentives, adding friction for blockchain users. +- **[Add Multiple Instances of a Pallet](/parachains/customize-runtime/add-pallet-instances/)**: Run multiple instances of the same pallet with different configurations—useful for multi-token systems or parallel features. -## Additional Resources +- **[Add Smart Contract Functionality](/parachains/customize-runtime/add-smart-contract-functionality/)**: Enable smart contract execution on your parachain using Contracts pallets. -For more information about the reasoning for choices made along with proofs, see Polkadot's research on blockchain randomness and sortition in the [Block production](https://research.web3.foundation/Polkadot/protocols/block-production){target=\_blank} entry of the Polkadot Wiki. +- **[Create Custom Pallets](/parachains/customize-runtime/pallet-development/create-a-pallet/)**: Build entirely custom pallets for features unique to your blockchain. -For a discussion with Web3 Foundation researchers about when and under what conditions Polkadot's randomness can be utilized, see the [Discussion on Randomness used in Polkadot](https://github.com/use-ink/ink/issues/57){target=\_blank} issue on GitHub. +- **[Test Your Runtime](/parachains/customize-runtime/pallet-development/pallet-testing/)**: Unit test pallets and mock complete runtimes to ensure everything works correctly. --- @@ -4611,514 +3059,122 @@ Page Title: Smart Contracts Cookbook - Canonical (HTML): https://docs.polkadot.com/smart-contracts/cookbook/ - Summary: Explore our full collection of tutorials and guides to learn step-by-step how to build, deploy, and work with smart contracts on Polkadot. -# Smart Contracts Cookbook - -Welcome to the Polkadot smart contracts cookbook index. - -This page contains a list of all relevant tutorials and guides to help you get started coding smart contracts and dApps in Polkadot. - - - - -## Get Tokens from the Faucet - -| Title | Difficulty | Tools | Description | -|------------------------------------|:-----------:|-------|-----------------------------------------------------------------------------------------------------------------------| -| [Faucet](/smart-contracts/faucet/) | 🟢 Beginner | N/A | Learn how to obtain test tokens from Polkadot faucets for development and testing purposes across different networks. | - -## EVM Smart Contracts - -| Title | Difficulty | Tools | Description | -|---------------------------------------------------------------------------------------------------------|:-----------:|--------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------| -| [Deploy an ERC-20 to Polkadot Hub](/smart-contracts/cookbook/smart-contracts/deploy-erc20/erc20-remix/) | 🟢 Beginner | EVM Wallet, Polkadot Remix IDE | Deploy an ERC-20 token on Polkadot Hub using PolkaVM. This guide covers contract creation, compilation, deployment, and interaction via Polkadot Remix IDE. | -| [Deploy an NFT to Polkadot Hub](/smart-contracts/cookbook/smart-contracts/deploy-nft/nft-remix/) | 🟢 Beginner | EVM Wallet, Polkadot Remix IDE | Deploy an NFT on Polkadot Hub using PolkaVM and OpenZeppelin. Learn how to compile, deploy, and interact with your contract using Polkadot Remix IDE. | - -## Port Ethereum DApps - -| Title | Difficulty | Tools | Description | -|-------------------------------------------------------------------------------------|:---------------:|---------|----------------------------------------------------------------------------------------------------------------------------------| -| [Deploying Uniswap V2 on Polkadot](/smart-contracts/cookbook/eth-dapps/uniswap-v2/) | 🟡 Intermediate | Hardhat | Learn how to deploy and test Uniswap V2 on Polkadot Hub using Hardhat, bringing AMM-based token swaps to the Polkadot ecosystem. | - - ---- - -Page Title: Smart Contracts Overview - -- Source (raw): https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/smart-contracts-overview.md -- Canonical (HTML): https://docs.polkadot.com/smart-contracts/overview/ -- Summary: Learn about smart contract development on Polkadot Hub with native PolkaVM support, dual-VM execution, and seamless cross-chain capabilities. - -# Smart Contracts on Polkadot Hub - -## Introduction - -Polkadot Hub provides a production-ready smart contract platform that combines Ethereum compatibility with the performance and cross-chain capabilities of the Polkadot ecosystem. Developers can deploy smart contracts directly on Polkadot Hub while using familiar Ethereum tooling, workflows, and programming languages. - -Built with a dual-VM approach, Polkadot Hub offers two execution backends: REVM for unmodified EVM compatibility and native PolkaVM for optimized computationally expensive workloads. This dual-VM architecture enables developers to migrate existing Ethereum contracts instantly or optimize for speed and efficiency with native execution. - -## Why Build on Polkadot Hub - -### Ethereum Compatibility - -Deploy existing Ethereum contracts with zero modifications while maintaining full compatibility with your existing development stack: - -- **Complete JSON-RPC API support**: Use MetaMask, Hardhat, Remix, Foundry, and all standard Ethereum tooling. -- **Standard libraries**: Integrate Ethers.js, Web3.js, Viem, Wagmi, and Web3.py without changes. -- **Solidity development**: Write contracts in Solidity or migrate existing code directly. -- **Familiar workflows**: Maintain your existing deployment, testing, and monitoring processes. - -### Performance Options - -Choose between two execution backends: - -- **REVM**: Run unmodified Ethereum contracts with full EVM/Ethereum compatibility. -- **PolkaVM**: Compile to optimized RISC-V bytecode for enhanced performance and lower fees while keeping Ethereum-compatibility. - -Both backends share the same RPC interface and tooling support, allowing seamless transitions. In addition, smart contracts can interact with Polkadot native services via [precompile contracts](/smart-contracts/precompiles/){target=\_blank}. - -### Cross-VM & Cross-Chain Capabilities - -Smart contracts written for one VM (for example, EVM) can interact directly with other smart contracts written for the RISC-V PolkaVM, and back. This allows to use full EVM compatible contracts but extend to heavy/complex execution workloads to the PolkaVM RISC-V backend. - -Furthermore, all smart contracts in Polkadot Hub can interact with any service in the Polkadot ecosystem through [XCM](/smart-contracts/precompiles/xcm/){target=\_blank}, enabling token transfers, remote execution, and cross-chain composability without bridges or intermediaries. - -## Other Smart Contract Environments - -Beyond Polkadot Hub's native PolkaVM support, the ecosystem offers two main alternatives for smart contract development: - -- **EVM-compatible parachains**: Provide access to Ethereum's extensive developer ecosystem, smart contract portability, and established tooling like Hardhat, Remix, Foundry, and OpenZeppelin. The main options include Moonbeam (the first full Ethereum-compatible parachain serving as an interoperability hub), Astar (featuring dual VM support for both EVM and WebAssembly contracts), and Acala (DeFi-focused with enhanced Acala EVM+ offering advanced DeFi primitives). - -- **Rust (ink!)**: ink! is a Rust-based framework that can compile to PolkaVM. It uses [`#[ink(...)]`](https://use.ink/docs/v6/macros-attributes/){target=\_blank} attribute macros to create Polkadot SDK-compatible PolkaVM bytecode, offering strong memory safety from Rust, an advanced type system, high-performance PolkaVM execution, and platform independence with sandboxed security. - -## Next Steps - -
- -- Guide __Get Started__ - - --- - - Quick-start guides for connecting, deploying, and building your first smart contract. - - [:octicons-arrow-right-24: Get Started](/smart-contracts/get-started/) - -- Guide __Cookbook__ - - --- - - Step-by-step tutorials for deploying contracts, tokens, NFTs, and full dApps. - - [:octicons-arrow-right-24: View Tutorials](/smart-contracts/cookbook/) - -- Guide __Ethereum Developers__ - - --- - - Understand key differences in accounts, fees, gas model, and deployment on Polkadot Hub. - - [:octicons-arrow-right-24: Learn More](/smart-contracts/for-eth-devs/accounts/) - -- Guide __Precompiles__ - - --- - - Discover advanced functionalities including XCM for cross-chain interactions. - - [:octicons-arrow-right-24: Explore Precompiles](/smart-contracts/precompiles/) - -
- - ---- - -Page Title: Technical Reference Overview - -- Source (raw): https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/reference.md -- Canonical (HTML): https://docs.polkadot.com/reference/ -- Summary: Learn about Polkadot's technical architecture, governance framework, parachain ecosystem, and the tools you need to build and interact with the network. - -## Introduction - -The Technical Reference section provides comprehensive documentation of Polkadot's architecture, core concepts, and development tooling. Whether you're exploring how Polkadot's relay chain coordinates parachains, understanding governance mechanisms, or building applications on the network, this reference covers the technical foundations you need. - -Polkadot is a multi-chain network that enables diverse, interconnected blockchains to share security and communicate seamlessly. Understanding how these components interact from the [relay chain](/polkadot-protocol/glossary#relay-chain){target=\_blank} that validates [parachains](/polkadot-protocol/glossary#parachain){target=\_blank} to the [governance](/reference/glossary#governance){target=\_blank} mechanisms that evolve the protocol is essential for developers, validators, and network participants. - -This guide organizes technical documentation across five core areas: Polkadot Hub, Parachains, On-Chain Governance, Glossary, and Tools, each providing detailed information on different aspects of the Polkadot ecosystem. - -## Polkadot Hub - -[Polkadot Hub](/reference/polkadot-hub/){target=\_blank} is the entry point to Polkadot for all users and application developers. It provides access to essential Web3 services, including smart contracts, staking, governance, identity management, and cross-ecosystem interoperability—without requiring you to deploy or manage a parachain. - -The Hub encompasses a set of core functionality that enables developers and users to build and interact with applications on Polkadot. Key capabilities include: - -- **Smart contracts**: Deploy Ethereum-compatible smart contracts and build decentralized applications. -- **Assets and tokens**: Create, manage, and transfer fungible tokens and NFTs across the ecosystem. -- **Staking**: Participate in network security and earn rewards by staking DOT. -- **Governance**: Vote on proposals and participate in Polkadot's decentralized decision-making through OpenGov. -- **Identity services**: Register and manage on-chain identities, enabling access to governance roles and network opportunities. -- **Cross-chain interoperability**: Leverage XCM messaging to interact securely with other chains in the Polkadot ecosystem. -- **Collectives and DAOs**: Participate in governance collectives and decentralized autonomous organizations. - -## Parachains - -[Parachains](/reference/parachains/){target=\_blank} are specialized blockchains that connect to the Polkadot relay chain, inheriting its security while maintaining their own application-specific logic. The parachains documentation covers: - -- **Accounts**: Deep dive into account types, storage, and management on parachains. -- **Blocks, transactions and fees**: Understand block production, transaction inclusion, and fee mechanisms. -- **Consensus**: Learn how parachain blocks are validated and finalized through the relay chain's consensus. -- **Chain data**: Explore data structures, storage layouts, and state management. -- **Cryptography**: Study cryptographic primitives used in Polkadot SDK-based chains. -- **Data encoding**: Understand how data is encoded and decoded for blockchain compatibility. -- **Networks**: Learn about networking protocols and peer-to-peer communication. -- **Interoperability**: Discover [Cross-Consensus Messaging (XCM)](/parachains/interoperability/get-started/){target=\_blank}, the standard for cross-chain communication. -- **Randomness**: Understand how randomness is generated and used in Polkadot chains. -- **Node and runtime**: Learn about parachain nodes, runtime environments, and the [Polkadot SDK](https://github.com/paritytech/polkadot-sdk){target=\_blank}. - -## On-Chain Governance - -[On-Chain governance](/reference/governance/){target=\_blank} is the decentralized decision-making mechanism for the Polkadot network. It manages the evolution and modification of the network's runtime logic, enabling community oversight and approval for proposed changes. The governance documentation details: - -- **OpenGov framework**: Understand Polkadot's next-generation governance system with enhanced delegation, flexible tracks, and simultaneous referendums. -- **Origins and tracks**: Learn how governance proposals are categorized, prioritized, and executed based on their privilege level and complexity. -- **Voting and delegation**: Explore conviction voting, vote delegation, and how token holders participate in governance. -- **Governance evolution**: See how Polkadot's governance has evolved from Governance V1 to the current OpenGov system. - -## Glossary - -The [Glossary](/reference/glossary/){target=\_blank} provides quick-reference definitions for Polkadot-specific terminology. Essential terms include: - -- Blockchain concepts (blocks, transactions, state) -- Consensus mechanisms (validators, collators, finality) -- Polkadot-specific terms (relay chain, parachain, XCM, FRAME) -- Network components (nodes, runtimes, storage) -- Governance terminology (origins, tracks, referendums) - -## Tools - -The [Tools](/reference/tools/){target=\_blank} section documents essential development and interaction tools for the Polkadot ecosystem: - -- **Light clients**: Lightweight solutions for interacting with the network without running full nodes. -- **JavaScript/TypeScript tools**: Libraries like [Polkadot.js API](/reference/tools/polkadot-js-api/){target=\_blank} and [PAPI](/reference/tools/papi/){target=\_blank} for building applications. -- **Rust tools**: [Polkadart](/reference/tools/polkadart/){target=\_blank} and other Rust-based libraries for SDK development. -- **Python tools**: [py-substrate-interface](/reference/tools/py-substrate-interface/){target=\_blank} for Python developers. -- **Testing and development**: Tools like [Moonwall](/reference/tools/moonwall/){target=\_blank}, [Chopsticks](/reference/tools/chopsticks/){target=\_blank}, and [Omninode](/reference/tools/omninode/){target=\_blank} for smart contract and parachain testing. -- **Indexing and monitoring**: [Sidecar](/reference/tools/sidecar/){target=\_blank} for data indexing and [Dedot](/reference/tools/dedot/){target=\_blank} for substrate interaction. -- **Cross-chain tools**: [ParaSpell](/reference/tools/paraspell/){target=\_blank} for XCM integration and asset transfers. - -## Where to Go Next - -For detailed exploration of specific areas, proceed to any of the main sections: - -
- -- Learn **Polkadot Hub** - - --- - - Understand the relay chain's role in coordinating parachains, providing shared security, and enabling governance. - - [:octicons-arrow-right-24: Reference](/reference/polkadot-hub/) - -- Learn **Parachains** - - --- - - Deep dive into parachain architecture, consensus, data structures, and building application-specific blockchains. - - [:octicons-arrow-right-24: Reference](/reference/parachains/) - -- Learn **On-Chain Governance** - - --- - - Explore Polkadot's decentralized governance framework and how to participate in network decision-making. - - [:octicons-arrow-right-24: Reference](/reference/governance/) - -- Guide **Glossary** - - --- - - Quick reference for Polkadot-specific terminology and concepts used throughout the documentation. - - [:octicons-arrow-right-24: Reference](/reference/glossary/) - -- Guide **Tools** - - --- - - Discover development tools, libraries, and frameworks for building and interacting with Polkadot. - - [:octicons-arrow-right-24: Reference](/reference/tools/) - -
- - ---- - -Page Title: Transactions - -- Source (raw): https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/reference-parachains-blocks-transactions-fees-transactions.md -- Canonical (HTML): https://docs.polkadot.com/reference/parachains/blocks-transactions-fees/transactions/ -- Summary: Learn how to construct, submit, and validate transactions in the Polkadot SDK, covering signed, unsigned, and inherent types of transactions. - -# Transactions - -## Introduction - -Transactions are essential components of blockchain networks, enabling state changes and the execution of key operations. In the Polkadot SDK, transactions, often called extrinsics, come in multiple forms, including signed, unsigned, and inherent transactions. - -This guide walks you through the different transaction types and how they're formatted, validated, and processed within the Polkadot ecosystem. You'll also learn how to customize transaction formats and construct transactions for FRAME-based runtimes, ensuring a complete understanding of how transactions are built and executed in Polkadot SDK-based chains. - -## What Is a Transaction? - -In the Polkadot SDK, transactions represent operations that modify the chain's state, bundled into blocks for execution. The term extrinsic is often used to refer to any data that originates outside the runtime and is included in the chain. While other blockchain systems typically refer to these operations as "transactions," the Polkadot SDK adopts the broader term "extrinsic" to capture the wide variety of data types that can be added to a block. - -There are three primary types of transactions (extrinsics) in the Polkadot SDK: - -- **Signed transactions**: Signed by the submitting account, often carrying transaction fees. -- **Unsigned transactions**: Submitted without a signature, often requiring custom validation logic. -- **Inherent transactions**: Typically inserted directly into blocks by block authoring nodes, without gossiping between peers. - -Each type serves a distinct purpose, and understanding when and how to use each is key to efficiently working with the Polkadot SDK. - -### Signed Transactions - -Signed transactions require an account's signature and typically involve submitting a request to execute a runtime call. The signature serves as a form of cryptographic proof that the sender has authorized the action, using their private key. These transactions often involve a transaction fee to cover the cost of execution and incentivize block producers. - -Signed transactions are the most common type of transaction and are integral to user-driven actions, such as token transfers. For instance, when you transfer tokens from one account to another, the sending account must sign the transaction to authorize the operation. - -For example, the [`pallet_balances::Call::transfer_allow_death`](https://paritytech.github.io/polkadot-sdk/master/pallet_balances/pallet/struct.Pallet.html#method.transfer_allow_death){target=\_blank} extrinsic in the Balances pallet allows you to transfer tokens. Since your account initiates this transaction, your account key is used to sign it. You'll also be responsible for paying the associated transaction fee, with the option to include an additional tip to incentivize faster inclusion in the block. - -### Unsigned Transactions - -Unsigned transactions do not require a signature or account-specific data from the sender. Unlike signed transactions, they do not come with any form of economic deterrent, such as fees, which makes them susceptible to spam or replay attacks. Custom validation logic must be implemented to mitigate these risks and ensure these transactions are secure. - -Unsigned transactions typically involve scenarios where including a fee or signature is unnecessary or counterproductive. However, due to the absence of fees, they require careful validation to protect the network. For example, [`pallet_im_online::Call::heartbeat`](https://paritytech.github.io/polkadot-sdk/master/pallet_im_online/pallet/struct.Pallet.html#method.heartbeat){target=\_blank} extrinsic allows validators to send a heartbeat signal, indicating they are active. Since only validators can make this call, the logic embedded in the transaction ensures that the sender is a validator, making the need for a signature or fee redundant. - -Unsigned transactions are more resource-intensive than signed ones because custom validation is required, but they play a crucial role in certain operational scenarios, especially when regular user accounts aren't involved. - -### Inherent Transactions - -Inherent transactions are a specialized type of unsigned transaction that is used primarily for block authoring. Unlike signed or other unsigned transactions, inherent transactions are added directly by block producers and are not broadcasted to the network or stored in the transaction queue. They don't require signatures or the usual validation steps and are generally used to insert system-critical data directly into blocks. - -A key example of an inherent transaction is inserting a timestamp into each block. The [`pallet_timestamp::Call::now`](https://paritytech.github.io/polkadot-sdk/master/pallet_timestamp/pallet/struct.Pallet.html#method.now-1){target=\_blank} extrinsic allows block authors to include the current time in the block they are producing. Since the block producer adds this information, there is no need for transaction validation, like signature verification. The validation in this case is done indirectly by the validators, who check whether the timestamp is within an acceptable range before finalizing the block. - -Another example is the [`paras_inherent::Call::enter`](https://paritytech.github.io/polkadot-sdk/master/polkadot_runtime_parachains/paras_inherent/pallet/struct.Pallet.html#method.enter){target=\_blank} extrinsic, which enables parachain collator nodes to send validation data to the relay chain. This inherent transaction ensures that the necessary parachain data is included in each block without the overhead of gossiped transactions. - -Inherent transactions serve a critical role in block authoring by allowing important operational data to be added directly to the chain without needing the validation processes required for standard transactions. - -## Transaction Formats - -Understanding the structure of signed and unsigned transactions is crucial for developers building on Polkadot SDK-based chains. Whether you're optimizing transaction processing, customizing formats, or interacting with the transaction pool, knowing the format of extrinsics, Polkadot's term for transactions, is essential. - -### Types of Transaction Formats - -In Polkadot SDK-based chains, extrinsics can fall into three main categories: - -- **Unchecked extrinsics**: Typically used for signed transactions that require validation. They contain a signature and additional data, such as a nonce and information for fee calculation. Unchecked extrinsics are named as such because they require validation checks before being accepted into the transaction pool. -- **Checked extrinsics**: Typically used for inherent extrinsics (unsigned transactions); these don't require signature verification. Instead, they carry information such as where the extrinsic originates and any additional data required for the block authoring process. -- **Opaque extrinsics**: Used when the format of an extrinsic is not yet fully committed or finalized. They are still decodable, but their structure can be flexible depending on the context. - -### Signed Transaction Data Structure - -A signed transaction typically includes the following components: - -- **Signature**: Verifies the authenticity of the transaction sender. -- **Call**: The actual function or method call the transaction is requesting (for example, transferring funds). -- **Nonce**: Tracks the number of prior transactions sent from the account, helping to prevent replay attacks. -- **Tip**: An optional incentive to prioritize the transaction in block inclusion. -- **Additional data**: Includes details such as spec version, block hash, and genesis hash to ensure the transaction is valid within the correct runtime and chain context. - -Here's a simplified breakdown of how signed transactions are typically constructed in a Polkadot SDK runtime: - -``` code - + + -``` - -Each part of the signed transaction has a purpose, ensuring the transaction's authenticity and context within the blockchain. - -### Signed Extensions - -Polkadot SDK also provides the concept of [signed extensions](https://paritytech.github.io/polkadot-sdk/master/polkadot_sdk_docs/reference_docs/signed_extensions/index.html){target=\_blank}, which allow developers to extend extrinsics with additional data or validation logic before they are included in a block. The [`SignedExtension`](https://paritytech.github.io/try-runtime-cli/sp_runtime/traits/trait.SignedExtension.html){target=\_blank} set helps enforce custom rules or protections, such as ensuring the transaction's validity or calculating priority. - -The transaction queue regularly calls signed extensions to verify a transaction's validity before placing it in the ready queue. This safeguard ensures transactions won't fail in a block. Signed extensions are commonly used to enforce validation logic and protect the transaction pool from spam and replay attacks. - -In FRAME, a signed extension can hold any of the following types by default: - -- **[`AccountId`](https://paritytech.github.io/polkadot-sdk/master/polkadot_sdk_frame/runtime/types_common/type.AccountId.html){target=\_blank}**: To encode the sender's identity. -- **[`Call`](https://paritytech.github.io/polkadot-sdk/master/polkadot_sdk_frame/traits/trait.SignedExtension.html#associatedtype.Call){target=\_blank}**: To encode the pallet call to be dispatched. This data is used to calculate transaction fees. -- **[`AdditionalSigned`](https://paritytech.github.io/polkadot-sdk/master/polkadot_sdk_frame/traits/trait.SignedExtension.html#associatedtype.AdditionalSigned){target=\_blank}**: To handle any additional data to go into the signed payload allowing you to attach any custom logic prior to dispatching a transaction. -- **[`Pre`](https://paritytech.github.io/polkadot-sdk/master/polkadot_sdk_frame/traits/trait.SignedExtension.html#associatedtype.Pre){target=\_blank}**: To encode the information that can be passed from before a call is dispatched to after it gets dispatched. - -Signed extensions can enforce checks like: - -- **[`CheckSpecVersion`](https://paritytech.github.io/polkadot-sdk/master/src/frame_system/extensions/check_spec_version.rs.html){target=\_blank}**: Ensures the transaction is compatible with the runtime's current version. -- **[`CheckWeight`](https://paritytech.github.io/polkadot-sdk/master/frame_system/struct.CheckWeight.html){target=\_blank}**: Calculates the weight (or computational cost) of the transaction, ensuring the block doesn't exceed the maximum allowed weight. - -These extensions are critical in the transaction lifecycle, ensuring that only valid and prioritized transactions are processed. - -## Transaction Construction - -Building transactions in the Polkadot SDK involves constructing a payload that can be verified, signed, and submitted for inclusion in a block. Each runtime in the Polkadot SDK has its own rules for validating and executing transactions, but there are common patterns for constructing a signed transaction. - -### Construct a Signed Transaction - -A signed transaction in the Polkadot SDK includes various pieces of data to ensure security, prevent replay attacks, and prioritize processing. Here's an overview of how to construct one: - -1. **Construct the unsigned payload**: Gather the necessary information for the call, including: - - - **Pallet index**: Identifies the pallet where the runtime function resides. - - **Function index**: Specifies the particular function to call in the pallet. - - **Parameters**: Any additional arguments required by the function call. - -2. **Create a signing payload**: Once the unsigned payload is ready, additional data must be included: - - - **Transaction nonce**: Unique identifier to prevent replay attacks. - - **Era information**: Defines how long the transaction is valid before it's dropped from the pool. - - **Block hash**: Ensures the transaction doesn't execute on the wrong chain or fork. - -3. **Sign the payload**: Using the sender's private key, sign the payload to ensure that the transaction can only be executed by the account holder. -4. **Serialize the signed payload**: Once signed, the transaction must be serialized into a binary format, ensuring the data is compact and easy to transmit over the network. -5. **Submit the serialized transaction**: Finally, submit the serialized transaction to the network, where it will enter the transaction pool and wait for processing by an authoring node. - -The following is an example of how a signed transaction might look: - -``` rust -node_runtime::UncheckedExtrinsic::new_signed( - function.clone(), // some call - sp_runtime::AccountId32::from(sender.public()).into(), // some sending account - node_runtime::Signature::Sr25519(signature.clone()), // the account's signature - extra.clone(), // the signed extensions -) -``` - -### Transaction Encoding +# Smart Contracts Cookbook -Before a transaction is sent to the network, it is serialized and encoded using a structured encoding process that ensures consistency and prevents tampering: +Welcome to the Polkadot smart contracts cookbook index. -- **`[1]`**: Compact encoded length in bytes of the entire transaction. -- **`[2]`**: A u8 containing 1 byte to indicate whether the transaction is signed or unsigned (1 bit) and the encoded transaction version ID (7 bits). -- **`[3]`**: If signed, this field contains an account ID, an SR25519 signature, and some extra data. -- **`[4]`**: Encoded call data, including pallet and function indices and any required arguments. +This page contains a list of all relevant tutorials and guides to help you get started coding smart contracts and dApps in Polkadot. -This encoded format ensures consistency and efficiency in processing transactions across the network. By adhering to this format, applications can construct valid transactions and pass them to the network for execution. -To learn more about how compact encoding works using SCALE, see the [SCALE Codec](https://github.com/paritytech/parity-scale-codec){target=\_blank} README on GitHub. -### Customize Transaction Construction -Although the basic steps for constructing transactions are consistent across Polkadot SDK-based chains, developers can customize transaction formats and validation rules. For example: +## Get Tokens from the Faucet -- **Custom pallets**: You can define new pallets with custom function calls, each with its own parameters and validation logic. -- **Signed extensions**: Developers can implement custom extensions that modify how transactions are prioritized, validated, or included in blocks. +| Title | Difficulty | Tools | Description | +|------------------------------------|:-----------:|-------|-----------------------------------------------------------------------------------------------------------------------| +| [Faucet](/smart-contracts/faucet/) | 🟢 Beginner | N/A | Learn how to obtain test tokens from Polkadot faucets for development and testing purposes across different networks. | -By leveraging Polkadot SDK's modular design, developers can create highly specialized transaction logic tailored to their chain's needs. +## EVM Smart Contracts -## Lifecycle of a Transaction +| Title | Difficulty | Tools | Description | +|---------------------------------------------------------------------------------------------------------|:-----------:|--------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------| +| [Deploy an ERC-20 to Polkadot Hub](/smart-contracts/cookbook/smart-contracts/deploy-erc20/erc20-remix/) | 🟢 Beginner | EVM Wallet, Polkadot Remix IDE | Deploy an ERC-20 token on Polkadot Hub using PolkaVM. This guide covers contract creation, compilation, deployment, and interaction via Polkadot Remix IDE. | +| [Deploy an NFT to Polkadot Hub](/smart-contracts/cookbook/smart-contracts/deploy-nft/nft-remix/) | 🟢 Beginner | EVM Wallet, Polkadot Remix IDE | Deploy an NFT on Polkadot Hub using PolkaVM and OpenZeppelin. Learn how to compile, deploy, and interact with your contract using Polkadot Remix IDE. | -In the Polkadot SDK, transactions are often referred to as extrinsics because the data in transactions originates outside of the runtime. These transactions contain data that initiates changes to the chain state. The most common type of extrinsic is a signed transaction, which is cryptographically verified and typically incurs a fee. This section focuses on how signed transactions are processed, validated, and ultimately included in a block. +## Port Ethereum DApps -### Define Transaction Properties +| Title | Difficulty | Tools | Description | +|-------------------------------------------------------------------------------------|:---------------:|---------|----------------------------------------------------------------------------------------------------------------------------------| +| [Deploying Uniswap V2 on Polkadot](/smart-contracts/cookbook/eth-dapps/uniswap-v2/) | 🟡 Intermediate | Hardhat | Learn how to deploy and test Uniswap V2 on Polkadot Hub using Hardhat, bringing AMM-based token swaps to the Polkadot ecosystem. | -The Polkadot SDK runtime defines key transaction properties, such as: -- **Transaction validity**: Ensures the transaction meets all runtime requirements. -- **Signed or unsigned**: Identifies whether a transaction needs to be signed by an account. -- **State changes**: Determines how the transaction modifies the state of the chain. +--- -Pallets, which compose the runtime's logic, define the specific transactions that your chain supports. When a user submits a transaction, such as a token transfer, it becomes a signed transaction, verified by the user's account signature. If the account has enough funds to cover fees, the transaction is executed, and the chain's state is updated accordingly. +Page Title: Smart Contracts Overview -### Process on a Block Authoring Node +- Source (raw): https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/smart-contracts-overview.md +- Canonical (HTML): https://docs.polkadot.com/smart-contracts/overview/ +- Summary: Learn about smart contract development on Polkadot Hub with native PolkaVM support, dual-VM execution, and seamless cross-chain capabilities. -In Polkadot SDK-based networks, some nodes are authorized to author blocks. These nodes validate and process transactions. When a transaction is sent to a node that can produce blocks, it undergoes a lifecycle that involves several stages, including validation and execution. Non-authoring nodes gossip the transaction across the network until an authoring node receives it. The following diagram illustrates the lifecycle of a transaction that's submitted to a network and processed by an authoring node. +# Smart Contracts on Polkadot Hub -![Transaction lifecycle diagram](/images/reference/parachains/blocks-transactions-fees/transactions/transactions-01.webp){ style="background:white" } +## Introduction -### Validate and Queue +Polkadot Hub provides a production-ready smart contract platform that combines Ethereum compatibility with the performance and cross-chain capabilities of the Polkadot ecosystem. Developers can deploy smart contracts directly on Polkadot Hub while using familiar Ethereum tooling, workflows, and programming languages. -Once a transaction reaches an authoring node, it undergoes an initial validation process to ensure it meets specific conditions defined in the runtime. This validation includes checks for: +Built with a dual-VM approach, Polkadot Hub offers two execution backends: REVM for unmodified EVM compatibility and native PolkaVM for optimized computationally expensive workloads. This dual-VM architecture enables developers to migrate existing Ethereum contracts instantly or optimize for speed and efficiency with native execution. -- **Correct nonce**: Ensures the transaction is sequentially valid for the account. -- **Sufficient funds**: Confirms the account can cover any associated transaction fees. -- **Signature validity**: Verifies that the sender's signature matches the transaction data. +## Why Build on Polkadot Hub -After these checks, valid transactions are placed in the transaction pool, where they are queued for inclusion in a block. The transaction pool regularly re-validates queued transactions to ensure they remain valid before being processed. To reach consensus, two-thirds of the nodes must agree on the order of the transactions executed and the resulting state change. Transactions are validated and queued on the local node in a transaction pool to prepare for consensus. +### Ethereum Compatibility -#### Transaction Pool +Deploy existing Ethereum contracts with zero modifications while maintaining full compatibility with your existing development stack: -The transaction pool is responsible for managing valid transactions. It ensures that only transactions that pass initial validity checks are queued. Transactions that fail validation, expire, or become invalid for other reasons are removed from the pool. +- **Complete JSON-RPC API support**: Use MetaMask, Hardhat, Remix, Foundry, and all standard Ethereum tooling. +- **Standard libraries**: Integrate Ethers.js, Web3.js, Viem, Wagmi, and Web3.py without changes. +- **Solidity development**: Write contracts in Solidity or migrate existing code directly. +- **Familiar workflows**: Maintain your existing deployment, testing, and monitoring processes. -The transaction pool organizes transactions into two queues: +### Performance Options -- **Ready queue**: Transactions that are valid and ready to be included in a block. -- **Future queue**: Transactions that are not yet valid but could be in the future, such as transactions with a nonce too high for the current state. +Choose between two execution backends: -Details on how the transaction pool validates transactions, including fee and signature handling, can be found in the [`validate_transaction`](https://paritytech.github.io/polkadot-sdk/master/sp_transaction_pool/runtime_api/trait.TaggedTransactionQueue.html#method.validate_transaction){target=\_blank} method. +- **REVM**: Run unmodified Ethereum contracts with full EVM/Ethereum compatibility. +- **PolkaVM**: Compile to optimized RISC-V bytecode for enhanced performance and lower fees while keeping Ethereum-compatibility. -#### Invalid Transactions +Both backends share the same RPC interface and tooling support, allowing seamless transitions. In addition, smart contracts can interact with Polkadot native services via [precompile contracts](/smart-contracts/precompiles/){target=\_blank}. -If a transaction is invalid, for example, due to an invalid signature or insufficient funds, it is rejected and won't be added to the block. Invalid transactions might be rejected for reasons such as: +### Cross-VM & Cross-Chain Capabilities -- The transaction has already been included in a block. -- The transaction's signature does not match the sender. -- The transaction is too large to fit in the current block. +Smart contracts written for one VM (for example, EVM) can interact directly with other smart contracts written for the RISC-V PolkaVM, and back. This allows to use full EVM compatible contracts but extend to heavy/complex execution workloads to the PolkaVM RISC-V backend. -### Transaction Ordering and Priority +Furthermore, all smart contracts in Polkadot Hub can interact with any service in the Polkadot ecosystem through [XCM](/smart-contracts/precompiles/xcm/){target=\_blank}, enabling token transfers, remote execution, and cross-chain composability without bridges or intermediaries. -When a node is selected as the next block author, it prioritizes transactions based on weight, length, and tip amount. The goal is to fill the block with high-priority transactions without exceeding its maximum size or computational limits. Transactions are ordered as follows: +## Other Smart Contract Environments -- **Inherents first**: Inherent transactions, such as block timestamp updates, are always placed first. -- **Nonce-based ordering**: Transactions from the same account are ordered by their nonce. -- **Fee-based ordering**: Among transactions with the same nonce or priority level, those with higher fees are prioritized. +Beyond Polkadot Hub's native PolkaVM support, the ecosystem offers two main alternatives for smart contract development: -### Transaction Execution +- **EVM-compatible parachains**: Provide access to Ethereum's extensive developer ecosystem, smart contract portability, and established tooling like Hardhat, Remix, Foundry, and OpenZeppelin. The main options include Moonbeam (the first full Ethereum-compatible parachain serving as an interoperability hub), Astar (featuring dual VM support for both EVM and WebAssembly contracts), and Acala (DeFi-focused with enhanced Acala EVM+ offering advanced DeFi primitives). -Once a block author selects transactions from the pool, the transactions are executed in priority order. As each transaction is processed, the state changes are written directly to the chain's storage. It's important to note that these changes are not cached, meaning a failed transaction won't revert earlier state changes, which could leave the block in an inconsistent state. +- **Rust (ink!)**: ink! is a Rust-based framework that can compile to PolkaVM. It uses [`#[ink(...)]`](https://use.ink/docs/v6/macros-attributes/){target=\_blank} attribute macros to create Polkadot SDK-compatible PolkaVM bytecode, offering strong memory safety from Rust, an advanced type system, high-performance PolkaVM execution, and platform independence with sandboxed security. -Events are also written to storage. Runtime logic should not emit an event before performing the associated actions. If the associated transaction fails after the event was emitted, the event will not revert. +## Next Steps -## Transaction Mortality +
-Transactions in the network can be configured as either mortal (with expiration) or immortal (without expiration). Every transaction payload contains a block checkpoint (reference block number and hash) and an era/validity period that determines how many blocks after the checkpoint the transaction remains valid. +- Guide __Get Started__ -When a transaction is submitted, the network validates it against these parameters. If the transaction is not included in a block within the specified validity window, it is automatically removed from the transaction queue. + --- -- **Mortal transactions**: Have a finite lifespan and will expire after a specified number of blocks. For example, a transaction with a block checkpoint of 1000 and a validity period of 64 blocks will be valid from blocks 1000 to 1064. + Quick-start guides for connecting, deploying, and building your first smart contract. -- **Immortal transactions**: Never expire and remain valid indefinitely. To create an immortal transaction, set the block checkpoint to 0 (genesis block), use the genesis hash as a reference, and set the validity period to 0. + [:octicons-arrow-right-24: Get Started](/smart-contracts/get-started/) -However, immortal transactions pose significant security risks through replay attacks. If an account is reaped (balance drops to zero, account removed) and later re-funded, malicious actors can replay old immortal transactions. +- Guide __Cookbook__ -The blockchain maintains only a limited number of prior block hashes for reference validation, called `BlockHashCount`. If your validity period exceeds `BlockHashCount`, the effective validity period becomes the minimum of your specified period and the block hash count. + --- -## Unique Identifiers for Extrinsics + Step-by-step tutorials for deploying contracts, tokens, NFTs, and full dApps. -Transaction hashes are **not unique identifiers** in Polkadot SDK-based chains. + [:octicons-arrow-right-24: View Tutorials](/smart-contracts/cookbook/) -Key differences from traditional blockchains: +- Guide __Ethereum Developers__ -- Transaction hashes serve only as fingerprints of transaction information. -- Multiple valid transactions can share the same hash. -- Hash uniqueness assumptions lead to serious issues. + --- -For example, when an account is reaped (removed due to insufficient balance) and later recreated, it resets to nonce 0, allowing identical transactions to be valid at different points: + Understand key differences in accounts, fees, gas model, and deployment on Polkadot Hub. -| Block | Extrinsic Index | Hash | Origin | Nonce | Call | Result | -|-------|----------------|------|-----------|-------|---------------------|-------------------------------| -| 100 | 0 | 0x01 | Account A | 0 | Transfer 5 DOT to B | Account A reaped | -| 150 | 5 | 0x02 | Account B | 4 | Transfer 7 DOT to A | Account A created (nonce = 0) | -| 200 | 2 | 0x01 | Account A | 0 | Transfer 5 DOT to B | Successful transaction | + [:octicons-arrow-right-24: Learn More](/smart-contracts/for-eth-devs/accounts/) -Notice that blocks 100 and 200 contain transactions with identical hashes (0x01) but are completely different, valid operations occurring at different times. +- Guide __Precompiles__ -Additional complexity comes from Polkadot SDK's origin abstraction. Origins can represent collectives, governance bodies, or other non-account entities that don't maintain nonces like regular accounts and might dispatch identical calls multiple times with the same hash values. Each execution occurs in different chain states with different results. + --- -The correct way to uniquely identify an extrinsic on a Polkadot SDK-based chain is to use the block ID (height or hash) and the extrinsic index. Since the Polkadot SDK defines blocks as headers plus ordered arrays of extrinsics, the index position within a canonical block provides guaranteed uniqueness. + Discover advanced functionalities including XCM for cross-chain interactions. -## Additional Resources + [:octicons-arrow-right-24: Explore Precompiles](/smart-contracts/precompiles/) -For a video overview of the lifecycle of transactions and the types of transactions that exist, see the [Transaction lifecycle](https://www.youtube.com/watch?v=3pfM0GOp02c){target=\_blank} seminar from Parity Tech. +
--- @@ -5224,436 +3280,3 @@ The system maintains precise conversion mechanisms between: - Different resource metrics within the multi-dimensional model. This ensures accurate fee calculation while maintaining compatibility with existing Ethereum tools and workflows. - - ---- - -Page Title: Transactions Weights and Fees - -- Source (raw): https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/reference-parachains-blocks-transactions-fees-fees.md -- Canonical (HTML): https://docs.polkadot.com/reference/parachains/blocks-transactions-fees/fees/ -- Summary: Overview of transaction weights and fees in Polkadot SDK chains, detailing how fees are calculated using a defined formula and runtime specifics. - -# Transactions Weights and Fees - -## Introductions - -When transactions are executed, or data is stored on-chain, the activity changes the chain's state and consumes blockchain resources. Because the resources available to a blockchain are limited, managing how operations on-chain consume them is important. In addition to being limited in practical terms, such as storage capacity, blockchain resources represent a potential attack vector for malicious users. For example, a malicious user might attempt to overload the network with messages to stop the network from producing new blocks. To protect blockchain resources from being drained or overloaded, you need to manage how they are made available and how they are consumed. The resources to be aware of include: - -- Memory usage -- Storage input and output -- Computation -- Transaction and block size -- State database size - -The Polkadot SDK provides block authors with several ways to manage access to resources and to prevent individual components of the chain from consuming too much of any single resource. Two of the most important mechanisms available to block authors are weights and transaction fees. - -[Weights](/reference/glossary/#weight){target=\_blank} manage the time it takes to validate a block and characterize the time it takes to execute the calls in the block's body. By controlling the execution time a block can consume, weights set limits on storage input, output, and computation. - -Some of the weight allowed for a block is consumed as part of the block's initialization and finalization. The weight might also be used to execute mandatory inherent extrinsic calls. To help ensure blocks don’t consume too much execution time and prevent malicious users from overloading the system with unnecessary calls, weights are combined with transaction fees. - -[Transaction fees](/reference/parachains/blocks-transactions-fees/transactions/#transaction-fees){target=\_blank} provide an economic incentive to limit execution time, computation, and the number of calls required to perform operations. Transaction fees are also used to make the blockchain economically sustainable because they are typically applied to transactions initiated by users and deducted before a transaction request is executed. - -## How Fees are Calculated - -The final fee for a transaction is calculated using the following parameters: - -- **`base fee`**: This is the minimum amount a user pays for a transaction. It is declared a base weight in the runtime and converted to a fee using the [`WeightToFee`](https://docs.rs/pallet-transaction-payment/latest/pallet_transaction_payment/pallet/trait.Config.html#associatedtype.WeightToFee){target=\_blank} conversion. -- **`weight fee`**: A fee proportional to the execution time (input and output and computation) that a transaction consumes. -- **`length fee`**: A fee proportional to the encoded length of the transaction. -- **`tip`**: An optional tip to increase the transaction’s priority, giving it a higher chance to be included in the transaction queue. - -The base fee and proportional weight and length fees constitute the inclusion fee. The inclusion fee is the minimum fee that must be available for a transaction to be included in a block. - -```text -inclusion fee = base fee + weight fee + length fee -``` - -Transaction fees are withdrawn before the transaction is executed. After the transaction is executed, the weight can be adjusted to reflect the resources used. If a transaction uses fewer resources than expected, the transaction fee is corrected, and the adjusted transaction fee is deposited. - -## Using the Transaction Payment Pallet - -The [Transaction Payment pallet](https://github.com/paritytech/polkadot-sdk/tree/polkadot-stable2506-2/substrate/frame/transaction-payment){target=\_blank} provides the basic logic for calculating the inclusion fee. You can also use the Transaction Payment pallet to: - -- Convert a weight value into a deductible fee based on a currency type using [`Config::WeightToFee`](https://docs.rs/pallet-transaction-payment/latest/pallet_transaction_payment/pallet/trait.Config.html#associatedtype.WeightToFee){target=\_blank}. -- Update the fee for the next block by defining a multiplier based on the chain’s final state at the end of the previous block using [`Config::FeeMultiplierUpdate`](https://docs.rs/pallet-transaction-payment/latest/pallet_transaction_payment/pallet/trait.Config.html#associatedtype.FeeMultiplierUpdate){target=\_blank}. -- Manage the withdrawal, refund, and deposit of transaction fees using [`Config::OnChargeTransaction`](https://docs.rs/pallet-transaction-payment/latest/pallet_transaction_payment/pallet/trait.Config.html#associatedtype.OnChargeTransaction){target=\_blank}. - -You can learn more about these configuration traits in the [Transaction Payment documentation](https://paritytech.github.io/polkadot-sdk/master/pallet_transaction_payment/index.html){target=\_blank}. - -### Understanding the Inclusion Fee - -The formula for calculating the inclusion fee is as follows: - -```text -inclusion_fee = base_fee + length_fee + [targeted_fee_adjustment * weight_fee] -``` - -And then, for calculating the final fee: - -```text -final_fee = inclusion_fee + tip -``` - -In the first formula, the `targeted_fee_adjustment` is a multiplier that can tune the final fee based on the network’s congestion. - -- The `base_fee` derived from the base weight covers inclusion overhead like signature verification. -- The `length_fee` is a per-byte fee that is multiplied by the length of the encoded extrinsic. -- The `weight_fee` fee is calculated using two parameters: - - The `ExtrinsicBaseWeight` that is declared in the runtime and applies to all extrinsics. - - The `#[pallet::weight]` annotation that accounts for an extrinsic's complexity. - -To convert the weight to `Currency`, the runtime must define a `WeightToFee` struct that implements a conversion function, [`Convert`](https://docs.rs/pallet-transaction-payment/latest/pallet_transaction_payment/pallet/struct.Pallet.html#method.weight_to_fee){target=\_blank}. - -Note that the extrinsic sender is charged the inclusion fee before the extrinsic is invoked. The fee is deducted from the sender's balance even if the transaction fails upon execution. - -### Accounts with an Insufficient Balance - -If an account does not have a sufficient balance to pay the inclusion fee and remain alive—that is, enough to pay the inclusion fee and maintain the minimum existential deposit—then you should ensure the transaction is canceled so that no fee is deducted and the transaction does not begin execution. - -The Polkadot SDK doesn't enforce this rollback behavior. However, this scenario would be rare because the transaction queue and block-making logic perform checks to prevent it before adding an extrinsic to a block. - -### Fee Multipliers - -The inclusion fee formula always results in the same fee for the same input. However, weight can be dynamic and—based on how [`WeightToFee`](https://docs.rs/pallet-transaction-payment/latest/pallet_transaction_payment/pallet/trait.Config.html#associatedtype.WeightToFee){target=\_blank} is defined—the final fee can include some degree of variability. -The Transaction Payment pallet provides the [`FeeMultiplierUpdate`](https://docs.rs/pallet-transaction-payment/latest/pallet_transaction_payment/pallet/trait.Config.html#associatedtype.FeeMultiplierUpdate){target=\_blank} configurable parameter to account for this variability. - -The Polkadot network inspires the default update function and implements a targeted adjustment in which a target saturation level of block weight is defined. If the previous block is more saturated, the fees increase slightly. Similarly, if the last block has fewer transactions than the target, fees are decreased by a small amount. For more information about fee multiplier adjustments, see the [Web3 Research Page](https://research.web3.foundation/Polkadot/overview/token-economics#relay-chain-transaction-fees-and-per-block-transaction-limits){target=\_blank}. - -## Transactions with Special Requirements - -Inclusion fees must be computable before execution and can only represent fixed logic. Some transactions warrant limiting resources with other strategies. For example: - -- Bonds are a type of fee that might be returned or slashed after some on-chain event. For example, you might want to require users to place a bond to participate in a vote. The bond might then be returned at the end of the referendum or slashed if the voter attempted malicious behavior. -- Deposits are fees that might be returned later. For example, you might require users to pay a deposit to execute an operation that uses storage. The user’s deposit could be returned if a subsequent operation frees up storage. -- Burn operations are used to pay for a transaction based on its internal logic. For example, a transaction might burn funds from the sender if the transaction creates new storage items to pay for the increased state size. -- Limits enable you to enforce constant or configurable limits on specific operations. For example, the default [Staking pallet](https://github.com/paritytech/polkadot-sdk/tree/polkadot-stable2506-2/substrate/frame/staking){target=\_blank} only allows nominators to nominate 16 validators to limit the complexity of the validator election process. - -It is important to note that if you query the chain for a transaction fee, it only returns the inclusion fee. - -## Default Weight Annotations - -All dispatchable functions in the Polkadot SDK must specify a weight. The way of doing that is using the annotation-based system that lets you combine fixed values for database read/write weight and/or fixed values based on benchmarks. The most basic example would look like this: - -```rust -#[pallet::weight(100_000)] -fn my_dispatchable() { - // ... -} -``` - -Note that the [`ExtrinsicBaseWeight`](https://crates.parity.io/frame_support/weights/constants/struct.ExtrinsicBaseWeight.html){target=\_blank} is automatically added to the declared weight to account for the costs of simply including an empty extrinsic into a block. - -### Weights and Database Read/Write Operations - -To make weight annotations independent of the deployed database backend, they are defined as a constant and then used in the annotations when expressing database accesses performed by the dispatchable: - -```rust -#[pallet::weight(T::DbWeight::get().reads_writes(1, 2) + 20_000)] -fn my_dispatchable() { - // ... -} -``` - -This dispatchable allows one database to read and two to write, in addition to other things that add the additional 20,000. Database access is generally every time a value declared inside the [`#[pallet::storage]`](https://paritytech.github.io/polkadot-sdk/master/frame_support/pallet_macros/attr.storage.html){target=\_blank} block is accessed. However, unique accesses are counted because after a value is accessed, it is cached, and reaccessing it does not result in a database operation. That is: - -- Multiple reads of the exact value count as one read. -- Multiple writes of the exact value count as one write. -- Multiple reads of the same value, followed by a write to that value, count as one read and one write. -- A write followed by a read-only counts as one write. - -### Dispatch Classes - -Dispatches are broken into three classes: - -- Normal -- Operational -- Mandatory - -If a dispatch is not defined as `Operational` or `Mandatory` in the weight annotation, the dispatch is identified as `Normal` by default. You can specify that the dispatchable uses another class like this: - -```rust -#[pallet::dispatch((DispatchClass::Operational))] -fn my_dispatchable() { - // ... -} -``` - -This tuple notation also allows you to specify a final argument determining whether the user is charged based on the annotated weight. If you don't specify otherwise, `Pays::Yes` is assumed: - -```rust -#[pallet::dispatch(DispatchClass::Normal, Pays::No)] -fn my_dispatchable() { - // ... -} -``` - -#### Normal Dispatches - -Dispatches in this class represent normal user-triggered transactions. These types of dispatches only consume a portion of a block's total weight limit. For information about the maximum portion of a block that can be consumed for normal dispatches, see [`AvailableBlockRatio`](https://paritytech.github.io/polkadot-sdk/master/frame_system/limits/struct.BlockLength.html){target=\_blank}. Normal dispatches are sent to the transaction pool. - -#### Operational Dispatches - -Unlike normal dispatches, which represent the usage of network capabilities, operational dispatches are those that provide network capabilities. Operational dispatches can consume the entire weight limit of a block. They are not bound by the [`AvailableBlockRatio`](https://paritytech.github.io/polkadot-sdk/master/frame_system/limits/struct.BlockLength.html){target=\_blank}. Dispatches in this class are given maximum priority and are exempt from paying the [`length_fee`](https://docs.rs/pallet-transaction-payment/latest/pallet_transaction_payment/){target=\_blank}. - -#### Mandatory Dispatches - -Mandatory dispatches are included in a block even if they cause the block to surpass its weight limit. You can only use the mandatory dispatch class for inherent transactions that the block author submits. This dispatch class is intended to represent functions in the block validation process. Because these dispatches are always included in a block regardless of the function weight, the validation process must prevent malicious nodes from abusing the function to craft valid but impossibly heavy blocks. You can typically accomplish this by ensuring that: - -- The operation performed is always light. -- The operation can only be included in a block once. - -To make it more difficult for malicious nodes to abuse mandatory dispatches, they cannot be included in blocks that return errors. This dispatch class serves the assumption that it is better to allow an overweight block to be created than not to allow any block to be created at all. - -### Dynamic Weights - -In addition to purely fixed weights and constants, the weight calculation can consider the input arguments of a dispatchable. The weight should be trivially computable from the input arguments with some basic arithmetic: - -```rust -use frame_support:: { - dispatch:: { - DispatchClass::Normal, - Pays::Yes, - }, - weights::Weight, -}; - -#[pallet::weight(FunctionOf( - |args: (&Vec,)| args.0.len().saturating_mul(10_000), - ) -] -fn handle_users(origin, calls: Vec) { - // Do something per user -} -``` - -## Post Dispatch Weight Correction - -Depending on the execution logic, a dispatchable function might consume less weight than was prescribed pre-dispatch. To correct weight, the function declares a different return type and returns its actual weight: - -```rust -#[pallet::weight(10_000 + 500_000_000)] -fn expensive_or_cheap(input: u64) -> DispatchResultWithPostInfo { - let was_heavy = do_calculation(input); - - if (was_heavy) { - // None means "no correction" from the weight annotation. - Ok(None.into()) - } else { - // Return the actual weight consumed. - Ok(Some(10_000).into()) - } -} -``` - -## Custom Fees - -You can also define custom fee systems through custom weight functions or inclusion fee functions. - -### Custom Weights - -Instead of using the default weight annotations, you can create a custom weight calculation type using the weights module. The custom weight calculation type must implement the following traits: - -- [`WeighData`](https://crates.parity.io/frame_support/weights/trait.WeighData.html){target=\_blank} to determine the weight of the dispatch. -- [`ClassifyDispatch`](https://crates.parity.io/frame_support/weights/trait.ClassifyDispatch.html){target=\_blank} to determine the class of the dispatch. -- [`PaysFee`](https://crates.parity.io/frame_support/weights/trait.PaysFee.html){target=\_blank} to determine whether the sender of the dispatch pays fees. - -The Polkadot SDK then bundles the output information of the three traits into the [`DispatchInfo`](https://paritytech.github.io/polkadot-sdk/master/frame_support/dispatch/struct.DispatchInfo.html){target=\_blank} struct and provides it by implementing the [`GetDispatchInfo`](https://docs.rs/frame-support/latest/frame_support/dispatch/trait.GetDispatchInfo.html){target=\_blank} for all `Call` variants and opaque extrinsic types. This is used internally by the System and Executive modules. - -`ClassifyDispatch`, `WeighData`, and `PaysFee` are generic over T, which gets resolved into the tuple of all dispatch arguments except for the origin. The following example illustrates a struct that calculates the weight as `m * len(args)`, where `m` is a given multiplier and args is the concatenated tuple of all dispatch arguments. In this example, the dispatch class is `Operational` if the transaction has more than 100 bytes of length in arguments and will pay fees if the encoded length exceeds 10 bytes. - -```rust -struct LenWeight(u32); -impl WeighData for LenWeight { - fn weigh_data(&self, target: T) -> Weight { - let multiplier = self.0; - let encoded_len = target.encode().len() as u32; - multiplier * encoded_len - } -} - -impl ClassifyDispatch for LenWeight { - fn classify_dispatch(&self, target: T) -> DispatchClass { - let encoded_len = target.encode().len() as u32; - if encoded_len > 100 { - DispatchClass::Operational - } else { - DispatchClass::Normal - } - } -} - -impl PaysFee { - fn pays_fee(&self, target: T) -> Pays { - let encoded_len = target.encode().len() as u32; - if encoded_len > 10 { - Pays::Yes - } else { - Pays::No - } - } -} -``` - -A weight calculator function can also be coerced to the final type of the argument instead of defining it as a vague type that can be encoded. The code would roughly look like this: - -```rust -struct CustomWeight; -impl WeighData<(&u32, &u64)> for CustomWeight { - fn weigh_data(&self, target: (&u32, &u64)) -> Weight { - ... - } -} - -// given a dispatch: -#[pallet::call] -impl, I: 'static> Pallet { - #[pallet::weight(CustomWeight)] - fn foo(a: u32, b: u64) { ... } -} -``` - -In this example, the `CustomWeight` can only be used in conjunction with a dispatch with a particular signature `(u32, u64)`, as opposed to `LenWeight`, which can be used with anything because there aren't any assumptions about ``. - -#### Custom Inclusion Fee - -The following example illustrates how to customize your inclusion fee. You must configure the appropriate associated types in the respective module. - -```rust -// Assume this is the balance type -type Balance = u64; - -// Assume we want all the weights to have a `100 + 2 * w` conversion to fees -struct CustomWeightToFee; -impl WeightToFee for CustomWeightToFee { - fn convert(w: Weight) -> Balance { - let a = Balance::from(100); - let b = Balance::from(2); - let w = Balance::from(w); - a + b * w - } -} - -parameter_types! { - pub const ExtrinsicBaseWeight: Weight = 10_000_000; -} - -impl frame_system::Config for Runtime { - type ExtrinsicBaseWeight = ExtrinsicBaseWeight; -} - -parameter_types! { - pub const TransactionByteFee: Balance = 10; -} - -impl transaction_payment::Config { - type TransactionByteFee = TransactionByteFee; - type WeightToFee = CustomWeightToFee; - type FeeMultiplierUpdate = TargetedFeeAdjustment; -} - -struct TargetedFeeAdjustment(sp_std::marker::PhantomData); -impl> WeightToFee for TargetedFeeAdjustment { - fn convert(multiplier: Fixed128) -> Fixed128 { - // Don't change anything. Put any fee update info here. - multiplier - } -} -``` - -## Additional Resources - -You now know the weight system, how it affects transaction fee computation, and how to specify weights for your dispatchable calls. The next step is determining the correct weight for your dispatchable operations. You can use Substrate benchmarking functions and frame-benchmarking calls to test your functions with different parameters and empirically determine the proper weight in their worst-case scenarios. - -- [Benchmark](/parachains/customize-runtime/pallet-development/benchmark-pallet/) -- [`SignedExtension`](https://paritytech.github.io/polkadot-sdk/master/sp_runtime/traits/trait.SignedExtension.html){target=\_blank} -- [Custom weights for the Example pallet](https://github.com/paritytech/polkadot-sdk/blob/polkadot-stable2506-2/substrate/frame/examples/basic/src/weights.rs){target=\_blank} -- [Web3 Foundation Research](https://research.web3.foundation/Polkadot/overview/token-economics#relay-chain-transaction-fees-and-per-block-transaction-limits){target=\_blank} - - ---- - -Page Title: XCM Tools - -- Source (raw): https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/reference-tools-xcm-tools.md -- Canonical (HTML): https://docs.polkadot.com/reference/tools/xcm-tools/ -- Summary: Explore essential XCM tools across Polkadot, crafted to enhance cross-chain functionality and integration within the ecosystem. - -# XCM Tools - -## Introduction - -As described in the [Interoperability](/develop/interoperability){target=\_blank} section, XCM (Cross-Consensus Messaging) is a protocol used in the Polkadot and Kusama ecosystems to enable communication and interaction between chains. It facilitates cross-chain communication, allowing assets, data, and messages to flow seamlessly across the ecosystem. - -As XCM is central to enabling communication between blockchains, developers need robust tools to help interact with, build, and test XCM messages. Several XCM tools simplify working with the protocol by providing libraries, frameworks, and utilities that enhance the development process, ensuring that applications built within the Polkadot ecosystem can efficiently use cross-chain functionalities. - -## Popular XCM Tools - -### Moonsong Labs XCM Tools - -[Moonsong Labs XCM Tools](https://github.com/Moonsong-Labs/xcm-tools){target=\_blank} provides a collection of scripts for managing and testing XCM operations between Polkadot SDK-based runtimes. These tools allow performing tasks like asset registration, channel setup, and XCM initialization. Key features include: - -- **Asset registration**: Registers assets, setting units per second (up-front fees), and configuring error (revert) codes. -- **XCM initializer**: Initializes XCM, sets default XCM versions, and configures revert codes for XCM-related precompiles. -- **HRMP manipulator**: Manages HRMP channel actions, including opening, accepting, or closing channels. -- **XCM-Transactor-Info-Setter**: Configures transactor information, including extra weight and fee settings. -- **Decode XCM**: Decodes XCM messages on the relay chain or parachains to help interpret cross-chain communication. - -To get started, clone the repository and install the required dependencies: - -```bash -git clone https://github.com/Moonsong-Labs/xcm-tools && -cd xcm-tools && -yarn install -``` - -For a full overview of each script, visit the [scripts](https://github.com/Moonsong-Labs/xcm-tools/tree/main/scripts){target=\_blank} directory or refer to the [official documentation](https://github.com/Moonsong-Labs/xcm-tools/blob/main/README.md){target=\_blank} on GitHub. - -### ParaSpell - -[ParaSpell](/reference/tools/paraspell/){target=\_blank} is a collection of open-source XCM tools that streamline cross-chain asset transfers and interactions across the Polkadot and Kusama ecosystems. It provides developers with an intuitive interface to build, test, and deploy interoperable dApps, featuring message composition, decoding, and practical utilities for parachain interactions that simplify debugging and cross-chain communication optimization. - -### Astar XCM Tools - -The [Astar parachain](https://github.com/AstarNetwork/Astar/tree/master){target=\_blank} offers a crate with a set of utilities for interacting with the XCM protocol. The [xcm-tools](https://github.com/AstarNetwork/Astar/tree/master/bin/xcm-tools){target=\_blank} crate provides a straightforward method for users to locate a sovereign account or calculate an XC20 asset ID. Some commands included by the xcm-tools crate allow users to perform the following tasks: - -- **Sovereign accounts**: Obtain the sovereign account address for any parachain, either on the Relay Chain or for sibling parachains, using a simple command. -- **XC20 EVM addresses**: Generate XC20-compatible Ethereum addresses for assets by entering the asset ID, making it easy to integrate assets across Ethereum-compatible environments. -- **Remote accounts**: Retrieve remote account addresses needed for multi-location compatibility, using flexible options to specify account types and parachain IDs. - -To start using these tools, clone the [Astar repository](https://github.com/AstarNetwork/Astar){target=\_blank} and compile the xcm-tools package: - -```bash -git clone https://github.com/AstarNetwork/Astar && -cd Astar && -cargo build --release -p xcm-tools -``` - -After compiling, verify the setup with the following command: - -```bash -./target/release/xcm-tools --help -``` -For more details on using Astar xcm-tools, consult the [official documentation](https://docs.astar.network/docs/learn/interoperability/xcm/integration/tools/){target=\_blank}. - -### Chopsticks - -The Chopsticks library provides XCM functionality for testing XCM messages across networks, enabling you to fork multiple parachains along with a relay chain. For further details, see the [Chopsticks documentation](/tutorials/polkadot-sdk/testing/fork-live-chains/){target=\_blank} about XCM. - -### Moonbeam XCM SDK - -The [Moonbeam XCM SDK](https://github.com/moonbeam-foundation/xcm-sdk){target=\_blank} enables developers to easily transfer assets between chains, either between parachains or between a parachain and the relay chain, within the Polkadot/Kusama ecosystem. With the SDK, you don't need to worry about determining the [Multilocation](https://github.com/polkadot-fellows/xcm-format?tab=readme-ov-file#7-universal-consensus-location-identifiers){target=\_blank} of the origin or destination assets or which extrinsics are used on which networks. - -The SDK consists of two main packages: - -- **[XCM SDK](https://github.com/moonbeam-foundation/xcm-sdk/tree/main/packages/sdk){target=\_blank}**: Core SDK for executing XCM transfers between chains in the Polkadot/Kusama ecosystem. -- **[MRL SDK](https://github.com/moonbeam-foundation/xcm-sdk/tree/main/packages/mrl){target=\_blank}**: Extension of the XCM SDK for transferring liquidity into and across the Polkadot ecosystem from other ecosystems like Ethereum. - -Key features include: - -- **Simplified asset transfers**: Abstracts away complex multilocation determinations and extrinsic selection. -- **Cross-ecosystem support**: Enables transfers between Polkadot/Kusama chains and external ecosystems. -- **Developer-friendly API**: Provides intuitive interfaces for cross-chain functionality. -- **Comprehensive documentation**: Includes usage guides and API references for both packages. - -For detailed usage examples and API documentation, visit the [official Moonbeam XCM SDK documentation](https://moonbeam-foundation.github.io/xcm-sdk/latest/){target=\_blank}. diff --git a/.ai/categories/parachains.md b/.ai/categories/parachains.md index c0cea0eae..35a55e33c 100644 --- a/.ai/categories/parachains.md +++ b/.ai/categories/parachains.md @@ -1425,440 +1425,6 @@ Congratulations, you've successfully benchmarked a pallet and updated your runti - [frame-omni-bencher Tool](https://paritytech.github.io/polkadot-sdk/master/frame_omni_bencher/index.html){target=\_blank} ---- - -Page Title: Blocks - -- Source (raw): https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/reference-parachains-blocks-transactions-fees-blocks.md -- Canonical (HTML): https://docs.polkadot.com/reference/parachains/blocks-transactions-fees/blocks/ -- Summary: Understand how blocks are produced, validated, and imported in Polkadot SDK-based blockchains, covering initialization, finalization, and authoring processes. - -# Blocks - -## Introduction - -In the Polkadot SDK, blocks are fundamental to the functioning of the blockchain, serving as containers for [transactions](/reference/parachains/blocks-transactions-fees/transactions/){target=\_blank} and changes to the chain's state. Blocks consist of headers and an array of transactions, ensuring the integrity and validity of operations on the network. This guide explores the essential components of a block, the process of block production, and how blocks are validated and imported across the network. By understanding these concepts, developers can better grasp how blockchains maintain security, consistency, and performance within the Polkadot ecosystem. - -## What is a Block? - -In the Polkadot SDK, a block is a fundamental unit that encapsulates both the header and an array of transactions. The block header includes critical metadata to ensure the integrity and sequence of the blockchain. Here's a breakdown of its components: - -- **Block height**: Indicates the number of blocks created in the chain so far. -- **Parent hash**: The hash of the previous block, providing a link to maintain the blockchain's immutability. -- **Transaction root**: Cryptographic digest summarizing all transactions in the block. -- **State root**: A cryptographic digest representing the post-execution state. -- **Digest**: Additional information that can be attached to a block, such as consensus-related messages. - -Each transaction is part of a series that is executed according to the runtime's rules. The transaction root is a cryptographic digest of this series, which prevents alterations and enables succinct verification by light clients. This verification process allows light clients to confirm whether a transaction exists in a block with only the block header, avoiding downloading the entire block. - -## Block Production - -When an authoring node is authorized to create a new block, it selects transactions from the transaction queue based on priority. This step, known as block production, relies heavily on the executive module to manage the initialization and finalization of blocks. The process is summarized as follows: - -### Initialize Block - -The block initialization process begins with a series of function calls that prepare the block for transaction execution: - -1. **Call `on_initialize`**: The executive module calls the [`on_initialize`](https://paritytech.github.io/polkadot-sdk/master/frame_support/traits/trait.Hooks.html#method.on_initialize){target=\_blank} hook from the system pallet and other runtime pallets to prepare for the block's transactions. -2. **Coordinate runtime calls**: Coordinates function calls in the order defined by the transaction queue. -3. **Verify information**: Once [`on_initialize`](https://paritytech.github.io/polkadot-sdk/master/frame_support/traits/trait.Hooks.html#method.on_initialize){target=\_blank} functions are executed, the executive module checks the parent hash in the block header and the trie root to verify information is consistent. - -### Finalize Block - -Once transactions are processed, the block must be finalized before being broadcast to the network. The finalization steps are as follows: - -1. **Call `on_finalize`**: The executive module calls the [`on_finalize`](https://paritytech.github.io/polkadot-sdk/master/frame_support/traits/trait.Hooks.html#method.on_finalize){target=\_blank} hooks in each pallet to ensure any remaining state updates or checks are completed before the block is sealed and published. -2. **Verify information**: The block's digest and storage root in the header are checked against the initialized block to ensure consistency. -3. **Call `on_idle`**: The [`on_idle`](https://paritytech.github.io/polkadot-sdk/master/frame_support/traits/trait.Hooks.html#method.on_idle){target=\_blank} hook is triggered to process any remaining tasks using the leftover weight from the block. - -## Block Authoring and Import - -Once the block is finalized, it is gossiped to other nodes in the network. Nodes follow this procedure: - -1. **Receive transactions**: The authoring node collects transactions from the network. -2. **Validate**: Transactions are checked for validity. -3. **Queue**: Valid transactions are placed in the transaction pool for execution. -4. **Execute**: State changes are made as the transactions are executed. -5. **Publish**: The finalized block is broadcast to the network. - -### Block Import Queue - -After a block is published, other nodes on the network can import it into their chain state. The block import queue is part of the outer node in every Polkadot SDK-based node and ensures incoming blocks are valid before adding them to the node's state. - -In most cases, you don't need to know details about how transactions are gossiped or how other nodes on the network import blocks. The following traits are relevant, however, if you plan to write any custom consensus logic or want a deeper dive into the block import queue: - -- **[`ImportQueue`](https://paritytech.github.io/polkadot-sdk/master/sc_consensus/import_queue/trait.ImportQueue.html){target=\_blank}**: The trait that defines the block import queue. -- **[`Link`](https://paritytech.github.io/polkadot-sdk/master/sc_consensus/import_queue/trait.Link.html){target=\_blank}**: The trait that defines the link between the block import queue and the network. -- **[`BasicQueue`](https://paritytech.github.io/polkadot-sdk/master/sc_consensus/import_queue/struct.BasicQueue.html){target=\_blank}**: A basic implementation of the block import queue. -- **[`Verifier`](https://paritytech.github.io/polkadot-sdk/master/sc_consensus/import_queue/trait.Verifier.html){target=\_blank}**: The trait that defines the block verifier. -- **[`BlockImport`](https://paritytech.github.io/polkadot-sdk/master/sc_consensus/block_import/trait.BlockImport.html){target=\_blank}**: The trait that defines the block import process. - -These traits govern how blocks are validated and imported across the network, ensuring consistency and security. - -## Additional Resources - -To learn more about the block structure in the Polkadot SDK runtime, see the [`Block` reference](https://paritytech.github.io/polkadot-sdk/master/sp_runtime/traits/trait.Block.html){target=\_blank} entry in the Rust Docs. - - ---- - -Page Title: Chain Data - -- Source (raw): https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/reference-parachains-chain-data.md -- Canonical (HTML): https://docs.polkadot.com/reference/parachains/chain-data/ -- Summary: Learn how to expose and utilize chain data for blockchain applications. Discover runtime metadata, RPC APIs, and tools for efficient development. - -# Chain Data - -## Introduction - -Understanding and leveraging on-chain data is a fundamental aspect of blockchain development. Whether you're building frontend applications or backend systems, accessing and decoding runtime metadata is vital to interacting with the blockchain. This guide introduces you to the tools and processes for generating and retrieving metadata, explains its role in application development, and outlines the additional APIs available for interacting with a Polkadot node. By mastering these components, you can ensure seamless communication between your applications and the blockchain. - -## Application Development - -You might not be directly involved in building frontend applications as a blockchain developer. However, most applications that run on a blockchain require some form of frontend or user-facing client to enable users or other programs to access and modify the data that the blockchain stores. For example, you might develop a browser-based, mobile, or desktop application that allows users to submit transactions, post articles, view their assets, or track previous activity. The backend for that application is configured in the runtime logic for your blockchain, but the frontend client makes the runtime features accessible to your users. - -For your custom chain to be useful to others, you'll need to provide a client application that allows users to view, interact with, or update information that the blockchain keeps track of. In this article, you'll learn how to expose information about your runtime so that client applications can use it, see examples of the information exposed, and explore tools and libraries that use it. - -## Understand Metadata - -Polkadot SDK-based blockchain networks are designed to expose their runtime information, allowing developers to learn granular details regarding pallets, RPC calls, and runtime APIs. The metadata also exposes their related documentation. The chain's metadata is [SCALE-encoded](/reference/parachains/data-encoding/){target=\_blank}, allowing for the development of browser-based, mobile, or desktop applications to support the chain's runtime upgrades seamlessly. It is also possible to develop applications compatible with multiple Polkadot SDK-based chains simultaneously. - -## Expose Runtime Information as Metadata - -To interact with a node or the state of the blockchain, you need to know how to connect to the chain and access the exposed runtime features. This interaction involves a Remote Procedure Call (RPC) through a node endpoint address, commonly through a secure web socket connection. - -An application developer typically needs to know the contents of the runtime logic, including the following details: - -- Version of the runtime the application is connecting to. -- Supported APIs. -- Implemented pallets. -- Defined functions and corresponding type signatures. -- Defined custom types. -- Exposed parameters users can set. - -As the Polkadot SDK is modular and provides a composable framework for building blockchains, there are limitless opportunities to customize the schema of properties. Each runtime can be configured with its properties, including function calls and types, which can be changed over time with runtime upgrades. - -The Polkadot SDK enables you to generate the runtime metadata schema to capture information unique to a runtime. The metadata for a runtime describes the pallets in use and types defined for a specific runtime version. The metadata includes information about each pallet's storage items, functions, events, errors, and constants. The metadata also provides type definitions for any custom types included in the runtime. - -Metadata provides a complete inventory of a chain's runtime. It is key to enabling client applications to interact with the node, parse responses, and correctly format message payloads sent back to that chain. - -## Generate Metadata - -To efficiently use the blockchain's networking resources and minimize the data transmitted over the network, the metadata schema is encoded using the [Parity SCALE Codec](https://github.com/paritytech/parity-scale-codec?tab=readme-ov-file#parity-scale-codec){target=\_blank}. This encoding is done automatically through the [`scale-info`](https://docs.rs/scale-info/latest/scale_info/){target=\_blank}crate. - -At a high level, generating the metadata involves the following steps: - -1. The pallets in the runtime logic expose callable functions, types, parameters, and documentation that need to be encoded in the metadata. -2. The `scale-info` crate collects type information for the pallets in the runtime, builds a registry of the pallets that exist in a particular runtime, and the relevant types for each pallet in the registry. The type information is detailed enough to enable encoding and decoding for every type. -3. The [`frame-metadata`](https://github.com/paritytech/frame-metadata){target=\_blank} crate describes the structure of the runtime based on the registry provided by the `scale-info` crate. -4. Nodes provide the RPC method `state_getMetadata` to return a complete description of all the types in the current runtime as a hex-encoded vector of SCALE-encoded bytes. - -## Retrieve Runtime Metadata - -The type information provided by the metadata enables applications to communicate with nodes using different runtime versions and across chains that expose different calls, events, types, and storage items. The metadata also allows libraries to generate a substantial portion of the code needed to communicate with a given node, enabling libraries like [`subxt`](https://github.com/paritytech/subxt){target=\_blank} to generate frontend interfaces that are specific to a target chain. - -### Use Polkadot.js - -Visit the [Polkadot.js Portal](https://polkadot.js.org/apps/#/rpc){target=\_blank} and select the **Developer** dropdown in the top banner. Select **RPC Calls** to make the call to request metadata. Follow these steps to make the RPC call: - -1. Select **state** as the endpoint to call. -2. Select **`getMetadata(at)`** as the method to call. -3. Click **Submit RPC call** to submit the call and return the metadata in JSON format. - -### Use Curl - -You can fetch the metadata for the network by calling the node's RPC endpoint. This request returns the metadata in bytes rather than human-readable JSON: - -```sh -curl -H "Content-Type: application/json" \ --d '{"id":1, "jsonrpc":"2.0", "method": "state_getMetadata"}' \ -https://rpc.polkadot.io - -``` - -### Use Subxt - -[`subxt`](https://github.com/paritytech/subxt){target=\_blank} may also be used to fetch the metadata of any data in a human-readable JSON format: - -```sh -subxt metadata --url wss://rpc.polkadot.io --format json > spec.json -``` - -Another option is to use the [`subxt` explorer web UI](https://paritytech.github.io/subxt-explorer/#/){target=\_blank}. - -## Client Applications and Metadata - -The metadata exposes the expected way to decode each type, meaning applications can send, retrieve, and process application information without manual encoding and decoding. Client applications must use the [SCALE codec library](https://github.com/paritytech/parity-scale-codec?tab=readme-ov-file#parity-scale-codec){target=\_blank} to encode and decode RPC payloads to use the metadata. Client applications use the metadata to interact with the node, parse responses, and format message payloads sent to the node. - -## Metadata Format - -Although the SCALE-encoded bytes can be decoded using the `frame-metadata` and [`parity-scale-codec`](https://github.com/paritytech/parity-scale-codec){target=\_blank} libraries, there are other tools, such as `subxt` and the Polkadot-JS API, that can convert the raw data to human-readable JSON format. - -The types and type definitions included in the metadata returned by the `state_getMetadata` RPC call depend on the runtime's metadata version. - -In general, the metadata includes the following information: - -- A constant identifying the file as containing metadata. -- The version of the metadata format used in the runtime. -- Type definitions for all types used in the runtime and generated by the `scale-info` crate. -- Pallet information for the pallets included in the runtime in the order that they are defined in the `construct_runtime` macro. - -!!!tip - Depending on the frontend library used (such as the [Polkadot API](https://papi.how/){target=\_blank}), they may format the metadata differently than the raw format shown. - -The following example illustrates a condensed and annotated section of metadata decoded and converted to JSON: - -```json -[ - 1635018093, - { - "V14": { - "types": { - "types": [{}] - }, - "pallets": [{}], - "extrinsic": { - "ty": 126, - "version": 4, - "signed_extensions": [{}] - }, - "ty": 141 - } - } -] - -``` - -The constant `1635018093` is a magic number that identifies the file as a metadata file. The rest of the metadata is divided into the `types`, `pallets`, and `extrinsic` sections: - -- The `types` section contains an index of the types and information about each type's type signature. -- The `pallets` section contains information about each pallet in the runtime. -- The `extrinsic` section describes the type identifier and transaction format version that the runtime uses. - -Different extrinsic versions can have varying formats, especially when considering [signed transactions](/reference/parachains/blocks-transactions-fees/transactions/#signed-transactions){target=\_blank}. - -### Pallets - -The following is a condensed and annotated example of metadata for a single element in the `pallets` array (the [`sudo`](https://paritytech.github.io/polkadot-sdk/master/pallet_sudo/index.html){target=\_blank} pallet): - -```json -{ - "name": "Sudo", - "storage": { - "prefix": "Sudo", - "entries": [ - { - "name": "Key", - "modifier": "Optional", - "ty": { - "Plain": 0 - }, - "default": [0], - "docs": ["The `AccountId` of the sudo key."] - } - ] - }, - "calls": { - "ty": 117 - }, - "event": { - "ty": 42 - }, - "constants": [], - "error": { - "ty": 124 - }, - "index": 8 -} - -``` - -Every element metadata contains the name of the pallet it represents and information about its storage, calls, events, and errors. You can look up details about the definition of the calls, events, and errors by viewing the type index identifier. The type index identifier is the `u32` integer used to access the type information for that item. For example, the type index identifier for calls in the Sudo pallet is 117. If you view information for that type identifier in the `types` section of the metadata, it provides information about the available calls, including the documentation for each call. - -For example, the following is a condensed excerpt of the calls for the Sudo pallet: - -```json -{ - "id": 117, - "type": { - "path": ["pallet_sudo", "pallet", "Call"], - "params": [ - { - "name": "T", - "type": null - } - ], - "def": { - "variant": { - "variants": [ - { - "name": "sudo", - "fields": [ - { - "name": "call", - "type": 114, - "typeName": "Box<::RuntimeCall>" - } - ], - "index": 0, - "docs": [ - "Authenticates sudo key, dispatches a function call with `Root` origin" - ] - }, - { - "name": "sudo_unchecked_weight", - "fields": [ - { - "name": "call", - "type": 114, - "typeName": "Box<::RuntimeCall>" - }, - { - "name": "weight", - "type": 8, - "typeName": "Weight" - } - ], - "index": 1, - "docs": [ - "Authenticates sudo key, dispatches a function call with `Root` origin" - ] - }, - { - "name": "set_key", - "fields": [ - { - "name": "new", - "type": 103, - "typeName": "AccountIdLookupOf" - } - ], - "index": 2, - "docs": [ - "Authenticates current sudo key, sets the given AccountId (`new`) as the new sudo" - ] - }, - { - "name": "sudo_as", - "fields": [ - { - "name": "who", - "type": 103, - "typeName": "AccountIdLookupOf" - }, - { - "name": "call", - "type": 114, - "typeName": "Box<::RuntimeCall>" - } - ], - "index": 3, - "docs": [ - "Authenticates sudo key, dispatches a function call with `Signed` origin from a given account" - ] - } - ] - } - } - } -} - -``` - -For each field, you can access type information and metadata for the following: - -- **Storage metadata**: Provides the information required to enable applications to get information for specific storage items. -- **Call metadata**: Includes information about the runtime calls defined by the `#[pallet]` macro including call names, arguments and documentation. -- **Event metadata**: Provides the metadata generated by the `#[pallet::event]` macro, including the name, arguments, and documentation for each pallet event. -- **Constants metadata**: Provides metadata generated by the `#[pallet::constant]` macro, including the name, type, and hex-encoded value of the constant. -- **Error metadata**: Provides metadata generated by the `#[pallet::error]` macro, including the name and documentation for each pallet error. - -!!!tip - Type identifiers change from time to time, so you should avoid relying on specific type identifiers in your applications. - -### Extrinsic - -The runtime generates extrinsic metadata and provides useful information about transaction format. When decoded, the metadata contains the transaction version and the list of signed extensions. - -For example: - -```json -{ - "extrinsic": { - "ty": 126, - "version": 4, - "signed_extensions": [ - { - "identifier": "CheckNonZeroSender", - "ty": 132, - "additional_signed": 41 - }, - { - "identifier": "CheckSpecVersion", - "ty": 133, - "additional_signed": 4 - }, - { - "identifier": "CheckTxVersion", - "ty": 134, - "additional_signed": 4 - }, - { - "identifier": "CheckGenesis", - "ty": 135, - "additional_signed": 11 - }, - { - "identifier": "CheckMortality", - "ty": 136, - "additional_signed": 11 - }, - { - "identifier": "CheckNonce", - "ty": 138, - "additional_signed": 41 - }, - { - "identifier": "CheckWeight", - "ty": 139, - "additional_signed": 41 - }, - { - "identifier": "ChargeTransactionPayment", - "ty": 140, - "additional_signed": 41 - } - ] - }, - "ty": 141 -} - -``` - -The type system is [composite](https://paritytech.github.io/polkadot-sdk/master/polkadot_sdk_docs/reference_docs/frame_runtime_types/index.html){target=\_blank}, meaning each type identifier contains a reference to a specific type or to another type identifier that provides information about the associated primitive types. - -For example, you can encode the `BitVec` type, but to decode it properly, you must know the types used for the `Order` and `Store` types. To find type information for `Order` and `Store`, you can use the path in the decoded JSON to locate their type identifiers. - -## Included RPC APIs - -A standard node comes with the following APIs to interact with a node: - -- **[`AuthorApiServer`](https://paritytech.github.io/polkadot-sdk/master/sc_rpc/author/trait.AuthorApiServer.html){target=\_blank}**: Make calls into a full node, including authoring extrinsics and verifying session keys. -- **[`ChainApiServer`](https://paritytech.github.io/polkadot-sdk/master/sc_rpc/chain/trait.ChainApiServer.html){target=\_blank}**: Retrieve block header and finality information. -- **[`OffchainApiServer`](https://paritytech.github.io/polkadot-sdk/master/sc_rpc/offchain/trait.OffchainApiServer.html){target=\_blank}**: Make RPC calls for off-chain workers. -- **[`StateApiServer`](https://paritytech.github.io/polkadot-sdk/master/sc_rpc/state/trait.StateApiServer.html){target=\_blank}**: Query information about on-chain state such as runtime version, storage items, and proofs. -- **[`SystemApiServer`](https://paritytech.github.io/polkadot-sdk/master/sc_rpc/system/trait.SystemApiServer.html){target=\_blank}**: Retrieve information about network state, such as connected peers and node roles. - -## Additional Resources - -The following tools can help you locate and decode metadata: - -- [Subxt Explorer](https://paritytech.github.io/subxt-explorer/#/){target=\_blank} -- [Metadata Portal 🌗](https://github.com/paritytech/metadata-portal){target=\_blank} -- [De[code] Sub[strate]](https://github.com/paritytech/desub){target=\_blank} - - --- Page Title: Contract Deployment @@ -3974,382 +3540,91 @@ PolkaVM differs from the EVM in two key ways that make it faster, more hardware- --- -Page Title: E2E Testing with Moonwall +Page Title: Fork a Parachain Using Chopsticks -- Source (raw): https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/reference-tools-moonwall.md -- Canonical (HTML): https://docs.polkadot.com/reference/tools/moonwall/ -- Summary: Enhance blockchain end-to-end testing with Moonwall's standardized environment setup, comprehensive configuration management, and simple network interactions. +- Source (raw): https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/parachains-testing-fork-a-parachain.md +- Canonical (HTML): https://docs.polkadot.com/parachains/testing/fork-a-parachain/ +- Summary: Simplify Polkadot SDK development with Chopsticks. Learn essential features, how to install Chopsticks, and how to configure local blockchain forks. -# E2E Testing with Moonwall +# Fork a Parachain Using Chopsticks ## Introduction -Moonwall is an end-to-end testing framework designed explicitly for Polkadot SDK-based blockchain networks. It addresses one of the most significant challenges in blockchain development: managing complex test environments and network configurations. +[Chopsticks](https://github.com/AcalaNetwork/chopsticks/){target=\_blank}, developed by the [Acala Foundation](https://github.com/AcalaNetwork){target=\_blank}, is a versatile tool tailored for developers working on Polkadot SDK-based blockchains. With Chopsticks, you can fork live chains locally, replay blocks to analyze extrinsics, and simulate complex scenarios like XCM interactions all without deploying to a live network. -Moonwall consolidates this complexity by providing the following: +This guide walks you through installing Chopsticks and provides information on configuring a local blockchain fork. By streamlining testing and experimentation, Chopsticks empowers developers to innovate and accelerate their blockchain projects within the Polkadot ecosystem. -- A centralized configuration management system that explicitly defines all network parameters. -- A standardized approach to environment setup across different Substrate-based chains. -- Built-in utilities for common testing scenarios and network interactions. +For additional support and information, please reach out through [GitHub Issues](https://github.com/AcalaNetwork/chopsticks/issues){target=_blank}. -Developers can focus on writing meaningful tests rather than managing infrastructure complexities or searching through documentation for configuration options. +!!! warning + Chopsticks uses [Smoldot](https://github.com/smol-dot/smoldot){target=_blank} light client, which only supports the native Polkadot SDK API. Consequently, a Chopsticks-based fork doesn't support Ethereum JSON-RPC calls, meaning you cannot use it to fork your chain and connect Metamask. ## Prerequisites Before you begin, ensure you have the following installed: -- [Node.js](https://nodejs.org/en/){target=\_blank} (version 20.10 or higher). -- A package manager such as [npm](https://www.npmjs.com/){target=\_blank}, [yarn](https://yarnpkg.com/){target=\_blank}, or [pnpm](https://pnpm.io/){target=\_blank}. - -## Install Moonwall +- [Node.js](https://nodejs.org/en/){target=\_blank}. +- A package manager such as [npm](https://www.npmjs.com/){target=\_blank}, which should be installed with Node.js by default, or [Yarn](https://yarnpkg.com/){target=\_blank}. -Moonwall can be installed globally for system-wide access or locally within specific projects. This section covers both installation methods. +## Install Chopsticks -!!! tip - This documentation corresponds to Moonwall version `5.15.0`. To avoid compatibility issues with the documented features, ensure you're using the matching version. +You can install Chopsticks globally or locally in your project. Choose the option that best fits your development workflow. This documentation explains the features of Chopsticks version `1.2.2`. Make sure you're using the correct version to match these instructions. ### Global Installation -Global installation provides system-wide access to the Moonwall CLI, making it ideal for developers working across multiple blockchain projects. Install it by running one of the following commands: - -=== "npm" - - ```bash - npm install -g @moonwall/cli@5.15.0 - ``` - -=== "pnpm" - - ```bash - pnpm -g install @moonwall/cli@5.15.0 - ``` - -=== "yarn" +To install Chopsticks globally, allowing you to use it across multiple projects, run: - ```bash - yarn global add @moonwall/cli@5.15.0 - ``` +```bash +npm i -g @acala-network/chopsticks@1.2.2 +``` -Now, you can run the `moonwall` command from your terminal. +Now, you should be able to run the `chopsticks` command from your terminal. ### Local Installation -Local installation is recommended for better dependency management and version control within a specific project. First, initialize your project: +To use Chopsticks in a specific project, first create a new directory and initialize a Node.js project: ```bash -mkdir my-moonwall-project -cd my-moonwall-project +mkdir my-chopsticks-project +cd my-chopsticks-project npm init -y ``` -Then, install it as a local dependency: - -=== "npm" - - ```bash - npm install @moonwall/cli@5.15.0 - ``` - -=== "pnpm" - - ```bash - pnpm install @moonwall/cli@5.15.0 - ``` - -=== "yarn" - - ```bash - yarn add @moonwall/cli@5.15.0 - ``` +Then, install Chopsticks as a local dependency: -## Initialize Moonwall +```bash +npm i @acala-network/chopsticks@1.2.2 +``` -The `moonwall init` command launches an interactive wizard to create your configuration file: +Finally, you can run Chopsticks using the `npx` command. To see all available options and commands, run it with the `--help` flag: ```bash -moonwall init +npx @acala-network/chopsticks --help ``` -During setup, you will see prompts for the following parameters: - -- **`label`**: Identifies your test configuration. -- **`global timeout`**: Maximum time (ms) for test execution. -- **`environment name`**: Name for your testing environment. -- **`network foundation`**: Type of blockchain environment to use. -- **`tests directory`**: Location of your test files. +## Configure Chopsticks -Select `Enter` to accept defaults or input custom values. You should see something like this: +To run Chopsticks, you need to configure some parameters. This can be set either through using a configuration file or the command line interface (CLI). The parameters that can be configured are as follows: -
- moonwall init - ✔ Provide a label for the config file moonwall_config - ✔ Provide a global timeout value 30000 - ✔ Provide a name for this environment default_env - ✔ What type of network foundation is this? dev - ✔ Provide the path for where tests for this environment are kept tests/ - ? Would you like to generate this config? (no to restart from beginning) (Y/n) -
+- **`genesis`**: The link to a parachain's raw genesis file to build the fork from, instead of an endpoint. +- **`timestamp`**: Timestamp of the block to fork from. +- **`endpoint`**: The endpoint of the parachain to fork. +- **`block`**: Use to specify at which block hash or number to replay the fork. +- **`wasm-override`**: Path of the Wasm to use as the parachain runtime, instead of an endpoint's runtime. +- **`db`**: Path to the name of the file that stores or will store the parachain's database. +- **`config`**: Path or URL of the config file. +- **`port`**: The port to expose an endpoint on. +- **`build-block-mode`**: How blocks should be built in the fork: batch, manual, instant. +- **`import-storage`**: A pre-defined JSON/YAML storage path to override in the parachain's storage. +- **`allow-unresolved-imports`**: Whether to allow Wasm unresolved imports when using a Wasm to build the parachain. +- **`html`**: Include to generate storage diff preview between blocks. +- **`mock-signature-host`**: Mock signature host so that any signature starts with `0xdeadbeef` and filled by `0xcd` is considered valid. -The wizard generates a `moonwall.config` file: +### Configuration File -```json -{ - "label": "moonwall_config", - "defaultTestTimeout": 30000, - "environments": [ - { - "name": "default_env", - "testFileDir": ["tests/"], - "foundation": { - "type": "dev" - } - } - ] -} +The Chopsticks source repository includes a collection of [YAML](https://yaml.org/){target=\_blank} files that can be used to set up various Polkadot SDK chains locally. You can download these configuration files from the [repository's `configs` folder](https://github.com/AcalaNetwork/chopsticks/tree/master/configs){target=\_blank}. -``` - -The default configuration requires specific details about your blockchain node and test requirements: - -- The `foundation` object defines how your test blockchain node will be launched and managed. The dev foundation, which runs a local node binary, is used for local development. - - For more information about available options, check the [Foundations](https://moonsong-labs.github.io/moonwall/guide/intro/foundations.html){target=\_blank} section. - -- The `connections` array specifies how your tests will interact with the blockchain node. This typically includes provider configuration and endpoint details. - - A provider is a tool that allows you or your application to connect to a blockchain network and simplifies the low-level details of the process. A provider handles submitting transactions, reading state, and more. For more information on available providers, check the [Providers supported](https://moonsong-labs.github.io/moonwall/guide/intro/providers.html#providers-supported){target=\_blank} page in the Moonwall documentation. - -Here's a complete configuration example for testing a local node using Polkadot.js as a provider: - -```json -{ - "label": "moonwall_config", - "defaultTestTimeout": 30000, - "environments": [ - { - "name": "default_env", - "testFileDir": ["tests/"], - "foundation": { - "launchSpec": [ - { - "binPath": "./node-template", - "newRpcBehaviour": true, - "ports": { "rpcPort": 9944 } - } - ], - "type": "dev" - }, - "connections": [ - { - "name": "myconnection", - "type": "polkadotJs", - "endpoints": ["ws://127.0.0.1:9944"] - } - ] - } - ] -} - -``` - -## Writing Tests - -Moonwall uses the [`describeSuite`](https://github.com/Moonsong-Labs/moonwall/blob/7568048c52e9f7844f38fb4796ae9e1b9205fdaa/packages/cli/src/lib/runnerContext.ts#L65){target=\_blank} function to define test suites, like using [Mocha](https://mochajs.org/){target=\_blank}. Each test suite requires the following: - -- **`id`**: Unique identifier for the suite. -- **`title`**: Descriptive name for the suite. -- **`foundationMethods`**: Specifies the testing environment (e.g., `dev` for local node testing). -- **`testCases`**: A callback function that houses the individual test cases of this suite. - -The following example shows how to test a balance transfer between two accounts: - -```ts -import '@polkadot/api-augment'; -import { describeSuite, expect } from '@moonwall/cli'; -import { Keyring } from '@polkadot/api'; - -describeSuite({ - id: 'D1', - title: 'Demo suite', - foundationMethods: 'dev', - testCases: ({ it, context, log }) => { - it({ - id: 'T1', - title: 'Test Case', - test: async () => { - // Set up polkadot.js API and testing accounts - let api = context.polkadotJs(); - let alice = new Keyring({ type: 'sr25519' }).addFromUri('//Alice'); - let charlie = new Keyring({ type: 'sr25519' }).addFromUri('//Charlie'); - - // Query Charlie's account balance before transfer - const balanceBefore = (await api.query.system.account(charlie.address)) - .data.free; - - // Before transfer, Charlie's account balance should be 0 - expect(balanceBefore.toString()).toEqual('0'); - log('Balance before: ' + balanceBefore.toString()); - - // Transfer from Alice to Charlie - const amount = 1000000000000000; - await api.tx.balances - .transferAllowDeath(charlie.address, amount) - .signAndSend(alice); - - // Wait for the transaction to be included in a block. - // This is necessary because the balance is not updated immediately. - // Block time is 6 seconds. - await new Promise((resolve) => setTimeout(resolve, 6000)); - - // Query Charlie's account balance after transfer - const balanceAfter = (await api.query.system.account(charlie.address)) - .data.free; - - // After transfer, Charlie's account balance should be 1000000000000000 - expect(balanceAfter.toString()).toEqual(amount.toString()); - log('Balance after: ' + balanceAfter.toString()); - }, - }); - }, -}); - -``` - -This test demonstrates several key concepts: - -- Initializing the Polkadot.js API through Moonwall's context and setting up test accounts. -- Querying on-chain state. -- Executing transactions. -- Waiting for block inclusion. -- Verifying results using assertions. - -## Running the Tests - -Execute your tests using the `test` Moonwall CLI command. For the default environment setup run: - -```bash -moonwall test default_env -c moonwall.config -``` - -The test runner will output detailed results showing: - -- Test suite execution status. -- Individual test case results. -- Execution time. -- Detailed logs and error messages (if any). - -Example output: -
- moonwall test default_env -c moonwall.config - stdout | tests/test1.ts > 🗃️ D1 Demo suite > 📁 D1T1 Test Case - 2025-01-21T19:27:55.624Z test:default_env Balance before: 0 - - stdout | tests/test1.ts > 🗃️ D1 Demo suite > 📁 D1T1 Test Case - 2025-01-21T19:28:01.637Z test:default_env Balance after: 1000000000000000 - - ✓ default_env tests/test1.ts (1 test) 6443ms - ✓ 🗃️ D1 Demo suite > 📁 D1T1 Test Case 6028ms - - Test Files 1 passed (1) - Tests 1 passed (1) - Start at 16:27:53 - Duration 7.95s (transform 72ms, setup 0ms, collect 1.31s, tests 6.44s, environment 0ms, prepare 46ms) - - ✅ All tests passed -
- -## Where to Go Next - -For a comprehensive guide to Moonwall's full capabilities, available configurations, and advanced usage, see the official [Moonwall](https://moonsong-labs.github.io/moonwall/){target=\_blank} documentation. - - ---- - -Page Title: Fork a Parachain Using Chopsticks - -- Source (raw): https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/parachains-testing-fork-a-parachain.md -- Canonical (HTML): https://docs.polkadot.com/parachains/testing/fork-a-parachain/ -- Summary: Simplify Polkadot SDK development with Chopsticks. Learn essential features, how to install Chopsticks, and how to configure local blockchain forks. - -# Fork a Parachain Using Chopsticks - -## Introduction - -[Chopsticks](https://github.com/AcalaNetwork/chopsticks/){target=\_blank}, developed by the [Acala Foundation](https://github.com/AcalaNetwork){target=\_blank}, is a versatile tool tailored for developers working on Polkadot SDK-based blockchains. With Chopsticks, you can fork live chains locally, replay blocks to analyze extrinsics, and simulate complex scenarios like XCM interactions all without deploying to a live network. - -This guide walks you through installing Chopsticks and provides information on configuring a local blockchain fork. By streamlining testing and experimentation, Chopsticks empowers developers to innovate and accelerate their blockchain projects within the Polkadot ecosystem. - -For additional support and information, please reach out through [GitHub Issues](https://github.com/AcalaNetwork/chopsticks/issues){target=_blank}. - -!!! warning - Chopsticks uses [Smoldot](https://github.com/smol-dot/smoldot){target=_blank} light client, which only supports the native Polkadot SDK API. Consequently, a Chopsticks-based fork doesn't support Ethereum JSON-RPC calls, meaning you cannot use it to fork your chain and connect Metamask. - -## Prerequisites - -Before you begin, ensure you have the following installed: - -- [Node.js](https://nodejs.org/en/){target=\_blank}. -- A package manager such as [npm](https://www.npmjs.com/){target=\_blank}, which should be installed with Node.js by default, or [Yarn](https://yarnpkg.com/){target=\_blank}. - -## Install Chopsticks - -You can install Chopsticks globally or locally in your project. Choose the option that best fits your development workflow. This documentation explains the features of Chopsticks version `1.2.2`. Make sure you're using the correct version to match these instructions. - -### Global Installation - -To install Chopsticks globally, allowing you to use it across multiple projects, run: - -```bash -npm i -g @acala-network/chopsticks@1.2.2 -``` - -Now, you should be able to run the `chopsticks` command from your terminal. - -### Local Installation - -To use Chopsticks in a specific project, first create a new directory and initialize a Node.js project: - -```bash -mkdir my-chopsticks-project -cd my-chopsticks-project -npm init -y -``` - -Then, install Chopsticks as a local dependency: - -```bash -npm i @acala-network/chopsticks@1.2.2 -``` - -Finally, you can run Chopsticks using the `npx` command. To see all available options and commands, run it with the `--help` flag: - -```bash -npx @acala-network/chopsticks --help -``` - -## Configure Chopsticks - -To run Chopsticks, you need to configure some parameters. This can be set either through using a configuration file or the command line interface (CLI). The parameters that can be configured are as follows: - -- **`genesis`**: The link to a parachain's raw genesis file to build the fork from, instead of an endpoint. -- **`timestamp`**: Timestamp of the block to fork from. -- **`endpoint`**: The endpoint of the parachain to fork. -- **`block`**: Use to specify at which block hash or number to replay the fork. -- **`wasm-override`**: Path of the Wasm to use as the parachain runtime, instead of an endpoint's runtime. -- **`db`**: Path to the name of the file that stores or will store the parachain's database. -- **`config`**: Path or URL of the config file. -- **`port`**: The port to expose an endpoint on. -- **`build-block-mode`**: How blocks should be built in the fork: batch, manual, instant. -- **`import-storage`**: A pre-defined JSON/YAML storage path to override in the parachain's storage. -- **`allow-unresolved-imports`**: Whether to allow Wasm unresolved imports when using a Wasm to build the parachain. -- **`html`**: Include to generate storage diff preview between blocks. -- **`mock-signature-host`**: Mock signature host so that any signature starts with `0xdeadbeef` and filled by `0xcd` is considered valid. - -### Configuration File - -The Chopsticks source repository includes a collection of [YAML](https://yaml.org/){target=\_blank} files that can be used to set up various Polkadot SDK chains locally. You can download these configuration files from the [repository's `configs` folder](https://github.com/AcalaNetwork/chopsticks/tree/master/configs){target=\_blank}. - -An example of a configuration file for Polkadot is as follows: +An example of a configuration file for Polkadot is as follows: {% raw %} ```yaml @@ -4849,399 +4124,31 @@ The message consists of three instructions described as follows: - **[DepositAsset](https://github.com/polkadot-fellows/xcm-format?tab=readme-ov-file#depositasset){target=\_blank}**: Moves the remaining tokens from the holding register to Bob’s account. ```rust - DepositAsset { - assets: All.into(), - beneficiary: MultiLocation { - parents: 0, - interior: Junction::AccountId32 { - network: None, - id: BOB.clone().into() - }.into(), - }.into() - } - ``` - - - **`All`**: The wildcard for the asset(s) to be deposited. In this case, all assets in the holding register should be deposited. - -This step-by-step process showcases how XCM enables precise state changes within a blockchain system. You can find a complete XCM message example in the [XCM repository](https://github.com/paritytech/xcm-docs/blob/main/examples/src/0_first_look/mod.rs){target=\_blank}. - -## Overview - -XCM revolutionizes cross-chain communication by enabling use cases such as: - -- Token transfers between blockchains. -- Asset locking for cross-chain smart contract interactions. -- Remote execution of functions on other blockchains. - -These functionalities empower developers to build innovative, multi-chain applications, leveraging the strengths of various blockchain networks. To stay updated on XCM’s evolving format or contribute, visit the [XCM repository](https://github.com/paritytech/xcm-docs/blob/main/examples/src/0_first_look/mod.rs){target=\_blank}. - - ---- - -Page Title: Glossary - -- Source (raw): https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/reference-glossary.md -- Canonical (HTML): https://docs.polkadot.com/reference/glossary/ -- Summary: Glossary of terms used within the Polkadot ecosystem, Polkadot SDK, its subsequent libraries, and other relevant Web3 terminology. - -# Glossary - -Key definitions, concepts, and terminology specific to the Polkadot ecosystem are included here. - -Additional glossaries from around the ecosystem you might find helpful: - -- [Polkadot Wiki Glossary](https://wiki.polkadot.com/general/glossary){target=\_blank} -- [Polkadot SDK Glossary](https://paritytech.github.io/polkadot-sdk/master/polkadot_sdk_docs/reference_docs/glossary/index.html){target=\_blank} - -## Authority - -The role in a blockchain that can participate in consensus mechanisms. - -- **[GRANDPA](#grandpa)**: The authorities vote on chains they consider final. -- **[Blind Assignment of Blockchain Extension](#blind-assignment-of-blockchain-extension-babe) (BABE)**: The authorities are also [block authors](#block-author). - -Authority sets can be used as a basis for consensus mechanisms such as the [Nominated Proof of Stake (NPoS)](#nominated-proof-of-stake-npos) protocol. - -## Authority Round (Aura) - -A deterministic [consensus](#consensus) protocol where block production is limited to a rotating list of [authorities](#authority) that take turns creating blocks. In authority round (Aura) consensus, most online authorities are assumed to be honest. It is often used in combination with [GRANDPA](#grandpa) as a [hybrid consensus](#hybrid-consensus) protocol. - -Learn more by reading the official [Aura consensus algorithm](https://openethereum.github.io/Aura){target=\_blank} wiki article. - -## Blind Assignment of Blockchain Extension (BABE) - -A [block authoring](#block-author) protocol similar to [Aura](#authority-round-aura), except [authorities](#authority) win [slots](#slot) based on a Verifiable Random Function (VRF) instead of the round-robin selection method. The winning authority can select a chain and submit a new block. - -Learn more by reading the official Web3 Foundation [BABE research document](https://research.web3.foundation/Polkadot/protocols/block-production/Babe){target=\_blank}. - -## Block Author - -The node responsible for the creation of a block, also called _block producers_. In a Proof of Work (PoW) blockchain, these nodes are called _miners_. - -## Byzantine Fault Tolerance (BFT) - -The ability of a distributed computer network to remain operational if a certain proportion of its nodes or [authorities](#authority) are defective or behaving maliciously. A distributed network is typically considered Byzantine fault tolerant if it can remain functional, with up to one-third of nodes assumed to be defective, offline, actively malicious, and part of a coordinated attack. - -### Byzantine Failure - -The loss of a network service due to node failures that exceed the proportion of nodes required to reach consensus. - -### Practical Byzantine Fault Tolerance (pBFT) - -An early approach to Byzantine fault tolerance (BFT), practical Byzantine fault tolerance (pBFT) systems tolerate Byzantine behavior from up to one-third of participants. - -The communication overhead for such systems is `O(n²)`, where `n` is the number of nodes (participants) in the system. - -### Preimage - -A preimage is the data that is input into a hash function to calculate a hash. Since a hash function is a [one-way function](https://en.wikipedia.org/wiki/One-way_function){target=\_blank}, the output, the hash, cannot be used to reveal the input, the preimage. - -## Call - -In the context of pallets containing functions to be dispatched to the runtime, `Call` is an enumeration data type that describes the functions that can be dispatched with one variant per pallet. A `Call` represents a [dispatch](#dispatchable) data structure object. - -## Chain Specification - -A chain specification file defines the properties required to run a node in an active or new Polkadot SDK-built network. It often contains the initial genesis runtime code, network properties (such as the network's name), the initial state for some pallets, and the boot node list. The chain specification file makes it easy to use a single Polkadot SDK codebase as the foundation for multiple independently configured chains. - -## Collator - -An [author](#block-author) of a [parachain](#parachain) network. -They aren't [authorities](#authority) in themselves, as they require a [relay chain](#relay-chain) to coordinate [consensus](#consensus). - -More details are found on the [Polkadot Collator Wiki](https://wiki.polkadot.com/learn/learn-collator/){target=\_blank}. - -## Collective - -Most often used to refer to an instance of the Collective pallet on Polkadot SDK-based networks such as [Kusama](#kusama) or [Polkadot](#polkadot) if the Collective pallet is part of the FRAME-based runtime for the network. - -## Consensus - -Consensus is the process blockchain nodes use to agree on a chain's canonical fork. It is composed of [authorship](#block-author), finality, and [fork-choice rule](#fork-choice-rulestrategy). In the Polkadot ecosystem, these three components are usually separate and the term consensus often refers specifically to authorship. - -See also [hybrid consensus](#hybrid-consensus). - -## Consensus Algorithm - -Ensures a set of [actors](#authority)—who don't necessarily trust each other—can reach an agreement about the state as the result of some computation. Most consensus algorithms assume that up to one-third of the actors or nodes can be [Byzantine fault tolerant](#byzantine-fault-tolerance-bft). - -Consensus algorithms are generally concerned with ensuring two properties: - -- **Safety**: Indicating that all honest nodes eventually agreed on the state of the chain. -- **Liveness**: Indicating the ability of the chain to keep progressing. - -## Consensus Engine - -The node subsystem responsible for consensus tasks. - -For detailed information about the consensus strategies of the [Polkadot](#polkadot) network, see the [Polkadot Consensus](/reference/polkadot-hub/consensus-and-security/pos-consensus/){target=\_blank} blog series. - -See also [hybrid consensus](#hybrid-consensus). - -## Coretime - -The time allocated for utilizing a core, measured in relay chain blocks. There are two types of coretime: *on-demand* and *bulk*. - -On-demand coretime refers to coretime acquired through bidding in near real-time for the validation of a single parachain block on one of the cores reserved specifically for on-demand orders. They are available as an on-demand coretime pool. Set of cores that are available on-demand. Cores reserved through bulk coretime could also be made available in the on-demand coretime pool, in parts or in entirety. - -Bulk coretime is a fixed duration of continuous coretime represented by an NFT that can be split, shared, or resold. It is managed by the [Broker pallet](https://paritytech.github.io/polkadot-sdk/master/pallet_broker/index.html){target=\_blank}. - -## Development Phrase - -A [mnemonic phrase](https://en.wikipedia.org/wiki/Mnemonic#For_numerical_sequences_and_mathematical_operations){target=\_blank} that is intentionally made public. - -Well-known development accounts, such as Alice, Bob, Charlie, Dave, Eve, and Ferdie, are generated from the same secret phrase: - -``` -bottom drive obey lake curtain smoke basket hold race lonely fit walk -``` - -Many tools in the Polkadot SDK ecosystem, such as [`subkey`](https://github.com/paritytech/polkadot-sdk/tree/polkadot-stable2506-2/substrate/bin/utils/subkey){target=\_blank}, allow you to implicitly specify an account using a derivation path such as `//Alice`. - -## Digest - -An extensible field of the [block header](#header) that encodes information needed by several actors in a blockchain network, including: - -- [Light clients](#light-client) for chain synchronization. -- Consensus engines for block verification. -- The runtime itself, in the case of pre-runtime digests. - -## Dispatchable - -Function objects that act as the entry points in FRAME [pallets](#pallet). Internal or external entities can call them to interact with the blockchain’s state. They are a core aspect of the runtime logic, handling [transactions](#transaction) and other state-changing operations. - -## Events - -A means of recording that some particular [state](#state) transition happened. - -In the context of [FRAME](#frame-framework-for-runtime-aggregation-of-modularized-entities), events are composable data types that each [pallet](#pallet) can individually define. Events in FRAME are implemented as a set of transient storage items inspected immediately after a block has been executed and reset during block initialization. - -## Executor - -A means of executing a function call in a given [runtime](#runtime) with a set of dependencies. -There are two orchestration engines in Polkadot SDK, _WebAssembly_ and _native_. - -- The _native executor_ uses a natively compiled runtime embedded in the node to execute calls. This is a performance optimization available to up-to-date nodes. - -- The _WebAssembly executor_ uses a [Wasm](#webassembly-wasm) binary and a Wasm interpreter to execute calls. The binary is guaranteed to be up-to-date regardless of the version of the blockchain node because it is persisted in the [state](#state) of the Polkadot SDK-based chain. - -## Existential Deposit - -The minimum balance an account is allowed to have in the [Balances pallet](https://paritytech.github.io/polkadot-sdk/master/pallet_balances/index.html){target=\_blank}. Accounts cannot be created with a balance less than the existential deposit amount. - -If an account balance drops below this amount, the Balances pallet uses [a FRAME System API](https://paritytech.github.io/substrate/master/frame_system/pallet/struct.Pallet.html#method.dec_ref){target=\_blank} to drop its references to that account. - -If the Balances pallet reference to an account is dropped, the account can be [reaped](https://paritytech.github.io/substrate/master/frame_system/pallet/struct.Pallet.html#method.allow_death){target=\_blank}. - -## Extrinsic - -A general term for data that originates outside the runtime, is included in a block, and leads to some action. This includes user-initiated transactions and inherent transactions placed into the block by the block builder. - -It is a SCALE-encoded array typically consisting of a version number, signature, and varying data types indicating the resulting runtime function to be called. Extrinsics can take two forms: [inherents](#inherent-transactions) and [transactions](#transaction). - -For more technical details, see the [Polkadot spec](https://spec.polkadot.network/id-extrinsics){target=\_blank}. - -## Fork Choice Rule/Strategy - -A fork choice rule or strategy helps determine which chain is valid when reconciling several network forks. A common fork choice rule is the [longest chain](https://paritytech.github.io/polkadot-sdk/master/sc_consensus/struct.LongestChain.html){target=\_blank}, in which the chain with the most blocks is selected. - -## FRAME (Framework for Runtime Aggregation of Modularized Entities) - -Enables developers to create blockchain [runtime](#runtime) environments from a modular set of components called [pallets](#pallet). It utilizes a set of procedural macros to construct runtimes. - -[Visit the Polkadot SDK docs for more details on FRAME.](https://paritytech.github.io/polkadot-sdk/master/polkadot_sdk_docs/polkadot_sdk/frame_runtime/index.html){target=\_blank} - -## Full Node - -A node that prunes historical states, keeping only recently finalized block states to reduce storage needs. Full nodes provide current chain state access and allow direct submission and validation of [extrinsics](#extrinsic), maintaining network decentralization. - -## Genesis Configuration - -A mechanism for specifying the initial state of a blockchain. By convention, this initial state or first block is commonly referred to as the genesis state or genesis block. The genesis configuration for Polkadot SDK-based chains is accomplished by way of a [chain specification](#chain-specification) file. - -## GRANDPA - -A deterministic finality mechanism for blockchains that is implemented in the [Rust](https://www.rust-lang.org/){target=\_blank} programming language. - -The [formal specification](https://github.com/w3f/consensus/blob/master/pdf/grandpa-old.pdf){target=\_blank} is maintained by the [Web3 Foundation](https://web3.foundation/){target=\_blank}. - -## Header - -A structure that aggregates the information used to summarize a block. Primarily, it consists of cryptographic information used by [light clients](#light-client) to get minimally secure but very efficient chain synchronization. - -## Hybrid Consensus - -A blockchain consensus protocol that consists of independent or loosely coupled mechanisms for [block production](#block-author) and finality. - -Hybrid consensus allows the chain to grow as fast as probabilistic consensus protocols, such as [Aura](#authority-round-aura), while maintaining the same level of security as deterministic finality consensus protocols, such as [GRANDPA](#grandpa). - -## Inherent Transactions - -A special type of unsigned transaction, referred to as _inherents_, that enables a block authoring node to insert information that doesn't require validation directly into a block. - -Only the block-authoring node that calls the inherent transaction function can insert data into its block. In general, validators assume the data inserted using an inherent transaction is valid and reasonable even if it can't be deterministically verified. - -## JSON-RPC - -A stateless, lightweight remote procedure call protocol encoded in JavaScript Object Notation (JSON). JSON-RPC provides a standard way to call functions on a remote system by using JSON. - -For Polkadot SDK, this protocol is implemented through the [Parity JSON-RPC](https://github.com/paritytech/jsonrpc){target=\_blank} crate. - -## Keystore - -A subsystem for managing keys for the purpose of producing new blocks. - -## Kusama - -[Kusama](https://kusama.network/){target=\_blank} is a Polkadot SDK-based blockchain that implements a design similar to the [Polkadot](#polkadot) network. - -Kusama is a [canary](https://en.wiktionary.org/wiki/canary_in_a_coal_mine){target=\_blank} network and is referred to as [Polkadot's "wild cousin."](https://wiki.polkadot.com/learn/learn-comparisons-kusama/){target=\_blank}. - -As a canary network, Kusama is expected to be more stable than a test network like [Westend](#westend) but less stable than a production network like [Polkadot](#polkadot). Kusama is controlled by its network participants and is intended to be stable enough to encourage meaningful experimentation. - -## libp2p - -A peer-to-peer networking stack that allows the use of many transport mechanisms, including WebSockets (usable in a web browser). - -Polkadot SDK uses the [Rust implementation](https://github.com/libp2p/rust-libp2p){target=\_blank} of the `libp2p` networking stack. - -## Light Client - -A type of blockchain node that doesn't store the [chain state](#state) or produce blocks. - -A light client can verify cryptographic primitives and provides a [remote procedure call (RPC)](https://en.wikipedia.org/wiki/Remote_procedure_call){target=\_blank} server, enabling blockchain users to interact with the network. - -## Metadata - -Data that provides information about one or more aspects of a system. -The metadata that exposes information about a Polkadot SDK blockchain enables you to interact with that system. - -## Nominated Proof of Stake (NPoS) - -A method for determining [validators](#validator) or _[authorities](#authority)_ based on a willingness to commit their stake to the proper functioning of one or more block-producing nodes. - -## Oracle - -An entity that connects a blockchain to a non-blockchain data source. Oracles enable the blockchain to access and act upon information from existing data sources and incorporate data from non-blockchain systems and services. - -## Origin - -A [FRAME](#frame-framework-for-runtime-aggregation-of-modularized-entities) primitive that identifies the source of a [dispatched](#dispatchable) function call into the [runtime](#runtime). The FRAME System pallet defines three built-in [origins](#origin). As a [pallet](#pallet) developer, you can also define custom origins, such as those defined by the [Collective pallet](https://paritytech.github.io/substrate/master/pallet_collective/enum.RawOrigin.html){target=\_blank}. - -## Pallet - -A module that can be used to extend the capabilities of a [FRAME](#frame-framework-for-runtime-aggregation-of-modularized-entities)-based [runtime](#runtime). -Pallets bundle domain-specific logic with runtime primitives like [events](#events) and [storage items](#storage-item). - -## Parachain - -A parachain is a blockchain that derives shared infrastructure and security from a _[relay chain](#relay-chain)_. -You can learn more about parachains on the [Polkadot Wiki](https://wiki.polkadot.com/learn/learn-parachains/){target=\_blank}. - -## Paseo - -Paseo TestNet provisions testing on Polkadot's "production" runtime, which means less chance of feature or code mismatch when developing parachain apps. Specifically, after the [Polkadot Technical fellowship](https://wiki.polkadot.com/learn/learn-polkadot-technical-fellowship/){target=\_blank} proposes a runtime upgrade for Polkadot, this TestNet is updated, giving a period where the TestNet will be ahead of Polkadot to allow for testing. - -## Polkadot - -The [Polkadot network](https://polkadot.com/){target=\_blank} is a blockchain that serves as the central hub of a heterogeneous blockchain network. It serves the role of the [relay chain](#relay-chain) and provides shared infrastructure and security to support [parachains](#parachain). - -## Polkadot Cloud - -Polkadot Cloud is a platform for deploying resilient, customizable and scalable Web3 applications through Polkadot's functionality. It encompasses the wider Polkadot network infrastructure and security layer where parachains operate. The platform enables users to launch Ethereum-compatible chains, build specialized blockchains, and flexibly manage computing resources through on-demand or bulk coretime purchases. Initially launched with basic parachain functionality, Polkadot Cloud has evolved to offer enhanced flexibility with features like coretime, elastic scaling, and async backing for improved performance. - -## Polkadot Hub - -Polkadot Hub is a Layer 1 platform that serves as the primary entry point to the Polkadot ecosystem, providing essential functionality without requiring parachain deployment. It offers core services including smart contracts, identity management, staking, governance, and interoperability with other ecosystems, making it simple and fast for both builders and users to get started in Web3. - -## PolkaVM - -PolkaVM is a custom virtual machine optimized for performance, leveraging a RISC-V-based architecture to support Solidity and any language that compiles to RISC-V. It is specifically designed for the Polkadot ecosystem, enabling smart contract deployment and execution. - -## Relay Chain - -Relay chains are blockchains that provide shared infrastructure and security to the [parachains](#parachain) in the network. In addition to providing [consensus](#consensus) capabilities, relay chains allow parachains to communicate and exchange digital assets without needing to trust one another. - -## Rococo - -A [parachain](#parachain) test network for the Polkadot network. The [Rococo](#rococo) network is a Polkadot SDK-based blockchain with an October 14, 2024 deprecation date. Development teams are encouraged to use the Paseo TestNet instead. - -## Runtime - -The runtime represents the [state transition function](#state-transition-function-stf) for a blockchain. In Polkadot SDK, the runtime is stored as a [Wasm](#webassembly-wasm) binary in the chain state. The Runtime is stored under a unique state key and can be modified during the execution of the state transition function. - -## Slot - -A fixed, equal interval of time used by consensus engines such as [Aura](#authority-round-aura) and [BABE](#blind-assignment-of-blockchain-extension-babe). In each slot, a subset of [authorities](#authority) is permitted, or obliged, to [author](#block-author) a block. - -## Sovereign Account - -The unique account identifier for each chain in the relay chain ecosystem. It is often used in cross-consensus (XCM) interactions to sign XCM messages sent to the relay chain or other chains in the ecosystem. - -The sovereign account for each chain is a root-level account that can only be accessed using the Sudo pallet or through governance. The account identifier is calculated by concatenating the Blake2 hash of a specific text string and the registered parachain identifier. - -## SS58 Address Format - -A public key address based on the Bitcoin [`Base-58-check`](https://en.bitcoin.it/wiki/Base58Check_encoding){target=\_blank} encoding. Each Polkadot SDK SS58 address uses a `base-58` encoded value to identify a specific account on a specific Polkadot SDK-based chain - -The [canonical `ss58-registry`](https://github.com/paritytech/ss58-registry){target=\_blank} provides additional details about the address format used by different Polkadot SDK-based chains, including the network prefix and website used for different networks - -## State Transition Function (STF) - -The logic of a blockchain that determines how the state changes when a block is processed. In Polkadot SDK, the state transition function is effectively equivalent to the [runtime](#runtime). - -## Storage Item - -[FRAME](#frame-framework-for-runtime-aggregation-of-modularized-entities) primitives that provide type-safe data persistence capabilities to the [runtime](#runtime). -Learn more in the [storage items](https://paritytech.github.io/polkadot-sdk/master/frame_support/storage/types/index.html){target=\_blank} reference document in the Polkadot SDK. - -## Substrate - -A flexible framework for building modular, efficient, and upgradeable blockchains. Substrate is written in the [Rust](https://www.rust-lang.org/){target=\_blank} programming language and is maintained by [Parity Technologies](https://www.parity.io/){target=\_blank}. - -## Transaction - -An [extrinsic](#extrinsic) that includes a signature that can be used to verify the account authorizing it inherently or via [signed extensions](https://paritytech.github.io/polkadot-sdk/master/polkadot_sdk_docs/reference_docs/signed_extensions/index.html){target=\_blank}. - -## Transaction Era - -A definable period expressed as a range of block numbers during which a transaction can be included in a block. -Transaction eras are used to protect against transaction replay attacks if an account is reaped and its replay-protecting nonce is reset to zero. - -## Trie (Patricia Merkle Tree) - -A data structure used to represent sets of key-value pairs and enables the items in the data set to be stored and retrieved using a cryptographic hash. Because incremental changes to the data set result in a new hash, retrieving data is efficient even if the data set is very large. With this data structure, you can also prove whether the data set includes any particular key-value pair without access to the entire data set. - -In Polkadot SDK-based blockchains, state is stored in a trie data structure that supports the efficient creation of incremental digests. This trie is exposed to the [runtime](#runtime) as [a simple key/value map](#storage-item) where both keys and values can be arbitrary byte arrays. - -## Validator - -A validator is a node that participates in the consensus mechanism of the network. Its roles include block production, transaction validation, network integrity, and security maintenance. - -## WebAssembly (Wasm) - -An execution architecture that allows for the efficient, platform-neutral expression of -deterministic, machine-executable logic. - -[Wasm](https://webassembly.org/){target=\_blank} can be compiled from many languages, including -the [Rust](https://www.rust-lang.org/){target=\_blank} programming language. Polkadot SDK-based chains use a Wasm binary to provide portable [runtimes](#runtime) that can be included as part of the chain's state. - -## Weight - -A convention used in Polkadot SDK-based blockchains to measure and manage the time it takes to validate a block. -Polkadot SDK defines one unit of weight as one picosecond of execution time on reference hardware. + DepositAsset { + assets: All.into(), + beneficiary: MultiLocation { + parents: 0, + interior: Junction::AccountId32 { + network: None, + id: BOB.clone().into() + }.into(), + }.into() + } + ``` -The maximum block weight should be equivalent to one-third of the target block time with an allocation of one-third each for: + - **`All`**: The wildcard for the asset(s) to be deposited. In this case, all assets in the holding register should be deposited. + +This step-by-step process showcases how XCM enables precise state changes within a blockchain system. You can find a complete XCM message example in the [XCM repository](https://github.com/paritytech/xcm-docs/blob/main/examples/src/0_first_look/mod.rs){target=\_blank}. -- Block construction -- Network propagation -- Import and verification +## Overview -By defining weights, you can trade-off the number of transactions per second and the hardware required to maintain the target block time appropriate for your use case. Weights are defined in the runtime, meaning you can tune them using runtime updates to keep up with hardware and software improvements. +XCM revolutionizes cross-chain communication by enabling use cases such as: -## Westend +- Token transfers between blockchains. +- Asset locking for cross-chain smart contract interactions. +- Remote execution of functions on other blockchains. -Westend is a Parity-maintained, Polkadot SDK-based blockchain that serves as a test network for the [Polkadot](#polkadot) network. +These functionalities empower developers to build innovative, multi-chain applications, leveraging the strengths of various blockchain networks. To stay updated on XCM’s evolving format or contribute, visit the [XCM repository](https://github.com/paritytech/xcm-docs/blob/main/examples/src/0_first_look/mod.rs){target=\_blank}. --- @@ -5666,76 +4573,6 @@ To stop the node, press `Control-C` in the terminal. ---- - -Page Title: Interoperability - -- Source (raw): https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/reference-parachains-interoperability.md -- Canonical (HTML): https://docs.polkadot.com/reference/parachains/interoperability/ -- Summary: Explore the importance of interoperability in the Polkadot ecosystem, covering XCM, bridges, and cross-chain communication. - -# Interoperability - -## Introduction - -Interoperability lies at the heart of the Polkadot ecosystem, enabling communication and collaboration across a diverse range of blockchains. By bridging the gaps between parachains, relay chains, and even external networks, Polkadot unlocks the potential for truly decentralized applications, efficient resource sharing, and scalable solutions. - -Polkadot’s design ensures that blockchains can transcend their individual limitations by working together as part of a unified system. This cooperative architecture is what sets Polkadot apart in the blockchain landscape. - -## Why Interoperability Matters - -The blockchain ecosystem is inherently fragmented. Different blockchains excel in specialized domains such as finance, gaming, or supply chain management, but these chains function in isolation without interoperability. This lack of connectivity stifles the broader utility of blockchain technology. - -Interoperability solves this problem by enabling blockchains to: - -- **Collaborate across networks**: Chains can interact to share assets, functionality, and data, creating synergies that amplify their individual strengths. -- **Achieve greater scalability**: Specialized chains can offload tasks to others, optimizing performance and resource utilization. -- **Expand use-case potential**: Cross-chain applications can leverage features from multiple blockchains, unlocking novel user experiences and solutions. - -In the Polkadot ecosystem, interoperability transforms a collection of isolated chains into a cohesive, efficient network, pushing the boundaries of what blockchains can achieve together. - -## Key Mechanisms for Interoperability - -At the core of Polkadot's cross-chain collaboration are foundational technologies designed to break down barriers between networks. These mechanisms empower blockchains to communicate, share resources, and operate as a cohesive ecosystem. - -### Cross-Consensus Messaging (XCM): The Backbone of Communication - -Polkadot's Cross-Consensus Messaging (XCM) is the standard framework for interaction between parachains, relay chains, and, eventually, external blockchains. XCM provides a trustless, secure messaging format for exchanging assets, sharing data, and executing cross-chain operations. - -Through XCM, decentralized applications can: - -- Transfer tokens and other assets across chains. -- Coordinate complex workflows that span multiple blockchains. -- Enable seamless user experiences where underlying blockchain differences are invisible. -- XCM exemplifies Polkadot’s commitment to creating a robust and interoperable ecosystem. - -For further information about XCM, check the [Get Started with XCM](/parachains/interoperability/get-started/){target=\_blank} article. - -### Bridges: Connecting External Networks - -While XCM enables interoperability within the Polkadot ecosystem, bridges extend this functionality to external blockchains such as Ethereum and Bitcoin. By connecting these networks, bridges allow Polkadot-based chains to access external liquidity, additional functionalities, and broader user bases. - -With bridges, developers and users gain the ability to: - -- Integrate external assets into Polkadot-based applications. -- Combine the strengths of Polkadot’s scalability with the liquidity of other networks. -- Facilitate accurate multi-chain applications that transcend ecosystem boundaries. - -For more information about bridges in the Polkadot ecosystem, see the [Bridge Hub](/reference/polkadot-hub/bridging/){target=\_blank} guide. - -## The Polkadot Advantage - -Polkadot was purpose-built for interoperability. Unlike networks that add interoperability as an afterthought, Polkadot integrates it as a fundamental design principle. This approach offers several distinct advantages: - -- **Developer empowerment**: Polkadot’s interoperability tools allow developers to build applications that leverage multiple chains’ capabilities without added complexity. -- **Enhanced ecosystem collaboration**: Chains in Polkadot can focus on their unique strengths while contributing to the ecosystem’s overall growth. -- **Future-proofing blockchain**: By enabling seamless communication, Polkadot ensures its ecosystem can adapt to evolving demands and technologies. - -## Looking Ahead - -Polkadot’s vision of interoperability extends beyond technical functionality, representing a shift towards a more collaborative blockchain landscape. By enabling chains to work together, Polkadot fosters innovation, efficiency, and accessibility, paving the way for a decentralized future where blockchains are not isolated competitors but interconnected collaborators. - - --- Page Title: JSON-RPC APIs @@ -6605,92 +5442,6 @@ If an error occurs, the response will include an error object: ``` ---- - -Page Title: Light Clients - -- Source (raw): https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/reference-tools-light-clients.md -- Canonical (HTML): https://docs.polkadot.com/reference/tools/light-clients/ -- Summary: Light clients enable secure and efficient blockchain interaction without running a full node. Learn everything you need to know about light clients on Polkadot. - -# Light Clients - -## Introduction - -Light clients enable secure and efficient blockchain interaction without running a full node. They provide a trust-minimized alternative to JSON-RPC by verifying data through cryptographic proofs rather than blindly trusting remote nodes. - -This guide covers: - -- What light clients are and how they work. -- Their advantages compared to full nodes and JSON-RPC. -- Available implementations in the Polkadot ecosystem. -- How to use light clients in your applications. - -Light clients are particularly valuable for resource-constrained environments and applications requiring secure, decentralized blockchain access without the overhead of maintaining full nodes. - -!!!note "Light node or light client?" - The terms _light node_ and _light client_ are interchangeable. Both refer to a blockchain client that syncs without downloading the entire blockchain state. All nodes in a blockchain network are fundamentally clients, engaging in peer-to-peer communication. - -## Light Clients Workflow - -Unlike JSON-RPC interfaces, where an application must maintain a list of providers or rely on a single node, light clients are not limited to or dependent on a single node. They use cryptographic proofs to verify the blockchain's state, ensuring it is up-to-date and accurate. By verifying only block headers, light clients avoid syncing the entire state, making them ideal for resource-constrained environments. - -```mermaid -flowchart LR -DAPP([dApp])-- Query Account Info -->LC([Light Client]) -LC -- Request --> FN(((Full Node))) -LC -- Response --> DAPP -FN -- Response (validated via Merkle proof) --> LC -``` - -In the diagram above, the decentralized application queries on-chain account information through the light client. The light client runs as part of the application and requires minimal memory and computational resources. It uses Merkle proofs to verify the state retrieved from a full node in a trust-minimized manner. Polkadot-compatible light clients utilize [warp syncing](https://spec.polkadot.network/sect-lightclient#sect-sync-warp-lightclient){target=\_blank}, which downloads only block headers. - -Light clients can quickly verify the blockchain's state, including [GRANDPA finality](/polkadot-protocol/glossary#grandpa){target=\_blank} justifications. - -!!!note "What does it mean to be trust-minimized?" - _Trust-minimized_ means that the light client does not need to fully trust the full node from which it retrieves the state. This is achieved through the use of Merkle proofs, which allow the light client to verify the correctness of the state by checking the Merkle tree root. - -## JSON-RPC and Light Client Comparison - -Another common method of communication between a user interface (UI) and a node is through the JSON-RPC protocol. Generally, the UI retrieves information from the node, fetches network or [pallet](/polkadot-protocol/glossary#pallet){target=\_blank} data, and interacts with the blockchain. This is typically done in one of two ways: - -- **User-controlled nodes**: The UI connects to a node client installed on the user's machine. - - These nodes are secure, but installation and maintenance can be inconvenient. -- **Publicly accessible nodes**: The UI connects to a third-party-owned publicly accessible node client. - - These nodes are convenient but centralized and less secure. Applications must maintain a list of backup nodes in case the primary node becomes unavailable. - -While light clients still communicate with [full nodes](/polkadot-protocol/glossary#full-node), they offer significant advantages for applications requiring a secure alternative to running a full node: - -| Full Node | Light Client | -| :---------------------------------------------------------------------------------------------: | :------------------------------------------------------------: | -| Fully verifies all blocks of the chain | Verifies only the authenticity of blocks | -| Stores previous block data and the chain's storage in a database | Does not require a database | -| Installation, maintenance, and execution are resource-intensive and require technical expertise | No installation is typically included as part of the application | - -## Using Light Clients - -The [`smoldot`](https://github.com/smol-dot/smoldot){target=\_blank} client is the cornerstone of light client implementation for Polkadot SDK-based chains. It provides the primitives needed to build light clients and is also integrated into libraries such as [PAPI](#papi-light-client-support). - -### PAPI Light Client Support - -The [Polkadot API (PAPI)](/develop/toolkit/api-libraries/papi){target=\_blank} library natively supports light client configurations powered by [`smoldot`](https://github.com/smol-dot/smoldot){target=\_blank}. This allows developers to connect to multiple chains simultaneously using a light client. - -### Substrate Connect - Browser Extension - -The [Substrate Connect browser extension](https://www.npmjs.com/package/@substrate/connect-extension-protocol){target=\_blank} enables end-users to interact with applications connected to multiple blockchains or to connect their own blockchains to supported applications. - -Establishing a sufficient number of peers can be challenging due to browser limitations on WebSocket connections from HTTPS pages, as many nodes require TLS. The Substrate Connect browser extension addresses this limitation by keeping chains synced in the background, enabling faster application performance. - -Substrate Connect automatically detects whether the user has the extension installed. If not, an in-page Wasm light client is created for them. - -## Resources - -- [What is a light client and why you should care?](https://medium.com/paritytech/what-is-a-light-client-and-why-you-should-care-75f813ae2670){target=\_blank} -- [Introducing Substrate Connect: Browser-Based Light Clients for Connecting to Substrate Chains](https://www.parity.io/blog/introducing-substrate-connect){target=\_blank} -- [Substrate Connect GitHub Repository](https://github.com/paritytech/substrate-connect/tree/master/projects/extension){target=\_blank} -- [Light Clients - Polkadot Specification](https://spec.polkadot.network/sect-lightclient){target=\_blank} - - --- Page Title: Mock Your Runtime @@ -7032,204 +5783,6 @@ The mock runtime with a genesis configuration is essential for test-driven devel ---- - -Page Title: Networks - -- Source (raw): https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/reference-parachains-networks.md -- Canonical (HTML): https://docs.polkadot.com/reference/parachains/networks/ -- Summary: Explore Polkadot's testing and production networks, including Westend, Kusama, and Paseo, for efficient development, deployment, and testing. - -# Networks - -## Introduction - -The Polkadot ecosystem is built on a robust set of networks designed to enable secure and scalable development. Whether you are testing new features or deploying to live production, Polkadot offers several layers of networks tailored for each stage of the development process. From local environments to experimental networks like Kusama and community-run TestNets such as Paseo, developers can thoroughly test, iterate, and validate their applications. This guide will introduce you to Polkadot's various networks and explain how they fit into the development workflow. - -## Network Overview - -Polkadot's development process is structured to ensure new features and upgrades are rigorously tested before being deployed on live production networks. The progression follows a well-defined path, starting from local environments and advancing through TestNets, ultimately reaching the Polkadot MainNet. The diagram below outlines the typical progression of the Polkadot development cycle: - -``` mermaid -flowchart LR - id1[Local] --> id2[Westend] --> id4[Kusama] --> id5[Polkadot] - id1[Local] --> id3[Paseo] --> id5[Polkadot] -``` - -This flow ensures developers can thoroughly test and iterate without risking real tokens or affecting production networks. Testing tools like [Chopsticks](#chopsticks) and various TestNets make it easier to experiment safely before releasing to production. - -A typical journey through the Polkadot core protocol development process might look like this: - -1. **Local development node**: Development starts in a local environment, where developers can create, test, and iterate on upgrades or new features using a local development node. This stage allows rapid experimentation in an isolated setup without any external dependencies. - -2. **Westend**: After testing locally, upgrades are deployed to [Westend](#westend), Polkadot's primary TestNet. Westend simulates real-world conditions without using real tokens, making it the ideal place for rigorous feature testing before moving on to production networks. - -3. **Kusama**: Once features have passed extensive testing on Westend, they move to Kusama, Polkadot's experimental and fast-moving "canary" network. Kusama operates as a high-fidelity testing ground with actual economic incentives, giving developers insights into how their features will perform in a real-world environment. - -4. **Polkadot**: After passing tests on Westend and Kusama, features are considered ready for deployment to Polkadot, the live production network. - - In addition, parachain developers can leverage local TestNets like [Zombienet](#zombienet) and deploy upgrades on parachain TestNets. - -5. **Paseo**: For parachain and dApp developers, Paseo serves as a community-run TestNet that mirrors Polkadot's runtime. Like Westend for core protocol development, Paseo provides a testing ground for parachain development without affecting live networks. - -!!!note - The Rococo TestNet deprecation date was October 14, 2024. Teams should use Westend for Polkadot protocol and feature testing and Paseo for chain development-related testing. - -## Polkadot Development Networks - -Development and testing are crucial to building robust dApps and parachains and performing network upgrades within the Polkadot ecosystem. To achieve this, developers can leverage various networks and tools that provide a risk-free environment for experimentation and validation before deploying features to live networks. These networks help avoid the costs and risks associated with real tokens, enabling testing for functionalities like governance, cross-chain messaging, and runtime upgrades. - -## Kusama Network - -Kusama is the experimental version of Polkadot, designed for developers who want to move quickly and test their applications in a real-world environment with economic incentives. Kusama serves as a production-grade testing ground where developers can deploy features and upgrades with the pressure of game theory and economics in mind. It mirrors Polkadot but operates as a more flexible space for innovation. - -The native token for Kusama is KSM. For more information about KSM, visit the [Native Assets](https://wiki.polkadot.com/kusama/kusama-getting-started/){target=\_blank} page. - -## Test Networks - -The following test networks provide controlled environments for testing upgrades and new features. TestNet tokens are available from the [Polkadot faucet](https://faucet.polkadot.io/){target=\_blank}. - -### Westend - -Westend is Polkadot's primary permanent TestNet. Unlike temporary test networks, Westend is not reset to the genesis block, making it an ongoing environment for testing Polkadot core features. Managed by Parity Technologies, Westend ensures that developers can test features in a real-world simulation without using actual tokens. - -The native token for Westend is WND. More details about WND can be found on the [Native Assets](https://wiki.polkadot.com/learn/learn-dot/#__tabbed_2_2){target=\_blank} page. - -### Paseo - -[Paseo](https://github.com/paseo-network){target=\_blank} is a community-managed TestNet designed for parachain and dApp developers. It mirrors Polkadot's runtime and is maintained by Polkadot community members. Paseo provides a dedicated space for parachain developers to test their applications in a Polkadot-like environment without the risks associated with live networks. - -The native token for Paseo is PAS. Additional information on PAS is available on the [Native Assets](https://wiki.polkadot.com/learn/learn-dot/#__tabbed_2_1){target=\_blank} page. - -## Local Test Networks - -Local test networks are an essential part of the development cycle for blockchain developers using the Polkadot SDK. They allow for fast, iterative testing in controlled, private environments without connecting to public TestNets. Developers can quickly spin up local instances to experiment, debug, and validate their code before deploying to larger TestNets like Westend or Paseo. Two key tools for local network testing are Zombienet and Chopsticks. - -### Zombienet - -[Zombienet](https://github.com/paritytech/zombienet){target=\_blank} is a flexible testing framework for Polkadot SDK-based blockchains. It enables developers to create and manage ephemeral, short-lived networks. This feature makes Zombienet particularly useful for quick iterations, as it allows you to run multiple local networks concurrently, mimicking different runtime conditions. Whether you're developing a parachain or testing your custom blockchain logic, Zombienet gives you the tools to automate local testing. - -Key features of Zombienet include: - -- Creating dynamic, local networks with different configurations. -- Running parachains and relay chains in a simulated environment. -- Efficient testing of network components like cross-chain messaging and governance. - -Zombienet is ideal for developers looking to test quickly and thoroughly before moving to more resource-intensive public TestNets. - -### Chopsticks - -[Chopsticks](https://github.com/AcalaNetwork/chopsticks){target=\_blank} is a tool designed to create forks of Polkadot SDK-based blockchains, allowing developers to interact with network forks as part of their testing process. This capability makes Chopsticks a powerful option for testing upgrades, runtime changes, or cross-chain applications in a forked network environment. - -Key features of Chopsticks include: - -- Forking live Polkadot SDK-based blockchains for isolated testing. -- Simulating cross-chain messages in a private, controlled setup. -- Debugging network behavior by interacting with the fork in real-time. - -Chopsticks provides a controlled environment for developers to safely explore the effects of runtime changes. It ensures that network behavior is tested and verified before upgrades are deployed to live networks. - - ---- - -Page Title: Node and Runtime - -- Source (raw): https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/reference-parachains-node-and-runtime.md -- Canonical (HTML): https://docs.polkadot.com/reference/parachains/node-and-runtime/ -- Summary: Learn how Polkadot SDK-based nodes function, how the client and runtime are separated, and how they communicate using SCALE-encoded data. - -# Node and Runtime - -## Introduction - -Every blockchain platform relies on a decentralized network of computers, called nodes, that communicate with each other about transactions and blocks. In this context, a node refers to the software running on the connected devices rather than the physical or virtual machines in the network. - -Polkadot SDK-based nodes consist of two main components, each with distinct responsibilities: the client (also called node) and the runtime. - -If the system were a monolithic protocol, any modification would require updating the entire system. Instead, Polkadot achieves true upgradeability by defining an immutable meta-protocol (the client) and a protocol (the runtime) that can be upgraded independently. - -This separation gives the [Polkadot Relay Chain](/polkadot-protocol/architecture/polkadot-chain){target=\_blank} and all connected [parachains](/polkadot-protocol/architecture/parachains){target=\_blank} an evolutionary advantage over other blockchain platforms. - -## Architectural Principles - -The Polkadot SDK-based blockchain architecture is fundamentally built on two distinct yet interconnected components: - -- Client (Meta-protocol): - - Handles the foundational infrastructure of the blockchain. - - Manages runtime execution, networking, consensus, and other off-chain components. - - Provides an immutable base layer that ensures network stability. - - Upgradable only through hard forks. - -- Runtime (Protocol): - - Defines the blockchain's state transition logic. - - Determines the specific rules and behaviors of the blockchain. - - Compiled to WebAssembly (Wasm) for platform-independent execution. - - Capable of being upgraded without network-wide forking. - -### Advantages of this Architecture - -- **Forkless upgrades**: Runtime can be updated without disrupting the entire network. -- **Modularity**: Clear separation allows independent development of client and runtime. -- **Flexibility**: Enables rapid iteration and evolution of blockchain logic. -- **Performance**: WebAssembly compilation provides efficient, cross-platform execution. - -## Node (Client) - -The node, also known as the client, is the core component responsible for executing the Wasm runtime and orchestrating various essential blockchain components. It ensures the correct execution of the state transition function and manages multiple critical subsystems, including: - -- **Wasm execution**: Runs the blockchain runtime, which defines the state transition rules. -- **Database management**: Stores blockchain data. -- **Networking**: Facilitates peer-to-peer communication, block propagation, and transaction gossiping. -- **Transaction pool (Mempool)**: Manages pending transactions before they are included in a block. -- **Consensus mechanism**: Ensures agreement on the blockchain state across nodes. -- **RPC services**: Provides external interfaces for applications and users to interact with the node. - -## Runtime - -The runtime is more than just a set of rules. It's the fundamental logic engine that defines a blockchain's entire behavior. In Polkadot SDK-based blockchains, the runtime represents a complete, self-contained description of the blockchain's state transition function. - -### Characteristics - -The runtime is distinguished by three key characteristics: - -- **Business logic**: Defines the complete application-specific blockchain behavior. -- **WebAssembly compilation**: Ensures platform-independent, secure execution. -- **On-chain storage**: Stored within the blockchain's state, allowing dynamic updates. - -### Key Functions - -The runtime performs several critical functions, such as: - -- Define state transition rules. -- Implement blockchain-specific logic. -- Manage account interactions. -- Control transaction processing. -- Define governance mechanisms. -- Handle custom pallets and modules. - -## Communication Between Node and Runtime - -The client and runtime communicate exclusively using [SCALE-encoded](/polkadot-protocol/parachain-basics/data-encoding){target=\_blank} communication. This ensures efficient and compact data exchange between the two components. - -### Runtime APIs - -The Runtime API consists of well-defined functions and constants a client assumes are implemented in the Runtime Wasm blob. These APIs enable the client to interact with the runtime to execute blockchain operations and retrieve information. The client invokes these APIs to: - -- Build, execute, and finalize blocks. -- Access metadata. -- Access consensus related information. -- Handle transaction execution. - -### Host Functions - -During execution, the runtime can access certain external client functionalities via host functions. The specific functions the client exposes allow the runtime to perform operations outside the WebAssembly domain. Host functions enable the runtime to: - -- Perform cryptographic operations. -- Access the current blockchain state. -- Handle storage modifications. -- Allocate memory. - - --- Page Title: Obtain Coretime @@ -7338,169 +5891,75 @@ To purchase a core, you need funds on the Coretime Chain. You can fund your acco 4. Click **Get some PASs** to receive 5000 PAS tokens. -!!!note - The Polkadot Faucet has a daily limit of 5,000 PAS tokens per account. If you need more tokens than this limit allows, you have two options: - - - Return to the faucet on consecutive days to accumulate additional tokens. - - Create additional accounts, fund each one separately, and then transfer the tokens to your primary account that will be making the bulk coretime purchase. - - Alternatively, to expedite the process, you can send a message to the [Paseo Support channel](https://matrix.to/#/#paseo-testnet-support:parity.io){target=\_blank} on Matrix, and the Paseo team will assist you in funding your account. - -### Purchase a Core - -1. From the RegionX home page, ensure the correct network is selected using the network switch in the top right corner (set to **Paseo**). - -2. Review the information displayed on the home page, including: - - **Cores Remaining**: Number of available cores - - **Cores Offered**: Total cores in the current sale - - **Current price**: The price per core in PAS tokens - - **Auction Phase Status**: Current phase and progress - -3. Click the **Purchase New Core** button displayed on the page. - -4. A modal will appear detailing the transaction details and fees. Review the information carefully. - -5. Click **Ok** and sign the transaction using your connected wallet. - -6. Wait for the transaction to be confirmed on-chain. - -### Verify Your Purchase - -1. Once the transaction is confirmed, navigate to [**My Regions**](https://app.regionx.tech/regions){target=\_blank} from the left menu. - -2. You should see your newly purchased core listed in your dashboard. - -Congratulations! You've successfully purchased a core using RegionX. - -### Assign Your Parachain to the Core - -With your core purchased, you now need to assign your parachain to it for block production: - -1. From the **My Regions** page, click on your core to select it. - -2. Click the **Assign** option from the left-hand menu. - -3. A modal will appear, allowing you to add a new task. - -4. Click **Add Task** and enter the following information: - - - **Parachain ID**: Your reserved parachain identifier - - **Project Name**: The name of your parachain project - -5. Click **Add Task** to proceed. - -6. Select your parachain task from the list. - -7. Set the core's **Finality** setting: - - - **Provisional**: Allows interlacing and partitioning of the core, but the region cannot be renewed as-is. - - **Final**: Prevents modification of the core but allows renewal. Choose this if you plan to renew the core. - -8. Sign and submit the transaction. - -Once confirmed, your parachain will be assigned to the core and should begin producing blocks (provided your collator is running and synced with the relay chain). - -## Next Steps - -Your parachain is now set up for block production. Consider the following: - -- **Monitor your collator**: Keep your collator node running and monitor its performance. -- **Plan coretime renewal**: If using bulk coretime, plan to renew your core before the current lease expires. -- **Explore runtime upgrades**: Once comfortable with your setup, explore how to upgrade your parachain's runtime without interrupting block production. - - ---- - -Page Title: On-Chain Governance Overview - -- Source (raw): https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/reference-governance.md -- Canonical (HTML): https://docs.polkadot.com/reference/governance/ -- Summary: Discover Polkadot’s cutting-edge OpenGov system, enabling transparent, decentralized decision-making through direct democracy and flexible governance tracks. - -# On-Chain Governance - -## Introduction - -Polkadot’s governance system exemplifies decentralized decision-making, empowering its community of stakeholders to shape the network’s future through active participation. The latest evolution, OpenGov, builds on Polkadot’s foundation by providing a more inclusive and efficient governance model. - -This guide will explain the principles and structure of OpenGov and walk you through its key components, such as Origins, Tracks, and Delegation. You will learn about improvements over earlier governance systems, including streamlined voting processes and enhanced stakeholder participation. - -With OpenGov, Polkadot achieves a flexible, scalable, and democratic governance framework that allows multiple proposals to proceed simultaneously, ensuring the network evolves in alignment with its community's needs. - -## Governance Evolution - -Polkadot’s governance journey began with [Governance V1](https://wiki.polkadot.com/learn/learn-polkadot-opengov/#governance-summary){target=\_blank}, a system that proved effective in managing treasury funds and protocol upgrades. However, it faced limitations, such as: - -- Slow voting cycles, causing delays in decision-making. -- Inflexibility in handling multiple referendums, restricting scalability. +!!!note + The Polkadot Faucet has a daily limit of 5,000 PAS tokens per account. If you need more tokens than this limit allows, you have two options: + + - Return to the faucet on consecutive days to accumulate additional tokens. + - Create additional accounts, fund each one separately, and then transfer the tokens to your primary account that will be making the bulk coretime purchase. -To address these challenges, Polkadot introduced OpenGov, a governance model designed for greater inclusivity, efficiency, and scalability. OpenGov replaces the centralized structures of Governance V1, such as the Council and Technical Committee, with a fully decentralized and dynamic framework. + Alternatively, to expedite the process, you can send a message to the [Paseo Support channel](https://matrix.to/#/#paseo-testnet-support:parity.io){target=\_blank} on Matrix, and the Paseo team will assist you in funding your account. -For a full comparison of the historic and current governance models, visit the [Gov1 vs. Polkadot OpenGov](https://wiki.polkadot.com/learn/learn-polkadot-opengov/#gov1-vs-polkadot-opengov){target=\_blank} section of the Polkadot Wiki. +### Purchase a Core -## OpenGov Key Features +1. From the RegionX home page, ensure the correct network is selected using the network switch in the top right corner (set to **Paseo**). -OpenGov transforms Polkadot’s governance into a decentralized, stakeholder-driven model, eliminating centralized decision-making bodies like the Council. Key enhancements include: +2. Review the information displayed on the home page, including: + - **Cores Remaining**: Number of available cores + - **Cores Offered**: Total cores in the current sale + - **Current price**: The price per core in PAS tokens + - **Auction Phase Status**: Current phase and progress -- **Decentralization**: Shifts all decision-making power to the public, ensuring a more democratic process. -- **Enhanced delegation**: Allows users to delegate their votes to trusted experts across specific governance tracks. -- **Simultaneous referendums**: Multiple proposals can progress at once, enabling faster decision-making. -- **Polkadot Technical Fellowship**: A broad, community-driven group replacing the centralized Technical Committee. +3. Click the **Purchase New Core** button displayed on the page. -This new system ensures Polkadot governance remains agile and inclusive, even as the ecosystem grows. +4. A modal will appear detailing the transaction details and fees. Review the information carefully. -## Origins and Tracks +5. Click **Ok** and sign the transaction using your connected wallet. -In OpenGov, origins and tracks are central to managing proposals and votes. +6. Wait for the transaction to be confirmed on-chain. -- **Origin**: Determines the authority level of a proposal (e.g., Treasury, Root) which decides the track of all referendums from that origin. -- **Track**: Define the procedural flow of a proposal, such as voting duration, approval thresholds, and enactment timelines. +### Verify Your Purchase -Developers must be aware that referendums from different origins and tracks will take varying amounts of time to reach approval and enactment. The [Polkadot Technical Fellowship](https://wiki.polkadot.com/learn/learn-polkadot-technical-fellowship/){target=\_blank} has the option to shorten this timeline by whitelisting a proposal and allowing it to be enacted through the [Whitelist Caller](https://wiki.polkadot.com/learn/learn-polkadot-opengov-origins/#whitelisted-caller){target=\_blank} origin. +1. Once the transaction is confirmed, navigate to [**My Regions**](https://app.regionx.tech/regions){target=\_blank} from the left menu. -Visit [Origins and Tracks Info](https://wiki.polkadot.com/learn/learn-polkadot-opengov/#origins-and-tracks){target=\_blank} for details on current origins and tracks, associated terminology, and parameters. +2. You should see your newly purchased core listed in your dashboard. -## Referendums +Congratulations! You've successfully purchased a core using RegionX. -In OpenGov, anyone can submit a referendum, fostering an open and participatory system. The timeline for a referendum depends on the privilege level of the origin with more significant changes offering more time for community voting and participation before enactment. +### Assign Your Parachain to the Core -The timeline for an individual referendum includes four distinct periods: +With your core purchased, you now need to assign your parachain to it for block production: -- **Lead-in**: A minimum amount of time to allow for community participation, available room in the origin, and payment of the decision deposit. Voting is open during this period. -- **Decision**: Voting continues. -- **Confirmation**: Referendum must meet [approval and support](https://wiki.polkadot.com/learn/learn-polkadot-opengov/#approval-and-support){target=\_blank} criteria during entire period to avoid rejection. -- **Enactment**: Changes approved by the referendum are executed. +1. From the **My Regions** page, click on your core to select it. -### Vote on Referendums +2. Click the **Assign** option from the left-hand menu. -Voters can vote with their tokens on each referendum. Polkadot uses a voluntary token locking mechanism, called conviction voting, as a way for voters to increase their voting power. A token holder signals they have a stronger preference for approving a proposal based upon their willingness to lock up tokens. Longer voluntary token locks are seen as a signal of continual approval and translate to increased voting weight. +3. A modal will appear, allowing you to add a new task. -See [Voting on a Referendum](https://wiki.polkadot.com/learn/learn-polkadot-opengov/#voting-on-a-referendum){target=\_blank} for a deeper look at conviction voting and related token locks. +4. Click **Add Task** and enter the following information: -### Delegate Voting Power + - **Parachain ID**: Your reserved parachain identifier + - **Project Name**: The name of your parachain project -The OpenGov system also supports multi-role delegations, allowing token holders to assign their voting power on different tracks to entities with expertise in those areas. +5. Click **Add Task** to proceed. -For example, if a token holder lacks the technical knowledge to evaluate proposals on the [Root track](https://wiki.polkadot.com/learn/learn-polkadot-opengov-origins/#root){target=\_blank}, they can delegate their voting power for that track to an expert they trust to vote in the best interest of the network. This ensures informed decision-making across tracks while maintaining flexibility for token holders. +6. Select your parachain task from the list. -Visit [Multirole Delegation](https://wiki.polkadot.com/learn/learn-polkadot-opengov/#multirole-delegation){target=\_blank} for more details on delegating voting power. +7. Set the core's **Finality** setting: -### Cancel a Referendum + - **Provisional**: Allows interlacing and partitioning of the core, but the region cannot be renewed as-is. + - **Final**: Prevents modification of the core but allows renewal. Choose this if you plan to renew the core. -Polkadot OpenGov has two origins for rejecting ongoing referendums: +8. Sign and submit the transaction. -- [**Referendum Canceller**](https://wiki.polkadot.com/learn/learn-polkadot-opengov-origins/#referendum-canceller){target=\_blank}: Cancels an active referendum when non-malicious errors occur and refunds the deposits to the originators. -- [**Referendum Killer**](https://wiki.polkadot.com/learn/learn-polkadot-opengov-origins/#referendum-killer){target=\_blank}: Used for urgent, malicious cases this origin instantly terminates an active referendum and slashes deposits. +Once confirmed, your parachain will be assigned to the core and should begin producing blocks (provided your collator is running and synced with the relay chain). -See [Cancelling, Killing, and Blacklisting](https://wiki.polkadot.com/learn/learn-polkadot-opengov/#cancelling-killing--blacklisting){target=\_blank} for additional information on rejecting referendums. +## Next Steps -## Additional Resources +Your parachain is now set up for block production. Consider the following: -- **[Democracy pallet](https://github.com/paritytech/polkadot-sdk/tree/polkadot-stable2506-2/substrate/frame/democracy/src){target=\_blank}**: Handles administration of general stakeholder voting. -- **[Gov2: Polkadot’s Next Generation of Decentralised Governance](https://medium.com/polkadot-network/gov2-polkadots-next-generation-of-decentralised-governance-4d9ef657d11b){target=\_blank}**: Medium article by Gavin Wood. -- **[Polkadot Direction](https://matrix.to/#/#Polkadot-Direction:parity.io){target=\_blank}**: Matrix Element client. -- **[Polkassembly](https://polkadot.polkassembly.io/){target=\_blank}**: OpenGov dashboard and UI. -- **[Polkadot.js Apps Governance](https://polkadot.js.org/apps/#/referenda){target=\_blank}**: Overview of active referendums. +- **Monitor your collator**: Keep your collator node running and monitor its performance. +- **Plan coretime renewal**: If using bulk coretime, plan to renew your core before the current lease expires. +- **Explore runtime upgrades**: Once comfortable with your setup, explore how to upgrade your parachain's runtime without interrupting block production. --- @@ -9767,398 +8226,6 @@ The primary trade-off is increased implementation complexity, as you must manage For a complete implementation example of multi-block migrations, refer to the [official example](https://github.com/paritytech/polkadot-sdk/tree/polkadot-stable2506-2/substrate/frame/examples/multi-block-migrations){target=\_blank} in the Polkadot SDK. ---- - -Page Title: Technical Reference Overview - -- Source (raw): https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/reference.md -- Canonical (HTML): https://docs.polkadot.com/reference/ -- Summary: Learn about Polkadot's technical architecture, governance framework, parachain ecosystem, and the tools you need to build and interact with the network. - -## Introduction - -The Technical Reference section provides comprehensive documentation of Polkadot's architecture, core concepts, and development tooling. Whether you're exploring how Polkadot's relay chain coordinates parachains, understanding governance mechanisms, or building applications on the network, this reference covers the technical foundations you need. - -Polkadot is a multi-chain network that enables diverse, interconnected blockchains to share security and communicate seamlessly. Understanding how these components interact from the [relay chain](/polkadot-protocol/glossary#relay-chain){target=\_blank} that validates [parachains](/polkadot-protocol/glossary#parachain){target=\_blank} to the [governance](/reference/glossary#governance){target=\_blank} mechanisms that evolve the protocol is essential for developers, validators, and network participants. - -This guide organizes technical documentation across five core areas: Polkadot Hub, Parachains, On-Chain Governance, Glossary, and Tools, each providing detailed information on different aspects of the Polkadot ecosystem. - -## Polkadot Hub - -[Polkadot Hub](/reference/polkadot-hub/){target=\_blank} is the entry point to Polkadot for all users and application developers. It provides access to essential Web3 services, including smart contracts, staking, governance, identity management, and cross-ecosystem interoperability—without requiring you to deploy or manage a parachain. - -The Hub encompasses a set of core functionality that enables developers and users to build and interact with applications on Polkadot. Key capabilities include: - -- **Smart contracts**: Deploy Ethereum-compatible smart contracts and build decentralized applications. -- **Assets and tokens**: Create, manage, and transfer fungible tokens and NFTs across the ecosystem. -- **Staking**: Participate in network security and earn rewards by staking DOT. -- **Governance**: Vote on proposals and participate in Polkadot's decentralized decision-making through OpenGov. -- **Identity services**: Register and manage on-chain identities, enabling access to governance roles and network opportunities. -- **Cross-chain interoperability**: Leverage XCM messaging to interact securely with other chains in the Polkadot ecosystem. -- **Collectives and DAOs**: Participate in governance collectives and decentralized autonomous organizations. - -## Parachains - -[Parachains](/reference/parachains/){target=\_blank} are specialized blockchains that connect to the Polkadot relay chain, inheriting its security while maintaining their own application-specific logic. The parachains documentation covers: - -- **Accounts**: Deep dive into account types, storage, and management on parachains. -- **Blocks, transactions and fees**: Understand block production, transaction inclusion, and fee mechanisms. -- **Consensus**: Learn how parachain blocks are validated and finalized through the relay chain's consensus. -- **Chain data**: Explore data structures, storage layouts, and state management. -- **Cryptography**: Study cryptographic primitives used in Polkadot SDK-based chains. -- **Data encoding**: Understand how data is encoded and decoded for blockchain compatibility. -- **Networks**: Learn about networking protocols and peer-to-peer communication. -- **Interoperability**: Discover [Cross-Consensus Messaging (XCM)](/parachains/interoperability/get-started/){target=\_blank}, the standard for cross-chain communication. -- **Randomness**: Understand how randomness is generated and used in Polkadot chains. -- **Node and runtime**: Learn about parachain nodes, runtime environments, and the [Polkadot SDK](https://github.com/paritytech/polkadot-sdk){target=\_blank}. - -## On-Chain Governance - -[On-Chain governance](/reference/governance/){target=\_blank} is the decentralized decision-making mechanism for the Polkadot network. It manages the evolution and modification of the network's runtime logic, enabling community oversight and approval for proposed changes. The governance documentation details: - -- **OpenGov framework**: Understand Polkadot's next-generation governance system with enhanced delegation, flexible tracks, and simultaneous referendums. -- **Origins and tracks**: Learn how governance proposals are categorized, prioritized, and executed based on their privilege level and complexity. -- **Voting and delegation**: Explore conviction voting, vote delegation, and how token holders participate in governance. -- **Governance evolution**: See how Polkadot's governance has evolved from Governance V1 to the current OpenGov system. - -## Glossary - -The [Glossary](/reference/glossary/){target=\_blank} provides quick-reference definitions for Polkadot-specific terminology. Essential terms include: - -- Blockchain concepts (blocks, transactions, state) -- Consensus mechanisms (validators, collators, finality) -- Polkadot-specific terms (relay chain, parachain, XCM, FRAME) -- Network components (nodes, runtimes, storage) -- Governance terminology (origins, tracks, referendums) - -## Tools - -The [Tools](/reference/tools/){target=\_blank} section documents essential development and interaction tools for the Polkadot ecosystem: - -- **Light clients**: Lightweight solutions for interacting with the network without running full nodes. -- **JavaScript/TypeScript tools**: Libraries like [Polkadot.js API](/reference/tools/polkadot-js-api/){target=\_blank} and [PAPI](/reference/tools/papi/){target=\_blank} for building applications. -- **Rust tools**: [Polkadart](/reference/tools/polkadart/){target=\_blank} and other Rust-based libraries for SDK development. -- **Python tools**: [py-substrate-interface](/reference/tools/py-substrate-interface/){target=\_blank} for Python developers. -- **Testing and development**: Tools like [Moonwall](/reference/tools/moonwall/){target=\_blank}, [Chopsticks](/reference/tools/chopsticks/){target=\_blank}, and [Omninode](/reference/tools/omninode/){target=\_blank} for smart contract and parachain testing. -- **Indexing and monitoring**: [Sidecar](/reference/tools/sidecar/){target=\_blank} for data indexing and [Dedot](/reference/tools/dedot/){target=\_blank} for substrate interaction. -- **Cross-chain tools**: [ParaSpell](/reference/tools/paraspell/){target=\_blank} for XCM integration and asset transfers. - -## Where to Go Next - -For detailed exploration of specific areas, proceed to any of the main sections: - -
- -- Learn **Polkadot Hub** - - --- - - Understand the relay chain's role in coordinating parachains, providing shared security, and enabling governance. - - [:octicons-arrow-right-24: Reference](/reference/polkadot-hub/) - -- Learn **Parachains** - - --- - - Deep dive into parachain architecture, consensus, data structures, and building application-specific blockchains. - - [:octicons-arrow-right-24: Reference](/reference/parachains/) - -- Learn **On-Chain Governance** - - --- - - Explore Polkadot's decentralized governance framework and how to participate in network decision-making. - - [:octicons-arrow-right-24: Reference](/reference/governance/) - -- Guide **Glossary** - - --- - - Quick reference for Polkadot-specific terminology and concepts used throughout the documentation. - - [:octicons-arrow-right-24: Reference](/reference/glossary/) - -- Guide **Tools** - - --- - - Discover development tools, libraries, and frameworks for building and interacting with Polkadot. - - [:octicons-arrow-right-24: Reference](/reference/tools/) - -
- - ---- - -Page Title: Transactions - -- Source (raw): https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/reference-parachains-blocks-transactions-fees-transactions.md -- Canonical (HTML): https://docs.polkadot.com/reference/parachains/blocks-transactions-fees/transactions/ -- Summary: Learn how to construct, submit, and validate transactions in the Polkadot SDK, covering signed, unsigned, and inherent types of transactions. - -# Transactions - -## Introduction - -Transactions are essential components of blockchain networks, enabling state changes and the execution of key operations. In the Polkadot SDK, transactions, often called extrinsics, come in multiple forms, including signed, unsigned, and inherent transactions. - -This guide walks you through the different transaction types and how they're formatted, validated, and processed within the Polkadot ecosystem. You'll also learn how to customize transaction formats and construct transactions for FRAME-based runtimes, ensuring a complete understanding of how transactions are built and executed in Polkadot SDK-based chains. - -## What Is a Transaction? - -In the Polkadot SDK, transactions represent operations that modify the chain's state, bundled into blocks for execution. The term extrinsic is often used to refer to any data that originates outside the runtime and is included in the chain. While other blockchain systems typically refer to these operations as "transactions," the Polkadot SDK adopts the broader term "extrinsic" to capture the wide variety of data types that can be added to a block. - -There are three primary types of transactions (extrinsics) in the Polkadot SDK: - -- **Signed transactions**: Signed by the submitting account, often carrying transaction fees. -- **Unsigned transactions**: Submitted without a signature, often requiring custom validation logic. -- **Inherent transactions**: Typically inserted directly into blocks by block authoring nodes, without gossiping between peers. - -Each type serves a distinct purpose, and understanding when and how to use each is key to efficiently working with the Polkadot SDK. - -### Signed Transactions - -Signed transactions require an account's signature and typically involve submitting a request to execute a runtime call. The signature serves as a form of cryptographic proof that the sender has authorized the action, using their private key. These transactions often involve a transaction fee to cover the cost of execution and incentivize block producers. - -Signed transactions are the most common type of transaction and are integral to user-driven actions, such as token transfers. For instance, when you transfer tokens from one account to another, the sending account must sign the transaction to authorize the operation. - -For example, the [`pallet_balances::Call::transfer_allow_death`](https://paritytech.github.io/polkadot-sdk/master/pallet_balances/pallet/struct.Pallet.html#method.transfer_allow_death){target=\_blank} extrinsic in the Balances pallet allows you to transfer tokens. Since your account initiates this transaction, your account key is used to sign it. You'll also be responsible for paying the associated transaction fee, with the option to include an additional tip to incentivize faster inclusion in the block. - -### Unsigned Transactions - -Unsigned transactions do not require a signature or account-specific data from the sender. Unlike signed transactions, they do not come with any form of economic deterrent, such as fees, which makes them susceptible to spam or replay attacks. Custom validation logic must be implemented to mitigate these risks and ensure these transactions are secure. - -Unsigned transactions typically involve scenarios where including a fee or signature is unnecessary or counterproductive. However, due to the absence of fees, they require careful validation to protect the network. For example, [`pallet_im_online::Call::heartbeat`](https://paritytech.github.io/polkadot-sdk/master/pallet_im_online/pallet/struct.Pallet.html#method.heartbeat){target=\_blank} extrinsic allows validators to send a heartbeat signal, indicating they are active. Since only validators can make this call, the logic embedded in the transaction ensures that the sender is a validator, making the need for a signature or fee redundant. - -Unsigned transactions are more resource-intensive than signed ones because custom validation is required, but they play a crucial role in certain operational scenarios, especially when regular user accounts aren't involved. - -### Inherent Transactions - -Inherent transactions are a specialized type of unsigned transaction that is used primarily for block authoring. Unlike signed or other unsigned transactions, inherent transactions are added directly by block producers and are not broadcasted to the network or stored in the transaction queue. They don't require signatures or the usual validation steps and are generally used to insert system-critical data directly into blocks. - -A key example of an inherent transaction is inserting a timestamp into each block. The [`pallet_timestamp::Call::now`](https://paritytech.github.io/polkadot-sdk/master/pallet_timestamp/pallet/struct.Pallet.html#method.now-1){target=\_blank} extrinsic allows block authors to include the current time in the block they are producing. Since the block producer adds this information, there is no need for transaction validation, like signature verification. The validation in this case is done indirectly by the validators, who check whether the timestamp is within an acceptable range before finalizing the block. - -Another example is the [`paras_inherent::Call::enter`](https://paritytech.github.io/polkadot-sdk/master/polkadot_runtime_parachains/paras_inherent/pallet/struct.Pallet.html#method.enter){target=\_blank} extrinsic, which enables parachain collator nodes to send validation data to the relay chain. This inherent transaction ensures that the necessary parachain data is included in each block without the overhead of gossiped transactions. - -Inherent transactions serve a critical role in block authoring by allowing important operational data to be added directly to the chain without needing the validation processes required for standard transactions. - -## Transaction Formats - -Understanding the structure of signed and unsigned transactions is crucial for developers building on Polkadot SDK-based chains. Whether you're optimizing transaction processing, customizing formats, or interacting with the transaction pool, knowing the format of extrinsics, Polkadot's term for transactions, is essential. - -### Types of Transaction Formats - -In Polkadot SDK-based chains, extrinsics can fall into three main categories: - -- **Unchecked extrinsics**: Typically used for signed transactions that require validation. They contain a signature and additional data, such as a nonce and information for fee calculation. Unchecked extrinsics are named as such because they require validation checks before being accepted into the transaction pool. -- **Checked extrinsics**: Typically used for inherent extrinsics (unsigned transactions); these don't require signature verification. Instead, they carry information such as where the extrinsic originates and any additional data required for the block authoring process. -- **Opaque extrinsics**: Used when the format of an extrinsic is not yet fully committed or finalized. They are still decodable, but their structure can be flexible depending on the context. - -### Signed Transaction Data Structure - -A signed transaction typically includes the following components: - -- **Signature**: Verifies the authenticity of the transaction sender. -- **Call**: The actual function or method call the transaction is requesting (for example, transferring funds). -- **Nonce**: Tracks the number of prior transactions sent from the account, helping to prevent replay attacks. -- **Tip**: An optional incentive to prioritize the transaction in block inclusion. -- **Additional data**: Includes details such as spec version, block hash, and genesis hash to ensure the transaction is valid within the correct runtime and chain context. - -Here's a simplified breakdown of how signed transactions are typically constructed in a Polkadot SDK runtime: - -``` code - + + -``` - -Each part of the signed transaction has a purpose, ensuring the transaction's authenticity and context within the blockchain. - -### Signed Extensions - -Polkadot SDK also provides the concept of [signed extensions](https://paritytech.github.io/polkadot-sdk/master/polkadot_sdk_docs/reference_docs/signed_extensions/index.html){target=\_blank}, which allow developers to extend extrinsics with additional data or validation logic before they are included in a block. The [`SignedExtension`](https://paritytech.github.io/try-runtime-cli/sp_runtime/traits/trait.SignedExtension.html){target=\_blank} set helps enforce custom rules or protections, such as ensuring the transaction's validity or calculating priority. - -The transaction queue regularly calls signed extensions to verify a transaction's validity before placing it in the ready queue. This safeguard ensures transactions won't fail in a block. Signed extensions are commonly used to enforce validation logic and protect the transaction pool from spam and replay attacks. - -In FRAME, a signed extension can hold any of the following types by default: - -- **[`AccountId`](https://paritytech.github.io/polkadot-sdk/master/polkadot_sdk_frame/runtime/types_common/type.AccountId.html){target=\_blank}**: To encode the sender's identity. -- **[`Call`](https://paritytech.github.io/polkadot-sdk/master/polkadot_sdk_frame/traits/trait.SignedExtension.html#associatedtype.Call){target=\_blank}**: To encode the pallet call to be dispatched. This data is used to calculate transaction fees. -- **[`AdditionalSigned`](https://paritytech.github.io/polkadot-sdk/master/polkadot_sdk_frame/traits/trait.SignedExtension.html#associatedtype.AdditionalSigned){target=\_blank}**: To handle any additional data to go into the signed payload allowing you to attach any custom logic prior to dispatching a transaction. -- **[`Pre`](https://paritytech.github.io/polkadot-sdk/master/polkadot_sdk_frame/traits/trait.SignedExtension.html#associatedtype.Pre){target=\_blank}**: To encode the information that can be passed from before a call is dispatched to after it gets dispatched. - -Signed extensions can enforce checks like: - -- **[`CheckSpecVersion`](https://paritytech.github.io/polkadot-sdk/master/src/frame_system/extensions/check_spec_version.rs.html){target=\_blank}**: Ensures the transaction is compatible with the runtime's current version. -- **[`CheckWeight`](https://paritytech.github.io/polkadot-sdk/master/frame_system/struct.CheckWeight.html){target=\_blank}**: Calculates the weight (or computational cost) of the transaction, ensuring the block doesn't exceed the maximum allowed weight. - -These extensions are critical in the transaction lifecycle, ensuring that only valid and prioritized transactions are processed. - -## Transaction Construction - -Building transactions in the Polkadot SDK involves constructing a payload that can be verified, signed, and submitted for inclusion in a block. Each runtime in the Polkadot SDK has its own rules for validating and executing transactions, but there are common patterns for constructing a signed transaction. - -### Construct a Signed Transaction - -A signed transaction in the Polkadot SDK includes various pieces of data to ensure security, prevent replay attacks, and prioritize processing. Here's an overview of how to construct one: - -1. **Construct the unsigned payload**: Gather the necessary information for the call, including: - - - **Pallet index**: Identifies the pallet where the runtime function resides. - - **Function index**: Specifies the particular function to call in the pallet. - - **Parameters**: Any additional arguments required by the function call. - -2. **Create a signing payload**: Once the unsigned payload is ready, additional data must be included: - - - **Transaction nonce**: Unique identifier to prevent replay attacks. - - **Era information**: Defines how long the transaction is valid before it's dropped from the pool. - - **Block hash**: Ensures the transaction doesn't execute on the wrong chain or fork. - -3. **Sign the payload**: Using the sender's private key, sign the payload to ensure that the transaction can only be executed by the account holder. -4. **Serialize the signed payload**: Once signed, the transaction must be serialized into a binary format, ensuring the data is compact and easy to transmit over the network. -5. **Submit the serialized transaction**: Finally, submit the serialized transaction to the network, where it will enter the transaction pool and wait for processing by an authoring node. - -The following is an example of how a signed transaction might look: - -``` rust -node_runtime::UncheckedExtrinsic::new_signed( - function.clone(), // some call - sp_runtime::AccountId32::from(sender.public()).into(), // some sending account - node_runtime::Signature::Sr25519(signature.clone()), // the account's signature - extra.clone(), // the signed extensions -) -``` - -### Transaction Encoding - -Before a transaction is sent to the network, it is serialized and encoded using a structured encoding process that ensures consistency and prevents tampering: - -- **`[1]`**: Compact encoded length in bytes of the entire transaction. -- **`[2]`**: A u8 containing 1 byte to indicate whether the transaction is signed or unsigned (1 bit) and the encoded transaction version ID (7 bits). -- **`[3]`**: If signed, this field contains an account ID, an SR25519 signature, and some extra data. -- **`[4]`**: Encoded call data, including pallet and function indices and any required arguments. - -This encoded format ensures consistency and efficiency in processing transactions across the network. By adhering to this format, applications can construct valid transactions and pass them to the network for execution. - -To learn more about how compact encoding works using SCALE, see the [SCALE Codec](https://github.com/paritytech/parity-scale-codec){target=\_blank} README on GitHub. - -### Customize Transaction Construction - -Although the basic steps for constructing transactions are consistent across Polkadot SDK-based chains, developers can customize transaction formats and validation rules. For example: - -- **Custom pallets**: You can define new pallets with custom function calls, each with its own parameters and validation logic. -- **Signed extensions**: Developers can implement custom extensions that modify how transactions are prioritized, validated, or included in blocks. - -By leveraging Polkadot SDK's modular design, developers can create highly specialized transaction logic tailored to their chain's needs. - -## Lifecycle of a Transaction - -In the Polkadot SDK, transactions are often referred to as extrinsics because the data in transactions originates outside of the runtime. These transactions contain data that initiates changes to the chain state. The most common type of extrinsic is a signed transaction, which is cryptographically verified and typically incurs a fee. This section focuses on how signed transactions are processed, validated, and ultimately included in a block. - -### Define Transaction Properties - -The Polkadot SDK runtime defines key transaction properties, such as: - -- **Transaction validity**: Ensures the transaction meets all runtime requirements. -- **Signed or unsigned**: Identifies whether a transaction needs to be signed by an account. -- **State changes**: Determines how the transaction modifies the state of the chain. - -Pallets, which compose the runtime's logic, define the specific transactions that your chain supports. When a user submits a transaction, such as a token transfer, it becomes a signed transaction, verified by the user's account signature. If the account has enough funds to cover fees, the transaction is executed, and the chain's state is updated accordingly. - -### Process on a Block Authoring Node - -In Polkadot SDK-based networks, some nodes are authorized to author blocks. These nodes validate and process transactions. When a transaction is sent to a node that can produce blocks, it undergoes a lifecycle that involves several stages, including validation and execution. Non-authoring nodes gossip the transaction across the network until an authoring node receives it. The following diagram illustrates the lifecycle of a transaction that's submitted to a network and processed by an authoring node. - -![Transaction lifecycle diagram](/images/reference/parachains/blocks-transactions-fees/transactions/transactions-01.webp){ style="background:white" } - -### Validate and Queue - -Once a transaction reaches an authoring node, it undergoes an initial validation process to ensure it meets specific conditions defined in the runtime. This validation includes checks for: - -- **Correct nonce**: Ensures the transaction is sequentially valid for the account. -- **Sufficient funds**: Confirms the account can cover any associated transaction fees. -- **Signature validity**: Verifies that the sender's signature matches the transaction data. - -After these checks, valid transactions are placed in the transaction pool, where they are queued for inclusion in a block. The transaction pool regularly re-validates queued transactions to ensure they remain valid before being processed. To reach consensus, two-thirds of the nodes must agree on the order of the transactions executed and the resulting state change. Transactions are validated and queued on the local node in a transaction pool to prepare for consensus. - -#### Transaction Pool - -The transaction pool is responsible for managing valid transactions. It ensures that only transactions that pass initial validity checks are queued. Transactions that fail validation, expire, or become invalid for other reasons are removed from the pool. - -The transaction pool organizes transactions into two queues: - -- **Ready queue**: Transactions that are valid and ready to be included in a block. -- **Future queue**: Transactions that are not yet valid but could be in the future, such as transactions with a nonce too high for the current state. - -Details on how the transaction pool validates transactions, including fee and signature handling, can be found in the [`validate_transaction`](https://paritytech.github.io/polkadot-sdk/master/sp_transaction_pool/runtime_api/trait.TaggedTransactionQueue.html#method.validate_transaction){target=\_blank} method. - -#### Invalid Transactions - -If a transaction is invalid, for example, due to an invalid signature or insufficient funds, it is rejected and won't be added to the block. Invalid transactions might be rejected for reasons such as: - -- The transaction has already been included in a block. -- The transaction's signature does not match the sender. -- The transaction is too large to fit in the current block. - -### Transaction Ordering and Priority - -When a node is selected as the next block author, it prioritizes transactions based on weight, length, and tip amount. The goal is to fill the block with high-priority transactions without exceeding its maximum size or computational limits. Transactions are ordered as follows: - -- **Inherents first**: Inherent transactions, such as block timestamp updates, are always placed first. -- **Nonce-based ordering**: Transactions from the same account are ordered by their nonce. -- **Fee-based ordering**: Among transactions with the same nonce or priority level, those with higher fees are prioritized. - -### Transaction Execution - -Once a block author selects transactions from the pool, the transactions are executed in priority order. As each transaction is processed, the state changes are written directly to the chain's storage. It's important to note that these changes are not cached, meaning a failed transaction won't revert earlier state changes, which could leave the block in an inconsistent state. - -Events are also written to storage. Runtime logic should not emit an event before performing the associated actions. If the associated transaction fails after the event was emitted, the event will not revert. - -## Transaction Mortality - -Transactions in the network can be configured as either mortal (with expiration) or immortal (without expiration). Every transaction payload contains a block checkpoint (reference block number and hash) and an era/validity period that determines how many blocks after the checkpoint the transaction remains valid. - -When a transaction is submitted, the network validates it against these parameters. If the transaction is not included in a block within the specified validity window, it is automatically removed from the transaction queue. - -- **Mortal transactions**: Have a finite lifespan and will expire after a specified number of blocks. For example, a transaction with a block checkpoint of 1000 and a validity period of 64 blocks will be valid from blocks 1000 to 1064. - -- **Immortal transactions**: Never expire and remain valid indefinitely. To create an immortal transaction, set the block checkpoint to 0 (genesis block), use the genesis hash as a reference, and set the validity period to 0. - -However, immortal transactions pose significant security risks through replay attacks. If an account is reaped (balance drops to zero, account removed) and later re-funded, malicious actors can replay old immortal transactions. - -The blockchain maintains only a limited number of prior block hashes for reference validation, called `BlockHashCount`. If your validity period exceeds `BlockHashCount`, the effective validity period becomes the minimum of your specified period and the block hash count. - -## Unique Identifiers for Extrinsics - -Transaction hashes are **not unique identifiers** in Polkadot SDK-based chains. - -Key differences from traditional blockchains: - -- Transaction hashes serve only as fingerprints of transaction information. -- Multiple valid transactions can share the same hash. -- Hash uniqueness assumptions lead to serious issues. - -For example, when an account is reaped (removed due to insufficient balance) and later recreated, it resets to nonce 0, allowing identical transactions to be valid at different points: - -| Block | Extrinsic Index | Hash | Origin | Nonce | Call | Result | -|-------|----------------|------|-----------|-------|---------------------|-------------------------------| -| 100 | 0 | 0x01 | Account A | 0 | Transfer 5 DOT to B | Account A reaped | -| 150 | 5 | 0x02 | Account B | 4 | Transfer 7 DOT to A | Account A created (nonce = 0) | -| 200 | 2 | 0x01 | Account A | 0 | Transfer 5 DOT to B | Successful transaction | - -Notice that blocks 100 and 200 contain transactions with identical hashes (0x01) but are completely different, valid operations occurring at different times. - -Additional complexity comes from Polkadot SDK's origin abstraction. Origins can represent collectives, governance bodies, or other non-account entities that don't maintain nonces like regular accounts and might dispatch identical calls multiple times with the same hash values. Each execution occurs in different chain states with different results. - -The correct way to uniquely identify an extrinsic on a Polkadot SDK-based chain is to use the block ID (height or hash) and the extrinsic index. Since the Polkadot SDK defines blocks as headers plus ordered arrays of extrinsics, the index position within a canonical block provides guaranteed uniqueness. - -## Additional Resources - -For a video overview of the lifecycle of transactions and the types of transactions that exist, see the [Transaction lifecycle](https://www.youtube.com/watch?v=3pfM0GOp02c){target=\_blank} seminar from Parity Tech. - - --- Page Title: Transactions and Fees on Asset Hub @@ -11155,91 +9222,3 @@ Here's how to submit this XCM using Astar (Parachain 2006) as an example: After submitting the transaction, wait for it to be finalized and then verify that your parachain has been successfully unlocked by following the steps described in the [Check if the Parachain is Locked](#check-if-the-parachain-is-locked) section. If the parachain shows as unlocked, your operation has been successful. If it still appears locked, verify that your XCM transaction was processed correctly and consider troubleshooting the XCM built. ![](/images/parachains/runtime-maintenance/unlock-parachains/unlock-parachain-6.webp) - - ---- - -Page Title: XCM Tools - -- Source (raw): https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/reference-tools-xcm-tools.md -- Canonical (HTML): https://docs.polkadot.com/reference/tools/xcm-tools/ -- Summary: Explore essential XCM tools across Polkadot, crafted to enhance cross-chain functionality and integration within the ecosystem. - -# XCM Tools - -## Introduction - -As described in the [Interoperability](/develop/interoperability){target=\_blank} section, XCM (Cross-Consensus Messaging) is a protocol used in the Polkadot and Kusama ecosystems to enable communication and interaction between chains. It facilitates cross-chain communication, allowing assets, data, and messages to flow seamlessly across the ecosystem. - -As XCM is central to enabling communication between blockchains, developers need robust tools to help interact with, build, and test XCM messages. Several XCM tools simplify working with the protocol by providing libraries, frameworks, and utilities that enhance the development process, ensuring that applications built within the Polkadot ecosystem can efficiently use cross-chain functionalities. - -## Popular XCM Tools - -### Moonsong Labs XCM Tools - -[Moonsong Labs XCM Tools](https://github.com/Moonsong-Labs/xcm-tools){target=\_blank} provides a collection of scripts for managing and testing XCM operations between Polkadot SDK-based runtimes. These tools allow performing tasks like asset registration, channel setup, and XCM initialization. Key features include: - -- **Asset registration**: Registers assets, setting units per second (up-front fees), and configuring error (revert) codes. -- **XCM initializer**: Initializes XCM, sets default XCM versions, and configures revert codes for XCM-related precompiles. -- **HRMP manipulator**: Manages HRMP channel actions, including opening, accepting, or closing channels. -- **XCM-Transactor-Info-Setter**: Configures transactor information, including extra weight and fee settings. -- **Decode XCM**: Decodes XCM messages on the relay chain or parachains to help interpret cross-chain communication. - -To get started, clone the repository and install the required dependencies: - -```bash -git clone https://github.com/Moonsong-Labs/xcm-tools && -cd xcm-tools && -yarn install -``` - -For a full overview of each script, visit the [scripts](https://github.com/Moonsong-Labs/xcm-tools/tree/main/scripts){target=\_blank} directory or refer to the [official documentation](https://github.com/Moonsong-Labs/xcm-tools/blob/main/README.md){target=\_blank} on GitHub. - -### ParaSpell - -[ParaSpell](/reference/tools/paraspell/){target=\_blank} is a collection of open-source XCM tools that streamline cross-chain asset transfers and interactions across the Polkadot and Kusama ecosystems. It provides developers with an intuitive interface to build, test, and deploy interoperable dApps, featuring message composition, decoding, and practical utilities for parachain interactions that simplify debugging and cross-chain communication optimization. - -### Astar XCM Tools - -The [Astar parachain](https://github.com/AstarNetwork/Astar/tree/master){target=\_blank} offers a crate with a set of utilities for interacting with the XCM protocol. The [xcm-tools](https://github.com/AstarNetwork/Astar/tree/master/bin/xcm-tools){target=\_blank} crate provides a straightforward method for users to locate a sovereign account or calculate an XC20 asset ID. Some commands included by the xcm-tools crate allow users to perform the following tasks: - -- **Sovereign accounts**: Obtain the sovereign account address for any parachain, either on the Relay Chain or for sibling parachains, using a simple command. -- **XC20 EVM addresses**: Generate XC20-compatible Ethereum addresses for assets by entering the asset ID, making it easy to integrate assets across Ethereum-compatible environments. -- **Remote accounts**: Retrieve remote account addresses needed for multi-location compatibility, using flexible options to specify account types and parachain IDs. - -To start using these tools, clone the [Astar repository](https://github.com/AstarNetwork/Astar){target=\_blank} and compile the xcm-tools package: - -```bash -git clone https://github.com/AstarNetwork/Astar && -cd Astar && -cargo build --release -p xcm-tools -``` - -After compiling, verify the setup with the following command: - -```bash -./target/release/xcm-tools --help -``` -For more details on using Astar xcm-tools, consult the [official documentation](https://docs.astar.network/docs/learn/interoperability/xcm/integration/tools/){target=\_blank}. - -### Chopsticks - -The Chopsticks library provides XCM functionality for testing XCM messages across networks, enabling you to fork multiple parachains along with a relay chain. For further details, see the [Chopsticks documentation](/tutorials/polkadot-sdk/testing/fork-live-chains/){target=\_blank} about XCM. - -### Moonbeam XCM SDK - -The [Moonbeam XCM SDK](https://github.com/moonbeam-foundation/xcm-sdk){target=\_blank} enables developers to easily transfer assets between chains, either between parachains or between a parachain and the relay chain, within the Polkadot/Kusama ecosystem. With the SDK, you don't need to worry about determining the [Multilocation](https://github.com/polkadot-fellows/xcm-format?tab=readme-ov-file#7-universal-consensus-location-identifiers){target=\_blank} of the origin or destination assets or which extrinsics are used on which networks. - -The SDK consists of two main packages: - -- **[XCM SDK](https://github.com/moonbeam-foundation/xcm-sdk/tree/main/packages/sdk){target=\_blank}**: Core SDK for executing XCM transfers between chains in the Polkadot/Kusama ecosystem. -- **[MRL SDK](https://github.com/moonbeam-foundation/xcm-sdk/tree/main/packages/mrl){target=\_blank}**: Extension of the XCM SDK for transferring liquidity into and across the Polkadot ecosystem from other ecosystems like Ethereum. - -Key features include: - -- **Simplified asset transfers**: Abstracts away complex multilocation determinations and extrinsic selection. -- **Cross-ecosystem support**: Enables transfers between Polkadot/Kusama chains and external ecosystems. -- **Developer-friendly API**: Provides intuitive interfaces for cross-chain functionality. -- **Comprehensive documentation**: Includes usage guides and API references for both packages. - -For detailed usage examples and API documentation, visit the [official Moonbeam XCM SDK documentation](https://moonbeam-foundation.github.io/xcm-sdk/latest/){target=\_blank}. diff --git a/.ai/categories/polkadot-protocol.md b/.ai/categories/polkadot-protocol.md index 8fd5ccbad..f0346659b 100644 --- a/.ai/categories/polkadot-protocol.md +++ b/.ai/categories/polkadot-protocol.md @@ -1078,144 +1078,6 @@ PolkaVM differs from the EVM in two key ways that make it faster, more hardware- ---- - -Page Title: Elastic Scaling - -- Source (raw): https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/reference-parachains-consensus-elastic-scaling.md -- Canonical (HTML): https://docs.polkadot.com/reference/parachains/consensus/elastic-scaling/ -- Summary: Learn how elastic scaling in Polkadot boosts parachain throughput, reduces latency, and supports dynamic, cost-efficient resource allocation. - -# Elastic Scaling - -## Introduction - -Polkadot's architecture delivers scalability and security through its shared security model, where the relay chain coordinates and validates multiple parallel chains. - -Elastic scaling enhances this architecture by allowing parachains to utilize multiple computational cores simultaneously, breaking the previous 1:1 relationship between parachain and relay chain blocks. - -This technical advancement enables parachains to process multiple blocks within a single relay chain block, significantly increasing throughput capabilities. By leveraging [Agile Coretime](/polkadot-protocol/architecture/polkadot-chain/agile-coretime){target=\_blank}, parachains can dynamically adjust their processing capacity based on demand, creating an efficient and responsive infrastructure for high-throughput applications. - -## How Elastic Scaling Works - -Elastic scaling enables parachains to process multiple blocks in parallel by utilizing additional cores on the relay chain. This section provides a technical analysis of the performance advantages and details of the implementation. - -Consider a parachain that needs to process four consecutive parablocks. With traditional single-core allocation, the validation process follows a strictly sequential pattern. Each parablock undergoes a two-phase process on the relay chain: - -1. **Backing phase**: Validators create and distribute validity statements. -2. **Inclusion phase**: The parablock is included in the relay chain after availability verification. - -Throughout the following diagrams, specific notation is used to represent different components of the system: - -- **R1, R2, ...**: Relay chain blocks (produced at ~6-second intervals). -- **P1, P2, ...**: Parachain blocks that need validation and inclusion. -- **C1, C2, ...**: Cores on the relay chain. - -In the single-core scenario (assuming a 6-second relay chain block time), processing four parablocks requires approximately 30 seconds: - -```mermaid -sequenceDiagram - participant R1 as R1 - participant R2 as R2 - participant R3 as R3 - participant R4 as R4 - participant R5 as R5 - - Note over R1,R5: Single Core Scenario - - rect rgb(200, 220, 240) - Note right of R1: Core C1 - R1->>R1: Back P1 - R2->>R2: Include P1 - R2->>R2: Back P2 - R3->>R3: Include P2 - R3->>R3: Back P3 - R4->>R4: Include P3 - R4->>R4: Back P4 - R5->>R5: Include P4 - end -``` - -With elastic scaling utilizing two cores simultaneously, the same four parablocks can be processed in approximately 18 seconds: - -```mermaid -sequenceDiagram - participant R1 as R1 - participant R2 as R2 - participant R3 as R3 - participant R4 as R4 - participant R5 as R5 - - Note over R1,R3: Multi-Core Scenario - - rect rgb(200, 220, 240) - Note right of R1: Core C1 - R1->>R1: Back P1 - R2->>R2: Include P1 - R2->>R2: Back P2 - R3->>R3: Include P2 - end - - rect rgb(220, 200, 240) - Note right of R1: Core C2 - R1->>R1: Back P3 - R2->>R2: Include P3 - R2->>R2: Back P4 - R3->>R3: Include P4 - end -``` - -To help interpret the sequence diagrams above, note the following key elements: - -- The horizontal axis represents time progression through relay chain blocks (R1-R5). -- Each colored rectangle shows processing on a specific core (C1 or C2). -- In the single-core scenario, all blocks must be processed sequentially on one core. -- In the multi-core scenario, blocks are processed in parallel across multiple cores, reducing total time. - -The relay chain processes these multiple parablocks as independent validation units during the backing, availability, and approval phases. However, during inclusion, it verifies that their state roots align properly to maintain chain consistency. - -From an implementation perspective: - -- **Parachain side**: Collators must increase their block production rate to utilize multiple cores fully. -- **Validation process**: Each core operates independently, but with coordinated state verification. -- **Resource management**: Cores are dynamically allocated based on parachain requirements. -- **State consistency**: While backed and processed in parallel, the parablocks maintain sequential state transitions. - -## Benefits of Elastic Scaling - -- **Increased throughput**: Multiple concurrent cores enable parachains to process transactions at multiples of their previous capacity. By allowing multiple parachain blocks to be validated within each relay chain block cycle, applications can achieve significantly higher transaction volumes. - -- **Lower latency**: Transaction finality improves substantially with multi-core processing. Parachains currently achieve 2-second latency with three cores, with projected improvements to 500ms using 12 cores, enabling near-real-time application responsiveness. - -- **Resource efficiency**: Applications acquire computational resources precisely matched to their needs, eliminating wasteful over-provisioning. Coretime can be purchased at granular intervals (blocks, hours, days), creating cost-effective operations, particularly for applications with variable transaction patterns. - -- **Scalable growth**: New applications can launch with minimal initial resource commitment and scale dynamically as adoption increases. This eliminates the traditional paradox of either over-allocating resources (increasing costs) or under-allocating (degrading performance) during growth phases. - -- **Workload distribution**: Parachains intelligently distribute workloads across cores during peak demand periods and release resources when traffic subsides. Paired with secondary coretime markets, this ensures maximum resource utilization across the entire network ecosystem. - -- **Reliable performance**: End-users experience reliable application performance regardless of network congestion levels. Applications maintain responsiveness even during traffic spikes, eliminating performance degradation that commonly impacts blockchain applications during high-demand periods. - -## Use Cases - -Elastic scaling enables applications to dynamically adjust their resource consumption based on real-time demand. This is especially valuable for decentralized applications where usage patterns can be highly variable. The following examples illustrate common scenarios where elastic scaling delivers significant performance and cost-efficiency benefits. - -### Handling Sudden Traffic Spikes - -Many decentralized applications experience unpredictable, high-volume traffic bursts, especially in gaming, DeFi protocols, NFT auctions, messaging platforms, and social media. Elastic scaling allows these systems to acquire additional coretime during peak usage and release it during quieter periods, ensuring responsiveness without incurring constant high infrastructure costs. - -### Supporting Early-Stage Growth - -Startups and new projects often begin with uncertain or volatile demand. With elastic scaling, teams can launch with minimal compute resources (e.g., a single core) and gradually scale as adoption increases. This prevents overprovisioning and enables cost-efficient growth until the application is ready for more permanent or horizontal scaling. - -### Scaling Massive IoT Networks - -Internet of Things (IoT) applications often involve processing data from millions of devices in real time. Elastic scaling supports this need by enabling high-throughput transaction processing as demand fluctuates. Combined with Polkadot’s shared security model, it provides a reliable and privacy-preserving foundation for large-scale IoT deployments. - -### Powering Real-Time, Low-Latency Systems - -Applications like payment processors, trading platforms, gaming engines, or real-time data feeds require fast, consistent performance. Elastic scaling can reduce execution latency during demand spikes, helping ensure low-latency, reliable service even under heavy load. - - --- Page Title: Get Started with Parachain Development @@ -1534,374 +1396,6 @@ XCM revolutionizes cross-chain communication by enabling use cases such as: These functionalities empower developers to build innovative, multi-chain applications, leveraging the strengths of various blockchain networks. To stay updated on XCM’s evolving format or contribute, visit the [XCM repository](https://github.com/paritytech/xcm-docs/blob/main/examples/src/0_first_look/mod.rs){target=\_blank}. ---- - -Page Title: Glossary - -- Source (raw): https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/reference-glossary.md -- Canonical (HTML): https://docs.polkadot.com/reference/glossary/ -- Summary: Glossary of terms used within the Polkadot ecosystem, Polkadot SDK, its subsequent libraries, and other relevant Web3 terminology. - -# Glossary - -Key definitions, concepts, and terminology specific to the Polkadot ecosystem are included here. - -Additional glossaries from around the ecosystem you might find helpful: - -- [Polkadot Wiki Glossary](https://wiki.polkadot.com/general/glossary){target=\_blank} -- [Polkadot SDK Glossary](https://paritytech.github.io/polkadot-sdk/master/polkadot_sdk_docs/reference_docs/glossary/index.html){target=\_blank} - -## Authority - -The role in a blockchain that can participate in consensus mechanisms. - -- **[GRANDPA](#grandpa)**: The authorities vote on chains they consider final. -- **[Blind Assignment of Blockchain Extension](#blind-assignment-of-blockchain-extension-babe) (BABE)**: The authorities are also [block authors](#block-author). - -Authority sets can be used as a basis for consensus mechanisms such as the [Nominated Proof of Stake (NPoS)](#nominated-proof-of-stake-npos) protocol. - -## Authority Round (Aura) - -A deterministic [consensus](#consensus) protocol where block production is limited to a rotating list of [authorities](#authority) that take turns creating blocks. In authority round (Aura) consensus, most online authorities are assumed to be honest. It is often used in combination with [GRANDPA](#grandpa) as a [hybrid consensus](#hybrid-consensus) protocol. - -Learn more by reading the official [Aura consensus algorithm](https://openethereum.github.io/Aura){target=\_blank} wiki article. - -## Blind Assignment of Blockchain Extension (BABE) - -A [block authoring](#block-author) protocol similar to [Aura](#authority-round-aura), except [authorities](#authority) win [slots](#slot) based on a Verifiable Random Function (VRF) instead of the round-robin selection method. The winning authority can select a chain and submit a new block. - -Learn more by reading the official Web3 Foundation [BABE research document](https://research.web3.foundation/Polkadot/protocols/block-production/Babe){target=\_blank}. - -## Block Author - -The node responsible for the creation of a block, also called _block producers_. In a Proof of Work (PoW) blockchain, these nodes are called _miners_. - -## Byzantine Fault Tolerance (BFT) - -The ability of a distributed computer network to remain operational if a certain proportion of its nodes or [authorities](#authority) are defective or behaving maliciously. A distributed network is typically considered Byzantine fault tolerant if it can remain functional, with up to one-third of nodes assumed to be defective, offline, actively malicious, and part of a coordinated attack. - -### Byzantine Failure - -The loss of a network service due to node failures that exceed the proportion of nodes required to reach consensus. - -### Practical Byzantine Fault Tolerance (pBFT) - -An early approach to Byzantine fault tolerance (BFT), practical Byzantine fault tolerance (pBFT) systems tolerate Byzantine behavior from up to one-third of participants. - -The communication overhead for such systems is `O(n²)`, where `n` is the number of nodes (participants) in the system. - -### Preimage - -A preimage is the data that is input into a hash function to calculate a hash. Since a hash function is a [one-way function](https://en.wikipedia.org/wiki/One-way_function){target=\_blank}, the output, the hash, cannot be used to reveal the input, the preimage. - -## Call - -In the context of pallets containing functions to be dispatched to the runtime, `Call` is an enumeration data type that describes the functions that can be dispatched with one variant per pallet. A `Call` represents a [dispatch](#dispatchable) data structure object. - -## Chain Specification - -A chain specification file defines the properties required to run a node in an active or new Polkadot SDK-built network. It often contains the initial genesis runtime code, network properties (such as the network's name), the initial state for some pallets, and the boot node list. The chain specification file makes it easy to use a single Polkadot SDK codebase as the foundation for multiple independently configured chains. - -## Collator - -An [author](#block-author) of a [parachain](#parachain) network. -They aren't [authorities](#authority) in themselves, as they require a [relay chain](#relay-chain) to coordinate [consensus](#consensus). - -More details are found on the [Polkadot Collator Wiki](https://wiki.polkadot.com/learn/learn-collator/){target=\_blank}. - -## Collective - -Most often used to refer to an instance of the Collective pallet on Polkadot SDK-based networks such as [Kusama](#kusama) or [Polkadot](#polkadot) if the Collective pallet is part of the FRAME-based runtime for the network. - -## Consensus - -Consensus is the process blockchain nodes use to agree on a chain's canonical fork. It is composed of [authorship](#block-author), finality, and [fork-choice rule](#fork-choice-rulestrategy). In the Polkadot ecosystem, these three components are usually separate and the term consensus often refers specifically to authorship. - -See also [hybrid consensus](#hybrid-consensus). - -## Consensus Algorithm - -Ensures a set of [actors](#authority)—who don't necessarily trust each other—can reach an agreement about the state as the result of some computation. Most consensus algorithms assume that up to one-third of the actors or nodes can be [Byzantine fault tolerant](#byzantine-fault-tolerance-bft). - -Consensus algorithms are generally concerned with ensuring two properties: - -- **Safety**: Indicating that all honest nodes eventually agreed on the state of the chain. -- **Liveness**: Indicating the ability of the chain to keep progressing. - -## Consensus Engine - -The node subsystem responsible for consensus tasks. - -For detailed information about the consensus strategies of the [Polkadot](#polkadot) network, see the [Polkadot Consensus](/reference/polkadot-hub/consensus-and-security/pos-consensus/){target=\_blank} blog series. - -See also [hybrid consensus](#hybrid-consensus). - -## Coretime - -The time allocated for utilizing a core, measured in relay chain blocks. There are two types of coretime: *on-demand* and *bulk*. - -On-demand coretime refers to coretime acquired through bidding in near real-time for the validation of a single parachain block on one of the cores reserved specifically for on-demand orders. They are available as an on-demand coretime pool. Set of cores that are available on-demand. Cores reserved through bulk coretime could also be made available in the on-demand coretime pool, in parts or in entirety. - -Bulk coretime is a fixed duration of continuous coretime represented by an NFT that can be split, shared, or resold. It is managed by the [Broker pallet](https://paritytech.github.io/polkadot-sdk/master/pallet_broker/index.html){target=\_blank}. - -## Development Phrase - -A [mnemonic phrase](https://en.wikipedia.org/wiki/Mnemonic#For_numerical_sequences_and_mathematical_operations){target=\_blank} that is intentionally made public. - -Well-known development accounts, such as Alice, Bob, Charlie, Dave, Eve, and Ferdie, are generated from the same secret phrase: - -``` -bottom drive obey lake curtain smoke basket hold race lonely fit walk -``` - -Many tools in the Polkadot SDK ecosystem, such as [`subkey`](https://github.com/paritytech/polkadot-sdk/tree/polkadot-stable2506-2/substrate/bin/utils/subkey){target=\_blank}, allow you to implicitly specify an account using a derivation path such as `//Alice`. - -## Digest - -An extensible field of the [block header](#header) that encodes information needed by several actors in a blockchain network, including: - -- [Light clients](#light-client) for chain synchronization. -- Consensus engines for block verification. -- The runtime itself, in the case of pre-runtime digests. - -## Dispatchable - -Function objects that act as the entry points in FRAME [pallets](#pallet). Internal or external entities can call them to interact with the blockchain’s state. They are a core aspect of the runtime logic, handling [transactions](#transaction) and other state-changing operations. - -## Events - -A means of recording that some particular [state](#state) transition happened. - -In the context of [FRAME](#frame-framework-for-runtime-aggregation-of-modularized-entities), events are composable data types that each [pallet](#pallet) can individually define. Events in FRAME are implemented as a set of transient storage items inspected immediately after a block has been executed and reset during block initialization. - -## Executor - -A means of executing a function call in a given [runtime](#runtime) with a set of dependencies. -There are two orchestration engines in Polkadot SDK, _WebAssembly_ and _native_. - -- The _native executor_ uses a natively compiled runtime embedded in the node to execute calls. This is a performance optimization available to up-to-date nodes. - -- The _WebAssembly executor_ uses a [Wasm](#webassembly-wasm) binary and a Wasm interpreter to execute calls. The binary is guaranteed to be up-to-date regardless of the version of the blockchain node because it is persisted in the [state](#state) of the Polkadot SDK-based chain. - -## Existential Deposit - -The minimum balance an account is allowed to have in the [Balances pallet](https://paritytech.github.io/polkadot-sdk/master/pallet_balances/index.html){target=\_blank}. Accounts cannot be created with a balance less than the existential deposit amount. - -If an account balance drops below this amount, the Balances pallet uses [a FRAME System API](https://paritytech.github.io/substrate/master/frame_system/pallet/struct.Pallet.html#method.dec_ref){target=\_blank} to drop its references to that account. - -If the Balances pallet reference to an account is dropped, the account can be [reaped](https://paritytech.github.io/substrate/master/frame_system/pallet/struct.Pallet.html#method.allow_death){target=\_blank}. - -## Extrinsic - -A general term for data that originates outside the runtime, is included in a block, and leads to some action. This includes user-initiated transactions and inherent transactions placed into the block by the block builder. - -It is a SCALE-encoded array typically consisting of a version number, signature, and varying data types indicating the resulting runtime function to be called. Extrinsics can take two forms: [inherents](#inherent-transactions) and [transactions](#transaction). - -For more technical details, see the [Polkadot spec](https://spec.polkadot.network/id-extrinsics){target=\_blank}. - -## Fork Choice Rule/Strategy - -A fork choice rule or strategy helps determine which chain is valid when reconciling several network forks. A common fork choice rule is the [longest chain](https://paritytech.github.io/polkadot-sdk/master/sc_consensus/struct.LongestChain.html){target=\_blank}, in which the chain with the most blocks is selected. - -## FRAME (Framework for Runtime Aggregation of Modularized Entities) - -Enables developers to create blockchain [runtime](#runtime) environments from a modular set of components called [pallets](#pallet). It utilizes a set of procedural macros to construct runtimes. - -[Visit the Polkadot SDK docs for more details on FRAME.](https://paritytech.github.io/polkadot-sdk/master/polkadot_sdk_docs/polkadot_sdk/frame_runtime/index.html){target=\_blank} - -## Full Node - -A node that prunes historical states, keeping only recently finalized block states to reduce storage needs. Full nodes provide current chain state access and allow direct submission and validation of [extrinsics](#extrinsic), maintaining network decentralization. - -## Genesis Configuration - -A mechanism for specifying the initial state of a blockchain. By convention, this initial state or first block is commonly referred to as the genesis state or genesis block. The genesis configuration for Polkadot SDK-based chains is accomplished by way of a [chain specification](#chain-specification) file. - -## GRANDPA - -A deterministic finality mechanism for blockchains that is implemented in the [Rust](https://www.rust-lang.org/){target=\_blank} programming language. - -The [formal specification](https://github.com/w3f/consensus/blob/master/pdf/grandpa-old.pdf){target=\_blank} is maintained by the [Web3 Foundation](https://web3.foundation/){target=\_blank}. - -## Header - -A structure that aggregates the information used to summarize a block. Primarily, it consists of cryptographic information used by [light clients](#light-client) to get minimally secure but very efficient chain synchronization. - -## Hybrid Consensus - -A blockchain consensus protocol that consists of independent or loosely coupled mechanisms for [block production](#block-author) and finality. - -Hybrid consensus allows the chain to grow as fast as probabilistic consensus protocols, such as [Aura](#authority-round-aura), while maintaining the same level of security as deterministic finality consensus protocols, such as [GRANDPA](#grandpa). - -## Inherent Transactions - -A special type of unsigned transaction, referred to as _inherents_, that enables a block authoring node to insert information that doesn't require validation directly into a block. - -Only the block-authoring node that calls the inherent transaction function can insert data into its block. In general, validators assume the data inserted using an inherent transaction is valid and reasonable even if it can't be deterministically verified. - -## JSON-RPC - -A stateless, lightweight remote procedure call protocol encoded in JavaScript Object Notation (JSON). JSON-RPC provides a standard way to call functions on a remote system by using JSON. - -For Polkadot SDK, this protocol is implemented through the [Parity JSON-RPC](https://github.com/paritytech/jsonrpc){target=\_blank} crate. - -## Keystore - -A subsystem for managing keys for the purpose of producing new blocks. - -## Kusama - -[Kusama](https://kusama.network/){target=\_blank} is a Polkadot SDK-based blockchain that implements a design similar to the [Polkadot](#polkadot) network. - -Kusama is a [canary](https://en.wiktionary.org/wiki/canary_in_a_coal_mine){target=\_blank} network and is referred to as [Polkadot's "wild cousin."](https://wiki.polkadot.com/learn/learn-comparisons-kusama/){target=\_blank}. - -As a canary network, Kusama is expected to be more stable than a test network like [Westend](#westend) but less stable than a production network like [Polkadot](#polkadot). Kusama is controlled by its network participants and is intended to be stable enough to encourage meaningful experimentation. - -## libp2p - -A peer-to-peer networking stack that allows the use of many transport mechanisms, including WebSockets (usable in a web browser). - -Polkadot SDK uses the [Rust implementation](https://github.com/libp2p/rust-libp2p){target=\_blank} of the `libp2p` networking stack. - -## Light Client - -A type of blockchain node that doesn't store the [chain state](#state) or produce blocks. - -A light client can verify cryptographic primitives and provides a [remote procedure call (RPC)](https://en.wikipedia.org/wiki/Remote_procedure_call){target=\_blank} server, enabling blockchain users to interact with the network. - -## Metadata - -Data that provides information about one or more aspects of a system. -The metadata that exposes information about a Polkadot SDK blockchain enables you to interact with that system. - -## Nominated Proof of Stake (NPoS) - -A method for determining [validators](#validator) or _[authorities](#authority)_ based on a willingness to commit their stake to the proper functioning of one or more block-producing nodes. - -## Oracle - -An entity that connects a blockchain to a non-blockchain data source. Oracles enable the blockchain to access and act upon information from existing data sources and incorporate data from non-blockchain systems and services. - -## Origin - -A [FRAME](#frame-framework-for-runtime-aggregation-of-modularized-entities) primitive that identifies the source of a [dispatched](#dispatchable) function call into the [runtime](#runtime). The FRAME System pallet defines three built-in [origins](#origin). As a [pallet](#pallet) developer, you can also define custom origins, such as those defined by the [Collective pallet](https://paritytech.github.io/substrate/master/pallet_collective/enum.RawOrigin.html){target=\_blank}. - -## Pallet - -A module that can be used to extend the capabilities of a [FRAME](#frame-framework-for-runtime-aggregation-of-modularized-entities)-based [runtime](#runtime). -Pallets bundle domain-specific logic with runtime primitives like [events](#events) and [storage items](#storage-item). - -## Parachain - -A parachain is a blockchain that derives shared infrastructure and security from a _[relay chain](#relay-chain)_. -You can learn more about parachains on the [Polkadot Wiki](https://wiki.polkadot.com/learn/learn-parachains/){target=\_blank}. - -## Paseo - -Paseo TestNet provisions testing on Polkadot's "production" runtime, which means less chance of feature or code mismatch when developing parachain apps. Specifically, after the [Polkadot Technical fellowship](https://wiki.polkadot.com/learn/learn-polkadot-technical-fellowship/){target=\_blank} proposes a runtime upgrade for Polkadot, this TestNet is updated, giving a period where the TestNet will be ahead of Polkadot to allow for testing. - -## Polkadot - -The [Polkadot network](https://polkadot.com/){target=\_blank} is a blockchain that serves as the central hub of a heterogeneous blockchain network. It serves the role of the [relay chain](#relay-chain) and provides shared infrastructure and security to support [parachains](#parachain). - -## Polkadot Cloud - -Polkadot Cloud is a platform for deploying resilient, customizable and scalable Web3 applications through Polkadot's functionality. It encompasses the wider Polkadot network infrastructure and security layer where parachains operate. The platform enables users to launch Ethereum-compatible chains, build specialized blockchains, and flexibly manage computing resources through on-demand or bulk coretime purchases. Initially launched with basic parachain functionality, Polkadot Cloud has evolved to offer enhanced flexibility with features like coretime, elastic scaling, and async backing for improved performance. - -## Polkadot Hub - -Polkadot Hub is a Layer 1 platform that serves as the primary entry point to the Polkadot ecosystem, providing essential functionality without requiring parachain deployment. It offers core services including smart contracts, identity management, staking, governance, and interoperability with other ecosystems, making it simple and fast for both builders and users to get started in Web3. - -## PolkaVM - -PolkaVM is a custom virtual machine optimized for performance, leveraging a RISC-V-based architecture to support Solidity and any language that compiles to RISC-V. It is specifically designed for the Polkadot ecosystem, enabling smart contract deployment and execution. - -## Relay Chain - -Relay chains are blockchains that provide shared infrastructure and security to the [parachains](#parachain) in the network. In addition to providing [consensus](#consensus) capabilities, relay chains allow parachains to communicate and exchange digital assets without needing to trust one another. - -## Rococo - -A [parachain](#parachain) test network for the Polkadot network. The [Rococo](#rococo) network is a Polkadot SDK-based blockchain with an October 14, 2024 deprecation date. Development teams are encouraged to use the Paseo TestNet instead. - -## Runtime - -The runtime represents the [state transition function](#state-transition-function-stf) for a blockchain. In Polkadot SDK, the runtime is stored as a [Wasm](#webassembly-wasm) binary in the chain state. The Runtime is stored under a unique state key and can be modified during the execution of the state transition function. - -## Slot - -A fixed, equal interval of time used by consensus engines such as [Aura](#authority-round-aura) and [BABE](#blind-assignment-of-blockchain-extension-babe). In each slot, a subset of [authorities](#authority) is permitted, or obliged, to [author](#block-author) a block. - -## Sovereign Account - -The unique account identifier for each chain in the relay chain ecosystem. It is often used in cross-consensus (XCM) interactions to sign XCM messages sent to the relay chain or other chains in the ecosystem. - -The sovereign account for each chain is a root-level account that can only be accessed using the Sudo pallet or through governance. The account identifier is calculated by concatenating the Blake2 hash of a specific text string and the registered parachain identifier. - -## SS58 Address Format - -A public key address based on the Bitcoin [`Base-58-check`](https://en.bitcoin.it/wiki/Base58Check_encoding){target=\_blank} encoding. Each Polkadot SDK SS58 address uses a `base-58` encoded value to identify a specific account on a specific Polkadot SDK-based chain - -The [canonical `ss58-registry`](https://github.com/paritytech/ss58-registry){target=\_blank} provides additional details about the address format used by different Polkadot SDK-based chains, including the network prefix and website used for different networks - -## State Transition Function (STF) - -The logic of a blockchain that determines how the state changes when a block is processed. In Polkadot SDK, the state transition function is effectively equivalent to the [runtime](#runtime). - -## Storage Item - -[FRAME](#frame-framework-for-runtime-aggregation-of-modularized-entities) primitives that provide type-safe data persistence capabilities to the [runtime](#runtime). -Learn more in the [storage items](https://paritytech.github.io/polkadot-sdk/master/frame_support/storage/types/index.html){target=\_blank} reference document in the Polkadot SDK. - -## Substrate - -A flexible framework for building modular, efficient, and upgradeable blockchains. Substrate is written in the [Rust](https://www.rust-lang.org/){target=\_blank} programming language and is maintained by [Parity Technologies](https://www.parity.io/){target=\_blank}. - -## Transaction - -An [extrinsic](#extrinsic) that includes a signature that can be used to verify the account authorizing it inherently or via [signed extensions](https://paritytech.github.io/polkadot-sdk/master/polkadot_sdk_docs/reference_docs/signed_extensions/index.html){target=\_blank}. - -## Transaction Era - -A definable period expressed as a range of block numbers during which a transaction can be included in a block. -Transaction eras are used to protect against transaction replay attacks if an account is reaped and its replay-protecting nonce is reset to zero. - -## Trie (Patricia Merkle Tree) - -A data structure used to represent sets of key-value pairs and enables the items in the data set to be stored and retrieved using a cryptographic hash. Because incremental changes to the data set result in a new hash, retrieving data is efficient even if the data set is very large. With this data structure, you can also prove whether the data set includes any particular key-value pair without access to the entire data set. - -In Polkadot SDK-based blockchains, state is stored in a trie data structure that supports the efficient creation of incremental digests. This trie is exposed to the [runtime](#runtime) as [a simple key/value map](#storage-item) where both keys and values can be arbitrary byte arrays. - -## Validator - -A validator is a node that participates in the consensus mechanism of the network. Its roles include block production, transaction validation, network integrity, and security maintenance. - -## WebAssembly (Wasm) - -An execution architecture that allows for the efficient, platform-neutral expression of -deterministic, machine-executable logic. - -[Wasm](https://webassembly.org/){target=\_blank} can be compiled from many languages, including -the [Rust](https://www.rust-lang.org/){target=\_blank} programming language. Polkadot SDK-based chains use a Wasm binary to provide portable [runtimes](#runtime) that can be included as part of the chain's state. - -## Weight - -A convention used in Polkadot SDK-based blockchains to measure and manage the time it takes to validate a block. -Polkadot SDK defines one unit of weight as one picosecond of execution time on reference hardware. - -The maximum block weight should be equivalent to one-third of the target block time with an allocation of one-third each for: - -- Block construction -- Network propagation -- Import and verification - -By defining weights, you can trade-off the number of transactions per second and the hardware required to maintain the target block time appropriate for your use case. Weights are defined in the runtime, meaning you can tune them using runtime updates to keep up with hardware and software improvements. - -## Westend - -Westend is a Parity-maintained, Polkadot SDK-based blockchain that serves as a test network for the [Polkadot](#polkadot) network. - - --- Page Title: Install Polkadot SDK @@ -2326,105 +1820,35 @@ To stop the node, press `Control-C` in the terminal. --- -Page Title: Interoperability +Page Title: JSON-RPC APIs -- Source (raw): https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/reference-parachains-interoperability.md -- Canonical (HTML): https://docs.polkadot.com/reference/parachains/interoperability/ -- Summary: Explore the importance of interoperability in the Polkadot ecosystem, covering XCM, bridges, and cross-chain communication. +- Source (raw): https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/smart-contracts-for-eth-devs-json-rpc-apis.md +- Canonical (HTML): https://docs.polkadot.com/smart-contracts/for-eth-devs/json-rpc-apis/ +- Summary: JSON-RPC APIs guide for Polkadot Hub, covering supported methods, parameters, and examples for interacting with the chain. -# Interoperability +# JSON-RPC APIs ## Introduction -Interoperability lies at the heart of the Polkadot ecosystem, enabling communication and collaboration across a diverse range of blockchains. By bridging the gaps between parachains, relay chains, and even external networks, Polkadot unlocks the potential for truly decentralized applications, efficient resource sharing, and scalable solutions. - -Polkadot’s design ensures that blockchains can transcend their individual limitations by working together as part of a unified system. This cooperative architecture is what sets Polkadot apart in the blockchain landscape. - -## Why Interoperability Matters - -The blockchain ecosystem is inherently fragmented. Different blockchains excel in specialized domains such as finance, gaming, or supply chain management, but these chains function in isolation without interoperability. This lack of connectivity stifles the broader utility of blockchain technology. - -Interoperability solves this problem by enabling blockchains to: - -- **Collaborate across networks**: Chains can interact to share assets, functionality, and data, creating synergies that amplify their individual strengths. -- **Achieve greater scalability**: Specialized chains can offload tasks to others, optimizing performance and resource utilization. -- **Expand use-case potential**: Cross-chain applications can leverage features from multiple blockchains, unlocking novel user experiences and solutions. - -In the Polkadot ecosystem, interoperability transforms a collection of isolated chains into a cohesive, efficient network, pushing the boundaries of what blockchains can achieve together. - -## Key Mechanisms for Interoperability - -At the core of Polkadot's cross-chain collaboration are foundational technologies designed to break down barriers between networks. These mechanisms empower blockchains to communicate, share resources, and operate as a cohesive ecosystem. - -### Cross-Consensus Messaging (XCM): The Backbone of Communication +Polkadot Hub provides Ethereum compatibility through its JSON-RPC interface, allowing developers to interact with the chain using familiar Ethereum tooling and methods. This document outlines the supported [Ethereum JSON-RPC methods](https://ethereum.org/developers/docs/apis/json-rpc/#json-rpc-methods){target=\_blank} and provides examples of how to use them. -Polkadot's Cross-Consensus Messaging (XCM) is the standard framework for interaction between parachains, relay chains, and, eventually, external blockchains. XCM provides a trustless, secure messaging format for exchanging assets, sharing data, and executing cross-chain operations. +This guide uses the Polkadot Hub TestNet endpoint: -Through XCM, decentralized applications can: +```text +https://testnet-passet-hub-eth-rpc.polkadot.io +``` -- Transfer tokens and other assets across chains. -- Coordinate complex workflows that span multiple blockchains. -- Enable seamless user experiences where underlying blockchain differences are invisible. -- XCM exemplifies Polkadot’s commitment to creating a robust and interoperable ecosystem. +## Available Methods -For further information about XCM, check the [Get Started with XCM](/parachains/interoperability/get-started/){target=\_blank} article. +### eth_accounts -### Bridges: Connecting External Networks +Returns a list of addresses owned by the client. [Reference](https://ethereum.org/developers/docs/apis/json-rpc/#eth_accounts){target=\_blank}. -While XCM enables interoperability within the Polkadot ecosystem, bridges extend this functionality to external blockchains such as Ethereum and Bitcoin. By connecting these networks, bridges allow Polkadot-based chains to access external liquidity, additional functionalities, and broader user bases. +**Parameters**: -With bridges, developers and users gain the ability to: +None. -- Integrate external assets into Polkadot-based applications. -- Combine the strengths of Polkadot’s scalability with the liquidity of other networks. -- Facilitate accurate multi-chain applications that transcend ecosystem boundaries. - -For more information about bridges in the Polkadot ecosystem, see the [Bridge Hub](/reference/polkadot-hub/bridging/){target=\_blank} guide. - -## The Polkadot Advantage - -Polkadot was purpose-built for interoperability. Unlike networks that add interoperability as an afterthought, Polkadot integrates it as a fundamental design principle. This approach offers several distinct advantages: - -- **Developer empowerment**: Polkadot’s interoperability tools allow developers to build applications that leverage multiple chains’ capabilities without added complexity. -- **Enhanced ecosystem collaboration**: Chains in Polkadot can focus on their unique strengths while contributing to the ecosystem’s overall growth. -- **Future-proofing blockchain**: By enabling seamless communication, Polkadot ensures its ecosystem can adapt to evolving demands and technologies. - -## Looking Ahead - -Polkadot’s vision of interoperability extends beyond technical functionality, representing a shift towards a more collaborative blockchain landscape. By enabling chains to work together, Polkadot fosters innovation, efficiency, and accessibility, paving the way for a decentralized future where blockchains are not isolated competitors but interconnected collaborators. - - ---- - -Page Title: JSON-RPC APIs - -- Source (raw): https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/smart-contracts-for-eth-devs-json-rpc-apis.md -- Canonical (HTML): https://docs.polkadot.com/smart-contracts/for-eth-devs/json-rpc-apis/ -- Summary: JSON-RPC APIs guide for Polkadot Hub, covering supported methods, parameters, and examples for interacting with the chain. - -# JSON-RPC APIs - -## Introduction - -Polkadot Hub provides Ethereum compatibility through its JSON-RPC interface, allowing developers to interact with the chain using familiar Ethereum tooling and methods. This document outlines the supported [Ethereum JSON-RPC methods](https://ethereum.org/developers/docs/apis/json-rpc/#json-rpc-methods){target=\_blank} and provides examples of how to use them. - -This guide uses the Polkadot Hub TestNet endpoint: - -```text -https://testnet-passet-hub-eth-rpc.polkadot.io -``` - -## Available Methods - -### eth_accounts - -Returns a list of addresses owned by the client. [Reference](https://ethereum.org/developers/docs/apis/json-rpc/#eth_accounts){target=\_blank}. - -**Parameters**: - -None. - -**Example**: +**Example**: ```bash title="eth_accounts" curl -X POST https://testnet-passet-hub-eth-rpc.polkadot.io \ @@ -3263,346 +2687,6 @@ If an error occurs, the response will include an error object: ``` ---- - -Page Title: Networks - -- Source (raw): https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/reference-parachains-networks.md -- Canonical (HTML): https://docs.polkadot.com/reference/parachains/networks/ -- Summary: Explore Polkadot's testing and production networks, including Westend, Kusama, and Paseo, for efficient development, deployment, and testing. - -# Networks - -## Introduction - -The Polkadot ecosystem is built on a robust set of networks designed to enable secure and scalable development. Whether you are testing new features or deploying to live production, Polkadot offers several layers of networks tailored for each stage of the development process. From local environments to experimental networks like Kusama and community-run TestNets such as Paseo, developers can thoroughly test, iterate, and validate their applications. This guide will introduce you to Polkadot's various networks and explain how they fit into the development workflow. - -## Network Overview - -Polkadot's development process is structured to ensure new features and upgrades are rigorously tested before being deployed on live production networks. The progression follows a well-defined path, starting from local environments and advancing through TestNets, ultimately reaching the Polkadot MainNet. The diagram below outlines the typical progression of the Polkadot development cycle: - -``` mermaid -flowchart LR - id1[Local] --> id2[Westend] --> id4[Kusama] --> id5[Polkadot] - id1[Local] --> id3[Paseo] --> id5[Polkadot] -``` - -This flow ensures developers can thoroughly test and iterate without risking real tokens or affecting production networks. Testing tools like [Chopsticks](#chopsticks) and various TestNets make it easier to experiment safely before releasing to production. - -A typical journey through the Polkadot core protocol development process might look like this: - -1. **Local development node**: Development starts in a local environment, where developers can create, test, and iterate on upgrades or new features using a local development node. This stage allows rapid experimentation in an isolated setup without any external dependencies. - -2. **Westend**: After testing locally, upgrades are deployed to [Westend](#westend), Polkadot's primary TestNet. Westend simulates real-world conditions without using real tokens, making it the ideal place for rigorous feature testing before moving on to production networks. - -3. **Kusama**: Once features have passed extensive testing on Westend, they move to Kusama, Polkadot's experimental and fast-moving "canary" network. Kusama operates as a high-fidelity testing ground with actual economic incentives, giving developers insights into how their features will perform in a real-world environment. - -4. **Polkadot**: After passing tests on Westend and Kusama, features are considered ready for deployment to Polkadot, the live production network. - - In addition, parachain developers can leverage local TestNets like [Zombienet](#zombienet) and deploy upgrades on parachain TestNets. - -5. **Paseo**: For parachain and dApp developers, Paseo serves as a community-run TestNet that mirrors Polkadot's runtime. Like Westend for core protocol development, Paseo provides a testing ground for parachain development without affecting live networks. - -!!!note - The Rococo TestNet deprecation date was October 14, 2024. Teams should use Westend for Polkadot protocol and feature testing and Paseo for chain development-related testing. - -## Polkadot Development Networks - -Development and testing are crucial to building robust dApps and parachains and performing network upgrades within the Polkadot ecosystem. To achieve this, developers can leverage various networks and tools that provide a risk-free environment for experimentation and validation before deploying features to live networks. These networks help avoid the costs and risks associated with real tokens, enabling testing for functionalities like governance, cross-chain messaging, and runtime upgrades. - -## Kusama Network - -Kusama is the experimental version of Polkadot, designed for developers who want to move quickly and test their applications in a real-world environment with economic incentives. Kusama serves as a production-grade testing ground where developers can deploy features and upgrades with the pressure of game theory and economics in mind. It mirrors Polkadot but operates as a more flexible space for innovation. - -The native token for Kusama is KSM. For more information about KSM, visit the [Native Assets](https://wiki.polkadot.com/kusama/kusama-getting-started/){target=\_blank} page. - -## Test Networks - -The following test networks provide controlled environments for testing upgrades and new features. TestNet tokens are available from the [Polkadot faucet](https://faucet.polkadot.io/){target=\_blank}. - -### Westend - -Westend is Polkadot's primary permanent TestNet. Unlike temporary test networks, Westend is not reset to the genesis block, making it an ongoing environment for testing Polkadot core features. Managed by Parity Technologies, Westend ensures that developers can test features in a real-world simulation without using actual tokens. - -The native token for Westend is WND. More details about WND can be found on the [Native Assets](https://wiki.polkadot.com/learn/learn-dot/#__tabbed_2_2){target=\_blank} page. - -### Paseo - -[Paseo](https://github.com/paseo-network){target=\_blank} is a community-managed TestNet designed for parachain and dApp developers. It mirrors Polkadot's runtime and is maintained by Polkadot community members. Paseo provides a dedicated space for parachain developers to test their applications in a Polkadot-like environment without the risks associated with live networks. - -The native token for Paseo is PAS. Additional information on PAS is available on the [Native Assets](https://wiki.polkadot.com/learn/learn-dot/#__tabbed_2_1){target=\_blank} page. - -## Local Test Networks - -Local test networks are an essential part of the development cycle for blockchain developers using the Polkadot SDK. They allow for fast, iterative testing in controlled, private environments without connecting to public TestNets. Developers can quickly spin up local instances to experiment, debug, and validate their code before deploying to larger TestNets like Westend or Paseo. Two key tools for local network testing are Zombienet and Chopsticks. - -### Zombienet - -[Zombienet](https://github.com/paritytech/zombienet){target=\_blank} is a flexible testing framework for Polkadot SDK-based blockchains. It enables developers to create and manage ephemeral, short-lived networks. This feature makes Zombienet particularly useful for quick iterations, as it allows you to run multiple local networks concurrently, mimicking different runtime conditions. Whether you're developing a parachain or testing your custom blockchain logic, Zombienet gives you the tools to automate local testing. - -Key features of Zombienet include: - -- Creating dynamic, local networks with different configurations. -- Running parachains and relay chains in a simulated environment. -- Efficient testing of network components like cross-chain messaging and governance. - -Zombienet is ideal for developers looking to test quickly and thoroughly before moving to more resource-intensive public TestNets. - -### Chopsticks - -[Chopsticks](https://github.com/AcalaNetwork/chopsticks){target=\_blank} is a tool designed to create forks of Polkadot SDK-based blockchains, allowing developers to interact with network forks as part of their testing process. This capability makes Chopsticks a powerful option for testing upgrades, runtime changes, or cross-chain applications in a forked network environment. - -Key features of Chopsticks include: - -- Forking live Polkadot SDK-based blockchains for isolated testing. -- Simulating cross-chain messages in a private, controlled setup. -- Debugging network behavior by interacting with the fork in real-time. - -Chopsticks provides a controlled environment for developers to safely explore the effects of runtime changes. It ensures that network behavior is tested and verified before upgrades are deployed to live networks. - - ---- - -Page Title: Node and Runtime - -- Source (raw): https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/reference-parachains-node-and-runtime.md -- Canonical (HTML): https://docs.polkadot.com/reference/parachains/node-and-runtime/ -- Summary: Learn how Polkadot SDK-based nodes function, how the client and runtime are separated, and how they communicate using SCALE-encoded data. - -# Node and Runtime - -## Introduction - -Every blockchain platform relies on a decentralized network of computers, called nodes, that communicate with each other about transactions and blocks. In this context, a node refers to the software running on the connected devices rather than the physical or virtual machines in the network. - -Polkadot SDK-based nodes consist of two main components, each with distinct responsibilities: the client (also called node) and the runtime. - -If the system were a monolithic protocol, any modification would require updating the entire system. Instead, Polkadot achieves true upgradeability by defining an immutable meta-protocol (the client) and a protocol (the runtime) that can be upgraded independently. - -This separation gives the [Polkadot Relay Chain](/polkadot-protocol/architecture/polkadot-chain){target=\_blank} and all connected [parachains](/polkadot-protocol/architecture/parachains){target=\_blank} an evolutionary advantage over other blockchain platforms. - -## Architectural Principles - -The Polkadot SDK-based blockchain architecture is fundamentally built on two distinct yet interconnected components: - -- Client (Meta-protocol): - - Handles the foundational infrastructure of the blockchain. - - Manages runtime execution, networking, consensus, and other off-chain components. - - Provides an immutable base layer that ensures network stability. - - Upgradable only through hard forks. - -- Runtime (Protocol): - - Defines the blockchain's state transition logic. - - Determines the specific rules and behaviors of the blockchain. - - Compiled to WebAssembly (Wasm) for platform-independent execution. - - Capable of being upgraded without network-wide forking. - -### Advantages of this Architecture - -- **Forkless upgrades**: Runtime can be updated without disrupting the entire network. -- **Modularity**: Clear separation allows independent development of client and runtime. -- **Flexibility**: Enables rapid iteration and evolution of blockchain logic. -- **Performance**: WebAssembly compilation provides efficient, cross-platform execution. - -## Node (Client) - -The node, also known as the client, is the core component responsible for executing the Wasm runtime and orchestrating various essential blockchain components. It ensures the correct execution of the state transition function and manages multiple critical subsystems, including: - -- **Wasm execution**: Runs the blockchain runtime, which defines the state transition rules. -- **Database management**: Stores blockchain data. -- **Networking**: Facilitates peer-to-peer communication, block propagation, and transaction gossiping. -- **Transaction pool (Mempool)**: Manages pending transactions before they are included in a block. -- **Consensus mechanism**: Ensures agreement on the blockchain state across nodes. -- **RPC services**: Provides external interfaces for applications and users to interact with the node. - -## Runtime - -The runtime is more than just a set of rules. It's the fundamental logic engine that defines a blockchain's entire behavior. In Polkadot SDK-based blockchains, the runtime represents a complete, self-contained description of the blockchain's state transition function. - -### Characteristics - -The runtime is distinguished by three key characteristics: - -- **Business logic**: Defines the complete application-specific blockchain behavior. -- **WebAssembly compilation**: Ensures platform-independent, secure execution. -- **On-chain storage**: Stored within the blockchain's state, allowing dynamic updates. - -### Key Functions - -The runtime performs several critical functions, such as: - -- Define state transition rules. -- Implement blockchain-specific logic. -- Manage account interactions. -- Control transaction processing. -- Define governance mechanisms. -- Handle custom pallets and modules. - -## Communication Between Node and Runtime - -The client and runtime communicate exclusively using [SCALE-encoded](/polkadot-protocol/parachain-basics/data-encoding){target=\_blank} communication. This ensures efficient and compact data exchange between the two components. - -### Runtime APIs - -The Runtime API consists of well-defined functions and constants a client assumes are implemented in the Runtime Wasm blob. These APIs enable the client to interact with the runtime to execute blockchain operations and retrieve information. The client invokes these APIs to: - -- Build, execute, and finalize blocks. -- Access metadata. -- Access consensus related information. -- Handle transaction execution. - -### Host Functions - -During execution, the runtime can access certain external client functionalities via host functions. The specific functions the client exposes allow the runtime to perform operations outside the WebAssembly domain. Host functions enable the runtime to: - -- Perform cryptographic operations. -- Access the current blockchain state. -- Handle storage modifications. -- Allocate memory. - - ---- - -Page Title: On-Chain Governance Overview - -- Source (raw): https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/reference-governance.md -- Canonical (HTML): https://docs.polkadot.com/reference/governance/ -- Summary: Discover Polkadot’s cutting-edge OpenGov system, enabling transparent, decentralized decision-making through direct democracy and flexible governance tracks. - -# On-Chain Governance - -## Introduction - -Polkadot’s governance system exemplifies decentralized decision-making, empowering its community of stakeholders to shape the network’s future through active participation. The latest evolution, OpenGov, builds on Polkadot’s foundation by providing a more inclusive and efficient governance model. - -This guide will explain the principles and structure of OpenGov and walk you through its key components, such as Origins, Tracks, and Delegation. You will learn about improvements over earlier governance systems, including streamlined voting processes and enhanced stakeholder participation. - -With OpenGov, Polkadot achieves a flexible, scalable, and democratic governance framework that allows multiple proposals to proceed simultaneously, ensuring the network evolves in alignment with its community's needs. - -## Governance Evolution - -Polkadot’s governance journey began with [Governance V1](https://wiki.polkadot.com/learn/learn-polkadot-opengov/#governance-summary){target=\_blank}, a system that proved effective in managing treasury funds and protocol upgrades. However, it faced limitations, such as: - -- Slow voting cycles, causing delays in decision-making. -- Inflexibility in handling multiple referendums, restricting scalability. - -To address these challenges, Polkadot introduced OpenGov, a governance model designed for greater inclusivity, efficiency, and scalability. OpenGov replaces the centralized structures of Governance V1, such as the Council and Technical Committee, with a fully decentralized and dynamic framework. - -For a full comparison of the historic and current governance models, visit the [Gov1 vs. Polkadot OpenGov](https://wiki.polkadot.com/learn/learn-polkadot-opengov/#gov1-vs-polkadot-opengov){target=\_blank} section of the Polkadot Wiki. - -## OpenGov Key Features - -OpenGov transforms Polkadot’s governance into a decentralized, stakeholder-driven model, eliminating centralized decision-making bodies like the Council. Key enhancements include: - -- **Decentralization**: Shifts all decision-making power to the public, ensuring a more democratic process. -- **Enhanced delegation**: Allows users to delegate their votes to trusted experts across specific governance tracks. -- **Simultaneous referendums**: Multiple proposals can progress at once, enabling faster decision-making. -- **Polkadot Technical Fellowship**: A broad, community-driven group replacing the centralized Technical Committee. - -This new system ensures Polkadot governance remains agile and inclusive, even as the ecosystem grows. - -## Origins and Tracks - -In OpenGov, origins and tracks are central to managing proposals and votes. - -- **Origin**: Determines the authority level of a proposal (e.g., Treasury, Root) which decides the track of all referendums from that origin. -- **Track**: Define the procedural flow of a proposal, such as voting duration, approval thresholds, and enactment timelines. - -Developers must be aware that referendums from different origins and tracks will take varying amounts of time to reach approval and enactment. The [Polkadot Technical Fellowship](https://wiki.polkadot.com/learn/learn-polkadot-technical-fellowship/){target=\_blank} has the option to shorten this timeline by whitelisting a proposal and allowing it to be enacted through the [Whitelist Caller](https://wiki.polkadot.com/learn/learn-polkadot-opengov-origins/#whitelisted-caller){target=\_blank} origin. - -Visit [Origins and Tracks Info](https://wiki.polkadot.com/learn/learn-polkadot-opengov/#origins-and-tracks){target=\_blank} for details on current origins and tracks, associated terminology, and parameters. - -## Referendums - -In OpenGov, anyone can submit a referendum, fostering an open and participatory system. The timeline for a referendum depends on the privilege level of the origin with more significant changes offering more time for community voting and participation before enactment. - -The timeline for an individual referendum includes four distinct periods: - -- **Lead-in**: A minimum amount of time to allow for community participation, available room in the origin, and payment of the decision deposit. Voting is open during this period. -- **Decision**: Voting continues. -- **Confirmation**: Referendum must meet [approval and support](https://wiki.polkadot.com/learn/learn-polkadot-opengov/#approval-and-support){target=\_blank} criteria during entire period to avoid rejection. -- **Enactment**: Changes approved by the referendum are executed. - -### Vote on Referendums - -Voters can vote with their tokens on each referendum. Polkadot uses a voluntary token locking mechanism, called conviction voting, as a way for voters to increase their voting power. A token holder signals they have a stronger preference for approving a proposal based upon their willingness to lock up tokens. Longer voluntary token locks are seen as a signal of continual approval and translate to increased voting weight. - -See [Voting on a Referendum](https://wiki.polkadot.com/learn/learn-polkadot-opengov/#voting-on-a-referendum){target=\_blank} for a deeper look at conviction voting and related token locks. - -### Delegate Voting Power - -The OpenGov system also supports multi-role delegations, allowing token holders to assign their voting power on different tracks to entities with expertise in those areas. - -For example, if a token holder lacks the technical knowledge to evaluate proposals on the [Root track](https://wiki.polkadot.com/learn/learn-polkadot-opengov-origins/#root){target=\_blank}, they can delegate their voting power for that track to an expert they trust to vote in the best interest of the network. This ensures informed decision-making across tracks while maintaining flexibility for token holders. - -Visit [Multirole Delegation](https://wiki.polkadot.com/learn/learn-polkadot-opengov/#multirole-delegation){target=\_blank} for more details on delegating voting power. - -### Cancel a Referendum - -Polkadot OpenGov has two origins for rejecting ongoing referendums: - -- [**Referendum Canceller**](https://wiki.polkadot.com/learn/learn-polkadot-opengov-origins/#referendum-canceller){target=\_blank}: Cancels an active referendum when non-malicious errors occur and refunds the deposits to the originators. -- [**Referendum Killer**](https://wiki.polkadot.com/learn/learn-polkadot-opengov-origins/#referendum-killer){target=\_blank}: Used for urgent, malicious cases this origin instantly terminates an active referendum and slashes deposits. - -See [Cancelling, Killing, and Blacklisting](https://wiki.polkadot.com/learn/learn-polkadot-opengov/#cancelling-killing--blacklisting){target=\_blank} for additional information on rejecting referendums. - -## Additional Resources - -- **[Democracy pallet](https://github.com/paritytech/polkadot-sdk/tree/polkadot-stable2506-2/substrate/frame/democracy/src){target=\_blank}**: Handles administration of general stakeholder voting. -- **[Gov2: Polkadot’s Next Generation of Decentralised Governance](https://medium.com/polkadot-network/gov2-polkadots-next-generation-of-decentralised-governance-4d9ef657d11b){target=\_blank}**: Medium article by Gavin Wood. -- **[Polkadot Direction](https://matrix.to/#/#Polkadot-Direction:parity.io){target=\_blank}**: Matrix Element client. -- **[Polkassembly](https://polkadot.polkassembly.io/){target=\_blank}**: OpenGov dashboard and UI. -- **[Polkadot.js Apps Governance](https://polkadot.js.org/apps/#/referenda){target=\_blank}**: Overview of active referendums. - - ---- - -Page Title: Origins and Tracks - -- Source (raw): https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/reference-governance-origins-tracks.md -- Canonical (HTML): https://docs.polkadot.com/reference/governance/origins-tracks/ -- Summary: Explore Polkadot's OpenGov origins and tracks system, defining privilege levels, decision processes, and tailored pathways for network proposals. - -# Origins and Tracks - -## Introduction - -Polkadot's OpenGov system empowers decentralized decision-making and active community participation by tailoring the governance process to the impact of proposed changes. Through a system of origins and tracks, OpenGov ensures that every referendum receives the appropriate scrutiny, balancing security, inclusivity, and efficiency. - -This guide will help you understand the role of origins in classifying proposals by privilege and priority. You will learn how tracks guide proposals through tailored stages like voting, confirmation, and enactment and how to select the correct origin for your referendum to align with community expectations and network governance. - -Origins and tracks are vital in streamlining the governance workflow and maintaining Polkadot's resilience and adaptability. - -## Origins - -Origins are the foundation of Polkadot's OpenGov governance system. They categorize proposals by privilege and define their decision-making rules. Each origin corresponds to a specific level of importance and risk, guiding how referendums progress through the governance process. - -- High-privilege origins like Root Origin govern critical network changes, such as core software upgrades. -- Lower-privilege origins like Small Spender handle minor requests, such as community project funding under 10,000 DOT. - -Proposers select an origin based on the nature of their referendum. Origins determine parameters like approval thresholds, required deposits, and timeframes for voting and confirmation. Each origin is paired with a track, which acts as a roadmap for the proposal's lifecycle, including preparation, voting, and enactment. - -For a detailed list of origins and their associated parameters, see the [Polkadot OpenGov Origins](https://wiki.polkadot.com/learn/learn-polkadot-opengov-origins/){target=\_blank} entry in the Polkadot Wiki. - -## Tracks - -Tracks define a referendum's journey from submission to enactment, tailoring governance parameters to the impact of proposed changes. Each track operates independently and includes several key stages: - -- **Preparation**: Time for community discussion before voting begins. -- **Voting**: Period for token holders to cast their votes. -- **Decision**: Finalization of results and determination of the proposal's outcome. -- **Confirmation**: Period to verify sustained community support before enactment. -- **Enactment**: Final waiting period before the proposal takes effect. - -Tracks customize these stages with parameters like decision deposit requirements, voting durations, and approval thresholds, ensuring proposals from each origin receive the required scrutiny and process. For example, a runtime upgrade in the Root Origin track will have longer timeframes and stricter thresholds than a treasury request in the Small Spender track. - -## Additional Resources - -- For a list of origins and tracks for Polkadot and Kusama, including associated parameters, see the [Origins and Tracks Info](https://wiki.polkadot.com/learn/learn-polkadot-opengov-origins/#origins-and-tracks-info){target=\_blank} entry in the Polkadot Wiki. - -- For a deeper dive into the approval and support system, see the [Approval and Support](https://wiki.polkadot.com/learn/learn-polkadot-opengov/#approval-and-support){target=\_blank} entry of the Polkadot Wiki. - - --- Page Title: Overview of FRAME @@ -3741,1316 +2825,102 @@ This section covers the most common customization patterns you'll encounter: --- -Page Title: Overview of the Polkadot Relay Chain +Page Title: Set Up the Polkadot SDK Parachain Template -- Source (raw): https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/reference-polkadot-hub-consensus-and-security-relay-chain.md -- Canonical (HTML): https://docs.polkadot.com/reference/polkadot-hub/consensus-and-security/relay-chain/ -- Summary: Explore Polkadot's core architecture, including its multi-chain vision, shared security, and the DOT token's governance and staking roles. +- Source (raw): https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/parachains-launch-a-parachain-set-up-the-parachain-template.md +- Canonical (HTML): https://docs.polkadot.com/parachains/launch-a-parachain/set-up-the-parachain-template/ +- Summary: Learn how to set up and run the Polkadot SDK Parachain Template locally, creating a ready-to-customize foundation for your parachain. -# Overview +# Set Up the Polkadot SDK Parachain Template ## Introduction -Polkadot is a next-generation blockchain protocol designed to support a multi-chain future by enabling secure communication and interoperability between different blockchains. Built as a Layer-0 protocol, Polkadot introduces innovations like application-specific Layer-1 chains ([parachains](/polkadot-protocol/architecture/parachains/){targe=\_blank}), shared security through [Nominated Proof of Stake (NPoS)](/reference/glossary/#nominated-proof-of-stake-npos){target=\_blank}, and cross-chain interactions via its native [Cross-Consensus Messaging Format (XCM)](/parachains/interoperability/get-started/){target=\_blank}. - -This guide covers key aspects of Polkadot’s architecture, including its high-level protocol structure, blockspace commoditization, and the role of its native token, DOT, in governance, staking, and resource allocation. - -## Polkadot 1.0 - -Polkadot 1.0 represents the state of Polkadot as of 2023, coinciding with the release of [Polkadot runtime v1.0.0](https://github.com/paritytech/polkadot/releases/tag/v1.0.0){target=\_blank}. This section will focus on Polkadot 1.0, along with philosophical insights into network resilience and blockspace. - -As a Layer-0 blockchain, Polkadot contributes to the multi-chain vision through several key innovations and initiatives, including: +The [Polkadot SDK](https://github.com/paritytech/polkadot-sdk){target=\_blank} includes several [templates](/parachains/customize-runtime/#starting-templates){target=\_blank} designed to help you quickly start building your own blockchain. Each template offers a different level of configuration, from minimal setups to feature-rich environments, allowing you to choose the foundation that best fits your project's needs. -- **Application-specific Layer-1 blockchains (parachains)**: Polkadot's sharded network allows for parallel transaction processing, with shards that can have unique state transition functions, enabling custom-built L1 chains optimized for specific applications. +Among these, the [Parachain Template](https://github.com/paritytech/polkadot-sdk-parachain-template){target=\_blank} provides a preconfigured runtime with commonly used pallets, making it an ideal starting point for most parachain development projects. -- **Shared security and scalability**: L1 chains connected to Polkadot benefit from its [Nominated Proof of Stake (NPoS)](/reference/polkadot-hub/consensus-and-security/pos-consensus/#nominated-proof-of-stake){target=\_blank} system, providing security out-of-the-box without the need to bootstrap their own. +This guide walks you through the full process of working with this template. You will: -- **Secure interoperability**: Polkadot's native interoperability enables seamless data and value exchange between parachains. This interoperability can also be used outside of the ecosystem for bridging with external networks. +- Set up the Polkadot SDK Parachain Template. +- Understand the project structure and key components. +- Verify your template is ready for development. +- Run the parachain template locally in development mode. -- **Resilient infrastructure**: Decentralized and scalable, Polkadot ensures ongoing support for development and community initiatives via its on-chain [treasury](https://wiki.polkadot.com/learn/learn-polkadot-opengov-treasury/){target=\_blank} and governance. +By the end of this guide, you'll have a working template ready to customize and deploy as a parachain. -- **Rapid L1 development**: The [Polkadot SDK](/reference/parachains/){target=\_blank} allows fast, flexible creation and deployment of Layer-1 chains. +## Prerequisites -- **Cultivating the next generation of Web3 developers**: Polkadot supports the growth of Web3 core developers through initiatives such as. +Before getting started, ensure you have done the following: - - [Polkadot Blockchain Academy](https://polkadot.com/blockchain-academy){target=\_blank} - - [EdX courses](https://www.edx.org/school/web3x){target=\_blank} - - Rust and Substrate courses (coming soon) +- Completed the [Install Polkadot SDK](/parachains/install-polkadot-sdk/){target=\_blank} guide and successfully installed [Rust](https://www.rust-lang.org/){target=\_blank} and the required packages to set up your development environment. -### High-Level Architecture +For this tutorial series, you need to use Rust `1.86`. Newer versions of the compiler may not work with this parachain template version. -Polkadot features a chain that serves as the central component of the system. This chain is depicted as a ring encircled by several parachains that are connected to it. +Run the following commands to set up the correct Rust version: -According to Polkadot's design, any blockchain that can compile to WebAssembly (Wasm) and adheres to the Parachains Protocol becomes a parachain on the Polkadot network. +=== "macOS" -Here’s a high-level overview of the Polkadot protocol architecture: + ```bash + rustup install 1.86 + rustup default 1.86 + rustup target add wasm32-unknown-unknown --toolchain 1.86-aarch64-apple-darwin + rustup component add rust-src --toolchain 1.86-aarch64-apple-darwin + ``` -![](/images/reference/polkadot-hub/consensus-and-security/relay-chain/relay-chain-01.webp){ style="background:white" } +=== "Ubuntu" -Parachains propose blocks to Polkadot validators, who check for availability and validity before finalizing them. With the relay chain providing security, collators—full nodes of parachains—can focus on their tasks without needing strong incentives. + ```bash + rustup toolchain install 1.86.0 + rustup default 1.86.0 + rustup target add wasm32-unknown-unknown --toolchain 1.86.0 + rustup component add rust-src --toolchain 1.86.0 + ``` -The [Cross-Consensus Messaging Format (XCM)](/parachains/interoperability/get-started/){target=\_blank} allows parachains to exchange messages freely, leveraging the chain's security for trust-free communication. +## Polkadot SDK Utility Tools -In order to interact with chains that want to use their own finalization process (e.g., Bitcoin), Polkadot has [bridges](/reference/parachains/interoperability/#bridges-connecting-external-networks){target=\_blank} that offer two-way compatibility, meaning that transactions can be made between different parachains. +This tutorial requires two essential tools: -### Polkadot's Additional Functionalities +- [**Chain spec builder**](https://crates.io/crates/staging-chain-spec-builder/10.0.0){target=\_blank}: A Polkadot SDK utility for generating chain specifications. Refer to the [Generate Chain Specs](/parachains/launch-a-parachain/deploy-to-polkadot/#generate-the-chain-specification){target=\_blank} documentation for detailed usage. + + Install it by executing the following command: + + ```bash + cargo install --locked staging-chain-spec-builder@10.0.0 + ``` -Historically, obtaining core slots on Polkadot chain relied upon crowdloans and auctions. Chain cores were leased through auctions for three-month periods, up to a maximum of two years. Crowdloans enabled users to securely lend funds to teams for lease deposits in exchange for pre-sale tokens, which is the only way to access slots on Polkadot 1.0. Auctions are now deprecated in favor of [coretime](/polkadot-protocol/architecture/system-chains/coretime/){target=\_blank}. + This command installs the `chain-spec-builder` binary. -Additionally, the chain handles [staking](https://wiki.polkadot.com/learn/learn-staking/){target=\_blank}, [accounts](/reference/parachains/accounts/){target=\_blank}, balances, and [governance](/reference/governance/){target=\_blank}. +- [**Polkadot Omni Node**](https://crates.io/crates/polkadot-omni-node/0.5.0){target=\_blank}: A white-labeled binary, released as a part of Polkadot SDK that can act as the collator of a parachain in production, with all the related auxiliary functionalities that a normal collator node has: RPC server, archiving state, etc. Moreover, it can also run the Wasm blob of the parachain locally for testing and development. -#### Agile Coretime + To install it, run the following command: -The new and more efficient way of obtaining core on Polkadot is to go through the process of purchasing coretime. + ```bash + cargo install --locked polkadot-omni-node@0.5.0 + ``` -[Agile coretime](/reference/polkadot-hub/consensus-and-security/agile-coretime/){target=\_blank} improves the efficient use of Polkadot's network resources and offers economic flexibility for developers, extending Polkadot's capabilities far beyond the original vision outlined in the [whitepaper](https://polkadot.com/papers/Polkadot-whitepaper.pdf){target=\_blank}. + This command installs the `polkadot-omni-node` binary. -It enables parachains to purchase monthly "bulk" allocations of coretime (the time allocated for utilizing a core, measured in Polkadot relay chain blocks), ensuring heavy-duty parachains that can author a block every six seconds with [Asynchronous Backing](https://wiki.polkadot.com/learn/learn-async-backing/#asynchronous-backing){target=\_blank} can reliably renew their coretime each month. Although six-second block times are now the default, parachains have the option of producing blocks less frequently. +## Clone the Template -Renewal orders are prioritized over new orders, offering stability against price fluctuations and helping parachains budget more effectively for project costs. +The [Polkadot SDK Parachain Template](https://github.com/paritytech/polkadot-sdk-parachain-template){target=\_blank} provides a ready-to-use development environment for building with the [Polkadot SDK](https://github.com/paritytech/polkadot-sdk){target=\_blank}. Follow these steps to set up the template: -### Polkadot's Resilience +1. Clone the template repository: -Decentralization is a vital component of blockchain networks, but it comes with trade-offs: + ```bash + git clone https://github.com/paritytech/polkadot-sdk-parachain-template.git parachain-template + ``` -- An overly decentralized network may face challenges in reaching consensus and require significant energy to operate. -- Also, a network that achieves consensus quickly risks centralization, making it easier to manipulate or attack. +2. Navigate into the project directory: -A network should be decentralized enough to prevent manipulative or malicious influence. In this sense, decentralization is a tool for achieving resilience. + ```bash + cd parachain-template + ``` -Polkadot 1.0 currently achieves resilience through several strategies: +## Explore the Project Structure -- **Nominated Proof of Stake (NPoS)**: Ensures that the stake per validator is maximized and evenly distributed among validators. +Before building the template, take a moment to familiarize yourself with its structure. Understanding this organization will help you navigate the codebase as you develop your parachain. -- **Decentralized nodes**: Designed to encourage operators to join the network. This program aims to expand and diversify the validators in the ecosystem who aim to become independent of the program during their term. Feel free to explore more about the program on the official [Decentralized Nodes](https://nodes.web3.foundation/){target=\_blank} page. - -- **On-chain treasury and governance**: Known as [OpenGov](/reference/governance/){target=\_blank}, this system allows every decision to be made through public referenda, enabling any token holder to cast a vote. - -### Polkadot's Blockspace - -Polkadot 1.0’s design allows for the commoditization of blockspace. - -Blockspace is a blockchain's capacity to finalize and commit operations, encompassing its security, computing, and storage capabilities. Its characteristics can vary across different blockchains, affecting security, flexibility, and availability. - -- **Security**: Measures the robustness of blockspace in Proof of Stake (PoS) networks linked to the stake locked on validator nodes, the variance in stake among validators, and the total number of validators. It also considers social centralization (how many validators are owned by single operators) and physical centralization (how many validators run on the same service provider). - -- **Flexibility**: Reflects the functionalities and types of data that can be stored, with high-quality data essential to avoid bottlenecks in critical processes. - -- **Availability**: Indicates how easily users can access blockspace. It should be easily accessible, allowing diverse business models to thrive, ideally regulated by a marketplace based on demand and supplemented by options for "second-hand" blockspace. - -Polkadot is built on core blockspace principles, but there's room for improvement. Tasks like balance transfers, staking, and governance are managed on the relay chain. - -Delegating these responsibilities to [system chains](/polkadot-protocol/architecture/system-chains/){target=\_blank} could enhance flexibility and allow the relay chain to concentrate on providing shared security and interoperability. - -For more information about blockspace, watch [Robert Habermeier’s interview](https://www.youtube.com/watch?v=e1vISppPwe4){target=\_blank} or read his [technical blog post](https://www.rob.tech/blog/polkadot-blockspace-over-blockchains/){target=\_blank}. - -## DOT Token - -DOT is the native token of the Polkadot network, much like BTC for Bitcoin and Ether for the Ethereum blockchain. DOT has 10 decimals, uses the Planck base unit, and has a balance type of `u128`. The same is true for Kusama's KSM token with the exception of having 12 decimals. - -### Redenomination of DOT - -Polkadot conducted a community poll, which ended on 27 July 2020 at block 888,888, to decide whether to redenominate the DOT token. The stakeholders chose to redenominate the token, changing the value of 1 DOT from 1e12 plancks to 1e10 plancks. - -Importantly, this did not affect the network's total number of base units (plancks); it only affects how a single DOT is represented. The redenomination became effective 72 hours after transfers were enabled, occurring at block 1,248,328 on 21 August 2020 around 16:50 UTC. - -### The Planck Unit - -The smallest unit of account balance on Polkadot SDK-based blockchains (such as Polkadot and Kusama) is called _Planck_, named after the Planck length, the smallest measurable distance in the physical universe. - -Similar to how BTC's smallest unit is the Satoshi and ETH's is the Wei, Polkadot's native token DOT equals 1e10 Planck, while Kusama's native token KSM equals 1e12 Planck. - -### Uses for DOT - -DOT serves three primary functions within the Polkadot network: - -- **Governance**: It is used to participate in the governance of the network. -- **Staking**: DOT is staked to support the network's operation and security. -- **Buying coretime**: Used to purchase coretime in-bulk or on-demand and access the chain to benefit from Polkadot's security and interoperability. - -Additionally, DOT can serve as a transferable token. For example, DOT, held in the treasury, can be allocated to teams developing projects that benefit the Polkadot ecosystem. - -## JAM and the Road Ahead - -The Join-Accumulate Machine (JAM) represents a transformative redesign of Polkadot's core architecture, envisioned as the successor to the current relay chain. Unlike traditional blockchain architectures, JAM introduces a unique computational model that processes work through two primary functions: - -- **Join**: Handles data integration. -- **Accumulate**: Folds computations into the chain's state. - -JAM removes many of the opinions and constraints of the current relay chain while maintaining its core security properties. Expected improvements include: - -- **Permissionless code execution**: JAM is designed to be more generic and flexible, allowing for permissionless code execution through services that can be deployed without governance approval. -- **More effective block time utilization**: JAM's efficient pipeline processing model places the prior state root in block headers instead of the posterior state root, enabling more effective utilization of block time for computations. - -This architectural evolution promises to enhance Polkadot's scalability and flexibility while maintaining robust security guarantees. JAM is planned to be rolled out to Polkadot as a single, complete upgrade rather than a stream of smaller updates. This approach seeks to minimize the developer overhead required to address any breaking changes. - - ---- - -Page Title: Parachain Consensus - -- Source (raw): https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/reference-parachains-consensus-overview.md -- Canonical (HTML): https://docs.polkadot.com/reference/parachains/consensus/overview/ -- Summary: Understand how the blocks authored by parachain collators are secured by the relay chain validators and how the parachain transactions achieve finality. - -# Parachain Consensus - -## Introduction - -Parachains are independent blockchains built with the Polkadot SDK, designed to leverage Polkadot’s relay chain for shared security and transaction finality. These specialized chains operate as part of Polkadot’s execution sharding model, where each parachain manages its own state and transactions while relying on the relay chain for validation and consensus. - -At the core of parachain functionality are collators, specialized nodes that sequence transactions into blocks and maintain the parachain’s state. Collators optimize Polkadot’s architecture by offloading state management from the relay chain, allowing relay chain validators to focus solely on validating parachain blocks. - -This guide explores how parachain consensus works, including the roles of collators and validators, and the steps involved in securing parachain blocks within Polkadot’s scalable and decentralized framework. - -## The Role of Collators - -Collators are responsible for sequencing end-user transactions into blocks and maintaining the current state of their respective parachains. Their role is akin to Ethereum’s sequencers but optimized for Polkadot's architecture. - -Key responsibilities include: - -- **Transaction sequencing**: Organizing transactions into [Proof of Validity (PoV)](https://wiki.polkadot.com/general/glossary/#proof-of-validity){target=\_blank} blocks. -- **State management**: Maintaining parachain states without burdening the relay chain validators. -- **Consensus participation**: Sending PoV blocks to relay chain validators for approval. - -## Consensus and Validation - -Parachain consensus operates in tandem with the relay chain, leveraging [Nominated Proof of Stake (NPoS)](/reference/glossary/#nominated-proof-of-stake-npos){target=\_blank} for shared security. The process ensures parachain transactions achieve finality through the following steps: - -1. **Packaging transactions**: Collators bundle transactions into PoV blocks (parablocks). -2. **Submission to validator**: Parablocks are submitted to a randomly selected subset of relay chain validators, known as paravalidators. -3. **Validation of PoV Blocks**: Paravalidators use the parachain’s state transition function (already available on the relay chain) to verify transaction validity. -4. **Backing and inclusion**: If a sufficient number of positive validations are received, the parablock is backed and included via a para-header on the relay chain. - -The following sections describe the actions taking place during each stage of the process. - -### Path of a Parachain Block - -Polkadot achieves scalability through execution sharding, where each parachain operates as an independent shard with its own blockchain and state. Shared security for all parachains is provided by the relay chain, powered by Nominated Proof of Stake (NPoS). This framework allows parachains to focus on transaction processing and state management, while the relay chain ensures validation and finality. - -The journey of parachain transactions to reach consensus and finality can be described as follows: - -- Collators and parablocks: - - - Collators, specialized nodes on parachains, package transactions into Proof of Validity (PoV) blocks, also called parablocks. - - These parablocks are sent to a subset of relay chain validators, known as paravalidators, for validation. - - The parachain's state transition function (Wasm blob) is not re-sent, as it is already stored on the relay chain. - -```mermaid -flowchart TB - %% Subgraph: Parachain - subgraph Parachain - direction LR - Txs[Network Transactions] - Collator[Collator Node] - ParaBlock[ParaBlock + PoV] - Txs -->|Package Transactions| Collator - Collator -->|Create| ParaBlock - end - - subgraph Relay["Relay Chain"] - ParaValidator - end - - %% Main Flow - Parachain -->|Submit To| Relay -``` - -- Validation by paravalidators: - - - Paravalidators are groups of approximately five relay chain validators, randomly assigned to parachains and shuffled every minute. - - Each paravalidator downloads the parachain's Wasm blob and validates the parablock by ensuring all transactions comply with the parachain’s state transition rules. - - Paravalidators sign positive or negative validation statements based on the block’s validity. - -- Backing and approval: - - - If a parablock receives sufficient positive validation statements, it is backed and included on the relay chain as a para-header. - - An additional approval process resolves disputes. If a parablock contains invalid transactions, additional validators are tasked with verification. - - Validators who back invalid parablocks are penalized through slashing, creating strong incentives for honest behavior. - -```mermaid -flowchart - subgraph RelayChain["Relay Chain"] - direction TB - subgraph InitialValidation["Initial Validation"] - direction LR - PValidators[ParaValidators] - Backing[Backing
Process] - Header[Submit Para-header
on Relay Chain] - end - subgraph Secondary["Secondary Validation"] - Approval[Approval
Process] - Dispute[Dispute
Resolution] - Slashing[Slashing
Mechanism] - end - - end - - - %% Validation Process - PValidators -->|Download
Wasm
Validate Block| Backing - Backing -->|If Valid
Signatures| Header - InitialValidation -->|Additional
Verification| Secondary - - %% Dispute Flow - Approval -->|If Invalid
Detected| Dispute - Dispute -->|Penalize
Dishonest
Validators| Slashing -``` - -It is important to understand that relay chain blocks do not store full parachain blocks (parablocks). Instead, they include para-headers, which serve as summaries of the backed parablocks. The complete parablock remains within the parachain network, maintaining its autonomy while relying on the relay chain for validation and finality. - - -## Where to Go Next - -Explore more about Parachain consensus through these resources: - -
- -- Learn __Elastic Scaling__ - - --- - - Learn more about how Elastic Scaling boosts parachain performance. - - [:octicons-arrow-right-24: Elastic Scaling](/reference/parachains/consensus/elastic-scaling/){target=\_blank} - -- Learn __Asynchronous Backing__ - - --- - - Read about pipelining parachain block production via Async Backing. - - [:octicons-arrow-right-24: Asynchronous Backing](/reference/parachains/consensus/async-backing/){target=\_blank} - - - -- Learn __Parachain Wiki__ - - --- - - Explore more on Parachains in the Wiki. - - [:octicons-arrow-right-24: Parachains](https://wiki.polkadot.com/learn/learn-parachains/){target=\_blank} - - - -
- - ---- - -Page Title: Parachains Overview - -- Source (raw): https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/reference-parachains.md -- Canonical (HTML): https://docs.polkadot.com/reference/parachains/ -- Summary: Learn about parachains, specialized blockchains on Polkadot that gain shared security and interoperability. Discover how they work and the tools to build them. - -# Parachains Overview - -## Introduction - -A parachain is a specialized blockchain that connects to the Polkadot relay chain, benefiting from shared security, interoperability, and scalability. Parachains are built using the [Polkadot SDK](https://github.com/paritytech/polkadot-sdk){target=\_blank}, a powerful toolkit written in Rust that provides everything needed to create custom blockchain logic while integrating seamlessly with the Polkadot network. - -Unlike standalone blockchains that must bootstrap their own validator sets and security, parachains leverage Polkadot's pooled security model. This allows parachain developers to focus on their application-specific functionality rather than consensus and security infrastructure. Parachains can communicate with each other through Cross-Consensus Messaging (XCM), enabling seamless interoperability across the Polkadot ecosystem. - -Key capabilities that parachains provide include: - -- **Shared security**: Inherit security from Polkadot's validator set without maintaining your own. -- **Interoperability**: Communicate trustlessly with other parachains via XCM. -- **Scalability**: Process transactions in parallel with other parachains. -- **Customization**: Build application-specific logic tailored to your use case. -- **Upgradeability**: Upgrade runtime logic without hard forks. - -## Polkadot SDK: Parachain Architecture - -Building a parachain involves understanding and utilizing several key components of the Polkadot SDK: - -![](/images/reference/parachains/index/overview-01.webp) - -- **[Substrate](https://paritytech.github.io/polkadot-sdk/master/polkadot_sdk_docs/polkadot_sdk/substrate/index.html){target=\_blank}**: The foundation providing core blockchain primitives and libraries. -- **[FRAME](https://paritytech.github.io/polkadot-sdk/master/polkadot_sdk_docs/polkadot_sdk/frame_runtime/index.html){target=\_blank}**: A modular framework for building your parachain's runtime logic. -- **[Cumulus](https://paritytech.github.io/polkadot-sdk/master/polkadot_sdk_docs/polkadot_sdk/cumulus/index.html){target=\_blank}**: Essential libraries and pallets that enable parachain functionality. -- **[XCM (Cross Consensus Messaging)](https://paritytech.github.io/polkadot-sdk/master/polkadot_sdk_docs/polkadot_sdk/xcm/index.html){target=\_blank}**: The messaging format for communicating with other parachains and the relay chain. -- **[Polkadot](https://paritytech.github.io/polkadot-sdk/master/polkadot_sdk_docs/polkadot_sdk/polkadot/index.html){target=\_blank}**: The relay chain that provides security and coordination. - -### Substrate: The Foundation - -Substrate provides the core infrastructure that every parachain is built upon. It handles the low-level blockchain functionality, allowing you to focus on your application's unique features. Substrate includes implementations for networking, database management, consensus participation, and the execution environment for your runtime. - -Every Polkadot SDK node consists of two main components: - -- **Client (Host)**: Handles infrastructure services. - - - Native binary that runs on validator and collator nodes. - - Executes the Wasm-compiled runtime. - - Manages networking, database, mempool, and block production. - - Interfaces with the relay chain for validation. - -- **Runtime (State Transition Function)**: Contains your business logic. - - - Defines how your Polkadot SDK node processes transactions. - - Compiled to [Wasm](https://webassembly.org/){target=\_blank} for deterministic execution. - - Stored on-chain and upgradeable via governance. - -```mermaid -%%{init: {'flowchart': {'padding': 5, 'nodeSpacing': 50, 'rankSpacing': 10}}}%% -graph TB - classDef title font-size:20px,font-weight:bold,stroke-width:0px - classDef clientStyle font-size:16px,font-weight:bold - classDef clientSubNodeStyle margin-top:10px - classDef runtimeCallExecutorStyle padding-top:10px - - subgraph sg1[Parachain
Node] - direction TB - - I[RuntimeCall Executor] - B[Wasm Runtime - STF] - - subgraph sg2[Client] - direction TB - C[Network and Blockchain
Infrastructure Services
+ Relay Chain Interface] - end - - I --> B - end - - class sg1 title - class sg2 clientStyle - class C clientSubNodeStyle - class I runtimeCallExecutorStyle - -``` - -### FRAME: Building Blocks for Your Runtime - -FRAME provides modular components called [pallets](/reference/glossary#pallet){target=\_blank} that you can compose to build your parachain's runtime. Each pallet provides specific functionality that you can customize and configure for your needs. This modular approach allows you to quickly assemble complex functionality without writing everything from scratch. - -```mermaid -graph LR - subgraph SP["Parachain Runtime"] - direction LR - Timestamp ~~~ Aura ~~~ ParachainSystem - Balances ~~~ TransactionPayment ~~~ Sudo - subgraph Timestamp["Timestamp"] - SS1[Custom Config] - end - subgraph Aura["Aura"] - SS2[Custom Config] - end - subgraph ParachainSystem["Parachain System"] - SS3[Custom Config] - end - subgraph Balances["Balances"] - SS4[Custom Config] - end - subgraph TransactionPayment["Transaction Payment"] - SS5[Custom Config] - end - subgraph Sudo["Sudo"] - SS6[Custom Config] - end - style Timestamp stroke:#FF69B4 - style Aura stroke:#FF69B4 - style ParachainSystem stroke:#FF69B4 - style Balances stroke:#FF69B4 - style TransactionPayment stroke:#FF69B4 - style Sudo stroke:#FF69B4 - style SS1 stroke-dasharray: 5 - style SS2 stroke-dasharray: 5 - style SS3 stroke-dasharray: 5 - style SS4 stroke-dasharray: 5 - style SS5 stroke-dasharray: 5 - style SS6 stroke-dasharray: 5 - - end - subgraph AP["Available FRAME Pallets"] - direction LR - A1[Aura]~~~A2[Parachain
System]~~~A3[Transaction
Payment]~~~A4[Sudo] - B1[Identity]~~~B2[Balances]~~~B3[Assets]~~~B4[EVM] - C1[Timestamp]~~~C2[Staking]~~~C3[Contracts]~~~C4[and more...] - end - AP --> SP -``` - -### Cumulus: Parachain-Specific Functionality - -Cumulus is what transforms a Polkadot SDK-based runtime into a parachain-capable runtime. It provides the essential components for communicating with the relay chain, participating in Polkadot's consensus, and handling parachain-specific operations like block validation and collation. - -Key Cumulus components include: - -- **Parachain system pallet**: Core parachain functionality and relay chain communication. -- **Collator consensus**: Block production logic for parachain collators. -- **Relay chain interface**: APIs for interacting with the Polkadot relay chain. -- **Validation data**: Handling proof-of-validity data required by relay chain validators. - -## Where to Go Next - -Building a parachain requires understanding the relationship between your chain and the Polkadot relay chain. The Polkadot SDK provides all the tools needed to design custom runtime logic, enable cross-chain communication, and deploy your parachain to production. - -The following sections provide detailed guidance on each aspect of parachain development, from initial design through deployment and ongoing maintenance. - -
- -- Guide __Launch a Simple Parachain__ - - --- - - Walk through the complete parachain launch flow: from setup and deployment to obtaining coretime. - - [:octicons-arrow-right-24: Deploy](/parachains/launch-a-parachain/set-up-the-parachain-template/) - - -- Guide __Customize Your Runtime__ - - --- - - Design your parachain's runtime logic and choose appropriate pallets for your use case. - - [:octicons-arrow-right-24: Get Started](/parachains/customize-runtime/) - -- Guide __Interoperability__ - - --- - - Implement XCM for trustless cross-chain communication with other parachains. - - [:octicons-arrow-right-24: Learn More](/parachains/interoperability/get-started/) - -- Guide __Runtime Upgrades__ - - --- - - Upgrade your parachain's runtime without hard forks using forkless upgrade mechanisms. - - [:octicons-arrow-right-24: Maintain](/parachains/runtime-maintenance/runtime-upgrades/) - -
- - ---- - -Page Title: People Chain - -- Source (raw): https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/reference-polkadot-hub-people-and-identity.md -- Canonical (HTML): https://docs.polkadot.com/reference/polkadot-hub/people-and-identity/ -- Summary: Learn how People chain secures decentralized identity management, empowering users to control and verify digital identities without central authorities. - -# People Chain - -## Introduction - -People chain is a specialized parachain within the Polkadot ecosystem dedicated to secure, decentralized identity management. - -This solution empowers users to create, control, and verify their digital identities without reliance on centralized authorities. By prioritizing user sovereignty and data privacy, People chain establishes a foundation for trusted interactions throughout the Polkadot ecosystem while returning control of personal information to individuals. - -## Identity Management System - -People chain provides a comprehensive identity framework allowing users to: - -- Establish verifiable on-chain identities. -- Control disclosure of personal information. -- Receive verification from trusted registrars. -- Link multiple accounts under a unified identity. - -Users must reserve funds in a bond to store their information on chain. These funds are locked, not spent, and returned when the identity is cleared. - -### Sub-Identities - -The platform supports hierarchical identity structures through sub-accounts: - -- Primary accounts can establish up to 100 linked sub-accounts. -- Each sub-account maintains its own distinct identity. -- All sub-accounts require a separate bond deposit. - -## Verification Process - -### Judgment Requests - -After establishing an on-chain identity, users can request verification from [registrars](#registrars): - -1. Users specify the maximum fee they're willing to pay for judgment. -2. Only registrars whose fees fall below this threshold can provide verification. -3. Registrars assess the provided information and issue a judgment. - -### Judgment Classifications - -Registrars can assign the following confidence levels to identity information: - -- **Unknown**: Default status; no judgment rendered yet. -- **Reasonable**: Data appears valid but without formal verification (standard for most verified identities). -- **Known good**: Information certified correct through formal verification (requires documentation; limited to registrars). -- **Out of date**: Previously verified information that requires updating. -- **Low quality**: Imprecise information requiring correction. -- **Erroneous**: Incorrect information, potentially indicating fraudulent intent. - -A temporary "Fee Paid" status indicates judgment in progress. Both "Fee Paid" and "Erroneous" statuses lock identity information from modification until resolved. - -### Registrars - -Registrars serve as trusted verification authorities within the People chain ecosystem. These entities validate user identities and provide attestations that build trust in the network. - -- Registrars set specific fees for their verification services. -- They can specialize in verifying particular identity fields. -- Verification costs vary based on complexity and thoroughness. - -When requesting verification, users specify their maximum acceptable fee. Only registrars whose fees fall below this threshold can provide judgment. Upon completing the verification process, the user pays the registrar's fee, and the registrar issues an appropriate confidence level classification based on their assessment. - -Multiple registrars operate across the Polkadot and People chain ecosystems, each with unique specializations and fee structures. To request verification: - -1. Research available registrars and their verification requirements. -2. Contact your chosen registrar directly through their specified channels. -3. Submit required documentation according to their verification process. -4. Pay the associated verification fee. - -You must contact specific registrars individually to request judgment. Each registrar maintains its own verification procedures and communication channels. - -## Where to Go Next - -
- -- External __Polkadot.js Guides about Identity__ - - --- - - Step-by-step instructions for managing identities through the Polkadot.js interface, with practical examples and visual guides. - - [:octicons-arrow-right-24: Reference](https://wiki.polkadot.com/learn/learn-guides-identity/) - -- External __How to Set and Clear an Identity__ - - --- - - Practical walkthrough covering identity setup and removal process on People chain. - - [:octicons-arrow-right-24: Reference](https://support.polkadot.network/support/solutions/articles/65000181981-how-to-set-and-clear-an-identity) - -- External __People Chain Runtime Implementation__ - - --- - - Source code for the People chain runtime, detailing the technical architecture of decentralized identity management. - - [:octicons-arrow-right-24: Reference](https://github.com/polkadot-fellows/runtimes/tree/main/system-parachains/people) - -
- - ---- - -Page Title: Polkadot SDK Accounts - -- Source (raw): https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/reference-parachains-accounts.md -- Canonical (HTML): https://docs.polkadot.com/reference/parachains/accounts/ -- Summary: Learn about account structures, balances, and address formats in the Polkadot SDK, including how to manage lifecycle, references, and balances. - -# Accounts - -## Introduction - -Accounts are essential for managing identity, transactions, and governance on the network in the Polkadot SDK. Understanding these components is critical for seamless development and operation on the network, whether you're building or interacting with Polkadot-based chains. - -This page will guide you through the essential aspects of accounts, including their data structure, balance types, reference counters, and address formats. You’ll learn how accounts are managed within the runtime, how balances are categorized, and how addresses are encoded and validated. - -## Account Data Structure - -Accounts are foundational to any blockchain, and the Polkadot SDK provides a flexible management system. This section explains how the Polkadot SDK defines accounts and manages their lifecycle through data structures within the runtime. - -### Account - -The [`Account` data type](https://paritytech.github.io/polkadot-sdk/master/frame_system/pallet/type.Account.html){target=\_blank} is a storage map within the [System pallet](https://paritytech.github.io/polkadot-sdk/master/src/frame_system/lib.rs.html){target=\_blank} that links an account ID to its corresponding data. This structure is fundamental for mapping account-related information within the chain. - -The code snippet below shows how accounts are defined: - -```rs - /// The full account information for a particular account ID. - #[pallet::storage] - #[pallet::getter(fn account)] - pub type Account = StorageMap< - _, - Blake2_128Concat, - T::AccountId, - AccountInfo, - ValueQuery, - >; -``` - -The preceding code block defines a storage map named `Account`. The `StorageMap` is a type of on-chain storage that maps keys to values. In the `Account` map, the key is an account ID, and the value is the account's information. Here, `T` represents the generic parameter for the runtime configuration, which is defined by the pallet's configuration trait (`Config`). - -The `StorageMap` consists of the following parameters: - -- **`_`**: Used in macro expansion and acts as a placeholder for the storage prefix type. Tells the macro to insert the default prefix during expansion. -- **`Blake2_128Concat`**: The hashing function applied to keys in the storage map. -- **`T: :AccountId`**: Represents the key type, which corresponds to the account’s unique ID. -- **`AccountInfo`**: The value type stored in the map. For each account ID, the map stores an `AccountInfo` struct containing: - - - **`T::Nonce`**: A nonce for the account, which is incremented with each transaction to ensure transaction uniqueness. - - **`T: :AccountData`**: Custom account data defined by the runtime configuration, which could include balances, locked funds, or other relevant information. - -- **`ValueQuery`**: Defines how queries to the storage map behave when no value is found; returns a default value instead of `None`. - -For a detailed explanation of storage maps, see the [`StorageMap`](https://paritytech.github.io/polkadot-sdk/master/frame_support/storage/types/struct.StorageMap.html){target=\_blank} entry in the Rust docs. - -### Account Info - -The `AccountInfo` structure is another key element within the [System pallet](https://paritytech.github.io/polkadot-sdk/master/src/frame_system/lib.rs.html){target=\_blank}, providing more granular details about each account's state. This structure tracks vital data, such as the number of transactions and the account’s relationships with other modules. - -```rs -/// Information of an account. -#[derive(Clone, Eq, PartialEq, Default, RuntimeDebug, Encode, Decode, TypeInfo, MaxEncodedLen)] -pub struct AccountInfo { - /// The number of transactions this account has sent. - pub nonce: Nonce, - /// The number of other modules that currently depend on this account's existence. The account - /// cannot be reaped until this is zero. - pub consumers: RefCount, - /// The number of other modules that allow this account to exist. The account may not be reaped - /// until this and `sufficients` are both zero. - pub providers: RefCount, - /// The number of modules that allow this account to exist for their own purposes only. The - /// account may not be reaped until this and `providers` are both zero. - pub sufficients: RefCount, - /// The additional data that belongs to this account. Used to store the balance(s) in a lot of - /// chains. - pub data: AccountData, -} -``` - -The `AccountInfo` structure includes the following components: - -- **`nonce`**: Tracks the number of transactions initiated by the account, which ensures transaction uniqueness and prevents replay attacks. -- **`consumers`**: Counts how many other modules or pallets rely on this account’s existence. The account cannot be removed from the chain (reaped) until this count reaches zero. -- **`providers`**: Tracks how many modules permit this account’s existence. An account can only be reaped once both `providers` and `sufficients` are zero. -- **`sufficients`**: Represents the number of modules that allow the account to exist for internal purposes, independent of any other modules. -- **`AccountData`**: A flexible data structure that can be customized in the runtime configuration, usually containing balances or other user-specific data. - -This structure helps manage an account's state and prevents its premature removal while it is still referenced by other on-chain data or modules. The [`AccountInfo`](https://paritytech.github.io/polkadot-sdk/master/frame_system/struct.AccountInfo.html){target=\_blank} structure can vary as long as it satisfies the trait bounds defined by the `AccountData` associated type in the [`frame-system::pallet::Config`](https://paritytech.github.io/polkadot-sdk/master/frame_system/pallet/trait.Config.html){target=\_blank} trait. - -### Account Reference Counters - -Polkadot SDK uses reference counters to track an account’s dependencies across different runtime modules. These counters ensure that accounts remain active while data is associated with them. - -The reference counters include: - -- **`consumers`**: Prevents account removal while other pallets still rely on the account. -- **`providers`**: Ensures an account is active before other pallets store data related to it. -- **`sufficients`**: Indicates the account’s independence, ensuring it can exist even without a native token balance, such as when holding sufficient alternative assets. - -#### Providers Reference Counters - -The `providers` counter ensures that an account is ready to be depended upon by other runtime modules. For example, it is incremented when an account has a balance above the existential deposit, which marks the account as active. - -The system requires this reference counter to be greater than zero for the `consumers` counter to be incremented, ensuring the account is stable before any dependencies are added. - -#### Consumers Reference Counters - -The `consumers` counter ensures that the account cannot be reaped until all references to it across the runtime have been removed. This check prevents the accidental deletion of accounts that still have active on-chain data. - -It is the user’s responsibility to clear out any data from other runtime modules if they wish to remove their account and reclaim their existential deposit. - -#### Sufficients Reference Counter - -The `sufficients` counter tracks accounts that can exist independently without relying on a native account balance. This is useful for accounts holding other types of assets, like tokens, without needing a minimum balance in the native token. - -For instance, the [Assets pallet](https://paritytech.github.io/polkadot-sdk/master/pallet_assets/index.html){target=\_blank}, may increment this counter for an account holding sufficient tokens. - -#### Account Deactivation - -In Polkadot SDK-based chains, an account is deactivated when its reference counters (such as `providers`, `consumers`, and `sufficient`) reach zero. These counters ensure the account remains active as long as other runtime modules or pallets reference it. - -When all dependencies are cleared and the counters drop to zero, the account becomes deactivated and may be removed from the chain (reaped). This is particularly important in Polkadot SDK-based blockchains, where accounts with balances below the existential deposit threshold are pruned from storage to conserve state resources. - -Each pallet that references an account has cleanup functions that decrement these counters when the pallet no longer depends on the account. Once these counters reach zero, the account is marked for deactivation. - -#### Updating Counters - -The Polkadot SDK provides runtime developers with various methods to manage account lifecycle events, such as deactivation or incrementing reference counters. These methods ensure that accounts cannot be reaped while still in use. - -The following helper functions manage these counters: - -- **`inc_consumers()`**: Increments the `consumer` reference counter for an account, signaling that another pallet depends on it. -- **`dec_consumers()`**: Decrements the `consumer` reference counter, signaling that a pallet no longer relies on the account. -- **`inc_providers()`**: Increments the `provider` reference counter, ensuring the account remains active. -- **`dec_providers()`**: Decrements the `provider` reference counter, allowing for account deactivation when no longer in use. -- **`inc_sufficients()`**: Increments the `sufficient` reference counter for accounts that hold sufficient assets. -- **`dec_sufficients()`**: Decrements the `sufficient` reference counter. - -To ensure proper account cleanup and lifecycle management, a corresponding decrement should be made for each increment action. - -The `System` pallet offers three query functions to assist developers in tracking account states: - -- **[`can_inc_consumer()`](https://paritytech.github.io/polkadot-sdk/master/frame_system/pallet/struct.Pallet.html#method.can_inc_consumer){target=\_blank}**: Checks if the account can safely increment the consumer reference. -- **[`can_dec_provider()`](https://paritytech.github.io/polkadot-sdk/master/frame_system/pallet/struct.Pallet.html#method.can_dec_provider){target=\_blank}**: Ensures that no consumers exist before allowing the decrement of the provider counter. -- **[`is_provider_required()`](https://paritytech.github.io/polkadot-sdk/master/frame_system/pallet/struct.Pallet.html#method.is_provider_required){target=\_blank}**: Verifies whether the account still has any active consumer references. - -This modular and flexible system of reference counters tightly controls the lifecycle of accounts in Polkadot SDK-based blockchains, preventing the accidental removal or retention of unneeded accounts. You can refer to the [System pallet Rust docs](https://paritytech.github.io/polkadot-sdk/master/frame_system/pallet/struct.Pallet.html){target=\_blank} for more details. - - -## Account Balance Types - -In the Polkadot ecosystem, account balances are categorized into different types based on how the funds are utilized and their availability. These balance types determine the actions that can be performed, such as transferring tokens, paying transaction fees, or participating in governance activities. Understanding these balance types helps developers manage user accounts and implement balance-dependent logic. - -!!! note "A more efficient distribution of account balance types is in development" - Soon, pallets in the Polkadot SDK will implement the [`Fungible` trait](https://paritytech.github.io/polkadot-sdk/master/frame_support/traits/tokens/fungible/index.html){target=\_blank} (see the [tracking issue](https://github.com/paritytech/polkadot-sdk/issues/226){target=\_blank} for more details). For example, the [`transaction-storage`](https://paritytech.github.io/polkadot-sdk/master/pallet_transaction_storage/index.html){target=\_blank} pallet changed the implementation of the [`Currency`](https://paritytech.github.io/polkadot-sdk/master/frame_support/traits/tokens/currency/index.html){target=\_blank} trait (see the [Refactor transaction storage pallet to use fungible traits](https://github.com/paritytech/polkadot-sdk/pull/1800){target=\_blank} PR for further details): - - ```rust - type BalanceOf = <::Currency as Currency<::AccountId>>::Balance; - ``` - - To the [`Fungible`](https://paritytech.github.io/polkadot-sdk/master/frame_support/traits/tokens/fungible/index.html){target=\_blank} trait: - - ```rust - type BalanceOf = <::Currency as FnInspect<::AccountId>>::Balance; - ``` - - This update will enable more efficient use of account balances, allowing the free balance to be utilized for on-chain activities such as setting proxies and managing identities. - -### Balance Types - -The five main balance types are: - -- **Free balance**: Represents the total tokens available to the account for any on-chain activity, including staking, governance, and voting. However, it may not be fully spendable or transferrable if portions of it are locked or reserved. -- **Locked balance**: Portions of the free balance that cannot be spent or transferred because they are tied up in specific activities like [staking](https://wiki.polkadot.com/learn/learn-staking/#nominating-validators){target=\_blank}, [vesting](https://wiki.polkadot.com/learn/learn-guides-transfers/#vested-transfers-with-the-polkadot-js-ui){target=\_blank}, or participating in [governance](https://wiki.polkadot.com/learn/learn-polkadot-opengov/#voting-on-a-referendum){target=\_blank}. While the tokens remain part of the free balance, they are non-transferable for the duration of the lock. -- **Reserved balance**: Funds locked by specific system actions, such as setting up an [identity](https://wiki.polkadot.com/learn/learn-identity/){target=\_blank}, creating [proxies](https://wiki.polkadot.com/learn/learn-proxies/){target=\_blank}, or submitting [deposits for governance proposals](https://wiki.polkadot.com/learn/learn-guides-polkadot-opengov/#claiming-opengov-deposits){target=\_blank}. These tokens are not part of the free balance and cannot be spent unless they are unreserved. -- **Spendable balance**: The portion of the free balance that is available for immediate spending or transfers. It is calculated by subtracting the maximum of locked or reserved amounts from the free balance, ensuring that existential deposit limits are met. -- **Untouchable balance**: Funds that cannot be directly spent or transferred but may still be utilized for on-chain activities, such as governance participation or staking. These tokens are typically tied to certain actions or locked for a specific period. - -The spendable balance is calculated as follows: - -```text -spendable = free - max(locked - reserved, ED) -``` - -Here, `free`, `locked`, and `reserved` are defined above. The `ED` represents the [existential deposit](https://wiki.polkadot.com/learn/learn-accounts/#existential-deposit-and-reaping){target=\_blank}, the minimum balance required to keep an account active and prevent it from being reaped. You may find you can't see all balance types when looking at your account via a wallet. Wallet providers often display only spendable, locked, and reserved balances. - -### Locks - -Locks are applied to an account's free balance, preventing that portion from being spent or transferred. Locks are automatically placed when an account participates in specific on-chain activities, such as staking or governance. Although multiple locks may be applied simultaneously, they do not stack. Instead, the largest lock determines the total amount of locked tokens. - -Locks follow these basic rules: - -- If different locks apply to varying amounts, the largest lock amount takes precedence. -- If multiple locks apply to the same amount, the lock with the longest duration governs when the balance can be unlocked. - -#### Locks Example - -Consider an example where an account has 80 DOT locked for both staking and governance purposes like so: - -- 80 DOT is staked with a 28-day lock period. -- 24 DOT is locked for governance with a 1x conviction and a 7-day lock period. -- 4 DOT is locked for governance with a 6x conviction and a 224-day lock period. - -In this case, the total locked amount is 80 DOT because only the largest lock (80 DOT from staking) governs the locked balance. These 80 DOT will be released at different times based on the lock durations. In this example, the 24 DOT locked for governance will be released first since the shortest lock period is seven days. The 80 DOT stake with a 28-day lock period is released next. Now, all that remains locked is the 4 DOT for governance. After 224 days, all 80 DOT (minus the existential deposit) will be free and transferable. - -![Illustration of Lock Example](/images/reference/parachains/accounts/accounts-01.webp) - -#### Edge Cases for Locks - -In scenarios where multiple convictions and lock periods are active, the lock duration and amount are determined by the longest period and largest amount. For example, if you delegate with different convictions and attempt to undelegate during an active lock period, the lock may be extended for the full amount of tokens. For a detailed discussion on edge case lock behavior, see this [Stack Exchange post](https://substrate.stackexchange.com/questions/5067/delegating-and-undelegating-during-the-lock-period-extends-it-for-the-initial-am){target=\_blank}. - -### Balance Types on Polkadot.js - -Polkadot.js provides a user-friendly interface for managing and visualizing various account balances on Polkadot and Kusama networks. When interacting with Polkadot.js, you will encounter multiple balance types that are critical for understanding how your funds are distributed and restricted. This section explains how different balances are displayed in the Polkadot.js UI and what each type represents. - -![](/images/reference/parachains/accounts/accounts-02.webp) - -The most common balance types displayed on Polkadot.js are: - -- **Total balance**: The total number of tokens available in the account. This includes all tokens, whether they are transferable, locked, reserved, or vested. However, the total balance does not always reflect what can be spent immediately. In this example, the total balance is 0.6274 KSM. - -- **Transferable balance**: Shows how many tokens are immediately available for transfer. It is calculated by subtracting the locked and reserved balances from the total balance. For example, if an account has a total balance of 0.6274 KSM and a transferable balance of 0.0106 KSM, only the latter amount can be sent or spent freely. - -- **Vested balance**: Tokens that allocated to the account but released according to a specific schedule. Vested tokens remain locked and cannot be transferred until fully vested. For example, an account with a vested balance of 0.2500 KSM means that this amount is owned but not yet transferable. - -- **Locked balance**: Tokens that are temporarily restricted from being transferred or spent. These locks typically result from participating in staking, governance, or vested transfers. In Polkadot.js, locked balances do not stack—only the largest lock is applied. For instance, if an account has 0.5500 KSM locked for governance and staking, the locked balance would display 0.5500 KSM, not the sum of all locked amounts. - -- **Reserved balance**: Refers to tokens locked for specific on-chain actions, such as setting an identity, creating a proxy, or making governance deposits. Reserved tokens are not part of the free balance, but can be freed by performing certain actions. For example, removing an identity would unreserve those funds. - -- **Bonded balance**: The tokens locked for staking purposes. Bonded tokens are not transferable until they are unbonded after the unbonding period. - -- **Redeemable balance**: The number of tokens that have completed the unbonding period and are ready to be unlocked and transferred again. For example, if an account has a redeemable balance of 0.1000 KSM, those tokens are now available for spending. - -- **Democracy balance**: Reflects the number of tokens locked for governance activities, such as voting on referenda. These tokens are locked for the duration of the governance action and are only released after the lock period ends. - -By understanding these balance types and their implications, developers and users can better manage their funds and engage with on-chain activities more effectively. - -## Address Formats - -The SS58 address format is a core component of the Polkadot SDK that enables accounts to be uniquely identified across Polkadot-based networks. This format is a modified version of Bitcoin's Base58Check encoding, specifically designed to accommodate the multi-chain nature of the Polkadot ecosystem. SS58 encoding allows each chain to define its own set of addresses while maintaining compatibility and checksum validation for security. - -### Basic Format - -SS58 addresses consist of three main components: - -```text -base58encode(concat(,
, )) -``` - -- **Address type**: A byte or set of bytes that define the network (or chain) for which the address is intended. This ensures that addresses are unique across different Polkadot SDK-based chains. -- **Address**: The public key of the account encoded as bytes. -- **Checksum**: A hash-based checksum which ensures that addresses are valid and unaltered. The checksum is derived from the concatenated address type and address components, ensuring integrity. - -The encoding process transforms the concatenated components into a Base58 string, providing a compact and human-readable format that avoids easily confused characters (e.g., zero '0', capital 'O', lowercase 'l'). This encoding function ([`encode`](https://docs.rs/bs58/latest/bs58/fn.encode.html){target=\_blank}) is implemented exactly as defined in Bitcoin and IPFS specifications, using the same alphabet as both implementations. - -For more details about the SS58 address format implementation, see the [`Ss58Codec`](https://paritytech.github.io/polkadot-sdk/master/sp_core/crypto/trait.Ss58Codec.html){target=\_blank} trait in the Rust Docs. - -### Address Type - -The address type defines how an address is interpreted and to which network it belongs. Polkadot SDK uses different prefixes to distinguish between various chains and address formats: - -- **Address types `0-63`**: Simple addresses, commonly used for network identifiers. -- **Address types `64-127`**: Full addresses that support a wider range of network identifiers. -- **Address types `128-255`**: Reserved for future address format extensions. - -For example, Polkadot’s main network uses an address type of 0, while Kusama uses 2. This ensures that addresses can be used without confusion between networks. - -The address type is always encoded as part of the SS58 address, making it easy to quickly identify the network. Refer to the [SS58 registry](https://github.com/paritytech/ss58-registry){target=\_blank} for the canonical listing of all address type identifiers and how they map to Polkadot SDK-based networks. - -### Address Length - -SS58 addresses can have different lengths depending on the specific format. Address lengths range from as short as 3 to 35 bytes, depending on the complexity of the address and network requirements. This flexibility allows SS58 addresses to adapt to different chains while providing a secure encoding mechanism. - -| Total | Type | Raw account | Checksum | -|-------|------|-------------|----------| -| 3 | 1 | 1 | 1 | -| 4 | 1 | 2 | 1 | -| 5 | 1 | 2 | 2 | -| 6 | 1 | 4 | 1 | -| 7 | 1 | 4 | 2 | -| 8 | 1 | 4 | 3 | -| 9 | 1 | 4 | 4 | -| 10 | 1 | 8 | 1 | -| 11 | 1 | 8 | 2 | -| 12 | 1 | 8 | 3 | -| 13 | 1 | 8 | 4 | -| 14 | 1 | 8 | 5 | -| 15 | 1 | 8 | 6 | -| 16 | 1 | 8 | 7 | -| 17 | 1 | 8 | 8 | -| 35 | 1 | 32 | 2 | - -SS58 addresses also support different payload sizes, allowing a flexible range of account identifiers. - -### Checksum Types - -A checksum is applied to validate SS58 addresses. Polkadot SDK uses a Blake2b-512 hash function to calculate the checksum, which is appended to the address before encoding. The checksum length can vary depending on the address format (e.g., 1-byte, 2-byte, or longer), providing varying levels of validation strength. - -The checksum ensures that an address is not modified or corrupted, adding an extra layer of security for account management. - -### Validating Addresses - -SS58 addresses can be validated using the subkey command-line interface or the Polkadot.js API. These tools help ensure an address is correctly formatted and valid for the intended network. The following sections will provide an overview of how validation works with these tools. - -#### Using Subkey - -[Subkey](https://paritytech.github.io/polkadot-sdk/master/subkey/index.html){target=\_blank} is a CLI tool provided by Polkadot SDK for generating and managing keys. It can inspect and validate SS58 addresses. - -The `inspect` command gets a public key and an SS58 address from the provided secret URI. The basic syntax for the `subkey inspect` command is: - -```bash -subkey inspect [flags] [options] uri -``` - -For the `uri` command-line argument, you can specify the secret seed phrase, a hex-encoded private key, or an SS58 address. If the input is a valid address, the `subkey` program displays the corresponding hex-encoded public key, account identifier, and SS58 addresses. - -For example, to inspect the public keys derived from a secret seed phrase, you can run a command similar to the following: - -```bash -subkey inspect "caution juice atom organ advance problem want pledge someone senior holiday very" -``` - -The command displays output similar to the following: - -
- subkey inspect "caution juice atom organ advance problem want pledge someone senior holiday very" - Secret phrase `caution juice atom organ advance problem want pledge someone senior holiday very` is account: - Secret seed: 0xc8fa03532fb22ee1f7f6908b9c02b4e72483f0dbd66e4cd456b8f34c6230b849 - Public key (hex): 0xd6a3105d6768e956e9e5d41050ac29843f98561410d3a47f9dd5b3b227ab8746 - Public key (SS58): 5Gv8YYFu8H1btvmrJy9FjjAWfb99wrhV3uhPFoNEr918utyR - Account ID: 0xd6a3105d6768e956e9e5d41050ac29843f98561410d3a47f9dd5b3b227ab8746 - SS58 Address: 5Gv8YYFu8H1btvmrJy9FjjAWfb99wrhV3uhPFoNEr918utyR -
- -The `subkey` program assumes an address is based on a public/private key pair. If you inspect an address, the command returns the 32-byte account identifier. - -However, not all addresses in Polkadot SDK-based networks are based on keys. - -Depending on the command-line options you specify and the input you provided, the command output might also display the network for which the address has been encoded. For example: - -```bash -subkey inspect "12bzRJfh7arnnfPPUZHeJUaE62QLEwhK48QnH9LXeK2m1iZU" -``` - -The command displays output similar to the following: - -
- subkey inspect "12bzRJfh7arnnfPPUZHeJUaE62QLEwhK48QnH9LXeK2m1iZU" - Public Key URI `12bzRJfh7arnnfPPUZHeJUaE62QLEwhK48QnH9LXeK2m1iZU` is account: - Network ID/Version: polkadot - Public key (hex): 0x46ebddef8cd9bb167dc30878d7113b7e168e6f0646beffd77d69d39bad76b47a - Account ID: 0x46ebddef8cd9bb167dc30878d7113b7e168e6f0646beffd77d69d39bad76b47a - Public key (SS58): 12bzRJfh7arnnfPPUZHeJUaE62QLEwhK48QnH9LXeK2m1iZU - SS58 Address: 12bzRJfh7arnnfPPUZHeJUaE62QLEwhK48QnH9LXeK2m1iZU -
- -#### Using Polkadot.js API - -To verify an address in JavaScript or TypeScript projects, you can use the functions built into the [Polkadot.js API](https://polkadot.js.org/docs/){target=\_blank}. For example: - -```js -// Import Polkadot.js API dependencies -const { decodeAddress, encodeAddress } = require('@polkadot/keyring'); -const { hexToU8a, isHex } = require('@polkadot/util'); - -// Specify an address to test. -const address = 'INSERT_ADDRESS_TO_TEST'; - -// Check address -const isValidSubstrateAddress = () => { - try { - encodeAddress(isHex(address) ? hexToU8a(address) : decodeAddress(address)); - - return true; - } catch (error) { - return false; - } -}; - -// Query result -const isValid = isValidSubstrateAddress(); -console.log(isValid); - -``` - -If the function returns `true`, the specified address is a valid address. - -#### Other SS58 Implementations - -Support for encoding and decoding Polkadot SDK SS58 addresses has been implemented in several other languages and libraries. - -- **Crystal**: [`wyhaines/base58.cr`](https://github.com/wyhaines/base58.cr){target=\_blank} -- **Go**: [`itering/subscan-plugin`](https://github.com/itering/subscan-plugin){target=\_blank} -- **Python**: [`polkascan/py-scale-codec`](https://github.com/polkascan/py-scale-codec){target=\_blank} -- **TypeScript**: [`subsquid/squid-sdk`](https://github.com/subsquid/squid-sdk){target=\_blank} - - ---- - -Page Title: Proof of Stake Consensus - -- Source (raw): https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/reference-polkadot-hub-consensus-and-security-pos-consensus.md -- Canonical (HTML): https://docs.polkadot.com/reference/polkadot-hub/consensus-and-security/pos-consensus/ -- Summary: Explore Polkadot's consensus protocols for secure, scalable, and decentralized network operation, including NPoS, BABE, GRANDPA, and BEEFY. - -# Proof of Stake Consensus - -## Introduction - -Polkadot's Proof of Stake consensus model leverages a unique hybrid approach by design to promote decentralized and secure network operations. In traditional Proof of Stake (PoS) systems, a node's ability to validate transactions is tied to its token holdings, which can lead to centralization risks and limited validator participation. Polkadot addresses these concerns through its [Nominated Proof of Stake (NPoS)](/reference/glossary/#nominated-proof-of-stake-npos){target=\_blank} model and a combination of advanced consensus mechanisms to ensure efficient block production and strong finality guarantees. This combination enables the Polkadot network to scale while maintaining security and decentralization. - -## Nominated Proof of Stake - -Polkadot uses Nominated Proof of Stake (NPoS) to select the validator set and secure the network. This model is designed to maximize decentralization and security by balancing the roles of [validators](https://wiki.polkadot.com/learn/learn-validator/){target=\_blank} and [nominators](https://wiki.polkadot.com/learn/learn-nominator/){target=\_blank}. - -- **Validators**: Play a key role in maintaining the network's integrity. They produce new blocks, validate parachain blocks, and ensure the finality of transactions across the relay chain. -- **Nominators**: Support the network by selecting validators to back with their stake. This mechanism allows users who don't want to run a validator node to still participate in securing the network and earn rewards based on the validators they support. - -In Polkadot's NPoS system, nominators can delegate their tokens to trusted validators, giving them voting power in selecting validators while spreading security responsibilities across the network. - -## Hybrid Consensus - -Polkadot employs a hybrid consensus model that combines two key protocols: a finality gadget called [GRANDPA](#finality-gadget-grandpa) and a block production mechanism known as [BABE](#block-production-babe). This hybrid approach enables the network to benefit from both rapid block production and provable finality, ensuring security and performance. - -The hybrid consensus model has some key advantages: - -- **Probabilistic finality**: With BABE constantly producing new blocks, Polkadot ensures that the network continues to make progress, even when a final decision has not yet been reached on which chain is the true canonical chain. - -- **Provable finality**: GRANDPA guarantees that once a block is finalized, it can never be reverted, ensuring that all network participants agree on the finalized chain. - -By using separate protocols for block production and finality, Polkadot can achieve rapid block creation and strong guarantees of finality while avoiding the typical trade-offs seen in traditional consensus mechanisms. - -## Block Production - BABE - -Blind Assignment for Blockchain Extension (BABE) is Polkadot's block production mechanism, working with GRANDPA to ensure blocks are produced consistently across the network. As validators participate in BABE, they are assigned block production slots through a randomness-based lottery system. This helps determine which validator is responsible for producing a block at a given time. BABE shares similarities with [Ouroboros Praos](https://eprint.iacr.org/2017/573.pdf){target=\_blank} but differs in key aspects like chain selection rules and slot timing. - -Key features of BABE include: - -- **Epochs and slots**: BABE operates in phases called epochs, each of which is divided into slots (around 6 seconds per slot). Validators are assigned slots at the beginning of each epoch based on stake and randomness. - -- **Randomized block production**: Validators enter a lottery to determine which will produce a block in a specific slot. This randomness is sourced from the relay chain's [randomness cycle](/reference/parachains/randomness/){target=\_blank}. - -- **Multiple block producers per slot**: In some cases, more than one validator might win the lottery for the same slot, resulting in multiple blocks being produced. These blocks are broadcasted, and the network's fork choice rule helps decide which chain to follow. - -- **Handling empty slots**: If no validators win the lottery for a slot, a secondary selection algorithm ensures that a block is still produced. Validators selected through this method always produce a block, ensuring no slots are skipped. - -BABE's combination of randomness and slot allocation creates a secure, decentralized system for consistent block production while also allowing for fork resolution when multiple validators produce blocks for the same slot. - -### Validator Participation - -In BABE, validators participate in a lottery for every slot to determine whether they are responsible for producing a block during that slot. This process's randomness ensures a decentralized and unpredictable block production mechanism. - -There are two lottery outcomes for any given slot that initiate additional processes: - -- **Multiple validators in a slot**: Due to the randomness, multiple validators can be selected to produce a block for the same slot. When this happens, each validator produces a block and broadcasts it to the network resulting in a race condition. The network's topology and latency then determine which block reaches the majority of nodes first. BABE allows both chains to continue building until the finalization process resolves which one becomes canonical. The [Fork Choice](#fork-choice) rule is then used to decide which chain the network should follow. - -- **No validators in a slot**: On occasions when no validator is selected by the lottery, a [secondary validator selection algorithm](https://spec.polkadot.network/sect-block-production#defn-babe-secondary-slots){target=\_blank} steps in. This backup ensures that a block is still produced, preventing skipped slots. However, if the primary block produced by a verifiable random function [(VRF)-selected](/reference/parachains/randomness/#vrf){target=\_blank} validator exists for that slot, the secondary block will be ignored. As a result, every slot will have either a primary or a secondary block. - -This design ensures continuous block production, even in cases of multiple competing validators or an absence of selected validators. - -### Additional Resources - -For further technical insights about BABE, including cryptographic details and formal proofs, see the [BABE paper](https://research.web3.foundation/Polkadot/protocols/block-production/Babe){target=\_blank} from Web3 Foundation. - -For BABE technical definitions, constants, and formulas, see the [Block Production Lottery](https://spec.polkadot.network/sect-block-production#sect-block-production-lottery){target=\_blank} section of the Polkadot Protocol Specification. - -## Finality Gadget - GRANDPA - -GRANDPA (GHOST-based Recursive ANcestor Deriving Prefix Agreement) serves as the finality gadget for Polkadot's relay chain. Operating alongside the BABE block production mechanism, it ensures provable finality, giving participants confidence that blocks finalized by GRANDPA cannot be reverted. - -Key features of GRANDPA include: - -- **Independent finality service**: GRANDPA runs separately from the block production process, operating in parallel to ensure seamless finalization. -- **Chain-based finalization**: Instead of finalizing one block at a time, GRANDPA finalizes entire chains, speeding up the process significantly. -- **Batch finalization**: Can finalize multiple blocks in a single round, enhancing efficiency and minimizing delays in the network. -- **Partial synchrony tolerance**: GRANDPA works effectively in a partially synchronous network environment, managing both asynchronous and synchronous conditions. -- **Byzantine fault tolerance**: Can handle up to 1/5 Byzantine (malicious) nodes, ensuring the system remains secure even when faced with adversarial behavior. - -??? note "What is GHOST?" - [GHOST (Greedy Heaviest-Observed Subtree)](https://eprint.iacr.org/2018/104.pdf){target=\blank} is a consensus protocol used in blockchain networks to select the heaviest branch in a block tree. Unlike traditional longest-chain rules, GHOST can more efficiently handle high block production rates by considering the weight of subtrees rather than just the chain length. - -### Probabilistic vs. Provable Finality - -In traditional Proof of Work (PoW) blockchains, finality is probabilistic. As blocks are added to the chain, the probability that a block is final increases, but it can never be guaranteed. Eventual consensus means that all nodes will agree on a single version of the blockchain over time, but this process can be unpredictable and slow. - -Conversely, GRANDPA provides provable finality, which means that once a block is finalized, it is irreversible. By using Byzantine fault-tolerant agreements, GRANDPA finalizes blocks more efficiently and securely than probabilistic mechanisms like Nakamoto consensus. Like Ethereum's Casper the Friendly Finality Gadget (FFG), GRANDPA ensures that finalized blocks cannot be reverted, offering stronger consensus guarantees. - -### Additional Resources - -For technical insights, including formal proofs and detailed algorithms, see the [GRANDPA paper](https://github.com/w3f/consensus/blob/master/pdf/grandpa.pdf){target=\_blank} from Web3 Foundation. - -For a deeper look at the code behind GRANDPA, see the following GitHub repositories: - -- [GRANDPA Rust implementation](https://github.com/paritytech/finality-grandpa){target=\_blank} -- [GRANDPA Pallet](https://github.com/paritytech/polkadot-sdk/blob/polkadot-stable2506-2/substrate/frame/grandpa/src/lib.rs){target=\_blank} - -## Fork Choice - -The fork choice of the relay chain combines BABE and GRANDPA: - -1. BABE must always build on the chain that GRANDPA has finalized. -2. When there are forks after the finalized head, BABE builds on the chain with the most primary blocks to provide probabilistic finality. - -![Fork choice diagram](/images/reference/polkadot-hub/consensus-and-security/pos-consensus/consensus-protocols-01.webp) - -In the preceding diagram, finalized blocks are black, and non-finalized blocks are yellow. Primary blocks are labeled '1', and secondary blocks are labeled '2.' The topmost chain is the longest chain originating from the last finalized block, but it is not selected because it only has one primary block at the time of evaluation. In comparison, the one below it originates from the last finalized block and has three primary blocks. - -### Additional Resources - -To learn more about how BABE and GRANDPA work together to produce and finalize blocks on Kusama, see this [Block Production and Finalization in Polkadot](https://youtu.be/FiEAnVECa8c){target=\_blank} talk from Web3 Foundation's Bill Laboon. - -For an in-depth academic discussion about Polkadot's hybrid consensus model, see this [Block Production and Finalization in Polkadot: Understanding the BABE and GRANDPA Protocols](https://www.youtube.com/watch?v=1CuTSluL7v4&t=4s){target=\_blank} MIT Cryptoeconomic Systems 2020 talk by Web3 Foundation's Bill Laboon. - -## Bridging - BEEFY - -Bridge Efficiency Enabling Finality Yielder (BEEFY) is a specialized protocol that extends the finality guarantees provided by GRANDPA. It is specifically designed to facilitate efficient bridging between Polkadot relay chains (such as Polkadot and Kusama) and external blockchains like Ethereum. While GRANDPA is well-suited for finalizing blocks within Polkadot, it has limitations when bridging external chains that weren't built with Polkadot's interoperability features in mind. BEEFY addresses these limitations by ensuring other networks can efficiently verify finality proofs. - -Key features of BEEFY include: - -- **Efficient finality proof verification**: BEEFY enables external networks to easily verify Polkadot finality proofs, ensuring seamless communication between chains. -- **Merkle Mountain Ranges (MMR)**: This data structure is used to efficiently store and transmit proofs between chains, optimizing data storage and reducing transmission overhead. -- **ECDSA signature schemes**: BEEFY uses ECDSA signatures, which are widely supported on Ethereum and other EVM-based chains, making integration with these ecosystems smoother. -- **Light client optimization**: BEEFY reduces the computational burden on light clients by allowing them to check for a super-majority of validator votes rather than needing to process all validator signatures, improving performance. - -### Additional Resources - -For BEEFY technical definitions, constants, and formulas, see the [Bridge design (BEEFY)](https://spec.polkadot.network/sect-finality#sect-grandpa-beefy){target=\_blank} section of the Polkadot Protocol Specification. - - ---- - -Page Title: Randomness - -- Source (raw): https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/reference-parachains-randomness.md -- Canonical (HTML): https://docs.polkadot.com/reference/parachains/randomness/ -- Summary: Explore the importance of randomness in PoS blockchains, focusing on Polkadot’s VRF-based approach to ensure fairness and security in validator selection. - -# Randomness - -## Introduction - -Randomness is crucial in Proof of Stake (PoS) blockchains to ensure a fair and unpredictable distribution of validator duties. However, computers are inherently deterministic, meaning the same input always produces the same output. What we typically refer to as "random" numbers on a computer are actually pseudo-random. These numbers rely on an initial "seed," which can come from external sources like [atmospheric noise](https://www.random.org/randomness/){target=\_blank}, [heart rates](https://mdpi.altmetric.com/details/47574324){target=\_blank}, or even [lava lamps](https://en.wikipedia.org/wiki/Lavarand){target=\_blank}. While this may seem random, given the same "seed," the same sequence of numbers will always be generated. - -In a global blockchain network, relying on real-world entropy for randomness isn’t feasible because these inputs vary by time and location. If nodes use different inputs, blockchains can fork. Hence, real-world randomness isn't suitable for use as a seed in blockchain systems. - -Currently, two primary methods for generating randomness in blockchains are used: [`RANDAO`](#randao) and [`VRF`](#vrf) (Verifiable Random Function). Polkadot adopts the `VRF` approach for its randomness. - -## VRF - -A Verifiable Random Function (VRF) is a cryptographic function that generates a random number and proof that ensures the submitter produced the number. This proof allows anyone to verify the validity of the random number. - -Polkadot's VRF is similar to the one used in [**Ouroboros Praos**](https://eprint.iacr.org/2017/573.pdf){target=\_blank}, which secures randomness for block production in systems like [BABE](/reference/polkadot-hub/consensus-and-security/pos-consensus/#block-production-babe){target=\_blank} (Polkadot’s block production mechanism). - -The key difference is that Polkadot's VRF doesn’t rely on a central clock—avoiding the issue of whose clock to trust. Instead, it uses its own past results and slot numbers to simulate time and determine future outcomes. - -### How VRF Works - -Slots on Polkadot are discrete units of time, each lasting six seconds, and can potentially hold a block. Multiple slots form an epoch, with 2400 slots making up one four-hour epoch. - -In each slot, validators execute a "die roll" using a VRF. The VRF uses three inputs: - -1. A "secret key," unique to each validator, is used for the die roll. -2. An epoch randomness value, derived from the hash of VRF outputs from blocks two epochs ago (N-2), so past randomness influences the current epoch (N). -3. The current slot number. - -This process helps maintain fair randomness across the network. - -Here is a graphical representation: - -![](/images/reference/parachains/randomness/randomness-01.webp) - -The VRF produces two outputs: a result (the random number) and a proof (verifying that the number was generated correctly). - -The result is checked by the validator against a protocol threshold. If it's below the threshold, the validator becomes a candidate for block production in that slot. - -The validator then attempts to create a block, submitting it along with the `PROOF` and `RESULT`. - -So, VRF can be expressed like: - -`(RESULT, PROOF) = VRF(SECRET, EPOCH_RANDOMNESS_VALUE, CURRENT_SLOT_NUMBER)` - -Put simply, performing a "VRF roll" generates a random number along with proof that the number was genuinely produced and not arbitrarily chosen. - -After executing the VRF, the `RESULT` is compared to a protocol-defined `THRESHOLD`. If the `RESULT` is below the `THRESHOLD`, the validator becomes a valid candidate to propose a block for that slot. Otherwise, the validator skips the slot. - -As a result, there may be multiple validators eligible to propose a block for a slot. In this case, the block accepted by other nodes will prevail, provided it is on the chain with the latest finalized block as determined by the GRANDPA finality gadget. It's also possible for no block producers to be available for a slot, in which case the AURA consensus takes over. AURA is a fallback mechanism that randomly selects a validator to produce a block, running in parallel with BABE and only stepping in when no block producers exist for a slot. Otherwise, it remains inactive. - -Because validators roll independently, no block candidates may appear in some slots if all roll numbers are above the threshold. - -To verify resolution of this issue and that Polkadot block times remain near constant-time, see the [PoS Consensus](/reference/polkadot-hub/consensus-and-security/pos-consensus/){target=\_blank} page of this documentation. - -## RANDAO - -An alternative on-chain randomness method is Ethereum's RANDAO, where validators perform thousands of hashes on a seed and publish the final hash during a round. The collective input from all validators forms the random number, and as long as one honest validator participates, the randomness is secure. - -To enhance security, RANDAO can optionally be combined with a Verifiable Delay Function (VDF), ensuring that randomness can't be predicted or manipulated during computation. - -For more information about RANDAO, see the [Randomness - RANDAO](https://eth2book.info/capella/part2/building_blocks/randomness/){target=\_blank} section of the Upgrading Ethereum documentation. - -## VDFs - -Verifiable Delay Functions (VDFs) are time-bound computations that, even on parallel computers, take a set amount of time to complete. - -They produce a unique result that can be quickly verified publicly. When combined with RANDAO, feeding RANDAO's output into a VDF introduces a delay that nullifies an attacker's chance to influence the randomness. - -However, VDF likely requires specialized ASIC devices to run separately from standard nodes. - -!!!warning - While only one is needed to secure the system, and they will be open-source and inexpensive, running VDF devices involves significant costs without direct incentives, adding friction for blockchain users. - -## Additional Resources - -For more information about the reasoning for choices made along with proofs, see Polkadot's research on blockchain randomness and sortition in the [Block production](https://research.web3.foundation/Polkadot/protocols/block-production){target=\_blank} entry of the Polkadot Wiki. - -For a discussion with Web3 Foundation researchers about when and under what conditions Polkadot's randomness can be utilized, see the [Discussion on Randomness used in Polkadot](https://github.com/use-ink/ink/issues/57){target=\_blank} issue on GitHub. - - ---- - -Page Title: Set Up the Polkadot SDK Parachain Template - -- Source (raw): https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/parachains-launch-a-parachain-set-up-the-parachain-template.md -- Canonical (HTML): https://docs.polkadot.com/parachains/launch-a-parachain/set-up-the-parachain-template/ -- Summary: Learn how to set up and run the Polkadot SDK Parachain Template locally, creating a ready-to-customize foundation for your parachain. - -# Set Up the Polkadot SDK Parachain Template - -## Introduction - -The [Polkadot SDK](https://github.com/paritytech/polkadot-sdk){target=\_blank} includes several [templates](/parachains/customize-runtime/#starting-templates){target=\_blank} designed to help you quickly start building your own blockchain. Each template offers a different level of configuration, from minimal setups to feature-rich environments, allowing you to choose the foundation that best fits your project's needs. - -Among these, the [Parachain Template](https://github.com/paritytech/polkadot-sdk-parachain-template){target=\_blank} provides a preconfigured runtime with commonly used pallets, making it an ideal starting point for most parachain development projects. - -This guide walks you through the full process of working with this template. You will: - -- Set up the Polkadot SDK Parachain Template. -- Understand the project structure and key components. -- Verify your template is ready for development. -- Run the parachain template locally in development mode. - -By the end of this guide, you'll have a working template ready to customize and deploy as a parachain. - -## Prerequisites - -Before getting started, ensure you have done the following: - -- Completed the [Install Polkadot SDK](/parachains/install-polkadot-sdk/){target=\_blank} guide and successfully installed [Rust](https://www.rust-lang.org/){target=\_blank} and the required packages to set up your development environment. - -For this tutorial series, you need to use Rust `1.86`. Newer versions of the compiler may not work with this parachain template version. - -Run the following commands to set up the correct Rust version: - -=== "macOS" - - ```bash - rustup install 1.86 - rustup default 1.86 - rustup target add wasm32-unknown-unknown --toolchain 1.86-aarch64-apple-darwin - rustup component add rust-src --toolchain 1.86-aarch64-apple-darwin - ``` - -=== "Ubuntu" - - ```bash - rustup toolchain install 1.86.0 - rustup default 1.86.0 - rustup target add wasm32-unknown-unknown --toolchain 1.86.0 - rustup component add rust-src --toolchain 1.86.0 - ``` - -## Polkadot SDK Utility Tools - -This tutorial requires two essential tools: - -- [**Chain spec builder**](https://crates.io/crates/staging-chain-spec-builder/10.0.0){target=\_blank}: A Polkadot SDK utility for generating chain specifications. Refer to the [Generate Chain Specs](/parachains/launch-a-parachain/deploy-to-polkadot/#generate-the-chain-specification){target=\_blank} documentation for detailed usage. - - Install it by executing the following command: - - ```bash - cargo install --locked staging-chain-spec-builder@10.0.0 - ``` - - This command installs the `chain-spec-builder` binary. - -- [**Polkadot Omni Node**](https://crates.io/crates/polkadot-omni-node/0.5.0){target=\_blank}: A white-labeled binary, released as a part of Polkadot SDK that can act as the collator of a parachain in production, with all the related auxiliary functionalities that a normal collator node has: RPC server, archiving state, etc. Moreover, it can also run the Wasm blob of the parachain locally for testing and development. - - To install it, run the following command: - - ```bash - cargo install --locked polkadot-omni-node@0.5.0 - ``` - - This command installs the `polkadot-omni-node` binary. - -## Clone the Template - -The [Polkadot SDK Parachain Template](https://github.com/paritytech/polkadot-sdk-parachain-template){target=\_blank} provides a ready-to-use development environment for building with the [Polkadot SDK](https://github.com/paritytech/polkadot-sdk){target=\_blank}. Follow these steps to set up the template: - -1. Clone the template repository: - - ```bash - git clone https://github.com/paritytech/polkadot-sdk-parachain-template.git parachain-template - ``` - -2. Navigate into the project directory: - - ```bash - cd parachain-template - ``` - -## Explore the Project Structure - -Before building the template, take a moment to familiarize yourself with its structure. Understanding this organization will help you navigate the codebase as you develop your parachain. - -The template follows a standard Polkadot SDK project layout: +The template follows a standard Polkadot SDK project layout: ```text parachain-template/ @@ -5189,514 +3059,122 @@ Page Title: Smart Contracts Cookbook - Canonical (HTML): https://docs.polkadot.com/smart-contracts/cookbook/ - Summary: Explore our full collection of tutorials and guides to learn step-by-step how to build, deploy, and work with smart contracts on Polkadot. -# Smart Contracts Cookbook - -Welcome to the Polkadot smart contracts cookbook index. - -This page contains a list of all relevant tutorials and guides to help you get started coding smart contracts and dApps in Polkadot. - - - - -## Get Tokens from the Faucet - -| Title | Difficulty | Tools | Description | -|------------------------------------|:-----------:|-------|-----------------------------------------------------------------------------------------------------------------------| -| [Faucet](/smart-contracts/faucet/) | 🟢 Beginner | N/A | Learn how to obtain test tokens from Polkadot faucets for development and testing purposes across different networks. | - -## EVM Smart Contracts - -| Title | Difficulty | Tools | Description | -|---------------------------------------------------------------------------------------------------------|:-----------:|--------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------| -| [Deploy an ERC-20 to Polkadot Hub](/smart-contracts/cookbook/smart-contracts/deploy-erc20/erc20-remix/) | 🟢 Beginner | EVM Wallet, Polkadot Remix IDE | Deploy an ERC-20 token on Polkadot Hub using PolkaVM. This guide covers contract creation, compilation, deployment, and interaction via Polkadot Remix IDE. | -| [Deploy an NFT to Polkadot Hub](/smart-contracts/cookbook/smart-contracts/deploy-nft/nft-remix/) | 🟢 Beginner | EVM Wallet, Polkadot Remix IDE | Deploy an NFT on Polkadot Hub using PolkaVM and OpenZeppelin. Learn how to compile, deploy, and interact with your contract using Polkadot Remix IDE. | - -## Port Ethereum DApps - -| Title | Difficulty | Tools | Description | -|-------------------------------------------------------------------------------------|:---------------:|---------|----------------------------------------------------------------------------------------------------------------------------------| -| [Deploying Uniswap V2 on Polkadot](/smart-contracts/cookbook/eth-dapps/uniswap-v2/) | 🟡 Intermediate | Hardhat | Learn how to deploy and test Uniswap V2 on Polkadot Hub using Hardhat, bringing AMM-based token swaps to the Polkadot ecosystem. | - - ---- - -Page Title: Smart Contracts Overview - -- Source (raw): https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/smart-contracts-overview.md -- Canonical (HTML): https://docs.polkadot.com/smart-contracts/overview/ -- Summary: Learn about smart contract development on Polkadot Hub with native PolkaVM support, dual-VM execution, and seamless cross-chain capabilities. - -# Smart Contracts on Polkadot Hub - -## Introduction - -Polkadot Hub provides a production-ready smart contract platform that combines Ethereum compatibility with the performance and cross-chain capabilities of the Polkadot ecosystem. Developers can deploy smart contracts directly on Polkadot Hub while using familiar Ethereum tooling, workflows, and programming languages. - -Built with a dual-VM approach, Polkadot Hub offers two execution backends: REVM for unmodified EVM compatibility and native PolkaVM for optimized computationally expensive workloads. This dual-VM architecture enables developers to migrate existing Ethereum contracts instantly or optimize for speed and efficiency with native execution. - -## Why Build on Polkadot Hub - -### Ethereum Compatibility - -Deploy existing Ethereum contracts with zero modifications while maintaining full compatibility with your existing development stack: - -- **Complete JSON-RPC API support**: Use MetaMask, Hardhat, Remix, Foundry, and all standard Ethereum tooling. -- **Standard libraries**: Integrate Ethers.js, Web3.js, Viem, Wagmi, and Web3.py without changes. -- **Solidity development**: Write contracts in Solidity or migrate existing code directly. -- **Familiar workflows**: Maintain your existing deployment, testing, and monitoring processes. - -### Performance Options - -Choose between two execution backends: - -- **REVM**: Run unmodified Ethereum contracts with full EVM/Ethereum compatibility. -- **PolkaVM**: Compile to optimized RISC-V bytecode for enhanced performance and lower fees while keeping Ethereum-compatibility. - -Both backends share the same RPC interface and tooling support, allowing seamless transitions. In addition, smart contracts can interact with Polkadot native services via [precompile contracts](/smart-contracts/precompiles/){target=\_blank}. - -### Cross-VM & Cross-Chain Capabilities - -Smart contracts written for one VM (for example, EVM) can interact directly with other smart contracts written for the RISC-V PolkaVM, and back. This allows to use full EVM compatible contracts but extend to heavy/complex execution workloads to the PolkaVM RISC-V backend. - -Furthermore, all smart contracts in Polkadot Hub can interact with any service in the Polkadot ecosystem through [XCM](/smart-contracts/precompiles/xcm/){target=\_blank}, enabling token transfers, remote execution, and cross-chain composability without bridges or intermediaries. - -## Other Smart Contract Environments - -Beyond Polkadot Hub's native PolkaVM support, the ecosystem offers two main alternatives for smart contract development: - -- **EVM-compatible parachains**: Provide access to Ethereum's extensive developer ecosystem, smart contract portability, and established tooling like Hardhat, Remix, Foundry, and OpenZeppelin. The main options include Moonbeam (the first full Ethereum-compatible parachain serving as an interoperability hub), Astar (featuring dual VM support for both EVM and WebAssembly contracts), and Acala (DeFi-focused with enhanced Acala EVM+ offering advanced DeFi primitives). - -- **Rust (ink!)**: ink! is a Rust-based framework that can compile to PolkaVM. It uses [`#[ink(...)]`](https://use.ink/docs/v6/macros-attributes/){target=\_blank} attribute macros to create Polkadot SDK-compatible PolkaVM bytecode, offering strong memory safety from Rust, an advanced type system, high-performance PolkaVM execution, and platform independence with sandboxed security. - -## Next Steps - -
- -- Guide __Get Started__ - - --- - - Quick-start guides for connecting, deploying, and building your first smart contract. - - [:octicons-arrow-right-24: Get Started](/smart-contracts/get-started/) - -- Guide __Cookbook__ - - --- - - Step-by-step tutorials for deploying contracts, tokens, NFTs, and full dApps. - - [:octicons-arrow-right-24: View Tutorials](/smart-contracts/cookbook/) - -- Guide __Ethereum Developers__ - - --- - - Understand key differences in accounts, fees, gas model, and deployment on Polkadot Hub. - - [:octicons-arrow-right-24: Learn More](/smart-contracts/for-eth-devs/accounts/) - -- Guide __Precompiles__ - - --- - - Discover advanced functionalities including XCM for cross-chain interactions. - - [:octicons-arrow-right-24: Explore Precompiles](/smart-contracts/precompiles/) - -
- - ---- - -Page Title: Technical Reference Overview - -- Source (raw): https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/reference.md -- Canonical (HTML): https://docs.polkadot.com/reference/ -- Summary: Learn about Polkadot's technical architecture, governance framework, parachain ecosystem, and the tools you need to build and interact with the network. - -## Introduction - -The Technical Reference section provides comprehensive documentation of Polkadot's architecture, core concepts, and development tooling. Whether you're exploring how Polkadot's relay chain coordinates parachains, understanding governance mechanisms, or building applications on the network, this reference covers the technical foundations you need. - -Polkadot is a multi-chain network that enables diverse, interconnected blockchains to share security and communicate seamlessly. Understanding how these components interact from the [relay chain](/polkadot-protocol/glossary#relay-chain){target=\_blank} that validates [parachains](/polkadot-protocol/glossary#parachain){target=\_blank} to the [governance](/reference/glossary#governance){target=\_blank} mechanisms that evolve the protocol is essential for developers, validators, and network participants. - -This guide organizes technical documentation across five core areas: Polkadot Hub, Parachains, On-Chain Governance, Glossary, and Tools, each providing detailed information on different aspects of the Polkadot ecosystem. - -## Polkadot Hub - -[Polkadot Hub](/reference/polkadot-hub/){target=\_blank} is the entry point to Polkadot for all users and application developers. It provides access to essential Web3 services, including smart contracts, staking, governance, identity management, and cross-ecosystem interoperability—without requiring you to deploy or manage a parachain. - -The Hub encompasses a set of core functionality that enables developers and users to build and interact with applications on Polkadot. Key capabilities include: - -- **Smart contracts**: Deploy Ethereum-compatible smart contracts and build decentralized applications. -- **Assets and tokens**: Create, manage, and transfer fungible tokens and NFTs across the ecosystem. -- **Staking**: Participate in network security and earn rewards by staking DOT. -- **Governance**: Vote on proposals and participate in Polkadot's decentralized decision-making through OpenGov. -- **Identity services**: Register and manage on-chain identities, enabling access to governance roles and network opportunities. -- **Cross-chain interoperability**: Leverage XCM messaging to interact securely with other chains in the Polkadot ecosystem. -- **Collectives and DAOs**: Participate in governance collectives and decentralized autonomous organizations. - -## Parachains - -[Parachains](/reference/parachains/){target=\_blank} are specialized blockchains that connect to the Polkadot relay chain, inheriting its security while maintaining their own application-specific logic. The parachains documentation covers: - -- **Accounts**: Deep dive into account types, storage, and management on parachains. -- **Blocks, transactions and fees**: Understand block production, transaction inclusion, and fee mechanisms. -- **Consensus**: Learn how parachain blocks are validated and finalized through the relay chain's consensus. -- **Chain data**: Explore data structures, storage layouts, and state management. -- **Cryptography**: Study cryptographic primitives used in Polkadot SDK-based chains. -- **Data encoding**: Understand how data is encoded and decoded for blockchain compatibility. -- **Networks**: Learn about networking protocols and peer-to-peer communication. -- **Interoperability**: Discover [Cross-Consensus Messaging (XCM)](/parachains/interoperability/get-started/){target=\_blank}, the standard for cross-chain communication. -- **Randomness**: Understand how randomness is generated and used in Polkadot chains. -- **Node and runtime**: Learn about parachain nodes, runtime environments, and the [Polkadot SDK](https://github.com/paritytech/polkadot-sdk){target=\_blank}. - -## On-Chain Governance - -[On-Chain governance](/reference/governance/){target=\_blank} is the decentralized decision-making mechanism for the Polkadot network. It manages the evolution and modification of the network's runtime logic, enabling community oversight and approval for proposed changes. The governance documentation details: - -- **OpenGov framework**: Understand Polkadot's next-generation governance system with enhanced delegation, flexible tracks, and simultaneous referendums. -- **Origins and tracks**: Learn how governance proposals are categorized, prioritized, and executed based on their privilege level and complexity. -- **Voting and delegation**: Explore conviction voting, vote delegation, and how token holders participate in governance. -- **Governance evolution**: See how Polkadot's governance has evolved from Governance V1 to the current OpenGov system. - -## Glossary - -The [Glossary](/reference/glossary/){target=\_blank} provides quick-reference definitions for Polkadot-specific terminology. Essential terms include: - -- Blockchain concepts (blocks, transactions, state) -- Consensus mechanisms (validators, collators, finality) -- Polkadot-specific terms (relay chain, parachain, XCM, FRAME) -- Network components (nodes, runtimes, storage) -- Governance terminology (origins, tracks, referendums) - -## Tools - -The [Tools](/reference/tools/){target=\_blank} section documents essential development and interaction tools for the Polkadot ecosystem: - -- **Light clients**: Lightweight solutions for interacting with the network without running full nodes. -- **JavaScript/TypeScript tools**: Libraries like [Polkadot.js API](/reference/tools/polkadot-js-api/){target=\_blank} and [PAPI](/reference/tools/papi/){target=\_blank} for building applications. -- **Rust tools**: [Polkadart](/reference/tools/polkadart/){target=\_blank} and other Rust-based libraries for SDK development. -- **Python tools**: [py-substrate-interface](/reference/tools/py-substrate-interface/){target=\_blank} for Python developers. -- **Testing and development**: Tools like [Moonwall](/reference/tools/moonwall/){target=\_blank}, [Chopsticks](/reference/tools/chopsticks/){target=\_blank}, and [Omninode](/reference/tools/omninode/){target=\_blank} for smart contract and parachain testing. -- **Indexing and monitoring**: [Sidecar](/reference/tools/sidecar/){target=\_blank} for data indexing and [Dedot](/reference/tools/dedot/){target=\_blank} for substrate interaction. -- **Cross-chain tools**: [ParaSpell](/reference/tools/paraspell/){target=\_blank} for XCM integration and asset transfers. - -## Where to Go Next - -For detailed exploration of specific areas, proceed to any of the main sections: - -
- -- Learn **Polkadot Hub** - - --- - - Understand the relay chain's role in coordinating parachains, providing shared security, and enabling governance. - - [:octicons-arrow-right-24: Reference](/reference/polkadot-hub/) - -- Learn **Parachains** - - --- - - Deep dive into parachain architecture, consensus, data structures, and building application-specific blockchains. - - [:octicons-arrow-right-24: Reference](/reference/parachains/) - -- Learn **On-Chain Governance** - - --- - - Explore Polkadot's decentralized governance framework and how to participate in network decision-making. - - [:octicons-arrow-right-24: Reference](/reference/governance/) - -- Guide **Glossary** - - --- - - Quick reference for Polkadot-specific terminology and concepts used throughout the documentation. - - [:octicons-arrow-right-24: Reference](/reference/glossary/) - -- Guide **Tools** - - --- - - Discover development tools, libraries, and frameworks for building and interacting with Polkadot. - - [:octicons-arrow-right-24: Reference](/reference/tools/) - -
- - ---- - -Page Title: Transactions - -- Source (raw): https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/reference-parachains-blocks-transactions-fees-transactions.md -- Canonical (HTML): https://docs.polkadot.com/reference/parachains/blocks-transactions-fees/transactions/ -- Summary: Learn how to construct, submit, and validate transactions in the Polkadot SDK, covering signed, unsigned, and inherent types of transactions. - -# Transactions - -## Introduction - -Transactions are essential components of blockchain networks, enabling state changes and the execution of key operations. In the Polkadot SDK, transactions, often called extrinsics, come in multiple forms, including signed, unsigned, and inherent transactions. - -This guide walks you through the different transaction types and how they're formatted, validated, and processed within the Polkadot ecosystem. You'll also learn how to customize transaction formats and construct transactions for FRAME-based runtimes, ensuring a complete understanding of how transactions are built and executed in Polkadot SDK-based chains. - -## What Is a Transaction? - -In the Polkadot SDK, transactions represent operations that modify the chain's state, bundled into blocks for execution. The term extrinsic is often used to refer to any data that originates outside the runtime and is included in the chain. While other blockchain systems typically refer to these operations as "transactions," the Polkadot SDK adopts the broader term "extrinsic" to capture the wide variety of data types that can be added to a block. - -There are three primary types of transactions (extrinsics) in the Polkadot SDK: - -- **Signed transactions**: Signed by the submitting account, often carrying transaction fees. -- **Unsigned transactions**: Submitted without a signature, often requiring custom validation logic. -- **Inherent transactions**: Typically inserted directly into blocks by block authoring nodes, without gossiping between peers. - -Each type serves a distinct purpose, and understanding when and how to use each is key to efficiently working with the Polkadot SDK. - -### Signed Transactions - -Signed transactions require an account's signature and typically involve submitting a request to execute a runtime call. The signature serves as a form of cryptographic proof that the sender has authorized the action, using their private key. These transactions often involve a transaction fee to cover the cost of execution and incentivize block producers. - -Signed transactions are the most common type of transaction and are integral to user-driven actions, such as token transfers. For instance, when you transfer tokens from one account to another, the sending account must sign the transaction to authorize the operation. - -For example, the [`pallet_balances::Call::transfer_allow_death`](https://paritytech.github.io/polkadot-sdk/master/pallet_balances/pallet/struct.Pallet.html#method.transfer_allow_death){target=\_blank} extrinsic in the Balances pallet allows you to transfer tokens. Since your account initiates this transaction, your account key is used to sign it. You'll also be responsible for paying the associated transaction fee, with the option to include an additional tip to incentivize faster inclusion in the block. - -### Unsigned Transactions - -Unsigned transactions do not require a signature or account-specific data from the sender. Unlike signed transactions, they do not come with any form of economic deterrent, such as fees, which makes them susceptible to spam or replay attacks. Custom validation logic must be implemented to mitigate these risks and ensure these transactions are secure. - -Unsigned transactions typically involve scenarios where including a fee or signature is unnecessary or counterproductive. However, due to the absence of fees, they require careful validation to protect the network. For example, [`pallet_im_online::Call::heartbeat`](https://paritytech.github.io/polkadot-sdk/master/pallet_im_online/pallet/struct.Pallet.html#method.heartbeat){target=\_blank} extrinsic allows validators to send a heartbeat signal, indicating they are active. Since only validators can make this call, the logic embedded in the transaction ensures that the sender is a validator, making the need for a signature or fee redundant. - -Unsigned transactions are more resource-intensive than signed ones because custom validation is required, but they play a crucial role in certain operational scenarios, especially when regular user accounts aren't involved. - -### Inherent Transactions - -Inherent transactions are a specialized type of unsigned transaction that is used primarily for block authoring. Unlike signed or other unsigned transactions, inherent transactions are added directly by block producers and are not broadcasted to the network or stored in the transaction queue. They don't require signatures or the usual validation steps and are generally used to insert system-critical data directly into blocks. - -A key example of an inherent transaction is inserting a timestamp into each block. The [`pallet_timestamp::Call::now`](https://paritytech.github.io/polkadot-sdk/master/pallet_timestamp/pallet/struct.Pallet.html#method.now-1){target=\_blank} extrinsic allows block authors to include the current time in the block they are producing. Since the block producer adds this information, there is no need for transaction validation, like signature verification. The validation in this case is done indirectly by the validators, who check whether the timestamp is within an acceptable range before finalizing the block. - -Another example is the [`paras_inherent::Call::enter`](https://paritytech.github.io/polkadot-sdk/master/polkadot_runtime_parachains/paras_inherent/pallet/struct.Pallet.html#method.enter){target=\_blank} extrinsic, which enables parachain collator nodes to send validation data to the relay chain. This inherent transaction ensures that the necessary parachain data is included in each block without the overhead of gossiped transactions. - -Inherent transactions serve a critical role in block authoring by allowing important operational data to be added directly to the chain without needing the validation processes required for standard transactions. - -## Transaction Formats - -Understanding the structure of signed and unsigned transactions is crucial for developers building on Polkadot SDK-based chains. Whether you're optimizing transaction processing, customizing formats, or interacting with the transaction pool, knowing the format of extrinsics, Polkadot's term for transactions, is essential. - -### Types of Transaction Formats - -In Polkadot SDK-based chains, extrinsics can fall into three main categories: - -- **Unchecked extrinsics**: Typically used for signed transactions that require validation. They contain a signature and additional data, such as a nonce and information for fee calculation. Unchecked extrinsics are named as such because they require validation checks before being accepted into the transaction pool. -- **Checked extrinsics**: Typically used for inherent extrinsics (unsigned transactions); these don't require signature verification. Instead, they carry information such as where the extrinsic originates and any additional data required for the block authoring process. -- **Opaque extrinsics**: Used when the format of an extrinsic is not yet fully committed or finalized. They are still decodable, but their structure can be flexible depending on the context. - -### Signed Transaction Data Structure - -A signed transaction typically includes the following components: - -- **Signature**: Verifies the authenticity of the transaction sender. -- **Call**: The actual function or method call the transaction is requesting (for example, transferring funds). -- **Nonce**: Tracks the number of prior transactions sent from the account, helping to prevent replay attacks. -- **Tip**: An optional incentive to prioritize the transaction in block inclusion. -- **Additional data**: Includes details such as spec version, block hash, and genesis hash to ensure the transaction is valid within the correct runtime and chain context. - -Here's a simplified breakdown of how signed transactions are typically constructed in a Polkadot SDK runtime: - -``` code - + + -``` - -Each part of the signed transaction has a purpose, ensuring the transaction's authenticity and context within the blockchain. - -### Signed Extensions - -Polkadot SDK also provides the concept of [signed extensions](https://paritytech.github.io/polkadot-sdk/master/polkadot_sdk_docs/reference_docs/signed_extensions/index.html){target=\_blank}, which allow developers to extend extrinsics with additional data or validation logic before they are included in a block. The [`SignedExtension`](https://paritytech.github.io/try-runtime-cli/sp_runtime/traits/trait.SignedExtension.html){target=\_blank} set helps enforce custom rules or protections, such as ensuring the transaction's validity or calculating priority. - -The transaction queue regularly calls signed extensions to verify a transaction's validity before placing it in the ready queue. This safeguard ensures transactions won't fail in a block. Signed extensions are commonly used to enforce validation logic and protect the transaction pool from spam and replay attacks. - -In FRAME, a signed extension can hold any of the following types by default: - -- **[`AccountId`](https://paritytech.github.io/polkadot-sdk/master/polkadot_sdk_frame/runtime/types_common/type.AccountId.html){target=\_blank}**: To encode the sender's identity. -- **[`Call`](https://paritytech.github.io/polkadot-sdk/master/polkadot_sdk_frame/traits/trait.SignedExtension.html#associatedtype.Call){target=\_blank}**: To encode the pallet call to be dispatched. This data is used to calculate transaction fees. -- **[`AdditionalSigned`](https://paritytech.github.io/polkadot-sdk/master/polkadot_sdk_frame/traits/trait.SignedExtension.html#associatedtype.AdditionalSigned){target=\_blank}**: To handle any additional data to go into the signed payload allowing you to attach any custom logic prior to dispatching a transaction. -- **[`Pre`](https://paritytech.github.io/polkadot-sdk/master/polkadot_sdk_frame/traits/trait.SignedExtension.html#associatedtype.Pre){target=\_blank}**: To encode the information that can be passed from before a call is dispatched to after it gets dispatched. - -Signed extensions can enforce checks like: - -- **[`CheckSpecVersion`](https://paritytech.github.io/polkadot-sdk/master/src/frame_system/extensions/check_spec_version.rs.html){target=\_blank}**: Ensures the transaction is compatible with the runtime's current version. -- **[`CheckWeight`](https://paritytech.github.io/polkadot-sdk/master/frame_system/struct.CheckWeight.html){target=\_blank}**: Calculates the weight (or computational cost) of the transaction, ensuring the block doesn't exceed the maximum allowed weight. - -These extensions are critical in the transaction lifecycle, ensuring that only valid and prioritized transactions are processed. - -## Transaction Construction - -Building transactions in the Polkadot SDK involves constructing a payload that can be verified, signed, and submitted for inclusion in a block. Each runtime in the Polkadot SDK has its own rules for validating and executing transactions, but there are common patterns for constructing a signed transaction. - -### Construct a Signed Transaction - -A signed transaction in the Polkadot SDK includes various pieces of data to ensure security, prevent replay attacks, and prioritize processing. Here's an overview of how to construct one: - -1. **Construct the unsigned payload**: Gather the necessary information for the call, including: - - - **Pallet index**: Identifies the pallet where the runtime function resides. - - **Function index**: Specifies the particular function to call in the pallet. - - **Parameters**: Any additional arguments required by the function call. - -2. **Create a signing payload**: Once the unsigned payload is ready, additional data must be included: - - - **Transaction nonce**: Unique identifier to prevent replay attacks. - - **Era information**: Defines how long the transaction is valid before it's dropped from the pool. - - **Block hash**: Ensures the transaction doesn't execute on the wrong chain or fork. - -3. **Sign the payload**: Using the sender's private key, sign the payload to ensure that the transaction can only be executed by the account holder. -4. **Serialize the signed payload**: Once signed, the transaction must be serialized into a binary format, ensuring the data is compact and easy to transmit over the network. -5. **Submit the serialized transaction**: Finally, submit the serialized transaction to the network, where it will enter the transaction pool and wait for processing by an authoring node. - -The following is an example of how a signed transaction might look: - -``` rust -node_runtime::UncheckedExtrinsic::new_signed( - function.clone(), // some call - sp_runtime::AccountId32::from(sender.public()).into(), // some sending account - node_runtime::Signature::Sr25519(signature.clone()), // the account's signature - extra.clone(), // the signed extensions -) -``` - -### Transaction Encoding +# Smart Contracts Cookbook -Before a transaction is sent to the network, it is serialized and encoded using a structured encoding process that ensures consistency and prevents tampering: +Welcome to the Polkadot smart contracts cookbook index. -- **`[1]`**: Compact encoded length in bytes of the entire transaction. -- **`[2]`**: A u8 containing 1 byte to indicate whether the transaction is signed or unsigned (1 bit) and the encoded transaction version ID (7 bits). -- **`[3]`**: If signed, this field contains an account ID, an SR25519 signature, and some extra data. -- **`[4]`**: Encoded call data, including pallet and function indices and any required arguments. +This page contains a list of all relevant tutorials and guides to help you get started coding smart contracts and dApps in Polkadot. -This encoded format ensures consistency and efficiency in processing transactions across the network. By adhering to this format, applications can construct valid transactions and pass them to the network for execution. -To learn more about how compact encoding works using SCALE, see the [SCALE Codec](https://github.com/paritytech/parity-scale-codec){target=\_blank} README on GitHub. -### Customize Transaction Construction -Although the basic steps for constructing transactions are consistent across Polkadot SDK-based chains, developers can customize transaction formats and validation rules. For example: +## Get Tokens from the Faucet -- **Custom pallets**: You can define new pallets with custom function calls, each with its own parameters and validation logic. -- **Signed extensions**: Developers can implement custom extensions that modify how transactions are prioritized, validated, or included in blocks. +| Title | Difficulty | Tools | Description | +|------------------------------------|:-----------:|-------|-----------------------------------------------------------------------------------------------------------------------| +| [Faucet](/smart-contracts/faucet/) | 🟢 Beginner | N/A | Learn how to obtain test tokens from Polkadot faucets for development and testing purposes across different networks. | -By leveraging Polkadot SDK's modular design, developers can create highly specialized transaction logic tailored to their chain's needs. +## EVM Smart Contracts -## Lifecycle of a Transaction +| Title | Difficulty | Tools | Description | +|---------------------------------------------------------------------------------------------------------|:-----------:|--------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------| +| [Deploy an ERC-20 to Polkadot Hub](/smart-contracts/cookbook/smart-contracts/deploy-erc20/erc20-remix/) | 🟢 Beginner | EVM Wallet, Polkadot Remix IDE | Deploy an ERC-20 token on Polkadot Hub using PolkaVM. This guide covers contract creation, compilation, deployment, and interaction via Polkadot Remix IDE. | +| [Deploy an NFT to Polkadot Hub](/smart-contracts/cookbook/smart-contracts/deploy-nft/nft-remix/) | 🟢 Beginner | EVM Wallet, Polkadot Remix IDE | Deploy an NFT on Polkadot Hub using PolkaVM and OpenZeppelin. Learn how to compile, deploy, and interact with your contract using Polkadot Remix IDE. | -In the Polkadot SDK, transactions are often referred to as extrinsics because the data in transactions originates outside of the runtime. These transactions contain data that initiates changes to the chain state. The most common type of extrinsic is a signed transaction, which is cryptographically verified and typically incurs a fee. This section focuses on how signed transactions are processed, validated, and ultimately included in a block. +## Port Ethereum DApps -### Define Transaction Properties +| Title | Difficulty | Tools | Description | +|-------------------------------------------------------------------------------------|:---------------:|---------|----------------------------------------------------------------------------------------------------------------------------------| +| [Deploying Uniswap V2 on Polkadot](/smart-contracts/cookbook/eth-dapps/uniswap-v2/) | 🟡 Intermediate | Hardhat | Learn how to deploy and test Uniswap V2 on Polkadot Hub using Hardhat, bringing AMM-based token swaps to the Polkadot ecosystem. | -The Polkadot SDK runtime defines key transaction properties, such as: -- **Transaction validity**: Ensures the transaction meets all runtime requirements. -- **Signed or unsigned**: Identifies whether a transaction needs to be signed by an account. -- **State changes**: Determines how the transaction modifies the state of the chain. +--- -Pallets, which compose the runtime's logic, define the specific transactions that your chain supports. When a user submits a transaction, such as a token transfer, it becomes a signed transaction, verified by the user's account signature. If the account has enough funds to cover fees, the transaction is executed, and the chain's state is updated accordingly. +Page Title: Smart Contracts Overview -### Process on a Block Authoring Node +- Source (raw): https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/smart-contracts-overview.md +- Canonical (HTML): https://docs.polkadot.com/smart-contracts/overview/ +- Summary: Learn about smart contract development on Polkadot Hub with native PolkaVM support, dual-VM execution, and seamless cross-chain capabilities. -In Polkadot SDK-based networks, some nodes are authorized to author blocks. These nodes validate and process transactions. When a transaction is sent to a node that can produce blocks, it undergoes a lifecycle that involves several stages, including validation and execution. Non-authoring nodes gossip the transaction across the network until an authoring node receives it. The following diagram illustrates the lifecycle of a transaction that's submitted to a network and processed by an authoring node. +# Smart Contracts on Polkadot Hub -![Transaction lifecycle diagram](/images/reference/parachains/blocks-transactions-fees/transactions/transactions-01.webp){ style="background:white" } +## Introduction -### Validate and Queue +Polkadot Hub provides a production-ready smart contract platform that combines Ethereum compatibility with the performance and cross-chain capabilities of the Polkadot ecosystem. Developers can deploy smart contracts directly on Polkadot Hub while using familiar Ethereum tooling, workflows, and programming languages. -Once a transaction reaches an authoring node, it undergoes an initial validation process to ensure it meets specific conditions defined in the runtime. This validation includes checks for: +Built with a dual-VM approach, Polkadot Hub offers two execution backends: REVM for unmodified EVM compatibility and native PolkaVM for optimized computationally expensive workloads. This dual-VM architecture enables developers to migrate existing Ethereum contracts instantly or optimize for speed and efficiency with native execution. -- **Correct nonce**: Ensures the transaction is sequentially valid for the account. -- **Sufficient funds**: Confirms the account can cover any associated transaction fees. -- **Signature validity**: Verifies that the sender's signature matches the transaction data. +## Why Build on Polkadot Hub -After these checks, valid transactions are placed in the transaction pool, where they are queued for inclusion in a block. The transaction pool regularly re-validates queued transactions to ensure they remain valid before being processed. To reach consensus, two-thirds of the nodes must agree on the order of the transactions executed and the resulting state change. Transactions are validated and queued on the local node in a transaction pool to prepare for consensus. +### Ethereum Compatibility -#### Transaction Pool +Deploy existing Ethereum contracts with zero modifications while maintaining full compatibility with your existing development stack: -The transaction pool is responsible for managing valid transactions. It ensures that only transactions that pass initial validity checks are queued. Transactions that fail validation, expire, or become invalid for other reasons are removed from the pool. +- **Complete JSON-RPC API support**: Use MetaMask, Hardhat, Remix, Foundry, and all standard Ethereum tooling. +- **Standard libraries**: Integrate Ethers.js, Web3.js, Viem, Wagmi, and Web3.py without changes. +- **Solidity development**: Write contracts in Solidity or migrate existing code directly. +- **Familiar workflows**: Maintain your existing deployment, testing, and monitoring processes. -The transaction pool organizes transactions into two queues: +### Performance Options -- **Ready queue**: Transactions that are valid and ready to be included in a block. -- **Future queue**: Transactions that are not yet valid but could be in the future, such as transactions with a nonce too high for the current state. +Choose between two execution backends: -Details on how the transaction pool validates transactions, including fee and signature handling, can be found in the [`validate_transaction`](https://paritytech.github.io/polkadot-sdk/master/sp_transaction_pool/runtime_api/trait.TaggedTransactionQueue.html#method.validate_transaction){target=\_blank} method. +- **REVM**: Run unmodified Ethereum contracts with full EVM/Ethereum compatibility. +- **PolkaVM**: Compile to optimized RISC-V bytecode for enhanced performance and lower fees while keeping Ethereum-compatibility. -#### Invalid Transactions +Both backends share the same RPC interface and tooling support, allowing seamless transitions. In addition, smart contracts can interact with Polkadot native services via [precompile contracts](/smart-contracts/precompiles/){target=\_blank}. -If a transaction is invalid, for example, due to an invalid signature or insufficient funds, it is rejected and won't be added to the block. Invalid transactions might be rejected for reasons such as: +### Cross-VM & Cross-Chain Capabilities -- The transaction has already been included in a block. -- The transaction's signature does not match the sender. -- The transaction is too large to fit in the current block. +Smart contracts written for one VM (for example, EVM) can interact directly with other smart contracts written for the RISC-V PolkaVM, and back. This allows to use full EVM compatible contracts but extend to heavy/complex execution workloads to the PolkaVM RISC-V backend. -### Transaction Ordering and Priority +Furthermore, all smart contracts in Polkadot Hub can interact with any service in the Polkadot ecosystem through [XCM](/smart-contracts/precompiles/xcm/){target=\_blank}, enabling token transfers, remote execution, and cross-chain composability without bridges or intermediaries. -When a node is selected as the next block author, it prioritizes transactions based on weight, length, and tip amount. The goal is to fill the block with high-priority transactions without exceeding its maximum size or computational limits. Transactions are ordered as follows: +## Other Smart Contract Environments -- **Inherents first**: Inherent transactions, such as block timestamp updates, are always placed first. -- **Nonce-based ordering**: Transactions from the same account are ordered by their nonce. -- **Fee-based ordering**: Among transactions with the same nonce or priority level, those with higher fees are prioritized. +Beyond Polkadot Hub's native PolkaVM support, the ecosystem offers two main alternatives for smart contract development: -### Transaction Execution +- **EVM-compatible parachains**: Provide access to Ethereum's extensive developer ecosystem, smart contract portability, and established tooling like Hardhat, Remix, Foundry, and OpenZeppelin. The main options include Moonbeam (the first full Ethereum-compatible parachain serving as an interoperability hub), Astar (featuring dual VM support for both EVM and WebAssembly contracts), and Acala (DeFi-focused with enhanced Acala EVM+ offering advanced DeFi primitives). -Once a block author selects transactions from the pool, the transactions are executed in priority order. As each transaction is processed, the state changes are written directly to the chain's storage. It's important to note that these changes are not cached, meaning a failed transaction won't revert earlier state changes, which could leave the block in an inconsistent state. +- **Rust (ink!)**: ink! is a Rust-based framework that can compile to PolkaVM. It uses [`#[ink(...)]`](https://use.ink/docs/v6/macros-attributes/){target=\_blank} attribute macros to create Polkadot SDK-compatible PolkaVM bytecode, offering strong memory safety from Rust, an advanced type system, high-performance PolkaVM execution, and platform independence with sandboxed security. -Events are also written to storage. Runtime logic should not emit an event before performing the associated actions. If the associated transaction fails after the event was emitted, the event will not revert. +## Next Steps -## Transaction Mortality +
-Transactions in the network can be configured as either mortal (with expiration) or immortal (without expiration). Every transaction payload contains a block checkpoint (reference block number and hash) and an era/validity period that determines how many blocks after the checkpoint the transaction remains valid. +- Guide __Get Started__ -When a transaction is submitted, the network validates it against these parameters. If the transaction is not included in a block within the specified validity window, it is automatically removed from the transaction queue. + --- -- **Mortal transactions**: Have a finite lifespan and will expire after a specified number of blocks. For example, a transaction with a block checkpoint of 1000 and a validity period of 64 blocks will be valid from blocks 1000 to 1064. + Quick-start guides for connecting, deploying, and building your first smart contract. -- **Immortal transactions**: Never expire and remain valid indefinitely. To create an immortal transaction, set the block checkpoint to 0 (genesis block), use the genesis hash as a reference, and set the validity period to 0. + [:octicons-arrow-right-24: Get Started](/smart-contracts/get-started/) -However, immortal transactions pose significant security risks through replay attacks. If an account is reaped (balance drops to zero, account removed) and later re-funded, malicious actors can replay old immortal transactions. +- Guide __Cookbook__ -The blockchain maintains only a limited number of prior block hashes for reference validation, called `BlockHashCount`. If your validity period exceeds `BlockHashCount`, the effective validity period becomes the minimum of your specified period and the block hash count. + --- -## Unique Identifiers for Extrinsics + Step-by-step tutorials for deploying contracts, tokens, NFTs, and full dApps. -Transaction hashes are **not unique identifiers** in Polkadot SDK-based chains. + [:octicons-arrow-right-24: View Tutorials](/smart-contracts/cookbook/) -Key differences from traditional blockchains: +- Guide __Ethereum Developers__ -- Transaction hashes serve only as fingerprints of transaction information. -- Multiple valid transactions can share the same hash. -- Hash uniqueness assumptions lead to serious issues. + --- -For example, when an account is reaped (removed due to insufficient balance) and later recreated, it resets to nonce 0, allowing identical transactions to be valid at different points: + Understand key differences in accounts, fees, gas model, and deployment on Polkadot Hub. -| Block | Extrinsic Index | Hash | Origin | Nonce | Call | Result | -|-------|----------------|------|-----------|-------|---------------------|-------------------------------| -| 100 | 0 | 0x01 | Account A | 0 | Transfer 5 DOT to B | Account A reaped | -| 150 | 5 | 0x02 | Account B | 4 | Transfer 7 DOT to A | Account A created (nonce = 0) | -| 200 | 2 | 0x01 | Account A | 0 | Transfer 5 DOT to B | Successful transaction | + [:octicons-arrow-right-24: Learn More](/smart-contracts/for-eth-devs/accounts/) -Notice that blocks 100 and 200 contain transactions with identical hashes (0x01) but are completely different, valid operations occurring at different times. +- Guide __Precompiles__ -Additional complexity comes from Polkadot SDK's origin abstraction. Origins can represent collectives, governance bodies, or other non-account entities that don't maintain nonces like regular accounts and might dispatch identical calls multiple times with the same hash values. Each execution occurs in different chain states with different results. + --- -The correct way to uniquely identify an extrinsic on a Polkadot SDK-based chain is to use the block ID (height or hash) and the extrinsic index. Since the Polkadot SDK defines blocks as headers plus ordered arrays of extrinsics, the index position within a canonical block provides guaranteed uniqueness. + Discover advanced functionalities including XCM for cross-chain interactions. -## Additional Resources + [:octicons-arrow-right-24: Explore Precompiles](/smart-contracts/precompiles/) -For a video overview of the lifecycle of transactions and the types of transactions that exist, see the [Transaction lifecycle](https://www.youtube.com/watch?v=3pfM0GOp02c){target=\_blank} seminar from Parity Tech. +
--- @@ -5802,436 +3280,3 @@ The system maintains precise conversion mechanisms between: - Different resource metrics within the multi-dimensional model. This ensures accurate fee calculation while maintaining compatibility with existing Ethereum tools and workflows. - - ---- - -Page Title: Transactions Weights and Fees - -- Source (raw): https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/reference-parachains-blocks-transactions-fees-fees.md -- Canonical (HTML): https://docs.polkadot.com/reference/parachains/blocks-transactions-fees/fees/ -- Summary: Overview of transaction weights and fees in Polkadot SDK chains, detailing how fees are calculated using a defined formula and runtime specifics. - -# Transactions Weights and Fees - -## Introductions - -When transactions are executed, or data is stored on-chain, the activity changes the chain's state and consumes blockchain resources. Because the resources available to a blockchain are limited, managing how operations on-chain consume them is important. In addition to being limited in practical terms, such as storage capacity, blockchain resources represent a potential attack vector for malicious users. For example, a malicious user might attempt to overload the network with messages to stop the network from producing new blocks. To protect blockchain resources from being drained or overloaded, you need to manage how they are made available and how they are consumed. The resources to be aware of include: - -- Memory usage -- Storage input and output -- Computation -- Transaction and block size -- State database size - -The Polkadot SDK provides block authors with several ways to manage access to resources and to prevent individual components of the chain from consuming too much of any single resource. Two of the most important mechanisms available to block authors are weights and transaction fees. - -[Weights](/reference/glossary/#weight){target=\_blank} manage the time it takes to validate a block and characterize the time it takes to execute the calls in the block's body. By controlling the execution time a block can consume, weights set limits on storage input, output, and computation. - -Some of the weight allowed for a block is consumed as part of the block's initialization and finalization. The weight might also be used to execute mandatory inherent extrinsic calls. To help ensure blocks don’t consume too much execution time and prevent malicious users from overloading the system with unnecessary calls, weights are combined with transaction fees. - -[Transaction fees](/reference/parachains/blocks-transactions-fees/transactions/#transaction-fees){target=\_blank} provide an economic incentive to limit execution time, computation, and the number of calls required to perform operations. Transaction fees are also used to make the blockchain economically sustainable because they are typically applied to transactions initiated by users and deducted before a transaction request is executed. - -## How Fees are Calculated - -The final fee for a transaction is calculated using the following parameters: - -- **`base fee`**: This is the minimum amount a user pays for a transaction. It is declared a base weight in the runtime and converted to a fee using the [`WeightToFee`](https://docs.rs/pallet-transaction-payment/latest/pallet_transaction_payment/pallet/trait.Config.html#associatedtype.WeightToFee){target=\_blank} conversion. -- **`weight fee`**: A fee proportional to the execution time (input and output and computation) that a transaction consumes. -- **`length fee`**: A fee proportional to the encoded length of the transaction. -- **`tip`**: An optional tip to increase the transaction’s priority, giving it a higher chance to be included in the transaction queue. - -The base fee and proportional weight and length fees constitute the inclusion fee. The inclusion fee is the minimum fee that must be available for a transaction to be included in a block. - -```text -inclusion fee = base fee + weight fee + length fee -``` - -Transaction fees are withdrawn before the transaction is executed. After the transaction is executed, the weight can be adjusted to reflect the resources used. If a transaction uses fewer resources than expected, the transaction fee is corrected, and the adjusted transaction fee is deposited. - -## Using the Transaction Payment Pallet - -The [Transaction Payment pallet](https://github.com/paritytech/polkadot-sdk/tree/polkadot-stable2506-2/substrate/frame/transaction-payment){target=\_blank} provides the basic logic for calculating the inclusion fee. You can also use the Transaction Payment pallet to: - -- Convert a weight value into a deductible fee based on a currency type using [`Config::WeightToFee`](https://docs.rs/pallet-transaction-payment/latest/pallet_transaction_payment/pallet/trait.Config.html#associatedtype.WeightToFee){target=\_blank}. -- Update the fee for the next block by defining a multiplier based on the chain’s final state at the end of the previous block using [`Config::FeeMultiplierUpdate`](https://docs.rs/pallet-transaction-payment/latest/pallet_transaction_payment/pallet/trait.Config.html#associatedtype.FeeMultiplierUpdate){target=\_blank}. -- Manage the withdrawal, refund, and deposit of transaction fees using [`Config::OnChargeTransaction`](https://docs.rs/pallet-transaction-payment/latest/pallet_transaction_payment/pallet/trait.Config.html#associatedtype.OnChargeTransaction){target=\_blank}. - -You can learn more about these configuration traits in the [Transaction Payment documentation](https://paritytech.github.io/polkadot-sdk/master/pallet_transaction_payment/index.html){target=\_blank}. - -### Understanding the Inclusion Fee - -The formula for calculating the inclusion fee is as follows: - -```text -inclusion_fee = base_fee + length_fee + [targeted_fee_adjustment * weight_fee] -``` - -And then, for calculating the final fee: - -```text -final_fee = inclusion_fee + tip -``` - -In the first formula, the `targeted_fee_adjustment` is a multiplier that can tune the final fee based on the network’s congestion. - -- The `base_fee` derived from the base weight covers inclusion overhead like signature verification. -- The `length_fee` is a per-byte fee that is multiplied by the length of the encoded extrinsic. -- The `weight_fee` fee is calculated using two parameters: - - The `ExtrinsicBaseWeight` that is declared in the runtime and applies to all extrinsics. - - The `#[pallet::weight]` annotation that accounts for an extrinsic's complexity. - -To convert the weight to `Currency`, the runtime must define a `WeightToFee` struct that implements a conversion function, [`Convert`](https://docs.rs/pallet-transaction-payment/latest/pallet_transaction_payment/pallet/struct.Pallet.html#method.weight_to_fee){target=\_blank}. - -Note that the extrinsic sender is charged the inclusion fee before the extrinsic is invoked. The fee is deducted from the sender's balance even if the transaction fails upon execution. - -### Accounts with an Insufficient Balance - -If an account does not have a sufficient balance to pay the inclusion fee and remain alive—that is, enough to pay the inclusion fee and maintain the minimum existential deposit—then you should ensure the transaction is canceled so that no fee is deducted and the transaction does not begin execution. - -The Polkadot SDK doesn't enforce this rollback behavior. However, this scenario would be rare because the transaction queue and block-making logic perform checks to prevent it before adding an extrinsic to a block. - -### Fee Multipliers - -The inclusion fee formula always results in the same fee for the same input. However, weight can be dynamic and—based on how [`WeightToFee`](https://docs.rs/pallet-transaction-payment/latest/pallet_transaction_payment/pallet/trait.Config.html#associatedtype.WeightToFee){target=\_blank} is defined—the final fee can include some degree of variability. -The Transaction Payment pallet provides the [`FeeMultiplierUpdate`](https://docs.rs/pallet-transaction-payment/latest/pallet_transaction_payment/pallet/trait.Config.html#associatedtype.FeeMultiplierUpdate){target=\_blank} configurable parameter to account for this variability. - -The Polkadot network inspires the default update function and implements a targeted adjustment in which a target saturation level of block weight is defined. If the previous block is more saturated, the fees increase slightly. Similarly, if the last block has fewer transactions than the target, fees are decreased by a small amount. For more information about fee multiplier adjustments, see the [Web3 Research Page](https://research.web3.foundation/Polkadot/overview/token-economics#relay-chain-transaction-fees-and-per-block-transaction-limits){target=\_blank}. - -## Transactions with Special Requirements - -Inclusion fees must be computable before execution and can only represent fixed logic. Some transactions warrant limiting resources with other strategies. For example: - -- Bonds are a type of fee that might be returned or slashed after some on-chain event. For example, you might want to require users to place a bond to participate in a vote. The bond might then be returned at the end of the referendum or slashed if the voter attempted malicious behavior. -- Deposits are fees that might be returned later. For example, you might require users to pay a deposit to execute an operation that uses storage. The user’s deposit could be returned if a subsequent operation frees up storage. -- Burn operations are used to pay for a transaction based on its internal logic. For example, a transaction might burn funds from the sender if the transaction creates new storage items to pay for the increased state size. -- Limits enable you to enforce constant or configurable limits on specific operations. For example, the default [Staking pallet](https://github.com/paritytech/polkadot-sdk/tree/polkadot-stable2506-2/substrate/frame/staking){target=\_blank} only allows nominators to nominate 16 validators to limit the complexity of the validator election process. - -It is important to note that if you query the chain for a transaction fee, it only returns the inclusion fee. - -## Default Weight Annotations - -All dispatchable functions in the Polkadot SDK must specify a weight. The way of doing that is using the annotation-based system that lets you combine fixed values for database read/write weight and/or fixed values based on benchmarks. The most basic example would look like this: - -```rust -#[pallet::weight(100_000)] -fn my_dispatchable() { - // ... -} -``` - -Note that the [`ExtrinsicBaseWeight`](https://crates.parity.io/frame_support/weights/constants/struct.ExtrinsicBaseWeight.html){target=\_blank} is automatically added to the declared weight to account for the costs of simply including an empty extrinsic into a block. - -### Weights and Database Read/Write Operations - -To make weight annotations independent of the deployed database backend, they are defined as a constant and then used in the annotations when expressing database accesses performed by the dispatchable: - -```rust -#[pallet::weight(T::DbWeight::get().reads_writes(1, 2) + 20_000)] -fn my_dispatchable() { - // ... -} -``` - -This dispatchable allows one database to read and two to write, in addition to other things that add the additional 20,000. Database access is generally every time a value declared inside the [`#[pallet::storage]`](https://paritytech.github.io/polkadot-sdk/master/frame_support/pallet_macros/attr.storage.html){target=\_blank} block is accessed. However, unique accesses are counted because after a value is accessed, it is cached, and reaccessing it does not result in a database operation. That is: - -- Multiple reads of the exact value count as one read. -- Multiple writes of the exact value count as one write. -- Multiple reads of the same value, followed by a write to that value, count as one read and one write. -- A write followed by a read-only counts as one write. - -### Dispatch Classes - -Dispatches are broken into three classes: - -- Normal -- Operational -- Mandatory - -If a dispatch is not defined as `Operational` or `Mandatory` in the weight annotation, the dispatch is identified as `Normal` by default. You can specify that the dispatchable uses another class like this: - -```rust -#[pallet::dispatch((DispatchClass::Operational))] -fn my_dispatchable() { - // ... -} -``` - -This tuple notation also allows you to specify a final argument determining whether the user is charged based on the annotated weight. If you don't specify otherwise, `Pays::Yes` is assumed: - -```rust -#[pallet::dispatch(DispatchClass::Normal, Pays::No)] -fn my_dispatchable() { - // ... -} -``` - -#### Normal Dispatches - -Dispatches in this class represent normal user-triggered transactions. These types of dispatches only consume a portion of a block's total weight limit. For information about the maximum portion of a block that can be consumed for normal dispatches, see [`AvailableBlockRatio`](https://paritytech.github.io/polkadot-sdk/master/frame_system/limits/struct.BlockLength.html){target=\_blank}. Normal dispatches are sent to the transaction pool. - -#### Operational Dispatches - -Unlike normal dispatches, which represent the usage of network capabilities, operational dispatches are those that provide network capabilities. Operational dispatches can consume the entire weight limit of a block. They are not bound by the [`AvailableBlockRatio`](https://paritytech.github.io/polkadot-sdk/master/frame_system/limits/struct.BlockLength.html){target=\_blank}. Dispatches in this class are given maximum priority and are exempt from paying the [`length_fee`](https://docs.rs/pallet-transaction-payment/latest/pallet_transaction_payment/){target=\_blank}. - -#### Mandatory Dispatches - -Mandatory dispatches are included in a block even if they cause the block to surpass its weight limit. You can only use the mandatory dispatch class for inherent transactions that the block author submits. This dispatch class is intended to represent functions in the block validation process. Because these dispatches are always included in a block regardless of the function weight, the validation process must prevent malicious nodes from abusing the function to craft valid but impossibly heavy blocks. You can typically accomplish this by ensuring that: - -- The operation performed is always light. -- The operation can only be included in a block once. - -To make it more difficult for malicious nodes to abuse mandatory dispatches, they cannot be included in blocks that return errors. This dispatch class serves the assumption that it is better to allow an overweight block to be created than not to allow any block to be created at all. - -### Dynamic Weights - -In addition to purely fixed weights and constants, the weight calculation can consider the input arguments of a dispatchable. The weight should be trivially computable from the input arguments with some basic arithmetic: - -```rust -use frame_support:: { - dispatch:: { - DispatchClass::Normal, - Pays::Yes, - }, - weights::Weight, -}; - -#[pallet::weight(FunctionOf( - |args: (&Vec,)| args.0.len().saturating_mul(10_000), - ) -] -fn handle_users(origin, calls: Vec) { - // Do something per user -} -``` - -## Post Dispatch Weight Correction - -Depending on the execution logic, a dispatchable function might consume less weight than was prescribed pre-dispatch. To correct weight, the function declares a different return type and returns its actual weight: - -```rust -#[pallet::weight(10_000 + 500_000_000)] -fn expensive_or_cheap(input: u64) -> DispatchResultWithPostInfo { - let was_heavy = do_calculation(input); - - if (was_heavy) { - // None means "no correction" from the weight annotation. - Ok(None.into()) - } else { - // Return the actual weight consumed. - Ok(Some(10_000).into()) - } -} -``` - -## Custom Fees - -You can also define custom fee systems through custom weight functions or inclusion fee functions. - -### Custom Weights - -Instead of using the default weight annotations, you can create a custom weight calculation type using the weights module. The custom weight calculation type must implement the following traits: - -- [`WeighData`](https://crates.parity.io/frame_support/weights/trait.WeighData.html){target=\_blank} to determine the weight of the dispatch. -- [`ClassifyDispatch`](https://crates.parity.io/frame_support/weights/trait.ClassifyDispatch.html){target=\_blank} to determine the class of the dispatch. -- [`PaysFee`](https://crates.parity.io/frame_support/weights/trait.PaysFee.html){target=\_blank} to determine whether the sender of the dispatch pays fees. - -The Polkadot SDK then bundles the output information of the three traits into the [`DispatchInfo`](https://paritytech.github.io/polkadot-sdk/master/frame_support/dispatch/struct.DispatchInfo.html){target=\_blank} struct and provides it by implementing the [`GetDispatchInfo`](https://docs.rs/frame-support/latest/frame_support/dispatch/trait.GetDispatchInfo.html){target=\_blank} for all `Call` variants and opaque extrinsic types. This is used internally by the System and Executive modules. - -`ClassifyDispatch`, `WeighData`, and `PaysFee` are generic over T, which gets resolved into the tuple of all dispatch arguments except for the origin. The following example illustrates a struct that calculates the weight as `m * len(args)`, where `m` is a given multiplier and args is the concatenated tuple of all dispatch arguments. In this example, the dispatch class is `Operational` if the transaction has more than 100 bytes of length in arguments and will pay fees if the encoded length exceeds 10 bytes. - -```rust -struct LenWeight(u32); -impl WeighData for LenWeight { - fn weigh_data(&self, target: T) -> Weight { - let multiplier = self.0; - let encoded_len = target.encode().len() as u32; - multiplier * encoded_len - } -} - -impl ClassifyDispatch for LenWeight { - fn classify_dispatch(&self, target: T) -> DispatchClass { - let encoded_len = target.encode().len() as u32; - if encoded_len > 100 { - DispatchClass::Operational - } else { - DispatchClass::Normal - } - } -} - -impl PaysFee { - fn pays_fee(&self, target: T) -> Pays { - let encoded_len = target.encode().len() as u32; - if encoded_len > 10 { - Pays::Yes - } else { - Pays::No - } - } -} -``` - -A weight calculator function can also be coerced to the final type of the argument instead of defining it as a vague type that can be encoded. The code would roughly look like this: - -```rust -struct CustomWeight; -impl WeighData<(&u32, &u64)> for CustomWeight { - fn weigh_data(&self, target: (&u32, &u64)) -> Weight { - ... - } -} - -// given a dispatch: -#[pallet::call] -impl, I: 'static> Pallet { - #[pallet::weight(CustomWeight)] - fn foo(a: u32, b: u64) { ... } -} -``` - -In this example, the `CustomWeight` can only be used in conjunction with a dispatch with a particular signature `(u32, u64)`, as opposed to `LenWeight`, which can be used with anything because there aren't any assumptions about ``. - -#### Custom Inclusion Fee - -The following example illustrates how to customize your inclusion fee. You must configure the appropriate associated types in the respective module. - -```rust -// Assume this is the balance type -type Balance = u64; - -// Assume we want all the weights to have a `100 + 2 * w` conversion to fees -struct CustomWeightToFee; -impl WeightToFee for CustomWeightToFee { - fn convert(w: Weight) -> Balance { - let a = Balance::from(100); - let b = Balance::from(2); - let w = Balance::from(w); - a + b * w - } -} - -parameter_types! { - pub const ExtrinsicBaseWeight: Weight = 10_000_000; -} - -impl frame_system::Config for Runtime { - type ExtrinsicBaseWeight = ExtrinsicBaseWeight; -} - -parameter_types! { - pub const TransactionByteFee: Balance = 10; -} - -impl transaction_payment::Config { - type TransactionByteFee = TransactionByteFee; - type WeightToFee = CustomWeightToFee; - type FeeMultiplierUpdate = TargetedFeeAdjustment; -} - -struct TargetedFeeAdjustment(sp_std::marker::PhantomData); -impl> WeightToFee for TargetedFeeAdjustment { - fn convert(multiplier: Fixed128) -> Fixed128 { - // Don't change anything. Put any fee update info here. - multiplier - } -} -``` - -## Additional Resources - -You now know the weight system, how it affects transaction fee computation, and how to specify weights for your dispatchable calls. The next step is determining the correct weight for your dispatchable operations. You can use Substrate benchmarking functions and frame-benchmarking calls to test your functions with different parameters and empirically determine the proper weight in their worst-case scenarios. - -- [Benchmark](/parachains/customize-runtime/pallet-development/benchmark-pallet/) -- [`SignedExtension`](https://paritytech.github.io/polkadot-sdk/master/sp_runtime/traits/trait.SignedExtension.html){target=\_blank} -- [Custom weights for the Example pallet](https://github.com/paritytech/polkadot-sdk/blob/polkadot-stable2506-2/substrate/frame/examples/basic/src/weights.rs){target=\_blank} -- [Web3 Foundation Research](https://research.web3.foundation/Polkadot/overview/token-economics#relay-chain-transaction-fees-and-per-block-transaction-limits){target=\_blank} - - ---- - -Page Title: XCM Tools - -- Source (raw): https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/reference-tools-xcm-tools.md -- Canonical (HTML): https://docs.polkadot.com/reference/tools/xcm-tools/ -- Summary: Explore essential XCM tools across Polkadot, crafted to enhance cross-chain functionality and integration within the ecosystem. - -# XCM Tools - -## Introduction - -As described in the [Interoperability](/develop/interoperability){target=\_blank} section, XCM (Cross-Consensus Messaging) is a protocol used in the Polkadot and Kusama ecosystems to enable communication and interaction between chains. It facilitates cross-chain communication, allowing assets, data, and messages to flow seamlessly across the ecosystem. - -As XCM is central to enabling communication between blockchains, developers need robust tools to help interact with, build, and test XCM messages. Several XCM tools simplify working with the protocol by providing libraries, frameworks, and utilities that enhance the development process, ensuring that applications built within the Polkadot ecosystem can efficiently use cross-chain functionalities. - -## Popular XCM Tools - -### Moonsong Labs XCM Tools - -[Moonsong Labs XCM Tools](https://github.com/Moonsong-Labs/xcm-tools){target=\_blank} provides a collection of scripts for managing and testing XCM operations between Polkadot SDK-based runtimes. These tools allow performing tasks like asset registration, channel setup, and XCM initialization. Key features include: - -- **Asset registration**: Registers assets, setting units per second (up-front fees), and configuring error (revert) codes. -- **XCM initializer**: Initializes XCM, sets default XCM versions, and configures revert codes for XCM-related precompiles. -- **HRMP manipulator**: Manages HRMP channel actions, including opening, accepting, or closing channels. -- **XCM-Transactor-Info-Setter**: Configures transactor information, including extra weight and fee settings. -- **Decode XCM**: Decodes XCM messages on the relay chain or parachains to help interpret cross-chain communication. - -To get started, clone the repository and install the required dependencies: - -```bash -git clone https://github.com/Moonsong-Labs/xcm-tools && -cd xcm-tools && -yarn install -``` - -For a full overview of each script, visit the [scripts](https://github.com/Moonsong-Labs/xcm-tools/tree/main/scripts){target=\_blank} directory or refer to the [official documentation](https://github.com/Moonsong-Labs/xcm-tools/blob/main/README.md){target=\_blank} on GitHub. - -### ParaSpell - -[ParaSpell](/reference/tools/paraspell/){target=\_blank} is a collection of open-source XCM tools that streamline cross-chain asset transfers and interactions across the Polkadot and Kusama ecosystems. It provides developers with an intuitive interface to build, test, and deploy interoperable dApps, featuring message composition, decoding, and practical utilities for parachain interactions that simplify debugging and cross-chain communication optimization. - -### Astar XCM Tools - -The [Astar parachain](https://github.com/AstarNetwork/Astar/tree/master){target=\_blank} offers a crate with a set of utilities for interacting with the XCM protocol. The [xcm-tools](https://github.com/AstarNetwork/Astar/tree/master/bin/xcm-tools){target=\_blank} crate provides a straightforward method for users to locate a sovereign account or calculate an XC20 asset ID. Some commands included by the xcm-tools crate allow users to perform the following tasks: - -- **Sovereign accounts**: Obtain the sovereign account address for any parachain, either on the Relay Chain or for sibling parachains, using a simple command. -- **XC20 EVM addresses**: Generate XC20-compatible Ethereum addresses for assets by entering the asset ID, making it easy to integrate assets across Ethereum-compatible environments. -- **Remote accounts**: Retrieve remote account addresses needed for multi-location compatibility, using flexible options to specify account types and parachain IDs. - -To start using these tools, clone the [Astar repository](https://github.com/AstarNetwork/Astar){target=\_blank} and compile the xcm-tools package: - -```bash -git clone https://github.com/AstarNetwork/Astar && -cd Astar && -cargo build --release -p xcm-tools -``` - -After compiling, verify the setup with the following command: - -```bash -./target/release/xcm-tools --help -``` -For more details on using Astar xcm-tools, consult the [official documentation](https://docs.astar.network/docs/learn/interoperability/xcm/integration/tools/){target=\_blank}. - -### Chopsticks - -The Chopsticks library provides XCM functionality for testing XCM messages across networks, enabling you to fork multiple parachains along with a relay chain. For further details, see the [Chopsticks documentation](/tutorials/polkadot-sdk/testing/fork-live-chains/){target=\_blank} about XCM. - -### Moonbeam XCM SDK - -The [Moonbeam XCM SDK](https://github.com/moonbeam-foundation/xcm-sdk){target=\_blank} enables developers to easily transfer assets between chains, either between parachains or between a parachain and the relay chain, within the Polkadot/Kusama ecosystem. With the SDK, you don't need to worry about determining the [Multilocation](https://github.com/polkadot-fellows/xcm-format?tab=readme-ov-file#7-universal-consensus-location-identifiers){target=\_blank} of the origin or destination assets or which extrinsics are used on which networks. - -The SDK consists of two main packages: - -- **[XCM SDK](https://github.com/moonbeam-foundation/xcm-sdk/tree/main/packages/sdk){target=\_blank}**: Core SDK for executing XCM transfers between chains in the Polkadot/Kusama ecosystem. -- **[MRL SDK](https://github.com/moonbeam-foundation/xcm-sdk/tree/main/packages/mrl){target=\_blank}**: Extension of the XCM SDK for transferring liquidity into and across the Polkadot ecosystem from other ecosystems like Ethereum. - -Key features include: - -- **Simplified asset transfers**: Abstracts away complex multilocation determinations and extrinsic selection. -- **Cross-ecosystem support**: Enables transfers between Polkadot/Kusama chains and external ecosystems. -- **Developer-friendly API**: Provides intuitive interfaces for cross-chain functionality. -- **Comprehensive documentation**: Includes usage guides and API references for both packages. - -For detailed usage examples and API documentation, visit the [official Moonbeam XCM SDK documentation](https://moonbeam-foundation.github.io/xcm-sdk/latest/){target=\_blank}. diff --git a/.ai/categories/reference.md b/.ai/categories/reference.md index a0dfa9c51..20c9d3235 100644 --- a/.ai/categories/reference.md +++ b/.ai/categories/reference.md @@ -1,374 +1,6 @@ Begin New Bundle: Reference ---- - -Page Title: Glossary - -- Source (raw): https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/reference-glossary.md -- Canonical (HTML): https://docs.polkadot.com/reference/glossary/ -- Summary: Glossary of terms used within the Polkadot ecosystem, Polkadot SDK, its subsequent libraries, and other relevant Web3 terminology. - -# Glossary - -Key definitions, concepts, and terminology specific to the Polkadot ecosystem are included here. - -Additional glossaries from around the ecosystem you might find helpful: - -- [Polkadot Wiki Glossary](https://wiki.polkadot.com/general/glossary){target=\_blank} -- [Polkadot SDK Glossary](https://paritytech.github.io/polkadot-sdk/master/polkadot_sdk_docs/reference_docs/glossary/index.html){target=\_blank} - -## Authority - -The role in a blockchain that can participate in consensus mechanisms. - -- **[GRANDPA](#grandpa)**: The authorities vote on chains they consider final. -- **[Blind Assignment of Blockchain Extension](#blind-assignment-of-blockchain-extension-babe) (BABE)**: The authorities are also [block authors](#block-author). - -Authority sets can be used as a basis for consensus mechanisms such as the [Nominated Proof of Stake (NPoS)](#nominated-proof-of-stake-npos) protocol. - -## Authority Round (Aura) - -A deterministic [consensus](#consensus) protocol where block production is limited to a rotating list of [authorities](#authority) that take turns creating blocks. In authority round (Aura) consensus, most online authorities are assumed to be honest. It is often used in combination with [GRANDPA](#grandpa) as a [hybrid consensus](#hybrid-consensus) protocol. - -Learn more by reading the official [Aura consensus algorithm](https://openethereum.github.io/Aura){target=\_blank} wiki article. - -## Blind Assignment of Blockchain Extension (BABE) - -A [block authoring](#block-author) protocol similar to [Aura](#authority-round-aura), except [authorities](#authority) win [slots](#slot) based on a Verifiable Random Function (VRF) instead of the round-robin selection method. The winning authority can select a chain and submit a new block. - -Learn more by reading the official Web3 Foundation [BABE research document](https://research.web3.foundation/Polkadot/protocols/block-production/Babe){target=\_blank}. - -## Block Author - -The node responsible for the creation of a block, also called _block producers_. In a Proof of Work (PoW) blockchain, these nodes are called _miners_. - -## Byzantine Fault Tolerance (BFT) - -The ability of a distributed computer network to remain operational if a certain proportion of its nodes or [authorities](#authority) are defective or behaving maliciously. A distributed network is typically considered Byzantine fault tolerant if it can remain functional, with up to one-third of nodes assumed to be defective, offline, actively malicious, and part of a coordinated attack. - -### Byzantine Failure - -The loss of a network service due to node failures that exceed the proportion of nodes required to reach consensus. - -### Practical Byzantine Fault Tolerance (pBFT) - -An early approach to Byzantine fault tolerance (BFT), practical Byzantine fault tolerance (pBFT) systems tolerate Byzantine behavior from up to one-third of participants. - -The communication overhead for such systems is `O(n²)`, where `n` is the number of nodes (participants) in the system. - -### Preimage - -A preimage is the data that is input into a hash function to calculate a hash. Since a hash function is a [one-way function](https://en.wikipedia.org/wiki/One-way_function){target=\_blank}, the output, the hash, cannot be used to reveal the input, the preimage. - -## Call - -In the context of pallets containing functions to be dispatched to the runtime, `Call` is an enumeration data type that describes the functions that can be dispatched with one variant per pallet. A `Call` represents a [dispatch](#dispatchable) data structure object. - -## Chain Specification - -A chain specification file defines the properties required to run a node in an active or new Polkadot SDK-built network. It often contains the initial genesis runtime code, network properties (such as the network's name), the initial state for some pallets, and the boot node list. The chain specification file makes it easy to use a single Polkadot SDK codebase as the foundation for multiple independently configured chains. - -## Collator - -An [author](#block-author) of a [parachain](#parachain) network. -They aren't [authorities](#authority) in themselves, as they require a [relay chain](#relay-chain) to coordinate [consensus](#consensus). - -More details are found on the [Polkadot Collator Wiki](https://wiki.polkadot.com/learn/learn-collator/){target=\_blank}. - -## Collective - -Most often used to refer to an instance of the Collective pallet on Polkadot SDK-based networks such as [Kusama](#kusama) or [Polkadot](#polkadot) if the Collective pallet is part of the FRAME-based runtime for the network. - -## Consensus - -Consensus is the process blockchain nodes use to agree on a chain's canonical fork. It is composed of [authorship](#block-author), finality, and [fork-choice rule](#fork-choice-rulestrategy). In the Polkadot ecosystem, these three components are usually separate and the term consensus often refers specifically to authorship. - -See also [hybrid consensus](#hybrid-consensus). - -## Consensus Algorithm - -Ensures a set of [actors](#authority)—who don't necessarily trust each other—can reach an agreement about the state as the result of some computation. Most consensus algorithms assume that up to one-third of the actors or nodes can be [Byzantine fault tolerant](#byzantine-fault-tolerance-bft). - -Consensus algorithms are generally concerned with ensuring two properties: - -- **Safety**: Indicating that all honest nodes eventually agreed on the state of the chain. -- **Liveness**: Indicating the ability of the chain to keep progressing. - -## Consensus Engine - -The node subsystem responsible for consensus tasks. - -For detailed information about the consensus strategies of the [Polkadot](#polkadot) network, see the [Polkadot Consensus](/reference/polkadot-hub/consensus-and-security/pos-consensus/){target=\_blank} blog series. - -See also [hybrid consensus](#hybrid-consensus). - -## Coretime - -The time allocated for utilizing a core, measured in relay chain blocks. There are two types of coretime: *on-demand* and *bulk*. - -On-demand coretime refers to coretime acquired through bidding in near real-time for the validation of a single parachain block on one of the cores reserved specifically for on-demand orders. They are available as an on-demand coretime pool. Set of cores that are available on-demand. Cores reserved through bulk coretime could also be made available in the on-demand coretime pool, in parts or in entirety. - -Bulk coretime is a fixed duration of continuous coretime represented by an NFT that can be split, shared, or resold. It is managed by the [Broker pallet](https://paritytech.github.io/polkadot-sdk/master/pallet_broker/index.html){target=\_blank}. - -## Development Phrase - -A [mnemonic phrase](https://en.wikipedia.org/wiki/Mnemonic#For_numerical_sequences_and_mathematical_operations){target=\_blank} that is intentionally made public. - -Well-known development accounts, such as Alice, Bob, Charlie, Dave, Eve, and Ferdie, are generated from the same secret phrase: - -``` -bottom drive obey lake curtain smoke basket hold race lonely fit walk -``` - -Many tools in the Polkadot SDK ecosystem, such as [`subkey`](https://github.com/paritytech/polkadot-sdk/tree/polkadot-stable2506-2/substrate/bin/utils/subkey){target=\_blank}, allow you to implicitly specify an account using a derivation path such as `//Alice`. - -## Digest - -An extensible field of the [block header](#header) that encodes information needed by several actors in a blockchain network, including: - -- [Light clients](#light-client) for chain synchronization. -- Consensus engines for block verification. -- The runtime itself, in the case of pre-runtime digests. - -## Dispatchable - -Function objects that act as the entry points in FRAME [pallets](#pallet). Internal or external entities can call them to interact with the blockchain’s state. They are a core aspect of the runtime logic, handling [transactions](#transaction) and other state-changing operations. - -## Events - -A means of recording that some particular [state](#state) transition happened. - -In the context of [FRAME](#frame-framework-for-runtime-aggregation-of-modularized-entities), events are composable data types that each [pallet](#pallet) can individually define. Events in FRAME are implemented as a set of transient storage items inspected immediately after a block has been executed and reset during block initialization. - -## Executor - -A means of executing a function call in a given [runtime](#runtime) with a set of dependencies. -There are two orchestration engines in Polkadot SDK, _WebAssembly_ and _native_. - -- The _native executor_ uses a natively compiled runtime embedded in the node to execute calls. This is a performance optimization available to up-to-date nodes. - -- The _WebAssembly executor_ uses a [Wasm](#webassembly-wasm) binary and a Wasm interpreter to execute calls. The binary is guaranteed to be up-to-date regardless of the version of the blockchain node because it is persisted in the [state](#state) of the Polkadot SDK-based chain. - -## Existential Deposit - -The minimum balance an account is allowed to have in the [Balances pallet](https://paritytech.github.io/polkadot-sdk/master/pallet_balances/index.html){target=\_blank}. Accounts cannot be created with a balance less than the existential deposit amount. - -If an account balance drops below this amount, the Balances pallet uses [a FRAME System API](https://paritytech.github.io/substrate/master/frame_system/pallet/struct.Pallet.html#method.dec_ref){target=\_blank} to drop its references to that account. - -If the Balances pallet reference to an account is dropped, the account can be [reaped](https://paritytech.github.io/substrate/master/frame_system/pallet/struct.Pallet.html#method.allow_death){target=\_blank}. - -## Extrinsic - -A general term for data that originates outside the runtime, is included in a block, and leads to some action. This includes user-initiated transactions and inherent transactions placed into the block by the block builder. - -It is a SCALE-encoded array typically consisting of a version number, signature, and varying data types indicating the resulting runtime function to be called. Extrinsics can take two forms: [inherents](#inherent-transactions) and [transactions](#transaction). - -For more technical details, see the [Polkadot spec](https://spec.polkadot.network/id-extrinsics){target=\_blank}. - -## Fork Choice Rule/Strategy - -A fork choice rule or strategy helps determine which chain is valid when reconciling several network forks. A common fork choice rule is the [longest chain](https://paritytech.github.io/polkadot-sdk/master/sc_consensus/struct.LongestChain.html){target=\_blank}, in which the chain with the most blocks is selected. - -## FRAME (Framework for Runtime Aggregation of Modularized Entities) - -Enables developers to create blockchain [runtime](#runtime) environments from a modular set of components called [pallets](#pallet). It utilizes a set of procedural macros to construct runtimes. - -[Visit the Polkadot SDK docs for more details on FRAME.](https://paritytech.github.io/polkadot-sdk/master/polkadot_sdk_docs/polkadot_sdk/frame_runtime/index.html){target=\_blank} - -## Full Node - -A node that prunes historical states, keeping only recently finalized block states to reduce storage needs. Full nodes provide current chain state access and allow direct submission and validation of [extrinsics](#extrinsic), maintaining network decentralization. - -## Genesis Configuration - -A mechanism for specifying the initial state of a blockchain. By convention, this initial state or first block is commonly referred to as the genesis state or genesis block. The genesis configuration for Polkadot SDK-based chains is accomplished by way of a [chain specification](#chain-specification) file. - -## GRANDPA - -A deterministic finality mechanism for blockchains that is implemented in the [Rust](https://www.rust-lang.org/){target=\_blank} programming language. - -The [formal specification](https://github.com/w3f/consensus/blob/master/pdf/grandpa-old.pdf){target=\_blank} is maintained by the [Web3 Foundation](https://web3.foundation/){target=\_blank}. - -## Header - -A structure that aggregates the information used to summarize a block. Primarily, it consists of cryptographic information used by [light clients](#light-client) to get minimally secure but very efficient chain synchronization. - -## Hybrid Consensus - -A blockchain consensus protocol that consists of independent or loosely coupled mechanisms for [block production](#block-author) and finality. - -Hybrid consensus allows the chain to grow as fast as probabilistic consensus protocols, such as [Aura](#authority-round-aura), while maintaining the same level of security as deterministic finality consensus protocols, such as [GRANDPA](#grandpa). - -## Inherent Transactions - -A special type of unsigned transaction, referred to as _inherents_, that enables a block authoring node to insert information that doesn't require validation directly into a block. - -Only the block-authoring node that calls the inherent transaction function can insert data into its block. In general, validators assume the data inserted using an inherent transaction is valid and reasonable even if it can't be deterministically verified. - -## JSON-RPC - -A stateless, lightweight remote procedure call protocol encoded in JavaScript Object Notation (JSON). JSON-RPC provides a standard way to call functions on a remote system by using JSON. - -For Polkadot SDK, this protocol is implemented through the [Parity JSON-RPC](https://github.com/paritytech/jsonrpc){target=\_blank} crate. - -## Keystore - -A subsystem for managing keys for the purpose of producing new blocks. - -## Kusama - -[Kusama](https://kusama.network/){target=\_blank} is a Polkadot SDK-based blockchain that implements a design similar to the [Polkadot](#polkadot) network. - -Kusama is a [canary](https://en.wiktionary.org/wiki/canary_in_a_coal_mine){target=\_blank} network and is referred to as [Polkadot's "wild cousin."](https://wiki.polkadot.com/learn/learn-comparisons-kusama/){target=\_blank}. - -As a canary network, Kusama is expected to be more stable than a test network like [Westend](#westend) but less stable than a production network like [Polkadot](#polkadot). Kusama is controlled by its network participants and is intended to be stable enough to encourage meaningful experimentation. - -## libp2p - -A peer-to-peer networking stack that allows the use of many transport mechanisms, including WebSockets (usable in a web browser). - -Polkadot SDK uses the [Rust implementation](https://github.com/libp2p/rust-libp2p){target=\_blank} of the `libp2p` networking stack. - -## Light Client - -A type of blockchain node that doesn't store the [chain state](#state) or produce blocks. - -A light client can verify cryptographic primitives and provides a [remote procedure call (RPC)](https://en.wikipedia.org/wiki/Remote_procedure_call){target=\_blank} server, enabling blockchain users to interact with the network. - -## Metadata - -Data that provides information about one or more aspects of a system. -The metadata that exposes information about a Polkadot SDK blockchain enables you to interact with that system. - -## Nominated Proof of Stake (NPoS) - -A method for determining [validators](#validator) or _[authorities](#authority)_ based on a willingness to commit their stake to the proper functioning of one or more block-producing nodes. - -## Oracle - -An entity that connects a blockchain to a non-blockchain data source. Oracles enable the blockchain to access and act upon information from existing data sources and incorporate data from non-blockchain systems and services. - -## Origin - -A [FRAME](#frame-framework-for-runtime-aggregation-of-modularized-entities) primitive that identifies the source of a [dispatched](#dispatchable) function call into the [runtime](#runtime). The FRAME System pallet defines three built-in [origins](#origin). As a [pallet](#pallet) developer, you can also define custom origins, such as those defined by the [Collective pallet](https://paritytech.github.io/substrate/master/pallet_collective/enum.RawOrigin.html){target=\_blank}. - -## Pallet - -A module that can be used to extend the capabilities of a [FRAME](#frame-framework-for-runtime-aggregation-of-modularized-entities)-based [runtime](#runtime). -Pallets bundle domain-specific logic with runtime primitives like [events](#events) and [storage items](#storage-item). - -## Parachain - -A parachain is a blockchain that derives shared infrastructure and security from a _[relay chain](#relay-chain)_. -You can learn more about parachains on the [Polkadot Wiki](https://wiki.polkadot.com/learn/learn-parachains/){target=\_blank}. - -## Paseo - -Paseo TestNet provisions testing on Polkadot's "production" runtime, which means less chance of feature or code mismatch when developing parachain apps. Specifically, after the [Polkadot Technical fellowship](https://wiki.polkadot.com/learn/learn-polkadot-technical-fellowship/){target=\_blank} proposes a runtime upgrade for Polkadot, this TestNet is updated, giving a period where the TestNet will be ahead of Polkadot to allow for testing. - -## Polkadot - -The [Polkadot network](https://polkadot.com/){target=\_blank} is a blockchain that serves as the central hub of a heterogeneous blockchain network. It serves the role of the [relay chain](#relay-chain) and provides shared infrastructure and security to support [parachains](#parachain). - -## Polkadot Cloud - -Polkadot Cloud is a platform for deploying resilient, customizable and scalable Web3 applications through Polkadot's functionality. It encompasses the wider Polkadot network infrastructure and security layer where parachains operate. The platform enables users to launch Ethereum-compatible chains, build specialized blockchains, and flexibly manage computing resources through on-demand or bulk coretime purchases. Initially launched with basic parachain functionality, Polkadot Cloud has evolved to offer enhanced flexibility with features like coretime, elastic scaling, and async backing for improved performance. - -## Polkadot Hub - -Polkadot Hub is a Layer 1 platform that serves as the primary entry point to the Polkadot ecosystem, providing essential functionality without requiring parachain deployment. It offers core services including smart contracts, identity management, staking, governance, and interoperability with other ecosystems, making it simple and fast for both builders and users to get started in Web3. - -## PolkaVM - -PolkaVM is a custom virtual machine optimized for performance, leveraging a RISC-V-based architecture to support Solidity and any language that compiles to RISC-V. It is specifically designed for the Polkadot ecosystem, enabling smart contract deployment and execution. - -## Relay Chain - -Relay chains are blockchains that provide shared infrastructure and security to the [parachains](#parachain) in the network. In addition to providing [consensus](#consensus) capabilities, relay chains allow parachains to communicate and exchange digital assets without needing to trust one another. - -## Rococo - -A [parachain](#parachain) test network for the Polkadot network. The [Rococo](#rococo) network is a Polkadot SDK-based blockchain with an October 14, 2024 deprecation date. Development teams are encouraged to use the Paseo TestNet instead. - -## Runtime - -The runtime represents the [state transition function](#state-transition-function-stf) for a blockchain. In Polkadot SDK, the runtime is stored as a [Wasm](#webassembly-wasm) binary in the chain state. The Runtime is stored under a unique state key and can be modified during the execution of the state transition function. - -## Slot - -A fixed, equal interval of time used by consensus engines such as [Aura](#authority-round-aura) and [BABE](#blind-assignment-of-blockchain-extension-babe). In each slot, a subset of [authorities](#authority) is permitted, or obliged, to [author](#block-author) a block. - -## Sovereign Account - -The unique account identifier for each chain in the relay chain ecosystem. It is often used in cross-consensus (XCM) interactions to sign XCM messages sent to the relay chain or other chains in the ecosystem. - -The sovereign account for each chain is a root-level account that can only be accessed using the Sudo pallet or through governance. The account identifier is calculated by concatenating the Blake2 hash of a specific text string and the registered parachain identifier. - -## SS58 Address Format - -A public key address based on the Bitcoin [`Base-58-check`](https://en.bitcoin.it/wiki/Base58Check_encoding){target=\_blank} encoding. Each Polkadot SDK SS58 address uses a `base-58` encoded value to identify a specific account on a specific Polkadot SDK-based chain - -The [canonical `ss58-registry`](https://github.com/paritytech/ss58-registry){target=\_blank} provides additional details about the address format used by different Polkadot SDK-based chains, including the network prefix and website used for different networks - -## State Transition Function (STF) - -The logic of a blockchain that determines how the state changes when a block is processed. In Polkadot SDK, the state transition function is effectively equivalent to the [runtime](#runtime). - -## Storage Item - -[FRAME](#frame-framework-for-runtime-aggregation-of-modularized-entities) primitives that provide type-safe data persistence capabilities to the [runtime](#runtime). -Learn more in the [storage items](https://paritytech.github.io/polkadot-sdk/master/frame_support/storage/types/index.html){target=\_blank} reference document in the Polkadot SDK. - -## Substrate - -A flexible framework for building modular, efficient, and upgradeable blockchains. Substrate is written in the [Rust](https://www.rust-lang.org/){target=\_blank} programming language and is maintained by [Parity Technologies](https://www.parity.io/){target=\_blank}. - -## Transaction - -An [extrinsic](#extrinsic) that includes a signature that can be used to verify the account authorizing it inherently or via [signed extensions](https://paritytech.github.io/polkadot-sdk/master/polkadot_sdk_docs/reference_docs/signed_extensions/index.html){target=\_blank}. - -## Transaction Era - -A definable period expressed as a range of block numbers during which a transaction can be included in a block. -Transaction eras are used to protect against transaction replay attacks if an account is reaped and its replay-protecting nonce is reset to zero. - -## Trie (Patricia Merkle Tree) - -A data structure used to represent sets of key-value pairs and enables the items in the data set to be stored and retrieved using a cryptographic hash. Because incremental changes to the data set result in a new hash, retrieving data is efficient even if the data set is very large. With this data structure, you can also prove whether the data set includes any particular key-value pair without access to the entire data set. - -In Polkadot SDK-based blockchains, state is stored in a trie data structure that supports the efficient creation of incremental digests. This trie is exposed to the [runtime](#runtime) as [a simple key/value map](#storage-item) where both keys and values can be arbitrary byte arrays. - -## Validator - -A validator is a node that participates in the consensus mechanism of the network. Its roles include block production, transaction validation, network integrity, and security maintenance. - -## WebAssembly (Wasm) - -An execution architecture that allows for the efficient, platform-neutral expression of -deterministic, machine-executable logic. - -[Wasm](https://webassembly.org/){target=\_blank} can be compiled from many languages, including -the [Rust](https://www.rust-lang.org/){target=\_blank} programming language. Polkadot SDK-based chains use a Wasm binary to provide portable [runtimes](#runtime) that can be included as part of the chain's state. - -## Weight - -A convention used in Polkadot SDK-based blockchains to measure and manage the time it takes to validate a block. -Polkadot SDK defines one unit of weight as one picosecond of execution time on reference hardware. - -The maximum block weight should be equivalent to one-third of the target block time with an allocation of one-third each for: - -- Block construction -- Network propagation -- Import and verification - -By defining weights, you can trade-off the number of transactions per second and the hardware required to maintain the target block time appropriate for your use case. Weights are defined in the runtime, meaning you can tune them using runtime updates to keep up with hardware and software improvements. - -## Westend - -Westend is a Parity-maintained, Polkadot SDK-based blockchain that serves as a test network for the [Polkadot](#polkadot) network. - - --- Page Title: JSON-RPC APIs @@ -1236,128 +868,3 @@ If an error occurs, the response will include an error object: } } ``` - - ---- - -Page Title: Technical Reference Overview - -- Source (raw): https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/reference.md -- Canonical (HTML): https://docs.polkadot.com/reference/ -- Summary: Learn about Polkadot's technical architecture, governance framework, parachain ecosystem, and the tools you need to build and interact with the network. - -## Introduction - -The Technical Reference section provides comprehensive documentation of Polkadot's architecture, core concepts, and development tooling. Whether you're exploring how Polkadot's relay chain coordinates parachains, understanding governance mechanisms, or building applications on the network, this reference covers the technical foundations you need. - -Polkadot is a multi-chain network that enables diverse, interconnected blockchains to share security and communicate seamlessly. Understanding how these components interact from the [relay chain](/polkadot-protocol/glossary#relay-chain){target=\_blank} that validates [parachains](/polkadot-protocol/glossary#parachain){target=\_blank} to the [governance](/reference/glossary#governance){target=\_blank} mechanisms that evolve the protocol is essential for developers, validators, and network participants. - -This guide organizes technical documentation across five core areas: Polkadot Hub, Parachains, On-Chain Governance, Glossary, and Tools, each providing detailed information on different aspects of the Polkadot ecosystem. - -## Polkadot Hub - -[Polkadot Hub](/reference/polkadot-hub/){target=\_blank} is the entry point to Polkadot for all users and application developers. It provides access to essential Web3 services, including smart contracts, staking, governance, identity management, and cross-ecosystem interoperability—without requiring you to deploy or manage a parachain. - -The Hub encompasses a set of core functionality that enables developers and users to build and interact with applications on Polkadot. Key capabilities include: - -- **Smart contracts**: Deploy Ethereum-compatible smart contracts and build decentralized applications. -- **Assets and tokens**: Create, manage, and transfer fungible tokens and NFTs across the ecosystem. -- **Staking**: Participate in network security and earn rewards by staking DOT. -- **Governance**: Vote on proposals and participate in Polkadot's decentralized decision-making through OpenGov. -- **Identity services**: Register and manage on-chain identities, enabling access to governance roles and network opportunities. -- **Cross-chain interoperability**: Leverage XCM messaging to interact securely with other chains in the Polkadot ecosystem. -- **Collectives and DAOs**: Participate in governance collectives and decentralized autonomous organizations. - -## Parachains - -[Parachains](/reference/parachains/){target=\_blank} are specialized blockchains that connect to the Polkadot relay chain, inheriting its security while maintaining their own application-specific logic. The parachains documentation covers: - -- **Accounts**: Deep dive into account types, storage, and management on parachains. -- **Blocks, transactions and fees**: Understand block production, transaction inclusion, and fee mechanisms. -- **Consensus**: Learn how parachain blocks are validated and finalized through the relay chain's consensus. -- **Chain data**: Explore data structures, storage layouts, and state management. -- **Cryptography**: Study cryptographic primitives used in Polkadot SDK-based chains. -- **Data encoding**: Understand how data is encoded and decoded for blockchain compatibility. -- **Networks**: Learn about networking protocols and peer-to-peer communication. -- **Interoperability**: Discover [Cross-Consensus Messaging (XCM)](/parachains/interoperability/get-started/){target=\_blank}, the standard for cross-chain communication. -- **Randomness**: Understand how randomness is generated and used in Polkadot chains. -- **Node and runtime**: Learn about parachain nodes, runtime environments, and the [Polkadot SDK](https://github.com/paritytech/polkadot-sdk){target=\_blank}. - -## On-Chain Governance - -[On-Chain governance](/reference/governance/){target=\_blank} is the decentralized decision-making mechanism for the Polkadot network. It manages the evolution and modification of the network's runtime logic, enabling community oversight and approval for proposed changes. The governance documentation details: - -- **OpenGov framework**: Understand Polkadot's next-generation governance system with enhanced delegation, flexible tracks, and simultaneous referendums. -- **Origins and tracks**: Learn how governance proposals are categorized, prioritized, and executed based on their privilege level and complexity. -- **Voting and delegation**: Explore conviction voting, vote delegation, and how token holders participate in governance. -- **Governance evolution**: See how Polkadot's governance has evolved from Governance V1 to the current OpenGov system. - -## Glossary - -The [Glossary](/reference/glossary/){target=\_blank} provides quick-reference definitions for Polkadot-specific terminology. Essential terms include: - -- Blockchain concepts (blocks, transactions, state) -- Consensus mechanisms (validators, collators, finality) -- Polkadot-specific terms (relay chain, parachain, XCM, FRAME) -- Network components (nodes, runtimes, storage) -- Governance terminology (origins, tracks, referendums) - -## Tools - -The [Tools](/reference/tools/){target=\_blank} section documents essential development and interaction tools for the Polkadot ecosystem: - -- **Light clients**: Lightweight solutions for interacting with the network without running full nodes. -- **JavaScript/TypeScript tools**: Libraries like [Polkadot.js API](/reference/tools/polkadot-js-api/){target=\_blank} and [PAPI](/reference/tools/papi/){target=\_blank} for building applications. -- **Rust tools**: [Polkadart](/reference/tools/polkadart/){target=\_blank} and other Rust-based libraries for SDK development. -- **Python tools**: [py-substrate-interface](/reference/tools/py-substrate-interface/){target=\_blank} for Python developers. -- **Testing and development**: Tools like [Moonwall](/reference/tools/moonwall/){target=\_blank}, [Chopsticks](/reference/tools/chopsticks/){target=\_blank}, and [Omninode](/reference/tools/omninode/){target=\_blank} for smart contract and parachain testing. -- **Indexing and monitoring**: [Sidecar](/reference/tools/sidecar/){target=\_blank} for data indexing and [Dedot](/reference/tools/dedot/){target=\_blank} for substrate interaction. -- **Cross-chain tools**: [ParaSpell](/reference/tools/paraspell/){target=\_blank} for XCM integration and asset transfers. - -## Where to Go Next - -For detailed exploration of specific areas, proceed to any of the main sections: - -
- -- Learn **Polkadot Hub** - - --- - - Understand the relay chain's role in coordinating parachains, providing shared security, and enabling governance. - - [:octicons-arrow-right-24: Reference](/reference/polkadot-hub/) - -- Learn **Parachains** - - --- - - Deep dive into parachain architecture, consensus, data structures, and building application-specific blockchains. - - [:octicons-arrow-right-24: Reference](/reference/parachains/) - -- Learn **On-Chain Governance** - - --- - - Explore Polkadot's decentralized governance framework and how to participate in network decision-making. - - [:octicons-arrow-right-24: Reference](/reference/governance/) - -- Guide **Glossary** - - --- - - Quick reference for Polkadot-specific terminology and concepts used throughout the documentation. - - [:octicons-arrow-right-24: Reference](/reference/glossary/) - -- Guide **Tools** - - --- - - Discover development tools, libraries, and frameworks for building and interacting with Polkadot. - - [:octicons-arrow-right-24: Reference](/reference/tools/) - -
diff --git a/.ai/categories/smart-contracts.md b/.ai/categories/smart-contracts.md index 9d92c1c80..ae870db50 100644 --- a/.ai/categories/smart-contracts.md +++ b/.ai/categories/smart-contracts.md @@ -158,440 +158,6 @@ BlockScout is an open-source explorer platform with a user-friendly interface ad ![](/images/smart-contracts/explorers/explorers-01.webp) ---- - -Page Title: Blocks - -- Source (raw): https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/reference-parachains-blocks-transactions-fees-blocks.md -- Canonical (HTML): https://docs.polkadot.com/reference/parachains/blocks-transactions-fees/blocks/ -- Summary: Understand how blocks are produced, validated, and imported in Polkadot SDK-based blockchains, covering initialization, finalization, and authoring processes. - -# Blocks - -## Introduction - -In the Polkadot SDK, blocks are fundamental to the functioning of the blockchain, serving as containers for [transactions](/reference/parachains/blocks-transactions-fees/transactions/){target=\_blank} and changes to the chain's state. Blocks consist of headers and an array of transactions, ensuring the integrity and validity of operations on the network. This guide explores the essential components of a block, the process of block production, and how blocks are validated and imported across the network. By understanding these concepts, developers can better grasp how blockchains maintain security, consistency, and performance within the Polkadot ecosystem. - -## What is a Block? - -In the Polkadot SDK, a block is a fundamental unit that encapsulates both the header and an array of transactions. The block header includes critical metadata to ensure the integrity and sequence of the blockchain. Here's a breakdown of its components: - -- **Block height**: Indicates the number of blocks created in the chain so far. -- **Parent hash**: The hash of the previous block, providing a link to maintain the blockchain's immutability. -- **Transaction root**: Cryptographic digest summarizing all transactions in the block. -- **State root**: A cryptographic digest representing the post-execution state. -- **Digest**: Additional information that can be attached to a block, such as consensus-related messages. - -Each transaction is part of a series that is executed according to the runtime's rules. The transaction root is a cryptographic digest of this series, which prevents alterations and enables succinct verification by light clients. This verification process allows light clients to confirm whether a transaction exists in a block with only the block header, avoiding downloading the entire block. - -## Block Production - -When an authoring node is authorized to create a new block, it selects transactions from the transaction queue based on priority. This step, known as block production, relies heavily on the executive module to manage the initialization and finalization of blocks. The process is summarized as follows: - -### Initialize Block - -The block initialization process begins with a series of function calls that prepare the block for transaction execution: - -1. **Call `on_initialize`**: The executive module calls the [`on_initialize`](https://paritytech.github.io/polkadot-sdk/master/frame_support/traits/trait.Hooks.html#method.on_initialize){target=\_blank} hook from the system pallet and other runtime pallets to prepare for the block's transactions. -2. **Coordinate runtime calls**: Coordinates function calls in the order defined by the transaction queue. -3. **Verify information**: Once [`on_initialize`](https://paritytech.github.io/polkadot-sdk/master/frame_support/traits/trait.Hooks.html#method.on_initialize){target=\_blank} functions are executed, the executive module checks the parent hash in the block header and the trie root to verify information is consistent. - -### Finalize Block - -Once transactions are processed, the block must be finalized before being broadcast to the network. The finalization steps are as follows: - -1. **Call `on_finalize`**: The executive module calls the [`on_finalize`](https://paritytech.github.io/polkadot-sdk/master/frame_support/traits/trait.Hooks.html#method.on_finalize){target=\_blank} hooks in each pallet to ensure any remaining state updates or checks are completed before the block is sealed and published. -2. **Verify information**: The block's digest and storage root in the header are checked against the initialized block to ensure consistency. -3. **Call `on_idle`**: The [`on_idle`](https://paritytech.github.io/polkadot-sdk/master/frame_support/traits/trait.Hooks.html#method.on_idle){target=\_blank} hook is triggered to process any remaining tasks using the leftover weight from the block. - -## Block Authoring and Import - -Once the block is finalized, it is gossiped to other nodes in the network. Nodes follow this procedure: - -1. **Receive transactions**: The authoring node collects transactions from the network. -2. **Validate**: Transactions are checked for validity. -3. **Queue**: Valid transactions are placed in the transaction pool for execution. -4. **Execute**: State changes are made as the transactions are executed. -5. **Publish**: The finalized block is broadcast to the network. - -### Block Import Queue - -After a block is published, other nodes on the network can import it into their chain state. The block import queue is part of the outer node in every Polkadot SDK-based node and ensures incoming blocks are valid before adding them to the node's state. - -In most cases, you don't need to know details about how transactions are gossiped or how other nodes on the network import blocks. The following traits are relevant, however, if you plan to write any custom consensus logic or want a deeper dive into the block import queue: - -- **[`ImportQueue`](https://paritytech.github.io/polkadot-sdk/master/sc_consensus/import_queue/trait.ImportQueue.html){target=\_blank}**: The trait that defines the block import queue. -- **[`Link`](https://paritytech.github.io/polkadot-sdk/master/sc_consensus/import_queue/trait.Link.html){target=\_blank}**: The trait that defines the link between the block import queue and the network. -- **[`BasicQueue`](https://paritytech.github.io/polkadot-sdk/master/sc_consensus/import_queue/struct.BasicQueue.html){target=\_blank}**: A basic implementation of the block import queue. -- **[`Verifier`](https://paritytech.github.io/polkadot-sdk/master/sc_consensus/import_queue/trait.Verifier.html){target=\_blank}**: The trait that defines the block verifier. -- **[`BlockImport`](https://paritytech.github.io/polkadot-sdk/master/sc_consensus/block_import/trait.BlockImport.html){target=\_blank}**: The trait that defines the block import process. - -These traits govern how blocks are validated and imported across the network, ensuring consistency and security. - -## Additional Resources - -To learn more about the block structure in the Polkadot SDK runtime, see the [`Block` reference](https://paritytech.github.io/polkadot-sdk/master/sp_runtime/traits/trait.Block.html){target=\_blank} entry in the Rust Docs. - - ---- - -Page Title: Chain Data - -- Source (raw): https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/reference-parachains-chain-data.md -- Canonical (HTML): https://docs.polkadot.com/reference/parachains/chain-data/ -- Summary: Learn how to expose and utilize chain data for blockchain applications. Discover runtime metadata, RPC APIs, and tools for efficient development. - -# Chain Data - -## Introduction - -Understanding and leveraging on-chain data is a fundamental aspect of blockchain development. Whether you're building frontend applications or backend systems, accessing and decoding runtime metadata is vital to interacting with the blockchain. This guide introduces you to the tools and processes for generating and retrieving metadata, explains its role in application development, and outlines the additional APIs available for interacting with a Polkadot node. By mastering these components, you can ensure seamless communication between your applications and the blockchain. - -## Application Development - -You might not be directly involved in building frontend applications as a blockchain developer. However, most applications that run on a blockchain require some form of frontend or user-facing client to enable users or other programs to access and modify the data that the blockchain stores. For example, you might develop a browser-based, mobile, or desktop application that allows users to submit transactions, post articles, view their assets, or track previous activity. The backend for that application is configured in the runtime logic for your blockchain, but the frontend client makes the runtime features accessible to your users. - -For your custom chain to be useful to others, you'll need to provide a client application that allows users to view, interact with, or update information that the blockchain keeps track of. In this article, you'll learn how to expose information about your runtime so that client applications can use it, see examples of the information exposed, and explore tools and libraries that use it. - -## Understand Metadata - -Polkadot SDK-based blockchain networks are designed to expose their runtime information, allowing developers to learn granular details regarding pallets, RPC calls, and runtime APIs. The metadata also exposes their related documentation. The chain's metadata is [SCALE-encoded](/reference/parachains/data-encoding/){target=\_blank}, allowing for the development of browser-based, mobile, or desktop applications to support the chain's runtime upgrades seamlessly. It is also possible to develop applications compatible with multiple Polkadot SDK-based chains simultaneously. - -## Expose Runtime Information as Metadata - -To interact with a node or the state of the blockchain, you need to know how to connect to the chain and access the exposed runtime features. This interaction involves a Remote Procedure Call (RPC) through a node endpoint address, commonly through a secure web socket connection. - -An application developer typically needs to know the contents of the runtime logic, including the following details: - -- Version of the runtime the application is connecting to. -- Supported APIs. -- Implemented pallets. -- Defined functions and corresponding type signatures. -- Defined custom types. -- Exposed parameters users can set. - -As the Polkadot SDK is modular and provides a composable framework for building blockchains, there are limitless opportunities to customize the schema of properties. Each runtime can be configured with its properties, including function calls and types, which can be changed over time with runtime upgrades. - -The Polkadot SDK enables you to generate the runtime metadata schema to capture information unique to a runtime. The metadata for a runtime describes the pallets in use and types defined for a specific runtime version. The metadata includes information about each pallet's storage items, functions, events, errors, and constants. The metadata also provides type definitions for any custom types included in the runtime. - -Metadata provides a complete inventory of a chain's runtime. It is key to enabling client applications to interact with the node, parse responses, and correctly format message payloads sent back to that chain. - -## Generate Metadata - -To efficiently use the blockchain's networking resources and minimize the data transmitted over the network, the metadata schema is encoded using the [Parity SCALE Codec](https://github.com/paritytech/parity-scale-codec?tab=readme-ov-file#parity-scale-codec){target=\_blank}. This encoding is done automatically through the [`scale-info`](https://docs.rs/scale-info/latest/scale_info/){target=\_blank}crate. - -At a high level, generating the metadata involves the following steps: - -1. The pallets in the runtime logic expose callable functions, types, parameters, and documentation that need to be encoded in the metadata. -2. The `scale-info` crate collects type information for the pallets in the runtime, builds a registry of the pallets that exist in a particular runtime, and the relevant types for each pallet in the registry. The type information is detailed enough to enable encoding and decoding for every type. -3. The [`frame-metadata`](https://github.com/paritytech/frame-metadata){target=\_blank} crate describes the structure of the runtime based on the registry provided by the `scale-info` crate. -4. Nodes provide the RPC method `state_getMetadata` to return a complete description of all the types in the current runtime as a hex-encoded vector of SCALE-encoded bytes. - -## Retrieve Runtime Metadata - -The type information provided by the metadata enables applications to communicate with nodes using different runtime versions and across chains that expose different calls, events, types, and storage items. The metadata also allows libraries to generate a substantial portion of the code needed to communicate with a given node, enabling libraries like [`subxt`](https://github.com/paritytech/subxt){target=\_blank} to generate frontend interfaces that are specific to a target chain. - -### Use Polkadot.js - -Visit the [Polkadot.js Portal](https://polkadot.js.org/apps/#/rpc){target=\_blank} and select the **Developer** dropdown in the top banner. Select **RPC Calls** to make the call to request metadata. Follow these steps to make the RPC call: - -1. Select **state** as the endpoint to call. -2. Select **`getMetadata(at)`** as the method to call. -3. Click **Submit RPC call** to submit the call and return the metadata in JSON format. - -### Use Curl - -You can fetch the metadata for the network by calling the node's RPC endpoint. This request returns the metadata in bytes rather than human-readable JSON: - -```sh -curl -H "Content-Type: application/json" \ --d '{"id":1, "jsonrpc":"2.0", "method": "state_getMetadata"}' \ -https://rpc.polkadot.io - -``` - -### Use Subxt - -[`subxt`](https://github.com/paritytech/subxt){target=\_blank} may also be used to fetch the metadata of any data in a human-readable JSON format: - -```sh -subxt metadata --url wss://rpc.polkadot.io --format json > spec.json -``` - -Another option is to use the [`subxt` explorer web UI](https://paritytech.github.io/subxt-explorer/#/){target=\_blank}. - -## Client Applications and Metadata - -The metadata exposes the expected way to decode each type, meaning applications can send, retrieve, and process application information without manual encoding and decoding. Client applications must use the [SCALE codec library](https://github.com/paritytech/parity-scale-codec?tab=readme-ov-file#parity-scale-codec){target=\_blank} to encode and decode RPC payloads to use the metadata. Client applications use the metadata to interact with the node, parse responses, and format message payloads sent to the node. - -## Metadata Format - -Although the SCALE-encoded bytes can be decoded using the `frame-metadata` and [`parity-scale-codec`](https://github.com/paritytech/parity-scale-codec){target=\_blank} libraries, there are other tools, such as `subxt` and the Polkadot-JS API, that can convert the raw data to human-readable JSON format. - -The types and type definitions included in the metadata returned by the `state_getMetadata` RPC call depend on the runtime's metadata version. - -In general, the metadata includes the following information: - -- A constant identifying the file as containing metadata. -- The version of the metadata format used in the runtime. -- Type definitions for all types used in the runtime and generated by the `scale-info` crate. -- Pallet information for the pallets included in the runtime in the order that they are defined in the `construct_runtime` macro. - -!!!tip - Depending on the frontend library used (such as the [Polkadot API](https://papi.how/){target=\_blank}), they may format the metadata differently than the raw format shown. - -The following example illustrates a condensed and annotated section of metadata decoded and converted to JSON: - -```json -[ - 1635018093, - { - "V14": { - "types": { - "types": [{}] - }, - "pallets": [{}], - "extrinsic": { - "ty": 126, - "version": 4, - "signed_extensions": [{}] - }, - "ty": 141 - } - } -] - -``` - -The constant `1635018093` is a magic number that identifies the file as a metadata file. The rest of the metadata is divided into the `types`, `pallets`, and `extrinsic` sections: - -- The `types` section contains an index of the types and information about each type's type signature. -- The `pallets` section contains information about each pallet in the runtime. -- The `extrinsic` section describes the type identifier and transaction format version that the runtime uses. - -Different extrinsic versions can have varying formats, especially when considering [signed transactions](/reference/parachains/blocks-transactions-fees/transactions/#signed-transactions){target=\_blank}. - -### Pallets - -The following is a condensed and annotated example of metadata for a single element in the `pallets` array (the [`sudo`](https://paritytech.github.io/polkadot-sdk/master/pallet_sudo/index.html){target=\_blank} pallet): - -```json -{ - "name": "Sudo", - "storage": { - "prefix": "Sudo", - "entries": [ - { - "name": "Key", - "modifier": "Optional", - "ty": { - "Plain": 0 - }, - "default": [0], - "docs": ["The `AccountId` of the sudo key."] - } - ] - }, - "calls": { - "ty": 117 - }, - "event": { - "ty": 42 - }, - "constants": [], - "error": { - "ty": 124 - }, - "index": 8 -} - -``` - -Every element metadata contains the name of the pallet it represents and information about its storage, calls, events, and errors. You can look up details about the definition of the calls, events, and errors by viewing the type index identifier. The type index identifier is the `u32` integer used to access the type information for that item. For example, the type index identifier for calls in the Sudo pallet is 117. If you view information for that type identifier in the `types` section of the metadata, it provides information about the available calls, including the documentation for each call. - -For example, the following is a condensed excerpt of the calls for the Sudo pallet: - -```json -{ - "id": 117, - "type": { - "path": ["pallet_sudo", "pallet", "Call"], - "params": [ - { - "name": "T", - "type": null - } - ], - "def": { - "variant": { - "variants": [ - { - "name": "sudo", - "fields": [ - { - "name": "call", - "type": 114, - "typeName": "Box<::RuntimeCall>" - } - ], - "index": 0, - "docs": [ - "Authenticates sudo key, dispatches a function call with `Root` origin" - ] - }, - { - "name": "sudo_unchecked_weight", - "fields": [ - { - "name": "call", - "type": 114, - "typeName": "Box<::RuntimeCall>" - }, - { - "name": "weight", - "type": 8, - "typeName": "Weight" - } - ], - "index": 1, - "docs": [ - "Authenticates sudo key, dispatches a function call with `Root` origin" - ] - }, - { - "name": "set_key", - "fields": [ - { - "name": "new", - "type": 103, - "typeName": "AccountIdLookupOf" - } - ], - "index": 2, - "docs": [ - "Authenticates current sudo key, sets the given AccountId (`new`) as the new sudo" - ] - }, - { - "name": "sudo_as", - "fields": [ - { - "name": "who", - "type": 103, - "typeName": "AccountIdLookupOf" - }, - { - "name": "call", - "type": 114, - "typeName": "Box<::RuntimeCall>" - } - ], - "index": 3, - "docs": [ - "Authenticates sudo key, dispatches a function call with `Signed` origin from a given account" - ] - } - ] - } - } - } -} - -``` - -For each field, you can access type information and metadata for the following: - -- **Storage metadata**: Provides the information required to enable applications to get information for specific storage items. -- **Call metadata**: Includes information about the runtime calls defined by the `#[pallet]` macro including call names, arguments and documentation. -- **Event metadata**: Provides the metadata generated by the `#[pallet::event]` macro, including the name, arguments, and documentation for each pallet event. -- **Constants metadata**: Provides metadata generated by the `#[pallet::constant]` macro, including the name, type, and hex-encoded value of the constant. -- **Error metadata**: Provides metadata generated by the `#[pallet::error]` macro, including the name and documentation for each pallet error. - -!!!tip - Type identifiers change from time to time, so you should avoid relying on specific type identifiers in your applications. - -### Extrinsic - -The runtime generates extrinsic metadata and provides useful information about transaction format. When decoded, the metadata contains the transaction version and the list of signed extensions. - -For example: - -```json -{ - "extrinsic": { - "ty": 126, - "version": 4, - "signed_extensions": [ - { - "identifier": "CheckNonZeroSender", - "ty": 132, - "additional_signed": 41 - }, - { - "identifier": "CheckSpecVersion", - "ty": 133, - "additional_signed": 4 - }, - { - "identifier": "CheckTxVersion", - "ty": 134, - "additional_signed": 4 - }, - { - "identifier": "CheckGenesis", - "ty": 135, - "additional_signed": 11 - }, - { - "identifier": "CheckMortality", - "ty": 136, - "additional_signed": 11 - }, - { - "identifier": "CheckNonce", - "ty": 138, - "additional_signed": 41 - }, - { - "identifier": "CheckWeight", - "ty": 139, - "additional_signed": 41 - }, - { - "identifier": "ChargeTransactionPayment", - "ty": 140, - "additional_signed": 41 - } - ] - }, - "ty": 141 -} - -``` - -The type system is [composite](https://paritytech.github.io/polkadot-sdk/master/polkadot_sdk_docs/reference_docs/frame_runtime_types/index.html){target=\_blank}, meaning each type identifier contains a reference to a specific type or to another type identifier that provides information about the associated primitive types. - -For example, you can encode the `BitVec` type, but to decode it properly, you must know the types used for the `Order` and `Store` types. To find type information for `Order` and `Store`, you can use the path in the decoded JSON to locate their type identifiers. - -## Included RPC APIs - -A standard node comes with the following APIs to interact with a node: - -- **[`AuthorApiServer`](https://paritytech.github.io/polkadot-sdk/master/sc_rpc/author/trait.AuthorApiServer.html){target=\_blank}**: Make calls into a full node, including authoring extrinsics and verifying session keys. -- **[`ChainApiServer`](https://paritytech.github.io/polkadot-sdk/master/sc_rpc/chain/trait.ChainApiServer.html){target=\_blank}**: Retrieve block header and finality information. -- **[`OffchainApiServer`](https://paritytech.github.io/polkadot-sdk/master/sc_rpc/offchain/trait.OffchainApiServer.html){target=\_blank}**: Make RPC calls for off-chain workers. -- **[`StateApiServer`](https://paritytech.github.io/polkadot-sdk/master/sc_rpc/state/trait.StateApiServer.html){target=\_blank}**: Query information about on-chain state such as runtime version, storage items, and proofs. -- **[`SystemApiServer`](https://paritytech.github.io/polkadot-sdk/master/sc_rpc/system/trait.SystemApiServer.html){target=\_blank}**: Retrieve information about network state, such as connected peers and node roles. - -## Additional Resources - -The following tools can help you locate and decode metadata: - -- [Subxt Explorer](https://paritytech.github.io/subxt-explorer/#/){target=\_blank} -- [Metadata Portal 🌗](https://github.com/paritytech/metadata-portal){target=\_blank} -- [De[code] Sub[strate]](https://github.com/paritytech/desub){target=\_blank} - - --- Page Title: Connect to Polkadot @@ -816,280 +382,6 @@ Both REVM and PolkaVM deployments may show significant differences between gas e Both backends support contract deployment effectively, with REVM offering drop-in Ethereum compatibility and PolkaVM providing a more structured two-step approach. For the majority of use cases—deploying standard contracts like tokens or applications—both backends work seamlessly. Advanced patterns like factory contracts may require adjustment for PolkaVM, but these adaptations are straightforward with proper planning. ---- - -Page Title: Cryptography - -- Source (raw): https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/reference-parachains-cryptography.md -- Canonical (HTML): https://docs.polkadot.com/reference/parachains/cryptography/ -- Summary: A concise guide to cryptography in blockchain, covering hash functions, encryption types, digital signatures, and elliptic curve applications. - -# Cryptography - -## Introduction - -Cryptography forms the backbone of blockchain technology, providing the mathematical verifiability crucial for consensus systems, data integrity, and user security. While a deep understanding of the underlying mathematical processes isn't necessary for most blockchain developers, grasping the fundamental applications of cryptography is essential. This page comprehensively overviews cryptographic implementations used across Polkadot SDK-based chains and the broader blockchain ecosystem. - -## Hash Functions - -Hash functions are fundamental to blockchain technology, creating a unique digital fingerprint for any piece of data, including simple text, images, or any other form of file. They map input data of any size to a fixed-size output (typically 32 bytes) using complex mathematical operations. Hashing is used to verify data integrity, create digital signatures, and provide a secure way to store passwords. This form of mapping is known as the ["pigeonhole principle,"](https://en.wikipedia.org/wiki/Pigeonhole_principle){target=\_blank} it is primarily implemented to efficiently and verifiably identify data from large sets. - -### Key Properties of Hash Functions - -- **Deterministic**: The same input always produces the same output. -- **Quick computation**: It's easy to calculate the hash value for any given input. -- **Pre-image resistance**: It's infeasible to generate the input data from its hash. -- **Small changes in input yield large changes in output**: Known as the ["avalanche effect"](https://en.wikipedia.org/wiki/Avalanche_effect){target=\_blank}. -- **Collision resistance**: The probabilities are extremely low to find two different inputs with the same hash. - -### Blake2 - -The Polkadot SDK utilizes Blake2, a state-of-the-art hashing method that offers: - -- Equal or greater security compared to [SHA-2](https://en.wikipedia.org/wiki/SHA-2){target=\_blank}. -- Significantly faster performance than other algorithms. - -These properties make Blake2 ideal for blockchain systems, reducing sync times for new nodes and lowering the resources required for validation. For detailed technical specifications about Blake2, see the [official Blake2 paper](https://www.blake2.net/blake2.pdf){target=\_blank}. - -## Types of Cryptography - -There are two different ways that cryptographic algorithms are implemented: symmetric cryptography and asymmetric cryptography. - -### Symmetric Cryptography - -Symmetric encryption is a branch of cryptography that isn't based on one-way functions, unlike asymmetric cryptography. It uses the same cryptographic key to encrypt plain text and decrypt the resulting ciphertext. - -Symmetric cryptography is a type of encryption that has been used throughout history, such as the Enigma Cipher and the Caesar Cipher. It is still widely used today and can be found in Web2 and Web3 applications alike. There is only one single key, and a recipient must also have access to it to access the contained information. - -#### Advantages {: #symmetric-advantages } - -- Fast and efficient for large amounts of data. -- Requires less computational power. - -#### Disadvantages {: #symmetric-disadvantages } - -- Key distribution can be challenging. -- Scalability issues in systems with many users. - -### Asymmetric Cryptography - -Asymmetric encryption is a type of cryptography that uses two different keys, known as a keypair: a public key, used to encrypt plain text, and a private counterpart, used to decrypt the ciphertext. - -The public key encrypts a fixed-length message that can only be decrypted with the recipient's private key and, sometimes, a set password. The public key can be used to cryptographically verify that the corresponding private key was used to create a piece of data without compromising the private key, such as with digital signatures. This has obvious implications for identity, ownership, and properties and is used in many different protocols across Web2 and Web3. - -#### Advantages {: #asymmetric-advantages } - -- Solves the key distribution problem. -- Enables digital signatures and secure key exchange. - -#### Disadvantages {: #asymmetric-disadvantages } - -- Slower than symmetric encryption. -- Requires more computational resources. - -### Trade-offs and Compromises - -Symmetric cryptography is faster and requires fewer bits in the key to achieve the same level of security that asymmetric cryptography provides. However, it requires a shared secret before communication can occur, which poses issues to its integrity and a potential compromise point. On the other hand, asymmetric cryptography doesn't require the secret to be shared ahead of time, allowing for far better end-user security. - -Hybrid symmetric and asymmetric cryptography is often used to overcome the engineering issues of asymmetric cryptography, as it is slower and requires more bits in the key to achieve the same level of security. It encrypts a key and then uses the comparatively lightweight symmetric cipher to do the "heavy lifting" with the message. - -## Digital Signatures - -Digital signatures are a way of verifying the authenticity of a document or message using asymmetric keypairs. They are used to ensure that a sender or signer's document or message hasn't been tampered with in transit, and for recipients to verify that the data is accurate and from the expected sender. - -Signing digital signatures only requires a low-level understanding of mathematics and cryptography. For a conceptual example -- when signing a check, it is expected that it cannot be cashed multiple times. This isn't a feature of the signature system but rather the check serialization system. The bank will check that the serial number on the check hasn't already been used. Digital signatures essentially combine these two concepts, allowing the signature to provide the serialization via a unique cryptographic fingerprint that cannot be reproduced. - -Unlike pen-and-paper signatures, knowledge of a digital signature cannot be used to create other signatures. Digital signatures are often used in bureaucratic processes, as they are more secure than simply scanning in a signature and pasting it onto a document. - -Polkadot SDK provides multiple different cryptographic schemes and is generic so that it can support anything that implements the [`Pair` trait](https://paritytech.github.io/polkadot-sdk/master/sp_core/crypto/trait.Pair.html){target=\_blank}. - -### Example of Creating a Digital Signature - -The process of creating and verifying a digital signature involves several steps: - -1. The sender creates a hash of the message. -2. The hash is encrypted using the sender's private key, creating the signature. -3. The message and signature are sent to the recipient. -4. The recipient decrypts the signature using the sender's public key. -5. The recipient hashes the received message and compares it to the decrypted hash. - -If the hashes match, the signature is valid, confirming the message's integrity and the sender's identity. - -## Elliptic Curve - -Blockchain technology requires the ability to have multiple keys creating a signature for block proposal and validation. To this end, Elliptic Curve Digital Signature Algorithm (ECDSA) and Schnorr signatures are two of the most commonly used methods. While ECDSA is a far simpler implementation, Schnorr signatures are more efficient when it comes to multi-signatures. - -Schnorr signatures bring some noticeable features over the ECDSA/EdDSA schemes: - -- It is better for hierarchical deterministic key derivations. -- It allows for native multi-signature through [signature aggregation](https://bitcoincore.org/en/2017/03/23/schnorr-signature-aggregation/){target=\_blank}. -- It is generally more resistant to misuse. - -One sacrifice that is made when using Schnorr signatures over ECDSA is that both require 64 bytes, but only ECDSA signatures communicate their public key. - -### Various Implementations - -- **[ECDSA](https://en.wikipedia.org/wiki/Elliptic_Curve_Digital_Signature_Algorithm){target=\_blank}**: Polkadot SDK provides an ECDSA signature scheme using the [secp256k1](https://en.bitcoin.it/wiki/Secp256k1){target=\_blank} curve. This is the same cryptographic algorithm used to secure [Bitcoin](https://en.wikipedia.org/wiki/Bitcoin){target=\_blank} and [Ethereum](https://en.wikipedia.org/wiki/Ethereum){target=\_blank}. - -- **[Ed25519](https://en.wikipedia.org/wiki/EdDSA#Ed25519){target=\_blank}**: An EdDSA signature scheme using [Curve25519](https://en.wikipedia.org/wiki/Curve25519){target=\_blank}. It is carefully engineered at several levels of design and implementation to achieve very high speeds without compromising security. - -- **[SR25519](https://research.web3.foundation/Polkadot/security/keys/accounts-more){target=\_blank}**: Based on the same underlying curve as Ed25519. However, it uses Schnorr signatures instead of the EdDSA scheme. - - ---- - -Page Title: Data Encoding - -- Source (raw): https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/reference-parachains-data-encoding.md -- Canonical (HTML): https://docs.polkadot.com/reference/parachains/data-encoding/ -- Summary: SCALE codec enables fast, efficient data encoding, ideal for resource-constrained environments like Wasm, supporting custom types and compact encoding. - -# Data Encoding - -## Introduction - -The Polkadot SDK uses a lightweight and efficient encoding/decoding mechanism to optimize data transmission across the network. This mechanism, known as the _SCALE_ codec, is used for serializing and deserializing data. - -The SCALE codec enables communication between the runtime and the outer node. This mechanism is designed for high-performance, copy-free data encoding and decoding in resource-constrained environments like the Polkadot SDK [Wasm runtime](/develop/parachains/deployment/build-deterministic-runtime/#introduction){target=\_blank}. - -It is not self-describing, meaning the decoding context must fully know the encoded data types. - -Parity's libraries utilize the [`parity-scale-codec`](https://github.com/paritytech/parity-scale-codec){target=\_blank} crate (a Rust implementation of the SCALE codec) to handle encoding and decoding for interactions between RPCs and the runtime. - -The `codec` mechanism is ideal for Polkadot SDK-based chains because: - -- It is lightweight compared to generic serialization frameworks like [`serde`](https://serde.rs/){target=\_blank}, which add unnecessary bulk to binaries. -- It doesn’t rely on Rust’s `libstd`, making it compatible with `no_std` environments like Wasm runtime. -- It integrates seamlessly with Rust, allowing easy derivation of encoding and decoding logic for new types using `#[derive(Encode, Decode)]`. - -Defining a custom encoding scheme in the Polkadot SDK-based chains, rather than using an existing Rust codec library, is crucial for enabling cross-platform and multi-language support. - -## SCALE Codec - -The codec is implemented using the following traits: - -- [`Encode`](#encode) -- [`Decode`](#decode) -- [`CompactAs`](#compactas) -- [`HasCompact`](#hascompact) -- [`EncodeLike`](#encodelike) - -### Encode - -The [`Encode`](https://docs.rs/parity-scale-codec/latest/parity_scale_codec/trait.Encode.html){target=\_blank} trait handles data encoding into SCALE format and includes the following key functions: - -- **`size_hint(&self) -> usize`**: Estimates the number of bytes required for encoding to prevent multiple memory allocations. This should be inexpensive and avoid complex operations. Optional if the size isn’t known. -- **`encode_to(&self, dest: &mut T)`**: Encodes the data, appending it to a destination buffer. -- **`encode(&self) -> Vec`**: Encodes the data and returns it as a byte vector. -- **`using_encoded R>(&self, f: F) -> R`**: Encodes the data and passes it to a closure, returning the result. -- **`encoded_size(&self) -> usize`**: Calculates the encoded size. Should be used when the encoded data isn’t required. - -!!!tip - For best performance, value types should override `using_encoded`, and allocating types should override `encode_to`. It's recommended to implement `size_hint` for all types where possible. - -### Decode - -The [`Decode`](https://docs.rs/parity-scale-codec/latest/parity_scale_codec/trait.Decode.html){target=\_blank} trait handles decoding SCALE-encoded data back into the appropriate types: - -- **`fn decode(value: &mut I) -> Result`**: Decodes data from the SCALE format, returning an error if decoding fails. - -### CompactAs - -The [`CompactAs`](https://docs.rs/parity-scale-codec/latest/parity_scale_codec/trait.CompactAs.html){target=\_blank} trait wraps custom types for compact encoding: - -- **`encode_as(&self) -> &Self::As`**: Encodes the type as a compact type. -- **`decode_from(_: Self::As) -> Result`**: decodes from a compact encoded type. - -### HasCompact - -The [`HasCompact`](https://docs.rs/parity-scale-codec/latest/parity_scale_codec/trait.HasCompact.html){target=\_blank} trait indicates a type supports compact encoding. - -### EncodeLike - -The [`EncodeLike`](https://docs.rs/parity-scale-codec/latest/parity_scale_codec/trait.EncodeLike.html){target=\_blank} trait is used to ensure multiple types that encode similarly are accepted by the same function. When using `derive`, it is automatically implemented. - -### Data Types - -The table below outlines how the Rust implementation of the Parity SCALE codec encodes different data types. - -| Type | Description | Example SCALE Decoded Value | SCALE Encoded Value | -|-------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------|-------------------------------------------------------------------------| -| Boolean | Boolean values are encoded using the least significant bit of a single byte. | `false` / `true` | `0x00` / `0x01` | -| Compact/general integers | A "compact" or general integer encoding is sufficient for encoding large integers (up to 2^536) and is more efficient at encoding most values than the fixed-width version. | `unsigned integer 0` / `unsigned integer 1` / `unsigned integer 42` / `unsigned integer 69` / `unsigned integer 65535` / `BigInt(100000000000000)` | `0x00` / `0x04` / `0xa8` / `0x1501` / `0xfeff0300` / `0x0b00407a10f35a` | -| Enumerations (tagged-unions) | A fixed number of variants, each mutually exclusive and potentially implying a further value or series of values. Encoded as the first byte identifying the index of the variant that the value is. Any further bytes are used to encode any data that the variant implies. Thus, no more than 256 variants are supported. | `Int(42)` and `Bool(true)` where `enum IntOrBool { Int(u8), Bool(bool) }` | `0x002a` and `0x0101` | -| Fixed-width integers | Basic integers are encoded using a fixed-width little-endian (LE) format. | `signed 8-bit integer 69` / `unsigned 16-bit integer 42` / `unsigned 32-bit integer 16777215` | `0x45` / `0x2a00` / `0xffffff00` | -| Options | One or zero values of a particular type. | `Some` / `None` | `0x01` followed by the encoded value / `0x00` | -| Results | Results are commonly used enumerations which indicate whether certain operations were successful or unsuccessful. | `Ok(42)` / `Err(false)` | `0x002a` / `0x0100` | -| Strings | Strings are Vectors of bytes (Vec) containing a valid UTF8 sequence. | | | -| Structs | For structures, the values are named, but that is irrelevant for the encoding (names are ignored - only order matters). | `SortedVecAsc::from([3, 5, 2, 8])` | `[3, 2, 5, 8] ` | -| Tuples | A fixed-size series of values, each with a possibly different but predetermined and fixed type. This is simply the concatenation of each encoded value. | Tuple of compact unsigned integer and boolean: `(3, false)` | `0x0c00` | -| Vectors (lists, series, sets) | A collection of same-typed values is encoded, prefixed with a compact encoding of the number of items, followed by each item's encoding concatenated in turn. | Vector of unsigned `16`-bit integers: `[4, 8, 15, 16, 23, 42]` | `0x18040008000f00100017002a00` | - -## Encode and Decode Rust Trait Implementations - -Here's how the `Encode` and `Decode` traits are implemented: - - -```rust -use parity_scale_codec::{Encode, Decode}; - -[derive(Debug, PartialEq, Encode, Decode)] -enum EnumType { - #[codec(index = 15)] - A, - B(u32, u64), - C { - a: u32, - b: u64, - }, -} - -let a = EnumType::A; -let b = EnumType::B(1, 2); -let c = EnumType::C { a: 1, b: 2 }; - -a.using_encoded(|ref slice| { - assert_eq!(slice, &b"\x0f"); -}); - -b.using_encoded(|ref slice| { - assert_eq!(slice, &b"\x01\x01\0\0\0\x02\0\0\0\0\0\0\0"); -}); - -c.using_encoded(|ref slice| { - assert_eq!(slice, &b"\x02\x01\0\0\0\x02\0\0\0\0\0\0\0"); -}); - -let mut da: &[u8] = b"\x0f"; -assert_eq!(EnumType::decode(&mut da).ok(), Some(a)); - -let mut db: &[u8] = b"\x01\x01\0\0\0\x02\0\0\0\0\0\0\0"; -assert_eq!(EnumType::decode(&mut db).ok(), Some(b)); - -let mut dc: &[u8] = b"\x02\x01\0\0\0\x02\0\0\0\0\0\0\0"; -assert_eq!(EnumType::decode(&mut dc).ok(), Some(c)); - -let mut dz: &[u8] = &[0]; -assert_eq!(EnumType::decode(&mut dz).ok(), None); -``` - -## SCALE Codec Libraries - -Several SCALE codec implementations are available in various languages. Here's a list of them: - -- **AssemblyScript**: [`LimeChain/as-scale-codec`](https://github.com/LimeChain/as-scale-codec){target=\_blank} -- **C**: [`MatthewDarnell/cScale`](https://github.com/MatthewDarnell/cScale){target=\_blank} -- **C++**: [`qdrvm/scale-codec-cpp`](https://github.com/qdrvm/scale-codec-cpp){target=\_blank} -- **JavaScript**: [`polkadot-js/api`](https://github.com/polkadot-js/api){target=\_blank} -- **Dart**: [`leonardocustodio/polkadart`](https://github.com/leonardocustodio/polkadart){target=\_blank} -- **Haskell**: [`airalab/hs-web3`](https://github.com/airalab/hs-web3/tree/master/packages/scale){target=\_blank} -- **Golang**: [`itering/scale.go`](https://github.com/itering/scale.go){target=\_blank} -- **Java**: [`splix/polkaj`](https://github.com/splix/polkaj){target=\_blank} -- **Python**: [`polkascan/py-scale-codec`](https://github.com/polkascan/py-scale-codec){target=\_blank} -- **Ruby**: [` wuminzhe/scale_rb`](https://github.com/wuminzhe/scale_rb){target=\_blank} -- **TypeScript**: [`parity-scale-codec-ts`](https://github.com/tjjfvi/subshape){target=\_blank}, [`scale-ts`](https://github.com/unstoppablejs/unstoppablejs/tree/main/packages/scale-ts#scale-ts){target=\_blank}, [`soramitsu/scale-codec-js-library`](https://github.com/soramitsu/scale-codec-js-library){target=\_blank}, [`subsquid/scale-codec`](https://github.com/subsquid/squid-sdk/tree/master/substrate/scale-codec){target=\_blank} - - --- Page Title: Deploy a Basic Contract to Polkadot Hub @@ -4462,374 +3754,6 @@ For Polkadot Hub TestNet, you can use the [Polkadot Faucet](https://faucet.polka Getting started with test tokens is the first step in your Polkadot development journey. These free resources enable you to build, experiment with, and refine your applications without financial constraints, ensuring your projects are robust and ready for deployment on MainNet. ---- - -Page Title: Glossary - -- Source (raw): https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/reference-glossary.md -- Canonical (HTML): https://docs.polkadot.com/reference/glossary/ -- Summary: Glossary of terms used within the Polkadot ecosystem, Polkadot SDK, its subsequent libraries, and other relevant Web3 terminology. - -# Glossary - -Key definitions, concepts, and terminology specific to the Polkadot ecosystem are included here. - -Additional glossaries from around the ecosystem you might find helpful: - -- [Polkadot Wiki Glossary](https://wiki.polkadot.com/general/glossary){target=\_blank} -- [Polkadot SDK Glossary](https://paritytech.github.io/polkadot-sdk/master/polkadot_sdk_docs/reference_docs/glossary/index.html){target=\_blank} - -## Authority - -The role in a blockchain that can participate in consensus mechanisms. - -- **[GRANDPA](#grandpa)**: The authorities vote on chains they consider final. -- **[Blind Assignment of Blockchain Extension](#blind-assignment-of-blockchain-extension-babe) (BABE)**: The authorities are also [block authors](#block-author). - -Authority sets can be used as a basis for consensus mechanisms such as the [Nominated Proof of Stake (NPoS)](#nominated-proof-of-stake-npos) protocol. - -## Authority Round (Aura) - -A deterministic [consensus](#consensus) protocol where block production is limited to a rotating list of [authorities](#authority) that take turns creating blocks. In authority round (Aura) consensus, most online authorities are assumed to be honest. It is often used in combination with [GRANDPA](#grandpa) as a [hybrid consensus](#hybrid-consensus) protocol. - -Learn more by reading the official [Aura consensus algorithm](https://openethereum.github.io/Aura){target=\_blank} wiki article. - -## Blind Assignment of Blockchain Extension (BABE) - -A [block authoring](#block-author) protocol similar to [Aura](#authority-round-aura), except [authorities](#authority) win [slots](#slot) based on a Verifiable Random Function (VRF) instead of the round-robin selection method. The winning authority can select a chain and submit a new block. - -Learn more by reading the official Web3 Foundation [BABE research document](https://research.web3.foundation/Polkadot/protocols/block-production/Babe){target=\_blank}. - -## Block Author - -The node responsible for the creation of a block, also called _block producers_. In a Proof of Work (PoW) blockchain, these nodes are called _miners_. - -## Byzantine Fault Tolerance (BFT) - -The ability of a distributed computer network to remain operational if a certain proportion of its nodes or [authorities](#authority) are defective or behaving maliciously. A distributed network is typically considered Byzantine fault tolerant if it can remain functional, with up to one-third of nodes assumed to be defective, offline, actively malicious, and part of a coordinated attack. - -### Byzantine Failure - -The loss of a network service due to node failures that exceed the proportion of nodes required to reach consensus. - -### Practical Byzantine Fault Tolerance (pBFT) - -An early approach to Byzantine fault tolerance (BFT), practical Byzantine fault tolerance (pBFT) systems tolerate Byzantine behavior from up to one-third of participants. - -The communication overhead for such systems is `O(n²)`, where `n` is the number of nodes (participants) in the system. - -### Preimage - -A preimage is the data that is input into a hash function to calculate a hash. Since a hash function is a [one-way function](https://en.wikipedia.org/wiki/One-way_function){target=\_blank}, the output, the hash, cannot be used to reveal the input, the preimage. - -## Call - -In the context of pallets containing functions to be dispatched to the runtime, `Call` is an enumeration data type that describes the functions that can be dispatched with one variant per pallet. A `Call` represents a [dispatch](#dispatchable) data structure object. - -## Chain Specification - -A chain specification file defines the properties required to run a node in an active or new Polkadot SDK-built network. It often contains the initial genesis runtime code, network properties (such as the network's name), the initial state for some pallets, and the boot node list. The chain specification file makes it easy to use a single Polkadot SDK codebase as the foundation for multiple independently configured chains. - -## Collator - -An [author](#block-author) of a [parachain](#parachain) network. -They aren't [authorities](#authority) in themselves, as they require a [relay chain](#relay-chain) to coordinate [consensus](#consensus). - -More details are found on the [Polkadot Collator Wiki](https://wiki.polkadot.com/learn/learn-collator/){target=\_blank}. - -## Collective - -Most often used to refer to an instance of the Collective pallet on Polkadot SDK-based networks such as [Kusama](#kusama) or [Polkadot](#polkadot) if the Collective pallet is part of the FRAME-based runtime for the network. - -## Consensus - -Consensus is the process blockchain nodes use to agree on a chain's canonical fork. It is composed of [authorship](#block-author), finality, and [fork-choice rule](#fork-choice-rulestrategy). In the Polkadot ecosystem, these three components are usually separate and the term consensus often refers specifically to authorship. - -See also [hybrid consensus](#hybrid-consensus). - -## Consensus Algorithm - -Ensures a set of [actors](#authority)—who don't necessarily trust each other—can reach an agreement about the state as the result of some computation. Most consensus algorithms assume that up to one-third of the actors or nodes can be [Byzantine fault tolerant](#byzantine-fault-tolerance-bft). - -Consensus algorithms are generally concerned with ensuring two properties: - -- **Safety**: Indicating that all honest nodes eventually agreed on the state of the chain. -- **Liveness**: Indicating the ability of the chain to keep progressing. - -## Consensus Engine - -The node subsystem responsible for consensus tasks. - -For detailed information about the consensus strategies of the [Polkadot](#polkadot) network, see the [Polkadot Consensus](/reference/polkadot-hub/consensus-and-security/pos-consensus/){target=\_blank} blog series. - -See also [hybrid consensus](#hybrid-consensus). - -## Coretime - -The time allocated for utilizing a core, measured in relay chain blocks. There are two types of coretime: *on-demand* and *bulk*. - -On-demand coretime refers to coretime acquired through bidding in near real-time for the validation of a single parachain block on one of the cores reserved specifically for on-demand orders. They are available as an on-demand coretime pool. Set of cores that are available on-demand. Cores reserved through bulk coretime could also be made available in the on-demand coretime pool, in parts or in entirety. - -Bulk coretime is a fixed duration of continuous coretime represented by an NFT that can be split, shared, or resold. It is managed by the [Broker pallet](https://paritytech.github.io/polkadot-sdk/master/pallet_broker/index.html){target=\_blank}. - -## Development Phrase - -A [mnemonic phrase](https://en.wikipedia.org/wiki/Mnemonic#For_numerical_sequences_and_mathematical_operations){target=\_blank} that is intentionally made public. - -Well-known development accounts, such as Alice, Bob, Charlie, Dave, Eve, and Ferdie, are generated from the same secret phrase: - -``` -bottom drive obey lake curtain smoke basket hold race lonely fit walk -``` - -Many tools in the Polkadot SDK ecosystem, such as [`subkey`](https://github.com/paritytech/polkadot-sdk/tree/polkadot-stable2506-2/substrate/bin/utils/subkey){target=\_blank}, allow you to implicitly specify an account using a derivation path such as `//Alice`. - -## Digest - -An extensible field of the [block header](#header) that encodes information needed by several actors in a blockchain network, including: - -- [Light clients](#light-client) for chain synchronization. -- Consensus engines for block verification. -- The runtime itself, in the case of pre-runtime digests. - -## Dispatchable - -Function objects that act as the entry points in FRAME [pallets](#pallet). Internal or external entities can call them to interact with the blockchain’s state. They are a core aspect of the runtime logic, handling [transactions](#transaction) and other state-changing operations. - -## Events - -A means of recording that some particular [state](#state) transition happened. - -In the context of [FRAME](#frame-framework-for-runtime-aggregation-of-modularized-entities), events are composable data types that each [pallet](#pallet) can individually define. Events in FRAME are implemented as a set of transient storage items inspected immediately after a block has been executed and reset during block initialization. - -## Executor - -A means of executing a function call in a given [runtime](#runtime) with a set of dependencies. -There are two orchestration engines in Polkadot SDK, _WebAssembly_ and _native_. - -- The _native executor_ uses a natively compiled runtime embedded in the node to execute calls. This is a performance optimization available to up-to-date nodes. - -- The _WebAssembly executor_ uses a [Wasm](#webassembly-wasm) binary and a Wasm interpreter to execute calls. The binary is guaranteed to be up-to-date regardless of the version of the blockchain node because it is persisted in the [state](#state) of the Polkadot SDK-based chain. - -## Existential Deposit - -The minimum balance an account is allowed to have in the [Balances pallet](https://paritytech.github.io/polkadot-sdk/master/pallet_balances/index.html){target=\_blank}. Accounts cannot be created with a balance less than the existential deposit amount. - -If an account balance drops below this amount, the Balances pallet uses [a FRAME System API](https://paritytech.github.io/substrate/master/frame_system/pallet/struct.Pallet.html#method.dec_ref){target=\_blank} to drop its references to that account. - -If the Balances pallet reference to an account is dropped, the account can be [reaped](https://paritytech.github.io/substrate/master/frame_system/pallet/struct.Pallet.html#method.allow_death){target=\_blank}. - -## Extrinsic - -A general term for data that originates outside the runtime, is included in a block, and leads to some action. This includes user-initiated transactions and inherent transactions placed into the block by the block builder. - -It is a SCALE-encoded array typically consisting of a version number, signature, and varying data types indicating the resulting runtime function to be called. Extrinsics can take two forms: [inherents](#inherent-transactions) and [transactions](#transaction). - -For more technical details, see the [Polkadot spec](https://spec.polkadot.network/id-extrinsics){target=\_blank}. - -## Fork Choice Rule/Strategy - -A fork choice rule or strategy helps determine which chain is valid when reconciling several network forks. A common fork choice rule is the [longest chain](https://paritytech.github.io/polkadot-sdk/master/sc_consensus/struct.LongestChain.html){target=\_blank}, in which the chain with the most blocks is selected. - -## FRAME (Framework for Runtime Aggregation of Modularized Entities) - -Enables developers to create blockchain [runtime](#runtime) environments from a modular set of components called [pallets](#pallet). It utilizes a set of procedural macros to construct runtimes. - -[Visit the Polkadot SDK docs for more details on FRAME.](https://paritytech.github.io/polkadot-sdk/master/polkadot_sdk_docs/polkadot_sdk/frame_runtime/index.html){target=\_blank} - -## Full Node - -A node that prunes historical states, keeping only recently finalized block states to reduce storage needs. Full nodes provide current chain state access and allow direct submission and validation of [extrinsics](#extrinsic), maintaining network decentralization. - -## Genesis Configuration - -A mechanism for specifying the initial state of a blockchain. By convention, this initial state or first block is commonly referred to as the genesis state or genesis block. The genesis configuration for Polkadot SDK-based chains is accomplished by way of a [chain specification](#chain-specification) file. - -## GRANDPA - -A deterministic finality mechanism for blockchains that is implemented in the [Rust](https://www.rust-lang.org/){target=\_blank} programming language. - -The [formal specification](https://github.com/w3f/consensus/blob/master/pdf/grandpa-old.pdf){target=\_blank} is maintained by the [Web3 Foundation](https://web3.foundation/){target=\_blank}. - -## Header - -A structure that aggregates the information used to summarize a block. Primarily, it consists of cryptographic information used by [light clients](#light-client) to get minimally secure but very efficient chain synchronization. - -## Hybrid Consensus - -A blockchain consensus protocol that consists of independent or loosely coupled mechanisms for [block production](#block-author) and finality. - -Hybrid consensus allows the chain to grow as fast as probabilistic consensus protocols, such as [Aura](#authority-round-aura), while maintaining the same level of security as deterministic finality consensus protocols, such as [GRANDPA](#grandpa). - -## Inherent Transactions - -A special type of unsigned transaction, referred to as _inherents_, that enables a block authoring node to insert information that doesn't require validation directly into a block. - -Only the block-authoring node that calls the inherent transaction function can insert data into its block. In general, validators assume the data inserted using an inherent transaction is valid and reasonable even if it can't be deterministically verified. - -## JSON-RPC - -A stateless, lightweight remote procedure call protocol encoded in JavaScript Object Notation (JSON). JSON-RPC provides a standard way to call functions on a remote system by using JSON. - -For Polkadot SDK, this protocol is implemented through the [Parity JSON-RPC](https://github.com/paritytech/jsonrpc){target=\_blank} crate. - -## Keystore - -A subsystem for managing keys for the purpose of producing new blocks. - -## Kusama - -[Kusama](https://kusama.network/){target=\_blank} is a Polkadot SDK-based blockchain that implements a design similar to the [Polkadot](#polkadot) network. - -Kusama is a [canary](https://en.wiktionary.org/wiki/canary_in_a_coal_mine){target=\_blank} network and is referred to as [Polkadot's "wild cousin."](https://wiki.polkadot.com/learn/learn-comparisons-kusama/){target=\_blank}. - -As a canary network, Kusama is expected to be more stable than a test network like [Westend](#westend) but less stable than a production network like [Polkadot](#polkadot). Kusama is controlled by its network participants and is intended to be stable enough to encourage meaningful experimentation. - -## libp2p - -A peer-to-peer networking stack that allows the use of many transport mechanisms, including WebSockets (usable in a web browser). - -Polkadot SDK uses the [Rust implementation](https://github.com/libp2p/rust-libp2p){target=\_blank} of the `libp2p` networking stack. - -## Light Client - -A type of blockchain node that doesn't store the [chain state](#state) or produce blocks. - -A light client can verify cryptographic primitives and provides a [remote procedure call (RPC)](https://en.wikipedia.org/wiki/Remote_procedure_call){target=\_blank} server, enabling blockchain users to interact with the network. - -## Metadata - -Data that provides information about one or more aspects of a system. -The metadata that exposes information about a Polkadot SDK blockchain enables you to interact with that system. - -## Nominated Proof of Stake (NPoS) - -A method for determining [validators](#validator) or _[authorities](#authority)_ based on a willingness to commit their stake to the proper functioning of one or more block-producing nodes. - -## Oracle - -An entity that connects a blockchain to a non-blockchain data source. Oracles enable the blockchain to access and act upon information from existing data sources and incorporate data from non-blockchain systems and services. - -## Origin - -A [FRAME](#frame-framework-for-runtime-aggregation-of-modularized-entities) primitive that identifies the source of a [dispatched](#dispatchable) function call into the [runtime](#runtime). The FRAME System pallet defines three built-in [origins](#origin). As a [pallet](#pallet) developer, you can also define custom origins, such as those defined by the [Collective pallet](https://paritytech.github.io/substrate/master/pallet_collective/enum.RawOrigin.html){target=\_blank}. - -## Pallet - -A module that can be used to extend the capabilities of a [FRAME](#frame-framework-for-runtime-aggregation-of-modularized-entities)-based [runtime](#runtime). -Pallets bundle domain-specific logic with runtime primitives like [events](#events) and [storage items](#storage-item). - -## Parachain - -A parachain is a blockchain that derives shared infrastructure and security from a _[relay chain](#relay-chain)_. -You can learn more about parachains on the [Polkadot Wiki](https://wiki.polkadot.com/learn/learn-parachains/){target=\_blank}. - -## Paseo - -Paseo TestNet provisions testing on Polkadot's "production" runtime, which means less chance of feature or code mismatch when developing parachain apps. Specifically, after the [Polkadot Technical fellowship](https://wiki.polkadot.com/learn/learn-polkadot-technical-fellowship/){target=\_blank} proposes a runtime upgrade for Polkadot, this TestNet is updated, giving a period where the TestNet will be ahead of Polkadot to allow for testing. - -## Polkadot - -The [Polkadot network](https://polkadot.com/){target=\_blank} is a blockchain that serves as the central hub of a heterogeneous blockchain network. It serves the role of the [relay chain](#relay-chain) and provides shared infrastructure and security to support [parachains](#parachain). - -## Polkadot Cloud - -Polkadot Cloud is a platform for deploying resilient, customizable and scalable Web3 applications through Polkadot's functionality. It encompasses the wider Polkadot network infrastructure and security layer where parachains operate. The platform enables users to launch Ethereum-compatible chains, build specialized blockchains, and flexibly manage computing resources through on-demand or bulk coretime purchases. Initially launched with basic parachain functionality, Polkadot Cloud has evolved to offer enhanced flexibility with features like coretime, elastic scaling, and async backing for improved performance. - -## Polkadot Hub - -Polkadot Hub is a Layer 1 platform that serves as the primary entry point to the Polkadot ecosystem, providing essential functionality without requiring parachain deployment. It offers core services including smart contracts, identity management, staking, governance, and interoperability with other ecosystems, making it simple and fast for both builders and users to get started in Web3. - -## PolkaVM - -PolkaVM is a custom virtual machine optimized for performance, leveraging a RISC-V-based architecture to support Solidity and any language that compiles to RISC-V. It is specifically designed for the Polkadot ecosystem, enabling smart contract deployment and execution. - -## Relay Chain - -Relay chains are blockchains that provide shared infrastructure and security to the [parachains](#parachain) in the network. In addition to providing [consensus](#consensus) capabilities, relay chains allow parachains to communicate and exchange digital assets without needing to trust one another. - -## Rococo - -A [parachain](#parachain) test network for the Polkadot network. The [Rococo](#rococo) network is a Polkadot SDK-based blockchain with an October 14, 2024 deprecation date. Development teams are encouraged to use the Paseo TestNet instead. - -## Runtime - -The runtime represents the [state transition function](#state-transition-function-stf) for a blockchain. In Polkadot SDK, the runtime is stored as a [Wasm](#webassembly-wasm) binary in the chain state. The Runtime is stored under a unique state key and can be modified during the execution of the state transition function. - -## Slot - -A fixed, equal interval of time used by consensus engines such as [Aura](#authority-round-aura) and [BABE](#blind-assignment-of-blockchain-extension-babe). In each slot, a subset of [authorities](#authority) is permitted, or obliged, to [author](#block-author) a block. - -## Sovereign Account - -The unique account identifier for each chain in the relay chain ecosystem. It is often used in cross-consensus (XCM) interactions to sign XCM messages sent to the relay chain or other chains in the ecosystem. - -The sovereign account for each chain is a root-level account that can only be accessed using the Sudo pallet or through governance. The account identifier is calculated by concatenating the Blake2 hash of a specific text string and the registered parachain identifier. - -## SS58 Address Format - -A public key address based on the Bitcoin [`Base-58-check`](https://en.bitcoin.it/wiki/Base58Check_encoding){target=\_blank} encoding. Each Polkadot SDK SS58 address uses a `base-58` encoded value to identify a specific account on a specific Polkadot SDK-based chain - -The [canonical `ss58-registry`](https://github.com/paritytech/ss58-registry){target=\_blank} provides additional details about the address format used by different Polkadot SDK-based chains, including the network prefix and website used for different networks - -## State Transition Function (STF) - -The logic of a blockchain that determines how the state changes when a block is processed. In Polkadot SDK, the state transition function is effectively equivalent to the [runtime](#runtime). - -## Storage Item - -[FRAME](#frame-framework-for-runtime-aggregation-of-modularized-entities) primitives that provide type-safe data persistence capabilities to the [runtime](#runtime). -Learn more in the [storage items](https://paritytech.github.io/polkadot-sdk/master/frame_support/storage/types/index.html){target=\_blank} reference document in the Polkadot SDK. - -## Substrate - -A flexible framework for building modular, efficient, and upgradeable blockchains. Substrate is written in the [Rust](https://www.rust-lang.org/){target=\_blank} programming language and is maintained by [Parity Technologies](https://www.parity.io/){target=\_blank}. - -## Transaction - -An [extrinsic](#extrinsic) that includes a signature that can be used to verify the account authorizing it inherently or via [signed extensions](https://paritytech.github.io/polkadot-sdk/master/polkadot_sdk_docs/reference_docs/signed_extensions/index.html){target=\_blank}. - -## Transaction Era - -A definable period expressed as a range of block numbers during which a transaction can be included in a block. -Transaction eras are used to protect against transaction replay attacks if an account is reaped and its replay-protecting nonce is reset to zero. - -## Trie (Patricia Merkle Tree) - -A data structure used to represent sets of key-value pairs and enables the items in the data set to be stored and retrieved using a cryptographic hash. Because incremental changes to the data set result in a new hash, retrieving data is efficient even if the data set is very large. With this data structure, you can also prove whether the data set includes any particular key-value pair without access to the entire data set. - -In Polkadot SDK-based blockchains, state is stored in a trie data structure that supports the efficient creation of incremental digests. This trie is exposed to the [runtime](#runtime) as [a simple key/value map](#storage-item) where both keys and values can be arbitrary byte arrays. - -## Validator - -A validator is a node that participates in the consensus mechanism of the network. Its roles include block production, transaction validation, network integrity, and security maintenance. - -## WebAssembly (Wasm) - -An execution architecture that allows for the efficient, platform-neutral expression of -deterministic, machine-executable logic. - -[Wasm](https://webassembly.org/){target=\_blank} can be compiled from many languages, including -the [Rust](https://www.rust-lang.org/){target=\_blank} programming language. Polkadot SDK-based chains use a Wasm binary to provide portable [runtimes](#runtime) that can be included as part of the chain's state. - -## Weight - -A convention used in Polkadot SDK-based blockchains to measure and manage the time it takes to validate a block. -Polkadot SDK defines one unit of weight as one picosecond of execution time on reference hardware. - -The maximum block weight should be equivalent to one-third of the target block time with an allocation of one-third each for: - -- Block construction -- Network propagation -- Import and verification - -By defining weights, you can trade-off the number of transactions per second and the hardware required to maintain the target block time appropriate for your use case. Weights are defined in the runtime, meaning you can tune them using runtime updates to keep up with hardware and software improvements. - -## Westend - -Westend is a Parity-maintained, Polkadot SDK-based blockchain that serves as a test network for the [Polkadot](#polkadot) network. - - --- Page Title: Install Polkadot SDK @@ -5443,76 +4367,6 @@ Head to the Polkadot Hub TestNet and start playing around with the precompile us You can use PAPI to build XCM programs and test them with Chopsticks. ---- - -Page Title: Interoperability - -- Source (raw): https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/reference-parachains-interoperability.md -- Canonical (HTML): https://docs.polkadot.com/reference/parachains/interoperability/ -- Summary: Explore the importance of interoperability in the Polkadot ecosystem, covering XCM, bridges, and cross-chain communication. - -# Interoperability - -## Introduction - -Interoperability lies at the heart of the Polkadot ecosystem, enabling communication and collaboration across a diverse range of blockchains. By bridging the gaps between parachains, relay chains, and even external networks, Polkadot unlocks the potential for truly decentralized applications, efficient resource sharing, and scalable solutions. - -Polkadot’s design ensures that blockchains can transcend their individual limitations by working together as part of a unified system. This cooperative architecture is what sets Polkadot apart in the blockchain landscape. - -## Why Interoperability Matters - -The blockchain ecosystem is inherently fragmented. Different blockchains excel in specialized domains such as finance, gaming, or supply chain management, but these chains function in isolation without interoperability. This lack of connectivity stifles the broader utility of blockchain technology. - -Interoperability solves this problem by enabling blockchains to: - -- **Collaborate across networks**: Chains can interact to share assets, functionality, and data, creating synergies that amplify their individual strengths. -- **Achieve greater scalability**: Specialized chains can offload tasks to others, optimizing performance and resource utilization. -- **Expand use-case potential**: Cross-chain applications can leverage features from multiple blockchains, unlocking novel user experiences and solutions. - -In the Polkadot ecosystem, interoperability transforms a collection of isolated chains into a cohesive, efficient network, pushing the boundaries of what blockchains can achieve together. - -## Key Mechanisms for Interoperability - -At the core of Polkadot's cross-chain collaboration are foundational technologies designed to break down barriers between networks. These mechanisms empower blockchains to communicate, share resources, and operate as a cohesive ecosystem. - -### Cross-Consensus Messaging (XCM): The Backbone of Communication - -Polkadot's Cross-Consensus Messaging (XCM) is the standard framework for interaction between parachains, relay chains, and, eventually, external blockchains. XCM provides a trustless, secure messaging format for exchanging assets, sharing data, and executing cross-chain operations. - -Through XCM, decentralized applications can: - -- Transfer tokens and other assets across chains. -- Coordinate complex workflows that span multiple blockchains. -- Enable seamless user experiences where underlying blockchain differences are invisible. -- XCM exemplifies Polkadot’s commitment to creating a robust and interoperable ecosystem. - -For further information about XCM, check the [Get Started with XCM](/parachains/interoperability/get-started/){target=\_blank} article. - -### Bridges: Connecting External Networks - -While XCM enables interoperability within the Polkadot ecosystem, bridges extend this functionality to external blockchains such as Ethereum and Bitcoin. By connecting these networks, bridges allow Polkadot-based chains to access external liquidity, additional functionalities, and broader user bases. - -With bridges, developers and users gain the ability to: - -- Integrate external assets into Polkadot-based applications. -- Combine the strengths of Polkadot’s scalability with the liquidity of other networks. -- Facilitate accurate multi-chain applications that transcend ecosystem boundaries. - -For more information about bridges in the Polkadot ecosystem, see the [Bridge Hub](/reference/polkadot-hub/bridging/){target=\_blank} guide. - -## The Polkadot Advantage - -Polkadot was purpose-built for interoperability. Unlike networks that add interoperability as an afterthought, Polkadot integrates it as a fundamental design principle. This approach offers several distinct advantages: - -- **Developer empowerment**: Polkadot’s interoperability tools allow developers to build applications that leverage multiple chains’ capabilities without added complexity. -- **Enhanced ecosystem collaboration**: Chains in Polkadot can focus on their unique strengths while contributing to the ecosystem’s overall growth. -- **Future-proofing blockchain**: By enabling seamless communication, Polkadot ensures its ecosystem can adapt to evolving demands and technologies. - -## Looking Ahead - -Polkadot’s vision of interoperability extends beyond technical functionality, representing a shift towards a more collaborative blockchain landscape. By enabling chains to work together, Polkadot fosters innovation, efficiency, and accessibility, paving the way for a decentralized future where blockchains are not isolated competitors but interconnected collaborators. - - --- Page Title: JSON-RPC APIs @@ -6673,1252 +5527,138 @@ Your existing Solidity knowledge and tooling transfer directly to Polkadot Hub, --- -Page Title: Networks +Page Title: Overview of FRAME -- Source (raw): https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/reference-parachains-networks.md -- Canonical (HTML): https://docs.polkadot.com/reference/parachains/networks/ -- Summary: Explore Polkadot's testing and production networks, including Westend, Kusama, and Paseo, for efficient development, deployment, and testing. +- Source (raw): https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/parachains-customize-runtime.md +- Canonical (HTML): https://docs.polkadot.com/parachains/customize-runtime/ +- Summary: Learn how Polkadot SDK’s FRAME framework simplifies blockchain development with modular pallets and support libraries for efficient runtime design. -# Networks +# Customize Your Runtime ## Introduction -The Polkadot ecosystem is built on a robust set of networks designed to enable secure and scalable development. Whether you are testing new features or deploying to live production, Polkadot offers several layers of networks tailored for each stage of the development process. From local environments to experimental networks like Kusama and community-run TestNets such as Paseo, developers can thoroughly test, iterate, and validate their applications. This guide will introduce you to Polkadot's various networks and explain how they fit into the development workflow. - -## Network Overview - -Polkadot's development process is structured to ensure new features and upgrades are rigorously tested before being deployed on live production networks. The progression follows a well-defined path, starting from local environments and advancing through TestNets, ultimately reaching the Polkadot MainNet. The diagram below outlines the typical progression of the Polkadot development cycle: - -``` mermaid -flowchart LR - id1[Local] --> id2[Westend] --> id4[Kusama] --> id5[Polkadot] - id1[Local] --> id3[Paseo] --> id5[Polkadot] -``` - -This flow ensures developers can thoroughly test and iterate without risking real tokens or affecting production networks. Testing tools like [Chopsticks](#chopsticks) and various TestNets make it easier to experiment safely before releasing to production. - -A typical journey through the Polkadot core protocol development process might look like this: - -1. **Local development node**: Development starts in a local environment, where developers can create, test, and iterate on upgrades or new features using a local development node. This stage allows rapid experimentation in an isolated setup without any external dependencies. - -2. **Westend**: After testing locally, upgrades are deployed to [Westend](#westend), Polkadot's primary TestNet. Westend simulates real-world conditions without using real tokens, making it the ideal place for rigorous feature testing before moving on to production networks. - -3. **Kusama**: Once features have passed extensive testing on Westend, they move to Kusama, Polkadot's experimental and fast-moving "canary" network. Kusama operates as a high-fidelity testing ground with actual economic incentives, giving developers insights into how their features will perform in a real-world environment. - -4. **Polkadot**: After passing tests on Westend and Kusama, features are considered ready for deployment to Polkadot, the live production network. - - In addition, parachain developers can leverage local TestNets like [Zombienet](#zombienet) and deploy upgrades on parachain TestNets. - -5. **Paseo**: For parachain and dApp developers, Paseo serves as a community-run TestNet that mirrors Polkadot's runtime. Like Westend for core protocol development, Paseo provides a testing ground for parachain development without affecting live networks. +A blockchain runtime is more than just a fixed set of rules—it's a dynamic foundation that you can shape to match your specific needs. With Polkadot SDK's [FRAME (Framework for Runtime Aggregation of Modularized Entities)](https://paritytech.github.io/polkadot-sdk/master/polkadot_sdk_docs/polkadot_sdk/frame_runtime/index.html){target=\_blank}, customizing your runtime is straightforward and modular. Instead of building everything from scratch, you combine pre-built pallets with your own custom logic to create a runtime suited to your blockchain's purpose. -!!!note - The Rococo TestNet deprecation date was October 14, 2024. Teams should use Westend for Polkadot protocol and feature testing and Paseo for chain development-related testing. -## Polkadot Development Networks -Development and testing are crucial to building robust dApps and parachains and performing network upgrades within the Polkadot ecosystem. To achieve this, developers can leverage various networks and tools that provide a risk-free environment for experimentation and validation before deploying features to live networks. These networks help avoid the costs and risks associated with real tokens, enabling testing for functionalities like governance, cross-chain messaging, and runtime upgrades. +This overview explains how runtime customization works, introduces the building blocks you'll use, and guides you through the key patterns for extending your runtime. -## Kusama Network +## Understanding Your Runtime -Kusama is the experimental version of Polkadot, designed for developers who want to move quickly and test their applications in a real-world environment with economic incentives. Kusama serves as a production-grade testing ground where developers can deploy features and upgrades with the pressure of game theory and economics in mind. It mirrors Polkadot but operates as a more flexible space for innovation. +The runtime is the core logic of your blockchain—it processes transactions, manages state, and enforces the rules that govern your network. When a transaction arrives at your blockchain, the [`frame_executive`](https://paritytech.github.io/polkadot-sdk/master/frame_executive/index.html){target=\_blank} pallet receives it and routes it to the appropriate pallet for execution. -The native token for Kusama is KSM. For more information about KSM, visit the [Native Assets](https://wiki.polkadot.com/kusama/kusama-getting-started/){target=\_blank} page. +Think of your runtime as a collection of specialized modules, each handling a different aspect of your blockchain. Need token balances? Use the Balances pallet. Want governance? Add the Governance pallets. Need something custom? Create your own pallet. By mixing and matching these modules, you build a runtime that's efficient, secure, and tailored to your use case. -## Test Networks +## Runtime Architecture -The following test networks provide controlled environments for testing upgrades and new features. TestNet tokens are available from the [Polkadot faucet](https://faucet.polkadot.io/){target=\_blank}. +The following diagram shows how FRAME components work together to form your runtime: -### Westend +![](/images/parachains/customize-runtime/index/frame-overview-01.webp) -Westend is Polkadot's primary permanent TestNet. Unlike temporary test networks, Westend is not reset to the genesis block, making it an ongoing environment for testing Polkadot core features. Managed by Parity Technologies, Westend ensures that developers can test features in a real-world simulation without using actual tokens. +The main components are: -The native token for Westend is WND. More details about WND can be found on the [Native Assets](https://wiki.polkadot.com/learn/learn-dot/#__tabbed_2_2){target=\_blank} page. +- **`frame_executive`**: Routes all incoming transactions to the correct pallet for execution. +- **Pallets**: Domain-specific modules that implement your blockchain's features and business logic. +- **`frame_system`**: Provides core runtime primitives and storage. +- **`frame_support`**: Utilities and macros that simplify pallet development. -### Paseo +## Building Blocks: Pallets -[Paseo](https://github.com/paseo-network){target=\_blank} is a community-managed TestNet designed for parachain and dApp developers. It mirrors Polkadot's runtime and is maintained by Polkadot community members. Paseo provides a dedicated space for parachain developers to test their applications in a Polkadot-like environment without the risks associated with live networks. +[Pallets](https://paritytech.github.io/polkadot-sdk/master/polkadot_sdk_docs/polkadot_sdk/frame_runtime/pallet/index.html){target=\_blank} are the fundamental units of runtime customization. Each pallet encapsulates specific functionality and can be independently developed, tested, and integrated. -The native token for Paseo is PAS. Additional information on PAS is available on the [Native Assets](https://wiki.polkadot.com/learn/learn-dot/#__tabbed_2_1){target=\_blank} page. +A pallet can implement virtually any blockchain feature you need: -## Local Test Networks +- Expose new transactions that users can submit. +- Store data on-chain. +- Enforce business rules and validation logic. +- Emit events to notify users of state changes. +- Handle errors gracefully. -Local test networks are an essential part of the development cycle for blockchain developers using the Polkadot SDK. They allow for fast, iterative testing in controlled, private environments without connecting to public TestNets. Developers can quickly spin up local instances to experiment, debug, and validate their code before deploying to larger TestNets like Westend or Paseo. Two key tools for local network testing are Zombienet and Chopsticks. +### Pre-Built Pallets vs. Custom Pallets -### Zombienet +FRAME provides a comprehensive library of [pre-built pallets](https://github.com/paritytech/polkadot-sdk/tree/polkadot-stable2506-2/substrate/frame){target=\_blank} for common blockchain features, including consensus, staking, balances, governance, and more. These pallets are battle-tested, optimized, and ready to use. -[Zombienet](https://github.com/paritytech/zombienet){target=\_blank} is a flexible testing framework for Polkadot SDK-based blockchains. It enables developers to create and manage ephemeral, short-lived networks. This feature makes Zombienet particularly useful for quick iterations, as it allows you to run multiple local networks concurrently, mimicking different runtime conditions. Whether you're developing a parachain or testing your custom blockchain logic, Zombienet gives you the tools to automate local testing. +However, you're not limited to pre-built functionality. When pre-built pallets don't meet your needs, you can create custom pallets with entirely custom logic. The real power of FRAME is the flexibility to use pre-built modules for standard features while building your own for unique requirements. -Key features of Zombienet include: +### Pallet Structure -- Creating dynamic, local networks with different configurations. -- Running parachains and relay chains in a simulated environment. -- Efficient testing of network components like cross-chain messaging and governance. +FRAME uses Rust macros extensively, allowing you to focus on your pallet's logic while the framework handles boilerplate and integration code. -Zombienet is ideal for developers looking to test quickly and thoroughly before moving to more resource-intensive public TestNets. +A typical pallet looks like this: -### Chopsticks - -[Chopsticks](https://github.com/AcalaNetwork/chopsticks){target=\_blank} is a tool designed to create forks of Polkadot SDK-based blockchains, allowing developers to interact with network forks as part of their testing process. This capability makes Chopsticks a powerful option for testing upgrades, runtime changes, or cross-chain applications in a forked network environment. - -Key features of Chopsticks include: - -- Forking live Polkadot SDK-based blockchains for isolated testing. -- Simulating cross-chain messages in a private, controlled setup. -- Debugging network behavior by interacting with the fork in real-time. - -Chopsticks provides a controlled environment for developers to safely explore the effects of runtime changes. It ensures that network behavior is tested and verified before upgrades are deployed to live networks. - - ---- - -Page Title: Node and Runtime - -- Source (raw): https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/reference-parachains-node-and-runtime.md -- Canonical (HTML): https://docs.polkadot.com/reference/parachains/node-and-runtime/ -- Summary: Learn how Polkadot SDK-based nodes function, how the client and runtime are separated, and how they communicate using SCALE-encoded data. - -# Node and Runtime - -## Introduction - -Every blockchain platform relies on a decentralized network of computers, called nodes, that communicate with each other about transactions and blocks. In this context, a node refers to the software running on the connected devices rather than the physical or virtual machines in the network. - -Polkadot SDK-based nodes consist of two main components, each with distinct responsibilities: the client (also called node) and the runtime. - -If the system were a monolithic protocol, any modification would require updating the entire system. Instead, Polkadot achieves true upgradeability by defining an immutable meta-protocol (the client) and a protocol (the runtime) that can be upgraded independently. - -This separation gives the [Polkadot Relay Chain](/polkadot-protocol/architecture/polkadot-chain){target=\_blank} and all connected [parachains](/polkadot-protocol/architecture/parachains){target=\_blank} an evolutionary advantage over other blockchain platforms. - -## Architectural Principles - -The Polkadot SDK-based blockchain architecture is fundamentally built on two distinct yet interconnected components: - -- Client (Meta-protocol): - - Handles the foundational infrastructure of the blockchain. - - Manages runtime execution, networking, consensus, and other off-chain components. - - Provides an immutable base layer that ensures network stability. - - Upgradable only through hard forks. - -- Runtime (Protocol): - - Defines the blockchain's state transition logic. - - Determines the specific rules and behaviors of the blockchain. - - Compiled to WebAssembly (Wasm) for platform-independent execution. - - Capable of being upgraded without network-wide forking. - -### Advantages of this Architecture - -- **Forkless upgrades**: Runtime can be updated without disrupting the entire network. -- **Modularity**: Clear separation allows independent development of client and runtime. -- **Flexibility**: Enables rapid iteration and evolution of blockchain logic. -- **Performance**: WebAssembly compilation provides efficient, cross-platform execution. - -## Node (Client) - -The node, also known as the client, is the core component responsible for executing the Wasm runtime and orchestrating various essential blockchain components. It ensures the correct execution of the state transition function and manages multiple critical subsystems, including: - -- **Wasm execution**: Runs the blockchain runtime, which defines the state transition rules. -- **Database management**: Stores blockchain data. -- **Networking**: Facilitates peer-to-peer communication, block propagation, and transaction gossiping. -- **Transaction pool (Mempool)**: Manages pending transactions before they are included in a block. -- **Consensus mechanism**: Ensures agreement on the blockchain state across nodes. -- **RPC services**: Provides external interfaces for applications and users to interact with the node. - -## Runtime - -The runtime is more than just a set of rules. It's the fundamental logic engine that defines a blockchain's entire behavior. In Polkadot SDK-based blockchains, the runtime represents a complete, self-contained description of the blockchain's state transition function. - -### Characteristics - -The runtime is distinguished by three key characteristics: - -- **Business logic**: Defines the complete application-specific blockchain behavior. -- **WebAssembly compilation**: Ensures platform-independent, secure execution. -- **On-chain storage**: Stored within the blockchain's state, allowing dynamic updates. - -### Key Functions - -The runtime performs several critical functions, such as: - -- Define state transition rules. -- Implement blockchain-specific logic. -- Manage account interactions. -- Control transaction processing. -- Define governance mechanisms. -- Handle custom pallets and modules. - -## Communication Between Node and Runtime - -The client and runtime communicate exclusively using [SCALE-encoded](/polkadot-protocol/parachain-basics/data-encoding){target=\_blank} communication. This ensures efficient and compact data exchange between the two components. - -### Runtime APIs - -The Runtime API consists of well-defined functions and constants a client assumes are implemented in the Runtime Wasm blob. These APIs enable the client to interact with the runtime to execute blockchain operations and retrieve information. The client invokes these APIs to: - -- Build, execute, and finalize blocks. -- Access metadata. -- Access consensus related information. -- Handle transaction execution. - -### Host Functions - -During execution, the runtime can access certain external client functionalities via host functions. The specific functions the client exposes allow the runtime to perform operations outside the WebAssembly domain. Host functions enable the runtime to: - -- Perform cryptographic operations. -- Access the current blockchain state. -- Handle storage modifications. -- Allocate memory. - - ---- - -Page Title: On-Chain Governance Overview - -- Source (raw): https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/reference-governance.md -- Canonical (HTML): https://docs.polkadot.com/reference/governance/ -- Summary: Discover Polkadot’s cutting-edge OpenGov system, enabling transparent, decentralized decision-making through direct democracy and flexible governance tracks. - -# On-Chain Governance - -## Introduction - -Polkadot’s governance system exemplifies decentralized decision-making, empowering its community of stakeholders to shape the network’s future through active participation. The latest evolution, OpenGov, builds on Polkadot’s foundation by providing a more inclusive and efficient governance model. - -This guide will explain the principles and structure of OpenGov and walk you through its key components, such as Origins, Tracks, and Delegation. You will learn about improvements over earlier governance systems, including streamlined voting processes and enhanced stakeholder participation. - -With OpenGov, Polkadot achieves a flexible, scalable, and democratic governance framework that allows multiple proposals to proceed simultaneously, ensuring the network evolves in alignment with its community's needs. - -## Governance Evolution - -Polkadot’s governance journey began with [Governance V1](https://wiki.polkadot.com/learn/learn-polkadot-opengov/#governance-summary){target=\_blank}, a system that proved effective in managing treasury funds and protocol upgrades. However, it faced limitations, such as: - -- Slow voting cycles, causing delays in decision-making. -- Inflexibility in handling multiple referendums, restricting scalability. - -To address these challenges, Polkadot introduced OpenGov, a governance model designed for greater inclusivity, efficiency, and scalability. OpenGov replaces the centralized structures of Governance V1, such as the Council and Technical Committee, with a fully decentralized and dynamic framework. - -For a full comparison of the historic and current governance models, visit the [Gov1 vs. Polkadot OpenGov](https://wiki.polkadot.com/learn/learn-polkadot-opengov/#gov1-vs-polkadot-opengov){target=\_blank} section of the Polkadot Wiki. - -## OpenGov Key Features - -OpenGov transforms Polkadot’s governance into a decentralized, stakeholder-driven model, eliminating centralized decision-making bodies like the Council. Key enhancements include: - -- **Decentralization**: Shifts all decision-making power to the public, ensuring a more democratic process. -- **Enhanced delegation**: Allows users to delegate their votes to trusted experts across specific governance tracks. -- **Simultaneous referendums**: Multiple proposals can progress at once, enabling faster decision-making. -- **Polkadot Technical Fellowship**: A broad, community-driven group replacing the centralized Technical Committee. - -This new system ensures Polkadot governance remains agile and inclusive, even as the ecosystem grows. - -## Origins and Tracks - -In OpenGov, origins and tracks are central to managing proposals and votes. - -- **Origin**: Determines the authority level of a proposal (e.g., Treasury, Root) which decides the track of all referendums from that origin. -- **Track**: Define the procedural flow of a proposal, such as voting duration, approval thresholds, and enactment timelines. - -Developers must be aware that referendums from different origins and tracks will take varying amounts of time to reach approval and enactment. The [Polkadot Technical Fellowship](https://wiki.polkadot.com/learn/learn-polkadot-technical-fellowship/){target=\_blank} has the option to shorten this timeline by whitelisting a proposal and allowing it to be enacted through the [Whitelist Caller](https://wiki.polkadot.com/learn/learn-polkadot-opengov-origins/#whitelisted-caller){target=\_blank} origin. - -Visit [Origins and Tracks Info](https://wiki.polkadot.com/learn/learn-polkadot-opengov/#origins-and-tracks){target=\_blank} for details on current origins and tracks, associated terminology, and parameters. - -## Referendums - -In OpenGov, anyone can submit a referendum, fostering an open and participatory system. The timeline for a referendum depends on the privilege level of the origin with more significant changes offering more time for community voting and participation before enactment. - -The timeline for an individual referendum includes four distinct periods: - -- **Lead-in**: A minimum amount of time to allow for community participation, available room in the origin, and payment of the decision deposit. Voting is open during this period. -- **Decision**: Voting continues. -- **Confirmation**: Referendum must meet [approval and support](https://wiki.polkadot.com/learn/learn-polkadot-opengov/#approval-and-support){target=\_blank} criteria during entire period to avoid rejection. -- **Enactment**: Changes approved by the referendum are executed. - -### Vote on Referendums - -Voters can vote with their tokens on each referendum. Polkadot uses a voluntary token locking mechanism, called conviction voting, as a way for voters to increase their voting power. A token holder signals they have a stronger preference for approving a proposal based upon their willingness to lock up tokens. Longer voluntary token locks are seen as a signal of continual approval and translate to increased voting weight. - -See [Voting on a Referendum](https://wiki.polkadot.com/learn/learn-polkadot-opengov/#voting-on-a-referendum){target=\_blank} for a deeper look at conviction voting and related token locks. - -### Delegate Voting Power - -The OpenGov system also supports multi-role delegations, allowing token holders to assign their voting power on different tracks to entities with expertise in those areas. - -For example, if a token holder lacks the technical knowledge to evaluate proposals on the [Root track](https://wiki.polkadot.com/learn/learn-polkadot-opengov-origins/#root){target=\_blank}, they can delegate their voting power for that track to an expert they trust to vote in the best interest of the network. This ensures informed decision-making across tracks while maintaining flexibility for token holders. - -Visit [Multirole Delegation](https://wiki.polkadot.com/learn/learn-polkadot-opengov/#multirole-delegation){target=\_blank} for more details on delegating voting power. - -### Cancel a Referendum - -Polkadot OpenGov has two origins for rejecting ongoing referendums: - -- [**Referendum Canceller**](https://wiki.polkadot.com/learn/learn-polkadot-opengov-origins/#referendum-canceller){target=\_blank}: Cancels an active referendum when non-malicious errors occur and refunds the deposits to the originators. -- [**Referendum Killer**](https://wiki.polkadot.com/learn/learn-polkadot-opengov-origins/#referendum-killer){target=\_blank}: Used for urgent, malicious cases this origin instantly terminates an active referendum and slashes deposits. - -See [Cancelling, Killing, and Blacklisting](https://wiki.polkadot.com/learn/learn-polkadot-opengov/#cancelling-killing--blacklisting){target=\_blank} for additional information on rejecting referendums. - -## Additional Resources - -- **[Democracy pallet](https://github.com/paritytech/polkadot-sdk/tree/polkadot-stable2506-2/substrate/frame/democracy/src){target=\_blank}**: Handles administration of general stakeholder voting. -- **[Gov2: Polkadot’s Next Generation of Decentralised Governance](https://medium.com/polkadot-network/gov2-polkadots-next-generation-of-decentralised-governance-4d9ef657d11b){target=\_blank}**: Medium article by Gavin Wood. -- **[Polkadot Direction](https://matrix.to/#/#Polkadot-Direction:parity.io){target=\_blank}**: Matrix Element client. -- **[Polkassembly](https://polkadot.polkassembly.io/){target=\_blank}**: OpenGov dashboard and UI. -- **[Polkadot.js Apps Governance](https://polkadot.js.org/apps/#/referenda){target=\_blank}**: Overview of active referendums. - - ---- - -Page Title: Overview of FRAME - -- Source (raw): https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/parachains-customize-runtime.md -- Canonical (HTML): https://docs.polkadot.com/parachains/customize-runtime/ -- Summary: Learn how Polkadot SDK’s FRAME framework simplifies blockchain development with modular pallets and support libraries for efficient runtime design. - -# Customize Your Runtime - -## Introduction - -A blockchain runtime is more than just a fixed set of rules—it's a dynamic foundation that you can shape to match your specific needs. With Polkadot SDK's [FRAME (Framework for Runtime Aggregation of Modularized Entities)](https://paritytech.github.io/polkadot-sdk/master/polkadot_sdk_docs/polkadot_sdk/frame_runtime/index.html){target=\_blank}, customizing your runtime is straightforward and modular. Instead of building everything from scratch, you combine pre-built pallets with your own custom logic to create a runtime suited to your blockchain's purpose. - - - -This overview explains how runtime customization works, introduces the building blocks you'll use, and guides you through the key patterns for extending your runtime. - -## Understanding Your Runtime - -The runtime is the core logic of your blockchain—it processes transactions, manages state, and enforces the rules that govern your network. When a transaction arrives at your blockchain, the [`frame_executive`](https://paritytech.github.io/polkadot-sdk/master/frame_executive/index.html){target=\_blank} pallet receives it and routes it to the appropriate pallet for execution. - -Think of your runtime as a collection of specialized modules, each handling a different aspect of your blockchain. Need token balances? Use the Balances pallet. Want governance? Add the Governance pallets. Need something custom? Create your own pallet. By mixing and matching these modules, you build a runtime that's efficient, secure, and tailored to your use case. - -## Runtime Architecture - -The following diagram shows how FRAME components work together to form your runtime: - -![](/images/parachains/customize-runtime/index/frame-overview-01.webp) - -The main components are: - -- **`frame_executive`**: Routes all incoming transactions to the correct pallet for execution. -- **Pallets**: Domain-specific modules that implement your blockchain's features and business logic. -- **`frame_system`**: Provides core runtime primitives and storage. -- **`frame_support`**: Utilities and macros that simplify pallet development. - -## Building Blocks: Pallets - -[Pallets](https://paritytech.github.io/polkadot-sdk/master/polkadot_sdk_docs/polkadot_sdk/frame_runtime/pallet/index.html){target=\_blank} are the fundamental units of runtime customization. Each pallet encapsulates specific functionality and can be independently developed, tested, and integrated. - -A pallet can implement virtually any blockchain feature you need: - -- Expose new transactions that users can submit. -- Store data on-chain. -- Enforce business rules and validation logic. -- Emit events to notify users of state changes. -- Handle errors gracefully. - -### Pre-Built Pallets vs. Custom Pallets - -FRAME provides a comprehensive library of [pre-built pallets](https://github.com/paritytech/polkadot-sdk/tree/polkadot-stable2506-2/substrate/frame){target=\_blank} for common blockchain features, including consensus, staking, balances, governance, and more. These pallets are battle-tested, optimized, and ready to use. - -However, you're not limited to pre-built functionality. When pre-built pallets don't meet your needs, you can create custom pallets with entirely custom logic. The real power of FRAME is the flexibility to use pre-built modules for standard features while building your own for unique requirements. - -### Pallet Structure - -FRAME uses Rust macros extensively, allowing you to focus on your pallet's logic while the framework handles boilerplate and integration code. - -A typical pallet looks like this: - -```rust -pub use pallet::*; +```rust +pub use pallet::*; #[frame_support::pallet] pub mod pallet { use frame_support::pallet_prelude::*; use frame_system::pallet_prelude::*; - #[pallet::pallet] - #[pallet::generate_store(pub(super) trait Store)] - pub struct Pallet(_); - - #[pallet::config] // snip - #[pallet::event] // snip - #[pallet::error] // snip - #[pallet::storage] // snip - #[pallet::call] // snip -} -``` - -Every pallet can implement these core macros: - -- **`#[frame_support::pallet]`**: Marks your module as a FRAME pallet. -- **`#[pallet::pallet]`**: Designates the struct that holds pallet metadata. -- **`#[pallet::config]`**: Defines configuration and associated types. -- **`#[pallet::event]`**: Defines events emitted by your pallet. -- **`#[pallet::error]`**: Defines error types your pallet can return. -- **`#[pallet::storage]`**: Defines on-chain storage items. -- **`#[pallet::call]`**: Defines dispatchable functions (transactions). - -For a comprehensive reference, see the [`pallet_macros` documentation](https://paritytech.github.io/polkadot-sdk/master/frame_support/pallet_macros/index.html){target=\_blank}. - -## How Runtime Customization Works - -Customizing your runtime typically follows these patterns: - -**Adding Pre-Built Pallets**: Select pallets from the FRAME library and integrate them into your runtime configuration. This is the fastest way to add functionality. - -**Creating Custom Pallets**: Write custom pallets for features that don't exist in the pre-built library. Custom pallets follow the same structure as pre-built ones and integrate seamlessly. - -**Combining Multiple Pallets**: Layer multiple pallets together to create complex behaviors. Pallets can call each other and share storage when needed. - -**Configuring Pallet Parameters**: Most pallets are configurable—you can adjust their behavior through configuration traits without modifying their code. - -The following diagram illustrates how pallets combine to form a complete runtime: - -![](/images/parachains/customize-runtime/index/frame-overview-02.webp) - -## Starting Templates - -The easiest way to begin customizing your runtime is with a starter template. These templates provide a pre-configured foundation so you can focus on customization rather than setup. - -- **[Polkadot SDK Parachain Template](https://github.com/paritytech/polkadot-sdk-parachain-template){target=\_blank}**: The recommended choice for most developers, it includes pre-configured pallets for common features (balances, block production, governance), a complete runtime setup, and built-in parachain consensus support. This template offers the best balance of features and learning opportunities. - -- **[Polkadot SDK Minimal Template](https://github.com/paritytech/polkadot-sdk-minimal-template){target=\_blank}**: Provides a bare-bones runtime with only essential components. Choose this if you want maximum flexibility and prefer building from a clean slate. - -- **[Polkadot SDK Solochain Template](https://github.com/paritytech/polkadot-sdk/tree/master/templates/solochain){target=\_blank}**: Designed for building standalone blockchains with moderate features, simple consensus, and several core pallets. Use this if you want a sovereign blockchain independent of a relay chain. - -- **[OpenZeppelin Runtime Templates](https://github.com/OpenZeppelin/polkadot-runtime-templates){target=\_blank}**: Provides security-focused configurations following industry best practices. The [generic-template](https://github.com/OpenZeppelin/polkadot-runtime-templates/tree/main/generic-template){target=\_blank} includes curated pallet selections and production-ready defaults—ideal if security is your top priority. - -## Key Customization Scenarios - -This section covers the most common customization patterns you'll encounter: - -- **[Add Existing Pallets to Your Runtime](/parachains/customize-runtime/add-existing-pallets/)**: Integrate pre-built pallets from the FRAME library with minimal configuration. - -- **[Add Multiple Instances of a Pallet](/parachains/customize-runtime/add-pallet-instances/)**: Run multiple instances of the same pallet with different configurations—useful for multi-token systems or parallel features. - -- **[Add Smart Contract Functionality](/parachains/customize-runtime/add-smart-contract-functionality/)**: Enable smart contract execution on your parachain using Contracts pallets. - -- **[Create Custom Pallets](/parachains/customize-runtime/pallet-development/create-a-pallet/)**: Build entirely custom pallets for features unique to your blockchain. - -- **[Test Your Runtime](/parachains/customize-runtime/pallet-development/pallet-testing/)**: Unit test pallets and mock complete runtimes to ensure everything works correctly. - - ---- - -Page Title: Overview of the Polkadot Relay Chain - -- Source (raw): https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/reference-polkadot-hub-consensus-and-security-relay-chain.md -- Canonical (HTML): https://docs.polkadot.com/reference/polkadot-hub/consensus-and-security/relay-chain/ -- Summary: Explore Polkadot's core architecture, including its multi-chain vision, shared security, and the DOT token's governance and staking roles. - -# Overview - -## Introduction - -Polkadot is a next-generation blockchain protocol designed to support a multi-chain future by enabling secure communication and interoperability between different blockchains. Built as a Layer-0 protocol, Polkadot introduces innovations like application-specific Layer-1 chains ([parachains](/polkadot-protocol/architecture/parachains/){targe=\_blank}), shared security through [Nominated Proof of Stake (NPoS)](/reference/glossary/#nominated-proof-of-stake-npos){target=\_blank}, and cross-chain interactions via its native [Cross-Consensus Messaging Format (XCM)](/parachains/interoperability/get-started/){target=\_blank}. - -This guide covers key aspects of Polkadot’s architecture, including its high-level protocol structure, blockspace commoditization, and the role of its native token, DOT, in governance, staking, and resource allocation. - -## Polkadot 1.0 - -Polkadot 1.0 represents the state of Polkadot as of 2023, coinciding with the release of [Polkadot runtime v1.0.0](https://github.com/paritytech/polkadot/releases/tag/v1.0.0){target=\_blank}. This section will focus on Polkadot 1.0, along with philosophical insights into network resilience and blockspace. - -As a Layer-0 blockchain, Polkadot contributes to the multi-chain vision through several key innovations and initiatives, including: - -- **Application-specific Layer-1 blockchains (parachains)**: Polkadot's sharded network allows for parallel transaction processing, with shards that can have unique state transition functions, enabling custom-built L1 chains optimized for specific applications. - -- **Shared security and scalability**: L1 chains connected to Polkadot benefit from its [Nominated Proof of Stake (NPoS)](/reference/polkadot-hub/consensus-and-security/pos-consensus/#nominated-proof-of-stake){target=\_blank} system, providing security out-of-the-box without the need to bootstrap their own. - -- **Secure interoperability**: Polkadot's native interoperability enables seamless data and value exchange between parachains. This interoperability can also be used outside of the ecosystem for bridging with external networks. - -- **Resilient infrastructure**: Decentralized and scalable, Polkadot ensures ongoing support for development and community initiatives via its on-chain [treasury](https://wiki.polkadot.com/learn/learn-polkadot-opengov-treasury/){target=\_blank} and governance. - -- **Rapid L1 development**: The [Polkadot SDK](/reference/parachains/){target=\_blank} allows fast, flexible creation and deployment of Layer-1 chains. - -- **Cultivating the next generation of Web3 developers**: Polkadot supports the growth of Web3 core developers through initiatives such as. - - - [Polkadot Blockchain Academy](https://polkadot.com/blockchain-academy){target=\_blank} - - [EdX courses](https://www.edx.org/school/web3x){target=\_blank} - - Rust and Substrate courses (coming soon) - -### High-Level Architecture - -Polkadot features a chain that serves as the central component of the system. This chain is depicted as a ring encircled by several parachains that are connected to it. - -According to Polkadot's design, any blockchain that can compile to WebAssembly (Wasm) and adheres to the Parachains Protocol becomes a parachain on the Polkadot network. - -Here’s a high-level overview of the Polkadot protocol architecture: - -![](/images/reference/polkadot-hub/consensus-and-security/relay-chain/relay-chain-01.webp){ style="background:white" } - -Parachains propose blocks to Polkadot validators, who check for availability and validity before finalizing them. With the relay chain providing security, collators—full nodes of parachains—can focus on their tasks without needing strong incentives. - -The [Cross-Consensus Messaging Format (XCM)](/parachains/interoperability/get-started/){target=\_blank} allows parachains to exchange messages freely, leveraging the chain's security for trust-free communication. - -In order to interact with chains that want to use their own finalization process (e.g., Bitcoin), Polkadot has [bridges](/reference/parachains/interoperability/#bridges-connecting-external-networks){target=\_blank} that offer two-way compatibility, meaning that transactions can be made between different parachains. - -### Polkadot's Additional Functionalities - -Historically, obtaining core slots on Polkadot chain relied upon crowdloans and auctions. Chain cores were leased through auctions for three-month periods, up to a maximum of two years. Crowdloans enabled users to securely lend funds to teams for lease deposits in exchange for pre-sale tokens, which is the only way to access slots on Polkadot 1.0. Auctions are now deprecated in favor of [coretime](/polkadot-protocol/architecture/system-chains/coretime/){target=\_blank}. - -Additionally, the chain handles [staking](https://wiki.polkadot.com/learn/learn-staking/){target=\_blank}, [accounts](/reference/parachains/accounts/){target=\_blank}, balances, and [governance](/reference/governance/){target=\_blank}. - -#### Agile Coretime - -The new and more efficient way of obtaining core on Polkadot is to go through the process of purchasing coretime. - -[Agile coretime](/reference/polkadot-hub/consensus-and-security/agile-coretime/){target=\_blank} improves the efficient use of Polkadot's network resources and offers economic flexibility for developers, extending Polkadot's capabilities far beyond the original vision outlined in the [whitepaper](https://polkadot.com/papers/Polkadot-whitepaper.pdf){target=\_blank}. - -It enables parachains to purchase monthly "bulk" allocations of coretime (the time allocated for utilizing a core, measured in Polkadot relay chain blocks), ensuring heavy-duty parachains that can author a block every six seconds with [Asynchronous Backing](https://wiki.polkadot.com/learn/learn-async-backing/#asynchronous-backing){target=\_blank} can reliably renew their coretime each month. Although six-second block times are now the default, parachains have the option of producing blocks less frequently. - -Renewal orders are prioritized over new orders, offering stability against price fluctuations and helping parachains budget more effectively for project costs. - -### Polkadot's Resilience - -Decentralization is a vital component of blockchain networks, but it comes with trade-offs: - -- An overly decentralized network may face challenges in reaching consensus and require significant energy to operate. -- Also, a network that achieves consensus quickly risks centralization, making it easier to manipulate or attack. - -A network should be decentralized enough to prevent manipulative or malicious influence. In this sense, decentralization is a tool for achieving resilience. - -Polkadot 1.0 currently achieves resilience through several strategies: - -- **Nominated Proof of Stake (NPoS)**: Ensures that the stake per validator is maximized and evenly distributed among validators. - -- **Decentralized nodes**: Designed to encourage operators to join the network. This program aims to expand and diversify the validators in the ecosystem who aim to become independent of the program during their term. Feel free to explore more about the program on the official [Decentralized Nodes](https://nodes.web3.foundation/){target=\_blank} page. - -- **On-chain treasury and governance**: Known as [OpenGov](/reference/governance/){target=\_blank}, this system allows every decision to be made through public referenda, enabling any token holder to cast a vote. - -### Polkadot's Blockspace - -Polkadot 1.0’s design allows for the commoditization of blockspace. - -Blockspace is a blockchain's capacity to finalize and commit operations, encompassing its security, computing, and storage capabilities. Its characteristics can vary across different blockchains, affecting security, flexibility, and availability. - -- **Security**: Measures the robustness of blockspace in Proof of Stake (PoS) networks linked to the stake locked on validator nodes, the variance in stake among validators, and the total number of validators. It also considers social centralization (how many validators are owned by single operators) and physical centralization (how many validators run on the same service provider). - -- **Flexibility**: Reflects the functionalities and types of data that can be stored, with high-quality data essential to avoid bottlenecks in critical processes. - -- **Availability**: Indicates how easily users can access blockspace. It should be easily accessible, allowing diverse business models to thrive, ideally regulated by a marketplace based on demand and supplemented by options for "second-hand" blockspace. - -Polkadot is built on core blockspace principles, but there's room for improvement. Tasks like balance transfers, staking, and governance are managed on the relay chain. - -Delegating these responsibilities to [system chains](/polkadot-protocol/architecture/system-chains/){target=\_blank} could enhance flexibility and allow the relay chain to concentrate on providing shared security and interoperability. - -For more information about blockspace, watch [Robert Habermeier’s interview](https://www.youtube.com/watch?v=e1vISppPwe4){target=\_blank} or read his [technical blog post](https://www.rob.tech/blog/polkadot-blockspace-over-blockchains/){target=\_blank}. - -## DOT Token - -DOT is the native token of the Polkadot network, much like BTC for Bitcoin and Ether for the Ethereum blockchain. DOT has 10 decimals, uses the Planck base unit, and has a balance type of `u128`. The same is true for Kusama's KSM token with the exception of having 12 decimals. - -### Redenomination of DOT - -Polkadot conducted a community poll, which ended on 27 July 2020 at block 888,888, to decide whether to redenominate the DOT token. The stakeholders chose to redenominate the token, changing the value of 1 DOT from 1e12 plancks to 1e10 plancks. - -Importantly, this did not affect the network's total number of base units (plancks); it only affects how a single DOT is represented. The redenomination became effective 72 hours after transfers were enabled, occurring at block 1,248,328 on 21 August 2020 around 16:50 UTC. - -### The Planck Unit - -The smallest unit of account balance on Polkadot SDK-based blockchains (such as Polkadot and Kusama) is called _Planck_, named after the Planck length, the smallest measurable distance in the physical universe. - -Similar to how BTC's smallest unit is the Satoshi and ETH's is the Wei, Polkadot's native token DOT equals 1e10 Planck, while Kusama's native token KSM equals 1e12 Planck. - -### Uses for DOT - -DOT serves three primary functions within the Polkadot network: - -- **Governance**: It is used to participate in the governance of the network. -- **Staking**: DOT is staked to support the network's operation and security. -- **Buying coretime**: Used to purchase coretime in-bulk or on-demand and access the chain to benefit from Polkadot's security and interoperability. - -Additionally, DOT can serve as a transferable token. For example, DOT, held in the treasury, can be allocated to teams developing projects that benefit the Polkadot ecosystem. - -## JAM and the Road Ahead - -The Join-Accumulate Machine (JAM) represents a transformative redesign of Polkadot's core architecture, envisioned as the successor to the current relay chain. Unlike traditional blockchain architectures, JAM introduces a unique computational model that processes work through two primary functions: - -- **Join**: Handles data integration. -- **Accumulate**: Folds computations into the chain's state. - -JAM removes many of the opinions and constraints of the current relay chain while maintaining its core security properties. Expected improvements include: - -- **Permissionless code execution**: JAM is designed to be more generic and flexible, allowing for permissionless code execution through services that can be deployed without governance approval. -- **More effective block time utilization**: JAM's efficient pipeline processing model places the prior state root in block headers instead of the posterior state root, enabling more effective utilization of block time for computations. - -This architectural evolution promises to enhance Polkadot's scalability and flexibility while maintaining robust security guarantees. JAM is planned to be rolled out to Polkadot as a single, complete upgrade rather than a stream of smaller updates. This approach seeks to minimize the developer overhead required to address any breaking changes. - - ---- - -Page Title: Parachains Overview - -- Source (raw): https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/reference-parachains.md -- Canonical (HTML): https://docs.polkadot.com/reference/parachains/ -- Summary: Learn about parachains, specialized blockchains on Polkadot that gain shared security and interoperability. Discover how they work and the tools to build them. - -# Parachains Overview - -## Introduction - -A parachain is a specialized blockchain that connects to the Polkadot relay chain, benefiting from shared security, interoperability, and scalability. Parachains are built using the [Polkadot SDK](https://github.com/paritytech/polkadot-sdk){target=\_blank}, a powerful toolkit written in Rust that provides everything needed to create custom blockchain logic while integrating seamlessly with the Polkadot network. - -Unlike standalone blockchains that must bootstrap their own validator sets and security, parachains leverage Polkadot's pooled security model. This allows parachain developers to focus on their application-specific functionality rather than consensus and security infrastructure. Parachains can communicate with each other through Cross-Consensus Messaging (XCM), enabling seamless interoperability across the Polkadot ecosystem. - -Key capabilities that parachains provide include: - -- **Shared security**: Inherit security from Polkadot's validator set without maintaining your own. -- **Interoperability**: Communicate trustlessly with other parachains via XCM. -- **Scalability**: Process transactions in parallel with other parachains. -- **Customization**: Build application-specific logic tailored to your use case. -- **Upgradeability**: Upgrade runtime logic without hard forks. - -## Polkadot SDK: Parachain Architecture - -Building a parachain involves understanding and utilizing several key components of the Polkadot SDK: - -![](/images/reference/parachains/index/overview-01.webp) - -- **[Substrate](https://paritytech.github.io/polkadot-sdk/master/polkadot_sdk_docs/polkadot_sdk/substrate/index.html){target=\_blank}**: The foundation providing core blockchain primitives and libraries. -- **[FRAME](https://paritytech.github.io/polkadot-sdk/master/polkadot_sdk_docs/polkadot_sdk/frame_runtime/index.html){target=\_blank}**: A modular framework for building your parachain's runtime logic. -- **[Cumulus](https://paritytech.github.io/polkadot-sdk/master/polkadot_sdk_docs/polkadot_sdk/cumulus/index.html){target=\_blank}**: Essential libraries and pallets that enable parachain functionality. -- **[XCM (Cross Consensus Messaging)](https://paritytech.github.io/polkadot-sdk/master/polkadot_sdk_docs/polkadot_sdk/xcm/index.html){target=\_blank}**: The messaging format for communicating with other parachains and the relay chain. -- **[Polkadot](https://paritytech.github.io/polkadot-sdk/master/polkadot_sdk_docs/polkadot_sdk/polkadot/index.html){target=\_blank}**: The relay chain that provides security and coordination. - -### Substrate: The Foundation - -Substrate provides the core infrastructure that every parachain is built upon. It handles the low-level blockchain functionality, allowing you to focus on your application's unique features. Substrate includes implementations for networking, database management, consensus participation, and the execution environment for your runtime. - -Every Polkadot SDK node consists of two main components: - -- **Client (Host)**: Handles infrastructure services. - - - Native binary that runs on validator and collator nodes. - - Executes the Wasm-compiled runtime. - - Manages networking, database, mempool, and block production. - - Interfaces with the relay chain for validation. - -- **Runtime (State Transition Function)**: Contains your business logic. - - - Defines how your Polkadot SDK node processes transactions. - - Compiled to [Wasm](https://webassembly.org/){target=\_blank} for deterministic execution. - - Stored on-chain and upgradeable via governance. - -```mermaid -%%{init: {'flowchart': {'padding': 5, 'nodeSpacing': 50, 'rankSpacing': 10}}}%% -graph TB - classDef title font-size:20px,font-weight:bold,stroke-width:0px - classDef clientStyle font-size:16px,font-weight:bold - classDef clientSubNodeStyle margin-top:10px - classDef runtimeCallExecutorStyle padding-top:10px - - subgraph sg1[Parachain
Node] - direction TB - - I[RuntimeCall Executor] - B[Wasm Runtime - STF] - - subgraph sg2[Client] - direction TB - C[Network and Blockchain
Infrastructure Services
+ Relay Chain Interface] - end - - I --> B - end - - class sg1 title - class sg2 clientStyle - class C clientSubNodeStyle - class I runtimeCallExecutorStyle - -``` - -### FRAME: Building Blocks for Your Runtime - -FRAME provides modular components called [pallets](/reference/glossary#pallet){target=\_blank} that you can compose to build your parachain's runtime. Each pallet provides specific functionality that you can customize and configure for your needs. This modular approach allows you to quickly assemble complex functionality without writing everything from scratch. - -```mermaid -graph LR - subgraph SP["Parachain Runtime"] - direction LR - Timestamp ~~~ Aura ~~~ ParachainSystem - Balances ~~~ TransactionPayment ~~~ Sudo - subgraph Timestamp["Timestamp"] - SS1[Custom Config] - end - subgraph Aura["Aura"] - SS2[Custom Config] - end - subgraph ParachainSystem["Parachain System"] - SS3[Custom Config] - end - subgraph Balances["Balances"] - SS4[Custom Config] - end - subgraph TransactionPayment["Transaction Payment"] - SS5[Custom Config] - end - subgraph Sudo["Sudo"] - SS6[Custom Config] - end - style Timestamp stroke:#FF69B4 - style Aura stroke:#FF69B4 - style ParachainSystem stroke:#FF69B4 - style Balances stroke:#FF69B4 - style TransactionPayment stroke:#FF69B4 - style Sudo stroke:#FF69B4 - style SS1 stroke-dasharray: 5 - style SS2 stroke-dasharray: 5 - style SS3 stroke-dasharray: 5 - style SS4 stroke-dasharray: 5 - style SS5 stroke-dasharray: 5 - style SS6 stroke-dasharray: 5 - - end - subgraph AP["Available FRAME Pallets"] - direction LR - A1[Aura]~~~A2[Parachain
System]~~~A3[Transaction
Payment]~~~A4[Sudo] - B1[Identity]~~~B2[Balances]~~~B3[Assets]~~~B4[EVM] - C1[Timestamp]~~~C2[Staking]~~~C3[Contracts]~~~C4[and more...] - end - AP --> SP -``` - -### Cumulus: Parachain-Specific Functionality - -Cumulus is what transforms a Polkadot SDK-based runtime into a parachain-capable runtime. It provides the essential components for communicating with the relay chain, participating in Polkadot's consensus, and handling parachain-specific operations like block validation and collation. - -Key Cumulus components include: - -- **Parachain system pallet**: Core parachain functionality and relay chain communication. -- **Collator consensus**: Block production logic for parachain collators. -- **Relay chain interface**: APIs for interacting with the Polkadot relay chain. -- **Validation data**: Handling proof-of-validity data required by relay chain validators. - -## Where to Go Next - -Building a parachain requires understanding the relationship between your chain and the Polkadot relay chain. The Polkadot SDK provides all the tools needed to design custom runtime logic, enable cross-chain communication, and deploy your parachain to production. - -The following sections provide detailed guidance on each aspect of parachain development, from initial design through deployment and ongoing maintenance. - -
- -- Guide __Launch a Simple Parachain__ - - --- - - Walk through the complete parachain launch flow: from setup and deployment to obtaining coretime. - - [:octicons-arrow-right-24: Deploy](/parachains/launch-a-parachain/set-up-the-parachain-template/) - - -- Guide __Customize Your Runtime__ - - --- - - Design your parachain's runtime logic and choose appropriate pallets for your use case. - - [:octicons-arrow-right-24: Get Started](/parachains/customize-runtime/) - -- Guide __Interoperability__ - - --- - - Implement XCM for trustless cross-chain communication with other parachains. - - [:octicons-arrow-right-24: Learn More](/parachains/interoperability/get-started/) - -- Guide __Runtime Upgrades__ - - --- - - Upgrade your parachain's runtime without hard forks using forkless upgrade mechanisms. - - [:octicons-arrow-right-24: Maintain](/parachains/runtime-maintenance/runtime-upgrades/) - -
- - ---- - -Page Title: Polkadot SDK Accounts - -- Source (raw): https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/reference-parachains-accounts.md -- Canonical (HTML): https://docs.polkadot.com/reference/parachains/accounts/ -- Summary: Learn about account structures, balances, and address formats in the Polkadot SDK, including how to manage lifecycle, references, and balances. - -# Accounts - -## Introduction - -Accounts are essential for managing identity, transactions, and governance on the network in the Polkadot SDK. Understanding these components is critical for seamless development and operation on the network, whether you're building or interacting with Polkadot-based chains. - -This page will guide you through the essential aspects of accounts, including their data structure, balance types, reference counters, and address formats. You’ll learn how accounts are managed within the runtime, how balances are categorized, and how addresses are encoded and validated. - -## Account Data Structure - -Accounts are foundational to any blockchain, and the Polkadot SDK provides a flexible management system. This section explains how the Polkadot SDK defines accounts and manages their lifecycle through data structures within the runtime. - -### Account - -The [`Account` data type](https://paritytech.github.io/polkadot-sdk/master/frame_system/pallet/type.Account.html){target=\_blank} is a storage map within the [System pallet](https://paritytech.github.io/polkadot-sdk/master/src/frame_system/lib.rs.html){target=\_blank} that links an account ID to its corresponding data. This structure is fundamental for mapping account-related information within the chain. - -The code snippet below shows how accounts are defined: - -```rs - /// The full account information for a particular account ID. - #[pallet::storage] - #[pallet::getter(fn account)] - pub type Account = StorageMap< - _, - Blake2_128Concat, - T::AccountId, - AccountInfo, - ValueQuery, - >; -``` - -The preceding code block defines a storage map named `Account`. The `StorageMap` is a type of on-chain storage that maps keys to values. In the `Account` map, the key is an account ID, and the value is the account's information. Here, `T` represents the generic parameter for the runtime configuration, which is defined by the pallet's configuration trait (`Config`). - -The `StorageMap` consists of the following parameters: - -- **`_`**: Used in macro expansion and acts as a placeholder for the storage prefix type. Tells the macro to insert the default prefix during expansion. -- **`Blake2_128Concat`**: The hashing function applied to keys in the storage map. -- **`T: :AccountId`**: Represents the key type, which corresponds to the account’s unique ID. -- **`AccountInfo`**: The value type stored in the map. For each account ID, the map stores an `AccountInfo` struct containing: - - - **`T::Nonce`**: A nonce for the account, which is incremented with each transaction to ensure transaction uniqueness. - - **`T: :AccountData`**: Custom account data defined by the runtime configuration, which could include balances, locked funds, or other relevant information. - -- **`ValueQuery`**: Defines how queries to the storage map behave when no value is found; returns a default value instead of `None`. - -For a detailed explanation of storage maps, see the [`StorageMap`](https://paritytech.github.io/polkadot-sdk/master/frame_support/storage/types/struct.StorageMap.html){target=\_blank} entry in the Rust docs. - -### Account Info - -The `AccountInfo` structure is another key element within the [System pallet](https://paritytech.github.io/polkadot-sdk/master/src/frame_system/lib.rs.html){target=\_blank}, providing more granular details about each account's state. This structure tracks vital data, such as the number of transactions and the account’s relationships with other modules. - -```rs -/// Information of an account. -#[derive(Clone, Eq, PartialEq, Default, RuntimeDebug, Encode, Decode, TypeInfo, MaxEncodedLen)] -pub struct AccountInfo { - /// The number of transactions this account has sent. - pub nonce: Nonce, - /// The number of other modules that currently depend on this account's existence. The account - /// cannot be reaped until this is zero. - pub consumers: RefCount, - /// The number of other modules that allow this account to exist. The account may not be reaped - /// until this and `sufficients` are both zero. - pub providers: RefCount, - /// The number of modules that allow this account to exist for their own purposes only. The - /// account may not be reaped until this and `providers` are both zero. - pub sufficients: RefCount, - /// The additional data that belongs to this account. Used to store the balance(s) in a lot of - /// chains. - pub data: AccountData, -} -``` - -The `AccountInfo` structure includes the following components: - -- **`nonce`**: Tracks the number of transactions initiated by the account, which ensures transaction uniqueness and prevents replay attacks. -- **`consumers`**: Counts how many other modules or pallets rely on this account’s existence. The account cannot be removed from the chain (reaped) until this count reaches zero. -- **`providers`**: Tracks how many modules permit this account’s existence. An account can only be reaped once both `providers` and `sufficients` are zero. -- **`sufficients`**: Represents the number of modules that allow the account to exist for internal purposes, independent of any other modules. -- **`AccountData`**: A flexible data structure that can be customized in the runtime configuration, usually containing balances or other user-specific data. - -This structure helps manage an account's state and prevents its premature removal while it is still referenced by other on-chain data or modules. The [`AccountInfo`](https://paritytech.github.io/polkadot-sdk/master/frame_system/struct.AccountInfo.html){target=\_blank} structure can vary as long as it satisfies the trait bounds defined by the `AccountData` associated type in the [`frame-system::pallet::Config`](https://paritytech.github.io/polkadot-sdk/master/frame_system/pallet/trait.Config.html){target=\_blank} trait. - -### Account Reference Counters - -Polkadot SDK uses reference counters to track an account’s dependencies across different runtime modules. These counters ensure that accounts remain active while data is associated with them. - -The reference counters include: - -- **`consumers`**: Prevents account removal while other pallets still rely on the account. -- **`providers`**: Ensures an account is active before other pallets store data related to it. -- **`sufficients`**: Indicates the account’s independence, ensuring it can exist even without a native token balance, such as when holding sufficient alternative assets. - -#### Providers Reference Counters - -The `providers` counter ensures that an account is ready to be depended upon by other runtime modules. For example, it is incremented when an account has a balance above the existential deposit, which marks the account as active. - -The system requires this reference counter to be greater than zero for the `consumers` counter to be incremented, ensuring the account is stable before any dependencies are added. - -#### Consumers Reference Counters - -The `consumers` counter ensures that the account cannot be reaped until all references to it across the runtime have been removed. This check prevents the accidental deletion of accounts that still have active on-chain data. - -It is the user’s responsibility to clear out any data from other runtime modules if they wish to remove their account and reclaim their existential deposit. - -#### Sufficients Reference Counter - -The `sufficients` counter tracks accounts that can exist independently without relying on a native account balance. This is useful for accounts holding other types of assets, like tokens, without needing a minimum balance in the native token. - -For instance, the [Assets pallet](https://paritytech.github.io/polkadot-sdk/master/pallet_assets/index.html){target=\_blank}, may increment this counter for an account holding sufficient tokens. - -#### Account Deactivation - -In Polkadot SDK-based chains, an account is deactivated when its reference counters (such as `providers`, `consumers`, and `sufficient`) reach zero. These counters ensure the account remains active as long as other runtime modules or pallets reference it. - -When all dependencies are cleared and the counters drop to zero, the account becomes deactivated and may be removed from the chain (reaped). This is particularly important in Polkadot SDK-based blockchains, where accounts with balances below the existential deposit threshold are pruned from storage to conserve state resources. - -Each pallet that references an account has cleanup functions that decrement these counters when the pallet no longer depends on the account. Once these counters reach zero, the account is marked for deactivation. - -#### Updating Counters - -The Polkadot SDK provides runtime developers with various methods to manage account lifecycle events, such as deactivation or incrementing reference counters. These methods ensure that accounts cannot be reaped while still in use. - -The following helper functions manage these counters: - -- **`inc_consumers()`**: Increments the `consumer` reference counter for an account, signaling that another pallet depends on it. -- **`dec_consumers()`**: Decrements the `consumer` reference counter, signaling that a pallet no longer relies on the account. -- **`inc_providers()`**: Increments the `provider` reference counter, ensuring the account remains active. -- **`dec_providers()`**: Decrements the `provider` reference counter, allowing for account deactivation when no longer in use. -- **`inc_sufficients()`**: Increments the `sufficient` reference counter for accounts that hold sufficient assets. -- **`dec_sufficients()`**: Decrements the `sufficient` reference counter. - -To ensure proper account cleanup and lifecycle management, a corresponding decrement should be made for each increment action. - -The `System` pallet offers three query functions to assist developers in tracking account states: - -- **[`can_inc_consumer()`](https://paritytech.github.io/polkadot-sdk/master/frame_system/pallet/struct.Pallet.html#method.can_inc_consumer){target=\_blank}**: Checks if the account can safely increment the consumer reference. -- **[`can_dec_provider()`](https://paritytech.github.io/polkadot-sdk/master/frame_system/pallet/struct.Pallet.html#method.can_dec_provider){target=\_blank}**: Ensures that no consumers exist before allowing the decrement of the provider counter. -- **[`is_provider_required()`](https://paritytech.github.io/polkadot-sdk/master/frame_system/pallet/struct.Pallet.html#method.is_provider_required){target=\_blank}**: Verifies whether the account still has any active consumer references. - -This modular and flexible system of reference counters tightly controls the lifecycle of accounts in Polkadot SDK-based blockchains, preventing the accidental removal or retention of unneeded accounts. You can refer to the [System pallet Rust docs](https://paritytech.github.io/polkadot-sdk/master/frame_system/pallet/struct.Pallet.html){target=\_blank} for more details. - - -## Account Balance Types - -In the Polkadot ecosystem, account balances are categorized into different types based on how the funds are utilized and their availability. These balance types determine the actions that can be performed, such as transferring tokens, paying transaction fees, or participating in governance activities. Understanding these balance types helps developers manage user accounts and implement balance-dependent logic. - -!!! note "A more efficient distribution of account balance types is in development" - Soon, pallets in the Polkadot SDK will implement the [`Fungible` trait](https://paritytech.github.io/polkadot-sdk/master/frame_support/traits/tokens/fungible/index.html){target=\_blank} (see the [tracking issue](https://github.com/paritytech/polkadot-sdk/issues/226){target=\_blank} for more details). For example, the [`transaction-storage`](https://paritytech.github.io/polkadot-sdk/master/pallet_transaction_storage/index.html){target=\_blank} pallet changed the implementation of the [`Currency`](https://paritytech.github.io/polkadot-sdk/master/frame_support/traits/tokens/currency/index.html){target=\_blank} trait (see the [Refactor transaction storage pallet to use fungible traits](https://github.com/paritytech/polkadot-sdk/pull/1800){target=\_blank} PR for further details): - - ```rust - type BalanceOf = <::Currency as Currency<::AccountId>>::Balance; - ``` - - To the [`Fungible`](https://paritytech.github.io/polkadot-sdk/master/frame_support/traits/tokens/fungible/index.html){target=\_blank} trait: - - ```rust - type BalanceOf = <::Currency as FnInspect<::AccountId>>::Balance; - ``` - - This update will enable more efficient use of account balances, allowing the free balance to be utilized for on-chain activities such as setting proxies and managing identities. - -### Balance Types - -The five main balance types are: - -- **Free balance**: Represents the total tokens available to the account for any on-chain activity, including staking, governance, and voting. However, it may not be fully spendable or transferrable if portions of it are locked or reserved. -- **Locked balance**: Portions of the free balance that cannot be spent or transferred because they are tied up in specific activities like [staking](https://wiki.polkadot.com/learn/learn-staking/#nominating-validators){target=\_blank}, [vesting](https://wiki.polkadot.com/learn/learn-guides-transfers/#vested-transfers-with-the-polkadot-js-ui){target=\_blank}, or participating in [governance](https://wiki.polkadot.com/learn/learn-polkadot-opengov/#voting-on-a-referendum){target=\_blank}. While the tokens remain part of the free balance, they are non-transferable for the duration of the lock. -- **Reserved balance**: Funds locked by specific system actions, such as setting up an [identity](https://wiki.polkadot.com/learn/learn-identity/){target=\_blank}, creating [proxies](https://wiki.polkadot.com/learn/learn-proxies/){target=\_blank}, or submitting [deposits for governance proposals](https://wiki.polkadot.com/learn/learn-guides-polkadot-opengov/#claiming-opengov-deposits){target=\_blank}. These tokens are not part of the free balance and cannot be spent unless they are unreserved. -- **Spendable balance**: The portion of the free balance that is available for immediate spending or transfers. It is calculated by subtracting the maximum of locked or reserved amounts from the free balance, ensuring that existential deposit limits are met. -- **Untouchable balance**: Funds that cannot be directly spent or transferred but may still be utilized for on-chain activities, such as governance participation or staking. These tokens are typically tied to certain actions or locked for a specific period. - -The spendable balance is calculated as follows: - -```text -spendable = free - max(locked - reserved, ED) -``` - -Here, `free`, `locked`, and `reserved` are defined above. The `ED` represents the [existential deposit](https://wiki.polkadot.com/learn/learn-accounts/#existential-deposit-and-reaping){target=\_blank}, the minimum balance required to keep an account active and prevent it from being reaped. You may find you can't see all balance types when looking at your account via a wallet. Wallet providers often display only spendable, locked, and reserved balances. - -### Locks - -Locks are applied to an account's free balance, preventing that portion from being spent or transferred. Locks are automatically placed when an account participates in specific on-chain activities, such as staking or governance. Although multiple locks may be applied simultaneously, they do not stack. Instead, the largest lock determines the total amount of locked tokens. - -Locks follow these basic rules: - -- If different locks apply to varying amounts, the largest lock amount takes precedence. -- If multiple locks apply to the same amount, the lock with the longest duration governs when the balance can be unlocked. - -#### Locks Example - -Consider an example where an account has 80 DOT locked for both staking and governance purposes like so: - -- 80 DOT is staked with a 28-day lock period. -- 24 DOT is locked for governance with a 1x conviction and a 7-day lock period. -- 4 DOT is locked for governance with a 6x conviction and a 224-day lock period. - -In this case, the total locked amount is 80 DOT because only the largest lock (80 DOT from staking) governs the locked balance. These 80 DOT will be released at different times based on the lock durations. In this example, the 24 DOT locked for governance will be released first since the shortest lock period is seven days. The 80 DOT stake with a 28-day lock period is released next. Now, all that remains locked is the 4 DOT for governance. After 224 days, all 80 DOT (minus the existential deposit) will be free and transferable. - -![Illustration of Lock Example](/images/reference/parachains/accounts/accounts-01.webp) - -#### Edge Cases for Locks - -In scenarios where multiple convictions and lock periods are active, the lock duration and amount are determined by the longest period and largest amount. For example, if you delegate with different convictions and attempt to undelegate during an active lock period, the lock may be extended for the full amount of tokens. For a detailed discussion on edge case lock behavior, see this [Stack Exchange post](https://substrate.stackexchange.com/questions/5067/delegating-and-undelegating-during-the-lock-period-extends-it-for-the-initial-am){target=\_blank}. - -### Balance Types on Polkadot.js - -Polkadot.js provides a user-friendly interface for managing and visualizing various account balances on Polkadot and Kusama networks. When interacting with Polkadot.js, you will encounter multiple balance types that are critical for understanding how your funds are distributed and restricted. This section explains how different balances are displayed in the Polkadot.js UI and what each type represents. - -![](/images/reference/parachains/accounts/accounts-02.webp) - -The most common balance types displayed on Polkadot.js are: - -- **Total balance**: The total number of tokens available in the account. This includes all tokens, whether they are transferable, locked, reserved, or vested. However, the total balance does not always reflect what can be spent immediately. In this example, the total balance is 0.6274 KSM. - -- **Transferable balance**: Shows how many tokens are immediately available for transfer. It is calculated by subtracting the locked and reserved balances from the total balance. For example, if an account has a total balance of 0.6274 KSM and a transferable balance of 0.0106 KSM, only the latter amount can be sent or spent freely. - -- **Vested balance**: Tokens that allocated to the account but released according to a specific schedule. Vested tokens remain locked and cannot be transferred until fully vested. For example, an account with a vested balance of 0.2500 KSM means that this amount is owned but not yet transferable. - -- **Locked balance**: Tokens that are temporarily restricted from being transferred or spent. These locks typically result from participating in staking, governance, or vested transfers. In Polkadot.js, locked balances do not stack—only the largest lock is applied. For instance, if an account has 0.5500 KSM locked for governance and staking, the locked balance would display 0.5500 KSM, not the sum of all locked amounts. - -- **Reserved balance**: Refers to tokens locked for specific on-chain actions, such as setting an identity, creating a proxy, or making governance deposits. Reserved tokens are not part of the free balance, but can be freed by performing certain actions. For example, removing an identity would unreserve those funds. - -- **Bonded balance**: The tokens locked for staking purposes. Bonded tokens are not transferable until they are unbonded after the unbonding period. - -- **Redeemable balance**: The number of tokens that have completed the unbonding period and are ready to be unlocked and transferred again. For example, if an account has a redeemable balance of 0.1000 KSM, those tokens are now available for spending. - -- **Democracy balance**: Reflects the number of tokens locked for governance activities, such as voting on referenda. These tokens are locked for the duration of the governance action and are only released after the lock period ends. - -By understanding these balance types and their implications, developers and users can better manage their funds and engage with on-chain activities more effectively. - -## Address Formats - -The SS58 address format is a core component of the Polkadot SDK that enables accounts to be uniquely identified across Polkadot-based networks. This format is a modified version of Bitcoin's Base58Check encoding, specifically designed to accommodate the multi-chain nature of the Polkadot ecosystem. SS58 encoding allows each chain to define its own set of addresses while maintaining compatibility and checksum validation for security. - -### Basic Format - -SS58 addresses consist of three main components: - -```text -base58encode(concat(,
, )) -``` - -- **Address type**: A byte or set of bytes that define the network (or chain) for which the address is intended. This ensures that addresses are unique across different Polkadot SDK-based chains. -- **Address**: The public key of the account encoded as bytes. -- **Checksum**: A hash-based checksum which ensures that addresses are valid and unaltered. The checksum is derived from the concatenated address type and address components, ensuring integrity. - -The encoding process transforms the concatenated components into a Base58 string, providing a compact and human-readable format that avoids easily confused characters (e.g., zero '0', capital 'O', lowercase 'l'). This encoding function ([`encode`](https://docs.rs/bs58/latest/bs58/fn.encode.html){target=\_blank}) is implemented exactly as defined in Bitcoin and IPFS specifications, using the same alphabet as both implementations. - -For more details about the SS58 address format implementation, see the [`Ss58Codec`](https://paritytech.github.io/polkadot-sdk/master/sp_core/crypto/trait.Ss58Codec.html){target=\_blank} trait in the Rust Docs. - -### Address Type - -The address type defines how an address is interpreted and to which network it belongs. Polkadot SDK uses different prefixes to distinguish between various chains and address formats: - -- **Address types `0-63`**: Simple addresses, commonly used for network identifiers. -- **Address types `64-127`**: Full addresses that support a wider range of network identifiers. -- **Address types `128-255`**: Reserved for future address format extensions. - -For example, Polkadot’s main network uses an address type of 0, while Kusama uses 2. This ensures that addresses can be used without confusion between networks. - -The address type is always encoded as part of the SS58 address, making it easy to quickly identify the network. Refer to the [SS58 registry](https://github.com/paritytech/ss58-registry){target=\_blank} for the canonical listing of all address type identifiers and how they map to Polkadot SDK-based networks. - -### Address Length - -SS58 addresses can have different lengths depending on the specific format. Address lengths range from as short as 3 to 35 bytes, depending on the complexity of the address and network requirements. This flexibility allows SS58 addresses to adapt to different chains while providing a secure encoding mechanism. - -| Total | Type | Raw account | Checksum | -|-------|------|-------------|----------| -| 3 | 1 | 1 | 1 | -| 4 | 1 | 2 | 1 | -| 5 | 1 | 2 | 2 | -| 6 | 1 | 4 | 1 | -| 7 | 1 | 4 | 2 | -| 8 | 1 | 4 | 3 | -| 9 | 1 | 4 | 4 | -| 10 | 1 | 8 | 1 | -| 11 | 1 | 8 | 2 | -| 12 | 1 | 8 | 3 | -| 13 | 1 | 8 | 4 | -| 14 | 1 | 8 | 5 | -| 15 | 1 | 8 | 6 | -| 16 | 1 | 8 | 7 | -| 17 | 1 | 8 | 8 | -| 35 | 1 | 32 | 2 | - -SS58 addresses also support different payload sizes, allowing a flexible range of account identifiers. - -### Checksum Types - -A checksum is applied to validate SS58 addresses. Polkadot SDK uses a Blake2b-512 hash function to calculate the checksum, which is appended to the address before encoding. The checksum length can vary depending on the address format (e.g., 1-byte, 2-byte, or longer), providing varying levels of validation strength. - -The checksum ensures that an address is not modified or corrupted, adding an extra layer of security for account management. - -### Validating Addresses - -SS58 addresses can be validated using the subkey command-line interface or the Polkadot.js API. These tools help ensure an address is correctly formatted and valid for the intended network. The following sections will provide an overview of how validation works with these tools. - -#### Using Subkey - -[Subkey](https://paritytech.github.io/polkadot-sdk/master/subkey/index.html){target=\_blank} is a CLI tool provided by Polkadot SDK for generating and managing keys. It can inspect and validate SS58 addresses. - -The `inspect` command gets a public key and an SS58 address from the provided secret URI. The basic syntax for the `subkey inspect` command is: - -```bash -subkey inspect [flags] [options] uri -``` - -For the `uri` command-line argument, you can specify the secret seed phrase, a hex-encoded private key, or an SS58 address. If the input is a valid address, the `subkey` program displays the corresponding hex-encoded public key, account identifier, and SS58 addresses. - -For example, to inspect the public keys derived from a secret seed phrase, you can run a command similar to the following: - -```bash -subkey inspect "caution juice atom organ advance problem want pledge someone senior holiday very" -``` - -The command displays output similar to the following: - -
- subkey inspect "caution juice atom organ advance problem want pledge someone senior holiday very" - Secret phrase `caution juice atom organ advance problem want pledge someone senior holiday very` is account: - Secret seed: 0xc8fa03532fb22ee1f7f6908b9c02b4e72483f0dbd66e4cd456b8f34c6230b849 - Public key (hex): 0xd6a3105d6768e956e9e5d41050ac29843f98561410d3a47f9dd5b3b227ab8746 - Public key (SS58): 5Gv8YYFu8H1btvmrJy9FjjAWfb99wrhV3uhPFoNEr918utyR - Account ID: 0xd6a3105d6768e956e9e5d41050ac29843f98561410d3a47f9dd5b3b227ab8746 - SS58 Address: 5Gv8YYFu8H1btvmrJy9FjjAWfb99wrhV3uhPFoNEr918utyR -
- -The `subkey` program assumes an address is based on a public/private key pair. If you inspect an address, the command returns the 32-byte account identifier. - -However, not all addresses in Polkadot SDK-based networks are based on keys. - -Depending on the command-line options you specify and the input you provided, the command output might also display the network for which the address has been encoded. For example: - -```bash -subkey inspect "12bzRJfh7arnnfPPUZHeJUaE62QLEwhK48QnH9LXeK2m1iZU" -``` - -The command displays output similar to the following: - -
- subkey inspect "12bzRJfh7arnnfPPUZHeJUaE62QLEwhK48QnH9LXeK2m1iZU" - Public Key URI `12bzRJfh7arnnfPPUZHeJUaE62QLEwhK48QnH9LXeK2m1iZU` is account: - Network ID/Version: polkadot - Public key (hex): 0x46ebddef8cd9bb167dc30878d7113b7e168e6f0646beffd77d69d39bad76b47a - Account ID: 0x46ebddef8cd9bb167dc30878d7113b7e168e6f0646beffd77d69d39bad76b47a - Public key (SS58): 12bzRJfh7arnnfPPUZHeJUaE62QLEwhK48QnH9LXeK2m1iZU - SS58 Address: 12bzRJfh7arnnfPPUZHeJUaE62QLEwhK48QnH9LXeK2m1iZU -
- -#### Using Polkadot.js API - -To verify an address in JavaScript or TypeScript projects, you can use the functions built into the [Polkadot.js API](https://polkadot.js.org/docs/){target=\_blank}. For example: - -```js -// Import Polkadot.js API dependencies -const { decodeAddress, encodeAddress } = require('@polkadot/keyring'); -const { hexToU8a, isHex } = require('@polkadot/util'); - -// Specify an address to test. -const address = 'INSERT_ADDRESS_TO_TEST'; - -// Check address -const isValidSubstrateAddress = () => { - try { - encodeAddress(isHex(address) ? hexToU8a(address) : decodeAddress(address)); - - return true; - } catch (error) { - return false; - } -}; - -// Query result -const isValid = isValidSubstrateAddress(); -console.log(isValid); - -``` - -If the function returns `true`, the specified address is a valid address. - -#### Other SS58 Implementations - -Support for encoding and decoding Polkadot SDK SS58 addresses has been implemented in several other languages and libraries. - -- **Crystal**: [`wyhaines/base58.cr`](https://github.com/wyhaines/base58.cr){target=\_blank} -- **Go**: [`itering/subscan-plugin`](https://github.com/itering/subscan-plugin){target=\_blank} -- **Python**: [`polkascan/py-scale-codec`](https://github.com/polkascan/py-scale-codec){target=\_blank} -- **TypeScript**: [`subsquid/squid-sdk`](https://github.com/subsquid/squid-sdk){target=\_blank} - - ---- - -Page Title: Randomness - -- Source (raw): https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/reference-parachains-randomness.md -- Canonical (HTML): https://docs.polkadot.com/reference/parachains/randomness/ -- Summary: Explore the importance of randomness in PoS blockchains, focusing on Polkadot’s VRF-based approach to ensure fairness and security in validator selection. - -# Randomness - -## Introduction - -Randomness is crucial in Proof of Stake (PoS) blockchains to ensure a fair and unpredictable distribution of validator duties. However, computers are inherently deterministic, meaning the same input always produces the same output. What we typically refer to as "random" numbers on a computer are actually pseudo-random. These numbers rely on an initial "seed," which can come from external sources like [atmospheric noise](https://www.random.org/randomness/){target=\_blank}, [heart rates](https://mdpi.altmetric.com/details/47574324){target=\_blank}, or even [lava lamps](https://en.wikipedia.org/wiki/Lavarand){target=\_blank}. While this may seem random, given the same "seed," the same sequence of numbers will always be generated. - -In a global blockchain network, relying on real-world entropy for randomness isn’t feasible because these inputs vary by time and location. If nodes use different inputs, blockchains can fork. Hence, real-world randomness isn't suitable for use as a seed in blockchain systems. - -Currently, two primary methods for generating randomness in blockchains are used: [`RANDAO`](#randao) and [`VRF`](#vrf) (Verifiable Random Function). Polkadot adopts the `VRF` approach for its randomness. - -## VRF - -A Verifiable Random Function (VRF) is a cryptographic function that generates a random number and proof that ensures the submitter produced the number. This proof allows anyone to verify the validity of the random number. - -Polkadot's VRF is similar to the one used in [**Ouroboros Praos**](https://eprint.iacr.org/2017/573.pdf){target=\_blank}, which secures randomness for block production in systems like [BABE](/reference/polkadot-hub/consensus-and-security/pos-consensus/#block-production-babe){target=\_blank} (Polkadot’s block production mechanism). - -The key difference is that Polkadot's VRF doesn’t rely on a central clock—avoiding the issue of whose clock to trust. Instead, it uses its own past results and slot numbers to simulate time and determine future outcomes. - -### How VRF Works - -Slots on Polkadot are discrete units of time, each lasting six seconds, and can potentially hold a block. Multiple slots form an epoch, with 2400 slots making up one four-hour epoch. - -In each slot, validators execute a "die roll" using a VRF. The VRF uses three inputs: - -1. A "secret key," unique to each validator, is used for the die roll. -2. An epoch randomness value, derived from the hash of VRF outputs from blocks two epochs ago (N-2), so past randomness influences the current epoch (N). -3. The current slot number. + #[pallet::pallet] + #[pallet::generate_store(pub(super) trait Store)] + pub struct Pallet(_); -This process helps maintain fair randomness across the network. + #[pallet::config] // snip + #[pallet::event] // snip + #[pallet::error] // snip + #[pallet::storage] // snip + #[pallet::call] // snip +} +``` -Here is a graphical representation: +Every pallet can implement these core macros: -![](/images/reference/parachains/randomness/randomness-01.webp) +- **`#[frame_support::pallet]`**: Marks your module as a FRAME pallet. +- **`#[pallet::pallet]`**: Designates the struct that holds pallet metadata. +- **`#[pallet::config]`**: Defines configuration and associated types. +- **`#[pallet::event]`**: Defines events emitted by your pallet. +- **`#[pallet::error]`**: Defines error types your pallet can return. +- **`#[pallet::storage]`**: Defines on-chain storage items. +- **`#[pallet::call]`**: Defines dispatchable functions (transactions). -The VRF produces two outputs: a result (the random number) and a proof (verifying that the number was generated correctly). +For a comprehensive reference, see the [`pallet_macros` documentation](https://paritytech.github.io/polkadot-sdk/master/frame_support/pallet_macros/index.html){target=\_blank}. -The result is checked by the validator against a protocol threshold. If it's below the threshold, the validator becomes a candidate for block production in that slot. +## How Runtime Customization Works -The validator then attempts to create a block, submitting it along with the `PROOF` and `RESULT`. +Customizing your runtime typically follows these patterns: -So, VRF can be expressed like: +**Adding Pre-Built Pallets**: Select pallets from the FRAME library and integrate them into your runtime configuration. This is the fastest way to add functionality. -`(RESULT, PROOF) = VRF(SECRET, EPOCH_RANDOMNESS_VALUE, CURRENT_SLOT_NUMBER)` +**Creating Custom Pallets**: Write custom pallets for features that don't exist in the pre-built library. Custom pallets follow the same structure as pre-built ones and integrate seamlessly. -Put simply, performing a "VRF roll" generates a random number along with proof that the number was genuinely produced and not arbitrarily chosen. +**Combining Multiple Pallets**: Layer multiple pallets together to create complex behaviors. Pallets can call each other and share storage when needed. -After executing the VRF, the `RESULT` is compared to a protocol-defined `THRESHOLD`. If the `RESULT` is below the `THRESHOLD`, the validator becomes a valid candidate to propose a block for that slot. Otherwise, the validator skips the slot. +**Configuring Pallet Parameters**: Most pallets are configurable—you can adjust their behavior through configuration traits without modifying their code. -As a result, there may be multiple validators eligible to propose a block for a slot. In this case, the block accepted by other nodes will prevail, provided it is on the chain with the latest finalized block as determined by the GRANDPA finality gadget. It's also possible for no block producers to be available for a slot, in which case the AURA consensus takes over. AURA is a fallback mechanism that randomly selects a validator to produce a block, running in parallel with BABE and only stepping in when no block producers exist for a slot. Otherwise, it remains inactive. +The following diagram illustrates how pallets combine to form a complete runtime: -Because validators roll independently, no block candidates may appear in some slots if all roll numbers are above the threshold. +![](/images/parachains/customize-runtime/index/frame-overview-02.webp) -To verify resolution of this issue and that Polkadot block times remain near constant-time, see the [PoS Consensus](/reference/polkadot-hub/consensus-and-security/pos-consensus/){target=\_blank} page of this documentation. +## Starting Templates -## RANDAO +The easiest way to begin customizing your runtime is with a starter template. These templates provide a pre-configured foundation so you can focus on customization rather than setup. -An alternative on-chain randomness method is Ethereum's RANDAO, where validators perform thousands of hashes on a seed and publish the final hash during a round. The collective input from all validators forms the random number, and as long as one honest validator participates, the randomness is secure. +- **[Polkadot SDK Parachain Template](https://github.com/paritytech/polkadot-sdk-parachain-template){target=\_blank}**: The recommended choice for most developers, it includes pre-configured pallets for common features (balances, block production, governance), a complete runtime setup, and built-in parachain consensus support. This template offers the best balance of features and learning opportunities. -To enhance security, RANDAO can optionally be combined with a Verifiable Delay Function (VDF), ensuring that randomness can't be predicted or manipulated during computation. +- **[Polkadot SDK Minimal Template](https://github.com/paritytech/polkadot-sdk-minimal-template){target=\_blank}**: Provides a bare-bones runtime with only essential components. Choose this if you want maximum flexibility and prefer building from a clean slate. -For more information about RANDAO, see the [Randomness - RANDAO](https://eth2book.info/capella/part2/building_blocks/randomness/){target=\_blank} section of the Upgrading Ethereum documentation. +- **[Polkadot SDK Solochain Template](https://github.com/paritytech/polkadot-sdk/tree/master/templates/solochain){target=\_blank}**: Designed for building standalone blockchains with moderate features, simple consensus, and several core pallets. Use this if you want a sovereign blockchain independent of a relay chain. -## VDFs +- **[OpenZeppelin Runtime Templates](https://github.com/OpenZeppelin/polkadot-runtime-templates){target=\_blank}**: Provides security-focused configurations following industry best practices. The [generic-template](https://github.com/OpenZeppelin/polkadot-runtime-templates/tree/main/generic-template){target=\_blank} includes curated pallet selections and production-ready defaults—ideal if security is your top priority. -Verifiable Delay Functions (VDFs) are time-bound computations that, even on parallel computers, take a set amount of time to complete. +## Key Customization Scenarios -They produce a unique result that can be quickly verified publicly. When combined with RANDAO, feeding RANDAO's output into a VDF introduces a delay that nullifies an attacker's chance to influence the randomness. +This section covers the most common customization patterns you'll encounter: -However, VDF likely requires specialized ASIC devices to run separately from standard nodes. +- **[Add Existing Pallets to Your Runtime](/parachains/customize-runtime/add-existing-pallets/)**: Integrate pre-built pallets from the FRAME library with minimal configuration. -!!!warning - While only one is needed to secure the system, and they will be open-source and inexpensive, running VDF devices involves significant costs without direct incentives, adding friction for blockchain users. +- **[Add Multiple Instances of a Pallet](/parachains/customize-runtime/add-pallet-instances/)**: Run multiple instances of the same pallet with different configurations—useful for multi-token systems or parallel features. -## Additional Resources +- **[Add Smart Contract Functionality](/parachains/customize-runtime/add-smart-contract-functionality/)**: Enable smart contract execution on your parachain using Contracts pallets. -For more information about the reasoning for choices made along with proofs, see Polkadot's research on blockchain randomness and sortition in the [Block production](https://research.web3.foundation/Polkadot/protocols/block-production){target=\_blank} entry of the Polkadot Wiki. +- **[Create Custom Pallets](/parachains/customize-runtime/pallet-development/create-a-pallet/)**: Build entirely custom pallets for features unique to your blockchain. -For a discussion with Web3 Foundation researchers about when and under what conditions Polkadot's randomness can be utilized, see the [Discussion on Randomness used in Polkadot](https://github.com/use-ink/ink/issues/57){target=\_blank} issue on GitHub. +- **[Test Your Runtime](/parachains/customize-runtime/pallet-development/pallet-testing/)**: Unit test pallets and mock complete runtimes to ensure everything works correctly. --- @@ -8275,398 +6015,6 @@ Beyond Polkadot Hub's native PolkaVM support, the ecosystem offers two main alte ---- - -Page Title: Technical Reference Overview - -- Source (raw): https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/reference.md -- Canonical (HTML): https://docs.polkadot.com/reference/ -- Summary: Learn about Polkadot's technical architecture, governance framework, parachain ecosystem, and the tools you need to build and interact with the network. - -## Introduction - -The Technical Reference section provides comprehensive documentation of Polkadot's architecture, core concepts, and development tooling. Whether you're exploring how Polkadot's relay chain coordinates parachains, understanding governance mechanisms, or building applications on the network, this reference covers the technical foundations you need. - -Polkadot is a multi-chain network that enables diverse, interconnected blockchains to share security and communicate seamlessly. Understanding how these components interact from the [relay chain](/polkadot-protocol/glossary#relay-chain){target=\_blank} that validates [parachains](/polkadot-protocol/glossary#parachain){target=\_blank} to the [governance](/reference/glossary#governance){target=\_blank} mechanisms that evolve the protocol is essential for developers, validators, and network participants. - -This guide organizes technical documentation across five core areas: Polkadot Hub, Parachains, On-Chain Governance, Glossary, and Tools, each providing detailed information on different aspects of the Polkadot ecosystem. - -## Polkadot Hub - -[Polkadot Hub](/reference/polkadot-hub/){target=\_blank} is the entry point to Polkadot for all users and application developers. It provides access to essential Web3 services, including smart contracts, staking, governance, identity management, and cross-ecosystem interoperability—without requiring you to deploy or manage a parachain. - -The Hub encompasses a set of core functionality that enables developers and users to build and interact with applications on Polkadot. Key capabilities include: - -- **Smart contracts**: Deploy Ethereum-compatible smart contracts and build decentralized applications. -- **Assets and tokens**: Create, manage, and transfer fungible tokens and NFTs across the ecosystem. -- **Staking**: Participate in network security and earn rewards by staking DOT. -- **Governance**: Vote on proposals and participate in Polkadot's decentralized decision-making through OpenGov. -- **Identity services**: Register and manage on-chain identities, enabling access to governance roles and network opportunities. -- **Cross-chain interoperability**: Leverage XCM messaging to interact securely with other chains in the Polkadot ecosystem. -- **Collectives and DAOs**: Participate in governance collectives and decentralized autonomous organizations. - -## Parachains - -[Parachains](/reference/parachains/){target=\_blank} are specialized blockchains that connect to the Polkadot relay chain, inheriting its security while maintaining their own application-specific logic. The parachains documentation covers: - -- **Accounts**: Deep dive into account types, storage, and management on parachains. -- **Blocks, transactions and fees**: Understand block production, transaction inclusion, and fee mechanisms. -- **Consensus**: Learn how parachain blocks are validated and finalized through the relay chain's consensus. -- **Chain data**: Explore data structures, storage layouts, and state management. -- **Cryptography**: Study cryptographic primitives used in Polkadot SDK-based chains. -- **Data encoding**: Understand how data is encoded and decoded for blockchain compatibility. -- **Networks**: Learn about networking protocols and peer-to-peer communication. -- **Interoperability**: Discover [Cross-Consensus Messaging (XCM)](/parachains/interoperability/get-started/){target=\_blank}, the standard for cross-chain communication. -- **Randomness**: Understand how randomness is generated and used in Polkadot chains. -- **Node and runtime**: Learn about parachain nodes, runtime environments, and the [Polkadot SDK](https://github.com/paritytech/polkadot-sdk){target=\_blank}. - -## On-Chain Governance - -[On-Chain governance](/reference/governance/){target=\_blank} is the decentralized decision-making mechanism for the Polkadot network. It manages the evolution and modification of the network's runtime logic, enabling community oversight and approval for proposed changes. The governance documentation details: - -- **OpenGov framework**: Understand Polkadot's next-generation governance system with enhanced delegation, flexible tracks, and simultaneous referendums. -- **Origins and tracks**: Learn how governance proposals are categorized, prioritized, and executed based on their privilege level and complexity. -- **Voting and delegation**: Explore conviction voting, vote delegation, and how token holders participate in governance. -- **Governance evolution**: See how Polkadot's governance has evolved from Governance V1 to the current OpenGov system. - -## Glossary - -The [Glossary](/reference/glossary/){target=\_blank} provides quick-reference definitions for Polkadot-specific terminology. Essential terms include: - -- Blockchain concepts (blocks, transactions, state) -- Consensus mechanisms (validators, collators, finality) -- Polkadot-specific terms (relay chain, parachain, XCM, FRAME) -- Network components (nodes, runtimes, storage) -- Governance terminology (origins, tracks, referendums) - -## Tools - -The [Tools](/reference/tools/){target=\_blank} section documents essential development and interaction tools for the Polkadot ecosystem: - -- **Light clients**: Lightweight solutions for interacting with the network without running full nodes. -- **JavaScript/TypeScript tools**: Libraries like [Polkadot.js API](/reference/tools/polkadot-js-api/){target=\_blank} and [PAPI](/reference/tools/papi/){target=\_blank} for building applications. -- **Rust tools**: [Polkadart](/reference/tools/polkadart/){target=\_blank} and other Rust-based libraries for SDK development. -- **Python tools**: [py-substrate-interface](/reference/tools/py-substrate-interface/){target=\_blank} for Python developers. -- **Testing and development**: Tools like [Moonwall](/reference/tools/moonwall/){target=\_blank}, [Chopsticks](/reference/tools/chopsticks/){target=\_blank}, and [Omninode](/reference/tools/omninode/){target=\_blank} for smart contract and parachain testing. -- **Indexing and monitoring**: [Sidecar](/reference/tools/sidecar/){target=\_blank} for data indexing and [Dedot](/reference/tools/dedot/){target=\_blank} for substrate interaction. -- **Cross-chain tools**: [ParaSpell](/reference/tools/paraspell/){target=\_blank} for XCM integration and asset transfers. - -## Where to Go Next - -For detailed exploration of specific areas, proceed to any of the main sections: - -
- -- Learn **Polkadot Hub** - - --- - - Understand the relay chain's role in coordinating parachains, providing shared security, and enabling governance. - - [:octicons-arrow-right-24: Reference](/reference/polkadot-hub/) - -- Learn **Parachains** - - --- - - Deep dive into parachain architecture, consensus, data structures, and building application-specific blockchains. - - [:octicons-arrow-right-24: Reference](/reference/parachains/) - -- Learn **On-Chain Governance** - - --- - - Explore Polkadot's decentralized governance framework and how to participate in network decision-making. - - [:octicons-arrow-right-24: Reference](/reference/governance/) - -- Guide **Glossary** - - --- - - Quick reference for Polkadot-specific terminology and concepts used throughout the documentation. - - [:octicons-arrow-right-24: Reference](/reference/glossary/) - -- Guide **Tools** - - --- - - Discover development tools, libraries, and frameworks for building and interacting with Polkadot. - - [:octicons-arrow-right-24: Reference](/reference/tools/) - -
- - ---- - -Page Title: Transactions - -- Source (raw): https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/reference-parachains-blocks-transactions-fees-transactions.md -- Canonical (HTML): https://docs.polkadot.com/reference/parachains/blocks-transactions-fees/transactions/ -- Summary: Learn how to construct, submit, and validate transactions in the Polkadot SDK, covering signed, unsigned, and inherent types of transactions. - -# Transactions - -## Introduction - -Transactions are essential components of blockchain networks, enabling state changes and the execution of key operations. In the Polkadot SDK, transactions, often called extrinsics, come in multiple forms, including signed, unsigned, and inherent transactions. - -This guide walks you through the different transaction types and how they're formatted, validated, and processed within the Polkadot ecosystem. You'll also learn how to customize transaction formats and construct transactions for FRAME-based runtimes, ensuring a complete understanding of how transactions are built and executed in Polkadot SDK-based chains. - -## What Is a Transaction? - -In the Polkadot SDK, transactions represent operations that modify the chain's state, bundled into blocks for execution. The term extrinsic is often used to refer to any data that originates outside the runtime and is included in the chain. While other blockchain systems typically refer to these operations as "transactions," the Polkadot SDK adopts the broader term "extrinsic" to capture the wide variety of data types that can be added to a block. - -There are three primary types of transactions (extrinsics) in the Polkadot SDK: - -- **Signed transactions**: Signed by the submitting account, often carrying transaction fees. -- **Unsigned transactions**: Submitted without a signature, often requiring custom validation logic. -- **Inherent transactions**: Typically inserted directly into blocks by block authoring nodes, without gossiping between peers. - -Each type serves a distinct purpose, and understanding when and how to use each is key to efficiently working with the Polkadot SDK. - -### Signed Transactions - -Signed transactions require an account's signature and typically involve submitting a request to execute a runtime call. The signature serves as a form of cryptographic proof that the sender has authorized the action, using their private key. These transactions often involve a transaction fee to cover the cost of execution and incentivize block producers. - -Signed transactions are the most common type of transaction and are integral to user-driven actions, such as token transfers. For instance, when you transfer tokens from one account to another, the sending account must sign the transaction to authorize the operation. - -For example, the [`pallet_balances::Call::transfer_allow_death`](https://paritytech.github.io/polkadot-sdk/master/pallet_balances/pallet/struct.Pallet.html#method.transfer_allow_death){target=\_blank} extrinsic in the Balances pallet allows you to transfer tokens. Since your account initiates this transaction, your account key is used to sign it. You'll also be responsible for paying the associated transaction fee, with the option to include an additional tip to incentivize faster inclusion in the block. - -### Unsigned Transactions - -Unsigned transactions do not require a signature or account-specific data from the sender. Unlike signed transactions, they do not come with any form of economic deterrent, such as fees, which makes them susceptible to spam or replay attacks. Custom validation logic must be implemented to mitigate these risks and ensure these transactions are secure. - -Unsigned transactions typically involve scenarios where including a fee or signature is unnecessary or counterproductive. However, due to the absence of fees, they require careful validation to protect the network. For example, [`pallet_im_online::Call::heartbeat`](https://paritytech.github.io/polkadot-sdk/master/pallet_im_online/pallet/struct.Pallet.html#method.heartbeat){target=\_blank} extrinsic allows validators to send a heartbeat signal, indicating they are active. Since only validators can make this call, the logic embedded in the transaction ensures that the sender is a validator, making the need for a signature or fee redundant. - -Unsigned transactions are more resource-intensive than signed ones because custom validation is required, but they play a crucial role in certain operational scenarios, especially when regular user accounts aren't involved. - -### Inherent Transactions - -Inherent transactions are a specialized type of unsigned transaction that is used primarily for block authoring. Unlike signed or other unsigned transactions, inherent transactions are added directly by block producers and are not broadcasted to the network or stored in the transaction queue. They don't require signatures or the usual validation steps and are generally used to insert system-critical data directly into blocks. - -A key example of an inherent transaction is inserting a timestamp into each block. The [`pallet_timestamp::Call::now`](https://paritytech.github.io/polkadot-sdk/master/pallet_timestamp/pallet/struct.Pallet.html#method.now-1){target=\_blank} extrinsic allows block authors to include the current time in the block they are producing. Since the block producer adds this information, there is no need for transaction validation, like signature verification. The validation in this case is done indirectly by the validators, who check whether the timestamp is within an acceptable range before finalizing the block. - -Another example is the [`paras_inherent::Call::enter`](https://paritytech.github.io/polkadot-sdk/master/polkadot_runtime_parachains/paras_inherent/pallet/struct.Pallet.html#method.enter){target=\_blank} extrinsic, which enables parachain collator nodes to send validation data to the relay chain. This inherent transaction ensures that the necessary parachain data is included in each block without the overhead of gossiped transactions. - -Inherent transactions serve a critical role in block authoring by allowing important operational data to be added directly to the chain without needing the validation processes required for standard transactions. - -## Transaction Formats - -Understanding the structure of signed and unsigned transactions is crucial for developers building on Polkadot SDK-based chains. Whether you're optimizing transaction processing, customizing formats, or interacting with the transaction pool, knowing the format of extrinsics, Polkadot's term for transactions, is essential. - -### Types of Transaction Formats - -In Polkadot SDK-based chains, extrinsics can fall into three main categories: - -- **Unchecked extrinsics**: Typically used for signed transactions that require validation. They contain a signature and additional data, such as a nonce and information for fee calculation. Unchecked extrinsics are named as such because they require validation checks before being accepted into the transaction pool. -- **Checked extrinsics**: Typically used for inherent extrinsics (unsigned transactions); these don't require signature verification. Instead, they carry information such as where the extrinsic originates and any additional data required for the block authoring process. -- **Opaque extrinsics**: Used when the format of an extrinsic is not yet fully committed or finalized. They are still decodable, but their structure can be flexible depending on the context. - -### Signed Transaction Data Structure - -A signed transaction typically includes the following components: - -- **Signature**: Verifies the authenticity of the transaction sender. -- **Call**: The actual function or method call the transaction is requesting (for example, transferring funds). -- **Nonce**: Tracks the number of prior transactions sent from the account, helping to prevent replay attacks. -- **Tip**: An optional incentive to prioritize the transaction in block inclusion. -- **Additional data**: Includes details such as spec version, block hash, and genesis hash to ensure the transaction is valid within the correct runtime and chain context. - -Here's a simplified breakdown of how signed transactions are typically constructed in a Polkadot SDK runtime: - -``` code - + + -``` - -Each part of the signed transaction has a purpose, ensuring the transaction's authenticity and context within the blockchain. - -### Signed Extensions - -Polkadot SDK also provides the concept of [signed extensions](https://paritytech.github.io/polkadot-sdk/master/polkadot_sdk_docs/reference_docs/signed_extensions/index.html){target=\_blank}, which allow developers to extend extrinsics with additional data or validation logic before they are included in a block. The [`SignedExtension`](https://paritytech.github.io/try-runtime-cli/sp_runtime/traits/trait.SignedExtension.html){target=\_blank} set helps enforce custom rules or protections, such as ensuring the transaction's validity or calculating priority. - -The transaction queue regularly calls signed extensions to verify a transaction's validity before placing it in the ready queue. This safeguard ensures transactions won't fail in a block. Signed extensions are commonly used to enforce validation logic and protect the transaction pool from spam and replay attacks. - -In FRAME, a signed extension can hold any of the following types by default: - -- **[`AccountId`](https://paritytech.github.io/polkadot-sdk/master/polkadot_sdk_frame/runtime/types_common/type.AccountId.html){target=\_blank}**: To encode the sender's identity. -- **[`Call`](https://paritytech.github.io/polkadot-sdk/master/polkadot_sdk_frame/traits/trait.SignedExtension.html#associatedtype.Call){target=\_blank}**: To encode the pallet call to be dispatched. This data is used to calculate transaction fees. -- **[`AdditionalSigned`](https://paritytech.github.io/polkadot-sdk/master/polkadot_sdk_frame/traits/trait.SignedExtension.html#associatedtype.AdditionalSigned){target=\_blank}**: To handle any additional data to go into the signed payload allowing you to attach any custom logic prior to dispatching a transaction. -- **[`Pre`](https://paritytech.github.io/polkadot-sdk/master/polkadot_sdk_frame/traits/trait.SignedExtension.html#associatedtype.Pre){target=\_blank}**: To encode the information that can be passed from before a call is dispatched to after it gets dispatched. - -Signed extensions can enforce checks like: - -- **[`CheckSpecVersion`](https://paritytech.github.io/polkadot-sdk/master/src/frame_system/extensions/check_spec_version.rs.html){target=\_blank}**: Ensures the transaction is compatible with the runtime's current version. -- **[`CheckWeight`](https://paritytech.github.io/polkadot-sdk/master/frame_system/struct.CheckWeight.html){target=\_blank}**: Calculates the weight (or computational cost) of the transaction, ensuring the block doesn't exceed the maximum allowed weight. - -These extensions are critical in the transaction lifecycle, ensuring that only valid and prioritized transactions are processed. - -## Transaction Construction - -Building transactions in the Polkadot SDK involves constructing a payload that can be verified, signed, and submitted for inclusion in a block. Each runtime in the Polkadot SDK has its own rules for validating and executing transactions, but there are common patterns for constructing a signed transaction. - -### Construct a Signed Transaction - -A signed transaction in the Polkadot SDK includes various pieces of data to ensure security, prevent replay attacks, and prioritize processing. Here's an overview of how to construct one: - -1. **Construct the unsigned payload**: Gather the necessary information for the call, including: - - - **Pallet index**: Identifies the pallet where the runtime function resides. - - **Function index**: Specifies the particular function to call in the pallet. - - **Parameters**: Any additional arguments required by the function call. - -2. **Create a signing payload**: Once the unsigned payload is ready, additional data must be included: - - - **Transaction nonce**: Unique identifier to prevent replay attacks. - - **Era information**: Defines how long the transaction is valid before it's dropped from the pool. - - **Block hash**: Ensures the transaction doesn't execute on the wrong chain or fork. - -3. **Sign the payload**: Using the sender's private key, sign the payload to ensure that the transaction can only be executed by the account holder. -4. **Serialize the signed payload**: Once signed, the transaction must be serialized into a binary format, ensuring the data is compact and easy to transmit over the network. -5. **Submit the serialized transaction**: Finally, submit the serialized transaction to the network, where it will enter the transaction pool and wait for processing by an authoring node. - -The following is an example of how a signed transaction might look: - -``` rust -node_runtime::UncheckedExtrinsic::new_signed( - function.clone(), // some call - sp_runtime::AccountId32::from(sender.public()).into(), // some sending account - node_runtime::Signature::Sr25519(signature.clone()), // the account's signature - extra.clone(), // the signed extensions -) -``` - -### Transaction Encoding - -Before a transaction is sent to the network, it is serialized and encoded using a structured encoding process that ensures consistency and prevents tampering: - -- **`[1]`**: Compact encoded length in bytes of the entire transaction. -- **`[2]`**: A u8 containing 1 byte to indicate whether the transaction is signed or unsigned (1 bit) and the encoded transaction version ID (7 bits). -- **`[3]`**: If signed, this field contains an account ID, an SR25519 signature, and some extra data. -- **`[4]`**: Encoded call data, including pallet and function indices and any required arguments. - -This encoded format ensures consistency and efficiency in processing transactions across the network. By adhering to this format, applications can construct valid transactions and pass them to the network for execution. - -To learn more about how compact encoding works using SCALE, see the [SCALE Codec](https://github.com/paritytech/parity-scale-codec){target=\_blank} README on GitHub. - -### Customize Transaction Construction - -Although the basic steps for constructing transactions are consistent across Polkadot SDK-based chains, developers can customize transaction formats and validation rules. For example: - -- **Custom pallets**: You can define new pallets with custom function calls, each with its own parameters and validation logic. -- **Signed extensions**: Developers can implement custom extensions that modify how transactions are prioritized, validated, or included in blocks. - -By leveraging Polkadot SDK's modular design, developers can create highly specialized transaction logic tailored to their chain's needs. - -## Lifecycle of a Transaction - -In the Polkadot SDK, transactions are often referred to as extrinsics because the data in transactions originates outside of the runtime. These transactions contain data that initiates changes to the chain state. The most common type of extrinsic is a signed transaction, which is cryptographically verified and typically incurs a fee. This section focuses on how signed transactions are processed, validated, and ultimately included in a block. - -### Define Transaction Properties - -The Polkadot SDK runtime defines key transaction properties, such as: - -- **Transaction validity**: Ensures the transaction meets all runtime requirements. -- **Signed or unsigned**: Identifies whether a transaction needs to be signed by an account. -- **State changes**: Determines how the transaction modifies the state of the chain. - -Pallets, which compose the runtime's logic, define the specific transactions that your chain supports. When a user submits a transaction, such as a token transfer, it becomes a signed transaction, verified by the user's account signature. If the account has enough funds to cover fees, the transaction is executed, and the chain's state is updated accordingly. - -### Process on a Block Authoring Node - -In Polkadot SDK-based networks, some nodes are authorized to author blocks. These nodes validate and process transactions. When a transaction is sent to a node that can produce blocks, it undergoes a lifecycle that involves several stages, including validation and execution. Non-authoring nodes gossip the transaction across the network until an authoring node receives it. The following diagram illustrates the lifecycle of a transaction that's submitted to a network and processed by an authoring node. - -![Transaction lifecycle diagram](/images/reference/parachains/blocks-transactions-fees/transactions/transactions-01.webp){ style="background:white" } - -### Validate and Queue - -Once a transaction reaches an authoring node, it undergoes an initial validation process to ensure it meets specific conditions defined in the runtime. This validation includes checks for: - -- **Correct nonce**: Ensures the transaction is sequentially valid for the account. -- **Sufficient funds**: Confirms the account can cover any associated transaction fees. -- **Signature validity**: Verifies that the sender's signature matches the transaction data. - -After these checks, valid transactions are placed in the transaction pool, where they are queued for inclusion in a block. The transaction pool regularly re-validates queued transactions to ensure they remain valid before being processed. To reach consensus, two-thirds of the nodes must agree on the order of the transactions executed and the resulting state change. Transactions are validated and queued on the local node in a transaction pool to prepare for consensus. - -#### Transaction Pool - -The transaction pool is responsible for managing valid transactions. It ensures that only transactions that pass initial validity checks are queued. Transactions that fail validation, expire, or become invalid for other reasons are removed from the pool. - -The transaction pool organizes transactions into two queues: - -- **Ready queue**: Transactions that are valid and ready to be included in a block. -- **Future queue**: Transactions that are not yet valid but could be in the future, such as transactions with a nonce too high for the current state. - -Details on how the transaction pool validates transactions, including fee and signature handling, can be found in the [`validate_transaction`](https://paritytech.github.io/polkadot-sdk/master/sp_transaction_pool/runtime_api/trait.TaggedTransactionQueue.html#method.validate_transaction){target=\_blank} method. - -#### Invalid Transactions - -If a transaction is invalid, for example, due to an invalid signature or insufficient funds, it is rejected and won't be added to the block. Invalid transactions might be rejected for reasons such as: - -- The transaction has already been included in a block. -- The transaction's signature does not match the sender. -- The transaction is too large to fit in the current block. - -### Transaction Ordering and Priority - -When a node is selected as the next block author, it prioritizes transactions based on weight, length, and tip amount. The goal is to fill the block with high-priority transactions without exceeding its maximum size or computational limits. Transactions are ordered as follows: - -- **Inherents first**: Inherent transactions, such as block timestamp updates, are always placed first. -- **Nonce-based ordering**: Transactions from the same account are ordered by their nonce. -- **Fee-based ordering**: Among transactions with the same nonce or priority level, those with higher fees are prioritized. - -### Transaction Execution - -Once a block author selects transactions from the pool, the transactions are executed in priority order. As each transaction is processed, the state changes are written directly to the chain's storage. It's important to note that these changes are not cached, meaning a failed transaction won't revert earlier state changes, which could leave the block in an inconsistent state. - -Events are also written to storage. Runtime logic should not emit an event before performing the associated actions. If the associated transaction fails after the event was emitted, the event will not revert. - -## Transaction Mortality - -Transactions in the network can be configured as either mortal (with expiration) or immortal (without expiration). Every transaction payload contains a block checkpoint (reference block number and hash) and an era/validity period that determines how many blocks after the checkpoint the transaction remains valid. - -When a transaction is submitted, the network validates it against these parameters. If the transaction is not included in a block within the specified validity window, it is automatically removed from the transaction queue. - -- **Mortal transactions**: Have a finite lifespan and will expire after a specified number of blocks. For example, a transaction with a block checkpoint of 1000 and a validity period of 64 blocks will be valid from blocks 1000 to 1064. - -- **Immortal transactions**: Never expire and remain valid indefinitely. To create an immortal transaction, set the block checkpoint to 0 (genesis block), use the genesis hash as a reference, and set the validity period to 0. - -However, immortal transactions pose significant security risks through replay attacks. If an account is reaped (balance drops to zero, account removed) and later re-funded, malicious actors can replay old immortal transactions. - -The blockchain maintains only a limited number of prior block hashes for reference validation, called `BlockHashCount`. If your validity period exceeds `BlockHashCount`, the effective validity period becomes the minimum of your specified period and the block hash count. - -## Unique Identifiers for Extrinsics - -Transaction hashes are **not unique identifiers** in Polkadot SDK-based chains. - -Key differences from traditional blockchains: - -- Transaction hashes serve only as fingerprints of transaction information. -- Multiple valid transactions can share the same hash. -- Hash uniqueness assumptions lead to serious issues. - -For example, when an account is reaped (removed due to insufficient balance) and later recreated, it resets to nonce 0, allowing identical transactions to be valid at different points: - -| Block | Extrinsic Index | Hash | Origin | Nonce | Call | Result | -|-------|----------------|------|-----------|-------|---------------------|-------------------------------| -| 100 | 0 | 0x01 | Account A | 0 | Transfer 5 DOT to B | Account A reaped | -| 150 | 5 | 0x02 | Account B | 4 | Transfer 7 DOT to A | Account A created (nonce = 0) | -| 200 | 2 | 0x01 | Account A | 0 | Transfer 5 DOT to B | Successful transaction | - -Notice that blocks 100 and 200 contain transactions with identical hashes (0x01) but are completely different, valid operations occurring at different times. - -Additional complexity comes from Polkadot SDK's origin abstraction. Origins can represent collectives, governance bodies, or other non-account entities that don't maintain nonces like regular accounts and might dispatch identical calls multiple times with the same hash values. Each execution occurs in different chain states with different results. - -The correct way to uniquely identify an extrinsic on a Polkadot SDK-based chain is to use the block ID (height or hash) and the extrinsic index. Since the Polkadot SDK defines blocks as headers plus ordered arrays of extrinsics, the index position within a canonical block provides guaranteed uniqueness. - -## Additional Resources - -For a video overview of the lifecycle of transactions and the types of transactions that exist, see the [Transaction lifecycle](https://www.youtube.com/watch?v=3pfM0GOp02c){target=\_blank} seminar from Parity Tech. - - --- Page Title: Transactions and Fees on Asset Hub @@ -9608,10 +6956,10 @@ cd wagmi-polkadot-hub ## Install Dependencies -Install Wagmi and its peer dependencies: +Install Wagmi v3 and its peer dependencies: ```bash -npm install wagmi viem @tanstack/react-query +npm install wagmi@3 viem @tanstack/react-query ``` ## Configure Wagmi for Polkadot Hub @@ -9724,12 +7072,12 @@ Create a component to connect wallets to your dApp. Create a file named `app/com "use client"; import React from "react"; -import { useConnect, useAccount, useDisconnect } from "wagmi"; +import { useConnect, useConnection, useDisconnect } from "wagmi"; import { injected } from "wagmi/connectors"; export function ConnectWallet() { const { connect } = useConnect(); - const { address, isConnected } = useAccount(); + const { address, isConnected } = useConnection(); const { disconnect } = useDisconnect(); if (isConnected) { @@ -9754,7 +7102,7 @@ This component uses the following React hooks: - **[`useConnect`](https://wagmi.sh/react/api/hooks/useConnect#useconnect){target=\_blank}**: Provides functions and state for connecting the user's wallet to your dApp. The `connect` function initiates the connection flow with the specified connector. - **[`useDisconnect`](https://wagmi.sh/react/api/hooks/useDisconnect#usedisconnect){target=\_blank}**: Provides a function to disconnect the currently connected wallet. -- **[`useAccount`](https://2.x.wagmi.sh/react/api/hooks/useAccount#useaccount){target=\_blank}**: Returns data about the connected account, including the address and connection status. +- **[`useConnection`](https://wagmi.sh/react/api/hooks/useConnection#useconnection){target=\_blank}**: Returns data about the connected account, including the address and connection status. In Wagmi v3, `useAccount` has been renamed to `useConnection`. ## Fetch Blockchain Data @@ -9763,10 +7111,10 @@ Wagmi provides various hooks to fetch blockchain data. Here's an example compone ```typescript title="app/components/BlockchainInfo.tsx" "use client"; -import { useBlockNumber, useBalance, useAccount } from "wagmi"; +import { useBlockNumber, useBalance, useConnection } from "wagmi"; export function BlockchainInfo() { - const { address } = useAccount(); + const { address } = useConnection(); // Get the latest block number const { data: blockNumber } = useBlockNumber({ watch: true }); @@ -9957,10 +7305,10 @@ Update your main page to combine all the components. Create or update the file ` import { BlockchainInfo } from "./components/BlockchainInfo"; import { ConnectWallet } from "./components/ConnectWallet"; import { StorageContract } from "./components/StorageContract"; -import { useAccount } from "wagmi"; +import { useConnection } from "wagmi"; export default function Home() { - const { isConnected } = useAccount(); + const { isConnected } = useConnection(); return (
@@ -10566,91 +7914,3 @@ python update_storage.py [:octicons-arrow-right-24: Get Started](https://web3py.readthedocs.io/en/stable/){target=\_blank} - - ---- - -Page Title: XCM Tools - -- Source (raw): https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/reference-tools-xcm-tools.md -- Canonical (HTML): https://docs.polkadot.com/reference/tools/xcm-tools/ -- Summary: Explore essential XCM tools across Polkadot, crafted to enhance cross-chain functionality and integration within the ecosystem. - -# XCM Tools - -## Introduction - -As described in the [Interoperability](/develop/interoperability){target=\_blank} section, XCM (Cross-Consensus Messaging) is a protocol used in the Polkadot and Kusama ecosystems to enable communication and interaction between chains. It facilitates cross-chain communication, allowing assets, data, and messages to flow seamlessly across the ecosystem. - -As XCM is central to enabling communication between blockchains, developers need robust tools to help interact with, build, and test XCM messages. Several XCM tools simplify working with the protocol by providing libraries, frameworks, and utilities that enhance the development process, ensuring that applications built within the Polkadot ecosystem can efficiently use cross-chain functionalities. - -## Popular XCM Tools - -### Moonsong Labs XCM Tools - -[Moonsong Labs XCM Tools](https://github.com/Moonsong-Labs/xcm-tools){target=\_blank} provides a collection of scripts for managing and testing XCM operations between Polkadot SDK-based runtimes. These tools allow performing tasks like asset registration, channel setup, and XCM initialization. Key features include: - -- **Asset registration**: Registers assets, setting units per second (up-front fees), and configuring error (revert) codes. -- **XCM initializer**: Initializes XCM, sets default XCM versions, and configures revert codes for XCM-related precompiles. -- **HRMP manipulator**: Manages HRMP channel actions, including opening, accepting, or closing channels. -- **XCM-Transactor-Info-Setter**: Configures transactor information, including extra weight and fee settings. -- **Decode XCM**: Decodes XCM messages on the relay chain or parachains to help interpret cross-chain communication. - -To get started, clone the repository and install the required dependencies: - -```bash -git clone https://github.com/Moonsong-Labs/xcm-tools && -cd xcm-tools && -yarn install -``` - -For a full overview of each script, visit the [scripts](https://github.com/Moonsong-Labs/xcm-tools/tree/main/scripts){target=\_blank} directory or refer to the [official documentation](https://github.com/Moonsong-Labs/xcm-tools/blob/main/README.md){target=\_blank} on GitHub. - -### ParaSpell - -[ParaSpell](/reference/tools/paraspell/){target=\_blank} is a collection of open-source XCM tools that streamline cross-chain asset transfers and interactions across the Polkadot and Kusama ecosystems. It provides developers with an intuitive interface to build, test, and deploy interoperable dApps, featuring message composition, decoding, and practical utilities for parachain interactions that simplify debugging and cross-chain communication optimization. - -### Astar XCM Tools - -The [Astar parachain](https://github.com/AstarNetwork/Astar/tree/master){target=\_blank} offers a crate with a set of utilities for interacting with the XCM protocol. The [xcm-tools](https://github.com/AstarNetwork/Astar/tree/master/bin/xcm-tools){target=\_blank} crate provides a straightforward method for users to locate a sovereign account or calculate an XC20 asset ID. Some commands included by the xcm-tools crate allow users to perform the following tasks: - -- **Sovereign accounts**: Obtain the sovereign account address for any parachain, either on the Relay Chain or for sibling parachains, using a simple command. -- **XC20 EVM addresses**: Generate XC20-compatible Ethereum addresses for assets by entering the asset ID, making it easy to integrate assets across Ethereum-compatible environments. -- **Remote accounts**: Retrieve remote account addresses needed for multi-location compatibility, using flexible options to specify account types and parachain IDs. - -To start using these tools, clone the [Astar repository](https://github.com/AstarNetwork/Astar){target=\_blank} and compile the xcm-tools package: - -```bash -git clone https://github.com/AstarNetwork/Astar && -cd Astar && -cargo build --release -p xcm-tools -``` - -After compiling, verify the setup with the following command: - -```bash -./target/release/xcm-tools --help -``` -For more details on using Astar xcm-tools, consult the [official documentation](https://docs.astar.network/docs/learn/interoperability/xcm/integration/tools/){target=\_blank}. - -### Chopsticks - -The Chopsticks library provides XCM functionality for testing XCM messages across networks, enabling you to fork multiple parachains along with a relay chain. For further details, see the [Chopsticks documentation](/tutorials/polkadot-sdk/testing/fork-live-chains/){target=\_blank} about XCM. - -### Moonbeam XCM SDK - -The [Moonbeam XCM SDK](https://github.com/moonbeam-foundation/xcm-sdk){target=\_blank} enables developers to easily transfer assets between chains, either between parachains or between a parachain and the relay chain, within the Polkadot/Kusama ecosystem. With the SDK, you don't need to worry about determining the [Multilocation](https://github.com/polkadot-fellows/xcm-format?tab=readme-ov-file#7-universal-consensus-location-identifiers){target=\_blank} of the origin or destination assets or which extrinsics are used on which networks. - -The SDK consists of two main packages: - -- **[XCM SDK](https://github.com/moonbeam-foundation/xcm-sdk/tree/main/packages/sdk){target=\_blank}**: Core SDK for executing XCM transfers between chains in the Polkadot/Kusama ecosystem. -- **[MRL SDK](https://github.com/moonbeam-foundation/xcm-sdk/tree/main/packages/mrl){target=\_blank}**: Extension of the XCM SDK for transferring liquidity into and across the Polkadot ecosystem from other ecosystems like Ethereum. - -Key features include: - -- **Simplified asset transfers**: Abstracts away complex multilocation determinations and extrinsic selection. -- **Cross-ecosystem support**: Enables transfers between Polkadot/Kusama chains and external ecosystems. -- **Developer-friendly API**: Provides intuitive interfaces for cross-chain functionality. -- **Comprehensive documentation**: Includes usage guides and API references for both packages. - -For detailed usage examples and API documentation, visit the [official Moonbeam XCM SDK documentation](https://moonbeam-foundation.github.io/xcm-sdk/latest/){target=\_blank}. diff --git a/.ai/categories/tooling.md b/.ai/categories/tooling.md index 4a026f9be..dc7f78395 100644 --- a/.ai/categories/tooling.md +++ b/.ai/categories/tooling.md @@ -158,440 +158,6 @@ BlockScout is an open-source explorer platform with a user-friendly interface ad ![](/images/smart-contracts/explorers/explorers-01.webp) ---- - -Page Title: Blocks - -- Source (raw): https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/reference-parachains-blocks-transactions-fees-blocks.md -- Canonical (HTML): https://docs.polkadot.com/reference/parachains/blocks-transactions-fees/blocks/ -- Summary: Understand how blocks are produced, validated, and imported in Polkadot SDK-based blockchains, covering initialization, finalization, and authoring processes. - -# Blocks - -## Introduction - -In the Polkadot SDK, blocks are fundamental to the functioning of the blockchain, serving as containers for [transactions](/reference/parachains/blocks-transactions-fees/transactions/){target=\_blank} and changes to the chain's state. Blocks consist of headers and an array of transactions, ensuring the integrity and validity of operations on the network. This guide explores the essential components of a block, the process of block production, and how blocks are validated and imported across the network. By understanding these concepts, developers can better grasp how blockchains maintain security, consistency, and performance within the Polkadot ecosystem. - -## What is a Block? - -In the Polkadot SDK, a block is a fundamental unit that encapsulates both the header and an array of transactions. The block header includes critical metadata to ensure the integrity and sequence of the blockchain. Here's a breakdown of its components: - -- **Block height**: Indicates the number of blocks created in the chain so far. -- **Parent hash**: The hash of the previous block, providing a link to maintain the blockchain's immutability. -- **Transaction root**: Cryptographic digest summarizing all transactions in the block. -- **State root**: A cryptographic digest representing the post-execution state. -- **Digest**: Additional information that can be attached to a block, such as consensus-related messages. - -Each transaction is part of a series that is executed according to the runtime's rules. The transaction root is a cryptographic digest of this series, which prevents alterations and enables succinct verification by light clients. This verification process allows light clients to confirm whether a transaction exists in a block with only the block header, avoiding downloading the entire block. - -## Block Production - -When an authoring node is authorized to create a new block, it selects transactions from the transaction queue based on priority. This step, known as block production, relies heavily on the executive module to manage the initialization and finalization of blocks. The process is summarized as follows: - -### Initialize Block - -The block initialization process begins with a series of function calls that prepare the block for transaction execution: - -1. **Call `on_initialize`**: The executive module calls the [`on_initialize`](https://paritytech.github.io/polkadot-sdk/master/frame_support/traits/trait.Hooks.html#method.on_initialize){target=\_blank} hook from the system pallet and other runtime pallets to prepare for the block's transactions. -2. **Coordinate runtime calls**: Coordinates function calls in the order defined by the transaction queue. -3. **Verify information**: Once [`on_initialize`](https://paritytech.github.io/polkadot-sdk/master/frame_support/traits/trait.Hooks.html#method.on_initialize){target=\_blank} functions are executed, the executive module checks the parent hash in the block header and the trie root to verify information is consistent. - -### Finalize Block - -Once transactions are processed, the block must be finalized before being broadcast to the network. The finalization steps are as follows: - -1. **Call `on_finalize`**: The executive module calls the [`on_finalize`](https://paritytech.github.io/polkadot-sdk/master/frame_support/traits/trait.Hooks.html#method.on_finalize){target=\_blank} hooks in each pallet to ensure any remaining state updates or checks are completed before the block is sealed and published. -2. **Verify information**: The block's digest and storage root in the header are checked against the initialized block to ensure consistency. -3. **Call `on_idle`**: The [`on_idle`](https://paritytech.github.io/polkadot-sdk/master/frame_support/traits/trait.Hooks.html#method.on_idle){target=\_blank} hook is triggered to process any remaining tasks using the leftover weight from the block. - -## Block Authoring and Import - -Once the block is finalized, it is gossiped to other nodes in the network. Nodes follow this procedure: - -1. **Receive transactions**: The authoring node collects transactions from the network. -2. **Validate**: Transactions are checked for validity. -3. **Queue**: Valid transactions are placed in the transaction pool for execution. -4. **Execute**: State changes are made as the transactions are executed. -5. **Publish**: The finalized block is broadcast to the network. - -### Block Import Queue - -After a block is published, other nodes on the network can import it into their chain state. The block import queue is part of the outer node in every Polkadot SDK-based node and ensures incoming blocks are valid before adding them to the node's state. - -In most cases, you don't need to know details about how transactions are gossiped or how other nodes on the network import blocks. The following traits are relevant, however, if you plan to write any custom consensus logic or want a deeper dive into the block import queue: - -- **[`ImportQueue`](https://paritytech.github.io/polkadot-sdk/master/sc_consensus/import_queue/trait.ImportQueue.html){target=\_blank}**: The trait that defines the block import queue. -- **[`Link`](https://paritytech.github.io/polkadot-sdk/master/sc_consensus/import_queue/trait.Link.html){target=\_blank}**: The trait that defines the link between the block import queue and the network. -- **[`BasicQueue`](https://paritytech.github.io/polkadot-sdk/master/sc_consensus/import_queue/struct.BasicQueue.html){target=\_blank}**: A basic implementation of the block import queue. -- **[`Verifier`](https://paritytech.github.io/polkadot-sdk/master/sc_consensus/import_queue/trait.Verifier.html){target=\_blank}**: The trait that defines the block verifier. -- **[`BlockImport`](https://paritytech.github.io/polkadot-sdk/master/sc_consensus/block_import/trait.BlockImport.html){target=\_blank}**: The trait that defines the block import process. - -These traits govern how blocks are validated and imported across the network, ensuring consistency and security. - -## Additional Resources - -To learn more about the block structure in the Polkadot SDK runtime, see the [`Block` reference](https://paritytech.github.io/polkadot-sdk/master/sp_runtime/traits/trait.Block.html){target=\_blank} entry in the Rust Docs. - - ---- - -Page Title: Chain Data - -- Source (raw): https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/reference-parachains-chain-data.md -- Canonical (HTML): https://docs.polkadot.com/reference/parachains/chain-data/ -- Summary: Learn how to expose and utilize chain data for blockchain applications. Discover runtime metadata, RPC APIs, and tools for efficient development. - -# Chain Data - -## Introduction - -Understanding and leveraging on-chain data is a fundamental aspect of blockchain development. Whether you're building frontend applications or backend systems, accessing and decoding runtime metadata is vital to interacting with the blockchain. This guide introduces you to the tools and processes for generating and retrieving metadata, explains its role in application development, and outlines the additional APIs available for interacting with a Polkadot node. By mastering these components, you can ensure seamless communication between your applications and the blockchain. - -## Application Development - -You might not be directly involved in building frontend applications as a blockchain developer. However, most applications that run on a blockchain require some form of frontend or user-facing client to enable users or other programs to access and modify the data that the blockchain stores. For example, you might develop a browser-based, mobile, or desktop application that allows users to submit transactions, post articles, view their assets, or track previous activity. The backend for that application is configured in the runtime logic for your blockchain, but the frontend client makes the runtime features accessible to your users. - -For your custom chain to be useful to others, you'll need to provide a client application that allows users to view, interact with, or update information that the blockchain keeps track of. In this article, you'll learn how to expose information about your runtime so that client applications can use it, see examples of the information exposed, and explore tools and libraries that use it. - -## Understand Metadata - -Polkadot SDK-based blockchain networks are designed to expose their runtime information, allowing developers to learn granular details regarding pallets, RPC calls, and runtime APIs. The metadata also exposes their related documentation. The chain's metadata is [SCALE-encoded](/reference/parachains/data-encoding/){target=\_blank}, allowing for the development of browser-based, mobile, or desktop applications to support the chain's runtime upgrades seamlessly. It is also possible to develop applications compatible with multiple Polkadot SDK-based chains simultaneously. - -## Expose Runtime Information as Metadata - -To interact with a node or the state of the blockchain, you need to know how to connect to the chain and access the exposed runtime features. This interaction involves a Remote Procedure Call (RPC) through a node endpoint address, commonly through a secure web socket connection. - -An application developer typically needs to know the contents of the runtime logic, including the following details: - -- Version of the runtime the application is connecting to. -- Supported APIs. -- Implemented pallets. -- Defined functions and corresponding type signatures. -- Defined custom types. -- Exposed parameters users can set. - -As the Polkadot SDK is modular and provides a composable framework for building blockchains, there are limitless opportunities to customize the schema of properties. Each runtime can be configured with its properties, including function calls and types, which can be changed over time with runtime upgrades. - -The Polkadot SDK enables you to generate the runtime metadata schema to capture information unique to a runtime. The metadata for a runtime describes the pallets in use and types defined for a specific runtime version. The metadata includes information about each pallet's storage items, functions, events, errors, and constants. The metadata also provides type definitions for any custom types included in the runtime. - -Metadata provides a complete inventory of a chain's runtime. It is key to enabling client applications to interact with the node, parse responses, and correctly format message payloads sent back to that chain. - -## Generate Metadata - -To efficiently use the blockchain's networking resources and minimize the data transmitted over the network, the metadata schema is encoded using the [Parity SCALE Codec](https://github.com/paritytech/parity-scale-codec?tab=readme-ov-file#parity-scale-codec){target=\_blank}. This encoding is done automatically through the [`scale-info`](https://docs.rs/scale-info/latest/scale_info/){target=\_blank}crate. - -At a high level, generating the metadata involves the following steps: - -1. The pallets in the runtime logic expose callable functions, types, parameters, and documentation that need to be encoded in the metadata. -2. The `scale-info` crate collects type information for the pallets in the runtime, builds a registry of the pallets that exist in a particular runtime, and the relevant types for each pallet in the registry. The type information is detailed enough to enable encoding and decoding for every type. -3. The [`frame-metadata`](https://github.com/paritytech/frame-metadata){target=\_blank} crate describes the structure of the runtime based on the registry provided by the `scale-info` crate. -4. Nodes provide the RPC method `state_getMetadata` to return a complete description of all the types in the current runtime as a hex-encoded vector of SCALE-encoded bytes. - -## Retrieve Runtime Metadata - -The type information provided by the metadata enables applications to communicate with nodes using different runtime versions and across chains that expose different calls, events, types, and storage items. The metadata also allows libraries to generate a substantial portion of the code needed to communicate with a given node, enabling libraries like [`subxt`](https://github.com/paritytech/subxt){target=\_blank} to generate frontend interfaces that are specific to a target chain. - -### Use Polkadot.js - -Visit the [Polkadot.js Portal](https://polkadot.js.org/apps/#/rpc){target=\_blank} and select the **Developer** dropdown in the top banner. Select **RPC Calls** to make the call to request metadata. Follow these steps to make the RPC call: - -1. Select **state** as the endpoint to call. -2. Select **`getMetadata(at)`** as the method to call. -3. Click **Submit RPC call** to submit the call and return the metadata in JSON format. - -### Use Curl - -You can fetch the metadata for the network by calling the node's RPC endpoint. This request returns the metadata in bytes rather than human-readable JSON: - -```sh -curl -H "Content-Type: application/json" \ --d '{"id":1, "jsonrpc":"2.0", "method": "state_getMetadata"}' \ -https://rpc.polkadot.io - -``` - -### Use Subxt - -[`subxt`](https://github.com/paritytech/subxt){target=\_blank} may also be used to fetch the metadata of any data in a human-readable JSON format: - -```sh -subxt metadata --url wss://rpc.polkadot.io --format json > spec.json -``` - -Another option is to use the [`subxt` explorer web UI](https://paritytech.github.io/subxt-explorer/#/){target=\_blank}. - -## Client Applications and Metadata - -The metadata exposes the expected way to decode each type, meaning applications can send, retrieve, and process application information without manual encoding and decoding. Client applications must use the [SCALE codec library](https://github.com/paritytech/parity-scale-codec?tab=readme-ov-file#parity-scale-codec){target=\_blank} to encode and decode RPC payloads to use the metadata. Client applications use the metadata to interact with the node, parse responses, and format message payloads sent to the node. - -## Metadata Format - -Although the SCALE-encoded bytes can be decoded using the `frame-metadata` and [`parity-scale-codec`](https://github.com/paritytech/parity-scale-codec){target=\_blank} libraries, there are other tools, such as `subxt` and the Polkadot-JS API, that can convert the raw data to human-readable JSON format. - -The types and type definitions included in the metadata returned by the `state_getMetadata` RPC call depend on the runtime's metadata version. - -In general, the metadata includes the following information: - -- A constant identifying the file as containing metadata. -- The version of the metadata format used in the runtime. -- Type definitions for all types used in the runtime and generated by the `scale-info` crate. -- Pallet information for the pallets included in the runtime in the order that they are defined in the `construct_runtime` macro. - -!!!tip - Depending on the frontend library used (such as the [Polkadot API](https://papi.how/){target=\_blank}), they may format the metadata differently than the raw format shown. - -The following example illustrates a condensed and annotated section of metadata decoded and converted to JSON: - -```json -[ - 1635018093, - { - "V14": { - "types": { - "types": [{}] - }, - "pallets": [{}], - "extrinsic": { - "ty": 126, - "version": 4, - "signed_extensions": [{}] - }, - "ty": 141 - } - } -] - -``` - -The constant `1635018093` is a magic number that identifies the file as a metadata file. The rest of the metadata is divided into the `types`, `pallets`, and `extrinsic` sections: - -- The `types` section contains an index of the types and information about each type's type signature. -- The `pallets` section contains information about each pallet in the runtime. -- The `extrinsic` section describes the type identifier and transaction format version that the runtime uses. - -Different extrinsic versions can have varying formats, especially when considering [signed transactions](/reference/parachains/blocks-transactions-fees/transactions/#signed-transactions){target=\_blank}. - -### Pallets - -The following is a condensed and annotated example of metadata for a single element in the `pallets` array (the [`sudo`](https://paritytech.github.io/polkadot-sdk/master/pallet_sudo/index.html){target=\_blank} pallet): - -```json -{ - "name": "Sudo", - "storage": { - "prefix": "Sudo", - "entries": [ - { - "name": "Key", - "modifier": "Optional", - "ty": { - "Plain": 0 - }, - "default": [0], - "docs": ["The `AccountId` of the sudo key."] - } - ] - }, - "calls": { - "ty": 117 - }, - "event": { - "ty": 42 - }, - "constants": [], - "error": { - "ty": 124 - }, - "index": 8 -} - -``` - -Every element metadata contains the name of the pallet it represents and information about its storage, calls, events, and errors. You can look up details about the definition of the calls, events, and errors by viewing the type index identifier. The type index identifier is the `u32` integer used to access the type information for that item. For example, the type index identifier for calls in the Sudo pallet is 117. If you view information for that type identifier in the `types` section of the metadata, it provides information about the available calls, including the documentation for each call. - -For example, the following is a condensed excerpt of the calls for the Sudo pallet: - -```json -{ - "id": 117, - "type": { - "path": ["pallet_sudo", "pallet", "Call"], - "params": [ - { - "name": "T", - "type": null - } - ], - "def": { - "variant": { - "variants": [ - { - "name": "sudo", - "fields": [ - { - "name": "call", - "type": 114, - "typeName": "Box<::RuntimeCall>" - } - ], - "index": 0, - "docs": [ - "Authenticates sudo key, dispatches a function call with `Root` origin" - ] - }, - { - "name": "sudo_unchecked_weight", - "fields": [ - { - "name": "call", - "type": 114, - "typeName": "Box<::RuntimeCall>" - }, - { - "name": "weight", - "type": 8, - "typeName": "Weight" - } - ], - "index": 1, - "docs": [ - "Authenticates sudo key, dispatches a function call with `Root` origin" - ] - }, - { - "name": "set_key", - "fields": [ - { - "name": "new", - "type": 103, - "typeName": "AccountIdLookupOf" - } - ], - "index": 2, - "docs": [ - "Authenticates current sudo key, sets the given AccountId (`new`) as the new sudo" - ] - }, - { - "name": "sudo_as", - "fields": [ - { - "name": "who", - "type": 103, - "typeName": "AccountIdLookupOf" - }, - { - "name": "call", - "type": 114, - "typeName": "Box<::RuntimeCall>" - } - ], - "index": 3, - "docs": [ - "Authenticates sudo key, dispatches a function call with `Signed` origin from a given account" - ] - } - ] - } - } - } -} - -``` - -For each field, you can access type information and metadata for the following: - -- **Storage metadata**: Provides the information required to enable applications to get information for specific storage items. -- **Call metadata**: Includes information about the runtime calls defined by the `#[pallet]` macro including call names, arguments and documentation. -- **Event metadata**: Provides the metadata generated by the `#[pallet::event]` macro, including the name, arguments, and documentation for each pallet event. -- **Constants metadata**: Provides metadata generated by the `#[pallet::constant]` macro, including the name, type, and hex-encoded value of the constant. -- **Error metadata**: Provides metadata generated by the `#[pallet::error]` macro, including the name and documentation for each pallet error. - -!!!tip - Type identifiers change from time to time, so you should avoid relying on specific type identifiers in your applications. - -### Extrinsic - -The runtime generates extrinsic metadata and provides useful information about transaction format. When decoded, the metadata contains the transaction version and the list of signed extensions. - -For example: - -```json -{ - "extrinsic": { - "ty": 126, - "version": 4, - "signed_extensions": [ - { - "identifier": "CheckNonZeroSender", - "ty": 132, - "additional_signed": 41 - }, - { - "identifier": "CheckSpecVersion", - "ty": 133, - "additional_signed": 4 - }, - { - "identifier": "CheckTxVersion", - "ty": 134, - "additional_signed": 4 - }, - { - "identifier": "CheckGenesis", - "ty": 135, - "additional_signed": 11 - }, - { - "identifier": "CheckMortality", - "ty": 136, - "additional_signed": 11 - }, - { - "identifier": "CheckNonce", - "ty": 138, - "additional_signed": 41 - }, - { - "identifier": "CheckWeight", - "ty": 139, - "additional_signed": 41 - }, - { - "identifier": "ChargeTransactionPayment", - "ty": 140, - "additional_signed": 41 - } - ] - }, - "ty": 141 -} - -``` - -The type system is [composite](https://paritytech.github.io/polkadot-sdk/master/polkadot_sdk_docs/reference_docs/frame_runtime_types/index.html){target=\_blank}, meaning each type identifier contains a reference to a specific type or to another type identifier that provides information about the associated primitive types. - -For example, you can encode the `BitVec` type, but to decode it properly, you must know the types used for the `Order` and `Store` types. To find type information for `Order` and `Store`, you can use the path in the decoded JSON to locate their type identifiers. - -## Included RPC APIs - -A standard node comes with the following APIs to interact with a node: - -- **[`AuthorApiServer`](https://paritytech.github.io/polkadot-sdk/master/sc_rpc/author/trait.AuthorApiServer.html){target=\_blank}**: Make calls into a full node, including authoring extrinsics and verifying session keys. -- **[`ChainApiServer`](https://paritytech.github.io/polkadot-sdk/master/sc_rpc/chain/trait.ChainApiServer.html){target=\_blank}**: Retrieve block header and finality information. -- **[`OffchainApiServer`](https://paritytech.github.io/polkadot-sdk/master/sc_rpc/offchain/trait.OffchainApiServer.html){target=\_blank}**: Make RPC calls for off-chain workers. -- **[`StateApiServer`](https://paritytech.github.io/polkadot-sdk/master/sc_rpc/state/trait.StateApiServer.html){target=\_blank}**: Query information about on-chain state such as runtime version, storage items, and proofs. -- **[`SystemApiServer`](https://paritytech.github.io/polkadot-sdk/master/sc_rpc/system/trait.SystemApiServer.html){target=\_blank}**: Retrieve information about network state, such as connected peers and node roles. - -## Additional Resources - -The following tools can help you locate and decode metadata: - -- [Subxt Explorer](https://paritytech.github.io/subxt-explorer/#/){target=\_blank} -- [Metadata Portal 🌗](https://github.com/paritytech/metadata-portal){target=\_blank} -- [De[code] Sub[strate]](https://github.com/paritytech/desub){target=\_blank} - - --- Page Title: Contract Deployment @@ -3032,423 +2598,132 @@ PolkaVM differs from the EVM in two key ways that make it faster, more hardware- --- -Page Title: E2E Testing with Moonwall +Page Title: Fork a Parachain Using Chopsticks -- Source (raw): https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/reference-tools-moonwall.md -- Canonical (HTML): https://docs.polkadot.com/reference/tools/moonwall/ -- Summary: Enhance blockchain end-to-end testing with Moonwall's standardized environment setup, comprehensive configuration management, and simple network interactions. +- Source (raw): https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/parachains-testing-fork-a-parachain.md +- Canonical (HTML): https://docs.polkadot.com/parachains/testing/fork-a-parachain/ +- Summary: Simplify Polkadot SDK development with Chopsticks. Learn essential features, how to install Chopsticks, and how to configure local blockchain forks. -# E2E Testing with Moonwall +# Fork a Parachain Using Chopsticks ## Introduction -Moonwall is an end-to-end testing framework designed explicitly for Polkadot SDK-based blockchain networks. It addresses one of the most significant challenges in blockchain development: managing complex test environments and network configurations. +[Chopsticks](https://github.com/AcalaNetwork/chopsticks/){target=\_blank}, developed by the [Acala Foundation](https://github.com/AcalaNetwork){target=\_blank}, is a versatile tool tailored for developers working on Polkadot SDK-based blockchains. With Chopsticks, you can fork live chains locally, replay blocks to analyze extrinsics, and simulate complex scenarios like XCM interactions all without deploying to a live network. -Moonwall consolidates this complexity by providing the following: +This guide walks you through installing Chopsticks and provides information on configuring a local blockchain fork. By streamlining testing and experimentation, Chopsticks empowers developers to innovate and accelerate their blockchain projects within the Polkadot ecosystem. -- A centralized configuration management system that explicitly defines all network parameters. -- A standardized approach to environment setup across different Substrate-based chains. -- Built-in utilities for common testing scenarios and network interactions. +For additional support and information, please reach out through [GitHub Issues](https://github.com/AcalaNetwork/chopsticks/issues){target=_blank}. -Developers can focus on writing meaningful tests rather than managing infrastructure complexities or searching through documentation for configuration options. +!!! warning + Chopsticks uses [Smoldot](https://github.com/smol-dot/smoldot){target=_blank} light client, which only supports the native Polkadot SDK API. Consequently, a Chopsticks-based fork doesn't support Ethereum JSON-RPC calls, meaning you cannot use it to fork your chain and connect Metamask. ## Prerequisites Before you begin, ensure you have the following installed: -- [Node.js](https://nodejs.org/en/){target=\_blank} (version 20.10 or higher). -- A package manager such as [npm](https://www.npmjs.com/){target=\_blank}, [yarn](https://yarnpkg.com/){target=\_blank}, or [pnpm](https://pnpm.io/){target=\_blank}. - -## Install Moonwall +- [Node.js](https://nodejs.org/en/){target=\_blank}. +- A package manager such as [npm](https://www.npmjs.com/){target=\_blank}, which should be installed with Node.js by default, or [Yarn](https://yarnpkg.com/){target=\_blank}. -Moonwall can be installed globally for system-wide access or locally within specific projects. This section covers both installation methods. +## Install Chopsticks -!!! tip - This documentation corresponds to Moonwall version `5.15.0`. To avoid compatibility issues with the documented features, ensure you're using the matching version. +You can install Chopsticks globally or locally in your project. Choose the option that best fits your development workflow. This documentation explains the features of Chopsticks version `1.2.2`. Make sure you're using the correct version to match these instructions. ### Global Installation -Global installation provides system-wide access to the Moonwall CLI, making it ideal for developers working across multiple blockchain projects. Install it by running one of the following commands: - -=== "npm" - - ```bash - npm install -g @moonwall/cli@5.15.0 - ``` - -=== "pnpm" - - ```bash - pnpm -g install @moonwall/cli@5.15.0 - ``` - -=== "yarn" +To install Chopsticks globally, allowing you to use it across multiple projects, run: - ```bash - yarn global add @moonwall/cli@5.15.0 - ``` +```bash +npm i -g @acala-network/chopsticks@1.2.2 +``` -Now, you can run the `moonwall` command from your terminal. +Now, you should be able to run the `chopsticks` command from your terminal. ### Local Installation -Local installation is recommended for better dependency management and version control within a specific project. First, initialize your project: +To use Chopsticks in a specific project, first create a new directory and initialize a Node.js project: ```bash -mkdir my-moonwall-project -cd my-moonwall-project +mkdir my-chopsticks-project +cd my-chopsticks-project npm init -y ``` -Then, install it as a local dependency: +Then, install Chopsticks as a local dependency: -=== "npm" +```bash +npm i @acala-network/chopsticks@1.2.2 +``` - ```bash - npm install @moonwall/cli@5.15.0 - ``` +Finally, you can run Chopsticks using the `npx` command. To see all available options and commands, run it with the `--help` flag: -=== "pnpm" +```bash +npx @acala-network/chopsticks --help +``` - ```bash - pnpm install @moonwall/cli@5.15.0 - ``` +## Configure Chopsticks -=== "yarn" +To run Chopsticks, you need to configure some parameters. This can be set either through using a configuration file or the command line interface (CLI). The parameters that can be configured are as follows: - ```bash - yarn add @moonwall/cli@5.15.0 - ``` +- **`genesis`**: The link to a parachain's raw genesis file to build the fork from, instead of an endpoint. +- **`timestamp`**: Timestamp of the block to fork from. +- **`endpoint`**: The endpoint of the parachain to fork. +- **`block`**: Use to specify at which block hash or number to replay the fork. +- **`wasm-override`**: Path of the Wasm to use as the parachain runtime, instead of an endpoint's runtime. +- **`db`**: Path to the name of the file that stores or will store the parachain's database. +- **`config`**: Path or URL of the config file. +- **`port`**: The port to expose an endpoint on. +- **`build-block-mode`**: How blocks should be built in the fork: batch, manual, instant. +- **`import-storage`**: A pre-defined JSON/YAML storage path to override in the parachain's storage. +- **`allow-unresolved-imports`**: Whether to allow Wasm unresolved imports when using a Wasm to build the parachain. +- **`html`**: Include to generate storage diff preview between blocks. +- **`mock-signature-host`**: Mock signature host so that any signature starts with `0xdeadbeef` and filled by `0xcd` is considered valid. -## Initialize Moonwall +### Configuration File -The `moonwall init` command launches an interactive wizard to create your configuration file: +The Chopsticks source repository includes a collection of [YAML](https://yaml.org/){target=\_blank} files that can be used to set up various Polkadot SDK chains locally. You can download these configuration files from the [repository's `configs` folder](https://github.com/AcalaNetwork/chopsticks/tree/master/configs){target=\_blank}. -```bash -moonwall init -``` +An example of a configuration file for Polkadot is as follows: -During setup, you will see prompts for the following parameters: +{% raw %} +```yaml +endpoint: + - wss://rpc.ibp.network/polkadot + - wss://polkadot-rpc.dwellir.com +mock-signature-host: true +block: ${env.POLKADOT_BLOCK_NUMBER} +db: ./db.sqlite +runtime-log-level: 5 -- **`label`**: Identifies your test configuration. -- **`global timeout`**: Maximum time (ms) for test execution. -- **`environment name`**: Name for your testing environment. -- **`network foundation`**: Type of blockchain environment to use. -- **`tests directory`**: Location of your test files. +import-storage: + System: + Account: + - - - 5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY + - providers: 1 + data: + free: '10000000000000000000' + ParasDisputes: + $removePrefix: ['disputes'] # those can makes block building super slow -Select `Enter` to accept defaults or input custom values. You should see something like this: +``` +{% endraw %} -
- moonwall init - ✔ Provide a label for the config file moonwall_config - ✔ Provide a global timeout value 30000 - ✔ Provide a name for this environment default_env - ✔ What type of network foundation is this? dev - ✔ Provide the path for where tests for this environment are kept tests/ - ? Would you like to generate this config? (no to restart from beginning) (Y/n) -
+The configuration file allows you to modify the storage of the forked network by rewriting the pallet, state component and value that you want to change. For example, Polkadot's file rewrites Alice's `system.Account` storage so that the free balance is set to `10000000000000000000`. -The wizard generates a `moonwall.config` file: +### CLI Flags -```json -{ - "label": "moonwall_config", - "defaultTestTimeout": 30000, - "environments": [ - { - "name": "default_env", - "testFileDir": ["tests/"], - "foundation": { - "type": "dev" - } - } - ] -} +Alternatively, all settings (except for genesis and timestamp) can be configured via command-line flags, providing a comprehensive method to set up the environment. -``` +## WebSocket Commands -The default configuration requires specific details about your blockchain node and test requirements: +Chopstick's internal WebSocket server has special endpoints that allow the manipulation of the local Polkadot SDK chain. -- The `foundation` object defines how your test blockchain node will be launched and managed. The dev foundation, which runs a local node binary, is used for local development. +These are the methods that can be invoked and their parameters: - For more information about available options, check the [Foundations](https://moonsong-labs.github.io/moonwall/guide/intro/foundations.html){target=\_blank} section. +- **dev_newBlock** (newBlockParams): Generates one or more new blocks. -- The `connections` array specifies how your tests will interact with the blockchain node. This typically includes provider configuration and endpoint details. + === "Parameters" - A provider is a tool that allows you or your application to connect to a blockchain network and simplifies the low-level details of the process. A provider handles submitting transactions, reading state, and more. For more information on available providers, check the [Providers supported](https://moonsong-labs.github.io/moonwall/guide/intro/providers.html#providers-supported){target=\_blank} page in the Moonwall documentation. - -Here's a complete configuration example for testing a local node using Polkadot.js as a provider: - -```json -{ - "label": "moonwall_config", - "defaultTestTimeout": 30000, - "environments": [ - { - "name": "default_env", - "testFileDir": ["tests/"], - "foundation": { - "launchSpec": [ - { - "binPath": "./node-template", - "newRpcBehaviour": true, - "ports": { "rpcPort": 9944 } - } - ], - "type": "dev" - }, - "connections": [ - { - "name": "myconnection", - "type": "polkadotJs", - "endpoints": ["ws://127.0.0.1:9944"] - } - ] - } - ] -} - -``` - -## Writing Tests - -Moonwall uses the [`describeSuite`](https://github.com/Moonsong-Labs/moonwall/blob/7568048c52e9f7844f38fb4796ae9e1b9205fdaa/packages/cli/src/lib/runnerContext.ts#L65){target=\_blank} function to define test suites, like using [Mocha](https://mochajs.org/){target=\_blank}. Each test suite requires the following: - -- **`id`**: Unique identifier for the suite. -- **`title`**: Descriptive name for the suite. -- **`foundationMethods`**: Specifies the testing environment (e.g., `dev` for local node testing). -- **`testCases`**: A callback function that houses the individual test cases of this suite. - -The following example shows how to test a balance transfer between two accounts: - -```ts -import '@polkadot/api-augment'; -import { describeSuite, expect } from '@moonwall/cli'; -import { Keyring } from '@polkadot/api'; - -describeSuite({ - id: 'D1', - title: 'Demo suite', - foundationMethods: 'dev', - testCases: ({ it, context, log }) => { - it({ - id: 'T1', - title: 'Test Case', - test: async () => { - // Set up polkadot.js API and testing accounts - let api = context.polkadotJs(); - let alice = new Keyring({ type: 'sr25519' }).addFromUri('//Alice'); - let charlie = new Keyring({ type: 'sr25519' }).addFromUri('//Charlie'); - - // Query Charlie's account balance before transfer - const balanceBefore = (await api.query.system.account(charlie.address)) - .data.free; - - // Before transfer, Charlie's account balance should be 0 - expect(balanceBefore.toString()).toEqual('0'); - log('Balance before: ' + balanceBefore.toString()); - - // Transfer from Alice to Charlie - const amount = 1000000000000000; - await api.tx.balances - .transferAllowDeath(charlie.address, amount) - .signAndSend(alice); - - // Wait for the transaction to be included in a block. - // This is necessary because the balance is not updated immediately. - // Block time is 6 seconds. - await new Promise((resolve) => setTimeout(resolve, 6000)); - - // Query Charlie's account balance after transfer - const balanceAfter = (await api.query.system.account(charlie.address)) - .data.free; - - // After transfer, Charlie's account balance should be 1000000000000000 - expect(balanceAfter.toString()).toEqual(amount.toString()); - log('Balance after: ' + balanceAfter.toString()); - }, - }); - }, -}); - -``` - -This test demonstrates several key concepts: - -- Initializing the Polkadot.js API through Moonwall's context and setting up test accounts. -- Querying on-chain state. -- Executing transactions. -- Waiting for block inclusion. -- Verifying results using assertions. - -## Running the Tests - -Execute your tests using the `test` Moonwall CLI command. For the default environment setup run: - -```bash -moonwall test default_env -c moonwall.config -``` - -The test runner will output detailed results showing: - -- Test suite execution status. -- Individual test case results. -- Execution time. -- Detailed logs and error messages (if any). - -Example output: -
- moonwall test default_env -c moonwall.config - stdout | tests/test1.ts > 🗃️ D1 Demo suite > 📁 D1T1 Test Case - 2025-01-21T19:27:55.624Z test:default_env Balance before: 0 - - stdout | tests/test1.ts > 🗃️ D1 Demo suite > 📁 D1T1 Test Case - 2025-01-21T19:28:01.637Z test:default_env Balance after: 1000000000000000 - - ✓ default_env tests/test1.ts (1 test) 6443ms - ✓ 🗃️ D1 Demo suite > 📁 D1T1 Test Case 6028ms - - Test Files 1 passed (1) - Tests 1 passed (1) - Start at 16:27:53 - Duration 7.95s (transform 72ms, setup 0ms, collect 1.31s, tests 6.44s, environment 0ms, prepare 46ms) - - ✅ All tests passed -
- -## Where to Go Next - -For a comprehensive guide to Moonwall's full capabilities, available configurations, and advanced usage, see the official [Moonwall](https://moonsong-labs.github.io/moonwall/){target=\_blank} documentation. - - ---- - -Page Title: Fork a Parachain Using Chopsticks - -- Source (raw): https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/parachains-testing-fork-a-parachain.md -- Canonical (HTML): https://docs.polkadot.com/parachains/testing/fork-a-parachain/ -- Summary: Simplify Polkadot SDK development with Chopsticks. Learn essential features, how to install Chopsticks, and how to configure local blockchain forks. - -# Fork a Parachain Using Chopsticks - -## Introduction - -[Chopsticks](https://github.com/AcalaNetwork/chopsticks/){target=\_blank}, developed by the [Acala Foundation](https://github.com/AcalaNetwork){target=\_blank}, is a versatile tool tailored for developers working on Polkadot SDK-based blockchains. With Chopsticks, you can fork live chains locally, replay blocks to analyze extrinsics, and simulate complex scenarios like XCM interactions all without deploying to a live network. - -This guide walks you through installing Chopsticks and provides information on configuring a local blockchain fork. By streamlining testing and experimentation, Chopsticks empowers developers to innovate and accelerate their blockchain projects within the Polkadot ecosystem. - -For additional support and information, please reach out through [GitHub Issues](https://github.com/AcalaNetwork/chopsticks/issues){target=_blank}. - -!!! warning - Chopsticks uses [Smoldot](https://github.com/smol-dot/smoldot){target=_blank} light client, which only supports the native Polkadot SDK API. Consequently, a Chopsticks-based fork doesn't support Ethereum JSON-RPC calls, meaning you cannot use it to fork your chain and connect Metamask. - -## Prerequisites - -Before you begin, ensure you have the following installed: - -- [Node.js](https://nodejs.org/en/){target=\_blank}. -- A package manager such as [npm](https://www.npmjs.com/){target=\_blank}, which should be installed with Node.js by default, or [Yarn](https://yarnpkg.com/){target=\_blank}. - -## Install Chopsticks - -You can install Chopsticks globally or locally in your project. Choose the option that best fits your development workflow. This documentation explains the features of Chopsticks version `1.2.2`. Make sure you're using the correct version to match these instructions. - -### Global Installation - -To install Chopsticks globally, allowing you to use it across multiple projects, run: - -```bash -npm i -g @acala-network/chopsticks@1.2.2 -``` - -Now, you should be able to run the `chopsticks` command from your terminal. - -### Local Installation - -To use Chopsticks in a specific project, first create a new directory and initialize a Node.js project: - -```bash -mkdir my-chopsticks-project -cd my-chopsticks-project -npm init -y -``` - -Then, install Chopsticks as a local dependency: - -```bash -npm i @acala-network/chopsticks@1.2.2 -``` - -Finally, you can run Chopsticks using the `npx` command. To see all available options and commands, run it with the `--help` flag: - -```bash -npx @acala-network/chopsticks --help -``` - -## Configure Chopsticks - -To run Chopsticks, you need to configure some parameters. This can be set either through using a configuration file or the command line interface (CLI). The parameters that can be configured are as follows: - -- **`genesis`**: The link to a parachain's raw genesis file to build the fork from, instead of an endpoint. -- **`timestamp`**: Timestamp of the block to fork from. -- **`endpoint`**: The endpoint of the parachain to fork. -- **`block`**: Use to specify at which block hash or number to replay the fork. -- **`wasm-override`**: Path of the Wasm to use as the parachain runtime, instead of an endpoint's runtime. -- **`db`**: Path to the name of the file that stores or will store the parachain's database. -- **`config`**: Path or URL of the config file. -- **`port`**: The port to expose an endpoint on. -- **`build-block-mode`**: How blocks should be built in the fork: batch, manual, instant. -- **`import-storage`**: A pre-defined JSON/YAML storage path to override in the parachain's storage. -- **`allow-unresolved-imports`**: Whether to allow Wasm unresolved imports when using a Wasm to build the parachain. -- **`html`**: Include to generate storage diff preview between blocks. -- **`mock-signature-host`**: Mock signature host so that any signature starts with `0xdeadbeef` and filled by `0xcd` is considered valid. - -### Configuration File - -The Chopsticks source repository includes a collection of [YAML](https://yaml.org/){target=\_blank} files that can be used to set up various Polkadot SDK chains locally. You can download these configuration files from the [repository's `configs` folder](https://github.com/AcalaNetwork/chopsticks/tree/master/configs){target=\_blank}. - -An example of a configuration file for Polkadot is as follows: - -{% raw %} -```yaml -endpoint: - - wss://rpc.ibp.network/polkadot - - wss://polkadot-rpc.dwellir.com -mock-signature-host: true -block: ${env.POLKADOT_BLOCK_NUMBER} -db: ./db.sqlite -runtime-log-level: 5 - -import-storage: - System: - Account: - - - - 5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY - - providers: 1 - data: - free: '10000000000000000000' - ParasDisputes: - $removePrefix: ['disputes'] # those can makes block building super slow - -``` -{% endraw %} - -The configuration file allows you to modify the storage of the forked network by rewriting the pallet, state component and value that you want to change. For example, Polkadot's file rewrites Alice's `system.Account` storage so that the free balance is set to `10000000000000000000`. - -### CLI Flags - -Alternatively, all settings (except for genesis and timestamp) can be configured via command-line flags, providing a comprehensive method to set up the environment. - -## WebSocket Commands - -Chopstick's internal WebSocket server has special endpoints that allow the manipulation of the local Polkadot SDK chain. - -These are the methods that can be invoked and their parameters: - -- **dev_newBlock** (newBlockParams): Generates one or more new blocks. - - === "Parameters" - - - **`newBlockParams` ++"NewBlockParams"++**: The parameters to build the new block with. Where the `NewBlockParams` interface includes the following properties. + - **`newBlockParams` ++"NewBlockParams"++**: The parameters to build the new block with. Where the `NewBlockParams` interface includes the following properties. - **`count` ++"number"++**: The number of blocks to build. - **`dmp` ++"{ msg: string, sentAt: number }[]"++**: The downward messages to include in the block. @@ -3936,497 +3211,129 @@ These functionalities empower developers to build innovative, multi-chain applic --- -Page Title: Glossary - -- Source (raw): https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/reference-glossary.md -- Canonical (HTML): https://docs.polkadot.com/reference/glossary/ -- Summary: Glossary of terms used within the Polkadot ecosystem, Polkadot SDK, its subsequent libraries, and other relevant Web3 terminology. - -# Glossary +Page Title: Indexers -Key definitions, concepts, and terminology specific to the Polkadot ecosystem are included here. +- Source (raw): https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/parachains-integrations-indexers.md +- Canonical (HTML): https://docs.polkadot.com/parachains/integrations/indexers/ +- Summary: Discover blockchain indexers. Enhance data access, enable fast and complex queries, and optimize blockchain data for seamless app performance. -Additional glossaries from around the ecosystem you might find helpful: +# Indexers -- [Polkadot Wiki Glossary](https://wiki.polkadot.com/general/glossary){target=\_blank} -- [Polkadot SDK Glossary](https://paritytech.github.io/polkadot-sdk/master/polkadot_sdk_docs/reference_docs/glossary/index.html){target=\_blank} +## The Challenge of Blockchain Data Access -## Authority +Blockchain data is inherently sequential and distributed, with information stored chronologically across numerous blocks. While retrieving data from a single block through JSON-RPC API calls is straightforward, more complex queries that span multiple blocks present significant challenges: -The role in a blockchain that can participate in consensus mechanisms. +- Data is scattered and unorganized across the blockchain. +- Retrieving large datasets can take days or weeks to sync. +- Complex operations (like aggregations, averages, or cross-chain queries) require additional processing. +- Direct blockchain queries can impact dApp performance and responsiveness. -- **[GRANDPA](#grandpa)**: The authorities vote on chains they consider final. -- **[Blind Assignment of Blockchain Extension](#blind-assignment-of-blockchain-extension-babe) (BABE)**: The authorities are also [block authors](#block-author). +## What is a Blockchain Indexer? -Authority sets can be used as a basis for consensus mechanisms such as the [Nominated Proof of Stake (NPoS)](#nominated-proof-of-stake-npos) protocol. +A blockchain indexer is a specialized infrastructure tool that processes, organizes, and stores blockchain data in an optimized format for efficient querying. Think of it as a search engine for blockchain data that: -## Authority Round (Aura) +- Continuously monitors the blockchain for new blocks and transactions. +- Processes and categorizes this data according to predefined schemas. +- Stores the processed data in an easily queryable database. +- Provides efficient APIs (typically [GraphQL](https://graphql.org/){target=\_blank}) for data retrieval. -A deterministic [consensus](#consensus) protocol where block production is limited to a rotating list of [authorities](#authority) that take turns creating blocks. In authority round (Aura) consensus, most online authorities are assumed to be honest. It is often used in combination with [GRANDPA](#grandpa) as a [hybrid consensus](#hybrid-consensus) protocol. +## Indexer Implementations -Learn more by reading the official [Aura consensus algorithm](https://openethereum.github.io/Aura){target=\_blank} wiki article. +
-## Blind Assignment of Blockchain Extension (BABE) +- __Subsquid__ -A [block authoring](#block-author) protocol similar to [Aura](#authority-round-aura), except [authorities](#authority) win [slots](#slot) based on a Verifiable Random Function (VRF) instead of the round-robin selection method. The winning authority can select a chain and submit a new block. + --- -Learn more by reading the official Web3 Foundation [BABE research document](https://research.web3.foundation/Polkadot/protocols/block-production/Babe){target=\_blank}. + Subsquid is a data network that allows rapid and cost-efficient retrieval of blockchain data from 100+ chains using Subsquid's decentralized data lake and open-source SDK. In simple terms, Subsquid can be considered an ETL (extract, transform, and load) tool with a GraphQL server included. It enables comprehensive filtering, pagination, and even full-text search capabilities. Subsquid has native and full support for EVM and Substrate data, even within the same project. -## Block Author + [:octicons-arrow-right-24: Reference](https://www.sqd.ai/){target=\_blank} -The node responsible for the creation of a block, also called _block producers_. In a Proof of Work (PoW) blockchain, these nodes are called _miners_. +- __Subquery__ -## Byzantine Fault Tolerance (BFT) + --- -The ability of a distributed computer network to remain operational if a certain proportion of its nodes or [authorities](#authority) are defective or behaving maliciously. A distributed network is typically considered Byzantine fault tolerant if it can remain functional, with up to one-third of nodes assumed to be defective, offline, actively malicious, and part of a coordinated attack. + SubQuery is a fast, flexible, and reliable open-source data decentralised infrastructure network that provides both RPC and indexed data to consumers worldwide. + It provides custom APIs for your web3 project across multiple supported chains. -### Byzantine Failure + [:octicons-arrow-right-24: Reference](https://subquery.network/){target=\_blank} -The loss of a network service due to node failures that exceed the proportion of nodes required to reach consensus. +
-### Practical Byzantine Fault Tolerance (pBFT) -An early approach to Byzantine fault tolerance (BFT), practical Byzantine fault tolerance (pBFT) systems tolerate Byzantine behavior from up to one-third of participants. +--- -The communication overhead for such systems is `O(n²)`, where `n` is the number of nodes (participants) in the system. +Page Title: Install Polkadot SDK -### Preimage +- Source (raw): https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/parachains-install-polkadot-sdk.md +- Canonical (HTML): https://docs.polkadot.com/parachains/install-polkadot-sdk/ +- Summary: Install all required Polkadot SDK dependencies, set up the SDK itself, and verify that it runs correctly on your machine. -A preimage is the data that is input into a hash function to calculate a hash. Since a hash function is a [one-way function](https://en.wikipedia.org/wiki/One-way_function){target=\_blank}, the output, the hash, cannot be used to reveal the input, the preimage. +# Install Polkadot SDK -## Call +This guide provides step-by-step instructions for installing the Polkadot SDK on macOS, Linux, and Windows. The installation process consists of two main parts: -In the context of pallets containing functions to be dispatched to the runtime, `Call` is an enumeration data type that describes the functions that can be dispatched with one variant per pallet. A `Call` represents a [dispatch](#dispatchable) data structure object. +- **Installing dependencies**: Setting up Rust, required system packages, and development tools. +- **Building the Polkadot SDK**: Cloning and compiling the Polkadot SDK repository. -## Chain Specification +Follow the appropriate section for your operating system to ensure all necessary tools are installed and configured properly. -A chain specification file defines the properties required to run a node in an active or new Polkadot SDK-built network. It often contains the initial genesis runtime code, network properties (such as the network's name), the initial state for some pallets, and the boot node list. The chain specification file makes it easy to use a single Polkadot SDK codebase as the foundation for multiple independently configured chains. +## Install Dependencies: macOS -## Collator +You can install Rust and set up a Substrate development environment on Apple macOS computers with Intel or Apple M1 processors. -An [author](#block-author) of a [parachain](#parachain) network. -They aren't [authorities](#authority) in themselves, as they require a [relay chain](#relay-chain) to coordinate [consensus](#consensus). +### Before You Begin {: #before-you-begin-mac-os } -More details are found on the [Polkadot Collator Wiki](https://wiki.polkadot.com/learn/learn-collator/){target=\_blank}. +Before you install Rust and set up your development environment on macOS, verify that your computer meets the following basic requirements: -## Collective +- Operating system version is 10.7 Lion or later. +- Processor speed of at least 2 GHz. Note that 3 GHz is recommended. +- Memory of at least 8 GB RAM. Note that 16 GB is recommended. +- Storage of at least 10 GB of available space. +- Broadband Internet connection. -Most often used to refer to an instance of the Collective pallet on Polkadot SDK-based networks such as [Kusama](#kusama) or [Polkadot](#polkadot) if the Collective pallet is part of the FRAME-based runtime for the network. +### Install Homebrew -## Consensus +In most cases, you should use Homebrew to install and manage packages on macOS computers. If you don't already have Homebrew installed on your local computer, you should download and install it before continuing. -Consensus is the process blockchain nodes use to agree on a chain's canonical fork. It is composed of [authorship](#block-author), finality, and [fork-choice rule](#fork-choice-rulestrategy). In the Polkadot ecosystem, these three components are usually separate and the term consensus often refers specifically to authorship. +To install Homebrew: -See also [hybrid consensus](#hybrid-consensus). +1. Open the Terminal application. +2. Download and install Homebrew by running the following command: -## Consensus Algorithm + ```bash + /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install.sh)" + ``` -Ensures a set of [actors](#authority)—who don't necessarily trust each other—can reach an agreement about the state as the result of some computation. Most consensus algorithms assume that up to one-third of the actors or nodes can be [Byzantine fault tolerant](#byzantine-fault-tolerance-bft). +3. Verify Homebrew has been successfully installed by running the following command: -Consensus algorithms are generally concerned with ensuring two properties: + ```bash + brew --version + ``` -- **Safety**: Indicating that all honest nodes eventually agreed on the state of the chain. -- **Liveness**: Indicating the ability of the chain to keep progressing. + The command displays output similar to the following: -## Consensus Engine +
+ brew --version + Homebrew 4.3.15 +
-The node subsystem responsible for consensus tasks. +### Support for Apple Silicon -For detailed information about the consensus strategies of the [Polkadot](#polkadot) network, see the [Polkadot Consensus](/reference/polkadot-hub/consensus-and-security/pos-consensus/){target=\_blank} blog series. +Protobuf must be installed before the build process can begin. To install it, run the following command: -See also [hybrid consensus](#hybrid-consensus). +```bash +brew install protobuf +``` -## Coretime +### Install Required Packages and Rust {: #install-required-packages-and-rust-mac-os } -The time allocated for utilizing a core, measured in relay chain blocks. There are two types of coretime: *on-demand* and *bulk*. +Because the blockchain requires standard cryptography to support the generation of public/private key pairs and the validation of transaction signatures, you must also have a package that provides cryptography, such as `openssl`. -On-demand coretime refers to coretime acquired through bidding in near real-time for the validation of a single parachain block on one of the cores reserved specifically for on-demand orders. They are available as an on-demand coretime pool. Set of cores that are available on-demand. Cores reserved through bulk coretime could also be made available in the on-demand coretime pool, in parts or in entirety. +To install `openssl` and the Rust toolchain on macOS: -Bulk coretime is a fixed duration of continuous coretime represented by an NFT that can be split, shared, or resold. It is managed by the [Broker pallet](https://paritytech.github.io/polkadot-sdk/master/pallet_broker/index.html){target=\_blank}. - -## Development Phrase - -A [mnemonic phrase](https://en.wikipedia.org/wiki/Mnemonic#For_numerical_sequences_and_mathematical_operations){target=\_blank} that is intentionally made public. - -Well-known development accounts, such as Alice, Bob, Charlie, Dave, Eve, and Ferdie, are generated from the same secret phrase: - -``` -bottom drive obey lake curtain smoke basket hold race lonely fit walk -``` - -Many tools in the Polkadot SDK ecosystem, such as [`subkey`](https://github.com/paritytech/polkadot-sdk/tree/polkadot-stable2506-2/substrate/bin/utils/subkey){target=\_blank}, allow you to implicitly specify an account using a derivation path such as `//Alice`. - -## Digest - -An extensible field of the [block header](#header) that encodes information needed by several actors in a blockchain network, including: - -- [Light clients](#light-client) for chain synchronization. -- Consensus engines for block verification. -- The runtime itself, in the case of pre-runtime digests. - -## Dispatchable - -Function objects that act as the entry points in FRAME [pallets](#pallet). Internal or external entities can call them to interact with the blockchain’s state. They are a core aspect of the runtime logic, handling [transactions](#transaction) and other state-changing operations. - -## Events - -A means of recording that some particular [state](#state) transition happened. - -In the context of [FRAME](#frame-framework-for-runtime-aggregation-of-modularized-entities), events are composable data types that each [pallet](#pallet) can individually define. Events in FRAME are implemented as a set of transient storage items inspected immediately after a block has been executed and reset during block initialization. - -## Executor - -A means of executing a function call in a given [runtime](#runtime) with a set of dependencies. -There are two orchestration engines in Polkadot SDK, _WebAssembly_ and _native_. - -- The _native executor_ uses a natively compiled runtime embedded in the node to execute calls. This is a performance optimization available to up-to-date nodes. - -- The _WebAssembly executor_ uses a [Wasm](#webassembly-wasm) binary and a Wasm interpreter to execute calls. The binary is guaranteed to be up-to-date regardless of the version of the blockchain node because it is persisted in the [state](#state) of the Polkadot SDK-based chain. - -## Existential Deposit - -The minimum balance an account is allowed to have in the [Balances pallet](https://paritytech.github.io/polkadot-sdk/master/pallet_balances/index.html){target=\_blank}. Accounts cannot be created with a balance less than the existential deposit amount. - -If an account balance drops below this amount, the Balances pallet uses [a FRAME System API](https://paritytech.github.io/substrate/master/frame_system/pallet/struct.Pallet.html#method.dec_ref){target=\_blank} to drop its references to that account. - -If the Balances pallet reference to an account is dropped, the account can be [reaped](https://paritytech.github.io/substrate/master/frame_system/pallet/struct.Pallet.html#method.allow_death){target=\_blank}. - -## Extrinsic - -A general term for data that originates outside the runtime, is included in a block, and leads to some action. This includes user-initiated transactions and inherent transactions placed into the block by the block builder. - -It is a SCALE-encoded array typically consisting of a version number, signature, and varying data types indicating the resulting runtime function to be called. Extrinsics can take two forms: [inherents](#inherent-transactions) and [transactions](#transaction). - -For more technical details, see the [Polkadot spec](https://spec.polkadot.network/id-extrinsics){target=\_blank}. - -## Fork Choice Rule/Strategy - -A fork choice rule or strategy helps determine which chain is valid when reconciling several network forks. A common fork choice rule is the [longest chain](https://paritytech.github.io/polkadot-sdk/master/sc_consensus/struct.LongestChain.html){target=\_blank}, in which the chain with the most blocks is selected. - -## FRAME (Framework for Runtime Aggregation of Modularized Entities) - -Enables developers to create blockchain [runtime](#runtime) environments from a modular set of components called [pallets](#pallet). It utilizes a set of procedural macros to construct runtimes. - -[Visit the Polkadot SDK docs for more details on FRAME.](https://paritytech.github.io/polkadot-sdk/master/polkadot_sdk_docs/polkadot_sdk/frame_runtime/index.html){target=\_blank} - -## Full Node - -A node that prunes historical states, keeping only recently finalized block states to reduce storage needs. Full nodes provide current chain state access and allow direct submission and validation of [extrinsics](#extrinsic), maintaining network decentralization. - -## Genesis Configuration - -A mechanism for specifying the initial state of a blockchain. By convention, this initial state or first block is commonly referred to as the genesis state or genesis block. The genesis configuration for Polkadot SDK-based chains is accomplished by way of a [chain specification](#chain-specification) file. - -## GRANDPA - -A deterministic finality mechanism for blockchains that is implemented in the [Rust](https://www.rust-lang.org/){target=\_blank} programming language. - -The [formal specification](https://github.com/w3f/consensus/blob/master/pdf/grandpa-old.pdf){target=\_blank} is maintained by the [Web3 Foundation](https://web3.foundation/){target=\_blank}. - -## Header - -A structure that aggregates the information used to summarize a block. Primarily, it consists of cryptographic information used by [light clients](#light-client) to get minimally secure but very efficient chain synchronization. - -## Hybrid Consensus - -A blockchain consensus protocol that consists of independent or loosely coupled mechanisms for [block production](#block-author) and finality. - -Hybrid consensus allows the chain to grow as fast as probabilistic consensus protocols, such as [Aura](#authority-round-aura), while maintaining the same level of security as deterministic finality consensus protocols, such as [GRANDPA](#grandpa). - -## Inherent Transactions - -A special type of unsigned transaction, referred to as _inherents_, that enables a block authoring node to insert information that doesn't require validation directly into a block. - -Only the block-authoring node that calls the inherent transaction function can insert data into its block. In general, validators assume the data inserted using an inherent transaction is valid and reasonable even if it can't be deterministically verified. - -## JSON-RPC - -A stateless, lightweight remote procedure call protocol encoded in JavaScript Object Notation (JSON). JSON-RPC provides a standard way to call functions on a remote system by using JSON. - -For Polkadot SDK, this protocol is implemented through the [Parity JSON-RPC](https://github.com/paritytech/jsonrpc){target=\_blank} crate. - -## Keystore - -A subsystem for managing keys for the purpose of producing new blocks. - -## Kusama - -[Kusama](https://kusama.network/){target=\_blank} is a Polkadot SDK-based blockchain that implements a design similar to the [Polkadot](#polkadot) network. - -Kusama is a [canary](https://en.wiktionary.org/wiki/canary_in_a_coal_mine){target=\_blank} network and is referred to as [Polkadot's "wild cousin."](https://wiki.polkadot.com/learn/learn-comparisons-kusama/){target=\_blank}. - -As a canary network, Kusama is expected to be more stable than a test network like [Westend](#westend) but less stable than a production network like [Polkadot](#polkadot). Kusama is controlled by its network participants and is intended to be stable enough to encourage meaningful experimentation. - -## libp2p - -A peer-to-peer networking stack that allows the use of many transport mechanisms, including WebSockets (usable in a web browser). - -Polkadot SDK uses the [Rust implementation](https://github.com/libp2p/rust-libp2p){target=\_blank} of the `libp2p` networking stack. - -## Light Client - -A type of blockchain node that doesn't store the [chain state](#state) or produce blocks. - -A light client can verify cryptographic primitives and provides a [remote procedure call (RPC)](https://en.wikipedia.org/wiki/Remote_procedure_call){target=\_blank} server, enabling blockchain users to interact with the network. - -## Metadata - -Data that provides information about one or more aspects of a system. -The metadata that exposes information about a Polkadot SDK blockchain enables you to interact with that system. - -## Nominated Proof of Stake (NPoS) - -A method for determining [validators](#validator) or _[authorities](#authority)_ based on a willingness to commit their stake to the proper functioning of one or more block-producing nodes. - -## Oracle - -An entity that connects a blockchain to a non-blockchain data source. Oracles enable the blockchain to access and act upon information from existing data sources and incorporate data from non-blockchain systems and services. - -## Origin - -A [FRAME](#frame-framework-for-runtime-aggregation-of-modularized-entities) primitive that identifies the source of a [dispatched](#dispatchable) function call into the [runtime](#runtime). The FRAME System pallet defines three built-in [origins](#origin). As a [pallet](#pallet) developer, you can also define custom origins, such as those defined by the [Collective pallet](https://paritytech.github.io/substrate/master/pallet_collective/enum.RawOrigin.html){target=\_blank}. - -## Pallet - -A module that can be used to extend the capabilities of a [FRAME](#frame-framework-for-runtime-aggregation-of-modularized-entities)-based [runtime](#runtime). -Pallets bundle domain-specific logic with runtime primitives like [events](#events) and [storage items](#storage-item). - -## Parachain - -A parachain is a blockchain that derives shared infrastructure and security from a _[relay chain](#relay-chain)_. -You can learn more about parachains on the [Polkadot Wiki](https://wiki.polkadot.com/learn/learn-parachains/){target=\_blank}. - -## Paseo - -Paseo TestNet provisions testing on Polkadot's "production" runtime, which means less chance of feature or code mismatch when developing parachain apps. Specifically, after the [Polkadot Technical fellowship](https://wiki.polkadot.com/learn/learn-polkadot-technical-fellowship/){target=\_blank} proposes a runtime upgrade for Polkadot, this TestNet is updated, giving a period where the TestNet will be ahead of Polkadot to allow for testing. - -## Polkadot - -The [Polkadot network](https://polkadot.com/){target=\_blank} is a blockchain that serves as the central hub of a heterogeneous blockchain network. It serves the role of the [relay chain](#relay-chain) and provides shared infrastructure and security to support [parachains](#parachain). - -## Polkadot Cloud - -Polkadot Cloud is a platform for deploying resilient, customizable and scalable Web3 applications through Polkadot's functionality. It encompasses the wider Polkadot network infrastructure and security layer where parachains operate. The platform enables users to launch Ethereum-compatible chains, build specialized blockchains, and flexibly manage computing resources through on-demand or bulk coretime purchases. Initially launched with basic parachain functionality, Polkadot Cloud has evolved to offer enhanced flexibility with features like coretime, elastic scaling, and async backing for improved performance. - -## Polkadot Hub - -Polkadot Hub is a Layer 1 platform that serves as the primary entry point to the Polkadot ecosystem, providing essential functionality without requiring parachain deployment. It offers core services including smart contracts, identity management, staking, governance, and interoperability with other ecosystems, making it simple and fast for both builders and users to get started in Web3. - -## PolkaVM - -PolkaVM is a custom virtual machine optimized for performance, leveraging a RISC-V-based architecture to support Solidity and any language that compiles to RISC-V. It is specifically designed for the Polkadot ecosystem, enabling smart contract deployment and execution. - -## Relay Chain - -Relay chains are blockchains that provide shared infrastructure and security to the [parachains](#parachain) in the network. In addition to providing [consensus](#consensus) capabilities, relay chains allow parachains to communicate and exchange digital assets without needing to trust one another. - -## Rococo - -A [parachain](#parachain) test network for the Polkadot network. The [Rococo](#rococo) network is a Polkadot SDK-based blockchain with an October 14, 2024 deprecation date. Development teams are encouraged to use the Paseo TestNet instead. - -## Runtime - -The runtime represents the [state transition function](#state-transition-function-stf) for a blockchain. In Polkadot SDK, the runtime is stored as a [Wasm](#webassembly-wasm) binary in the chain state. The Runtime is stored under a unique state key and can be modified during the execution of the state transition function. - -## Slot - -A fixed, equal interval of time used by consensus engines such as [Aura](#authority-round-aura) and [BABE](#blind-assignment-of-blockchain-extension-babe). In each slot, a subset of [authorities](#authority) is permitted, or obliged, to [author](#block-author) a block. - -## Sovereign Account - -The unique account identifier for each chain in the relay chain ecosystem. It is often used in cross-consensus (XCM) interactions to sign XCM messages sent to the relay chain or other chains in the ecosystem. - -The sovereign account for each chain is a root-level account that can only be accessed using the Sudo pallet or through governance. The account identifier is calculated by concatenating the Blake2 hash of a specific text string and the registered parachain identifier. - -## SS58 Address Format - -A public key address based on the Bitcoin [`Base-58-check`](https://en.bitcoin.it/wiki/Base58Check_encoding){target=\_blank} encoding. Each Polkadot SDK SS58 address uses a `base-58` encoded value to identify a specific account on a specific Polkadot SDK-based chain - -The [canonical `ss58-registry`](https://github.com/paritytech/ss58-registry){target=\_blank} provides additional details about the address format used by different Polkadot SDK-based chains, including the network prefix and website used for different networks - -## State Transition Function (STF) - -The logic of a blockchain that determines how the state changes when a block is processed. In Polkadot SDK, the state transition function is effectively equivalent to the [runtime](#runtime). - -## Storage Item - -[FRAME](#frame-framework-for-runtime-aggregation-of-modularized-entities) primitives that provide type-safe data persistence capabilities to the [runtime](#runtime). -Learn more in the [storage items](https://paritytech.github.io/polkadot-sdk/master/frame_support/storage/types/index.html){target=\_blank} reference document in the Polkadot SDK. - -## Substrate - -A flexible framework for building modular, efficient, and upgradeable blockchains. Substrate is written in the [Rust](https://www.rust-lang.org/){target=\_blank} programming language and is maintained by [Parity Technologies](https://www.parity.io/){target=\_blank}. - -## Transaction - -An [extrinsic](#extrinsic) that includes a signature that can be used to verify the account authorizing it inherently or via [signed extensions](https://paritytech.github.io/polkadot-sdk/master/polkadot_sdk_docs/reference_docs/signed_extensions/index.html){target=\_blank}. - -## Transaction Era - -A definable period expressed as a range of block numbers during which a transaction can be included in a block. -Transaction eras are used to protect against transaction replay attacks if an account is reaped and its replay-protecting nonce is reset to zero. - -## Trie (Patricia Merkle Tree) - -A data structure used to represent sets of key-value pairs and enables the items in the data set to be stored and retrieved using a cryptographic hash. Because incremental changes to the data set result in a new hash, retrieving data is efficient even if the data set is very large. With this data structure, you can also prove whether the data set includes any particular key-value pair without access to the entire data set. - -In Polkadot SDK-based blockchains, state is stored in a trie data structure that supports the efficient creation of incremental digests. This trie is exposed to the [runtime](#runtime) as [a simple key/value map](#storage-item) where both keys and values can be arbitrary byte arrays. - -## Validator - -A validator is a node that participates in the consensus mechanism of the network. Its roles include block production, transaction validation, network integrity, and security maintenance. - -## WebAssembly (Wasm) - -An execution architecture that allows for the efficient, platform-neutral expression of -deterministic, machine-executable logic. - -[Wasm](https://webassembly.org/){target=\_blank} can be compiled from many languages, including -the [Rust](https://www.rust-lang.org/){target=\_blank} programming language. Polkadot SDK-based chains use a Wasm binary to provide portable [runtimes](#runtime) that can be included as part of the chain's state. - -## Weight - -A convention used in Polkadot SDK-based blockchains to measure and manage the time it takes to validate a block. -Polkadot SDK defines one unit of weight as one picosecond of execution time on reference hardware. - -The maximum block weight should be equivalent to one-third of the target block time with an allocation of one-third each for: - -- Block construction -- Network propagation -- Import and verification - -By defining weights, you can trade-off the number of transactions per second and the hardware required to maintain the target block time appropriate for your use case. Weights are defined in the runtime, meaning you can tune them using runtime updates to keep up with hardware and software improvements. - -## Westend - -Westend is a Parity-maintained, Polkadot SDK-based blockchain that serves as a test network for the [Polkadot](#polkadot) network. - - ---- - -Page Title: Indexers - -- Source (raw): https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/parachains-integrations-indexers.md -- Canonical (HTML): https://docs.polkadot.com/parachains/integrations/indexers/ -- Summary: Discover blockchain indexers. Enhance data access, enable fast and complex queries, and optimize blockchain data for seamless app performance. - -# Indexers - -## The Challenge of Blockchain Data Access - -Blockchain data is inherently sequential and distributed, with information stored chronologically across numerous blocks. While retrieving data from a single block through JSON-RPC API calls is straightforward, more complex queries that span multiple blocks present significant challenges: - -- Data is scattered and unorganized across the blockchain. -- Retrieving large datasets can take days or weeks to sync. -- Complex operations (like aggregations, averages, or cross-chain queries) require additional processing. -- Direct blockchain queries can impact dApp performance and responsiveness. - -## What is a Blockchain Indexer? - -A blockchain indexer is a specialized infrastructure tool that processes, organizes, and stores blockchain data in an optimized format for efficient querying. Think of it as a search engine for blockchain data that: - -- Continuously monitors the blockchain for new blocks and transactions. -- Processes and categorizes this data according to predefined schemas. -- Stores the processed data in an easily queryable database. -- Provides efficient APIs (typically [GraphQL](https://graphql.org/){target=\_blank}) for data retrieval. - -## Indexer Implementations - -
- -- __Subsquid__ - - --- - - Subsquid is a data network that allows rapid and cost-efficient retrieval of blockchain data from 100+ chains using Subsquid's decentralized data lake and open-source SDK. In simple terms, Subsquid can be considered an ETL (extract, transform, and load) tool with a GraphQL server included. It enables comprehensive filtering, pagination, and even full-text search capabilities. Subsquid has native and full support for EVM and Substrate data, even within the same project. - - [:octicons-arrow-right-24: Reference](https://www.sqd.ai/){target=\_blank} - -- __Subquery__ - - --- - - SubQuery is a fast, flexible, and reliable open-source data decentralised infrastructure network that provides both RPC and indexed data to consumers worldwide. - It provides custom APIs for your web3 project across multiple supported chains. - - [:octicons-arrow-right-24: Reference](https://subquery.network/){target=\_blank} - -
- - ---- - -Page Title: Install Polkadot SDK - -- Source (raw): https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/parachains-install-polkadot-sdk.md -- Canonical (HTML): https://docs.polkadot.com/parachains/install-polkadot-sdk/ -- Summary: Install all required Polkadot SDK dependencies, set up the SDK itself, and verify that it runs correctly on your machine. - -# Install Polkadot SDK - -This guide provides step-by-step instructions for installing the Polkadot SDK on macOS, Linux, and Windows. The installation process consists of two main parts: - -- **Installing dependencies**: Setting up Rust, required system packages, and development tools. -- **Building the Polkadot SDK**: Cloning and compiling the Polkadot SDK repository. - -Follow the appropriate section for your operating system to ensure all necessary tools are installed and configured properly. - -## Install Dependencies: macOS - -You can install Rust and set up a Substrate development environment on Apple macOS computers with Intel or Apple M1 processors. - -### Before You Begin {: #before-you-begin-mac-os } - -Before you install Rust and set up your development environment on macOS, verify that your computer meets the following basic requirements: - -- Operating system version is 10.7 Lion or later. -- Processor speed of at least 2 GHz. Note that 3 GHz is recommended. -- Memory of at least 8 GB RAM. Note that 16 GB is recommended. -- Storage of at least 10 GB of available space. -- Broadband Internet connection. - -### Install Homebrew - -In most cases, you should use Homebrew to install and manage packages on macOS computers. If you don't already have Homebrew installed on your local computer, you should download and install it before continuing. - -To install Homebrew: - -1. Open the Terminal application. -2. Download and install Homebrew by running the following command: - - ```bash - /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install.sh)" - ``` - -3. Verify Homebrew has been successfully installed by running the following command: - - ```bash - brew --version - ``` - - The command displays output similar to the following: - -
- brew --version - Homebrew 4.3.15 -
- -### Support for Apple Silicon - -Protobuf must be installed before the build process can begin. To install it, run the following command: - -```bash -brew install protobuf -``` - -### Install Required Packages and Rust {: #install-required-packages-and-rust-mac-os } - -Because the blockchain requires standard cryptography to support the generation of public/private key pairs and the validation of transaction signatures, you must also have a package that provides cryptography, such as `openssl`. - -To install `openssl` and the Rust toolchain on macOS: - -1. Open the Terminal application. -2. Ensure you have an updated version of Homebrew by running the following command: +1. Open the Terminal application. +2. Ensure you have an updated version of Homebrew by running the following command: ```bash brew update @@ -4778,87 +3685,17 @@ To stop the node, press `Control-C` in the terminal. --- -Page Title: Interoperability +Page Title: JSON-RPC APIs -- Source (raw): https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/reference-parachains-interoperability.md -- Canonical (HTML): https://docs.polkadot.com/reference/parachains/interoperability/ -- Summary: Explore the importance of interoperability in the Polkadot ecosystem, covering XCM, bridges, and cross-chain communication. +- Source (raw): https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/smart-contracts-for-eth-devs-json-rpc-apis.md +- Canonical (HTML): https://docs.polkadot.com/smart-contracts/for-eth-devs/json-rpc-apis/ +- Summary: JSON-RPC APIs guide for Polkadot Hub, covering supported methods, parameters, and examples for interacting with the chain. -# Interoperability +# JSON-RPC APIs ## Introduction -Interoperability lies at the heart of the Polkadot ecosystem, enabling communication and collaboration across a diverse range of blockchains. By bridging the gaps between parachains, relay chains, and even external networks, Polkadot unlocks the potential for truly decentralized applications, efficient resource sharing, and scalable solutions. - -Polkadot’s design ensures that blockchains can transcend their individual limitations by working together as part of a unified system. This cooperative architecture is what sets Polkadot apart in the blockchain landscape. - -## Why Interoperability Matters - -The blockchain ecosystem is inherently fragmented. Different blockchains excel in specialized domains such as finance, gaming, or supply chain management, but these chains function in isolation without interoperability. This lack of connectivity stifles the broader utility of blockchain technology. - -Interoperability solves this problem by enabling blockchains to: - -- **Collaborate across networks**: Chains can interact to share assets, functionality, and data, creating synergies that amplify their individual strengths. -- **Achieve greater scalability**: Specialized chains can offload tasks to others, optimizing performance and resource utilization. -- **Expand use-case potential**: Cross-chain applications can leverage features from multiple blockchains, unlocking novel user experiences and solutions. - -In the Polkadot ecosystem, interoperability transforms a collection of isolated chains into a cohesive, efficient network, pushing the boundaries of what blockchains can achieve together. - -## Key Mechanisms for Interoperability - -At the core of Polkadot's cross-chain collaboration are foundational technologies designed to break down barriers between networks. These mechanisms empower blockchains to communicate, share resources, and operate as a cohesive ecosystem. - -### Cross-Consensus Messaging (XCM): The Backbone of Communication - -Polkadot's Cross-Consensus Messaging (XCM) is the standard framework for interaction between parachains, relay chains, and, eventually, external blockchains. XCM provides a trustless, secure messaging format for exchanging assets, sharing data, and executing cross-chain operations. - -Through XCM, decentralized applications can: - -- Transfer tokens and other assets across chains. -- Coordinate complex workflows that span multiple blockchains. -- Enable seamless user experiences where underlying blockchain differences are invisible. -- XCM exemplifies Polkadot’s commitment to creating a robust and interoperable ecosystem. - -For further information about XCM, check the [Get Started with XCM](/parachains/interoperability/get-started/){target=\_blank} article. - -### Bridges: Connecting External Networks - -While XCM enables interoperability within the Polkadot ecosystem, bridges extend this functionality to external blockchains such as Ethereum and Bitcoin. By connecting these networks, bridges allow Polkadot-based chains to access external liquidity, additional functionalities, and broader user bases. - -With bridges, developers and users gain the ability to: - -- Integrate external assets into Polkadot-based applications. -- Combine the strengths of Polkadot’s scalability with the liquidity of other networks. -- Facilitate accurate multi-chain applications that transcend ecosystem boundaries. - -For more information about bridges in the Polkadot ecosystem, see the [Bridge Hub](/reference/polkadot-hub/bridging/){target=\_blank} guide. - -## The Polkadot Advantage - -Polkadot was purpose-built for interoperability. Unlike networks that add interoperability as an afterthought, Polkadot integrates it as a fundamental design principle. This approach offers several distinct advantages: - -- **Developer empowerment**: Polkadot’s interoperability tools allow developers to build applications that leverage multiple chains’ capabilities without added complexity. -- **Enhanced ecosystem collaboration**: Chains in Polkadot can focus on their unique strengths while contributing to the ecosystem’s overall growth. -- **Future-proofing blockchain**: By enabling seamless communication, Polkadot ensures its ecosystem can adapt to evolving demands and technologies. - -## Looking Ahead - -Polkadot’s vision of interoperability extends beyond technical functionality, representing a shift towards a more collaborative blockchain landscape. By enabling chains to work together, Polkadot fosters innovation, efficiency, and accessibility, paving the way for a decentralized future where blockchains are not isolated competitors but interconnected collaborators. - - ---- - -Page Title: JSON-RPC APIs - -- Source (raw): https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/smart-contracts-for-eth-devs-json-rpc-apis.md -- Canonical (HTML): https://docs.polkadot.com/smart-contracts/for-eth-devs/json-rpc-apis/ -- Summary: JSON-RPC APIs guide for Polkadot Hub, covering supported methods, parameters, and examples for interacting with the chain. - -# JSON-RPC APIs - -## Introduction - -Polkadot Hub provides Ethereum compatibility through its JSON-RPC interface, allowing developers to interact with the chain using familiar Ethereum tooling and methods. This document outlines the supported [Ethereum JSON-RPC methods](https://ethereum.org/developers/docs/apis/json-rpc/#json-rpc-methods){target=\_blank} and provides examples of how to use them. +Polkadot Hub provides Ethereum compatibility through its JSON-RPC interface, allowing developers to interact with the chain using familiar Ethereum tooling and methods. This document outlines the supported [Ethereum JSON-RPC methods](https://ethereum.org/developers/docs/apis/json-rpc/#json-rpc-methods){target=\_blank} and provides examples of how to use them. This guide uses the Polkadot Hub TestNet endpoint: @@ -5715,384 +4552,6 @@ If an error occurs, the response will include an error object: ``` ---- - -Page Title: Light Clients - -- Source (raw): https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/reference-tools-light-clients.md -- Canonical (HTML): https://docs.polkadot.com/reference/tools/light-clients/ -- Summary: Light clients enable secure and efficient blockchain interaction without running a full node. Learn everything you need to know about light clients on Polkadot. - -# Light Clients - -## Introduction - -Light clients enable secure and efficient blockchain interaction without running a full node. They provide a trust-minimized alternative to JSON-RPC by verifying data through cryptographic proofs rather than blindly trusting remote nodes. - -This guide covers: - -- What light clients are and how they work. -- Their advantages compared to full nodes and JSON-RPC. -- Available implementations in the Polkadot ecosystem. -- How to use light clients in your applications. - -Light clients are particularly valuable for resource-constrained environments and applications requiring secure, decentralized blockchain access without the overhead of maintaining full nodes. - -!!!note "Light node or light client?" - The terms _light node_ and _light client_ are interchangeable. Both refer to a blockchain client that syncs without downloading the entire blockchain state. All nodes in a blockchain network are fundamentally clients, engaging in peer-to-peer communication. - -## Light Clients Workflow - -Unlike JSON-RPC interfaces, where an application must maintain a list of providers or rely on a single node, light clients are not limited to or dependent on a single node. They use cryptographic proofs to verify the blockchain's state, ensuring it is up-to-date and accurate. By verifying only block headers, light clients avoid syncing the entire state, making them ideal for resource-constrained environments. - -```mermaid -flowchart LR -DAPP([dApp])-- Query Account Info -->LC([Light Client]) -LC -- Request --> FN(((Full Node))) -LC -- Response --> DAPP -FN -- Response (validated via Merkle proof) --> LC -``` - -In the diagram above, the decentralized application queries on-chain account information through the light client. The light client runs as part of the application and requires minimal memory and computational resources. It uses Merkle proofs to verify the state retrieved from a full node in a trust-minimized manner. Polkadot-compatible light clients utilize [warp syncing](https://spec.polkadot.network/sect-lightclient#sect-sync-warp-lightclient){target=\_blank}, which downloads only block headers. - -Light clients can quickly verify the blockchain's state, including [GRANDPA finality](/polkadot-protocol/glossary#grandpa){target=\_blank} justifications. - -!!!note "What does it mean to be trust-minimized?" - _Trust-minimized_ means that the light client does not need to fully trust the full node from which it retrieves the state. This is achieved through the use of Merkle proofs, which allow the light client to verify the correctness of the state by checking the Merkle tree root. - -## JSON-RPC and Light Client Comparison - -Another common method of communication between a user interface (UI) and a node is through the JSON-RPC protocol. Generally, the UI retrieves information from the node, fetches network or [pallet](/polkadot-protocol/glossary#pallet){target=\_blank} data, and interacts with the blockchain. This is typically done in one of two ways: - -- **User-controlled nodes**: The UI connects to a node client installed on the user's machine. - - These nodes are secure, but installation and maintenance can be inconvenient. -- **Publicly accessible nodes**: The UI connects to a third-party-owned publicly accessible node client. - - These nodes are convenient but centralized and less secure. Applications must maintain a list of backup nodes in case the primary node becomes unavailable. - -While light clients still communicate with [full nodes](/polkadot-protocol/glossary#full-node), they offer significant advantages for applications requiring a secure alternative to running a full node: - -| Full Node | Light Client | -| :---------------------------------------------------------------------------------------------: | :------------------------------------------------------------: | -| Fully verifies all blocks of the chain | Verifies only the authenticity of blocks | -| Stores previous block data and the chain's storage in a database | Does not require a database | -| Installation, maintenance, and execution are resource-intensive and require technical expertise | No installation is typically included as part of the application | - -## Using Light Clients - -The [`smoldot`](https://github.com/smol-dot/smoldot){target=\_blank} client is the cornerstone of light client implementation for Polkadot SDK-based chains. It provides the primitives needed to build light clients and is also integrated into libraries such as [PAPI](#papi-light-client-support). - -### PAPI Light Client Support - -The [Polkadot API (PAPI)](/develop/toolkit/api-libraries/papi){target=\_blank} library natively supports light client configurations powered by [`smoldot`](https://github.com/smol-dot/smoldot){target=\_blank}. This allows developers to connect to multiple chains simultaneously using a light client. - -### Substrate Connect - Browser Extension - -The [Substrate Connect browser extension](https://www.npmjs.com/package/@substrate/connect-extension-protocol){target=\_blank} enables end-users to interact with applications connected to multiple blockchains or to connect their own blockchains to supported applications. - -Establishing a sufficient number of peers can be challenging due to browser limitations on WebSocket connections from HTTPS pages, as many nodes require TLS. The Substrate Connect browser extension addresses this limitation by keeping chains synced in the background, enabling faster application performance. - -Substrate Connect automatically detects whether the user has the extension installed. If not, an in-page Wasm light client is created for them. - -## Resources - -- [What is a light client and why you should care?](https://medium.com/paritytech/what-is-a-light-client-and-why-you-should-care-75f813ae2670){target=\_blank} -- [Introducing Substrate Connect: Browser-Based Light Clients for Connecting to Substrate Chains](https://www.parity.io/blog/introducing-substrate-connect){target=\_blank} -- [Substrate Connect GitHub Repository](https://github.com/paritytech/substrate-connect/tree/master/projects/extension){target=\_blank} -- [Light Clients - Polkadot Specification](https://spec.polkadot.network/sect-lightclient){target=\_blank} - - ---- - -Page Title: Networks - -- Source (raw): https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/reference-parachains-networks.md -- Canonical (HTML): https://docs.polkadot.com/reference/parachains/networks/ -- Summary: Explore Polkadot's testing and production networks, including Westend, Kusama, and Paseo, for efficient development, deployment, and testing. - -# Networks - -## Introduction - -The Polkadot ecosystem is built on a robust set of networks designed to enable secure and scalable development. Whether you are testing new features or deploying to live production, Polkadot offers several layers of networks tailored for each stage of the development process. From local environments to experimental networks like Kusama and community-run TestNets such as Paseo, developers can thoroughly test, iterate, and validate their applications. This guide will introduce you to Polkadot's various networks and explain how they fit into the development workflow. - -## Network Overview - -Polkadot's development process is structured to ensure new features and upgrades are rigorously tested before being deployed on live production networks. The progression follows a well-defined path, starting from local environments and advancing through TestNets, ultimately reaching the Polkadot MainNet. The diagram below outlines the typical progression of the Polkadot development cycle: - -``` mermaid -flowchart LR - id1[Local] --> id2[Westend] --> id4[Kusama] --> id5[Polkadot] - id1[Local] --> id3[Paseo] --> id5[Polkadot] -``` - -This flow ensures developers can thoroughly test and iterate without risking real tokens or affecting production networks. Testing tools like [Chopsticks](#chopsticks) and various TestNets make it easier to experiment safely before releasing to production. - -A typical journey through the Polkadot core protocol development process might look like this: - -1. **Local development node**: Development starts in a local environment, where developers can create, test, and iterate on upgrades or new features using a local development node. This stage allows rapid experimentation in an isolated setup without any external dependencies. - -2. **Westend**: After testing locally, upgrades are deployed to [Westend](#westend), Polkadot's primary TestNet. Westend simulates real-world conditions without using real tokens, making it the ideal place for rigorous feature testing before moving on to production networks. - -3. **Kusama**: Once features have passed extensive testing on Westend, they move to Kusama, Polkadot's experimental and fast-moving "canary" network. Kusama operates as a high-fidelity testing ground with actual economic incentives, giving developers insights into how their features will perform in a real-world environment. - -4. **Polkadot**: After passing tests on Westend and Kusama, features are considered ready for deployment to Polkadot, the live production network. - - In addition, parachain developers can leverage local TestNets like [Zombienet](#zombienet) and deploy upgrades on parachain TestNets. - -5. **Paseo**: For parachain and dApp developers, Paseo serves as a community-run TestNet that mirrors Polkadot's runtime. Like Westend for core protocol development, Paseo provides a testing ground for parachain development without affecting live networks. - -!!!note - The Rococo TestNet deprecation date was October 14, 2024. Teams should use Westend for Polkadot protocol and feature testing and Paseo for chain development-related testing. - -## Polkadot Development Networks - -Development and testing are crucial to building robust dApps and parachains and performing network upgrades within the Polkadot ecosystem. To achieve this, developers can leverage various networks and tools that provide a risk-free environment for experimentation and validation before deploying features to live networks. These networks help avoid the costs and risks associated with real tokens, enabling testing for functionalities like governance, cross-chain messaging, and runtime upgrades. - -## Kusama Network - -Kusama is the experimental version of Polkadot, designed for developers who want to move quickly and test their applications in a real-world environment with economic incentives. Kusama serves as a production-grade testing ground where developers can deploy features and upgrades with the pressure of game theory and economics in mind. It mirrors Polkadot but operates as a more flexible space for innovation. - -The native token for Kusama is KSM. For more information about KSM, visit the [Native Assets](https://wiki.polkadot.com/kusama/kusama-getting-started/){target=\_blank} page. - -## Test Networks - -The following test networks provide controlled environments for testing upgrades and new features. TestNet tokens are available from the [Polkadot faucet](https://faucet.polkadot.io/){target=\_blank}. - -### Westend - -Westend is Polkadot's primary permanent TestNet. Unlike temporary test networks, Westend is not reset to the genesis block, making it an ongoing environment for testing Polkadot core features. Managed by Parity Technologies, Westend ensures that developers can test features in a real-world simulation without using actual tokens. - -The native token for Westend is WND. More details about WND can be found on the [Native Assets](https://wiki.polkadot.com/learn/learn-dot/#__tabbed_2_2){target=\_blank} page. - -### Paseo - -[Paseo](https://github.com/paseo-network){target=\_blank} is a community-managed TestNet designed for parachain and dApp developers. It mirrors Polkadot's runtime and is maintained by Polkadot community members. Paseo provides a dedicated space for parachain developers to test their applications in a Polkadot-like environment without the risks associated with live networks. - -The native token for Paseo is PAS. Additional information on PAS is available on the [Native Assets](https://wiki.polkadot.com/learn/learn-dot/#__tabbed_2_1){target=\_blank} page. - -## Local Test Networks - -Local test networks are an essential part of the development cycle for blockchain developers using the Polkadot SDK. They allow for fast, iterative testing in controlled, private environments without connecting to public TestNets. Developers can quickly spin up local instances to experiment, debug, and validate their code before deploying to larger TestNets like Westend or Paseo. Two key tools for local network testing are Zombienet and Chopsticks. - -### Zombienet - -[Zombienet](https://github.com/paritytech/zombienet){target=\_blank} is a flexible testing framework for Polkadot SDK-based blockchains. It enables developers to create and manage ephemeral, short-lived networks. This feature makes Zombienet particularly useful for quick iterations, as it allows you to run multiple local networks concurrently, mimicking different runtime conditions. Whether you're developing a parachain or testing your custom blockchain logic, Zombienet gives you the tools to automate local testing. - -Key features of Zombienet include: - -- Creating dynamic, local networks with different configurations. -- Running parachains and relay chains in a simulated environment. -- Efficient testing of network components like cross-chain messaging and governance. - -Zombienet is ideal for developers looking to test quickly and thoroughly before moving to more resource-intensive public TestNets. - -### Chopsticks - -[Chopsticks](https://github.com/AcalaNetwork/chopsticks){target=\_blank} is a tool designed to create forks of Polkadot SDK-based blockchains, allowing developers to interact with network forks as part of their testing process. This capability makes Chopsticks a powerful option for testing upgrades, runtime changes, or cross-chain applications in a forked network environment. - -Key features of Chopsticks include: - -- Forking live Polkadot SDK-based blockchains for isolated testing. -- Simulating cross-chain messages in a private, controlled setup. -- Debugging network behavior by interacting with the fork in real-time. - -Chopsticks provides a controlled environment for developers to safely explore the effects of runtime changes. It ensures that network behavior is tested and verified before upgrades are deployed to live networks. - - ---- - -Page Title: Node and Runtime - -- Source (raw): https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/reference-parachains-node-and-runtime.md -- Canonical (HTML): https://docs.polkadot.com/reference/parachains/node-and-runtime/ -- Summary: Learn how Polkadot SDK-based nodes function, how the client and runtime are separated, and how they communicate using SCALE-encoded data. - -# Node and Runtime - -## Introduction - -Every blockchain platform relies on a decentralized network of computers, called nodes, that communicate with each other about transactions and blocks. In this context, a node refers to the software running on the connected devices rather than the physical or virtual machines in the network. - -Polkadot SDK-based nodes consist of two main components, each with distinct responsibilities: the client (also called node) and the runtime. - -If the system were a monolithic protocol, any modification would require updating the entire system. Instead, Polkadot achieves true upgradeability by defining an immutable meta-protocol (the client) and a protocol (the runtime) that can be upgraded independently. - -This separation gives the [Polkadot Relay Chain](/polkadot-protocol/architecture/polkadot-chain){target=\_blank} and all connected [parachains](/polkadot-protocol/architecture/parachains){target=\_blank} an evolutionary advantage over other blockchain platforms. - -## Architectural Principles - -The Polkadot SDK-based blockchain architecture is fundamentally built on two distinct yet interconnected components: - -- Client (Meta-protocol): - - Handles the foundational infrastructure of the blockchain. - - Manages runtime execution, networking, consensus, and other off-chain components. - - Provides an immutable base layer that ensures network stability. - - Upgradable only through hard forks. - -- Runtime (Protocol): - - Defines the blockchain's state transition logic. - - Determines the specific rules and behaviors of the blockchain. - - Compiled to WebAssembly (Wasm) for platform-independent execution. - - Capable of being upgraded without network-wide forking. - -### Advantages of this Architecture - -- **Forkless upgrades**: Runtime can be updated without disrupting the entire network. -- **Modularity**: Clear separation allows independent development of client and runtime. -- **Flexibility**: Enables rapid iteration and evolution of blockchain logic. -- **Performance**: WebAssembly compilation provides efficient, cross-platform execution. - -## Node (Client) - -The node, also known as the client, is the core component responsible for executing the Wasm runtime and orchestrating various essential blockchain components. It ensures the correct execution of the state transition function and manages multiple critical subsystems, including: - -- **Wasm execution**: Runs the blockchain runtime, which defines the state transition rules. -- **Database management**: Stores blockchain data. -- **Networking**: Facilitates peer-to-peer communication, block propagation, and transaction gossiping. -- **Transaction pool (Mempool)**: Manages pending transactions before they are included in a block. -- **Consensus mechanism**: Ensures agreement on the blockchain state across nodes. -- **RPC services**: Provides external interfaces for applications and users to interact with the node. - -## Runtime - -The runtime is more than just a set of rules. It's the fundamental logic engine that defines a blockchain's entire behavior. In Polkadot SDK-based blockchains, the runtime represents a complete, self-contained description of the blockchain's state transition function. - -### Characteristics - -The runtime is distinguished by three key characteristics: - -- **Business logic**: Defines the complete application-specific blockchain behavior. -- **WebAssembly compilation**: Ensures platform-independent, secure execution. -- **On-chain storage**: Stored within the blockchain's state, allowing dynamic updates. - -### Key Functions - -The runtime performs several critical functions, such as: - -- Define state transition rules. -- Implement blockchain-specific logic. -- Manage account interactions. -- Control transaction processing. -- Define governance mechanisms. -- Handle custom pallets and modules. - -## Communication Between Node and Runtime - -The client and runtime communicate exclusively using [SCALE-encoded](/polkadot-protocol/parachain-basics/data-encoding){target=\_blank} communication. This ensures efficient and compact data exchange between the two components. - -### Runtime APIs - -The Runtime API consists of well-defined functions and constants a client assumes are implemented in the Runtime Wasm blob. These APIs enable the client to interact with the runtime to execute blockchain operations and retrieve information. The client invokes these APIs to: - -- Build, execute, and finalize blocks. -- Access metadata. -- Access consensus related information. -- Handle transaction execution. - -### Host Functions - -During execution, the runtime can access certain external client functionalities via host functions. The specific functions the client exposes allow the runtime to perform operations outside the WebAssembly domain. Host functions enable the runtime to: - -- Perform cryptographic operations. -- Access the current blockchain state. -- Handle storage modifications. -- Allocate memory. - - ---- - -Page Title: On-Chain Governance Overview - -- Source (raw): https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/reference-governance.md -- Canonical (HTML): https://docs.polkadot.com/reference/governance/ -- Summary: Discover Polkadot’s cutting-edge OpenGov system, enabling transparent, decentralized decision-making through direct democracy and flexible governance tracks. - -# On-Chain Governance - -## Introduction - -Polkadot’s governance system exemplifies decentralized decision-making, empowering its community of stakeholders to shape the network’s future through active participation. The latest evolution, OpenGov, builds on Polkadot’s foundation by providing a more inclusive and efficient governance model. - -This guide will explain the principles and structure of OpenGov and walk you through its key components, such as Origins, Tracks, and Delegation. You will learn about improvements over earlier governance systems, including streamlined voting processes and enhanced stakeholder participation. - -With OpenGov, Polkadot achieves a flexible, scalable, and democratic governance framework that allows multiple proposals to proceed simultaneously, ensuring the network evolves in alignment with its community's needs. - -## Governance Evolution - -Polkadot’s governance journey began with [Governance V1](https://wiki.polkadot.com/learn/learn-polkadot-opengov/#governance-summary){target=\_blank}, a system that proved effective in managing treasury funds and protocol upgrades. However, it faced limitations, such as: - -- Slow voting cycles, causing delays in decision-making. -- Inflexibility in handling multiple referendums, restricting scalability. - -To address these challenges, Polkadot introduced OpenGov, a governance model designed for greater inclusivity, efficiency, and scalability. OpenGov replaces the centralized structures of Governance V1, such as the Council and Technical Committee, with a fully decentralized and dynamic framework. - -For a full comparison of the historic and current governance models, visit the [Gov1 vs. Polkadot OpenGov](https://wiki.polkadot.com/learn/learn-polkadot-opengov/#gov1-vs-polkadot-opengov){target=\_blank} section of the Polkadot Wiki. - -## OpenGov Key Features - -OpenGov transforms Polkadot’s governance into a decentralized, stakeholder-driven model, eliminating centralized decision-making bodies like the Council. Key enhancements include: - -- **Decentralization**: Shifts all decision-making power to the public, ensuring a more democratic process. -- **Enhanced delegation**: Allows users to delegate their votes to trusted experts across specific governance tracks. -- **Simultaneous referendums**: Multiple proposals can progress at once, enabling faster decision-making. -- **Polkadot Technical Fellowship**: A broad, community-driven group replacing the centralized Technical Committee. - -This new system ensures Polkadot governance remains agile and inclusive, even as the ecosystem grows. - -## Origins and Tracks - -In OpenGov, origins and tracks are central to managing proposals and votes. - -- **Origin**: Determines the authority level of a proposal (e.g., Treasury, Root) which decides the track of all referendums from that origin. -- **Track**: Define the procedural flow of a proposal, such as voting duration, approval thresholds, and enactment timelines. - -Developers must be aware that referendums from different origins and tracks will take varying amounts of time to reach approval and enactment. The [Polkadot Technical Fellowship](https://wiki.polkadot.com/learn/learn-polkadot-technical-fellowship/){target=\_blank} has the option to shorten this timeline by whitelisting a proposal and allowing it to be enacted through the [Whitelist Caller](https://wiki.polkadot.com/learn/learn-polkadot-opengov-origins/#whitelisted-caller){target=\_blank} origin. - -Visit [Origins and Tracks Info](https://wiki.polkadot.com/learn/learn-polkadot-opengov/#origins-and-tracks){target=\_blank} for details on current origins and tracks, associated terminology, and parameters. - -## Referendums - -In OpenGov, anyone can submit a referendum, fostering an open and participatory system. The timeline for a referendum depends on the privilege level of the origin with more significant changes offering more time for community voting and participation before enactment. - -The timeline for an individual referendum includes four distinct periods: - -- **Lead-in**: A minimum amount of time to allow for community participation, available room in the origin, and payment of the decision deposit. Voting is open during this period. -- **Decision**: Voting continues. -- **Confirmation**: Referendum must meet [approval and support](https://wiki.polkadot.com/learn/learn-polkadot-opengov/#approval-and-support){target=\_blank} criteria during entire period to avoid rejection. -- **Enactment**: Changes approved by the referendum are executed. - -### Vote on Referendums - -Voters can vote with their tokens on each referendum. Polkadot uses a voluntary token locking mechanism, called conviction voting, as a way for voters to increase their voting power. A token holder signals they have a stronger preference for approving a proposal based upon their willingness to lock up tokens. Longer voluntary token locks are seen as a signal of continual approval and translate to increased voting weight. - -See [Voting on a Referendum](https://wiki.polkadot.com/learn/learn-polkadot-opengov/#voting-on-a-referendum){target=\_blank} for a deeper look at conviction voting and related token locks. - -### Delegate Voting Power - -The OpenGov system also supports multi-role delegations, allowing token holders to assign their voting power on different tracks to entities with expertise in those areas. - -For example, if a token holder lacks the technical knowledge to evaluate proposals on the [Root track](https://wiki.polkadot.com/learn/learn-polkadot-opengov-origins/#root){target=\_blank}, they can delegate their voting power for that track to an expert they trust to vote in the best interest of the network. This ensures informed decision-making across tracks while maintaining flexibility for token holders. - -Visit [Multirole Delegation](https://wiki.polkadot.com/learn/learn-polkadot-opengov/#multirole-delegation){target=\_blank} for more details on delegating voting power. - -### Cancel a Referendum - -Polkadot OpenGov has two origins for rejecting ongoing referendums: - -- [**Referendum Canceller**](https://wiki.polkadot.com/learn/learn-polkadot-opengov-origins/#referendum-canceller){target=\_blank}: Cancels an active referendum when non-malicious errors occur and refunds the deposits to the originators. -- [**Referendum Killer**](https://wiki.polkadot.com/learn/learn-polkadot-opengov-origins/#referendum-killer){target=\_blank}: Used for urgent, malicious cases this origin instantly terminates an active referendum and slashes deposits. - -See [Cancelling, Killing, and Blacklisting](https://wiki.polkadot.com/learn/learn-polkadot-opengov/#cancelling-killing--blacklisting){target=\_blank} for additional information on rejecting referendums. - -## Additional Resources - -- **[Democracy pallet](https://github.com/paritytech/polkadot-sdk/tree/polkadot-stable2506-2/substrate/frame/democracy/src){target=\_blank}**: Handles administration of general stakeholder voting. -- **[Gov2: Polkadot’s Next Generation of Decentralised Governance](https://medium.com/polkadot-network/gov2-polkadots-next-generation-of-decentralised-governance-4d9ef657d11b){target=\_blank}**: Medium article by Gavin Wood. -- **[Polkadot Direction](https://matrix.to/#/#Polkadot-Direction:parity.io){target=\_blank}**: Matrix Element client. -- **[Polkassembly](https://polkadot.polkassembly.io/){target=\_blank}**: OpenGov dashboard and UI. -- **[Polkadot.js Apps Governance](https://polkadot.js.org/apps/#/referenda){target=\_blank}**: Overview of active referendums. - - --- Page Title: Oracles @@ -6262,3677 +4721,1358 @@ This section covers the most common customization patterns you'll encounter: --- -Page Title: Overview of the Polkadot Relay Chain +Page Title: Run a Parachain Network -- Source (raw): https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/reference-polkadot-hub-consensus-and-security-relay-chain.md -- Canonical (HTML): https://docs.polkadot.com/reference/polkadot-hub/consensus-and-security/relay-chain/ -- Summary: Explore Polkadot's core architecture, including its multi-chain vision, shared security, and the DOT token's governance and staking roles. +- Source (raw): https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/parachains-testing-run-a-parachain-network.md +- Canonical (HTML): https://docs.polkadot.com/parachains/testing/run-a-parachain-network/ +- Summary: Quickly install and configure Zombienet to deploy and test Polkadot-based blockchain networks with this comprehensive getting-started guide. -# Overview +# Run a Parachain Network Using Zombienet ## Introduction -Polkadot is a next-generation blockchain protocol designed to support a multi-chain future by enabling secure communication and interoperability between different blockchains. Built as a Layer-0 protocol, Polkadot introduces innovations like application-specific Layer-1 chains ([parachains](/polkadot-protocol/architecture/parachains/){targe=\_blank}), shared security through [Nominated Proof of Stake (NPoS)](/reference/glossary/#nominated-proof-of-stake-npos){target=\_blank}, and cross-chain interactions via its native [Cross-Consensus Messaging Format (XCM)](/parachains/interoperability/get-started/){target=\_blank}. +Zombienet is a robust testing framework designed for Polkadot SDK-based blockchain networks. It enables developers to efficiently deploy and test ephemeral blockchain environments on platforms like Kubernetes, Podman, and native setups. With its simple and versatile CLI, Zombienet provides an all-in-one solution for spawning networks, running tests, and validating performance. -This guide covers key aspects of Polkadot’s architecture, including its high-level protocol structure, blockspace commoditization, and the role of its native token, DOT, in governance, staking, and resource allocation. +This guide will outline the different installation methods for Zombienet, provide step-by-step instructions for setting up on various platforms, and highlight essential provider-specific features and requirements. -## Polkadot 1.0 +By following this guide, Zombienet will be up and running quickly, ready to streamline your blockchain testing and development workflows. -Polkadot 1.0 represents the state of Polkadot as of 2023, coinciding with the release of [Polkadot runtime v1.0.0](https://github.com/paritytech/polkadot/releases/tag/v1.0.0){target=\_blank}. This section will focus on Polkadot 1.0, along with philosophical insights into network resilience and blockspace. +## Install Zombienet -As a Layer-0 blockchain, Polkadot contributes to the multi-chain vision through several key innovations and initiatives, including: +Zombienet releases are available on the [Zombienet repository](https://github.com/paritytech/zombienet){target=\_blank}. -- **Application-specific Layer-1 blockchains (parachains)**: Polkadot's sharded network allows for parallel transaction processing, with shards that can have unique state transition functions, enabling custom-built L1 chains optimized for specific applications. +Multiple options are available for installing Zombienet, depending on the user's preferences and the environment where it will be used. The following section will guide you through the installation process for each option. -- **Shared security and scalability**: L1 chains connected to Polkadot benefit from its [Nominated Proof of Stake (NPoS)](/reference/polkadot-hub/consensus-and-security/pos-consensus/#nominated-proof-of-stake){target=\_blank} system, providing security out-of-the-box without the need to bootstrap their own. +=== "Use the executable" -- **Secure interoperability**: Polkadot's native interoperability enables seamless data and value exchange between parachains. This interoperability can also be used outside of the ecosystem for bridging with external networks. + Install Zombienet using executables by visiting the [latest release](https://github.com/paritytech/zombienet/releases){target=\_blank} page and selecting the appropriate asset for your operating system. You can download the executable and move it to a directory in your PATH. -- **Resilient infrastructure**: Decentralized and scalable, Polkadot ensures ongoing support for development and community initiatives via its on-chain [treasury](https://wiki.polkadot.com/learn/learn-polkadot-opengov-treasury/){target=\_blank} and governance. + Each release includes executables for Linux and macOS. Executables are generated using [pkg](https://github.com/vercel/pkg){target=\_blank}, which allows the Zombienet CLI to operate without requiring Node.js to be installed. -- **Rapid L1 development**: The [Polkadot SDK](/reference/parachains/){target=\_blank} allows fast, flexible creation and deployment of Layer-1 chains. + Then, ensure the downloaded file is executable: -- **Cultivating the next generation of Web3 developers**: Polkadot supports the growth of Web3 core developers through initiatives such as. + ```bash + chmod +x zombienet-macos-arm64 + ``` - - [Polkadot Blockchain Academy](https://polkadot.com/blockchain-academy){target=\_blank} - - [EdX courses](https://www.edx.org/school/web3x){target=\_blank} - - Rust and Substrate courses (coming soon) + Finally, you can run the following command to check if the installation was successful. If so, it will display the version of the installed Zombienet: -### High-Level Architecture + ```bash + ./zombienet-macos-arm64 version + ``` -Polkadot features a chain that serves as the central component of the system. This chain is depicted as a ring encircled by several parachains that are connected to it. + If you want to add the `zombienet` executable to your PATH, you can move it to a directory in your PATH, such as `/usr/local/bin`: -According to Polkadot's design, any blockchain that can compile to WebAssembly (Wasm) and adheres to the Parachains Protocol becomes a parachain on the Polkadot network. + ```bash + mv zombienet-macos-arm64 /usr/local/bin/zombienet + ``` -Here’s a high-level overview of the Polkadot protocol architecture: + Now you can refer to the `zombienet` executable directly. -![](/images/reference/polkadot-hub/consensus-and-security/relay-chain/relay-chain-01.webp){ style="background:white" } + ```bash + zombienet version + ``` -Parachains propose blocks to Polkadot validators, who check for availability and validity before finalizing them. With the relay chain providing security, collators—full nodes of parachains—can focus on their tasks without needing strong incentives. +=== "Use Nix" -The [Cross-Consensus Messaging Format (XCM)](/parachains/interoperability/get-started/){target=\_blank} allows parachains to exchange messages freely, leveraging the chain's security for trust-free communication. + For Nix users, the Zombienet repository provides a [`flake.nix`](https://github.com/paritytech/zombienet/blob/main/flake.nix){target=\_blank} file to install Zombienet making it easy to incorporate Zombienet into Nix-based projects. + + To install Zombienet utilizing Nix, users can run the following command, triggering the fetching of the flake and subsequently installing the Zombienet package: -In order to interact with chains that want to use their own finalization process (e.g., Bitcoin), Polkadot has [bridges](/reference/parachains/interoperability/#bridges-connecting-external-networks){target=\_blank} that offer two-way compatibility, meaning that transactions can be made between different parachains. + ```bash + nix run github:paritytech/zombienet/INSERT_ZOMBIENET_VERSION -- \ + spawn INSERT_ZOMBIENET_CONFIG_FILE_NAME.toml + ``` -### Polkadot's Additional Functionalities + Replace the `INSERT_ZOMBIENET_VERSION` with the desired version of Zombienet and the `INSERT_ZOMBIENET_CONFIG_FILE_NAME` with the name of the configuration file you want to use. -Historically, obtaining core slots on Polkadot chain relied upon crowdloans and auctions. Chain cores were leased through auctions for three-month periods, up to a maximum of two years. Crowdloans enabled users to securely lend funds to teams for lease deposits in exchange for pre-sale tokens, which is the only way to access slots on Polkadot 1.0. Auctions are now deprecated in favor of [coretime](/polkadot-protocol/architecture/system-chains/coretime/){target=\_blank}. + To run the command above, you need to have [Flakes](https://nixos.wiki/wiki/Flakes#Enable_flakes){target=\_blank} enabled. -Additionally, the chain handles [staking](https://wiki.polkadot.com/learn/learn-staking/){target=\_blank}, [accounts](/reference/parachains/accounts/){target=\_blank}, balances, and [governance](/reference/governance/){target=\_blank}. + Alternatively, you can also include the Zombienet binary in the PATH for the current shell using the following command: + + ```bash + nix shell github:paritytech/zombienet/INSERT_ZOMBIENET_VERSION + ``` -#### Agile Coretime +=== "Use Docker" -The new and more efficient way of obtaining core on Polkadot is to go through the process of purchasing coretime. + Zombienet can also be run using Docker. The Zombienet repository provides a Docker image that can be used to run the Zombienet CLI. To run Zombienet using Docker, you can use the following command: -[Agile coretime](/reference/polkadot-hub/consensus-and-security/agile-coretime/){target=\_blank} improves the efficient use of Polkadot's network resources and offers economic flexibility for developers, extending Polkadot's capabilities far beyond the original vision outlined in the [whitepaper](https://polkadot.com/papers/Polkadot-whitepaper.pdf){target=\_blank}. + ```bash + docker run -it --rm \ + -v $(pwd):/home/nonroot/zombie-net/host-current-files \ + paritytech/zombienet + ``` -It enables parachains to purchase monthly "bulk" allocations of coretime (the time allocated for utilizing a core, measured in Polkadot relay chain blocks), ensuring heavy-duty parachains that can author a block every six seconds with [Asynchronous Backing](https://wiki.polkadot.com/learn/learn-async-backing/#asynchronous-backing){target=\_blank} can reliably renew their coretime each month. Although six-second block times are now the default, parachains have the option of producing blocks less frequently. + The command above will run the Zombienet CLI inside a Docker container and mount the current directory to the `/home/nonroot/zombie-net/host-current-files` directory. This allows Zombienet to access the configuration file and other files in the current directory. If you want to mount a different directory, replace `$(pwd)` with the desired directory path. -Renewal orders are prioritized over new orders, offering stability against price fluctuations and helping parachains budget more effectively for project costs. + Inside the Docker container, you can run the Zombienet CLI commands. First, you need to set up Zombienet to download the necessary binaries: -### Polkadot's Resilience - -Decentralization is a vital component of blockchain networks, but it comes with trade-offs: - -- An overly decentralized network may face challenges in reaching consensus and require significant energy to operate. -- Also, a network that achieves consensus quickly risks centralization, making it easier to manipulate or attack. - -A network should be decentralized enough to prevent manipulative or malicious influence. In this sense, decentralization is a tool for achieving resilience. + ```bash + npm run zombie -- setup polkadot polkadot-parachain + ``` -Polkadot 1.0 currently achieves resilience through several strategies: + After that, you need to add those binaries to the PATH: -- **Nominated Proof of Stake (NPoS)**: Ensures that the stake per validator is maximized and evenly distributed among validators. + ```bash + export PATH=/home/nonroot/zombie-net:$PATH + ``` -- **Decentralized nodes**: Designed to encourage operators to join the network. This program aims to expand and diversify the validators in the ecosystem who aim to become independent of the program during their term. Feel free to explore more about the program on the official [Decentralized Nodes](https://nodes.web3.foundation/){target=\_blank} page. + Finally, you can run the Zombienet CLI commands. For example, to spawn a network using a specific configuration file, you can run the following command: -- **On-chain treasury and governance**: Known as [OpenGov](/reference/governance/){target=\_blank}, this system allows every decision to be made through public referenda, enabling any token holder to cast a vote. + ```bash + npm run zombie -- -p native spawn host-current-files/minimal.toml + ``` -### Polkadot's Blockspace + The command above mounts the current directory to the `/workspace` directory inside the Docker container, allowing Zombienet to access the configuration file and other files in the current directory. If you want to mount a different directory, replace `$(pwd)` with the desired directory path. -Polkadot 1.0’s design allows for the commoditization of blockspace. +## Providers -Blockspace is a blockchain's capacity to finalize and commit operations, encompassing its security, computing, and storage capabilities. Its characteristics can vary across different blockchains, affecting security, flexibility, and availability. +Zombienet supports different backend providers for running the nodes. At this moment, [Kubernetes](https://kubernetes.io/){target=\_blank}, [Podman](https://podman.io/){target=\_blank}, and local providers are supported, which can be declared as `kubernetes`, `podman`, or `native`, respectively. -- **Security**: Measures the robustness of blockspace in Proof of Stake (PoS) networks linked to the stake locked on validator nodes, the variance in stake among validators, and the total number of validators. It also considers social centralization (how many validators are owned by single operators) and physical centralization (how many validators run on the same service provider). +To use a particular provider, you can specify it in the network file or use the `--provider` flag in the CLI: -- **Flexibility**: Reflects the functionalities and types of data that can be stored, with high-quality data essential to avoid bottlenecks in critical processes. +```bash +zombienet spawn network.toml --provider INSERT_PROVIDER +``` -- **Availability**: Indicates how easily users can access blockspace. It should be easily accessible, allowing diverse business models to thrive, ideally regulated by a marketplace based on demand and supplemented by options for "second-hand" blockspace. +Alternatively, you can set the provider in the network file: -Polkadot is built on core blockspace principles, but there's room for improvement. Tasks like balance transfers, staking, and governance are managed on the relay chain. +```toml +[settings] +provider = "INSERT_PROVIDER" +... +``` -Delegating these responsibilities to [system chains](/polkadot-protocol/architecture/system-chains/){target=\_blank} could enhance flexibility and allow the relay chain to concentrate on providing shared security and interoperability. +It's important to note that each provider has specific requirements and associated features. The following sections cover each provider's requirements and added features. -For more information about blockspace, watch [Robert Habermeier’s interview](https://www.youtube.com/watch?v=e1vISppPwe4){target=\_blank} or read his [technical blog post](https://www.rob.tech/blog/polkadot-blockspace-over-blockchains/){target=\_blank}. +### Kubernetes -## DOT Token +Kubernetes is a portable, extensible, open-source platform for managing containerized workloads and services. Zombienet is designed to be compatible with a variety of Kubernetes clusters, including: -DOT is the native token of the Polkadot network, much like BTC for Bitcoin and Ether for the Ethereum blockchain. DOT has 10 decimals, uses the Planck base unit, and has a balance type of `u128`. The same is true for Kusama's KSM token with the exception of having 12 decimals. +- [Google Kubernetes Engine (GKE)](https://cloud.google.com/kubernetes-engine){target=\_blank} +- [Docker Desktop](https://docs.docker.com/desktop/features/kubernetes/){target=\_blank} +- [kind](https://kind.sigs.k8s.io/){target=\_blank} -### Redenomination of DOT +#### Requirements -Polkadot conducted a community poll, which ended on 27 July 2020 at block 888,888, to decide whether to redenominate the DOT token. The stakeholders chose to redenominate the token, changing the value of 1 DOT from 1e12 plancks to 1e10 plancks. - -Importantly, this did not affect the network's total number of base units (plancks); it only affects how a single DOT is represented. The redenomination became effective 72 hours after transfers were enabled, occurring at block 1,248,328 on 21 August 2020 around 16:50 UTC. - -### The Planck Unit - -The smallest unit of account balance on Polkadot SDK-based blockchains (such as Polkadot and Kusama) is called _Planck_, named after the Planck length, the smallest measurable distance in the physical universe. - -Similar to how BTC's smallest unit is the Satoshi and ETH's is the Wei, Polkadot's native token DOT equals 1e10 Planck, while Kusama's native token KSM equals 1e12 Planck. - -### Uses for DOT +To effectively interact with your cluster, you'll need to ensure that [`kubectl`](https://kubernetes.io/docs/reference/kubectl/){target=\_blank} is installed on your system. This Kubernetes command-line tool allows you to run commands against Kubernetes clusters. If you don't have `kubectl` installed, you can follow the instructions provided in the [Kubernetes documentation](https://kubernetes.io/docs/tasks/tools/#kubectl){target=\_blank}. -DOT serves three primary functions within the Polkadot network: +To create resources such as namespaces, pods, and CronJobs within the target cluster, you must grant your user or service account the appropriate permissions. These permissions are essential for managing and deploying applications effectively within Kubernetes. -- **Governance**: It is used to participate in the governance of the network. -- **Staking**: DOT is staked to support the network's operation and security. -- **Buying coretime**: Used to purchase coretime in-bulk or on-demand and access the chain to benefit from Polkadot's security and interoperability. +#### Features + +If available, Zombienet uses the Prometheus operator to oversee monitoring and visibility. This configuration ensures that only essential networking-related pods are deployed. Using the Prometheus operator, Zombienet improves its ability to monitor and manage network activities within the Kubernetes cluster efficiently. -Additionally, DOT can serve as a transferable token. For example, DOT, held in the treasury, can be allocated to teams developing projects that benefit the Polkadot ecosystem. +### Podman -## JAM and the Road Ahead +Podman is a daemonless container engine for developing, managing, and running Open Container Initiative (OCI) containers and container images on Linux-based systems. Zombienet supports Podman rootless as a provider on Linux machines. Although Podman has support for macOS through an internal virtual machine (VM), the Zombienet provider code requires Podman to run natively on Linux. -The Join-Accumulate Machine (JAM) represents a transformative redesign of Polkadot's core architecture, envisioned as the successor to the current relay chain. Unlike traditional blockchain architectures, JAM introduces a unique computational model that processes work through two primary functions: +#### Requirements + +To use Podman as a provider, you need to have Podman installed on your system. You can install Podman by following the instructions provided on the [Podman website](https://podman.io/getting-started/installation){target=\_blank}. -- **Join**: Handles data integration. -- **Accumulate**: Folds computations into the chain's state. +#### Features + +Using Podman, Zombienet deploys additional pods to enhance the monitoring and visibility of the active network. Specifically, pods for [Prometheus](https://prometheus.io/){target=\_blank}, [Tempo](https://grafana.com/docs/tempo/latest/operations/monitor/){target=\_blank}, and [Grafana](https://grafana.com/){target=\_blank} are included in the deployment. Grafana is configured with Prometheus and Tempo as data sources. -JAM removes many of the opinions and constraints of the current relay chain while maintaining its core security properties. Expected improvements include: +Upon launching Zombienet, access to these monitoring services is facilitated through specific URLs provided in the output: -- **Permissionless code execution**: JAM is designed to be more generic and flexible, allowing for permissionless code execution through services that can be deployed without governance approval. -- **More effective block time utilization**: JAM's efficient pipeline processing model places the prior state root in block headers instead of the posterior state root, enabling more effective utilization of block time for computations. +- **Prometheus**: `http://127.0.0.1:34123` +- **Tempo**: `http://127.0.0.1:34125` +- **Grafana**: `http://127.0.0.1:41461` -This architectural evolution promises to enhance Polkadot's scalability and flexibility while maintaining robust security guarantees. JAM is planned to be rolled out to Polkadot as a single, complete upgrade rather than a stream of smaller updates. This approach seeks to minimize the developer overhead required to address any breaking changes. +It's important to note that Grafana is deployed with default administrator access. + +When network operations cease, either from halting a running spawn with the `Ctrl+C` command or test completion, Zombienet automatically removes all associated pods. +### Local Provider ---- +The Zombienet local provider, also called native, enables you to run nodes as local processes in your environment. -Page Title: Parachains Overview +#### Requirements + +You must have the necessary binaries for your network (such as `polkadot` and `polkadot-parachain`). These binaries should be available in your PATH, allowing Zombienet to spawn the nodes as local processes. -- Source (raw): https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/reference-parachains.md -- Canonical (HTML): https://docs.polkadot.com/reference/parachains/ -- Summary: Learn about parachains, specialized blockchains on Polkadot that gain shared security and interoperability. Discover how they work and the tools to build them. +To install the necessary binaries, you can use the Zombienet CLI command: -# Parachains Overview +```bash +zombienet setup polkadot polkadot-parachain +``` -## Introduction +This command will download and prepare the necessary binaries for Zombienet's use. -A parachain is a specialized blockchain that connects to the Polkadot relay chain, benefiting from shared security, interoperability, and scalability. Parachains are built using the [Polkadot SDK](https://github.com/paritytech/polkadot-sdk){target=\_blank}, a powerful toolkit written in Rust that provides everything needed to create custom blockchain logic while integrating seamlessly with the Polkadot network. +If you need to use a custom binary, ensure the binary is available in your PATH. You can also specify the binary path in the network configuration file. The following example uses the custom [OpenZeppelin template](https://github.com/OpenZeppelin/polkadot-runtime-templates){target=\_blank}: -Unlike standalone blockchains that must bootstrap their own validator sets and security, parachains leverage Polkadot's pooled security model. This allows parachain developers to focus on their application-specific functionality rather than consensus and security infrastructure. Parachains can communicate with each other through Cross-Consensus Messaging (XCM), enabling seamless interoperability across the Polkadot ecosystem. +First, clone the OpenZeppelin template repository using the following command: -Key capabilities that parachains provide include: +```bash +git clone https://github.com/OpenZeppelin/polkadot-runtime-templates \ +&& cd polkadot-runtime-templates/generic-template +``` -- **Shared security**: Inherit security from Polkadot's validator set without maintaining your own. -- **Interoperability**: Communicate trustlessly with other parachains via XCM. -- **Scalability**: Process transactions in parallel with other parachains. -- **Customization**: Build application-specific logic tailored to your use case. -- **Upgradeability**: Upgrade runtime logic without hard forks. +Next, run the command to build the custom binary: -## Polkadot SDK: Parachain Architecture +```bash +cargo build --release +``` -Building a parachain involves understanding and utilizing several key components of the Polkadot SDK: +Finally, add the custom binary to your PATH as follows: -![](/images/reference/parachains/index/overview-01.webp) +```bash +export PATH=$PATH:INSERT_PATH_TO_RUNTIME_TEMPLATES/parachain-template-node/target/release +``` -- **[Substrate](https://paritytech.github.io/polkadot-sdk/master/polkadot_sdk_docs/polkadot_sdk/substrate/index.html){target=\_blank}**: The foundation providing core blockchain primitives and libraries. -- **[FRAME](https://paritytech.github.io/polkadot-sdk/master/polkadot_sdk_docs/polkadot_sdk/frame_runtime/index.html){target=\_blank}**: A modular framework for building your parachain's runtime logic. -- **[Cumulus](https://paritytech.github.io/polkadot-sdk/master/polkadot_sdk_docs/polkadot_sdk/cumulus/index.html){target=\_blank}**: Essential libraries and pallets that enable parachain functionality. -- **[XCM (Cross Consensus Messaging)](https://paritytech.github.io/polkadot-sdk/master/polkadot_sdk_docs/polkadot_sdk/xcm/index.html){target=\_blank}**: The messaging format for communicating with other parachains and the relay chain. -- **[Polkadot](https://paritytech.github.io/polkadot-sdk/master/polkadot_sdk_docs/polkadot_sdk/polkadot/index.html){target=\_blank}**: The relay chain that provides security and coordination. +Alternatively, you can specify the binary path in the network configuration file. The local provider exclusively utilizes the command configuration for nodes, which supports both relative and absolute paths. You can employ the `default_command` configuration to specify the binary for spawning all nodes in the relay chain. -### Substrate: The Foundation +```toml +[relaychain] +chain = "rococo-local" +default_command = "./bin-v1.6.0/polkadot" -Substrate provides the core infrastructure that every parachain is built upon. It handles the low-level blockchain functionality, allowing you to focus on your application's unique features. Substrate includes implementations for networking, database management, consensus participation, and the execution environment for your runtime. +[parachain] +id = 1000 -Every Polkadot SDK node consists of two main components: + [parachain.collators] + name = "collator01" + command = "./target/release/parachain-template-node" +``` -- **Client (Host)**: Handles infrastructure services. +#### Features - - Native binary that runs on validator and collator nodes. - - Executes the Wasm-compiled runtime. - - Manages networking, database, mempool, and block production. - - Interfaces with the relay chain for validation. +The local provider does not offer any additional features. -- **Runtime (State Transition Function)**: Contains your business logic. +## Configure Zombienet - - Defines how your Polkadot SDK node processes transactions. - - Compiled to [Wasm](https://webassembly.org/){target=\_blank} for deterministic execution. - - Stored on-chain and upgradeable via governance. +Effective network configuration is crucial for deploying and managing blockchain systems. Zombienet simplifies this process by offering versatile configuration options in both JSON and TOML formats. Whether setting up a simple test network or a complex multi-node system, Zombienet's tools provide the flexibility to customize every aspect of your network's setup. -```mermaid -%%{init: {'flowchart': {'padding': 5, 'nodeSpacing': 50, 'rankSpacing': 10}}}%% -graph TB - classDef title font-size:20px,font-weight:bold,stroke-width:0px - classDef clientStyle font-size:16px,font-weight:bold - classDef clientSubNodeStyle margin-top:10px - classDef runtimeCallExecutorStyle padding-top:10px +The following sections will explore the structure and usage of Zombienet configuration files, explain key settings for network customization, and walk through CLI commands and flags to optimize your development workflow. - subgraph sg1[Parachain
Node] - direction TB +### Configuration Files - I[RuntimeCall Executor] - B[Wasm Runtime - STF] +The network configuration file can be either JSON or TOML format. The Zombienet repository also provides a collection of [example configuration files](https://github.com/paritytech/zombienet/tree/main/examples){target=\_blank} that can be used as a reference. - subgraph sg2[Client] - direction TB - C[Network and Blockchain
Infrastructure Services
+ Relay Chain Interface] - end +Each section may include provider-specific keys that aren't recognized by other providers. For example, if you use the local provider, any references to images for nodes will be disregarded. - I --> B - end +### CLI Usage - class sg1 title - class sg2 clientStyle - class C clientSubNodeStyle - class I runtimeCallExecutorStyle +Zombienet provides a CLI that allows interaction with the tool. The CLI can receive commands and flags to perform different kinds of operations. These operations use the following syntax: +```bash +zombienet ``` -### FRAME: Building Blocks for Your Runtime - -FRAME provides modular components called [pallets](/reference/glossary#pallet){target=\_blank} that you can compose to build your parachain's runtime. Each pallet provides specific functionality that you can customize and configure for your needs. This modular approach allows you to quickly assemble complex functionality without writing everything from scratch. - -```mermaid -graph LR - subgraph SP["Parachain Runtime"] - direction LR - Timestamp ~~~ Aura ~~~ ParachainSystem - Balances ~~~ TransactionPayment ~~~ Sudo - subgraph Timestamp["Timestamp"] - SS1[Custom Config] - end - subgraph Aura["Aura"] - SS2[Custom Config] - end - subgraph ParachainSystem["Parachain System"] - SS3[Custom Config] - end - subgraph Balances["Balances"] - SS4[Custom Config] - end - subgraph TransactionPayment["Transaction Payment"] - SS5[Custom Config] - end - subgraph Sudo["Sudo"] - SS6[Custom Config] - end - style Timestamp stroke:#FF69B4 - style Aura stroke:#FF69B4 - style ParachainSystem stroke:#FF69B4 - style Balances stroke:#FF69B4 - style TransactionPayment stroke:#FF69B4 - style Sudo stroke:#FF69B4 - style SS1 stroke-dasharray: 5 - style SS2 stroke-dasharray: 5 - style SS3 stroke-dasharray: 5 - style SS4 stroke-dasharray: 5 - style SS5 stroke-dasharray: 5 - style SS6 stroke-dasharray: 5 - - end - subgraph AP["Available FRAME Pallets"] - direction LR - A1[Aura]~~~A2[Parachain
System]~~~A3[Transaction
Payment]~~~A4[Sudo] - B1[Identity]~~~B2[Balances]~~~B3[Assets]~~~B4[EVM] - C1[Timestamp]~~~C2[Staking]~~~C3[Contracts]~~~C4[and more...] - end - AP --> SP -``` - -### Cumulus: Parachain-Specific Functionality - -Cumulus is what transforms a Polkadot SDK-based runtime into a parachain-capable runtime. It provides the essential components for communicating with the relay chain, participating in Polkadot's consensus, and handling parachain-specific operations like block validation and collation. - -Key Cumulus components include: - -- **Parachain system pallet**: Core parachain functionality and relay chain communication. -- **Collator consensus**: Block production logic for parachain collators. -- **Relay chain interface**: APIs for interacting with the Polkadot relay chain. -- **Validation data**: Handling proof-of-validity data required by relay chain validators. - -## Where to Go Next - -Building a parachain requires understanding the relationship between your chain and the Polkadot relay chain. The Polkadot SDK provides all the tools needed to design custom runtime logic, enable cross-chain communication, and deploy your parachain to production. - -The following sections provide detailed guidance on each aspect of parachain development, from initial design through deployment and ongoing maintenance. +The following sections will guide you through the primary usage of the Zombienet CLI and the available commands and flags. -
+#### CLI Commands -- Guide __Launch a Simple Parachain__ +- **`spawn `**: Spawn the network defined in the [configuration file](#configuration-files). +- **`test `**: Run tests on the spawned network using the assertions and tests defined in the test file. +- **`setup `**: Set up the Zombienet development environment to download and use the `polkadot` or `polkadot-parachain` executable. +- **`convert `**: Transforms a [polkadot-launch](https://github.com/paritytech/polkadot-launch){target=\_blank} configuration file with a `.js` or `.json` extension into a Zombienet configuration file. +- **`version`**: Prints Zombienet version. +- **`help`**: Prints help information. - --- +#### CLI Flags - Walk through the complete parachain launch flow: from setup and deployment to obtaining coretime. +You can use the following flags to customize the behavior of the CLI: - [:octicons-arrow-right-24: Deploy](/parachains/launch-a-parachain/set-up-the-parachain-template/) +- **`-p`, `--provider`**: Override the [provider](#providers) to use. +- **`-d`, `--dir`**: Specify a directory path for placing the network files instead of using the default temporary path. +- **`-f`, `--force`**: Force override all prompt commands. +- **`-l`, `--logType`**: Type of logging on the console. Defaults to `table`. +- **`-m`, `--monitor`**: Start as monitor and don't auto clean up network. +- **`-c`, `--spawn-concurrency`**: Number of concurrent spawning processes to launch. Defaults to `1`. +- **`-h`, `--help`**: Display help for command. +### Settings -- Guide __Customize Your Runtime__ +Through the keyword `settings`, it's possible to define the general settings for the network. The available keys are: - --- +- **`global_volumes?`** ++"GlobalVolume[]"++: A list of global volumes to use. - Design your parachain's runtime logic and choose appropriate pallets for your use case. + ??? child "`GlobalVolume` interface definition" + ```js + export interface GlobalVolume { + name: string; + fs_type: string; + mount_path: string; + } + ``` - [:octicons-arrow-right-24: Get Started](/parachains/customize-runtime/) +- **`bootnode`** ++"boolean"++: Add bootnode to network. Defaults to `true`. +- **`bootnode_domain?`** ++"string"++: Domain to use for bootnode. +- **`timeout`** ++"number"++: Global timeout to use for spawning the whole network. +- **`node_spawn_timeout?`** ++"number"++: Timeout to spawn pod/process. +- **`grafana?`** ++"boolean"++: Deploy an instance of Grafana. +- **`prometheus?`** ++"boolean"++: Deploy an instance of Prometheus. +- **`telemetry?`** ++"boolean"++: Enable telemetry for the network. +- **`jaeger_agent?`** ++"string"++: The Jaeger agent endpoint passed to the nodes. Only available on Kubernetes. +- **`tracing_collator_url?`** ++"string"++: The URL of the tracing collator used to query by the tracing assertion. Should be tempo query compatible. +- **`tracing_collator_service_name?`** ++"string"++: Service name for tempo query frontend. Only available on Kubernetes. Defaults to `tempo-tempo-distributed-query-frontend`. +- **`tracing_collator_service_namespace?`** ++"string"++: Namespace where tempo is running. Only available on Kubernetes. Defaults to `tempo`. +- **`tracing_collator_service_port?`** ++"number"++: Port of the query instance of tempo. Only available on Kubernetes. Defaults to `3100`. +- **`enable_tracing?`** ++"boolean"++: Enable the tracing system. Only available on Kubernetes. Defaults to `true`. +- **`provider`** ++"string"++: Provider to use. Default is `kubernetes`". +- **`polkadot_introspector?`** ++"boolean"++: Deploy an instance of polkadot-introspector. Only available on Podman and Kubernetes. Defaults to `false`. +- **`backchannel?`** ++"boolean"++: Deploy an instance of backchannel server. Only available on Kubernetes. Defaults to `false`. +- **`image_pull_policy?`** ++"string"++: Image pull policy to use in the network. Possible values are `Always`, `IfNotPresent`, and `Never`. +- **`local_ip?`** ++"string"++: IP used for exposing local services (rpc/metrics/monitors). Defaults to `"127.0.0.1"`. +- **`global_delay_network_global_settings?`** ++"number"++: Delay in seconds to apply to the network. +- **`node_verifier?`** ++"string"++: Specify how to verify node readiness or deactivate by using `None`. Possible values are `None` and `Metric`. Defaults to `Metric`. -- Guide __Interoperability__ +For example, the following configuration file defines a minimal example for the settings: - --- +=== "TOML" - Implement XCM for trustless cross-chain communication with other parachains. + ```toml title="base-example.toml" + [settings] + timeout = 1000 + bootnode = false + provider = "kubernetes" + backchannel = false + # ... - [:octicons-arrow-right-24: Learn More](/parachains/interoperability/get-started/) + ``` -- Guide __Runtime Upgrades__ +=== "JSON" - --- + ```json title="base-example.json" + { + "settings": { + "timeout": 1000, + "bootnode": false, + "provider": "kubernetes", + "backchannel": false, + "...": {} + }, + "...": {} + } - Upgrade your parachain's runtime without hard forks using forkless upgrade mechanisms. + ``` - [:octicons-arrow-right-24: Maintain](/parachains/runtime-maintenance/runtime-upgrades/) +### Relay Chain Configuration -
+You can use the `relaychain` keyword to define further parameters for the relay chain at start-up. The available keys are: +- **`default_command?`** ++"string"++: The default command to run. Defaults to `polkadot`. +- **`default_image?`** ++"string"++: The default Docker image to use. +- **`default_resources?`** ++"Resources"++: Represents the resource limits/reservations the nodes need by default. Only available on Kubernetes. ---- + ??? child "`Resources` interface definition" + ```js + export interface Resources { + resources: { + requests?: { + memory?: string; + cpu?: string; + }; + limits?: { + memory?: string; + cpu?: string; + }; + }; + } + ``` -Page Title: Polkadart +- **`default_db_snapshot?`** ++"string"++: The default database snapshot to use. +- **`default_prometheus_prefix`** ++"string"++: A parameter for customizing the metric's prefix. Defaults to `substrate`. +- **`default_substrate_cli_args_version?`** ++"SubstrateCliArgsVersion"++: Set the Substrate CLI arguments version. -- Source (raw): https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/reference-tools-polkadart.md -- Canonical (HTML): https://docs.polkadot.com/reference/tools/polkadart/ -- Summary: Polkadart is a type-safe, native Dart, SDK for Polkadot and any compatible Polkadot-SDK blockchain network. + ??? child "`SubstrateCliArgsVersion` enum definition" + ```js + export enum SubstrateCliArgsVersion { + V0 = 0, + V1 = 1, + V2 = 2, + V3 = 3, + } + ``` -# Polkadart +- **`default_keystore_key_types?`** ++"string[]"++: Defines which keystore keys should be created. +- **`chain`** ++"string"++: The chain name. +- **`chain_spec_path?`** ++"string"++: Path to the chain spec file. Should be the plain version to allow customizations. +- **`chain_spec_command?`** ++"string"++: Command to generate the chain spec. It can't be used in combination with `chain_spec_path`. +- **`default_args?`** ++"string[]"++: An array of arguments to use as default to pass to the command. +- **`default_overrides?`** ++"Override[]"++: An array of overrides to upload to the node. -Polkadart is the most comprehensive Dart/Flutter SDK for interacting with Polkadot, Substrate, and other compatible blockchain networks. Designed with a Dart-first approach and type-safe APIs, it provides everything developers need to build powerful decentralized applications. + ??? child "`Override` interface definition" + ```js + export interface Override { + local_path: string; + remote_name: string; + } + ``` -This page will outline some of the core components of Polkadart. For more details, refer to the [official documentation](https://polkadart.dev){target=\_blank}. +- **`random_nominators_count?`** ++"number"++: If set and the stacking pallet is enabled, Zombienet will generate the input quantity of nominators and inject them into the genesis. +- **`max_nominations`** ++"number"++: The max number of nominations allowed by a nominator. Should match the value set in the runtime. Defaults to `24`. +- **`nodes?`** ++"Node[]"++: An array of nodes to spawn. It is further defined in the [Node Configuration](#node-configuration) section. +- **`node_groups?`** ++"NodeGroup[]"++: An array of node groups to spawn. It is further defined in the [Node Group Configuration](#node-group-configuration) section. +- **`total_node_in_group?`** ++"number"++: The total number of nodes in the group. Defaults to `1`. +- **`genesis`** ++"JSON"++: The genesis configuration. +- **`default_delay_network_settings?`** ++"DelayNetworkSettings"++: Sets the expected configuration to delay the network. -## Installation + ??? child "`DelayNetworkSettings` interface definition" + ```js + export interface DelayNetworkSettings { + latency: string; + correlation?: string; // should be parsable as float by k8s + jitter?: string; + } + ``` -Add Polkadart to your `pubspec.yaml`: +#### Node Configuration -=== "All packages" +One specific key capable of receiving more subkeys is the `nodes` key. This key is used to define further parameters for the nodes. The available keys: - ```bash - dart pub add polkadart polkadart_cli polkadart_keyring polkadart_scale_codec secp256k1_ecdsa sr25519 ss58 substrate_bip39 substrate_metadata - ``` - -=== "Core only" - - ```bash - dart pub add polkadart polkadart_cli polkadart_keyring - ``` - -For type-safe API generation, add the following to your `pubspec.yaml`: - -{% raw %} -```yaml title="pubspec.yaml" -polkadart: - output_dir: lib/generated - chains: - polkadot: wss://rpc.polkadot.io - kusama: wss://kusama-rpc.polkadot.io - custom: wss://your-node.example.com -``` -{% endraw %} - -## Get Started - -### Type Generation - -Polkadart provides a CLI tool to generate type definitions from any Polkadot-SDK compatible blockchain network. This allows you to build type-safe Dart applications without dealing with the low-level details of the blockchain. - -### Run Generator - -```bash -dart run polkadart_cli:generate -v -``` - -### Use Generated Types - -```dart -import 'package:your_app/generated/polkadot/polkadot.dart'; -import 'package:polkadart/polkadart.dart'; -import 'package:ss58/ss58.dart'; - -final provider = Provider.fromUri(Uri.parse('wss://rpc.polkadot.io')); -final polkadot = Polkadot(provider); - -// Account from SS58 address -final account = Address.decode('19t9Q2ay58hMDaeg6eeBhqmHsRnc2jDMV3cYYw9zbc59HLj'); - -// Retrieve Account Balance -final accountInfo = await polkadot.query.system.account(account.pubkey); -print('Balance: ${accountInfo.data.free}') -``` - -### Creating an API Instance - -An API instance is required to interact with the blockchain. Polkadart provides a `Provider` class that allows you to connect to any network. - -```dart -import 'package:demo/generated/polkadot/polkadot.dart'; -import 'package:polkadart/provider.dart'; - -Future main(List arguments) async { - final provider = Provider.fromUri(Uri.parse('wss://rpc.polkadot.io')); - final polkadot = Polkadot(provider); -} -``` - -### Reading Chain Data - -Besides querying the data using the `query` from the generated API, you can also use the State API for querying storage data, metadata, runtime information, and other chain information. - -```dart -final stateApi = StateApi(provider); - -// Get current runtime version -final runtimeVersion = await stateApi.getRuntimeVersion(); -print(runtimeVersion.toJson()); - -// Get metadata -final metadata = await stateApi.getMetadata(); -print('Metadata version: ${metadata.version}'); -``` - -### Subscribe to New Blocks - -You can subscribe to new blocks on the blockchain using the `subscribe` method. - -```dart -final subscription = await provider.subscribe('chain_subscribeNewHeads', []); - -subscription.stream.forEach((response) { - print('New head: ${response.result}'); -}); -``` - -### Send a Transaction - -Perhaps the most common operation done in any blockchain is transferring funds. Here you can see how that can be done using Polkadart: - -```dart -final wallet = await KeyPair.sr25519.fromUri("//Alice"); -print('Alice\' wallet: ${wallet.address}'); - -// Get information necessary to build a proper extrinsic -final runtimeVersion = await polkadot.rpc.state.getRuntimeVersion(); -final currentBlockNumber = (await polkadot.query.system.number()) - 1; -final currentBlockHash = await polkadot.query.system.blockHash(currentBlockNumber); -final genesisHash = await polkadot.query.system.blockHash(0); -final nonce = await polkadot.rpc.system.accountNextIndex(wallet.address); - -// Make the encoded call -final multiAddress = $MultiAddress().id(wallet.publicKey.bytes); -final transferCall = polkadot.tx.balances.transferKeepAlive(dest: multiAddress, value: BigInt.one).encode(); - -// Make the payload -final payload = SigningPayload( - method: transferCall, - specVersion: runtimeVersion.specVersion, - transactionVersion: runtimeVersion.transactionVersion, - genesisHash: encodeHex(genesisHash), - blockHash: encodeHex(currentBlockHash), - blockNumber: currentBlockNumber, - eraPeriod: 64, - nonce: nonce, - tip: 0, -).encode(polkadot.registry); - -// Sign the payload and build the final extrinsic -final signature = wallet.sign(payload); -final extrinsic = ExtrinsicPayload( - signer: wallet.bytes(), - method: transferCall, - signature: signature, - eraPeriod: 64, - blockNumber: currentBlockNumber, - nonce: nonce, - tip: 0, -).encode(polkadot.registry, SignatureType.sr25519); - -// Send the extrinsic to the blockchain -final author = AuthorApi(provider); -await author.submitAndWatchExtrinsic(extrinsic, (data) { - print(data); -}); -``` - -## Where to Go Next - -To dive deeper into Polkadart, refer to the [official Polkadart documentation](https://polkadart.dev/){target=\_blank}, where you can find comprehensive guides for common use cases and advanced usage. - - ---- - -Page Title: Polkadot Omni Node - -- Source (raw): https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/reference-tools-omninode.md -- Canonical (HTML): https://docs.polkadot.com/reference/tools/omninode/ -- Summary: Run parachain nodes easily with the polkadot-omni-node, a white-labeled binary that can run parachain nodes using a single pre-built solution. - -# Polkadot Omni Node - -## Introduction - -The [`polkadot-omni-node`](https://crates.io/crates/polkadot-omni-node/0.7.0){target=\_blank} crate is a versatile, pre-built binary designed to simplify running parachains in the Polkadot ecosystem. Unlike traditional node binaries that are tightly coupled to specific runtime code, the `polkadot-omni-node` operates using an external [chain specification](/polkadot-protocol/glossary#chain-specification){target=\_blank} file, allowing it to adapt dynamically to different parachains. - -This approach enables it to act as a white-labeled node binary, capable of running most parachains that do not require custom node-level logic or extensions. Developers can leverage this flexibility to test, deploy, or operate parachain nodes without maintaining a dedicated codebase for each network. - -This guide provides step-by-step instructions for installing the `polkadot-omni-node`, obtaining a chain specification, and spinning up a parachain node. - -## Prerequisites - -Before getting started, ensure you have the following prerequisites: - -- **[Rust](https://rust-lang.org/tools/install/){target=\_blank}**: Required to build and install the `polkadot-omni-node` binary. - -Ensure Rust's `cargo` command is available in your terminal by running: - -```bash -cargo --version -``` - -## Install Polkadot Omni Node - -To install `polkadot-omni-node` globally using `cargo`, run: - -```bash -cargo install --locked polkadot-omni-node@0.7.0 -``` - -This command downloads and installs version 0.7.0 of the binary, making it available system-wide. - -To confirm the installation, run: - -```bash -polkadot-omni-node --version -``` - -You should see the installed version number printed to the terminal, confirming a successful installation. - -## Obtain Chain Specifications - -The `polkadot-omni-node` binary uses a chain specification file to configure and launch a parachain node. This file defines the parachain's genesis state and network settings. - -The most common source for official chain specifications is the [`paritytech/chainspecs`](https://github.com/paritytech/chainspecs){target=\_blank} repository. These specifications are also browsable in a user-friendly format via the [Chainspec Collection](https://paritytech.github.io/chainspecs/){target=\_blank} website. - -To obtain a chain specification: - -1. Visit the [Chainspec Collection](https://paritytech.github.io/chainspecs/){target=\_blank} website. -2. Find the parachain you want to run. -3. Click the chain spec to open it. -4. Copy the JSON content and save it locally as a `.json` file, e.g., `chain_spec.json`. - -## Run a Parachain Full Node - -Once you've installed `polkadot-omni-node` and saved the appropriate chain specification file, you can start a full node for your chosen parachain. - -To see all available flags and configuration options, run: - -```bash -polkadot-omni-node --help -``` - -To launch the node, run the following command, replacing `./INSERT_PARACHAIN_CHAIN_SPEC.json` with the actual path to your saved chain spec file. - -This command will: - -- Load the chain specification. -- Initialize the node using the provided network configuration. -- Begin syncing with the parachain network. - -```bash -polkadot-omni-node --chain ./INSERT_PARACHAIN_CHAIN_SPEC.json --sync warp -``` - -- The `--chain` flag tells the `polkadot-omni-node` which parachain to run by pointing to its chain specification file. -- The `--sync warp` flag enables warp sync, allowing the node to quickly catch up to the latest finalized state. Historical blocks are fetched in the background as the node continues operating. - -Once started, the node will begin connecting to peers and syncing with the network. You’ll see logs in your terminal reflecting its progress. - -## Interact with the Node - -By default, `polkadot-omni-node` exposes a WebSocket endpoint at `ws://localhost:9944`, which you can use to interact with the running node. You can connect using: - -- **[Polkadot.js Apps](https://polkadot.js.org/apps/#/explorer){target=\_blank}**: A web-based interface for exploring and interacting with Polkadot SDK-based chains. -- Custom scripts using compatible [libraries](/develop/toolkit/api-libraries/){target=\_blank}. - -Once connected, you can review blocks, call extrinsics, inspect storage, and interact with the runtime. - -## Parachain Compatibility - -The `polkadot-omni-node` is designed to work with most parachains out of the box; however, your parachain's runtime must meet specific requirements and follow certain conventions to be compatible. This section outlines what your runtime needs to implement and configure to work seamlessly with the `polkadot-omni-node`: - -- Your runtime must implement the required runtime APIs (see below). -- Your runtime must include and configure the required pallets. - -The [`parachain-template`](https://github.com/paritytech/polkadot-sdk-parachain-template/tree/v0.0.4){target=_blank} provides a complete reference implementation that is fully compatible with the `polkadot-omni-node`. You can use it as a starting point or reference for ensuring your runtime meets all compatibility requirements. - -### Required Runtime APIs - -Your parachain runtime must implement the following runtime APIs for the `polkadot-omni-node` to function properly: - -- **GetParachainInfo Runtime API**: The omni-node requires the [`GetParachainInfo`](https://paritytech.github.io/polkadot-sdk/master/cumulus_primitives_core/trait.GetParachainInfo.html){target=\_blank} runtime API to identify and configure the parachain correctly. This API provides the parachain ID to the node. +- **`name`** ++"string"++: Name of the node. Any whitespace will be replaced with a dash (for example, `new alice` will be converted to `new-alice`). +- **`image?`** ++"string"++: Override default Docker image to use for this node. +- **`command?`** ++"string"++: Override default command to run. +- **`command_with_args?`** ++"string"++: Override default command and arguments. +- **`args?`** ++"string[]"++: Arguments to be passed to the command. +- **`env?`** ++"envVars[]"++: Environment variables to set in the container. - ```rust title="runtime/src/apis.rs" - impl cumulus_primitives_core::GetParachainInfo for Runtime { - fn parachain_id() -> cumulus_primitives_core::ParaId { - // Return your parachain ID - ParachainInfo::parachain_id() + ??? child "`envVars` interface definition" + ```js + export interface EnvVars { + name: string; + value: string; } - } - ``` - -- **Aura Runtime API**: For consensus, the `polkadot-omni-node` expects the [Aura runtime API](https://paritytech.github.io/polkadot-sdk/master/polkadot_sdk_frame/runtime/apis/trait.AuraApi.html){target=\_blank} to be implemented. + ``` - ```rust title="runtime/src/apis.rs" - impl sp_consensus_aura::AuraApi for Runtime { - fn slot_duration() -> sp_consensus_aura::SlotDuration { - sp_consensus_aura::SlotDuration::from_millis(SLOT_DURATION) - } +- **`prometheus_prefix?`** ++"string"++: Customizes the metric's prefix for the specific node. Defaults to `substrate`. +- **`db_snapshot?`** ++"string"++: Database snapshot to use. +- **`substrate_cli_args_version?`** ++"SubstrateCliArgsVersion"++: Set the Substrate CLI arguments version directly to skip binary evaluation overhead. - fn authorities() -> Vec { - Aura::authorities().into_inner() + ??? child "`SubstrateCliArgsVersion` enum definition" + ```js + export enum SubstrateCliArgsVersion { + V0 = 0, + V1 = 1, + V2 = 2, + V3 = 3, } - } - ``` - -### Required Pallets - -Your runtime must include and properly configure the following pallets: - -- **System Pallet**: The System pallet ([`frame-system`](https://paritytech.github.io/polkadot-sdk/master/polkadot_sdk_frame/prelude/frame_system/index.html){target=\_blank}) is fundamental and must be configured with appropriate types. - - ```rust title="runtime/src/lib.rs" - #[frame_support::runtime] - impl frame_system::Config for Runtime { - type Block = Block; - type BlockNumber = BlockNumber; - // ... other configurations - } - - // Must be named "System" for omni-node compatibility - pub type System = frame_system::Pallet; - ``` - -- **ParachainSystem Pallet**: This pallet ([`cumulus-pallet-parachain-system`](https://paritytech.github.io/polkadot-sdk/master/cumulus_pallet_parachain_system/index.html){target=\_blank}) enables parachain functionality and handles low-level details of being a parachain. - - ```rust title="runtime/src/lib.rs" - impl cumulus_pallet_parachain_system::Config for Runtime { - type RuntimeEvent = RuntimeEvent; - type OnSystemEvent = (); - // ... other configurations - } - - // Must be named "ParachainSystem" for omni-node compatibility - pub type ParachainSystem = cumulus_pallet_parachain_system::Pallet; - ``` - -- **Aura Pallet**: For block authoring consensus ([`pallet-aura`](https://paritytech.github.io/polkadot-sdk/master/pallet_aura/index.html){target=\_blank}). - - ```rust title="runtime/src/lib.rs" - impl pallet_aura::Config for Runtime { - type AuthorityId = AuraId; - type DisabledValidators = (); - type MaxAuthorities = MaxAuthorities; - type AllowMultipleBlocksPerSlot = ConstBool; - } - - pub type Aura = pallet_aura::Pallet; - ``` - -- **ParachainInfo Pallet**: Provides parachain metadata ([`parachain-info`](https://paritytech.github.io/polkadot-sdk/master/staging_parachain_info/index.html){target=\_blank}). - - ```rust title="runtime/src/lib.rs" - impl parachain_info::Config for Runtime {} - - pub type ParachainInfo = parachain_info::Pallet; - ``` - -If you're migrating an existing parachain to use the `polkadot-omni-node`, you may need to perform runtime upgrades to add the required runtime APIs and pallets. Follow the standard parachain [runtime upgrade](/parachains/runtime-maintenance/runtime-upgrades/){target=\_blank} procedures to implement these changes on your live network. - - ---- - -Page Title: Polkadot SDK Accounts - -- Source (raw): https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/reference-parachains-accounts.md -- Canonical (HTML): https://docs.polkadot.com/reference/parachains/accounts/ -- Summary: Learn about account structures, balances, and address formats in the Polkadot SDK, including how to manage lifecycle, references, and balances. - -# Accounts - -## Introduction - -Accounts are essential for managing identity, transactions, and governance on the network in the Polkadot SDK. Understanding these components is critical for seamless development and operation on the network, whether you're building or interacting with Polkadot-based chains. - -This page will guide you through the essential aspects of accounts, including their data structure, balance types, reference counters, and address formats. You’ll learn how accounts are managed within the runtime, how balances are categorized, and how addresses are encoded and validated. - -## Account Data Structure - -Accounts are foundational to any blockchain, and the Polkadot SDK provides a flexible management system. This section explains how the Polkadot SDK defines accounts and manages their lifecycle through data structures within the runtime. - -### Account - -The [`Account` data type](https://paritytech.github.io/polkadot-sdk/master/frame_system/pallet/type.Account.html){target=\_blank} is a storage map within the [System pallet](https://paritytech.github.io/polkadot-sdk/master/src/frame_system/lib.rs.html){target=\_blank} that links an account ID to its corresponding data. This structure is fundamental for mapping account-related information within the chain. - -The code snippet below shows how accounts are defined: - -```rs - /// The full account information for a particular account ID. - #[pallet::storage] - #[pallet::getter(fn account)] - pub type Account = StorageMap< - _, - Blake2_128Concat, - T::AccountId, - AccountInfo, - ValueQuery, - >; -``` - -The preceding code block defines a storage map named `Account`. The `StorageMap` is a type of on-chain storage that maps keys to values. In the `Account` map, the key is an account ID, and the value is the account's information. Here, `T` represents the generic parameter for the runtime configuration, which is defined by the pallet's configuration trait (`Config`). - -The `StorageMap` consists of the following parameters: - -- **`_`**: Used in macro expansion and acts as a placeholder for the storage prefix type. Tells the macro to insert the default prefix during expansion. -- **`Blake2_128Concat`**: The hashing function applied to keys in the storage map. -- **`T: :AccountId`**: Represents the key type, which corresponds to the account’s unique ID. -- **`AccountInfo`**: The value type stored in the map. For each account ID, the map stores an `AccountInfo` struct containing: - - - **`T::Nonce`**: A nonce for the account, which is incremented with each transaction to ensure transaction uniqueness. - - **`T: :AccountData`**: Custom account data defined by the runtime configuration, which could include balances, locked funds, or other relevant information. - -- **`ValueQuery`**: Defines how queries to the storage map behave when no value is found; returns a default value instead of `None`. - -For a detailed explanation of storage maps, see the [`StorageMap`](https://paritytech.github.io/polkadot-sdk/master/frame_support/storage/types/struct.StorageMap.html){target=\_blank} entry in the Rust docs. - -### Account Info - -The `AccountInfo` structure is another key element within the [System pallet](https://paritytech.github.io/polkadot-sdk/master/src/frame_system/lib.rs.html){target=\_blank}, providing more granular details about each account's state. This structure tracks vital data, such as the number of transactions and the account’s relationships with other modules. - -```rs -/// Information of an account. -#[derive(Clone, Eq, PartialEq, Default, RuntimeDebug, Encode, Decode, TypeInfo, MaxEncodedLen)] -pub struct AccountInfo { - /// The number of transactions this account has sent. - pub nonce: Nonce, - /// The number of other modules that currently depend on this account's existence. The account - /// cannot be reaped until this is zero. - pub consumers: RefCount, - /// The number of other modules that allow this account to exist. The account may not be reaped - /// until this and `sufficients` are both zero. - pub providers: RefCount, - /// The number of modules that allow this account to exist for their own purposes only. The - /// account may not be reaped until this and `providers` are both zero. - pub sufficients: RefCount, - /// The additional data that belongs to this account. Used to store the balance(s) in a lot of - /// chains. - pub data: AccountData, -} -``` - -The `AccountInfo` structure includes the following components: - -- **`nonce`**: Tracks the number of transactions initiated by the account, which ensures transaction uniqueness and prevents replay attacks. -- **`consumers`**: Counts how many other modules or pallets rely on this account’s existence. The account cannot be removed from the chain (reaped) until this count reaches zero. -- **`providers`**: Tracks how many modules permit this account’s existence. An account can only be reaped once both `providers` and `sufficients` are zero. -- **`sufficients`**: Represents the number of modules that allow the account to exist for internal purposes, independent of any other modules. -- **`AccountData`**: A flexible data structure that can be customized in the runtime configuration, usually containing balances or other user-specific data. - -This structure helps manage an account's state and prevents its premature removal while it is still referenced by other on-chain data or modules. The [`AccountInfo`](https://paritytech.github.io/polkadot-sdk/master/frame_system/struct.AccountInfo.html){target=\_blank} structure can vary as long as it satisfies the trait bounds defined by the `AccountData` associated type in the [`frame-system::pallet::Config`](https://paritytech.github.io/polkadot-sdk/master/frame_system/pallet/trait.Config.html){target=\_blank} trait. - -### Account Reference Counters - -Polkadot SDK uses reference counters to track an account’s dependencies across different runtime modules. These counters ensure that accounts remain active while data is associated with them. - -The reference counters include: - -- **`consumers`**: Prevents account removal while other pallets still rely on the account. -- **`providers`**: Ensures an account is active before other pallets store data related to it. -- **`sufficients`**: Indicates the account’s independence, ensuring it can exist even without a native token balance, such as when holding sufficient alternative assets. - -#### Providers Reference Counters - -The `providers` counter ensures that an account is ready to be depended upon by other runtime modules. For example, it is incremented when an account has a balance above the existential deposit, which marks the account as active. - -The system requires this reference counter to be greater than zero for the `consumers` counter to be incremented, ensuring the account is stable before any dependencies are added. - -#### Consumers Reference Counters - -The `consumers` counter ensures that the account cannot be reaped until all references to it across the runtime have been removed. This check prevents the accidental deletion of accounts that still have active on-chain data. - -It is the user’s responsibility to clear out any data from other runtime modules if they wish to remove their account and reclaim their existential deposit. - -#### Sufficients Reference Counter - -The `sufficients` counter tracks accounts that can exist independently without relying on a native account balance. This is useful for accounts holding other types of assets, like tokens, without needing a minimum balance in the native token. - -For instance, the [Assets pallet](https://paritytech.github.io/polkadot-sdk/master/pallet_assets/index.html){target=\_blank}, may increment this counter for an account holding sufficient tokens. - -#### Account Deactivation - -In Polkadot SDK-based chains, an account is deactivated when its reference counters (such as `providers`, `consumers`, and `sufficient`) reach zero. These counters ensure the account remains active as long as other runtime modules or pallets reference it. - -When all dependencies are cleared and the counters drop to zero, the account becomes deactivated and may be removed from the chain (reaped). This is particularly important in Polkadot SDK-based blockchains, where accounts with balances below the existential deposit threshold are pruned from storage to conserve state resources. - -Each pallet that references an account has cleanup functions that decrement these counters when the pallet no longer depends on the account. Once these counters reach zero, the account is marked for deactivation. - -#### Updating Counters - -The Polkadot SDK provides runtime developers with various methods to manage account lifecycle events, such as deactivation or incrementing reference counters. These methods ensure that accounts cannot be reaped while still in use. - -The following helper functions manage these counters: - -- **`inc_consumers()`**: Increments the `consumer` reference counter for an account, signaling that another pallet depends on it. -- **`dec_consumers()`**: Decrements the `consumer` reference counter, signaling that a pallet no longer relies on the account. -- **`inc_providers()`**: Increments the `provider` reference counter, ensuring the account remains active. -- **`dec_providers()`**: Decrements the `provider` reference counter, allowing for account deactivation when no longer in use. -- **`inc_sufficients()`**: Increments the `sufficient` reference counter for accounts that hold sufficient assets. -- **`dec_sufficients()`**: Decrements the `sufficient` reference counter. - -To ensure proper account cleanup and lifecycle management, a corresponding decrement should be made for each increment action. - -The `System` pallet offers three query functions to assist developers in tracking account states: - -- **[`can_inc_consumer()`](https://paritytech.github.io/polkadot-sdk/master/frame_system/pallet/struct.Pallet.html#method.can_inc_consumer){target=\_blank}**: Checks if the account can safely increment the consumer reference. -- **[`can_dec_provider()`](https://paritytech.github.io/polkadot-sdk/master/frame_system/pallet/struct.Pallet.html#method.can_dec_provider){target=\_blank}**: Ensures that no consumers exist before allowing the decrement of the provider counter. -- **[`is_provider_required()`](https://paritytech.github.io/polkadot-sdk/master/frame_system/pallet/struct.Pallet.html#method.is_provider_required){target=\_blank}**: Verifies whether the account still has any active consumer references. - -This modular and flexible system of reference counters tightly controls the lifecycle of accounts in Polkadot SDK-based blockchains, preventing the accidental removal or retention of unneeded accounts. You can refer to the [System pallet Rust docs](https://paritytech.github.io/polkadot-sdk/master/frame_system/pallet/struct.Pallet.html){target=\_blank} for more details. - - -## Account Balance Types - -In the Polkadot ecosystem, account balances are categorized into different types based on how the funds are utilized and their availability. These balance types determine the actions that can be performed, such as transferring tokens, paying transaction fees, or participating in governance activities. Understanding these balance types helps developers manage user accounts and implement balance-dependent logic. - -!!! note "A more efficient distribution of account balance types is in development" - Soon, pallets in the Polkadot SDK will implement the [`Fungible` trait](https://paritytech.github.io/polkadot-sdk/master/frame_support/traits/tokens/fungible/index.html){target=\_blank} (see the [tracking issue](https://github.com/paritytech/polkadot-sdk/issues/226){target=\_blank} for more details). For example, the [`transaction-storage`](https://paritytech.github.io/polkadot-sdk/master/pallet_transaction_storage/index.html){target=\_blank} pallet changed the implementation of the [`Currency`](https://paritytech.github.io/polkadot-sdk/master/frame_support/traits/tokens/currency/index.html){target=\_blank} trait (see the [Refactor transaction storage pallet to use fungible traits](https://github.com/paritytech/polkadot-sdk/pull/1800){target=\_blank} PR for further details): - - ```rust - type BalanceOf = <::Currency as Currency<::AccountId>>::Balance; - ``` - - To the [`Fungible`](https://paritytech.github.io/polkadot-sdk/master/frame_support/traits/tokens/fungible/index.html){target=\_blank} trait: - - ```rust - type BalanceOf = <::Currency as FnInspect<::AccountId>>::Balance; - ``` - - This update will enable more efficient use of account balances, allowing the free balance to be utilized for on-chain activities such as setting proxies and managing identities. - -### Balance Types - -The five main balance types are: - -- **Free balance**: Represents the total tokens available to the account for any on-chain activity, including staking, governance, and voting. However, it may not be fully spendable or transferrable if portions of it are locked or reserved. -- **Locked balance**: Portions of the free balance that cannot be spent or transferred because they are tied up in specific activities like [staking](https://wiki.polkadot.com/learn/learn-staking/#nominating-validators){target=\_blank}, [vesting](https://wiki.polkadot.com/learn/learn-guides-transfers/#vested-transfers-with-the-polkadot-js-ui){target=\_blank}, or participating in [governance](https://wiki.polkadot.com/learn/learn-polkadot-opengov/#voting-on-a-referendum){target=\_blank}. While the tokens remain part of the free balance, they are non-transferable for the duration of the lock. -- **Reserved balance**: Funds locked by specific system actions, such as setting up an [identity](https://wiki.polkadot.com/learn/learn-identity/){target=\_blank}, creating [proxies](https://wiki.polkadot.com/learn/learn-proxies/){target=\_blank}, or submitting [deposits for governance proposals](https://wiki.polkadot.com/learn/learn-guides-polkadot-opengov/#claiming-opengov-deposits){target=\_blank}. These tokens are not part of the free balance and cannot be spent unless they are unreserved. -- **Spendable balance**: The portion of the free balance that is available for immediate spending or transfers. It is calculated by subtracting the maximum of locked or reserved amounts from the free balance, ensuring that existential deposit limits are met. -- **Untouchable balance**: Funds that cannot be directly spent or transferred but may still be utilized for on-chain activities, such as governance participation or staking. These tokens are typically tied to certain actions or locked for a specific period. - -The spendable balance is calculated as follows: - -```text -spendable = free - max(locked - reserved, ED) -``` - -Here, `free`, `locked`, and `reserved` are defined above. The `ED` represents the [existential deposit](https://wiki.polkadot.com/learn/learn-accounts/#existential-deposit-and-reaping){target=\_blank}, the minimum balance required to keep an account active and prevent it from being reaped. You may find you can't see all balance types when looking at your account via a wallet. Wallet providers often display only spendable, locked, and reserved balances. - -### Locks - -Locks are applied to an account's free balance, preventing that portion from being spent or transferred. Locks are automatically placed when an account participates in specific on-chain activities, such as staking or governance. Although multiple locks may be applied simultaneously, they do not stack. Instead, the largest lock determines the total amount of locked tokens. - -Locks follow these basic rules: - -- If different locks apply to varying amounts, the largest lock amount takes precedence. -- If multiple locks apply to the same amount, the lock with the longest duration governs when the balance can be unlocked. - -#### Locks Example - -Consider an example where an account has 80 DOT locked for both staking and governance purposes like so: - -- 80 DOT is staked with a 28-day lock period. -- 24 DOT is locked for governance with a 1x conviction and a 7-day lock period. -- 4 DOT is locked for governance with a 6x conviction and a 224-day lock period. - -In this case, the total locked amount is 80 DOT because only the largest lock (80 DOT from staking) governs the locked balance. These 80 DOT will be released at different times based on the lock durations. In this example, the 24 DOT locked for governance will be released first since the shortest lock period is seven days. The 80 DOT stake with a 28-day lock period is released next. Now, all that remains locked is the 4 DOT for governance. After 224 days, all 80 DOT (minus the existential deposit) will be free and transferable. - -![Illustration of Lock Example](/images/reference/parachains/accounts/accounts-01.webp) + ``` -#### Edge Cases for Locks +- **`resources?`** ++"Resources"++: Represent the resources limits/reservations needed by the node. -In scenarios where multiple convictions and lock periods are active, the lock duration and amount are determined by the longest period and largest amount. For example, if you delegate with different convictions and attempt to undelegate during an active lock period, the lock may be extended for the full amount of tokens. For a detailed discussion on edge case lock behavior, see this [Stack Exchange post](https://substrate.stackexchange.com/questions/5067/delegating-and-undelegating-during-the-lock-period-extends-it-for-the-initial-am){target=\_blank}. + ??? child "`Resources` interface definition" + ```js + export interface Resources { + resources: { + requests?: { + memory?: string; + cpu?: string; + }; + limits?: { + memory?: string; + cpu?: string; + }; + }; + } + ``` -### Balance Types on Polkadot.js - -Polkadot.js provides a user-friendly interface for managing and visualizing various account balances on Polkadot and Kusama networks. When interacting with Polkadot.js, you will encounter multiple balance types that are critical for understanding how your funds are distributed and restricted. This section explains how different balances are displayed in the Polkadot.js UI and what each type represents. - -![](/images/reference/parachains/accounts/accounts-02.webp) - -The most common balance types displayed on Polkadot.js are: - -- **Total balance**: The total number of tokens available in the account. This includes all tokens, whether they are transferable, locked, reserved, or vested. However, the total balance does not always reflect what can be spent immediately. In this example, the total balance is 0.6274 KSM. - -- **Transferable balance**: Shows how many tokens are immediately available for transfer. It is calculated by subtracting the locked and reserved balances from the total balance. For example, if an account has a total balance of 0.6274 KSM and a transferable balance of 0.0106 KSM, only the latter amount can be sent or spent freely. - -- **Vested balance**: Tokens that allocated to the account but released according to a specific schedule. Vested tokens remain locked and cannot be transferred until fully vested. For example, an account with a vested balance of 0.2500 KSM means that this amount is owned but not yet transferable. - -- **Locked balance**: Tokens that are temporarily restricted from being transferred or spent. These locks typically result from participating in staking, governance, or vested transfers. In Polkadot.js, locked balances do not stack—only the largest lock is applied. For instance, if an account has 0.5500 KSM locked for governance and staking, the locked balance would display 0.5500 KSM, not the sum of all locked amounts. - -- **Reserved balance**: Refers to tokens locked for specific on-chain actions, such as setting an identity, creating a proxy, or making governance deposits. Reserved tokens are not part of the free balance, but can be freed by performing certain actions. For example, removing an identity would unreserve those funds. - -- **Bonded balance**: The tokens locked for staking purposes. Bonded tokens are not transferable until they are unbonded after the unbonding period. - -- **Redeemable balance**: The number of tokens that have completed the unbonding period and are ready to be unlocked and transferred again. For example, if an account has a redeemable balance of 0.1000 KSM, those tokens are now available for spending. - -- **Democracy balance**: Reflects the number of tokens locked for governance activities, such as voting on referenda. These tokens are locked for the duration of the governance action and are only released after the lock period ends. - -By understanding these balance types and their implications, developers and users can better manage their funds and engage with on-chain activities more effectively. - -## Address Formats - -The SS58 address format is a core component of the Polkadot SDK that enables accounts to be uniquely identified across Polkadot-based networks. This format is a modified version of Bitcoin's Base58Check encoding, specifically designed to accommodate the multi-chain nature of the Polkadot ecosystem. SS58 encoding allows each chain to define its own set of addresses while maintaining compatibility and checksum validation for security. - -### Basic Format - -SS58 addresses consist of three main components: - -```text -base58encode(concat(,
, )) -``` - -- **Address type**: A byte or set of bytes that define the network (or chain) for which the address is intended. This ensures that addresses are unique across different Polkadot SDK-based chains. -- **Address**: The public key of the account encoded as bytes. -- **Checksum**: A hash-based checksum which ensures that addresses are valid and unaltered. The checksum is derived from the concatenated address type and address components, ensuring integrity. - -The encoding process transforms the concatenated components into a Base58 string, providing a compact and human-readable format that avoids easily confused characters (e.g., zero '0', capital 'O', lowercase 'l'). This encoding function ([`encode`](https://docs.rs/bs58/latest/bs58/fn.encode.html){target=\_blank}) is implemented exactly as defined in Bitcoin and IPFS specifications, using the same alphabet as both implementations. - -For more details about the SS58 address format implementation, see the [`Ss58Codec`](https://paritytech.github.io/polkadot-sdk/master/sp_core/crypto/trait.Ss58Codec.html){target=\_blank} trait in the Rust Docs. - -### Address Type - -The address type defines how an address is interpreted and to which network it belongs. Polkadot SDK uses different prefixes to distinguish between various chains and address formats: - -- **Address types `0-63`**: Simple addresses, commonly used for network identifiers. -- **Address types `64-127`**: Full addresses that support a wider range of network identifiers. -- **Address types `128-255`**: Reserved for future address format extensions. - -For example, Polkadot’s main network uses an address type of 0, while Kusama uses 2. This ensures that addresses can be used without confusion between networks. - -The address type is always encoded as part of the SS58 address, making it easy to quickly identify the network. Refer to the [SS58 registry](https://github.com/paritytech/ss58-registry){target=\_blank} for the canonical listing of all address type identifiers and how they map to Polkadot SDK-based networks. - -### Address Length - -SS58 addresses can have different lengths depending on the specific format. Address lengths range from as short as 3 to 35 bytes, depending on the complexity of the address and network requirements. This flexibility allows SS58 addresses to adapt to different chains while providing a secure encoding mechanism. - -| Total | Type | Raw account | Checksum | -|-------|------|-------------|----------| -| 3 | 1 | 1 | 1 | -| 4 | 1 | 2 | 1 | -| 5 | 1 | 2 | 2 | -| 6 | 1 | 4 | 1 | -| 7 | 1 | 4 | 2 | -| 8 | 1 | 4 | 3 | -| 9 | 1 | 4 | 4 | -| 10 | 1 | 8 | 1 | -| 11 | 1 | 8 | 2 | -| 12 | 1 | 8 | 3 | -| 13 | 1 | 8 | 4 | -| 14 | 1 | 8 | 5 | -| 15 | 1 | 8 | 6 | -| 16 | 1 | 8 | 7 | -| 17 | 1 | 8 | 8 | -| 35 | 1 | 32 | 2 | - -SS58 addresses also support different payload sizes, allowing a flexible range of account identifiers. - -### Checksum Types - -A checksum is applied to validate SS58 addresses. Polkadot SDK uses a Blake2b-512 hash function to calculate the checksum, which is appended to the address before encoding. The checksum length can vary depending on the address format (e.g., 1-byte, 2-byte, or longer), providing varying levels of validation strength. - -The checksum ensures that an address is not modified or corrupted, adding an extra layer of security for account management. - -### Validating Addresses - -SS58 addresses can be validated using the subkey command-line interface or the Polkadot.js API. These tools help ensure an address is correctly formatted and valid for the intended network. The following sections will provide an overview of how validation works with these tools. - -#### Using Subkey - -[Subkey](https://paritytech.github.io/polkadot-sdk/master/subkey/index.html){target=\_blank} is a CLI tool provided by Polkadot SDK for generating and managing keys. It can inspect and validate SS58 addresses. - -The `inspect` command gets a public key and an SS58 address from the provided secret URI. The basic syntax for the `subkey inspect` command is: - -```bash -subkey inspect [flags] [options] uri -``` - -For the `uri` command-line argument, you can specify the secret seed phrase, a hex-encoded private key, or an SS58 address. If the input is a valid address, the `subkey` program displays the corresponding hex-encoded public key, account identifier, and SS58 addresses. - -For example, to inspect the public keys derived from a secret seed phrase, you can run a command similar to the following: - -```bash -subkey inspect "caution juice atom organ advance problem want pledge someone senior holiday very" -``` - -The command displays output similar to the following: - -
- subkey inspect "caution juice atom organ advance problem want pledge someone senior holiday very" - Secret phrase `caution juice atom organ advance problem want pledge someone senior holiday very` is account: - Secret seed: 0xc8fa03532fb22ee1f7f6908b9c02b4e72483f0dbd66e4cd456b8f34c6230b849 - Public key (hex): 0xd6a3105d6768e956e9e5d41050ac29843f98561410d3a47f9dd5b3b227ab8746 - Public key (SS58): 5Gv8YYFu8H1btvmrJy9FjjAWfb99wrhV3uhPFoNEr918utyR - Account ID: 0xd6a3105d6768e956e9e5d41050ac29843f98561410d3a47f9dd5b3b227ab8746 - SS58 Address: 5Gv8YYFu8H1btvmrJy9FjjAWfb99wrhV3uhPFoNEr918utyR -
- -The `subkey` program assumes an address is based on a public/private key pair. If you inspect an address, the command returns the 32-byte account identifier. - -However, not all addresses in Polkadot SDK-based networks are based on keys. - -Depending on the command-line options you specify and the input you provided, the command output might also display the network for which the address has been encoded. For example: - -```bash -subkey inspect "12bzRJfh7arnnfPPUZHeJUaE62QLEwhK48QnH9LXeK2m1iZU" -``` - -The command displays output similar to the following: - -
- subkey inspect "12bzRJfh7arnnfPPUZHeJUaE62QLEwhK48QnH9LXeK2m1iZU" - Public Key URI `12bzRJfh7arnnfPPUZHeJUaE62QLEwhK48QnH9LXeK2m1iZU` is account: - Network ID/Version: polkadot - Public key (hex): 0x46ebddef8cd9bb167dc30878d7113b7e168e6f0646beffd77d69d39bad76b47a - Account ID: 0x46ebddef8cd9bb167dc30878d7113b7e168e6f0646beffd77d69d39bad76b47a - Public key (SS58): 12bzRJfh7arnnfPPUZHeJUaE62QLEwhK48QnH9LXeK2m1iZU - SS58 Address: 12bzRJfh7arnnfPPUZHeJUaE62QLEwhK48QnH9LXeK2m1iZU -
- -#### Using Polkadot.js API - -To verify an address in JavaScript or TypeScript projects, you can use the functions built into the [Polkadot.js API](https://polkadot.js.org/docs/){target=\_blank}. For example: - -```js -// Import Polkadot.js API dependencies -const { decodeAddress, encodeAddress } = require('@polkadot/keyring'); -const { hexToU8a, isHex } = require('@polkadot/util'); - -// Specify an address to test. -const address = 'INSERT_ADDRESS_TO_TEST'; - -// Check address -const isValidSubstrateAddress = () => { - try { - encodeAddress(isHex(address) ? hexToU8a(address) : decodeAddress(address)); - - return true; - } catch (error) { - return false; - } -}; - -// Query result -const isValid = isValidSubstrateAddress(); -console.log(isValid); - -``` - -If the function returns `true`, the specified address is a valid address. - -#### Other SS58 Implementations - -Support for encoding and decoding Polkadot SDK SS58 addresses has been implemented in several other languages and libraries. - -- **Crystal**: [`wyhaines/base58.cr`](https://github.com/wyhaines/base58.cr){target=\_blank} -- **Go**: [`itering/subscan-plugin`](https://github.com/itering/subscan-plugin){target=\_blank} -- **Python**: [`polkascan/py-scale-codec`](https://github.com/polkascan/py-scale-codec){target=\_blank} -- **TypeScript**: [`subsquid/squid-sdk`](https://github.com/subsquid/squid-sdk){target=\_blank} - - ---- - -Page Title: Polkadot-API - -- Source (raw): https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/reference-tools-papi.md -- Canonical (HTML): https://docs.polkadot.com/reference/tools/papi/ -- Summary: Polkadot-API (PAPI) is a modular, composable library set designed for efficient interaction with Polkadot chains, prioritizing a "light-client first" approach. - -# Polkadot-API - -## Introduction - -[Polkadot-API](https://github.com/polkadot-api/polkadot-api){target=\_blank} (PAPI) is a set of libraries built to be modular, composable, and grounded in a “light-client first” approach. Its primary aim is to equip dApp developers with an extensive toolkit for building fully decentralized applications. - -PAPI is optimized for light-client functionality, using the new JSON-RPC spec to support decentralized interactions fully. It provides strong TypeScript support with types and documentation generated directly from on-chain metadata, and it offers seamless access to storage reads, constants, transactions, events, and runtime calls. Developers can connect to multiple chains simultaneously and prepare for runtime updates through multi-descriptor generation and compatibility checks. PAPI is lightweight and performant, leveraging native BigInt, dynamic imports, and modular subpaths to avoid bundling unnecessary assets. It supports promise-based and observable-based APIs, integrates easily with Polkadot.js extensions, and offers signing options through browser extensions or private keys. - -## Get Started - -### API Instantiation - -To instantiate the API, you can install the package by using the following command: - -=== "npm" - - ```bash - npm i polkadot-api@1.17.2 - ``` - -=== "pnpm" - - ```bash - pnpm add polkadot-api@1.17.2 - ``` - -=== "yarn" - - ```bash - yarn add polkadot-api@1.17.2 - ``` - -Then, obtain the latest metadata from the target chain and generate the necessary types: - -```bash -# Add the target chain -npx papi add dot -n polkadot -``` - -The `papi add` command initializes the library by generating the corresponding types needed for the chain used. It assigns the chain a custom name and specifies downloading metadata from the Polkadot chain. You can replace `dot` with the name you prefer or with another chain if you want to add a different one. Once the latest metadata is downloaded, generate the required types: - -```bash -# Generate the necessary types -npx papi -``` - -You can now set up a [`PolkadotClient`](https://github.com/polkadot-api/polkadot-api/blob/main/packages/client/src/types.ts#L153){target=\_blank} with your chosen provider to begin interacting with the API. Choose from Smoldot via WebWorker, Node.js, or direct usage, or connect through the WSS provider. The examples below show how to configure each option for your setup. - -=== "Smoldot (WebWorker)" - - ```typescript - // `dot` is the identifier assigned during `npx papi add` - import { dot } from '@polkadot-api/descriptors'; - import { createClient } from 'polkadot-api'; - import { getSmProvider } from 'polkadot-api/sm-provider'; - import { chainSpec } from 'polkadot-api/chains/polkadot'; - import { startFromWorker } from 'polkadot-api/smoldot/from-worker'; - import SmWorker from 'polkadot-api/smoldot/worker?worker'; - - const worker = new SmWorker(); - const smoldot = startFromWorker(worker); - const chain = await smoldot.addChain({ chainSpec }); - - // Establish connection to the Polkadot relay chain - const client = createClient(getSmProvider(chain)); - - // To interact with the chain, obtain the `TypedApi`, which provides - // the necessary types for every API call on this chain - const dotApi = client.getTypedApi(dot); - - ``` - -=== "Smoldot (Node.js)" - - ```typescript - // `dot` is the alias assigned during `npx papi add` - import { dot } from '@polkadot-api/descriptors'; - import { createClient } from 'polkadot-api'; - import { getSmProvider } from 'polkadot-api/sm-provider'; - import { chainSpec } from 'polkadot-api/chains/polkadot'; - import { startFromWorker } from 'polkadot-api/smoldot/from-node-worker'; - import { fileURLToPath } from 'url'; - import { Worker } from 'worker_threads'; - - // Get the path for the worker file in ESM - const workerPath = fileURLToPath( - import.meta.resolve('polkadot-api/smoldot/node-worker'), - ); - - const worker = new Worker(workerPath); - const smoldot = startFromWorker(worker); - const chain = await smoldot.addChain({ chainSpec }); - - // Set up a client to connect to the Polkadot relay chain - const client = createClient(getSmProvider(chain)); - - // To interact with the chain's API, use `TypedApi` for access to - // all the necessary types and calls associated with this chain - const dotApi = client.getTypedApi(dot); - - ``` - -=== "Smoldot" - - ```typescript - // `dot` is the alias assigned when running `npx papi add` - import { dot } from '@polkadot-api/descriptors'; - import { createClient } from 'polkadot-api'; - import { getSmProvider } from 'polkadot-api/sm-provider'; - import { chainSpec } from 'polkadot-api/chains/polkadot'; - import { start } from 'polkadot-api/smoldot'; - - // Initialize Smoldot client - const smoldot = start(); - const chain = await smoldot.addChain({ chainSpec }); - - // Set up a client to connect to the Polkadot relay chain - const client = createClient(getSmProvider(chain)); - - // Access the `TypedApi` to interact with all available chain calls and types - const dotApi = client.getTypedApi(dot); - - ``` - -=== "WSS" - - ```typescript - // `dot` is the identifier assigned when executing `npx papi add` - import { dot } from '@polkadot-api/descriptors'; - import { createClient } from 'polkadot-api'; - // Use this import for Node.js environments - import { getWsProvider } from 'polkadot-api/ws-provider/web'; - import { withPolkadotSdkCompat } from 'polkadot-api/polkadot-sdk-compat'; - - // Establish a connection to the Polkadot relay chain - const client = createClient( - // The Polkadot SDK nodes may have compatibility issues; using this enhancer is recommended. - // Refer to the Requirements page for additional details - withPolkadotSdkCompat(getWsProvider('wss://dot-rpc.stakeworld.io')), - ); - - // To interact with the chain, obtain the `TypedApi`, which provides - // the types for all available calls in that chain - const dotApi = client.getTypedApi(dot); - - ``` - -Now that you have set up the client, you can interact with the chain by reading and sending transactions. - -### Reading Chain Data - -The `TypedApi` provides a streamlined way to read blockchain data through three main interfaces, each designed for specific data access patterns: - -- **Constants**: Access fixed values or configurations on the blockchain using the `constants` interface. - - ```typescript - const version = await typedApi.constants.System.Version(); - ``` - -- **Storage queries**: Retrieve stored values by querying the blockchain’s storage via the `query` interface. - - ```typescript - const asset = await api.query.ForeignAssets.Asset.getValue( - token.location, - { at: 'best' }, - ); - ``` - -- **Runtime APIs**: Interact directly with runtime APIs using the `apis` interface. - - ```typescript - const metadata = await typedApi.apis.Metadata.metadata(); - ``` - -To learn more about the different actions you can perform with the `TypedApi`, refer to the [TypedApi reference](https://papi.how/typed){target=\_blank}. - -### Sending Transactions - -In PAPI, the `TypedApi` provides the `tx` and `txFromCallData` methods to send transactions. - -- The `tx` method allows you to directly send a transaction with the specified parameters by using the `typedApi.tx.Pallet.Call` pattern: - - ```typescript - const tx: Transaction = typedApi.tx.Pallet.Call({arg1, arg2, arg3}); - ``` - - For instance, to execute the `balances.transferKeepAlive` call, you can use the following snippet: - - ```typescript - import { MultiAddress } from '@polkadot-api/descriptors'; - - const tx: Transaction = typedApi.tx.Balances.transfer_keep_alive({ - dest: MultiAddress.Id('INSERT_DESTINATION_ADDRESS'), - value: BigInt(INSERT_VALUE), - }); - - ``` - - Ensure you replace `INSERT_DESTINATION_ADDRESS` and `INSERT_VALUE` with the actual destination address and value, respectively. - -- The `txFromCallData` method allows you to send a transaction using the call data. This option accepts binary call data and constructs the transaction from it. It validates the input upon creation and will throw an error if invalid data is provided. The pattern is as follows: - - ```typescript - const callData = Binary.fromHex('0x...'); - const tx: Transaction = typedApi.txFromCallData(callData); - ``` - - For instance, to execute a transaction using the call data, you can use the following snippet: - - ```typescript - const callData = Binary.fromHex('0x00002470617065726d6f6f6e'); - const tx: Transaction = typedApi.txFromCallData(callData); - ``` - -For more information about sending transactions, refer to the [Transactions](https://papi.how/typed/tx#transactions){target=\_blank} page. - -## Where to Go Next - -For an in-depth guide on how to use PAPI, refer to the official [PAPI](https://papi.how/){target=\_blank} documentation. - - ---- - -Page Title: Polkadot.js API - -- Source (raw): https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/reference-tools-polkadot-js-api.md -- Canonical (HTML): https://docs.polkadot.com/reference/tools/polkadot-js-api/ -- Summary: Interact with Polkadot SDK-based chains easily using the Polkadot.js API. Query chain data, submit transactions, and more via JavaScript or Typescript. - -# Polkadot.js API - -!!! warning "Maintenance Mode Only" - The Polkadot.js API is now in maintenance mode and is no longer actively developed. New projects should use [Dedot](/develop/toolkit/api-libraries/dedot){target=\_blank} (TypeScript-first API) or [Polkadot API](/develop/toolkit/api-libraries/papi){target=\_blank} (modern, type-safe API) as actively maintained alternatives. - -## Introduction - -The [Polkadot.js API](https://github.com/polkadot-js/api){target=\_blank} uses JavaScript/TypeScript to interact with Polkadot SDK-based chains. It allows you to query nodes, read chain state, and submit transactions through a dynamic, auto-generated API interface. - -### Dynamic API Generation - -Unlike traditional static APIs, the Polkadot.js API generates its interfaces automatically when connecting to a node. Here's what happens when you connect: - -1. The API connects to your node. -2. It retrieves the chain's metadata. -3. Based on this metadata, it creates specific endpoints in this format: `api...
`. - -### Available API Categories - -You can access three main categories of chain interactions: - -- **[Runtime constants](https://polkadot.js.org/docs/api/start/api.consts){target=\_blank}** (`api.consts`): - - - Access runtime constants directly. - - Returns values immediately without function calls. - - **Example**: `api.consts.balances.existentialDeposit` - -- **[State queries](https://polkadot.js.org/docs/api/start/api.query/){target=\_blank}** (`api.query`): - - - Read chain state. - - **Example**: `api.query.system.account(accountId)` - -- **[Transactions](https://polkadot.js.org/docs/api/start/api.tx/){target=\_blank}** (`api.tx`): - - Submit extrinsics (transactions). - - **Example**: `api.tx.balances.transfer(accountId, value)` - -The available methods and interfaces will automatically reflect what's possible on your connected chain. - -## Installation - -To add the Polkadot.js API to your project, use the following command to install the version `16.4.7` which supports any Polkadot SDK-based chain: - -=== "npm" - ```bash - npm i @polkadot/api@16.4.7 - ``` - -=== "pnpm" - ```bash - pnpm add @polkadot/api@16.4.7 - ``` - -=== "yarn" - ```bash - yarn add @polkadot/api@16.4.7 - ``` - -For more detailed information about installation, see the [Installation](https://polkadot.js.org/docs/api/start/install/){target=\_blank} section in the official Polkadot.js API documentation. - -## Get Started - -### Creating an API Instance - -To interact with a Polkadot SDK-based chain, you must establish a connection through an API instance. The API provides methods for querying chain state, sending transactions, and subscribing to updates. - -To create an API connection: - -```js -import { ApiPromise, WsProvider } from '@polkadot/api'; - -// Create a WebSocket provider -const wsProvider = new WsProvider('wss://rpc.polkadot.io'); - -// Initialize the API -const api = await ApiPromise.create({ provider: wsProvider }); - -// Verify the connection by getting the chain's genesis hash -console.log('Genesis Hash:', api.genesisHash.toHex()); - -``` - -!!!warning - All `await` operations must be wrapped in an async function or block since the API uses promises for asynchronous operations. - -### Reading Chain Data - -The API provides several ways to read data from the chain. You can access: - -- **Constants**: Values that are fixed in the runtime and don't change without a runtime upgrade. - - ```js - // Get the minimum balance required for a new account - const minBalance = api.consts.balances.existentialDeposit.toNumber(); - - ``` - -- **State**: Current chain state that updates with each block. - - ```js - // Example address - const address = '5DTestUPts3kjeXSTMyerHihn1uwMfLj8vU8sqF7qYrFabHE'; - - // Get current timestamp - const timestamp = await api.query.timestamp.now(); - - // Get account information - const { nonce, data: balance } = await api.query.system.account(address); - - console.log(` - Timestamp: ${timestamp} - Free Balance: ${balance.free} - Nonce: ${nonce} - `); - - ``` - -### Sending Transactions - -Transactions (also called extrinsics) modify the chain state. Before sending a transaction, you need: - -- A funded account with sufficient balance to pay transaction fees. -- The account's keypair for signing. - -To make a transfer: - -```js -// Assuming you have an `alice` keypair from the Keyring -const recipient = 'INSERT_RECIPIENT_ADDRESS'; -const amount = 'INSERT_VALUE'; // Amount in the smallest unit (e.g., Planck for DOT) - -// Sign and send a transfer -const txHash = await api.tx.balances - .transfer(recipient, amount) - .signAndSend(alice); - -console.log('Transaction Hash:', txHash); - -``` - -The `alice` keypair in the example comes from a `Keyring` object. For more details about managing keypairs, see the [Keyring documentation](https://polkadot.js.org/docs/keyring){target=\_blank}. - -## Where to Go Next - -For more detailed information about the Polkadot.js API, check the [official documentation](https://polkadot.js.org/docs/){target=\_blank}. - - ---- - -Page Title: Python Substrate Interface - -- Source (raw): https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/reference-tools-py-substrate-interface.md -- Canonical (HTML): https://docs.polkadot.com/reference/tools/py-substrate-interface/ -- Summary: Learn how to connect to Polkadot SDK-based nodes, query data, submit transactions, and manage blockchain interactions using the Python Substrate Interface. - -# Python Substrate Interface - -## Introduction - -The [Python Substrate Interface](https://github.com/polkascan/py-substrate-interface){target=\_blank} is a powerful library that enables interaction with Polkadot SDK-based chains. It provides essential functionality for: - -- Querying on-chain storage. -- Composing and submitting extrinsics. -- SCALE encoding/decoding. -- Interacting with Substrate runtime metadata. -- Managing blockchain interactions through convenient utility methods. - -## Installation - -Install the library using `pip`: - -```py -pip install substrate-interface -``` - -For more installation details, see the [Installation](https://jamdottech.github.io/py-polkadot-sdk/getting-started/installation/){target=\_blank} section in the official Python Substrate Interface documentation. - -## Get Started - -This guide will walk you through the basic operations with the Python Substrate Interface: connecting to a node, reading chain state, and submitting transactions. - -### Establishing Connection - -The first step is to establish a connection to a Polkadot SDK-based node. You can connect to either a local or remote node: - -```py -from substrateinterface import SubstrateInterface - -# Connect to a node using websocket -substrate = SubstrateInterface( - # For local node: "ws://127.0.0.1:9944" - # For Polkadot: "wss://rpc.polkadot.io" - # For Kusama: "wss://kusama-rpc.polkadot.io" - url="INSERT_WS_URL" -) - -# Verify connection -print(f"Connected to chain: {substrate.chain}") - -``` - -### Reading Chain State - -You can query various on-chain storage items. To retrieve data, you need to specify three key pieces of information: - -- **Pallet name**: Module or pallet that contains the storage item you want to access. -- **Storage item**: Specific storage entry you want to query within the pallet. -- **Required parameters**: Any parameters needed to retrieve the desired data. - -Here's an example of how to check an account's balance and other details: - -```py -# ... - -# Query account balance and info -account_info = substrate.query( - module="System", # The pallet name - storage_function="Account", # The storage item - params=["INSERT_ADDRESS"], # Account address in SS58 format -) - -# Access account details from the result -free_balance = account_info.value["data"]["free"] -reserved = account_info.value["data"]["reserved"] -nonce = account_info.value["nonce"] - -print( - f""" - Account Details: - - Free Balance: {free_balance} - - Reserved: {reserved} - - Nonce: {nonce} - """ -) - -``` - -### Submitting Transactions - -To modify the chain state, you need to submit transactions (extrinsics). Before proceeding, ensure you have: - -- A funded account with sufficient balance to pay transaction fees. -- Access to the account's keypair. - -Here's how to create and submit a balance transfer: - -```py -#... - -# Compose the transfer call -call = substrate.compose_call( - call_module="Balances", # The pallet name - call_function="transfer_keep_alive", # The extrinsic function - call_params={ - 'dest': 'INSERT_ADDRESS', # Recipient's address - 'value': 'INSERT_VALUE' # Amount in smallest unit (e.g., Planck for DOT) - } -) - -# Create a signed extrinsic -extrinsic = substrate.create_signed_extrinsic( - call=call, keypair=keypair # Your keypair for signing -) - -# Submit and wait for inclusion -receipt = substrate.submit_extrinsic( - extrinsic, wait_for_inclusion=True # Wait until the transaction is in a block -) - -if receipt.is_success: - print( - f""" - Transaction successful: - - Extrinsic Hash: {receipt.extrinsic_hash} - - Block Hash: {receipt.block_hash} - """ - ) -else: - print(f"Transaction failed: {receipt.error_message}") - -``` - -The `keypair` object is essential for signing transactions. See the [Keypair](https://jamdottech.github.io/py-polkadot-sdk/reference/keypair/){target=\_blank} documentation for more details. - -## Where to Go Next - -Now that you understand the basics, you can: - -- Explore more complex queries and transactions. -- Learn about batch transactions and utility functions. -- Discover how to work with custom pallets and types. - -For comprehensive reference materials and advanced features, see the [Python Substrate Interface](https://jamdottech.github.io/py-polkadot-sdk/){target=\_blank} documentation. - - ---- - -Page Title: Randomness - -- Source (raw): https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/reference-parachains-randomness.md -- Canonical (HTML): https://docs.polkadot.com/reference/parachains/randomness/ -- Summary: Explore the importance of randomness in PoS blockchains, focusing on Polkadot’s VRF-based approach to ensure fairness and security in validator selection. - -# Randomness - -## Introduction - -Randomness is crucial in Proof of Stake (PoS) blockchains to ensure a fair and unpredictable distribution of validator duties. However, computers are inherently deterministic, meaning the same input always produces the same output. What we typically refer to as "random" numbers on a computer are actually pseudo-random. These numbers rely on an initial "seed," which can come from external sources like [atmospheric noise](https://www.random.org/randomness/){target=\_blank}, [heart rates](https://mdpi.altmetric.com/details/47574324){target=\_blank}, or even [lava lamps](https://en.wikipedia.org/wiki/Lavarand){target=\_blank}. While this may seem random, given the same "seed," the same sequence of numbers will always be generated. - -In a global blockchain network, relying on real-world entropy for randomness isn’t feasible because these inputs vary by time and location. If nodes use different inputs, blockchains can fork. Hence, real-world randomness isn't suitable for use as a seed in blockchain systems. - -Currently, two primary methods for generating randomness in blockchains are used: [`RANDAO`](#randao) and [`VRF`](#vrf) (Verifiable Random Function). Polkadot adopts the `VRF` approach for its randomness. - -## VRF - -A Verifiable Random Function (VRF) is a cryptographic function that generates a random number and proof that ensures the submitter produced the number. This proof allows anyone to verify the validity of the random number. - -Polkadot's VRF is similar to the one used in [**Ouroboros Praos**](https://eprint.iacr.org/2017/573.pdf){target=\_blank}, which secures randomness for block production in systems like [BABE](/reference/polkadot-hub/consensus-and-security/pos-consensus/#block-production-babe){target=\_blank} (Polkadot’s block production mechanism). - -The key difference is that Polkadot's VRF doesn’t rely on a central clock—avoiding the issue of whose clock to trust. Instead, it uses its own past results and slot numbers to simulate time and determine future outcomes. - -### How VRF Works - -Slots on Polkadot are discrete units of time, each lasting six seconds, and can potentially hold a block. Multiple slots form an epoch, with 2400 slots making up one four-hour epoch. - -In each slot, validators execute a "die roll" using a VRF. The VRF uses three inputs: - -1. A "secret key," unique to each validator, is used for the die roll. -2. An epoch randomness value, derived from the hash of VRF outputs from blocks two epochs ago (N-2), so past randomness influences the current epoch (N). -3. The current slot number. - -This process helps maintain fair randomness across the network. - -Here is a graphical representation: - -![](/images/reference/parachains/randomness/randomness-01.webp) - -The VRF produces two outputs: a result (the random number) and a proof (verifying that the number was generated correctly). - -The result is checked by the validator against a protocol threshold. If it's below the threshold, the validator becomes a candidate for block production in that slot. - -The validator then attempts to create a block, submitting it along with the `PROOF` and `RESULT`. - -So, VRF can be expressed like: - -`(RESULT, PROOF) = VRF(SECRET, EPOCH_RANDOMNESS_VALUE, CURRENT_SLOT_NUMBER)` - -Put simply, performing a "VRF roll" generates a random number along with proof that the number was genuinely produced and not arbitrarily chosen. - -After executing the VRF, the `RESULT` is compared to a protocol-defined `THRESHOLD`. If the `RESULT` is below the `THRESHOLD`, the validator becomes a valid candidate to propose a block for that slot. Otherwise, the validator skips the slot. - -As a result, there may be multiple validators eligible to propose a block for a slot. In this case, the block accepted by other nodes will prevail, provided it is on the chain with the latest finalized block as determined by the GRANDPA finality gadget. It's also possible for no block producers to be available for a slot, in which case the AURA consensus takes over. AURA is a fallback mechanism that randomly selects a validator to produce a block, running in parallel with BABE and only stepping in when no block producers exist for a slot. Otherwise, it remains inactive. - -Because validators roll independently, no block candidates may appear in some slots if all roll numbers are above the threshold. - -To verify resolution of this issue and that Polkadot block times remain near constant-time, see the [PoS Consensus](/reference/polkadot-hub/consensus-and-security/pos-consensus/){target=\_blank} page of this documentation. - -## RANDAO - -An alternative on-chain randomness method is Ethereum's RANDAO, where validators perform thousands of hashes on a seed and publish the final hash during a round. The collective input from all validators forms the random number, and as long as one honest validator participates, the randomness is secure. - -To enhance security, RANDAO can optionally be combined with a Verifiable Delay Function (VDF), ensuring that randomness can't be predicted or manipulated during computation. - -For more information about RANDAO, see the [Randomness - RANDAO](https://eth2book.info/capella/part2/building_blocks/randomness/){target=\_blank} section of the Upgrading Ethereum documentation. - -## VDFs - -Verifiable Delay Functions (VDFs) are time-bound computations that, even on parallel computers, take a set amount of time to complete. - -They produce a unique result that can be quickly verified publicly. When combined with RANDAO, feeding RANDAO's output into a VDF introduces a delay that nullifies an attacker's chance to influence the randomness. - -However, VDF likely requires specialized ASIC devices to run separately from standard nodes. - -!!!warning - While only one is needed to secure the system, and they will be open-source and inexpensive, running VDF devices involves significant costs without direct incentives, adding friction for blockchain users. - -## Additional Resources - -For more information about the reasoning for choices made along with proofs, see Polkadot's research on blockchain randomness and sortition in the [Block production](https://research.web3.foundation/Polkadot/protocols/block-production){target=\_blank} entry of the Polkadot Wiki. - -For a discussion with Web3 Foundation researchers about when and under what conditions Polkadot's randomness can be utilized, see the [Discussion on Randomness used in Polkadot](https://github.com/use-ink/ink/issues/57){target=\_blank} issue on GitHub. - - ---- - -Page Title: Run a Parachain Network - -- Source (raw): https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/parachains-testing-run-a-parachain-network.md -- Canonical (HTML): https://docs.polkadot.com/parachains/testing/run-a-parachain-network/ -- Summary: Quickly install and configure Zombienet to deploy and test Polkadot-based blockchain networks with this comprehensive getting-started guide. - -# Run a Parachain Network Using Zombienet - -## Introduction - -Zombienet is a robust testing framework designed for Polkadot SDK-based blockchain networks. It enables developers to efficiently deploy and test ephemeral blockchain environments on platforms like Kubernetes, Podman, and native setups. With its simple and versatile CLI, Zombienet provides an all-in-one solution for spawning networks, running tests, and validating performance. - -This guide will outline the different installation methods for Zombienet, provide step-by-step instructions for setting up on various platforms, and highlight essential provider-specific features and requirements. - -By following this guide, Zombienet will be up and running quickly, ready to streamline your blockchain testing and development workflows. - -## Install Zombienet - -Zombienet releases are available on the [Zombienet repository](https://github.com/paritytech/zombienet){target=\_blank}. - -Multiple options are available for installing Zombienet, depending on the user's preferences and the environment where it will be used. The following section will guide you through the installation process for each option. - -=== "Use the executable" - - Install Zombienet using executables by visiting the [latest release](https://github.com/paritytech/zombienet/releases){target=\_blank} page and selecting the appropriate asset for your operating system. You can download the executable and move it to a directory in your PATH. - - Each release includes executables for Linux and macOS. Executables are generated using [pkg](https://github.com/vercel/pkg){target=\_blank}, which allows the Zombienet CLI to operate without requiring Node.js to be installed. - - Then, ensure the downloaded file is executable: - - ```bash - chmod +x zombienet-macos-arm64 - ``` - - Finally, you can run the following command to check if the installation was successful. If so, it will display the version of the installed Zombienet: - - ```bash - ./zombienet-macos-arm64 version - ``` - - If you want to add the `zombienet` executable to your PATH, you can move it to a directory in your PATH, such as `/usr/local/bin`: - - ```bash - mv zombienet-macos-arm64 /usr/local/bin/zombienet - ``` - - Now you can refer to the `zombienet` executable directly. - - ```bash - zombienet version - ``` - -=== "Use Nix" - - For Nix users, the Zombienet repository provides a [`flake.nix`](https://github.com/paritytech/zombienet/blob/main/flake.nix){target=\_blank} file to install Zombienet making it easy to incorporate Zombienet into Nix-based projects. - - To install Zombienet utilizing Nix, users can run the following command, triggering the fetching of the flake and subsequently installing the Zombienet package: - - ```bash - nix run github:paritytech/zombienet/INSERT_ZOMBIENET_VERSION -- \ - spawn INSERT_ZOMBIENET_CONFIG_FILE_NAME.toml - ``` - - Replace the `INSERT_ZOMBIENET_VERSION` with the desired version of Zombienet and the `INSERT_ZOMBIENET_CONFIG_FILE_NAME` with the name of the configuration file you want to use. - - To run the command above, you need to have [Flakes](https://nixos.wiki/wiki/Flakes#Enable_flakes){target=\_blank} enabled. - - Alternatively, you can also include the Zombienet binary in the PATH for the current shell using the following command: - - ```bash - nix shell github:paritytech/zombienet/INSERT_ZOMBIENET_VERSION - ``` - -=== "Use Docker" - - Zombienet can also be run using Docker. The Zombienet repository provides a Docker image that can be used to run the Zombienet CLI. To run Zombienet using Docker, you can use the following command: - - ```bash - docker run -it --rm \ - -v $(pwd):/home/nonroot/zombie-net/host-current-files \ - paritytech/zombienet - ``` - - The command above will run the Zombienet CLI inside a Docker container and mount the current directory to the `/home/nonroot/zombie-net/host-current-files` directory. This allows Zombienet to access the configuration file and other files in the current directory. If you want to mount a different directory, replace `$(pwd)` with the desired directory path. - - Inside the Docker container, you can run the Zombienet CLI commands. First, you need to set up Zombienet to download the necessary binaries: - - ```bash - npm run zombie -- setup polkadot polkadot-parachain - ``` - - After that, you need to add those binaries to the PATH: - - ```bash - export PATH=/home/nonroot/zombie-net:$PATH - ``` - - Finally, you can run the Zombienet CLI commands. For example, to spawn a network using a specific configuration file, you can run the following command: - - ```bash - npm run zombie -- -p native spawn host-current-files/minimal.toml - ``` - - The command above mounts the current directory to the `/workspace` directory inside the Docker container, allowing Zombienet to access the configuration file and other files in the current directory. If you want to mount a different directory, replace `$(pwd)` with the desired directory path. - -## Providers - -Zombienet supports different backend providers for running the nodes. At this moment, [Kubernetes](https://kubernetes.io/){target=\_blank}, [Podman](https://podman.io/){target=\_blank}, and local providers are supported, which can be declared as `kubernetes`, `podman`, or `native`, respectively. - -To use a particular provider, you can specify it in the network file or use the `--provider` flag in the CLI: - -```bash -zombienet spawn network.toml --provider INSERT_PROVIDER -``` - -Alternatively, you can set the provider in the network file: - -```toml -[settings] -provider = "INSERT_PROVIDER" -... -``` - -It's important to note that each provider has specific requirements and associated features. The following sections cover each provider's requirements and added features. - -### Kubernetes - -Kubernetes is a portable, extensible, open-source platform for managing containerized workloads and services. Zombienet is designed to be compatible with a variety of Kubernetes clusters, including: - -- [Google Kubernetes Engine (GKE)](https://cloud.google.com/kubernetes-engine){target=\_blank} -- [Docker Desktop](https://docs.docker.com/desktop/features/kubernetes/){target=\_blank} -- [kind](https://kind.sigs.k8s.io/){target=\_blank} - -#### Requirements - -To effectively interact with your cluster, you'll need to ensure that [`kubectl`](https://kubernetes.io/docs/reference/kubectl/){target=\_blank} is installed on your system. This Kubernetes command-line tool allows you to run commands against Kubernetes clusters. If you don't have `kubectl` installed, you can follow the instructions provided in the [Kubernetes documentation](https://kubernetes.io/docs/tasks/tools/#kubectl){target=\_blank}. - -To create resources such as namespaces, pods, and CronJobs within the target cluster, you must grant your user or service account the appropriate permissions. These permissions are essential for managing and deploying applications effectively within Kubernetes. - -#### Features - -If available, Zombienet uses the Prometheus operator to oversee monitoring and visibility. This configuration ensures that only essential networking-related pods are deployed. Using the Prometheus operator, Zombienet improves its ability to monitor and manage network activities within the Kubernetes cluster efficiently. - -### Podman - -Podman is a daemonless container engine for developing, managing, and running Open Container Initiative (OCI) containers and container images on Linux-based systems. Zombienet supports Podman rootless as a provider on Linux machines. Although Podman has support for macOS through an internal virtual machine (VM), the Zombienet provider code requires Podman to run natively on Linux. - -#### Requirements - -To use Podman as a provider, you need to have Podman installed on your system. You can install Podman by following the instructions provided on the [Podman website](https://podman.io/getting-started/installation){target=\_blank}. - -#### Features - -Using Podman, Zombienet deploys additional pods to enhance the monitoring and visibility of the active network. Specifically, pods for [Prometheus](https://prometheus.io/){target=\_blank}, [Tempo](https://grafana.com/docs/tempo/latest/operations/monitor/){target=\_blank}, and [Grafana](https://grafana.com/){target=\_blank} are included in the deployment. Grafana is configured with Prometheus and Tempo as data sources. - -Upon launching Zombienet, access to these monitoring services is facilitated through specific URLs provided in the output: - -- **Prometheus**: `http://127.0.0.1:34123` -- **Tempo**: `http://127.0.0.1:34125` -- **Grafana**: `http://127.0.0.1:41461` - -It's important to note that Grafana is deployed with default administrator access. - -When network operations cease, either from halting a running spawn with the `Ctrl+C` command or test completion, Zombienet automatically removes all associated pods. - -### Local Provider - -The Zombienet local provider, also called native, enables you to run nodes as local processes in your environment. - -#### Requirements - -You must have the necessary binaries for your network (such as `polkadot` and `polkadot-parachain`). These binaries should be available in your PATH, allowing Zombienet to spawn the nodes as local processes. - -To install the necessary binaries, you can use the Zombienet CLI command: - -```bash -zombienet setup polkadot polkadot-parachain -``` - -This command will download and prepare the necessary binaries for Zombienet's use. - -If you need to use a custom binary, ensure the binary is available in your PATH. You can also specify the binary path in the network configuration file. The following example uses the custom [OpenZeppelin template](https://github.com/OpenZeppelin/polkadot-runtime-templates){target=\_blank}: - -First, clone the OpenZeppelin template repository using the following command: - -```bash -git clone https://github.com/OpenZeppelin/polkadot-runtime-templates \ -&& cd polkadot-runtime-templates/generic-template -``` - -Next, run the command to build the custom binary: - -```bash -cargo build --release -``` - -Finally, add the custom binary to your PATH as follows: - -```bash -export PATH=$PATH:INSERT_PATH_TO_RUNTIME_TEMPLATES/parachain-template-node/target/release -``` - -Alternatively, you can specify the binary path in the network configuration file. The local provider exclusively utilizes the command configuration for nodes, which supports both relative and absolute paths. You can employ the `default_command` configuration to specify the binary for spawning all nodes in the relay chain. - -```toml -[relaychain] -chain = "rococo-local" -default_command = "./bin-v1.6.0/polkadot" - -[parachain] -id = 1000 - - [parachain.collators] - name = "collator01" - command = "./target/release/parachain-template-node" -``` - -#### Features - -The local provider does not offer any additional features. - -## Configure Zombienet - -Effective network configuration is crucial for deploying and managing blockchain systems. Zombienet simplifies this process by offering versatile configuration options in both JSON and TOML formats. Whether setting up a simple test network or a complex multi-node system, Zombienet's tools provide the flexibility to customize every aspect of your network's setup. - -The following sections will explore the structure and usage of Zombienet configuration files, explain key settings for network customization, and walk through CLI commands and flags to optimize your development workflow. - -### Configuration Files - -The network configuration file can be either JSON or TOML format. The Zombienet repository also provides a collection of [example configuration files](https://github.com/paritytech/zombienet/tree/main/examples){target=\_blank} that can be used as a reference. - -Each section may include provider-specific keys that aren't recognized by other providers. For example, if you use the local provider, any references to images for nodes will be disregarded. - -### CLI Usage - -Zombienet provides a CLI that allows interaction with the tool. The CLI can receive commands and flags to perform different kinds of operations. These operations use the following syntax: - -```bash -zombienet -``` - -The following sections will guide you through the primary usage of the Zombienet CLI and the available commands and flags. - -#### CLI Commands - -- **`spawn `**: Spawn the network defined in the [configuration file](#configuration-files). -- **`test `**: Run tests on the spawned network using the assertions and tests defined in the test file. -- **`setup `**: Set up the Zombienet development environment to download and use the `polkadot` or `polkadot-parachain` executable. -- **`convert `**: Transforms a [polkadot-launch](https://github.com/paritytech/polkadot-launch){target=\_blank} configuration file with a `.js` or `.json` extension into a Zombienet configuration file. -- **`version`**: Prints Zombienet version. -- **`help`**: Prints help information. - -#### CLI Flags - -You can use the following flags to customize the behavior of the CLI: - -- **`-p`, `--provider`**: Override the [provider](#providers) to use. -- **`-d`, `--dir`**: Specify a directory path for placing the network files instead of using the default temporary path. -- **`-f`, `--force`**: Force override all prompt commands. -- **`-l`, `--logType`**: Type of logging on the console. Defaults to `table`. -- **`-m`, `--monitor`**: Start as monitor and don't auto clean up network. -- **`-c`, `--spawn-concurrency`**: Number of concurrent spawning processes to launch. Defaults to `1`. -- **`-h`, `--help`**: Display help for command. - -### Settings - -Through the keyword `settings`, it's possible to define the general settings for the network. The available keys are: - -- **`global_volumes?`** ++"GlobalVolume[]"++: A list of global volumes to use. - - ??? child "`GlobalVolume` interface definition" - ```js - export interface GlobalVolume { - name: string; - fs_type: string; - mount_path: string; - } - ``` - -- **`bootnode`** ++"boolean"++: Add bootnode to network. Defaults to `true`. -- **`bootnode_domain?`** ++"string"++: Domain to use for bootnode. -- **`timeout`** ++"number"++: Global timeout to use for spawning the whole network. -- **`node_spawn_timeout?`** ++"number"++: Timeout to spawn pod/process. -- **`grafana?`** ++"boolean"++: Deploy an instance of Grafana. -- **`prometheus?`** ++"boolean"++: Deploy an instance of Prometheus. -- **`telemetry?`** ++"boolean"++: Enable telemetry for the network. -- **`jaeger_agent?`** ++"string"++: The Jaeger agent endpoint passed to the nodes. Only available on Kubernetes. -- **`tracing_collator_url?`** ++"string"++: The URL of the tracing collator used to query by the tracing assertion. Should be tempo query compatible. -- **`tracing_collator_service_name?`** ++"string"++: Service name for tempo query frontend. Only available on Kubernetes. Defaults to `tempo-tempo-distributed-query-frontend`. -- **`tracing_collator_service_namespace?`** ++"string"++: Namespace where tempo is running. Only available on Kubernetes. Defaults to `tempo`. -- **`tracing_collator_service_port?`** ++"number"++: Port of the query instance of tempo. Only available on Kubernetes. Defaults to `3100`. -- **`enable_tracing?`** ++"boolean"++: Enable the tracing system. Only available on Kubernetes. Defaults to `true`. -- **`provider`** ++"string"++: Provider to use. Default is `kubernetes`". -- **`polkadot_introspector?`** ++"boolean"++: Deploy an instance of polkadot-introspector. Only available on Podman and Kubernetes. Defaults to `false`. -- **`backchannel?`** ++"boolean"++: Deploy an instance of backchannel server. Only available on Kubernetes. Defaults to `false`. -- **`image_pull_policy?`** ++"string"++: Image pull policy to use in the network. Possible values are `Always`, `IfNotPresent`, and `Never`. -- **`local_ip?`** ++"string"++: IP used for exposing local services (rpc/metrics/monitors). Defaults to `"127.0.0.1"`. -- **`global_delay_network_global_settings?`** ++"number"++: Delay in seconds to apply to the network. -- **`node_verifier?`** ++"string"++: Specify how to verify node readiness or deactivate by using `None`. Possible values are `None` and `Metric`. Defaults to `Metric`. - -For example, the following configuration file defines a minimal example for the settings: - -=== "TOML" - - ```toml title="base-example.toml" - [settings] - timeout = 1000 - bootnode = false - provider = "kubernetes" - backchannel = false - # ... - - ``` - -=== "JSON" - - ```json title="base-example.json" - { - "settings": { - "timeout": 1000, - "bootnode": false, - "provider": "kubernetes", - "backchannel": false, - "...": {} - }, - "...": {} - } - - ``` - -### Relay Chain Configuration - -You can use the `relaychain` keyword to define further parameters for the relay chain at start-up. The available keys are: - -- **`default_command?`** ++"string"++: The default command to run. Defaults to `polkadot`. -- **`default_image?`** ++"string"++: The default Docker image to use. -- **`default_resources?`** ++"Resources"++: Represents the resource limits/reservations the nodes need by default. Only available on Kubernetes. - - ??? child "`Resources` interface definition" - ```js - export interface Resources { - resources: { - requests?: { - memory?: string; - cpu?: string; - }; - limits?: { - memory?: string; - cpu?: string; - }; - }; - } - ``` - -- **`default_db_snapshot?`** ++"string"++: The default database snapshot to use. -- **`default_prometheus_prefix`** ++"string"++: A parameter for customizing the metric's prefix. Defaults to `substrate`. -- **`default_substrate_cli_args_version?`** ++"SubstrateCliArgsVersion"++: Set the Substrate CLI arguments version. - - ??? child "`SubstrateCliArgsVersion` enum definition" - ```js - export enum SubstrateCliArgsVersion { - V0 = 0, - V1 = 1, - V2 = 2, - V3 = 3, - } - ``` - -- **`default_keystore_key_types?`** ++"string[]"++: Defines which keystore keys should be created. -- **`chain`** ++"string"++: The chain name. -- **`chain_spec_path?`** ++"string"++: Path to the chain spec file. Should be the plain version to allow customizations. -- **`chain_spec_command?`** ++"string"++: Command to generate the chain spec. It can't be used in combination with `chain_spec_path`. -- **`default_args?`** ++"string[]"++: An array of arguments to use as default to pass to the command. -- **`default_overrides?`** ++"Override[]"++: An array of overrides to upload to the node. - - ??? child "`Override` interface definition" - ```js - export interface Override { - local_path: string; - remote_name: string; - } - ``` - -- **`random_nominators_count?`** ++"number"++: If set and the stacking pallet is enabled, Zombienet will generate the input quantity of nominators and inject them into the genesis. -- **`max_nominations`** ++"number"++: The max number of nominations allowed by a nominator. Should match the value set in the runtime. Defaults to `24`. -- **`nodes?`** ++"Node[]"++: An array of nodes to spawn. It is further defined in the [Node Configuration](#node-configuration) section. -- **`node_groups?`** ++"NodeGroup[]"++: An array of node groups to spawn. It is further defined in the [Node Group Configuration](#node-group-configuration) section. -- **`total_node_in_group?`** ++"number"++: The total number of nodes in the group. Defaults to `1`. -- **`genesis`** ++"JSON"++: The genesis configuration. -- **`default_delay_network_settings?`** ++"DelayNetworkSettings"++: Sets the expected configuration to delay the network. - - ??? child "`DelayNetworkSettings` interface definition" - ```js - export interface DelayNetworkSettings { - latency: string; - correlation?: string; // should be parsable as float by k8s - jitter?: string; - } - ``` - -#### Node Configuration - -One specific key capable of receiving more subkeys is the `nodes` key. This key is used to define further parameters for the nodes. The available keys: - -- **`name`** ++"string"++: Name of the node. Any whitespace will be replaced with a dash (for example, `new alice` will be converted to `new-alice`). -- **`image?`** ++"string"++: Override default Docker image to use for this node. -- **`command?`** ++"string"++: Override default command to run. -- **`command_with_args?`** ++"string"++: Override default command and arguments. -- **`args?`** ++"string[]"++: Arguments to be passed to the command. -- **`env?`** ++"envVars[]"++: Environment variables to set in the container. - - ??? child "`envVars` interface definition" - ```js - export interface EnvVars { - name: string; - value: string; - } - ``` - -- **`prometheus_prefix?`** ++"string"++: Customizes the metric's prefix for the specific node. Defaults to `substrate`. -- **`db_snapshot?`** ++"string"++: Database snapshot to use. -- **`substrate_cli_args_version?`** ++"SubstrateCliArgsVersion"++: Set the Substrate CLI arguments version directly to skip binary evaluation overhead. - - ??? child "`SubstrateCliArgsVersion` enum definition" - ```js - export enum SubstrateCliArgsVersion { - V0 = 0, - V1 = 1, - V2 = 2, - V3 = 3, - } - ``` - -- **`resources?`** ++"Resources"++: Represent the resources limits/reservations needed by the node. - - ??? child "`Resources` interface definition" - ```js - export interface Resources { - resources: { - requests?: { - memory?: string; - cpu?: string; - }; - limits?: { - memory?: string; - cpu?: string; - }; - }; - } - ``` - -- **`keystore_key_types?`** ++"string[]"++: Defines which keystore keys should be created. -- **`validator`** ++"boolean"++: Pass the `--validator` flag to the command. Defaults to `true`. -- **`invulnerable`** ++"boolean"++: If true, add the node to invulnerables in the chain spec. Defaults to `false`. -- **`balance`** ++"number"++: Balance to set in balances for node's account. Defaults to `2000000000000`. -- **`bootnodes?`** ++"string[]"++: Array of bootnodes to use. -- **`add_to_bootnodes?`** ++"boolean"++: Add this node to the bootnode list. Defaults to `false`. -- **`ws_port?`** ++"number"++: WS port to use. -- **`rpc_port?`** ++"number"++: RPC port to use. -- **`prometheus_port?`** ++"number"++: Prometheus port to use. -- **`p2p_cert_hash?`** ++"string"++: Libp2p certhash to use with webRTC transport. -- **`delay_network_settings?`** ++"DelayNetworkSettings"++: Sets the expected configuration to delay the network. - - ??? child "`DelayNetworkSettings` interface definition" - ```js - export interface DelayNetworkSettings { - latency: string; - correlation?: string; // should be parsable as float by k8s - jitter?: string; - } - ``` - -The following configuration file defines a minimal example for the relay chain, including the `nodes` key: - -=== "TOML" - - ```toml title="relaychain-example-nodes.toml" - [relaychain] - default_command = "polkadot" - default_image = "polkadot-debug:master" - chain = "rococo-local" - chain_spec_path = "INSERT_PATH_TO_CHAIN_SPEC" - default_args = ["--chain", "rococo-local"] - - [[relaychain.nodes]] - name = "alice" - validator = true - balance = 1000000000000 - - [[relaychain.nodes]] - name = "bob" - validator = true - balance = 1000000000000 - # ... - - ``` - -=== "JSON" - - ```json title="relaychain-example-nodes.json" - { - "relaychain": { - "default_command": "polkadot", - "default_image": "polkadot-debug:master", - "chain": "rococo-local", - "chain_spec_path": "INSERT_PATH_TO_CHAIN-SPEC.JSON", - "default_args": ["--chain", "rococo-local"], - "nodes": [ - { - "name": "alice", - "validator": true, - "balance": 1000000000000 - }, - { - "name": "bob", - "validator": true, - "balance": 1000000000000 - } - ] - } - } - - ``` - -#### Node Group Configuration - -The `node_groups` key defines further parameters for the node groups. The available keys are: - -- **`name`** ++"string"++: Name of the node. Any whitespace will be replaced with a dash (for example, `new alice` will be converted to `new-alice`). -- **`image?`** ++"string"++: Override default Docker image to use for this node. -- **`command?`** ++"string"++: Override default command to run. -- **`args?`** ++"string[]"++: Arguments to be passed to the command. -- **`env?`** ++"envVars[]"++: Environment variables to set in the container. - - ??? child "`envVars` interface definition" - ```js - export interface EnvVars { - name: string; - value: string; - } - ``` - -- **`overrides?`** ++"Override[]"++: Array of overrides definitions. - - ??? child "`Override` interface definition" - ```js - export interface Override { - local_path: string; - remote_name: string; - } - ``` - -- **`prometheus_prefix?`** ++"string"++: Customizes the metric's prefix for the specific node. Defaults to `substrate`. -- **`db_snapshot?`** ++"string"++: Database snapshot to use. -- **`substrate_cli_args_version?`** ++"SubstrateCliArgsVersion"++: Set the Substrate CLI arguments version directly to skip binary evaluation overhead. - - ??? child "`SubstrateCliArgsVersion` enum definition" - ```js - export enum SubstrateCliArgsVersion { - V0 = 0, - V1 = 1, - V2 = 2, - V3 = 3, - } - ``` - -- **`resources?`** ++"Resources"++: Represent the resources limits/reservations needed by the node. - - ??? child "`Resources` interface definition" - ```js - export interface Resources { - resources: { - requests?: { - memory?: string; - cpu?: string; - }; - limits?: { - memory?: string; - cpu?: string; - }; - }; - } - ``` - -- **`keystore_key_types?`** ++"string[]"++: Defines which keystore keys should be created. -- **`count`** ++"number | string"++: Number of nodes to launch for this group. -- **`delay_network_settings?`** ++"DelayNetworkSettings"++: Sets the expected configuration to delay the network. - - ??? child "`DelayNetworkSettings` interface definition" - ```js - export interface DelayNetworkSettings { - latency: string; - correlation?: string; // should be parsable as float by k8s - jitter?: string; - } - ``` - -The following configuration file defines a minimal example for the relay chain, including the `node_groups` key: - -=== "TOML" - - ```toml title="relaychain-example-node-groups.toml" - [relaychain] - default_command = "polkadot" - default_image = "polkadot-debug:master" - chain = "rococo-local" - chain_spec_path = "INSERT_PATH_TO_CHAIN_SPEC" - default_args = ["--chain", "rococo-local"] - - [[relaychain.node_groups]] - name = "group-1" - count = 2 - image = "polkadot-debug:master" - command = "polkadot" - args = ["--chain", "rococo-local"] - # ... - - ``` - -=== "JSON" - - ```json title="relaychain-example-node-groups.json" - { - "relaychain": { - "default_command": "polkadot", - "default_image": "polkadot-debug:master", - "chain": "rococo-local", - "chain_spec_path": "INSERT_PATH_TO_CHAIN-SPEC.JSON", - "default_args": ["--chain", "rococo-local"], - "node_groups": [ - { - "name": "group-1", - "count": 2, - "image": "polkadot-debug:master", - "command": "polkadot", - "args": ["--chain", "rococo-local"] - } - ], - "...": {} - }, - "...": {} - } - - ``` - -### Parachain Configuration - -The `parachain` keyword defines further parameters for the parachain. The available keys are: - -- **`id`** ++"number"++: The id to assign to this parachain. Must be unique. -- **`chain?`** ++"string"++: The chain name. -- **`force_decorator?`** ++"string"++: Force the use of a specific decorator. -- **`genesis?`** ++"JSON"++: The genesis configuration. -- **`balance?`** ++"number"++: Balance to set in balances for parachain's account. -- **`delay_network_settings?`** ++"DelayNetworkSettings"++: Sets the expected configuration to delay the network. - - ??? child "`DelayNetworkSettings` interface definition" - ```js - export interface DelayNetworkSettings { - latency: string; - correlation?: string; // should be parsable as float by k8s - jitter?: string; - } - ``` - -- **`add_to_genesis?`** ++"boolean"++: Flag to add parachain to genesis or register in runtime. Defaults to `true`. -- **`register_para?`** ++"boolean"++: Flag to specify whether the para should be registered. The `add_to_genesis` flag must be set to false for this flag to have any effect. Defaults to `true`. -- **`onboard_as_parachain?`** ++"boolean"++: Flag to specify whether the para should be onboarded as a parachain, rather than remaining a parathread. Defaults to `true`. -- **`genesis_wasm_path?`** ++"string"++: Path to the Wasm file to use. -- **`genesis_wasm_generator?`** ++"string"++: Command to generate the Wasm file. -- **`genesis_state_path?`** ++"string"++: Path to the state file to use. -- **`genesis_state_generator?`** ++"string"++: Command to generate the state file. -- **`chain_spec_path?`** ++"string"++: Path to the chain spec file. -- **`chain_spec_command?`** ++"string"++: Command to generate the chain spec. -- **`cumulus_based?`** ++"boolean"++: Flag to use cumulus command generation. Defaults to `true`. -- **`bootnodes?`** ++"string[]"++: Array of bootnodes to use. -- **`prometheus_prefix?`** ++"string"++: Parameter for customizing the metric's prefix for all parachain nodes/collators. Defaults to `substrate`. -- **`collator?`** ++"Collator"++: Further defined in the [Collator Configuration](#collator-configuration) section. -- **`collator_groups?`** ++"CollatorGroup[]"++: An array of collator groups to spawn. It is further defined in the [Collator Groups Configuration](#collator-groups-configuration) section. - -For example, the following configuration file defines a minimal example for the parachain: - -=== "TOML" - - ```toml title="parachain-example.toml" - [parachain] - id = 100 - add_to_genesis = true - cumulus_based = true - genesis_wasm_path = "INSERT_PATH_TO_WASM" - genesis_state_path = "INSERT_PATH_TO_STATE" - # ... - - ``` - -=== "JSON" - - ```json title="parachain-example.json" - { - "parachain": { - "id": 100, - "add_to_genesis": true, - "cumulus_based": true, - "genesis_wasm_path": "INSERT_PATH_TO_WASM", - "genesis_state_path": "INSERT_PATH_TO_STATE", - "...": {} - }, - "...": {} - } - - ``` - -#### Collator Configuration - -One specific key capable of receiving more subkeys is the `collator` key. This key defines further parameters for the nodes. The available keys are: - -- **`name`** ++"string"++: Name of the collator. Any whitespace will be replaced with a dash (for example, `new alice` will be converted to `new-alice`). -- **`image?`** ++"string"++: Image to use for the collator. -- **`command_with_args?`** ++"string"++: Overrides both command and arguments for the collator. -- **`validator`** ++"boolean"++: Pass the `--validator` flag to the command. Defaults to `true`. -- **`invulnerable`** ++"boolean"++: If true, add the collator to invulnerables in the chain spec. Defaults to `false`. -- **`balance`** ++"number"++: Balance to set in balances for collator's account. Defaults to `2000000000000`. -- **`bootnodes?`** ++"string[]"++: Array of bootnodes to use. -- **`add_to_bootnodes?`** ++"boolean"++: Add this collator to the bootnode list. Defaults to `false`. -- **`ws_port?`** ++"number"++: WS port to use. -- **`rpc_port?`** ++"number"++: RPC port to use. -- **`prometheus_port?`** ++"number"++: Prometheus port to use. -- **`p2p_port?`** ++"number"++: P2P port to use. -- **`p2p_cert_hash?`** ++"string"++: Libp2p certhash to use with webRTC transport. -- **`delay_network_settings?`** ++"DelayNetworkSettings"++: Sets the expected configuration to delay the network. - - ??? child "`DelayNetworkSettings` interface definition" - ```js - export interface DelayNetworkSettings { - latency: string; - correlation?: string; // should be parsable as float by k8s - jitter?: string; - } - ``` - -- **`command?`** ++"string"++: Override default command to run. -- **`args?`** ++"string[]"++: Arguments to be passed to the command. -- **`env?`** ++"envVars[]"++: Environment variables to set in the container. - - ??? child "`envVars` interface definition" - ```js - export interface EnvVars { - name: string; - value: string; - } - ``` - -- **`overrides?`** ++"Override[]"++: Array of overrides definitions. - - ??? child "`Override` interface definition" - ```js - export interface Override { - local_path: string; - remote_name: string; - } - ``` - -- **`prometheus_prefix?`** ++"string"++: Customizes the metric's prefix for the specific node. Defaults to `substrate`. -- **`db_snapshot?`** ++"string"++: Database snapshot to use. -- **`substrate_cli_args_version?`** ++"SubstrateCliArgsVersion"++: Set the Substrate CLI arguments version directly to skip binary evaluation overhead. - - ??? child "`SubstrateCliArgsVersion` enum definition" - ```js - export enum SubstrateCliArgsVersion { - V0 = 0, - V1 = 1, - V2 = 2, - V3 = 3, - } - ``` - -- **`resources?`** ++"Resources"++: Represent the resources limits/reservations needed by the node. - - ??? child "`Resources` interface definition" - ```js - export interface Resources { - resources: { - requests?: { - memory?: string; - cpu?: string; - }; - limits?: { - memory?: string; - cpu?: string; - }; - }; - } - ``` - -- **`keystore_key_types?`** ++"string[]"++: Defines which keystore keys should be created. - -The configuration file below defines a minimal example for the collator: - -=== "TOML" - - ```toml title="collator-example.toml" - [parachain] - id = 100 - add_to_genesis = true - cumulus_based = true - genesis_wasm_path = "INSERT_PATH_TO_WASM" - genesis_state_path = "INSERT_PATH_TO_STATE" - - [[parachain.collators]] - name = "alice" - image = "polkadot-parachain" - command = "polkadot-parachain" - # ... - - ``` - -=== "JSON" - - ```json title="collator-example.json" - { - "parachain": { - "id": 100, - "add_to_genesis": true, - "cumulus_based": true, - "genesis_wasm_path": "INSERT_PATH_TO_WASM", - "genesis_state_path": "INSERT_PATH_TO_STATE", - "collators": [ - { - "name": "alice", - "image": "polkadot-parachain", - "command": "polkadot-parachain", - "...": {} - } - ] - }, - "...": {} - } - - ``` - -#### Collator Groups Configuration - -The `collator_groups` key defines further parameters for the collator groups. The available keys are: - -- **`name`** ++"string"++: Name of the node. Any whitespace will be replaced with a dash (for example, `new alice` will be converted to `new-alice`). -- **`image?`** ++"string"++: Override default Docker image to use for this node. -- **`command?`** ++"string"++: Override default command to run. -- **`args?`** ++"string[]"++: Arguments to be passed to the command. -- **`env?`** ++"envVars[]"++: Environment variables to set in the container. - - ??? child "`envVars` interface definition" - ```js - export interface EnvVars { - name: string; - value: string; - } - ``` - -- **`overrides?`** ++"Override[]"++: Array of overrides definitions. - - ??? child "`Override` interface definition" - ```js - export interface Override { - local_path: string; - remote_name: string; - } - ``` - -- **`prometheus_prefix?`** ++"string"++: Customizes the metric's prefix for the specific node. Defaults to `substrate`. -- **`db_snapshot?`** ++"string"++: Database snapshot to use. -- **`substrate_cli_args_version?`** ++"SubstrateCliArgsVersion"++: Set the Substrate CLI arguments version directly to skip binary evaluation overhead. - - ??? child "`SubstrateCliArgsVersion` enum definition" - ```js - export enum SubstrateCliArgsVersion { - V0 = 0, - V1 = 1, - V2 = 2, - V3 = 3, - } - ``` - -- **`resources?`** ++"Resources"++: Represent the resources limits/reservations needed by the node. - - ??? child "`Resources` interface definition" - ```js - export interface Resources { - resources: { - requests?: { - memory?: string; - cpu?: string; - }; - limits?: { - memory?: string; - cpu?: string; - }; - }; - } - ``` - -- **`keystore_key_types?`** ++"string[]"++: Defines which keystore keys should be created. -- **`count`** ++"number | string"++: Number of nodes to launch for this group. -- **`delay_network_settings?`** ++"DelayNetworkSettings"++: Sets the expected configuration to delay the network. - - ??? child "`DelayNetworkSettings` interface definition" - ```js - export interface DelayNetworkSettings { - latency: string; - correlation?: string; // should be parsable as float by k8s - jitter?: string; - } - ``` - -For instance, the configuration file below defines a minimal example for the collator groups: - -=== "TOML" - - ```toml title="collator-groups-example.toml" - [parachain] - id = 100 - add_to_genesis = true - cumulus_based = true - genesis_wasm_path = "INSERT_PATH_TO_WASM" - genesis_state_path = "INSERT_PATH_TO_STATE" - - [[parachain.collator_groups]] - name = "group-1" - count = 2 - image = "polkadot-parachain" - command = "polkadot-parachain" - # ... - - ``` - -=== "JSON" - - ```json title="collator-groups-example.json" - { - "parachain": { - "id": 100, - "add_to_genesis": true, - "cumulus_based": true, - "genesis_wasm_path": "INSERT_PATH_TO_WASM", - "genesis_state_path": "INSERT_PATH_TO_STATE", - "collator_groups": [ - { - "name": "group-1", - "count": 2, - "image": "polkadot-parachain", - "command": "polkadot-parachain", - "...": {} - } - ] - }, - "...": {} - } - - ``` - -### XCM Configuration - -You can use the `hrmp_channels` keyword to define further parameters for the XCM channels at start-up. The available keys are: - -- **`hrmp_channels`** ++"HrmpChannelsConfig[]"++: Array of Horizontal Relay-routed Message Passing (HRMP) channel configurations. - - ??? child "`HrmpChannelsConfig` interface definition" - ```js - export interface HrmpChannelsConfig { - sender: number; - recipient: number; - max_capacity: number; - max_message_size: number; - } - ``` - Each of the `HrmpChannelsConfig` keys are defined as follows: - - - **`sender` ++"number"++**: Parachain ID of the sender. - - **`recipient` ++"number"++**: Parachain ID of the recipient. - - **`max_capacity` ++"number"++**: Maximum capacity of the HRMP channel. - - **`max_message_size` ++"number"++**: Maximum message size allowed in the HRMP channel. - -## Where to Go Next - -
- -- External __Zombienet Support__ - - --- - - [Parity Technologies](https://www.parity.io/){target=\_blank} has designed and developed this framework, now maintained by the Zombienet team. - - For further support and information, refer to the following contact points: - - [:octicons-arrow-right-24: Zombienet repository](https://github.com/paritytech/zombienet){target=\_blank} - - [:octicons-arrow-right-24: Element public channel](https://matrix.to/#/!FWyuEyNvIFygLnWNMh:parity.io?via=parity.io&via=matrix.org&via=web3.foundation){target=\_blank} - -
- - ---- - -Page Title: Set Up the Polkadot SDK Parachain Template - -- Source (raw): https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/parachains-launch-a-parachain-set-up-the-parachain-template.md -- Canonical (HTML): https://docs.polkadot.com/parachains/launch-a-parachain/set-up-the-parachain-template/ -- Summary: Learn how to set up and run the Polkadot SDK Parachain Template locally, creating a ready-to-customize foundation for your parachain. - -# Set Up the Polkadot SDK Parachain Template - -## Introduction - -The [Polkadot SDK](https://github.com/paritytech/polkadot-sdk){target=\_blank} includes several [templates](/parachains/customize-runtime/#starting-templates){target=\_blank} designed to help you quickly start building your own blockchain. Each template offers a different level of configuration, from minimal setups to feature-rich environments, allowing you to choose the foundation that best fits your project's needs. - -Among these, the [Parachain Template](https://github.com/paritytech/polkadot-sdk-parachain-template){target=\_blank} provides a preconfigured runtime with commonly used pallets, making it an ideal starting point for most parachain development projects. - -This guide walks you through the full process of working with this template. You will: - -- Set up the Polkadot SDK Parachain Template. -- Understand the project structure and key components. -- Verify your template is ready for development. -- Run the parachain template locally in development mode. - -By the end of this guide, you'll have a working template ready to customize and deploy as a parachain. - -## Prerequisites - -Before getting started, ensure you have done the following: - -- Completed the [Install Polkadot SDK](/parachains/install-polkadot-sdk/){target=\_blank} guide and successfully installed [Rust](https://www.rust-lang.org/){target=\_blank} and the required packages to set up your development environment. - -For this tutorial series, you need to use Rust `1.86`. Newer versions of the compiler may not work with this parachain template version. - -Run the following commands to set up the correct Rust version: - -=== "macOS" - - ```bash - rustup install 1.86 - rustup default 1.86 - rustup target add wasm32-unknown-unknown --toolchain 1.86-aarch64-apple-darwin - rustup component add rust-src --toolchain 1.86-aarch64-apple-darwin - ``` - -=== "Ubuntu" - - ```bash - rustup toolchain install 1.86.0 - rustup default 1.86.0 - rustup target add wasm32-unknown-unknown --toolchain 1.86.0 - rustup component add rust-src --toolchain 1.86.0 - ``` - -## Polkadot SDK Utility Tools - -This tutorial requires two essential tools: - -- [**Chain spec builder**](https://crates.io/crates/staging-chain-spec-builder/10.0.0){target=\_blank}: A Polkadot SDK utility for generating chain specifications. Refer to the [Generate Chain Specs](/parachains/launch-a-parachain/deploy-to-polkadot/#generate-the-chain-specification){target=\_blank} documentation for detailed usage. - - Install it by executing the following command: - - ```bash - cargo install --locked staging-chain-spec-builder@10.0.0 - ``` - - This command installs the `chain-spec-builder` binary. - -- [**Polkadot Omni Node**](https://crates.io/crates/polkadot-omni-node/0.5.0){target=\_blank}: A white-labeled binary, released as a part of Polkadot SDK that can act as the collator of a parachain in production, with all the related auxiliary functionalities that a normal collator node has: RPC server, archiving state, etc. Moreover, it can also run the Wasm blob of the parachain locally for testing and development. - - To install it, run the following command: - - ```bash - cargo install --locked polkadot-omni-node@0.5.0 - ``` - - This command installs the `polkadot-omni-node` binary. - -## Clone the Template - -The [Polkadot SDK Parachain Template](https://github.com/paritytech/polkadot-sdk-parachain-template){target=\_blank} provides a ready-to-use development environment for building with the [Polkadot SDK](https://github.com/paritytech/polkadot-sdk){target=\_blank}. Follow these steps to set up the template: - -1. Clone the template repository: - - ```bash - git clone https://github.com/paritytech/polkadot-sdk-parachain-template.git parachain-template - ``` - -2. Navigate into the project directory: - - ```bash - cd parachain-template - ``` - -## Explore the Project Structure - -Before building the template, take a moment to familiarize yourself with its structure. Understanding this organization will help you navigate the codebase as you develop your parachain. - -The template follows a standard Polkadot SDK project layout: - -```text -parachain-template/ -├── node/ # Node implementation and client -├── pallets/ # Custom pallets for your parachain -├── runtime/ # Runtime configuration and logic -├── Cargo.toml # Workspace configuration -└── README.md # Documentation -``` - -Key directories explained: - -- **runtime/**: Contains your parachain's state transition function and pallet configuration. This is where you'll define what your blockchain can do. -- **node/**: Houses the client implementation that runs your blockchain, handles networking, and manages the database. -- **pallets/**: Where you'll create custom business logic modules (pallets) for your specific use case. -- **Cargo.toml**: The workspace configuration that ties all components together. - -!!!note - The runtime is compiled to WebAssembly (Wasm), enabling forkless upgrades. The node binary remains constant while the runtime can be updated on-chain. - -## Compile the Runtime - -Now that you understand the template structure, let's compile the runtime to ensure everything is working correctly. - -1. Compile the runtime: - - ```bash - cargo build --release --locked - ``` - - !!!tip - Initial compilation may take several minutes, depending on your machine specifications. Use the `--release` flag for improved runtime performance compared to the default `--debug` build. If you need to troubleshoot issues, the `--debug` build provides better diagnostics. - - For production deployments, consider using a dedicated `--profile production` flag - this can provide an additional 15-30% performance improvement over the standard `--release` profile. - -2. Upon successful compilation, you should see output indicating the build was successful. The compiled runtime will be located at: - - `./target/release/wbuild/parachain-template-runtime/parachain_template_runtime.compact.compressed.wasm` - -## Verify the Build - -After compilation completes, verify that the runtime was created successfully by checking for the Wasm blob: - -```bash -ls -la ./target/release/wbuild/parachain-template-runtime/ -``` - -You should see the `parachain_template_runtime.compact.compressed.wasm` file in the output, confirming the build was successful. - -## Run the Node Locally - -After successfully compiling your runtime, you can spin up a local chain and produce blocks. This process will start your local parachain using the Polkadot Omni Node and allow you to interact with it. You'll first need to generate a chain specification that defines your network's identity, initial connections, and genesis state, providing the foundational configuration for how your nodes connect and what initial state they agree upon. - -Follow these steps to launch your node in development mode: - -1. Generate the chain specification file of your parachain: - - ```bash - chain-spec-builder create -t development \ - --relay-chain paseo \ - --para-id 1000 \ - --runtime ./target/release/wbuild/parachain-template-runtime/parachain_template_runtime.compact.compressed.wasm \ - named-preset development - ``` - -2. Start the Omni Node with the generated chain spec. You'll start it in development mode (without a relay chain config), producing and finalizing blocks: - - ```bash - polkadot-omni-node --chain ./chain_spec.json --dev - ``` - - The `--dev` option does the following: - - - Deletes all active data (keys, blockchain database, networking information) when stopped. - - Ensures a clean working state each time you restart the node. - -3. Verify that your node is running by reviewing the terminal output. You should see log messages indicating block production and finalization. - -4. Confirm that your blockchain is producing new blocks by checking if the number after `finalized` is increasing in the output. - -The details of the log output will be explored in a later tutorial. For now, knowing that your node is running and producing blocks is sufficient. - -## Interact with the Node - -When running the template node, it's accessible by default at `ws://localhost:9944`. To interact with your node using the [Polkadot.js Apps](https://polkadot.js.org/apps/#/explorer){target=\_blank} interface, follow these steps: - -1. Open [Polkadot.js Apps](https://polkadot.js.org/apps/#/explorer){target=\_blank} in your web browser and click the network icon (which should be the Polkadot logo) in the top left corner: - - ![](/images/parachains/launch-a-parachain/set-up-the-parachain-template/parachain-template-01.webp) - -2. Connect to your local node: - - 1. Scroll to the bottom and select **Development**. - 2. Choose **Custom**. - 3. Enter `ws://localhost:9944` in the **custom endpoint** input field. - 4. Click the **Switch** button. - - ![](/images/parachains/launch-a-parachain/set-up-the-parachain-template/parachain-template-02.webp) - -3. Once connected, you should see **parachain-template-runtime** in the top left corner, with the interface displaying information about your local blockchain. - - ![](/images/parachains/launch-a-parachain/set-up-the-parachain-template/parachain-template-03.webp) - -You are now connected to your local node and can interact with it through the Polkadot.js Apps interface. This tool enables you to explore blocks, execute transactions, and interact with your blockchain's features. For in-depth guidance on using the interface effectively, refer to the [Polkadot.js Guides](https://wiki.polkadot.com/general/polkadotjs/){target=\_blank} available on the Polkadot Wiki. - -## Stop the Node - -When you're done exploring your local node, you can stop it to remove any state changes you've made. Since you started the node with the `--dev` option, stopping the node will purge all persistent block data, allowing you to start fresh the next time. - -To stop the local node: - -1. Return to the terminal window where the node output is displayed. -2. Press `Control-C` to stop the running process. -3. Verify that your terminal returns to the prompt in the `parachain-template` directory. - -## Where to Go Next - -
- -- Tutorial __Deploy to Polkadot__ - - --- - - Learn how to deploy your parachain template to a relay chain testnet. Configure your chain specification, register as a parachain, and start producing blocks. - - [:octicons-arrow-right-24: Get Started](/parachains/launch-a-parachain/deploy-to-polkadot/) - -
- - ---- - -Page Title: Smart Contracts Cookbook - -- Source (raw): https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/smart-contracts-cookbook.md -- Canonical (HTML): https://docs.polkadot.com/smart-contracts/cookbook/ -- Summary: Explore our full collection of tutorials and guides to learn step-by-step how to build, deploy, and work with smart contracts on Polkadot. - -# Smart Contracts Cookbook - -Welcome to the Polkadot smart contracts cookbook index. - -This page contains a list of all relevant tutorials and guides to help you get started coding smart contracts and dApps in Polkadot. - - - - -## Get Tokens from the Faucet - -| Title | Difficulty | Tools | Description | -|------------------------------------|:-----------:|-------|-----------------------------------------------------------------------------------------------------------------------| -| [Faucet](/smart-contracts/faucet/) | 🟢 Beginner | N/A | Learn how to obtain test tokens from Polkadot faucets for development and testing purposes across different networks. | - -## EVM Smart Contracts - -| Title | Difficulty | Tools | Description | -|---------------------------------------------------------------------------------------------------------|:-----------:|--------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------| -| [Deploy an ERC-20 to Polkadot Hub](/smart-contracts/cookbook/smart-contracts/deploy-erc20/erc20-remix/) | 🟢 Beginner | EVM Wallet, Polkadot Remix IDE | Deploy an ERC-20 token on Polkadot Hub using PolkaVM. This guide covers contract creation, compilation, deployment, and interaction via Polkadot Remix IDE. | -| [Deploy an NFT to Polkadot Hub](/smart-contracts/cookbook/smart-contracts/deploy-nft/nft-remix/) | 🟢 Beginner | EVM Wallet, Polkadot Remix IDE | Deploy an NFT on Polkadot Hub using PolkaVM and OpenZeppelin. Learn how to compile, deploy, and interact with your contract using Polkadot Remix IDE. | - -## Port Ethereum DApps - -| Title | Difficulty | Tools | Description | -|-------------------------------------------------------------------------------------|:---------------:|---------|----------------------------------------------------------------------------------------------------------------------------------| -| [Deploying Uniswap V2 on Polkadot](/smart-contracts/cookbook/eth-dapps/uniswap-v2/) | 🟡 Intermediate | Hardhat | Learn how to deploy and test Uniswap V2 on Polkadot Hub using Hardhat, bringing AMM-based token swaps to the Polkadot ecosystem. | - - ---- - -Page Title: Smart Contracts Overview - -- Source (raw): https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/smart-contracts-overview.md -- Canonical (HTML): https://docs.polkadot.com/smart-contracts/overview/ -- Summary: Learn about smart contract development on Polkadot Hub with native PolkaVM support, dual-VM execution, and seamless cross-chain capabilities. - -# Smart Contracts on Polkadot Hub - -## Introduction - -Polkadot Hub provides a production-ready smart contract platform that combines Ethereum compatibility with the performance and cross-chain capabilities of the Polkadot ecosystem. Developers can deploy smart contracts directly on Polkadot Hub while using familiar Ethereum tooling, workflows, and programming languages. - -Built with a dual-VM approach, Polkadot Hub offers two execution backends: REVM for unmodified EVM compatibility and native PolkaVM for optimized computationally expensive workloads. This dual-VM architecture enables developers to migrate existing Ethereum contracts instantly or optimize for speed and efficiency with native execution. - -## Why Build on Polkadot Hub - -### Ethereum Compatibility - -Deploy existing Ethereum contracts with zero modifications while maintaining full compatibility with your existing development stack: - -- **Complete JSON-RPC API support**: Use MetaMask, Hardhat, Remix, Foundry, and all standard Ethereum tooling. -- **Standard libraries**: Integrate Ethers.js, Web3.js, Viem, Wagmi, and Web3.py without changes. -- **Solidity development**: Write contracts in Solidity or migrate existing code directly. -- **Familiar workflows**: Maintain your existing deployment, testing, and monitoring processes. - -### Performance Options - -Choose between two execution backends: - -- **REVM**: Run unmodified Ethereum contracts with full EVM/Ethereum compatibility. -- **PolkaVM**: Compile to optimized RISC-V bytecode for enhanced performance and lower fees while keeping Ethereum-compatibility. +- **`keystore_key_types?`** ++"string[]"++: Defines which keystore keys should be created. +- **`validator`** ++"boolean"++: Pass the `--validator` flag to the command. Defaults to `true`. +- **`invulnerable`** ++"boolean"++: If true, add the node to invulnerables in the chain spec. Defaults to `false`. +- **`balance`** ++"number"++: Balance to set in balances for node's account. Defaults to `2000000000000`. +- **`bootnodes?`** ++"string[]"++: Array of bootnodes to use. +- **`add_to_bootnodes?`** ++"boolean"++: Add this node to the bootnode list. Defaults to `false`. +- **`ws_port?`** ++"number"++: WS port to use. +- **`rpc_port?`** ++"number"++: RPC port to use. +- **`prometheus_port?`** ++"number"++: Prometheus port to use. +- **`p2p_cert_hash?`** ++"string"++: Libp2p certhash to use with webRTC transport. +- **`delay_network_settings?`** ++"DelayNetworkSettings"++: Sets the expected configuration to delay the network. -Both backends share the same RPC interface and tooling support, allowing seamless transitions. In addition, smart contracts can interact with Polkadot native services via [precompile contracts](/smart-contracts/precompiles/){target=\_blank}. + ??? child "`DelayNetworkSettings` interface definition" + ```js + export interface DelayNetworkSettings { + latency: string; + correlation?: string; // should be parsable as float by k8s + jitter?: string; + } + ``` -### Cross-VM & Cross-Chain Capabilities +The following configuration file defines a minimal example for the relay chain, including the `nodes` key: -Smart contracts written for one VM (for example, EVM) can interact directly with other smart contracts written for the RISC-V PolkaVM, and back. This allows to use full EVM compatible contracts but extend to heavy/complex execution workloads to the PolkaVM RISC-V backend. +=== "TOML" -Furthermore, all smart contracts in Polkadot Hub can interact with any service in the Polkadot ecosystem through [XCM](/smart-contracts/precompiles/xcm/){target=\_blank}, enabling token transfers, remote execution, and cross-chain composability without bridges or intermediaries. + ```toml title="relaychain-example-nodes.toml" + [relaychain] + default_command = "polkadot" + default_image = "polkadot-debug:master" + chain = "rococo-local" + chain_spec_path = "INSERT_PATH_TO_CHAIN_SPEC" + default_args = ["--chain", "rococo-local"] -## Other Smart Contract Environments + [[relaychain.nodes]] + name = "alice" + validator = true + balance = 1000000000000 -Beyond Polkadot Hub's native PolkaVM support, the ecosystem offers two main alternatives for smart contract development: + [[relaychain.nodes]] + name = "bob" + validator = true + balance = 1000000000000 + # ... -- **EVM-compatible parachains**: Provide access to Ethereum's extensive developer ecosystem, smart contract portability, and established tooling like Hardhat, Remix, Foundry, and OpenZeppelin. The main options include Moonbeam (the first full Ethereum-compatible parachain serving as an interoperability hub), Astar (featuring dual VM support for both EVM and WebAssembly contracts), and Acala (DeFi-focused with enhanced Acala EVM+ offering advanced DeFi primitives). + ``` -- **Rust (ink!)**: ink! is a Rust-based framework that can compile to PolkaVM. It uses [`#[ink(...)]`](https://use.ink/docs/v6/macros-attributes/){target=\_blank} attribute macros to create Polkadot SDK-compatible PolkaVM bytecode, offering strong memory safety from Rust, an advanced type system, high-performance PolkaVM execution, and platform independence with sandboxed security. +=== "JSON" -## Next Steps + ```json title="relaychain-example-nodes.json" + { + "relaychain": { + "default_command": "polkadot", + "default_image": "polkadot-debug:master", + "chain": "rococo-local", + "chain_spec_path": "INSERT_PATH_TO_CHAIN-SPEC.JSON", + "default_args": ["--chain", "rococo-local"], + "nodes": [ + { + "name": "alice", + "validator": true, + "balance": 1000000000000 + }, + { + "name": "bob", + "validator": true, + "balance": 1000000000000 + } + ] + } + } -
+ ``` -- Guide __Get Started__ +#### Node Group Configuration - --- +The `node_groups` key defines further parameters for the node groups. The available keys are: - Quick-start guides for connecting, deploying, and building your first smart contract. +- **`name`** ++"string"++: Name of the node. Any whitespace will be replaced with a dash (for example, `new alice` will be converted to `new-alice`). +- **`image?`** ++"string"++: Override default Docker image to use for this node. +- **`command?`** ++"string"++: Override default command to run. +- **`args?`** ++"string[]"++: Arguments to be passed to the command. +- **`env?`** ++"envVars[]"++: Environment variables to set in the container. + + ??? child "`envVars` interface definition" + ```js + export interface EnvVars { + name: string; + value: string; + } + ``` - [:octicons-arrow-right-24: Get Started](/smart-contracts/get-started/) +- **`overrides?`** ++"Override[]"++: Array of overrides definitions. -- Guide __Cookbook__ + ??? child "`Override` interface definition" + ```js + export interface Override { + local_path: string; + remote_name: string; + } + ``` - --- +- **`prometheus_prefix?`** ++"string"++: Customizes the metric's prefix for the specific node. Defaults to `substrate`. +- **`db_snapshot?`** ++"string"++: Database snapshot to use. +- **`substrate_cli_args_version?`** ++"SubstrateCliArgsVersion"++: Set the Substrate CLI arguments version directly to skip binary evaluation overhead. - Step-by-step tutorials for deploying contracts, tokens, NFTs, and full dApps. + ??? child "`SubstrateCliArgsVersion` enum definition" + ```js + export enum SubstrateCliArgsVersion { + V0 = 0, + V1 = 1, + V2 = 2, + V3 = 3, + } + ``` - [:octicons-arrow-right-24: View Tutorials](/smart-contracts/cookbook/) +- **`resources?`** ++"Resources"++: Represent the resources limits/reservations needed by the node. -- Guide __Ethereum Developers__ + ??? child "`Resources` interface definition" + ```js + export interface Resources { + resources: { + requests?: { + memory?: string; + cpu?: string; + }; + limits?: { + memory?: string; + cpu?: string; + }; + }; + } + ``` - --- +- **`keystore_key_types?`** ++"string[]"++: Defines which keystore keys should be created. +- **`count`** ++"number | string"++: Number of nodes to launch for this group. +- **`delay_network_settings?`** ++"DelayNetworkSettings"++: Sets the expected configuration to delay the network. - Understand key differences in accounts, fees, gas model, and deployment on Polkadot Hub. + ??? child "`DelayNetworkSettings` interface definition" + ```js + export interface DelayNetworkSettings { + latency: string; + correlation?: string; // should be parsable as float by k8s + jitter?: string; + } + ``` - [:octicons-arrow-right-24: Learn More](/smart-contracts/for-eth-devs/accounts/) +The following configuration file defines a minimal example for the relay chain, including the `node_groups` key: -- Guide __Precompiles__ +=== "TOML" - --- + ```toml title="relaychain-example-node-groups.toml" + [relaychain] + default_command = "polkadot" + default_image = "polkadot-debug:master" + chain = "rococo-local" + chain_spec_path = "INSERT_PATH_TO_CHAIN_SPEC" + default_args = ["--chain", "rococo-local"] - Discover advanced functionalities including XCM for cross-chain interactions. + [[relaychain.node_groups]] + name = "group-1" + count = 2 + image = "polkadot-debug:master" + command = "polkadot" + args = ["--chain", "rococo-local"] + # ... - [:octicons-arrow-right-24: Explore Precompiles](/smart-contracts/precompiles/) + ``` -
+=== "JSON" + ```json title="relaychain-example-node-groups.json" + { + "relaychain": { + "default_command": "polkadot", + "default_image": "polkadot-debug:master", + "chain": "rococo-local", + "chain_spec_path": "INSERT_PATH_TO_CHAIN-SPEC.JSON", + "default_args": ["--chain", "rococo-local"], + "node_groups": [ + { + "name": "group-1", + "count": 2, + "image": "polkadot-debug:master", + "command": "polkadot", + "args": ["--chain", "rococo-local"] + } + ], + "...": {} + }, + "...": {} + } ---- + ``` -Page Title: Subxt Rust API +### Parachain Configuration -- Source (raw): https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/reference-tools-subxt.md -- Canonical (HTML): https://docs.polkadot.com/reference/tools/subxt/ -- Summary: Subxt is a Rust library for type-safe interaction with Polkadot SDK blockchains, enabling transactions, state queries, runtime API access, and more. +The `parachain` keyword defines further parameters for the parachain. The available keys are: -# Subxt Rust API +- **`id`** ++"number"++: The id to assign to this parachain. Must be unique. +- **`chain?`** ++"string"++: The chain name. +- **`force_decorator?`** ++"string"++: Force the use of a specific decorator. +- **`genesis?`** ++"JSON"++: The genesis configuration. +- **`balance?`** ++"number"++: Balance to set in balances for parachain's account. +- **`delay_network_settings?`** ++"DelayNetworkSettings"++: Sets the expected configuration to delay the network. -## Introduction + ??? child "`DelayNetworkSettings` interface definition" + ```js + export interface DelayNetworkSettings { + latency: string; + correlation?: string; // should be parsable as float by k8s + jitter?: string; + } + ``` -Subxt is a Rust library designed to interact with Polkadot SDK-based blockchains. It provides a type-safe interface for submitting transactions, querying on-chain state, and performing other blockchain interactions. By leveraging Rust's strong type system, subxt ensures that your code is validated at compile time, reducing runtime errors and improving reliability. +- **`add_to_genesis?`** ++"boolean"++: Flag to add parachain to genesis or register in runtime. Defaults to `true`. +- **`register_para?`** ++"boolean"++: Flag to specify whether the para should be registered. The `add_to_genesis` flag must be set to false for this flag to have any effect. Defaults to `true`. +- **`onboard_as_parachain?`** ++"boolean"++: Flag to specify whether the para should be onboarded as a parachain, rather than remaining a parathread. Defaults to `true`. +- **`genesis_wasm_path?`** ++"string"++: Path to the Wasm file to use. +- **`genesis_wasm_generator?`** ++"string"++: Command to generate the Wasm file. +- **`genesis_state_path?`** ++"string"++: Path to the state file to use. +- **`genesis_state_generator?`** ++"string"++: Command to generate the state file. +- **`chain_spec_path?`** ++"string"++: Path to the chain spec file. +- **`chain_spec_command?`** ++"string"++: Command to generate the chain spec. +- **`cumulus_based?`** ++"boolean"++: Flag to use cumulus command generation. Defaults to `true`. +- **`bootnodes?`** ++"string[]"++: Array of bootnodes to use. +- **`prometheus_prefix?`** ++"string"++: Parameter for customizing the metric's prefix for all parachain nodes/collators. Defaults to `substrate`. +- **`collator?`** ++"Collator"++: Further defined in the [Collator Configuration](#collator-configuration) section. +- **`collator_groups?`** ++"CollatorGroup[]"++: An array of collator groups to spawn. It is further defined in the [Collator Groups Configuration](#collator-groups-configuration) section. + +For example, the following configuration file defines a minimal example for the parachain: -## Prerequisites +=== "TOML" -Before using subxt, ensure you have the following requirements: + ```toml title="parachain-example.toml" + [parachain] + id = 100 + add_to_genesis = true + cumulus_based = true + genesis_wasm_path = "INSERT_PATH_TO_WASM" + genesis_state_path = "INSERT_PATH_TO_STATE" + # ... -- Rust and Cargo installed on your system. You can install them using [Rustup](https://rustup.rs/){target=\_blank}. -- A Rust project initialized. If you don't have one, create it with: - ```bash - cargo new my_project && cd my_project ``` -## Installation - -To use subxt in your project, you must install the necessary dependencies. Each plays a specific role in enabling interaction with the blockchain: +=== "JSON" -1. **Install the subxt CLI**: [`subxt-cli`](https://crates.io/crates/subxt-cli){target=\_blank} is a command-line tool that provides utilities for working with Polkadot SDK metadata. In the context of subxt, it is essential to download chain metadata, which is required to generate type-safe Rust interfaces for interacting with the blockchain. Install it using the following: + ```json title="parachain-example.json" + { + "parachain": { + "id": 100, + "add_to_genesis": true, + "cumulus_based": true, + "genesis_wasm_path": "INSERT_PATH_TO_WASM", + "genesis_state_path": "INSERT_PATH_TO_STATE", + "...": {} + }, + "...": {} + } - ```bash - cargo install subxt-cli@0.44.0 ``` -2. **Add core dependencies**: These dependencies are essential for interacting with the blockchain. +#### Collator Configuration + +One specific key capable of receiving more subkeys is the `collator` key. This key defines further parameters for the nodes. The available keys are: - - **[subxt](https://crates.io/crates/subxt){target=\_blank}**: The main library for communicating with Polkadot SDK nodes. It handles RPC requests, encoding/decoding, and type generation. +- **`name`** ++"string"++: Name of the collator. Any whitespace will be replaced with a dash (for example, `new alice` will be converted to `new-alice`). +- **`image?`** ++"string"++: Image to use for the collator. +- **`command_with_args?`** ++"string"++: Overrides both command and arguments for the collator. +- **`validator`** ++"boolean"++: Pass the `--validator` flag to the command. Defaults to `true`. +- **`invulnerable`** ++"boolean"++: If true, add the collator to invulnerables in the chain spec. Defaults to `false`. +- **`balance`** ++"number"++: Balance to set in balances for collator's account. Defaults to `2000000000000`. +- **`bootnodes?`** ++"string[]"++: Array of bootnodes to use. +- **`add_to_bootnodes?`** ++"boolean"++: Add this collator to the bootnode list. Defaults to `false`. +- **`ws_port?`** ++"number"++: WS port to use. +- **`rpc_port?`** ++"number"++: RPC port to use. +- **`prometheus_port?`** ++"number"++: Prometheus port to use. +- **`p2p_port?`** ++"number"++: P2P port to use. +- **`p2p_cert_hash?`** ++"string"++: Libp2p certhash to use with webRTC transport. +- **`delay_network_settings?`** ++"DelayNetworkSettings"++: Sets the expected configuration to delay the network. - ```bash - cargo add subxt@0.44.0 + ??? child "`DelayNetworkSettings` interface definition" + ```js + export interface DelayNetworkSettings { + latency: string; + correlation?: string; // should be parsable as float by k8s + jitter?: string; + } ``` - - **[subxt-signer](https://crates.io/crates/subxt-signer){target=\_blank}**: Provides cryptographic functionality for signing transactions. Without this, you can only read data but cannot submit transactions. +- **`command?`** ++"string"++: Override default command to run. +- **`args?`** ++"string[]"++: Arguments to be passed to the command. +- **`env?`** ++"envVars[]"++: Environment variables to set in the container. - ```bash - cargo add subxt-signer@0.44.0 + ??? child "`envVars` interface definition" + ```js + export interface EnvVars { + name: string; + value: string; + } ``` - - **[tokio](https://crates.io/crates/tokio){target=\_blank}**: An asynchronous runtime for Rust. Since blockchain operations are async, Tokio enables the efficient handling of network requests. The `rt` feature enables Tokio's runtime, including the current-thread single-threaded scheduler, which is necessary for async execution. The `macros` feature provides procedural macros like `#[tokio::main]` to simplify runtime setup. +- **`overrides?`** ++"Override[]"++: Array of overrides definitions. - ```bash - cargo add tokio@1.44.2 --features rt,macros + ??? child "`Override` interface definition" + ```js + export interface Override { + local_path: string; + remote_name: string; + } ``` - After adding the dependencies, your `Cargo.toml` should look like this: - - ```toml - [package] - name = "my_project" - version = "0.1.0" - edition = "2021" +- **`prometheus_prefix?`** ++"string"++: Customizes the metric's prefix for the specific node. Defaults to `substrate`. +- **`db_snapshot?`** ++"string"++: Database snapshot to use. +- **`substrate_cli_args_version?`** ++"SubstrateCliArgsVersion"++: Set the Substrate CLI arguments version directly to skip binary evaluation overhead. - [dependencies] - subxt = "0.41.0" - subxt-signer = "0.41.0" - tokio = { version = "1.44.2", features = ["rt", "macros"] } + ??? child "`SubstrateCliArgsVersion` enum definition" + ```js + export enum SubstrateCliArgsVersion { + V0 = 0, + V1 = 1, + V2 = 2, + V3 = 3, + } + ``` - ``` +- **`resources?`** ++"Resources"++: Represent the resources limits/reservations needed by the node. -## Get Started + ??? child "`Resources` interface definition" + ```js + export interface Resources { + resources: { + requests?: { + memory?: string; + cpu?: string; + }; + limits?: { + memory?: string; + cpu?: string; + }; + }; + } + ``` -This guide will walk you through the fundamental operations of subxt, from setting up your environment to executing transactions and querying blockchain state. +- **`keystore_key_types?`** ++"string[]"++: Defines which keystore keys should be created. -### Download Chain Metadata +The configuration file below defines a minimal example for the collator: -Before interacting with a blockchain, you need to retrieve its metadata. This metadata defines storage structures, extrinsics, and other runtime details. Use the `subxt-cli` tool to download the metadata, replacing `INSERT_NODE_URL` with the URL of the node you want to interact with: +=== "TOML" -```bash -subxt metadata --url INSERT_NODE_URL > polkadot_metadata.scale -``` + ```toml title="collator-example.toml" + [parachain] + id = 100 + add_to_genesis = true + cumulus_based = true + genesis_wasm_path = "INSERT_PATH_TO_WASM" + genesis_state_path = "INSERT_PATH_TO_STATE" -### Generate Type-Safe Interfaces + [[parachain.collators]] + name = "alice" + image = "polkadot-parachain" + command = "polkadot-parachain" + # ... -Use the `#[subxt::subxt]` macro to generate a type-safe Rust interface from the downloaded metadata: + ``` -```rust -// Generate an interface that we can use from the node's metadata. -#[subxt::subxt(runtime_metadata_path = "./polkadot_metadata.scale")] -pub mod polkadot {} -``` +=== "JSON" -Once subxt interfaces are generated, you can interact with your node in the following ways. You can use the links below to view the related subxt documentation: + ```json title="collator-example.json" + { + "parachain": { + "id": 100, + "add_to_genesis": true, + "cumulus_based": true, + "genesis_wasm_path": "INSERT_PATH_TO_WASM", + "genesis_state_path": "INSERT_PATH_TO_STATE", + "collators": [ + { + "name": "alice", + "image": "polkadot-parachain", + "command": "polkadot-parachain", + "...": {} + } + ] + }, + "...": {} + } -- **[Transactions](https://docs.rs/subxt/latest/subxt/book/usage/transactions/index.html){target=\_blank}**: Builds and submits transactions, monitors their inclusion in blocks, and retrieves associated events. -- **[Storage](https://docs.rs/subxt/latest/subxt/book/usage/storage/index.html){target=\_blank}**: Enables querying of node storage data. -- **[Events](https://docs.rs/subxt/latest/subxt/book/usage/events/index.html){target=\_blank}**: Retrieves events emitted from recent blocks. -- **[Constants](https://docs.rs/subxt/latest/subxt/book/usage/constants/index.html){target=\_blank}**: Accesses constant values stored in nodes that remain unchanged across a specific runtime version. -- **[Blocks](https://docs.rs/subxt/latest/subxt/book/usage/blocks/index.html){target=\_blank}**: Loads recent blocks or subscribes to new/finalized blocks, allowing examination of extrinsics, events, and storage at those blocks. -- **[Runtime APIs](https://docs.rs/subxt/latest/subxt/book/usage/runtime_apis/index.html){target=\_blank}**: Makes calls into pallet runtime APIs to fetch data. -- **[Custom values](https://docs.rs/subxt/latest/subxt/book/usage/custom_values/index.html){target=\_blank}**: Accesses "custom values" contained within metadata. -- **[Raw RPC calls](https://docs.rs/subxt/latest/subxt/book/usage/rpc/index.html){target=\_blank}**: Facilitates raw RPC requests to compatible nodes. + ``` -### Initialize the Subxt Client +#### Collator Groups Configuration -To interact with a blockchain node using subxt, create an asynchronous main function and initialize the client. Replace `INSERT_NODE_URL` with the URL of your target node: +The `collator_groups` key defines further parameters for the collator groups. The available keys are: -```rust -use std::str::FromStr; -use subxt::utils::AccountId32; -use subxt::{OnlineClient, PolkadotConfig}; -use subxt_signer::{bip39::Mnemonic,sr25519::Keypair}; +- **`name`** ++"string"++: Name of the node. Any whitespace will be replaced with a dash (for example, `new alice` will be converted to `new-alice`). +- **`image?`** ++"string"++: Override default Docker image to use for this node. +- **`command?`** ++"string"++: Override default command to run. +- **`args?`** ++"string[]"++: Arguments to be passed to the command. +- **`env?`** ++"envVars[]"++: Environment variables to set in the container. -// Generate an interface that we can use from the node's metadata. -#[subxt::subxt(runtime_metadata_path = "./polkadot_metadata.scale")] -pub mod polkadot {} + ??? child "`envVars` interface definition" + ```js + export interface EnvVars { + name: string; + value: string; + } + ``` -#[tokio::main(flavor = "current_thread")] -async fn main() -> Result<(), Box> { - // Define the node URL. - const NODE_URL: &str = "INSERT_NODE_URL"; +- **`overrides?`** ++"Override[]"++: Array of overrides definitions. - // Initialize the Subxt client to interact with the blockchain. - let api = OnlineClient::::from_url(NODE_URL).await?; + ??? child "`Override` interface definition" + ```js + export interface Override { + local_path: string; + remote_name: string; + } + ``` - // Your code here... +- **`prometheus_prefix?`** ++"string"++: Customizes the metric's prefix for the specific node. Defaults to `substrate`. +- **`db_snapshot?`** ++"string"++: Database snapshot to use. +- **`substrate_cli_args_version?`** ++"SubstrateCliArgsVersion"++: Set the Substrate CLI arguments version directly to skip binary evaluation overhead. - Ok(()) -} -``` + ??? child "`SubstrateCliArgsVersion` enum definition" + ```js + export enum SubstrateCliArgsVersion { + V0 = 0, + V1 = 1, + V2 = 2, + V3 = 3, + } + ``` -### Read Chain Data +- **`resources?`** ++"Resources"++: Represent the resources limits/reservations needed by the node. -subxt provides multiple ways to access on-chain data: + ??? child "`Resources` interface definition" + ```js + export interface Resources { + resources: { + requests?: { + memory?: string; + cpu?: string; + }; + limits?: { + memory?: string; + cpu?: string; + }; + }; + } + ``` -- **Constants**: Constants are predefined values in the runtime that remain unchanged unless modified by a runtime upgrade. +- **`keystore_key_types?`** ++"string[]"++: Defines which keystore keys should be created. +- **`count`** ++"number | string"++: Number of nodes to launch for this group. +- **`delay_network_settings?`** ++"DelayNetworkSettings"++: Sets the expected configuration to delay the network. - For example, to retrieve the existential deposit, use: - - ```rust - // A query to obtain some constant. - let constant_query = polkadot::constants().balances().existential_deposit(); + ??? child "`DelayNetworkSettings` interface definition" + ```js + export interface DelayNetworkSettings { + latency: string; + correlation?: string; // should be parsable as float by k8s + jitter?: string; + } + ``` - // Obtain the value. - let value = api.constants().at(&constant_query)?; +For instance, the configuration file below defines a minimal example for the collator groups: - println!("Existential deposit: {:?}", value); - ``` +=== "TOML" -- **State**: State refers to the current chain data, which updates with each block. + ```toml title="collator-groups-example.toml" + [parachain] + id = 100 + add_to_genesis = true + cumulus_based = true + genesis_wasm_path = "INSERT_PATH_TO_WASM" + genesis_state_path = "INSERT_PATH_TO_STATE" - To fetch account information, replace `INSERT_ADDRESS` with the address you want to fetch data from and use: + [[parachain.collator_groups]] + name = "group-1" + count = 2 + image = "polkadot-parachain" + command = "polkadot-parachain" + # ... - ```rust - // Define the target account address. - const ADDRESS: &str = "INSERT_ADDRESS"; - let account = AccountId32::from_str(ADDRESS).unwrap(); - - // Build a storage query to access account information. - let storage_query = polkadot::storage().system().account(&account.into()); - - // Fetch the latest state for the account. - let result = api - .storage() - .at_latest() - .await? - .fetch(&storage_query) - .await? - .unwrap(); - - println!("Account info: {:?}", result); ``` -### Submit Transactions - -To submit a transaction, you must construct an extrinsic, sign it with your private key, and send it to the blockchain. Replace `INSERT_DEST_ADDRESS` with the recipient's address, `INSERT_AMOUNT` with the amount to transfer, and `INSERT_SECRET_PHRASE` with the sender's mnemonic phrase: +=== "JSON" -```rust - // Define the recipient address and transfer amount. - const DEST_ADDRESS: &str = "INSERT_DEST_ADDRESS"; - const AMOUNT: u128 = INSERT_AMOUNT; - - // Convert the recipient address into an `AccountId32`. - let dest = AccountId32::from_str(DEST_ADDRESS).unwrap(); - - // Build the balance transfer extrinsic. - let balance_transfer_tx = polkadot::tx() - .balances() - .transfer_allow_death(dest.into(), AMOUNT); - - // Load the sender's keypair from a mnemonic phrase. - const SECRET_PHRASE: &str = "INSERT_SECRET_PHRASE"; - let mnemonic = Mnemonic::parse(SECRET_PHRASE).unwrap(); - let sender_keypair = Keypair::from_phrase(&mnemonic, None).unwrap(); - - // Sign and submit the extrinsic, then wait for it to be finalized. - let events = api - .tx() - .sign_and_submit_then_watch_default(&balance_transfer_tx, &sender_keypair) - .await? - .wait_for_finalized_success() - .await?; - - // Check for a successful transfer event. - if let Some(event) = events.find_first::()? { - println!("Balance transfer successful: {:?}", event); + ```json title="collator-groups-example.json" + { + "parachain": { + "id": 100, + "add_to_genesis": true, + "cumulus_based": true, + "genesis_wasm_path": "INSERT_PATH_TO_WASM", + "genesis_state_path": "INSERT_PATH_TO_STATE", + "collator_groups": [ + { + "name": "group-1", + "count": 2, + "image": "polkadot-parachain", + "command": "polkadot-parachain", + "...": {} + } + ] + }, + "...": {} } -``` - -## Where to Go Next -Now that you've covered the basics dive into the official [subxt documentation](https://docs.rs/subxt/latest/subxt/book/index.html){target=\_blank} for comprehensive reference materials and advanced features. - - ---- - -Page Title: Technical Reference Overview - -- Source (raw): https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/reference.md -- Canonical (HTML): https://docs.polkadot.com/reference/ -- Summary: Learn about Polkadot's technical architecture, governance framework, parachain ecosystem, and the tools you need to build and interact with the network. - -## Introduction + ``` -The Technical Reference section provides comprehensive documentation of Polkadot's architecture, core concepts, and development tooling. Whether you're exploring how Polkadot's relay chain coordinates parachains, understanding governance mechanisms, or building applications on the network, this reference covers the technical foundations you need. +### XCM Configuration -Polkadot is a multi-chain network that enables diverse, interconnected blockchains to share security and communicate seamlessly. Understanding how these components interact from the [relay chain](/polkadot-protocol/glossary#relay-chain){target=\_blank} that validates [parachains](/polkadot-protocol/glossary#parachain){target=\_blank} to the [governance](/reference/glossary#governance){target=\_blank} mechanisms that evolve the protocol is essential for developers, validators, and network participants. +You can use the `hrmp_channels` keyword to define further parameters for the XCM channels at start-up. The available keys are: -This guide organizes technical documentation across five core areas: Polkadot Hub, Parachains, On-Chain Governance, Glossary, and Tools, each providing detailed information on different aspects of the Polkadot ecosystem. +- **`hrmp_channels`** ++"HrmpChannelsConfig[]"++: Array of Horizontal Relay-routed Message Passing (HRMP) channel configurations. -## Polkadot Hub + ??? child "`HrmpChannelsConfig` interface definition" + ```js + export interface HrmpChannelsConfig { + sender: number; + recipient: number; + max_capacity: number; + max_message_size: number; + } + ``` + Each of the `HrmpChannelsConfig` keys are defined as follows: -[Polkadot Hub](/reference/polkadot-hub/){target=\_blank} is the entry point to Polkadot for all users and application developers. It provides access to essential Web3 services, including smart contracts, staking, governance, identity management, and cross-ecosystem interoperability—without requiring you to deploy or manage a parachain. + - **`sender` ++"number"++**: Parachain ID of the sender. + - **`recipient` ++"number"++**: Parachain ID of the recipient. + - **`max_capacity` ++"number"++**: Maximum capacity of the HRMP channel. + - **`max_message_size` ++"number"++**: Maximum message size allowed in the HRMP channel. -The Hub encompasses a set of core functionality that enables developers and users to build and interact with applications on Polkadot. Key capabilities include: +## Where to Go Next -- **Smart contracts**: Deploy Ethereum-compatible smart contracts and build decentralized applications. -- **Assets and tokens**: Create, manage, and transfer fungible tokens and NFTs across the ecosystem. -- **Staking**: Participate in network security and earn rewards by staking DOT. -- **Governance**: Vote on proposals and participate in Polkadot's decentralized decision-making through OpenGov. -- **Identity services**: Register and manage on-chain identities, enabling access to governance roles and network opportunities. -- **Cross-chain interoperability**: Leverage XCM messaging to interact securely with other chains in the Polkadot ecosystem. -- **Collectives and DAOs**: Participate in governance collectives and decentralized autonomous organizations. +
-## Parachains +- External __Zombienet Support__ -[Parachains](/reference/parachains/){target=\_blank} are specialized blockchains that connect to the Polkadot relay chain, inheriting its security while maintaining their own application-specific logic. The parachains documentation covers: + --- -- **Accounts**: Deep dive into account types, storage, and management on parachains. -- **Blocks, transactions and fees**: Understand block production, transaction inclusion, and fee mechanisms. -- **Consensus**: Learn how parachain blocks are validated and finalized through the relay chain's consensus. -- **Chain data**: Explore data structures, storage layouts, and state management. -- **Cryptography**: Study cryptographic primitives used in Polkadot SDK-based chains. -- **Data encoding**: Understand how data is encoded and decoded for blockchain compatibility. -- **Networks**: Learn about networking protocols and peer-to-peer communication. -- **Interoperability**: Discover [Cross-Consensus Messaging (XCM)](/parachains/interoperability/get-started/){target=\_blank}, the standard for cross-chain communication. -- **Randomness**: Understand how randomness is generated and used in Polkadot chains. -- **Node and runtime**: Learn about parachain nodes, runtime environments, and the [Polkadot SDK](https://github.com/paritytech/polkadot-sdk){target=\_blank}. + [Parity Technologies](https://www.parity.io/){target=\_blank} has designed and developed this framework, now maintained by the Zombienet team. -## On-Chain Governance + For further support and information, refer to the following contact points: -[On-Chain governance](/reference/governance/){target=\_blank} is the decentralized decision-making mechanism for the Polkadot network. It manages the evolution and modification of the network's runtime logic, enabling community oversight and approval for proposed changes. The governance documentation details: + [:octicons-arrow-right-24: Zombienet repository](https://github.com/paritytech/zombienet){target=\_blank} -- **OpenGov framework**: Understand Polkadot's next-generation governance system with enhanced delegation, flexible tracks, and simultaneous referendums. -- **Origins and tracks**: Learn how governance proposals are categorized, prioritized, and executed based on their privilege level and complexity. -- **Voting and delegation**: Explore conviction voting, vote delegation, and how token holders participate in governance. -- **Governance evolution**: See how Polkadot's governance has evolved from Governance V1 to the current OpenGov system. + [:octicons-arrow-right-24: Element public channel](https://matrix.to/#/!FWyuEyNvIFygLnWNMh:parity.io?via=parity.io&via=matrix.org&via=web3.foundation){target=\_blank} -## Glossary +
-The [Glossary](/reference/glossary/){target=\_blank} provides quick-reference definitions for Polkadot-specific terminology. Essential terms include: -- Blockchain concepts (blocks, transactions, state) -- Consensus mechanisms (validators, collators, finality) -- Polkadot-specific terms (relay chain, parachain, XCM, FRAME) -- Network components (nodes, runtimes, storage) -- Governance terminology (origins, tracks, referendums) +--- -## Tools +Page Title: Set Up the Polkadot SDK Parachain Template -The [Tools](/reference/tools/){target=\_blank} section documents essential development and interaction tools for the Polkadot ecosystem: +- Source (raw): https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/parachains-launch-a-parachain-set-up-the-parachain-template.md +- Canonical (HTML): https://docs.polkadot.com/parachains/launch-a-parachain/set-up-the-parachain-template/ +- Summary: Learn how to set up and run the Polkadot SDK Parachain Template locally, creating a ready-to-customize foundation for your parachain. -- **Light clients**: Lightweight solutions for interacting with the network without running full nodes. -- **JavaScript/TypeScript tools**: Libraries like [Polkadot.js API](/reference/tools/polkadot-js-api/){target=\_blank} and [PAPI](/reference/tools/papi/){target=\_blank} for building applications. -- **Rust tools**: [Polkadart](/reference/tools/polkadart/){target=\_blank} and other Rust-based libraries for SDK development. -- **Python tools**: [py-substrate-interface](/reference/tools/py-substrate-interface/){target=\_blank} for Python developers. -- **Testing and development**: Tools like [Moonwall](/reference/tools/moonwall/){target=\_blank}, [Chopsticks](/reference/tools/chopsticks/){target=\_blank}, and [Omninode](/reference/tools/omninode/){target=\_blank} for smart contract and parachain testing. -- **Indexing and monitoring**: [Sidecar](/reference/tools/sidecar/){target=\_blank} for data indexing and [Dedot](/reference/tools/dedot/){target=\_blank} for substrate interaction. -- **Cross-chain tools**: [ParaSpell](/reference/tools/paraspell/){target=\_blank} for XCM integration and asset transfers. +# Set Up the Polkadot SDK Parachain Template -## Where to Go Next +## Introduction -For detailed exploration of specific areas, proceed to any of the main sections: +The [Polkadot SDK](https://github.com/paritytech/polkadot-sdk){target=\_blank} includes several [templates](/parachains/customize-runtime/#starting-templates){target=\_blank} designed to help you quickly start building your own blockchain. Each template offers a different level of configuration, from minimal setups to feature-rich environments, allowing you to choose the foundation that best fits your project's needs. -
+Among these, the [Parachain Template](https://github.com/paritytech/polkadot-sdk-parachain-template){target=\_blank} provides a preconfigured runtime with commonly used pallets, making it an ideal starting point for most parachain development projects. -- Learn **Polkadot Hub** +This guide walks you through the full process of working with this template. You will: - --- +- Set up the Polkadot SDK Parachain Template. +- Understand the project structure and key components. +- Verify your template is ready for development. +- Run the parachain template locally in development mode. - Understand the relay chain's role in coordinating parachains, providing shared security, and enabling governance. +By the end of this guide, you'll have a working template ready to customize and deploy as a parachain. - [:octicons-arrow-right-24: Reference](/reference/polkadot-hub/) +## Prerequisites -- Learn **Parachains** +Before getting started, ensure you have done the following: - --- +- Completed the [Install Polkadot SDK](/parachains/install-polkadot-sdk/){target=\_blank} guide and successfully installed [Rust](https://www.rust-lang.org/){target=\_blank} and the required packages to set up your development environment. - Deep dive into parachain architecture, consensus, data structures, and building application-specific blockchains. +For this tutorial series, you need to use Rust `1.86`. Newer versions of the compiler may not work with this parachain template version. - [:octicons-arrow-right-24: Reference](/reference/parachains/) +Run the following commands to set up the correct Rust version: -- Learn **On-Chain Governance** +=== "macOS" - --- + ```bash + rustup install 1.86 + rustup default 1.86 + rustup target add wasm32-unknown-unknown --toolchain 1.86-aarch64-apple-darwin + rustup component add rust-src --toolchain 1.86-aarch64-apple-darwin + ``` - Explore Polkadot's decentralized governance framework and how to participate in network decision-making. +=== "Ubuntu" - [:octicons-arrow-right-24: Reference](/reference/governance/) + ```bash + rustup toolchain install 1.86.0 + rustup default 1.86.0 + rustup target add wasm32-unknown-unknown --toolchain 1.86.0 + rustup component add rust-src --toolchain 1.86.0 + ``` -- Guide **Glossary** +## Polkadot SDK Utility Tools - --- +This tutorial requires two essential tools: - Quick reference for Polkadot-specific terminology and concepts used throughout the documentation. +- [**Chain spec builder**](https://crates.io/crates/staging-chain-spec-builder/10.0.0){target=\_blank}: A Polkadot SDK utility for generating chain specifications. Refer to the [Generate Chain Specs](/parachains/launch-a-parachain/deploy-to-polkadot/#generate-the-chain-specification){target=\_blank} documentation for detailed usage. + + Install it by executing the following command: + + ```bash + cargo install --locked staging-chain-spec-builder@10.0.0 + ``` - [:octicons-arrow-right-24: Reference](/reference/glossary/) + This command installs the `chain-spec-builder` binary. -- Guide **Tools** +- [**Polkadot Omni Node**](https://crates.io/crates/polkadot-omni-node/0.5.0){target=\_blank}: A white-labeled binary, released as a part of Polkadot SDK that can act as the collator of a parachain in production, with all the related auxiliary functionalities that a normal collator node has: RPC server, archiving state, etc. Moreover, it can also run the Wasm blob of the parachain locally for testing and development. - --- + To install it, run the following command: - Discover development tools, libraries, and frameworks for building and interacting with Polkadot. + ```bash + cargo install --locked polkadot-omni-node@0.5.0 + ``` - [:octicons-arrow-right-24: Reference](/reference/tools/) + This command installs the `polkadot-omni-node` binary. -
+## Clone the Template +The [Polkadot SDK Parachain Template](https://github.com/paritytech/polkadot-sdk-parachain-template){target=\_blank} provides a ready-to-use development environment for building with the [Polkadot SDK](https://github.com/paritytech/polkadot-sdk){target=\_blank}. Follow these steps to set up the template: ---- +1. Clone the template repository: -Page Title: Transactions + ```bash + git clone https://github.com/paritytech/polkadot-sdk-parachain-template.git parachain-template + ``` -- Source (raw): https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/reference-parachains-blocks-transactions-fees-transactions.md -- Canonical (HTML): https://docs.polkadot.com/reference/parachains/blocks-transactions-fees/transactions/ -- Summary: Learn how to construct, submit, and validate transactions in the Polkadot SDK, covering signed, unsigned, and inherent types of transactions. +2. Navigate into the project directory: -# Transactions + ```bash + cd parachain-template + ``` -## Introduction +## Explore the Project Structure -Transactions are essential components of blockchain networks, enabling state changes and the execution of key operations. In the Polkadot SDK, transactions, often called extrinsics, come in multiple forms, including signed, unsigned, and inherent transactions. +Before building the template, take a moment to familiarize yourself with its structure. Understanding this organization will help you navigate the codebase as you develop your parachain. -This guide walks you through the different transaction types and how they're formatted, validated, and processed within the Polkadot ecosystem. You'll also learn how to customize transaction formats and construct transactions for FRAME-based runtimes, ensuring a complete understanding of how transactions are built and executed in Polkadot SDK-based chains. +The template follows a standard Polkadot SDK project layout: -## What Is a Transaction? +```text +parachain-template/ +├── node/ # Node implementation and client +├── pallets/ # Custom pallets for your parachain +├── runtime/ # Runtime configuration and logic +├── Cargo.toml # Workspace configuration +└── README.md # Documentation +``` -In the Polkadot SDK, transactions represent operations that modify the chain's state, bundled into blocks for execution. The term extrinsic is often used to refer to any data that originates outside the runtime and is included in the chain. While other blockchain systems typically refer to these operations as "transactions," the Polkadot SDK adopts the broader term "extrinsic" to capture the wide variety of data types that can be added to a block. +Key directories explained: -There are three primary types of transactions (extrinsics) in the Polkadot SDK: +- **runtime/**: Contains your parachain's state transition function and pallet configuration. This is where you'll define what your blockchain can do. +- **node/**: Houses the client implementation that runs your blockchain, handles networking, and manages the database. +- **pallets/**: Where you'll create custom business logic modules (pallets) for your specific use case. +- **Cargo.toml**: The workspace configuration that ties all components together. -- **Signed transactions**: Signed by the submitting account, often carrying transaction fees. -- **Unsigned transactions**: Submitted without a signature, often requiring custom validation logic. -- **Inherent transactions**: Typically inserted directly into blocks by block authoring nodes, without gossiping between peers. +!!!note + The runtime is compiled to WebAssembly (Wasm), enabling forkless upgrades. The node binary remains constant while the runtime can be updated on-chain. -Each type serves a distinct purpose, and understanding when and how to use each is key to efficiently working with the Polkadot SDK. +## Compile the Runtime -### Signed Transactions +Now that you understand the template structure, let's compile the runtime to ensure everything is working correctly. -Signed transactions require an account's signature and typically involve submitting a request to execute a runtime call. The signature serves as a form of cryptographic proof that the sender has authorized the action, using their private key. These transactions often involve a transaction fee to cover the cost of execution and incentivize block producers. +1. Compile the runtime: -Signed transactions are the most common type of transaction and are integral to user-driven actions, such as token transfers. For instance, when you transfer tokens from one account to another, the sending account must sign the transaction to authorize the operation. + ```bash + cargo build --release --locked + ``` -For example, the [`pallet_balances::Call::transfer_allow_death`](https://paritytech.github.io/polkadot-sdk/master/pallet_balances/pallet/struct.Pallet.html#method.transfer_allow_death){target=\_blank} extrinsic in the Balances pallet allows you to transfer tokens. Since your account initiates this transaction, your account key is used to sign it. You'll also be responsible for paying the associated transaction fee, with the option to include an additional tip to incentivize faster inclusion in the block. + !!!tip + Initial compilation may take several minutes, depending on your machine specifications. Use the `--release` flag for improved runtime performance compared to the default `--debug` build. If you need to troubleshoot issues, the `--debug` build provides better diagnostics. + + For production deployments, consider using a dedicated `--profile production` flag - this can provide an additional 15-30% performance improvement over the standard `--release` profile. -### Unsigned Transactions +2. Upon successful compilation, you should see output indicating the build was successful. The compiled runtime will be located at: + + `./target/release/wbuild/parachain-template-runtime/parachain_template_runtime.compact.compressed.wasm` -Unsigned transactions do not require a signature or account-specific data from the sender. Unlike signed transactions, they do not come with any form of economic deterrent, such as fees, which makes them susceptible to spam or replay attacks. Custom validation logic must be implemented to mitigate these risks and ensure these transactions are secure. +## Verify the Build -Unsigned transactions typically involve scenarios where including a fee or signature is unnecessary or counterproductive. However, due to the absence of fees, they require careful validation to protect the network. For example, [`pallet_im_online::Call::heartbeat`](https://paritytech.github.io/polkadot-sdk/master/pallet_im_online/pallet/struct.Pallet.html#method.heartbeat){target=\_blank} extrinsic allows validators to send a heartbeat signal, indicating they are active. Since only validators can make this call, the logic embedded in the transaction ensures that the sender is a validator, making the need for a signature or fee redundant. +After compilation completes, verify that the runtime was created successfully by checking for the Wasm blob: -Unsigned transactions are more resource-intensive than signed ones because custom validation is required, but they play a crucial role in certain operational scenarios, especially when regular user accounts aren't involved. +```bash +ls -la ./target/release/wbuild/parachain-template-runtime/ +``` -### Inherent Transactions +You should see the `parachain_template_runtime.compact.compressed.wasm` file in the output, confirming the build was successful. -Inherent transactions are a specialized type of unsigned transaction that is used primarily for block authoring. Unlike signed or other unsigned transactions, inherent transactions are added directly by block producers and are not broadcasted to the network or stored in the transaction queue. They don't require signatures or the usual validation steps and are generally used to insert system-critical data directly into blocks. +## Run the Node Locally -A key example of an inherent transaction is inserting a timestamp into each block. The [`pallet_timestamp::Call::now`](https://paritytech.github.io/polkadot-sdk/master/pallet_timestamp/pallet/struct.Pallet.html#method.now-1){target=\_blank} extrinsic allows block authors to include the current time in the block they are producing. Since the block producer adds this information, there is no need for transaction validation, like signature verification. The validation in this case is done indirectly by the validators, who check whether the timestamp is within an acceptable range before finalizing the block. +After successfully compiling your runtime, you can spin up a local chain and produce blocks. This process will start your local parachain using the Polkadot Omni Node and allow you to interact with it. You'll first need to generate a chain specification that defines your network's identity, initial connections, and genesis state, providing the foundational configuration for how your nodes connect and what initial state they agree upon. -Another example is the [`paras_inherent::Call::enter`](https://paritytech.github.io/polkadot-sdk/master/polkadot_runtime_parachains/paras_inherent/pallet/struct.Pallet.html#method.enter){target=\_blank} extrinsic, which enables parachain collator nodes to send validation data to the relay chain. This inherent transaction ensures that the necessary parachain data is included in each block without the overhead of gossiped transactions. +Follow these steps to launch your node in development mode: -Inherent transactions serve a critical role in block authoring by allowing important operational data to be added directly to the chain without needing the validation processes required for standard transactions. +1. Generate the chain specification file of your parachain: -## Transaction Formats + ```bash + chain-spec-builder create -t development \ + --relay-chain paseo \ + --para-id 1000 \ + --runtime ./target/release/wbuild/parachain-template-runtime/parachain_template_runtime.compact.compressed.wasm \ + named-preset development + ``` -Understanding the structure of signed and unsigned transactions is crucial for developers building on Polkadot SDK-based chains. Whether you're optimizing transaction processing, customizing formats, or interacting with the transaction pool, knowing the format of extrinsics, Polkadot's term for transactions, is essential. +2. Start the Omni Node with the generated chain spec. You'll start it in development mode (without a relay chain config), producing and finalizing blocks: -### Types of Transaction Formats + ```bash + polkadot-omni-node --chain ./chain_spec.json --dev + ``` -In Polkadot SDK-based chains, extrinsics can fall into three main categories: + The `--dev` option does the following: -- **Unchecked extrinsics**: Typically used for signed transactions that require validation. They contain a signature and additional data, such as a nonce and information for fee calculation. Unchecked extrinsics are named as such because they require validation checks before being accepted into the transaction pool. -- **Checked extrinsics**: Typically used for inherent extrinsics (unsigned transactions); these don't require signature verification. Instead, they carry information such as where the extrinsic originates and any additional data required for the block authoring process. -- **Opaque extrinsics**: Used when the format of an extrinsic is not yet fully committed or finalized. They are still decodable, but their structure can be flexible depending on the context. + - Deletes all active data (keys, blockchain database, networking information) when stopped. + - Ensures a clean working state each time you restart the node. -### Signed Transaction Data Structure +3. Verify that your node is running by reviewing the terminal output. You should see log messages indicating block production and finalization. -A signed transaction typically includes the following components: +4. Confirm that your blockchain is producing new blocks by checking if the number after `finalized` is increasing in the output. -- **Signature**: Verifies the authenticity of the transaction sender. -- **Call**: The actual function or method call the transaction is requesting (for example, transferring funds). -- **Nonce**: Tracks the number of prior transactions sent from the account, helping to prevent replay attacks. -- **Tip**: An optional incentive to prioritize the transaction in block inclusion. -- **Additional data**: Includes details such as spec version, block hash, and genesis hash to ensure the transaction is valid within the correct runtime and chain context. +The details of the log output will be explored in a later tutorial. For now, knowing that your node is running and producing blocks is sufficient. -Here's a simplified breakdown of how signed transactions are typically constructed in a Polkadot SDK runtime: +## Interact with the Node -``` code - + + -``` +When running the template node, it's accessible by default at `ws://localhost:9944`. To interact with your node using the [Polkadot.js Apps](https://polkadot.js.org/apps/#/explorer){target=\_blank} interface, follow these steps: -Each part of the signed transaction has a purpose, ensuring the transaction's authenticity and context within the blockchain. +1. Open [Polkadot.js Apps](https://polkadot.js.org/apps/#/explorer){target=\_blank} in your web browser and click the network icon (which should be the Polkadot logo) in the top left corner: + + ![](/images/parachains/launch-a-parachain/set-up-the-parachain-template/parachain-template-01.webp) -### Signed Extensions +2. Connect to your local node: -Polkadot SDK also provides the concept of [signed extensions](https://paritytech.github.io/polkadot-sdk/master/polkadot_sdk_docs/reference_docs/signed_extensions/index.html){target=\_blank}, which allow developers to extend extrinsics with additional data or validation logic before they are included in a block. The [`SignedExtension`](https://paritytech.github.io/try-runtime-cli/sp_runtime/traits/trait.SignedExtension.html){target=\_blank} set helps enforce custom rules or protections, such as ensuring the transaction's validity or calculating priority. + 1. Scroll to the bottom and select **Development**. + 2. Choose **Custom**. + 3. Enter `ws://localhost:9944` in the **custom endpoint** input field. + 4. Click the **Switch** button. + + ![](/images/parachains/launch-a-parachain/set-up-the-parachain-template/parachain-template-02.webp) -The transaction queue regularly calls signed extensions to verify a transaction's validity before placing it in the ready queue. This safeguard ensures transactions won't fail in a block. Signed extensions are commonly used to enforce validation logic and protect the transaction pool from spam and replay attacks. +3. Once connected, you should see **parachain-template-runtime** in the top left corner, with the interface displaying information about your local blockchain. + + ![](/images/parachains/launch-a-parachain/set-up-the-parachain-template/parachain-template-03.webp) -In FRAME, a signed extension can hold any of the following types by default: +You are now connected to your local node and can interact with it through the Polkadot.js Apps interface. This tool enables you to explore blocks, execute transactions, and interact with your blockchain's features. For in-depth guidance on using the interface effectively, refer to the [Polkadot.js Guides](https://wiki.polkadot.com/general/polkadotjs/){target=\_blank} available on the Polkadot Wiki. -- **[`AccountId`](https://paritytech.github.io/polkadot-sdk/master/polkadot_sdk_frame/runtime/types_common/type.AccountId.html){target=\_blank}**: To encode the sender's identity. -- **[`Call`](https://paritytech.github.io/polkadot-sdk/master/polkadot_sdk_frame/traits/trait.SignedExtension.html#associatedtype.Call){target=\_blank}**: To encode the pallet call to be dispatched. This data is used to calculate transaction fees. -- **[`AdditionalSigned`](https://paritytech.github.io/polkadot-sdk/master/polkadot_sdk_frame/traits/trait.SignedExtension.html#associatedtype.AdditionalSigned){target=\_blank}**: To handle any additional data to go into the signed payload allowing you to attach any custom logic prior to dispatching a transaction. -- **[`Pre`](https://paritytech.github.io/polkadot-sdk/master/polkadot_sdk_frame/traits/trait.SignedExtension.html#associatedtype.Pre){target=\_blank}**: To encode the information that can be passed from before a call is dispatched to after it gets dispatched. +## Stop the Node -Signed extensions can enforce checks like: +When you're done exploring your local node, you can stop it to remove any state changes you've made. Since you started the node with the `--dev` option, stopping the node will purge all persistent block data, allowing you to start fresh the next time. -- **[`CheckSpecVersion`](https://paritytech.github.io/polkadot-sdk/master/src/frame_system/extensions/check_spec_version.rs.html){target=\_blank}**: Ensures the transaction is compatible with the runtime's current version. -- **[`CheckWeight`](https://paritytech.github.io/polkadot-sdk/master/frame_system/struct.CheckWeight.html){target=\_blank}**: Calculates the weight (or computational cost) of the transaction, ensuring the block doesn't exceed the maximum allowed weight. +To stop the local node: -These extensions are critical in the transaction lifecycle, ensuring that only valid and prioritized transactions are processed. +1. Return to the terminal window where the node output is displayed. +2. Press `Control-C` to stop the running process. +3. Verify that your terminal returns to the prompt in the `parachain-template` directory. -## Transaction Construction +## Where to Go Next -Building transactions in the Polkadot SDK involves constructing a payload that can be verified, signed, and submitted for inclusion in a block. Each runtime in the Polkadot SDK has its own rules for validating and executing transactions, but there are common patterns for constructing a signed transaction. +
-### Construct a Signed Transaction +- Tutorial __Deploy to Polkadot__ -A signed transaction in the Polkadot SDK includes various pieces of data to ensure security, prevent replay attacks, and prioritize processing. Here's an overview of how to construct one: + --- -1. **Construct the unsigned payload**: Gather the necessary information for the call, including: + Learn how to deploy your parachain template to a relay chain testnet. Configure your chain specification, register as a parachain, and start producing blocks. - - **Pallet index**: Identifies the pallet where the runtime function resides. - - **Function index**: Specifies the particular function to call in the pallet. - - **Parameters**: Any additional arguments required by the function call. + [:octicons-arrow-right-24: Get Started](/parachains/launch-a-parachain/deploy-to-polkadot/) -2. **Create a signing payload**: Once the unsigned payload is ready, additional data must be included: +
- - **Transaction nonce**: Unique identifier to prevent replay attacks. - - **Era information**: Defines how long the transaction is valid before it's dropped from the pool. - - **Block hash**: Ensures the transaction doesn't execute on the wrong chain or fork. -3. **Sign the payload**: Using the sender's private key, sign the payload to ensure that the transaction can only be executed by the account holder. -4. **Serialize the signed payload**: Once signed, the transaction must be serialized into a binary format, ensuring the data is compact and easy to transmit over the network. -5. **Submit the serialized transaction**: Finally, submit the serialized transaction to the network, where it will enter the transaction pool and wait for processing by an authoring node. +--- -The following is an example of how a signed transaction might look: +Page Title: Smart Contracts Cookbook -``` rust -node_runtime::UncheckedExtrinsic::new_signed( - function.clone(), // some call - sp_runtime::AccountId32::from(sender.public()).into(), // some sending account - node_runtime::Signature::Sr25519(signature.clone()), // the account's signature - extra.clone(), // the signed extensions -) -``` +- Source (raw): https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/smart-contracts-cookbook.md +- Canonical (HTML): https://docs.polkadot.com/smart-contracts/cookbook/ +- Summary: Explore our full collection of tutorials and guides to learn step-by-step how to build, deploy, and work with smart contracts on Polkadot. -### Transaction Encoding +# Smart Contracts Cookbook -Before a transaction is sent to the network, it is serialized and encoded using a structured encoding process that ensures consistency and prevents tampering: +Welcome to the Polkadot smart contracts cookbook index. -- **`[1]`**: Compact encoded length in bytes of the entire transaction. -- **`[2]`**: A u8 containing 1 byte to indicate whether the transaction is signed or unsigned (1 bit) and the encoded transaction version ID (7 bits). -- **`[3]`**: If signed, this field contains an account ID, an SR25519 signature, and some extra data. -- **`[4]`**: Encoded call data, including pallet and function indices and any required arguments. +This page contains a list of all relevant tutorials and guides to help you get started coding smart contracts and dApps in Polkadot. -This encoded format ensures consistency and efficiency in processing transactions across the network. By adhering to this format, applications can construct valid transactions and pass them to the network for execution. -To learn more about how compact encoding works using SCALE, see the [SCALE Codec](https://github.com/paritytech/parity-scale-codec){target=\_blank} README on GitHub. -### Customize Transaction Construction -Although the basic steps for constructing transactions are consistent across Polkadot SDK-based chains, developers can customize transaction formats and validation rules. For example: +## Get Tokens from the Faucet -- **Custom pallets**: You can define new pallets with custom function calls, each with its own parameters and validation logic. -- **Signed extensions**: Developers can implement custom extensions that modify how transactions are prioritized, validated, or included in blocks. +| Title | Difficulty | Tools | Description | +|------------------------------------|:-----------:|-------|-----------------------------------------------------------------------------------------------------------------------| +| [Faucet](/smart-contracts/faucet/) | 🟢 Beginner | N/A | Learn how to obtain test tokens from Polkadot faucets for development and testing purposes across different networks. | -By leveraging Polkadot SDK's modular design, developers can create highly specialized transaction logic tailored to their chain's needs. +## EVM Smart Contracts -## Lifecycle of a Transaction +| Title | Difficulty | Tools | Description | +|---------------------------------------------------------------------------------------------------------|:-----------:|--------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------| +| [Deploy an ERC-20 to Polkadot Hub](/smart-contracts/cookbook/smart-contracts/deploy-erc20/erc20-remix/) | 🟢 Beginner | EVM Wallet, Polkadot Remix IDE | Deploy an ERC-20 token on Polkadot Hub using PolkaVM. This guide covers contract creation, compilation, deployment, and interaction via Polkadot Remix IDE. | +| [Deploy an NFT to Polkadot Hub](/smart-contracts/cookbook/smart-contracts/deploy-nft/nft-remix/) | 🟢 Beginner | EVM Wallet, Polkadot Remix IDE | Deploy an NFT on Polkadot Hub using PolkaVM and OpenZeppelin. Learn how to compile, deploy, and interact with your contract using Polkadot Remix IDE. | -In the Polkadot SDK, transactions are often referred to as extrinsics because the data in transactions originates outside of the runtime. These transactions contain data that initiates changes to the chain state. The most common type of extrinsic is a signed transaction, which is cryptographically verified and typically incurs a fee. This section focuses on how signed transactions are processed, validated, and ultimately included in a block. +## Port Ethereum DApps -### Define Transaction Properties +| Title | Difficulty | Tools | Description | +|-------------------------------------------------------------------------------------|:---------------:|---------|----------------------------------------------------------------------------------------------------------------------------------| +| [Deploying Uniswap V2 on Polkadot](/smart-contracts/cookbook/eth-dapps/uniswap-v2/) | 🟡 Intermediate | Hardhat | Learn how to deploy and test Uniswap V2 on Polkadot Hub using Hardhat, bringing AMM-based token swaps to the Polkadot ecosystem. | -The Polkadot SDK runtime defines key transaction properties, such as: -- **Transaction validity**: Ensures the transaction meets all runtime requirements. -- **Signed or unsigned**: Identifies whether a transaction needs to be signed by an account. -- **State changes**: Determines how the transaction modifies the state of the chain. +--- -Pallets, which compose the runtime's logic, define the specific transactions that your chain supports. When a user submits a transaction, such as a token transfer, it becomes a signed transaction, verified by the user's account signature. If the account has enough funds to cover fees, the transaction is executed, and the chain's state is updated accordingly. +Page Title: Smart Contracts Overview -### Process on a Block Authoring Node +- Source (raw): https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/smart-contracts-overview.md +- Canonical (HTML): https://docs.polkadot.com/smart-contracts/overview/ +- Summary: Learn about smart contract development on Polkadot Hub with native PolkaVM support, dual-VM execution, and seamless cross-chain capabilities. -In Polkadot SDK-based networks, some nodes are authorized to author blocks. These nodes validate and process transactions. When a transaction is sent to a node that can produce blocks, it undergoes a lifecycle that involves several stages, including validation and execution. Non-authoring nodes gossip the transaction across the network until an authoring node receives it. The following diagram illustrates the lifecycle of a transaction that's submitted to a network and processed by an authoring node. +# Smart Contracts on Polkadot Hub -![Transaction lifecycle diagram](/images/reference/parachains/blocks-transactions-fees/transactions/transactions-01.webp){ style="background:white" } +## Introduction -### Validate and Queue +Polkadot Hub provides a production-ready smart contract platform that combines Ethereum compatibility with the performance and cross-chain capabilities of the Polkadot ecosystem. Developers can deploy smart contracts directly on Polkadot Hub while using familiar Ethereum tooling, workflows, and programming languages. -Once a transaction reaches an authoring node, it undergoes an initial validation process to ensure it meets specific conditions defined in the runtime. This validation includes checks for: +Built with a dual-VM approach, Polkadot Hub offers two execution backends: REVM for unmodified EVM compatibility and native PolkaVM for optimized computationally expensive workloads. This dual-VM architecture enables developers to migrate existing Ethereum contracts instantly or optimize for speed and efficiency with native execution. -- **Correct nonce**: Ensures the transaction is sequentially valid for the account. -- **Sufficient funds**: Confirms the account can cover any associated transaction fees. -- **Signature validity**: Verifies that the sender's signature matches the transaction data. +## Why Build on Polkadot Hub -After these checks, valid transactions are placed in the transaction pool, where they are queued for inclusion in a block. The transaction pool regularly re-validates queued transactions to ensure they remain valid before being processed. To reach consensus, two-thirds of the nodes must agree on the order of the transactions executed and the resulting state change. Transactions are validated and queued on the local node in a transaction pool to prepare for consensus. +### Ethereum Compatibility -#### Transaction Pool +Deploy existing Ethereum contracts with zero modifications while maintaining full compatibility with your existing development stack: -The transaction pool is responsible for managing valid transactions. It ensures that only transactions that pass initial validity checks are queued. Transactions that fail validation, expire, or become invalid for other reasons are removed from the pool. +- **Complete JSON-RPC API support**: Use MetaMask, Hardhat, Remix, Foundry, and all standard Ethereum tooling. +- **Standard libraries**: Integrate Ethers.js, Web3.js, Viem, Wagmi, and Web3.py without changes. +- **Solidity development**: Write contracts in Solidity or migrate existing code directly. +- **Familiar workflows**: Maintain your existing deployment, testing, and monitoring processes. -The transaction pool organizes transactions into two queues: +### Performance Options -- **Ready queue**: Transactions that are valid and ready to be included in a block. -- **Future queue**: Transactions that are not yet valid but could be in the future, such as transactions with a nonce too high for the current state. +Choose between two execution backends: -Details on how the transaction pool validates transactions, including fee and signature handling, can be found in the [`validate_transaction`](https://paritytech.github.io/polkadot-sdk/master/sp_transaction_pool/runtime_api/trait.TaggedTransactionQueue.html#method.validate_transaction){target=\_blank} method. +- **REVM**: Run unmodified Ethereum contracts with full EVM/Ethereum compatibility. +- **PolkaVM**: Compile to optimized RISC-V bytecode for enhanced performance and lower fees while keeping Ethereum-compatibility. -#### Invalid Transactions +Both backends share the same RPC interface and tooling support, allowing seamless transitions. In addition, smart contracts can interact with Polkadot native services via [precompile contracts](/smart-contracts/precompiles/){target=\_blank}. -If a transaction is invalid, for example, due to an invalid signature or insufficient funds, it is rejected and won't be added to the block. Invalid transactions might be rejected for reasons such as: +### Cross-VM & Cross-Chain Capabilities -- The transaction has already been included in a block. -- The transaction's signature does not match the sender. -- The transaction is too large to fit in the current block. +Smart contracts written for one VM (for example, EVM) can interact directly with other smart contracts written for the RISC-V PolkaVM, and back. This allows to use full EVM compatible contracts but extend to heavy/complex execution workloads to the PolkaVM RISC-V backend. -### Transaction Ordering and Priority +Furthermore, all smart contracts in Polkadot Hub can interact with any service in the Polkadot ecosystem through [XCM](/smart-contracts/precompiles/xcm/){target=\_blank}, enabling token transfers, remote execution, and cross-chain composability without bridges or intermediaries. -When a node is selected as the next block author, it prioritizes transactions based on weight, length, and tip amount. The goal is to fill the block with high-priority transactions without exceeding its maximum size or computational limits. Transactions are ordered as follows: +## Other Smart Contract Environments -- **Inherents first**: Inherent transactions, such as block timestamp updates, are always placed first. -- **Nonce-based ordering**: Transactions from the same account are ordered by their nonce. -- **Fee-based ordering**: Among transactions with the same nonce or priority level, those with higher fees are prioritized. +Beyond Polkadot Hub's native PolkaVM support, the ecosystem offers two main alternatives for smart contract development: -### Transaction Execution +- **EVM-compatible parachains**: Provide access to Ethereum's extensive developer ecosystem, smart contract portability, and established tooling like Hardhat, Remix, Foundry, and OpenZeppelin. The main options include Moonbeam (the first full Ethereum-compatible parachain serving as an interoperability hub), Astar (featuring dual VM support for both EVM and WebAssembly contracts), and Acala (DeFi-focused with enhanced Acala EVM+ offering advanced DeFi primitives). -Once a block author selects transactions from the pool, the transactions are executed in priority order. As each transaction is processed, the state changes are written directly to the chain's storage. It's important to note that these changes are not cached, meaning a failed transaction won't revert earlier state changes, which could leave the block in an inconsistent state. +- **Rust (ink!)**: ink! is a Rust-based framework that can compile to PolkaVM. It uses [`#[ink(...)]`](https://use.ink/docs/v6/macros-attributes/){target=\_blank} attribute macros to create Polkadot SDK-compatible PolkaVM bytecode, offering strong memory safety from Rust, an advanced type system, high-performance PolkaVM execution, and platform independence with sandboxed security. -Events are also written to storage. Runtime logic should not emit an event before performing the associated actions. If the associated transaction fails after the event was emitted, the event will not revert. +## Next Steps -## Transaction Mortality +
-Transactions in the network can be configured as either mortal (with expiration) or immortal (without expiration). Every transaction payload contains a block checkpoint (reference block number and hash) and an era/validity period that determines how many blocks after the checkpoint the transaction remains valid. +- Guide __Get Started__ -When a transaction is submitted, the network validates it against these parameters. If the transaction is not included in a block within the specified validity window, it is automatically removed from the transaction queue. + --- -- **Mortal transactions**: Have a finite lifespan and will expire after a specified number of blocks. For example, a transaction with a block checkpoint of 1000 and a validity period of 64 blocks will be valid from blocks 1000 to 1064. + Quick-start guides for connecting, deploying, and building your first smart contract. -- **Immortal transactions**: Never expire and remain valid indefinitely. To create an immortal transaction, set the block checkpoint to 0 (genesis block), use the genesis hash as a reference, and set the validity period to 0. + [:octicons-arrow-right-24: Get Started](/smart-contracts/get-started/) -However, immortal transactions pose significant security risks through replay attacks. If an account is reaped (balance drops to zero, account removed) and later re-funded, malicious actors can replay old immortal transactions. +- Guide __Cookbook__ -The blockchain maintains only a limited number of prior block hashes for reference validation, called `BlockHashCount`. If your validity period exceeds `BlockHashCount`, the effective validity period becomes the minimum of your specified period and the block hash count. + --- -## Unique Identifiers for Extrinsics + Step-by-step tutorials for deploying contracts, tokens, NFTs, and full dApps. -Transaction hashes are **not unique identifiers** in Polkadot SDK-based chains. + [:octicons-arrow-right-24: View Tutorials](/smart-contracts/cookbook/) -Key differences from traditional blockchains: +- Guide __Ethereum Developers__ -- Transaction hashes serve only as fingerprints of transaction information. -- Multiple valid transactions can share the same hash. -- Hash uniqueness assumptions lead to serious issues. + --- -For example, when an account is reaped (removed due to insufficient balance) and later recreated, it resets to nonce 0, allowing identical transactions to be valid at different points: + Understand key differences in accounts, fees, gas model, and deployment on Polkadot Hub. -| Block | Extrinsic Index | Hash | Origin | Nonce | Call | Result | -|-------|----------------|------|-----------|-------|---------------------|-------------------------------| -| 100 | 0 | 0x01 | Account A | 0 | Transfer 5 DOT to B | Account A reaped | -| 150 | 5 | 0x02 | Account B | 4 | Transfer 7 DOT to A | Account A created (nonce = 0) | -| 200 | 2 | 0x01 | Account A | 0 | Transfer 5 DOT to B | Successful transaction | + [:octicons-arrow-right-24: Learn More](/smart-contracts/for-eth-devs/accounts/) -Notice that blocks 100 and 200 contain transactions with identical hashes (0x01) but are completely different, valid operations occurring at different times. +- Guide __Precompiles__ -Additional complexity comes from Polkadot SDK's origin abstraction. Origins can represent collectives, governance bodies, or other non-account entities that don't maintain nonces like regular accounts and might dispatch identical calls multiple times with the same hash values. Each execution occurs in different chain states with different results. + --- -The correct way to uniquely identify an extrinsic on a Polkadot SDK-based chain is to use the block ID (height or hash) and the extrinsic index. Since the Polkadot SDK defines blocks as headers plus ordered arrays of extrinsics, the index position within a canonical block provides guaranteed uniqueness. + Discover advanced functionalities including XCM for cross-chain interactions. -## Additional Resources + [:octicons-arrow-right-24: Explore Precompiles](/smart-contracts/precompiles/) -For a video overview of the lifecycle of transactions and the types of transactions that exist, see the [Transaction lifecycle](https://www.youtube.com/watch?v=3pfM0GOp02c){target=\_blank} seminar from Parity Tech. +
--- @@ -10876,10 +7016,10 @@ cd wagmi-polkadot-hub ## Install Dependencies -Install Wagmi and its peer dependencies: +Install Wagmi v3 and its peer dependencies: ```bash -npm install wagmi viem @tanstack/react-query +npm install wagmi@3 viem @tanstack/react-query ``` ## Configure Wagmi for Polkadot Hub @@ -10992,12 +7132,12 @@ Create a component to connect wallets to your dApp. Create a file named `app/com "use client"; import React from "react"; -import { useConnect, useAccount, useDisconnect } from "wagmi"; +import { useConnect, useConnection, useDisconnect } from "wagmi"; import { injected } from "wagmi/connectors"; export function ConnectWallet() { const { connect } = useConnect(); - const { address, isConnected } = useAccount(); + const { address, isConnected } = useConnection(); const { disconnect } = useDisconnect(); if (isConnected) { @@ -11022,7 +7162,7 @@ This component uses the following React hooks: - **[`useConnect`](https://wagmi.sh/react/api/hooks/useConnect#useconnect){target=\_blank}**: Provides functions and state for connecting the user's wallet to your dApp. The `connect` function initiates the connection flow with the specified connector. - **[`useDisconnect`](https://wagmi.sh/react/api/hooks/useDisconnect#usedisconnect){target=\_blank}**: Provides a function to disconnect the currently connected wallet. -- **[`useAccount`](https://2.x.wagmi.sh/react/api/hooks/useAccount#useaccount){target=\_blank}**: Returns data about the connected account, including the address and connection status. +- **[`useConnection`](https://wagmi.sh/react/api/hooks/useConnection#useconnection){target=\_blank}**: Returns data about the connected account, including the address and connection status. In Wagmi v3, `useAccount` has been renamed to `useConnection`. ## Fetch Blockchain Data @@ -11031,10 +7171,10 @@ Wagmi provides various hooks to fetch blockchain data. Here's an example compone ```typescript title="app/components/BlockchainInfo.tsx" "use client"; -import { useBlockNumber, useBalance, useAccount } from "wagmi"; +import { useBlockNumber, useBalance, useConnection } from "wagmi"; export function BlockchainInfo() { - const { address } = useAccount(); + const { address } = useConnection(); // Get the latest block number const { data: blockNumber } = useBlockNumber({ watch: true }); @@ -11225,10 +7365,10 @@ Update your main page to combine all the components. Create or update the file ` import { BlockchainInfo } from "./components/BlockchainInfo"; import { ConnectWallet } from "./components/ConnectWallet"; import { StorageContract } from "./components/StorageContract"; -import { useAccount } from "wagmi"; +import { useConnection } from "wagmi"; export default function Home() { - const { isConnected } = useAccount(); + const { isConnected } = useConnection(); return (
@@ -11924,94 +8064,6 @@ python update_storage.py ---- - -Page Title: XCM Tools - -- Source (raw): https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/reference-tools-xcm-tools.md -- Canonical (HTML): https://docs.polkadot.com/reference/tools/xcm-tools/ -- Summary: Explore essential XCM tools across Polkadot, crafted to enhance cross-chain functionality and integration within the ecosystem. - -# XCM Tools - -## Introduction - -As described in the [Interoperability](/develop/interoperability){target=\_blank} section, XCM (Cross-Consensus Messaging) is a protocol used in the Polkadot and Kusama ecosystems to enable communication and interaction between chains. It facilitates cross-chain communication, allowing assets, data, and messages to flow seamlessly across the ecosystem. - -As XCM is central to enabling communication between blockchains, developers need robust tools to help interact with, build, and test XCM messages. Several XCM tools simplify working with the protocol by providing libraries, frameworks, and utilities that enhance the development process, ensuring that applications built within the Polkadot ecosystem can efficiently use cross-chain functionalities. - -## Popular XCM Tools - -### Moonsong Labs XCM Tools - -[Moonsong Labs XCM Tools](https://github.com/Moonsong-Labs/xcm-tools){target=\_blank} provides a collection of scripts for managing and testing XCM operations between Polkadot SDK-based runtimes. These tools allow performing tasks like asset registration, channel setup, and XCM initialization. Key features include: - -- **Asset registration**: Registers assets, setting units per second (up-front fees), and configuring error (revert) codes. -- **XCM initializer**: Initializes XCM, sets default XCM versions, and configures revert codes for XCM-related precompiles. -- **HRMP manipulator**: Manages HRMP channel actions, including opening, accepting, or closing channels. -- **XCM-Transactor-Info-Setter**: Configures transactor information, including extra weight and fee settings. -- **Decode XCM**: Decodes XCM messages on the relay chain or parachains to help interpret cross-chain communication. - -To get started, clone the repository and install the required dependencies: - -```bash -git clone https://github.com/Moonsong-Labs/xcm-tools && -cd xcm-tools && -yarn install -``` - -For a full overview of each script, visit the [scripts](https://github.com/Moonsong-Labs/xcm-tools/tree/main/scripts){target=\_blank} directory or refer to the [official documentation](https://github.com/Moonsong-Labs/xcm-tools/blob/main/README.md){target=\_blank} on GitHub. - -### ParaSpell - -[ParaSpell](/reference/tools/paraspell/){target=\_blank} is a collection of open-source XCM tools that streamline cross-chain asset transfers and interactions across the Polkadot and Kusama ecosystems. It provides developers with an intuitive interface to build, test, and deploy interoperable dApps, featuring message composition, decoding, and practical utilities for parachain interactions that simplify debugging and cross-chain communication optimization. - -### Astar XCM Tools - -The [Astar parachain](https://github.com/AstarNetwork/Astar/tree/master){target=\_blank} offers a crate with a set of utilities for interacting with the XCM protocol. The [xcm-tools](https://github.com/AstarNetwork/Astar/tree/master/bin/xcm-tools){target=\_blank} crate provides a straightforward method for users to locate a sovereign account or calculate an XC20 asset ID. Some commands included by the xcm-tools crate allow users to perform the following tasks: - -- **Sovereign accounts**: Obtain the sovereign account address for any parachain, either on the Relay Chain or for sibling parachains, using a simple command. -- **XC20 EVM addresses**: Generate XC20-compatible Ethereum addresses for assets by entering the asset ID, making it easy to integrate assets across Ethereum-compatible environments. -- **Remote accounts**: Retrieve remote account addresses needed for multi-location compatibility, using flexible options to specify account types and parachain IDs. - -To start using these tools, clone the [Astar repository](https://github.com/AstarNetwork/Astar){target=\_blank} and compile the xcm-tools package: - -```bash -git clone https://github.com/AstarNetwork/Astar && -cd Astar && -cargo build --release -p xcm-tools -``` - -After compiling, verify the setup with the following command: - -```bash -./target/release/xcm-tools --help -``` -For more details on using Astar xcm-tools, consult the [official documentation](https://docs.astar.network/docs/learn/interoperability/xcm/integration/tools/){target=\_blank}. - -### Chopsticks - -The Chopsticks library provides XCM functionality for testing XCM messages across networks, enabling you to fork multiple parachains along with a relay chain. For further details, see the [Chopsticks documentation](/tutorials/polkadot-sdk/testing/fork-live-chains/){target=\_blank} about XCM. - -### Moonbeam XCM SDK - -The [Moonbeam XCM SDK](https://github.com/moonbeam-foundation/xcm-sdk){target=\_blank} enables developers to easily transfer assets between chains, either between parachains or between a parachain and the relay chain, within the Polkadot/Kusama ecosystem. With the SDK, you don't need to worry about determining the [Multilocation](https://github.com/polkadot-fellows/xcm-format?tab=readme-ov-file#7-universal-consensus-location-identifiers){target=\_blank} of the origin or destination assets or which extrinsics are used on which networks. - -The SDK consists of two main packages: - -- **[XCM SDK](https://github.com/moonbeam-foundation/xcm-sdk/tree/main/packages/sdk){target=\_blank}**: Core SDK for executing XCM transfers between chains in the Polkadot/Kusama ecosystem. -- **[MRL SDK](https://github.com/moonbeam-foundation/xcm-sdk/tree/main/packages/mrl){target=\_blank}**: Extension of the XCM SDK for transferring liquidity into and across the Polkadot ecosystem from other ecosystems like Ethereum. - -Key features include: - -- **Simplified asset transfers**: Abstracts away complex multilocation determinations and extrinsic selection. -- **Cross-ecosystem support**: Enables transfers between Polkadot/Kusama chains and external ecosystems. -- **Developer-friendly API**: Provides intuitive interfaces for cross-chain functionality. -- **Comprehensive documentation**: Includes usage guides and API references for both packages. - -For detailed usage examples and API documentation, visit the [official Moonbeam XCM SDK documentation](https://moonbeam-foundation.github.io/xcm-sdk/latest/){target=\_blank}. - - --- Page Title: Zero to Hero Smart Contract DApp diff --git a/.ai/pages/smart-contracts-libraries-wagmi.md b/.ai/pages/smart-contracts-libraries-wagmi.md index b900ebf63..24c537f49 100644 --- a/.ai/pages/smart-contracts-libraries-wagmi.md +++ b/.ai/pages/smart-contracts-libraries-wagmi.md @@ -24,10 +24,10 @@ cd wagmi-polkadot-hub ## Install Dependencies -Install Wagmi and its peer dependencies: +Install Wagmi v3 and its peer dependencies: ```bash -npm install wagmi viem @tanstack/react-query +npm install wagmi@3 viem @tanstack/react-query ``` ## Configure Wagmi for Polkadot Hub @@ -140,12 +140,12 @@ Create a component to connect wallets to your dApp. Create a file named `app/com "use client"; import React from "react"; -import { useConnect, useAccount, useDisconnect } from "wagmi"; +import { useConnect, useConnection, useDisconnect } from "wagmi"; import { injected } from "wagmi/connectors"; export function ConnectWallet() { const { connect } = useConnect(); - const { address, isConnected } = useAccount(); + const { address, isConnected } = useConnection(); const { disconnect } = useDisconnect(); if (isConnected) { @@ -170,7 +170,7 @@ This component uses the following React hooks: - **[`useConnect`](https://wagmi.sh/react/api/hooks/useConnect#useconnect){target=\_blank}**: Provides functions and state for connecting the user's wallet to your dApp. The `connect` function initiates the connection flow with the specified connector. - **[`useDisconnect`](https://wagmi.sh/react/api/hooks/useDisconnect#usedisconnect){target=\_blank}**: Provides a function to disconnect the currently connected wallet. -- **[`useAccount`](https://2.x.wagmi.sh/react/api/hooks/useAccount#useaccount){target=\_blank}**: Returns data about the connected account, including the address and connection status. +- **[`useConnection`](https://wagmi.sh/react/api/hooks/useConnection#useconnection){target=\_blank}**: Returns data about the connected account, including the address and connection status. In Wagmi v3, `useAccount` has been renamed to `useConnection`. ## Fetch Blockchain Data @@ -179,10 +179,10 @@ Wagmi provides various hooks to fetch blockchain data. Here's an example compone ```typescript title="app/components/BlockchainInfo.tsx" "use client"; -import { useBlockNumber, useBalance, useAccount } from "wagmi"; +import { useBlockNumber, useBalance, useConnection } from "wagmi"; export function BlockchainInfo() { - const { address } = useAccount(); + const { address } = useConnection(); // Get the latest block number const { data: blockNumber } = useBlockNumber({ watch: true }); @@ -373,10 +373,10 @@ Update your main page to combine all the components. Create or update the file ` import { BlockchainInfo } from "./components/BlockchainInfo"; import { ConnectWallet } from "./components/ConnectWallet"; import { StorageContract } from "./components/StorageContract"; -import { useAccount } from "wagmi"; +import { useConnection } from "wagmi"; export default function Home() { - const { isConnected } = useAccount(); + const { isConnected } = useConnection(); return (
diff --git a/.ai/site-index.json b/.ai/site-index.json index 579210f70..1387bffd8 100644 --- a/.ai/site-index.json +++ b/.ai/site-index.json @@ -2930,2869 +2930,6 @@ "hash": "sha256:2a765ad6d0a676b644ef3dd3565f2db58bfafbc9ef43c49e9eefe8bb0aeeee0a", "token_estimator": "heuristic-v1" }, - { - "id": "reference-glossary", - "title": "Glossary", - "slug": "reference-glossary", - "categories": [ - "Reference" - ], - "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/reference-glossary.md", - "html_url": "https://docs.polkadot.com/reference/glossary/", - "preview": "Key definitions, concepts, and terminology specific to the Polkadot ecosystem are included here.", - "outline": [ - { - "depth": 2, - "title": "Authority", - "anchor": "authority" - }, - { - "depth": 2, - "title": "Authority Round (Aura)", - "anchor": "authority-round-aura" - }, - { - "depth": 2, - "title": "Blind Assignment of Blockchain Extension (BABE)", - "anchor": "blind-assignment-of-blockchain-extension-babe" - }, - { - "depth": 2, - "title": "Block Author", - "anchor": "block-author" - }, - { - "depth": 2, - "title": "Byzantine Fault Tolerance (BFT)", - "anchor": "byzantine-fault-tolerance-bft" - }, - { - "depth": 3, - "title": "Byzantine Failure", - "anchor": "byzantine-failure" - }, - { - "depth": 3, - "title": "Practical Byzantine Fault Tolerance (pBFT)", - "anchor": "practical-byzantine-fault-tolerance-pbft" - }, - { - "depth": 3, - "title": "Preimage", - "anchor": "preimage" - }, - { - "depth": 2, - "title": "Call", - "anchor": "call" - }, - { - "depth": 2, - "title": "Chain Specification", - "anchor": "chain-specification" - }, - { - "depth": 2, - "title": "Collator", - "anchor": "collator" - }, - { - "depth": 2, - "title": "Collective", - "anchor": "collective" - }, - { - "depth": 2, - "title": "Consensus", - "anchor": "consensus" - }, - { - "depth": 2, - "title": "Consensus Algorithm", - "anchor": "consensus-algorithm" - }, - { - "depth": 2, - "title": "Consensus Engine", - "anchor": "consensus-engine" - }, - { - "depth": 2, - "title": "Coretime", - "anchor": "coretime" - }, - { - "depth": 2, - "title": "Development Phrase", - "anchor": "development-phrase" - }, - { - "depth": 2, - "title": "Digest", - "anchor": "digest" - }, - { - "depth": 2, - "title": "Dispatchable", - "anchor": "dispatchable" - }, - { - "depth": 2, - "title": "Events", - "anchor": "events" - }, - { - "depth": 2, - "title": "Executor", - "anchor": "executor" - }, - { - "depth": 2, - "title": "Existential Deposit", - "anchor": "existential-deposit" - }, - { - "depth": 2, - "title": "Extrinsic", - "anchor": "extrinsic" - }, - { - "depth": 2, - "title": "Fork Choice Rule/Strategy", - "anchor": "fork-choice-rulestrategy" - }, - { - "depth": 2, - "title": "FRAME (Framework for Runtime Aggregation of Modularized Entities)", - "anchor": "frame-framework-for-runtime-aggregation-of-modularized-entities" - }, - { - "depth": 2, - "title": "Full Node", - "anchor": "full-node" - }, - { - "depth": 2, - "title": "Genesis Configuration", - "anchor": "genesis-configuration" - }, - { - "depth": 2, - "title": "GRANDPA", - "anchor": "grandpa" - }, - { - "depth": 2, - "title": "Header", - "anchor": "header" - }, - { - "depth": 2, - "title": "Hybrid Consensus", - "anchor": "hybrid-consensus" - }, - { - "depth": 2, - "title": "Inherent Transactions", - "anchor": "inherent-transactions" - }, - { - "depth": 2, - "title": "JSON-RPC", - "anchor": "json-rpc" - }, - { - "depth": 2, - "title": "Keystore", - "anchor": "keystore" - }, - { - "depth": 2, - "title": "Kusama", - "anchor": "kusama" - }, - { - "depth": 2, - "title": "libp2p", - "anchor": "libp2p" - }, - { - "depth": 2, - "title": "Light Client", - "anchor": "light-client" - }, - { - "depth": 2, - "title": "Metadata", - "anchor": "metadata" - }, - { - "depth": 2, - "title": "Nominated Proof of Stake (NPoS)", - "anchor": "nominated-proof-of-stake-npos" - }, - { - "depth": 2, - "title": "Oracle", - "anchor": "oracle" - }, - { - "depth": 2, - "title": "Origin", - "anchor": "origin" - }, - { - "depth": 2, - "title": "Pallet", - "anchor": "pallet" - }, - { - "depth": 2, - "title": "Parachain", - "anchor": "parachain" - }, - { - "depth": 2, - "title": "Paseo", - "anchor": "paseo" - }, - { - "depth": 2, - "title": "Polkadot", - "anchor": "polkadot" - }, - { - "depth": 2, - "title": "Polkadot Cloud", - "anchor": "polkadot-cloud" - }, - { - "depth": 2, - "title": "Polkadot Hub", - "anchor": "polkadot-hub" - }, - { - "depth": 2, - "title": "PolkaVM", - "anchor": "polkavm" - }, - { - "depth": 2, - "title": "Relay Chain", - "anchor": "relay-chain" - }, - { - "depth": 2, - "title": "Rococo", - "anchor": "rococo" - }, - { - "depth": 2, - "title": "Runtime", - "anchor": "runtime" - }, - { - "depth": 2, - "title": "Slot", - "anchor": "slot" - }, - { - "depth": 2, - "title": "Sovereign Account", - "anchor": "sovereign-account" - }, - { - "depth": 2, - "title": "SS58 Address Format", - "anchor": "ss58-address-format" - }, - { - "depth": 2, - "title": "State Transition Function (STF)", - "anchor": "state-transition-function-stf" - }, - { - "depth": 2, - "title": "Storage Item", - "anchor": "storage-item" - }, - { - "depth": 2, - "title": "Substrate", - "anchor": "substrate" - }, - { - "depth": 2, - "title": "Transaction", - "anchor": "transaction" - }, - { - "depth": 2, - "title": "Transaction Era", - "anchor": "transaction-era" - }, - { - "depth": 2, - "title": "Trie (Patricia Merkle Tree)", - "anchor": "trie-patricia-merkle-tree" - }, - { - "depth": 2, - "title": "Validator", - "anchor": "validator" - }, - { - "depth": 2, - "title": "WebAssembly (Wasm)", - "anchor": "webassembly-wasm" - }, - { - "depth": 2, - "title": "Weight", - "anchor": "weight" - }, - { - "depth": 2, - "title": "Westend", - "anchor": "westend" - } - ], - "stats": { - "chars": 24739, - "words": 3626, - "headings": 63, - "estimated_token_count_total": 5273 - }, - "hash": "sha256:40bd67811e7eabc79ca5d105eae388b19380d9f035022da17fc0d6bb173c817c", - "token_estimator": "heuristic-v1" - }, - { - "id": "reference-governance-origins-tracks", - "title": "Origins and Tracks", - "slug": "reference-governance-origins-tracks", - "categories": [ - "Polkadot Protocol" - ], - "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/reference-governance-origins-tracks.md", - "html_url": "https://docs.polkadot.com/reference/governance/origins-tracks/", - "preview": "Polkadot's OpenGov system empowers decentralized decision-making and active community participation by tailoring the governance process to the impact of proposed changes. Through a system of origins and tracks, OpenGov ensures that every referendum receives the appropriate scrutiny, balancing security, inclusivity, and efficiency.", - "outline": [ - { - "depth": 2, - "title": "Introduction", - "anchor": "introduction" - }, - { - "depth": 2, - "title": "Origins", - "anchor": "origins" - }, - { - "depth": 2, - "title": "Tracks", - "anchor": "tracks" - }, - { - "depth": 2, - "title": "Additional Resources", - "anchor": "additional-resources" - } - ], - "stats": { - "chars": 3333, - "words": 469, - "headings": 4, - "estimated_token_count_total": 631 - }, - "hash": "sha256:baba9dd41091b792d09005d55d3df0bf65b35f42b40ebe63caf425a0978a22b0", - "token_estimator": "heuristic-v1" - }, - { - "id": "reference-governance", - "title": "On-Chain Governance Overview", - "slug": "reference-governance", - "categories": [ - "Basics", - "Polkadot Protocol" - ], - "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/reference-governance.md", - "html_url": "https://docs.polkadot.com/reference/governance/", - "preview": "Polkadot’s governance system exemplifies decentralized decision-making, empowering its community of stakeholders to shape the network’s future through active participation. The latest evolution, OpenGov, builds on Polkadot’s foundation by providing a more inclusive and efficient governance model.", - "outline": [ - { - "depth": 2, - "title": "Introduction", - "anchor": "introduction" - }, - { - "depth": 2, - "title": "Governance Evolution", - "anchor": "governance-evolution" - }, - { - "depth": 2, - "title": "OpenGov Key Features", - "anchor": "opengov-key-features" - }, - { - "depth": 2, - "title": "Origins and Tracks", - "anchor": "origins-and-tracks" - }, - { - "depth": 2, - "title": "Referendums", - "anchor": "referendums" - }, - { - "depth": 3, - "title": "Vote on Referendums", - "anchor": "vote-on-referendums" - }, - { - "depth": 3, - "title": "Delegate Voting Power", - "anchor": "delegate-voting-power" - }, - { - "depth": 3, - "title": "Cancel a Referendum", - "anchor": "cancel-a-referendum" - }, - { - "depth": 2, - "title": "Additional Resources", - "anchor": "additional-resources" - } - ], - "stats": { - "chars": 7493, - "words": 1019, - "headings": 9, - "estimated_token_count_total": 1611 - }, - "hash": "sha256:62beec261e72529f70e07a641177d489d2c8872f9c9d618cbadf1ac0fd881986", - "token_estimator": "heuristic-v1" - }, - { - "id": "reference-parachains-accounts", - "title": "Polkadot SDK Accounts", - "slug": "reference-parachains-accounts", - "categories": [ - "Basics", - "Polkadot Protocol" - ], - "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/reference-parachains-accounts.md", - "html_url": "https://docs.polkadot.com/reference/parachains/accounts/", - "preview": "Accounts are essential for managing identity, transactions, and governance on the network in the Polkadot SDK. Understanding these components is critical for seamless development and operation on the network, whether you're building or interacting with Polkadot-based chains.", - "outline": [ - { - "depth": 2, - "title": "Introduction", - "anchor": "introduction" - }, - { - "depth": 2, - "title": "Account Data Structure", - "anchor": "account-data-structure" - }, - { - "depth": 3, - "title": "Account", - "anchor": "account" - }, - { - "depth": 3, - "title": "Account Info", - "anchor": "account-info" - }, - { - "depth": 3, - "title": "Account Reference Counters", - "anchor": "account-reference-counters" - }, - { - "depth": 2, - "title": "Account Balance Types", - "anchor": "account-balance-types" - }, - { - "depth": 3, - "title": "Balance Types", - "anchor": "balance-types" - }, - { - "depth": 3, - "title": "Locks", - "anchor": "locks" - }, - { - "depth": 3, - "title": "Balance Types on Polkadot.js", - "anchor": "balance-types-on-polkadotjs" - }, - { - "depth": 2, - "title": "Address Formats", - "anchor": "address-formats" - }, - { - "depth": 3, - "title": "Basic Format", - "anchor": "basic-format" - }, - { - "depth": 3, - "title": "Address Type", - "anchor": "address-type" - }, - { - "depth": 3, - "title": "Address Length", - "anchor": "address-length" - }, - { - "depth": 3, - "title": "Checksum Types", - "anchor": "checksum-types" - }, - { - "depth": 3, - "title": "Validating Addresses", - "anchor": "validating-addresses" - } - ], - "stats": { - "chars": 29604, - "words": 4194, - "headings": 15, - "estimated_token_count_total": 6507 - }, - "hash": "sha256:0104a9132a69345a2faac37fca0e2853a2ded1efb009511a83a98d44509ab887", - "token_estimator": "heuristic-v1" - }, - { - "id": "reference-parachains-blocks-transactions-fees-blocks", - "title": "Blocks", - "slug": "reference-parachains-blocks-transactions-fees-blocks", - "categories": [ - "Basics", - "Polkadot Protocol" - ], - "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/reference-parachains-blocks-transactions-fees-blocks.md", - "html_url": "https://docs.polkadot.com/reference/parachains/blocks-transactions-fees/blocks/", - "preview": "In the Polkadot SDK, blocks are fundamental to the functioning of the blockchain, serving as containers for [transactions](/reference/parachains/blocks-transactions-fees/transactions/){target=\\_blank} and changes to the chain's state. Blocks consist of headers and an array of transactions, ensuring the integrity and validity of operations on the network. This guide explores the essential components of a block, the process of block production, and how blocks are validated and imported across the", - "outline": [ - { - "depth": 2, - "title": "Introduction", - "anchor": "introduction" - }, - { - "depth": 2, - "title": "What is a Block?", - "anchor": "what-is-a-block" - }, - { - "depth": 2, - "title": "Block Production", - "anchor": "block-production" - }, - { - "depth": 3, - "title": "Initialize Block", - "anchor": "initialize-block" - }, - { - "depth": 3, - "title": "Finalize Block", - "anchor": "finalize-block" - }, - { - "depth": 2, - "title": "Block Authoring and Import", - "anchor": "block-authoring-and-import" - }, - { - "depth": 3, - "title": "Block Import Queue", - "anchor": "block-import-queue" - }, - { - "depth": 2, - "title": "Additional Resources", - "anchor": "additional-resources" - } - ], - "stats": { - "chars": 6252, - "words": 910, - "headings": 8, - "estimated_token_count_total": 1395 - }, - "hash": "sha256:424783c102bea5dae5b8749635858c6c59055563442a98f57521f0027dafa8d3", - "token_estimator": "heuristic-v1" - }, - { - "id": "reference-parachains-blocks-transactions-fees-fees", - "title": "Transactions Weights and Fees", - "slug": "reference-parachains-blocks-transactions-fees-fees", - "categories": [ - "Basics", - "Polkadot Protocol" - ], - "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/reference-parachains-blocks-transactions-fees-fees.md", - "html_url": "https://docs.polkadot.com/reference/parachains/blocks-transactions-fees/fees/", - "preview": "When transactions are executed, or data is stored on-chain, the activity changes the chain's state and consumes blockchain resources. Because the resources available to a blockchain are limited, managing how operations on-chain consume them is important. In addition to being limited in practical terms, such as storage capacity, blockchain resources represent a potential attack vector for malicious users. For example, a malicious user might attempt to overload the network with messages to stop th", - "outline": [ - { - "depth": 2, - "title": "Introductions", - "anchor": "introductions" - }, - { - "depth": 2, - "title": "How Fees are Calculated", - "anchor": "how-fees-are-calculated" - }, - { - "depth": 2, - "title": "Using the Transaction Payment Pallet", - "anchor": "using-the-transaction-payment-pallet" - }, - { - "depth": 3, - "title": "Understanding the Inclusion Fee", - "anchor": "understanding-the-inclusion-fee" - }, - { - "depth": 3, - "title": "Accounts with an Insufficient Balance", - "anchor": "accounts-with-an-insufficient-balance" - }, - { - "depth": 3, - "title": "Fee Multipliers", - "anchor": "fee-multipliers" - }, - { - "depth": 2, - "title": "Transactions with Special Requirements", - "anchor": "transactions-with-special-requirements" - }, - { - "depth": 2, - "title": "Default Weight Annotations", - "anchor": "default-weight-annotations" - }, - { - "depth": 3, - "title": "Weights and Database Read/Write Operations", - "anchor": "weights-and-database-readwrite-operations" - }, - { - "depth": 3, - "title": "Dispatch Classes", - "anchor": "dispatch-classes" - }, - { - "depth": 3, - "title": "Dynamic Weights", - "anchor": "dynamic-weights" - }, - { - "depth": 2, - "title": "Post Dispatch Weight Correction", - "anchor": "post-dispatch-weight-correction" - }, - { - "depth": 2, - "title": "Custom Fees", - "anchor": "custom-fees" - }, - { - "depth": 3, - "title": "Custom Weights", - "anchor": "custom-weights" - }, - { - "depth": 2, - "title": "Additional Resources", - "anchor": "additional-resources" - } - ], - "stats": { - "chars": 20800, - "words": 2917, - "headings": 15, - "estimated_token_count_total": 4464 - }, - "hash": "sha256:7d0c3fa7982b3e1843adb8f27422456397580b3a3eba5047b381da8517742536", - "token_estimator": "heuristic-v1" - }, - { - "id": "reference-parachains-blocks-transactions-fees-transactions", - "title": "Transactions", - "slug": "reference-parachains-blocks-transactions-fees-transactions", - "categories": [ - "Basics", - "Polkadot Protocol" - ], - "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/reference-parachains-blocks-transactions-fees-transactions.md", - "html_url": "https://docs.polkadot.com/reference/parachains/blocks-transactions-fees/transactions/", - "preview": "Transactions are essential components of blockchain networks, enabling state changes and the execution of key operations. In the Polkadot SDK, transactions, often called extrinsics, come in multiple forms, including signed, unsigned, and inherent transactions.", - "outline": [ - { - "depth": 2, - "title": "Introduction", - "anchor": "introduction" - }, - { - "depth": 2, - "title": "What Is a Transaction?", - "anchor": "what-is-a-transaction" - }, - { - "depth": 3, - "title": "Signed Transactions", - "anchor": "signed-transactions" - }, - { - "depth": 3, - "title": "Unsigned Transactions", - "anchor": "unsigned-transactions" - }, - { - "depth": 3, - "title": "Inherent Transactions", - "anchor": "inherent-transactions" - }, - { - "depth": 2, - "title": "Transaction Formats", - "anchor": "transaction-formats" - }, - { - "depth": 3, - "title": "Types of Transaction Formats", - "anchor": "types-of-transaction-formats" - }, - { - "depth": 3, - "title": "Signed Transaction Data Structure", - "anchor": "signed-transaction-data-structure" - }, - { - "depth": 3, - "title": "Signed Extensions", - "anchor": "signed-extensions" - }, - { - "depth": 2, - "title": "Transaction Construction", - "anchor": "transaction-construction" - }, - { - "depth": 3, - "title": "Construct a Signed Transaction", - "anchor": "construct-a-signed-transaction" - }, - { - "depth": 3, - "title": "Transaction Encoding", - "anchor": "transaction-encoding" - }, - { - "depth": 3, - "title": "Customize Transaction Construction", - "anchor": "customize-transaction-construction" - }, - { - "depth": 2, - "title": "Lifecycle of a Transaction", - "anchor": "lifecycle-of-a-transaction" - }, - { - "depth": 3, - "title": "Define Transaction Properties", - "anchor": "define-transaction-properties" - }, - { - "depth": 3, - "title": "Process on a Block Authoring Node", - "anchor": "process-on-a-block-authoring-node" - }, - { - "depth": 3, - "title": "Validate and Queue", - "anchor": "validate-and-queue" - }, - { - "depth": 3, - "title": "Transaction Ordering and Priority", - "anchor": "transaction-ordering-and-priority" - }, - { - "depth": 3, - "title": "Transaction Execution", - "anchor": "transaction-execution" - }, - { - "depth": 2, - "title": "Transaction Mortality", - "anchor": "transaction-mortality" - }, - { - "depth": 2, - "title": "Unique Identifiers for Extrinsics", - "anchor": "unique-identifiers-for-extrinsics" - }, - { - "depth": 2, - "title": "Additional Resources", - "anchor": "additional-resources" - } - ], - "stats": { - "chars": 23610, - "words": 3333, - "headings": 22, - "estimated_token_count_total": 4708 - }, - "hash": "sha256:66726634d3a51cd9c471621054a6e5f09c8061dca6144b64c8bcf45626359617", - "token_estimator": "heuristic-v1" - }, - { - "id": "reference-parachains-chain-data", - "title": "Chain Data", - "slug": "reference-parachains-chain-data", - "categories": [ - "Basics", - "Polkadot Protocol" - ], - "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/reference-parachains-chain-data.md", - "html_url": "https://docs.polkadot.com/reference/parachains/chain-data/", - "preview": "Understanding and leveraging on-chain data is a fundamental aspect of blockchain development. Whether you're building frontend applications or backend systems, accessing and decoding runtime metadata is vital to interacting with the blockchain. This guide introduces you to the tools and processes for generating and retrieving metadata, explains its role in application development, and outlines the additional APIs available for interacting with a Polkadot node. By mastering these components, you", - "outline": [ - { - "depth": 2, - "title": "Introduction", - "anchor": "introduction" - }, - { - "depth": 2, - "title": "Application Development", - "anchor": "application-development" - }, - { - "depth": 2, - "title": "Understand Metadata", - "anchor": "understand-metadata" - }, - { - "depth": 2, - "title": "Expose Runtime Information as Metadata", - "anchor": "expose-runtime-information-as-metadata" - }, - { - "depth": 2, - "title": "Generate Metadata", - "anchor": "generate-metadata" - }, - { - "depth": 2, - "title": "Retrieve Runtime Metadata", - "anchor": "retrieve-runtime-metadata" - }, - { - "depth": 3, - "title": "Use Polkadot.js", - "anchor": "use-polkadotjs" - }, - { - "depth": 3, - "title": "Use Curl", - "anchor": "use-curl" - }, - { - "depth": 3, - "title": "Use Subxt", - "anchor": "use-subxt" - }, - { - "depth": 2, - "title": "Client Applications and Metadata", - "anchor": "client-applications-and-metadata" - }, - { - "depth": 2, - "title": "Metadata Format", - "anchor": "metadata-format" - }, - { - "depth": 3, - "title": "Pallets", - "anchor": "pallets" - }, - { - "depth": 3, - "title": "Extrinsic", - "anchor": "extrinsic" - }, - { - "depth": 2, - "title": "Included RPC APIs", - "anchor": "included-rpc-apis" - }, - { - "depth": 2, - "title": "Additional Resources", - "anchor": "additional-resources" - } - ], - "stats": { - "chars": 18650, - "words": 2216, - "headings": 15, - "estimated_token_count_total": 3774 - }, - "hash": "sha256:49238d1e9e2c33e0fcd3a84b5e30f0d3840d7d23a783b538875e0a23f38efc1d", - "token_estimator": "heuristic-v1" - }, - { - "id": "reference-parachains-consensus-async-backing", - "title": "reference-parachains-consensus-async-backing", - "slug": "reference-parachains-consensus-async-backing", - "categories": [ - "Uncategorized" - ], - "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/reference-parachains-consensus-async-backing.md", - "html_url": "https://docs.polkadot.com/reference/parachains/consensus/async-backing/", - "preview": "TODO", - "outline": [], - "stats": { - "chars": 5, - "words": 1, - "headings": 0, - "estimated_token_count_total": 0 - }, - "hash": "sha256:56ba36249ea8216ad513b13df3de6c0e490ba214897674d30331f1c7e7edbef3", - "token_estimator": "heuristic-v1" - }, - { - "id": "reference-parachains-consensus-elastic-scaling", - "title": "Elastic Scaling", - "slug": "reference-parachains-consensus-elastic-scaling", - "categories": [ - "Polkadot Protocol" - ], - "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/reference-parachains-consensus-elastic-scaling.md", - "html_url": "https://docs.polkadot.com/reference/parachains/consensus/elastic-scaling/", - "preview": "Polkadot's architecture delivers scalability and security through its shared security model, where the relay chain coordinates and validates multiple parallel chains.", - "outline": [ - { - "depth": 2, - "title": "Introduction", - "anchor": "introduction" - }, - { - "depth": 2, - "title": "How Elastic Scaling Works", - "anchor": "how-elastic-scaling-works" - }, - { - "depth": 2, - "title": "Benefits of Elastic Scaling", - "anchor": "benefits-of-elastic-scaling" - }, - { - "depth": 2, - "title": "Use Cases", - "anchor": "use-cases" - }, - { - "depth": 3, - "title": "Handling Sudden Traffic Spikes", - "anchor": "handling-sudden-traffic-spikes" - }, - { - "depth": 3, - "title": "Supporting Early-Stage Growth", - "anchor": "supporting-early-stage-growth" - }, - { - "depth": 3, - "title": "Scaling Massive IoT Networks", - "anchor": "scaling-massive-iot-networks" - }, - { - "depth": 3, - "title": "Powering Real-Time, Low-Latency Systems", - "anchor": "powering-real-time-low-latency-systems" - } - ], - "stats": { - "chars": 7871, - "words": 1047, - "headings": 8, - "estimated_token_count_total": 1440 - }, - "hash": "sha256:2d228c52844df8952520fafdd3e6f0e26bfd2f32b5ee60c6241cf7d38603643c", - "token_estimator": "heuristic-v1" - }, - { - "id": "reference-parachains-consensus-overview", - "title": "Parachain Consensus", - "slug": "reference-parachains-consensus-overview", - "categories": [ - "Polkadot Protocol", - "Parachains" - ], - "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/reference-parachains-consensus-overview.md", - "html_url": "https://docs.polkadot.com/reference/parachains/consensus/overview/", - "preview": "Parachains are independent blockchains built with the Polkadot SDK, designed to leverage Polkadot’s relay chain for shared security and transaction finality. These specialized chains operate as part of Polkadot’s execution sharding model, where each parachain manages its own state and transactions while relying on the relay chain for validation and consensus.", - "outline": [ - { - "depth": 2, - "title": "Introduction", - "anchor": "introduction" - }, - { - "depth": 2, - "title": "The Role of Collators", - "anchor": "the-role-of-collators" - }, - { - "depth": 2, - "title": "Consensus and Validation", - "anchor": "consensus-and-validation" - }, - { - "depth": 3, - "title": "Path of a Parachain Block", - "anchor": "path-of-a-parachain-block" - }, - { - "depth": 2, - "title": "Where to Go Next", - "anchor": "where-to-go-next" - } - ], - "stats": { - "chars": 6874, - "words": 873, - "headings": 5, - "estimated_token_count_total": 1296 - }, - "hash": "sha256:58e87829668cd9e3e034d94fcaf48b090970093f6d5a6136630e5d268a8846c8", - "token_estimator": "heuristic-v1" - }, - { - "id": "reference-parachains-consensus", - "title": "reference-parachains-consensus", - "slug": "reference-parachains-consensus", - "categories": [ - "Uncategorized" - ], - "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/reference-parachains-consensus.md", - "html_url": "https://docs.polkadot.com/reference/parachains/consensus/", - "preview": "TODO", - "outline": [], - "stats": { - "chars": 5, - "words": 1, - "headings": 0, - "estimated_token_count_total": 0 - }, - "hash": "sha256:56ba36249ea8216ad513b13df3de6c0e490ba214897674d30331f1c7e7edbef3", - "token_estimator": "heuristic-v1" - }, - { - "id": "reference-parachains-cryptography", - "title": "Cryptography", - "slug": "reference-parachains-cryptography", - "categories": [ - "Basics", - "Polkadot Protocol" - ], - "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/reference-parachains-cryptography.md", - "html_url": "https://docs.polkadot.com/reference/parachains/cryptography/", - "preview": "Cryptography forms the backbone of blockchain technology, providing the mathematical verifiability crucial for consensus systems, data integrity, and user security. While a deep understanding of the underlying mathematical processes isn't necessary for most blockchain developers, grasping the fundamental applications of cryptography is essential. This page comprehensively overviews cryptographic implementations used across Polkadot SDK-based chains and the broader blockchain ecosystem.", - "outline": [ - { - "depth": 2, - "title": "Introduction", - "anchor": "introduction" - }, - { - "depth": 2, - "title": "Hash Functions", - "anchor": "hash-functions" - }, - { - "depth": 3, - "title": "Key Properties of Hash Functions", - "anchor": "key-properties-of-hash-functions" - }, - { - "depth": 3, - "title": "Blake2", - "anchor": "blake2" - }, - { - "depth": 2, - "title": "Types of Cryptography", - "anchor": "types-of-cryptography" - }, - { - "depth": 3, - "title": "Symmetric Cryptography", - "anchor": "symmetric-cryptography" - }, - { - "depth": 3, - "title": "Asymmetric Cryptography", - "anchor": "asymmetric-cryptography" - }, - { - "depth": 3, - "title": "Trade-offs and Compromises", - "anchor": "trade-offs-and-compromises" - }, - { - "depth": 2, - "title": "Digital Signatures", - "anchor": "digital-signatures" - }, - { - "depth": 3, - "title": "Example of Creating a Digital Signature", - "anchor": "example-of-creating-a-digital-signature" - }, - { - "depth": 2, - "title": "Elliptic Curve", - "anchor": "elliptic-curve" - }, - { - "depth": 3, - "title": "Various Implementations", - "anchor": "various-implementations" - } - ], - "stats": { - "chars": 8860, - "words": 1293, - "headings": 12, - "estimated_token_count_total": 1797 - }, - "hash": "sha256:259dcef86aadc513675258b665cc3940db65af6eb32a5db85da6ac339966fa60", - "token_estimator": "heuristic-v1" - }, - { - "id": "reference-parachains-data-encoding", - "title": "Data Encoding", - "slug": "reference-parachains-data-encoding", - "categories": [ - "Basics", - "Polkadot Protocol" - ], - "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/reference-parachains-data-encoding.md", - "html_url": "https://docs.polkadot.com/reference/parachains/data-encoding/", - "preview": "The Polkadot SDK uses a lightweight and efficient encoding/decoding mechanism to optimize data transmission across the network. This mechanism, known as the _SCALE_ codec, is used for serializing and deserializing data.", - "outline": [ - { - "depth": 2, - "title": "Introduction", - "anchor": "introduction" - }, - { - "depth": 2, - "title": "SCALE Codec", - "anchor": "scale-codec" - }, - { - "depth": 3, - "title": "Encode", - "anchor": "encode" - }, - { - "depth": 3, - "title": "Decode", - "anchor": "decode" - }, - { - "depth": 3, - "title": "CompactAs", - "anchor": "compactas" - }, - { - "depth": 3, - "title": "HasCompact", - "anchor": "hascompact" - }, - { - "depth": 3, - "title": "EncodeLike", - "anchor": "encodelike" - }, - { - "depth": 3, - "title": "Data Types", - "anchor": "data-types" - }, - { - "depth": 2, - "title": "Encode and Decode Rust Trait Implementations", - "anchor": "encode-and-decode-rust-trait-implementations" - }, - { - "depth": 2, - "title": "SCALE Codec Libraries", - "anchor": "scale-codec-libraries" - } - ], - "stats": { - "chars": 13629, - "words": 1314, - "headings": 10, - "estimated_token_count_total": 3213 - }, - "hash": "sha256:e448294b6e52291ac0add5fa6533572814e6cd27af42bdaccc2000b86f52d775", - "token_estimator": "heuristic-v1" - }, - { - "id": "reference-parachains-interoperability", - "title": "Interoperability", - "slug": "reference-parachains-interoperability", - "categories": [ - "Basics", - "Polkadot Protocol" - ], - "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/reference-parachains-interoperability.md", - "html_url": "https://docs.polkadot.com/reference/parachains/interoperability/", - "preview": "Interoperability lies at the heart of the Polkadot ecosystem, enabling communication and collaboration across a diverse range of blockchains. By bridging the gaps between parachains, relay chains, and even external networks, Polkadot unlocks the potential for truly decentralized applications, efficient resource sharing, and scalable solutions.", - "outline": [ - { - "depth": 2, - "title": "Introduction", - "anchor": "introduction" - }, - { - "depth": 2, - "title": "Why Interoperability Matters", - "anchor": "why-interoperability-matters" - }, - { - "depth": 2, - "title": "Key Mechanisms for Interoperability", - "anchor": "key-mechanisms-for-interoperability" - }, - { - "depth": 3, - "title": "Cross-Consensus Messaging (XCM): The Backbone of Communication", - "anchor": "cross-consensus-messaging-xcm-the-backbone-of-communication" - }, - { - "depth": 3, - "title": "Bridges: Connecting External Networks", - "anchor": "bridges-connecting-external-networks" - }, - { - "depth": 2, - "title": "The Polkadot Advantage", - "anchor": "the-polkadot-advantage" - }, - { - "depth": 2, - "title": "Looking Ahead", - "anchor": "looking-ahead" - } - ], - "stats": { - "chars": 4636, - "words": 585, - "headings": 7, - "estimated_token_count_total": 773 - }, - "hash": "sha256:6d91e4459ae2fca5f55e77d69a2b14c1205c78c064f2fc99ae5b92927e85601a", - "token_estimator": "heuristic-v1" - }, - { - "id": "reference-parachains-networks", - "title": "Networks", - "slug": "reference-parachains-networks", - "categories": [ - "Basics", - "Polkadot Protocol", - "Networks" - ], - "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/reference-parachains-networks.md", - "html_url": "https://docs.polkadot.com/reference/parachains/networks/", - "preview": "The Polkadot ecosystem is built on a robust set of networks designed to enable secure and scalable development. Whether you are testing new features or deploying to live production, Polkadot offers several layers of networks tailored for each stage of the development process. From local environments to experimental networks like Kusama and community-run TestNets such as Paseo, developers can thoroughly test, iterate, and validate their applications. This guide will introduce you to Polkadot's va", - "outline": [ - { - "depth": 2, - "title": "Introduction", - "anchor": "introduction" - }, - { - "depth": 2, - "title": "Network Overview", - "anchor": "network-overview" - }, - { - "depth": 2, - "title": "Polkadot Development Networks", - "anchor": "polkadot-development-networks" - }, - { - "depth": 2, - "title": "Kusama Network", - "anchor": "kusama-network" - }, - { - "depth": 2, - "title": "Test Networks", - "anchor": "test-networks" - }, - { - "depth": 3, - "title": "Westend", - "anchor": "westend" - }, - { - "depth": 3, - "title": "Paseo", - "anchor": "paseo" - }, - { - "depth": 2, - "title": "Local Test Networks", - "anchor": "local-test-networks" - }, - { - "depth": 3, - "title": "Zombienet", - "anchor": "zombienet" - }, - { - "depth": 3, - "title": "Chopsticks", - "anchor": "chopsticks" - } - ], - "stats": { - "chars": 7834, - "words": 1111, - "headings": 10, - "estimated_token_count_total": 1473 - }, - "hash": "sha256:e49e063a2cc0fb5a48c6cdc3de266bb6e025a006940fea8e90cc4d5f9884900f", - "token_estimator": "heuristic-v1" - }, - { - "id": "reference-parachains-node-and-runtime", - "title": "Node and Runtime", - "slug": "reference-parachains-node-and-runtime", - "categories": [ - "Basics", - "Polkadot Protocol" - ], - "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/reference-parachains-node-and-runtime.md", - "html_url": "https://docs.polkadot.com/reference/parachains/node-and-runtime/", - "preview": "Every blockchain platform relies on a decentralized network of computers, called nodes, that communicate with each other about transactions and blocks. In this context, a node refers to the software running on the connected devices rather than the physical or virtual machines in the network.", - "outline": [ - { - "depth": 2, - "title": "Introduction", - "anchor": "introduction" - }, - { - "depth": 2, - "title": "Architectural Principles", - "anchor": "architectural-principles" - }, - { - "depth": 3, - "title": "Advantages of this Architecture", - "anchor": "advantages-of-this-architecture" - }, - { - "depth": 2, - "title": "Node (Client)", - "anchor": "node-client" - }, - { - "depth": 2, - "title": "Runtime", - "anchor": "runtime" - }, - { - "depth": 3, - "title": "Characteristics", - "anchor": "characteristics" - }, - { - "depth": 3, - "title": "Key Functions", - "anchor": "key-functions" - }, - { - "depth": 2, - "title": "Communication Between Node and Runtime", - "anchor": "communication-between-node-and-runtime" - }, - { - "depth": 3, - "title": "Runtime APIs", - "anchor": "runtime-apis" - }, - { - "depth": 3, - "title": "Host Functions", - "anchor": "host-functions" - } - ], - "stats": { - "chars": 4937, - "words": 628, - "headings": 10, - "estimated_token_count_total": 914 - }, - "hash": "sha256:8122e21c149d0863cfe3b37fc5606bcdb91668e9d265f0f05451a61ff70e4e93", - "token_estimator": "heuristic-v1" - }, - { - "id": "reference-parachains-randomness", - "title": "Randomness", - "slug": "reference-parachains-randomness", - "categories": [ - "Basics", - "Polkadot Protocol" - ], - "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/reference-parachains-randomness.md", - "html_url": "https://docs.polkadot.com/reference/parachains/randomness/", - "preview": "Randomness is crucial in Proof of Stake (PoS) blockchains to ensure a fair and unpredictable distribution of validator duties. However, computers are inherently deterministic, meaning the same input always produces the same output. What we typically refer to as \"random\" numbers on a computer are actually pseudo-random. These numbers rely on an initial \"seed,\" which can come from external sources like [atmospheric noise](https://www.random.org/randomness/){target=\\_blank}, [heart rates](https://m", - "outline": [ - { - "depth": 2, - "title": "Introduction", - "anchor": "introduction" - }, - { - "depth": 2, - "title": "VRF", - "anchor": "vrf" - }, - { - "depth": 3, - "title": "How VRF Works", - "anchor": "how-vrf-works" - }, - { - "depth": 2, - "title": "RANDAO", - "anchor": "randao" - }, - { - "depth": 2, - "title": "VDFs", - "anchor": "vdfs" - }, - { - "depth": 2, - "title": "Additional Resources", - "anchor": "additional-resources" - } - ], - "stats": { - "chars": 6503, - "words": 1005, - "headings": 6, - "estimated_token_count_total": 1388 - }, - "hash": "sha256:c7d8a5a4263fd21af458ab0bd102377104affdf2431b4fe74eeff4ebe62a4a81", - "token_estimator": "heuristic-v1" - }, - { - "id": "reference-parachains", - "title": "Parachains Overview", - "slug": "reference-parachains", - "categories": [ - "Basics", - "Parachains" - ], - "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/reference-parachains.md", - "html_url": "https://docs.polkadot.com/reference/parachains/", - "preview": "A parachain is a specialized blockchain that connects to the Polkadot relay chain, benefiting from shared security, interoperability, and scalability. Parachains are built using the [Polkadot SDK](https://github.com/paritytech/polkadot-sdk){target=\\_blank}, a powerful toolkit written in Rust that provides everything needed to create custom blockchain logic while integrating seamlessly with the Polkadot network.", - "outline": [ - { - "depth": 2, - "title": "Introduction", - "anchor": "introduction" - }, - { - "depth": 2, - "title": "Polkadot SDK: Parachain Architecture", - "anchor": "polkadot-sdk-parachain-architecture" - }, - { - "depth": 3, - "title": "Substrate: The Foundation", - "anchor": "substrate-the-foundation" - }, - { - "depth": 3, - "title": "FRAME: Building Blocks for Your Runtime", - "anchor": "frame-building-blocks-for-your-runtime" - }, - { - "depth": 3, - "title": "Cumulus: Parachain-Specific Functionality", - "anchor": "cumulus-parachain-specific-functionality" - }, - { - "depth": 2, - "title": "Where to Go Next", - "anchor": "where-to-go-next" - } - ], - "stats": { - "chars": 8495, - "words": 1029, - "headings": 6, - "estimated_token_count_total": 1759 - }, - "hash": "sha256:ecb0d9459e08920db7d2d59dc7c01aba7a91ce8c9e39256bd0c3efa473dbaa17", - "token_estimator": "heuristic-v1" - }, - { - "id": "reference-polkadot-hub-assets-and-smart-contracts", - "title": "Asset Hub", - "slug": "reference-polkadot-hub-assets-and-smart-contracts", - "categories": [ - "Polkadot Protocol" - ], - "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/reference-polkadot-hub-assets-and-smart-contracts.md", - "html_url": "https://docs.polkadot.com/reference/polkadot-hub/assets-and-smart-contracts/", - "preview": "The Asset Hub is a critical component in the Polkadot ecosystem, enabling the management of fungible and non-fungible assets across the network. Since the relay chain focuses on maintaining security and consensus without direct asset management, Asset Hub provides a streamlined platform for creating, managing, and using on-chain assets in a fee-efficient manner. This guide outlines the core features of Asset Hub, including how it handles asset operations, cross-chain transfers, and asset integra", - "outline": [ - { - "depth": 2, - "title": "Introduction", - "anchor": "introduction" - }, - { - "depth": 2, - "title": "Assets Basics", - "anchor": "assets-basics" - }, - { - "depth": 2, - "title": "Assets Pallet", - "anchor": "assets-pallet" - }, - { - "depth": 3, - "title": "Key Features", - "anchor": "key-features" - }, - { - "depth": 3, - "title": "Main Functions", - "anchor": "main-functions" - }, - { - "depth": 3, - "title": "Querying Functions", - "anchor": "querying-functions" - }, - { - "depth": 3, - "title": "Permission Models and Roles", - "anchor": "permission-models-and-roles" - }, - { - "depth": 3, - "title": "Asset Freezing", - "anchor": "asset-freezing" - }, - { - "depth": 3, - "title": "Non-Custodial Transfers (Approval API)", - "anchor": "non-custodial-transfers-approval-api" - }, - { - "depth": 2, - "title": "Foreign Assets", - "anchor": "foreign-assets" - }, - { - "depth": 3, - "title": "Handling Foreign Assets", - "anchor": "handling-foreign-assets" - }, - { - "depth": 2, - "title": "Integration", - "anchor": "integration" - }, - { - "depth": 3, - "title": "API Sidecar", - "anchor": "api-sidecar" - }, - { - "depth": 3, - "title": "TxWrapper", - "anchor": "txwrapper" - }, - { - "depth": 3, - "title": "Parachain Node", - "anchor": "parachain-node" - }, - { - "depth": 2, - "title": "XCM Transfer Monitoring", - "anchor": "xcm-transfer-monitoring" - }, - { - "depth": 3, - "title": "Monitor XCM Deposits", - "anchor": "monitor-xcm-deposits" - }, - { - "depth": 3, - "title": "Track XCM Information Back to the Source", - "anchor": "track-xcm-information-back-to-the-source" - }, - { - "depth": 3, - "title": "Practical Monitoring Examples", - "anchor": "practical-monitoring-examples" - }, - { - "depth": 3, - "title": "Monitor for Failed XCM Transfers", - "anchor": "monitor-for-failed-xcm-transfers" - }, - { - "depth": 2, - "title": "Where to Go Next", - "anchor": "where-to-go-next" - } - ], - "stats": { - "chars": 18211, - "words": 2649, - "headings": 21, - "estimated_token_count_total": 3678 - }, - "hash": "sha256:3d10c04cffc5f737ff75b079d661c2c1904629d23ae1e415e64fd6ae4e98759e", - "token_estimator": "heuristic-v1" - }, - { - "id": "reference-polkadot-hub-bridging", - "title": "Bridge Hub", - "slug": "reference-polkadot-hub-bridging", - "categories": [ - "Polkadot Protocol" - ], - "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/reference-polkadot-hub-bridging.md", - "html_url": "https://docs.polkadot.com/reference/polkadot-hub/bridging/", - "preview": "The Bridge Hub system parachain plays a crucial role in facilitating trustless interactions between Polkadot, Kusama, Ethereum, and other blockchain ecosystems. By implementing on-chain light clients and supporting protocols like BEEFY and GRANDPA, Bridge Hub ensures seamless message transmission and state verification across chains. It also provides essential [pallets](/reference/glossary/#pallet){target=\\_blank} for sending and receiving messages, making it a cornerstone of Polkadot’s interope", - "outline": [ - { - "depth": 2, - "title": "Introduction", - "anchor": "introduction" - }, - { - "depth": 2, - "title": "Trustless Bridging", - "anchor": "trustless-bridging" - }, - { - "depth": 2, - "title": "Bridging Components", - "anchor": "bridging-components" - }, - { - "depth": 3, - "title": "Ethereum-Specific Support", - "anchor": "ethereum-specific-support" - }, - { - "depth": 2, - "title": "Deployed Bridges", - "anchor": "deployed-bridges" - }, - { - "depth": 2, - "title": "Where to Go Next", - "anchor": "where-to-go-next" - } - ], - "stats": { - "chars": 5467, - "words": 776, - "headings": 6, - "estimated_token_count_total": 1220 - }, - "hash": "sha256:86734ba8bcdea7913f488edf666a6104bed0a18649d57abde82c149c41c2b871", - "token_estimator": "heuristic-v1" - }, - { - "id": "reference-polkadot-hub-collectives-and-daos", - "title": "Collectives Chain", - "slug": "reference-polkadot-hub-collectives-and-daos", - "categories": [ - "Polkadot Protocol" - ], - "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/reference-polkadot-hub-collectives-and-daos.md", - "html_url": "https://docs.polkadot.com/reference/polkadot-hub/collectives-and-daos/", - "preview": "Established through [Referendum 81](https://polkadot-old.polkassembly.io/referendum/81){target=\\_blank}, the Collectives chain operates as a dedicated parachain exclusive to the Polkadot network with no counterpart on Kusama. This specialized infrastructure provides a foundation for various on-chain governance groups essential to Polkadot's ecosystem.", - "outline": [ - { - "depth": 2, - "title": "Introduction", - "anchor": "introduction" - }, - { - "depth": 2, - "title": "Key Collectives", - "anchor": "key-collectives" - } - ], - "stats": { - "chars": 2288, - "words": 293, - "headings": 2, - "estimated_token_count_total": 424 - }, - "hash": "sha256:59ec351fbb8d3a392e90f4f5bf6b62f58b21d6d7a900c5e367e5d2e09ecb3aca", - "token_estimator": "heuristic-v1" - }, - { - "id": "reference-polkadot-hub-consensus-and-security-agile-coretime", - "title": "Agile Coretime", - "slug": "reference-polkadot-hub-consensus-and-security-agile-coretime", - "categories": [ - "Polkadot Protocol" - ], - "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/reference-polkadot-hub-consensus-and-security-agile-coretime.md", - "html_url": "https://docs.polkadot.com/reference/polkadot-hub/consensus-and-security/agile-coretime/", - "preview": "Agile Coretime is the [scheduling](https://en.wikipedia.org/wiki/Scheduling_(computing)){target=\\_blank} framework on Polkadot that lets parachains efficiently access cores, which comprise an active validator set tasked with parablock validation. As the first blockchain to enable a flexible scheduling system for blockspace production, Polkadot offers unparalleled adaptability for parachains.", - "outline": [ - { - "depth": 2, - "title": "Introduction", - "anchor": "introduction" - }, - { - "depth": 2, - "title": "Bulk Coretime", - "anchor": "bulk-coretime" - }, - { - "depth": 3, - "title": "Coretime Interlacing", - "anchor": "coretime-interlacing" - }, - { - "depth": 3, - "title": "Coretime Splitting", - "anchor": "coretime-splitting" - }, - { - "depth": 2, - "title": "On-Demand Coretime", - "anchor": "on-demand-coretime" - } - ], - "stats": { - "chars": 3028, - "words": 452, - "headings": 5, - "estimated_token_count_total": 619 - }, - "hash": "sha256:00be43ac8d666bbe15c5c2fa5a5085697d0bb5a6f341ebbb943a209f0be355df", - "token_estimator": "heuristic-v1" - }, - { - "id": "reference-polkadot-hub-consensus-and-security-pos-consensus", - "title": "Proof of Stake Consensus", - "slug": "reference-polkadot-hub-consensus-and-security-pos-consensus", - "categories": [ - "Polkadot Protocol" - ], - "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/reference-polkadot-hub-consensus-and-security-pos-consensus.md", - "html_url": "https://docs.polkadot.com/reference/polkadot-hub/consensus-and-security/pos-consensus/", - "preview": "Polkadot's Proof of Stake consensus model leverages a unique hybrid approach by design to promote decentralized and secure network operations. In traditional Proof of Stake (PoS) systems, a node's ability to validate transactions is tied to its token holdings, which can lead to centralization risks and limited validator participation. Polkadot addresses these concerns through its [Nominated Proof of Stake (NPoS)](/reference/glossary/#nominated-proof-of-stake-npos){target=\\_blank} model and a com", - "outline": [ - { - "depth": 2, - "title": "Introduction", - "anchor": "introduction" - }, - { - "depth": 2, - "title": "Nominated Proof of Stake", - "anchor": "nominated-proof-of-stake" - }, - { - "depth": 2, - "title": "Hybrid Consensus", - "anchor": "hybrid-consensus" - }, - { - "depth": 2, - "title": "Block Production - BABE", - "anchor": "block-production-babe" - }, - { - "depth": 3, - "title": "Validator Participation", - "anchor": "validator-participation" - }, - { - "depth": 3, - "title": "Additional Resources", - "anchor": "additional-resources" - }, - { - "depth": 2, - "title": "Finality Gadget - GRANDPA", - "anchor": "finality-gadget-grandpa" - }, - { - "depth": 3, - "title": "Probabilistic vs. Provable Finality", - "anchor": "probabilistic-vs-provable-finality" - }, - { - "depth": 3, - "title": "Additional Resources", - "anchor": "additional-resources-2" - }, - { - "depth": 2, - "title": "Fork Choice", - "anchor": "fork-choice" - }, - { - "depth": 3, - "title": "Additional Resources", - "anchor": "additional-resources-3" - }, - { - "depth": 2, - "title": "Bridging - BEEFY", - "anchor": "bridging-beefy" - }, - { - "depth": 3, - "title": "Additional Resources", - "anchor": "additional-resources-4" - } - ], - "stats": { - "chars": 12753, - "words": 1834, - "headings": 13, - "estimated_token_count_total": 2526 - }, - "hash": "sha256:231fc555eefe5f910fb36e0c03945147d0fb235272850797391751f4444b0a9c", - "token_estimator": "heuristic-v1" - }, - { - "id": "reference-polkadot-hub-consensus-and-security-relay-chain", - "title": "Overview of the Polkadot Relay Chain", - "slug": "reference-polkadot-hub-consensus-and-security-relay-chain", - "categories": [ - "Basics", - "Polkadot Protocol", - "Parachains" - ], - "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/reference-polkadot-hub-consensus-and-security-relay-chain.md", - "html_url": "https://docs.polkadot.com/reference/polkadot-hub/consensus-and-security/relay-chain/", - "preview": "Polkadot is a next-generation blockchain protocol designed to support a multi-chain future by enabling secure communication and interoperability between different blockchains. Built as a Layer-0 protocol, Polkadot introduces innovations like application-specific Layer-1 chains ([parachains](/polkadot-protocol/architecture/parachains/){targe=\\_blank}), shared security through [Nominated Proof of Stake (NPoS)](/reference/glossary/#nominated-proof-of-stake-npos){target=\\_blank}, and cross-chain int", - "outline": [ - { - "depth": 2, - "title": "Introduction", - "anchor": "introduction" - }, - { - "depth": 2, - "title": "Polkadot 1.0", - "anchor": "polkadot-10" - }, - { - "depth": 3, - "title": "High-Level Architecture", - "anchor": "high-level-architecture" - }, - { - "depth": 3, - "title": "Polkadot's Additional Functionalities", - "anchor": "polkadots-additional-functionalities" - }, - { - "depth": 3, - "title": "Polkadot's Resilience", - "anchor": "polkadots-resilience" - }, - { - "depth": 3, - "title": "Polkadot's Blockspace", - "anchor": "polkadots-blockspace" - }, - { - "depth": 2, - "title": "DOT Token", - "anchor": "dot-token" - }, - { - "depth": 3, - "title": "Redenomination of DOT", - "anchor": "redenomination-of-dot" - }, - { - "depth": 3, - "title": "The Planck Unit", - "anchor": "the-planck-unit" - }, - { - "depth": 3, - "title": "Uses for DOT", - "anchor": "uses-for-dot" - }, - { - "depth": 2, - "title": "JAM and the Road Ahead", - "anchor": "jam-and-the-road-ahead" - } - ], - "stats": { - "chars": 12458, - "words": 1774, - "headings": 11, - "estimated_token_count_total": 2580 - }, - "hash": "sha256:60f5ac9f67fb9f2188121219830538d334028b3b9e85d42bd1e7279043654e39", - "token_estimator": "heuristic-v1" - }, - { - "id": "reference-polkadot-hub-people-and-identity", - "title": "People Chain", - "slug": "reference-polkadot-hub-people-and-identity", - "categories": [ - "Polkadot Protocol" - ], - "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/reference-polkadot-hub-people-and-identity.md", - "html_url": "https://docs.polkadot.com/reference/polkadot-hub/people-and-identity/", - "preview": "People chain is a specialized parachain within the Polkadot ecosystem dedicated to secure, decentralized identity management.", - "outline": [ - { - "depth": 2, - "title": "Introduction", - "anchor": "introduction" - }, - { - "depth": 2, - "title": "Identity Management System", - "anchor": "identity-management-system" - }, - { - "depth": 3, - "title": "Sub-Identities", - "anchor": "sub-identities" - }, - { - "depth": 2, - "title": "Verification Process", - "anchor": "verification-process" - }, - { - "depth": 3, - "title": "Judgment Requests", - "anchor": "judgment-requests" - }, - { - "depth": 3, - "title": "Judgment Classifications", - "anchor": "judgment-classifications" - }, - { - "depth": 3, - "title": "Registrars", - "anchor": "registrars" - }, - { - "depth": 2, - "title": "Where to Go Next", - "anchor": "where-to-go-next" - } - ], - "stats": { - "chars": 4750, - "words": 606, - "headings": 8, - "estimated_token_count_total": 876 - }, - "hash": "sha256:8239d1e8d8642cb7c10e9e5f971c99b999e9e4a87373b50bf4a691225c1e4702", - "token_estimator": "heuristic-v1" - }, - { - "id": "reference-polkadot-hub", - "title": "reference-polkadot-hub", - "slug": "reference-polkadot-hub", - "categories": [ - "Uncategorized" - ], - "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/reference-polkadot-hub.md", - "html_url": "https://docs.polkadot.com/reference/polkadot-hub/", - "preview": "TODO", - "outline": [], - "stats": { - "chars": 5, - "words": 1, - "headings": 0, - "estimated_token_count_total": 0 - }, - "hash": "sha256:56ba36249ea8216ad513b13df3de6c0e490ba214897674d30331f1c7e7edbef3", - "token_estimator": "heuristic-v1" - }, - { - "id": "reference-tools-chopsticks", - "title": "reference-tools-chopsticks", - "slug": "reference-tools-chopsticks", - "categories": [ - "Uncategorized" - ], - "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/reference-tools-chopsticks.md", - "html_url": "https://docs.polkadot.com/reference/tools/chopsticks/", - "preview": "TODO", - "outline": [], - "stats": { - "chars": 5, - "words": 1, - "headings": 0, - "estimated_token_count_total": 0 - }, - "hash": "sha256:56ba36249ea8216ad513b13df3de6c0e490ba214897674d30331f1c7e7edbef3", - "token_estimator": "heuristic-v1" - }, - { - "id": "reference-tools-dedot", - "title": "Dedot", - "slug": "reference-tools-dedot", - "categories": [ - "Tooling", - "Dapps" - ], - "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/reference-tools-dedot.md", - "html_url": "https://docs.polkadot.com/reference/tools/dedot/", - "preview": "[Dedot](https://github.com/dedotdev/dedot){target=\\_blank} is a next-generation JavaScript client for Polkadot and Polkadot SDK-based blockchains. Designed to elevate the dApp development experience, Dedot is built and optimized to be lightweight and tree-shakable, offering precise types and APIs suggestions for individual Polkadot SDK-based blockchains and [ink! smart contracts](https://use.ink/){target=\\_blank}.", - "outline": [ - { - "depth": 2, - "title": "Introduction", - "anchor": "introduction" - }, - { - "depth": 3, - "title": "Key Features", - "anchor": "key-features" - }, - { - "depth": 2, - "title": "Installation", - "anchor": "installation" - }, - { - "depth": 2, - "title": "Get Started", - "anchor": "get-started" - }, - { - "depth": 3, - "title": "Initialize a Client Instance", - "anchor": "initialize-a-client-instance" - }, - { - "depth": 3, - "title": "Enable Type and API Suggestions", - "anchor": "enable-type-and-api-suggestions" - }, - { - "depth": 3, - "title": "Read On-Chain Data", - "anchor": "read-on-chain-data" - }, - { - "depth": 3, - "title": "Sign and Send Transactions", - "anchor": "sign-and-send-transactions" - }, - { - "depth": 2, - "title": "Where to Go Next", - "anchor": "where-to-go-next" - } - ], - "stats": { - "chars": 8855, - "words": 1100, - "headings": 9, - "estimated_token_count_total": 2300 - }, - "hash": "sha256:ba24e31e2ad94fbf1d73f1878da92dd2e1476db00170780bbdf0e65ab18bc961", - "token_estimator": "heuristic-v1" - }, - { - "id": "reference-tools-light-clients", - "title": "Light Clients", - "slug": "reference-tools-light-clients", - "categories": [ - "Parachains", - "Tooling" - ], - "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/reference-tools-light-clients.md", - "html_url": "https://docs.polkadot.com/reference/tools/light-clients/", - "preview": "Light clients enable secure and efficient blockchain interaction without running a full node. They provide a trust-minimized alternative to JSON-RPC by verifying data through cryptographic proofs rather than blindly trusting remote nodes.", - "outline": [ - { - "depth": 2, - "title": "Introduction", - "anchor": "introduction" - }, - { - "depth": 2, - "title": "Light Clients Workflow", - "anchor": "light-clients-workflow" - }, - { - "depth": 2, - "title": "JSON-RPC and Light Client Comparison", - "anchor": "json-rpc-and-light-client-comparison" - }, - { - "depth": 2, - "title": "Using Light Clients", - "anchor": "using-light-clients" - }, - { - "depth": 3, - "title": "PAPI Light Client Support", - "anchor": "papi-light-client-support" - }, - { - "depth": 3, - "title": "Substrate Connect - Browser Extension", - "anchor": "substrate-connect-browser-extension" - }, - { - "depth": 2, - "title": "Resources", - "anchor": "resources" - } - ], - "stats": { - "chars": 6490, - "words": 870, - "headings": 7, - "estimated_token_count_total": 1430 - }, - "hash": "sha256:1284c42be692167e01bcc44e2e134ec20615402675fac26df246c00aa1588d80", - "token_estimator": "heuristic-v1" - }, - { - "id": "reference-tools-moonwall", - "title": "E2E Testing with Moonwall", - "slug": "reference-tools-moonwall", - "categories": [ - "Parachains", - "Tooling" - ], - "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/reference-tools-moonwall.md", - "html_url": "https://docs.polkadot.com/reference/tools/moonwall/", - "preview": "Moonwall is an end-to-end testing framework designed explicitly for Polkadot SDK-based blockchain networks. It addresses one of the most significant challenges in blockchain development: managing complex test environments and network configurations.", - "outline": [ - { - "depth": 2, - "title": "Introduction", - "anchor": "introduction" - }, - { - "depth": 2, - "title": "Prerequisites", - "anchor": "prerequisites" - }, - { - "depth": 2, - "title": "Install Moonwall", - "anchor": "install-moonwall" - }, - { - "depth": 3, - "title": "Global Installation", - "anchor": "global-installation" - }, - { - "depth": 3, - "title": "Local Installation", - "anchor": "local-installation" - }, - { - "depth": 2, - "title": "Initialize Moonwall", - "anchor": "initialize-moonwall" - }, - { - "depth": 2, - "title": "Writing Tests", - "anchor": "writing-tests" - }, - { - "depth": 2, - "title": "Running the Tests", - "anchor": "running-the-tests" - }, - { - "depth": 2, - "title": "Where to Go Next", - "anchor": "where-to-go-next" - } - ], - "stats": { - "chars": 10240, - "words": 1295, - "headings": 9, - "estimated_token_count_total": 2453 - }, - "hash": "sha256:2c77cfb38bb2e466a8f56dabbb706fcd2e90cf1634fc9beb7f0ee95a75735653", - "token_estimator": "heuristic-v1" - }, - { - "id": "reference-tools-omninode", - "title": "Polkadot Omni Node", - "slug": "reference-tools-omninode", - "categories": [ - "Parachains", - "Tooling" - ], - "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/reference-tools-omninode.md", - "html_url": "https://docs.polkadot.com/reference/tools/omninode/", - "preview": "The [`polkadot-omni-node`](https://crates.io/crates/polkadot-omni-node/0.7.0){target=\\_blank} crate is a versatile, pre-built binary designed to simplify running parachains in the Polkadot ecosystem. Unlike traditional node binaries that are tightly coupled to specific runtime code, the `polkadot-omni-node` operates using an external [chain specification](/polkadot-protocol/glossary#chain-specification){target=\\_blank} file, allowing it to adapt dynamically to different parachains.", - "outline": [ - { - "depth": 2, - "title": "Introduction", - "anchor": "introduction" - }, - { - "depth": 2, - "title": "Prerequisites", - "anchor": "prerequisites" - }, - { - "depth": 2, - "title": "Install Polkadot Omni Node", - "anchor": "install-polkadot-omni-node" - }, - { - "depth": 2, - "title": "Obtain Chain Specifications", - "anchor": "obtain-chain-specifications" - }, - { - "depth": 2, - "title": "Run a Parachain Full Node", - "anchor": "run-a-parachain-full-node" - }, - { - "depth": 2, - "title": "Interact with the Node", - "anchor": "interact-with-the-node" - }, - { - "depth": 2, - "title": "Parachain Compatibility", - "anchor": "parachain-compatibility" - }, - { - "depth": 3, - "title": "Required Runtime APIs", - "anchor": "required-runtime-apis" - }, - { - "depth": 3, - "title": "Required Pallets", - "anchor": "required-pallets" - } - ], - "stats": { - "chars": 8913, - "words": 1164, - "headings": 9, - "estimated_token_count_total": 2017 - }, - "hash": "sha256:7db2d31ba37abad20b026c875f632b89739b45707e58809e2e8b32a09715c6f9", - "token_estimator": "heuristic-v1" - }, - { - "id": "reference-tools-papi", - "title": "Polkadot-API", - "slug": "reference-tools-papi", - "categories": [ - "Tooling", - "Dapps" - ], - "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/reference-tools-papi.md", - "html_url": "https://docs.polkadot.com/reference/tools/papi/", - "preview": "[Polkadot-API](https://github.com/polkadot-api/polkadot-api){target=\\_blank} (PAPI) is a set of libraries built to be modular, composable, and grounded in a “light-client first” approach. Its primary aim is to equip dApp developers with an extensive toolkit for building fully decentralized applications.", - "outline": [ - { - "depth": 2, - "title": "Introduction", - "anchor": "introduction" - }, - { - "depth": 2, - "title": "Get Started", - "anchor": "get-started" - }, - { - "depth": 3, - "title": "API Instantiation", - "anchor": "api-instantiation" - }, - { - "depth": 3, - "title": "Reading Chain Data", - "anchor": "reading-chain-data" - }, - { - "depth": 3, - "title": "Sending Transactions", - "anchor": "sending-transactions" - }, - { - "depth": 2, - "title": "Where to Go Next", - "anchor": "where-to-go-next" - } - ], - "stats": { - "chars": 8957, - "words": 1156, - "headings": 6, - "estimated_token_count_total": 1987 - }, - "hash": "sha256:2ca93b09d3bb9159bbf53816886a9b242bb3c13b996c51fd52962e049e2d5477", - "token_estimator": "heuristic-v1" - }, - { - "id": "reference-tools-paraspell", - "title": "ParaSpell XCM SDK", - "slug": "reference-tools-paraspell", - "categories": [ - "Uncategorized" - ], - "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/reference-tools-paraspell.md", - "html_url": "https://docs.polkadot.com/reference/tools/paraspell/", - "preview": "[ParaSpell](https://paraspell.github.io/docs/){target=\\_blank} is a comprehensive suite of open-source tools designed to simplify cross-chain interactions within the Polkadot ecosystem. At its core, ParaSpell is dedicated to enhancing the functionality of the [XCM (Cross-Consensus Messaging)](/parachains/interoperability/get-started/){target=\\_blank} protocol by providing developers with a unified and streamlined experience for building interoperable decentralized applications (dApps).", - "outline": [ - { - "depth": 2, - "title": "Introduction", - "anchor": "introduction" - }, - { - "depth": 3, - "title": "ParaSpell XCM SDK", - "anchor": "paraspell-xcm-sdk" - }, - { - "depth": 2, - "title": "Install ParaSpell", - "anchor": "install-paraspell" - }, - { - "depth": 2, - "title": "Where to Go Next", - "anchor": "where-to-go-next" - } - ], - "stats": { - "chars": 4043, - "words": 562, - "headings": 4, - "estimated_token_count_total": 888 - }, - "hash": "sha256:c8741954ea656680aa3322c825e3f6acbaac369baaa42232b06af9e5e482f74f", - "token_estimator": "heuristic-v1" - }, - { - "id": "reference-tools-polkadart", - "title": "Polkadart", - "slug": "reference-tools-polkadart", - "categories": [ - "Tooling", - "Dapps" - ], - "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/reference-tools-polkadart.md", - "html_url": "https://docs.polkadot.com/reference/tools/polkadart/", - "preview": "Polkadart is the most comprehensive Dart/Flutter SDK for interacting with Polkadot, Substrate, and other compatible blockchain networks. Designed with a Dart-first approach and type-safe APIs, it provides everything developers need to build powerful decentralized applications.", - "outline": [ - { - "depth": 2, - "title": "Installation", - "anchor": "installation" - }, - { - "depth": 2, - "title": "Get Started", - "anchor": "get-started" - }, - { - "depth": 3, - "title": "Type Generation", - "anchor": "type-generation" - }, - { - "depth": 3, - "title": "Run Generator", - "anchor": "run-generator" - }, - { - "depth": 3, - "title": "Use Generated Types", - "anchor": "use-generated-types" - }, - { - "depth": 3, - "title": "Creating an API Instance", - "anchor": "creating-an-api-instance" - }, - { - "depth": 3, - "title": "Reading Chain Data", - "anchor": "reading-chain-data" - }, - { - "depth": 3, - "title": "Subscribe to New Blocks", - "anchor": "subscribe-to-new-blocks" - }, - { - "depth": 3, - "title": "Send a Transaction", - "anchor": "send-a-transaction" - }, - { - "depth": 2, - "title": "Where to Go Next", - "anchor": "where-to-go-next" - } - ], - "stats": { - "chars": 5178, - "words": 624, - "headings": 10, - "estimated_token_count_total": 1084 - }, - "hash": "sha256:7f533abe61586af8438e350c41b741d74a8edb839f9dc4139bc4619ba3748258", - "token_estimator": "heuristic-v1" - }, - { - "id": "reference-tools-polkadot-js-api", - "title": "Polkadot.js API", - "slug": "reference-tools-polkadot-js-api", - "categories": [ - "Tooling", - "Dapps" - ], - "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/reference-tools-polkadot-js-api.md", - "html_url": "https://docs.polkadot.com/reference/tools/polkadot-js-api/", - "preview": "!!! warning \"Maintenance Mode Only\" The Polkadot.js API is now in maintenance mode and is no longer actively developed. New projects should use [Dedot](/develop/toolkit/api-libraries/dedot){target=\\_blank} (TypeScript-first API) or [Polkadot API](/develop/toolkit/api-libraries/papi){target=\\_blank} (modern, type-safe API) as actively maintained alternatives.", - "outline": [ - { - "depth": 2, - "title": "Introduction", - "anchor": "introduction" - }, - { - "depth": 3, - "title": "Dynamic API Generation", - "anchor": "dynamic-api-generation" - }, - { - "depth": 3, - "title": "Available API Categories", - "anchor": "available-api-categories" - }, - { - "depth": 2, - "title": "Installation", - "anchor": "installation" - }, - { - "depth": 2, - "title": "Get Started", - "anchor": "get-started" - }, - { - "depth": 3, - "title": "Creating an API Instance", - "anchor": "creating-an-api-instance" - }, - { - "depth": 3, - "title": "Reading Chain Data", - "anchor": "reading-chain-data" - }, - { - "depth": 3, - "title": "Sending Transactions", - "anchor": "sending-transactions" - }, - { - "depth": 2, - "title": "Where to Go Next", - "anchor": "where-to-go-next" - } - ], - "stats": { - "chars": 5042, - "words": 684, - "headings": 9, - "estimated_token_count_total": 1166 - }, - "hash": "sha256:ed3986f30880fefca5975fcdc847c68b4aca65862c63e3002b25391b0521781d", - "token_estimator": "heuristic-v1" - }, - { - "id": "reference-tools-py-substrate-interface", - "title": "Python Substrate Interface", - "slug": "reference-tools-py-substrate-interface", - "categories": [ - "Tooling", - "Dapps" - ], - "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/reference-tools-py-substrate-interface.md", - "html_url": "https://docs.polkadot.com/reference/tools/py-substrate-interface/", - "preview": "The [Python Substrate Interface](https://github.com/polkascan/py-substrate-interface){target=\\_blank} is a powerful library that enables interaction with Polkadot SDK-based chains. It provides essential functionality for:", - "outline": [ - { - "depth": 2, - "title": "Introduction", - "anchor": "introduction" - }, - { - "depth": 2, - "title": "Installation", - "anchor": "installation" - }, - { - "depth": 2, - "title": "Get Started", - "anchor": "get-started" - }, - { - "depth": 3, - "title": "Establishing Connection", - "anchor": "establishing-connection" - }, - { - "depth": 3, - "title": "Reading Chain State", - "anchor": "reading-chain-state" - }, - { - "depth": 3, - "title": "Submitting Transactions", - "anchor": "submitting-transactions" - }, - { - "depth": 2, - "title": "Where to Go Next", - "anchor": "where-to-go-next" - } - ], - "stats": { - "chars": 4302, - "words": 541, - "headings": 7, - "estimated_token_count_total": 942 - }, - "hash": "sha256:8987fc35cd28602054ee018031f773e2e3837425107c51d0e2ac68a94b86e9c0", - "token_estimator": "heuristic-v1" - }, - { - "id": "reference-tools-sidecar", - "title": "Sidecar REST API", - "slug": "reference-tools-sidecar", - "categories": [ - "Tooling", - "Dapps" - ], - "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/reference-tools-sidecar.md", - "html_url": "https://docs.polkadot.com/reference/tools/sidecar/", - "preview": "The [Sidecar REST API](https://github.com/paritytech/substrate-api-sidecar){target=\\_blank} is a service that provides a REST interface for interacting with Polkadot SDK-based blockchains. With this API, developers can easily access a broad range of endpoints for nodes, accounts, transactions, parachains, and more.", - "outline": [ - { - "depth": 2, - "title": "Introduction", - "anchor": "introduction" - }, - { - "depth": 2, - "title": "Prerequisites", - "anchor": "prerequisites" - }, - { - "depth": 2, - "title": "Installation", - "anchor": "installation" - }, - { - "depth": 2, - "title": "Usage", - "anchor": "usage" - }, - { - "depth": 3, - "title": "Endpoints", - "anchor": "endpoints" - }, - { - "depth": 2, - "title": "Where to Go Next", - "anchor": "where-to-go-next" - } - ], - "stats": { - "chars": 7309, - "words": 1033, - "headings": 6, - "estimated_token_count_total": 1945 - }, - "hash": "sha256:0795462182cb97256bb5c2acb035855fe0d6557185de8ac99482725ecb4f94c1", - "token_estimator": "heuristic-v1" - }, - { - "id": "reference-tools-subxt", - "title": "Subxt Rust API", - "slug": "reference-tools-subxt", - "categories": [ - "Tooling", - "Dapps" - ], - "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/reference-tools-subxt.md", - "html_url": "https://docs.polkadot.com/reference/tools/subxt/", - "preview": "Subxt is a Rust library designed to interact with Polkadot SDK-based blockchains. It provides a type-safe interface for submitting transactions, querying on-chain state, and performing other blockchain interactions. By leveraging Rust's strong type system, subxt ensures that your code is validated at compile time, reducing runtime errors and improving reliability.", - "outline": [ - { - "depth": 2, - "title": "Introduction", - "anchor": "introduction" - }, - { - "depth": 2, - "title": "Prerequisites", - "anchor": "prerequisites" - }, - { - "depth": 2, - "title": "Installation", - "anchor": "installation" - }, - { - "depth": 2, - "title": "Get Started", - "anchor": "get-started" - }, - { - "depth": 3, - "title": "Download Chain Metadata", - "anchor": "download-chain-metadata" - }, - { - "depth": 3, - "title": "Generate Type-Safe Interfaces", - "anchor": "generate-type-safe-interfaces" - }, - { - "depth": 3, - "title": "Initialize the Subxt Client", - "anchor": "initialize-the-subxt-client" - }, - { - "depth": 3, - "title": "Read Chain Data", - "anchor": "read-chain-data" - }, - { - "depth": 3, - "title": "Submit Transactions", - "anchor": "submit-transactions" - }, - { - "depth": 2, - "title": "Where to Go Next", - "anchor": "where-to-go-next" - } - ], - "stats": { - "chars": 9174, - "words": 1175, - "headings": 10, - "estimated_token_count_total": 2187 - }, - "hash": "sha256:56269d9ea47f5b4e92cd7d5a1e65ab06d181a9c380f90bb3ef285529b12299f7", - "token_estimator": "heuristic-v1" - }, - { - "id": "reference-tools-xcm-tools", - "title": "XCM Tools", - "slug": "reference-tools-xcm-tools", - "categories": [ - "Basics", - "Tooling", - "Dapps" - ], - "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/reference-tools-xcm-tools.md", - "html_url": "https://docs.polkadot.com/reference/tools/xcm-tools/", - "preview": "As described in the [Interoperability](/develop/interoperability){target=\\_blank} section, XCM (Cross-Consensus Messaging) is a protocol used in the Polkadot and Kusama ecosystems to enable communication and interaction between chains. It facilitates cross-chain communication, allowing assets, data, and messages to flow seamlessly across the ecosystem.", - "outline": [ - { - "depth": 2, - "title": "Introduction", - "anchor": "introduction" - }, - { - "depth": 2, - "title": "Popular XCM Tools", - "anchor": "popular-xcm-tools" - }, - { - "depth": 3, - "title": "Moonsong Labs XCM Tools", - "anchor": "moonsong-labs-xcm-tools" - }, - { - "depth": 3, - "title": "ParaSpell", - "anchor": "paraspell" - }, - { - "depth": 3, - "title": "Astar XCM Tools", - "anchor": "astar-xcm-tools" - }, - { - "depth": 3, - "title": "Chopsticks", - "anchor": "chopsticks" - }, - { - "depth": 3, - "title": "Moonbeam XCM SDK", - "anchor": "moonbeam-xcm-sdk" - } - ], - "stats": { - "chars": 6146, - "words": 852, - "headings": 7, - "estimated_token_count_total": 1377 - }, - "hash": "sha256:674e4f60c82fc7544c7af8e09f1e0f677c9907cdff88b107f6c8489e97a43487", - "token_estimator": "heuristic-v1" - }, - { - "id": "reference-tools-zombienet", - "title": "reference-tools-zombienet", - "slug": "reference-tools-zombienet", - "categories": [ - "Uncategorized" - ], - "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/reference-tools-zombienet.md", - "html_url": "https://docs.polkadot.com/reference/tools/zombienet/", - "preview": "TODO", - "outline": [], - "stats": { - "chars": 5, - "words": 1, - "headings": 0, - "estimated_token_count_total": 0 - }, - "hash": "sha256:56ba36249ea8216ad513b13df3de6c0e490ba214897674d30331f1c7e7edbef3", - "token_estimator": "heuristic-v1" - }, - { - "id": "reference", - "title": "Technical Reference Overview", - "slug": "reference", - "categories": [ - "Basics", - "Polkadot Protocol", - "Reference" - ], - "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/reference.md", - "html_url": "https://docs.polkadot.com/reference/", - "preview": "The Technical Reference section provides comprehensive documentation of Polkadot's architecture, core concepts, and development tooling. Whether you're exploring how Polkadot's relay chain coordinates parachains, understanding governance mechanisms, or building applications on the network, this reference covers the technical foundations you need.", - "outline": [ - { - "depth": 2, - "title": "Introduction", - "anchor": "introduction" - }, - { - "depth": 2, - "title": "Polkadot Hub", - "anchor": "polkadot-hub" - }, - { - "depth": 2, - "title": "Parachains", - "anchor": "parachains" - }, - { - "depth": 2, - "title": "On-Chain Governance", - "anchor": "on-chain-governance" - }, - { - "depth": 2, - "title": "Glossary", - "anchor": "glossary" - }, - { - "depth": 2, - "title": "Tools", - "anchor": "tools" - }, - { - "depth": 2, - "title": "Where to Go Next", - "anchor": "where-to-go-next" - } - ], - "stats": { - "chars": 7648, - "words": 937, - "headings": 7, - "estimated_token_count_total": 1682 - }, - "hash": "sha256:9f71f3b4018f7a9e127cff51fab7cfe1168adcde2553cd1fc5dc8c25fb97a30d", - "token_estimator": "heuristic-v1" - }, { "id": "smart-contracts-connect", "title": "Connect to Polkadot", @@ -7861,12 +4998,12 @@ } ], "stats": { - "chars": 13344, - "words": 1490, + "chars": 13435, + "words": 1499, "headings": 10, - "estimated_token_count_total": 3244 + "estimated_token_count_total": 3258 }, - "hash": "sha256:b63a0684cf554b7c248bd3b5327c6a80c60300d87944080d51467e086ade6fed", + "hash": "sha256:99916a667b468415b029bd745edfa23716e23dfc7cd313921a1bb0ea3378f644", "token_estimator": "heuristic-v1" }, { diff --git a/.nav.yml b/.nav.yml index 4f6f9672b..097dd07a7 100644 --- a/.nav.yml +++ b/.nav.yml @@ -5,4 +5,4 @@ nav: # - 'Chain Interactions': chain-interactions # 'Get Support': get-support - 'Node Infrastructure': node-infrastructure - - 'Technical Reference': reference + # - 'Technical Reference': reference diff --git a/.snippets/code/nodes-and-validators/run-a-node/bootnode/bootnode.conf b/.snippets/code/node-infrastructure/run-a-node/bootnode/bootnode.conf similarity index 100% rename from .snippets/code/nodes-and-validators/run-a-node/bootnode/bootnode.conf rename to .snippets/code/node-infrastructure/run-a-node/bootnode/bootnode.conf diff --git a/.snippets/code/nodes-and-validators/run-a-node/full-node/run-node.html b/.snippets/code/node-infrastructure/run-a-node/full-node/run-node.html similarity index 100% rename from .snippets/code/nodes-and-validators/run-a-node/full-node/run-node.html rename to .snippets/code/node-infrastructure/run-a-node/full-node/run-node.html diff --git a/.snippets/code/nodes-and-validators/run-a-node/full-node/setup-full-node-1.html b/.snippets/code/node-infrastructure/run-a-node/full-node/setup-full-node-1.html similarity index 100% rename from .snippets/code/nodes-and-validators/run-a-node/full-node/setup-full-node-1.html rename to .snippets/code/node-infrastructure/run-a-node/full-node/setup-full-node-1.html diff --git a/.snippets/code/nodes-and-validators/run-a-node/full-node/setup-full-node-2.html b/.snippets/code/node-infrastructure/run-a-node/full-node/setup-full-node-2.html similarity index 100% rename from .snippets/code/nodes-and-validators/run-a-node/full-node/setup-full-node-2.html rename to .snippets/code/node-infrastructure/run-a-node/full-node/setup-full-node-2.html diff --git a/.snippets/code/nodes-and-validators/run-a-node/secure-wss/apache2-config.md b/.snippets/code/node-infrastructure/run-a-node/secure-wss/apache2-config.md similarity index 100% rename from .snippets/code/nodes-and-validators/run-a-node/secure-wss/apache2-config.md rename to .snippets/code/node-infrastructure/run-a-node/secure-wss/apache2-config.md diff --git a/.snippets/code/nodes-and-validators/run-a-node/secure-wss/install-apache2.md b/.snippets/code/node-infrastructure/run-a-node/secure-wss/install-apache2.md similarity index 100% rename from .snippets/code/nodes-and-validators/run-a-node/secure-wss/install-apache2.md rename to .snippets/code/node-infrastructure/run-a-node/secure-wss/install-apache2.md diff --git a/.snippets/code/nodes-and-validators/run-a-node/secure-wss/install-openssl.md b/.snippets/code/node-infrastructure/run-a-node/secure-wss/install-openssl.md similarity index 100% rename from .snippets/code/nodes-and-validators/run-a-node/secure-wss/install-openssl.md rename to .snippets/code/node-infrastructure/run-a-node/secure-wss/install-openssl.md diff --git a/.snippets/code/nodes-and-validators/run-a-node/secure-wss/nginx-config.md b/.snippets/code/node-infrastructure/run-a-node/secure-wss/nginx-config.md similarity index 100% rename from .snippets/code/nodes-and-validators/run-a-node/secure-wss/nginx-config.md rename to .snippets/code/node-infrastructure/run-a-node/secure-wss/nginx-config.md diff --git a/.snippets/code/nodes-and-validators/run-a-node/secure-wss/nginx-rate-limit.md b/.snippets/code/node-infrastructure/run-a-node/secure-wss/nginx-rate-limit.md similarity index 100% rename from .snippets/code/nodes-and-validators/run-a-node/secure-wss/nginx-rate-limit.md rename to .snippets/code/node-infrastructure/run-a-node/secure-wss/nginx-rate-limit.md diff --git a/.snippets/code/nodes-and-validators/run-a-validator/onboarding-and-offboarding/key-management/node-key-error-01.html b/.snippets/code/node-infrastructure/run-a-validator/onboarding-and-offboarding/key-management/node-key-error-01.html similarity index 100% rename from .snippets/code/nodes-and-validators/run-a-validator/onboarding-and-offboarding/key-management/node-key-error-01.html rename to .snippets/code/node-infrastructure/run-a-validator/onboarding-and-offboarding/key-management/node-key-error-01.html diff --git a/.snippets/code/nodes-and-validators/run-a-validator/onboarding-and-offboarding/key-management/subkey-generate.html b/.snippets/code/node-infrastructure/run-a-validator/onboarding-and-offboarding/key-management/subkey-generate.html similarity index 100% rename from .snippets/code/nodes-and-validators/run-a-validator/onboarding-and-offboarding/key-management/subkey-generate.html rename to .snippets/code/node-infrastructure/run-a-validator/onboarding-and-offboarding/key-management/subkey-generate.html diff --git a/.snippets/code/nodes-and-validators/run-a-validator/onboarding-and-offboarding/set-up-validator/terminal-output-01.html b/.snippets/code/node-infrastructure/run-a-validator/onboarding-and-offboarding/set-up-validator/terminal-output-01.html similarity index 100% rename from .snippets/code/nodes-and-validators/run-a-validator/onboarding-and-offboarding/set-up-validator/terminal-output-01.html rename to .snippets/code/node-infrastructure/run-a-validator/onboarding-and-offboarding/set-up-validator/terminal-output-01.html diff --git a/.snippets/code/nodes-and-validators/run-a-validator/onboarding-and-offboarding/start-validating/terminal-output-01.html b/.snippets/code/node-infrastructure/run-a-validator/onboarding-and-offboarding/start-validating/terminal-output-01.html similarity index 100% rename from .snippets/code/nodes-and-validators/run-a-validator/onboarding-and-offboarding/start-validating/terminal-output-01.html rename to .snippets/code/node-infrastructure/run-a-validator/onboarding-and-offboarding/start-validating/terminal-output-01.html diff --git a/.snippets/code/nodes-and-validators/run-a-validator/onboarding-and-offboarding/start-validating/terminal-output-02.html b/.snippets/code/node-infrastructure/run-a-validator/onboarding-and-offboarding/start-validating/terminal-output-02.html similarity index 100% rename from .snippets/code/nodes-and-validators/run-a-validator/onboarding-and-offboarding/start-validating/terminal-output-02.html rename to .snippets/code/node-infrastructure/run-a-validator/onboarding-and-offboarding/start-validating/terminal-output-02.html diff --git a/.snippets/code/nodes-and-validators/run-a-validator/operational-tasks/general-management/alertmanager-status.html b/.snippets/code/node-infrastructure/run-a-validator/operational-tasks/general-management/alertmanager-status.html similarity index 100% rename from .snippets/code/nodes-and-validators/run-a-validator/operational-tasks/general-management/alertmanager-status.html rename to .snippets/code/node-infrastructure/run-a-validator/operational-tasks/general-management/alertmanager-status.html diff --git a/.snippets/code/nodes-and-validators/run-a-validator/operational-tasks/general-management/alertmanager.yml b/.snippets/code/node-infrastructure/run-a-validator/operational-tasks/general-management/alertmanager.yml similarity index 100% rename from .snippets/code/nodes-and-validators/run-a-validator/operational-tasks/general-management/alertmanager.yml rename to .snippets/code/node-infrastructure/run-a-validator/operational-tasks/general-management/alertmanager.yml diff --git a/.snippets/code/nodes-and-validators/run-a-validator/operational-tasks/general-management/grub-config-01.js b/.snippets/code/node-infrastructure/run-a-validator/operational-tasks/general-management/grub-config-01.js similarity index 100% rename from .snippets/code/nodes-and-validators/run-a-validator/operational-tasks/general-management/grub-config-01.js rename to .snippets/code/node-infrastructure/run-a-validator/operational-tasks/general-management/grub-config-01.js diff --git a/.snippets/code/nodes-and-validators/run-a-validator/operational-tasks/general-management/instance-down.yml b/.snippets/code/node-infrastructure/run-a-validator/operational-tasks/general-management/instance-down.yml similarity index 100% rename from .snippets/code/nodes-and-validators/run-a-validator/operational-tasks/general-management/instance-down.yml rename to .snippets/code/node-infrastructure/run-a-validator/operational-tasks/general-management/instance-down.yml diff --git a/.snippets/code/nodes-and-validators/run-a-validator/operational-tasks/general-management/prometheus-config.yml b/.snippets/code/node-infrastructure/run-a-validator/operational-tasks/general-management/prometheus-config.yml similarity index 100% rename from .snippets/code/nodes-and-validators/run-a-validator/operational-tasks/general-management/prometheus-config.yml rename to .snippets/code/node-infrastructure/run-a-validator/operational-tasks/general-management/prometheus-config.yml diff --git a/.snippets/code/nodes-and-validators/run-a-validator/operational-tasks/general-management/systemd-alert-config.md b/.snippets/code/node-infrastructure/run-a-validator/operational-tasks/general-management/systemd-alert-config.md similarity index 100% rename from .snippets/code/nodes-and-validators/run-a-validator/operational-tasks/general-management/systemd-alert-config.md rename to .snippets/code/node-infrastructure/run-a-validator/operational-tasks/general-management/systemd-alert-config.md diff --git a/.snippets/code/nodes-and-validators/run-a-validator/operational-tasks/general-management/systemd-config.md b/.snippets/code/node-infrastructure/run-a-validator/operational-tasks/general-management/systemd-config.md similarity index 100% rename from .snippets/code/nodes-and-validators/run-a-validator/operational-tasks/general-management/systemd-config.md rename to .snippets/code/node-infrastructure/run-a-validator/operational-tasks/general-management/systemd-config.md diff --git a/.snippets/code/nodes-and-validators/run-a-validator/operational-tasks/general-management/terminal-output-01.html b/.snippets/code/node-infrastructure/run-a-validator/operational-tasks/general-management/terminal-output-01.html similarity index 100% rename from .snippets/code/nodes-and-validators/run-a-validator/operational-tasks/general-management/terminal-output-01.html rename to .snippets/code/node-infrastructure/run-a-validator/operational-tasks/general-management/terminal-output-01.html diff --git a/.snippets/code/nodes-and-validators/run-a-validator/operational-tasks/general-management/update-prometheus.yml b/.snippets/code/node-infrastructure/run-a-validator/operational-tasks/general-management/update-prometheus.yml similarity index 100% rename from .snippets/code/nodes-and-validators/run-a-validator/operational-tasks/general-management/update-prometheus.yml rename to .snippets/code/node-infrastructure/run-a-validator/operational-tasks/general-management/update-prometheus.yml diff --git a/.snippets/code/nodes-and-validators/run-a-validator/operational-tasks/upgrade-your-node/verify-session-change.md b/.snippets/code/node-infrastructure/run-a-validator/operational-tasks/upgrade-your-node/verify-session-change.md similarity index 100% rename from .snippets/code/nodes-and-validators/run-a-validator/operational-tasks/upgrade-your-node/verify-session-change.md rename to .snippets/code/node-infrastructure/run-a-validator/operational-tasks/upgrade-your-node/verify-session-change.md diff --git a/.snippets/code/smart-contracts/libraries/wagmi/BlockchainInfo.tsx b/.snippets/code/smart-contracts/libraries/wagmi/BlockchainInfo.tsx index 8c8a5775b..4fba8d92c 100644 --- a/.snippets/code/smart-contracts/libraries/wagmi/BlockchainInfo.tsx +++ b/.snippets/code/smart-contracts/libraries/wagmi/BlockchainInfo.tsx @@ -1,9 +1,9 @@ "use client"; -import { useBlockNumber, useBalance, useAccount } from "wagmi"; +import { useBlockNumber, useBalance, useConnection } from "wagmi"; export function BlockchainInfo() { - const { address } = useAccount(); + const { address } = useConnection(); // Get the latest block number const { data: blockNumber } = useBlockNumber({ watch: true }); diff --git a/.snippets/code/smart-contracts/libraries/wagmi/ConnectWallet.tsx b/.snippets/code/smart-contracts/libraries/wagmi/ConnectWallet.tsx index 167476452..9e0b2bcea 100644 --- a/.snippets/code/smart-contracts/libraries/wagmi/ConnectWallet.tsx +++ b/.snippets/code/smart-contracts/libraries/wagmi/ConnectWallet.tsx @@ -1,12 +1,12 @@ "use client"; import React from "react"; -import { useConnect, useAccount, useDisconnect } from "wagmi"; +import { useConnect, useConnection, useDisconnect } from "wagmi"; import { injected } from "wagmi/connectors"; export function ConnectWallet() { const { connect } = useConnect(); - const { address, isConnected } = useAccount(); + const { address, isConnected } = useConnection(); const { disconnect } = useDisconnect(); if (isConnected) { diff --git a/.snippets/code/smart-contracts/libraries/wagmi/page.tsx b/.snippets/code/smart-contracts/libraries/wagmi/page.tsx index 6adeeeac8..908837b32 100644 --- a/.snippets/code/smart-contracts/libraries/wagmi/page.tsx +++ b/.snippets/code/smart-contracts/libraries/wagmi/page.tsx @@ -3,10 +3,10 @@ import { BlockchainInfo } from "./components/BlockchainInfo"; import { ConnectWallet } from "./components/ConnectWallet"; import { StorageContract } from "./components/StorageContract"; -import { useAccount } from "wagmi"; +import { useConnection } from "wagmi"; export default function Home() { - const { isConnected } = useAccount(); + const { isConnected } = useConnection(); return (
diff --git a/images/nodes-and-validators/run-a-node/secure-wss/secure-wss-01.webp b/images/node-infrastructure/run-a-node/secure-wss/secure-wss-01.webp similarity index 100% rename from images/nodes-and-validators/run-a-node/secure-wss/secure-wss-01.webp rename to images/node-infrastructure/run-a-node/secure-wss/secure-wss-01.webp diff --git a/images/nodes-and-validators/run-a-validator/onboarding-and-offboarding/key-management/key-management-01.webp b/images/node-infrastructure/run-a-validator/onboarding-and-offboarding/key-management/key-management-01.webp similarity index 100% rename from images/nodes-and-validators/run-a-validator/onboarding-and-offboarding/key-management/key-management-01.webp rename to images/node-infrastructure/run-a-validator/onboarding-and-offboarding/key-management/key-management-01.webp diff --git a/images/nodes-and-validators/run-a-validator/onboarding-and-offboarding/key-management/key-management-02.webp b/images/node-infrastructure/run-a-validator/onboarding-and-offboarding/key-management/key-management-02.webp similarity index 100% rename from images/nodes-and-validators/run-a-validator/onboarding-and-offboarding/key-management/key-management-02.webp rename to images/node-infrastructure/run-a-validator/onboarding-and-offboarding/key-management/key-management-02.webp diff --git a/images/nodes-and-validators/run-a-validator/onboarding-and-offboarding/start-validating/start-validating-01.webp b/images/node-infrastructure/run-a-validator/onboarding-and-offboarding/start-validating/start-validating-01.webp similarity index 100% rename from images/nodes-and-validators/run-a-validator/onboarding-and-offboarding/start-validating/start-validating-01.webp rename to images/node-infrastructure/run-a-validator/onboarding-and-offboarding/start-validating/start-validating-01.webp diff --git a/images/nodes-and-validators/run-a-validator/onboarding-and-offboarding/start-validating/start-validating-02.webp b/images/node-infrastructure/run-a-validator/onboarding-and-offboarding/start-validating/start-validating-02.webp similarity index 100% rename from images/nodes-and-validators/run-a-validator/onboarding-and-offboarding/start-validating/start-validating-02.webp rename to images/node-infrastructure/run-a-validator/onboarding-and-offboarding/start-validating/start-validating-02.webp diff --git a/images/nodes-and-validators/run-a-validator/onboarding-and-offboarding/start-validating/start-validating-03.webp b/images/node-infrastructure/run-a-validator/onboarding-and-offboarding/start-validating/start-validating-03.webp similarity index 100% rename from images/nodes-and-validators/run-a-validator/onboarding-and-offboarding/start-validating/start-validating-03.webp rename to images/node-infrastructure/run-a-validator/onboarding-and-offboarding/start-validating/start-validating-03.webp diff --git a/images/nodes-and-validators/run-a-validator/onboarding-and-offboarding/start-validating/start-validating-04.webp b/images/node-infrastructure/run-a-validator/onboarding-and-offboarding/start-validating/start-validating-04.webp similarity index 100% rename from images/nodes-and-validators/run-a-validator/onboarding-and-offboarding/start-validating/start-validating-04.webp rename to images/node-infrastructure/run-a-validator/onboarding-and-offboarding/start-validating/start-validating-04.webp diff --git a/images/nodes-and-validators/run-a-validator/onboarding-and-offboarding/start-validating/start-validating-05.webp b/images/node-infrastructure/run-a-validator/onboarding-and-offboarding/start-validating/start-validating-05.webp similarity index 100% rename from images/nodes-and-validators/run-a-validator/onboarding-and-offboarding/start-validating/start-validating-05.webp rename to images/node-infrastructure/run-a-validator/onboarding-and-offboarding/start-validating/start-validating-05.webp diff --git a/images/nodes-and-validators/run-a-validator/onboarding-and-offboarding/start-validating/start-validating-06.webp b/images/node-infrastructure/run-a-validator/onboarding-and-offboarding/start-validating/start-validating-06.webp similarity index 100% rename from images/nodes-and-validators/run-a-validator/onboarding-and-offboarding/start-validating/start-validating-06.webp rename to images/node-infrastructure/run-a-validator/onboarding-and-offboarding/start-validating/start-validating-06.webp diff --git a/images/nodes-and-validators/run-a-validator/operational-tasks/general-management/general-management-01.webp b/images/node-infrastructure/run-a-validator/operational-tasks/general-management/general-management-01.webp similarity index 100% rename from images/nodes-and-validators/run-a-validator/operational-tasks/general-management/general-management-01.webp rename to images/node-infrastructure/run-a-validator/operational-tasks/general-management/general-management-01.webp diff --git a/images/nodes-and-validators/run-a-validator/operational-tasks/general-management/general-management-02.webp b/images/node-infrastructure/run-a-validator/operational-tasks/general-management/general-management-02.webp similarity index 100% rename from images/nodes-and-validators/run-a-validator/operational-tasks/general-management/general-management-02.webp rename to images/node-infrastructure/run-a-validator/operational-tasks/general-management/general-management-02.webp diff --git a/images/nodes-and-validators/run-a-validator/operational-tasks/general-management/general-management-03.webp b/images/node-infrastructure/run-a-validator/operational-tasks/general-management/general-management-03.webp similarity index 100% rename from images/nodes-and-validators/run-a-validator/operational-tasks/general-management/general-management-03.webp rename to images/node-infrastructure/run-a-validator/operational-tasks/general-management/general-management-03.webp diff --git a/images/nodes-and-validators/run-a-validator/operational-tasks/general-management/general-management-04.webp b/images/node-infrastructure/run-a-validator/operational-tasks/general-management/general-management-04.webp similarity index 100% rename from images/nodes-and-validators/run-a-validator/operational-tasks/general-management/general-management-04.webp rename to images/node-infrastructure/run-a-validator/operational-tasks/general-management/general-management-04.webp diff --git a/images/nodes-and-validators/run-a-validator/operational-tasks/general-management/general-management-05.webp b/images/node-infrastructure/run-a-validator/operational-tasks/general-management/general-management-05.webp similarity index 100% rename from images/nodes-and-validators/run-a-validator/operational-tasks/general-management/general-management-05.webp rename to images/node-infrastructure/run-a-validator/operational-tasks/general-management/general-management-05.webp diff --git a/llms-full.jsonl b/llms-full.jsonl index 9346a8944..e9d35edf9 100644 --- a/llms-full.jsonl +++ b/llms-full.jsonl @@ -17,120 +17,120 @@ {"page_id": "get-support", "page_title": "Support", "index": 0, "depth": 2, "title": "Need More than Just Documentation?", "anchor": "need-more-than-just-documentation", "start_char": 456, "end_char": 796, "estimated_token_count": 76, "token_estimator": "heuristic-v1", "text": "## Need More than Just Documentation?\n\nYou're already in the docs — solid start. \nBut sometimes you need more: answers, real examples, someone to talk to. \nThis support hub is here to help you move forward — faster.\n\nWhether you're building something new, integrating into the ecosystem, or running into blockers — **don't stay stuck**."} {"page_id": "get-support", "page_title": "Support", "index": 1, "depth": 2, "title": "What You Can Do Here", "anchor": "what-you-can-do-here", "start_char": 796, "end_char": 1419, "estimated_token_count": 139, "token_estimator": "heuristic-v1", "text": "## What You Can Do Here\n\n- 📨 [**Get In Touch**](/get-support/get-in-touch/) \n Reach out to the Polkadot support team and community via Telegram, Matrix, or Discord. \n Ask technical questions, report blockers, or share feedback — and get a human response.\n\n- 🧠 [**Explore Available Resources**](/get-support/explore-resources/) \n Find answers beyond the documentation: developer forums, Stack Exchange, Reddit, YouTube, governance hubs, and more.\n\nThis hub is evolving. More support tools and shortcuts are on the way, including enhanced onboarding, CLI helpers, development environments, and live feedback channels."} {"page_id": "get-support", "page_title": "Support", "index": 2, "depth": 2, "title": "Help Us Improve", "anchor": "help-us-improve", "start_char": 1419, "end_char": 1658, "estimated_token_count": 65, "token_estimator": "heuristic-v1", "text": "## Help Us Improve\n\nIf something’s missing, unclear, or broken — **tell us**. \nYour feedback makes the whole ecosystem better for everyone.\n\n👉 [**Get In Touch**](/get-support/get-in-touch/) and help shape the future of developer support."} -{"page_id": "nodes-and-validators-run-a-node-bootnode", "page_title": "Set Up a Bootnode", "index": 0, "depth": 2, "title": "Introduction", "anchor": "introduction", "start_char": 21, "end_char": 613, "estimated_token_count": 113, "token_estimator": "heuristic-v1", "text": "## Introduction\n\nBootnodes are essential for helping blockchain nodes discover peers and join the network. When a node starts, it needs to find other nodes, and bootnodes provide an initial point of contact. Once connected, a node can expand its peer connections and play its role in the network, like participating as a validator.\n\nThis guide will walk you through setting up a Polkadot bootnode, configuring P2P, WebSocket (WS), secure WSS connections, and managing network keys. You'll also learn how to test your bootnode to ensure it is running correctly and accessible to other nodes."} -{"page_id": "nodes-and-validators-run-a-node-bootnode", "page_title": "Set Up a Bootnode", "index": 1, "depth": 2, "title": "Prerequisites", "anchor": "prerequisites", "start_char": 613, "end_char": 986, "estimated_token_count": 86, "token_estimator": "heuristic-v1", "text": "## Prerequisites\n\nBefore you start, you need to have the following prerequisites:\n\n- Verify a working Polkadot (`polkadot`) binary is available on your machine.\n- Ensure you have nginx installed. Please refer to the [Installation Guide](https://nginx.org/en/docs/install.html){target=\\_blank} for help with installation if needed.\n- A VPS or other dedicated server setup."} -{"page_id": "nodes-and-validators-run-a-node-bootnode", "page_title": "Set Up a Bootnode", "index": 2, "depth": 2, "title": "Accessing the Bootnode", "anchor": "accessing-the-bootnode", "start_char": 986, "end_char": 1573, "estimated_token_count": 149, "token_estimator": "heuristic-v1", "text": "## Accessing the Bootnode\n\nBootnodes must be accessible through three key channels to connect with other nodes in the network:\n\n- **P2P**: A direct peer-to-peer connection, set by.\n\n ```bash\n\n --listen-addr /ip4/0.0.0.0/tcp/INSERT_PORT\n\n ```\n \n This is not enabled by default on non-validator nodes like archive RPC nodes.\n\n- **P2P/WS**: A WebSocket (WS) connection, also configured via `--listen-addr`.\n- **P2P/WSS**: A secure WebSocket (WSS) connection using SSL, often required for light clients. An SSL proxy is needed, as the node itself cannot handle certificates."} -{"page_id": "nodes-and-validators-run-a-node-bootnode", "page_title": "Set Up a Bootnode", "index": 3, "depth": 2, "title": "Node Key", "anchor": "node-key", "start_char": 1573, "end_char": 2240, "estimated_token_count": 148, "token_estimator": "heuristic-v1", "text": "## Node Key\n\nA node key is the ED25519 key used by `libp2p` to assign your node an identity or peer ID. Generating a known node key for a bootnode is crucial, as it gives you a consistent key that can be placed in chain specifications as a known, reliable bootnode.\n\nStarting a node creates its node key in the `chains/INSERT_CHAIN/network/secret_ed25519` file.\n\nYou can create a node key using:\n\n ``` bash\n polkadot key generate-node-key\n ``` \n \nThis key can be used in the startup command line.\n\nIt is imperative that you backup the node key. If it is included in the `polkadot` binary, it is hardcoded into the binary, which must be recompiled to change the key."} -{"page_id": "nodes-and-validators-run-a-node-bootnode", "page_title": "Set Up a Bootnode", "index": 4, "depth": 2, "title": "Running the Bootnode", "anchor": "running-the-bootnode", "start_char": 2240, "end_char": 3333, "estimated_token_count": 240, "token_estimator": "heuristic-v1", "text": "## Running the Bootnode\n\nA bootnode can be run as follows:\n\n ``` bash\n polkadot --chain polkadot \\\n --name dot-bootnode \\\n --listen-addr /ip4/0.0.0.0/tcp/30310 \\\n --listen-addr /ip4/0.0.0.0/tcp/30311/ws\n ```\n\nThis assigns the p2p to port 30310 and p2p/ws to port 30311. For the p2p/wss port, a proxy must be set up with a DNS name and a corresponding certificate. The following example is for the popular nginx server and enables p2p/wss on port 30312 by adding a proxy to the p2p/ws port 30311:\n\n``` conf title=\"/etc/nginx/sites-enabled/dot-bootnode\"\nserver {\n listen 30312 ssl http2 default_server;\n server_name dot-bootnode.stakeworld.io;\n root /var/www/html;\n\n ssl_certificate \"INSERT_YOUR_CERT\";\n ssl_certificate_key \"INSERT_YOUR_KEY\";\n\n location / {\n proxy_buffers 16 4k;\n proxy_buffer_size 2k;\n proxy_pass http://localhost:30311;\n proxy_http_version 1.1;\n proxy_set_header Upgrade $http_upgrade;\n proxy_set_header Connection \"Upgrade\";\n proxy_set_header Host $host;\n }\n\n}\n```"} -{"page_id": "nodes-and-validators-run-a-node-bootnode", "page_title": "Set Up a Bootnode", "index": 5, "depth": 2, "title": "Testing Bootnode Connection", "anchor": "testing-bootnode-connection", "start_char": 3333, "end_char": 3727, "estimated_token_count": 78, "token_estimator": "heuristic-v1", "text": "## Testing Bootnode Connection\n\nIf the preceding node is running with DNS name `dot-bootnode.stakeworld.io`, which contains a proxy with a valid certificate and node-id `12D3KooWAb5MyC1UJiEQJk4Hg4B2Vi3AJdqSUhTGYUqSnEqCFMFg` then the following commands should output `syncing 1 peers`.\n\n!!!tip\n You can add `-lsub-libp2p=trace` on the end to get libp2p trace logging for debugging purposes."} -{"page_id": "nodes-and-validators-run-a-node-bootnode", "page_title": "Set Up a Bootnode", "index": 6, "depth": 3, "title": "P2P", "anchor": "p2p", "start_char": 3727, "end_char": 3993, "estimated_token_count": 74, "token_estimator": "heuristic-v1", "text": "### P2P\n\n```bash\npolkadot --chain polkadot \\\n--base-path /tmp/node \\\n--name \"Bootnode testnode\" \\\n--reserved-only \\\n--reserved-nodes \"/dns/dot-bootnode.stakeworld.io/tcp/30310/p2p/12D3KooWAb5MyC1UJiEQJk4Hg4B2Vi3AJdqSUhTGYUqSnEqCFMFg\" \\\n--no-hardware-benchmarks\n```"} -{"page_id": "nodes-and-validators-run-a-node-bootnode", "page_title": "Set Up a Bootnode", "index": 7, "depth": 3, "title": "P2P/WS", "anchor": "p2pws", "start_char": 3993, "end_char": 4265, "estimated_token_count": 78, "token_estimator": "heuristic-v1", "text": "### P2P/WS\n\n```bash\npolkadot --chain polkadot \\\n--base-path /tmp/node \\\n--name \"Bootnode testnode\" \\\n--reserved-only \\\n--reserved-nodes \"/dns/dot-bootnode.stakeworld.io/tcp/30311/ws/p2p/12D3KooWAb5MyC1UJiEQJk4Hg4B2Vi3AJdqSUhTGYUqSnEqCFMFg\" \\\n--no-hardware-benchmarks\n```"} -{"page_id": "nodes-and-validators-run-a-node-bootnode", "page_title": "Set Up a Bootnode", "index": 8, "depth": 3, "title": "P2P/WSS", "anchor": "p2pwss", "start_char": 4265, "end_char": 4538, "estimated_token_count": 78, "token_estimator": "heuristic-v1", "text": "### P2P/WSS\n\n```bash\npolkadot --chain polkadot \\\n--base-path /tmp/node \\\n--name \"Bootnode testnode\" \\\n--reserved-only \\\n--reserved-nodes \"/dns/dot-bootnode.stakeworld.io/tcp/30312/wss/p2p/12D3KooWAb5MyC1UJiEQJk4Hg4B2Vi3AJdqSUhTGYUqSnEqCFMFg\" \\\n--no-hardware-benchmarks\n```"} -{"page_id": "nodes-and-validators-run-a-node-full-node", "page_title": "Set Up a Node", "index": 0, "depth": 2, "title": "Introduction", "anchor": "introduction", "start_char": 17, "end_char": 945, "estimated_token_count": 165, "token_estimator": "heuristic-v1", "text": "## Introduction\n\nRunning a node on Polkadot provides direct interaction with the network, enhanced privacy, and full control over RPC requests, transactions, and data queries. As the backbone of the network, nodes ensure decentralized data propagation, transaction validation, and seamless communication across the ecosystem.\n\nPolkadot supports multiple node types, including pruned, archive, and light nodes, each suited to specific use cases. During setup, you can use configuration flags to choose the node type you wish to run.\n\nThis guide walks you through configuring, securing, and maintaining a node on Polkadot or any Polkadot SDK-based chain. It covers instructions for the different node types and how to safely expose your node's RPC server for external access. Whether you're building a local development environment, powering dApps, or supporting network decentralization, this guide provides all the essentials."} -{"page_id": "nodes-and-validators-run-a-node-full-node", "page_title": "Set Up a Node", "index": 1, "depth": 2, "title": "Set Up a Node", "anchor": "set-up-a-node", "start_char": 945, "end_char": 1150, "estimated_token_count": 43, "token_estimator": "heuristic-v1", "text": "## Set Up a Node\n\nNow that you're familiar with the different types of nodes, this section will walk you through configuring, securing, and maintaining a node on Polkadot or any Polkadot SDK-based chain."} -{"page_id": "nodes-and-validators-run-a-node-full-node", "page_title": "Set Up a Node", "index": 2, "depth": 3, "title": "Prerequisites", "anchor": "prerequisites", "start_char": 1150, "end_char": 1721, "estimated_token_count": 144, "token_estimator": "heuristic-v1", "text": "### Prerequisites\n\nBefore getting started, ensure the following prerequisites are met:\n\n- Ensure [Rust](https://rust-lang.org/tools/install/){target=\\_blank} is installed on your operating system.\n- [Install the necessary dependencies for the Polkadot SDK](/parachains/install-polkadot-sdk/){target=\\_blank}.\n\n!!! warning\n This setup is not recommended for validators. If you plan to run a validator, refer to the [Running a Validator](/nodes-and-validators/run-a-validator/onboarding-and-offboarding/set-up-validator/){target=\\_blank} guide for proper instructions."} -{"page_id": "nodes-and-validators-run-a-node-full-node", "page_title": "Set Up a Node", "index": 3, "depth": 3, "title": "Install and Build the Polkadot Binary", "anchor": "install-and-build-the-polkadot-binary", "start_char": 1721, "end_char": 8205, "estimated_token_count": 1560, "token_estimator": "heuristic-v1", "text": "### Install and Build the Polkadot Binary\n\nThis section will walk you through installing and building the Polkadot binary for different operating systems and methods.\n\n??? interface \"macOS\"\n\n To get started, update and configure the Rust toolchain by running the following commands:\n\n ```bash\n source ~/.cargo/env\n\n rustup default stable\n rustup update\n\n rustup update nightly\n rustup target add wasm32-unknown-unknown --toolchain nightly\n rustup component add rust-src --toolchain stable-aarch64-apple-darwin\n ```\n\n You can verify your installation by running:\n\n ```bash\n rustup show\n rustup +nightly show\n ```\n\n You should see output similar to the following:\n\n
\n rustup show
\n rustup +nightly show\n active toolchain\n ----------------\n \n stable-aarch64-apple-darwin (default)\n rustc 1.82.0 (f6e511eec 2024-10-15)\n \n active toolchain\n ----------------\n \n nightly-aarch64-apple-darwin (overridden by +toolchain on the command line) \n rustc 1.84.0-nightly (03ee48451 2024-11-18)\n \n
\n\n Then, run the following commands to clone and build the Polkadot binary:\n \n ```bash\n git clone https://github.com/paritytech/polkadot-sdk polkadot-sdk\n cd polkadot-sdk\n cargo build --release\n ```\n\n Depending upon the specs of your machine, compiling the binary may take an hour or more. After building the Polkadot node from source, the executable binary will be located in the `./target/release/polkadot` directory.\n\n??? interface \"Windows\"\n\n To get started, make sure that you have [WSL and Ubuntu](https://learn.microsoft.com/en-us/windows/wsl/install){target=\\_blank} installed on your Windows machine.\n\n Once installed, you have a couple options for installing the Polkadot binary:\n\n - If Rust is installed, then `cargo` can be used similar to the macOS instructions.\n - Or, the instructions in the Linux section can be used.\n\n??? interface \"Linux (pre-built binary)\"\n\n To grab the [latest release of the Polkadot binary](https://github.com/paritytech/polkadot-sdk/releases){target=\\_blank}, you can use `wget`:\n\n ```bash\n wget https://github.com/paritytech/polkadot-sdk/releases/download/polkadot-INSERT_VERSION/polkadot\n ```\n \n Ensure you note the executable binary's location, as you'll need to use it when running the start-up command. If you prefer, you can specify the output location of the executable binary with the `-O` flag, for example:\n\n ```bash\n wget https://github.com/paritytech/polkadot-sdk/releases/download/polkadot-INSERT_VERSION/polkadot \\\n - O /var/lib/polkadot-data/polkadot\n ```\n\n !!!tip\n The nature of pre-built binaries means that they may not work on your particular architecture or Linux distribution. If you see an error like `cannot execute binary file: Exec format error` it likely means the binary is incompatible with your system. You will either need to compile the binary or use [Docker](#use-docker).\n\n Ensure that you properly configure the permissions to make the Polkadot release binary executable:\n\n ```bash\n sudo chmod +x polkadot\n ```\n\n??? interface \"Linux (compile binary)\"\n\n The most reliable (although perhaps not the fastest) way of launching a full node is to compile the binary yourself. Depending on your machine's specs, this may take an hour or more.\n\n To get started, run the following commands to configure the Rust toolchain:\n\n ```bash\n rustup default stable\n rustup update\n rustup update nightly\n rustup target add wasm32-unknown-unknown --toolchain nightly\n rustup target add wasm32-unknown-unknown --toolchain stable-x86_64-unknown-linux-gnu\n rustup component add rust-src --toolchain stable-x86_64-unknown-linux-gnu\n ```\n\n You can verify your installation by running:\n\n ```bash\n rustup show\n ```\n\n You should see output similar to the following:\n\n
\n rustup show
\n rustup +nightly show\n active toolchain\n ----------------\n \n stable-x86_64-unknown-linux-gnu (default)\n rustc 1.82.0 (f6e511eec 2024-10-15)\n
\n\n Once Rust is configured, run the following commands to clone and build Polkadot:\n \n ```bash\n git clone https://github.com/paritytech/polkadot-sdk polkadot-sdk\n cd polkadot-sdk\n cargo build --release\n ```\n\n Compiling the binary may take an hour or more, depending on your machine's specs. After building the Polkadot node from the source, the executable binary will be located in the `./target/release/polkadot` directory.\n\n??? interface \"Linux (snap package)\"\n\n Polkadot can be installed as a [snap package](https://snapcraft.io/polkadot){target=\\_blank}. If you don't already have Snap installed, take the following steps to install it:\n\n ```bash\n sudo apt update\n sudo apt install snapd\n ```\n\n Install the Polkadot snap package:\n\n ```bash\n sudo snap install polkadot\n ```\n \n Before continuing on with the following instructions, check out the [Configure and Run Your Node](#configure-and-run-your-node) section to learn more about the configuration options.\n\n To configure your Polkadot node with your desired options, you'll run a command similar to the following:\n\n ```bash\n sudo snap set polkadot service-args=\"--name=MyName --chain=polkadot\"\n ```\n\n Then to start the node service, run:\n\n ```bash\n sudo snap start polkadot\n ```\n\n You can review the logs to check on the status of the node: \n\n ```bash\n snap logs polkadot -f\n ```\n\n And at any time, you can stop the node service:\n\n ```bash\n sudo snap stop polkadot\n ```\n\n You can optionally prevent the service from stopping when snap is updated with the following command:\n\n ```bash\n sudo snap set polkadot endure=true\n ```"} -{"page_id": "nodes-and-validators-run-a-node-full-node", "page_title": "Set Up a Node", "index": 4, "depth": 3, "title": "Use Docker", "anchor": "use-docker", "start_char": 8205, "end_char": 9272, "estimated_token_count": 293, "token_estimator": "heuristic-v1", "text": "### Use Docker\n\nAs an additional option, you can use Docker to run your node in a container. Doing this is more advanced, so it's best left up to those already familiar with Docker or who have completed the other set-up instructions in this guide. You can review the latest versions on [DockerHub](https://hub.docker.com/r/parity/polkadot/tags){target=\\_blank}.\n\nBe aware that when you run Polkadot in Docker, the process only listens on `localhost` by default. If you would like to connect to your node's services (RPC and Prometheus) you need to ensure that you run the node with the `--rpc-external`, and `--prometheus-external` commands.\n\n```bash\ndocker run -p 9944:9944 -p 9615:9615 parity/polkadot:v1.16.2 --name \"my-polkadot-node-calling-home\" --rpc-external --prometheus-external\n```\n\nIf you're running Docker on an Apple Silicon machine (e.g. M4), you'll need to adapt the command slightly:\n\n```bash\ndocker run --platform linux/amd64 -p 9944:9944 -p 9615:9615 parity/polkadot:v1.16.2 --name \"kearsarge-calling-home\" --rpc-external --prometheus-external\n```"} -{"page_id": "nodes-and-validators-run-a-node-full-node", "page_title": "Set Up a Node", "index": 5, "depth": 2, "title": "Configure and Run Your Node", "anchor": "configure-and-run-your-node", "start_char": 9272, "end_char": 11064, "estimated_token_count": 418, "token_estimator": "heuristic-v1", "text": "## Configure and Run Your Node\n\nNow that you've installed and built the Polkadot binary, the next step is to configure the start-up command depending on the type of node that you want to run. You'll need to modify the start-up command accordingly based on the location of the binary. In some cases, it may be located within the `./target/release/` folder, so you'll need to replace polkadot with `./target/release/polkadot` in the following commands.\n\nAlso, note that you can use the same binary for Polkadot as you would for Kusama or any other relay chain. You'll need to use the `--chain` flag to differentiate between chains.\n\nThe base commands for running a Polkadot node are as follows:\n\n=== \"Default pruned node\"\n\n This uses the default pruning value of the last 256 blocks:\n\n ```bash\n polkadot --chain polkadot \\\n --name \"INSERT_NODE_NAME\"\n ```\n\n=== \"Custom pruned node\"\n\n You can customize the pruning value, for example, to the last 1000 finalized blocks:\n\n ```bash\n polkadot --chain polkadot \\\n --name INSERT_YOUR_NODE_NAME \\\n --state-pruning 1000 \\\n --blocks-pruning archive \\\n --rpc-cors all \\\n --rpc-methods safe\n ```\n\n=== \"Archive node\"\n\n To support the full state, use the `archive` option:\n\n ```bash\n polkadot --chain polkadot \\\n --name INSERT_YOUR_NODE_NAME \\\n --state-pruning archive \\\n --blocks-pruning archive \\\n ```\n\nIf you want to run an RPC node, please refer to the following [RPC Configurations](#rpc-configurations) section.\n\nTo review a complete list of the available commands, flags, and options, you can use the `--help` flag:\n\n```bash\npolkadot --help\n```\n\nOnce you've fully configured your start-up command, you can execute it in your terminal and your node will start [syncing](#sync-your-node)."} -{"page_id": "nodes-and-validators-run-a-node-full-node", "page_title": "Set Up a Node", "index": 6, "depth": 3, "title": "RPC Configurations", "anchor": "rpc-configurations", "start_char": 11064, "end_char": 11923, "estimated_token_count": 221, "token_estimator": "heuristic-v1", "text": "### RPC Configurations\n\nThe node startup settings allow you to choose what to expose, how many connections to expose, and which systems should be granted access through the RPC server.\n\n- You can limit the methods to use with `--rpc-methods`; an easy way to set this to a safe mode is `--rpc-methods safe`.\n- You can set your maximum connections through `--rpc-max-connections`, for example, `--rpc-max-connections 200`.\n- By default, localhost and Polkadot.js can access the RPC server. You can change this by setting `--rpc-cors`. To allow access from everywhere, you can use `--rpc-cors all`.\n\nFor a list of important flags when running RPC nodes, refer to the Parity DevOps documentation: [Important Flags for Running an RPC Node](https://paritytech.github.io/devops-guide/guides/rpc_index.html?#important-flags-for-running-an-rpc-node){target=\\_blank}."} -{"page_id": "nodes-and-validators-run-a-node-full-node", "page_title": "Set Up a Node", "index": 7, "depth": 2, "title": "Sync Your Node", "anchor": "sync-your-node", "start_char": 11923, "end_char": 15591, "estimated_token_count": 1235, "token_estimator": "heuristic-v1", "text": "## Sync Your Node\n\nThe syncing process will take a while, depending on your capacity, processing power, disk speed, and RAM. The process may be completed on a $10 DigitalOcean droplet in about ~36 hours. While syncing, your node name should be visible in gray on Polkadot Telemetry, and once it is fully synced, your node name will appear in white on [Polkadot Telemetry](https://telemetry.polkadot.io/#list/Polkadot){target=_blank}.\n\nA healthy node syncing blocks will output logs like the following:\n\n
\n 2024-11-19 23:49:57 Parity Polkadot\n 2024-11-19 23:49:57 ✌️ version 1.14.1-7c4cd60da6d\n 2024-11-19 23:49:57 ❤️ by Parity Technologies <admin@parity.io>, 2017-2024\n 2024-11-19 23:49:57 📋 Chain specification: Polkadot\n 2024-11-19 23:49:57 🏷 Node name: myPolkadotNode\n 2024-11-19 23:49:57 👤 Role: FULL\n 2024-11-19 23:49:57 💾 Database: RocksDb at /home/ubuntu/.local/share/polkadot/chains/polkadot/db/full\n 2024-11-19 23:50:00 🏷 Local node identity is: 12D3KooWDmhHEgPRJUJnUpJ4TFWn28EENqvKWH4dZGCN9TS51y9h\n 2024-11-19 23:50:00 Running libp2p network backend\n 2024-11-19 23:50:00 💻 Operating system: linux\n 2024-11-19 23:50:00 💻 CPU architecture: x86_64\n 2024-11-19 23:50:00 💻 Target environment: gnu\n 2024-11-19 23:50:00 💻 CPU: Intel(R) Xeon(R) CPU E3-1245 V2 @ 3.40GHz\n 2024-11-19 23:50:00 💻 CPU cores: 4\n 2024-11-19 23:50:00 💻 Memory: 32001MB\n 2024-11-19 23:50:00 💻 Kernel: 5.15.0-113-generic\n 2024-11-19 23:50:00 💻 Linux distribution: Ubuntu 22.04.5 LTS\n 2024-11-19 23:50:00 💻 Virtual machine: no\n 2024-11-19 23:50:00 📦 Highest known block at #9319\n 2024-11-19 23:50:00 〽️ Prometheus exporter started at 127.0.0.1:9615\n 2024-11-19 23:50:00 Running JSON-RPC server: addr=127.0.0.1:9944, allowed origins=[\"http://localhost:*\", \"http://127.0.0.1:*\", \"https://localhost:*\", \"https://127.0.0.1:*\", \"https://polkadot.js.org\"]\n 2024-11-19 23:50:00 🏁 CPU score: 671.67 MiBs\n 2024-11-19 23:50:00 🏁 Memory score: 7.96 GiBs\n 2024-11-19 23:50:00 🏁 Disk score (seq. writes): 377.87 MiBs\n 2024-11-19 23:50:00 🏁 Disk score (rand. writes): 147.92 MiBs\n 2024-11-19 23:50:00 🥩 BEEFY gadget waiting for BEEFY pallet to become available...\n 2024-11-19 23:50:00 🔍 Discovered new external address for our node: /ip4/37.187.93.17/tcp/30333/ws/p2p/12D3KooWDmhHEgPRJUJnUpJ4TFWn28EENqvKWH4dZGCN9TS51y9h\n 2024-11-19 23:50:01 🔍 Discovered new external address for our node: /ip6/2001:41d0:a:3511::1/tcp/30333/ws/p2p/12D3KooWDmhHEgPRJUJnUpJ4TFWn28EENqvKWH4dZGCN9TS51y9h\n 2024-11-19 23:50:05 ⚙️ Syncing, target=#23486325 (5 peers), best: #12262 (0x8fb5…f310), finalized #11776 (0x9de1…32fb), ⬇ 430.5kiB/s ⬆ 17.8kiB/s\n 2024-11-19 23:50:10 ⚙️ Syncing 628.8 bps, target=#23486326 (6 peers), best: #15406 (0x9ce1…2d76), finalized #15360 (0x0e41…a064), ⬇ 255.0kiB/s ⬆ 1.8kiB/s\n
\n\nCongratulations, you're now syncing a Polkadot full node! Remember that the process is identical when using any other Polkadot SDK-based chain, although individual chains may have chain-specific flag requirements."} -{"page_id": "nodes-and-validators-run-a-node-full-node", "page_title": "Set Up a Node", "index": 8, "depth": 3, "title": "Connect to Your Node", "anchor": "connect-to-your-node", "start_char": 15591, "end_char": 15944, "estimated_token_count": 117, "token_estimator": "heuristic-v1", "text": "### Connect to Your Node\n\nOpen [Polkadot.js Apps](https://polkadot.js.org/apps/?rpc=ws%3A%2F%2F127.0.0.1%3A9944#/explorer){target=\\_blank} and click the logo in the top left to switch the node. Activate the **Development** toggle and input your node's domain or IP address. The default WSS endpoint for a local node is:\n\n```bash\nws://127.0.0.1:9944\n```"} -{"page_id": "nodes-and-validators-run-a-node-secure-wss", "page_title": "Set Up Secure WebSocket", "index": 0, "depth": 2, "title": "Introduction", "anchor": "introduction", "start_char": 27, "end_char": 600, "estimated_token_count": 103, "token_estimator": "heuristic-v1", "text": "## Introduction\n\nEnsuring secure WebSocket communication is crucial for maintaining the integrity and security of a Polkadot or Kusama node when interacting with remote clients. This guide walks you through setting up a secure WebSocket (WSS) connection for your node by leveraging SSL encryption with popular web server proxies like nginx or Apache.\n\nBy the end of this guide, you'll be able to secure your node's WebSocket port, enabling safe remote connections without exposing your node to unnecessary risks. The instructions in this guide are for UNIX-based systems."} -{"page_id": "nodes-and-validators-run-a-node-secure-wss", "page_title": "Set Up Secure WebSocket", "index": 1, "depth": 2, "title": "Secure a WebSocket Port", "anchor": "secure-a-websocket-port", "start_char": 600, "end_char": 1053, "estimated_token_count": 102, "token_estimator": "heuristic-v1", "text": "## Secure a WebSocket Port\n\nYou can convert a non-secured WebSocket port to a secure WSS port by placing it behind an SSL-enabled proxy. This approach can be used to secure a bootnode or RPC server. The SSL-enabled apache2/nginx/other proxy server redirects requests to the internal WebSocket and converts it to a secure (WSS) connection. You can use a service like [LetsEncrypt](https://letsencrypt.org/){target=\\_blank} to obtain an SSL certificate."} -{"page_id": "nodes-and-validators-run-a-node-secure-wss", "page_title": "Set Up Secure WebSocket", "index": 2, "depth": 3, "title": "Obtain an SSL Certificate", "anchor": "obtain-an-ssl-certificate", "start_char": 1053, "end_char": 2080, "estimated_token_count": 257, "token_estimator": "heuristic-v1", "text": "### Obtain an SSL Certificate\n\nLetsEncrypt suggests using the [Certbot ACME client](https://letsencrypt.org/getting-started/#with-shell-access/){target=\\_blank} for your respective web server implementation to get a free SSL certificate:\n\n- [nginx](https://certbot.eff.org/instructions?ws=nginx&os=ubuntufocal){target=\\_blank}\n- [apache2](https://certbot.eff.org/instructions?ws=apache&os=ubuntufocal){target=\\_blank}\n \nLetsEncrypt will auto-generate an SSL certificate and include it in your configuration.\n\nWhen connecting, you can generate a self-signed certificate and rely on your node's raw IP address. However, self-signed certificates aren't optimal because you must include the certificate in an allowlist to access it from a browser.\n\nUse the following command to generate a self-signed certificate using OpenSSL:\n\n```bash\nsudo openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout /etc/ssl/private/selfsigned.key -out /etc/ssl/certs/selfsigned.crt\nsudo openssl dhparam -out /etc/ssl/certs/dhparam.pem 2048\n```"} -{"page_id": "nodes-and-validators-run-a-node-secure-wss", "page_title": "Set Up Secure WebSocket", "index": 3, "depth": 2, "title": "Install a Proxy Server", "anchor": "install-a-proxy-server", "start_char": 2080, "end_char": 2477, "estimated_token_count": 99, "token_estimator": "heuristic-v1", "text": "## Install a Proxy Server\n\nThere are a lot of different implementations of a WebSocket proxy; some of the more widely used are [nginx](https://www.f5.com/go/product/welcome-to-nginx){target=\\_blank} and [apache2](https://httpd.apache.org/){target=\\_blank}, both of which are commonly used web server implementations. See the following section for configuration examples for both implementations."} -{"page_id": "nodes-and-validators-run-a-node-secure-wss", "page_title": "Set Up Secure WebSocket", "index": 4, "depth": 3, "title": "Use nginx", "anchor": "use-nginx", "start_char": 2477, "end_char": 3219, "estimated_token_count": 154, "token_estimator": "heuristic-v1", "text": "### Use nginx\n\n1. Install the `nginx` web server: \n ```bash\n apt install nginx\n ```\n\n2. In an SSL-enabled virtual host, add:\n ```conf\n server {\n (...)\n location / {\n proxy_buffers 16 4k;\n proxy_buffer_size 2k;\n proxy_pass http://localhost:9944;\n proxy_http_version 1.1;\n proxy_set_header Upgrade $http_upgrade;\n proxy_set_header Connection \"Upgrade\";\n proxy_set_header Host $host;\n }\n }\n ```\n3. Optionally, you can introduce some form of rate limiting:\n ```conf\n http {\n limit_req_zone \"$http_x_forwarded_for\" zone=zone:10m rate=2r/s;\n (...)\n }\n location / {\n limit_req zone=zone burst=5;\n (...)\n }\n ```"} -{"page_id": "nodes-and-validators-run-a-node-secure-wss", "page_title": "Set Up Secure WebSocket", "index": 5, "depth": 3, "title": "Use Apache2", "anchor": "use-apache2", "start_char": 3219, "end_char": 5047, "estimated_token_count": 406, "token_estimator": "heuristic-v1", "text": "### Use Apache2\n\nApache2 can run in various modes, including `prefork`, `worker`, and `event`. In this example, the [`event`](https://httpd.apache.org/docs/2.4/mod/event.html){target=\\_blank} mode is recommended for handling higher traffic loads, as it is optimized for performance in such environments. However, depending on the specific requirements of your setup, other modes like `prefork` or `worker` may also be appropriate.\n\n1. Install the `apache2` web server:\n ```bash\n apt install apache2\n a2dismod mpm_prefork\n a2enmod mpm_event proxy proxy_html proxy_http proxy_wstunnel rewrite ssl\n ```\n2. The [`mod_proxy_wstunnel`](https://httpd.apache.org/docs/2.4/mod/mod_proxy_wstunnel.html){target=\\_blank} provides support for the tunneling of WebSocket connections to a backend WebSocket server. The connection is automatically upgraded to a WebSocket connection. In an SSL-enabled virtual host add:\n\n ```apacheconf\n # (...)\n SSLProxyEngine on\n ProxyRequests off\n ProxyPass / ws://localhost:9944\n ProxyPassReverse / ws://localhost:9944\n ```\n !!!warning \n Older versions of `mod_proxy_wstunnel` don't upgrade the connection automatically and will need the following config added:\n ```apacheconf\n RewriteEngine on\n RewriteCond %{HTTP:Upgrade} websocket [NC]\n RewriteRule /(.*) ws://localhost:9944/$1 [P,L]\n RewriteRule /(.*) http://localhost:9944/$1 [P,L]\n ```\n\n3. Optionally, some form of rate limiting can be introduced by first running the following command:\n\n ```bash\n apt install libapache2-mod-qos\n a2enmod qos\n ```\n\n Then edit `/etc/apache2/mods-available/qos.conf` as follows:\n\n ```conf\n # allows max 50 connections from a single IP address:\n QS_SrvMaxConnPerIP 50\n ```"} -{"page_id": "nodes-and-validators-run-a-node-secure-wss", "page_title": "Set Up Secure WebSocket", "index": 6, "depth": 2, "title": "Connect to the Node", "anchor": "connect-to-the-node", "start_char": 5047, "end_char": 5568, "estimated_token_count": 159, "token_estimator": "heuristic-v1", "text": "## Connect to the Node\n\n1. Open [Polkadot.js Apps interface](https://polkadot.js.org/apps){target=\\_blank} and click the logo in the top left to switch the node.\n2. Activate the **Development** toggle and input either your node's domain or IP address. Remember to prefix with `wss://` and, if you're using the 443 port, append `:443` as follows:\n\n ```bash\n wss://example.com:443\n ```\n\n![A sync-in-progress chain connected to Polkadot.js UI](/images/nodes-and-validators/run-a-node/secure-wss/secure-wss-01.webp)"} -{"page_id": "nodes-and-validators-run-a-validator-onboarding-and-offboarding-key-management", "page_title": "Validator Key Management", "index": 0, "depth": 2, "title": "Introduction", "anchor": "introduction", "start_char": 18, "end_char": 577, "estimated_token_count": 118, "token_estimator": "heuristic-v1", "text": "## Introduction\n\nAfter setting up your node environment as shown in the [Setup](/nodes-and-validators/run-a-validator/onboarding-and-offboarding/set-up-validator/){target=\\_blank} section, you'll need to configure multiple keys for your validator to operate properly. This includes setting up session keys, which are essential for participating in the consensus process, and configuring a node key that maintains a stable network identity. This guide walks you through the key management process, showing you how to generate, store, and register these keys."} -{"page_id": "nodes-and-validators-run-a-validator-onboarding-and-offboarding-key-management", "page_title": "Validator Key Management", "index": 1, "depth": 2, "title": "Set Session Keys", "anchor": "set-session-keys", "start_char": 577, "end_char": 1107, "estimated_token_count": 100, "token_estimator": "heuristic-v1", "text": "## Set Session Keys\n\nSetting up your validator's session keys is essential to associate your node with your stash account on the Polkadot network. Validators use session keys to participate in the consensus process. Your validator can only perform its role in the network by properly setting session keys which consist of several key pairs for different parts of the protocol (e.g., GRANDPA, BABE). These keys must be registered on-chain and associated with your validator node to ensure it can participate in validating blocks."} -{"page_id": "nodes-and-validators-run-a-validator-onboarding-and-offboarding-key-management", "page_title": "Validator Key Management", "index": 2, "depth": 3, "title": "Generate Session Keys", "anchor": "generate-session-keys", "start_char": 1107, "end_char": 4121, "estimated_token_count": 648, "token_estimator": "heuristic-v1", "text": "### Generate Session Keys\n\nThere are multiple ways to create the session keys. It can be done by interacting with the [Polkadot.js Apps UI](https://polkadot.js.org/apps/#/explorer){target=\\_blank}, using the curl command or by using [Subkey](https://paritytech.github.io/polkadot-sdk/master/subkey/index.html){target=\\_blank}.\n\n=== \"Polkadot.js Apps UI\"\n\n 1. In Polkadot.js Apps, connect to your local node, navigate to the **Developer** dropdown, and select the **RPC Calls** option.\n\n 2. Construct an `author_rotateKeys` RPC call and execute it:\n\n 1. Select the **author** endpoint.\n 2. Choose the **rotateKeys()** call.\n 3. Click the **Submit RPC Call** button.\n 4. Copy the hex-encoded public key from the response.\n\n ![](/images/nodes-and-validators/run-a-validator/onboarding-and-offboarding/key-management/key-management-01.webp)\n\n=== \"Curl\"\n\n Generate session keys by running the following command on your validator node:\n\n ``` bash\n curl -H \"Content-Type: application/json\" \\\n -d '{\"id\":1, \"jsonrpc\":\"2.0\", \"method\": \"author_rotateKeys\", \"params\":[]}' \\\n http://localhost:9944\n ```\n\n This command will return a JSON object. The `result` key is the hex-encoded public part of the newly created session key. Save this for later use.\n \n ```json\n {\"jsonrpc\":\"2.0\",\"result\":\"0xda3861a45e0197f3ca145c2c209f9126e5053fas503e459af4255cf8011d51010\",\"id\":1}\n ```\n\n=== \"Subkey\"\n\n To create a keypair for your node's session keys, use the `subkey generate` command. This generates a set of cryptographic keys that must be stored in your node's keystore directory.\n\n When you run the command, it produces output similar to this example:\n\n
\n subkey generate\n
\n    Secret phrase:       twist buffalo mixture excess device drastic vague mammal fitness punch match hammer\n      Network ID:        substrate\n      Secret seed:       0x5faa9e5defe42b201388d5c2b8202d6625a344abc9aa52943a71f12cb90b88a9\n      Public key (hex):  0x28cc2fdb6e28835e2bbac9a16feb65c23d448c9314ef12fe083b61bab8fc2755\n      Account ID:        0x28cc2fdb6e28835e2bbac9a16feb65c23d448c9314ef12fe083b61bab8fc2755\n      Public key (SS58): 5CzCRpXzHYhuo6G3gYFR3cgV6X3qCNwVt51m8q14ZcChsSXQ\n      SS58 Address:      5CzCRpXzHYhuo6G3gYFR3cgV6X3qCNwVt51m8q14ZcChsSXQ\n      
\n
\n\n To properly store these keys, create a file in your keystore directory with a specific naming convention. The filename must consist of the hex string `61757261` (which represents \"aura\" in hex) followed by the public key without its `0x` prefix.\n\n Using the example above, you would create a file named:\n\n ```\n ./keystores/6175726128cc2fdb6e28835e2bbac9a16feb65c23d448c9314ef12fe083b61bab8fc2755\n ```\n\n And store only the secret phrase in the file:\n\n ```\n \"twist buffalo mixture excess device drastic vague mammal fitness punch match hammer\"\n ```"} -{"page_id": "nodes-and-validators-run-a-validator-onboarding-and-offboarding-key-management", "page_title": "Validator Key Management", "index": 3, "depth": 3, "title": "Submit Transaction to Set Keys", "anchor": "submit-transaction-to-set-keys", "start_char": 4121, "end_char": 4757, "estimated_token_count": 152, "token_estimator": "heuristic-v1", "text": "### Submit Transaction to Set Keys\n\nNow that you have generated your session keys, you must submit them to the chain. Follow these steps:\n\n1. Go to the **Network > Staking > Accounts** section on Polkadot.js Apps.\n2. Select **Set Session Key** on the bonding account you generated earlier.\n3. Paste the hex-encoded session key string you generated (from either the UI or CLI) into the input field and submit the transaction.\n\n![](/images/nodes-and-validators/run-a-validator/onboarding-and-offboarding/key-management/key-management-02.webp)\n\nOnce the transaction is signed and submitted, your session keys will be registered on-chain."} -{"page_id": "nodes-and-validators-run-a-validator-onboarding-and-offboarding-key-management", "page_title": "Validator Key Management", "index": 4, "depth": 3, "title": "Verify Session Key Setup", "anchor": "verify-session-key-setup", "start_char": 4757, "end_char": 5302, "estimated_token_count": 138, "token_estimator": "heuristic-v1", "text": "### Verify Session Key Setup\n\nTo verify that your session keys are properly set, you can use one of two RPC calls:\n\n- **`hasKey`**: Checks if the node has a specific key by public key and key type.\n- **`hasSessionKeys`**: Verifies if your node has the full session key string associated with the validator.\n\nFor example, you can [check session keys on the Polkadot.js Apps](https://polkadot.js.org/apps/#/rpc){target=\\_blank} interface or by running an RPC query against your node. Once this is done, your validator node is ready for its role."} -{"page_id": "nodes-and-validators-run-a-validator-onboarding-and-offboarding-key-management", "page_title": "Validator Key Management", "index": 5, "depth": 2, "title": "Set the Node Key", "anchor": "set-the-node-key", "start_char": 5302, "end_char": 6944, "estimated_token_count": 408, "token_estimator": "heuristic-v1", "text": "## Set the Node Key\n\nValidators on Polkadot need a static network key (also known as the node key) to maintain a stable node identity. This key ensures that your validator can maintain a consistent peer ID, even across restarts, which is crucial for maintaining reliable network connections.\n\nStarting with Polkadot version 1.11, validators without a stable network key may encounter the following error on startup:\n\n
\n polkadot --validator --name \"INSERT_NAME_FROM_TELEMETRY\"\n Error:\n 0: Starting an authority without network key\n This is not a safe operation because other authorities in the network may depend on your node having a stable identity.\n Otherwise these other authorities may not being able to reach you.\n If it is the first time running your node you could use one of the following methods:\n 1. [Preferred] Separately generate the key with: INSERT_NODE_BINARY key generate-node-key --base-path INSERT_YOUR_BASE_PATH\n 2. [Preferred] Separately generate the key with: INSERT_NODE_BINARY key generate-node-key --file INSERT_YOUR_PATH_TO_NODE_KEY\n 3. [Preferred] Separately generate the key with: INSERT_NODE_BINARY key generate-node-key --default-base-path\n 4. [Unsafe] Pass --unsafe-force-node-key-generation and make sure you remove it for subsequent node restarts\n \n
"} -{"page_id": "nodes-and-validators-run-a-validator-onboarding-and-offboarding-key-management", "page_title": "Validator Key Management", "index": 6, "depth": 3, "title": "Generate the Node Key", "anchor": "generate-the-node-key", "start_char": 6944, "end_char": 7605, "estimated_token_count": 144, "token_estimator": "heuristic-v1", "text": "### Generate the Node Key\n\nUse one of the following methods to generate your node key:\n\n=== \"Save to file\"\n\n The recommended solution is to generate a node key and save it to a file using the following command:\n\n ``` bash\n polkadot key generate-node-key --file INSERT_PATH_TO_NODE_KEY\n ```\n \n=== \"Use default path\"\n\n You can also generate the node key with the following command, which will automatically save the key to the base path of your node:\n\n ``` bash\n polkadot key generate-node-key --default-base-path\n ```\n\nSave the file path for reference. You will need it in the next step to configure your node with a static identity."} -{"page_id": "nodes-and-validators-run-a-validator-onboarding-and-offboarding-key-management", "page_title": "Validator Key Management", "index": 7, "depth": 3, "title": "Set Node Key", "anchor": "set-node-key", "start_char": 7605, "end_char": 8227, "estimated_token_count": 132, "token_estimator": "heuristic-v1", "text": "### Set Node Key\n\nAfter generating the node key, configure your node to use it by specifying the path to the key file when launching your node. Add the following flag to your validator node's startup command:\n\n``` bash\npolkadot --node-key-file INSERT_PATH_TO_NODE_KEY\n```\n\nFollowing these steps ensures that your node retains its identity, making it discoverable by peers without the risk of conflicting identities across sessions. For further technical background, see Polkadot SDK [Pull Request #3852](https://github.com/paritytech/polkadot-sdk/pull/3852){target=\\_blank} for the rationale behind requiring static keys."} -{"page_id": "nodes-and-validators-run-a-validator-onboarding-and-offboarding-set-up-validator", "page_title": "Set Up a Validator", "index": 0, "depth": 2, "title": "Introduction", "anchor": "introduction", "start_char": 22, "end_char": 642, "estimated_token_count": 101, "token_estimator": "heuristic-v1", "text": "## Introduction\n\nSetting up a Polkadot validator node is essential for securing the network and earning staking rewards. This guide walks you through the technical steps to set up a validator, from installing the necessary software to managing keys and synchronizing your node with the chain.\n\nRunning a validator requires a commitment to maintaining a stable, secure infrastructure. Validators are responsible for their own stakes and those of nominators who trust them with their tokens. Proper setup and ongoing management are critical to ensuring smooth operation and avoiding potential penalties such as slashing."} -{"page_id": "nodes-and-validators-run-a-validator-onboarding-and-offboarding-set-up-validator", "page_title": "Set Up a Validator", "index": 1, "depth": 2, "title": "Prerequisites", "anchor": "prerequisites", "start_char": 642, "end_char": 1744, "estimated_token_count": 279, "token_estimator": "heuristic-v1", "text": "## Prerequisites\n\nTo get the most from this guide, ensure you've done the following before going forward:\n\n- Read [Validator Requirements](/nodes-and-validators/run-a-validator/requirements/){target=\\_blank} and understand the recommended minimum skill level and hardware needs.\n- Read [General Management](/nodes-and-validators/run-a-validator/operational-tasks/general-management/){target=\\_blank}, [Upgrade Your Node](/nodes-and-validators/run-a-validator/operational-tasks/upgrade-your-node/){target=\\_blank}, and [Pause Validating](/nodes-and-validators/run-a-validator/operational-tasks/pause-validating/){target=\\_blank} and understand the tasks required to keep your validator operational.\n- Read [Rewards Payout](/nodes-and-validators/run-a-validator/staking-mechanics/rewards/){target=\\_blank} and understand how validator rewards are determined and paid out.\n- Read [Offenses and Slashes](/nodes-and-validators/run-a-validator/staking-mechanics/offenses-and-slashes/){target=\\_blank} and understand how validator performance and security can affect tokens staked by you or your nominators."} -{"page_id": "nodes-and-validators-run-a-validator-onboarding-and-offboarding-set-up-validator", "page_title": "Set Up a Validator", "index": 2, "depth": 2, "title": "Initial Setup", "anchor": "initial-setup", "start_char": 1744, "end_char": 2300, "estimated_token_count": 94, "token_estimator": "heuristic-v1", "text": "## Initial Setup\n\nBefore running your validator, you must configure your server environment to meet the operational and security standards required for validating.\n\nYou must use a Linux-based operating system with Kernel 5.16 or later. Configuration includes setting up time synchronization, ensuring critical security features are active, and installing the necessary binaries. Proper setup at this stage is essential to prevent issues like block production errors or being penalized for downtime. Below are the essential steps to get your system ready."} -{"page_id": "nodes-and-validators-run-a-validator-onboarding-and-offboarding-set-up-validator", "page_title": "Set Up a Validator", "index": 3, "depth": 3, "title": "Install Network Time Protocol Client", "anchor": "install-network-time-protocol-client", "start_char": 2300, "end_char": 3412, "estimated_token_count": 236, "token_estimator": "heuristic-v1", "text": "### Install Network Time Protocol Client\n\nAccurate timekeeping is critical to ensure your validator is synchronized with the network. Validators need local clocks in sync with the blockchain to avoid missing block authorship opportunities. Using [Network Time Protocol (NTP)](https://en.wikipedia.org/wiki/Network_Time_Protocol){target=\\_blank} is the standard solution to keep your system's clock accurate.\n\nIf you are using Ubuntu version 18.04 or newer, the NTP Client should be installed by default. You can check whether you have the NTP client by running:\n\n```sh\ntimedatectl\n```\n\nIf NTP is running, you should see a message like the following:\n\n``` sh\nSystem clock synchronized: yes\n```\n\nIf NTP is not installed or running, you can install it using:\n\n```sh\nsudo apt-get install ntp\n```\n\nAfter installation, NTP will automatically start. To check its status:\n\n```sh\nsudo ntpq -p\n```\n\nThis command will return a message with the status of the NTP synchronization. Skipping this step could result in your validator node missing blocks due to minor clock drift, potentially affecting its network performance."} -{"page_id": "nodes-and-validators-run-a-validator-onboarding-and-offboarding-set-up-validator", "page_title": "Set Up a Validator", "index": 4, "depth": 3, "title": "Verify Landlock is Activated", "anchor": "verify-landlock-is-activated", "start_char": 3412, "end_char": 5009, "estimated_token_count": 319, "token_estimator": "heuristic-v1", "text": "### Verify Landlock is Activated\n\n[Landlock](https://docs.kernel.org/userspace-api/landlock.html){target=\\_blank} is an important security feature integrated into Linux kernels starting with version 5.13. It allows processes, even those without special privileges, to limit their access to the system to reduce the machine's attack surface. This feature is crucial for validators, as it helps ensure the security and stability of the node by preventing unauthorized access or malicious behavior.\n\nTo use Landlock, ensure you use the reference kernel or newer versions. Most Linux distributions should already have Landlock activated. You can check if Landlock is activated on your machine by running the following command as root:\n\n```sh\ndmesg | grep landlock || journalctl -kg landlock\n```\n\nIf Landlock is not activated, your system logs won't show any related output. In this case, you will need to activate it manually or ensure that your Linux distribution supports it. Most modern distributions with the required kernel version should have Landlock activated by default. However, if your system lacks support, you may need to build the kernel with Landlock activated. For more information on doing so, refer to the [official kernel documentation](https://docs.kernel.org/userspace-api/landlock.html#kernel-support){target=\\_blank}.\n\nImplementing Landlock ensures your node operates in a restricted, self-imposed sandbox, limiting potential damage from security breaches or bugs. While not a mandatory requirement, enabling this feature greatly improves the security of your validator setup."} -{"page_id": "nodes-and-validators-run-a-validator-onboarding-and-offboarding-set-up-validator", "page_title": "Set Up a Validator", "index": 5, "depth": 2, "title": "Install the Polkadot Binaries", "anchor": "install-the-polkadot-binaries", "start_char": 5009, "end_char": 5435, "estimated_token_count": 82, "token_estimator": "heuristic-v1", "text": "## Install the Polkadot Binaries\n\nYou must install the Polkadot binaries required to run your validator node. These binaries include the main `polkadot`, `polkadot-prepare-worker`, and `polkadot-execute-worker` binaries. All three are needed to run a fully functioning validator node.\n\nDepending on your preference and operating system setup, there are multiple methods to install these binaries. Below are the main options:"} -{"page_id": "nodes-and-validators-run-a-validator-onboarding-and-offboarding-set-up-validator", "page_title": "Set Up a Validator", "index": 6, "depth": 3, "title": "Install from Official Releases", "anchor": "install-from-official-releases", "start_char": 5435, "end_char": 8225, "estimated_token_count": 622, "token_estimator": "heuristic-v1", "text": "### Install from Official Releases\n\nThe preferred, most straightforward method to install the required binaries is downloading the latest versions from the official releases. You can visit the [Github Releases](https://github.com/paritytech/polkadot-sdk/releases){target=\\_blank} page for the most current versions of the `polkadot`, `polkadot-prepare-worker`, and `polkadot-execute-worker` binaries.\n\nYou can also download the binaries by using the following direct links:\n\n=== \"`polkadot`\"\n\n ``` bash\n # Download the binary\n curl -LO https://github.com/paritytech/polkadot-sdk/releases/download/polkadot-stable2506-2/polkadot\n\n # Verify signature\n curl -LO https://github.com/paritytech/polkadot-sdk/releases/download/polkadot-stable2506-2/polkadot.asc\n \n gpg --keyserver hkps://keyserver.ubuntu.com --receive-keys 90BD75EBBB8E95CB3DA6078F94A4029AB4B35DAE\n\n gpg --verify polkadot.asc\n ```\n\n=== \"`polkadot-prepare-worker`\"\n\n ``` bash\n # Download the binary\n curl -LO https://github.com/paritytech/polkadot-sdk/releases/download/polkadot-stable2506-2/polkadot-prepare-worker\n\n # Verify signature\n curl -LO https://github.com/paritytech/polkadot-sdk/releases/download/polkadot-stable2506-2/polkadot-prepare-worker.asc\n\n gpg --keyserver hkps://keyserver.ubuntu.com --receive-keys 90BD75EBBB8E95CB3DA6078F94A4029AB4B35DAE\n\n gpg --verify polkadot-prepare-worker.asc\n ```\n\n=== \"`polkadot-execute-worker`\"\n\n ``` bash\n # Download the binary\n curl -LO https://github.com/paritytech/polkadot-sdk/releases/download/polkadot-stable2506-2/polkadot-execute-worker\n\n # Verify signature\n curl -LO https://github.com/paritytech/polkadot-sdk/releases/download/polkadot-stable2506-2/polkadot-execute-worker.asc\n\n gpg --keyserver hkps://keyserver.ubuntu.com --receive-keys 90BD75EBBB8E95CB3DA6078F94A4029AB4B35DAE\n\n gpg --verify polkadot-execute-worker.asc\n ```\n\n\nSignature verification cryptographically ensures the downloaded binaries are authentic and have not been tampered with by using GPG signing keys. Polkadot releases use two different signing keys:\n\n- ParityReleases (release-team@parity.io) with key [`90BD75EBBB8E95CB3DA6078F94A4029AB4B35DAE`](https://keyserver.ubuntu.com/pks/lookup?search=90BD75EBBB8E95CB3DA6078F94A4029AB4B35DAE&fingerprint=on&op=index){target=\\_blank} for current and new releases.\n- Parity Security Team (security@parity.io) with key [`9D4B2B6EB8F97156D19669A9FF0812D491B96798`](https://keyserver.ubuntu.com/pks/lookup?search=9D4B2B6EB8F97156D19669A9FF0812D491B96798&fingerprint=on&op=index){target=\\_blank} for old releases.\n\n !!!warning\n When verifying a signature, a \"Good signature\" message indicates successful verification, while any other output signals a potential security risk."} -{"page_id": "nodes-and-validators-run-a-validator-onboarding-and-offboarding-set-up-validator", "page_title": "Set Up a Validator", "index": 7, "depth": 3, "title": "Install with Package Managers", "anchor": "install-with-package-managers", "start_char": 8225, "end_char": 9292, "estimated_token_count": 241, "token_estimator": "heuristic-v1", "text": "### Install with Package Managers\n\nUsers running Debian-based distributions like Ubuntu can install the binaries using the [APT](https://wiki.debian.org/Apt){target=\\_blank} package manager.\n\nExecute the following commands as root to add the official repository and install the binaries:\n\n```bash\n# Import the release-team@parity.io GPG key\ngpg --keyserver hkps://keyserver.ubuntu.com --receive-keys 90BD75EBBB8E95CB3DA6078F94A4029AB4B35DAE\ngpg --export 90BD75EBBB8E95CB3DA6078F94A4029AB4B35DAE > /usr/share/keyrings/parity.gpg\n\n# Add the Parity repository and update the package index\necho 'deb [signed-by=/usr/share/keyrings/parity.gpg] https://releases.parity.io/deb release main' > /etc/apt/sources.list.d/parity.list\napt update\n\n# Install the `parity-keyring` package - This will ensure the GPG key\n# used by APT remains up-to-date\napt install parity-keyring\n\n# Install polkadot\napt install polkadot\n```\n\nOnce installation completes, verify the binaries are correctly installed by following the steps in the [verify installation](#verify-installation) section."} -{"page_id": "nodes-and-validators-run-a-validator-onboarding-and-offboarding-set-up-validator", "page_title": "Set Up a Validator", "index": 8, "depth": 3, "title": "Install with Ansible", "anchor": "install-with-ansible", "start_char": 9292, "end_char": 9649, "estimated_token_count": 70, "token_estimator": "heuristic-v1", "text": "### Install with Ansible\n\nYou can also manage Polkadot installations using Ansible. This approach can be beneficial for users managing multiple validator nodes or requiring automated deployment. The [Parity chain operations Ansible collection](https://github.com/paritytech/ansible-galaxy/){target=\\_blank} provides a Substrate node role for this purpose."} -{"page_id": "nodes-and-validators-run-a-validator-onboarding-and-offboarding-set-up-validator", "page_title": "Set Up a Validator", "index": 9, "depth": 3, "title": "Install with Docker", "anchor": "install-with-docker", "start_char": 9649, "end_char": 9932, "estimated_token_count": 60, "token_estimator": "heuristic-v1", "text": "### Install with Docker\n\nIf you prefer using Docker or an OCI-compatible container runtime, the official Polkadot Docker image can be pulled directly from Docker Hub.\n\nTo pull the latest stable image, run the following command:\n\n```bash\ndocker pull parity/polkadot:stable2506-2\n```"} -{"page_id": "nodes-and-validators-run-a-validator-onboarding-and-offboarding-set-up-validator", "page_title": "Set Up a Validator", "index": 10, "depth": 3, "title": "Build from Sources", "anchor": "build-from-sources", "start_char": 9932, "end_char": 10165, "estimated_token_count": 58, "token_estimator": "heuristic-v1", "text": "### Build from Sources\n\nYou may build the binaries from source by following the instructions on the [Polkadot SDK repository](https://github.com/paritytech/polkadot-sdk/tree/polkadot-stable2506-2/polkadot#building){target=\\_blank}."} -{"page_id": "nodes-and-validators-run-a-validator-onboarding-and-offboarding-set-up-validator", "page_title": "Set Up a Validator", "index": 11, "depth": 2, "title": "Verify Installation", "anchor": "verify-installation", "start_char": 10165, "end_char": 11921, "estimated_token_count": 430, "token_estimator": "heuristic-v1", "text": "## Verify Installation\n\nOnce the Polkadot binaries are installed, it's essential to verify that everything is set up correctly and that all the necessary components are in place. Follow these steps to ensure the binaries are installed and functioning as expected.\n\n1. **Check the versions**: Run the following commands to verify the versions of the installed binaries.\n\n ```bash\n polkadot --version\n polkadot-execute-worker --version\n polkadot-prepare-worker --version\n ```\n\n The output should show the version numbers for each of the binaries. Ensure that the versions match and are consistent, similar to the following example (the specific version may vary):\n\n
\n polkadot --version polkadot-execute-worker --version polkadot-prepare-worker --version\n 1.16.1-36264cb36db\n 1.16.1-36264cb36db\n 1.16.1-36264cb36db\n \n
\n\n If the versions do not match or if there is an error, double-check that all the binaries were correctly installed and are accessible within your `$PATH`.\n\n2. **Ensure all binaries are in the same directory**: All the binaries must be in the same directory for the Polkadot validator node to function properly. If the binaries are not in the same location, move them to a unified directory and ensure this directory is added to your system's `$PATH`.\n\n To verify the `$PATH`, run the following command:\n\n ```bash\n echo $PATH\n ```\n\n If necessary, you can move the binaries to a shared location, such as `/usr/local/bin/`, and add it to your `$PATH`."} -{"page_id": "nodes-and-validators-run-a-validator-onboarding-and-offboarding-start-validating", "page_title": "Start Validating", "index": 0, "depth": 2, "title": "Introduction", "anchor": "introduction", "start_char": 20, "end_char": 449, "estimated_token_count": 94, "token_estimator": "heuristic-v1", "text": "## Introduction\n\nAfter configuring your node keys as shown in the [Key Management](/nodes-and-validators/run-a-validator/onboarding-and-offboarding/key-management/){target=\\_blank} section and ensuring your system is set up, you're ready to begin the validator setup process. This guide will walk you through choosing a network, synchronizing your node with the blockchain, bonding your DOT tokens, and starting your validator."} -{"page_id": "nodes-and-validators-run-a-validator-onboarding-and-offboarding-start-validating", "page_title": "Start Validating", "index": 1, "depth": 2, "title": "Choose a Network", "anchor": "choose-a-network", "start_char": 449, "end_char": 1438, "estimated_token_count": 193, "token_estimator": "heuristic-v1", "text": "## Choose a Network\n\nRunning your validator on a test network like Westend or Kusama is a smart way to familiarize yourself with the process and identify any setup issues in a lower-stakes environment before joining the Polkadot MainNet.\n\n- **Westend**: Polkadot's primary TestNet is open to anyone for testing purposes. Validator slots are intentionally limited to keep the network stable for the Polkadot release process, so it may not support as many validators at any given time.\n- **Kusama**: Often called Polkadot's \"canary network,\" Kusama has real economic value but operates with a faster and more experimental approach. Running a validator here provides an experience closer to MainNet with the benefit of more frequent validation opportunities with an era time of 6 hours vs 24 hours for Polkadot.\n- **Polkadot**: The main network, where validators secure the Polkadot relay chain. It has a slower era time of 24 hours and requires a higher minimum bond amount to participate."} -{"page_id": "nodes-and-validators-run-a-validator-onboarding-and-offboarding-start-validating", "page_title": "Start Validating", "index": 2, "depth": 2, "title": "Synchronize Chain Data", "anchor": "synchronize-chain-data", "start_char": 1438, "end_char": 4716, "estimated_token_count": 857, "token_estimator": "heuristic-v1", "text": "## Synchronize Chain Data\n\nThe next step is to sync your node with the chosen blockchain network. Synchronization is necessary to download and validate the blockchain data, ensuring your node is ready to participate as a validator. Follow these steps to sync your node:\n\n1. **Start syncing**: You can run a full or warp sync.\n\n === \"Full sync\"\n\n Polkadot defaults to using a full sync, which downloads and validates the entire blockchain history from the genesis block. Start the syncing process by running the following command:\n\n ```sh\n polkadot\n ```\n\n This command starts your Polkadot node in non-validator mode, allowing you to synchronize the chain data.\n\n === \"Warp sync\"\n\n You can opt to use warp sync which initially downloads only GRANDPA finality proofs and the latest finalized block's state. Use the following command to start a warp sync:\n\n ``` bash\n polkadot --sync warp\n ```\n\n Warp sync ensures that your node quickly updates to the latest finalized state. The historical blocks are downloaded in the background as the node continues to operate.\n\n If you're planning to run a validator on a TestNet, you can specify the chain using the `--chain` flag. For example, the following will run a validator on Kusama:\n\n ```sh\n polkadot --chain=kusama\n ```\n\n2. **Monitor sync progress**: Once the sync starts, you will see a stream of logs providing information about the node's status and progress. Here's an example of what the output might look like:\n\n
\n polkadot\n 2021-06-17 03:07:07 Parity Polkadot\n 2021-06-17 03:07:07 ✌️ version 0.9.5-95f6aa201-x86_64-linux-gnu\n 2021-06-17 03:07:07 ❤️ by Parity Technologies <admin@parity.io>, 2017-2021\n 2021-06-17 03:07:07 📋 Chain specification: Polkadot\n 2021-06-17 03:07:07 🏷 Node name: boiling-pet-7554\n 2021-06-17 03:07:07 👤 Role: FULL\n 2021-06-17 03:07:07 💾 Database: RocksDb at /root/.local/share/polkadot/chains/polkadot/db\n 2021-06-17 03:07:07 ⛓ Native runtime: polkadot-9050 (parity-polkadot-0.tx7.au0)\n 2021-06-17 03:07:10 🏷 Local node identity is: 12D3KooWLtXFWf1oGrnxMGmPKPW54xWCHAXHbFh4Eap6KXmxoi9u\n 2021-06-17 03:07:10 📦 Highest known block at #17914\n 2021-06-17 03:07:10 〽️ Prometheus server started at 127.0.0.1:9615\n 2021-06-17 03:07:10 Listening for new connections on 127.0.0.1:9944\n ...\n
\n\n The output logs provide information such as the current block number, node name, and network connections. Monitor the sync progress and any errors that might occur during the process. Look for information about the latest processed block and compare it with the current highest block using tools like [Telemetry](https://telemetry.polkadot.io/#list/Polkadot%20CC1){target=\\_blank} or [Polkadot.js Apps Explorer](https://polkadot.js.org/apps/#/explorer){target=\\_blank}."} -{"page_id": "nodes-and-validators-run-a-validator-onboarding-and-offboarding-start-validating", "page_title": "Start Validating", "index": 3, "depth": 3, "title": "Database Snapshot Services", "anchor": "database-snapshot-services", "start_char": 4716, "end_char": 6683, "estimated_token_count": 628, "token_estimator": "heuristic-v1", "text": "### Database Snapshot Services\n\nIf you'd like to speed up the process further, you can use a database snapshot. Snapshots are compressed backups of the blockchain's database directory and can significantly reduce the time required to sync a new node. Here are a few public snapshot providers:\n\n- [Stakeworld](https://stakeworld.io/snapshot){target=\\_blank}\n- [Polkachu](https://polkachu.com/substrate_snapshots){target=\\_blank}\n- [Polkashots](https://polkashots.io/){target=\\_blank}\n- [ITRocket](https://itrocket.net/services/mainnet/polkadot/#snapshot){target=\\_blank}\n\n!!!warning\n Although snapshots are convenient, syncing from scratch is recommended for security purposes. If snapshots become corrupted and most nodes rely on them, the network could inadvertently run on a non-canonical chain.\n\n
\n polkadot\n 2021-06-17 03:07:07 Idle (0 peers), best: #0 (0x3fd7...5baf), finalized #0 (0x3fd7...5baf), ⬇ 2.9kiB/s ⬆ 3.7kiB/s\n 2021-06-17 03:07:12 Idle (0 peers), best: #0 (0x3fd7...5baf), finalized #0 (0x3fd7...5baf), ⬇ 1.7kiB/s ⬆ 2.0kiB/s\n 2021-06-17 03:07:17 Idle (0 peers), best: #0 (0x3fd7...5baf), finalized #0 (0x3fd7...5baf), ⬇ 0.9kiB/s ⬆ 1.2kiB/s\n 2021-06-17 03:07:19 Libp2p => Random Kademlia query has yielded empty results\n 2021-06-17 03:08:00 Idle (0 peers), best: #0 (0x3fd7...5baf), finalized #0 (0x3fd7...5baf), ⬇ 1.6kiB/s ⬆ 1.9kiB/s\n 2021-06-17 03:08:05 Idle (0 peers), best: #0 (0x3fd7...5baf), finalized #0 (0x3fd7...5baf), ⬇ 0.6kiB/s ⬆ 0.9kiB/s\n ...\n
\n\nIf you see terminal output similar to the preceding, and you are unable to synchronize the chain due to having zero peers, make sure you have libp2p port `30333` activated. It will take some time to discover other peers over the network."} -{"page_id": "nodes-and-validators-run-a-validator-onboarding-and-offboarding-start-validating", "page_title": "Start Validating", "index": 4, "depth": 2, "title": "Bond DOT", "anchor": "bond-dot", "start_char": 6683, "end_char": 7251, "estimated_token_count": 123, "token_estimator": "heuristic-v1", "text": "## Bond DOT\n\nOnce your validator node is synced, the next step is bonding DOT. A bonded account, or stash, holds your staked tokens (DOT) that back your validator node. Bonding your DOT means locking it for a period, during which it cannot be transferred or spent but is used to secure your validator's role in the network. Visit the [Minimum Bond Requirement](/nodes-and-validators/run-a-validator/requirements/#minimum-bond-requirement) section for details on how much DOT is required.\n\nThe following sections will guide you through bonding DOT for your validator."} -{"page_id": "nodes-and-validators-run-a-validator-onboarding-and-offboarding-start-validating", "page_title": "Start Validating", "index": 5, "depth": 3, "title": "Bonding DOT on Polkadot.js Apps", "anchor": "bonding-dot-on-polkadotjs-apps", "start_char": 7251, "end_char": 8852, "estimated_token_count": 382, "token_estimator": "heuristic-v1", "text": "### Bonding DOT on Polkadot.js Apps\n\nOnce you're ready to bond your DOT, head over to the [Polkadot.js Apps](https://polkadot.js.org/apps/){target=\\_blank} staking page by clicking the **Network** dropdown at the top of the page and selecting [**Staking**](https://polkadot.js.org/apps/#/staking/actions){target=\\_blank}.\n\nTo get started with the bond submission, click on the **Accounts** tab, then the **+ Stash** button, and then enter the following information:\n\n1. **Stash account**: Select your stash account (which is the account with the DOT/KSM balance).\n2. **Value bonded**: Enter how much DOT from the stash account you want to bond/stake. You are not required to bond all of the DOT in that account and you may bond more DOT at a later time. Be aware, withdrawing any bonded amount requires waiting for the unbonding period. The unbonding period is seven days for Kusama and 28 days for Polkadot.\n3. **Payment destination**: Add the recipient account for validator rewards. If you'd like to redirect payments to an account that is not the stash account, you can do it by entering the address here. Note that it is extremely unsafe to set an exchange address as the recipient of the staking rewards.\n\nOnce everything is filled in properly, select **Bond** and sign the transaction with your stash account. If successful, you should see an `ExtrinsicSuccess` message.\n\nYour bonded account will be available under **Stashes**. After refreshing the screen, you should now see a card with all your accounts. The bonded amount on the right corresponds to the funds bonded by the stash account."} -{"page_id": "nodes-and-validators-run-a-validator-onboarding-and-offboarding-start-validating", "page_title": "Start Validating", "index": 6, "depth": 2, "title": "Validate", "anchor": "validate", "start_char": 8852, "end_char": 9080, "estimated_token_count": 45, "token_estimator": "heuristic-v1", "text": "## Validate\n\nOnce your validator node is fully synced and ready, the next step is to ensure it's visible on the network and performing as expected. Below are steps for monitoring and managing your node on the Polkadot network."} -{"page_id": "nodes-and-validators-run-a-validator-onboarding-and-offboarding-start-validating", "page_title": "Start Validating", "index": 7, "depth": 3, "title": "Verify Sync via Telemetry", "anchor": "verify-sync-via-telemetry", "start_char": 9080, "end_char": 9807, "estimated_token_count": 153, "token_estimator": "heuristic-v1", "text": "### Verify Sync via Telemetry\n\nTo confirm that your validator is live and synchronized with the Polkadot network, visit the [Telemetry](https://telemetry.polkadot.io/#list/Polkadot%20CC1){target=\\_blank} page. Telemetry provides real-time information on node performance and can help you check if your validator is connected properly. Search for your node by name. You can search all nodes currently active on the network, which is why you should use a unique name for easy recognition. Now, confirm that your node is fully synced by comparing the block height of your node with the network's latest block. Nodes that are fully synced will appear white in the list, while nodes that are not yet fully synced will appear gray."} -{"page_id": "nodes-and-validators-run-a-validator-onboarding-and-offboarding-start-validating", "page_title": "Start Validating", "index": 8, "depth": 3, "title": "Activate using Polkadot.js Apps", "anchor": "activate-using-polkadotjs-apps", "start_char": 9807, "end_char": 11126, "estimated_token_count": 362, "token_estimator": "heuristic-v1", "text": "### Activate using Polkadot.js Apps\n\nFollow these steps to use Polkadot.js Apps to activate your validator:\n\n1. In Polkadot.js Apps, navigate to **Network** and select **Staking**:\n\n ![](/images/nodes-and-validators/run-a-validator/onboarding-and-offboarding/start-validating/start-validating-01.webp)\n\n2. Open the **Accounts** tab and click on **+ Validator**:\n\n ![](/images/nodes-and-validators/run-a-validator/onboarding-and-offboarding/start-validating/start-validating-02.webp)\n\n3. Set a bond amount in the **value bonded** field and then click **next**:\n\n ![](/images/nodes-and-validators/run-a-validator/onboarding-and-offboarding/start-validating/start-validating-03.webp)\n\n4. Paste the hex output from `author_rotateKeys`, set the commission, allow or block new nominations, then click **Bond & Validate** to link your validator with its session keys.\n\n ![](/images/nodes-and-validators/run-a-validator/onboarding-and-offboarding/start-validating/start-validating-04.webp)\n\n You can also set the **commission** and **blocked** nominations option via `staking.validate` extrinsic. By default, the blocked option is set to FALSE (i.e., the validator accepts nominations).\n\n ![](/images/nodes-and-validators/run-a-validator/onboarding-and-offboarding/start-validating/start-validating-05.webp)"} -{"page_id": "nodes-and-validators-run-a-validator-onboarding-and-offboarding-start-validating", "page_title": "Start Validating", "index": 9, "depth": 3, "title": "Monitor Validation Status and Slots", "anchor": "monitor-validation-status-and-slots", "start_char": 11126, "end_char": 12080, "estimated_token_count": 221, "token_estimator": "heuristic-v1", "text": "### Monitor Validation Status and Slots\n\nOn the [**Staking**](https://polkadot.js.org/apps/#/staking){target=\\_blank} tab in Polkadot.js Apps, you can see your validator's status, the number of available validator slots, and the nodes that have signaled their intent to validate. Your node may initially appear in the waiting queue, especially if the validator slots are full. The following is an example view of the **Staking** tab:\n\n![staking queue](/images/nodes-and-validators/run-a-validator/onboarding-and-offboarding/start-validating/start-validating-06.webp)\n\nThe validator set refreshes each era. If there's an available slot in the next era, your node may be selected to move from the waiting queue to the active validator set, allowing it to start validating blocks. If your validator is not selected, it remains in the waiting queue. Increasing your stake or gaining more nominators may improve your chance of being selected in future eras."} -{"page_id": "nodes-and-validators-run-a-validator-onboarding-and-offboarding-start-validating", "page_title": "Start Validating", "index": 10, "depth": 2, "title": "Run a Validator Using Systemd", "anchor": "run-a-validator-using-systemd", "start_char": 12080, "end_char": 13106, "estimated_token_count": 222, "token_estimator": "heuristic-v1", "text": "## Run a Validator Using Systemd\n\nRunning your Polkadot validator as a [systemd](https://en.wikipedia.org/wiki/Systemd){target=\\_blank} service is an effective way to ensure its high uptime and reliability. Using systemd allows your validator to automatically restart after server reboots or unexpected crashes, significantly reducing the risk of slashing due to downtime.\n\nThis following sections will walk you through creating and managing a systemd service for your validator, allowing you to seamlessly monitor and control it as part of your Linux system. \n\nEnsure the following requirements are met before proceeding with the systemd setup:\n\n- Confirm your system meets the [requirements](/nodes-and-validators/run-a-validator/requirements/){target=\\_blank} for running a validator.\n- Ensure you meet the [minimum bond requirements](https://wiki.polkadot.com/general/chain-state-values/#minimum-validator-bond){target=\\_blank} for validating.\n- Verify the Polkadot binary is [installed](#install-the-polkadot-binaries)."} -{"page_id": "nodes-and-validators-run-a-validator-onboarding-and-offboarding-start-validating", "page_title": "Start Validating", "index": 11, "depth": 3, "title": "Create the Systemd Service File", "anchor": "create-the-systemd-service-file", "start_char": 13106, "end_char": 14845, "estimated_token_count": 338, "token_estimator": "heuristic-v1", "text": "### Create the Systemd Service File\n\nFirst create a new unit file called `polkadot-validator.service` in `/etc/systemd/system/`:\n\n```bash\ntouch /etc/systemd/system/polkadot-validator.service\n```\n\nIn this unit file, you will write the commands that you want to run on server boot/restart:\n\n```systemd title=\"/etc/systemd/system/polkadot-validator.service\"\n[Unit]\nDescription=Polkadot Node\nAfter=network.target\nDocumentation=https://github.com/paritytech/polkadot-sdk\n\n[Service]\nEnvironmentFile=-/etc/default/polkadot\nExecStart=/usr/bin/polkadot $POLKADOT_CLI_ARGS\nUser=polkadot\nGroup=polkadot\nRestart=always\nRestartSec=120\nCapabilityBoundingSet=\nLockPersonality=true\nNoNewPrivileges=true\nPrivateDevices=true\nPrivateMounts=true\nPrivateTmp=true\nPrivateUsers=true\nProtectClock=true\nProtectControlGroups=true\nProtectHostname=true\nProtectKernelModules=true\nProtectKernelTunables=true\nProtectSystem=strict\nRemoveIPC=true\nRestrictAddressFamilies=AF_INET AF_INET6 AF_NETLINK AF_UNIX\nRestrictNamespaces=false\nRestrictSUIDSGID=true\nSystemCallArchitectures=native\nSystemCallFilter=@system-service\nSystemCallFilter=landlock_add_rule landlock_create_ruleset landlock_restrict_self seccomp mount umount2\nSystemCallFilter=~@clock @module @reboot @swap @privileged\nSystemCallFilter=pivot_root\nUMask=0027\n\n[Install]\nWantedBy=multi-user.target\n```\n\n!!! warning \"Restart delay and equivocation risk\"\n It is recommended that a node's restart be delayed with `RestartSec` in the case of a crash. It's possible that when a node crashes, consensus votes in GRANDPA aren't persisted to disk. In this case, there is potential to equivocate when immediately restarting. Delaying the restart will allow the network to progress past potentially conflicting votes."} -{"page_id": "nodes-and-validators-run-a-validator-onboarding-and-offboarding-start-validating", "page_title": "Start Validating", "index": 12, "depth": 3, "title": "Run the Service", "anchor": "run-the-service", "start_char": 14845, "end_char": 15820, "estimated_token_count": 243, "token_estimator": "heuristic-v1", "text": "### Run the Service\n\nActivate the systemd service to start on system boot by running:\n\n```bash\nsystemctl enable polkadot-validator.service\n```\n\nTo start the service manually, use:\n\n```bash\nsystemctl start polkadot-validator.service\n```\n\nCheck the service's status to confirm it is running:\n\n```bash\nsystemctl status polkadot-validator.service\n```\n\nTo view the logs in real-time, use [journalctl](https://www.freedesktop.org/software/systemd/man/latest/journalctl.html){target=\\_blank} like so:\n\n```bash\njournalctl -f -u polkadot-validator\n```\n\nWith these steps, you can effectively manage and monitor your validator as a systemd service.\n\nOnce your validator is active, it's officially part of Polkadot's security infrastructure. For questions or further support, you can reach out to the [Polkadot Validator chat](https://matrix.to/#/!NZrbtteFeqYKCUGQtr:matrix.parity.io?via=matrix.parity.io&via=matrix.org&via=web3.foundation){target=\\_blank} for tips and troubleshooting."} -{"page_id": "nodes-and-validators-run-a-validator-onboarding-and-offboarding-stop-validating", "page_title": "Stop Validating", "index": 0, "depth": 2, "title": "Introduction", "anchor": "introduction", "start_char": 19, "end_char": 498, "estimated_token_count": 89, "token_estimator": "heuristic-v1", "text": "## Introduction\n\nIf you're ready to stop validating on Polkadot, there are essential steps to ensure a smooth transition while protecting your funds and account integrity. Whether you're taking a break for maintenance or unbonding entirely, you'll need to chill your validator, purge session keys, and unbond your tokens. This guide explains how to use Polkadot's tools and extrinsics to safely withdraw from validation activities, safeguarding your account's future usability."} -{"page_id": "nodes-and-validators-run-a-validator-onboarding-and-offboarding-stop-validating", "page_title": "Stop Validating", "index": 1, "depth": 2, "title": "Pause Versus Stop", "anchor": "pause-versus-stop", "start_char": 498, "end_char": 920, "estimated_token_count": 83, "token_estimator": "heuristic-v1", "text": "## Pause Versus Stop\n\nIf you wish to remain a validator or nominator (for example, stopping for planned downtime or server maintenance), submitting the `chill` extrinsic in the `staking` pallet should suffice. Additional steps are only needed to unbond funds or reap an account.\n\nThe following are steps to ensure a smooth stop to validation:\n\n- Chill the validator.\n- Purge validator session keys.\n- Unbond your tokens."} -{"page_id": "nodes-and-validators-run-a-validator-onboarding-and-offboarding-stop-validating", "page_title": "Stop Validating", "index": 2, "depth": 2, "title": "Chill Validator", "anchor": "chill-validator", "start_char": 920, "end_char": 1501, "estimated_token_count": 121, "token_estimator": "heuristic-v1", "text": "## Chill Validator\n\nWhen stepping back from validating, the first step is to chill your validator status. This action stops your validator from being considered for the next era without fully unbonding your tokens, which can be useful for temporary pauses like maintenance or planned downtime.\n\nUse the `staking.chill` extrinsic to initiate this. For more guidance on chilling your node, refer to the [Pause Validating](/nodes-and-validators/run-a-validator/operational-tasks/pause-validating/){target=\\_blank} guide. You may also claim any pending staking rewards at this point."} -{"page_id": "nodes-and-validators-run-a-validator-onboarding-and-offboarding-stop-validating", "page_title": "Stop Validating", "index": 3, "depth": 2, "title": "Purge Validator Session Keys", "anchor": "purge-validator-session-keys", "start_char": 1501, "end_char": 2532, "estimated_token_count": 194, "token_estimator": "heuristic-v1", "text": "## Purge Validator Session Keys\n\nPurging validator session keys is a critical step in removing the association between your validator account and its session keys, which ensures that your account is fully disassociated from validator activities. The `session.purgeKeys` extrinsic removes the reference to your session keys from the stash or staking proxy account that originally set them.\n\nHere are a couple of important things to know about purging keys:\n\n- **Account used to purge keys**: Always use the same account to purge keys you originally used to set them, usually your stash or staking proxy account. Using a different account may leave an unremovable reference to the session keys on the original account, preventing its reaping.\n- **Account reaping issue**: Failing to purge keys will prevent you from reaping (fully deleting) your stash account. If you attempt to transfer tokens without purging, you'll need to rebond, purge the session keys, unbond again, and wait through the unbonding period before any transfer."} -{"page_id": "nodes-and-validators-run-a-validator-onboarding-and-offboarding-stop-validating", "page_title": "Stop Validating", "index": 4, "depth": 2, "title": "Unbond Your Tokens", "anchor": "unbond-your-tokens", "start_char": 2532, "end_char": 3230, "estimated_token_count": 142, "token_estimator": "heuristic-v1", "text": "## Unbond Your Tokens\n\nAfter chilling your node and purging session keys, the final step is to unbond your staked tokens. This action removes them from staking and begins the unbonding period (usually 28 days for Polkadot and seven days for Kusama), after which the tokens will be transferable.\n\nTo unbond tokens, go to **Network > Staking > Account Actions** on Polkadot.js Apps. Select your stash account, click on the dropdown menu, and choose **Unbond Funds**. Alternatively, you can use the `staking.unbond` extrinsic if you handle this via a staking proxy account.\n\nOnce the unbonding period is complete, your tokens will be available for use in transactions or transfers outside of staking."} -{"page_id": "nodes-and-validators-run-a-validator-operational-tasks-general-management", "page_title": "General Management", "index": 0, "depth": 2, "title": "Introduction", "anchor": "introduction", "start_char": 22, "end_char": 759, "estimated_token_count": 119, "token_estimator": "heuristic-v1", "text": "## Introduction\n\nValidator performance is pivotal in maintaining the security and stability of the Polkadot network. As a validator, optimizing your setup ensures efficient transaction processing, minimizes latency, and maintains system reliability during high-demand periods. Proper configuration and proactive monitoring also help mitigate risks like slashing and service interruptions.\n\nThis guide covers essential practices for managing a validator, including performance tuning techniques, security hardening, and tools for real-time monitoring. Whether you're fine-tuning CPU settings, configuring NUMA balancing, or setting up a robust alert system, these steps will help you build a resilient and efficient validator operation."} -{"page_id": "nodes-and-validators-run-a-validator-operational-tasks-general-management", "page_title": "General Management", "index": 1, "depth": 2, "title": "Configuration Optimization", "anchor": "configuration-optimization", "start_char": 759, "end_char": 987, "estimated_token_count": 35, "token_estimator": "heuristic-v1", "text": "## Configuration Optimization\n\nFor those seeking to optimize their validator's performance, the following configurations can improve responsiveness, reduce latency, and ensure consistent performance during high-demand periods."} -{"page_id": "nodes-and-validators-run-a-validator-operational-tasks-general-management", "page_title": "General Management", "index": 2, "depth": 3, "title": "Deactivate Simultaneous Multithreading", "anchor": "deactivate-simultaneous-multithreading", "start_char": 987, "end_char": 2478, "estimated_token_count": 333, "token_estimator": "heuristic-v1", "text": "### Deactivate Simultaneous Multithreading\n\nPolkadot validators operate primarily in single-threaded mode for critical tasks, so optimizing single-core CPU performance can reduce latency and improve stability. Deactivating simultaneous multithreading (SMT) can prevent virtual cores from affecting performance. SMT is called Hyper-Threading on Intel and 2-way SMT on AMD Zen.\n\nTake the following steps to deactivate every other (vCPU) core:\n\n1. Loop though all the CPU cores and deactivate the virtual cores associated with them:\n\n ```bash\n for cpunum in $(cat /sys/devices/system/cpu/cpu*/topology/thread_siblings_list | \\\n cut -s -d, -f2- | tr ',' '\\n' | sort -un)\n do\n echo 0 > /sys/devices/system/cpu/cpu$cpunum/online\n done\n ```\n\n2. To permanently save the changes, add `nosmt=force` to the `GRUB_CMDLINE_LINUX_DEFAULT` variable in `/etc/default/grub`:\n\n ```bash\n sudo nano /etc/default/grub\n # Add to GRUB_CMDLINE_LINUX_DEFAULT\n ```\n\n ```config title=\"/etc/default/grub\"\n GRUB_DEFAULT = 0;\n GRUB_HIDDEN_TIMEOUT = 0;\n GRUB_HIDDEN_TIMEOUT_QUIET = true;\n GRUB_TIMEOUT = 10;\n GRUB_DISTRIBUTOR = `lsb_release -i -s 2> /dev/null || echo Debian`;\n GRUB_CMDLINE_LINUX_DEFAULT = 'nosmt=force';\n GRUB_CMDLINE_LINUX = '';\n ```\n\n3. Update GRUB to apply changes:\n\n ```bash\n sudo update-grub\n ```\n\n4. After the reboot, you should see that half of the cores are offline. To confirm, run:\n\n ```bash\n lscpu --extended\n ```"} -{"page_id": "nodes-and-validators-run-a-validator-operational-tasks-general-management", "page_title": "General Management", "index": 3, "depth": 3, "title": "Deactivate Automatic NUMA Balancing", "anchor": "deactivate-automatic-numa-balancing", "start_char": 2478, "end_char": 3554, "estimated_token_count": 220, "token_estimator": "heuristic-v1", "text": "### Deactivate Automatic NUMA Balancing\n\nDeactivating NUMA (Non-Uniform Memory Access) balancing for multi-CPU setups helps keep processes on the same CPU node, minimizing latency.\n\nFollow these stpes:\n\n1. Deactivate NUMA balancing in runtime:\n\n ```bash\n sysctl kernel.numa_balancing=0\n ```\n\n2. Deactivate NUMA balancing permanently by adding `numa_balancing=disable` to the GRUB settings:\n\n ```bash\n sudo nano /etc/default/grub\n # Add to GRUB_CMDLINE_LINUX_DEFAULT\n ```\n\n ```config title=\"/etc/default/grub\"\n GRUB_DEFAULT = 0;\n GRUB_HIDDEN_TIMEOUT = 0;\n GRUB_HIDDEN_TIMEOUT_QUIET = true;\n GRUB_TIMEOUT = 10;\n GRUB_DISTRIBUTOR = `lsb_release -i -s 2> /dev/null || echo Debian`;\n GRUB_CMDLINE_LINUX_DEFAULT = 'numa_balancing=disable';\n GRUB_CMDLINE_LINUX = '';\n ```\n\n3. Update GRUB to apply changes:\n\n ```bash\n sudo update-grub\n ```\n\n4. Confirm the deactivation:\n\n ```bash\n sysctl -a | grep 'kernel.numa_balancing'\n ```\n\nIf you successfully deactivated NUMA balancing, the preceding command should return `0`."} -{"page_id": "nodes-and-validators-run-a-validator-operational-tasks-general-management", "page_title": "General Management", "index": 4, "depth": 3, "title": "Spectre and Meltdown Mitigations", "anchor": "spectre-and-meltdown-mitigations", "start_char": 3554, "end_char": 5210, "estimated_token_count": 319, "token_estimator": "heuristic-v1", "text": "### Spectre and Meltdown Mitigations\n\n[Spectre](https://en.wikipedia.org/wiki/Spectre_(security_vulnerability)){target=\\_blank} and [Meltdown](https://en.wikipedia.org/wiki/Meltdown_(security_vulnerability)){target=\\_blank} are well-known CPU vulnerabilities that exploit speculative execution to access sensitive data. These vulnerabilities have been patched in recent Linux kernels, but the mitigations can slightly impact performance, especially in high-throughput or containerized environments.\n\nIf your security requirements allow it, you can deactivate specific mitigations, such as Spectre V2 and Speculative Store Bypass Disable (SSBD), to improve performance.\n\nTo selectively deactivate the Spectre mitigations, take these steps:\n\n1. Update the `GRUB_CMDLINE_LINUX_DEFAULT` variable in your `/etc/default/grub` configuration:\n\n ```bash\n sudo nano /etc/default/grub\n # Add to GRUB_CMDLINE_LINUX_DEFAULT\n ```\n\n ```config title=\"/etc/default/grub\"\n GRUB_DEFAULT = 0;\n GRUB_HIDDEN_TIMEOUT = 0;\n GRUB_HIDDEN_TIMEOUT_QUIET = true;\n GRUB_TIMEOUT = 10;\n GRUB_DISTRIBUTOR = `lsb_release -i -s 2> /dev/null || echo Debian`;\n GRUB_CMDLINE_LINUX_DEFAULT =\n 'spec_store_bypass_disable=prctl spectre_v2_user=prctl';\n ```\n\n2. Update GRUB to apply changes and then reboot:\n\n ```bash\n sudo update-grub\n sudo reboot\n ```\n\nThis approach selectively deactivates the Spectre V2 and Spectre V4 mitigations, leaving other protections intact. For full security, keep mitigations activated unless there's a significant performance need, as disabling them could expose the system to potential attacks on affected CPUs."} -{"page_id": "nodes-and-validators-run-a-validator-operational-tasks-general-management", "page_title": "General Management", "index": 5, "depth": 2, "title": "Monitor Your Node", "anchor": "monitor-your-node", "start_char": 5210, "end_char": 5907, "estimated_token_count": 167, "token_estimator": "heuristic-v1", "text": "## Monitor Your Node\n\nMonitoring your node's performance is critical for network reliability and security. Tools like the following provide valuable insights:\n\n- **[Prometheus](https://prometheus.io/){target=\\_blank}**: An open-source monitoring toolkit for collecting and querying time-series data.\n- **[Grafana](https://grafana.com/){target=\\_blank}**: A visualization tool for real-time metrics, providing interactive dashboards.\n- **[Alertmanager](https://prometheus.io/docs/alerting/latest/alertmanager/){target=\\_blank}**: A tool for managing and routing alerts based on Prometheus data.\n\nThis section covers setting up these tools and configuring alerts to notify you of potential issues."} -{"page_id": "nodes-and-validators-run-a-validator-operational-tasks-general-management", "page_title": "General Management", "index": 6, "depth": 3, "title": "Environment Setup", "anchor": "environment-setup", "start_char": 5907, "end_char": 6601, "estimated_token_count": 141, "token_estimator": "heuristic-v1", "text": "### Environment Setup\n\nBefore installing Prometheus, ensure the environment is set up securely by running Prometheus with restricted user privileges.\n\nFollow these steps:\n\n1. Create a Prometheus user to ensure Prometheus runs with minimal permissions:\n\n ```bash\n sudo useradd --no-create-home --shell /usr/sbin/nologin prometheus\n ```\n\n2. Create directories for configuration and data storage:\n\n ```bash\n sudo mkdir /etc/prometheus\n sudo mkdir /var/lib/prometheus\n ```\n \n3. Change directory ownership to ensure Prometheus has access:\n\n ```bash\n sudo chown -R prometheus:prometheus /etc/prometheus\n sudo chown -R prometheus:prometheus /var/lib/prometheus\n ```"} -{"page_id": "nodes-and-validators-run-a-validator-operational-tasks-general-management", "page_title": "General Management", "index": 7, "depth": 3, "title": "Install and Configure Prometheus", "anchor": "install-and-configure-prometheus", "start_char": 6601, "end_char": 9085, "estimated_token_count": 545, "token_estimator": "heuristic-v1", "text": "### Install and Configure Prometheus\n\nAfter setting up the environment, install and configure the latest version of Prometheus as follows:\n\n1. Download Prometheus for your system architecture from the [releases page](https://github.com/prometheus/prometheus/releases/){target=\\_blank}. Replace `INSERT_RELEASE_DOWNLOAD` with the release binary URL (e.g., `https://github.com/prometheus/prometheus/releases/download/v3.0.0/prometheus-3.0.0.linux-amd64.tar.gz`):\n\n ```bash\n sudo apt-get update && sudo apt-get upgrade\n wget INSERT_RELEASE_DOWNLOAD_LINK\n tar xfz prometheus-*.tar.gz\n cd prometheus-3.0.0.linux-amd64\n ```\n\n2. Set up Prometheus:\n\n 1. Copy binaries:\n\n ```bash\n sudo cp ./prometheus /usr/local/bin/\n sudo cp ./promtool /usr/local/bin/\n sudo cp ./prometheus /usr/local/bin/\n ```\n\n 2. Copy directories and assign ownership of these files to the `prometheus` user:\n\n ```bash\n sudo cp -r ./consoles /etc/prometheus\n sudo cp -r ./console_libraries /etc/prometheus\n sudo chown -R prometheus:prometheus /etc/prometheus/consoles\n sudo chown -R prometheus:prometheus /etc/prometheus/console_libraries\n ```\n\n 3. Clean up the download directory:\n\n ```bash\n cd .. && rm -r prometheus*\n ```\n\n3. Create `prometheus.yml` to define global settings, rule files, and scrape targets:\n\n ```bash\n sudo nano /etc/prometheus/prometheus.yml\n ```\n\n {% raw %}\n ```yaml title=\"prometheus-config.yml\"\n global:\n scrape_interval: 15s\n evaluation_interval: 15s\n\n rule_files:\n # - \"first.rules\"\n # - \"second.rules\"\n\n scrape_configs:\n - job_name: 'prometheus'\n scrape_interval: 5s\n static_configs:\n - targets: ['localhost:9090']\n - job_name: 'substrate_node'\n scrape_interval: 5s\n static_configs:\n - targets: ['localhost:9615']\n ```\n {% endraw %}\n\n Prometheus is scraped every 5 seconds in this example configuration file, ensuring detailed internal metrics. Node metrics with customizable intervals are scraped from port `9615` by default.\n\n4. Verify the configuration with `promtool`, an open source monitoring tool:\n\n ```bash\n promtool check config /etc/prometheus/prometheus.yml\n ```\n\n5. Save the configuration and change the ownership of the file to `prometheus` user:\n\n ```bash\n sudo chown prometheus:prometheus /etc/prometheus/prometheus.yml\n ```"} -{"page_id": "nodes-and-validators-run-a-validator-operational-tasks-general-management", "page_title": "General Management", "index": 8, "depth": 3, "title": "Start Prometheus", "anchor": "start-prometheus", "start_char": 9085, "end_char": 10918, "estimated_token_count": 410, "token_estimator": "heuristic-v1", "text": "### Start Prometheus\n\n1. Launch Prometheus with the appropriate configuration file, storage location, and necessary web resources, running it with restricted privileges for security:\n\n ```bash\n sudo -u prometheus /usr/local/bin/prometheus --config.file /etc/prometheus/prometheus.yml \\\n --storage.tsdb.path /var/lib/prometheus/ \\\n --web.console.templates=/etc/prometheus/consoles \\\n --web.console.libraries=/etc/prometheus/console_libraries\n ```\n\n If you set the server up properly, you should see terminal output similar to the following:\n\n \n2. Verify you can access the Prometheus interface by navigating to:\n\n ```text\n http://SERVER_IP_ADDRESS:9090/graph\n ```\n\n If the interface appears to work as expected, exit the process using `Control + C`.\n\n3. Create a systemd service file to ensure Prometheus starts on boot:\n\n ```bash\n sudo nano /etc/systemd/system/prometheus.service\n ```\n\n ```bash title=\"prometheus.service\"\n [Unit]\n Description=Prometheus Monitoring\n Wants=network-online.target\n After=network-online.target\n\n [Service]\n User=prometheus\n Group=prometheus\n Type=simple\n ExecStart=/usr/local/bin/prometheus \\\n --config.file /etc/prometheus/prometheus.yml \\\n --storage.tsdb.path /var/lib/prometheus/ \\\n --web.console.templates=/etc/prometheus/consoles \\\n --web.console.libraries=/etc/prometheus/console_libraries\n ExecReload=/bin/kill -HUP $MAINPID\n\n [Install]\n WantedBy=multi-user.target\n\n ```\n\n4. Reload systemd and enable the service to start on boot:\n\n ```bash\n sudo systemctl daemon-reload && sudo systemctl enable prometheus && sudo systemctl start prometheus\n ```\n\n5. Verify the service is running by visiting the Prometheus interface again at:\n\n ```text\n http://SERVER_IP_ADDRESS:9090/\n ```"} -{"page_id": "nodes-and-validators-run-a-validator-operational-tasks-general-management", "page_title": "General Management", "index": 9, "depth": 3, "title": "Install and Configure Grafana", "anchor": "install-and-configure-grafana", "start_char": 10918, "end_char": 14591, "estimated_token_count": 931, "token_estimator": "heuristic-v1", "text": "### Install and Configure Grafana\n\nThis guide follows [Grafana's canonical installation instructions](https://grafana.com/docs/grafana/latest/setup-grafana/installation/debian/#install-from-apt-repository){target=\\_blank}.\n\nTo install and configure Grafana, follow these steps:\n\n1. Install Grafana prerequisites:\n\n ```bash\n sudo apt-get install -y apt-transport-https software-properties-common wget \n ```\n\n2. Import the [GPG key](https://gnupg.org/){target=\\_blank}:\n\n ```bash\n sudo mkdir -p /etc/apt/keyrings/\n wget -q -O - https://apt.grafana.com/gpg.key | gpg --dearmor | sudo tee /etc/apt/keyrings/grafana.gpg > /dev/null\n ```\n\n3. Configure the stable release repo and update packages:\n\n ```bash\n echo \"deb [signed-by=/etc/apt/keyrings/grafana.gpg] https://apt.grafana.com stable main\" | sudo tee -a /etc/apt/sources.list.d/grafana.list\n sudo apt-get update\n ```\n\n4. Install the latest stable version of Grafana:\n\n ```bash\n sudo apt-get install grafana\n ```\n\nTo configure Grafana, take these steps:\n\n1. Configure Grafana to start automatically on boot and start the service:\n\n ```bash\n sudo systemctl daemon-reload\n sudo systemctl enable grafana-server.service\n sudo systemctl start grafana-server\n ```\n\n2. Check if Grafana is running:\n\n ```bash\n sudo systemctl status grafana-server\n ```\n\n If necessary, you can stop or restart the service with the following commands:\n\n ```bash\n sudo systemctl stop grafana-server\n sudo systemctl restart grafana-server\n ```\n\n3. Access Grafana by navigating to the following URL and logging in with the default username and password (`admin`):\n\n ```text\n http://SERVER_IP_ADDRESS:3000/login\n ```\n\n !!! tip \"Change default port\"\n To change Grafana's port, edit `/usr/share/grafana/conf/defaults.ini`:\n\n ```bash\n sudo vim /usr/share/grafana/conf/defaults.ini\n ```\n\n Modify the `http_port` value, then restart Grafana:\n\n ```bash\n sudo systemctl restart grafana-server\n ```\n\n![Grafana login screen](/images/nodes-and-validators/run-a-validator/operational-tasks/general-management/general-management-01.webp)\n\nTo visualize node metrics, follow these steps:\n\n1. Select the gear icon to access **Data Sources** settings.\n2. Select **Add data source** to define the data source.\n\n ![Select Prometheus](/images/nodes-and-validators/run-a-validator/operational-tasks/general-management/general-management-02.webp)\n\n3. Select **Prometheus**.\n\n ![Save and test](/images/nodes-and-validators/run-a-validator/operational-tasks/general-management/general-management-03.webp)\n\n4. Enter `http://localhost:9090` in the **URL** field and click **Save & Test**. If **\"Data source is working\"** appears, your connection is configured correctly.\n\n ![Import dashboard](/images/nodes-and-validators/run-a-validator/operational-tasks/general-management/general-management-04.webp)\n\n5. Select **Import** from the left menu, choose **Prometheus** from the dropdown, and click **Import**.\n\n6. Start your Polkadot node by running `./polkadot`. You should now be able to monitor node performance, block height, network traffic, and tasks tasks on the Grafana dashboard.\n\n ![Live dashboard](/images/nodes-and-validators/run-a-validator/operational-tasks/general-management/general-management-05.webp)\n\nThe [Grafana dashboards](https://grafana.com/grafana/dashboards){target=\\_blank} page features user created dashboards made available for public use. For an example, see the [Substrate Node Metrics](https://grafana.com/grafana/dashboards/21715-substrate-node-metrics/){target=\\_blank} dashboard."} -{"page_id": "nodes-and-validators-run-a-validator-operational-tasks-general-management", "page_title": "General Management", "index": 10, "depth": 3, "title": "Install and Configure Alertmanager", "anchor": "install-and-configure-alertmanager", "start_char": 14591, "end_char": 22147, "estimated_token_count": 1677, "token_estimator": "heuristic-v1", "text": "### Install and Configure Alertmanager\n\n[Alertmanager](https://prometheus.io/docs/alerting/latest/alertmanager/){target=\\_blank} is an optional component that complements Prometheus by managing alerts and notifying users about potential issues.\n\nFollow these steps to install and configure Alertmanager:\n\n1. Download Alertmanager for your system architecture from the [releases page](https://github.com/prometheus/alertmanager/releases){target=\\_blank}. Replace `INSERT_RELEASE_DOWNLOAD` with the release binary URL (e.g., `https://github.com/prometheus/alertmanager/releases/download/v0.28.0-rc.0/alertmanager-0.28.0-rc.0.linux-amd64.tar.gz`):\n\n ```bash\n wget INSERT_RELEASE_DOWNLOAD_LINK\n tar -xvzf alertmanager*\n ```\n\n2. Copy the binaries to the system directory and set permissions:\n\n ```bash\n cd alertmanager-0.28.0-rc.0.linux-amd64\n sudo cp ./alertmanager /usr/local/bin/\n sudo cp ./amtool /usr/local/bin/\n sudo chown prometheus:prometheus /usr/local/bin/alertmanager\n sudo chown prometheus:prometheus /usr/local/bin/amtool\n ```\n\n3. Create the `alertmanager.yml` configuration file under `/etc/alertmanager`:\n\n ```bash\n sudo mkdir /etc/alertmanager\n sudo nano /etc/alertmanager/alertmanager.yml\n ```\n\n Generate an [app password in your Google account](https://support.google.com/accounts/answer/185833?hl=en){target=\\_blank} to enable email notifications from Alertmanager. Then, add the following code to the configuration file to define email notifications using your email and app password: \n\n {% raw %}\n ```yml title=\"alertmanager.yml\"\n global:\n resolve_timeout: 1m\n\n route:\n receiver: 'gmail-notifications'\n\n receivers:\n - name: 'gmail-notifications'\n email_configs:\n - to: INSERT_YOUR_EMAIL\n from: INSERT_YOUR_EMAIL\n smarthost: smtp.gmail.com:587\n auth_username: INSERT_YOUR_EMAIL\n auth_identity: INSERT_YOUR_EMAIL\n auth_password: INSERT_YOUR_APP_PASSWORD\n send_resolved: true\n\n ```\n {% endraw %}\n\n\n ```bash\n sudo chown -R prometheus:prometheus /etc/alertmanager\n ```\n\n4. Configure Alertmanager as a service by creating a systemd service file:\n\n ```bash\n sudo nano /etc/systemd/system/alertmanager.service\n ```\n\n {% raw %}\n ```yml title=\"alertmanager.service\"\n [Unit]\n Description=AlertManager Server Service\n Wants=network-online.target\n After=network-online.target\n\n [Service]\n User=root\n Group=root\n Type=simple\n ExecStart=/usr/local/bin/alertmanager --config.file /etc/alertmanager/alertmanager.yml --web.external-url=http://SERVER_IP:9093 --cluster.advertise-address='0.0.0.0:9093'\n\n [Install]\n WantedBy=multi-user.target\n\n ```\n {% endraw %}\n\n5. Reload and enable the service:\n\n ```bash\n sudo systemctl daemon-reload\n sudo systemctl enable alertmanager\n sudo systemctl start alertmanager\n ```\n\n6. Verify the service status:\n\n ```bash\n sudo systemctl status alertmanager\n ```\n\n If you have configured Alertmanager properly, the **Active** field should display **active (running)** similar to below:\n\n
\n sudo systemctl status alertmanager\n alertmanager.service - AlertManager Server Service\n Loaded: loaded (/etc/systemd/system/alertmanager.service; enabled; vendor preset: enabled)\n Active: active (running) since Thu 2020-08-20 22:01:21 CEST; 3 days ago\n Main PID: 20592 (alertmanager)\n Tasks: 70 (limit: 9830)\n CGroup: /system.slice/alertmanager.service\n \n
\n\n#### Grafana Plugin\n\nThere is an [Alertmanager plugin in Grafana](https://grafana.com/grafana/plugins/alertmanager/){target=\\_blank} that can help you monitor alert information.\n\nFollow these steps to use the plugin:\n\n1. Install the plugin:\n\n ```bash\n sudo grafana-cli plugins install camptocamp-prometheus-alertmanager-datasource\n ```\n\n2. Restart Grafana:\n\n ```bash\n sudo systemctl restart grafana-server\n ```\n\n3. Configure Alertmanager as a data source in your Grafana dashboard (`SERVER_IP:3000`):\n\n 1. Go to **Configuration** > **Data Sources** and search for **Prometheus Alertmanager**.\n 2. Enter the server URL and port for the Alertmanager service, and select **Save & Test** to verify the connection.\n\n4. Import the [8010](https://grafana.com/grafana/dashboards/8010-prometheus-alertmanager/){target=\\_blank} dashboard for Alertmanager, selecting **Prometheus Alertmanager** in the last column, then select **Import**.\n\n#### Integrate Alertmanager\n\nComplete the integration by following these steps to enable communication between Prometheus and Alertmanager and configure detection and alert rules:\n\n1. Update the `etc/prometheus/prometheus.yml` configuration file to include the following code:\n\n {% raw %}\n ```yml title=\"prometheus.yml\"\n rule_files:\n - 'rules.yml'\n\n alerting:\n alertmanagers:\n - static_configs:\n - targets:\n - localhost:9093\n ```\n {% endraw %}\n\n Expand the following item to view the complete `prometheus.yml` file.\n\n ??? code \"prometheus.yml\"\n\n {% raw %}\n ```yml title=\"prometheus.yml\"\n global:\n scrape_interval: 15s\n evaluation_interval: 15s\n\n rule_files:\n - 'rules.yml'\n\n alerting:\n alertmanagers:\n - static_configs:\n - targets:\n - localhost:9093\n\n scrape_configs:\n - job_name: 'prometheus'\n scrape_interval: 5s\n static_configs:\n - targets: ['localhost:9090']\n - job_name: 'substrate_node'\n scrape_interval: 5s\n static_configs:\n - targets: ['localhost:9615']\n\n ```\n {% endraw %}\n\n2. Create the rules file for detection and alerts:\n\n ```bash\n sudo nano /etc/prometheus/rules.yml\n ```\n\n Add a sample rule to trigger email notifications for node downtime over five minutes:\n\n {% raw %}\n ```yml title=\"rules.yml\"\n groups:\n - name: alert_rules\n rules:\n - alert: InstanceDown\n expr: up == 0\n for: 5m\n labels:\n severity: critical\n annotations:\n summary: 'Instance [{{ $labels.instance }}] down'\n description: '[{{ $labels.instance }}] of job [{{ $labels.job }}] has been down for more than 5 minutes.'\n\n ```\n {% endraw %}\n\n If any of the conditions defined in the rules file are met, an alert will be triggered. For more on alert rules, refer to [Alerting Rules](https://prometheus.io/docs/prometheus/latest/configuration/alerting_rules/){target=\\_blank} and [additional alerts](https://samber.github.io/awesome-prometheus-alerts/rules.html){target=\\_blank}.\n\n3. Update the file ownership to `prometheus`:\n\n ```bash\n sudo chown prometheus:prometheus rules.yml\n ```\n\n4. Validate the rules syntax:\n\n ```bash\n sudo -u prometheus promtool check rules rules.yml\n ```\n\n5. Restart Prometheus and Alertmanager:\n\n ```bash\n sudo systemctl restart prometheus && sudo systemctl restart alertmanager\n ```\n\nNow you will receive an email alert if one of your rule triggering conditions is met."} -{"page_id": "nodes-and-validators-run-a-validator-operational-tasks-general-management", "page_title": "General Management", "index": 11, "depth": 2, "title": "Secure Your Validator", "anchor": "secure-your-validator", "start_char": 22147, "end_char": 22499, "estimated_token_count": 58, "token_estimator": "heuristic-v1", "text": "## Secure Your Validator\n\nValidators in Polkadot's Proof of Stake (PoS) network play a critical role in maintaining network integrity and security by keeping the network in consensus and verifying state transitions. To ensure optimal performance and minimize risks, validators must adhere to strict guidelines around security and reliable operations."} -{"page_id": "nodes-and-validators-run-a-validator-operational-tasks-general-management", "page_title": "General Management", "index": 12, "depth": 3, "title": "Key Management", "anchor": "key-management", "start_char": 22499, "end_char": 23790, "estimated_token_count": 275, "token_estimator": "heuristic-v1", "text": "### Key Management\n\nThough they don't transfer funds, session keys are essential for validators as they sign messages related to consensus and parachains. Securing session keys is crucial as allowing them to be exploited or used across multiple nodes can lead to a loss of staked funds via [slashing](/nodes-and-validators/run-a-validator/staking-mechanics/offenses-and-slashes/){target=\\_blank}.\n\nGiven the current limitations in high-availability setups and the risks associated with double-signing, it’s recommended to run only a single validator instance. Keys should be securely managed, and processes automated to minimize human error.\n\nThere are two approaches for generating session keys:\n\n- **Generate and store in node**: Using the `author.rotateKeys` RPC call. For most users, generating keys directly within the client is recommended. You must submit a session certificate from your staking proxy to register new keys. See the [How to Validate](/nodes-and-validators/run-a-validator/onboarding-and-offboarding/set-up-validator/){target=\\_blank} guide for instructions on setting keys.\n\n- **Generate outside node and insert**: Using the `author.setKeys` RPC call. This flexibility accommodates advanced security setups and should only be used by experienced validator operators."} -{"page_id": "nodes-and-validators-run-a-validator-operational-tasks-general-management", "page_title": "General Management", "index": 13, "depth": 3, "title": "Signing Outside the Client", "anchor": "signing-outside-the-client", "start_char": 23790, "end_char": 24082, "estimated_token_count": 50, "token_estimator": "heuristic-v1", "text": "### Signing Outside the Client\n\nPolkadot plans to support external signing, allowing session keys to reside in secure environments like Hardware Security Modules (HSMs). However, these modules can sign any payload they receive, potentially enabling an attacker to perform slashable actions."} -{"page_id": "nodes-and-validators-run-a-validator-operational-tasks-general-management", "page_title": "General Management", "index": 14, "depth": 3, "title": "Secure-Validator Mode", "anchor": "secure-validator-mode", "start_char": 24082, "end_char": 24843, "estimated_token_count": 169, "token_estimator": "heuristic-v1", "text": "### Secure-Validator Mode\n\nPolkadot's Secure-Validator mode offers an extra layer of protection through strict filesystem, networking, and process sandboxing. This secure mode is activated by default if the machine meets the following requirements:\n\n- **Linux (x86-64 architecture)**: Usually Intel or AMD.\n- **Enabled `seccomp`**: This kernel feature facilitates a more secure approach for process management on Linux. Verify by running.\n\n ```bash\n cat /boot/config-`uname -r` | grep CONFIG_SECCOMP=\n ```\n\n If `seccomp` is enabled, you should see output similar to the following:\n\n ```bash\n CONFIG_SECCOMP=y\n ```\n\n!!! tip \n Optionally, **Linux 5.13** may also be used, as it provides access to even more strict filesystem protections."} -{"page_id": "nodes-and-validators-run-a-validator-operational-tasks-general-management", "page_title": "General Management", "index": 15, "depth": 3, "title": "Linux Best Practices", "anchor": "linux-best-practices", "start_char": 24843, "end_char": 25301, "estimated_token_count": 107, "token_estimator": "heuristic-v1", "text": "### Linux Best Practices\n\nFollow these best practices to keep your validator secure:\n\n- Use a non-root user for all operations.\n- Regularly apply OS security patches.\n- Enable and configure a firewall.\n- Use key-based SSH authentication; deactivate password-based login.\n- Regularly back up data and harden your SSH configuration. Visit this [SSH guide](https://blog.stribik.technology/2015/01/04/secure-secure-shell.html){target=\\_blank} for more details."} -{"page_id": "nodes-and-validators-run-a-validator-operational-tasks-general-management", "page_title": "General Management", "index": 16, "depth": 3, "title": "Validator Best Practices", "anchor": "validator-best-practices", "start_char": 25301, "end_char": 26059, "estimated_token_count": 147, "token_estimator": "heuristic-v1", "text": "### Validator Best Practices\n\nAdditional best practices can add an additional layer of security and operational reliability:\n\n- Only run the Polkadot binary, and only listen on the configured p2p port.\n- Run on bare-metal machines, as opposed to virtual machines.\n- Provisioning of the validator machine should be automated and defined in code which is kept in private version control, reviewed, audited, and tested.\n- Generate and provide session keys in a secure way.\n- Start Polkadot at boot and restart if stopped for any reason.\n- Run Polkadot as a non-root user.\n- Establish and maintain an on-call rotation for managing alerts.\n- Establish and maintain a clear protocol with actions to perform for each level of each alert with an escalation policy."} -{"page_id": "nodes-and-validators-run-a-validator-operational-tasks-general-management", "page_title": "General Management", "index": 17, "depth": 2, "title": "Additional Resources", "anchor": "additional-resources", "start_char": 26059, "end_char": 26673, "estimated_token_count": 163, "token_estimator": "heuristic-v1", "text": "## Additional Resources\n\n- [Certus One's Knowledge Base](https://knowledgebase.certus.com/FAQ/){target=\\_blank}\n- [EOS Block Producer Security List](https://github.com/slowmist/eos-bp-nodes-security-checklist){target=\\_blank}\n- [HSM Policies and the Importance of Validator Security](https://medium.com/loom-network/hsm-policies-and-the-importance-of-validator-security-ec8a4cc1b6f){target=\\_blank}\n\nFor additional guidance, connect with other validators and the Polkadot engineering team in the [Polkadot Validator Lounge](https://matrix.to/#/#polkadotvalidatorlounge:web3.foundation){target=\\_blank} on Element."} -{"page_id": "nodes-and-validators-run-a-validator-operational-tasks-pause-validating", "page_title": "Pause Validating", "index": 0, "depth": 2, "title": "Introduction", "anchor": "introduction", "start_char": 20, "end_char": 554, "estimated_token_count": 93, "token_estimator": "heuristic-v1", "text": "## Introduction\n\nIf you need to temporarily stop participating in Polkadot staking activities without fully unbonding your funds, chilling your account allows you to do so efficiently. Chilling removes your node from active validation or nomination in the next era while keeping your funds bonded, making it ideal for planned downtimes or temporary pauses.\n\nThis guide covers the steps for chilling as a validator or nominator, using the `chill` and `chillOther` extrinsics, and how these affect your staking status and nominations."} -{"page_id": "nodes-and-validators-run-a-validator-operational-tasks-pause-validating", "page_title": "Pause Validating", "index": 1, "depth": 2, "title": "Chilling Your Node", "anchor": "chilling-your-node", "start_char": 554, "end_char": 1176, "estimated_token_count": 155, "token_estimator": "heuristic-v1", "text": "## Chilling Your Node\n\nIf you need to temporarily step back from staking without unbonding your funds, you can \"chill\" your account. Chilling pauses your active staking participation, setting your account to inactive in the next era while keeping your funds bonded.\n\nTo chill your account, go to the **Network > Staking > Account Actions** page on [Polkadot.js Apps](https://polkadot.js.org/apps){target=\\_blank}, and select **Stop**. Alternatively, you can call the [`chill`](https://paritytech.github.io/polkadot-sdk/master/pallet_staking/enum.Call.html#variant.chill){target=\\_blank} extrinsic in the Staking pallet."} -{"page_id": "nodes-and-validators-run-a-validator-operational-tasks-pause-validating", "page_title": "Pause Validating", "index": 2, "depth": 2, "title": "Staking Election Timing Considerations", "anchor": "staking-election-timing-considerations", "start_char": 1176, "end_char": 1777, "estimated_token_count": 123, "token_estimator": "heuristic-v1", "text": "## Staking Election Timing Considerations\n\nWhen a node actively participates in staking but then chills, it will continue contributing for the remainder of the current era. However, its eligibility for the next election depends on the chill status at the start of the new era:\n\n- **Chilled during previous era**: Will not participate in the current era election and will remain inactive until reactivated.\n- **Chilled during current era**: Will not be selected for the next era's election.\n- **Chilled after current era**: May be selected if it was active during the previous era and is now chilled."} -{"page_id": "nodes-and-validators-run-a-validator-operational-tasks-pause-validating", "page_title": "Pause Validating", "index": 3, "depth": 2, "title": "Chilling as a Nominator", "anchor": "chilling-as-a-nominator", "start_char": 1777, "end_char": 2554, "estimated_token_count": 142, "token_estimator": "heuristic-v1", "text": "## Chilling as a Nominator\n\nWhen you choose to chill as a nominator, your active nominations are reset. Upon re-entering the nominating process, you must reselect validators to support manually. Depending on preferences, these can be the same validators as before or a new set. Remember that your previous nominations won’t be saved or automatically reactivated after chilling.\n\nWhile chilled, your nominator account remains bonded, preserving your staked funds without requiring a full unbonding process. When you’re ready to start nominating again, you can issue a new nomination call to activate your bond with a fresh set of validators. This process bypasses the need for re-bonding, allowing you to maintain your stake while adjusting your involvement in active staking."} -{"page_id": "nodes-and-validators-run-a-validator-operational-tasks-pause-validating", "page_title": "Pause Validating", "index": 4, "depth": 2, "title": "Chilling as a Validator", "anchor": "chilling-as-a-validator", "start_char": 2554, "end_char": 3452, "estimated_token_count": 157, "token_estimator": "heuristic-v1", "text": "## Chilling as a Validator\n\nWhen you chill as a validator, your active validator status is paused. Although your nominators remain bonded to you, the validator bond will no longer appear as an active choice for new or revised nominations until reactivated. Any existing nominators who take no action will still have their stake linked to the validator, meaning they don’t need to reselect the validator upon reactivation. However, if nominators adjust their stakes while the validator is chilled, they will not be able to nominate the chilled validator until it resumes activity.\n\nUpon reactivating as a validator, you must also reconfigure your validator preferences, such as commission rate and other parameters. These can be set to match your previous configuration or updated as desired. This step is essential for rejoining the active validator set and regaining eligibility for nominations."} -{"page_id": "nodes-and-validators-run-a-validator-operational-tasks-pause-validating", "page_title": "Pause Validating", "index": 5, "depth": 2, "title": "Chill Other", "anchor": "chill-other", "start_char": 3452, "end_char": 4439, "estimated_token_count": 191, "token_estimator": "heuristic-v1", "text": "## Chill Other\n\nHistorical constraints in the runtime prevented unlimited nominators and validators from being supported. These constraints created a need for checks to keep the size of the staking system manageable. One of these checks is the `chillOther` extrinsic, allowing users to chill accounts that no longer met standards such as minimum staking requirements set through on-chain governance.\n\nThis control mechanism included a `ChillThreshold`, which was structured to define how close to the maximum number of nominators or validators the staking system would be allowed to get before users could start chilling one another. With the passage of [Referendum #90](https://polkadot-old.polkassembly.io/referendum/90){target=\\_blank}, the value for `maxNominatorCount` on Polkadot was set to `None`, effectively removing the limit on how many nominators and validators can participate. This means the `ChillThreshold` will never be met; thus, `chillOther` no longer has any effect."} -{"page_id": "nodes-and-validators-run-a-validator-operational-tasks-upgrade-your-node", "page_title": "Upgrade a Validator Node", "index": 0, "depth": 2, "title": "Introduction", "anchor": "introduction", "start_char": 28, "end_char": 821, "estimated_token_count": 123, "token_estimator": "heuristic-v1", "text": "## Introduction\n\nUpgrading a Polkadot validator node is essential for staying current with network updates and maintaining optimal performance. This guide covers routine and extended maintenance scenarios, including software upgrades and major server changes. Following these steps, you can manage session keys and transition smoothly between servers without risking downtime, slashing, or network disruptions. The process requires strategic planning, especially if you need to perform long-lead maintenance, ensuring your validator remains active and compliant.\n\nThis guide will allow validators to seamlessly substitute an active validator server to allow for maintenance operations. The process can take several hours, so ensure you understand the instructions first and plan accordingly."} -{"page_id": "nodes-and-validators-run-a-validator-operational-tasks-upgrade-your-node", "page_title": "Upgrade a Validator Node", "index": 1, "depth": 2, "title": "Prerequisites", "anchor": "prerequisites", "start_char": 821, "end_char": 1378, "estimated_token_count": 122, "token_estimator": "heuristic-v1", "text": "## Prerequisites\n\nBefore beginning the upgrade process for your validator node, ensure the following:\n\n- You have a fully functional validator setup with all required binaries installed. See [Set Up a Validator](/nodes-and-validators/run-a-validator/onboarding-and-offboarding/set-up-validator/){target=\\_blank} and [Validator Requirements](/nodes-and-validators/run-a-validator/requirements/){target=\\_blank} for additional guidance.\n- Your VPS infrastructure has enough capacity to run a secondary validator instance temporarily for the upgrade process."} -{"page_id": "nodes-and-validators-run-a-validator-operational-tasks-upgrade-your-node", "page_title": "Upgrade a Validator Node", "index": 2, "depth": 2, "title": "Session Keys", "anchor": "session-keys", "start_char": 1378, "end_char": 2091, "estimated_token_count": 137, "token_estimator": "heuristic-v1", "text": "## Session Keys\n\nSession keys are used to sign validator operations and establish a connection between your validator node and your staking proxy account. These keys are stored in the client, and any change to them requires a waiting period. Specifically, if you modify your session keys, the change will take effect only after the current session is completed and two additional sessions have passed.\n\nRemembering this delayed effect when planning upgrades is crucial to ensure that your validator continues to function correctly and avoids interruptions. To learn more about session keys and their importance, visit the [Keys section](https://wiki.polkadot.com/learn/learn-cryptography/#keys){target=\\_blank}."} -{"page_id": "nodes-and-validators-run-a-validator-operational-tasks-upgrade-your-node", "page_title": "Upgrade a Validator Node", "index": 3, "depth": 2, "title": "Keystore", "anchor": "keystore", "start_char": 2091, "end_char": 2885, "estimated_token_count": 168, "token_estimator": "heuristic-v1", "text": "## Keystore\n\nYour validator server's `keystore` folder holds the private keys needed for signing network-level transactions. It is important not to duplicate or transfer this folder between validator instances. Doing so could result in multiple validators signing with the duplicate keys, leading to severe consequences such as [equivocation slashing](/nodes-and-validators/run-a-validator/staking-mechanics/offenses-and-slashes/#equivocation-slash){target=\\_blank}. Instead, always generate new session keys for each validator instance.\n\nThe default path to the `keystore` is as follows:\n\n```bash\n/home/polkadot/.local/share/polkadot/chains//keystore\n```\n\nTaking care to manage your keys securely ensures that your validator operates safely and without the risk of slashing penalties."} -{"page_id": "nodes-and-validators-run-a-validator-operational-tasks-upgrade-your-node", "page_title": "Upgrade a Validator Node", "index": 4, "depth": 2, "title": "Upgrade Using Backup Validator", "anchor": "upgrade-using-backup-validator", "start_char": 2885, "end_char": 3137, "estimated_token_count": 41, "token_estimator": "heuristic-v1", "text": "## Upgrade Using Backup Validator\n\nThe following instructions outline how to temporarily switch between two validator nodes. The original active validator is referred to as Validator A and the backup node used for maintenance purposes as Validator B."} -{"page_id": "nodes-and-validators-run-a-validator-operational-tasks-upgrade-your-node", "page_title": "Upgrade a Validator Node", "index": 5, "depth": 3, "title": "Session `N`", "anchor": "session-n", "start_char": 3137, "end_char": 4089, "estimated_token_count": 216, "token_estimator": "heuristic-v1", "text": "### Session `N`\n\n1. **Start Validator B**: Launch a secondary node and wait until it is fully synced with the network. Once synced, start it with the `--validator` flag. This node will now act as Validator B.\n2. **Generate session keys**: Create new session keys specifically for Validator B.\n3. **Submit the `set_key` extrinsic**: Use your staking proxy account to submit a `set_key` extrinsic, linking the session keys for Validator B to your staking setup.\n4. **Record the session**: Make a note of the session in which you executed this extrinsic.\n5. **Wait for session changes**: Allow the current session to end and then wait for two additional full sessions for the new keys to take effect.\n\n!!! warning \"Keep Validator A running\"\n\n It is crucial to keep Validator A operational during this entire waiting period. Since `set_key` does not take effect immediately, turning off Validator A too early may result in chilling or even slashing."} -{"page_id": "nodes-and-validators-run-a-validator-operational-tasks-upgrade-your-node", "page_title": "Upgrade a Validator Node", "index": 6, "depth": 3, "title": "Session `N+3`", "anchor": "session-n3", "start_char": 4089, "end_char": 5650, "estimated_token_count": 378, "token_estimator": "heuristic-v1", "text": "### Session `N+3`\n\nAt this stage, Validator B becomes your active validator. You can now safely perform any maintenance tasks on Validator A.\n\nComplete the following steps when you are ready to bring Validator A back online:\n\n1. **Start Validator A**: Launch Validator A, sync the blockchain database, and ensure it is running with the `--validator` flag.\n2. **Generate new session keys for Validator A**: Create fresh session keys for Validator A.\n3. **Submit the `set_key` extrinsic**: Using your staking proxy account, submit a `set_key` extrinsic with the new Validator A session keys.\n4. **Record the session**: Again, make a note of the session in which you executed this extrinsic.\n\nKeep Validator B active until the session during which you executed the `set-key` extrinsic completes plus two additional full sessions have passed. Once Validator A has successfully taken over, you can safely stop Validator B. This process helps ensure a smooth handoff between nodes and minimizes the risk of downtime or penalties. Verify the transition by checking for finalized blocks in the new session. The logs should indicate the successful change, similar to the example below:\n\n
\n INSERT_COMMAND\n 2019-10-28 21:44:13 Applying authority set change scheduled at block #450092\n 2019-10-28 21:44:13 Applying GRANDPA set change to new set with 20 authorities\n \n
"} -{"page_id": "nodes-and-validators-run-a-validator-requirements", "page_title": "Validator Requirements", "index": 0, "depth": 2, "title": "Introduction", "anchor": "introduction", "start_char": 26, "end_char": 981, "estimated_token_count": 159, "token_estimator": "heuristic-v1", "text": "## Introduction\n\nRunning a validator in the Polkadot ecosystem is essential for maintaining network security and decentralization. Validators are responsible for validating transactions and adding new blocks to the chain, ensuring the system operates smoothly. In return for their services, validators earn rewards. However, the role comes with inherent risks, such as slashing penalties for misbehavior or technical failures. If you’re new to validation, starting on Kusama provides a lower-stakes environment to gain valuable experience before progressing to the Polkadot network.\n\nThis guide covers everything you need to know about becoming a validator, including system requirements, staking prerequisites, and infrastructure setup. Whether you’re deploying on a VPS or running your node on custom hardware, you’ll learn how to optimize your validator for performance and security, ensuring compliance with network standards while minimizing risks."} -{"page_id": "nodes-and-validators-run-a-validator-requirements", "page_title": "Validator Requirements", "index": 1, "depth": 2, "title": "Prerequisites", "anchor": "prerequisites", "start_char": 981, "end_char": 2394, "estimated_token_count": 304, "token_estimator": "heuristic-v1", "text": "## Prerequisites\n\nRunning a validator requires solid system administration skills and a secure, well-maintained infrastructure. Below are the primary requirements you need to be aware of before getting started:\n\n- **System administration expertise**: Handling technical anomalies and maintaining node infrastructure is critical. Validators must be able to troubleshoot and optimize their setup.\n- **Security**: Ensure your setup follows best practices for securing your node. Refer to the [Secure Your Validator](/nodes-and-validators/run-a-validator/operational-tasks/general-management/#secure-your-validator){target=\\_blank} section to learn about important security measures.\n- **Network choice**: Start with [Kusama](/nodes-and-validators/run-a-validator/onboarding-and-offboarding/set-up-validator/#run-a-kusama-validator){target=\\_blank} to gain experience. Look for \"Adjustments for Kusama\" throughout these guides for tips on adapting the provided instructions for the Kusama network.\n- **Staking requirements**: A minimum amount of native token (KSM or DOT) is required to be elected into the validator set. The required stake can come from your own holdings or from nominators.\n- **Risk of slashing**: Any DOT you stake is at risk if your setup fails or your validator misbehaves. If you’re unsure of your ability to maintain a reliable validator, consider nominating your DOT to a trusted validator."} -{"page_id": "nodes-and-validators-run-a-validator-requirements", "page_title": "Validator Requirements", "index": 2, "depth": 2, "title": "Minimum Hardware Requirements", "anchor": "minimum-hardware-requirements", "start_char": 2394, "end_char": 3558, "estimated_token_count": 251, "token_estimator": "heuristic-v1", "text": "## Minimum Hardware Requirements\n\nPolkadot validators rely on high-performance hardware to process blocks efficiently. The recommended minimum hardware requirements to ensure a fully functional and performant validator are as follows:\n\n- CPU:\n\n - x86-64 compatible.\n - Eight physical cores @ 3.4 GHz.\n - Processor:\n - **Intel**: Ice Lake or newer (Xeon or Core series)\n - **AMD**: Zen3 or newer (EPYC or Ryzen)\n - Simultaneous multithreading disabled:\n - **Intel**: Hyper-Threading\n - **AMD**: SMT\n - [Single-threaded performance](https://www.cpubenchmark.net/singleThread.html){target=\\_blank} is prioritized over higher cores count.\n\n- Storage:\n\n - **NVMe SSD**: At least 2 TB for blockchain data recommended (prioritize latency rather than throughput).\n - Storage requirements will increase as the chain grows. For current estimates, see the [current chain snapshot](https://stakeworld.io/docs/dbsize){target=\\_blank}.\n\n- Memory:\n\n - 32 GB DDR4 ECC\n\n- Network:\n\n - Symmetric networking speed of 500 Mbit/s is required to handle large numbers of parachains and ensure congestion control during peak times."} -{"page_id": "nodes-and-validators-run-a-validator-requirements", "page_title": "Validator Requirements", "index": 3, "depth": 2, "title": "VPS Provider List", "anchor": "vps-provider-list", "start_char": 3558, "end_char": 6077, "estimated_token_count": 575, "token_estimator": "heuristic-v1", "text": "## VPS Provider List\n\nWhen selecting a VPS provider for your validator node, prioritize reliability, consistent performance, and adherence to the specific hardware requirements set for Polkadot validators. The following server types have been tested and showed acceptable performance in benchmark tests. However, this is not an endorsement and actual performance may vary depending on your workload and VPS provider.\n\nBe aware that some providers may overprovision the underlying host and use shared storage such as NVMe over TCP, which appears as local storage. These setups might result in poor or inconsistent performance. Benchmark your infrastructure before deploying.\n\n- **[Google Cloud Platform (GCP)](https://cloud.google.com/){target=\\_blank}**: `c2` and `c2d` machine families offer high-performance configurations suitable for validators.\n- **[Amazon Web Services (AWS)](https://aws.amazon.com/){target=\\_blank}**: `c6id` machine family provides strong performance, particularly for I/O-intensive workloads.\n- **[OVH](https://www.ovhcloud.com/en-au/){target=\\_blank}**: Can be a budget-friendly solution if it meets your minimum hardware specifications.\n- **[Digital Ocean](https://www.digitalocean.com/){target=\\_blank}**: Popular among developers, Digital Ocean's premium droplets offer configurations suitable for medium to high-intensity workloads.\n- **[Vultr](https://www.vultr.com/){target=\\_blank}**: Offers flexibility with plans that may meet validator requirements, especially for high-bandwidth needs.\n- **[Linode](https://www.linode.com/){target=\\_blank}**: Provides detailed documentation, which can be helpful for setup.\n- **[Scaleway](https://www.scaleway.com/en/){target=\\_blank}**: Offers high-performance cloud instances that can be suitable for validator nodes.\n- **[OnFinality](https://onfinality.io/en){target=\\_blank}**: Specialized in blockchain infrastructure, OnFinality provides validator-specific support and configurations.\n\n!!! warning \"Acceptable use policies\"\n Different VPS providers have varying acceptable use policies, and not all allow cryptocurrency-related activities. \n\n For example, Digital Ocean, requires explicit permission to use servers for cryptocurrency mining and defines unauthorized mining as [network abuse](https://www.digitalocean.com/legal/acceptable-use-policy#network-abuse){target=\\_blank} in their acceptable use policy. \n \n Review the terms for your VPS provider to avoid account suspension or server shutdown due to policy violations."} -{"page_id": "nodes-and-validators-run-a-validator-requirements", "page_title": "Validator Requirements", "index": 4, "depth": 2, "title": "Minimum Bond Requirement", "anchor": "minimum-bond-requirement", "start_char": 6077, "end_char": 6842, "estimated_token_count": 196, "token_estimator": "heuristic-v1", "text": "## Minimum Bond Requirement\n\nBefore bonding DOT, ensure you meet the minimum bond requirement to start a validator instance. The minimum bond is the least DOT you need to stake to enter the validator set. To become eligible for rewards, your validator node must be nominated by enough staked tokens.\n\nFor example, on November 19, 2024, the minimum stake backing a validator in Polkadot's era 1632 was 1,159,434.248 DOT. You can check the current minimum stake required using these tools:\n\n- [**Chain State Values**](https://wiki.polkadot.com/general/chain-state-values/){target=\\_blank}\n- [**Subscan**](https://polkadot.subscan.io/validator_list?status=validator){target=\\_blank}\n- [**Staking Dashboard**](https://staking.polkadot.cloud/#/overview){target=\\_blank}"} -{"page_id": "nodes-and-validators-run-a-validator-staking-mechanics-offenses-and-slashes", "page_title": "Offenses and Slashes", "index": 0, "depth": 2, "title": "Introduction", "anchor": "introduction", "start_char": 24, "end_char": 674, "estimated_token_count": 104, "token_estimator": "heuristic-v1", "text": "## Introduction\n\nIn Polkadot's Nominated Proof of Stake (NPoS) system, validator misconduct is deterred through a combination of slashing, disabling, and reputation penalties. Validators and nominators who stake tokens face consequences for validator misbehavior, which range from token slashes to restrictions on network participation.\n\nThis page outlines the types of offenses recognized by Polkadot, including block equivocations and invalid votes, as well as the corresponding penalties. While some parachains may implement additional custom slashing mechanisms, this guide focuses on the offenses tied to staking within the Polkadot ecosystem."} -{"page_id": "nodes-and-validators-run-a-validator-staking-mechanics-offenses-and-slashes", "page_title": "Offenses and Slashes", "index": 1, "depth": 2, "title": "Offenses", "anchor": "offenses", "start_char": 674, "end_char": 1106, "estimated_token_count": 86, "token_estimator": "heuristic-v1", "text": "## Offenses\n\nPolkadot is a public permissionless network. As such, it has a mechanism to disincentivize offenses and incentivize good behavior. You can review the [parachain protocol](https://wiki.polkadot.com/learn/learn-parachains-protocol/#parachain-protocol){target=\\_blank} to understand better the terminology used to describe offenses. Polkadot validator offenses fall into two categories: invalid votes and equivocations."} -{"page_id": "nodes-and-validators-run-a-validator-staking-mechanics-offenses-and-slashes", "page_title": "Offenses and Slashes", "index": 2, "depth": 3, "title": "Invalid Votes", "anchor": "invalid-votes", "start_char": 1106, "end_char": 1733, "estimated_token_count": 128, "token_estimator": "heuristic-v1", "text": "### Invalid Votes\n\nA validator will be penalized for inappropriate voting activity during the block inclusion and approval processes. The invalid voting related offenses are as follows:\n\n- **Backing an invalid block**: A para-validator backs an invalid block for inclusion in a fork of the relay chain.\n- **`ForInvalid` vote**: When acting as a secondary checker, the validator votes in favor of an invalid block.\n- **`AgainstValid` vote**: When acting as a secondary checker, the validator votes against a valid block. This type of vote wastes network resources required to resolve the disparate votes and resulting dispute."} -{"page_id": "nodes-and-validators-run-a-validator-staking-mechanics-offenses-and-slashes", "page_title": "Offenses and Slashes", "index": 3, "depth": 3, "title": "Equivocations", "anchor": "equivocations", "start_char": 1733, "end_char": 2746, "estimated_token_count": 197, "token_estimator": "heuristic-v1", "text": "### Equivocations\n\nEquivocation occurs when a validator produces statements that conflict with each other when producing blocks or voting. Unintentional equivocations usually occur when duplicate signing keys reside on the validator host. If keys are never duplicated, the probability of an honest equivocation slash decreases to near zero. The equivocation related offenses are as follows:\n\n- **Equivocation**: The validator produces two or more of the same block or vote.\n - **GRANDPA and BEEFY equivocation**: The validator signs two or more votes in the same round on different chains.\n - **BABE equivocation**: The validator produces two or more blocks on the relay chain in the same time slot.\n- **Double seconded equivocation**: The validator attempts to second, or back, more than one block in the same round.\n- **Seconded and valid equivocation**: The validator seconds, or backs, a block and then attempts to hide their role as the responsible backer by later placing a standard validation vote."} -{"page_id": "nodes-and-validators-run-a-validator-staking-mechanics-offenses-and-slashes", "page_title": "Offenses and Slashes", "index": 4, "depth": 2, "title": "Penalties", "anchor": "penalties", "start_char": 2746, "end_char": 2924, "estimated_token_count": 31, "token_estimator": "heuristic-v1", "text": "## Penalties\n\nOn Polkadot, offenses to the network incur different penalties depending on severity. There are three main penalties: slashing, disabling, and reputation changes."} -{"page_id": "nodes-and-validators-run-a-validator-staking-mechanics-offenses-and-slashes", "page_title": "Offenses and Slashes", "index": 5, "depth": 3, "title": "Slashing", "anchor": "slashing", "start_char": 2924, "end_char": 13705, "estimated_token_count": 2520, "token_estimator": "heuristic-v1", "text": "### Slashing\n\nValidators engaging in bad actor behavior in the network may be subject to slashing if they commit a qualifying offense. When a validator is slashed, they and their nominators lose a percentage of their staked DOT or KSM, from as little as 0.01% up to 100% based on the severity of the offense. Nominators are evaluated for slashing against their active validations at any given time. Validator nodes are evaluated as discrete entities, meaning an operator can't attempt to mitigate the offense on another node they operate in order to avoid a slash. \n\nAny slashed DOT or KSM will be added to the [Treasury](https://wiki.polkadot.com/learn/learn-polkadot-opengov-treasury/){target=\\_blank} rather than burned or distributed as rewards. Moving slashed funds to the Treasury allows tokens to be quickly moved away from malicious validators while maintaining the ability to revert faulty slashes when needed.\n\nA nominator with a very large bond may nominate several validators in a single era. In this case, a slash is proportionate to the amount staked to the offending validator. Stake allocation and validator activation is controlled by the [Phragmén algorithm](https://wiki.polkadot.com/learn/learn-phragmen/#algorithm){target=\\_blank}.\n\nA validator slash creates an `unapplied` state transition. You can view pending slashes on [Polkadot.js Apps](https://polkadot.js.org/apps/?rpc=wss%3A%2F%2Frpc.polkadot.io#/staking/slashes){target=\\_blank}. The UI will display the slash per validator, the affected nominators, and the slash amounts. The unapplied state includes a 27-day grace period during which a governance proposal can be made to reverse the slash. Once this grace period expires, the slash is applied.\n\n#### Equivocation Slash\n\nThe Web3 Foundation's [Slashing mechanisms](https://research.web3.foundation/Polkadot/security/slashing/amounts){target=\\_blank} page provides guidelines for evaluating the security threat level of different offenses and determining penalties proportionate to the threat level of the offense. Offenses requiring coordination between validators or extensive computational costs to the system will typically call for harsher penalties than those more likely to be unintentional than malicious. A description of potential offenses for each threat level and the corresponding penalties is as follows:\n\n- **Level 1**: Honest misconduct such as isolated cases of unresponsiveness.\n - **Penalty**: Validator can be kicked out or slashed up to 0.1% of stake in the validator slot.\n- **Level 2**: Misconduct that can occur honestly but is a sign of bad practices. Examples include repeated cases of unresponsiveness and isolated cases of equivocation.\n - **Penalty**: Slash of up to 1% of stake in the validator slot.\n- **Level 3**: Misconduct that is likely intentional but of limited effect on the performance or security of the network. This level will typically include signs of coordination between validators. Examples include repeated cases of equivocation or isolated cases of unjustified voting on GRANDPA.\n - **Penalty**: Reduction in networking reputation metrics, slash of up to 10% of stake in the validator slot.\n- **Level 4**: Misconduct that poses severe security or monetary risk to the system or mass collusion. Examples include signs of extensive coordination, creating a serious security risk to the system, or forcing the system to use extensive resources to counter the misconduct.\n - **Penalty**: Slash of up to 100% of stake in the validator slot.\n\nSee the next section to understand how slash amounts for equivocations are calculated. If you want to know more details about slashing, please look at the research page on [Slashing mechanisms](https://research.web3.foundation/Polkadot/security/slashing/amounts){target=\\_blank}.\n\n#### Slash Calculation for Equivocation\n\nThe slashing penalty for GRANDPA, BABE, and BEEFY equivocations is calculated using the formula below, where `x` represents the number of offenders and `n` is the total number of validators in the active set:\n\n```text\nmin((3 * x / n )^2, 1)\n```\n\nThe following scenarios demonstrate how this formula means slash percentages can increase exponentially based on the number of offenders involved compared to the size of the validator pool:\n\n- **Minor offense**: Assume 1 validator out of a 100 validator active set equivocates in a slot. A single validator committing an isolated offense is most likely a mistake rather than malicious attack on the network. This offense results in a 0.09% slash to the stake in the validator slot.\n\n ``` mermaid\n flowchart LR\n N[\"Total Validators = 100\"]\n X[\"Offenders = 1\"]\n F[\"min((3 * 1 / 100)^2, 1) = 0.0009\"]\n G[\"0.09% slash of stake\"]\n\n N --> F\n X --> F\n F --> G\n ```\n\n- **Moderate offense**: Assume 5 validators out a 100 validator active set equivocate in a slot. This is a slightly more serious event as there may be some element of coordination involved. This offense results in a 2.25% slash to the stake in the validator slot.\n\n ``` mermaid\n flowchart LR\n N[\"Total Validators = 100\"]\n X[\"Offenders = 5\"]\n F[\"min((3 * 5 / 100)^2, 1) = 0.0225\"]\n G[\"2.25% slash of stake\"]\n\n N --> F\n X --> F\n F --> G\n ```\n\n- **Major offense**: Assume 20 validators out a 100 validator active set equivocate in a slot. This is a major security threat as it possible represents a coordinated attack on the network. This offense results in a 36% slash and all slashed validators will also be chilled.\n ``` mermaid\n flowchart LR\n N[\"Total Validators = 100\"]\n X[\"Offenders = 20\"]\n F[\"min((3 * 20 / 100)^2, 1) = 0.36\"]\n G[\"36% slash of stake\"]\n\n N --> F\n X --> F\n F --> G\n ```\n\nThe examples above show the risk of nominating or running many validators in the active set. While rewards grow linearly (two validators will get you approximately twice as many staking rewards as one), slashing grows exponentially. Going from a single validator equivocating to two validators equivocating causes a slash four time as much as the single validator.\n\nValidators may run their nodes on multiple machines to ensure they can still perform validation work if one of their nodes goes down. Still, validator operators should be cautious when setting these up. Equivocation is possible if they don't coordinate well in managing signing machines.\n\n#### Best Practices to Avoid Slashing\n\nThe following are advised to node operators to ensure that they obtain pristine binaries or source code and to ensure the security of their node:\n\n- Always download either source files or binaries from the official Parity repository.\n- Verify the hash of downloaded files.\n- Use the W3F secure validator setup or adhere to its principles.\n- Ensure essential security items are checked, use a firewall, manage user access, use SSH certificates.\n- Avoid using your server as a general-purpose system. Hosting a validator on your workstation or one that hosts other services increases the risk of maleficence.\n- Avoid cloning servers (copying all contents) when migrating to new hardware. If an image is needed, create it before generating keys.\n- High Availability (HA) systems are generally not recommended as equivocation may occur if concurrent operations happen—such as when a failed server restarts or two servers are falsely online simultaneously.\n- Copying the keystore folder when moving a database between instances can cause equivocation. Even brief use of duplicated keystores can result in slashing.\n\nBelow are some examples of small equivocations that happened in the past:\n\n| Network | Era | Event Type | Details | Action Taken |\n|----------|------|--------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------|\n| Polkadot | 774 | Small Equivocation | [The validator](https://matrix.to/#/!NZrbtteFeqYKCUGQtr:matrix.parity.io/$165562246360408hKCfC:matrix.org?via=matrix.parity.io&via=corepaper.org&via=matrix.org){target=\\_blank} migrated servers and cloned the keystore folder. The on-chain event can be viewed on [Subscan](https://polkadot.subscan.io/extrinsic/11190109-0?event=11190109-5){target=\\_blank}. | The validator didn't submit a request for the slash to be canceled. |\n| Kusama | 3329 | Small Equivocation | The validator operated a test machine with cloned keys. The test machine was online simultaneously as the primary, which resulted in a slash. | The validator requested a slash cancellation, but the council declined. |\n| Kusama | 3995 | Small Equivocation | The validator noticed several errors, after which the client crashed, and a slash was applied. The validator recorded all events and opened GitHub issues to allow for technical opinions to be shared. | The validator requested to cancel the slash. The council approved the request as they believed the error wasn't operator-related. |\n\n#### Slashing Across Eras\n\nThere are three main difficulties to account for with slashing in NPoS:\n\n- A nominator can nominate multiple validators and be slashed as a result of actions taken by any of them.\n- Until slashed, the stake is reused from era to era.\n- Slashable offenses can be found after the fact and out of order.\n\nTo balance this, the system applies only the maximum slash a participant can receive in a given time period rather than the sum. This ensures protection from excessive slashing."} -{"page_id": "nodes-and-validators-run-a-validator-staking-mechanics-offenses-and-slashes", "page_title": "Offenses and Slashes", "index": 6, "depth": 3, "title": "Disabling", "anchor": "disabling", "start_char": 13705, "end_char": 14617, "estimated_token_count": 185, "token_estimator": "heuristic-v1", "text": "### Disabling\n\nThe disabling mechanism is triggered when validators commit serious infractions, such as backing invalid blocks or engaging in equivocations. Disabling stops validators from performing specific actions after they have committed an offense. Disabling is further divided into:\n\n- **On-chain disabling**: Lasts for a whole era and stops validators from authoring blocks, backing, and initiating a dispute.\n- **Off-chain disabling**: Lasts for a session, is caused by losing a dispute, and stops validators from initiating a dispute.\n\nOff-chain disabling is always a lower priority than on-chain disabling. Off-chain disabling prioritizes disabling first backers and then approval checkers.\n\nThe material in this guide reflects the changes introduced in Stage 4. For more details, see the [State of Disabling issue](https://github.com/paritytech/polkadot-sdk/issues/4359){target=\\_blank} on GitHub."} -{"page_id": "nodes-and-validators-run-a-validator-staking-mechanics-offenses-and-slashes", "page_title": "Offenses and Slashes", "index": 7, "depth": 3, "title": "Reputation Changes", "anchor": "reputation-changes", "start_char": 14617, "end_char": 15241, "estimated_token_count": 108, "token_estimator": "heuristic-v1", "text": "### Reputation Changes\n\nSome minor offenses, such as spamming, are only punished by networking reputation changes. Validators use a reputation metric when choosing which peers to connect with. The system adds reputation if a peer provides valuable data and behaves appropriately. If they provide faulty or spam data, the system reduces their reputation. If a validator loses enough reputation, their peers will temporarily close their channels to them. This helps in fighting against Denial of Service (DoS) attacks. Performing validator tasks under reduced reputation will be harder, resulting in lower validator rewards."} -{"page_id": "nodes-and-validators-run-a-validator-staking-mechanics-offenses-and-slashes", "page_title": "Offenses and Slashes", "index": 8, "depth": 3, "title": "Penalties by Offense", "anchor": "penalties-by-offense", "start_char": 15241, "end_char": 15427, "estimated_token_count": 50, "token_estimator": "heuristic-v1", "text": "### Penalties by Offense\n\nRefer to the Polkadot Wiki's [offenses page](https://wiki.polkadot.com/learn/learn-offenses/){target=\\_blank} for a summary of penalties for specific offenses."} -{"page_id": "nodes-and-validators-run-a-validator-staking-mechanics-rewards", "page_title": "Rewards Payout", "index": 0, "depth": 2, "title": "Introduction", "anchor": "introduction", "start_char": 18, "end_char": 621, "estimated_token_count": 95, "token_estimator": "heuristic-v1", "text": "## Introduction\n\nUnderstanding how rewards are distributed to validators and nominators is essential for network participants. In Polkadot and Kusama, validators earn rewards based on their era points, which are accrued through actions like block production and parachain validation.\n\nThis guide explains the payout scheme, factors influencing rewards, and how multiple validators affect returns. Validators can also share rewards with nominators, who contribute by staking behind them. By following the payout mechanics, validators can optimize their earnings and better engage with their nominators."} -{"page_id": "nodes-and-validators-run-a-validator-staking-mechanics-rewards", "page_title": "Rewards Payout", "index": 1, "depth": 2, "title": "Era Points", "anchor": "era-points", "start_char": 621, "end_char": 1497, "estimated_token_count": 165, "token_estimator": "heuristic-v1", "text": "## Era Points\n\nThe Polkadot ecosystem measures its reward cycles in a unit called an era. Kusama eras are approximately 6 hours long, and Polkadot eras are 24 hours long. At the end of each era, validators are paid proportionally to the amount of era points they have collected. Era points are reward points earned for payable actions like:\n\n- Issuing validity statements for parachain blocks.\n \n- Producing a non-uncle block in the relay chain.\n- Producing a reference to a previously unreferenced uncle block.\n- Producing a referenced uncle block.\n\nAn uncle block is a relay chain block that is valid in every regard but has failed to become canonical. This can happen when two or more validators are block producers in a single slot, and the block produced by one validator reaches the next block producer before the others. The lagging blocks are called uncle blocks."} -{"page_id": "nodes-and-validators-run-a-validator-staking-mechanics-rewards", "page_title": "Rewards Payout", "index": 2, "depth": 2, "title": "Reward Variance", "anchor": "reward-variance", "start_char": 1497, "end_char": 4038, "estimated_token_count": 564, "token_estimator": "heuristic-v1", "text": "## Reward Variance\n\nRewards in Polkadot and Kusama staking systems can fluctuate due to differences in era points earned by para-validators and non-para-validators. Para-validators generally contribute more to the overall reward distribution due to their role in validating parachain blocks, thus influencing the variance in staking rewards.\n\nTo illustrate this relationship:\n\n- Para-validator era points tend to have a higher impact on the expected value of staking rewards compared to non-para-validator points.\n- The variance in staking rewards increases as the total number of validators grows relative to the number of para-validators.\n- In simpler terms, when more validators are added to the active set without increasing the para-validator pool, the disparity in rewards between validators becomes more pronounced.\n\nHowever, despite this increased variance, rewards tend to even out over time due to the continuous rotation of para-validators across eras. The network's design ensures that over multiple eras, each validator has an equal opportunity to participate in para-validation, eventually leading to a balanced distribution of rewards.\n\n??? interface \"Probability in Staking Rewards\"\n\n This should only serve as a high-level overview of the probabilistic nature for staking rewards.\n\n Let:\n\n - `pe` = para-validator era points\n - `ne` = non-para-validator era points\n - `EV` = expected value of staking rewards\n\n Then, `EV(pe)` has more influence on the `EV` than `EV(ne)`.\n\n Since `EV(pe)` has a more weighted probability on the `EV`, the increase in variance against the `EV` becomes apparent between the different validator pools (aka. validators in the active set and the ones chosen to para-validate).\n\n Also, let:\n\n - `v` = the variance of staking rewards\n - `p` = number of para-validators\n - `w` = number validators in the active set\n - `e` = era\n\n Then, `v` ↑ if `w` ↑, as this reduces `p` : `w`, with respect to `e`.\n\n Increased `v` is expected, and initially keeping `p` ↓ using the same para-validator set for all parachains ensures [availability](https://spec.polkadot.network/chapter-anv){target=\\_blank} and [voting](https://wiki.polkadot.com/learn/learn-polkadot-opengov/){target=\\_blank}. In addition, despite `v` ↑ on an `e` to `e` basis, over time, the amount of rewards each validator receives will equal out based on the continuous selection of para-validators.\n\n There are plans to scale the active para-validation set in the future."} -{"page_id": "nodes-and-validators-run-a-validator-staking-mechanics-rewards", "page_title": "Rewards Payout", "index": 3, "depth": 2, "title": "Payout Scheme", "anchor": "payout-scheme", "start_char": 4038, "end_char": 5459, "estimated_token_count": 328, "token_estimator": "heuristic-v1", "text": "## Payout Scheme\n\nValidator rewards are distributed equally among all validators in the active set, regardless of the total stake behind each validator. However, individual payouts may differ based on the number of era points a validator has earned. Although factors like network connectivity can affect era points, well-performing validators should accumulate similar totals over time.\n\nValidators can also receive tips from users, which incentivize them to include certain transactions in their blocks. Validators retain 100% of these tips.\n\nRewards are paid out in the network's native token (DOT for Polkadot and KSM for Kusama). \n\nThe following example illustrates a four member validator set with their names, amount they have staked, and how payout of rewards is divided. This scenario assumes all validators earned the same amount of era points and no one received tips: \n\n``` mermaid\nflowchart TD\n A[\"Alice (18 DOT)\"]\n B[\"Bob (9 DOT)\"]\n C[\"Carol (8 DOT)\"]\n D[\"Dave (7 DOT)\"]\n E[\"Payout (8 DOT total)\"]\n E --\"2 DOT\"--> A\n E --\"2 DOT\"--> B\n E --\"2 DOT\"--> C\n E --\"2 DOT\"--> D\n```\n\nNote that this is different than most other Proof of Stake (PoS) systems. As long as a validator is in the validator set, it will receive the same block reward as every other validator. Validator Alice, who had 18 DOT staked, received the same 2 DOT reward in this era as Dave, who had only 7 DOT staked."} -{"page_id": "nodes-and-validators-run-a-validator-staking-mechanics-rewards", "page_title": "Rewards Payout", "index": 4, "depth": 2, "title": "Running Multiple Validators", "anchor": "running-multiple-validators", "start_char": 5459, "end_char": 7070, "estimated_token_count": 423, "token_estimator": "heuristic-v1", "text": "## Running Multiple Validators\n\nRunning multiple validators can offer a more favorable risk/reward ratio compared to running a single one. If you have sufficient DOT or nominators staking on your validators, maintaining multiple validators within the active set can yield higher rewards.\n\nIn the preceding section, with 18 DOT staked and no nominators, Alice earned 2 DOT in one era. This example uses DOT, but the same principles apply for KSM on the Kusama network. By managing stake across multiple validators, you can potentially increase overall returns. Recall the set of validators from the preceding section:\n\n``` mermaid\nflowchart TD\n A[\"Alice (18 DOT)\"]\n B[\"Bob (9 DOT)\"]\n C[\"Carol (8 DOT)\"]\n D[\"Dave (7 DOT)\"]\n E[\"Payout (8 DOT total)\"]\n E --\"2 DOT\"--> A\n E --\"2 DOT\"--> B\n E --\"2 DOT\"--> C\n E --\"2 DOT\"--> D \n```\n\nNow, assume Alice decides to split their stake and run two validators, each with a nine DOT stake. This validator set only has four spots and priority is given to validators with a larger stake. In this example, Dave has the smallest stake and loses his spot in the validator set. Now, Alice will earn two shares of the total payout each era as illustrated below:\n\n``` mermaid\nflowchart TD\n A[\"Alice (9 DOT)\"]\n F[\"Alice (9 DOT)\"]\n B[\"Bob (9 DOT)\"]\n C[\"Carol (8 DOT)\"]\n E[\"Payout (8 DOT total)\"]\n E --\"2 DOT\"--> A\n E --\"2 DOT\"--> B\n E --\"2 DOT\"--> C\n E --\"2 DOT\"--> F \n```\n\nWith enough stake, you could run more than two validators. However, each validator must have enough stake behind it to maintain a spot in the validator set."} -{"page_id": "nodes-and-validators-run-a-validator-staking-mechanics-rewards", "page_title": "Rewards Payout", "index": 5, "depth": 2, "title": "Nominators and Validator Payments", "anchor": "nominators-and-validator-payments", "start_char": 7070, "end_char": 10907, "estimated_token_count": 990, "token_estimator": "heuristic-v1", "text": "## Nominators and Validator Payments\n\nA nominator's stake allows them to vote for validators and earn a share of the rewards without managing a validator node. Although staking rewards depend on validator activity during an era, validators themselves never control or own nominator rewards. To trigger payouts, anyone can call the `staking.payoutStakers` or `staking.payoutStakerByPage` methods, which mint and distribute rewards directly to the recipients. This trustless process ensures nominators receive their earned rewards.\n\nValidators set a commission rate as a percentage of the block reward, affecting how rewards are shared with nominators. A 0% commission means the validator keeps only rewards from their self-stake, while a 100% commission means they retain all rewards, leaving none for nominators.\n\nThe following examples model splitting validator payments between nominator and validator using various commission percentages. For simplicity, these examples assume a Polkadot-SDK based relay chain that uses DOT as a native token and a single nominator per validator. Calculations of KSM reward payouts for Kusama follow the same formula. \n\nStart with the original validator set from the previous section: \n\n``` mermaid\nflowchart TD\n A[\"Alice (18 DOT)\"]\n B[\"Bob (9 DOT)\"]\n C[\"Carol (8 DOT)\"]\n D[\"Dave (7 DOT)\"]\n E[\"Payout (8 DOT total)\"]\n E --\"2 DOT\"--> A\n E --\"2 DOT\"--> B\n E --\"2 DOT\"--> C\n E --\"2 DOT\"--> D \n```\n\nThe preceding diagram shows each validator receiving a 2 DOT payout, but doesn't account for sharing rewards with nominators. The following diagram shows what nominator payout might look like for validator Alice. Alice has a 20% commission rate and holds 50% of the stake for their validator:\n\n``` mermaid\n\nflowchart TD\n A[\"Gross Rewards = 2 DOT\"]\n E[\"Commission = 20%\"]\n F[\"Alice Validator Payment = 0.4 DOT\"]\n G[\"Total Stake Rewards = 1.6 DOT\"]\n B[\"Alice Validator Stake = 18 DOT\"]\n C[\"9 DOT Alice (50%)\"]\n H[\"Alice Stake Reward = 0.8 DOT\"]\n I[\"Total Alice Validator Reward = 1.2 DOT\"]\n D[\"9 DOT Nominator (50%)\"]\n J[\"Total Nominator Reward = 0.8 DOT\"]\n \n A --> E\n E --(2 x 0.20)--> F\n F --(2 - 0.4)--> G\n B --> C\n B --> D\n C --(1.6 x 0.50)--> H\n H --(0.4 + 0.8)--> I\n D --(1.60 x 0.50)--> J\n```\n\nNotice the validator commission rate is applied against the gross amount of rewards for the era. The validator commission is subtracted from the total rewards. After the commission is paid to the validator, the remaining amount is split among stake owners according to their percentage of the total stake. A validator's total rewards for an era include their commission plus their piece of the stake rewards. \n\nNow, consider a different scenario for validator Bob where the commission rate is 40%, and Bob holds 33% of the stake for their validator:\n\n``` mermaid\n\nflowchart TD\n A[\"Gross Rewards = 2 DOT\"]\n E[\"Commission = 40%\"]\n F[\"Bob Validator Payment = 0.8 DOT\"]\n G[\"Total Stake Rewards = 1.2 DOT\"]\n B[\"Bob Validator Stake = 9 DOT\"]\n C[\"3 DOT Bob (33%)\"]\n H[\"Bob Stake Reward = 0.4 DOT\"]\n I[\"Total Bob Validator Reward = 1.2 DOT\"]\n D[\"6 DOT Nominator (67%)\"]\n J[\"Total Nominator Reward = 0.8 DOT\"]\n \n A --> E\n E --(2 x 0.4)--> F\n F --(2 - 0.8)--> G\n B --> C\n B --> D\n C --(1.2 x 0.33)--> H\n H --(0.8 + 0.4)--> I\n D --(1.2 x 0.67)--> J\n```\n\nBob holds a smaller percentage of their node's total stake, making their stake reward smaller than Alice's. In this scenario, Bob makes up the difference by charging a 40% commission rate and ultimately ends up with the same total payment as Alice. Each validator will need to find their ideal balance between the amount of stake and commission rate to attract nominators while still making running a validator worthwhile."} +{"page_id": "node-infrastructure-run-a-node-bootnode", "page_title": "Set Up a Bootnode", "index": 0, "depth": 2, "title": "Introduction", "anchor": "introduction", "start_char": 21, "end_char": 613, "estimated_token_count": 113, "token_estimator": "heuristic-v1", "text": "## Introduction\n\nBootnodes are essential for helping blockchain nodes discover peers and join the network. When a node starts, it needs to find other nodes, and bootnodes provide an initial point of contact. Once connected, a node can expand its peer connections and play its role in the network, like participating as a validator.\n\nThis guide will walk you through setting up a Polkadot bootnode, configuring P2P, WebSocket (WS), secure WSS connections, and managing network keys. You'll also learn how to test your bootnode to ensure it is running correctly and accessible to other nodes."} +{"page_id": "node-infrastructure-run-a-node-bootnode", "page_title": "Set Up a Bootnode", "index": 1, "depth": 2, "title": "Prerequisites", "anchor": "prerequisites", "start_char": 613, "end_char": 986, "estimated_token_count": 86, "token_estimator": "heuristic-v1", "text": "## Prerequisites\n\nBefore you start, you need to have the following prerequisites:\n\n- Verify a working Polkadot (`polkadot`) binary is available on your machine.\n- Ensure you have nginx installed. Please refer to the [Installation Guide](https://nginx.org/en/docs/install.html){target=\\_blank} for help with installation if needed.\n- A VPS or other dedicated server setup."} +{"page_id": "node-infrastructure-run-a-node-bootnode", "page_title": "Set Up a Bootnode", "index": 2, "depth": 2, "title": "Accessing the Bootnode", "anchor": "accessing-the-bootnode", "start_char": 986, "end_char": 1573, "estimated_token_count": 149, "token_estimator": "heuristic-v1", "text": "## Accessing the Bootnode\n\nBootnodes must be accessible through three key channels to connect with other nodes in the network:\n\n- **P2P**: A direct peer-to-peer connection, set by.\n\n ```bash\n\n --listen-addr /ip4/0.0.0.0/tcp/INSERT_PORT\n\n ```\n \n This is not enabled by default on non-validator nodes like archive RPC nodes.\n\n- **P2P/WS**: A WebSocket (WS) connection, also configured via `--listen-addr`.\n- **P2P/WSS**: A secure WebSocket (WSS) connection using SSL, often required for light clients. An SSL proxy is needed, as the node itself cannot handle certificates."} +{"page_id": "node-infrastructure-run-a-node-bootnode", "page_title": "Set Up a Bootnode", "index": 3, "depth": 2, "title": "Node Key", "anchor": "node-key", "start_char": 1573, "end_char": 2240, "estimated_token_count": 148, "token_estimator": "heuristic-v1", "text": "## Node Key\n\nA node key is the ED25519 key used by `libp2p` to assign your node an identity or peer ID. Generating a known node key for a bootnode is crucial, as it gives you a consistent key that can be placed in chain specifications as a known, reliable bootnode.\n\nStarting a node creates its node key in the `chains/INSERT_CHAIN/network/secret_ed25519` file.\n\nYou can create a node key using:\n\n ``` bash\n polkadot key generate-node-key\n ``` \n \nThis key can be used in the startup command line.\n\nIt is imperative that you backup the node key. If it is included in the `polkadot` binary, it is hardcoded into the binary, which must be recompiled to change the key."} +{"page_id": "node-infrastructure-run-a-node-bootnode", "page_title": "Set Up a Bootnode", "index": 4, "depth": 2, "title": "Running the Bootnode", "anchor": "running-the-bootnode", "start_char": 2240, "end_char": 3333, "estimated_token_count": 240, "token_estimator": "heuristic-v1", "text": "## Running the Bootnode\n\nA bootnode can be run as follows:\n\n ``` bash\n polkadot --chain polkadot \\\n --name dot-bootnode \\\n --listen-addr /ip4/0.0.0.0/tcp/30310 \\\n --listen-addr /ip4/0.0.0.0/tcp/30311/ws\n ```\n\nThis assigns the p2p to port 30310 and p2p/ws to port 30311. For the p2p/wss port, a proxy must be set up with a DNS name and a corresponding certificate. The following example is for the popular nginx server and enables p2p/wss on port 30312 by adding a proxy to the p2p/ws port 30311:\n\n``` conf title=\"/etc/nginx/sites-enabled/dot-bootnode\"\nserver {\n listen 30312 ssl http2 default_server;\n server_name dot-bootnode.stakeworld.io;\n root /var/www/html;\n\n ssl_certificate \"INSERT_YOUR_CERT\";\n ssl_certificate_key \"INSERT_YOUR_KEY\";\n\n location / {\n proxy_buffers 16 4k;\n proxy_buffer_size 2k;\n proxy_pass http://localhost:30311;\n proxy_http_version 1.1;\n proxy_set_header Upgrade $http_upgrade;\n proxy_set_header Connection \"Upgrade\";\n proxy_set_header Host $host;\n }\n\n}\n```"} +{"page_id": "node-infrastructure-run-a-node-bootnode", "page_title": "Set Up a Bootnode", "index": 5, "depth": 2, "title": "Testing Bootnode Connection", "anchor": "testing-bootnode-connection", "start_char": 3333, "end_char": 3727, "estimated_token_count": 78, "token_estimator": "heuristic-v1", "text": "## Testing Bootnode Connection\n\nIf the preceding node is running with DNS name `dot-bootnode.stakeworld.io`, which contains a proxy with a valid certificate and node-id `12D3KooWAb5MyC1UJiEQJk4Hg4B2Vi3AJdqSUhTGYUqSnEqCFMFg` then the following commands should output `syncing 1 peers`.\n\n!!!tip\n You can add `-lsub-libp2p=trace` on the end to get libp2p trace logging for debugging purposes."} +{"page_id": "node-infrastructure-run-a-node-bootnode", "page_title": "Set Up a Bootnode", "index": 6, "depth": 3, "title": "P2P", "anchor": "p2p", "start_char": 3727, "end_char": 3993, "estimated_token_count": 74, "token_estimator": "heuristic-v1", "text": "### P2P\n\n```bash\npolkadot --chain polkadot \\\n--base-path /tmp/node \\\n--name \"Bootnode testnode\" \\\n--reserved-only \\\n--reserved-nodes \"/dns/dot-bootnode.stakeworld.io/tcp/30310/p2p/12D3KooWAb5MyC1UJiEQJk4Hg4B2Vi3AJdqSUhTGYUqSnEqCFMFg\" \\\n--no-hardware-benchmarks\n```"} +{"page_id": "node-infrastructure-run-a-node-bootnode", "page_title": "Set Up a Bootnode", "index": 7, "depth": 3, "title": "P2P/WS", "anchor": "p2pws", "start_char": 3993, "end_char": 4265, "estimated_token_count": 78, "token_estimator": "heuristic-v1", "text": "### P2P/WS\n\n```bash\npolkadot --chain polkadot \\\n--base-path /tmp/node \\\n--name \"Bootnode testnode\" \\\n--reserved-only \\\n--reserved-nodes \"/dns/dot-bootnode.stakeworld.io/tcp/30311/ws/p2p/12D3KooWAb5MyC1UJiEQJk4Hg4B2Vi3AJdqSUhTGYUqSnEqCFMFg\" \\\n--no-hardware-benchmarks\n```"} +{"page_id": "node-infrastructure-run-a-node-bootnode", "page_title": "Set Up a Bootnode", "index": 8, "depth": 3, "title": "P2P/WSS", "anchor": "p2pwss", "start_char": 4265, "end_char": 4538, "estimated_token_count": 78, "token_estimator": "heuristic-v1", "text": "### P2P/WSS\n\n```bash\npolkadot --chain polkadot \\\n--base-path /tmp/node \\\n--name \"Bootnode testnode\" \\\n--reserved-only \\\n--reserved-nodes \"/dns/dot-bootnode.stakeworld.io/tcp/30312/wss/p2p/12D3KooWAb5MyC1UJiEQJk4Hg4B2Vi3AJdqSUhTGYUqSnEqCFMFg\" \\\n--no-hardware-benchmarks\n```"} +{"page_id": "node-infrastructure-run-a-node-full-node", "page_title": "Set Up a Node", "index": 0, "depth": 2, "title": "Introduction", "anchor": "introduction", "start_char": 17, "end_char": 945, "estimated_token_count": 165, "token_estimator": "heuristic-v1", "text": "## Introduction\n\nRunning a node on Polkadot provides direct interaction with the network, enhanced privacy, and full control over RPC requests, transactions, and data queries. As the backbone of the network, nodes ensure decentralized data propagation, transaction validation, and seamless communication across the ecosystem.\n\nPolkadot supports multiple node types, including pruned, archive, and light nodes, each suited to specific use cases. During setup, you can use configuration flags to choose the node type you wish to run.\n\nThis guide walks you through configuring, securing, and maintaining a node on Polkadot or any Polkadot SDK-based chain. It covers instructions for the different node types and how to safely expose your node's RPC server for external access. Whether you're building a local development environment, powering dApps, or supporting network decentralization, this guide provides all the essentials."} +{"page_id": "node-infrastructure-run-a-node-full-node", "page_title": "Set Up a Node", "index": 1, "depth": 2, "title": "Set Up a Node", "anchor": "set-up-a-node", "start_char": 945, "end_char": 1150, "estimated_token_count": 43, "token_estimator": "heuristic-v1", "text": "## Set Up a Node\n\nNow that you're familiar with the different types of nodes, this section will walk you through configuring, securing, and maintaining a node on Polkadot or any Polkadot SDK-based chain."} +{"page_id": "node-infrastructure-run-a-node-full-node", "page_title": "Set Up a Node", "index": 2, "depth": 3, "title": "Prerequisites", "anchor": "prerequisites", "start_char": 1150, "end_char": 1721, "estimated_token_count": 144, "token_estimator": "heuristic-v1", "text": "### Prerequisites\n\nBefore getting started, ensure the following prerequisites are met:\n\n- Ensure [Rust](https://rust-lang.org/tools/install/){target=\\_blank} is installed on your operating system.\n- [Install the necessary dependencies for the Polkadot SDK](/parachains/install-polkadot-sdk/){target=\\_blank}.\n\n!!! warning\n This setup is not recommended for validators. If you plan to run a validator, refer to the [Running a Validator](/node-infrastructure/run-a-validator/onboarding-and-offboarding/set-up-validator/){target=\\_blank} guide for proper instructions."} +{"page_id": "node-infrastructure-run-a-node-full-node", "page_title": "Set Up a Node", "index": 3, "depth": 3, "title": "Install and Build the Polkadot Binary", "anchor": "install-and-build-the-polkadot-binary", "start_char": 1721, "end_char": 8205, "estimated_token_count": 1560, "token_estimator": "heuristic-v1", "text": "### Install and Build the Polkadot Binary\n\nThis section will walk you through installing and building the Polkadot binary for different operating systems and methods.\n\n??? interface \"macOS\"\n\n To get started, update and configure the Rust toolchain by running the following commands:\n\n ```bash\n source ~/.cargo/env\n\n rustup default stable\n rustup update\n\n rustup update nightly\n rustup target add wasm32-unknown-unknown --toolchain nightly\n rustup component add rust-src --toolchain stable-aarch64-apple-darwin\n ```\n\n You can verify your installation by running:\n\n ```bash\n rustup show\n rustup +nightly show\n ```\n\n You should see output similar to the following:\n\n
\n rustup show
\n rustup +nightly show\n active toolchain\n ----------------\n \n stable-aarch64-apple-darwin (default)\n rustc 1.82.0 (f6e511eec 2024-10-15)\n \n active toolchain\n ----------------\n \n nightly-aarch64-apple-darwin (overridden by +toolchain on the command line) \n rustc 1.84.0-nightly (03ee48451 2024-11-18)\n \n
\n\n Then, run the following commands to clone and build the Polkadot binary:\n \n ```bash\n git clone https://github.com/paritytech/polkadot-sdk polkadot-sdk\n cd polkadot-sdk\n cargo build --release\n ```\n\n Depending upon the specs of your machine, compiling the binary may take an hour or more. After building the Polkadot node from source, the executable binary will be located in the `./target/release/polkadot` directory.\n\n??? interface \"Windows\"\n\n To get started, make sure that you have [WSL and Ubuntu](https://learn.microsoft.com/en-us/windows/wsl/install){target=\\_blank} installed on your Windows machine.\n\n Once installed, you have a couple options for installing the Polkadot binary:\n\n - If Rust is installed, then `cargo` can be used similar to the macOS instructions.\n - Or, the instructions in the Linux section can be used.\n\n??? interface \"Linux (pre-built binary)\"\n\n To grab the [latest release of the Polkadot binary](https://github.com/paritytech/polkadot-sdk/releases){target=\\_blank}, you can use `wget`:\n\n ```bash\n wget https://github.com/paritytech/polkadot-sdk/releases/download/polkadot-INSERT_VERSION/polkadot\n ```\n \n Ensure you note the executable binary's location, as you'll need to use it when running the start-up command. If you prefer, you can specify the output location of the executable binary with the `-O` flag, for example:\n\n ```bash\n wget https://github.com/paritytech/polkadot-sdk/releases/download/polkadot-INSERT_VERSION/polkadot \\\n - O /var/lib/polkadot-data/polkadot\n ```\n\n !!!tip\n The nature of pre-built binaries means that they may not work on your particular architecture or Linux distribution. If you see an error like `cannot execute binary file: Exec format error` it likely means the binary is incompatible with your system. You will either need to compile the binary or use [Docker](#use-docker).\n\n Ensure that you properly configure the permissions to make the Polkadot release binary executable:\n\n ```bash\n sudo chmod +x polkadot\n ```\n\n??? interface \"Linux (compile binary)\"\n\n The most reliable (although perhaps not the fastest) way of launching a full node is to compile the binary yourself. Depending on your machine's specs, this may take an hour or more.\n\n To get started, run the following commands to configure the Rust toolchain:\n\n ```bash\n rustup default stable\n rustup update\n rustup update nightly\n rustup target add wasm32-unknown-unknown --toolchain nightly\n rustup target add wasm32-unknown-unknown --toolchain stable-x86_64-unknown-linux-gnu\n rustup component add rust-src --toolchain stable-x86_64-unknown-linux-gnu\n ```\n\n You can verify your installation by running:\n\n ```bash\n rustup show\n ```\n\n You should see output similar to the following:\n\n
\n rustup show
\n rustup +nightly show\n active toolchain\n ----------------\n \n stable-x86_64-unknown-linux-gnu (default)\n rustc 1.82.0 (f6e511eec 2024-10-15)\n
\n\n Once Rust is configured, run the following commands to clone and build Polkadot:\n \n ```bash\n git clone https://github.com/paritytech/polkadot-sdk polkadot-sdk\n cd polkadot-sdk\n cargo build --release\n ```\n\n Compiling the binary may take an hour or more, depending on your machine's specs. After building the Polkadot node from the source, the executable binary will be located in the `./target/release/polkadot` directory.\n\n??? interface \"Linux (snap package)\"\n\n Polkadot can be installed as a [snap package](https://snapcraft.io/polkadot){target=\\_blank}. If you don't already have Snap installed, take the following steps to install it:\n\n ```bash\n sudo apt update\n sudo apt install snapd\n ```\n\n Install the Polkadot snap package:\n\n ```bash\n sudo snap install polkadot\n ```\n \n Before continuing on with the following instructions, check out the [Configure and Run Your Node](#configure-and-run-your-node) section to learn more about the configuration options.\n\n To configure your Polkadot node with your desired options, you'll run a command similar to the following:\n\n ```bash\n sudo snap set polkadot service-args=\"--name=MyName --chain=polkadot\"\n ```\n\n Then to start the node service, run:\n\n ```bash\n sudo snap start polkadot\n ```\n\n You can review the logs to check on the status of the node: \n\n ```bash\n snap logs polkadot -f\n ```\n\n And at any time, you can stop the node service:\n\n ```bash\n sudo snap stop polkadot\n ```\n\n You can optionally prevent the service from stopping when snap is updated with the following command:\n\n ```bash\n sudo snap set polkadot endure=true\n ```"} +{"page_id": "node-infrastructure-run-a-node-full-node", "page_title": "Set Up a Node", "index": 4, "depth": 3, "title": "Use Docker", "anchor": "use-docker", "start_char": 8205, "end_char": 9272, "estimated_token_count": 293, "token_estimator": "heuristic-v1", "text": "### Use Docker\n\nAs an additional option, you can use Docker to run your node in a container. Doing this is more advanced, so it's best left up to those already familiar with Docker or who have completed the other set-up instructions in this guide. You can review the latest versions on [DockerHub](https://hub.docker.com/r/parity/polkadot/tags){target=\\_blank}.\n\nBe aware that when you run Polkadot in Docker, the process only listens on `localhost` by default. If you would like to connect to your node's services (RPC and Prometheus) you need to ensure that you run the node with the `--rpc-external`, and `--prometheus-external` commands.\n\n```bash\ndocker run -p 9944:9944 -p 9615:9615 parity/polkadot:v1.16.2 --name \"my-polkadot-node-calling-home\" --rpc-external --prometheus-external\n```\n\nIf you're running Docker on an Apple Silicon machine (e.g. M4), you'll need to adapt the command slightly:\n\n```bash\ndocker run --platform linux/amd64 -p 9944:9944 -p 9615:9615 parity/polkadot:v1.16.2 --name \"kearsarge-calling-home\" --rpc-external --prometheus-external\n```"} +{"page_id": "node-infrastructure-run-a-node-full-node", "page_title": "Set Up a Node", "index": 5, "depth": 2, "title": "Configure and Run Your Node", "anchor": "configure-and-run-your-node", "start_char": 9272, "end_char": 11064, "estimated_token_count": 418, "token_estimator": "heuristic-v1", "text": "## Configure and Run Your Node\n\nNow that you've installed and built the Polkadot binary, the next step is to configure the start-up command depending on the type of node that you want to run. You'll need to modify the start-up command accordingly based on the location of the binary. In some cases, it may be located within the `./target/release/` folder, so you'll need to replace polkadot with `./target/release/polkadot` in the following commands.\n\nAlso, note that you can use the same binary for Polkadot as you would for Kusama or any other relay chain. You'll need to use the `--chain` flag to differentiate between chains.\n\nThe base commands for running a Polkadot node are as follows:\n\n=== \"Default pruned node\"\n\n This uses the default pruning value of the last 256 blocks:\n\n ```bash\n polkadot --chain polkadot \\\n --name \"INSERT_NODE_NAME\"\n ```\n\n=== \"Custom pruned node\"\n\n You can customize the pruning value, for example, to the last 1000 finalized blocks:\n\n ```bash\n polkadot --chain polkadot \\\n --name INSERT_YOUR_NODE_NAME \\\n --state-pruning 1000 \\\n --blocks-pruning archive \\\n --rpc-cors all \\\n --rpc-methods safe\n ```\n\n=== \"Archive node\"\n\n To support the full state, use the `archive` option:\n\n ```bash\n polkadot --chain polkadot \\\n --name INSERT_YOUR_NODE_NAME \\\n --state-pruning archive \\\n --blocks-pruning archive \\\n ```\n\nIf you want to run an RPC node, please refer to the following [RPC Configurations](#rpc-configurations) section.\n\nTo review a complete list of the available commands, flags, and options, you can use the `--help` flag:\n\n```bash\npolkadot --help\n```\n\nOnce you've fully configured your start-up command, you can execute it in your terminal and your node will start [syncing](#sync-your-node)."} +{"page_id": "node-infrastructure-run-a-node-full-node", "page_title": "Set Up a Node", "index": 6, "depth": 3, "title": "RPC Configurations", "anchor": "rpc-configurations", "start_char": 11064, "end_char": 11923, "estimated_token_count": 221, "token_estimator": "heuristic-v1", "text": "### RPC Configurations\n\nThe node startup settings allow you to choose what to expose, how many connections to expose, and which systems should be granted access through the RPC server.\n\n- You can limit the methods to use with `--rpc-methods`; an easy way to set this to a safe mode is `--rpc-methods safe`.\n- You can set your maximum connections through `--rpc-max-connections`, for example, `--rpc-max-connections 200`.\n- By default, localhost and Polkadot.js can access the RPC server. You can change this by setting `--rpc-cors`. To allow access from everywhere, you can use `--rpc-cors all`.\n\nFor a list of important flags when running RPC nodes, refer to the Parity DevOps documentation: [Important Flags for Running an RPC Node](https://paritytech.github.io/devops-guide/guides/rpc_index.html?#important-flags-for-running-an-rpc-node){target=\\_blank}."} +{"page_id": "node-infrastructure-run-a-node-full-node", "page_title": "Set Up a Node", "index": 7, "depth": 2, "title": "Sync Your Node", "anchor": "sync-your-node", "start_char": 11923, "end_char": 15591, "estimated_token_count": 1235, "token_estimator": "heuristic-v1", "text": "## Sync Your Node\n\nThe syncing process will take a while, depending on your capacity, processing power, disk speed, and RAM. The process may be completed on a $10 DigitalOcean droplet in about ~36 hours. While syncing, your node name should be visible in gray on Polkadot Telemetry, and once it is fully synced, your node name will appear in white on [Polkadot Telemetry](https://telemetry.polkadot.io/#list/Polkadot){target=_blank}.\n\nA healthy node syncing blocks will output logs like the following:\n\n
\n 2024-11-19 23:49:57 Parity Polkadot\n 2024-11-19 23:49:57 ✌️ version 1.14.1-7c4cd60da6d\n 2024-11-19 23:49:57 ❤️ by Parity Technologies <admin@parity.io>, 2017-2024\n 2024-11-19 23:49:57 📋 Chain specification: Polkadot\n 2024-11-19 23:49:57 🏷 Node name: myPolkadotNode\n 2024-11-19 23:49:57 👤 Role: FULL\n 2024-11-19 23:49:57 💾 Database: RocksDb at /home/ubuntu/.local/share/polkadot/chains/polkadot/db/full\n 2024-11-19 23:50:00 🏷 Local node identity is: 12D3KooWDmhHEgPRJUJnUpJ4TFWn28EENqvKWH4dZGCN9TS51y9h\n 2024-11-19 23:50:00 Running libp2p network backend\n 2024-11-19 23:50:00 💻 Operating system: linux\n 2024-11-19 23:50:00 💻 CPU architecture: x86_64\n 2024-11-19 23:50:00 💻 Target environment: gnu\n 2024-11-19 23:50:00 💻 CPU: Intel(R) Xeon(R) CPU E3-1245 V2 @ 3.40GHz\n 2024-11-19 23:50:00 💻 CPU cores: 4\n 2024-11-19 23:50:00 💻 Memory: 32001MB\n 2024-11-19 23:50:00 💻 Kernel: 5.15.0-113-generic\n 2024-11-19 23:50:00 💻 Linux distribution: Ubuntu 22.04.5 LTS\n 2024-11-19 23:50:00 💻 Virtual machine: no\n 2024-11-19 23:50:00 📦 Highest known block at #9319\n 2024-11-19 23:50:00 〽️ Prometheus exporter started at 127.0.0.1:9615\n 2024-11-19 23:50:00 Running JSON-RPC server: addr=127.0.0.1:9944, allowed origins=[\"http://localhost:*\", \"http://127.0.0.1:*\", \"https://localhost:*\", \"https://127.0.0.1:*\", \"https://polkadot.js.org\"]\n 2024-11-19 23:50:00 🏁 CPU score: 671.67 MiBs\n 2024-11-19 23:50:00 🏁 Memory score: 7.96 GiBs\n 2024-11-19 23:50:00 🏁 Disk score (seq. writes): 377.87 MiBs\n 2024-11-19 23:50:00 🏁 Disk score (rand. writes): 147.92 MiBs\n 2024-11-19 23:50:00 🥩 BEEFY gadget waiting for BEEFY pallet to become available...\n 2024-11-19 23:50:00 🔍 Discovered new external address for our node: /ip4/37.187.93.17/tcp/30333/ws/p2p/12D3KooWDmhHEgPRJUJnUpJ4TFWn28EENqvKWH4dZGCN9TS51y9h\n 2024-11-19 23:50:01 🔍 Discovered new external address for our node: /ip6/2001:41d0:a:3511::1/tcp/30333/ws/p2p/12D3KooWDmhHEgPRJUJnUpJ4TFWn28EENqvKWH4dZGCN9TS51y9h\n 2024-11-19 23:50:05 ⚙️ Syncing, target=#23486325 (5 peers), best: #12262 (0x8fb5…f310), finalized #11776 (0x9de1…32fb), ⬇ 430.5kiB/s ⬆ 17.8kiB/s\n 2024-11-19 23:50:10 ⚙️ Syncing 628.8 bps, target=#23486326 (6 peers), best: #15406 (0x9ce1…2d76), finalized #15360 (0x0e41…a064), ⬇ 255.0kiB/s ⬆ 1.8kiB/s\n
\n\nCongratulations, you're now syncing a Polkadot full node! Remember that the process is identical when using any other Polkadot SDK-based chain, although individual chains may have chain-specific flag requirements."} +{"page_id": "node-infrastructure-run-a-node-full-node", "page_title": "Set Up a Node", "index": 8, "depth": 3, "title": "Connect to Your Node", "anchor": "connect-to-your-node", "start_char": 15591, "end_char": 15944, "estimated_token_count": 117, "token_estimator": "heuristic-v1", "text": "### Connect to Your Node\n\nOpen [Polkadot.js Apps](https://polkadot.js.org/apps/?rpc=ws%3A%2F%2F127.0.0.1%3A9944#/explorer){target=\\_blank} and click the logo in the top left to switch the node. Activate the **Development** toggle and input your node's domain or IP address. The default WSS endpoint for a local node is:\n\n```bash\nws://127.0.0.1:9944\n```"} +{"page_id": "node-infrastructure-run-a-node-secure-wss", "page_title": "Set Up Secure WebSocket", "index": 0, "depth": 2, "title": "Introduction", "anchor": "introduction", "start_char": 27, "end_char": 600, "estimated_token_count": 103, "token_estimator": "heuristic-v1", "text": "## Introduction\n\nEnsuring secure WebSocket communication is crucial for maintaining the integrity and security of a Polkadot or Kusama node when interacting with remote clients. This guide walks you through setting up a secure WebSocket (WSS) connection for your node by leveraging SSL encryption with popular web server proxies like nginx or Apache.\n\nBy the end of this guide, you'll be able to secure your node's WebSocket port, enabling safe remote connections without exposing your node to unnecessary risks. The instructions in this guide are for UNIX-based systems."} +{"page_id": "node-infrastructure-run-a-node-secure-wss", "page_title": "Set Up Secure WebSocket", "index": 1, "depth": 2, "title": "Secure a WebSocket Port", "anchor": "secure-a-websocket-port", "start_char": 600, "end_char": 1053, "estimated_token_count": 102, "token_estimator": "heuristic-v1", "text": "## Secure a WebSocket Port\n\nYou can convert a non-secured WebSocket port to a secure WSS port by placing it behind an SSL-enabled proxy. This approach can be used to secure a bootnode or RPC server. The SSL-enabled apache2/nginx/other proxy server redirects requests to the internal WebSocket and converts it to a secure (WSS) connection. You can use a service like [LetsEncrypt](https://letsencrypt.org/){target=\\_blank} to obtain an SSL certificate."} +{"page_id": "node-infrastructure-run-a-node-secure-wss", "page_title": "Set Up Secure WebSocket", "index": 2, "depth": 3, "title": "Obtain an SSL Certificate", "anchor": "obtain-an-ssl-certificate", "start_char": 1053, "end_char": 2080, "estimated_token_count": 257, "token_estimator": "heuristic-v1", "text": "### Obtain an SSL Certificate\n\nLetsEncrypt suggests using the [Certbot ACME client](https://letsencrypt.org/getting-started/#with-shell-access/){target=\\_blank} for your respective web server implementation to get a free SSL certificate:\n\n- [nginx](https://certbot.eff.org/instructions?ws=nginx&os=ubuntufocal){target=\\_blank}\n- [apache2](https://certbot.eff.org/instructions?ws=apache&os=ubuntufocal){target=\\_blank}\n \nLetsEncrypt will auto-generate an SSL certificate and include it in your configuration.\n\nWhen connecting, you can generate a self-signed certificate and rely on your node's raw IP address. However, self-signed certificates aren't optimal because you must include the certificate in an allowlist to access it from a browser.\n\nUse the following command to generate a self-signed certificate using OpenSSL:\n\n```bash\nsudo openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout /etc/ssl/private/selfsigned.key -out /etc/ssl/certs/selfsigned.crt\nsudo openssl dhparam -out /etc/ssl/certs/dhparam.pem 2048\n```"} +{"page_id": "node-infrastructure-run-a-node-secure-wss", "page_title": "Set Up Secure WebSocket", "index": 3, "depth": 2, "title": "Install a Proxy Server", "anchor": "install-a-proxy-server", "start_char": 2080, "end_char": 2477, "estimated_token_count": 99, "token_estimator": "heuristic-v1", "text": "## Install a Proxy Server\n\nThere are a lot of different implementations of a WebSocket proxy; some of the more widely used are [nginx](https://www.f5.com/go/product/welcome-to-nginx){target=\\_blank} and [apache2](https://httpd.apache.org/){target=\\_blank}, both of which are commonly used web server implementations. See the following section for configuration examples for both implementations."} +{"page_id": "node-infrastructure-run-a-node-secure-wss", "page_title": "Set Up Secure WebSocket", "index": 4, "depth": 3, "title": "Use nginx", "anchor": "use-nginx", "start_char": 2477, "end_char": 3219, "estimated_token_count": 154, "token_estimator": "heuristic-v1", "text": "### Use nginx\n\n1. Install the `nginx` web server: \n ```bash\n apt install nginx\n ```\n\n2. In an SSL-enabled virtual host, add:\n ```conf\n server {\n (...)\n location / {\n proxy_buffers 16 4k;\n proxy_buffer_size 2k;\n proxy_pass http://localhost:9944;\n proxy_http_version 1.1;\n proxy_set_header Upgrade $http_upgrade;\n proxy_set_header Connection \"Upgrade\";\n proxy_set_header Host $host;\n }\n }\n ```\n3. Optionally, you can introduce some form of rate limiting:\n ```conf\n http {\n limit_req_zone \"$http_x_forwarded_for\" zone=zone:10m rate=2r/s;\n (...)\n }\n location / {\n limit_req zone=zone burst=5;\n (...)\n }\n ```"} +{"page_id": "node-infrastructure-run-a-node-secure-wss", "page_title": "Set Up Secure WebSocket", "index": 5, "depth": 3, "title": "Use Apache2", "anchor": "use-apache2", "start_char": 3219, "end_char": 5047, "estimated_token_count": 406, "token_estimator": "heuristic-v1", "text": "### Use Apache2\n\nApache2 can run in various modes, including `prefork`, `worker`, and `event`. In this example, the [`event`](https://httpd.apache.org/docs/2.4/mod/event.html){target=\\_blank} mode is recommended for handling higher traffic loads, as it is optimized for performance in such environments. However, depending on the specific requirements of your setup, other modes like `prefork` or `worker` may also be appropriate.\n\n1. Install the `apache2` web server:\n ```bash\n apt install apache2\n a2dismod mpm_prefork\n a2enmod mpm_event proxy proxy_html proxy_http proxy_wstunnel rewrite ssl\n ```\n2. The [`mod_proxy_wstunnel`](https://httpd.apache.org/docs/2.4/mod/mod_proxy_wstunnel.html){target=\\_blank} provides support for the tunneling of WebSocket connections to a backend WebSocket server. The connection is automatically upgraded to a WebSocket connection. In an SSL-enabled virtual host add:\n\n ```apacheconf\n # (...)\n SSLProxyEngine on\n ProxyRequests off\n ProxyPass / ws://localhost:9944\n ProxyPassReverse / ws://localhost:9944\n ```\n !!!warning \n Older versions of `mod_proxy_wstunnel` don't upgrade the connection automatically and will need the following config added:\n ```apacheconf\n RewriteEngine on\n RewriteCond %{HTTP:Upgrade} websocket [NC]\n RewriteRule /(.*) ws://localhost:9944/$1 [P,L]\n RewriteRule /(.*) http://localhost:9944/$1 [P,L]\n ```\n\n3. Optionally, some form of rate limiting can be introduced by first running the following command:\n\n ```bash\n apt install libapache2-mod-qos\n a2enmod qos\n ```\n\n Then edit `/etc/apache2/mods-available/qos.conf` as follows:\n\n ```conf\n # allows max 50 connections from a single IP address:\n QS_SrvMaxConnPerIP 50\n ```"} +{"page_id": "node-infrastructure-run-a-node-secure-wss", "page_title": "Set Up Secure WebSocket", "index": 6, "depth": 2, "title": "Connect to the Node", "anchor": "connect-to-the-node", "start_char": 5047, "end_char": 5568, "estimated_token_count": 159, "token_estimator": "heuristic-v1", "text": "## Connect to the Node\n\n1. Open [Polkadot.js Apps interface](https://polkadot.js.org/apps){target=\\_blank} and click the logo in the top left to switch the node.\n2. Activate the **Development** toggle and input either your node's domain or IP address. Remember to prefix with `wss://` and, if you're using the 443 port, append `:443` as follows:\n\n ```bash\n wss://example.com:443\n ```\n\n![A sync-in-progress chain connected to Polkadot.js UI](/images/node-infrastructure/run-a-node/secure-wss/secure-wss-01.webp)"} +{"page_id": "node-infrastructure-run-a-validator-onboarding-and-offboarding-key-management", "page_title": "Validator Key Management", "index": 0, "depth": 2, "title": "Introduction", "anchor": "introduction", "start_char": 18, "end_char": 577, "estimated_token_count": 118, "token_estimator": "heuristic-v1", "text": "## Introduction\n\nAfter setting up your node environment as shown in the [Setup](/node-infrastructure/run-a-validator/onboarding-and-offboarding/set-up-validator/){target=\\_blank} section, you'll need to configure multiple keys for your validator to operate properly. This includes setting up session keys, which are essential for participating in the consensus process, and configuring a node key that maintains a stable network identity. This guide walks you through the key management process, showing you how to generate, store, and register these keys."} +{"page_id": "node-infrastructure-run-a-validator-onboarding-and-offboarding-key-management", "page_title": "Validator Key Management", "index": 1, "depth": 2, "title": "Set Session Keys", "anchor": "set-session-keys", "start_char": 577, "end_char": 1107, "estimated_token_count": 100, "token_estimator": "heuristic-v1", "text": "## Set Session Keys\n\nSetting up your validator's session keys is essential to associate your node with your stash account on the Polkadot network. Validators use session keys to participate in the consensus process. Your validator can only perform its role in the network by properly setting session keys which consist of several key pairs for different parts of the protocol (e.g., GRANDPA, BABE). These keys must be registered on-chain and associated with your validator node to ensure it can participate in validating blocks."} +{"page_id": "node-infrastructure-run-a-validator-onboarding-and-offboarding-key-management", "page_title": "Validator Key Management", "index": 2, "depth": 3, "title": "Generate Session Keys", "anchor": "generate-session-keys", "start_char": 1107, "end_char": 4121, "estimated_token_count": 648, "token_estimator": "heuristic-v1", "text": "### Generate Session Keys\n\nThere are multiple ways to create the session keys. It can be done by interacting with the [Polkadot.js Apps UI](https://polkadot.js.org/apps/#/explorer){target=\\_blank}, using the curl command or by using [Subkey](https://paritytech.github.io/polkadot-sdk/master/subkey/index.html){target=\\_blank}.\n\n=== \"Polkadot.js Apps UI\"\n\n 1. In Polkadot.js Apps, connect to your local node, navigate to the **Developer** dropdown, and select the **RPC Calls** option.\n\n 2. Construct an `author_rotateKeys` RPC call and execute it:\n\n 1. Select the **author** endpoint.\n 2. Choose the **rotateKeys()** call.\n 3. Click the **Submit RPC Call** button.\n 4. Copy the hex-encoded public key from the response.\n\n ![](/images/node-infrastructure/run-a-validator/onboarding-and-offboarding/key-management/key-management-01.webp)\n\n=== \"Curl\"\n\n Generate session keys by running the following command on your validator node:\n\n ``` bash\n curl -H \"Content-Type: application/json\" \\\n -d '{\"id\":1, \"jsonrpc\":\"2.0\", \"method\": \"author_rotateKeys\", \"params\":[]}' \\\n http://localhost:9944\n ```\n\n This command will return a JSON object. The `result` key is the hex-encoded public part of the newly created session key. Save this for later use.\n \n ```json\n {\"jsonrpc\":\"2.0\",\"result\":\"0xda3861a45e0197f3ca145c2c209f9126e5053fas503e459af4255cf8011d51010\",\"id\":1}\n ```\n\n=== \"Subkey\"\n\n To create a keypair for your node's session keys, use the `subkey generate` command. This generates a set of cryptographic keys that must be stored in your node's keystore directory.\n\n When you run the command, it produces output similar to this example:\n\n
\n subkey generate\n
\n    Secret phrase:       twist buffalo mixture excess device drastic vague mammal fitness punch match hammer\n      Network ID:        substrate\n      Secret seed:       0x5faa9e5defe42b201388d5c2b8202d6625a344abc9aa52943a71f12cb90b88a9\n      Public key (hex):  0x28cc2fdb6e28835e2bbac9a16feb65c23d448c9314ef12fe083b61bab8fc2755\n      Account ID:        0x28cc2fdb6e28835e2bbac9a16feb65c23d448c9314ef12fe083b61bab8fc2755\n      Public key (SS58): 5CzCRpXzHYhuo6G3gYFR3cgV6X3qCNwVt51m8q14ZcChsSXQ\n      SS58 Address:      5CzCRpXzHYhuo6G3gYFR3cgV6X3qCNwVt51m8q14ZcChsSXQ\n      
\n
\n\n To properly store these keys, create a file in your keystore directory with a specific naming convention. The filename must consist of the hex string `61757261` (which represents \"aura\" in hex) followed by the public key without its `0x` prefix.\n\n Using the example above, you would create a file named:\n\n ```\n ./keystores/6175726128cc2fdb6e28835e2bbac9a16feb65c23d448c9314ef12fe083b61bab8fc2755\n ```\n\n And store only the secret phrase in the file:\n\n ```\n \"twist buffalo mixture excess device drastic vague mammal fitness punch match hammer\"\n ```"} +{"page_id": "node-infrastructure-run-a-validator-onboarding-and-offboarding-key-management", "page_title": "Validator Key Management", "index": 3, "depth": 3, "title": "Submit Transaction to Set Keys", "anchor": "submit-transaction-to-set-keys", "start_char": 4121, "end_char": 4757, "estimated_token_count": 152, "token_estimator": "heuristic-v1", "text": "### Submit Transaction to Set Keys\n\nNow that you have generated your session keys, you must submit them to the chain. Follow these steps:\n\n1. Go to the **Network > Staking > Accounts** section on Polkadot.js Apps.\n2. Select **Set Session Key** on the bonding account you generated earlier.\n3. Paste the hex-encoded session key string you generated (from either the UI or CLI) into the input field and submit the transaction.\n\n![](/images/node-infrastructure/run-a-validator/onboarding-and-offboarding/key-management/key-management-02.webp)\n\nOnce the transaction is signed and submitted, your session keys will be registered on-chain."} +{"page_id": "node-infrastructure-run-a-validator-onboarding-and-offboarding-key-management", "page_title": "Validator Key Management", "index": 4, "depth": 3, "title": "Verify Session Key Setup", "anchor": "verify-session-key-setup", "start_char": 4757, "end_char": 5302, "estimated_token_count": 138, "token_estimator": "heuristic-v1", "text": "### Verify Session Key Setup\n\nTo verify that your session keys are properly set, you can use one of two RPC calls:\n\n- **`hasKey`**: Checks if the node has a specific key by public key and key type.\n- **`hasSessionKeys`**: Verifies if your node has the full session key string associated with the validator.\n\nFor example, you can [check session keys on the Polkadot.js Apps](https://polkadot.js.org/apps/#/rpc){target=\\_blank} interface or by running an RPC query against your node. Once this is done, your validator node is ready for its role."} +{"page_id": "node-infrastructure-run-a-validator-onboarding-and-offboarding-key-management", "page_title": "Validator Key Management", "index": 5, "depth": 2, "title": "Set the Node Key", "anchor": "set-the-node-key", "start_char": 5302, "end_char": 6944, "estimated_token_count": 408, "token_estimator": "heuristic-v1", "text": "## Set the Node Key\n\nValidators on Polkadot need a static network key (also known as the node key) to maintain a stable node identity. This key ensures that your validator can maintain a consistent peer ID, even across restarts, which is crucial for maintaining reliable network connections.\n\nStarting with Polkadot version 1.11, validators without a stable network key may encounter the following error on startup:\n\n
\n polkadot --validator --name \"INSERT_NAME_FROM_TELEMETRY\"\n Error:\n 0: Starting an authority without network key\n This is not a safe operation because other authorities in the network may depend on your node having a stable identity.\n Otherwise these other authorities may not being able to reach you.\n If it is the first time running your node you could use one of the following methods:\n 1. [Preferred] Separately generate the key with: INSERT_NODE_BINARY key generate-node-key --base-path INSERT_YOUR_BASE_PATH\n 2. [Preferred] Separately generate the key with: INSERT_NODE_BINARY key generate-node-key --file INSERT_YOUR_PATH_TO_NODE_KEY\n 3. [Preferred] Separately generate the key with: INSERT_NODE_BINARY key generate-node-key --default-base-path\n 4. [Unsafe] Pass --unsafe-force-node-key-generation and make sure you remove it for subsequent node restarts\n \n
"} +{"page_id": "node-infrastructure-run-a-validator-onboarding-and-offboarding-key-management", "page_title": "Validator Key Management", "index": 6, "depth": 3, "title": "Generate the Node Key", "anchor": "generate-the-node-key", "start_char": 6944, "end_char": 7605, "estimated_token_count": 144, "token_estimator": "heuristic-v1", "text": "### Generate the Node Key\n\nUse one of the following methods to generate your node key:\n\n=== \"Save to file\"\n\n The recommended solution is to generate a node key and save it to a file using the following command:\n\n ``` bash\n polkadot key generate-node-key --file INSERT_PATH_TO_NODE_KEY\n ```\n \n=== \"Use default path\"\n\n You can also generate the node key with the following command, which will automatically save the key to the base path of your node:\n\n ``` bash\n polkadot key generate-node-key --default-base-path\n ```\n\nSave the file path for reference. You will need it in the next step to configure your node with a static identity."} +{"page_id": "node-infrastructure-run-a-validator-onboarding-and-offboarding-key-management", "page_title": "Validator Key Management", "index": 7, "depth": 3, "title": "Set Node Key", "anchor": "set-node-key", "start_char": 7605, "end_char": 8227, "estimated_token_count": 132, "token_estimator": "heuristic-v1", "text": "### Set Node Key\n\nAfter generating the node key, configure your node to use it by specifying the path to the key file when launching your node. Add the following flag to your validator node's startup command:\n\n``` bash\npolkadot --node-key-file INSERT_PATH_TO_NODE_KEY\n```\n\nFollowing these steps ensures that your node retains its identity, making it discoverable by peers without the risk of conflicting identities across sessions. For further technical background, see Polkadot SDK [Pull Request #3852](https://github.com/paritytech/polkadot-sdk/pull/3852){target=\\_blank} for the rationale behind requiring static keys."} +{"page_id": "node-infrastructure-run-a-validator-onboarding-and-offboarding-set-up-validator", "page_title": "Set Up a Validator", "index": 0, "depth": 2, "title": "Introduction", "anchor": "introduction", "start_char": 22, "end_char": 642, "estimated_token_count": 101, "token_estimator": "heuristic-v1", "text": "## Introduction\n\nSetting up a Polkadot validator node is essential for securing the network and earning staking rewards. This guide walks you through the technical steps to set up a validator, from installing the necessary software to managing keys and synchronizing your node with the chain.\n\nRunning a validator requires a commitment to maintaining a stable, secure infrastructure. Validators are responsible for their own stakes and those of nominators who trust them with their tokens. Proper setup and ongoing management are critical to ensuring smooth operation and avoiding potential penalties such as slashing."} +{"page_id": "node-infrastructure-run-a-validator-onboarding-and-offboarding-set-up-validator", "page_title": "Set Up a Validator", "index": 1, "depth": 2, "title": "Prerequisites", "anchor": "prerequisites", "start_char": 642, "end_char": 1744, "estimated_token_count": 279, "token_estimator": "heuristic-v1", "text": "## Prerequisites\n\nTo get the most from this guide, ensure you've done the following before going forward:\n\n- Read [Validator Requirements](/node-infrastructure/run-a-validator/requirements/){target=\\_blank} and understand the recommended minimum skill level and hardware needs.\n- Read [General Management](/node-infrastructure/run-a-validator/operational-tasks/general-management/){target=\\_blank}, [Upgrade Your Node](/node-infrastructure/run-a-validator/operational-tasks/upgrade-your-node/){target=\\_blank}, and [Pause Validating](/node-infrastructure/run-a-validator/operational-tasks/pause-validating/){target=\\_blank} and understand the tasks required to keep your validator operational.\n- Read [Rewards Payout](/node-infrastructure/run-a-validator/staking-mechanics/rewards/){target=\\_blank} and understand how validator rewards are determined and paid out.\n- Read [Offenses and Slashes](/node-infrastructure/run-a-validator/staking-mechanics/offenses-and-slashes/){target=\\_blank} and understand how validator performance and security can affect tokens staked by you or your nominators."} +{"page_id": "node-infrastructure-run-a-validator-onboarding-and-offboarding-set-up-validator", "page_title": "Set Up a Validator", "index": 2, "depth": 2, "title": "Initial Setup", "anchor": "initial-setup", "start_char": 1744, "end_char": 2300, "estimated_token_count": 94, "token_estimator": "heuristic-v1", "text": "## Initial Setup\n\nBefore running your validator, you must configure your server environment to meet the operational and security standards required for validating.\n\nYou must use a Linux-based operating system with Kernel 5.16 or later. Configuration includes setting up time synchronization, ensuring critical security features are active, and installing the necessary binaries. Proper setup at this stage is essential to prevent issues like block production errors or being penalized for downtime. Below are the essential steps to get your system ready."} +{"page_id": "node-infrastructure-run-a-validator-onboarding-and-offboarding-set-up-validator", "page_title": "Set Up a Validator", "index": 3, "depth": 3, "title": "Install Network Time Protocol Client", "anchor": "install-network-time-protocol-client", "start_char": 2300, "end_char": 3412, "estimated_token_count": 236, "token_estimator": "heuristic-v1", "text": "### Install Network Time Protocol Client\n\nAccurate timekeeping is critical to ensure your validator is synchronized with the network. Validators need local clocks in sync with the blockchain to avoid missing block authorship opportunities. Using [Network Time Protocol (NTP)](https://en.wikipedia.org/wiki/Network_Time_Protocol){target=\\_blank} is the standard solution to keep your system's clock accurate.\n\nIf you are using Ubuntu version 18.04 or newer, the NTP Client should be installed by default. You can check whether you have the NTP client by running:\n\n```sh\ntimedatectl\n```\n\nIf NTP is running, you should see a message like the following:\n\n``` sh\nSystem clock synchronized: yes\n```\n\nIf NTP is not installed or running, you can install it using:\n\n```sh\nsudo apt-get install ntp\n```\n\nAfter installation, NTP will automatically start. To check its status:\n\n```sh\nsudo ntpq -p\n```\n\nThis command will return a message with the status of the NTP synchronization. Skipping this step could result in your validator node missing blocks due to minor clock drift, potentially affecting its network performance."} +{"page_id": "node-infrastructure-run-a-validator-onboarding-and-offboarding-set-up-validator", "page_title": "Set Up a Validator", "index": 4, "depth": 3, "title": "Verify Landlock is Activated", "anchor": "verify-landlock-is-activated", "start_char": 3412, "end_char": 5009, "estimated_token_count": 319, "token_estimator": "heuristic-v1", "text": "### Verify Landlock is Activated\n\n[Landlock](https://docs.kernel.org/userspace-api/landlock.html){target=\\_blank} is an important security feature integrated into Linux kernels starting with version 5.13. It allows processes, even those without special privileges, to limit their access to the system to reduce the machine's attack surface. This feature is crucial for validators, as it helps ensure the security and stability of the node by preventing unauthorized access or malicious behavior.\n\nTo use Landlock, ensure you use the reference kernel or newer versions. Most Linux distributions should already have Landlock activated. You can check if Landlock is activated on your machine by running the following command as root:\n\n```sh\ndmesg | grep landlock || journalctl -kg landlock\n```\n\nIf Landlock is not activated, your system logs won't show any related output. In this case, you will need to activate it manually or ensure that your Linux distribution supports it. Most modern distributions with the required kernel version should have Landlock activated by default. However, if your system lacks support, you may need to build the kernel with Landlock activated. For more information on doing so, refer to the [official kernel documentation](https://docs.kernel.org/userspace-api/landlock.html#kernel-support){target=\\_blank}.\n\nImplementing Landlock ensures your node operates in a restricted, self-imposed sandbox, limiting potential damage from security breaches or bugs. While not a mandatory requirement, enabling this feature greatly improves the security of your validator setup."} +{"page_id": "node-infrastructure-run-a-validator-onboarding-and-offboarding-set-up-validator", "page_title": "Set Up a Validator", "index": 5, "depth": 2, "title": "Install the Polkadot Binaries", "anchor": "install-the-polkadot-binaries", "start_char": 5009, "end_char": 5435, "estimated_token_count": 82, "token_estimator": "heuristic-v1", "text": "## Install the Polkadot Binaries\n\nYou must install the Polkadot binaries required to run your validator node. These binaries include the main `polkadot`, `polkadot-prepare-worker`, and `polkadot-execute-worker` binaries. All three are needed to run a fully functioning validator node.\n\nDepending on your preference and operating system setup, there are multiple methods to install these binaries. Below are the main options:"} +{"page_id": "node-infrastructure-run-a-validator-onboarding-and-offboarding-set-up-validator", "page_title": "Set Up a Validator", "index": 6, "depth": 3, "title": "Install from Official Releases", "anchor": "install-from-official-releases", "start_char": 5435, "end_char": 8225, "estimated_token_count": 622, "token_estimator": "heuristic-v1", "text": "### Install from Official Releases\n\nThe preferred, most straightforward method to install the required binaries is downloading the latest versions from the official releases. You can visit the [Github Releases](https://github.com/paritytech/polkadot-sdk/releases){target=\\_blank} page for the most current versions of the `polkadot`, `polkadot-prepare-worker`, and `polkadot-execute-worker` binaries.\n\nYou can also download the binaries by using the following direct links:\n\n=== \"`polkadot`\"\n\n ``` bash\n # Download the binary\n curl -LO https://github.com/paritytech/polkadot-sdk/releases/download/polkadot-stable2506-2/polkadot\n\n # Verify signature\n curl -LO https://github.com/paritytech/polkadot-sdk/releases/download/polkadot-stable2506-2/polkadot.asc\n \n gpg --keyserver hkps://keyserver.ubuntu.com --receive-keys 90BD75EBBB8E95CB3DA6078F94A4029AB4B35DAE\n\n gpg --verify polkadot.asc\n ```\n\n=== \"`polkadot-prepare-worker`\"\n\n ``` bash\n # Download the binary\n curl -LO https://github.com/paritytech/polkadot-sdk/releases/download/polkadot-stable2506-2/polkadot-prepare-worker\n\n # Verify signature\n curl -LO https://github.com/paritytech/polkadot-sdk/releases/download/polkadot-stable2506-2/polkadot-prepare-worker.asc\n\n gpg --keyserver hkps://keyserver.ubuntu.com --receive-keys 90BD75EBBB8E95CB3DA6078F94A4029AB4B35DAE\n\n gpg --verify polkadot-prepare-worker.asc\n ```\n\n=== \"`polkadot-execute-worker`\"\n\n ``` bash\n # Download the binary\n curl -LO https://github.com/paritytech/polkadot-sdk/releases/download/polkadot-stable2506-2/polkadot-execute-worker\n\n # Verify signature\n curl -LO https://github.com/paritytech/polkadot-sdk/releases/download/polkadot-stable2506-2/polkadot-execute-worker.asc\n\n gpg --keyserver hkps://keyserver.ubuntu.com --receive-keys 90BD75EBBB8E95CB3DA6078F94A4029AB4B35DAE\n\n gpg --verify polkadot-execute-worker.asc\n ```\n\n\nSignature verification cryptographically ensures the downloaded binaries are authentic and have not been tampered with by using GPG signing keys. Polkadot releases use two different signing keys:\n\n- ParityReleases (release-team@parity.io) with key [`90BD75EBBB8E95CB3DA6078F94A4029AB4B35DAE`](https://keyserver.ubuntu.com/pks/lookup?search=90BD75EBBB8E95CB3DA6078F94A4029AB4B35DAE&fingerprint=on&op=index){target=\\_blank} for current and new releases.\n- Parity Security Team (security@parity.io) with key [`9D4B2B6EB8F97156D19669A9FF0812D491B96798`](https://keyserver.ubuntu.com/pks/lookup?search=9D4B2B6EB8F97156D19669A9FF0812D491B96798&fingerprint=on&op=index){target=\\_blank} for old releases.\n\n !!!warning\n When verifying a signature, a \"Good signature\" message indicates successful verification, while any other output signals a potential security risk."} +{"page_id": "node-infrastructure-run-a-validator-onboarding-and-offboarding-set-up-validator", "page_title": "Set Up a Validator", "index": 7, "depth": 3, "title": "Install with Package Managers", "anchor": "install-with-package-managers", "start_char": 8225, "end_char": 9292, "estimated_token_count": 241, "token_estimator": "heuristic-v1", "text": "### Install with Package Managers\n\nUsers running Debian-based distributions like Ubuntu can install the binaries using the [APT](https://wiki.debian.org/Apt){target=\\_blank} package manager.\n\nExecute the following commands as root to add the official repository and install the binaries:\n\n```bash\n# Import the release-team@parity.io GPG key\ngpg --keyserver hkps://keyserver.ubuntu.com --receive-keys 90BD75EBBB8E95CB3DA6078F94A4029AB4B35DAE\ngpg --export 90BD75EBBB8E95CB3DA6078F94A4029AB4B35DAE > /usr/share/keyrings/parity.gpg\n\n# Add the Parity repository and update the package index\necho 'deb [signed-by=/usr/share/keyrings/parity.gpg] https://releases.parity.io/deb release main' > /etc/apt/sources.list.d/parity.list\napt update\n\n# Install the `parity-keyring` package - This will ensure the GPG key\n# used by APT remains up-to-date\napt install parity-keyring\n\n# Install polkadot\napt install polkadot\n```\n\nOnce installation completes, verify the binaries are correctly installed by following the steps in the [verify installation](#verify-installation) section."} +{"page_id": "node-infrastructure-run-a-validator-onboarding-and-offboarding-set-up-validator", "page_title": "Set Up a Validator", "index": 8, "depth": 3, "title": "Install with Ansible", "anchor": "install-with-ansible", "start_char": 9292, "end_char": 9649, "estimated_token_count": 70, "token_estimator": "heuristic-v1", "text": "### Install with Ansible\n\nYou can also manage Polkadot installations using Ansible. This approach can be beneficial for users managing multiple validator nodes or requiring automated deployment. The [Parity chain operations Ansible collection](https://github.com/paritytech/ansible-galaxy/){target=\\_blank} provides a Substrate node role for this purpose."} +{"page_id": "node-infrastructure-run-a-validator-onboarding-and-offboarding-set-up-validator", "page_title": "Set Up a Validator", "index": 9, "depth": 3, "title": "Install with Docker", "anchor": "install-with-docker", "start_char": 9649, "end_char": 9932, "estimated_token_count": 60, "token_estimator": "heuristic-v1", "text": "### Install with Docker\n\nIf you prefer using Docker or an OCI-compatible container runtime, the official Polkadot Docker image can be pulled directly from Docker Hub.\n\nTo pull the latest stable image, run the following command:\n\n```bash\ndocker pull parity/polkadot:stable2506-2\n```"} +{"page_id": "node-infrastructure-run-a-validator-onboarding-and-offboarding-set-up-validator", "page_title": "Set Up a Validator", "index": 10, "depth": 3, "title": "Build from Sources", "anchor": "build-from-sources", "start_char": 9932, "end_char": 10165, "estimated_token_count": 58, "token_estimator": "heuristic-v1", "text": "### Build from Sources\n\nYou may build the binaries from source by following the instructions on the [Polkadot SDK repository](https://github.com/paritytech/polkadot-sdk/tree/polkadot-stable2506-2/polkadot#building){target=\\_blank}."} +{"page_id": "node-infrastructure-run-a-validator-onboarding-and-offboarding-set-up-validator", "page_title": "Set Up a Validator", "index": 11, "depth": 2, "title": "Verify Installation", "anchor": "verify-installation", "start_char": 10165, "end_char": 11921, "estimated_token_count": 430, "token_estimator": "heuristic-v1", "text": "## Verify Installation\n\nOnce the Polkadot binaries are installed, it's essential to verify that everything is set up correctly and that all the necessary components are in place. Follow these steps to ensure the binaries are installed and functioning as expected.\n\n1. **Check the versions**: Run the following commands to verify the versions of the installed binaries.\n\n ```bash\n polkadot --version\n polkadot-execute-worker --version\n polkadot-prepare-worker --version\n ```\n\n The output should show the version numbers for each of the binaries. Ensure that the versions match and are consistent, similar to the following example (the specific version may vary):\n\n
\n polkadot --version polkadot-execute-worker --version polkadot-prepare-worker --version\n 1.16.1-36264cb36db\n 1.16.1-36264cb36db\n 1.16.1-36264cb36db\n \n
\n\n If the versions do not match or if there is an error, double-check that all the binaries were correctly installed and are accessible within your `$PATH`.\n\n2. **Ensure all binaries are in the same directory**: All the binaries must be in the same directory for the Polkadot validator node to function properly. If the binaries are not in the same location, move them to a unified directory and ensure this directory is added to your system's `$PATH`.\n\n To verify the `$PATH`, run the following command:\n\n ```bash\n echo $PATH\n ```\n\n If necessary, you can move the binaries to a shared location, such as `/usr/local/bin/`, and add it to your `$PATH`."} +{"page_id": "node-infrastructure-run-a-validator-onboarding-and-offboarding-start-validating", "page_title": "Start Validating", "index": 0, "depth": 2, "title": "Introduction", "anchor": "introduction", "start_char": 20, "end_char": 449, "estimated_token_count": 94, "token_estimator": "heuristic-v1", "text": "## Introduction\n\nAfter configuring your node keys as shown in the [Key Management](/node-infrastructure/run-a-validator/onboarding-and-offboarding/key-management/){target=\\_blank} section and ensuring your system is set up, you're ready to begin the validator setup process. This guide will walk you through choosing a network, synchronizing your node with the blockchain, bonding your DOT tokens, and starting your validator."} +{"page_id": "node-infrastructure-run-a-validator-onboarding-and-offboarding-start-validating", "page_title": "Start Validating", "index": 1, "depth": 2, "title": "Choose a Network", "anchor": "choose-a-network", "start_char": 449, "end_char": 1438, "estimated_token_count": 193, "token_estimator": "heuristic-v1", "text": "## Choose a Network\n\nRunning your validator on a test network like Westend or Kusama is a smart way to familiarize yourself with the process and identify any setup issues in a lower-stakes environment before joining the Polkadot MainNet.\n\n- **Westend**: Polkadot's primary TestNet is open to anyone for testing purposes. Validator slots are intentionally limited to keep the network stable for the Polkadot release process, so it may not support as many validators at any given time.\n- **Kusama**: Often called Polkadot's \"canary network,\" Kusama has real economic value but operates with a faster and more experimental approach. Running a validator here provides an experience closer to MainNet with the benefit of more frequent validation opportunities with an era time of 6 hours vs 24 hours for Polkadot.\n- **Polkadot**: The main network, where validators secure the Polkadot relay chain. It has a slower era time of 24 hours and requires a higher minimum bond amount to participate."} +{"page_id": "node-infrastructure-run-a-validator-onboarding-and-offboarding-start-validating", "page_title": "Start Validating", "index": 2, "depth": 2, "title": "Synchronize Chain Data", "anchor": "synchronize-chain-data", "start_char": 1438, "end_char": 4716, "estimated_token_count": 857, "token_estimator": "heuristic-v1", "text": "## Synchronize Chain Data\n\nThe next step is to sync your node with the chosen blockchain network. Synchronization is necessary to download and validate the blockchain data, ensuring your node is ready to participate as a validator. Follow these steps to sync your node:\n\n1. **Start syncing**: You can run a full or warp sync.\n\n === \"Full sync\"\n\n Polkadot defaults to using a full sync, which downloads and validates the entire blockchain history from the genesis block. Start the syncing process by running the following command:\n\n ```sh\n polkadot\n ```\n\n This command starts your Polkadot node in non-validator mode, allowing you to synchronize the chain data.\n\n === \"Warp sync\"\n\n You can opt to use warp sync which initially downloads only GRANDPA finality proofs and the latest finalized block's state. Use the following command to start a warp sync:\n\n ``` bash\n polkadot --sync warp\n ```\n\n Warp sync ensures that your node quickly updates to the latest finalized state. The historical blocks are downloaded in the background as the node continues to operate.\n\n If you're planning to run a validator on a TestNet, you can specify the chain using the `--chain` flag. For example, the following will run a validator on Kusama:\n\n ```sh\n polkadot --chain=kusama\n ```\n\n2. **Monitor sync progress**: Once the sync starts, you will see a stream of logs providing information about the node's status and progress. Here's an example of what the output might look like:\n\n
\n polkadot\n 2021-06-17 03:07:07 Parity Polkadot\n 2021-06-17 03:07:07 ✌️ version 0.9.5-95f6aa201-x86_64-linux-gnu\n 2021-06-17 03:07:07 ❤️ by Parity Technologies <admin@parity.io>, 2017-2021\n 2021-06-17 03:07:07 📋 Chain specification: Polkadot\n 2021-06-17 03:07:07 🏷 Node name: boiling-pet-7554\n 2021-06-17 03:07:07 👤 Role: FULL\n 2021-06-17 03:07:07 💾 Database: RocksDb at /root/.local/share/polkadot/chains/polkadot/db\n 2021-06-17 03:07:07 ⛓ Native runtime: polkadot-9050 (parity-polkadot-0.tx7.au0)\n 2021-06-17 03:07:10 🏷 Local node identity is: 12D3KooWLtXFWf1oGrnxMGmPKPW54xWCHAXHbFh4Eap6KXmxoi9u\n 2021-06-17 03:07:10 📦 Highest known block at #17914\n 2021-06-17 03:07:10 〽️ Prometheus server started at 127.0.0.1:9615\n 2021-06-17 03:07:10 Listening for new connections on 127.0.0.1:9944\n ...\n
\n\n The output logs provide information such as the current block number, node name, and network connections. Monitor the sync progress and any errors that might occur during the process. Look for information about the latest processed block and compare it with the current highest block using tools like [Telemetry](https://telemetry.polkadot.io/#list/Polkadot%20CC1){target=\\_blank} or [Polkadot.js Apps Explorer](https://polkadot.js.org/apps/#/explorer){target=\\_blank}."} +{"page_id": "node-infrastructure-run-a-validator-onboarding-and-offboarding-start-validating", "page_title": "Start Validating", "index": 3, "depth": 3, "title": "Database Snapshot Services", "anchor": "database-snapshot-services", "start_char": 4716, "end_char": 6683, "estimated_token_count": 628, "token_estimator": "heuristic-v1", "text": "### Database Snapshot Services\n\nIf you'd like to speed up the process further, you can use a database snapshot. Snapshots are compressed backups of the blockchain's database directory and can significantly reduce the time required to sync a new node. Here are a few public snapshot providers:\n\n- [Stakeworld](https://stakeworld.io/snapshot){target=\\_blank}\n- [Polkachu](https://polkachu.com/substrate_snapshots){target=\\_blank}\n- [Polkashots](https://polkashots.io/){target=\\_blank}\n- [ITRocket](https://itrocket.net/services/mainnet/polkadot/#snapshot){target=\\_blank}\n\n!!!warning\n Although snapshots are convenient, syncing from scratch is recommended for security purposes. If snapshots become corrupted and most nodes rely on them, the network could inadvertently run on a non-canonical chain.\n\n
\n polkadot\n 2021-06-17 03:07:07 Idle (0 peers), best: #0 (0x3fd7...5baf), finalized #0 (0x3fd7...5baf), ⬇ 2.9kiB/s ⬆ 3.7kiB/s\n 2021-06-17 03:07:12 Idle (0 peers), best: #0 (0x3fd7...5baf), finalized #0 (0x3fd7...5baf), ⬇ 1.7kiB/s ⬆ 2.0kiB/s\n 2021-06-17 03:07:17 Idle (0 peers), best: #0 (0x3fd7...5baf), finalized #0 (0x3fd7...5baf), ⬇ 0.9kiB/s ⬆ 1.2kiB/s\n 2021-06-17 03:07:19 Libp2p => Random Kademlia query has yielded empty results\n 2021-06-17 03:08:00 Idle (0 peers), best: #0 (0x3fd7...5baf), finalized #0 (0x3fd7...5baf), ⬇ 1.6kiB/s ⬆ 1.9kiB/s\n 2021-06-17 03:08:05 Idle (0 peers), best: #0 (0x3fd7...5baf), finalized #0 (0x3fd7...5baf), ⬇ 0.6kiB/s ⬆ 0.9kiB/s\n ...\n
\n\nIf you see terminal output similar to the preceding, and you are unable to synchronize the chain due to having zero peers, make sure you have libp2p port `30333` activated. It will take some time to discover other peers over the network."} +{"page_id": "node-infrastructure-run-a-validator-onboarding-and-offboarding-start-validating", "page_title": "Start Validating", "index": 4, "depth": 2, "title": "Bond DOT", "anchor": "bond-dot", "start_char": 6683, "end_char": 7251, "estimated_token_count": 123, "token_estimator": "heuristic-v1", "text": "## Bond DOT\n\nOnce your validator node is synced, the next step is bonding DOT. A bonded account, or stash, holds your staked tokens (DOT) that back your validator node. Bonding your DOT means locking it for a period, during which it cannot be transferred or spent but is used to secure your validator's role in the network. Visit the [Minimum Bond Requirement](/node-infrastructure/run-a-validator/requirements/#minimum-bond-requirement) section for details on how much DOT is required.\n\nThe following sections will guide you through bonding DOT for your validator."} +{"page_id": "node-infrastructure-run-a-validator-onboarding-and-offboarding-start-validating", "page_title": "Start Validating", "index": 5, "depth": 3, "title": "Bonding DOT on Polkadot.js Apps", "anchor": "bonding-dot-on-polkadotjs-apps", "start_char": 7251, "end_char": 8852, "estimated_token_count": 382, "token_estimator": "heuristic-v1", "text": "### Bonding DOT on Polkadot.js Apps\n\nOnce you're ready to bond your DOT, head over to the [Polkadot.js Apps](https://polkadot.js.org/apps/){target=\\_blank} staking page by clicking the **Network** dropdown at the top of the page and selecting [**Staking**](https://polkadot.js.org/apps/#/staking/actions){target=\\_blank}.\n\nTo get started with the bond submission, click on the **Accounts** tab, then the **+ Stash** button, and then enter the following information:\n\n1. **Stash account**: Select your stash account (which is the account with the DOT/KSM balance).\n2. **Value bonded**: Enter how much DOT from the stash account you want to bond/stake. You are not required to bond all of the DOT in that account and you may bond more DOT at a later time. Be aware, withdrawing any bonded amount requires waiting for the unbonding period. The unbonding period is seven days for Kusama and 28 days for Polkadot.\n3. **Payment destination**: Add the recipient account for validator rewards. If you'd like to redirect payments to an account that is not the stash account, you can do it by entering the address here. Note that it is extremely unsafe to set an exchange address as the recipient of the staking rewards.\n\nOnce everything is filled in properly, select **Bond** and sign the transaction with your stash account. If successful, you should see an `ExtrinsicSuccess` message.\n\nYour bonded account will be available under **Stashes**. After refreshing the screen, you should now see a card with all your accounts. The bonded amount on the right corresponds to the funds bonded by the stash account."} +{"page_id": "node-infrastructure-run-a-validator-onboarding-and-offboarding-start-validating", "page_title": "Start Validating", "index": 6, "depth": 2, "title": "Validate", "anchor": "validate", "start_char": 8852, "end_char": 9080, "estimated_token_count": 45, "token_estimator": "heuristic-v1", "text": "## Validate\n\nOnce your validator node is fully synced and ready, the next step is to ensure it's visible on the network and performing as expected. Below are steps for monitoring and managing your node on the Polkadot network."} +{"page_id": "node-infrastructure-run-a-validator-onboarding-and-offboarding-start-validating", "page_title": "Start Validating", "index": 7, "depth": 3, "title": "Verify Sync via Telemetry", "anchor": "verify-sync-via-telemetry", "start_char": 9080, "end_char": 9807, "estimated_token_count": 153, "token_estimator": "heuristic-v1", "text": "### Verify Sync via Telemetry\n\nTo confirm that your validator is live and synchronized with the Polkadot network, visit the [Telemetry](https://telemetry.polkadot.io/#list/Polkadot%20CC1){target=\\_blank} page. Telemetry provides real-time information on node performance and can help you check if your validator is connected properly. Search for your node by name. You can search all nodes currently active on the network, which is why you should use a unique name for easy recognition. Now, confirm that your node is fully synced by comparing the block height of your node with the network's latest block. Nodes that are fully synced will appear white in the list, while nodes that are not yet fully synced will appear gray."} +{"page_id": "node-infrastructure-run-a-validator-onboarding-and-offboarding-start-validating", "page_title": "Start Validating", "index": 8, "depth": 3, "title": "Activate using Polkadot.js Apps", "anchor": "activate-using-polkadotjs-apps", "start_char": 9807, "end_char": 11126, "estimated_token_count": 362, "token_estimator": "heuristic-v1", "text": "### Activate using Polkadot.js Apps\n\nFollow these steps to use Polkadot.js Apps to activate your validator:\n\n1. In Polkadot.js Apps, navigate to **Network** and select **Staking**:\n\n ![](/images/node-infrastructure/run-a-validator/onboarding-and-offboarding/start-validating/start-validating-01.webp)\n\n2. Open the **Accounts** tab and click on **+ Validator**:\n\n ![](/images/node-infrastructure/run-a-validator/onboarding-and-offboarding/start-validating/start-validating-02.webp)\n\n3. Set a bond amount in the **value bonded** field and then click **next**:\n\n ![](/images/node-infrastructure/run-a-validator/onboarding-and-offboarding/start-validating/start-validating-03.webp)\n\n4. Paste the hex output from `author_rotateKeys`, set the commission, allow or block new nominations, then click **Bond & Validate** to link your validator with its session keys.\n\n ![](/images/node-infrastructure/run-a-validator/onboarding-and-offboarding/start-validating/start-validating-04.webp)\n\n You can also set the **commission** and **blocked** nominations option via `staking.validate` extrinsic. By default, the blocked option is set to FALSE (i.e., the validator accepts nominations).\n\n ![](/images/node-infrastructure/run-a-validator/onboarding-and-offboarding/start-validating/start-validating-05.webp)"} +{"page_id": "node-infrastructure-run-a-validator-onboarding-and-offboarding-start-validating", "page_title": "Start Validating", "index": 9, "depth": 3, "title": "Monitor Validation Status and Slots", "anchor": "monitor-validation-status-and-slots", "start_char": 11126, "end_char": 12080, "estimated_token_count": 221, "token_estimator": "heuristic-v1", "text": "### Monitor Validation Status and Slots\n\nOn the [**Staking**](https://polkadot.js.org/apps/#/staking){target=\\_blank} tab in Polkadot.js Apps, you can see your validator's status, the number of available validator slots, and the nodes that have signaled their intent to validate. Your node may initially appear in the waiting queue, especially if the validator slots are full. The following is an example view of the **Staking** tab:\n\n![staking queue](/images/node-infrastructure/run-a-validator/onboarding-and-offboarding/start-validating/start-validating-06.webp)\n\nThe validator set refreshes each era. If there's an available slot in the next era, your node may be selected to move from the waiting queue to the active validator set, allowing it to start validating blocks. If your validator is not selected, it remains in the waiting queue. Increasing your stake or gaining more nominators may improve your chance of being selected in future eras."} +{"page_id": "node-infrastructure-run-a-validator-onboarding-and-offboarding-start-validating", "page_title": "Start Validating", "index": 10, "depth": 2, "title": "Run a Validator Using Systemd", "anchor": "run-a-validator-using-systemd", "start_char": 12080, "end_char": 13106, "estimated_token_count": 222, "token_estimator": "heuristic-v1", "text": "## Run a Validator Using Systemd\n\nRunning your Polkadot validator as a [systemd](https://en.wikipedia.org/wiki/Systemd){target=\\_blank} service is an effective way to ensure its high uptime and reliability. Using systemd allows your validator to automatically restart after server reboots or unexpected crashes, significantly reducing the risk of slashing due to downtime.\n\nThis following sections will walk you through creating and managing a systemd service for your validator, allowing you to seamlessly monitor and control it as part of your Linux system. \n\nEnsure the following requirements are met before proceeding with the systemd setup:\n\n- Confirm your system meets the [requirements](/node-infrastructure/run-a-validator/requirements/){target=\\_blank} for running a validator.\n- Ensure you meet the [minimum bond requirements](https://wiki.polkadot.com/general/chain-state-values/#minimum-validator-bond){target=\\_blank} for validating.\n- Verify the Polkadot binary is [installed](#install-the-polkadot-binaries)."} +{"page_id": "node-infrastructure-run-a-validator-onboarding-and-offboarding-start-validating", "page_title": "Start Validating", "index": 11, "depth": 3, "title": "Create the Systemd Service File", "anchor": "create-the-systemd-service-file", "start_char": 13106, "end_char": 14845, "estimated_token_count": 338, "token_estimator": "heuristic-v1", "text": "### Create the Systemd Service File\n\nFirst create a new unit file called `polkadot-validator.service` in `/etc/systemd/system/`:\n\n```bash\ntouch /etc/systemd/system/polkadot-validator.service\n```\n\nIn this unit file, you will write the commands that you want to run on server boot/restart:\n\n```systemd title=\"/etc/systemd/system/polkadot-validator.service\"\n[Unit]\nDescription=Polkadot Node\nAfter=network.target\nDocumentation=https://github.com/paritytech/polkadot-sdk\n\n[Service]\nEnvironmentFile=-/etc/default/polkadot\nExecStart=/usr/bin/polkadot $POLKADOT_CLI_ARGS\nUser=polkadot\nGroup=polkadot\nRestart=always\nRestartSec=120\nCapabilityBoundingSet=\nLockPersonality=true\nNoNewPrivileges=true\nPrivateDevices=true\nPrivateMounts=true\nPrivateTmp=true\nPrivateUsers=true\nProtectClock=true\nProtectControlGroups=true\nProtectHostname=true\nProtectKernelModules=true\nProtectKernelTunables=true\nProtectSystem=strict\nRemoveIPC=true\nRestrictAddressFamilies=AF_INET AF_INET6 AF_NETLINK AF_UNIX\nRestrictNamespaces=false\nRestrictSUIDSGID=true\nSystemCallArchitectures=native\nSystemCallFilter=@system-service\nSystemCallFilter=landlock_add_rule landlock_create_ruleset landlock_restrict_self seccomp mount umount2\nSystemCallFilter=~@clock @module @reboot @swap @privileged\nSystemCallFilter=pivot_root\nUMask=0027\n\n[Install]\nWantedBy=multi-user.target\n```\n\n!!! warning \"Restart delay and equivocation risk\"\n It is recommended that a node's restart be delayed with `RestartSec` in the case of a crash. It's possible that when a node crashes, consensus votes in GRANDPA aren't persisted to disk. In this case, there is potential to equivocate when immediately restarting. Delaying the restart will allow the network to progress past potentially conflicting votes."} +{"page_id": "node-infrastructure-run-a-validator-onboarding-and-offboarding-start-validating", "page_title": "Start Validating", "index": 12, "depth": 3, "title": "Run the Service", "anchor": "run-the-service", "start_char": 14845, "end_char": 15820, "estimated_token_count": 243, "token_estimator": "heuristic-v1", "text": "### Run the Service\n\nActivate the systemd service to start on system boot by running:\n\n```bash\nsystemctl enable polkadot-validator.service\n```\n\nTo start the service manually, use:\n\n```bash\nsystemctl start polkadot-validator.service\n```\n\nCheck the service's status to confirm it is running:\n\n```bash\nsystemctl status polkadot-validator.service\n```\n\nTo view the logs in real-time, use [journalctl](https://www.freedesktop.org/software/systemd/man/latest/journalctl.html){target=\\_blank} like so:\n\n```bash\njournalctl -f -u polkadot-validator\n```\n\nWith these steps, you can effectively manage and monitor your validator as a systemd service.\n\nOnce your validator is active, it's officially part of Polkadot's security infrastructure. For questions or further support, you can reach out to the [Polkadot Validator chat](https://matrix.to/#/!NZrbtteFeqYKCUGQtr:matrix.parity.io?via=matrix.parity.io&via=matrix.org&via=web3.foundation){target=\\_blank} for tips and troubleshooting."} +{"page_id": "node-infrastructure-run-a-validator-onboarding-and-offboarding-stop-validating", "page_title": "Stop Validating", "index": 0, "depth": 2, "title": "Introduction", "anchor": "introduction", "start_char": 19, "end_char": 498, "estimated_token_count": 89, "token_estimator": "heuristic-v1", "text": "## Introduction\n\nIf you're ready to stop validating on Polkadot, there are essential steps to ensure a smooth transition while protecting your funds and account integrity. Whether you're taking a break for maintenance or unbonding entirely, you'll need to chill your validator, purge session keys, and unbond your tokens. This guide explains how to use Polkadot's tools and extrinsics to safely withdraw from validation activities, safeguarding your account's future usability."} +{"page_id": "node-infrastructure-run-a-validator-onboarding-and-offboarding-stop-validating", "page_title": "Stop Validating", "index": 1, "depth": 2, "title": "Pause Versus Stop", "anchor": "pause-versus-stop", "start_char": 498, "end_char": 920, "estimated_token_count": 83, "token_estimator": "heuristic-v1", "text": "## Pause Versus Stop\n\nIf you wish to remain a validator or nominator (for example, stopping for planned downtime or server maintenance), submitting the `chill` extrinsic in the `staking` pallet should suffice. Additional steps are only needed to unbond funds or reap an account.\n\nThe following are steps to ensure a smooth stop to validation:\n\n- Chill the validator.\n- Purge validator session keys.\n- Unbond your tokens."} +{"page_id": "node-infrastructure-run-a-validator-onboarding-and-offboarding-stop-validating", "page_title": "Stop Validating", "index": 2, "depth": 2, "title": "Chill Validator", "anchor": "chill-validator", "start_char": 920, "end_char": 1501, "estimated_token_count": 121, "token_estimator": "heuristic-v1", "text": "## Chill Validator\n\nWhen stepping back from validating, the first step is to chill your validator status. This action stops your validator from being considered for the next era without fully unbonding your tokens, which can be useful for temporary pauses like maintenance or planned downtime.\n\nUse the `staking.chill` extrinsic to initiate this. For more guidance on chilling your node, refer to the [Pause Validating](/node-infrastructure/run-a-validator/operational-tasks/pause-validating/){target=\\_blank} guide. You may also claim any pending staking rewards at this point."} +{"page_id": "node-infrastructure-run-a-validator-onboarding-and-offboarding-stop-validating", "page_title": "Stop Validating", "index": 3, "depth": 2, "title": "Purge Validator Session Keys", "anchor": "purge-validator-session-keys", "start_char": 1501, "end_char": 2532, "estimated_token_count": 194, "token_estimator": "heuristic-v1", "text": "## Purge Validator Session Keys\n\nPurging validator session keys is a critical step in removing the association between your validator account and its session keys, which ensures that your account is fully disassociated from validator activities. The `session.purgeKeys` extrinsic removes the reference to your session keys from the stash or staking proxy account that originally set them.\n\nHere are a couple of important things to know about purging keys:\n\n- **Account used to purge keys**: Always use the same account to purge keys you originally used to set them, usually your stash or staking proxy account. Using a different account may leave an unremovable reference to the session keys on the original account, preventing its reaping.\n- **Account reaping issue**: Failing to purge keys will prevent you from reaping (fully deleting) your stash account. If you attempt to transfer tokens without purging, you'll need to rebond, purge the session keys, unbond again, and wait through the unbonding period before any transfer."} +{"page_id": "node-infrastructure-run-a-validator-onboarding-and-offboarding-stop-validating", "page_title": "Stop Validating", "index": 4, "depth": 2, "title": "Unbond Your Tokens", "anchor": "unbond-your-tokens", "start_char": 2532, "end_char": 3230, "estimated_token_count": 142, "token_estimator": "heuristic-v1", "text": "## Unbond Your Tokens\n\nAfter chilling your node and purging session keys, the final step is to unbond your staked tokens. This action removes them from staking and begins the unbonding period (usually 28 days for Polkadot and seven days for Kusama), after which the tokens will be transferable.\n\nTo unbond tokens, go to **Network > Staking > Account Actions** on Polkadot.js Apps. Select your stash account, click on the dropdown menu, and choose **Unbond Funds**. Alternatively, you can use the `staking.unbond` extrinsic if you handle this via a staking proxy account.\n\nOnce the unbonding period is complete, your tokens will be available for use in transactions or transfers outside of staking."} +{"page_id": "node-infrastructure-run-a-validator-operational-tasks-general-management", "page_title": "General Management", "index": 0, "depth": 2, "title": "Introduction", "anchor": "introduction", "start_char": 22, "end_char": 759, "estimated_token_count": 119, "token_estimator": "heuristic-v1", "text": "## Introduction\n\nValidator performance is pivotal in maintaining the security and stability of the Polkadot network. As a validator, optimizing your setup ensures efficient transaction processing, minimizes latency, and maintains system reliability during high-demand periods. Proper configuration and proactive monitoring also help mitigate risks like slashing and service interruptions.\n\nThis guide covers essential practices for managing a validator, including performance tuning techniques, security hardening, and tools for real-time monitoring. Whether you're fine-tuning CPU settings, configuring NUMA balancing, or setting up a robust alert system, these steps will help you build a resilient and efficient validator operation."} +{"page_id": "node-infrastructure-run-a-validator-operational-tasks-general-management", "page_title": "General Management", "index": 1, "depth": 2, "title": "Configuration Optimization", "anchor": "configuration-optimization", "start_char": 759, "end_char": 987, "estimated_token_count": 35, "token_estimator": "heuristic-v1", "text": "## Configuration Optimization\n\nFor those seeking to optimize their validator's performance, the following configurations can improve responsiveness, reduce latency, and ensure consistent performance during high-demand periods."} +{"page_id": "node-infrastructure-run-a-validator-operational-tasks-general-management", "page_title": "General Management", "index": 2, "depth": 3, "title": "Deactivate Simultaneous Multithreading", "anchor": "deactivate-simultaneous-multithreading", "start_char": 987, "end_char": 2478, "estimated_token_count": 333, "token_estimator": "heuristic-v1", "text": "### Deactivate Simultaneous Multithreading\n\nPolkadot validators operate primarily in single-threaded mode for critical tasks, so optimizing single-core CPU performance can reduce latency and improve stability. Deactivating simultaneous multithreading (SMT) can prevent virtual cores from affecting performance. SMT is called Hyper-Threading on Intel and 2-way SMT on AMD Zen.\n\nTake the following steps to deactivate every other (vCPU) core:\n\n1. Loop though all the CPU cores and deactivate the virtual cores associated with them:\n\n ```bash\n for cpunum in $(cat /sys/devices/system/cpu/cpu*/topology/thread_siblings_list | \\\n cut -s -d, -f2- | tr ',' '\\n' | sort -un)\n do\n echo 0 > /sys/devices/system/cpu/cpu$cpunum/online\n done\n ```\n\n2. To permanently save the changes, add `nosmt=force` to the `GRUB_CMDLINE_LINUX_DEFAULT` variable in `/etc/default/grub`:\n\n ```bash\n sudo nano /etc/default/grub\n # Add to GRUB_CMDLINE_LINUX_DEFAULT\n ```\n\n ```config title=\"/etc/default/grub\"\n GRUB_DEFAULT = 0;\n GRUB_HIDDEN_TIMEOUT = 0;\n GRUB_HIDDEN_TIMEOUT_QUIET = true;\n GRUB_TIMEOUT = 10;\n GRUB_DISTRIBUTOR = `lsb_release -i -s 2> /dev/null || echo Debian`;\n GRUB_CMDLINE_LINUX_DEFAULT = 'nosmt=force';\n GRUB_CMDLINE_LINUX = '';\n ```\n\n3. Update GRUB to apply changes:\n\n ```bash\n sudo update-grub\n ```\n\n4. After the reboot, you should see that half of the cores are offline. To confirm, run:\n\n ```bash\n lscpu --extended\n ```"} +{"page_id": "node-infrastructure-run-a-validator-operational-tasks-general-management", "page_title": "General Management", "index": 3, "depth": 3, "title": "Deactivate Automatic NUMA Balancing", "anchor": "deactivate-automatic-numa-balancing", "start_char": 2478, "end_char": 3554, "estimated_token_count": 220, "token_estimator": "heuristic-v1", "text": "### Deactivate Automatic NUMA Balancing\n\nDeactivating NUMA (Non-Uniform Memory Access) balancing for multi-CPU setups helps keep processes on the same CPU node, minimizing latency.\n\nFollow these stpes:\n\n1. Deactivate NUMA balancing in runtime:\n\n ```bash\n sysctl kernel.numa_balancing=0\n ```\n\n2. Deactivate NUMA balancing permanently by adding `numa_balancing=disable` to the GRUB settings:\n\n ```bash\n sudo nano /etc/default/grub\n # Add to GRUB_CMDLINE_LINUX_DEFAULT\n ```\n\n ```config title=\"/etc/default/grub\"\n GRUB_DEFAULT = 0;\n GRUB_HIDDEN_TIMEOUT = 0;\n GRUB_HIDDEN_TIMEOUT_QUIET = true;\n GRUB_TIMEOUT = 10;\n GRUB_DISTRIBUTOR = `lsb_release -i -s 2> /dev/null || echo Debian`;\n GRUB_CMDLINE_LINUX_DEFAULT = 'numa_balancing=disable';\n GRUB_CMDLINE_LINUX = '';\n ```\n\n3. Update GRUB to apply changes:\n\n ```bash\n sudo update-grub\n ```\n\n4. Confirm the deactivation:\n\n ```bash\n sysctl -a | grep 'kernel.numa_balancing'\n ```\n\nIf you successfully deactivated NUMA balancing, the preceding command should return `0`."} +{"page_id": "node-infrastructure-run-a-validator-operational-tasks-general-management", "page_title": "General Management", "index": 4, "depth": 3, "title": "Spectre and Meltdown Mitigations", "anchor": "spectre-and-meltdown-mitigations", "start_char": 3554, "end_char": 5210, "estimated_token_count": 319, "token_estimator": "heuristic-v1", "text": "### Spectre and Meltdown Mitigations\n\n[Spectre](https://en.wikipedia.org/wiki/Spectre_(security_vulnerability)){target=\\_blank} and [Meltdown](https://en.wikipedia.org/wiki/Meltdown_(security_vulnerability)){target=\\_blank} are well-known CPU vulnerabilities that exploit speculative execution to access sensitive data. These vulnerabilities have been patched in recent Linux kernels, but the mitigations can slightly impact performance, especially in high-throughput or containerized environments.\n\nIf your security requirements allow it, you can deactivate specific mitigations, such as Spectre V2 and Speculative Store Bypass Disable (SSBD), to improve performance.\n\nTo selectively deactivate the Spectre mitigations, take these steps:\n\n1. Update the `GRUB_CMDLINE_LINUX_DEFAULT` variable in your `/etc/default/grub` configuration:\n\n ```bash\n sudo nano /etc/default/grub\n # Add to GRUB_CMDLINE_LINUX_DEFAULT\n ```\n\n ```config title=\"/etc/default/grub\"\n GRUB_DEFAULT = 0;\n GRUB_HIDDEN_TIMEOUT = 0;\n GRUB_HIDDEN_TIMEOUT_QUIET = true;\n GRUB_TIMEOUT = 10;\n GRUB_DISTRIBUTOR = `lsb_release -i -s 2> /dev/null || echo Debian`;\n GRUB_CMDLINE_LINUX_DEFAULT =\n 'spec_store_bypass_disable=prctl spectre_v2_user=prctl';\n ```\n\n2. Update GRUB to apply changes and then reboot:\n\n ```bash\n sudo update-grub\n sudo reboot\n ```\n\nThis approach selectively deactivates the Spectre V2 and Spectre V4 mitigations, leaving other protections intact. For full security, keep mitigations activated unless there's a significant performance need, as disabling them could expose the system to potential attacks on affected CPUs."} +{"page_id": "node-infrastructure-run-a-validator-operational-tasks-general-management", "page_title": "General Management", "index": 5, "depth": 2, "title": "Monitor Your Node", "anchor": "monitor-your-node", "start_char": 5210, "end_char": 5907, "estimated_token_count": 167, "token_estimator": "heuristic-v1", "text": "## Monitor Your Node\n\nMonitoring your node's performance is critical for network reliability and security. Tools like the following provide valuable insights:\n\n- **[Prometheus](https://prometheus.io/){target=\\_blank}**: An open-source monitoring toolkit for collecting and querying time-series data.\n- **[Grafana](https://grafana.com/){target=\\_blank}**: A visualization tool for real-time metrics, providing interactive dashboards.\n- **[Alertmanager](https://prometheus.io/docs/alerting/latest/alertmanager/){target=\\_blank}**: A tool for managing and routing alerts based on Prometheus data.\n\nThis section covers setting up these tools and configuring alerts to notify you of potential issues."} +{"page_id": "node-infrastructure-run-a-validator-operational-tasks-general-management", "page_title": "General Management", "index": 6, "depth": 3, "title": "Environment Setup", "anchor": "environment-setup", "start_char": 5907, "end_char": 6601, "estimated_token_count": 141, "token_estimator": "heuristic-v1", "text": "### Environment Setup\n\nBefore installing Prometheus, ensure the environment is set up securely by running Prometheus with restricted user privileges.\n\nFollow these steps:\n\n1. Create a Prometheus user to ensure Prometheus runs with minimal permissions:\n\n ```bash\n sudo useradd --no-create-home --shell /usr/sbin/nologin prometheus\n ```\n\n2. Create directories for configuration and data storage:\n\n ```bash\n sudo mkdir /etc/prometheus\n sudo mkdir /var/lib/prometheus\n ```\n \n3. Change directory ownership to ensure Prometheus has access:\n\n ```bash\n sudo chown -R prometheus:prometheus /etc/prometheus\n sudo chown -R prometheus:prometheus /var/lib/prometheus\n ```"} +{"page_id": "node-infrastructure-run-a-validator-operational-tasks-general-management", "page_title": "General Management", "index": 7, "depth": 3, "title": "Install and Configure Prometheus", "anchor": "install-and-configure-prometheus", "start_char": 6601, "end_char": 9085, "estimated_token_count": 545, "token_estimator": "heuristic-v1", "text": "### Install and Configure Prometheus\n\nAfter setting up the environment, install and configure the latest version of Prometheus as follows:\n\n1. Download Prometheus for your system architecture from the [releases page](https://github.com/prometheus/prometheus/releases/){target=\\_blank}. Replace `INSERT_RELEASE_DOWNLOAD` with the release binary URL (e.g., `https://github.com/prometheus/prometheus/releases/download/v3.0.0/prometheus-3.0.0.linux-amd64.tar.gz`):\n\n ```bash\n sudo apt-get update && sudo apt-get upgrade\n wget INSERT_RELEASE_DOWNLOAD_LINK\n tar xfz prometheus-*.tar.gz\n cd prometheus-3.0.0.linux-amd64\n ```\n\n2. Set up Prometheus:\n\n 1. Copy binaries:\n\n ```bash\n sudo cp ./prometheus /usr/local/bin/\n sudo cp ./promtool /usr/local/bin/\n sudo cp ./prometheus /usr/local/bin/\n ```\n\n 2. Copy directories and assign ownership of these files to the `prometheus` user:\n\n ```bash\n sudo cp -r ./consoles /etc/prometheus\n sudo cp -r ./console_libraries /etc/prometheus\n sudo chown -R prometheus:prometheus /etc/prometheus/consoles\n sudo chown -R prometheus:prometheus /etc/prometheus/console_libraries\n ```\n\n 3. Clean up the download directory:\n\n ```bash\n cd .. && rm -r prometheus*\n ```\n\n3. Create `prometheus.yml` to define global settings, rule files, and scrape targets:\n\n ```bash\n sudo nano /etc/prometheus/prometheus.yml\n ```\n\n {% raw %}\n ```yaml title=\"prometheus-config.yml\"\n global:\n scrape_interval: 15s\n evaluation_interval: 15s\n\n rule_files:\n # - \"first.rules\"\n # - \"second.rules\"\n\n scrape_configs:\n - job_name: 'prometheus'\n scrape_interval: 5s\n static_configs:\n - targets: ['localhost:9090']\n - job_name: 'substrate_node'\n scrape_interval: 5s\n static_configs:\n - targets: ['localhost:9615']\n ```\n {% endraw %}\n\n Prometheus is scraped every 5 seconds in this example configuration file, ensuring detailed internal metrics. Node metrics with customizable intervals are scraped from port `9615` by default.\n\n4. Verify the configuration with `promtool`, an open source monitoring tool:\n\n ```bash\n promtool check config /etc/prometheus/prometheus.yml\n ```\n\n5. Save the configuration and change the ownership of the file to `prometheus` user:\n\n ```bash\n sudo chown prometheus:prometheus /etc/prometheus/prometheus.yml\n ```"} +{"page_id": "node-infrastructure-run-a-validator-operational-tasks-general-management", "page_title": "General Management", "index": 8, "depth": 3, "title": "Start Prometheus", "anchor": "start-prometheus", "start_char": 9085, "end_char": 10918, "estimated_token_count": 410, "token_estimator": "heuristic-v1", "text": "### Start Prometheus\n\n1. Launch Prometheus with the appropriate configuration file, storage location, and necessary web resources, running it with restricted privileges for security:\n\n ```bash\n sudo -u prometheus /usr/local/bin/prometheus --config.file /etc/prometheus/prometheus.yml \\\n --storage.tsdb.path /var/lib/prometheus/ \\\n --web.console.templates=/etc/prometheus/consoles \\\n --web.console.libraries=/etc/prometheus/console_libraries\n ```\n\n If you set the server up properly, you should see terminal output similar to the following:\n\n \n2. Verify you can access the Prometheus interface by navigating to:\n\n ```text\n http://SERVER_IP_ADDRESS:9090/graph\n ```\n\n If the interface appears to work as expected, exit the process using `Control + C`.\n\n3. Create a systemd service file to ensure Prometheus starts on boot:\n\n ```bash\n sudo nano /etc/systemd/system/prometheus.service\n ```\n\n ```bash title=\"prometheus.service\"\n [Unit]\n Description=Prometheus Monitoring\n Wants=network-online.target\n After=network-online.target\n\n [Service]\n User=prometheus\n Group=prometheus\n Type=simple\n ExecStart=/usr/local/bin/prometheus \\\n --config.file /etc/prometheus/prometheus.yml \\\n --storage.tsdb.path /var/lib/prometheus/ \\\n --web.console.templates=/etc/prometheus/consoles \\\n --web.console.libraries=/etc/prometheus/console_libraries\n ExecReload=/bin/kill -HUP $MAINPID\n\n [Install]\n WantedBy=multi-user.target\n\n ```\n\n4. Reload systemd and enable the service to start on boot:\n\n ```bash\n sudo systemctl daemon-reload && sudo systemctl enable prometheus && sudo systemctl start prometheus\n ```\n\n5. Verify the service is running by visiting the Prometheus interface again at:\n\n ```text\n http://SERVER_IP_ADDRESS:9090/\n ```"} +{"page_id": "node-infrastructure-run-a-validator-operational-tasks-general-management", "page_title": "General Management", "index": 9, "depth": 3, "title": "Install and Configure Grafana", "anchor": "install-and-configure-grafana", "start_char": 10918, "end_char": 14591, "estimated_token_count": 931, "token_estimator": "heuristic-v1", "text": "### Install and Configure Grafana\n\nThis guide follows [Grafana's canonical installation instructions](https://grafana.com/docs/grafana/latest/setup-grafana/installation/debian/#install-from-apt-repository){target=\\_blank}.\n\nTo install and configure Grafana, follow these steps:\n\n1. Install Grafana prerequisites:\n\n ```bash\n sudo apt-get install -y apt-transport-https software-properties-common wget \n ```\n\n2. Import the [GPG key](https://gnupg.org/){target=\\_blank}:\n\n ```bash\n sudo mkdir -p /etc/apt/keyrings/\n wget -q -O - https://apt.grafana.com/gpg.key | gpg --dearmor | sudo tee /etc/apt/keyrings/grafana.gpg > /dev/null\n ```\n\n3. Configure the stable release repo and update packages:\n\n ```bash\n echo \"deb [signed-by=/etc/apt/keyrings/grafana.gpg] https://apt.grafana.com stable main\" | sudo tee -a /etc/apt/sources.list.d/grafana.list\n sudo apt-get update\n ```\n\n4. Install the latest stable version of Grafana:\n\n ```bash\n sudo apt-get install grafana\n ```\n\nTo configure Grafana, take these steps:\n\n1. Configure Grafana to start automatically on boot and start the service:\n\n ```bash\n sudo systemctl daemon-reload\n sudo systemctl enable grafana-server.service\n sudo systemctl start grafana-server\n ```\n\n2. Check if Grafana is running:\n\n ```bash\n sudo systemctl status grafana-server\n ```\n\n If necessary, you can stop or restart the service with the following commands:\n\n ```bash\n sudo systemctl stop grafana-server\n sudo systemctl restart grafana-server\n ```\n\n3. Access Grafana by navigating to the following URL and logging in with the default username and password (`admin`):\n\n ```text\n http://SERVER_IP_ADDRESS:3000/login\n ```\n\n !!! tip \"Change default port\"\n To change Grafana's port, edit `/usr/share/grafana/conf/defaults.ini`:\n\n ```bash\n sudo vim /usr/share/grafana/conf/defaults.ini\n ```\n\n Modify the `http_port` value, then restart Grafana:\n\n ```bash\n sudo systemctl restart grafana-server\n ```\n\n![Grafana login screen](/images/node-infrastructure/run-a-validator/operational-tasks/general-management/general-management-01.webp)\n\nTo visualize node metrics, follow these steps:\n\n1. Select the gear icon to access **Data Sources** settings.\n2. Select **Add data source** to define the data source.\n\n ![Select Prometheus](/images/node-infrastructure/run-a-validator/operational-tasks/general-management/general-management-02.webp)\n\n3. Select **Prometheus**.\n\n ![Save and test](/images/node-infrastructure/run-a-validator/operational-tasks/general-management/general-management-03.webp)\n\n4. Enter `http://localhost:9090` in the **URL** field and click **Save & Test**. If **\"Data source is working\"** appears, your connection is configured correctly.\n\n ![Import dashboard](/images/node-infrastructure/run-a-validator/operational-tasks/general-management/general-management-04.webp)\n\n5. Select **Import** from the left menu, choose **Prometheus** from the dropdown, and click **Import**.\n\n6. Start your Polkadot node by running `./polkadot`. You should now be able to monitor node performance, block height, network traffic, and tasks tasks on the Grafana dashboard.\n\n ![Live dashboard](/images/node-infrastructure/run-a-validator/operational-tasks/general-management/general-management-05.webp)\n\nThe [Grafana dashboards](https://grafana.com/grafana/dashboards){target=\\_blank} page features user created dashboards made available for public use. For an example, see the [Substrate Node Metrics](https://grafana.com/grafana/dashboards/21715-substrate-node-metrics/){target=\\_blank} dashboard."} +{"page_id": "node-infrastructure-run-a-validator-operational-tasks-general-management", "page_title": "General Management", "index": 10, "depth": 3, "title": "Install and Configure Alertmanager", "anchor": "install-and-configure-alertmanager", "start_char": 14591, "end_char": 22147, "estimated_token_count": 1677, "token_estimator": "heuristic-v1", "text": "### Install and Configure Alertmanager\n\n[Alertmanager](https://prometheus.io/docs/alerting/latest/alertmanager/){target=\\_blank} is an optional component that complements Prometheus by managing alerts and notifying users about potential issues.\n\nFollow these steps to install and configure Alertmanager:\n\n1. Download Alertmanager for your system architecture from the [releases page](https://github.com/prometheus/alertmanager/releases){target=\\_blank}. Replace `INSERT_RELEASE_DOWNLOAD` with the release binary URL (e.g., `https://github.com/prometheus/alertmanager/releases/download/v0.28.0-rc.0/alertmanager-0.28.0-rc.0.linux-amd64.tar.gz`):\n\n ```bash\n wget INSERT_RELEASE_DOWNLOAD_LINK\n tar -xvzf alertmanager*\n ```\n\n2. Copy the binaries to the system directory and set permissions:\n\n ```bash\n cd alertmanager-0.28.0-rc.0.linux-amd64\n sudo cp ./alertmanager /usr/local/bin/\n sudo cp ./amtool /usr/local/bin/\n sudo chown prometheus:prometheus /usr/local/bin/alertmanager\n sudo chown prometheus:prometheus /usr/local/bin/amtool\n ```\n\n3. Create the `alertmanager.yml` configuration file under `/etc/alertmanager`:\n\n ```bash\n sudo mkdir /etc/alertmanager\n sudo nano /etc/alertmanager/alertmanager.yml\n ```\n\n Generate an [app password in your Google account](https://support.google.com/accounts/answer/185833?hl=en){target=\\_blank} to enable email notifications from Alertmanager. Then, add the following code to the configuration file to define email notifications using your email and app password: \n\n {% raw %}\n ```yml title=\"alertmanager.yml\"\n global:\n resolve_timeout: 1m\n\n route:\n receiver: 'gmail-notifications'\n\n receivers:\n - name: 'gmail-notifications'\n email_configs:\n - to: INSERT_YOUR_EMAIL\n from: INSERT_YOUR_EMAIL\n smarthost: smtp.gmail.com:587\n auth_username: INSERT_YOUR_EMAIL\n auth_identity: INSERT_YOUR_EMAIL\n auth_password: INSERT_YOUR_APP_PASSWORD\n send_resolved: true\n\n ```\n {% endraw %}\n\n\n ```bash\n sudo chown -R prometheus:prometheus /etc/alertmanager\n ```\n\n4. Configure Alertmanager as a service by creating a systemd service file:\n\n ```bash\n sudo nano /etc/systemd/system/alertmanager.service\n ```\n\n {% raw %}\n ```yml title=\"alertmanager.service\"\n [Unit]\n Description=AlertManager Server Service\n Wants=network-online.target\n After=network-online.target\n\n [Service]\n User=root\n Group=root\n Type=simple\n ExecStart=/usr/local/bin/alertmanager --config.file /etc/alertmanager/alertmanager.yml --web.external-url=http://SERVER_IP:9093 --cluster.advertise-address='0.0.0.0:9093'\n\n [Install]\n WantedBy=multi-user.target\n\n ```\n {% endraw %}\n\n5. Reload and enable the service:\n\n ```bash\n sudo systemctl daemon-reload\n sudo systemctl enable alertmanager\n sudo systemctl start alertmanager\n ```\n\n6. Verify the service status:\n\n ```bash\n sudo systemctl status alertmanager\n ```\n\n If you have configured Alertmanager properly, the **Active** field should display **active (running)** similar to below:\n\n
\n sudo systemctl status alertmanager\n alertmanager.service - AlertManager Server Service\n Loaded: loaded (/etc/systemd/system/alertmanager.service; enabled; vendor preset: enabled)\n Active: active (running) since Thu 2020-08-20 22:01:21 CEST; 3 days ago\n Main PID: 20592 (alertmanager)\n Tasks: 70 (limit: 9830)\n CGroup: /system.slice/alertmanager.service\n \n
\n\n#### Grafana Plugin\n\nThere is an [Alertmanager plugin in Grafana](https://grafana.com/grafana/plugins/alertmanager/){target=\\_blank} that can help you monitor alert information.\n\nFollow these steps to use the plugin:\n\n1. Install the plugin:\n\n ```bash\n sudo grafana-cli plugins install camptocamp-prometheus-alertmanager-datasource\n ```\n\n2. Restart Grafana:\n\n ```bash\n sudo systemctl restart grafana-server\n ```\n\n3. Configure Alertmanager as a data source in your Grafana dashboard (`SERVER_IP:3000`):\n\n 1. Go to **Configuration** > **Data Sources** and search for **Prometheus Alertmanager**.\n 2. Enter the server URL and port for the Alertmanager service, and select **Save & Test** to verify the connection.\n\n4. Import the [8010](https://grafana.com/grafana/dashboards/8010-prometheus-alertmanager/){target=\\_blank} dashboard for Alertmanager, selecting **Prometheus Alertmanager** in the last column, then select **Import**.\n\n#### Integrate Alertmanager\n\nComplete the integration by following these steps to enable communication between Prometheus and Alertmanager and configure detection and alert rules:\n\n1. Update the `etc/prometheus/prometheus.yml` configuration file to include the following code:\n\n {% raw %}\n ```yml title=\"prometheus.yml\"\n rule_files:\n - 'rules.yml'\n\n alerting:\n alertmanagers:\n - static_configs:\n - targets:\n - localhost:9093\n ```\n {% endraw %}\n\n Expand the following item to view the complete `prometheus.yml` file.\n\n ??? code \"prometheus.yml\"\n\n {% raw %}\n ```yml title=\"prometheus.yml\"\n global:\n scrape_interval: 15s\n evaluation_interval: 15s\n\n rule_files:\n - 'rules.yml'\n\n alerting:\n alertmanagers:\n - static_configs:\n - targets:\n - localhost:9093\n\n scrape_configs:\n - job_name: 'prometheus'\n scrape_interval: 5s\n static_configs:\n - targets: ['localhost:9090']\n - job_name: 'substrate_node'\n scrape_interval: 5s\n static_configs:\n - targets: ['localhost:9615']\n\n ```\n {% endraw %}\n\n2. Create the rules file for detection and alerts:\n\n ```bash\n sudo nano /etc/prometheus/rules.yml\n ```\n\n Add a sample rule to trigger email notifications for node downtime over five minutes:\n\n {% raw %}\n ```yml title=\"rules.yml\"\n groups:\n - name: alert_rules\n rules:\n - alert: InstanceDown\n expr: up == 0\n for: 5m\n labels:\n severity: critical\n annotations:\n summary: 'Instance [{{ $labels.instance }}] down'\n description: '[{{ $labels.instance }}] of job [{{ $labels.job }}] has been down for more than 5 minutes.'\n\n ```\n {% endraw %}\n\n If any of the conditions defined in the rules file are met, an alert will be triggered. For more on alert rules, refer to [Alerting Rules](https://prometheus.io/docs/prometheus/latest/configuration/alerting_rules/){target=\\_blank} and [additional alerts](https://samber.github.io/awesome-prometheus-alerts/rules.html){target=\\_blank}.\n\n3. Update the file ownership to `prometheus`:\n\n ```bash\n sudo chown prometheus:prometheus rules.yml\n ```\n\n4. Validate the rules syntax:\n\n ```bash\n sudo -u prometheus promtool check rules rules.yml\n ```\n\n5. Restart Prometheus and Alertmanager:\n\n ```bash\n sudo systemctl restart prometheus && sudo systemctl restart alertmanager\n ```\n\nNow you will receive an email alert if one of your rule triggering conditions is met."} +{"page_id": "node-infrastructure-run-a-validator-operational-tasks-general-management", "page_title": "General Management", "index": 11, "depth": 2, "title": "Secure Your Validator", "anchor": "secure-your-validator", "start_char": 22147, "end_char": 22499, "estimated_token_count": 58, "token_estimator": "heuristic-v1", "text": "## Secure Your Validator\n\nValidators in Polkadot's Proof of Stake (PoS) network play a critical role in maintaining network integrity and security by keeping the network in consensus and verifying state transitions. To ensure optimal performance and minimize risks, validators must adhere to strict guidelines around security and reliable operations."} +{"page_id": "node-infrastructure-run-a-validator-operational-tasks-general-management", "page_title": "General Management", "index": 12, "depth": 3, "title": "Key Management", "anchor": "key-management", "start_char": 22499, "end_char": 23790, "estimated_token_count": 275, "token_estimator": "heuristic-v1", "text": "### Key Management\n\nThough they don't transfer funds, session keys are essential for validators as they sign messages related to consensus and parachains. Securing session keys is crucial as allowing them to be exploited or used across multiple nodes can lead to a loss of staked funds via [slashing](/node-infrastructure/run-a-validator/staking-mechanics/offenses-and-slashes/){target=\\_blank}.\n\nGiven the current limitations in high-availability setups and the risks associated with double-signing, it’s recommended to run only a single validator instance. Keys should be securely managed, and processes automated to minimize human error.\n\nThere are two approaches for generating session keys:\n\n- **Generate and store in node**: Using the `author.rotateKeys` RPC call. For most users, generating keys directly within the client is recommended. You must submit a session certificate from your staking proxy to register new keys. See the [How to Validate](/node-infrastructure/run-a-validator/onboarding-and-offboarding/set-up-validator/){target=\\_blank} guide for instructions on setting keys.\n\n- **Generate outside node and insert**: Using the `author.setKeys` RPC call. This flexibility accommodates advanced security setups and should only be used by experienced validator operators."} +{"page_id": "node-infrastructure-run-a-validator-operational-tasks-general-management", "page_title": "General Management", "index": 13, "depth": 3, "title": "Signing Outside the Client", "anchor": "signing-outside-the-client", "start_char": 23790, "end_char": 24082, "estimated_token_count": 50, "token_estimator": "heuristic-v1", "text": "### Signing Outside the Client\n\nPolkadot plans to support external signing, allowing session keys to reside in secure environments like Hardware Security Modules (HSMs). However, these modules can sign any payload they receive, potentially enabling an attacker to perform slashable actions."} +{"page_id": "node-infrastructure-run-a-validator-operational-tasks-general-management", "page_title": "General Management", "index": 14, "depth": 3, "title": "Secure-Validator Mode", "anchor": "secure-validator-mode", "start_char": 24082, "end_char": 24843, "estimated_token_count": 169, "token_estimator": "heuristic-v1", "text": "### Secure-Validator Mode\n\nPolkadot's Secure-Validator mode offers an extra layer of protection through strict filesystem, networking, and process sandboxing. This secure mode is activated by default if the machine meets the following requirements:\n\n- **Linux (x86-64 architecture)**: Usually Intel or AMD.\n- **Enabled `seccomp`**: This kernel feature facilitates a more secure approach for process management on Linux. Verify by running.\n\n ```bash\n cat /boot/config-`uname -r` | grep CONFIG_SECCOMP=\n ```\n\n If `seccomp` is enabled, you should see output similar to the following:\n\n ```bash\n CONFIG_SECCOMP=y\n ```\n\n!!! tip \n Optionally, **Linux 5.13** may also be used, as it provides access to even more strict filesystem protections."} +{"page_id": "node-infrastructure-run-a-validator-operational-tasks-general-management", "page_title": "General Management", "index": 15, "depth": 3, "title": "Linux Best Practices", "anchor": "linux-best-practices", "start_char": 24843, "end_char": 25301, "estimated_token_count": 107, "token_estimator": "heuristic-v1", "text": "### Linux Best Practices\n\nFollow these best practices to keep your validator secure:\n\n- Use a non-root user for all operations.\n- Regularly apply OS security patches.\n- Enable and configure a firewall.\n- Use key-based SSH authentication; deactivate password-based login.\n- Regularly back up data and harden your SSH configuration. Visit this [SSH guide](https://blog.stribik.technology/2015/01/04/secure-secure-shell.html){target=\\_blank} for more details."} +{"page_id": "node-infrastructure-run-a-validator-operational-tasks-general-management", "page_title": "General Management", "index": 16, "depth": 3, "title": "Validator Best Practices", "anchor": "validator-best-practices", "start_char": 25301, "end_char": 26059, "estimated_token_count": 147, "token_estimator": "heuristic-v1", "text": "### Validator Best Practices\n\nAdditional best practices can add an additional layer of security and operational reliability:\n\n- Only run the Polkadot binary, and only listen on the configured p2p port.\n- Run on bare-metal machines, as opposed to virtual machines.\n- Provisioning of the validator machine should be automated and defined in code which is kept in private version control, reviewed, audited, and tested.\n- Generate and provide session keys in a secure way.\n- Start Polkadot at boot and restart if stopped for any reason.\n- Run Polkadot as a non-root user.\n- Establish and maintain an on-call rotation for managing alerts.\n- Establish and maintain a clear protocol with actions to perform for each level of each alert with an escalation policy."} +{"page_id": "node-infrastructure-run-a-validator-operational-tasks-general-management", "page_title": "General Management", "index": 17, "depth": 2, "title": "Additional Resources", "anchor": "additional-resources", "start_char": 26059, "end_char": 26673, "estimated_token_count": 163, "token_estimator": "heuristic-v1", "text": "## Additional Resources\n\n- [Certus One's Knowledge Base](https://knowledgebase.certus.com/FAQ/){target=\\_blank}\n- [EOS Block Producer Security List](https://github.com/slowmist/eos-bp-nodes-security-checklist){target=\\_blank}\n- [HSM Policies and the Importance of Validator Security](https://medium.com/loom-network/hsm-policies-and-the-importance-of-validator-security-ec8a4cc1b6f){target=\\_blank}\n\nFor additional guidance, connect with other validators and the Polkadot engineering team in the [Polkadot Validator Lounge](https://matrix.to/#/#polkadotvalidatorlounge:web3.foundation){target=\\_blank} on Element."} +{"page_id": "node-infrastructure-run-a-validator-operational-tasks-pause-validating", "page_title": "Pause Validating", "index": 0, "depth": 2, "title": "Introduction", "anchor": "introduction", "start_char": 20, "end_char": 554, "estimated_token_count": 93, "token_estimator": "heuristic-v1", "text": "## Introduction\n\nIf you need to temporarily stop participating in Polkadot staking activities without fully unbonding your funds, chilling your account allows you to do so efficiently. Chilling removes your node from active validation or nomination in the next era while keeping your funds bonded, making it ideal for planned downtimes or temporary pauses.\n\nThis guide covers the steps for chilling as a validator or nominator, using the `chill` and `chillOther` extrinsics, and how these affect your staking status and nominations."} +{"page_id": "node-infrastructure-run-a-validator-operational-tasks-pause-validating", "page_title": "Pause Validating", "index": 1, "depth": 2, "title": "Chilling Your Node", "anchor": "chilling-your-node", "start_char": 554, "end_char": 1176, "estimated_token_count": 155, "token_estimator": "heuristic-v1", "text": "## Chilling Your Node\n\nIf you need to temporarily step back from staking without unbonding your funds, you can \"chill\" your account. Chilling pauses your active staking participation, setting your account to inactive in the next era while keeping your funds bonded.\n\nTo chill your account, go to the **Network > Staking > Account Actions** page on [Polkadot.js Apps](https://polkadot.js.org/apps){target=\\_blank}, and select **Stop**. Alternatively, you can call the [`chill`](https://paritytech.github.io/polkadot-sdk/master/pallet_staking/enum.Call.html#variant.chill){target=\\_blank} extrinsic in the Staking pallet."} +{"page_id": "node-infrastructure-run-a-validator-operational-tasks-pause-validating", "page_title": "Pause Validating", "index": 2, "depth": 2, "title": "Staking Election Timing Considerations", "anchor": "staking-election-timing-considerations", "start_char": 1176, "end_char": 1777, "estimated_token_count": 123, "token_estimator": "heuristic-v1", "text": "## Staking Election Timing Considerations\n\nWhen a node actively participates in staking but then chills, it will continue contributing for the remainder of the current era. However, its eligibility for the next election depends on the chill status at the start of the new era:\n\n- **Chilled during previous era**: Will not participate in the current era election and will remain inactive until reactivated.\n- **Chilled during current era**: Will not be selected for the next era's election.\n- **Chilled after current era**: May be selected if it was active during the previous era and is now chilled."} +{"page_id": "node-infrastructure-run-a-validator-operational-tasks-pause-validating", "page_title": "Pause Validating", "index": 3, "depth": 2, "title": "Chilling as a Nominator", "anchor": "chilling-as-a-nominator", "start_char": 1777, "end_char": 2554, "estimated_token_count": 142, "token_estimator": "heuristic-v1", "text": "## Chilling as a Nominator\n\nWhen you choose to chill as a nominator, your active nominations are reset. Upon re-entering the nominating process, you must reselect validators to support manually. Depending on preferences, these can be the same validators as before or a new set. Remember that your previous nominations won’t be saved or automatically reactivated after chilling.\n\nWhile chilled, your nominator account remains bonded, preserving your staked funds without requiring a full unbonding process. When you’re ready to start nominating again, you can issue a new nomination call to activate your bond with a fresh set of validators. This process bypasses the need for re-bonding, allowing you to maintain your stake while adjusting your involvement in active staking."} +{"page_id": "node-infrastructure-run-a-validator-operational-tasks-pause-validating", "page_title": "Pause Validating", "index": 4, "depth": 2, "title": "Chilling as a Validator", "anchor": "chilling-as-a-validator", "start_char": 2554, "end_char": 3452, "estimated_token_count": 157, "token_estimator": "heuristic-v1", "text": "## Chilling as a Validator\n\nWhen you chill as a validator, your active validator status is paused. Although your nominators remain bonded to you, the validator bond will no longer appear as an active choice for new or revised nominations until reactivated. Any existing nominators who take no action will still have their stake linked to the validator, meaning they don’t need to reselect the validator upon reactivation. However, if nominators adjust their stakes while the validator is chilled, they will not be able to nominate the chilled validator until it resumes activity.\n\nUpon reactivating as a validator, you must also reconfigure your validator preferences, such as commission rate and other parameters. These can be set to match your previous configuration or updated as desired. This step is essential for rejoining the active validator set and regaining eligibility for nominations."} +{"page_id": "node-infrastructure-run-a-validator-operational-tasks-pause-validating", "page_title": "Pause Validating", "index": 5, "depth": 2, "title": "Chill Other", "anchor": "chill-other", "start_char": 3452, "end_char": 4439, "estimated_token_count": 191, "token_estimator": "heuristic-v1", "text": "## Chill Other\n\nHistorical constraints in the runtime prevented unlimited nominators and validators from being supported. These constraints created a need for checks to keep the size of the staking system manageable. One of these checks is the `chillOther` extrinsic, allowing users to chill accounts that no longer met standards such as minimum staking requirements set through on-chain governance.\n\nThis control mechanism included a `ChillThreshold`, which was structured to define how close to the maximum number of nominators or validators the staking system would be allowed to get before users could start chilling one another. With the passage of [Referendum #90](https://polkadot-old.polkassembly.io/referendum/90){target=\\_blank}, the value for `maxNominatorCount` on Polkadot was set to `None`, effectively removing the limit on how many nominators and validators can participate. This means the `ChillThreshold` will never be met; thus, `chillOther` no longer has any effect."} +{"page_id": "node-infrastructure-run-a-validator-operational-tasks-upgrade-your-node", "page_title": "Upgrade a Validator Node", "index": 0, "depth": 2, "title": "Introduction", "anchor": "introduction", "start_char": 28, "end_char": 821, "estimated_token_count": 123, "token_estimator": "heuristic-v1", "text": "## Introduction\n\nUpgrading a Polkadot validator node is essential for staying current with network updates and maintaining optimal performance. This guide covers routine and extended maintenance scenarios, including software upgrades and major server changes. Following these steps, you can manage session keys and transition smoothly between servers without risking downtime, slashing, or network disruptions. The process requires strategic planning, especially if you need to perform long-lead maintenance, ensuring your validator remains active and compliant.\n\nThis guide will allow validators to seamlessly substitute an active validator server to allow for maintenance operations. The process can take several hours, so ensure you understand the instructions first and plan accordingly."} +{"page_id": "node-infrastructure-run-a-validator-operational-tasks-upgrade-your-node", "page_title": "Upgrade a Validator Node", "index": 1, "depth": 2, "title": "Prerequisites", "anchor": "prerequisites", "start_char": 821, "end_char": 1378, "estimated_token_count": 122, "token_estimator": "heuristic-v1", "text": "## Prerequisites\n\nBefore beginning the upgrade process for your validator node, ensure the following:\n\n- You have a fully functional validator setup with all required binaries installed. See [Set Up a Validator](/node-infrastructure/run-a-validator/onboarding-and-offboarding/set-up-validator/){target=\\_blank} and [Validator Requirements](/node-infrastructure/run-a-validator/requirements/){target=\\_blank} for additional guidance.\n- Your VPS infrastructure has enough capacity to run a secondary validator instance temporarily for the upgrade process."} +{"page_id": "node-infrastructure-run-a-validator-operational-tasks-upgrade-your-node", "page_title": "Upgrade a Validator Node", "index": 2, "depth": 2, "title": "Session Keys", "anchor": "session-keys", "start_char": 1378, "end_char": 2091, "estimated_token_count": 137, "token_estimator": "heuristic-v1", "text": "## Session Keys\n\nSession keys are used to sign validator operations and establish a connection between your validator node and your staking proxy account. These keys are stored in the client, and any change to them requires a waiting period. Specifically, if you modify your session keys, the change will take effect only after the current session is completed and two additional sessions have passed.\n\nRemembering this delayed effect when planning upgrades is crucial to ensure that your validator continues to function correctly and avoids interruptions. To learn more about session keys and their importance, visit the [Keys section](https://wiki.polkadot.com/learn/learn-cryptography/#keys){target=\\_blank}."} +{"page_id": "node-infrastructure-run-a-validator-operational-tasks-upgrade-your-node", "page_title": "Upgrade a Validator Node", "index": 3, "depth": 2, "title": "Keystore", "anchor": "keystore", "start_char": 2091, "end_char": 2885, "estimated_token_count": 168, "token_estimator": "heuristic-v1", "text": "## Keystore\n\nYour validator server's `keystore` folder holds the private keys needed for signing network-level transactions. It is important not to duplicate or transfer this folder between validator instances. Doing so could result in multiple validators signing with the duplicate keys, leading to severe consequences such as [equivocation slashing](/node-infrastructure/run-a-validator/staking-mechanics/offenses-and-slashes/#equivocation-slash){target=\\_blank}. Instead, always generate new session keys for each validator instance.\n\nThe default path to the `keystore` is as follows:\n\n```bash\n/home/polkadot/.local/share/polkadot/chains//keystore\n```\n\nTaking care to manage your keys securely ensures that your validator operates safely and without the risk of slashing penalties."} +{"page_id": "node-infrastructure-run-a-validator-operational-tasks-upgrade-your-node", "page_title": "Upgrade a Validator Node", "index": 4, "depth": 2, "title": "Upgrade Using Backup Validator", "anchor": "upgrade-using-backup-validator", "start_char": 2885, "end_char": 3137, "estimated_token_count": 41, "token_estimator": "heuristic-v1", "text": "## Upgrade Using Backup Validator\n\nThe following instructions outline how to temporarily switch between two validator nodes. The original active validator is referred to as Validator A and the backup node used for maintenance purposes as Validator B."} +{"page_id": "node-infrastructure-run-a-validator-operational-tasks-upgrade-your-node", "page_title": "Upgrade a Validator Node", "index": 5, "depth": 3, "title": "Session `N`", "anchor": "session-n", "start_char": 3137, "end_char": 4089, "estimated_token_count": 216, "token_estimator": "heuristic-v1", "text": "### Session `N`\n\n1. **Start Validator B**: Launch a secondary node and wait until it is fully synced with the network. Once synced, start it with the `--validator` flag. This node will now act as Validator B.\n2. **Generate session keys**: Create new session keys specifically for Validator B.\n3. **Submit the `set_key` extrinsic**: Use your staking proxy account to submit a `set_key` extrinsic, linking the session keys for Validator B to your staking setup.\n4. **Record the session**: Make a note of the session in which you executed this extrinsic.\n5. **Wait for session changes**: Allow the current session to end and then wait for two additional full sessions for the new keys to take effect.\n\n!!! warning \"Keep Validator A running\"\n\n It is crucial to keep Validator A operational during this entire waiting period. Since `set_key` does not take effect immediately, turning off Validator A too early may result in chilling or even slashing."} +{"page_id": "node-infrastructure-run-a-validator-operational-tasks-upgrade-your-node", "page_title": "Upgrade a Validator Node", "index": 6, "depth": 3, "title": "Session `N+3`", "anchor": "session-n3", "start_char": 4089, "end_char": 5650, "estimated_token_count": 378, "token_estimator": "heuristic-v1", "text": "### Session `N+3`\n\nAt this stage, Validator B becomes your active validator. You can now safely perform any maintenance tasks on Validator A.\n\nComplete the following steps when you are ready to bring Validator A back online:\n\n1. **Start Validator A**: Launch Validator A, sync the blockchain database, and ensure it is running with the `--validator` flag.\n2. **Generate new session keys for Validator A**: Create fresh session keys for Validator A.\n3. **Submit the `set_key` extrinsic**: Using your staking proxy account, submit a `set_key` extrinsic with the new Validator A session keys.\n4. **Record the session**: Again, make a note of the session in which you executed this extrinsic.\n\nKeep Validator B active until the session during which you executed the `set-key` extrinsic completes plus two additional full sessions have passed. Once Validator A has successfully taken over, you can safely stop Validator B. This process helps ensure a smooth handoff between nodes and minimizes the risk of downtime or penalties. Verify the transition by checking for finalized blocks in the new session. The logs should indicate the successful change, similar to the example below:\n\n
\n INSERT_COMMAND\n 2019-10-28 21:44:13 Applying authority set change scheduled at block #450092\n 2019-10-28 21:44:13 Applying GRANDPA set change to new set with 20 authorities\n \n
"} +{"page_id": "node-infrastructure-run-a-validator-requirements", "page_title": "Validator Requirements", "index": 0, "depth": 2, "title": "Introduction", "anchor": "introduction", "start_char": 26, "end_char": 981, "estimated_token_count": 159, "token_estimator": "heuristic-v1", "text": "## Introduction\n\nRunning a validator in the Polkadot ecosystem is essential for maintaining network security and decentralization. Validators are responsible for validating transactions and adding new blocks to the chain, ensuring the system operates smoothly. In return for their services, validators earn rewards. However, the role comes with inherent risks, such as slashing penalties for misbehavior or technical failures. If you’re new to validation, starting on Kusama provides a lower-stakes environment to gain valuable experience before progressing to the Polkadot network.\n\nThis guide covers everything you need to know about becoming a validator, including system requirements, staking prerequisites, and infrastructure setup. Whether you’re deploying on a VPS or running your node on custom hardware, you’ll learn how to optimize your validator for performance and security, ensuring compliance with network standards while minimizing risks."} +{"page_id": "node-infrastructure-run-a-validator-requirements", "page_title": "Validator Requirements", "index": 1, "depth": 2, "title": "Prerequisites", "anchor": "prerequisites", "start_char": 981, "end_char": 2394, "estimated_token_count": 304, "token_estimator": "heuristic-v1", "text": "## Prerequisites\n\nRunning a validator requires solid system administration skills and a secure, well-maintained infrastructure. Below are the primary requirements you need to be aware of before getting started:\n\n- **System administration expertise**: Handling technical anomalies and maintaining node infrastructure is critical. Validators must be able to troubleshoot and optimize their setup.\n- **Security**: Ensure your setup follows best practices for securing your node. Refer to the [Secure Your Validator](/node-infrastructure/run-a-validator/operational-tasks/general-management/#secure-your-validator){target=\\_blank} section to learn about important security measures.\n- **Network choice**: Start with [Kusama](/node-infrastructure/run-a-validator/onboarding-and-offboarding/set-up-validator/#run-a-kusama-validator){target=\\_blank} to gain experience. Look for \"Adjustments for Kusama\" throughout these guides for tips on adapting the provided instructions for the Kusama network.\n- **Staking requirements**: A minimum amount of native token (KSM or DOT) is required to be elected into the validator set. The required stake can come from your own holdings or from nominators.\n- **Risk of slashing**: Any DOT you stake is at risk if your setup fails or your validator misbehaves. If you’re unsure of your ability to maintain a reliable validator, consider nominating your DOT to a trusted validator."} +{"page_id": "node-infrastructure-run-a-validator-requirements", "page_title": "Validator Requirements", "index": 2, "depth": 2, "title": "Minimum Hardware Requirements", "anchor": "minimum-hardware-requirements", "start_char": 2394, "end_char": 3558, "estimated_token_count": 251, "token_estimator": "heuristic-v1", "text": "## Minimum Hardware Requirements\n\nPolkadot validators rely on high-performance hardware to process blocks efficiently. The recommended minimum hardware requirements to ensure a fully functional and performant validator are as follows:\n\n- CPU:\n\n - x86-64 compatible.\n - Eight physical cores @ 3.4 GHz.\n - Processor:\n - **Intel**: Ice Lake or newer (Xeon or Core series)\n - **AMD**: Zen3 or newer (EPYC or Ryzen)\n - Simultaneous multithreading disabled:\n - **Intel**: Hyper-Threading\n - **AMD**: SMT\n - [Single-threaded performance](https://www.cpubenchmark.net/singleThread.html){target=\\_blank} is prioritized over higher cores count.\n\n- Storage:\n\n - **NVMe SSD**: At least 2 TB for blockchain data recommended (prioritize latency rather than throughput).\n - Storage requirements will increase as the chain grows. For current estimates, see the [current chain snapshot](https://stakeworld.io/docs/dbsize){target=\\_blank}.\n\n- Memory:\n\n - 32 GB DDR4 ECC\n\n- Network:\n\n - Symmetric networking speed of 500 Mbit/s is required to handle large numbers of parachains and ensure congestion control during peak times."} +{"page_id": "node-infrastructure-run-a-validator-requirements", "page_title": "Validator Requirements", "index": 3, "depth": 2, "title": "VPS Provider List", "anchor": "vps-provider-list", "start_char": 3558, "end_char": 6077, "estimated_token_count": 575, "token_estimator": "heuristic-v1", "text": "## VPS Provider List\n\nWhen selecting a VPS provider for your validator node, prioritize reliability, consistent performance, and adherence to the specific hardware requirements set for Polkadot validators. The following server types have been tested and showed acceptable performance in benchmark tests. However, this is not an endorsement and actual performance may vary depending on your workload and VPS provider.\n\nBe aware that some providers may overprovision the underlying host and use shared storage such as NVMe over TCP, which appears as local storage. These setups might result in poor or inconsistent performance. Benchmark your infrastructure before deploying.\n\n- **[Google Cloud Platform (GCP)](https://cloud.google.com/){target=\\_blank}**: `c2` and `c2d` machine families offer high-performance configurations suitable for validators.\n- **[Amazon Web Services (AWS)](https://aws.amazon.com/){target=\\_blank}**: `c6id` machine family provides strong performance, particularly for I/O-intensive workloads.\n- **[OVH](https://www.ovhcloud.com/en-au/){target=\\_blank}**: Can be a budget-friendly solution if it meets your minimum hardware specifications.\n- **[Digital Ocean](https://www.digitalocean.com/){target=\\_blank}**: Popular among developers, Digital Ocean's premium droplets offer configurations suitable for medium to high-intensity workloads.\n- **[Vultr](https://www.vultr.com/){target=\\_blank}**: Offers flexibility with plans that may meet validator requirements, especially for high-bandwidth needs.\n- **[Linode](https://www.linode.com/){target=\\_blank}**: Provides detailed documentation, which can be helpful for setup.\n- **[Scaleway](https://www.scaleway.com/en/){target=\\_blank}**: Offers high-performance cloud instances that can be suitable for validator nodes.\n- **[OnFinality](https://onfinality.io/en){target=\\_blank}**: Specialized in blockchain infrastructure, OnFinality provides validator-specific support and configurations.\n\n!!! warning \"Acceptable use policies\"\n Different VPS providers have varying acceptable use policies, and not all allow cryptocurrency-related activities. \n\n For example, Digital Ocean, requires explicit permission to use servers for cryptocurrency mining and defines unauthorized mining as [network abuse](https://www.digitalocean.com/legal/acceptable-use-policy#network-abuse){target=\\_blank} in their acceptable use policy. \n \n Review the terms for your VPS provider to avoid account suspension or server shutdown due to policy violations."} +{"page_id": "node-infrastructure-run-a-validator-requirements", "page_title": "Validator Requirements", "index": 4, "depth": 2, "title": "Minimum Bond Requirement", "anchor": "minimum-bond-requirement", "start_char": 6077, "end_char": 6842, "estimated_token_count": 196, "token_estimator": "heuristic-v1", "text": "## Minimum Bond Requirement\n\nBefore bonding DOT, ensure you meet the minimum bond requirement to start a validator instance. The minimum bond is the least DOT you need to stake to enter the validator set. To become eligible for rewards, your validator node must be nominated by enough staked tokens.\n\nFor example, on November 19, 2024, the minimum stake backing a validator in Polkadot's era 1632 was 1,159,434.248 DOT. You can check the current minimum stake required using these tools:\n\n- [**Chain State Values**](https://wiki.polkadot.com/general/chain-state-values/){target=\\_blank}\n- [**Subscan**](https://polkadot.subscan.io/validator_list?status=validator){target=\\_blank}\n- [**Staking Dashboard**](https://staking.polkadot.cloud/#/overview){target=\\_blank}"} +{"page_id": "node-infrastructure-run-a-validator-staking-mechanics-offenses-and-slashes", "page_title": "Offenses and Slashes", "index": 0, "depth": 2, "title": "Introduction", "anchor": "introduction", "start_char": 24, "end_char": 674, "estimated_token_count": 104, "token_estimator": "heuristic-v1", "text": "## Introduction\n\nIn Polkadot's Nominated Proof of Stake (NPoS) system, validator misconduct is deterred through a combination of slashing, disabling, and reputation penalties. Validators and nominators who stake tokens face consequences for validator misbehavior, which range from token slashes to restrictions on network participation.\n\nThis page outlines the types of offenses recognized by Polkadot, including block equivocations and invalid votes, as well as the corresponding penalties. While some parachains may implement additional custom slashing mechanisms, this guide focuses on the offenses tied to staking within the Polkadot ecosystem."} +{"page_id": "node-infrastructure-run-a-validator-staking-mechanics-offenses-and-slashes", "page_title": "Offenses and Slashes", "index": 1, "depth": 2, "title": "Offenses", "anchor": "offenses", "start_char": 674, "end_char": 1106, "estimated_token_count": 86, "token_estimator": "heuristic-v1", "text": "## Offenses\n\nPolkadot is a public permissionless network. As such, it has a mechanism to disincentivize offenses and incentivize good behavior. You can review the [parachain protocol](https://wiki.polkadot.com/learn/learn-parachains-protocol/#parachain-protocol){target=\\_blank} to understand better the terminology used to describe offenses. Polkadot validator offenses fall into two categories: invalid votes and equivocations."} +{"page_id": "node-infrastructure-run-a-validator-staking-mechanics-offenses-and-slashes", "page_title": "Offenses and Slashes", "index": 2, "depth": 3, "title": "Invalid Votes", "anchor": "invalid-votes", "start_char": 1106, "end_char": 1733, "estimated_token_count": 128, "token_estimator": "heuristic-v1", "text": "### Invalid Votes\n\nA validator will be penalized for inappropriate voting activity during the block inclusion and approval processes. The invalid voting related offenses are as follows:\n\n- **Backing an invalid block**: A para-validator backs an invalid block for inclusion in a fork of the relay chain.\n- **`ForInvalid` vote**: When acting as a secondary checker, the validator votes in favor of an invalid block.\n- **`AgainstValid` vote**: When acting as a secondary checker, the validator votes against a valid block. This type of vote wastes network resources required to resolve the disparate votes and resulting dispute."} +{"page_id": "node-infrastructure-run-a-validator-staking-mechanics-offenses-and-slashes", "page_title": "Offenses and Slashes", "index": 3, "depth": 3, "title": "Equivocations", "anchor": "equivocations", "start_char": 1733, "end_char": 2746, "estimated_token_count": 197, "token_estimator": "heuristic-v1", "text": "### Equivocations\n\nEquivocation occurs when a validator produces statements that conflict with each other when producing blocks or voting. Unintentional equivocations usually occur when duplicate signing keys reside on the validator host. If keys are never duplicated, the probability of an honest equivocation slash decreases to near zero. The equivocation related offenses are as follows:\n\n- **Equivocation**: The validator produces two or more of the same block or vote.\n - **GRANDPA and BEEFY equivocation**: The validator signs two or more votes in the same round on different chains.\n - **BABE equivocation**: The validator produces two or more blocks on the relay chain in the same time slot.\n- **Double seconded equivocation**: The validator attempts to second, or back, more than one block in the same round.\n- **Seconded and valid equivocation**: The validator seconds, or backs, a block and then attempts to hide their role as the responsible backer by later placing a standard validation vote."} +{"page_id": "node-infrastructure-run-a-validator-staking-mechanics-offenses-and-slashes", "page_title": "Offenses and Slashes", "index": 4, "depth": 2, "title": "Penalties", "anchor": "penalties", "start_char": 2746, "end_char": 2924, "estimated_token_count": 31, "token_estimator": "heuristic-v1", "text": "## Penalties\n\nOn Polkadot, offenses to the network incur different penalties depending on severity. There are three main penalties: slashing, disabling, and reputation changes."} +{"page_id": "node-infrastructure-run-a-validator-staking-mechanics-offenses-and-slashes", "page_title": "Offenses and Slashes", "index": 5, "depth": 3, "title": "Slashing", "anchor": "slashing", "start_char": 2924, "end_char": 13705, "estimated_token_count": 2520, "token_estimator": "heuristic-v1", "text": "### Slashing\n\nValidators engaging in bad actor behavior in the network may be subject to slashing if they commit a qualifying offense. When a validator is slashed, they and their nominators lose a percentage of their staked DOT or KSM, from as little as 0.01% up to 100% based on the severity of the offense. Nominators are evaluated for slashing against their active validations at any given time. Validator nodes are evaluated as discrete entities, meaning an operator can't attempt to mitigate the offense on another node they operate in order to avoid a slash. \n\nAny slashed DOT or KSM will be added to the [Treasury](https://wiki.polkadot.com/learn/learn-polkadot-opengov-treasury/){target=\\_blank} rather than burned or distributed as rewards. Moving slashed funds to the Treasury allows tokens to be quickly moved away from malicious validators while maintaining the ability to revert faulty slashes when needed.\n\nA nominator with a very large bond may nominate several validators in a single era. In this case, a slash is proportionate to the amount staked to the offending validator. Stake allocation and validator activation is controlled by the [Phragmén algorithm](https://wiki.polkadot.com/learn/learn-phragmen/#algorithm){target=\\_blank}.\n\nA validator slash creates an `unapplied` state transition. You can view pending slashes on [Polkadot.js Apps](https://polkadot.js.org/apps/?rpc=wss%3A%2F%2Frpc.polkadot.io#/staking/slashes){target=\\_blank}. The UI will display the slash per validator, the affected nominators, and the slash amounts. The unapplied state includes a 27-day grace period during which a governance proposal can be made to reverse the slash. Once this grace period expires, the slash is applied.\n\n#### Equivocation Slash\n\nThe Web3 Foundation's [Slashing mechanisms](https://research.web3.foundation/Polkadot/security/slashing/amounts){target=\\_blank} page provides guidelines for evaluating the security threat level of different offenses and determining penalties proportionate to the threat level of the offense. Offenses requiring coordination between validators or extensive computational costs to the system will typically call for harsher penalties than those more likely to be unintentional than malicious. A description of potential offenses for each threat level and the corresponding penalties is as follows:\n\n- **Level 1**: Honest misconduct such as isolated cases of unresponsiveness.\n - **Penalty**: Validator can be kicked out or slashed up to 0.1% of stake in the validator slot.\n- **Level 2**: Misconduct that can occur honestly but is a sign of bad practices. Examples include repeated cases of unresponsiveness and isolated cases of equivocation.\n - **Penalty**: Slash of up to 1% of stake in the validator slot.\n- **Level 3**: Misconduct that is likely intentional but of limited effect on the performance or security of the network. This level will typically include signs of coordination between validators. Examples include repeated cases of equivocation or isolated cases of unjustified voting on GRANDPA.\n - **Penalty**: Reduction in networking reputation metrics, slash of up to 10% of stake in the validator slot.\n- **Level 4**: Misconduct that poses severe security or monetary risk to the system or mass collusion. Examples include signs of extensive coordination, creating a serious security risk to the system, or forcing the system to use extensive resources to counter the misconduct.\n - **Penalty**: Slash of up to 100% of stake in the validator slot.\n\nSee the next section to understand how slash amounts for equivocations are calculated. If you want to know more details about slashing, please look at the research page on [Slashing mechanisms](https://research.web3.foundation/Polkadot/security/slashing/amounts){target=\\_blank}.\n\n#### Slash Calculation for Equivocation\n\nThe slashing penalty for GRANDPA, BABE, and BEEFY equivocations is calculated using the formula below, where `x` represents the number of offenders and `n` is the total number of validators in the active set:\n\n```text\nmin((3 * x / n )^2, 1)\n```\n\nThe following scenarios demonstrate how this formula means slash percentages can increase exponentially based on the number of offenders involved compared to the size of the validator pool:\n\n- **Minor offense**: Assume 1 validator out of a 100 validator active set equivocates in a slot. A single validator committing an isolated offense is most likely a mistake rather than malicious attack on the network. This offense results in a 0.09% slash to the stake in the validator slot.\n\n ``` mermaid\n flowchart LR\n N[\"Total Validators = 100\"]\n X[\"Offenders = 1\"]\n F[\"min((3 * 1 / 100)^2, 1) = 0.0009\"]\n G[\"0.09% slash of stake\"]\n\n N --> F\n X --> F\n F --> G\n ```\n\n- **Moderate offense**: Assume 5 validators out a 100 validator active set equivocate in a slot. This is a slightly more serious event as there may be some element of coordination involved. This offense results in a 2.25% slash to the stake in the validator slot.\n\n ``` mermaid\n flowchart LR\n N[\"Total Validators = 100\"]\n X[\"Offenders = 5\"]\n F[\"min((3 * 5 / 100)^2, 1) = 0.0225\"]\n G[\"2.25% slash of stake\"]\n\n N --> F\n X --> F\n F --> G\n ```\n\n- **Major offense**: Assume 20 validators out a 100 validator active set equivocate in a slot. This is a major security threat as it possible represents a coordinated attack on the network. This offense results in a 36% slash and all slashed validators will also be chilled.\n ``` mermaid\n flowchart LR\n N[\"Total Validators = 100\"]\n X[\"Offenders = 20\"]\n F[\"min((3 * 20 / 100)^2, 1) = 0.36\"]\n G[\"36% slash of stake\"]\n\n N --> F\n X --> F\n F --> G\n ```\n\nThe examples above show the risk of nominating or running many validators in the active set. While rewards grow linearly (two validators will get you approximately twice as many staking rewards as one), slashing grows exponentially. Going from a single validator equivocating to two validators equivocating causes a slash four time as much as the single validator.\n\nValidators may run their nodes on multiple machines to ensure they can still perform validation work if one of their nodes goes down. Still, validator operators should be cautious when setting these up. Equivocation is possible if they don't coordinate well in managing signing machines.\n\n#### Best Practices to Avoid Slashing\n\nThe following are advised to node operators to ensure that they obtain pristine binaries or source code and to ensure the security of their node:\n\n- Always download either source files or binaries from the official Parity repository.\n- Verify the hash of downloaded files.\n- Use the W3F secure validator setup or adhere to its principles.\n- Ensure essential security items are checked, use a firewall, manage user access, use SSH certificates.\n- Avoid using your server as a general-purpose system. Hosting a validator on your workstation or one that hosts other services increases the risk of maleficence.\n- Avoid cloning servers (copying all contents) when migrating to new hardware. If an image is needed, create it before generating keys.\n- High Availability (HA) systems are generally not recommended as equivocation may occur if concurrent operations happen—such as when a failed server restarts or two servers are falsely online simultaneously.\n- Copying the keystore folder when moving a database between instances can cause equivocation. Even brief use of duplicated keystores can result in slashing.\n\nBelow are some examples of small equivocations that happened in the past:\n\n| Network | Era | Event Type | Details | Action Taken |\n|----------|------|--------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------|\n| Polkadot | 774 | Small Equivocation | [The validator](https://matrix.to/#/!NZrbtteFeqYKCUGQtr:matrix.parity.io/$165562246360408hKCfC:matrix.org?via=matrix.parity.io&via=corepaper.org&via=matrix.org){target=\\_blank} migrated servers and cloned the keystore folder. The on-chain event can be viewed on [Subscan](https://polkadot.subscan.io/extrinsic/11190109-0?event=11190109-5){target=\\_blank}. | The validator didn't submit a request for the slash to be canceled. |\n| Kusama | 3329 | Small Equivocation | The validator operated a test machine with cloned keys. The test machine was online simultaneously as the primary, which resulted in a slash. | The validator requested a slash cancellation, but the council declined. |\n| Kusama | 3995 | Small Equivocation | The validator noticed several errors, after which the client crashed, and a slash was applied. The validator recorded all events and opened GitHub issues to allow for technical opinions to be shared. | The validator requested to cancel the slash. The council approved the request as they believed the error wasn't operator-related. |\n\n#### Slashing Across Eras\n\nThere are three main difficulties to account for with slashing in NPoS:\n\n- A nominator can nominate multiple validators and be slashed as a result of actions taken by any of them.\n- Until slashed, the stake is reused from era to era.\n- Slashable offenses can be found after the fact and out of order.\n\nTo balance this, the system applies only the maximum slash a participant can receive in a given time period rather than the sum. This ensures protection from excessive slashing."} +{"page_id": "node-infrastructure-run-a-validator-staking-mechanics-offenses-and-slashes", "page_title": "Offenses and Slashes", "index": 6, "depth": 3, "title": "Disabling", "anchor": "disabling", "start_char": 13705, "end_char": 14617, "estimated_token_count": 185, "token_estimator": "heuristic-v1", "text": "### Disabling\n\nThe disabling mechanism is triggered when validators commit serious infractions, such as backing invalid blocks or engaging in equivocations. Disabling stops validators from performing specific actions after they have committed an offense. Disabling is further divided into:\n\n- **On-chain disabling**: Lasts for a whole era and stops validators from authoring blocks, backing, and initiating a dispute.\n- **Off-chain disabling**: Lasts for a session, is caused by losing a dispute, and stops validators from initiating a dispute.\n\nOff-chain disabling is always a lower priority than on-chain disabling. Off-chain disabling prioritizes disabling first backers and then approval checkers.\n\nThe material in this guide reflects the changes introduced in Stage 4. For more details, see the [State of Disabling issue](https://github.com/paritytech/polkadot-sdk/issues/4359){target=\\_blank} on GitHub."} +{"page_id": "node-infrastructure-run-a-validator-staking-mechanics-offenses-and-slashes", "page_title": "Offenses and Slashes", "index": 7, "depth": 3, "title": "Reputation Changes", "anchor": "reputation-changes", "start_char": 14617, "end_char": 15241, "estimated_token_count": 108, "token_estimator": "heuristic-v1", "text": "### Reputation Changes\n\nSome minor offenses, such as spamming, are only punished by networking reputation changes. Validators use a reputation metric when choosing which peers to connect with. The system adds reputation if a peer provides valuable data and behaves appropriately. If they provide faulty or spam data, the system reduces their reputation. If a validator loses enough reputation, their peers will temporarily close their channels to them. This helps in fighting against Denial of Service (DoS) attacks. Performing validator tasks under reduced reputation will be harder, resulting in lower validator rewards."} +{"page_id": "node-infrastructure-run-a-validator-staking-mechanics-offenses-and-slashes", "page_title": "Offenses and Slashes", "index": 8, "depth": 3, "title": "Penalties by Offense", "anchor": "penalties-by-offense", "start_char": 15241, "end_char": 15427, "estimated_token_count": 50, "token_estimator": "heuristic-v1", "text": "### Penalties by Offense\n\nRefer to the Polkadot Wiki's [offenses page](https://wiki.polkadot.com/learn/learn-offenses/){target=\\_blank} for a summary of penalties for specific offenses."} +{"page_id": "node-infrastructure-run-a-validator-staking-mechanics-rewards", "page_title": "Rewards Payout", "index": 0, "depth": 2, "title": "Introduction", "anchor": "introduction", "start_char": 18, "end_char": 621, "estimated_token_count": 95, "token_estimator": "heuristic-v1", "text": "## Introduction\n\nUnderstanding how rewards are distributed to validators and nominators is essential for network participants. In Polkadot and Kusama, validators earn rewards based on their era points, which are accrued through actions like block production and parachain validation.\n\nThis guide explains the payout scheme, factors influencing rewards, and how multiple validators affect returns. Validators can also share rewards with nominators, who contribute by staking behind them. By following the payout mechanics, validators can optimize their earnings and better engage with their nominators."} +{"page_id": "node-infrastructure-run-a-validator-staking-mechanics-rewards", "page_title": "Rewards Payout", "index": 1, "depth": 2, "title": "Era Points", "anchor": "era-points", "start_char": 621, "end_char": 1497, "estimated_token_count": 165, "token_estimator": "heuristic-v1", "text": "## Era Points\n\nThe Polkadot ecosystem measures its reward cycles in a unit called an era. Kusama eras are approximately 6 hours long, and Polkadot eras are 24 hours long. At the end of each era, validators are paid proportionally to the amount of era points they have collected. Era points are reward points earned for payable actions like:\n\n- Issuing validity statements for parachain blocks.\n \n- Producing a non-uncle block in the relay chain.\n- Producing a reference to a previously unreferenced uncle block.\n- Producing a referenced uncle block.\n\nAn uncle block is a relay chain block that is valid in every regard but has failed to become canonical. This can happen when two or more validators are block producers in a single slot, and the block produced by one validator reaches the next block producer before the others. The lagging blocks are called uncle blocks."} +{"page_id": "node-infrastructure-run-a-validator-staking-mechanics-rewards", "page_title": "Rewards Payout", "index": 2, "depth": 2, "title": "Reward Variance", "anchor": "reward-variance", "start_char": 1497, "end_char": 4038, "estimated_token_count": 564, "token_estimator": "heuristic-v1", "text": "## Reward Variance\n\nRewards in Polkadot and Kusama staking systems can fluctuate due to differences in era points earned by para-validators and non-para-validators. Para-validators generally contribute more to the overall reward distribution due to their role in validating parachain blocks, thus influencing the variance in staking rewards.\n\nTo illustrate this relationship:\n\n- Para-validator era points tend to have a higher impact on the expected value of staking rewards compared to non-para-validator points.\n- The variance in staking rewards increases as the total number of validators grows relative to the number of para-validators.\n- In simpler terms, when more validators are added to the active set without increasing the para-validator pool, the disparity in rewards between validators becomes more pronounced.\n\nHowever, despite this increased variance, rewards tend to even out over time due to the continuous rotation of para-validators across eras. The network's design ensures that over multiple eras, each validator has an equal opportunity to participate in para-validation, eventually leading to a balanced distribution of rewards.\n\n??? interface \"Probability in Staking Rewards\"\n\n This should only serve as a high-level overview of the probabilistic nature for staking rewards.\n\n Let:\n\n - `pe` = para-validator era points\n - `ne` = non-para-validator era points\n - `EV` = expected value of staking rewards\n\n Then, `EV(pe)` has more influence on the `EV` than `EV(ne)`.\n\n Since `EV(pe)` has a more weighted probability on the `EV`, the increase in variance against the `EV` becomes apparent between the different validator pools (aka. validators in the active set and the ones chosen to para-validate).\n\n Also, let:\n\n - `v` = the variance of staking rewards\n - `p` = number of para-validators\n - `w` = number validators in the active set\n - `e` = era\n\n Then, `v` ↑ if `w` ↑, as this reduces `p` : `w`, with respect to `e`.\n\n Increased `v` is expected, and initially keeping `p` ↓ using the same para-validator set for all parachains ensures [availability](https://spec.polkadot.network/chapter-anv){target=\\_blank} and [voting](https://wiki.polkadot.com/learn/learn-polkadot-opengov/){target=\\_blank}. In addition, despite `v` ↑ on an `e` to `e` basis, over time, the amount of rewards each validator receives will equal out based on the continuous selection of para-validators.\n\n There are plans to scale the active para-validation set in the future."} +{"page_id": "node-infrastructure-run-a-validator-staking-mechanics-rewards", "page_title": "Rewards Payout", "index": 3, "depth": 2, "title": "Payout Scheme", "anchor": "payout-scheme", "start_char": 4038, "end_char": 5459, "estimated_token_count": 328, "token_estimator": "heuristic-v1", "text": "## Payout Scheme\n\nValidator rewards are distributed equally among all validators in the active set, regardless of the total stake behind each validator. However, individual payouts may differ based on the number of era points a validator has earned. Although factors like network connectivity can affect era points, well-performing validators should accumulate similar totals over time.\n\nValidators can also receive tips from users, which incentivize them to include certain transactions in their blocks. Validators retain 100% of these tips.\n\nRewards are paid out in the network's native token (DOT for Polkadot and KSM for Kusama). \n\nThe following example illustrates a four member validator set with their names, amount they have staked, and how payout of rewards is divided. This scenario assumes all validators earned the same amount of era points and no one received tips: \n\n``` mermaid\nflowchart TD\n A[\"Alice (18 DOT)\"]\n B[\"Bob (9 DOT)\"]\n C[\"Carol (8 DOT)\"]\n D[\"Dave (7 DOT)\"]\n E[\"Payout (8 DOT total)\"]\n E --\"2 DOT\"--> A\n E --\"2 DOT\"--> B\n E --\"2 DOT\"--> C\n E --\"2 DOT\"--> D\n```\n\nNote that this is different than most other Proof of Stake (PoS) systems. As long as a validator is in the validator set, it will receive the same block reward as every other validator. Validator Alice, who had 18 DOT staked, received the same 2 DOT reward in this era as Dave, who had only 7 DOT staked."} +{"page_id": "node-infrastructure-run-a-validator-staking-mechanics-rewards", "page_title": "Rewards Payout", "index": 4, "depth": 2, "title": "Running Multiple Validators", "anchor": "running-multiple-validators", "start_char": 5459, "end_char": 7070, "estimated_token_count": 423, "token_estimator": "heuristic-v1", "text": "## Running Multiple Validators\n\nRunning multiple validators can offer a more favorable risk/reward ratio compared to running a single one. If you have sufficient DOT or nominators staking on your validators, maintaining multiple validators within the active set can yield higher rewards.\n\nIn the preceding section, with 18 DOT staked and no nominators, Alice earned 2 DOT in one era. This example uses DOT, but the same principles apply for KSM on the Kusama network. By managing stake across multiple validators, you can potentially increase overall returns. Recall the set of validators from the preceding section:\n\n``` mermaid\nflowchart TD\n A[\"Alice (18 DOT)\"]\n B[\"Bob (9 DOT)\"]\n C[\"Carol (8 DOT)\"]\n D[\"Dave (7 DOT)\"]\n E[\"Payout (8 DOT total)\"]\n E --\"2 DOT\"--> A\n E --\"2 DOT\"--> B\n E --\"2 DOT\"--> C\n E --\"2 DOT\"--> D \n```\n\nNow, assume Alice decides to split their stake and run two validators, each with a nine DOT stake. This validator set only has four spots and priority is given to validators with a larger stake. In this example, Dave has the smallest stake and loses his spot in the validator set. Now, Alice will earn two shares of the total payout each era as illustrated below:\n\n``` mermaid\nflowchart TD\n A[\"Alice (9 DOT)\"]\n F[\"Alice (9 DOT)\"]\n B[\"Bob (9 DOT)\"]\n C[\"Carol (8 DOT)\"]\n E[\"Payout (8 DOT total)\"]\n E --\"2 DOT\"--> A\n E --\"2 DOT\"--> B\n E --\"2 DOT\"--> C\n E --\"2 DOT\"--> F \n```\n\nWith enough stake, you could run more than two validators. However, each validator must have enough stake behind it to maintain a spot in the validator set."} +{"page_id": "node-infrastructure-run-a-validator-staking-mechanics-rewards", "page_title": "Rewards Payout", "index": 5, "depth": 2, "title": "Nominators and Validator Payments", "anchor": "nominators-and-validator-payments", "start_char": 7070, "end_char": 10907, "estimated_token_count": 990, "token_estimator": "heuristic-v1", "text": "## Nominators and Validator Payments\n\nA nominator's stake allows them to vote for validators and earn a share of the rewards without managing a validator node. Although staking rewards depend on validator activity during an era, validators themselves never control or own nominator rewards. To trigger payouts, anyone can call the `staking.payoutStakers` or `staking.payoutStakerByPage` methods, which mint and distribute rewards directly to the recipients. This trustless process ensures nominators receive their earned rewards.\n\nValidators set a commission rate as a percentage of the block reward, affecting how rewards are shared with nominators. A 0% commission means the validator keeps only rewards from their self-stake, while a 100% commission means they retain all rewards, leaving none for nominators.\n\nThe following examples model splitting validator payments between nominator and validator using various commission percentages. For simplicity, these examples assume a Polkadot-SDK based relay chain that uses DOT as a native token and a single nominator per validator. Calculations of KSM reward payouts for Kusama follow the same formula. \n\nStart with the original validator set from the previous section: \n\n``` mermaid\nflowchart TD\n A[\"Alice (18 DOT)\"]\n B[\"Bob (9 DOT)\"]\n C[\"Carol (8 DOT)\"]\n D[\"Dave (7 DOT)\"]\n E[\"Payout (8 DOT total)\"]\n E --\"2 DOT\"--> A\n E --\"2 DOT\"--> B\n E --\"2 DOT\"--> C\n E --\"2 DOT\"--> D \n```\n\nThe preceding diagram shows each validator receiving a 2 DOT payout, but doesn't account for sharing rewards with nominators. The following diagram shows what nominator payout might look like for validator Alice. Alice has a 20% commission rate and holds 50% of the stake for their validator:\n\n``` mermaid\n\nflowchart TD\n A[\"Gross Rewards = 2 DOT\"]\n E[\"Commission = 20%\"]\n F[\"Alice Validator Payment = 0.4 DOT\"]\n G[\"Total Stake Rewards = 1.6 DOT\"]\n B[\"Alice Validator Stake = 18 DOT\"]\n C[\"9 DOT Alice (50%)\"]\n H[\"Alice Stake Reward = 0.8 DOT\"]\n I[\"Total Alice Validator Reward = 1.2 DOT\"]\n D[\"9 DOT Nominator (50%)\"]\n J[\"Total Nominator Reward = 0.8 DOT\"]\n \n A --> E\n E --(2 x 0.20)--> F\n F --(2 - 0.4)--> G\n B --> C\n B --> D\n C --(1.6 x 0.50)--> H\n H --(0.4 + 0.8)--> I\n D --(1.60 x 0.50)--> J\n```\n\nNotice the validator commission rate is applied against the gross amount of rewards for the era. The validator commission is subtracted from the total rewards. After the commission is paid to the validator, the remaining amount is split among stake owners according to their percentage of the total stake. A validator's total rewards for an era include their commission plus their piece of the stake rewards. \n\nNow, consider a different scenario for validator Bob where the commission rate is 40%, and Bob holds 33% of the stake for their validator:\n\n``` mermaid\n\nflowchart TD\n A[\"Gross Rewards = 2 DOT\"]\n E[\"Commission = 40%\"]\n F[\"Bob Validator Payment = 0.8 DOT\"]\n G[\"Total Stake Rewards = 1.2 DOT\"]\n B[\"Bob Validator Stake = 9 DOT\"]\n C[\"3 DOT Bob (33%)\"]\n H[\"Bob Stake Reward = 0.4 DOT\"]\n I[\"Total Bob Validator Reward = 1.2 DOT\"]\n D[\"6 DOT Nominator (67%)\"]\n J[\"Total Nominator Reward = 0.8 DOT\"]\n \n A --> E\n E --(2 x 0.4)--> F\n F --(2 - 0.8)--> G\n B --> C\n B --> D\n C --(1.2 x 0.33)--> H\n H --(0.8 + 0.4)--> I\n D --(1.2 x 0.67)--> J\n```\n\nBob holds a smaller percentage of their node's total stake, making their stake reward smaller than Alice's. In this scenario, Bob makes up the difference by charging a 40% commission rate and ultimately ends up with the same total payment as Alice. Each validator will need to find their ideal balance between the amount of stake and commission rate to attract nominators while still making running a validator worthwhile."} {"page_id": "parachains-customize-runtime-add-existing-pallets", "page_title": "Add an Existing Pallet to the Runtime", "index": 0, "depth": 2, "title": "Introduction", "anchor": "introduction", "start_char": 41, "end_char": 1382, "estimated_token_count": 270, "token_estimator": "heuristic-v1", "text": "## Introduction\n\nThe [Polkadot SDK Parachain Template](https://github.com/paritytech/polkadot-sdk-parachain-template){target=\\_blank} provides a functional runtime that includes default [FRAME](https://paritytech.github.io/polkadot-sdk/master/polkadot_sdk_docs/polkadot_sdk/frame_runtime/index.html){target=\\_blank} development modules ([pallets](https://paritytech.github.io/polkadot-sdk/master/polkadot_sdk_docs/polkadot_sdk/frame_runtime/pallet/index.html){target=\\_blank}) to help you get started building a custom parachain. However, you'll often need to extend your runtime by adding additional pallets to enable new functionality.\n\nEach pallet has specific configuration requirements, including the necessary parameters and types that enable its functionality. This guide walks you through the complete process of adding an existing pallet to your runtime and configuring it properly using `pallet-utility` as a practical example.\n\nThe Utility pallet offers batch transaction capabilities, enabling multiple calls to be dispatched together, as well as origin manipulation functionality for advanced use cases.\n\nIn this guide, you'll learn how to:\n\n- Update runtime dependencies to integrate a new pallet\n- Configure pallet-specific Rust traits to enable the pallet's functionality\n- Run your parachain locally to test the new pallet"} {"page_id": "parachains-customize-runtime-add-existing-pallets", "page_title": "Add an Existing Pallet to the Runtime", "index": 1, "depth": 2, "title": "Check Prerequisites", "anchor": "check-prerequisites", "start_char": 1382, "end_char": 1664, "estimated_token_count": 72, "token_estimator": "heuristic-v1", "text": "## Check Prerequisites\n\nBefore you begin, ensure you have:\n\n- [Polkadot SDK dependencies installed](/parachains/install-polkadot-sdk/){target=\\_blank}\n- A working [Polkadot SDK development environment](/parachains/launch-a-parachain/set-up-the-parachain-template/){target=\\_blank}"} {"page_id": "parachains-customize-runtime-add-existing-pallets", "page_title": "Add an Existing Pallet to the Runtime", "index": 2, "depth": 2, "title": "Add an Existing Polkadot SDK Pallet to Your Runtime", "anchor": "add-an-existing-polkadot-sdk-pallet-to-your-runtime", "start_char": 1664, "end_char": 1898, "estimated_token_count": 39, "token_estimator": "heuristic-v1", "text": "## Add an Existing Polkadot SDK Pallet to Your Runtime\n\nAdding a pallet to your parachain runtime involves configuring dependencies, implementing the pallet's configuration trait, and registering the pallet in the runtime construct."} @@ -675,14 +675,14 @@ {"page_id": "smart-contracts-libraries-viem", "page_title": "viem for Polkadot Hub Smart Contracts", "index": 13, "depth": 2, "title": "Where to Go Next", "anchor": "where-to-go-next", "start_char": 15647, "end_char": 17416, "estimated_token_count": 545, "token_estimator": "heuristic-v1", "text": "## Where to Go Next\n\nNow that you have the foundation for using viem with Polkadot Hub, consider exploring:\n\n
\n\n- External __Advanced viem Features__\n\n ---\n Explore viem's documentation:\n
    \n
  • [:octicons-arrow-right-24: Multi call](https://viem.sh/docs/contract/multicall#multicall){target=\\_blank}
  • \n\n
  • [:octicons-arrow-right-24: Batch transactions](https://viem.sh/docs/clients/transports/http#batch-json-rpc){target=\\_blank}
  • \n\n
  • [:octicons-arrow-right-24: Custom actions](https://viem.sh/docs/clients/custom#extending-with-actions-or-configuration){target=\\_blank}
  • \n
\n\n- External __Test Frameworks__\n\n ---\n\n Integrate viem with the following frameworks for comprehensive testing:\n
    \n
  • [:octicons-arrow-right-24: Hardhat](https://hardhat.org/){target=\\_blank}
  • \n\n
  • [:octicons-arrow-right-24: Foundry](https://getfoundry.sh/){target=\\_blank}
  • \n
\n\n- External __Event Handling__\n\n ---\n\n Learn how to subscribe to and process contract events:\n
    \n
  • [:octicons-arrow-right-24: Event subscription](https://viem.sh/docs/actions/public/watchEvent#watchevent){target=\\_blank}
  • \n
\n\n- External __Building dApps__\n\n ---\n\n Combine viem the following technologies to create full-stack applications:\n
    \n
  • [:octicons-arrow-right-24: Next.js](https://nextjs.org/docs){target=\\_blank}
  • \n\n
  • [:octicons-arrow-right-24: Node.js](https://nodejs.org/en){target=\\_blank}
  • \n
\n\n
"} {"page_id": "smart-contracts-libraries-wagmi", "page_title": "Wagmi for Polkadot Hub Smart Contracts", "index": 0, "depth": 2, "title": "Introduction", "anchor": "introduction", "start_char": 9, "end_char": 437, "estimated_token_count": 97, "token_estimator": "heuristic-v1", "text": "## Introduction\n\n[Wagmi](https://wagmi.sh/){target=\\_blank} is a collection of [React Hooks](https://wagmi.sh/react/api/hooks){target=\\_blank} for interacting with Ethereum-compatible blockchains, focusing on developer experience, feature richness, and reliability.\n\nThis guide demonstrates how to use Wagmi to interact with and deploy smart contracts to Polkadot Hub, providing a seamless frontend integration for your dApps."} {"page_id": "smart-contracts-libraries-wagmi", "page_title": "Wagmi for Polkadot Hub Smart Contracts", "index": 1, "depth": 2, "title": "Set Up the Project", "anchor": "set-up-the-project", "start_char": 437, "end_char": 668, "estimated_token_count": 55, "token_estimator": "heuristic-v1", "text": "## Set Up the Project\n\nTo start working with Wagmi, create a new React project and initialize it by running the following commands in your terminal:\n\n```bash\nnpx create-next-app@latest wagmi-polkadot-hub\ncd wagmi-polkadot-hub\n```"} -{"page_id": "smart-contracts-libraries-wagmi", "page_title": "Wagmi for Polkadot Hub Smart Contracts", "index": 2, "depth": 2, "title": "Install Dependencies", "anchor": "install-dependencies", "start_char": 668, "end_char": 793, "estimated_token_count": 28, "token_estimator": "heuristic-v1", "text": "## Install Dependencies\n\nInstall Wagmi and its peer dependencies:\n\n```bash\nnpm install wagmi viem @tanstack/react-query\n```"} -{"page_id": "smart-contracts-libraries-wagmi", "page_title": "Wagmi for Polkadot Hub Smart Contracts", "index": 3, "depth": 2, "title": "Configure Wagmi for Polkadot Hub", "anchor": "configure-wagmi-for-polkadot-hub", "start_char": 793, "end_char": 2527, "estimated_token_count": 392, "token_estimator": "heuristic-v1", "text": "## Configure Wagmi for Polkadot Hub\n\nCreate a configuration file to initialize Wagmi with Polkadot Hub. In your project, create a file named `app/lib/wagmi.ts` and add the code below. Be sure to replace `INSERT_RPC_URL`, `INSERT_CHAIN_ID`, `INSERT_CHAIN_NAME`, `INSERT_NETWORK_NAME`, `INSERT_CHAIN_DECIMALS`, `INSERT_CURRENCY_NAME`, and `INSERT_CURRENCY_SYMBOL` with your specific values.\n\n```typescript title=\"app/lib/wagmi.ts\"\nimport { http, createConfig } from 'wagmi'\n\n// Configure the Polkadot Hub chain\nconst assetHub = {\n id: INSERT_CHAIN_ID,\n name: 'INSERT_CHAIN_NAME',\n network: 'INSERT_NETWORK_NAME',\n nativeCurrency: {\n decimals: INSERT_CHAIN_DECIMALS,\n name: 'INSERT_CURRENCY_NAME',\n symbol: 'INSERT_CURRENCY_SYMBOL',\n },\n rpcUrls: {\n default: {\n http: ['INSERT_RPC_URL'],\n },\n },\n} as const;\n\n// Create Wagmi config\nexport const config = createConfig({\n chains: [assetHub],\n transports: {\n [assetHub.id]: http(),\n },\n})\n```\n\n??? code \"Example Polkadot Hub TestNet Configuration\"\n\n ```typescript title=\"src/lib/wagmi.ts\"\n import { http, createConfig } from 'wagmi';\n\n // Configure the Polkadot Hub chain\n const assetHub = {\n id: 420420422,\n name: 'polkadot-hub-testnet',\n network: 'polkadot-hub-testnet',\n nativeCurrency: {\n decimals: 18,\n name: 'PAS',\n symbol: 'PAS',\n },\n rpcUrls: {\n default: {\n http: ['https://testnet-passet-hub-eth-rpc.polkadot.io'], // TODO: change to paseo asset hub once ready\n },\n },\n } as const;\n\n // Create wagmi config\n export const config = createConfig({\n chains: [assetHub],\n transports: {\n [assetHub.id]: http(),\n },\n });\n ```"} -{"page_id": "smart-contracts-libraries-wagmi", "page_title": "Wagmi for Polkadot Hub Smart Contracts", "index": 4, "depth": 2, "title": "Set Up the Wagmi Provider", "anchor": "set-up-the-wagmi-provider", "start_char": 2527, "end_char": 3571, "estimated_token_count": 263, "token_estimator": "heuristic-v1", "text": "## Set Up the Wagmi Provider\n\nTo enable Wagmi in your React application, you need to wrap your app with the [`WagmiProvider`](https://wagmi.sh/react/api/WagmiProvider#wagmiprovider){target=\\_blank}. Update your `app/layout.tsx` file (for Next.js app router) with the following code:\n\n```typescript title=\"app/layout.tsx\"\n// For app router (src/app/layout.tsx)\n\"use client\";\n\nimport { WagmiProvider } from \"wagmi\";\nimport { QueryClient, QueryClientProvider } from \"@tanstack/react-query\";\nimport { config } from \"./lib/wagmi\";\n\n// Create a query client\nconst queryClient = new QueryClient();\n\nexport default function RootLayout({\n children,\n}: {\n children: React.ReactNode;\n}) {\n return (\n \n \n \n \n {children}\n \n \n \n \n );\n}\n\n```\n\n!!!note\n If you are using a Next.js pages router, you should modify the `src/pages/_app.tsx` instead."} -{"page_id": "smart-contracts-libraries-wagmi", "page_title": "Wagmi for Polkadot Hub Smart Contracts", "index": 5, "depth": 2, "title": "Connect a Wallet", "anchor": "connect-a-wallet", "start_char": 3571, "end_char": 5026, "estimated_token_count": 371, "token_estimator": "heuristic-v1", "text": "## Connect a Wallet\n\nCreate a component to connect wallets to your dApp. Create a file named `app/components/ConnectWallet.tsx`:\n\n```typescript title=\"app/components/ConnectWallet.tsx\"\n\"use client\";\n\nimport React from \"react\";\nimport { useConnect, useAccount, useDisconnect } from \"wagmi\";\nimport { injected } from \"wagmi/connectors\";\n\nexport function ConnectWallet() {\n const { connect } = useConnect();\n const { address, isConnected } = useAccount();\n const { disconnect } = useDisconnect();\n\n if (isConnected) {\n return (\n
\n
Connected to {address}
\n \n
\n );\n }\n\n return (\n \n );\n}\n\n```\n\nThis component uses the following React hooks:\n\n- **[`useConnect`](https://wagmi.sh/react/api/hooks/useConnect#useconnect){target=\\_blank}**: Provides functions and state for connecting the user's wallet to your dApp. The `connect` function initiates the connection flow with the specified connector.\n- **[`useDisconnect`](https://wagmi.sh/react/api/hooks/useDisconnect#usedisconnect){target=\\_blank}**: Provides a function to disconnect the currently connected wallet.\n- **[`useAccount`](https://2.x.wagmi.sh/react/api/hooks/useAccount#useaccount){target=\\_blank}**: Returns data about the connected account, including the address and connection status."} -{"page_id": "smart-contracts-libraries-wagmi", "page_title": "Wagmi for Polkadot Hub Smart Contracts", "index": 6, "depth": 2, "title": "Fetch Blockchain Data", "anchor": "fetch-blockchain-data", "start_char": 5026, "end_char": 6506, "estimated_token_count": 359, "token_estimator": "heuristic-v1", "text": "## Fetch Blockchain Data\n\nWagmi provides various hooks to fetch blockchain data. Here's an example component that demonstrates some of these hooks:\n\n```typescript title=\"app/components/BlockchainInfo.tsx\"\n\"use client\";\n\nimport { useBlockNumber, useBalance, useAccount } from \"wagmi\";\n\nexport function BlockchainInfo() {\n const { address } = useAccount();\n // Get the latest block number\n const { data: blockNumber } = useBlockNumber({ watch: true });\n\n // Get balance for the connected wallet\n const { data: balance } = useBalance({\n address,\n });\n\n return (\n
\n

Blockchain Information

\n
\n

Current Block: {blockNumber?.toString() || \"Loading...\"}

\n\n {address && balance && (\n

\n Balance:{\" \"}\n {(\n BigInt(balance.value) / BigInt(10 ** balance.decimals)\n ).toLocaleString()}{\" \"}\n {balance.symbol}\n

\n )}\n
\n
\n );\n}\n\n```\n\nThis component uses the following React hooks:\n\n- **[`useBlockNumber`](https://wagmi.sh/react/api/hooks/useBlockNumber#useBlockNumber){target=\\_blank}**: Fetches the current block number of the connected chain. The `watch` parameter enables real-time updates when new blocks are mined.\n- **[`useBalance`](https://wagmi.sh/react/api/hooks/useBalance#useBalance){target=\\_blank}**: Retrieves the native token balance for a specified address, including value, symbol, and decimals information."} -{"page_id": "smart-contracts-libraries-wagmi", "page_title": "Wagmi for Polkadot Hub Smart Contracts", "index": 7, "depth": 2, "title": "Interact with Deployed Contract", "anchor": "interact-with-deployed-contract", "start_char": 6506, "end_char": 10949, "estimated_token_count": 984, "token_estimator": "heuristic-v1", "text": "## Interact with Deployed Contract\n\nThis guide uses a simple Storage contract already deployed to the Polkadot Hub TestNet. The code of that contract is:\n\n??? code \"Storage.sol\"\n\n ```solidity title=\"Storage.sol\"\n //SPDX-License-Identifier: MIT\n\n // Solidity files have to start with this pragma.\n // It will be used by the Solidity compiler to validate its version.\n pragma solidity ^0.8.9;\n\n contract Storage {\n // Public state variable to store a number\n uint256 public storedNumber;\n\n /**\n * Updates the stored number.\n *\n * The `public` modifier allows anyone to call this function.\n *\n * @param _newNumber - The new value to store.\n */\n function setNumber(uint256 _newNumber) public {\n storedNumber = _newNumber;\n }\n }\n ```\n\nCreate a component to interact with your deployed contract. Create a file named `app/components/StorageContract.tsx`:\n\n```typescript title=\"app/components/StorageContract.tsx\"\n\"use client\";\n\nimport { useState } from \"react\";\nimport {\n useReadContract,\n useWriteContract,\n useWaitForTransactionReceipt,\n} from \"wagmi\";\n\nconst CONTRACT_ADDRESS =\n \"INSERT_CONTRACT_ADDRESS\" as `0x${string}`;\n\nexport function StorageContract() {\n const [number, setNumber] = useState(\"42\");\n\n // Contract ABI (should match your compiled contract)\n const abi = [\n {\n inputs: [],\n name: \"storedNumber\",\n outputs: [{ internalType: \"uint256\", name: \"\", type: \"uint256\" }],\n stateMutability: \"view\",\n type: \"function\",\n },\n {\n inputs: [\n { internalType: \"uint256\", name: \"_newNumber\", type: \"uint256\" },\n ],\n name: \"setNumber\",\n outputs: [],\n stateMutability: \"nonpayable\",\n type: \"function\",\n },\n ];\n\n // Read the current stored number\n const { data: storedNumber, refetch } = useReadContract({\n address: CONTRACT_ADDRESS,\n abi,\n functionName: \"storedNumber\",\n });\n\n // Write to the contract\n const { writeContract, data: hash, error, isPending } = useWriteContract();\n\n // Wait for transaction to be mined\n const { isLoading: isConfirming, isSuccess: isConfirmed } =\n useWaitForTransactionReceipt({\n hash,\n });\n\n const handleSetNumber = () => {\n writeContract({\n address: CONTRACT_ADDRESS,\n abi,\n functionName: \"setNumber\",\n args: [BigInt(number)],\n });\n };\n\n return (\n
\n

Storage Contract Interaction

\n
\n

Contract Address: {CONTRACT_ADDRESS}

\n

Current Stored Number: {storedNumber?.toString() || \"Loading...\"}

\n
\n\n
\n setNumber(e.target.value)}\n disabled={isPending || isConfirming}\n />\n \n
\n\n {error &&
Error: {error.message}
}\n\n {isConfirmed && (\n
\n Successfully updated!{\" \"}\n \n
\n )}\n
\n );\n}\n\n```\n\nThis component demonstrates how to interact with a smart contract using Wagmi's hooks:\n\n- **[`useReadContract`](https://wagmi.sh/react/api/hooks/useReadContract#useReadContract){target=\\_blank}**: Calls a read-only function on your smart contract to retrieve data without modifying the blockchain state.\n- **[`useWriteContract`](https://wagmi.sh/react/api/hooks/useWriteContract#useWriteContract){target=\\_blank}**: Calls a state-modifying function on your smart contract, which requires a transaction to be signed and sent.\n- **[`useWaitForTransactionReceipt`](https://wagmi.sh/react/api/hooks/useWaitForTransactionReceipt#useWaitForTransactionReceipt){target=\\_blank}**: Tracks the status of a transaction after it's been submitted, allowing you to know when it's been confirmed.\n\nThe component also includes proper state handling to:\n\n- Show the current value stored in the contract.\n- Allow users to input a new value.\n- Display transaction status (pending, confirming, or completed).\n- Handle errors.\n- Provide feedback when a transaction is successful."} -{"page_id": "smart-contracts-libraries-wagmi", "page_title": "Wagmi for Polkadot Hub Smart Contracts", "index": 8, "depth": 2, "title": "Integrate Components", "anchor": "integrate-components", "start_char": 10949, "end_char": 11701, "estimated_token_count": 183, "token_estimator": "heuristic-v1", "text": "## Integrate Components\n\nUpdate your main page to combine all the components. Create or update the file `src/app/page.tsx`:\n\n```typescript title=\"src/app/page.tsx\"\n\"use client\";\n\nimport { BlockchainInfo } from \"./components/BlockchainInfo\";\nimport { ConnectWallet } from \"./components/ConnectWallet\";\nimport { StorageContract } from \"./components/StorageContract\";\nimport { useAccount } from \"wagmi\";\n\nexport default function Home() {\n const { isConnected } = useAccount();\n\n return (\n
\n

Wagmi - Polkadot Hub Smart Contracts

\n \n {isConnected ? : Connect your wallet}\n {isConnected ? : Connect your wallet}\n
\n );\n}\n\n```"} -{"page_id": "smart-contracts-libraries-wagmi", "page_title": "Wagmi for Polkadot Hub Smart Contracts", "index": 9, "depth": 2, "title": "Where to Go Next", "anchor": "where-to-go-next", "start_char": 11701, "end_char": 13344, "estimated_token_count": 512, "token_estimator": "heuristic-v1", "text": "## Where to Go Next\n\nNow that you have the foundational knowledge to use Wagmi with Polkadot Hub, consider exploring:\n\n
\n\n- External __Advanced Wagmi__\n\n ---\n\n Explore Wagmi's advanced features:\n\n
    \n
  • [:octicons-arrow-right-24: Watch Contract Events](https://wagmi.sh/core/api/actions/watchContractEvent#eventname){target=\\_blank}
  • \n
  • [:octicons-arrow-right-24: Different Transports](https://wagmi.sh/react/api/transports){target=\\_blank}
  • \n
  • [:octicons-arrow-right-24: Actions](https://wagmi.sh/react/api/actions){target=\\_blank}
  • \n
\n\n- External __Wallet Integration__\n\n ---\n\n Connect your dApp with popular wallet providers:\n\n
    \n
  • [:octicons-arrow-right-24: MetaMask](https://wagmi.sh/core/api/connectors/metaMask){target=\\_blank}
  • \n
  • [:octicons-arrow-right-24: WalletConnect](https://wagmi.sh/core/api/connectors/walletConnect){target=\\_blank}
  • \n
  • [:octicons-arrow-right-24: Coinbase Wallet](https://wagmi.sh/core/api/connectors/coinbaseWallet){target=\\_blank}
  • \n
\n\n- External __Testing & Development__\n\n ---\n\n Enhance your development workflow:\n\n
    \n
  • [:octicons-arrow-right-24: Test Suite](https://wagmi.sh/dev/contributing#_6-running-the-test-suite){target=\\_blank}
  • \n
  • [:octicons-arrow-right-24: Dev Playground](https://wagmi.sh/dev/contributing#_5-running-the-dev-playgrounds){target=\\_blank}
  • \n
\n
"} +{"page_id": "smart-contracts-libraries-wagmi", "page_title": "Wagmi for Polkadot Hub Smart Contracts", "index": 2, "depth": 2, "title": "Install Dependencies", "anchor": "install-dependencies", "start_char": 668, "end_char": 798, "estimated_token_count": 31, "token_estimator": "heuristic-v1", "text": "## Install Dependencies\n\nInstall Wagmi v3 and its peer dependencies:\n\n```bash\nnpm install wagmi@3 viem @tanstack/react-query\n```"} +{"page_id": "smart-contracts-libraries-wagmi", "page_title": "Wagmi for Polkadot Hub Smart Contracts", "index": 3, "depth": 2, "title": "Configure Wagmi for Polkadot Hub", "anchor": "configure-wagmi-for-polkadot-hub", "start_char": 798, "end_char": 2532, "estimated_token_count": 392, "token_estimator": "heuristic-v1", "text": "## Configure Wagmi for Polkadot Hub\n\nCreate a configuration file to initialize Wagmi with Polkadot Hub. In your project, create a file named `app/lib/wagmi.ts` and add the code below. Be sure to replace `INSERT_RPC_URL`, `INSERT_CHAIN_ID`, `INSERT_CHAIN_NAME`, `INSERT_NETWORK_NAME`, `INSERT_CHAIN_DECIMALS`, `INSERT_CURRENCY_NAME`, and `INSERT_CURRENCY_SYMBOL` with your specific values.\n\n```typescript title=\"app/lib/wagmi.ts\"\nimport { http, createConfig } from 'wagmi'\n\n// Configure the Polkadot Hub chain\nconst assetHub = {\n id: INSERT_CHAIN_ID,\n name: 'INSERT_CHAIN_NAME',\n network: 'INSERT_NETWORK_NAME',\n nativeCurrency: {\n decimals: INSERT_CHAIN_DECIMALS,\n name: 'INSERT_CURRENCY_NAME',\n symbol: 'INSERT_CURRENCY_SYMBOL',\n },\n rpcUrls: {\n default: {\n http: ['INSERT_RPC_URL'],\n },\n },\n} as const;\n\n// Create Wagmi config\nexport const config = createConfig({\n chains: [assetHub],\n transports: {\n [assetHub.id]: http(),\n },\n})\n```\n\n??? code \"Example Polkadot Hub TestNet Configuration\"\n\n ```typescript title=\"src/lib/wagmi.ts\"\n import { http, createConfig } from 'wagmi';\n\n // Configure the Polkadot Hub chain\n const assetHub = {\n id: 420420422,\n name: 'polkadot-hub-testnet',\n network: 'polkadot-hub-testnet',\n nativeCurrency: {\n decimals: 18,\n name: 'PAS',\n symbol: 'PAS',\n },\n rpcUrls: {\n default: {\n http: ['https://testnet-passet-hub-eth-rpc.polkadot.io'], // TODO: change to paseo asset hub once ready\n },\n },\n } as const;\n\n // Create wagmi config\n export const config = createConfig({\n chains: [assetHub],\n transports: {\n [assetHub.id]: http(),\n },\n });\n ```"} +{"page_id": "smart-contracts-libraries-wagmi", "page_title": "Wagmi for Polkadot Hub Smart Contracts", "index": 4, "depth": 2, "title": "Set Up the Wagmi Provider", "anchor": "set-up-the-wagmi-provider", "start_char": 2532, "end_char": 3576, "estimated_token_count": 263, "token_estimator": "heuristic-v1", "text": "## Set Up the Wagmi Provider\n\nTo enable Wagmi in your React application, you need to wrap your app with the [`WagmiProvider`](https://wagmi.sh/react/api/WagmiProvider#wagmiprovider){target=\\_blank}. Update your `app/layout.tsx` file (for Next.js app router) with the following code:\n\n```typescript title=\"app/layout.tsx\"\n// For app router (src/app/layout.tsx)\n\"use client\";\n\nimport { WagmiProvider } from \"wagmi\";\nimport { QueryClient, QueryClientProvider } from \"@tanstack/react-query\";\nimport { config } from \"./lib/wagmi\";\n\n// Create a query client\nconst queryClient = new QueryClient();\n\nexport default function RootLayout({\n children,\n}: {\n children: React.ReactNode;\n}) {\n return (\n \n \n \n \n {children}\n \n \n \n \n );\n}\n\n```\n\n!!!note\n If you are using a Next.js pages router, you should modify the `src/pages/_app.tsx` instead."} +{"page_id": "smart-contracts-libraries-wagmi", "page_title": "Wagmi for Polkadot Hub Smart Contracts", "index": 5, "depth": 2, "title": "Connect a Wallet", "anchor": "connect-a-wallet", "start_char": 3576, "end_char": 5105, "estimated_token_count": 382, "token_estimator": "heuristic-v1", "text": "## Connect a Wallet\n\nCreate a component to connect wallets to your dApp. Create a file named `app/components/ConnectWallet.tsx`:\n\n```typescript title=\"app/components/ConnectWallet.tsx\"\n\"use client\";\n\nimport React from \"react\";\nimport { useConnect, useConnection, useDisconnect } from \"wagmi\";\nimport { injected } from \"wagmi/connectors\";\n\nexport function ConnectWallet() {\n const { connect } = useConnect();\n const { address, isConnected } = useConnection();\n const { disconnect } = useDisconnect();\n\n if (isConnected) {\n return (\n
\n
Connected to {address}
\n \n
\n );\n }\n\n return (\n \n );\n}\n\n```\n\nThis component uses the following React hooks:\n\n- **[`useConnect`](https://wagmi.sh/react/api/hooks/useConnect#useconnect){target=\\_blank}**: Provides functions and state for connecting the user's wallet to your dApp. The `connect` function initiates the connection flow with the specified connector.\n- **[`useDisconnect`](https://wagmi.sh/react/api/hooks/useDisconnect#usedisconnect){target=\\_blank}**: Provides a function to disconnect the currently connected wallet.\n- **[`useConnection`](https://wagmi.sh/react/api/hooks/useConnection#useconnection){target=\\_blank}**: Returns data about the connected account, including the address and connection status. In Wagmi v3, `useAccount` has been renamed to `useConnection`."} +{"page_id": "smart-contracts-libraries-wagmi", "page_title": "Wagmi for Polkadot Hub Smart Contracts", "index": 6, "depth": 2, "title": "Fetch Blockchain Data", "anchor": "fetch-blockchain-data", "start_char": 5105, "end_char": 6591, "estimated_token_count": 359, "token_estimator": "heuristic-v1", "text": "## Fetch Blockchain Data\n\nWagmi provides various hooks to fetch blockchain data. Here's an example component that demonstrates some of these hooks:\n\n```typescript title=\"app/components/BlockchainInfo.tsx\"\n\"use client\";\n\nimport { useBlockNumber, useBalance, useConnection } from \"wagmi\";\n\nexport function BlockchainInfo() {\n const { address } = useConnection();\n // Get the latest block number\n const { data: blockNumber } = useBlockNumber({ watch: true });\n\n // Get balance for the connected wallet\n const { data: balance } = useBalance({\n address,\n });\n\n return (\n
\n

Blockchain Information

\n
\n

Current Block: {blockNumber?.toString() || \"Loading...\"}

\n\n {address && balance && (\n

\n Balance:{\" \"}\n {(\n BigInt(balance.value) / BigInt(10 ** balance.decimals)\n ).toLocaleString()}{\" \"}\n {balance.symbol}\n

\n )}\n
\n
\n );\n}\n\n```\n\nThis component uses the following React hooks:\n\n- **[`useBlockNumber`](https://wagmi.sh/react/api/hooks/useBlockNumber#useBlockNumber){target=\\_blank}**: Fetches the current block number of the connected chain. The `watch` parameter enables real-time updates when new blocks are mined.\n- **[`useBalance`](https://wagmi.sh/react/api/hooks/useBalance#useBalance){target=\\_blank}**: Retrieves the native token balance for a specified address, including value, symbol, and decimals information."} +{"page_id": "smart-contracts-libraries-wagmi", "page_title": "Wagmi for Polkadot Hub Smart Contracts", "index": 7, "depth": 2, "title": "Interact with Deployed Contract", "anchor": "interact-with-deployed-contract", "start_char": 6591, "end_char": 11034, "estimated_token_count": 984, "token_estimator": "heuristic-v1", "text": "## Interact with Deployed Contract\n\nThis guide uses a simple Storage contract already deployed to the Polkadot Hub TestNet. The code of that contract is:\n\n??? code \"Storage.sol\"\n\n ```solidity title=\"Storage.sol\"\n //SPDX-License-Identifier: MIT\n\n // Solidity files have to start with this pragma.\n // It will be used by the Solidity compiler to validate its version.\n pragma solidity ^0.8.9;\n\n contract Storage {\n // Public state variable to store a number\n uint256 public storedNumber;\n\n /**\n * Updates the stored number.\n *\n * The `public` modifier allows anyone to call this function.\n *\n * @param _newNumber - The new value to store.\n */\n function setNumber(uint256 _newNumber) public {\n storedNumber = _newNumber;\n }\n }\n ```\n\nCreate a component to interact with your deployed contract. Create a file named `app/components/StorageContract.tsx`:\n\n```typescript title=\"app/components/StorageContract.tsx\"\n\"use client\";\n\nimport { useState } from \"react\";\nimport {\n useReadContract,\n useWriteContract,\n useWaitForTransactionReceipt,\n} from \"wagmi\";\n\nconst CONTRACT_ADDRESS =\n \"INSERT_CONTRACT_ADDRESS\" as `0x${string}`;\n\nexport function StorageContract() {\n const [number, setNumber] = useState(\"42\");\n\n // Contract ABI (should match your compiled contract)\n const abi = [\n {\n inputs: [],\n name: \"storedNumber\",\n outputs: [{ internalType: \"uint256\", name: \"\", type: \"uint256\" }],\n stateMutability: \"view\",\n type: \"function\",\n },\n {\n inputs: [\n { internalType: \"uint256\", name: \"_newNumber\", type: \"uint256\" },\n ],\n name: \"setNumber\",\n outputs: [],\n stateMutability: \"nonpayable\",\n type: \"function\",\n },\n ];\n\n // Read the current stored number\n const { data: storedNumber, refetch } = useReadContract({\n address: CONTRACT_ADDRESS,\n abi,\n functionName: \"storedNumber\",\n });\n\n // Write to the contract\n const { writeContract, data: hash, error, isPending } = useWriteContract();\n\n // Wait for transaction to be mined\n const { isLoading: isConfirming, isSuccess: isConfirmed } =\n useWaitForTransactionReceipt({\n hash,\n });\n\n const handleSetNumber = () => {\n writeContract({\n address: CONTRACT_ADDRESS,\n abi,\n functionName: \"setNumber\",\n args: [BigInt(number)],\n });\n };\n\n return (\n
\n

Storage Contract Interaction

\n
\n

Contract Address: {CONTRACT_ADDRESS}

\n

Current Stored Number: {storedNumber?.toString() || \"Loading...\"}

\n
\n\n
\n setNumber(e.target.value)}\n disabled={isPending || isConfirming}\n />\n \n
\n\n {error &&
Error: {error.message}
}\n\n {isConfirmed && (\n
\n Successfully updated!{\" \"}\n \n
\n )}\n
\n );\n}\n\n```\n\nThis component demonstrates how to interact with a smart contract using Wagmi's hooks:\n\n- **[`useReadContract`](https://wagmi.sh/react/api/hooks/useReadContract#useReadContract){target=\\_blank}**: Calls a read-only function on your smart contract to retrieve data without modifying the blockchain state.\n- **[`useWriteContract`](https://wagmi.sh/react/api/hooks/useWriteContract#useWriteContract){target=\\_blank}**: Calls a state-modifying function on your smart contract, which requires a transaction to be signed and sent.\n- **[`useWaitForTransactionReceipt`](https://wagmi.sh/react/api/hooks/useWaitForTransactionReceipt#useWaitForTransactionReceipt){target=\\_blank}**: Tracks the status of a transaction after it's been submitted, allowing you to know when it's been confirmed.\n\nThe component also includes proper state handling to:\n\n- Show the current value stored in the contract.\n- Allow users to input a new value.\n- Display transaction status (pending, confirming, or completed).\n- Handle errors.\n- Provide feedback when a transaction is successful."} +{"page_id": "smart-contracts-libraries-wagmi", "page_title": "Wagmi for Polkadot Hub Smart Contracts", "index": 8, "depth": 2, "title": "Integrate Components", "anchor": "integrate-components", "start_char": 11034, "end_char": 11792, "estimated_token_count": 183, "token_estimator": "heuristic-v1", "text": "## Integrate Components\n\nUpdate your main page to combine all the components. Create or update the file `src/app/page.tsx`:\n\n```typescript title=\"src/app/page.tsx\"\n\"use client\";\n\nimport { BlockchainInfo } from \"./components/BlockchainInfo\";\nimport { ConnectWallet } from \"./components/ConnectWallet\";\nimport { StorageContract } from \"./components/StorageContract\";\nimport { useConnection } from \"wagmi\";\n\nexport default function Home() {\n const { isConnected } = useConnection();\n\n return (\n
\n

Wagmi - Polkadot Hub Smart Contracts

\n \n {isConnected ? : Connect your wallet}\n {isConnected ? : Connect your wallet}\n
\n );\n}\n\n```"} +{"page_id": "smart-contracts-libraries-wagmi", "page_title": "Wagmi for Polkadot Hub Smart Contracts", "index": 9, "depth": 2, "title": "Where to Go Next", "anchor": "where-to-go-next", "start_char": 11792, "end_char": 13435, "estimated_token_count": 512, "token_estimator": "heuristic-v1", "text": "## Where to Go Next\n\nNow that you have the foundational knowledge to use Wagmi with Polkadot Hub, consider exploring:\n\n
\n\n- External __Advanced Wagmi__\n\n ---\n\n Explore Wagmi's advanced features:\n\n
    \n
  • [:octicons-arrow-right-24: Watch Contract Events](https://wagmi.sh/core/api/actions/watchContractEvent#eventname){target=\\_blank}
  • \n
  • [:octicons-arrow-right-24: Different Transports](https://wagmi.sh/react/api/transports){target=\\_blank}
  • \n
  • [:octicons-arrow-right-24: Actions](https://wagmi.sh/react/api/actions){target=\\_blank}
  • \n
\n\n- External __Wallet Integration__\n\n ---\n\n Connect your dApp with popular wallet providers:\n\n
    \n
  • [:octicons-arrow-right-24: MetaMask](https://wagmi.sh/core/api/connectors/metaMask){target=\\_blank}
  • \n
  • [:octicons-arrow-right-24: WalletConnect](https://wagmi.sh/core/api/connectors/walletConnect){target=\\_blank}
  • \n
  • [:octicons-arrow-right-24: Coinbase Wallet](https://wagmi.sh/core/api/connectors/coinbaseWallet){target=\\_blank}
  • \n
\n\n- External __Testing & Development__\n\n ---\n\n Enhance your development workflow:\n\n
    \n
  • [:octicons-arrow-right-24: Test Suite](https://wagmi.sh/dev/contributing#_6-running-the-test-suite){target=\\_blank}
  • \n
  • [:octicons-arrow-right-24: Dev Playground](https://wagmi.sh/dev/contributing#_5-running-the-dev-playgrounds){target=\\_blank}
  • \n
\n
"} {"page_id": "smart-contracts-libraries-web3-js", "page_title": "Deploy Contracts to Polkadot Hub with Web3.js", "index": 0, "depth": 2, "title": "Introduction", "anchor": "introduction", "start_char": 298, "end_char": 857, "estimated_token_count": 102, "token_estimator": "heuristic-v1", "text": "## Introduction\n\nInteracting with blockchains typically requires an interface between your application and the network. [Web3.js](https://web3js.readthedocs.io/){target=\\_blank} offers this interface through a comprehensive collection of libraries, facilitating seamless interaction with the nodes using HTTP or WebSocket protocols. This guide illustrates how to utilize Web3.js specifically for interactions with Polkadot Hub.\n\nThis guide is intended for developers who are familiar with JavaScript and want to interact with the Polkadot Hub using Web3.js."} {"page_id": "smart-contracts-libraries-web3-js", "page_title": "Deploy Contracts to Polkadot Hub with Web3.js", "index": 1, "depth": 2, "title": "Prerequisites", "anchor": "prerequisites", "start_char": 857, "end_char": 1213, "estimated_token_count": 110, "token_estimator": "heuristic-v1", "text": "## Prerequisites\n\nBefore getting started, ensure you have the following installed:\n\n- **Node.js**: v22.13.1 or later, check the [Node.js installation guide](https://nodejs.org/en/download/current/){target=\\_blank}.\n- **npm**: v6.13.4 or later (comes bundled with Node.js).\n- **Solidity**: This guide uses Solidity `^0.8.9` for smart contract development."} {"page_id": "smart-contracts-libraries-web3-js", "page_title": "Deploy Contracts to Polkadot Hub with Web3.js", "index": 2, "depth": 2, "title": "Project Structure", "anchor": "project-structure", "start_char": 1213, "end_char": 1691, "estimated_token_count": 135, "token_estimator": "heuristic-v1", "text": "## Project Structure\n\nThis project organizes contracts, scripts, and compiled artifacts for easy development and deployment.\n\n```text\nweb3js-project\n├── contracts\n│ ├── Storage.sol\n├── scripts\n│ ├── connectToProvider.js\n│ ├── fetchLastBlock.js\n│ ├── compile.js\n│ ├── deploy.js\n│ ├── updateStorage.js\n├── abis\n│ ├── Storage.json\n├── artifacts\n│ ├── Storage.bin\n├── contract-address.json\n├── node_modules/\n├── package.json\n├── package-lock.json\n└── README.md\n```"} diff --git a/llms.txt b/llms.txt index 4019296cb..c6b491c4c 100644 --- a/llms.txt +++ b/llms.txt @@ -81,63 +81,31 @@ Docs: Parachains - [Unlock a Parachain](https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/parachains-runtime-maintenance-unlock-parachains.md): Learn how to unlock your parachain. This step-by-step guide covers verifying lock status, preparing calls, and executing the unlock process. - [Fork a Parachain Using Chopsticks](https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/parachains-testing-fork-a-parachain.md): Simplify Polkadot SDK development with Chopsticks. Learn essential features, how to install Chopsticks, and how to configure local blockchain forks. - [Run a Parachain Network](https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/parachains-testing-run-a-parachain-network.md): Quickly install and configure Zombienet to deploy and test Polkadot-based blockchain networks with this comprehensive getting-started guide. -- [Parachain Consensus](https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/reference-parachains-consensus-overview.md): Understand how the blocks authored by parachain collators are secured by the relay chain validators and how the parachain transactions achieve finality. -- [Parachains Overview](https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/reference-parachains.md): Learn about parachains, specialized blockchains on Polkadot that gain shared security and interoperability. Discover how they work and the tools to build them. -- [Overview of the Polkadot Relay Chain](https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/reference-polkadot-hub-consensus-and-security-relay-chain.md): Explore Polkadot's core architecture, including its multi-chain vision, shared security, and the DOT token's governance and staking roles. -- [Light Clients](https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/reference-tools-light-clients.md): Light clients enable secure and efficient blockchain interaction without running a full node. Learn everything you need to know about light clients on Polkadot. -- [E2E Testing with Moonwall](https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/reference-tools-moonwall.md): Enhance blockchain end-to-end testing with Moonwall's standardized environment setup, comprehensive configuration management, and simple network interactions. -- [Polkadot Omni Node](https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/reference-tools-omninode.md): Run parachain nodes easily with the polkadot-omni-node, a white-labeled binary that can run parachain nodes using a single pre-built solution. Docs: dApps - [Deploying Uniswap V2 on Polkadot](https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/smart-contracts-cookbook-eth-dapps-uniswap-v2.md): Learn how to deploy and test Uniswap V2 on Polkadot Hub using Hardhat, bringing AMM-based token swaps to the Polkadot ecosystem. - [Smart Contracts Cookbook](https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/smart-contracts-cookbook.md): Explore our full collection of tutorials and guides to learn step-by-step how to build, deploy, and work with smart contracts on Polkadot. -Docs: Networks -- [Networks](https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/reference-parachains-networks.md): Explore Polkadot's testing and production networks, including Westend, Kusama, and Paseo, for efficient development, deployment, and testing. - Docs: Polkadot Protocol - [Get Started with XCM](https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/parachains-interoperability-get-started.md): Unlock blockchain interoperability with XCM — Polkadot's Cross-Consensus Messaging format for cross-chain interactions. -- [Origins and Tracks](https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/reference-governance-origins-tracks.md): Explore Polkadot's OpenGov origins and tracks system, defining privilege levels, decision processes, and tailored pathways for network proposals. -- [On-Chain Governance Overview](https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/reference-governance.md): Discover Polkadot’s cutting-edge OpenGov system, enabling transparent, decentralized decision-making through direct democracy and flexible governance tracks. -- [Polkadot SDK Accounts](https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/reference-parachains-accounts.md): Learn about account structures, balances, and address formats in the Polkadot SDK, including how to manage lifecycle, references, and balances. -- [Blocks](https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/reference-parachains-blocks-transactions-fees-blocks.md): Understand how blocks are produced, validated, and imported in Polkadot SDK-based blockchains, covering initialization, finalization, and authoring processes. -- [Transactions Weights and Fees](https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/reference-parachains-blocks-transactions-fees-fees.md): Overview of transaction weights and fees in Polkadot SDK chains, detailing how fees are calculated using a defined formula and runtime specifics. -- [Transactions](https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/reference-parachains-blocks-transactions-fees-transactions.md): Learn how to construct, submit, and validate transactions in the Polkadot SDK, covering signed, unsigned, and inherent types of transactions. -- [Chain Data](https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/reference-parachains-chain-data.md): Learn how to expose and utilize chain data for blockchain applications. Discover runtime metadata, RPC APIs, and tools for efficient development. -- [Elastic Scaling](https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/reference-parachains-consensus-elastic-scaling.md): Learn how elastic scaling in Polkadot boosts parachain throughput, reduces latency, and supports dynamic, cost-efficient resource allocation. -- [Parachain Consensus](https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/reference-parachains-consensus-overview.md): Understand how the blocks authored by parachain collators are secured by the relay chain validators and how the parachain transactions achieve finality. -- [Cryptography](https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/reference-parachains-cryptography.md): A concise guide to cryptography in blockchain, covering hash functions, encryption types, digital signatures, and elliptic curve applications. -- [Data Encoding](https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/reference-parachains-data-encoding.md): SCALE codec enables fast, efficient data encoding, ideal for resource-constrained environments like Wasm, supporting custom types and compact encoding. -- [Interoperability](https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/reference-parachains-interoperability.md): Explore the importance of interoperability in the Polkadot ecosystem, covering XCM, bridges, and cross-chain communication. -- [Networks](https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/reference-parachains-networks.md): Explore Polkadot's testing and production networks, including Westend, Kusama, and Paseo, for efficient development, deployment, and testing. -- [Node and Runtime](https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/reference-parachains-node-and-runtime.md): Learn how Polkadot SDK-based nodes function, how the client and runtime are separated, and how they communicate using SCALE-encoded data. -- [Randomness](https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/reference-parachains-randomness.md): Explore the importance of randomness in PoS blockchains, focusing on Polkadot’s VRF-based approach to ensure fairness and security in validator selection. -- [Asset Hub](https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/reference-polkadot-hub-assets-and-smart-contracts.md): Learn about Asset Hub in Polkadot, managing on-chain assets, foreign asset integration, and using XCM for cross-chain asset transfers. -- [Bridge Hub](https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/reference-polkadot-hub-bridging.md): Learn about the Bridge Hub system parachain, a parachain that facilitates the interactions from Polkadot to the rest of Web3. -- [Collectives Chain](https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/reference-polkadot-hub-collectives-and-daos.md): Learn how the Collectives chain provides infrastructure for governance organizations, enabling decentralized network stewardship and decision-making. -- [Agile Coretime](https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/reference-polkadot-hub-consensus-and-security-agile-coretime.md): Explore the efficient scheduling mechanisms to access Polkadot cores to produce blockspace continuously or on-demand. -- [Proof of Stake Consensus](https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/reference-polkadot-hub-consensus-and-security-pos-consensus.md): Explore Polkadot's consensus protocols for secure, scalable, and decentralized network operation, including NPoS, BABE, GRANDPA, and BEEFY. -- [Overview of the Polkadot Relay Chain](https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/reference-polkadot-hub-consensus-and-security-relay-chain.md): Explore Polkadot's core architecture, including its multi-chain vision, shared security, and the DOT token's governance and staking roles. -- [People Chain](https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/reference-polkadot-hub-people-and-identity.md): Learn how People chain secures decentralized identity management, empowering users to control and verify digital identities without central authorities. -- [Technical Reference Overview](https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/reference.md): Learn about Polkadot's technical architecture, governance framework, parachain ecosystem, and the tools you need to build and interact with the network. - [Accounts in Asset Hub Smart Contracts](https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/smart-contracts-for-eth-devs-accounts.md): Bridges Ethereum's 20-byte addresses with Polkadot's 32-byte accounts, enabling seamless interaction while maintaining compatibility with Ethereum tooling. - [Transactions and Fees on Asset Hub](https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/smart-contracts-for-eth-devs-blocks-transactions-fees.md): Explore how Asset Hub smart contracts handle blocks, transactions, and fees with EVM compatibility, supporting various Ethereum transaction types. - [Dual Virtual Machine Stack](https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/smart-contracts-for-eth-devs-dual-vm-stack.md): Compare Polkadot’s dual smart contract VMs—REVM for EVM compatibility and PolkaVM for RISC-V performance, flexibility, and efficiency. Docs: Infrastructure -- [Set Up a Bootnode](https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/nodes-and-validators-run-a-node-bootnode.md): Learn how to configure and run a bootnode for Polkadot, including P2P, WS, and secure WSS connections with network key management and proxies. -- [Set Up a Node](https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/nodes-and-validators-run-a-node-full-node.md): Learn how to install, configure, and run Polkadot nodes, including setting up different node types and connecting to the network. -- [Set Up Secure WebSocket](https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/nodes-and-validators-run-a-node-secure-wss.md): Instructions on enabling SSL for your node and setting up a secure WebSocket proxy server using nginx for remote connections. -- [Validator Key Management](https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/nodes-and-validators-run-a-validator-onboarding-and-offboarding-key-management.md): Learn how to generate and manage validator keys, including session keys for consensus participation and node keys for maintaining a stable network identity. -- [Set Up a Validator](https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/nodes-and-validators-run-a-validator-onboarding-and-offboarding-set-up-validator.md): Set up a Polkadot validator node to secure the network and earn staking rewards. Follow this step-by-step guide to install, configure, and manage your node. -- [Start Validating](https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/nodes-and-validators-run-a-validator-onboarding-and-offboarding-start-validating.md): Learn how to start validating on Polkadot by choosing a network, syncing your node, bonding DOT tokens, and activating your validator. -- [Stop Validating](https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/nodes-and-validators-run-a-validator-onboarding-and-offboarding-stop-validating.md): Learn to safely stop validating on Polkadot, including chilling, unbonding tokens, and purging validator keys. -- [General Management](https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/nodes-and-validators-run-a-validator-operational-tasks-general-management.md): Optimize your Polkadot validator setup with advanced configuration techniques. Learn how to boost performance, enhance security, and ensure seamless operations. -- [Pause Validating](https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/nodes-and-validators-run-a-validator-operational-tasks-pause-validating.md): Learn how to temporarily pause staking activity in Polkadot using the chill extrinsic, with guidance for validators and nominators. -- [Upgrade a Validator Node](https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/nodes-and-validators-run-a-validator-operational-tasks-upgrade-your-node.md): Guide to seamlessly upgrading your Polkadot validator node, managing session keys, and executing server maintenance while avoiding downtime and slashing risks. -- [Validator Requirements](https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/nodes-and-validators-run-a-validator-requirements.md): Explore the technical and system requirements for running a Polkadot validator, including setup, hardware, staking prerequisites, and security best practices. -- [Offenses and Slashes](https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/nodes-and-validators-run-a-validator-staking-mechanics-offenses-and-slashes.md): Learn about how Polkadot discourages validator misconduct via an offenses and slashing system, including details on offenses and their consequences. -- [Rewards Payout](https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/nodes-and-validators-run-a-validator-staking-mechanics-rewards.md): Learn how validator rewards work on the network, including era points, payout distribution, running multiple validators, and nominator payments. +- [Set Up a Bootnode](https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/node-infrastructure-run-a-node-bootnode.md): Learn how to configure and run a bootnode for Polkadot, including P2P, WS, and secure WSS connections with network key management and proxies. +- [Set Up a Node](https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/node-infrastructure-run-a-node-full-node.md): Learn how to install, configure, and run Polkadot nodes, including setting up different node types and connecting to the network. +- [Set Up Secure WebSocket](https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/node-infrastructure-run-a-node-secure-wss.md): Instructions on enabling SSL for your node and setting up a secure WebSocket proxy server using nginx for remote connections. +- [Validator Key Management](https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/node-infrastructure-run-a-validator-onboarding-and-offboarding-key-management.md): Learn how to generate and manage validator keys, including session keys for consensus participation and node keys for maintaining a stable network identity. +- [Set Up a Validator](https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/node-infrastructure-run-a-validator-onboarding-and-offboarding-set-up-validator.md): Set up a Polkadot validator node to secure the network and earn staking rewards. Follow this step-by-step guide to install, configure, and manage your node. +- [Start Validating](https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/node-infrastructure-run-a-validator-onboarding-and-offboarding-start-validating.md): Learn how to start validating on Polkadot by choosing a network, syncing your node, bonding DOT tokens, and activating your validator. +- [Stop Validating](https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/node-infrastructure-run-a-validator-onboarding-and-offboarding-stop-validating.md): Learn to safely stop validating on Polkadot, including chilling, unbonding tokens, and purging validator keys. +- [General Management](https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/node-infrastructure-run-a-validator-operational-tasks-general-management.md): Optimize your Polkadot validator setup with advanced configuration techniques. Learn how to boost performance, enhance security, and ensure seamless operations. +- [Pause Validating](https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/node-infrastructure-run-a-validator-operational-tasks-pause-validating.md): Learn how to temporarily pause staking activity in Polkadot using the chill extrinsic, with guidance for validators and nominators. +- [Upgrade a Validator Node](https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/node-infrastructure-run-a-validator-operational-tasks-upgrade-your-node.md): Guide to seamlessly upgrading your Polkadot validator node, managing session keys, and executing server maintenance while avoiding downtime and slashing risks. +- [Validator Requirements](https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/node-infrastructure-run-a-validator-requirements.md): Explore the technical and system requirements for running a Polkadot validator, including setup, hardware, staking prerequisites, and security best practices. +- [Offenses and Slashes](https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/node-infrastructure-run-a-validator-staking-mechanics-offenses-and-slashes.md): Learn about how Polkadot discourages validator misconduct via an offenses and slashing system, including details on offenses and their consequences. +- [Rewards Payout](https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/node-infrastructure-run-a-validator-staking-mechanics-rewards.md): Learn how validator rewards work on the network, including era points, payout distribution, running multiple validators, and nominator payments. Docs: Tooling - [Install Polkadot SDK](https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/parachains-install-polkadot-sdk.md): Install all required Polkadot SDK dependencies, set up the SDK itself, and verify that it runs correctly on your machine. @@ -146,17 +114,6 @@ Docs: Tooling - [Wallets](https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/parachains-integrations-wallets.md): Explore blockchain wallets. Securely manage digital assets with hot wallets for online access or cold wallets for offline, enhanced security. - [Fork a Parachain Using Chopsticks](https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/parachains-testing-fork-a-parachain.md): Simplify Polkadot SDK development with Chopsticks. Learn essential features, how to install Chopsticks, and how to configure local blockchain forks. - [Run a Parachain Network](https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/parachains-testing-run-a-parachain-network.md): Quickly install and configure Zombienet to deploy and test Polkadot-based blockchain networks with this comprehensive getting-started guide. -- [Dedot](https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/reference-tools-dedot.md): Dedot is a next-gen JavaScript client for Polkadot and Polkadot SDK-based blockchains, offering lightweight, tree-shakable APIs with strong TypeScript support. -- [Light Clients](https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/reference-tools-light-clients.md): Light clients enable secure and efficient blockchain interaction without running a full node. Learn everything you need to know about light clients on Polkadot. -- [E2E Testing with Moonwall](https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/reference-tools-moonwall.md): Enhance blockchain end-to-end testing with Moonwall's standardized environment setup, comprehensive configuration management, and simple network interactions. -- [Polkadot Omni Node](https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/reference-tools-omninode.md): Run parachain nodes easily with the polkadot-omni-node, a white-labeled binary that can run parachain nodes using a single pre-built solution. -- [Polkadot-API](https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/reference-tools-papi.md): Polkadot-API (PAPI) is a modular, composable library set designed for efficient interaction with Polkadot chains, prioritizing a "light-client first" approach. -- [Polkadart](https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/reference-tools-polkadart.md): Polkadart is a type-safe, native Dart, SDK for Polkadot and any compatible Polkadot-SDK blockchain network. -- [Polkadot.js API](https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/reference-tools-polkadot-js-api.md): Interact with Polkadot SDK-based chains easily using the Polkadot.js API. Query chain data, submit transactions, and more via JavaScript or Typescript. -- [Python Substrate Interface](https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/reference-tools-py-substrate-interface.md): Learn how to connect to Polkadot SDK-based nodes, query data, submit transactions, and manage blockchain interactions using the Python Substrate Interface. -- [Sidecar REST API](https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/reference-tools-sidecar.md): Learn about Substrate API Sidecar, a REST service that provides endpoints for interacting with Polkadot SDK-based chains and simplifies blockchain interactions. -- [Subxt Rust API](https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/reference-tools-subxt.md): Subxt is a Rust library for type-safe interaction with Polkadot SDK blockchains, enabling transactions, state queries, runtime API access, and more. -- [XCM Tools](https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/reference-tools-xcm-tools.md): Explore essential XCM tools across Polkadot, crafted to enhance cross-chain functionality and integration within the ecosystem. - [Zero to Hero Smart Contract DApp](https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/smart-contracts-cookbook-dapps-zero-to-hero.md): Learn how to build a decentralized application on Polkadot Hub using Viem and Next.js by creating a simple dApp that interacts with a smart contract. - [Deploying Uniswap V2 on Polkadot](https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/smart-contracts-cookbook-eth-dapps-uniswap-v2.md): Learn how to deploy and test Uniswap V2 on Polkadot Hub using Hardhat, bringing AMM-based token swaps to the Polkadot ecosystem. - [Use Hardhat with Polkadot Hub](https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/smart-contracts-dev-environments-hardhat.md): Learn how to create, compile, test, and deploy smart contracts on Polkadot Hub using Hardhat, a powerful development environment for blockchain developers. @@ -170,22 +127,12 @@ Docs: Tooling - [Web3.py](https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/smart-contracts-libraries-web3-py.md): Learn how to interact with Polkadot Hub using the Web3 python library, deploying Solidity contracts, and interacting with deployed smart contracts. Docs: Reference -- [Glossary](https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/reference-glossary.md): Glossary of terms used within the Polkadot ecosystem, Polkadot SDK, its subsequent libraries, and other relevant Web3 terminology. -- [Technical Reference Overview](https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/reference.md): Learn about Polkadot's technical architecture, governance framework, parachain ecosystem, and the tools you need to build and interact with the network. - [JSON-RPC APIs](https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/smart-contracts-for-eth-devs-json-rpc-apis.md): JSON-RPC APIs guide for Polkadot Hub, covering supported methods, parameters, and examples for interacting with the chain. Docs: Dapps - [Indexers](https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/parachains-integrations-indexers.md): Discover blockchain indexers. Enhance data access, enable fast and complex queries, and optimize blockchain data for seamless app performance. - [Oracles](https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/parachains-integrations-oracles.md): Learn about blockchain oracles, the essential bridges connecting blockchains with real-world data for decentralized applications in the Polkadot ecosystem. - [Wallets](https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/parachains-integrations-wallets.md): Explore blockchain wallets. Securely manage digital assets with hot wallets for online access or cold wallets for offline, enhanced security. -- [Dedot](https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/reference-tools-dedot.md): Dedot is a next-gen JavaScript client for Polkadot and Polkadot SDK-based blockchains, offering lightweight, tree-shakable APIs with strong TypeScript support. -- [Polkadot-API](https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/reference-tools-papi.md): Polkadot-API (PAPI) is a modular, composable library set designed for efficient interaction with Polkadot chains, prioritizing a "light-client first" approach. -- [Polkadart](https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/reference-tools-polkadart.md): Polkadart is a type-safe, native Dart, SDK for Polkadot and any compatible Polkadot-SDK blockchain network. -- [Polkadot.js API](https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/reference-tools-polkadot-js-api.md): Interact with Polkadot SDK-based chains easily using the Polkadot.js API. Query chain data, submit transactions, and more via JavaScript or Typescript. -- [Python Substrate Interface](https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/reference-tools-py-substrate-interface.md): Learn how to connect to Polkadot SDK-based nodes, query data, submit transactions, and manage blockchain interactions using the Python Substrate Interface. -- [Sidecar REST API](https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/reference-tools-sidecar.md): Learn about Substrate API Sidecar, a REST service that provides endpoints for interacting with Polkadot SDK-based chains and simplifies blockchain interactions. -- [Subxt Rust API](https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/reference-tools-subxt.md): Subxt is a Rust library for type-safe interaction with Polkadot SDK blockchains, enabling transactions, state queries, runtime API access, and more. -- [XCM Tools](https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/reference-tools-xcm-tools.md): Explore essential XCM tools across Polkadot, crafted to enhance cross-chain functionality and integration within the ecosystem. Docs: Uncategorized - [AI Ready Docs](https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/get-support-ai-ready-docs.md): Download LLM-optimized files of the Polkadot documentation, including full content and category-specific resources for AI agents. diff --git a/node-infrastructure/.nav.yml b/node-infrastructure/.nav.yml index d907a96bb..efa0cc257 100644 --- a/node-infrastructure/.nav.yml +++ b/node-infrastructure/.nav.yml @@ -1,5 +1,5 @@ nav: - - 'Overview': overview.md + - 'Overview': index.md - 'Run a Node': run-a-node - - 'Run a Collator': run-a-collator + - 'Run a Collator': run-a-collator.md - 'Run a Validator': run-a-validator diff --git a/node-infrastructure/overview.md b/node-infrastructure/index.md similarity index 69% rename from node-infrastructure/overview.md rename to node-infrastructure/index.md index 4b06c00ee..c6203466f 100644 --- a/node-infrastructure/overview.md +++ b/node-infrastructure/index.md @@ -1,6 +1,6 @@ --- title: Node Infrastructure -description: Overview of running nodes in the Polkadot ecosystem, including RPC nodes, collators, and validators. +description: From running RPC endpoints to producing parachain blocks or validating the relay chain, this guide explains your options and how to begin. categories: Infrastructure --- @@ -18,14 +18,14 @@ Whether you want to provide RPC endpoints for applications, produce blocks for a RPC nodes provide API access to blockchain data without participating in consensus. They are essential infrastructure for: -- **Applications and dApps**: Query blockchain state and submit transactions -- **Block explorers**: Index and display blockchain data -- **Wallets**: Check balances and broadcast transactions -- **Development**: Test and debug applications +- **Applications and dApps**: Query blockchain state and submit transactions. +- **Block explorers**: Index and display blockchain data. +- **Wallets**: Check balances and broadcast transactions. +- **Development**: Test and debug applications. RPC nodes can be run for both the relay chain and parachains, with varying levels of data retention: -- **Pruned Nodes**: Keep recent state and a limited number of finalized blocks. Suitable for most applications that only need current state and recent history. More efficient in terms of storage and sync time. +- **Pruned Nodes**: Keep recent state and a limited number of finalized blocks. Suitable for most applications that only need the current state and recent history. More efficient in terms of storage and sync time. - **Archive Nodes**: Maintain complete historical state and all blocks since genesis. Required for block explorers, analytics platforms, or applications that need to query historical data at any point in time. **Transaction Broadcasting**: RPC nodes play a crucial role in transaction submission and propagation. When a client submits a transaction via RPC methods like `author_submitExtrinsic`, the node validates the transaction format, adds it to its local transaction pool, and broadcasts it across the P2P network. Block producers (collators or validators) then pick up these transactions from their pools for inclusion in blocks. This makes RPC nodes the primary gateway for users and applications to interact with the blockchain. @@ -34,51 +34,49 @@ RPC nodes can be run for both the relay chain and parachains, with varying level Collators are block producers for parachains. They perform critical functions: -- **Collect transactions**: Aggregate user transactions into blocks -- **Produce blocks**: Create parachain block candidates -- **Generate and package PoV**: Generate the Proof-of-Validity containing the state transition proof and necessary witness data for validation -- **Submit to validators**: Send block candidates and PoVs to relay chain validators +- **Collect transactions**: Aggregate user transactions into blocks. +- **Produce blocks**: Create parachain block candidates. +- **Generate and package PoV**: Generate the Proof-of-Validity containing the state transition proof and necessary witness data for validation. +- **Submit to validators**: Send block candidates and PoVs to relay chain validators. -Unlike validators, collators do not provide security guarantees—that responsibility lies with relay chain validators. However, collators are essential for parachain liveness and censorship resistance. +Unlike validators, collators do not provide security guarantees—that responsibility lies with the relay chain validators. However, collators are essential for parachain liveness and censorship resistance. ### Validators Validators secure the Polkadot relay chain through [Nominated Proof of Stake (NPoS)](https://wiki.polkadot.network/docs/learn-staking){target=\_blank}. They: -- **Validate blocks**: Verify parachain blocks and relay chain transactions -- **Participate in consensus**: Run [BABE](https://wiki.polkadot.network/docs/learn-consensus#babe-block-production){target=\_blank} and [GRANDPA](https://wiki.polkadot.network/docs/learn-consensus#grandpa-finality-gadget){target=\_blank} protocols -- **Earn rewards**: Receive staking rewards for honest behavior -- **Risk slashing**: Face penalties for misbehavior or downtime +- **Validate blocks**: Verify parachain blocks and relay chain transactions. +- **Participate in consensus**: Run [BABE](https://wiki.polkadot.network/docs/learn-consensus#babe-block-production){target=\_blank} and [GRANDPA](https://wiki.polkadot.network/docs/learn-consensus#grandpa-finality-gadget){target=\_blank} protocols. +- **Earn rewards**: Receive staking rewards for honest behavior. +- **Risk slashing**: Face penalties for misbehavior or downtime. Running a validator requires significant technical expertise, reliable infrastructure, and a stake of DOT tokens. ## Next Steps -Choose your path based on your goals: -
-- :material-api:{ .lg .middle } **Run RPC Nodes** +- **Run RPC Nodes** --- - Provide API access for applications, explorers, and wallets + Provide API access for applications, explorers, and wallets. - [:octicons-arrow-right-24: Run a Node](/node-infrastructure/run-a-node/parachain-rpc/) + [:octicons-arrow-right-24: Run a Node](/node-infrastructure/run-a-node/polkadot-hub-rpc/) -- :material-cube-outline:{ .lg .middle } **Run a Collator** +- **Run a Collator** --- - Produce blocks for system parachains or your own parachain + Produce blocks for system parachains or your own parachain. [:octicons-arrow-right-24: Run a Collator](/node-infrastructure/run-a-collator/collator/) -- :material-shield-check:{ .lg .middle } **Run a Validator** +- **Run a Validator** --- - Secure the relay chain and earn staking rewards + Secure the relay chain and earn staking rewards. [:octicons-arrow-right-24: Run a Validator](/node-infrastructure/run-a-validator/requirements/) diff --git a/node-infrastructure/run-a-collator/collator.md b/node-infrastructure/run-a-collator.md similarity index 94% rename from node-infrastructure/run-a-collator/collator.md rename to node-infrastructure/run-a-collator.md index 65e53571b..bd9f2103c 100644 --- a/node-infrastructure/run-a-collator/collator.md +++ b/node-infrastructure/run-a-collator.md @@ -6,24 +6,17 @@ categories: Infrastructure # Run a Block-Producing Collator -## Overview +## Introduction -Block-producing collators are the backbone of system parachain operations. Unlike RPC or archive nodes, which maintain state, collators actively produce blocks and submit them to relay chain validators for inclusion. +Block-producing collators are the backbone of system parachain operations. Unlike RPC or archive nodes, which maintain state, collators actively produce blocks and submit them to relay chain validators for inclusion. They ensure network liveness, censorship resistance, and cross-chain message processing. -This guide covers setting up a block-producing collator for Polkadot system parachains. Running a collator requires: - -- Meeting hardware requirements for reliable block production -- Setting up and registering session keys -- Obtaining governance approval or meeting selection criteria -- Maintaining high uptime and performance - -System parachain collators typically require governance approval or being added to the invulnerables list. This is different from non-system parachains where collator selection may be more permissionless. +This guide explains how to set up a block-producing collator for Polkadot system parachains, covering all key requirements, setting up and registering session keys, and meeting governance approval or invulnerables-list criteria (required for system parachains, non-system parachains may be more permissionless). ## Collator Responsibilities Block-producing collators perform critical functions: -- Maintain full nodes for relay chain and parachain. +- Maintain full nodes for relay chain and parachain with high uptime and performance. - Aggregate user transactions into blocks. - Create parachain block candidates. - Produce state transition proofs (Proof-of-Validity). @@ -51,16 +44,15 @@ Block-producing collators require robust hardware for reliable operation includi - 30333 (parachain P2P) - 30334 (relay chain P2P) -Uptime is critical. Consider redundancy and monitoring to maintain block production reliability. +!!! warning "Uptime is critical" + Consider redundancy and monitoring to maintain block production reliability. ### Software Requirements -Collators use the Polkadot Parachain binary, the standard client for running Polkadot system parachains. +Required software: -Required software includes the following: - -- **Operating System**: Ubuntu 22.04 LTS (recommended) or similar Linux distribution -- **Docker**: Required for obtaining binaries and running containers +- **Operating system**: Ubuntu 22.04 LTS (recommended) or similar Linux distribution +- **[Docker](https://www.docker.com/get-started/){target=\_blank}**: Required for obtaining binaries and running containers ### Account Requirements @@ -74,10 +66,10 @@ Your account must meet the following requirements: This guide provides two deployment options. Select the option that best fits your needs: -- **Docker-based Setup**: Best for simpler setup and maintenance -- **Manual/systemd Setup**: Best for production environments requiring more control +- **Docker**: Best for simpler setup and maintenance +- **systemd**: Best for production environments requiring more control -=== "Docker Setup" +=== "Docker" Pull the Polkadot Parachain Docker image: diff --git a/node-infrastructure/run-a-collator/.nav.yml b/node-infrastructure/run-a-collator/.nav.yml deleted file mode 100644 index a18175837..000000000 --- a/node-infrastructure/run-a-collator/.nav.yml +++ /dev/null @@ -1,2 +0,0 @@ -nav: - - 'Run a Block-Producing Collator': collator.md diff --git a/node-infrastructure/run-a-node/parachain-rpc.md b/node-infrastructure/run-a-node/parachain-rpc.md index 38d6e7168..40cba6536 100644 --- a/node-infrastructure/run-a-node/parachain-rpc.md +++ b/node-infrastructure/run-a-node/parachain-rpc.md @@ -1,55 +1,16 @@ --- title: Run a Parachain RPC Node -description: Complete guide to set up and run an RPC node for any Polkadot parachain, with system parachains as examples. +description: Follow this guide to understand hardware and software requirements and how to set up and run an RPC node for any parachain, including system parachains. categories: Infrastructure --- # Run a Parachain RPC Node -## Overview +## Introduction -Running an RPC node for a parachain enables applications, wallets, and users to interact with the parachain's functionality. +A parachain RPC node provides direct access to a specific parachain on the Polkadot network, enabling developers and applications to interact with its assets, governance, cross-chain messages, and more. Running your own node also supports essential infrastructure tasks, such as block indexing and compatibility with Polkadot SDK tools. -Each parachain RPC node provides access through the Polkadot SDK Node RPC (Port 9944), offering native Polkadot API access via WebSocket and HTTP. This setup enables block explorer indexing and provides full compatibility with Polkadot SDK development tools. - -!!! note - - The parameters and configurations in this guide are provided as illustrative examples. You may need to modify them according to your specific environment, hardware capabilities, and network conditions. - -## Obtaining a Chain Specification - -To run an RPC node for any parachain, you need its **chain specification file**. This JSON file defines the network parameters, genesis state, and bootnodes. - -### System Parachains - -System parachain chain specs are available from multiple sources: - -**Option 1: Chainspec Collection (Recommended)** - -Visit the [Chainspec Collection](https://paritytech.github.io/chainspecs/) to download official chain specifications. - -**Option 2: Polkadot SDK Repository** - -Download directly from the Polkadot SDK repository: - -```bash -# Example for People Chain -curl -L https://raw.githubusercontent.com/paritytech/polkadot-sdk/master/cumulus/parachains/chain-specs/people-polkadot.json -o chain-spec.json -``` - -| System Parachain | Para ID | Chain Spec File | Snapshot Path | -|------------------|---------|-----------------|---------------| -| **Bridge Hub** | 1002 | `bridge-hub-polkadot.json` | `polkadot-bridge-hub-rocksdb-archive` | -| **People Chain** | 1004 | `people-polkadot.json` | `polkadot-people-rocksdb-archive` | -| **Coretime Chain** | 1005 | `coretime-polkadot.json` | `polkadot-coretime-rocksdb-archive` | - -### Other Parachains - -For non-system parachains, check the parachain's documentation for official chain specification files. - -!!! note - - Throughout this guide, we use **People Chain** as the example. To set up a different parachain, substitute the chain spec file, snapshot path, and chain name with values for your target parachain. +Through the parachain RPC (WebSocket port 9944, HTTP port 9933), your node acts as the bridge between the parachain and applications. This page walks through setting up a node from scratch, covering hardware requirements and deployment options using Docker or systemd. ## Prerequisites @@ -75,138 +36,126 @@ RPC nodes serving production traffic require robust hardware: - Consider DDoS protection and rate limiting for production deployments !!! note - - For development or low-traffic scenarios, you can reduce these requirements proportionally. Consider using a reverse proxy (nginx, Caddy) for production deployments. + For development or low-traffic scenarios, you can reduce these requirements proportionally. Consider using a reverse proxy ([nginx](https://nginx.org/){target=\_blank}, [Caddy](https://caddyserver.com/){target=\_blank}) for production deployments. ### Software Requirements Required software: -- **Operating System**: Ubuntu 22.04 LTS (recommended) or similar Linux distribution -- **Docker**: Required for obtaining binaries and running containers -- **rclone**: (Optional but recommended) Command-line program for managing files on cloud storage (https://rclone.org/downloads/) +- **Operating system**: Ubuntu 22.04 LTS (recommended) or similar Linux distribution +- **[Docker](https://www.docker.com/get-started/){target=\_blank}**: Required for obtaining binaries and running containers +- **[rclone](https://rclone.org/downloads/){target=\_blank}**: (Optional but recommended) Command-line program for managing files on cloud storage + +## Obtain the Chain Specification + +To run an RPC node for a parachain, you need its chain specification file. This JSON file defines the network parameters, genesis state, and bootnodes. The process for obtaining the chain spec may differ depending on whether you’re running a system parachain or a regular parachain. + +### System Parachains + +System parachain chain specs are available from multiple sources: + +- **[Chainspec Collection](https://paritytech.github.io/chainspecs/)**: (Recommended) Choose a file to download from the **List of Chainspecs** section. +- **[Polkadot SDK repository](https://github.com/paritytech/polkadot-sdk){target=\_blank}**: Download directly from the Polkadot SDK repository: + + ```bash + # Example for People Chain + curl -L https://raw.githubusercontent.com/paritytech/polkadot-sdk/master/cumulus/parachains/chain-specs/people-polkadot.json -o chain-spec.json + ``` + +### Other Parachains + +For non-system parachains, check the parachain's documentation for official chain specification files. -## Setup Options +## Spin Up a Node -This guide provides two options for deployment: +Choose the deployment option that fits your project, and follow the steps in the appropriate tab to complete setup: -- **Docker-based Setup**: Best for simpler set up and maintenance -- **Manual/systemd Setup**: Best for production environments requiring more control +- **Docker**: Best for simpler set up and maintenance +- **systemd**: Best for production environments requiring more control -Select the best option for your project, then use the steps in the following tabs to complete set up. +This guide uses **People Chain** as an example. To set up a different parachain, replace the chain spec file, snapshot path, and chain name with the corresponding values for your target parachain. -=== "Docker-Based Setup" +System parachain details: - This option uses Docker containers for the Polkadot SDK node, making it easy to set up and manage. Follow these steps to set your RPC node using Docker: +| System Parachain | Para ID | Chain Spec File | Snapshot Path | +|--------------------|---------|----------------------------|---------------------------------------| +| **Bridge Hub** | 1002 | `bridge-hub-polkadot.json` | `polkadot-bridge-hub-rocksdb-archive` | +| **People Chain** | 1004 | `people-polkadot.json` | `polkadot-people-rocksdb-archive` | +| **Coretime Chain** | 1005 | `coretime-polkadot.json` | `polkadot-coretime-rocksdb-archive` | - 1. Download your parachain's chain specification as described in [Obtaining a Chain Specification](#obtaining-a-chain-specification). +=== "Docker" - 2. (Optional but recommended) Download database snapshots: - - Using pre-synchronized snapshots significantly reduces initial sync time from several days to just a few hours. You need to download both parachain and relay chain data. - - You can obtain the latest snapshot from the [Snapshot Provider](https://snapshots.polkadot.io/){target=\_blank}. Follow these steps to download and use snapshots: + 1. Download your parachain's chain specification as described in [Obtain the Chain Specification](#obtain-the-chain-specification). - !!! note + 2. (Optional but recommended) Download pre-synced snapshots from the [Snapshot Provider](https://snapshots.polkadot.io/){target=\_blank} to cut initial sync time from days to hours: - Snapshots are available for system parachains and the Polkadot relay chain. For other parachains, check with the parachain team for snapshot availability or sync from genesis. + !!! note + Snapshots are available for system parachains and the Polkadot relay chain. For other parachains, check with the parachain team for snapshot availability or sync from genesis. + + 1. Create new directories: + + ```bash + mkdir -p my-node-data/chains/people-polkadot/db + mkdir -p my-node-data/chains/polkadot/db + ``` + + 2. Choose between archive (complete history; ~400 GB) or pruned (recent state; TODO: ERIN) snapshots of the parachain and set the snapshot URL accordingly: + + === "Archive" - 1. Create new directories with the following commands: ```bash - mkdir -p my-node-data/chains/people-polkadot/db - mkdir -p my-node-data/chains/polkadot/db + # Check https://snapshots.polkadot.io/ for the latest snapshot URL + export SNAPSHOT_URL_PARACHAIN="https://snapshots.polkadot.io/polkadot-people-rocksdb-archive/INSERT_LATEST" ``` - 2. Download the appropriate snapshots using the following commands: - - === "Archive Node" - - Archive node setup maintains complete parachain history. Download both parachain archive and relay chain pruned snapshots: - - **Parachain archive snapshot** (People Chain example): - ```bash - # Check https://snapshots.polkadot.io/ for the latest snapshot URL - export SNAPSHOT_URL_PARACHAIN="https://snapshots.polkadot.io/polkadot-people-rocksdb-archive/LATEST" - - rclone copyurl $SNAPSHOT_URL_PARACHAIN/files.txt files.txt - rclone copy --progress --transfers 20 \ - --http-url $SNAPSHOT_URL_PARACHAIN \ - --no-traverse --http-no-head --disable-http2 \ - --inplace --no-gzip-encoding --size-only \ - --retries 6 --retries-sleep 10s \ - --files-from files.txt :http: my-node-data/chains/people-polkadot/db/ - - rm files.txt - ``` - - **Relay chain pruned snapshot** (~200 GB): - ```bash - # Check https://snapshots.polkadot.io/ for the latest snapshot URL - export SNAPSHOT_URL_RELAY="https://snapshots.polkadot.io/polkadot-rocksdb-prune/LATEST" - - rclone copyurl $SNAPSHOT_URL_RELAY/files.txt files.txt - rclone copy --progress --transfers 20 \ - --http-url $SNAPSHOT_URL_RELAY \ - --no-traverse --http-no-head --disable-http2 \ - --inplace --no-gzip-encoding --size-only \ - --retries 6 --retries-sleep 10s \ - --files-from files.txt :http: my-node-data/chains/polkadot/db/ - - rm files.txt - ``` - - **rclone parameters:** - - - `--transfers 20`: Uses 20 parallel transfers for faster download - - `--retries 6`: Automatically retries failed transfers up to 6 times - - `--retries-sleep 10s`: Waits 10 seconds between retry attempts - - `--size-only`: Only transfers if sizes differ (prevents unnecessary re-downloads) - - === "Pruned Node" - - Pruned node setup keeps recent state for smaller storage. Download both parachain pruned and relay chain pruned snapshots: - - **Parachain pruned snapshot** (People Chain example): - ```bash - # Check https://snapshots.polkadot.io/ for the latest snapshot URL - export SNAPSHOT_URL_PARACHAIN="https://snapshots.polkadot.io/polkadot-people-rocksdb-prune/LATEST" - - rclone copyurl $SNAPSHOT_URL_PARACHAIN/files.txt files.txt - rclone copy --progress --transfers 20 \ - --http-url $SNAPSHOT_URL_PARACHAIN \ - --no-traverse --http-no-head --disable-http2 \ - --inplace --no-gzip-encoding --size-only \ - --retries 6 --retries-sleep 10s \ - --files-from files.txt :http: my-node-data/chains/people-polkadot/db/ - - rm files.txt - ``` - - **Relay chain pruned snapshot** (~200 GB): - ```bash - # Check https://snapshots.polkadot.io/ for the latest snapshot URL - export SNAPSHOT_URL_RELAY="https://snapshots.polkadot.io/polkadot-rocksdb-prune/LATEST" - - rclone copyurl $SNAPSHOT_URL_RELAY/files.txt files.txt - rclone copy --progress --transfers 20 \ - --http-url $SNAPSHOT_URL_RELAY \ - --no-traverse --http-no-head --disable-http2 \ - --inplace --no-gzip-encoding --size-only \ - --retries 6 --retries-sleep 10s \ - --files-from files.txt :http: my-node-data/chains/polkadot/db/ - - rm files.txt - ``` - - **rclone parameters:** - - - `--transfers 20`: Uses 20 parallel transfers for faster download - - `--retries 6`: Automatically retries failed transfers up to 6 times - - `--retries-sleep 10s`: Waits 10 seconds between retry attempts - - `--size-only`: Only transfers if sizes differ (prevents unnecessary re-downloads) - 3. Launch the parachain node using the official [Parity Docker image](https://hub.docker.com/r/parity/polkadot-parachain){target=\_blank}: + === "Pruned" - === "Archive Node" + ```bash + # Check https://snapshots.polkadot.io/ for the latest snapshot URL + export SNAPSHOT_URL_PARACHAIN="https://snapshots.polkadot.io/polkadot-people-rocksdb-prune/INSERT_LATEST" + ``` + + 3. Use `rclone` to download and save the parachain snapshots: + + ```bash + rclone copyurl $SNAPSHOT_URL_PARACHAIN/files.txt files.txt + rclone copy --progress --transfers 20 \ + --http-url $SNAPSHOT_URL_PARACHAIN \ + --no-traverse --http-no-head --disable-http2 \ + --inplace --no-gzip-encoding --size-only \ + --retries 6 --retries-sleep 10s \ + --files-from files.txt :http: my-node-data/chains/people-polkadot/db/ + + rm files.txt + ``` - Archive node configuration maintains complete parachain history for historical queries: + ??? interface "rclone parameters" + + - **`--transfers 20`**: Uses 20 parallel transfers for faster download + - **`--retries 6`**: Automatically retries failed transfers up to 6 times + - **`--retries-sleep 10s`**: Waits 10 seconds between retry attempts + - **`--size-only`**: Only transfers if sizes differ (prevents unnecessary re-downloads) + + 4. Repeat the process with the pruned relay chain snapshot (~200 GB): + + ```bash + # Check https://snapshots.polkadot.io/ for the latest snapshot URL + export SNAPSHOT_URL_RELAY="https://snapshots.polkadot.io/polkadot-rocksdb-prune/INSERT_LATEST" + + rclone copyurl $SNAPSHOT_URL_RELAY/files.txt files.txt + rclone copy --progress --transfers 20 \ + --http-url $SNAPSHOT_URL_RELAY \ + --no-traverse --http-no-head --disable-http2 \ + --inplace --no-gzip-encoding --size-only \ + --retries 6 --retries-sleep 10s \ + --files-from files.txt :http: my-node-data/chains/polkadot/db/ + + rm files.txt + ``` + + 3. Launch the parachain node using the official [Parity Docker image](https://hub.docker.com/r/parity/polkadot-parachain){target=\_blank}: + + === "Archive" ```bash docker run -d --name people-chain-rpc --restart unless-stopped \ @@ -238,9 +187,7 @@ Select the best option for your project, then use the steps in the following tab --rpc-port=0 ``` - === "Pruned Node" - - Pruned node configuration keeps recent state for smaller storage requirements: + === "Pruned" ```bash docker run -d --name people-chain-rpc --restart unless-stopped \ @@ -273,99 +220,14 @@ Select the best option for your project, then use the steps in the following tab ``` !!! note - The `parity/polkadot-parachain` image works for system parachains and parachains built with standard Cumulus templates. For parachains with custom runtimes, check the parachain's documentation for their specific Docker image or binary. - Critical configuration parameters include port mappings and node parameters: - - === "Port mappings" - - - `9944`: Polkadot SDK RPC endpoint (WebSocket/HTTP) - - `9933`: Polkadot SDK HTTP RPC endpoint - - `9615`: Prometheus metrics endpoint - - `30333/30334`: P2P networking ports - - === "Node parameters" - - - `--unsafe-rpc-external`: Enables external RPC access - - `--rpc-cors=all`: Allows all origins for CORS - - `--rpc-methods=safe`: Only allows safe RPC methods - - `--state-pruning=archive` or `--state-pruning=1000`: Archive keeps complete state history, pruned keeps last 1000 blocks - - `--blocks-pruning=archive` or `--blocks-pruning=256`: Archive keeps all blocks, pruned keeps last 256 finalized blocks - - `--prometheus-external`: Exposes metrics externally - - !!! warning - - The `--unsafe-rpc-external` flag should only be used in development or properly secured environments. For production, use a reverse proxy with authentication. - - 4. Monitor the node synchronization status using the following command: - ```bash - curl -H "Content-Type: application/json" \ - -d '{"id":1, "jsonrpc":"2.0", "method": "system_syncState", "params":[]}' \ - http://localhost:9944 - ``` - - You should see a response similar to the following: - - ```json - { - "jsonrpc":"2.0", - "id":1, - "result":{ - "startingBlock":0, - "currentBlock":3394816, - "highestBlock":3394816 - } - } - ``` - - When synchronization is complete, `currentBlock` will be equal to `highestBlock`. - - 5. You can use a few different commands to verify your node is running properly: - - - Get chain information: - ```bash - curl -H "Content-Type: application/json" \ - -d '{"id":1, "jsonrpc":"2.0", "method": "system_chain", "params":[]}' \ - http://localhost:9944 - ``` - - Get the latest block: - ```bash - curl -H "Content-Type: application/json" \ - -d '{"id":1, "jsonrpc":"2.0", "method": "chain_getHeader", "params":[]}' \ - http://localhost:9944 - ``` - - Query node health: - ```bash - curl -H "Content-Type: application/json" \ - -d '{"id":1, "jsonrpc":"2.0", "method": "system_health", "params":[]}' \ - http://localhost:9944 - ``` - - 6. Use the following commands to manage your Docker containers: - - - View node logs: - ```bash - docker logs -f people-chain-rpc - ``` - - Stop container: - ```bash - docker stop people-chain-rpc - ``` - - Start container: - ```bash - docker start people-chain-rpc - ``` - - Remove container: - ```bash - docker rm people-chain-rpc - ``` - -=== "Manual systemd Setup" + Refer to the [Port Mappings](#port-mappings) and [Node Configuration Parameters](#node-configuration-parameters) sections for details on the command's configurations. - This option provides more control and is recommended for production environments requiring custom configurations. +=== "systemd" 1. Download the `polkadot-parachain` binary from the latest stable [Polkadot SDK release](https://github.com/paritytech/polkadot-sdk/releases){target=\_blank}: + ```bash # Download the latest stable release (check releases page for current version) wget https://github.com/paritytech/polkadot-sdk/releases/download/polkadot-stable2509-2/polkadot-parachain @@ -378,38 +240,33 @@ Select the best option for your project, then use the steps in the following tab polkadot-parachain --version ``` - Check the [Polkadot SDK releases](https://github.com/paritytech/polkadot-sdk/releases){target=\_blank} page for the latest stable version. - - 2. Download your parachain's chain specification as described in [Obtaining a Chain Specification](#obtaining-a-chain-specification). + 2. Download your parachain's chain specification as described in [Obtain the Chain Specification](#obtain-the-chain-specification). 3. Create user and directory structures using the following commands: - - Create a dedicated user: - ```bash - sudo useradd -r -s /bin/bash polkadot - ``` - - Create data directory: - ```bash - sudo mkdir -p /var/lib/people-chain-rpc - ``` - - Copy the chain spec to the directory: - ```bash - sudo cp people-polkadot.json /var/lib/people-chain-rpc/ - ``` - - Set permissions: - ```bash - sudo chown -R polkadot:polkadot /var/lib/people-chain-rpc - ``` + + ```bash + # Create a dedicated user + sudo useradd -r -s /bin/bash polkadot + + # Create data directory + sudo mkdir -p /var/lib/people-chain-rpc + + # Copy the chain spec to the directory + sudo cp asset-hub-polkadot.json /var/lib/people-chain-rpc/ + + # Set permissions + sudo chown -R polkadot:polkadot /var/lib/people-chain-rpc + ``` 4. Create a systemd service file for the Polkadot SDK RPC node: + ```bash sudo nano /etc/systemd/system/people-chain-rpc.service ``` - 5. Open the new service file and add the configuration for your chosen node type: + 5. Open the new service file and add the configuration for either an archive (complete history) or pruned (recent state) node: - === "Archive Node" - - Archive node configuration maintains complete parachain history for historical queries: + === "Archive" ```ini [Unit] @@ -452,9 +309,7 @@ Select the best option for your project, then use the steps in the following tab WantedBy=multi-user.target ``` - === "Pruned Node" - - Pruned node configuration keeps recent state for smaller storage requirements: + === "Pruned" ```ini [Unit] @@ -497,44 +352,135 @@ Select the best option for your project, then use the steps in the following tab WantedBy=multi-user.target ``` - 6. Start the service using the following commands: - - Reload systemd: - ```bash - sudo systemctl daemon-reload - ``` - - Enable service to start on boot: - ```bash - sudo systemctl enable people-chain-rpc - ``` - - Start the Polkadot SDK node: - ```bash - sudo systemctl start people-chain-rpc - ``` - - Check status and wait for sync: - ```bash - sudo systemctl status people-chain-rpc - sudo journalctl -u people-chain-rpc -f - ``` + Refer to the [Port Mappings](#port-mappings) and [Node Configuration Parameters](#node-configuration-parameters) sections for details on the command's configurations. - 7. You can use a few different commands to verify your node is running properly: - - Get chain information: - ```bash - curl -H "Content-Type: application/json" \ - -d '{"id":1, "jsonrpc":"2.0", "method": "system_chain", "params":[]}' \ - http://localhost:9944 - ``` - - Get the latest block: - ```bash - curl -H "Content-Type: application/json" \ - -d '{"id":1, "jsonrpc":"2.0", "method": "chain_getHeader", "params":[]}' \ - http://localhost:9944 - ``` - - Query node health: - ```bash - curl -H "Content-Type: application/json" \ - -d '{"id":1, "jsonrpc":"2.0", "method": "system_health", "params":[]}' \ - http://localhost:9944 - ``` + 6. Start the service: + + ```bash + # Reload systemd + sudo systemctl daemon-reload + + # Enable service to start on boot + sudo systemctl enable people-chain-rpc + + # Start the Polkadot SDK node: + sudo systemctl start people-chain-rpc + ``` + +### Port Mappings + +- **`9944`**: Polkadot SDK RPC endpoint (WebSocket/HTTP) +- **`9933`**: Polkadot SDK HTTP RPC endpoint +- **`9615`**: Prometheus metrics endpoint +- **`30333/30334`**: P2P networking ports + +### Node Configuration Parameters + +- **`--unsafe-rpc-external`**: Enables external RPC access. **This command should only be used in development or properly secured environments**. For production, use a reverse proxy with authentication. +- **`--rpc-cors=all`**: Allows all origins for CORS. +- **`--rpc-methods=safe`**: Only allows safe RPC methods. +- **`--state-pruning`**: Archive keeps complete state history, pruned keeps last specified number of blocks. +- **`--blocks-pruning`**: Archive keeps all blocks, pruned keeps last specified number of finalized blocks. +- **`--prometheus-external`**: Exposes metrics externally. + +## Monitor Node Synchronization + +Monitor the node synchronization status: + +```bash +curl -H "Content-Type: application/json" \ +-d '{"id":1, "jsonrpc":"2.0", "method": "system_syncState", "params":[]}' \ +http://localhost:9944 +``` + +When synchronization is complete, `currentBlock` will be equal to `highestBlock`: + +
+ curl -H "Content-Type: application/json" \ + -d '{"id":1, "jsonrpc":"2.0", "method": "system_syncState", "params":[]}' \ + http://localhost:9944 +
{
+  "jsonrpc":"2.0",
+  "id":1,
+  "result":{
+    "startingBlock":0,
+    "currentBlock":3394816,
+    "highestBlock":3394816
+  }
+}
+  
+
+ +!!! tip + You can use the `system_health` command to verify your node is running properly. + + ```bash + curl -H "Content-Type: application/json" \ + -d '{"id":1, "jsonrpc":"2.0", "method": "system_health", "params":[]}' \ + http://localhost:9944 + ``` + +## Commands for Managing Your Node + +Use the following commands to manage your node: + +=== "Docker" + + - View node logs: + + ```bash + docker logs -f people-chain-rpc + ``` + + - Stop container: + + ```bash + docker stop people-chain-rpc + ``` + + - Start container: + + ```bash + docker start people-chain-rpc + ``` + + - Remove container: + + ```bash + docker rm people-chain-rpc + ``` + +=== "systemd" + + - Check status + + ```bash + sudo systemctl status people-chain-rpc + ``` + + - View node logs: + + ```bash + sudo journalctl -u people-chain-rpc -f + ``` + + - Stop service: + + ```bash + sudo systemctl stop people-chain-rpc + ``` + + - Enable service: + + ```bash + sudo systemctl enable people-chain-rpc + ``` + + - Start service: + + ```bash + sudo systemctl start people-chain-rpc + ``` ## Conclusion diff --git a/node-infrastructure/run-a-node/polkadot-hub-rpc.md b/node-infrastructure/run-a-node/polkadot-hub-rpc.md index 0656e7fa5..146952633 100644 --- a/node-infrastructure/run-a-node/polkadot-hub-rpc.md +++ b/node-infrastructure/run-a-node/polkadot-hub-rpc.md @@ -6,23 +6,14 @@ categories: Infrastructure # Run an RPC Node for Polkadot Hub -## Overview +## Introduction -[Polkadot Hub](/reference/polkadot-hub/){target=\_blank} is the entry point to Polkadot for all users and application developers. It provides access to essential Web3 services, including: +Polkadot Hub is the gateway to the Polkadot network, providing access to core services such as asset management, governance, and cross-chain messaging. Running your own RPC node gives developers and applications direct access to these services while also supporting infrastructure tasks like block indexing and SDK tool compatibility. -- **Asset Management**: Native support for fungible and non-fungible assets -- **Governance, Staking, and Treasury**: Core protocol operations -- **Cross-chain Communication**: XCM message handling + -Running an RPC node for Polkadot Hub enables applications, wallets, and users to interact with the parachain through: - -- **Polkadot SDK Node RPC** (Port 9944): Native Polkadot API (WebSocket and HTTP) - -This setup enables block explorer indexing and provides full compatibility with Polkadot SDK development tools. - -!!! note - - The parameters and configurations in this guide are provided as illustrative examples. You may need to modify them according to your specific environment, hardware capabilities, and network conditions. +Through the Polkadot SDK node RPC (WebSocket port 9944, HTTP port 9933), your node serves as the bridge between the network and applications. This page guides you through setting up a node from scratch, including hardware requirements and deployment options using Docker or systemd. ## Prerequisites @@ -47,138 +38,100 @@ RPC nodes serving production traffic require robust hardware. The following shou - 9933 (Polkadot SDK HTTP RPC) - Consider DDoS protection and rate limiting for production deployments -**Note**: For development or low-traffic scenarios, you can reduce these requirements proportionally. Consider using a reverse proxy (nginx, Caddy) for production deployments. +!!! note + For development or low-traffic scenarios, you can reduce these requirements proportionally. Consider using a reverse proxy ([nginx](https://nginx.org/){target=\_blank}, [Caddy](https://caddyserver.com/){target=\_blank}) for production deployments. ### Software Requirements Required software: -- **Operating System**: Ubuntu 22.04 LTS (recommended) or similar Linux distribution -- **Docker**: Required for obtaining binaries and running containers -- **rclone**: (Optional but recommended) Command-line program for managing files on cloud storage (https://rclone.org/downloads/) +- **Operating system**: Ubuntu 22.04 LTS (recommended) or similar Linux distribution +- **[Docker](https://www.docker.com/get-started/){target=\_blank}**: Required for obtaining binaries and running containers +- **[rclone](https://rclone.org/downloads/){target=\_blank}**: (Optional but recommended) Command-line program for managing files on cloud storage -## Setup Options +## Spin Up a Node This guide provides two options for deployment: -- **Docker-based Setup**: Best for simpler set up and maintenance -- **Manual/systemd Setup**: Best for production environments requiring more control +- **Docker**: Best for simpler set up and maintenance +- **systemd**: Best for production environments requiring more control Select the best option for your project, then use the steps in the following tabs to complete set up. -=== "Docker-Based Setup" +=== "Docker" - This option uses Docker containers for the Polkadot SDK node, making it easy to set up and manage. Follow these steps to set your RPC node using Docker: + 1. Download the official Polkadot Hub (formerly known as Asset Hub) chain specification file: - 1. Download the official Polkadot Hub (formerly known as Asset Hub) chain specification: ```bash curl -L https://raw.githubusercontent.com/paritytech/polkadot-sdk/master/cumulus/parachains/chain-specs/asset-hub-polkadot.json -o asset-hub-polkadot.json ``` - !!! note - - This chain specification is the official configuration file that defines the network parameters for Polkadot Hub. - - 2. (Optional but recommended) Download database snapshots: - - Using pre-synchronized snapshots significantly reduces initial sync time from several days to just a few hours. You need to download both parachain and relay chain data. - - You can obtain the latest snapshot from the [Snapshot Provider](https://snapshots.polkadot.io/){target=\_blank}. Follow these steps to download and use snapshots: - 1. Create new directories with the following commands: - ```bash - mkdir -p my-node-data/chains/asset-hub-polkadot/db - mkdir -p my-node-data/chains/polkadot/db - ``` - 2. Download the appropriate snapshots using the following commands: - - === "Archive Node" + 2. (Optional but recommended) Download pre-synced snapshots from the [Snapshot Provider](https://snapshots.polkadot.io/){target=\_blank} to cut initial sync time from days to hours: - Archive node setup maintains complete parachain history (~600-800 GB total). Download both Asset Hub archive and Relay chain pruned snapshots: + 1. Create new directories: - **Asset Hub archive snapshot** (~400 GB): - ```bash - # Check https://snapshots.polkadot.io/ for the latest snapshot URL - export SNAPSHOT_URL_ASSET_HUB="https://snapshots.polkadot.io/polkadot-asset-hub-rocksdb-archive/LATEST" - - rclone copyurl $SNAPSHOT_URL_ASSET_HUB/files.txt files.txt - rclone copy --progress --transfers 20 \ - --http-url $SNAPSHOT_URL_ASSET_HUB \ - --no-traverse --http-no-head --disable-http2 \ - --inplace --no-gzip-encoding --size-only \ - --retries 6 --retries-sleep 10s \ - --files-from files.txt :http: my-node-data/chains/asset-hub-polkadot/db/ - - rm files.txt - ``` - - **Relay chain pruned snapshot** (~200 GB): - ```bash - # Check https://snapshots.polkadot.io/ for the latest snapshot URL - export SNAPSHOT_URL_RELAY="https://snapshots.polkadot.io/polkadot-rocksdb-prune/LATEST" - - rclone copyurl $SNAPSHOT_URL_RELAY/files.txt files.txt - rclone copy --progress --transfers 20 \ - --http-url $SNAPSHOT_URL_RELAY \ - --no-traverse --http-no-head --disable-http2 \ - --inplace --no-gzip-encoding --size-only \ - --retries 6 --retries-sleep 10s \ - --files-from files.txt :http: my-node-data/chains/polkadot/db/ - - rm files.txt - ``` - - **rclone parameters:** - - - `--transfers 20`: Uses 20 parallel transfers for faster download - - `--retries 6`: Automatically retries failed transfers up to 6 times - - `--retries-sleep 10s`: Waits 10 seconds between retry attempts - - `--size-only`: Only transfers if sizes differ (prevents unnecessary re-downloads) - - === "Pruned Node" + ```bash + mkdir -p my-node-data/chains/asset-hub-polkadot/db + mkdir -p my-node-data/chains/polkadot/db + ``` - Pruned node setup keeps recent state for smaller storage (~500 GB total). Download both Asset Hub pruned and Relay chain pruned snapshots: + 2. Choose between Asset Hub archive (complete history; ~400 GB) or pruned (recent state; TODO: ERIN) snapshots and set the snapshot URL accordingly: - **Asset Hub pruned snapshot**: - ```bash - # Check https://snapshots.polkadot.io/ for the latest snapshot URL - export SNAPSHOT_URL_ASSET_HUB="https://snapshots.polkadot.io/polkadot-asset-hub-rocksdb-prune/LATEST" + === "Archive" - rclone copyurl $SNAPSHOT_URL_ASSET_HUB/files.txt files.txt - rclone copy --progress --transfers 20 \ - --http-url $SNAPSHOT_URL_ASSET_HUB \ - --no-traverse --http-no-head --disable-http2 \ - --inplace --no-gzip-encoding --size-only \ - --retries 6 --retries-sleep 10s \ - --files-from files.txt :http: my-node-data/chains/asset-hub-polkadot/db/ + ```bash + # Check https://snapshots.polkadot.io/ for the latest snapshot URL + export SNAPSHOT_URL_ASSET_HUB="https://snapshots.polkadot.io/polkadot-asset-hub-rocksdb-archive/INSERT_LATEST" + ``` + + === "Pruned" - rm files.txt - ``` + ```bash + # Check https://snapshots.polkadot.io/ for the latest snapshot URL + export SNAPSHOT_URL_ASSET_HUB="https://snapshots.polkadot.io/polkadot-asset-hub-rocksdb-prune/INSERT_LATEST" + ``` + + 3. Use `rclone` to download and save the Asset Hub snapshots: - **Relay chain pruned snapshot** (~200 GB): - ```bash - # Check https://snapshots.polkadot.io/ for the latest snapshot URL - export SNAPSHOT_URL_RELAY="https://snapshots.polkadot.io/polkadot-rocksdb-prune/LATEST" + ```bash + rclone copyurl $SNAPSHOT_URL_ASSET_HUB/files.txt files.txt + rclone copy --progress --transfers 20 \ + --http-url $SNAPSHOT_URL_ASSET_HUB \ + --no-traverse --http-no-head --disable-http2 \ + --inplace --no-gzip-encoding --size-only \ + --retries 6 --retries-sleep 10s \ + --files-from files.txt :http: my-node-data/chains/asset-hub-polkadot/db/ + + rm files.txt + ``` - rclone copyurl $SNAPSHOT_URL_RELAY/files.txt files.txt - rclone copy --progress --transfers 20 \ - --http-url $SNAPSHOT_URL_RELAY \ - --no-traverse --http-no-head --disable-http2 \ - --inplace --no-gzip-encoding --size-only \ - --retries 6 --retries-sleep 10s \ - --files-from files.txt :http: my-node-data/chains/polkadot/db/ + ??? interface "rclone parameters" - rm files.txt - ``` + - **`--transfers 20`**: Uses 20 parallel transfers for faster download + - **`--retries 6`**: Automatically retries failed transfers up to 6 times + - **`--retries-sleep 10s`**: Waits 10 seconds between retry attempts + - **`--size-only`**: Only transfers if sizes differ (prevents unnecessary re-downloads) - **rclone parameters:** + 4. Repeat the process with the pruned relay chain snapshot (~200 GB): - - `--transfers 20`: Uses 20 parallel transfers for faster download - - `--retries 6`: Automatically retries failed transfers up to 6 times - - `--retries-sleep 10s`: Waits 10 seconds between retry attempts - - `--size-only`: Only transfers if sizes differ (prevents unnecessary re-downloads) - 3. Launch Polkadot Hub Node using the official [Parity Docker image](https://hub.docker.com/r/parity/polkadot-parachain){target=\_blank}: + ```bash + # Check https://snapshots.polkadot.io/ for the latest snapshot URL + export SNAPSHOT_URL_RELAY="https://snapshots.polkadot.io/polkadot-rocksdb-prune/INSERT_LATEST" + + rclone copyurl $SNAPSHOT_URL_RELAY/files.txt files.txt + rclone copy --progress --transfers 20 \ + --http-url $SNAPSHOT_URL_RELAY \ + --no-traverse --http-no-head --disable-http2 \ + --inplace --no-gzip-encoding --size-only \ + --retries 6 --retries-sleep 10s \ + --files-from files.txt :http: my-node-data/chains/polkadot/db/ + + rm files.txt + ``` - === "Archive Node" + 3. Launch your Polkadot Hub node using the official [Parity Docker image](https://hub.docker.com/r/parity/polkadot-parachain){target=\_blank}: - Archive node configuration maintains complete parachain history for historical queries: + === "Archive" ```bash docker run -d --name polkadot-hub-rpc --restart unless-stopped \ @@ -210,9 +163,7 @@ Select the best option for your project, then use the steps in the following tab --rpc-port=0 ``` - === "Pruned Node" - - Pruned node configuration keeps recent state for smaller storage requirements: + === "Pruned" ```bash docker run -d --name polkadot-hub-rpc --restart unless-stopped \ @@ -244,85 +195,12 @@ Select the best option for your project, then use the steps in the following tab --rpc-port=0 ``` - Critical configuration parameters include port mappings and node parameters: - - === "Port mappings" - - - `9944`: Polkadot SDK RPC endpoint (WebSocket/HTTP) - - `9933`: Polkadot SDK HTTP RPC endpoint - - `9615`: Prometheus metrics endpoint - - `30333/30334`: P2P networking ports - - === "Node parameters" - - - `--unsafe-rpc-external`: Enables external RPC access - - `--rpc-cors=all`: Allows all origins for CORS - - `--rpc-methods=safe`: Only allows safe RPC methods - - `--state-pruning=archive` or `--state-pruning=1000`: Archive keeps complete state history, pruned keeps last 1000 blocks - - `--blocks-pruning=archive` or `--blocks-pruning=256`: Archive keeps all blocks, pruned keeps last 256 finalized blocks - - `--prometheus-external`: Exposes metrics externally - - !!! warning - - The `--unsafe-rpc-external` flag should only be used in development or properly secured environments. For production, use a reverse proxy with authentication. - - 4. Monitor the node synchronization status using the following command: - - ```bash - curl -H "Content-Type: application/json" \ - -d '{"id":1, "jsonrpc":"2.0", "method": "system_syncState", "params":[]}' \ - http://localhost:9944 - ``` - - You should see a response similar to the following: - - ```json - { - "jsonrpc":"2.0", - "id":1, - "result":{ - "startingBlock":0, - "currentBlock":3394816, - "highestBlock":3394816 - } - } - ``` - - When synchronization is complete, `currentBlock` will be equal to `highestBlock`. - - 5. You can use the `system_health` command to verify your node is running properly: - - - Query node health: - ```bash - curl -H "Content-Type: application/json" \ - -d '{"id":1, "jsonrpc":"2.0", "method": "system_health", "params":[]}' \ - http://localhost:9944 - ``` - - 6. Use the following commands to manage your Docker containers: - - - View node logs: - ```bash - docker logs -f polkadot-hub-rpc - ``` - - Stop container: - ```bash - docker stop polkadot-hub-rpc - ``` - - Start container: - ```bash - docker start polkadot-hub-rpc - ``` - - Remove container: - ```bash - docker rm polkadot-hub-rpc - ``` - -=== "Manual systemd Setup" - - This option provides more control and is recommended for production environments requiring custom configurations. + Refer to the [Port Mappings](#port-mappings) and [Node Configuration Parameters](#node-configuration-parameters) sections for details on the command's configurations. + +=== "systemd" 1. Download the `polkadot-parachain` binary from the latest stable [Polkadot SDK release](https://github.com/paritytech/polkadot-sdk/releases){target=\_blank}: + ```bash # Download the latest stable release (check releases page for current version) wget https://github.com/paritytech/polkadot-sdk/releases/download/polkadot-stable2509-2/polkadot-parachain @@ -336,38 +214,36 @@ Select the best option for your project, then use the steps in the following tab ``` 2. Download the Polkadot Hub chain specification: + ```bash curl -L https://raw.githubusercontent.com/paritytech/polkadot-sdk/master/cumulus/parachains/chain-specs/asset-hub-polkadot.json -o asset-hub-polkadot.json ``` - 3. Create user and directory structures using the following commands: - - Create a dedicated user: - ```bash - sudo useradd -r -s /bin/bash polkadot - ``` - - Create data directory: - ```bash - sudo mkdir -p /var/lib/polkadot-hub-rpc - ``` - - Copy the chain spec to the directory: - ```bash - sudo cp asset-hub-polkadot.json /var/lib/polkadot-hub-rpc/ - ``` - - Set permissions: - ```bash - sudo chown -R polkadot:polkadot /var/lib/polkadot-hub-rpc - ``` + 3. Create user and directory structures: + + ```bash + # Create a dedicated user + sudo useradd -r -s /bin/bash polkadot + + # Create data directory + sudo mkdir -p /var/lib/polkadot-hub-rpc + + # Copy the chain spec to the directory + sudo cp asset-hub-polkadot.json /var/lib/polkadot-hub-rpc/ + + # Set permissions + sudo chown -R polkadot:polkadot /var/lib/polkadot-hub-rpc + ``` 4. Create a systemd service file for the Polkadot SDK RPC node: + ```bash sudo nano /etc/systemd/system/polkadot-hub-rpc.service ``` - 5. Open the new service file and add the configuration for your chosen node type: - - === "Archive Node" + 5. Open the new service file and add the configuration for either an archive (complete history) or pruned (recent state) node: - Archive node configuration maintains complete parachain history for historical queries: + === "Archive" ```ini [Unit] @@ -412,8 +288,6 @@ Select the best option for your project, then use the steps in the following tab === "Pruned Node" - Pruned node configuration keeps recent state for smaller storage requirements: - ```ini [Unit] Description=Polkadot Hub RPC Node @@ -455,44 +329,135 @@ Select the best option for your project, then use the steps in the following tab WantedBy=multi-user.target ``` - 6. Start the service using the following commands: - - Reload systemd: - ```bash - sudo systemctl daemon-reload - ``` - - Enable service to start on boot: - ```bash - sudo systemctl enable polkadot-hub-rpc - ``` - - Start the Polkadot SDK node: - ```bash - sudo systemctl start polkadot-hub-rpc - ``` - - Check status and wait for sync: - ```bash - sudo systemctl status polkadot-hub-rpc - sudo journalctl -u polkadot-hub-rpc -f - ``` + Refer to the [Port Mappings](#port-mappings) and [Node Configuration Parameters](#node-configuration-parameters) sections for details on the command's configurations. - 7. You can use a few different commands to verify your node is running properly: - - Get chain information: - ```bash - curl -H "Content-Type: application/json" \ - -d '{"id":1, "jsonrpc":"2.0", "method": "system_chain", "params":[]}' \ - http://localhost:9944 - ``` - - Get the latest block: - ```bash - curl -H "Content-Type: application/json" \ - -d '{"id":1, "jsonrpc":"2.0", "method": "chain_getHeader", "params":[]}' \ - http://localhost:9944 - ``` - - Query node health: - ```bash - curl -H "Content-Type: application/json" \ - -d '{"id":1, "jsonrpc":"2.0", "method": "system_health", "params":[]}' \ - http://localhost:9944 - ``` + 6. Start the service: + + ```bash + # Reload systemd + sudo systemctl daemon-reload + + # Enable service to start on boot + sudo systemctl enable polkadot-hub-rpc + + # Start the Polkadot SDK node: + sudo systemctl start polkadot-hub-rpc + ``` + +### Port Mappings + +- **`9944`**: Polkadot SDK RPC endpoint (WebSocket/HTTP) +- **`9933`**: Polkadot SDK HTTP RPC endpoint +- **`9615`**: Prometheus metrics endpoint +- **`30333/30334`**: P2P networking ports + +### Node Configuration Parameters + +- **`--unsafe-rpc-external`**: Enables external RPC access. **This command should only be used in development or properly secured environments**. For production, use a reverse proxy with authentication. +- **`--rpc-cors=all`**: Allows all origins for CORS. +- **`--rpc-methods=safe`**: Only allows safe RPC methods. +- **`--state-pruning`**: Archive keeps complete state history, pruned keeps last specified number of blocks. +- **`--blocks-pruning`**: Archive keeps all blocks, pruned keeps last specified number of finalized blocks. +- **`--prometheus-external`**: Exposes metrics externally. + +## Monitor Node Synchronization + +Monitor the node synchronization status: + +```bash +curl -H "Content-Type: application/json" \ +-d '{"id":1, "jsonrpc":"2.0", "method": "system_syncState", "params":[]}' \ +http://localhost:9944 +``` + +When synchronization is complete, `currentBlock` will be equal to `highestBlock`: + +
+ curl -H "Content-Type: application/json" \ + -d '{"id":1, "jsonrpc":"2.0", "method": "system_syncState", "params":[]}' \ + http://localhost:9944 +
{
+  "jsonrpc":"2.0",
+  "id":1,
+  "result":{
+    "startingBlock":0,
+    "currentBlock":3394816,
+    "highestBlock":3394816
+  }
+}
+  
+
+ +!!! tip + You can use the `system_health` command to verify your node is running properly. + + ```bash + curl -H "Content-Type: application/json" \ + -d '{"id":1, "jsonrpc":"2.0", "method": "system_health", "params":[]}' \ + http://localhost:9944 + ``` + +## Commands for Managing Your Node + +Use the following commands to manage your node: + +=== "Docker" + + - View node logs: + + ```bash + docker logs -f polkadot-hub-rpc + ``` + + - Stop container: + + ```bash + docker stop polkadot-hub-rpc + ``` + + - Start container: + + ```bash + docker start polkadot-hub-rpc + ``` + + - Remove container: + + ```bash + docker rm polkadot-hub-rpc + ``` + +=== "systemd" + + - Check status + + ```bash + sudo systemctl status polkadot-hub-rpc + ``` + + - View node logs: + + ```bash + sudo journalctl -u polkadot-hub-rpc -f + ``` + + - Stop service: + + ```bash + sudo systemctl stop polkadot-hub-rpc + ``` + + - Enable service: + + ```bash + sudo systemctl enable polkadot-hub-rpc + ``` + + - Start service: + + ```bash + sudo systemctl start polkadot-hub-rpc + ``` ## Conclusion diff --git a/node-infrastructure/run-a-node/relay-chain/bootnode.md b/node-infrastructure/run-a-node/relay-chain/bootnode.md index 3ca2e7aff..bb4bdcb73 100644 --- a/node-infrastructure/run-a-node/relay-chain/bootnode.md +++ b/node-infrastructure/run-a-node/relay-chain/bootnode.md @@ -67,7 +67,7 @@ A bootnode can be run as follows: This assigns the p2p to port 30310 and p2p/ws to port 30311. For the p2p/wss port, a proxy must be set up with a DNS name and a corresponding certificate. The following example is for the popular nginx server and enables p2p/wss on port 30312 by adding a proxy to the p2p/ws port 30311: ``` conf title="/etc/nginx/sites-enabled/dot-bootnode" ---8<-- 'code/nodes-and-validators/run-a-node/bootnode/bootnode.conf' +--8<-- 'code/node-infrastructure/run-a-node/bootnode/bootnode.conf' ``` ## Testing Bootnode Connection diff --git a/node-infrastructure/run-a-node/relay-chain/full-node.md b/node-infrastructure/run-a-node/relay-chain/full-node.md index 3d9fa45b1..5aed5acf1 100644 --- a/node-infrastructure/run-a-node/relay-chain/full-node.md +++ b/node-infrastructure/run-a-node/relay-chain/full-node.md @@ -26,7 +26,7 @@ Before getting started, ensure the following prerequisites are met: - [Install the necessary dependencies for the Polkadot SDK](/parachains/install-polkadot-sdk/){target=\_blank}. !!! warning - This setup is not recommended for validators. If you plan to run a validator, refer to the [Running a Validator](/nodes-and-validators/run-a-validator/onboarding-and-offboarding/set-up-validator/){target=\_blank} guide for proper instructions. + This setup is not recommended for validators. If you plan to run a validator, refer to the [Running a Validator](/node-infrastructure/run-a-validator/onboarding-and-offboarding/set-up-validator/){target=\_blank} guide for proper instructions. ### Install and Build the Polkadot Binary @@ -56,7 +56,7 @@ This section will walk you through installing and building the Polkadot binary f You should see output similar to the following: - --8<-- 'code/nodes-and-validators/run-a-node/full-node/setup-full-node-1.html' + --8<-- 'code/node-infrastructure/run-a-node/full-node/setup-full-node-1.html' Then, run the following commands to clone and build the Polkadot binary: @@ -124,7 +124,7 @@ This section will walk you through installing and building the Polkadot binary f You should see output similar to the following: - --8<-- 'code/nodes-and-validators/run-a-node/full-node/setup-full-node-2.html' + --8<-- 'code/node-infrastructure/run-a-node/full-node/setup-full-node-2.html' Once Rust is configured, run the following commands to clone and build Polkadot: @@ -266,7 +266,7 @@ The syncing process will take a while, depending on your capacity, processing po A healthy node syncing blocks will output logs like the following: ---8<-- 'code/nodes-and-validators/run-a-node/full-node/run-node.html' +--8<-- 'code/node-infrastructure/run-a-node/full-node/run-node.html' Congratulations, you're now syncing a Polkadot full node! Remember that the process is identical when using any other Polkadot SDK-based chain, although individual chains may have chain-specific flag requirements. diff --git a/node-infrastructure/run-a-node/relay-chain/secure-wss.md b/node-infrastructure/run-a-node/relay-chain/secure-wss.md index 571e183ab..9626d2097 100644 --- a/node-infrastructure/run-a-node/relay-chain/secure-wss.md +++ b/node-infrastructure/run-a-node/relay-chain/secure-wss.md @@ -29,7 +29,7 @@ When connecting, you can generate a self-signed certificate and rely on your nod Use the following command to generate a self-signed certificate using OpenSSL: ---8<-- 'code/nodes-and-validators/run-a-node/secure-wss/install-openssl.md' +--8<-- 'code/node-infrastructure/run-a-node/secure-wss/install-openssl.md' ## Install a Proxy Server @@ -43,21 +43,21 @@ There are a lot of different implementations of a WebSocket proxy; some of the m ``` 2. In an SSL-enabled virtual host, add: - --8<-- 'code/nodes-and-validators/run-a-node/secure-wss/nginx-config.md' + --8<-- 'code/node-infrastructure/run-a-node/secure-wss/nginx-config.md' 3. Optionally, you can introduce some form of rate limiting: - --8<-- 'code/nodes-and-validators/run-a-node/secure-wss/nginx-rate-limit.md' + --8<-- 'code/node-infrastructure/run-a-node/secure-wss/nginx-rate-limit.md' ### Use Apache2 Apache2 can run in various modes, including `prefork`, `worker`, and `event`. In this example, the [`event`](https://httpd.apache.org/docs/2.4/mod/event.html){target=\_blank} mode is recommended for handling higher traffic loads, as it is optimized for performance in such environments. However, depending on the specific requirements of your setup, other modes like `prefork` or `worker` may also be appropriate. 1. Install the `apache2` web server: - --8<-- 'code/nodes-and-validators/run-a-node/secure-wss/install-apache2.md' + --8<-- 'code/node-infrastructure/run-a-node/secure-wss/install-apache2.md' 2. The [`mod_proxy_wstunnel`](https://httpd.apache.org/docs/2.4/mod/mod_proxy_wstunnel.html){target=\_blank} provides support for the tunneling of WebSocket connections to a backend WebSocket server. The connection is automatically upgraded to a WebSocket connection. In an SSL-enabled virtual host add: - --8<-- 'code/nodes-and-validators/run-a-node/secure-wss/apache2-config.md' + --8<-- 'code/node-infrastructure/run-a-node/secure-wss/apache2-config.md' !!!warning Older versions of `mod_proxy_wstunnel` don't upgrade the connection automatically and will need the following config added: @@ -91,4 +91,4 @@ Apache2 can run in various modes, including `prefork`, `worker`, and `event`. In wss://example.com:443 ``` -![A sync-in-progress chain connected to Polkadot.js UI](/images/nodes-and-validators/run-a-node/secure-wss/secure-wss-01.webp) \ No newline at end of file +![A sync-in-progress chain connected to Polkadot.js UI](/images/node-infrastructure/run-a-node/secure-wss/secure-wss-01.webp) \ No newline at end of file diff --git a/node-infrastructure/run-a-validator/onboarding-and-offboarding/key-management.md b/node-infrastructure/run-a-validator/onboarding-and-offboarding/key-management.md index 41f7f56ef..3da0da942 100644 --- a/node-infrastructure/run-a-validator/onboarding-and-offboarding/key-management.md +++ b/node-infrastructure/run-a-validator/onboarding-and-offboarding/key-management.md @@ -8,7 +8,7 @@ categories: Infrastructure ## Introduction -After setting up your node environment as shown in the [Setup](/nodes-and-validators/run-a-validator/onboarding-and-offboarding/set-up-validator/){target=\_blank} section, you'll need to configure multiple keys for your validator to operate properly. This includes setting up session keys, which are essential for participating in the consensus process, and configuring a node key that maintains a stable network identity. This guide walks you through the key management process, showing you how to generate, store, and register these keys. +After setting up your node environment as shown in the [Setup](/node-infrastructure/run-a-validator/onboarding-and-offboarding/set-up-validator/){target=\_blank} section, you'll need to configure multiple keys for your validator to operate properly. This includes setting up session keys, which are essential for participating in the consensus process, and configuring a node key that maintains a stable network identity. This guide walks you through the key management process, showing you how to generate, store, and register these keys. ## Set Session Keys @@ -29,7 +29,7 @@ There are multiple ways to create the session keys. It can be done by interactin 3. Click the **Submit RPC Call** button. 4. Copy the hex-encoded public key from the response. - ![](/images/nodes-and-validators/run-a-validator/onboarding-and-offboarding/key-management/key-management-01.webp) + ![](/images/node-infrastructure/run-a-validator/onboarding-and-offboarding/key-management/key-management-01.webp) === "Curl" @@ -53,7 +53,7 @@ There are multiple ways to create the session keys. It can be done by interactin When you run the command, it produces output similar to this example: - --8<-- 'code/nodes-and-validators/run-a-validator/onboarding-and-offboarding/key-management/subkey-generate.html' + --8<-- 'code/node-infrastructure/run-a-validator/onboarding-and-offboarding/key-management/subkey-generate.html' To properly store these keys, create a file in your keystore directory with a specific naming convention. The filename must consist of the hex string `61757261` (which represents "aura" in hex) followed by the public key without its `0x` prefix. @@ -77,7 +77,7 @@ Now that you have generated your session keys, you must submit them to the chain 2. Select **Set Session Key** on the bonding account you generated earlier. 3. Paste the hex-encoded session key string you generated (from either the UI or CLI) into the input field and submit the transaction. -![](/images/nodes-and-validators/run-a-validator/onboarding-and-offboarding/key-management/key-management-02.webp) +![](/images/node-infrastructure/run-a-validator/onboarding-and-offboarding/key-management/key-management-02.webp) Once the transaction is signed and submitted, your session keys will be registered on-chain. @@ -96,7 +96,7 @@ Validators on Polkadot need a static network key (also known as the node key) to Starting with Polkadot version 1.11, validators without a stable network key may encounter the following error on startup: ---8<-- 'code/nodes-and-validators/run-a-validator/onboarding-and-offboarding/key-management/node-key-error-01.html' +--8<-- 'code/node-infrastructure/run-a-validator/onboarding-and-offboarding/key-management/node-key-error-01.html' ### Generate the Node Key diff --git a/node-infrastructure/run-a-validator/onboarding-and-offboarding/set-up-validator.md b/node-infrastructure/run-a-validator/onboarding-and-offboarding/set-up-validator.md index 5c0516ef6..86ddf175b 100644 --- a/node-infrastructure/run-a-validator/onboarding-and-offboarding/set-up-validator.md +++ b/node-infrastructure/run-a-validator/onboarding-and-offboarding/set-up-validator.md @@ -16,10 +16,10 @@ Running a validator requires a commitment to maintaining a stable, secure infras To get the most from this guide, ensure you've done the following before going forward: -- Read [Validator Requirements](/nodes-and-validators/run-a-validator/requirements/){target=\_blank} and understand the recommended minimum skill level and hardware needs. -- Read [General Management](/nodes-and-validators/run-a-validator/operational-tasks/general-management/){target=\_blank}, [Upgrade Your Node](/nodes-and-validators/run-a-validator/operational-tasks/upgrade-your-node/){target=\_blank}, and [Pause Validating](/nodes-and-validators/run-a-validator/operational-tasks/pause-validating/){target=\_blank} and understand the tasks required to keep your validator operational. -- Read [Rewards Payout](/nodes-and-validators/run-a-validator/staking-mechanics/rewards/){target=\_blank} and understand how validator rewards are determined and paid out. -- Read [Offenses and Slashes](/nodes-and-validators/run-a-validator/staking-mechanics/offenses-and-slashes/){target=\_blank} and understand how validator performance and security can affect tokens staked by you or your nominators. +- Read [Validator Requirements](/node-infrastructure/run-a-validator/requirements/){target=\_blank} and understand the recommended minimum skill level and hardware needs. +- Read [General Management](/node-infrastructure/run-a-validator/operational-tasks/general-management/){target=\_blank}, [Upgrade Your Node](/node-infrastructure/run-a-validator/operational-tasks/upgrade-your-node/){target=\_blank}, and [Pause Validating](/node-infrastructure/run-a-validator/operational-tasks/pause-validating/){target=\_blank} and understand the tasks required to keep your validator operational. +- Read [Rewards Payout](/node-infrastructure/run-a-validator/staking-mechanics/rewards/){target=\_blank} and understand how validator rewards are determined and paid out. +- Read [Offenses and Slashes](/node-infrastructure/run-a-validator/staking-mechanics/offenses-and-slashes/){target=\_blank} and understand how validator performance and security can affect tokens staked by you or your nominators. ## Initial Setup @@ -191,7 +191,7 @@ Once the Polkadot binaries are installed, it's essential to verify that everythi The output should show the version numbers for each of the binaries. Ensure that the versions match and are consistent, similar to the following example (the specific version may vary): - --8<-- 'code/nodes-and-validators/run-a-validator/onboarding-and-offboarding/set-up-validator/terminal-output-01.html' + --8<-- 'code/node-infrastructure/run-a-validator/onboarding-and-offboarding/set-up-validator/terminal-output-01.html' If the versions do not match or if there is an error, double-check that all the binaries were correctly installed and are accessible within your `$PATH`. diff --git a/node-infrastructure/run-a-validator/onboarding-and-offboarding/start-validating.md b/node-infrastructure/run-a-validator/onboarding-and-offboarding/start-validating.md index 3119cd48b..1f53c22b1 100644 --- a/node-infrastructure/run-a-validator/onboarding-and-offboarding/start-validating.md +++ b/node-infrastructure/run-a-validator/onboarding-and-offboarding/start-validating.md @@ -8,7 +8,7 @@ categories: Infrastructure ## Introduction -After configuring your node keys as shown in the [Key Management](/nodes-and-validators/run-a-validator/onboarding-and-offboarding/key-management/){target=\_blank} section and ensuring your system is set up, you're ready to begin the validator setup process. This guide will walk you through choosing a network, synchronizing your node with the blockchain, bonding your DOT tokens, and starting your validator. +After configuring your node keys as shown in the [Key Management](/node-infrastructure/run-a-validator/onboarding-and-offboarding/key-management/){target=\_blank} section and ensuring your system is set up, you're ready to begin the validator setup process. This guide will walk you through choosing a network, synchronizing your node with the blockchain, bonding your DOT tokens, and starting your validator. ## Choose a Network @@ -52,7 +52,7 @@ The next step is to sync your node with the chosen blockchain network. Synchroni 2. **Monitor sync progress**: Once the sync starts, you will see a stream of logs providing information about the node's status and progress. Here's an example of what the output might look like: - --8<-- 'code/nodes-and-validators/run-a-validator/onboarding-and-offboarding/start-validating/terminal-output-01.html' + --8<-- 'code/node-infrastructure/run-a-validator/onboarding-and-offboarding/start-validating/terminal-output-01.html' The output logs provide information such as the current block number, node name, and network connections. Monitor the sync progress and any errors that might occur during the process. Look for information about the latest processed block and compare it with the current highest block using tools like [Telemetry](https://telemetry.polkadot.io/#list/Polkadot%20CC1){target=\_blank} or [Polkadot.js Apps Explorer](https://polkadot.js.org/apps/#/explorer){target=\_blank}. @@ -68,13 +68,13 @@ If you'd like to speed up the process further, you can use a database snapshot. !!!warning Although snapshots are convenient, syncing from scratch is recommended for security purposes. If snapshots become corrupted and most nodes rely on them, the network could inadvertently run on a non-canonical chain. ---8<-- 'code/nodes-and-validators/run-a-validator/onboarding-and-offboarding/start-validating/terminal-output-02.html' +--8<-- 'code/node-infrastructure/run-a-validator/onboarding-and-offboarding/start-validating/terminal-output-02.html' If you see terminal output similar to the preceding, and you are unable to synchronize the chain due to having zero peers, make sure you have libp2p port `30333` activated. It will take some time to discover other peers over the network. ## Bond DOT -Once your validator node is synced, the next step is bonding DOT. A bonded account, or stash, holds your staked tokens (DOT) that back your validator node. Bonding your DOT means locking it for a period, during which it cannot be transferred or spent but is used to secure your validator's role in the network. Visit the [Minimum Bond Requirement](/nodes-and-validators/run-a-validator/requirements/#minimum-bond-requirement) section for details on how much DOT is required. +Once your validator node is synced, the next step is bonding DOT. A bonded account, or stash, holds your staked tokens (DOT) that back your validator node. Bonding your DOT means locking it for a period, during which it cannot be transferred or spent but is used to secure your validator's role in the network. Visit the [Minimum Bond Requirement](/node-infrastructure/run-a-validator/requirements/#minimum-bond-requirement) section for details on how much DOT is required. The following sections will guide you through bonding DOT for your validator. @@ -106,29 +106,29 @@ Follow these steps to use Polkadot.js Apps to activate your validator: 1. In Polkadot.js Apps, navigate to **Network** and select **Staking**: - ![](/images/nodes-and-validators/run-a-validator/onboarding-and-offboarding/start-validating/start-validating-01.webp) + ![](/images/node-infrastructure/run-a-validator/onboarding-and-offboarding/start-validating/start-validating-01.webp) 2. Open the **Accounts** tab and click on **+ Validator**: - ![](/images/nodes-and-validators/run-a-validator/onboarding-and-offboarding/start-validating/start-validating-02.webp) + ![](/images/node-infrastructure/run-a-validator/onboarding-and-offboarding/start-validating/start-validating-02.webp) 3. Set a bond amount in the **value bonded** field and then click **next**: - ![](/images/nodes-and-validators/run-a-validator/onboarding-and-offboarding/start-validating/start-validating-03.webp) + ![](/images/node-infrastructure/run-a-validator/onboarding-and-offboarding/start-validating/start-validating-03.webp) 4. Paste the hex output from `author_rotateKeys`, set the commission, allow or block new nominations, then click **Bond & Validate** to link your validator with its session keys. - ![](/images/nodes-and-validators/run-a-validator/onboarding-and-offboarding/start-validating/start-validating-04.webp) + ![](/images/node-infrastructure/run-a-validator/onboarding-and-offboarding/start-validating/start-validating-04.webp) You can also set the **commission** and **blocked** nominations option via `staking.validate` extrinsic. By default, the blocked option is set to FALSE (i.e., the validator accepts nominations). - ![](/images/nodes-and-validators/run-a-validator/onboarding-and-offboarding/start-validating/start-validating-05.webp) + ![](/images/node-infrastructure/run-a-validator/onboarding-and-offboarding/start-validating/start-validating-05.webp) ### Monitor Validation Status and Slots On the [**Staking**](https://polkadot.js.org/apps/#/staking){target=\_blank} tab in Polkadot.js Apps, you can see your validator's status, the number of available validator slots, and the nodes that have signaled their intent to validate. Your node may initially appear in the waiting queue, especially if the validator slots are full. The following is an example view of the **Staking** tab: -![staking queue](/images/nodes-and-validators/run-a-validator/onboarding-and-offboarding/start-validating/start-validating-06.webp) +![staking queue](/images/node-infrastructure/run-a-validator/onboarding-and-offboarding/start-validating/start-validating-06.webp) The validator set refreshes each era. If there's an available slot in the next era, your node may be selected to move from the waiting queue to the active validator set, allowing it to start validating blocks. If your validator is not selected, it remains in the waiting queue. Increasing your stake or gaining more nominators may improve your chance of being selected in future eras. @@ -140,7 +140,7 @@ This following sections will walk you through creating and managing a systemd se Ensure the following requirements are met before proceeding with the systemd setup: -- Confirm your system meets the [requirements](/nodes-and-validators/run-a-validator/requirements/){target=\_blank} for running a validator. +- Confirm your system meets the [requirements](/node-infrastructure/run-a-validator/requirements/){target=\_blank} for running a validator. - Ensure you meet the [minimum bond requirements](https://wiki.polkadot.com/general/chain-state-values/#minimum-validator-bond){target=\_blank} for validating. - Verify the Polkadot binary is [installed](#install-the-polkadot-binaries). diff --git a/node-infrastructure/run-a-validator/onboarding-and-offboarding/stop-validating.md b/node-infrastructure/run-a-validator/onboarding-and-offboarding/stop-validating.md index 4b0ca1104..0c3432c6b 100644 --- a/node-infrastructure/run-a-validator/onboarding-and-offboarding/stop-validating.md +++ b/node-infrastructure/run-a-validator/onboarding-and-offboarding/stop-validating.md @@ -24,7 +24,7 @@ The following are steps to ensure a smooth stop to validation: When stepping back from validating, the first step is to chill your validator status. This action stops your validator from being considered for the next era without fully unbonding your tokens, which can be useful for temporary pauses like maintenance or planned downtime. -Use the `staking.chill` extrinsic to initiate this. For more guidance on chilling your node, refer to the [Pause Validating](/nodes-and-validators/run-a-validator/operational-tasks/pause-validating/){target=\_blank} guide. You may also claim any pending staking rewards at this point. +Use the `staking.chill` extrinsic to initiate this. For more guidance on chilling your node, refer to the [Pause Validating](/node-infrastructure/run-a-validator/operational-tasks/pause-validating/){target=\_blank} guide. You may also claim any pending staking rewards at this point. ## Purge Validator Session Keys diff --git a/node-infrastructure/run-a-validator/operational-tasks/general-management.md b/node-infrastructure/run-a-validator/operational-tasks/general-management.md index a6752aaa1..a81b3e3a4 100644 --- a/node-infrastructure/run-a-validator/operational-tasks/general-management.md +++ b/node-infrastructure/run-a-validator/operational-tasks/general-management.md @@ -40,7 +40,7 @@ Take the following steps to deactivate every other (vCPU) core: ``` ```config title="/etc/default/grub" - -8<-- 'code/nodes-and-validators/run-a-validator/operational-tasks/general-management/grub-config-01.js:1:7' + -8<-- 'code/node-infrastructure/run-a-validator/operational-tasks/general-management/grub-config-01.js:1:7' ``` 3. Update GRUB to apply changes: @@ -75,7 +75,7 @@ Follow these stpes: ``` ```config title="/etc/default/grub" - -8<-- 'code/nodes-and-validators/run-a-validator/operational-tasks/general-management/grub-config-01.js:9:15' + -8<-- 'code/node-infrastructure/run-a-validator/operational-tasks/general-management/grub-config-01.js:9:15' ``` 3. Update GRUB to apply changes: @@ -108,7 +108,7 @@ To selectively deactivate the Spectre mitigations, take these steps: ``` ```config title="/etc/default/grub" - -8<-- 'code/nodes-and-validators/run-a-validator/operational-tasks/general-management/grub-config-01.js:17:23' + -8<-- 'code/node-infrastructure/run-a-validator/operational-tasks/general-management/grub-config-01.js:17:23' ``` 2. Update GRUB to apply changes and then reboot: @@ -201,7 +201,7 @@ After setting up the environment, install and configure the latest version of Pr ``` ```yaml title="prometheus-config.yml" - --8<-- 'code/nodes-and-validators/run-a-validator/operational-tasks/general-management/prometheus-config.yml' + --8<-- 'code/node-infrastructure/run-a-validator/operational-tasks/general-management/prometheus-config.yml' ``` Prometheus is scraped every 5 seconds in this example configuration file, ensuring detailed internal metrics. Node metrics with customizable intervals are scraped from port `9615` by default. @@ -231,7 +231,7 @@ After setting up the environment, install and configure the latest version of Pr If you set the server up properly, you should see terminal output similar to the following: - -8<-- 'code/nodes-and-validators/run-a-validator/operational-tasks/general-management/terminal-ouput-01.html' + -8<-- 'code/node-infrastructure/run-a-validator/operational-tasks/general-management/terminal-ouput-01.html' 2. Verify you can access the Prometheus interface by navigating to: @@ -248,7 +248,7 @@ After setting up the environment, install and configure the latest version of Pr ``` ```bash title="prometheus.service" - --8<-- 'code/nodes-and-validators/run-a-validator/operational-tasks/general-management/systemd-config.md' + --8<-- 'code/node-infrastructure/run-a-validator/operational-tasks/general-management/systemd-config.md' ``` 4. Reload systemd and enable the service to start on boot: @@ -337,28 +337,28 @@ To configure Grafana, take these steps: sudo systemctl restart grafana-server ``` -![Grafana login screen](/images/nodes-and-validators/run-a-validator/operational-tasks/general-management/general-management-01.webp) +![Grafana login screen](/images/node-infrastructure/run-a-validator/operational-tasks/general-management/general-management-01.webp) To visualize node metrics, follow these steps: 1. Select the gear icon to access **Data Sources** settings. 2. Select **Add data source** to define the data source. - ![Select Prometheus](/images/nodes-and-validators/run-a-validator/operational-tasks/general-management/general-management-02.webp) + ![Select Prometheus](/images/node-infrastructure/run-a-validator/operational-tasks/general-management/general-management-02.webp) 3. Select **Prometheus**. - ![Save and test](/images/nodes-and-validators/run-a-validator/operational-tasks/general-management/general-management-03.webp) + ![Save and test](/images/node-infrastructure/run-a-validator/operational-tasks/general-management/general-management-03.webp) 4. Enter `http://localhost:9090` in the **URL** field and click **Save & Test**. If **"Data source is working"** appears, your connection is configured correctly. - ![Import dashboard](/images/nodes-and-validators/run-a-validator/operational-tasks/general-management/general-management-04.webp) + ![Import dashboard](/images/node-infrastructure/run-a-validator/operational-tasks/general-management/general-management-04.webp) 5. Select **Import** from the left menu, choose **Prometheus** from the dropdown, and click **Import**. 6. Start your Polkadot node by running `./polkadot`. You should now be able to monitor node performance, block height, network traffic, and tasks tasks on the Grafana dashboard. - ![Live dashboard](/images/nodes-and-validators/run-a-validator/operational-tasks/general-management/general-management-05.webp) + ![Live dashboard](/images/node-infrastructure/run-a-validator/operational-tasks/general-management/general-management-05.webp) The [Grafana dashboards](https://grafana.com/grafana/dashboards){target=\_blank} page features user created dashboards made available for public use. For an example, see the [Substrate Node Metrics](https://grafana.com/grafana/dashboards/21715-substrate-node-metrics/){target=\_blank} dashboard. @@ -395,7 +395,7 @@ Follow these steps to install and configure Alertmanager: Generate an [app password in your Google account](https://support.google.com/accounts/answer/185833?hl=en){target=\_blank} to enable email notifications from Alertmanager. Then, add the following code to the configuration file to define email notifications using your email and app password: ```yml title="alertmanager.yml" - -8<-- 'code/nodes-and-validators/run-a-validator/operational-tasks/general-management/alertmanager.yml' + -8<-- 'code/node-infrastructure/run-a-validator/operational-tasks/general-management/alertmanager.yml' ``` @@ -410,7 +410,7 @@ Follow these steps to install and configure Alertmanager: ``` ```yml title="alertmanager.service" - -8<-- 'code/nodes-and-validators/run-a-validator/operational-tasks/general-management/systemd-alert-config.md' + -8<-- 'code/node-infrastructure/run-a-validator/operational-tasks/general-management/systemd-alert-config.md' ``` 5. Reload and enable the service: @@ -429,7 +429,7 @@ Follow these steps to install and configure Alertmanager: If you have configured Alertmanager properly, the **Active** field should display **active (running)** similar to below: - -8<-- 'code/nodes-and-validators/run-a-validator/operational-tasks/general-management/alertmanager-status.html' + -8<-- 'code/node-infrastructure/run-a-validator/operational-tasks/general-management/alertmanager-status.html' #### Grafana Plugin @@ -463,7 +463,7 @@ Complete the integration by following these steps to enable communication betwee 1. Update the `etc/prometheus/prometheus.yml` configuration file to include the following code: ```yml title="prometheus.yml" - --8<-- 'code/nodes-and-validators/run-a-validator/operational-tasks/general-management/update-prometheus.yml:5:12' + --8<-- 'code/node-infrastructure/run-a-validator/operational-tasks/general-management/update-prometheus.yml:5:12' ``` Expand the following item to view the complete `prometheus.yml` file. @@ -471,7 +471,7 @@ Complete the integration by following these steps to enable communication betwee ??? code "prometheus.yml" ```yml title="prometheus.yml" - --8<-- 'code/nodes-and-validators/run-a-validator/operational-tasks/general-management/update-prometheus.yml' + --8<-- 'code/node-infrastructure/run-a-validator/operational-tasks/general-management/update-prometheus.yml' ``` 2. Create the rules file for detection and alerts: @@ -483,7 +483,7 @@ Complete the integration by following these steps to enable communication betwee Add a sample rule to trigger email notifications for node downtime over five minutes: ```yml title="rules.yml" - -8<-- 'code/nodes-and-validators/run-a-validator/operational-tasks/general-management/instance-down.yml' + -8<-- 'code/node-infrastructure/run-a-validator/operational-tasks/general-management/instance-down.yml' ``` If any of the conditions defined in the rules file are met, an alert will be triggered. For more on alert rules, refer to [Alerting Rules](https://prometheus.io/docs/prometheus/latest/configuration/alerting_rules/){target=\_blank} and [additional alerts](https://samber.github.io/awesome-prometheus-alerts/rules.html){target=\_blank}. @@ -514,13 +514,13 @@ Validators in Polkadot's Proof of Stake (PoS) network play a critical role in ma ### Key Management -Though they don't transfer funds, session keys are essential for validators as they sign messages related to consensus and parachains. Securing session keys is crucial as allowing them to be exploited or used across multiple nodes can lead to a loss of staked funds via [slashing](/nodes-and-validators/run-a-validator/staking-mechanics/offenses-and-slashes/){target=\_blank}. +Though they don't transfer funds, session keys are essential for validators as they sign messages related to consensus and parachains. Securing session keys is crucial as allowing them to be exploited or used across multiple nodes can lead to a loss of staked funds via [slashing](/node-infrastructure/run-a-validator/staking-mechanics/offenses-and-slashes/){target=\_blank}. Given the current limitations in high-availability setups and the risks associated with double-signing, it’s recommended to run only a single validator instance. Keys should be securely managed, and processes automated to minimize human error. There are two approaches for generating session keys: -- **Generate and store in node**: Using the `author.rotateKeys` RPC call. For most users, generating keys directly within the client is recommended. You must submit a session certificate from your staking proxy to register new keys. See the [How to Validate](/nodes-and-validators/run-a-validator/onboarding-and-offboarding/set-up-validator/){target=\_blank} guide for instructions on setting keys. +- **Generate and store in node**: Using the `author.rotateKeys` RPC call. For most users, generating keys directly within the client is recommended. You must submit a session certificate from your staking proxy to register new keys. See the [How to Validate](/node-infrastructure/run-a-validator/onboarding-and-offboarding/set-up-validator/){target=\_blank} guide for instructions on setting keys. - **Generate outside node and insert**: Using the `author.setKeys` RPC call. This flexibility accommodates advanced security setups and should only be used by experienced validator operators. diff --git a/node-infrastructure/run-a-validator/operational-tasks/upgrade-your-node.md b/node-infrastructure/run-a-validator/operational-tasks/upgrade-your-node.md index a4a0d17a9..81633a152 100644 --- a/node-infrastructure/run-a-validator/operational-tasks/upgrade-your-node.md +++ b/node-infrastructure/run-a-validator/operational-tasks/upgrade-your-node.md @@ -16,7 +16,7 @@ This guide will allow validators to seamlessly substitute an active validator se Before beginning the upgrade process for your validator node, ensure the following: -- You have a fully functional validator setup with all required binaries installed. See [Set Up a Validator](/nodes-and-validators/run-a-validator/onboarding-and-offboarding/set-up-validator/){target=\_blank} and [Validator Requirements](/nodes-and-validators/run-a-validator/requirements/){target=\_blank} for additional guidance. +- You have a fully functional validator setup with all required binaries installed. See [Set Up a Validator](/node-infrastructure/run-a-validator/onboarding-and-offboarding/set-up-validator/){target=\_blank} and [Validator Requirements](/node-infrastructure/run-a-validator/requirements/){target=\_blank} for additional guidance. - Your VPS infrastructure has enough capacity to run a secondary validator instance temporarily for the upgrade process. ## Session Keys @@ -27,7 +27,7 @@ Remembering this delayed effect when planning upgrades is crucial to ensure that ## Keystore -Your validator server's `keystore` folder holds the private keys needed for signing network-level transactions. It is important not to duplicate or transfer this folder between validator instances. Doing so could result in multiple validators signing with the duplicate keys, leading to severe consequences such as [equivocation slashing](/nodes-and-validators/run-a-validator/staking-mechanics/offenses-and-slashes/#equivocation-slash){target=\_blank}. Instead, always generate new session keys for each validator instance. +Your validator server's `keystore` folder holds the private keys needed for signing network-level transactions. It is important not to duplicate or transfer this folder between validator instances. Doing so could result in multiple validators signing with the duplicate keys, leading to severe consequences such as [equivocation slashing](/node-infrastructure/run-a-validator/staking-mechanics/offenses-and-slashes/#equivocation-slash){target=\_blank}. Instead, always generate new session keys for each validator instance. The default path to the `keystore` is as follows: @@ -66,4 +66,4 @@ Complete the following steps when you are ready to bring Validator A back online Keep Validator B active until the session during which you executed the `set-key` extrinsic completes plus two additional full sessions have passed. Once Validator A has successfully taken over, you can safely stop Validator B. This process helps ensure a smooth handoff between nodes and minimizes the risk of downtime or penalties. Verify the transition by checking for finalized blocks in the new session. The logs should indicate the successful change, similar to the example below: ---8<-- 'code/nodes-and-validators/run-a-validator/operational-tasks/upgrade-your-node/verify-session-change.md' +--8<-- 'code/node-infrastructure/run-a-validator/operational-tasks/upgrade-your-node/verify-session-change.md' diff --git a/node-infrastructure/run-a-validator/requirements.md b/node-infrastructure/run-a-validator/requirements.md index 69e4f3a4d..0e1bc5f50 100644 --- a/node-infrastructure/run-a-validator/requirements.md +++ b/node-infrastructure/run-a-validator/requirements.md @@ -17,8 +17,8 @@ This guide covers everything you need to know about becoming a validator, includ Running a validator requires solid system administration skills and a secure, well-maintained infrastructure. Below are the primary requirements you need to be aware of before getting started: - **System administration expertise**: Handling technical anomalies and maintaining node infrastructure is critical. Validators must be able to troubleshoot and optimize their setup. -- **Security**: Ensure your setup follows best practices for securing your node. Refer to the [Secure Your Validator](/nodes-and-validators/run-a-validator/operational-tasks/general-management/#secure-your-validator){target=\_blank} section to learn about important security measures. -- **Network choice**: Start with [Kusama](/nodes-and-validators/run-a-validator/onboarding-and-offboarding/set-up-validator/#run-a-kusama-validator){target=\_blank} to gain experience. Look for "Adjustments for Kusama" throughout these guides for tips on adapting the provided instructions for the Kusama network. +- **Security**: Ensure your setup follows best practices for securing your node. Refer to the [Secure Your Validator](/node-infrastructure/run-a-validator/operational-tasks/general-management/#secure-your-validator){target=\_blank} section to learn about important security measures. +- **Network choice**: Start with [Kusama](/node-infrastructure/run-a-validator/onboarding-and-offboarding/set-up-validator/#run-a-kusama-validator){target=\_blank} to gain experience. Look for "Adjustments for Kusama" throughout these guides for tips on adapting the provided instructions for the Kusama network. - **Staking requirements**: A minimum amount of native token (KSM or DOT) is required to be elected into the validator set. The required stake can come from your own holdings or from nominators. - **Risk of slashing**: Any DOT you stake is at risk if your setup fails or your validator misbehaves. If you’re unsure of your ability to maintain a reliable validator, consider nominating your DOT to a trusted validator. diff --git a/smart-contracts/libraries/wagmi.md b/smart-contracts/libraries/wagmi.md index 21487ddde..c73cf8bfd 100644 --- a/smart-contracts/libraries/wagmi.md +++ b/smart-contracts/libraries/wagmi.md @@ -23,10 +23,10 @@ cd wagmi-polkadot-hub ## Install Dependencies -Install Wagmi and its peer dependencies: +Install Wagmi v3 and its peer dependencies: ```bash -npm install wagmi viem @tanstack/react-query +npm install wagmi@3 viem @tanstack/react-query ``` ## Configure Wagmi for Polkadot Hub @@ -66,7 +66,7 @@ This component uses the following React hooks: - **[`useConnect`](https://wagmi.sh/react/api/hooks/useConnect#useconnect){target=\_blank}**: Provides functions and state for connecting the user's wallet to your dApp. The `connect` function initiates the connection flow with the specified connector. - **[`useDisconnect`](https://wagmi.sh/react/api/hooks/useDisconnect#usedisconnect){target=\_blank}**: Provides a function to disconnect the currently connected wallet. -- **[`useAccount`](https://2.x.wagmi.sh/react/api/hooks/useAccount#useaccount){target=\_blank}**: Returns data about the connected account, including the address and connection status. +- **[`useConnection`](https://wagmi.sh/react/api/hooks/useConnection#useconnection){target=\_blank}**: Returns data about the connected account, including the address and connection status. In Wagmi v3, `useAccount` has been renamed to `useConnection`. ## Fetch Blockchain Data From cc374814d005848fbaf903269d8741ba3bbe6905 Mon Sep 17 00:00:00 2001 From: Erin Shaben Date: Tue, 9 Dec 2025 16:15:27 -0500 Subject: [PATCH 29/39] add bruno's changes to my changes --- .../run-a-node/parachain-rpc.md | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/node-infrastructure/run-a-node/parachain-rpc.md b/node-infrastructure/run-a-node/parachain-rpc.md index c3968d21d..5b5ce722b 100644 --- a/node-infrastructure/run-a-node/parachain-rpc.md +++ b/node-infrastructure/run-a-node/parachain-rpc.md @@ -21,8 +21,8 @@ RPC nodes serving production traffic require robust hardware: - **CPU**: 8+ cores (16+ cores for high traffic) - **Memory**: 64 GB RAM minimum (128 GB recommended for high traffic) - **Storage**: - - Archive node: Storage varies by parachain. Using snapshots, system parachain totals are: Asset Hub (~1.2 TB), Bridge Hub (~1.1 TB), Collectives (~1 TB), People Chain (~900 GB), Coretime (~900 GB). For non-system parachains, check the [snapshot sizes](https://snapshots.polkadot.io/){target=\_blank} and add ~822 GB for the relay chain. - - Pruned node: 200+ GB NVMe SSD (with pruning enabled for both parachain and relay chain) + - **Archive node**: Storage varies by parachain. Using snapshots, system parachain totals are: Asset Hub (~1.2 TB), Bridge Hub (~1.1 TB), Collectives (~1 TB), People Chain (~900 GB), Coretime (~900 GB). For non-system parachains, check the [snapshot sizes](https://snapshots.polkadot.io/){target=\_blank} and add ~822 GB for the relay chain + - **Pruned node**: 200+ GB NVMe SSD (with pruning enabled for both parachain and relay chain) - Fast disk I/O is critical for query performance - **Network**: - Public IP address @@ -77,11 +77,11 @@ This guide uses **People Chain** as an example. To set up a different parachain, System parachain details: -| System Parachain | Para ID | Chain Spec File | Snapshot Path | -|--------------------|---------|----------------------------|---------------------------------------| -| **Bridge Hub** | 1002 | `bridge-hub-polkadot.json` | `polkadot-bridge-hub-rocksdb-archive` | -| **People Chain** | 1004 | `people-polkadot.json` | `polkadot-people-rocksdb-archive` | -| **Coretime Chain** | 1005 | `coretime-polkadot.json` | `polkadot-coretime-rocksdb-archive` | +| System Parachain | Para ID | Chain Spec File | Snapshot Path | +|--------------------|---------|----------------------------|----------------------------------------| +| **Bridge Hub** | 1002 | `bridge-hub-polkadot.json` | `polkadot-bridge-hub-paritydb-archive` | +| **People Chain** | 1004 | `people-polkadot.json` | `polkadot-people-rocksdb-archive` | +| **Coretime Chain** | 1005 | `coretime-polkadot.json` | `polkadot-coretime-rocksdb-archive` | === "Docker" @@ -99,7 +99,7 @@ System parachain details: mkdir -p my-node-data/chains/polkadot/db ``` - 2. Choose between archive (complete history; ~400 GB) or pruned (recent state; TODO: ERIN) snapshots of the parachain and set the snapshot URL accordingly: + 2. Choose between archive (complete history; ~71 GB for People Chain) or pruned (recent state; TODO: ERIN) snapshots of the parachain and set the snapshot URL accordingly: === "Archive" @@ -136,7 +136,7 @@ System parachain details: - **`--retries-sleep 10s`**: Waits 10 seconds between retry attempts - **`--size-only`**: Only transfers if sizes differ (prevents unnecessary re-downloads) - 4. Repeat the process with the pruned relay chain snapshot (~200 GB): + 4. Repeat the process for the pruned relay chain snapshot (~822 GB): ```bash # Check https://snapshots.polkadot.io/ for the latest snapshot URL From 88cd0773fae29212d7bb74060128e1a135edb1d9 Mon Sep 17 00:00:00 2001 From: Erin Shaben Date: Tue, 9 Dec 2025 16:17:45 -0500 Subject: [PATCH 30/39] add bruno's changes to my changes --- node-infrastructure/run-a-node/polkadot-hub-rpc.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/node-infrastructure/run-a-node/polkadot-hub-rpc.md b/node-infrastructure/run-a-node/polkadot-hub-rpc.md index b63254c99..36f0105a4 100644 --- a/node-infrastructure/run-a-node/polkadot-hub-rpc.md +++ b/node-infrastructure/run-a-node/polkadot-hub-rpc.md @@ -24,8 +24,8 @@ RPC nodes serving production traffic require robust hardware. The following shou - **CPU**: 8+ cores (16+ cores for high traffic) - **Memory**: 64 GB RAM minimum (128 GB recommended for high traffic) - **Storage**: - - Archive node: ~1.2 TB NVMe SSD total (~392 GB for Asset Hub archive + ~822 GB for relay chain pruned snapshot) - - Pruned node: 200+ GB NVMe SSD (with pruning enabled for both parachain and relay chain) + - **Archive node**: ~1.2 TB NVMe SSD total (~392 GB for Asset Hub archive + ~822 GB for relay chain pruned snapshot) + - **Pruned node**: 200+ GB NVMe SSD (with pruning enabled for both parachain and relay chain) - Fast disk I/O is critical for query performance - **Network**: - Public IP address @@ -75,7 +75,7 @@ Select the best option for your project, then use the steps in the following tab mkdir -p my-node-data/chains/polkadot/db ``` - 2. Choose between Asset Hub archive (complete history; ~400 GB) or pruned (recent state; TODO: ERIN) snapshots and set the snapshot URL accordingly: + 2. Choose between Asset Hub archive (complete history; ~392 GB GB) or pruned (recent state; TODO: ERIN) snapshots and set the snapshot URL accordingly: === "Archive" @@ -112,7 +112,7 @@ Select the best option for your project, then use the steps in the following tab - **`--retries-sleep 10s`**: Waits 10 seconds between retry attempts - **`--size-only`**: Only transfers if sizes differ (prevents unnecessary re-downloads) - 4. Repeat the process with the pruned relay chain snapshot (~200 GB): + 4. Repeat the process with the pruned relay chain snapshot (~822 GB): ```bash # Check https://snapshots.polkadot.io/ for the latest snapshot URL From 8485f3297f61c1c12efad4423b0caa671684fe0f Mon Sep 17 00:00:00 2001 From: Erin Shaben Date: Tue, 9 Dec 2025 16:40:18 -0500 Subject: [PATCH 31/39] fix link --- node-infrastructure/index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/node-infrastructure/index.md b/node-infrastructure/index.md index c6203466f..2c4aa39d6 100644 --- a/node-infrastructure/index.md +++ b/node-infrastructure/index.md @@ -70,7 +70,7 @@ Running a validator requires significant technical expertise, reliable infrastru Produce blocks for system parachains or your own parachain. - [:octicons-arrow-right-24: Run a Collator](/node-infrastructure/run-a-collator/collator/) + [:octicons-arrow-right-24: Run a Collator](/node-infrastructure/run-a-collator/) - **Run a Validator** From 0ad288c9d127306afbbf1a68941d5e065e165cc8 Mon Sep 17 00:00:00 2001 From: Erin Shaben Date: Wed, 10 Dec 2025 19:21:58 -0500 Subject: [PATCH 32/39] update parachain rpc page --- .../run-a-node/parachain-rpc.md | 68 +++++++++---------- 1 file changed, 31 insertions(+), 37 deletions(-) diff --git a/node-infrastructure/run-a-node/parachain-rpc.md b/node-infrastructure/run-a-node/parachain-rpc.md index 5b5ce722b..570b9823c 100644 --- a/node-infrastructure/run-a-node/parachain-rpc.md +++ b/node-infrastructure/run-a-node/parachain-rpc.md @@ -18,22 +18,29 @@ Through the parachain RPC (WebSocket port 9944, HTTP port 9933), your node acts RPC nodes serving production traffic require robust hardware: -- **CPU**: 8+ cores (16+ cores for high traffic) -- **Memory**: 64 GB RAM minimum (128 GB recommended for high traffic) -- **Storage**: - - **Archive node**: Storage varies by parachain. Using snapshots, system parachain totals are: Asset Hub (~1.2 TB), Bridge Hub (~1.1 TB), Collectives (~1 TB), People Chain (~900 GB), Coretime (~900 GB). For non-system parachains, check the [snapshot sizes](https://snapshots.polkadot.io/){target=\_blank} and add ~822 GB for the relay chain - - **Pruned node**: 200+ GB NVMe SSD (with pruning enabled for both parachain and relay chain) - - Fast disk I/O is critical for query performance +- **CPU**: 8+ cores; 16+ cores for high traffic +- **Memory**: 64 GB RAM minimum; 128 GB recommended for high traffic +- **Storage**: Storage requirements vary by parachain. Fast NVMe I/O is critical for RPC query performance + - **System parachains**: [Snapshots](https://snapshots.polkadot.io/){target=\_blank} _may_ be available + - **Archive node**: Using snapshots, expected storage requirements (including ~822 GB for the pruned relay chain) are: + - **Asset Hub**: ~1.2 TB + - **Bridge Hub**: ~1.1 TB + - **Collectives**: ~1 TB + - **People Chain**: ~900 GB + - **Coretime**: ~900 GB + + - **Pruned node**: 200+ GB for both parachain and relay chain + - **Non-system parachains**: Consult the parachain team or documentation, then add ~822 GB for the pruned relay chain - **Network**: - Public IP address - - 1 Gbps connection (for high traffic scenarios) - Stable internet connection with sufficient bandwidth + - 1 Gbps connection for high traffic scenarios + - Consider DDoS protection and rate limiting for production deployments - Open ports: - 30333 (parachain P2P) - 30334 (relay chain P2P) - 9944 (Polkadot SDK WebSocket RPC) - 9933 (Polkadot SDK HTTP RPC) - - Consider DDoS protection and rate limiting for production deployments !!! note For development or low-traffic scenarios, you can reduce these requirements proportionally. Consider using a reverse proxy ([nginx](https://nginx.org/){target=\_blank}, [Caddy](https://caddyserver.com/){target=\_blank}) for production deployments. @@ -87,7 +94,7 @@ System parachain details: 1. Download your parachain's chain specification as described in [Obtain the Chain Specification](#obtain-the-chain-specification). - 2. (Optional but recommended) Download pre-synced snapshots from the [Snapshot Provider](https://snapshots.polkadot.io/){target=\_blank} to cut initial sync time from days to hours: + 2. (Optional but recommended) Download pre-synced [snapshots](https://snapshots.polkadot.io/){target=\_blank} to cut initial sync time from days to hours: !!! note Snapshots are available for system parachains and the Polkadot relay chain. For other parachains, check with the parachain team for snapshot availability or sync from genesis. @@ -99,25 +106,12 @@ System parachain details: mkdir -p my-node-data/chains/polkadot/db ``` - 2. Choose between archive (complete history; ~71 GB for People Chain) or pruned (recent state; TODO: ERIN) snapshots of the parachain and set the snapshot URL accordingly: - - === "Archive" - - ```bash - # Check https://snapshots.polkadot.io/ for the latest snapshot URL - export SNAPSHOT_URL_PARACHAIN="https://snapshots.polkadot.io/polkadot-people-rocksdb-archive/INSERT_LATEST" - ``` - - === "Pruned" - - ```bash - # Check https://snapshots.polkadot.io/ for the latest snapshot URL - export SNAPSHOT_URL_PARACHAIN="https://snapshots.polkadot.io/polkadot-people-rocksdb-prune/INSERT_LATEST" - ``` - - 3. Use `rclone` to download and save the parachain snapshots: + 2. Download and save the archive parachain snapshot: ```bash + # Check https://snapshots.polkadot.io/ for the latest snapshot URL + export SNAPSHOT_URL_PARACHAIN="https://snapshots.polkadot.io/polkadot-people-rocksdb-archive/INSERT_LATEST" + rclone copyurl $SNAPSHOT_URL_PARACHAIN/files.txt files.txt rclone copy --progress --transfers 20 \ --http-url $SNAPSHOT_URL_PARACHAIN \ @@ -136,7 +130,7 @@ System parachain details: - **`--retries-sleep 10s`**: Waits 10 seconds between retry attempts - **`--size-only`**: Only transfers if sizes differ (prevents unnecessary re-downloads) - 4. Repeat the process for the pruned relay chain snapshot (~822 GB): + 3. Repeat the process for the pruned relay chain snapshot: ```bash # Check https://snapshots.polkadot.io/ for the latest snapshot URL @@ -242,7 +236,7 @@ System parachain details: 2. Download your parachain's chain specification as described in [Obtain the Chain Specification](#obtain-the-chain-specification). - 3. Create user and directory structures using the following commands: + 3. Create user and directory structures: ```bash # Create a dedicated user @@ -426,25 +420,25 @@ Use the following commands to manage your node: === "Docker" - - View node logs: + - **View node logs**: ```bash docker logs -f people-chain-rpc ``` - - Stop container: + - **Stop container**: ```bash docker stop people-chain-rpc ``` - - Start container: + - **Start container**: ```bash docker start people-chain-rpc ``` - - Remove container: + - **Remove container**: ```bash docker rm people-chain-rpc @@ -452,31 +446,31 @@ Use the following commands to manage your node: === "systemd" - - Check status + - **Check status**: ```bash sudo systemctl status people-chain-rpc ``` - - View node logs: + - **View node logs**: ```bash sudo journalctl -u people-chain-rpc -f ``` - - Stop service: + - **Stop service**: ```bash sudo systemctl stop people-chain-rpc ``` - - Enable service: + - **Enable service**: ```bash sudo systemctl enable people-chain-rpc ``` - - Start service: + - **Start service**: ```bash sudo systemctl start people-chain-rpc From 0d709489fd345301bf75af5852bd49838ee6fdb0 Mon Sep 17 00:00:00 2001 From: Erin Shaben Date: Wed, 10 Dec 2025 19:43:10 -0500 Subject: [PATCH 33/39] update polkadot hub rpc page --- .../run-a-node/parachain-rpc.md | 8 +-- .../run-a-node/polkadot-hub-rpc.md | 58 ++++++++----------- 2 files changed, 27 insertions(+), 39 deletions(-) diff --git a/node-infrastructure/run-a-node/parachain-rpc.md b/node-infrastructure/run-a-node/parachain-rpc.md index 570b9823c..d79d226ec 100644 --- a/node-infrastructure/run-a-node/parachain-rpc.md +++ b/node-infrastructure/run-a-node/parachain-rpc.md @@ -37,10 +37,10 @@ RPC nodes serving production traffic require robust hardware: - 1 Gbps connection for high traffic scenarios - Consider DDoS protection and rate limiting for production deployments - Open ports: - - 30333 (parachain P2P) - - 30334 (relay chain P2P) - - 9944 (Polkadot SDK WebSocket RPC) - - 9933 (Polkadot SDK HTTP RPC) + - **30333**: Parachain P2P + - **30334**: Relay chain P2P + - **9944**: Polkadot SDK WebSocket RPC + - **9933**: Polkadot SDK HTTP RPC !!! note For development or low-traffic scenarios, you can reduce these requirements proportionally. Consider using a reverse proxy ([nginx](https://nginx.org/){target=\_blank}, [Caddy](https://caddyserver.com/){target=\_blank}) for production deployments. diff --git a/node-infrastructure/run-a-node/polkadot-hub-rpc.md b/node-infrastructure/run-a-node/polkadot-hub-rpc.md index 36f0105a4..dbeb95459 100644 --- a/node-infrastructure/run-a-node/polkadot-hub-rpc.md +++ b/node-infrastructure/run-a-node/polkadot-hub-rpc.md @@ -21,22 +21,23 @@ Through the Polkadot SDK node RPC (WebSocket port 9944, HTTP port 9933), your no RPC nodes serving production traffic require robust hardware. The following should be considered the minimum standard to effectively operate an RPC node: -- **CPU**: 8+ cores (16+ cores for high traffic) -- **Memory**: 64 GB RAM minimum (128 GB recommended for high traffic) +- **CPU**: 8+ cores; 16+ cores for high traffic +- **Memory**: 64 GB RAM minimum; 128 GB recommended for high traffic - **Storage**: - **Archive node**: ~1.2 TB NVMe SSD total (~392 GB for Asset Hub archive + ~822 GB for relay chain pruned snapshot) + - **Pruned node**: 200+ GB NVMe SSD (with pruning enabled for both parachain and relay chain) - Fast disk I/O is critical for query performance - **Network**: - Public IP address - - 1 Gbps connection (for high traffic scenarios) - Stable internet connection with sufficient bandwidth - - Open ports: - - 30333 (parachain P2P) - - 30334 (relay chain P2P) - - 9944 (Polkadot SDK WebSocket RPC) - - 9933 (Polkadot SDK HTTP RPC) + - 1 Gbps connection for high traffic scenarios - Consider DDoS protection and rate limiting for production deployments + - Open ports: + - **30333**: Parachain P2P + - **30334**: Relay chain P2P + - **9944**: Polkadot SDK WebSocket RPC + - **9933**: Polkadot SDK HTTP RPC !!! note For development or low-traffic scenarios, you can reduce these requirements proportionally. Consider using a reverse proxy ([nginx](https://nginx.org/){target=\_blank}, [Caddy](https://caddyserver.com/){target=\_blank}) for production deployments. @@ -75,25 +76,12 @@ Select the best option for your project, then use the steps in the following tab mkdir -p my-node-data/chains/polkadot/db ``` - 2. Choose between Asset Hub archive (complete history; ~392 GB GB) or pruned (recent state; TODO: ERIN) snapshots and set the snapshot URL accordingly: - - === "Archive" - - ```bash - # Check https://snapshots.polkadot.io/ for the latest snapshot URL - export SNAPSHOT_URL_ASSET_HUB="https://snapshots.polkadot.io/polkadot-asset-hub-rocksdb-archive/INSERT_LATEST" - ``` - - === "Pruned" - - ```bash - # Check https://snapshots.polkadot.io/ for the latest snapshot URL - export SNAPSHOT_URL_ASSET_HUB="https://snapshots.polkadot.io/polkadot-asset-hub-rocksdb-prune/INSERT_LATEST" - ``` - - 3. Use `rclone` to download and save the Asset Hub snapshots: + 2. Download and save the archive Asset Hub snapshot: ```bash + # Check https://snapshots.polkadot.io/ for the latest snapshot URL + export SNAPSHOT_URL_ASSET_HUB="https://snapshots.polkadot.io/polkadot-asset-hub-rocksdb-archive/INSERT_LATEST" + rclone copyurl $SNAPSHOT_URL_ASSET_HUB/files.txt files.txt rclone copy --progress --transfers 20 \ --http-url $SNAPSHOT_URL_ASSET_HUB \ @@ -112,7 +100,7 @@ Select the best option for your project, then use the steps in the following tab - **`--retries-sleep 10s`**: Waits 10 seconds between retry attempts - **`--size-only`**: Only transfers if sizes differ (prevents unnecessary re-downloads) - 4. Repeat the process with the pruned relay chain snapshot (~822 GB): + 3. Repeat the process with the pruned relay chain snapshot: ```bash # Check https://snapshots.polkadot.io/ for the latest snapshot URL @@ -403,25 +391,25 @@ Use the following commands to manage your node: === "Docker" - - View node logs: + - **View node logs**: ```bash docker logs -f polkadot-hub-rpc ``` - - Stop container: + - **Stop container**: ```bash docker stop polkadot-hub-rpc ``` - - Start container: + - **Start container**: ```bash docker start polkadot-hub-rpc ``` - - Remove container: + - **Remove container**: ```bash docker rm polkadot-hub-rpc @@ -429,31 +417,31 @@ Use the following commands to manage your node: === "systemd" - - Check status + - **Check status**: ```bash sudo systemctl status polkadot-hub-rpc ``` - - View node logs: + - **View node logs**: ```bash sudo journalctl -u polkadot-hub-rpc -f ``` - - Stop service: + - **Stop service**: ```bash sudo systemctl stop polkadot-hub-rpc ``` - - Enable service: + - **Enable service**: ```bash sudo systemctl enable polkadot-hub-rpc ``` - - Start service: + - **Start service**: ```bash sudo systemctl start polkadot-hub-rpc From 5fb16909e4e845b053cf9d4bbbae94f64a94c243 Mon Sep 17 00:00:00 2001 From: Erin Shaben Date: Wed, 10 Dec 2025 20:12:28 -0500 Subject: [PATCH 34/39] fix full node terminal elements --- .../run-a-node/full-node/setup-full-node-1.html | 7 +++---- .../run-a-node/full-node/setup-full-node-2.html | 6 ++---- 2 files changed, 5 insertions(+), 8 deletions(-) diff --git a/.snippets/code/node-infrastructure/run-a-node/full-node/setup-full-node-1.html b/.snippets/code/node-infrastructure/run-a-node/full-node/setup-full-node-1.html index e71684fa1..43d657df8 100644 --- a/.snippets/code/node-infrastructure/run-a-node/full-node/setup-full-node-1.html +++ b/.snippets/code/node-infrastructure/run-a-node/full-node/setup-full-node-1.html @@ -1,8 +1,7 @@
- rustup show
- rustup +nightly show
+ rustup show + rustup +nightly show + active toolchain ---------------- diff --git a/.snippets/code/node-infrastructure/run-a-node/full-node/setup-full-node-2.html b/.snippets/code/node-infrastructure/run-a-node/full-node/setup-full-node-2.html index 602e8149a..d364f2c10 100644 --- a/.snippets/code/node-infrastructure/run-a-node/full-node/setup-full-node-2.html +++ b/.snippets/code/node-infrastructure/run-a-node/full-node/setup-full-node-2.html @@ -1,8 +1,6 @@
- rustup show
- rustup +nightly show
+ rustup show + active toolchain ---------------- From 5644b858aeed7b2720a431c795326a59a7fa8094 Mon Sep 17 00:00:00 2001 From: Erin Shaben Date: Wed, 10 Dec 2025 23:38:46 -0500 Subject: [PATCH 35/39] update collator page --- .../run-a-collator/run-a-collator-01.webp | Bin 0 -> 119148 bytes .../run-a-collator/run-a-collator-02.webp | Bin 0 -> 48274 bytes .../run-a-collator/run-a-collator-03.webp | Bin 0 -> 70350 bytes node-infrastructure/run-a-collator.md | 477 ++++++++++-------- .../run-a-node/parachain-rpc.md | 4 +- .../run-a-node/polkadot-hub-rpc.md | 6 +- 6 files changed, 277 insertions(+), 210 deletions(-) create mode 100644 images/node-infrastructure/run-a-collator/run-a-collator-01.webp create mode 100644 images/node-infrastructure/run-a-collator/run-a-collator-02.webp create mode 100644 images/node-infrastructure/run-a-collator/run-a-collator-03.webp diff --git a/images/node-infrastructure/run-a-collator/run-a-collator-01.webp b/images/node-infrastructure/run-a-collator/run-a-collator-01.webp new file mode 100644 index 0000000000000000000000000000000000000000..9968babc5e2501fb7eb7684478dbfa92874efe88 GIT binary patch literal 119148 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 literal 0 HcmV?d00001 diff --git a/images/node-infrastructure/run-a-collator/run-a-collator-02.webp b/images/node-infrastructure/run-a-collator/run-a-collator-02.webp new file mode 100644 index 0000000000000000000000000000000000000000..f1c6c1292846a06d93212b3c0443fd36f36eb08e GIT binary patch literal 48274 zcmcG#bC4(Bmn~YhZQHh8UAEDMF56a@%`UUcwr$(CZGArP`)2OUyL0DvU)=Y{i`aQ0 zBTq(TCPYzKtVu2D04dR1x_!+ zfsbIjfYKKM9AGQZ89Fb*$ln?OeqTDmWOu8y-HQY43Frq(J|d0@lDu_x2Q&lEg~5Re zK=8Eq2w?OH@9}OnFcb*-Ne+MpSS$%Y37_}&1?U2~A66fg-truY4+F-4^#S%kN&xnk zG@v#+U=7))cUO1`IPn7c)%wBxzIz933+M$p2_Fh?1D#*#zv(~!dz-aMcwkoY_6 zQ|s&Yai^EKG9c<(;g$dK_R?rh7^!!_FE9WeK>fA)>F^eCxw{11^`rg1{cK$YHbZX# z2Lqyk#Gm1S!z<{w-iO}HfOX;F06)Mku=Z>B!04)XUwAMeAE@%Z2@L-t4&O}%>H?wv zNqXLU?QOu9@H!wU023hoZTgA*wtK(3(fbN4|MdFYd_Vl>T^}DU&PJbwza37cZ$F&+ zf?aF3ftB$1r%i8BHbWlS57i*^Zlo*<)k+(JSdB1#=mueYaWV6a`gsHo3XhjEvj+L? zd%&PMwB;r75b9X2$bXAaS9U1x`*DWDd8=J|>;V7&ocJHpeui2~EiqVEbbIZ@V8;s6 zstNp^-7VoTq^%w6#(PKFehgk4<7r5oA!r!oaWwt0x+8M4R+>@3Qy!(az zRI)M=$6>WI9L}Q4OOdG(*t%HoQofAsE91XDB8MD>=84~yO^8wb61l)NE77Tz$QD%h z4B~0qOX#>MgyVSJ#8Y>CG2@--0zG|9XbtXqvzwOc0xmOk5I_)*owzs1&m@~d2$}Ec zo6TP2c=ZAI_p#j`>5PenOi$VmHZ0nxLRkygmOKf&+Dg`&J$55ahZ1s8GfFDc8OF4m zS6hgxZPccsc@2*wN_qmS&f{gXc%p=7hum`1wvqI*dHGV>pX%?2>8c0eh1Y-B|M;D4 zM;%$ZU8=(%GLJ|rGCNzuBP50(AjHgK1DuJnX!z)L-Q+E5mY1DLvKhdxW&em|I9yQB zSht(a`%N;G=5$U~an*7liki|pq1V+~n(Zws7#pm(So~*hS>T{EuoqhcrkGOL(l=C; z<(J9#x+@DuePdY!(eVjE1kE+S_0T(nGIRGZu`+Z4$N`*-mF&!e&l z!4vDj;~nPD(mwv(H0ac5zODBLU)!-k_(R<-&_FP^!n4HIvLb75%WOgiap^tEL z;0uFgAJ90Y*zIR$!Am39+>w`@fx{K25CzQFqzp>*^>?5{CvuhPQI%7)E6VHnYWmFd&j z0TdHCo~L9DcRiQWeHd2Ce==Ut$=Lq5;;Hoy$dw-li|drJl2Q5iO16tEI%;bkr6tsy z)a>UQx3yNiiVA7l%3CehZz?al=I1fC)Hj=KUv`qj2LDA-|M!o&`;C({BS^7qkhb;y zCWatuL6l@&GXyuat60)H6{$C4*`$1YLUhmEH6))-s)vf$4bt~3`)I*b$52jj9t%%| ze^q-ERY#wZ2U{U|b zLTCS3Q3ofREDngrw+TSo&+vzH`+8w22m!G{+euZO_a7Sk(M|J9Prw5F9kd@lF1uDm zn+)#(1|X=k_is-Jc80Ip7{&2{$J}_9+kyH*Z@UB4#DX4OOCI5`{QJ!6#?3` zOG$cdXyQKbN|xNbOH#MhNzJ-}5BByc@x0t2x^fxzKRQ9rJZ0RDcw6b>E6S#H-Ocyi zzq~UvsYeFw#S$}4Y(YgMOJ(nNCj_|pdpk&DEPLaJ3WcWsGUVVhx0t|3 z4>ZXuQn_pMDN(;Pd&zpIQhk{s6(}0xWjVFXTZQ~lLeO+Z|NeglU0DE}nlfLw9Q%dD zU8!mcT715gjQzi z3R5a;iN)6k0VVQ7EMev^kqGs=3-ZD7yM?9CWbj$1=mg<>cf0?B#mHD(&}kF6_iHje zQNp^TQ_LjU34t~?wG4OP@J+N;avG2=b)E>dFeFsUd!bmjJ{hL4`G*l7Ino&@$}clz zd~PX*GbN(Hvi?K5{|(GkN>wRsxWYBCO^NJ|oxGB`V#k-Y`6L6Jr+XdQ@FvLUgeYSp zZpNS4e`!omk|Hu|K!?-wc5 zf8xiR!McB~NBqqFEb!)?ot9o$?H9^A4Jx8oi1Bb{{@2N3>#n(7QY>Vn1iNT%d@h># zHk@~^fQ?_-O<2C9giSSQSB&Nt@ma8q53C(+DRVN2kdBz$YViM8NK(API7UOby>jT= z@D>}_^IiOvnG{DWD)OYmoohixApJ*6D3J!X?&r&lTdfb$K8N@ z4i&=OVt2knX=`HOpw#H=5m5L4(wzU^u?<(9Ijv01vxRL*FOA$i!@19~J}K83|H-QV zOS1ounpHAZTlCU$a@Q{GIL6NSsn5YML9v0Nxgo8B`bkrBiu>kO6DM#r!s&a2O5#5y z{J(ggk=iDCA+Xxc6Np4P)tY{3lyEQLw! zFF6r9oBiEwZR=Ol@Bf(g8NdDs!+N9E{6c3x*91+A^7i(R z7XP=D{oexlFH2cyfLl+VNP#P8Fr~hx>2&5Q5y>ON732HAC-wiq^d6EQQ+ZimY=F@M zl)t%97XM-N{=@11yWjnf5jV*h=7cj4X~Kd@Ks5Pr-!)RrnbT=>6Bw^qeWp~kzN~cb z;i;FLEzo@azm;0vHj$)I2igk?5=$C)esk-r0RTTW+wU24<8x6BjAnPBRPF}Y#>>p|%0F{^sMND3-<|xe z1`P4*-Ds~~Kjfxhkyzu!=dWua>7EZwt7#6jr64+9oYB_vQ2a_RW17(eTo*I)f90YR z=Yy&2a~sxSDW*k+Sxb@@R$Cau2PSoW&4TTK9ij1K-I)l96EYF$L3DllkjzSnLe2($ zkXu%lT0_qiOBGJ5sEksftDCy#;edr8zJ#BK8$zsPR)*g}?j6td56SO#R1EkV2ESjm zF<9T@%yH|Vc7_QO7>0K3_sd)wqQ{zEG1-v+%#2rxp`RacFY+#@K>aPp&Q#_%Yt5{`V>gf#@n`C6DVNN=8jheL2p1ody&T`X4qE<9L08m3#cAv&WZ3;5P0s z-)I`YRBG{J%BlY5z3iXWAnwAezg_lHU&y{#TSqSMd2oz09;q*GiEVz>*`mK9B)9gP zmeiHCom21q3S!+K6s0#d42)WKo`sF5#wQN1lXb&y$YfTO8thO4ozp7p_lRS&=#nA! zm&KMAmckVrad_m4eSvk(Jy@2gj1$W16x~1^xDpe6XIqpQpfKOmKhX~$t25(z(xBBX z^2RaQc`^S0C8+$tA<^8JmC>sO&^8Ve_K-6VEl1~{&eV{Hsy%lU}Q>~JZ>SYdyi>YirQE*~rQ z_lIAgATpSO*~IM)m5={^H9&z=-_FT+6l1iYRO2DBl%2hL*BtyKq(JuG+D_Wq_z0Wx z#eEvy|N2x2uOe|RMf~jcV~58b{q3ltKE#iKPtQl0$v&?Moyx;%Zq@$_$FU46;O@sk zEY$9eah{L?4T6GVn63J@vfrIa*W=XDTf>+@9Tj`Qjf~g+xmDRilGFEI+i33=7vRd)P z*s#uOc+>;Yd5K#7FSvFN4bn{nM|_AvLVW!wP>X?{Igyvb@*zos&u`L2f6h0W`1CJ6 z-9<8Nli`mK>ErRYkuVNN#7LnyoAeT)1q+khut=3p{ieh=9^V~?C1WDI2k0&IFBZi% zKwA-DWx5jfXVk=~PL)o1f!P9xpZ?-6%01=zg^t6ABQ^u)izGGdxi(R^p0u?fRQK}} zR(4_yPakeY14_7-fhP7B@d5sXlK}^7m2SA)!PkK~nx4kEqt>U6&#OkQH}iBzlOH(K zOvmUmWq3e&TYg@xon2<$&4ki+iY8Q10K-!(Ng?K4&ZAnV!>2=AznA4luhXd|Q*j~{ zC|e7<+nsYTajmcFHuVUmCfw%vJ)afkvjgR~)bRuzrgeQxp-q(2Msk85R$cryq@Wq(c<=VpY(Hjp)CLm!LJaU%fJZIgUd@$Wg+L z??9CyB*yA`hMtpK=Cb6;o0x~T07;jqxaZ;jx3WnvJ*Htl#i`q z$mztg=SM9-v4qd7Bh`ZBQ&s|NWYg?R!5^_zdO6h#8Q?#QkU1KBLQXWt)))|HW>PX5 zG%)VjC*4;C=NdQB6{b%K$dQ*giP2Xxw2;T$<++eHZn zz;F4O4L>UcnZGu^%I%dgvO99wV646{%izI2;d}GLgkDxpVy}V5sl_(>ql~(2IuDy2 z;qqU;(yh;(1&ifzA)4arAHHO zL8BJk+e9pEXY#~u8G?UizISEfr|GPj3F1iEX$ZnijQ-s0qmh}zxikI@n~$q&k8rZ6 z9HqXFSKjP_z_es@N<$EA70QUiu0G?kE|(?Vmul}(uFmjIl)xe#G$}MSuqbIq?TWTBEu-O~ZDz82 z7H`m4midX?G;#NN8BO&AMWPkq=F#<@uH|1KgY0V zm<-12uu+Ox@)~m0Bghoy#9ud&n&2AtSxYuuu8C?O$T?LAV^(k&s9N-Qb>luM$w z2V%ji8v`T8Y&Bx(3m%pEx-kE9v4STE%}ZbLYG-wPDt}V;Q^z;&dv=@HAR2l1 zMf8L7%t$8qZ^xKtdTPGZkI0C^G>xYMpN)?fLe$7G-u#RQ51GM z>O{`28X@_SL$(oI<%tqefQFxPXf%>?wG&BfoQ|JamE-Q6Yps%H07I9MlR}4tCE73* z5MiM>9Q~nnPKPiBmdmLfP4oyw@`?&REqDzE#+fqCFU_apmLHDJZXU%`Upn2jn3prd z8Z=uNIa{;{x9rQ4jWYUA*&sv>lNGmZam1Bdo(IlLlAy^u{N`RA0dLIaLufxQk(S;1 z0Yj_rWHzckKwi%&!@g07skQe@HTlz`xyWAh?`LBPuY)}A-Ke-Q8>v$szI>!{RXxgF zX^2!S_~p2)SyH@v=%# zw%q5+6_6=4+p_ATnYfU|cCFs-Pd_E{d*MyCa9OY{Aun3oM{=mxBup9f!CE`6X&K`- zJ~7@FjTh79j;NcBMmRnqr3$ zguZpJHV(ZJ->{bdr5Wx{u?^KUa}8c~VvCrjP|I`VL~uo+Ap|u3F7)&(!* z_&Wn00x#1*IoAF6CEnyV#`j46kB~`@cic;aJvxqSM2;N%1GaZzpA798^^sG$l9MyN zG{L?sH_!@;jHC!$ar%6_N844&X<^^UYput-$DDWQ$SjS6Cr7zS=QvcO_YGYYJEaF$ ze|j^50K^#|TrR<0FTM@a`L?bbE*Gp>2#rcc#*M08);YbmgQs6oz9(#6=}Qpi*pv1N zKJ%e21rvu!Y;kk59&-3A!Jl9l07U`M>~0;NC5Yb(>{KUZtGg#=nqZ&D8Y7^^AN*|F ze4P8}5uW_N8(OP*koPhWIk<B({dJ0VoQ%*eR?t67 z5OWo&bitMUUz7?QxFo32y)eapsH7*88{K(oS+y!31KJ77BbF)-{M&uL8?iL9g+j1F zgrJ~x6v~uAtJIq89jG<~^ZR^F<10$r9yU%S!ZaF0Cb(9dp1;DI&Hs)O2|^cQQ$Len z3os8=rV8yYqumzgOy!De4LfQ7V{T1?lPPkV=Q%E9AybdzXqf5FG zNF&4F>rD1Br@4HC52y`8Ia<#Cv_9co`q6HG2j0H6twIc@KMh4UluBBHP+{DP}vhf+p zNupMHdQ}OHzkyd4xcq9Ml0AnGx8f$GWT2hs@;oU0ORp7PY4P#RnWLG)nJKwEJN2y% zlUkii?3=HP{#*5DS|Y@!Fn-vVuoHXdjp7H-bk}hu%p>LGUfPlGaG<@#D40iI?*=Sjqs>F%dfZ!p)azdO}W zb+vdnKJk-cUySVtW=6_N0&3m|g6*}8*0Tln0+77J4=UpB7O>_#Q&ssy4kjfdt0RIW7 zeLbk8%@ykBN*%2w-xoZqNjst;U7nL8kqZUd`pR{XG8oWH0yPEgo*qavf}RY?6p`6& z4l^Zhzx#!akdd|1vhSI~FFrH7J$)Y?^`m5a%uF!Bem{ytyyRmCWd6W-?#SW`wE;c~ zvQJ*vro};zh<$AL`(RXY;wyjm=zCYnsjJKr^<24fdO~~-Z)jAeV5tK|!xm9SWDi4l z1k91_Pgt`-^;c*^D3|w5GV%Hrk!kR|_c`p0g2j8S!O`^wA3NIOeF4SFt8NvKglSlB z*^e^KDfA6YzvF_0oHbQ2kk+h86_(}M8(e(tZ%*-b%Jace$$juQ(9^*Hu@l})sKXY~ z7|^@?06wGbduREWa-M)#oK8GfBE+1l+PK>w3LiF`2vq9*o1`0662@J1KnSb^B0aB} z7q#Vp;nw3KI-PW^L-{nbg!#C&6}D*_uPCOO>MX}{7XlVId;K@BZ{PGS^o$MW1qPIV<;05_i3g}lFjqc>wA!6miu^$6 zQXuaKFofmyarb0}z?mE!*Fb$MAe3~g-UzOYP~dOFa{cM$u5XECH!0|>lZ1nIMbQdm zjB9kKD_D&2keQYxjVoLBX7M8f?DNHDFo@~uIv7A|{oekelRZd#R`6G6YHU&y_D3(e zZJ~d8eG9bJQGIg_oJH_@wR}S(xcJYSr7q$wHbgg+|8mE^r#m()Y+hxQRv)KAzY~gjzv*NbTa48 zp0%l&;Jb)_{B`Z$dtYYKU>)AJ0ijEO$x0SlEeU37{ohOdI}Cr{I0^*dSiewGS% zem+WTbiUOY;q4t{196?=I)YQ^Yd@(|ec=_A#*#`+Xq7zvoucEWD&3`m)1%M3n|trG zt>c6sq)hDGyBXyrE<~Fc`C?QFkPOLhWqjjo`^DVqaWQwdd?C%*3dwClXOHr*CZPVD z00FhD;@@D>H}k$L^6sb(Q?w!N;|igyFuJFDS(@yVo1hmT-=Ib*Qc?&hyY?HE-kN^i za_|D`q9_HF#+>ftgY4BjuMc>rqeZ!pO{XEs-K9T_V!PQ6<4bgG*N=DuX>M5;dljq5 zUY%YMhVm0mD`l^fi_glTKxdFS!bK+HXJ(+2lMJ6n$6y#s5jC2hcWHnbmT&H(&9o$< z#gEiRC?)37FM}V$DY$IFqiTg8q=uQG`??K$-jVr@I7w6UGHqq+UH1!6zag%fU^|zO zvREM&e~uZa5qr?JC0U{}-tM95rbi40RU;lZc1Vz}w0-JweF17wlXXrg{}M(h^SW=L zj#M69RMW8(OwO|(Jal!tXE(*?d@;*rCYc97WHsPJ=v8KMDz*!AF{=hi{QcvL{^|V& zo!rQcG^iT>ODP(;(prbH>xt%Vz1ln&{&%&I7XwZ5-p_M}rv}6pgp4qG6s%o=+zX?w zgg%N+u#5>ZFZDVETC^VdS!Azo@7aW{#CyLW4A6vz#`AT-IBG4_enRh!P`)y} z)6Jk@iB*>9qQur7ZQmHGuGa- zPTlnuG%nU3WNaWMJwK-#jWuh7sU00DF{Xgcf_H^a>dE$I)Cr*EsFjm`!5txiMD?5>{ z#;5`BR&zr-v!GrovJ)o8rJ3(P^EZ^^+oDt+jR2I>xfD9s?LGSK;WNWPmCN&VfsUe>O0)SH&9ssZ&2qBT+R#Y`A%wa>gr zMBFyDn38e&##dA@7C0g8pol&TleZ-N4Gct0TCL8^bSr?UnysI=x}EsjdrIxP>VVl# zTqaTmKNNe1%L3I8q17@$kyk1D3SO8}44)e7q*yyNqk9V*H(h|Sxn?32PK>f?_xAN? zD+%F6@czo!|1IE}?P&8#2Jy*9*%LsFyZH;1*T{=eAt*mFuDhzhJC_{ij$swk!bF?A zjqn3#H#+Q<#r5dszligv@*daKY{2eT1tkw@shfbgW-*;1C%$1p+Ru%$X|T^q#RYi{zkmgJ_CKpI@@Z0 zKkL`uLE%5pV$X)kl)PhbWh|@Nx2Fm4<9wJ7w5NW4GGl^A0{2F_?QhB5ayz&X(n9^X zzPKHD7Yay63S7JmaA>h=PnD4FF)w&EkyB0(puI^?VBy*cPL^Nox6@A()4s26DHMfoN@J=X(r@=>NWp!SHI%>@Mp|CX}EsuNQC@Yu4R zWsKA3YN)FMcw)UbVU!~@YgGfGv$$m;p3m{etY4x+4oXl9FY84!L2eS8A1+Ix+{jW| zbyHhuTZRJapvWI8S)wP?+t2sC6Y@2Om=~gOf=;q+qJ@=Tq#5cIg}g~h{0}$9Wf>l$ zq#m7>cvVCr8iX#O+f_7|H5)c*W+?vT(NLVrnMmM7t|roeUAi{xV(6#s%Oj<#dPwLz zhncyatlr$$5fjQjda{KG7jjoqMbD@yQ`WU#UGv}{o`LIM)Uw9Ddhdt7V~$Y zAmy!_WIa70@9y6NpEf^7&FvmoXqW^$b7)8B4;iCNN6*^xdcSLnZXL>Od6@d6U8q;E zMZ}&cQ_W0Zwq}&0gBQW@&%IDacYF$`{d5ZKQb#V3@``(G;fGmKMnfKd%h*dR2MF zvk@oBooNu1FeK#-9Qtu@K)%wwd&E6NK|ox>7=a1GasGP9=WmZIkCxJAgLpKK>2A>3GBhpK zpqEg9LK$3PF@bvXQn0X==dG<2rSul|wl!ms-RwT}_uDrpGLx}LaFInXd)0DD4bMTp zAwzS@;I(!(glF7rv5j^MNPrkV;f)^IhkONxrD^3(knoSW;7jSU*i9^Xx+{A~YBahT zh4cEzfLFP%3X=#^U(%OoEq#DiZPG1JAtnt4?^pj;mKA@W?elpJS60S=blkdGWgxb{ zY+D^_l$SvC(9{f)G@S0=$PCdN?Z<5%Xf|toRI&Pn@Y=uMV+h50IF$p*U^>PXKrZv3 zaQ3Jy(G9;=82pm#Y&p7YChOEusKQ3I__VqthH?4#B&bDbI{}Ek7eh9h%WDrK-L}<-TN|l?z6E^>?HC0jKkSXKkU1KH=#cF4m7+}WY*TGs@-^}uFeuw1f%1Ro73V*clqseGf-Ryxw6q^d`3+F_vQw?54Cu zfo47RBN#Gn=6rJ|gbLXoPy6S`JeuJ<%?UqN5vxBX1v6Tpzkv9HD2~E=RJ2xlpcck~ zlteFkQn|}|0{0+)(X(p%IV7-U%%rN<&%AY^#j)kC59rmF{S!&oFWDD41pQBZGbeS# zC)(6(Ixy2#e`SwQbmgW(8?~Hgms=LA6){Tv4rU$(EeW!p(4fpmMsp(3ltG^PO&DUw zLmI-3Yi9Dv?MQTg8?@wegwl2@kWvD3VJ9r00;gjd{|JG7hgYksT7y`rIX(Yl5@T)6 zMFy>AYdz-f!&IUlxf|C_SgbHH6O*6)TsTohi_xdQd%&&D|bYox{RrrG$Gd8t#N14 zB;}X&A8!K3xR*LU9Hoh+%PYA**p3>?Xz&xAfW(xiUpKeSyWUN7D5 zG`il;)O$fe@t5{{Gcg}Iy9zg<-AK4lKn;nvIv~moSeBrn>AYs2 zz+hKc9~%P;;R{3M1E7+ju*w2mmy}Z57MGv{WW9lnPb#(*awH)S@2MUHhIXI^3>u&L z&N#|E*&0BRVc&<7l~^iyKcsv1XeC-)vQKgmBFA2s%|pJuA!OdJVzI}I>E*8OOh1!l znt@l7@EY;1b13Yn-&=CY&5_Y6&vL8T{g)oOQ9?UySOneke73$+d@(2H8iouQ#5q4( z?il@WVKXXz(pmY-D5lV#yB{A4CFaYLCpq}r_4jh4JfsQ=k~3$w zs#BKESGqhwZ&W^-&Js-nfnbm!{{}yQUjYm~e-ItmxdmTrmMevIntP%Y_$nOY8W#Z` zg!mD;1x2`N`Q;U%=myTe1lxzh@ug`!ReDe#6^we3$5z zc)4!221|sJV}U<7R5QA`ni8vD1k0r`Lj>FWrF#R+G0MY0=dtnAwZ8XO^jhp`1x#_%)|pVQh0T2v^l8b*>W{+ zjIoQ$<*2IP6ny_9fh_15V>}87CxG)UE8X9cRebRHDoXsk+RjLG+;f^BFdWNOFQ<_=$sEM4jw!e4g-)8UNl)~22`$S^Y7v%&nz+*y1)MWiUD zL?5dMPI>;`ed^SylV<|&+Z69qxD~j)hrAsdCtb;gll@v|S6M0c_P|A$Q}Ze+V|!_} z0%P*H?2mSuY392rL~30yYAGNg=7dEc#Y8uIWrk==pIF6?Hw13V%qVEG^ODE#ckN0hRsWAPwXC|yCNjjUb(lw0ytpU9l>4};D?J;s z^J6IDke4bX7WmwkMElv78z{ai@<6R)vIJ02n{zzL9EB~LedySZt!`SbK)0vk2Svrm z5JfLxOV$}4*Y}zWDAAl4o8n%DlDwvsO>;x&m)E2nD5sp?`W&3`sF!WsVOFgrbF9y% zl^*gRwiu~4UnqIuzh)W*V|t!;R%(MY9~b?Nb5BIJr$&ZJCleI%6yccddOI`=v$KZ< z3?S<9!o)W>`Kj_CMB1p&M`LkQtorJ58Q9>tYxK_5&8rfVH%*585gk$QJaE{Hhkqia zj8UqJ0`eexm?i{n)^I7msuGW?_$0=iVMyJ61lOUa-th%jff3PKDjbG?h$z}v*g5~K zwbgRuN|j7{(O_LBc}xSNOzI|dGy0?S%2I{RL2rh|R^|bYajQy(&Mg{d*oboI=vVJV zaJt1_Mh78s8d&*ypiq^&nT(?jfjwSfYvMo0()f@AtrH`ISa>t=DpbhoZN?q!Bd@V< ztDBoHLP`vCOEI>ShQ^6txw0)#Of-{6jf^Krx}C=#g%&wLn8C+J;4Fj{?mju#H>?}N zG()R_v9HH@Uadw2n@Tu4Y6D)c>tw%jKS}99e_a5U=X3TVGSJJffN=TslP3@aQPrr) zWXmE5Wk}3Xt`RA_Gg!3pm&5hbS3A$~nZqA|X@sZbeZq4a*FyCP447%U*Nx(cN394@#q^sDO*RoX|W zB{E$FOsV}N$1HIHQyVTJ*V(#TIIZFLJIG2=pRbr93Fbgh`v@Hw($(q?)xpKp2~C@R zDK?6VjjzzS);-L9n*&TH30Hm8^5BwJUMyP;_tv%Gf&WOvLel2YJrQa8Wy@bR1OClX zJy0=QOz2C>R0uiDi{WFpf+@CY+^kFXgw|l{#`b7pQgZ`iy>BZ2nqwHevABteN+SGz}1|v2GN1%@`RU z&m?}k{U>r{P{~>0Hapr+u&{U`8Ano07{z({#nxjC*i>(7a`k+R9BJN>XH%^flpO{O zuQ3nWH{BzgM}~uRc#Q&tqVk8IQCWK!frub}Ha3)hD1-2%JRg&lDdB}!fpD){p7g%S zD55=sQ!Z}knZmepjG&Z;+gp1zJ)T>@>et6zW$DtYSci`z2r9|xrf)+(UO zE#-2dcmYej@1ukG2V6ncvP$_AL9b+Bpgb}ImHC59+nXILGF!SqXa#*J!kAg)vbFMu zPEQRoX8}aio?YvYfG+^uX`#d#Te>Q$7yf$U+RdowVyTo9ExJnk$9PR))Ob2zR zxm<*=%7_VFf7oI3&gh}3*MTM2>Na#L+|R$YD} z5p~m&O9qWq+|hgVF9(gUJGDCyYPdx~jO4vc)!p(8vwZ3C7^HCZ$pdX7A>X4bn~Kun zgwQCGm;yOQI1qK2Q5267TArJTk46ca9-lwb_<N~xiME6Z9kDT%`A-wK4UBF#}r}$WslILkKXV0g$b9t z!E4w(dpwCI6&5jb=i1g0q8@=_2d-(E20VfmtSl3?yGoK8xHToa%P?h_HY0VodYDfP z0W!}Gwv613D}bFB;#|x^OPddj8aZC2i&#Tt3Q43D*MBnMM zm#KA|bCdnZ(LsI?nkZuCkZEX#+8UJhcXI7ZOms?c;TrMzcX{>Q(io7-c;T<~hn_>Q z@bIAO#&@~pN0LNh#nWm9h1`|h7qzJyiFO5aqMdLiJw>(er2mw* zQgP0|;*!2C65?aRc4Qvi=_ew3)_dni!o(Gqm<#moNHNX|SE0^`;w%6MEeu=N?pw^# z(cbOm`_;Bp1tE2{I;W_G7JS!|S3Hc?NFzwz^ND?kO_zO$eZ18* z@dbSd8p*}L|KVkf@Cb1rtq-7-LJ{-PPpCE#(&VAs9HePVylg~2r;-QB|FZmX9l)Ms z%CwBL(i%O%PPX<%dKFazoMP`P)$ZgTAlt5vkz90*?`q7=Xo+PAwn1Hke(_F5XJ*T+ zKNi&x`^cGzcO@u3S_Sk^#Ib_$GWy}=IF318EyzJeCv4~#Ml zC4H$Io4l=jh&5PWZYHiBqLMADV}pWOM3Jy&CF`lOGQXrbvR~rSN=F0;XD0^9J+*`m zuf$Uuo;A(Q?Z*IYf$PvS^gN;Z_>?Z&#f~u6@iD4F))v0SU;cYb&Z})OT2-eEbXr-K z)YOoqacC=IK>hT(fo`jcy0c{XPEpNBhYFR4dG}+17m!hst&g1?T?2zGJ%+qx3Y7&a zt;{})*IqYdq2j`hMlHpinA~b5I&+Tj6%K+DcD$gMEEZ}J5UCn#EV04 zT*8Jl3hdc3LZQ}Rw_rBruSP zT_0`Sdv$y8iLpO(3o<^RL*Fgd$LqeoDTV-5t9^CsR@{-s{Ed{0=HA6-cyD|tsB<#= zMd4GCvDV#_l$jiehf?R7jb`^lQ<%;nF*3&jlxu5!j6K3&xM{OuiR5TnXaZu~lP&@| z25J-i^+nIP7AlEG6qL*jqe=$>b@YMlLC!AU9Ho}{JY5hJl$9Ae$M#5Bo{^7aTc_nmI_zB#}rP8U{SR?c>s}a zH)2QLWBUs6`vy&nE*C_n*8TP(K)JiK#G7pQpDk!!Nmh&t!&m)JCDWW}`G>;Ey34JR ztZ-*@P*LMBQca>8X;et$4I+_6pYxy8(H0jmEjLk3LZx}nJxNidT8Wk8ovyqpze_dm zung1m?>{CYX-MhDXSt-K<6D7b7}4&Pb?4yNDxukN?OoG)19s^^u$CWVW>3%;1)|Is zuM(Xb;4iWRH@OcL`_n-#g;*5R^t*h!2A!U&Y>~ukil-2-VlBzfy5#5PUWWdU`r##G zkyJXo^N+D@D5?kchb(E zpnAaSYrMQcOpsXn^N%Pk81d#;25)aoQ+2(R*X>NGEfQ!x;dV&bVcx7?gQv`<_B!9Mc5M@?;B))+S!Nr^8xr(!oR*EjZ0+{Fr!0Zqk#!mdljNjYPdR2a@^yf716ivF<9uI)p7OA=!^W`}R;^5UCJ1hwxK7 z;Qs8?Vnn$iphLp`m_d-cf}_n2oEA(#m`KgkzbEHF;LZ&d|K0}#fRp@`BntGBa`Whjkd@LnYP?;)Tz#o|TsZTL%BR1) z=0RWH)7~`c@&*xx2+NG@~3(Ph|bB7k$N(1NmUV%MB9~5C;YV&Jkls*xTJo#GQ7L*T% z>QDpWm&*^G179Fx+bK;b8+uMo1<+?chYgQ}PeB4CXG0JY$aKhb!KmtLjOMwbcIGqdbFmSJ zw@FxPP|uV_Q^mti*PD%Nz@KCRCa#*8K&6e(Zv0X25me7 zMFC(UWsMfU+@1>*6QAfE-+or~Gi#qAgCrGtcS7frZu|e#8I7$8!L=bCR|yQIWZ&EG z!G*&a*T%19J|PgO6lfm61%VYJrWTJ-{ug(yVhrf+?B`g{85aLq3Ez~ta1jClgBAwb zfIGSB4)9k9(;fwApgE{cRP1HXL_a0375ny!L6%n>mU_L{$nptG9$aGRbOZRNDeZtS zEy9b46wGA*9Wn__VC5#*>XJhA=uFQz^|b*>rGjsaOSloK=jm0kjHCFX7}{Z21}yT~ ze*OgW;*}eUFTpLT5xrE4A{#00Q=PmIlQh^5JjY4H@D>8%FPQoZ zle_BP3v~X*#(^hxf?MISkbpf2F-50ZMgkVP4B=seKZTzdS_(dVJ7d!YWOV<`wtC@I zIq7?9XA;;FIV^*5Q}Kl3mCH8q%2s4!{zX_MhN)4#7z&shHH(NO?4eKkm(B)DZz0B3 zsS->bknw~%f1B>uj3)~X$Lh3^e0^Ae878Oj=mxR3>^olBeKB)yL;wWf68Qc`O)$3V zdSmSWOSX1aIfxZ}SC)9tAxk$@-gzv!A5D=AwL7hbF{1iQO zZdDQq<3)}72_LT%yNETro=ub+OO@USsG$byi`t>)ggKjBYDb+)Zvxci<=~qpR2#NA z#FZ*aL9%y9V%I2{LhWH{X{l3OEShcZ~4dQRgBdn{y8dzUErbq zi;#EImu%4%P}Sp}XNP6Rm6!Sd7rLV`9Y}7kmwQ03YPrwSi)vJ4HfN!e&eVqX^oxi0 z++Dx(o`64$)1=1-&6(RM8pqfG0000001Nwi=D+{|0l#==Wq}KKyy8TWsH|nD@{ET2 z;=PL#C+?kyL>aM0p2%R0MN2b?S1p{UW2|HqOxT}bGp2;ZCd#>h^h*ER8DY&8EKsx+ zau1DUV#TEUqT-&K5;RvCw}UZmOIV&HuP}-(9jl0g0zj)_+P0q7@o8eZ2pL)$>89Xwlmjz~~+`0T7DJL?yht6x=W=omc-r zLFA&ABF5o|w;~}vMhkWg<@W)~n#(AbzYMSxbi?5FB(9l&>|?J zfA~MfxRQ*D)Vh)pi3DhWXMR08^}f_hgA@DCC5kK1G$R0}#60023;S4*OqAp8zl+^e zX!n&Q|l*DQ7u>w@Le*R_mI6Kb_J@P$RmQi^Zr-tpt9Y^Hy z(#`rODtJdY000-3nomK~#QkrK^}yfc@!%L>c6&ozN){Jz{4z$|8m`6`_ruyQX2S#L zF0UaN3)4-F{u7m9^HaCl8`Fpmexu!8?}ac1xEN!y^%L63<8T~DLI~+nH`QGwn}o}b zG(b!G6oI{sE!38r{rI{ zwUJ2N_*&h36>^?x|3#-pZOSaHmkTQI`WP^-NJAfguPLsuR#nd{ zr8OH%_OWKYvR-uiLK%GW>+e|Ul%GeDu%`wBLJn#Mfk27d)N?v$cuYu8eJyZfKEaX> z2`fupdn*myDWsbD&$WgM3m#*Y2+ZE@{C}Ov)uQSyhoZ`We&Dx{RFY=azKqpo5>1R= zYn;z@+OyYlx0NkZbvQd^-QjhzWz3G9WP~gDM{bFw_`hk@#KJ~Q3GQ(SpE%w1-5PyW z+z9nrRX`__!SCnzcB3$&ydyYwl#M3Zb7 z-Xsis3!+Udp!&sTCx&6-1|kOt6wq?c@R6}miP`MbP18ieLvVo@3eDV@`OU@7n;Z4v zXlt%UZHXRoIXySHhAp+Tq4W?8X$VwaeS>Y%X3g@8xd8$IQq22aNru!345G4?Ug6PH z+`2$zGGUp3<+(;ZD_%Agkaz<-^Q?xwAuNY3=})0OZ2bTYncu?LZecQ_gRaLZ9QCo! z%5E-^fW3a*+J^XTSmv*GtXUR-MmWts;u(>Qedvb=77UqU7pDUx&?vab%lp+pZQb z=J?_t8vfSHEb<*6P0FaIxGAK8bV5M@*{6AEOuvZT+Ag8O#H_!f~Q4l@6!mzFuMsZDtA?|JCU7og8K|M;Rz z%RZbC+Y5On?zvmC3(;=raNM2!Ux`4EFq;4~eM($vKu&S86=p2<5WKuo8L^iB(Qb(` z70#8}cZl2CZY9O@l41KWWSoY0mO`d?RCnVm8JG!~7=uEy$;9@55v#-Ytn9iuW_L*e zAe?Vq#`N)YvMwJhHi&+)sc|Ff-EpM0I^Zaz{M4PH#l4)BJhqUed6>;hNv$z%#kH#p ztJRQfD=+&jYM%U4O7GGbX+3FK?P{7OoUgY2;c9D>cFLE2NJpvC8iE5Sv*R!UGeG)= zOyUt0Cto&JBZkI3**Qljb;jf_Z+zBrj37l~yx|UfnGSwwW^pFLY2EYD37-<_r5_Pg z;lcZsUYrSDqx8!u{Ua0?u1*br~4h=D)gAwBUZ!LRm2&$A!Vgq}4hqq3?02JQ| z>~31}Zg*C{JE#8lJ+C#%>X8E8_D*)l*QpobE@Jb6C#(9OhO-8NX4@e}OI3D_$}s44 zmvK27z&L1;$FsOb|9%(^t3SnPkj2)T6ZjmB4$xzY%PX@t-d+J(Yu912+gAipZsqP|g;Oo9tR~6#Ot^WY zA zV$kL-?JOPUJg*K;yTg&5f^yO=0GNAYq2*bz`*o&E(lE3yvP-HQqZ_THoNIbBDqCSQ zx6{k{VdX@P635&~EyJfa#L;TegdM6tiXT=3I9Sy8Y*FxJ-Wfc;EI`!k1-0*}mP?l) zrhX$%7Kg<^|B{m!>txUL!6}f_N5>AV65Be)rousJTn zNTe-;(0YxV)c%Cd8WgcZi{0}P)T!7;NkDZwaSYRAIuwvzaEOi6AKvUGO_zoFtjYO? zkUK8VN)Sjhx}S)wk1Fn)u+z86!Vy$R*)SJ!#<7Fh9-}zK7Ki3QShmjK7Pb zh$+<^eL_rzp~6pBQT~r8*_%7Kk>9Kq3Xk|(L2p=S%rM6`4N|6P7GaQ+;f1Z_(M6Jax=dsl0i+^Hwq$Z_iH<=Mg48b?kSowxetnE zD~&)7e>5=fr9|YGy>EeM5W4@Gtttpw+E?=s2&%jgMWg;03Zg28CXC{P^~R5+W;AtT z&yD31Z;NFOk0d&>7+YpSlph#HT?7HtF}^RT8=of$@A0uwUvtLBiAMfQl$9RIXS48q z-7S4#k?4l9D--$c0ji(BB0!o#fU>vpH7T$F00tF7a+OqS zcjyK)eQ;xp3U})H{5j+VUV&$_ED!(y0w}oEgTO@`G-IL@m{dtupYAgLOb5^Kr=ePX zUrm)OroWf9vt7dE*nb!$KP={c{k9PePj>n{rX>MC!4U1`7|tRcTF)p;>mhkdMR(jt z6AzTF@$}po7j$7xVK&Z~+0%6>u8H+btTjZ|yL3u1>1i@YX?6V6>j*NN#x(k%KNQW& znJYUU)I->eS^J?eefL>IK=dc{*@Nty>jM72`Gy{wxePLWGvJ9ia>cJL22lf(08DWKUSI%$hIPa5iD@pIrjx{feWNs~ z3^A&Z)OkAjW7Z543p(Oi_WrMP-iZ+9C(c=w1i`U71Lukz>qqoqh1Oz8nLC|?%Ga2g zHi|$-`clqwH_D7eogB^#MnCs@#T(E~q|11{jxgjcwTYOzML32Tc+GM5-csFPA1_}6PmP{FY zHAo_VuC`f4+1MtbopZa&_u4(E=vx6KRW#WarO8%4Qi({WBD{TGD1>Nh2WA|RhH5+# z=L_9|9oNuRW10vLb2H5MV_=%r-c)23dSn=bMsYFyL0aj~(Ri$S#zZIJ2OpAW3Pis| zO+^iw-$>N7Q)f)okLT6M?)2gL#*C>8MbN!Yt45sXHCu4~)A2 zumXT_N5M6|(1wZy%-s*y$Dh-^_lrxg+Xw_ilKJ7T$hRC(^ND_{|Y!E(!tzScGes(fizW5hyys3%K;-k~ab ziki*MvTpu6XO0qm!b+kI_3M5xaF=foBHvkYVOo$RiRQQ7xe*1!J;2?gd!J(-AJoE< z8i&MZh5n~3gP*f|A;dG<#_NW@k_*^Vr{hoWx}K+qf?=@t0AM#!v^I8kqi6p)2%G4&}+-m zpQ)^F+kWcu<|SIbSn-IIYu`w)Ubt+p+LG}GcUem${k3aTZ9WzWS7_DiyH!oub@ivg z=GMh$G&jK}*7T4cu0*;A(+Jct3hI@MwPVemO~^;p|B(Y7GZ1-%hD(P8aXm z9u4t|xMJIQ^_J_Ef#~DEq=B#4c(qk^AQ*{|nfIfj<#p^Y zc~wSPCPi63v)(-%r(|_l817QL&4igJ(e~(M9t=tM;cZaKCc{~x<0=Ym=+S)qCg*vp zjO~(X%k3E!z6#<$3kE$q8{1jVif=BBLY}LjmDy!y;#78X$8lRK42nw*i%RqS9@i}A z2#dU|cxQ9RK`OMyRG7262;Vcpt@0cT`I`Y?a05TRCBl!=Q9nXi-V;`lsBj$|K znt4d7*OXePv_84r#g~%?Y zQ*O!EV(vxnZ`d^NyKlRgw)&Aaz#zd14#hE8$MxQ*t_bRZW`qcLmlKu)rvIkS!MdW1 zi1>EZLh-D_Mc3{ma;@gkGOxG2BEpun3X^Ovmi8Kj!2c4vd|kt1n(~~YVe5>}XaE4T z*IX!-JdrALg<@8}vkT3HnCv!szT-)uGYL_`j|b03pkqVQVX&(=!RQxx5)#Vl4}LK` z!!={Ovs7&{I5DcphH_4#EOg}+63DrCJ6k5jKkUKlshTr7R?y%6CQf^5QF^#`%5fu1 zZB+3^L<|;WJETSdzU~MjLwMmI#K`{~Xd0feM#vp@pUoXO5@xo*g2Q_`z8a3inf*|I zIi8btN}C+hqAQa$<784z5@5BeYQ zr(x}f5j+Nca^N85BYaOhBnhfZ1Ea^!|2E z#I4BmAm=@vIbM>n@;6E;ts=M zKqV}LKXNR4%ZydYiS){>j!f)PnyL@|Z-RTzub$Intvcl*wj8aHr`C$^1)FoUdRag5 zohySvWG+8Ii~82Xuh_B#&tw5Co0-@DF&7Y|vi9kZ)%ai5nuiVm=#BDV{MjlxJ-(bs z%b}bWUK0kbo2(9Pi|$ZWh;bdjg?-aoL*rSWPfs(3?_@%HA;Q@@p^6*-M|dV)SaDba z)O!_|rq+|(eU5DdnStd!J_6gzV?O9 z&V;U`vJEy(O!r9b#*J3@ZnjA8)Tp7`P{g!ExGW253^c;a*&3w<4!Dd4d8cit6%ra7@T|NFAoCbHKv{ljd*tvBph;{j=iMYK z@W&P#<~+q}kv6lut;58QU1`ofFMOjW0iZsi=VRWE0g;j>Zz zI*`5-y5G{XA!&Em97=aUsp@ZPh!bBq^cW#~G>yvgK{bI4#uqE&wL=Kx*^xDckavx! z^0R&Y(P5BOi;#t&jbJ}7#f5S8^ZX$G)?Y7)reFIqJ|}ynl3cDx1xejhH&fd5SaaE< zM0j9NL5pTRkET|F^ENqPHgpSoZ8h^1+&mos_4nvCGVchhR(Y<6h@DN(X<7=mW&Yjr zkg+Z;n&RP8QlbCH>J;@c0}*ZO7d=Y5vft&bTj#PgTNi&KGi#N@j#SBSgm6Ay}eJ6x8H28=2h$4|IPYjhH}b=D}GSr#R5lIxddcT zMsVZh>D}-_kfR7EYLxR9J=}@=PO;+G1KMuD_+oMezaxi5J3Owb+BAt!*=a398|NOk z8PQtXFYTd#d+OzhKd~3C>?d7Fs}uuiYf$KrE8H7~>i6EYAlPzTr%QPWy_i8%Z~kA) zOY-xPFJO206m8Rr%=I+99w;x;8xUm`IH%5c zX$rC4s?`svn=W5P6s4LWE04aG&mzE`%Wu_8dBf}>X#^U{LJ`o+b#92Rh zDJ4810^xW)r3~J6)_yVYUeKR%iA@ej@wT)r)x2HJzqtg(2?zZ?K}b$^0JEFJXYgX1 zwtOP$D*WCj_aEa}12LOr{S$#vizkLbqdC~P?H?a0v(jEkS*;v@#(|EIk3)`66MgN> zw+F%EuO(VIq+bFU!qfeS(S;kipAY$c?^M2*uM9aRc6G?N63LAR_yK61#wtCsuf1FM zs75i69oCCKrrI(LL3YuZZB+jXJcF$msSW^Bo&y;N##6c!ajeJC1BVJ(bC=ps;!V<1 z(3%|z3V3%!8#8A8)D3P<+XJRbyN&<H~>tr2*Nhg~ID0 z5Y!((dyM>afyb#e*w3Fvf?5m~k^G8l{m!bPYM3d8N;$oX^?H$M&BJTkgxXGBa4?MVQ#Dh5Q(Qs(B~wN`N*5zxreY|K5f6XQRc#E9lkN-()NPP7+>h|gh|VN^&H zg^F?)~pgX%d?fK==mjVJY87XX1*#qQ= z1CkfJDN$rXc@p;!b#4xf_y#^|02ScZx-*wQ2dtSxszaa#CYPlx1yqmrC zMMA)HPAr2UR>??=-KFeT*bZg3Wu~g|75QpKjl!}`7 za*W7IRx%xKJ}h-RIuRt7yqgV|U)lFL!sz2p_@xebLJmrVDEcazyMxMlE~5Z!^$s=} z?#oG|Q*}b`nytjXfmZ}z%$q$A!i5~U$NA}az^X%$y;|CmX5kFJZ6ax>O;r_pBLZ3) zzG~|=(C+hQ(|G(u8SyxP1*;K%+iEhFe$E7kqHAqc1G7!ZH1=zeY1j20T8HKf`&=@f zPr@~imlL=qb!>N&jn_nyJn~m&Sgv{S;6NhjbK|&s@vd>^QsFNUH;?b8thJ^u!`{Q7 zYQ+avz|Ue}JGfx}ly6x&YMScN{_a2s9k#H8!X`m>8l`%S@9a|M4|++t>MMes5;oV+ z+|G{wc|a^CRlbP<%fX2}C%ID=>|e>vG-8Yhp7N6Crq2N(ZL8<0_5R>y2r8bF$q5I# z8^-mgPN}$zyrBK6i)GE7=X^v&O~oHZFjF0YJ%MBUBMC(^YtvRLH~;_%Z59UPl@Q%^ z^2KW#^9L7DZ*nQVK}52bILa?ZAd?jmEA8|Pl{TM@_=QY|v=v_jwUhrYb72Cr=BgB2 zAUoRCQ2VnWgvb;XHztFAq@*ENZfQrzI)BEs9p<9v7S|lYxHT zw~jj61ez*9fD#Q9O)_=tN?n%|LEg39PJSHT2CopVELZl>2d)xBlrx1r!l&IQ~nZV_+G^as=Js)JXHY6LL=jZg+zlP4M>KutaoMvy<& zv}0Nk0>#Mn{T3{ESKg%k+7_Fw741VOV%~Xm!+3@)uJ#3Jv$AMezyt1%y-WYtp~YIh zI1q5dx@R|Bm&AOY?QL_8`!(ZP9-2U3H`5|?4}ahrJ(h4A>95f-%|M3EaMR{L^tqD@>{1QSOplg7fuDOhP|pT|wU_JdQ?*myK*U$CU! z_9j$ap+E$XYN_DKfY}MT)1*p&%G=W0cRHl%D`emIQuV!Yt}B)f?4g5o*f8&s_#c}B zPzyVEhPGJg;hEt5jv1Eu-!^*g&ae+#x^q`X_gBxUTMTRb&Yw)hfYK)>BsGmWvefP~ zRo0ps*Z|>@L;|k&`pa&o5PI2$*kO^yLO6sR8MdaG3nF<%(&CMmFO3UWZes*PMNig(EokN??1@z_z%}C+=gkcb`Qn>lJ-UgF=J4Im+ zH^+(-`=y&HAE#rTRr;JX0Ey+gx@TRqN_9N54py1V@iu+=LxfFow(4p67=`nN$Tebu zH7YN0s+_8dyjbGpntu$+Xw8t?v_Jcj3U`J@K_K}3aW3Xv=@c6+o!|Vks&V^n`KwNp zV%R>4bx$P5@Iu7=#t$jQWDg&QEq{yIHv}979M!d*=~+H*68~T0TR#S$*4(YlLvGHW z;m8JLXUXGXdG;|w+aCAeNT3AX&^ktxzDR@dQu%$z$)DATa$L)k;M;)NupkPuV|yJO z5ld9SFB?zv6L8{TXh;ME=sLqN7$X;ri|-%;sIxH)xmfzP^(x!U&Zbrf6HvUmJEXO5Ie z_RU>sj}RES^6wZZdpo*U)t%*R?q5ZRkS<`ln zlxO)C9e{xJ^p&{$nCSx=3o+az=CMrGWKUV`V8Zc8qkEmr7S3GoAf%O`YLsfwEAu;_ zb9WS`tF@y@d$h%H$f9={9m23WVi4{pcUowV@*cc}re%eew;wR=>F)x=PluF)DNWnm zsUJnF7g2t_RGc=7oL!$w5WnzT^gl|br+KWCNiC8!#JB)#?Ge^oUCK~M{l%leLN19C z5V`&?ip492l~m`aQDOOh@B^M0Zk>*NBWi8JS@Dr4%_!84i#TC40000L-Zi!q?uahG z;N#8v8`~EjlzCB)P70=fNvXwK)VyyJpN@Uo7;2Zm;u6ep1+T0|d+qLQ7nAtmD`{PkhP7oXInJ;^3j3yUwnKtdR}p zk_1X6%2nN)9;}e4-*D6!`r1<>Rk(KHj%KK`%x2h^ebtvbIx#J20^~MaI2xrP8reSd zzSdZ1VM?fx{4mSFPuj)C%jRsmm-+9tp*^ z5k}>LDBQ3`8<())tj-B?P^8~|)QO`@$4UR8toS`x_>y&kh6!4m;B{^fjAoWaj54)? zw@>J(GA`)CoWgCLF|(%XQC$=2nOJIxt#;^?W75)O$WFx*7qXQta^FX*B(+PY0mEm& z2RC>N48@fM)#rUyvPY#MWPvVn5tS=MzCd#V{03rURhDsthd2)sn1G?{k6ALB!Hox7 zM;+vGroKtj&eOP<*%vyGAe0}YSS7o6&YB_EXRaP_V~XLt!K|kHf!{S8BOrDZ5e z4z%PYEAStl@M+>FA_CsrMC*K-e{;*q*Ax_%67U)Ih}>-C1%-N%(u2_N-|Eoy;K2$; z+(qa3ArrbSvs!cg?T5XLbcQSvU{|p4kiL8^%^GN|Mric=Op9P!4?sVX(Bti+g$1s&s*|Jrajb@Ars0%6>ZP^`U{!v%*ngysM z8tf)6_K7ru2<4esv!CxHmLhf_dJEz>Notx?pMcBrJL(lf9-nrp-LJbXnbeW{qWw>u zTU~bJFWd7bj};+`>xXf%`0NKd(EcCnJgS2i7M8w-20)SgcAp55Yhs?#5Wq*t-Al~; zr-g03%5s_{#NLpMw(Y&>gLTh+fv7aX6CLQv4E{eN{Y(Ai(Sfcgi5fg;XS?d%X~Src z^uwQs#RuJgRin%MOj}oOs}kUjS)@i7VG5RBg=E}&ZM+kJ@|it8pq0n0-}kSv(8M5%*%T_?mlw+zh_m~x4N8FQi1W3M4Jn!hj!IeK+L#9;O8ojC@#bss zf!FQ_tSPA4RB-j^CN3}+GrFDMV&1!3#cY))?U^*{TeZ`Hyq-qBp!s3{7kt5!!Xk{9 zo9Lh2I7mALD2rV96*?~&a-(PCT-xppA(yAIGmQSYQGFpHR_xjsrOPL%jPr8e>r$gf z8@IqL$7Y?bu&rzu*3b|D000000000000CKiTNdn_AkcPDK)@rV__v}kgq*$F?3>mDp0;nupdNB~QL=+L973behrH6%h_!8)WD9S{P_CTbM^rpXg_rf^z`@0o=s> zL1Yt$I2 zG4*HqIP4-6K|IXE0g!rBMHXArY2T5Fc z!W?B;{NW+b%Op8a($=?xVb6rqI4&L?h?&l*)sPd6u2C8i2W?xu4HagP+(4!q@Iqyt z7*1xfq;6+wv;12)kDRp;iDkz)e3?wQ*SpI>8a}e3YtfGgxW%$pUxHHK;j=!e8o@7(5x(88)e4>*!X zu_+%ll-4;J<3)MzS*Xl}LkB%0*-F3)_#i-TWiW1lYQUKT7YLMISz8 zwCUgaNP5sqI&>Rc@x64i(yOW~=L9aQ_AwBfnUkchS2YehS+LuG+sG5dpk~yeiX^k;J9iD2o0P;&?$rWfoh#R$M;&c(lhdwGG96&4Fym_k z`j*vNVHxl@C~UHQSgR+We?$sFBBqe?l)f?gaV<1Otu#iQN}bxx&KlD_{N>cA z=+M78(J^NEk4eQz28J&9uv}pH)9y~uQ3n?@zbOZ0&`KlR=VPF~ z+DuzUmrFA+4c^^Pp-qHFtM%#|_XT}?wu*_&d)c6$@DiF9&ViNu@Du<_t#UI>#!7{s z*zk$@ifF3rX=GLxxbsFKK+sa)1+SO#q@bDKFq=EjMQz;*)W7pAgdXKE^q9K@Vq|u? zFX^PMd*UCsW+;nwOw`nmVr2EhpHotqpF4G-Rjsx#r$&a>-S=@W@5I$4?uw>hRuV9Q zaMYV19Oz*H6LXbxH-Rd66VvwZIWp%Go7i?;AdZR^soQgT?y8zA^ELDPce^`jg;zOi zzceD)Y>Gc%n7bS9Hp-;X8h9}9AT@53H~bSQ!m>%qYWE1uiH7b;Z5{vFce z$!-k$9IC;G-q>`~8{-g91g~@$?;Xp4iv)mA_i=6@?n*9mICldap2%89tMw(!plm{G z&5H;(fM*_C=CPuFN-|%oO;2`9J?EIT4t8HqhHS81Mt$DTW9tAn&7u&l$~v793F=8a zzp1~g)M4gpS505E9{WgA^jZ82)MD5Y7973hAnE;}pe@F|@I?>TSBYN|0uq zXhp)>;A26`DUHxD`r{)<&+KH2Ct2|(j^<_w>fVsq*MSb`S5>k%UZ<9ouFPi$emSI! zgrn~d_b7`e;z8gB-2|SQdI&N{miZcj69B17k5vgCuG`M4@gupyx_^MyIpHnFFd#VC z7p!-?OjW0ro>PW7(jj5a0P*i~x_agT3gw~1J_m)2!ip7ZIU=N}<`z4N78tj( zv;pc4^_fv||M(~lj0RbC+DhE&7wE=J$tYp+`2Mz~UFaygB`&OgyX|mNEdT%S)PVyq z3{7V(4k7S%C2}{RoP44!9zU7Bi$)w{fIuJ-{(y1kOT-DS=j6Z($Rc3ZWr1$$y2vO7nJ{81?tIe;#~kyZ{5| z=h7a?SsCmJKMn5pAg|3p0r#L_uA8e>i9}EN52n1GW$tj0>NRwe&T|VlX>|qMPTQq4 zfKM$;ygz70D*VZMu$H5)fNvtI1uWa9WUYJEzhD-;J6FS&k@x%-E5W@p+P^eX}P25yUBrP@J47}Wd zQ95qth%RzMVRn9IYeyft%K`PWV8WjIhi>5Ex zc18DXV#>e2pDY_;)6(9P7->3WC^qVuIcjT+Rq^2;8P(3_a= zS5wWHIo{xvf7zNdc2=qxbDaB&u{+2G;4WXJpc4IbB$p^K9)JodW6M-ZIG))~3KZpC z`<@11BWrB?r@me$tt`^Kfgu^MM}7-JkkmG(o5N=kpuz~`Sk$zKgyT&UF$(GQLF`It z@?FTxt@bezb+)5#?mjh>!!YGN+Pz!C>nbu`1Fv+QK&{di9$Gz?`%UWk#ah{mx)!Nq z;>=-k2iX9ja9pPT6Iqa*WK!`$JG+6i#lFh$t*rJVVwaT}Y1Gyc!6O5IqmNd2f`TO2 z9AF`%-bNV&hdnOlTL%>*NJpZEfG=@1Wxdx}AVix2)Kt7qCCnm(0+qC_=iOo@JmZlA zXg2hD@R`EWa3PnHra#^NYgKB*r(3gL0ooaW?ebLSRC7uhz4p~zkCOCe9nLxF;^+5U z5mx~(K&zGOeNu&jzdfx_GHMdj4Hz2_6%=-fvs!;3j1Fz{5cTPfUj`u{80XAR2>nz{ zekY$`B%>t%4YYi8^ta4A(W}ObA9vlxAN|%j-66$0a-H`{e5KSV0T@~LHT1bZJc;{uuDGkgv3#DX-2A>s^qQLY={{$?JUw5(2AbGoZrT^UQEwbYv&5!K7RZ zO3*9A_k`}?LFx-#X%=d`O{{v88sNHqAZgEw)q(BxMwYXti=|S87`VIXlb1_VbtoZ` z%PsijxS{~3Rm|r3=Ah(N89cHi9Jc)hx!M>Hp1*!;J@&KA{xI+}{}~N4DTF`YkvRaf zRqN@fi8;qZ*q&~Ohr!YCA^UDqE53T37WG0|aXc00mi-GkPUY7?R$dZdGDn)vF&N8~ z`P5kyuZ=d(ofXssom}ffsBey;ttUt~AvSa_%oe((U%>i#kC4Fqa-rT`{E+t~$(szE zBk+R3r68Y~GZd7N2g@7>PT~kflm=Vcp9c1*9A}N@ka^%;*|{2$o5-{Kmb+vN@~YN( z&~K9V0BLao%K=w{cgNyWc3o|JVhpJ3fdL>(I@unB7)oDmNaT02Q+LiSY)Tz_hPaE& z&xRdWac$`B5tU`TO^Q3YH=44ht=^MK;(CBXV>)D)T)uf`3N6{0L_+8k?MMm+MkVzR zC$I!%1F0Yy1T&w*cg1~{XA9Q@?E<-;4Me{RF&6;=txZYJ10as_R|H~M%?8f= zT)qnD%_))8m3%**TQR z9_xL$YexL~7lSHR*A179G%U1eeBrta&Xu$|9@-J{G91jf3{I^f5!nqF?t9M`0Mu0O zbA#K`bk(xlATD(TSjvy<5kYc;aoy5v-4f;iPqTN@Y=&b=`Bj~^{?yolp#8-r`0_+P zv40kSv2`FVutmFwNA%Mqb(Zajh@M$QiL&H_K#Q5JajHW=aU!g%`hw_0DaH|1CjxxueZ$+;hrk>Q`;Oo8CwS*{ z^cgdqn~z)|6yFKjvI%Z$6VDZ|~Rb?wOHwxn2Zn@GU1$b@-& z6~^8?E-+P)o1&4pii#)YFUFbt6iDT@*i(O+AGxRlP!B!O{}mXdH!0O72?)@8!0%O? z#f%IC1HSVeZWr}y95uNRBysG?MK>v8rD6;-8?ZxEPppRtTAtID54@+VVFOvvE`@Bgl7Q2UK{ zh(vtr*%xwzsJ}0gLF!a(kOZOtaU2u1u^p7n^Khza!V*38+MC{GN#=4eb+x;$YT`OU z6t4>-WT;U62}JJtB7V#3OQ53B>-Up2sd>NZ(r_#l{;0pNmk*f}!xOKp&}gVCydj-{ zH7z~?UHqru*x^|BMNsZ|7j7@;Iu!QtB1kurRWB3XFzEkAU6QTbt*bYtc&7SIG5kSN z;kyqo3Dz~1M)Gx1GIIc#;yU=|PHC}dxTG>wn4FXxUGz5*X*f+KEwVo=k&*2Pm4XkGlK}G2?Y>u*Jc_o#)-;VZ zYBgD)v8i_jlp^h)PKqk&A{%`W-8v zVP8f9y&|?Ri!yR+18!{~8xELKWz=OPsN_tyPzwQb?>6FgGNI05+Yfud`QMAj8lOgy z^*>0`3T;|>G9JTT!>W{dN&?^C9Iv+l6gPLxxLh?#1KWy70gOKbs6Dg+GJUHLQ%0?h zRqcVDjxqytcjD3T0o#CnR$kYK0;kiSV{*$m5Uh=)-HKqXIHySvsf5URZl9P#V`DXK zNB^)wOBZ6FA|-M$i-hA>-@4y$JOQ>iNyoM*bidC)IL%qRA%AsiMJ}a&%V;pt?1ZYk z>>4_hD02qKEFu}3Z|zfDer5TXPtXn@*X0f@7id2T-0b>?`39Gw4tJ;^j(doU+hVO? zgmG0=vbyxzxoxKJeOy`woN`T@k_BNmfgPu~aMR;)mVFb~(*G>blR+S$LAg+StC^p% zqsl7?3+YjsiX3?Nifn+XqwrWECh8;&seENeBc%Yx(lWC~wgB;^{@ZB@g|mSiQcE-J zNn8>dCEg;=T$TQ$F6j*P6Ifk*FPpGcmJW7^Y*6?Hmru4XxyU9$JjG!J?Ze%rU+!5s zx|JX-?ydL)FgR#d>Z@s@>DX%MrcORLK4M-(lH6O_XZ>|EKldw#f)lC^RLr{k7z}Ly zYxRO+NAK4&Nc#$akzi5KiZd*N;CmJ6=E8r!R=QxNmzKMdqj7qxN+l8+mp%vrwjE-IWd=gi(GIbU z{&AEi0gu!pCckauTRC7Eqo^+~VB6-J^|vAqtt72?c!n3^zo z!TrTdqJf^&@j(-MHfWI=Gfarj152$aE%+3-x;L`Ak+?5mgju<5Gh-oz%xFO#INera zB;>Mf5D4Gh883W^o$TCPL9${-iRQ=qQfZ^`jpr5V<|v!>VztXGvqT) zj01@py43pQ*=IJ3U5WlYc^O}dWWSooL{^Xh%4|pePCrN0vSoXpe56N*GBKbP<^yXM;t5OK=LEA|T(VcNJyvNG#=I3MT1T#_hOXfW(BC_TQtw0#GEcM5~2{*z#%aK>!Uw4I)5Br#Tv`pMcCg zw%flp&FsoHkx^|L;9v{mn$O}AiX}0OF3yS>sJMN+CRh_t56JOb^~!Xebb*kcLmxm@ z@*JBN7KTyC4^Jan4cIb|4&`?OjNNx$TP&!?<`tgj&|q)8l1Gkkt-N5j>zm5Mc0?eQ z!C+2n&ehy-?jt8)TvzYo4w_-s;iyqj4en9>m*i?|*`$ZZ2B(%Kq4-JnS;t?)AWoHt zH*OST@`LxNo@#U(qASUt#9&$05v$i<&Ic$6FhFsNYIV9^IWu27S+XMCimHsLGo}@^ zRwMZU<#^10^&d<^hu%=*?!<7iqJ4M(8P6F);zks3y5CP&n@8S6!EV&?dfI`n4HZxt zYW1xBY*>AXhn6L|IA-i5kAM|jXBqILwS3)ul9)etRKLZth-1l|2dRwMM_7%81Gu+6 zhR|S-1-vPTHgD!3NvFOWh~x4B|6R(;#7m=Uv6pBZiTQ)~+h3V8r7gTF{z6l4P>3wd z%|725&he%78YBRA@gumAO+pYPhdt2VrK2IfoSwDV@#^d^7T@^71N7meG*;Xf(0>ze z(P1QyS+YIeC0XZ`1%gFbKqk#$8%sD}EnuFug?z)yoQuGCu6@Hs|2$v-I_@?2wUJ!@ zQ}p*+HwjRZ(a_*%nE9!BnjPrwczYbx9Ai?{${Db9rRoxe;JgrL>6fnZ5HxnZm(UOt zUM+Qn)D^IyuGa6furEUdytKW}?OF1-1hBbK%7Q0!x0N7=dp0Ml|Lb>TmJ|mN-0^{j zbtV8!;HA;gTdF5Yg4-MJ-rbhfh&~k12W@VZs+?#hm~=$LPP@+G5YrtT!JGg_sPL#J zlB{>&t011}gXUy8EE|~)#JN{Ac9_}%l*3gfsMPcA@$>mAI0OIy0UCMVRiTXicIS#5 zqp!h}SbbCt#LwJ3$>RI(ONRX$tC!nlP>D&Hkr7|rs1N2 zz*2MW{DynQ<5PD(S{bMO{5#^ZPN?zmrzTHjmgOJd>OQ0b@FCu2VF& zk2zpAL^!*%wN_4EPt=U> z^b8U;5Gsz)+rN8xgShi-WPW*&H!Hw~joUb?m>U*8jnBUw@b#dP?v6jLcB0|559Sd9 z#m9y+Ot$JHMFQvTk@aV9FA8h;O)A*l`c7V|koSUELrfijkawgC5tk}pojee!%N}Js z3{T(nMx{Z;1C9ura&URT+~9XvMvm4s`QZ@2QdV5$i5GH!6)0cOB4on5m74X}BX3mf zho7BqqDUZ4U0{WqIGF66mXG?qJ<%fEq@TJ>JKVJqw z4g{ym!t|~_;H$J11{5?t{GMl+^c0ZlnhFDPwYHu)&6bN5fKBob_7sU>JJW7Pi^OyJ z3WH*(IdxJc`E57^5xQ$RLx=EI4|AQ-J5U`|_(QE%ci0PUVV4DNEKUMCuc)@a8F(B7 zte4m&SA5MsZDlKA?}t8^^&MP`R{DfukLEF2!z!`y3SpN`|7lQQ>8Q|3ZJFo8H|2Wq z?1#2331*D?+QCs%Vujs)^it+~Td5GQ9{^5h26+Tiqiqa|DIwz~NAkYSWdw!TGmKiO zv?XOR{H4@r;%}SYhjlw3t+Y9;g(%kq;6b8<2tq)S;(WfbN{5v`vz2cg__TXq9qYDe zO(@GcB6v3mt_3uRe{Y%9WgkZ>sM*8WcV?4st);xndTh0Ga|%34?2-+Q+t-1_kO?q| zJO@fvWWXAW6rq>H+mL_K7$q;5aX$cK9bK9iA6I7o=}WDP59~uK1lwCyvr9E=?t76+ z@?+mcyospp4fVc1;fERoYrwzN<(OMT=fdHhtW|F9SFQAXOD{nW6BS4m9&GD4pRl!;g`A2z~ zXN>e}CZaiyWrQUfpnH-OVC&1o?~!kCZVh6x)S;5dp%%Bw2)BNS#iG@QI+j)j%N|Ii z0XhD!5G}NFZD@Rc{`2bvz7^qYu zIrH_pWzME;n!%x0y?`}OU^_KvPwn%yYn!=^3VWFh7(KX+`8L{c6dKL6SO#@Es_PK$ zFeJw0LGl6F1IjOH9OQnS^KX-H0)xFv5TM5q5s`xJ^_Wt5W4S+z%m(q$ zh+Sy$Xcqwuz&BA5)NU&6ohX&%c}Bhv2GIuZ3ml=wp%CxMK*Q*Hog#)l5LydXN~SK) zR7Ujr(!)`&c&n2D+5a!3uO`DffnzEwIZ(c>uW(7sxzUc)j%ypq46Acl$h8vp_u_w@ zCpe07Ho>Z|a45d0gRFc0yL9)5tBF>7p^@2sls}|I`zR7GUP5Wvl079-9i(wb&5@>W z>P+(PGiD}D-N&g0z$c}Y(+?EWLCvq>8EkE9NJK>r5SOmYpr_p}X~LX{CyE5``&+H_ zOxW}W?IgATBxOd+w{DC0Q@0Z6W{qoRL64+7orYz^XeUy<^-!AtAK9{Ms-J*t3yVC5 z(T7pW8Us3-(_9Q*%+)CslJlKIL>`@y-y*xnkV~g(0xH$)Z9wzQA(gZS-0#0~62>_? zY@%ubIYPRa1RSfSh-?w-@{pt>z-!y50eN;#5na_*Y+g%FZ#CeU*cow`s0xkOwYg3$ z9_8`};l{a#%xj)Sa1XIIAa@f;#twzm;H89&ob*6P-AG!To_xGbkQD9{&-2sQm7|)) z1Ay~xs^q7RDW-8g`kaa%O1+HfZMxfkWLd;RF5+h&QxD+7;ElDOG%+yR_+2wynbWlM zpN8Tp=pE_Sm*icW?v}|i-DYUzuIgB$f)33oC+$iZv_ns<_mOlwT9xD`Y4 zaC-znqs4WzMZOR$y9M}`0O<M0a?pqJllRBL;z)d3?O|z zl%nu|80mE52|uT-%2D}~>U0E?g4pBdFNUOC)y2!)EZ#e{-HQmfDV6m+x_R*bX)ZCo zqo^NZ_x8DY()=;70vD1Eh(_rLSUhyjBDz{XiWTGef5j6!Ju>W-(rPr<#emeZ*#uX3m z#us{8JBT2idH7&kF)(bmQiQ0NJp;LSHFs0+fyzBNyckH;>2)n>Uy@D&C}TQ~@<3~Uwb?yX zVCSgVn1NEId(0T5yp!@nY1`dL_7x>Jj~`Zo>pxtY&}ALak!qh-rKPmI&pf$p)hN)f z2O*7IVXYPl6hw0oNDVs%l^BdNo62FTx)Hd-FI?`fZIhEA1P!8a?`6t%MI~LPTF2;b z07m^701T!1APfoOJ7Pty*~D~x^OyYnC{`~og^WdIu5OBLz{w=zHDk;m55-{bIP=(d z32NyyAl7Q30C^vvIsPg+#ykGwgZJXmoHItIOqULi@1 zYa$x>1)5xhBKgmh91zylGuoNg&N3?{g)*~OEjmZiJZgauJ6=e+NTrqCiIu63sNPlZ{sN?bi$C~Um(@*EoI z>%~pg`HO7&W1#+F?LIL?L=GkX_*e@348iotOUZ{`Ou{e)pUyh6JAXjK#jgBZWBg)N z7W|Rd_UTOc+%Bq-$9Bb1(cnW1LQ$c)R^sU;wpF%v3&JLpAaPEujMedhFV$$8g$J_~ zm1x_ZJ`umsDxD$bHr1}#<@(1o@FjPIuGs=a`BTlYTdlko3*{l>7I z1O$z^bCIO;+UGqQSl^AEn}AZN?|H7#PyhfX?fCvgmJ@wyt$$W`yIA>QQ7gv)CN|r% zL{qq#Z~DluEV$C%XHCb_0XTo*y0#j4{6D#)8R)wo|5S+DD~gpaz^d~}?|8=>JXZm{ zvoz_Amx%EuuMvTqpqV8YMut$K0^Hs!9Q2}omk}#3mrblx+ej>D%lWO#C3w<#$WDBl z94Kbz6jOf^fJU>|UzjW^MTD5$r006t$U@9**ou+m|66J19?Sl?!PhB9g@^8yAv_{i zKFNt@%VdUhav=k>M@S*r*#9n$$iDQ2Q0bnJ z*h3VFbIeQrPvR7gIyLqM>j{viRoQfCw?w5CAEH|*R)FV5q+NA?H>*?(wLK7NpzyJUV&v&WnW#yvb z%jh|>xE@i1@JcR|X1uZ7pm_G@=iB?Gr?KD&8)3sT7t#>3WIcyQpj-w2G#;h(7w@SD z9$3u&K?|s(pGpkB!Gf5UcnLhj;}q8TbYEY^*Gy_bHU(QY!-3mWF;`8h5Rx8=EzIHZ z+M}Gr-gs>_sENanZ+KRK;RI(Mb}3GJ6ZG{aoe$7t35}abekag3$(R9n@`C%cTd`q! zEY(p<0X+MRjn2Qhq+4IRBVBbJAKGSEJMbXdw(nBo*B`$H+4kqDTKC}amjHM`Kj*>i z(^=X;IWi+oh$qgfyQ`gg|3geqL?^qrb>8gykCNYY^a9EohL2D^6!~W$X3Tm)5D+h^ zt87+&G1va_$=qs!(YDMvlK#x$6Rk&<)nxy(NIocK%d;o|000020)=59&$0p#yg{t5 zawe?cST>bnDliI?E>>|d>%?UHL=<$=6T->jmx(Ae`JO*109KK&d17C>&J7IHRC;{| z;X{oF$BaY*biUR*Y0F?H794kahm)AqrHHkh6dC@}I54+ns&;~%Ml`*K25sa;S_8bt zrJJI)KGyjpH(+d^Z(#TIp}j35`iOQ5N>^)|`vJ88I(TYs#)Mu$-2FqOV9~ogIBqwZ zsY;_*V3lZq#VXKuu1Zm3>|FvLL(7?I(3TF1GZziw@6S|96fvErDMnRp2+YR=#hLN6 zc>e))`j_f8^c~w@#MzX0%vGV?r`)AZS2;}Xb zF?g-hv^@otm-yNT0&;ldn`uHM+i*yAHGoEn!!VjidpDf3Dz3Rg@|njy*=6GOMjySA zk1-`C;YS1MR1i*h#_KnYAtGtrq^m%js@hPAHsqUJwiQZqstGzKZ#jm_ZbE*cJh|lCl5M33LeY{vC|2REhPE2mT+m8r zF#rGwd$Z~2&y`788vjdJihMp(*`}8C??8QO zeakPs(okQ0(zMh(-92o@4dDHkzYgNO&58NR5v~{5yBrrt9Ta5)V-3w&p-_i_aoIxs zJBc*AAc$^sLe_%z6~1(k4&HhJeV-g}{sq9(0-}O=GQH+@*%hzVn7j za?NxzSeH@tx$}P~1525PMtM$-s2Tn>h&ZhOR@}04Ue$aVf(cn5&0-;f#`ig}AgB7% zYOTZuXhec%s^eNe0F_zj-<8OUGbNXbN;|s!*`K)H^wix?UWF?hvt(aMK?S$DF+0685H8&VUo$OzzX3eOK5c+2m&yLC4}qnG+p3Ac%O6>CB9@T}%RE zSw~k8lVMT&^j4=m@$vOrk`6(1HXUXbM^Q4m3Lw7#Yz^dJ6_eY(@U%Op&?~`+TpiVr z??hRi`F7Ywl_vRpLnhp&Y82(bFFK=ROfDA+k$w~msyG&kgRJ)S_virxcE;HhRoNMX$WBr)U6gPrT+p<*!Qd(V6sZj}`EJ>oU07Q(J z%fQ)p(o34QYKZgJG;@)OM=cN<0<7U>7EOh(c)TfUB^kX)g#Usnz5g)*-8bR#S{Lvx zoV$Hcm1yEwnZK|6@{G3h1LBM2#p9g$%XR2&zN{glQ05F5UuwP9%bBdgq-@k5c`YL# zl395B8=&8Wh`9^(HQuqnKNVq+9-hYac=)(F-f?gS3x@%y0002aK$q9jSAIokJzGkj zfR5?Zsr&S3%Xn@r?i^@XpS1Asz_A<$N%@<_8nZdN`TQ=hD@K@jXbhK;S~5TXT1vo5 z%Hz{CaN|Z%;Tv!Q{A4U*1Tz|Ft zJ;&QZ#k@IFfKnC^I3f@7{pcku8EL^c+AVutgBM-+lV#@Rtsh@JQ6fnWJML!H+yjWF zKo8?Rtx@;pJ^YH68s&K077_2NBc-tQ;V8~x-+Y)o>Mr$bN|`wH8UZA6Fn`%2tUdqo z#>rVgAtT&Kf?a7Nym^oU=eHOk+oX$$p^M}gr;JIi>_y2snJ_25q-|5blO8335v>K_ zSSoVp*Wc{`-^z16sl)M(lWLvuwU*^C0^9T~WAsv%kHXQY^ljmR^`?80gx0}Q_ZLn$ zH~K0=OM`&<{82Ag7(dY8CMjdks_fM3!yyc;c6%5SV8!(z|Q8xX4+yhM)&9IcLej^6YM4| za$q9{?8GO&A2SDbP_{1#p{x-XSn@A5S@@-n3;1iYJ&6}$j0dgcmBon}Kf$R0=QAW)eU zO!C~!Y~i5hBCH6+ECbGvKYJc=PC{@3xhM5pgt(w=(H`WRZx>l>jg)Fl^uas9JJ1CD zPFtG@mOScZ z@Aq*TZ!)OkHN_|@(m-B#>Hz134w!ZWxQ0Fen_TLMS5B-{Wnuae$|*|E_9YI^Qq->C zJIC#0n`o#TRNg*7q3%7kKWZ%RsuHRUJ2~JaK0Huht_a{4ubMT2*4R6NNyysVXtE90 zd*|)8#Ev!}ehko9pT&@hgfp61M#LY~IoV44r8@4de$N5L7Qy@<~N zp>(xZ2PUf_@GPG+eOZf&@l7Lagr#{I2h+y!HLqRVb-b!e>o4si4q$*fn9l1)qG^pd zz!xFvCh{na;gLLOn-%IERp^M??B}=R(8qa?LOOe)#r;>TICpOVu&J$H1gpFoqOJvj_$nrnLJxzhX4IB#RS%6lKlU+1KQM^J+p zePuCyX5oV;!)5hxeV%d!zPbu>DOrdb3YTHoJls|vR0M$Z$bfv&@kV(zaqjTnH6wlMM~VZPL}IuO(TQwub*Gc*`Q*uBAJQV+PW`?5F2`fn516Fh^^=t^`nB8>#uDGq(6Gc7|g!O4(fF}USJ|2;matZH8aUb&3zo@9Kj9z1D`1t zMuWBcz(Pktf}~BGWo=a4Ti%mM_#{T0L-WrJ!suTj(UxyBx^pUN;PtH*x4;4&Z3Y@K zgctX6cZY0pU|bQkTTXn?(lhW0%Yl>9c_AkH3x0Nw(hB34fto_>N0G+*$%%bK`=VBp zw9FI@HX4QT4>UJeh?e=!{BX2<+ghs)>{2d#?*SqSA>@&p8L(y%RD<9a!9#KR! z!_>ASwau3jJ1-xqVPDT!3O}~aH`_37S}}zl-sntF#AJTG@io(@WqM3z>ysWU8-lUI zT~xUki#TV3n@l39Y}=AsQM`Gqa|KX_@u@v}6!~4Z0rbtmQnY%{nn6EPr;|Q8*&Fl! zE-YfH5&Yk-&z-6D97FeEbsSiZFYcE=lW9EaF3;&76TcsWXu<;P0I^k(_H-XwJ{03j8L%e*pA1*? z2EhZ+yQEBV)K}rP4Ae$op^p=Y4-AqlX=gd;aY=CmQ8VgG_no!}2V zjQPqS>*(5^*Z+4a{j8f5YZmIry3Xvq_2z#s>v0>pU5vbqDiuNeq+2CL``rr_(R$w9 zIeGN=4iA>iW=*|z$U^~6`^}ehQ zN~jNaPK_XwU2j^&MmV14!QzzVY*5hS?0*Xm0x5rs1uI|1kjXxaiH&cYZ}2+NkA<10 z&K~u}IHSQJW?`zNC+0Lbh}s_LlWp&bQpDJwcc!+rbE)oHC^LeOmxM?4CBy{M*VWUaX3a3S(i1ZcG`PLxHT{j7HJdn)7^;wvKaXUzKfRDZf%b)=5PRUIu--fS# z6z>z(H&}qOR1dMy$oMNU(CNg?XCgLh*dGcK`Kj}7-sT1y>$<0pR_Ji$!*HSvHW<{w zL{DBIfG}C1eK~2c@cK)Q&bc35LVWt5%zN5@=G-chQ(nPx9dx+urfP#%c=T~J)=Inl zg$DN&pj8|HnI)Sk<(Y%j{A!UDAvc+6H?r_ux(a|J)(S@IoCJ;%fXRYavC4GmWVpTp3kyU}os{)xo zPh{(~t$$^lHn8O~w>H7&^+ElJ`0YFYVVxlNd-yJ;5_$XTt@ux;9!XbaWpL=UgCMEiSj z{awN0!5n=21f7czI9XF=o9(xBXXbYaoW>ro%JhnYbj^Ru2XHi+?l0g>!qU5J82w7q z<+rG`p_^QzUdS$&e$qQ8Tlzqt^&lzdnQdj{nmU;(oBgkkcMB%4&=}hATXDv#{H%36 z9J=hgKBw=9C2*E+y+bBsnIy?>G;0xIK)LCfu2KLUahtoKKn@qYVIPcN!Yji)M8FKpQ)!=G8jD#)W!7001QYB1<`4JX-Y5xr1FiTJ?(Y5XGzQ4E(C(p@=+HtezNN`RhejE}tg*9{6l=U7%?n1IHU*z9; z=AKY#i0hA}_X*C-!N^M}!=@HSq=n7^i&7RiS^5zHP8}+g%{B{jDwMKS*Z=?k00000 z0003k>3DTCg$>}Dg+qjB^C4WxNdw^PH%bscVH#~VpGd;l5c8l{;62u|dk>Qzz(yogq3ni#elnC~dh&kxUAviBuhbG~WMjf6<}6Pp@k zF6%iBb*hT1&*JGQ_uMD~S$`UVowdlLHgd|aZ27~x1op4lk}KK|kLUk#k*Rd>T`F@i zz$?kS!A>oY{bVY>L#5}G(H4Sft*}5wL2xiTFaQ7m?cR;3uW>ag^SK&WAX2Anf4bTj zz9-erPVjA)h9+m>R)(u4DClsuxM`fJ8Yd{$UyzbyVfmi0eceT1RDLa zLXKXn53`~(iQgFBp58i-u_{GLskeDXwJKvS!i5?b>|&P_#r}-wZ1wK{npXklDmsEJ z+k;=fn=j|0Z1BW+6Lw<>edAG^U?g%Z4S>GdmN$6tA08AsCZ!JUE{Gb%VsjTG^th4j z*b-;azR@7h<>_rpXrxQ{3S+Q{j>T(-u6s{SSvuSrVm`O!y?tqOGN32=CJIes^=!A< zfncpBS`>ynq_H0q1+&hu%E%@OoPrYiB!#pR30GpL&o}hggSv4WqaJ=pyHPR=BzPo> zy+w-j#1Yi?UH&6T00004pd6jFsH&JR!Hd(eaw@xxHrfG>LNQ<^(*vpow%0W;auP&M zzbueQn-HxIlQPuqb~D2aqgQEn$Qb$ThA^HpIATeC$zAg7dc$n^A53`%jb9qzvuvTSftHxvt|9?J7{irrfiVRQ*Z zW3mX*!t=7pu8hokHCpam%HuutpQ%6!afn9a@Be}cfe*ihHx&t7E)_+adV$Ua4>qP} z$JJ@GUTW;PGY@<*&k{2GWR)Sm^LZ{H0pdKJiFR!_cue60Vj^I3*o)f4n4G(1=-SEl0tNran@?z?Q0GWCJPqp`^7 zavR1cEs|mNg&53<9TqOf!%G&CtgYBGz&y1h{Pt%)gd%?fr*b{{7BJV5wZQcKyBCTo zDHExifa^X>P1=3d*MT=z0nrYzDG*sE9#DZ)aqThlVT#SqH&pZpMMI zeu=|@t^k({yJv%W{Y`-zq#|k->8Uh{q)j4_53_T&%>CUC2R!sHtb$yZ8-*@@7T=3k zAaZ(@-aQJrV-l|C1CY%lhEeWSdA^ZFN={tG|lLyMYyb#@m^)eLtBuVrT0@5BJ>V9AS2!gEsazL`1 z3ND4%2=dIsfx75i3~kRkO@R!~b?Cw1i{0;A?RfwIPIZNSTb($f?L>KC)^9bqht|7R zZe?Gx$5767C=R~uqOn{qDk=s>G}pW*OJw0CswT;dEs+y->NtNy_B}qPK7Z8OB zNelA62-Re-^19PmI3+AB3<5nB(2VYue(fM+!LPI=OEM>tM8UH2lCKU?sPxg~eu*uE zuQ?lv_t79JFIG?dEEJ^JqHX?XVzT~Qffcd$7n&I}RHzeG zKUhQoHgj*ZA3^QSE|hpSjoL!xWX<(0u%`0{-^ov6MHsDdkV&@BNR(KrqQe+lZc_ulZ_)#0Lng=faja&} zT!5z7=k=ZuaDC{6Gd2OL4pN}a$H zAfpIf+hUS=mxRm4Hw!@X{C{7G&5J;KGl3dUF`n!WvvzCSOdRDOuv;-B)5Tf>ky+dc z=f}a!AeAz51%~2&UiReS8q59LO8CXFzFU(+!UQ4_yT&rM5Ia#)ZNRy$Bv%-TvTZ5k z*?SE+vp4`b3M^#6=#5BN5YN=p38APb1iot`!N3CpY&GHP6Q;Vae=O9-GC{5myzQY+ zd`>jMLWo5`g#^1Tt=~HoEitZ&2%>5bE~^EBp%1Rem?O?lROqY>bRk!-8?n_l>m1w) zido>aRV9Q9)41htltc7ZBclJHPrJiIJ;pYGajE;Q_g5KH;E8X0)QtG_IOc*@N&XTj zJnu28&vjbysq4p-ui99lNX*7*_;qvb1~fdIyARR{w|bQ-%QAJ zqwEAT1~Cq}>qv${9}iVmJ&tFVlLR(7^~WQ5995{V_{I>7%CsS$^Evt(o64jz6{DFd zhpG+$*sLxZc@(@IDw1Py^}RcHET63X*V1}VePI&BT@9RdFfvG_840eoMvN1$+;bdI z(1C^w*y%|(rU2SWf#X`h;2%mty2v0^)8(NElaT^qO_>+ku#I$S;3Ici%8JFkaW(Y{ z#V;VI4)6L)Hqa_Z@CRq?2I%?mydMrC-VazZ8HlM~k1qJ4#M!QuTrtNJS?2Gx+EWC% znDN?9O~k~(aM#z35k7j8RCv1OKQ^7%g>UcU(Az`R&``)qvmx|?op;RiB1aH)`voVi?AKPHUpTX|l3jgOgH53r{>8_vojgQz#yU$L$&n$Hc`^@n*HLqajO z&S*k>qa(O5HyFK>xD1Dh`&lL`ltY~eru$BbW}yW!+k;4e$;!}!dy|EyTl@%#Do2U$<@f`i;zFAc{E5jyNd1f;~qaDqzG zHQ(|n%Cixqnz2GoEFHEA`xoF6R~l7!Vmk?r@AG~3D-;8sj1J0Lt-b4q{B^YcfP=#) znD)s-K`b{1xP=0@N{JR}vR#BUi7eQAoFt*Fz#^$Lm^y5D(p)wl2`#G%&5hIx1tT0w zJvPAsT6edaRSccWc#pV@;ILZF@J?O(Hz8DIkB@o;h z_&Czxnn){wjlOE~V~a`gEAyk=7eVOYGWlE*YH)&+BS8FemIn-EI@rFdefad74{Hq{ z=xL0`P~77PiM!b3$+H*f$@5$!Au>{Tw@Wf=?@qI#o;AAA&hZGElKKN99C2snCQzRN z6NjH;a4^c@MNo(gqX+&NJ$mi;O1^+D7dxm}(3ZkYrumY!*gK;1qABEVvhxxhz`CY* zU}j<3R+fb{!RQ<|8zjMYz+jixm@9$V10a8TPx96yBUG=&)!SJuovH5@VVgDVl+PFz zF?2^jqYiekNqzF!LI8hoTS?{zrqo$wxJh!SCXU%?6(-G&AoUtTYADL^sWqv1@t1hL z(idP0Bv@p5xO~8-&qMR4zcmG_8_$;&4Phtfec+TJ{V6!fokMJ}*=D3gh|-n$-ym+F nfezVgxQt`5Uv}u2fE7^kV>I}yG6Dbq000000000000000H2F&; literal 0 HcmV?d00001 diff --git a/images/node-infrastructure/run-a-collator/run-a-collator-03.webp b/images/node-infrastructure/run-a-collator/run-a-collator-03.webp new file mode 100644 index 0000000000000000000000000000000000000000..78d7b19566e23628126a85287742536e6c91d563 GIT binary patch literal 70350 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≥KB^wE?w^f513 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 H00000k2alP literal 0 HcmV?d00001 diff --git a/node-infrastructure/run-a-collator.md b/node-infrastructure/run-a-collator.md index a320bc886..1d3e150de 100644 --- a/node-infrastructure/run-a-collator.md +++ b/node-infrastructure/run-a-collator.md @@ -10,38 +10,28 @@ categories: Infrastructure Block-producing collators are the backbone of system parachain operations. Unlike RPC or archive nodes, which maintain state, collators actively produce blocks and submit them to relay chain validators for inclusion. They ensure network liveness, censorship resistance, and cross-chain message processing. -This guide explains how to set up a block-producing collator for Polkadot system parachains, covering all key requirements, setting up and registering session keys, and meeting governance approval or invulnerables-list criteria (required for system parachains, non-system parachains may be more permissionless). +Collators maintain fully synced relay chain and parachain nodes, aggregate transactions into blocks, create parachain block candidates, generate state transition proofs (Proof-of-Validity), and send block candidates to relay chain validators. They also enable cross-chain message handling via XCM. While critical for liveness, collators do not secure the network—security is provided by relay chain validators through the [ELVES protocol](https://wiki.polkadot.com/learn/learn-parachains-protocol/){target=\_blank}. -## Collator Responsibilities - -Block-producing collators perform critical functions: - -- Maintain full nodes for relay chain and parachain with high uptime and performance. -- Aggregate user transactions into blocks. -- Create parachain block candidates. -- Produce state transition proofs (Proof-of-Validity). -- Send block candidates to relay chain validators. -- Enable cross-chain message passing using XCM - -Unlike relay chain validators, collators do not provide security guarantees—that responsibility lies with relay chain validators through the [ELVES protocol](https://wiki.polkadot.com/learn/learn-parachains-protocol/){target=\_blank}. Rather, collators are essential for network liveness and censorship resistance. +This guide explains how to set up a collator for Polkadot system parachains, covering all key requirements, setting up and registering session keys, and meeting governance approval or invulnerables-list criteria (required for system parachains; non-system parachains may be more permissionless). ## Prerequisites ### Hardware Requirements -Block-producing collators require robust hardware for reliable operation including the following: +Block-producing collators require robust hardware for reliable operation, including the following: - **CPU**: 4+ cores (8+ cores recommended for optimal performance) - **Memory**: 32 GB RAM minimum (64 GB recommended) - **Storage**: + - 200+ GB NVMe SSD (with pruning enabled for both parachain and relay chain) - Fast disk I/O is critical for block production performance - **Network**: - - Public IP address (required) - - 100+ Mbps connection (stable connection critical) + - Public IP address + - 100+ Mbps connection; a stable connection is critical - Open ports: - - 30333 (parachain P2P) - - 30334 (relay chain P2P) + - **30333**: Parachain P2P + - **30334**: Relay chain P2P !!! warning "Uptime is critical" Consider redundancy and monitoring to maintain block production reliability. @@ -55,9 +45,46 @@ Required software: ### Account Requirements +??? interface "Need to create an account?" + + You can generate an account by taking the following steps: + + 1. Generate an account key with the `sr25519` scheme using the following command: + + ```bash + docker run -it parity/subkey:latest generate --scheme sr25519 + ``` + + The output will be similar to the following: + +
+ docker run -it parity/subkey:latest generate --scheme sr25519 +
Secret phrase:       embody rail hour peanut .... badge syrup luggage canvas
+            Network ID:        substrate
+            Secret seed:       0x6498dd3416c491406e2c8283c76760ce4ca018478888b42315e7718778f2c2e1
+            Public key (hex):  0x2202210357e49390d4f8d868da983940fe220a0a0e00bc6feaeda462aa031810
+            Account ID:        0x2202210357e49390d4f8d868da983940fe220a0a0e00bc6feaeda462aa031810
+            Public key (SS58): 5CqJ7n72GvvF5ZzUT2HMj83KyDje4n8sXR8kuiK8HWtfDktF
+            SS58 Address:      5CqJ7n72GvvF5ZzUT2HMj83KyDje4n8sXR8kuiK8HWtfDktF
+        
+
+ + 2. Save the following items displayed in the output: + - Secret phrase (seed) - Keep this secure! + - Public key (hex) + - Account ID + - SS58 Address + + !!! warning + + Store the secret phrase securely. Never share it. Consider using a hardware wallet for production collators. + Your account must meet the following requirements: - **Funded account**: For on-chain transactions and potential bonding + +You will also need the following, which are generated or configured later in this guide: + - **Session keys**: For collator identification (generated after node setup) - **Node key**: For stable P2P peer ID (recommended) @@ -70,146 +97,124 @@ This guide provides two deployment options. Select the option that best fits you === "Docker" - Pull the Polkadot Parachain Docker image: - - ```bash - docker pull parity/polkadot-parachain:stable2509-2 - ``` + 1. Pull the Polkadot Parachain Docker image using the latest stable tag on [Docker Hub](https://hub.docker.com/r/parity/polkadot-parachain/tags){target=\_blank}: - Verify the installation: + ```bash + docker pull parity/polkadot-parachain:stable2509-2 + ``` - ```bash - docker run --rm parity/polkadot-parachain:stable2509-2 --version - ``` + 2. Verify the installation: - Check [Docker Hub](https://hub.docker.com/r/parity/polkadot-parachain/tags){target=\_blank} for the latest stable tags. + ```bash + docker run --rm parity/polkadot-parachain:stable2509-2 --version + ``` -=== "Manual Setup" +=== "systemd" - Download the `polkadot-parachain` binary from the latest stable [Polkadot SDK release](https://github.com/paritytech/polkadot-sdk/releases){target=\_blank}: + 1. Download the `polkadot-parachain` binary using the latest stable [Polkadot SDK release](https://github.com/paritytech/polkadot-sdk/releases){target=\_blank}: - ```bash - # Download the latest stable release (check releases page for current version) - wget https://github.com/paritytech/polkadot-sdk/releases/download/polkadot-stable2509-2/polkadot-parachain + ```bash + wget https://github.com/paritytech/polkadot-sdk/releases/download/polkadot-stable2509-2/polkadot-parachain + ``` - # Make it executable and move to system path - chmod +x polkadot-parachain - sudo mv polkadot-parachain /usr/local/bin/ - sudo chown root:root /usr/local/bin/polkadot-parachain + 2. Make it executable and move it to your system path: + + ```bash + chmod +x polkadot-parachain + sudo mv polkadot-parachain /usr/local/bin/ + sudo chown root:root /usr/local/bin/polkadot-parachain + ``` - # Verify installation - polkadot-parachain --version - ``` + 3. Verify installation: - Check the [Polkadot SDK releases](https://github.com/paritytech/polkadot-sdk/releases){target=\_blank} page for the latest stable version. + ```bash + polkadot-parachain --version + ``` ## Generate Node Key Generating a stable node key enables a consistent peer ID across the network. Follow these steps to generate a node key: -1. Create a directory for node data using the following command: - ```bash - sudo mkdir -p /var/lib/polkadot-collator - ``` +1. Create a directory for node data: -2. Generate your node key using Docker with the following command: - ```bash - docker run -it parity/subkey:latest generate-node-key > /var/lib/polkadot-collator/node.key - ``` + ```bash + sudo mkdir -p /var/lib/polkadot-collator + ``` -3. Locate your peer ID in the displayed output. It will be similar to the following example: - ```bash - 12D3KooWExcVYu7Mvjd4kxPVLwN2ZPnZ5NyLZ5ft477wqzfP2q6E - ``` +2. Generate your node key using Docker: -Be sure to save the peer ID for future reference. + ```bash + docker run -it parity/subkey:latest generate-node-key > /var/lib/polkadot-collator/node.key + ``` -## Generate Account Key +3. Locate your peer ID in the displayed output. It will be similar to the following example: -Generate an account for on-chain transactions as follows: + ```bash + 12D3KooWExcVYu7Mvjd4kxPVLwN2ZPnZ5NyLZ5ft477wqzfP2q6E + ``` -1. Generate an account key with `sr25519` scheme using the following command: - ```bash - docker run -it parity/subkey:latest generate --scheme sr25519 - ``` +Be sure to save the peer ID for future reference. - The output will be similar to the following: - ```bash - Secret phrase: embody rail hour peanut .... badge syrup luggage canvas - Network ID: substrate - Secret seed: 0x6498dd3416c491406e2c8283c76760ce4ca018478888b42315e7718778f2c2e1 - Public key (hex): 0x2202210357e49390d4f8d868da983940fe220a0a0e00bc6feaeda462aa031810 - Account ID: 0x2202210357e49390d4f8d868da983940fe220a0a0e00bc6feaeda462aa031810 - Public key (SS58): 5CqJ7n72GvvF5ZzUT2HMj83KyDje4n8sXR8kuiK8HWtfDktF - SS58 Address: 5CqJ7n72GvvF5ZzUT2HMj83KyDje4n8sXR8kuiK8HWtfDktF - ``` +## Obtain Chain Specification -2. Save the following items displayed in the output: - - Secret phrase (seed) - Keep this secure! - - Public key (hex) - - Account ID - - SS58 Address +Download the chain specification for your target system parachain using one of the following options: - !!! warning - - Store the secret phrase securely. Never share it. Consider using a hardware wallet for production collators. +=== "Download from Chainspec Collection (Recommended)" -## Obtain Chain Specification + Follow these steps to download your specification from the [Chainspec Collection](https://paritytech.github.io/chainspecs/){target=\_blank}: -Download the chain specification for your target system parachain using one of the following options: + 1. Find your target system parachain under the [**List of Chainspecs**](https://paritytech.github.io/chainspecs/#list-of-chainspecs){target=\_blank}. + 2. Download the chain specification JSON file. + 3. Save it as `chain-spec.json`. -### Download from Chainspec Collection (Recommended) +=== "Build Chain Spec from Runtime" -Follow these steps to download your specification from the Chainspec Collection: + Follow these steps to build a chainspec from the runtime: -1. Visit the [Chainspec Collection](https://paritytech.github.io/chainspecs/){target=\_blank} website. -2. Find your target system parachain. -3. Download the chain specification JSON file. -4. Save it as `chain-spec.json`. + 1. Clone the runtimes repository and navigate into it: -### Build Chainspec from Runtime + ```bash + git clone https://github.com/polkadot-fellows/runtimes.git + cd runtimes + ``` -Follow these steps to build a chainspec from the runtime: + 2. Build the desired runtime. Use the following command for Polkadot Hub: -1. Clone the runtimes repository and navigate into it using the following commands: - ```bash - git clone https://github.com/polkadot-fellows/runtimes.git - cd runtimes - ``` + ```bash + cargo build --release -p asset-hub-polkadot-runtime + ``` -2. Build the desired runtime. Use the following command for Polkadot Hub: - ```bash - cargo build --release -p asset-hub-polkadot-runtime - ``` + 3. Install the `chain-spec-builder` dependency: -3. Install the `chain-spec-builder` dependency using the following command: - ```bash - cargo install --locked staging-chain-spec-builder@14.0.0 - ``` + ```bash + cargo install --locked staging-chain-spec-builder@14.0.0 + ``` -4. Finally, generate the chain spec using the following commands: - ```bash - chain-spec-builder create \ - --relay-chain polkadot \ - --para-id 1000 \ - --runtime target/release/wbuild/asset-hub-polkadot-runtime/asset_hub_polkadot_runtime.compact.compressed.wasm \ - named-preset production > chain-spec.json - ``` + 4. Finally, generate the chain spec: -??? tip "System Parachain Para IDs" + ```bash + chain-spec-builder create \ + --relay-chain polkadot \ + --para-id 1000 \ + --runtime target/release/wbuild/asset-hub-polkadot-runtime/asset_hub_polkadot_runtime.compact.compressed.wasm \ + named-preset production > chain-spec.json + ``` + + ??? tip "System Parachain Para IDs" - - Polkadot Hub: 1000 - - Bridge Hub: 1002 - - People Chain: 1004 - - Coretime Chain: 1005 + - **Polkadot Hub**: 1000 + - **Bridge Hub**: 1002 + - **People Chain**: 1004 + - **Coretime Chain**: 1005 ## Run the Collator -Select your preferred deployment method: +Using your preferred deployment method, take the following steps to set up and run your collator: -=== "Docker Setup" +=== "Docker" 1. Create a directory for collator data and copy the chain spec: + ```bash mkdir -p collator-data cp chain-spec.json collator-data/ @@ -217,6 +222,7 @@ Select your preferred deployment method: ``` 2. Launch the collator using Docker: + ```bash docker run -d --name polkadot-collator --restart unless-stopped \ -p 30333:30333 \ @@ -234,7 +240,7 @@ Select your preferred deployment method: --prometheus-port=9615 \ --prometheus-external \ --node-key-file=/data/node.key \ - --name="YourCollatorName" \ + --name="INSERT_YOUR_COLLATOR_NAME" \ --blocks-pruning=256 \ --state-pruning=256 \ --database=paritydb \ @@ -250,47 +256,39 @@ Select your preferred deployment method: ``` 3. View logs to monitor sync progress: + ```bash docker logs -f polkadot-collator ``` - 4. Use the following commands to manage your Docker container: - - Stop container: - ```bash - docker stop polkadot-collator - ``` - - Start container: - ```bash - docker start polkadot-collator - ``` - - Remove container: - ```bash - docker rm polkadot-collator - ``` - -=== "systemd Setup" +=== "systemd" 1. Create a dedicated user: + ```bash sudo useradd -r -s /bin/bash polkadot ``` 2. Copy your chain spec to the directory: + ```bash sudo cp chain-spec.json /var/lib/polkadot-collator/ ``` 3. Set permissions: + ```bash sudo chown -R polkadot:polkadot /var/lib/polkadot-collator ``` 4. Create a systemd service file: + ```bash sudo nano /etc/systemd/system/polkadot-collator.service ``` 5. Add the following configuration: + ```ini title="systemd/system/polkadot-collator.service" [Unit] Description=Polkadot System Parachain Collator @@ -310,7 +308,7 @@ Select your preferred deployment method: --rpc-port=9944 \ --prometheus-port=9615 \ --node-key-file=/var/lib/polkadot-collator/node.key \ - --name="YourCollatorName" \ + --name="INSERT_YOUR_COLLATOR_NAME" \ --blocks-pruning=256 \ --state-pruning=256 \ --database=paritydb \ @@ -333,6 +331,7 @@ Select your preferred deployment method: ``` 6. Start the service: + ```bash sudo systemctl daemon-reload sudo systemctl enable polkadot-collator @@ -340,41 +339,38 @@ Select your preferred deployment method: ``` 7. Check the status: + ```bash sudo systemctl status polkadot-collator ``` 8. View logs: + ```bash sudo journalctl -u polkadot-collator -f ``` -??? note "Configuration notes" - - - `--collator`: Enables block production mode - - `--node-key-file`: Uses the generated node key for stable peer ID - - `--name`: Your collator name (visible in telemetry) - - `--blocks-pruning=256` and `--state-pruning=256`: Keeps only recent blocks and state, reducing disk usage (collators don't need archive data) - - `--database=paritydb`: Uses ParityDB for better performance - - `--sync=fast`: Fast sync mode for the relay chain - - `--pool-limit=0`: Disables transaction pool on relay chain (collators don't need it) - - `--rpc-port=0` (relay chain): Disables RPC on the embedded relay chain node (not needed for collators) +??? interface "Configuration Arguments" -## Complete Initial Sync + - **`--collator`**: Enables block production mode. + - **`--node-key-file`**: Uses the generated node key for stable peer ID. + - **`--name`**: Your collator name (visible in [telemetry](https://telemetry.polkadot.io/){target=\_blank}). + - **`--blocks-pruning=256`**: Keeps the last 256 blocks. + - **`--state-pruning=256`**: Keeps the state history of the last 256 blocks. + - **`--database=paritydb`**: Uses ParityDB for better performance. + - **`--sync=fast`**: Fast sync mode for the relay chain. + - **`--pool-limit=0`**: Disables transaction pool on relay chain (not needed for collators). + - **`--rpc-port=0` (relay chain)**: Disables RPC on the embedded relay chain node (not needed for collators). -Your collator must sync both the relay chain and parachain before producing blocks. - -Sync time depends on: +Your collator must sync both the relay chain and parachain before producing blocks. The relay chain uses fast sync to speed up synchronization. Overall sync time depends on: - Network bandwidth - Disk I/O speed - Current chain size -The relay chain uses fast sync for faster synchronization. - !!! warning - Do not proceed with registration until both chains are fully synced. Monitor sync progress using the log viewing commands in the [Log Management](#log-management) section. + Do not proceed with registration until both chains are fully synced. Monitor sync progress using the log viewing commands in the [Log Management](#commands-for-log-management) section. ## Generate Session Keys @@ -388,29 +384,17 @@ curl -H "Content-Type: application/json" \ http://localhost:9944 ``` -This command returns session keys as a hexstring in the terminal. You must save these session keys as you'll need them for on-chain registration. As session keys are stored in the node's database, if you wipe the database, you'll also need to generate new keys. +This command returns session keys as a hex string in the terminal. You must save these session keys as you'll need them for on-chain registration. As session keys are stored in the node's database, if you wipe the database, you'll also need to generate new keys. ## Register Collator for Selection -System parachains use different collator selection mechanisms. Explore the following tabs to see how mechanisms compare and determine the most suitable mechanism for registering your collator. - -=== "Invulnerables List" - - - Fixed list of collators approved through governance. - - Most common for system parachains. - - Requires governance proposal and approval. - - -=== "On-chain Selection" +System parachains use different mechanisms for selecting collators. A quick breakdown of each mechanism is as follows: - - Some parachains use [pallet-collator-selection](https://paritytech.github.io/polkadot-sdk/master/pallet_collator_selection/index.html){target=\_blank}. - - May require bonding tokens. - - Automatic selection based on criteria. - -=== "Fellowship Decisions" - - - Technical Fellowship may manage some system parachain collators. - - Requires Fellowship membership or approval. +| Method | How it Works | Requirements | +|--------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|------------------------------------------------------------------| +| **Invulnerables list** | Fixed list defined through governance. Most common for system parachains. | Permissioned via governance | +| **On-chain selection** | Runtime automatically selects eligible collators. Some parachains use [pallet-collator-selection](https://paritytech.github.io/polkadot-sdk/master/pallet_collator_selection/index.html){target=\_blank}. | Semi-permissionless (criteria-based; may require bonding tokens) | +| **Fellowship decisions** | Technical fellowship may manage some system parachain collators. | Permissioned via Fellowship | ### Registration Process @@ -419,80 +403,151 @@ Collator registration authorizes your node to produce blocks on the network. The The registration process varies by system parachain. General steps include the following: 1. Check the existing collators for your target parachain: - 1. Navigate to Polkadot.js Apps and connect to your system parachain. 2. Locate **Developer > Chain State**. - 3. Query `collatorSelection.invulnerables()` + 3. Query **`collatorSelection.invulnerables()`**. + + ![](/images/node-infrastructure/run-a-collator/run-a-collator-01.webp) -2. Prepare a governance proposal for invulnerables-based selection including the following information: - - **Draft proposal**: Explain why you should be added as a collator - - **Technical details**: Provide your session keys and account ID - - **Infrastructure**: Describe your hardware and monitoring setup - - **Experience**: Detail your relevant experience +2. Prepare a governance proposal for invulnerables-based selection, including the following information: + + - **Draft proposal**: Explain why you should be added as a collator. + - **Technical details**: Provide your session keys and account ID. + - **Infrastructure**: Describe your hardware and monitoring setup. + - **Experience**: Detail your relevant experience. Submit the proposal to the relevant governance channels on the [Polkadot Forum](https://forum.polkadot.network){target=\_blank}. 3. Once approved (or if using on-chain selection), follow these steps to register session keys using Polkadot.js Apps: - 1. Navigate to Polkadot.js Apps and connect to your system parachain. - 2. Locate **Developer > Extrinsics**. - 3. Select your account. - 4. Choose the `session.setKeys` extrinsic. - 5. Enter the following information: - - `keys`: Your session keys (from `author_rotateKeys`) - - `proof`: 0x00 (typically) - 6. Submit and sign the transaction. + + 1. Locate **Developer > Extrinsics**. + 2. Select your account. + 3. Choose the **`session.setKeys`** extrinsic. + 4. Enter the following information: + - **`keys`**: Your session keys (from `author_rotateKeys`) + - **`proof`**: 0x00 (typically) + 5. Click **Submit Transaction** and sign the transaction. + ![](/images/node-infrastructure/run-a-collator/run-a-collator-02.webp) + 4. (Optional - primarily for non-system parachains) If the parachain uses on-chain bonding for collator selection, register as a candidate using Polkadot.js Apps: !!! note Most system parachains use invulnerables lists exclusively and do not require this step. Skip to step 5 if you're running a collator for a system parachain. 1. Locate **Developer > Extrinsics**. - 2. Select `collatorSelection.registerAsCandidate`. - 3. Submit and sign the transaction. The required bond amount will be automatically reserved from your account based on the pallet's configured `CandidacyBond`. + 2. Select your account. + 3. Select `collatorSelection.registerAsCandidate`. + 4. Click **Submit Transaction** and sign the transaction. The required bond amount will be automatically reserved from your account based on the pallet's configured `CandidacyBond`. + + ![](/images/node-infrastructure/run-a-collator/run-a-collator-03.webp) 5. For system parachains using invulnerables lists, await governance approval for your proposal. Monitor the [Polkadot Forum](https://forum.polkadot.network){target=\_blank} governance channels and announcements. Once approved, your collator is added to the invulnerables list and will begin producing blocks in the next session or era. -6. Verify your collator is active by monitoring logs for block production messages like "Prepared block for proposing" and "Imported #123". See the [Log Management](#log-management) section for log viewing commands. +6. Verify your collator is active by monitoring logs for block production messages like "Prepared block for proposing" and "Imported #123". See the [Log Management](#commands-for-log-management) section for commands for log viewing. + +## Commands for Node Management + +Use the following commands to manage your node: + +=== "Docker" + + - **Stop container**: + + ```bash + docker stop polkadot-collator + ``` + + - **Start container**: + + ```bash + docker start polkadot-collator + ``` + + - **Remove container**: + + ```bash + docker rm polkadot-collator + ``` + +=== "systemd" -## Log Management + - **Check status**: + + ```bash + sudo systemctl status polkadot-collator + ``` + + - **Stop service**: + + ```bash + sudo systemctl stop polkadot-collator + ``` + + - **Enable service**: + + ```bash + sudo systemctl enable polkadot-collator + ``` + + - **Start service**: + + ```bash + sudo systemctl start polkadot-collator + ``` + +## Commands for Log Management Efficient log management is essential to ensure collator performance and uptime. Use the following commands to help you manage logs to monitor and maintain your collator: -=== "Docker Setup" +=== "Docker" + + - **View logs**: - - View logs: ```bash docker logs -f polkadot-collator ``` - - View recent logs (last 100 lines): + + - **View recent logs (last 100 lines)**: + ```bash docker logs --tail 100 polkadot-collator ``` - - Filter for errors: + + - **Filter for errors**: + ```bash docker logs polkadot-collator 2>&1 | grep -i error ``` - - Filter for block production: + + - **Filter for block production**: + ```bash docker logs polkadot-collator 2>&1 | grep -i "imported" ``` -=== "systemd Setup" +=== "systemd" + + - **View recent logs**: - - View recent logs: ```bash sudo journalctl -u polkadot-collator -n 100 ``` - - Follow logs in real-time: + + - **Follow logs in real-time**: + ```bash sudo journalctl -u polkadot-collator -f ``` - - Filter for errors: + + - **Filter for errors**: + ```bash sudo journalctl -u polkadot-collator | grep -i error ``` - - Filter for block production: + + - **Filter for block production**: + ```bash sudo journalctl -u polkadot-collator | grep -i "imported" ``` @@ -501,88 +556,100 @@ Efficient log management is essential to ensure collator performance and uptime. Check database size periodically using the commands for your selected setup: -=== "Docker Setup" +=== "Docker" ```bash # Replace with your mounted data directory path du -sh ./collator-data ``` -=== "systemd Setup" +=== "systemd" ```bash du -sh /var/lib/polkadot-collator ``` -The collator node handles pruning automatically based on configuration. +The collator node automatically prunes based on configuration. ## Updates and Upgrades -Updates or upgrades can happen on either the runtime or client. Runtime upgrades happen automatically via on-chain governance and do not require manual action on your part. Client upgrades do require a manual binary update process performed via terminal commands as follows: +Updates or upgrades can happen on either the runtime or client. Runtime upgrades are automatically applied via on-chain governance and do not require any manual action on your part. Client upgrades do require a manual binary update process performed via terminal commands as follows: -=== "Docker Setup" +=== "Docker" 1. Stop the service: + ```bash sudo systemctl stop polkadot-collator ``` 2. Backup data (recommended): + ```bash sudo cp -r /var/lib/polkadot-collator /var/lib/polkadot-collator.backup ``` 3. Pull the new Docker image: + ```bash docker pull parity/polkadot-parachain: ``` 4. Update the image tag in your systemd service file: + ```bash sudo nano /etc/systemd/system/polkadot-collator.service ``` 5. Reload systemd and restart the service: + ```bash sudo systemctl daemon-reload sudo systemctl start polkadot-collator ``` 6. Verify the service is running: + ```bash sudo systemctl status polkadot-collator ``` -=== "Manual Setup" +=== "systemd" 1. Stop the service: + ```bash sudo systemctl stop polkadot-collator ``` 2. Backup data (recommended): + ```bash sudo cp -r /var/lib/polkadot-collator /var/lib/polkadot-collator.backup ``` 3. Download the new binary from [GitHub releases](https://github.com/paritytech/polkadot-sdk/releases){target=\_blank}: + ```bash - wget https://github.com/paritytech/polkadot-sdk/releases/download//polkadot-parachain + wget https://github.com/paritytech/polkadot-sdk/releases/download/INSERT_NEW_VERSION/polkadot-parachain chmod +x polkadot-parachain sudo mv polkadot-parachain /usr/local/bin/ ``` 4. Verify `polkadot-parachain` version to confirm successful update: + ```bash polkadot-parachain --version ``` 5. Restart the service: + ```bash sudo systemctl start polkadot-collator ``` 6. Verify the service is running: + ```bash sudo systemctl status polkadot-collator ``` diff --git a/node-infrastructure/run-a-node/parachain-rpc.md b/node-infrastructure/run-a-node/parachain-rpc.md index d79d226ec..6daafbb1a 100644 --- a/node-infrastructure/run-a-node/parachain-rpc.md +++ b/node-infrastructure/run-a-node/parachain-rpc.md @@ -216,7 +216,7 @@ System parachain details: !!! note The `parity/polkadot-parachain` image works for system parachains and parachains built with standard Cumulus templates. For parachains with custom runtimes, check the parachain's documentation for their specific Docker image or binary. - Refer to the [Port Mappings](#port-mappings) and [Node Configuration Parameters](#node-configuration-parameters) sections for details on the command's configurations. + Refer to the [Port Mappings](#port-mappings) and [Node Configuration Arguments](#node-configuration-arguments) sections for details on the command's configurations. === "systemd" @@ -346,7 +346,7 @@ System parachain details: WantedBy=multi-user.target ``` - Refer to the [Port Mappings](#port-mappings) and [Node Configuration Parameters](#node-configuration-parameters) sections for details on the command's configurations. + Refer to the [Port Mappings](#port-mappings) and [Node Configuration Arguments](#node-configuration-arguments) sections for details on the command's configurations. 6. Start the service: diff --git a/node-infrastructure/run-a-node/polkadot-hub-rpc.md b/node-infrastructure/run-a-node/polkadot-hub-rpc.md index dbeb95459..31c1260c5 100644 --- a/node-infrastructure/run-a-node/polkadot-hub-rpc.md +++ b/node-infrastructure/run-a-node/polkadot-hub-rpc.md @@ -183,7 +183,7 @@ Select the best option for your project, then use the steps in the following tab --rpc-port=0 ``` - Refer to the [Port Mappings](#port-mappings) and [Node Configuration Parameters](#node-configuration-parameters) sections for details on the command's configurations. + Refer to the [Port Mappings](#port-mappings) and [Node Configuration Arguments](#node-configuration-arguments) sections for details on the command's configurations. === "systemd" @@ -317,7 +317,7 @@ Select the best option for your project, then use the steps in the following tab WantedBy=multi-user.target ``` - Refer to the [Port Mappings](#port-mappings) and [Node Configuration Parameters](#node-configuration-parameters) sections for details on the command's configurations. + Refer to the [Port Mappings](#port-mappings) and [Node Configuration Arguments](#node-configuration-arguments) sections for details on the command's configurations. 6. Start the service: @@ -339,7 +339,7 @@ Select the best option for your project, then use the steps in the following tab - **`9615`**: Prometheus metrics endpoint - **`30333/30334`**: P2P networking ports -### Node Configuration Parameters +### Node Configuration Arguments - **`--unsafe-rpc-external`**: Enables external RPC access. **This command should only be used in development or properly secured environments**. For production, use a reverse proxy with authentication. - **`--rpc-cors=all`**: Allows all origins for CORS. From 59603f122d846a5a3e187c5d6ea13b064ae4ba6c Mon Sep 17 00:00:00 2001 From: Erin Shaben Date: Thu, 11 Dec 2025 11:11:19 -0500 Subject: [PATCH 36/39] resolve TODOs --- node-infrastructure/run-a-collator.md | 3 +-- node-infrastructure/run-a-node/parachain-rpc.md | 5 ++--- node-infrastructure/run-a-node/polkadot-hub-rpc.md | 5 ++--- 3 files changed, 5 insertions(+), 8 deletions(-) diff --git a/node-infrastructure/run-a-collator.md b/node-infrastructure/run-a-collator.md index 1d3e150de..004dc9ee0 100644 --- a/node-infrastructure/run-a-collator.md +++ b/node-infrastructure/run-a-collator.md @@ -23,7 +23,6 @@ Block-producing collators require robust hardware for reliable operation, includ - **CPU**: 4+ cores (8+ cores recommended for optimal performance) - **Memory**: 32 GB RAM minimum (64 GB recommended) - **Storage**: - - 200+ GB NVMe SSD (with pruning enabled for both parachain and relay chain) - Fast disk I/O is critical for block production performance - **Network**: @@ -442,7 +441,7 @@ The registration process varies by system parachain. General steps include the f ![](/images/node-infrastructure/run-a-collator/run-a-collator-03.webp) -5. For system parachains using invulnerables lists, await governance approval for your proposal. Monitor the [Polkadot Forum](https://forum.polkadot.network){target=\_blank} governance channels and announcements. Once approved, your collator is added to the invulnerables list and will begin producing blocks in the next session or era. +5. For system parachains using invulnerables lists, await governance approval for your proposal. Once approved, your collator is added to the invulnerables list and will begin producing blocks in the next session or era. 6. Verify your collator is active by monitoring logs for block production messages like "Prepared block for proposing" and "Imported #123". See the [Log Management](#commands-for-log-management) section for commands for log viewing. diff --git a/node-infrastructure/run-a-node/parachain-rpc.md b/node-infrastructure/run-a-node/parachain-rpc.md index 6daafbb1a..81fb4cc1e 100644 --- a/node-infrastructure/run-a-node/parachain-rpc.md +++ b/node-infrastructure/run-a-node/parachain-rpc.md @@ -22,14 +22,13 @@ RPC nodes serving production traffic require robust hardware: - **Memory**: 64 GB RAM minimum; 128 GB recommended for high traffic - **Storage**: Storage requirements vary by parachain. Fast NVMe I/O is critical for RPC query performance - **System parachains**: [Snapshots](https://snapshots.polkadot.io/){target=\_blank} _may_ be available - - **Archive node**: Using snapshots, expected storage requirements (including ~822 GB for the pruned relay chain) are: + - **Archive node (complete history)**: Using snapshots, expected storage requirements (including ~822 GB for the pruned relay chain) are: - **Asset Hub**: ~1.2 TB - **Bridge Hub**: ~1.1 TB - **Collectives**: ~1 TB - **People Chain**: ~900 GB - **Coretime**: ~900 GB - - - **Pruned node**: 200+ GB for both parachain and relay chain + - **Pruned node (recent state)**: ~200 GB total for both parachain and relay chain - **Non-system parachains**: Consult the parachain team or documentation, then add ~822 GB for the pruned relay chain - **Network**: - Public IP address diff --git a/node-infrastructure/run-a-node/polkadot-hub-rpc.md b/node-infrastructure/run-a-node/polkadot-hub-rpc.md index 31c1260c5..41a6999f9 100644 --- a/node-infrastructure/run-a-node/polkadot-hub-rpc.md +++ b/node-infrastructure/run-a-node/polkadot-hub-rpc.md @@ -24,9 +24,8 @@ RPC nodes serving production traffic require robust hardware. The following shou - **CPU**: 8+ cores; 16+ cores for high traffic - **Memory**: 64 GB RAM minimum; 128 GB recommended for high traffic - **Storage**: - - **Archive node**: ~1.2 TB NVMe SSD total (~392 GB for Asset Hub archive + ~822 GB for relay chain pruned snapshot) - - - **Pruned node**: 200+ GB NVMe SSD (with pruning enabled for both parachain and relay chain) + - **Archive node (complete history)**: ~1.2 TB NVMe SSD total (~392 GB for Asset Hub archive + ~822 GB for relay chain pruned snapshot) + - **Pruned node (recent state)**: ~2~00 GB NVMe SSD total (with pruning enabled for both parachain and relay chain) - Fast disk I/O is critical for query performance - **Network**: - Public IP address From 3f78b601df01b2eef183b46817b99fd0c4a3dabc Mon Sep 17 00:00:00 2001 From: Erin Shaben Date: Thu, 11 Dec 2025 11:21:25 -0500 Subject: [PATCH 37/39] fix capitalization --- node-infrastructure/index.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/node-infrastructure/index.md b/node-infrastructure/index.md index 2c4aa39d6..d0add9861 100644 --- a/node-infrastructure/index.md +++ b/node-infrastructure/index.md @@ -25,8 +25,8 @@ RPC nodes provide API access to blockchain data without participating in consens RPC nodes can be run for both the relay chain and parachains, with varying levels of data retention: -- **Pruned Nodes**: Keep recent state and a limited number of finalized blocks. Suitable for most applications that only need the current state and recent history. More efficient in terms of storage and sync time. -- **Archive Nodes**: Maintain complete historical state and all blocks since genesis. Required for block explorers, analytics platforms, or applications that need to query historical data at any point in time. +- **Pruned nodes**: Keep recent state and a limited number of finalized blocks. Suitable for most applications that only need the current state and recent history. More efficient in terms of storage and sync time. +- **Archive nodes**: Maintain complete historical state and all blocks since genesis. Required for block explorers, analytics platforms, or applications that need to query historical data at any point in time. **Transaction Broadcasting**: RPC nodes play a crucial role in transaction submission and propagation. When a client submits a transaction via RPC methods like `author_submitExtrinsic`, the node validates the transaction format, adds it to its local transaction pool, and broadcasts it across the P2P network. Block producers (collators or validators) then pick up these transactions from their pools for inclusion in blocks. This makes RPC nodes the primary gateway for users and applications to interact with the blockchain. From 979be37c868d69238fc3fceef98b5aecc9a541c3 Mon Sep 17 00:00:00 2001 From: nhussein11 Date: Thu, 11 Dec 2025 20:15:59 -0300 Subject: [PATCH 38/39] fix: images --- .../run-a-collator/run-a-collator-02.webp | Bin 48274 -> 49546 bytes .../run-a-collator/run-a-collator-03.webp | Bin 70350 -> 70814 bytes 2 files changed, 0 insertions(+), 0 deletions(-) diff --git a/images/node-infrastructure/run-a-collator/run-a-collator-02.webp b/images/node-infrastructure/run-a-collator/run-a-collator-02.webp index f1c6c1292846a06d93212b3c0443fd36f36eb08e..0386012904699a88f0c2428d4685f7761fcbad73 100644 GIT binary patch literal 49546 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
u z9r+qrFVb=q&YIrCRGdhp_ZVUf*xZfgP(N&7u;HTaq!;#L?K0pX9$TwqI7+=C2OmS- zIXFTrP^7CCy0L_3EkLA#*4Bg?Ar4Rxb^rhXgTAahz6z>GZV@OmseS#Yd7u<_WnmpX z;1D(nPXrgZLQHPl%<1ah&V$Y{$-~ilQV5Z!4n@a8(F&^H%1jTiyKe3Wj$SaKsZ6!- z3}O$n+gtm2x`H}I#Mr_a&@Z(V|7jh11EU7r)D^*Qc_qr8KkirVB1>k4IGIY@FLjQ*JwTi`#}h zXVrxyb|c?ehmr0gjem85v&kjZB9q?b%jj&LltrBXV4x3n+wG&jDW!@2cHJ`wj+! z&V8pU?0LZe4(z%2WKBE&xDl_SAGu%vU`8x!{z~;Cs(HIn`stxdTV43z-sO{$jWYRP;=tczag#1-E2DiG&lkL>M;bggZJ= zN3lD%laNaqk4;+~H=D1~$m#P{qpZ-(n(~F*(unRx@CV!DSOKq<(us8_ zEtbWE3n)5*tUKw$$dmb?`dw3eWJtOdlZH;{a*jehw4snbIVr4ZQHU6*1E4(#euec# zMZ4i(^#?NIks{UxPL-1HK`M68_kKX9ALC2nAQn9&Y$mK0=y_~ia_LJroO@xI2)J;P zqfW%@lf5I=+M5=j7#$3pj}5d7aZzV>eE44vq&#lo0|i!@ zW7$z@Bxg2Zm^eGJsSHlfXH>J z7zFXCI^};S)1nF+7Xjp)!GuRZEn$=8`ptUdl%T}Mkp$+m$?$?gu}sh+z5pH6pB&lBdi1mS@y)3-eO$E&8Az)*6@`nhUU<7^(}V*ii&?K?Wa; zvGCM$dE2<(fzoh4B+njShh}#%t6e8ADBjf zS^8Np$3Z#sKdMZ6LtKXc(I(_6mua3(e0(}a?K7!lR;d!(`Q9JbxC1M|woeS9iU^w? z<&&x{X+04iyPE3Br-bTs@kaIhA(tEjGEwIc%su9Rd{bR><=z=u0WMM^X$d9+c)odiQ0ZxOGw{)>a$8>*(dAjQW~j?lKAHS zXPHblO%x0V6?vyZ44*&rfT8UjP%5~Tb}%2ebk4_iCX<@oHYl9!7}XzdAl;k`4?>pHkSSKJPowqnKQRaUf%q7vt*Wc$5qhpMF((ieAdqS4n2aFrWP$F`F zsNkAtZ&DCO-&1AbX#Y$FX|MQ&TxI@-)6IpoMs#E5n^Jc3^`y1S^P|Nfu<864NP&`- z0Mfik0uqwpyv4# zP$&iK8^PQh--5DTN&Kc>s{S*7kQZOL;A{uBnOqtB@YTE@*6uK>?bkN&(FIe^RUGE? zZ1f>km5C6tl@^-bU*FQ2>OQKi-$VgEShi|F37>ouFHywW!AYX*i;qDs@z82*8bWp3 zEZ7gYBZl*m_9{>-@Btjh>QU*_<764G6j|WM;ApXBjw84=$1IxG`{m-45}3Vi3wXSI z&GQBiNo56*`}1!&S&0c#Is_g}K3{Qk{ouU-yX~DheKYfF!j$w=Jpcdz0000000000 H00000sF8kX literal 48274 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 diff --git a/images/node-infrastructure/run-a-collator/run-a-collator-03.webp b/images/node-infrastructure/run-a-collator/run-a-collator-03.webp index 78d7b19566e23628126a85287742536e6c91d563..d9bbad1d299024ff5b8c225c3ea046e293f4b390 100644 GIT binary patch literal 70814 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≥KB^wE?w^f513 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 H00000k2alP From f7838df154ed1438c865742306fa99c97ce1a05c Mon Sep 17 00:00:00 2001 From: Bruno Galvao Date: Fri, 12 Dec 2025 13:38:39 +0700 Subject: [PATCH 39/39] update content --- ...-infrastructure-run-a-collator-collator.md | 608 ---------------- .../node-infrastructure-run-a-collator.md | 666 ++++++++++++++++++ ...infrastructure-run-a-node-parachain-rpc.md | 520 +++++++------- ...rastructure-run-a-node-polkadot-hub-rpc.md | 438 ++++++------ ...ucture-run-a-node-relay-chain-full-node.md | 15 +- ...cture-run-a-node-relay-chain-secure-wss.md | 2 +- ...boarding-and-offboarding-key-management.md | 6 +- ...arding-and-offboarding-set-up-validator.md | 8 +- ...arding-and-offboarding-start-validating.md | 18 +- ...oarding-and-offboarding-stop-validating.md | 2 +- ...or-operational-tasks-general-management.md | 14 +- ...tor-operational-tasks-upgrade-your-node.md | 4 +- ...astructure-run-a-validator-requirements.md | 4 +- ...ure-overview.md => node-infrastructure.md} | 52 +- node-infrastructure/run-a-collator.md | 2 +- .../run-a-node/polkadot-hub-rpc.md | 2 +- 16 files changed, 1199 insertions(+), 1162 deletions(-) delete mode 100644 .ai/pages/node-infrastructure-run-a-collator-collator.md create mode 100644 .ai/pages/node-infrastructure-run-a-collator.md rename .ai/pages/{node-infrastructure-overview.md => node-infrastructure.md} (65%) diff --git a/.ai/pages/node-infrastructure-run-a-collator-collator.md b/.ai/pages/node-infrastructure-run-a-collator-collator.md deleted file mode 100644 index 2219a928d..000000000 --- a/.ai/pages/node-infrastructure-run-a-collator-collator.md +++ /dev/null @@ -1,608 +0,0 @@ ---- -title: Run a Block-Producing Collator -description: Learn how to set up and run a block-producing collator for Polkadot system parachains, including registration and session key management. -categories: Infrastructure -url: https://docs.polkadot.com/node-infrastructure/run-a-collator/collator/ ---- - -# Run a Block-Producing Collator - -## Overview - -Block-producing collators are the backbone of system parachain operations. Unlike RPC or archive nodes, which maintain state, collators actively produce blocks and submit them to relay chain validators for inclusion. - -This guide covers setting up a block-producing collator for Polkadot system parachains. Running a collator requires: - -- Meeting hardware requirements for reliable block production -- Setting up and registering session keys -- Obtaining governance approval or meeting selection criteria -- Maintaining high uptime and performance - -System parachain collators typically require governance approval or being added to the invulnerables list. This is different from non-system parachains where collator selection may be more permissionless. - -## Collator Responsibilities - -Block-producing collators perform critical functions: - -- Maintain full nodes for relay chain and parachain. -- Aggregate user transactions into blocks. -- Create parachain block candidates. -- Produce state transition proofs (Proof-of-Validity). -- Send block candidates to relay chain validators. -- Enable cross-chain message passing using XCM - -Unlike relay chain validators, collators do not provide security guarantees—that responsibility lies with relay chain validators through the [ELVES protocol](https://wiki.polkadot.com/learn/learn-parachains-protocol/){target=\_blank}. Rather, collators are essential for network liveness and censorship resistance. - -## Prerequisites - -### Hardware Requirements - -Block-producing collators require robust hardware for reliable operation including the following: - -- **CPU**: 4+ cores (8+ cores recommended for optimal performance) -- **Memory**: 32 GB RAM minimum (64 GB recommended) -- **Storage**: - - 200+ GB NVMe SSD (with pruning enabled for both parachain and relay chain) - - Fast disk I/O is critical for block production performance -- **Network**: - - Public IP address (required) - - 100+ Mbps connection (stable connection critical) - - Open ports: - - 30333 (parachain P2P) - - 30334 (relay chain P2P) - -Uptime is critical. Consider redundancy and monitoring to maintain block production reliability. - -### Software Requirements - -Collators use the Polkadot Parachain binary, the standard client for running Polkadot system parachains. - -Required software includes the following: - -- **Operating System**: Ubuntu 22.04 LTS (recommended) or similar Linux distribution -- **Docker**: Required for obtaining binaries and running containers - -### Account Requirements - -Your account must meet the following requirements: - -- **Funded account**: For on-chain transactions and potential bonding -- **Session keys**: For collator identification (generated after node setup) -- **Node key**: For stable P2P peer ID (recommended) - -## Install Dependencies - -This guide provides two deployment options. Select the option that best fits your needs: - -- **Docker-based Setup**: Best for simpler setup and maintenance -- **Manual/systemd Setup**: Best for production environments requiring more control - -=== "Docker Setup" - - Pull the Polkadot Parachain Docker image: - - ```bash - docker pull parity/polkadot-parachain:stable2509-2 - ``` - - Verify the installation: - - ```bash - docker run --rm parity/polkadot-parachain:stable2509-2 --version - ``` - - Check [Docker Hub](https://hub.docker.com/r/parity/polkadot-parachain/tags){target=\_blank} for the latest stable tags. - -=== "Manual Setup" - - Download the `polkadot-parachain` binary from the latest stable [Polkadot SDK release](https://github.com/paritytech/polkadot-sdk/releases){target=\_blank}: - - ```bash - # Download the latest stable release (check releases page for current version) - wget https://github.com/paritytech/polkadot-sdk/releases/download/polkadot-stable2509-2/polkadot-parachain - - # Make it executable and move to system path - chmod +x polkadot-parachain - sudo mv polkadot-parachain /usr/local/bin/ - sudo chown root:root /usr/local/bin/polkadot-parachain - - # Verify installation - polkadot-parachain --version - ``` - - Check the [Polkadot SDK releases](https://github.com/paritytech/polkadot-sdk/releases){target=\_blank} page for the latest stable version. - -## Generate Node Key - -Generating a stable node key enables a consistent peer ID across the network. Follow these steps to generate a node key: - -1. Create a directory for node data using the following command: - ```bash - sudo mkdir -p /var/lib/polkadot-collator - ``` - -2. Generate your node key using Docker with the following command: - ```bash - docker run -it parity/subkey:latest generate-node-key > /var/lib/polkadot-collator/node.key - ``` - -3. Locate your peer ID in the displayed output. It will be similar to the following example: - ```bash - 12D3KooWExcVYu7Mvjd4kxPVLwN2ZPnZ5NyLZ5ft477wqzfP2q6E - ``` - -Be sure to save the peer ID for future reference. - -## Generate Account Key - -Generate an account for on-chain transactions as follows: - -1. Generate an account key with `sr25519` scheme using the following command: - ```bash - docker run -it parity/subkey:latest generate --scheme sr25519 - ``` - - The output will be similar to the following: - ```bash - Secret phrase: embody rail hour peanut .... badge syrup luggage canvas - Network ID: substrate - Secret seed: 0x6498dd3416c491406e2c8283c76760ce4ca018478888b42315e7718778f2c2e1 - Public key (hex): 0x2202210357e49390d4f8d868da983940fe220a0a0e00bc6feaeda462aa031810 - Account ID: 0x2202210357e49390d4f8d868da983940fe220a0a0e00bc6feaeda462aa031810 - Public key (SS58): 5CqJ7n72GvvF5ZzUT2HMj83KyDje4n8sXR8kuiK8HWtfDktF - SS58 Address: 5CqJ7n72GvvF5ZzUT2HMj83KyDje4n8sXR8kuiK8HWtfDktF - ``` - -2. Save the following items displayed in the output: - - Secret phrase (seed) - Keep this secure! - - Public key (hex) - - Account ID - - SS58 Address - - !!! warning - - Store the secret phrase securely. Never share it. Consider using a hardware wallet for production collators. - -## Obtain Chain Specification - -Download the chain specification for your target system parachain using one of the following options: - -### Download from Chainspec Collection (Recommended) - -Follow these steps to download your specification from the Chainspec Collection: - -1. Visit the [Chainspec Collection](https://paritytech.github.io/chainspecs/){target=\_blank} website. -2. Find your target system parachain. -3. Download the chain specification JSON file. -4. Save it as `chain-spec.json`. - -### Build Chainspec from Runtime - -Follow these steps to build a chainspec from the runtime: - -1. Clone the runtimes repository and navigate into it using the following commands: - ```bash - git clone https://github.com/polkadot-fellows/runtimes.git - cd runtimes - ``` - -2. Build the desired runtime. Use the following command for Polkadot Hub: - ```bash - cargo build --release -p asset-hub-polkadot-runtime - ``` - -3. Install the `chain-spec-builder` dependency using the following command: - ```bash - cargo install --locked staging-chain-spec-builder@14.0.0 - ``` - -4. Finally, generate the chain spec using the following commands: - ```bash - chain-spec-builder create \ - --relay-chain polkadot \ - --para-id 1000 \ - --runtime target/release/wbuild/asset-hub-polkadot-runtime/asset_hub_polkadot_runtime.compact.compressed.wasm \ - named-preset production > chain-spec.json - ``` - -??? tip "System Parachain Para IDs" - - - Polkadot Hub: 1000 - - Bridge Hub: 1002 - - People Chain: 1004 - - Coretime Chain: 1005 - -## Run the Collator - -Select your preferred deployment method: - -=== "Docker Setup" - - 1. Create a directory for collator data and copy the chain spec: - ```bash - mkdir -p collator-data - cp chain-spec.json collator-data/ - cp /var/lib/polkadot-collator/node.key collator-data/ - ``` - - 2. Launch the collator using Docker: - ```bash - docker run -d --name polkadot-collator --restart unless-stopped \ - -p 30333:30333 \ - -p 30334:30334 \ - -p 9944:9944 \ - -p 9615:9615 \ - -v $(pwd)/collator-data:/data \ - -v $(pwd)/chain-spec.json:/chain-spec.json \ - parity/polkadot-parachain:stable2509-2 \ - --collator \ - --chain=/chain-spec.json \ - --base-path=/data \ - --port=30333 \ - --rpc-port=9944 \ - --prometheus-port=9615 \ - --prometheus-external \ - --node-key-file=/data/node.key \ - --name="YourCollatorName" \ - --blocks-pruning=256 \ - --state-pruning=256 \ - --database=paritydb \ - -- \ - --chain=polkadot \ - --port=30334 \ - --sync=fast \ - --blocks-pruning=256 \ - --state-pruning=256 \ - --database=paritydb \ - --pool-limit=0 \ - --rpc-port=0 - ``` - - 3. View logs to monitor sync progress: - ```bash - docker logs -f polkadot-collator - ``` - - 4. Use the following commands to manage your Docker container: - - Stop container: - ```bash - docker stop polkadot-collator - ``` - - Start container: - ```bash - docker start polkadot-collator - ``` - - Remove container: - ```bash - docker rm polkadot-collator - ``` - -=== "systemd Setup" - - 1. Create a dedicated user: - ```bash - sudo useradd -r -s /bin/bash polkadot - ``` - - 2. Copy your chain spec to the directory: - ```bash - sudo cp chain-spec.json /var/lib/polkadot-collator/ - ``` - - 3. Set permissions: - ```bash - sudo chown -R polkadot:polkadot /var/lib/polkadot-collator - ``` - - 4. Create a systemd service file: - ```bash - sudo nano /etc/systemd/system/polkadot-collator.service - ``` - - 5. Add the following configuration: - ```ini title="systemd/system/polkadot-collator.service" - [Unit] - Description=Polkadot System Parachain Collator - After=network.target - - [Service] - Type=simple - User=polkadot - Group=polkadot - WorkingDirectory=/var/lib/polkadot-collator - - ExecStart=/usr/local/bin/polkadot-parachain \ - --collator \ - --chain=/var/lib/polkadot-collator/chain-spec.json \ - --base-path=/var/lib/polkadot-collator \ - --port=30333 \ - --rpc-port=9944 \ - --prometheus-port=9615 \ - --node-key-file=/var/lib/polkadot-collator/node.key \ - --name="YourCollatorName" \ - --blocks-pruning=256 \ - --state-pruning=256 \ - --database=paritydb \ - -- \ - --chain=polkadot \ - --port=30334 \ - --sync=fast \ - --blocks-pruning=256 \ - --state-pruning=256 \ - --database=paritydb \ - --pool-limit=0 \ - --rpc-port=0 - - Restart=always - RestartSec=10 - LimitNOFILE=65536 - - [Install] - WantedBy=multi-user.target - ``` - - 6. Start the service: - ```bash - sudo systemctl daemon-reload - sudo systemctl enable polkadot-collator - sudo systemctl start polkadot-collator - ``` - - 7. Check the status: - ```bash - sudo systemctl status polkadot-collator - ``` - - 8. View logs: - ```bash - sudo journalctl -u polkadot-collator -f - ``` - -??? note "Configuration notes" - - - `--collator`: Enables block production mode - - `--node-key-file`: Uses the generated node key for stable peer ID - - `--name`: Your collator name (visible in telemetry) - - `--blocks-pruning=256` and `--state-pruning=256`: Keeps only recent blocks and state, reducing disk usage (collators don't need archive data) - - `--database=paritydb`: Uses ParityDB for better performance - - `--sync=fast`: Fast sync mode for the relay chain - - `--pool-limit=0`: Disables transaction pool on relay chain (collators don't need it) - - `--rpc-port=0` (relay chain): Disables RPC on the embedded relay chain node (not needed for collators) - -## Complete Initial Sync - -Your collator must sync both the relay chain and parachain before producing blocks. - -Sync time depends on: - -- Network bandwidth -- Disk I/O speed -- Current chain size - -The relay chain uses fast sync for faster synchronization. - -!!! warning - - Do not proceed with registration until both chains are fully synced. Monitor sync progress using the log viewing commands in the [Log Management](#log-management) section. - -## Generate Session Keys - -Session keys are cryptographic keys used by your collator node to sign authorship information when producing blocks. They uniquely identify your collator on the network and must be registered on-chain before your collator can participate in block production. - -Once your node is fully synced, use the following command to generate session keys via RPC: - -```bash -curl -H "Content-Type: application/json" \ - -d '{"id":1, "jsonrpc":"2.0", "method": "author_rotateKeys", "params":[]}' \ - http://localhost:9944 -``` - -This command returns session keys as a hexstring in the terminal. You must save these session keys as you'll need them for on-chain registration. As session keys are stored in the node's database, if you wipe the database, you'll also need to generate new keys. - -## Register Collator for Selection - -System parachains use different collator selection mechanisms. Explore the following tabs to see how mechanisms compare and determine the most suitable mechanism for registering your collator. - -=== "Invulnerables List" - - - Fixed list of collators approved through governance. - - Most common for system parachains. - - Requires governance proposal and approval. - - -=== "On-chain Selection" - - - Some parachains use [pallet-collator-selection](https://paritytech.github.io/polkadot-sdk/master/pallet_collator_selection/index.html){target=\_blank}. - - May require bonding tokens. - - Automatic selection based on criteria. - -=== "Fellowship Decisions" - - - Technical Fellowship may manage some system parachain collators. - - Requires Fellowship membership or approval. - -### Registration Process - -Collator registration authorizes your node to produce blocks on the network. The parachain's collator selection mechanism uses this on-chain registration to determine which nodes are eligible to author blocks. - -The registration process varies by system parachain. General steps include the following: - -1. Check the existing collators for your target parachain: - - 1. Navigate to Polkadot.js Apps and connect to your system parachain. - 2. Locate **Developer > Chain State**. - 3. Query `collatorSelection.invulnerables()` - -2. Prepare a governance proposal for invulnerables-based selection including the following information: - - **Draft proposal**: Explain why you should be added as a collator - - **Technical details**: Provide your session keys and account ID - - **Infrastructure**: Describe your hardware and monitoring setup - - **Experience**: Detail your relevant experience - - Submit the proposal to the relevant governance channels on the [Polkadot Forum](https://forum.polkadot.network){target=\_blank}. - -3. Once approved (or if using on-chain selection), follow these steps to register session keys using Polkadot.js Apps: - 1. Navigate to Polkadot.js Apps and connect to your system parachain. - 2. Locate **Developer > Extrinsics**. - 3. Select your account. - 4. Choose the `session.setKeys` extrinsic. - 5. Enter the following information: - - `keys`: Your session keys (from `author_rotateKeys`) - - `proof`: 0x00 (typically) - 6. Submit and sign the transaction. - -4. (Optional - primarily for non-system parachains) If the parachain uses on-chain bonding for collator selection, register as a candidate using Polkadot.js Apps: - - !!! note - Most system parachains use invulnerables lists exclusively and do not require this step. Skip to step 5 if you're running a collator for a system parachain. - - 1. Locate **Developer > Extrinsics**. - 2. Select `collatorSelection.registerAsCandidate`. - 3. Submit and sign the transaction. The required bond amount will be automatically reserved from your account based on the pallet's configured `CandidacyBond`. - -5. For system parachains using invulnerables lists, await governance approval for your proposal. Monitor the [Polkadot Forum](https://forum.polkadot.network){target=\_blank} governance channels and announcements. Once approved, your collator is added to the invulnerables list and will begin producing blocks in the next session or era. - -6. Verify your collator is active by monitoring logs for block production messages like "Prepared block for proposing" and "Imported #123". See the [Log Management](#log-management) section for log viewing commands. - -## Log Management - -Efficient log management is essential to ensure collator performance and uptime. Use the following commands to help you manage logs to monitor and maintain your collator: - -=== "Docker Setup" - - - View logs: - ```bash - docker logs -f polkadot-collator - ``` - - View recent logs (last 100 lines): - ```bash - docker logs --tail 100 polkadot-collator - ``` - - Filter for errors: - ```bash - docker logs polkadot-collator 2>&1 | grep -i error - ``` - - Filter for block production: - ```bash - docker logs polkadot-collator 2>&1 | grep -i "imported" - ``` - -=== "systemd Setup" - - - View recent logs: - ```bash - sudo journalctl -u polkadot-collator -n 100 - ``` - - Follow logs in real-time: - ```bash - sudo journalctl -u polkadot-collator -f - ``` - - Filter for errors: - ```bash - sudo journalctl -u polkadot-collator | grep -i error - ``` - - Filter for block production: - ```bash - sudo journalctl -u polkadot-collator | grep -i "imported" - ``` - -## Database Maintenance - -Check database size periodically using the commands for your selected setup: - -=== "Docker Setup" - - ```bash - # Replace with your mounted data directory path - du -sh ./collator-data - ``` - -=== "systemd Setup" - - ```bash - du -sh /var/lib/polkadot-collator - ``` - -The collator node handles pruning automatically based on configuration. - -## Updates and Upgrades - -Updates or upgrades can happen on either the runtime or client. Runtime upgrades happen automatically via on-chain governance and do not require manual action on your part. Client upgrades do require a manual binary update process performed via terminal commands as follows: - -=== "Docker Setup" - - 1. Stop the service: - ```bash - sudo systemctl stop polkadot-collator - ``` - - 2. Backup data (recommended): - ```bash - sudo cp -r /var/lib/polkadot-collator /var/lib/polkadot-collator.backup - ``` - - 3. Pull the new Docker image: - ```bash - docker pull parity/polkadot-parachain: - ``` - - 4. Update the image tag in your systemd service file: - ```bash - sudo nano /etc/systemd/system/polkadot-collator.service - ``` - - 5. Reload systemd and restart the service: - ```bash - sudo systemctl daemon-reload - sudo systemctl start polkadot-collator - ``` - - 6. Verify the service is running: - ```bash - sudo systemctl status polkadot-collator - ``` - -=== "Manual Setup" - - 1. Stop the service: - ```bash - sudo systemctl stop polkadot-collator - ``` - - 2. Backup data (recommended): - ```bash - sudo cp -r /var/lib/polkadot-collator /var/lib/polkadot-collator.backup - ``` - - 3. Download the new binary from [GitHub releases](https://github.com/paritytech/polkadot-sdk/releases){target=\_blank}: - ```bash - wget https://github.com/paritytech/polkadot-sdk/releases/download//polkadot-parachain - chmod +x polkadot-parachain - sudo mv polkadot-parachain /usr/local/bin/ - ``` - - 4. Verify `polkadot-parachain` version to confirm successful update: - ```bash - polkadot-parachain --version - ``` - - 5. Restart the service: - ```bash - sudo systemctl start polkadot-collator - ``` - - 6. Verify the service is running: - ```bash - sudo systemctl status polkadot-collator - ``` - -## Conclusion - -Running a collator node is essential for parachain operation and network security. By following this guide, you have set up a production-ready collator that: - -- Produces blocks for your parachain and maintains network consensus. -- Implements comprehensive security measures to protect keys and operations. -- Supports robust monitoring and alerting for reliable performance. -- Follows best practices for both Docker and systemd deployments. - -As a collator operator, you play a vital role in your parachain's infrastructure. Regular maintenance, security updates, and monitoring will ensure your collator continues to perform reliably. Stay engaged with your parachain community and keep up with updates to maintain optimal performance and security. diff --git a/.ai/pages/node-infrastructure-run-a-collator.md b/.ai/pages/node-infrastructure-run-a-collator.md new file mode 100644 index 000000000..52c6e3457 --- /dev/null +++ b/.ai/pages/node-infrastructure-run-a-collator.md @@ -0,0 +1,666 @@ +--- +title: Run a Block-Producing Collator +description: Learn how to set up and run a block-producing collator for Polkadot system parachains, including registration and session key management. +categories: Infrastructure +url: https://docs.polkadot.com/node-infrastructure/run-a-collator/ +--- + +# Run a Block-Producing Collator + +## Introduction + +Block-producing collators are the backbone of system parachain operations. Unlike RPC or archive nodes, which maintain state, collators actively produce blocks and submit them to relay chain validators for inclusion. They ensure network liveness, censorship resistance, and cross-chain message processing. + +Collators maintain fully synced relay chain and parachain nodes, aggregate transactions into blocks, create parachain block candidates, generate state transition proofs (Proof-of-Validity), and send block candidates to relay chain validators. They also enable cross-chain message handling via XCM. While critical for liveness, collators do not secure the network—security is provided by relay chain validators through the [ELVES protocol](https://wiki.polkadot.com/learn/learn-parachains-protocol/){target=\_blank}. + +This guide explains how to set up a collator for Polkadot system parachains, covering all key requirements, setting up and registering session keys, and meeting governance approval or invulnerables-list criteria (required for system parachains; non-system parachains may be more permissionless). + +## Prerequisites + +### Hardware Requirements + +Block-producing collators require robust hardware for reliable operation, including the following: + +- **CPU**: 4+ cores (8+ cores recommended for optimal performance) +- **Memory**: 32 GB RAM minimum (64 GB recommended) +- **Storage**: + - 200+ GB NVMe SSD (with pruning enabled for both parachain and relay chain) + - Fast disk I/O is critical for block production performance +- **Network**: + - Public IP address + - 100+ Mbps connection; a stable connection is critical + - Open ports: + - **30333**: Parachain P2P + - **30334**: Relay chain P2P + +!!! warning "Uptime is critical" + Consider redundancy and monitoring to maintain block production reliability. + +### Software Requirements + +Required software: + +- **Operating system**: Ubuntu 22.04 LTS (recommended) or similar Linux distribution +- **[Docker](https://www.docker.com/get-started/){target=\_blank}**: Required for obtaining binaries and running containers + +### Account Requirements + +??? interface "Need to create an account?" + + You can generate an account by taking the following steps: + + 1. Generate an account key with the `sr25519` scheme using the following command: + + ```bash + docker run -it parity/subkey:latest generate --scheme sr25519 + ``` + + The output will be similar to the following: + +
+ docker run -it parity/subkey:latest generate --scheme sr25519 +
Secret phrase:       embody rail hour peanut .... badge syrup luggage canvas
+            Network ID:        substrate
+            Secret seed:       0x6498dd3416c491406e2c8283c76760ce4ca018478888b42315e7718778f2c2e1
+            Public key (hex):  0x2202210357e49390d4f8d868da983940fe220a0a0e00bc6feaeda462aa031810
+            Account ID:        0x2202210357e49390d4f8d868da983940fe220a0a0e00bc6feaeda462aa031810
+            Public key (SS58): 5CqJ7n72GvvF5ZzUT2HMj83KyDje4n8sXR8kuiK8HWtfDktF
+            SS58 Address:      5CqJ7n72GvvF5ZzUT2HMj83KyDje4n8sXR8kuiK8HWtfDktF
+        
+
+ + 2. Save the following items displayed in the output: + - Secret phrase (seed) - Keep this secure! + - Public key (hex) + - Account ID + - SS58 Address + + !!! warning + + Store the secret phrase securely. Never share it. Consider using a hardware wallet for production collators. + +Your account must meet the following requirements: + +- **Funded account**: For on-chain transactions and potential bonding + +You will also need the following, which are generated or configured later in this guide: + +- **Session keys**: For collator identification (generated after node setup) +- **Node key**: For stable P2P peer ID (recommended) + +## Install Dependencies + +This guide provides two deployment options. Select the option that best fits your needs: + +- **Docker**: Best for simpler setup and maintenance +- **systemd**: Best for production environments requiring more control + +=== "Docker" + + 1. Pull the Polkadot Parachain Docker image using the latest stable tag on [Docker Hub](https://hub.docker.com/r/parity/polkadot-parachain/tags){target=\_blank}: + + ```bash + docker pull parity/polkadot-parachain:stable2509-2 + ``` + + 2. Verify the installation: + + ```bash + docker run --rm parity/polkadot-parachain:stable2509-2 --version + ``` + +=== "systemd" + + 1. Download the `polkadot-parachain` binary using the latest stable [Polkadot SDK release](https://github.com/paritytech/polkadot-sdk/releases){target=\_blank}: + + ```bash + wget https://github.com/paritytech/polkadot-sdk/releases/download/polkadot-stable2509-2/polkadot-parachain + ``` + + 2. Make it executable and move it to your system path: + + ```bash + chmod +x polkadot-parachain + sudo mv polkadot-parachain /usr/local/bin/ + sudo chown root:root /usr/local/bin/polkadot-parachain + ``` + + 3. Verify installation: + + ```bash + polkadot-parachain --version + ``` + +## Generate Node Key + +Generating a stable node key enables a consistent peer ID across the network. Follow these steps to generate a node key: + +1. Create a directory for node data: + + ```bash + sudo mkdir -p /var/lib/polkadot-collator + ``` + +2. Generate your node key using Docker: + + ```bash + docker run -it parity/subkey:latest generate-node-key > /var/lib/polkadot-collator/node.key + ``` + +3. Locate your peer ID in the displayed output. It will be similar to the following example: + + ```bash + 12D3KooWExcVYu7Mvjd4kxPVLwN2ZPnZ5NyLZ5ft477wqzfP2q6E + ``` + +Be sure to save the peer ID for future reference. + +## Obtain Chain Specification + +Download the chain specification for your target system parachain using one of the following options: + +=== "Download from Chainspec Collection (Recommended)" + + Follow these steps to download your specification from the [Chainspec Collection](https://paritytech.github.io/chainspecs/){target=\_blank}: + + 1. Find your target system parachain under the [**List of Chainspecs**](https://paritytech.github.io/chainspecs/#list-of-chainspecs){target=\_blank}. + 2. Download the chain specification JSON file. + 3. Save it as `chain-spec.json`. + +=== "Build Chain Spec from Runtime" + + Follow these steps to build a chainspec from the runtime: + + 1. Clone the runtimes repository and navigate into it: + + ```bash + git clone https://github.com/polkadot-fellows/runtimes.git + cd runtimes + ``` + + 2. Build the desired runtime. Use the following command for Polkadot Hub: + + ```bash + cargo build --release -p asset-hub-polkadot-runtime + ``` + + 3. Install the `chain-spec-builder` dependency: + + ```bash + cargo install --locked staging-chain-spec-builder@14.0.0 + ``` + + 4. Finally, generate the chain spec: + + ```bash + chain-spec-builder create \ + --relay-chain polkadot \ + --para-id 1000 \ + --runtime target/release/wbuild/asset-hub-polkadot-runtime/asset_hub_polkadot_runtime.compact.compressed.wasm \ + named-preset production > chain-spec.json + ``` + + ??? tip "System Parachain Para IDs" + + - **Polkadot Hub**: 1000 + - **Bridge Hub**: 1002 + - **People Chain**: 1004 + - **Coretime Chain**: 1005 + +## Run the Collator + +Using your preferred deployment method, take the following steps to set up and run your collator: + +=== "Docker" + + 1. Create a directory for collator data and copy the chain spec: + + ```bash + mkdir -p collator-data + cp chain-spec.json collator-data/ + cp /var/lib/polkadot-collator/node.key collator-data/ + ``` + + 2. Launch the collator using Docker: + + ```bash + docker run -d --name polkadot-collator --restart unless-stopped \ + -p 30333:30333 \ + -p 30334:30334 \ + -p 9944:9944 \ + -p 9615:9615 \ + -v $(pwd)/collator-data:/data \ + -v $(pwd)/chain-spec.json:/chain-spec.json \ + parity/polkadot-parachain:stable2509-2 \ + --collator \ + --chain=/chain-spec.json \ + --base-path=/data \ + --port=30333 \ + --rpc-port=9944 \ + --prometheus-port=9615 \ + --prometheus-external \ + --node-key-file=/data/node.key \ + --name="INSERT_YOUR_COLLATOR_NAME" \ + --blocks-pruning=256 \ + --state-pruning=256 \ + --database=paritydb \ + -- \ + --chain=polkadot \ + --port=30334 \ + --sync=fast \ + --blocks-pruning=256 \ + --state-pruning=256 \ + --database=paritydb \ + --pool-limit=0 \ + --rpc-port=0 + ``` + + 3. View logs to monitor sync progress: + + ```bash + docker logs -f polkadot-collator + ``` + +=== "systemd" + + 1. Create a dedicated user: + + ```bash + sudo useradd -r -s /bin/bash polkadot + ``` + + 2. Copy your chain spec to the directory: + + ```bash + sudo cp chain-spec.json /var/lib/polkadot-collator/ + ``` + + 3. Set permissions: + + ```bash + sudo chown -R polkadot:polkadot /var/lib/polkadot-collator + ``` + + 4. Create a systemd service file: + + ```bash + sudo nano /etc/systemd/system/polkadot-collator.service + ``` + + 5. Add the following configuration: + + ```ini title="systemd/system/polkadot-collator.service" + [Unit] + Description=Polkadot System Parachain Collator + After=network.target + + [Service] + Type=simple + User=polkadot + Group=polkadot + WorkingDirectory=/var/lib/polkadot-collator + + ExecStart=/usr/local/bin/polkadot-parachain \ + --collator \ + --chain=/var/lib/polkadot-collator/chain-spec.json \ + --base-path=/var/lib/polkadot-collator \ + --port=30333 \ + --rpc-port=9944 \ + --prometheus-port=9615 \ + --node-key-file=/var/lib/polkadot-collator/node.key \ + --name="INSERT_YOUR_COLLATOR_NAME" \ + --blocks-pruning=256 \ + --state-pruning=256 \ + --database=paritydb \ + -- \ + --chain=polkadot \ + --port=30334 \ + --sync=fast \ + --blocks-pruning=256 \ + --state-pruning=256 \ + --database=paritydb \ + --pool-limit=0 \ + --rpc-port=0 + + Restart=always + RestartSec=10 + LimitNOFILE=65536 + + [Install] + WantedBy=multi-user.target + ``` + + 6. Start the service: + + ```bash + sudo systemctl daemon-reload + sudo systemctl enable polkadot-collator + sudo systemctl start polkadot-collator + ``` + + 7. Check the status: + + ```bash + sudo systemctl status polkadot-collator + ``` + + 8. View logs: + + ```bash + sudo journalctl -u polkadot-collator -f + ``` + +??? interface "Configuration Arguments" + + - **`--collator`**: Enables block production mode. + - **`--node-key-file`**: Uses the generated node key for stable peer ID. + - **`--name`**: Your collator name (visible in [telemetry](https://telemetry.polkadot.io/){target=\_blank}). + - **`--blocks-pruning=256`**: Keeps the last 256 blocks. + - **`--state-pruning=256`**: Keeps the state history of the last 256 blocks. + - **`--database=paritydb`**: Uses ParityDB for better performance. + - **`--sync=fast`**: Fast sync mode for the relay chain. + - **`--pool-limit=0`**: Disables transaction pool on relay chain (not needed for collators). + - **`--rpc-port=0` (relay chain)**: Disables RPC on the embedded relay chain node (not needed for collators). + +Your collator must sync both the relay chain and parachain before producing blocks. The relay chain uses fast sync to speed up synchronization. Overall sync time depends on: + +- Network bandwidth +- Disk I/O speed +- Current chain size + +!!! warning + + Do not proceed with registration until both chains are fully synced. Monitor sync progress using the log viewing commands in the [Log Management](#commands-for-log-management) section. + +## Generate Session Keys + +Session keys are cryptographic keys used by your collator node to sign authorship information when producing blocks. They uniquely identify your collator on the network and must be registered on-chain before your collator can participate in block production. + +Once your node is fully synced, use the following command to generate session keys via RPC: + +```bash +curl -H "Content-Type: application/json" \ + -d '{"id":1, "jsonrpc":"2.0", "method": "author_rotateKeys", "params":[]}' \ + http://localhost:9944 +``` + +This command returns session keys as a hex string in the terminal. You must save these session keys as you'll need them for on-chain registration. As session keys are stored in the node's database, if you wipe the database, you'll also need to generate new keys. + +## Register Collator for Selection + +System parachains use different mechanisms for selecting collators. A quick breakdown of each mechanism is as follows: + +| Method | How it Works | Requirements | +|--------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|------------------------------------------------------------------| +| **Invulnerables list** | Fixed list defined through governance. Most common for system parachains. | Permissioned via governance | +| **On-chain selection** | Runtime automatically selects eligible collators. Some parachains use [pallet-collator-selection](https://paritytech.github.io/polkadot-sdk/master/pallet_collator_selection/index.html){target=\_blank}. | Semi-permissionless (criteria-based; may require bonding tokens) | +| **Fellowship decisions** | Technical fellowship may manage some system parachain collators. | Permissioned via Fellowship | + +### Registration Process + +Collator registration authorizes your node to produce blocks on the network. The parachain's collator selection mechanism uses this on-chain registration to determine which nodes are eligible to author blocks. + +The registration process varies by system parachain. General steps include the following: + +1. Check the existing collators for your target parachain: + 1. Navigate to Polkadot.js Apps and connect to your system parachain. + 2. Locate **Developer > Chain State**. + 3. Query **`collatorSelection.invulnerables()`**. + + ![](/images/node-infrastructure/run-a-collator/run-a-collator-01.webp) + +2. Prepare a governance proposal for invulnerables-based selection, including the following information: + + - **Draft proposal**: Explain why you should be added as a collator. + - **Technical details**: Provide your session keys and account ID. + - **Infrastructure**: Describe your hardware and monitoring setup. + - **Experience**: Detail your relevant experience. + + Submit the proposal to the relevant governance channels. + +3. Once approved (or if using on-chain selection), follow these steps to register session keys using Polkadot.js Apps: + + 1. Locate **Developer > Extrinsics**. + 2. Select your account. + 3. Choose the **`session.setKeys`** extrinsic. + 4. Enter the following information: + - **`keys`**: Your session keys (from `author_rotateKeys`) + - **`proof`**: 0x00 (typically) + 5. Click **Submit Transaction** and sign the transaction. + + ![](/images/node-infrastructure/run-a-collator/run-a-collator-02.webp) + +4. (Optional - primarily for non-system parachains) If the parachain uses on-chain bonding for collator selection, register as a candidate using Polkadot.js Apps: + + !!! note + Most system parachains use invulnerables lists exclusively and do not require this step. Skip to step 5 if you're running a collator for a system parachain. + + 1. Locate **Developer > Extrinsics**. + 2. Select your account. + 3. Select `collatorSelection.registerAsCandidate`. + 4. Click **Submit Transaction** and sign the transaction. The required bond amount will be automatically reserved from your account based on the pallet's configured `CandidacyBond`. + + ![](/images/node-infrastructure/run-a-collator/run-a-collator-03.webp) + +5. For system parachains using invulnerables lists, await governance approval for your proposal. Once approved, your collator is added to the invulnerables list and will begin producing blocks in the next session or era. + +6. Verify your collator is active by monitoring logs for block production messages like "Prepared block for proposing" and "Imported #123". See the [Log Management](#commands-for-log-management) section for commands for log viewing. + +## Commands for Node Management + +Use the following commands to manage your node: + +=== "Docker" + + - **Stop container**: + + ```bash + docker stop polkadot-collator + ``` + + - **Start container**: + + ```bash + docker start polkadot-collator + ``` + + - **Remove container**: + + ```bash + docker rm polkadot-collator + ``` + +=== "systemd" + + - **Check status**: + + ```bash + sudo systemctl status polkadot-collator + ``` + + - **Stop service**: + + ```bash + sudo systemctl stop polkadot-collator + ``` + + - **Enable service**: + + ```bash + sudo systemctl enable polkadot-collator + ``` + + - **Start service**: + + ```bash + sudo systemctl start polkadot-collator + ``` + +## Commands for Log Management + +Efficient log management is essential to ensure collator performance and uptime. Use the following commands to help you manage logs to monitor and maintain your collator: + +=== "Docker" + + - **View logs**: + + ```bash + docker logs -f polkadot-collator + ``` + + - **View recent logs (last 100 lines)**: + + ```bash + docker logs --tail 100 polkadot-collator + ``` + + - **Filter for errors**: + + ```bash + docker logs polkadot-collator 2>&1 | grep -i error + ``` + + - **Filter for block production**: + + ```bash + docker logs polkadot-collator 2>&1 | grep -i "imported" + ``` + +=== "systemd" + + - **View recent logs**: + + ```bash + sudo journalctl -u polkadot-collator -n 100 + ``` + + - **Follow logs in real-time**: + + ```bash + sudo journalctl -u polkadot-collator -f + ``` + + - **Filter for errors**: + + ```bash + sudo journalctl -u polkadot-collator | grep -i error + ``` + + - **Filter for block production**: + + ```bash + sudo journalctl -u polkadot-collator | grep -i "imported" + ``` + +## Database Maintenance + +Check database size periodically using the commands for your selected setup: + +=== "Docker" + + ```bash + # Replace with your mounted data directory path + du -sh ./collator-data + ``` + +=== "systemd" + + ```bash + du -sh /var/lib/polkadot-collator + ``` + +The collator node automatically prunes based on configuration. + +## Updates and Upgrades + +Updates or upgrades can happen on either the runtime or client. Runtime upgrades are automatically applied via on-chain governance and do not require any manual action on your part. Client upgrades do require a manual binary update process performed via terminal commands as follows: + +=== "Docker" + + 1. Stop the service: + + ```bash + sudo systemctl stop polkadot-collator + ``` + + 2. Backup data (recommended): + + ```bash + sudo cp -r /var/lib/polkadot-collator /var/lib/polkadot-collator.backup + ``` + + 3. Pull the new Docker image: + + ```bash + docker pull parity/polkadot-parachain: + ``` + + 4. Update the image tag in your systemd service file: + + ```bash + sudo nano /etc/systemd/system/polkadot-collator.service + ``` + + 5. Reload systemd and restart the service: + + ```bash + sudo systemctl daemon-reload + sudo systemctl start polkadot-collator + ``` + + 6. Verify the service is running: + + ```bash + sudo systemctl status polkadot-collator + ``` + +=== "systemd" + + 1. Stop the service: + + ```bash + sudo systemctl stop polkadot-collator + ``` + + 2. Backup data (recommended): + + ```bash + sudo cp -r /var/lib/polkadot-collator /var/lib/polkadot-collator.backup + ``` + + 3. Download the new binary from [GitHub releases](https://github.com/paritytech/polkadot-sdk/releases){target=\_blank}: + + ```bash + wget https://github.com/paritytech/polkadot-sdk/releases/download/INSERT_NEW_VERSION/polkadot-parachain + chmod +x polkadot-parachain + sudo mv polkadot-parachain /usr/local/bin/ + ``` + + 4. Verify `polkadot-parachain` version to confirm successful update: + + ```bash + polkadot-parachain --version + ``` + + 5. Restart the service: + + ```bash + sudo systemctl start polkadot-collator + ``` + + 6. Verify the service is running: + + ```bash + sudo systemctl status polkadot-collator + ``` + +## Conclusion + +Running a collator node is essential for parachain operation and network security. By following this guide, you have set up a production-ready collator that: + +- Produces blocks for your parachain and maintains network consensus. +- Implements comprehensive security measures to protect keys and operations. +- Supports robust monitoring and alerting for reliable performance. +- Follows best practices for both Docker and systemd deployments. + +As a collator operator, you play a vital role in your parachain's infrastructure. Regular maintenance, security updates, and monitoring will ensure your collator continues to perform reliably. Stay engaged with your parachain community and keep up with updates to maintain optimal performance and security. diff --git a/.ai/pages/node-infrastructure-run-a-node-parachain-rpc.md b/.ai/pages/node-infrastructure-run-a-node-parachain-rpc.md index fe0c5c578..067f1eb1d 100644 --- a/.ai/pages/node-infrastructure-run-a-node-parachain-rpc.md +++ b/.ai/pages/node-infrastructure-run-a-node-parachain-rpc.md @@ -1,56 +1,17 @@ --- title: Run a Parachain RPC Node -description: Complete guide to set up and run an RPC node for any Polkadot parachain, with system parachains as examples. +description: Follow this guide to understand hardware and software requirements and how to set up and run an RPC node for any parachain, including system parachains. categories: Infrastructure url: https://docs.polkadot.com/node-infrastructure/run-a-node/parachain-rpc/ --- # Run a Parachain RPC Node -## Overview +## Introduction -Running an RPC node for a parachain enables applications, wallets, and users to interact with the parachain's functionality. +A parachain RPC node provides direct access to a specific parachain on the Polkadot network, enabling developers and applications to interact with its assets, governance, cross-chain messages, and more. Running your own node also supports essential infrastructure tasks, such as block indexing and compatibility with Polkadot SDK tools. -Each parachain RPC node provides access through the Polkadot SDK Node RPC (Port 9944), offering native Polkadot API access via WebSocket and HTTP. This setup enables block explorer indexing and provides full compatibility with Polkadot SDK development tools. - -!!! note - - The parameters and configurations in this guide are provided as illustrative examples. You may need to modify them according to your specific environment, hardware capabilities, and network conditions. - -## Obtaining a Chain Specification - -To run an RPC node for any parachain, you need its **chain specification file**. This JSON file defines the network parameters, genesis state, and bootnodes. - -### System Parachains - -System parachain chain specs are available from multiple sources: - -**Option 1: Chainspec Collection (Recommended)** - -Visit the [Chainspec Collection](https://paritytech.github.io/chainspecs/) to download official chain specifications. - -**Option 2: Polkadot SDK Repository** - -Download directly from the Polkadot SDK repository: - -```bash -# Example for People Chain -curl -L https://raw.githubusercontent.com/paritytech/polkadot-sdk/master/cumulus/parachains/chain-specs/people-polkadot.json -o chain-spec.json -``` - -| System Parachain | Para ID | Chain Spec File | Snapshot Path | -|------------------|---------|-----------------|---------------| -| **Bridge Hub** | 1002 | `bridge-hub-polkadot.json` | `polkadot-bridge-hub-paritydb-archive` | -| **People Chain** | 1004 | `people-polkadot.json` | `polkadot-people-rocksdb-archive` | -| **Coretime Chain** | 1005 | `coretime-polkadot.json` | `polkadot-coretime-rocksdb-archive` | - -### Other Parachains - -For non-system parachains, check the parachain's documentation for official chain specification files. - -!!! note - - Throughout this guide, we use **People Chain** as the example. To set up a different parachain, substitute the chain spec file, snapshot path, and chain name with values for your target parachain. +Through the parachain RPC (WebSocket port 9944, HTTP port 9933), your node acts as the bridge between the parachain and applications. This page walks through setting up a node from scratch, covering hardware requirements and deployment options using Docker or systemd. ## Prerequisites @@ -58,109 +19,137 @@ For non-system parachains, check the parachain's documentation for official chai RPC nodes serving production traffic require robust hardware: -- **CPU**: 8+ cores (16+ cores for high traffic) -- **Memory**: 64 GB RAM minimum (128 GB recommended for high traffic) -- **Storage**: - - Archive node: Storage varies by parachain. Using snapshots, system parachain totals are: Asset Hub (~1.2 TB), Bridge Hub (~1.1 TB), Collectives (~1 TB), People Chain (~900 GB), Coretime (~900 GB). For non-system parachains, check the [snapshot sizes](https://snapshots.polkadot.io/){target=\_blank} and add ~822 GB for the relay chain. - - Pruned node: 200+ GB NVMe SSD (with pruning enabled for both parachain and relay chain) - - Fast disk I/O is critical for query performance +- **CPU**: 8+ cores; 16+ cores for high traffic +- **Memory**: 64 GB RAM minimum; 128 GB recommended for high traffic +- **Storage**: Storage requirements vary by parachain. Fast NVMe I/O is critical for RPC query performance + - **System parachains**: [Snapshots](https://snapshots.polkadot.io/){target=\_blank} _may_ be available + - **Archive node (complete history)**: Using snapshots, expected storage requirements (including ~822 GB for the pruned relay chain) are: + - **Asset Hub**: ~1.2 TB + - **Bridge Hub**: ~1.1 TB + - **Collectives**: ~1 TB + - **People Chain**: ~900 GB + - **Coretime**: ~900 GB + - **Pruned node (recent state)**: ~200 GB total for both parachain and relay chain + - **Non-system parachains**: Consult the parachain team or documentation, then add ~822 GB for the pruned relay chain - **Network**: - Public IP address - - 1 Gbps connection (for high traffic scenarios) - Stable internet connection with sufficient bandwidth - - Open ports: - - 30333 (parachain P2P) - - 30334 (relay chain P2P) - - 9944 (Polkadot SDK WebSocket RPC) - - 9933 (Polkadot SDK HTTP RPC) + - 1 Gbps connection for high traffic scenarios - Consider DDoS protection and rate limiting for production deployments + - Open ports: + - **30333**: Parachain P2P + - **30334**: Relay chain P2P + - **9944**: Polkadot SDK WebSocket RPC + - **9933**: Polkadot SDK HTTP RPC !!! note - - For development or low-traffic scenarios, you can reduce these requirements proportionally. Consider using a reverse proxy (nginx, Caddy) for production deployments. + For development or low-traffic scenarios, you can reduce these requirements proportionally. Consider using a reverse proxy ([nginx](https://nginx.org/){target=\_blank}, [Caddy](https://caddyserver.com/){target=\_blank}) for production deployments. ### Software Requirements Required software: -- **Operating System**: Ubuntu 22.04 LTS (recommended) or similar Linux distribution -- **Docker**: Required for obtaining binaries and running containers -- **rclone**: (Optional but recommended) Command-line program for managing files on cloud storage (https://rclone.org/downloads/) +- **Operating system**: Ubuntu 22.04 LTS (recommended) or similar Linux distribution +- **[Docker](https://www.docker.com/get-started/){target=\_blank}**: Required for obtaining binaries and running containers +- **[rclone](https://rclone.org/downloads/){target=\_blank}**: (Optional but recommended) Command-line program for managing files on cloud storage -## Setup Options +## Obtain the Chain Specification -This guide provides two options for deployment: +To run an RPC node for a parachain, you need its chain specification file. This JSON file defines the network parameters, genesis state, and bootnodes. The process for obtaining the chain spec may differ depending on whether you’re running a system parachain or a regular parachain. -- **Docker-based Setup**: Best for simpler set up and maintenance -- **Manual/systemd Setup**: Best for production environments requiring more control +### System Parachains -Select the best option for your project, then use the steps in the following tabs to complete set up. +System parachain chain specs are available from multiple sources: -=== "Docker-Based Setup" +- **[Chainspec Collection](https://paritytech.github.io/chainspecs/)**: (Recommended) Choose a file to download from the **List of Chainspecs** section. +- **[Polkadot SDK repository](https://github.com/paritytech/polkadot-sdk){target=\_blank}**: Download directly from the Polkadot SDK repository: - This option uses Docker containers for the Polkadot SDK node, making it easy to set up and manage. Follow these steps to set your RPC node using Docker: + ```bash + # Example for People Chain + curl -L https://raw.githubusercontent.com/paritytech/polkadot-sdk/master/cumulus/parachains/chain-specs/people-polkadot.json -o chain-spec.json + ``` - 1. Download your parachain's chain specification as described in [Obtaining a Chain Specification](#obtaining-a-chain-specification). +### Other Parachains - 2. (Optional but recommended) Download database snapshots: - - Using pre-synchronized snapshots significantly reduces initial sync time from several days to just a few hours. You need to download both parachain and relay chain data. - - You can obtain the latest snapshot from the [Snapshot Provider](https://snapshots.polkadot.io/){target=\_blank}. Follow these steps to download and use snapshots: +For non-system parachains, check the parachain's documentation for official chain specification files. - !!! note +## Spin Up a Node - Snapshots are available for system parachains and the Polkadot relay chain. For other parachains, check with the parachain team for snapshot availability or sync from genesis. +Choose the deployment option that fits your project, and follow the steps in the appropriate tab to complete setup: - 1. Create new directories with the following commands: - ```bash - mkdir -p my-node-data/chains/people-polkadot/db - mkdir -p my-node-data/chains/polkadot/db - ``` - 2. Download the snapshots: +- **Docker**: Best for simpler set up and maintenance +- **systemd**: Best for production environments requiring more control - **Parachain archive snapshot** (People Chain example, ~71 GB): - ```bash - # Check https://snapshots.polkadot.io/ for the latest snapshot URL - export SNAPSHOT_URL_PARACHAIN="https://snapshots.polkadot.io/polkadot-people-rocksdb-archive/LATEST" +This guide uses **People Chain** as an example. To set up a different parachain, replace the chain spec file, snapshot path, and chain name with the corresponding values for your target parachain. - rclone copyurl $SNAPSHOT_URL_PARACHAIN/files.txt files.txt - rclone copy --progress --transfers 20 \ - --http-url $SNAPSHOT_URL_PARACHAIN \ - --no-traverse --http-no-head --disable-http2 \ - --inplace --no-gzip-encoding --size-only \ - --retries 6 --retries-sleep 10s \ - --files-from files.txt :http: my-node-data/chains/people-polkadot/db/ +System parachain details: - rm files.txt - ``` +| System Parachain | Para ID | Chain Spec File | Snapshot Path | +|--------------------|---------|----------------------------|----------------------------------------| +| **Bridge Hub** | 1002 | `bridge-hub-polkadot.json` | `polkadot-bridge-hub-paritydb-archive` | +| **People Chain** | 1004 | `people-polkadot.json` | `polkadot-people-rocksdb-archive` | +| **Coretime Chain** | 1005 | `coretime-polkadot.json` | `polkadot-coretime-rocksdb-archive` | - **Relay chain pruned snapshot** (~822 GB): - ```bash - # Check https://snapshots.polkadot.io/ for the latest snapshot URL - export SNAPSHOT_URL_RELAY="https://snapshots.polkadot.io/polkadot-paritydb-prune/LATEST" +=== "Docker" - rclone copyurl $SNAPSHOT_URL_RELAY/files.txt files.txt - rclone copy --progress --transfers 20 \ - --http-url $SNAPSHOT_URL_RELAY \ - --no-traverse --http-no-head --disable-http2 \ - --inplace --no-gzip-encoding --size-only \ - --retries 6 --retries-sleep 10s \ - --files-from files.txt :http: my-node-data/chains/polkadot/db/ + 1. Download your parachain's chain specification as described in [Obtain the Chain Specification](#obtain-the-chain-specification). - rm files.txt - ``` + 2. (Optional but recommended) Download pre-synced [snapshots](https://snapshots.polkadot.io/){target=\_blank} to cut initial sync time from days to hours: - **rclone parameters:** + !!! note + Snapshots are available for system parachains and the Polkadot relay chain. For other parachains, check with the parachain team for snapshot availability or sync from genesis. - - `--transfers 20`: Uses 20 parallel transfers for faster download - - `--retries 6`: Automatically retries failed transfers up to 6 times - - `--retries-sleep 10s`: Waits 10 seconds between retry attempts - - `--size-only`: Only transfers if sizes differ (prevents unnecessary re-downloads) + 1. Create new directories: - 3. Launch the parachain node using the official [Parity Docker image](https://hub.docker.com/r/parity/polkadot-parachain){target=\_blank}: + ```bash + mkdir -p my-node-data/chains/people-polkadot/db + mkdir -p my-node-data/chains/polkadot/db + ``` + + 2. Download and save the archive parachain snapshot: + + ```bash + # Check https://snapshots.polkadot.io/ for the latest snapshot URL + export SNAPSHOT_URL_PARACHAIN="https://snapshots.polkadot.io/polkadot-people-rocksdb-archive/INSERT_LATEST" + + rclone copyurl $SNAPSHOT_URL_PARACHAIN/files.txt files.txt + rclone copy --progress --transfers 20 \ + --http-url $SNAPSHOT_URL_PARACHAIN \ + --no-traverse --http-no-head --disable-http2 \ + --inplace --no-gzip-encoding --size-only \ + --retries 6 --retries-sleep 10s \ + --files-from files.txt :http: my-node-data/chains/people-polkadot/db/ + + rm files.txt + ``` + + ??? interface "rclone parameters" - === "Archive Node" + - **`--transfers 20`**: Uses 20 parallel transfers for faster download + - **`--retries 6`**: Automatically retries failed transfers up to 6 times + - **`--retries-sleep 10s`**: Waits 10 seconds between retry attempts + - **`--size-only`**: Only transfers if sizes differ (prevents unnecessary re-downloads) - Archive node configuration maintains complete parachain history for historical queries: + 3. Repeat the process for the pruned relay chain snapshot: + + ```bash + # Check https://snapshots.polkadot.io/ for the latest snapshot URL + export SNAPSHOT_URL_RELAY="https://snapshots.polkadot.io/polkadot-rocksdb-prune/INSERT_LATEST" + + rclone copyurl $SNAPSHOT_URL_RELAY/files.txt files.txt + rclone copy --progress --transfers 20 \ + --http-url $SNAPSHOT_URL_RELAY \ + --no-traverse --http-no-head --disable-http2 \ + --inplace --no-gzip-encoding --size-only \ + --retries 6 --retries-sleep 10s \ + --files-from files.txt :http: my-node-data/chains/polkadot/db/ + + rm files.txt + ``` + + 3. Launch the parachain node using the official [Parity Docker image](https://hub.docker.com/r/parity/polkadot-parachain){target=\_blank}: + + === "Archive" ```bash docker run -d --name people-chain-rpc --restart unless-stopped \ @@ -192,9 +181,7 @@ Select the best option for your project, then use the steps in the following tab --rpc-port=0 ``` - === "Pruned Node" - - Pruned node configuration keeps recent state for smaller storage requirements: + === "Pruned" ```bash docker run -d --name people-chain-rpc --restart unless-stopped \ @@ -227,99 +214,14 @@ Select the best option for your project, then use the steps in the following tab ``` !!! note - The `parity/polkadot-parachain` image works for system parachains and parachains built with standard Cumulus templates. For parachains with custom runtimes, check the parachain's documentation for their specific Docker image or binary. - Critical configuration parameters include port mappings and node parameters: - - === "Port mappings" - - - `9944`: Polkadot SDK RPC endpoint (WebSocket/HTTP) - - `9933`: Polkadot SDK HTTP RPC endpoint - - `9615`: Prometheus metrics endpoint - - `30333/30334`: P2P networking ports - - === "Node parameters" - - - `--unsafe-rpc-external`: Enables external RPC access - - `--rpc-cors=all`: Allows all origins for CORS - - `--rpc-methods=safe`: Only allows safe RPC methods - - `--state-pruning=archive` or `--state-pruning=1000`: Archive keeps complete state history, pruned keeps last 1000 blocks - - `--blocks-pruning=archive` or `--blocks-pruning=256`: Archive keeps all blocks, pruned keeps last 256 finalized blocks - - `--prometheus-external`: Exposes metrics externally - - !!! warning + Refer to the [Port Mappings](#port-mappings) and [Node Configuration Arguments](#node-configuration-arguments) sections for details on the command's configurations. - The `--unsafe-rpc-external` flag should only be used in development or properly secured environments. For production, use a reverse proxy with authentication. - - 4. Monitor the node synchronization status using the following command: - ```bash - curl -H "Content-Type: application/json" \ - -d '{"id":1, "jsonrpc":"2.0", "method": "system_syncState", "params":[]}' \ - http://localhost:9944 - ``` - - You should see a response similar to the following: - - ```json - { - "jsonrpc":"2.0", - "id":1, - "result":{ - "startingBlock":0, - "currentBlock":3394816, - "highestBlock":3394816 - } - } - ``` - - When synchronization is complete, `currentBlock` will be equal to `highestBlock`. - - 5. You can use a few different commands to verify your node is running properly: - - - Get chain information: - ```bash - curl -H "Content-Type: application/json" \ - -d '{"id":1, "jsonrpc":"2.0", "method": "system_chain", "params":[]}' \ - http://localhost:9944 - ``` - - Get the latest block: - ```bash - curl -H "Content-Type: application/json" \ - -d '{"id":1, "jsonrpc":"2.0", "method": "chain_getHeader", "params":[]}' \ - http://localhost:9944 - ``` - - Query node health: - ```bash - curl -H "Content-Type: application/json" \ - -d '{"id":1, "jsonrpc":"2.0", "method": "system_health", "params":[]}' \ - http://localhost:9944 - ``` - - 6. Use the following commands to manage your Docker containers: - - - View node logs: - ```bash - docker logs -f people-chain-rpc - ``` - - Stop container: - ```bash - docker stop people-chain-rpc - ``` - - Start container: - ```bash - docker start people-chain-rpc - ``` - - Remove container: - ```bash - docker rm people-chain-rpc - ``` - -=== "Manual systemd Setup" - - This option provides more control and is recommended for production environments requiring custom configurations. +=== "systemd" 1. Download the `polkadot-parachain` binary from the latest stable [Polkadot SDK release](https://github.com/paritytech/polkadot-sdk/releases){target=\_blank}: + ```bash # Download the latest stable release (check releases page for current version) wget https://github.com/paritytech/polkadot-sdk/releases/download/polkadot-stable2509-2/polkadot-parachain @@ -332,38 +234,33 @@ Select the best option for your project, then use the steps in the following tab polkadot-parachain --version ``` - Check the [Polkadot SDK releases](https://github.com/paritytech/polkadot-sdk/releases){target=\_blank} page for the latest stable version. + 2. Download your parachain's chain specification as described in [Obtain the Chain Specification](#obtain-the-chain-specification). - 2. Download your parachain's chain specification as described in [Obtaining a Chain Specification](#obtaining-a-chain-specification). + 3. Create user and directory structures: - 3. Create user and directory structures using the following commands: - - Create a dedicated user: - ```bash - sudo useradd -r -s /bin/bash polkadot - ``` - - Create data directory: - ```bash - sudo mkdir -p /var/lib/people-chain-rpc - ``` - - Copy the chain spec to the directory: - ```bash - sudo cp people-polkadot.json /var/lib/people-chain-rpc/ - ``` - - Set permissions: - ```bash - sudo chown -R polkadot:polkadot /var/lib/people-chain-rpc - ``` + ```bash + # Create a dedicated user + sudo useradd -r -s /bin/bash polkadot + + # Create data directory + sudo mkdir -p /var/lib/people-chain-rpc + + # Copy the chain spec to the directory + sudo cp asset-hub-polkadot.json /var/lib/people-chain-rpc/ + + # Set permissions + sudo chown -R polkadot:polkadot /var/lib/people-chain-rpc + ``` 4. Create a systemd service file for the Polkadot SDK RPC node: + ```bash sudo nano /etc/systemd/system/people-chain-rpc.service ``` - 5. Open the new service file and add the configuration for your chosen node type: - - === "Archive Node" + 5. Open the new service file and add the configuration for either an archive (complete history) or pruned (recent state) node: - Archive node configuration maintains complete parachain history for historical queries: + === "Archive" ```ini [Unit] @@ -406,9 +303,7 @@ Select the best option for your project, then use the steps in the following tab WantedBy=multi-user.target ``` - === "Pruned Node" - - Pruned node configuration keeps recent state for smaller storage requirements: + === "Pruned" ```ini [Unit] @@ -451,44 +346,135 @@ Select the best option for your project, then use the steps in the following tab WantedBy=multi-user.target ``` - 6. Start the service using the following commands: - - Reload systemd: - ```bash - sudo systemctl daemon-reload - ``` - - Enable service to start on boot: - ```bash - sudo systemctl enable people-chain-rpc - ``` - - Start the Polkadot SDK node: - ```bash - sudo systemctl start people-chain-rpc - ``` - - Check status and wait for sync: - ```bash - sudo systemctl status people-chain-rpc - sudo journalctl -u people-chain-rpc -f - ``` + Refer to the [Port Mappings](#port-mappings) and [Node Configuration Arguments](#node-configuration-arguments) sections for details on the command's configurations. - 7. You can use a few different commands to verify your node is running properly: - - Get chain information: - ```bash - curl -H "Content-Type: application/json" \ - -d '{"id":1, "jsonrpc":"2.0", "method": "system_chain", "params":[]}' \ - http://localhost:9944 - ``` - - Get the latest block: - ```bash - curl -H "Content-Type: application/json" \ - -d '{"id":1, "jsonrpc":"2.0", "method": "chain_getHeader", "params":[]}' \ - http://localhost:9944 - ``` - - Query node health: - ```bash - curl -H "Content-Type: application/json" \ - -d '{"id":1, "jsonrpc":"2.0", "method": "system_health", "params":[]}' \ - http://localhost:9944 - ``` + 6. Start the service: + + ```bash + # Reload systemd + sudo systemctl daemon-reload + + # Enable service to start on boot + sudo systemctl enable people-chain-rpc + + # Start the Polkadot SDK node: + sudo systemctl start people-chain-rpc + ``` + +### Port Mappings + +- **`9944`**: Polkadot SDK RPC endpoint (WebSocket/HTTP) +- **`9933`**: Polkadot SDK HTTP RPC endpoint +- **`9615`**: Prometheus metrics endpoint +- **`30333/30334`**: P2P networking ports + +### Node Configuration Parameters + +- **`--unsafe-rpc-external`**: Enables external RPC access. **This command should only be used in development or properly secured environments**. For production, use a reverse proxy with authentication. +- **`--rpc-cors=all`**: Allows all origins for CORS. +- **`--rpc-methods=safe`**: Only allows safe RPC methods. +- **`--state-pruning`**: Archive keeps complete state history, pruned keeps last specified number of blocks. +- **`--blocks-pruning`**: Archive keeps all blocks, pruned keeps last specified number of finalized blocks. +- **`--prometheus-external`**: Exposes metrics externally. + +## Monitor Node Synchronization + +Monitor the node synchronization status: + +```bash +curl -H "Content-Type: application/json" \ +-d '{"id":1, "jsonrpc":"2.0", "method": "system_syncState", "params":[]}' \ +http://localhost:9944 +``` + +When synchronization is complete, `currentBlock` will be equal to `highestBlock`: + +
+ curl -H "Content-Type: application/json" \ + -d '{"id":1, "jsonrpc":"2.0", "method": "system_syncState", "params":[]}' \ + http://localhost:9944 +
{
+  "jsonrpc":"2.0",
+  "id":1,
+  "result":{
+    "startingBlock":0,
+    "currentBlock":3394816,
+    "highestBlock":3394816
+  }
+}
+  
+
+ +!!! tip + You can use the `system_health` command to verify your node is running properly. + + ```bash + curl -H "Content-Type: application/json" \ + -d '{"id":1, "jsonrpc":"2.0", "method": "system_health", "params":[]}' \ + http://localhost:9944 + ``` + +## Commands for Managing Your Node + +Use the following commands to manage your node: + +=== "Docker" + + - **View node logs**: + + ```bash + docker logs -f people-chain-rpc + ``` + + - **Stop container**: + + ```bash + docker stop people-chain-rpc + ``` + + - **Start container**: + + ```bash + docker start people-chain-rpc + ``` + + - **Remove container**: + + ```bash + docker rm people-chain-rpc + ``` + +=== "systemd" + + - **Check status**: + + ```bash + sudo systemctl status people-chain-rpc + ``` + + - **View node logs**: + + ```bash + sudo journalctl -u people-chain-rpc -f + ``` + + - **Stop service**: + + ```bash + sudo systemctl stop people-chain-rpc + ``` + + - **Enable service**: + + ```bash + sudo systemctl enable people-chain-rpc + ``` + + - **Start service**: + + ```bash + sudo systemctl start people-chain-rpc + ``` ## Conclusion diff --git a/.ai/pages/node-infrastructure-run-a-node-polkadot-hub-rpc.md b/.ai/pages/node-infrastructure-run-a-node-polkadot-hub-rpc.md index 8c2c946d9..622fb0496 100644 --- a/.ai/pages/node-infrastructure-run-a-node-polkadot-hub-rpc.md +++ b/.ai/pages/node-infrastructure-run-a-node-polkadot-hub-rpc.md @@ -7,23 +7,13 @@ url: https://docs.polkadot.com/node-infrastructure/run-a-node/polkadot-hub-rpc/ # Run an RPC Node for Polkadot Hub -## Overview +## Introduction -[Polkadot Hub](/reference/polkadot-hub/){target=\_blank} is the entry point to Polkadot for all users and application developers. It provides access to essential Web3 services, including: +Polkadot Hub is the gateway to the Polkadot network, providing access to core services such as asset management, governance, and cross-chain messaging. Running your own RPC node gives developers and applications direct access to these services while also supporting infrastructure tasks like block indexing and SDK tool compatibility. -- **Asset Management**: Native support for fungible and non-fungible assets -- **Governance, Staking, and Treasury**: Core protocol operations -- **Cross-chain Communication**: XCM message handling -Running an RPC node for Polkadot Hub enables applications, wallets, and users to interact with the parachain through: -- **Polkadot SDK Node RPC** (Port 9944): Native Polkadot API (WebSocket and HTTP) - -This setup enables block explorer indexing and provides full compatibility with Polkadot SDK development tools. - -!!! note - - The parameters and configurations in this guide are provided as illustrative examples. You may need to modify them according to your specific environment, hardware capabilities, and network conditions. +Through the Polkadot SDK node RPC (WebSocket port 9944, HTTP port 9933), your node serves as the bridge between the network and applications. This page guides you through setting up a node from scratch, including hardware requirements and deployment options using Docker or systemd. ## Prerequisites @@ -31,108 +21,104 @@ This setup enables block explorer indexing and provides full compatibility with RPC nodes serving production traffic require robust hardware. The following should be considered the minimum standard to effectively operate an RPC node: -- **CPU**: 8+ cores (16+ cores for high traffic) -- **Memory**: 64 GB RAM minimum (128 GB recommended for high traffic) +- **CPU**: 8+ cores; 16+ cores for high traffic +- **Memory**: 64 GB RAM minimum; 128 GB recommended for high traffic - **Storage**: - - Archive node: ~1.2 TB NVMe SSD total (~392 GB for Asset Hub archive + ~822 GB for relay chain pruned snapshot) - - Pruned node: 200+ GB NVMe SSD (with pruning enabled for both parachain and relay chain) + - **Archive node (complete history)**: ~1.2 TB NVMe SSD total (~392 GB for Asset Hub archive + ~822 GB for relay chain pruned snapshot) + - **Pruned node (recent state)**: ~200 GB NVMe SSD total (with pruning enabled for both parachain and relay chain) - Fast disk I/O is critical for query performance - **Network**: - Public IP address - - 1 Gbps connection (for high traffic scenarios) - Stable internet connection with sufficient bandwidth - - Open ports: - - 30333 (parachain P2P) - - 30334 (relay chain P2P) - - 9944 (Polkadot SDK WebSocket RPC) - - 9933 (Polkadot SDK HTTP RPC) + - 1 Gbps connection for high traffic scenarios - Consider DDoS protection and rate limiting for production deployments + - Open ports: + - **30333**: Parachain P2P + - **30334**: Relay chain P2P + - **9944**: Polkadot SDK WebSocket RPC + - **9933**: Polkadot SDK HTTP RPC -**Note**: For development or low-traffic scenarios, you can reduce these requirements proportionally. Consider using a reverse proxy (nginx, Caddy) for production deployments. +!!! note + For development or low-traffic scenarios, you can reduce these requirements proportionally. Consider using a reverse proxy ([nginx](https://nginx.org/){target=\_blank}, [Caddy](https://caddyserver.com/){target=\_blank}) for production deployments. ### Software Requirements Required software: -- **Operating System**: Ubuntu 22.04 LTS (recommended) or similar Linux distribution -- **Docker**: Required for obtaining binaries and running containers -- **rclone**: (Optional but recommended) Command-line program for managing files on cloud storage (https://rclone.org/downloads/) +- **Operating system**: Ubuntu 22.04 LTS (recommended) or similar Linux distribution +- **[Docker](https://www.docker.com/get-started/){target=\_blank}**: Required for obtaining binaries and running containers +- **[rclone](https://rclone.org/downloads/){target=\_blank}**: (Optional but recommended) Command-line program for managing files on cloud storage -## Setup Options +## Spin Up a Node This guide provides two options for deployment: -- **Docker-based Setup**: Best for simpler set up and maintenance -- **Manual/systemd Setup**: Best for production environments requiring more control +- **Docker**: Best for simpler set up and maintenance +- **systemd**: Best for production environments requiring more control Select the best option for your project, then use the steps in the following tabs to complete set up. -=== "Docker-Based Setup" +=== "Docker" - This option uses Docker containers for the Polkadot SDK node, making it easy to set up and manage. Follow these steps to set your RPC node using Docker: + 1. Download the official Polkadot Hub (formerly known as Asset Hub) chain specification file: - 1. Download the official Polkadot Hub (formerly known as Asset Hub) chain specification: ```bash curl -L https://raw.githubusercontent.com/paritytech/polkadot-sdk/master/cumulus/parachains/chain-specs/asset-hub-polkadot.json -o asset-hub-polkadot.json ``` - !!! note + 2. (Optional but recommended) Download pre-synced snapshots from the [Snapshot Provider](https://snapshots.polkadot.io/){target=\_blank} to cut initial sync time from days to hours: - This chain specification is the official configuration file that defines the network parameters for Polkadot Hub. + 1. Create new directories: - 2. (Optional but recommended) Download database snapshots: - - Using pre-synchronized snapshots significantly reduces initial sync time from several days to just a few hours. You need to download both parachain and relay chain data. - - You can obtain the latest snapshot from the [Snapshot Provider](https://snapshots.polkadot.io/){target=\_blank}. Follow these steps to download and use snapshots: - 1. Create new directories with the following commands: - ```bash - mkdir -p my-node-data/chains/asset-hub-polkadot/db - mkdir -p my-node-data/chains/polkadot/db - ``` - 2. Download the snapshots (~1.2 TB total): - - **Asset Hub archive snapshot** (~392 GB): - ```bash - # Check https://snapshots.polkadot.io/ for the latest snapshot URL - export SNAPSHOT_URL_ASSET_HUB="https://snapshots.polkadot.io/polkadot-asset-hub-paritydb-archive/LATEST" - - rclone copyurl $SNAPSHOT_URL_ASSET_HUB/files.txt files.txt - rclone copy --progress --transfers 20 \ - --http-url $SNAPSHOT_URL_ASSET_HUB \ - --no-traverse --http-no-head --disable-http2 \ - --inplace --no-gzip-encoding --size-only \ - --retries 6 --retries-sleep 10s \ - --files-from files.txt :http: my-node-data/chains/asset-hub-polkadot/db/ + ```bash + mkdir -p my-node-data/chains/asset-hub-polkadot/db + mkdir -p my-node-data/chains/polkadot/db + ``` - rm files.txt - ``` + 2. Download and save the archive Asset Hub snapshot: - **Relay chain pruned snapshot** (~822 GB): - ```bash - # Check https://snapshots.polkadot.io/ for the latest snapshot URL - export SNAPSHOT_URL_RELAY="https://snapshots.polkadot.io/polkadot-paritydb-prune/LATEST" + ```bash + # Check https://snapshots.polkadot.io/ for the latest snapshot URL + export SNAPSHOT_URL_ASSET_HUB="https://snapshots.polkadot.io/polkadot-asset-hub-rocksdb-archive/INSERT_LATEST" + + rclone copyurl $SNAPSHOT_URL_ASSET_HUB/files.txt files.txt + rclone copy --progress --transfers 20 \ + --http-url $SNAPSHOT_URL_ASSET_HUB \ + --no-traverse --http-no-head --disable-http2 \ + --inplace --no-gzip-encoding --size-only \ + --retries 6 --retries-sleep 10s \ + --files-from files.txt :http: my-node-data/chains/asset-hub-polkadot/db/ + + rm files.txt + ``` - rclone copyurl $SNAPSHOT_URL_RELAY/files.txt files.txt - rclone copy --progress --transfers 20 \ - --http-url $SNAPSHOT_URL_RELAY \ - --no-traverse --http-no-head --disable-http2 \ - --inplace --no-gzip-encoding --size-only \ - --retries 6 --retries-sleep 10s \ - --files-from files.txt :http: my-node-data/chains/polkadot/db/ + ??? interface "rclone parameters" - rm files.txt - ``` + - **`--transfers 20`**: Uses 20 parallel transfers for faster download + - **`--retries 6`**: Automatically retries failed transfers up to 6 times + - **`--retries-sleep 10s`**: Waits 10 seconds between retry attempts + - **`--size-only`**: Only transfers if sizes differ (prevents unnecessary re-downloads) - **rclone parameters:** + 3. Repeat the process with the pruned relay chain snapshot: - - `--transfers 20`: Uses 20 parallel transfers for faster download - - `--retries 6`: Automatically retries failed transfers up to 6 times - - `--retries-sleep 10s`: Waits 10 seconds between retry attempts - - `--size-only`: Only transfers if sizes differ (prevents unnecessary re-downloads) - 3. Launch Polkadot Hub Node using the official [Parity Docker image](https://hub.docker.com/r/parity/polkadot-parachain){target=\_blank}: + ```bash + # Check https://snapshots.polkadot.io/ for the latest snapshot URL + export SNAPSHOT_URL_RELAY="https://snapshots.polkadot.io/polkadot-rocksdb-prune/INSERT_LATEST" + + rclone copyurl $SNAPSHOT_URL_RELAY/files.txt files.txt + rclone copy --progress --transfers 20 \ + --http-url $SNAPSHOT_URL_RELAY \ + --no-traverse --http-no-head --disable-http2 \ + --inplace --no-gzip-encoding --size-only \ + --retries 6 --retries-sleep 10s \ + --files-from files.txt :http: my-node-data/chains/polkadot/db/ + + rm files.txt + ``` - === "Archive Node" + 3. Launch your Polkadot Hub node using the official [Parity Docker image](https://hub.docker.com/r/parity/polkadot-parachain){target=\_blank}: - Archive node configuration maintains complete parachain history for historical queries: + === "Archive" ```bash docker run -d --name polkadot-hub-rpc --restart unless-stopped \ @@ -164,9 +150,7 @@ Select the best option for your project, then use the steps in the following tab --rpc-port=0 ``` - === "Pruned Node" - - Pruned node configuration keeps recent state for smaller storage requirements: + === "Pruned" ```bash docker run -d --name polkadot-hub-rpc --restart unless-stopped \ @@ -198,85 +182,12 @@ Select the best option for your project, then use the steps in the following tab --rpc-port=0 ``` - Critical configuration parameters include port mappings and node parameters: - - === "Port mappings" - - - `9944`: Polkadot SDK RPC endpoint (WebSocket/HTTP) - - `9933`: Polkadot SDK HTTP RPC endpoint - - `9615`: Prometheus metrics endpoint - - `30333/30334`: P2P networking ports - - === "Node parameters" - - - `--unsafe-rpc-external`: Enables external RPC access - - `--rpc-cors=all`: Allows all origins for CORS - - `--rpc-methods=safe`: Only allows safe RPC methods - - `--state-pruning=archive` or `--state-pruning=1000`: Archive keeps complete state history, pruned keeps last 1000 blocks - - `--blocks-pruning=archive` or `--blocks-pruning=256`: Archive keeps all blocks, pruned keeps last 256 finalized blocks - - `--prometheus-external`: Exposes metrics externally - - !!! warning - - The `--unsafe-rpc-external` flag should only be used in development or properly secured environments. For production, use a reverse proxy with authentication. - - 4. Monitor the node synchronization status using the following command: - - ```bash - curl -H "Content-Type: application/json" \ - -d '{"id":1, "jsonrpc":"2.0", "method": "system_syncState", "params":[]}' \ - http://localhost:9944 - ``` - - You should see a response similar to the following: - - ```json - { - "jsonrpc":"2.0", - "id":1, - "result":{ - "startingBlock":0, - "currentBlock":3394816, - "highestBlock":3394816 - } - } - ``` - - When synchronization is complete, `currentBlock` will be equal to `highestBlock`. - - 5. You can use the `system_health` command to verify your node is running properly: - - - Query node health: - ```bash - curl -H "Content-Type: application/json" \ - -d '{"id":1, "jsonrpc":"2.0", "method": "system_health", "params":[]}' \ - http://localhost:9944 - ``` - - 6. Use the following commands to manage your Docker containers: - - - View node logs: - ```bash - docker logs -f polkadot-hub-rpc - ``` - - Stop container: - ```bash - docker stop polkadot-hub-rpc - ``` - - Start container: - ```bash - docker start polkadot-hub-rpc - ``` - - Remove container: - ```bash - docker rm polkadot-hub-rpc - ``` - -=== "Manual systemd Setup" - - This option provides more control and is recommended for production environments requiring custom configurations. + Refer to the [Port Mappings](#port-mappings) and [Node Configuration Arguments](#node-configuration-arguments) sections for details on the command's configurations. + +=== "systemd" 1. Download the `polkadot-parachain` binary from the latest stable [Polkadot SDK release](https://github.com/paritytech/polkadot-sdk/releases){target=\_blank}: + ```bash # Download the latest stable release (check releases page for current version) wget https://github.com/paritytech/polkadot-sdk/releases/download/polkadot-stable2509-2/polkadot-parachain @@ -290,38 +201,36 @@ Select the best option for your project, then use the steps in the following tab ``` 2. Download the Polkadot Hub chain specification: + ```bash curl -L https://raw.githubusercontent.com/paritytech/polkadot-sdk/master/cumulus/parachains/chain-specs/asset-hub-polkadot.json -o asset-hub-polkadot.json ``` - 3. Create user and directory structures using the following commands: - - Create a dedicated user: - ```bash - sudo useradd -r -s /bin/bash polkadot - ``` - - Create data directory: - ```bash - sudo mkdir -p /var/lib/polkadot-hub-rpc - ``` - - Copy the chain spec to the directory: - ```bash - sudo cp asset-hub-polkadot.json /var/lib/polkadot-hub-rpc/ - ``` - - Set permissions: - ```bash - sudo chown -R polkadot:polkadot /var/lib/polkadot-hub-rpc - ``` + 3. Create user and directory structures: + + ```bash + # Create a dedicated user + sudo useradd -r -s /bin/bash polkadot + + # Create data directory + sudo mkdir -p /var/lib/polkadot-hub-rpc + + # Copy the chain spec to the directory + sudo cp asset-hub-polkadot.json /var/lib/polkadot-hub-rpc/ + + # Set permissions + sudo chown -R polkadot:polkadot /var/lib/polkadot-hub-rpc + ``` 4. Create a systemd service file for the Polkadot SDK RPC node: + ```bash sudo nano /etc/systemd/system/polkadot-hub-rpc.service ``` - 5. Open the new service file and add the configuration for your chosen node type: + 5. Open the new service file and add the configuration for either an archive (complete history) or pruned (recent state) node: - === "Archive Node" - - Archive node configuration maintains complete parachain history for historical queries: + === "Archive" ```ini [Unit] @@ -366,8 +275,6 @@ Select the best option for your project, then use the steps in the following tab === "Pruned Node" - Pruned node configuration keeps recent state for smaller storage requirements: - ```ini [Unit] Description=Polkadot Hub RPC Node @@ -409,44 +316,135 @@ Select the best option for your project, then use the steps in the following tab WantedBy=multi-user.target ``` - 6. Start the service using the following commands: - - Reload systemd: - ```bash - sudo systemctl daemon-reload - ``` - - Enable service to start on boot: - ```bash - sudo systemctl enable polkadot-hub-rpc - ``` - - Start the Polkadot SDK node: - ```bash - sudo systemctl start polkadot-hub-rpc - ``` - - Check status and wait for sync: - ```bash - sudo systemctl status polkadot-hub-rpc - sudo journalctl -u polkadot-hub-rpc -f - ``` + Refer to the [Port Mappings](#port-mappings) and [Node Configuration Arguments](#node-configuration-arguments) sections for details on the command's configurations. - 7. You can use a few different commands to verify your node is running properly: - - Get chain information: - ```bash - curl -H "Content-Type: application/json" \ - -d '{"id":1, "jsonrpc":"2.0", "method": "system_chain", "params":[]}' \ - http://localhost:9944 - ``` - - Get the latest block: - ```bash - curl -H "Content-Type: application/json" \ - -d '{"id":1, "jsonrpc":"2.0", "method": "chain_getHeader", "params":[]}' \ - http://localhost:9944 - ``` - - Query node health: - ```bash - curl -H "Content-Type: application/json" \ - -d '{"id":1, "jsonrpc":"2.0", "method": "system_health", "params":[]}' \ - http://localhost:9944 - ``` + 6. Start the service: + + ```bash + # Reload systemd + sudo systemctl daemon-reload + + # Enable service to start on boot + sudo systemctl enable polkadot-hub-rpc + + # Start the Polkadot SDK node: + sudo systemctl start polkadot-hub-rpc + ``` + +### Port Mappings + +- **`9944`**: Polkadot SDK RPC endpoint (WebSocket/HTTP) +- **`9933`**: Polkadot SDK HTTP RPC endpoint +- **`9615`**: Prometheus metrics endpoint +- **`30333/30334`**: P2P networking ports + +### Node Configuration Arguments + +- **`--unsafe-rpc-external`**: Enables external RPC access. **This command should only be used in development or properly secured environments**. For production, use a reverse proxy with authentication. +- **`--rpc-cors=all`**: Allows all origins for CORS. +- **`--rpc-methods=safe`**: Only allows safe RPC methods. +- **`--state-pruning`**: Archive keeps complete state history, pruned keeps last specified number of blocks. +- **`--blocks-pruning`**: Archive keeps all blocks, pruned keeps last specified number of finalized blocks. +- **`--prometheus-external`**: Exposes metrics externally. + +## Monitor Node Synchronization + +Monitor the node synchronization status: + +```bash +curl -H "Content-Type: application/json" \ +-d '{"id":1, "jsonrpc":"2.0", "method": "system_syncState", "params":[]}' \ +http://localhost:9944 +``` + +When synchronization is complete, `currentBlock` will be equal to `highestBlock`: + +
+ curl -H "Content-Type: application/json" \ + -d '{"id":1, "jsonrpc":"2.0", "method": "system_syncState", "params":[]}' \ + http://localhost:9944 +
{
+  "jsonrpc":"2.0",
+  "id":1,
+  "result":{
+    "startingBlock":0,
+    "currentBlock":3394816,
+    "highestBlock":3394816
+  }
+}
+  
+
+ +!!! tip + You can use the `system_health` command to verify your node is running properly. + + ```bash + curl -H "Content-Type: application/json" \ + -d '{"id":1, "jsonrpc":"2.0", "method": "system_health", "params":[]}' \ + http://localhost:9944 + ``` + +## Commands for Managing Your Node + +Use the following commands to manage your node: + +=== "Docker" + + - **View node logs**: + + ```bash + docker logs -f polkadot-hub-rpc + ``` + + - **Stop container**: + + ```bash + docker stop polkadot-hub-rpc + ``` + + - **Start container**: + + ```bash + docker start polkadot-hub-rpc + ``` + + - **Remove container**: + + ```bash + docker rm polkadot-hub-rpc + ``` + +=== "systemd" + + - **Check status**: + + ```bash + sudo systemctl status polkadot-hub-rpc + ``` + + - **View node logs**: + + ```bash + sudo journalctl -u polkadot-hub-rpc -f + ``` + + - **Stop service**: + + ```bash + sudo systemctl stop polkadot-hub-rpc + ``` + + - **Enable service**: + + ```bash + sudo systemctl enable polkadot-hub-rpc + ``` + + - **Start service**: + + ```bash + sudo systemctl start polkadot-hub-rpc + ``` ## Conclusion diff --git a/.ai/pages/node-infrastructure-run-a-node-relay-chain-full-node.md b/.ai/pages/node-infrastructure-run-a-node-relay-chain-full-node.md index 05c3394fc..058baca20 100644 --- a/.ai/pages/node-infrastructure-run-a-node-relay-chain-full-node.md +++ b/.ai/pages/node-infrastructure-run-a-node-relay-chain-full-node.md @@ -27,7 +27,7 @@ Before getting started, ensure the following prerequisites are met: - [Install the necessary dependencies for the Polkadot SDK](/parachains/install-polkadot-sdk/){target=\_blank}. !!! warning - This setup is not recommended for validators. If you plan to run a validator, refer to the [Running a Validator](/nodes-and-validators/run-a-validator/onboarding-and-offboarding/set-up-validator/){target=\_blank} guide for proper instructions. + This setup is not recommended for validators. If you plan to run a validator, refer to the [Running a Validator](/node-infrastructure/run-a-validator/onboarding-and-offboarding/set-up-validator/){target=\_blank} guide for proper instructions. ### Install and Build the Polkadot Binary @@ -58,10 +58,9 @@ This section will walk you through installing and building the Polkadot binary f You should see output similar to the following:
- rustup show
- rustup +nightly show
+ rustup show + rustup +nightly show + active toolchain ---------------- @@ -143,10 +142,8 @@ This section will walk you through installing and building the Polkadot binary f You should see output similar to the following:
- rustup show
- rustup +nightly show
+ rustup show + active toolchain ---------------- diff --git a/.ai/pages/node-infrastructure-run-a-node-relay-chain-secure-wss.md b/.ai/pages/node-infrastructure-run-a-node-relay-chain-secure-wss.md index c39c29993..0effd82e8 100644 --- a/.ai/pages/node-infrastructure-run-a-node-relay-chain-secure-wss.md +++ b/.ai/pages/node-infrastructure-run-a-node-relay-chain-secure-wss.md @@ -122,4 +122,4 @@ Apache2 can run in various modes, including `prefork`, `worker`, and `event`. In wss://example.com:443 ``` -![A sync-in-progress chain connected to Polkadot.js UI](/images/nodes-and-validators/run-a-node/secure-wss/secure-wss-01.webp) +![A sync-in-progress chain connected to Polkadot.js UI](/images/node-infrastructure/run-a-node/secure-wss/secure-wss-01.webp) diff --git a/.ai/pages/node-infrastructure-run-a-validator-onboarding-and-offboarding-key-management.md b/.ai/pages/node-infrastructure-run-a-validator-onboarding-and-offboarding-key-management.md index 1f688736e..3d8740b66 100644 --- a/.ai/pages/node-infrastructure-run-a-validator-onboarding-and-offboarding-key-management.md +++ b/.ai/pages/node-infrastructure-run-a-validator-onboarding-and-offboarding-key-management.md @@ -9,7 +9,7 @@ url: https://docs.polkadot.com/node-infrastructure/run-a-validator/onboarding-an ## Introduction -After setting up your node environment as shown in the [Setup](/nodes-and-validators/run-a-validator/onboarding-and-offboarding/set-up-validator/){target=\_blank} section, you'll need to configure multiple keys for your validator to operate properly. This includes setting up session keys, which are essential for participating in the consensus process, and configuring a node key that maintains a stable network identity. This guide walks you through the key management process, showing you how to generate, store, and register these keys. +After setting up your node environment as shown in the [Setup](/node-infrastructure/run-a-validator/onboarding-and-offboarding/set-up-validator/){target=\_blank} section, you'll need to configure multiple keys for your validator to operate properly. This includes setting up session keys, which are essential for participating in the consensus process, and configuring a node key that maintains a stable network identity. This guide walks you through the key management process, showing you how to generate, store, and register these keys. ## Set Session Keys @@ -30,7 +30,7 @@ There are multiple ways to create the session keys. It can be done by interactin 3. Click the **Submit RPC Call** button. 4. Copy the hex-encoded public key from the response. - ![](/images/nodes-and-validators/run-a-validator/onboarding-and-offboarding/key-management/key-management-01.webp) + ![](/images/node-infrastructure/run-a-validator/onboarding-and-offboarding/key-management/key-management-01.webp) === "Curl" @@ -89,7 +89,7 @@ Now that you have generated your session keys, you must submit them to the chain 2. Select **Set Session Key** on the bonding account you generated earlier. 3. Paste the hex-encoded session key string you generated (from either the UI or CLI) into the input field and submit the transaction. -![](/images/nodes-and-validators/run-a-validator/onboarding-and-offboarding/key-management/key-management-02.webp) +![](/images/node-infrastructure/run-a-validator/onboarding-and-offboarding/key-management/key-management-02.webp) Once the transaction is signed and submitted, your session keys will be registered on-chain. diff --git a/.ai/pages/node-infrastructure-run-a-validator-onboarding-and-offboarding-set-up-validator.md b/.ai/pages/node-infrastructure-run-a-validator-onboarding-and-offboarding-set-up-validator.md index 4fd33b1ef..774d24055 100644 --- a/.ai/pages/node-infrastructure-run-a-validator-onboarding-and-offboarding-set-up-validator.md +++ b/.ai/pages/node-infrastructure-run-a-validator-onboarding-and-offboarding-set-up-validator.md @@ -17,10 +17,10 @@ Running a validator requires a commitment to maintaining a stable, secure infras To get the most from this guide, ensure you've done the following before going forward: -- Read [Validator Requirements](/nodes-and-validators/run-a-validator/requirements/){target=\_blank} and understand the recommended minimum skill level and hardware needs. -- Read [General Management](/nodes-and-validators/run-a-validator/operational-tasks/general-management/){target=\_blank}, [Upgrade Your Node](/nodes-and-validators/run-a-validator/operational-tasks/upgrade-your-node/){target=\_blank}, and [Pause Validating](/nodes-and-validators/run-a-validator/operational-tasks/pause-validating/){target=\_blank} and understand the tasks required to keep your validator operational. -- Read [Rewards Payout](/nodes-and-validators/run-a-validator/staking-mechanics/rewards/){target=\_blank} and understand how validator rewards are determined and paid out. -- Read [Offenses and Slashes](/nodes-and-validators/run-a-validator/staking-mechanics/offenses-and-slashes/){target=\_blank} and understand how validator performance and security can affect tokens staked by you or your nominators. +- Read [Validator Requirements](/node-infrastructure/run-a-validator/requirements/){target=\_blank} and understand the recommended minimum skill level and hardware needs. +- Read [General Management](/node-infrastructure/run-a-validator/operational-tasks/general-management/){target=\_blank}, [Upgrade Your Node](/node-infrastructure/run-a-validator/operational-tasks/upgrade-your-node/){target=\_blank}, and [Pause Validating](/node-infrastructure/run-a-validator/operational-tasks/pause-validating/){target=\_blank} and understand the tasks required to keep your validator operational. +- Read [Rewards Payout](/node-infrastructure/run-a-validator/staking-mechanics/rewards/){target=\_blank} and understand how validator rewards are determined and paid out. +- Read [Offenses and Slashes](/node-infrastructure/run-a-validator/staking-mechanics/offenses-and-slashes/){target=\_blank} and understand how validator performance and security can affect tokens staked by you or your nominators. ## Initial Setup diff --git a/.ai/pages/node-infrastructure-run-a-validator-onboarding-and-offboarding-start-validating.md b/.ai/pages/node-infrastructure-run-a-validator-onboarding-and-offboarding-start-validating.md index 0ca3cc0fc..cfa032f78 100644 --- a/.ai/pages/node-infrastructure-run-a-validator-onboarding-and-offboarding-start-validating.md +++ b/.ai/pages/node-infrastructure-run-a-validator-onboarding-and-offboarding-start-validating.md @@ -9,7 +9,7 @@ url: https://docs.polkadot.com/node-infrastructure/run-a-validator/onboarding-an ## Introduction -After configuring your node keys as shown in the [Key Management](/nodes-and-validators/run-a-validator/onboarding-and-offboarding/key-management/){target=\_blank} section and ensuring your system is set up, you're ready to begin the validator setup process. This guide will walk you through choosing a network, synchronizing your node with the blockchain, bonding your DOT tokens, and starting your validator. +After configuring your node keys as shown in the [Key Management](/node-infrastructure/run-a-validator/onboarding-and-offboarding/key-management/){target=\_blank} section and ensuring your system is set up, you're ready to begin the validator setup process. This guide will walk you through choosing a network, synchronizing your node with the blockchain, bonding your DOT tokens, and starting your validator. ## Choose a Network @@ -99,7 +99,7 @@ If you see terminal output similar to the preceding, and you are unable to synch ## Bond DOT -Once your validator node is synced, the next step is bonding DOT. A bonded account, or stash, holds your staked tokens (DOT) that back your validator node. Bonding your DOT means locking it for a period, during which it cannot be transferred or spent but is used to secure your validator's role in the network. Visit the [Minimum Bond Requirement](/nodes-and-validators/run-a-validator/requirements/#minimum-bond-requirement) section for details on how much DOT is required. +Once your validator node is synced, the next step is bonding DOT. A bonded account, or stash, holds your staked tokens (DOT) that back your validator node. Bonding your DOT means locking it for a period, during which it cannot be transferred or spent but is used to secure your validator's role in the network. Visit the [Minimum Bond Requirement](/node-infrastructure/run-a-validator/requirements/#minimum-bond-requirement) section for details on how much DOT is required. The following sections will guide you through bonding DOT for your validator. @@ -131,29 +131,29 @@ Follow these steps to use Polkadot.js Apps to activate your validator: 1. In Polkadot.js Apps, navigate to **Network** and select **Staking**: - ![](/images/nodes-and-validators/run-a-validator/onboarding-and-offboarding/start-validating/start-validating-01.webp) + ![](/images/node-infrastructure/run-a-validator/onboarding-and-offboarding/start-validating/start-validating-01.webp) 2. Open the **Accounts** tab and click on **+ Validator**: - ![](/images/nodes-and-validators/run-a-validator/onboarding-and-offboarding/start-validating/start-validating-02.webp) + ![](/images/node-infrastructure/run-a-validator/onboarding-and-offboarding/start-validating/start-validating-02.webp) 3. Set a bond amount in the **value bonded** field and then click **next**: - ![](/images/nodes-and-validators/run-a-validator/onboarding-and-offboarding/start-validating/start-validating-03.webp) + ![](/images/node-infrastructure/run-a-validator/onboarding-and-offboarding/start-validating/start-validating-03.webp) 4. Paste the hex output from `author_rotateKeys`, set the commission, allow or block new nominations, then click **Bond & Validate** to link your validator with its session keys. - ![](/images/nodes-and-validators/run-a-validator/onboarding-and-offboarding/start-validating/start-validating-04.webp) + ![](/images/node-infrastructure/run-a-validator/onboarding-and-offboarding/start-validating/start-validating-04.webp) You can also set the **commission** and **blocked** nominations option via `staking.validate` extrinsic. By default, the blocked option is set to FALSE (i.e., the validator accepts nominations). - ![](/images/nodes-and-validators/run-a-validator/onboarding-and-offboarding/start-validating/start-validating-05.webp) + ![](/images/node-infrastructure/run-a-validator/onboarding-and-offboarding/start-validating/start-validating-05.webp) ### Monitor Validation Status and Slots On the [**Staking**](https://polkadot.js.org/apps/#/staking){target=\_blank} tab in Polkadot.js Apps, you can see your validator's status, the number of available validator slots, and the nodes that have signaled their intent to validate. Your node may initially appear in the waiting queue, especially if the validator slots are full. The following is an example view of the **Staking** tab: -![staking queue](/images/nodes-and-validators/run-a-validator/onboarding-and-offboarding/start-validating/start-validating-06.webp) +![staking queue](/images/node-infrastructure/run-a-validator/onboarding-and-offboarding/start-validating/start-validating-06.webp) The validator set refreshes each era. If there's an available slot in the next era, your node may be selected to move from the waiting queue to the active validator set, allowing it to start validating blocks. If your validator is not selected, it remains in the waiting queue. Increasing your stake or gaining more nominators may improve your chance of being selected in future eras. @@ -165,7 +165,7 @@ This following sections will walk you through creating and managing a systemd se Ensure the following requirements are met before proceeding with the systemd setup: -- Confirm your system meets the [requirements](/nodes-and-validators/run-a-validator/requirements/){target=\_blank} for running a validator. +- Confirm your system meets the [requirements](/node-infrastructure/run-a-validator/requirements/){target=\_blank} for running a validator. - Ensure you meet the [minimum bond requirements](https://wiki.polkadot.com/general/chain-state-values/#minimum-validator-bond){target=\_blank} for validating. - Verify the Polkadot binary is [installed](#install-the-polkadot-binaries). diff --git a/.ai/pages/node-infrastructure-run-a-validator-onboarding-and-offboarding-stop-validating.md b/.ai/pages/node-infrastructure-run-a-validator-onboarding-and-offboarding-stop-validating.md index 5cff77ad4..10a6ad29f 100644 --- a/.ai/pages/node-infrastructure-run-a-validator-onboarding-and-offboarding-stop-validating.md +++ b/.ai/pages/node-infrastructure-run-a-validator-onboarding-and-offboarding-stop-validating.md @@ -25,7 +25,7 @@ The following are steps to ensure a smooth stop to validation: When stepping back from validating, the first step is to chill your validator status. This action stops your validator from being considered for the next era without fully unbonding your tokens, which can be useful for temporary pauses like maintenance or planned downtime. -Use the `staking.chill` extrinsic to initiate this. For more guidance on chilling your node, refer to the [Pause Validating](/nodes-and-validators/run-a-validator/operational-tasks/pause-validating/){target=\_blank} guide. You may also claim any pending staking rewards at this point. +Use the `staking.chill` extrinsic to initiate this. For more guidance on chilling your node, refer to the [Pause Validating](/node-infrastructure/run-a-validator/operational-tasks/pause-validating/){target=\_blank} guide. You may also claim any pending staking rewards at this point. ## Purge Validator Session Keys diff --git a/.ai/pages/node-infrastructure-run-a-validator-operational-tasks-general-management.md b/.ai/pages/node-infrastructure-run-a-validator-operational-tasks-general-management.md index 9c8ac6502..b1a7b14e9 100644 --- a/.ai/pages/node-infrastructure-run-a-validator-operational-tasks-general-management.md +++ b/.ai/pages/node-infrastructure-run-a-validator-operational-tasks-general-management.md @@ -391,28 +391,28 @@ To configure Grafana, take these steps: sudo systemctl restart grafana-server ``` -![Grafana login screen](/images/nodes-and-validators/run-a-validator/operational-tasks/general-management/general-management-01.webp) +![Grafana login screen](/images/node-infrastructure/run-a-validator/operational-tasks/general-management/general-management-01.webp) To visualize node metrics, follow these steps: 1. Select the gear icon to access **Data Sources** settings. 2. Select **Add data source** to define the data source. - ![Select Prometheus](/images/nodes-and-validators/run-a-validator/operational-tasks/general-management/general-management-02.webp) + ![Select Prometheus](/images/node-infrastructure/run-a-validator/operational-tasks/general-management/general-management-02.webp) 3. Select **Prometheus**. - ![Save and test](/images/nodes-and-validators/run-a-validator/operational-tasks/general-management/general-management-03.webp) + ![Save and test](/images/node-infrastructure/run-a-validator/operational-tasks/general-management/general-management-03.webp) 4. Enter `http://localhost:9090` in the **URL** field and click **Save & Test**. If **"Data source is working"** appears, your connection is configured correctly. - ![Import dashboard](/images/nodes-and-validators/run-a-validator/operational-tasks/general-management/general-management-04.webp) + ![Import dashboard](/images/node-infrastructure/run-a-validator/operational-tasks/general-management/general-management-04.webp) 5. Select **Import** from the left menu, choose **Prometheus** from the dropdown, and click **Import**. 6. Start your Polkadot node by running `./polkadot`. You should now be able to monitor node performance, block height, network traffic, and tasks tasks on the Grafana dashboard. - ![Live dashboard](/images/nodes-and-validators/run-a-validator/operational-tasks/general-management/general-management-05.webp) + ![Live dashboard](/images/node-infrastructure/run-a-validator/operational-tasks/general-management/general-management-05.webp) The [Grafana dashboards](https://grafana.com/grafana/dashboards){target=\_blank} page features user created dashboards made available for public use. For an example, see the [Substrate Node Metrics](https://grafana.com/grafana/dashboards/21715-substrate-node-metrics/){target=\_blank} dashboard. @@ -656,13 +656,13 @@ Validators in Polkadot's Proof of Stake (PoS) network play a critical role in ma ### Key Management -Though they don't transfer funds, session keys are essential for validators as they sign messages related to consensus and parachains. Securing session keys is crucial as allowing them to be exploited or used across multiple nodes can lead to a loss of staked funds via [slashing](/nodes-and-validators/run-a-validator/staking-mechanics/offenses-and-slashes/){target=\_blank}. +Though they don't transfer funds, session keys are essential for validators as they sign messages related to consensus and parachains. Securing session keys is crucial as allowing them to be exploited or used across multiple nodes can lead to a loss of staked funds via [slashing](/node-infrastructure/run-a-validator/staking-mechanics/offenses-and-slashes/){target=\_blank}. Given the current limitations in high-availability setups and the risks associated with double-signing, it’s recommended to run only a single validator instance. Keys should be securely managed, and processes automated to minimize human error. There are two approaches for generating session keys: -- **Generate and store in node**: Using the `author.rotateKeys` RPC call. For most users, generating keys directly within the client is recommended. You must submit a session certificate from your staking proxy to register new keys. See the [How to Validate](/nodes-and-validators/run-a-validator/onboarding-and-offboarding/set-up-validator/){target=\_blank} guide for instructions on setting keys. +- **Generate and store in node**: Using the `author.rotateKeys` RPC call. For most users, generating keys directly within the client is recommended. You must submit a session certificate from your staking proxy to register new keys. See the [How to Validate](/node-infrastructure/run-a-validator/onboarding-and-offboarding/set-up-validator/){target=\_blank} guide for instructions on setting keys. - **Generate outside node and insert**: Using the `author.setKeys` RPC call. This flexibility accommodates advanced security setups and should only be used by experienced validator operators. diff --git a/.ai/pages/node-infrastructure-run-a-validator-operational-tasks-upgrade-your-node.md b/.ai/pages/node-infrastructure-run-a-validator-operational-tasks-upgrade-your-node.md index d3bf39683..840e36185 100644 --- a/.ai/pages/node-infrastructure-run-a-validator-operational-tasks-upgrade-your-node.md +++ b/.ai/pages/node-infrastructure-run-a-validator-operational-tasks-upgrade-your-node.md @@ -17,7 +17,7 @@ This guide will allow validators to seamlessly substitute an active validator se Before beginning the upgrade process for your validator node, ensure the following: -- You have a fully functional validator setup with all required binaries installed. See [Set Up a Validator](/nodes-and-validators/run-a-validator/onboarding-and-offboarding/set-up-validator/){target=\_blank} and [Validator Requirements](/nodes-and-validators/run-a-validator/requirements/){target=\_blank} for additional guidance. +- You have a fully functional validator setup with all required binaries installed. See [Set Up a Validator](/node-infrastructure/run-a-validator/onboarding-and-offboarding/set-up-validator/){target=\_blank} and [Validator Requirements](/node-infrastructure/run-a-validator/requirements/){target=\_blank} for additional guidance. - Your VPS infrastructure has enough capacity to run a secondary validator instance temporarily for the upgrade process. ## Session Keys @@ -28,7 +28,7 @@ Remembering this delayed effect when planning upgrades is crucial to ensure that ## Keystore -Your validator server's `keystore` folder holds the private keys needed for signing network-level transactions. It is important not to duplicate or transfer this folder between validator instances. Doing so could result in multiple validators signing with the duplicate keys, leading to severe consequences such as [equivocation slashing](/nodes-and-validators/run-a-validator/staking-mechanics/offenses-and-slashes/#equivocation-slash){target=\_blank}. Instead, always generate new session keys for each validator instance. +Your validator server's `keystore` folder holds the private keys needed for signing network-level transactions. It is important not to duplicate or transfer this folder between validator instances. Doing so could result in multiple validators signing with the duplicate keys, leading to severe consequences such as [equivocation slashing](/node-infrastructure/run-a-validator/staking-mechanics/offenses-and-slashes/#equivocation-slash){target=\_blank}. Instead, always generate new session keys for each validator instance. The default path to the `keystore` is as follows: diff --git a/.ai/pages/node-infrastructure-run-a-validator-requirements.md b/.ai/pages/node-infrastructure-run-a-validator-requirements.md index 2997baeb9..60966ac9b 100644 --- a/.ai/pages/node-infrastructure-run-a-validator-requirements.md +++ b/.ai/pages/node-infrastructure-run-a-validator-requirements.md @@ -18,8 +18,8 @@ This guide covers everything you need to know about becoming a validator, includ Running a validator requires solid system administration skills and a secure, well-maintained infrastructure. Below are the primary requirements you need to be aware of before getting started: - **System administration expertise**: Handling technical anomalies and maintaining node infrastructure is critical. Validators must be able to troubleshoot and optimize their setup. -- **Security**: Ensure your setup follows best practices for securing your node. Refer to the [Secure Your Validator](/nodes-and-validators/run-a-validator/operational-tasks/general-management/#secure-your-validator){target=\_blank} section to learn about important security measures. -- **Network choice**: Start with [Kusama](/nodes-and-validators/run-a-validator/onboarding-and-offboarding/set-up-validator/#run-a-kusama-validator){target=\_blank} to gain experience. Look for "Adjustments for Kusama" throughout these guides for tips on adapting the provided instructions for the Kusama network. +- **Security**: Ensure your setup follows best practices for securing your node. Refer to the [Secure Your Validator](/node-infrastructure/run-a-validator/operational-tasks/general-management/#secure-your-validator){target=\_blank} section to learn about important security measures. +- **Network choice**: Start with [Kusama](/node-infrastructure/run-a-validator/onboarding-and-offboarding/set-up-validator/#run-a-kusama-validator){target=\_blank} to gain experience. Look for "Adjustments for Kusama" throughout these guides for tips on adapting the provided instructions for the Kusama network. - **Staking requirements**: A minimum amount of native token (KSM or DOT) is required to be elected into the validator set. The required stake can come from your own holdings or from nominators. - **Risk of slashing**: Any DOT you stake is at risk if your setup fails or your validator misbehaves. If you’re unsure of your ability to maintain a reliable validator, consider nominating your DOT to a trusted validator. diff --git a/.ai/pages/node-infrastructure-overview.md b/.ai/pages/node-infrastructure.md similarity index 65% rename from .ai/pages/node-infrastructure-overview.md rename to .ai/pages/node-infrastructure.md index 15da08c89..5833bebd9 100644 --- a/.ai/pages/node-infrastructure-overview.md +++ b/.ai/pages/node-infrastructure.md @@ -1,8 +1,8 @@ --- title: Node Infrastructure -description: Overview of running nodes in the Polkadot ecosystem, including RPC nodes, collators, and validators. +description: From running RPC endpoints to producing parachain blocks or validating the relay chain, this guide explains your options and how to begin. categories: Infrastructure -url: https://docs.polkadot.com/node-infrastructure/overview/ +url: https://docs.polkadot.com/node-infrastructure/ --- # Node Infrastructure Overview @@ -19,15 +19,15 @@ Whether you want to provide RPC endpoints for applications, produce blocks for a RPC nodes provide API access to blockchain data without participating in consensus. They are essential infrastructure for: -- **Applications and dApps**: Query blockchain state and submit transactions -- **Block explorers**: Index and display blockchain data -- **Wallets**: Check balances and broadcast transactions -- **Development**: Test and debug applications +- **Applications and dApps**: Query blockchain state and submit transactions. +- **Block explorers**: Index and display blockchain data. +- **Wallets**: Check balances and broadcast transactions. +- **Development**: Test and debug applications. RPC nodes can be run for both the relay chain and parachains, with varying levels of data retention: -- **Pruned Nodes**: Keep recent state and a limited number of finalized blocks. Suitable for most applications that only need current state and recent history. More efficient in terms of storage and sync time. -- **Archive Nodes**: Maintain complete historical state and all blocks since genesis. Required for block explorers, analytics platforms, or applications that need to query historical data at any point in time. +- **Pruned nodes**: Keep recent state and a limited number of finalized blocks. Suitable for most applications that only need the current state and recent history. More efficient in terms of storage and sync time. +- **Archive nodes**: Maintain complete historical state and all blocks since genesis. Required for block explorers, analytics platforms, or applications that need to query historical data at any point in time. **Transaction Broadcasting**: RPC nodes play a crucial role in transaction submission and propagation. When a client submits a transaction via RPC methods like `author_submitExtrinsic`, the node validates the transaction format, adds it to its local transaction pool, and broadcasts it across the P2P network. Block producers (collators or validators) then pick up these transactions from their pools for inclusion in blocks. This makes RPC nodes the primary gateway for users and applications to interact with the blockchain. @@ -35,51 +35,49 @@ RPC nodes can be run for both the relay chain and parachains, with varying level Collators are block producers for parachains. They perform critical functions: -- **Collect transactions**: Aggregate user transactions into blocks -- **Produce blocks**: Create parachain block candidates -- **Generate and package PoV**: Generate the Proof-of-Validity containing the state transition proof and necessary witness data for validation -- **Submit to validators**: Send block candidates and PoVs to relay chain validators +- **Collect transactions**: Aggregate user transactions into blocks. +- **Produce blocks**: Create parachain block candidates. +- **Generate and package PoV**: Generate the Proof-of-Validity containing the state transition proof and necessary witness data for validation. +- **Submit to validators**: Send block candidates and PoVs to relay chain validators. -Unlike validators, collators do not provide security guarantees—that responsibility lies with relay chain validators. However, collators are essential for parachain liveness and censorship resistance. +Unlike validators, collators do not provide security guarantees—that responsibility lies with the relay chain validators. However, collators are essential for parachain liveness and censorship resistance. ### Validators Validators secure the Polkadot relay chain through [Nominated Proof of Stake (NPoS)](https://wiki.polkadot.network/docs/learn-staking){target=\_blank}. They: -- **Validate blocks**: Verify parachain blocks and relay chain transactions -- **Participate in consensus**: Run [BABE](https://wiki.polkadot.network/docs/learn-consensus#babe-block-production){target=\_blank} and [GRANDPA](https://wiki.polkadot.network/docs/learn-consensus#grandpa-finality-gadget){target=\_blank} protocols -- **Earn rewards**: Receive staking rewards for honest behavior -- **Risk slashing**: Face penalties for misbehavior or downtime +- **Validate blocks**: Verify parachain blocks and relay chain transactions. +- **Participate in consensus**: Run [BABE](https://wiki.polkadot.network/docs/learn-consensus#babe-block-production){target=\_blank} and [GRANDPA](https://wiki.polkadot.network/docs/learn-consensus#grandpa-finality-gadget){target=\_blank} protocols. +- **Earn rewards**: Receive staking rewards for honest behavior. +- **Risk slashing**: Face penalties for misbehavior or downtime. Running a validator requires significant technical expertise, reliable infrastructure, and a stake of DOT tokens. ## Next Steps -Choose your path based on your goals: -
-- :material-api:{ .lg .middle } **Run RPC Nodes** +- **Run RPC Nodes** --- - Provide API access for applications, explorers, and wallets + Provide API access for applications, explorers, and wallets. - [:octicons-arrow-right-24: Run a Node](/node-infrastructure/run-a-node/parachain-rpc/) + [:octicons-arrow-right-24: Run a Node](/node-infrastructure/run-a-node/polkadot-hub-rpc/) -- :material-cube-outline:{ .lg .middle } **Run a Collator** +- **Run a Collator** --- - Produce blocks for system parachains or your own parachain + Produce blocks for system parachains or your own parachain. - [:octicons-arrow-right-24: Run a Collator](/node-infrastructure/run-a-collator/collator/) + [:octicons-arrow-right-24: Run a Collator](/node-infrastructure/run-a-collator/) -- :material-shield-check:{ .lg .middle } **Run a Validator** +- **Run a Validator** --- - Secure the relay chain and earn staking rewards + Secure the relay chain and earn staking rewards. [:octicons-arrow-right-24: Run a Validator](/node-infrastructure/run-a-validator/requirements/) diff --git a/node-infrastructure/run-a-collator.md b/node-infrastructure/run-a-collator.md index 004dc9ee0..237de4fb4 100644 --- a/node-infrastructure/run-a-collator.md +++ b/node-infrastructure/run-a-collator.md @@ -415,7 +415,7 @@ The registration process varies by system parachain. General steps include the f - **Infrastructure**: Describe your hardware and monitoring setup. - **Experience**: Detail your relevant experience. - Submit the proposal to the relevant governance channels on the [Polkadot Forum](https://forum.polkadot.network){target=\_blank}. + Submit the proposal to the relevant governance channels. 3. Once approved (or if using on-chain selection), follow these steps to register session keys using Polkadot.js Apps: diff --git a/node-infrastructure/run-a-node/polkadot-hub-rpc.md b/node-infrastructure/run-a-node/polkadot-hub-rpc.md index 41a6999f9..ccda287f9 100644 --- a/node-infrastructure/run-a-node/polkadot-hub-rpc.md +++ b/node-infrastructure/run-a-node/polkadot-hub-rpc.md @@ -25,7 +25,7 @@ RPC nodes serving production traffic require robust hardware. The following shou - **Memory**: 64 GB RAM minimum; 128 GB recommended for high traffic - **Storage**: - **Archive node (complete history)**: ~1.2 TB NVMe SSD total (~392 GB for Asset Hub archive + ~822 GB for relay chain pruned snapshot) - - **Pruned node (recent state)**: ~2~00 GB NVMe SSD total (with pruning enabled for both parachain and relay chain) + - **Pruned node (recent state)**: ~200 GB NVMe SSD total (with pruning enabled for both parachain and relay chain) - Fast disk I/O is critical for query performance - **Network**: - Public IP address