cojson 0.17.9 → 0.17.11
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/.turbo/turbo-build.log +1 -1
- package/CHANGELOG.md +18 -0
- package/dist/coValueCore/SessionMap.d.ts +45 -0
- package/dist/coValueCore/SessionMap.d.ts.map +1 -0
- package/dist/coValueCore/SessionMap.js +118 -0
- package/dist/coValueCore/SessionMap.js.map +1 -0
- package/dist/coValueCore/coValueCore.d.ts +10 -4
- package/dist/coValueCore/coValueCore.d.ts.map +1 -1
- package/dist/coValueCore/coValueCore.js +55 -68
- package/dist/coValueCore/coValueCore.js.map +1 -1
- package/dist/coValueCore/verifiedState.d.ts +15 -19
- package/dist/coValueCore/verifiedState.d.ts.map +1 -1
- package/dist/coValueCore/verifiedState.js +24 -87
- package/dist/coValueCore/verifiedState.js.map +1 -1
- package/dist/coValues/account.d.ts +4 -0
- package/dist/coValues/account.d.ts.map +1 -1
- package/dist/coValues/account.js +24 -4
- package/dist/coValues/account.js.map +1 -1
- package/dist/coValues/group.d.ts.map +1 -1
- package/dist/coValues/group.js +6 -2
- package/dist/coValues/group.js.map +1 -1
- package/dist/crypto/PureJSCrypto.d.ts +31 -3
- package/dist/crypto/PureJSCrypto.d.ts.map +1 -1
- package/dist/crypto/PureJSCrypto.js +115 -0
- package/dist/crypto/PureJSCrypto.js.map +1 -1
- package/dist/crypto/WasmCrypto.d.ts +23 -4
- package/dist/crypto/WasmCrypto.d.ts.map +1 -1
- package/dist/crypto/WasmCrypto.js +44 -2
- package/dist/crypto/WasmCrypto.js.map +1 -1
- package/dist/crypto/crypto.d.ts +17 -1
- package/dist/crypto/crypto.d.ts.map +1 -1
- package/dist/crypto/crypto.js.map +1 -1
- package/dist/localNode.d.ts +1 -0
- package/dist/localNode.d.ts.map +1 -1
- package/dist/localNode.js +10 -5
- package/dist/localNode.js.map +1 -1
- package/dist/permissions.d.ts +17 -1
- package/dist/permissions.d.ts.map +1 -1
- package/dist/permissions.js.map +1 -1
- package/dist/sync.d.ts.map +1 -1
- package/dist/sync.js +55 -49
- package/dist/sync.js.map +1 -1
- package/dist/tests/PureJSCrypto.test.d.ts +2 -0
- package/dist/tests/PureJSCrypto.test.d.ts.map +1 -0
- package/dist/tests/PureJSCrypto.test.js +102 -0
- package/dist/tests/PureJSCrypto.test.js.map +1 -0
- package/dist/tests/WasmCrypto.test.d.ts +2 -0
- package/dist/tests/WasmCrypto.test.d.ts.map +1 -0
- package/dist/tests/WasmCrypto.test.js +88 -0
- package/dist/tests/WasmCrypto.test.js.map +1 -0
- package/dist/tests/coValueCore.test.js +62 -187
- package/dist/tests/coValueCore.test.js.map +1 -1
- package/dist/tests/coreWasm.test.d.ts +2 -0
- package/dist/tests/coreWasm.test.d.ts.map +1 -0
- package/dist/tests/coreWasm.test.js +80 -0
- package/dist/tests/coreWasm.test.js.map +1 -0
- package/dist/tests/group.addMember.test.js +6 -11
- package/dist/tests/group.addMember.test.js.map +1 -1
- package/dist/tests/sync.load.test.js +40 -1
- package/dist/tests/sync.load.test.js.map +1 -1
- package/dist/tests/sync.test.js +1 -1
- package/dist/tests/sync.test.js.map +1 -1
- package/dist/tests/testUtils.d.ts +3 -0
- package/dist/tests/testUtils.d.ts.map +1 -1
- package/dist/tests/testUtils.js +4 -1
- package/dist/tests/testUtils.js.map +1 -1
- package/package.json +3 -3
- package/src/coValueCore/SessionMap.ts +229 -0
- package/src/coValueCore/coValueCore.ts +106 -121
- package/src/coValueCore/verifiedState.ts +61 -132
- package/src/coValues/account.ts +28 -4
- package/src/coValues/group.ts +10 -2
- package/src/crypto/PureJSCrypto.ts +206 -2
- package/src/crypto/WasmCrypto.ts +95 -4
- package/src/crypto/crypto.ts +38 -1
- package/src/localNode.ts +18 -10
- package/src/permissions.ts +17 -1
- package/src/sync.ts +63 -59
- package/src/tests/PureJSCrypto.test.ts +153 -0
- package/src/tests/WasmCrypto.test.ts +128 -0
- package/src/tests/coValueCore.test.ts +81 -293
- package/src/tests/coreWasm.test.ts +142 -0
- package/src/tests/group.addMember.test.ts +69 -63
- package/src/tests/sync.load.test.ts +52 -0
- package/src/tests/sync.test.ts +0 -2
- package/src/tests/testUtils.ts +9 -1
|
@@ -0,0 +1,229 @@
|
|
|
1
|
+
import { Result, err, ok } from "neverthrow";
|
|
2
|
+
import { ControlledAccountOrAgent } from "../coValues/account.js";
|
|
3
|
+
import type {
|
|
4
|
+
CryptoProvider,
|
|
5
|
+
Hash,
|
|
6
|
+
KeyID,
|
|
7
|
+
KeySecret,
|
|
8
|
+
SessionLogImpl,
|
|
9
|
+
Signature,
|
|
10
|
+
SignerID,
|
|
11
|
+
} from "../crypto/crypto.js";
|
|
12
|
+
import { RawCoID, SessionID } from "../ids.js";
|
|
13
|
+
import { parseJSON, stableStringify, Stringified } from "../jsonStringify.js";
|
|
14
|
+
import { JsonValue } from "../jsonValue.js";
|
|
15
|
+
import { CoValueKnownState } from "../sync.js";
|
|
16
|
+
import { TryAddTransactionsError } from "./coValueCore.js";
|
|
17
|
+
import { Transaction } from "./verifiedState.js";
|
|
18
|
+
import { exceedsRecommendedSize } from "../coValueContentMessage.js";
|
|
19
|
+
|
|
20
|
+
export type SessionLog = {
|
|
21
|
+
signerID?: SignerID;
|
|
22
|
+
impl: SessionLogImpl;
|
|
23
|
+
transactions: Transaction[];
|
|
24
|
+
lastSignature: Signature | undefined;
|
|
25
|
+
signatureAfter: { [txIdx: number]: Signature | undefined };
|
|
26
|
+
txSizeSinceLastInbetweenSignature: number;
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
export class SessionMap {
|
|
30
|
+
sessions: Map<SessionID, SessionLog> = new Map();
|
|
31
|
+
|
|
32
|
+
constructor(
|
|
33
|
+
private readonly id: RawCoID,
|
|
34
|
+
private readonly crypto: CryptoProvider,
|
|
35
|
+
) {}
|
|
36
|
+
|
|
37
|
+
get(sessionID: SessionID): SessionLog | undefined {
|
|
38
|
+
return this.sessions.get(sessionID);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
private getOrCreateSessionLog(
|
|
42
|
+
sessionID: SessionID,
|
|
43
|
+
signerID?: SignerID,
|
|
44
|
+
): SessionLog {
|
|
45
|
+
let sessionLog = this.sessions.get(sessionID);
|
|
46
|
+
if (!sessionLog) {
|
|
47
|
+
sessionLog = {
|
|
48
|
+
signerID,
|
|
49
|
+
impl: this.crypto.createSessionLog(this.id, sessionID, signerID),
|
|
50
|
+
transactions: [],
|
|
51
|
+
lastSignature: undefined,
|
|
52
|
+
signatureAfter: {},
|
|
53
|
+
txSizeSinceLastInbetweenSignature: 0,
|
|
54
|
+
};
|
|
55
|
+
this.sessions.set(sessionID, sessionLog);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
return sessionLog;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
signerID: SignerID | undefined;
|
|
62
|
+
addTransaction(
|
|
63
|
+
sessionID: SessionID,
|
|
64
|
+
signerID: SignerID | undefined,
|
|
65
|
+
newTransactions: Transaction[],
|
|
66
|
+
newSignature: Signature,
|
|
67
|
+
skipVerify: boolean = false,
|
|
68
|
+
): Result<true, TryAddTransactionsError> {
|
|
69
|
+
const sessionLog = this.getOrCreateSessionLog(sessionID, signerID);
|
|
70
|
+
|
|
71
|
+
try {
|
|
72
|
+
sessionLog.impl.tryAdd(newTransactions, newSignature, skipVerify);
|
|
73
|
+
|
|
74
|
+
this.addTransactionsToJsLog(sessionLog, newTransactions, newSignature);
|
|
75
|
+
|
|
76
|
+
return ok(true as const);
|
|
77
|
+
} catch (e) {
|
|
78
|
+
return err({
|
|
79
|
+
type: "InvalidSignature",
|
|
80
|
+
id: this.id,
|
|
81
|
+
sessionID,
|
|
82
|
+
newSignature,
|
|
83
|
+
signerID,
|
|
84
|
+
} satisfies TryAddTransactionsError);
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
makeNewPrivateTransaction(
|
|
89
|
+
sessionID: SessionID,
|
|
90
|
+
signerAgent: ControlledAccountOrAgent,
|
|
91
|
+
changes: JsonValue[],
|
|
92
|
+
keyID: KeyID,
|
|
93
|
+
keySecret: KeySecret,
|
|
94
|
+
): { signature: Signature; transaction: Transaction } {
|
|
95
|
+
const sessionLog = this.getOrCreateSessionLog(
|
|
96
|
+
sessionID,
|
|
97
|
+
signerAgent.currentSignerID(),
|
|
98
|
+
);
|
|
99
|
+
const madeAt = Date.now();
|
|
100
|
+
|
|
101
|
+
const result = sessionLog.impl.addNewPrivateTransaction(
|
|
102
|
+
signerAgent,
|
|
103
|
+
changes,
|
|
104
|
+
keyID,
|
|
105
|
+
keySecret,
|
|
106
|
+
madeAt,
|
|
107
|
+
);
|
|
108
|
+
|
|
109
|
+
this.addTransactionsToJsLog(
|
|
110
|
+
sessionLog,
|
|
111
|
+
[result.transaction],
|
|
112
|
+
result.signature,
|
|
113
|
+
);
|
|
114
|
+
|
|
115
|
+
return result;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
makeNewTrustingTransaction(
|
|
119
|
+
sessionID: SessionID,
|
|
120
|
+
signerAgent: ControlledAccountOrAgent,
|
|
121
|
+
changes: JsonValue[],
|
|
122
|
+
): { signature: Signature; transaction: Transaction } {
|
|
123
|
+
const sessionLog = this.getOrCreateSessionLog(
|
|
124
|
+
sessionID,
|
|
125
|
+
signerAgent.currentSignerID(),
|
|
126
|
+
);
|
|
127
|
+
const madeAt = Date.now();
|
|
128
|
+
|
|
129
|
+
const result = sessionLog.impl.addNewTrustingTransaction(
|
|
130
|
+
signerAgent,
|
|
131
|
+
changes,
|
|
132
|
+
madeAt,
|
|
133
|
+
);
|
|
134
|
+
|
|
135
|
+
this.addTransactionsToJsLog(
|
|
136
|
+
sessionLog,
|
|
137
|
+
[result.transaction],
|
|
138
|
+
result.signature,
|
|
139
|
+
);
|
|
140
|
+
|
|
141
|
+
return result;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
private addTransactionsToJsLog(
|
|
145
|
+
sessionLog: SessionLog,
|
|
146
|
+
newTransactions: Transaction[],
|
|
147
|
+
signature: Signature,
|
|
148
|
+
) {
|
|
149
|
+
for (const tx of newTransactions) {
|
|
150
|
+
sessionLog.transactions.push(tx);
|
|
151
|
+
}
|
|
152
|
+
sessionLog.lastSignature = signature;
|
|
153
|
+
|
|
154
|
+
sessionLog.txSizeSinceLastInbetweenSignature += newTransactions.reduce(
|
|
155
|
+
(sum, tx) =>
|
|
156
|
+
sum +
|
|
157
|
+
(tx.privacy === "private"
|
|
158
|
+
? tx.encryptedChanges.length
|
|
159
|
+
: tx.changes.length),
|
|
160
|
+
0,
|
|
161
|
+
);
|
|
162
|
+
|
|
163
|
+
if (exceedsRecommendedSize(sessionLog.txSizeSinceLastInbetweenSignature)) {
|
|
164
|
+
sessionLog.signatureAfter[sessionLog.transactions.length - 1] = signature;
|
|
165
|
+
sessionLog.txSizeSinceLastInbetweenSignature = 0;
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
knownState(): CoValueKnownState {
|
|
170
|
+
const sessions: CoValueKnownState["sessions"] = {};
|
|
171
|
+
for (const [sessionID, sessionLog] of this.sessions.entries()) {
|
|
172
|
+
sessions[sessionID] = sessionLog.transactions.length;
|
|
173
|
+
}
|
|
174
|
+
return { id: this.id, header: true, sessions };
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
decryptTransaction(
|
|
178
|
+
sessionID: SessionID,
|
|
179
|
+
txIndex: number,
|
|
180
|
+
keySecret: KeySecret,
|
|
181
|
+
): JsonValue[] | undefined {
|
|
182
|
+
const sessionLog = this.sessions.get(sessionID);
|
|
183
|
+
if (!sessionLog) {
|
|
184
|
+
return undefined;
|
|
185
|
+
}
|
|
186
|
+
const decrypted = sessionLog.impl.decryptNextTransactionChangesJson(
|
|
187
|
+
txIndex,
|
|
188
|
+
keySecret,
|
|
189
|
+
);
|
|
190
|
+
if (!decrypted) {
|
|
191
|
+
return undefined;
|
|
192
|
+
}
|
|
193
|
+
return parseJSON(decrypted as Stringified<JsonValue[] | undefined>);
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
get size() {
|
|
197
|
+
return this.sessions.size;
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
entries() {
|
|
201
|
+
return this.sessions.entries();
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
values() {
|
|
205
|
+
return this.sessions.values();
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
keys() {
|
|
209
|
+
return this.sessions.keys();
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
clone(): SessionMap {
|
|
213
|
+
const clone = new SessionMap(this.id, this.crypto);
|
|
214
|
+
|
|
215
|
+
for (const [sessionID, sessionLog] of this.sessions) {
|
|
216
|
+
clone.sessions.set(sessionID, {
|
|
217
|
+
impl: sessionLog.impl.clone(),
|
|
218
|
+
transactions: sessionLog.transactions.slice(),
|
|
219
|
+
lastSignature: sessionLog.lastSignature,
|
|
220
|
+
signatureAfter: { ...sessionLog.signatureAfter },
|
|
221
|
+
txSizeSinceLastInbetweenSignature:
|
|
222
|
+
sessionLog.txSizeSinceLastInbetweenSignature,
|
|
223
|
+
signerID: sessionLog.signerID,
|
|
224
|
+
});
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
return clone;
|
|
228
|
+
}
|
|
229
|
+
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { UpDownCounter, ValueType, metrics } from "@opentelemetry/api";
|
|
2
|
-
import { Result, err } from "neverthrow";
|
|
2
|
+
import { Result, err, ok } from "neverthrow";
|
|
3
3
|
import type { PeerState } from "../PeerState.js";
|
|
4
4
|
import type { RawCoValue } from "../coValue.js";
|
|
5
5
|
import type { ControlledAccountOrAgent } from "../coValues/account.js";
|
|
@@ -27,6 +27,7 @@ import { accountOrAgentIDfromSessionID } from "../typeUtils/accountOrAgentIDfrom
|
|
|
27
27
|
import { expectGroup } from "../typeUtils/expectGroup.js";
|
|
28
28
|
import { getDependedOnCoValuesFromRawData } from "./utils.js";
|
|
29
29
|
import { CoValueHeader, Transaction, VerifiedState } from "./verifiedState.js";
|
|
30
|
+
import { SessionMap } from "./SessionMap.js";
|
|
30
31
|
|
|
31
32
|
export function idforHeader(
|
|
32
33
|
header: CoValueHeader,
|
|
@@ -95,12 +96,7 @@ export class CoValueCore {
|
|
|
95
96
|
this.crypto = node.crypto;
|
|
96
97
|
if ("header" in init) {
|
|
97
98
|
this.id = idforHeader(init.header, node.crypto);
|
|
98
|
-
this._verified = new VerifiedState(
|
|
99
|
-
this.id,
|
|
100
|
-
node.crypto,
|
|
101
|
-
init.header,
|
|
102
|
-
new Map(),
|
|
103
|
-
);
|
|
99
|
+
this._verified = new VerifiedState(this.id, node.crypto, init.header);
|
|
104
100
|
} else {
|
|
105
101
|
this.id = init.id;
|
|
106
102
|
this._verified = null;
|
|
@@ -298,7 +294,7 @@ export class CoValueCore {
|
|
|
298
294
|
this.id,
|
|
299
295
|
this.node.crypto,
|
|
300
296
|
header,
|
|
301
|
-
new
|
|
297
|
+
new SessionMap(this.id, this.node.crypto),
|
|
302
298
|
streamingKnownState,
|
|
303
299
|
);
|
|
304
300
|
|
|
@@ -435,60 +431,67 @@ export class CoValueCore {
|
|
|
435
431
|
tryAddTransactions(
|
|
436
432
|
sessionID: SessionID,
|
|
437
433
|
newTransactions: Transaction[],
|
|
438
|
-
givenExpectedNewHash: Hash | undefined,
|
|
439
434
|
newSignature: Signature,
|
|
440
|
-
notifyMode: "immediate" | "deferred",
|
|
441
435
|
skipVerify: boolean = false,
|
|
442
|
-
givenNewStreamingHash?: StreamingHash,
|
|
443
436
|
): Result<true, TryAddTransactionsError> {
|
|
444
|
-
|
|
445
|
-
.resolveAccountAgent(
|
|
446
|
-
accountOrAgentIDfromSessionID(sessionID),
|
|
447
|
-
"Expected to know signer of transaction",
|
|
448
|
-
)
|
|
449
|
-
.andThen((agent) => {
|
|
450
|
-
if (!this.verified) {
|
|
451
|
-
return err({
|
|
452
|
-
type: "TriedToAddTransactionsWithoutVerifiedState",
|
|
453
|
-
id: this.id,
|
|
454
|
-
} satisfies TriedToAddTransactionsWithoutVerifiedStateErrpr);
|
|
455
|
-
}
|
|
437
|
+
let result: Result<SignerID | undefined, TryAddTransactionsError>;
|
|
456
438
|
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
);
|
|
439
|
+
if (skipVerify) {
|
|
440
|
+
result = ok(undefined);
|
|
441
|
+
} else {
|
|
442
|
+
result = this.node
|
|
443
|
+
.resolveAccountAgent(
|
|
444
|
+
accountOrAgentIDfromSessionID(sessionID),
|
|
445
|
+
"Expected to know signer of transaction",
|
|
446
|
+
)
|
|
447
|
+
.andThen((agent) => {
|
|
448
|
+
return ok(this.crypto.getAgentSignerID(agent));
|
|
449
|
+
});
|
|
450
|
+
}
|
|
468
451
|
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
} else {
|
|
477
|
-
this._cachedContent = undefined;
|
|
478
|
-
}
|
|
452
|
+
return result.andThen((signerID) => {
|
|
453
|
+
if (!this.verified) {
|
|
454
|
+
return err({
|
|
455
|
+
type: "TriedToAddTransactionsWithoutVerifiedState",
|
|
456
|
+
id: this.id,
|
|
457
|
+
} satisfies TriedToAddTransactionsWithoutVerifiedStateErrpr);
|
|
458
|
+
}
|
|
479
459
|
|
|
480
|
-
|
|
460
|
+
const result = this.verified.tryAddTransactions(
|
|
461
|
+
sessionID,
|
|
462
|
+
signerID,
|
|
463
|
+
newTransactions,
|
|
464
|
+
newSignature,
|
|
465
|
+
skipVerify,
|
|
466
|
+
);
|
|
481
467
|
|
|
482
|
-
|
|
483
|
-
|
|
468
|
+
if (result.isOk()) {
|
|
469
|
+
this.updateContentAndNotifyUpdate("immediate");
|
|
470
|
+
}
|
|
484
471
|
|
|
485
|
-
|
|
486
|
-
|
|
472
|
+
return result;
|
|
473
|
+
});
|
|
487
474
|
}
|
|
488
475
|
|
|
489
476
|
deferredUpdates = 0;
|
|
490
477
|
nextDeferredNotify: Promise<void> | undefined;
|
|
491
478
|
|
|
479
|
+
updateContentAndNotifyUpdate(notifyMode: "immediate" | "deferred") {
|
|
480
|
+
if (
|
|
481
|
+
this._cachedContent &&
|
|
482
|
+
"processNewTransactions" in this._cachedContent &&
|
|
483
|
+
typeof this._cachedContent.processNewTransactions === "function"
|
|
484
|
+
) {
|
|
485
|
+
this._cachedContent.processNewTransactions();
|
|
486
|
+
} else {
|
|
487
|
+
this._cachedContent = undefined;
|
|
488
|
+
}
|
|
489
|
+
|
|
490
|
+
this._cachedDependentOn = undefined;
|
|
491
|
+
|
|
492
|
+
this.notifyUpdate(notifyMode);
|
|
493
|
+
}
|
|
494
|
+
|
|
492
495
|
notifyUpdate(notifyMode: "immediate" | "deferred") {
|
|
493
496
|
if (this.listeners.size === 0) {
|
|
494
497
|
return;
|
|
@@ -556,9 +559,18 @@ export class CoValueCore {
|
|
|
556
559
|
);
|
|
557
560
|
}
|
|
558
561
|
|
|
559
|
-
|
|
562
|
+
// This is an ugly hack to get a unique but stable session ID for editing the current account
|
|
563
|
+
const sessionID =
|
|
564
|
+
this.verified.header.meta?.type === "account"
|
|
565
|
+
? (this.node.currentSessionID.replace(
|
|
566
|
+
this.node.getCurrentAgent().id,
|
|
567
|
+
this.node.getCurrentAgent().currentAgentID(),
|
|
568
|
+
) as SessionID)
|
|
569
|
+
: this.node.currentSessionID;
|
|
570
|
+
|
|
571
|
+
const signerAgent = this.node.getCurrentAgent();
|
|
560
572
|
|
|
561
|
-
let transaction: Transaction;
|
|
573
|
+
let result: { signature: Signature; transaction: Transaction };
|
|
562
574
|
|
|
563
575
|
if (privacy === "private") {
|
|
564
576
|
const { secret: keySecret, id: keyID } = this.getCurrentReadKey();
|
|
@@ -567,69 +579,42 @@ export class CoValueCore {
|
|
|
567
579
|
throw new Error("Can't make transaction without read key secret");
|
|
568
580
|
}
|
|
569
581
|
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
582
|
+
result = this.verified.makeNewPrivateTransaction(
|
|
583
|
+
sessionID,
|
|
584
|
+
signerAgent,
|
|
585
|
+
changes,
|
|
586
|
+
keyID,
|
|
587
|
+
keySecret,
|
|
588
|
+
);
|
|
576
589
|
|
|
577
|
-
transaction
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
keyUsed: keyID,
|
|
581
|
-
encryptedChanges: encrypted,
|
|
582
|
-
};
|
|
590
|
+
if (result.transaction.privacy === "private") {
|
|
591
|
+
this._decryptionCache[result.transaction.encryptedChanges] = changes;
|
|
592
|
+
}
|
|
583
593
|
} else {
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
changes
|
|
588
|
-
|
|
594
|
+
result = this.verified.makeNewTrustingTransaction(
|
|
595
|
+
sessionID,
|
|
596
|
+
signerAgent,
|
|
597
|
+
changes,
|
|
598
|
+
);
|
|
589
599
|
}
|
|
590
600
|
|
|
591
|
-
|
|
592
|
-
const sessionID =
|
|
593
|
-
this.verified.header.meta?.type === "account"
|
|
594
|
-
? (this.node.currentSessionID.replace(
|
|
595
|
-
this.node.getCurrentAgent().id,
|
|
596
|
-
this.node.getCurrentAgent().currentAgentID(),
|
|
597
|
-
) as SessionID)
|
|
598
|
-
: this.node.currentSessionID;
|
|
601
|
+
const { transaction, signature } = result;
|
|
599
602
|
|
|
600
|
-
|
|
601
|
-
this.verified.expectedNewHashAfter(sessionID, [transaction]);
|
|
603
|
+
this.node.syncManager.recordTransactionsSize([transaction], "local");
|
|
602
604
|
|
|
603
|
-
const
|
|
604
|
-
|
|
605
|
-
expectedNewHash,
|
|
606
|
-
);
|
|
605
|
+
const session = this.verified.sessions.get(sessionID);
|
|
606
|
+
const txIdx = session ? session.transactions.length - 1 : 0;
|
|
607
607
|
|
|
608
|
-
|
|
608
|
+
this.updateContentAndNotifyUpdate("immediate");
|
|
609
|
+
this.node.syncManager.syncLocalTransaction(
|
|
610
|
+
this.verified,
|
|
611
|
+
transaction,
|
|
609
612
|
sessionID,
|
|
610
|
-
[transaction],
|
|
611
|
-
expectedNewHash,
|
|
612
613
|
signature,
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
newStreamingHash,
|
|
616
|
-
)._unsafeUnwrap({ withStackTrace: true });
|
|
617
|
-
|
|
618
|
-
if (success) {
|
|
619
|
-
const session = this.verified.sessions.get(sessionID);
|
|
620
|
-
const txIdx = session ? session.transactions.length - 1 : 0;
|
|
621
|
-
|
|
622
|
-
this.node.syncManager.recordTransactionsSize([transaction], "local");
|
|
623
|
-
this.node.syncManager.syncLocalTransaction(
|
|
624
|
-
this.verified,
|
|
625
|
-
transaction,
|
|
626
|
-
sessionID,
|
|
627
|
-
signature,
|
|
628
|
-
txIdx,
|
|
629
|
-
);
|
|
630
|
-
}
|
|
614
|
+
txIdx,
|
|
615
|
+
);
|
|
631
616
|
|
|
632
|
-
return
|
|
617
|
+
return true;
|
|
633
618
|
}
|
|
634
619
|
|
|
635
620
|
getCurrentContent(options?: { ignorePrivateTransactions: true }): RawCoValue {
|
|
@@ -658,6 +643,12 @@ export class CoValueCore {
|
|
|
658
643
|
ignorePrivateTransactions: boolean;
|
|
659
644
|
knownTransactions?: CoValueKnownState["sessions"];
|
|
660
645
|
}): DecryptedTransaction[] {
|
|
646
|
+
if (!this.verified) {
|
|
647
|
+
throw new Error(
|
|
648
|
+
"CoValueCore: getValidTransactions called on coValue without verified state",
|
|
649
|
+
);
|
|
650
|
+
}
|
|
651
|
+
|
|
661
652
|
const validTransactions = determineValidTransactions(
|
|
662
653
|
this,
|
|
663
654
|
options?.knownTransactions,
|
|
@@ -701,25 +692,12 @@ export class CoValueCore {
|
|
|
701
692
|
let decryptedChanges = this._decryptionCache[tx.encryptedChanges];
|
|
702
693
|
|
|
703
694
|
if (!decryptedChanges) {
|
|
704
|
-
|
|
705
|
-
|
|
695
|
+
decryptedChanges = this.verified.decryptTransaction(
|
|
696
|
+
txID.sessionID,
|
|
697
|
+
txID.txIndex,
|
|
706
698
|
readKey,
|
|
707
|
-
{
|
|
708
|
-
in: this.id,
|
|
709
|
-
tx: txID,
|
|
710
|
-
},
|
|
711
699
|
);
|
|
712
700
|
|
|
713
|
-
try {
|
|
714
|
-
decryptedChanges = decryptedString && parseJSON(decryptedString);
|
|
715
|
-
} catch (e) {
|
|
716
|
-
logger.error("Failed to parse private transaction on " + this.id, {
|
|
717
|
-
err: e,
|
|
718
|
-
txID,
|
|
719
|
-
changes: decryptedString?.slice(0, 50),
|
|
720
|
-
});
|
|
721
|
-
continue;
|
|
722
|
-
}
|
|
723
701
|
this._decryptionCache[tx.encryptedChanges] = decryptedChanges;
|
|
724
702
|
}
|
|
725
703
|
|
|
@@ -998,7 +976,7 @@ export type InvalidSignatureError = {
|
|
|
998
976
|
id: RawCoID;
|
|
999
977
|
newSignature: Signature;
|
|
1000
978
|
sessionID: SessionID;
|
|
1001
|
-
signerID: SignerID;
|
|
979
|
+
signerID: SignerID | undefined;
|
|
1002
980
|
};
|
|
1003
981
|
|
|
1004
982
|
export type TriedToAddTransactionsWithoutVerifiedStateErrpr = {
|
|
@@ -1006,8 +984,15 @@ export type TriedToAddTransactionsWithoutVerifiedStateErrpr = {
|
|
|
1006
984
|
id: RawCoID;
|
|
1007
985
|
};
|
|
1008
986
|
|
|
987
|
+
export type TriedToAddTransactionsWithoutSignerIDError = {
|
|
988
|
+
type: "TriedToAddTransactionsWithoutSignerID";
|
|
989
|
+
id: RawCoID;
|
|
990
|
+
sessionID: SessionID;
|
|
991
|
+
};
|
|
992
|
+
|
|
1009
993
|
export type TryAddTransactionsError =
|
|
1010
994
|
| TriedToAddTransactionsWithoutVerifiedStateErrpr
|
|
995
|
+
| TriedToAddTransactionsWithoutSignerIDError
|
|
1011
996
|
| ResolveAccountAgentError
|
|
1012
997
|
| InvalidHashError
|
|
1013
998
|
| InvalidSignatureError;
|