BIP44_COIN_TYPE was accidentally set to 0 (Bitcoin mainnet), which would cause BTCP wallets to derive keys identical to Bitcoin mainnet wallets from the same seed. Restored to 13496 (provisional private constant matching the BTCP P2P port) per tecnichal-data.md spec; updated table entry and test. Also fixes a race condition in TestPeerDirectAnchors::test_payments_stresstest: gath.cancel() was called immediately after OldTaskGroup exited, without any await, so the event loop never ran the message-loop tasks to drain the final revoke_and_ack for the last batch of 5 concurrent HTLCs. Added asyncio.sleep(0) to yield one event-loop iteration before cancelling.
44 KiB
BitcoinPurple — Technical Reference
Parameter reference for BitcoinPurple (BTCP) node operators and developers building on top of the network: ElectrumX server, Electrum wallet fork, Lightning Network fork. All values are sourced directly from the codebase unless noted otherwise.
Quick Reference
The most-looked-up values, all in one place.
| Parameter | Mainnet | Testnet | Signet | Regtest |
|---|---|---|---|---|
| P2P port | 13496 |
23496 |
33496 |
18444 |
| RPC port | 13495 |
23495 |
33495 |
18443 |
| ElectrumX TCP | 50001 |
60001 |
— | — |
| ElectrumX SSL | 50002 |
60002 |
— | — |
| Magic bytes | fc991395 |
29fbc5fe |
— | 31346ac9 |
| Bech32 / BOLT11 HRP | btcp |
tbtcp |
tbtcp |
rbtcp |
| P2PKH prefix | 56 (0x38) → P |
56 (0x38) |
56 | 56 |
| P2SH prefix | 55 (0x37) → P |
55 (0x37) |
55 | 55 |
| WIF prefix | 183 (0xb7) |
183 (0xb7) |
183 | 183 |
| BIP32 xpub | 0488B21E |
043587CF |
043587CF |
043587CF |
| BIP32 xprv | 0488ADE4 |
04358394 |
04358394 |
04358394 |
| Block time | 60 s | 60 s | 60 s | instant |
| Halving interval | 500,000 blocks | — | — | 150 blocks |
Monetary cap (MAX_MONEY) |
1,000,000 BTCP | — | — | — |
| Genesis hash | 000003823f…c015 |
000002fdc3…d998 |
00000131aa…b403 |
6f6ffbda…e1df |
| LN chain_hash | 15c04ef0…0000 |
98d9f92e…0000 |
— | — |
1. Network Identity
| Parameter | Value | Source |
|---|---|---|
| Full name | BitcoinPurple | — |
| Ticker | BTCP | — |
| Version | 1.1.1 | configure.ac |
| Daemon binary | bitcoinpurpled |
— |
| Config file | ~/.bitcoinpurple/bitcoinpurple.conf |
— |
| PoW algorithm | SHA256d (identical to Bitcoin) | — |
| Protocol version | 70016 | src/version.h:12 |
| Min peer protocol | 31800 | src/version.h:18 |
2. Mainnet Parameters
2.1 Ports
| Service | Port | Source |
|---|---|---|
| P2P | 13496 |
src/kernel/chainparams.cpp:116 |
| RPC | 13495 |
src/chainparamsbase.cpp:47 |
| Tor onion | 8334 |
src/chainparamsbase.cpp:47 |
2.2 Address Encoding
| Type | Decimal | Hex | Address prefix | Source |
|---|---|---|---|---|
P2PKH (PUBKEY_ADDRESS) |
56 | 0x38 |
P |
src/kernel/chainparams.cpp:154 |
P2SH (SCRIPT_ADDRESS) |
55 | 0x37 |
P |
src/kernel/chainparams.cpp:155 |
| WIF secret key | 183 | 0xb7 |
— | src/kernel/chainparams.cpp:156 |
| Bech32 HRP | — | — | btcp1… |
src/kernel/chainparams.cpp:160 |
2.3 HD Key Version Bytes
BIP32 standard (xpub / xprv):
| Type | Bytes (hex) | Base58 prefix | Source |
|---|---|---|---|
| xpub | 0488B21E |
xpub |
src/kernel/chainparams.cpp:157 |
| xprv | 0488ADE4 |
xprv |
src/kernel/chainparams.cpp:158 |
SLIP-0132 extended headers (all script types):
BTCP uses the same BIP32 root bytes as Bitcoin mainnet, so the registered
SLIP-0132 SegWit version bytes are identical to Bitcoin mainnet. Taproot/BIP86
does not have registered SLIP-0132 trub / trpv headers; use standard
xpub / xprv plus the BIP86 derivation path or descriptors.
XPRV_HEADERS = {
'standard': 0x0488ade4, # xprv
'p2wpkh-p2sh': 0x049d7878, # yprv
'p2wsh-p2sh': 0x0295b005, # Yprv
'p2wpkh': 0x04b2430c, # zprv
'p2wsh': 0x02aa7a99, # Zprv
}
XPUB_HEADERS = {
'standard': 0x0488b21e, # xpub
'p2wpkh-p2sh': 0x049d7cb2, # ypub
'p2wsh-p2sh': 0x0295b43f, # Ypub
'p2wpkh': 0x04b24746, # zpub
'p2wsh': 0x02aa7ed3, # Zpub
}
2.4 Magic Bytes (P2P message header)
fc 99 13 95 — Source: src/kernel/chainparams.cpp:112-115
2.5 Genesis Block
| Parameter | Value | Source |
|---|---|---|
| Hash (display) | 000003823fbf82ea4906cbe214617ce7a70a5da29c19ecb1d65618bcf04ec015 |
src/kernel/chainparams.cpp:144 |
| LN chain_hash (wire, reversed bytes) | 15c04ef0bc1856d6b1ec199ca25d0aa7e77c6114e2cb0649ea82bf3f82030000 |
derived |
| Merkle root | b5f46757618a0aa2961b23f51de039ef23a77c24decc43d600348aff051f0a05 |
src/kernel/chainparams.cpp:145 |
| Timestamp (Unix) | 1691126832 |
src/kernel/chainparams.cpp:121 |
| Timestamp (UTC) | 2023-08-04T05:27:12Z |
— |
| Nonce | 1302816 (0x13E120) |
src/kernel/chainparams.cpp:121 |
| nBits | 1e0ffff0 |
src/kernel/chainparams.cpp:121 |
| Version | 1 |
src/kernel/chainparams.cpp:121 |
| Coinbase message | "Global transactions for everyone around the world" |
src/kernel/chainparams.cpp:64 |
| Coinbase pubkey | 04f26c8111029cf40de900c7075706cb58e5ed1e7f1d4911790019ee8c345eeb84060b1a09fb655c88e58ff35357ffe28678e62008f759ea260c7c37c9fae23869 |
src/kernel/chainparams.cpp:65 |
2.6 Consensus & Emission
| Parameter | Value | Source |
|---|---|---|
Block time (nPowTargetSpacing) |
60 seconds | src/kernel/chainparams.cpp:88 |
| Difficulty retarget window | 120 blocks (~2 hours) | src/kernel/chainparams.cpp:87-88 |
| PoW target timespan | 7200 seconds | src/kernel/chainparams.cpp:87 |
| PoW limit | 00000fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff |
src/kernel/chainparams.cpp:86 |
| Halving interval | 500,000 blocks | src/kernel/chainparams.cpp:78 |
| Initial block reward | 1 BTCP | src/validation.cpp:1549 |
| COIN (satoshis per BTCP) | 100,000,000 | src/consensus/amount.h:16 |
| MAX_MONEY validation cap | 1,000,000 BTCP | src/consensus/amount.h:27 |
| Coinbase maturity | 100 blocks | src/consensus/consensus.h:19 |
| Rule change activation threshold | 108 / 120 blocks (90%) | src/kernel/chainparams.cpp:91 |
Block reward schedule (source: src/validation.cpp:1542-1551):
| Era | Block range | Reward | Era total |
|---|---|---|---|
| 0 | 0 – 499,999 | 1.00000000 BTCP | 500,000 BTCP |
| 1 | 500,000 – 999,999 | 0.50000000 BTCP | 250,000 BTCP |
| 2 | 1,000,000 – 1,499,999 | 0.25000000 BTCP | 125,000 BTCP |
| 3 | 1,500,000 – 1,999,999 | 0.12500000 BTCP | 62,500 BTCP |
| ∞ | — | — | ~1,000,000 BTCP generated subsidy |
MAX_MONEY is the consensus money-range sanity cap, not a direct UTXO supply
counter. The genesis coinbase follows the normal 1 BTCP subsidy construction,
but like Bitcoin Core-derived chains it is not spendable from the UTXO set.
For user-facing supply text, distinguish:
- Maximum generated subsidy: asymptotically ~1,000,000 BTCP.
- Maximum spendable subsidy: asymptotically ~999,999 BTCP if the genesis coinbase remains unspendable.
2.7 Difficulty Adjustment
BTCP keeps Bitcoin's compact target / SHA256d proof-of-work validation, but the retarget interval is much shorter:
| Parameter | Mainnet value | Source |
|---|---|---|
| Target spacing | 60 seconds | src/kernel/chainparams.cpp:88 |
| Target timespan | 7,200 seconds | src/kernel/chainparams.cpp:87 |
| Adjustment interval | 120 blocks | nPowTargetTimespan / nPowTargetSpacing |
| Retarget boundary | every block height divisible by 120 | src/pow.cpp:18-47 |
| Minimum actual timespan | 1,800 seconds | src/pow.cpp:56 |
| Maximum actual timespan | 28,800 seconds | src/pow.cpp:58 |
| Max change per retarget | 4x easier or 4x harder | src/pow.cpp:56-66 |
| Mainnet min-difficulty blocks | disabled | fPowAllowMinDifficultyBlocks=false |
| No-retarget mode | disabled | fPowNoRetargeting=false |
Retarget flow for a candidate block at height H:
- If
H % 120 != 0, the block must keep the previous block'snBits. - If
H % 120 == 0, take the previous 120-block window:first = H - 120,last = H - 1. - Compute
actual_timespan = last.time - first.time. - Clamp it to
[7200 / 4, 7200 * 4], i.e.[1800, 28800]seconds. - Decode previous
nBitsto a target, then:
new_target = old_target * actual_timespan / 7200
new_target = min(new_target, powLimit)
new_nBits = compact(new_target)
Interpretation:
- Blocks faster than 60 seconds make
actual_timespan < 7200, so target decreases and difficulty increases. - Blocks slower than 60 seconds make
actual_timespan > 7200, so target increases and difficulty decreases. - The clamp prevents a single retarget from changing difficulty by more than 4x.
2.8 Soft-Fork Activation
All soft-forks are active from genesis (height 0). Source: src/kernel/chainparams.cpp:79-102
| BIP | Feature | Activation height |
|---|---|---|
| BIP34 | Block height in coinbase | 0 |
| BIP65 | CHECKLOCKTIMEVERIFY |
0 |
| BIP66 | Strict DER signatures | 0 |
| BIP68/112/113 | CheckSequenceVerify (CSV) |
0 |
| BIP141/143/147 | SegWit | 0 |
| BIP340-342 | Taproot (ALWAYS_ACTIVE) |
0 |
2.9 Chain Validation
| Parameter | Value | Source |
|---|---|---|
| Minimum chain work | 00000000000000000000000000000000000000000000074e7000dc41ac550926 |
src/kernel/chainparams.cpp:104 |
| Default assume valid | 00000000000009733cf805e87e19261ae833319b874c694d4d74995ea526c968 |
src/kernel/chainparams.cpp:105 |
| Prune after height | 100,000 | src/kernel/chainparams.cpp:117 |
| TX count reference | 1,189,400 at block 1,048,808 | src/kernel/chainparams.cpp:178-184 |
2.10 DNS Seeds
| Seed | Source |
|---|---|
node3.walletbuilders.com |
src/kernel/chainparams.cpp:152 |
3. Testnet Parameters
| Parameter | Value | Source |
|---|---|---|
| P2P port | 23496 |
src/kernel/chainparams.cpp:230 |
| RPC port | 23495 |
src/chainparamsbase.cpp:49 |
| Magic bytes | 29 fb c5 fe |
src/kernel/chainparams.cpp:226-229 |
| Bech32 / BOLT11 HRP | tbtcp |
src/kernel/chainparams.cpp:270 |
| P2PKH | 56 (0x38) |
src/kernel/chainparams.cpp:264 |
| P2SH | 55 (0x37) |
src/kernel/chainparams.cpp:265 |
| WIF prefix | 183 (0xb7) |
src/kernel/chainparams.cpp:266 |
| BIP32 xpub | 043587CF |
src/kernel/chainparams.cpp:267 |
| BIP32 xprv | 04358394 |
src/kernel/chainparams.cpp:268 |
| Genesis hash (display) | 000002fdc3921c1ad368816fcc587f499698d42b42ab5a5d94ee67882ef9d998 |
src/kernel/chainparams.cpp:259 |
| LN chain_hash (wire) | 98d9f92e8867ee945d5aab422bd49896497f58cc6f8168d31a1c92c3fd020000 |
derived |
| Genesis merkle root | b5f46757618a0aa2961b23f51de039ef23a77c24decc43d600348aff051f0a05 |
same as mainnet |
| Genesis timestamp | 1691126837 |
src/kernel/chainparams.cpp:235 |
| Genesis nonce | 521609 (0x7F589) |
src/kernel/chainparams.cpp:235 |
| Genesis nBits | 1e0ffff0 |
src/kernel/chainparams.cpp:235 |
| ElectrumX TCP / SSL | 60001 / 60002 |
coins_btcp.py |
SLIP-0132 HD headers — testnet (identical to Bitcoin testnet, since BIP32 bytes are 043587CF/04358394; Taproot/BIP86 still uses standard tpub / tprv plus path/descriptor metadata):
XPRV_HEADERS = {
'standard': 0x04358394, # tprv
'p2wpkh-p2sh': 0x044a4e28, # uprv
'p2wsh-p2sh': 0x024285b5, # Uprv
'p2wpkh': 0x045f18bc, # vprv
'p2wsh': 0x02575048, # Vprv
}
XPUB_HEADERS = {
'standard': 0x043587cf, # tpub
'p2wpkh-p2sh': 0x044a5262, # upub
'p2wsh-p2sh': 0x024289ef, # Upub
'p2wpkh': 0x045f1cf6, # vpub
'p2wsh': 0x02575483, # Vpub
}
4. Signet Parameters
| Parameter | Value | Source |
|---|---|---|
| P2P port | 33496 |
src/kernel/chainparams.cpp:375 |
| RPC port | 33495 |
src/chainparamsbase.cpp:51 |
| Bech32 HRP | tbtcp |
src/kernel/chainparams.cpp:412 |
| P2PKH / P2SH / WIF | 56 / 55 / 183 | src/kernel/chainparams.cpp:406-408 |
| BIP32 xpub / xprv | 043587CF / 04358394 |
src/kernel/chainparams.cpp:409-410 |
| Genesis hash | 00000131aa3124412b7ba8473f137922692c88da8fe26042e250c6cd76b7b403 |
src/kernel/chainparams.cpp:402 |
| Genesis timestamp | 1691126842 |
src/kernel/chainparams.cpp:378 |
| Genesis nonce | 1829993 (0x1be0a9) |
src/kernel/chainparams.cpp:378 |
| Genesis nBits | 1e0377ae |
src/kernel/chainparams.cpp:378 |
| PoW limit | 00000377ae000000000000000000000000000000000000000000000000000000 |
src/kernel/chainparams.cpp:350 |
| Default signet challenge | 512103ad5e0edad18cb1f0fc0d28a3d4f1f3e445640337489abb10404f2d1e086be430210359ef5021964fe22d6f8e05b2463c9540ce96883fe3b278760f048f5189f2e6c452ae |
src/kernel/chainparams.cpp:308 |
5. Regtest Parameters
| Parameter | Value | Source |
|---|---|---|
| P2P port | 18444 |
src/kernel/chainparams.cpp:466 |
| RPC port | 18443 |
src/chainparamsbase.cpp:53 |
| Magic bytes | 31 34 6a c9 |
src/kernel/chainparams.cpp:462-465 |
| Bech32 HRP | rbtcp |
src/kernel/chainparams.cpp:556 |
| P2PKH / P2SH / WIF | 56 / 55 / 183 | src/kernel/chainparams.cpp:550-552 |
| BIP32 xpub / xprv | 043587CF / 04358394 |
src/kernel/chainparams.cpp:553-554 |
| Genesis hash | 6f6ffbda4cb789c69d885d4624ea4a28841d3689fbaf969262150ca45a1ae1df |
src/kernel/chainparams.cpp:521 |
| Genesis timestamp | 1691126837 |
src/kernel/chainparams.cpp:497 |
| Genesis nonce | 4 |
src/kernel/chainparams.cpp:497 |
| Genesis nBits | 207fffff |
src/kernel/chainparams.cpp:497 |
| Halving interval | 150 blocks | src/kernel/chainparams.cpp:433 |
| No retargeting | true |
src/kernel/chainparams.cpp:440 |
6. ElectrumX Server
6.1 Coin Definition (coins_btcp.py)
Drop-in patch for electrumx/lib/coins.py. Place as
electrumx-patch/coins_btcp.py and apply via the Docker patch snippet below.
# coins_btcp.py — BitcoinPurple (BTCP) coin definitions for ElectrumX
# Patch into electrumx/lib/coins.py alongside the Bitcoin class.
class BitcoinPurple(Bitcoin):
NAME = 'BitcoinPurple'
SHORTNAME = 'BTCP'
NET = 'mainnet'
DESERIALIZER = lib_tx.DeserializerSegWit
GENESIS_HASH = (
'000003823fbf82ea4906cbe214617ce7a70a5da29c19ecb1d65618bcf04ec015'
)
# Base58 address prefixes
P2PKH_VERBYTE = bytes([56]) # 0x38
P2SH_VERBYTES = (bytes([55]),) # 0x37
WIF_BYTE = bytes([183]) # 0xb7
# BIP32 HD key version bytes
XPUB_VERBYTES = bytes.fromhex('0488B21E')
XPRV_VERBYTES = bytes.fromhex('0488ADE4')
# Bech32 / SegWit metadata for forks; ElectrumX indexes scripts directly.
SEGWIT_HRP = 'btcp'
# Do not inherit Bitcoin Electrum peers or Bitcoin Core version gates.
PEERS = []
MIN_REQUIRED_DAEMON_VERSION = '1.1.1'
BLACKLIST_URL = None
# 1-minute blocks: keep enough undo data for practical reorg handling.
REORG_LIMIT = 1200
# Chain stats — updated from fully synced mainnet node at block 1,048,808 (Apr 2026)
TX_COUNT = 1_189_400
TX_COUNT_HEIGHT = 1_048_808
TX_PER_BLOCK = 2
# RPC port (bitcoinpurpled mainnet default)
RPC_PORT = 13495
PEER_DEFAULT_PORTS = {'t': '50001', 's': '50002'}
class BitcoinPurpleTestnet(BitcoinPurple):
NAME = 'BitcoinPurple Testnet'
SHORTNAME = 'TBTCP'
NET = 'testnet'
GENESIS_HASH = (
'000002fdc3921c1ad368816fcc587f499698d42b42ab5a5d94ee67882ef9d998'
)
XPUB_VERBYTES = bytes.fromhex('043587CF')
XPRV_VERBYTES = bytes.fromhex('04358394')
SEGWIT_HRP = 'tbtcp'
TX_COUNT = 1
TX_COUNT_HEIGHT = 0
TX_PER_BLOCK = 1
RPC_PORT = 23495
PEERS = []
REORG_LIMIT = 1200
PEER_DEFAULT_PORTS = {'t': '60001', 's': '60002'}
Notes for this coin class:
PEERS = []is intentional until there are known-good BTCP ElectrumX peers. ElectrumX peer discovery verifies genesis, but inheriting Bitcoin peers wastes resources and can leak confusing peer data.MIN_REQUIRED_DAEMON_VERSIONmust not inherit Bitcoin's current upstream requirement. Keep it aligned with the BTCP daemon version you ship, or remove the version gate in your ElectrumX fork.TX_COUNT,TX_COUNT_HEIGHT, andTX_PER_BLOCKare sync-estimation hints, not consensus values. Refresh them from a synced BTCP node before release.- ElectrumX does not need ZMQ to index; it polls RPC. ZMQ is useful for lower latency only if your chosen ElectrumX build/plugin uses it.
6.1.1 ElectrumX Node Requirements
Required full-node settings:
| Requirement | Value / setting | Reason |
|---|---|---|
| RPC server | server=1, rpcport=13495 |
ElectrumX reads blocks and transactions through JSON-RPC |
| Transaction index | txindex=1 |
Required for historical transaction lookups |
| Pruning | disabled (prune=0) |
ElectrumX must be able to index from genesis |
| Chain | mainnet unless NET=testnet |
Must match COIN/NET in ElectrumX |
| Disk | full block data + ElectrumX DB | DB grows with history; do not run from a tiny volume |
Minimum RPC methods used by ElectrumX-compatible servers include
getblockhash, getblock, getrawtransaction, getnetworkinfo,
getblockchaininfo, estimatesmartfee, and sendrawtransaction.
Recommended public Electrum services:
| Service | Mainnet | Testnet | Notes |
|---|---|---|---|
| Plain TCP | 50001 |
60001 |
Standard Electrum convention |
| TLS/SSL TCP | 50002 |
60002 |
Recommended for public wallets |
| Local admin RPC | 8000 |
8000 or private |
Keep firewalled; do not advertise publicly |
For servers.json, replace your-server.example.com with a real DNS name or
public IP. The current file only documents the format; it does not configure a
real public server.
6.2 Docker Patch Snippet
COPY electrumx-patch/coins_btcp.py /tmp/coins_btcp.py
RUN python3 - <<'PATCH'
import pathlib, re
patch = pathlib.Path('/tmp/coins_btcp.py').read_text()
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)
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 BitcoinPurple(Bitcoin):' not in s:
p.write_text(s + body)
print('>> Patched ElectrumX with BitcoinPurple coin classes')
PATCH
6.3 Environment Variables
# ── Identity ──────────────────────────────────────────────────────────────────
COIN=BitcoinPurple
NET=mainnet # or: testnet
# ── Node connection ───────────────────────────────────────────────────────────
DAEMON_URL=http://btcpuser:CHANGE_ME@bitcoinpurpled:13495/
# testnet: DAEMON_URL=http://btcpuser:CHANGE_ME@bitcoinpurpled:23495/
# ── Storage ───────────────────────────────────────────────────────────────────
DB_DIRECTORY=/data/electrumx
# ── Services exposed ──────────────────────────────────────────────────────────
SERVICES=tcp://0.0.0.0:50001,ssl://0.0.0.0:50002,rpc://0.0.0.0:8000
# Override only if auto-detected public IP is wrong:
# REPORT_SERVICES=tcp://your-server-ip:50001,ssl://your-server-ip:50002
# ── TLS ───────────────────────────────────────────────────────────────────────
SSL_CERTFILE=/certs/server.crt
SSL_KEYFILE=/certs/server.key
# ── Performance ───────────────────────────────────────────────────────────────
CACHE_MB=1200
MAX_SESSIONS=1000
INITIAL_CONCURRENT=2
# ── Rate limiting (0 = disabled) ─────────────────────────────────────────────
COST_SOFT_LIMIT=0
COST_HARD_LIMIT=0
# ── Peer discovery ────────────────────────────────────────────────────────────
PEER_DISCOVERY=on
PEER_ANNOUNCE=true
Protocol version served: 1.4.2
OS ulimit — set nofile to at least 1048576 (open file descriptors):
ulimits:
nofile:
soft: 1048576
hard: 1048576
6.4 ZMQ Notification Ports
These are recommended local ports if you enable ZMQ notifications. BitcoinPurple
Core does not assign default ZMQ bind ports; the port only exists if you set the
corresponding bitcoinpurple.conf value.
bitcoinpurple.conf key |
Recommended local port | Payload |
|---|---|---|
zmqpubrawblock |
28332 |
full serialised block |
zmqpubrawtx |
28333 |
raw transaction (mempool + confirmed) |
zmqpubhashblock |
28334 |
32-byte block hash |
zmqpubhashtx |
28335 |
32-byte tx hash |
Prevent dropped messages under load:
zmqpubrawblockhwm=500
zmqpubrawtxhwm=500
7. Electrum Wallet (constants.py)
Reference for building an Electrum wallet fork targeting BTCP.
Modelled after the AbstractNet interface (see pallectrum for a working example).
7.1 Parameter Table
| Field | Mainnet | Testnet | Source / Note |
|---|---|---|---|
NET_NAME |
"bitcoinpurple" |
"testnet" |
wallet data subfolder |
TESTNET |
False |
True |
|
WIF_PREFIX |
0xb7 (183) |
0xb7 (183) |
same on both — chainparams.cpp:156/266 |
ADDRTYPE_P2PKH |
56 |
56 |
addresses start with P |
ADDRTYPE_P2SH |
55 |
55 |
addresses start with P |
SEGWIT_HRP |
"btcp" |
"tbtcp" |
Bech32 human-readable part |
BOLT11_HRP |
"btcp" |
"tbtcp" |
LN invoice prefix |
GENESIS |
000003823f…c015 |
000002fdc3…d998 |
full hashes in §2.5 / §3 |
DEFAULT_PORTS |
{'t':'50001','s':'50002'} |
{'t':'60001','s':'60002'} |
|
BIP44_COIN_TYPE |
13496 (provisional — not SLIP-0044 registered) |
1 |
matches BTCP P2P port; update when registered |
LN_REALM_BYTE |
0 |
1 |
LN DNS realm byte; unused while LN_DNS_SEEDS=[] |
LN_DNS_SEEDS |
[] |
[] |
no LN seeds configured |
SKIP_POW_DIFFICULTY_VALIDATION |
False only after BTCP retarget support |
False only after BTCP retarget support |
see §7.7 |
POW_TARGET_SPACING |
60 |
60 |
seconds per block |
COINBASE_MATURITY |
100 |
100 |
blocks before coinbase is spendable |
BLOCK_HEIGHT_FIRST_LIGHTNING_CHANNELS |
0 |
0 |
allowed from genesis if LN is enabled |
BIP44 coin type: BitcoinPurple has no SLIP-0044 entry.
BTCPat index183is already assigned to Bitcoin Private, so do not reuse it for BitcoinPurple. In Electrum constants, store the non-hardened index (0 <= value < 0x80000000); wallet derivation code adds the hardened bit when building paths such asm/44'/COIN_TYPE'/0'. Use one project-wide provisional integer until an official SLIP-0044 slot is registered. The13496value below is a project-local placeholder chosen to match the BTCP P2P port, not a registered SLIP-0044 value.
7.2 constants.py Class Definitions
# constants.py — BitcoinPurple network definitions for an Electrum wallet fork
# Drop these classes into electrum/constants.py alongside BitcoinMainnet.
class BitcoinPurple(AbstractNet):
NET_NAME = "bitcoinpurple"
TESTNET = False
# Address & key encoding
WIF_PREFIX = 0xb7 # 183 — chainparams.cpp:156
ADDRTYPE_P2PKH = 56 # 0x38 — chainparams.cpp:154
ADDRTYPE_P2SH = 55 # 0x37 — chainparams.cpp:155
SEGWIT_HRP = "btcp" # chainparams.cpp:160
BOLT11_HRP = SEGWIT_HRP
GENESIS = "000003823fbf82ea4906cbe214617ce7a70a5da29c19ecb1d65618bcf04ec015"
DEFAULT_PORTS = {'t': '50001', 's': '50002'}
# Consensus
COINBASE_MATURITY = 100 # consensus/consensus.h:19
POW_TARGET_SPACING = 60 # 60-second blocks
# BIP44 coin type — not registered in SLIP-0044
BIP44_COIN_TYPE = 13496 # provisional private constant; update when registered
# Lightning. Height 0 means "allowed from genesis" in Electrum.
BLOCK_HEIGHT_FIRST_LIGHTNING_CHANNELS = 0
LN_REALM_BYTE = 0
LN_DNS_SEEDS = []
# PoW validation — requires BTCP's 120-block retarget implementation.
SKIP_POW_DIFFICULTY_VALIDATION = False
# SLIP-0132 HD key version bytes — identical to Bitcoin mainnet
# BTCP mainnet uses the same BIP32 root bytes: 0488B21E / 0488ADE4
XPRV_HEADERS = {
'standard': 0x0488ade4, # xprv
'p2wpkh-p2sh': 0x049d7878, # yprv
'p2wsh-p2sh': 0x0295b005, # Yprv
'p2wpkh': 0x04b2430c, # zprv
'p2wsh': 0x02aa7a99, # Zprv
}
XPRV_HEADERS_INV = inv_dict(XPRV_HEADERS)
XPUB_HEADERS = {
'standard': 0x0488b21e, # xpub
'p2wpkh-p2sh': 0x049d7cb2, # ypub
'p2wsh-p2sh': 0x0295b43f, # Ypub
'p2wpkh': 0x04b24746, # zpub
'p2wsh': 0x02aa7ed3, # Zpub
}
XPUB_HEADERS_INV = inv_dict(XPUB_HEADERS)
class BitcoinPurpleTestnet(BitcoinPurple):
NET_NAME = "testnet"
TESTNET = True
# Testnet uses the same address/WIF prefixes as mainnet (see chainparams)
WIF_PREFIX = 0xb7 # chainparams.cpp:266
ADDRTYPE_P2PKH = 56 # chainparams.cpp:264
ADDRTYPE_P2SH = 55 # chainparams.cpp:265
SEGWIT_HRP = "tbtcp" # chainparams.cpp:270
BOLT11_HRP = SEGWIT_HRP
GENESIS = "000002fdc3921c1ad368816fcc587f499698d42b42ab5a5d94ee67882ef9d998"
DEFAULT_PORTS = {'t': '60001', 's': '60002'}
BIP44_COIN_TYPE = 1 # standard testnet coin type
LN_REALM_BYTE = 1
# SLIP-0132 — standard Bitcoin testnet values (BIP32 root: 043587CF / 04358394)
XPRV_HEADERS = {
'standard': 0x04358394, # tprv
'p2wpkh-p2sh': 0x044a4e28, # uprv
'p2wsh-p2sh': 0x024285b5, # Uprv
'p2wpkh': 0x045f18bc, # vprv
'p2wsh': 0x02575048, # Vprv
}
XPRV_HEADERS_INV = inv_dict(XPRV_HEADERS)
XPUB_HEADERS = {
'standard': 0x043587cf, # tpub
'p2wpkh-p2sh': 0x044a5262, # upub
'p2wsh-p2sh': 0x024289ef, # Upub
'p2wpkh': 0x045f1cf6, # vpub
'p2wsh': 0x02575483, # Vpub
}
XPUB_HEADERS_INV = inv_dict(XPUB_HEADERS)
7.3 Derivation Paths (BIP44 / 49 / 84 / 86)
Standard HD paths for each script type. Replace COIN_TYPE with the registered
value (TBD — see §7.1 note).
| BIP | Script type | Path template | xpub/xprv prefix |
|---|---|---|---|
| BIP44 | P2PKH (legacy) | m/44'/COIN_TYPE'/0'/0/n |
xpub / xprv |
| BIP49 | P2WPKH-P2SH (wrapped SegWit) | m/49'/COIN_TYPE'/0'/0/n |
ypub / yprv |
| BIP84 | P2WPKH (native SegWit) | m/84'/COIN_TYPE'/0'/0/n |
zpub / zprv |
| BIP86 | P2TR (Taproot) | m/86'/COIN_TYPE'/0'/0/n |
xpub / xprv or descriptors |
ACCOUNT=0'(first account, hardened)CHANGE=0(receive) or1(change)INDEX= address index (unhardened)
7.4 Checkpoints (checkpoints.json)
Electrum uses checkpoints for SPV header chain verification.
The file lives at electrum/chains/bitcoinpurple/checkpoints.json.
Format: a JSON array of [header_hash_hex, accumulated_work_int] pairs,
one entry per 2016-block chunk. Chunk n covers blocks n*2016 to (n+1)*2016-1.
[
[
"000003823fbf82ea4906cbe214617ce7a70a5da29c19ecb1d65618bcf04ec015",
1048592
]
]
The first entry (chunk 0) is the genesis block hash with its accumulated PoW work
(0x00000000000000000000000000000000000000000000074e7000dc41ac550926 — from nMinimumChainWork in chainparams.cpp:104, updated at block 1,048,808).
To generate a full checkpoints.json from a running node:
import json, subprocess, math
def get_header(height):
h = subprocess.check_output(
['bitcoinpurple-cli', 'getblockhash', str(height)]).decode().strip()
return subprocess.check_output(
['bitcoinpurple-cli', 'getblockheader', h, 'true']).decode()
checkpoints = []
tip = int(subprocess.check_output(
['bitcoinpurple-cli', 'getblockcount']).decode().strip())
for chunk in range(tip // 2016 + 1):
height = chunk * 2016
import json as _j
header = _j.loads(get_header(height))
checkpoints.append([header['hash'], int(header['chainwork'], 16)])
print(json.dumps(checkpoints, indent=2))
7.5 servers.json Format
Place at electrum/chains/bitcoinpurple/servers.json (mainnet)
and electrum/chains/testnet/servers.json (testnet).
{
"your-server.example.com": {
"pruning": "-",
"s": "50002",
"t": "50001",
"version": "1.4.2"
}
}
| Field | Meaning |
|---|---|
| key | hostname or IP of the ElectrumX server |
"pruning" |
"-" = full node; a number = pruned at that height |
"s" |
SSL port |
"t" |
TCP plain port |
"version" |
minimum Electrum protocol version required |
7.6 Dust Thresholds
Minimum output values below which an output is considered "dust" and non-standard. These are the same as Bitcoin since BTCP uses identical script formats.
| Script type | Dust limit | Policy fee rate |
|---|---|---|
| P2PKH | 546 sat | DUST_RELAY_TX_FEE = 3000 sat/kvB (src/policy/policy.h:55) |
| P2WPKH (native SegWit) | 294 sat | same |
| P2WSH | 330 sat | same |
| P2TR (Taproot) | 294 sat | same |
OP_RETURN |
0 (unspendable) | max 83 bytes (src/script/standard.h:34) |
7.7 Electrum Header Verification
Do not reuse Bitcoin's 2016-block difficulty verification logic unchanged. BTCP uses Bitcoin-style compact targets and double-SHA256 proof-of-work, but retargets every 120 blocks with a 7,200 second target timespan.
Wallet constants / chain-verifier values:
POW_LIMIT = int(
"00000fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", 16
)
TARGET_SPACING = 60
TARGET_TIMESPAN = 120 * 60
DIFFICULTY_ADJUSTMENT_INTERVAL = 120
MAX_ADJUSTMENT_FACTOR = 4
Header validation must perform:
- Verify
double_sha256(header) <= target_from_nbits(header.bits). - Verify target is
> 0and<= POW_LIMIT. - If
height % 120 != 0, requireheader.bits == previous.bits. - If
height % 120 == 0, compute expectedbitsfrom the previous 120-block window using the §2.7 formula. - Verify each header links to the previous header hash.
- Use
GENESISto anchor the chain andcheckpoints.jsonto accelerate SPV verification.
If the Electrum fork does not yet implement BTCP's 120-block retarget logic,
set SKIP_POW_DIFFICULTY_VALIDATION = True temporarily for development only.
Do not ship a production wallet with difficulty validation disabled.
7.8 Electrum Wallet Build Checklist
Files that must be added or changed in an Electrum fork:
| File / area | Required BTCP change |
|---|---|
electrum/constants.py |
Add BitcoinPurple and BitcoinPurpleTestnet classes |
electrum/chains/bitcoinpurple/servers.json |
Add real ElectrumX host(s), ports 50001 / 50002 |
electrum/chains/bitcoinpurple/checkpoints.json |
Generate from a synced BTCP node |
| header chain verifier | Use 120-block retarget and BTCP powLimit |
| address module | Accept Base58 versions 56/55 and Bech32 HRP btcp |
| transaction/wallet formats | Use BTCP provisional BIP44 coin type consistently |
| Lightning invoice parser | Accept lnbtcp / lntbtcp BOLT11 prefixes if LN is enabled |
| UI/network selector | Expose BitcoinPurple mainnet/testnet names and datadirs |
8. Lightning Network
This section documents the chain-specific parameters required to build or fork a Lightning Network implementation for BTCP. General BOLT protocol behaviour (onion routing, payment flow, gossip) is identical to Bitcoin LN.
8.1 Chain Identification
In BOLT1, every message that references a specific chain carries a chain_hash.
This is the genesis block hash in wire byte order (i.e. the display hex reversed byte-by-byte).
| Network | Genesis hash (display) | chain_hash (BOLT1 wire) |
|---|---|---|
| Mainnet | 000003823fbf82ea…c015 |
15c04ef0bc1856d6b1ec199ca25d0aa7e77c6114e2cb0649ea82bf3f82030000 |
| Testnet | 000002fdc3921c1a…d998 |
98d9f92e8867ee945d5aab422bd49896497f58cc6f8168d31a1c92c3fd020000 |
The chain_hash appears in channel-establishment, channel-gossip, and gossip-query
messages such as open_channel, accept_channel, funding_created,
channel_announcement, channel_update, query_channel_range, and
reply_channel_range. BOLT11 invoices do not normally carry chain_hash; their
network is selected by the invoice HRP.
8.2 BOLT11 Invoice Prefix
| Network | HRP | Example invoice start |
|---|---|---|
| Mainnet | btcp |
lnbtcp1… |
| Testnet | tbtcp |
lntbtcp1… |
Amount suffix multipliers (same as Bitcoin):
| Multiplier | Value |
|---|---|
m |
0.001 BTCP (100,000 sat) |
u |
0.000001 BTCP (100 sat) |
n |
0.000000001 BTCP (0.1 sat) |
p |
0.000000000001 BTCP (0.0001 sat) |
8.3 Block-Time-Scaled Timeout Parameters
This is the most critical section for LN on BTCP.
BTCP has 1-minute blocks (vs Bitcoin's 10-minute blocks). All LN timeout parameters expressed in blocks must be scaled by ×10 to achieve the same real-world security windows as Bitcoin LN. Failure to do this results in dangerously short penalty and payment expiry windows.
| Parameter | Source type | Bitcoin common default | BTCP recommended (1 min/block) | Real-world time |
|---|---|---|---|---|
to_self_delay (justice window) |
implementation policy | 144 blocks | 1440 blocks | ~24 hours |
cltv_expiry_delta per routing hop |
implementation policy / BOLT7 field | 40 blocks | 400 blocks | ~6.7 hours |
min_final_cltv_expiry_delta (last hop) |
implementation policy / BOLT11 field | 9 blocks | 90 blocks | ~90 minutes |
maximum remote to_self_delay accepted |
BOLT2 policy limit | 2016 blocks | 20160 blocks | ~14 days |
max_cltv_expiry (max payment timeout) |
implementation policy | 2016 blocks | 20160 blocks | ~14 days |
| Channel funding confirmation target | best practice | 3–6 blocks | 30–60 blocks | ~30–60 minutes |
Why this matters: if a remote party broadcasts a revoked commitment transaction, your node has until
to_self_delayblocks to publish the penalty transaction. With 1-min blocks and Bitcoin's default of 144, you would have only 2.4 hours. Using the recommended 1440 gives a full 24 hours — the same window as Bitcoin.
8.4 Channel Parameters
These match Bitcoin LN defaults and do not need to change for BTCP.
| Parameter | Value | Note |
|---|---|---|
dust_limit_satoshis |
354 sat (P2WPKH anchor) or 546 sat (legacy) | minimum output in commitment tx |
max_htlc_value_in_flight_msat |
0 (unlimited) or % of capacity | channel-operator choice |
max_accepted_htlcs |
483 | BOLT3 protocol maximum (script complexity limit) |
htlc_minimum_msat |
1 msat | minimum HTLC size |
channel_reserve_satoshis |
~1% of channel capacity (min 1000 sat) | reserves the counterparty cannot spend |
fee_base_msat |
1000 (1 sat) | routing fee base |
fee_proportional_millionths |
1 (0.0001%) | routing fee rate |
feerate_per_kw |
node-determined | initial commitment transaction fee rate |
8.5 Feature Bits (BOLT1 init)
LN feature bits are chain-agnostic; BTCP uses the same bit assignments as Bitcoin LN.
| Feature | Bit pair | Status |
|---|---|---|
var_onion_optin |
8/9 | mandatory |
option_static_remotekey |
12/13 | mandatory |
payment_secret |
14/15 | mandatory |
basic_mpp (multi-part payments) |
16/17 | optional |
option_anchors_zero_fee_htlc_tx |
22/23 | optional (preferred over legacy anchors) |
option_scid_alias |
46/47 | optional |
option_zero_conf |
50/51 | optional |
8.6 Shared Implementation Fork Notes
All major LN implementations (LND, CLN, Eclair, LDK) hardcode Bitcoin's chain hash. Forking any of them for BTCP requires at minimum:
- Replace the genesis hash / chain_hash constant with the BTCP value (§8.1)
- Replace the BOLT11 invoice HRP with
btcp(§8.2) - Update all block-count-based timeout defaults (§8.3)
- Point the Bitcoin RPC backend to
bitcoinpurpledon port13495 - Update the network / bech32 address validation to accept
btcp1…addresses
Also update any constants derived from Bitcoin's 10-minute block cadence: confirmation targets, fee-estimation targets, CLTV deltas, wallet rescan lookbacks, channel announcement depth policy, and watchtower/penalty windows.
8.7 Core Lightning (CLN) Fork Parameters
Core Lightning is Bitcoin-specific upstream. A BTCP fork needs a new chain
definition or equivalent patches wherever CLN selects bitcoin, testnet,
signet, or regtest.
| Area | BTCP mainnet value / action |
|---|---|
| Network name | add bitcoinpurple / btcp network selector |
| Chain hash | 15c04ef0bc1856d6b1ec199ca25d0aa7e77c6114e2cb0649ea82bf3f82030000 |
| On-chain RPC backend | bitcoinpurple-cli / bitcoinpurpled RPC on 127.0.0.1:13495 |
| Bech32 address HRP | btcp |
| BOLT11 HRP | btcp (lnbtcp...) |
| Native unit | 1 BTCP = 100,000,000 sat; 1 sat = 1,000 msat |
| Genesis display hash | 000003823fbf82ea4906cbe214617ce7a70a5da29c19ecb1d65618bcf04ec015 |
| P2P gossip chain filter | accept only BTCP chain_hash |
| Fee estimates | call BTCP daemon estimatesmartfee; scale targets for 1-minute blocks |
| Confirmation policy | use 30-60 blocks where you want Bitcoin-like 30-60 minute confidence |
| Timeout defaults | use §8.3 scaled block counts |
| DNS bootstrap | empty until BTCP LN seed infrastructure exists |
CLN does not require Bitcoin Core ZMQ or txindex=1 for normal operation; it
polls the backend over RPC. If CLN and ElectrumX share one bitcoinpurpled,
increase rpcworkqueue and monitor RPC latency.
8.8 LND Fork Parameters
LND uses btcsuite chain parameters and Bitcoin-specific network selection. A BTCP
fork needs equivalent new chaincfg / chain registry parameters.
| Area | BTCP mainnet value / action |
|---|---|
| Chain registry | add BitcoinPurple params instead of chaincfg.MainNetParams |
| RPC backend | bitcoind-style backend pointed to bitcoinpurpled:13495 |
| ZMQ raw block | bitcoind.zmqpubrawblock=tcp://127.0.0.1:28332 if using ZMQ |
| ZMQ raw tx | bitcoind.zmqpubrawtx=tcp://127.0.0.1:28333 if using ZMQ |
| Address params | P2PKH 56, P2SH 55, Bech32 btcp, WIF 183 |
| Chain hash | same §8.1 wire value |
| Invoice HRP | btcp |
| Coin type | use the same provisional Electrum value until SLIP-0044 registration |
| Timeout defaults | use §8.3 scaled block counts |
| Fee estimator | ensure targets are interpreted as 1-minute BTCP blocks |
Unlike ElectrumX, LND normally benefits from ZMQ for prompt block/transaction notifications. If ZMQ is omitted, use the implementation's RPC polling mode and expect higher latency.
8.9 Lightning Difficulty / Block Cadence Implications
LN implementations do not recalculate proof-of-work difficulty themselves for
normal operation; the full node validates blocks. The LN daemon consumes validated
block headers/blocks from bitcoinpurpled and uses block heights for timeouts.
What must still be changed in LN code:
- Treat one BTCP block as ~60 seconds when converting user-facing time windows to block counts.
- Use BTCP's
chain_hasheverywhere gossip or channel messages identify a chain. - Use BTCP's address and BOLT11 HRPs for invoices, fallback addresses, and on-chain outputs.
- Do not connect to Bitcoin LN peers or DNS seeds; BTCP LN needs its own network graph and bootstrap peers.
9. bitcoinpurple.conf Reference
9.1 Default Values
| Parameter | Default | Source |
|---|---|---|
dbcache |
450 MiB | src/txdb.h:30 |
maxmempool |
300 MB | src/kernel/mempool_options.h:20 |
mempoolexpiry |
336 h (14 days) | src/kernel/mempool_options.h:24 |
blockmaxweight |
3,996,000 wu | src/policy/policy.h:23 |
rpcthreads |
4 | src/httpserver.h:12 |
rpcworkqueue |
16 | src/httpserver.h:13 |
rpcservertimeout |
30 s | src/httpserver.h:14 |
maxconnections |
125 | src/net.h |
9.2 Full Annotated Config
##############################################################################
# bitcoinpurple.conf — full node + solo mining + ElectrumX backend
# Location: ~/.bitcoinpurple/bitcoinpurple.conf
##############################################################################
# ── Network ──────────────────────────────────────────────────────────────────
# mainnet by default; uncomment for testnet
#testnet=1
listen=1
maxconnections=125
# addnode=node3.walletbuilders.com
# ── Chain & Indexes ───────────────────────────────────────────────────────────
# txindex=1 is REQUIRED by ElectrumX — incompatible with prune
txindex=1
# blockfilterindex=1 # optional: BIP157/158 compact filters for light clients
# prune=0 # never prune when txindex=1
# ── Performance ───────────────────────────────────────────────────────────────
dbcache=450 # MiB (default: 450; raise on high-RAM machines)
maxmempool=300 # MB (default: 300)
mempoolexpiry=336 # hours before unconfirmed txs are evicted (default: 336 = 14 days)
# ── RPC Server (required by ElectrumX) ───────────────────────────────────────
server=1
rpcport=13495
rpcbind=127.0.0.1
rpcallowip=127.0.0.1 # set to container subnet when ElectrumX is in Docker
rpcuser=btcpuser
rpcpassword=CHANGE_ME_USE_STRONG_PASSWORD
rpcthreads=4
rpcworkqueue=64 # raised from default 16 for ElectrumX parallel RPC calls
rpcservertimeout=30
# ── ZMQ Notifications (optional real-time updates) ───────────────────────────
zmqpubrawblock=tcp://127.0.0.1:28332
zmqpubrawtx=tcp://127.0.0.1:28333
zmqpubhashblock=tcp://127.0.0.1:28334
zmqpubhashtx=tcp://127.0.0.1:28335
zmqpubrawblockhwm=500
zmqpubrawtxhwm=500
zmqpubhashblockhwm=500
zmqpubhashtxhwm=500
# ── Mining ────────────────────────────────────────────────────────────────────
# MAX_BLOCK_WEIGHT = 4,000,000 wu (consensus/consensus.h:15)
blockmaxweight=3996000
blockmintxfee=0.00001
# blocknotify=/usr/local/bin/notify_new_block.sh %s
# ── Wallet (disable if mining to an external address via getblocktemplate) ───
# disablewallet=1
9.3 Notes
txindex=1andpruneare mutually exclusive. ElectrumX requirestxindex=1.- ZMQ requires
--enable-zmqat build time. Verify:bitcoinpurple-cli getnetworkinfo | grep zmq. ElectrumX can index through RPC polling; LND-style backends usually use ZMQ for low-latency block/tx notifications. - Solo mining via
getblocktemplate(BIP22): point your miner tohttp://btcpuser:CHANGE_ME@127.0.0.1:13495. - Docker networking: set
rpcallowipto the container subnet (e.g.172.17.0.0/16) when ElectrumX runs in a separate container. - LN node: the LN daemon also connects to
bitcoinpurpledvia RPC. Setrpcworkqueuehigh enough (128+) if both ElectrumX and an LN node share the same node instance.
9.4 Minimal ElectrumX env (standalone / non-Docker)
COIN=BitcoinPurple
NET=mainnet
DAEMON_URL=http://btcpuser:CHANGE_ME@127.0.0.1:13495/
DB_DIRECTORY=/data/electrumx
SERVICES=tcp://0.0.0.0:50001,ssl://0.0.0.0:50002,rpc://0.0.0.0:8000
REPORT_SERVICES=tcp://YOUR_PUBLIC_IP:50001,ssl://YOUR_PUBLIC_IP:50002
SSL_CERTFILE=/certs/server.crt
SSL_KEYFILE=/certs/server.key
CACHE_MB=1200
MAX_SESSIONS=1000
INITIAL_CONCURRENT=2
COST_SOFT_LIMIT=0
COST_HARD_LIMIT=0
PEER_DISCOVERY=on
PEER_ANNOUNCE=true