Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
fa37c11
docs: rewrite CONTRIBUTING.md for voice and accuracy
VijitSingh97 Jul 2, 2026
e10cc42
docs: rewrite README.md for voice and accuracy
VijitSingh97 Jul 2, 2026
1004cfd
docs: rewrite SECURITY.md for voice and accuracy
VijitSingh97 Jul 2, 2026
d9fd134
docs: rewrite build/dashboard/README.md for voice and accuracy
VijitSingh97 Jul 2, 2026
fa8395e
docs: rewrite docs/README.md for voice and accuracy
VijitSingh97 Jul 2, 2026
b117aae
docs: rewrite docs/architecture.md for voice and accuracy
VijitSingh97 Jul 2, 2026
add20b6
docs: rewrite docs/configuration.md for voice and accuracy
VijitSingh97 Jul 2, 2026
b9b404a
docs: rewrite docs/dashboard.md for voice and accuracy
VijitSingh97 Jul 2, 2026
ecf27e9
docs: rewrite docs/faq.md for voice and accuracy
VijitSingh97 Jul 2, 2026
816eb92
docs: rewrite docs/getting-started.md for voice and accuracy
VijitSingh97 Jul 2, 2026
4e67659
docs: rewrite docs/hardware.md for voice and accuracy
VijitSingh97 Jul 2, 2026
7ba2c79
docs: rewrite docs/integration-testing.md for voice and accuracy
VijitSingh97 Jul 2, 2026
3e943cd
docs: rewrite docs/operations.md for voice and accuracy
VijitSingh97 Jul 2, 2026
4a21ad2
docs: rewrite docs/privacy.md for voice and accuracy
VijitSingh97 Jul 2, 2026
4208bca
docs: rewrite docs/release-server.md for voice and accuracy
VijitSingh97 Jul 2, 2026
17c581f
docs: rewrite docs/releasing.md for voice and accuracy
VijitSingh97 Jul 2, 2026
65c2171
docs: rewrite docs/test-server-architecture.md for voice and accuracy
VijitSingh97 Jul 2, 2026
d2ed2e1
docs: rewrite docs/testing-guide.md for voice and accuracy
VijitSingh97 Jul 2, 2026
e3bc7ed
docs: rewrite docs/testing-strategy.md for voice and accuracy
VijitSingh97 Jul 2, 2026
c2c4894
docs: rewrite docs/workers.md for voice and accuracy
VijitSingh97 Jul 2, 2026
f37a54b
docs: rewrite images/launch/README.md for voice and accuracy
VijitSingh97 Jul 2, 2026
db54b0d
docs: verify hardware.md sizing against live deployments; fix Tari ov…
VijitSingh97 Jul 2, 2026
1aa7cef
Merge remote-tracking branch 'origin/develop' into docs/voice-and-acc…
VijitSingh97 Jul 2, 2026
1bad4c1
docs: fix banned word in monitoring.md (powerful -> high-privilege)
VijitSingh97 Jul 2, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 14 additions & 15 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -1,35 +1,34 @@
# Contributing to Pithead

This guide covers the workflow for contributing bug fixes, docs changes, and features.
The workflow for contributing bug fixes, docs changes, and features.

## Before you start

