cojson 0.9.9 → 0.9.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 +3 -3
- package/CHANGELOG.md +13 -0
- package/dist/native/PeerState.js +2 -1
- package/dist/native/PeerState.js.map +1 -1
- package/dist/native/PriorityBasedMessageQueue.js +54 -7
- package/dist/native/PriorityBasedMessageQueue.js.map +1 -1
- package/dist/native/base64url.js +0 -6
- package/dist/native/base64url.js.map +1 -1
- package/dist/native/coValue.js +27 -0
- package/dist/native/coValue.js.map +1 -1
- package/dist/native/coValueCore.js +30 -177
- package/dist/native/coValueCore.js.map +1 -1
- package/dist/native/coValueState.js +5 -4
- package/dist/native/coValueState.js.map +1 -1
- package/dist/native/coValues/account.js +2 -1
- package/dist/native/coValues/account.js.map +1 -1
- package/dist/native/coValues/coList.js +0 -7
- package/dist/native/coValues/coList.js.map +1 -1
- package/dist/native/coValues/coStream.js +3 -8
- package/dist/native/coValues/coStream.js.map +1 -1
- package/dist/native/coValues/group.js +3 -2
- package/dist/native/coValues/group.js.map +1 -1
- package/dist/native/coreToCoValue.js +2 -1
- package/dist/native/coreToCoValue.js.map +1 -1
- package/dist/native/crypto/PureJSCrypto.js +2 -1
- package/dist/native/crypto/PureJSCrypto.js.map +1 -1
- package/dist/native/crypto/WasmCrypto.js +2 -1
- package/dist/native/crypto/WasmCrypto.js.map +1 -1
- package/dist/native/crypto/crypto.js +2 -4
- package/dist/native/crypto/crypto.js.map +1 -1
- package/dist/native/exports.js +2 -1
- package/dist/native/exports.js.map +1 -1
- package/dist/native/localNode.js +5 -6
- package/dist/native/localNode.js.map +1 -1
- package/dist/native/logger.js +58 -0
- package/dist/native/logger.js.map +1 -0
- package/dist/native/permissions.js +3 -4
- package/dist/native/permissions.js.map +1 -1
- package/dist/native/storage/FileSystem.js +0 -10
- package/dist/native/storage/FileSystem.js.map +1 -1
- package/dist/native/storage/index.js +14 -23
- package/dist/native/storage/index.js.map +1 -1
- package/dist/native/sync.js +20 -28
- package/dist/native/sync.js.map +1 -1
- package/dist/web/PeerState.js +2 -1
- package/dist/web/PeerState.js.map +1 -1
- package/dist/web/PriorityBasedMessageQueue.js +54 -7
- package/dist/web/PriorityBasedMessageQueue.js.map +1 -1
- package/dist/web/base64url.js +0 -6
- package/dist/web/base64url.js.map +1 -1
- package/dist/web/coValue.js +27 -0
- package/dist/web/coValue.js.map +1 -1
- package/dist/web/coValueCore.js +30 -177
- package/dist/web/coValueCore.js.map +1 -1
- package/dist/web/coValueState.js +5 -4
- package/dist/web/coValueState.js.map +1 -1
- package/dist/web/coValues/account.js +2 -1
- package/dist/web/coValues/account.js.map +1 -1
- package/dist/web/coValues/coList.js +0 -7
- package/dist/web/coValues/coList.js.map +1 -1
- package/dist/web/coValues/coStream.js +3 -8
- package/dist/web/coValues/coStream.js.map +1 -1
- package/dist/web/coValues/group.js +3 -2
- package/dist/web/coValues/group.js.map +1 -1
- package/dist/web/coreToCoValue.js +2 -1
- package/dist/web/coreToCoValue.js.map +1 -1
- package/dist/web/crypto/PureJSCrypto.js +2 -1
- package/dist/web/crypto/PureJSCrypto.js.map +1 -1
- package/dist/web/crypto/WasmCrypto.js +2 -1
- package/dist/web/crypto/WasmCrypto.js.map +1 -1
- package/dist/web/crypto/crypto.js +2 -4
- package/dist/web/crypto/crypto.js.map +1 -1
- package/dist/web/exports.js +2 -1
- package/dist/web/exports.js.map +1 -1
- package/dist/web/localNode.js +5 -6
- package/dist/web/localNode.js.map +1 -1
- package/dist/web/logger.js +58 -0
- package/dist/web/logger.js.map +1 -0
- package/dist/web/permissions.js +3 -4
- package/dist/web/permissions.js.map +1 -1
- package/dist/web/storage/FileSystem.js +0 -10
- package/dist/web/storage/FileSystem.js.map +1 -1
- package/dist/web/storage/index.js +14 -23
- package/dist/web/storage/index.js.map +1 -1
- package/dist/web/sync.js +20 -28
- package/dist/web/sync.js.map +1 -1
- package/package.json +1 -1
- package/src/PeerState.ts +4 -3
- package/src/PriorityBasedMessageQueue.ts +67 -11
- package/src/base64url.ts +1 -6
- package/src/coValue.ts +37 -0
- package/src/coValueCore.ts +34 -180
- package/src/coValueState.ts +5 -4
- package/src/coValues/account.ts +2 -1
- package/src/coValues/coList.ts +0 -7
- package/src/coValues/coStream.ts +3 -8
- package/src/coValues/group.ts +3 -2
- package/src/coreToCoValue.ts +2 -1
- package/src/crypto/PureJSCrypto.ts +2 -1
- package/src/crypto/WasmCrypto.ts +2 -1
- package/src/crypto/crypto.ts +2 -4
- package/src/exports.ts +2 -0
- package/src/localNode.ts +5 -9
- package/src/logger.ts +78 -0
- package/src/permissions.ts +3 -5
- package/src/storage/FileSystem.ts +0 -12
- package/src/storage/index.ts +21 -37
- package/src/sync.ts +20 -29
- package/src/tests/PeerState.test.ts +0 -3
- package/src/tests/PriorityBasedMessageQueue.test.ts +1 -1
- package/src/tests/coValueCore.test.ts +32 -2
- package/src/tests/logger.test.ts +145 -0
- package/src/tests/sync.test.ts +43 -0
- package/src/tests/testUtils.ts +19 -0
package/src/crypto/WasmCrypto.ts
CHANGED
|
@@ -15,6 +15,7 @@ import { base64URLtoBytes, bytesToBase64url } from "../base64url.js";
|
|
|
15
15
|
import { RawCoID, TransactionID } from "../ids.js";
|
|
16
16
|
import { Stringified, stableStringify } from "../jsonStringify.js";
|
|
17
17
|
import { JsonValue } from "../jsonValue.js";
|
|
18
|
+
import { logger } from "../logger.js";
|
|
18
19
|
import {
|
|
19
20
|
CryptoProvider,
|
|
20
21
|
Encrypted,
|
|
@@ -240,7 +241,7 @@ export class WasmCrypto extends CryptoProvider<Uint8Array> {
|
|
|
240
241
|
try {
|
|
241
242
|
return JSON.parse(textDecoder.decode(plaintext));
|
|
242
243
|
} catch (e) {
|
|
243
|
-
|
|
244
|
+
logger.error("Failed to decrypt/parse sealed message", e);
|
|
244
245
|
return undefined;
|
|
245
246
|
}
|
|
246
247
|
}
|
package/src/crypto/crypto.ts
CHANGED
|
@@ -4,6 +4,7 @@ import { AgentID, RawCoID, TransactionID } from "../ids.js";
|
|
|
4
4
|
import { SessionID } from "../ids.js";
|
|
5
5
|
import { Stringified, parseJSON, stableStringify } from "../jsonStringify.js";
|
|
6
6
|
import { JsonValue } from "../jsonValue.js";
|
|
7
|
+
import { logger } from "../logger.js";
|
|
7
8
|
|
|
8
9
|
export type SignerSecret = `signerSecret_z${string}`;
|
|
9
10
|
export type SignerID = `signer_z${string}`;
|
|
@@ -159,7 +160,7 @@ export abstract class CryptoProvider<Blake3State = any> {
|
|
|
159
160
|
try {
|
|
160
161
|
return parseJSON(this.decryptRaw(encrypted, keySecret, nOnceMaterial));
|
|
161
162
|
} catch (e) {
|
|
162
|
-
|
|
163
|
+
logger.error("Decryption error", e);
|
|
163
164
|
return undefined;
|
|
164
165
|
}
|
|
165
166
|
}
|
|
@@ -305,10 +306,7 @@ export class StreamingHash {
|
|
|
305
306
|
|
|
306
307
|
update(value: JsonValue): Uint8Array {
|
|
307
308
|
const encoded = textEncoder.encode(stableStringify(value));
|
|
308
|
-
// const before = performance.now();
|
|
309
309
|
this.state = this.crypto.blake3IncrementalUpdate(this.state, encoded);
|
|
310
|
-
// const after = performance.now();
|
|
311
|
-
// console.log(`Hashing throughput in MB/s`, 1000 * (encoded.length / (after - before)) / (1024 * 1024));
|
|
312
310
|
return encoded;
|
|
313
311
|
}
|
|
314
312
|
|
package/src/exports.ts
CHANGED
|
@@ -74,6 +74,7 @@ import {
|
|
|
74
74
|
|
|
75
75
|
type Value = JsonValue | AnyRawCoValue;
|
|
76
76
|
|
|
77
|
+
import { logger } from "./logger.js";
|
|
77
78
|
import { getPriorityFromHeader } from "./priority.js";
|
|
78
79
|
import { FileSystem } from "./storage/FileSystem.js";
|
|
79
80
|
import { BlockFilename, LSMStorage, WalFilename } from "./storage/index.js";
|
|
@@ -141,6 +142,7 @@ export {
|
|
|
141
142
|
emptyKnownState,
|
|
142
143
|
RawCoPlainText,
|
|
143
144
|
stringifyOpID,
|
|
145
|
+
logger,
|
|
144
146
|
};
|
|
145
147
|
|
|
146
148
|
export type {
|
package/src/localNode.ts
CHANGED
|
@@ -27,6 +27,7 @@ import {
|
|
|
27
27
|
} from "./coValues/group.js";
|
|
28
28
|
import { AgentSecret, CryptoProvider } from "./crypto/crypto.js";
|
|
29
29
|
import { AgentID, RawCoID, SessionID, isAgentID } from "./ids.js";
|
|
30
|
+
import { logger } from "./logger.js";
|
|
30
31
|
import { Peer, PeerID, SyncManager } from "./sync.js";
|
|
31
32
|
import { expectGroup } from "./typeUtils/expectGroup.js";
|
|
32
33
|
|
|
@@ -230,7 +231,7 @@ export class LocalNode {
|
|
|
230
231
|
|
|
231
232
|
return node;
|
|
232
233
|
} catch (e) {
|
|
233
|
-
|
|
234
|
+
logger.error("Error withLoadedAccount", e);
|
|
234
235
|
throw e;
|
|
235
236
|
}
|
|
236
237
|
}
|
|
@@ -269,7 +270,7 @@ export class LocalNode {
|
|
|
269
270
|
this.syncManager.getServerAndStoragePeers(skipLoadingFromPeer);
|
|
270
271
|
|
|
271
272
|
await entry.loadFromPeers(peers).catch((e) => {
|
|
272
|
-
|
|
273
|
+
logger.error("Error loading from peers", id, e);
|
|
273
274
|
});
|
|
274
275
|
}
|
|
275
276
|
|
|
@@ -311,8 +312,6 @@ export class LocalNode {
|
|
|
311
312
|
let stopped = false;
|
|
312
313
|
let unsubscribe!: () => void;
|
|
313
314
|
|
|
314
|
-
// console.log("Subscribing to " + id);
|
|
315
|
-
|
|
316
315
|
this.load(id)
|
|
317
316
|
.then((coValue) => {
|
|
318
317
|
if (stopped) {
|
|
@@ -325,11 +324,10 @@ export class LocalNode {
|
|
|
325
324
|
unsubscribe = coValue.subscribe(callback);
|
|
326
325
|
})
|
|
327
326
|
.catch((e) => {
|
|
328
|
-
|
|
327
|
+
logger.error("Error subscribing to ", id, e);
|
|
329
328
|
});
|
|
330
329
|
|
|
331
330
|
return () => {
|
|
332
|
-
console.log("Unsubscribing from " + id);
|
|
333
331
|
stopped = true;
|
|
334
332
|
unsubscribe?.();
|
|
335
333
|
};
|
|
@@ -390,9 +388,7 @@ export class LocalNode {
|
|
|
390
388
|
(existingRole === "reader" && inviteRole === "readerInvite") ||
|
|
391
389
|
(existingRole && inviteRole === "writeOnlyInvite")
|
|
392
390
|
) {
|
|
393
|
-
|
|
394
|
-
"Not accepting invite that would replace or downgrade role",
|
|
395
|
-
);
|
|
391
|
+
logger.debug("Not accepting invite that would replace or downgrade role");
|
|
396
392
|
return;
|
|
397
393
|
}
|
|
398
394
|
|
package/src/logger.ts
ADDED
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
export enum LogLevel {
|
|
2
|
+
DEBUG = 0,
|
|
3
|
+
INFO = 1,
|
|
4
|
+
WARN = 2,
|
|
5
|
+
ERROR = 3,
|
|
6
|
+
NONE = 4,
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export interface LogSystem {
|
|
10
|
+
debug(message: string, ...args: any[]): void;
|
|
11
|
+
info(message: string, ...args: any[]): void;
|
|
12
|
+
warn(message: string, ...args: any[]): void;
|
|
13
|
+
error(message: string, ...args: any[]): void;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
// Default console-based logging system
|
|
17
|
+
export class ConsoleLogSystem implements LogSystem {
|
|
18
|
+
debug(message: string, ...args: any[]) {
|
|
19
|
+
console.debug(message, ...args);
|
|
20
|
+
}
|
|
21
|
+
info(message: string, ...args: any[]) {
|
|
22
|
+
console.info(message, ...args);
|
|
23
|
+
}
|
|
24
|
+
warn(message: string, ...args: any[]) {
|
|
25
|
+
console.warn(message, ...args);
|
|
26
|
+
}
|
|
27
|
+
error(message: string, ...args: any[]) {
|
|
28
|
+
console.error(message, ...args);
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export class Logger {
|
|
33
|
+
private level: LogLevel;
|
|
34
|
+
private logSystem: LogSystem;
|
|
35
|
+
|
|
36
|
+
constructor(
|
|
37
|
+
level: LogLevel = LogLevel.INFO,
|
|
38
|
+
logSystem: LogSystem = new ConsoleLogSystem(),
|
|
39
|
+
) {
|
|
40
|
+
this.level = level;
|
|
41
|
+
this.logSystem = logSystem;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
setLevel(level: LogLevel) {
|
|
45
|
+
this.level = level;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
setLogSystem(logSystem: LogSystem) {
|
|
49
|
+
this.logSystem = logSystem;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
debug(message: string, ...args: any[]) {
|
|
53
|
+
if (this.level <= LogLevel.DEBUG) {
|
|
54
|
+
this.logSystem.debug(message, ...args);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
info(message: string, ...args: any[]) {
|
|
59
|
+
if (this.level <= LogLevel.INFO) {
|
|
60
|
+
this.logSystem.info(message, ...args);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
warn(message: string, ...args: any[]) {
|
|
65
|
+
if (this.level <= LogLevel.WARN) {
|
|
66
|
+
this.logSystem.warn(message, ...args);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
error(message: string, ...args: any[]) {
|
|
71
|
+
if (this.level <= LogLevel.ERROR) {
|
|
72
|
+
this.logSystem.error(message, ...args);
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
// Create default logger instance
|
|
78
|
+
export const logger = new Logger();
|
package/src/permissions.ts
CHANGED
|
@@ -14,6 +14,7 @@ import {
|
|
|
14
14
|
} from "./ids.js";
|
|
15
15
|
import { parseJSON } from "./jsonStringify.js";
|
|
16
16
|
import { JsonValue } from "./jsonValue.js";
|
|
17
|
+
import { logger } from "./logger.js";
|
|
17
18
|
import { accountOrAgentIDfromSessionID } from "./typeUtils/accountOrAgentIDfromSessionID.js";
|
|
18
19
|
import { expectGroup } from "./typeUtils/expectGroup.js";
|
|
19
20
|
|
|
@@ -46,7 +47,7 @@ function logPermissionError(...args: unknown[]) {
|
|
|
46
47
|
return;
|
|
47
48
|
}
|
|
48
49
|
|
|
49
|
-
|
|
50
|
+
logger.warn("Permission error", ...args);
|
|
50
51
|
}
|
|
51
52
|
|
|
52
53
|
export function determineValidTransactions(
|
|
@@ -204,7 +205,6 @@ function determineValidTransactionsForGroup(
|
|
|
204
205
|
const writeKeys = new Set<string>();
|
|
205
206
|
|
|
206
207
|
for (const { sessionID, txIndex, tx } of allTransactionsSorted) {
|
|
207
|
-
// console.log("before", { memberState, validTransactions });
|
|
208
208
|
const transactor = accountOrAgentIDfromSessionID(sessionID);
|
|
209
209
|
|
|
210
210
|
if (tx.privacy === "private") {
|
|
@@ -458,8 +458,6 @@ function determineValidTransactionsForGroup(
|
|
|
458
458
|
|
|
459
459
|
memberState[affectedMember] = change.value;
|
|
460
460
|
validTransactions.push({ txID: { sessionID, txIndex }, tx });
|
|
461
|
-
|
|
462
|
-
// console.log("after", { memberState, validTransactions });
|
|
463
461
|
}
|
|
464
462
|
|
|
465
463
|
return { validTransactions, memberState };
|
|
@@ -473,7 +471,7 @@ function agentInAccountOrMemberInGroup(
|
|
|
473
471
|
return groupAtTime.currentAgentID().match(
|
|
474
472
|
(agentID) => agentID,
|
|
475
473
|
(e) => {
|
|
476
|
-
|
|
474
|
+
logger.error(
|
|
477
475
|
"Error while determining current agent ID in valid transactions",
|
|
478
476
|
e,
|
|
479
477
|
);
|
|
@@ -87,26 +87,15 @@ export async function writeBlock<WH, RH, FS extends FileSystem<WH, RH>>(
|
|
|
87
87
|
const headerBytes = textEncoder.encode(JSON.stringify(blockHeader));
|
|
88
88
|
await fs.append(file, headerBytes);
|
|
89
89
|
|
|
90
|
-
// console.log(
|
|
91
|
-
// "full file",
|
|
92
|
-
// yield* $(
|
|
93
|
-
// fs.read(file as unknown as RH, 0, offset + headerBytes.length),
|
|
94
|
-
// ),
|
|
95
|
-
// );
|
|
96
|
-
|
|
97
90
|
const filename: BlockFilename = `L${level}-${(blockNumber + "").padStart(
|
|
98
91
|
3,
|
|
99
92
|
"0",
|
|
100
93
|
)}-${hash.digest().replace("hash_", "").slice(0, 15)}-H${
|
|
101
94
|
headerBytes.length
|
|
102
95
|
}.jsonl`;
|
|
103
|
-
// console.log("renaming to" + filename);
|
|
104
96
|
await fs.closeAndRename(file, filename);
|
|
105
97
|
|
|
106
98
|
return filename;
|
|
107
|
-
|
|
108
|
-
// console.log("Wrote block", filename, blockHeader);
|
|
109
|
-
// console.log("IDs in block", blockHeader.map(e => e.id));
|
|
110
99
|
}
|
|
111
100
|
|
|
112
101
|
export async function writeToWal<WH, RH, FS extends FileSystem<WH, RH>>(
|
|
@@ -120,6 +109,5 @@ export async function writeToWal<WH, RH, FS extends FileSystem<WH, RH>>(
|
|
|
120
109
|
...chunk,
|
|
121
110
|
};
|
|
122
111
|
const bytes = textEncoder.encode(JSON.stringify(walEntry) + "\n");
|
|
123
|
-
console.log("writing to WAL", handle, id, bytes.length);
|
|
124
112
|
return fs.append(handle, bytes);
|
|
125
113
|
}
|
package/src/storage/index.ts
CHANGED
|
@@ -2,6 +2,7 @@ import { CoID, RawCoValue } from "../coValue.js";
|
|
|
2
2
|
import { CoValueHeader, Transaction } from "../coValueCore.js";
|
|
3
3
|
import { Signature } from "../crypto/crypto.js";
|
|
4
4
|
import { RawCoID } from "../ids.js";
|
|
5
|
+
import { logger } from "../logger.js";
|
|
5
6
|
import { connectedPeers } from "../streamUtils.js";
|
|
6
7
|
import {
|
|
7
8
|
CoValueKnownState,
|
|
@@ -68,7 +69,6 @@ export class LSMStorage<WH, RH, FS extends FileSystem<WH, RH>> {
|
|
|
68
69
|
|
|
69
70
|
const processMessages = async () => {
|
|
70
71
|
for await (const msg of fromLocalNode) {
|
|
71
|
-
console.log("Storage msg start", nMsg);
|
|
72
72
|
try {
|
|
73
73
|
if (msg === "Disconnected" || msg === "PingTimeout") {
|
|
74
74
|
throw new Error("Unexpected Disconnected message");
|
|
@@ -83,32 +83,29 @@ export class LSMStorage<WH, RH, FS extends FileSystem<WH, RH>> {
|
|
|
83
83
|
await this.sendNewContent(msg.id, msg, undefined);
|
|
84
84
|
}
|
|
85
85
|
} catch (e) {
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
{ cause: e },
|
|
96
|
-
),
|
|
86
|
+
logger.error(
|
|
87
|
+
`Error reading from localNode, handling msg\n\n${JSON.stringify(
|
|
88
|
+
msg,
|
|
89
|
+
(k, v) =>
|
|
90
|
+
k === "changes" || k === "encryptedChanges"
|
|
91
|
+
? v.slice(0, 20) + "..."
|
|
92
|
+
: v,
|
|
93
|
+
)}`,
|
|
94
|
+
e,
|
|
97
95
|
);
|
|
98
96
|
}
|
|
99
|
-
console.log("Storage msg end", nMsg);
|
|
100
97
|
nMsg++;
|
|
101
98
|
}
|
|
102
99
|
};
|
|
103
100
|
|
|
104
101
|
processMessages().catch((e) =>
|
|
105
|
-
|
|
102
|
+
logger.error("Error in processMessages in storage", e),
|
|
106
103
|
);
|
|
107
104
|
|
|
108
105
|
setTimeout(
|
|
109
106
|
() =>
|
|
110
107
|
this.compact().catch((e) => {
|
|
111
|
-
|
|
108
|
+
logger.error("Error while compacting", e);
|
|
112
109
|
}),
|
|
113
110
|
20000,
|
|
114
111
|
);
|
|
@@ -134,7 +131,7 @@ export class LSMStorage<WH, RH, FS extends FileSystem<WH, RH>> {
|
|
|
134
131
|
sessions: {},
|
|
135
132
|
asDependencyOf,
|
|
136
133
|
})
|
|
137
|
-
.catch((e) =>
|
|
134
|
+
.catch((e) => logger.error("Error while pushing known", e));
|
|
138
135
|
|
|
139
136
|
return;
|
|
140
137
|
}
|
|
@@ -190,13 +187,13 @@ export class LSMStorage<WH, RH, FS extends FileSystem<WH, RH>> {
|
|
|
190
187
|
...ourKnown,
|
|
191
188
|
asDependencyOf,
|
|
192
189
|
})
|
|
193
|
-
.catch((e) =>
|
|
190
|
+
.catch((e) => logger.error("Error while pushing known", e));
|
|
194
191
|
|
|
195
192
|
for (const message of newContentMessages) {
|
|
196
193
|
if (Object.keys(message.new).length === 0) continue;
|
|
197
194
|
this.toLocalNode
|
|
198
195
|
.push(message)
|
|
199
|
-
.catch((e) =>
|
|
196
|
+
.catch((e) => logger.error("Error while pushing new content", e));
|
|
200
197
|
}
|
|
201
198
|
|
|
202
199
|
this.coValues[id] = coValue;
|
|
@@ -232,20 +229,19 @@ export class LSMStorage<WH, RH, FS extends FileSystem<WH, RH>> {
|
|
|
232
229
|
|
|
233
230
|
if (!coValue) {
|
|
234
231
|
if (newContent.header) {
|
|
235
|
-
// console.log("Creating in WAL", newContent.id);
|
|
236
232
|
await this.withWAL((wal) =>
|
|
237
233
|
writeToWal(wal, this.fs, newContent.id, newContentAsChunk),
|
|
238
234
|
);
|
|
239
235
|
|
|
240
236
|
this.coValues[newContent.id] = newContentAsChunk;
|
|
241
237
|
} else {
|
|
242
|
-
|
|
238
|
+
logger.warn("Incontiguous incoming update for " + newContent.id);
|
|
243
239
|
return;
|
|
244
240
|
}
|
|
245
241
|
} else {
|
|
246
242
|
const merged = mergeChunks(coValue, newContentAsChunk);
|
|
247
243
|
if (merged === "nonContigous") {
|
|
248
|
-
|
|
244
|
+
logger.warn(
|
|
249
245
|
"Non-contigous new content for " + newContent.id,
|
|
250
246
|
Object.entries(coValue.sessionEntries).map(([session, entries]) =>
|
|
251
247
|
entries.map((entry) => ({
|
|
@@ -264,7 +260,6 @@ export class LSMStorage<WH, RH, FS extends FileSystem<WH, RH>> {
|
|
|
264
260
|
),
|
|
265
261
|
);
|
|
266
262
|
} else {
|
|
267
|
-
// console.log("Appending to WAL", newContent.id);
|
|
268
263
|
await this.withWAL((wal) =>
|
|
269
264
|
writeToWal(wal, this.fs, newContent.id, newContentAsChunk),
|
|
270
265
|
);
|
|
@@ -301,8 +296,6 @@ export class LSMStorage<WH, RH, FS extends FileSystem<WH, RH>> {
|
|
|
301
296
|
|
|
302
297
|
const { handle, size } = await this.getBlockHandle(blockFile, fs);
|
|
303
298
|
|
|
304
|
-
// console.log("Attempting to load", id, blockFile);
|
|
305
|
-
|
|
306
299
|
if (!cachedHeader) {
|
|
307
300
|
cachedHeader = {};
|
|
308
301
|
const header = await readHeader(blockFile, handle, size, fs);
|
|
@@ -317,15 +310,13 @@ export class LSMStorage<WH, RH, FS extends FileSystem<WH, RH>> {
|
|
|
317
310
|
}
|
|
318
311
|
const headerEntry = cachedHeader[id];
|
|
319
312
|
|
|
320
|
-
// console.log("Header entry", id, headerEntry);
|
|
321
|
-
|
|
322
313
|
if (headerEntry) {
|
|
323
314
|
const nextChunk = await readChunk(handle, headerEntry, fs);
|
|
324
315
|
if (result) {
|
|
325
316
|
const merged = mergeChunks(result, nextChunk);
|
|
326
317
|
|
|
327
318
|
if (merged === "nonContigous") {
|
|
328
|
-
|
|
319
|
+
logger.warn(
|
|
329
320
|
"Non-contigous chunks while loading " + id,
|
|
330
321
|
result,
|
|
331
322
|
nextChunk,
|
|
@@ -354,7 +345,6 @@ export class LSMStorage<WH, RH, FS extends FileSystem<WH, RH>> {
|
|
|
354
345
|
|
|
355
346
|
const coValues = new Map<RawCoID, CoValueChunk>();
|
|
356
347
|
|
|
357
|
-
console.log("Compacting WAL files", walFiles);
|
|
358
348
|
if (walFiles.length === 0) return;
|
|
359
349
|
|
|
360
350
|
const oldWal = this.currentWal;
|
|
@@ -385,7 +375,7 @@ export class LSMStorage<WH, RH, FS extends FileSystem<WH, RH>> {
|
|
|
385
375
|
if (existingChunk) {
|
|
386
376
|
const merged = mergeChunks(existingChunk, chunk);
|
|
387
377
|
if (merged === "nonContigous") {
|
|
388
|
-
|
|
378
|
+
logger.info(
|
|
389
379
|
"Non-contigous chunks in " + chunk.id + ", " + fileName,
|
|
390
380
|
existingChunk,
|
|
391
381
|
chunk,
|
|
@@ -411,8 +401,6 @@ export class LSMStorage<WH, RH, FS extends FileSystem<WH, RH>> {
|
|
|
411
401
|
return acc;
|
|
412
402
|
}, 0);
|
|
413
403
|
|
|
414
|
-
console.log([...coValues.keys()], fileNames, highestBlockNumber);
|
|
415
|
-
|
|
416
404
|
await writeBlock(coValues, MAX_N_LEVELS, highestBlockNumber + 1, this.fs);
|
|
417
405
|
|
|
418
406
|
for (const walFile of walFiles) {
|
|
@@ -438,15 +426,11 @@ export class LSMStorage<WH, RH, FS extends FileSystem<WH, RH>> {
|
|
|
438
426
|
blockFilesByLevelInOrder[level]!.push(blockFile);
|
|
439
427
|
}
|
|
440
428
|
|
|
441
|
-
console.log(blockFilesByLevelInOrder);
|
|
442
|
-
|
|
443
429
|
for (let level = MAX_N_LEVELS; level > 0; level--) {
|
|
444
430
|
const nBlocksDesired = Math.pow(2, level);
|
|
445
431
|
const blocksInLevel = blockFilesByLevelInOrder[level];
|
|
446
432
|
|
|
447
433
|
if (blocksInLevel && blocksInLevel.length > nBlocksDesired) {
|
|
448
|
-
console.log("Compacting blocks in level", level, blocksInLevel);
|
|
449
|
-
|
|
450
434
|
const coValues = new Map<RawCoID, CoValueChunk>();
|
|
451
435
|
|
|
452
436
|
for (const blockFile of blocksInLevel) {
|
|
@@ -465,7 +449,7 @@ export class LSMStorage<WH, RH, FS extends FileSystem<WH, RH>> {
|
|
|
465
449
|
if (existingChunk) {
|
|
466
450
|
const merged = mergeChunks(existingChunk, chunk);
|
|
467
451
|
if (merged === "nonContigous") {
|
|
468
|
-
|
|
452
|
+
logger.info(
|
|
469
453
|
"Non-contigous chunks in " + entry.id + ", " + blockFile,
|
|
470
454
|
existingChunk,
|
|
471
455
|
chunk,
|
|
@@ -517,7 +501,7 @@ export class LSMStorage<WH, RH, FS extends FileSystem<WH, RH>> {
|
|
|
517
501
|
setTimeout(
|
|
518
502
|
() =>
|
|
519
503
|
this.compact().catch((e) => {
|
|
520
|
-
|
|
504
|
+
logger.error("Error while compacting", e);
|
|
521
505
|
}),
|
|
522
506
|
5000,
|
|
523
507
|
);
|
package/src/sync.ts
CHANGED
|
@@ -6,6 +6,7 @@ import { CoValueCore } from "./coValueCore.js";
|
|
|
6
6
|
import { Signature } from "./crypto/crypto.js";
|
|
7
7
|
import { RawCoID, SessionID } from "./ids.js";
|
|
8
8
|
import { LocalNode } from "./localNode.js";
|
|
9
|
+
import { logger } from "./logger.js";
|
|
9
10
|
import { CoValuePriority } from "./priority.js";
|
|
10
11
|
|
|
11
12
|
export type CoValueKnownState = {
|
|
@@ -150,7 +151,7 @@ export class SyncManager {
|
|
|
150
151
|
|
|
151
152
|
async handleSyncMessage(msg: SyncMessage, peer: PeerState) {
|
|
152
153
|
if (peer.erroredCoValues.has(msg.id)) {
|
|
153
|
-
|
|
154
|
+
logger.warn(
|
|
154
155
|
`Skipping message ${msg.action} on errored coValue ${msg.id} from peer ${peer.id}`,
|
|
155
156
|
);
|
|
156
157
|
return;
|
|
@@ -182,7 +183,7 @@ export class SyncManager {
|
|
|
182
183
|
|
|
183
184
|
if (entry.state.type !== "available") {
|
|
184
185
|
entry.loadFromPeers([peer]).catch((e: unknown) => {
|
|
185
|
-
|
|
186
|
+
logger.error("Error sending load", e);
|
|
186
187
|
});
|
|
187
188
|
return;
|
|
188
189
|
}
|
|
@@ -199,7 +200,7 @@ export class SyncManager {
|
|
|
199
200
|
action: "load",
|
|
200
201
|
...coValue.knownState(),
|
|
201
202
|
}).catch((e: unknown) => {
|
|
202
|
-
|
|
203
|
+
logger.error("Error sending load", e);
|
|
203
204
|
});
|
|
204
205
|
}
|
|
205
206
|
}
|
|
@@ -229,7 +230,7 @@ export class SyncManager {
|
|
|
229
230
|
asDependencyOf,
|
|
230
231
|
...coValue.knownState(),
|
|
231
232
|
}).catch((e: unknown) => {
|
|
232
|
-
|
|
233
|
+
logger.error("Error sending known state", e);
|
|
233
234
|
});
|
|
234
235
|
|
|
235
236
|
peer.toldKnownState.add(id);
|
|
@@ -256,15 +257,8 @@ export class SyncManager {
|
|
|
256
257
|
const sendPieces = async () => {
|
|
257
258
|
let lastYield = performance.now();
|
|
258
259
|
for (const [_i, piece] of newContentPieces.entries()) {
|
|
259
|
-
// console.log(
|
|
260
|
-
// `${id} -> ${peer.id}: Sending content piece ${i + 1}/${
|
|
261
|
-
// newContentPieces.length
|
|
262
|
-
// } header: ${!!piece.header}`,
|
|
263
|
-
// // Object.values(piece.new).map((s) => s.newTransactions)
|
|
264
|
-
// );
|
|
265
|
-
|
|
266
260
|
this.trySendToPeer(peer, piece).catch((e: unknown) => {
|
|
267
|
-
|
|
261
|
+
logger.error("Error sending content piece", e);
|
|
268
262
|
});
|
|
269
263
|
|
|
270
264
|
if (performance.now() - lastYield > 10) {
|
|
@@ -277,7 +271,7 @@ export class SyncManager {
|
|
|
277
271
|
};
|
|
278
272
|
|
|
279
273
|
sendPieces().catch((e) => {
|
|
280
|
-
|
|
274
|
+
logger.error("Error sending new content piece, retrying", e);
|
|
281
275
|
peer.optimisticKnownStates.dispatch({
|
|
282
276
|
type: "SET",
|
|
283
277
|
id,
|
|
@@ -337,7 +331,7 @@ export class SyncManager {
|
|
|
337
331
|
return;
|
|
338
332
|
}
|
|
339
333
|
if (msg === "PingTimeout") {
|
|
340
|
-
|
|
334
|
+
logger.error("Ping timeout from peer", peer.id);
|
|
341
335
|
return;
|
|
342
336
|
}
|
|
343
337
|
try {
|
|
@@ -360,13 +354,13 @@ export class SyncManager {
|
|
|
360
354
|
processMessages()
|
|
361
355
|
.then(() => {
|
|
362
356
|
if (peer.crashOnClose) {
|
|
363
|
-
|
|
357
|
+
logger.warn("Unexepcted close from peer", peer.id);
|
|
364
358
|
this.local.crashed = new Error("Unexpected close from peer");
|
|
365
359
|
throw new Error("Unexpected close from peer");
|
|
366
360
|
}
|
|
367
361
|
})
|
|
368
362
|
.catch((e) => {
|
|
369
|
-
|
|
363
|
+
logger.error("Error processing messages from peer", peer.id, e);
|
|
370
364
|
if (peer.crashOnClose) {
|
|
371
365
|
this.local.crashed = e;
|
|
372
366
|
throw new Error(e);
|
|
@@ -406,13 +400,13 @@ export class SyncManager {
|
|
|
406
400
|
// where we can get informations about the coValue
|
|
407
401
|
if (msg.header || Object.keys(msg.sessions).length > 0) {
|
|
408
402
|
entry.loadFromPeers([peer]).catch((e) => {
|
|
409
|
-
|
|
403
|
+
logger.error("Error loading coValue in handleLoad", e);
|
|
410
404
|
});
|
|
411
405
|
}
|
|
412
406
|
return;
|
|
413
407
|
} else {
|
|
414
408
|
this.local.loadCoValueCore(msg.id, peer.id).catch((e) => {
|
|
415
|
-
|
|
409
|
+
logger.error("Error loading coValue in handleLoad", e);
|
|
416
410
|
});
|
|
417
411
|
}
|
|
418
412
|
}
|
|
@@ -439,7 +433,7 @@ export class SyncManager {
|
|
|
439
433
|
header: false,
|
|
440
434
|
sessions: {},
|
|
441
435
|
}).catch((e) => {
|
|
442
|
-
|
|
436
|
+
logger.error("Error sending known state back", e);
|
|
443
437
|
});
|
|
444
438
|
|
|
445
439
|
return;
|
|
@@ -449,7 +443,7 @@ export class SyncManager {
|
|
|
449
443
|
await this.sendNewContentIncludingDependencies(msg.id, peer);
|
|
450
444
|
})
|
|
451
445
|
.catch((e) => {
|
|
452
|
-
|
|
446
|
+
logger.error("Error loading coValue in handleLoad loading state", e);
|
|
453
447
|
});
|
|
454
448
|
}
|
|
455
449
|
|
|
@@ -484,7 +478,7 @@ export class SyncManager {
|
|
|
484
478
|
peer.role === "storage" ? undefined : peer.id,
|
|
485
479
|
)
|
|
486
480
|
.catch((e) => {
|
|
487
|
-
|
|
481
|
+
logger.error(
|
|
488
482
|
`Error loading coValue ${msg.id} to create loading state, as dependency of ${msg.asDependencyOf}`,
|
|
489
483
|
e,
|
|
490
484
|
);
|
|
@@ -521,7 +515,7 @@ export class SyncManager {
|
|
|
521
515
|
|
|
522
516
|
if (entry.state.type !== "available") {
|
|
523
517
|
if (!msg.header) {
|
|
524
|
-
|
|
518
|
+
logger.error("Expected header to be sent in first message");
|
|
525
519
|
return;
|
|
526
520
|
}
|
|
527
521
|
|
|
@@ -584,7 +578,7 @@ export class SyncManager {
|
|
|
584
578
|
: t.changes.length,
|
|
585
579
|
)
|
|
586
580
|
.reduce((a, b) => a + b, 0);
|
|
587
|
-
|
|
581
|
+
logger.debug(
|
|
588
582
|
`Adding incoming transactions took ${(after - before).toFixed(
|
|
589
583
|
2,
|
|
590
584
|
)}ms for ${totalTxLength} bytes = bandwidth: ${(
|
|
@@ -602,7 +596,7 @@ export class SyncManager {
|
|
|
602
596
|
// );
|
|
603
597
|
|
|
604
598
|
if (result.isErr()) {
|
|
605
|
-
|
|
599
|
+
logger.error(
|
|
606
600
|
"Failed to add transactions from",
|
|
607
601
|
peer.id,
|
|
608
602
|
result.error,
|
|
@@ -633,7 +627,7 @@ export class SyncManager {
|
|
|
633
627
|
isCorrection: true,
|
|
634
628
|
...coValue.knownState(),
|
|
635
629
|
}).catch((e) => {
|
|
636
|
-
|
|
630
|
+
logger.error("Error sending known state correction", e);
|
|
637
631
|
});
|
|
638
632
|
} else {
|
|
639
633
|
/**
|
|
@@ -647,7 +641,7 @@ export class SyncManager {
|
|
|
647
641
|
action: "known",
|
|
648
642
|
...coValue.knownState(),
|
|
649
643
|
}).catch((e: unknown) => {
|
|
650
|
-
|
|
644
|
+
logger.error("Error sending known state", e);
|
|
651
645
|
});
|
|
652
646
|
}
|
|
653
647
|
|
|
@@ -681,9 +675,6 @@ export class SyncManager {
|
|
|
681
675
|
const done = new Promise<void>((resolve) => {
|
|
682
676
|
queueMicrotask(async () => {
|
|
683
677
|
delete this.requestedSyncs[coValue.id];
|
|
684
|
-
// if (entry.nRequestsThisTick >= 2) {
|
|
685
|
-
// console.log("Syncing", coValue.id, "for", entry.nRequestsThisTick, "requests");
|
|
686
|
-
// }
|
|
687
678
|
await this.actuallySyncCoValue(coValue);
|
|
688
679
|
resolve();
|
|
689
680
|
});
|
|
@@ -49,12 +49,9 @@ describe("PeerState", () => {
|
|
|
49
49
|
|
|
50
50
|
test("should perform graceful shutdown", () => {
|
|
51
51
|
const { mockPeer, peerState } = setup();
|
|
52
|
-
const consoleSpy = vi.spyOn(console, "debug").mockImplementation(() => {});
|
|
53
52
|
peerState.gracefulShutdown();
|
|
54
53
|
expect(mockPeer.outgoing.close).toHaveBeenCalled();
|
|
55
54
|
expect(peerState.closed).toBe(true);
|
|
56
|
-
expect(consoleSpy).toHaveBeenCalledWith("Gracefully closing", "test-peer");
|
|
57
|
-
consoleSpy.mockRestore();
|
|
58
55
|
});
|
|
59
56
|
|
|
60
57
|
test("should empty the queue when closing", async () => {
|
|
@@ -22,7 +22,7 @@ describe("PriorityBasedMessageQueue", () => {
|
|
|
22
22
|
const { queue } = setup();
|
|
23
23
|
expect(queue["defaultPriority"]).toBe(CO_VALUE_PRIORITY.MEDIUM);
|
|
24
24
|
expect(queue["queues"].length).toBe(8);
|
|
25
|
-
expect(queue["queues"].every((q) => q.
|
|
25
|
+
expect(queue["queues"].every((q) => !q.isNonEmpty())).toBe(true);
|
|
26
26
|
});
|
|
27
27
|
|
|
28
28
|
test("should push message with default priority", async () => {
|