v2.1.9 - Rebrand repository, docs, scripts, and tooling from c-relay to c-relay-pg

This commit is contained in:
Laan Tungir
2026-04-02 07:06:41 -04:00
parent 22c943d495
commit 5577b57149
84 changed files with 609 additions and 609 deletions
+11 -11
View File
@@ -1,12 +1,12 @@
# AGENTS.md - AI Agent Integration Guide for Architect Mode # AGENTS.md - AI Agent Integration Guide for Architect Mode
**Project-Specific Information for AI Agents Working with C-Relay in Architect Mode** **Project-Specific Information for AI Agents Working with C-Relay-PG in Architect Mode**
## Critical Architecture Understanding ## Critical Architecture Understanding
### System Architecture Overview ### System Architecture Overview
C-Relay implements a **unique event-based configuration architecture** that fundamentally differs from traditional Nostr relays: C-Relay-PG implements a **unique event-based configuration architecture** that fundamentally differs from traditional Nostr relays:
``` ```
┌─────────────────┐ ┌──────────────────┐ ┌─────────────────┐ ┌─────────────────┐ ┌──────────────────┐ ┌─────────────────┐
@@ -51,9 +51,9 @@ C-Relay implements a **unique event-based configuration architecture** that fund
## Architectural Decision Analysis ## Architectural Decision Analysis
### Configuration System Design ### Configuration System Design
**Traditional Approach vs C-Relay:** **Traditional Approach vs C-Relay-PG:**
``` ```
Traditional: C-Relay: Traditional: C-Relay-PG:
config.json → kind 33334 events config.json → kind 33334 events
ENV variables → cryptographically signed tags ENV variables → cryptographically signed tags
File watching → database polling/restart File watching → database polling/restart
@@ -119,18 +119,18 @@ File watching → database polling/restart
``` ```
Developer Machine: Developer Machine:
├── ./make_and_restart_relay.sh ├── ./make_and_restart_relay.sh
├── build/c_relay_x86 ├── build/c_relay_pg_x86
├── build/<relay_pubkey>.db ├── build/<relay_pubkey>.db
└── relay.log └── relay.log
``` ```
### Production SystemD Deployment ### Production SystemD Deployment
``` ```
/opt/c-relay/: /opt/c-relay-pg/:
├── c_relay_x86 ├── c_relay_pg_x86
├── <relay_pubkey>.db ├── <relay_pubkey>.db
├── systemd service (c-relay.service) ├── systemd service (c-relay-pg.service)
└── c-relay user isolation └── c-relay-pg user isolation
``` ```
### Container Deployment Architecture ### Container Deployment Architecture
@@ -144,7 +144,7 @@ Container:
### Reverse Proxy Architecture ### Reverse Proxy Architecture
``` ```
Internet → Nginx/HAProxy → C-Relay Internet → Nginx/HAProxy → C-Relay-PG
├── WebSocket upgrade handling ├── WebSocket upgrade handling
├── SSL termination ├── SSL termination
└── Rate limiting └── Rate limiting
@@ -292,7 +292,7 @@ Admin Signs Event → WebSocket Submit → Validate → Store → Restart Requir
**Decision**: Same port serves both protocols **Decision**: Same port serves both protocols
**Consequences**: Simplified deployment, protocol detection overhead, libwebsockets dependency **Consequences**: Simplified deployment, protocol detection overhead, libwebsockets dependency
These architectural decisions form the foundation of C-Relay's unique approach to Nostr relay implementation and should be carefully considered when planning extensions or modifications. These architectural decisions form the foundation of C-Relay-PG's unique approach to Nostr relay implementation and should be carefully considered when planning extensions or modifications.
** **
[Response interrupted by a tool use result. Only one tool may be used at a time and should be placed at the end of the message.] [Response interrupted by a tool use result. Only one tool may be used at a time and should be placed at the end of the message.]
+8 -8
View File
@@ -1,6 +1,6 @@
# AGENTS.md - AI Agent Integration Guide # AGENTS.md - AI Agent Integration Guide
**Project-Specific Information for AI Agents Working with C-Relay** **Project-Specific Information for AI Agents Working with C-Relay-PG**
## Critical Build Commands ## Critical Build Commands
@@ -15,9 +15,9 @@
- Starts relay in background with proper logging - Starts relay in background with proper logging
### Architecture-Specific Binary Outputs ### Architecture-Specific Binary Outputs
- **x86_64**: `./build/c_relay_x86` - **x86_64**: `./build/c_relay_pg_x86`
- **ARM64**: `./build/c_relay_arm64` - **ARM64**: `./build/c_relay_pg_arm64`
- **Other**: `./build/c_relay_$(ARCH)` - **Other**: `./build/c_relay_pg_$(ARCH)`
### Database File Naming Convention ### Database File Naming Convention
- **Format**: `<relay_pubkey>.db` (NOT `.nrdb` as shown in docs) - **Format**: `<relay_pubkey>.db` (NOT `.nrdb` as shown in docs)
@@ -75,10 +75,10 @@
### Process Management ### Process Management
```bash ```bash
# Kill existing relay processes # Kill existing relay processes
pkill -f "c_relay_" pkill -f "c_relay_pg_"
# Check running processes # Check running processes
ps aux | grep c_relay_ ps aux | grep c_relay_pg_
# Force kill port binding # Force kill port binding
fuser -k 8888/tcp fuser -k 8888/tcp
@@ -95,7 +95,7 @@ fuser -k 8888/tcp
- Event configuration tests: `tests/event_config_tests.sh` - Event configuration tests: `tests/event_config_tests.sh`
### SystemD Integration Considerations ### SystemD Integration Considerations
- Service runs as `c-relay` user in `/opt/c-relay` - Service runs as `c-relay-pg` user in `/opt/c-relay-pg`
- Database files created in WorkingDirectory automatically - Database files created in WorkingDirectory automatically
- No environment variables needed (event-based config) - No environment variables needed (event-based config)
- Resource limits: 65536 file descriptors, 4096 processes - Resource limits: 65536 file descriptors, 4096 processes
@@ -137,7 +137,7 @@ fuser -k 8888/tcp
## Quick Debugging Commands ## Quick Debugging Commands
```bash ```bash
# Check relay status # Check relay status
ps aux | grep c_relay_ && netstat -tln | grep 8888 ps aux | grep c_relay_pg_ && netstat -tln | grep 8888
# View logs # View logs
tail -f relay.log tail -f relay.log
+9 -9
View File
@@ -1,6 +1,6 @@
# C-Relay API Documentation # C-Relay-PG API Documentation
Complete API reference for the C-Relay event-based administration system and advanced features. Complete API reference for the C-Relay-PG event-based administration system and advanced features.
## Table of Contents ## Table of Contents
@@ -21,7 +21,7 @@ Complete API reference for the C-Relay event-based administration system and adv
## Overview ## Overview
C-Relay uses an innovative **event-based administration system** where all configuration and management commands are sent as cryptographically signed Nostr events. This provides: C-Relay-PG uses an innovative **event-based administration system** where all configuration and management commands are sent as cryptographically signed Nostr events. This provides:
- **Cryptographic security**: All commands must be signed with the admin private key - **Cryptographic security**: All commands must be signed with the admin private key
- **Audit trail**: Complete history of all administrative actions - **Audit trail**: Complete history of all administrative actions
@@ -63,8 +63,8 @@ Store the admin private key securely:
export C_RELAY_ADMIN_KEY="nsec1abc123..." export C_RELAY_ADMIN_KEY="nsec1abc123..."
# Secure file # Secure file
echo "nsec1abc123..." > ~/.c-relay-admin echo "nsec1abc123..." > ~/.c-relay-pg-admin
chmod 600 ~/.c-relay-admin chmod 600 ~/.c-relay-pg-admin
# Password manager (recommended) # Password manager (recommended)
# Store in 1Password, Bitwarden, etc. # Store in 1Password, Bitwarden, etc.
@@ -167,7 +167,7 @@ Examples:
"data": [ "data": [
{ {
"key": "relay_name", "key": "relay_name",
"value": "C-Relay", "value": "C-Relay-PG",
"data_type": "string", "data_type": "string",
"category": "relay", "category": "relay",
"description": "Relay name displayed in NIP-11" "description": "Relay name displayed in NIP-11"
@@ -506,10 +506,10 @@ ORDER BY count DESC
| Key | Type | Default | Description | | Key | Type | Default | Description |
|-----|------|---------|-------------| |-----|------|---------|-------------|
| `relay_name` | string | "C-Relay" | Relay name (NIP-11) | | `relay_name` | string | "C-Relay-PG" | Relay name (NIP-11) |
| `relay_description` | string | "C Nostr Relay" | Relay description | | `relay_description` | string | "C Nostr Relay" | Relay description |
| `relay_contact` | string | "" | Admin contact info | | `relay_contact` | string | "" | Admin contact info |
| `relay_software` | string | "c-relay" | Software identifier | | `relay_software` | string | "c-relay-pg" | Software identifier |
| `relay_version` | string | auto | Software version | | `relay_version` | string | auto | Software version |
| `supported_nips` | string | "1,9,11,13,15,20,33,40,42,45,50,70" | Supported NIPs | | `supported_nips` | string | "1,9,11,13,15,20,33,40,42,45,50,70" | Supported NIPs |
| `language_tags` | string | "*" | Supported languages | | `language_tags` | string | "*" | Supported languages |
@@ -576,7 +576,7 @@ ORDER BY count DESC
## Real-time Monitoring ## Real-time Monitoring
C-Relay provides subscription-based real-time monitoring using ephemeral events (kind 24567). C-Relay-PG provides subscription-based real-time monitoring using ephemeral events (kind 24567).
### Activation ### Activation
+9 -9
View File
@@ -1,4 +1,4 @@
# Alpine-based MUSL static binary builder for C-Relay # Alpine-based MUSL static binary builder for C-Relay-PG
# Produces truly portable binaries with zero runtime dependencies # Produces truly portable binaries with zero runtime dependencies
ARG DEBUG_BUILD=false ARG DEBUG_BUILD=false
@@ -95,11 +95,11 @@ RUN cd nostr_core_lib && \
rm -f *.o *.a 2>/dev/null || true && \ rm -f *.o *.a 2>/dev/null || true && \
./build.sh --nips=1,6,13,17,19,44,59 ./build.sh --nips=1,6,13,17,19,44,59
# Copy c-relay source files LAST (only this layer rebuilds on source changes) # Copy c-relay-pg source files LAST (only this layer rebuilds on source changes)
COPY src/ /build/src/ COPY src/ /build/src/
COPY Makefile /build/Makefile COPY Makefile /build/Makefile
# Build c-relay with full static linking (only rebuilds when src/ changes) # Build c-relay-pg with full static linking (only rebuilds when src/ changes)
# Disable fortification to avoid __*_chk symbols that don't exist in MUSL # Disable fortification to avoid __*_chk symbols that don't exist in MUSL
# Use conditional compilation flags based on DEBUG_BUILD argument # Use conditional compilation flags based on DEBUG_BUILD argument
RUN if [ "$DEBUG_BUILD" = "true" ]; then \ RUN if [ "$DEBUG_BUILD" = "true" ]; then \
@@ -108,7 +108,7 @@ RUN if [ "$DEBUG_BUILD" = "true" ]; then \
echo "Building with DEBUG symbols enabled (optimized with -O2)"; \ echo "Building with DEBUG symbols enabled (optimized with -O2)"; \
else \ else \
CFLAGS="-O2"; \ CFLAGS="-O2"; \
STRIP_CMD="strip /build/c_relay_static"; \ STRIP_CMD="strip /build/c_relay_pg_static"; \
echo "Building optimized production binary (symbols stripped)"; \ echo "Building optimized production binary (symbols stripped)"; \
fi && \ fi && \
gcc -static $CFLAGS -Wall -Wextra -std=c99 \ gcc -static $CFLAGS -Wall -Wextra -std=c99 \
@@ -119,7 +119,7 @@ RUN if [ "$DEBUG_BUILD" = "true" ]; then \
src/nip009.c src/nip011.c src/nip013.c src/nip040.c src/nip042.c \ src/nip009.c src/nip011.c src/nip013.c src/nip040.c src/nip042.c \
src/websockets.c src/subscriptions.c src/api.c src/embedded_web_content.c src/ip_ban.c \ src/websockets.c src/subscriptions.c src/api.c src/embedded_web_content.c src/ip_ban.c \
src/db_ops.c src/thread_pool.c \ src/db_ops.c src/thread_pool.c \
-o /build/c_relay_static \ -o /build/c_relay_pg_static \
c_utils_lib/libc_utils.a \ c_utils_lib/libc_utils.a \
nostr_core_lib/libnostr_core_x64.a \ nostr_core_lib/libnostr_core_x64.a \
-lwebsockets -lssl -lcrypto -lsqlite3 -lsecp256k1 \ -lwebsockets -lssl -lcrypto -lsqlite3 -lsecp256k1 \
@@ -128,12 +128,12 @@ RUN if [ "$DEBUG_BUILD" = "true" ]; then \
# Verify it's truly static # Verify it's truly static
RUN echo "=== Binary Information ===" && \ RUN echo "=== Binary Information ===" && \
file /build/c_relay_static && \ file /build/c_relay_pg_static && \
ls -lh /build/c_relay_static && \ ls -lh /build/c_relay_pg_static && \
echo "=== Checking for dynamic dependencies ===" && \ echo "=== Checking for dynamic dependencies ===" && \
(ldd /build/c_relay_static 2>&1 || echo "Binary is static") && \ (ldd /build/c_relay_pg_static 2>&1 || echo "Binary is static") && \
echo "=== Build complete ===" echo "=== Build complete ==="
# Output stage - just the binary # Output stage - just the binary
FROM scratch AS output FROM scratch AS output
COPY --from=builder /build/c_relay_static /c_relay_static COPY --from=builder /build/c_relay_pg_static /c_relay_pg_static
+20 -20
View File
@@ -1,4 +1,4 @@
# C-Relay Makefile # C-Relay-PG Makefile
CC = gcc CC = gcc
CFLAGS = -Wall -Wextra -std=c99 -g -O2 CFLAGS = -Wall -Wextra -std=c99 -g -O2
@@ -16,13 +16,13 @@ C_UTILS_LIB = c_utils_lib/libc_utils.a
# Architecture detection # Architecture detection
ARCH = $(shell uname -m) ARCH = $(shell uname -m)
ifeq ($(ARCH),x86_64) ifeq ($(ARCH),x86_64)
TARGET = $(BUILD_DIR)/c_relay_x86 TARGET = $(BUILD_DIR)/c_relay_pg_x86
else ifeq ($(ARCH),aarch64) else ifeq ($(ARCH),aarch64)
TARGET = $(BUILD_DIR)/c_relay_arm64 TARGET = $(BUILD_DIR)/c_relay_pg_arm64
else ifeq ($(ARCH),arm64) else ifeq ($(ARCH),arm64)
TARGET = $(BUILD_DIR)/c_relay_arm64 TARGET = $(BUILD_DIR)/c_relay_pg_arm64
else else
TARGET = $(BUILD_DIR)/c_relay_$(ARCH) TARGET = $(BUILD_DIR)/c_relay_pg_$(ARCH)
endif endif
# Default target # Default target
@@ -82,18 +82,18 @@ force-version:
# Build the relay # Build the relay
$(TARGET): $(BUILD_DIR) src/main.h src/sql_schema.h $(MAIN_SRC) $(NOSTR_CORE_LIB) $(C_UTILS_LIB) $(TARGET): $(BUILD_DIR) src/main.h src/sql_schema.h $(MAIN_SRC) $(NOSTR_CORE_LIB) $(C_UTILS_LIB)
@echo "Compiling C-Relay for architecture: $(ARCH)" @echo "Compiling C-Relay-PG for architecture: $(ARCH)"
$(CC) $(CFLAGS) $(INCLUDES) $(MAIN_SRC) -o $(TARGET) $(NOSTR_CORE_LIB) $(C_UTILS_LIB) $(LIBS) $(CC) $(CFLAGS) $(INCLUDES) $(MAIN_SRC) -o $(TARGET) $(NOSTR_CORE_LIB) $(C_UTILS_LIB) $(LIBS)
@echo "Build complete: $(TARGET)" @echo "Build complete: $(TARGET)"
# Build for specific architectures # Build for specific architectures
x86: $(BUILD_DIR) src/main.h src/sql_schema.h $(MAIN_SRC) $(NOSTR_CORE_LIB) $(C_UTILS_LIB) x86: $(BUILD_DIR) src/main.h src/sql_schema.h $(MAIN_SRC) $(NOSTR_CORE_LIB) $(C_UTILS_LIB)
@echo "Building C-Relay for x86_64..." @echo "Building C-Relay-PG for x86_64..."
$(CC) $(CFLAGS) $(INCLUDES) $(MAIN_SRC) -o $(BUILD_DIR)/c_relay_x86 $(NOSTR_CORE_LIB) $(C_UTILS_LIB) $(LIBS) $(CC) $(CFLAGS) $(INCLUDES) $(MAIN_SRC) -o $(BUILD_DIR)/c_relay_pg_x86 $(NOSTR_CORE_LIB) $(C_UTILS_LIB) $(LIBS)
@echo "Build complete: $(BUILD_DIR)/c_relay_x86" @echo "Build complete: $(BUILD_DIR)/c_relay_pg_x86"
arm64: $(BUILD_DIR) src/main.h src/sql_schema.h $(MAIN_SRC) $(NOSTR_CORE_LIB) $(C_UTILS_LIB) arm64: $(BUILD_DIR) src/main.h src/sql_schema.h $(MAIN_SRC) $(NOSTR_CORE_LIB) $(C_UTILS_LIB)
@echo "Cross-compiling C-Relay for ARM64..." @echo "Cross-compiling C-Relay-PG for ARM64..."
@if ! command -v aarch64-linux-gnu-gcc >/dev/null 2>&1; then \ @if ! command -v aarch64-linux-gnu-gcc >/dev/null 2>&1; then \
echo "ERROR: ARM64 cross-compiler not found."; \ echo "ERROR: ARM64 cross-compiler not found."; \
echo "Install with: make install-cross-tools"; \ echo "Install with: make install-cross-tools"; \
@@ -116,9 +116,9 @@ arm64: $(BUILD_DIR) src/main.h src/sql_schema.h $(MAIN_SRC) $(NOSTR_CORE_LIB) $(
fi fi
@echo "Using aarch64-linux-gnu-gcc with ARM64 libraries..." @echo "Using aarch64-linux-gnu-gcc with ARM64 libraries..."
PKG_CONFIG_PATH=/usr/lib/aarch64-linux-gnu/pkgconfig:/usr/share/pkgconfig \ PKG_CONFIG_PATH=/usr/lib/aarch64-linux-gnu/pkgconfig:/usr/share/pkgconfig \
aarch64-linux-gnu-gcc $(CFLAGS) $(INCLUDES) $(MAIN_SRC) -o $(BUILD_DIR)/c_relay_arm64 $(NOSTR_CORE_LIB) $(C_UTILS_LIB) \ aarch64-linux-gnu-gcc $(CFLAGS) $(INCLUDES) $(MAIN_SRC) -o $(BUILD_DIR)/c_relay_pg_arm64 $(NOSTR_CORE_LIB) $(C_UTILS_LIB) \
-L/usr/lib/aarch64-linux-gnu $(LIBS) -L/usr/lib/aarch64-linux-gnu $(LIBS)
@echo "Build complete: $(BUILD_DIR)/c_relay_arm64" @echo "Build complete: $(BUILD_DIR)/c_relay_pg_arm64"
# Install ARM64 cross-compilation dependencies # Install ARM64 cross-compilation dependencies
install-arm64-deps: install-arm64-deps:
@@ -160,7 +160,7 @@ test: $(TARGET)
init-db: init-db:
@echo "Database initialization is now handled automatically when the server starts." @echo "Database initialization is now handled automatically when the server starts."
@echo "The schema is embedded in the binary - no external files needed." @echo "The schema is embedded in the binary - no external files needed."
@echo "To manually recreate database: rm -f db/c_nostr_relay.db && ./build/c_relay_x86" @echo "To manually recreate database: rm -f db/c_nostr_relay.db && ./build/c_relay_pg_x86"
# Clean build artifacts # Clean build artifacts
clean: clean:
@@ -180,7 +180,7 @@ install-deps:
# Help # Help
help: help:
@echo "C-Relay Build System" @echo "C-Relay-PG Build System"
@echo "" @echo ""
@echo "Targets:" @echo "Targets:"
@echo " all Build the relay for current architecture (default)" @echo " all Build the relay for current architecture (default)"
@@ -209,15 +209,15 @@ help:
# Build fully static MUSL binaries using Docker # Build fully static MUSL binaries using Docker
static-musl-x86_64: static-musl-x86_64:
@echo "Building fully static MUSL binary for x86_64..." @echo "Building fully static MUSL binary for x86_64..."
docker buildx build --platform linux/amd64 -f examples/deployment/static-builder.Dockerfile -t c-relay-static-builder-x86_64 --load . docker buildx build --platform linux/amd64 -f examples/deployment/static-builder.Dockerfile -t c-relay-pg-static-builder-x86_64 --load .
docker run --rm -v $(PWD)/build:/output c-relay-static-builder-x86_64 sh -c "cp /c_relay_static_musl_x86_64 /output/" docker run --rm -v $(PWD)/build:/output c-relay-pg-static-builder-x86_64 sh -c "cp /c_relay_pg_static_musl_x86_64 /output/"
@echo "Static binary created: build/c_relay_static_musl_x86_64" @echo "Static binary created: build/c_relay_pg_static_musl_x86_64"
static-musl-arm64: static-musl-arm64:
@echo "Building fully static MUSL binary for ARM64..." @echo "Building fully static MUSL binary for ARM64..."
docker buildx build --platform linux/arm64 -f examples/deployment/static-builder.Dockerfile -t c-relay-static-builder-arm64 --load . docker buildx build --platform linux/arm64 -f examples/deployment/static-builder.Dockerfile -t c-relay-pg-static-builder-arm64 --load .
docker run --rm -v $(PWD)/build:/output c-relay-static-builder-arm64 sh -c "cp /c_relay_static_musl_x86_64 /output/c_relay_static_musl_arm64" docker run --rm -v $(PWD)/build:/output c-relay-pg-static-builder-arm64 sh -c "cp /c_relay_pg_static_musl_x86_64 /output/c_relay_pg_static_musl_arm64"
@echo "Static binary created: build/c_relay_static_musl_arm64" @echo "Static binary created: build/c_relay_pg_static_musl_arm64"
static-musl: static-musl-x86_64 static-musl-arm64 static-musl: static-musl-x86_64 static-musl-arm64
@echo "Built static MUSL binaries for both architectures" @echo "Built static MUSL binaries for both architectures"
+6 -6
View File
@@ -45,21 +45,21 @@ Also included is a more standard administrative web front end. This front end co
## Screenshots ## Screenshots
![](https://git.laantungir.net/laantungir/c-relay/raw/branch/master/screenshots/main.png) ![](https://git.laantungir.net/laantungir/c-relay-pg/raw/branch/master/screenshots/main.png)
Main page with real time updates. Main page with real time updates.
![](https://git.laantungir.net/laantungir/c-relay/raw/branch/master/screenshots/config.png) ![](https://git.laantungir.net/laantungir/c-relay-pg/raw/branch/master/screenshots/config.png)
Set your configuration preferences. Set your configuration preferences.
![](https://git.laantungir.net/laantungir/c-relay/raw/branch/master/screenshots/subscriptions.png) ![](https://git.laantungir.net/laantungir/c-relay-pg/raw/branch/master/screenshots/subscriptions.png)
View current subscriptions View current subscriptions
![](https://git.laantungir.net/laantungir/c-relay/raw/branch/master/screenshots/white-blacklists.png) ![](https://git.laantungir.net/laantungir/c-relay-pg/raw/branch/master/screenshots/white-blacklists.png)
Add npubs to white or black lists. Add npubs to white or black lists.
![](https://git.laantungir.net/laantungir/c-relay/raw/branch/master/screenshots/sqlQuery.png) ![](https://git.laantungir.net/laantungir/c-relay-pg/raw/branch/master/screenshots/sqlQuery.png)
Run sql queries on the database. Run sql queries on the database.
![](https://git.laantungir.net/laantungir/c-relay/raw/branch/master/screenshots/main-light.png) ![](https://git.laantungir.net/laantungir/c-relay-pg/raw/branch/master/screenshots/main-light.png)
Light mode. Light mode.
+24 -24
View File
@@ -1,11 +1,11 @@
# C-Relay: High-Performance Nostr Relay # C-Relay-PG: High-Performance Nostr Relay
A blazingly fast, production-ready Nostr relay implemented in C with an innovative event-based configuration system. Built for performance, security, and ease of deployment. A blazingly fast, production-ready Nostr relay implemented in C with an innovative event-based configuration system. Built for performance, security, and ease of deployment.
## 🚀 Why C-Relay? ## 🚀 Why C-Relay-PG?
### Event-Based Configuration ### Event-Based Configuration
Unlike traditional relays that require config files, C-Relay uses **cryptographically signed Nostr events** for all configuration. This means: Unlike traditional relays that require config files, C-Relay-PG uses **cryptographically signed Nostr events** for all configuration. This means:
- **Zero config files** - Everything stored in the database - **Zero config files** - Everything stored in the database
- **Real-time updates** - Changes applied instantly without restart - **Real-time updates** - Changes applied instantly without restart
- **Cryptographic security** - All changes must be signed by admin - **Cryptographic security** - All changes must be signed by admin
@@ -36,7 +36,7 @@ Control your relay by sending direct messages from any Nostr client:
## 📋 Supported NIPs ## 📋 Supported NIPs
C-Relay implements a comprehensive set of Nostr Improvement Proposals: C-Relay-PG implements a comprehensive set of Nostr Improvement Proposals:
-**NIP-01**: Basic protocol flow implementation -**NIP-01**: Basic protocol flow implementation
-**NIP-09**: Event deletion -**NIP-09**: Event deletion
@@ -89,12 +89,12 @@ Download and run - no dependencies required:
```bash ```bash
# Download the latest static release # Download the latest static release
wget https://git.laantungir.net/laantungir/c-relay/releases/download/v0.6.0/c-relay-v0.6.0-linux-x86_64-static wget https://git.laantungir.net/laantungir/c-relay-pg/releases/download/v0.6.0/c-relay-pg-v0.6.0-linux-x86_64-static
chmod +x c-relay-v0.6.0-linux-x86_64-static chmod +x c-relay-pg-v0.6.0-linux-x86_64-static
mv c-relay-v0.6.0-linux-x86_64-static c-relay mv c-relay-pg-v0.6.0-linux-x86_64-static c-relay-pg
# Run the relay # Run the relay
./c-relay ./c-relay-pg
``` ```
**Important**: On first startup, save the **Admin Private Key** displayed in the console. You'll need it for all administrative operations. **Important**: On first startup, save the **Admin Private Key** displayed in the console. You'll need it for all administrative operations.
@@ -107,8 +107,8 @@ sudo apt install -y build-essential git sqlite3 libsqlite3-dev \
libwebsockets-dev libssl-dev libsecp256k1-dev libcurl4-openssl-dev zlib1g-dev libwebsockets-dev libssl-dev libsecp256k1-dev libcurl4-openssl-dev zlib1g-dev
# Clone and build # Clone and build
git clone https://github.com/your-org/c-relay.git git clone https://github.com/your-org/c-relay-pg.git
cd c-relay cd c-relay-pg
git submodule update --init --recursive git submodule update --init --recursive
./make_and_restart_relay.sh ./make_and_restart_relay.sh
``` ```
@@ -136,8 +136,8 @@ The web interface provides:
```bash ```bash
# Clone repository # Clone repository
git clone https://github.com/your-org/c-relay.git git clone https://github.com/your-org/c-relay-pg.git
cd c-relay cd c-relay-pg
git submodule update --init --recursive git submodule update --init --recursive
# Build # Build
@@ -147,25 +147,25 @@ make clean && make
sudo systemd/install-service.sh sudo systemd/install-service.sh
# Start and enable # Start and enable
sudo systemctl start c-relay sudo systemctl start c-relay-pg
sudo systemctl enable c-relay sudo systemctl enable c-relay-pg
# Capture admin keys from logs # Capture admin keys from logs
sudo journalctl -u c-relay | grep "Admin Private Key" sudo journalctl -u c-relay-pg | grep "Admin Private Key"
``` ```
### Docker Deployment ### Docker Deployment
```bash ```bash
# Build Docker image # Build Docker image
docker build -f Dockerfile.alpine-musl -t c-relay . docker build -f Dockerfile.alpine-musl -t c-relay-pg .
# Run container # Run container
docker run -d \ docker run -d \
--name c-relay \ --name c-relay-pg \
-p 8888:8888 \ -p 8888:8888 \
-v /path/to/data:/data \ -v /path/to/data:/data \
c-relay c-relay-pg
``` ```
### Cloud Deployment ### Cloud Deployment
@@ -181,7 +181,7 @@ See [`docs/deployment_guide.md`](docs/deployment_guide.md) for detailed deployme
## 🔧 Configuration ## 🔧 Configuration
C-Relay uses an innovative event-based configuration system. All settings are managed through signed Nostr events. C-Relay-PG uses an innovative event-based configuration system. All settings are managed through signed Nostr events.
### Basic Configuration ### Basic Configuration
@@ -239,8 +239,8 @@ The admin private key is displayed **only once** during first startup. Store it
```bash ```bash
# Save to secure location # Save to secure location
echo "ADMIN_PRIVKEY=your_admin_private_key" > ~/.c-relay-admin echo "ADMIN_PRIVKEY=your_admin_private_key" > ~/.c-relay-pg-admin
chmod 600 ~/.c-relay-admin chmod 600 ~/.c-relay-pg-admin
``` ```
### Production Security ### Production Security
@@ -269,9 +269,9 @@ Contributions are welcome! Please:
## 🔗 Links ## 🔗 Links
- **Repository**: [https://github.com/your-org/c-relay](https://github.com/your-org/c-relay) - **Repository**: [https://github.com/your-org/c-relay-pg](https://github.com/your-org/c-relay-pg)
- **Releases**: [https://git.laantungir.net/laantungir/c-relay/releases](https://git.laantungir.net/laantungir/c-relay/releases) - **Releases**: [https://git.laantungir.net/laantungir/c-relay-pg/releases](https://git.laantungir.net/laantungir/c-relay-pg/releases)
- **Issues**: [https://github.com/your-org/c-relay/issues](https://github.com/your-org/c-relay/issues) - **Issues**: [https://github.com/your-org/c-relay-pg/issues](https://github.com/your-org/c-relay-pg/issues)
- **Nostr Protocol**: [https://github.com/nostr-protocol/nostr](https://github.com/nostr-protocol/nostr) - **Nostr Protocol**: [https://github.com/nostr-protocol/nostr](https://github.com/nostr-protocol/nostr)
## 💬 Support ## 💬 Support
+7 -7
View File
@@ -41,7 +41,7 @@ This guide is specifically tailored for C programs that use:
```bash ```bash
# 1. Copy the Dockerfile template (see below) # 1. Copy the Dockerfile template (see below)
cp /path/to/c-relay/Dockerfile.alpine-musl ./Dockerfile.static cp /path/to/c-relay-pg/Dockerfile.alpine-musl ./Dockerfile.static
# 2. Customize for your project (see Customization section) # 2. Customize for your project (see Customization section)
vim Dockerfile.static vim Dockerfile.static
@@ -466,13 +466,13 @@ docker build -t my-app:latest .
docker run --rm my-app:latest --help docker run --rm my-app:latest --help
``` ```
## Reusing c-relay Files ## Reusing c-relay-pg Files
You can directly copy these files from c-relay: You can directly copy these files from c-relay-pg:
### 1. Dockerfile.alpine-musl ### 1. Dockerfile.alpine-musl
```bash ```bash
cp /path/to/c-relay/Dockerfile.alpine-musl ./Dockerfile.static cp /path/to/c-relay-pg/Dockerfile.alpine-musl ./Dockerfile.static
``` ```
Then customize: Then customize:
@@ -482,7 +482,7 @@ Then customize:
### 2. build_static.sh ### 2. build_static.sh
```bash ```bash
cp /path/to/c-relay/build_static.sh ./ cp /path/to/c-relay-pg/build_static.sh ./
``` ```
Then customize: Then customize:
@@ -492,7 +492,7 @@ Then customize:
### 3. .dockerignore (Optional) ### 3. .dockerignore (Optional)
```bash ```bash
cp /path/to/c-relay/.dockerignore ./ cp /path/to/c-relay-pg/.dockerignore ./
``` ```
Helps speed up Docker builds by excluding unnecessary files. Helps speed up Docker builds by excluding unnecessary files.
@@ -522,7 +522,7 @@ Helps speed up Docker builds by excluding unnecessary files.
- [Alpine Linux](https://alpinelinux.org/) - [Alpine Linux](https://alpinelinux.org/)
- [nostr_core_lib](https://github.com/chebizarro/nostr_core_lib) - [nostr_core_lib](https://github.com/chebizarro/nostr_core_lib)
- [Static Linking Best Practices](https://www.musl-libc.org/faq.html) - [Static Linking Best Practices](https://www.musl-libc.org/faq.html)
- [c-relay Implementation](./docs/musl_static_build.md) - [c-relay-pg Implementation](./docs/musl_static_build.md)
## Example: Minimal Nostr Client ## Example: Minimal Nostr Client
+2 -2
View File
@@ -4,7 +4,7 @@
<head> <head>
<meta charset="UTF-8"> <meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>C-Relay Admin</title> <title>C-Relay-PG Admin</title>
<link rel="stylesheet" href="/api/index.css"> <link rel="stylesheet" href="/api/index.css">
</head> </head>
@@ -42,7 +42,7 @@
<span class="relay-letter" data-letter="Y">Y</span> <span class="relay-letter" data-letter="Y">Y</span>
</div> </div>
<div class="relay-info"> <div class="relay-info">
<div id="relay-name" class="relay-name">C-Relay</div> <div id="relay-name" class="relay-name">C-Relay-PG</div>
<div id="relay-description" class="relay-description">Loading...</div> <div id="relay-description" class="relay-description">Loading...</div>
<div id="relay-pubkey-container" class="relay-pubkey-container"> <div id="relay-pubkey-container" class="relay-pubkey-container">
<div id="relay-pubkey" class="relay-pubkey">Loading...</div> <div id="relay-pubkey" class="relay-pubkey">Loading...</div>
+9 -9
View File
@@ -185,7 +185,7 @@ async function fetchRelayInfo(relayUrl) {
method: 'GET', method: 'GET',
headers: { headers: {
'Accept': 'application/nostr+json', 'Accept': 'application/nostr+json',
'User-Agent': 'C-Relay-Admin-API/1.0' 'User-Agent': 'C-Relay-PG-Admin-API/1.0'
}, },
timeout: 10000 // 10 second timeout timeout: 10000 // 10 second timeout
}); });
@@ -454,7 +454,7 @@ async function setupAutomaticRelayConnection(showSections = false) {
// Keep relay metadata (including version) even when pubkey is missing/fallback // Keep relay metadata (including version) even when pubkey is missing/fallback
relayInfoData = { relayInfoData = {
name: relayInfo?.name || 'C-Relay', name: relayInfo?.name || 'C-Relay-PG',
version: relayInfo?.version || '', version: relayInfo?.version || '',
description: relayInfo?.description || 'Nostr Relay', description: relayInfo?.description || 'Nostr Relay',
pubkey: relayPubkey pubkey: relayPubkey
@@ -3963,9 +3963,9 @@ async function testPostEvent() {
created_at: Math.floor(Date.now() / 1000), created_at: Math.floor(Date.now() / 1000),
tags: [ tags: [
["t", "test"], ["t", "test"],
["client", "c-relay-admin-api"] ["client", "c-relay-pg-admin-api"]
], ],
content: `Test event from C-Relay Admin API at ${new Date().toISOString()}` content: `Test event from C-Relay-PG Admin API at ${new Date().toISOString()}`
}; };
logTestEvent('SENT', `Test event (before signing): ${JSON.stringify(testEvent)}`, 'EVENT'); logTestEvent('SENT', `Test event (before signing): ${JSON.stringify(testEvent)}`, 'EVENT');
@@ -4249,7 +4249,7 @@ function updateRelayInfoInHeader() {
// Get relay info from NIP-11/config data or use defaults // Get relay info from NIP-11/config data or use defaults
const relayInfo = getRelayInfo(); const relayInfo = getRelayInfo();
const relayName = relayInfo.name || 'C-Relay'; const relayName = relayInfo.name || 'C-Relay-PG';
const relayVersion = relayInfo.version || ''; const relayVersion = relayInfo.version || '';
const relayDescription = relayInfo.description || 'Nostr Relay'; const relayDescription = relayInfo.description || 'Nostr Relay';
@@ -4292,7 +4292,7 @@ function getRelayInfo() {
// Default values // Default values
return { return {
name: 'C-Relay', name: 'C-Relay-PG',
version: '', version: '',
description: 'Nostr Relay', description: 'Nostr Relay',
pubkey: relayPubkey pubkey: relayPubkey
@@ -4303,7 +4303,7 @@ function getRelayInfo() {
function updateStoredRelayInfo(configData) { function updateStoredRelayInfo(configData) {
if (configData && configData.data) { if (configData && configData.data) {
// Extract relay info from config data // Extract relay info from config data
const relayName = configData.data.find(item => item.key === 'relay_name')?.value || 'C-Relay'; const relayName = configData.data.find(item => item.key === 'relay_name')?.value || 'C-Relay-PG';
const relayVersion = configData.data.find(item => item.key === 'relay_version')?.value || ''; const relayVersion = configData.data.find(item => item.key === 'relay_version')?.value || '';
const relayDescription = configData.data.find(item => item.key === 'relay_description')?.value || 'Nostr Relay'; const relayDescription = configData.data.find(item => item.key === 'relay_description')?.value || 'Nostr Relay';
@@ -5421,7 +5421,7 @@ function switchPage(pageName) {
// Initialize the app // Initialize the app
document.addEventListener('DOMContentLoaded', () => { document.addEventListener('DOMContentLoaded', () => {
console.log('C-Relay Admin API interface loaded'); console.log('C-Relay-PG Admin API interface loaded');
// Initialize dark mode // Initialize dark mode
initializeDarkMode(); initializeDarkMode();
@@ -5523,7 +5523,7 @@ const SQL_QUERY_TEMPLATES = {
}; };
// Query history management (localStorage) // Query history management (localStorage)
const QUERY_HISTORY_KEY = 'c_relay_sql_history'; const QUERY_HISTORY_KEY = 'c_relay_pg_sql_history';
const MAX_HISTORY_ITEMS = 20; const MAX_HISTORY_ITEMS = 20;
// Load query history from localStorage // Load query history from localStorage
+11 -11
View File
@@ -1,6 +1,6 @@
#!/bin/bash #!/bin/bash
# Build fully static MUSL binaries for C-Relay using Alpine Docker # Build fully static MUSL binaries for C-Relay-PG using Alpine Docker
# Produces truly portable binaries with zero runtime dependencies # Produces truly portable binaries with zero runtime dependencies
set -e set -e
@@ -14,11 +14,11 @@ DEBUG_BUILD=false
if [[ "$1" == "--debug" ]]; then if [[ "$1" == "--debug" ]]; then
DEBUG_BUILD=true DEBUG_BUILD=true
echo "==========================================" echo "=========================================="
echo "C-Relay MUSL Static Binary Builder (DEBUG MODE)" echo "C-Relay-PG MUSL Static Binary Builder (DEBUG MODE)"
echo "==========================================" echo "=========================================="
else else
echo "==========================================" echo "=========================================="
echo "C-Relay MUSL Static Binary Builder (PRODUCTION MODE)" echo "C-Relay-PG MUSL Static Binary Builder (PRODUCTION MODE)"
echo "==========================================" echo "=========================================="
fi fi
echo "Project directory: $SCRIPT_DIR" echo "Project directory: $SCRIPT_DIR"
@@ -63,17 +63,17 @@ ARCH=$(uname -m)
case "$ARCH" in case "$ARCH" in
x86_64) x86_64)
PLATFORM="linux/amd64" PLATFORM="linux/amd64"
OUTPUT_NAME="c_relay_static_x86_64" OUTPUT_NAME="c_relay_pg_static_x86_64"
;; ;;
aarch64|arm64) aarch64|arm64)
PLATFORM="linux/arm64" PLATFORM="linux/arm64"
OUTPUT_NAME="c_relay_static_arm64" OUTPUT_NAME="c_relay_pg_static_arm64"
;; ;;
*) *)
echo "WARNING: Unknown architecture: $ARCH" echo "WARNING: Unknown architecture: $ARCH"
echo "Defaulting to linux/amd64" echo "Defaulting to linux/amd64"
PLATFORM="linux/amd64" PLATFORM="linux/amd64"
OUTPUT_NAME="c_relay_static_${ARCH}" OUTPUT_NAME="c_relay_pg_static_${ARCH}"
;; ;;
esac esac
@@ -116,14 +116,14 @@ echo "=========================================="
echo "This will:" echo "This will:"
echo " - Use Alpine Linux (native MUSL)" echo " - Use Alpine Linux (native MUSL)"
echo " - Build all dependencies statically" echo " - Build all dependencies statically"
echo " - Compile c-relay with full static linking" echo " - Compile c-relay-pg with full static linking"
echo "" echo ""
$DOCKER_CMD build \ $DOCKER_CMD build \
--platform "$PLATFORM" \ --platform "$PLATFORM" \
--build-arg DEBUG_BUILD=$DEBUG_BUILD \ --build-arg DEBUG_BUILD=$DEBUG_BUILD \
-f "$DOCKERFILE" \ -f "$DOCKERFILE" \
-t c-relay-musl-builder:latest \ -t c-relay-pg-musl-builder:latest \
--progress=plain \ --progress=plain \
. || { . || {
echo "" echo ""
@@ -147,14 +147,14 @@ $DOCKER_CMD build \
--build-arg DEBUG_BUILD=$DEBUG_BUILD \ --build-arg DEBUG_BUILD=$DEBUG_BUILD \
--target builder \ --target builder \
-f "$DOCKERFILE" \ -f "$DOCKERFILE" \
-t c-relay-static-builder-stage:latest \ -t c-relay-pg-static-builder-stage:latest \
. > /dev/null 2>&1 . > /dev/null 2>&1
# Create a temporary container to copy the binary # Create a temporary container to copy the binary
CONTAINER_ID=$($DOCKER_CMD create c-relay-static-builder-stage:latest) CONTAINER_ID=$($DOCKER_CMD create c-relay-pg-static-builder-stage:latest)
# Copy binary from container # Copy binary from container
$DOCKER_CMD cp "$CONTAINER_ID:/build/c_relay_static" "$BUILD_DIR/$OUTPUT_NAME" || { $DOCKER_CMD cp "$CONTAINER_ID:/build/c_relay_pg_static" "$BUILD_DIR/$OUTPUT_NAME" || {
echo "ERROR: Failed to extract binary from container" echo "ERROR: Failed to extract binary from container"
$DOCKER_CMD rm "$CONTAINER_ID" 2>/dev/null $DOCKER_CMD rm "$CONTAINER_ID" 2>/dev/null
exit 1 exit 1
+4 -4
View File
@@ -1,12 +1,12 @@
#!/bin/bash #!/bin/bash
# Restart the service # Restart the service
sudo systemctl stop c-relay.service sudo systemctl stop c-relay-pg.service
# Copy the binary to the deployment location # Copy the binary to the deployment location
cp build/c_relay_static_x86_64 ~/Storage/c_relay/crelay cp build/c_relay_pg_static_x86_64 ~/Storage/c_relay_pg/crelay
# Restart the service # Restart the service
sudo systemctl restart c-relay.service sudo systemctl restart c-relay-pg.service
# Show service status # Show service status
sudo systemctl status c-relay.service --no-pager -l sudo systemctl status c-relay-pg.service --no-pager -l
+8 -8
View File
@@ -1,24 +1,24 @@
#!/bin/bash #!/bin/bash
# C-Relay Static Binary Deployment Script # C-Relay-PG Static Binary Deployment Script
# Deploys build/c_relay_static_x86_64 to server via ssh # Deploys build/c_relay_pg_static_x86_64 to server via ssh
set -e set -e
# Configuration # Configuration
LOCAL_BINARY="build/c_relay_static_x86_64" LOCAL_BINARY="build/c_relay_pg_static_x86_64"
REMOTE_BINARY_PATH="/usr/local/bin/c_relay/c_relay" REMOTE_BINARY_PATH="/usr/local/bin/c_relay_pg/c_relay_pg"
SERVICE_NAME="c-relay" SERVICE_NAME="c-relay-pg"
# Create backup # Create backup
ssh ubuntu@laantungir.com "sudo cp '$REMOTE_BINARY_PATH' '${REMOTE_BINARY_PATH}.backup.$(date +%Y%m%d_%H%M%S)'" 2>/dev/null || true ssh ubuntu@laantungir.com "sudo cp '$REMOTE_BINARY_PATH' '${REMOTE_BINARY_PATH}.backup.$(date +%Y%m%d_%H%M%S)'" 2>/dev/null || true
# Upload binary to temp location # Upload binary to temp location
scp "$LOCAL_BINARY" "ubuntu@laantungir.com:/tmp/c_relay.tmp" scp "$LOCAL_BINARY" "ubuntu@laantungir.com:/tmp/c_relay_pg.tmp"
# Install binary # Install binary
ssh ubuntu@laantungir.com "sudo mv '/tmp/c_relay.tmp' '$REMOTE_BINARY_PATH'" ssh ubuntu@laantungir.com "sudo mv '/tmp/c_relay_pg.tmp' '$REMOTE_BINARY_PATH'"
ssh ubuntu@laantungir.com "sudo chown c-relay:c-relay '$REMOTE_BINARY_PATH'" ssh ubuntu@laantungir.com "sudo chown c-relay-pg:c-relay-pg '$REMOTE_BINARY_PATH'"
ssh ubuntu@laantungir.com "sudo chmod +x '$REMOTE_BINARY_PATH'" ssh ubuntu@laantungir.com "sudo chmod +x '$REMOTE_BINARY_PATH'"
# Reload systemd and restart service # Reload systemd and restart service
+15 -15
View File
@@ -1,14 +1,14 @@
#!/bin/bash #!/bin/bash
# C-Relay Debug Binary Deployment Script # C-Relay-PG Debug Binary Deployment Script
# Deploys build/c_relay_static_x86_64_debug to server for CPU profiling # Deploys build/c_relay_pg_static_x86_64_debug to server for CPU profiling
# #
# Usage: # Usage:
# ./deploy_lt_debug.sh -- deploy debug binary and restart # ./deploy_lt_debug.sh -- deploy debug binary and restart
# ./deploy_lt_debug.sh --profile -- deploy, then run perf and fetch results # ./deploy_lt_debug.sh --profile -- deploy, then run perf and fetch results
# #
# After deploying, profile with: # After deploying, profile with:
# sudo perf record -g -p $(pgrep c_relay) -- sleep 30 # sudo perf record -g -p $(pgrep c_relay_pg) -- sleep 30
# sudo perf report --stdio --sort=symbol --no-children -n 2>/dev/null | head -80 # sudo perf report --stdio --sort=symbol --no-children -n 2>/dev/null | head -80
# #
# Restore production binary: # Restore production binary:
@@ -16,10 +16,10 @@
set -e set -e
LOCAL_DEBUG_BINARY="build/c_relay_static_x86_64_debug" LOCAL_DEBUG_BINARY="build/c_relay_pg_static_x86_64_debug"
REMOTE_BINARY_PATH="/usr/local/bin/c_relay/c_relay" REMOTE_BINARY_PATH="/usr/local/bin/c_relay_pg/c_relay_pg"
REMOTE_PROD_BACKUP="/usr/local/bin/c_relay/c_relay.production" REMOTE_PROD_BACKUP="/usr/local/bin/c_relay_pg/c_relay_pg.production"
SERVICE_NAME="c-relay" SERVICE_NAME="c-relay-pg"
REMOTE_HOST="ubuntu@laantungir.com" REMOTE_HOST="ubuntu@laantungir.com"
# Check debug binary exists # Check debug binary exists
@@ -33,7 +33,7 @@ if [ ! -f "$LOCAL_DEBUG_BINARY" ]; then
fi fi
echo "==========================================" echo "=========================================="
echo "C-Relay Debug Deployment" echo "C-Relay-PG Debug Deployment"
echo "==========================================" echo "=========================================="
echo "Binary: $LOCAL_DEBUG_BINARY ($(du -h "$LOCAL_DEBUG_BINARY" | cut -f1))" echo "Binary: $LOCAL_DEBUG_BINARY ($(du -h "$LOCAL_DEBUG_BINARY" | cut -f1))"
echo "Target: $REMOTE_HOST:$REMOTE_BINARY_PATH" echo "Target: $REMOTE_HOST:$REMOTE_BINARY_PATH"
@@ -55,18 +55,18 @@ ssh "$REMOTE_HOST" "
# Upload debug binary # Upload debug binary
echo "Uploading debug binary..." echo "Uploading debug binary..."
scp "$LOCAL_DEBUG_BINARY" "$REMOTE_HOST:/tmp/c_relay_debug.tmp" scp "$LOCAL_DEBUG_BINARY" "$REMOTE_HOST:/tmp/c_relay_pg_debug.tmp"
# Install debug binary # Install debug binary
echo "Installing debug binary..." echo "Installing debug binary..."
ssh "$REMOTE_HOST" " ssh "$REMOTE_HOST" "
sudo mv '/tmp/c_relay_debug.tmp' '$REMOTE_BINARY_PATH' sudo mv '/tmp/c_relay_pg_debug.tmp' '$REMOTE_BINARY_PATH'
sudo chown c-relay:c-relay '$REMOTE_BINARY_PATH' sudo chown c-relay-pg:c-relay-pg '$REMOTE_BINARY_PATH'
sudo chmod +x '$REMOTE_BINARY_PATH' sudo chmod +x '$REMOTE_BINARY_PATH'
" "
# Restart service # Restart service
echo "Restarting c-relay service..." echo "Restarting c-relay-pg service..."
ssh "$REMOTE_HOST" "sudo systemctl daemon-reload && sudo systemctl restart '$SERVICE_NAME'" ssh "$REMOTE_HOST" "sudo systemctl daemon-reload && sudo systemctl restart '$SERVICE_NAME'"
echo "" echo ""
@@ -84,9 +84,9 @@ if [ "$1" = "--profile" ]; then
sleep 3 sleep 3
ssh "$REMOTE_HOST" " ssh "$REMOTE_HOST" "
PID=\$(pgrep c_relay) PID=\$(pgrep c_relay_pg)
if [ -z \"\$PID\" ]; then if [ -z \"\$PID\" ]; then
echo 'ERROR: c_relay not running' echo 'ERROR: c_relay_pg not running'
exit 1 exit 1
fi fi
echo \"Profiling PID \$PID for 30 seconds...\" echo \"Profiling PID \$PID for 30 seconds...\"
@@ -101,7 +101,7 @@ else
echo "==========================================" echo "=========================================="
echo "" echo ""
echo "SSH to server and run:" echo "SSH to server and run:"
echo " sudo perf record -g -p \$(pgrep c_relay) -- sleep 30" echo " sudo perf record -g -p \$(pgrep c_relay_pg) -- sleep 30"
echo " sudo perf report --stdio --sort=symbol --no-children -n 2>/dev/null | head -60" echo " sudo perf report --stdio --sort=symbol --no-children -n 2>/dev/null | head -60"
echo "" echo ""
echo "Or run with --profile to do it automatically:" echo "Or run with --profile to do it automatically:"
+2 -2
View File
@@ -1,4 +1,4 @@
# C-Relay Administrator API Implementation Plan # C-Relay-PG Administrator API Implementation Plan
## Problem Analysis ## Problem Analysis
@@ -161,7 +161,7 @@ Would require changing schema, migration scripts, and storage logic.
#### README.md Documentation Format: #### README.md Documentation Format:
```markdown ```markdown
# C-Relay Administrator API # C-Relay-PG Administrator API
## Authentication ## Authentication
All admin commands require signing with the admin private key generated during first startup. All admin commands require signing with the admin private key generated during first startup.
+2 -2
View File
@@ -1,6 +1,6 @@
# Agent Browser Testing Guide for C-Relay # Agent Browser Testing Guide for C-Relay-PG
This document explains how to use the `agent-browser` CLI tool to test the c-relay admin web UI from an AI agent context (no physical display required). This document explains how to use the `agent-browser` CLI tool to test the c-relay-pg admin web UI from an AI agent context (no physical display required).
## Prerequisites ## Prerequisites
+11 -11
View File
@@ -324,7 +324,7 @@ int main() {
} }
``` ```
## Migration Plan for c-relay ## Migration Plan for c-relay-pg
### Phase 1: Extract Debug System ### Phase 1: Extract Debug System
1. Create `c_utils_lib` repository 1. Create `c_utils_lib` repository
@@ -333,16 +333,16 @@ int main() {
4. Add basic tests 4. Add basic tests
### Phase 2: Add Versioning System ### Phase 2: Add Versioning System
1. Extract version generation logic from c-relay 1. Extract version generation logic from c-relay-pg
2. Create reusable version utilities 2. Create reusable version utilities
3. Update c-relay to use new system 3. Update c-relay-pg to use new system
4. Update nostr_core_lib to use new system 4. Update nostr_core_lib to use new system
### Phase 3: Add as Submodule ### Phase 3: Add as Submodule
1. Add `c_utils_lib` as submodule to c-relay 1. Add `c_utils_lib` as submodule to c-relay-pg
2. Update c-relay Makefile 2. Update c-relay-pg Makefile
3. Update includes in c-relay source files 3. Update includes in c-relay-pg source files
4. Remove old debug files from c-relay 4. Remove old debug files from c-relay-pg
### Phase 4: Documentation & Examples ### Phase 4: Documentation & Examples
1. Create comprehensive README 1. Create comprehensive README
@@ -352,7 +352,7 @@ int main() {
## Benefits ## Benefits
### For c-relay ### For c-relay-pg
- Cleaner separation of concerns - Cleaner separation of concerns
- Reusable utilities across projects - Reusable utilities across projects
- Easier to maintain and test - Easier to maintain and test
@@ -379,7 +379,7 @@ int main() {
- Memory leak detection (valgrind) - Memory leak detection (valgrind)
### Integration Tests ### Integration Tests
- Test with real projects (c-relay, nostr_core_lib) - Test with real projects (c-relay-pg, nostr_core_lib)
- Cross-platform testing - Cross-platform testing
- Performance benchmarks - Performance benchmarks
@@ -433,7 +433,7 @@ MIT License - permissive and suitable for learning and commercial use.
## Success Criteria ## Success Criteria
1. ✅ Successfully integrated into c-relay 1. ✅ Successfully integrated into c-relay-pg
2. ✅ Successfully integrated into nostr_core_lib 2. ✅ Successfully integrated into nostr_core_lib
3. ✅ All tests passing 3. ✅ All tests passing
4. ✅ Documentation complete 4. ✅ Documentation complete
@@ -449,7 +449,7 @@ MIT License - permissive and suitable for learning and commercial use.
4. Create build system 4. Create build system
5. Write tests 5. Write tests
6. Create documentation 6. Create documentation
7. Integrate into c-relay 7. Integrate into c-relay-pg
8. Publish to GitHub 8. Publish to GitHub
--- ---
+16 -16
View File
@@ -2,13 +2,13 @@
## Overview ## Overview
This document provides a step-by-step implementation plan for creating the `c_utils_lib` library and integrating it into the c-relay project. This document provides a step-by-step implementation plan for creating the `c_utils_lib` library and integrating it into the c-relay-pg project.
## Phase 1: Repository Setup & Structure ## Phase 1: Repository Setup & Structure
### Step 1.1: Create Repository Structure ### Step 1.1: Create Repository Structure
**Location**: Create outside c-relay project (sibling directory) **Location**: Create outside c-relay-pg project (sibling directory)
```bash ```bash
# Create directory structure # Create directory structure
@@ -42,7 +42,7 @@ git branch -M main
### Step 2.1: Move Debug Files ### Step 2.1: Move Debug Files
**Source files** (from c-relay): **Source files** (from c-relay-pg):
- `src/debug.c``c_utils_lib/src/debug.c` - `src/debug.c``c_utils_lib/src/debug.c`
- `src/debug.h``c_utils_lib/include/c_utils/debug.h` - `src/debug.h``c_utils_lib/include/c_utils/debug.h`
@@ -484,20 +484,20 @@ How to integrate into projects:
3. Code examples 3. Code examples
4. Migration from standalone utilities 4. Migration from standalone utilities
## Phase 7: Integration with c-relay ## Phase 7: Integration with c-relay-pg
### Step 7.1: Add as Submodule ### Step 7.1: Add as Submodule
```bash ```bash
cd /path/to/c-relay cd /path/to/c-relay-pg
git submodule add <repo-url> c_utils_lib git submodule add <repo-url> c_utils_lib
git submodule update --init --recursive git submodule update --init --recursive
``` ```
### Step 7.2: Update c-relay Makefile ### Step 7.2: Update c-relay-pg Makefile
```makefile ```makefile
# Add to c-relay Makefile # Add to c-relay-pg Makefile
C_UTILS_LIB = c_utils_lib/libc_utils.a C_UTILS_LIB = c_utils_lib/libc_utils.a
# Update includes # Update includes
@@ -514,7 +514,7 @@ $(C_UTILS_LIB):
$(TARGET): $(C_UTILS_LIB) ... $(TARGET): $(C_UTILS_LIB) ...
``` ```
### Step 7.3: Update c-relay Source Files ### Step 7.3: Update c-relay-pg Source Files
**Changes needed**: **Changes needed**:
@@ -543,7 +543,7 @@ $(TARGET): $(C_UTILS_LIB) ...
### Step 7.4: Test Integration ### Step 7.4: Test Integration
```bash ```bash
cd c-relay cd c-relay-pg
make clean make clean
make make
./make_and_restart_relay.sh ./make_and_restart_relay.sh
@@ -556,7 +556,7 @@ Verify:
## Phase 8: Version System Integration ## Phase 8: Version System Integration
### Step 8.1: Update c-relay Makefile for Versioning ### Step 8.1: Update c-relay-pg Makefile for Versioning
```makefile ```makefile
# Add version generation # Add version generation
@@ -567,7 +567,7 @@ src/version.h: .git/refs/tags/*
$(TARGET): src/version.h ... $(TARGET): src/version.h ...
``` ```
### Step 8.2: Update c-relay to Use Generated Version ### Step 8.2: Update c-relay-pg to Use Generated Version
Replace hardcoded version in `src/main.h` with: Replace hardcoded version in `src/main.h` with:
```c ```c
@@ -583,7 +583,7 @@ Replace hardcoded version in `src/main.h` with:
- **Phase 4**: Build System - 2 hours - **Phase 4**: Build System - 2 hours
- **Phase 5**: Examples & Tests - 3 hours - **Phase 5**: Examples & Tests - 3 hours
- **Phase 6**: Documentation - 3 hours - **Phase 6**: Documentation - 3 hours
- **Phase 7**: c-relay Integration - 2 hours - **Phase 7**: c-relay-pg Integration - 2 hours
- **Phase 8**: Version Integration - 2 hours - **Phase 8**: Version Integration - 2 hours
**Total**: ~19 hours **Total**: ~19 hours
@@ -593,11 +593,11 @@ Replace hardcoded version in `src/main.h` with:
- [ ] c_utils_lib builds successfully - [ ] c_utils_lib builds successfully
- [ ] All tests pass - [ ] All tests pass
- [ ] Examples compile and run - [ ] Examples compile and run
- [ ] c-relay integrates successfully - [ ] c-relay-pg integrates successfully
- [ ] Debug output works in c-relay - [ ] Debug output works in c-relay-pg
- [ ] Version generation works - [ ] Version generation works
- [ ] Documentation complete - [ ] Documentation complete
- [ ] No regressions in c-relay functionality - [ ] No regressions in c-relay-pg functionality
## Next Steps ## Next Steps
@@ -608,7 +608,7 @@ Replace hardcoded version in `src/main.h` with:
5. Create build system 5. Create build system
6. Write tests and examples 6. Write tests and examples
7. Create documentation 7. Create documentation
8. Integrate into c-relay 8. Integrate into c-relay-pg
9. Test thoroughly 9. Test thoroughly
10. Publish to GitHub 10. Publish to GitHub
+6 -6
View File
@@ -78,9 +78,9 @@ Configuration events follow the standard Nostr event format with kind 33334:
#### `relay_software` #### `relay_software`
- **Description**: Software identifier for NIP-11 - **Description**: Software identifier for NIP-11
- **Default**: `"c-relay"` - **Default**: `"c-relay-pg"`
- **Format**: String, max 64 characters - **Format**: String, max 64 characters
- **Example**: `"c-relay v1.0.0"` - **Example**: `"c-relay-pg v1.0.0"`
#### `relay_version` #### `relay_version`
- **Description**: Software version string - **Description**: Software version string
@@ -366,7 +366,7 @@ sqlite3 relay.nrdb "SELECT json_pretty(json_object(
#### Invalid Parameter Values #### Invalid Parameter Values
```bash ```bash
# Check relay logs for validation errors # Check relay logs for validation errors
journalctl -u c-relay | grep "Configuration.*invalid\|Invalid.*configuration" journalctl -u c-relay-pg | grep "Configuration.*invalid\|Invalid.*configuration"
# Common issues: # Common issues:
# - Numeric values outside valid ranges # - Numeric values outside valid ranges
@@ -395,10 +395,10 @@ ORDER BY date DESC;"
#### Resource Usage After Changes #### Resource Usage After Changes
```bash ```bash
# Monitor system resources after configuration updates # Monitor system resources after configuration updates
top -p $(pgrep c_relay) top -p $(pgrep c_relay_pg)
# Check for memory leaks # Check for memory leaks
ps aux | grep c_relay | awk '{print $6}' # RSS memory ps aux | grep c_relay_pg | awk '{print $6}' # RSS memory
``` ```
### Emergency Recovery ### Emergency Recovery
@@ -425,7 +425,7 @@ nostrtool event \
# If database is corrupted, backup and recreate # If database is corrupted, backup and recreate
cp relay.nrdb relay.nrdb.backup cp relay.nrdb relay.nrdb.backup
rm relay.nrdb* rm relay.nrdb*
./build/c_relay_x86 # Creates fresh database with new keys ./build/c_relay_pg_x86 # Creates fresh database with new keys
``` ```
--- ---
+14 -14
View File
@@ -21,22 +21,22 @@ typedef enum {
```bash ```bash
# Production (default - no debug output) # Production (default - no debug output)
./c_relay_x86 ./c_relay_pg_x86
# Show errors only # Show errors only
./c_relay_x86 --debug-level=1 ./c_relay_pg_x86 --debug-level=1
# Show errors and warnings # Show errors and warnings
./c_relay_x86 --debug-level=2 ./c_relay_pg_x86 --debug-level=2
# Show errors, warnings, and info (recommended for development) # Show errors, warnings, and info (recommended for development)
./c_relay_x86 --debug-level=3 ./c_relay_pg_x86 --debug-level=3
# Show all debug messages # Show all debug messages
./c_relay_x86 --debug-level=4 ./c_relay_pg_x86 --debug-level=4
# Show everything including trace with file:line (very verbose) # Show everything including trace with file:line (very verbose)
./c_relay_x86 --debug-level=5 ./c_relay_pg_x86 --debug-level=5
``` ```
## Implementation ## Implementation
@@ -475,7 +475,7 @@ When `g_debug_level = 0` (constant), you'll see the compiler has removed all deb
### Level 3 (Errors + Warnings + Info) ### Level 3 (Errors + Warnings + Info)
``` ```
[2025-01-12 14:30:15] [INFO ] Initializing C-Relay v0.4.6 [2025-01-12 14:30:15] [INFO ] Initializing C-Relay-PG v0.4.6
[2025-01-12 14:30:15] [INFO ] Loading configuration from database [2025-01-12 14:30:15] [INFO ] Loading configuration from database
[2025-01-12 14:30:15] [ERROR] Failed to open database: permission denied [2025-01-12 14:30:15] [ERROR] Failed to open database: permission denied
[2025-01-12 14:30:16] [WARN ] Port 8888 unavailable, trying 8889 [2025-01-12 14:30:16] [WARN ] Port 8888 unavailable, trying 8889
@@ -484,7 +484,7 @@ When `g_debug_level = 0` (constant), you'll see the compiler has removed all deb
### Level 4 (All Debug Messages) ### Level 4 (All Debug Messages)
``` ```
[2025-01-12 14:30:15] [INFO ] Initializing C-Relay v0.4.6 [2025-01-12 14:30:15] [INFO ] Initializing C-Relay-PG v0.4.6
[2025-01-12 14:30:15] [DEBUG] Opening database: build/abc123...def.db [2025-01-12 14:30:15] [DEBUG] Opening database: build/abc123...def.db
[2025-01-12 14:30:15] [DEBUG] Executing schema initialization [2025-01-12 14:30:15] [DEBUG] Executing schema initialization
[2025-01-12 14:30:15] [INFO ] SQLite WAL mode enabled [2025-01-12 14:30:15] [INFO ] SQLite WAL mode enabled
@@ -496,7 +496,7 @@ When `g_debug_level = 0` (constant), you'll see the compiler has removed all deb
### Level 5 (Everything Including file:line for ALL messages) ### Level 5 (Everything Including file:line for ALL messages)
``` ```
[2025-01-12 14:30:15] [INFO ] [main.c:1607] Initializing C-Relay v0.4.6 [2025-01-12 14:30:15] [INFO ] [main.c:1607] Initializing C-Relay-PG v0.4.6
[2025-01-12 14:30:15] [DEBUG] [main.c:348] Opening database: build/abc123...def.db [2025-01-12 14:30:15] [DEBUG] [main.c:348] Opening database: build/abc123...def.db
[2025-01-12 14:30:15] [TRACE] [main.c:330] Entering init_database() [2025-01-12 14:30:15] [TRACE] [main.c:330] Entering init_database()
[2025-01-12 14:30:15] [ERROR] [config.c:125] Database locked [2025-01-12 14:30:15] [ERROR] [config.c:125] Database locked
@@ -525,11 +525,11 @@ Update the existing `log_*` functions to use the new debug macros
make clean && make make clean && make
# Test different levels # Test different levels
./build/c_relay_x86 # No output ./build/c_relay_pg_x86 # No output
./build/c_relay_x86 --debug-level=1 # Errors only ./build/c_relay_pg_x86 --debug-level=1 # Errors only
./build/c_relay_x86 --debug-level=3 # Info + warnings + errors ./build/c_relay_pg_x86 --debug-level=3 # Info + warnings + errors
./build/c_relay_x86 --debug-level=4 # All debug messages ./build/c_relay_pg_x86 --debug-level=4 # All debug messages
./build/c_relay_x86 --debug-level=5 # Everything with file:line on TRACE ./build/c_relay_pg_x86 --debug-level=5 # Everything with file:line on TRACE
``` ```
### Step 5: Gradual Migration (Ongoing) ### Step 5: Gradual Migration (Ongoing)
+1 -1
View File
@@ -34,7 +34,7 @@ static const struct {
// NIP-11 Relay Information (relay keys will be populated at runtime) // NIP-11 Relay Information (relay keys will be populated at runtime)
{"relay_description", "High-performance C Nostr relay with SQLite storage"}, {"relay_description", "High-performance C Nostr relay with SQLite storage"},
{"relay_contact", ""}, {"relay_contact", ""},
{"relay_software", "https://git.laantungir.net/laantungir/c-relay.git"}, {"relay_software", "https://git.laantungir.net/laantungir/c-relay-pg.git"},
{"relay_version", "v1.0.0"}, {"relay_version", "v1.0.0"},
// NIP-13 Proof of Work (pow_min_difficulty = 0 means PoW disabled) // NIP-13 Proof of Work (pow_min_difficulty = 0 means PoW disabled)
+51 -51
View File
@@ -52,11 +52,11 @@ sudo apt install -y build-essential git sqlite3 libsqlite3-dev \
#### User and Directory Setup #### User and Directory Setup
```bash ```bash
# Create dedicated system user # Create dedicated system user
sudo useradd --system --home-dir /opt/c-relay --shell /bin/false c-relay sudo useradd --system --home-dir /opt/c-relay-pg --shell /bin/false c-relay-pg
# Create application directory # Create application directory
sudo mkdir -p /opt/c-relay sudo mkdir -p /opt/c-relay-pg
sudo chown c-relay:c-relay /opt/c-relay sudo chown c-relay-pg:c-relay-pg /opt/c-relay-pg
``` ```
### Build and Installation ### Build and Installation
@@ -64,8 +64,8 @@ sudo chown c-relay:c-relay /opt/c-relay
#### Automated Installation (Recommended) #### Automated Installation (Recommended)
```bash ```bash
# Clone repository # Clone repository
git clone https://github.com/your-org/c-relay.git git clone https://github.com/your-org/c-relay-pg.git
cd c-relay cd c-relay-pg
git submodule update --init --recursive git submodule update --init --recursive
# Build # Build
@@ -81,12 +81,12 @@ sudo systemd/install-service.sh
make clean && make make clean && make
# Install binary # Install binary
sudo cp build/c_relay_x86 /opt/c-relay/ sudo cp build/c_relay_pg_x86 /opt/c-relay-pg/
sudo chown c-relay:c-relay /opt/c-relay/c_relay_x86 sudo chown c-relay-pg:c-relay-pg /opt/c-relay-pg/c_relay_pg_x86
sudo chmod +x /opt/c-relay/c_relay_x86 sudo chmod +x /opt/c-relay-pg/c_relay_pg_x86
# Install systemd service # Install systemd service
sudo cp systemd/c-relay.service /etc/systemd/system/ sudo cp systemd/c-relay-pg.service /etc/systemd/system/
sudo systemctl daemon-reload sudo systemctl daemon-reload
``` ```
@@ -95,22 +95,22 @@ sudo systemctl daemon-reload
#### Start and Enable Service #### Start and Enable Service
```bash ```bash
# Start the service # Start the service
sudo systemctl start c-relay sudo systemctl start c-relay-pg
# Enable auto-start on boot # Enable auto-start on boot
sudo systemctl enable c-relay sudo systemctl enable c-relay-pg
# Check status # Check status
sudo systemctl status c-relay sudo systemctl status c-relay-pg
``` ```
#### Capture Admin Keys (CRITICAL) #### Capture Admin Keys (CRITICAL)
```bash ```bash
# View startup logs to get admin keys # View startup logs to get admin keys
sudo journalctl -u c-relay --since "5 minutes ago" | grep -A 10 "IMPORTANT: SAVE THIS ADMIN PRIVATE KEY" sudo journalctl -u c-relay-pg --since "5 minutes ago" | grep -A 10 "IMPORTANT: SAVE THIS ADMIN PRIVATE KEY"
# Or check the full log # Or check the full log
sudo journalctl -u c-relay --no-pager | grep "Admin Private Key" sudo journalctl -u c-relay-pg --no-pager | grep "Admin Private Key"
``` ```
⚠️ **CRITICAL**: Save the admin private key immediately - it's only shown once and is needed for all configuration updates! ⚠️ **CRITICAL**: Save the admin private key immediately - it's only shown once and is needed for all configuration updates!
@@ -151,8 +151,8 @@ sudo iptables-save > /etc/iptables/rules.v4
ssh -i your-key.pem ubuntu@your-instance-ip ssh -i your-key.pem ubuntu@your-instance-ip
# Use the simple deployment script # Use the simple deployment script
git clone https://github.com/your-org/c-relay.git git clone https://github.com/your-org/c-relay-pg.git
cd c-relay cd c-relay-pg
sudo examples/deployment/simple-vps/deploy.sh sudo examples/deployment/simple-vps/deploy.sh
``` ```
@@ -168,10 +168,10 @@ sudo examples/deployment/simple-vps/deploy.sh
sudo mkfs.ext4 /dev/xvdf sudo mkfs.ext4 /dev/xvdf
sudo mkdir /data sudo mkdir /data
sudo mount /dev/xvdf /data sudo mount /dev/xvdf /data
sudo chown c-relay:c-relay /data sudo chown c-relay-pg:c-relay-pg /data
# Update systemd service to use /data # Update systemd service to use /data
sudo sed -i 's/WorkingDirectory=\/opt\/c-relay/WorkingDirectory=\/data/' /etc/systemd/system/c-relay.service sudo sed -i 's/WorkingDirectory=\/opt\/c-relay-pg/WorkingDirectory=\/data/' /etc/systemd/system/c-relay-pg.service
sudo systemctl daemon-reload sudo systemctl daemon-reload
``` ```
@@ -180,7 +180,7 @@ sudo systemctl daemon-reload
#### Compute Engine Setup #### Compute Engine Setup
```bash ```bash
# Create VM instance (e2-micro or larger) # Create VM instance (e2-micro or larger)
gcloud compute instances create c-relay-instance \ gcloud compute instances create c-relay-pg-instance \
--image-family=ubuntu-2204-lts \ --image-family=ubuntu-2204-lts \
--image-project=ubuntu-os-cloud \ --image-project=ubuntu-os-cloud \
--machine-type=e2-micro \ --machine-type=e2-micro \
@@ -193,9 +193,9 @@ gcloud compute firewall-rules create allow-nostr-relay \
--target-tags nostr-relay --target-tags nostr-relay
# SSH and deploy # SSH and deploy
gcloud compute ssh c-relay-instance gcloud compute ssh c-relay-pg-instance
git clone https://github.com/your-org/c-relay.git git clone https://github.com/your-org/c-relay-pg.git
cd c-relay cd c-relay-pg
sudo examples/deployment/simple-vps/deploy.sh sudo examples/deployment/simple-vps/deploy.sh
``` ```
@@ -203,13 +203,13 @@ sudo examples/deployment/simple-vps/deploy.sh
```bash ```bash
# Create and attach persistent disk # Create and attach persistent disk
gcloud compute disks create relay-data --size=50GB gcloud compute disks create relay-data --size=50GB
gcloud compute instances attach-disk c-relay-instance --disk=relay-data gcloud compute instances attach-disk c-relay-pg-instance --disk=relay-data
# Format and mount # Format and mount
sudo mkfs.ext4 /dev/sdb sudo mkfs.ext4 /dev/sdb
sudo mkdir /data sudo mkdir /data
sudo mount /dev/sdb /data sudo mount /dev/sdb /data
sudo chown c-relay:c-relay /data sudo chown c-relay-pg:c-relay-pg /data
``` ```
### DigitalOcean ### DigitalOcean
@@ -223,8 +223,8 @@ sudo chown c-relay:c-relay /data
ssh root@your-droplet-ip ssh root@your-droplet-ip
# Deploy relay # Deploy relay
git clone https://github.com/your-org/c-relay.git git clone https://github.com/your-org/c-relay-pg.git
cd c-relay cd c-relay-pg
examples/deployment/simple-vps/deploy.sh examples/deployment/simple-vps/deploy.sh
``` ```
@@ -245,8 +245,8 @@ The `examples/deployment/` directory contains ready-to-use scripts:
### Simple VPS Deployment ### Simple VPS Deployment
```bash ```bash
# Clone repository and run automated deployment # Clone repository and run automated deployment
git clone https://github.com/your-org/c-relay.git git clone https://github.com/your-org/c-relay-pg.git
cd c-relay cd c-relay-pg
sudo examples/deployment/simple-vps/deploy.sh sudo examples/deployment/simple-vps/deploy.sh
``` ```
@@ -417,9 +417,9 @@ LOG_FILE="/var/log/relay-monitor.log"
DATE=$(date '+%Y-%m-%d %H:%M:%S') DATE=$(date '+%Y-%m-%d %H:%M:%S')
# Check if relay is running # Check if relay is running
if ! pgrep -f "c_relay_x86" > /dev/null; then if ! pgrep -f "c_relay_pg_x86" > /dev/null; then
echo "[$DATE] ERROR: Relay process not running" >> $LOG_FILE echo "[$DATE] ERROR: Relay process not running" >> $LOG_FILE
systemctl restart c-relay systemctl restart c-relay-pg
fi fi
# Check port availability # Check port availability
@@ -428,14 +428,14 @@ if ! netstat -tln | grep -q ":8888"; then
fi fi
# Check database file # Check database file
RELAY_DB=$(find /opt/c-relay -name "*.nrdb" | head -1) RELAY_DB=$(find /opt/c-relay-pg -name "*.nrdb" | head -1)
if [[ -n "$RELAY_DB" ]]; then if [[ -n "$RELAY_DB" ]]; then
DB_SIZE=$(du -h "$RELAY_DB" | cut -f1) DB_SIZE=$(du -h "$RELAY_DB" | cut -f1)
echo "[$DATE] INFO: Database size: $DB_SIZE" >> $LOG_FILE echo "[$DATE] INFO: Database size: $DB_SIZE" >> $LOG_FILE
fi fi
# Check memory usage # Check memory usage
MEM_USAGE=$(ps aux | grep c_relay_x86 | grep -v grep | awk '{print $6}') MEM_USAGE=$(ps aux | grep c_relay_pg_x86 | grep -v grep | awk '{print $6}')
if [[ -n "$MEM_USAGE" ]]; then if [[ -n "$MEM_USAGE" ]]; then
echo "[$DATE] INFO: Memory usage: ${MEM_USAGE}KB" >> $LOG_FILE echo "[$DATE] INFO: Memory usage: ${MEM_USAGE}KB" >> $LOG_FILE
fi fi
@@ -454,8 +454,8 @@ sudo chmod +x /usr/local/bin/relay-monitor.sh
#### Centralized Logging with rsyslog #### Centralized Logging with rsyslog
```bash ```bash
# /etc/rsyslog.d/50-c-relay.conf # /etc/rsyslog.d/50-c-relay-pg.conf
if $programname == 'c-relay' then /var/log/c-relay.log if $programname == 'c-relay-pg' then /var/log/c-relay-pg.log
& stop & stop
``` ```
@@ -465,7 +465,7 @@ if $programname == 'c-relay' then /var/log/c-relay.log
```yaml ```yaml
# /etc/prometheus/prometheus.yml # /etc/prometheus/prometheus.yml
scrape_configs: scrape_configs:
- job_name: 'c-relay' - job_name: 'c-relay-pg'
static_configs: static_configs:
- targets: ['localhost:8888'] - targets: ['localhost:8888']
metrics_path: '/metrics' # If implemented metrics_path: '/metrics' # If implemented
@@ -479,30 +479,30 @@ scrape_configs:
#### Service User Restrictions #### Service User Restrictions
```bash ```bash
# Restrict service user # Restrict service user
sudo usermod -s /bin/false c-relay sudo usermod -s /bin/false c-relay-pg
sudo usermod -d /opt/c-relay c-relay sudo usermod -d /opt/c-relay-pg c-relay-pg
# Set proper permissions # Set proper permissions
sudo chmod 700 /opt/c-relay sudo chmod 700 /opt/c-relay-pg
sudo chown -R c-relay:c-relay /opt/c-relay sudo chown -R c-relay-pg:c-relay-pg /opt/c-relay-pg
``` ```
#### File System Restrictions #### File System Restrictions
```bash ```bash
# Mount data directory with appropriate options # Mount data directory with appropriate options
echo "/dev/sdb /opt/c-relay ext4 defaults,noexec,nosuid,nodev 0 2" >> /etc/fstab echo "/dev/sdb /opt/c-relay-pg ext4 defaults,noexec,nosuid,nodev 0 2" >> /etc/fstab
``` ```
### Network Security ### Network Security
#### Fail2Ban Configuration #### Fail2Ban Configuration
```ini ```ini
# /etc/fail2ban/jail.d/c-relay.conf # /etc/fail2ban/jail.d/c-relay-pg.conf
[c-relay-dos] [c-relay-pg-dos]
enabled = true enabled = true
port = 8888 port = 8888
filter = c-relay-dos filter = c-relay-pg-dos
logpath = /var/log/c-relay.log logpath = /var/log/c-relay-pg.log
maxretry = 10 maxretry = 10
findtime = 60 findtime = 60
bantime = 300 bantime = 300
@@ -534,9 +534,9 @@ sudo mkfs.ext4 /dev/mapper/relay-data
#!/bin/bash #!/bin/bash
# /usr/local/bin/backup-relay.sh # /usr/local/bin/backup-relay.sh
BACKUP_DIR="/backup/c-relay" BACKUP_DIR="/backup/c-relay-pg"
DATE=$(date +%Y%m%d_%H%M%S) DATE=$(date +%Y%m%d_%H%M%S)
RELAY_DB=$(find /opt/c-relay -name "*.nrdb" | head -1) RELAY_DB=$(find /opt/c-relay-pg -name "*.nrdb" | head -1)
mkdir -p "$BACKUP_DIR" mkdir -p "$BACKUP_DIR"
@@ -574,7 +574,7 @@ sudo apt install -y awscli
aws configure aws configure
# Sync backups to S3 # Sync backups to S3
aws s3 sync /backup/c-relay/ s3://your-backup-bucket/c-relay/ --delete aws s3 sync /backup/c-relay-pg/ s3://your-backup-bucket/c-relay-pg/ --delete
``` ```
### Disaster Recovery ### Disaster Recovery
@@ -583,16 +583,16 @@ aws s3 sync /backup/c-relay/ s3://your-backup-bucket/c-relay/ --delete
```bash ```bash
# 1. Restore from backup # 1. Restore from backup
gunzip backup/relay_backup_20231201_020000.nrdb.gz gunzip backup/relay_backup_20231201_020000.nrdb.gz
cp backup/relay_backup_20231201_020000.nrdb /opt/c-relay/ cp backup/relay_backup_20231201_020000.nrdb /opt/c-relay-pg/
# 2. Fix permissions # 2. Fix permissions
sudo chown c-relay:c-relay /opt/c-relay/*.nrdb sudo chown c-relay-pg:c-relay-pg /opt/c-relay-pg/*.nrdb
# 3. Restart service # 3. Restart service
sudo systemctl restart c-relay sudo systemctl restart c-relay-pg
# 4. Verify recovery # 4. Verify recovery
sudo journalctl -u c-relay --since "1 minute ago" sudo journalctl -u c-relay-pg --since "1 minute ago"
``` ```
--- ---
+25 -25
View File
@@ -2,7 +2,7 @@
## Overview ## Overview
This guide explains how to build truly portable MUSL-based static binaries of c-relay using Alpine Linux Docker containers. These binaries have **zero runtime dependencies** and work on any Linux distribution. This guide explains how to build truly portable MUSL-based static binaries of c-relay-pg using Alpine Linux Docker containers. These binaries have **zero runtime dependencies** and work on any Linux distribution.
## Why MUSL? ## Why MUSL?
@@ -36,8 +36,8 @@ This guide explains how to build truly portable MUSL-based static binaries of c-
./build_static.sh ./build_static.sh
# The binary will be created at: # The binary will be created at:
# build/c_relay_static_musl_x86_64 (on x86_64) # build/c_relay_pg_static_musl_x86_64 (on x86_64)
# build/c_relay_static_musl_arm64 (on ARM64) # build/c_relay_pg_static_musl_arm64 (on ARM64)
``` ```
### What Happens During Build ### What Happens During Build
@@ -56,7 +56,7 @@ This guide explains how to build truly portable MUSL-based static binaries of c-
- Includes required NIPs: 001, 006, 013, 017, 019, 044, 059 - Includes required NIPs: 001, 006, 013, 017, 019, 044, 059
- Produces static library (~316KB) - Produces static library (~316KB)
4. **c-relay Compilation**: Links everything statically: 4. **c-relay-pg Compilation**: Links everything statically:
- All source files compiled with `-static` flag - All source files compiled with `-static` flag
- Fortification disabled to avoid `__*_chk` symbols - Fortification disabled to avoid `__*_chk` symbols
- Results in ~7.6MB stripped binary - Results in ~7.6MB stripped binary
@@ -78,7 +78,7 @@ FROM alpine:3.19 AS builder
- Install build tools and static libraries - Install build tools and static libraries
- Build dependencies from source - Build dependencies from source
- Compile nostr_core_lib with MUSL flags - Compile nostr_core_lib with MUSL flags
- Compile c-relay with full static linking - Compile c-relay-pg with full static linking
- Strip binary to reduce size - Strip binary to reduce size
# Stage 2: Output (scratch) # Stage 2: Output (scratch)
@@ -93,7 +93,7 @@ FROM scratch AS output
CFLAGS="-U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=0 -Wall -Wextra -std=c99 -fPIC -O2" CFLAGS="-U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=0 -Wall -Wextra -std=c99 -fPIC -O2"
``` ```
**For c-relay:** **For c-relay-pg:**
```bash ```bash
gcc -static -O2 -Wall -Wextra -std=c99 \ gcc -static -O2 -Wall -Wextra -std=c99 \
-U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=0 \ -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=0 \
@@ -110,7 +110,7 @@ gcc -static -O2 -Wall -Wextra -std=c99 \
- `-U_FORTIFY_SOURCE` (undefine any existing definition) - `-U_FORTIFY_SOURCE` (undefine any existing definition)
- `-D_FORTIFY_SOURCE=0` (set to 0) - `-D_FORTIFY_SOURCE=0` (set to 0)
This must be applied to **both** nostr_core_lib and c-relay compilation. This must be applied to **both** nostr_core_lib and c-relay-pg compilation.
### NIP Dependencies ### NIP Dependencies
@@ -129,26 +129,26 @@ The build includes these NIPs in nostr_core_lib:
```bash ```bash
# Should show "statically linked" # Should show "statically linked"
file build/c_relay_static_musl_x86_64 file build/c_relay_pg_static_musl_x86_64
# Should show "not a dynamic executable" # Should show "not a dynamic executable"
ldd build/c_relay_static_musl_x86_64 ldd build/c_relay_pg_static_musl_x86_64
# Check size (should be ~7.6MB) # Check size (should be ~7.6MB)
ls -lh build/c_relay_static_musl_x86_64 ls -lh build/c_relay_pg_static_musl_x86_64
``` ```
### Test Execution ### Test Execution
```bash ```bash
# Show help # Show help
./build/c_relay_static_musl_x86_64 --help ./build/c_relay_pg_static_musl_x86_64 --help
# Show version # Show version
./build/c_relay_static_musl_x86_64 --version ./build/c_relay_pg_static_musl_x86_64 --version
# Run relay # Run relay
./build/c_relay_static_musl_x86_64 --port 8888 ./build/c_relay_pg_static_musl_x86_64 --port 8888
``` ```
### Cross-Distribution Testing ### Cross-Distribution Testing
@@ -157,16 +157,16 @@ Test the binary on different distributions to verify portability:
```bash ```bash
# Alpine Linux # Alpine Linux
docker run --rm -v $(pwd)/build:/app alpine:latest /app/c_relay_static_musl_x86_64 --version docker run --rm -v $(pwd)/build:/app alpine:latest /app/c_relay_pg_static_musl_x86_64 --version
# Ubuntu # Ubuntu
docker run --rm -v $(pwd)/build:/app ubuntu:latest /app/c_relay_static_musl_x86_64 --version docker run --rm -v $(pwd)/build:/app ubuntu:latest /app/c_relay_pg_static_musl_x86_64 --version
# Debian # Debian
docker run --rm -v $(pwd)/build:/app debian:latest /app/c_relay_static_musl_x86_64 --version docker run --rm -v $(pwd)/build:/app debian:latest /app/c_relay_pg_static_musl_x86_64 --version
# CentOS # CentOS
docker run --rm -v $(pwd)/build:/app centos:latest /app/c_relay_static_musl_x86_64 --version docker run --rm -v $(pwd)/build:/app centos:latest /app/c_relay_pg_static_musl_x86_64 --version
``` ```
## Troubleshooting ## Troubleshooting
@@ -187,7 +187,7 @@ newgrp docker # Or logout and login again
**Solution**: Ensure fortification is disabled in both: **Solution**: Ensure fortification is disabled in both:
1. nostr_core_lib build.sh (line 534) 1. nostr_core_lib build.sh (line 534)
2. c-relay compilation flags in Dockerfile 2. c-relay-pg compilation flags in Dockerfile
### Binary Won't Execute ### Binary Won't Execute
@@ -213,26 +213,26 @@ newgrp docker # Or logout and login again
```bash ```bash
# Copy binary to server # Copy binary to server
scp build/c_relay_static_musl_x86_64 user@server:/opt/c-relay/ scp build/c_relay_pg_static_musl_x86_64 user@server:/opt/c-relay-pg/
# Run on server (no dependencies needed!) # Run on server (no dependencies needed!)
ssh user@server ssh user@server
cd /opt/c-relay cd /opt/c-relay-pg
./c_relay_static_musl_x86_64 --port 8888 ./c_relay_pg_static_musl_x86_64 --port 8888
``` ```
### SystemD Service ### SystemD Service
```ini ```ini
[Unit] [Unit]
Description=C-Relay Nostr Relay (MUSL Static) Description=C-Relay-PG Nostr Relay (MUSL Static)
After=network.target After=network.target
[Service] [Service]
Type=simple Type=simple
User=c-relay User=c-relay-pg
WorkingDirectory=/opt/c-relay WorkingDirectory=/opt/c-relay-pg
ExecStart=/opt/c-relay/c_relay_static_musl_x86_64 ExecStart=/opt/c-relay-pg/c_relay_pg_static_musl_x86_64
Restart=always Restart=always
RestartSec=5 RestartSec=5
+4 -4
View File
@@ -23,7 +23,7 @@ We chose Option B because:
## Detailed Implementation Steps ## Detailed Implementation Steps
### Phase 1: Configuration Setup in c-relay ### Phase 1: Configuration Setup in c-relay-pg
#### 1.1 Add Configuration Parameter #### 1.1 Add Configuration Parameter
**File:** `src/default_config_event.h` **File:** `src/default_config_event.h`
@@ -293,7 +293,7 @@ int nostr_nip17_send_dm(cJSON* dm_event,
--- ---
### Phase 4: Update c-relay Call Sites ### Phase 4: Update c-relay-pg Call Sites
#### 4.1 Update src/api.c #### 4.1 Update src/api.c
**Location:** Line 1319 **Location:** Line 1319
@@ -470,7 +470,7 @@ causing compatibility issues.
- [ ] Update `nostr_nip17_send_dm()` signature and implementation - [ ] Update `nostr_nip17_send_dm()` signature and implementation
- [ ] Update `nip017.h` function declaration and documentation - [ ] Update `nip017.h` function declaration and documentation
### c-relay Changes ### c-relay-pg Changes
- [ ] Add `nip59_timestamp_max_delay_sec` to `default_config_event.h` - [ ] Add `nip59_timestamp_max_delay_sec` to `default_config_event.h`
- [ ] Add validation in `config.c` for new parameter - [ ] Add validation in `config.c` for new parameter
- [ ] Update `src/api.c` call site to pass `max_delay_sec` - [ ] Update `src/api.c` call site to pass `max_delay_sec`
@@ -494,7 +494,7 @@ causing compatibility issues.
If issues arise: If issues arise:
1. Revert nostr_core_lib changes (git revert in submodule) 1. Revert nostr_core_lib changes (git revert in submodule)
2. Revert c-relay changes 2. Revert c-relay-pg changes
3. Configuration parameter will be ignored if not used 3. Configuration parameter will be ignored if not used
4. Default behavior (0) provides maximum compatibility 4. Default behavior (0) provides maximum compatibility
+2 -2
View File
@@ -2,7 +2,7 @@
## Overview ## Overview
This document describes the design for a general-purpose SQL query interface for the C-Relay admin API. This allows administrators to execute read-only SQL queries against the relay database through cryptographically signed kind 23456 events with NIP-44 encrypted command arrays. This document describes the design for a general-purpose SQL query interface for the C-Relay-PG admin API. This allows administrators to execute read-only SQL queries against the relay database through cryptographically signed kind 23456 events with NIP-44 encrypted command arrays.
## Security Model ## Security Model
@@ -271,7 +271,7 @@ const SQL_QUERY_TEMPLATES = {
}; };
// Query history management (localStorage) // Query history management (localStorage)
const QUERY_HISTORY_KEY = 'c_relay_sql_history'; const QUERY_HISTORY_KEY = 'c_relay_pg_sql_history';
const MAX_HISTORY_ITEMS = 20; const MAX_HISTORY_ITEMS = 20;
// Load query history from localStorage // Load query history from localStorage
+1 -1
View File
@@ -224,7 +224,7 @@ The script should:
- `curl` or `websocat` for WebSocket communication - `curl` or `websocat` for WebSocket communication
- `jq` for JSON parsing - `jq` for JSON parsing
- Nostr CLI tools (optional, for event signing) - Nostr CLI tools (optional, for event signing)
- Running c-relay instance - Running c-relay-pg instance
## Example Output ## Example Output
+6 -6
View File
@@ -1,8 +1,8 @@
# C-Relay Complete Startup Flow Documentation # C-Relay-PG Complete Startup Flow Documentation
## Overview ## Overview
C-Relay has two distinct startup paths: C-Relay-PG has two distinct startup paths:
1. **First-Time Startup**: No database exists, generates keys and initializes system 1. **First-Time Startup**: No database exists, generates keys and initializes system
2. **Existing Relay Startup**: Database exists, loads configuration and resumes operation 2. **Existing Relay Startup**: Database exists, loads configuration and resumes operation
@@ -220,7 +220,7 @@ int populate_default_config_values(void) {
struct config_default defaults[] = { struct config_default defaults[] = {
{"relay_port", "8888", "integer", "WebSocket port", "network", 1}, {"relay_port", "8888", "integer", "WebSocket port", "network", 1},
{"relay_name", "C-Relay", "string", "Relay name", "info", 0}, {"relay_name", "C-Relay-PG", "string", "Relay name", "info", 0},
{"relay_description", "High-performance C Nostr relay", "string", "Description", "info", 0}, {"relay_description", "High-performance C Nostr relay", "string", "Description", "info", 0},
{"max_subscriptions_per_client", "25", "integer", "Max subs per client", "limits", 0}, {"max_subscriptions_per_client", "25", "integer", "Max subs per client", "limits", 0},
{"pow_min_difficulty", "0", "integer", "Minimum PoW difficulty", "security", 0}, {"pow_min_difficulty", "0", "integer", "Minimum PoW difficulty", "security", 0},
@@ -983,7 +983,7 @@ if (current_version < LATEST_VERSION) {
**Solutions**: **Solutions**:
- Use `--port <number>` to specify different port - Use `--port <number>` to specify different port
- Kill existing process: `pkill -f c_relay_` - Kill existing process: `pkill -f c_relay_pg_`
- Force kill port: `fuser -k 8888/tcp` - Force kill port: `fuser -k 8888/tcp`
- Use `--strict-port` to fail fast instead of trying fallback ports - Use `--strict-port` to fail fast instead of trying fallback ports
@@ -994,7 +994,7 @@ if (current_version < LATEST_VERSION) {
**Solutions**: **Solutions**:
- Kill existing relay processes - Kill existing relay processes
- Remove WAL files: `rm build/*.db-wal build/*.db-shm` - Remove WAL files: `rm build/*.db-wal build/*.db-shm`
- Check for stale processes: `ps aux | grep c_relay_` - Check for stale processes: `ps aux | grep c_relay_pg_`
#### 3. Missing Admin Private Key #### 3. Missing Admin Private Key
@@ -1071,7 +1071,7 @@ Typical startup times (on modern hardware):
## Summary ## Summary
The c-relay startup system is designed for: The c-relay-pg startup system is designed for:
1. **Security**: Admin keys never stored, relay keys encrypted 1. **Security**: Admin keys never stored, relay keys encrypted
2. **Reliability**: Automatic port fallback, schema migrations 2. **Reliability**: Automatic port fallback, schema migrations
+9 -9
View File
@@ -18,10 +18,10 @@ The script now attempts to build with `musl-gcc` for truly portable static binar
SQLite is now built once and cached for future builds: SQLite is now built once and cached for future builds:
- **Cache location**: `~/.cache/c-relay-sqlite/` - **Cache location**: `~/.cache/c-relay-pg-sqlite/`
- **Version-specific**: Each SQLite version gets its own cache directory - **Version-specific**: Each SQLite version gets its own cache directory
- **Significant speedup**: Subsequent builds skip the SQLite compilation step - **Significant speedup**: Subsequent builds skip the SQLite compilation step
- **Manual cleanup**: `rm -rf ~/.cache/c-relay-sqlite` to clear cache - **Manual cleanup**: `rm -rf ~/.cache/c-relay-pg-sqlite` to clear cache
### 3. Smart Package Installation ### 3. Smart Package Installation
@@ -51,13 +51,13 @@ The script will:
## Binary Types ## Binary Types
### MUSL Static Binary (Ideal - Currently Not Achievable) ### MUSL Static Binary (Ideal - Currently Not Achievable)
- **Filename**: `build/c_relay_static_musl_x86_64` - **Filename**: `build/c_relay_pg_static_musl_x86_64`
- **Dependencies**: None (truly static) - **Dependencies**: None (truly static)
- **Portability**: Works on any Linux distribution - **Portability**: Works on any Linux distribution
- **Status**: Requires MUSL-compiled libwebsockets and other dependencies (not available by default) - **Status**: Requires MUSL-compiled libwebsockets and other dependencies (not available by default)
### Glibc Static Binary (Current Output) ### Glibc Static Binary (Current Output)
- **Filename**: `build/c_relay_static_x86_64` or `build/c_relay_static_glibc_x86_64` - **Filename**: `build/c_relay_pg_static_x86_64` or `build/c_relay_pg_static_glibc_x86_64`
- **Dependencies**: None - fully statically linked with glibc - **Dependencies**: None - fully statically linked with glibc
- **Portability**: Works on most Linux distributions (glibc is statically included) - **Portability**: Works on most Linux distributions (glibc is statically included)
- **Note**: Despite using glibc, this is a **fully static binary** with no runtime dependencies - **Note**: Despite using glibc, this is a **fully static binary** with no runtime dependencies
@@ -68,11 +68,11 @@ The script automatically verifies binaries using `ldd` and `file`:
```bash ```bash
# For MUSL binary # For MUSL binary
ldd build/c_relay_static_musl_x86_64 ldd build/c_relay_pg_static_musl_x86_64
# Output: "not a dynamic executable" (good!) # Output: "not a dynamic executable" (good!)
# For glibc binary # For glibc binary
ldd build/c_relay_static_glibc_x86_64 ldd build/c_relay_pg_static_glibc_x86_64
# Output: Shows glibc dependencies # Output: Shows glibc dependencies
``` ```
@@ -112,7 +112,7 @@ The script attempts MUSL compilation but falls back to glibc:
### Clear SQLite Cache ### Clear SQLite Cache
```bash ```bash
rm -rf ~/.cache/c-relay-sqlite rm -rf ~/.cache/c-relay-pg-sqlite
``` ```
### Force Package Reinstall ### Force Package Reinstall
@@ -127,8 +127,8 @@ cat /tmp/musl_build.log
### Verify Binary Type ### Verify Binary Type
```bash ```bash
file build/c_relay_static_* file build/c_relay_pg_static_*
ldd build/c_relay_static_* 2>&1 ldd build/c_relay_pg_static_* 2>&1
``` ```
## Performance Impact ## Performance Impact
+1 -1
View File
@@ -2,7 +2,7 @@
## Problem Summary ## Problem Summary
The c-relay Nostr relay experienced severe performance degradation (90-100% CPU) due to subscription accumulation in the database. Investigation revealed **323,644 orphaned subscriptions** that were never properly closed when WebSocket connections dropped. The c-relay-pg Nostr relay experienced severe performance degradation (90-100% CPU) due to subscription accumulation in the database. Investigation revealed **323,644 orphaned subscriptions** that were never properly closed when WebSocket connections dropped.
## Solution: Two-Component Approach ## Solution: Two-Component Approach
+8 -8
View File
@@ -586,7 +586,7 @@ int add_pubkeys_to_config_table(void) {
rm -f *.db rm -f *.db
# Start relay with defaults # Start relay with defaults
./build/c_relay_x86 ./build/c_relay_pg_x86
# Verify config table complete # Verify config table complete
sqlite3 <relay_pubkey>.db "SELECT COUNT(*) FROM config;" sqlite3 <relay_pubkey>.db "SELECT COUNT(*) FROM config;"
@@ -602,7 +602,7 @@ int add_pubkeys_to_config_table(void) {
rm -f *.db rm -f *.db
# Start relay with port override # Start relay with port override
./build/c_relay_x86 --port 9999 ./build/c_relay_pg_x86 --port 9999
# Verify port override applied # Verify port override applied
sqlite3 <relay_pubkey>.db "SELECT value FROM config WHERE key='relay_port';" sqlite3 <relay_pubkey>.db "SELECT value FROM config WHERE key='relay_port';"
@@ -612,13 +612,13 @@ int add_pubkeys_to_config_table(void) {
3. **Restart with Existing Database** 3. **Restart with Existing Database**
```bash ```bash
# Start relay (creates database) # Start relay (creates database)
./build/c_relay_x86 ./build/c_relay_pg_x86
# Stop relay # Stop relay
pkill -f c_relay_ pkill -f c_relay_pg_
# Restart relay # Restart relay
./build/c_relay_x86 ./build/c_relay_pg_x86
# Verify config unchanged # Verify config unchanged
# Check relay.log for validation message # Check relay.log for validation message
@@ -627,13 +627,13 @@ int add_pubkeys_to_config_table(void) {
4. **Restart with CLI Overrides** 4. **Restart with CLI Overrides**
```bash ```bash
# Start relay (creates database) # Start relay (creates database)
./build/c_relay_x86 ./build/c_relay_pg_x86
# Stop relay # Stop relay
pkill -f c_relay_ pkill -f c_relay_pg_
# Restart with port override # Restart with port override
./build/c_relay_x86 --port 9999 ./build/c_relay_pg_x86 --port 9999
# Verify port override applied # Verify port override applied
sqlite3 <relay_pubkey>.db "SELECT value FROM config WHERE key='relay_port';" sqlite3 <relay_pubkey>.db "SELECT value FROM config WHERE key='relay_port';"
+32 -32
View File
@@ -19,12 +19,12 @@ Complete guide for deploying, configuring, and managing the C Nostr Relay with e
```bash ```bash
# Clone and build # Clone and build
git clone <repository-url> git clone <repository-url>
cd c-relay cd c-relay-pg
git submodule update --init --recursive git submodule update --init --recursive
make make
# Start relay (zero configuration needed) # Start relay (zero configuration needed)
./build/c_relay_x86 ./build/c_relay_pg_x86
``` ```
### 2. First Startup - Save Keys ### 2. First Startup - Save Keys
@@ -78,7 +78,7 @@ brew install git sqlite libwebsockets openssl libsecp256k1 curl zlib
```bash ```bash
# Clone repository # Clone repository
git clone <repository-url> git clone <repository-url>
cd c-relay cd c-relay-pg
# Initialize submodules # Initialize submodules
git submodule update --init --recursive git submodule update --init --recursive
@@ -87,7 +87,7 @@ git submodule update --init --recursive
make clean && make make clean && make
# Verify build # Verify build
ls -la build/c_relay_x86 ls -la build/c_relay_pg_x86
``` ```
### Production Deployment ### Production Deployment
@@ -98,27 +98,27 @@ ls -la build/c_relay_x86
sudo systemd/install-service.sh sudo systemd/install-service.sh
# Start service # Start service
sudo systemctl start c-relay sudo systemctl start c-relay-pg
# Enable auto-start # Enable auto-start
sudo systemctl enable c-relay sudo systemctl enable c-relay-pg
# Check status # Check status
sudo systemctl status c-relay sudo systemctl status c-relay-pg
``` ```
#### Manual Deployment #### Manual Deployment
```bash ```bash
# Create dedicated user # Create dedicated user
sudo useradd --system --home-dir /opt/c-relay --shell /bin/false c-relay sudo useradd --system --home-dir /opt/c-relay-pg --shell /bin/false c-relay-pg
# Install binary # Install binary
sudo mkdir -p /opt/c-relay sudo mkdir -p /opt/c-relay-pg
sudo cp build/c_relay_x86 /opt/c-relay/ sudo cp build/c_relay_pg_x86 /opt/c-relay-pg/
sudo chown -R c-relay:c-relay /opt/c-relay sudo chown -R c-relay-pg:c-relay-pg /opt/c-relay-pg
# Run as service user # Run as service user
sudo -u c-relay /opt/c-relay/c_relay_x86 sudo -u c-relay-pg /opt/c-relay-pg/c_relay_pg_x86
``` ```
## Configuration Management ## Configuration Management
@@ -188,7 +188,7 @@ Send this to your relay via WebSocket, and changes are applied immediately.
|-----------|-------------|---------|---------| |-----------|-------------|---------|---------|
| `relay_description` | Relay description for NIP-11 | "C Nostr Relay" | "My awesome relay" | | `relay_description` | Relay description for NIP-11 | "C Nostr Relay" | "My awesome relay" |
| `relay_contact` | Admin contact information | "" | "admin@example.com" | | `relay_contact` | Admin contact information | "" | "admin@example.com" |
| `relay_software` | Software identifier | "c-relay" | "c-relay v1.0" | | `relay_software` | Software identifier | "c-relay-pg" | "c-relay-pg v1.0" |
#### Client Limits #### Client Limits
| Parameter | Description | Default | Range | | Parameter | Description | Default | Range |
@@ -273,7 +273,7 @@ chmod 600 admin_keys_backup_*.txt
#### Key Recovery #### Key Recovery
If you lose your admin private key: If you lose your admin private key:
1. **Stop the relay**: `pkill c_relay` or `sudo systemctl stop c-relay` 1. **Stop the relay**: `pkill c_relay_pg` or `sudo systemctl stop c-relay-pg`
2. **Backup events**: `cp <relay_pubkey>.nrdb backup_$(date +%Y%m%d).nrdb` 2. **Backup events**: `cp <relay_pubkey>.nrdb backup_$(date +%Y%m%d).nrdb`
3. **Remove database**: `rm <relay_pubkey>.nrdb*` 3. **Remove database**: `rm <relay_pubkey>.nrdb*`
4. **Restart relay**: This creates new database with new keys 4. **Restart relay**: This creates new database with new keys
@@ -300,7 +300,7 @@ sudo ufw allow 8888/tcp
```bash ```bash
# Secure database file permissions # Secure database file permissions
chmod 600 <relay_pubkey>.nrdb chmod 600 <relay_pubkey>.nrdb
chown c-relay:c-relay <relay_pubkey>.nrdb chown c-relay-pg:c-relay-pg <relay_pubkey>.nrdb
# Regular backups # Regular backups
cp <relay_pubkey>.nrdb backup/relay_backup_$(date +%Y%m%d_%H%M%S).nrdb cp <relay_pubkey>.nrdb backup/relay_backup_$(date +%Y%m%d_%H%M%S).nrdb
@@ -311,10 +311,10 @@ cp <relay_pubkey>.nrdb backup/relay_backup_$(date +%Y%m%d_%H%M%S).nrdb
### Service Status ### Service Status
```bash ```bash
# Check if relay is running # Check if relay is running
ps aux | grep c_relay ps aux | grep c_relay_pg
# SystemD status # SystemD status
sudo systemctl status c-relay sudo systemctl status c-relay-pg
# Network connections # Network connections
netstat -tln | grep 8888 netstat -tln | grep 8888
@@ -324,16 +324,16 @@ sudo ss -tlpn | grep 8888
### Log Monitoring ### Log Monitoring
```bash ```bash
# Real-time logs (systemd) # Real-time logs (systemd)
sudo journalctl -u c-relay -f sudo journalctl -u c-relay-pg -f
# Recent logs # Recent logs
sudo journalctl -u c-relay --since "1 hour ago" sudo journalctl -u c-relay-pg --since "1 hour ago"
# Error logs only # Error logs only
sudo journalctl -u c-relay -p err sudo journalctl -u c-relay-pg -p err
# Configuration changes # Configuration changes
sudo journalctl -u c-relay | grep "Configuration updated via kind 33334" sudo journalctl -u c-relay-pg | grep "Configuration updated via kind 33334"
``` ```
### Database Analytics ### Database Analytics
@@ -365,13 +365,13 @@ ORDER BY created_at DESC;
du -sh <relay_pubkey>.nrdb* du -sh <relay_pubkey>.nrdb*
# Memory usage # Memory usage
ps aux | grep c_relay | awk '{print $6}' # RSS memory in KB ps aux | grep c_relay_pg | awk '{print $6}' # RSS memory in KB
# Connection count (approximate) # Connection count (approximate)
netstat -an | grep :8888 | grep ESTABLISHED | wc -l netstat -an | grep :8888 | grep ESTABLISHED | wc -l
# System resources # System resources
top -p $(pgrep c_relay) top -p $(pgrep c_relay_pg)
``` ```
## Troubleshooting ## Troubleshooting
@@ -385,11 +385,11 @@ netstat -tln | grep 8888
# If port in use, find process: sudo lsof -i :8888 # If port in use, find process: sudo lsof -i :8888
# Check binary permissions # Check binary permissions
ls -la build/c_relay_x86 ls -la build/c_relay_pg_x86
chmod +x build/c_relay_x86 chmod +x build/c_relay_pg_x86
# Check dependencies # Check dependencies
ldd build/c_relay_x86 ldd build/c_relay_pg_x86
``` ```
#### Configuration Not Updating #### Configuration Not Updating
@@ -442,7 +442,7 @@ sqlite3 recovered.nrdb < recovered.sql
# If repair fails, start fresh (loses all events) # If repair fails, start fresh (loses all events)
mv <relay_pubkey>.nrdb <relay_pubkey>.nrdb.corrupted mv <relay_pubkey>.nrdb <relay_pubkey>.nrdb.corrupted
./build/c_relay_x86 # Creates new database ./build/c_relay_pg_x86 # Creates new database
``` ```
#### Lost Configuration Recovery #### Lost Configuration Recovery
@@ -455,12 +455,12 @@ If configuration is lost but database is intact:
#### Emergency Restart #### Emergency Restart
```bash ```bash
# Quick restart with clean state # Quick restart with clean state
sudo systemctl stop c-relay sudo systemctl stop c-relay-pg
mv <relay_pubkey>.nrdb <relay_pubkey>.nrdb.backup mv <relay_pubkey>.nrdb <relay_pubkey>.nrdb.backup
sudo systemctl start c-relay sudo systemctl start c-relay-pg
# Check logs for new admin keys # Check logs for new admin keys
sudo journalctl -u c-relay --since "5 minutes ago" | grep "Admin Private Key" sudo journalctl -u c-relay-pg --since "5 minutes ago" | grep "Admin Private Key"
``` ```
## Advanced Usage ## Advanced Usage
@@ -503,7 +503,7 @@ ws.on('open', function() {
# backup-relay.sh # backup-relay.sh
DATE=$(date +%Y%m%d_%H%M%S) DATE=$(date +%Y%m%d_%H%M%S)
DB_FILE=$(ls *.nrdb | head -1) DB_FILE=$(ls *.nrdb | head -1)
BACKUP_DIR="/backup/c-relay" BACKUP_DIR="/backup/c-relay-pg"
mkdir -p $BACKUP_DIR mkdir -p $BACKUP_DIR
cp $DB_FILE $BACKUP_DIR/relay_backup_$DATE.nrdb cp $DB_FILE $BACKUP_DIR/relay_backup_$DATE.nrdb
@@ -533,7 +533,7 @@ tar czf relay_migration.tar.gz *.nrdb* relay.log
# Target server # Target server
tar xzf relay_migration.tar.gz tar xzf relay_migration.tar.gz
./build/c_relay_x86 # Will detect existing database and continue ./build/c_relay_pg_x86 # Will detect existing database and continue
``` ```
--- ---
+1 -1
View File
@@ -1,6 +1,6 @@
#!/bin/bash #!/bin/bash
# Script to embed web files into C headers for the C-Relay admin interface # Script to embed web files into C headers for the C-Relay-PG admin interface
# Converts HTML, CSS, and JS files from api/ directory into C byte arrays # Converts HTML, CSS, and JS files from api/ directory into C byte arrays
set -e set -e
+1 -1
View File
@@ -60,7 +60,7 @@ All examples assume the event-based configuration system where:
- **Save Admin Keys**: All deployment examples emphasize capturing the admin private key on first startup - **Save Admin Keys**: All deployment examples emphasize capturing the admin private key on first startup
- **Firewall Configuration**: Examples include proper firewall rules - **Firewall Configuration**: Examples include proper firewall rules
- **SSL/TLS**: Production examples include HTTPS configuration - **SSL/TLS**: Production examples include HTTPS configuration
- **User Isolation**: Service runs as dedicated `c-relay` system user - **User Isolation**: Service runs as dedicated `c-relay-pg` system user
## Support ## Support
+6 -6
View File
@@ -13,8 +13,8 @@ BLUE='\033[0;34m'
NC='\033[0m' # No Color NC='\033[0m' # No Color
# Default configuration # Default configuration
RELAY_DIR="/opt/c-relay" RELAY_DIR="/opt/c-relay-pg"
BACKUP_DIR="/backup/c-relay" BACKUP_DIR="/backup/c-relay-pg"
RETENTION_DAYS="30" RETENTION_DAYS="30"
COMPRESS="true" COMPRESS="true"
REMOTE_BACKUP="" REMOTE_BACKUP=""
@@ -47,8 +47,8 @@ show_help() {
echo "Usage: $0 [OPTIONS]" echo "Usage: $0 [OPTIONS]"
echo echo
echo "Options:" echo "Options:"
echo " -d, --relay-dir DIR Relay directory (default: /opt/c-relay)" echo " -d, --relay-dir DIR Relay directory (default: /opt/c-relay-pg)"
echo " -b, --backup-dir DIR Backup directory (default: /backup/c-relay)" echo " -b, --backup-dir DIR Backup directory (default: /backup/c-relay-pg)"
echo " -r, --retention DAYS Retention period in days (default: 30)" echo " -r, --retention DAYS Retention period in days (default: 30)"
echo " -n, --no-compress Don't compress backups" echo " -n, --no-compress Don't compress backups"
echo " -s, --s3-bucket BUCKET Upload to S3 bucket" echo " -s, --s3-bucket BUCKET Upload to S3 bucket"
@@ -231,7 +231,7 @@ upload_to_s3() {
print_step "Uploading backup to S3..." print_step "Uploading backup to S3..."
local s3_path="s3://$S3_BUCKET/c-relay/$(date +%Y)/$(date +%m)/" local s3_path="s3://$S3_BUCKET/c-relay-pg/$(date +%Y)/$(date +%m)/"
if aws s3 cp "$BACKUP_FILE" "$s3_path" --storage-class STANDARD_IA; then if aws s3 cp "$BACKUP_FILE" "$s3_path" --storage-class STANDARD_IA; then
print_success "Backup uploaded to S3: $s3_path" print_success "Backup uploaded to S3: $s3_path"
@@ -264,7 +264,7 @@ cleanup_old_backups() {
print_step "Cleaning S3 backups older than $cutoff_date..." print_step "Cleaning S3 backups older than $cutoff_date..."
# Note: This is a simplified approach. In production, use S3 lifecycle policies # Note: This is a simplified approach. In production, use S3 lifecycle policies
aws s3 ls "s3://$S3_BUCKET/c-relay/" --recursive | \ aws s3 ls "s3://$S3_BUCKET/c-relay-pg/" --recursive | \
awk '$1 < "'$cutoff_date'" {print $4}' | \ awk '$1 < "'$cutoff_date'" {print $4}' | \
while read -r key; do while read -r key; do
aws s3 rm "s3://$S3_BUCKET/$key" aws s3 rm "s3://$S3_BUCKET/$key"
@@ -13,8 +13,8 @@ BLUE='\033[0;34m'
NC='\033[0m' # No Color NC='\033[0m' # No Color
# Configuration # Configuration
RELAY_DIR="/opt/c-relay" RELAY_DIR="/opt/c-relay-pg"
SERVICE_NAME="c-relay" SERVICE_NAME="c-relay-pg"
RELAY_PORT="8888" RELAY_PORT="8888"
LOG_FILE="/var/log/relay-monitor.log" LOG_FILE="/var/log/relay-monitor.log"
ALERT_EMAIL="" ALERT_EMAIL=""
@@ -60,7 +60,7 @@ show_help() {
echo "Usage: $0 [OPTIONS]" echo "Usage: $0 [OPTIONS]"
echo echo
echo "Options:" echo "Options:"
echo " -d, --relay-dir DIR Relay directory (default: /opt/c-relay)" echo " -d, --relay-dir DIR Relay directory (default: /opt/c-relay-pg)"
echo " -p, --port PORT Relay port (default: 8888)" echo " -p, --port PORT Relay port (default: 8888)"
echo " -i, --interval SECONDS Check interval (default: 60)" echo " -i, --interval SECONDS Check interval (default: 60)"
echo " -e, --email EMAIL Alert email address" echo " -e, --email EMAIL Alert email address"
@@ -134,7 +134,7 @@ parse_args() {
check_process_running() { check_process_running() {
print_step "Checking if relay process is running..." print_step "Checking if relay process is running..."
if pgrep -f "c_relay_x86" > /dev/null; then if pgrep -f "c_relay_pg_x86" > /dev/null; then
print_success "Relay process is running" print_success "Relay process is running"
return 0 return 0
else else
@@ -172,7 +172,7 @@ check_service_status() {
check_memory_usage() { check_memory_usage() {
print_step "Checking memory usage..." print_step "Checking memory usage..."
local memory_kb=$(ps aux | grep "c_relay_x86" | grep -v grep | awk '{sum+=$6} END {print sum}') local memory_kb=$(ps aux | grep "c_relay_pg_x86" | grep -v grep | awk '{sum+=$6} END {print sum}')
if [[ -z "$memory_kb" ]]; then if [[ -z "$memory_kb" ]]; then
print_warning "Could not determine memory usage" print_warning "Could not determine memory usage"
+4 -4
View File
@@ -56,7 +56,7 @@ http {
} }
# Upstream for the relay # Upstream for the relay
upstream c_relay_backend { upstream c_relay_pg_backend {
server 127.0.0.1:8888; server 127.0.0.1:8888;
keepalive 32; keepalive 32;
} }
@@ -108,7 +108,7 @@ http {
# Main proxy location for WebSocket and HTTP # Main proxy location for WebSocket and HTTP
location / { location / {
# Proxy settings # Proxy settings
proxy_pass http://c_relay_backend; proxy_pass http://c_relay_pg_backend;
proxy_http_version 1.1; proxy_http_version 1.1;
proxy_cache_bypass $http_upgrade; proxy_cache_bypass $http_upgrade;
@@ -144,7 +144,7 @@ http {
# Health check endpoint (if implemented) # Health check endpoint (if implemented)
location /health { location /health {
proxy_pass http://c_relay_backend/health; proxy_pass http://c_relay_pg_backend/health;
access_log off; access_log off;
} }
@@ -157,7 +157,7 @@ http {
# Optional: Metrics endpoint (if implemented) # Optional: Metrics endpoint (if implemented)
location /metrics { location /metrics {
proxy_pass http://c_relay_backend/metrics; proxy_pass http://c_relay_pg_backend/metrics;
# Restrict access to monitoring systems # Restrict access to monitoring systems
allow 10.0.0.0/8; allow 10.0.0.0/8;
allow 172.16.0.0/12; allow 172.16.0.0/12;
@@ -96,9 +96,9 @@ check_root() {
check_relay_running() { check_relay_running() {
print_step "Checking if C Nostr Relay is running..." print_step "Checking if C Nostr Relay is running..."
if ! pgrep -f "c_relay_x86" > /dev/null; then if ! pgrep -f "c_relay_pg_x86" > /dev/null; then
print_error "C Nostr Relay is not running" print_error "C Nostr Relay is not running"
print_error "Please start the relay first with: sudo systemctl start c-relay" print_error "Please start the relay first with: sudo systemctl start c-relay-pg"
exit 1 exit 1
fi fi
+12 -12
View File
@@ -13,9 +13,9 @@ BLUE='\033[0;34m'
NC='\033[0m' # No Color NC='\033[0m' # No Color
# Configuration # Configuration
RELAY_USER="c-relay" RELAY_USER="c-relay-pg"
INSTALL_DIR="/opt/c-relay" INSTALL_DIR="/opt/c-relay-pg"
SERVICE_NAME="c-relay" SERVICE_NAME="c-relay-pg"
RELAY_PORT="8888" RELAY_PORT="8888"
# Functions # Functions
@@ -99,7 +99,7 @@ build_relay() {
# Check if we're in the source directory # Check if we're in the source directory
if [[ ! -f "Makefile" ]]; then if [[ ! -f "Makefile" ]]; then
print_error "Makefile not found. Please run this script from the c-relay source directory." print_error "Makefile not found. Please run this script from the c-relay-pg source directory."
exit 1 exit 1
fi fi
@@ -107,7 +107,7 @@ build_relay() {
make clean make clean
make make
if [[ ! -f "build/c_relay_x86" ]]; then if [[ ! -f "build/c_relay_pg_x86" ]]; then
print_error "Build failed - binary not found" print_error "Build failed - binary not found"
exit 1 exit 1
fi fi
@@ -118,9 +118,9 @@ build_relay() {
install_binary() { install_binary() {
print_step "Installing relay binary..." print_step "Installing relay binary..."
cp build/c_relay_x86 "$INSTALL_DIR/" cp build/c_relay_pg_x86 "$INSTALL_DIR/"
chown "$RELAY_USER:$RELAY_USER" "$INSTALL_DIR/c_relay_x86" chown "$RELAY_USER:$RELAY_USER" "$INSTALL_DIR/c_relay_pg_x86"
chmod +x "$INSTALL_DIR/c_relay_x86" chmod +x "$INSTALL_DIR/c_relay_pg_x86"
print_success "Binary installed to $INSTALL_DIR" print_success "Binary installed to $INSTALL_DIR"
} }
@@ -129,14 +129,14 @@ install_service() {
print_step "Installing systemd service..." print_step "Installing systemd service..."
# Use the existing systemd service file # Use the existing systemd service file
if [[ -f "systemd/c-relay.service" ]]; then if [[ -f "systemd/c-relay-pg.service" ]]; then
cp systemd/c-relay.service /etc/systemd/system/ cp systemd/c-relay-pg.service /etc/systemd/system/
systemctl daemon-reload systemctl daemon-reload
print_success "Systemd service installed" print_success "Systemd service installed"
else else
print_warning "Systemd service file not found, creating basic one..." print_warning "Systemd service file not found, creating basic one..."
cat > /etc/systemd/system/c-relay.service << EOF cat > /etc/systemd/system/c-relay-pg.service << EOF
[Unit] [Unit]
Description=C Nostr Relay Description=C Nostr Relay
After=network.target After=network.target
@@ -146,7 +146,7 @@ Type=simple
User=$RELAY_USER User=$RELAY_USER
Group=$RELAY_USER Group=$RELAY_USER
WorkingDirectory=$INSTALL_DIR WorkingDirectory=$INSTALL_DIR
ExecStart=$INSTALL_DIR/c_relay_x86 ExecStart=$INSTALL_DIR/c_relay_pg_x86
Restart=always Restart=always
RestartSec=5 RestartSec=5
@@ -1,4 +1,4 @@
# MUSL-based fully static C-Relay builder # MUSL-based fully static C-Relay-PG builder
# Produces portable binaries with zero runtime dependencies # Produces portable binaries with zero runtime dependencies
FROM alpine:latest AS builder FROM alpine:latest AS builder
@@ -125,7 +125,7 @@ RUN cd /tmp && \
--prefix=/usr && \ --prefix=/usr && \
make && make install make && make install
# Copy c-relay source # Copy c-relay-pg source
COPY . /build/ COPY . /build/
# Initialize submodules # Initialize submodules
@@ -134,7 +134,7 @@ RUN git submodule update --init --recursive
# Build nostr_core_lib # Build nostr_core_lib
RUN cd nostr_core_lib && ./build.sh RUN cd nostr_core_lib && ./build.sh
# Build c-relay static # Build c-relay-pg static
RUN make clean && \ RUN make clean && \
CC="musl-gcc -static" \ CC="musl-gcc -static" \
CFLAGS="-O2 -Wall -Wextra -std=c99 -g" \ CFLAGS="-O2 -Wall -Wextra -std=c99 -g" \
@@ -143,8 +143,8 @@ RUN make clean && \
make make
# Strip binary for size # Strip binary for size
RUN strip build/c_relay_x86 RUN strip build/c_relay_pg_x86
# Multi-stage build to produce minimal output # Multi-stage build to produce minimal output
FROM scratch AS output FROM scratch AS output
COPY --from=builder /build/build/c_relay_x86 /c_relay_static_musl_x86_64 COPY --from=builder /build/build/c_relay_pg_x86 /c_relay_pg_static_musl_x86_64
+8 -8
View File
@@ -19,7 +19,7 @@ RELEASE_MODE=false
VERSION_INCREMENT_TYPE="patch" # "patch", "minor", or "major" VERSION_INCREMENT_TYPE="patch" # "patch", "minor", or "major"
show_usage() { show_usage() {
echo "C-Relay Increment and Push Script" echo "C-Relay-PG Increment and Push Script"
echo "" echo ""
echo "USAGE:" echo "USAGE:"
echo " $0 [OPTIONS] \"commit message\"" echo " $0 [OPTIONS] \"commit message\""
@@ -330,7 +330,7 @@ build_release_binary() {
create_source_tarball() { create_source_tarball() {
print_status "Creating source tarball..." print_status "Creating source tarball..."
local tarball_name="c-relay-${NEW_VERSION#v}.tar.gz" local tarball_name="c-relay-pg-${NEW_VERSION#v}.tar.gz"
# Create tarball excluding build artifacts and git files # Create tarball excluding build artifacts and git files
if tar -czf "$tarball_name" \ if tar -czf "$tarball_name" \
@@ -365,7 +365,7 @@ upload_release_assets() {
fi fi
local token=$(cat "$HOME/.gitea_token" | tr -d '\n\r') local token=$(cat "$HOME/.gitea_token" | tr -d '\n\r')
local api_url="https://git.laantungir.net/api/v1/repos/laantungir/c-relay" local api_url="https://git.laantungir.net/api/v1/repos/laantungir/c-relay-pg"
local assets_url="$api_url/releases/$release_id/assets" local assets_url="$api_url/releases/$release_id/assets"
print_status "Assets URL: $assets_url" print_status "Assets URL: $assets_url"
@@ -427,7 +427,7 @@ create_gitea_release() {
fi fi
local token=$(cat "$HOME/.gitea_token" | tr -d '\n\r') local token=$(cat "$HOME/.gitea_token" | tr -d '\n\r')
local api_url="https://git.laantungir.net/api/v1/repos/laantungir/c-relay" local api_url="https://git.laantungir.net/api/v1/repos/laantungir/c-relay-pg"
# Create release # Create release
print_status "Creating release $NEW_VERSION..." print_status "Creating release $NEW_VERSION..."
@@ -473,7 +473,7 @@ create_gitea_release() {
# Main execution # Main execution
main() { main() {
print_status "C-Relay Increment and Push Script" print_status "C-Relay-PG Increment and Push Script"
# Check prerequisites # Check prerequisites
check_git_repo check_git_repo
@@ -505,13 +505,13 @@ main() {
# Build release binary # Build release binary
if build_release_binary; then if build_release_binary; then
local binary_path="build/c_relay_static_x86_64" local binary_path="build/c_relay_pg_static_x86_64"
else else
print_warning "Binary build failed, continuing with release creation" print_warning "Binary build failed, continuing with release creation"
# Check if binary exists from previous build # Check if binary exists from previous build
if [[ -f "build/c_relay_static_x86_64" ]]; then if [[ -f "build/c_relay_pg_static_x86_64" ]]; then
print_status "Using existing binary from previous build" print_status "Using existing binary from previous build"
binary_path="build/c_relay_static_x86_64" binary_path="build/c_relay_pg_static_x86_64"
else else
binary_path="" binary_path=""
fi fi
+10 -10
View File
@@ -1,6 +1,6 @@
#!/bin/bash #!/bin/bash
# C-Relay Build and Restart Script # C-Relay-PG Build and Restart Script
# Builds the project first, then stops any running relay and starts a new one in the background # Builds the project first, then stops any running relay and starts a new one in the background
echo "=== C Nostr Relay Build and Restart Script ===" echo "=== C Nostr Relay Build and Restart Script ==="
@@ -242,13 +242,13 @@ fi
ARCH=$(uname -m) ARCH=$(uname -m)
case "$ARCH" in case "$ARCH" in
x86_64) x86_64)
BINARY_PATH="./build/c_relay_static_x86_64" BINARY_PATH="./build/c_relay_pg_static_x86_64"
;; ;;
aarch64|arm64) aarch64|arm64)
BINARY_PATH="./build/c_relay_static_arm64" BINARY_PATH="./build/c_relay_pg_static_arm64"
;; ;;
*) *)
BINARY_PATH="./build/c_relay_static_$ARCH" BINARY_PATH="./build/c_relay_pg_static_$ARCH"
;; ;;
esac esac
@@ -270,7 +270,7 @@ echo "Build successful. Proceeding with relay restart..."
echo "Stopping any existing relay servers..." echo "Stopping any existing relay servers..."
# Get all relay processes and kill them immediately with -9 # Get all relay processes and kill them immediately with -9
RELAY_PIDS=$(pgrep -f "c_relay_" || echo "") RELAY_PIDS=$(pgrep -f "c_relay_pg_" || echo "")
if [ -n "$RELAY_PIDS" ]; then if [ -n "$RELAY_PIDS" ]; then
echo "Force killing relay processes immediately: $RELAY_PIDS" echo "Force killing relay processes immediately: $RELAY_PIDS"
kill -9 $RELAY_PIDS 2>/dev/null kill -9 $RELAY_PIDS 2>/dev/null
@@ -291,7 +291,7 @@ for attempt in {1..15}; do
fuser -k 8888/tcp 2>/dev/null || true fuser -k 8888/tcp 2>/dev/null || true
# Double-check for any remaining relay processes # Double-check for any remaining relay processes
REMAINING_PIDS=$(pgrep -f "c_relay_" || echo "") REMAINING_PIDS=$(pgrep -f "c_relay_pg_" || echo "")
if [ -n "$REMAINING_PIDS" ]; then if [ -n "$REMAINING_PIDS" ]; then
echo "Killing remaining relay processes: $REMAINING_PIDS" echo "Killing remaining relay processes: $REMAINING_PIDS"
kill -9 $REMAINING_PIDS 2>/dev/null || true kill -9 $REMAINING_PIDS 2>/dev/null || true
@@ -309,7 +309,7 @@ for attempt in {1..15}; do
done done
# Final safety check - ensure no relay processes remain # Final safety check - ensure no relay processes remain
FINAL_PIDS=$(pgrep -f "c_relay_" || echo "") FINAL_PIDS=$(pgrep -f "c_relay_pg_" || echo "")
if [ -n "$FINAL_PIDS" ]; then if [ -n "$FINAL_PIDS" ]; then
echo "Final cleanup: killing processes $FINAL_PIDS" echo "Final cleanup: killing processes $FINAL_PIDS"
kill -9 $FINAL_PIDS 2>/dev/null || true kill -9 $FINAL_PIDS 2>/dev/null || true
@@ -325,7 +325,7 @@ echo "Database will be initialized automatically on startup if needed"
# Start relay in background with output redirection # Start relay in background with output redirection
echo "Starting relay server..." echo "Starting relay server..."
echo "Debug: Current processes: $(ps aux | grep 'c_relay_' | grep -v grep || echo 'None')" echo "Debug: Current processes: $(ps aux | grep 'c_relay_pg_' | grep -v grep || echo 'None')"
# Build command line arguments for relay binary # Build command line arguments for relay binary
RELAY_ARGS="" RELAY_ARGS=""
@@ -428,8 +428,8 @@ if ps -p "$RELAY_PID" >/dev/null 2>&1; then
echo "=== Event-Based Relay Server Running ===" echo "=== Event-Based Relay Server Running ==="
echo "Configuration: Event-based (kind 33334 Nostr events)" echo "Configuration: Event-based (kind 33334 Nostr events)"
echo "Database: Automatically created with relay pubkey naming" echo "Database: Automatically created with relay pubkey naming"
echo "To kill relay: pkill -f 'c_relay_'" echo "To kill relay: pkill -f 'c_relay_pg_'"
echo "To check status: ps aux | grep c_relay_" echo "To check status: ps aux | grep c_relay_pg_"
echo "To view logs: tail -f relay.log" echo "To view logs: tail -f relay.log"
echo "Binary: $BINARY_PATH (zero configuration needed)" echo "Binary: $BINARY_PATH (zero configuration needed)"
echo "Ready for Nostr client connections!" echo "Ready for Nostr client connections!"
+12 -12
View File
@@ -12,11 +12,11 @@ After the next crash, analyze it:
# List all core dumps (most recent first) # List all core dumps (most recent first)
sudo coredumpctl list sudo coredumpctl list
# View info about the most recent c-relay crash # View info about the most recent c-relay-pg crash
sudo coredumpctl info c-relay sudo coredumpctl info c-relay-pg
# Load the core dump in gdb for detailed analysis # Load the core dump in gdb for detailed analysis
sudo coredumpctl gdb c-relay sudo coredumpctl gdb c-relay-pg
Inside gdb, run these commands: Inside gdb, run these commands:
(gdb) bt full # Full backtrace with all variables (gdb) bt full # Full backtrace with all variables
@@ -36,8 +36,8 @@ DEBUGGING
Even simpler: Use this one-liner Even simpler: Use this one-liner
# Start relay and immediately attach gdb # Start relay and immediately attach gdb
cd /usr/local/bin/c_relay cd /usr/local/bin/c_relay_pg
sudo -u c-relay ./c_relay --debug-level=5 & sleep 2 && sudo gdb -p $(pgrep c_relay) sudo -u c-relay-pg ./c_relay_pg --debug-level=5 & sleep 2 && sudo gdb -p $(pgrep c_relay_pg)
Inside gdb, after attaching: Inside gdb, after attaching:
@@ -48,17 +48,17 @@ Or shorter:
How to View the Logs How to View the Logs
Check systemd journal: Check systemd journal:
# View all c-relay logs # View all c-relay-pg logs
sudo journalctl -u c-relay sudo journalctl -u c-relay-pg
# View recent logs (last 50 lines) # View recent logs (last 50 lines)
sudo journalctl -u c-relay -n 50 sudo journalctl -u c-relay-pg -n 50
# Follow logs in real-time # Follow logs in real-time
sudo journalctl -u c-relay -f sudo journalctl -u c-relay-pg -f
# View logs since last boot # View logs since last boot
sudo journalctl -u c-relay -b sudo journalctl -u c-relay-pg -b
Check if service is running: Check if service is running:
@@ -78,9 +78,9 @@ sudo systemctl start rsyslog
sudo systemctl status rsyslog sudo systemctl status rsyslog
sudo -u c-relay ./c_relay --debug-level=5 -r 85d0b37e2ae822966dcadd06b2dc9368cde73865f90ea4d44f8b57d47ef0820a -a 1ec454734dcbf6fe54901ce25c0c7c6bca5edd89443416761fadc321d38df139 sudo -u c-relay-pg ./c_relay_pg --debug-level=5 -r 85d0b37e2ae822966dcadd06b2dc9368cde73865f90ea4d44f8b57d47ef0820a -a 1ec454734dcbf6fe54901ce25c0c7c6bca5edd89443416761fadc321d38df139
./c_relay_static_x86_64 -p 7889 --debug-level=5 -r 85d0b37e2ae822966dcadd06b2dc9368cde73865f90ea4d44f8b57d47ef0820a -a 1ec454734dcbf6fe54901ce25c0c7c6bca5edd89443416761fadc321d38df139 ./c_relay_pg_static_x86_64 -p 7889 --debug-level=5 -r 85d0b37e2ae822966dcadd06b2dc9368cde73865f90ea4d44f8b57d47ef0820a -a 1ec454734dcbf6fe54901ce25c0c7c6bca5edd89443416761fadc321d38df139
sudo ufw allow 8888/tcp sudo ufw allow 8888/tcp
+1 -1
View File
@@ -1,5 +1,5 @@
{ {
"name": "c-relay", "name": "c-relay-pg",
"lockfileVersion": 3, "lockfileVersion": 3,
"requires": true, "requires": true,
"packages": { "packages": {
+34 -34
View File
@@ -1,17 +1,17 @@
# c-relay-pg Plan — PostgreSQL Backend + Multi-Instance + Dashboard # c-relay-pg-pg Plan — PostgreSQL Backend + Multi-Instance + Dashboard
## Overview ## Overview
**c-relay-pg** is a new project (separate repository) forked from c-relay after the `db_ops` abstraction layer is complete. It replaces the SQLite backend with PostgreSQL, enabling horizontal scaling, external dashboards, and production-grade deployments. **c-relay-pg-pg** is a new project (separate repository) forked from c-relay-pg after the `db_ops` abstraction layer is complete. It replaces the SQLite backend with PostgreSQL, enabling horizontal scaling, external dashboards, and production-grade deployments.
### Prerequisites ### Prerequisites
- The `db_ops.h` / `db_ops.c` abstraction layer must be complete in c-relay first — see [c-relay thread pool plan](c_relay_thread_pool_plan.md) Phase 1. - The `db_ops.h` / `db_ops.c` abstraction layer must be complete in c-relay-pg first — see [c-relay-pg thread pool plan](c_relay_pg_thread_pool_plan.md) Phase 1.
- The fork happens after Phase 1 of that plan is done and tested. - The fork happens after Phase 1 of that plan is done and tested.
### Why a Separate Project? ### Why a Separate Project?
| | c-relay | c-relay-pg | | | c-relay-pg | c-relay-pg-pg |
|---|---------|-----------| |---|---------|-----------|
| **Database** | SQLite (embedded) | PostgreSQL (client-server) | | **Database** | SQLite (embedded) | PostgreSQL (client-server) |
| **Deployment** | Single binary + DB file | Binary + PostgreSQL server | | **Deployment** | Single binary + DB file | Binary + PostgreSQL server |
@@ -26,9 +26,9 @@ For the full analysis of why PostgreSQL was chosen over MySQL/MariaDB and other
```mermaid ```mermaid
flowchart TD flowchart TD
subgraph c-relay-pg - Production Deployment subgraph c-relay-pg-pg - Production Deployment
LB[nginx - TLS + load balancing] -->|WebSocket| R1[c-relay-pg Instance 1] LB[nginx - TLS + load balancing] -->|WebSocket| R1[c-relay-pg-pg Instance 1]
LB -->|WebSocket| R2[c-relay-pg Instance 2] LB -->|WebSocket| R2[c-relay-pg-pg Instance 2]
LB -->|HTTP| DASH[Dashboard] LB -->|HTTP| DASH[Dashboard]
R1 -->|db_ops API| PGBACK[PostgreSQL Backend - db_ops_postgres.c] R1 -->|db_ops API| PGBACK[PostgreSQL Backend - db_ops_postgres.c]
R2 -->|db_ops API| PGBACK R2 -->|db_ops API| PGBACK
@@ -44,18 +44,18 @@ flowchart TD
### Goal ### Goal
Fork c-relay into a new repository called **c-relay-pg**. Replace the SQLite `db_ops` implementation with PostgreSQL using `libpq`. The `db_ops.h` interface stays identical — only the backend changes. Fork c-relay-pg into a new repository called **c-relay-pg-pg**. Replace the SQLite `db_ops` implementation with PostgreSQL using `libpq`. The `db_ops.h` interface stays identical — only the backend changes.
### New Files ### New Files
- `src/db_ops_sqlite.c` — Renamed from `db_ops.c` (the Phase 1 SQLite implementation from c-relay) - `src/db_ops_sqlite.c` — Renamed from `db_ops.c` (the Phase 1 SQLite implementation from c-relay-pg)
- `src/db_ops_postgres.c` — New PostgreSQL implementation - `src/db_ops_postgres.c` — New PostgreSQL implementation
- `src/db_ops.c` — Thin dispatcher that calls the active backend - `src/db_ops.c` — Thin dispatcher that calls the active backend
### PostgreSQL Schema ### PostgreSQL Schema
```sql ```sql
-- PostgreSQL schema for c-relay-pg -- PostgreSQL schema for c-relay-pg-pg
-- No event_tags table needed — JSONB + GIN handles everything -- No event_tags table needed — JSONB + GIN handles everything
CREATE TABLE events ( CREATE TABLE events (
@@ -289,14 +289,14 @@ psql -d crelay -c "REFRESH MATERIALIZED VIEW event_kinds_mv; REFRESH MATERIALIZE
### Goal ### Goal
Run multiple c-relay-pg instances behind a load balancer with a separate dashboard web server, all sharing the same PostgreSQL database. Run multiple c-relay-pg-pg instances behind a load balancer with a separate dashboard web server, all sharing the same PostgreSQL database.
### Components ### Components
1. **nginx config** — WebSocket load balancing with `ip_hash` stickiness 1. **nginx config** — WebSocket load balancing with `ip_hash` stickiness
2. **systemd template**`c-relay-pg@.service` for multiple instances 2. **systemd template**`c-relay-pg-pg@.service` for multiple instances
3. **LISTEN/NOTIFY integration** — Cross-instance event broadcasting in the `lws_service()` loop 3. **LISTEN/NOTIFY integration** — Cross-instance event broadcasting in the `lws_service()` loop
4. **PgBouncer** — Connection pooling between c-relay-pg instances and PostgreSQL 4. **PgBouncer** — Connection pooling between c-relay-pg-pg instances and PostgreSQL
5. **Dashboard** — Separate web server querying PostgreSQL directly 5. **Dashboard** — Separate web server querying PostgreSQL directly
6. **Materialized view refresh** — Background job to refresh analytics views 6. **Materialized view refresh** — Background job to refresh analytics views
@@ -306,9 +306,9 @@ Run multiple c-relay-pg instances behind a load balancer with a separate dashboa
flowchart TD flowchart TD
INTERNET[Internet - Nostr Clients] -->|wss://relay.example.com| NGINX[nginx reverse proxy - TLS termination + load balancing] INTERNET[Internet - Nostr Clients] -->|wss://relay.example.com| NGINX[nginx reverse proxy - TLS termination + load balancing]
NGINX -->|ws://localhost:8888| R1[c-relay-pg Instance 1 - port 8888] NGINX -->|ws://localhost:8888| R1[c-relay-pg-pg Instance 1 - port 8888]
NGINX -->|ws://localhost:8889| R2[c-relay-pg Instance 2 - port 8889] NGINX -->|ws://localhost:8889| R2[c-relay-pg-pg Instance 2 - port 8889]
NGINX -->|ws://localhost:8890| R3[c-relay-pg Instance 3 - port 8890] NGINX -->|ws://localhost:8890| R3[c-relay-pg-pg Instance 3 - port 8890]
NGINX -->|http://localhost:3000| DASHWEB[Dashboard Web Server] NGINX -->|http://localhost:3000| DASHWEB[Dashboard Web Server]
R1 -->|libpq connection pool| PGPOOL[PgBouncer - connection pooler] R1 -->|libpq connection pool| PGPOOL[PgBouncer - connection pooler]
@@ -325,7 +325,7 @@ flowchart TD
### nginx Load Balancing Config ### nginx Load Balancing Config
```nginx ```nginx
# nginx.conf - WebSocket load balancing for c-relay-pg # nginx.conf - WebSocket load balancing for c-relay-pg-pg
upstream relay_backends { upstream relay_backends {
# ip_hash ensures a client always hits the same instance # ip_hash ensures a client always hits the same instance
# (important for WebSocket session stickiness) # (important for WebSocket session stickiness)
@@ -366,35 +366,35 @@ Each instance is the same binary, just on a different port, all pointing to the
```bash ```bash
# Instance 1 # Instance 1
./build/c_relay_x86 --port 8888 --db-host localhost --db-name crelay & ./build/c_relay_pg_x86 --port 8888 --db-host localhost --db-name crelay &
# Instance 2 # Instance 2
./build/c_relay_x86 --port 8889 --db-host localhost --db-name crelay & ./build/c_relay_pg_x86 --port 8889 --db-host localhost --db-name crelay &
# Instance 3 # Instance 3
./build/c_relay_x86 --port 8890 --db-host localhost --db-name crelay & ./build/c_relay_pg_x86 --port 8890 --db-host localhost --db-name crelay &
``` ```
Or with systemd template units: Or with systemd template units:
```ini ```ini
# /etc/systemd/system/c-relay-pg@.service # /etc/systemd/system/c-relay-pg-pg@.service
[Unit] [Unit]
Description=C-Relay-PG Nostr Instance %i Description=C-Relay-PG-PG Nostr Instance %i
After=postgresql.service After=postgresql.service
[Service] [Service]
ExecStart=/opt/c-relay-pg/c_relay_x86 --port %i --db-host localhost --db-name crelay ExecStart=/opt/c-relay-pg-pg/c_relay_pg_x86 --port %i --db-host localhost --db-name crelay
Restart=always Restart=always
User=c-relay User=c-relay-pg
[Install] [Install]
WantedBy=multi-user.target WantedBy=multi-user.target
``` ```
```bash ```bash
systemctl enable c-relay-pg@8888 c-relay-pg@8889 c-relay-pg@8890 systemctl enable c-relay-pg-pg@8888 c-relay-pg-pg@8889 c-relay-pg-pg@8890
systemctl start c-relay-pg@8888 c-relay-pg@8889 c-relay-pg@8890 systemctl start c-relay-pg-pg@8888 c-relay-pg-pg@8889 c-relay-pg-pg@8890
``` ```
### Cross-Instance Event Broadcasting ### Cross-Instance Event Broadcasting
@@ -559,13 +559,13 @@ for port in 8888 8889 8890; do
sleep 30 sleep 30
# 3. Stop old instance # 3. Stop old instance
systemctl stop c-relay-pg@$port systemctl stop c-relay-pg-pg@$port
# 4. Deploy new binary # 4. Deploy new binary
cp ./build/c_relay_x86 /opt/c-relay-pg/c_relay_x86 cp ./build/c_relay_pg_x86 /opt/c-relay-pg-pg/c_relay_pg_x86
# 5. Start new instance # 5. Start new instance
systemctl start c-relay-pg@$port systemctl start c-relay-pg-pg@$port
# 6. Wait for health check # 6. Wait for health check
sleep 5 sleep 5
@@ -584,7 +584,7 @@ With PostgreSQL, the dashboard can be built with any technology:
- **Grafana** — Point directly at PostgreSQL, zero custom code - **Grafana** — Point directly at PostgreSQL, zero custom code
- **Custom web app** — React/Vue frontend + any backend (Node, Python, Go) querying PostgreSQL - **Custom web app** — React/Vue frontend + any backend (Node, Python, Go) querying PostgreSQL
- **Embedded in c-relay-pg** — Keep current approach but queries go through `db_ops` to PostgreSQL (no longer blocks event loop since PostgreSQL handles concurrency) - **Embedded in c-relay-pg-pg** — Keep current approach but queries go through `db_ops` to PostgreSQL (no longer blocks event loop since PostgreSQL handles concurrency)
### Scaling Scenarios ### Scaling Scenarios
@@ -622,11 +622,11 @@ Running multiple relay instances with PostgreSQL on a single VPS:
--- ---
## Relationship to c-relay ## Relationship to c-relay-pg
This project depends on the `db_ops.h` abstraction layer built in [c-relay thread pool plan](c_relay_thread_pool_plan.md) Phase 1. The interface is identical — only the backend implementation changes: This project depends on the `db_ops.h` abstraction layer built in [c-relay-pg thread pool plan](c_relay_pg_thread_pool_plan.md) Phase 1. The interface is identical — only the backend implementation changes:
- **c-relay**: `db_ops.c` → SQLite calls via `sqlite3_*` - **c-relay-pg**: `db_ops.c` → SQLite calls via `sqlite3_*`
- **c-relay-pg**: `db_ops_postgres.c` → PostgreSQL calls via `libpq` (`PQexec`, `PQgetvalue`, etc.) - **c-relay-pg-pg**: `db_ops_postgres.c` → PostgreSQL calls via `libpq` (`PQexec`, `PQgetvalue`, etc.)
The `db_ops.h` header file is shared between both projects. Changes to the interface should be coordinated. The `db_ops.h` header file is shared between both projects. Changes to the interface should be coordinated.
+9 -9
View File
@@ -1,13 +1,13 @@
# c-relay Thread Pool Plan — db_ops Abstraction + SQLite Thread Pool # c-relay-pg Thread Pool Plan — db_ops Abstraction + SQLite Thread Pool
## Overview ## Overview
This plan covers improvements to **c-relay** (this repo) — the lean, single-binary, embedded-SQLite Nostr relay. Two phases: This plan covers improvements to **c-relay-pg** (this repo) — the lean, single-binary, embedded-SQLite Nostr relay. Two phases:
1. **Phase 1: Database Abstraction Layer** — Consolidate all scattered `sqlite3_*` calls into a single `db_ops.h` / `db_ops.c` module. Pure refactor, no behavior change. 1. **Phase 1: Database Abstraction Layer** — Consolidate all scattered `sqlite3_*` calls into a single `db_ops.h` / `db_ops.c` module. Pure refactor, no behavior change.
2. **Phase 2: SQLite Thread Pool** — Add worker threads for concurrent reads, unblocking the `lws_service()` event loop. 2. **Phase 2: SQLite Thread Pool** — Add worker threads for concurrent reads, unblocking the `lws_service()` event loop.
This is the **final form of c-relay**: an embedded-SQLite relay with clean architecture and non-blocking database access. The abstraction layer also enables a future fork to PostgreSQL — see [c-relay-pg plan](c_relay_pg_plan.md). This is the **final form of c-relay-pg**: an embedded-SQLite relay with clean architecture and non-blocking database access. The abstraction layer also enables a future fork to PostgreSQL — see [c-relay-pg-pg plan](c_relay_pg_pg_plan.md).
### Why This First? ### Why This First?
@@ -25,15 +25,15 @@ The current architecture has a fundamental bottleneck documented in the [databas
```mermaid ```mermaid
flowchart TD flowchart TD
subgraph c-relay - Final Form subgraph c-relay-pg - Final Form
RELAY[c-relay binary] -->|db_ops API| DBOPS[db_ops.c - abstraction layer] RELAY[c-relay-pg binary] -->|db_ops API| DBOPS[db_ops.c - abstraction layer]
DBOPS -->|sqlite3 calls| SQLITE[SQLite WAL database] DBOPS -->|sqlite3 calls| SQLITE[SQLite WAL database]
end end
``` ```
```mermaid ```mermaid
flowchart TD flowchart TD
subgraph c-relay with Thread Pool subgraph c-relay-pg with Thread Pool
LWS[lws_service event loop] -->|REQ arrives| Q[Thread-safe job queue] LWS[lws_service event loop] -->|REQ arrives| Q[Thread-safe job queue]
LWS -->|EVENT arrives| WQ[Write queue - single writer] LWS -->|EVENT arrives| WQ[Write queue - single writer]
Q --> T1[Reader Thread 1 - own sqlite3*] Q --> T1[Reader Thread 1 - own sqlite3*]
@@ -322,11 +322,11 @@ int thread_pool_submit_write(db_job_t* job);
--- ---
## Relationship to c-relay-pg ## Relationship to c-relay-pg-pg
After Phase 1 (abstraction layer) is complete, the codebase is ready to be forked into a separate **c-relay-pg** project that replaces the SQLite backend with PostgreSQL. See [c-relay-pg plan](c_relay_pg_plan.md) for details. After Phase 1 (abstraction layer) is complete, the codebase is ready to be forked into a separate **c-relay-pg-pg** project that replaces the SQLite backend with PostgreSQL. See [c-relay-pg-pg plan](c_relay_pg_pg_plan.md) for details.
The `db_ops.h` interface is designed to work with any backend: The `db_ops.h` interface is designed to work with any backend:
- **SQLite** (this plan): `db_result_next_json()` copies from `sqlite3_column_text()` - **SQLite** (this plan): `db_result_next_json()` copies from `sqlite3_column_text()`
- **PostgreSQL** (c-relay-pg): `db_result_next_json()` returns from `PQgetvalue()` - **PostgreSQL** (c-relay-pg-pg): `db_result_next_json()` returns from `PQgetvalue()`
- **LMDB** (future possibility): `db_result_next_json()` returns a zero-copy pointer into mmap'd memory - **LMDB** (future possibility): `db_result_next_json()` returns a zero-copy pointer into mmap'd memory
+19 -19
View File
@@ -2,7 +2,7 @@
## Current Architecture Problem ## Current Architecture Problem
The c-relay runs a **single-threaded event loop** via `lws_service()` in [`start_websocket_relay()`](src/websockets.c:2637). Every WebSocket callback — including [`handle_req_message()`](src/main.c:1101) and [`store_event()`](src/main.c:787) — executes **synchronously** inside this loop. When a REQ query takes 672ms (as documented in your [query analysis report](query_analysis_report.md:39)), **every other connected client is frozen** for that duration. The c-relay-pg runs a **single-threaded event loop** via `lws_service()` in [`start_websocket_relay()`](src/websockets.c:2637). Every WebSocket callback — including [`handle_req_message()`](src/main.c:1101) and [`store_event()`](src/main.c:787) — executes **synchronously** inside this loop. When a REQ query takes 672ms (as documented in your [query analysis report](query_analysis_report.md:39)), **every other connected client is frozen** for that duration.
### The Blocking Chain ### The Blocking Chain
@@ -183,7 +183,7 @@ LMDB is an embedded key-value store created by Howard Chu for OpenLDAP. It's wha
- **Zero-copy reads**: When you read a value, you get a pointer directly into the mmap'd region. No `malloc`, no `memcpy`. - **Zero-copy reads**: When you read a value, you get a pointer directly into the mmap'd region. No `malloc`, no `memcpy`.
- **Single-writer, multiple-reader**: Like SQLite WAL, but implemented at a much lower level with near-zero overhead. - **Single-writer, multiple-reader**: Like SQLite WAL, but implemented at a much lower level with near-zero overhead.
### How It Would Work for c-relay ### How It Would Work for c-relay-pg
LMDB is a **key-value store**, not a relational database. There's no SQL. You design your own indexes as separate "databases" (sub-B-trees within the same file): LMDB is a **key-value store**, not a relational database. There's no SQL. You design your own indexes as separate "databases" (sub-B-trees within the same file):
@@ -216,7 +216,7 @@ strfry doesn't use SQL at all. When a REQ comes in with `kinds: [1], #p: [pubkey
4. For each ID, does a direct pointer lookup in the events B-tree 4. For each ID, does a direct pointer lookup in the events B-tree
5. Returns the raw bytes — zero-copy, no JSON parsing, no serialization 5. Returns the raw bytes — zero-copy, no JSON parsing, no serialization
Compare this to your current c-relay flow: Compare this to your current c-relay-pg flow:
1. Build SQL string with parameter binding 1. Build SQL string with parameter binding
2. `sqlite3_prepare_v2()` — parse SQL, build query plan 2. `sqlite3_prepare_v2()` — parse SQL, build query plan
3. `sqlite3_step()` — traverse B-tree, copy data to SQLite's page cache, then copy to your buffer 3. `sqlite3_step()` — traverse B-tree, copy data to SQLite's page cache, then copy to your buffer
@@ -505,9 +505,9 @@ With a client-server database, you unlock something fundamentally impossible wit
flowchart TD flowchart TD
INTERNET[Internet - Nostr Clients] -->|wss://relay.example.com| NGINX[nginx reverse proxy - TLS termination + load balancing] INTERNET[Internet - Nostr Clients] -->|wss://relay.example.com| NGINX[nginx reverse proxy - TLS termination + load balancing]
NGINX -->|ws://localhost:8888| R1[c-relay Instance 1 - port 8888] NGINX -->|ws://localhost:8888| R1[c-relay-pg Instance 1 - port 8888]
NGINX -->|ws://localhost:8889| R2[c-relay Instance 2 - port 8889] NGINX -->|ws://localhost:8889| R2[c-relay-pg Instance 2 - port 8889]
NGINX -->|ws://localhost:8890| R3[c-relay Instance 3 - port 8890] NGINX -->|ws://localhost:8890| R3[c-relay-pg Instance 3 - port 8890]
NGINX -->|http://localhost:3000| DASHWEB[Dashboard Web Server] NGINX -->|http://localhost:3000| DASHWEB[Dashboard Web Server]
R1 -->|libpq connection pool| PGPOOL[PgBouncer - connection pooler] R1 -->|libpq connection pool| PGPOOL[PgBouncer - connection pooler]
@@ -526,7 +526,7 @@ flowchart TD
nginx already handles TLS termination for most Nostr relays. Adding WebSocket load balancing is a small configuration change: nginx already handles TLS termination for most Nostr relays. Adding WebSocket load balancing is a small configuration change:
```nginx ```nginx
# nginx.conf - WebSocket load balancing for c-relay # nginx.conf - WebSocket load balancing for c-relay-pg
upstream relay_backends { upstream relay_backends {
# ip_hash ensures a client always hits the same instance # ip_hash ensures a client always hits the same instance
# (important for WebSocket session stickiness) # (important for WebSocket session stickiness)
@@ -567,35 +567,35 @@ Each instance is the same binary, just on a different port, all pointing to the
```bash ```bash
# Instance 1 # Instance 1
./build/c_relay_x86 --port 8888 --db-host localhost --db-name crelay & ./build/c_relay_pg_x86 --port 8888 --db-host localhost --db-name crelay &
# Instance 2 # Instance 2
./build/c_relay_x86 --port 8889 --db-host localhost --db-name crelay & ./build/c_relay_pg_x86 --port 8889 --db-host localhost --db-name crelay &
# Instance 3 # Instance 3
./build/c_relay_x86 --port 8890 --db-host localhost --db-name crelay & ./build/c_relay_pg_x86 --port 8890 --db-host localhost --db-name crelay &
``` ```
Or with systemd, you'd use a template unit: Or with systemd, you'd use a template unit:
```ini ```ini
# /etc/systemd/system/c-relay@.service # /etc/systemd/system/c-relay-pg@.service
[Unit] [Unit]
Description=C-Relay Nostr Instance %i Description=C-Relay-PG Nostr Instance %i
After=postgresql.service After=postgresql.service
[Service] [Service]
ExecStart=/opt/c-relay/c_relay_x86 --port %i --db-host localhost --db-name crelay ExecStart=/opt/c-relay-pg/c_relay_pg_x86 --port %i --db-host localhost --db-name crelay
Restart=always Restart=always
User=c-relay User=c-relay-pg
[Install] [Install]
WantedBy=multi-user.target WantedBy=multi-user.target
``` ```
```bash ```bash
systemctl enable c-relay@8888 c-relay@8889 c-relay@8890 systemctl enable c-relay-pg@8888 c-relay-pg@8889 c-relay-pg@8890
systemctl start c-relay@8888 c-relay@8889 c-relay@8890 systemctl start c-relay-pg@8888 c-relay-pg@8889 c-relay-pg@8890
``` ```
### The Subscription Broadcasting Challenge (Detailed) ### The Subscription Broadcasting Challenge (Detailed)
@@ -741,13 +741,13 @@ for port in 8888 8889 8890; do
sleep 30 sleep 30
# 3. Stop old instance # 3. Stop old instance
systemctl stop c-relay@$port systemctl stop c-relay-pg@$port
# 4. Deploy new binary # 4. Deploy new binary
cp ./build/c_relay_x86 /opt/c-relay/c_relay_x86 cp ./build/c_relay_pg_x86 /opt/c-relay-pg/c_relay_pg_x86
# 5. Start new instance # 5. Start new instance
systemctl start c-relay@$port systemctl start c-relay-pg@$port
# 6. Wait for health check # 6. Wait for health check
sleep 5 sleep 5
+1 -1
View File
@@ -2,7 +2,7 @@
## Problem Statement ## Problem Statement
The main `c_relay` thread consumes ~56% CPU while the DB worker threads (`db-read-1..4`, `db-write`) sit near 0%. All protocol handling, JSON parsing, event validation, subscription matching, and message queueing happens synchronously inside `nostr_relay_callback()` on the main libwebsockets event-loop thread. The main `c_relay_pg` thread consumes ~56% CPU while the DB worker threads (`db-read-1..4`, `db-write`) sit near 0%. All protocol handling, JSON parsing, event validation, subscription matching, and message queueing happens synchronously inside `nostr_relay_callback()` on the main libwebsockets event-loop thread.
## Current Architecture ## Current Architecture
+3 -3
View File
@@ -1,8 +1,8 @@
# C-Relay Memory Leak Investigation & Fix Plan # C-Relay-PG Memory Leak Investigation & Fix Plan
## Problem Statement ## Problem Statement
c-relay reached **1.56 GB** of its 1.5 GB `MemoryHigh` cgroup limit after only **1 hour 37 minutes** of runtime. The kernel is actively throttling the process with swap pressure (1.8M swap used). This strongly indicates one or more memory leaks causing unbounded growth. c-relay-pg reached **1.56 GB** of its 1.5 GB `MemoryHigh` cgroup limit after only **1 hour 37 minutes** of runtime. The kernel is actively throttling the process with swap pressure (1.8M swap used). This strongly indicates one or more memory leaks causing unbounded growth.
## Root Cause Analysis ## Root Cause Analysis
@@ -187,7 +187,7 @@ Add `free((char*)result)` after every `get_config_value()` call that doesn't alr
While fixes are being implemented: While fixes are being implemented:
1. **Raise `MemoryHigh`** to 2 GB in the systemd unit to prevent throttling 1. **Raise `MemoryHigh`** to 2 GB in the systemd unit to prevent throttling
2. **Add a cron job** to restart the service every 12-24 hours 2. **Add a cron job** to restart the service every 12-24 hours
3. **Monitor with**: `watch -n 5 'cat /proc/$(pgrep c_relay)/status | grep -E "VmRSS|VmSwap"'` 3. **Monitor with**: `watch -n 5 'cat /proc/$(pgrep c_relay_pg)/status | grep -E "VmRSS|VmSwap"'`
--- ---
+1 -1
View File
@@ -2274,7 +2274,7 @@ int main(int argc, char* argv[]) {
// All configuration is loaded from database events // All configuration is loaded from database events
// Initialize unified request validator system // Initialize unified request validator system
if (ginxsom_request_validator_init(g_database_path, "c-relay") != 0) { if (ginxsom_request_validator_init(g_database_path, "c-relay-pg") != 0) {
DEBUG_ERROR("Failed to initialize unified request validator"); DEBUG_ERROR("Failed to initialize unified request validator");
cleanup_configuration_system(); cleanup_configuration_system();
nostr_cleanup(); nostr_cleanup();
+5 -5
View File
@@ -1,5 +1,5 @@
/* /*
* C-Relay Main Header - Version and Metadata Information * C-Relay-PG Main Header - Version and Metadata Information
* *
* This header contains version information and relay metadata. * This header contains version information and relay metadata.
* Version macros are auto-updated by the build system. * Version macros are auto-updated by the build system.
@@ -13,14 +13,14 @@
// Using CRELAY_ prefix to avoid conflicts with nostr_core_lib VERSION macros // Using CRELAY_ prefix to avoid conflicts with nostr_core_lib VERSION macros
#define CRELAY_VERSION_MAJOR 2 #define CRELAY_VERSION_MAJOR 2
#define CRELAY_VERSION_MINOR 1 #define CRELAY_VERSION_MINOR 1
#define CRELAY_VERSION_PATCH 8 #define CRELAY_VERSION_PATCH 9
#define CRELAY_VERSION "v2.1.8" #define CRELAY_VERSION "v2.1.9"
// Relay metadata (authoritative source for NIP-11 information) // Relay metadata (authoritative source for NIP-11 information)
#define RELAY_NAME "C-Relay" #define RELAY_NAME "C-Relay-PG"
#define RELAY_DESCRIPTION "High-performance C Nostr relay with SQLite storage" #define RELAY_DESCRIPTION "High-performance C Nostr relay with SQLite storage"
#define RELAY_CONTACT "" #define RELAY_CONTACT ""
#define RELAY_SOFTWARE "https://git.laantungir.net/laantungir/c-relay.git" #define RELAY_SOFTWARE "https://git.laantungir.net/laantungir/c-relay-pg.git"
#define RELAY_VERSION CRELAY_VERSION // Use the same version as the build #define RELAY_VERSION CRELAY_VERSION // Use the same version as the build
#define SUPPORTED_NIPS "1,2,4,9,11,12,13,15,16,20,22,33,40,42,50,70" #define SUPPORTED_NIPS "1,2,4,9,11,12,13,15,16,20,22,33,40,42,50,70"
#define LANGUAGE_TAGS "" #define LANGUAGE_TAGS ""
+1 -1
View File
@@ -1,5 +1,5 @@
/* /*
* C-Relay Request Validator - Integrated Authentication System * C-Relay-PG Request Validator - Integrated Authentication System
* *
* Provides complete request validation including: * Provides complete request validation including:
* - Protocol validation via nostr_core_lib (signatures, pubkey extraction, * - Protocol validation via nostr_core_lib (signatures, pubkey extraction,
+1 -1
View File
@@ -1,4 +1,4 @@
// Subscription system structures and functions for C-Relay // Subscription system structures and functions for C-Relay-PG
// This header defines subscription management functionality // This header defines subscription management functionality
#ifndef SUBSCRIPTIONS_H #ifndef SUBSCRIPTIONS_H
+1 -1
View File
@@ -1,4 +1,4 @@
// WebSocket protocol structures and constants for C-Relay // WebSocket protocol structures and constants for C-Relay-PG
// This header defines structures shared between main.c and websockets.c // This header defines structures shared between main.c and websockets.c
#ifndef WEBSOCKETS_H #ifndef WEBSOCKETS_H
+34 -34
View File
@@ -8,7 +8,7 @@ The C Nostr Relay now uses a revolutionary **zero-configuration** approach where
## Files ## Files
- **`c-relay.service`** - SystemD service unit file - **`c-relay-pg.service`** - SystemD service unit file
- **`install-service.sh`** - Automated installation script - **`install-service.sh`** - Automated installation script
- **`uninstall-service.sh`** - Automated uninstall script - **`uninstall-service.sh`** - Automated uninstall script
- **`README.md`** - This documentation - **`README.md`** - This documentation
@@ -27,12 +27,12 @@ The C Nostr Relay now uses a revolutionary **zero-configuration** approach where
3. **Start the service:** 3. **Start the service:**
```bash ```bash
sudo systemctl start c-relay sudo systemctl start c-relay-pg
``` ```
4. **Check admin keys (IMPORTANT!):** 4. **Check admin keys (IMPORTANT!):**
```bash ```bash
sudo journalctl -u c-relay --since="1 hour ago" | grep "Admin Private Key" sudo journalctl -u c-relay-pg --since="1 hour ago" | grep "Admin Private Key"
``` ```
## Event-Based Configuration System ## Event-Based Configuration System
@@ -61,7 +61,7 @@ On first startup, the relay will:
```bash ```bash
# View first startup logs to get admin private key # View first startup logs to get admin private key
sudo journalctl -u c-relay --since="1 hour ago" | grep -A 5 "IMPORTANT: SAVE THIS ADMIN PRIVATE KEY" sudo journalctl -u c-relay-pg --since="1 hour ago" | grep -A 5 "IMPORTANT: SAVE THIS ADMIN PRIVATE KEY"
``` ```
The admin private key is needed to update relay configuration by sending signed kind 33334 events. The admin private key is needed to update relay configuration by sending signed kind 33334 events.
@@ -72,10 +72,10 @@ The admin private key is needed to update relay configuration by sending signed
```bash ```bash
# Find the database file # Find the database file
ls /opt/c-relay/*.nrdb ls /opt/c-relay-pg/*.nrdb
# View configuration event # View configuration event
sqlite3 /opt/c-relay/<relay_pubkey>.nrdb "SELECT content, tags FROM events WHERE kind = 33334;" sqlite3 /opt/c-relay-pg/<relay_pubkey>.nrdb "SELECT content, tags FROM events WHERE kind = 33334;"
``` ```
### Updating Configuration ### Updating Configuration
@@ -93,57 +93,57 @@ Send a new kind 33334 event to the relay via WebSocket:
```bash ```bash
# Start service # Start service
sudo systemctl start c-relay sudo systemctl start c-relay-pg
# Stop service # Stop service
sudo systemctl stop c-relay sudo systemctl stop c-relay-pg
# Restart service # Restart service
sudo systemctl restart c-relay sudo systemctl restart c-relay-pg
# Enable auto-start on boot # Enable auto-start on boot
sudo systemctl enable c-relay sudo systemctl enable c-relay-pg
# Check status # Check status
sudo systemctl status c-relay sudo systemctl status c-relay-pg
# View logs (live) # View logs (live)
sudo journalctl -u c-relay -f sudo journalctl -u c-relay-pg -f
# View recent logs # View recent logs
sudo journalctl -u c-relay --since="1 hour ago" sudo journalctl -u c-relay-pg --since="1 hour ago"
``` ```
### Log Analysis ### Log Analysis
```bash ```bash
# Check for successful startup # Check for successful startup
sudo journalctl -u c-relay | grep "First-time startup sequence completed" sudo journalctl -u c-relay-pg | grep "First-time startup sequence completed"
# Find admin keys # Find admin keys
sudo journalctl -u c-relay | grep "Admin Private Key" sudo journalctl -u c-relay-pg | grep "Admin Private Key"
# Check configuration updates # Check configuration updates
sudo journalctl -u c-relay | grep "Configuration updated via kind 33334" sudo journalctl -u c-relay-pg | grep "Configuration updated via kind 33334"
# Monitor real-time activity # Monitor real-time activity
sudo journalctl -u c-relay -f | grep -E "(INFO|SUCCESS|ERROR)" sudo journalctl -u c-relay-pg -f | grep -E "(INFO|SUCCESS|ERROR)"
``` ```
## File Locations ## File Locations
After installation: After installation:
- **Binary:** `/opt/c-relay/c_relay_x86` - **Binary:** `/opt/c-relay-pg/c_relay_pg_x86`
- **Database:** `/opt/c-relay/<relay_pubkey>.nrdb` (created automatically) - **Database:** `/opt/c-relay-pg/<relay_pubkey>.nrdb` (created automatically)
- **Service File:** `/etc/systemd/system/c-relay.service` - **Service File:** `/etc/systemd/system/c-relay-pg.service`
- **User:** `c-relay` (system user created automatically) - **User:** `c-relay-pg` (system user created automatically)
## Security Features ## Security Features
The systemd service includes security hardening: The systemd service includes security hardening:
- Runs as dedicated system user `c-relay` - Runs as dedicated system user `c-relay-pg`
- `NoNewPrivileges=true` - `NoNewPrivileges=true`
- `ProtectSystem=strict` - `ProtectSystem=strict`
- `ProtectHome=true` - `ProtectHome=true`
@@ -165,7 +165,7 @@ The database file contains everything:
```bash ```bash
# Backup database file # Backup database file
sudo cp /opt/c-relay/*.nrdb /backup/location/ sudo cp /opt/c-relay-pg/*.nrdb /backup/location/
# The .nrdb file contains: # The .nrdb file contains:
# - All Nostr events # - All Nostr events
@@ -177,7 +177,7 @@ sudo cp /opt/c-relay/*.nrdb /backup/location/
To migrate to new server: To migrate to new server:
1. Copy `.nrdb` file to new server's `/opt/c-relay/` directory 1. Copy `.nrdb` file to new server's `/opt/c-relay-pg/` directory
2. Install service with `install-service.sh` 2. Install service with `install-service.sh`
3. Start service - it will automatically detect existing configuration 3. Start service - it will automatically detect existing configuration
@@ -187,39 +187,39 @@ To migrate to new server:
```bash ```bash
# Check service status # Check service status
sudo systemctl status c-relay sudo systemctl status c-relay-pg
# Check logs for errors # Check logs for errors
sudo journalctl -u c-relay --no-pager sudo journalctl -u c-relay-pg --no-pager
# Check if binary exists and is executable # Check if binary exists and is executable
ls -la /opt/c-relay/c_relay_x86 ls -la /opt/c-relay-pg/c_relay_pg_x86
# Check permissions # Check permissions
sudo -u c-relay ls -la /opt/c-relay/ sudo -u c-relay-pg ls -la /opt/c-relay-pg/
``` ```
### Database Issues ### Database Issues
```bash ```bash
# Check if database file exists # Check if database file exists
ls -la /opt/c-relay/*.nrdb* ls -la /opt/c-relay-pg/*.nrdb*
# Check database integrity # Check database integrity
sqlite3 /opt/c-relay/*.nrdb "PRAGMA integrity_check;" sqlite3 /opt/c-relay-pg/*.nrdb "PRAGMA integrity_check;"
# View database schema # View database schema
sqlite3 /opt/c-relay/*.nrdb ".schema" sqlite3 /opt/c-relay-pg/*.nrdb ".schema"
``` ```
### Configuration Issues ### Configuration Issues
```bash ```bash
# Check if configuration event exists # Check if configuration event exists
sqlite3 /opt/c-relay/*.nrdb "SELECT COUNT(*) FROM events WHERE kind = 33334;" sqlite3 /opt/c-relay-pg/*.nrdb "SELECT COUNT(*) FROM events WHERE kind = 33334;"
# View configuration event # View configuration event
sqlite3 /opt/c-relay/*.nrdb "SELECT id, created_at, LENGTH(tags) FROM events WHERE kind = 33334;" sqlite3 /opt/c-relay-pg/*.nrdb "SELECT id, created_at, LENGTH(tags) FROM events WHERE kind = 33334;"
``` ```
## Uninstallation ## Uninstallation
@@ -238,7 +238,7 @@ The uninstall script will:
For issues with the event-based configuration system: For issues with the event-based configuration system:
1. Check service logs: `sudo journalctl -u c-relay -f` 1. Check service logs: `sudo journalctl -u c-relay-pg -f`
2. Verify database integrity 2. Verify database integrity
3. Ensure admin private key is saved securely 3. Ensure admin private key is saved securely
4. Check WebSocket connectivity on port 8888 4. Check WebSocket connectivity on port 8888
+7 -7
View File
@@ -1,27 +1,27 @@
[Unit] [Unit]
Description=C Nostr Relay Server (Event-Based Configuration) Description=C Nostr Relay Server (Event-Based Configuration)
Documentation=https://github.com/your-repo/c-relay Documentation=https://github.com/your-repo/c-relay-pg
After=network.target After=network.target
Wants=network-online.target Wants=network-online.target
[Service] [Service]
Type=simple Type=simple
User=c-relay User=c-relay-pg
Group=c-relay Group=c-relay-pg
WorkingDirectory=/opt/c-relay WorkingDirectory=/opt/c-relay-pg
Environment=DEBUG_LEVEL=0 Environment=DEBUG_LEVEL=0
ExecStart=/opt/c-relay/c_relay_x86 --debug-level=$DEBUG_LEVEL ExecStart=/opt/c-relay-pg/c_relay_pg_x86 --debug-level=$DEBUG_LEVEL
Restart=always Restart=always
RestartSec=5 RestartSec=5
StandardOutput=journal StandardOutput=journal
StandardError=journal StandardError=journal
SyslogIdentifier=c-relay SyslogIdentifier=c-relay-pg
# Security settings # Security settings
NoNewPrivileges=true NoNewPrivileges=true
ProtectSystem=strict ProtectSystem=strict
ProtectHome=true ProtectHome=true
ReadWritePaths=/opt/c-relay ReadWritePaths=/opt/c-relay-pg
PrivateTmp=true PrivateTmp=true
ProtectKernelTunables=true ProtectKernelTunables=true
ProtectKernelModules=true ProtectKernelModules=true
+4 -4
View File
@@ -6,10 +6,10 @@
set -e set -e
# Configuration # Configuration
SERVICE_NAME="c-relay" SERVICE_NAME="c-relay-pg"
SERVICE_USER="c-relay" SERVICE_USER="c-relay-pg"
INSTALL_DIR="/opt/c-relay" INSTALL_DIR="/opt/c-relay-pg"
BINARY_NAME="c_relay_x86" BINARY_NAME="c_relay_pg_x86"
# Colors for output # Colors for output
RED='\033[0;31m' RED='\033[0;31m'
+13 -13
View File
@@ -1,15 +1,15 @@
#!/bin/bash #!/bin/bash
# C-Relay Systemd Service Installation Script # C-Relay-PG Systemd Service Installation Script
# This script installs the C-Relay as a systemd service # This script installs the C-Relay-PG as a systemd service
set -e set -e
# Configuration # Configuration
INSTALL_DIR="/opt/c-relay" INSTALL_DIR="/opt/c-relay-pg"
SERVICE_NAME="c-relay" SERVICE_NAME="c-relay-pg"
SERVICE_FILE="c-relay.service" SERVICE_FILE="c-relay-pg.service"
BINARY_NAME="c_relay_x86" BINARY_NAME="c_relay_pg_x86"
# Colors for output # Colors for output
RED='\033[0;31m' RED='\033[0;31m'
@@ -17,7 +17,7 @@ GREEN='\033[0;32m'
YELLOW='\033[1;33m' YELLOW='\033[1;33m'
NC='\033[0m' # No Color NC='\033[0m' # No Color
echo -e "${GREEN}=== C-Relay Systemd Service Installation ===${NC}" echo -e "${GREEN}=== C-Relay-PG Systemd Service Installation ===${NC}"
# Check if running as root # Check if running as root
if [[ $EUID -ne 0 ]]; then if [[ $EUID -ne 0 ]]; then
@@ -39,12 +39,12 @@ if [ ! -f "$SERVICE_FILE" ]; then
exit 1 exit 1
fi fi
# Create c-relay user if it doesn't exist # Create c-relay-pg user if it doesn't exist
if ! id "c-relay" &>/dev/null; then if ! id "c-relay-pg" &>/dev/null; then
echo -e "${YELLOW}Creating c-relay user...${NC}" echo -e "${YELLOW}Creating c-relay-pg user...${NC}"
useradd --system --shell /bin/false --home-dir $INSTALL_DIR --create-home c-relay useradd --system --shell /bin/false --home-dir $INSTALL_DIR --create-home c-relay-pg
else else
echo -e "${GREEN}User c-relay already exists${NC}" echo -e "${GREEN}User c-relay-pg already exists${NC}"
fi fi
# Create installation directory # Create installation directory
@@ -59,7 +59,7 @@ chmod +x $INSTALL_DIR/$BINARY_NAME
# Set permissions # Set permissions
echo -e "${YELLOW}Setting permissions...${NC}" echo -e "${YELLOW}Setting permissions...${NC}"
chown -R c-relay:c-relay $INSTALL_DIR chown -R c-relay-pg:c-relay-pg $INSTALL_DIR
# Install systemd service # Install systemd service
echo -e "${YELLOW}Installing systemd service...${NC}" echo -e "${YELLOW}Installing systemd service...${NC}"
+3 -3
View File
@@ -6,9 +6,9 @@
set -e set -e
# Configuration # Configuration
SERVICE_NAME="c-relay" SERVICE_NAME="c-relay-pg"
SERVICE_USER="c-relay" SERVICE_USER="c-relay-pg"
INSTALL_DIR="/opt/c-relay" INSTALL_DIR="/opt/c-relay-pg"
# Colors for output # Colors for output
RED='\033[0;31m' RED='\033[0;31m'
+15 -15
View File
@@ -1,14 +1,14 @@
#!/bin/bash #!/bin/bash
# C-Relay Systemd Service Uninstallation Script # C-Relay-PG Systemd Service Uninstallation Script
# This script removes the C-Relay systemd service # This script removes the C-Relay-PG systemd service
set -e set -e
# Configuration # Configuration
INSTALL_DIR="/opt/c-relay" INSTALL_DIR="/opt/c-relay-pg"
SERVICE_NAME="c-relay" SERVICE_NAME="c-relay-pg"
SERVICE_FILE="c-relay.service" SERVICE_FILE="c-relay-pg.service"
# Colors for output # Colors for output
RED='\033[0;31m' RED='\033[0;31m'
@@ -16,7 +16,7 @@ GREEN='\033[0;32m'
YELLOW='\033[1;33m' YELLOW='\033[1;33m'
NC='\033[0m' # No Color NC='\033[0m' # No Color
echo -e "${GREEN}=== C-Relay Systemd Service Uninstallation ===${NC}" echo -e "${GREEN}=== C-Relay-PG Systemd Service Uninstallation ===${NC}"
# Check if running as root # Check if running as root
if [[ $EUID -ne 0 ]]; then if [[ $EUID -ne 0 ]]; then
@@ -65,22 +65,22 @@ else
echo -e "${GREEN}Installation directory preserved${NC}" echo -e "${GREEN}Installation directory preserved${NC}"
fi fi
# Ask about removing c-relay user # Ask about removing c-relay-pg user
echo echo
echo -e "${YELLOW}Do you want to remove the c-relay user? (y/N)${NC}" echo -e "${YELLOW}Do you want to remove the c-relay-pg user? (y/N)${NC}"
read -r response read -r response
if [[ "$response" =~ ^([yY][eE][sS]|[yY])$ ]]; then if [[ "$response" =~ ^([yY][eE][sS]|[yY])$ ]]; then
echo -e "${YELLOW}Removing c-relay user...${NC}" echo -e "${YELLOW}Removing c-relay-pg user...${NC}"
if id "c-relay" &>/dev/null; then if id "c-relay-pg" &>/dev/null; then
userdel c-relay userdel c-relay-pg
echo -e "${GREEN}User c-relay removed${NC}" echo -e "${GREEN}User c-relay-pg removed${NC}"
else else
echo -e "${GREEN}User c-relay was not found${NC}" echo -e "${GREEN}User c-relay-pg was not found${NC}"
fi fi
else else
echo -e "${GREEN}User c-relay preserved${NC}" echo -e "${GREEN}User c-relay-pg preserved${NC}"
fi fi
echo echo
echo -e "${GREEN}=== Uninstallation Complete ===${NC}" echo -e "${GREEN}=== Uninstallation Complete ===${NC}"
echo -e "${GREEN}C-Relay systemd service has been removed${NC}" echo -e "${GREEN}C-Relay-PG systemd service has been removed${NC}"
+1 -1
View File
@@ -421,7 +421,7 @@ echo
if run_nip11_tests; then if run_nip11_tests; then
echo echo
print_success "All NIP-11 tests completed successfully!" print_success "All NIP-11 tests completed successfully!"
print_info "The C-Relay NIP-11 implementation is fully compliant" print_info "The C-Relay-PG NIP-11 implementation is fully compliant"
print_info "✅ HTTP endpoint, Accept header validation, CORS, and JSON structure all working" print_info "✅ HTTP endpoint, Accept header validation, CORS, and JSON structure all working"
echo echo
exit 0 exit 0
+6 -6
View File
@@ -1,6 +1,6 @@
#!/bin/bash #!/bin/bash
# Comprehensive C-Relay Test - Test event types and subscriptions # Comprehensive C-Relay-PG Test - Test event types and subscriptions
# Uses nak to generate and publish various event types, then tests subscriptions # Uses nak to generate and publish various event types, then tests subscriptions
set -e # Exit on any error set -e # Exit on any error
@@ -284,7 +284,7 @@ test_subscription() {
# Main test function # Main test function
run_comprehensive_test() { run_comprehensive_test() {
print_header "C-Relay Comprehensive Test" print_header "C-Relay-PG Comprehensive Test"
# Check dependencies # Check dependencies
print_step "Checking dependencies..." print_step "Checking dependencies..."
@@ -317,7 +317,7 @@ run_comprehensive_test() {
# Test 2: Replaceable Events (kind 0 - metadata) # Test 2: Replaceable Events (kind 0 - metadata)
print_step "Creating replaceable events (kind 0)..." print_step "Creating replaceable events (kind 0)..."
local replaceable1=$(nak event --sec "$TEST_PRIVATE_KEY" -c '{"name":"Test User","about":"Testing C-Relay"}' -k 0 --ts $(($(date +%s) - 80)) -t "type=replaceable" 2>/dev/null) local replaceable1=$(nak event --sec "$TEST_PRIVATE_KEY" -c '{"name":"Test User","about":"Testing C-Relay-PG"}' -k 0 --ts $(($(date +%s) - 80)) -t "type=replaceable" 2>/dev/null)
local replaceable2=$(nak event --sec "$TEST_PRIVATE_KEY" -c '{"name":"Test User Updated","about":"Updated profile"}' -k 0 --ts $(($(date +%s) - 70)) -t "type=replaceable" 2>/dev/null) local replaceable2=$(nak event --sec "$TEST_PRIVATE_KEY" -c '{"name":"Test User Updated","about":"Updated profile"}' -k 0 --ts $(($(date +%s) - 70)) -t "type=replaceable" 2>/dev/null)
publish_event "$replaceable1" "replaceable" "Replaceable event #1 (metadata)" publish_event "$replaceable1" "replaceable" "Replaceable event #1 (metadata)"
@@ -473,20 +473,20 @@ run_comprehensive_test() {
} }
# Run the comprehensive test # Run the comprehensive test
print_header "Starting C-Relay Comprehensive Test Suite with NIP-01 Validation" print_header "Starting C-Relay-PG Comprehensive Test Suite with NIP-01 Validation"
echo echo
if run_comprehensive_test; then if run_comprehensive_test; then
echo echo
print_success "All tests completed successfully!" print_success "All tests completed successfully!"
print_info "The C-Relay with full NIP-01 validation is working correctly" print_info "The C-Relay-PG with full NIP-01 validation is working correctly"
print_info "✅ Event validation, signature verification, and error handling all working" print_info "✅ Event validation, signature verification, and error handling all working"
echo echo
exit 0 exit 0
else else
echo echo
print_error "❌ TESTS FAILED: Protocol violations detected!" print_error "❌ TESTS FAILED: Protocol violations detected!"
print_error "The C-Relay has critical issues that need to be fixed:" print_error "The C-Relay-PG has critical issues that need to be fixed:"
print_error " - Server-side filtering is not implemented properly" print_error " - Server-side filtering is not implemented properly"
print_error " - Events are sent to clients regardless of subscription filters" print_error " - Events are sent to clients regardless of subscription filters"
print_error " - This violates the Nostr protocol specification" print_error " - This violates the Nostr protocol specification"
+1 -1
View File
@@ -461,7 +461,7 @@ echo
if run_count_test; then if run_count_test; then
echo echo
print_success "All NIP-45 COUNT tests completed successfully!" print_success "All NIP-45 COUNT tests completed successfully!"
print_info "The C-Relay COUNT functionality is working correctly" print_info "The C-Relay-PG COUNT functionality is working correctly"
print_info "✅ COUNT messages are processed and return correct event counts" print_info "✅ COUNT messages are processed and return correct event counts"
echo echo
exit 0 exit 0
+1 -1
View File
@@ -405,7 +405,7 @@ echo
if run_search_test; then if run_search_test; then
echo echo
print_success "All NIP-50 SEARCH tests completed successfully!" print_success "All NIP-50 SEARCH tests completed successfully!"
print_info "The C-Relay SEARCH functionality is working correctly" print_info "The C-Relay-PG SEARCH functionality is working correctly"
print_info "✅ Search field in filter objects works for both REQ and COUNT messages" print_info "✅ Search field in filter objects works for both REQ and COUNT messages"
print_info "✅ Search works across event content and tag values" print_info "✅ Search works across event content and tag values"
print_info "✅ Search is case-insensitive and supports partial matches" print_info "✅ Search is case-insensitive and supports partial matches"
+1 -1
View File
@@ -220,7 +220,7 @@ echo
if run_protected_events_test; then if run_protected_events_test; then
echo echo
print_success "All NIP-70 PROTECTED EVENTS tests completed successfully!" print_success "All NIP-70 PROTECTED EVENTS tests completed successfully!"
print_info "The C-Relay PROTECTED EVENTS functionality is working correctly" print_info "The C-Relay-PG PROTECTED EVENTS functionality is working correctly"
print_info "✅ Protected events are rejected when feature is disabled" print_info "✅ Protected events are rejected when feature is disabled"
print_info "✅ Protected events are rejected when enabled but not authenticated" print_info "✅ Protected events are rejected when enabled but not authenticated"
print_info "✅ Normal events work regardless of protected events setting" print_info "✅ Normal events work regardless of protected events setting"
+2 -2
View File
@@ -1,6 +1,6 @@
#!/bin/bash #!/bin/bash
# NIP-09 Event Deletion Request Test for C-Relay # NIP-09 Event Deletion Request Test for C-Relay-PG
# Tests deletion request functionality - assumes relay is already running # Tests deletion request functionality - assumes relay is already running
# Based on the pattern from 1_nip_test.sh # Based on the pattern from 1_nip_test.sh
@@ -372,7 +372,7 @@ echo
if run_deletion_test; then if run_deletion_test; then
echo echo
print_success "All NIP-09 deletion tests completed successfully!" print_success "All NIP-09 deletion tests completed successfully!"
print_info "The C-Relay NIP-09 implementation is working correctly" print_info "The C-Relay-PG NIP-09 implementation is working correctly"
print_info "✅ Event deletion by ID working" print_info "✅ Event deletion by ID working"
print_info "✅ Address-based deletion working" print_info "✅ Address-based deletion working"
print_info "✅ Authorization validation working" print_info "✅ Authorization validation working"
+6 -6
View File
@@ -1,6 +1,6 @@
# C-Relay Comprehensive Testing Framework # C-Relay-PG Comprehensive Testing Framework
This directory contains a comprehensive testing framework for the C-Relay Nostr relay implementation. The framework provides automated testing for security vulnerabilities, performance validation, and stability assurance. This directory contains a comprehensive testing framework for the C-Relay-PG Nostr relay implementation. The framework provides automated testing for security vulnerabilities, performance validation, and stability assurance.
## Overview ## Overview
@@ -194,14 +194,14 @@ brew install websocat curl jq
Download `websocat` from: https://github.com/vi/websocat/releases Download `websocat` from: https://github.com/vi/websocat/releases
### Relay Setup ### Relay Setup
Before running tests, ensure the C-Relay is running: Before running tests, ensure the C-Relay-PG is running:
```bash ```bash
# Build and start the relay # Build and start the relay
./make_and_restart_relay.sh ./make_and_restart_relay.sh
# Verify it's running # Verify it's running
ps aux | grep c_relay ps aux | grep c_relay_pg
curl -H "Accept: application/nostr+json" http://localhost:8888 curl -H "Accept: application/nostr+json" http://localhost:8888
``` ```
@@ -308,7 +308,7 @@ Modify test parameters within individual test scripts:
#### "Could not connect to relay" #### "Could not connect to relay"
- Ensure relay is running: `./make_and_restart_relay.sh` - Ensure relay is running: `./make_and_restart_relay.sh`
- Check port availability: `netstat -tln | grep 8888` - Check port availability: `netstat -tln | grep 8888`
- Verify relay process: `ps aux | grep c_relay` - Verify relay process: `ps aux | grep c_relay_pg`
#### "websocat: command not found" #### "websocat: command not found"
- Install websocat: `sudo apt-get install websocat` - Install websocat: `sudo apt-get install websocat`
@@ -377,7 +377,7 @@ Integrate with CI/CD pipelines:
```yaml ```yaml
# Example GitHub Actions workflow # Example GitHub Actions workflow
- name: Run C-Relay Tests - name: Run C-Relay-PG Tests
run: | run: |
./make_and_restart_relay.sh ./make_and_restart_relay.sh
./tests/run_all_tests.sh ./tests/run_all_tests.sh
+1 -1
View File
@@ -1,7 +1,7 @@
#!/bin/bash #!/bin/bash
# Authentication Testing Suite for C-Relay # Authentication Testing Suite for C-Relay-PG
# Tests NIP-42 authentication mechanisms # Tests NIP-42 authentication mechanisms
set -e set -e
+1 -1
View File
@@ -262,7 +262,7 @@ if [ -n "$DB_FILE" ]; then
fi fi
echo "Check relay logs for [QUERY] entries to see actual query times:" echo "Check relay logs for [QUERY] entries to see actual query times:"
echo " journalctl -u c-relay -n 100 | grep QUERY" echo " journalctl -u c-relay-pg -n 100 | grep QUERY"
echo "" echo ""
echo "==========================================" echo "=========================================="
+2 -2
View File
@@ -1,6 +1,6 @@
#!/bin/bash #!/bin/bash
# Configuration Testing Suite for C-Relay # Configuration Testing Suite for C-Relay-PG
# Tests configuration management and persistence # Tests configuration management and persistence
set -e set -e
@@ -138,7 +138,7 @@ test_nip11_info() {
} }
echo "==========================================" echo "=========================================="
echo "C-Relay Configuration Testing Suite" echo "C-Relay-PG Configuration Testing Suite"
echo "==========================================" echo "=========================================="
echo "Testing configuration management at ws://$RELAY_HOST:$RELAY_PORT" echo "Testing configuration management at ws://$RELAY_HOST:$RELAY_PORT"
echo "" echo ""
+2 -2
View File
@@ -1,6 +1,6 @@
#!/bin/bash #!/bin/bash
# Filter Validation Test Script for C-Relay # Filter Validation Test Script for C-Relay-PG
# Tests comprehensive input validation for REQ and COUNT messages # Tests comprehensive input validation for REQ and COUNT messages
set -e set -e
@@ -91,7 +91,7 @@ test_valid_message() {
fi fi
} }
echo "=== C-Relay Filter Validation Tests ===" echo "=== C-Relay-PG Filter Validation Tests ==="
echo "Testing against relay at ws://$RELAY_HOST:$RELAY_PORT" echo "Testing against relay at ws://$RELAY_HOST:$RELAY_PORT"
echo echo
+2 -2
View File
@@ -1,6 +1,6 @@
#!/bin/bash #!/bin/bash
# Input Validation Test Suite for C-Relay # Input Validation Test Suite for C-Relay-PG
# Comprehensive testing of input boundary conditions and malformed data # Comprehensive testing of input boundary conditions and malformed data
set -e set -e
@@ -69,7 +69,7 @@ test_input_validation() {
} }
echo "==========================================" echo "=========================================="
echo "C-Relay Input Validation Test Suite" echo "C-Relay-PG Input Validation Test Suite"
echo "==========================================" echo "=========================================="
echo "Testing against relay at ws://$RELAY_HOST:$RELAY_PORT" echo "Testing against relay at ws://$RELAY_HOST:$RELAY_PORT"
echo echo
+2 -2
View File
@@ -1,6 +1,6 @@
#!/bin/bash #!/bin/bash
# Load Testing Suite for C-Relay # Load Testing Suite for C-Relay-PG
# Tests high concurrent connection scenarios and performance under load # Tests high concurrent connection scenarios and performance under load
set -e set -e
@@ -203,7 +203,7 @@ run_load_test() {
# Only run main code if script is executed directly (not sourced) # Only run main code if script is executed directly (not sourced)
if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then
echo "==========================================" echo "=========================================="
echo "C-Relay Load Testing Suite" echo "C-Relay-PG Load Testing Suite"
echo "==========================================" echo "=========================================="
echo "Testing against relay at ws://$RELAY_HOST:$RELAY_PORT" echo "Testing against relay at ws://$RELAY_HOST:$RELAY_PORT"
echo "" echo ""
+2 -2
View File
@@ -1,6 +1,6 @@
#!/bin/bash #!/bin/bash
# Memory Corruption Detection Test Suite for C-Relay # Memory Corruption Detection Test Suite for C-Relay-PG
# Tests for buffer overflows, use-after-free, and memory safety issues # Tests for buffer overflows, use-after-free, and memory safety issues
set -e set -e
@@ -135,7 +135,7 @@ test_concurrent_access() {
} }
echo "==========================================" echo "=========================================="
echo "C-Relay Memory Corruption Test Suite" echo "C-Relay-PG Memory Corruption Test Suite"
echo "==========================================" echo "=========================================="
echo "Testing against relay at ws://$RELAY_HOST:$RELAY_PORT" echo "Testing against relay at ws://$RELAY_HOST:$RELAY_PORT"
echo "Note: These tests may cause the relay to crash if vulnerabilities exist" echo "Note: These tests may cause the relay to crash if vulnerabilities exist"
+5 -5
View File
@@ -1,6 +1,6 @@
#!/bin/bash #!/bin/bash
# Performance Benchmarking Suite for C-Relay # Performance Benchmarking Suite for C-Relay-PG
# Measures performance metrics and throughput # Measures performance metrics and throughput
set -e set -e
@@ -202,7 +202,7 @@ benchmark_memory_usage() {
echo "==========================================" echo "=========================================="
local initial_memory local initial_memory
initial_memory=$(ps aux | grep c_relay | grep -v grep | awk '{print $6}' | head -1) initial_memory=$(ps aux | grep c_relay_pg | grep -v grep | awk '{print $6}' | head -1)
echo "Initial memory usage: ${initial_memory}KB" echo "Initial memory usage: ${initial_memory}KB"
@@ -218,7 +218,7 @@ benchmark_memory_usage() {
sleep 2 sleep 2
local current_memory local current_memory
current_memory=$(ps aux | grep c_relay | grep -v grep | awk '{print $6}' | head -1) current_memory=$(ps aux | grep c_relay_pg | grep -v grep | awk '{print $6}' | head -1)
local memory_increase=$((current_memory - initial_memory)) local memory_increase=$((current_memory - initial_memory))
echo "${current_memory}KB (+${memory_increase}KB)" echo "${current_memory}KB (+${memory_increase}KB)"
@@ -232,14 +232,14 @@ benchmark_memory_usage() {
done done
local final_memory local final_memory
final_memory=$(ps aux | grep c_relay | grep -v grep | awk '{print $6}' | head -1) final_memory=$(ps aux | grep c_relay_pg | grep -v grep | awk '{print $6}' | head -1)
echo "Final memory usage: ${final_memory}KB" echo "Final memory usage: ${final_memory}KB"
} }
# Only run main code if script is executed directly (not sourced) # Only run main code if script is executed directly (not sourced)
if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then
echo "==========================================" echo "=========================================="
echo "C-Relay Performance Benchmarking Suite" echo "C-Relay-PG Performance Benchmarking Suite"
echo "==========================================" echo "=========================================="
echo "Benchmarking relay at ws://$RELAY_HOST:$RELAY_PORT" echo "Benchmarking relay at ws://$RELAY_HOST:$RELAY_PORT"
echo "" echo ""
+4 -4
View File
@@ -1,6 +1,6 @@
#!/bin/bash #!/bin/bash
# Resource Monitoring Suite for C-Relay # Resource Monitoring Suite for C-Relay-PG
# Monitors memory and CPU usage during testing # Monitors memory and CPU usage during testing
set -e set -e
@@ -27,7 +27,7 @@ TIMESTAMP_SAMPLES=()
# Function to get relay process info # Function to get relay process info
get_relay_info() { get_relay_info() {
local pid local pid
pid=$(pgrep -f "c_relay" | head -1) pid=$(pgrep -f "c_relay_pg" | head -1)
if [[ -z "$pid" ]]; then if [[ -z "$pid" ]]; then
echo "0:0:0:0" echo "0:0:0:0"
@@ -232,13 +232,13 @@ run_monitored_load_test() {
} }
echo "==========================================" echo "=========================================="
echo "C-Relay Resource Monitoring Suite" echo "C-Relay-PG Resource Monitoring Suite"
echo "==========================================" echo "=========================================="
echo "Monitoring relay at ws://$RELAY_HOST:$RELAY_PORT" echo "Monitoring relay at ws://$RELAY_HOST:$RELAY_PORT"
echo "" echo ""
# Check if relay is running # Check if relay is running
if ! pgrep -f "c_relay" >/dev/null 2>&1; then if ! pgrep -f "c_relay_pg" >/dev/null 2>&1; then
echo -e "${RED}Relay process not found. Please start the relay first.${NC}" echo -e "${RED}Relay process not found. Please start the relay first.${NC}"
echo "Use: ./make_and_restart_relay.sh" echo "Use: ./make_and_restart_relay.sh"
exit 1 exit 1
+4 -4
View File
@@ -1,6 +1,6 @@
#!/bin/bash #!/bin/bash
# C-Relay Comprehensive Test Suite Runner # C-Relay-PG Comprehensive Test Suite Runner
# This script runs all security and stability tests for the Nostr relay # This script runs all security and stability tests for the Nostr relay
set -e set -e
@@ -132,7 +132,7 @@ generate_html_report() {
<head> <head>
<meta charset="UTF-8"> <meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>C-Relay Test Report - $(date)</title> <title>C-Relay-PG Test Report - $(date)</title>
<style> <style>
body { font-family: Arial, sans-serif; margin: 40px; background-color: #f5f5f5; } body { font-family: Arial, sans-serif; margin: 40px; background-color: #f5f5f5; }
.header { background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); color: white; padding: 20px; border-radius: 8px; margin-bottom: 30px; } .header { background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); color: white; padding: 20px; border-radius: 8px; margin-bottom: 30px; }
@@ -152,7 +152,7 @@ generate_html_report() {
</head> </head>
<body> <body>
<div class="header"> <div class="header">
<h1>C-Relay Comprehensive Test Report</h1> <h1>C-Relay-PG Comprehensive Test Report</h1>
<p>Generated on: $(date)</p> <p>Generated on: $(date)</p>
<p>Test Environment: $RELAY_URL</p> <p>Test Environment: $RELAY_URL</p>
</div> </div>
@@ -211,7 +211,7 @@ EOF
# Main execution # Main execution
log "==========================================" log "=========================================="
log "C-Relay Comprehensive Test Suite Runner" log "C-Relay-PG Comprehensive Test Suite Runner"
log "==========================================" log "=========================================="
log "Relay URL: $RELAY_URL" log "Relay URL: $RELAY_URL"
log "Log file: $LOG_FILE" log "Log file: $LOG_FILE"
+2 -2
View File
@@ -1,6 +1,6 @@
#!/bin/bash #!/bin/bash
# NIP Protocol Test Runner for C-Relay # NIP Protocol Test Runner for C-Relay-PG
# Runs all NIP compliance tests # Runs all NIP compliance tests
set -e set -e
@@ -84,7 +84,7 @@ check_relay() {
} }
echo "==========================================" echo "=========================================="
echo "C-Relay NIP Protocol Test Suite" echo "C-Relay-PG NIP Protocol Test Suite"
echo "==========================================" echo "=========================================="
echo "Testing NIP compliance against relay at ws://$RELAY_HOST:$RELAY_PORT" echo "Testing NIP compliance against relay at ws://$RELAY_HOST:$RELAY_PORT"
echo "" echo ""
+2 -2
View File
@@ -1,6 +1,6 @@
#!/bin/bash #!/bin/bash
# SQL Injection Test Suite for C-Relay # SQL Injection Test Suite for C-Relay-PG
# Comprehensive testing of SQL injection vulnerabilities across all filter types # Comprehensive testing of SQL injection vulnerabilities across all filter types
set -e set -e
@@ -93,7 +93,7 @@ test_valid_query() {
} }
echo "==========================================" echo "=========================================="
echo "C-Relay SQL Injection Test Suite" echo "C-Relay-PG SQL Injection Test Suite"
echo "==========================================" echo "=========================================="
echo "Testing against relay at ws://$RELAY_HOST:$RELAY_PORT" echo "Testing against relay at ws://$RELAY_HOST:$RELAY_PORT"
echo echo
+1 -1
View File
@@ -380,7 +380,7 @@ test_empty_result() {
} }
echo "==========================================" echo "=========================================="
echo "C-Relay SQL Query Admin API Testing Suite" echo "C-Relay-PG SQL Query Admin API Testing Suite"
echo "==========================================" echo "=========================================="
echo "Testing SQL query functionality at $RELAY_URL" echo "Testing SQL query functionality at $RELAY_URL"
echo "" echo ""
+1 -1
View File
@@ -2,7 +2,7 @@
# Persistent Subscription Test Script # Persistent Subscription Test Script
# Subscribes to all events in the relay and prints them as they arrive in real-time # Subscribes to all events in the relay and prints them as they arrive in real-time
# This tests the persistent subscription functionality of the C-Relay # This tests the persistent subscription functionality of the C-Relay-PG
set -e # Exit on any error set -e # Exit on any error
+1 -1
View File
@@ -1,6 +1,6 @@
#!/bin/bash #!/bin/bash
# Subscription Cleanup Testing Suite for C-Relay # Subscription Cleanup Testing Suite for C-Relay-PG
# Tests startup cleanup and connection age limit features # Tests startup cleanup and connection age limit features
set -e set -e
+5 -5
View File
@@ -1,6 +1,6 @@
#!/bin/bash #!/bin/bash
# Thread-level CPU profiler for c-relay on remote server # Thread-level CPU profiler for c-relay-pg on remote server
# - Samples per-thread CPU every N seconds using /proc/<pid>/task/*/stat deltas # - Samples per-thread CPU every N seconds using /proc/<pid>/task/*/stat deltas
# - Optionally runs perf record in parallel for callgraph data # - Optionally runs perf record in parallel for callgraph data
# - Pulls artifacts locally and generates a summary report # - Pulls artifacts locally and generates a summary report
@@ -15,13 +15,13 @@ RUN_TS="$(date -u +%Y%m%d_%H%M%S)"
RUN_DIR="${OUTDIR_BASE}/${RUN_TS}" RUN_DIR="${OUTDIR_BASE}/${RUN_TS}"
LOCAL_CSV="${RUN_DIR}/thread_samples.csv" LOCAL_CSV="${RUN_DIR}/thread_samples.csv"
LOCAL_REPORT="${RUN_DIR}/thread_summary.txt" LOCAL_REPORT="${RUN_DIR}/thread_summary.txt"
REMOTE_DIR="/tmp/c_relay_thread_profile_${RUN_TS}" REMOTE_DIR="/tmp/c_relay_pg_thread_profile_${RUN_TS}"
ENABLE_PERF="${ENABLE_PERF:-1}" # 1=run perf, 0=skip ENABLE_PERF="${ENABLE_PERF:-1}" # 1=run perf, 0=skip
mkdir -p "${RUN_DIR}" mkdir -p "${RUN_DIR}"
echo "==========================================" echo "=========================================="
echo "C-Relay Thread CPU Profiler" echo "C-Relay-PG Thread CPU Profiler"
echo "==========================================" echo "=========================================="
echo "Remote host : ${REMOTE_HOST}" echo "Remote host : ${REMOTE_HOST}"
echo "Duration : ${DURATION}s" echo "Duration : ${DURATION}s"
@@ -43,9 +43,9 @@ CSV_FILE="\${REMOTE_DIR}/thread_samples.csv"
PERF_FILE="\${REMOTE_DIR}/perf.data" PERF_FILE="\${REMOTE_DIR}/perf.data"
LOG_FILE="\${REMOTE_DIR}/run.log" LOG_FILE="\${REMOTE_DIR}/run.log"
PID=\$(pgrep -f '/usr/local/bin/c_relay/c_relay|c_relay' | head -1 || true) PID=\$(pgrep -f '/usr/local/bin/c_relay_pg/c_relay_pg|c_relay_pg' | head -1 || true)
if [ -z "\${PID}" ]; then if [ -z "\${PID}" ]; then
echo "ERROR: c_relay process not found (checked by cmdline pattern)" | tee -a "\${LOG_FILE}" echo "ERROR: c_relay_pg process not found (checked by cmdline pattern)" | tee -a "\${LOG_FILE}"
exit 1 exit 1
fi fi
+2 -2
View File
@@ -1,6 +1,6 @@
#!/bin/bash #!/bin/bash
# C-Relay Whitelist/Blacklist Test Script # C-Relay-PG Whitelist/Blacklist Test Script
# Tests the relay's authentication functionality using nak # Tests the relay's authentication functionality using nak
set -e # Exit on any error set -e # Exit on any error
@@ -362,7 +362,7 @@ test_whitelist_functionality() {
# Main test function # Main test function
main() { main() {
log_info "Starting C-Relay Whitelist/Blacklist Test" log_info "Starting C-Relay-PG Whitelist/Blacklist Test"
log_info "==========================================" log_info "=========================================="
# Check prerequisites # Check prerequisites