- **Found a bug or have an idea?** Open an issue first. For anything beyond a small fix,
discuss it in an issue before writing code. It saves time and avoids
surprises at review.
- Check the [open issues](https://github.com/p2pool-starter-stack/pithead/issues) to see
if someone's already on it.
- Open an issue before writing code for anything beyond a small fix. Discuss the approach
there first.
- Check the [open issues](https://github.com/p2pool-starter-stack/pithead/issues) for existing
work on the same thing.

## Dev environment

The dashboard uses [uv](https://docs.astral.sh/uv/) for dependency management; a hashed
`uv.lock` pins every transitive dependency so installs are reproducible build-to-build. Its
Python tooling ([`ruff`](https://docs.astral.sh/ruff/) lint + format,
[`pre-commit`](https://pre-commit.com/)) lives in the `dev` extra. Install uv, then from the
repo root:
`uv.lock` pins every transitive dependency for reproducible installs. Its Python tooling
([`ruff`](https://docs.astral.sh/ruff/) lint + format, [`pre-commit`](https://pre-commit.com/))
lives in the `dev` extra. Install uv, then from the repo root:

```bash
uv sync --project build/dashboard --extra dev # deps + tooling into build/dashboard/.venv, from the lock
uv run --project build/dashboard pre-commit install
```

`make test` and `make lint-py` run through uv automatically (no venv to activate); `pre-commit`
then runs `ruff` (plus a few hygiene hooks) on your changed files. If you change dependencies in
runs `ruff` (plus a few hygiene hooks) on your changed files. If you change dependencies in
`build/dashboard/pyproject.toml`, run `uv lock` and commit the updated `uv.lock`.

## Development workflow

1. Fork the repo and create a branch off `main`.
1. Fork the repo and create a branch off `develop` (the integration branch; `main` holds released
commits only).
2. Make your change. Keep it focused: one logical change per PR.
3. Run the full test suite locally:

Expand Down Expand Up @@ -58,18 +57,18 @@ then runs `ruff` (plus a few hygiene hooks) on your changed files. If you change
Bigger, infra-dependent suites run separately: `make test-mini-stack` (tier-3 docker) and
`make test-integration` (tier-4 live, against a real box; start with `--check`).

4. **Add or update tests** for your change. Cover the *intent* (a behavior/contract), not just
4. Add or update tests for your change. Cover the *intent* (a behavior/contract), not just
the line. The [Testing Guide](docs/testing-guide.md) has per-change recipes; the
[Testing Strategy](docs/testing-strategy.md) explains the tiers.
5. Update the docs in [`docs/`](docs/) (and the README, if relevant) for any
user-facing change, and run `make test-inventory` if you touched the test suites.

## Opening a pull request

- Target the `main` branch and fill out the PR template.
- Target the `develop` branch and fill out the PR template.
- Link the issue your PR addresses (e.g. `Closes #123`).
- Make sure `make test` passes; CI runs the same checks.
- PRs require review before merging; the right reviewers are requested automatically via
- PRs require review before merging; reviewers are requested automatically via
[CODEOWNERS](.github/CODEOWNERS).

## Style
Expand Down
56 changes: 26 additions & 30 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,9 @@
![Platform: Ubuntu 24.04](https://img.shields.io/badge/Platform-Ubuntu%2024.04-E95420?logo=ubuntu&logoColor=white)
![Tor](https://img.shields.io/badge/Networking-Tor--first-7D4698?logo=torproject&logoColor=white)

Pithead is a containerized stack for running a private [Monero](https://www.getmonero.org/) full
node, [P2Pool](https://github.com/SChernykh/p2pool), and [Tari](https://www.tari.com/) merge mining.
An interactive setup script takes you from clone to mining in a few minutes.
Docker Compose stack for Monero + Tari merge mining on [P2Pool](https://github.com/SChernykh/p2pool),
with a [Monero](https://www.getmonero.org/) full node, [Tari](https://www.tari.com/) base node, and
a Tor daemon. The `pithead` script renders config, provisions Tor, and drives docker-compose.

<picture>
<source media="(prefers-color-scheme: dark)" srcset="./images/launch/hero.png">
Expand All @@ -26,25 +26,22 @@ An interactive setup script takes you from clone to mining in a few minutes.

## What it does

- ⛏️ **Zero-fee, decentralized payouts.** Mines Monero on [P2Pool](https://p2pool.io/): no pool
operator, no fees, rewards paid straight to your own wallet. Every hash also merge-mines Tari at
no extra power or config cost.
- 🧠 **XvB yield optimizer.** An algorithmic engine watches the XMRvsBeast raffle and shifts
hashrate to catch bonus rounds. It donates only the minimum needed to hold your tier and returns
every spare cycle to your own P2Pool payouts.
- 🧅 **Tor-first networking.** A built-in Tor daemon gives Monero, Tari, and P2Pool onion addresses,
so your router stays closed and your home IP is never advertised to an inbound peer. Two outbound
yield paths still touch clearnet in v1.0; the [privacy guide](docs/privacy.md) maps every
connection and how to harden it.
- 🔌 **One endpoint for every rig.** Point all your workers at a single address. Wallets and per-rig
pool config stay out of the miner; the stack routes the hashrate.
- 📊 **Live dashboard.** Shows hashrate, your P2Pool/XvB split, the PPLNS window, and every worker
update, served over HTTPS on your LAN.
- 🚀 **Interactive setup.** A script handles dependencies, config, Tor, and (on Linux) RandomX
kernel tuning. It asks before touching GRUB, then offers to start the stack.
- 🔒 **Hardened defaults.** Least-privilege containers, SHA256-verified binaries, pinned versions,
localhost-only RPC, and least-privilege Docker socket proxies (a read-only one for stats, plus a
separate start/stop-only one for node-down worker failover).
- ⛏️ **P2Pool payouts, Tari merge mined.** Mines Monero on [P2Pool](https://p2pool.io/): no pool
operator, no fee, rewards paid to your own wallet. Every hash merge-mines Tari on the same work.
- 🧠 **XvB switching engine.** Watches the XMRvsBeast raffle and shifts hashrate to hold your tier,
donating the minimum needed and routing the rest to your P2Pool payouts.
- 🧅 **Tor-first networking.** A built-in Tor daemon gives Monero, Tari, and P2Pool onion addresses;
a host firewall drops any direct clearnet dial from the stack. Two outbound paths still touch
clearnet in v1.0 — the [privacy guide](docs/privacy.md) maps every connection and how to harden it.
- 🔌 **One endpoint for every rig.** Point all workers at a single address on port `3333`. No wallet
address in the miner config; the stack routes the hashrate.
- 📊 **Live dashboard.** Hashrate, the P2Pool/XvB split, the PPLNS window, and per-worker updates,
served over HTTPS on your LAN.
- 🚀 **Interactive setup.** `pithead setup` checks dependencies, writes config, provisions Tor, and
(on Linux) tunes HugePages for RandomX. It prompts before any GRUB change, then offers to start.
- 🔒 **Hardened defaults.** Non-root containers, SHA256-verified binaries, pinned image digests,
localhost-only RPC, and two scoped Docker socket proxies: a read-only one for stats and a
separate start/stop-only one for node-down worker failover.

---

Expand All @@ -66,16 +63,15 @@ cp config.minimal.json config.json # then set your Monero + Tari payout addres
> payout addresses. Full sizing in [Hardware Requirements](docs/hardware.md).

`setup` checks dependencies (and offers to install them on Ubuntu), asks for your wallet
addresses, provisions Tor, tunes the kernel for RandomX, and offers to start the stack. Then:
addresses, provisions Tor, tunes HugePages for RandomX, and offers to start the stack. Then:

1. Open the dashboard at `https://<your-hostname>` (the script prints the exact URL).
2. Let it sync. On first boot the dashboard shows Sync Mode while your Monero and Tari nodes catch
up to the network, then switches to the live view automatically once synced. p2pool and the
proxy stay parked until then, so the sync logs stay clean.
3. Connect your miners by pointing any [XMRig](https://github.com/xmrig/xmrig) rig at
`YOUR_STACK_IP:3333` (no wallet address needed). New to mining?
[RigForge](https://github.com/p2pool-starter-stack/rigforge) provisions a tuned worker in one
command.
2. Wait for the initial sync. On first boot the dashboard shows Sync Mode while the Monero and Tari
nodes catch up, then switches to the live view once both are synced. p2pool and the proxy stay
parked until then.
3. Point any [XMRig](https://github.com/xmrig/xmrig) rig at `YOUR_STACK_IP:3333` — no wallet
address in the miner. [RigForge](https://github.com/p2pool-starter-stack/rigforge) provisions a
tuned worker in one command.

<div align="center">
<img src="./images/launch/demo.gif" alt="Pithead — live mining dashboard tour" width="85%">
Expand Down
32 changes: 17 additions & 15 deletions SECURITY.md
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
# Security Policy

This is the security policy for Pithead: supported versions, how to report a vulnerability,
The security policy for Pithead: supported versions, how to report a vulnerability,
and the stack's default security posture.

Pithead runs a Monero full node, P2Pool, Tari merge mining, and a dashboard on your
hardware, and it handles wallet payout addresses. We appreciate reports that help keep
operators safe.
hardware, and it handles wallet payout addresses.

## Supported versions

Expand All @@ -22,24 +21,27 @@ Make sure you're running an up-to-date checkout before reporting an issue.
**Please do not open a public issue for security problems.**

Use GitHub's private vulnerability reporting instead: go to the **Security** tab and
click **"Report a vulnerability"**. This opens a private advisory visible only to the
maintainers, where we can triage and coordinate a fix and disclosure with you.
click **Report a vulnerability**. This opens a private advisory visible only to the
maintainers, for triage and coordinated disclosure.

When you report, it helps to include:
Include:

- A description of the issue and its impact.
- Steps to reproduce, and the affected component (node, P2Pool, proxy, dashboard, Tor,
`pithead` script, etc.).
- Any relevant logs or configuration (redact wallet addresses and secrets).

We aim to acknowledge reports promptly and will keep you posted as we work on a fix.

## Security posture

The stack is hardened by default: least-privilege containers (every service runs as a **non-root
user**, not uid 0; leaf services run with `no-new-privileges` and drop all Linux capabilities; the
internet-facing and Docker-socket-facing ones also use a read-only root filesystem),
SHA256-verified and version-pinned binaries,
localhost-only RPC, a LAN-scoped (and narrowable) stratum port, scoped Docker socket proxies,
and Tor for all node networking. If you find a gap in any of these, that's the kind of
report we want.
The stack's defaults:

- Least-privilege containers: every service runs as a non-root user (not uid 0); leaf services
run with `no-new-privileges` and drop all Linux capabilities; internet-facing and
Docker-socket-facing services also use a read-only root filesystem.
- SHA256-verified, version-pinned binaries.
- Localhost-only RPC.
- LAN-scoped (and narrowable) stratum port.
- Scoped Docker socket proxies.
- Tor for all node networking.

Report any gap in these.
19 changes: 11 additions & 8 deletions build/dashboard/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,12 +25,14 @@ Everything is served from `/static`: the vendored Preact, htm and Chart.js (`sta
the app modules and `dashboard.css`. Nothing is inlined and the libraries are eval-free, so the
page runs under a strict Content-Security-Policy with no `'unsafe-inline'`/`'unsafe-eval'`.

Testing: the Python API, where all the logic and formatting live, is fully unit-tested. The pure
client logic (worker sort, tooltip formatting, hero-KPI selection in `static/logic.mjs`) is
unit-tested with Node's built-in runner
(`node --test build/dashboard/tests/frontend/*.test.mjs`) — no
`package.json`/`node_modules`/build step, so the repo stays Node-free. Component rendering has no
unit tests by design; it's covered by a manual browser smoke test.
Testing: the Python API, where the logic and formatting live, is unit-tested. The client-side
tests run under Node's built-in runner (`node --test build/dashboard/tests/frontend/`) — no
`package.json`/`node_modules`/build step, so the repo stays Node-free. They cover the pure logic
(`logic.test.mjs`: worker sort, tooltip formatting, hero-KPI selection), the chart helpers
(`chart.test.mjs`: `withAlpha`, `padYAxis`), the topology geometry (`topology.test.mjs`), and
component rendering (`components.test.mjs`: every card driven through `App` against a real
`build_state()` fixture, via a DOM-free vnode walker). The DOM-bound wiring (Chart.js canvas,
the SVG topology component) needs a browser and is left to a manual smoke test.

## Layout

Expand All @@ -42,6 +44,7 @@ mining_dashboard/
├── collector/ # local stats collectors (pools, system, docker logs)
├── service/ # algo_service (XvB switching), data_service (aggregation), storage_service (SQLite),
│ # metrics (typed computed domain values consumed by the view layer)
├── sim/ # donation_model (the XvB donation simulator; property-tested, #284)
├── web/ # server.py (transport: / shell + /api/state + middleware),
│ # views.py (build_state: the JSON state object), templates/index.html
│ # (static shell), static/ (Preact app + dashboard.css + vendored libs)
Expand All @@ -64,8 +67,8 @@ uv sync --extra test
pytest # quick run
pytest --cov=mining_dashboard --cov-report=term-missing --cov-fail-under=80

# pure client logic (needs only Node >= 18, no install):
node --test tests/frontend/*.test.mjs
# client-side tests (needs only Node >= 18, no install):
node --test tests/frontend/
```

Or from the repo root: `make test-dashboard`. The same Python suite runs in the Docker test stage:
Expand Down
5 changes: 2 additions & 3 deletions docs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,8 @@

Guides for running, configuring, and operating Pithead.

New here? Start with the [Getting Started](getting-started.md) guide. It takes you from a fresh
Ubuntu machine to a synced, mining stack in a handful of commands. The other guides go deeper on
individual topics once you're running.
Start with [Getting Started](getting-started.md): it takes a fresh Ubuntu host to a synced, mining
stack. The other guides cover individual topics once you're running.

## Guides

Expand Down
Loading