feat: mainnet name registration plan and batch tooling
Some checks are pending
Build & Release / Linux x86_64 (push) Waiting to run
Build & Release / macOS ARM64 (push) Waiting to run
Build & Release / Create Release (push) Blocked by required conditions

90,041 names from HNS reserved list need pre-registering to prevent
squatting. Strategy: genesis seeds namereg wallets, staking funds the
rest, parallel wallets batch-register into multi-sig.

Co-Authored-By: Charon <charon@lethean.io>
This commit is contained in:
Claude 2026-04-03 14:46:52 +01:00
parent a6773abaca
commit 56d7607754
No known key found for this signature in database
GPG key ID: AF404715446AEB41
2 changed files with 277 additions and 0 deletions

147
PLAN-NAME-REGISTRATION.md Normal file
View file

@ -0,0 +1,147 @@
# Mainnet Name Registration Plan
> **Status:** Validating on testnet
> **Date:** 2026-04-03
> **Authors:** Snider, Charon
## Problem
The Lethean chain merges two blockchains — a main chain (aliases) and an HNS sidechain (DNS). The sidechain blocks Alexa top 100K domains and ICANN TLDs from being registered by random users. But the main chain has no such protection — anyone could register `@google` as an alias before the sidechain has a chance to refuse it.
This creates a window for name squatting that corrupts the namespace before real users arrive.
## Numbers
| Category | Count |
|----------|-------|
| Reserved (Alexa top 100K) | 90,016 |
| Locked (ICANN TLDs) | 11,554 |
| **Total unique names** | **90,041** |
| Long names (>=6 chars, public) | 73,977 |
| Short names (<6 chars, need authority key) | 16,062 |
**Source:** `blockchain-network-dcore/lib/covenants/names.json` and `lockup.json`
## Strategy
### Phase 1: Genesis + HF Warmup
1. Mainnet launches with HF0 — 10M LTHN premine in SWAP wallet
2. During HF warmup (HF0 → HF1), send **1,000+ LTHN** from genesis to dedicated namereg wallets
3. Multiple namereg wallets (2-4) for parallel registration
4. Destination for all reserved aliases: a **multi-sig wallet** controlled by the team
### Phase 2: Staking Funds the Protection
1. Network wallet stakes during warmup — earns ~720 LTHN/day from PoS
2. Legacy users haven't reclaimed tokens yet (SWAP happens later)
3. Staking rewards from the network's own balance fund all registrations
4. The network literally pays for its own name protection
### Phase 3: Batch Registration
When aliases activate (HF that enables alias registration):
1. Namereg wallets already have coins and mature UTXOs ready
2. Multiple wallets work in parallel, each tackling a chunk of the 90K list
3. Priority order:
- **Tier 1:** Top brands (google, facebook, amazon, etc) — ~120 names
- **Tier 2:** Long names from Alexa list (>=6 chars) — ~73,977 names
- **Tier 3:** Short names with authority key (<6 chars) ~16,062 names
4. Rate: ~1 alias per 3 seconds per wallet = ~28,800/day with 1 wallet, ~115,200/day with 4
### Phase 4: Ongoing Governance
1. All reserved names sit in a multi-sig wallet
2. Legitimate brand owners can request transfer (proof of domain ownership)
3. Community aliases (common words like "wallet", "exchange") remain locked
4. Infrastructure names (@vpn, @proxy, @exit, etc) transferred to service operators
## Cost Model
| Item | Cost |
|------|------|
| Alias registration fee | 1 LTHN each |
| Transaction fee | 0.01 LTHN each |
| **Total for 90K names** | **~90,900 LTHN** |
| PoS earnings (720/day) | Covered in ~126 days |
| With 1000 LTHN seed | First ~1000 names immediate |
The network earns back the registration cost through staking before legacy users even begin the SWAP process.
## Technical Requirements
### Testnet Validation (current)
- [x] PoS staking working (first PoS block at height 12,382)
- [x] Alias registration via wallet RPC confirmed
- [x] Batch registration script built and tested
- [x] Priority name list generated from HNS data (90,041 names)
- [ ] Multi-wallet parallel registration tested
- [ ] Authority key for short names (<6 chars) tested
- [ ] Full 90K registration completed on testnet
- [ ] Explorer confirms all names visible
- [ ] LNS resolves registered names
### Mainnet Requirements
- [ ] Multi-sig wallet created for reserved names
- [ ] Genesis transaction plan (SWAP wallet → namereg wallets)
- [ ] Authority key provisioned for short-name registration
- [ ] Ansible playbook for deploying namereg wallets on prod
- [ ] Monitoring: alias count dashboard, registration rate, failures
## Alias Comment Format
All reserved names use this comment format for identification:
```
v=lthn1;type=reserved;reason=hns-protected
```
This allows:
- LNS to identify reserved vs user-registered names
- Future tools to query reserved names
- Governance decisions (release to brand owners) to be automated
## Daemon Configuration
PoS staking requires `--rpc-ignore-offline` when the daemon has no peers:
```
lethean-chain-node --rpc-ignore-offline --do-pos-mining
```
Without this flag, the daemon refuses PoS mining requests when disconnected.
## Batch Registration Tool
```bash
# Generate priority list from HNS data
python3 tools/generate-name-list.py
# Register names (3s delay, checks balance every 10)
bash tools/register-reserved.sh /tmp/protected-names-long.txt http://127.0.0.1:46944/json_rpc 10 3
```
Tool location: `docker/tools/register-reserved.sh`
## Risk Mitigations
| Risk | Mitigation |
|------|-----------|
| Tx pool congestion | Multiple wallets, 3s delay, batch checkpoints |
| Insufficient funds | Staking covers ongoing costs, seed from genesis |
| Authority key compromise | Multi-sig for the key, not single holder |
| Name disputes post-launch | Governance process for brand transfers |
| Testnet/mainnet drift | Same tooling, same scripts, validated on testnet first |
## Timeline
| Phase | When | Duration |
|-------|------|----------|
| Testnet validation | Now (Apr 2026) | 1-2 weeks |
| Mainnet genesis | TBD (Darbs approval) | Day 0 |
| HF warmup | Day 0-7 | 1 week |
| Batch registration | Day 7+ | 1-4 days (with parallel wallets) |
| Full coverage | Day 14 | All 90K protected |

