Running a Relayer Node

Running a Relayer Node

Secure Config • Encrypted Message Queue


Relayer nodes are the off-chain backbone of SnarkSide’s intent-based architecture. They perform the critical functions of:

  • Aggregating encrypted user trade intents

  • Computing valid match candidates off-chain

  • Generating zero-knowledge proofs for match validity

  • Submitting compressed batches to the on-chain verifier

Given their sensitive operational role, relayers must be deployed with high reliability, strict cryptographic hygiene, and zero-leak message handling. This guide provides a comprehensive overview for running and hardening a SnarkSide relayer node.


1. System Overview

Each relayer is composed of the following core services:

Component
Purpose

Intent Aggregator

Receives encrypted trade intents via API or pub/sub

Match Engine

Detects viable trade pairs among encrypted intents

Witness Generator

Produces witness inputs for circuit proofs

Proof Generator

Runs Groth16 proof construction using precompiled keys

Batch Submitter

Posts Merkle root, circuit hash, and proof to on-chain

Encrypted Queue

Maintains encrypted, timestamped message bus for intents


2. Secure Configuration

Environment Variables

Set the following in .env:

RPC_URL=https://<your-l2-rpc>
PRIVATE_KEY=0xabc...
VERIFIER_CONTRACT=0x...
RELAYER_IDENTITY_KEY=<your-ed25519 key>
CIRCUIT_HASH=0x...
QUEUE_ENCRYPTION_KEY=<AES256_GCM key>

Recommendations

  • Never run a relayer from a hot wallet

  • Use a separate signer for relayer submissions with strict withdrawal constraints

  • Use a hardened enclave (e.g., Intel SGX, Nitro Enclave) for private key usage and proof generation

  • Only expose intent intake API behind a proxy with IP allowlists or mutual TLS


3. Encrypted Message Queue

Relayers must never expose decrypted user intents. Every message received is:

  1. Encrypted with user’s ephemeral key using X25519 → AES-256-GCM

  2. Timestamped using a cryptographic nonce (Poseidon or SHA256-DRBG)

  3. Stored in a local ring buffer or Redis queue

  4. Cleared only after:

    • Proof is successfully posted

    • A TTL (time-to-live) threshold is exceeded

Queue Structure (encrypted):

{
  "intent_id": "0xposeidonhash",
  "payload": "base64-encoded ciphertext",
  "timestamp": 1717612822,
  "ttl": 120,
  "ephemeral_pubkey": "0x...",
  "circuit_version": "v1.3.4"
}

Relayers must not inspect or log decrypted messages, even for debugging.


4. Match Loop Logic

The core of the relayer runs a continuous loop:

while (true) {
  const intents = pullEncryptedQueue();
  const decrypted = decryptIntents(intents);
  const matches = findValidMatches(decrypted);
  const witness = generateWitness(matches);
  const proof = groth16.prove(witness);
  const calldata = formatCalldata(proof);
  submitToVerifier(calldata);
}
  • Matching must validate:

    • Notional equivalence

    • Margin ratio

    • Leverage bounds

    • Intent freshness

  • All matches are run through the circuit-defined MatchValidityCircuit


5. Proof Lifecycle

User Intent → Encrypted Message Queue → Relayer → Matching →
Witness Generation → Groth16 Prover → Batch Merkle Root →
Verifier.sol → Compressed on-chain record
  • Relayers must maintain a local Merkle tree for state commitments

  • Relayer can be challenged if batch commitment mismatches generated root

  • Proof caching must use ephemeral disk (e.g., /tmp) to avoid trace artifacts


6. Uptime Monitoring

To incentivize honest relayer performance, SnarkSide tracks:

  • Match frequency per relayer identity

  • Proof success/failure rate

  • Time-to-batch latency

  • Encrypted queue throughput

Future releases will include:

  • Bonded stake slashing for proof failures

  • zk-SLA attestations (Service Level Proofs)

  • Decentralized relayer rotation with MPC fallback


7. Deployment Tips

  • Prefer containerization via Docker with host resource limits

  • Separate intent ingestion from match+proof generation via internal RPC

  • Run proof generation in GPU-enabled environments if available (e.g., CUDA zkSNARK variants)

  • Use rate limiting and intent deduplication to avoid DoS by spam


8. Sample Config Skeleton

relayer:
  id: snarkside-mainnet-relayer-01
  rpc_url: https://mainnet.l2.rpc
  verifier_contract: 0xabc...
  circuit_hash: 0xposeidonhash
  encryption_key: $QUEUE_ENCRYPTION_KEY
  max_batch_size: 64
  match_interval_ms: 1500
  prover: local
  proof_cache: /tmp/proofs
  log_level: info
  metrics:
    enable: true
    endpoint: /metrics

9. Local Testing

yarn start:relayer
yarn test:match-simulation
yarn test:proof-submit

Tests will:

  • Simulate encrypted intent injection

  • Match mock trades

  • Generate Groth16 proof using dummy circuit

  • Post proof to testnet verifier with dry-run


Conclusion

Running a relayer for SnarkSide is a high-responsibility, cryptographically sensitive task. It requires consistent uptime, verifiable honesty, and strict adherence to privacy principles. Operators are rewarded not for visibility—but for silent accuracy, zero-leak performance, and provable output.

Last updated