v0.7.12 - Implemented comprehensive debug system with 6 levels (0-5), file:line tracking at TRACE level, deployment script integration, and default level 5 for development

This commit is contained in:
Your Name
2025-10-13 12:44:18 -04:00
parent 49ffc3d99e
commit e3938a2c85
23 changed files with 2163 additions and 622 deletions

View File

@@ -24,6 +24,7 @@
#include "sql_schema.h" // Embedded database schema
#include "websockets.h" // WebSocket protocol implementation
#include "subscriptions.h" // Subscription management system
#include "debug.h" // Debug system
// Forward declarations for unified request validator
int nostr_validate_unified_request(const char* json_string, size_t json_length);
@@ -95,11 +96,7 @@ extern subscription_manager_t g_subscription_manager;
// Forward declarations for logging functions
void log_info(const char* message);
void log_success(const char* message);
void log_error(const char* message);
void log_warning(const char* message);
// Forward declarations for logging functions - REMOVED (replaced by debug system)
// Forward declaration for subscription manager configuration
void update_subscription_manager_config(void);
@@ -189,41 +186,7 @@ int validate_event_expiration(cJSON* event, char* error_message, size_t error_si
/////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////
// Helper function to get current timestamp string
static void get_timestamp_string(char* buffer, size_t buffer_size) {
time_t now = time(NULL);
struct tm* local_time = localtime(&now);
strftime(buffer, buffer_size, "%Y-%m-%d %H:%M:%S", local_time);
}
// Logging functions
void log_info(const char* message) {
char timestamp[32];
get_timestamp_string(timestamp, sizeof(timestamp));
printf("[%s] [INFO] %s\n", timestamp, message);
fflush(stdout);
}
void log_success(const char* message) {
char timestamp[32];
get_timestamp_string(timestamp, sizeof(timestamp));
printf("[%s] [SUCCESS] %s\n", timestamp, message);
fflush(stdout);
}
void log_error(const char* message) {
char timestamp[32];
get_timestamp_string(timestamp, sizeof(timestamp));
printf("[%s] [ERROR] %s\n", timestamp, message);
fflush(stdout);
}
void log_warning(const char* message) {
char timestamp[32];
get_timestamp_string(timestamp, sizeof(timestamp));
printf("[%s] [WARNING] %s\n", timestamp, message);
fflush(stdout);
}
// Logging functions - REMOVED (replaced by debug system in debug.c)
// Update subscription manager configuration from config system
void update_subscription_manager_config(void) {
@@ -300,27 +263,27 @@ static void cleanup_stale_wal_files(const char* db_path) {
int has_shm = (access(shm_path, F_OK) == 0);
if (has_wal || has_shm) {
log_warning("Detected stale SQLite WAL files from previous unclean shutdown");
DEBUG_WARN("Detected stale SQLite WAL files from previous unclean shutdown");
// Try to remove WAL file
if (has_wal) {
if (unlink(wal_path) == 0) {
log_info("Removed stale WAL file");
DEBUG_INFO("Removed stale WAL file");
} else {
char error_msg[256];
snprintf(error_msg, sizeof(error_msg), "Failed to remove WAL file: %s", strerror(errno));
log_warning(error_msg);
DEBUG_WARN(error_msg);
}
}
// Try to remove SHM file
if (has_shm) {
if (unlink(shm_path) == 0) {
log_info("Removed stale SHM file");
DEBUG_INFO("Removed stale SHM file");
} else {
char error_msg[256];
snprintf(error_msg, sizeof(error_msg), "Failed to remove SHM file: %s", strerror(errno));
log_warning(error_msg);
DEBUG_WARN(error_msg);
}
}
}
@@ -328,25 +291,30 @@ static void cleanup_stale_wal_files(const char* db_path) {
// Initialize database connection and schema
int init_database(const char* database_path_override) {
DEBUG_TRACE("Entering init_database()");
// Priority 1: Command line database path override
const char* db_path = database_path_override;
// Priority 2: Configuration system (if available)
if (!db_path) {
db_path = get_config_value("database_path");
}
// Priority 3: Default path
if (!db_path) {
db_path = DEFAULT_DATABASE_PATH;
}
DEBUG_LOG("Initializing database: %s", db_path);
// Clean up stale WAL files before opening database
cleanup_stale_wal_files(db_path);
int rc = sqlite3_open(db_path, &g_db);
if (rc != SQLITE_OK) {
log_error("Cannot open database");
DEBUG_ERROR("Cannot open database");
DEBUG_TRACE("Exiting init_database() - failed to open database");
return -1;
}
@@ -379,7 +347,7 @@ int init_database(const char* database_path_override) {
} else {
char warning_msg[256];
snprintf(warning_msg, sizeof(warning_msg), "Unknown database schema version: %s", db_version);
log_warning(warning_msg);
DEBUG_WARN(warning_msg);
}
} else {
needs_migration = 1;
@@ -422,7 +390,7 @@ int init_database(const char* database_path_override) {
char error_log[512];
snprintf(error_log, sizeof(error_log), "Failed to create auth_rules table: %s",
error_msg ? error_msg : "unknown error");
log_error(error_log);
DEBUG_ERROR(error_log);
if (error_msg) sqlite3_free(error_msg);
return -1;
}
@@ -439,7 +407,7 @@ int init_database(const char* database_path_override) {
char index_error_log[512];
snprintf(index_error_log, sizeof(index_error_log), "Failed to create auth_rules indexes: %s",
index_error_msg ? index_error_msg : "unknown error");
log_error(index_error_log);
DEBUG_ERROR(index_error_log);
if (index_error_msg) sqlite3_free(index_error_msg);
return -1;
}
@@ -458,7 +426,7 @@ int init_database(const char* database_path_override) {
char error_log[512];
snprintf(error_log, sizeof(error_log), "Failed to update schema version: %s",
error_msg ? error_msg : "unknown error");
log_error(error_log);
DEBUG_ERROR(error_log);
if (error_msg) sqlite3_free(error_msg);
return -1;
}
@@ -474,7 +442,7 @@ int init_database(const char* database_path_override) {
char error_log[512];
snprintf(error_log, sizeof(error_log), "Failed to initialize database schema: %s",
error_msg ? error_msg : "unknown error");
log_error(error_log);
DEBUG_ERROR(error_log);
if (error_msg) {
sqlite3_free(error_msg);
}
@@ -483,7 +451,7 @@ int init_database(const char* database_path_override) {
}
} else {
log_error("Failed to check existing database schema");
DEBUG_ERROR("Failed to check existing database schema");
return -1;
}
@@ -493,36 +461,41 @@ int init_database(const char* database_path_override) {
if (rc != SQLITE_OK) {
char error_msg[256];
snprintf(error_msg, sizeof(error_msg), "Failed to enable WAL mode: %s",
wal_error ? wal_error : "unknown error");
log_warning(error_msg);
wal_error ? wal_error : "unknown error");
DEBUG_WARN(error_msg);
if (wal_error) sqlite3_free(wal_error);
// Continue anyway - WAL mode is optional
} else {
log_info("SQLite WAL mode enabled");
DEBUG_LOG("SQLite WAL mode enabled");
}
DEBUG_TRACE("Exiting init_database() - success");
return 0;
}
// Close database connection with proper WAL checkpoint
void close_database() {
DEBUG_TRACE("Entering close_database()");
if (g_db) {
// Perform WAL checkpoint to minimize stale files on next startup
log_info("Performing WAL checkpoint before database close");
DEBUG_LOG("Performing WAL checkpoint before database close");
char* checkpoint_error = NULL;
int rc = sqlite3_exec(g_db, "PRAGMA wal_checkpoint(TRUNCATE);", NULL, NULL, &checkpoint_error);
if (rc != SQLITE_OK) {
char error_msg[256];
snprintf(error_msg, sizeof(error_msg), "WAL checkpoint warning: %s",
checkpoint_error ? checkpoint_error : "unknown error");
log_warning(error_msg);
checkpoint_error ? checkpoint_error : "unknown error");
DEBUG_WARN(error_msg);
if (checkpoint_error) sqlite3_free(checkpoint_error);
}
sqlite3_close(g_db);
g_db = NULL;
log_info("Database connection closed");
DEBUG_LOG("Database connection closed");
}
DEBUG_TRACE("Exiting close_database()");
}
// Event type classification
@@ -691,7 +664,7 @@ int store_event(cJSON* event) {
cJSON* tags = cJSON_GetObjectItem(event, "tags");
if (!id || !pubkey || !created_at || !kind || !content || !sig) {
log_error("Invalid event - missing required fields");
DEBUG_ERROR("Invalid event - missing required fields");
return -1;
}
@@ -707,7 +680,7 @@ int store_event(cJSON* event) {
}
if (!tags_json) {
log_error("Failed to serialize tags to JSON");
DEBUG_ERROR("Failed to serialize tags to JSON");
return -1;
}
@@ -719,7 +692,7 @@ int store_event(cJSON* event) {
sqlite3_stmt* stmt;
int rc = sqlite3_prepare_v2(g_db, sql, -1, &stmt, NULL);
if (rc != SQLITE_OK) {
log_error("Failed to prepare event insert statement");
DEBUG_ERROR("Failed to prepare event insert statement");
free(tags_json);
return -1;
}
@@ -740,13 +713,13 @@ int store_event(cJSON* event) {
if (rc != SQLITE_DONE) {
if (rc == SQLITE_CONSTRAINT) {
log_warning("Event already exists in database");
DEBUG_WARN("Event already exists in database");
free(tags_json);
return 0; // Not an error, just duplicate
}
char error_msg[256];
snprintf(error_msg, sizeof(error_msg), "Failed to insert event: %s", sqlite3_errmsg(g_db));
log_error(error_msg);
DEBUG_ERROR(error_msg);
free(tags_json);
return -1;
}
@@ -815,7 +788,7 @@ cJSON* retrieve_event(const char* event_id) {
int handle_req_message(const char* sub_id, cJSON* filters, struct lws *wsi, struct per_session_data *pss) {
if (!cJSON_IsArray(filters)) {
log_error("REQ filters is not an array");
DEBUG_ERROR("REQ filters is not an array");
return 0;
}
@@ -859,7 +832,7 @@ int handle_req_message(const char* sub_id, cJSON* filters, struct lws *wsi, stru
// Check session subscription limits
if (pss->subscription_count >= g_subscription_manager.max_subscriptions_per_client) {
log_error("Maximum subscriptions per client exceeded");
DEBUG_ERROR("Maximum subscriptions per client exceeded");
// Update rate limiting counters for failed attempt
pss->failed_subscription_attempts++;
@@ -953,13 +926,13 @@ int handle_req_message(const char* sub_id, cJSON* filters, struct lws *wsi, stru
// Create persistent subscription
subscription_t* subscription = create_subscription(sub_id, wsi, filters, pss ? pss->client_ip : "unknown");
if (!subscription) {
log_error("Failed to create subscription");
DEBUG_ERROR("Failed to create subscription");
return has_config_request ? config_events_sent : 0;
}
// Add to global manager
if (add_subscription_to_manager(subscription) != 0) {
log_error("Failed to add subscription to global manager");
DEBUG_ERROR("Failed to add subscription to global manager");
free_subscription(subscription);
// Send CLOSED notice
@@ -1007,7 +980,7 @@ int handle_req_message(const char* sub_id, cJSON* filters, struct lws *wsi, stru
for (int i = 0; i < cJSON_GetArraySize(filters); i++) {
cJSON* filter = cJSON_GetArrayItem(filters, i);
if (!filter || !cJSON_IsObject(filter)) {
log_warning("Invalid filter object");
DEBUG_WARN("Invalid filter object");
continue;
}
@@ -1250,7 +1223,7 @@ int handle_req_message(const char* sub_id, cJSON* filters, struct lws *wsi, stru
if (rc != SQLITE_OK) {
char error_msg[256];
snprintf(error_msg, sizeof(error_msg), "Failed to prepare subscription query: %s", sqlite3_errmsg(g_db));
log_error(error_msg);
DEBUG_ERROR(error_msg);
continue;
}
@@ -1395,7 +1368,7 @@ int is_authorized_admin_event(cJSON* event, char* error_buffer, size_t error_buf
// Step 3: Verify admin signature authorization
cJSON *pubkey_json = cJSON_GetObjectItem(event, "pubkey");
if (!pubkey_json || !cJSON_IsString(pubkey_json)) {
log_warning("Unauthorized admin event attempt: missing or invalid pubkey");
DEBUG_WARN("Unauthorized admin event attempt: missing or invalid pubkey");
snprintf(error_buffer, error_buffer_size, "Unauthorized admin event attempt: missing pubkey");
return -1;
}
@@ -1403,19 +1376,19 @@ int is_authorized_admin_event(cJSON* event, char* error_buffer, size_t error_buf
// Get admin pubkey from configuration
const char* admin_pubkey = get_config_value("admin_pubkey");
if (!admin_pubkey || strlen(admin_pubkey) == 0) {
log_warning("Unauthorized admin event attempt: no admin pubkey configured");
DEBUG_WARN("Unauthorized admin event attempt: no admin pubkey configured");
snprintf(error_buffer, error_buffer_size, "Unauthorized admin event attempt: no admin configured");
return -1;
}
// Compare pubkeys
if (strcmp(pubkey_json->valuestring, admin_pubkey) != 0) {
log_warning("Unauthorized admin event attempt: pubkey mismatch");
DEBUG_WARN("Unauthorized admin event attempt: pubkey mismatch");
char warning_msg[256];
snprintf(warning_msg, sizeof(warning_msg),
"Unauthorized admin event attempt from pubkey: %.32s...", pubkey_json->valuestring);
log_warning(warning_msg);
log_info("DEBUG: Pubkey comparison failed - event pubkey != admin pubkey");
DEBUG_WARN(warning_msg);
DEBUG_INFO("DEBUG: Pubkey comparison failed - event pubkey != admin pubkey");
snprintf(error_buffer, error_buffer_size, "Unauthorized admin event attempt: invalid admin pubkey");
return -1;
}
@@ -1423,7 +1396,7 @@ int is_authorized_admin_event(cJSON* event, char* error_buffer, size_t error_buf
// Step 4: Verify event signature
if (nostr_verify_event_signature(event) != 0) {
log_warning("Unauthorized admin event attempt: invalid signature");
DEBUG_WARN("Unauthorized admin event attempt: invalid signature");
snprintf(error_buffer, error_buffer_size, "Unauthorized admin event attempt: signature verification failed");
return -1;
}
@@ -1455,6 +1428,8 @@ void print_usage(const char* program_name) {
printf(" --strict-port Fail if exact port is unavailable (no port increment)\n");
printf(" -a, --admin-pubkey KEY Override admin public key (64-char hex or npub)\n");
printf(" -r, --relay-privkey KEY Override relay private key (64-char hex or nsec)\n");
printf(" --debug-level=N Set debug output level (0-5, default: 0)\n");
printf(" 0=none, 1=errors, 2=warnings, 3=info, 4=debug, 5=trace\n");
printf("\n");
printf("Configuration:\n");
printf(" This relay uses event-based configuration stored in the database.\n");
@@ -1492,7 +1467,8 @@ int main(int argc, char* argv[]) {
.port_override = -1, // -1 = not set
.admin_pubkey_override = {0}, // Empty string = not set
.relay_privkey_override = {0}, // Empty string = not set
.strict_port = 0 // 0 = allow port increment (default)
.strict_port = 0, // 0 = allow port increment (default)
.debug_level = 0 // 0 = no debug output (default)
};
// Parse command line arguments
@@ -1506,7 +1482,7 @@ int main(int argc, char* argv[]) {
} else if (strcmp(argv[i], "-p") == 0 || strcmp(argv[i], "--port") == 0) {
// Port override option
if (i + 1 >= argc) {
log_error("Port option requires a value. Use --help for usage information.");
DEBUG_ERROR("Port option requires a value. Use --help for usage information.");
print_usage(argv[0]);
return 1;
}
@@ -1516,7 +1492,7 @@ int main(int argc, char* argv[]) {
long port = strtol(argv[i + 1], &endptr, 10);
if (endptr == argv[i + 1] || *endptr != '\0' || port < 1 || port > 65535) {
log_error("Invalid port number. Port must be between 1 and 65535.");
DEBUG_ERROR("Invalid port number. Port must be between 1 and 65535.");
print_usage(argv[0]);
return 1;
}
@@ -1529,7 +1505,7 @@ int main(int argc, char* argv[]) {
} else if (strcmp(argv[i], "-a") == 0 || strcmp(argv[i], "--admin-pubkey") == 0) {
// Admin public key override option
if (i + 1 >= argc) {
log_error("Admin pubkey option requires a value. Use --help for usage information.");
DEBUG_ERROR("Admin pubkey option requires a value. Use --help for usage information.");
print_usage(argv[0]);
return 1;
}
@@ -1547,7 +1523,7 @@ int main(int argc, char* argv[]) {
hex_ptr += 2;
}
} else {
log_error("Invalid admin public key format. Must be 64 hex characters or valid npub format.");
DEBUG_ERROR("Invalid admin public key format. Must be 64 hex characters or valid npub format.");
print_usage(argv[0]);
return 1;
}
@@ -1559,7 +1535,7 @@ int main(int argc, char* argv[]) {
} else if (strcmp(argv[i], "-r") == 0 || strcmp(argv[i], "--relay-privkey") == 0) {
// Relay private key override option
if (i + 1 >= argc) {
log_error("Relay privkey option requires a value. Use --help for usage information.");
DEBUG_ERROR("Relay privkey option requires a value. Use --help for usage information.");
print_usage(argv[0]);
return 1;
}
@@ -1577,7 +1553,7 @@ int main(int argc, char* argv[]) {
hex_ptr += 2;
}
} else {
log_error("Invalid relay private key format. Must be 64 hex characters or valid nsec format.");
DEBUG_ERROR("Invalid relay private key format. Must be 64 hex characters or valid nsec format.");
print_usage(argv[0]);
return 1;
}
@@ -1589,13 +1565,28 @@ int main(int argc, char* argv[]) {
} else if (strcmp(argv[i], "--strict-port") == 0) {
// Strict port mode option
cli_options.strict_port = 1;
} else if (strncmp(argv[i], "--debug-level=", 14) == 0) {
// Debug level option
char* endptr;
int debug_level = (int)strtol(argv[i] + 14, &endptr, 10);
if (endptr == argv[i] + 14 || *endptr != '\0' || debug_level < 0 || debug_level > 5) {
DEBUG_ERROR("Invalid debug level. Debug level must be between 0 and 5.");
print_usage(argv[0]);
return 1;
}
cli_options.debug_level = debug_level;
} else {
log_error("Unknown argument. Use --help for usage information.");
DEBUG_ERROR("Unknown argument. Use --help for usage information.");
print_usage(argv[0]);
return 1;
}
}
// Initialize debug system
debug_init(cli_options.debug_level);
// Set up signal handlers
signal(SIGINT, signal_handler);
signal(SIGTERM, signal_handler);
@@ -1603,49 +1594,56 @@ int main(int argc, char* argv[]) {
printf(BLUE BOLD "=== C Nostr Relay Server ===" RESET "\n");
DEBUG_TRACE("Starting main initialization sequence");
// Initialize nostr library FIRST (required for key generation and event creation)
if (nostr_init() != 0) {
log_error("Failed to initialize nostr library");
DEBUG_ERROR("Failed to initialize nostr library");
return 1;
}
DEBUG_LOG("Nostr library initialized");
// Check if this is first-time startup or existing relay
if (is_first_time_startup()) {
DEBUG_LOG("First-time startup detected");
// Initialize event-based configuration system
if (init_configuration_system(NULL, NULL) != 0) {
log_error("Failed to initialize event-based configuration system");
DEBUG_ERROR("Failed to initialize event-based configuration system");
nostr_cleanup();
return 1;
}
// Run first-time startup sequence (generates keys, sets up database path, but doesn't store private key yet)
if (first_time_startup_sequence(&cli_options) != 0) {
log_error("Failed to complete first-time startup sequence");
DEBUG_ERROR("Failed to complete first-time startup sequence");
cleanup_configuration_system();
nostr_cleanup();
return 1;
}
// Initialize database with the generated relay pubkey
DEBUG_TRACE("Initializing database for first-time startup");
if (init_database(g_database_path) != 0) {
log_error("Failed to initialize database after first-time setup");
DEBUG_ERROR("Failed to initialize database after first-time setup");
cleanup_configuration_system();
nostr_cleanup();
return 1;
}
DEBUG_LOG("Database initialized for first-time startup");
// Now that database is available, store the relay private key securely
const char* relay_privkey = get_temp_relay_private_key();
if (relay_privkey) {
if (store_relay_private_key(relay_privkey) != 0) {
log_error("Failed to store relay private key securely after database initialization");
DEBUG_ERROR("Failed to store relay private key securely after database initialization");
cleanup_configuration_system();
nostr_cleanup();
return 1;
}
} else {
log_error("Relay private key not available from first-time startup");
DEBUG_ERROR("Relay private key not available from first-time startup");
cleanup_configuration_system();
nostr_cleanup();
return 1;
@@ -1656,7 +1654,7 @@ int main(int argc, char* argv[]) {
// Populate default config values in table
if (populate_default_config_values() != 0) {
log_error("Failed to populate default config values");
DEBUG_ERROR("Failed to populate default config values");
cleanup_configuration_system();
nostr_cleanup();
close_database();
@@ -1668,7 +1666,7 @@ int main(int argc, char* argv[]) {
char port_str[16];
snprintf(port_str, sizeof(port_str), "%d", cli_options.port_override);
if (update_config_in_table("relay_port", port_str) != 0) {
log_error("Failed to update relay port override in config table");
DEBUG_ERROR("Failed to update relay port override in config table");
cleanup_configuration_system();
nostr_cleanup();
close_database();
@@ -1679,7 +1677,7 @@ int main(int argc, char* argv[]) {
// Add pubkeys to config table (single authoritative call)
if (add_pubkeys_to_config_table() != 0) {
log_error("Failed to add pubkeys to config table");
DEBUG_ERROR("Failed to add pubkeys to config table");
cleanup_configuration_system();
nostr_cleanup();
close_database();
@@ -1689,7 +1687,7 @@ int main(int argc, char* argv[]) {
// Find existing database file
char** existing_files = find_existing_db_files();
if (!existing_files || !existing_files[0]) {
log_error("No existing relay database found");
DEBUG_ERROR("No existing relay database found");
nostr_cleanup();
return 1;
}
@@ -1697,7 +1695,7 @@ int main(int argc, char* argv[]) {
// Extract relay pubkey from filename
char* relay_pubkey = extract_pubkey_from_filename(existing_files[0]);
if (!relay_pubkey) {
log_error("Failed to extract relay pubkey from database filename");
DEBUG_ERROR("Failed to extract relay pubkey from database filename");
// Free the files array
for (int i = 0; existing_files[i]; i++) {
free(existing_files[i]);
@@ -1709,7 +1707,7 @@ int main(int argc, char* argv[]) {
// Initialize event-based configuration system
if (init_configuration_system(NULL, NULL) != 0) {
log_error("Failed to initialize event-based configuration system");
DEBUG_ERROR("Failed to initialize event-based configuration system");
free(relay_pubkey);
for (int i = 0; existing_files[i]; i++) {
free(existing_files[i]);
@@ -1721,7 +1719,7 @@ int main(int argc, char* argv[]) {
// Setup existing relay (sets database path and loads config)
if (startup_existing_relay(relay_pubkey) != 0) {
log_error("Failed to setup existing relay");
DEBUG_ERROR("Failed to setup existing relay");
cleanup_configuration_system();
free(relay_pubkey);
for (int i = 0; existing_files[i]; i++) {
@@ -1739,7 +1737,8 @@ int main(int argc, char* argv[]) {
sqlite3_stmt* stmt;
if (sqlite3_prepare_v2(temp_db, "SELECT COUNT(*) FROM config", -1, &stmt, NULL) == SQLITE_OK) {
if (sqlite3_step(stmt) == SQLITE_ROW) {
// Row count check completed
int row_count = sqlite3_column_int(stmt, 0);
printf(" Config table row count before database initialization: %d\n", row_count);
}
sqlite3_finalize(stmt);
}
@@ -1748,8 +1747,9 @@ int main(int argc, char* argv[]) {
}
// Initialize database with existing database path
DEBUG_TRACE("Initializing existing database");
if (init_database(g_database_path) != 0) {
log_error("Failed to initialize existing database");
DEBUG_ERROR("Failed to initialize existing database");
cleanup_configuration_system();
free(relay_pubkey);
for (int i = 0; existing_files[i]; i++) {
@@ -1759,13 +1759,15 @@ int main(int argc, char* argv[]) {
nostr_cleanup();
return 1;
}
DEBUG_LOG("Existing database initialized");
// Check config table row count after database initialization
{
sqlite3_stmt* stmt;
if (sqlite3_prepare_v2(g_db, "SELECT COUNT(*) FROM config", -1, &stmt, NULL) == SQLITE_OK) {
if (sqlite3_step(stmt) == SQLITE_ROW) {
// Row count check completed
int row_count = sqlite3_column_int(stmt, 0);
printf(" Config table row count after database initialization: %d\n", row_count);
}
sqlite3_finalize(stmt);
}
@@ -1775,14 +1777,14 @@ int main(int argc, char* argv[]) {
// This must be done AFTER database initialization
// COMMENTED OUT: Don't modify existing database config on restart
// if (populate_default_config_values() != 0) {
// log_warning("Failed to populate default config values for existing relay - continuing");
// DEBUG_WARN("Failed to populate default config values for existing relay - continuing");
// }
// Load configuration from database
cJSON* config_event = load_config_event_from_database(relay_pubkey);
if (config_event) {
if (apply_configuration_from_event(config_event) != 0) {
log_warning("Failed to apply configuration from database");
DEBUG_WARN("Failed to apply configuration from database");
}
cJSON_Delete(config_event);
} else {
@@ -1799,14 +1801,14 @@ int main(int argc, char* argv[]) {
// Check if admin_pubkey is missing or invalid
if (!admin_pubkey_from_table || strlen(admin_pubkey_from_table) != 64) {
log_warning("Admin pubkey missing or invalid in config table - will regenerate from cache");
DEBUG_WARN("Admin pubkey missing or invalid in config table - will regenerate from cache");
need_to_add_pubkeys = 1;
}
if (admin_pubkey_from_table) free((char*)admin_pubkey_from_table);
// Check if relay_pubkey is missing or invalid
if (!relay_pubkey_from_table || strlen(relay_pubkey_from_table) != 64) {
log_warning("Relay pubkey missing or invalid in config table - will regenerate from cache");
DEBUG_WARN("Relay pubkey missing or invalid in config table - will regenerate from cache");
need_to_add_pubkeys = 1;
}
if (relay_pubkey_from_table) free((char*)relay_pubkey_from_table);
@@ -1814,7 +1816,7 @@ int main(int argc, char* argv[]) {
// If either pubkey is missing, call add_pubkeys_to_config_table to populate both
if (need_to_add_pubkeys) {
if (add_pubkeys_to_config_table() != 0) {
log_error("Failed to add pubkeys to config table for existing relay");
DEBUG_ERROR("Failed to add pubkeys to config table for existing relay");
cleanup_configuration_system();
nostr_cleanup();
close_database();
@@ -1827,7 +1829,7 @@ int main(int argc, char* argv[]) {
char port_str[16];
snprintf(port_str, sizeof(port_str), "%d", cli_options.port_override);
if (update_config_in_table("relay_port", port_str) != 0) {
log_error("Failed to update relay port override in config table for existing relay");
DEBUG_ERROR("Failed to update relay port override in config table for existing relay");
cleanup_configuration_system();
nostr_cleanup();
close_database();
@@ -1846,7 +1848,7 @@ int main(int argc, char* argv[]) {
// Verify database is now available
if (!g_db) {
log_error("Database not available after initialization");
DEBUG_ERROR("Database not available after initialization");
cleanup_configuration_system();
nostr_cleanup();
return 1;
@@ -1857,7 +1859,7 @@ int main(int argc, char* argv[]) {
// Initialize unified request validator system
if (ginxsom_request_validator_init(g_database_path, "c-relay") != 0) {
log_error("Failed to initialize unified request validator");
DEBUG_ERROR("Failed to initialize unified request validator");
cleanup_configuration_system();
nostr_cleanup();
close_database();
@@ -1877,7 +1879,7 @@ int main(int argc, char* argv[]) {
// Initialize subscription manager mutexes
if (pthread_mutex_init(&g_subscription_manager.subscriptions_lock, NULL) != 0) {
log_error("Failed to initialize subscription manager subscriptions lock");
DEBUG_ERROR("Failed to initialize subscription manager subscriptions lock");
cleanup_configuration_system();
nostr_cleanup();
close_database();
@@ -1885,7 +1887,7 @@ int main(int argc, char* argv[]) {
}
if (pthread_mutex_init(&g_subscription_manager.ip_tracking_lock, NULL) != 0) {
log_error("Failed to initialize subscription manager IP tracking lock");
DEBUG_ERROR("Failed to initialize subscription manager IP tracking lock");
pthread_mutex_destroy(&g_subscription_manager.subscriptions_lock);
cleanup_configuration_system();
nostr_cleanup();
@@ -1912,7 +1914,7 @@ int main(int argc, char* argv[]) {
if (result == 0) {
} else {
log_error("Server shutdown with errors");
DEBUG_ERROR("Server shutdown with errors");
}
return result;