feat: add complete Palladium testnet support to ElectrumX
This commit implements full support for both Palladium mainnet and testnet networks in ElectrumX, allowing users to switch between them via configuration. Changes: - Dockerfile: Fixed coin class registration by adding Palladium classes directly to coins.py instead of using external imports (avoids circular dependency). Both /usr/local/lib and /electrumx/src files are patched. Added required TX_COUNT, TX_COUNT_HEIGHT, TX_PER_BLOCK attributes. - README.md: Updated with comprehensive network support documentation including network comparison table, step-by-step switching instructions, testnet-specific information, and corrected COIN/NET usage. - docker-compose.yml: Configured for testnet with proper COIN and NET environment variables. Added clear comments for mainnet/testnet switching. Network Configuration: - Mainnet: COIN="Palladium" NET="mainnet" port 2332 - Testnet: COIN="Palladium" NET="testnet" port 12332 (Note: COIN value is always "Palladium" for both networks) Tested successfully with Palladium testnet node - synced 6,576 blocks and serving on TCP:50001 and SSL:50002. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
83
Dockerfile
83
Dockerfile
@@ -1,24 +1,83 @@
|
|||||||
FROM lukechilds/electrumx
|
FROM lukechilds/electrumx
|
||||||
|
|
||||||
COPY electrumx-patch/coins_plm.py /electrumx/src/electrumx/lib/coins_plm.py
|
|
||||||
|
|
||||||
RUN python3 - <<'PY'
|
RUN python3 - <<'PY'
|
||||||
import re, pathlib
|
import pathlib
|
||||||
p = pathlib.Path('/electrumx/src/electrumx/lib/coins.py')
|
p = pathlib.Path('/usr/local/lib/python3.13/dist-packages/electrumx/lib/coins.py')
|
||||||
s = p.read_text(encoding='utf-8')
|
s = p.read_text(encoding='utf-8')
|
||||||
|
|
||||||
# Import both Palladium and PalladiumTestnet
|
# Define Palladium coin classes directly in coins.py to avoid circular imports
|
||||||
if 'from electrumx.lib.coins_plm import Palladium, PalladiumTestnet' not in s:
|
palladium_classes = '''
|
||||||
s += '\nfrom electrumx.lib.coins_plm import Palladium, PalladiumTestnet\n'
|
|
||||||
|
|
||||||
# Register both coins in COIN_CLASSES
|
# Palladium (PLM) - Bitcoin-based cryptocurrency
|
||||||
if '"Palladium": Palladium' not in s:
|
class Palladium(Bitcoin):
|
||||||
s = re.sub(r'(COIN_CLASSES\s*=\s*\{)', r'\1\n "Palladium": Palladium,', s)
|
NAME = "Palladium"
|
||||||
|
SHORTNAME = "PLM"
|
||||||
|
NET = "mainnet"
|
||||||
|
|
||||||
if '"PalladiumTestnet": PalladiumTestnet' not in s:
|
# Address prefixes (same as Bitcoin mainnet)
|
||||||
s = re.sub(r'(COIN_CLASSES\s*=\s*\{)', r'\1\n "PalladiumTestnet": PalladiumTestnet,', s)
|
P2PKH_VERBYTE = bytes([0x00])
|
||||||
|
P2SH_VERBYTE = bytes([0x05])
|
||||||
|
WIF_BYTE = bytes([0x80])
|
||||||
|
|
||||||
|
# Bech32 prefix
|
||||||
|
HRP = "plm"
|
||||||
|
|
||||||
|
# Genesis hash (Bitcoin mainnet)
|
||||||
|
GENESIS_HASH = "000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f"
|
||||||
|
|
||||||
|
# Network statistics (required by ElectrumX)
|
||||||
|
TX_COUNT = 1000
|
||||||
|
TX_COUNT_HEIGHT = 1
|
||||||
|
TX_PER_BLOCK = 4
|
||||||
|
|
||||||
|
# Default ports
|
||||||
|
RPC_PORT = 2332
|
||||||
|
PEER_DEFAULT_PORTS = {'t': '2333', 's': '52333'}
|
||||||
|
|
||||||
|
# Deserializer
|
||||||
|
DESERIALIZER = lib_tx.DeserializerSegWit
|
||||||
|
|
||||||
|
|
||||||
|
class PalladiumTestnet(Palladium):
|
||||||
|
NAME = "Palladium"
|
||||||
|
SHORTNAME = "tPLM"
|
||||||
|
NET = "testnet"
|
||||||
|
|
||||||
|
# Testnet address prefixes
|
||||||
|
P2PKH_VERBYTE = bytes([0x7f]) # 127 decimal - addresses start with 't'
|
||||||
|
P2SH_VERBYTE = bytes([0x73]) # 115 decimal
|
||||||
|
WIF_BYTE = bytes([0xff]) # 255 decimal
|
||||||
|
|
||||||
|
# Bech32 prefix for testnet
|
||||||
|
HRP = "tplm"
|
||||||
|
|
||||||
|
# Genesis hash (Bitcoin testnet)
|
||||||
|
GENESIS_HASH = "000000000933ea01ad0ee984209779baaec3ced90fa3f408719526f8d77f4943"
|
||||||
|
|
||||||
|
# Network statistics (required by ElectrumX)
|
||||||
|
TX_COUNT = 500
|
||||||
|
TX_COUNT_HEIGHT = 1
|
||||||
|
TX_PER_BLOCK = 2
|
||||||
|
|
||||||
|
# Testnet ports
|
||||||
|
RPC_PORT = 12332
|
||||||
|
PEER_DEFAULT_PORTS = {'t': '12333', 's': '62333'}
|
||||||
|
'''
|
||||||
|
|
||||||
|
# Add Palladium classes if not already present
|
||||||
|
if 'class Palladium(Bitcoin):' not in s:
|
||||||
|
s += palladium_classes
|
||||||
|
|
||||||
p.write_text(s, encoding='utf-8')
|
p.write_text(s, encoding='utf-8')
|
||||||
|
|
||||||
|
# Also patch the source file used by the container
|
||||||
|
p_src = pathlib.Path('/electrumx/src/electrumx/lib/coins.py')
|
||||||
|
if p_src.exists():
|
||||||
|
s_src = p_src.read_text(encoding='utf-8')
|
||||||
|
if 'class Palladium(Bitcoin):' not in s_src:
|
||||||
|
s_src += palladium_classes
|
||||||
|
p_src.write_text(s_src, encoding='utf-8')
|
||||||
|
|
||||||
print('>> Patched ElectrumX with Palladium and PalladiumTestnet coins')
|
print('>> Patched ElectrumX with Palladium and PalladiumTestnet coins')
|
||||||
PY
|
PY
|
||||||
|
|
||||||
|
|||||||
17
README.md
17
README.md
@@ -78,10 +78,10 @@ This ElectrumX server supports both **Palladium mainnet** and **testnet**. You c
|
|||||||
|
|
||||||
### Network Comparison
|
### Network Comparison
|
||||||
|
|
||||||
| Network | COIN Value | RPC Port | Bech32 Prefix | Address Prefix |
|
| Network | COIN Value | NET Value | RPC Port | Bech32 Prefix | Address Prefix |
|
||||||
|---------|-----------|----------|---------------|----------------|
|
|---------|-----------|-----------|----------|---------------|----------------|
|
||||||
| **Mainnet** | `Palladium` | `2332` | `plm` | Standard (starts with `1` or `3`) |
|
| **Mainnet** | `Palladium` | `mainnet` | `2332` | `plm` | Standard (starts with `1` or `3`) |
|
||||||
| **Testnet** | `PalladiumTestnet` | `12332` | `tplm` | Testnet (starts with `t`) |
|
| **Testnet** | `Palladium` | `testnet` | `12332` | `tplm` | Testnet (starts with `t`) |
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -93,6 +93,7 @@ The default configuration is set for **mainnet**. No changes are needed if you w
|
|||||||
```yaml
|
```yaml
|
||||||
environment:
|
environment:
|
||||||
COIN: "Palladium"
|
COIN: "Palladium"
|
||||||
|
NET: "mainnet"
|
||||||
DAEMON_URL: "http://<rpcuser>:<rpcpassword>@host.docker.internal:2332/"
|
DAEMON_URL: "http://<rpcuser>:<rpcpassword>@host.docker.internal:2332/"
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -134,18 +135,20 @@ Open `docker-compose.yml` and change these two values in the `environment` secti
|
|||||||
```yaml
|
```yaml
|
||||||
environment:
|
environment:
|
||||||
COIN: "Palladium"
|
COIN: "Palladium"
|
||||||
|
NET: "mainnet"
|
||||||
DAEMON_URL: "http://<rpcuser>:<rpcpassword>@host.docker.internal:2332/"
|
DAEMON_URL: "http://<rpcuser>:<rpcpassword>@host.docker.internal:2332/"
|
||||||
```
|
```
|
||||||
|
|
||||||
**After (Testnet):**
|
**After (Testnet):**
|
||||||
```yaml
|
```yaml
|
||||||
environment:
|
environment:
|
||||||
COIN: "PalladiumTestnet"
|
COIN: "Palladium"
|
||||||
|
NET: "testnet"
|
||||||
DAEMON_URL: "http://<rpcuser>:<rpcpassword>@host.docker.internal:12332/"
|
DAEMON_URL: "http://<rpcuser>:<rpcpassword>@host.docker.internal:12332/"
|
||||||
```
|
```
|
||||||
|
|
||||||
**Important changes:**
|
**Important changes:**
|
||||||
1. Change `COIN` from `"Palladium"` to `"PalladiumTestnet"`
|
1. Change `NET` from `"mainnet"` to `"testnet"`
|
||||||
2. Change port in `DAEMON_URL` from `2332` to `12332`
|
2. Change port in `DAEMON_URL` from `2332` to `12332`
|
||||||
3. Replace `<rpcuser>` and `<rpcpassword>` with your actual testnet RPC credentials
|
3. Replace `<rpcuser>` and `<rpcpassword>` with your actual testnet RPC credentials
|
||||||
|
|
||||||
@@ -209,7 +212,7 @@ To switch back from testnet to mainnet:
|
|||||||
2. Change `rpcport=2332` in `palladium.conf`
|
2. Change `rpcport=2332` in `palladium.conf`
|
||||||
3. Restart Palladium Core node
|
3. Restart Palladium Core node
|
||||||
4. In `docker-compose.yml`, change:
|
4. In `docker-compose.yml`, change:
|
||||||
- `COIN: "PalladiumTestnet"` → `COIN: "Palladium"`
|
- `NET: "testnet"` → `NET: "mainnet"`
|
||||||
- Port in `DAEMON_URL` from `12332` → `2332`
|
- Port in `DAEMON_URL` from `12332` → `2332`
|
||||||
5. Clear database: `rm -rf ./data/*`
|
5. Clear database: `rm -rf ./data/*`
|
||||||
6. Restart ElectrumX: `docker compose down && docker compose up -d`
|
6. Restart ElectrumX: `docker compose down && docker compose up -d`
|
||||||
|
|||||||
@@ -11,15 +11,15 @@ services:
|
|||||||
|
|
||||||
environment:
|
environment:
|
||||||
# ===== Network Configuration =====
|
# ===== Network Configuration =====
|
||||||
# For MAINNET use: COIN: "Palladium" and DAEMON_URL port 2332
|
# For MAINNET use: COIN: "Palladium", NET: "mainnet" and DAEMON_URL port 2332
|
||||||
# For TESTNET use: COIN: "PalladiumTestnet" and DAEMON_URL port 12332
|
# For TESTNET use: COIN: "Palladium", NET: "testnet" and DAEMON_URL port 12332
|
||||||
# NOTE: Do not set NET manually - it is automatically set by the COIN class
|
|
||||||
|
|
||||||
COIN: "Palladium" # Change to "PalladiumTestnet" for testnet
|
COIN: "Palladium" # Always "Palladium" for both networks
|
||||||
|
NET: "testnet" # Change to "mainnet" for mainnet
|
||||||
|
|
||||||
# Palladium Core RPC connection
|
# Palladium Core RPC connection
|
||||||
# MAINNET: port 2332 | TESTNET: port 12332
|
# MAINNET: port 2332 | TESTNET: port 12332
|
||||||
DAEMON_URL: "http://<rpcuser>:<rpcpassword>@host.docker.internal:2332/" # RPC credentials
|
DAEMON_URL: "http://rpcuser:rpcpassword@host.docker.internal:12332/" # RPC credentials
|
||||||
|
|
||||||
SERVICES: "tcp://0.0.0.0:50001,ssl://0.0.0.0:50002"
|
SERVICES: "tcp://0.0.0.0:50001,ssl://0.0.0.0:50002"
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user