Files
smom-dbis-138/docs/channels/WATCHTOWER_AND_INDEXER.md
2026-03-02 12:14:09 -08:00

65 lines
4.3 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Watchtower and Indexer
Optional off-chain components for payment channels: watchtower (dispute response) and indexer (channel listing).
---
## Watchtower
### Purpose
When a channel is in **Dispute**, the party that did not initiate the close has a limited time (challenge window) to submit a **newer** signed state via `challengeClose`. If they are offline, a malicious counterparty could submit an old state and wait for the deadline, then `finalizeClose` and take more than their share.
A **watchtower** watches the chain for `ChallengeSubmitted` (and channel close activity) for channels where a designated participant is involved. If it sees a close that uses an older state than the one the watchtower holds, it submits `challengeClose` with the latest signed state before the deadline.
### Design
- **Inputs**: RPC URL, list of (channelId, latest signed state: nonce, balanceA, balanceB, sigs) for channels the user cares about, and a key that can sign txs (or the watchtower runs on behalf of the user and has delegated authority).
- **Logic**: Subscribe to or poll PaymentChannelManager for `ChallengeSubmitted` and `ChannelClosed`. For each channel in the list, if `ChallengeSubmitted` shows a dispute with `nonce` less than the watchtowers latest nonce, call `challengeClose` with the stored state before `disputeDeadline`.
- **Security**: The key that signs `challengeClose` must be secure (env var, HSM, or user-backed key). Prefer a dedicated key with no other funds.
### Implementation options
- **Small service**: e.g. `services/watchtower/` in this repo: Node.js or Python script that uses ethers/web3.py, reads config from env, and runs a loop or event subscription.
- **Separate repo**: Standalone watchtower service that supports this contracts ABI and events.
No watchtower implementation is included in this repo; this doc is the specification. Deploy and run a watchtower only if users need automated dispute response.
---
## Indexer
### Purpose
The frontend “Channels” tab lists channels by calling `getChannelCount` and `getChannelIdByIndex`, then `getChannel` for each. That works for a small number of channels. For many channels or for filtering by participant, an **indexer** can:
- Index `ChannelOpened` and `ChannelClosed` (and optionally `ChallengeSubmitted`).
- Expose an API: e.g. “channels where address X is participantA or participantB”, “channels in status Open/Dispute”.
### Design
- **Events**: `ChannelOpened(channelId, participantA, participantB, depositA, depositB)`, `ChannelClosed(channelId, balanceA, balanceB, cooperative)`, `ChallengeSubmitted(channelId, nonce, balanceA, balanceB, newDeadline)`.
- **Storage**: DB (e.g. Postgres) with tables for channels and events, keyed by chain and channelId.
- **API**: REST or GraphQL: e.g. `GET /channels?chainId=138&participant=0x...`.
### Implementation options
- **Existing Chain-138 / Mainnet indexer**: If the project already has an indexer for the chain, add handlers for PaymentChannelManager events and expose channel queries.
- **Subgraph (The Graph)**: Create a subgraph for PaymentChannelManager and query channels by participant.
- **Custom service**: Small service that subscribes to logs, writes to DB, and serves HTTP.
Document the indexer API and deployment in ops/deployment docs when one is added. Until then, the frontend uses on-chain `getChannelCount` + `getChannelIdByIndex` + `getChannel` only.
---
## Implementation status
- **Watchtower**: A minimal implementation lives in `services/watchtower/`. It subscribes to `ChallengeSubmitted` on PaymentChannelManager and calls `challengeClose` with a newer state from a JSON file before the dispute deadline. See `services/watchtower/README.md`.
- **Indexer**: No indexer or subgraph is implemented yet. Channels are enumerated on-chain by the frontend. To add "channels by participant", implement a custom indexer or The Graph subgraph as described above and expose an API (e.g. `GET /channels?participant=0x...`).
---
## Transaction mirroring (no change)
Channel transactions on **Chain-138** are normal txs. The existing **Transaction Mirroring Service** mirrors them to **TransactionMirror** on Mainnet. No change to that service or contract is required. State anchoring of Chain-138 (including PaymentChannelManager state) is already done by the **State Anchoring Service** and **MainnetTether**.