Skip to content

Commit 68f8d9d

Browse files
committed
purge, rdy4merge
1 parent 471f672 commit 68f8d9d

31 files changed

Lines changed: 549 additions & 1696 deletions

.env.example

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,4 +23,4 @@ VITE_TESTNET_L1_RPC_URL=https://0xrpc.io/sep
2323
VITE_TESTNET_REGISTRY_ADDRESS=0xA0BFb1B494FB49041e5c6e8c2C1BE09cD171c6Ba
2424

2525
# The Web Push public key is deliberately not a VITE_* variable. The frontend
26-
# fetches it from GET /api/v3/config; its private half stays on the backend.
26+
# fetches it from GET /api/config; its private half stays on the backend.

.github/workflows/deploy.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ jobs:
4848
- name: Install dependencies
4949
run: pnpm install --frozen-lockfile
5050

51-
- name: Require reachable HTTPS endpoints for the PWA
51+
- name: Require HTTPS endpoints for the PWA
5252
env:
5353
PUBLIC_API_ORIGIN: https://api.slashveto.me
5454
MAINNET_L1_RPC_URL: ${{ vars.VITE_L1_RPC_URL }}

README.md

Lines changed: 66 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -1,85 +1,89 @@
11
# slashveto.me
22

3-
slashveto.me helps Aztec sequencer operators answer two questions:
4-
5-
1. Is one of my sequencers beginning to move through the slashing process?
6-
2. What does confirmed L1 state say about slashing risk across the network?
7-
8-
An operator enters one or more sequencer addresses. For each address,
9-
slashveto.me should show a single, linked Slashing Timeline rather than a collection
10-
of unrelated events:
3+
slashveto.me tracks an Aztec sequencer from the first observed duty miss to an
4+
L1 slash and ejection:
115

126
```text
13-
duty miss → node offense → L1 mentioncandidate → execution delay
7+
duty miss → node offense → L1 votequorum → execution delay
148
→ executable → executed → stake removed → ejection
159
```
1610

17-
That path can stop at any step. Examples include “one inactive epoch observed;
18-
the configured consecutive-epoch threshold has not been met” and “candidate
19-
slash becomes executable in two days; this node observed inactivity in the
20-
target epoch.” The second statement deliberately says **node evidence**:
21-
onchain slash votes contain a validator, target epoch, and penalty unit, but no
22-
offense reason.
11+
A path can stop at any step. The product keeps candidate amounts, executed
12+
rounds, and actual stake deductions separate. L1 votes do not encode an
13+
offense reason; a displayed reason is always labelled as evidence from the
14+
attached Aztec node.
2315

24-
## Two independent views
16+
## Surfaces
2517

