Skip to content

Commit

Permalink
Add NTSchema's SVS (in progress)
Browse files Browse the repository at this point in the history
  • Loading branch information
zjkmxy committed Feb 24, 2024
1 parent 4b64753 commit 76a0320
Show file tree
Hide file tree
Showing 9 changed files with 105 additions and 19 deletions.
5 changes: 3 additions & 2 deletions deno.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 3 additions & 1 deletion src/namespace/base-node.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,11 +36,13 @@ export class BaseNode {
public verifyPacket(
matched: schemaTree.StrictMatch<BaseNode>,
pkt: Verifier.Verifiable,
deadline: number,
deadline: number | undefined,
context: Record<string, unknown>,
) {
console.warn(`Silently drop unverified packet ${matched.name.toString()}`);
pkt;
deadline;
context;
return Promise.resolve(false);
}

Expand Down
13 changes: 8 additions & 5 deletions src/namespace/expressing-point.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,10 @@ export interface ExpressingPointEvents extends BaseNodeEvents {
verify(
args: {
target: schemaTree.StrictMatch<ExpressingPoint>;
deadline: number;
deadline: number | undefined;
pkt: Verifier.Verifiable;
prevResult: VerifyResult;
context: Record<string, unknown>;
},
): Promise<VerifyResult>;

Expand Down Expand Up @@ -69,7 +70,8 @@ export class ExpressingPoint extends BaseNode {
public override async verifyPacket(
matched: schemaTree.StrictMatch<ExpressingPoint>,
pkt: Verifier.Verifiable,
deadline: number,
deadline: number | undefined,
context: Record<string, unknown>,
) {
const verifyResult = await this.onVerify.chain(
VerifyResult.Unknown,
Expand All @@ -80,7 +82,7 @@ export class ExpressingPoint extends BaseNode {
prevResult: ret,
}],
),
{ target: matched, pkt, deadline, prevResult: VerifyResult.Unknown },
{ target: matched, pkt, deadline, prevResult: VerifyResult.Unknown, context },
);
return verifyResult >= VerifyResult.Pass;
}
Expand All @@ -103,7 +105,7 @@ export class ExpressingPoint extends BaseNode {
// Signed Interests are required to carry AppParam, but may be zero length.
// To guarantee everything is good in case the underlying library returns `undefined` when zero length, check both.
if (interest.appParameters || interest.sigInfo) {
if (!await this.verifyPacket(matched, interest, deadline)) {
if (!await this.verifyPacket(matched, interest, deadline, {})) {
// Unverified Interest. Drop
return;
}
Expand Down Expand Up @@ -136,6 +138,7 @@ export class ExpressingPoint extends BaseNode {
lifetimeMs?: number;
deadline?: number;
verifier?: Verifier;
verificationContext?: Record<string, unknown>;
} = {},
): Promise<Data> {
// Construct Interest, but without signing, so the parameter digest is not there
Expand Down Expand Up @@ -200,7 +203,7 @@ export class ExpressingPoint extends BaseNode {
signal: opts.abortSignal as any,
retx: this.config.retx,
// Note: the verifier is at the LeafNode if CanBePrefix is set
verifier: opts.verifier ?? this.handler!.getVerifier(deadline),
verifier: opts.verifier ?? this.handler!.getVerifier(deadline, opts.verificationContext),
});

// (no await) Save (cache) the data in the storage
Expand Down
1 change: 1 addition & 0 deletions src/namespace/mod.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,4 @@ export * from './nt-schema.ts';
export * from './base-node.ts';
export * from './expressing-point.ts';
export * from './leaf-node.ts';
export * from './segmented-object/segmented-object.ts';
6 changes: 3 additions & 3 deletions src/namespace/nt-schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ export enum VerifyResult {
export interface NamespaceHandler {
get endpoint(): Endpoint | undefined;
get attachedPrefix(): Name | undefined;
getVerifier(deadline: number): Verifier;
getVerifier(deadline: number | undefined, verificationContext?: Record<string, unknown>): Verifier;
storeData(data: Data): Promise<void>;
}

Expand All @@ -42,14 +42,14 @@ export class NtSchema implements NamespaceHandler, AsyncDisposable {
return schemaTree.match(this.tree, name.slice(prefixLength));
}

public getVerifier(deadline: number): Verifier {
public getVerifier(deadline: number | undefined, verificationContext?: Record<string, unknown>): Verifier {
return {
verify: async (pkt: Verifier.Verifiable) => {
const matched = this.match(pkt.name);
if (!matched || !matched.resource) {
throw new Error('Unexpected packet');
}
if (!await schemaTree.call(matched, 'verifyPacket', pkt, deadline)) {
if (!await schemaTree.call(matched, 'verifyPacket', pkt, deadline, verificationContext ?? {})) {
throw new Error('Unverified packet');
}
},
Expand Down
2 changes: 1 addition & 1 deletion src/namespace/segmented-object/fetcher.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import * as Pattern from '../name-pattern.ts';
import * as Schema from '../schema-tree.ts';
// @deno-types="@ndn/segmented-object/lib/fetch/logic.d.ts"
import { FetchLogic } from '@ndn/segmented-object/lib/fetch/logic_browser.js';
import { LeafNode } from '../mod.ts';
import { LeafNode } from '../leaf-node.ts';
import { NNI } from '@ndn/tlv';
import { EventChain } from '../../utils/mod.ts';

Expand Down
6 changes: 3 additions & 3 deletions src/namespace/segmented-object/segmented-object.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import { NtSchema, VerifyResult } from '../nt-schema.ts';
import { InMemoryStorage } from '../../storage/mod.ts';
import { LeafNode } from '../leaf-node.ts';
import * as Tree from '../schema-tree.ts';
import { SegmentedObject } from './segmented-object.ts';
import { SegmentedObjectNode } from './segmented-object.ts';

export const b = ([value]: TemplateStringsArray) => new TextEncoder().encode(value);

Expand All @@ -32,7 +32,7 @@ Deno.test('SegmentedObject.1 Basic fetching', async () => {
return VerifyResult.Fail;
}
});
const segObjNode = schema.set('/object', SegmentedObject, {
const segObjNode = schema.set('/object', SegmentedObjectNode, {
leafNode,
lifetimeAfterRto: 100,
});
Expand Down Expand Up @@ -98,7 +98,7 @@ Deno.test('SegmentedObject.2 Basic provide', async () => {
return undefined;
}
});
const segObjNode = schema.set('/object', SegmentedObject, {
const segObjNode = schema.set('/object', SegmentedObjectNode, {
leafNode,
lifetimeAfterRto: 100,
});
Expand Down
8 changes: 4 additions & 4 deletions src/namespace/segmented-object/segmented-object.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import { EventIterator } from 'event-iterator';
import { BaseNode } from '../base-node.ts';
import * as Pattern from '../name-pattern.ts';
import * as Schema from '../schema-tree.ts';
import { LeafNode } from '../mod.ts';
import { LeafNode } from '../leaf-node.ts';
import { Fetcher, FetcherOptions, PipelineOptions } from './fetcher.ts';

export interface Result extends PromiseLike<Uint8Array>, AsyncIterable<Data> {
Expand Down Expand Up @@ -143,7 +143,7 @@ export type SegmentedObjectOpts = {
pipelineOpts?: PipelineOptions;
};

export class SegmentedObject extends BaseNode {
export class SegmentedObjectNode extends BaseNode {
lifetimeAfterRto: number;
segmentPattern: string;
segmentType: number;
Expand All @@ -163,7 +163,7 @@ export class SegmentedObject extends BaseNode {
}

public async provide(
matched: Schema.StrictMatch<SegmentedObject>,
matched: Schema.StrictMatch<SegmentedObjectNode>,
source: ChunkSource,
opts: {
freshnessMs?: number;
Expand All @@ -190,7 +190,7 @@ export class SegmentedObject extends BaseNode {
}

public need(
matched: Schema.StrictMatch<SegmentedObject>,
matched: Schema.StrictMatch<SegmentedObjectNode>,
opts: {
abortSignal?: AbortSignal;
lifetimeAfterRto?: number;
Expand Down
79 changes: 79 additions & 0 deletions src/namespace/sync/sync.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
import { Signer, Verifier } from '@ndn/packet';
import { StateVector, SvSync } from '@ndn/svs';
import { BaseNode } from '../base-node.ts';
import * as Schema from '../schema-tree.ts';
import { EventChain } from '../../utils/event-chain.ts';
import { ExpressingPointEvents } from '../expressing-point.ts';

export type SvsInstNodeEvents = Pick<ExpressingPointEvents, 'verify'>;

export type SvsInstNodeOpts = {
lifetimeMs?: number;
steadyTimerMs?: number;
suppressionTimerMs?: number;
interestSigner?: Signer;
};

/**
* SVS works more like a separated component from NTSchema, because
* it runs at some specific prefix(es) instead of a general pattern.
* Each SVS instance has its own state, and there is little to share.
*/
export class SvsInstNode extends BaseNode {
/** Verify Interest event. */
public readonly onVerify = new EventChain<SvsInstNodeEvents['verify']>();

constructor(
public readonly config: SvsInstNodeOpts,
describe?: string,
) {
super(describe);
}

public static readonly fireSvsInstance = (inst: SvSync) => {
(inst as unknown as { resetTimer: (immediate?: boolean) => void }).resetTimer(true);
};

public async createSvsInst(
matched: Schema.StrictMatch<SvsInstNode>,
opts: {
lifetimeMs?: number;
steadyTimerMs?: number;
suppressionTimerMs?: number;
signer?: Signer;
verifier?: Verifier;
initialStateVector?: StateVector;
initialize?: (sync: SvSync) => PromiseLike<void>;
} = {},
): Promise<SvSync> {
const signer = opts.signer ?? this.config.interestSigner;
const verifier = opts.verifier ?? this.handler!.getVerifier(undefined, {});
const lifetimeMs = opts.lifetimeMs ?? this.config.lifetimeMs;
if (!signer || !verifier || lifetimeMs === undefined) {
throw new Error(
`[${this.describe}:createSvsInst] Unable to create SVS instance when signer, ` +
`verifier or lifetimeMs is missing in config.`,
);
}
const steadyTimer = [opts.steadyTimerMs ?? this.config.steadyTimerMs ?? 30000, 0.1] satisfies SvSync.Timer;
const suppressionTimer = [
opts.suppressionTimerMs ?? this.config.suppressionTimerMs ?? 200,
0.5,
] satisfies SvSync.Timer;
const describe = this.describe ? `${this.describe}(${matched.name.toString()})` : undefined;

const ret = await SvSync.create({
endpoint: this.handler!.endpoint!,
syncPrefix: matched.name,
signer: signer,
verifier: verifier,
syncInterestLifetime: lifetimeMs,
steadyTimer: steadyTimer,
suppressionTimer: suppressionTimer,
describe: describe,
initialStateVector: new StateVector(opts.initialStateVector),
initialize: opts.initialize,
});
return ret;
}
}

0 comments on commit 76a0320

Please sign in to comment.