feat: full event verify in wasm
Some checks failed
continuous-integration/drone/push Build is failing
Some checks failed
continuous-integration/drone/push Build is failing
This commit is contained in:
parent
267c09a946
commit
0043b7e8bd
@ -1,4 +1,4 @@
|
|||||||
import { useEffect, useState } from "react";
|
import { useEffect, useMemo, useState } from "react";
|
||||||
import { FormattedMessage } from "react-intl";
|
import { FormattedMessage } from "react-intl";
|
||||||
|
|
||||||
export interface NoteTimeProps {
|
export interface NoteTimeProps {
|
||||||
@ -14,10 +14,14 @@ export default function NoteTime(props: NoteTimeProps) {
|
|||||||
const { from, fallback } = props;
|
const { from, fallback } = props;
|
||||||
const [time, setTime] = useState<string | JSX.Element>(calcTime());
|
const [time, setTime] = useState<string | JSX.Element>(calcTime());
|
||||||
|
|
||||||
const absoluteTime = new Intl.DateTimeFormat(undefined, {
|
const absoluteTime = useMemo(
|
||||||
|
() =>
|
||||||
|
new Intl.DateTimeFormat(undefined, {
|
||||||
dateStyle: "medium",
|
dateStyle: "medium",
|
||||||
timeStyle: "long",
|
timeStyle: "long",
|
||||||
}).format(from);
|
}).format(from),
|
||||||
|
[from],
|
||||||
|
);
|
||||||
|
|
||||||
const isoDate = new Date(from).toISOString();
|
const isoDate = new Date(from).toISOString();
|
||||||
|
|
||||||
|
@ -8,7 +8,7 @@ import {
|
|||||||
flat_merge,
|
flat_merge,
|
||||||
get_diff,
|
get_diff,
|
||||||
pow,
|
pow,
|
||||||
schnorr_verify,
|
schnorr_verify_event,
|
||||||
default as wasmInit,
|
default as wasmInit,
|
||||||
} from "@snort/system-wasm";
|
} from "@snort/system-wasm";
|
||||||
import WasmPath from "@snort/system-wasm/pkg/system_wasm_bg.wasm";
|
import WasmPath from "@snort/system-wasm/pkg/system_wasm_bg.wasm";
|
||||||
@ -19,7 +19,7 @@ import { createBrowserRouter, RouteObject, RouterProvider } from "react-router-d
|
|||||||
import {
|
import {
|
||||||
NostrSystem,
|
NostrSystem,
|
||||||
ProfileLoaderService,
|
ProfileLoaderService,
|
||||||
QueryOptimizer,
|
Optimizer,
|
||||||
FlatReqFilter,
|
FlatReqFilter,
|
||||||
ReqFilter,
|
ReqFilter,
|
||||||
PowMiner,
|
PowMiner,
|
||||||
@ -76,7 +76,7 @@ declare global {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const WasmQueryOptimizer = {
|
const WasmOptimizer = {
|
||||||
expandFilter: (f: ReqFilter) => {
|
expandFilter: (f: ReqFilter) => {
|
||||||
return expand_filter(f) as Array<FlatReqFilter>;
|
return expand_filter(f) as Array<FlatReqFilter>;
|
||||||
},
|
},
|
||||||
@ -89,10 +89,10 @@ const WasmQueryOptimizer = {
|
|||||||
compress: (all: Array<ReqFilter>) => {
|
compress: (all: Array<ReqFilter>) => {
|
||||||
return compress(all) as Array<ReqFilter>;
|
return compress(all) as Array<ReqFilter>;
|
||||||
},
|
},
|
||||||
schnorrVerify: (id, sig, pubkey) => {
|
schnorrVerify: ev => {
|
||||||
return schnorr_verify(id, sig, pubkey);
|
return schnorr_verify_event(ev);
|
||||||
},
|
},
|
||||||
} as QueryOptimizer;
|
} as Optimizer;
|
||||||
|
|
||||||
export class WasmPowWorker implements PowMiner {
|
export class WasmPowWorker implements PowMiner {
|
||||||
minePow(ev: NostrEvent, target: number): Promise<NostrEvent> {
|
minePow(ev: NostrEvent, target: number): Promise<NostrEvent> {
|
||||||
@ -114,7 +114,7 @@ export const System = new NostrSystem({
|
|||||||
relayCache: UserRelays,
|
relayCache: UserRelays,
|
||||||
profileCache: UserCache,
|
profileCache: UserCache,
|
||||||
relayMetrics: RelayMetrics,
|
relayMetrics: RelayMetrics,
|
||||||
queryOptimizer: hasWasm ? WasmQueryOptimizer : undefined,
|
optimizer: hasWasm ? WasmOptimizer : undefined,
|
||||||
db: SystemDb,
|
db: SystemDb,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -12,9 +12,10 @@ argon2 = "0.5.2"
|
|||||||
console_error_panic_hook = "0.1.7"
|
console_error_panic_hook = "0.1.7"
|
||||||
hex = { version = "0.4.3", features = [], default-features = false }
|
hex = { version = "0.4.3", features = [], default-features = false }
|
||||||
itertools = "0.11.0"
|
itertools = "0.11.0"
|
||||||
secp256k1 = "0.28.0"
|
secp256k1 = { version = "0.28.0", features = ["global-context"] }
|
||||||
serde = { version = "1.0.188", features = ["derive"], default-features = false }
|
serde = { version = "1.0.188", features = ["derive"], default-features = false }
|
||||||
serde-wasm-bindgen = "0.5.0"
|
serde-wasm-bindgen = "0.5.0"
|
||||||
|
serde_json = "1.0.105"
|
||||||
sha256 = { version = "1.4.0", features = [], default-features = false }
|
sha256 = { version = "1.4.0", features = [], default-features = false }
|
||||||
wasm-bindgen = "0.2.87"
|
wasm-bindgen = "0.2.87"
|
||||||
|
|
||||||
|
6
packages/system-wasm/pkg/system_wasm.d.ts
vendored
6
packages/system-wasm/pkg/system_wasm.d.ts
vendored
@ -46,6 +46,11 @@ export function argon2(password: any, salt: any): any;
|
|||||||
* @returns {boolean}
|
* @returns {boolean}
|
||||||
*/
|
*/
|
||||||
export function schnorr_verify(hash: any, sig: any, pub_key: any): boolean;
|
export function schnorr_verify(hash: any, sig: any, pub_key: any): boolean;
|
||||||
|
/**
|
||||||
|
* @param {any} event
|
||||||
|
* @returns {boolean}
|
||||||
|
*/
|
||||||
|
export function schnorr_verify_event(event: any): boolean;
|
||||||
|
|
||||||
export type InitInput = RequestInfo | URL | Response | BufferSource | WebAssembly.Module;
|
export type InitInput = RequestInfo | URL | Response | BufferSource | WebAssembly.Module;
|
||||||
|
|
||||||
@ -59,6 +64,7 @@ export interface InitOutput {
|
|||||||
readonly pow: (a: number, b: number, c: number) => void;
|
readonly pow: (a: number, b: number, c: number) => void;
|
||||||
readonly argon2: (a: number, b: number, c: number) => void;
|
readonly argon2: (a: number, b: number, c: number) => void;
|
||||||
readonly schnorr_verify: (a: number, b: number, c: number, d: number) => void;
|
readonly schnorr_verify: (a: number, b: number, c: number, d: number) => void;
|
||||||
|
readonly schnorr_verify_event: (a: number, b: number) => void;
|
||||||
readonly rustsecp256k1_v0_9_1_context_create: (a: number) => number;
|
readonly rustsecp256k1_v0_9_1_context_create: (a: number) => number;
|
||||||
readonly rustsecp256k1_v0_9_1_context_destroy: (a: number) => void;
|
readonly rustsecp256k1_v0_9_1_context_destroy: (a: number) => void;
|
||||||
readonly rustsecp256k1_v0_9_1_default_illegal_callback_fn: (a: number, b: number) => void;
|
readonly rustsecp256k1_v0_9_1_default_illegal_callback_fn: (a: number, b: number) => void;
|
||||||
|
@ -383,6 +383,26 @@ export function schnorr_verify(hash, sig, pub_key) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {any} event
|
||||||
|
* @returns {boolean}
|
||||||
|
*/
|
||||||
|
export function schnorr_verify_event(event) {
|
||||||
|
try {
|
||||||
|
const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
|
||||||
|
wasm.schnorr_verify_event(retptr, addHeapObject(event));
|
||||||
|
var r0 = getInt32Memory0()[retptr / 4 + 0];
|
||||||
|
var r1 = getInt32Memory0()[retptr / 4 + 1];
|
||||||
|
var r2 = getInt32Memory0()[retptr / 4 + 2];
|
||||||
|
if (r2) {
|
||||||
|
throw takeObject(r1);
|
||||||
|
}
|
||||||
|
return r0 !== 0;
|
||||||
|
} finally {
|
||||||
|
wasm.__wbindgen_add_to_stack_pointer(16);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function handleError(f, args) {
|
function handleError(f, args) {
|
||||||
try {
|
try {
|
||||||
return f.apply(this, args);
|
return f.apply(this, args);
|
||||||
|
Binary file not shown.
@ -9,6 +9,7 @@ export function compress(a: number, b: number): void;
|
|||||||
export function pow(a: number, b: number, c: number): void;
|
export function pow(a: number, b: number, c: number): void;
|
||||||
export function argon2(a: number, b: number, c: number): void;
|
export function argon2(a: number, b: number, c: number): void;
|
||||||
export function schnorr_verify(a: number, b: number, c: number, d: number): void;
|
export function schnorr_verify(a: number, b: number, c: number, d: number): void;
|
||||||
|
export function schnorr_verify_event(a: number, b: number): void;
|
||||||
export function rustsecp256k1_v0_9_1_context_create(a: number): number;
|
export function rustsecp256k1_v0_9_1_context_create(a: number): number;
|
||||||
export function rustsecp256k1_v0_9_1_context_destroy(a: number): void;
|
export function rustsecp256k1_v0_9_1_context_destroy(a: number): void;
|
||||||
export function rustsecp256k1_v0_9_1_default_illegal_callback_fn(a: number, b: number): void;
|
export function rustsecp256k1_v0_9_1_default_illegal_callback_fn(a: number, b: number): void;
|
||||||
|
@ -1,8 +1,9 @@
|
|||||||
extern crate console_error_panic_hook;
|
extern crate console_error_panic_hook;
|
||||||
|
|
||||||
use argon2::{Argon2};
|
use argon2::{Argon2};
|
||||||
use secp256k1::{Message, Secp256k1, XOnlyPublicKey};
|
use secp256k1::{Message, XOnlyPublicKey, SECP256K1};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
use serde_json::json;
|
||||||
use crate::filter::{FlatReqFilter, ReqFilter};
|
use crate::filter::{FlatReqFilter, ReqFilter};
|
||||||
use wasm_bindgen::prelude::*;
|
use wasm_bindgen::prelude::*;
|
||||||
|
|
||||||
@ -106,13 +107,25 @@ pub fn schnorr_verify(hash: JsValue, sig: JsValue, pub_key: JsValue) -> Result<b
|
|||||||
let sig_hex: String = serde_wasm_bindgen::from_value(sig)?;
|
let sig_hex: String = serde_wasm_bindgen::from_value(sig)?;
|
||||||
let pub_key_hex: String = serde_wasm_bindgen::from_value(pub_key)?;
|
let pub_key_hex: String = serde_wasm_bindgen::from_value(pub_key)?;
|
||||||
|
|
||||||
let secp = Secp256k1::new();
|
|
||||||
let msg = Message::from_digest_slice(&hex::decode(msg_hex).unwrap()).unwrap();
|
let msg = Message::from_digest_slice(&hex::decode(msg_hex).unwrap()).unwrap();
|
||||||
let key = XOnlyPublicKey::from_slice(&hex::decode(pub_key_hex).unwrap()).unwrap();
|
let key = XOnlyPublicKey::from_slice(&hex::decode(pub_key_hex).unwrap()).unwrap();
|
||||||
let sig = secp256k1::schnorr::Signature::from_slice(&hex::decode(sig_hex).unwrap()).unwrap();
|
let sig = secp256k1::schnorr::Signature::from_slice(&hex::decode(sig_hex).unwrap()).unwrap();
|
||||||
Ok(secp.verify_schnorr(&sig, &msg, &key).is_ok())
|
Ok(SECP256K1.verify_schnorr(&sig, &msg, &key).is_ok())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[wasm_bindgen]
|
||||||
|
pub fn schnorr_verify_event(event: JsValue) -> Result<bool, JsValue> {
|
||||||
|
console_error_panic_hook::set_once();
|
||||||
|
let event_obj: Event = serde_wasm_bindgen::from_value(event)?;
|
||||||
|
|
||||||
|
let json = json!([0, event_obj.pubkey, event_obj.created_at, event_obj.kind, event_obj.tags, event_obj.content]);
|
||||||
|
let id = sha256::digest(json.to_string().as_bytes());
|
||||||
|
|
||||||
|
let msg = Message::from_digest_slice(&hex::decode(id).unwrap()).unwrap();
|
||||||
|
let key = XOnlyPublicKey::from_slice(&hex::decode(&event_obj.pubkey).unwrap()).unwrap();
|
||||||
|
let sig = secp256k1::schnorr::Signature::from_slice(&hex::decode(&event_obj.sig.unwrap()).unwrap()).unwrap();
|
||||||
|
Ok(SECP256K1.verify_schnorr(&sig, &msg, &key).is_ok())
|
||||||
|
}
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
@ -5,7 +5,7 @@ import { Query } from "./query";
|
|||||||
import { NostrEvent, ReqFilter, TaggedNostrEvent } from "./nostr";
|
import { NostrEvent, ReqFilter, TaggedNostrEvent } from "./nostr";
|
||||||
import { ProfileLoaderService } from "./profile-cache";
|
import { ProfileLoaderService } from "./profile-cache";
|
||||||
import { RelayCache } from "./outbox-model";
|
import { RelayCache } from "./outbox-model";
|
||||||
import { QueryOptimizer } from "./query-optimizer";
|
import { Optimizer } from "./query-optimizer";
|
||||||
import { base64 } from "@scure/base";
|
import { base64 } from "@scure/base";
|
||||||
|
|
||||||
export { NostrSystem } from "./nostr-system";
|
export { NostrSystem } from "./nostr-system";
|
||||||
@ -127,7 +127,7 @@ export interface SystemInterface {
|
|||||||
/**
|
/**
|
||||||
* Query optimizer
|
* Query optimizer
|
||||||
*/
|
*/
|
||||||
get QueryOptimizer(): QueryOptimizer;
|
get Optimizer(): Optimizer;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface SystemSnapshot {
|
export interface SystemSnapshot {
|
||||||
|
@ -23,7 +23,7 @@ import {
|
|||||||
} from ".";
|
} from ".";
|
||||||
import { EventsCache } from "./cache/events";
|
import { EventsCache } from "./cache/events";
|
||||||
import { RelayCache, RelayMetadataLoader } from "./outbox-model";
|
import { RelayCache, RelayMetadataLoader } from "./outbox-model";
|
||||||
import { QueryOptimizer, DefaultQueryOptimizer } from "./query-optimizer";
|
import { Optimizer, DefaultOptimizer } from "./query-optimizer";
|
||||||
import { trimFilters } from "./request-trim";
|
import { trimFilters } from "./request-trim";
|
||||||
import { NostrConnectionPool } from "./nostr-connection-pool";
|
import { NostrConnectionPool } from "./nostr-connection-pool";
|
||||||
|
|
||||||
@ -39,7 +39,7 @@ export interface NostrsystemProps {
|
|||||||
profileCache?: FeedCache<MetadataCache>;
|
profileCache?: FeedCache<MetadataCache>;
|
||||||
relayMetrics?: FeedCache<RelayMetrics>;
|
relayMetrics?: FeedCache<RelayMetrics>;
|
||||||
eventsCache?: FeedCache<NostrEvent>;
|
eventsCache?: FeedCache<NostrEvent>;
|
||||||
queryOptimizer?: QueryOptimizer;
|
optimizer?: Optimizer;
|
||||||
db?: SnortSystemDb;
|
db?: SnortSystemDb;
|
||||||
checkSigs?: boolean;
|
checkSigs?: boolean;
|
||||||
}
|
}
|
||||||
@ -87,9 +87,9 @@ export class NostrSystem extends EventEmitter<NostrSystemEvents> implements Syst
|
|||||||
#eventsCache: FeedCache<NostrEvent>;
|
#eventsCache: FeedCache<NostrEvent>;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Query optimizer instance
|
* Optimizer instance, contains optimized functions for processing data
|
||||||
*/
|
*/
|
||||||
#queryOptimizer: QueryOptimizer;
|
#optimizer: Optimizer;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check event signatures (reccomended)
|
* Check event signatures (reccomended)
|
||||||
@ -104,7 +104,7 @@ export class NostrSystem extends EventEmitter<NostrSystemEvents> implements Syst
|
|||||||
this.#profileCache = props.profileCache ?? new UserProfileCache(props.db?.users);
|
this.#profileCache = props.profileCache ?? new UserProfileCache(props.db?.users);
|
||||||
this.#relayMetricsCache = props.relayMetrics ?? new RelayMetricCache(props.db?.relayMetrics);
|
this.#relayMetricsCache = props.relayMetrics ?? new RelayMetricCache(props.db?.relayMetrics);
|
||||||
this.#eventsCache = props.eventsCache ?? new EventsCache(props.db?.events);
|
this.#eventsCache = props.eventsCache ?? new EventsCache(props.db?.events);
|
||||||
this.#queryOptimizer = props.queryOptimizer ?? DefaultQueryOptimizer;
|
this.#optimizer = props.optimizer ?? DefaultOptimizer;
|
||||||
|
|
||||||
this.#profileLoader = new ProfileLoaderService(this, this.#profileCache);
|
this.#profileLoader = new ProfileLoaderService(this, this.#profileCache);
|
||||||
this.#relayMetrics = new RelayMetricHandler(this.#relayMetricsCache);
|
this.#relayMetrics = new RelayMetricHandler(this.#relayMetricsCache);
|
||||||
@ -135,8 +135,7 @@ export class NostrSystem extends EventEmitter<NostrSystemEvents> implements Syst
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (this.checkSigs) {
|
if (this.checkSigs) {
|
||||||
const id = EventExt.createId(ev);
|
if (!this.#optimizer.schnorrVerify(ev)) {
|
||||||
if (!this.#queryOptimizer.schnorrVerify(id, ev.sig, ev.pubkey)) {
|
|
||||||
this.#log("Invalid sig %O", ev);
|
this.#log("Invalid sig %O", ev);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -186,8 +185,8 @@ export class NostrSystem extends EventEmitter<NostrSystemEvents> implements Syst
|
|||||||
return this.#relayCache;
|
return this.#relayCache;
|
||||||
}
|
}
|
||||||
|
|
||||||
get QueryOptimizer(): QueryOptimizer {
|
get Optimizer(): Optimizer {
|
||||||
return this.#queryOptimizer;
|
return this.#optimizer;
|
||||||
}
|
}
|
||||||
|
|
||||||
async Init() {
|
async Init() {
|
||||||
|
@ -1,8 +1,9 @@
|
|||||||
import { schnorr } from "@noble/curves/secp256k1";
|
import { schnorr } from "@noble/curves/secp256k1";
|
||||||
import { ReqFilter } from "../nostr";
|
import { NostrEvent, ReqFilter } from "../nostr";
|
||||||
import { expandFilter } from "./request-expander";
|
import { expandFilter } from "./request-expander";
|
||||||
import { flatMerge, mergeSimilar } from "./request-merger";
|
import { flatMerge, mergeSimilar } from "./request-merger";
|
||||||
import { diffFilters } from "./request-splitter";
|
import { diffFilters } from "./request-splitter";
|
||||||
|
import { EventExt } from "../event-ext";
|
||||||
|
|
||||||
export interface FlatReqFilter {
|
export interface FlatReqFilter {
|
||||||
keys: number;
|
keys: number;
|
||||||
@ -21,15 +22,15 @@ export interface FlatReqFilter {
|
|||||||
resultSetId: string;
|
resultSetId: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface QueryOptimizer {
|
export interface Optimizer {
|
||||||
expandFilter(f: ReqFilter): Array<FlatReqFilter>;
|
expandFilter(f: ReqFilter): Array<FlatReqFilter>;
|
||||||
getDiff(prev: Array<ReqFilter>, next: Array<ReqFilter>): Array<FlatReqFilter>;
|
getDiff(prev: Array<ReqFilter>, next: Array<ReqFilter>): Array<FlatReqFilter>;
|
||||||
flatMerge(all: Array<FlatReqFilter>): Array<ReqFilter>;
|
flatMerge(all: Array<FlatReqFilter>): Array<ReqFilter>;
|
||||||
compress(all: Array<ReqFilter>): Array<ReqFilter>;
|
compress(all: Array<ReqFilter>): Array<ReqFilter>;
|
||||||
schnorrVerify(hash: string, sig: string, pubkey: string): boolean;
|
schnorrVerify(ev: NostrEvent): boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const DefaultQueryOptimizer = {
|
export const DefaultOptimizer = {
|
||||||
expandFilter: (f: ReqFilter) => {
|
expandFilter: (f: ReqFilter) => {
|
||||||
return expandFilter(f);
|
return expandFilter(f);
|
||||||
},
|
},
|
||||||
@ -46,7 +47,8 @@ export const DefaultQueryOptimizer = {
|
|||||||
compress: (all: Array<ReqFilter>) => {
|
compress: (all: Array<ReqFilter>) => {
|
||||||
return mergeSimilar(all);
|
return mergeSimilar(all);
|
||||||
},
|
},
|
||||||
schnorrVerify: (hash, sig, pubkey) => {
|
schnorrVerify: ev => {
|
||||||
return schnorr.verify(sig, hash, pubkey);
|
const id = EventExt.createId(ev);
|
||||||
|
return schnorr.verify(ev.sig, id, ev.pubkey);
|
||||||
},
|
},
|
||||||
} as QueryOptimizer;
|
} as Optimizer;
|
||||||
|
@ -121,14 +121,14 @@ export class RequestBuilder {
|
|||||||
buildDiff(system: SystemInterface, prev: Array<ReqFilter>): Array<BuiltRawReqFilter> {
|
buildDiff(system: SystemInterface, prev: Array<ReqFilter>): Array<BuiltRawReqFilter> {
|
||||||
const start = unixNowMs();
|
const start = unixNowMs();
|
||||||
|
|
||||||
const diff = system.QueryOptimizer.getDiff(prev, this.buildRaw());
|
const diff = system.Optimizer.getDiff(prev, this.buildRaw());
|
||||||
const ts = unixNowMs() - start;
|
const ts = unixNowMs() - start;
|
||||||
this.#log("buildDiff %s %d ms +%d", this.id, ts, diff.length);
|
this.#log("buildDiff %s %d ms +%d", this.id, ts, diff.length);
|
||||||
if (diff.length > 0) {
|
if (diff.length > 0) {
|
||||||
return splitFlatByWriteRelays(system.RelayCache, diff).map(a => {
|
return splitFlatByWriteRelays(system.RelayCache, diff).map(a => {
|
||||||
return {
|
return {
|
||||||
strategy: RequestStrategy.AuthorsRelays,
|
strategy: RequestStrategy.AuthorsRelays,
|
||||||
filters: system.QueryOptimizer.flatMerge(a.filters),
|
filters: system.Optimizer.flatMerge(a.filters),
|
||||||
relay: a.relay,
|
relay: a.relay,
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
@ -154,9 +154,7 @@ export class RequestBuilder {
|
|||||||
|
|
||||||
const filtersSquashed = [...relayMerged.values()].map(a => {
|
const filtersSquashed = [...relayMerged.values()].map(a => {
|
||||||
return {
|
return {
|
||||||
filters: system.QueryOptimizer.flatMerge(
|
filters: system.Optimizer.flatMerge(a.flatMap(b => b.filters.flatMap(c => system.Optimizer.expandFilter(c)))),
|
||||||
a.flatMap(b => b.filters.flatMap(c => system.QueryOptimizer.expandFilter(c))),
|
|
||||||
),
|
|
||||||
relay: a[0].relay,
|
relay: a[0].relay,
|
||||||
strategy: a[0].strategy,
|
strategy: a[0].strategy,
|
||||||
} as BuiltRawReqFilter;
|
} as BuiltRawReqFilter;
|
||||||
|
@ -6,7 +6,7 @@ import {
|
|||||||
NoteStore,
|
NoteStore,
|
||||||
OkResponse,
|
OkResponse,
|
||||||
ProfileLoaderService,
|
ProfileLoaderService,
|
||||||
QueryOptimizer,
|
Optimizer,
|
||||||
RelayCache,
|
RelayCache,
|
||||||
RelaySettings,
|
RelaySettings,
|
||||||
RequestBuilder,
|
RequestBuilder,
|
||||||
@ -79,7 +79,7 @@ export class SystemWorker extends EventEmitter<NostrSystemEvents> implements Sys
|
|||||||
throw new Error("Method not implemented.");
|
throw new Error("Method not implemented.");
|
||||||
}
|
}
|
||||||
|
|
||||||
get QueryOptimizer(): QueryOptimizer {
|
get Optimizer(): Optimizer {
|
||||||
throw new Error("Method not implemented.");
|
throw new Error("Method not implemented.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user