Testnet Resets
Pilier testnet may be reset periodically to maintain performance and test new features.
This document explains when resets happen, how to prepare, and what to do when a reset occurs.
What is a Testnet Reset?
Overview
A testnet reset wipes all blockchain state and starts fresh from a new genesis block.
What gets deleted:
├─ All blocks (history wiped)
├─ All account balances (except genesis allocations)
├─ All on-chain data (DPPs, governance proposals, etc.)
├─ All validator registrations
└─ Transaction history (no trace of previous testnet)
What survives:
├─ Validator session keys (reusable, stored on server)
├─ Account keys (seed phrases still valid)
├─ Node binary (same software, new chain)
├─ Node configuration (systemd service, config files)
└─ Documentation, guides (external to chain)
Analogy:
Reset = Factory reset your phone
├─ Operating system stays (node binary)
├─ Apps reinstalled from scratch (runtime)
├─ All user data deleted (blockchain state)
└─ Fresh start (new genesis block)
Mainnet vs Testnet
| Aspect | Testnet | Mainnet |
|---|---|---|
| Resets | Yes (periodic) | NEVER |
| Data preservation | None (wiped) | Permanent (immutable) |
| Token value | Zero (test PIL) | Real value (PIL) |
| Purpose | Testing, development | Production |
Mainnet will NEVER be reset. All data is permanent. This is a fundamental property of production blockchains.
Testnet resets are ONLY for testing purposes.
Why Reset Testnet?
Valid Reasons
1. Breaking changes requiring new genesis
Examples:
├─ New consensus algorithm (AURA → BABE hypothetical)
├─ Fundamental pallet changes (incompatible storage)
├─ Chain ID change (testnet_v1 → testnet_v2)
└─ Genesis parameters update (validator set, token allocation)
Why necessary:
├─ Runtime upgrade cannot handle migration
├─ Too complex to migrate (risk of bugs)
└─ Cleaner to start fresh
2. State bloat (database too large)
Symptoms:
├─ Testnet database >100 GB (excessive for test network)
├─ Sync time >6 hours (slow for new validators)
├─ Node performance degraded (slow queries)
└─ Storage costs high (unnecessary for testnet)
Solution:
├─ Reset → fresh genesis (database starts at ~1 GB)
├─ Sync time <10 minutes (only new blocks)
└─ Performance restored
3. Scheduled maintenance (regular cleanup)
Pilier testnet policy:
├─ Major reset: Every 6 months (planned)
├─ Minor reset: As needed (for breaking changes)
└─ Emergency reset: Rare (critical bugs only)
Benefits:
├─ Validators practice reset procedures (prepares for mainnet issues)
├─ Fresh start allows testing new genesis parameters
└─ Removes accumulated "test junk" (spam transactions, etc.)
4. Critical bug requiring restart
Examples:
├─ Consensus failure (chain halted, cannot recover)
├─ State corruption (validators disagree on state root)
├─ Security vulnerability (requires immediate mitigation)
└─ Genesis parameter error (e.g., wrong validator set)
Response:
├─ Attempt runtime upgrade fix first (if possible)
├─ If unfixable → emergency reset
└─ Document issue → prevent in mainnet
Invalid Reasons (Won't Trigger Reset)
❌ Minor bugs (fix via runtime upgrade)
❌ Individual validator issues (local problem, not network-wide)
❌ Governance disagreements (resolve via on-chain voting)
❌ "Clean slate" requests (not a valid reason alone)
❌ Cosmetic changes (can be done via upgrade)
Reset Schedule
Planned Resets
Pilier testnet schedule:
Regular resets:
├─ Frequency: Every 6 months
├─ Advance notice: 30 days minimum
├─ Timing: Low-activity periods (avoid major testing campaigns)
└─ Coordination: Announced via all channels
Example schedule (2026):
├─ February 1: Testnet launch (genesis)
├─ August 1: First scheduled reset (6 months)
└─ February 1, 2027: Second scheduled reset (12 months)
Reset windows (typical times):
Preferred days:
├─ Monday-Wednesday (avoids weekends)
├─ First week of month (predictable)
└─ Not during holidays (validator availability)
Preferred times (UTC):
├─ 12:00-16:00 UTC (working hours in EU/US)
├─ Avoids: Late night (validator fatigue)
└─ Allows: Real-time coordination (Telegram call)
Emergency Resets
Unscheduled resets for critical issues:
Advance notice: 24-48 hours (minimum)
Triggers: Chain halt, security vulnerability, state corruption
Process: Emergency announcement → rapid coordination → reset
Post-mortem: Detailed report published within 7 days
Recent emergency resets (hypothetical examples):
March 15, 2026:
├─ Issue: Consensus bug (chain halted at block 50,000)
├─ Notice: 36 hours
├─ Reset: March 17, 14:00 UTC
└─ Impact: 2 days of testnet data lost
April 20, 2026:
├─ Issue: Storage migration bug (validators disagree on state)
├─ Notice: 48 hours
├─ Reset: April 22, 12:00 UTC
└─ Impact: 3 weeks of testnet data lost
Reset Announcement
Notification Channels
All resets announced via:
Primary channels (30 days before):
├─ GitHub Discussion: https://github.com/pilier-org/pilier-node/discussions
│ └─ Pinned post: "Testnet Reset: [Date]"
├─ Governance Forum: https://forum.pilier.net/testnet
│ └─ Category: Testnet Announcements
├─ Validator Telegram: https://t.me/pilier_validators
│ └─ Pinned message + @everyone mention
└─ Email: validators@pilier.net mailing list
Secondary channels (14 days before):
├─ Twitter/X: @pilier_network
├─ Discord: Validator channel
└─ Newsletter: Monthly validator update
Final reminder (7 days before):
├─ All channels above (re-notification)
├─ Direct messages (to active validators)
└─ Telemetry banner (if implemented)
Announcement Template
Example notification:
🔄 **Pilier Testnet Reset Announcement**
**What:** Testnet reset (wipe all state, start fresh genesis)
**When:** August 1, 2026, 14:00 UTC (Block time, not wall clock)
**Why:** Scheduled 6-month maintenance + new pallet-dpp deployment
**Impact:** All balances, validators, on-chain data reset
---
**Timeline:**
📅 **July 1** (30 days before):
- Announcement published (this post)
- New genesis spec released (testnet-v2.json)
📅 **July 15** (14 days before):
- Reminder notification
- Validator preparation guide published
📅 **July 25** (7 days before):
- Final reminder
- Coordination call (Telegram voice chat, 13:00 UTC)
📅 **August 1** (Reset day):
- 13:00 UTC: Pre-reset coordination call (optional)
- 14:00 UTC: RESET (all validators stop old chain, start new)
- 15:00 UTC: Post-reset verification call
---
**What validators need to do:**
1. Backup session keys (if you want to reuse them)
2. Download new chain spec (testnet-v2.json)
3. Purge old chain data (before reset)
4. Join coordination call (August 1, 13:00 UTC)
5. Start new testnet (August 1, 14:00 UTC)
**Detailed instructions:** [link to reset guide]
---
**Questions?**
- Telegram: https://t.me/pilier_validators
- Forum: https://forum.pilier.net/testnet
- Email: validators@pilier.net
---
**Changes in new testnet:**
- ✨ pallet-dpp enabled (DPP creation)
- 🔧 Block time reduced (6s → 4s, testing faster finality)
- 🏛️ Governance parameters updated (voting period 7d → 5d)
- 🔑 Validator set: 5 validators (was 3)
**Full release notes:** [link to GitHub release]
Preparing for Reset
Validator Checklist (Before Reset)
Complete 7 days before reset:
-
Read reset announcement thoroughly
- Understand timeline, changes, new features
- Note coordination call times
-
Backup session keys (if reusing)
# Backup keystore
sudo cp -r /var/lib/pilier/chains/pilier_testnet/keystore /secure-backup/keystore-testnet-v1
# Note: You can reuse these keys on new testnet (optional)
-
Export account keys (controller, stash seed phrases)
- These remain valid (not affected by reset)
- But double-check you have backups!
-
Document your setup
# Save current node version
pilier-node --version > ~/validator-info-pre-reset.txt
# Save current block height (for reference)
curl -s http://127.0.0.1:9933 -H "Content-Type: application/json" \
-d '{"id":1, "jsonrpc":"2.0", "method":"chain_getBlock"}' \
| jq -r '.result.block.header.number' >> ~/validator-info-pre-reset.txt
# Save validator account address
echo "Stash: 5GNJq..." >> ~/validator-info-pre-reset.txt
echo "Controller: 5FHne..." >> ~/validator-info-pre-reset.txt
- Download new chain spec
wget https://raw.githubusercontent.com/pilier-org/pilier-node/main/chain-specs/testnet-v2.json \
-O /tmp/testnet-v2.json
# Verify checksum (from announcement)
sha256sum /tmp/testnet-v2.json
- Update node binary (if new version released)
# Check announcement for required version
# Example: "Requires pilier-node v0.3.0+"
wget https://github.com/pilier-org/pilier-node/releases/download/v0.3.0/pilier-node-linux-x86_64
sha256sum pilier-node-linux-x86_64
# Verify checksum!
- Test run (optional, recommended)
# Start local node with new chain spec (dry run)
pilier-node \
--base-path /tmp/pilier-test-v2 \
--chain /tmp/testnet-v2.json \
--alice \
--tmp
# Should start without errors
# Ctrl+C after 1 minute, clean up:
rm -rf /tmp/pilier-test-v2
- Join coordination call (7 days before)
- Telegram voice chat
- Confirm attendance, ask questions
- Coordinate timing with other validators
User Checklist (Before Reset)
For non-validators (dApp users, testers):
- Export important data
What to export:
├─ Account addresses (will be reused)
├─ DPP IDs, transaction hashes (for records)
├─ Test results, bug reports (document findings)
└─ Any data you want to preserve (off-chain backup)
- Request test tokens (after reset)
Faucet will be refilled after reset:
└─ New testnet → visit https://testnet.pilier.net/faucet
- Update bookmarks
New endpoints (after reset):
├─ RPC: wss://testnet-rpc.pilier.net (same URL, new chain)
├─ Explorer: https://testnet-explorer.pilier.net (will show new genesis)
└─ Apps UI: https://polkadot.js.org/apps → Re-connect to testnet
Reset Execution
Day Before Reset
Final preparations (August 0, evening):
# 1. Verify you have new chain spec
ls -lh /tmp/testnet-v2.json
# 2. Verify node binary version
pilier-node --version
# Should match required version (e.g., v0.3.0)
# 3. Check disk space
df -h /var/lib/pilier
# Need at least 5 GB free
# 4. Ensure systemd service is ready
sudo systemctl status pilier
# Should be active (running)
# 5. Set calendar reminder
# "August 1, 13:00 UTC: Join coordination call"
# "August 1, 14:00 UTC: Execute reset"
Reset Day - Coordination Call (13:00 UTC)
Pre-reset call (1 hour before):
Agenda:
├─ Roll call (who's present?)
├─ Quick review of reset procedure
├─ Q&A (last-minute questions)
├─ Confirm timing (14:00 UTC sharp)
└─ Stay on call until 14:00 (or reconvene at 13:55)
Telegram voice chat: https://t.me/pilier_validators
Reset Day - Execution (14:00 UTC)
Step 1: Stop old testnet (13:58 UTC - 2 minutes early)
# Stop validator node
sudo systemctl stop pilier
# Confirm stopped
sudo systemctl status pilier
# Should show: "inactive (dead)"
Step 2: Purge old chain data (13:59 UTC)
# Delete old testnet database
sudo rm -rf /var/lib/pilier/chains/pilier_testnet/
# Keep keystore backup (already done earlier)
# Do NOT delete: /secure-backup/keystore-testnet-v1/
# Confirm deleted
du -sh /var/lib/pilier/chains/
# Should show: 0 (or only pilier_testnet_v2 if created)
DO NOT skip this step! If you don't delete old chain data, your node will sync old testnet, not new testnet.
Old genesis hash ≠ New genesis hash → Different chains!
Step 3: Install new chain spec (14:00 UTC)
# Replace old chain spec with new
sudo cp /tmp/testnet-v2.json /etc/pilier/testnet.json
# Verify
cat /etc/pilier/testnet.json | head -5
# Should show: "name": "Pilier Testnet v2" (or similar)
# Set ownership
sudo chown pilier:pilier /etc/pilier/testnet.json
Step 4: (Optional) Insert session keys
# Option A: Reuse old session keys
# If you backed up keystore earlier:
sudo cp -r /secure-backup/keystore-testnet-v1/* /var/lib/pilier/chains/pilier_testnet_v2/keystore/
# Option B: Generate new session keys
# (Will do after node starts via author_rotateKeys)
Step 5: Start new testnet (14:00 UTC)
# Start validator node
sudo systemctl start pilier
# Monitor logs (real-time)
sudo journalctl -u pilier -f
# Expected output:
# 2026-08-01 14:00:05 Pilier Node
# 2026-08-01 14:00:05 version 0.3.0-abc123def
# 2026-08-01 14:00:05 Chain specification: Pilier Testnet v2
# 2026-08-01 14:00:05 Node name: validator-lyon-01
# 2026-08-01 14:00:05 Role: AUTHORITY
# 2026-08-01 14:00:05 Database: RocksDb at /var/lib/pilier/chains/pilier_testnet_v2/db/full
# 2026-08-01 14:00:10 Local node identity: 12D3Koo...
# 2026-08-01 14:00:10 Running libp2p network backend
# 2026-08-01 14:00:15 🏷 Listening on /ip4/0.0.0.0/tcp/30333
# 2026-08-01 14:00:20 Discovered new external address: /ip4/51.210.XXX.XXX/tcp/30333
# 2026-08-01 14:00:25 💤 Idle (0 peers), best: #0 (0xabc...genesis)
# 2026-08-01 14:00:30 🔍 Discovered peer: 12D3Koo...validator-02
# 2026-08-01 14:00:35 🔍 Discovered peer: 12D3Koo...validator-03
# 2026-08-01 14:00:40 💤 Idle (2 peers), best: #0
# 2026-08-01 14:00:46 Starting consensus session on top of #0
# 2026-08-01 14:00:46 ✨ Imported #1 (0xdef...)
# 2026-08-01 14:00:52 ✨ Imported #2 (0x123...)
# 2026-08-01 14:00:58 💤 Idle (2 peers), best: #2, finalized #0
# 2026-08-01 14:01:04 ✅ Finalized #1
Key indicators:
✅ "Chain specification: Pilier Testnet v2" (correct chain)
✅ "best: #0 (0xabc...genesis)" (genesis block, block 0)
✅ "Discovered peer" (connecting to other validators)
✅ "Imported #1, #2..." (producing blocks)
✅ "Finalized #1" (finality working)
Step 6: Verify genesis hash (14:01 UTC)
# Query genesis block hash
curl -s -H "Content-Type: application/json" \
-d '{"id":1, "jsonrpc":"2.0", "method":"chain_getBlockHash", "params":[0]}' \
http://127.0.0.1:9933/ | jq -r '.result'
# Output (example):
0x9876543210fedcba9876543210fedcba9876543210fedcba9876543210fedcba
# Compare with official genesis hash (from announcement)
# Should match EXACTLY
Step 7: Re-register validator (14:05 UTC - after first blocks)
# If you generated NEW session keys (Option B above):
# Generate session keys
curl -H "Content-Type: application/json" \
-d '{"id":1, "jsonrpc":"2.0", "method":"author_rotateKeys"}' \
http://127.0.0.1:9933/
# Save result (session keys hex)
# Then set keys on-chain via Polkadot.js Apps:
# - Connect to wss://testnet-rpc.pilier.net
# - Extrinsics → session.setKeys(keys, proof=0x00)
# - Sign with controller account
# If you REUSED old session keys (Option A):
# Keys already in keystore → No action needed!
# But you still need to set keys on-chain (new chain = empty state)
# Check if keys loaded:
ls -la /var/lib/pilier/chains/pilier_testnet_v2/keystore/
# Should see: 61757261... (AURA) and 6772616e... (GRANDPA)
# Set keys on-chain (same as above)
Step 8: Request faucet funds (14:10 UTC)
# Visit faucet
https://testnet.pilier.net/faucet
# Enter your stash account address
# Receive 100 test PIL (or whatever faucet amount)
# Verify balance
curl -s http://127.0.0.1:9933 -H "Content-Type: application/json" \
-d '{"id":1, "jsonrpc":"2.0", "method":"system_account", "params":["5GNJq...your-address"]}' \
| jq '.result.data.free'
# Output: 100000000000000 (100 PIL * 10^15)
Step 9: Bond & validate (14:15 UTC)
# Via Polkadot.js Apps:
1. Network → Staking → Account Actions
2. "+ Stash" → Bond funds
- Stash: Your stash account
- Controller: Your controller account
- Value: 10 PIL (testnet minimum)
3. "Validate" → Start validating
- Commission: 10% (example)
4. Wait for next session (~1 hour)
5. Verify you're in active validator set
Step 10: Report status (14:20 UTC)
# In Telegram coordination call:
"✅ validator-lyon-01 online
- Genesis: 0x9876...
- Peers: 4
- Best block: #15
- Session keys set: Yes
- Validating: Pending (next session)"
# Coordinator tracks all validators:
# - All 5 validators online? ✓
# - All on correct genesis? ✓
# - All producing blocks? ✓
# - Finality working? ✓
Post-Reset Verification (14:30 UTC)
Coordinator checklist:
Network health:
├─ All validators online (telemetry green)
├─ Block production normal (~1 block per 6 seconds)
├─ Finality working (finalized block < 12 seconds behind best)
├─ No consensus errors (logs clean)
└─ Public RPC responding (can query from external)
Validator status:
├─ All 5 founding validators online
├─ All have set session keys
├─ All registered in staking pallet
└─ First blocks produced by each validator
Post-reset tasks:
├─ Update block explorer (point to new chain)
├─ Update public RPC endpoints (flush cache)
├─ Announce reset completion (forum, Telegram)
└─ Monitor for 24 hours (watch for issues)
Common Issues
Issue 1: Node Stuck on Old Genesis
Symptom:
Logs show:
"best: #50000" (old testnet height)
"Syncing from peer..." (syncing old chain)
Genesis hash: 0x1234...old (not matching announcement)
Cause: Didn't delete old chain data.
Fix:
# 1. Stop node
sudo systemctl stop pilier
# 2. Delete old chain data (for real this time!)
sudo rm -rf /var/lib/pilier/chains/pilier_testnet/
sudo rm -rf /var/lib/pilier/chains/pilier_testnet_v2/db/ # If created
# 3. Verify deleted
ls -la /var/lib/pilier/chains/
# Should be empty (or only have other chains)
# 4. Start node
sudo systemctl start pilier
# 5. Monitor - should sync new genesis now
sudo journalctl -u pilier -f
# Look for: "best: #0" (genesis), "Imported #1, #2..."
Issue 2: Peer Discovery Failure
Symptom:
Logs show:
"💤 Idle (0 peers), best: #0"
No peers discovered after 5 minutes
Blocks not being imported
Cause:
- Firewall blocking P2P port
- Incorrect boot nodes in chain spec
- Network isolation
Fix:
# 1. Check firewall
sudo ufw status
# Ensure port 30333 is allowed
# 2. Check boot nodes in chain spec
cat /etc/pilier/testnet.json | jq '.bootNodes'
# Should list 2-3 boot node addresses
# 3. Manually connect to peer (temporary fix)
# Find another validator's peer ID from Telegram
# Restart node with --reserved-nodes flag
# 4. If all validators have 0 peers:
# - Coordination issue (not all validators started)
# - Wait for other validators to come online
# - Verify in Telegram call
Issue 3: Session Keys Not Working
Symptom:
Logs show:
"Authority set mismatch"
"Not in validator set"
Blocks being imported, but NOT produced by you
Cause:
- Session keys not set on-chain
- Wrong keys (old testnet keys, but forgot to insert into new keystore)
- Not registered as validator (forgot to call session.setKeys)
Fix:
# 1. Check if keys in keystore
ls -la /var/lib/pilier/chains/pilier_testnet_v2/keystore/
# Should see 2 files (AURA + GRANDPA)
# 2. If NO keys: Generate new
curl -H "Content-Type: application/json" \
-d '{"id":1, "jsonrpc":"2.0", "method":"author_rotateKeys"}' \
http://127.0.0.1:9933/
# 3. Set keys on-chain (via Polkadot.js Apps)
# session.setKeys(keys, proof=0x00)
# 4. Wait for next session (~1 hour)
# Then check logs: "Prepared block for proposing"
Issue 4: Genesis Hash Mismatch
Symptom:
Your genesis: 0xabc123...
Announced genesis: 0xdef456... (different!)
Peers disconnecting: "Genesis hash mismatch"
Cause: Using wrong chain spec file.
Fix:
# 1. Verify you downloaded correct chain spec
cat /etc/pilier/testnet.json | jq '.id'
# Output: "pilier_testnet_v2"
# 2. Re-download from official source
sudo rm /etc/pilier/testnet.json
wget https://raw.githubusercontent.com/pilier-org/pilier-node/main/chain-specs/testnet-v2.json \
-O /etc/pilier/testnet.json
# 3. Verify checksum
sha256sum /etc/pilier/testnet.json
# Compare with announcement
# 4. Delete chain data (force re-sync with correct genesis)
sudo systemctl stop pilier
sudo rm -rf /var/lib/pilier/chains/pilier_testnet_v2/
sudo systemctl start pilier
Issue 5: Faucet Not Working
Symptom:
Faucet website returns:
"Error: Insufficient funds"
"Please try again later"
Account balance stays 0 PIL
Cause: Faucet not refilled after reset (coordinator task).
Fix:
# For validators: Request directly in Telegram
# @coordinator: "Faucet empty, can you refill?"
# For users: Wait 10-30 minutes
# Faucet usually refilled within first hour of reset
# Alternative: Ask existing testnet user to send you test PIL
# Polkadot.js Apps → Accounts → Transfer
After Reset
Network Monitoring (First 24 Hours)
Coordinator responsibilities:
Hour 0-1:
├─ All validators online?
├─ Blocks producing normally?
├─ Finality working?
└─ Public RPC operational?
Hour 1-6:
├─ Any validators dropped offline?
├─ Block time stable (~6 seconds)?
├─ Faucet functional?
└─ Block explorer updated?
Hour 6-24:
├─ Long-term stability (no crashes)?
├─ Database size normal (<2 GB)?
├─ Validator rewards distributing?
└─ User feedback (any issues reported)?
Day 1-7:
├─ Monitor telemetry daily
├─ Respond to bug reports
├─ Publish post-reset summary (forum)
└─ Plan next features/upgrades
Post-Reset Announcement
Example completion message:
✅ **Testnet Reset Complete!**
🎉 Pilier Testnet v2 is now live!
**Summary:**
- Genesis block: #0 (0x9876...fedcba)
- Launch time: August 1, 2026, 14:00 UTC
- Validators online: 5/5 ✓
- Finality: Working ✓
- Public RPC: Operational ✓
**What's new:**
- ✨ pallet-dpp enabled (create Digital Product Passports)
- ⚡ Faster block time (4 seconds, down from 6)
- 🏛️ Updated governance (5-day voting period)
- 🔑 5 validators (was 3)
**Getting started:**
1. Faucet: https://testnet.pilier.net/faucet
2. RPC: wss://testnet-rpc.pilier.net
3. Explorer: https://testnet-explorer.pilier.net
4. Docs: https://docs.pilier.net
**Known issues:**
- None reported (will update if any arise)
**Feedback:**
- Forum: https://forum.pilier.net/testnet
- Telegram: https://t.me/pilier_validators
**Next reset:**
- Scheduled: February 1, 2027 (6 months)
- Will announce 30 days in advance
Thanks to all validators for smooth coordination! 🙌
Best Practices
For Validators
DO:
- ✅ Subscribe to announcements (GitHub, Telegram, email)
- ✅ Read reset notices fully (don't skim)
- ✅ Backup session keys (before reset)
- ✅ Join coordination calls (synchronize with team)
- ✅ Test beforehand (dry run on local node)
- ✅ Delete old chain data (critical step!)
- ✅ Verify genesis hash (avoid wrong chain)
- ✅ Report issues immediately (Telegram, don't wait)
DON'T:
- ❌ Don't skip steps (follow guide exactly)
- ❌ Don't keep old chain data (causes sync to wrong chain)
- ❌ Don't use old chain spec (download new one)
- ❌ Don't panic (resets are routine, coordinator will help)
- ❌ Don't modify genesis (use official chain spec only)
For Coordinators
Pre-reset:
- ✅ Announce 30 days in advance (minimum)
- ✅ Publish detailed guide (like this one)
- ✅ Test reset procedure internally (dry run)
- ✅ Prepare new chain spec (reviewed, tested)
- ✅ Schedule coordination calls (multiple timezones)
- ✅ Verify validator availability (poll in Telegram)
During reset:
- ✅ Lead coordination call (guide validators through steps)