@plane31/blind-relay 0.0.0-stage → 0.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +202 -0
- package/README.md +26 -2
- package/dist/adapters/index.d.ts +18 -0
- package/dist/adapters/index.d.ts.map +1 -0
- package/dist/adapters/index.js +22 -0
- package/dist/adapters/index.js.map +1 -0
- package/dist/audience.d.ts +77 -0
- package/dist/audience.d.ts.map +1 -0
- package/dist/audience.js +76 -0
- package/dist/audience.js.map +1 -0
- package/dist/bytes.d.ts +54 -0
- package/dist/bytes.d.ts.map +1 -0
- package/dist/bytes.js +200 -0
- package/dist/bytes.js.map +1 -0
- package/dist/circle.d.ts +59 -0
- package/dist/circle.d.ts.map +1 -0
- package/dist/circle.js +105 -0
- package/dist/circle.js.map +1 -0
- package/dist/client.d.ts +234 -0
- package/dist/client.d.ts.map +1 -0
- package/dist/client.js +1365 -0
- package/dist/client.js.map +1 -0
- package/dist/codec.d.ts +189 -0
- package/dist/codec.d.ts.map +1 -0
- package/dist/codec.js +512 -0
- package/dist/codec.js.map +1 -0
- package/dist/crypto/backend.d.ts +39 -0
- package/dist/crypto/backend.d.ts.map +1 -0
- package/dist/crypto/backend.js +8 -0
- package/dist/crypto/backend.js.map +1 -0
- package/dist/crypto/noble.d.ts +3 -0
- package/dist/crypto/noble.d.ts.map +1 -0
- package/dist/crypto/noble.js +107 -0
- package/dist/crypto/noble.js.map +1 -0
- package/dist/crypto/sodium.d.ts +9 -0
- package/dist/crypto/sodium.d.ts.map +1 -0
- package/dist/crypto/sodium.js +51 -0
- package/dist/crypto/sodium.js.map +1 -0
- package/dist/crypto.d.ts +66 -0
- package/dist/crypto.d.ts.map +1 -0
- package/dist/crypto.js +225 -0
- package/dist/crypto.js.map +1 -0
- package/dist/epoch.d.ts +93 -0
- package/dist/epoch.d.ts.map +1 -0
- package/dist/epoch.js +121 -0
- package/dist/epoch.js.map +1 -0
- package/dist/errors.d.ts +17 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +30 -0
- package/dist/errors.js.map +1 -0
- package/dist/historyIndex.d.ts +15 -0
- package/dist/historyIndex.d.ts.map +1 -0
- package/dist/historyIndex.js +57 -0
- package/dist/historyIndex.js.map +1 -0
- package/dist/identity.d.ts +62 -0
- package/dist/identity.d.ts.map +1 -0
- package/dist/identity.js +99 -0
- package/dist/identity.js.map +1 -0
- package/dist/inbox.d.ts +153 -0
- package/dist/inbox.d.ts.map +1 -0
- package/dist/inbox.js +472 -0
- package/dist/inbox.js.map +1 -0
- package/dist/index.d.ts +19 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +22 -0
- package/dist/index.js.map +1 -0
- package/dist/outbox.d.ts +96 -0
- package/dist/outbox.d.ts.map +1 -0
- package/dist/outbox.js +339 -0
- package/dist/outbox.js.map +1 -0
- package/dist/policy.d.ts +33 -0
- package/dist/policy.d.ts.map +1 -0
- package/dist/policy.js +71 -0
- package/dist/policy.js.map +1 -0
- package/dist/record.d.ts +49 -0
- package/dist/record.d.ts.map +1 -0
- package/dist/record.js +46 -0
- package/dist/record.js.map +1 -0
- package/dist/reset.d.ts +74 -0
- package/dist/reset.d.ts.map +1 -0
- package/dist/reset.js +127 -0
- package/dist/reset.js.map +1 -0
- package/dist/rows.d.ts +16 -0
- package/dist/rows.d.ts.map +1 -0
- package/dist/rows.js +103 -0
- package/dist/rows.js.map +1 -0
- package/dist/slots.d.ts +22 -0
- package/dist/slots.d.ts.map +1 -0
- package/dist/slots.js +38 -0
- package/dist/slots.js.map +1 -0
- package/dist/store.d.ts +357 -0
- package/dist/store.d.ts.map +1 -0
- package/dist/store.js +192 -0
- package/dist/store.js.map +1 -0
- package/dist/testing/clock.d.ts +14 -0
- package/dist/testing/clock.d.ts.map +1 -0
- package/dist/testing/clock.js +27 -0
- package/dist/testing/clock.js.map +1 -0
- package/dist/testing/fakeHost.d.ts +118 -0
- package/dist/testing/fakeHost.d.ts.map +1 -0
- package/dist/testing/fakeHost.js +462 -0
- package/dist/testing/fakeHost.js.map +1 -0
- package/dist/testing/faults.d.ts +97 -0
- package/dist/testing/faults.d.ts.map +1 -0
- package/dist/testing/faults.js +264 -0
- package/dist/testing/faults.js.map +1 -0
- package/dist/testing/fixtures.d.ts +15 -0
- package/dist/testing/fixtures.d.ts.map +1 -0
- package/dist/testing/fixtures.js +22 -0
- package/dist/testing/fixtures.js.map +1 -0
- package/dist/testing/index.d.ts +7 -0
- package/dist/testing/index.d.ts.map +1 -0
- package/dist/testing/index.js +7 -0
- package/dist/testing/index.js.map +1 -0
- package/dist/testing/providers.d.ts +16 -0
- package/dist/testing/providers.d.ts.map +1 -0
- package/dist/testing/providers.js +36 -0
- package/dist/testing/providers.js.map +1 -0
- package/dist/testing/sweep.d.ts +46 -0
- package/dist/testing/sweep.d.ts.map +1 -0
- package/dist/testing/sweep.js +366 -0
- package/dist/testing/sweep.js.map +1 -0
- package/dist/transactions.d.ts +75 -0
- package/dist/transactions.d.ts.map +1 -0
- package/dist/transactions.js +212 -0
- package/dist/transactions.js.map +1 -0
- package/dist/transport.d.ts +125 -0
- package/dist/transport.d.ts.map +1 -0
- package/dist/transport.js +6 -0
- package/dist/transport.js.map +1 -0
- package/dist/vault.d.ts +59 -0
- package/dist/vault.d.ts.map +1 -0
- package/dist/vault.js +69 -0
- package/dist/vault.js.map +1 -0
- package/package.json +67 -3
- package/src/adapters/index.ts +102 -0
- package/src/audience.ts +123 -0
- package/src/bytes.ts +209 -0
- package/src/circle.ts +127 -0
- package/src/client.ts +1442 -0
- package/src/codec.ts +642 -0
- package/src/crypto/backend.ts +48 -0
- package/src/crypto/noble.ts +104 -0
- package/src/crypto/node-module.d.ts +11 -0
- package/src/crypto/sodium.ts +53 -0
- package/src/crypto.ts +266 -0
- package/src/epoch.ts +201 -0
- package/src/errors.ts +78 -0
- package/src/historyIndex.ts +61 -0
- package/src/identity.ts +158 -0
- package/src/inbox.ts +560 -0
- package/src/index.ts +59 -0
- package/src/outbox.ts +385 -0
- package/src/policy.ts +88 -0
- package/src/record.ts +106 -0
- package/src/reset.ts +176 -0
- package/src/rows.ts +116 -0
- package/src/slots.ts +55 -0
- package/src/store.ts +557 -0
- package/src/testing/clock.ts +29 -0
- package/src/testing/fakeHost.ts +482 -0
- package/src/testing/faults.ts +321 -0
- package/src/testing/fixtures.ts +35 -0
- package/src/testing/index.ts +6 -0
- package/src/testing/providers.ts +39 -0
- package/src/testing/sweep.ts +407 -0
- package/src/transactions.ts +231 -0
- package/src/transport.ts +106 -0
- package/src/vault.ts +126 -0
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
import { type RecordKind } from "../codec.js";
|
|
2
|
+
import { type SigningKeypair } from "../crypto.js";
|
|
3
|
+
import type { AppendOutcome, JoinRequest, Transport } from "../transport.js";
|
|
4
|
+
interface Account {
|
|
5
|
+
accountName: string;
|
|
6
|
+
accountKey: Uint8Array;
|
|
7
|
+
identityId: string;
|
|
8
|
+
certificate: Uint8Array;
|
|
9
|
+
certificateHash: string;
|
|
10
|
+
generation: bigint;
|
|
11
|
+
deviceIds: Set<string>;
|
|
12
|
+
retiredCertificates: Set<string>;
|
|
13
|
+
vault: {
|
|
14
|
+
wire: Uint8Array;
|
|
15
|
+
revision: bigint;
|
|
16
|
+
hash: string;
|
|
17
|
+
} | undefined;
|
|
18
|
+
retiredIdentity: boolean;
|
|
19
|
+
previousIdentities: Set<string>;
|
|
20
|
+
resetReceipt: Uint8Array | undefined;
|
|
21
|
+
}
|
|
22
|
+
interface StoredRecord {
|
|
23
|
+
recordId: string;
|
|
24
|
+
wire: Uint8Array;
|
|
25
|
+
acceptedAt: bigint;
|
|
26
|
+
epoch: number;
|
|
27
|
+
counter: number;
|
|
28
|
+
kind: RecordKind;
|
|
29
|
+
required: Set<string>;
|
|
30
|
+
}
|
|
31
|
+
interface StreamState {
|
|
32
|
+
authorIdentityId: string;
|
|
33
|
+
accountName: string;
|
|
34
|
+
currentEpoch: number;
|
|
35
|
+
currentManifestHash: string | undefined;
|
|
36
|
+
epochs: Map<number, {
|
|
37
|
+
manifest: Uint8Array;
|
|
38
|
+
wraps: Map<string, Uint8Array>;
|
|
39
|
+
rows: {
|
|
40
|
+
identityId: string;
|
|
41
|
+
certificateHash: string;
|
|
42
|
+
}[];
|
|
43
|
+
}>;
|
|
44
|
+
records: Map<bigint, StoredRecord>;
|
|
45
|
+
tail: bigint;
|
|
46
|
+
expiredThrough: bigint;
|
|
47
|
+
lastAcceptedAt: bigint;
|
|
48
|
+
highWater: {
|
|
49
|
+
epoch: number;
|
|
50
|
+
counter: number;
|
|
51
|
+
} | undefined;
|
|
52
|
+
lastAppend: {
|
|
53
|
+
recordId: string;
|
|
54
|
+
hash: string;
|
|
55
|
+
seq: bigint;
|
|
56
|
+
at: bigint;
|
|
57
|
+
outcome: AppendOutcome;
|
|
58
|
+
} | undefined;
|
|
59
|
+
subscriptions: Map<string, {
|
|
60
|
+
identityId: string;
|
|
61
|
+
cursor: bigint;
|
|
62
|
+
startSeq: bigint;
|
|
63
|
+
}>;
|
|
64
|
+
}
|
|
65
|
+
export interface Notification {
|
|
66
|
+
kind: "joinRequest" | "leaveRequest" | "visible" | "wake";
|
|
67
|
+
to: string;
|
|
68
|
+
from: string;
|
|
69
|
+
circleId?: string;
|
|
70
|
+
}
|
|
71
|
+
export declare class FakeHost {
|
|
72
|
+
now: () => bigint;
|
|
73
|
+
deliveryWindowMs: bigint;
|
|
74
|
+
appendRetryWindowMs: bigint;
|
|
75
|
+
readonly accounts: Map<string, Account>;
|
|
76
|
+
readonly certificates: Map<string, Uint8Array<ArrayBufferLike>>;
|
|
77
|
+
readonly circles: Map<string, {
|
|
78
|
+
snapshot: Uint8Array;
|
|
79
|
+
revision: bigint;
|
|
80
|
+
hash: string;
|
|
81
|
+
ownerIdentityId: string;
|
|
82
|
+
closed: boolean;
|
|
83
|
+
}>;
|
|
84
|
+
readonly requests: Map<string, JoinRequest[]>;
|
|
85
|
+
readonly streams: Map<string, StreamState>;
|
|
86
|
+
readonly notifications: Notification[];
|
|
87
|
+
readonly receipts: Map<string, Uint8Array<ArrayBufferLike>>;
|
|
88
|
+
resetKeyList: Uint8Array | undefined;
|
|
89
|
+
resetSigner: {
|
|
90
|
+
key: SigningKeypair;
|
|
91
|
+
keyId: Uint8Array;
|
|
92
|
+
} | undefined;
|
|
93
|
+
/** Test switches. */
|
|
94
|
+
failAppends: boolean;
|
|
95
|
+
dropAppendResponses: boolean;
|
|
96
|
+
withholdSnapshots: boolean;
|
|
97
|
+
withholdEpochs: boolean;
|
|
98
|
+
appendCalls: number;
|
|
99
|
+
/** Every append the relay answered, in order: what the author's stream has been asked to accept. */
|
|
100
|
+
readonly appendLog: {
|
|
101
|
+
streamId: string;
|
|
102
|
+
recordId: string;
|
|
103
|
+
hash: string;
|
|
104
|
+
status: AppendOutcome["status"];
|
|
105
|
+
epoch: number;
|
|
106
|
+
counter: number;
|
|
107
|
+
}[];
|
|
108
|
+
accountByIdentity(iid: string): Account | undefined;
|
|
109
|
+
private stream;
|
|
110
|
+
/** The expiry alarm: delete the expired prefix and advance the watermark. */
|
|
111
|
+
expire(): void;
|
|
112
|
+
private purgeEpochs;
|
|
113
|
+
private collect;
|
|
114
|
+
retainedCount(streamId: Uint8Array): number;
|
|
115
|
+
asDevice(accountName: string, certificateHash: Uint8Array): Transport;
|
|
116
|
+
}
|
|
117
|
+
export {};
|
|
118
|
+
//# sourceMappingURL=fakeHost.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fakeHost.d.ts","sourceRoot":"","sources":["../../src/testing/fakeHost.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,462 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* An in-memory host: the directory and the cumulative-cursor relay of protocol sections 6, 10
|
|
3
|
+
* and 13, bound per caller device. It is the behavioural reference for the Worker in
|
|
4
|
+
* examples/host-worker and the test double for the client. Not a production server, and
|
|
5
|
+
* exported under `@plane31/blind-relay/testing` only.
|
|
6
|
+
*/
|
|
7
|
+
import { equalBytes, fromHex, toHex } from "../bytes.js";
|
|
8
|
+
import { DocumentType, buildResetReceipt, expectType, parseDocument, parseVaultHeader, verifyDocument } from "../codec.js";
|
|
9
|
+
import { bodyHash, identityId, streamId as deriveStreamId } from "../crypto.js";
|
|
10
|
+
export class FakeHost {
|
|
11
|
+
now = () => 0n;
|
|
12
|
+
deliveryWindowMs = 86400000n;
|
|
13
|
+
appendRetryWindowMs = 604800000n;
|
|
14
|
+
accounts = new Map();
|
|
15
|
+
certificates = new Map();
|
|
16
|
+
circles = new Map();
|
|
17
|
+
requests = new Map();
|
|
18
|
+
streams = new Map();
|
|
19
|
+
notifications = [];
|
|
20
|
+
receipts = new Map();
|
|
21
|
+
resetKeyList;
|
|
22
|
+
resetSigner;
|
|
23
|
+
/** Test switches. */
|
|
24
|
+
failAppends = false;
|
|
25
|
+
dropAppendResponses = false;
|
|
26
|
+
withholdSnapshots = false;
|
|
27
|
+
withholdEpochs = false;
|
|
28
|
+
appendCalls = 0;
|
|
29
|
+
/** Every append the relay answered, in order: what the author's stream has been asked to accept. */
|
|
30
|
+
appendLog = [];
|
|
31
|
+
// Helpers ---------------------------------------------------------------------------------------
|
|
32
|
+
accountByIdentity(iid) {
|
|
33
|
+
return [...this.accounts.values()].find((a) => a.identityId === iid);
|
|
34
|
+
}
|
|
35
|
+
stream(streamHex, authorIdentityId, accountName) {
|
|
36
|
+
let s = this.streams.get(streamHex);
|
|
37
|
+
if (!s) {
|
|
38
|
+
s = {
|
|
39
|
+
authorIdentityId,
|
|
40
|
+
accountName,
|
|
41
|
+
currentEpoch: 0,
|
|
42
|
+
currentManifestHash: undefined,
|
|
43
|
+
epochs: new Map(),
|
|
44
|
+
records: new Map(),
|
|
45
|
+
tail: 0n,
|
|
46
|
+
expiredThrough: 0n,
|
|
47
|
+
lastAcceptedAt: 0n,
|
|
48
|
+
highWater: undefined,
|
|
49
|
+
lastAppend: undefined,
|
|
50
|
+
subscriptions: new Map()
|
|
51
|
+
};
|
|
52
|
+
this.streams.set(streamHex, s);
|
|
53
|
+
}
|
|
54
|
+
return s;
|
|
55
|
+
}
|
|
56
|
+
/** The expiry alarm: delete the expired prefix and advance the watermark. */
|
|
57
|
+
expire() {
|
|
58
|
+
const now = this.now();
|
|
59
|
+
for (const s of this.streams.values()) {
|
|
60
|
+
for (const [seq, r] of [...s.records])
|
|
61
|
+
if (r.acceptedAt + this.deliveryWindowMs <= now)
|
|
62
|
+
s.records.delete(seq);
|
|
63
|
+
const retained = [...s.records.keys()].sort((a, b) => (a < b ? -1 : a > b ? 1 : 0));
|
|
64
|
+
s.expiredThrough = retained.length ? (retained[0] ?? 0n) - 1n : s.tail;
|
|
65
|
+
this.purgeEpochs(s);
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
purgeEpochs(s) {
|
|
69
|
+
const referenced = new Set([...s.records.values()].map((r) => r.epoch));
|
|
70
|
+
for (const e of [...s.epochs.keys()])
|
|
71
|
+
if (e !== s.currentEpoch && !referenced.has(e))
|
|
72
|
+
s.epochs.delete(e);
|
|
73
|
+
}
|
|
74
|
+
collect(s, upTo) {
|
|
75
|
+
for (const [seq, r] of [...s.records]) {
|
|
76
|
+
if (seq > upTo)
|
|
77
|
+
continue;
|
|
78
|
+
let done = true;
|
|
79
|
+
for (const cert of r.required) {
|
|
80
|
+
const sub = s.subscriptions.get(cert);
|
|
81
|
+
if (!sub || sub.cursor < seq) {
|
|
82
|
+
done = false;
|
|
83
|
+
break;
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
if (done)
|
|
87
|
+
s.records.delete(seq);
|
|
88
|
+
}
|
|
89
|
+
this.purgeEpochs(s);
|
|
90
|
+
}
|
|
91
|
+
retainedCount(streamId) {
|
|
92
|
+
return this.streams.get(toHex(streamId))?.records.size ?? 0;
|
|
93
|
+
}
|
|
94
|
+
// Transport per caller ---------------------------------------------------------------------------
|
|
95
|
+
asDevice(accountName, certificateHash) {
|
|
96
|
+
// eslint-disable-next-line @typescript-eslint/no-this-alias -- the transport closures outlive this call
|
|
97
|
+
const host = this;
|
|
98
|
+
const callerCert = toHex(certificateHash);
|
|
99
|
+
const caller = () => {
|
|
100
|
+
const a = host.accounts.get(accountName);
|
|
101
|
+
if (!a)
|
|
102
|
+
throw new Error("unknown account");
|
|
103
|
+
return a;
|
|
104
|
+
};
|
|
105
|
+
const current = () => caller().certificateHash === callerCert;
|
|
106
|
+
const directory = {
|
|
107
|
+
async resolveAccounts(names) {
|
|
108
|
+
return names.flatMap((n) => {
|
|
109
|
+
const a = host.accounts.get(n);
|
|
110
|
+
if (!a)
|
|
111
|
+
return [];
|
|
112
|
+
const r = { accountName: n, accountKey: a.accountKey, certificate: a.certificate };
|
|
113
|
+
return [a.resetReceipt ? { ...r, resetReceipt: a.resetReceipt } : r];
|
|
114
|
+
});
|
|
115
|
+
},
|
|
116
|
+
async resolveIdentities(identityIds) {
|
|
117
|
+
return identityIds.flatMap((iid) => {
|
|
118
|
+
const a = host.accountByIdentity(toHex(iid)) ?? [...host.accounts.values()].find((x) => x.previousIdentities.has(toHex(iid)));
|
|
119
|
+
if (!a)
|
|
120
|
+
return [];
|
|
121
|
+
const r = { accountName: a.accountName, accountKey: a.accountKey, certificate: a.certificate };
|
|
122
|
+
return [a.resetReceipt ? { ...r, resetReceipt: a.resetReceipt } : r];
|
|
123
|
+
});
|
|
124
|
+
},
|
|
125
|
+
async getCertificate(hash) {
|
|
126
|
+
return host.certificates.get(toHex(hash));
|
|
127
|
+
},
|
|
128
|
+
async registerAccount({ certificate, vault }) {
|
|
129
|
+
const doc = expectType(verifyDocument(certificate), DocumentType.AccountDevice);
|
|
130
|
+
const taken = host.accounts.get(doc.accountName);
|
|
131
|
+
if (taken)
|
|
132
|
+
return equalBytes(taken.certificate, certificate) ? { status: "ALREADY_COMMITTED" } : { status: "CONFLICT" };
|
|
133
|
+
const vh = parseVaultHeader(vault);
|
|
134
|
+
const iid = toHex(identityId(doc.accountName, doc.accountKey));
|
|
135
|
+
host.accounts.set(doc.accountName, {
|
|
136
|
+
accountName: doc.accountName,
|
|
137
|
+
accountKey: doc.accountKey,
|
|
138
|
+
identityId: iid,
|
|
139
|
+
certificate,
|
|
140
|
+
certificateHash: toHex(doc.bodyHash),
|
|
141
|
+
generation: doc.generation,
|
|
142
|
+
deviceIds: new Set([toHex(doc.deviceId)]),
|
|
143
|
+
retiredCertificates: new Set(),
|
|
144
|
+
vault: { wire: vault, revision: vh.vaultRevision, hash: toHex(vh.hash) },
|
|
145
|
+
retiredIdentity: false,
|
|
146
|
+
previousIdentities: new Set(),
|
|
147
|
+
resetReceipt: undefined
|
|
148
|
+
});
|
|
149
|
+
host.certificates.set(toHex(doc.bodyHash), certificate);
|
|
150
|
+
host.stream(toHex(deriveStreamId(fromHex(iid), doc.deviceId)), iid, doc.accountName);
|
|
151
|
+
return { status: "COMMITTED" };
|
|
152
|
+
},
|
|
153
|
+
async activateDevice(input) {
|
|
154
|
+
const a = host.accounts.get(input.accountName);
|
|
155
|
+
if (!a)
|
|
156
|
+
return { status: "UNAUTHORIZED" };
|
|
157
|
+
const doc = expectType(verifyDocument(input.newCertificate), DocumentType.AccountDevice);
|
|
158
|
+
if (toHex(doc.bodyHash) === a.certificateHash)
|
|
159
|
+
return { status: "ALREADY_COMMITTED" };
|
|
160
|
+
if (a.certificateHash !== toHex(input.expectedCertificateHash))
|
|
161
|
+
return { status: "CONFLICT", current: a.certificate };
|
|
162
|
+
if (!a.vault || a.vault.revision !== input.expectedVaultRevision || a.vault.hash !== toHex(input.expectedVaultHash))
|
|
163
|
+
return { status: "CONFLICT", current: a.vault?.wire, currentRevision: a.vault?.revision };
|
|
164
|
+
if (!equalBytes(doc.accountKey, a.accountKey) || doc.generation !== a.generation + 1n || a.deviceIds.has(toHex(doc.deviceId)))
|
|
165
|
+
return { status: "UNAUTHORIZED" };
|
|
166
|
+
const vh = parseVaultHeader(input.newVault);
|
|
167
|
+
a.retiredCertificates.add(a.certificateHash);
|
|
168
|
+
a.certificate = input.newCertificate;
|
|
169
|
+
a.certificateHash = toHex(doc.bodyHash);
|
|
170
|
+
a.generation = doc.generation;
|
|
171
|
+
a.deviceIds.add(toHex(doc.deviceId));
|
|
172
|
+
a.vault = { wire: input.newVault, revision: vh.vaultRevision, hash: toHex(vh.hash) };
|
|
173
|
+
host.certificates.set(a.certificateHash, input.newCertificate);
|
|
174
|
+
host.stream(toHex(deriveStreamId(fromHex(a.identityId), doc.deviceId)), a.identityId, a.accountName);
|
|
175
|
+
return { status: "COMMITTED" };
|
|
176
|
+
},
|
|
177
|
+
async getVault(name) {
|
|
178
|
+
return host.accounts.get(name)?.vault?.wire;
|
|
179
|
+
},
|
|
180
|
+
async publishVault({ expectedRevision, expectedHash, newVault }) {
|
|
181
|
+
const a = caller();
|
|
182
|
+
if (!current())
|
|
183
|
+
return { status: "UNAUTHORIZED" };
|
|
184
|
+
const vh = parseVaultHeader(newVault);
|
|
185
|
+
if (a.vault && (a.vault.revision !== expectedRevision || (expectedHash && a.vault.hash !== toHex(expectedHash)))) {
|
|
186
|
+
if (a.vault.hash === toHex(vh.hash))
|
|
187
|
+
return { status: "ALREADY_COMMITTED" };
|
|
188
|
+
return { status: "CONFLICT", current: a.vault.wire, currentRevision: a.vault.revision };
|
|
189
|
+
}
|
|
190
|
+
if (vh.vaultRevision !== expectedRevision + 1n)
|
|
191
|
+
return { status: "CONFLICT", current: a.vault?.wire, currentRevision: a.vault?.revision };
|
|
192
|
+
a.vault = { wire: newVault, revision: vh.vaultRevision, hash: toHex(vh.hash) };
|
|
193
|
+
return { status: "COMMITTED" };
|
|
194
|
+
},
|
|
195
|
+
async getCircle(circleId) {
|
|
196
|
+
if (host.withholdSnapshots)
|
|
197
|
+
return undefined;
|
|
198
|
+
const c = host.circles.get(toHex(circleId));
|
|
199
|
+
return c && !c.closed ? c.snapshot : undefined;
|
|
200
|
+
},
|
|
201
|
+
async publishOwnedCircle({ circleId, expectedRevision, expectedHash, newSnapshot }) {
|
|
202
|
+
const a = caller();
|
|
203
|
+
if (!current())
|
|
204
|
+
return { status: "UNAUTHORIZED" };
|
|
205
|
+
const doc = expectType(verifyDocument(newSnapshot, a.accountKey), DocumentType.CircleSnapshot);
|
|
206
|
+
if (toHex(doc.ownerIdentityId) !== a.identityId || !equalBytes(doc.circleId, circleId))
|
|
207
|
+
return { status: "UNAUTHORIZED" };
|
|
208
|
+
const key = toHex(circleId);
|
|
209
|
+
const existing = host.circles.get(key);
|
|
210
|
+
if (existing) {
|
|
211
|
+
if (existing.hash === toHex(doc.bodyHash))
|
|
212
|
+
return { status: "ALREADY_COMMITTED" };
|
|
213
|
+
if (existing.revision !== expectedRevision || (expectedHash && existing.hash !== toHex(expectedHash)) || doc.revision !== existing.revision + 1n) {
|
|
214
|
+
return { status: "CONFLICT", current: existing.snapshot, currentRevision: existing.revision };
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
else if (expectedRevision !== 0n || doc.revision !== 1n)
|
|
218
|
+
return { status: "CONFLICT" };
|
|
219
|
+
host.circles.set(key, { snapshot: newSnapshot, revision: doc.revision, hash: toHex(doc.bodyHash), ownerIdentityId: a.identityId, closed: false });
|
|
220
|
+
// Requests for accounts now admitted are cleared.
|
|
221
|
+
const members = new Set(doc.members.map(toHex));
|
|
222
|
+
host.requests.set(key, (host.requests.get(key) ?? []).filter((r) => !members.has(host.accounts.get(r.accountName)?.identityId ?? "")));
|
|
223
|
+
return { status: "COMMITTED" };
|
|
224
|
+
},
|
|
225
|
+
async requestJoin(circleId) {
|
|
226
|
+
const a = caller();
|
|
227
|
+
const c = host.circles.get(toHex(circleId));
|
|
228
|
+
if (!c)
|
|
229
|
+
return { status: "PERMANENT_FAILURE" };
|
|
230
|
+
const list = (host.requests.get(toHex(circleId)) ?? []).filter((r) => !(r.accountName === a.accountName && r.action === "join"));
|
|
231
|
+
// A repeated request refreshes the pending one; the owner is notified once per live request.
|
|
232
|
+
const hadLive = (host.requests.get(toHex(circleId)) ?? []).some((r) => r.accountName === a.accountName && r.action === "join" && r.requestedAt > host.now() - 7n * 86400000n);
|
|
233
|
+
list.push({ circleId, accountName: a.accountName, action: "join", requestedAt: host.now() });
|
|
234
|
+
host.requests.set(toHex(circleId), list);
|
|
235
|
+
if (!hadLive) {
|
|
236
|
+
const owner = host.accountByIdentity(c.ownerIdentityId);
|
|
237
|
+
if (owner)
|
|
238
|
+
host.notifications.push({ kind: "joinRequest", to: owner.accountName, from: a.accountName, circleId: toHex(circleId) });
|
|
239
|
+
}
|
|
240
|
+
return { status: "COMMITTED" };
|
|
241
|
+
},
|
|
242
|
+
async requestLeave(circleId) {
|
|
243
|
+
const a = caller();
|
|
244
|
+
const c = host.circles.get(toHex(circleId));
|
|
245
|
+
if (!c)
|
|
246
|
+
return { status: "PERMANENT_FAILURE" };
|
|
247
|
+
const list = host.requests.get(toHex(circleId)) ?? [];
|
|
248
|
+
list.push({ circleId, accountName: a.accountName, action: "leave", requestedAt: host.now() });
|
|
249
|
+
host.requests.set(toHex(circleId), list);
|
|
250
|
+
const owner = host.accountByIdentity(c.ownerIdentityId);
|
|
251
|
+
if (owner)
|
|
252
|
+
host.notifications.push({ kind: "leaveRequest", to: owner.accountName, from: a.accountName, circleId: toHex(circleId) });
|
|
253
|
+
return { status: "COMMITTED" };
|
|
254
|
+
},
|
|
255
|
+
async readRequests(circleId) {
|
|
256
|
+
const a = caller();
|
|
257
|
+
const c = host.circles.get(toHex(circleId));
|
|
258
|
+
if (!c || c.ownerIdentityId !== a.identityId)
|
|
259
|
+
return [];
|
|
260
|
+
const cutoff = host.now() - 7n * 86400000n;
|
|
261
|
+
return (host.requests.get(toHex(circleId)) ?? []).filter((r) => r.requestedAt > cutoff);
|
|
262
|
+
},
|
|
263
|
+
async getResetKeyList() {
|
|
264
|
+
return host.resetKeyList;
|
|
265
|
+
},
|
|
266
|
+
async getResetReceipt(resetId) {
|
|
267
|
+
return host.receipts.get(toHex(resetId));
|
|
268
|
+
},
|
|
269
|
+
async resetAccount(input) {
|
|
270
|
+
// The reset id answers first: a device whose response was lost retries after the account
|
|
271
|
+
// already carries the new identity, and must get its receipt, not UNAUTHORIZED.
|
|
272
|
+
const existing = host.receipts.get(toHex(input.resetId));
|
|
273
|
+
if (existing)
|
|
274
|
+
return { status: "ALREADY_COMMITTED", receipt: existing };
|
|
275
|
+
const a = host.accounts.get(input.accountName);
|
|
276
|
+
if (!a || a.identityId !== toHex(input.expectedOldIdentityId) || !host.resetSigner)
|
|
277
|
+
return { status: "UNAUTHORIZED" };
|
|
278
|
+
const doc = expectType(verifyDocument(input.newCertificate), DocumentType.AccountDevice);
|
|
279
|
+
const newIid = identityId(doc.accountName, doc.accountKey);
|
|
280
|
+
const receipt = buildResetReceipt({ accountName: input.accountName, oldIdentityId: input.expectedOldIdentityId, newIdentityId: newIid, resetId: input.resetId, issuedAt: host.now(), authorityKeyId: host.resetSigner.keyId }, host.resetSigner.key.secretKey);
|
|
281
|
+
host.receipts.set(toHex(input.resetId), receipt);
|
|
282
|
+
for (const c of host.circles.values())
|
|
283
|
+
if (c.ownerIdentityId === a.identityId)
|
|
284
|
+
c.closed = true;
|
|
285
|
+
const vh = parseVaultHeader(input.newVault);
|
|
286
|
+
a.previousIdentities.add(a.identityId);
|
|
287
|
+
a.resetReceipt = receipt;
|
|
288
|
+
a.retiredCertificates.add(a.certificateHash);
|
|
289
|
+
a.accountKey = doc.accountKey;
|
|
290
|
+
a.identityId = toHex(newIid);
|
|
291
|
+
a.certificate = input.newCertificate;
|
|
292
|
+
a.certificateHash = toHex(doc.bodyHash);
|
|
293
|
+
a.generation = doc.generation;
|
|
294
|
+
a.deviceIds.add(toHex(doc.deviceId));
|
|
295
|
+
a.vault = { wire: input.newVault, revision: vh.vaultRevision, hash: toHex(vh.hash) };
|
|
296
|
+
host.certificates.set(a.certificateHash, input.newCertificate);
|
|
297
|
+
host.stream(toHex(deriveStreamId(newIid, doc.deviceId)), a.identityId, a.accountName);
|
|
298
|
+
return { status: "COMMITTED", receipt };
|
|
299
|
+
}
|
|
300
|
+
};
|
|
301
|
+
const relay = {
|
|
302
|
+
async getCurrentEpoch(streamId) {
|
|
303
|
+
const s = host.streams.get(toHex(streamId));
|
|
304
|
+
if (!s || s.currentEpoch === 0 || !s.currentManifestHash)
|
|
305
|
+
return undefined;
|
|
306
|
+
return { epoch: s.currentEpoch, manifestHash: fromHex(s.currentManifestHash) };
|
|
307
|
+
},
|
|
308
|
+
async getEpoch(streamId, epoch) {
|
|
309
|
+
if (host.withholdEpochs)
|
|
310
|
+
return undefined;
|
|
311
|
+
const s = host.streams.get(toHex(streamId));
|
|
312
|
+
const e = s?.epochs.get(epoch);
|
|
313
|
+
if (!e)
|
|
314
|
+
return undefined;
|
|
315
|
+
return { manifest: e.manifest, wrap: e.wraps.get(caller().identityId) };
|
|
316
|
+
},
|
|
317
|
+
async publishEpoch({ streamId, expectedEpoch, manifest, wraps }) {
|
|
318
|
+
const a = caller();
|
|
319
|
+
const s = host.streams.get(toHex(streamId));
|
|
320
|
+
if (!s || s.authorIdentityId !== a.identityId)
|
|
321
|
+
return { status: "UNAUTHORIZED" };
|
|
322
|
+
if (!current())
|
|
323
|
+
return { status: "UNAUTHORIZED" };
|
|
324
|
+
const doc = expectType(parseDocument(manifest), DocumentType.EpochManifest);
|
|
325
|
+
const cur = s.epochs.get(s.currentEpoch);
|
|
326
|
+
if (doc.epoch === s.currentEpoch && cur && equalBytes(cur.manifest, manifest))
|
|
327
|
+
return { status: "ALREADY_COMMITTED" };
|
|
328
|
+
if (expectedEpoch !== s.currentEpoch || doc.epoch !== s.currentEpoch + 1) {
|
|
329
|
+
return { status: "CONFLICT", currentEpoch: s.currentEpoch, currentManifest: cur?.manifest };
|
|
330
|
+
}
|
|
331
|
+
const rows = doc.audience.map((r) => ({ identityId: toHex(r.identityId), certificateHash: toHex(r.certificateHash) }));
|
|
332
|
+
s.epochs.set(doc.epoch, { manifest, wraps: new Map(wraps), rows });
|
|
333
|
+
s.currentEpoch = doc.epoch;
|
|
334
|
+
s.currentManifestHash = toHex(doc.bodyHash);
|
|
335
|
+
for (const r of rows) {
|
|
336
|
+
if (r.identityId === a.identityId)
|
|
337
|
+
continue;
|
|
338
|
+
if (!s.subscriptions.has(r.certificateHash))
|
|
339
|
+
s.subscriptions.set(r.certificateHash, { identityId: r.identityId, cursor: s.tail, startSeq: s.tail });
|
|
340
|
+
}
|
|
341
|
+
host.purgeEpochs(s);
|
|
342
|
+
return { status: "COMMITTED" };
|
|
343
|
+
},
|
|
344
|
+
appendRecord(recordId, wire) {
|
|
345
|
+
host.appendCalls++;
|
|
346
|
+
if (host.failAppends)
|
|
347
|
+
throw new Error("transport down");
|
|
348
|
+
const run = () => {
|
|
349
|
+
const a = caller();
|
|
350
|
+
const rec = expectType(parseDocument(wire), DocumentType.EncryptedRecord);
|
|
351
|
+
const s = host.streams.get(toHex(rec.streamId));
|
|
352
|
+
if (!s || s.authorIdentityId !== a.identityId)
|
|
353
|
+
return { status: "UNAUTHORIZED" };
|
|
354
|
+
if (!current())
|
|
355
|
+
return { status: "SUPERSEDED_DEVICE" };
|
|
356
|
+
const id = toHex(recordId);
|
|
357
|
+
const hash = toHex(bodyHash(wire)); // exact bytes, signature included
|
|
358
|
+
// Checkpoint first, then the epoch fence.
|
|
359
|
+
if (s.lastAppend && s.lastAppend.recordId === id) {
|
|
360
|
+
if (s.lastAppend.hash !== hash)
|
|
361
|
+
return { status: "EQUIVOCATION" };
|
|
362
|
+
if (s.lastAppend.at + host.appendRetryWindowMs > host.now())
|
|
363
|
+
return { status: "ALREADY_ACCEPTED", deliverySeq: s.lastAppend.seq };
|
|
364
|
+
}
|
|
365
|
+
const retained = [...s.records.values()].find((r) => r.recordId === id);
|
|
366
|
+
if (retained)
|
|
367
|
+
return hash === toHex(bodyHash(retained.wire)) ? { status: "ALREADY_ACCEPTED" } : { status: "EQUIVOCATION" };
|
|
368
|
+
if (s.highWater && (rec.epoch < s.highWater.epoch || (rec.epoch === s.highWater.epoch && rec.counter <= s.highWater.counter)))
|
|
369
|
+
return { status: "STALE_APPEND" };
|
|
370
|
+
if (rec.epoch !== s.currentEpoch)
|
|
371
|
+
return rec.epoch < s.currentEpoch ? { status: "EPOCH_FENCED" } : { status: "UNAUTHORIZED" };
|
|
372
|
+
const epoch = s.epochs.get(rec.epoch);
|
|
373
|
+
if (!epoch)
|
|
374
|
+
return { status: "UNAUTHORIZED" };
|
|
375
|
+
const seq = ++s.tail;
|
|
376
|
+
const acceptedAt = host.now() > s.lastAcceptedAt ? host.now() : s.lastAcceptedAt;
|
|
377
|
+
s.lastAcceptedAt = acceptedAt;
|
|
378
|
+
const required = new Set(epoch.rows.filter((r) => r.identityId !== a.identityId).map((r) => r.certificateHash));
|
|
379
|
+
s.records.set(seq, { recordId: id, wire, acceptedAt, epoch: rec.epoch, counter: rec.counter, kind: rec.headerClass, required });
|
|
380
|
+
s.highWater = { epoch: rec.epoch, counter: rec.counter };
|
|
381
|
+
const outcome = { status: "ACCEPTED", deliverySeq: seq };
|
|
382
|
+
s.lastAppend = { recordId: id, hash, seq, at: acceptedAt, outcome };
|
|
383
|
+
for (const r of epoch.rows) {
|
|
384
|
+
if (r.identityId === a.identityId)
|
|
385
|
+
continue;
|
|
386
|
+
const to = host.accountByIdentity(r.identityId)?.accountName ?? r.identityId;
|
|
387
|
+
// By header class, as the test profile declares them: 1 is a visible notification, 2 is
|
|
388
|
+
// silent and needs no wake-up, anything else is a wake-up. The host never sees the kind.
|
|
389
|
+
if (rec.headerClass !== 2)
|
|
390
|
+
host.notifications.push({ kind: rec.headerClass === 1 ? "visible" : "wake", to, from: a.accountName });
|
|
391
|
+
}
|
|
392
|
+
if (required.size === 0)
|
|
393
|
+
s.records.delete(seq);
|
|
394
|
+
return outcome;
|
|
395
|
+
};
|
|
396
|
+
const result = run();
|
|
397
|
+
try {
|
|
398
|
+
const rec = expectType(parseDocument(wire), DocumentType.EncryptedRecord);
|
|
399
|
+
host.appendLog.push({ streamId: toHex(rec.streamId), recordId: toHex(recordId), hash: toHex(bodyHash(wire)), status: result.status, epoch: rec.epoch, counter: rec.counter });
|
|
400
|
+
}
|
|
401
|
+
catch {
|
|
402
|
+
/* unparsable wires are refused above */
|
|
403
|
+
}
|
|
404
|
+
if (host.dropAppendResponses)
|
|
405
|
+
return new Promise((_, reject) => reject(new Error("response lost")));
|
|
406
|
+
return Promise.resolve(result);
|
|
407
|
+
},
|
|
408
|
+
async readRecords(streamId, afterSeq, limit) {
|
|
409
|
+
const s = host.streams.get(toHex(streamId));
|
|
410
|
+
if (!s)
|
|
411
|
+
return { records: [], nextSeq: afterSeq, tail: 0n, expiredThrough: 0n, committedCursor: 0n };
|
|
412
|
+
if (afterSeq > s.tail)
|
|
413
|
+
throw new Error("CURSOR_OUT_OF_RANGE");
|
|
414
|
+
const sub = s.subscriptions.get(callerCert);
|
|
415
|
+
if (!sub)
|
|
416
|
+
return { records: [], nextSeq: s.tail, tail: s.tail, expiredThrough: s.expiredThrough, committedCursor: 0n };
|
|
417
|
+
let scan = afterSeq;
|
|
418
|
+
if (sub.cursor > scan)
|
|
419
|
+
scan = sub.cursor;
|
|
420
|
+
if (s.expiredThrough > scan)
|
|
421
|
+
scan = s.expiredThrough;
|
|
422
|
+
const records = [];
|
|
423
|
+
let next = scan;
|
|
424
|
+
for (let seq = scan + 1n; seq <= s.tail; seq++) {
|
|
425
|
+
const r = s.records.get(seq);
|
|
426
|
+
if (r && r.required.has(callerCert)) {
|
|
427
|
+
if (records.length >= limit)
|
|
428
|
+
break;
|
|
429
|
+
records.push({ deliverySeq: seq, wire: r.wire });
|
|
430
|
+
}
|
|
431
|
+
next = seq;
|
|
432
|
+
}
|
|
433
|
+
return { records, nextSeq: next, tail: s.tail, expiredThrough: s.expiredThrough, committedCursor: sub.cursor };
|
|
434
|
+
},
|
|
435
|
+
async ackThrough(streamId, cursor) {
|
|
436
|
+
const s = host.streams.get(toHex(streamId));
|
|
437
|
+
const sub = s?.subscriptions.get(callerCert);
|
|
438
|
+
if (!s || !sub)
|
|
439
|
+
return { status: "UNAUTHORIZED" };
|
|
440
|
+
if (cursor > s.tail)
|
|
441
|
+
return { status: "CURSOR_OUT_OF_RANGE" };
|
|
442
|
+
if (cursor > sub.cursor) {
|
|
443
|
+
sub.cursor = cursor;
|
|
444
|
+
host.collect(s, cursor);
|
|
445
|
+
}
|
|
446
|
+
return { status: "COMMITTED", committedCursor: sub.cursor };
|
|
447
|
+
},
|
|
448
|
+
async listSubscriptions() {
|
|
449
|
+
const out = [];
|
|
450
|
+
for (const [sid, s] of host.streams)
|
|
451
|
+
if (s.subscriptions.has(callerCert))
|
|
452
|
+
out.push({ streamId: fromHex(sid), authorIdentityId: fromHex(s.authorIdentityId) });
|
|
453
|
+
return out;
|
|
454
|
+
}
|
|
455
|
+
};
|
|
456
|
+
return {
|
|
457
|
+
directory,
|
|
458
|
+
relay
|
|
459
|
+
};
|
|
460
|
+
}
|
|
461
|
+
}
|
|
462
|
+
//# sourceMappingURL=fakeHost.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fakeHost.js","sourceRoot":"","sources":["../../src/testing/fakeHost.ts"],"names":[],"mappings":"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"}
|