Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
81c5339063 |
@@ -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
@@ -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"
|
||||
|
||||
Reference in New Issue
Block a user