From 5030130aeff78bd40882a15f2447c7287036035c Mon Sep 17 00:00:00 2001 From: Tony Garnock-Jones Date: Mon, 6 Feb 2023 15:16:57 +0100 Subject: [PATCH] Update attenuations --- packages/core/src/runtime/actor.ts | 8 +++---- packages/core/src/runtime/rewrite.ts | 34 +++++++++++++++++---------- packages/core/src/transport/relay.ts | 4 ++-- packages/core/src/transport/sturdy.ts | 14 ++++++----- 4 files changed, 35 insertions(+), 25 deletions(-) diff --git a/packages/core/src/runtime/actor.ts b/packages/core/src/runtime/actor.ts index 8378ed9..0bda200 100644 --- a/packages/core/src/runtime/actor.ts +++ b/packages/core/src/runtime/actor.ts @@ -3,7 +3,7 @@ import { IdentitySet, Value, embeddedId, is, fromJS, stringify } from '@preserves/core'; import { Cell, Field, Graph } from './dataflow.js'; -import { Attenuation, runRewrites } from './rewrite.js'; +import { Caveat, runRewrites } from './rewrite.js'; import { queueTask } from './task.js'; export type AnyValue = Value; @@ -34,15 +34,15 @@ export type Cap = Ref; export interface Ref { readonly relay: Facet; readonly target: Partial; - readonly attenuation?: Attenuation; + readonly attenuation?: Caveat[]; } export class RefImpl implements Ref { readonly relay: Facet; readonly target: Partial; - readonly attenuation?: Attenuation; + readonly attenuation?: Caveat[]; - constructor(relay: Facet, target: Partial, attenuation?: Attenuation) { + constructor(relay: Facet, target: Partial, attenuation?: Caveat[]) { this.relay = relay; this.target = target; this.attenuation = attenuation; diff --git a/packages/core/src/runtime/rewrite.ts b/packages/core/src/runtime/rewrite.ts index c2acbc9..4c27c7b 100644 --- a/packages/core/src/runtime/rewrite.ts +++ b/packages/core/src/runtime/rewrite.ts @@ -8,7 +8,6 @@ import type { SturdyValue } from "../transport/sturdy.js"; import { Alts, - Attenuation, Caveat, Lit, PAnd, @@ -155,21 +154,30 @@ export function rewrite(r: Rewrite, v: Assertion): Assertion | null { } export function examineAlternatives(cav: Caveat, v: Assertion): Assertion | null { - if (cav._variant === 'Alts') { - for (const r of cav.value.alternatives) { - const w = rewrite(r, v); - if (w !== null) return w; + switch (cav._variant) { + case "Alts": { + for (const r of cav.value.alternatives) { + const w = rewrite(r, v); + if (w !== null) return w; + } + return null; } - return null; - } else { - return rewrite(cav.value, v); + case "Rewrite": + return rewrite(cav.value, v); + case "Reject": + return (match(cav.value.pattern, v) !== null) ? null : v; + case "unknown": + return null; + default: + ((_: never) => { throw new Error("bad caveat"); })(cav); } } -export function runRewrites(a: Attenuation | undefined, v: Assertion): Assertion | null { +export function runRewrites(a: Caveat[] | undefined, v: Assertion): Assertion | null { if (a !== void 0) { - for (const stage of a) { - const w = examineAlternatives(stage, v); + for (let i = a.length - 1; i >= 0; i--) { + const caveat = a[i]; + const w = examineAlternatives(caveat, v); if (w === null) return null; v = w; } @@ -185,9 +193,9 @@ export function rfilter(... patterns: Pattern[]): Caveat { return ps.length === 1 ? Caveat.Rewrite(ps[0]) : Caveat.Alts(Alts(ps)); } -export function attenuate(ref: Ref, ... a: Attenuation): Ref { +export function attenuate(ref: Ref, ... a: Caveat[]): Ref { if (a.length === 0) return ref; - return { ... ref, attenuation: [... a, ... (ref.attenuation ?? [])] }; + return { ... ref, attenuation: [... (ref.attenuation ?? []), ... a] }; } export function forwarder(ref: Ref): { proxy: Ref, revoker: Ref } { diff --git a/packages/core/src/transport/relay.ts b/packages/core/src/transport/relay.ts index 4922b1a..9f6bc64 100644 --- a/packages/core/src/transport/relay.ts +++ b/packages/core/src/transport/relay.ts @@ -7,7 +7,7 @@ import * as IO from '../gen/protocol.js'; import { wireRefEmbeddedType } from './protocol.js'; import { queueTask } from '../runtime/task.js'; import { attenuate } from '../runtime/rewrite.js'; -import { fromAttenuation, WireRef } from '../gen/sturdy.js'; +import { fromCaveat, WireRef } from '../gen/sturdy.js'; export class WireSymbol { count = 0; @@ -264,7 +264,7 @@ export class Relay { if (ar.__attenuations === void 0) { ar.__attenuations = new Dictionary(); } - return ar.__attenuations.getOrSet(fromAttenuation(n.attenuation), () => + return ar.__attenuations.getOrSet(n.attenuation.map(fromCaveat), () => attenuate(r, ... n.attenuation)); } } diff --git a/packages/core/src/transport/sturdy.ts b/packages/core/src/transport/sturdy.ts index 1a4a9df..146e7e6 100644 --- a/packages/core/src/transport/sturdy.ts +++ b/packages/core/src/transport/sturdy.ts @@ -45,17 +45,19 @@ export async function mint(oid: SturdyValue, secretKey: Bytes): Promise { +async function chainMac(key: Bytes | Promise, caveats: S.Caveat[]): Promise { + return caveats.reduce(async (key, c) => mac(await key, sturdyEncode(S.fromCaveat(c))), key); +} + +export async function attenuate(r: S.SturdyRef, ... a: S.Caveat[]): Promise { return S.SturdyRef({ oid: r.oid, - caveatChain: [... r.caveatChain, a], - sig: await mac(r.sig, sturdyEncode(S.fromAttenuation(a))) + caveatChain: [... r.caveatChain, ... a], + sig: await chainMac(r.sig, a), }); } export async function validate(r: S.SturdyRef, secretKey: Bytes): Promise { - const sig = await r.caveatChain.reduce( - async (sig, a) => mac(await sig, sturdyEncode(S.fromAttenuation(a))), - mac(secretKey, sturdyEncode(r.oid))); + const sig = await chainMac(await mac(secretKey, sturdyEncode(r.oid)), r.caveatChain); return is(sig, r.sig); }