Skip to main content

Open Ghost Root Updater

The Open Ghost Root Updater is a separate instance of the root updater service dedicated to maintaining the Merkle tree for the OpenGhost/Revels data privacy system. While it shares the same core logic as the primary root updater, it targets a different contract (OpenCommitmentTree) and maintains a completely independent Merkle tree.

Purpose

The Specter protocol operates two distinct commitment trees:

TreeContractPurposeUpdater Service
Ghost treeCommitmentTreeToken privacy (commit/reveal for fungible tokens)ghost-root-updater
OpenGhost treeOpenCommitmentTreeData privacy for OpenGhost/Revels (commit/reveal for structured data)open-ghost-root-updater

Separating the trees ensures that token privacy commitments and data privacy commitments do not share Merkle state. This isolation provides several benefits:

  • Independent root cadence: Token commits and data commits can have different volumes without affecting each other's root update frequency.
  • Circuit separation: The Ghost circuit and the OpenGhost circuit reference different roots, preventing cross-domain proof confusion.
  • Failure isolation: If the OpenGhost root updater falls behind or encounters errors, token privacy operations continue unaffected, and vice versa.

How It Works

The Open Ghost Root Updater follows the same operational pattern as the primary root updater:

  1. Historical sync: On startup, it replays all Committed events from the OpenCommitmentTree contract, rebuilding the local Merkle tree from genesis.
  2. Real-time listening: After sync completes, it subscribes to new Committed events.
  3. Tree insertion: Each commitment is inserted into the local incremental Poseidon Merkle tree at the next available leaf index.
  4. Root submission: After debounce batching, the new root is submitted on-chain via OpenCommitmentTree.updateRoot().

The Poseidon hash function, tree depth, zero-value precomputation, and debounce logic are identical to the primary root updater.

OpenGhost / Revels

OpenGhost is Specter's data privacy layer, distinct from the token privacy provided by the core Ghost Protocol. While Ghost Protocol hides token transfers (who sent what amount to whom), OpenGhost enables privacy-preserving data commitments used by the Revels system.

Revels allows users to commit structured data (e.g., event attendance proofs, credential attestations, NFC card bindings) into a Merkle tree and later reveal them with zero-knowledge proofs. The commitment scheme uses Poseidon4 (PoseidonT5) instead of the Poseidon7 used by the token privacy tree, reflecting the different input structure:

OpenGhost commitment = Poseidon4(secret, nullifier_secret, data_hash, blinding)

The Open Ghost Root Updater is agnostic to the commitment format — it simply inserts the emitted commitment hashes into the tree and computes roots. The commitment structure is enforced by the circuits and contracts, not by the updater.

Configuration

The Open Ghost Root Updater is configured with its own set of environment variables, separate from the primary root updater:

ParameterDescription
RPC_URLSpecter chain RPC endpoint (same as primary)
OPEN_COMMITMENT_TREE_ADDRESSAddress of the OpenCommitmentTree contract
OPERATOR_PRIVATE_KEYDedicated operator key for OpenCommitmentTree.updateRoot()
DEBOUNCE_MSDebounce interval for batching
START_BLOCKBlock to begin historical sync from

The operator key should be distinct from the primary root updater's key to maintain privilege isolation.

Deployment

The service runs as a separate PM2 process alongside the primary root updater:

pm2 status
# ┌─────────────────────────────┬────┬───────┐
# │ name │ id │ status│
# ├─────────────────────────────┼────┼───────┤
# │ ghost-root-updater │ 0 │ online│
# │ open-ghost-root-updater │ 1 │ online│
# └─────────────────────────────┴────┴───────┘

Both services connect to the same Specter RPC endpoint but watch different contract addresses and maintain independent tree state, caches, and operator keys.