Files
c-relay/db/README.md
2025-09-03 20:39:06 -04:00

6.2 KiB

C Nostr Relay Database

This directory contains the SQLite database schema and initialization scripts for the C Nostr Relay implementation.

Files

  • schema.sql - Complete database schema based on nostr-rs-relay v18
  • init.sh - Database initialization script
  • c_nostr_relay.db - SQLite database file (created after running init.sh)

Quick Start

  1. Initialize the database:

    cd db
    ./init.sh
    
  2. Force reinitialize (removes existing database):

    ./init.sh --force
    
  3. Initialize with optimization and info:

    ./init.sh --info --optimize
    

Database Schema

The schema is fully compatible with the Nostr protocol and includes:

Core Tables

  • event - Main event storage with all Nostr event data
  • tag - Denormalized tag index for efficient queries
  • user_verification - NIP-05 verification tracking
  • account - User account management (optional)
  • invoice - Lightning payment tracking (optional)

Key Features

  • NIP-01 compliant - Full basic protocol support
  • Replaceable events - Supports kinds 0, 3, 10000-19999
  • Parameterized replaceable - Supports kinds 30000-39999 with d tags
  • Event deletion - NIP-09 soft deletion with hidden column
  • Event expiration - NIP-40 automatic cleanup
  • Authentication - NIP-42 client authentication
  • NIP-05 verification - Domain-based identity verification
  • Performance optimized - Comprehensive indexing strategy

Schema Version

Current version: v18 (compatible with nostr-rs-relay v18)

Database Structure

Event Storage

CREATE TABLE event (
    id INTEGER PRIMARY KEY,
    event_hash BLOB NOT NULL,        -- 32-byte SHA256 hash
    first_seen INTEGER NOT NULL,     -- relay receive timestamp
    created_at INTEGER NOT NULL,     -- event creation timestamp
    expires_at INTEGER,              -- NIP-40 expiration
    author BLOB NOT NULL,            -- 32-byte pubkey
    delegated_by BLOB,               -- NIP-26 delegator
    kind INTEGER NOT NULL,           -- event kind
    hidden INTEGER DEFAULT FALSE,   -- soft deletion flag
    content TEXT NOT NULL            -- complete JSON event
);

Tag Indexing

CREATE TABLE tag (
    id INTEGER PRIMARY KEY,
    event_id INTEGER NOT NULL,
    name TEXT,                       -- tag name ("e", "p", etc.)
    value TEXT,                      -- tag value
    created_at INTEGER NOT NULL,     -- denormalized for performance
    kind INTEGER NOT NULL            -- denormalized for performance
);

Performance Features

Optimized Indexes

  • Hash-based lookups - event_hash_index for O(1) event retrieval
  • Author queries - author_index, author_created_at_index
  • Kind filtering - kind_index, kind_created_at_index
  • Tag searching - tag_covering_index for efficient tag queries
  • Composite queries - Multi-column indexes for complex filters

Query Optimization

  • Denormalized tags - Includes kind and created_at in tag table
  • Binary storage - BLOBs for hex data (pubkeys, hashes)
  • WAL mode - Write-Ahead Logging for concurrent access
  • Automatic cleanup - Triggers for data integrity

Usage Examples

Basic Operations

  1. Insert an event:

    INSERT INTO event (event_hash, first_seen, created_at, author, kind, content)
    VALUES (?, ?, ?, ?, ?, ?);
    
  2. Query by author:

    SELECT content FROM event 
    WHERE author = ? AND hidden != TRUE
    ORDER BY created_at DESC;
    
  3. Filter by tags:

    SELECT e.content FROM event e
    JOIN tag t ON e.id = t.event_id
    WHERE t.name = 'p' AND t.value = ? AND e.hidden != TRUE;
    

Advanced Queries

  1. Get replaceable event (latest only):

    SELECT content FROM event
    WHERE author = ? AND kind = ? AND hidden != TRUE
    ORDER BY created_at DESC LIMIT 1;
    
  2. Tag-based filtering (NIP-01 filters):

    SELECT e.content FROM event e
    WHERE e.id IN (
      SELECT t.event_id FROM tag t
      WHERE t.name = ? AND t.value IN (?, ?, ?)
    ) AND e.hidden != TRUE;
    

Maintenance

Regular Operations

  1. Check database integrity:

    sqlite3 c_nostr_relay.db "PRAGMA integrity_check;"
    
  2. Optimize database:

    sqlite3 c_nostr_relay.db "PRAGMA optimize; VACUUM; ANALYZE;"
    
  3. Clean expired events:

    DELETE FROM event WHERE expires_at <= strftime('%s', 'now');
    

Monitoring

  1. Database size:

    ls -lh c_nostr_relay.db
    
  2. Table statistics:

    SELECT name, COUNT(*) as count FROM (
      SELECT 'events' as name FROM event UNION ALL
      SELECT 'tags' as name FROM tag UNION ALL
      SELECT 'verifications' as name FROM user_verification
    ) GROUP BY name;
    

Migration Support

The schema includes a migration system for future updates:

CREATE TABLE schema_info (
    version INTEGER PRIMARY KEY,
    applied_at INTEGER NOT NULL,
    description TEXT
);

Security Considerations

  1. Input validation - Always validate event JSON and signatures
  2. Rate limiting - Implement at application level
  3. Access control - Use account table for permissions
  4. Backup strategy - Regular database backups recommended

Compatibility

  • SQLite version - Requires SQLite 3.8.0+
  • nostr-rs-relay - Schema compatible with v18
  • NIPs supported - 01, 02, 05, 09, 10, 11, 26, 40, 42
  • C libraries - Compatible with sqlite3 C API

Troubleshooting

Common Issues

  1. Database locked error:

    • Ensure proper connection closing in your C code
    • Check for long-running transactions
  2. Performance issues:

    • Run PRAGMA optimize; regularly
    • Consider VACUUM if database grew significantly
  3. Schema errors:

    • Verify SQLite version compatibility
    • Check foreign key constraints

Getting Help

  • Check the main project README for C implementation details
  • Review nostr-rs-relay documentation for reference implementation
  • Consult Nostr NIPs for protocol specifications

License

This database schema is part of the C Nostr Relay project and follows the same license terms.