130
docker/tools/register-reserved.sh Executable file
View file

@ -0,0 +1,130 @@
#!/bin/bash
# Lethean Reserved Name Registrar
# Batch-registers protected aliases on the main chain to prevent squatting.
#
# Usage:
# bash register-reserved.sh [names-file] [wallet-rpc] [batch-size] [delay]
#
# Defaults:
# names-file: /tmp/protected-names-priority.txt
# wallet-rpc: http://127.0.0.1:46944/json_rpc
# batch-size: 10 (aliases per batch before checking balance)
# delay: 2 (seconds between registrations)
NAMES_FILE="${1:-/tmp/protected-names-priority.txt}"
WALLET_RPC="${2:-http://127.0.0.1:46944/json_rpc}"
BATCH_SIZE="${3:-10}"
DELAY="${4:-2}"
COMMENT="v=lthn1;type=reserved;reason=hns-protected"
LOG_FILE="/tmp/register-reserved.log"
DONE_FILE="/tmp/registered-names.txt"
touch "$DONE_FILE"
get_balance() {
curl -sf "$WALLET_RPC" -d '{"jsonrpc":"2.0","id":"0","method":"getbalance"}' \
-H 'Content-Type: application/json' | python3 -c "
import sys,json
d=json.load(sys.stdin)['result']
print(d['unlocked_balance'])
" 2>/dev/null
}
get_address() {
curl -sf "$WALLET_RPC" -d '{"jsonrpc":"2.0","id":"0","method":"getaddress"}' \
-H 'Content-Type: application/json' | python3 -c "
import sys,json
print(json.load(sys.stdin)['result']['address'])
" 2>/dev/null
}
register_alias() {
local name="$1"
local address="$2"
result=$(curl -sf "$WALLET_RPC" -d "{
\"jsonrpc\":\"2.0\",\"id\":\"0\",\"method\":\"register_alias\",
\"params\":{
\"alias\":\"$name\",
\"address\":\"$address\",
\"comment\":\"$COMMENT\"
}
}" -H 'Content-Type: application/json' 2>/dev/null)
if echo "$result" | grep -q '"result"'; then
tx=$(echo "$result" | python3 -c "import sys,json; print(json.load(sys.stdin)['result'].get('tx_hash','ok'))" 2>/dev/null)
echo "$name" >> "$DONE_FILE"
echo "$(date +%H:%M:%S) OK @$name ($tx)" | tee -a "$LOG_FILE"
return 0
else
error=$(echo "$result" | python3 -c "import sys,json; print(json.load(sys.stdin).get('error',{}).get('message','unknown')[:80])" 2>/dev/null)
echo "$(date +%H:%M:%S) ERR @$name$error" | tee -a "$LOG_FILE"
return 1
fi
}
# Get wallet address
ADDRESS=$(get_address)
if [ -z "$ADDRESS" ]; then
echo "ERROR: Can't connect to wallet at $WALLET_RPC"
exit 1
fi
echo "Wallet: $ADDRESS"
echo "Names file: $NAMES_FILE ($(wc -l < "$NAMES_FILE") names)"
echo "Already registered: $(wc -l < "$DONE_FILE") names"
echo "Comment: $COMMENT"
echo "Batch: $BATCH_SIZE, Delay: ${DELAY}s"
echo "Log: $LOG_FILE"
echo "---"
BALANCE=$(get_balance)
BALANCE_LTHN=$(echo "scale=2; $BALANCE / 1000000000000" | bc 2>/dev/null)
echo "Balance: $BALANCE_LTHN LTHN"
echo ""
COUNT=0
REGISTERED=0
FAILED=0
SKIPPED=0
while IFS= read -r name; do
# Skip empty lines and comments
[[ -z "$name" || "$name" == \#* ]] && continue
# Skip already registered
if grep -qxF "$name" "$DONE_FILE" 2>/dev/null; then
((SKIPPED++))
continue
fi
# Check balance every batch
if (( COUNT % BATCH_SIZE == 0 && COUNT > 0 )); then
BALANCE=$(get_balance)
BALANCE_LTHN=$(echo "scale=2; $BALANCE / 1000000000000" | bc 2>/dev/null)
echo "--- Batch checkpoint: $BALANCE_LTHN LTHN, $REGISTERED registered, $FAILED failed ---"
# Stop if balance too low (need 1 LTHN + fee)
if (( BALANCE < 1100000000000 )); then
echo "Balance too low ($BALANCE_LTHN LTHN). Stopping."
break
fi
fi
register_alias "$name" "$ADDRESS"
if [ $? -eq 0 ]; then
((REGISTERED++))
else
((FAILED++))
fi
((COUNT++))
sleep "$DELAY"
done < "$NAMES_FILE"
echo ""
echo "=== Done ==="
echo "Registered: $REGISTERED"
echo "Failed: $FAILED"
echo "Skipped: $SKIPPED"
echo "Total processed: $COUNT"