Compare commits
5 Commits
8131d7048e
...
f631edfc4d
| Author | SHA1 | Date | |
|---|---|---|---|
| f631edfc4d | |||
| 2ed5c746a9 | |||
| 9cb7922ac1 | |||
| 3ce18c9860 | |||
| 5cc3dcacc8 |
@@ -1,88 +1,29 @@
|
||||
FROM lukechilds/electrumx
|
||||
|
||||
RUN python3 - <<'PY'
|
||||
import pathlib
|
||||
p = pathlib.Path('/usr/local/lib/python3.13/dist-packages/electrumx/lib/coins.py')
|
||||
s = p.read_text(encoding='utf-8')
|
||||
# Copy Palladium coin definition and patch ElectrumX
|
||||
COPY electrumx-patch/coins_plm.py /tmp/coins_plm.py
|
||||
|
||||
# Define Palladium coin classes directly in coins.py to avoid circular imports
|
||||
palladium_classes = '''
|
||||
RUN python3 - <<'PATCH'
|
||||
import pathlib, re
|
||||
|
||||
# Palladium (PLM) - Bitcoin-based cryptocurrency
|
||||
class Palladium(Bitcoin):
|
||||
NAME = "Palladium"
|
||||
SHORTNAME = "PLM"
|
||||
NET = "mainnet"
|
||||
patch = pathlib.Path('/tmp/coins_plm.py').read_text()
|
||||
# Extract only class definitions (skip import lines)
|
||||
classes = re.split(r'^(?=class )', patch, flags=re.MULTILINE)
|
||||
classes = [c for c in classes if c.strip().startswith('class ')]
|
||||
body = '\n' + '\n'.join(classes)
|
||||
|
||||
# Address prefixes (same as Bitcoin mainnet)
|
||||
P2PKH_VERBYTE = bytes([0x00])
|
||||
P2SH_VERBYTE = bytes([0x05])
|
||||
WIF_BYTE = bytes([0x80])
|
||||
for target in [
|
||||
'/usr/local/lib/python3.13/dist-packages/electrumx/lib/coins.py',
|
||||
'/electrumx/src/electrumx/lib/coins.py',
|
||||
]:
|
||||
p = pathlib.Path(target)
|
||||
if p.exists():
|
||||
s = p.read_text()
|
||||
if 'class Palladium(Bitcoin):' not in s:
|
||||
p.write_text(s + body)
|
||||
|
||||
# Bech32 prefix
|
||||
HRP = "plm"
|
||||
|
||||
# Genesis hash (Bitcoin mainnet)
|
||||
GENESIS_HASH = "000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f"
|
||||
|
||||
# Clear inherited checkpoints
|
||||
CHECKPOINTS = []
|
||||
|
||||
# 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')
|
||||
|
||||
# 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')
|
||||
PY
|
||||
print('>> Patched ElectrumX with Palladium coin classes')
|
||||
PATCH
|
||||
|
||||
RUN mkdir -p /certs && \
|
||||
cat >/certs/openssl.cnf <<'EOF' && \
|
||||
|
||||
55
daemon/README.md
Normal file
55
daemon/README.md
Normal file
@@ -0,0 +1,55 @@
|
||||
# Palladium Core Binaries
|
||||
|
||||
This directory must contain the pre-compiled Palladium Core binaries used by the Docker node container.
|
||||
|
||||
## Download
|
||||
|
||||
Download the latest release from the official repository:
|
||||
|
||||
**https://github.com/palladium-coin/palladiumcore/releases**
|
||||
|
||||
## Architecture
|
||||
|
||||
The binaries **must match the host architecture** where Docker is running.
|
||||
Choose the correct archive for your platform:
|
||||
|
||||
| Host Architecture | Archive to download | Common hardware |
|
||||
|-------------------|-------------------------|-------------------------------------|
|
||||
| `x86_64` | `x86_64-linux-gnu.tar.gz` | Standard PCs, most VPS/cloud servers |
|
||||
| `aarch64` | `aarch64-linux-gnu.tar.gz` | Single-board computers (Raspberry Pi 4/5, Orange Pi, etc.) |
|
||||
|
||||
To check your host architecture:
|
||||
|
||||
```bash
|
||||
uname -m
|
||||
```
|
||||
|
||||
## Required binaries
|
||||
|
||||
Extract the following files from the release archive and place them in this directory:
|
||||
|
||||
```
|
||||
daemon/
|
||||
palladiumd # Full node daemon (required)
|
||||
palladium-cli # RPC command-line client (required)
|
||||
palladium-tx # Transaction utility
|
||||
palladium-wallet # Wallet utility
|
||||
```
|
||||
|
||||
## Quick setup
|
||||
|
||||
```bash
|
||||
# Example for aarch64 (Raspberry Pi)
|
||||
tar xzf palladiumcore-*-aarch64-linux-gnu.tar.gz
|
||||
cp palladiumcore-*/bin/palladium{d,-cli,-tx,-wallet} daemon/
|
||||
|
||||
# Example for x86_64 (VPS/PC)
|
||||
tar xzf palladiumcore-*-x86_64-linux-gnu.tar.gz
|
||||
cp palladiumcore-*/bin/palladium{d,-cli,-tx,-wallet} daemon/
|
||||
```
|
||||
|
||||
After placing the binaries, rebuild the node image:
|
||||
|
||||
```bash
|
||||
docker compose build palladiumd
|
||||
```
|
||||
@@ -57,11 +57,14 @@ services:
|
||||
SSL_KEYFILE: "/certs/server.key"
|
||||
|
||||
DB_DIRECTORY: "/data"
|
||||
PEER_DISCOVERY: "off"
|
||||
PEER_ANNOUNCE: "false"
|
||||
PEER_DISCOVERY: "on"
|
||||
PEER_ANNOUNCE: "true"
|
||||
# Set this to the server's public IP or hostname (required for peer discovery)
|
||||
# REPORT_HOST: "your.public.ip.or.hostname"
|
||||
INITIAL_CONCURRENT: "2"
|
||||
COST_SOFT_LIMIT: "0"
|
||||
COST_HARD_LIMIT: "0"
|
||||
DONATION_ADDRESS: "plm1qdq3gu2zvg9lyr8gxd6yln4wavc5tlp8prmvfay"
|
||||
|
||||
ulimits:
|
||||
nofile:
|
||||
|
||||
@@ -21,9 +21,22 @@ class Palladium(Bitcoin):
|
||||
# Since we share Genesis with Bitcoin, we must clear inherited checkpoints
|
||||
CHECKPOINTS = []
|
||||
|
||||
# === Network statistics (required by ElectrumX) ===
|
||||
TX_COUNT = 457478
|
||||
TX_COUNT_HEIGHT = 382404
|
||||
TX_PER_BLOCK = 2
|
||||
|
||||
# === Default ports ===
|
||||
RPC_PORT = 2332
|
||||
PEER_DEFAULT_PORTS = {'t': '2333', 's': '52333'}
|
||||
PEER_DEFAULT_PORTS = {'t': '50001', 's': '50002'}
|
||||
|
||||
# === Seed peers for discovery ===
|
||||
PEERS = [
|
||||
'66.94.115.80 t',
|
||||
'89.117.149.130 t',
|
||||
'173.212.224.67 t',
|
||||
'82.165.218.152 t',
|
||||
]
|
||||
|
||||
# === Deserializer ===
|
||||
DESERIALIZER = lib_tx.DeserializerSegWit
|
||||
@@ -45,7 +58,12 @@ class PalladiumTestnet(Palladium):
|
||||
# === 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'}
|
||||
PEER_DEFAULT_PORTS = {'t': '60001', 's': '60002'}
|
||||
|
||||
|
||||
@@ -53,5 +53,41 @@ echo "RPC Port: ${RPC_PORT}"
|
||||
echo "DAEMON_URL: http://${RPC_USER}:***@palladiumd:${RPC_PORT}/"
|
||||
echo "=========================================="
|
||||
|
||||
# Update TX_COUNT / TX_COUNT_HEIGHT in coins.py from the live node
|
||||
echo "Fetching chain tx stats from palladiumd..."
|
||||
TX_STATS=$(curl -sf --user "${RPC_USER}:${RPC_PASSWORD}" \
|
||||
--data-binary '{"jsonrpc":"1.0","method":"getchaintxstats","params":[]}' \
|
||||
-H 'Content-Type: text/plain;' \
|
||||
"http://palladiumd:${RPC_PORT}/" 2>/dev/null || true)
|
||||
|
||||
if [ -n "$TX_STATS" ]; then
|
||||
TX_COUNT=$(echo "$TX_STATS" | python3 -c "import sys,json; print(json.load(sys.stdin)['result']['txcount'])" 2>/dev/null || true)
|
||||
TX_HEIGHT=$(echo "$TX_STATS" | python3 -c "import sys,json; print(json.load(sys.stdin)['result']['window_final_block_height'])" 2>/dev/null || true)
|
||||
|
||||
if [ -n "$TX_COUNT" ] && [ -n "$TX_HEIGHT" ]; then
|
||||
echo "Patching coins.py: TX_COUNT=${TX_COUNT}, TX_COUNT_HEIGHT=${TX_HEIGHT}"
|
||||
python3 - "$TX_COUNT" "$TX_HEIGHT" <<'TXPATCH'
|
||||
import sys, pathlib, re
|
||||
tx_count, tx_height = sys.argv[1], sys.argv[2]
|
||||
for target in [
|
||||
'/usr/local/lib/python3.13/dist-packages/electrumx/lib/coins.py',
|
||||
'/electrumx/src/electrumx/lib/coins.py',
|
||||
]:
|
||||
p = pathlib.Path(target)
|
||||
if not p.exists():
|
||||
continue
|
||||
s = p.read_text()
|
||||
s = re.sub(r'(class Palladium\(Bitcoin\):.*?TX_COUNT\s*=\s*)\d+', rf'\g<1>{tx_count}', s, count=1, flags=re.DOTALL)
|
||||
s = re.sub(r'(class Palladium\(Bitcoin\):.*?TX_COUNT_HEIGHT\s*=\s*)\d+', rf'\g<1>{tx_height}', s, count=1, flags=re.DOTALL)
|
||||
p.write_text(s)
|
||||
TXPATCH
|
||||
echo ">> TX stats updated from live node"
|
||||
else
|
||||
echo ">> Could not parse tx stats, using defaults from coins_plm.py"
|
||||
fi
|
||||
else
|
||||
echo ">> Node not reachable yet, using defaults from coins_plm.py"
|
||||
fi
|
||||
|
||||
# Execute the original electrumx command
|
||||
exec /usr/local/bin/electrumx_server
|
||||
|
||||
Reference in New Issue
Block a user