62 lines
6.8 KiB
Markdown
62 lines
6.8 KiB
Markdown
# CLAUDE.md
|
|
|
|
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
|
|
|
|
## Project
|
|
|
|
`plm-electrumx`: a fork of ElectrumX 2.0.0 with its own versioning (package name `plm-electrumx`, version in `src/electrumx/__init__.py` and `docs/conf.py`, import name `electrumx`), an Electrum-protocol server (asyncio) that indexes a coin daemon into a local DB (LevelDB or RocksDB), supporting **Palladium (PLM) only**. All other coins and their code were removed (see the "Fork notes" in `README.md` for the upstream base commit and how to merge upstream). Keep changes to core files small so upstream merges stay easy. MIT license: keep `LICENCE`.
|
|
|
|
## Commands
|
|
|
|
```bash
|
|
pip install -e ".[leveldb,rocksdb]" # at least one DB engine extra is required
|
|
pip install pytest pytest-asyncio pytest-cov pycodestyle
|
|
|
|
pytest # all tests (what CI runs, with --cov=electrumx)
|
|
pytest tests/lib/test_palladium.py # single file
|
|
pytest tests/server/test_mempool.py::test_name # single test
|
|
pycodestyle --max-line-length=140 src # the only lint, enforced in CI
|
|
|
|
cd docs && make html # docs (Sphinx)
|
|
|
|
# integration tests: ElectrumX against a real Palladium regtest node in Docker (skipped unless PLM_TEST_DAEMON_URL is set)
|
|
docker compose -f tests/integration/docker-compose.yml up -d --build --wait
|
|
PLM_TEST_DAEMON_URL=http://plmtest:plmtest@127.0.0.1:28443/ pytest tests/integration
|
|
docker compose -f tests/integration/docker-compose.yml down -v
|
|
|
|
DB_ENGINE=rocksdb DB_DIRECTORY=... DAEMON_URL=http://user:pass@host:port/ electrumx_server
|
|
electrumx_rpc getinfo # needs rpc:// in SERVICES (the Docker image does not enable it)
|
|
contrib/docker-smoke-test.sh # after `docker build -t plm-electrumx .`: checks the SSL handling of the entrypoint
|
|
```
|
|
|
|
Docker: needs `.env` (copy `.env.example`; `PLM_RPC_USER`/`PLM_RPC_PASSWORD` are required, the rest has defaults) and the data directory created as your user first: `mkdir -p ~/.plm-electrumx/db ~/.plm-electrumx/ssl`. Then `docker compose up -d --build` (root `Dockerfile`, `docker-compose.yml`, `.env` from `.env.example`) runs the server on the external `palladium` network of the Palladium node container, daemon at `palladiumd:2332`. `docker-entrypoint.sh` sets up SSL: it uses `SSL_CERTFILE`/`SSL_KEYFILE` if given, else the self-signed certificate in `ssl/` of the data directory (`~/.plm-electrumx`, bind-mounted), generating it only if missing (never overwrite it: clients pin it), and sets `SERVICES`.
|
|
|
|
Do not run Python with `src/electrumx/lib/` as the current directory: `lib/enum.py` shadows the standard `enum` module and breaks the interpreter.
|
|
|
|
Configuration is entirely via environment variables, parsed in `src/electrumx/server/env.py` (documented in `docs/environment.rst`). `DB_ENGINE` is mandatory in 2.0 (`leveldb` or `rocksdb`). Python >=3.10; free-threaded 3.14t is experimental.
|
|
|
|
## Architecture
|
|
|
|
Pipeline (see `docs/architecture.rst`): `Env` → `Controller` (`server/controller.py`) wires together `Daemon` (RPC client to the coin node, `server/daemon.py`), `BlockProcessor` (`block_processor.py`, indexes blocks/handles reorgs, writes via `db.py`/`history.py`/`storage.py`), `MemPool` (`mempool.py`), `SessionManager`/`ElectrumX` sessions (`session.py`, the only place that knows the Electrum wire protocol and its versions), and `PeerManager` (`peers.py`). `Notifications` in `controller.py` merges block and mempool "touched" hashXs/outpoints so clients are not notified twice.
|
|
|
|
Coin abstraction: `lib/coins.py` defines `Coin` and the `Palladium`, `PalladiumTestnet`, `PalladiumRegtest` subclasses. A coin class selects behavior through class attributes: `DESERIALIZER` (block/tx format, in `lib/tx.py`, only the segwit one remains), `DAEMON`, `BLOCK_PROCESSOR`, `SESSIONCLS`, address verbytes, `GENESIS_HASH`, `REORG_LIMIT`, `RPC_PORT`, `PEERS`, header handling, etc. Coins are discovered by walking `Coin` subclasses (`lookup_coin_class` matches `NAME` + `NET`; `COIN` defaults to `Palladium`). Concrete classes must define `TX_COUNT`, `TX_COUNT_HEIGHT`, `TX_PER_BLOCK` (used only for sync ETAs) or lookup raises.
|
|
|
|
Daemon: Palladium Core is based on Bitcoin Core 0.19: no `getindexinfo`, `txospenderindex` or `submitpackage`. So `MIN_REQUIRED_DAEMON_VERSION`/`REQUIRED_DAEMON_INDEXES` (see `Coin`) are unset, and `blockchain.outpoint.subscribe` / `blockchain.transaction.broadcast_package` return a daemon error to clients. The daemon needs `txindex=1`.
|
|
|
|
DB schema changed in 2.0 with no migration; changing on-disk format requires a full resync.
|
|
|
|
## Tests
|
|
|
|
Integration tests (`tests/integration`): `node/Dockerfile` + `node/palladium.conf` run the Palladium node (official release binaries, signature checked) in regtest, `conftest.py` starts `electrumx_server` on an empty DB against it and the tests mine blocks and check headers, balances, mempool, history, merkle proofs and broadcast through the Electrum protocol. Regtest coinbase maturity is 120 blocks, bech32 hrp is `rplm`. The CI job is `integration`. Bump `VERSION` in the Dockerfile to test against a newer node.
|
|
|
|
`tests/lib` (Palladium params, addresses, hashes, scripts), `tests/server` (env, daemon, mempool, storage, API), plus fixture-driven `tests/test_blocks.py` / `test_transactions.py` using JSON files named `<coin>_<net>_<id>.json` in `tests/blocks` and `tests/transactions` (real mainnet data from a synced node; tx vout values in satoshis). `test_storage.py` needs both DB engines installed. Bech32 addresses are not supported by `Coin.address_to_hashX` (base58 only). Fixtures were taken from a synced node (`getblock <hash> 0|1`, `getrawtransaction <txid> true <blockhash>`, run via `docker compose exec palladiumd palladium-cli ...` in the node's project); vout values converted to satoshis. Ports, SSL, RPC credentials and donation address are documented in `DEPLOY.md`.
|
|
|
|
## Repository and workflow
|
|
|
|
- Default branch `main`, remotes `origin` (palladium-coin/plm-electrumx) and `upstream` (spesmilo/electrumx). With two remotes `gh` needs `--repo palladium-coin/plm-electrumx` (or `gh repo set-default`).
|
|
- History is a snapshot of upstream commit `280cb33` plus Palladium commits: no common history, `git merge upstream` does not work. Update with `git diff 280cb33 upstream/master | git apply --3way` (see the "Fork notes" in `README.md`).
|
|
- Do not create, move or delete git tags.
|
|
- Do not `git add -A`: generated files (`.coverage`, `.env`) get swept in. Add files by name. `.coverage` and `.env` are in `.gitignore`.
|
|
- CI (`.github/workflows/ci.yml`, on `main`): `unittests`, `pycodestyle`, `build_docs`, `docker` (builds the image, runs the smoke test). It runs on Ubuntu 24.04; `test_storage.py` fails with RocksDB 9.10 (Debian trixie) in teardown.
|
|
- In repo documentation never cite paths or links of the palladiumcore repository; describe the concept (the Palladium node, the `palladium` Docker network).
|