Skip to content

Latest commit

 

History

History
365 lines (259 loc) · 11.2 KB

File metadata and controls

365 lines (259 loc) · 11.2 KB

Synapse Core — Setup Guide

This guide walks through setting up a local development environment, running the service, and deploying with Docker.

For an overview of the system design and module responsibilities, see architecture.md.


Automated Setup (Recommended)

The fastest way to get started is the setup script, which handles prerequisites checking, environment configuration, Docker services, migrations, and a health check in one command:

./scripts/setup.sh

To wipe all existing data and start completely fresh:

./scripts/setup.sh --reset

The script will:

  • Verify Rust, Docker, and psql are installed
  • Copy .env.example.failover.env if no .env exists
  • Start PostgreSQL and Redis via Docker Compose
  • Wait for both services to pass their health checks
  • Install sqlx-cli if needed and run all migrations
  • Print next steps to start the server

If you prefer to set things up manually, follow the steps below.


Prerequisites

Tool Version Installation
Rust 1.84+ (stable) rustup.rs
PostgreSQL 14+ Via Docker (recommended) or native install
Docker 20+ docker.com
sqlx-cli 0.7+ cargo install sqlx-cli

1. Clone the Repository

git clone https://github.com/synapse-bridgez/synapse-core.git
cd synapse-core

2. Environment Variables

Copy the example env file and customize:

cp .env.example .env
Variable Required Default Description
DATABASE_URL PostgreSQL connection string
SERVER_PORT 3000 Port for the HTTP server
STELLAR_HORIZON_URL Stellar Horizon API endpoint

Example .env:

SERVER_PORT=3000
DATABASE_URL=postgres://synapse:synapse@localhost:5432/synapse
STELLAR_HORIZON_URL=https://horizon-testnet.stellar.org

3. Database Setup

Option A: Docker (Recommended)

Start a PostgreSQL container:

docker run --name synapse-postgres \
  -e POSTGRES_USER=synapse \
  -e POSTGRES_PASSWORD=synapse \
  -e POSTGRES_DB=synapse \
  -p 5432:5432 \
  -d postgres:14-alpine

Verify it's running:

docker exec -it synapse-postgres pg_isready -U synapse

Option B: Native PostgreSQL

If you have PostgreSQL installed locally:

createuser synapse --password  # enter "synapse" when prompted
createdb synapse --owner=synapse

Update DATABASE_URL in .env to match your local credentials.


4. Run Database Migrations

Migrations run automatically when the app starts. To run them manually:

cargo install sqlx-cli  # if not already installed
sqlx migrate run

The migration file migrations/20250216000000_init.sql creates the transactions table and indexes. See architecture.md for the full schema.


5. Build & Run

Development

cargo run

You should see output like:

INFO  synapse_core > Database migrations completed
INFO  synapse_core > listening on 0.0.0.0:3000

Release Build

cargo build --release
./target/release/synapse-core

Verify

curl http://localhost:3000/health
# => OK

6. Running Tests

Create a Test Database

docker exec -it synapse-postgres psql -U synapse -c "CREATE DATABASE synapse_test;"

Run Tests

DATABASE_URL=postgres://synapse:synapse@localhost:5432/synapse_test cargo test

Note: Some warnings about unused imports or dead code are expected — they correspond to features planned for future issues.

Integration Tests (tests/)

Integration tests built on tests/common::TestApp (health checks, lifecycle, PITR restore, etc.) need their own Postgres/Redis. TestApp::new() looks for infra in this order:

  1. TEST_DATABASE_URL / TEST_REDIS_URL, if set — reuses whatever you already have running.
  2. A fresh testcontainers Postgres, if Docker is reachable (Redis is not auto-started this way — see below).
  3. Otherwise it fails fast with a message naming exactly what's missing and how to fix it.

For iterative local runs, start the stack once and point tests at it instead of paying the testcontainer startup cost (container create + Postgres boot) on every test binary:

docker compose up -d postgres redis

TEST_DATABASE_URL=postgres://synapse:synapse@localhost:5432/synapse \
TEST_REDIS_URL=redis://localhost:6379 \
cargo test

This makes a real difference: each #[tokio::test] in health_check_test.rs calls TestApp::new() independently, so on a Docker-only fallback every test pays for its own Postgres container. Measured locally, cargo test --test health_check_test went from ~61s (fresh testcontainer per test) to ~9s (reusing docker compose up -d postgres redis). If you don't set TEST_DATABASE_URL/TEST_REDIS_URL and don't have Docker running, tests fail fast with a message naming exactly what's missing instead of a raw testcontainers or Docker-daemon error.

