tmp
This commit is contained in:
@ -1,6 +1,7 @@
|
||||
import { ReqFilter, UsersRelays } from ".";
|
||||
import { unwrap } from "@snort/shared";
|
||||
import { dedupe, unwrap } from "@snort/shared";
|
||||
import debug from "debug";
|
||||
import { FlatReqFilter } from "request-expander";
|
||||
|
||||
const PickNRelays = 2;
|
||||
|
||||
@ -9,6 +10,11 @@ export interface RelayTaggedFilter {
|
||||
filter: ReqFilter;
|
||||
}
|
||||
|
||||
export interface RelayTaggedFlatFilters {
|
||||
relay: string;
|
||||
filters: Array<FlatReqFilter>;
|
||||
}
|
||||
|
||||
export interface RelayTaggedFilters {
|
||||
relay: string;
|
||||
filters: Array<ReqFilter>;
|
||||
@ -43,11 +49,10 @@ export function splitAllByWriteRelays(cache: RelayCache, filters: Array<ReqFilte
|
||||
|
||||
/**
|
||||
* Split filters by authors
|
||||
* @param filter
|
||||
* @returns
|
||||
*/
|
||||
export function splitByWriteRelays(cache: RelayCache, filter: ReqFilter): Array<RelayTaggedFilter> {
|
||||
if ((filter.authors?.length ?? 0) === 0) {
|
||||
const authors = filter.authors;
|
||||
if ((authors?.length ?? 0) === 0) {
|
||||
return [
|
||||
{
|
||||
relay: "",
|
||||
@ -56,10 +61,13 @@ export function splitByWriteRelays(cache: RelayCache, filter: ReqFilter): Array<
|
||||
];
|
||||
}
|
||||
|
||||
const allRelays = unwrap(filter.authors).map(a => {
|
||||
const allRelays = unwrap(authors).map(a => {
|
||||
return {
|
||||
key: a,
|
||||
relays: cache.getFromCache(a)?.relays?.filter(a => a.settings.write).sort(() => Math.random() < 0.5 ? 1 : -1),
|
||||
relays: cache
|
||||
.getFromCache(a)
|
||||
?.relays?.filter(a => a.settings.write)
|
||||
.sort(() => (Math.random() < 0.5 ? 1 : -1)),
|
||||
};
|
||||
});
|
||||
|
||||
@ -83,7 +91,7 @@ export function splitByWriteRelays(cache: RelayCache, filter: ReqFilter): Array<
|
||||
// <key, relay[]> - pick n top relays
|
||||
// <relay, key[]> - map keys per relay (for subscription filter)
|
||||
|
||||
const userPickedRelays = unwrap(filter.authors).map(k => {
|
||||
const userPickedRelays = unwrap(authors).map(k => {
|
||||
// pick top 3 relays for this key
|
||||
const relaysForKey = topRelays
|
||||
.filter(([, v]) => v.has(k))
|
||||
@ -116,3 +124,98 @@ export function splitByWriteRelays(cache: RelayCache, filter: ReqFilter): Array<
|
||||
debug("GOSSIP")("Picked %o", picked);
|
||||
return picked;
|
||||
}
|
||||
|
||||
/**
|
||||
* Split filters by author
|
||||
*/
|
||||
export function splitFlatByWriteRelays(cache: RelayCache, input: Array<FlatReqFilter>): Array<RelayTaggedFlatFilters> {
|
||||
const authors = input.filter(a => a.authors).map(a => unwrap(a.authors));
|
||||
if (authors.length === 0) {
|
||||
return [
|
||||
{
|
||||
relay: "",
|
||||
filters: input,
|
||||
},
|
||||
];
|
||||
}
|
||||
const topRelays = pickTopRelays(cache, authors, PickNRelays);
|
||||
const pickedRelays = dedupe(topRelays.flatMap(a => a.relays));
|
||||
|
||||
const picked = pickedRelays.map(a => {
|
||||
const keysOnPickedRelay = new Set(userPickedRelays.filter(b => b.relaysForKey.includes(a)).map(b => b.k));
|
||||
return {
|
||||
relay: a,
|
||||
filter: {
|
||||
...filter,
|
||||
authors: [...keysOnPickedRelay],
|
||||
},
|
||||
} as RelayTaggedFilter;
|
||||
});
|
||||
if (missing.length > 0) {
|
||||
picked.push({
|
||||
relay: "",
|
||||
filter: {
|
||||
...filter,
|
||||
authors: missing.map(a => a.key),
|
||||
},
|
||||
});
|
||||
}
|
||||
debug("GOSSIP")("Picked %o", picked);
|
||||
return picked;
|
||||
}
|
||||
|
||||
/**
|
||||
* Pick most popular relays for each authors
|
||||
*/
|
||||
function pickTopRelays(cache: RelayCache, authors: Array<string>, n: number) {
|
||||
// map of pubkey -> [write relays]
|
||||
const allRelays = authors.map(a => {
|
||||
return {
|
||||
key: a,
|
||||
relays: cache
|
||||
.getFromCache(a)
|
||||
?.relays?.filter(a => a.settings.write)
|
||||
.sort(() => (Math.random() < 0.5 ? 1 : -1)),
|
||||
};
|
||||
});
|
||||
|
||||
const missing = allRelays.filter(a => a.relays === undefined || a.relays.length === 0);
|
||||
const hasRelays = allRelays.filter(a => a.relays !== undefined && a.relays.length > 0);
|
||||
|
||||
// map of relay -> [pubkeys]
|
||||
const relayUserMap = hasRelays.reduce((acc, v) => {
|
||||
for (const r of unwrap(v.relays)) {
|
||||
if (!acc.has(r.url)) {
|
||||
acc.set(r.url, new Set([v.key]));
|
||||
} else {
|
||||
unwrap(acc.get(r.url)).add(v.key);
|
||||
}
|
||||
}
|
||||
return acc;
|
||||
}, new Map<string, Set<string>>());
|
||||
|
||||
// selection algo will just pick relays with the most users
|
||||
const topRelays = [...relayUserMap.entries()].sort(([, v], [, v1]) => v1.size - v.size);
|
||||
|
||||
// <relay, key[]> - count keys per relay
|
||||
// <key, relay[]> - pick n top relays
|
||||
// <relay, key[]> - map keys per relay (for subscription filter)
|
||||
|
||||
return hasRelays
|
||||
.map(k => {
|
||||
// pick top N relays for this key
|
||||
const relaysForKey = topRelays
|
||||
.filter(([, v]) => v.has(k.key))
|
||||
.slice(0, n)
|
||||
.map(([k]) => k);
|
||||
return { key: k.key, relays: relaysForKey };
|
||||
})
|
||||
.concat(
|
||||
missing.map(a => {
|
||||
return {
|
||||
key: a.key,
|
||||
relays: [],
|
||||
};
|
||||
})
|
||||
);
|
||||
}
|
||||
|
Reference in New Issue
Block a user