Update attenuations
This commit is contained in:
parent
93fcebc4ce
commit
5030130aef
|
@ -3,7 +3,7 @@
|
||||||
|
|
||||||
import { IdentitySet, Value, embeddedId, is, fromJS, stringify } from '@preserves/core';
|
import { IdentitySet, Value, embeddedId, is, fromJS, stringify } from '@preserves/core';
|
||||||
import { Cell, Field, Graph } from './dataflow.js';
|
import { Cell, Field, Graph } from './dataflow.js';
|
||||||
import { Attenuation, runRewrites } from './rewrite.js';
|
import { Caveat, runRewrites } from './rewrite.js';
|
||||||
import { queueTask } from './task.js';
|
import { queueTask } from './task.js';
|
||||||
|
|
||||||
export type AnyValue = Value<Ref>;
|
export type AnyValue = Value<Ref>;
|
||||||
|
@ -34,15 +34,15 @@ export type Cap = Ref;
|
||||||
export interface Ref {
|
export interface Ref {
|
||||||
readonly relay: Facet;
|
readonly relay: Facet;
|
||||||
readonly target: Partial<Entity>;
|
readonly target: Partial<Entity>;
|
||||||
readonly attenuation?: Attenuation;
|
readonly attenuation?: Caveat[];
|
||||||
}
|
}
|
||||||
|
|
||||||
export class RefImpl implements Ref {
|
export class RefImpl implements Ref {
|
||||||
readonly relay: Facet;
|
readonly relay: Facet;
|
||||||
readonly target: Partial<Entity>;
|
readonly target: Partial<Entity>;
|
||||||
readonly attenuation?: Attenuation;
|
readonly attenuation?: Caveat[];
|
||||||
|
|
||||||
constructor(relay: Facet, target: Partial<Entity>, attenuation?: Attenuation) {
|
constructor(relay: Facet, target: Partial<Entity>, attenuation?: Caveat[]) {
|
||||||
this.relay = relay;
|
this.relay = relay;
|
||||||
this.target = target;
|
this.target = target;
|
||||||
this.attenuation = attenuation;
|
this.attenuation = attenuation;
|
||||||
|
|
|
@ -8,7 +8,6 @@ import type { SturdyValue } from "../transport/sturdy.js";
|
||||||
|
|
||||||
import {
|
import {
|
||||||
Alts,
|
Alts,
|
||||||
Attenuation,
|
|
||||||
Caveat,
|
Caveat,
|
||||||
Lit,
|
Lit,
|
||||||
PAnd,
|
PAnd,
|
||||||
|
@ -155,21 +154,30 @@ export function rewrite(r: Rewrite, v: Assertion): Assertion | null {
|
||||||
}
|
}
|
||||||
|
|
||||||
export function examineAlternatives(cav: Caveat, v: Assertion): Assertion | null {
|
export function examineAlternatives(cav: Caveat, v: Assertion): Assertion | null {
|
||||||
if (cav._variant === 'Alts') {
|
switch (cav._variant) {
|
||||||
for (const r of cav.value.alternatives) {
|
case "Alts": {
|
||||||
const w = rewrite(r, v);
|
for (const r of cav.value.alternatives) {
|
||||||
if (w !== null) return w;
|
const w = rewrite(r, v);
|
||||||
|
if (w !== null) return w;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
return null;
|
case "Rewrite":
|
||||||
} else {
|
return rewrite(cav.value, v);
|
||||||
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) {
|
if (a !== void 0) {
|
||||||
for (const stage of a) {
|
for (let i = a.length - 1; i >= 0; i--) {
|
||||||
const w = examineAlternatives(stage, v);
|
const caveat = a[i];
|
||||||
|
const w = examineAlternatives(caveat, v);
|
||||||
if (w === null) return null;
|
if (w === null) return null;
|
||||||
v = w;
|
v = w;
|
||||||
}
|
}
|
||||||
|
@ -185,9 +193,9 @@ export function rfilter(... patterns: Pattern[]): Caveat {
|
||||||
return ps.length === 1 ? Caveat.Rewrite(ps[0]) : Caveat.Alts(Alts(ps));
|
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;
|
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 } {
|
export function forwarder(ref: Ref): { proxy: Ref, revoker: Ref } {
|
||||||
|
|
|
@ -7,7 +7,7 @@ import * as IO from '../gen/protocol.js';
|
||||||
import { wireRefEmbeddedType } from './protocol.js';
|
import { wireRefEmbeddedType } from './protocol.js';
|
||||||
import { queueTask } from '../runtime/task.js';
|
import { queueTask } from '../runtime/task.js';
|
||||||
import { attenuate } from '../runtime/rewrite.js';
|
import { attenuate } from '../runtime/rewrite.js';
|
||||||
import { fromAttenuation, WireRef } from '../gen/sturdy.js';
|
import { fromCaveat, WireRef } from '../gen/sturdy.js';
|
||||||
|
|
||||||
export class WireSymbol {
|
export class WireSymbol {
|
||||||
count = 0;
|
count = 0;
|
||||||
|
@ -264,7 +264,7 @@ export class Relay {
|
||||||
if (ar.__attenuations === void 0) {
|
if (ar.__attenuations === void 0) {
|
||||||
ar.__attenuations = new Dictionary();
|
ar.__attenuations = new Dictionary();
|
||||||
}
|
}
|
||||||
return ar.__attenuations.getOrSet(fromAttenuation(n.attenuation), () =>
|
return ar.__attenuations.getOrSet(n.attenuation.map(fromCaveat), () =>
|
||||||
attenuate(r, ... n.attenuation));
|
attenuate(r, ... n.attenuation));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -45,17 +45,19 @@ export async function mint(oid: SturdyValue, secretKey: Bytes): Promise<S.Sturdy
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function attenuate(r: S.SturdyRef, ... a: S.Attenuation): Promise<S.SturdyRef> {
|
async function chainMac(key: Bytes | Promise<Bytes>, caveats: S.Caveat[]): Promise<Bytes> {
|
||||||
|
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<S.SturdyRef> {
|
||||||
return S.SturdyRef({
|
return S.SturdyRef({
|
||||||
oid: r.oid,
|
oid: r.oid,
|
||||||
caveatChain: [... r.caveatChain, a],
|
caveatChain: [... r.caveatChain, ... a],
|
||||||
sig: await mac(r.sig, sturdyEncode(S.fromAttenuation(a)))
|
sig: await chainMac(r.sig, a),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function validate(r: S.SturdyRef, secretKey: Bytes): Promise<boolean> {
|
export async function validate(r: S.SturdyRef, secretKey: Bytes): Promise<boolean> {
|
||||||
const sig = await r.caveatChain.reduce(
|
const sig = await chainMac(await mac(secretKey, sturdyEncode(r.oid)), r.caveatChain);
|
||||||
async (sig, a) => mac(await sig, sturdyEncode(S.fromAttenuation(a))),
|
|
||||||
mac(secretKey, sturdyEncode(r.oid)));
|
|
||||||
return is(sig, r.sig);
|
return is(sig, r.sig);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue