Replace all user-visible "Bitcoin" and "Electrum" strings across Qt and QML
GUIs with "Bitcoin Purple" and "Electrum Purple" respectively. Update the
Help menu: replace the Bitcoin Paper link with the Bitcoin Purple whitepaper
and point the official website to bitcoinpurpleblockchain.com. Remove the
"Distributed by Electrum Technologies GmbH" attribution from the About dialog.
No code identifiers, class names or technical references were modified.
Large binary wheels (PyQt6 ~7-8 MB, cryptography ~3-4 MB) were timing out
with pip's default 15s socket timeout on slow connections, causing a
WinError 32 sharing violation on Wine temp files and an incomplete-download
error on Linux. Adding --timeout 120 to all pip install invocations in
both build-electrum-git.sh and make_appimage.sh fixes this
Adds BIP21_URI_SCHEME to AbstractNet (default 'bitcoin'), overridden
to 'btcp' in BitcoinPurple. All parse/create/scan paths now use
constants.net.BIP21_URI_SCHEME so QR codes with btcp:... URIs are
correctly recognised and generated on the Purple network.
Eliminates the startup dialog asking to enable update checks, the
background version check against electrum.org, the status bar button,
and the Help menu entry — all irrelevant for the Purple fork.
Replace hardcoded \"BTC\" with get_base_units_list()[0] so the top-level
unit name is resolved dynamically from chain constants (e.g. \"BTCP\" for
BitcoinPurple), preventing the UnknownBaseUnit exception on receive screen.
- Rename contrib/build-wine/electrum.nsi to electrum-purple.nsi
- Update PRODUCT_NAME from "Electrum" to "Electrum Purple"
- Update PRODUCT_WEB_SITE to https://github.com/DavideGrilli/electrum
- Update PRODUCT_PUBLISHER to "Electrum Purple"
- Update OutFile to dist/electrum-purple-setup.exe
- Update icon references to electrum-purple.ico
- Update exe references to electrum-purple-${PRODUCT_VERSION}.exe
- Update build-electrum-git.sh to reference new NSI filename
- Update NAME_ROOT to electrum-purple in build-electrum-git.sh
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
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.
SVG gradient stops updated directly; PNG files processed with a
+65° HSV hue rotation on blue-range pixels (185–245°, sat > 0.15),
preserving transparency, black, and white unchanged
Full run: pytest tests -v, Python 3.12.3, pytest 9.0.3, ~3:30 min.
Documents pass/skip counts per file, reasons for the 6 upstream-skipped tests,
BTCP-specific coverage, and flaky test fixes applied in this session.
SimpleConfig.path differs from electrum_path when the active network has a
subdirectory (e.g. BitcoinPurple mainnet). Tests that wrote directly to
electrum_path were resolving the wrong directory; use config.path consistently.
Also reorder setUp() so config is created before any path-dependent operations
- test_reestablish_fake_data: add 3-attempt retry per pay_invoice call to handle
asyncio event-loop pressure on sequential payments
- test_htlc_switch_iteration_benchmark: raise timeout 2s → 5s
- test_payment_multipart_trampoline_e2e: attempts 1 → 3
- _run_trampoline_payment: default attempts 2 → 5; add outer retry loop catching
NoPathFound (raised when all fee levels fail, bypassing the attempts counter)
- test_mpp_expiry (anchor): replace fixed asyncio.sleep with a polling loop that
waits until bob has received both HTLCs before asserting MPP state
The send_queue and forward_queue loops were doing put_nowait + sleep(SLEEP_DELAY)
+ get() to re-schedule not-yet-due messages. Under asyncio scheduler pressure the
get() can stall after the item was already put back, causing test_request_and_reply
to time out. Replaced with call_later(remaining, queue.put_nowait, item) which
schedules the re-insertion at the exact due time without any polling.
Two fixes:
1. test_trampoline_mpp_consolidation: set dave.MPP_EXPIRY=120 when
test_mpp_consolidation=True. With MPP_EXPIRY=2s and sequential HTLC
commitment rounds, Dave times out before the second HTLC arrives.
2. test_reestablish_fake_data: use explicit Task references in the
payment setup phase so that loop tasks (message loops, htlc_switch)
are cancelled in a finally block regardless of whether pay() succeeds
or raises. Without this, asyncio.gather leaves orphaned tasks running
across sub-test iterations when a payment fails, causing interference
get_target(): replace hardcoded Bitcoin constants (CHUNK_SIZE, 14-day
timespan, module-level MAX_TARGET) with per-chain values from constants.net.
Handle POW_GENESIS_BITS so that chains whose genesis nBits differs from
target_to_bits(MAX_TARGET) return the correct initial difficulty for period 0.
Map checkpoint indices correctly when adj_interval != CHUNK_SIZE.
verify_chunk(): add a separate code path for chains where the retarget
interval is shorter than CHUNK_SIZE (e.g. BTCP: 120 vs 2016). In this
case multiple retargets can occur within a single chunk; because the headers
are not yet on disk during verification, reading via read_header() would
raise MissingHeader and reject the entire chunk. Fix by reading from the
in-memory data buffer via a local helper _read_hdr(), and tracking
current_target across period boundaries inline.
can_connect(), chainwork_of_header_at_height(): use adj_interval instead of
CHUNK_SIZE when computing the difficulty-period index so that BTCP's 120-block
retarget windows are respected