Documents BTCP-specific PoW constants, the dual-path verify_chunk logic, POW_GENESIS_BITS rationale, retarget clamping formula, relevant file paths, run/test commands, and LN block-scaled timeout guidance
7.0 KiB
CLAUDE.md
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
Overview
Electrum is a lightweight Bitcoin wallet with full Lightning Network support. It communicates with Electrum servers (not full nodes) via the Electrum protocol, and can run as a daemon with GUI/CLI clients or as an embedded library.
Development Commands
Install for development:
python3 -m pip install --user -e .
Run from source:
./run_electrum
Run all tests:
pytest tests -v
Run a single test file or test:
pytest tests/test_bitcoin.py -v
pytest tests/test_bitcoin.py::TestBitcoin::test_address -v
Run tests in parallel:
pytest tests -v -n auto
Build translations (requires gettext):
./contrib/locale/build_locale.sh electrum/locale/locale electrum/locale/locale
Python >= 3.10.0 is required. Key optional dependencies are in contrib/requirements/.
High-Level Architecture
Entry and Routing
run_electrum is the single entry point. It parses config/CLI args and routes to one of three modes:
- GUI mode — starts a Qt, QML, text, or stdio interface
- Daemon mode — runs a background process that manages wallets and network, exposing an RPC socket
- Command mode — sends an RPC command to a running daemon (or runs offline)
The daemon is the central hub: it owns the Network instance, loads wallets, and services all clients.
Core Module Responsibilities
| Module | Role |
|---|---|
wallet.py |
Wallet logic: coin selection, address management, signing, history. Hierarchy: Abstract_Wallet → Deterministic_Wallet → Standard_Wallet / Multisig_Wallet; also Imported_Wallet |
keystore.py |
Key material: HD derivation, hardware wallet abstraction, signing |
transaction.py |
Transaction and PartialTransaction (PSBT) construction and parsing |
network.py |
Manages the pool of server connections, subscriptions, request dispatching |
interface.py |
Single Electrum-protocol TCP/SSL connection to one server |
blockchain.py |
Header chain verification and tracking |
address_synchronizer.py |
Keeps UTXOs, history, and labels in sync with the network |
lnworker.py |
Lightning wallet logic (payments, channel management, routing) |
lnpeer.py |
Lightning peer connection (BOLT messaging) |
lnchannel.py |
Channel state machine |
daemon.py |
Daemon process and JSON-RPC server |
commands.py |
All CLI/RPC commands; also the authoritative list of public API calls |
simple_config.py |
User configuration; wraps file-backed and in-memory config |
storage.py / wallet_db.py |
Wallet file I/O with AES encryption and JSON serialization |
plugin.py |
Plugin loader and base classes |
bitcoin.py |
Address types, script helpers, encoding (Base58, Bech32m) |
chains/ |
Per-network constants (mainnet, testnet, regtest, signet) |
GUI Backends
electrum/gui/ contains four independent implementations:
qt/— full-featured desktop GUI (PyQt5/PyQt6)qml/— mobile GUI (Qt Quick / QML)text.py— curses terminal UIstdio.py— minimal stdio interface
Plugin System
electrum/plugins/ holds all optional features: hardware wallets (Ledger, Trezor, BitBox02, ColdCard, Jade, KeepKey, …), swap servers, watchtowers, label sync, audio modem, etc. Plugins register hooks that the core calls at defined points.
Async Model
Network and Lightning code is heavily async (asyncio). Background tasks run as coroutines managed by TaskGroup / MonitoredTaskGroup. GUI threads communicate with async tasks via aiohttp-style futures or Qt signals.
Testing Conventions
- Base class:
ElectrumTestCaseintests/__init__.py(extendsunittest.IsolatedAsyncioTestCase) - Testnet mode:
@as_testnetdecorator on test classes/methods - Implementation sweeps:
@needs_test_with_all_aes_implementations,@needs_test_with_all_chacha20_implementations FAST_TESTS = Trueskips slow implementation variants- Test vectors live alongside tests as JSON files (e.g.,
tests/test_vectors/)
BitcoinPurple (BTCP) Support
BitcoinPurple is a Bitcoin fork with 1-minute blocks and a shorter difficulty retarget window. The Electrum client has been extended to support it as a first-class network alongside mainnet and testnet.
Key Parameters (differ from Bitcoin)
| Constant | Bitcoin | BTCP |
|---|---|---|
DIFFICULTY_ADJUSTMENT_INTERVAL |
2016 blocks | 120 blocks |
POW_TARGET_TIMESPAN |
1,209,600 s | 7,200 s |
MAX_TARGET |
0x00000000ffff… (compact 0x1d00ffff) |
0x00000ffff… (compact 0x1e0fffff) |
POW_GENESIS_BITS |
None (derived from MAX_TARGET) |
0x1e0ffff0 (genesis nBits differ from powLimit) |
MAX_ADJUSTMENT_FACTOR |
4 | 4 |
POW_GENESIS_BITS is non-None for BTCP because the genesis block's nBits (0x1e0ffff0) is stricter than the powLimit compact (0x1e0fffff). get_target(-1) in blockchain.py returns bits_to_target(POW_GENESIS_BITS) when this is set, so period-0 header verification passes the exact equality check.
Retarget Clamping (BTCP only)
At each 120-block boundary:
actual_timespan = clamp(last.time - first.time, 1800, 28800) # [7200/4, 7200*4]
new_target = old_target * actual_timespan / 7200
new_target = min(new_target, MAX_TARGET)
Critical blockchain.py Logic
verify_chunk() has two paths:
adj_interval == CHUNK_SIZE(Bitcoin, 2016): reads old targets from on-disk headers.adj_interval < CHUNK_SIZE(BTCP, 120): retargets happen within a chunk, so headers are still in RAM (the buffer being verified). Uses an internal_read_hdr(data, i)helper to read from the buffer instead ofread_header().
Files
| Path | Purpose |
|---|---|
electrum/constants.py |
BitcoinPurple and BitcoinPurpleTestnet classes with all chain params |
electrum/blockchain.py |
verify_chunk, get_target, can_connect — all generalised for per-chain PoW constants |
electrum/chains/bitcoinpurple/servers.json |
Known ElectrumX servers (TCP 51001, SSL 51002) |
electrum/chains/bitcoinpurple/checkpoints.json |
SPV checkpoints (one entry = one 2016-block chunk) |
tests/test_bitcoinpurple.py |
46 BTCP-specific tests (address encoding, difficulty, header verification) |
tecnichal-data.md |
Complete BTCP parameter reference (ports, genesis, PoW, LN, ElectrumX) |
Running with BitcoinPurple
# Mainnet
./run_electrum --bitcoinpurple
# Testnet
./run_electrum --bitcoinpurple_testnet
# BitcoinPurple tests only
pytest tests/test_bitcoinpurple.py -v
# Blockchain + bitcoin + BitcoinPurple together
pytest tests/test_blockchain.py tests/test_bitcoin.py tests/test_bitcoinpurple.py -v
LN Block-Scaled Timeouts
BTCP has 1-minute blocks (10× faster than Bitcoin). All LN timeout values expressed in blocks must be scaled ×10 to preserve the same real-world security windows (e.g. to_self_delay 144 → 1440, cltv_expiry_delta 40 → 400). See tecnichal-data.md §8.3 for the full table.