26-
| Surface | Data source | Purpose |
18+
| Surface | Source | Purpose |
2719
| --- | --- | --- |
28-
| **Monitor** | Public Ethereum RPCs, queried by the browser | Backend-independent view of canonical contracts, rounds, votes, candidate actions, vetoes, execution, and actual slash logs. |
29-
| **PINGME** | slashveto.me backend, one Aztec node, Ethereum RPCs | Earlier node and Sentinel warnings, linked per-sequencer history, realtime status, and Telegram or Web Push delivery. |
30-
31-
The overlap is intentional. Monitor must remain useful when
32-
`api.slashveto.me` or the attached Aztec node is unavailable. PINGME provides
33-
continuity while a browser is closed and evidence that is not published to L1.
34-
Neither view is an oracle: local evidence is an observer's report, while L1
35-
reveals voting and stake outcomes but not the underlying offense.
36-
37-
Both views expose the same case feed and educational Slashing Timeline.
38-
Watchlists can be shared as address-only URLs without exposing PINGME's private
39-
management capability. Individual cases retain a compact copy-link action for
40-
alerts and investigations.
41-
42-
Watchlist rows collapse cases per sequencer and retain a compact stake and
43-
pending-amount summary. The public feed collapses only cases that share an
44-
exact payload address.
45-
46-
## Read this first
47-
48-
- [Aztec protocol model](docs/protocol.md) — slots, blocks, checkpoints,
49-
committees, proposals, signals, and proofs
50-
- [Slashing and ejection](docs/slashing.md) — all v5 offenses and the exact
51-
warning-to-stake-removal lifecycle
52-
- [Monitor architecture](docs/architecture.md) — trust boundaries, case
53-
linking, and requirements for the refactor
54-
- [V3 architecture record](docs/v3-plan.md) — the implemented case-first
55-
clean break and its acceptance contract
56-
- [Notification contract](docs/notifications.md) — what an alert may claim at
57-
each stage
58-
- [Privacy](docs/privacy.md) and [production runbook](docs/runbook.md)
59-
60-
The protocol documentation was researched against the active Aztec mainnet
61-
deployment and `aztec-packages` commit
62-
[`def7152a`](https://github.com/AztecProtocol/aztec-packages/tree/def7152aa13dc0f880f24e45ce39442908170878)
63-
on 2026-07-29. Parameters and canonical contracts are upgradeable. Runtime
64-
views must resolve them from the Registry and read their current values rather
65-
than treating the examples in these documents as constants.
20+
| **Monitor** | Ethereum RPC queried in the browser | Independent view of canonical contracts, votes, candidates, execution, and slash logs. |
21+
| **PINGME** | Backend using one Aztec node and Ethereum RPC | Earlier Sentinel/offense evidence, durable cases, and Telegram or Web Push alerts. |
22+
23+
Monitor never calls the backend. PINGME keeps the last known state when one
24+
source fails and reports that source as stale. Neither surface is an oracle:
25+
node evidence is one observer's report, while L1 establishes contract state
26+
without revealing the reason behind a vote.
27+
28+
The primary object is a slashing case: network, contract lineage, sequencer,
29+
and target epoch with its source observations and state transitions. Linking is
30+
exact and conservative. An actual slash joins through its execution transaction
31+
and action order, never by address and approximate time.
32+
33+
## Repository
34+
35+
- `shared/protocol/` contains the pure case projection, tallying, transitions,
36+
and notification wording shared by frontend and backend.
37+
- `src/` contains the React PWA and independent browser L1 collector.
38+
- `collector/` contains the Node backend, SQLite repository, three evidence
39+
collectors, API, durable outbox, Telegram, and Web Push.
40+
- `scripts/deploy-backend.sh` installs an immutable backend release under
41+
systemd.
42+
43+
The backend API is rooted at `/api`. `/live` reports process liveness and
44+
`/health` reports whether the required evidence sources are current.
45+
46+
| Method | Route | Purpose |
47+
| --- | --- | --- |
48+
| `GET` | `/api/config`, `/api/status`, `/api/network` | Capabilities, freshness, protocol state, and public cases |
49+
| `GET` | `/api/sequencers/:address`, `/api/cases/:id` | Public sequencer and exact-case views |
50+
| `POST` | `/api/watches` | Create a private watch and return its management token once |
51+
| `GET/PATCH/DELETE` | `/api/watches/:id` | Bearer-authenticated watch management |
52+
| `PUT/DELETE` | `/api/watches/:id/channels/web_push` | Web Push enrollment |
53+
| `POST` | `/api/watches/:id/channels/telegram-link` | One-time Telegram enrollment link |
54+
| `POST` | `/api/watches/:id/channels/test` | Queue a test alert |
6655

6756
## Development
6857

69-
Use Node 24 and the pinned pnpm version:
58+
Node 24 and the pinned pnpm version are required:
7059

7160
```bash
7261
corepack enable
73-
pnpm install
62+
pnpm install --frozen-lockfile
7463
cp .env.example .env
7564
cp collector/.env.example collector/.env
7665
pnpm dev
7766
pnpm dev:backend
7867
```
7968

80-
Run `pnpm check` before deployment. All `VITE_*` values are public. RPC
81-
credentials, Telegram tokens, VAPID private keys, and the Aztec admin endpoint
82-
belong only in the backend environment.
69+
Run the release gate with:
70+
71+
```bash
72+
pnpm check
73+
```
74+
75+
Every `VITE_*` value is public. RPC credentials, Aztec admin credentials,
76+
Telegram tokens, VAPID private keys, and the SQLite database belong only in the
77+
backend environment. The ignored `apiReference.md` and `onchainSources.md` are
78+
local research inputs, not runtime dependencies or published documentation.
79+
80+
## Documentation
81+
82+
- [Protocol and correctness model](docs/protocol.md)
83+
- [Notification contract](docs/notifications.md)
84+
- [Production runbook](docs/runbook.md)
8385

84-
The ignored `apiReference.md` and `onchainSources.md` files are research
85-
snapshots, not runtime inputs or committed documentation.
86+
The protocol model was checked against the active Aztec mainnet deployment and
87+
[`aztec-packages` commit `def7152a`](https://github.com/AztecProtocol/aztec-packages/tree/def7152aa13dc0f880f24e45ce39442908170878)
88+
on 2026-07-29. Contracts and parameters are upgradeable; runtime code discovers
89+
the responsible lineage and reads its values.

collector/.env.example

Lines changed: 14 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -1,47 +1,22 @@
1-
# Backend identity and browser origin.
2-
SLASHMON_NETWORK=mainnet
1+
# Local backend. These URLs are the built-in defaults and are shown here so
2+
# the three required upstreams are explicit.
33
SLASHMON_PUBLIC_URL=http://localhost:5173
44
BACKEND_CORS_ORIGIN=http://localhost:5173
5-
6-
# Public node RPC and private admin RPC for the same Aztec node.
75
AZTEC_NODE_URL=http://127.0.0.1:8080
8-
AZTEC_NODE_API_KEY=
96
AZTEC_ADMIN_URL=http://127.0.0.1:8880
10-
AZTEC_ADMIN_API_KEY=
11-
AZTEC_SENTINEL_POLL_INTERVAL_MS=60000
12-
AZTEC_SENTINEL_LOOKBACK_EPOCHS=3
13-
AZTEC_SENTINEL_EPOCH_END_BUFFER_SLOTS=2
14-
AZTEC_SENTINEL_VALIDATOR_CONCURRENCY=8
15-
AZTEC_SENTINEL_VALIDATOR_MAX_RESPONSE_BYTES=2097152
16-
17-
# One Ethereum RPC. The network selects the chain and Registry.
187
L1_RPC_URL=http://127.0.0.1:8545
19-
# L1_REGISTRY_ADDRESS=
20-
# Exact mainnet v5 history. Requires an archive RPC.
21-
# L1_SLASH_LOG_START_BLOCK=25533241
22-
# Used only when no exact start block is configured.
23-
L1_SLASH_LOG_LOOKBACK_BLOCKS=50000
24-
# Archive calls for a chunk containing slash executions can take longer.
25-
L1_SLASH_LOG_PROVIDER_TIMEOUT_MS=30000
268

27-
# Enable Telegram only when both values are set.
28-
TELEGRAM_BOT_TOKEN=
29-
TELEGRAM_BOT_USERNAME=
9+
# Add only when required by the endpoints above.
10+
# AZTEC_NODE_API_KEY=
11+
# AZTEC_ADMIN_API_KEY=
3012

31-
# Enable Web Push only when all three values are set.
32-
VAPID_SUBJECT=
33-
VAPID_PUBLIC_KEY=
34-
VAPID_PRIVATE_KEY=
35-
36-
BACKEND_DATABASE_PATH=./data/slashmon.sqlite
37-
BACKEND_BIND_HOST=127.0.0.1
38-
BACKEND_PORT=8790
39-
BACKEND_TRUST_PROXY=false
40-
41-
# Mutating API calls share one simple per-client limit.
42-
BACKEND_MUTATION_RATE_LIMIT_MAX_PER_MINUTE=20
43-
TELEGRAM_SEND_MAX_PER_SECOND=20
44-
TELEGRAM_LOW_PRIORITY_SEND_MAX_PER_SECOND=5
45-
TELEGRAM_CHAT_SEND_INTERVAL_MS=1000
13+
# Uncomment for an exact mainnet backfill from the first current-stack Rollup
14+
# block. Historical observations are indexed without sending notifications.
15+
# L1_SLASH_LOG_START_BLOCK=25533241
4616

47-
BACKEND_LOG_LEVEL=info
17+
# Optional channels. Each group must be complete.
18+
# TELEGRAM_BOT_TOKEN=
19+
# TELEGRAM_BOT_USERNAME=
20+
# VAPID_SUBJECT=mailto:operator@example.com
21+
# VAPID_PUBLIC_KEY=
22+
# VAPID_PRIVATE_KEY=

collector/README.md

Lines changed: 0 additions & 102 deletions
This file was deleted.
Lines changed: 12 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1,46 +1,23 @@
11
# Install as /etc/slashmon-backend-testing.env with mode 0600.
2-
# Cloudflare should route the testing API hostname to http://127.0.0.1:8791.
3-
SLASHMON_NETWORK=mainnet
42
SLASHMON_PUBLIC_URL=https://testing.slashveto.me
53
BACKEND_CORS_ORIGIN=https://testing.slashveto.me
64
BACKEND_BIND_HOST=127.0.0.1
75
BACKEND_PORT=8791
8-
# Safe when cloudflared connects directly to this loopback listener.
96
BACKEND_TRUST_PROXY=true
107

11-
# Mutating API calls share one simple per-client limit.
12-
BACKEND_MUTATION_RATE_LIMIT_MAX_PER_MINUTE=20
13-
TELEGRAM_SEND_MAX_PER_SECOND=20
14-
TELEGRAM_LOW_PRIORITY_SEND_MAX_PER_SECOND=5
15-
TELEGRAM_CHAT_SEND_INTERVAL_MS=1000
16-
17-
# The testing service may read the same Aztec node and Ethereum RPC as
18-
# production; its database, cases, watches, cursors, and deliveries are separate.
198
AZTEC_NODE_URL=http://127.0.0.1:8080
20-
AZTEC_NODE_API_KEY=
219
AZTEC_ADMIN_URL=http://127.0.0.1:8880
22-
AZTEC_ADMIN_API_KEY=
23-
AZTEC_SENTINEL_POLL_INTERVAL_MS=60000
24-
AZTEC_SENTINEL_LOOKBACK_EPOCHS=3
25-
AZTEC_SENTINEL_EPOCH_END_BUFFER_SLOTS=2
26-
AZTEC_SENTINEL_VALIDATOR_CONCURRENCY=8
27-
AZTEC_SENTINEL_VALIDATOR_MAX_RESPONSE_BYTES=2097152
28-
29-
L1_RPC_URL=http://127.0.0.1:8545
30-
# L1_REGISTRY_ADDRESS=
31-
# Exact mainnet v5 history. Requires an archive RPC.
32-
# L1_SLASH_LOG_START_BLOCK=25533241
33-
# Used only when no exact start block is configured.
34-
L1_SLASH_LOG_LOOKBACK_BLOCKS=50000
35-
# Archive calls for a chunk containing slash executions can take longer.
36-
L1_SLASH_LOG_PROVIDER_TIMEOUT_MS=30000
10+
L1_RPC_URL=https://YOUR-ARCHIVE-ETHEREUM-RPC
11+
L1_SLASH_LOG_START_BLOCK=25533241
3712

38-
# Use testing-only notification credentials. In particular, Telegram long
39-
# polling cannot be shared with production. Leave these empty if not needed.
40-
TELEGRAM_BOT_TOKEN=
41-
TELEGRAM_BOT_USERNAME=
42-
VAPID_SUBJECT=
43-
VAPID_PUBLIC_KEY=
44-
VAPID_PRIVATE_KEY=
13+
# Add only when required by the node endpoints.
14+
# AZTEC_NODE_API_KEY=
15+
# AZTEC_ADMIN_API_KEY=
4516

46-
BACKEND_LOG_LEVEL=info
17+
# Use testing-only credentials. Telegram cannot poll the same bot in two
18+
# processes.
19+
# TELEGRAM_BOT_TOKEN=
20+
# TELEGRAM_BOT_USERNAME=
21+
# VAPID_SUBJECT=mailto:operator@example.com
22+
# VAPID_PUBLIC_KEY=
23+
# VAPID_PRIVATE_KEY=

collector/deploy/slashmon-backend-testing.service

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[Unit]
22
Description=slashveto.me testing backend
3-
Documentation=file:/opt/slashmon/testing/collector/README.md
3+
Documentation=file:/opt/slashmon/testing/docs/runbook.md
44
Wants=network-online.target
55
After=network-online.target
66
StartLimitIntervalSec=60

0 commit comments

Comments
 (0)