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
**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
### 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
### 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
ENV variables → cryptographically signed tags
File watching → database polling/restart
@@ -119,18 +119,18 @@ File watching → database polling/restart
```
Developer Machine:
├── ./make_and_restart_relay.sh
├── build/c_relay_x86
├── build/c_relay_pg_x86
├── build/<relay_pubkey>.db
└── relay.log
```
### Production SystemD Deployment
```
/opt/c-relay/:
├── c_relay_x86
/opt/c-relay-pg/:
├── c_relay_pg_x86
├── <relay_pubkey>.db
├── systemd service (c-relay.service)
└── c-relay user isolation
├── systemd service (c-relay-pg.service)
└── c-relay-pg user isolation
```
### Container Deployment Architecture
@@ -144,7 +144,7 @@ Container:
### Reverse Proxy Architecture
```
Internet → Nginx/HAProxy → C-Relay
Internet → Nginx/HAProxy → C-Relay-PG
├── WebSocket upgrade handling
├── SSL termination
└── Rate limiting
@@ -292,7 +292,7 @@ Admin Signs Event → WebSocket Submit → Validate → Store → Restart Requir
**Decision**: Same port serves both protocols
**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.]
+8 -8
View File
@@ -1,6 +1,6 @@
# 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
@@ -15,9 +15,9 @@
- Starts relay in background with proper logging
### Architecture-Specific Binary Outputs
- **x86_64**: `./build/c_relay_x86`
- **ARM64**: `./build/c_relay_arm64`
- **Other**: `./build/c_relay_$(ARCH)`
- **x86_64**: `./build/c_relay_pg_x86`
- **ARM64**: `./build/c_relay_pg_arm64`
- **Other**: `./build/c_relay_pg_$(ARCH)`
### Database File Naming Convention
- **Format**: `<relay_pubkey>.db` (NOT `.nrdb` as shown in docs)
@@ -75,10 +75,10 @@
### Process Management
```bash
# Kill existing relay processes
pkill -f "c_relay_"
pkill -f "c_relay_pg_"
# Check running processes
ps aux | grep c_relay_
ps aux | grep c_relay_pg_
# Force kill port binding
fuser -k 8888/tcp
@@ -95,7 +95,7 @@ fuser -k 8888/tcp
- Event configuration tests: `tests/event_config_tests.sh`
### 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
- No environment variables needed (event-based config)
- Resource limits: 65536 file descriptors, 4096 processes
@@ -137,7 +137,7 @@ fuser -k 8888/tcp
## Quick Debugging Commands
```bash
# Check relay status
ps aux | grep c_relay_ && netstat -tln | grep 8888
ps aux | grep c_relay_pg_ && netstat -tln | grep 8888
# View logs
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
@@ -21,7 +21,7 @@ Complete API reference for the C-Relay event-based administration system and adv
## 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
- **Audit trail**: Complete history of all administrative actions
@@ -63,8 +63,8 @@ Store the admin private key securely:
export C_RELAY_ADMIN_KEY="nsec1abc123..."
# Secure file
echo "nsec1abc123..." > ~/.c-relay-admin
chmod 600 ~/.c-relay-admin
echo "nsec1abc123..." > ~/.c-relay-pg-admin
chmod 600 ~/.c-relay-pg-admin
# Password manager (recommended)
# Store in 1Password, Bitwarden, etc.
@@ -167,7 +167,7 @@ Examples:
"data": [
{
"key": "relay_name",
"value": "C-Relay",
"value": "C-Relay-PG",
"data_type": "string",
"category": "relay",
"description": "Relay name displayed in NIP-11"
@@ -506,10 +506,10 @@ ORDER BY count DESC
| 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_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 |
| `supported_nips` | string | "1,9,11,13,15,20,33,40,42,45,50,70" | Supported NIPs |
| `language_tags` | string | "*" | Supported languages |
@@ -576,7 +576,7 @@ ORDER BY count DESC
## 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
+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
ARG DEBUG_BUILD=false
@@ -95,11 +95,11 @@ RUN cd nostr_core_lib && \
rm -f *.o *.a 2>/dev/null || true && \
./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 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
# Use conditional compilation flags based on DEBUG_BUILD argument
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)"; \
else \
CFLAGS="-O2"; \
STRIP_CMD="strip /build/c_relay_static"; \
STRIP_CMD="strip /build/c_relay_pg_static"; \
echo "Building optimized production binary (symbols stripped)"; \
fi && \
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/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 \
-o /build/c_relay_static \
-o /build/c_relay_pg_static \
c_utils_lib/libc_utils.a \
nostr_core_lib/libnostr_core_x64.a \
-lwebsockets -lssl -lcrypto -lsqlite3 -lsecp256k1 \
@@ -128,12 +128,12 @@ RUN if [ "$DEBUG_BUILD" = "true" ]; then \
# Verify it's truly static
RUN echo "=== Binary Information ===" && \
file /build/c_relay_static && \
ls -lh /build/c_relay_static && \
file /build/c_relay_pg_static && \
ls -lh /build/c_relay_pg_static && \
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 ==="
# Output stage - just the binary
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
CFLAGS = -Wall -Wextra -std=c99 -g -O2
@@ -16,13 +16,13 @@ C_UTILS_LIB = c_utils_lib/libc_utils.a
# Architecture detection
ARCH = $(shell uname -m)
ifeq ($(ARCH),x86_64)
TARGET = $(BUILD_DIR)/c_relay_x86
TARGET = $(BUILD_DIR)/c_relay_pg_x86
else ifeq ($(ARCH),aarch64)
TARGET = $(BUILD_DIR)/c_relay_arm64
TARGET = $(BUILD_DIR)/c_relay_pg_arm64
else ifeq ($(ARCH),arm64)
TARGET = $(BUILD_DIR)/c_relay_arm64
TARGET = $(BUILD_DIR)/c_relay_pg_arm64
else
TARGET = $(BUILD_DIR)/c_relay_$(ARCH)
TARGET = $(BUILD_DIR)/c_relay_pg_$(ARCH)
endif
# Default target
@@ -82,18 +82,18 @@ force-version:
# Build the relay
$(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)
@echo "Build complete: $(TARGET)"
# Build for specific architectures
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..."
$(CC) $(CFLAGS) $(INCLUDES) $(MAIN_SRC) -o $(BUILD_DIR)/c_relay_x86 $(NOSTR_CORE_LIB) $(C_UTILS_LIB) $(LIBS)
@echo "Build complete: $(BUILD_DIR)/c_relay_x86"
@echo "Building C-Relay-PG for x86_64..."
$(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_pg_x86"
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 \
echo "ERROR: ARM64 cross-compiler not found."; \
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
@echo "Using aarch64-linux-gnu-gcc with ARM64 libraries..."
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)
@echo "Build complete: $(BUILD_DIR)/c_relay_arm64"
@echo "Build complete: $(BUILD_DIR)/c_relay_pg_arm64"
# Install ARM64 cross-compilation dependencies
install-arm64-deps:
@@ -160,7 +160,7 @@ test: $(TARGET)
init-db:
@echo "Database initialization is now handled automatically when the server starts."
@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:
@@ -180,7 +180,7 @@ install-deps:
# Help
help:
@echo "C-Relay Build System"
@echo "C-Relay-PG Build System"
@echo ""
@echo "Targets:"
@echo " all Build the relay for current architecture (default)"
@@ -209,15 +209,15 @@ help:
# Build fully static MUSL binaries using Docker
static-musl-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 run --rm -v $(PWD)/build:/output c-relay-static-builder-x86_64 sh -c "cp /c_relay_static_musl_x86_64 /output/"
@echo "Static binary created: build/c_relay_static_musl_x86_64"
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-pg-static-builder-x86_64 sh -c "cp /c_relay_pg_static_musl_x86_64 /output/"
@echo "Static binary created: build/c_relay_pg_static_musl_x86_64"
static-musl-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 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"
@echo "Static binary created: build/c_relay_static_musl_arm64"
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-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_pg_static_musl_arm64"
static-musl: static-musl-x86_64 static-musl-arm64
@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
![](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.
![](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.
![](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
![](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.
![](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.
![](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.
+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.
## 🚀 Why C-Relay?
## 🚀 Why C-Relay-PG?
### 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
- **Real-time updates** - Changes applied instantly without restart
- **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
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-09**: Event deletion
@@ -89,12 +89,12 @@ Download and run - no dependencies required:
```bash
# 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
chmod +x c-relay-v0.6.0-linux-x86_64-static
mv c-relay-v0.6.0-linux-x86_64-static c-relay
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-pg-v0.6.0-linux-x86_64-static
mv c-relay-pg-v0.6.0-linux-x86_64-static c-relay-pg
# 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.
@@ -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
# Clone and build
git clone https://github.com/your-org/c-relay.git
cd c-relay
git clone https://github.com/your-org/c-relay-pg.git
cd c-relay-pg
git submodule update --init --recursive
./make_and_restart_relay.sh
```
@@ -136,8 +136,8 @@ The web interface provides:
```bash
# Clone repository
git clone https://github.com/your-org/c-relay.git
cd c-relay
git clone https://github.com/your-org/c-relay-pg.git
cd c-relay-pg
git submodule update --init --recursive
# Build
@@ -147,25 +147,25 @@ make clean && make
sudo systemd/install-service.sh
# Start and enable
sudo systemctl start c-relay
sudo systemctl enable c-relay
sudo systemctl start c-relay-pg
sudo systemctl enable c-relay-pg
# 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
```bash
# Build Docker image
docker build -f Dockerfile.alpine-musl -t c-relay .
docker build -f Dockerfile.alpine-musl -t c-relay-pg .
# Run container
docker run -d \
--name c-relay \
--name c-relay-pg \
-p 8888:8888 \
-v /path/to/data:/data \
c-relay
c-relay-pg
```
### Cloud Deployment
@@ -181,7 +181,7 @@ See [`docs/deployment_guide.md`](docs/deployment_guide.md) for detailed deployme
## 🔧 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
@@ -239,8 +239,8 @@ The admin private key is displayed **only once** during first startup. Store it
```bash
# Save to secure location
echo "ADMIN_PRIVKEY=your_admin_private_key" > ~/.c-relay-admin
chmod 600 ~/.c-relay-admin
echo "ADMIN_PRIVKEY=your_admin_private_key" > ~/.c-relay-pg-admin
chmod 600 ~/.c-relay-pg-admin
```
### Production Security
@@ -269,9 +269,9 @@ Contributions are welcome! Please:
## 🔗 Links
- **Repository**: [https://github.com/your-org/c-relay](https://github.com/your-org/c-relay)
- **Releases**: [https://git.laantungir.net/laantungir/c-relay/releases](https://git.laantungir.net/laantungir/c-relay/releases)
- **Issues**: [https://github.com/your-org/c-relay/issues](https://github.com/your-org/c-relay/issues)
- **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-pg/releases](https://git.laantungir.net/laantungir/c-relay-pg/releases)
- **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)
## 💬 Support
+7 -7
View File
@@ -41,7 +41,7 @@ This guide is specifically tailored for C programs that use:
```bash
# 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)
vim Dockerfile.static
@@ -466,13 +466,13 @@ docker build -t my-app:latest .
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
```bash
cp /path/to/c-relay/Dockerfile.alpine-musl ./Dockerfile.static
cp /path/to/c-relay-pg/Dockerfile.alpine-musl ./Dockerfile.static
```
Then customize:
@@ -482,7 +482,7 @@ Then customize:
### 2. build_static.sh
```bash
cp /path/to/c-relay/build_static.sh ./
cp /path/to/c-relay-pg/build_static.sh ./
```
Then customize:
@@ -492,7 +492,7 @@ Then customize:
### 3. .dockerignore (Optional)
```bash
cp /path/to/c-relay/.dockerignore ./
cp /path/to/c-relay-pg/.dockerignore ./
```
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/)
- [nostr_core_lib](https://github.com/chebizarro/nostr_core_lib)
- [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
+2 -2
View File
@@ -4,7 +4,7 @@
<head>
<meta charset="UTF-8">
<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">
</head>
@@ -42,7 +42,7 @@
<span class="relay-letter" data-letter="Y">Y</span>
</div>
<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-pubkey-container" class="relay-pubkey-container">
<div id="relay-pubkey" class="relay-pubkey">Loading...</div>
+9 -9
View File
@@ -185,7 +185,7 @@ async function fetchRelayInfo(relayUrl) {
method: 'GET',
headers: {
'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
});
@@ -454,7 +454,7 @@ async function setupAutomaticRelayConnection(showSections = false) {
// Keep relay metadata (including version) even when pubkey is missing/fallback
relayInfoData = {
name: relayInfo?.name || 'C-Relay',
name: relayInfo?.name || 'C-Relay-PG',
version: relayInfo?.version || '',
description: relayInfo?.description || 'Nostr Relay',
pubkey: relayPubkey
@@ -3963,9 +3963,9 @@ async function testPostEvent() {
created_at: Math.floor(Date.now() / 1000),
tags: [
["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');
@@ -4249,7 +4249,7 @@ function updateRelayInfoInHeader() {
// Get relay info from NIP-11/config data or use defaults
const relayInfo = getRelayInfo();
const relayName = relayInfo.name || 'C-Relay';
const relayName = relayInfo.name || 'C-Relay-PG';
const relayVersion = relayInfo.version || '';
const relayDescription = relayInfo.description || 'Nostr Relay';
@@ -4292,7 +4292,7 @@ function getRelayInfo() {
// Default values
return {
name: 'C-Relay',
name: 'C-Relay-PG',
version: '',
description: 'Nostr Relay',
pubkey: relayPubkey
@@ -4303,7 +4303,7 @@ function getRelayInfo() {
function updateStoredRelayInfo(configData) {
if (configData && configData.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 relayDescription = configData.data.find(item => item.key === 'relay_description')?.value || 'Nostr Relay';
@@ -5421,7 +5421,7 @@ function switchPage(pageName) {
// Initialize the app
document.addEventListener('DOMContentLoaded', () => {
console.log('C-Relay Admin API interface loaded');
console.log('C-Relay-PG Admin API interface loaded');
// Initialize dark mode
initializeDarkMode();
@@ -5523,7 +5523,7 @@ const SQL_QUERY_TEMPLATES = {
};
// 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;
// Load query history from localStorage
+11 -11
View File
@@ -1,6 +1,6 @@
#!/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
set -e
@@ -14,11 +14,11 @@ DEBUG_BUILD=false
if [[ "$1" == "--debug" ]]; then
DEBUG_BUILD=true
echo "=========================================="
echo "C-Relay MUSL Static Binary Builder (DEBUG MODE)"
echo "C-Relay-PG MUSL Static Binary Builder (DEBUG MODE)"
echo "=========================================="
else
echo "=========================================="
echo "C-Relay MUSL Static Binary Builder (PRODUCTION MODE)"
echo "C-Relay-PG MUSL Static Binary Builder (PRODUCTION MODE)"
echo "=========================================="
fi
echo "Project directory: $SCRIPT_DIR"
@@ -63,17 +63,17 @@ ARCH=$(uname -m)
case "$ARCH" in
x86_64)
PLATFORM="linux/amd64"
OUTPUT_NAME="c_relay_static_x86_64"
OUTPUT_NAME="c_relay_pg_static_x86_64"
;;
aarch64|arm64)
PLATFORM="linux/arm64"
OUTPUT_NAME="c_relay_static_arm64"
OUTPUT_NAME="c_relay_pg_static_arm64"
;;
*)
echo "WARNING: Unknown architecture: $ARCH"
echo "Defaulting to linux/amd64"
PLATFORM="linux/amd64"
OUTPUT_NAME="c_relay_static_${ARCH}"
OUTPUT_NAME="c_relay_pg_static_${ARCH}"
;;
esac
@@ -116,14 +116,14 @@ echo "=========================================="
echo "This will:"
echo " - Use Alpine Linux (native MUSL)"
echo " - Build all dependencies statically"
echo " - Compile c-relay with full static linking"
echo " - Compile c-relay-pg with full static linking"
echo ""
$DOCKER_CMD build \
--platform "$PLATFORM" \
--build-arg DEBUG_BUILD=$DEBUG_BUILD \
-f "$DOCKERFILE" \
-t c-relay-musl-builder:latest \
-t c-relay-pg-musl-builder:latest \
--progress=plain \
. || {
echo ""
@@ -147,14 +147,14 @@ $DOCKER_CMD build \
--build-arg DEBUG_BUILD=$DEBUG_BUILD \
--target builder \
-f "$DOCKERFILE" \
-t c-relay-static-builder-stage:latest \
-t c-relay-pg-static-builder-stage:latest \
. > /dev/null 2>&1
# 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
$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"
$DOCKER_CMD rm "$CONTAINER_ID" 2>/dev/null
exit 1
+4 -4
View File
@@ -1,12 +1,12 @@
#!/bin/bash
# Restart the service
sudo systemctl stop c-relay.service
sudo systemctl stop c-relay-pg.service
# 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
sudo systemctl restart c-relay.service
sudo systemctl restart c-relay-pg.service
# 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
# C-Relay Static Binary Deployment Script
# Deploys build/c_relay_static_x86_64 to server via ssh
# C-Relay-PG Static Binary Deployment Script
# Deploys build/c_relay_pg_static_x86_64 to server via ssh
set -e
# Configuration
LOCAL_BINARY="build/c_relay_static_x86_64"
REMOTE_BINARY_PATH="/usr/local/bin/c_relay/c_relay"
SERVICE_NAME="c-relay"
LOCAL_BINARY="build/c_relay_pg_static_x86_64"
REMOTE_BINARY_PATH="/usr/local/bin/c_relay_pg/c_relay_pg"
SERVICE_NAME="c-relay-pg"
# 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
# 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
ssh ubuntu@laantungir.com "sudo mv '/tmp/c_relay.tmp' '$REMOTE_BINARY_PATH'"
ssh ubuntu@laantungir.com "sudo chown c-relay:c-relay '$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-pg:c-relay-pg '$REMOTE_BINARY_PATH'"
ssh ubuntu@laantungir.com "sudo chmod +x '$REMOTE_BINARY_PATH'"
# Reload systemd and restart service
+15 -15
View File
@@ -1,14 +1,14 @@
#!/bin/bash
# C-Relay Debug Binary Deployment Script
# Deploys build/c_relay_static_x86_64_debug to server for CPU profiling
# C-Relay-PG Debug Binary Deployment Script
# Deploys build/c_relay_pg_static_x86_64_debug to server for CPU profiling
#
# Usage:
# ./deploy_lt_debug.sh -- deploy debug binary and restart
# ./deploy_lt_debug.sh --profile -- deploy, then run perf and fetch results
#
# 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
#
# Restore production binary:
@@ -16,10 +16,10 @@
set -e
LOCAL_DEBUG_BINARY="build/c_relay_static_x86_64_debug"
REMOTE_BINARY_PATH="/usr/local/bin/c_relay/c_relay"
REMOTE_PROD_BACKUP="/usr/local/bin/c_relay/c_relay.production"
SERVICE_NAME="c-relay"
LOCAL_DEBUG_BINARY="build/c_relay_pg_static_x86_64_debug"
REMOTE_BINARY_PATH="/usr/local/bin/c_relay_pg/c_relay_pg"
REMOTE_PROD_BACKUP="/usr/local/bin/c_relay_pg/c_relay_pg.production"
SERVICE_NAME="c-relay-pg"
REMOTE_HOST="ubuntu@laantungir.com"
# Check debug binary exists
@@ -33,7 +33,7 @@ if [ ! -f "$LOCAL_DEBUG_BINARY" ]; then
fi
echo "=========================================="
echo "C-Relay Debug Deployment"
echo "C-Relay-PG Debug Deployment"
echo "=========================================="
echo "Binary: $LOCAL_DEBUG_BINARY ($(du -h "$LOCAL_DEBUG_BINARY" | cut -f1))"
echo "Target: $REMOTE_HOST:$REMOTE_BINARY_PATH"
@@ -55,18 +55,18 @@ ssh "$REMOTE_HOST" "
# Upload 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
echo "Installing debug binary..."
ssh "$REMOTE_HOST" "
sudo mv '/tmp/c_relay_debug.tmp' '$REMOTE_BINARY_PATH'
sudo chown c-relay:c-relay '$REMOTE_BINARY_PATH'
sudo mv '/tmp/c_relay_pg_debug.tmp' '$REMOTE_BINARY_PATH'
sudo chown c-relay-pg:c-relay-pg '$REMOTE_BINARY_PATH'
sudo chmod +x '$REMOTE_BINARY_PATH'
"
# 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'"
echo ""
@@ -84,9 +84,9 @@ if [ "$1" = "--profile" ]; then
sleep 3
ssh "$REMOTE_HOST" "
PID=\$(pgrep c_relay)
PID=\$(pgrep c_relay_pg)
if [ -z \"\$PID\" ]; then
echo 'ERROR: c_relay not running'
echo 'ERROR: c_relay_pg not running'
exit 1
fi
echo \"Profiling PID \$PID for 30 seconds...\"
@@ -101,7 +101,7 @@ else
echo "=========================================="
echo ""
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 ""
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
@@ -161,7 +161,7 @@ Would require changing schema, migration scripts, and storage logic.
#### README.md Documentation Format:
```markdown
# C-Relay Administrator API
# C-Relay-PG Administrator API
## Authentication
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
+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
1. Create `c_utils_lib` repository
@@ -333,16 +333,16 @@ int main() {
4. Add basic tests
### 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
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
### Phase 3: Add as Submodule
1. Add `c_utils_lib` as submodule to c-relay
2. Update c-relay Makefile
3. Update includes in c-relay source files
4. Remove old debug files from c-relay
1. Add `c_utils_lib` as submodule to c-relay-pg
2. Update c-relay-pg Makefile
3. Update includes in c-relay-pg source files
4. Remove old debug files from c-relay-pg
### Phase 4: Documentation & Examples
1. Create comprehensive README
@@ -352,7 +352,7 @@ int main() {
## Benefits
### For c-relay
### For c-relay-pg
- Cleaner separation of concerns
- Reusable utilities across projects
- Easier to maintain and test
@@ -379,7 +379,7 @@ int main() {
- Memory leak detection (valgrind)
### Integration Tests
- Test with real projects (c-relay, nostr_core_lib)
- Test with real projects (c-relay-pg, nostr_core_lib)
- Cross-platform testing
- Performance benchmarks
@@ -433,7 +433,7 @@ MIT License - permissive and suitable for learning and commercial use.
## Success Criteria
1. ✅ Successfully integrated into c-relay
1. ✅ Successfully integrated into c-relay-pg
2. ✅ Successfully integrated into nostr_core_lib
3. ✅ All tests passing
4. ✅ Documentation complete
@@ -449,7 +449,7 @@ MIT License - permissive and suitable for learning and commercial use.
4. Create build system
5. Write tests
6. Create documentation
7. Integrate into c-relay
7. Integrate into c-relay-pg
8. Publish to GitHub
---
+16 -16
View File
@@ -2,13 +2,13 @@
## 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
### Step 1.1: Create Repository Structure
**Location**: Create outside c-relay project (sibling directory)
**Location**: Create outside c-relay-pg project (sibling directory)
```bash
# Create directory structure
@@ -42,7 +42,7 @@ git branch -M main
### 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.h``c_utils_lib/include/c_utils/debug.h`
@@ -484,20 +484,20 @@ How to integrate into projects:
3. Code examples
4. Migration from standalone utilities
## Phase 7: Integration with c-relay
## Phase 7: Integration with c-relay-pg
### Step 7.1: Add as Submodule
```bash
cd /path/to/c-relay
cd /path/to/c-relay-pg
git submodule add <repo-url> c_utils_lib
git submodule update --init --recursive
```
### Step 7.2: Update c-relay Makefile
### Step 7.2: Update c-relay-pg Makefile
```makefile
# Add to c-relay Makefile
# Add to c-relay-pg Makefile
C_UTILS_LIB = c_utils_lib/libc_utils.a
# Update includes
@@ -514,7 +514,7 @@ $(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**:
@@ -543,7 +543,7 @@ $(TARGET): $(C_UTILS_LIB) ...
### Step 7.4: Test Integration
```bash
cd c-relay
cd c-relay-pg
make clean
make
./make_and_restart_relay.sh
@@ -556,7 +556,7 @@ Verify:
## 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
# Add version generation
@@ -567,7 +567,7 @@ src/version.h: .git/refs/tags/*
$(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:
```c
@@ -583,7 +583,7 @@ Replace hardcoded version in `src/main.h` with:
- **Phase 4**: Build System - 2 hours
- **Phase 5**: Examples & Tests - 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
**Total**: ~19 hours
@@ -593,11 +593,11 @@ Replace hardcoded version in `src/main.h` with:
- [ ] c_utils_lib builds successfully
- [ ] All tests pass
- [ ] Examples compile and run
- [ ] c-relay integrates successfully
- [ ] Debug output works in c-relay
- [ ] c-relay-pg integrates successfully
- [ ] Debug output works in c-relay-pg
- [ ] Version generation works
- [ ] Documentation complete
- [ ] No regressions in c-relay functionality
- [ ] No regressions in c-relay-pg functionality
## Next Steps
@@ -608,7 +608,7 @@ Replace hardcoded version in `src/main.h` with:
5. Create build system
6. Write tests and examples
7. Create documentation
8. Integrate into c-relay
8. Integrate into c-relay-pg
9. Test thoroughly
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`
- **Description**: Software identifier for NIP-11
- **Default**: `"c-relay"`
- **Default**: `"c-relay-pg"`
- **Format**: String, max 64 characters
- **Example**: `"c-relay v1.0.0"`
- **Example**: `"c-relay-pg v1.0.0"`
#### `relay_version`
- **Description**: Software version string
@@ -366,7 +366,7 @@ sqlite3 relay.nrdb "SELECT json_pretty(json_object(
#### Invalid Parameter Values
```bash
# 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:
# - Numeric values outside valid ranges
@@ -395,10 +395,10 @@ ORDER BY date DESC;"
#### Resource Usage After Changes
```bash
# Monitor system resources after configuration updates
top -p $(pgrep c_relay)
top -p $(pgrep c_relay_pg)
# 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
@@ -425,7 +425,7 @@ nostrtool event \
# If database is corrupted, backup and recreate
cp relay.nrdb relay.nrdb.backup
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
# Production (default - no debug output)
./c_relay_x86
./c_relay_pg_x86
# Show errors only
./c_relay_x86 --debug-level=1
./c_relay_pg_x86 --debug-level=1
# 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)
./c_relay_x86 --debug-level=3
./c_relay_pg_x86 --debug-level=3
# 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)
./c_relay_x86 --debug-level=5
./c_relay_pg_x86 --debug-level=5
```
## 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)
```
[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] [ERROR] Failed to open database: permission denied
[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)
```
[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] Executing schema initialization
[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)
```
[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] [TRACE] [main.c:330] Entering init_database()
[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
# Test different levels
./build/c_relay_x86 # No output
./build/c_relay_x86 --debug-level=1 # Errors only
./build/c_relay_x86 --debug-level=3 # Info + warnings + errors
./build/c_relay_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 # No output
./build/c_relay_pg_x86 --debug-level=1 # Errors only
./build/c_relay_pg_x86 --debug-level=3 # Info + warnings + errors
./build/c_relay_pg_x86 --debug-level=4 # All debug messages
./build/c_relay_pg_x86 --debug-level=5 # Everything with file:line on TRACE
```
### 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)
{"relay_description", "High-performance C Nostr relay with SQLite storage"},
{"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"},
// 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
```bash
# 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
sudo mkdir -p /opt/c-relay
sudo chown c-relay:c-relay /opt/c-relay
sudo mkdir -p /opt/c-relay-pg
sudo chown c-relay-pg:c-relay-pg /opt/c-relay-pg
```
### Build and Installation
@@ -64,8 +64,8 @@ sudo chown c-relay:c-relay /opt/c-relay
#### Automated Installation (Recommended)
```bash
# Clone repository
git clone https://github.com/your-org/c-relay.git
cd c-relay
git clone https://github.com/your-org/c-relay-pg.git
cd c-relay-pg
git submodule update --init --recursive
# Build
@@ -81,12 +81,12 @@ sudo systemd/install-service.sh
make clean && make
# Install binary
sudo cp build/c_relay_x86 /opt/c-relay/
sudo chown c-relay:c-relay /opt/c-relay/c_relay_x86
sudo chmod +x /opt/c-relay/c_relay_x86
sudo cp build/c_relay_pg_x86 /opt/c-relay-pg/
sudo chown c-relay-pg:c-relay-pg /opt/c-relay-pg/c_relay_pg_x86
sudo chmod +x /opt/c-relay-pg/c_relay_pg_x86
# 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
```
@@ -95,22 +95,22 @@ sudo systemctl daemon-reload
#### Start and Enable Service
```bash
# Start the service
sudo systemctl start c-relay
sudo systemctl start c-relay-pg
# Enable auto-start on boot
sudo systemctl enable c-relay
sudo systemctl enable c-relay-pg
# Check status
sudo systemctl status c-relay
sudo systemctl status c-relay-pg
```
#### Capture Admin Keys (CRITICAL)
```bash
# 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
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!
@@ -151,8 +151,8 @@ sudo iptables-save > /etc/iptables/rules.v4
ssh -i your-key.pem ubuntu@your-instance-ip
# Use the simple deployment script
git clone https://github.com/your-org/c-relay.git
cd c-relay
git clone https://github.com/your-org/c-relay-pg.git
cd c-relay-pg
sudo examples/deployment/simple-vps/deploy.sh
```
@@ -168,10 +168,10 @@ sudo examples/deployment/simple-vps/deploy.sh
sudo mkfs.ext4 /dev/xvdf
sudo mkdir /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
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
```
@@ -180,7 +180,7 @@ sudo systemctl daemon-reload
#### Compute Engine Setup
```bash
# 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-project=ubuntu-os-cloud \
--machine-type=e2-micro \
@@ -193,9 +193,9 @@ gcloud compute firewall-rules create allow-nostr-relay \
--target-tags nostr-relay
# SSH and deploy
gcloud compute ssh c-relay-instance
git clone https://github.com/your-org/c-relay.git
cd c-relay
gcloud compute ssh c-relay-pg-instance
git clone https://github.com/your-org/c-relay-pg.git
cd c-relay-pg
sudo examples/deployment/simple-vps/deploy.sh
```
@@ -203,13 +203,13 @@ sudo examples/deployment/simple-vps/deploy.sh
```bash
# Create and attach persistent disk
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
sudo mkfs.ext4 /dev/sdb
sudo mkdir /data
sudo mount /dev/sdb /data
sudo chown c-relay:c-relay /data
sudo chown c-relay-pg:c-relay-pg /data
```
### DigitalOcean
@@ -223,8 +223,8 @@ sudo chown c-relay:c-relay /data
ssh root@your-droplet-ip
# Deploy relay
git clone https://github.com/your-org/c-relay.git
cd c-relay
git clone https://github.com/your-org/c-relay-pg.git
cd c-relay-pg
examples/deployment/simple-vps/deploy.sh
```
@@ -245,8 +245,8 @@ The `examples/deployment/` directory contains ready-to-use scripts:
### Simple VPS Deployment
```bash
# Clone repository and run automated deployment
git clone https://github.com/your-org/c-relay.git
cd c-relay
git clone https://github.com/your-org/c-relay-pg.git
cd c-relay-pg
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')
# 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
systemctl restart c-relay
systemctl restart c-relay-pg
fi
# Check port availability
@@ -428,14 +428,14 @@ if ! netstat -tln | grep -q ":8888"; then
fi
# 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
DB_SIZE=$(du -h "$RELAY_DB" | cut -f1)
echo "[$DATE] INFO: Database size: $DB_SIZE" >> $LOG_FILE
fi
# 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
echo "[$DATE] INFO: Memory usage: ${MEM_USAGE}KB" >> $LOG_FILE
fi
@@ -454,8 +454,8 @@ sudo chmod +x /usr/local/bin/relay-monitor.sh
#### Centralized Logging with rsyslog
```bash
# /etc/rsyslog.d/50-c-relay.conf
if $programname == 'c-relay' then /var/log/c-relay.log
# /etc/rsyslog.d/50-c-relay-pg.conf
if $programname == 'c-relay-pg' then /var/log/c-relay-pg.log
& stop
```
@@ -465,7 +465,7 @@ if $programname == 'c-relay' then /var/log/c-relay.log
```yaml
# /etc/prometheus/prometheus.yml
scrape_configs:
- job_name: 'c-relay'
- job_name: 'c-relay-pg'
static_configs:
- targets: ['localhost:8888']
metrics_path: '/metrics' # If implemented
@@ -479,30 +479,30 @@ scrape_configs:
#### Service User Restrictions
```bash
# Restrict service user
sudo usermod -s /bin/false c-relay
sudo usermod -d /opt/c-relay c-relay
sudo usermod -s /bin/false c-relay-pg
sudo usermod -d /opt/c-relay-pg c-relay-pg
# Set proper permissions
sudo chmod 700 /opt/c-relay
sudo chown -R c-relay:c-relay /opt/c-relay
sudo chmod 700 /opt/c-relay-pg
sudo chown -R c-relay-pg:c-relay-pg /opt/c-relay-pg
```
#### File System Restrictions
```bash
# 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
#### Fail2Ban Configuration
```ini
# /etc/fail2ban/jail.d/c-relay.conf
[c-relay-dos]
# /etc/fail2ban/jail.d/c-relay-pg.conf
[c-relay-pg-dos]
enabled = true
port = 8888
filter = c-relay-dos
logpath = /var/log/c-relay.log
filter = c-relay-pg-dos
logpath = /var/log/c-relay-pg.log
maxretry = 10
findtime = 60
bantime = 300
@@ -534,9 +534,9 @@ sudo mkfs.ext4 /dev/mapper/relay-data
#!/bin/bash
# /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)
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"
@@ -574,7 +574,7 @@ sudo apt install -y awscli
aws configure
# 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
@@ -583,16 +583,16 @@ aws s3 sync /backup/c-relay/ s3://your-backup-bucket/c-relay/ --delete
```bash
# 1. Restore from backup
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
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
sudo systemctl restart c-relay
sudo systemctl restart c-relay-pg
# 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
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?
@@ -36,8 +36,8 @@ This guide explains how to build truly portable MUSL-based static binaries of c-
./build_static.sh
# The binary will be created at:
# build/c_relay_static_musl_x86_64 (on x86_64)
# build/c_relay_static_musl_arm64 (on ARM64)
# build/c_relay_pg_static_musl_x86_64 (on x86_64)
# build/c_relay_pg_static_musl_arm64 (on ARM64)
```
### 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
- 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
- Fortification disabled to avoid `__*_chk` symbols
- Results in ~7.6MB stripped binary
@@ -78,7 +78,7 @@ FROM alpine:3.19 AS builder
- Install build tools and static libraries
- Build dependencies from source
- 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
# 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"
```
**For c-relay:**
**For c-relay-pg:**
```bash
gcc -static -O2 -Wall -Wextra -std=c99 \
-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)
- `-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
@@ -129,26 +129,26 @@ The build includes these NIPs in nostr_core_lib:
```bash
# 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"
ldd build/c_relay_static_musl_x86_64
ldd build/c_relay_pg_static_musl_x86_64
# 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
```bash
# Show help
./build/c_relay_static_musl_x86_64 --help
./build/c_relay_pg_static_musl_x86_64 --help
# Show version
./build/c_relay_static_musl_x86_64 --version
./build/c_relay_pg_static_musl_x86_64 --version
# Run relay
./build/c_relay_static_musl_x86_64 --port 8888
./build/c_relay_pg_static_musl_x86_64 --port 8888
```
### Cross-Distribution Testing
@@ -157,16 +157,16 @@ Test the binary on different distributions to verify portability:
```bash
# 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
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
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
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
@@ -187,7 +187,7 @@ newgrp docker # Or logout and login again
**Solution**: Ensure fortification is disabled in both:
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
@@ -213,26 +213,26 @@ newgrp docker # Or logout and login again
```bash
# 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!)
ssh user@server
cd /opt/c-relay
./c_relay_static_musl_x86_64 --port 8888
cd /opt/c-relay-pg
./c_relay_pg_static_musl_x86_64 --port 8888
```
### SystemD Service
```ini
[Unit]
Description=C-Relay Nostr Relay (MUSL Static)
Description=C-Relay-PG Nostr Relay (MUSL Static)
After=network.target
[Service]
Type=simple
User=c-relay
WorkingDirectory=/opt/c-relay
ExecStart=/opt/c-relay/c_relay_static_musl_x86_64
User=c-relay-pg
WorkingDirectory=/opt/c-relay-pg
ExecStart=/opt/c-relay-pg/c_relay_pg_static_musl_x86_64
Restart=always
RestartSec=5
+4 -4
View File
@@ -23,7 +23,7 @@ We chose Option B because:
## Detailed Implementation Steps
### Phase 1: Configuration Setup in c-relay
### Phase 1: Configuration Setup in c-relay-pg
#### 1.1 Add Configuration Parameter
**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
**Location:** Line 1319
@@ -470,7 +470,7 @@ causing compatibility issues.
- [ ] Update `nostr_nip17_send_dm()` signature and implementation
- [ ] 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 validation in `config.c` for new parameter
- [ ] Update `src/api.c` call site to pass `max_delay_sec`
@@ -494,7 +494,7 @@ causing compatibility issues.
If issues arise:
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
4. Default behavior (0) provides maximum compatibility
+2 -2
View File
@@ -2,7 +2,7 @@
## 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
@@ -271,7 +271,7 @@ const SQL_QUERY_TEMPLATES = {
};
// 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;
// Load query history from localStorage
+1 -1
View File
@@ -224,7 +224,7 @@ The script should:
- `curl` or `websocat` for WebSocket communication
- `jq` for JSON parsing
- Nostr CLI tools (optional, for event signing)
- Running c-relay instance
- Running c-relay-pg instance
## Example Output
+6 -6
View File
@@ -1,8 +1,8 @@
# C-Relay Complete Startup Flow Documentation
# C-Relay-PG Complete Startup Flow Documentation
## 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
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[] = {
{"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},
{"max_subscriptions_per_client", "25", "integer", "Max subs per client", "limits", 0},
{"pow_min_difficulty", "0", "integer", "Minimum PoW difficulty", "security", 0},
@@ -983,7 +983,7 @@ if (current_version < LATEST_VERSION) {
**Solutions**:
- 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`
- Use `--strict-port` to fail fast instead of trying fallback ports
@@ -994,7 +994,7 @@ if (current_version < LATEST_VERSION) {
**Solutions**:
- Kill existing relay processes
- 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
@@ -1071,7 +1071,7 @@ Typical startup times (on modern hardware):
## 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
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:
- **Cache location**: `~/.cache/c-relay-sqlite/`
- **Cache location**: `~/.cache/c-relay-pg-sqlite/`
- **Version-specific**: Each SQLite version gets its own cache directory
- **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
@@ -51,13 +51,13 @@ The script will:
## Binary Types
### 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)
- **Portability**: Works on any Linux distribution
- **Status**: Requires MUSL-compiled libwebsockets and other dependencies (not available by default)
### 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
- **Portability**: Works on most Linux distributions (glibc is statically included)
- **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
# 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!)
# For glibc binary
ldd build/c_relay_static_glibc_x86_64
ldd build/c_relay_pg_static_glibc_x86_64
# Output: Shows glibc dependencies
```
@@ -112,7 +112,7 @@ The script attempts MUSL compilation but falls back to glibc:
### Clear SQLite Cache
```bash
rm -rf ~/.cache/c-relay-sqlite
rm -rf ~/.cache/c-relay-pg-sqlite
```
### Force Package Reinstall
@@ -127,8 +127,8 @@ cat /tmp/musl_build.log
### Verify Binary Type
```bash
file build/c_relay_static_*
ldd build/c_relay_static_* 2>&1
file build/c_relay_pg_static_*
ldd build/c_relay_pg_static_* 2>&1
```
## Performance Impact
+1 -1
View File
@@ -2,7 +2,7 @@
## 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
+8 -8
View File
@@ -586,7 +586,7 @@ int add_pubkeys_to_config_table(void) {
rm -f *.db
# Start relay with defaults
./build/c_relay_x86
./build/c_relay_pg_x86
# Verify config table complete
sqlite3 <relay_pubkey>.db "SELECT COUNT(*) FROM config;"
@@ -602,7 +602,7 @@ int add_pubkeys_to_config_table(void) {
rm -f *.db
# Start relay with port override
./build/c_relay_x86 --port 9999
./build/c_relay_pg_x86 --port 9999
# Verify port override applied
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**
```bash
# Start relay (creates database)
./build/c_relay_x86
./build/c_relay_pg_x86
# Stop relay
pkill -f c_relay_
pkill -f c_relay_pg_
# Restart relay
./build/c_relay_x86
./build/c_relay_pg_x86
# Verify config unchanged
# Check relay.log for validation message
@@ -627,13 +627,13 @@ int add_pubkeys_to_config_table(void) {
4. **Restart with CLI Overrides**
```bash
# Start relay (creates database)
./build/c_relay_x86
./build/c_relay_pg_x86
# Stop relay
pkill -f c_relay_
pkill -f c_relay_pg_
# Restart with port override
./build/c_relay_x86 --port 9999
./build/c_relay_pg_x86 --port 9999
# Verify port override applied
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
# Clone and build
git clone <repository-url>
cd c-relay
cd c-relay-pg
git submodule update --init --recursive
make
# Start relay (zero configuration needed)
./build/c_relay_x86
./build/c_relay_pg_x86
```
### 2. First Startup - Save Keys
@@ -78,7 +78,7 @@ brew install git sqlite libwebsockets openssl libsecp256k1 curl zlib
```bash
# Clone repository
git clone <repository-url>
cd c-relay
cd c-relay-pg
# Initialize submodules
git submodule update --init --recursive
@@ -87,7 +87,7 @@ git submodule update --init --recursive
make clean && make
# Verify build
ls -la build/c_relay_x86
ls -la build/c_relay_pg_x86
```
### Production Deployment
@@ -98,27 +98,27 @@ ls -la build/c_relay_x86
sudo systemd/install-service.sh
# Start service
sudo systemctl start c-relay
sudo systemctl start c-relay-pg
# Enable auto-start
sudo systemctl enable c-relay
sudo systemctl enable c-relay-pg
# Check status
sudo systemctl status c-relay
sudo systemctl status c-relay-pg
```
#### Manual Deployment
```bash
# 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
sudo mkdir -p /opt/c-relay
sudo cp build/c_relay_x86 /opt/c-relay/
sudo chown -R c-relay:c-relay /opt/c-relay
sudo mkdir -p /opt/c-relay-pg
sudo cp build/c_relay_pg_x86 /opt/c-relay-pg/
sudo chown -R c-relay-pg:c-relay-pg /opt/c-relay-pg
# 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
@@ -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_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
| Parameter | Description | Default | Range |
@@ -273,7 +273,7 @@ chmod 600 admin_keys_backup_*.txt
#### Key Recovery
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`
3. **Remove database**: `rm <relay_pubkey>.nrdb*`
4. **Restart relay**: This creates new database with new keys
@@ -300,7 +300,7 @@ sudo ufw allow 8888/tcp
```bash
# Secure database file permissions
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
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
```bash
# Check if relay is running
ps aux | grep c_relay
ps aux | grep c_relay_pg
# SystemD status
sudo systemctl status c-relay
sudo systemctl status c-relay-pg
# Network connections
netstat -tln | grep 8888
@@ -324,16 +324,16 @@ sudo ss -tlpn | grep 8888
### Log Monitoring
```bash
# Real-time logs (systemd)
sudo journalctl -u c-relay -f
sudo journalctl -u c-relay-pg -f
# Recent logs
sudo journalctl -u c-relay --since "1 hour ago"
sudo journalctl -u c-relay-pg --since "1 hour ago"
# Error logs only
sudo journalctl -u c-relay -p err
sudo journalctl -u c-relay-pg -p err
# 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
@@ -365,13 +365,13 @@ ORDER BY created_at DESC;
du -sh <relay_pubkey>.nrdb*
# 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)
netstat -an | grep :8888 | grep ESTABLISHED | wc -l
# System resources
top -p $(pgrep c_relay)
top -p $(pgrep c_relay_pg)
```
## Troubleshooting
@@ -385,11 +385,11 @@ netstat -tln | grep 8888
# If port in use, find process: sudo lsof -i :8888
# Check binary permissions
ls -la build/c_relay_x86
chmod +x build/c_relay_x86
ls -la build/c_relay_pg_x86
chmod +x build/c_relay_pg_x86
# Check dependencies
ldd build/c_relay_x86
ldd build/c_relay_pg_x86
```
#### Configuration Not Updating
@@ -442,7 +442,7 @@ sqlite3 recovered.nrdb < recovered.sql
# If repair fails, start fresh (loses all events)
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
@@ -455,12 +455,12 @@ If configuration is lost but database is intact:
#### Emergency Restart
```bash
# Quick restart with clean state
sudo systemctl stop c-relay
sudo systemctl stop c-relay-pg
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
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
@@ -503,7 +503,7 @@ ws.on('open', function() {
# backup-relay.sh
DATE=$(date +%Y%m%d_%H%M%S)
DB_FILE=$(ls *.nrdb | head -1)
BACKUP_DIR="/backup/c-relay"
BACKUP_DIR="/backup/c-relay-pg"
mkdir -p $BACKUP_DIR
cp $DB_FILE $BACKUP_DIR/relay_backup_$DATE.nrdb
@@ -533,7 +533,7 @@ tar czf relay_migration.tar.gz *.nrdb* relay.log
# Target server
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
# 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
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
- **Firewall Configuration**: Examples include proper firewall rules
- **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
+6 -6
View File
@@ -13,8 +13,8 @@ BLUE='\033[0;34m'
NC='\033[0m' # No Color
# Default configuration
RELAY_DIR="/opt/c-relay"
BACKUP_DIR="/backup/c-relay"
RELAY_DIR="/opt/c-relay-pg"
BACKUP_DIR="/backup/c-relay-pg"
RETENTION_DAYS="30"
COMPRESS="true"
REMOTE_BACKUP=""
@@ -47,8 +47,8 @@ show_help() {
echo "Usage: $0 [OPTIONS]"
echo
echo "Options:"
echo " -d, --relay-dir DIR Relay directory (default: /opt/c-relay)"
echo " -b, --backup-dir DIR Backup directory (default: /backup/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-pg)"
echo " -r, --retention DAYS Retention period in days (default: 30)"
echo " -n, --no-compress Don't compress backups"
echo " -s, --s3-bucket BUCKET Upload to S3 bucket"
@@ -231,7 +231,7 @@ upload_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
print_success "Backup uploaded to S3: $s3_path"
@@ -264,7 +264,7 @@ cleanup_old_backups() {
print_step "Cleaning S3 backups older than $cutoff_date..."
# 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}' | \
while read -r key; do
aws s3 rm "s3://$S3_BUCKET/$key"
@@ -13,8 +13,8 @@ BLUE='\033[0;34m'
NC='\033[0m' # No Color
# Configuration
RELAY_DIR="/opt/c-relay"
SERVICE_NAME="c-relay"
RELAY_DIR="/opt/c-relay-pg"
SERVICE_NAME="c-relay-pg"
RELAY_PORT="8888"
LOG_FILE="/var/log/relay-monitor.log"
ALERT_EMAIL=""
@@ -60,7 +60,7 @@ show_help() {
echo "Usage: $0 [OPTIONS]"
echo
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 " -i, --interval SECONDS Check interval (default: 60)"
echo " -e, --email EMAIL Alert email address"
@@ -134,7 +134,7 @@ parse_args() {
check_process_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"
return 0
else
@@ -172,7 +172,7 @@ check_service_status() {
check_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
print_warning "Could not determine memory usage"
+4 -4
View File
@@ -56,7 +56,7 @@ http {
}
# Upstream for the relay
upstream c_relay_backend {
upstream c_relay_pg_backend {
server 127.0.0.1:8888;
keepalive 32;
}
@@ -108,7 +108,7 @@ http {
# Main proxy location for WebSocket and HTTP
location / {
# Proxy settings
proxy_pass http://c_relay_backend;
proxy_pass http://c_relay_pg_backend;
proxy_http_version 1.1;
proxy_cache_bypass $http_upgrade;
@@ -144,7 +144,7 @@ http {
# Health check endpoint (if implemented)
location /health {
proxy_pass http://c_relay_backend/health;
proxy_pass http://c_relay_pg_backend/health;
access_log off;
}
@@ -157,7 +157,7 @@ http {
# Optional: Metrics endpoint (if implemented)
location /metrics {
proxy_pass http://c_relay_backend/metrics;
proxy_pass http://c_relay_pg_backend/metrics;
# Restrict access to monitoring systems
allow 10.0.0.0/8;
allow 172.16.0.0/12;
@@ -96,9 +96,9 @@ check_root() {
check_relay_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 "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
fi
+12 -12
View File
@@ -13,9 +13,9 @@ BLUE='\033[0;34m'
NC='\033[0m' # No Color
# Configuration
RELAY_USER="c-relay"
INSTALL_DIR="/opt/c-relay"
SERVICE_NAME="c-relay"
RELAY_USER="c-relay-pg"
INSTALL_DIR="/opt/c-relay-pg"
SERVICE_NAME="c-relay-pg"
RELAY_PORT="8888"
# Functions
@@ -99,7 +99,7 @@ build_relay() {
# Check if we're in the source directory
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
fi
@@ -107,7 +107,7 @@ build_relay() {
make clean
make
if [[ ! -f "build/c_relay_x86" ]]; then
if [[ ! -f "build/c_relay_pg_x86" ]]; then
print_error "Build failed - binary not found"
exit 1
fi
@@ -118,9 +118,9 @@ build_relay() {
install_binary() {
print_step "Installing relay binary..."
cp build/c_relay_x86 "$INSTALL_DIR/"
chown "$RELAY_USER:$RELAY_USER" "$INSTALL_DIR/c_relay_x86"
chmod +x "$INSTALL_DIR/c_relay_x86"
cp build/c_relay_pg_x86 "$INSTALL_DIR/"
chown "$RELAY_USER:$RELAY_USER" "$INSTALL_DIR/c_relay_pg_x86"
chmod +x "$INSTALL_DIR/c_relay_pg_x86"
print_success "Binary installed to $INSTALL_DIR"
}
@@ -129,14 +129,14 @@ install_service() {
print_step "Installing systemd service..."
# Use the existing systemd service file
if [[ -f "systemd/c-relay.service" ]]; then
cp systemd/c-relay.service /etc/systemd/system/
if [[ -f "systemd/c-relay-pg.service" ]]; then
cp systemd/c-relay-pg.service /etc/systemd/system/
systemctl daemon-reload
print_success "Systemd service installed"
else
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]
Description=C Nostr Relay
After=network.target
@@ -146,7 +146,7 @@ Type=simple
User=$RELAY_USER
Group=$RELAY_USER
WorkingDirectory=$INSTALL_DIR
ExecStart=$INSTALL_DIR/c_relay_x86
ExecStart=$INSTALL_DIR/c_relay_pg_x86
Restart=always
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
FROM alpine:latest AS builder
@@ -125,7 +125,7 @@ RUN cd /tmp && \
--prefix=/usr && \
make && make install
# Copy c-relay source
# Copy c-relay-pg source
COPY . /build/
# Initialize submodules
@@ -134,7 +134,7 @@ RUN git submodule update --init --recursive
# Build nostr_core_lib
RUN cd nostr_core_lib && ./build.sh
# Build c-relay static
# Build c-relay-pg static
RUN make clean && \
CC="musl-gcc -static" \
CFLAGS="-O2 -Wall -Wextra -std=c99 -g" \
@@ -143,8 +143,8 @@ RUN make clean && \
make
# Strip binary for size
RUN strip build/c_relay_x86
RUN strip build/c_relay_pg_x86
# Multi-stage build to produce minimal 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"
show_usage() {
echo "C-Relay Increment and Push Script"
echo "C-Relay-PG Increment and Push Script"
echo ""
echo "USAGE:"
echo " $0 [OPTIONS] \"commit message\""
@@ -330,7 +330,7 @@ build_release_binary() {
create_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
if tar -czf "$tarball_name" \
@@ -365,7 +365,7 @@ upload_release_assets() {
fi
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"
print_status "Assets URL: $assets_url"
@@ -427,7 +427,7 @@ create_gitea_release() {
fi
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
print_status "Creating release $NEW_VERSION..."
@@ -473,7 +473,7 @@ create_gitea_release() {
# Main execution
main() {
print_status "C-Relay Increment and Push Script"
print_status "C-Relay-PG Increment and Push Script"
# Check prerequisites
check_git_repo
@@ -505,13 +505,13 @@ main() {
# Build release binary
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
print_warning "Binary build failed, continuing with release creation"
# 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"
binary_path="build/c_relay_static_x86_64"
binary_path="build/c_relay_pg_static_x86_64"
else
binary_path=""
fi
+10 -10
View File
@@ -1,6 +1,6 @@
#!/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
echo "=== C Nostr Relay Build and Restart Script ==="
@@ -242,13 +242,13 @@ fi
ARCH=$(uname -m)
case "$ARCH" in
x86_64)
BINARY_PATH="./build/c_relay_static_x86_64"
BINARY_PATH="./build/c_relay_pg_static_x86_64"
;;
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
@@ -270,7 +270,7 @@ echo "Build successful. Proceeding with relay restart..."
echo "Stopping any existing relay servers..."
# 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
echo "Force killing relay processes immediately: $RELAY_PIDS"
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
# 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
echo "Killing remaining relay processes: $REMAINING_PIDS"
kill -9 $REMAINING_PIDS 2>/dev/null || true
@@ -309,7 +309,7 @@ for attempt in {1..15}; do
done
# 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
echo "Final cleanup: killing processes $FINAL_PIDS"
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
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
RELAY_ARGS=""
@@ -428,8 +428,8 @@ if ps -p "$RELAY_PID" >/dev/null 2>&1; then
echo "=== Event-Based Relay Server Running ==="
echo "Configuration: Event-based (kind 33334 Nostr events)"
echo "Database: Automatically created with relay pubkey naming"
echo "To kill relay: pkill -f 'c_relay_'"
echo "To check status: ps aux | grep c_relay_"
echo "To kill relay: pkill -f 'c_relay_pg_'"
echo "To check status: ps aux | grep c_relay_pg_"
echo "To view logs: tail -f relay.log"
echo "Binary: $BINARY_PATH (zero configuration needed)"
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)
sudo coredumpctl list
# View info about the most recent c-relay crash
sudo coredumpctl info c-relay
# View info about the most recent c-relay-pg crash
sudo coredumpctl info c-relay-pg
# 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:
(gdb) bt full # Full backtrace with all variables
@@ -36,8 +36,8 @@ DEBUGGING
Even simpler: Use this one-liner
# Start relay and immediately attach gdb
cd /usr/local/bin/c_relay
sudo -u c-relay ./c_relay --debug-level=5 & sleep 2 && sudo gdb -p $(pgrep c_relay)
cd /usr/local/bin/c_relay_pg
sudo -u c-relay-pg ./c_relay_pg --debug-level=5 & sleep 2 && sudo gdb -p $(pgrep c_relay_pg)
Inside gdb, after attaching:
@@ -48,17 +48,17 @@ Or shorter:
How to View the Logs
Check systemd journal:
# View all c-relay logs
sudo journalctl -u c-relay
# View all c-relay-pg logs
sudo journalctl -u c-relay-pg
# 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
sudo journalctl -u c-relay -f
sudo journalctl -u c-relay-pg -f
# View logs since last boot
sudo journalctl -u c-relay -b
sudo journalctl -u c-relay-pg -b
Check if service is running:
@@ -78,9 +78,9 @@ sudo systemctl start 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
+1 -1
View File
@@ -1,5 +1,5 @@
{
"name": "c-relay",
"name": "c-relay-pg",
"lockfileVersion": 3,
"requires": true,
"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
**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
- 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.
### Why a Separate Project?
| | c-relay | c-relay-pg |
| | c-relay-pg | c-relay-pg-pg |
|---|---------|-----------|
| **Database** | SQLite (embedded) | PostgreSQL (client-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
flowchart TD
subgraph c-relay-pg - Production Deployment
LB[nginx - TLS + load balancing] -->|WebSocket| R1[c-relay-pg Instance 1]
LB -->|WebSocket| R2[c-relay-pg Instance 2]
subgraph c-relay-pg-pg - Production Deployment
LB[nginx - TLS + load balancing] -->|WebSocket| R1[c-relay-pg-pg Instance 1]
LB -->|WebSocket| R2[c-relay-pg-pg Instance 2]
LB -->|HTTP| DASH[Dashboard]
R1 -->|db_ops API| PGBACK[PostgreSQL Backend - db_ops_postgres.c]
R2 -->|db_ops API| PGBACK
@@ -44,18 +44,18 @@ flowchart TD
### 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
- `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.c` — Thin dispatcher that calls the active backend
### PostgreSQL Schema
```sql
-- PostgreSQL schema for c-relay-pg
-- PostgreSQL schema for c-relay-pg-pg
-- No event_tags table needed — JSONB + GIN handles everything
CREATE TABLE events (
@@ -289,14 +289,14 @@ psql -d crelay -c "REFRESH MATERIALIZED VIEW event_kinds_mv; REFRESH MATERIALIZE
### 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
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
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
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
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:8889| R2[c-relay-pg Instance 2 - port 8889]
NGINX -->|ws://localhost:8890| R3[c-relay-pg Instance 3 - port 8890]
NGINX -->|ws://localhost:8888| R1[c-relay-pg-pg Instance 1 - port 8888]
NGINX -->|ws://localhost:8889| R2[c-relay-pg-pg Instance 2 - port 8889]
NGINX -->|ws://localhost:8890| R3[c-relay-pg-pg Instance 3 - port 8890]
NGINX -->|http://localhost:3000| DASHWEB[Dashboard Web Server]
R1 -->|libpq connection pool| PGPOOL[PgBouncer - connection pooler]
@@ -325,7 +325,7 @@ flowchart TD
### nginx Load Balancing Config
```nginx
# nginx.conf - WebSocket load balancing for c-relay-pg
# nginx.conf - WebSocket load balancing for c-relay-pg-pg
upstream relay_backends {
# ip_hash ensures a client always hits the same instance
# (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
# 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
./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
./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:
```ini
# /etc/systemd/system/c-relay-pg@.service
# /etc/systemd/system/c-relay-pg-pg@.service
[Unit]
Description=C-Relay-PG Nostr Instance %i
Description=C-Relay-PG-PG Nostr Instance %i
After=postgresql.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
User=c-relay
User=c-relay-pg
[Install]
WantedBy=multi-user.target
```
```bash
systemctl enable c-relay-pg@8888 c-relay-pg@8889 c-relay-pg@8890
systemctl start 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-pg@8888 c-relay-pg-pg@8889 c-relay-pg-pg@8890
```
### Cross-Instance Event Broadcasting
@@ -559,13 +559,13 @@ for port in 8888 8889 8890; do
sleep 30
# 3. Stop old instance
systemctl stop c-relay-pg@$port
systemctl stop c-relay-pg-pg@$port
# 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
systemctl start c-relay-pg@$port
systemctl start c-relay-pg-pg@$port
# 6. Wait for health check
sleep 5
@@ -584,7 +584,7 @@ With PostgreSQL, the dashboard can be built with any technology:
- **Grafana** — Point directly at PostgreSQL, zero custom code
- **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
@@ -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_postgres.c` → PostgreSQL calls via `libpq` (`PQexec`, `PQgetvalue`, etc.)
- **c-relay-pg**: `db_ops.c` → SQLite calls via `sqlite3_*`
- **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.
+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
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.
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?
@@ -25,15 +25,15 @@ The current architecture has a fundamental bottleneck documented in the [databas
```mermaid
flowchart TD
subgraph c-relay - Final Form
RELAY[c-relay binary] -->|db_ops API| DBOPS[db_ops.c - abstraction layer]
subgraph c-relay-pg - Final Form
RELAY[c-relay-pg binary] -->|db_ops API| DBOPS[db_ops.c - abstraction layer]
DBOPS -->|sqlite3 calls| SQLITE[SQLite WAL database]
end
```
```mermaid
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 -->|EVENT arrives| WQ[Write queue - single writer]
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:
- **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
+19 -19
View File
@@ -2,7 +2,7 @@
## 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
@@ -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`.
- **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):
@@ -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
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
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
@@ -505,9 +505,9 @@ With a client-server database, you unlock something fundamentally impossible wit
flowchart TD
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:8889| R2[c-relay Instance 2 - port 8889]
NGINX -->|ws://localhost:8890| R3[c-relay Instance 3 - port 8890]
NGINX -->|ws://localhost:8888| R1[c-relay-pg Instance 1 - port 8888]
NGINX -->|ws://localhost:8889| R2[c-relay-pg Instance 2 - port 8889]
NGINX -->|ws://localhost:8890| R3[c-relay-pg Instance 3 - port 8890]
NGINX -->|http://localhost:3000| DASHWEB[Dashboard Web Server]
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
# nginx.conf - WebSocket load balancing for c-relay
# nginx.conf - WebSocket load balancing for c-relay-pg
upstream relay_backends {
# ip_hash ensures a client always hits the same instance
# (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
# 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
./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
./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:
```ini
# /etc/systemd/system/c-relay@.service
# /etc/systemd/system/c-relay-pg@.service
[Unit]
Description=C-Relay Nostr Instance %i
Description=C-Relay-PG Nostr Instance %i
After=postgresql.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
User=c-relay
User=c-relay-pg
[Install]
WantedBy=multi-user.target
```
```bash
systemctl enable c-relay@8888 c-relay@8889 c-relay@8890
systemctl start 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-pg@8888 c-relay-pg@8889 c-relay-pg@8890
```
### The Subscription Broadcasting Challenge (Detailed)
@@ -741,13 +741,13 @@ for port in 8888 8889 8890; do
sleep 30
# 3. Stop old instance
systemctl stop c-relay@$port
systemctl stop c-relay-pg@$port
# 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
systemctl start c-relay@$port
systemctl start c-relay-pg@$port
# 6. Wait for health check
sleep 5
+1 -1
View File
@@ -2,7 +2,7 @@
## 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
+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
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
@@ -187,7 +187,7 @@ Add `free((char*)result)` after every `get_config_value()` call that doesn't alr
While fixes are being implemented:
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
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
// 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");
cleanup_configuration_system();
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.
* 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
#define CRELAY_VERSION_MAJOR 2
#define CRELAY_VERSION_MINOR 1
#define CRELAY_VERSION_PATCH 8
#define CRELAY_VERSION "v2.1.8"
#define CRELAY_VERSION_PATCH 9
#define CRELAY_VERSION "v2.1.9"
// 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_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 SUPPORTED_NIPS "1,2,4,9,11,12,13,15,16,20,22,33,40,42,50,70"
#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:
* - 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
#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
#ifndef WEBSOCKETS_H
+34 -34
View File
@@ -8,7 +8,7 @@ The C Nostr Relay now uses a revolutionary **zero-configuration** approach where
## Files
- **`c-relay.service`** - SystemD service unit file
- **`c-relay-pg.service`** - SystemD service unit file
- **`install-service.sh`** - Automated installation script
- **`uninstall-service.sh`** - Automated uninstall script
- **`README.md`** - This documentation
@@ -27,12 +27,12 @@ The C Nostr Relay now uses a revolutionary **zero-configuration** approach where
3. **Start the service:**
```bash
sudo systemctl start c-relay
sudo systemctl start c-relay-pg
```
4. **Check admin keys (IMPORTANT!):**
```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
@@ -61,7 +61,7 @@ On first startup, the relay will:
```bash
# 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.
@@ -72,10 +72,10 @@ The admin private key is needed to update relay configuration by sending signed
```bash
# Find the database file
ls /opt/c-relay/*.nrdb
ls /opt/c-relay-pg/*.nrdb
# 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
@@ -93,57 +93,57 @@ Send a new kind 33334 event to the relay via WebSocket:
```bash
# Start service
sudo systemctl start c-relay
sudo systemctl start c-relay-pg
# Stop service
sudo systemctl stop c-relay
sudo systemctl stop c-relay-pg
# Restart service
sudo systemctl restart c-relay
sudo systemctl restart c-relay-pg
# Enable auto-start on boot
sudo systemctl enable c-relay
sudo systemctl enable c-relay-pg
# Check status
sudo systemctl status c-relay
sudo systemctl status c-relay-pg
# View logs (live)
sudo journalctl -u c-relay -f
sudo journalctl -u c-relay-pg -f
# View recent logs
sudo journalctl -u c-relay --since="1 hour ago"
sudo journalctl -u c-relay-pg --since="1 hour ago"
```
### Log Analysis
```bash
# 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
sudo journalctl -u c-relay | grep "Admin Private Key"
sudo journalctl -u c-relay-pg | grep "Admin Private Key"
# 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
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
After installation:
- **Binary:** `/opt/c-relay/c_relay_x86`
- **Database:** `/opt/c-relay/<relay_pubkey>.nrdb` (created automatically)
- **Service File:** `/etc/systemd/system/c-relay.service`
- **User:** `c-relay` (system user created automatically)
- **Binary:** `/opt/c-relay-pg/c_relay_pg_x86`
- **Database:** `/opt/c-relay-pg/<relay_pubkey>.nrdb` (created automatically)
- **Service File:** `/etc/systemd/system/c-relay-pg.service`
- **User:** `c-relay-pg` (system user created automatically)
## Security Features
The systemd service includes security hardening:
- Runs as dedicated system user `c-relay`
- Runs as dedicated system user `c-relay-pg`
- `NoNewPrivileges=true`
- `ProtectSystem=strict`
- `ProtectHome=true`
@@ -165,7 +165,7 @@ The database file contains everything:
```bash
# Backup database file
sudo cp /opt/c-relay/*.nrdb /backup/location/
sudo cp /opt/c-relay-pg/*.nrdb /backup/location/
# The .nrdb file contains:
# - All Nostr events
@@ -177,7 +177,7 @@ sudo cp /opt/c-relay/*.nrdb /backup/location/
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`
3. Start service - it will automatically detect existing configuration
@@ -187,39 +187,39 @@ To migrate to new server:
```bash
# Check service status
sudo systemctl status c-relay
sudo systemctl status c-relay-pg
# 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
ls -la /opt/c-relay/c_relay_x86
ls -la /opt/c-relay-pg/c_relay_pg_x86
# Check permissions
sudo -u c-relay ls -la /opt/c-relay/
sudo -u c-relay-pg ls -la /opt/c-relay-pg/
```
### Database Issues
```bash
# Check if database file exists
ls -la /opt/c-relay/*.nrdb*
ls -la /opt/c-relay-pg/*.nrdb*
# Check database integrity
sqlite3 /opt/c-relay/*.nrdb "PRAGMA integrity_check;"
sqlite3 /opt/c-relay-pg/*.nrdb "PRAGMA integrity_check;"
# View database schema
sqlite3 /opt/c-relay/*.nrdb ".schema"
sqlite3 /opt/c-relay-pg/*.nrdb ".schema"
```
### Configuration Issues
```bash
# 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
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
@@ -238,7 +238,7 @@ The uninstall script will:
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
3. Ensure admin private key is saved securely
4. Check WebSocket connectivity on port 8888
+7 -7
View File
@@ -1,27 +1,27 @@
[Unit]
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
Wants=network-online.target
[Service]
Type=simple
User=c-relay
Group=c-relay
WorkingDirectory=/opt/c-relay
User=c-relay-pg
Group=c-relay-pg
WorkingDirectory=/opt/c-relay-pg
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
RestartSec=5
StandardOutput=journal
StandardError=journal
SyslogIdentifier=c-relay
SyslogIdentifier=c-relay-pg
# Security settings
NoNewPrivileges=true
ProtectSystem=strict
ProtectHome=true
ReadWritePaths=/opt/c-relay
ReadWritePaths=/opt/c-relay-pg
PrivateTmp=true
ProtectKernelTunables=true
ProtectKernelModules=true
+4 -4
View File
@@ -6,10 +6,10 @@
set -e
# Configuration
SERVICE_NAME="c-relay"
SERVICE_USER="c-relay"
INSTALL_DIR="/opt/c-relay"
BINARY_NAME="c_relay_x86"
SERVICE_NAME="c-relay-pg"
SERVICE_USER="c-relay-pg"
INSTALL_DIR="/opt/c-relay-pg"
BINARY_NAME="c_relay_pg_x86"
# Colors for output
RED='\033[0;31m'
+13 -13
View File
@@ -1,15 +1,15 @@
#!/bin/bash
# C-Relay Systemd Service Installation Script
# This script installs the C-Relay as a systemd service
# C-Relay-PG Systemd Service Installation Script
# This script installs the C-Relay-PG as a systemd service
set -e
# Configuration
INSTALL_DIR="/opt/c-relay"
SERVICE_NAME="c-relay"
SERVICE_FILE="c-relay.service"
BINARY_NAME="c_relay_x86"
INSTALL_DIR="/opt/c-relay-pg"
SERVICE_NAME="c-relay-pg"
SERVICE_FILE="c-relay-pg.service"
BINARY_NAME="c_relay_pg_x86"
# Colors for output
RED='\033[0;31m'
@@ -17,7 +17,7 @@ GREEN='\033[0;32m'
YELLOW='\033[1;33m'
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
if [[ $EUID -ne 0 ]]; then
@@ -39,12 +39,12 @@ if [ ! -f "$SERVICE_FILE" ]; then
exit 1
fi
# Create c-relay user if it doesn't exist
if ! id "c-relay" &>/dev/null; then
echo -e "${YELLOW}Creating c-relay user...${NC}"
useradd --system --shell /bin/false --home-dir $INSTALL_DIR --create-home c-relay
# Create c-relay-pg user if it doesn't exist
if ! id "c-relay-pg" &>/dev/null; then
echo -e "${YELLOW}Creating c-relay-pg user...${NC}"
useradd --system --shell /bin/false --home-dir $INSTALL_DIR --create-home c-relay-pg
else
echo -e "${GREEN}User c-relay already exists${NC}"
echo -e "${GREEN}User c-relay-pg already exists${NC}"
fi
# Create installation directory
@@ -59,7 +59,7 @@ chmod +x $INSTALL_DIR/$BINARY_NAME
# Set permissions
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
echo -e "${YELLOW}Installing systemd service...${NC}"
+3 -3
View File
@@ -6,9 +6,9 @@
set -e
# Configuration
SERVICE_NAME="c-relay"
SERVICE_USER="c-relay"
INSTALL_DIR="/opt/c-relay"
SERVICE_NAME="c-relay-pg"
SERVICE_USER="c-relay-pg"
INSTALL_DIR="/opt/c-relay-pg"
# Colors for output
RED='\033[0;31m'
+15 -15
View File
@@ -1,14 +1,14 @@
#!/bin/bash
# C-Relay Systemd Service Uninstallation Script
# This script removes the C-Relay systemd service
# C-Relay-PG Systemd Service Uninstallation Script
# This script removes the C-Relay-PG systemd service
set -e
# Configuration
INSTALL_DIR="/opt/c-relay"
SERVICE_NAME="c-relay"
SERVICE_FILE="c-relay.service"
INSTALL_DIR="/opt/c-relay-pg"
SERVICE_NAME="c-relay-pg"
SERVICE_FILE="c-relay-pg.service"
# Colors for output
RED='\033[0;31m'
@@ -16,7 +16,7 @@ GREEN='\033[0;32m'
YELLOW='\033[1;33m'
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
if [[ $EUID -ne 0 ]]; then
@@ -65,22 +65,22 @@ else
echo -e "${GREEN}Installation directory preserved${NC}"
fi
# Ask about removing c-relay user
# Ask about removing c-relay-pg user
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
if [[ "$response" =~ ^([yY][eE][sS]|[yY])$ ]]; then
echo -e "${YELLOW}Removing c-relay user...${NC}"
if id "c-relay" &>/dev/null; then
userdel c-relay
echo -e "${GREEN}User c-relay removed${NC}"
echo -e "${YELLOW}Removing c-relay-pg user...${NC}"
if id "c-relay-pg" &>/dev/null; then
userdel c-relay-pg
echo -e "${GREEN}User c-relay-pg removed${NC}"
else
echo -e "${GREEN}User c-relay was not found${NC}"
echo -e "${GREEN}User c-relay-pg was not found${NC}"
fi
else
echo -e "${GREEN}User c-relay preserved${NC}"
echo -e "${GREEN}User c-relay-pg preserved${NC}"
fi
echo
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
echo
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"
echo
exit 0
+6 -6
View File
@@ -1,6 +1,6 @@
#!/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
set -e # Exit on any error
@@ -284,7 +284,7 @@ test_subscription() {
# Main test function
run_comprehensive_test() {
print_header "C-Relay Comprehensive Test"
print_header "C-Relay-PG Comprehensive Test"
# Check dependencies
print_step "Checking dependencies..."
@@ -317,7 +317,7 @@ run_comprehensive_test() {
# Test 2: Replaceable Events (kind 0 - metadata)
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)
publish_event "$replaceable1" "replaceable" "Replaceable event #1 (metadata)"
@@ -473,20 +473,20 @@ run_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
if run_comprehensive_test; then
echo
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"
echo
exit 0
else
echo
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 " - Events are sent to clients regardless of subscription filters"
print_error " - This violates the Nostr protocol specification"
+1 -1
View File
@@ -461,7 +461,7 @@ echo
if run_count_test; then
echo
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"
echo
exit 0
+1 -1
View File
@@ -405,7 +405,7 @@ echo
if run_search_test; then
echo
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 works across event content and tag values"
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
echo
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 enabled but not authenticated"
print_info "✅ Normal events work regardless of protected events setting"
+2 -2
View File
@@ -1,6 +1,6 @@
#!/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
# Based on the pattern from 1_nip_test.sh
@@ -372,7 +372,7 @@ echo
if run_deletion_test; then
echo
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 "✅ Address-based deletion 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
@@ -194,14 +194,14 @@ brew install websocat curl jq
Download `websocat` from: https://github.com/vi/websocat/releases
### Relay Setup
Before running tests, ensure the C-Relay is running:
Before running tests, ensure the C-Relay-PG is running:
```bash
# Build and start the relay
./make_and_restart_relay.sh
# Verify it's running
ps aux | grep c_relay
ps aux | grep c_relay_pg
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"
- Ensure relay is running: `./make_and_restart_relay.sh`
- 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"
- Install websocat: `sudo apt-get install websocat`
@@ -377,7 +377,7 @@ Integrate with CI/CD pipelines:
```yaml
# Example GitHub Actions workflow
- name: Run C-Relay Tests
- name: Run C-Relay-PG Tests
run: |
./make_and_restart_relay.sh
./tests/run_all_tests.sh
+1 -1
View File
@@ -1,7 +1,7 @@
#!/bin/bash
# Authentication Testing Suite for C-Relay
# Authentication Testing Suite for C-Relay-PG
# Tests NIP-42 authentication mechanisms
set -e
+1 -1
View File
@@ -262,7 +262,7 @@ if [ -n "$DB_FILE" ]; then
fi
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 "=========================================="
+2 -2
View File
@@ -1,6 +1,6 @@
#!/bin/bash
# Configuration Testing Suite for C-Relay
# Configuration Testing Suite for C-Relay-PG
# Tests configuration management and persistence
set -e
@@ -138,7 +138,7 @@ test_nip11_info() {
}
echo "=========================================="
echo "C-Relay Configuration Testing Suite"
echo "C-Relay-PG Configuration Testing Suite"
echo "=========================================="
echo "Testing configuration management at ws://$RELAY_HOST:$RELAY_PORT"
echo ""
+2 -2
View File
@@ -1,6 +1,6 @@
#!/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
set -e
@@ -91,7 +91,7 @@ test_valid_message() {
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
+2 -2
View File
@@ -1,6 +1,6 @@
#!/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
set -e
@@ -69,7 +69,7 @@ test_input_validation() {
}
echo "=========================================="
echo "C-Relay Input Validation Test Suite"
echo "C-Relay-PG Input Validation Test Suite"
echo "=========================================="
echo "Testing against relay at ws://$RELAY_HOST:$RELAY_PORT"
echo
+2 -2
View File
@@ -1,6 +1,6 @@
#!/bin/bash
# Load Testing Suite for C-Relay
# Load Testing Suite for C-Relay-PG
# Tests high concurrent connection scenarios and performance under load
set -e
@@ -203,7 +203,7 @@ run_load_test() {
# Only run main code if script is executed directly (not sourced)
if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then
echo "=========================================="
echo "C-Relay Load Testing Suite"
echo "C-Relay-PG Load Testing Suite"
echo "=========================================="
echo "Testing against relay at ws://$RELAY_HOST:$RELAY_PORT"
echo ""
+2 -2
View File
@@ -1,6 +1,6 @@
#!/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
set -e
@@ -135,7 +135,7 @@ test_concurrent_access() {
}
echo "=========================================="
echo "C-Relay Memory Corruption Test Suite"
echo "C-Relay-PG Memory Corruption Test Suite"
echo "=========================================="
echo "Testing against relay at ws://$RELAY_HOST:$RELAY_PORT"
echo "Note: These tests may cause the relay to crash if vulnerabilities exist"
+5 -5
View File
@@ -1,6 +1,6 @@
#!/bin/bash
# Performance Benchmarking Suite for C-Relay
# Performance Benchmarking Suite for C-Relay-PG
# Measures performance metrics and throughput
set -e
@@ -202,7 +202,7 @@ benchmark_memory_usage() {
echo "=========================================="
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"
@@ -218,7 +218,7 @@ benchmark_memory_usage() {
sleep 2
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))
echo "${current_memory}KB (+${memory_increase}KB)"
@@ -232,14 +232,14 @@ benchmark_memory_usage() {
done
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"
}
# Only run main code if script is executed directly (not sourced)
if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then
echo "=========================================="
echo "C-Relay Performance Benchmarking Suite"
echo "C-Relay-PG Performance Benchmarking Suite"
echo "=========================================="
echo "Benchmarking relay at ws://$RELAY_HOST:$RELAY_PORT"
echo ""
+4 -4
View File
@@ -1,6 +1,6 @@
#!/bin/bash
# Resource Monitoring Suite for C-Relay
# Resource Monitoring Suite for C-Relay-PG
# Monitors memory and CPU usage during testing
set -e
@@ -27,7 +27,7 @@ TIMESTAMP_SAMPLES=()
# Function to get relay process info
get_relay_info() {
local pid
pid=$(pgrep -f "c_relay" | head -1)
pid=$(pgrep -f "c_relay_pg" | head -1)
if [[ -z "$pid" ]]; then
echo "0:0:0:0"
@@ -232,13 +232,13 @@ run_monitored_load_test() {
}
echo "=========================================="
echo "C-Relay Resource Monitoring Suite"
echo "C-Relay-PG Resource Monitoring Suite"
echo "=========================================="
echo "Monitoring relay at ws://$RELAY_HOST:$RELAY_PORT"
echo ""
# 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 "Use: ./make_and_restart_relay.sh"
exit 1
+4 -4
View File
@@ -1,6 +1,6 @@
#!/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
set -e
@@ -132,7 +132,7 @@ generate_html_report() {
<head>
<meta charset="UTF-8">
<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>
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; }
@@ -152,7 +152,7 @@ generate_html_report() {
</head>
<body>
<div class="header">
<h1>C-Relay Comprehensive Test Report</h1>
<h1>C-Relay-PG Comprehensive Test Report</h1>
<p>Generated on: $(date)</p>
<p>Test Environment: $RELAY_URL</p>
</div>
@@ -211,7 +211,7 @@ EOF
# Main execution
log "=========================================="
log "C-Relay Comprehensive Test Suite Runner"
log "C-Relay-PG Comprehensive Test Suite Runner"
log "=========================================="
log "Relay URL: $RELAY_URL"
log "Log file: $LOG_FILE"
+2 -2
View File
@@ -1,6 +1,6 @@
#!/bin/bash
# NIP Protocol Test Runner for C-Relay
# NIP Protocol Test Runner for C-Relay-PG
# Runs all NIP compliance tests
set -e
@@ -84,7 +84,7 @@ check_relay() {
}
echo "=========================================="
echo "C-Relay NIP Protocol Test Suite"
echo "C-Relay-PG NIP Protocol Test Suite"
echo "=========================================="
echo "Testing NIP compliance against relay at ws://$RELAY_HOST:$RELAY_PORT"
echo ""
+2 -2
View File
@@ -1,6 +1,6 @@
#!/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
set -e
@@ -93,7 +93,7 @@ test_valid_query() {
}
echo "=========================================="
echo "C-Relay SQL Injection Test Suite"
echo "C-Relay-PG SQL Injection Test Suite"
echo "=========================================="
echo "Testing against relay at ws://$RELAY_HOST:$RELAY_PORT"
echo
+1 -1
View File
@@ -380,7 +380,7 @@ test_empty_result() {
}
echo "=========================================="
echo "C-Relay SQL Query Admin API Testing Suite"
echo "C-Relay-PG SQL Query Admin API Testing Suite"
echo "=========================================="
echo "Testing SQL query functionality at $RELAY_URL"
echo ""
+1 -1
View File
@@ -2,7 +2,7 @@
# Persistent Subscription Test Script
# 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
+1 -1
View File
@@ -1,6 +1,6 @@
#!/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
set -e
+5 -5
View File
@@ -1,6 +1,6 @@
#!/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
# - Optionally runs perf record in parallel for callgraph data
# - 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}"
LOCAL_CSV="${RUN_DIR}/thread_samples.csv"
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
mkdir -p "${RUN_DIR}"
echo "=========================================="
echo "C-Relay Thread CPU Profiler"
echo "C-Relay-PG Thread CPU Profiler"
echo "=========================================="
echo "Remote host : ${REMOTE_HOST}"
echo "Duration : ${DURATION}s"
@@ -43,9 +43,9 @@ CSV_FILE="\${REMOTE_DIR}/thread_samples.csv"
PERF_FILE="\${REMOTE_DIR}/perf.data"
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
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
fi
+2 -2
View File
@@ -1,6 +1,6 @@
#!/bin/bash
# C-Relay Whitelist/Blacklist Test Script
# C-Relay-PG Whitelist/Blacklist Test Script
# Tests the relay's authentication functionality using nak
set -e # Exit on any error
@@ -362,7 +362,7 @@ test_whitelist_functionality() {
# Main test function
main() {
log_info "Starting C-Relay Whitelist/Blacklist Test"
log_info "Starting C-Relay-PG Whitelist/Blacklist Test"
log_info "=========================================="
# Check prerequisites