feat: full event verify in wasm

This commit is contained in:
2024-01-03 23:20:00 +00:00
parent 267c09a946
commit 0043b7e8bd
13 changed files with 85 additions and 41 deletions

View File

@ -5,7 +5,7 @@ import { Query } from "./query";
import { NostrEvent, ReqFilter, TaggedNostrEvent } from "./nostr";
import { ProfileLoaderService } from "./profile-cache";
import { RelayCache } from "./outbox-model";
import { QueryOptimizer } from "./query-optimizer";
import { Optimizer } from "./query-optimizer";
import { base64 } from "@scure/base";
export { NostrSystem } from "./nostr-system";
@ -127,7 +127,7 @@ export interface SystemInterface {
/**
* Query optimizer
*/
get QueryOptimizer(): QueryOptimizer;
get Optimizer(): Optimizer;
}
export interface SystemSnapshot {

View File

@ -23,7 +23,7 @@ import {
} from ".";
import { EventsCache } from "./cache/events";
import { RelayCache, RelayMetadataLoader } from "./outbox-model";
import { QueryOptimizer, DefaultQueryOptimizer } from "./query-optimizer";
import { Optimizer, DefaultOptimizer } from "./query-optimizer";
import { trimFilters } from "./request-trim";
import { NostrConnectionPool } from "./nostr-connection-pool";
@ -39,7 +39,7 @@ export interface NostrsystemProps {
profileCache?: FeedCache<MetadataCache>;
relayMetrics?: FeedCache<RelayMetrics>;
eventsCache?: FeedCache<NostrEvent>;
queryOptimizer?: QueryOptimizer;
optimizer?: Optimizer;
db?: SnortSystemDb;
checkSigs?: boolean;
}
@ -87,9 +87,9 @@ export class NostrSystem extends EventEmitter<NostrSystemEvents> implements Syst
#eventsCache: FeedCache<NostrEvent>;
/**
* Query optimizer instance
* Optimizer instance, contains optimized functions for processing data
*/
#queryOptimizer: QueryOptimizer;
#optimizer: Optimizer;
/**
* 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.#relayMetricsCache = props.relayMetrics ?? new RelayMetricCache(props.db?.relayMetrics);
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.#relayMetrics = new RelayMetricHandler(this.#relayMetricsCache);
@ -135,8 +135,7 @@ export class NostrSystem extends EventEmitter<NostrSystemEvents> implements Syst
return;
}
if (this.checkSigs) {
const id = EventExt.createId(ev);
if (!this.#queryOptimizer.schnorrVerify(id, ev.sig, ev.pubkey)) {
if (!this.#optimizer.schnorrVerify(ev)) {
this.#log("Invalid sig %O", ev);
return;
}
@ -186,8 +185,8 @@ export class NostrSystem extends EventEmitter<NostrSystemEvents> implements Syst
return this.#relayCache;
}
get QueryOptimizer(): QueryOptimizer {
return this.#queryOptimizer;
get Optimizer(): Optimizer {
return this.#optimizer;
}
async Init() {

View File

@ -1,8 +1,9 @@
import { schnorr } from "@noble/curves/secp256k1";
import { ReqFilter } from "../nostr";
import { NostrEvent, ReqFilter } from "../nostr";
import { expandFilter } from "./request-expander";
import { flatMerge, mergeSimilar } from "./request-merger";
import { diffFilters } from "./request-splitter";
import { EventExt } from "../event-ext";
export interface FlatReqFilter {
keys: number;
@ -21,15 +22,15 @@ export interface FlatReqFilter {
resultSetId: string;
}
export interface QueryOptimizer {
export interface Optimizer {
expandFilter(f: ReqFilter): Array<FlatReqFilter>;
getDiff(prev: Array<ReqFilter>, next: Array<ReqFilter>): Array<FlatReqFilter>;
flatMerge(all: Array<FlatReqFilter>): 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) => {
return expandFilter(f);
},
@ -46,7 +47,8 @@ export const DefaultQueryOptimizer = {
compress: (all: Array<ReqFilter>) => {
return mergeSimilar(all);
},
schnorrVerify: (hash, sig, pubkey) => {
return schnorr.verify(sig, hash, pubkey);
schnorrVerify: ev => {
const id = EventExt.createId(ev);
return schnorr.verify(ev.sig, id, ev.pubkey);
},
} as QueryOptimizer;
} as Optimizer;

View File

@ -121,14 +121,14 @@ export class RequestBuilder {
buildDiff(system: SystemInterface, prev: Array<ReqFilter>): Array<BuiltRawReqFilter> {
const start = unixNowMs();
const diff = system.QueryOptimizer.getDiff(prev, this.buildRaw());
const diff = system.Optimizer.getDiff(prev, this.buildRaw());
const ts = unixNowMs() - start;
this.#log("buildDiff %s %d ms +%d", this.id, ts, diff.length);
if (diff.length > 0) {
return splitFlatByWriteRelays(system.RelayCache, diff).map(a => {
return {
strategy: RequestStrategy.AuthorsRelays,
filters: system.QueryOptimizer.flatMerge(a.filters),
filters: system.Optimizer.flatMerge(a.filters),
relay: a.relay,
};
});
@ -154,9 +154,7 @@ export class RequestBuilder {
const filtersSquashed = [...relayMerged.values()].map(a => {
return {
filters: system.QueryOptimizer.flatMerge(
a.flatMap(b => b.filters.flatMap(c => system.QueryOptimizer.expandFilter(c))),
),
filters: system.Optimizer.flatMerge(a.flatMap(b => b.filters.flatMap(c => system.Optimizer.expandFilter(c)))),
relay: a[0].relay,
strategy: a[0].strategy,
} as BuiltRawReqFilter;

View File

@ -6,7 +6,7 @@ import {
NoteStore,
OkResponse,
ProfileLoaderService,
QueryOptimizer,
Optimizer,
RelayCache,
RelaySettings,
RequestBuilder,
@ -79,7 +79,7 @@ export class SystemWorker extends EventEmitter<NostrSystemEvents> implements Sys
throw new Error("Method not implemented.");
}
get QueryOptimizer(): QueryOptimizer {
get Optimizer(): Optimizer {
throw new Error("Method not implemented.");
}