Compare commits

...
1 Commits
2 changed files with 95 additions and 5 deletions
+93 -3
View File
@@ -239,8 +239,8 @@ static void compute_covering_set(cr_relay_map_t *map, cr_config_t *cfg,
* Returns a cJSON array of events (caller must cJSON_Delete each + free).
* Sets *out_count to the number of events returned. */
static cJSON **query_kind10002_batch(nostr_relay_pool_t *pool,
const char **pubkeys, int pubkey_count,
int *out_count) {
const char **pubkeys, int pubkey_count,
int *out_count) {
cJSON *filter = cJSON_CreateObject();
cJSON *authors = cJSON_CreateArray();
for (int i = 0; i < pubkey_count; i++)
@@ -276,6 +276,44 @@ static cJSON **query_kind10002_batch(nostr_relay_pool_t *pool,
return events;
}
/* ---- batched kind-3 fallback query ---- */
/* Query kind 3 (contact list) for a batch of pubkeys from a pool.
* Kind-3 events historically contain "r" tags with relay URLs (pre-NIP-65).
* We use this as a fallback for pubkeys that don't have kind-10002.
* Returns a cJSON array of events (caller must cJSON_Delete each + free).
* Sets *out_count to the number of events returned. */
static cJSON **query_kind3_batch(nostr_relay_pool_t *pool,
const char **pubkeys, int pubkey_count,
int *out_count) {
cJSON *filter = cJSON_CreateObject();
cJSON *authors = cJSON_CreateArray();
for (int i = 0; i < pubkey_count; i++)
cJSON_AddItemToArray(authors, cJSON_CreateString(pubkeys[i]));
cJSON_AddItemToObject(filter, "authors", authors);
cJSON *kinds = cJSON_CreateArray();
cJSON_AddItemToArray(kinds, cJSON_CreateNumber(3));
cJSON_AddItemToObject(filter, "kinds", kinds);
/* limit=1 per author: we only need the most recent kind-3.
* The relay pool query_sync returns the most recent events. */
cJSON_AddItemToObject(filter, "limit", cJSON_CreateNumber(pubkey_count));
const char **urls = NULL;
int n = get_pool_urls(pool, &urls);
DEBUG_TRACE("query_kind3_batch: querying %d relays for %d pubkeys", n, pubkey_count);
int ev_count = 0;
cJSON **events = nostr_relay_pool_query_sync(pool, urls, n, filter, &ev_count, 30000);
free(urls);
cJSON_Delete(filter);
DEBUG_TRACE("query_kind3_batch: returned %d events", ev_count);
*out_count = ev_count;
return events;
}
/* Process a batch of kind-10002 events: parse r-tags, populate outbox entries,
* publish to local relay. Returns count of events processed. */
static int process_10002_batch(cJSON **events, int ev_count,
@@ -438,9 +476,61 @@ int cr_relay_discovery_run(cr_relay_map_t *map, cr_config_t *cfg,
free(remaining_pk);
}
/* Phase 3: Kind-3 fallback for pubkeys still without relay lists.
* Kind-3 (contact list) events historically contain "r" tags with relay
* URLs (pre-NIP-65). This catches older users who never published kind-10002. */
int remaining_k3 = 0;
for (int i = 0; i < followed->count; i++) if (!found[i]) remaining_k3++;
if (remaining_k3 > 0) {
DEBUG_INFO("relay_discovery: querying bootstrap relays for kind-3 fallback (%d pubkeys)...",
remaining_k3);
const char **remaining_pk = malloc(remaining_k3 * sizeof(char *));
int ridx = 0;
for (int i = 0; i < followed->count; i++) {
if (!found[i]) remaining_pk[ridx++] = followed->items[i];
}
int found_k3 = 0;
for (int start = 0; start < remaining_k3 && !g_shutdown; start += CR_10002_BATCH_SIZE) {
int batch = remaining_k3 - start;
if (batch > CR_10002_BATCH_SIZE) batch = CR_10002_BATCH_SIZE;
int ev_count = 0;
cJSON **events = query_kind3_batch(upstream,
&remaining_pk[start],
batch, &ev_count);
if (events && ev_count > 0) {
for (int k = 0; k < ev_count; k++) {
cJSON *pk = cJSON_GetObjectItem(events[k], "pubkey");
if (pk && cJSON_IsString(pk)) {
const char *hex = cJSON_GetStringValue(pk);
for (int i = 0; i < followed->count; i++) {
if (strcmp(followed->items[i], hex) == 0) {
if (!found[i]) { found[i] = 1; found_k3++; }
break;
}
}
}
}
/* process_10002_batch works for kind-3 too — same r-tag format */
process_10002_batch(events, ev_count, map, sink, "bootstrap");
cr_sink_pump(sink, 500);
} else {
free(events);
}
}
free(remaining_pk);
DEBUG_INFO("relay_discovery: kind-3 fallback found %d additional pubkeys with relays", found_k3);
}
found_none = followed->count - found_local - found_bootstrap;
/* Recalculate found_none after kind-3 fallback */
int still_none = 0;
for (int i = 0; i < followed->count; i++) if (!found[i]) still_none++;
DEBUG_INFO("relay_discovery: %d local, %d bootstrap, %d none",
found_local, found_bootstrap, found_none);
found_local, found_bootstrap, still_none);
free(found);
+2 -2
View File
@@ -13,8 +13,8 @@
// 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 27
#define CRELAY_VERSION "v2.1.27"
#define CRELAY_VERSION_PATCH 28
#define CRELAY_VERSION "v2.1.28"
// Relay metadata (authoritative source for NIP-11 information)
#define RELAY_NAME "C-Relay-PG"