Lint & Format

cargo fmt -- --check   # check formatting
cargo fmt              # auto-format
cargo clippy           # lint

7. Docker Compose (Full Stack)

Spin up both PostgreSQL and the application:

docker compose up --build

This starts:

Service Container Port Description
postgres synapse-postgres 5432 PostgreSQL 14 Alpine
app synapse-app 3000 synapse-core server

The app waits for PostgreSQL's health check to pass before starting. Migrations run automatically on boot.

To stop:

docker compose down

To also remove the database volume:

docker compose down -v

8. Docker Compose (Development — Hot Reload)

The dev compose file mounts source code as volumes and uses cargo-watch to rebuild on file changes.

docker compose -f docker-compose.dev.yml up

This starts:

Service Container Port Description
postgres synapse-postgres-dev 5432 PostgreSQL 14 Alpine
redis synapse-redis-dev 6379 Redis 7 Alpine
adminer synapse-adminer 8080 Adminer database UI
app synapse-app-dev 3000 synapse-core with hot-reload

Hot reload: Any change to a file under src/ or migrations/ triggers an automatic recompile and restart via cargo-watch. The first startup is slow (compiling from scratch); subsequent reloads are fast.

Database UI: Open http://localhost:8080 in your browser. Use these credentials:

  • System: PostgreSQL
  • Server: postgres
  • Username: synapse
  • Password: synapse
  • Database: synapse

Debug port: Port 9229 is exposed for IDE debugger attachment (lldb-server / rust-gdb). Configure your IDE to connect to localhost:9229.

Cargo cache: The cargo_registry, cargo_git, and target_cache Docker volumes persist the build cache between restarts, so you only pay the full compile cost once.

To stop and remove dev containers:

docker compose -f docker-compose.dev.yml down

To also wipe the build cache volumes (forces a full recompile next time):

docker compose -f docker-compose.dev.yml down -v

9. Docker (Standalone)

Build the image manually:

docker build -t synapse-core .

Run it (assumes PostgreSQL is reachable at the given URL):

docker run -p 3000:3000 \
  -e DATABASE_URL=postgres://synapse:synapse@host.docker.internal:5432/synapse \
  -e SERVER_PORT=3000 \
  -e STELLAR_HORIZON_URL=https://horizon-testnet.stellar.org \
  synapse-core

Note: Use host.docker.internal (macOS/Windows) or 172.17.0.1 (Linux) to reach the host machine's PostgreSQL from inside a container.


10. Project Structure

synapse-core/
├── Cargo.toml               # Dependencies and workspace config
├── .env.example              # Example environment variables
├── docker-compose.yml        # Full-stack Docker setup
├── dockerfile                # Multi-stage Rust build
├── migrations/
│   └── 20250216000000_init.sql  # Initial schema migration
├── docs/
│   ├── architecture.md       # System design & module docs
│   └── setup.md              # This file
├── src/
│   ├── main.rs               # Entry point, server setup, migrations
│   ├── config.rs             # Environment variable configuration
│   ├── error.rs              # Custom error types (planned)
│   ├── db/
│   │   ├── mod.rs            # Connection pool creation
│   │   └── models.rs         # Transaction struct & tests
│   ├── handlers/
│   │   ├── mod.rs            # Health check handler
│   │   └── webhook.rs        # Callback handler (planned)
│   ├── services/
│   │   ├── mod.rs            # Service exports (planned)
│   │   └── transaction_processor.rs  # Business logic (planned)
│   └── stellar/
│       ├── mod.rs            # Stellar module exports (planned)
│       └── client.rs         # Horizon API client (planned)
├── tests/
│   └── integration_test.rs   # Integration tests (planned)
└── .github/
    └── workflows/
        └── rust.yml          # CI pipeline

API Endpoints

Method Path Status Description
GET /health ✅ Active Health check — returns "OK"
POST /callback/transaction 🚧 Planned Receive Stellar Anchor Platform webhooks
GET /transactions 🚧 Planned List transactions with pagination
GET /transactions/:id 🚧 Planned Get a single transaction by UUID

Troubleshooting

Problem Solution
DATABASE_URL must be set Ensure .env exists and DATABASE_URL is set
Failed to connect to test DB Create the test DB: CREATE DATABASE synapse_test;
SQLX_OFFLINE errors in CI Run cargo sqlx prepare locally to generate offline query data
Port already in use Change SERVER_PORT in .env or stop the conflicting process
Docker connection refused to Postgres Use host.docker.internal or 172.17.0.1 instead of localhost